class Mutant::Integration::Rspec
rubocop:disable Metrics/ClassLength
for unique reference.
Is NOT enough. It would not be unique. So we add an “example index”
* location
* full description
For that reason identifying examples by:
aside the instances of ‘RSpec::Core::Example` objects itself.
* Does not maintain a unique identification for an example,
data structure
need to be selected in-place via mutating the `RSpec.filtered_examples`
* There is no API to “just run a subset of examples”, the examples
* Keeps its state global in RSpec.world and lots of other places
This looks so complicated, because rspec:
Rspec integration
def all_examples
def all_examples @rspec_world.example_groups.flat_map(&:descendants).flat_map(&:examples) end
def all_tests
-
(Enumerable
-)
def all_tests all_tests_index.keys end
def all_tests_index
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
def available_tests
-
(Enumerable
-)
def available_tests all_tests_index.select { |_test, example| example.metadata.fetch(:mutant, true) }.keys end
def call(tests)
-
(Result::Test)
-
Parameters:
-
tests
(Enumerable
) --
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
def effective_arguments
def effective_arguments arguments.empty? ? DEFAULT_CLI_OPTIONS : arguments end
def example_group_map
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
def freeze
def freeze super if @setup_elapsed self end
def initialize(*)
-
(undefined)
-
def initialize(*) super @runner = RSpec::Core::Runner.new(RSpec::Core::ConfigurationOptions.new(effective_arguments)) @rspec_world = RSpec.world end
def parse_example(example, index)
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
def parse_expression(input, &)
def parse_expression(input, &) expression_parser.call(input).from_right(&) end
def parse_metadata(metadata)
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
def reset_examples
def reset_examples @rspec_world.filtered_examples.each_value(&:clear) end
def rspec_is_quitting?
def rspec_is_quitting? @rspec_world.respond_to?(:rspec_is_quitting) && @rspec_world.rspec_is_quitting end
def rspec_setup_failure?
def rspec_setup_failure? @rspec_world.wants_to_quit || rspec_is_quitting? end
def setup
-
(self)
-
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
def setup_examples(examples)
def setup_examples(examples) examples.each do |example| @rspec_world.filtered_examples.fetch(example_group_map.fetch(example)) << example end end