Refactor method matcher
And add proper unit specs
This commit is contained in:
parent
124d44d398
commit
d040864e93
2 changed files with 150 additions and 40 deletions
|
@ -2,7 +2,7 @@ module Mutant
|
||||||
class Matcher
|
class Matcher
|
||||||
# Matcher for subjects that are a specific method
|
# Matcher for subjects that are a specific method
|
||||||
class Method < self
|
class Method < self
|
||||||
include Adamantium::Flat, Equalizer.new(:identification)
|
include Adamantium::Flat, Concord.new(:scope, :method)
|
||||||
|
|
||||||
# Methods within rbx kernel directory are precompiled and their source
|
# Methods within rbx kernel directory are precompiled and their source
|
||||||
# cannot be accessed via reading source location
|
# cannot be accessed via reading source location
|
||||||
|
@ -29,47 +29,8 @@ module Mutant
|
||||||
self
|
self
|
||||||
end
|
end
|
||||||
|
|
||||||
# Return method
|
|
||||||
#
|
|
||||||
# @return [UnboundMethod, Method]
|
|
||||||
#
|
|
||||||
# @api private
|
|
||||||
#
|
|
||||||
attr_reader :method
|
|
||||||
|
|
||||||
# Return scope
|
|
||||||
#
|
|
||||||
# @return [Class|Module]
|
|
||||||
#
|
|
||||||
# @api private
|
|
||||||
#
|
|
||||||
attr_reader :scope
|
|
||||||
|
|
||||||
# Return method name
|
|
||||||
#
|
|
||||||
# @return [String]
|
|
||||||
#
|
|
||||||
# @api private
|
|
||||||
#
|
|
||||||
def method_name
|
|
||||||
method.name
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
# Initialize method filter
|
|
||||||
#
|
|
||||||
# @param [Class|Module] scope
|
|
||||||
# @param [Method, UnboundMethod] method
|
|
||||||
#
|
|
||||||
# @return [undefined]
|
|
||||||
#
|
|
||||||
# @api private
|
|
||||||
#
|
|
||||||
def initialize(scope, method)
|
|
||||||
@scope, @method = scope, method
|
|
||||||
end
|
|
||||||
|
|
||||||
# Test if method is skipped
|
# Test if method is skipped
|
||||||
#
|
#
|
||||||
# @return [true]
|
# @return [true]
|
||||||
|
@ -90,6 +51,16 @@ module Mutant
|
||||||
false
|
false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Return method name
|
||||||
|
#
|
||||||
|
# @return [String]
|
||||||
|
#
|
||||||
|
# @api private
|
||||||
|
#
|
||||||
|
def method_name
|
||||||
|
method.name
|
||||||
|
end
|
||||||
|
|
||||||
# Return context
|
# Return context
|
||||||
#
|
#
|
||||||
# @return [Context::Scope]
|
# @return [Context::Scope]
|
||||||
|
@ -171,6 +142,7 @@ module Mutant
|
||||||
end
|
end
|
||||||
last_match
|
last_match
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
138
spec/unit/mutant/matcher/method/instance/each_spec.rb
Normal file
138
spec/unit/mutant/matcher/method/instance/each_spec.rb
Normal file
|
@ -0,0 +1,138 @@
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe Mutant::Matcher::Method::Instance, '#each' do
|
||||||
|
let(:object) { described_class.new(scope, method) }
|
||||||
|
let(:method) { scope.instance_method(method_name) }
|
||||||
|
|
||||||
|
let(:yields) { [] }
|
||||||
|
|
||||||
|
let(:namespace) do
|
||||||
|
klass = self.class
|
||||||
|
end
|
||||||
|
|
||||||
|
let(:scope) { self.class::Foo }
|
||||||
|
|
||||||
|
subject { object.each { |subject| yields << subject } }
|
||||||
|
|
||||||
|
shared_examples_for 'a method match' do
|
||||||
|
before do
|
||||||
|
subject
|
||||||
|
end
|
||||||
|
|
||||||
|
let(:node) { mutation_subject.node }
|
||||||
|
let(:context) { mutation_subject.context }
|
||||||
|
let(:mutation_subject) { yields.first }
|
||||||
|
|
||||||
|
it 'should return one subject' do
|
||||||
|
yields.size.should be(1)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should have correct method name' do
|
||||||
|
node.name.should eql(method_name)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should have correct line number' do
|
||||||
|
(node.line - base).should eql(method_line)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should have correct arity' do
|
||||||
|
node.arguments.required.length.should eql(method_arity)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should have correct scope in context' do
|
||||||
|
context.send(:scope).should eql(scope)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should have the correct node class' do
|
||||||
|
node.should be_a(node_class)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
let(:node_class) { Rubinius::AST::Define }
|
||||||
|
let(:method_name) { :bar }
|
||||||
|
let(:method_arity) { 0 }
|
||||||
|
|
||||||
|
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 match'
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when method is defined multiple times' do
|
||||||
|
context 'on differend lines' do
|
||||||
|
let(:base) { __LINE__ }
|
||||||
|
class self::Foo
|
||||||
|
def bar; end
|
||||||
|
def bar(arg); end
|
||||||
|
end
|
||||||
|
|
||||||
|
let(:method_line) { 3 }
|
||||||
|
let(:method_arity) { 1 }
|
||||||
|
|
||||||
|
it_should_behave_like 'a method match'
|
||||||
|
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 match'
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'on the same line with differend 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 match'
|
||||||
|
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 match'
|
||||||
|
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 match'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in a new issue