Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions bunny-mock.gemspec
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
#!/usr/bin/env gem build
# encoding: utf-8

require 'base64'
require File.expand_path("../lib/bunny_mock/version", __FILE__)

Gem::Specification.new do |s|
s.name = 'bunny-mock'
s.version = BunnyMock::VERSION.dup
s.platform = Gem::Platform::RUBY
s.authors = ['Andrew Rempe']
s.email = [Base64.decode64('YW5kcmV3cmVtcGVAZ21haWwuY29t\n')]
s.summary = 'Mocking for the popular Bunny client for RabbitMQ'
s.description = 'Easy to use mocking for testing the Bunny client for RabbitMQ'
s.license = 'MIT'
Expand Down
1 change: 1 addition & 0 deletions lib/bunny-mock.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
require 'bunny_mock/channel'
require 'bunny_mock/exchange'
require 'bunny_mock/queue'
require 'bunny_mock/consumer'

require 'bunny_mock/exchanges/direct'
require 'bunny_mock/exchanges/topic'
Expand Down
19 changes: 19 additions & 0 deletions lib/bunny_mock/consumer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
module BunnyMock
class Consumer
attr_reader :block, :args, :queue

def initialize(args, queue, block)
@args = args
@queue = queue
@block = block
end

def cancel
current_consumers = queue.instance_variable_get('@consumers')
queue.instance_variable_set('@consumers', current_consumers - [self])
true
rescue Exception
false
end
end
end
22 changes: 22 additions & 0 deletions lib/bunny_mock/exchange.rb
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,18 @@ def deliver(payload, opts, key)
# noOp
end

##
# Register a callback when messages cannot be delivered
#
# Takes a block that will be called anytime a message is returned
# @api publick
#
def on_return(&block)
@on_return = block

self
end

#
# Implementation
#
Expand All @@ -247,6 +259,16 @@ def add_route(key, xchg_or_queue)
@routes[key] << xchg_or_queue
end

# @private
def handle_return(basic_return, properties, content)
if @on_return
@on_return.call(
basic_return.merge(reply_code: 312, reply_text: 'NO_ROUTE'),
properties, content
)
end
end

# @private
def remove_route(key, xchg_or_queue)
instance = xchg_or_queue.respond_to?(:name) ? xchg_or_queue.name : xchg_or_queue
Expand Down
6 changes: 5 additions & 1 deletion lib/bunny_mock/exchanges/direct.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@ class Direct < BunnyMock::Exchange
# @api public
#
def deliver(payload, opts, key)
@routes[key].each { |route| route.publish payload, opts } if @routes[key]
if @routes[key] && @routes[key].any?
@routes[key].each { |route| route.publish payload, opts }
elsif opts.fetch(:mandatory, false)
handle_return({ exchange: name, routing_key: key }, opts, payload)
end
end
end
end
Expand Down
8 changes: 6 additions & 2 deletions lib/bunny_mock/exchanges/fanout.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,12 @@ class Fanout < BunnyMock::Exchange
#
# @api public
#
def deliver(payload, opts, _key)
@routes.values.flatten.each { |destination| destination.publish(payload, opts) }
def deliver(payload, opts, key)
if @routes.values.flatten.any?
@routes.values.flatten.each { |destination| destination.publish(payload, opts) }
elsif opts.fetch(:mandatory, false)
handle_return({ exchange: name, routing_key: key }, opts, payload)
end
end
end
end
Expand Down
6 changes: 5 additions & 1 deletion lib/bunny_mock/exchanges/topic.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,11 @@ class Topic < BunnyMock::Exchange
#
def deliver(payload, opts, key)
delivery_routes = @routes.dup.keep_if { |route, _| key =~ route_to_regex(route) }
delivery_routes.values.flatten.each { |dest| dest.publish(payload, opts) }
if delivery_routes.values.flatten.any?
delivery_routes.values.flatten.each { |dest| dest.publish(payload, opts) }
elsif opts.fetch(:mandatory, false)
handle_return({ exchange: name, routing_key: key }, opts, payload)
end
end

private
Expand Down
13 changes: 7 additions & 6 deletions lib/bunny_mock/queue.rb
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,11 @@ def publish(payload, opts = {})
# @api public
#
def subscribe(*args, &block)
@consumers << [block, args]
consumer = BunnyMock::Consumer.new(args, self, block)
@consumers << consumer
yield_consumers

self
consumer
end

##
Expand All @@ -102,7 +103,7 @@ def subscribe_with(consumer, *args)
@consumers << [consumer, args]
yield_consumers

self
consumer
end

##
Expand Down Expand Up @@ -261,12 +262,12 @@ def pop_response(message)

# @private
def yield_consumers
@consumers.each do |c, args|
@consumers.each do |consumer|
# rubocop:disable AssignmentInCondition
while message = all.pop
response = pop_response(message)
store_acknowledgement(response, args)
c.call(response)
store_acknowledgement(response, consumer.args)
consumer.block.call(response)
end
end
end
Expand Down