lib/pbt/check/runner_methods.rb in pbt-0.4.0 vs lib/pbt/check/runner_methods.rb in pbt-0.5.0
- old
+ new
@@ -52,35 +52,24 @@
# If using Ractor, some extra configurations are available and they need to be set up.
#
# - `:thread_report_on_exception`
# So many exception reports happen in Ractor and a console gets too messy. Suppress them to avoid that.
- # - `:experimental_ractor_rspec_integration`
- # Allow to use Ractor with RSpec. This is an experimental feature and it's not stable.
#
# @param config [Hash] Configuration parameters.
# @param property [Property]
# @param block [Proc]
def setup_for_ractor(config, property, &block)
if config[:worker] == :ractor
original_report_on_exception = Thread.report_on_exception
Thread.report_on_exception = config[:thread_report_on_exception]
-
- if config[:experimental_ractor_rspec_integration]
- require "pbt/check/rspec_adapter/integration"
- class << property
- include Pbt::Check::RSpecAdapter::PropertyExtension
- end
- property.setup_rspec_integration
- end
end
yield
ensure
if config[:worker] == :ractor
Thread.report_on_exception = original_report_on_exception
- property.teardown_rspec_integration if config[:experimental_ractor_rspec_integration]
end
end
# Run the property test for each value.
#
@@ -94,14 +83,10 @@
case config[:worker]
in :none
run_it_in_sequential(property, runner)
in :ractor
run_it_in_ractors(property, runner)
- in :process
- run_it_in_processes(property, runner)
- in :thread
- run_it_in_threads(property, runner)
end
end
runner.run_execution
end
@@ -131,82 +116,13 @@
Case.new(val:, index:, ractor: property.run_in_ractor(val))
}.each do |c|
c.ractor.take
runner.handle_result(c)
rescue => e
- handle_ractor_error(e.cause, c)
+ c.exception = e.cause # Ractor error is wrapped in a Ractor::RemoteError. We need to get the cause.
runner.handle_result(c)
break # Ignore the rest of the cases. Just pick up the first failure.
end
- end
-
- def handle_ractor_error(cause, c)
- # Ractor error is wrapped in a Ractor::RemoteError. We need to get the cause.
- unless defined?(Pbt::Check::RSpecAdapter) && cause.is_a?(Pbt::Check::RSpecAdapter::ExpectationNotMet) # Unknown error.
- c.exception = cause
- return
- end
-
- # Convert Pbt's custom error to RSpec's error.
- begin
- RSpec::Expectations::ExpectationHelper.handle_failure(cause.matcher, cause.custom_message, cause.failure_message_method)
- rescue RSpec::Expectations::ExpectationNotMetError => e # The class inherits Exception, not StandardError.
- c.exception = e
- end
- end
-
- # @param property [Property] Property to test.
- # @param runner [RunnerIterator]
- # @return [void]
- def run_it_in_threads(property, runner)
- require_parallel
-
- Parallel.map_with_index(runner, in_threads: Parallel.processor_count) do |val, index|
- Case.new(val:, index:).tap do |c|
- property.run(val)
- # Catch all exceptions including RSpec's ExpectationNotMet (It inherits Exception).
- rescue Exception => e # standard:disable Lint/RescueException:
- c.exception = e
- # It's possible to break this loop here by raising `Parallel::Break`.
- # But if it raises, we cannot fetch all cases' result. So this loop continues until the end.
- end
- end.each do |c|
- runner.handle_result(c)
- break if c.exception
- # Ignore the rest of the cases. Just pick up the first failure.
- end
- end
-
- # @param property [Property] Property to test.
- # @param runner [RunnerIterator]
- # @return [void]
- def run_it_in_processes(property, runner)
- require_parallel
-
- Parallel.map_with_index(runner, in_processes: Parallel.processor_count) do |val, index|
- Case.new(val:, index:).tap do |c|
- property.run(val)
- # Catch all exceptions including RSpec's ExpectationNotMet (It inherits Exception).
- rescue Exception => e # standard:disable Lint/RescueException:
- c.exception = e
- # It's possible to break this loop here by raising `Parallel::Break`.
- # But if it raises, we cannot fetch all cases' result. So this loop continues until the end.
- end
- end.each do |c|
- runner.handle_result(c)
- break if c.exception
- # Ignore the rest of the cases. Just pick up the first failure.
- end
- end
-
- # Load Parallel gem. If it's not installed, raise an error.
- # @see https://github.com/grosser/parallel
- # @raise [InvalidConfiguration]
- def require_parallel
- require "parallel"
- rescue LoadError
- raise InvalidConfiguration,
- "Parallel gem (https://github.com/grosser/parallel) is required to use worker `:process` or `:thread`. Please add `gem 'parallel'` to your Gemfile."
end
end
end
end