wisper 2.0.0.rc1 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.travis.yml +14 -9
- data/CHANGELOG.md +10 -0
- data/CONTRIBUTING.md +10 -4
- data/Gemfile +1 -1
- data/README.md +85 -29
- data/lib/wisper.rb +6 -0
- data/lib/wisper/broadcasters/logger_broadcaster.rb +10 -4
- data/lib/wisper/configuration.rb +10 -1
- data/lib/wisper/global_listeners.rb +13 -0
- data/lib/wisper/publisher.rb +2 -0
- data/lib/wisper/registration/object.rb +1 -16
- data/lib/wisper/registration/registration.rb +2 -26
- data/lib/wisper/value_objects/events.rb +61 -0
- data/lib/wisper/value_objects/prefix.rb +29 -0
- data/lib/wisper/version.rb +1 -1
- data/spec/lib/temporary_global_listeners_spec.rb +12 -9
- data/spec/lib/wisper/broadcasters/logger_broadcaster_spec.rb +23 -3
- data/spec/lib/wisper/configuration/broadcasters_spec.rb +11 -0
- data/spec/lib/wisper/configuration_spec.rb +12 -0
- data/spec/lib/wisper/publisher_spec.rb +13 -0
- data/spec/lib/wisper/value_objects/events_spec.rb +107 -0
- data/spec/lib/wisper/value_objects/prefix_spec.rb +46 -0
- data/spec/lib/wisper_spec.rb +61 -24
- data/spec/spec_helper.rb +0 -8
- data/wisper.gemspec +6 -2
- metadata +19 -32
- checksums.yaml.gz.sig +0 -2
- data.tar.gz.sig +0 -0
- data/Guardfile +0 -8
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 62cd6c2948137446de8f7f515bcbebd11c14092d
|
4
|
+
data.tar.gz: dfbc3b2d28c9023edc9f8308a6c406887c20efed
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d82be662081f118b83ce5f01f87a0760be1bbc9d711163fc76ac303db689ba307ec453afb9edfb374fa1b23e92ab6a684a2c3857580d3f6a29195c75c8d6f754
|
7
|
+
data.tar.gz: 9395fbd3e0d2b925d31dc06682aa573ad66b0f4ee980533b1671e497ce7f2b8b82019840c7f8eb15c7f52b7bdae73934592ae0e5634729b4ad99f2c068bcae3e
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
@@ -1,17 +1,22 @@
|
|
1
1
|
language: ruby
|
2
|
+
before_install:
|
3
|
+
- gem update --system
|
4
|
+
- gem update bundler
|
2
5
|
bundler_args: --without=extras
|
3
6
|
script: rspec spec
|
7
|
+
sudo: false
|
4
8
|
rvm:
|
5
|
-
- '1.
|
6
|
-
- '
|
7
|
-
- '2.
|
8
|
-
- '2.
|
9
|
-
- jruby
|
10
|
-
- rbx-2
|
9
|
+
- '2.1.10'
|
10
|
+
- '2.2.6'
|
11
|
+
- '2.3.3'
|
12
|
+
- '2.4.0'
|
13
|
+
- jruby-9.1.6.0
|
14
|
+
# - rbx-2
|
11
15
|
### ALLOWED FAILURES ###
|
12
16
|
# see how compatible we are with dev versions, but do not fail the build
|
13
17
|
- ruby-head
|
14
18
|
- jruby-head
|
15
|
-
|
16
|
-
|
17
|
-
|
19
|
+
matrix:
|
20
|
+
allow_failures:
|
21
|
+
- rvm: ruby-head
|
22
|
+
- rvm: jruby-head
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
## HEAD (unreleased)
|
2
|
+
|
3
|
+
## 2.0.0 (7th Mar 2017)
|
4
|
+
|
5
|
+
Authors: Sergey Mostovoy
|
6
|
+
|
7
|
+
* fix: logger raises exception if hash is passed as an argument to a listener
|
8
|
+
|
1
9
|
## 2.0.0.rc1 (17 Dec 2014)
|
2
10
|
|
3
11
|
Authors: Kris Leech
|
@@ -6,6 +14,8 @@ Authors: Kris Leech
|
|
6
14
|
* remove: rspec matcher and stubbing (moved to [wisper-rspec](https://github.com/krisleech/wisper-rspec))
|
7
15
|
* feature: add regexp support to `on` argument
|
8
16
|
* remove: announce alias for broadcasting
|
17
|
+
* docs: add Code of Conduct
|
18
|
+
* drop support for Ruby 1.9
|
9
19
|
|
10
20
|
## 1.6.0 (25 Oct 2014)
|
11
21
|
|
data/CONTRIBUTING.md
CHANGED
@@ -2,6 +2,10 @@
|
|
2
2
|
|
3
3
|
We very much welcome contributions to Wisper.
|
4
4
|
|
5
|
+
This project is intended to be a safe, welcoming space for collaboration,
|
6
|
+
and contributors are expected to adhere to the
|
7
|
+
[Contributor Covenant](http://contributor-covenant.org) code of conduct.
|
8
|
+
|
5
9
|
## Getting started
|
6
10
|
|
7
11
|
Please first check the existing [Issues](https://github.com/krisleech/wisper/issues)
|
@@ -19,11 +23,15 @@ Please open an issue with your proposed feature. We can discuss the feature and
|
|
19
23
|
if it is acceptable we can also discuss implimentation details. You will in
|
20
24
|
most cases have to submit a PR which adds the feature.
|
21
25
|
|
22
|
-
We also have a [Gitter channel](https://gitter.im/krisleech/wisper).
|
23
|
-
|
24
26
|
Wisper is a micro library and will remain lean. Some features would be most
|
25
27
|
appropriate as an extension to Wisper.
|
26
28
|
|
29
|
+
We also have a [Gitter channel](https://gitter.im/krisleech/wisper) if you wish to discuss your ideas.
|
30
|
+
|
31
|
+
## Backlog / Roadmap
|
32
|
+
|
33
|
+
The backlog for Wisper and related gems is on [Waffle](https://waffle.io/krisleech/wisper).
|
34
|
+
|
27
35
|
## Questions
|
28
36
|
|
29
37
|
Try the [Wiki](https://github.com/krisleech/wisper/wiki) first, the examples
|
@@ -33,8 +41,6 @@ Please ask questions on StackOverflow, [tagged wisper](https://stackoverflow.com
|
|
33
41
|
|
34
42
|
Feel free to ping me the URL on [Twitter](https://twitter.com/krisleech).
|
35
43
|
|
36
|
-
We also have a [channel on Gitter](https://gitter.im/krisleech/wisper).
|
37
|
-
|
38
44
|
## Pull requests
|
39
45
|
|
40
46
|
* Fork the project, create a new branch from `v1` or `master`.
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -2,10 +2,10 @@
|
|
2
2
|
|
3
3
|
*A micro library providing Ruby objects with Publish-Subscribe capabilities*
|
4
4
|
|
5
|
-
[![Gem Version](https://badge.fury.io/rb/wisper.
|
6
|
-
[![Code Climate](https://codeclimate.com/github/krisleech/wisper.
|
7
|
-
[![Build Status](https://travis-ci.org/krisleech/wisper.
|
8
|
-
[![Coverage Status](https://coveralls.io/repos/krisleech/wisper/badge.
|
5
|
+
[![Gem Version](https://badge.fury.io/rb/wisper.svg)](http://badge.fury.io/rb/wisper)
|
6
|
+
[![Code Climate](https://codeclimate.com/github/krisleech/wisper.svg)](https://codeclimate.com/github/krisleech/wisper)
|
7
|
+
[![Build Status](https://travis-ci.org/krisleech/wisper.svg?branch=master)](https://travis-ci.org/krisleech/wisper)
|
8
|
+
[![Coverage Status](https://coveralls.io/repos/krisleech/wisper/badge.svg?branch=master)](https://coveralls.io/r/krisleech/wisper?branch=master)
|
9
9
|
|
10
10
|
* Decouple core business logic from external concerns in Hexagonal style architectures
|
11
11
|
* Use as an alternative to ActiveRecord callbacks and Observers in Rails apps
|
@@ -19,12 +19,12 @@ Note: Wisper was originally extracted from a Rails codebase but is not dependant
|
|
19
19
|
Add this line to your application's Gemfile:
|
20
20
|
|
21
21
|
```ruby
|
22
|
-
gem 'wisper'
|
22
|
+
gem 'wisper', '2.0.0'
|
23
23
|
```
|
24
24
|
|
25
25
|
## Usage
|
26
26
|
|
27
|
-
Any class with the `Wisper::Publisher` module included can broadcast events
|
27
|
+
Any class with the `Wisper::Publisher` module included can broadcast events
|
28
28
|
to subscribed listeners. Listeners subscribe, at runtime, to the publisher.
|
29
29
|
|
30
30
|
### Publishing
|
@@ -47,7 +47,7 @@ class CancelOrder
|
|
47
47
|
end
|
48
48
|
```
|
49
49
|
|
50
|
-
When a publisher broadcasts an event it can include number of arguments.
|
50
|
+
When a publisher broadcasts an event it can include any number of arguments.
|
51
51
|
|
52
52
|
The `broadcast` method is also aliased as `publish`.
|
53
53
|
|
@@ -73,7 +73,7 @@ The listener would need to implement a method for every event it wishes to recei
|
|
73
73
|
class OrderNotifier
|
74
74
|
def cancel_order_successful(order_id)
|
75
75
|
order = Order.find_by_id(order_id)
|
76
|
-
|
76
|
+
|
77
77
|
# notify someone ...
|
78
78
|
end
|
79
79
|
end
|
@@ -88,10 +88,27 @@ cancel_order = CancelOrder.new
|
|
88
88
|
|
89
89
|
cancel_order.on(:cancel_order_successful) { |order_id| ... }
|
90
90
|
.on(:cancel_order_failed) { |order_id| ... }
|
91
|
-
|
91
|
+
|
92
92
|
cancel_order.call(order_id)
|
93
93
|
```
|
94
94
|
|
95
|
+
You can also subscribe to multiple events using `on` by passing
|
96
|
+
additional events as arguments.
|
97
|
+
|
98
|
+
```ruby
|
99
|
+
cancel_order = CancelOrder.new
|
100
|
+
|
101
|
+
cancel_order.on(:cancel_order_successful) { |order_id| ... }
|
102
|
+
.on(:cancel_order_failed,
|
103
|
+
:cancel_order_invalid) { |order_id| ... }
|
104
|
+
|
105
|
+
cancel_order.call(order_id)
|
106
|
+
```
|
107
|
+
|
108
|
+
Do not `return` from inside a subscribed block, due to the way
|
109
|
+
[Ruby treats blocks](http://product.reverb.com/2015/02/28/the-strange-case-of-wisper-and-ruby-blocks-behaving-like-procs/)
|
110
|
+
this will prevent any subsequent listeners having their events delivered.
|
111
|
+
|
95
112
|
### Handling Events Asynchronously
|
96
113
|
|
97
114
|
```ruby
|
@@ -100,16 +117,30 @@ cancel_order.subscribe(OrderNotifier.new, async: true)
|
|
100
117
|
|
101
118
|
Wisper has various adapters for asynchronous event handling, please refer to
|
102
119
|
[wisper-celluloid](https://github.com/krisleech/wisper-celluloid),
|
103
|
-
[wisper-sidekiq](https://github.com/krisleech/wisper-sidekiq)
|
104
|
-
[wisper-activejob](https://github.com/krisleech/wisper-activejob)
|
120
|
+
[wisper-sidekiq](https://github.com/krisleech/wisper-sidekiq),
|
121
|
+
[wisper-activejob](https://github.com/krisleech/wisper-activejob), or
|
122
|
+
[wisper-que](https://github.com/joevandyk/wisper-que).
|
123
|
+
|
124
|
+
Depending on the adapter used the listener may need to be a class instead of an object. In this situation, every method corresponding to events should be declared as a class method, too. For example:
|
125
|
+
|
126
|
+
```ruby
|
127
|
+
class OrderNotifier
|
128
|
+
# declare a class method if you are subscribing the listener class instead of its instance like:
|
129
|
+
# cancel_order.subscribe(OrderNotifier)
|
130
|
+
#
|
131
|
+
def self.cancel_order_successful(order_id)
|
132
|
+
order = Order.find_by_id(order_id)
|
105
133
|
|
106
|
-
|
134
|
+
# notify someone ...
|
135
|
+
end
|
136
|
+
end
|
137
|
+
```
|
107
138
|
|
108
139
|
### ActionController
|
109
140
|
|
110
141
|
```ruby
|
111
142
|
class CancelOrderController < ApplicationController
|
112
|
-
|
143
|
+
|
113
144
|
def create
|
114
145
|
cancel_order = CancelOrder.new
|
115
146
|
|
@@ -132,7 +163,7 @@ If you wish to publish directly from ActiveRecord models you can broadcast event
|
|
132
163
|
```ruby
|
133
164
|
class Order < ActiveRecord::Base
|
134
165
|
include Wisper::Publisher
|
135
|
-
|
166
|
+
|
136
167
|
after_commit :publish_creation_successful, on: :create
|
137
168
|
after_validation :publish_creation_failed, on: :create
|
138
169
|
|
@@ -171,9 +202,12 @@ class.
|
|
171
202
|
|
172
203
|
```ruby
|
173
204
|
Wisper.subscribe(MyListener.new, scope: :MyPublisher)
|
205
|
+
Wisper.subscribe(MyListener.new, scope: MyPublisher)
|
206
|
+
Wisper.subscribe(MyListener.new, scope: "MyPublisher")
|
207
|
+
Wisper.subscribe(MyListener.new, scope: [:MyPublisher, :MyOtherPublisher])
|
174
208
|
```
|
175
209
|
|
176
|
-
This will subscribe the listener to all instances of
|
210
|
+
This will subscribe the listener to all instances of the specified class(es) and their
|
177
211
|
subclasses.
|
178
212
|
|
179
213
|
Alternatively you can also do exactly the same with a publisher class itself:
|
@@ -193,7 +227,7 @@ end
|
|
193
227
|
```
|
194
228
|
|
195
229
|
Any events broadcast within the block by any publisher will be sent to the
|
196
|
-
listeners.
|
230
|
+
listeners.
|
197
231
|
|
198
232
|
This is useful for capturing events published by objects to which you do not have access in a given context.
|
199
233
|
|
@@ -202,11 +236,11 @@ Temporary Global Listeners are threadsafe.
|
|
202
236
|
## Subscribing to selected events
|
203
237
|
|
204
238
|
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
|
239
|
+
can limit which events a listener is notified of by passing a string, symbol,
|
206
240
|
array or regular expression to `on`:
|
207
241
|
|
208
242
|
```ruby
|
209
|
-
|
243
|
+
post_creator.subscribe(PusherListener.new, on: :create_post_successful)
|
210
244
|
```
|
211
245
|
|
212
246
|
## Prefixing broadcast events
|
@@ -215,10 +249,10 @@ If you would prefer listeners to receive events with a prefix, for example
|
|
215
249
|
`on`, you can do so by passing a string or symbol to `prefix:`.
|
216
250
|
|
217
251
|
```ruby
|
218
|
-
|
252
|
+
post_creator.subscribe(PusherListener.new, prefix: :on)
|
219
253
|
```
|
220
254
|
|
221
|
-
If `
|
255
|
+
If `post_creator` were to broadcast the event `post_created` the subscribed
|
222
256
|
listeners would receive `on_post_created`. You can also pass `true` which will
|
223
257
|
use the default prefix, "on".
|
224
258
|
|
@@ -231,7 +265,7 @@ broadcast. However it can be mapped to a different method using `with:`.
|
|
231
265
|
report_creator.subscribe(MailResponder.new, with: :successful)
|
232
266
|
```
|
233
267
|
|
234
|
-
This is pretty useless unless used in
|
268
|
+
This is pretty useless unless used in conjunction with `on:`, since all events
|
235
269
|
will get mapped to `:successful`. Instead you might do something like this:
|
236
270
|
|
237
271
|
```ruby
|
@@ -255,11 +289,14 @@ report_creator.subscribe(MailResponder.new, on: :create_report_failed,
|
|
255
289
|
You could also alias the method within your listener, as such
|
256
290
|
`alias successful create_report_successful`.
|
257
291
|
|
258
|
-
##
|
292
|
+
## Testing
|
293
|
+
|
294
|
+
Testing matchers and stubs are in seperate gems.
|
259
295
|
|
260
|
-
|
296
|
+
* [wisper-rspec](https://github.com/krisleech/wisper-rspec)
|
297
|
+
* [wisper-minitest](https://github.com/digitalcuisine/wisper-minitest)
|
261
298
|
|
262
|
-
|
299
|
+
### Clearing Global Listeners
|
263
300
|
|
264
301
|
If you use global listeners in non-feature tests you _might_ want to clear them
|
265
302
|
in a hook to prevent global subscriptions persisting between tests.
|
@@ -268,21 +305,40 @@ in a hook to prevent global subscriptions persisting between tests.
|
|
268
305
|
after { Wisper.clear }
|
269
306
|
```
|
270
307
|
|
308
|
+
## Need help?
|
309
|
+
|
310
|
+
The [Wiki](https://github.com/krisleech/wisper/wiki) has more examples,
|
311
|
+
articles and talks.
|
312
|
+
|
313
|
+
Got a specific question, try the
|
314
|
+
[Wisper tag on StackOverflow](http://stackoverflow.com/questions/tagged/wisper).
|
315
|
+
|
271
316
|
## Compatibility
|
272
317
|
|
273
|
-
Tested with MRI
|
274
|
-
mode).
|
318
|
+
Tested with MRI 2.x, JRuby and Rubinius.
|
275
319
|
|
276
320
|
See the [build status](https://travis-ci.org/krisleech/wisper) for details.
|
277
321
|
|
278
322
|
## Running Specs
|
279
323
|
|
280
324
|
```
|
281
|
-
rspec
|
325
|
+
bundle exec rspec
|
326
|
+
```
|
327
|
+
|
328
|
+
To run the specs on code changes try [entr](http://entrproject.org/):
|
329
|
+
|
330
|
+
```
|
331
|
+
ls **/*.rb | entr bundle exec rspec
|
282
332
|
```
|
283
333
|
|
284
|
-
|
285
|
-
|
334
|
+
## Contributing
|
335
|
+
|
336
|
+
Please read the [Contributing Guidelines](https://github.com/krisleech/wisper/blob/master/CONTRIBUTING.md).
|
337
|
+
|
338
|
+
## Security
|
339
|
+
|
340
|
+
* gem releases are [signed](http://guides.rubygems.org/security/) ([public key](https://github.com/krisleech/wisper/blob/master/gem-public_cert.pem))
|
341
|
+
* commits are GPG signed ([public key](https://pgp.mit.edu/pks/lookup?op=get&search=0x3ABC74851F7CCC88))
|
286
342
|
|
287
343
|
## License
|
288
344
|
|
data/lib/wisper.rb
CHANGED
@@ -2,6 +2,8 @@ require 'set'
|
|
2
2
|
require 'wisper/version'
|
3
3
|
require 'wisper/configuration'
|
4
4
|
require 'wisper/publisher'
|
5
|
+
require 'wisper/value_objects/prefix'
|
6
|
+
require 'wisper/value_objects/events'
|
5
7
|
require 'wisper/registration/registration'
|
6
8
|
require 'wisper/registration/object'
|
7
9
|
require 'wisper/registration/block'
|
@@ -33,6 +35,10 @@ module Wisper
|
|
33
35
|
end
|
34
36
|
end
|
35
37
|
|
38
|
+
def self.unsubscribe(*listeners)
|
39
|
+
GlobalListeners.unsubscribe(*listeners)
|
40
|
+
end
|
41
|
+
|
36
42
|
def self.publisher
|
37
43
|
Publisher
|
38
44
|
end
|
@@ -9,22 +9,28 @@ module Wisper
|
|
9
9
|
end
|
10
10
|
|
11
11
|
def broadcast(listener, publisher, event, args)
|
12
|
-
@logger.info("[WISPER] #{name(publisher)} published #{event} to #{name(listener)} with #{
|
12
|
+
@logger.info("[WISPER] #{name(publisher)} published #{event} to #{name(listener)} with #{args_info(args)}")
|
13
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
|
19
|
+
id_method = %w(id uuid key object_id).find do |method_name|
|
20
|
+
object.respond_to?(method_name) && object.method(method_name).arity <= 0
|
21
|
+
end
|
20
22
|
id = object.send(id_method)
|
21
23
|
class_name = object.class == Class ? object.name : object.class.name
|
22
24
|
"#{class_name}##{id}"
|
23
25
|
end
|
24
26
|
|
25
|
-
def
|
27
|
+
def args_info(args)
|
26
28
|
return 'no arguments' if args.empty?
|
27
|
-
args.map
|
29
|
+
args.map do |arg|
|
30
|
+
arg_string = name(arg)
|
31
|
+
arg_string += ": #{arg.inspect}" if [Numeric, Array, Hash, String].any? {|klass| arg.is_a?(klass) }
|
32
|
+
arg_string
|
33
|
+
end.join(', ')
|
28
34
|
end
|
29
35
|
end
|
30
36
|
end
|
data/lib/wisper/configuration.rb
CHANGED
@@ -17,10 +17,19 @@ module Wisper
|
|
17
17
|
self
|
18
18
|
end
|
19
19
|
|
20
|
+
# sets the default value for prefixes
|
21
|
+
#
|
22
|
+
# @param [#to_s] value
|
23
|
+
#
|
24
|
+
# @return [String]
|
25
|
+
def default_prefix=(value)
|
26
|
+
ValueObjects::Prefix.default = value
|
27
|
+
end
|
28
|
+
|
20
29
|
class Broadcasters
|
21
30
|
extend Forwardable
|
22
31
|
|
23
|
-
def_delegators :@data, :
|
32
|
+
def_delegators :@data, :[], :[]=, :empty?, :include?, :clear, :keys, :to_h
|
24
33
|
|
25
34
|
def initialize
|
26
35
|
@data = {}
|
@@ -24,6 +24,15 @@ module Wisper
|
|
24
24
|
self
|
25
25
|
end
|
26
26
|
|
27
|
+
def unsubscribe(*listeners)
|
28
|
+
with_mutex do
|
29
|
+
@registrations.delete_if do |registration|
|
30
|
+
listeners.include?(registration.listener)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
self
|
34
|
+
end
|
35
|
+
|
27
36
|
def registrations
|
28
37
|
with_mutex { @registrations }
|
29
38
|
end
|
@@ -40,6 +49,10 @@ module Wisper
|
|
40
49
|
instance.subscribe(*listeners)
|
41
50
|
end
|
42
51
|
|
52
|
+
def self.unsubscribe(*listeners)
|
53
|
+
instance.unsubscribe(*listeners)
|
54
|
+
end
|
55
|
+
|
43
56
|
def self.registrations
|
44
57
|
instance.registrations
|
45
58
|
end
|
data/lib/wisper/publisher.rb
CHANGED
@@ -11,6 +11,7 @@ module Wisper
|
|
11
11
|
#
|
12
12
|
# @return [self]
|
13
13
|
def subscribe(listener, options = {})
|
14
|
+
raise ArgumentError, "#{__method__} does not take a block, did you mean to call #on instead?" if block_given?
|
14
15
|
local_registrations << ObjectRegistration.new(listener, options)
|
15
16
|
self
|
16
17
|
end
|
@@ -23,6 +24,7 @@ module Wisper
|
|
23
24
|
# @return [self]
|
24
25
|
def on(*events, &block)
|
25
26
|
raise ArgumentError, 'must give at least one event' if events.empty?
|
27
|
+
raise ArgumentError, 'must pass a block' if !block
|
26
28
|
local_registrations << BlockRegistration.new(block, on: events)
|
27
29
|
self
|
28
30
|
end
|
@@ -7,7 +7,7 @@ module Wisper
|
|
7
7
|
def initialize(listener, options)
|
8
8
|
super(listener, options)
|
9
9
|
@with = options[:with]
|
10
|
-
@prefix =
|
10
|
+
@prefix = ValueObjects::Prefix.new options[:prefix]
|
11
11
|
@allowed_classes = Array(options[:scope]).map(&:to_s).to_set
|
12
12
|
@broadcaster = map_broadcaster(options[:async] || options[:broadcaster])
|
13
13
|
end
|
@@ -29,21 +29,6 @@ module Wisper
|
|
29
29
|
prefix + (with || event).to_s
|
30
30
|
end
|
31
31
|
|
32
|
-
def stringify_prefix(_prefix)
|
33
|
-
case _prefix
|
34
|
-
when nil
|
35
|
-
''
|
36
|
-
when true
|
37
|
-
default_prefix + '_'
|
38
|
-
else
|
39
|
-
_prefix.to_s + '_'
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
def default_prefix
|
44
|
-
'on'
|
45
|
-
end
|
46
|
-
|
47
32
|
def map_broadcaster(value)
|
48
33
|
return value if value.respond_to?(:broadcast)
|
49
34
|
value = :async if value == true
|
@@ -4,39 +4,15 @@ module Wisper
|
|
4
4
|
class Registration
|
5
5
|
attr_reader :on, :listener
|
6
6
|
|
7
|
-
ALL = Object.new.freeze
|
8
|
-
|
9
7
|
def initialize(listener, options)
|
10
8
|
@listener = listener
|
11
|
-
@on
|
9
|
+
@on = ValueObjects::Events.new options[:on]
|
12
10
|
end
|
13
11
|
|
14
12
|
private
|
15
13
|
|
16
14
|
def should_broadcast?(event)
|
17
|
-
|
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
|
15
|
+
on.include? event
|
40
16
|
end
|
41
17
|
end
|
42
18
|
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module Wisper
|
2
|
+
module ValueObjects #:nodoc:
|
3
|
+
# Describes allowed events
|
4
|
+
#
|
5
|
+
# Duck-types the argument to quack like array of strings
|
6
|
+
# when responding to the {#include?} method call.
|
7
|
+
class Events
|
8
|
+
|
9
|
+
# @!scope class
|
10
|
+
# @!method new(on)
|
11
|
+
# Initializes a 'list' of events
|
12
|
+
#
|
13
|
+
# @param [NilClass, String, Symbol, Array, Regexp] list
|
14
|
+
#
|
15
|
+
# @raise [ArgumentError]
|
16
|
+
# if an argument if of unsupported type
|
17
|
+
#
|
18
|
+
# @return [undefined]
|
19
|
+
def initialize(list)
|
20
|
+
@list = list
|
21
|
+
end
|
22
|
+
|
23
|
+
# Check if given event is 'included' to the 'list' of events
|
24
|
+
#
|
25
|
+
# @param [#to_s] event
|
26
|
+
#
|
27
|
+
# @return [Boolean]
|
28
|
+
def include?(event)
|
29
|
+
appropriate_method.call(event.to_s)
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def methods
|
35
|
+
{
|
36
|
+
NilClass => ->(_event) { true },
|
37
|
+
String => ->(event) { list == event },
|
38
|
+
Symbol => ->(event) { list.to_s == event },
|
39
|
+
Enumerable => ->(event) { list.map(&:to_s).include? event },
|
40
|
+
Regexp => ->(event) { list.match(event) || false }
|
41
|
+
}
|
42
|
+
end
|
43
|
+
|
44
|
+
def list
|
45
|
+
@list
|
46
|
+
end
|
47
|
+
|
48
|
+
def appropriate_method
|
49
|
+
@appropriate_method ||= methods[recognized_type]
|
50
|
+
end
|
51
|
+
|
52
|
+
def recognized_type
|
53
|
+
methods.keys.detect(&list.method(:is_a?)) || type_not_recognized
|
54
|
+
end
|
55
|
+
|
56
|
+
def type_not_recognized
|
57
|
+
fail(ArgumentError, "#{list.class} not supported for `on` argument")
|
58
|
+
end
|
59
|
+
end # class Events
|
60
|
+
end # module ValueObjects
|
61
|
+
end # module Wisper
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Wisper
|
2
|
+
module ValueObjects #:nodoc:
|
3
|
+
# Prefix for notifications
|
4
|
+
#
|
5
|
+
# @example
|
6
|
+
# Wisper::ValueObjects::Prefix.new nil # => ""
|
7
|
+
# Wisper::ValueObjects::Prefix.new "when" # => "when_"
|
8
|
+
# Wisper::ValueObjects::Prefix.new true # => "on_"
|
9
|
+
class Prefix < String
|
10
|
+
class << self
|
11
|
+
attr_accessor :default
|
12
|
+
end
|
13
|
+
|
14
|
+
# @param [true, nil, #to_s] value
|
15
|
+
#
|
16
|
+
# @return [undefined]
|
17
|
+
def initialize(value = nil)
|
18
|
+
super "#{ (value == true) ? default : value }_"
|
19
|
+
replace "" if self == "_"
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def default
|
25
|
+
self.class.default || 'on'
|
26
|
+
end
|
27
|
+
end # class Prefix
|
28
|
+
end # module ValueObjects
|
29
|
+
end # module Wisper
|
data/lib/wisper/version.rb
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
describe Wisper::TemporaryListeners do
|
2
2
|
let(:listener_1) { double('listener', :to_a => nil) } # [1]
|
3
3
|
let(:listener_2) { double('listener', :to_a => nil) }
|
4
|
-
|
4
|
+
|
5
|
+
let(:publisher) { publisher_class.new }
|
5
6
|
|
6
7
|
describe '.subscribe' do
|
7
8
|
it 'globally subscribes listener for duration of given block' do
|
@@ -31,30 +32,32 @@ describe Wisper::TemporaryListeners do
|
|
31
32
|
publisher.instance_eval { broadcast(:failure) }
|
32
33
|
end
|
33
34
|
|
34
|
-
it '
|
35
|
+
it 'is thread safe' do
|
35
36
|
num_threads = 20
|
36
37
|
(1..num_threads).to_a.map do
|
37
38
|
Thread.new do
|
38
39
|
Wisper::TemporaryListeners.registrations << Object.new
|
39
|
-
expect(Wisper::TemporaryListeners.registrations.size).to
|
40
|
+
expect(Wisper::TemporaryListeners.registrations.size).to eq 1
|
40
41
|
end
|
41
42
|
end.each(&:join)
|
42
43
|
|
43
|
-
expect(Wisper::TemporaryListeners.registrations
|
44
|
+
expect(Wisper::TemporaryListeners.registrations).to be_empty
|
44
45
|
end
|
45
46
|
|
46
|
-
it '
|
47
|
+
it 'clears registrations when an exception occurs' do
|
48
|
+
MyError = Class.new(StandardError)
|
49
|
+
|
47
50
|
begin
|
48
51
|
Wisper::TemporaryListeners.subscribe(listener_1) do
|
49
|
-
raise
|
52
|
+
raise MyError
|
50
53
|
end
|
51
|
-
rescue
|
54
|
+
rescue MyError
|
52
55
|
end
|
53
56
|
|
54
|
-
expect(Wisper::TemporaryListeners.registrations
|
57
|
+
expect(Wisper::TemporaryListeners.registrations).to be_empty
|
55
58
|
end
|
56
59
|
|
57
|
-
it 'returns self
|
60
|
+
it 'returns self' do
|
58
61
|
expect(Wisper::TemporaryListeners.subscribe {}).to be_an_instance_of(Wisper::TemporaryListeners)
|
59
62
|
end
|
60
63
|
end
|
@@ -28,12 +28,12 @@ module Wisper
|
|
28
28
|
context 'without arguments' do
|
29
29
|
let(:args) { [] }
|
30
30
|
|
31
|
-
it 'logs
|
31
|
+
it 'logs published event' do
|
32
32
|
expect(logger).to receive(:info).with('[WISPER] Publisher#1 published thing_created to Listener#2 with no arguments')
|
33
33
|
subject.broadcast(listener, publisher, event, args)
|
34
34
|
end
|
35
35
|
|
36
|
-
it '
|
36
|
+
it 'delegates broadcast to a given broadcaster' do
|
37
37
|
expect(broadcaster).to receive(:broadcast).with(listener, publisher, event, args)
|
38
38
|
subject.broadcast(listener, publisher, event, args)
|
39
39
|
end
|
@@ -47,10 +47,30 @@ module Wisper
|
|
47
47
|
subject.broadcast(listener, publisher, event, args)
|
48
48
|
end
|
49
49
|
|
50
|
-
it '
|
50
|
+
it 'delegates broadcast to a given broadcaster' do
|
51
51
|
expect(broadcaster).to receive(:broadcast).with(listener, publisher, event, args)
|
52
52
|
subject.broadcast(listener, publisher, event, args)
|
53
53
|
end
|
54
|
+
|
55
|
+
context 'when argument is a hash' do
|
56
|
+
let(:args) { [hash] }
|
57
|
+
let(:hash) { {key: 'value'} }
|
58
|
+
|
59
|
+
it 'logs published event and arguments' do
|
60
|
+
expect(logger).to receive(:info).with("[WISPER] Publisher#1 published thing_created to Listener#2 with Hash##{hash.object_id}: #{hash.inspect}")
|
61
|
+
subject.broadcast(listener, publisher, event, args)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
context 'when argument is an integer' do
|
66
|
+
let(:args) { [number] }
|
67
|
+
let(:number) { 10 }
|
68
|
+
|
69
|
+
it 'logs published event and arguments' do
|
70
|
+
expect(logger).to receive(:info).with("[WISPER] Publisher#1 published thing_created to Listener#2 with #{number.class.name}##{number.object_id}: 10")
|
71
|
+
subject.broadcast(listener, publisher, event, args)
|
72
|
+
end
|
73
|
+
end
|
54
74
|
end
|
55
75
|
|
56
76
|
end
|
@@ -20,5 +20,17 @@ module Wisper
|
|
20
20
|
end
|
21
21
|
end
|
22
22
|
end
|
23
|
+
|
24
|
+
describe '#default_prefix=' do
|
25
|
+
let(:prefix_class) { ValueObjects::Prefix }
|
26
|
+
let(:default_value) { double }
|
27
|
+
|
28
|
+
before { allow(prefix_class).to receive(:default=) }
|
29
|
+
|
30
|
+
it 'sets the default value for prefixes' do
|
31
|
+
expect(prefix_class).to receive(:default=).with(default_value)
|
32
|
+
subject.default_prefix = default_value
|
33
|
+
end
|
34
|
+
end
|
23
35
|
end
|
24
36
|
end
|
@@ -211,6 +211,15 @@ describe Wisper::Publisher do
|
|
211
211
|
it 'is aliased to .subscribe' do
|
212
212
|
expect(publisher).to respond_to(:subscribe)
|
213
213
|
end
|
214
|
+
|
215
|
+
it 'raises a helpful error if trying to pass a block' do
|
216
|
+
invalid = ->{
|
217
|
+
publisher.subscribe(:success) do
|
218
|
+
puts
|
219
|
+
end
|
220
|
+
}
|
221
|
+
expect{ invalid.call }.to raise_error(ArgumentError)
|
222
|
+
end
|
214
223
|
end
|
215
224
|
|
216
225
|
describe '.on' do
|
@@ -222,6 +231,10 @@ describe Wisper::Publisher do
|
|
222
231
|
expect { publisher.on() {} }.to raise_error(ArgumentError)
|
223
232
|
end
|
224
233
|
|
234
|
+
it 'raises an error of no block given' do
|
235
|
+
expect { publisher.on(:something) }.to raise_error(ArgumentError)
|
236
|
+
end
|
237
|
+
|
225
238
|
it 'returns publisher so methods can be chained' do
|
226
239
|
expect(publisher.on(:foo) {}).to eq publisher
|
227
240
|
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
describe Wisper::ValueObjects::Events do
|
2
|
+
context 'nil' do
|
3
|
+
subject { described_class.new nil }
|
4
|
+
|
5
|
+
describe '#include?' do
|
6
|
+
it 'returns true' do
|
7
|
+
expect(subject.include? 'foo').to be_truthy
|
8
|
+
expect(subject.include? :bar).to be_truthy
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
context '"foo"' do
|
14
|
+
let(:foo) { Class.new(String).new 'foo' }
|
15
|
+
subject { described_class.new foo }
|
16
|
+
|
17
|
+
describe '#include?' do
|
18
|
+
it 'returns true for "foo"' do
|
19
|
+
expect(subject.include? 'foo').to be_truthy
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'returns true for :foo' do
|
23
|
+
expect(subject.include? :foo).to be_truthy
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'returns false otherwise' do
|
27
|
+
expect(subject.include? 'bar').to be_falsey
|
28
|
+
expect(subject.include? :bar).to be_falsey
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
context ':foo' do
|
34
|
+
subject { described_class.new :foo }
|
35
|
+
|
36
|
+
describe '#include?' do
|
37
|
+
it 'returns true for "foo"' do
|
38
|
+
expect(subject.include? 'foo').to be_truthy
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'returns true for :foo' do
|
42
|
+
expect(subject.include? :foo).to be_truthy
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'returns false otherwise' do
|
46
|
+
expect(subject.include? 'bar').to be_falsey
|
47
|
+
expect(subject.include? :bar).to be_falsey
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
context '[:foo, "bar"]' do
|
53
|
+
subject { described_class.new [:foo, 'bar'] }
|
54
|
+
|
55
|
+
describe '#include?' do
|
56
|
+
it 'returns true for "foo"' do
|
57
|
+
expect(subject.include? 'foo').to be_truthy
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'returns true for :foo' do
|
61
|
+
expect(subject.include? :foo).to be_truthy
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'returns true for "bar"' do
|
65
|
+
expect(subject.include? 'bar').to be_truthy
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'returns true for :bar' do
|
69
|
+
expect(subject.include? :bar).to be_truthy
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'returns false otherwise' do
|
73
|
+
expect(subject.include? 'baz').to be_falsey
|
74
|
+
expect(subject.include? :baz).to be_falsey
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
context 'by /foo/' do
|
80
|
+
subject { described_class.new(/foo/) }
|
81
|
+
|
82
|
+
describe '#include?' do
|
83
|
+
it 'returns true for "foo"' do
|
84
|
+
expect(subject.include? 'foo').to be_truthy
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'returns true for :foo' do
|
88
|
+
expect(subject.include? :foo).to be_truthy
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'returns false otherwise' do
|
92
|
+
expect(subject.include? 'bar').to be_falsey
|
93
|
+
expect(subject.include? :bar).to be_falsey
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
context 'another class' do
|
99
|
+
subject { described_class.new Object.new }
|
100
|
+
|
101
|
+
describe '#include?' do
|
102
|
+
it 'raises ArgumentError' do
|
103
|
+
expect { subject.include? 'foo' }.to raise_error(ArgumentError)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
describe Wisper::ValueObjects::Prefix do
|
2
|
+
|
3
|
+
it 'is a string' do
|
4
|
+
expect(subject).to be_kind_of String
|
5
|
+
end
|
6
|
+
|
7
|
+
describe '.new' do
|
8
|
+
context 'without arguments' do
|
9
|
+
subject { described_class.new }
|
10
|
+
it { is_expected.to eq '' }
|
11
|
+
end
|
12
|
+
|
13
|
+
context 'nil' do
|
14
|
+
subject { described_class.new nil }
|
15
|
+
it { is_expected.to eq '' }
|
16
|
+
end
|
17
|
+
|
18
|
+
context 'true' do
|
19
|
+
subject { described_class.new true }
|
20
|
+
it { is_expected.to eq 'on_' }
|
21
|
+
end
|
22
|
+
|
23
|
+
context '"foo"' do
|
24
|
+
subject { described_class.new 'foo' }
|
25
|
+
it { is_expected.to eq 'foo_' }
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe '.default=' do
|
30
|
+
after { described_class.default = nil }
|
31
|
+
|
32
|
+
context 'nil' do
|
33
|
+
it "doesn't change default prefix" do
|
34
|
+
expect { described_class.default = nil }
|
35
|
+
.not_to change { described_class.new true }.from('on_')
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
context '"foo"' do
|
40
|
+
it 'changes default prefix' do
|
41
|
+
expect { described_class.default = 'foo' }
|
42
|
+
.to change { described_class.new true }.from('on_').to('foo_')
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
data/spec/lib/wisper_spec.rb
CHANGED
@@ -1,62 +1,99 @@
|
|
1
1
|
describe Wisper do
|
2
2
|
describe '.subscribe' do
|
3
|
-
context 'given block' do
|
3
|
+
context 'when given block' do
|
4
|
+
|
4
5
|
it 'subscribes listeners to all events for duration of the block' do
|
5
6
|
publisher = publisher_class.new
|
6
|
-
listener
|
7
|
+
listener = double('listener')
|
7
8
|
|
8
|
-
expect(listener).to receive(:
|
9
|
-
expect(listener).not_to receive(:
|
9
|
+
expect(listener).to receive(:first_event)
|
10
|
+
expect(listener).not_to receive(:second_event)
|
10
11
|
|
11
12
|
Wisper.subscribe(listener) do
|
12
|
-
publisher.send(:broadcast, '
|
13
|
+
publisher.send(:broadcast, 'first_event')
|
13
14
|
end
|
14
15
|
|
15
|
-
publisher.send(:broadcast, '
|
16
|
+
publisher.send(:broadcast, 'second_event')
|
16
17
|
end
|
17
18
|
end
|
18
19
|
|
19
|
-
context 'no block given' do
|
20
|
-
it 'subscribes
|
20
|
+
context 'when no block given' do
|
21
|
+
it 'subscribes listener to all events' do
|
21
22
|
listener = double('listener')
|
22
23
|
Wisper.subscribe(listener)
|
23
24
|
expect(Wisper::GlobalListeners.listeners).to eq [listener]
|
24
25
|
end
|
25
26
|
|
26
|
-
it 'subscribes
|
27
|
+
it 'subscribes listeners to all events' do
|
27
28
|
listener_1 = double('listener')
|
28
29
|
listener_2 = double('listener')
|
29
|
-
listener_3 = double('listener')
|
30
30
|
|
31
31
|
Wisper.subscribe(listener_1, listener_2)
|
32
32
|
|
33
33
|
expect(Wisper::GlobalListeners.listeners).to include listener_1, listener_2
|
34
|
-
expect(Wisper::GlobalListeners.listeners).not_to include listener_3
|
35
34
|
end
|
36
35
|
end
|
37
36
|
end
|
38
37
|
|
39
|
-
|
40
|
-
|
38
|
+
describe '.unsubscribe' do
|
39
|
+
it 'removes listener from list of listeners' do
|
40
|
+
listener = double('listener')
|
41
|
+
|
42
|
+
Wisper.subscribe(listener)
|
43
|
+
expect(Wisper::GlobalListeners.listeners).to eq [listener]
|
44
|
+
|
45
|
+
Wisper.unsubscribe(listener)
|
46
|
+
expect(Wisper::GlobalListeners.listeners).to eq []
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'removes listeners from list of listeners' do
|
50
|
+
listener_1 = double('listener')
|
51
|
+
listener_2 = double('listener')
|
52
|
+
|
53
|
+
Wisper.subscribe(listener_1, listener_2)
|
54
|
+
expect(Wisper::GlobalListeners.listeners).to include listener_1, listener_2
|
55
|
+
|
56
|
+
Wisper.unsubscribe(listener_1, listener_2)
|
57
|
+
expect(Wisper::GlobalListeners.listeners).to eq []
|
58
|
+
end
|
41
59
|
end
|
42
60
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
61
|
+
describe '.publisher' do
|
62
|
+
it 'returns the Publisher module' do
|
63
|
+
expect(Wisper.publisher).to eq Wisper::Publisher
|
64
|
+
end
|
47
65
|
end
|
48
66
|
|
49
|
-
|
50
|
-
|
67
|
+
describe '.clear' do
|
68
|
+
before { Wisper.subscribe(double) }
|
69
|
+
|
70
|
+
it 'clears all global listeners' do
|
71
|
+
Wisper.clear
|
72
|
+
expect(Wisper::GlobalListeners.listeners).to be_empty
|
73
|
+
end
|
51
74
|
end
|
52
75
|
|
53
|
-
|
54
|
-
|
55
|
-
expect(
|
76
|
+
describe '.configuration' do
|
77
|
+
it 'returns configuration object' do
|
78
|
+
expect(Wisper.configuration).to be_an_instance_of(Wisper::Configuration)
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'is memorized' do
|
82
|
+
expect(Wisper.configuration).to eq Wisper.configuration
|
56
83
|
end
|
57
84
|
end
|
58
85
|
|
59
|
-
|
60
|
-
|
86
|
+
describe '.configure' do
|
87
|
+
it 'passes configuration to given block' do
|
88
|
+
Wisper.configure do |config|
|
89
|
+
expect(config).to be_an_instance_of(Wisper::Configuration)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
describe '.setup' do
|
95
|
+
it 'sets a default broadcaster' do
|
96
|
+
expect(Wisper.configuration.broadcasters[:default]).to be_instance_of(Wisper::Broadcasters::SendBroadcaster)
|
97
|
+
end
|
61
98
|
end
|
62
99
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -22,11 +22,3 @@ end
|
|
22
22
|
def publisher_class
|
23
23
|
Class.new { include Wisper::Publisher }
|
24
24
|
end
|
25
|
-
|
26
|
-
# prevents deprecation warning showing up in spec output
|
27
|
-
def silence_warnings
|
28
|
-
original_verbosity = $VERBOSE
|
29
|
-
$VERBOSE = nil
|
30
|
-
yield
|
31
|
-
$VERBOSE = original_verbosity
|
32
|
-
end
|
data/wisper.gemspec
CHANGED
@@ -8,8 +8,12 @@ Gem::Specification.new do |gem|
|
|
8
8
|
gem.version = Wisper::VERSION
|
9
9
|
gem.authors = ["Kris Leech"]
|
10
10
|
gem.email = ["kris.leech@gmail.com"]
|
11
|
-
gem.description =
|
12
|
-
|
11
|
+
gem.description = <<-DESC
|
12
|
+
A micro library providing objects with Publish-Subscribe capabilities.
|
13
|
+
Both synchronous (in-process) and asynchronous (out-of-process) subscriptions are supported.
|
14
|
+
Check out the Wiki for articles, guides and examples: https://github.com/krisleech/wisper/wiki
|
15
|
+
DESC
|
16
|
+
gem.summary = "A micro library providing objects with Publish-Subscribe capabilities"
|
13
17
|
gem.homepage = "https://github.com/krisleech/wisper"
|
14
18
|
gem.license = "MIT"
|
15
19
|
|
metadata
CHANGED
@@ -1,38 +1,19 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: wisper
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.0
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kris Leech
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
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
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-03-07 00:00:00.000000000 Z
|
34
12
|
dependencies: []
|
35
|
-
description:
|
13
|
+
description: |2
|
14
|
+
A micro library providing objects with Publish-Subscribe capabilities.
|
15
|
+
Both synchronous (in-process) and asynchronous (out-of-process) subscriptions are supported.
|
16
|
+
Check out the Wiki for articles, guides and examples: https://github.com/krisleech/wisper/wiki
|
36
17
|
email:
|
37
18
|
- kris.leech@gmail.com
|
38
19
|
executables: []
|
@@ -45,7 +26,6 @@ files:
|
|
45
26
|
- CHANGELOG.md
|
46
27
|
- CONTRIBUTING.md
|
47
28
|
- Gemfile
|
48
|
-
- Guardfile
|
49
29
|
- README.md
|
50
30
|
- Rakefile
|
51
31
|
- gem-public_cert.pem
|
@@ -59,6 +39,8 @@ files:
|
|
59
39
|
- lib/wisper/registration/object.rb
|
60
40
|
- lib/wisper/registration/registration.rb
|
61
41
|
- lib/wisper/temporary_listeners.rb
|
42
|
+
- lib/wisper/value_objects/events.rb
|
43
|
+
- lib/wisper/value_objects/prefix.rb
|
62
44
|
- lib/wisper/version.rb
|
63
45
|
- spec/lib/global_listeners_spec.rb
|
64
46
|
- spec/lib/integration_spec.rb
|
@@ -66,9 +48,12 @@ files:
|
|
66
48
|
- spec/lib/temporary_global_listeners_spec.rb
|
67
49
|
- spec/lib/wisper/broadcasters/logger_broadcaster_spec.rb
|
68
50
|
- spec/lib/wisper/broadcasters/send_broadcaster_spec.rb
|
51
|
+
- spec/lib/wisper/configuration/broadcasters_spec.rb
|
69
52
|
- spec/lib/wisper/configuration_spec.rb
|
70
53
|
- spec/lib/wisper/publisher_spec.rb
|
71
54
|
- spec/lib/wisper/registrations/object_spec.rb
|
55
|
+
- spec/lib/wisper/value_objects/events_spec.rb
|
56
|
+
- spec/lib/wisper/value_objects/prefix_spec.rb
|
72
57
|
- spec/lib/wisper_spec.rb
|
73
58
|
- spec/spec_helper.rb
|
74
59
|
- wisper.gemspec
|
@@ -87,15 +72,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
87
72
|
version: '0'
|
88
73
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
89
74
|
requirements:
|
90
|
-
- - "
|
75
|
+
- - ">="
|
91
76
|
- !ruby/object:Gem::Version
|
92
|
-
version:
|
77
|
+
version: '0'
|
93
78
|
requirements: []
|
94
79
|
rubyforge_project:
|
95
|
-
rubygems_version: 2.
|
80
|
+
rubygems_version: 2.5.1
|
96
81
|
signing_key:
|
97
82
|
specification_version: 4
|
98
|
-
summary:
|
83
|
+
summary: A micro library providing objects with Publish-Subscribe capabilities
|
99
84
|
test_files:
|
100
85
|
- spec/lib/global_listeners_spec.rb
|
101
86
|
- spec/lib/integration_spec.rb
|
@@ -103,9 +88,11 @@ test_files:
|
|
103
88
|
- spec/lib/temporary_global_listeners_spec.rb
|
104
89
|
- spec/lib/wisper/broadcasters/logger_broadcaster_spec.rb
|
105
90
|
- spec/lib/wisper/broadcasters/send_broadcaster_spec.rb
|
91
|
+
- spec/lib/wisper/configuration/broadcasters_spec.rb
|
106
92
|
- spec/lib/wisper/configuration_spec.rb
|
107
93
|
- spec/lib/wisper/publisher_spec.rb
|
108
94
|
- spec/lib/wisper/registrations/object_spec.rb
|
95
|
+
- spec/lib/wisper/value_objects/events_spec.rb
|
96
|
+
- spec/lib/wisper/value_objects/prefix_spec.rb
|
109
97
|
- spec/lib/wisper_spec.rb
|
110
98
|
- spec/spec_helper.rb
|
111
|
-
has_rdoc:
|
checksums.yaml.gz.sig
DELETED
data.tar.gz.sig
DELETED
Binary file
|
data/Guardfile
DELETED
metadata.gz.sig
DELETED
Binary file
|