diff --git a/config/reek.yml b/config/reek.yml index 8e4ab941..9a625cc6 100644 --- a/config/reek.yml +++ b/config/reek.yml @@ -56,6 +56,7 @@ NestedIterators: - Mutant::CLI#parse - Mutant::Mutator::Util::Array::Element#dispatch - Mutant::Mutator::Node::Resbody#mutate_captures + - Mutant::Mutator::Node::Arguments#emit_argument_mutations - Mutant::Reporter::CLI::Report::Config#generic_stats - Mutant::RequireHighjack#infect - Mutant::RequireHighjack#desinfect diff --git a/lib/mutant/mutator/node.rb b/lib/mutant/mutator/node.rb index 253659b4..4e779443 100644 --- a/lib/mutant/mutator/node.rb +++ b/lib/mutant/mutator/node.rb @@ -119,7 +119,7 @@ module Mutant # @api private # def mutate_child(index, mutator = Mutator, &block) - block ||= lambda { |_node| true } + block ||= ->(_node) { true } child = children.at(index) mutator.each(child, self) do |mutation| if block.call(mutation) @@ -166,7 +166,7 @@ module Mutant # @api private # def emit_type(*children) - emit(new_self(*children)) + emit(Parser::AST::Node.new(node.type, children)) end # Emit singleton literals @@ -200,16 +200,6 @@ module Mutant emit(N_NIL) unless asgn_left? end - # Return new self typed child - # - # @return [Parser::AST::Node] - # - # @api private - # - def new_self(*children) - Parser::AST::Node.new(node.type, children) - end - # Emit values # # @param [Array] values diff --git a/lib/mutant/mutator/node/and_asgn.rb b/lib/mutant/mutator/node/and_asgn.rb index ec254603..5c82c29d 100644 --- a/lib/mutant/mutator/node/and_asgn.rb +++ b/lib/mutant/mutator/node/and_asgn.rb @@ -27,8 +27,7 @@ module Mutant emit_right_mutations end - end # OrAsgn + end # AndAsgn end # Node end # Mutator end # Mutant - diff --git a/lib/mutant/mutator/node/arguments.rb b/lib/mutant/mutator/node/arguments.rb index ffa84352..e9a70293 100644 --- a/lib/mutant/mutator/node/arguments.rb +++ b/lib/mutant/mutator/node/arguments.rb @@ -17,10 +17,55 @@ module Mutant # @api private # def dispatch - emit_children_mutations + emit_argument_presence + emit_argument_mutations emit_mlhs_expansion end + # Emit argument presence mutation + # + # @return [undefined] + # + # @api private + # + def emit_argument_presence + emit_type + Mutator::Util::Array::Presence.each(children, self) do |children| + emit_type(*children) + end + end + + # Emit argument mutations + # + # @return [undefined] + # + # @api private + # + def emit_argument_mutations + children.each_with_index do |child, index| + Mutator.each(child) do |mutant| + unless invalid_argument_replacement?(mutant, index) + emit_child_update(index, mutant) + end + end + end + end + + # Test if child mutation is allowed + # + # @param [Parser::AST::Node] + # + # @return [Boolean] + # + # @api private + # + def invalid_argument_replacement?(mutant, index) + original = children.fetch(index) + original.type.equal?(:optarg) && + mutant.type.equal?(:arg) && + children[0...index].any? { |node| node.type.equal?(:optarg) } + end + # Emit mlhs expansions # # @return [undefined] @@ -44,7 +89,7 @@ module Mutant # def mlhs_childs_with_index children.each_with_index.select do |child, _index| - child.type == :mlhs + child.type.equal?(:mlhs) end end diff --git a/lib/mutant/mutator/node/next.rb b/lib/mutant/mutator/node/next.rb index 2915b44a..ee373561 100644 --- a/lib/mutant/mutator/node/next.rb +++ b/lib/mutant/mutator/node/next.rb @@ -28,4 +28,3 @@ module Mutant end # Node end # Mutator end # Mutant - diff --git a/meta/def.rb b/meta/def.rb index faaec1f6..16540911 100644 --- a/meta/def.rb +++ b/meta/def.rb @@ -69,6 +69,25 @@ Mutant::Meta::Example.add do mutation 'def foo; end' end +Mutant::Meta::Example.add do + source 'def foo(a = 0, b = 0); end' + mutation 'def foo(a = 0, b__mutant__ = 0); end' + mutation 'def foo(a__mutant__ = 0, b = 0); end' + mutation 'def foo(a = 0, b = 1); end' + mutation 'def foo(a = 0, b = -1); end' + mutation 'def foo(a = 0, b = self); end' + mutation 'def foo(a = 0, b = nil); end' + mutation 'def foo(a = -1, b = 0); end' + mutation 'def foo(a = self, b = 0); end' + mutation 'def foo(a = nil, b = 0); end' + mutation 'def foo(a = 1, b = 0); end' + mutation 'def foo(a = 0); end' + mutation 'def foo(b = 0); end' + mutation 'def foo(a, b = 0); end' + mutation 'def foo; end' + mutation 'def foo(a = 0, b = 0); raise; end' +end + Mutant::Meta::Example.add do source 'def foo(a = true); end'