event_bus 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format progress
data/.yardopts ADDED
@@ -0,0 +1 @@
1
+ --no-private
data/Gemfile CHANGED
@@ -3,7 +3,7 @@ gemspec
3
3
 
4
4
  group :test do
5
5
  gem 'rspec', '~> 2.12'
6
- gem 'rake', '~> 0.9.2'
6
+ gem 'rake', '~> 10.0.1'
7
7
  gem 'simplecov', :require => false
8
8
  end
9
9
 
data/Gemfile.lock CHANGED
@@ -1,14 +1,14 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- event_bus (0.0.2)
4
+ event_bus (0.0.3)
5
5
 
6
6
  GEM
7
7
  remote: http://rubygems.org/
8
8
  specs:
9
9
  diff-lcs (1.1.3)
10
10
  multi_json (1.5.0)
11
- rake (0.9.2.2)
11
+ rake (10.0.3)
12
12
  rspec (2.12.0)
13
13
  rspec-core (~> 2.12.0)
14
14
  rspec-expectations (~> 2.12.0)
@@ -27,6 +27,6 @@ PLATFORMS
27
27
 
28
28
  DEPENDENCIES
29
29
  event_bus!
30
- rake (~> 0.9.2)
30
+ rake (~> 10.0.1)
31
31
  rspec (~> 2.12)
32
32
  simplecov
data/README.md CHANGED
@@ -3,6 +3,8 @@
3
3
  A simple pubsub event bus for Ruby applications.
4
4
 
