Correct mutations of send to self

* Invert the behaviour as this direction of mutation does make sense.
This commit is contained in:
Markus Schirp 2012-08-01 14:54:49 +02:00
parent 49b13bc1d8
commit 640ce5360e
3 changed files with 60 additions and 28 deletions

View file

@ -41,11 +41,37 @@ module Mutant
receiver.kind_of?(Rubinius::AST::Self) receiver.kind_of?(Rubinius::AST::Self)
end 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 = dup_node
mutant.privately = false mutant.privately = true
# TODO: Fix rubinius to allow this as an attr_accessor # 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) emit_safe(mutant)
end end
@ -56,7 +82,7 @@ module Mutant
# @api private # @api private
# #
def dispatch def dispatch
emit_explicit_self_receiver emit_implicit_self_receiver
end end
class SendWithArguments < Call class SendWithArguments < Call
@ -72,7 +98,7 @@ module Mutant
# @api private # @api private
# #
def dispatch def dispatch
emit_explicit_self_receiver super
end end
end end
end end

View file

@ -1,8 +1,8 @@
require 'spec_helper' require 'spec_helper'
describe Mutant::Mutator::Block, '.each' do describe Mutant::Mutator, 'block' do
# Two send operations # Two send operations
let(:source) { "foo\nbar" } let(:source) { "self.foo\nself.bar" }
let(:mutations) do let(:mutations) do
mutations = [] mutations = []
@ -12,8 +12,8 @@ describe Mutant::Mutator::Block, '.each' do
mutations << "self.foo\nbar" mutations << "self.foo\nbar"
## Remove statement in block ## Remove statement in block
mutations << [:block, 'foo'.to_sexp] mutations << [:block, 'self.foo'.to_sexp]
mutations << [:block, 'bar'.to_sexp] mutations << [:block, 'self.bar'.to_sexp]
end end
it_should_behave_like 'a mutation enumerator method' it_should_behave_like 'a mutation enumerator method'

View file

@ -2,46 +2,52 @@ require 'spec_helper'
describe Mutant::Mutator, 'call' do describe Mutant::Mutator, 'call' do
context 'send without arguments' 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(:source) { 'foo' }
let(:mutations) do it_should_behave_like 'a noop mutation enumerator method'
mutations = []
# with explicit receiver (not send privately)
mutations << 'self.foo'
end
it_should_behave_like 'a mutation enumerator method'
end end
context 'explict' do context 'explict' do
let(:source) { 'self.foo' } 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
end end
context 'to some object' do
let(:source) { '1.foo' }
it_should_behave_like 'a noop mutation enumerator method'
end
end end
context 'send with arguments' do context 'send with arguments' do
context 'to self' do context 'with self as receiver' do
context 'implicit' do context 'implicit' do
let(:source) { 'foo(1)' } let(:source) { 'foo(1)' }
let(:mutations) do it_should_behave_like 'a noop mutation enumerator method'
mutations = []
# with explicit receiver (not send privately)
mutations << 'self.foo(1)'
end
it_should_behave_like 'a mutation enumerator method'
end end
context 'explicit' do context 'explicit' do
let(:source) { 'self.foo(1)' } 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 end
end end