signals 0.0.2 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 682db5800cf5ba91ba8694e672f9ba94cc766e27
4
- data.tar.gz: 360251fd4a443e0ddac0b738af93e4a05e713026
3
+ metadata.gz: d0a17dcf963e613b1958719ee6335e765e1f4233
4
+ data.tar.gz: f322c5f49706eb819a44e39a8bb54211bf7fc49b
5
5
  SHA512:
6
- metadata.gz: 2bfa9e3d66d07c05840b374089148a69a124fce7fbfd4760ccf896fd331a033751b81a87ecb174d47bfbadba11a95411abdb094301ff53deb07b471d5cbd2fe2
7
- data.tar.gz: 684f968ef7cdfd6be8c9ca7a28e0a49f5e67a7a042a3ad35d703f675809d6b538968017089b3c2a7fa006aa540814888b963a8ab322e7b67a5f11248451b7bb2
6
+ metadata.gz: c6317c3d341b4fd50be0eaf0ef67e5ce8bbab4e1bb99ab60c4a4fa21dbe27d3d3bf6efbc57831b0ca82bb31572dd7be9b020d4ebcc8a3524fe403c4b425de9e0
7
+ data.tar.gz: e20efc2de3708bbf8e53ba7a574dd353799dfd0d58d51787f16e895844287c4f94000ecbbe61a4c142bccb4180841d608a2e2e724804f52ceabef8bf0778eccb
data/.gitignore CHANGED
@@ -15,3 +15,5 @@ spec/reports
15
15
  test/tmp
16
16
  test/version_tmp
17
17
  tmp
18
+ *.sublime-workspace
19
+ *.sublime-project
data/README.md CHANGED
@@ -17,30 +17,43 @@ require 'signals'
17
17
 
18
18
  class Coach
19
19
  include Signals::Publisher
20
-
21
- def run_play
22
- broadcast(:v_formation, self)
23
- end
24
20
  end
25
21
 
26
22
  class Player
23
+ include Signals::Subscriber
24
+
25
+ listen_for :v_formation => :run
26
+ listen_for [:hat_trick, :v_formation] => :audible
27
+ listen_for :stop => [:look, :run]
28
+ listen_for :stop => :audible
29
+
27
30
  def initialize(name)
28
31
  @name = name
29
32
  end
30
33
 
31
- def v_formation(coach)
32
- puts "#{@name} is in position"
34
+ def run(coach)
35
+ puts "#{@name} is running"
36
+ end
37
+
38
+ def audible(coach)
39
+ puts "#{@name} is calling an audible"
40
+ end
41
+
42
+ def look(coach)
43
+ puts "#{@name} is looking"
33
44
  end
34
45
  end
35
46
 
36
- coach = Coach.new
47
+ coach = Coach.new
37
48
  forward = Player.new('John')
38
- center = Player.new('Jeff')
49
+ center = Player.new('Jeff')
39
50
 
40
51
  coach.subscribe(forward)
41
52
  coach.subscribe(center)
42
53
 
