bunny-mock 1.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 +7 -0
- data/.gitignore +23 -0
- data/.rspec +3 -0
- data/.travis.yml +10 -0
- data/.yardopts +7 -0
- data/Gemfile +15 -0
- data/LICENSE +20 -0
- data/README.md +151 -0
- data/bunny-mock.gemspec +27 -0
- data/lib/bunny-mock.rb +48 -0
- data/lib/bunny_mock/channel.rb +310 -0
- data/lib/bunny_mock/exchange.rb +266 -0
- data/lib/bunny_mock/exchanges/direct.rb +24 -0
- data/lib/bunny_mock/exchanges/fanout.rb +28 -0
- data/lib/bunny_mock/exchanges/headers.rb +33 -0
- data/lib/bunny_mock/exchanges/topic.rb +51 -0
- data/lib/bunny_mock/queue.rb +208 -0
- data/lib/bunny_mock/session.rb +85 -0
- data/lib/bunny_mock/version.rb +7 -0
- data/spec/spec_helper.rb +17 -0
- data/spec/unit/bunny_mock/channel_spec.rb +175 -0
- data/spec/unit/bunny_mock/exchange_spec.rb +145 -0
- data/spec/unit/bunny_mock/exchanges/direct_spec.rb +28 -0
- data/spec/unit/bunny_mock/exchanges/fanout_spec.rb +31 -0
- data/spec/unit/bunny_mock/exchanges/topic_spec.rb +70 -0
- data/spec/unit/bunny_mock/queue_spec.rb +145 -0
- data/spec/unit/bunny_mock/session_spec.rb +79 -0
- data/spec/unit/bunny_mock_spec.rb +28 -0
- metadata +97 -0
@@ -0,0 +1,85 @@
|
|
1
|
+
module BunnyMock
|
2
|
+
# Mocks Bunny::Session
|
3
|
+
class Session
|
4
|
+
|
5
|
+
#
|
6
|
+
# API
|
7
|
+
#
|
8
|
+
|
9
|
+
# @return [Symbol] Current session status
|
10
|
+
attr_reader :status
|
11
|
+
|
12
|
+
##
|
13
|
+
# Creates a new {BunnyMock::Session} instance
|
14
|
+
#
|
15
|
+
# @api public
|
16
|
+
def initialize(*args)
|
17
|
+
|
18
|
+
# not connected until {BunnyMock::Session#start} is called
|
19
|
+
@status = :not_connected
|
20
|
+
|
21
|
+
# create channel hash
|
22
|
+
@channels = Hash.new
|
23
|
+
end
|
24
|
+
|
25
|
+
##
|
26
|
+
# Sets status to connected
|
27
|
+
#
|
28
|
+
# @return [BunnyMock::Session] self
|
29
|
+
# @api public
|
30
|
+
def start
|
31
|
+
|
32
|
+
@status = :connected
|
33
|
+
|
34
|
+
self
|
35
|
+
end
|
36
|
+
|
37
|
+
##
|
38
|
+
# Sets status to closed
|
39
|
+
#
|
40
|
+
# @return [BunnyMock::Session] self
|
41
|
+
# @api public
|
42
|
+
def stop
|
43
|
+
|
44
|
+
@status = :closed
|
45
|
+
|
46
|
+
self
|
47
|
+
end
|
48
|
+
alias close stop
|
49
|
+
|
50
|
+
##
|
51
|
+
# Tests if connection is available
|
52
|
+
#
|
53
|
+
# @return [Boolean] true if status is connected, false otherwise
|
54
|
+
# @api public
|
55
|
+
def open?
|
56
|
+
|
57
|
+
@status == :connected
|
58
|
+
end
|
59
|
+
|
60
|
+
##
|
61
|
+
# Creates a new {BunnyMock::Channel} instance
|
62
|
+
#
|
63
|
+
# @param [Integer] n Channel identifier
|
64
|
+
# @param [Integer] pool_size Work pool size (insignificant)
|
65
|
+
#
|
66
|
+
# @return [BunnyMock::Channel] Channel instance
|
67
|
+
# @api public
|
68
|
+
def create_channel(n = nil, pool_size = 1)
|
69
|
+
|
70
|
+
# raise same error as {Bunny::Session#create_channel}
|
71
|
+
raise ArgumentError, "channel number 0 is reserved in the protocol and cannot be used" if n == 0
|
72
|
+
|
73
|
+
# return cached channel if exists
|
74
|
+
return @channels[n] if n and @channels.key?(n)
|
75
|
+
|
76
|
+
# create and open channel
|
77
|
+
channel = Channel.new self, n
|
78
|
+
channel.open
|
79
|
+
|
80
|
+
# return channel
|
81
|
+
@channels[n] = channel
|
82
|
+
end
|
83
|
+
alias channel create_channel
|
84
|
+
end
|
85
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'rspec'
|
2
|
+
|
3
|
+
$LOAD_PATH.unshift File.expand_path('../lib', __FILE__)
|
4
|
+
|
5
|
+
require 'bundler'
|
6
|
+
Bundler.setup :default, :test
|
7
|
+
Bundler.require
|
8
|
+
|
9
|
+
require 'bunny-mock'
|
10
|
+
|
11
|
+
RSpec.configure do |config|
|
12
|
+
|
13
|
+
config.before :each do
|
14
|
+
@session = BunnyMock::Session.new
|
15
|
+
@channel = @session.channel
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,175 @@
|
|
1
|
+
describe BunnyMock::Channel do
|
2
|
+
|
3
|
+
context '::new' do
|
4
|
+
|
5
|
+
before do
|
6
|
+
@channel = BunnyMock::Channel.new @session, 1
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'should store connection' do
|
10
|
+
|
11
|
+
expect(@channel.connection).to eq(@session)
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'should store channel identifier' do
|
15
|
+
|
16
|
+
expect(@channel.id).to eq(1)
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'should set status to opening' do
|
20
|
+
|
21
|
+
expect(@channel.status).to eq(:opening)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
context '#open' do
|
26
|
+
|
27
|
+
it 'should set status to open' do
|
28
|
+
|
29
|
+
expect(@channel.open.status).to eq(:open)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
context '#close' do
|
34
|
+
|
35
|
+
it 'should set status to open' do
|
36
|
+
|
37
|
+
@channel.open
|
38
|
+
|
39
|
+
expect(@channel.close.status).to eq(:closed)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
context '#open?' do
|
44
|
+
|
45
|
+
it 'should return true if status is open' do
|
46
|
+
|
47
|
+
expect(@channel.open?).to be_truthy
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'should return false otherwise' do
|
51
|
+
|
52
|
+
# opening
|
53
|
+
expect(BunnyMock::Channel.new.open?).to be_falsey
|
54
|
+
|
55
|
+
# closed
|
56
|
+
expect(@channel.close.open?).to be_falsey
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
context '#closed?' do
|
61
|
+
|
62
|
+
it 'should return true if status is closed' do
|
63
|
+
|
64
|
+
expect(@channel.close.closed?).to be_truthy
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'should return false otherwise' do
|
68
|
+
|
69
|
+
# opening
|
70
|
+
expect(BunnyMock::Channel.new.closed?).to be_falsey
|
71
|
+
|
72
|
+
# open
|
73
|
+
expect(@channel.closed?).to be_falsey
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
context '#exchange' do
|
78
|
+
|
79
|
+
it 'should declare a new exchange' do
|
80
|
+
|
81
|
+
xchg = @channel.exchange 'testing.xchg', type: :fanout
|
82
|
+
|
83
|
+
expect(xchg.class).to eq(BunnyMock::Exchanges::Fanout)
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'should return a cached exchange with the same name' do
|
87
|
+
|
88
|
+
xchg = @channel.exchange 'testing.xchg', type: :fanout
|
89
|
+
|
90
|
+
expect(@channel.exchange('testing.xchg', type: :fanout)).to eq(xchg)
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'should register the exchange in cache' do
|
94
|
+
|
95
|
+
xchg = @channel.exchange 'testing.xchg', type: :fanout
|
96
|
+
|
97
|
+
expect(@channel.exchanges['testing.xchg']).to eq(xchg)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
context '#direct' do
|
102
|
+
|
103
|
+
it 'should declare a new direct exchange' do
|
104
|
+
|
105
|
+
expect(@channel.direct('testing.xchg').class).to eq(BunnyMock::Exchanges::Direct)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
context '#topic' do
|
110
|
+
|
111
|
+
it 'should declare a new topic exchange' do
|
112
|
+
|
113
|
+
expect(@channel.topic('testing.xchg').class).to eq(BunnyMock::Exchanges::Topic)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
context '#fanout' do
|
118
|
+
|
119
|
+
it 'should declare a new fanout exchange' do
|
120
|
+
|
121
|
+
expect(@channel.fanout('testing.xchg').class).to eq(BunnyMock::Exchanges::Fanout)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
context '#header' do
|
126
|
+
|
127
|
+
it 'should declare a new headers exchange' do
|
128
|
+
|
129
|
+
expect(@channel.header('testing.xchg').class).to eq(BunnyMock::Exchanges::Header)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
context '#default_exchange' do
|
134
|
+
|
135
|
+
it 'should return a nameless direct exchange' do
|
136
|
+
|
137
|
+
xchg = @channel.default_exchange
|
138
|
+
|
139
|
+
expect(xchg.class).to eq(BunnyMock::Exchanges::Direct)
|
140
|
+
expect(xchg.name).to eq('')
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
context '#queue' do
|
145
|
+
|
146
|
+
it 'should declare a new queue' do
|
147
|
+
|
148
|
+
q = @channel.queue 'testing.q'
|
149
|
+
|
150
|
+
expect(q.class).to eq(BunnyMock::Queue)
|
151
|
+
end
|
152
|
+
|
153
|
+
it 'should return a cached queue with the same name' do
|
154
|
+
|
155
|
+
q = @channel.queue 'testing.q'
|
156
|
+
|
157
|
+
expect(@channel.queue('testing.q')).to eq(q)
|
158
|
+
end
|
159
|
+
|
160
|
+
it 'should register the queue in cache' do
|
161
|
+
|
162
|
+
q = @channel.queue 'testing.q'
|
163
|
+
|
164
|
+
expect(@channel.queues['testing.q']).to eq(q)
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
context '#temporary_queue' do
|
169
|
+
|
170
|
+
it 'should declare a nameless queue' do
|
171
|
+
|
172
|
+
expect(@channel.temporary_queue.class).to eq(BunnyMock::Queue)
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
@@ -0,0 +1,145 @@
|
|
1
|
+
describe BunnyMock::Exchange do
|
2
|
+
|
3
|
+
context '::declare' do
|
4
|
+
|
5
|
+
it 'should create a direct exchange' do
|
6
|
+
|
7
|
+
expect(BunnyMock::Exchange.declare(@channel, 'testing.xchg', type: :direct).class).to eq(BunnyMock::Exchanges::Direct)
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'should create a topic exchange' do
|
11
|
+
|
12
|
+
expect(BunnyMock::Exchange.declare(@channel, 'testing.xchg', type: :topic).class).to eq(BunnyMock::Exchanges::Topic)
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'should create a fanout exchange' do
|
16
|
+
|
17
|
+
expect(BunnyMock::Exchange.declare(@channel, 'testing.xchg', type: :fanout).class).to eq(BunnyMock::Exchanges::Fanout)
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'should create a header exchange' do
|
21
|
+
|
22
|
+
expect(BunnyMock::Exchange.declare(@channel, 'testing.xchg', type: :header).class).to eq(BunnyMock::Exchanges::Header)
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'should default to a direct exchange' do
|
26
|
+
|
27
|
+
expect(BunnyMock::Exchange.declare(@channel, 'testing.xchg').class).to eq(BunnyMock::Exchanges::Direct)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context '#bind' do
|
32
|
+
|
33
|
+
before do
|
34
|
+
@source = @channel.exchange 'xchg.source'
|
35
|
+
@receiver = @channel.exchange 'xchg.receiver'
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'should bind by exchange instance' do
|
39
|
+
|
40
|
+
@receiver.bind @source
|
41
|
+
|
42
|
+
expect(@receiver.bound_to?(@source)).to be_truthy
|
43
|
+
expect(@source.has_binding?(@receiver)).to be_truthy
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'should bind by exchange name' do
|
47
|
+
|
48
|
+
@receiver.bind @source.name
|
49
|
+
|
50
|
+
expect(@receiver.bound_to?(@source)).to be_truthy
|
51
|
+
expect(@source.has_binding?(@receiver)).to be_truthy
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
context '#unbind' do
|
56
|
+
|
57
|
+
before do
|
58
|
+
@source = @channel.exchange 'xchg.source'
|
59
|
+
@receiver = @channel.exchange 'xchg.receiver'
|
60
|
+
|
61
|
+
@receiver.bind @source
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'should unbind by exchange instance' do
|
65
|
+
|
66
|
+
@receiver.unbind @source
|
67
|
+
|
68
|
+
expect(@receiver.bound_to?(@source)).to be_falsey
|
69
|
+
expect(@source.has_binding?(@receiver)).to be_falsey
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'should unbind by exchange name' do
|
73
|
+
|
74
|
+
@receiver.unbind @source.name
|
75
|
+
|
76
|
+
expect(@receiver.bound_to?(@source)).to be_falsey
|
77
|
+
expect(@source.has_binding?(@receiver)).to be_falsey
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
context '#bound_to?' do
|
82
|
+
|
83
|
+
before do
|
84
|
+
@source = @channel.exchange 'xchg.source'
|
85
|
+
@receiver = @channel.exchange 'xchg.receiver'
|
86
|
+
end
|
87
|
+
|
88
|
+
context 'should return true if bound' do
|
89
|
+
|
90
|
+
it 'by instance' do
|
91
|
+
|
92
|
+
@receiver.bind @source
|
93
|
+
|
94
|
+
expect(@receiver.bound_to?(@source)).to be_truthy
|
95
|
+
end
|
96
|
+
|
97
|
+
it 'by name' do
|
98
|
+
|
99
|
+
@receiver.bind @source
|
100
|
+
|
101
|
+
expect(@receiver.bound_to?(@source.name)).to be_truthy
|
102
|
+
end
|
103
|
+
|
104
|
+
it 'by routing key' do
|
105
|
+
|
106
|
+
@receiver.bind @source, routing_key: 'xchg.route'
|
107
|
+
|
108
|
+
expect(@receiver.bound_to?(@source)).to be_falsey
|
109
|
+
expect(@receiver.bound_to?(@source, routing_key: 'xchg.route')).to be_truthy
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
it 'return false otherwise' do
|
114
|
+
|
115
|
+
expect(@receiver.bound_to?(@source)).to be_falsey
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
context '#has_binding?' do
|
120
|
+
|
121
|
+
before do
|
122
|
+
@source = @channel.exchange 'xchg.source'
|
123
|
+
@receiver = @channel.exchange 'xchg.receiver'
|
124
|
+
|
125
|
+
@receiver.bind @source
|
126
|
+
end
|
127
|
+
|
128
|
+
it 'should unbind by exchange instance' do
|
129
|
+
|
130
|
+
@receiver.unbind @source
|
131
|
+
|
132
|
+
expect(@receiver.bound_to?(@source)).to be_falsey
|
133
|
+
expect(@source.has_binding?(@receiver)).to be_falsey
|
134
|
+
end
|
135
|
+
|
136
|
+
it 'should unbind by exchange name' do
|
137
|
+
|
138
|
+
@receiver.unbind @source.name
|
139
|
+
|
140
|
+
expect(@receiver.bound_to?(@source)).to be_falsey
|
141
|
+
expect(@source.has_binding?(@receiver)).to be_falsey
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
describe BunnyMock::Exchanges::Direct do
|
2
|
+
|
3
|
+
context '#deliver' do
|
4
|
+
|
5
|
+
before do
|
6
|
+
@source = @channel.direct 'xchg.source'
|
7
|
+
|
8
|
+
@first = @channel.queue 'queue.first'
|
9
|
+
@second = @channel.queue 'queue.second'
|
10
|
+
@third = @channel.queue 'queue.third'
|
11
|
+
|
12
|
+
@first.bind @source
|
13
|
+
@second.bind @source
|
14
|
+
@third.bind @source
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'should only deliver to direct route match' do
|
18
|
+
|
19
|
+
@source.publish 'Testing message', routing_key: 'queue.second'
|
20
|
+
|
21
|
+
expect(@first.message_count).to eq(0)
|
22
|
+
expect(@third.message_count).to eq(0)
|
23
|
+
|
24
|
+
expect(@second.message_count).to eq(1)
|
25
|
+
expect(@second.pop[:message]).to eq('Testing message')
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|