Change meta examples to allow specifying N types

This commit is contained in:
Markus Schirp 2018-12-02 00:18:10 +00:00
parent ce5bcb4c62
commit 4355b23369
9 changed files with 44 additions and 43 deletions

View file

@ -18,9 +18,9 @@ module Mutant
# @return [undefined] # @return [undefined]
# #
# rubocop:disable Performance/Caller # rubocop:disable Performance/Caller
def self.add(type, &block) def self.add(*types, &block)
file = caller.first.split(':in', 2).first file = caller.first.split(':in', 2).first
ALL << DSL.call(file, type, block) ALL << DSL.call(file, Set.new(types), block)
end end
Pathname.glob(Pathname.new(__dir__).parent.parent.join('meta', '*.rb')) Pathname.glob(Pathname.new(__dir__).parent.parent.join('meta', '*.rb'))

View file

@ -3,7 +3,7 @@
module Mutant module Mutant
module Meta module Meta
class Example class Example
include Adamantium, Anima.new(:file, :node, :node_type, :expected) include Adamantium, Anima.new(:file, :node, :types, :expected)
# Verification instance for example # Verification instance for example
# #

View file

@ -9,9 +9,12 @@ module Mutant
# Run DSL on block # Run DSL on block
# #
# @param [Pathname] file
# @param [Set<Symbol>] types
#
# @return [Example] # @return [Example]
def self.call(file, type, block) def self.call(file, types, block)
instance = new(file, type) instance = new(file, types)
instance.instance_eval(&block) instance.instance_eval(&block)
instance.example instance.example
end end
@ -21,9 +24,9 @@ module Mutant
# Initialize object # Initialize object
# #
# @return [undefined] # @return [undefined]
def initialize(file, type) def initialize(file, types)
@file = file @file = file
@type = type @types = types
@node = nil @node = nil
@expected = [] @expected = []
end end
@ -37,10 +40,10 @@ module Mutant
def example def example
fail 'source not defined' unless @node fail 'source not defined' unless @node
Example.new( Example.new(
file: @file, file: @file,
node: @node, node: @node,
node_type: @type, types: @types,
expected: @expected expected: @expected
) )
end end

View file

@ -80,10 +80,3 @@ Pathname
.glob(Pathname.new(__dir__).join('regexp', '*.rb')) .glob(Pathname.new(__dir__).join('regexp', '*.rb'))
.sort .sort
.each(&Kernel.public_method(:require)) .each(&Kernel.public_method(:require))
# Re-register examples for all regular expression nodes for node_type `:regexp`
Mutant::Meta::Example::ALL.each do |example|
next unless example.node_type.to_s.start_with?('regexp_')
Mutant::Meta::Example::ALL << example.with(node_type: :regexp)
end

View file

@ -12,7 +12,7 @@ mutations = {
mutations = mutations.merge(mutations.invert) mutations = mutations.merge(mutations.invert)
mutations.each do |(source_type, source_mutation), (_, regexp_mutation)| mutations.each do |(source_type, source_mutation), (_, regexp_mutation)|
Mutant::Meta::Example.add source_type do Mutant::Meta::Example.add :regexp, source_type do
source(source_mutation) source(source_mutation)
singleton_mutations singleton_mutations

View file

@ -2,19 +2,19 @@
RSpec.describe Mutant::Meta::Example::DSL do RSpec.describe Mutant::Meta::Example::DSL do
describe '.call' do describe '.call' do
subject { described_class.call(file, type, block) } subject { described_class.call(file, types, block) }
let(:file) { 'foo.rb' } let(:file) { 'foo.rb' }
let(:node) { s(:false) } let(:node) { s(:false) }
let(:type) { node.type } let(:types) { Set.new([node.type]) }
let(:expected) { [] } let(:expected) { [] }
let(:expected_example) do let(:expected_example) do
Mutant::Meta::Example.new( Mutant::Meta::Example.new(
file: file, file: file,
node: node, node: node,
node_type: type, types: types,
expected: expected expected: expected
) )
end end

View file

@ -5,10 +5,10 @@ RSpec.describe Mutant::Meta::Example::Verification do
let(:example) do let(:example) do
Mutant::Meta::Example.new( Mutant::Meta::Example.new(
file: 'foo.rb', file: 'foo.rb',
node: s(:true), node: s(:true),
node_type: :true, types: [:true],
expected: expected_nodes expected: expected_nodes
) )
end end

View file

@ -3,10 +3,10 @@
RSpec.describe Mutant::Meta::Example do RSpec.describe Mutant::Meta::Example do
let(:object) do let(:object) do
described_class.new( described_class.new(
file: file, file: file,
node: node, node: node,
node_type: node.type, types: [node.type],
expected: mutation_nodes expected: mutation_nodes
) )
end end

View file

@ -1,15 +1,20 @@
# frozen_string_literal: true # frozen_string_literal: true
Mutant::Meta::Example::ALL.each.group_by(&:node_type).each do |type, examples| aggregate = Hash.new { |hash, key| hash[key] = [] }
RSpec.describe Mutant::Mutator::REGISTRY.lookup(type) do
toplevel_nodes = examples.map { |example| example.node.type }.uniq
it "generates the correct mutations on #{toplevel_nodes} toplevel examples" do Mutant::Meta::Example::ALL
.each_with_object(aggregate) do |example, agg|
example.types.each do |type|
agg[Mutant::Mutator::REGISTRY.lookup(type)] << example
end
end
aggregate.each do |mutator, examples|
RSpec.describe mutator do
it 'generates expected mutations' do
examples.each do |example| examples.each do |example|
verification = example.verification verification = example.verification
unless verification.success? fail verification.error_report unless verification.success?
fail verification.error_report
end
end end
end end
end end