Skip to content

Commit

Permalink
As per Jay Fields recommendations [1] and with further impetus from a…
Browse files Browse the repository at this point in the history
… talk at Ruby Manor, any methods added to core classes are now added by including a module. This means that Mocha is a better citizen of the Ruby world and it's behaviour is more easily extended. [1] http://blog.jayfields.com/2008/07/ruby-underuse-of-modules.html & http://blog.jayfields.com/2008/07/ruby-redefine-method-behavior.html
  • Loading branch information
floehopper committed Nov 22, 2008
1 parent 36f20a4 commit 3251107
Show file tree
Hide file tree
Showing 5 changed files with 200 additions and 138 deletions.
68 changes: 48 additions & 20 deletions lib/mocha/inspect.rb
Original file line number Original file line Diff line number Diff line change
@@ -1,39 +1,67 @@
require 'date' require 'date'


class Object module Mocha
def mocha_inspect
address = self.__id__ * 2 module ObjectMethods
address += 0x100000000 if address < 0 def mocha_inspect
inspect =~ /#</ ? "#<#{self.class}:0x#{'%x' % address}>" : inspect address = self.__id__ * 2
address += 0x100000000 if address < 0
inspect =~ /#</ ? "#<#{self.class}:0x#{'%x' % address}>" : inspect
end
end

