184 lines
4.4 KiB
Ruby
184 lines
4.4 KiB
Ruby
# rubocop:disable ClassAndModuleChildren
|
|
RSpec.describe Mutant::Matcher::Method::Instance do
|
|
|
|
let(:env) { Fixtures::TEST_ENV }
|
|
let(:reporter) { Fixtures::TEST_CONFIG.reporter }
|
|
|
|
describe '#each' do
|
|
subject { object.each { |subject| yields << subject } }
|
|
|
|
let(:object) { described_class.build(env, scope, method) }
|
|
let(:method) { scope.instance_method(method_name) }
|
|
let(:yields) { [] }
|
|
let(:namespace) { self.class }
|
|
let(:scope) { self.class::Foo }
|
|
let(:type) { :def }
|
|
let(:method_name) { :bar }
|
|
let(:method_arity) { 0 }
|
|
|
|
def name
|
|
node.children[0]
|
|
end
|
|
|
|
def arguments
|
|
node.children[1]
|
|
end
|
|
|
|
context 'when method is defined without source location' do
|
|
let(:scope) { Module }
|
|
let(:method) { scope.instance_method(:object_id) }
|
|
|
|
it 'does not emit matcher' do
|
|
subject
|
|
expect(yields.length).to be(0)
|
|
end
|
|
|
|
it 'does warn' do
|
|
subject
|
|
expect(reporter.warn_calls.last).to(
|
|
eql("#{method.inspect} does not have valid source location unable to emit matcher")
|
|
)
|
|
end
|
|
end
|
|
|
|
context 'when method is defined once' do
|
|
let(:base) { __LINE__ }
|
|
class self::Foo
|
|
def bar; end
|
|
end
|
|
|
|
let(:method_line) { 2 }
|
|
|
|
it_should_behave_like 'a method matcher'
|
|
end
|
|
|
|
context 'when method is defined once with a memoizer' do
|
|
let(:base) { __LINE__ }
|
|
class self::Foo
|
|
def bar; end
|
|
include Adamantium
|
|
memoize :bar
|
|
end
|
|
|
|
let(:method_line) { 2 }
|
|
|
|
it_should_behave_like 'a method matcher'
|
|
end
|
|
|
|
context 'when method is defined multiple times' do
|
|
context 'on different lines' do
|
|
let(:base) { __LINE__ }
|
|
class self::Foo
|
|
def bar
|
|
end
|
|
|
|
def bar(_arg)
|
|
end
|
|
end
|
|
|
|
let(:method_line) { 5 }
|
|
let(:method_arity) { 1 }
|
|
|
|
it_should_behave_like 'a method matcher'
|
|
end
|
|
|
|
context 'on the same line' do
|
|
let(:base) { __LINE__ }
|
|
class self::Foo
|
|
def bar; end; def bar(_arg); end
|
|
end
|
|
|
|
let(:method_line) { 2 }
|
|
let(:method_arity) { 1 }
|
|
|
|
it_should_behave_like 'a method matcher'
|
|
end
|
|
|
|
context 'on the same line with different scope' do
|
|
let(:base) { __LINE__ }
|
|
class self::Foo
|
|
def self.bar; end; def bar(_arg); end
|
|
end
|
|
|
|
let(:method_line) { 2 }
|
|
let(:method_arity) { 1 }
|
|
|
|
it_should_behave_like 'a method matcher'
|
|
end
|
|
|
|
context 'when nested' do
|
|
let(:pattern) { 'Foo::Bar#baz' }
|
|
|
|
context 'in class' do
|
|
let(:base) { __LINE__ }
|
|
class self::Foo
|
|
class Bar
|
|
def baz
|
|
end
|
|
end
|
|
end
|
|
|
|
let(:method_line) { 3 }
|
|
let(:method_name) { :baz }
|
|
let(:scope) { self.class::Foo::Bar }
|
|
|
|
it_should_behave_like 'a method matcher'
|
|
end
|
|
|
|
context 'in module' do
|
|
let(:base) { __LINE__ }
|
|
module self::Foo
|
|
class Bar
|
|
def baz
|
|
end
|
|
end
|
|
end
|
|
|
|
let(:method_line) { 3 }
|
|
let(:method_name) { :baz }
|
|
let(:scope) { self.class::Foo::Bar }
|
|
|
|
it_should_behave_like 'a method matcher'
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
describe '.build' do
|
|
let(:object) { described_class }
|
|
|
|
subject { object.build(env, scope, method) }
|
|
|
|
let(:scope) do
|
|
Class.new do
|
|
include Adamantium
|
|
|
|
def foo
|
|
end
|
|
memoize :foo
|
|
|
|
def bar
|
|
end
|
|
end
|
|
end
|
|
|
|
let(:method) do
|
|
scope.instance_method(method_name)
|
|
end
|
|
|
|
context 'with adamantium infected scope' do
|
|
context 'with unmemoized method' do
|
|
let(:method_name) { :bar }
|
|
|
|
it { should eql(described_class.new(env, scope, method)) }
|
|
end
|
|
|
|
context 'with memoized method' do
|
|
let(:method_name) { :foo }
|
|
|
|
it { should eql(described_class::Memoized.new(env, scope, method)) }
|
|
end
|
|
end
|
|
end
|
|
end
|