bunny-mock 1.1.0 → 1.2.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 +4 -4
- data/.editorconfig +12 -0
- data/.rubocop.yml +9 -0
- data/.rubocop_todo.yml +65 -0
- data/.travis.yml +6 -5
- data/.yardopts +1 -0
- data/CHANGELOG.md +14 -0
- data/Gemfile +1 -11
- data/README.md +61 -88
- data/Rakefile +29 -0
- data/UPGRADING.md +12 -0
- data/bunny-mock.gemspec +19 -16
- data/lib/bunny-mock.rb +30 -29
- data/lib/bunny_mock/channel.rb +275 -274
- data/lib/bunny_mock/exchange.rb +258 -267
- data/lib/bunny_mock/exchanges/direct.rb +20 -19
- data/lib/bunny_mock/exchanges/fanout.rb +20 -23
- data/lib/bunny_mock/exchanges/headers.rb +27 -26
- data/lib/bunny_mock/exchanges/topic.rb +45 -49
- data/lib/bunny_mock/queue.rb +210 -209
- data/lib/bunny_mock/session.rb +171 -151
- data/lib/bunny_mock/version.rb +3 -2
- data/spec/spec_helper.rb +1 -1
- data/spec/unit/bunny_mock/exchange_spec.rb +10 -10
- data/spec/unit/bunny_mock/queue_spec.rb +7 -7
- data/spec/unit/bunny_mock/session_spec.rb +74 -48
- metadata +86 -14
- data/CHANGELOG +0 -8
- data/lib/bunny_mock/exceptions.rb +0 -16
data/lib/bunny_mock/exchange.rb
CHANGED
@@ -1,269 +1,260 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module BunnyMock
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
# @private
|
260
|
-
def add_route(key, xchg_or_queue)
|
261
|
-
@routes[key] = xchg_or_queue
|
262
|
-
end
|
263
|
-
|
264
|
-
# @private
|
265
|
-
def remove_route(key)
|
266
|
-
@routes.delete key
|
267
|
-
end
|
268
|
-
end
|
3
|
+
class Exchange
|
4
|
+
|
5
|
+
##
|
6
|
+
# Create a new {BunnyMock::Exchange} instance
|
7
|
+
#
|
8
|
+
# @param [BunnyMock::Channel] channel Channel this exchange will use
|
9
|
+
# @param [String] name Name of exchange
|
10
|
+
# @param [Hash] opts Creation options
|
11
|
+
#
|
12
|
+
# @option opts [Boolean] :durable (false) Should this exchange be durable?
|
13
|
+
# @option opts [Boolean] :auto_delete (false) Should this exchange be automatically deleted when it is no longer used?
|
14
|
+
# @option opts [Boolean] :arguments ({}) Additional optional arguments (typically used by RabbitMQ extensions and plugins)
|
15
|
+
#
|
16
|
+
# @return [BunnyMock::Exchange] A new exchange
|
17
|
+
# @see BunnyMock::Channel#exchange
|
18
|
+
# @api public
|
19
|
+
#
|
20
|
+
def self.declare(channel, name = '', opts = {})
|
21
|
+
|
22
|
+
# get requested type
|
23
|
+
type = opts.fetch :type, :direct
|
24
|
+
|
25
|
+
# get needed class type
|
26
|
+
klazz = BunnyMock::Exchanges.const_get type.to_s.capitalize
|
27
|
+
|
28
|
+
# create exchange of desired type
|
29
|
+
klazz.new channel, name, type, opts
|
30
|
+
end
|
31
|
+
|
32
|
+
#
|
33
|
+
# API
|
34
|
+
#
|
35
|
+
|
36
|
+
# @return [BunnyMock::Channel] Channel used by exchange
|
37
|
+
attr_reader :channel
|
38
|
+
|
39
|
+
# @return [String] Exchange name
|
40
|
+
attr_reader :name
|
41
|
+
|
42
|
+
# @return [String] Exchange type
|
43
|
+
attr_reader :type
|
44
|
+
|
45
|
+
# @return [Hash] Creation options
|
46
|
+
attr_reader :opts
|
47
|
+
|
48
|
+
# @return [Boolean] If the exchange was declared as durable
|
49
|
+
attr_reader :durable
|
50
|
+
alias durable? durable
|
51
|
+
|
52
|
+
# @return [Boolean] If the exchange was declared with auto deletion
|
53
|
+
attr_reader :auto_delete
|
54
|
+
alias auto_delete? auto_delete
|
55
|
+
|
56
|
+
# @return [Boolean] If the exchange was declared as internal
|
57
|
+
attr_reader :internal
|
58
|
+
alias internal? internal
|
59
|
+
|
60
|
+
# @return [Hash] Any additional declaration arguments
|
61
|
+
attr_reader :arguments
|
62
|
+
|
63
|
+
# @private
|
64
|
+
# @return [Boolean] If exchange has been deleted
|
65
|
+
attr_reader :deleted
|
66
|
+
|
67
|
+
# @private
|
68
|
+
def initialize(channel, name, type, opts)
|
69
|
+
|
70
|
+
# store creation information
|
71
|
+
@channel = channel
|
72
|
+
@name = name
|
73
|
+
@opts = opts
|
74
|
+
@type = type
|
75
|
+
|
76
|
+
# get options
|
77
|
+
@durable = @opts[:durable]
|
78
|
+
@auto_delete = @opts[:auto_delete]
|
79
|
+
@internal = @opts[:internal]
|
80
|
+
@arguments = @opts[:arguments]
|
81
|
+
|
82
|
+
# create binding storage
|
83
|
+
@routes = {}
|
84
|
+
end
|
85
|
+
|
86
|
+
# @group Bunny API
|
87
|
+
|
88
|
+
##
|
89
|
+
# Publish a message
|
90
|
+
#
|
91
|
+
# @param [Object] payload Message payload
|
92
|
+
# @param [Hash] opts Message properties
|
93
|
+
#
|
94
|
+
# @option opts [String] :routing_key Routing key
|
95
|
+
# @option opts [Boolean] :persistent Should the message be persisted to disk?
|
96
|
+
# @option opts [Boolean] :mandatory Should the message be returned if it cannot be routed to any queue?
|
97
|
+
# @option opts [Integer] :timestamp A timestamp associated with this message
|
98
|
+
# @option opts [Integer] :expiration Expiration time after which the message will be deleted
|
99
|
+
# @option opts [String] :type Message type, e.g. what type of event or command this message represents. Can be any string
|
100
|
+
# @option opts [String] :reply_to Queue name other apps should send the response to
|
101
|
+
# @option opts [String] :content_type Message content type (e.g. application/json)
|
102
|
+
# @option opts [String] :content_encoding Message content encoding (e.g. gzip)
|
103
|
+
# @option opts [String] :correlation_id Message correlated to this one, e.g. what request this message is a reply for
|
104
|
+
# @option opts [Integer] :priority Message priority, 0 to 9. Not used by RabbitMQ, only applications
|
105
|
+
# @option opts [String] :message_id Any message identifier
|
106
|
+
# @option opts [String] :user_id Optional user ID. Verified by RabbitMQ against the actual connection username
|
107
|
+
# @option opts [String] :app_id Optional application ID
|
108
|
+
#
|
109
|
+
# @return [BunnyMock::Exchange] self
|
110
|
+
# @see {BunnyMock::Exchanges::Direct#deliver}
|
111
|
+
# @see {BunnyMock::Exchanges::Topic#deliver}
|
112
|
+
# @see {BunnyMock::Exchanges::Fanout#deliver}
|
113
|
+
# @see {BunnyMock::Exchanges::Headers#deliver}
|
114
|
+
# @api public
|
115
|
+
#
|
116
|
+
def publish(payload, opts = {})
|
117
|
+
|
118
|
+
# handle message sending, varies by type
|
119
|
+
deliver payload, opts, opts.fetch(:routing_key, '')
|
120
|
+
|
121
|
+
self
|
122
|
+
end
|
123
|
+
|
124
|
+
##
|
125
|
+
# Delete this exchange
|
126
|
+
#
|
127
|
+
# @api public
|
128
|
+
#
|
129
|
+
def delete(*)
|
130
|
+
|
131
|
+
@channel.deregister_exchange self
|
132
|
+
|
133
|
+
@deleted = true
|
134
|
+
end
|
135
|
+
|
136
|
+
##
|
137
|
+
# Bind this exchange to another exchange
|
138
|
+
#
|
139
|
+
# @param [BunnyMock::Exchange,String] exchange Exchange to bind to
|
140
|
+
# @param [Hash] opts Binding properties
|
141
|
+
#
|
142
|
+
# @option opts [String] :routing_key Custom routing key
|
143
|
+
#
|
144
|
+
# @return [BunnyMock::Exchange] self
|
145
|
+
# @api public
|
146
|
+
#
|
147
|
+
def bind(exchange, opts = {})
|
148
|
+
|
149
|
+
if exchange.respond_to?(:add_route)
|
150
|
+
|
151
|
+
# we can do the binding ourselves
|
152
|
+
exchange.add_route opts.fetch(:routing_key, @name), self
|
153
|
+
|
154
|
+
else
|
155
|
+
|
156
|
+
# we need the channel to look up the exchange
|
157
|
+
@channel.xchg_bind self, opts.fetch(:routing_key, @name), exchange
|
158
|
+
end
|
159
|
+
|
160
|
+
self
|
161
|
+
end
|
162
|
+
|
163
|
+
##
|
164
|
+
# Unbind this exchange from another exchange
|
165
|
+
#
|
166
|
+
# @param [BunnyMock::Exchange,String] exchange Exchange to unbind from
|
167
|
+
# @param [Hash] opts Binding properties
|
168
|
+
#
|
169
|
+
# @option opts [String] :routing_key Custom routing key
|
170
|
+
#
|
171
|
+
# @api public
|
172
|
+
#
|
173
|
+
def unbind(exchange, opts = {})
|
174
|
+
|
175
|
+
if exchange.respond_to?(:remove_route)
|
176
|
+
|
177
|
+
# we can do the unbinding ourselves
|
178
|
+
exchange.remove_route opts.fetch(:routing_key, @name)
|
179
|
+
|
180
|
+
else
|
181
|
+
|
182
|
+
# we need the channel to look up the exchange
|
183
|
+
@channel.xchg_unbind opts.fetch(:routing_key, @name), exchange
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
# @endgroup
|
188
|
+
|
189
|
+
##
|
190
|
+
# Check if this exchange is bound to another exchange
|
191
|
+
#
|
192
|
+
# @param [BunnyMock::Exchange,String] exchange Exchange to check
|
193
|
+
# @param [Hash] opts Binding properties
|
194
|
+
#
|
195
|
+
# @option opts [String] :routing_key Routing key from binding
|
196
|
+
#
|
197
|
+
# @return [Boolean] true if this exchange is bound to the given exchange, false otherwise
|
198
|
+
# @api public
|
199
|
+
#
|
200
|
+
def bound_to?(exchange, opts = {})
|
201
|
+
|
202
|
+
if exchange.respond_to?(:routes_to?)
|
203
|
+
|
204
|
+
# we can find out on the exchange object
|
205
|
+
exchange.routes_to? self, opts
|
206
|
+
|
207
|
+
else
|
208
|
+
|
209
|
+
# we need the channel to look up the exchange
|
210
|
+
@channel.xchg_bound_to? self, opts.fetch(:routing_key, @name), exchange
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
##
|
215
|
+
# Check if a queue is bound to this exchange
|
216
|
+
#
|
217
|
+
# @param [BunnyMock::Queue,String] exchange_or_queue Exchange or queue to check
|
218
|
+
# @param [Hash] opts Binding properties
|
219
|
+
#
|
220
|
+
# @option opts [String] :routing_key Custom routing key
|
221
|
+
#
|
222
|
+
# @return [Boolean] true if the given queue or exchange matching options is bound to this exchange, false otherwise
|
223
|
+
# @api public
|
224
|
+
#
|
225
|
+
def routes_to?(exchange_or_queue, opts = {})
|
226
|
+
|
227
|
+
route = exchange_or_queue.respond_to?(:name) ? exchange_or_queue.name : exchange_or_queue
|
228
|
+
|
229
|
+
@routes.key? opts.fetch(:routing_key, route)
|
230
|
+
end
|
231
|
+
alias has_binding? routes_to?
|
232
|
+
|
233
|
+
##
|
234
|
+
# Deliver a message to routes
|
235
|
+
#
|
236
|
+
# @see {BunnyMock::Exchanges::Direct#deliver}
|
237
|
+
# @see {BunnyMock::Exchanges::Topic#deliver}
|
238
|
+
# @see {BunnyMock::Exchanges::Fanout#deliver}
|
239
|
+
# @see {BunnyMock::Exchanges::Headers#deliver}
|
240
|
+
# @api public
|
241
|
+
#
|
242
|
+
def deliver(payload, opts, key)
|
243
|
+
# noOp
|
244
|
+
end
|
245
|
+
|
246
|
+
#
|
247
|
+
# Implementation
|
248
|
+
#
|
249
|
+
|
250
|
+
# @private
|
251
|
+
def add_route(key, xchg_or_queue)
|
252
|
+
@routes[key] = xchg_or_queue
|
253
|
+
end
|
254
|
+
|
255
|
+
# @private
|
256
|
+
def remove_route(key)
|
257
|
+
@routes.delete key
|
258
|
+
end
|
259
|
+
end
|
269
260
|
end
|