wisper 0.0.2 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +6 -0
- data/README.md +157 -20
- data/Rakefile +6 -0
- data/lib/wisper.rb +13 -32
- data/lib/wisper/registration/block.rb +9 -0
- data/lib/wisper/registration/object.rb +23 -0
- data/lib/wisper/registration/registration.rb +16 -0
- data/lib/wisper/version.rb +1 -1
- data/spec/lib/integration_spec.rb +27 -0
- data/spec/lib/simple_example_spec.rb +23 -0
- data/spec/lib/wisper_spec.rb +95 -21
- data/wisper.gemspec +1 -1
- metadata +11 -5
data/.travis.yml
ADDED
data/README.md
CHANGED
@@ -2,6 +2,9 @@
|
|
2
2
|
|
3
3
|
Simple pub/sub for Ruby objects
|
4
4
|
|
5
|
+
[![Code Climate](https://codeclimate.com/github/krisleech/wisper.png)](https://codeclimate.com/github/krisleech/wisper)
|
6
|
+
[![Build Status](https://travis-ci.org/krisleech/wisper.png)](https://travis-ci.org/krisleech/wisper)
|
7
|
+
|
5
8
|
While this is not dependent on Rails in any way it was extracted from a Rails
|
6
9
|
project and is used as an alternative to ActiveRecord callbacks and Observers.
|
7
10
|
|
@@ -20,42 +23,123 @@ Add this line to your application's Gemfile:
|
|
20
23
|
|
21
24
|
## Usage
|
22
25
|
|
26
|
+
Any class with the Wisper module included can broadcast events to subscribed
|
27
|
+
listeners. Listeners are added, at runtime, to the publishing object.
|
28
|
+
|
29
|
+
### Publishing
|
30
|
+
|
23
31
|
```ruby
|
24
|
-
class
|
32
|
+
class MyPublisher
|
25
33
|
include Wisper
|
26
34
|
|
27
|
-
def
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
35
|
+
def do_something
|
36
|
+
publish(:done_something, self)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
```
|
40
|
+
|
41
|
+
When the publisher publishes an event it can pass any number of arguments which
|
42
|
+
are passed on to the listeners.
|
43
|
+
|
44
|
+
```ruby
|
45
|
+
publish(:done_something, self, 'hello', 'world')
|
46
|
+
```
|
47
|
+
|
48
|
+
### Subscribing
|
49
|
+
|
50
|
+
#### Listeners
|
51
|
+
|
52
|
+
The listener is subscribed to all events it responds to.
|
53
|
+
|
54
|
+
```ruby
|
55
|
+
listener = Object.new # any object
|
56
|
+
my_publisher = MyPublisher.new
|
57
|
+
my_publisher.subscribe(listener)
|
58
|
+
```
|
59
|
+
|
60
|
+
#### Blocks
|
61
|
+
|
62
|
+
The block is subscribed to a single event.
|
63
|
+
|
64
|
+
```ruby
|
65
|
+
my_publisher = MyPublisher.new
|
66
|
+
my_publisher.on(:done_something) do |publisher|
|
67
|
+
# ...
|
68
|
+
end
|
69
|
+
```
|
70
|
+
|
71
|
+
### ActiveRecord
|
72
|
+
|
73
|
+
```ruby
|
74
|
+
class Post < ActiveRecord::Base
|
75
|
+
include Wisper
|
76
|
+
|
77
|
+
def create
|
78
|
+
if save
|
79
|
+
publish(:create_post_successful, self)
|
32
80
|
else
|
33
|
-
|
81
|
+
publish(:create_post_failed, self)
|
34
82
|
end
|
35
83
|
end
|
36
84
|
end
|
85
|
+
```
|
86
|
+
|
87
|
+
### ActionController
|
37
88
|
|
38
|
-
|
89
|
+
```ruby
|
90
|
+
class PostsController < ApplicationController
|
39
91
|
def create
|
40
|
-
|
92
|
+
@post = Post.new(params[:post])
|
41
93
|
|
42
|
-
|
43
|
-
|
44
|
-
|
94
|
+
@post.subscribe(PusherListener.new)
|
95
|
+
@post.subscribe(ActivityListener.new)
|
96
|
+
@post.subscribe(StatisticsListener.new)
|
45
97
|
|
46
|
-
|
47
|
-
|
48
|
-
end
|
98
|
+
@post.on(:create_post_successful) { |post| redirect_to post }
|
99
|
+
@post.on(:create_post_failed) { |post| render :action => :new }
|
49
100
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
101
|
+
@post.create
|
102
|
+
end
|
103
|
+
end
|
104
|
+
```
|
105
|
+
|
106
|
+
### Service/Use case object
|
107
|
+
|
108
|
+
The downside to publishing directly from ActiveRecord models is that an event
|
109
|
+
can get fired and then rolled back if a transaction fails.
|
54
110
|
|
55
|
-
|
111
|
+
Since I am trying to make my models dumb I tend to use a separate service
|
112
|
+
object which contains all the logic and wraps it all in a transaction.
|
113
|
+
|
114
|
+
The follow is contrived, but you can imagine it doing more than just updating a
|
115
|
+
record, maybe sending an email or updating other records.
|
116
|
+
|
117
|
+
```ruby
|
118
|
+
class CreateThing
|
119
|
+
include Wisper
|
120
|
+
|
121
|
+
def execute(attributes)
|
122
|
+
thing = Thing.new(attributes)
|
123
|
+
|
124
|
+
if thing.valid?
|
125
|
+
ActiveRecord::Base.transaction do
|
126
|
+
thing.save
|
127
|
+
# ...
|
128
|
+
end
|
129
|
+
publish(:create_thing_successful, thing)
|
130
|
+
else
|
131
|
+
publish(:create_thing_failed, thing)
|
132
|
+
end
|
56
133
|
end
|
57
134
|
end
|
135
|
+
```
|
136
|
+
|
137
|
+
### Example listeners
|
58
138
|
|
139
|
+
These are typical app wide listeners which have a method for pretty much every
|
140
|
+
event which is broadcast.
|
141
|
+
|
142
|
+
```ruby
|
59
143
|
class PusherListener
|
60
144
|
def create_thing_successful(thing)
|
61
145
|
# ...
|
@@ -75,6 +159,59 @@ class StatisticsListener
|
|
75
159
|
end
|
76
160
|
```
|
77
161
|
|
162
|
+
## Subscribing to selected events
|
163
|
+
|
164
|
+
By default a listener will get notified of all events it responds to. You can
|
165
|
+
limit which events a listener is notified of by passing an event or array of
|
166
|
+
events to `:on`.
|
167
|
+
|
168
|
+
```ruby
|
169
|
+
post_creater.subscribe(PusherListener.new, :on => :create_post_successful)
|
170
|
+
```
|
171
|
+
|
172
|
+
## Mapping event to a different method
|
173
|
+
|
174
|
+
By default the method called on the subscriber is the same as the event
|
175
|
+
broadcast. However it can be mapped to a different method using `:with`.
|
176
|
+
|
177
|
+
```ruby
|
178
|
+
report_creator.subscribe(MailResponder.new, :with => :successful)
|
179
|
+
```
|
180
|
+
|
181
|
+
In the above case it is pretty useless unless used in conjuction with `:on`
|
182
|
+
since all events will get mapped to `:successful`. Instead you might do
|
183
|
+
something like this:
|
184
|
+
|
185
|
+
```ruby
|
186
|
+
report_creator.subscribe(MailResponder.new, :on => :create_report_successful,
|
187
|
+
:with => :successful)
|
188
|
+
```
|
189
|
+
|
190
|
+
If you pass an array of events to `:on` each event will be mapped to the same
|
191
|
+
method when `:with` is specified. If you need to listen for select events
|
192
|
+
_and_ map each one to a different method subscribe the listener once for
|
193
|
+
each mapping:
|
194
|
+
|
195
|
+
```ruby
|
196
|
+
report_creator.subscribe(MailResponder.new, :on => :create_report_successful,
|
197
|
+
:with => :successful)
|
198
|
+
|
199
|
+
report_creator.subscribe(MailResponder.new, :on => :create_report_failed,
|
200
|
+
:with => :failed)
|
201
|
+
```
|
202
|
+
|
203
|
+
## Chaining subscriptions
|
204
|
+
|
205
|
+
```ruby
|
206
|
+
post.on(:success) { |post| redirect_to post }
|
207
|
+
.on(:failure) { |post| render :action => :edit, :locals => :post => post }
|
208
|
+
```
|
209
|
+
|
210
|
+
## Compatibility
|
211
|
+
|
212
|
+
Tested with 1.9.x on MRI, JRuby and Rubinius.
|
213
|
+
See the [build status](https://travis-ci.org/krisleech/wisper) for details.
|
214
|
+
|
78
215
|
## License
|
79
216
|
|
80
217
|
(The MIT License)
|
data/Rakefile
CHANGED
data/lib/wisper.rb
CHANGED
@@ -1,4 +1,7 @@
|
|
1
1
|
require "wisper/version"
|
2
|
+
require "wisper/registration/registration"
|
3
|
+
require "wisper/registration/object"
|
4
|
+
require "wisper/registration/block"
|
2
5
|
|
3
6
|
module Wisper
|
4
7
|
def listeners
|
@@ -7,56 +10,34 @@ module Wisper
|
|
7
10
|
|
8
11
|
def add_listener(listener, options = {})
|
9
12
|
listeners << ObjectRegistration.new(listener, options)
|
13
|
+
self
|
10
14
|
end
|
11
15
|
|
16
|
+
alias :subscribe :add_listener
|
17
|
+
|
12
18
|
def add_block_listener(options = {}, &block)
|
13
19
|
listeners << BlockRegistration.new(block, options)
|
20
|
+
self
|
14
21
|
end
|
15
22
|
|
16
23
|
# sugar
|
17
24
|
def respond_to(event, &block)
|
18
|
-
|
19
|
-
end
|
20
|
-
|
21
|
-
class BlockRegistration
|
22
|
-
attr_reader :on, :listener
|
23
|
-
|
24
|
-
def initialize(block, options)
|
25
|
-
@listener = block
|
26
|
-
@on = Array(options.fetch(:on) { 'all' }).map(&:to_s)
|
27
|
-
end
|
28
|
-
|
29
|
-
def broadcast(event, *args)
|
30
|
-
if on.include?(event) || on.include?('all')
|
31
|
-
listener.call(*args)
|
32
|
-
end
|
33
|
-
end
|
25
|
+
add_block_listener({:on => event}, &block)
|
34
26
|
end
|
35
27
|
|
36
|
-
|
37
|
-
attr_reader :on, :listener
|
38
|
-
|
39
|
-
def initialize(listener, options)
|
40
|
-
@listener = listener
|
41
|
-
@method = options[:method]
|
42
|
-
@on = Array(options.fetch(:on) { 'all' }).map(&:to_s)
|
43
|
-
end
|
44
|
-
|
45
|
-
def broadcast(event, *args)
|
46
|
-
if (on.include?(event) || on.include?('all')) && listener.respond_to?(event)
|
47
|
-
listener.public_send(event, *args)
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
28
|
+
alias :on :respond_to
|
51
29
|
|
52
30
|
private
|
53
31
|
|
54
32
|
def broadcast(event, *args)
|
55
33
|
listeners.each do | listener |
|
56
|
-
listener.broadcast(clean_event(event), *args)
|
34
|
+
listener.broadcast(clean_event(event), *args)
|
57
35
|
end
|
58
36
|
end
|
59
37
|
|
38
|
+
alias :publish :broadcast
|
39
|
+
alias :announce :broadcast
|
40
|
+
|
60
41
|
def clean_event(event)
|
61
42
|
event.to_s.gsub('-', '_')
|
62
43
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Wisper
|
2
|
+
class ObjectRegistration < Registration
|
3
|
+
attr_reader :with
|
4
|
+
|
5
|
+
def initialize(listener, options)
|
6
|
+
super(listener, options)
|
7
|
+
@with = options[:with]
|
8
|
+
end
|
9
|
+
|
10
|
+
def broadcast(event, *args)
|
11
|
+
method_to_call = map_event_to_method(event)
|
12
|
+
if should_broadcast?(event) && listener.respond_to?(method_to_call)
|
13
|
+
listener.public_send(method_to_call, *args)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def map_event_to_method(event)
|
20
|
+
with || event
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Wisper
|
2
|
+
class Registration
|
3
|
+
attr_reader :on, :listener
|
4
|
+
|
5
|
+
def initialize(listener, options)
|
6
|
+
@listener = listener
|
7
|
+
@on = Array(options.fetch(:on) { 'all' }).map(&:to_s)
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def should_broadcast?(event)
|
13
|
+
on.include?(event) || on.include?('all')
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
data/lib/wisper/version.rb
CHANGED
@@ -38,4 +38,31 @@ describe Wisper do
|
|
38
38
|
|
39
39
|
command.execute(true)
|
40
40
|
end
|
41
|
+
|
42
|
+
it 'maps events to different methods' do
|
43
|
+
listener_1 = double('listener')
|
44
|
+
listener_2 = double('listener')
|
45
|
+
listener_1.should_receive(:happy_days).with('hello')
|
46
|
+
listener_2.should_receive(:sad_days).with('world')
|
47
|
+
|
48
|
+
command = MyCommand.new
|
49
|
+
|
50
|
+
command.add_listener(listener_1, :on => :success, :with => :happy_days)
|
51
|
+
command.add_listener(listener_2, :on => :failure, :with => :sad_days)
|
52
|
+
|
53
|
+
command.execute(true)
|
54
|
+
command.execute(false)
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'subscribes block can be chained' do
|
58
|
+
insider = double('Insider')
|
59
|
+
insider.should_receive(:render).with('success')
|
60
|
+
|
61
|
+
command = MyCommand.new
|
62
|
+
|
63
|
+
command.on(:success) { |message| insider.render('success') }
|
64
|
+
.on(:failure) { |message| insider.render('failure') }
|
65
|
+
|
66
|
+
command.execute(true)
|
67
|
+
end
|
41
68
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
class MyPublisher
|
4
|
+
include Wisper
|
5
|
+
|
6
|
+
def do_something
|
7
|
+
# ...
|
8
|
+
broadcast(:bar, self)
|
9
|
+
broadcast(:foo, self)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
describe 'simple publishing' do
|
14
|
+
it 'subscribes listener to events' do
|
15
|
+
listener = double('listener')
|
16
|
+
listener.should_receive(:foo).with instance_of MyPublisher
|
17
|
+
listener.should_receive(:bar).with instance_of MyPublisher
|
18
|
+
|
19
|
+
my_publisher = MyPublisher.new
|
20
|
+
my_publisher.add_listener(listener)
|
21
|
+
my_publisher.do_something
|
22
|
+
end
|
23
|
+
end
|
data/spec/lib/wisper_spec.rb
CHANGED
@@ -5,7 +5,7 @@ describe Wisper do
|
|
5
5
|
let(:publisher) { Object.new.extend(Wisper) }
|
6
6
|
|
7
7
|
describe '.add_listener' do
|
8
|
-
it 'subscribes listener to all published events' do
|
8
|
+
it 'subscribes given listener to all published events' do
|
9
9
|
listener.should_receive(:this_happened)
|
10
10
|
listener.should_receive(:so_did_this)
|
11
11
|
|
@@ -15,52 +15,126 @@ describe Wisper do
|
|
15
15
|
publisher.send(:broadcast, 'so_did_this')
|
16
16
|
end
|
17
17
|
|
18
|
-
|
19
|
-
listener
|
20
|
-
|
21
|
-
|
18
|
+
describe ':on argument' do
|
19
|
+
it 'subscribes given listener to a single event' do
|
20
|
+
listener.should_receive(:this_happened)
|
21
|
+
listener.stub(:so_did_this)
|
22
|
+
listener.should_not_receive(:so_did_this)
|
22
23
|
|
23
|
-
|
24
|
+
listener.respond_to?(:so_did_this).should be_true
|
24
25
|
|
25
|
-
|
26
|
+
publisher.add_listener(listener, :on => 'this_happened')
|
26
27
|
|
27
|
-
|
28
|
-
|
28
|
+
publisher.send(:broadcast, 'this_happened')
|
29
|
+
publisher.send(:broadcast, 'so_did_this')
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'subscribes given listener to many events' do
|
33
|
+
listener.should_receive(:this_happened)
|
34
|
+
listener.should_receive(:and_this)
|
35
|
+
listener.stub(:so_did_this)
|
36
|
+
listener.should_not_receive(:so_did_this)
|
37
|
+
|
38
|
+
listener.respond_to?(:so_did_this).should be_true
|
39
|
+
|
40
|
+
publisher.add_listener(listener, :on => ['this_happened', 'and_this'])
|
41
|
+
|
42
|
+
publisher.send(:broadcast, 'this_happened')
|
43
|
+
publisher.send(:broadcast, 'so_did_this')
|
44
|
+
publisher.send(:broadcast, 'and_this')
|
45
|
+
end
|
29
46
|
end
|
30
47
|
|
31
|
-
|
32
|
-
listener
|
33
|
-
|
48
|
+
describe ':with argument' do
|
49
|
+
it 'sets method to call listener with on event' do
|
50
|
+
listener.should_receive(:different_method).twice
|
34
51
|
|
35
|
-
|
52
|
+
publisher.add_listener(listener, :with => :different_method)
|
36
53
|
|
37
|
-
|
54
|
+
publisher.send(:broadcast, 'this_happened')
|
55
|
+
publisher.send(:broadcast, 'so_did_this')
|
56
|
+
end
|
57
|
+
end
|
38
58
|
|
39
|
-
|
59
|
+
it 'returns publisher so methods can be chained' do
|
60
|
+
publisher.add_listener(listener, :on => 'so_did_this').should == publisher
|
40
61
|
end
|
41
62
|
end
|
42
63
|
|
43
|
-
describe '
|
44
|
-
it 'subscribes block to all events' do
|
64
|
+
describe '.add_block_listener' do
|
65
|
+
it 'subscribes given block to all events' do
|
45
66
|
insider = double('insider')
|
46
|
-
insider.should_receive(:it_happened)
|
67
|
+
insider.should_receive(:it_happened).twice
|
47
68
|
|
48
69
|
publisher.add_block_listener do
|
49
70
|
insider.it_happened
|
50
71
|
end
|
51
72
|
|
52
73
|
publisher.send(:broadcast, 'something_happened')
|
74
|
+
publisher.send(:broadcast, 'and_so_did_this')
|
53
75
|
end
|
54
76
|
|
55
|
-
|
56
|
-
|
57
|
-
|
77
|
+
describe ':on argument' do
|
78
|
+
it '.add_block_listener subscribes block to an event' do
|
79
|
+
insider = double('insider')
|
80
|
+
insider.should_not_receive(:it_happened).once
|
58
81
|
|
82
|
+
publisher.add_block_listener(:on => 'something_happened') do
|
83
|
+
insider.it_happened
|
84
|
+
end
|
85
|
+
|
86
|
+
publisher.send(:broadcast, 'something_happened')
|
87
|
+
publisher.send(:broadcast, 'and_so_did_this')
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'returns publisher so methods can be chained' do
|
59
92
|
publisher.add_block_listener(:on => 'this_thing_happened') do
|
93
|
+
end.should == publisher
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
describe '.on (alternative block syntax)' do
|
98
|
+
it 'subscribes given block to an event' do
|
99
|
+
insider = double('insider')
|
100
|
+
insider.should_receive(:it_happened)
|
101
|
+
|
102
|
+
publisher.on(:something_happened) do
|
60
103
|
insider.it_happened
|
61
104
|
end
|
62
105
|
|
63
106
|
publisher.send(:broadcast, 'something_happened')
|
64
107
|
end
|
65
108
|
end
|
109
|
+
|
110
|
+
describe '.broadcast' do
|
111
|
+
it 'does not publish events which cannot be responded to' do
|
112
|
+
listener.should_not_receive(:so_did_this)
|
113
|
+
listener.stub(:respond_to?, false)
|
114
|
+
|
115
|
+
publisher.add_listener(listener, :on => 'so_did_this')
|
116
|
+
|
117
|
+
publisher.send(:broadcast, 'so_did_this')
|
118
|
+
end
|
119
|
+
|
120
|
+
describe ':event argument' do
|
121
|
+
it 'is indifferent to string and symbol' do
|
122
|
+
listener.should_receive(:this_happened).twice
|
123
|
+
|
124
|
+
publisher.add_listener(listener)
|
125
|
+
|
126
|
+
publisher.send(:broadcast, 'this_happened')
|
127
|
+
publisher.send(:broadcast, :this_happened)
|
128
|
+
end
|
129
|
+
|
130
|
+
it 'is indifferent to dasherized and underscored strings' do
|
131
|
+
listener.should_receive(:this_happened).twice
|
132
|
+
|
133
|
+
publisher.add_listener(listener)
|
134
|
+
|
135
|
+
publisher.send(:broadcast, 'this_happened')
|
136
|
+
publisher.send(:broadcast, 'this-happened')
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
66
140
|
end
|
data/wisper.gemspec
CHANGED
@@ -10,7 +10,7 @@ Gem::Specification.new do |gem|
|
|
10
10
|
gem.email = ["kris.leech@gmail.com"]
|
11
11
|
gem.description = %q{pub/sub for Ruby objects}
|
12
12
|
gem.summary = %q{pub/sub for Ruby objects}
|
13
|
-
gem.homepage = ""
|
13
|
+
gem.homepage = "https://github.com/krisleech/wisper"
|
14
14
|
|
15
15
|
gem.files = `git ls-files`.split($/)
|
16
16
|
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: wisper
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 1.0.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-04-07 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
@@ -68,17 +68,22 @@ extra_rdoc_files: []
|
|
68
68
|
files:
|
69
69
|
- .gitignore
|
70
70
|
- .rspec
|
71
|
+
- .travis.yml
|
71
72
|
- Gemfile
|
72
73
|
- Guardfile
|
73
74
|
- README.md
|
74
75
|
- Rakefile
|
75
76
|
- lib/wisper.rb
|
77
|
+
- lib/wisper/registration/block.rb
|
78
|
+
- lib/wisper/registration/object.rb
|
79
|
+
- lib/wisper/registration/registration.rb
|
76
80
|
- lib/wisper/version.rb
|
77
81
|
- spec/lib/integration_spec.rb
|
82
|
+
- spec/lib/simple_example_spec.rb
|
78
83
|
- spec/lib/wisper_spec.rb
|
79
84
|
- spec/spec_helper.rb
|
80
85
|
- wisper.gemspec
|
81
|
-
homepage:
|
86
|
+
homepage: https://github.com/krisleech/wisper
|
82
87
|
licenses: []
|
83
88
|
post_install_message:
|
84
89
|
rdoc_options: []
|
@@ -92,7 +97,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
92
97
|
version: '0'
|
93
98
|
segments:
|
94
99
|
- 0
|
95
|
-
hash:
|
100
|
+
hash: -3667309302433800657
|
96
101
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
97
102
|
none: false
|
98
103
|
requirements:
|
@@ -101,7 +106,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
101
106
|
version: '0'
|
102
107
|
segments:
|
103
108
|
- 0
|
104
|
-
hash:
|
109
|
+
hash: -3667309302433800657
|
105
110
|
requirements: []
|
106
111
|
rubyforge_project:
|
107
112
|
rubygems_version: 1.8.23
|
@@ -110,5 +115,6 @@ specification_version: 3
|
|
110
115
|
summary: pub/sub for Ruby objects
|
111
116
|
test_files:
|
112
117
|
- spec/lib/integration_spec.rb
|
118
|
+
- spec/lib/simple_example_spec.rb
|
113
119
|
- spec/lib/wisper_spec.rb
|
114
120
|
- spec/spec_helper.rb
|