diff --git a/spec/integration/mutant/method_matching_spec.rb b/spec/integration/mutant/method_matching_spec.rb deleted file mode 100644 index 2fc9af54..00000000 --- a/spec/integration/mutant/method_matching_spec.rb +++ /dev/null @@ -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 diff --git a/spec/shared/method_matcher_behavior.rb b/spec/shared/method_matcher_behavior.rb new file mode 100644 index 00000000..ca062614 --- /dev/null +++ b/spec/shared/method_matcher_behavior.rb @@ -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 diff --git a/spec/unit/mutant/matcher/method/instance/each_spec.rb b/spec/unit/mutant/matcher/method/instance/each_spec.rb index f1aeb37e..bbac59f6 100644 --- a/spec/unit/mutant/matcher/method/instance/each_spec.rb +++ b/spec/unit/mutant/matcher/method/instance/each_spec.rb @@ -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 diff --git a/spec/unit/mutant/matcher/method/singleton/each_spec.rb b/spec/unit/mutant/matcher/method/singleton/each_spec.rb new file mode 100644 index 00000000..58363eb0 --- /dev/null +++ b/spec/unit/mutant/matcher/method/singleton/each_spec.rb @@ -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