reactor 0.13.0 → 0.14.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +102 -17
- data/lib/reactor/controllers/concerns/actions/action_event.rb +11 -7
- data/lib/reactor/controllers/concerns/actions/create_event.rb +16 -12
- data/lib/reactor/controllers/concerns/actions/destroy_event.rb +8 -4
- data/lib/reactor/controllers/concerns/actions/edit_event.rb +8 -4
- data/lib/reactor/controllers/concerns/actions/index_event.rb +8 -4
- data/lib/reactor/controllers/concerns/actions/new_event.rb +8 -4
- data/lib/reactor/controllers/concerns/actions/show_event.rb +7 -3
- data/lib/reactor/controllers/concerns/actions/update_event.rb +16 -12
- data/lib/reactor/controllers/concerns/resource_actionable.rb +33 -31
- data/lib/reactor/controllers.rb +2 -0
- data/lib/reactor/errors.rb +7 -0
- data/lib/reactor/event.rb +2 -2
- data/lib/reactor/models/concerns/subscribable.rb +32 -79
- data/lib/reactor/models/subscriber.rb +21 -19
- data/lib/reactor/models.rb +5 -0
- data/lib/reactor/static_subscribers.rb +7 -0
- data/lib/reactor/subscription.rb +100 -0
- data/lib/reactor/testing.rb +50 -0
- data/lib/reactor/version.rb +1 -1
- data/lib/reactor/workers/database_subscriber_worker.rb +22 -0
- data/lib/reactor/workers/event_worker.rb +65 -0
- data/lib/reactor/workers/mailer_worker.rb +80 -0
- data/lib/reactor/workers.rb +8 -0
- data/lib/reactor.rb +24 -34
- data/reactor.gemspec +5 -1
- data/spec/event_spec.rb +10 -2
- data/spec/models/concerns/publishable_spec.rb +47 -38
- data/spec/models/concerns/subscribable_spec.rb +61 -5
- data/spec/models/subscriber_spec.rb +9 -2
- data/spec/reactor_spec.rb +2 -0
- data/spec/spec_helper.rb +19 -3
- data/spec/subscription_spec.rb +55 -0
- data/spec/support/active_record.rb +10 -0
- data/spec/workers/database_subscriber_worker_spec.rb +67 -0
- data/spec/workers/event_worker_spec.rb +126 -0
- data/spec/workers/mailer_worker_spec.rb +49 -0
- 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(
|
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.
|
109
|
-
|
110
|
-
|
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
|
27
|
-
|
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
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:
|
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:
|
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.
|
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-
|
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:
|
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.
|
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.
|
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
|