reactor 0.13.0 → 0.14.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.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +102 -17
  3. data/lib/reactor/controllers/concerns/actions/action_event.rb +11 -7
  4. data/lib/reactor/controllers/concerns/actions/create_event.rb +16 -12
  5. data/lib/reactor/controllers/concerns/actions/destroy_event.rb +8 -4
  6. data/lib/reactor/controllers/concerns/actions/edit_event.rb +8 -4
  7. data/lib/reactor/controllers/concerns/actions/index_event.rb +8 -4
  8. data/lib/reactor/controllers/concerns/actions/new_event.rb +8 -4
  9. data/lib/reactor/controllers/concerns/actions/show_event.rb +7 -3
  10. data/lib/reactor/controllers/concerns/actions/update_event.rb +16 -12
  11. data/lib/reactor/controllers/concerns/resource_actionable.rb +33 -31
  12. data/lib/reactor/controllers.rb +2 -0
  13. data/lib/reactor/errors.rb +7 -0
  14. data/lib/reactor/event.rb +2 -2
  15. data/lib/reactor/models/concerns/subscribable.rb +32 -79
  16. data/lib/reactor/models/subscriber.rb +21 -19
  17. data/lib/reactor/models.rb +5 -0
  18. data/lib/reactor/static_subscribers.rb +7 -0
  19. data/lib/reactor/subscription.rb +100 -0
  20. data/lib/reactor/testing.rb +50 -0
  21. data/lib/reactor/version.rb +1 -1
  22. data/lib/reactor/workers/database_subscriber_worker.rb +22 -0
  23. data/lib/reactor/workers/event_worker.rb +65 -0
  24. data/lib/reactor/workers/mailer_worker.rb +80 -0
  25. data/lib/reactor/workers.rb +8 -0
  26. data/lib/reactor.rb +24 -34
  27. data/reactor.gemspec +5 -1
  28. data/spec/event_spec.rb +10 -2
  29. data/spec/models/concerns/publishable_spec.rb +47 -38
  30. data/spec/models/concerns/subscribable_spec.rb +61 -5
  31. data/spec/models/subscriber_spec.rb +9 -2
  32. data/spec/reactor_spec.rb +2 -0
  33. data/spec/spec_helper.rb +19 -3
  34. data/spec/subscription_spec.rb +55 -0
  35. data/spec/support/active_record.rb +10 -0
  36. data/spec/workers/database_subscriber_worker_spec.rb +67 -0
  37. data/spec/workers/event_worker_spec.rb +126 -0
  38. data/spec/workers/mailer_worker_spec.rb +49 -0
  39. metadata +37 -5
@@ -35,6 +35,29 @@ module MyNamespace
35
35
  end
36
36
  end
37
37
 
38
+ class KittenMailer < ActionMailer::Base
39
+
40
+ include Reactor::Subscribable
41
+
42
+ on_event :auction, handler_name: 'auction' do |event|
43
+ raise "Event auction"
44
+ end
45
+
46
+ on_event :kitten_streaming do |event|
47
+ kitten_livestream(event)
48
+ end
49
+
50
+ def kitten_livestream(event)
51
+ mail(
52
+ to: 'admin@kittens.com',
53
+ from: 'test@kittens.com',
54
+ subject: 'Livestreaming kitten videos'
55
+ ) do |format|
56
+ format.text { 'Your favorite kittens are now live!' }
57
+ end
58
+ end
59
+ end
60
+
38
61
  Reactor.in_test_mode do
39
62
  class TestModeAuction < ActiveRecord::Base
40
63
  on_event :test_puppy_delivered, -> (event) { "success" }
@@ -43,9 +66,12 @@ end
43
66
 
44
67
  describe Reactor::Subscribable do
45
68
  let(:scheduled) { Sidekiq::ScheduledSet.new }
46
- before { Reactor::TEST_MODE_SUBSCRIBERS.clear }
47
69
 
48
70
  describe 'on_event' do
71
+ before do
72
+ Reactor.enable_test_mode_subscriber(Auction)
73
+ end
74
+
49
75
  it 'binds block of code statically to event being fired' do
50
76
  expect_any_instance_of(Auction).to receive(:update_column).with(:status, 'first_bid_made')
51
77
  Reactor::Event.publish(:bid_made, target: Auction.create!(start_at: 10.minutes.from_now))
@@ -63,6 +89,8 @@ describe Reactor::Subscribable do
63
89
  end
64
90
 