43
- coach.run_play
54
+ coach.on(:stop) do |c|
55
+ puts "I'm telling you to stop"
56
+ end
44
57
  ```
45
58
 
46
59
  ## Contributing
@@ -10,7 +10,7 @@ module Signals
10
10
  @event = event
11
11
  end
12
12
 
13
- def execute(event, *args)
13
+ def execute_event(event, *args)
14
14
  if self.event == event
15
15
  self.listener.call(*args)
16
16
  end
@@ -1,34 +1,45 @@
1
1
  module Signals
2
2
 
3
3
  module Publisher
4
- # Broadcasts an event to all of the subscribed listeners
5
- # @return [void]
6
- def broadcast(event, *args)
7
- listeners.each do |listener|
8
- listener.execute(event, *args)
9
- end
10
- nil
11
- end
12
4
 
13
- # Creates a one off listener that will respond to the event provided only
14
- # @param [Object] event the event that is triggered
15
- # @return [void]
16
- def on(event, &block)
17
- listeners.add(BlockListener.new(event, &block))
18
- nil
5
+ def self.included(base)
6
+ base.extend(ClassMethods)
7
+ base.send(:include, InstanceMethods)
19
8
  end
20
9
 
21
- # Subscribe a listener to the publisher
22
- # @return [void]
23
- def subscribe(listener)
24
- listeners.add(Listener.new(listener))
25
- nil
10
+ module ClassMethods
26
11
  end
27
12
 
28
- # All of the listeners subscribed to a publisher
29
- # @return [Set] a unique set of listeners
30
- def listeners
31
- @listeners ||= Set.new
13
+ module InstanceMethods
14
+ # Broadcasts an event to all of the subscribed listeners
15
+ # @return [void]
16
+ def broadcast(event, *args)
17
+ listeners.each do |listener|
18
+ listener.execute_event(event, *args)
19
+ end
20
+ nil
21
+ end
22
+
23
+ # Creates a one off listener that will respond to the event provided only
24
+ # @param [Object] event the event that is triggered
25
+ # @return [void]
26
+ def on(event, &block)
27
+ listeners.add(BlockListener.new(event, &block))
28
+ nil
29
+ end
30
+
31
+ # Subscribe a listener to the publisher
32
+ # @return [void]
33
+ def subscribe(listener)
34
+ listeners.add(listener)
35
+ nil
36
+ end
37
+
38
+ # All of the listeners subscribed to a publisher
39
+ # @return [Set] a unique set of listeners
40
+ def listeners
41
+ @listeners ||= Set.new
42
+ end
32
43
  end
33
44
  end
34
45
 
@@ -0,0 +1,125 @@
1
+ module Signals
2
+
3
+ module Subscriber
4
+
5
+ def self.included(base)
6
+ base.extend(ClassMethods)
7
+ base.send(:include, InstanceMethods)
8
+ end
9
+
10
+ module ClassMethods
11
+ # Register the class to listen for specific events and react accordingly.
12
+ # Any combination can be used. Listen for only accepts a hash as the
13
+ # parameter.
14
+ #
15
+ # == Example
16
+ #
17
+ # class Something
18
+ # include Signals::Subscriber
19
+ #
20
+ # listen_for :one => :action
21
+ # listen_for :one => [:action, :another]
22
+ # listen_for :one => [:and_another]
23
+ # listen_for [:one, :two] => :action
24
+ # listen_for [:one, :two] => [:action]
25
+ # listen_for [:one] => [:and_another]
26
+ # end
27
+ #
28
+ # @param [Hash] params
29
+ # @return [void]
30
+ def listen_for(params={})
31
+ params.each do |k, v|
32
+ if k.is_a?(Array)
33
+ k.each { |e| add_event(e, v) }
34
+ else
35
+ add_event(k, v)
36
+ end
37
+ end
38
+ nil
39
+ end
40
+
41
+ # @param [Symbol] e the event
42
+ # @param [Array|Symbol] actions the actions to be taken
43
+ def add_event(e, actions)
44
+ event(e).concat(actions.is_a?(Array) ? actions : [actions])
45
+ end
46
+
47
+ # @return [Hash]
48
+ def events
49
+ @@events ||= Hash.new
50
+ end
51
+
52
+ private
53
+
54
+ # @param [Symbol] key
55
+ # @return [Array]
56
+ def event(key)
57
+ events[key] ||= Array.new
58
+ end
59
+ end
60
+
61
+ module InstanceMethods
62
+ def execute_event(event, *args)
63
+ if event_enabled?(event)
64
+ actions_for(event).each do |action|
65
+ self.send(action, *args) if self.respond_to?(action)
66
+ end
67
+ end
68
+ end
69
+
70
+ # Disables an event temporarily
71
+ # @param [Symbol] event
72
+ # @return [void]
73
+ def disable_event(event)
74
+ disabled_events.add(event)
75
+ nil
76
+ end
77
+
78
+ # Enables an event that was disabled
79
+ # @param [Symbol] event
80
+ # @return [void]
81
+ def enable_event(event)
82
+ disabled_events.delete(event)
83
+ nil
84
+ end
85
+
86
+ # Checks to see if the event is disabled
87
+ # @param [Symbol] event
88
+ # @return [Boolean]
89
+ def event_disabled?(event)
90
+ disabled_events.include?(event)
91
+ end
92
+
93
+ # Checks to see if the event is enabled
94
+ # @param [Symbol] event
95
+ # @return [Boolean]
96
+ def event_enabled?(event)
97
+ !event_disabled?(event)
98
+ end
99
+
100
+ # Checks to see if the event is present
101
+ # @param [Symbol] event
102
+ # @return [Boolean]
103
+ def event?(event)
104
+ events.include?(event)
105
+ end
106
+
107
+ def actions_for(event)
108
+ self.events[event] || Array.new
109
+ end
110
+
111
+ # The set of disabled events
112
+ # @return [Set] a set of disabled events
113
+ def disabled_events
114
+ @disabled_events ||= Set.new
115
+ end
116
+
117
+ # The hash of events that the subscriber is listening for
118
+ # @return [Hash]
119
+ def events
120
+ self.class.events.freeze
121
+ end
122
+ end
123
+ end
124
+
125
+ end
@@ -1,3 +1,3 @@
1
1
  module Signals
2
- VERSION = "0.0.2"
2
+ VERSION = "1.0.0"
3
3
  end
data/lib/signals.rb CHANGED
@@ -3,6 +3,6 @@ end
3
3
 
4
4
  require 'set'
5
5
  require 'signals/version'
6
- require 'signals/listener'
7
6
  require 'signals/block_listener'
8
7
  require 'signals/publisher'
8
+ require 'signals/subscriber'
@@ -2,12 +2,12 @@ require 'spec_helper'
2
2
 
3
3
  describe Signals::BlockListener do
4
4
 
5
- describe '#execute' do
5
+ describe '#execute_event' do
6
6
  it 'should execute the event it was registered for' do
7
7
  block = Signals::BlockListener.new(:testing)
8
8
  block.stub(listener: double('lambda', call: true))
9
9
 
10
- block.execute(:testing)
10
+ block.execute_event(:testing)
11
11
 
12
12
  block.listener.should have_received(:call).once
13
13
  end
@@ -16,7 +16,7 @@ describe Signals::BlockListener do
16
16
  block = Signals::BlockListener.new(:testing)
17
17
  block.stub(listener: double('lambda', call: true))
18
18
 
19
- block.execute(:another)
19
+ block.execute_event(:another)
20
20
 
21
21
  block.listener.should_not have_received(:call)
22
22
  end
@@ -25,7 +25,7 @@ describe Signals::BlockListener do
25
25
  block = Signals::BlockListener.new(:testing)
26
26
  block.stub(listener: double('lambda', call: true))
27
27
 
28
- block.execute(:testing, 1, 2)
28
+ block.execute_event(:testing, 1, 2)
29
29
 
30
30
  block.listener.should have_received(:call).with(1,2).once
31
31
  end
@@ -5,42 +5,49 @@ describe Signals::Publisher do
5
5
  include Signals::Publisher
6
6
  end
7
7
 
8
- class SimpleListener
9
- end
10
-
11
- let(:publisher) { DummyPublisher.new }
12
-
13
8
  describe '#broadcast' do
14
- it 'should broadcast an event' do
15
- listener = double('AListener', execute: true)
16
- publisher.stub(listeners: Set.new([listener]))
9
+ it 'should broadcast an event to subscribers' do
10
+ publisher = DummyPublisher.new
11
+ listener = double('Listener', execute_event: true)
12
+ listeners = [listener]
13
+ publisher.stub(listeners: listeners)
17
14
 
18
15
  publisher.broadcast(:event, 1, 2)
19
16
 
20
- listener.should have_received(:execute).with(:event, 1, 2)
17
+ listener.should have_received(:execute_event).with(:event, 1, 2)
21
18
  end
22
19
  end
23
20
 
24
- describe '#subscribe' do
25
- it 'should subscribe a listener' do
26
- expect {
27
- publisher.subscribe(SimpleListener.new)
28
- }.to_not raise_error
21
+ describe '#on' do
22
+ it 'should should be successful' do
23
+ publisher = DummyPublisher.new
24
+ listeners = double('Set', add: true)
25
+ publisher.stub(listeners: listeners)
26
+
27
+ publisher.on(:event) do
28
+ true
29
+ end
30
+
31
+ listeners.should have_received(:add).once
29
32
  end
30
33
  end
31
34
 
32
- describe '#on' do
33
- it 'should subscribe a block listener' do
34
- publisher.stub(listeners: double('Set', add: true))
35
+ describe '#subscribe' do
36
+ it 'should subscribe a subscriber' do
37
+ publisher = DummyPublisher.new
38
+ listeners = double('Set', add: true)
39
+ listener = double('Listener')
40
+ publisher.stub(listeners: listeners)
35
41
 
36
- publisher.on(:event) { true }
42
+ publisher.subscribe(listener)
37
43
 
38
- publisher.listeners.should have_received(:add).once
44
+ listeners.should have_received(:add).with(listener).once
39
45
  end
40
46
  end
41
47
 
42
48
  describe '#listeners' do
43
- subject { publisher.listeners }
49
+ subject { DummyPublisher.new.listeners }
44
50
  it { should be_a(Set) }
45
51
  end
52
+
46
53
  end
@@ -0,0 +1,262 @@
1
+ require 'spec_helper'
2
+
3
+ describe Signals::Subscriber do
4
+ class DummySubscriber
5
+ include Signals::Subscriber
6
+
7
+ listen_for :event => :action_1
8
+ listen_for :complex => [:action_2, :action_3]
9
+ listen_for [:event, :complex] => :action_4
10
+ listen_for [:event, :complex] => [:action_5, :action_6]
11
+ end
12
+
13
+ describe '#execute_event' do
14
+ context 'when the event is disabled' do
15
+ it 'should not execute the actions' do
16
+ subscriber = DummySubscriber.new
17
+ subscriber.stub(event_enabled?: false, action_1: true)
18
+
19
+ subscriber.execute_event(:event)
20
+
21
+ subscriber.should_not have_received(:action_1)
22
+ end
23
+ end
24
+
25
+ context 'when the event is enabled' do
26
+ it 'should execute the actions' do
27
+ subscriber = DummySubscriber.new
28
+ subscriber.stub(event_enabled?: true, action_1: true)
29
+
30
+ subscriber.execute_event(:event)
31
+
32
+ subscriber.should have_received(:action_1).once
33
+ end
34
+ end
35
+ end
36
+
37
+
38
+ describe '#disable_event' do
39
+ it 'should disable an event' do
40
+ subscriber = DummySubscriber.new
41
+ events = double('Events', add: true)
42
+ subscriber.stub(disabled_events: events)
43
+
44
+ subscriber.disable_event(:event)
45
+
46
+ events.should have_received(:add).with(:event).once
47
+ end
48
+ end
49
+
50
+
51
+ describe '#enable_event' do
52
+ it 'should enable an event' do
53
+ subscriber = DummySubscriber.new
54
+ events = double('Events', delete: true)
55
+ subscriber.stub(disabled_events: events)
56
+
57
+ subscriber.enable_event(:event)
58
+
59
+ events.should have_received(:delete).with(:event).once
60
+ end
61
+ end
62
+
63
+
64
+ describe '#event_disabled?' do
65
+ context 'when an event is disabled' do
66
+ it 'should return true' do
67
+ subscriber = DummySubscriber.new
68
+ set = Set.new([:event])
69
+ subscriber.stub(disabled_events: set)
70
+
71
+ subscriber.event_disabled?(:event).should be_true
72
+ end
73
+ end
74
+
75
+ context 'when an event is enabled' do
76
+ it 'should return false' do
77
+ subscriber = DummySubscriber.new
78
+ set = Set.new([])
79
+ subscriber.stub(disabled_events: set)
80
+
81
+ subscriber.event_disabled?(:event).should be_false
82
+ end
83
+ end
84
+ end
85
+
86
+
87
+ describe '#event_enabled?' do
88
+ context 'when an event is disabled' do
89
+ it 'should return false' do
90
+ subscriber = DummySubscriber.new
91
+ set = Set.new([:event])
92
+ subscriber.stub(disabled_events: set)
93
+
94
+ subscriber.event_enabled?(:event).should be_false
95
+ end
96
+ end
97
+
98
+ context 'when an event is enabled' do
99
+ it 'should return true' do
100
+ subscriber = DummySubscriber.new
101
+ set = Set.new([])
102
+ subscriber.stub(disabled_events: set)
103
+
104
+ subscriber.event_enabled?(:event).should be_true
105
+ end
106
+ end
107
+ end
108
+
109
+
110
+ describe '#event?' do
111
+ context 'when the event is on the subscriber' do
112
+ it 'should return true' do
113
+ subscriber = DummySubscriber.new
114
+ subscriber.event?(:event).should be_true
115
+ end
116
+ end
117
+
118
+ context 'when the event is not on the subscriber' do
119
+ it 'should return false' do
120
+ subscriber = DummySubscriber.new
121
+ subscriber.event?(:not_here).should be_false
122
+ end
123
+ end
124
+ end
125
+
126
+
127
+ describe '#actions_for' do
128
+ context 'when the event is on the subscriber' do
129
+ it 'should return return its actions' do
130
+ subscriber = DummySubscriber.new
131
+ subscriber.actions_for(:event).should eq([:action_1, :action_4, :action_5, :action_6])
132
+ end
133
+ end
134
+
135
+ context 'when the event is not on the subscriber' do
136
+ it 'should return false' do
137
+ subscriber = DummySubscriber.new
138
+ subscriber.actions_for(:not_here).should eq([])
139
+ end
140
+ end
141
+ end
142
+
143
+
144
+ describe '#disabled_events' do
145
+ context 'when no events are disabled' do
146
+ it 'should be an empty set' do
147
+ subscriber = DummySubscriber.new
148
+ subscriber.disabled_events.should be_empty
149
+ end
150
+ end
151
+
152
+ context 'when an event is disabled' do
153
+ it 'should not be empty' do
154
+ subscriber = DummySubscriber.new
155
+ subscriber.disable_event(:event)
156
+ subscriber.disabled_events.should_not be_empty
157
+ end
158
+ end
159
+ end
160
+
161
+
162
+ describe '#events' do
163
+ it 'should not be empty' do
164
+ subscriber = DummySubscriber.new
165
+ subscriber.events.should_not be_empty
166
+ end
167
+ end
168
+
169
+
170
+ describe '.listen_for' do
171
+ class SubscriberListenTest
172
+ include Signals::Subscriber
173
+ end
174
+ let(:klass) { SubscriberListenTest }
175
+ context 'when the event is a symbol' do
176
+ context 'when the action is a symbol' do
177
+ it 'should register the action for the event' do
178
+ klass.stub(add_event: true)
179
+
180
+ klass.listen_for(:event_1 => :action_1)
181
+
182
+ klass.should have_received(:add_event).with(:event_1, :action_1)
183
+ end
184
+ end
185
+
186
+ context 'when the action is an array of symbols' do
187
+ it 'should register the actions for the event' do
188
+ klass.stub(add_event: true)
189
+
190
+ klass.listen_for(:event_1 => [:action_2, :action_3])
191
+
192
+ klass.should have_received(:add_event).with(:event_1, [:action_2, :action_3])
193
+ end
194
+ end
195
+ end
196
+
197
+ context 'when the event is an array of symbols' do
198
+ context 'when the action is a symbol' do
199
+ it 'should register the action for the events' do
200
+ klass.stub(add_event: true)
201
+
202
+ klass.listen_for([:event_2, :event_3] => :action_1)
203
+
204
+ klass.should have_received(:add_event).twice
205
+ end
206
+ end
207
+ context 'when the action is an array of symbols' do
208
+ it 'should register the actions for the events' do
209
+ klass.stub(add_event: true)
210
+
211
+ klass.listen_for([:event_2, :event_3] => [:action_1, :action_2])
212
+
213
+ klass.should have_received(:add_event).twice
214
+ end
215
+ end
216
+ end
217
+ end
218
+
219
+
220
+ describe '.add_event' do
221
+ class SubscriberAddEvent
222
+ include Signals::Subscriber
223
+ end
224
+ let(:klass) { SubscriberAddEvent }
225
+
226
+ context 'when the actions is an array of symbols' do
227
+ it 'should be successful' do
228
+ hash = double('Hash', concat: true)
229
+ klass.stub(event: hash)
230
+
231
+ klass.add_event(:event_1, [:action_1, :action_2])
232
+
233
+ klass.should have_received(:event).with(:event_1)
234
+ end
235
+ end
236
+ context 'when the action is a symbol' do
237
+ it 'should be successful' do
238
+ hash = double('Hash', concat: true)
239
+ klass.stub(event: hash)
240
+
241
+ klass.add_event(:event_1, :action_3)
242
+
243
+ klass.should have_received(:event).with(:event_1)
244
+ end
245
+ end
246
+ end
247
+
248
+
249
+ describe '.events' do
250
+ subject { DummySubscriber.events }
251
+ it { should be_a(Hash) }
252
+ end
253
+
254
+
255
+ describe '.event' do
256
+ it 'should raise an exception' do
257
+ expect {
258
+ DummySubscriber.event(1)
259
+ }.to raise_error
260
+ end
261
+ end
262
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: signals
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matthew Johnston
@@ -69,13 +69,13 @@ files:
69
69
  - Rakefile
70
70
  - lib/signals.rb
71
71
  - lib/signals/block_listener.rb
72
- - lib/signals/listener.rb
73
72
  - lib/signals/publisher.rb
73
+ - lib/signals/subscriber.rb
74
74
  - lib/signals/version.rb
75
75
  - signals.gemspec
76
76
  - spec/signals/block_listener_spec.rb
77
- - spec/signals/listener_spec.rb
78
77
  - spec/signals/publisher_spec.rb
78
+ - spec/signals/subscriber_spec.rb
79
79
  - spec/spec_helper.rb
80
80
  homepage: https://github.com/warmwaffles/signals
81
81
  licenses:
@@ -103,6 +103,6 @@ specification_version: 4
103
103
  summary: A lightweight publish / subscribe library
104
104
  test_files:
105
105
  - spec/signals/block_listener_spec.rb
106
- - spec/signals/listener_spec.rb
107
106
  - spec/signals/publisher_spec.rb
107
+ - spec/signals/subscriber_spec.rb
108
108
  - spec/spec_helper.rb
@@ -1,21 +0,0 @@
1
- module Signals
2
-
3
- class Listener
4
- attr_reader :listener
5
-
6
- # @param [Object] listener the listener you want to use
7
- def initialize(listener)
8
- @listener = listener
9
- end
10
-
11
- # @param [Object] event
12
- # @return [void]
13
- def execute(event, *args)
14
- if @listener.respond_to?(event)
15
- @listener.send(event, *args)
16
- end
17
- nil
18
- end
19
- end
20
-
21
- end
@@ -1,31 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Signals::Listener do
4
-
5
- describe '#execute' do
6
- it 'should execute an existing method with no params' do
7
- simple = double('SimpleListener', testing: true)
8
- listener = Signals::Listener.new(simple)
9
-
10
- listener.execute(:testing)
11
-
12
- listener.listener.should have_received(:testing).once
13
- end
14
-
15
- it 'should execute an existing method with params' do
16
- simple = double('SimpleListener', testing: true)
17
- listener = Signals::Listener.new(simple)
18
-
19
- listener.execute(:testing, 1, 2)
20
-
21
- listener.listener.should have_received(:testing).with(1, 2).once
22
- end
23
-
24
- it 'should not raise an error when the method does not exist' do
25
- simple = double('SimpleListener')
26
- listener = Signals::Listener.new(simple)
27
-
28
- expect { listener.execute(:testing) }.to_not raise_error
29
- end
30
- end
31
- end