vendor/hardmock/lib/hardmock/stubbing.rb in ceedling-0.28.3 vs vendor/hardmock/lib/hardmock/stubbing.rb in ceedling-0.29.0
- old
+ new
@@ -1,210 +1,210 @@
-
-
-# Stubbing support
-#
-# Stubs methods on classes and instances
-#
-
-# Why's "metaid.rb" stuff crunched down:
-class Object #:nodoc:#
- def hm_metaclass #:nodoc:#
- class << self
- self
- end
- end
-
- def hm_meta_eval(&blk) #:nodoc:#
- hm_metaclass.instance_eval(&blk)
- end
-
- def hm_meta_def(name, &blk) #:nodoc:#
- hm_meta_eval { define_method name, &blk }
- end
-end
-
-
-
-module Hardmock
-
- # == Hardmock: Stubbing and Mocking Concrete Methods
- #
- # Hardmock lets you stub and/or mock methods on concrete classes or objects.
- #
- # * To "stub" a concrete method is to rig it to return the same thing always, disregarding any arguments.
- # * To "mock" a concrete method is to surplant its funcionality by delegating to a mock object who will cover this behavior.
- #
- # Mocked methods have their expectations considered along with all other mock object expectations.
- #
- # If you use stubbing or concrete mocking in the absence (or before creation) of other mocks, you need to invoke <tt>prepare_hardmock_control</tt>.
- # Once <tt>verify_mocks</tt> or <tt>clear_expectaions</tt> is called, the overriden behavior in the target objects is restored.
- #
- # == Examples
- #
- # River.stubs!(:sounds_like).returns("gurgle")
- #
- # River.expects!(:jump).returns("splash")
- #
- # rogue.stubs!(:sounds_like).returns("pshshsh")
- #
- # rogue.expects!(:rawhide_tanning_solvents).returns("giant snapping turtles")
- #
- module Stubbing
- # Exists only for documentation
- end
-
- class ReplacedMethod #:nodoc:#
- attr_reader :target, :method_name
-
- def initialize(target, method_name)
- @target = target
- @method_name = method_name
-
- Hardmock.track_replaced_method self
- end
- end
-
- class StubbedMethod < ReplacedMethod #:nodoc:#
- def invoke(args)
- raise @raises if @raises
- @return_value
- end
-
- def returns(stubbed_return)
- @return_value = stubbed_return
- end
-
- def raises(err)
- err = RuntimeError.new(err) unless err.kind_of?(Exception)
- @raises = err
- end
- end
-
- class ::Object
- def stubs!(method_name)
- method_name = method_name.to_s
- already_stubbed = Hardmock.has_replaced_method?(self, method_name)
-
- stubbed_method = Hardmock::StubbedMethod.new(self, method_name)
-
-
- unless _is_mock? or already_stubbed
- if methods.include?(method_name.to_s)
- hm_meta_eval do
- alias_method "_hardmock_original_#{method_name}".to_sym, method_name.to_sym
- end
- end
- end
-
- hm_meta_def method_name do |*args|
- stubbed_method.invoke(args)
- end
-
- stubbed_method
- end
-
- def expects!(method_name, *args, &block)
- if self._is_mock?
- raise Hardmock::StubbingError, "Cannot use 'expects!(:#{method_name})' on a Mock object; try 'expects' instead"
- end
-
- method_name = method_name.to_s
-
- @_my_mock = Mock.new(_my_name, $main_mock_control) if @_my_mock.nil?
-
- unless Hardmock.has_replaced_method?(self, method_name)
- # Track the method as replaced
- Hardmock::ReplacedMethod.new(self, method_name)
-
- # Preserver original implementation of the method by aliasing it away
- if methods.include?(method_name)
- hm_meta_eval do
- alias_method "_hardmock_original_#{method_name}".to_sym, method_name.to_sym
- end
- end
-
- # Re-define the method to utilize our patron mock instance.
- # (This global-temp-var thing is hokey but I was having difficulty generating
- # code for the meta class.)
- begin
- $method_text_temp = %{
- def #{method_name}(*args,&block)
- @_my_mock.__send__(:#{method_name}, *args, &block)
- end
- }
- class << self
- eval $method_text_temp
- end
- ensure
- $method_text_temp = nil
- end
- end
-
- return @_my_mock.expects(method_name, *args, &block)
- end
-
- def _is_mock?
- self.kind_of?(Mock)
- end
-
- def _my_name
- self.kind_of?(Class) ? self.name : self.class.name
- end
-
- def _clear_mock
- @_my_mock = nil
- end
-
- end
-
- class ::NilClass
- # Use this only if you really mean it
- alias_method :intentionally_stubs!, :stubs!
-
- # Use this only if you really mean it
- alias_method :intentionally_expects!, :expects!
-
- # Overridden to protect against accidental nil reference self delusion
- def stubs!(mname)
- raise StubbingError, "Cannot stub #{mname} method on nil. (If you really mean to, try 'intentionally_stubs!')"
- end
-
- # Overridden to protect against accidental nil reference self delusion
- def expects!(mname, *args)
- raise StubbingError, "Cannot mock #{mname} method on nil. (If you really mean to, try 'intentionally_expects!')"
- end
- end
-
- class << self
- def track_replaced_method(replaced_method)
- all_replaced_methods << replaced_method
- end
-
- def all_replaced_methods
- $all_replaced_methods ||= []
- end
-
- def has_replaced_method?(obj, method_name)
- hits = all_replaced_methods.select do |replaced|
- (replaced.target.object_id == obj.object_id) and (replaced.method_name.to_s == method_name.to_s)
- end
- return !hits.empty?
- end
-
- def restore_all_replaced_methods
- all_replaced_methods.each do |replaced|
- unless replaced.target._is_mock?
- backed_up = "_hardmock_original_#{replaced.method_name}"
- if replaced.target.methods.include?(backed_up)
- replaced.target.hm_meta_eval do
- alias_method replaced.method_name.to_sym, backed_up.to_sym
- end
- end
- replaced.target._clear_mock
- end
- end
- all_replaced_methods.clear
- end
- end
-
-end
-
+
+
+# Stubbing support
+#
+# Stubs methods on classes and instances
+#
+
+# Why's "metaid.rb" stuff crunched down:
+class Object #:nodoc:#
+ def hm_metaclass #:nodoc:#
+ class << self
+ self
+ end
+ end
+
+ def hm_meta_eval(&blk) #:nodoc:#
+ hm_metaclass.instance_eval(&blk)
+ end
+
+ def hm_meta_def(name, &blk) #:nodoc:#
+ hm_meta_eval { define_method name, &blk }
+ end
+end
+
+
+
+module Hardmock
+
+ # == Hardmock: Stubbing and Mocking Concrete Methods
+ #
+ # Hardmock lets you stub and/or mock methods on concrete classes or objects.
+ #
+ # * To "stub" a concrete method is to rig it to return the same thing always, disregarding any arguments.
+ # * To "mock" a concrete method is to surplant its funcionality by delegating to a mock object who will cover this behavior.
+ #
+ # Mocked methods have their expectations considered along with all other mock object expectations.
+ #
+ # If you use stubbing or concrete mocking in the absence (or before creation) of other mocks, you need to invoke <tt>prepare_hardmock_control</tt>.
+ # Once <tt>verify_mocks</tt> or <tt>clear_expectaions</tt> is called, the overriden behavior in the target objects is restored.
+ #
+ # == Examples
+ #
+ # River.stubs!(:sounds_like).returns("gurgle")
+ #
+ # River.expects!(:jump).returns("splash")
+ #
+ # rogue.stubs!(:sounds_like).returns("pshshsh")
+ #
+ # rogue.expects!(:rawhide_tanning_solvents).returns("giant snapping turtles")
+ #
+ module Stubbing
+ # Exists only for documentation
+ end
+
+ class ReplacedMethod #:nodoc:#
+ attr_reader :target, :method_name
+
+ def initialize(target, method_name)
+ @target = target
+ @method_name = method_name
+
+ Hardmock.track_replaced_method self
+ end
+ end
+
+ class StubbedMethod < ReplacedMethod #:nodoc:#
+ def invoke(args)
+ raise @raises if @raises
+ @return_value
+ end
+
+ def returns(stubbed_return)
+ @return_value = stubbed_return
+ end
+
+ def raises(err)
+ err = RuntimeError.new(err) unless err.kind_of?(Exception)
+ @raises = err
+ end
+ end
+
+ class ::Object
+ def stubs!(method_name)
+ method_name = method_name.to_s
+ already_stubbed = Hardmock.has_replaced_method?(self, method_name)
+
+ stubbed_method = Hardmock::StubbedMethod.new(self, method_name)
+
+
+ unless _is_mock? or already_stubbed
+ if methods.include?(method_name.to_s)
+ hm_meta_eval do
+ alias_method "_hardmock_original_#{method_name}".to_sym, method_name.to_sym
+ end
+ end
+ end
+
+ hm_meta_def method_name do |*args|
+ stubbed_method.invoke(args)
+ end
+
+ stubbed_method
+ end
+
+ def expects!(method_name, *args, &block)
+ if self._is_mock?
+ raise Hardmock::StubbingError, "Cannot use 'expects!(:#{method_name})' on a Mock object; try 'expects' instead"
+ end
+
+ method_name = method_name.to_s
+
+ @_my_mock = Mock.new(_my_name, $main_mock_control) if @_my_mock.nil?
+
+ unless Hardmock.has_replaced_method?(self, method_name)
+ # Track the method as replaced
+ Hardmock::ReplacedMethod.new(self, method_name)
+
+ # Preserver original implementation of the method by aliasing it away
+ if methods.include?(method_name)
+ hm_meta_eval do
+ alias_method "_hardmock_original_#{method_name}".to_sym, method_name.to_sym
+ end
+ end
+
+ # Re-define the method to utilize our patron mock instance.
+ # (This global-temp-var thing is hokey but I was having difficulty generating
+ # code for the meta class.)
+ begin
+ $method_text_temp = %{
+ def #{method_name}(*args,&block)
+ @_my_mock.__send__(:#{method_name}, *args, &block)
+ end
+ }
+ class << self
+ eval $method_text_temp
+ end
+ ensure
+ $method_text_temp = nil
+ end
+ end
+
+ return @_my_mock.expects(method_name, *args, &block)
+ end
+
+ def _is_mock?
+ self.kind_of?(Mock)
+ end
+
+ def _my_name
+ self.kind_of?(Class) ? self.name : self.class.name
+ end
+
+ def _clear_mock
+ @_my_mock = nil
+ end
+
+ end
+
+ class ::NilClass
+ # Use this only if you really mean it
+ alias_method :intentionally_stubs!, :stubs!
+
+ # Use this only if you really mean it
+ alias_method :intentionally_expects!, :expects!
+
+ # Overridden to protect against accidental nil reference self delusion
+ def stubs!(mname)
+ raise StubbingError, "Cannot stub #{mname} method on nil. (If you really mean to, try 'intentionally_stubs!')"
+ end
+
+ # Overridden to protect against accidental nil reference self delusion
+ def expects!(mname, *args)
+ raise StubbingError, "Cannot mock #{mname} method on nil. (If you really mean to, try 'intentionally_expects!')"
+ end
+ end
+
+ class << self
+ def track_replaced_method(replaced_method)
+ all_replaced_methods << replaced_method
+ end
+
+ def all_replaced_methods
+ $all_replaced_methods ||= []
+ end
+
+ def has_replaced_method?(obj, method_name)
+ hits = all_replaced_methods.select do |replaced|
+ (replaced.target.object_id == obj.object_id) and (replaced.method_name.to_s == method_name.to_s)
+ end
+ return !hits.empty?
+ end
+
+ def restore_all_replaced_methods
+ all_replaced_methods.each do |replaced|
+ unless replaced.target._is_mock?
+ backed_up = "_hardmock_original_#{replaced.method_name}"
+ if replaced.target.methods.include?(backed_up)
+ replaced.target.hm_meta_eval do
+ alias_method replaced.method_name.to_sym, backed_up.to_sym
+ end
+ end
+ replaced.target._clear_mock
+ end
+ end
+ all_replaced_methods.clear
+ end
+ end
+
+end
+