65
91
  describe 'binding symbol of class method' do
92
+ let(:pooped_handler) { Reactor::StaticSubscribers::Auction::PoopedHandler }
93
+
66
94
  it 'fires on event' do
67
95
  expect(Auction).to receive(:ring_bell)
68
96
  Reactor::Event.publish(:puppy_delivered)
@@ -70,7 +98,7 @@ describe Reactor::Subscribable do
70
98
 
71
99
  it 'can be delayed' do
72
100
  expect(Auction).to receive(:pick_up_poop)
73
- expect(Auction).to receive(:delay_for).with(5.minutes).and_return(Auction)
101
+ expect(pooped_handler).to receive(:perform_in).with(5.minutes, anything).and_call_original
74
102
  Reactor::Event.perform('pooped', {})
75
103
  end
76
104
  end
@@ -85,6 +113,16 @@ describe Reactor::Subscribable do
85
113
  Reactor::Event.publish(:another_event, actor: Auction.create!(start_at: 5.minutes.from_now))
86
114
  end
87
115
 
116
+ # ran into a case where if a class for the event name already exists,
117
+ # it will re-open that class instead of putting it in the proper namespace
118
+ # which raised a NoMethodError for perform_where_needed
119
+ it 'handles names that already exist in the global namespace' do
120
+ expect(::Auction).to be_a(Class)
121
+ # have to ensure multiple subscribers are loaded
122
+ expect(KittenMailer).to be_a(Class)
123
+ expect { Reactor::Event.publish :auction }.not_to raise_error
124
+ end
125
+
88
126
  describe 'in_memory flag' do
89
127
  it 'doesnt fire perform_async when true' do
90
128
  expect(Auction).to receive(:puppies!)
@@ -99,16 +137,34 @@ describe Reactor::Subscribable do
99
137
  end
100
138
 
101
139
  describe '#perform' do
140
+ around(:each) do |example|
141
+ Reactor.in_test_mode { example.run }
142
+ end
143
+
102
144
  it 'returns :__perform_aborted__ when Reactor is in test mode' do
103
145
  expect(Reactor::StaticSubscribers::TestModeAuction::TestPuppyDeliveredHandler.new.perform({})).to eq(:__perform_aborted__)
104
146
  Reactor::Event.publish(:test_puppy_delivered)
105
147
  end
106
148
 
107
149
  it 'performs normally when specifically enabled' do
108
- Reactor.enable_test_mode_subscriber(TestModeAuction)
109
- expect(Reactor::StaticSubscribers::TestModeAuction::TestPuppyDeliveredHandler.new.perform({})).not_to eq(:__perform_aborted__)
110
- Reactor::Event.publish(:test_puppy_delivered)
150
+ Reactor.with_subscriber_enabled(TestModeAuction) do
151
+ expect(Reactor::StaticSubscribers::TestModeAuction::TestPuppyDeliveredHandler.new.perform({})).not_to eq(:__perform_aborted__)
152
+ Reactor::Event.publish(:test_puppy_delivered)
153
+ end
111
154
  end
112
155
  end
113
156
  end
157
+
158
+ describe 'mailers', type: :mailer do
159
+ before { Reactor.enable_test_mode_subscriber KittenMailer }
160
+ after { Reactor.disable_test_mode_subscriber KittenMailer }
161
+
162
+ def deliveries
163
+ ActionMailer::Base.deliveries
164
+ end
165
+
166
+ it 'sends an email from a method on_event', focus: true do
167
+ expect { Reactor::Event.publish(:kitten_streaming) }.to change{ deliveries.count }.by(1)
168
+ end
169
+ end
114
170
  end
@@ -23,8 +23,15 @@ describe Reactor::Subscriber do
23
23
 
24
24
 
25
25
  describe 'matcher' do
26
- before { MySubscriber.create!(event_name: '*') }
27
- after { MySubscriber.destroy_all }
26
+ before do
27
+ MySubscriber.create!(event_name: '*')
28
+ Reactor.enable_test_mode_subscriber Reactor::Subscriber
29
+ end
30
+
31
+ after do
32
+ Reactor.disable_test_mode_subscriber Reactor::Subscriber
33
+ MySubscriber.destroy_all
34
+ end
28
35
 
29
36
  it 'can be set to star to bind to all events' do
30
37
  expect_any_instance_of(MySubscriber).to receive(:fire).with(hash_including('random' => 'data', 'event' => 'this_event'))
