Add argument mutator
* Add Util mutator to share code more efficient
This commit is contained in:
parent
4a6954d53c
commit
b984a15691
5 changed files with 155 additions and 8 deletions
|
@ -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'
|
||||||
|
|
35
lib/mutant/mutator/arguments.rb
Normal file
35
lib/mutant/mutator/arguments.rb
Normal 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
|
|
@ -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
|
85
lib/mutant/mutator/util.rb
Normal file
85
lib/mutant/mutator/util.rb
Normal 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
|
|
@ -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'
|
Loading…
Reference in a new issue