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