data/spec/reactor_spec.rb CHANGED
@@ -11,6 +11,8 @@ describe Reactor do
11
11
  let(:subscriber) { SomeClass }
12
12
 
13
13
  describe '.test_mode!' do
14
+ before { Reactor.disable_test_mode! }
15
+
14
16
  it 'sets Reactor into test mode' do
15
17
  expect(Reactor.test_mode?).to be_falsey
16
18
  Reactor.test_mode!
data/spec/spec_helper.rb CHANGED
@@ -6,13 +6,23 @@ require 'support/active_record'
6
6
  require 'sidekiq'
7
7
  require 'sidekiq/testing/inline'
8
8
  require 'sidekiq/api'
9
+
10
+ require 'simplecov'
11
+ SimpleCov.start do
12
+ add_filter "/testing/"
13
+ end
14
+
9
15
  require 'reactor'
10
16
  require 'reactor/testing/matchers'
11
17
 
12
18
  require 'rspec/its'
13
19
 
20
+ REDIS_URL = ENV["REDISTOGO_URL"] || ENV["REDIS_URL"] || "redis://localhost:6379/4"
21
+
22
+ ActionMailer::Base.delivery_method = :test
23
+
14
24
  Sidekiq.configure_server do |config|
15
- config.redis = { url: ENV["REDISTOGO_URL"] }
25
+ config.redis = { url: REDIS_URL }
16
26
 
17
27
  database_url = ENV['DATABASE_URL']
18
28
  if database_url
@@ -22,13 +32,19 @@ Sidekiq.configure_server do |config|
22
32
  end
23
33
 
24
34
  Sidekiq.configure_client do |config|
25
- config.redis = { url: ENV["REDISTOGO_URL"] }
35
+ config.redis = { url: REDIS_URL }
26
36
  end
27
37
 
28
38
 
29
39
  RSpec.configure do |config|
30
40
  # some (optional) config here
31
41
 
42
+ config.before(:each) do
43
+ Reactor.test_mode!
44
+ Reactor.clear_test_subscribers!
45
+ ActionMailer::Base.deliveries.clear
46
+ end
47
+
32
48
  # Runs Sidekiq jobs inline by default unless the RSpec metadata :sidekiq is specified,
33
49
  # in which case it will use the real Redis-backed Sidekiq queue
34
50
  config.before(:each, :sidekiq) do
@@ -45,4 +61,4 @@ RSpec.configure do |config|
45
61
  # the seed, which is printed after each run.
46
62
  # --seed 1234
47
63
  config.order = "random"
48
- end
64
+ end
@@ -0,0 +1,55 @@
1
+ require 'spec_helper'
2
+
3
+ describe Reactor::Subscription do
4
+
5
+ describe '.build_handler_name' do
6
+ let(:event_name) { :kitten_sleeping }
7
+
8
+ subject { described_class.build_handler_name(event_name) }
9
+
10
+ it 'should camelize event name' do
11
+ expect(subject).to eq('KittenSleepingHandler')
12
+ end
13
+
14
+ context 'with wildcard event name' do
15
+ let(:event_name) { '*' }
16
+ it { is_expected.to eq('WildcardHandler') }
17
+ end
18
+
19
+ context 'with handler name specified' do
20
+ let(:result) { 'SleepyKittenHandler' }
21
+ subject { described_class.build_handler_name(event_name, handler_name) }
22
+
23
+ context 'as snake_cased' do
24
+ let(:handler_name) { :sleepy_kitten_handler }
25
+ it { is_expected.to eq(result) }
26
+ end
27
+
28
+ context 'as CamelCased' do
29
+ let(:handler_name) { 'SleepyKittenHandler' }
30
+ it { is_expected.to eq(result) }
31
+ end
32
+ end
33
+ end
34
+
35
+ describe 'building a new subscriptiong' do
36
+ class SleepyKittenSubscriber ; end
37
+
38
+ let(:source) { SleepyKittenSubscriber }
39
+ let(:event_name) { :kitten_sleeping }
40
+ let(:action) { double('Callable Action') }
41
+
42
+ context 'for delayed async worker' do
43
+ let(:delay) { 10.minutes }
44
+ end
45
+
46
+ context 'for synchronous runners' do
47
+ let(:async) { false }
48
+ end
49
+
50
+ context 'with handler name specified' do
51
+ let(:handler_name) { :sleepy_kitten_streaming_handler }
52
+ end
53
+ end
54
+
55
+ end
@@ -14,6 +14,16 @@ ActiveRecord::Migration.create_table :auctions do |t|
14
14
  t.timestamps null: false
