Add unit spec for singleton method matchers
Also remove old method integration spec
This commit is contained in:
parent
d040864e93
commit
ecb5be355f
4 changed files with 142 additions and 351 deletions
|
@ -1,311 +0,0 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe Mutant, 'method matching' do
|
||||
after do
|
||||
if defined?(::Foo)
|
||||
Object.send(:remove_const, 'Foo')
|
||||
end
|
||||
end
|
||||
|
||||
this_example = 'Mutant method matching'
|
||||
|
||||
shared_examples_for this_example do
|
||||
subject { Mutant::CLI::Classifier.build(pattern).to_a }
|
||||
|
||||
let(:values) { defaults.merge(expectation) }
|
||||
|
||||
let(:method_name) { values.fetch(:method_name) }
|
||||
let(:method_line) { values.fetch(:method_line) }
|
||||
let(:method_arity) { values.fetch(:method_arity) }
|
||||
let(:scope) { values.fetch(:scope) }
|
||||
let(:node_class) { values.fetch(:node_class) }
|
||||
|
||||
let(:node) { mutation_subject.node }
|
||||
let(:context) { mutation_subject.context }
|
||||
let(:mutation_subject) { subject.first }
|
||||
|
||||
it 'should return one subject' do
|
||||
subject.size.should be(1)
|
||||
end
|
||||
|
||||
it 'should have correct method name' do
|
||||
name(node).should eql(method_name)
|
||||
end
|
||||
|
||||
it 'should have correct line number' do
|
||||
node.line.should eql(method_line)
|
||||
end
|
||||
|
||||
it 'should have correct arity' do
|
||||
arguments(node).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
|
||||
|
||||
before do
|
||||
#eval(body, TOPLEVEL_BINDING, __FILE__, 0)
|
||||
eval(body)
|
||||
File.stub(:read => body)
|
||||
end
|
||||
|
||||
let(:defaults) { {} }
|
||||
|
||||
context 'on instance methods' do
|
||||
def name(node)
|
||||
node.name
|
||||
end
|
||||
|
||||
def arguments(node)
|
||||
node.arguments
|
||||
end
|
||||
|
||||
let(:pattern) { 'Foo#bar' }
|
||||
let(:defaults) do
|
||||
{
|
||||
:scope => Foo,
|
||||
:node_class => Rubinius::AST::Define,
|
||||
:method_name => :bar,
|
||||
:method_arity => 0
|
||||
}
|
||||
end
|
||||
|
||||
context 'when method is defined once' do
|
||||
let(:body) do
|
||||
<<-RUBY
|
||||
class Foo
|
||||
def bar; end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
let(:expectation) do
|
||||
{ :method_line => 2 }
|
||||
end
|
||||
|
||||
it_should_behave_like this_example
|
||||
end
|
||||
|
||||
context 'when method is defined multiple times' do
|
||||
context 'on differend lines' do
|
||||
let(:body) do
|
||||
<<-RUBY
|
||||
class Foo
|
||||
def bar; end
|
||||
def bar(arg); end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
let(:expectation) do
|
||||
{
|
||||
:method_line => 3,
|
||||
:method_arity => 1
|
||||
}
|
||||
end
|
||||
|
||||
it_should_behave_like this_example
|
||||
end
|
||||
|
||||
context 'on the same line' do
|
||||
let(:body) do
|
||||
<<-RUBY
|
||||
class Foo
|
||||
def bar; end; def bar(arg); end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
let(:expectation) do
|
||||
{
|
||||
:method_line => 2,
|
||||
:method_arity => 1
|
||||
}
|
||||
end
|
||||
|
||||
it_should_behave_like this_example
|
||||
end
|
||||
|
||||
context 'on the same line with differend scope' do
|
||||
let(:body) do
|
||||
<<-RUBY
|
||||
class Foo
|
||||
def self.bar; end; def bar(arg); end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
let(:expectation) do
|
||||
{
|
||||
:method_line => 2,
|
||||
:method_arity => 1
|
||||
}
|
||||
end
|
||||
|
||||
it_should_behave_like this_example
|
||||
end
|
||||
|
||||
context 'when nested' do
|
||||
let(:pattern) { 'Foo::Bar#baz' }
|
||||
|
||||
context 'in class' do
|
||||
let(:body) do
|
||||
<<-RUBY
|
||||
class Foo
|
||||
class Bar
|
||||
def baz; end
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
let(:expectation) do
|
||||
{
|
||||
:method_line => 3,
|
||||
:method_name => :baz,
|
||||
:scope => Foo::Bar
|
||||
}
|
||||
end
|
||||
|
||||
it_should_behave_like this_example
|
||||
end
|
||||
|
||||
context 'in module' do
|
||||
let(:body) do
|
||||
<<-RUBY
|
||||
module Foo
|
||||
class Bar
|
||||
def baz; end
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
let(:expectation) do
|
||||
{
|
||||
:method_line => 3,
|
||||
:method_name => :baz,
|
||||
:scope => Foo::Bar
|
||||
}
|
||||
end
|
||||
|
||||
it_should_behave_like this_example
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'on singleton methods' do
|
||||
let(:pattern) { 'Foo.bar' }
|
||||
let(:defaults) do
|
||||
{
|
||||
:scope => Foo,
|
||||
:node_class => Rubinius::AST::DefineSingleton,
|
||||
:method_arity => 0
|
||||
}
|
||||
end
|
||||
|
||||
def name(node)
|
||||
node.body.name
|
||||
end
|
||||
|
||||
def arguments(node)
|
||||
node.body.arguments
|
||||
end
|
||||
|
||||
context 'when defined on self' do
|
||||
let(:body) do
|
||||
<<-RUBY
|
||||
class Foo
|
||||
def self.bar; end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
|
||||
let(:expectation) do
|
||||
{
|
||||
:method_name => :bar,
|
||||
:method_line => 2,
|
||||
}
|
||||
end
|
||||
|
||||
it_should_behave_like this_example
|
||||
end
|
||||
|
||||
context 'when defined on constant' do
|
||||
|
||||
context 'inside namespace' do
|
||||
let(:body) do
|
||||
<<-RUBY
|
||||
class Foo
|
||||
def Foo.bar; end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
|
||||
let(:expectation) do
|
||||
{
|
||||
:method_name => :bar,
|
||||
:method_line => 2,
|
||||
}
|
||||
end
|
||||
|
||||
it_should_behave_like this_example
|
||||
end
|
||||
|
||||
context 'outside namespace' do
|
||||
let(:body) do
|
||||
<<-RUBY
|
||||
class Foo; end;
|
||||
def Foo.bar; end
|
||||
RUBY
|
||||
end
|
||||
|
||||
|
||||
let(:expectation) do
|
||||
{
|
||||
:method_name => :bar,
|
||||
:method_line => 2,
|
||||
}
|
||||
end
|
||||
|
||||
it_should_behave_like this_example
|
||||
end
|
||||
end
|
||||
|
||||
context 'when defined multiple times in the same line' do
|
||||
context 'with method on differend scope' do
|
||||
let(:body) do
|
||||
<<-RUBY
|
||||
module Foo; end
|
||||
|
||||
module Bar
|
||||
def self.baz; end; def Foo.baz(arg); end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
let(:pattern) { 'Bar.baz' }
|
||||
|
||||
let(:expectation) do
|
||||
{
|
||||
:scope => Bar,
|
||||
:method_name => :baz,
|
||||
:method_line => 4,
|
||||
:method_arity => 0
|
||||
}
|
||||
end
|
||||
|
||||
it_should_behave_like this_example
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
35
spec/shared/method_matcher_behavior.rb
Normal file
35
spec/shared/method_matcher_behavior.rb
Normal file
|
@ -0,0 +1,35 @@
|
|||
shared_examples_for 'a method matcher' 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_behave_like 'an #each method'
|
||||
|
||||
it 'should have correct method name' do
|
||||
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
|
||||
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
|
|
@ -14,44 +14,18 @@ describe Mutant::Matcher::Method::Instance, '#each' do
|
|||
|
||||
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 }
|
||||
|
||||
def name
|
||||
node.name
|
||||
end
|
||||
|
||||
def arguments
|
||||
node.arguments
|
||||
end
|
||||
|
||||
context 'when method is defined once' do
|
||||
let(:base) { __LINE__ }
|
||||
class self::Foo
|
||||
|
@ -60,7 +34,7 @@ describe Mutant::Matcher::Method::Instance, '#each' do
|
|||
|
||||
let(:method_line) { 2 }
|
||||
|
||||
it_should_behave_like 'a method match'
|
||||
it_should_behave_like 'a method matcher'
|
||||
end
|
||||
|
||||
context 'when method is defined multiple times' do
|
||||
|
@ -74,7 +48,7 @@ describe Mutant::Matcher::Method::Instance, '#each' do
|
|||
let(:method_line) { 3 }
|
||||
let(:method_arity) { 1 }
|
||||
|
||||
it_should_behave_like 'a method match'
|
||||
it_should_behave_like 'a method matcher'
|
||||
end
|
||||
|
||||
context 'on the same line' do
|
||||
|
@ -86,7 +60,7 @@ describe Mutant::Matcher::Method::Instance, '#each' do
|
|||
let(:method_line) { 2 }
|
||||
let(:method_arity) { 1 }
|
||||
|
||||
it_should_behave_like 'a method match'
|
||||
it_should_behave_like 'a method matcher'
|
||||
end
|
||||
|
||||
context 'on the same line with differend scope' do
|
||||
|
@ -98,7 +72,7 @@ describe Mutant::Matcher::Method::Instance, '#each' do
|
|||
let(:method_line) { 2 }
|
||||
let(:method_arity) { 1 }
|
||||
|
||||
it_should_behave_like 'a method match'
|
||||
it_should_behave_like 'a method matcher'
|
||||
end
|
||||
|
||||
context 'when nested' do
|
||||
|
@ -116,7 +90,7 @@ describe Mutant::Matcher::Method::Instance, '#each' do
|
|||
let(:method_name) { :baz }
|
||||
let(:scope) { self.class::Foo::Bar }
|
||||
|
||||
it_should_behave_like 'a method match'
|
||||
it_should_behave_like 'a method matcher'
|
||||
end
|
||||
|
||||
context 'in module' do
|
||||
|
@ -131,7 +105,7 @@ describe Mutant::Matcher::Method::Instance, '#each' do
|
|||
let(:method_name) { :baz }
|
||||
let(:scope) { self.class::Foo::Bar }
|
||||
|
||||
it_should_behave_like 'a method match'
|
||||
it_should_behave_like 'a method matcher'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
93
spec/unit/mutant/matcher/method/singleton/each_spec.rb
Normal file
93
spec/unit/mutant/matcher/method/singleton/each_spec.rb
Normal file
|
@ -0,0 +1,93 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe Mutant::Matcher::Method::Singleton, '#each' do
|
||||
let(:object) { described_class.new(scope, method) }
|
||||
let(:method) { scope.method(method_name) }
|
||||
|
||||
let(:yields) { [] }
|
||||
|
||||
let(:namespace) do
|
||||
klass = self.class
|
||||
end
|
||||
|
||||
let(:scope) { self.class::Foo }
|
||||
|
||||
subject { object.each { |subject| yields << subject } }
|
||||
|
||||
let(:node_class) { Rubinius::AST::DefineSingleton }
|
||||
let(:method_arity) { 0 }
|
||||
|
||||
def name
|
||||
node.body.name
|
||||
end
|
||||
|
||||
def arguments
|
||||
node.body.arguments
|
||||
end
|
||||
|
||||
context 'on singleton methods' do
|
||||
|
||||
context 'when defined on self' do
|
||||
let(:base) { __LINE__ }
|
||||
class self::Foo
|
||||
def self.bar; end
|
||||
end
|
||||
|
||||
let(:method_name) { :bar }
|
||||
let(:method_line) { 2 }
|
||||
|
||||
it_should_behave_like 'a method matcher'
|
||||
end
|
||||
|
||||
context 'when defined on constant' do
|
||||
|
||||
context 'inside namespace' do
|
||||
let(:base) { __LINE__ }
|
||||
module self::Namespace
|
||||
class Foo
|
||||
def Foo.bar; end
|
||||
end
|
||||
end
|
||||
|
||||
let(:scope) { self.class::Namespace::Foo }
|
||||
let(:method_name) { :bar }
|
||||
let(:method_line) { 3 }
|
||||
|
||||
it_should_behave_like 'a method matcher'
|
||||
end
|
||||
|
||||
context 'outside namespace' do
|
||||
let(:base) { __LINE__ }
|
||||
module self::Namespace
|
||||
class Foo; end;
|
||||
def Foo.bar; end
|
||||
end
|
||||
|
||||
let(:method_name) { :bar }
|
||||
let(:method_line) { 3 }
|
||||
let(:scope) { self.class::Namespace::Foo }
|
||||
|
||||
it_should_behave_like 'a method matcher'
|
||||
end
|
||||
end
|
||||
|
||||
context 'when defined multiple times in the same line' do
|
||||
context 'with method on differend scope' do
|
||||
let(:base) { __LINE__ }
|
||||
module self::Namespace
|
||||
module Foo; end
|
||||
module Bar
|
||||
def self.baz; end; def Foo.baz(arg); end
|
||||
end
|
||||
end
|
||||
|
||||
let(:scope) { self.class::Namespace::Bar }
|
||||
let(:method_name) { :baz }
|
||||
let(:method_line) { 4 }
|
||||
let(:method_arity) { 0 }
|
||||
|
||||
it_should_behave_like 'a method matcher'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Add table
Reference in a new issue