From 640ce5360eb0cd51bd12943b4a21abf24834c111 Mon Sep 17 00:00:00 2001 From: Markus Schirp Date: Wed, 1 Aug 2012 14:54:49 +0200 Subject: [PATCH] Correct mutations of send to self * Invert the behaviour as this direction of mutation does make sense. --- lib/mutant/mutator/call.rb | 36 ++++++++++++--- .../each_spec.rb => mutation_spec.rb} | 8 ++-- .../unit/mutant/mutator/call/mutation_spec.rb | 44 +++++++++++-------- 3 files changed, 60 insertions(+), 28 deletions(-) rename spec/unit/mutant/mutator/block/{class_methods/each_spec.rb => mutation_spec.rb} (63%) diff --git a/lib/mutant/mutator/call.rb b/lib/mutant/mutator/call.rb index 02eeed1a..ba14ebb1 100644 --- a/lib/mutant/mutator/call.rb +++ b/lib/mutant/mutator/call.rb @@ -41,11 +41,37 @@ module Mutant receiver.kind_of?(Rubinius::AST::Self) end - def emit_explicit_self_receiver + # Emit mutation that replaces explicit send to self with implicit send to self. + # + # @example: + # + # # This class does use Foo#a with explicitly specifing the receiver self. + # # But an implicit (privately) call should be used as there is no need for + # # specifing en explicit receiver. + # + # class Foo # Mutation + # def print_a # def print_a + # puts self.a # puts a + # end # end + # + # def a + # :bar + # end + # end + # + # There will not be any exception so the mutant is not killed and such calls where + # implicit receiver should be used will be spotted. + # + # @reutrn [undefined] + # + # @api private + # + def emit_implicit_self_receiver + return unless self? mutant = dup_node - mutant.privately = false + mutant.privately = true # TODO: Fix rubinius to allow this as an attr_accessor - mutant.instance_variable_set(:@vcall_style,false) + mutant.instance_variable_set(:@vcall_style,true) emit_safe(mutant) end @@ -56,7 +82,7 @@ module Mutant # @api private # def dispatch - emit_explicit_self_receiver + emit_implicit_self_receiver end class SendWithArguments < Call @@ -72,7 +98,7 @@ module Mutant # @api private # def dispatch - emit_explicit_self_receiver + super end end end diff --git a/spec/unit/mutant/mutator/block/class_methods/each_spec.rb b/spec/unit/mutant/mutator/block/mutation_spec.rb similarity index 63% rename from spec/unit/mutant/mutator/block/class_methods/each_spec.rb rename to spec/unit/mutant/mutator/block/mutation_spec.rb index 00c4fb7f..37fd24d5 100644 --- a/spec/unit/mutant/mutator/block/class_methods/each_spec.rb +++ b/spec/unit/mutant/mutator/block/mutation_spec.rb @@ -1,8 +1,8 @@ require 'spec_helper' -describe Mutant::Mutator::Block, '.each' do +describe Mutant::Mutator, 'block' do # Two send operations - let(:source) { "foo\nbar" } + let(:source) { "self.foo\nself.bar" } let(:mutations) do mutations = [] @@ -12,8 +12,8 @@ describe Mutant::Mutator::Block, '.each' do mutations << "self.foo\nbar" ## Remove statement in block - mutations << [:block, 'foo'.to_sexp] - mutations << [:block, 'bar'.to_sexp] + mutations << [:block, 'self.foo'.to_sexp] + mutations << [:block, 'self.bar'.to_sexp] end it_should_behave_like 'a mutation enumerator method' diff --git a/spec/unit/mutant/mutator/call/mutation_spec.rb b/spec/unit/mutant/mutator/call/mutation_spec.rb index 4f2f5e37..67f73e59 100644 --- a/spec/unit/mutant/mutator/call/mutation_spec.rb +++ b/spec/unit/mutant/mutator/call/mutation_spec.rb @@ -2,46 +2,52 @@ require 'spec_helper' describe Mutant::Mutator, 'call' do context 'send without arguments' do - context 'to self' do + context 'with self as receiver' do - context 'implict' do + context 'implicit' do let(:source) { 'foo' } - let(:mutations) do - mutations = [] - # with explicit receiver (not send privately) - mutations << 'self.foo' - end - - it_should_behave_like 'a mutation enumerator method' + it_should_behave_like 'a noop mutation enumerator method' end context 'explict' do let(:source) { 'self.foo' } - it_should_behave_like 'a noop mutation enumerator method' + let(:mutations) do + mutations = [] + # with implicit receiver (send privately) + mutations << 'foo' + end + + it_should_behave_like 'a mutation enumerator method' end end + + context 'to some object' do + let(:source) { '1.foo' } + + it_should_behave_like 'a noop mutation enumerator method' + end end context 'send with arguments' do - context 'to self' do + context 'with self as receiver' do context 'implicit' do let(:source) { 'foo(1)' } - let(:mutations) do - mutations = [] - # with explicit receiver (not send privately) - mutations << 'self.foo(1)' - end - - it_should_behave_like 'a mutation enumerator method' + it_should_behave_like 'a noop mutation enumerator method' end context 'explicit' do let(:source) { 'self.foo(1)' } - it_should_behave_like 'a noop mutation enumerator method' + let(:mutations) do + mutations = [] + # with implicit receiver (send privately) + mutations << 'foo(1)' + end + + it_should_behave_like 'a mutation enumerator method' end end end