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/literal/dynamic'
require 'mutant/mutator/block' require 'mutant/mutator/block'
require 'mutant/mutator/noop' 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/define'
require 'mutant/mutator/return' require 'mutant/mutator/return'
require 'mutant/mutator/if_statement' 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 module Mutant
class Mutator class Mutator
# Class for mutations where messages are send to objects # Class for mutations where messages are send to objects
class Call < self class Send < self
handle(Rubinius::AST::Send) handle(Rubinius::AST::Send)
@ -87,13 +87,13 @@ module Mutant
emit_implicit_self_receiver emit_implicit_self_receiver
end end
class SendWithArguments < Call class SendWithArguments < self
handle(Rubinius::AST::SendWithArguments) handle(Rubinius::AST::SendWithArguments)
private private
# Emut mutations # Emit mutations
# #
# @return [undefined] # @return [undefined]
# #
@ -101,6 +101,21 @@ module Mutant
# #
def dispatch def dispatch
super 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 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' it_should_behave_like 'a noop mutator'
end end
end end
context 'with self as receiver' do context 'with self as receiver' do
context 'implicit' do context 'implicit' do
@ -45,20 +46,29 @@ describe Mutant::Mutator, 'call' do
end end
context 'send with arguments' do context 'send with arguments' do
context 'with self as receiver' do context 'with self as receiver' do
context 'implicit' 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 end
context 'explicit' do context 'explicit' do
let(:source) { 'self.foo(1)' } let(:source) { 'self.foo(nil)' }
let(:mutations) do let(:mutations) do
mutations = [] mutations = []
# with implicit receiver (send privately) # with implicit receiver (send privately)
mutations << 'foo(1)' mutations << 'foo(nil)'
mutations << 'self.foo(Object.new)'
mutations << 'self.foo()'
end end
it_should_behave_like 'a mutator' it_should_behave_like 'a mutator'