From ba23a5ac276e59fdda8186750c6d0fd2cfecdeac Mon Sep 17 00:00:00 2001 From: luke Date: Sat, 17 Mar 2007 02:48:41 +0000 Subject: Adding spec libs, so we can use them some day git-svn-id: https://reductivelabs.com/svn/puppet/trunk@2283 980ebf18-57e1-0310-9a29-db15c13687c0 --- test/lib/spec/callback/callback_container.rb | 60 ++++++++++++++++++++++++++++ test/lib/spec/callback/extensions/module.rb | 24 +++++++++++ test/lib/spec/callback/extensions/object.rb | 37 +++++++++++++++++ 3 files changed, 121 insertions(+) create mode 100644 test/lib/spec/callback/callback_container.rb create mode 100644 test/lib/spec/callback/extensions/module.rb create mode 100644 test/lib/spec/callback/extensions/object.rb (limited to 'test/lib/spec/callback') diff --git a/test/lib/spec/callback/callback_container.rb b/test/lib/spec/callback/callback_container.rb new file mode 100644 index 000000000..24d4c0ced --- /dev/null +++ b/test/lib/spec/callback/callback_container.rb @@ -0,0 +1,60 @@ +module Callback + class CallbackContainer + def initialize + @callback_registry = Hash.new do |hash, key| + hash[key] = Array.new + end + end + + # Defines the callback with the key in this container. + def define(key, callback_proc=nil, &callback_block) + callback = extract_callback(callback_block, callback_proc) do + raise "You must define the callback that accepts the call method." + end + @callback_registry[key] << callback + callback + end + + # Undefines the callback with the key in this container. + def undefine(key, callback_proc) + callback = extract_callback(callback_proc) do + raise "You may only undefine callbacks that use the call method." + end + @callback_registry[key].delete callback + callback + end + + # Notifies the callbacks for the key. Arguments may be passed. + # An error handler may be passed in as a block. If there is an error, the block is called with + # error object as an argument. + # An array of the return values of the callbacks is returned. + def notify(key, *args, &error_handler) + @callback_registry[key].collect do |callback| + begin + callback.call(*args) + rescue Exception => e + yield(e) if error_handler + end + end + end + + # Clears all of the callbacks in this container. + def clear + @callback_registry.clear + end + + protected + def extract_callback(first_choice_callback, second_choice_callback = nil) + callback = nil + if first_choice_callback + callback = first_choice_callback + elsif second_choice_callback + callback = second_choice_callback + end + unless callback.respond_to? :call + yield + end + return callback + end + end +end diff --git a/test/lib/spec/callback/extensions/module.rb b/test/lib/spec/callback/extensions/module.rb new file mode 100644 index 000000000..429268ed1 --- /dev/null +++ b/test/lib/spec/callback/extensions/module.rb @@ -0,0 +1,24 @@ +module Callback + module ModuleMethods + # For each event_name submitted, defines a callback event with this name. + # Client code can then register as a callback listener using object.event_name. + def callback_events(*event_names) + event_names.each do |event_name| + define_callback_event(event_name) + end + end + + private + def define_callback_event(event_name) + module_eval <<-EOS + def #{event_name}(&block) + register_callback(:#{event_name}, &block) + end + EOS + end + end +end + +class Module + include Callback::ModuleMethods +end diff --git a/test/lib/spec/callback/extensions/object.rb b/test/lib/spec/callback/extensions/object.rb new file mode 100644 index 000000000..c6ac6fd14 --- /dev/null +++ b/test/lib/spec/callback/extensions/object.rb @@ -0,0 +1,37 @@ +module Callback + module InstanceMethods + # Registers a callback for the event on the object. The callback can either be a block or a proc. + # When the callbacks are notified, the return value of the proc is passed to the caller. + def register_callback(event, callback_proc=nil, &callback_block) + callbacks.define(event, callback_proc, &callback_block) + end + + # Removes the callback from the event. The callback proc must be the same + # object as the one that was passed to register_callback. + def unregister_callback(event, callback_proc) + callbacks.undefine(event, callback_proc) + end + + protected + # Notifies the callbacks registered with the event on the object. Arguments can be passed to the callbacks. + # An error handler may be passed in as a block. If there is an error, the block is called with + # error object as an argument. + # An array of the return values of the callbacks is returned. + def notify_callbacks(event, *args, &error_handler) + callbacks.notify(event, *args, &error_handler) + end + + def notify_class_callbacks(event, *args, &error_handler) + self.class.send(:notify_callbacks, event, *args, &error_handler) + end + + # The CallbackContainer for this object. + def callbacks + @callbacks ||= CallbackContainer.new + end + end +end + +class Object + include Callback::InstanceMethods +end \ No newline at end of file -- cgit