class Mutant::Integration::Rspec
Rspec
integration
This looks so complicated, because rspec:
-
Keeps its state global in RSpec.world and lots of other places
-
There is no API to “just run a subset of examples”, the examples need to be selected in-place via mutating the ‘RSpec.filtered_examples` data structure
-
Does not maintain a unique identification for an example, aside the instances of ‘RSpec::Core::Example` objects itself. For that reason identifying examples by:
-
full description
-
location
Is NOT enough. It would not be unique. So we add an “example index” for unique reference.
-
rubocop:disable Metrics/ClassLength
Constants
- ALL_EXPRESSION
- DEFAULT_CLI_OPTIONS
- EXIT_SUCCESS
- EXPRESSION_CANDIDATE
- TEST_ID_FORMAT
Public Class Methods
Source
# File lib/mutant/integration/rspec.rb, line 41 def initialize(*) super @runner = RSpec::Core::Runner.new(RSpec::Core::ConfigurationOptions.new(effective_arguments)) @rspec_world = RSpec.world end
Initialize rspec integration
@return [undefined]
Public Instance Methods
Source
# File lib/mutant/integration/rspec.rb, line 92 def all_tests all_tests_index.keys end
All tests
@return [Enumerable<Test>]
Source
# File lib/mutant/integration/rspec.rb, line 100 def available_tests all_tests_index.select { |_test, example| example.metadata.fetch(:mutant, true) }.keys end
Available tests
@return [Enumerable<Test>]
Source
# File lib/mutant/integration/rspec.rb, line 71 def call(tests) reset_examples setup_examples(tests.map(&all_tests_index)) @runner.configuration.start_time = world.time.now - @setup_elapsed start = timer.now passed = @runner.run_specs(@rspec_world.ordered_example_groups).equal?(EXIT_SUCCESS) @runner.configuration.reset_reporter Result::Test.new( job_index: nil, output: '', passed:, runtime: timer.now - start ) end
Run a collection of tests
@param [Enumerable<Mutant::Test>] tests
@return [Result::Test]
rubocop:disable Metrics/AbcSize rubocop:disable Metrics/MethodLength
Source
# File lib/mutant/integration/rspec.rb, line 33 def freeze super if @setup_elapsed self end
Source
# File lib/mutant/integration/rspec.rb, line 50 def setup @setup_elapsed = timer.elapsed do @runner.setup(world.stderr, world.stdout) fail 'RSpec setup failure' if rspec_setup_failure? example_group_map end @runner.configuration.force(color_mode: :on) @runner.configuration.reporter reset_examples freeze end
Setup rspec integration
@return [self]
Private Instance Methods
Source
# File lib/mutant/integration/rspec.rb, line 179 def all_examples @rspec_world.example_groups.flat_map(&:descendants).flat_map(&:examples) end
Source
# File lib/mutant/integration/rspec.rb, line 129 def all_tests_index all_examples.each_with_index.with_object({}) do |(example, example_index), index| index[parse_example(example, example_index)] = example end end
Source
# File lib/mutant/integration/rspec.rb, line 115 def effective_arguments arguments.empty? ? DEFAULT_CLI_OPTIONS : arguments end
Source
# File lib/mutant/integration/rspec.rb, line 151 def example_group_map @rspec_world.example_groups.flat_map(&:descendants).each_with_object({}) do |example_group, map| example_group.examples.each do |example| map[example] = example_group end end end
Source
# File lib/mutant/integration/rspec.rb, line 136 def parse_example(example, index) metadata = example.metadata id = TEST_ID_FORMAT % { index:, location: metadata.fetch(:location), description: metadata.fetch(:full_description) } Test.new( expressions: parse_metadata(metadata), id: ) end
Source
# File lib/mutant/integration/rspec.rb, line 175 def parse_expression(input, &) expression_parser.call(input).from_right(&) end
Source
# File lib/mutant/integration/rspec.rb, line 161 def parse_metadata(metadata) if metadata.key?(:mutant_expression) expression = metadata.fetch(:mutant_expression) expressions = expression.instance_of?(Array) ? expression : [expression] expressions.map(&method(:parse_expression)) else match = EXPRESSION_CANDIDATE.match(metadata.fetch(:full_description)) or return [ALL_EXPRESSION] [parse_expression(Util.one(match.captures)) { ALL_EXPRESSION }] end end
mutant:disable – 3.3 specific mutation on match.captures -> match
Source
# File lib/mutant/integration/rspec.rb, line 119 def reset_examples @rspec_world.filtered_examples.each_value(&:clear) end
Source
# File lib/mutant/integration/rspec.rb, line 111 def rspec_is_quitting? @rspec_world.respond_to?(:rspec_is_quitting) && @rspec_world.rspec_is_quitting end
Source
# File lib/mutant/integration/rspec.rb, line 107 def rspec_setup_failure? @rspec_world.wants_to_quit || rspec_is_quitting? end
Source
# File lib/mutant/integration/rspec.rb, line 123 def setup_examples(examples) examples.each do |example| @rspec_world.filtered_examples.fetch(example_group_map.fetch(example)) << example end end