Cleanup mutation generation
This is a reaction to the to_source rewrite * Do not use 1.8 specific nodes anymore * Do not generate AST nodes that would not be generatable from source
This commit is contained in:
parent
66b09f8d8a
commit
97a75dd062
15 changed files with 104 additions and 92 deletions
2
Gemfile
2
Gemfile
|
@ -2,5 +2,7 @@ source 'https://rubygems.org'
|
|||
|
||||
gemspec
|
||||
|
||||
gem 'to_source', :path => '../to_source'
|
||||
|
||||
gem 'devtools', :git => 'https://github.com/datamapper/devtools.git'
|
||||
eval(File.read(File.join(File.dirname(__FILE__),'Gemfile.devtools')))
|
||||
|
|
|
@ -103,7 +103,9 @@ module Mutant
|
|||
mutator.each(value) do |mutation|
|
||||
dup = dup_node
|
||||
dup.public_send(:"#{name}=", mutation)
|
||||
yield dup if block_given?
|
||||
if block_given?
|
||||
dup = yield(dup)
|
||||
end
|
||||
emit(dup)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -19,6 +19,7 @@ module Mutant
|
|||
def dispatch
|
||||
emit_attribute_mutations(:name) do |mutation|
|
||||
mutation.name = "#{self.class::PREFIX}#{mutation.name}".to_sym
|
||||
mutation
|
||||
end
|
||||
emit_attribute_mutations(:value)
|
||||
end
|
||||
|
|
|
@ -22,6 +22,7 @@ module Mutant
|
|||
if array.empty?
|
||||
array << new_nil
|
||||
end
|
||||
mutation
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ module Mutant
|
|||
def dispatch
|
||||
emit_attribute_mutations(:arguments) do |argument|
|
||||
argument.names = argument.arguments.map(&:name)
|
||||
argument
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -32,6 +32,7 @@ module Mutant
|
|||
def emit_required_mutations
|
||||
emit_attribute_mutations(:required) do |mutation|
|
||||
mutation.names = mutation.optional + mutation.required
|
||||
mutation
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -22,6 +22,7 @@ module Mutant
|
|||
if mutation.defaults.names.empty?
|
||||
mutation.defaults = nil
|
||||
end
|
||||
mutation
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ module Mutant
|
|||
emit_attribute_mutations(:arguments) do |mutation|
|
||||
arguments = mutation.arguments
|
||||
arguments.names = arguments.required + arguments.optional
|
||||
mutation
|
||||
end if node.arguments
|
||||
end
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@ module Mutant
|
|||
# @api private
|
||||
#
|
||||
def negative_infinity
|
||||
new(Rubinius::AST::Negate, infinity)
|
||||
new_send_with_arguments(new_float(-1), :/, new_float(0))
|
||||
end
|
||||
|
||||
# Return AST representing infinity
|
||||
|
|
|
@ -7,22 +7,6 @@ module Mutant
|
|||
|
||||
handle(Rubinius::AST::Send)
|
||||
|
||||
# Test if node name is a keyword
|
||||
#
|
||||
# @param [Rubinius::AST::Node] node
|
||||
#
|
||||
# @return [true]
|
||||
# if node name equals a ruby keyword
|
||||
#
|
||||
# @return [false]
|
||||
# otherwise
|
||||
#
|
||||
# @api private
|
||||
#
|
||||
def self.keyword_name?(node)
|
||||
Mutant::KEYWORDS.include?(node.name)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Emit mutations
|
||||
|
@ -143,7 +127,7 @@ module Mutant
|
|||
# @api private
|
||||
#
|
||||
def emit_implicit_self_receiver
|
||||
if to_self? and self.class.keyword_name?(node)
|
||||
unless to_self? and !Mutant::KEYWORDS.include?(node.name)
|
||||
return
|
||||
end
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ module Mutant
|
|||
def dispatch
|
||||
emit_left_mutations
|
||||
emit_right_mutations
|
||||
emit(right)
|
||||
end
|
||||
|
||||
# Emit left mutations
|
||||
|
@ -29,6 +30,16 @@ module Mutant
|
|||
emit_attribute_mutations(:receiver)
|
||||
end
|
||||
|
||||
# Return right
|
||||
#
|
||||
# @return [Rubinius::AST::Node]
|
||||
#
|
||||
# @api private
|
||||
#
|
||||
def right
|
||||
node.arguments.array.first
|
||||
end
|
||||
|
||||
# Emit right mutations
|
||||
#
|
||||
# @return [undefined]
|
||||
|
@ -36,7 +47,6 @@ module Mutant
|
|||
# @api private
|
||||
#
|
||||
def emit_right_mutations
|
||||
right = node.arguments.array.first
|
||||
Mutator.each(right).each do |mutated|
|
||||
dup = dup_node
|
||||
dup.arguments.array[0] = mutated
|
||||
|
|
|
@ -18,7 +18,13 @@ module Mutant
|
|||
#
|
||||
def dispatch
|
||||
super
|
||||
emit_call_remove_mutation
|
||||
|
||||
if binary_operator?
|
||||
run(BinaryOperatorMethod)
|
||||
return
|
||||
end
|
||||
|
||||
emit_send_remove_mutation
|
||||
emit_argument_mutations
|
||||
end
|
||||
|
||||
|
@ -45,21 +51,24 @@ module Mutant
|
|||
# @api private
|
||||
#
|
||||
def emit_argument_mutations
|
||||
if binary_operator?
|
||||
run(BinaryOperatorMethod)
|
||||
return
|
||||
emit_attribute_mutations(:arguments) do |mutation|
|
||||
if mutation.arguments.array.empty?
|
||||
mutation = new_send(receiver, node.name)
|
||||
mutation.privately = node.privately
|
||||
mutation
|
||||
else
|
||||
mutation
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
emit_attribute_mutations(:arguments)
|
||||
end
|
||||
|
||||
# Emit transfomr call mutation
|
||||
# Emit send remove mutation
|
||||
#
|
||||
# @return [undefined]
|
||||
#
|
||||
# @api private
|
||||
#
|
||||
def emit_call_remove_mutation
|
||||
def emit_send_remove_mutation
|
||||
array = node.arguments.array
|
||||
return unless array.length == 1
|
||||
emit(array.first)
|
||||
|
|
|
@ -51,8 +51,7 @@ shared_examples_for 'a mutator' do
|
|||
unexpected = (generated - expected_mutations).to_a
|
||||
|
||||
unless generated == expected_mutations
|
||||
message ="Missing mutations:\n%s\nUnexpected mutations:\n%s" % [missing.join("\n----\n"), unexpected.join("\n----\n")]
|
||||
fail message
|
||||
fail "Missing mutations:\n%s\nUnexpected mutations:\n%s" % [missing.join("\n----\n"), unexpected.join("\n----\n")]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -11,7 +11,7 @@ describe Mutant::Mutator::Node::Literal, 'float' do
|
|||
mutations << random_float.to_s
|
||||
mutations << '0.0/0.0'
|
||||
mutations << '1.0/0.0'
|
||||
mutations << '-(1.0 / 0.0)'
|
||||
mutations << '(-1.0 / 0.0)'
|
||||
mutations << '-10.0'
|
||||
end
|
||||
|
||||
|
|
|
@ -55,6 +55,66 @@ describe Mutant::Mutator, 'send' do
|
|||
end
|
||||
end
|
||||
|
||||
context 'with block' do
|
||||
let(:source) { 'foo() { a; b }' }
|
||||
|
||||
let(:mutations) do
|
||||
mutations = []
|
||||
mutations << 'foo() { a }'
|
||||
mutations << 'foo() { b }'
|
||||
mutations << 'foo() { }'
|
||||
mutations << 'foo'
|
||||
end
|
||||
|
||||
it_should_behave_like 'a mutator'
|
||||
end
|
||||
|
||||
context 'with block args' do
|
||||
|
||||
let(:source) { 'foo { |a, b| }' }
|
||||
|
||||
before do
|
||||
Mutant::Random.stub(:hex_string => :random)
|
||||
end
|
||||
|
||||
let(:mutations) do
|
||||
mutations = []
|
||||
mutations << 'foo'
|
||||
mutations << 'foo { |a, b| Object.new }'
|
||||
mutations << 'foo { |a, srandom| }'
|
||||
mutations << 'foo { |srandom, b| }'
|
||||
mutations << 'foo { |a| }'
|
||||
mutations << 'foo { |b| }'
|
||||
mutations << 'foo { || }'
|
||||
end
|
||||
|
||||
it_should_behave_like 'a mutator'
|
||||
end
|
||||
|
||||
context 'with block pattern args' do
|
||||
|
||||
before do
|
||||
Mutant::Random.stub(:hex_string => :random)
|
||||
end
|
||||
|
||||
let(:source) { 'foo { |(a, b), c| }' }
|
||||
|
||||
let(:mutations) do
|
||||
mutations = []
|
||||
mutations << 'foo { || }'
|
||||
mutations << 'foo { |a, b, c| }'
|
||||
mutations << 'foo { |(a, b), c| Object.new }'
|
||||
mutations << 'foo { |(a, b)| }'
|
||||
mutations << 'foo { |c| }'
|
||||
mutations << 'foo { |(srandom, b), c| }'
|
||||
mutations << 'foo { |(a, srandom), c| }'
|
||||
mutations << 'foo { |(a, b), srandom| }'
|
||||
mutations << 'foo'
|
||||
end
|
||||
|
||||
it_should_behave_like 'a mutator'
|
||||
end
|
||||
|
||||
context 'send with arguments' do
|
||||
|
||||
context 'one argument' do
|
||||
|
@ -62,7 +122,7 @@ describe Mutant::Mutator, 'send' do
|
|||
|
||||
let(:mutations) do
|
||||
mutations = []
|
||||
mutations << 'foo()'
|
||||
mutations << 'foo'
|
||||
mutations << 'nil'
|
||||
mutations << 'foo(Object.new)'
|
||||
end
|
||||
|
@ -134,65 +194,5 @@ describe Mutant::Mutator, 'send' do
|
|||
it_should_behave_like 'a mutator'
|
||||
end
|
||||
|
||||
context 'with block' do
|
||||
let(:source) { 'foo() { a; b }' }
|
||||
|
||||
let(:mutations) do
|
||||
mutations = []
|
||||
mutations << 'foo() { a }'
|
||||
mutations << 'foo() { b }'
|
||||
mutations << 'foo() { }'
|
||||
mutations << 'foo'
|
||||
end
|
||||
|
||||
it_should_behave_like 'a mutator'
|
||||
end
|
||||
|
||||
context 'with block args' do
|
||||
|
||||
let(:source) { 'foo { |a, b| }' }
|
||||
|
||||
before do
|
||||
Mutant::Random.stub(:hex_string => :random)
|
||||
end
|
||||
|
||||
let(:mutations) do
|
||||
mutations = []
|
||||
mutations << 'foo'
|
||||
mutations << 'foo() { |a, b| Object.new }'
|
||||
mutations << 'foo() { |a, srandom| }'
|
||||
mutations << 'foo() { |srandom, b| }'
|
||||
mutations << 'foo() { |a| }'
|
||||
mutations << 'foo() { |b| }'
|
||||
mutations << 'foo() { || }'
|
||||
end
|
||||
|
||||
it_should_behave_like 'a mutator'
|
||||
end
|
||||
|
||||
context 'with block pattern args' do
|
||||
|
||||
before do
|
||||
Mutant::Random.stub(:hex_string => :random)
|
||||
end
|
||||
|
||||
let(:source) { 'foo { |(a, b), c| }' }
|
||||
|
||||
let(:mutations) do
|
||||
mutations = []
|
||||
mutations << 'foo() { || }'
|
||||
mutations << 'foo() { |a, b, c| }'
|
||||
mutations << 'foo() { |(a, b), c| Object.new }'
|
||||
mutations << 'foo() { |(a, b)| }'
|
||||
mutations << 'foo() { |c| }'
|
||||
mutations << 'foo() { |(srandom, b), c| }'
|
||||
mutations << 'foo() { |(a, srandom), c| }'
|
||||
mutations << 'foo() { |(a, b), srandom| }'
|
||||
mutations << 'foo'
|
||||
end
|
||||
|
||||
it_should_behave_like 'a mutator'
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Add table
Reference in a new issue