Skip to content

Commit

Permalink
Correct mutations of send to self
Browse files Browse the repository at this point in the history
* Invert the behaviour as this direction of mutation does make sense.
  • Loading branch information
Markus Schirp committed Aug 1, 2012
1 parent 49b13bc commit 640ce53
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 26 deletions.
36 changes: 31 additions & 5 deletions lib/mutant/mutator/call.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,37 @@ def self?
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

Expand All @@ -56,7 +82,7 @@ def emit_explicit_self_receiver
# @api private
#
def dispatch
emit_explicit_self_receiver
emit_implicit_self_receiver
end

class SendWithArguments < Call
Expand All @@ -72,7 +98,7 @@ class SendWithArguments < Call
# @api private
#
def dispatch
emit_explicit_self_receiver
super
end
end
end
Expand Down
Original file line number Diff line number Diff line change
@@ -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 = []
Expand All @@ -12,8 +12,8 @@
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'
Expand Down
40 changes: 23 additions & 17 deletions spec/unit/mutant/mutator/call/mutation_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,46 +2,52 @@

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' }

it_should_behave_like 'a noop mutation enumerator method'
end

context 'explict' do
let(:source) { 'self.foo' }

let(:mutations) do
mutations = []
# with explicit receiver (not send privately)
mutations << 'self.foo'
# with implicit receiver (send privately)
mutations << 'foo'
end

it_should_behave_like 'a mutation enumerator method'
end
end

context 'explict' do
let(:source) { 'self.foo' }
context 'to some object' do
let(:source) { '1.foo' }

it_should_behave_like 'a noop mutation enumerator method'
end
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
Expand Down

0 comments on commit 640ce53

Please sign in to comment.