wisper 2.0.0.rc1 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
-
[](http://badge.fury.io/rb/wisper)
|
6
|
+
[](https://codeclimate.com/github/krisleech/wisper)
|
7
|
+
[](https://travis-ci.org/krisleech/wisper)
|
8
|
+
[](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
|