15
15
  end
16
16
 
17
+ ActiveRecord::Migration.create_table :publishers do |t|
18
+ t.string :name
19
+ t.datetime :start_at
20
+ t.datetime :close_at
21
+ t.boolean :we_want_it
22
+ t.integer :pet_id
23
+
24
+ t.timestamps null: false
25
+ end
26
+
17
27
  ActiveRecord::Migration.create_table :subscribers do |t|
18
28
  t.string :event_name
19
29
  t.string :type
@@ -0,0 +1,67 @@
1
+ require 'spec_helper'
2
+
3
+ class DbSubscriber < Reactor::Subscriber
4
+ attr_accessor :was_called
5
+
6
+ on_fire do
7
+ self.was_called = true
8
+ end
9
+ end
10
+
11
+ describe Reactor::Workers::DatabaseSubscriberWorker do
12
+ let(:event_name) { :fire_db_subscriber }
13
+ let(:data) { Hash[unused: :data] }
14
+ let!(:db_subscriber) { DbSubscriber.create!(event_name: event_name) }
15
+
16
+ let(:instance) { described_class.new }
17
+
18
+ describe '#perform' do
19
+
20
+ subject { instance.perform(db_subscriber.id, data) }
21
+
22
+ context 'when should_perform? is false' do
23
+ before { allow_any_instance_of(DbSubscriber).to receive(:should_perform?).and_return(false) }
24
+
25
+ it { is_expected.to eq(:__perform_aborted__) }
26
+ end
27
+
28
+ context 'when should_perform? is true' do
29
+ before do
30
+ allow(instance).to receive(:should_perform?).and_return(true)
31
+ end
32
+
33
+ it 'fires subscriber' do
34
+ expect(Reactor::Subscriber).to receive(:fire).with(db_subscriber.id, data)
35
+ subject
36
+ end
37
+ end
38
+
39
+ end
40
+
41
+ describe '#should_perform?' do
42
+ subject { instance.should_perform? }
43
+
44
+ context 'in test mode' do
45
+ context 'when subscriber is not enabled' do
46
+ it { is_expected.to eq(false) }
47
+ end
48
+
49
+ context 'when subscriber is enabled' do
50
+ it 'should equal true' do
51
+ Reactor.with_subscriber_enabled Reactor::Subscriber do
52
+ expect(subject).to eq(true)
53
+ end
54
+ end
55
+ end
56
+ end
57
+
58
+ context 'outside test mode' do
59
+ before do
60
+ allow(Reactor).to receive(:test_mode?).and_return(false)
61
+ end
62
+
63
+ it { is_expected.to eq(true) }
64
+ end
65
+ end
66
+
67
+ end
@@ -0,0 +1,126 @@
1
+ require 'spec_helper'
2
+
3
+ class SourceSubscriber
4
+ include Reactor::Subscribable
5
+
6
+ def self.fire_worker(event)
7
+ :method_called
8
+ end
9
+ end
10
+
11
+ class FailingEventWorker < Reactor::Workers::EventWorker
12
+ end
13
+
14
+ class MyEventWorker < Reactor::Workers::EventWorker
15
+ self.source = SourceSubscriber
16
+ self.action = :fire_worker
17
+ self.async = true
18
+ self.delay = 0
19
+ end
20
+
21
+ class MyBlockWorker < Reactor::Workers::EventWorker
22
+ self.source = SourceSubscriber
23
+ self.action = lambda { |event| :block_ran }
24
+ self.async = true
25
+ self.delay = 0
26
+ end
27
+
28
+ class MyDelayedWorker < Reactor::Workers::EventWorker
29
+ self.source = SourceSubscriber
30
+ self.action = :fire_worker
31
+ self.async = true
32
+ self.delay = 1 # seconds
33
+ end
34
+
35
+ class MyImmediateWorker < Reactor::Workers::EventWorker
36
+ self.source = SourceSubscriber
37
+ self.action = :fire_worker
38
+ self.async = false
39
+ self.delay = 0
40
+ end
41
+
42
+ describe Reactor::Workers::EventWorker do
43
+ let(:event_name) { :fire_worker }
44
+ let(:event_data) { Hash[my_event_data: true] }
45
+
46
+ describe '.configured?' do
47
+ context 'for unconfigured class' do
48
+ subject { FailingEventWorker.configured? }
49
+
50
+ it { is_expected.to eq(false) }
51
+ end
52
+
53
+ context 'for configured class' do
54
+ subject { MyEventWorker.configured? }
55
+
56
+ it { is_expected.to eq(true) }
57
+ end
58
+ end
59
+
60
+ describe '.perform_where_needed?' do
61
+ context 'for delayed worker' do
62
+ let(:klass) { MyDelayedWorker }
63
+ subject { klass.perform_where_needed(event_data) }
64
+
65
+ it 'uses perform_in to delay execution' do
66
+ expect(klass).to receive(:perform_in).with(1, event_data)
67
+ subject
68
+ end
69
+ end
70
+
71
+ context 'for async workers' do
72
+ let(:klass) { MyEventWorker }
73
+ subject { klass.perform_where_needed(event_data) }
74
+
75
+ it 'uses perform_async to execute wherever' do
76
+ expect(klass).to receive(:perform_async).with(event_data)
77
+ subject
78
+ end
79
+ end
80
+
81
+ context 'for immediate workers' do
82
+ let(:klass) { MyImmediateWorker }
83
+ subject { klass.perform_where_needed(event_data) }
84
+
85
+ it 'creates and executes new instance' do
86
+ expect_any_instance_of(klass).to receive(:perform).with(event_data)
87
+ subject
88
+ end
89
+ end
90
+ end
91
+
92
+ describe '#perform' do
93
+ let(:klass) { MyEventWorker }
94
+ subject { klass.new.perform(event_data) }
95
+
96
+ context 'for unconfigured worker' do
97
+ let(:klass) { FailingEventWorker }
98
+
99
+ it 'raises an error' do
100
+ expect { subject }.to raise_error(Reactor::UnconfiguredWorkerError)
101
+ end
102
+ end
103
+
104
+ context 'when should_perform? is false' do
105
+ let(:klass) { MyEventWorker }
106
+
107
+ it 'returns :__perform_aborted__' do
108
+ expect(subject).to eq(:__perform_aborted__)
109
+ end
110
+ end
111
+
112
+ context 'when should_perform? is true' do
113
+ before { allow_any_instance_of(klass).to receive(:should_perform?).and_return(true) }
114
+
115
+ it 'calls class method by symbol' do
116
+ expect(subject).to eq(:method_called)
117
+ end
118
+
119
+ context 'for block workers' do
120
+ let(:klass) { MyBlockWorker }
121
+ it { is_expected.to eq(:block_ran) }
122
+ end
123
+ end
124
+ end
125
+
126
+ end
@@ -0,0 +1,49 @@
1
+ require 'spec_helper'
2
+
3
+ class MailerSubscriber < ActionMailer::Base
4
+ include Reactor::Subscribable
5
+
6
+ def fire_mailer(event)
7
+ mail subject: 'Here is a mailer',
8
+ to: 'reactor@hired.com',
9
+ from: 'test+reactor@hired.com',
10
+ body: 'an example email body'
11
+ end
12
+ end
13
+
14
+ class MyMailerWorker < Reactor::Workers::MailerWorker
15
+ self.source = MailerSubscriber
16
+ self.action = :fire_mailer
17
+ self.async = false
18
+ self.delay = 0
19
+ end
20
+
21
+ class MyBlockMailerWorker < Reactor::Workers::MailerWorker
22
+ self.source = MailerSubscriber
23
+ self.async = false
24
+ self.delay = 0
25
+ self.action = lambda { |event| fire_mailer(event) }
26
+ end
27
+
28
+ describe Reactor::Workers::MailerWorker do
29
+ let(:klass) { MyMailerWorker }
30
+ let(:event_data) { Hash[some_example: :event_data] }
31
+ subject { klass.new.perform(event_data) }
32
+
33
+ before do
34
+ allow_any_instance_of(klass).to receive(:should_perform?).and_return(true)
35
+ end
36
+
37
+ it 'sends an email from symbol method name' do
38
+ expect { subject }.to change { ActionMailer::Base.deliveries.count }.by(1)
39
+ end
40
+
41
+ context 'for a block subscription' do
42
+ let(:klass) { MyBlockMailerWorker }
43
+
44
+ it 'sends an email from the block' do
45
+ expect { subject }.to change { ActionMailer::Base.deliveries.count }.by(1)
46
+ end
47
+ end
48
+
49
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: reactor
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.13.0
4
+ version: 0.14.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - winfred
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2017-04-11 00:00:00.000000000 Z
14
+ date: 2017-06-21 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: sidekiq
@@ -28,19 +28,19 @@ dependencies:
28
28
  - !ruby/object:Gem::Version
