chasqui 0.9.3 → 1.0.0.pre.rc1
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/README.md +60 -39
- data/Vagrantfile +15 -0
- data/lib/chasqui.rb +28 -55
- data/lib/chasqui/broker.rb +3 -3
- data/lib/chasqui/{multi_broker.rb → brokers/redis_broker.rb} +11 -11
- data/lib/chasqui/config.rb +26 -6
- data/lib/chasqui/queue_adapter.rb +14 -0
- data/lib/chasqui/queue_adapters/redis_queue_adapter.rb +51 -0
- data/lib/chasqui/subscriber.rb +56 -49
- data/lib/chasqui/subscriptions.rb +67 -0
- data/lib/chasqui/version.rb +1 -1
- data/lib/chasqui/worker.rb +81 -0
- data/spec/integration/pubsub_examples.rb +20 -20
- data/spec/integration/resque_spec.rb +1 -1
- data/spec/integration/setup/subscribers.rb +25 -9
- data/spec/integration/sidekiq_spec.rb +1 -1
- data/spec/lib/chasqui/{multi_broker_spec.rb → brokers/redis_broker_spec.rb} +54 -26
- data/spec/lib/chasqui/cli_spec.rb +1 -1
- data/spec/lib/chasqui/config_spec.rb +121 -0
- data/spec/lib/chasqui/fake_queue_adapter_spec.rb +5 -0
- data/spec/lib/chasqui/queue_adapters/redis_queue_adapter_spec.rb +73 -0
- data/spec/lib/chasqui/subscriber_spec.rb +95 -43
- data/spec/lib/chasqui/subscriptions_spec.rb +60 -0
- data/spec/lib/chasqui/worker_spec.rb +96 -0
- data/spec/lib/chasqui_spec.rb +32 -191
- data/spec/spec_helper.rb +1 -1
- data/spec/support/chasqui_spec_helpers.rb +28 -0
- data/spec/support/fake_queue_adapter.rb +3 -0
- data/spec/support/fake_subscriber.rb +2 -1
- data/spec/support/shared_examples/queue_adapter_examples.rb +13 -0
- metadata +25 -18
- data/lib/chasqui/subscription.rb +0 -53
- data/lib/chasqui/workers/resque_worker.rb +0 -25
- data/lib/chasqui/workers/sidekiq_worker.rb +0 -45
- data/lib/chasqui/workers/worker.rb +0 -34
- data/spec/lib/chasqui/subscription_spec.rb +0 -35
- data/spec/lib/chasqui/workers/resque_worker_spec.rb +0 -27
- data/spec/lib/chasqui/workers/sidekiq_worker_spec.rb +0 -34
@@ -3,7 +3,7 @@ require 'integration/pubsub_examples'
|
|
3
3
|
|
4
4
|
if sidekiq_supported_ruby_version?
|
5
5
|
describe "sidekiq integration", integration: true do
|
6
|
-
include_examples 'pubsub', :
|
6
|
+
include_examples 'pubsub', :start_sidekiq_workers
|
7
7
|
|
8
8
|
def start_sidekiq_workers
|
9
9
|
@pids << fork do
|
@@ -1,7 +1,22 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
|
4
|
-
|
3
|
+
class Worker1
|
4
|
+
include Chasqui::Subscriber
|
5
|
+
subscribe channel: 'app1', queue: 'queue1'
|
6
|
+
end
|
7
|
+
|
8
|
+
class Worker2
|
9
|
+
include Chasqui::Subscriber
|
10
|
+
subscribe channel: 'app2', queue: 'queue2'
|
11
|
+
end
|
12
|
+
|
13
|
+
class Worker3
|
14
|
+
include Chasqui::Subscriber
|
15
|
+
subscribe channel: 'app1', queue: 'queue3'
|
16
|
+
end
|
17
|
+
|
18
|
+
describe Chasqui::RedisBroker do
|
19
|
+
let(:broker) { Chasqui::RedisBroker.new }
|
5
20
|
|
6
21
|
before do
|
7
22
|
reset_chasqui
|
@@ -12,14 +27,13 @@ describe Chasqui::MultiBroker do
|
|
12
27
|
|
13
28
|
describe '#forward_event' do
|
14
29
|
before do
|
15
|
-
Chasqui.
|
16
|
-
Chasqui.
|
17
|
-
Chasqui.
|
18
|
-
Chasqui.subscribe channel: 'app1', queue: 'queue3'
|
30
|
+
Chasqui.register Worker1
|
31
|
+
Chasqui.register Worker2
|
32
|
+
Chasqui.register Worker3
|
19
33
|
end
|
20
34
|
|
21
35
|
it 'places the event on all subscriber queues' do
|
22
|
-
Chasqui.publish '
|
36
|
+
Chasqui.publish 'app1', foo: 'bar'
|
23
37
|
broker.forward_event
|
24
38
|
|
25
39
|
expect(nnredis.llen(broker.inbox_queue)).to eq(0)
|
@@ -28,7 +42,12 @@ describe Chasqui::MultiBroker do
|
|
28
42
|
expect(nnredis.llen('queue:queue2')).to eq(0)
|
29
43
|
expect(nnredis.llen('queue:queue3')).to eq(1)
|
30
44
|
|
31
|
-
event = {
|
45
|
+
event = {
|
46
|
+
'channel' => 'app1',
|
47
|
+
'payload' => [{ 'foo' => 'bar' }],
|
48
|
+
'created_at' => Time.now.to_f.to_s,
|
49
|
+
'retry' => true
|
50
|
+
}
|
32
51
|
|
33
52
|
job1 = JSON.parse nnredis.lpop('queue:queue1')
|
34
53
|
expect(job1['args']).to include(event)
|
@@ -43,13 +62,19 @@ describe Chasqui::MultiBroker do
|
|
43
62
|
begin
|
44
63
|
Timeout::timeout(1) do
|
45
64
|
Chasqui.config.redis = Redis.new
|
46
|
-
Chasqui.
|
47
|
-
Chasqui.publish 'foo.bar', 'A'
|
65
|
+
Chasqui.publish 'app2', foo: 'bar'
|
48
66
|
|
49
67
|
job = JSON.parse nnredis.blpop('queue:queue2')[1]
|
50
|
-
expect(job).to include('class' => 'Chasqui::
|
51
|
-
|
52
|
-
|
68
|
+
expect(job).to include('class' => 'Chasqui::Workers::Worker2')
|
69
|
+
|
70
|
+
event = {
|
71
|
+
'channel' => 'app2',
|
72
|
+
'payload' => [{ 'foo' => 'bar' }],
|
73
|
+
'created_at' => Time.now.to_f.to_s,
|
74
|
+
'retry' => true
|
75
|
+
}
|
76
|
+
|
77
|
+
expect(job).to include('args' => [event])
|
53
78
|
end
|
54
79
|
ensure
|
55
80
|
thread.kill
|
@@ -57,9 +82,8 @@ describe Chasqui::MultiBroker do
|
|
57
82
|
end
|
58
83
|
|
59
84
|
it "doesn't lose events if the broker fails" do
|
60
|
-
Chasqui.
|
61
|
-
Chasqui.publish '
|
62
|
-
Chasqui.publish 'foo', 'keep in queue'
|
85
|
+
Chasqui.publish 'app2', 'process'
|
86
|
+
Chasqui.publish 'app2', 'keep in queue'
|
63
87
|
allow(broker.redis).to receive(:smembers).and_raise(Redis::ConnectionError)
|
64
88
|
|
65
89
|
expect(-> { broker.forward_event }).to raise_error(Redis::ConnectionError)
|
@@ -72,7 +96,11 @@ describe Chasqui::MultiBroker do
|
|
72
96
|
|
73
97
|
job = JSON.parse nnredis.lpop('queue:queue2')
|
74
98
|
expect(job['args']).to include(
|
75
|
-
'
|
99
|
+
'channel' => 'app2',
|
100
|
+
'payload' => ['process'],
|
101
|
+
'created_at' => Time.now.to_f.to_s,
|
102
|
+
'retry' => true
|
103
|
+
)
|
76
104
|
expect(nnredis.llen(broker.in_progress_queue)).to eq(0)
|
77
105
|
end
|
78
106
|
|
@@ -84,33 +112,33 @@ describe Chasqui::MultiBroker do
|
|
84
112
|
|
85
113
|
describe '#build_job' do
|
86
114
|
it 'includes useful metadata' do
|
87
|
-
event = { '
|
88
|
-
job = JSON.parse broker.build_job('my-queue', event)
|
115
|
+
event = { 'channel' => 'fox4', 'payload' => [] }
|
116
|
+
job = JSON.parse broker.build_job('my-queue', 'MyWorker', event)
|
89
117
|
|
90
|
-
expect(job['class']).to eq('
|
118
|
+
expect(job['class']).to eq('MyWorker')
|
91
119
|
expect(job['args']).to include(event)
|
92
120
|
expect(job['queue']).to eq('my-queue')
|
93
121
|
expect(job['jid']).to match(/^[0-9a-f]{24}/i)
|
94
122
|
expect(job['created_at']).to be_within(0.01).of(Time.now.to_f)
|
95
123
|
expect(job['enqueued_at']).to be_within(0.01).of(Time.now.to_f)
|
96
|
-
expect(job['retry']).to
|
124
|
+
expect(job['retry']).to be nil
|
97
125
|
end
|
98
126
|
|
99
127
|
it 'uses the event created_at time' do
|
100
128
|
created_at = (Time.now - 3).to_f
|
101
|
-
job = JSON.parse broker.build_job('my-queue', 'created_at' => created_at.to_s)
|
129
|
+
job = JSON.parse broker.build_job('my-queue', 'MyWorker', 'created_at' => created_at.to_s)
|
102
130
|
expect(job['created_at']).to eq(created_at)
|
103
131
|
end
|
104
132
|
|
105
133
|
it 'uses the event retry value' do
|
106
|
-
job = JSON.parse broker.build_job('my-queue', 'retry' => true)
|
134
|
+
job = JSON.parse broker.build_job('my-queue', 'MyWorker', 'retry' => true)
|
107
135
|
expect(job['retry']).to be true
|
108
136
|
|
109
|
-
job = JSON.parse broker.build_job('my-queue', 'retry' => false)
|
137
|
+
job = JSON.parse broker.build_job('my-queue', 'MyWorker', 'retry' => false)
|
110
138
|
expect(job['retry']).to be false
|
111
139
|
|
112
|
-
job = JSON.parse broker.build_job('my-queue', 'retry' => nil)
|
113
|
-
expect(job['retry']).to be
|
140
|
+
job = JSON.parse broker.build_job('my-queue', 'MyWorker', 'retry' => nil)
|
141
|
+
expect(job['retry']).to be nil
|
114
142
|
end
|
115
143
|
end
|
116
144
|
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Chasqui::Config do
|
4
|
+
|
5
|
+
context 'defaults' do
|
6
|
+
it { expect(subject.channel_prefix).to be nil }
|
7
|
+
it { expect(subject.default_queue).to eq('chasqui-subscribers') }
|
8
|
+
it { expect(subject.inbox_queue).to eq('inbox') }
|
9
|
+
it { expect(subject.redis.client.db).to eq(0) }
|
10
|
+
it { expect(subject.broker_poll_interval).to eq(3) }
|
11
|
+
it { expect(subject.queue_adapter).to eq(Chasqui::QueueAdapters::RedisQueueAdapter) }
|
12
|
+
|
13
|
+
it do
|
14
|
+
# remove chasqui's test environment logger
|
15
|
+
subject[:logger] = nil
|
16
|
+
expect(subject.logger).to be_kind_of(Logger)
|
17
|
+
end
|
18
|
+
|
19
|
+
it { expect(subject.logger.level).to eq(Logger::INFO) }
|
20
|
+
it { expect(subject.logger.progname).to eq('chasqui') }
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'configures the channel prefix' do
|
24
|
+
subject.channel_prefix = 'com.example.test'
|
25
|
+
expect(subject.channel_prefix).to eq('com.example.test')
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'configures the default queue' do
|
29
|
+
subject.default_queue = 'my-app'
|
30
|
+
expect(subject.default_queue).to eq('my-app')
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'configures the inbox queue' do
|
34
|
+
subject.inbox_queue = 'foo'
|
35
|
+
expect(subject.inbox_queue).to eq('foo')
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'configures the broker poll interval' do
|
39
|
+
subject.broker_poll_interval = 1
|
40
|
+
expect(subject.broker_poll_interval).to eq(1)
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'configures the queue adapter' do
|
44
|
+
subject.queue_adapter = FakeQueueAdapter
|
45
|
+
expect(subject.queue_adapter).to eq(FakeQueueAdapter)
|
46
|
+
end
|
47
|
+
|
48
|
+
context 'redis' do
|
49
|
+
it 'accepts config options' do
|
50
|
+
redis_config = { host: '10.0.3.24' }
|
51
|
+
subject.redis = redis_config
|
52
|
+
expect(subject.redis.client.host).to eq('10.0.3.24')
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'accepts an initialized client' do
|
56
|
+
redis = Redis.new db: 2
|
57
|
+
subject.redis = redis
|
58
|
+
expect(subject.redis.client.db).to eq(2)
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'accepts URLs' do
|
62
|
+
subject.redis = 'redis://10.0.1.21:12345/0'
|
63
|
+
expect(subject.redis.client.host).to eq('10.0.1.21')
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'uses a namespace' do
|
67
|
+
subject.redis.set 'foo', 'bar'
|
68
|
+
expect(subject.redis.redis.get 'chasqui:foo').to eq('bar')
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
describe 'logger' do
|
73
|
+
it 'accepts a log device' do
|
74
|
+
logs = StringIO.new
|
75
|
+
subject.logger = logs
|
76
|
+
subject.logger.info "status"
|
77
|
+
subject.logger.warn "error"
|
78
|
+
|
79
|
+
logs.rewind
|
80
|
+
output = logs.read
|
81
|
+
|
82
|
+
%w(chasqui INFO status WARN error).each do |text|
|
83
|
+
expect(output).to match(text)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'accepts a logger-like object' do
|
88
|
+
fake_logger = FakeLogger.new
|
89
|
+
subject.logger = fake_logger
|
90
|
+
expect(subject.logger).to eq(fake_logger)
|
91
|
+
expect(subject.logger.progname).to eq('chasqui')
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
context 'worker_backend' do
|
96
|
+
it 'chooses resque' do
|
97
|
+
allow(Object).to receive(:const_defined?).with(:Resque).and_return true
|
98
|
+
allow(Object).to receive(:const_defined?).with(:Sidekiq).and_return false
|
99
|
+
expect(subject.worker_backend).to eq(:resque)
|
100
|
+
end
|
101
|
+
|
102
|
+
it 'chooses sidekiq' do
|
103
|
+
allow(Object).to receive(:const_defined?).with(:Resque).and_return true
|
104
|
+
allow(Object).to receive(:const_defined?).with(:Sidekiq).and_return true
|
105
|
+
expect(subject.worker_backend).to eq(:sidekiq)
|
106
|
+
end
|
107
|
+
|
108
|
+
it 'refuses to guess' do
|
109
|
+
allow(Object).to receive(:const_defined?).with(:Resque).and_return false
|
110
|
+
allow(Object).to receive(:const_defined?).with(:Sidekiq).and_return false
|
111
|
+
expect(subject.worker_backend).to be nil
|
112
|
+
end
|
113
|
+
|
114
|
+
it 'allows you to choose the worker backend' do
|
115
|
+
allow(Object).to receive(:const_defined?).with(:Resque).and_return true
|
116
|
+
allow(Object).to receive(:const_defined?).with(:Sidekiq).and_return true
|
117
|
+
subject.worker_backend = :resque
|
118
|
+
expect(subject.worker_backend).to eq(:resque)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
class MySubscriber
|
4
|
+
include Chasqui::Subscriber
|
5
|
+
subscribe channel: 'channel-name', queue: 'queue-name'
|
6
|
+
end
|
7
|
+
|
8
|
+
describe Chasqui::QueueAdapters::RedisQueueAdapter do
|
9
|
+
it_behaves_like 'a queue adapter'
|
10
|
+
|
11
|
+
let(:subscriber) { MySubscriber }
|
12
|
+
|
13
|
+
describe '#bind / #unbind' do
|
14
|
+
let(:key) { 'subscriptions:channel-name' }
|
15
|
+
|
16
|
+
before { reset_chasqui_workers }
|
17
|
+
after { reset_chasqui_workers }
|
18
|
+
|
19
|
+
context 'resque backend' do
|
20
|
+
before do
|
21
|
+
reset_chasqui
|
22
|
+
Chasqui.config.worker_backend = :resque
|
23
|
+
Resque.redis.namespace = :resque
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'persists the subscriptions to redis' do
|
27
|
+
subject.bind(subscriber)
|
28
|
+
subscriptions = redis.smembers(key)
|
29
|
+
expect(subscriptions).to eq(
|
30
|
+
['resque/Chasqui::Workers::MySubscriber/resque:queue:queue-name'])
|
31
|
+
|
32
|
+
expect(Chasqui::Workers.constants).to include(:MySubscriber)
|
33
|
+
worker = Chasqui::Workers.const_get :MySubscriber
|
34
|
+
expect(worker.subscriber).to eq(MySubscriber)
|
35
|
+
|
36
|
+
redis.sadd key, 'random'
|
37
|
+
|
38
|
+
subject.unbind(subscriber)
|
39
|
+
subscriptions = redis.smembers('subscriptions:channel-name')
|
40
|
+
expect(subscriptions).to eq(['random'])
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
if sidekiq_supported_ruby_version?
|
45
|
+
context 'sidekiq backend' do
|
46
|
+
before do
|
47
|
+
reset_chasqui
|
48
|
+
Chasqui.config.worker_backend = :sidekiq
|
49
|
+
Sidekiq.configure_client { |c| c.redis = { namespace: nil } }
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'persists the subscription to redis' do
|
53
|
+
subject.bind(subscriber)
|
54
|
+
subscriptions = redis.smembers('subscriptions:channel-name')
|
55
|
+
expect(subscriptions).to eq(
|
56
|
+
['sidekiq/Chasqui::Workers::MySubscriber/queue:queue-name'])
|
57
|
+
expect(redis_no_namespace.smembers 'queues').to eq(['queue-name'])
|
58
|
+
|
59
|
+
expect(Chasqui::Workers.constants).to include(:MySubscriber)
|
60
|
+
worker = Chasqui::Workers.const_get :MySubscriber
|
61
|
+
expect(worker.subscriber).to eq(MySubscriber)
|
62
|
+
|
63
|
+
redis.sadd key, 'random'
|
64
|
+
|
65
|
+
subject.unbind(subscriber)
|
66
|
+
subscriptions = redis.smembers('subscriptions:channel-name')
|
67
|
+
expect(subscriptions).to eq(['random'])
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
@@ -1,67 +1,119 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Chasqui::Subscriber do
|
4
|
-
let(:
|
4
|
+
let(:subscriber_class) { Class.new { include Chasqui::Subscriber } }
|
5
|
+
let(:redis) { Redis.new }
|
5
6
|
|
6
|
-
|
7
|
-
|
7
|
+
describe '#event' do
|
8
|
+
it { expect(subscriber_class.new(event: 'foo').event).to eq('foo') }
|
9
|
+
it { expect(-> { subscriber_class.new }).to raise_error(KeyError) }
|
10
|
+
end
|
8
11
|
|
9
|
-
describe '#
|
10
|
-
|
11
|
-
subscriber.on('foo') { |foo| foo }
|
12
|
-
subscriber.on('zig.zag') { |*args| args }
|
12
|
+
describe '#redis' do
|
13
|
+
let(:subscriber) { subscriber_class.new event: nil }
|
13
14
|
|
14
|
-
|
15
|
-
expect(subscriber.
|
15
|
+
context 'default' do
|
16
|
+
it { expect(subscriber.redis).to eq(Chasqui.redis) }
|
17
|
+
end
|
16
18
|
|
17
|
-
|
18
|
-
|
19
|
+
context 'custom' do
|
20
|
+
let(:redis) { Redis.new }
|
21
|
+
let(:subscriber) { subscriber_class.new event: nil, redis: redis }
|
22
|
+
it { expect(subscriber.redis.object_id).to eq(redis.object_id) }
|
19
23
|
end
|
24
|
+
end
|
20
25
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
+
describe '#logger' do
|
27
|
+
let(:subscriber) { subscriber_class.new event: nil }
|
28
|
+
|
29
|
+
context 'default' do
|
30
|
+
it { expect(subscriber.logger).to eq(Chasqui.logger) }
|
31
|
+
end
|
32
|
+
|
33
|
+
context 'custom' do
|
34
|
+
let(:logger) { FakeLogger.new }
|
35
|
+
let(:subscriber) { subscriber_class.new event: nil, logger: logger }
|
36
|
+
it { expect(subscriber.logger).to eq(logger) }
|
26
37
|
end
|
27
38
|
end
|
28
39
|
|
29
|
-
describe '
|
30
|
-
|
31
|
-
expect(
|
40
|
+
describe '.channels' do
|
41
|
+
before do
|
42
|
+
expect(Chasqui).to receive(:register).with(subscriber_class).at_least(:once)
|
43
|
+
subscriber_class.subscribe channel: 'some.channel'
|
32
44
|
end
|
33
45
|
|
34
|
-
|
35
|
-
|
36
|
-
subscriber.on('foo', &p)
|
37
|
-
expect(subscriber.matching_handler_patterns_for('foo')).to eq([/\Afoo\z/])
|
46
|
+
context 'default' do
|
47
|
+
it { expect(subscriber_class.channels).to include('some.channel') }
|
38
48
|
end
|
39
49
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
50
|
+
context 'with default prefix' do
|
51
|
+
before do
|
52
|
+
Chasqui.config.channel_prefix = 'prefix'
|
53
|
+
subscriber_class.subscribe channel: 'some.channel'
|
54
|
+
end
|
55
|
+
|
56
|
+
it { expect(subscriber_class.channels).to include('prefix.some.channel') }
|
57
|
+
end
|
58
|
+
|
59
|
+
context 'with custom prefix' do
|
60
|
+
before { Chasqui.config.channel_prefix = 'prefix' }
|
61
|
+
|
62
|
+
it 'uses the custom prefix' do
|
63
|
+
subscriber_class.subscribe channel: 'another.channel', prefix: 'custom'
|
64
|
+
expect(subscriber_class.channels).to include('custom.another.channel')
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'removes the prefix' do
|
68
|
+
subscriber_class.subscribe channel: 'another.channel', prefix: nil
|
69
|
+
expect(subscriber_class.channels).to include('another.channel')
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
context 'multiple channels' do
|
74
|
+
before { subscriber_class.subscribe channel: ['foo', 'bar'], prefix: 'custom' }
|
75
|
+
|
76
|
+
it 'subscribes to multiple channels' do
|
77
|
+
expect(subscriber_class.channels).to eq(['custom.foo', 'custom.bar'])
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
describe '.queue' do
|
83
|
+
context 'default' do
|
84
|
+
it { expect(subscriber_class.queue).to eq(Chasqui.default_queue) }
|
85
|
+
end
|
86
|
+
|
87
|
+
context 'custom' do
|
88
|
+
before do
|
89
|
+
expect(Chasqui).to receive(:register).with(subscriber_class)
|
90
|
+
subscriber_class.subscribe queue: 'custom-queue'
|
91
|
+
end
|
92
|
+
|
93
|
+
it { expect(subscriber_class.queue).to eq('custom-queue') }
|
54
94
|
end
|
55
95
|
end
|
56
96
|
|
57
97
|
describe '#perform' do
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
98
|
+
let(:subscriber) { subscriber_class.new event: nil }
|
99
|
+
|
100
|
+
it 'is not implemented' do
|
101
|
+
expect(-> {
|
102
|
+
subscriber.perform foo: 'bar'
|
103
|
+
}).to raise_error(NotImplementedError)
|
64
104
|
end
|
65
105
|
end
|
66
106
|
|
107
|
+
describe '.inherited' do
|
108
|
+
before { allow(Chasqui).to receive(:register) }
|
109
|
+
|
110
|
+
it 'maintains a registry of inherited classes' do
|
111
|
+
klass = Class.new do
|
112
|
+
include Chasqui::Subscriber
|
113
|
+
subscribe
|
114
|
+
end
|
115
|
+
|
116
|
+
expect(Chasqui::Subscriber.subscribers).to include(klass)
|
117
|
+
end
|
118
|
+
end
|
67
119
|
end
|