Add argument mutator

* Add Util mutator to share code more efficient
This commit is contained in:
Markus Schirp 2012-12-06 20:44:26 +01:00
parent 4a6954d53c
commit b984a15691
5 changed files with 155 additions and 8 deletions

View file

@ -67,7 +67,9 @@ require 'mutant/mutator/literal/nil'
#require 'mutant/mutator/literal/dynamic'
require 'mutant/mutator/block'
require 'mutant/mutator/noop'
require 'mutant/mutator/call'
require 'mutant/mutator/util'
require 'mutant/mutator/send'
require 'mutant/mutator/arguments'
require 'mutant/mutator/define'
require 'mutant/mutator/return'
require 'mutant/mutator/if_statement'

View file

@ -0,0 +1,35 @@
module Mutant
class Mutator
# Mutator for arguments
class Arguments < self
handle(Rubinius::AST::ActualArguments)
private
# Emit mutations
#
# @return [undefined]
#
# @api private
#
def dispatch
emit_argument_mutations
end
# Emit argument mutations
#
# @return [undefined]
#
# @api private
#
def emit_argument_mutations
Mutator::Util::Array.each(node.array) do |mutation|
dup = dup_node
dup.array = mutation
emit(dup)
end
end
end
end
end

View file

@ -1,7 +1,7 @@
module Mutant
class Mutator
# Class for mutations where messages are send to objects
class Call < self
class Send < self
handle(Rubinius::AST::Send)
@ -87,13 +87,13 @@ module Mutant
emit_implicit_self_receiver
end
class SendWithArguments < Call
class SendWithArguments < self
handle(Rubinius::AST::SendWithArguments)
private
# Emut mutations
# Emit mutations
#
# @return [undefined]
#
@ -101,6 +101,21 @@ module Mutant
#
def dispatch
super
emit_argument_mutations
end
# Emit argument mutations
#
# @return [undefined]
#
# @api private
#
def emit_argument_mutations
Mutator.each(node.arguments) do |mutation|
dup = dup_node
dup.arguments = mutation
emit(dup)
end
end
end
end

View file

@ -0,0 +1,85 @@
module Mutant
class Mutator
# Namespace for utility mutators
class Util < self
# Run ulitity mutator
#
# @param [Object]
#
# @api private
#
def self.each(object, &block)
return to_enum(__method__, object) unless block_given?
new(object, block)
self
end
# Test if mutation is new
#
# @param [Object] generated
#
# @return [true]
# if object is new
#
# @return [false]
# otherwise
#
def new?(generated)
node != generated
end
# Mutators that mutates an array of inputs
class Array < self
private
# Emit mutations
#
# @return [undefined]
#
# @api private
#
def dispatch
emit_element_presence
emit_element_mutations
emit([])
end
# Emit element mutations
#
# @return [undefined]
#
# @api private
#
def emit_element_mutations
node.each_with_index do |element, index|
dup = dup_node
Mutator.each(element).each do |mutation|
dup[index]=mutation
emit(dup)
end
end
end
# Emit element presence mutations
#
# @return [undefined]
#
# @api private
#
def emit_element_presence
node.each_index do |index|
dup = dup_node
dup.delete_at(index)
emit(dup)
end
end
end
end
end
end

View file

@ -16,6 +16,7 @@ describe Mutant::Mutator, 'call' do
it_should_behave_like 'a noop mutator'
end
end
context 'with self as receiver' do
context 'implicit' do
@ -45,20 +46,29 @@ describe Mutant::Mutator, 'call' do
end
context 'send with arguments' do
context 'with self as receiver' do
context 'implicit' do
let(:source) { 'foo(1)' }
let(:source) { 'foo(nil)' }
it_should_behave_like 'a noop mutator'
let(:mutations) do
mutations = []
mutations << 'foo()'
mutations << 'foo(Object.new)'
end
it_should_behave_like 'a mutator'
end
context 'explicit' do
let(:source) { 'self.foo(1)' }
let(:source) { 'self.foo(nil)' }
let(:mutations) do
mutations = []
# with implicit receiver (send privately)
mutations << 'foo(1)'
mutations << 'foo(nil)'
mutations << 'self.foo(Object.new)'
mutations << 'self.foo()'
end
it_should_behave_like 'a mutator'