5
5
  [![Build Status](https://travis-ci.org/kevinrutherford/event_bus.png)](https://travis-ci.org/kevinrutherford/event_bus)
6
+ [![Dependency
7
+ Status](https://gemnasium.com/kevinrutherford/event_bus.png)](https://gemnasium.com/kevinrutherford/event_bus)
6
8
 
7
9
  * <https://rubygems.org/gems/event_bus>
8
10
  * <http://rubydoc.info/gems/event_bus/frames>
@@ -35,29 +37,38 @@ gem 'event_bus'
35
37
  Subscribe to an event in your application's initialization code:
36
38
 
37
39
  ```ruby
38
- EventBus.listen_for('order-placed', StatsRecorder.new, :order_placed)
40
+ EventBus.subscribe('order-placed', StatsRecorder.new, :order_placed)
39
41
  ```
40
42
 
41
- Fire the event whenever something significant happens in your application:
43
+ ```ruby
44
+ class StatsRecorder
45
+ def order_placed(details)
46
+ order = details[:order]
47
+ //...
48
+ end
49
+ end
50
+ ```
51
+
52
+ Or subscribe a block:
42
53
 
43
54
  ```ruby
44
- class PlaceOrder
55
+ EventBus.subscribe('order-placed') do |details|
56
+ order = details[:order]
45
57
  //...
46
- EventBus.listen_for('order-placed', :order => current_order, :customer => current_user)
47
58
  end
48
59
  ```
49
60
 
50
- Handle the event without coupling the publisher or subscriber:
61
+ Fire the event whenever something significant happens in your application:
51
62
 
52
63
  ```ruby
53
- class StatsRecorder
54
- def order_placed(details)
55
- order = details[:order]
56
- //...
57
- end
64
+ class PlaceOrder
65
+ //...
66
+ EventBus.announce('order-placed', :order => current_order, :customer => current_user)
58
67
  end
59
68
  ```
60
69
 
70
+ See the specs for more detailed usage scenarios.
71
+
61
72
  ## Compatibility
62
73
 
63
74
  Tested with Ruby 1.8.7, 1.9.x, JRuby, Rubinius.
data/lib/event_bus.rb CHANGED
@@ -2,52 +2,75 @@ require 'singleton'
2
2
 
3
3
  class EventBus
4
4
 
5
- #
6
- # Announce an event to any waiting listeners.
7
- #
8
- # @param event_name [String, Symbol] the name of your event
9
- # @param details [Hash] the information you want to pass to the listeners
10
- # @return the EventBus, ready to be called again.
11
- #
12
- def self.announce(event_name, details)
13
- Registrations.instance.announce(event_name, details)
14
- self
15
- end
5
+ class << self
6
+
7
+ #
8
+ # Announce an event to any waiting listeners.
9
+ #
10
+ # The +event_name+ is added to the +details+ hash (with the key +:event_name+)
11
+ # before the event is passed on to listeners.
12
+ #
13
+ # @param event_name [String, Symbol] the name of your event
14
+ # @param details [Hash] the information you want to pass to the listeners
15
+ # @return the EventBus, ready to be called again.
16
+ #
17
+ def publish(event_name, details = {})
18
+ registrations.announce(event_name, details)
19
+ self
20
+ end
16
21
 
17
- #
18
- # Register a single listener.
19
- #
20
- # @param pattern [String, Regex] listen for any events whose name matches this pattern
21
- # @param listener the object to be notified when a matching event occurs
22
- # @param method_name [Symbol] the method to be called on listener when a matching event occurs
23
- # @return the EventBus, ready to be called again.
24
- #
25
- def self.listen_for(pattern, listener, method_name)
26
- Registrations.instance.register(pattern, listener, method_name)
27
- self
28
- end
22
+ alias :announce :publish
23
+ alias :broadcast :publish
24
+
25
+ #
26
+ # Register a single listener.
27
+ #
28
+ # @param pattern [String, Regex] listen for any events whose name matches this pattern
29
+ # @param listener the object to be notified when a matching event occurs
30
+ # @param method_name [Symbol] the method to be called on +listener+ when a matching event occurs
31
+ # @return the EventBus, ready to be called again.
32
+ #
33
+ def subscribe(pattern, listener = nil, method_name = nil, &blk)
34
+ if listener
35
+ raise ArgumentError.new('You cannot give both a listener and a block') if block_given?
36
+ raise ArgumentError.new('You must supply a method name') unless method_name
37
+ registrations.add_method(pattern, listener, method_name)
38
+ else
39
+ raise ArgumentError.new('You must provide a listener or a block') unless block_given?
40
+ registrations.add_block(pattern, blk)
41
+ end
42
+ self
43
+ end
29
44
 
30
- #
31
- # Delete all current listener registrations
32
- #
33
- # @return the EventBus, ready to be called again.
34
- #
35
- def self.clear
36
- Registrations.instance.clear
37
- self
38
- end
45
+ alias :listen_for :subscribe
39
46
 
40
- #
41
- # (experimental)
42
- #
43
- def self.register(listener)
44
- listener.events_map.each do |pattern, method_name|
45
- Registrations.instance.register(pattern, listener, method_name)
47
+ #
48
+ # Delete all current listener registrations
49
+ #
50
+ # @return the EventBus, ready to be called again.
51
+ #
52
+ def clear
53
+ registrations.clear
54
+ self
55
+ end
56
+
57
+ #
58
+ # (experimental)
59
+ #
60
+ def register(listener)
61
+ listener.events_map.each do |pattern, method_name|
62
+ registrations.add(pattern, listener, method_name)
63
+ end
64
+ self
46
65
  end
47
- self
48
- end
49
66
 
50
- private
67
+ private
68
+
69
+ def registrations
70
+ Registrations.instance
71
+ end
72
+
73
+ end
51
74
 
52
75
  class Registrations
53
76
  include Singleton
@@ -57,8 +80,9 @@ class EventBus
57
80
  end
58
81
 
59
82
  def announce(event_name, details)
83
+ info = {:event_name => event_name}.merge(details)
60
84
  @listeners.each do |listener|
61
- listener.respond(event_name, details)
85
+ listener.respond(event_name, info)
62
86
  end
63
87
  end
64
88
 
@@ -66,10 +90,22 @@ class EventBus
66
90
  @listeners = []
67
91
  end
68
92
 
69
- def register(pattern, listener, method_name)
93
+ def add(pattern, listener, method_name, &blk)
94
+ if listener
95
+ add_method(pattern, listener, method_name)
96
+ else
97
+ add_block(pattern, blk)
98
+ end
99
+ end
100
+
101
+ def add_method(pattern, listener, method_name)
70
102
  @listeners << Registration.new(pattern, listener, method_name)
71
103
  end
72
104
 
105
+ def add_block(pattern, blk)
106
+ @listeners << BlockRegistration.new(pattern, blk)
107
+ end
108
+
73
109
  private
74
110
 
75
111
  Registration = Struct.new(:pattern, :listener, :method_name) do
@@ -78,6 +114,12 @@ class EventBus
78
114
  end
79
115
  end
80
116
 
117
+ BlockRegistration = Struct.new(:pattern, :block) do
118
+ def respond(event_name, details)
119
+ block.call(details) if pattern === event_name
120
+ end
121
+ end
122
+
81
123
  end
82
124
 
83
125
  end
@@ -9,52 +9,103 @@ describe EventBus do
9
9
  EventBus.clear
10
10
  end
11
11
 
12
- describe '.announce' do
12
+ describe '.publish' do
13
13
 
14
14
  it 'returns itself, to facilitate cascades' do
15
- EventBus.clear.should == EventBus
15
+ EventBus.publish(event_name, {}).should == EventBus
16
16
  end
17
17
 
18
- context 'when the listener is specific about the event name' do
19
- it 'sends the event to the listener' do
20
- EventBus.listen_for(event_name, listener, receiving_method)
21
- listener.should_receive(receiving_method).with({:a => 1, :b => 2})
22
- EventBus.announce(event_name, {:a => 1, :b => 2})
23
- end
18
+ it 'passes the event name in the details hash' do
19
+ EventBus.subscribe(event_name, listener, receiving_method)
20
+ listener.should_receive(receiving_method).with(:event_name => event_name)
21
+ EventBus.publish(event_name, {})
24
22
  end
25
23
 
26
- context 'when the listener uses a regex that matches' do
27
- it 'sends the event to the listener' do
28
- EventBus.listen_for(/123b/, listener, receiving_method)
29
- listener.should_receive(receiving_method).with({:a => 1, :b => 2})
30
- EventBus.announce(event_name, {:a => 1, :b => 2})
31
- end
24
+ it 'allows the details hash to be omitted' do
25
+ EventBus.subscribe(event_name, listener, receiving_method)
26
+ listener.should_receive(receiving_method).with(:event_name => event_name)
27
+ EventBus.publish(event_name)
32
28
  end
33
29
 
34
- context 'when the listener listens for a different event' do
35
- it 'does not send the event to the listener' do
36
- EventBus.listen_for('blah', listener, receiving_method)
30
+ end
31
+
32
+ describe '.subscribe' do
33
+
34
+ it 'returns itself, to facilitate cascades' do
35
+ EventBus.subscribe(event_name, listener, receiving_method).should == EventBus
36
+ end
37
+
38
+ context 'accepts a string event name' do
39
+ it 'sends the event to a matching listener' do
40
+ EventBus.subscribe(event_name, listener, receiving_method)
41
+ listener.should_receive(receiving_method).with(:a => 1, :b => 2, :event_name => event_name)
42
+ EventBus.publish(event_name, :a => 1, :b => 2)
43
+ end
44
+
45
+ it 'does not send the event to non-matching listeners' do
46
+ EventBus.subscribe('blah', listener, receiving_method)
37
47
  listener.should_not_receive(receiving_method)
38
- EventBus.announce(event_name, {:a => 1, :b => 2})
48
+ EventBus.publish(event_name, :a => 1, :b => 2, :event_name => event_name)
39
49
  end
40
50
  end
41
51
 
42
- context 'when the listener listens for a non-matching regex' do
43
- it 'does not send the event to the listener' do
44
- EventBus.listen_for(/123a/, listener, receiving_method)
52
+ context 'accepts a regex event name' do
53
+ it 'sends the event to a matching listener' do
54
+ EventBus.subscribe(/123b/, listener, receiving_method)
55
+ listener.should_receive(receiving_method).with(:a => 1, :b => 2, :event_name => event_name)
56
+ EventBus.publish(event_name, :a => 1, :b => 2)
57
+ end
58
+
59
+ it 'does not send the event to non-matching listeners' do
60
+ EventBus.subscribe(/123a/, listener, receiving_method)
45
61
  listener.should_not_receive(receiving_method)
46
- EventBus.announce(event_name, {:a => 1, :b => 2})
62
+ EventBus.publish(event_name, :a => 1, :b => 2, :event_name => event_name)
63
+ end
64
+ end
65
+
66
+ context 'can take a block or a receiver' do
67
+ it 'calls the block when the event matches' do
68
+ block_called = false
69
+ EventBus.subscribe(event_name) do |info|
70
+ block_called = true
71
+ info.should == {:a => 1, :b => 2, :event_name => event_name}
72
+ end
73
+ EventBus.publish(event_name, :a => 1, :b => 2)
74
+ block_called.should be_true
75
+ end
76
+
77
+ it 'does not call the block when the event does not match' do
78
+ block_called = false
79
+ EventBus.subscribe('blah') {|_| block_called = true }
80
+ EventBus.publish(event_name, :a => 1, :b => 2)
81
+ block_called.should be_false
82
+ end
83
+ end
84
+
85
+ context 'listener variant' do
86
+ it 'will not accept a block too' do
87
+ expect { EventBus.subscribe('blah', listener, receiving_method) {|info| }}.to raise_error(ArgumentError)
88
+ end
89
+
90
+ it 'expects a method name' do
91
+ expect { EventBus.subscribe('blah', listener)}.to raise_error(ArgumentError)
92
+ end
93
+ end
94
+
95
+ context 'block variant' do
96
+ it 'requires a block when no listener method is supplied' do
97
+ expect { EventBus.subscribe('blah')}.to raise_error(ArgumentError)
47
98
  end
48
99
  end
49
100
 
50
101
  end
51
102
 
52
103
  describe '.clear' do
53
- it 'sends no event to previous registrants' do
54
- EventBus.listen_for(event_name, listener, receiving_method)
104
+ it 'removes all previous registrants' do
105
+ EventBus.subscribe(event_name, listener, receiving_method)
55
106
  EventBus.clear
56
107
  listener.should_not_receive(receiving_method)
57
- EventBus.announce(event_name, {})
108
+ EventBus.publish(event_name, {})
58
109
  end
59
110
 
60
111
  it 'returns itself, to facilitate cascades' do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: event_bus
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-01-24 00:00:00.000000000 Z
12
+ date: 2013-01-27 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake
@@ -18,7 +18,7 @@ dependencies:
18
18
  requirements:
19
19
  - - ~>
20
20
  - !ruby/object:Gem::Version
21
- version: 0.9.2
21
+ version: 10.0.1
22
22
  type: :development
23
23
  prerelease: false
24
24
  version_requirements: !ruby/object:Gem::Requirement
@@ -26,7 +26,7 @@ dependencies:
26
26
  requirements:
27
27
  - - ~>
28
28
  - !ruby/object:Gem::Version
29
- version: 0.9.2
29
+ version: 10.0.1
30
30
  - !ruby/object:Gem::Dependency
31
31
  name: rspec
32
32
  requirement: !ruby/object:Gem::Requirement
@@ -66,6 +66,8 @@ executables: []
66
66
  extensions: []
67
67
  extra_rdoc_files: []
68
68
  files:
69
+ - .rspec
70
+ - .yardopts
69
71
  - Gemfile
70
72
  - Gemfile.lock
71
73
  - README.md