module StringMethods
def mocha_inspect
inspect.gsub(/\"/, "'")
end
end

module ArrayMethods
def mocha_inspect
"[#{collect { |member| member.mocha_inspect }.join(', ')}]"
end
end

module HashMethods
def mocha_inspect
"{#{collect { |key, value| "#{key.mocha_inspect} => #{value.mocha_inspect}" }.join(', ')}}"
end
end end

module TimeMethods
def mocha_inspect
"#{inspect} (#{to_f} secs)"
end
end

module DateMethods
def mocha_inspect
to_s
end
end

end

class Object
include Mocha::ObjectMethods
end end


class String class String
def mocha_inspect include Mocha::StringMethods
inspect.gsub(/\"/, "'")
end
end end


class Array class Array
def mocha_inspect include Mocha::ArrayMethods
"[#{collect { |member| member.mocha_inspect }.join(', ')}]"
end
end end


class Hash class Hash
def mocha_inspect include Mocha::HashMethods
"{#{collect { |key, value| "#{key.mocha_inspect} => #{value.mocha_inspect}" }.join(', ')}}"
end
end end


class Time class Time
def mocha_inspect include Mocha::TimeMethods
"#{inspect} (#{to_f} secs)"
end
end end


class Date class Date
def mocha_inspect include Mocha::DateMethods
to_s
end
end end
12 changes: 9 additions & 3 deletions lib/mocha/metaclass.rb
Original file line number Original file line Diff line number Diff line change
@@ -1,7 +1,13 @@
class Object module Mocha


def __metaclass__ module ObjectMethods
class << self; self; end def __metaclass__
class << self; self; end
end
end end

end


class Object
include Mocha::ObjectMethods
end end
220 changes: 118 additions & 102 deletions lib/mocha/object.rb
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -4,131 +4,147 @@
require 'mocha/module_method' require 'mocha/module_method'
require 'mocha/any_instance_method' require 'mocha/any_instance_method'


# Methods added all objects to allow mocking and stubbing on real objects. module Mocha
#
# Methods return a Mocha::Expectation which can be further modified by methods on Mocha::Expectation.
class Object


def mocha # :nodoc: # Methods added all objects to allow mocking and stubbing on real objects.
@mocha ||= Mocha::Mockery.instance.mock_impersonating(self) #
end # Methods return a Mocha::Expectation which can be further modified by methods on Mocha::Expectation.
module ObjectMethods


def reset_mocha # :nodoc: def mocha # :nodoc:
@mocha = nil @mocha ||= Mocha::Mockery.instance.mock_impersonating(self)
end end


def stubba_method # :nodoc: def reset_mocha # :nodoc:
Mocha::InstanceMethod @mocha = nil
end end


def stubba_object # :nodoc: def stubba_method # :nodoc:
self Mocha::InstanceMethod
end end


# :call-seq: expects(symbol) -> expectation def stubba_object # :nodoc:
# self
# Adds an expectation that a method identified by +symbol+ must be called exactly once with any parameters. end
# Returns the new expectation which can be further modified by methods on Mocha::Expectation.
# product = Product.new
# product.expects(:save).returns(true)
# assert_equal false, product.save
#
# The original implementation of <tt>Product#save</tt> is replaced temporarily.
#
# The original implementation of <tt>Product#save</tt> is restored at the end of the test.
def expects(symbol)
mockery = Mocha::Mockery.instance
mockery.on_stubbing(self, symbol)
method = stubba_method.new(stubba_object, symbol)
mockery.stubba.stub(method)
mocha.expects(symbol, caller)
end


# :call-seq: stubs(symbol) -> expectation # :call-seq: expects(symbol) -> expectation
# #
# Adds an expectation that a method identified by +symbol+ may be called any number of times with any parameters. # Adds an expectation that a method identified by +symbol+ must be called exactly once with any parameters.
# Returns the new expectation which can be further modified by methods on Mocha::Expectation. # Returns the new expectation which can be further modified by methods on Mocha::Expectation.
# product = Product.new # product = Product.new
# product.stubs(:save).returns(true) # product.expects(:save).returns(true)
# assert_equal false, product.save # assert_equal false, product.save
# #
# The original implementation of <tt>Product#save</tt> is replaced temporarily. # The original implementation of <tt>Product#save</tt> is replaced temporarily.
# #
# The original implementation of <tt>Product#save</tt> is restored at the end of the test. # The original implementation of <tt>Product#save</tt> is restored at the end of the test.
def stubs(symbol) def expects(symbol)
mockery = Mocha::Mockery.instance mockery = Mocha::Mockery.instance
mockery.on_stubbing(self, symbol) mockery.on_stubbing(self, symbol)
method = stubba_method.new(stubba_object, symbol) method = stubba_method.new(stubba_object, symbol)
mockery.stubba.stub(method) mockery.stubba.stub(method)
mocha.stubs(symbol, caller) mocha.expects(symbol, caller)
end end


def method_exists?(method, include_public_methods = true) # :call-seq: stubs(symbol) -> expectation
if include_public_methods #
return true if public_methods(include_superclass_methods = true).include?(method) # Adds an expectation that a method identified by +symbol+ may be called any number of times with any parameters.
return true if respond_to?(method.to_sym) # Returns the new expectation which can be further modified by methods on Mocha::Expectation.
# product = Product.new
# product.stubs(:save).returns(true)
# assert_equal false, product.save
#
# The original implementation of <tt>Product#save</tt> is replaced temporarily.
#
# The original implementation of <tt>Product#save</tt> is restored at the end of the test.
def stubs(symbol)
mockery = Mocha::Mockery.instance
mockery.on_stubbing(self, symbol)
method = stubba_method.new(stubba_object, symbol)
mockery.stubba.stub(method)
mocha.stubs(symbol, caller)
end end
return true if protected_methods(include_superclass_methods = true).include?(method)
return true if private_methods(include_superclass_methods = true).include?(method)
return false
end


end def method_exists?(method, include_public_methods = true) # :nodoc:

if include_public_methods
class Module # :nodoc: return true if public_methods(include_superclass_methods = true).include?(method)
return true if respond_to?(method.to_sym)
end
return true if protected_methods(include_superclass_methods = true).include?(method)
return true if private_methods(include_superclass_methods = true).include?(method)
return false
end


def stubba_method
Mocha::ModuleMethod
end end

end

class Class


def stubba_method # :nodoc: module ModuleMethods # :nodoc:
Mocha::ClassMethod
end

class AnyInstance # :nodoc:


def initialize(klass) def stubba_method
@stubba_object = klass Mocha::ModuleMethod
end end


def mocha end
@mocha ||= Mocha::Mockery.instance.mock_impersonating_any_instance_of(@stubba_object)
# Methods added all classes to allow mocking and stubbing on real objects.
module ClassMethods

def stubba_method # :nodoc:
Mocha::ClassMethod
end end


def stubba_method class AnyInstance # :nodoc:
Mocha::AnyInstanceMethod
end


def stubba_object def initialize(klass)
@stubba_object @stubba_object = klass
end end


def method_exists?(method, include_public_methods = true) def mocha
if include_public_methods @mocha ||= Mocha::Mockery.instance.mock_impersonating_any_instance_of(@stubba_object)
return true if @stubba_object.public_instance_methods(include_superclass_methods = true).include?(method) end

def stubba_method
Mocha::AnyInstanceMethod
end end
return true if @stubba_object.protected_instance_methods(include_superclass_methods = true).include?(method)
return true if @stubba_object.private_instance_methods(include_superclass_methods = true).include?(method)
return false
end


end def stubba_object
@stubba_object
end

def method_exists?(method, include_public_methods = true)
if include_public_methods
return true if @stubba_object.public_instance_methods(include_superclass_methods = true).include?(method)
end
return true if @stubba_object.protected_instance_methods(include_superclass_methods = true).include?(method)
return true if @stubba_object.private_instance_methods(include_superclass_methods = true).include?(method)
return false
end

end

# :call-seq: any_instance -> mock object
#
# Returns a mock object which will detect calls to any instance of this class.
# Product.any_instance.stubs(:save).returns(false)
# product_1 = Product.new
# assert_equal false, product_1.save
# product_2 = Product.new
# assert_equal false, product_2.save
def any_instance
@any_instance ||= AnyInstance.new(self)
end


# :call-seq: any_instance -> mock object
#
# Returns a mock object which will detect calls to any instance of this class.
# Product.any_instance.stubs(:save).returns(false)
# product_1 = Product.new
# assert_equal false, product_1.save
# product_2 = Product.new
# assert_equal false, product_2.save
def any_instance
@any_instance ||= AnyInstance.new(self)
end end


end end


class Object # :nodoc:
include Mocha::ObjectMethods
end

class Module # :nodoc:
include Mocha::ModuleMethods
end

class Class # :nodoc:
include Mocha::ClassMethods
end
12 changes: 9 additions & 3 deletions lib/mocha/parameter_matchers/object.rb
Original file line number Original file line Diff line number Diff line change
@@ -1,9 +1,15 @@
require 'mocha/parameter_matchers/equals' require 'mocha/parameter_matchers/equals'


class Object module Mocha


def to_matcher # :nodoc: module ObjectMethods
Mocha::ParameterMatchers::Equals.new(self) def to_matcher # :nodoc:
Mocha::ParameterMatchers::Equals.new(self)
end
end end


end end

class Object
include Mocha::ObjectMethods
end
Loading

0 comments on commit 3251107

Please sign in to comment.