Permalink
Browse files

[BUG] Invocation.returned was not set / Added spec about the Invocati…

…on object's attributes.
  • Loading branch information...
1 parent 787e2ec commit fe857e026d97570ebfd2fc5c65c29795e5e1d195 Kaoru Kobo committed Nov 25, 2010
Showing with 96 additions and 9 deletions.
  1. +8 −8 lib/rhook.rb
  2. +45 −0 spec/rhook_spec.rb
  3. +43 −1 spec/spec_helper.rb
View
@@ -255,12 +255,12 @@ def concat_hooks_internal(dest, name)
# The object contains the invocation information.
#
- # @attr [Object] target The target object that the hook is applied. (Usually same to {#receiver})
- # @attr [Object] receiver The receiver object of this method invocation.
+ # @attr_reader [Object] target The target object that the hook is applied. (Usually same to {#receiver})
+ # @attr_reader [Object] receiver The receiver object of this method invocation.
# @attr [Array<Object>] args The arguments given to the method invocation.
# @attr [Proc] block The block given to the method invocation
- # @attr [Object] returned The returned value by the method invocation. (Don't set this. To change it, just return by the alternative value from the hook procedure.)
- # @attr [Array<Hook>] hooks (Internally used) The applied hooks on this invocation.
+ # @attr_reader [Object] returned The returned value by the method invocation. (Don't set this. To change it, just return by the alternative value from the hook procedure.)
+ # @attr_reader [Array<Hook>] hooks (Internally used) The applied hooks on this invocation.
# @attr [Proc] target_proc (Internally used) The procedure to execute the target method/procedure.
# @attr [Hash] hint Hint data given by {RHookService#does} / {RHookService#to}.
class Invocation < Struct.new(:target, :receiver, :args, :block, :returned, :hooks, :target_proc, :hint)
@@ -274,11 +274,11 @@ def initialize
def proceed
hook = hooks[@hook_index]
# -- If no more hook was found, calls target procedure and return
- hook or return target_proc.call(*args, &block)
+ hook or return self.returned = target_proc.call(*args, &block)
# -- Set hook pointer to next, then call next hook
@hook_index += 1
begin
- hook.call(self)
+ self.returned = hook.call(self)
ensure
@hook_index -= 1
end
@@ -329,8 +329,8 @@ def disable
#
class ::Object
- # Get {RHookService} object bound to this object.
- # @return [RHookService]
+ # Get {RHook::RHookService} object bound to this object.
+ # @return [RHook::RHookService]
def _rhook
@_rhook ||= RHook::RHookService.new(self)
end
View
@@ -216,6 +216,51 @@ def group_2
end
# ================================================================
+ # ========================================================================
+ describe "Invocation object" do
+ class Target
+ def invocation_object(*args, &block)
+ _rhook.to(:hint => {:hintkey => :hintval}).invocation_object_target(*args, &block)
+ end
+
+ def invocation_object_target(*args, &block)
+ :returned_value
+ end
+ end #/Target
+
+ example "attributes" do
+ args = [1, 2]
+ block = lambda do
+
+ end
+
+ lambda { |called|
+ t = Target.new
+ t._rhook.bind(:invocation_object_target) { |inv|
+ # first hook
+ called.yes
+ inv.call()
+ inv.returned.should == :returned_value
+ :returned_value_hooked
+ }
+ t._rhook.bind(:invocation_object_target) { |inv|
+ # second hook
+ called.yes
+ inv.args.should == args
+ inv.block.should == block
+ inv.hint[:hintkey].should == :hintval
+ inv.receiver.should == t
+ inv.target.should == t
+ inv.returned.should be_nil
+ inv.call()
+ inv.returned.should == :returned_value_hooked
+ }
+ t.invocation_object(*args, &block)
+ }.should calls_hook(:times => 2)
+ end
+ end
+ # ========================================================================
+
end
# ================================================================
View
@@ -1,5 +1,5 @@
require 'rubygems'
-gem 'rspec'
+gem 'rspec', "< 2.0"
$LOAD_PATH.unshift(File.dirname(__FILE__))
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
@@ -10,3 +10,45 @@
Spec::Runner.configure do |config|
end
+
+# ========================================================================
+# Defines custom matcher to test the hook was called.
+
+module ::Spec::Matchers
+ class HookCalledMatcher
+ def initialize(opt)
+ @times = opt[:times]
+ @count = 0
+ end
+
+ def yes
+ @count += 1
+ end
+
+ def matches?(block)
+ block.call(self)
+ if @times
+ begin
+ @count.should == @times
+ rescue
+ @times_msg = " (Exactly called count: #{$!})"
+ false
+ end
+ else
+ @count > 0
+ end
+ end
+
+ def failure_message
+ "Expected the hook to be called.#{@times_msg}"
+ end
+
+ def negative_failure_message
+ "Expected the hook not to be called.#{@times_msg}"
+ end
+ end
+
+ def calls_hook(opt = {})
+ HookCalledMatcher.new(opt)
+ end
+end

0 comments on commit fe857e0

Please sign in to comment.