Add method matcher infrastructure
Needs more specs for sure. Especially edge cases.
This commit is contained in:
		
							parent
							
								
									ef472cef20
								
							
						
					
					
						commit
						df6ccafeab
					
				
					 20 changed files with 437 additions and 2 deletions
				
			
		
							
								
								
									
										2
									
								
								.gitignore
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
										
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,2 @@
 | 
			
		|||
/.rbx
 | 
			
		||||
/Gemfile.lock
 | 
			
		||||
							
								
								
									
										3
									
								
								Gemfile
									
										
									
									
									
								
							
							
						
						
									
										3
									
								
								Gemfile
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -4,6 +4,9 @@ source 'https://rubygems.org'
 | 
			
		|||
 | 
			
		||||
gemspec
 | 
			
		||||
 | 
			
		||||
# For Veritas::Immutable, will be extracted soon
 | 
			
		||||
gem 'veritas', :git => 'https://github.com/dkubb/veritas'
 | 
			
		||||
 | 
			
		||||
group :development do
 | 
			
		||||
  gem 'rake',    '~> 0.9.2'
 | 
			
		||||
  gem 'rspec',   '~> 1.3.2'
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,6 +7,13 @@ GIT
 | 
			
		|||
      ruby_parser (~> 2.0)
 | 
			
		||||
      sexp_processor (~> 3.0)
 | 
			
		||||
 | 
			
		||||
GIT
 | 
			
		||||
  remote: https://github.com/dkubb/veritas
 | 
			
		||||
  revision: 4654c1bc61b18938c38a5e3c2f599e14adda4991
 | 
			
		||||
  specs:
 | 
			
		||||
    veritas (0.0.7)
 | 
			
		||||
      backports (~> 2.6.1)
 | 
			
		||||
 | 
			
		||||
PATH
 | 
			
		||||
  remote: .
 | 
			
		||||
  specs:
 | 
			
		||||
| 
						 | 
				
			
			@ -145,6 +152,7 @@ DEPENDENCIES
 | 
			
		|||
  roodi (~> 2.1.0)
 | 
			
		||||
  rspec (~> 1.3.2)
 | 
			
		||||
  ruby2ruby (= 1.2.2)
 | 
			
		||||
  veritas!
 | 
			
		||||
  yard (~> 0.8.1)
 | 
			
		||||
  yard-spellcheck (~> 0.1.5)
 | 
			
		||||
  yardstick (~> 0.5.0)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										6
									
								
								Rakefile
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								Rakefile
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,6 @@
 | 
			
		|||
require 'rake'
 | 
			
		||||
 | 
			
		||||
FileList['tasks/**/*.rake'].each { |task| import task }
 | 
			
		||||
 | 
			
		||||
desc 'Default: run all specs'
 | 
			
		||||
task :default => :spec
 | 
			
		||||
							
								
								
									
										3
									
								
								TODO
									
										
									
									
									
								
							
							
						
						
									
										3
									
								
								TODO
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -1,3 +1,4 @@
 | 
			
		|||
* Add a nice way to access the root ast to place the mutated ast nodes into.
 | 
			
		||||
* Get a rid of heckle and test mutant with mutant.
 | 
			
		||||
  This is interesting IMHO mutant should have another entry point
 | 
			
		||||
  that does not create the ::Mutant namespace, ideas:
 | 
			
		||||
| 
						 | 
				
			
			@ -8,4 +9,4 @@
 | 
			
		|||
  * Maybe the full clone could be generated by evaluating the full mutant ast
 | 
			
		||||
    a second time with a differend module name ast node.
 | 
			
		||||
* Get a rid of rspec-1 (can be done once we do not use heckle anymore)
 | 
			
		||||
* Add an infrastructure to whitelist components to heckle. 
 | 
			
		||||
* Add an infrastructure to whitelist for components to heckle on ruby-1.8.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										37
									
								
								lib/mutant.rb
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								lib/mutant.rb
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,37 @@
 | 
			
		|||
# For Veritas::Immutable will be extracted soon
 | 
			
		||||
require 'veritas'
 | 
			
		||||
 | 
			
		||||
# Library namespace
 | 
			
		||||
