Add binary connective mutator

This commit is contained in:
Dan Kubb 2013-07-23 22:58:53 -07:00
parent e4187edd77
commit d44115c0b6
4 changed files with 108 additions and 1 deletions

View file

@ -58,6 +58,7 @@ require 'mutant/mutator/node/argument'
require 'mutant/mutator/node/arguments'
require 'mutant/mutator/node/begin'
require 'mutant/mutator/node/cbase'
require 'mutant/mutator/node/connective/binary'
require 'mutant/mutator/node/const'
require 'mutant/mutator/node/named_value/access'
require 'mutant/mutator/node/named_value/constant_assignment'

View file

@ -0,0 +1,61 @@
module Mutant
class Mutator
class Node
module Connective
# Mutation emitter to handle binary connectives
class Binary < Node
INVERSE = {
:and => :or,
:or => :and,
}.freeze
handle *INVERSE.keys
children :left, :right
private
# Emit mutations
#
# @return [undefined]
#
# @api private
#
def dispatch
emit_nil
emit(left)
emit(right)
mutate_operator
mutate_conditions
end
# Emit operator mutations
#
# @return [undefined]
#
# @api private
#
def mutate_operator
emit(s(INVERSE.fetch(node.type), left, right))
end
# Emit condition mutations
#
# @return [undefined]
#
# @api private
#
def mutate_conditions
[N_TRUE, N_FALSE, N_NIL].each do |condition|
emit_left(condition) unless left == condition
emit_right(condition) unless right == condition
end
end
end # Binary
end # Connective
end # Node
end # Mutator
end # Mutant

View file

@ -8,7 +8,7 @@ module Mutant
# These nodes still need a dedicated mutator,
# your contribution is that close!
handle(
:not, :or, :and, :defined,
:not, :defined,
:next, :break, :match, :ensure,
:dstr, :dsym, :yield, :rescue, :redo, :defined?,
:blockarg, :block_pass, :op_asgn, :and_asgn,

View file

@ -0,0 +1,45 @@
require 'spec_helper'
describe Mutant::Mutator::Node::Connective::Binary, 'mutations' do
context 'and' do
let(:source) { 'true and false' }
let(:mutations) do
mutations = []
mutations << 'nil'
mutations << 'true'
mutations << 'false'
mutations << 'true or false'
mutations << 'false and false'
mutations << 'true and true'
mutations << 'nil and false'
mutations << 'true and nil'
end
it_should_behave_like 'a mutator'
end
context 'or' do
let(:source) { 'true or false' }
let(:mutations) do
mutations = []
mutations << 'nil'
mutations << 'true'
mutations << 'false'
mutations << 'true and false'
mutations << 'false or false'
mutations << 'true or true'
mutations << 'nil or false'
mutations << 'true or nil'
end
it_should_behave_like 'a mutator'
end
end