wisper 1.6.1 → 2.0.0.rc1

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: 07d3725f067d12c6952f8f3dad49ee68ec0aa0a9
4
- data.tar.gz: 643d00e3723146e6783cf1b819f16ee941663b20
3
+ metadata.gz: e196cad72b441abfb2aa87211e0241729dbfe803
4
+ data.tar.gz: d1506f6acdac8f354ab801814c73726933201abd
5
5
  SHA512:
6
- metadata.gz: 33edefa84e8681b40ac3e3375120bf69446b4285a76b6cb4d40793289a7deaef42f839c686c7ca9246ff329a2c7c9ff71527c789581876773ea64d05539cda5e
7
- data.tar.gz: c203cdab275836176dc0f47b6bc690967950793144b580feacdd3d2171a8905ea53fd1e0231ab8218a9d15068d4e8a6967d77172e2f56d810971efbfbdf79cd1
6
+ metadata.gz: 2f1fee408008e32f3861df1438edec17fb05e599e1bb6a196e6c288a5def62d8736d9d7667e22089bee64dae89e54f3d2a8615ecbba24a37efdd6aa23e0fb41d
7
+ data.tar.gz: b6f4e0b0bdfd905c8ae1562ca79f2c7606804de8ee7e23c4d378019ff780cb3176c1467752b6ec61ee16499658fe9de48bf1b8611da590bdf29bb8d89dcd5b9b
@@ -0,0 +1,2 @@
1
+ e�I�fwh��~�PDnZ��/Me��n�j@����Zu$�������'�������)��3�X�k��L���K�4�?B���t7D{��8٭�;�¦�d��m�s@� �!�^*���̊�ǒ����>��3w`��V�Ms���ԙ�$����C�% �
2
+ >q��̺��~��]�E+�� /g�&����W��u!3�CD���f��Sϥ��c⺼Z~�_�wr�D"Md׭:C*�3�\]p�L��
Binary file
data/.gitignore CHANGED
@@ -1,5 +1,6 @@
1
1
  *.gem
2
2
  *.rbc
3
+ .ruby-version
3
4
  .bundle
4
5
  .config
5
6
  .yardoc
@@ -6,7 +6,6 @@ rvm:
6
6
  - '1.9.3'
7
7
  - '2.0.0'
8
8
  - '2.1.2'
9
- - '2.2.2'
10
9
  - jruby
11
10
  - rbx-2
12
11
  ### ALLOWED FAILURES ###
@@ -1,8 +1,11 @@
1
- ## 1.6.1 (17 Aug 2015)
1
+ ## 2.0.0.rc1 (17 Dec 2014)
2
2
 
3
3
  Authors: Kris Leech
4
4
 