module Mutant
 | 
			
		||||
  # Helper method for raising not implemented exceptions
 | 
			
		||||
  #
 | 
			
		||||
  # @param [Object] object
 | 
			
		||||
  #   the object where method is not implemented
 | 
			
		||||
  #
 | 
			
		||||
  # @raise [NotImplementedError]
 | 
			
		||||
  #   raises a not implemented error with correct description
 | 
			
		||||
  #
 | 
			
		||||
  # @example
 | 
			
		||||
  #   class Foo
 | 
			
		||||
  #     def x
 | 
			
		||||
  #       Mutant.not_implemented(self)
 | 
			
		||||
  #     end
 | 
			
		||||
  #   end
 | 
			
		||||
  #
 | 
			
		||||
  #   Foo.new.x # raises NotImplementedError "Foo#x is not implemented"
 | 
			
		||||
  #
 | 
			
		||||
  # @return [undefined]
 | 
			
		||||
  #
 | 
			
		||||
  # @api private
 | 
			
		||||
  def self.not_implemented(object)
 | 
			
		||||
    method = caller(1).first[/`(.*)'/,1].to_sym
 | 
			
		||||
    delimiter = object.kind_of?(Module) ? '.' : '#'
 | 
			
		||||
    raise NotImplementedError,"#{object.class}#{delimiter}#{method} is not implemented"
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
require 'mutant/matcher'
 | 
			
		||||
require 'mutant/matcher/method'
 | 
			
		||||
require 'mutant/matcher/method/singleton'
 | 
			
		||||
require 'mutant/matcher/method/instance'
 | 
			
		||||
require 'mutant/matcher/method/classifier'
 | 
			
		||||
							
								
								
									
										14
									
								
								lib/mutant/matcher.rb
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								lib/mutant/matcher.rb
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,14 @@
 | 
			
		|||
module Mutant
 | 
			
		||||
  # Abstract filter for rubinius asts.
 | 
			
		||||
  class Matcher
 | 
			
		||||
    include Enumerable
 | 
			
		||||
 | 
			
		||||
    # Return each matched node
 | 
			
		||||
    #
 | 
			
		||||
    # @api private
 | 
			
		||||
    #
 | 
			
		||||
    def each
 | 
			
		||||
      Mutant.not_implemented(self)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										168
									
								
								lib/mutant/matcher/method.rb
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										168
									
								
								lib/mutant/matcher/method.rb
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,168 @@
 | 
			
		|||
module Mutant
 | 
			
		||||
  class Matcher
 | 
			
		||||
    # A filter for methods
 | 
			
		||||
    class Method < Matcher
 | 
			
		||||
      # Return constant name 
 | 
			
		||||
      #
 | 
			
		||||
      # @return [String]
 | 
			
		||||
      #
 | 
			
		||||
      # @api private
 | 
			
		||||
      #
 | 
			
		||||
      attr_reader :constant_name
 | 
			
		||||
 | 
			
		||||
      # Return method name
 | 
			
		||||
      #
 | 
			
		||||
      # @return [String]
 | 
			
		||||
      #
 | 
			
		||||
      # @api private
 | 
			
		||||
      #
 | 
			
		||||
      attr_reader :method_name
 | 
			
		||||
 | 
			
		||||
      # Initialize method filter
 | 
			
		||||
      # 
 | 
			
		||||
      # @param [String] constant_name
 | 
			
		||||
      # @param [String] method_name
 | 
			
		||||
      #
 | 
			
		||||
      # @return [undefined]
 | 
			
		||||
      #
 | 
			
		||||
      # @api private
 | 
			
		||||
      #
 | 
			
		||||
      def initialize(constant_name,method_name)
 | 
			
		||||
        @constant_name,@method_name = constant_name,method_name
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Parse a method string into filter
 | 
			
		||||
      #
 | 
			
		||||
      # @param [String] input
 | 
			
		||||
      #
 | 
			
		||||
      # @return [Matcher::Method]
 | 
			
		||||
      #
 | 
			
		||||
      # @api private
 | 
			
		||||
      #
 | 
			
		||||
      def self.parse(input)
 | 
			
		||||
        Classifier.run(input).filter
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Enumerate matches
 | 
			
		||||
      #
 | 
			
		||||
      # @return [Enumerable]
 | 
			
		||||
      #   returns enumerable when no block given
 | 
			
		||||
      #
 | 
			
		||||
      # @return [self]
 | 
			
		||||
      #   returns self when block given
 | 
			
		||||
      #
 | 
			
		||||
      # @api private
 | 
			
		||||
      #   
 | 
			
		||||
      def each
 | 
			
		||||
        return to_enum(__method__) unless block_given?
 | 
			
		||||
        yield root_node
 | 
			
		||||
        self
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Check if node is matched 
 | 
			
		||||
      #
 | 
			
		||||
      # @param [Rubinius::AST::Node]
 | 
			
		||||
      #
 | 
			
		||||
      # @return [true]
 | 
			
		||||
      #   returns true if node matches method
 | 
			
		||||
      #
 | 
			
		||||
      # @return [false]
 | 
			
		||||
      #   returns false if node NOT matches method
 | 
			
		||||
      #
 | 
			
		||||
      # @api private
 | 
			
		||||
      #
 | 
			
		||||
      def match?(node)
 | 
			
		||||
        node.line == source_file_line && node_class == node.class && node.name.to_s == method_name
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
    private
 | 
			
		||||
 | 
			
		||||
      # Return method
 | 
			
		||||
      # 
 | 
			
		||||
      # @return [UnboundMethod]
 | 
			
		||||
      #
 | 
			
		||||
      # @api private
 | 
			
		||||
      #
 | 
			
		||||
      def method
 | 
			
		||||
        Mutant.not_implemente(self)
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Return node classes this matcher matches
 | 
			
		||||
      #
 | 
			
		||||
      # @return [Enumerable]
 | 
			
		||||
      #
 | 
			
		||||
      # @api private
 | 
			
		||||
      #
 | 
			
		||||
      def node_classes
 | 
			
		||||
        Mutant.not_implemented(self)
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Return root node
 | 
			
		||||
      #
 | 
			
		||||
      # @return [Rubinus::AST::Node]
 | 
			
		||||
      #
 | 
			
		||||
      # @api private
 | 
			
		||||
      #
 | 
			
		||||
      def root_node
 | 
			
		||||
        root_node = nil
 | 
			
		||||
        ast.walk do |_,node|
 | 
			
		||||
          root_node = node if match?(node)
 | 
			
		||||
          true
 | 
			
		||||
        end
 | 
			
		||||
        root_node
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Return full ast
 | 
			
		||||
      #
 | 
			
		||||
      # @return [Rubinius::AST::Node]
 | 
			
		||||
      #
 | 
			
		||||
      # @api private
 | 
			
		||||
      #
 | 
			
		||||
      def ast
 | 
			
		||||
        File.read(source_filename).to_ast
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Return source filename
 | 
			
		||||
      #
 | 
			
		||||
      # @return [String]
 | 
			
		||||
      #
 | 
			
		||||
      # @api private
 | 
			
		||||
      #
 | 
			
		||||
      def source_filename
 | 
			
		||||
        source_location.first
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Return source file line
 | 
			
		||||
      #
 | 
			
		||||
      # @return [Integer]
 | 
			
		||||
      #
 | 
			
		||||
      # @api private
 | 
			
		||||
      #
 | 
			
		||||
      def source_file_line
 | 
			
		||||
        source_location.last
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Return source location
 | 
			
		||||
      #
 | 
			
		||||
      # @return [Array]
 | 
			
		||||
      #
 | 
			
		||||
      # @api private
 | 
			
		||||
      #
 | 
			
		||||
      def source_location
 | 
			
		||||
        method.source_location
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Return constant
 | 
			
		||||
      #
 | 
			
		||||
      # @return [Class|Module]
 | 
			
		||||
      #
 | 
			
		||||
      # @api private
 | 
			
		||||
      #
 | 
			
		||||
      def constant
 | 
			
		||||
        constant_name.split(/::/).inject(Object) do |context, name|
 | 
			
		||||
          context.const_get(name)
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										53
									
								
								lib/mutant/matcher/method/classifier.rb
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								lib/mutant/matcher/method/classifier.rb
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,53 @@
 | 
			
		|||
module Mutant
 | 
			
		||||
  class Matcher
 | 
			
		||||
    class Method < Matcher
 | 
			
		||||
      # A classifier for input strings
 | 
			
		||||
      class Classifier
 | 
			
		||||
        TABLE = {
 | 
			
		||||
          '.' => Matcher::Method::Singleton,
 | 
			
		||||
          '#' => Matcher::Method::Instance
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        SCOPE_FORMAT = Regexp.new('\A([^#.]+)(\.|#)(.+)\z')
 | 
			
		||||
 | 
			
		||||
        private_class_method :new
 | 
			
		||||
 | 
			
		||||
        def self.run(input)
 | 
			
		||||
          match = SCOPE_FORMAT.match(input)
 | 
			
		||||
          raise ArgumentError,"Cannot determine subject from #{input.inspect}" unless match
 | 
			
		||||
          new(match)
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        def filter
 | 
			
		||||
          scope.new(constant_name,method_name)
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
      private
 | 
			
		||||
 | 
			
		||||
        def initialize(match)
 | 
			
		||||
          @match = match
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        def constant_name
 | 
			
		||||
          @match[1]
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        def method_name
 | 
			
		||||
          @match[3]
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        def scope_name
 | 
			
		||||
          @match[2]
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        def scope
 | 
			
		||||
          TABLE.fetch(scope_name)
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        def method
 | 
			
		||||
          scope.method(method_name)
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										17
									
								
								lib/mutant/matcher/method/instance.rb
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								lib/mutant/matcher/method/instance.rb
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,17 @@
 | 
			
		|||
module Mutant
 | 
			
		||||
  class Matcher 
 | 
			
		||||
    class Method < Matcher
 | 
			
		||||
      # A instance method filter
 | 
			
		||||
      class Instance < Method
 | 
			
		||||
      private
 | 
			
		||||
        def method
 | 
			
		||||
          constant.instance_method(method_name)
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        def node_class
 | 
			
		||||
          Rubinius::AST::Define
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										17
									
								
								lib/mutant/matcher/method/singleton.rb
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								lib/mutant/matcher/method/singleton.rb
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,17 @@
 | 
			
		|||
module Mutant
 | 
			
		||||
  class Matcher
 | 
			
		||||
    class Method
 | 
			
		||||
      # A singleton method filter
 | 
			
		||||
      class Singleton < Method
 | 
			
		||||
      private
 | 
			
		||||
        def method
 | 
			
		||||
          constant.method(method_name)
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        def node_class
 | 
			
		||||
          Rubinius::AST::DefineSingleton
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										7
									
								
								spec/rcov.opts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								spec/rcov.opts
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,7 @@
 | 
			
		|||
--exclude-only "spec/,^/"
 | 
			
		||||
--sort coverage
 | 
			
		||||
--callsites
 | 
			
		||||
--xrefs
 | 
			
		||||
--profile
 | 
			
		||||
--text-summary
 | 
			
		||||
--failure-threshold 100
 | 
			
		||||
							
								
								
									
										7
									
								
								spec/shared/command_method_behavior.rb
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								spec/shared/command_method_behavior.rb
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,7 @@
 | 
			
		|||
# encoding: utf-8
 | 
			
		||||
 | 
			
		||||
shared_examples_for 'a command method' do
 | 
			
		||||
  it 'returns self' do
 | 
			
		||||
    should equal(object)
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										15
									
								
								spec/shared/each_method_behaviour.rb
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								spec/shared/each_method_behaviour.rb
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,15 @@
 | 
			
		|||
# encoding: utf-8
 | 
			
		||||
 | 
			
		||||
shared_examples_for 'an #each method' do
 | 
			
		||||
  it_should_behave_like 'a command method'
 | 
			
		||||
 | 
			
		||||
  context 'with no block' do
 | 
			
		||||
    subject { object.each }
 | 
			
		||||
 | 
			
		||||
    it { should be_instance_of(to_enum.class) }
 | 
			
		||||
 | 
			
		||||
    it 'yields the expected values' do
 | 
			
		||||
      subject.to_a.should eql(object.to_a)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										17
									
								
								spec/shared/hash_method_behavior.rb
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								spec/shared/hash_method_behavior.rb
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,17 @@
 | 
			
		|||
# encoding: utf-8
 | 
			
		||||
 | 
			
		||||
shared_examples_for 'a hash method' do
 | 
			
		||||
  it_should_behave_like 'an idempotent method'
 | 
			
		||||
 | 
			
		||||
  specification = proc do
 | 
			
		||||
    should be_instance_of(Fixnum)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  it 'is a fixnum' do
 | 
			
		||||
    instance_eval(&specification)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  it 'memoizes the hash code' do
 | 
			
		||||
    subject.should eql(object.memoized(:hash))
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										7
									
								
								spec/shared/idempotent_method_behavior.rb
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								spec/shared/idempotent_method_behavior.rb
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,7 @@
 | 
			
		|||
# encoding: utf-8
 | 
			
		||||
 | 
			
		||||
shared_examples_for 'an idempotent method' do
 | 
			
		||||
  it 'is idempotent' do
 | 
			
		||||
    should equal(instance_eval(&self.class.subject))
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										9
									
								
								spec/shared/invertible_method_behaviour.rb
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								spec/shared/invertible_method_behaviour.rb
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,9 @@
 | 
			
		|||
# encoding: utf-8
 | 
			
		||||
 | 
			
		||||
shared_examples_for 'an invertible method' do
 | 
			
		||||
  it_should_behave_like 'an idempotent method'
 | 
			
		||||
 | 
			
		||||
  it 'is invertible' do
 | 
			
		||||
    subject.inverse.should equal(object)
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			@ -8,5 +8,4 @@ require 'spec/autorun'
 | 
			
		|||
Dir[File.expand_path('../{support,shared}/**/*.rb', __FILE__)].each { |f| require f }
 | 
			
		||||
 | 
			
		||||
Spec::Runner.configure do |config|
 | 
			
		||||
  config.extend Spec::ExampleGroupMethods
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										14
									
								
								spec/unit/mutant/matcher/each_spec.rb
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								spec/unit/mutant/matcher/each_spec.rb
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,14 @@
 | 
			
		|||
require 'spec_helper'
 | 
			
		||||
 | 
			
		||||
# This spec is only present to ensure 100% test coverage.
 | 
			
		||||
# The code should not be triggered on runtime.
 | 
			
		||||
 | 
			
		||||
describe Mutant::Matcher,'#each' do
 | 
			
		||||
  subject { object.send(:each) }
 | 
			
		||||
 | 
			
		||||
  let(:object) { described_class.allocate }
 | 
			
		||||
 | 
			
		||||
  it 'should raise error' do
 | 
			
		||||
    expect { subject }.to raise_error(NotImplementedError,'Mutant::Matcher#each is not implemented')
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										34
									
								
								spec/unit/mutant/matcher/method/class_methods/parse_spec.rb
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								spec/unit/mutant/matcher/method/class_methods/parse_spec.rb
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,34 @@
 | 
			
		|||
require 'spec_helper'
 | 
			
		||||
 | 
			
		||||
shared_examples_for 'a method filter parse result' do
 | 
			
		||||
  it { should be(response) }
 | 
			
		||||
 | 
			
		||||
  it 'should initialize method filter with correct arguments' do
 | 
			
		||||
    expected_class.should_receive(:new).with('Foo','bar').and_return(response)
 | 
			
		||||
    subject
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
describe Mutant::Matcher::Method,'.parse' do
 | 
			
		||||
  subject { described_class.parse(input) }
 | 
			
		||||
 | 
			
		||||
  before do
 | 
			
		||||
    expected_class.stub(:new => response)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  let(:response) { mock('Response') }
 | 
			
		||||
 | 
			
		||||
  context 'when input is in instance method format' do
 | 
			
		||||
    let(:input)          { 'Foo#bar' }
 | 
			
		||||
    let(:expected_class) { described_class::Instance }
 | 
			
		||||
 | 
			
		||||
    it_should_behave_like 'a method filter parse result'
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  context 'when input is in singleton method format' do
 | 
			
		||||
    let(:input)          { 'Foo.bar' }
 | 
			
		||||
    let(:expected_class) { described_class::Singleton }
 | 
			
		||||
 | 
			
		||||
    it_should_behave_like 'a method filter parse result'
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue