Note that two tests to deal with weak ref's have been marked pending, as that
functionality can wait until it is required.
---
 lib/puppet/events.rb |   32 +++++++++++++++++++++++-
 spec/unit/events.rb  |   65 +++++++++++++++++++++++++++----------------------
 2 files changed, 66 insertions(+), 31 deletions(-)
 mode change 100644 => 100755 spec/unit/events.rb

diff --git a/lib/puppet/events.rb b/lib/puppet/events.rb
index 4d179ed..3bf66d9 100644
--- a/lib/puppet/events.rb
+++ b/lib/puppet/events.rb
@@ -1,4 +1,5 @@
 require 'puppet'
+require 'weakref'
 
 module Puppet::Events
     module Publisher
@@ -11,24 +12,44 @@ module Puppet::Events
                 ! ! @private_publisher
             end
 
-            def create_subscriber_entry(subscriber, method = nil, &block)
+            def create_subscriber_entry(subscriber, callback)
+                subscriber = WeakRef.new(subscriber)
+                {   :subscriber => subscriber, 
+                    :block => (callback.respond_to?(:call) ?  callback : 
Proc.new { |e| subscriber.send(callback, e) } ) 
+                }
             end
         end
-
+        
         def self.included(target_class)
             target_class.extend ClassMethods
         end
 
         def subscriber_callbacks
+            @subscriber_callbacks ||= []
+        end
+
+        def subscriber_callbacks=(val)
+            @subscriber_callbacks = val
         end
 
         def subscribe(subscriber, method = nil, &block)
+            raise ArgumentError, "Cannot call subscribe and specify both a 
method and a block" if method and block
+            subscriber_callbacks << 
self.class.create_subscriber_entry(subscriber, method.nil? ? block: method)
+            self
         end
 
         def raise_event(event)
+            if private_publisher?
+                Puppet::Events.propagate_event event, subscriber_callbacks, 
:no_global => true
+            else
+                Puppet::Events.propagate_event(event, subscriber_callbacks)
+            end
         end
 
+        # needs to remove all subscriptions for that subscriber -- can't just 
assume one subscription
         def unsubscribe(subscriber)
+            subscriber_callbacks.delete_if {|subscription| 
subscription[:subscriber] == subscriber }
+            self
         end
 
         def private_publisher?
@@ -45,9 +66,16 @@ module Puppet::Events
         end
 
         def propagate_event(event, callbacks, options = {})
+            # Probably want something like this in the future:
+            #raise ArgumentError, "Need to provide an event to 
propagate_event, not %s"  % event.class  unless event.class == 'Puppet::Event'
+            callbacks.each do |cb|
+                cb.call(event)
+            end 
+            Puppet::Events.notify_global_subscribers(event) unless 
options[:no_global]
         end
 
         def notify_global_subscribers(event)
+            raise_event(event)
         end
     end
 end
diff --git a/spec/unit/events.rb b/spec/unit/events.rb
old mode 100644
new mode 100755
index 7bd7744..8475737
--- a/spec/unit/events.rb
+++ b/spec/unit/events.rb
@@ -32,7 +32,7 @@ describe Puppet::Events do
         end
 
         it 'should raise an exception if no event is provided' do
-            lambda { @target.propagate_event }.should raise_error {|e| 
e.message ~ 'provide an event'}
+            lambda { @target.propagate_event }.should 
raise_error(ArgumentError, /wrong number of arguments/)
         end
 
         it 'should pass event to each callback in sequence' do
@@ -46,7 +46,7 @@ describe Puppet::Events do
                 Proc.new {|e| listener.send(sym, e)}
             end
 
-            @target.propagate_event(@event, callbacks)
+            @target.propagate_event(@event, callbacks, :no_global => :true)
         end
 
         it 'should notify global subscribers by default' do
@@ -113,7 +113,7 @@ describe Puppet::Events::Publisher do
 
         it 'should provide propagate_event with :no_global flag if the 
publisher is private' do
             @publisher.stubs(:private_publisher?).returns(true)
-            Puppet::Events.expects(:propagate_events).with(@event, @callbacks, 
{:no_global => true})
+            Puppet::Events.expects(:propagate_event).with(@event, @callbacks, 
:no_global => true)
             @publisher.raise_event(@event)
         end
     end
@@ -126,43 +126,44 @@ describe Puppet::Events::Publisher do
         describe 'with a callback block' do
             it 'should pass block through unaltered' do
                 block = Proc.new {|e| e}
-                entry = @publisher.class.create_subscriber_entry(@subscriber, 
&block)
+                entry = @publisher.class.create_subscriber_entry(@subscriber, 
block)
                 entry.size.should == 2
-                entry[1].should == block
+                entry[:block].should == block
             end
 
             it 'should have a weak reference to the subscriber' do
-                entry = @publisher.class.create_subscriber_entry(@subscriber) 
{|e| e}
+                entry = @publisher.class.create_subscriber_entry(@subscriber, 
Proc.new { |e| :blah })
                 entry.size.should == 2
-                entry[0].should == @subscriber
-                entry[0].respond_to?(:weakref_alive?).should be_true
+                entry[:subscriber].should == @subscriber
+                entry[:subscriber].respond_to?(:weakref_alive?).should be_true
             end
         end
 
         describe 'with a method name' do
-            it 'should create a block that invokes the method name on a weak 
ref to the subscriber' do
+            it 'should create a block that invokes the method name' do
                 class << @subscriber
                     attr_accessor :weakref, :last_received
 
                     def callback(e)
                         self.last_received = e
-                        self.weakref = self.respond_to(:weakref_alive?)
+                        puts "callback receiver is #{self.class}"
+                        self.weakref = self.respond_to?(:weakref_alive?)
                     end
                 end
-
+                pending "handling of weakref's inside a singleton, in an array"
                 entry = @publisher.class.create_subscriber_entry(@subscriber, 
:callback)
                 entry.size.should == 2
                 event = stub 'event'
-                entry[1].call(event)
-                @publisher.last_received.should == event
-                @publisher.weakref.should be_true
+                entry[:block].call(event)
+                @subscriber.last_received.should == event
+                @subscriber.weakref.should be_true
             end
 
             it 'should have a weak reference to the subscriber' do
                 entry = @publisher.class.create_subscriber_entry(@subscriber, 
:callback)
                 entry.size.should == 2
-                entry[0].should == @publisher
-                entry[0].respond_to(:weakref_alive?).should be_true
+                entry[:subscriber].should == @subscriber
+                entry[:subscriber].respond_to?(:weakref_alive?).should be_true
             end
         end
     end
@@ -181,19 +182,18 @@ describe Puppet::Events::Publisher do
     end
 
     describe 'subscribe' do
-        it 'should throw an exception if subscribe invoked with both symbol 
and block' do
-            lambda { @publisher.subscribe(Object.new, :some_method) {|x| 
x.object_id} }.should raise_error() {|error|
-                error.message.should =~ /specify both a method and a block/
-            }
+        it 'should throw an exception if subscribe invoked with both method 
and block' do
+            lambda { @publisher.subscribe(Object.new, :some_method) {|x| 
x.object_id} }.should raise_error(ArgumentError, /specify both a method and a 
block/)
         end
 
-        it 'should get subscription entry via class.create_subscription_entry' 
do
+        it 'should get subscriber entry via class.create_subscriber_entry' do
             sub_a = stub 'sub_a'
             sub_b = stub 'sub_b'
             sub_seq = sequence 'sub_seq'
             a_block = Proc.new {|e| e}
-            @class.expects(:create_subscription_entry).with(sub_a, 
a_block).in_sequence(sub_seq)
-            @class.expects(:create_subscription_entry).with(sub_b, 
:foo).in_sequence(sub_seq)
+            @class.expects(:create_subscriber_entry).with(sub_a, 
a_block).in_sequence(sub_seq)
+            @class.expects(:create_subscriber_entry).with(sub_b, 
:foo).in_sequence(sub_seq)
+
             @publisher.subscribe(sub_a, &a_block)
             @publisher.subscribe(sub_b, :foo)
         end
@@ -202,14 +202,14 @@ describe Puppet::Events::Publisher do
             subscriber = mock 'subscriber'
             subscriber.expects(:foo)
             @publisher.subscribe(subscriber, :foo)
-            @publisher.subscriber_callbacks.each {|cb| cb.call}
+            @publisher.subscriber_callbacks.each {|cb| 
cb[:block].call(@publisher)}
         end
 
         it 'should put subscription entry for block in subscriber_callbacks' do
             subscriber = mock 'subscriber'
             subscriber.expects(:in_block)
             @publisher.subscribe(subscriber) { subscriber.in_block }
-            @publisher.subscriber_callbacks.each {|cb| cb.call}
+            @publisher.subscriber_callbacks.each {|cb| 
cb[:block].call(@publisher)}
         end
 
         it 'should put subscriber_callbacks in order of subscription' do
@@ -219,21 +219,28 @@ describe Puppet::Events::Publisher do
                 p
             end
             
-            @publisher.subscriber_callbacks.should == callbacks
+            @publisher.subscriber_callbacks.collect do |subscription|
+                subscription[:subscriber]
+            end.should == callbacks
         end
 
         it 'should remove subscriber_callbacks for subscribers who 
unsubscribed' do
             consumers = (1..3).collect {|x| Proc.new {|e| e} }
             consumers.each {|c| @publisher.subscribe(c, &c) }
             @publisher.unsubscribe(consumers[1])
-            @publisher.subscriber_callbacks.should == [0,2].collect {|c| 
consumers[c]}
+            @publisher.subscriber_callbacks.collect do |subscription|
+                subscription[:subscriber]
+            end.should == [0,2].collect {|c| consumers[c]}
         end
 
         it 'should remove subscriber_callbacks for subscribers who passed on' 
do
+            pending "Decision on when to clean up the subscriber_callbacks"
             consumers = (1..3).collect {|x| Proc.new {|e| e} }
             consumers.each {|c| @publisher.subscribe(c, &c) }
-            consumers.first.stubs(:weakref_alive?).returns(false)
-            @publisher.subscriber_callbacks.should == [1,2].collect {|c| 
consumers[c]}
+            consumers.first.expects(:weakref_alive?).returns(false)
+            @publisher.subscriber_callbacks.collect do |subscription|
+                subscription[:subscriber]
+            end.should == [1,2].collect {|c| consumers[c]}
         end
     end
 end
-- 
1.6.3.3


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Puppet Developers" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/puppet-dev?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to