5
- * Fixed Ruby warnings
5
+ * remove: deprecated methods
6
+ * remove: rspec matcher and stubbing (moved to [wisper-rspec](https://github.com/krisleech/wisper-rspec))
7
+ * feature: add regexp support to `on` argument
8
+ * remove: announce alias for broadcasting
6
9
 
7
10
  ## 1.6.0 (25 Oct 2014)
8
11
 
@@ -0,0 +1,55 @@
1
+ # How to Contribute
2
+
3
+ We very much welcome contributions to Wisper.
4
+
5
+ ## Getting started
6
+
7
+ Please first check the existing [Issues](https://github.com/krisleech/wisper/issues)
8
+ and [Pull Requests](https://github.com/krisleech/wisper/pulls) to ensure your
9
+ issue has not already been discused.
10
+
11
+ ## Bugs
12
+
13
+ Please submit a bug report to the issue tracker, with the version of Wisper
14
+ and Ruby you are using and a small code sample (or better yet a failing test).
15
+
16
+ ## Features
17
+
18
+ Please open an issue with your proposed feature. We can discuss the feature and
19
+ if it is acceptable we can also discuss implimentation details. You will in
20
+ most cases have to submit a PR which adds the feature.
21
+
22
+ We also have a [Gitter channel](https://gitter.im/krisleech/wisper).
23
+
24
+ Wisper is a micro library and will remain lean. Some features would be most
25
+ appropriate as an extension to Wisper.
26
+
27
+ ## Questions
28
+
29
+ Try the [Wiki](https://github.com/krisleech/wisper/wiki) first, the examples
30
+ and how to sections have lots of information.
31
+
32
+ Please ask questions on StackOverflow, [tagged wisper](https://stackoverflow.com/questions/tagged/wisper).
33
+
34
+ Feel free to ping me the URL on [Twitter](https://twitter.com/krisleech).
35
+
36
+ We also have a [channel on Gitter](https://gitter.im/krisleech/wisper).
37
+
38
+ ## Pull requests
39
+
40
+ * Fork the project, create a new branch from `v1` or `master`.
41
+ * Squash commits which are related.
42
+ * Write a [good commit message](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html)
43
+ * Documentation only changes should have `[skip ci]` in the commit message
44
+ * Follow existing code style in terms of syntax, indentation etc.
45
+ * Add an entry to the CHANGELOG
46
+ * Do not bump the VERSION, but do indicate in the CHANGELOG if the change is
47
+ not backwards compatible.
48
+ * Issue a Pull Request
49
+
50
+ ## Versions
51
+
52
+ The `v1` branch is a long lived branch and you should
53
+ branch from this if you wish to fix an issue in version `~> 1.0`.
54
+
55
+ The `master` branch will target the next version of Wisper.
data/Gemfile CHANGED
@@ -9,4 +9,5 @@ gem 'coveralls', require: false
9
9
  group :extras do
10
10
  gem 'flay'
11
11
  gem 'pry'
12
+ gem 'yard'
12
13
  end
data/README.md CHANGED
@@ -32,10 +32,10 @@ to subscribed listeners. Listeners subscribe, at runtime, to the publisher.
32
32
  ```ruby
33
33
  class CancelOrder
34
34
  include Wisper::Publisher
35
-
35
+
36
36
  def call(order_id)
37
37
  order = Order.find_by_id(order_id)
38
-
38
+
39
39
  # business logic...
40
40
 
41
41
  if order.cancelled?
@@ -49,7 +49,7 @@ end
49
49
 
50
50
  When a publisher broadcasts an event it can include number of arguments.
51
51
 
52
- The `broadcast` method is also aliased as `publish` and `announce`.
52
+ The `broadcast` method is also aliased as `publish`.
53
53
 
54
54
  You can also include `Wisper.publisher` instead of `Wisper::Publisher`.
55
55
 
@@ -202,8 +202,8 @@ Temporary Global Listeners are threadsafe.
202
202
  ## Subscribing to selected events
203
203
 
204
204
  By default a listener will get notified of all events it can respond to. You
205
- can limit which events a listener is notified of by passing an event or array
206
- of events to `on:`.
205
+ can limit which events a listener is notified of by passing an string, symbol,
206
+ array or regular expression to `on`:
207
207
 
208
208
  ```ruby
209
209
  post_creater.subscribe(PusherListener.new, on: :create_post_successful)
@@ -224,7 +224,7 @@ use the default prefix, "on".
224
224
 
225
225
  ## Mapping an event to a different method
226
226
 
227
- By default the method called on the subscriber is the same as the event
227
+ By default the method called on the listener is the same as the event
228
228
  broadcast. However it can be mapped to a different method using `with:`.
229
229
 
230
230
  ```ruby
@@ -257,82 +257,7 @@ You could also alias the method within your listener, as such
257
257
 
258
258
  ## RSpec
259
259
 
260
- ### Broadcast Matcher
261
-
262
- ```ruby
263
- require 'wisper/rspec/matchers'
264
-
265
- RSpec::configure do |config|
266
- config.include(Wisper::RSpec::BroadcastMatcher)
267
- end
268
-
269
- expect { publisher.execute }.to broadcast(:an_event)
270
- ```
271
-
272
- ### Using message expections
273
-
274
- If you need to assert on the arguments broadcast you can subscribe a double
275
- with a [message expection](https://github.com/rspec/rspec-mocks#message-expectations)
276
- and then use any of the [argument matchers](https://github.com/rspec/rspec-mocks#argument-matchers).
277
-
278
- ```ruby
279
- listener = double('Listener')
280
-
281
- expect(listener).to receive(:an_event).with(some_args)
282
-
283
- publisher.subscribe(listener)
284
-
285
- publisher.execute
286
- ```
287
-
288
- ### Stubbing publishers
289
-
290
- You can stub publishers and their events in unit (isolated) tests that only care about reacting to events.
291
-
292
- Given this piece of code:
293
-
294
- ```ruby
295
- class MyController
296
- def create
297
- publisher = MyPublisher.new
298
-
299
- publisher.on(:some_event) do |variable|
300
- return "Hello with #{variable}!"
301
- end
302
-
303
- publisher.execute
304
- end
305
- end
306
- ```
307
-
308
- You can test it like this:
309
-
310
- ```ruby
311
- require 'wisper/rspec/stub_wisper_publisher'
312
-
313
- describe MyController do
314
- context "on some_event" do
315
- before do
316
- stub_wisper_publisher("MyPublisher", :execute, :some_event, "foo")
317
- end
318
-
319
- it "renders" do
320
- response = MyController.new.create
321
- expect(response).to eq "Hello with foo!"
322
- end
323
- end
324
- end
325
- ```
326
-
327
- This is useful when testing Rails controllers in isolation from the business logic.
328
-
329
- You can use any number of args to pass to the event:
330
-
331
- ```ruby
332
- stub_wisper_publisher("MyPublisher", :execute, :some_event, "foo1", "foo2", ...)
333
- ```
334
-
335
- See `spec/lib/rspec_extensions_spec.rb` for a runnable example.
260
+ Please see [wisper-rspec](https://github.com/krisleech/wisper-rspec).
336
261
 
337
262
  ## Clearing Global Listeners
338
263
 
@@ -0,0 +1,21 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIDeDCCAmCgAwIBAgIBATANBgkqhkiG9w0BAQUFADBBMRMwEQYDVQQDDAprcmlz
3
+ LmxlZWNoMRUwEwYKCZImiZPyLGQBGRYFZ21haWwxEzARBgoJkiaJk/IsZAEZFgNj
4
+ b20wHhcNMTQxMTA1MTEwMzQ4WhcNMTUxMTA1MTEwMzQ4WjBBMRMwEQYDVQQDDApr
5
+ cmlzLmxlZWNoMRUwEwYKCZImiZPyLGQBGRYFZ21haWwxEzARBgoJkiaJk/IsZAEZ
6
+ FgNjb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtW0/UtrFK/tSm
7
+ uq5HnCUkZAQjnSaZ/h1Tby9s30CDJjDUdizPRdLQCplLDAMHFsAfTyD0Mc+Ez8o9
8
+ CdTh8EZ4TSf+nokL+SUprpdR6qm6OWU03Ntd+bDCP0+rdqCX82g3N3mnvjR9aD3a
9
+ +hd9Fhp0WuEyqTNjQ7IlopeUPDW7eYfSwI4bjfRHxsDR1GuZ3j0npxCAgAIN41WH
10
+ MSTTZhdo0vKEiKZEtMMnT6w6fG/c3XIhVVPGnqy5+IZqBL0SYC+WJL3vC6yUBgqB
11
+ nrpA/q+b3M69W+q+TkGv0qOnrxln0O7J2pykjoGIxUhhRkiGEldEhy9dxQWubffr
12
+ hVJ4F0wLAgMBAAGjezB5MAkGA1UdEwQCMAAwCwYDVR0PBAQDAgSwMB0GA1UdDgQW
13
+ BBSzq+x8mwj0ldvNkvjOl44OJG354jAfBgNVHREEGDAWgRRrcmlzLmxlZWNoQGdt
14
+ YWlsLmNvbTAfBgNVHRIEGDAWgRRrcmlzLmxlZWNoQGdtYWlsLmNvbTANBgkqhkiG
15
+ 9w0BAQUFAAOCAQEAF5M2Md3DcNCrQrDRDLaIzHaMM+RTgfbpgmZ6tU0iEowES18g
16
+ QWQgrAbFuvQRPETJ2gbL5AC35fEqN80nU+3GhgW/bDYhII5D3PGLMorxhFw1JYLI
17
+ 0Fd7MCE0sImc2rPybYUdpZ6TxvqgPKp+8CzM8vBUrdYd+dSHXit1piViWBcZcJb+
18
+ EL5Ze4IodjkCPAeHvu2MQieieViLyfB4eG1syvfkxvAXCjFHeQoIFP16vVtcljdF
19
+ k5cHH/4SGeMuGrSLRsqVvltxVV3AbQAfH8WUos2brjYHsoH5tVPrJ7UcFhzP95oU
20
+ pEfFMW42smiNTOXpzG6JoIpA11szEHFT5ZS+UQ==
21
+ -----END CERTIFICATE-----
@@ -11,21 +11,6 @@ require 'wisper/broadcasters/send_broadcaster'
11
11
  require 'wisper/broadcasters/logger_broadcaster'
12
12
 
13
13
  module Wisper
14
- def self.included(base)
15
- warn "[DEPRECATION] `include Wisper::Publisher` instead of `include Wisper`"
16
- base.class_eval { include Wisper::Publisher }
17
- end
18
-
19
- def self.with_listeners(*args, &block)
20
- warn "[DEPRECATION] `use Wisper.subscribe` instead of `Wisper.with_listeners`"
21
- self.subscribe(*args, &block)
22
- end
23
-
24
- def self.add_listener(listener, options = {})
25
- warn "[DEPRECATION] `use Wisper.subscribe` instead of `Wisper.add_listener`"
26
- self.subscribe(listener, options)
27
- end
28
-
29
14
  # Examples:
30
15
  #
31
16
  # Wisper.subscribe(AuditRecorder.new)
@@ -8,15 +8,15 @@ module Wisper
8
8
  @broadcaster = broadcaster
9
9
  end
10
10
 
11
- def broadcast(subscriber, publisher, event, args)
12
- @logger.info("[WISPER] #{name(publisher)} published #{event} to #{name(subscriber)} with #{arg_names(args)}")
13
- @broadcaster.broadcast(subscriber, publisher, event, args)
11
+ def broadcast(listener, publisher, event, args)
12
+ @logger.info("[WISPER] #{name(publisher)} published #{event} to #{name(listener)} with #{arg_names(args)}")
13
+ @broadcaster.broadcast(listener, publisher, event, args)
14
14
  end
15
15
 
16
16
  private
17
17
 
18
18
  def name(object)
19
- id_method = %w(id uuid key object_id).find { |possibility| object.respond_to?(possibility) }
19
+ id_method = %w(id uuid key object_id).find { |id_method| object.respond_to?(id_method) }
20
20
  id = object.send(id_method)
21
21
  class_name = object.class == Class ? object.name : object.class.name
22
22
  "#{class_name}##{id}"
@@ -1,8 +1,8 @@
1
1
  module Wisper
2
2
  module Broadcasters
3
3
  class SendBroadcaster
4
- def broadcast(subscriber, publisher, event, args)
5
- subscriber.public_send(event, *args)
4
+ def broadcast(listener, publisher, event, args)
5
+ listener.public_send(event, *args)
6
6
  end
7
7
  end
8
8
  end
@@ -8,14 +8,19 @@ module Wisper
8
8
  @broadcasters = Broadcasters.new
9
9
  end
10
10
 
11
- def broadcaster(name, broadcaster)
12
- @broadcasters[name] = broadcaster
11
+ # registers a broadcaster, referenced by key
12
+ #
13
+ # @param key [String, #to_s] an arbitrary key
14
+ # @param broadcaster [#broadcast] a broadcaster
15
+ def broadcaster(key, broadcaster)
16
+ @broadcasters[key] = broadcaster
17
+ self
13
18
  end
14
19
 
15
20
  class Broadcasters
16
21
  extend Forwardable
17
22
 
18
- def_delegators :@data, :[], :[]=, :empty?, :include?, :clear
23
+ def_delegators :@data, :fetch, :[], :[]=, :empty?, :include?, :clear
19
24
 
20
25
  def initialize
21
26
  @data = {}
@@ -1,7 +1,9 @@
1
- require 'singleton'
2
-
3
1
  # Handles global subscriptions
4
2
 
3
+ # @api private
4
+
5
+ require 'singleton'
6
+
5
7
  module Wisper
6
8
  class GlobalListeners
7
9
  include Singleton
@@ -50,11 +52,6 @@ module Wisper
50
52
  instance.clear
51
53
  end
52
54
 
53
- def self.add_listener(listener, options = {}) # deprecated
54
- warn "[DEPRECATION] use `subscribe` instead of `add_listener`"
55
- subscribe(listener, options)
56
- end
57
-
58
55
  private
59
56
 
60
57
  def with_mutex
@@ -4,42 +4,58 @@ module Wisper
4
4
  registrations.map(&:listener).freeze
5
5
  end
6
6
 
7
+ # subscribe a listener
8
+ #
9
+ # @example
10
+ # my_publisher.subscribe(MyListener.new)
11
+ #
12
+ # @return [self]
7
13
  def subscribe(listener, options = {})
8
14
  local_registrations << ObjectRegistration.new(listener, options)
9
15
  self
10
16
  end
11
17
 
18
+ # subscribe a block
19
+ #
20
+ # @example
21
+ # my_publisher.on(:order_created) { |args| ... }
22
+ #
23
+ # @return [self]
12
24
  def on(*events, &block)
13
25
  raise ArgumentError, 'must give at least one event' if events.empty?
14
26
  local_registrations << BlockRegistration.new(block, on: events)
15
27
  self
16
28
  end
17
29
 
18
- def add_block_listener(options = {}, &block)
19
- warn "[DEPRECATED] use `on` instead of `add_block_listener`"
20
- local_registrations << BlockRegistration.new(block, options)
30
+ # broadcasts an event
31
+ #
32
+ # @example
33
+ # def call
34
+ # # ...
35
+ # broadcast(:finished, self)
36
+ # end
37
+ #
38
+ # @return [self]
39
+ def broadcast(event, *args)
40
+ registrations.each do | registration |
41
+ registration.broadcast(clean_event(event), self, *args)
42
+ end
21
43
  self
22
44
  end
23
45
 
24
- def add_listener(listener, options = {})
25
- warn "[DEPRECATED] use `subscribe` instead of `add_listener`"
26
- subscribe(listener, options)
27
- end
46
+ alias :publish :broadcast
28
47
 
29
- def respond_to(*events, &block)
30
- warn '[DEPRECATED] use `on` instead of `respond_to`'
31
- on(*events, &block)
32
- end
48
+ private :broadcast, :publish
33
49
 
34
50
  module ClassMethods
51
+ # subscribe a listener
52
+ #
53
+ # @example
54
+ # MyPublisher.subscribe(MyListener.new)
55
+ #
35
56
  def subscribe(listener, options = {})
36
57
  GlobalListeners.subscribe(listener, options.merge(:scope => self))
37
58
  end
38
-
39
- def add_listener(listener, options = {})
40
- warn "[DEPRECATED] use `subscribe` instead of `add_listener`"
41
- subscribe(listener, options)
42
- end
43
59
  end
44
60
 
45
61
  private
@@ -60,15 +76,6 @@ module Wisper
60
76
  local_registrations + global_registrations + temporary_registrations
61
77
  end
62
78
 
63
- def broadcast(event, *args)
64
- registrations.each do | registration |
65
- registration.broadcast(clean_event(event), self, *args)
66
- end
67
- end
68
-
69
- alias :publish :broadcast
70
- alias :announce :broadcast
71
-
72
79
  def clean_event(event)
73
80
  event.to_s.gsub('-', '_')
74
81
  end
@@ -78,4 +85,3 @@ module Wisper
78
85
  end
79
86
  end
80
87
  end
81
-
@@ -1,3 +1,5 @@
1
+ # @api private
2
+
1
3
  module Wisper
2
4
  class BlockRegistration < Registration
3
5
  def broadcast(event, publisher, *args)
@@ -1,3 +1,5 @@
1
+ # @api private
2
+
1
3
  module Wisper
2
4
  class ObjectRegistration < Registration
3
5
  attr_reader :with, :prefix, :allowed_classes, :broadcaster
@@ -1,16 +1,42 @@
1
+ # @api private
2
+
1
3
  module Wisper
2
4
  class Registration
3
5
  attr_reader :on, :listener
4
6
 
7
+ ALL = Object.new.freeze
8
+
5
9
  def initialize(listener, options)
6
- @listener = listener
7
- @on = Array(options.fetch(:on) { 'all' }).map(&:to_s)
10
+ @listener = listener
11
+ @on = stringify(options.fetch(:on, ALL))
8
12
  end
9
13
 
10
14
  private
11
15
 
12
16
  def should_broadcast?(event)
13
- on.include?(event) || on.include?('all')
17
+ return true if on == ALL
18
+
19
+ case on.class.name
20
+ when 'String'
21
+ event == on
22
+ when 'Array'
23
+ on.include?(event)
24
+ when 'Regexp'
25
+ !!on.match(event)
26
+ else
27
+ raise ArgumentError, "#{on.class} not supported for `on` argument"
28
+ end
29
+ end
30
+
31
+ def stringify(on)
32
+ case on.class.name
33
+ when 'Symbol'
34
+ on.to_s
35
+ when 'Array'
36
+ on.map(&:to_s)
37
+ else
38
+ on
39
+ end
14
40
  end
15
41
  end
16
42
  end
@@ -1,5 +1,7 @@
1
1
  # Handles temporary global subscriptions
2
2
 
3
+ # @api private
4
+
3
5
  module Wisper
4
6
  class TemporaryListeners
5
7
 
@@ -1,3 +1,3 @@
1
1
  module Wisper
2
- VERSION = "1.6.1"
2
+ VERSION = "2.0.0.rc1"
3
3
  end
@@ -79,13 +79,4 @@ describe Wisper::GlobalListeners do
79
79
  Wisper::GlobalListeners.clear
80
80
  expect(Wisper::GlobalListeners.listeners).to be_empty
81
81
  end
82
-
83
- describe 'backwards compatibility' do
84
- it '.add_listener is aliased to .add' do
85
- silence_warnings do
86
- expect(Wisper::GlobalListeners).to receive(:subscribe)
87
- Wisper::GlobalListeners.add_listener(global_listener)
88
- end
89
- end
90
- end
91
82
  end
@@ -53,10 +53,10 @@ describe Wisper::TemporaryListeners do
53
53
 
54
54
  expect(Wisper::TemporaryListeners.registrations.size).to eql 0
55
55
  end
56
- end
57
56
 
58
- it 'returns self so methods can be chained' do
59
- expect(Wisper::TemporaryListeners.subscribe {}).to be_an_instance_of(Wisper::TemporaryListeners)
57
+ it 'returns self so methods can be chained' do
58
+ expect(Wisper::TemporaryListeners.subscribe {}).to be_an_instance_of(Wisper::TemporaryListeners)
59
+ end
60
60
  end
61
61
  end
62
62
 
@@ -17,7 +17,7 @@ module Wisper
17
17
 
18
18
  describe 'unit tests:' do
19
19
  let(:publisher) { classy_double('Publisher', id: 1) }
20
- let(:subscriber) { classy_double('Subscriber', id: 2) }
20
+ let(:listener) { classy_double('Listener', id: 2) }
21
21
  let(:logger) { double('Logger').as_null_object }
22
22
  let(:broadcaster) { double('Broadcaster').as_null_object }
23
23
  let(:event) { 'thing_created' }
@@ -29,13 +29,13 @@ module Wisper
29
29
  let(:args) { [] }
30
30
 
31
31
  it 'logs publised event' do
32
- expect(logger).to receive(:info).with('[WISPER] Publisher#1 published thing_created to Subscriber#2 with no arguments')
33
- subject.broadcast(subscriber, publisher, event, args)
32
+ expect(logger).to receive(:info).with('[WISPER] Publisher#1 published thing_created to Listener#2 with no arguments')
33
+ subject.broadcast(listener, publisher, event, args)
34
34
  end
35
35
 
36
36
  it 'delgates broadcast to given broadcaster' do
37
- expect(broadcaster).to receive(:broadcast).with(subscriber, publisher, event, args)
38
- subject.broadcast(subscriber, publisher, event, args)
37
+ expect(broadcaster).to receive(:broadcast).with(listener, publisher, event, args)
38
+ subject.broadcast(listener, publisher, event, args)
39
39
  end
40
40
  end
41
41
 
@@ -43,13 +43,13 @@ module Wisper
43
43
  let(:args) { [arg_double(id: 3), arg_double(id: 4)] }
44
44
 
45
45
  it 'logs published event and arguments' do
46
- expect(logger).to receive(:info).with('[WISPER] Publisher#1 published thing_created to Subscriber#2 with Argument#3, Argument#4')
47
- subject.broadcast(subscriber, publisher, event, args)
46
+ expect(logger).to receive(:info).with('[WISPER] Publisher#1 published thing_created to Listener#2 with Argument#3, Argument#4')
47
+ subject.broadcast(listener, publisher, event, args)
48
48
  end
49
49
 
50
50
  it 'delgates broadcast to given broadcaster' do
51
- expect(broadcaster).to receive(:broadcast).with(subscriber, publisher, event, args)
52
- subject.broadcast(subscriber, publisher, event, args)
51
+ expect(broadcaster).to receive(:broadcast).with(listener, publisher, event, args)
52
+ subject.broadcast(listener, publisher, event, args)
53
53
  end
54
54
  end
55
55
 
@@ -1,25 +1,25 @@
1
1
  module Wisper
2
2
  module Broadcasters
3
3
  describe SendBroadcaster do
4
- let(:subscriber) { double('subscriber') }
4
+ let(:listener) { double('listener') }
5
5
  let(:event) { 'thing_created' }
6
6
 
7
7
  describe '#broadcast' do
8
8
  context 'without arguments' do
9
9
  let(:args) { [] }
10
10
 
11
- it 'sends event to subscriber without any arguments' do
12
- expect(subscriber).to receive(event).with(no_args())
13
- subject.broadcast(subscriber, anything, event, args)
11
+ it 'sends event to listener without any arguments' do
12
+ expect(listener).to receive(event).with(no_args())
13
+ subject.broadcast(listener, anything, event, args)
14
14
  end
15
15
  end
16
16
 
17
17
  context 'with arguments' do
18
18
  let(:args) { [1,2,3] }
19
19
 
20
- it 'sends event to subscriber with arguments' do
21
- expect(subscriber).to receive(event).with(*args)
22
- subject.broadcast(subscriber, anything, event, args)
20
+ it 'sends event to listener with arguments' do
21
+ expect(listener).to receive(event).with(*args)
22
+ subject.broadcast(listener, anything, event, args)
23
23
  end
24
24
  end
25
25
  end
@@ -8,10 +8,16 @@ module Wisper
8
8
  expect(subject.broadcasters).to be_empty
9
9
  end
10
10
 
11
- it '#broadcaster adds given broadcaster' do
12
- subject.broadcaster(key, broadcaster)
13
- expect(subject.broadcasters).to include key
14
- expect(subject.broadcasters[key]).to eql broadcaster
11
+ describe '#broadcaster' do
12
+ it 'adds given broadcaster' do
13
+ subject.broadcaster(key, broadcaster)
14
+ expect(subject.broadcasters).to include key
15
+ expect(subject.broadcasters[key]).to eql broadcaster
16
+ end
17
+
18
+ it 'returns the configuration' do
19
+ expect(subject.broadcaster(key, broadcaster)).to eq subject
20
+ end
15
21
  end
16
22
  end
17
23
  end
@@ -14,32 +14,67 @@ describe Wisper::Publisher do
14
14
  end
15
15
 
16
16
  describe ':on argument' do
17
- it 'subscribes given listener to a single event' do
18
- expect(listener).to receive(:this_happened)
17
+ before do
18
+ allow(listener).to receive(:something_a_happened)
19
+ allow(listener).to receive(:and_this)
19
20
  allow(listener).to receive(:so_did_this)
20
- expect(listener).not_to receive(:so_did_this)
21
+ end
21
22
 
22
- expect(listener).to respond_to(:so_did_this)
23
+ describe 'given a string' do
24
+ it 'subscribes listener to an event' do
25
+ expect(listener).to receive(:this_happened)
26
+ expect(listener).not_to receive(:so_did_this)
23
27
 
24
- publisher.subscribe(listener, :on => 'this_happened')
28
+ publisher.subscribe(listener, on: 'this_happened')
25
29
 
26
- publisher.send(:broadcast, 'this_happened')
27
- publisher.send(:broadcast, 'so_did_this')
30
+ publisher.send(:broadcast, 'this_happened')
31
+ publisher.send(:broadcast, 'so_did_this')
32
+ end
28
33
  end
29
34
 
30
- it 'subscribes given listener to many events' do
31
- expect(listener).to receive(:this_happened)
32
- expect(listener).to receive(:and_this)
33
- allow(listener).to receive(:so_did_this)
34
- expect(listener).not_to receive(:so_did_this)
35
+ describe 'given a symbol' do
36
+ it 'subscribes listener to an event' do
37
+ expect(listener).to receive(:this_happened)
38
+ expect(listener).not_to receive(:so_did_this)
35
39
 
36
- expect(listener).to respond_to(:so_did_this)
40
+ publisher.subscribe(listener, on: :this_happened)
37
41
 
38
- publisher.subscribe(listener, :on => ['this_happened', 'and_this'])
42
+ publisher.send(:broadcast, 'this_happened')
43
+ publisher.send(:broadcast, 'so_did_this')
44
+ end
45
+ end
39
46
 
40
- publisher.send(:broadcast, 'this_happened')
41
- publisher.send(:broadcast, 'so_did_this')
42
- publisher.send(:broadcast, 'and_this')
47
+ describe 'given an array' do
48
+ it 'subscribes listener to events' do
49
+ expect(listener).to receive(:this_happened)
50
+ expect(listener).to receive(:and_this)
51
+ expect(listener).not_to receive(:so_did_this)
52
+
53
+ publisher.subscribe(listener, on: ['this_happened', 'and_this'])
54
+
55
+ publisher.send(:broadcast, 'this_happened')
56
+ publisher.send(:broadcast, 'so_did_this')
57
+ publisher.send(:broadcast, 'and_this')
58
+ end
59
+ end
60
+
61
+ describe 'given a regex' do
62
+ it 'subscribes listener to matching events' do
63
+ expect(listener).to receive(:something_a_happened)
64
+ expect(listener).not_to receive(:so_did_this)
65
+
66
+ publisher.subscribe(listener, on: /something_._happened/)
67
+
68
+ publisher.send(:broadcast, 'something_a_happened')
69
+ publisher.send(:broadcast, 'so_did_this')
70
+ end
71
+ end
72
+
73
+ describe 'given an unsupported argument' do
74
+ it 'raises an error' do
75
+ publisher.subscribe(listener, on: Object.new)
76
+ expect { publisher.send(:broadcast, 'something_a_happened') }.to raise_error(ArgumentError)
77
+ end
43
78
  end
44
79
  end
45
80
 
@@ -74,8 +109,6 @@ describe Wisper::Publisher do
74
109
  end
75
110
  end
76
111
 
77
- # NOTE: these are not realistic use cases, since you would only ever use
78
- # `scope` when globally subscribing.
79
112
  describe ':scope argument' do
80
113
  let(:listener_1) { double('Listener') }
81
114
  let(:listener_2) { double('Listener') }
@@ -181,28 +214,8 @@ describe Wisper::Publisher do
181
214
  end
182
215
 
183
216
  describe '.on' do
184
- let(:insider) { double('insider') }
185
-
186
- it 'subscribes block to given event' do
187
- expect(insider).to receive(:yes).once
188
-
189
- publisher.on(:something_happened) do
190
- insider.yes
191
- end
192
-
193
- publisher.send(:broadcast, :something_happened)
194
- publisher.send(:broadcast, :and_so_did_this)
195
- end
196
-
197
- it 'subscribes block to given events' do
198
- expect(insider).to receive(:yes).twice
199
-
200
- publisher.on(:something_happened, :and_so_did_this) do
201
- insider.yes
202
- end
203
-
204
- publisher.send(:broadcast, :something_happened)
205
- publisher.send(:broadcast, :and_so_did_this)
217
+ it 'returns publisher so methods can be chained' do
218
+ expect(publisher.on('this_thing_happened') {}).to eq publisher
206
219
  end
207
220
 
208
221
  it 'raise an error if no events given' do
@@ -214,82 +227,8 @@ describe Wisper::Publisher do
214
227
  end
215
228
  end
216
229
 
217
- # @deprecated
218
- describe '.add_listener' do
219
- it 'is aliased to .subscribe' do
220
- expect(publisher).to receive(:subscribe)
221
- silence_warnings do
222
- publisher.add_listener(listener)
223
- end
224
- end
225
- end
226
-
227
- # @deprecated
228
- describe '.add_block_listener' do
229
- let(:insider) { double('insider') }
230
-
231
- it 'subscribes given block to all events' do
232
- expect(insider).to receive(:it_happened).twice
233
-
234
- silence_warnings do
235
- publisher.add_block_listener do
236
- insider.it_happened
237
- end
238
- end
239
-
240
- publisher.send(:broadcast, 'something_happened')
241
- publisher.send(:broadcast, 'and_so_did_this')
242
- end
243
-
244
- describe ':on argument' do
245
- it '.add_block_listener subscribes block to an event' do
246
- expect(insider).not_to receive(:it_happened).once
247
-
248
- silence_warnings do
249
- publisher.add_block_listener(:on => 'something_happened') do
250
- insider.it_happened
251
- end
252
- end
253
-
254
- publisher.send(:broadcast, 'something_happened')
255
- publisher.send(:broadcast, 'and_so_did_this')
256
- end
257
-
258
- it '.add_block_listener subscribes block to all listed events' do
259
- expect(insider).to receive(:it_happened).twice
260
-
261
- silence_warnings do
262
- publisher.add_block_listener(
263
- :on => ['something_happened', 'and_so_did_this']) do
264
- insider.it_happened
265
- end
266
- end
267
-
268
- publisher.send(:broadcast, 'something_happened')
269
- publisher.send(:broadcast, 'and_so_did_this')
270
- publisher.send(:broadcast, 'but_not_this')
271
- end
272
- end
273
-
274
- it 'returns publisher so methods can be chained' do
275
- silence_warnings do
276
- expect(publisher.add_block_listener(:on => 'this_thing_happened') do
277
- end).to eq publisher
278
- end
279
- end
280
- end
281
-
282
- # @deprecated
283
- describe '.respond_to (alternative block syntax)' do
284
- it 'delegates to .on' do
285
- expect(publisher).to receive(:on).with(:foobar)
286
- silence_warnings do
287
- publisher.respond_to(:foobar) { }
288
- end
289
- end
290
- end
291
-
292
230
  describe '.broadcast' do
231
+
293
232
  it 'does not publish events which cannot be responded to' do
294
233
  expect(listener).not_to receive(:so_did_this)
295
234
  allow(listener).to receive(:respond_to?).and_return(false)
@@ -318,6 +257,18 @@ describe Wisper::Publisher do
318
257
  publisher.send(:broadcast, 'this-happened')
319
258
  end
320
259
  end
260
+
261
+ it 'returns publisher' do
262
+ expect(publisher.send(:broadcast, :foo)).to eq publisher
263
+ end
264
+
265
+ it 'is not public' do
266
+ expect(publisher).not_to respond_to(:broadcast)
267
+ end
268
+
269
+ it 'is alised as .publish' do
270
+ expect(publisher.method(:broadcast)).to eq publisher.method(:publish)
271
+ end
321
272
  end
322
273
 
323
274
  describe '.listeners' do
@@ -344,13 +295,4 @@ describe Wisper::Publisher do
344
295
  publisher_klass_2.new.send(:broadcast, 'it_happened')
345
296
  end
346
297
  end
347
-
348
- describe '#add_listener' do # deprecated
349
- it 'is aliased to #subscribe' do
350
- expect(publisher).to receive(:subscribe)
351
- silence_warnings do
352
- publisher.add_listener(listener)
353
- end
354
- end
355
- end
356
298
  end
@@ -1,46 +1,4 @@
1
1
  describe Wisper do
2
- before do
3
- # assign the stderr to a new StringIO to test errors
4
- @orig_stderr, $stderr = $stderr, StringIO.new
5
- end
6
-
7
- after do
8
- # reassign the stderr to the original <IO:<STDERR>> instead of StringIO
9
- # used for testing
10
- $stderr = @orig_stderr
11
- end
12
-
13
- it 'includes Wisper::Publisher for backwards compatibility' do
14
- publisher_class = Class.new { include Wisper }
15
- expect(publisher_class.ancestors).to include Wisper::Publisher
16
-
17
- $stderr.rewind
18
- expect($stderr.gets.chomp).to include 'DEPRECATION'
19
- end
20
-
21
- # NOTE .with_listeners is deprecated
22
- it '.with_listeners subscribes listeners to all broadcast events for the duration of block' do
23
- publisher = publisher_class.new
24
- listener = double('listener')
25
-
26
- Wisper.with_listeners(listener) do
27
- publisher.send(:broadcast, 'im_here')
28
- end
29
-
30
- $stderr.rewind
31
- expect($stderr.string.chomp).to include 'DEPRECATION'
32
- end
33
-
34
- # NOTE .add_listener is deprecated
35
- it '.add_listener adds a global listener' do
36
- listener = double('listener')
37
-
38
- Wisper.add_listener(listener)
39
-
40
- $stderr.rewind
41
- expect($stderr.string.chomp).to include 'DEPRECATION'
42
- end
43
-
44
2
  describe '.subscribe' do
45
3
  context 'given block' do
46
4
  it 'subscribes listeners to all events for duration of the block' do
@@ -13,6 +13,13 @@ Gem::Specification.new do |gem|
13
13
  gem.homepage = "https://github.com/krisleech/wisper"
14
14
  gem.license = "MIT"
15
15
 
16
+ signing_key = File.expand_path('~/.ssh/gem-private_key.pem')
17
+
18
+ if File.exist?(signing_key)
19
+ gem.signing_key = signing_key
20
+ gem.cert_chain = ['gem-public_cert.pem']
21
+ end
22
+
16
23
  gem.files = `git ls-files`.split($/)
17
24
  gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
18
25
  gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
metadata CHANGED
@@ -1,14 +1,36 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: wisper
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.6.1
4
+ version: 2.0.0.rc1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kris Leech
8
8
  autorequire:
9
9
  bindir: bin
10
- cert_chain: []
11
- date: 2015-08-17 00:00:00.000000000 Z
10
+ cert_chain:
11
+ - |
12
+ -----BEGIN CERTIFICATE-----
13
+ MIIDeDCCAmCgAwIBAgIBATANBgkqhkiG9w0BAQUFADBBMRMwEQYDVQQDDAprcmlz
14
+ LmxlZWNoMRUwEwYKCZImiZPyLGQBGRYFZ21haWwxEzARBgoJkiaJk/IsZAEZFgNj
15
+ b20wHhcNMTQxMTA1MTEwMzQ4WhcNMTUxMTA1MTEwMzQ4WjBBMRMwEQYDVQQDDApr
16
+ cmlzLmxlZWNoMRUwEwYKCZImiZPyLGQBGRYFZ21haWwxEzARBgoJkiaJk/IsZAEZ
17
+ FgNjb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtW0/UtrFK/tSm
18
+ uq5HnCUkZAQjnSaZ/h1Tby9s30CDJjDUdizPRdLQCplLDAMHFsAfTyD0Mc+Ez8o9
19
+ CdTh8EZ4TSf+nokL+SUprpdR6qm6OWU03Ntd+bDCP0+rdqCX82g3N3mnvjR9aD3a
20
+ +hd9Fhp0WuEyqTNjQ7IlopeUPDW7eYfSwI4bjfRHxsDR1GuZ3j0npxCAgAIN41WH
21
+ MSTTZhdo0vKEiKZEtMMnT6w6fG/c3XIhVVPGnqy5+IZqBL0SYC+WJL3vC6yUBgqB
22
+ nrpA/q+b3M69W+q+TkGv0qOnrxln0O7J2pykjoGIxUhhRkiGEldEhy9dxQWubffr
23
+ hVJ4F0wLAgMBAAGjezB5MAkGA1UdEwQCMAAwCwYDVR0PBAQDAgSwMB0GA1UdDgQW
24
+ BBSzq+x8mwj0ldvNkvjOl44OJG354jAfBgNVHREEGDAWgRRrcmlzLmxlZWNoQGdt
25
+ YWlsLmNvbTAfBgNVHRIEGDAWgRRrcmlzLmxlZWNoQGdtYWlsLmNvbTANBgkqhkiG
26
+ 9w0BAQUFAAOCAQEAF5M2Md3DcNCrQrDRDLaIzHaMM+RTgfbpgmZ6tU0iEowES18g
27
+ QWQgrAbFuvQRPETJ2gbL5AC35fEqN80nU+3GhgW/bDYhII5D3PGLMorxhFw1JYLI
28
+ 0Fd7MCE0sImc2rPybYUdpZ6TxvqgPKp+8CzM8vBUrdYd+dSHXit1piViWBcZcJb+
29
+ EL5Ze4IodjkCPAeHvu2MQieieViLyfB4eG1syvfkxvAXCjFHeQoIFP16vVtcljdF
30
+ k5cHH/4SGeMuGrSLRsqVvltxVV3AbQAfH8WUos2brjYHsoH5tVPrJ7UcFhzP95oU
31
+ pEfFMW42smiNTOXpzG6JoIpA11szEHFT5ZS+UQ==
32
+ -----END CERTIFICATE-----
33
+ date: 2014-12-17 00:00:00.000000000 Z
12
34
  dependencies: []
13
35
  description: pub/sub for Ruby objects
14
36
  email:
@@ -19,13 +41,14 @@ extra_rdoc_files: []
19
41
  files:
20
42
  - ".gitignore"
21
43
  - ".rspec"
22
- - ".ruby-version"
23
44
  - ".travis.yml"
24
45
  - CHANGELOG.md
46
+ - CONTRIBUTING.md
25
47
  - Gemfile
26
48
  - Guardfile
27
49
  - README.md
28
50
  - Rakefile
51
+ - gem-public_cert.pem
29
52
  - lib/wisper.rb
30
53
  - lib/wisper/broadcasters/logger_broadcaster.rb
31
54
  - lib/wisper/broadcasters/send_broadcaster.rb
@@ -35,11 +58,9 @@ files:
35
58
  - lib/wisper/registration/block.rb
36
59
  - lib/wisper/registration/object.rb
37
60
  - lib/wisper/registration/registration.rb
38
- - lib/wisper/rspec/matchers.rb
39
- - lib/wisper/rspec/stub_wisper_publisher.rb
40
61
  - lib/wisper/temporary_listeners.rb
41
62
  - lib/wisper/version.rb
42
- - spec/lib/global_subscribers_spec.rb
63
+ - spec/lib/global_listeners_spec.rb
43
64
  - spec/lib/integration_spec.rb
44
65
  - spec/lib/simple_example_spec.rb
45
66
  - spec/lib/temporary_global_listeners_spec.rb
@@ -48,8 +69,6 @@ files:
48
69
  - spec/lib/wisper/configuration_spec.rb
49
70
  - spec/lib/wisper/publisher_spec.rb
50
71
  - spec/lib/wisper/registrations/object_spec.rb
51
- - spec/lib/wisper/rspec/matchers_spec.rb
52
- - spec/lib/wisper/rspec/stub_wisper_publisher_spec.rb
53
72
  - spec/lib/wisper_spec.rb
54
73
  - spec/spec_helper.rb
55
74
  - wisper.gemspec
@@ -68,17 +87,17 @@ required_ruby_version: !ruby/object:Gem::Requirement
68
87
  version: '0'
69
88
  required_rubygems_version: !ruby/object:Gem::Requirement
70
89
  requirements:
71
- - - ">="
90
+ - - ">"
72
91
  - !ruby/object:Gem::Version
73
- version: '0'
92
+ version: 1.3.1
74
93
  requirements: []
75
94
  rubyforge_project:
76
- rubygems_version: 2.4.5
95
+ rubygems_version: 2.2.2
77
96
  signing_key:
78
97
  specification_version: 4
79
98
  summary: pub/sub for Ruby objects
80
99
  test_files:
81
- - spec/lib/global_subscribers_spec.rb
100
+ - spec/lib/global_listeners_spec.rb
82
101
  - spec/lib/integration_spec.rb
83
102
  - spec/lib/simple_example_spec.rb
84
103
  - spec/lib/temporary_global_listeners_spec.rb
@@ -87,7 +106,6 @@ test_files:
87
106
  - spec/lib/wisper/configuration_spec.rb
88
107
  - spec/lib/wisper/publisher_spec.rb
89
108
  - spec/lib/wisper/registrations/object_spec.rb
90
- - spec/lib/wisper/rspec/matchers_spec.rb
91
- - spec/lib/wisper/rspec/stub_wisper_publisher_spec.rb
92
109
  - spec/lib/wisper_spec.rb
93
110
  - spec/spec_helper.rb
111
+ has_rdoc:
Binary file
@@ -1 +0,0 @@
1
- 2.2.2
@@ -1,57 +0,0 @@
1
- require 'rspec/expectations'
2
-
3
- module Wisper
4
- module RSpec
5
- class EventRecorder
6
- def initialize
7
- @broadcast_events = []
8
- end
9
-
10
- def respond_to?(method_name)
11
- true
12
- end
13
-
14
- def method_missing(method_name, *args, &block)
15
- @broadcast_events << method_name.to_s
16
- end
17
-
18
- def broadcast?(event_name)
19
- @broadcast_events.include?(event_name.to_s)
20
- end
21
- end
22
-
23
- module BroadcastMatcher
24
- class Matcher
25
- def initialize(event)
26
- @event = event
27
- end
28
-
29
- def supports_block_expectations?
30
- true
31
- end
32
-
33
- def matches?(block)
34
- event_recorder = EventRecorder.new
35
-
36
- Wisper.subscribe(event_recorder) do
37
- block.call
38
- end
39
-
40
- event_recorder.broadcast?(@event)
41
- end
42
-
43
- def failure_message
44
- "expected publisher to broadcast #{@event} event"
45
- end
46
-
47
- def failure_message_when_negated
48
- "expected publisher not to broadcast #{@event} event"
49
- end
50
- end
51
-
52
- def broadcast(event)
53
- Matcher.new(event)
54
- end
55
- end
56
- end
57
- end
@@ -1,12 +0,0 @@
1
- class TestWisperPublisher
2
- include Wisper::Publisher
3
- def initialize(*args); end
4
- end
5
-
6
- def stub_wisper_publisher(clazz, called_method, event_to_publish, *published_event_args)
7
- stub_const(clazz, Class.new(TestWisperPublisher) do
8
- define_method(called_method) do |*args|
9
- publish(event_to_publish, *published_event_args)
10
- end
11
- end)
12
- end
@@ -1,17 +0,0 @@
1
- require 'wisper/rspec/matchers'
2
-
3
- RSpec::configure do |config|
4
- config.include(Wisper::RSpec::BroadcastMatcher)
5
- end
6
-
7
- describe 'broadcast matcher' do
8
- it 'passes when publisher broadcasts inside block' do
9
- publisher = publisher_class.new
10
- expect { publisher.send(:broadcast, :foobar) }.to broadcast(:foobar)
11
- end
12
-
13
- it 'passes with not_to when publisher does not broadcast inside block' do
14
- publisher = publisher_class.new
15
- expect { publisher }.not_to broadcast(:foobar)
16
- end
17
- end
@@ -1,26 +0,0 @@
1
- require 'wisper/rspec/stub_wisper_publisher'
2
-
3
- describe '#stub_wisper_publisher' do
4
- describe "given a piece of code invoking a publisher" do
5
- class CodeThatReactsToEvents
6
- def do_something
7
- publisher = MyPublisher.new
8
- publisher.on(:some_event) do |variable1, variable2|
9
- return "Hello with #{variable1} #{variable2}!"
10
- end
11
- publisher.execute
12
- end
13
- end
14
-
15
- context "when stubbing the publisher to emit an event" do
16
- before do
17
- stub_wisper_publisher("MyPublisher", :execute, :some_event, "foo1", "foo2")
18
- end
19
-
20
- it "emits the event" do
21
- response = CodeThatReactsToEvents.new.do_something
22
- expect(response).to eq "Hello with foo1 foo2!"
23
- end
24
- end
25
- end
26
- end