29
29
  version: '0'
30
30
  - !ruby/object:Gem::Dependency
31
- name: activerecord
31
+ name: rails
32
32
  requirement: !ruby/object:Gem::Requirement
33
33
  requirements:
34
34
  - - "~>"
35
35
  - !ruby/object:Gem::Version
36
- version: 5.0.1
36
+ version: 5.0.2
37
37
  type: :runtime
38
38
  prerelease: false
39
39
  version_requirements: !ruby/object:Gem::Requirement
40
40
  requirements:
41
41
  - - "~>"
42
42
  - !ruby/object:Gem::Version
43
- version: 5.0.1
43
+ version: 5.0.2
44
44
  - !ruby/object:Gem::Dependency
45
45
  name: bundler
46
46
  requirement: !ruby/object:Gem::Requirement
@@ -153,6 +153,20 @@ dependencies:
153
153
  - - ">="
154
154
  - !ruby/object:Gem::Version
155
155
  version: '0'
156
+ - !ruby/object:Gem::Dependency
157
+ name: simplecov
158
+ requirement: !ruby/object:Gem::Requirement
159
+ requirements:
160
+ - - ">="
161
+ - !ruby/object:Gem::Version
162
+ version: '0'
163
+ type: :development
164
+ prerelease: false
165
+ version_requirements: !ruby/object:Gem::Requirement
166
+ requirements:
167
+ - - ">="
168
+ - !ruby/object:Gem::Version
169
+ version: '0'
156
170
  description: " rails chrono reactor "
157
171
  email:
158
172
  - winfred@hired.com
@@ -174,6 +188,7 @@ files:
174
188
  - README.md
175
189
  - Rakefile
176
190
  - lib/reactor.rb
191
+ - lib/reactor/controllers.rb
177
192
  - lib/reactor/controllers/concerns/actions/action_event.rb
178
193
  - lib/reactor/controllers/concerns/actions/create_event.rb
179
194
  - lib/reactor/controllers/concerns/actions/destroy_event.rb
@@ -183,13 +198,22 @@ files:
183
198
  - lib/reactor/controllers/concerns/actions/show_event.rb
184
199
  - lib/reactor/controllers/concerns/actions/update_event.rb
185
200
  - lib/reactor/controllers/concerns/resource_actionable.rb
201
+ - lib/reactor/errors.rb
186
202
  - lib/reactor/event.rb
203
+ - lib/reactor/models.rb
187
204
  - lib/reactor/models/concerns/optionally_subclassable.rb
188
205
  - lib/reactor/models/concerns/publishable.rb
189
206
  - lib/reactor/models/concerns/subscribable.rb
190
207
  - lib/reactor/models/subscriber.rb
208
+ - lib/reactor/static_subscribers.rb
209
+ - lib/reactor/subscription.rb
210
+ - lib/reactor/testing.rb
191
211
  - lib/reactor/testing/matchers.rb
192
212
  - lib/reactor/version.rb
213
+ - lib/reactor/workers.rb
214
+ - lib/reactor/workers/database_subscriber_worker.rb
215
+ - lib/reactor/workers/event_worker.rb
216
+ - lib/reactor/workers/mailer_worker.rb
193
217
  - reactor.gemspec
194
218
  - spec/controllers/concerns/resource_actionable_spec.rb
195
219
  - spec/event_spec.rb
@@ -198,7 +222,11 @@ files:
198
222
  - spec/models/subscriber_spec.rb
199
223
  - spec/reactor_spec.rb
200
224
  - spec/spec_helper.rb
225
+ - spec/subscription_spec.rb
201
226
  - spec/support/active_record.rb
227
+ - spec/workers/database_subscriber_worker_spec.rb
228
+ - spec/workers/event_worker_spec.rb
229
+ - spec/workers/mailer_worker_spec.rb
202
230
  homepage: ''
203
231
  licenses:
204
232
  - MIT
@@ -231,4 +259,8 @@ test_files:
231
259
  - spec/models/subscriber_spec.rb
232
260
  - spec/reactor_spec.rb
233
261
  - spec/spec_helper.rb
262
+ - spec/subscription_spec.rb
234
263
  - spec/support/active_record.rb
264
+ - spec/workers/database_subscriber_worker_spec.rb
265
+ - spec/workers/event_worker_spec.rb
266
+ - spec/workers/mailer_worker_spec.rb