danielsdeleo-moqueue 0.1.3 → 0.1.4
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.
- data/CONTRIBUTORS.rdoc +3 -0
- data/Rakefile +39 -0
- data/VERSION.yml +2 -2
- data/lib/moqueue/matchers.rb +39 -0
- data/lib/moqueue/mock_broker.rb +9 -0
- data/lib/moqueue/mock_exchange.rb +43 -9
- data/lib/moqueue/mock_queue.rb +8 -0
- data/lib/moqueue/object_methods.rb +10 -0
- data/lib/moqueue/overloads.rb +8 -0
- data/moqueue.gemspec +63 -6
- data/spec/examples/logger_spec.rb +5 -5
- data/spec/spec_helper.rb +5 -0
- data/spec/unit/matchers_spec.rb +14 -4
- data/spec/unit/mock_broker_spec.rb +6 -0
- data/spec/unit/mock_exchange_spec.rb +69 -3
- data/spec/unit/mock_queue_spec.rb +8 -2
- data/spec/unit/moqueue_spec.rb +0 -4
- data/spec/unit/object_methods_spec.rb +1 -1
- data/spec/unit/overloads_spec.rb +10 -2
- metadata +34 -16
data/CONTRIBUTORS.rdoc
ADDED
data/Rakefile
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require "spec/rake/spectask"
|
2
|
+
require "rake/rdoctask"
|
2
3
|
|
3
4
|
task :default => :spec
|
4
5
|
|
@@ -18,8 +19,46 @@ begin
|
|
18
19
|
s.description = "Mocktacular Companion to AMQP Library. Happy TATFTing!"
|
19
20
|
s.authors = ["Daniel DeLeo"]
|
20
21
|
s.files = FileList["[A-Za-z]*", "{lib,spec}/**/*"]
|
22
|
+
s.rubyforge_project = "moqueue"
|
23
|
+
s.add_dependency("amqp")
|
21
24
|
end
|
22
25
|
rescue LoadError
|
23
26
|
puts "Jeweler, or one of its dependencies, is not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
|
24
27
|
end
|
25
28
|
|
29
|
+
# These are new tasks
|
30
|
+
begin
|
31
|
+
require 'jeweler/rubyforge_tasks'
|
32
|
+
require 'rake/contrib/sshpublisher'
|
33
|
+
|
34
|
+
Jeweler::RubyforgeTasks.new
|
35
|
+
|
36
|
+
namespace :rubyforge do
|
37
|
+
|
38
|
+
desc "Release gem and RDoc documentation to RubyForge"
|
39
|
+
task :release => ["rubyforge:release:gem", "rubyforge:release:docs"]
|
40
|
+
|
41
|
+
namespace :release do
|
42
|
+
desc "Publish RDoc to RubyForge."
|
43
|
+
task :docs => [:rdoc] do
|
44
|
+
config = YAML.load(
|
45
|
+
File.read(File.expand_path('~/.rubyforge/user-config.yml'))
|
46
|
+
)
|
47
|
+
|
48
|
+
host = "#{config['username']}@rubyforge.org"
|
49
|
+
remote_dir = "/var/www/gforge-projects/moqueue/"
|
50
|
+
local_dir = 'rdoc'
|
51
|
+
|
52
|
+
Rake::SshDirPublisher.new(host, remote_dir, local_dir).upload
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
rescue LoadError
|
57
|
+
puts "Rake SshDirPublisher is unavailable or your rubyforge environment is not configured."
|
58
|
+
end
|
59
|
+
|
60
|
+
Rake::RDocTask.new do |rd|
|
61
|
+
rd.main = "README.rdoc"
|
62
|
+
rd.rdoc_files.include("README.rdoc", "lib/**/*.rb")
|
63
|
+
rd.rdoc_dir = "rdoc"
|
64
|
+
end
|
data/VERSION.yml
CHANGED
data/lib/moqueue/matchers.rb
CHANGED
@@ -54,6 +54,33 @@ module Moqueue
|
|
54
54
|
end
|
55
55
|
end
|
56
56
|
|
57
|
+
class HasExactRoutingKey
|
58
|
+
|
59
|
+
def initialize(expected_key)
|
60
|
+
@expected_key = expected_key
|
61
|
+
end
|
62
|
+
|
63
|
+
def matches?(queue)
|
64
|
+
if queue.respond_to?(:received_routing_key?)
|
65
|
+
@queue = queue
|
66
|
+
@queue.received_routing_key?(@expected_key)
|
67
|
+
else
|
68
|
+
raise NoMethodError,
|
69
|
+
"Grrr. you can't use ``should have_received_routing_key'' on #{queue.inspect} " +
|
70
|
+
"because it doesn't respond_to :received_routing_key?"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def failure_message_for_should
|
75
|
+
"expected #{@queue.inspect} to have received header with routing key ``#{@expected_msg}''"
|
76
|
+
end
|
77
|
+
|
78
|
+
def failure_message_for_should_not
|
79
|
+
"expected #{@queue.inspect} to not have received header with routing key ``#{@expected_msg}''"
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
|
57
84
|
def have_received_message(expected_msg)
|
58
85
|
HasReceived.new(expected_msg)
|
59
86
|
end
|
@@ -62,8 +89,20 @@ module Moqueue
|
|
62
89
|
HasAcked.new(expected_msg)
|
63
90
|
end
|
64
91
|
|
92
|
+
# Customer matcher for verifying a message was received with a specific routing key
|
93
|
+
# (matches exactly, no wildcards)
|
94
|
+
#
|
95
|
+
# queue.bind(exchange).subscribe {|msg| msg}
|
96
|
+
# exchange.publish msg, :key => 'foo.bar.baz'
|
97
|
+
# queue.should have_received_routing_key('foo.bar.baz')
|
98
|
+
#
|
99
|
+
def have_received_exact_routing_key(expected_key)
|
100
|
+
HasExactRoutingKey.new(expected_key)
|
101
|
+
end
|
102
|
+
|
65
103
|
alias_method :have_received, :have_received_message
|
66
104
|
alias_method :have_ack_for, :have_received_ack_for
|
105
|
+
alias_method :have_exact_routing_key, :have_received_exact_routing_key
|
67
106
|
end
|
68
107
|
end
|
69
108
|
|
data/lib/moqueue/mock_broker.rb
CHANGED
@@ -12,6 +12,7 @@ module Moqueue
|
|
12
12
|
|
13
13
|
def reset!
|
14
14
|
@registered_queues = {}
|
15
|
+
@registered_direct_exchanges = {}
|
15
16
|
@registered_topic_exchanges = {}
|
16
17
|
@registered_fanout_exchanges = {}
|
17
18
|
end
|
@@ -24,6 +25,14 @@ module Moqueue
|
|
24
25
|
@registered_queues[queue.name] = queue
|
25
26
|
end
|
26
27
|
|
28
|
+
def register_direct_exchange(exchange)
|
29
|
+
@registered_direct_exchanges[exchange.direct] = exchange
|
30
|
+
end
|
31
|
+
|
32
|
+
def find_direct_exchange(name)
|
33
|
+
@registered_direct_exchanges[name]
|
34
|
+
end
|
35
|
+
|
27
36
|
def register_topic_exchange(exchange)
|
28
37
|
@registered_topic_exchanges[exchange.topic] = exchange
|
29
38
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module Moqueue
|
2
2
|
|
3
3
|
class MockExchange
|
4
|
-
attr_reader :topic, :fanout
|
4
|
+
attr_reader :topic, :fanout, :direct
|
5
5
|
|
6
6
|
class << self
|
7
7
|
|
@@ -14,6 +14,10 @@ module Moqueue
|
|
14
14
|
return fanout
|
15
15
|
end
|
16
16
|
|
17
|
+
if opts[:direct] && direct = MockBroker.instance.find_direct_exchange(opts[:direct])
|
18
|
+
return direct
|
19
|
+
end
|
20
|
+
|
17
21
|
super
|
18
22
|
end
|
19
23
|
|
@@ -24,6 +28,8 @@ module Moqueue
|
|
24
28
|
MockBroker.instance.register_topic_exchange(self)
|
25
29
|
elsif @fanout = opts[:fanout]
|
26
30
|
MockBroker.instance.register_fanout_exchange(self)
|
31
|
+
elsif @direct = opts[:direct]
|
32
|
+
MockBroker.instance.register_direct_exchange(self)
|
27
33
|
end
|
28
34
|
end
|
29
35
|
|
@@ -40,7 +46,9 @@ module Moqueue
|
|
40
46
|
|
41
47
|
def attach_queue(queue, opts={})
|
42
48
|
if topic
|
43
|
-
attached_queues << [queue,
|
49
|
+
attached_queues << [queue, TopicBindingKey.new(opts[:key])]
|
50
|
+
elsif direct
|
51
|
+
attached_queues << [queue, DirectBindingKey.new(opts[:key])]
|
44
52
|
else
|
45
53
|
attached_queues << queue
|
46
54
|
end
|
@@ -60,11 +68,15 @@ module Moqueue
|
|
60
68
|
private
|
61
69
|
|
62
70
|
def routing_keys_match?(binding_key, message_key)
|
63
|
-
|
71
|
+
if topic
|
72
|
+
TopicBindingKey.new(binding_key).matches?(message_key)
|
73
|
+
elsif direct
|
74
|
+
DirectBindingKey.new(binding_key).matches?(message_key)
|
75
|
+
end
|
64
76
|
end
|
65
77
|
|
66
78
|
def matching_queues(opts={})
|
67
|
-
return attached_queues unless topic
|
79
|
+
return attached_queues unless topic || direct
|
68
80
|
attached_queues.map {|q, binding| binding.matches?(opts[:key]) ? q : nil}.compact
|
69
81
|
end
|
70
82
|
|
@@ -84,16 +96,20 @@ module Moqueue
|
|
84
96
|
|
85
97
|
public
|
86
98
|
|
87
|
-
|
99
|
+
module BaseKey
|
88
100
|
attr_reader :key
|
89
101
|
|
90
|
-
def initialize(key_string)
|
91
|
-
@key = key_string.to_s.split(".")
|
92
|
-
end
|
93
|
-
|
94
102
|
def ==(other)
|
95
103
|
other.respond_to?(:key) && other.key == @key
|
96
104
|
end
|
105
|
+
end
|
106
|
+
|
107
|
+
class TopicBindingKey
|
108
|
+
include BaseKey
|
109
|
+
|
110
|
+
def initialize(key_string)
|
111
|
+
@key = key_string.to_s.split(".")
|
112
|
+
end
|
97
113
|
|
98
114
|
def matches?(message_key)
|
99
115
|
message_key, binding_key = message_key.split("."), key.dup
|
@@ -108,6 +124,24 @@ module Moqueue
|
|
108
124
|
end
|
109
125
|
|
110
126
|
end
|
127
|
+
|
128
|
+
# Requires an *exact* match
|
129
|
+
class DirectBindingKey
|
130
|
+
include BaseKey
|
131
|
+
|
132
|
+
def initialize(key_string)
|
133
|
+
@key = key_string.to_s
|
134
|
+
end
|
135
|
+
|
136
|
+
def matches?(message_key)
|
137
|
+
message_key, binding_key = message_key.to_s, key.dup
|
138
|
+
|
139
|
+
# looking for string equivalence
|
140
|
+
message_key == binding_key
|
141
|
+
end
|
142
|
+
|
143
|
+
end
|
144
|
+
|
111
145
|
end
|
112
146
|
|
113
147
|
end
|
data/lib/moqueue/mock_queue.rb
CHANGED
@@ -45,6 +45,10 @@ module Moqueue
|
|
45
45
|
received_messages.include?(message_content)
|
46
46
|
end
|
47
47
|
|
48
|
+
def received_routing_key?(key)
|
49
|
+
received_messages_and_headers.find { |r| r[:headers] && r[:headers].properties[:routing_key] == key }
|
50
|
+
end
|
51
|
+
|
48
52
|
def unsubscribe
|
49
53
|
true
|
50
54
|
end
|
@@ -80,6 +84,10 @@ module Moqueue
|
|
80
84
|
received_messages_and_headers.map{|r| r[:message] }
|
81
85
|
end
|
82
86
|
|
87
|
+
def received_headers
|
88
|
+
received_messages_and_headers.map{ |r| r[:headers] }
|
89
|
+
end
|
90
|
+
|
83
91
|
def acked_messages
|
84
92
|
received_messages_and_headers.map do |r|
|
85
93
|
r[:message] if @ack_msgs && r[:headers].received_ack?
|
@@ -8,18 +8,28 @@ module Moqueue
|
|
8
8
|
[queue, exchange]
|
9
9
|
end
|
10
10
|
|
11
|
+
# Takes a string name as a parameter. Each queue name may only be used
|
12
|
+
# once. Multiple calls to #mock_queue with the same +name+ will return
|
13
|
+
# the same object.
|
11
14
|
def mock_queue(name=nil)
|
12
15
|
MockQueue.new(name || "anonymous-#{rand(2**32).to_s(16)}")
|
13
16
|
end
|
14
17
|
|
18
|
+
# Takes a hash to specify the exchange type and its name.
|
19
|
+
#
|
20
|
+
# topic = mock_exchange(:topic => 'topic exchange')
|
15
21
|
def mock_exchange(opts={})
|
16
22
|
MockExchange.new(opts)
|
17
23
|
end
|
18
24
|
|
25
|
+
# Overloads the class-level method calls typically used by AMQP code
|
26
|
+
# such as MQ.direct, MQ.queue, MQ.topic, etc.
|
19
27
|
def overload_amqp
|
20
28
|
require MOQUEUE_ROOT + "moqueue/overloads"
|
21
29
|
end
|
22
30
|
|
31
|
+
# Deletes all exchanges and queues from the mock broker. As a consequence of
|
32
|
+
# removing queues, all bindings and subscriptions are also deleted.
|
23
33
|
def reset_broker
|
24
34
|
MockBroker.instance.reset!
|
25
35
|
end
|
data/lib/moqueue/overloads.rb
CHANGED
@@ -7,6 +7,10 @@ class MQ
|
|
7
7
|
Moqueue::MockQueue.new(name)
|
8
8
|
end
|
9
9
|
|
10
|
+
def direct(name, opts={})
|
11
|
+
Moqueue::MockExchange.new(opts.merge(:direct=>name))
|
12
|
+
end
|
13
|
+
|
10
14
|
def fanout(name, opts={})
|
11
15
|
Moqueue::MockExchange.new(opts.merge(:fanout=>name))
|
12
16
|
end
|
@@ -16,6 +20,10 @@ class MQ
|
|
16
20
|
def initialize(*args)
|
17
21
|
end
|
18
22
|
|
23
|
+
def direct(name, opts = {})
|
24
|
+
Moqueue::MockExchange.new(opts.merge(:direct => name))
|
25
|
+
end
|
26
|
+
|
19
27
|
def fanout(name, opts = {})
|
20
28
|
Moqueue::MockExchange.new(opts.merge(:fanout => name))
|
21
29
|
end
|
data/moqueue.gemspec
CHANGED
@@ -1,29 +1,86 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run `rake gemspec`
|
1
4
|
# -*- encoding: utf-8 -*-
|
2
5
|
|
3
6
|
Gem::Specification.new do |s|
|
4
7
|
s.name = %q{moqueue}
|
5
|
-
s.version = "0.1.
|
8
|
+
s.version = "0.1.4"
|
6
9
|
|
7
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
11
|
s.authors = ["Daniel DeLeo"]
|
9
|
-
s.date = %q{2009-
|
12
|
+
s.date = %q{2009-09-21}
|
10
13
|
s.description = %q{Mocktacular Companion to AMQP Library. Happy TATFTing!}
|
11
14
|
s.email = %q{dan@kallistec.com}
|
12
|
-
s.extra_rdoc_files = [
|
13
|
-
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"README.rdoc"
|
17
|
+
]
|
18
|
+
s.files = [
|
19
|
+
"CONTRIBUTORS.rdoc",
|
20
|
+
"README.rdoc",
|
21
|
+
"Rakefile",
|
22
|
+
"VERSION.yml",
|
23
|
+
"lib/moqueue.rb",
|
24
|
+
"lib/moqueue/fibers18.rb",
|
25
|
+
"lib/moqueue/matchers.rb",
|
26
|
+
"lib/moqueue/mock_broker.rb",
|
27
|
+
"lib/moqueue/mock_exchange.rb",
|
28
|
+
"lib/moqueue/mock_headers.rb",
|
29
|
+
"lib/moqueue/mock_queue.rb",
|
30
|
+
"lib/moqueue/object_methods.rb",
|
31
|
+
"lib/moqueue/overloads.rb",
|
32
|
+
"moqueue.gemspec",
|
33
|
+
"spec/examples/ack_spec.rb",
|
34
|
+
"spec/examples/basic_usage_spec.rb",
|
35
|
+
"spec/examples/example_helper.rb",
|
36
|
+
"spec/examples/logger_spec.rb",
|
37
|
+
"spec/examples/ping_pong_spec.rb",
|
38
|
+
"spec/examples/stocks_spec.rb",
|
39
|
+
"spec/spec.opts",
|
40
|
+
"spec/spec_helper.rb",
|
41
|
+
"spec/unit/matchers_spec.rb",
|
42
|
+
"spec/unit/mock_broker_spec.rb",
|
43
|
+
"spec/unit/mock_exchange_spec.rb",
|
44
|
+
"spec/unit/mock_headers_spec.rb",
|
45
|
+
"spec/unit/mock_queue_spec.rb",
|
46
|
+
"spec/unit/moqueue_spec.rb",
|
47
|
+
"spec/unit/object_methods_spec.rb",
|
48
|
+
"spec/unit/overloads_spec.rb"
|
49
|
+
]
|
14
50
|
s.homepage = %q{http://github.com/danielsdeleo/moqueue}
|
15
|
-
s.rdoc_options = ["--
|
51
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
16
52
|
s.require_paths = ["lib"]
|
17
|
-
s.
|
53
|
+
s.rubyforge_project = %q{moqueue}
|
54
|
+
s.rubygems_version = %q{1.3.5}
|
18
55
|
s.summary = %q{Mocktacular Companion to AMQP Library. Happy TATFTing!}
|
56
|
+
s.test_files = [
|
57
|
+
"spec/examples/ack_spec.rb",
|
58
|
+
"spec/examples/basic_usage_spec.rb",
|
59
|
+
"spec/examples/example_helper.rb",
|
60
|
+
"spec/examples/logger_spec.rb",
|
61
|
+
"spec/examples/ping_pong_spec.rb",
|
62
|
+
"spec/examples/stocks_spec.rb",
|
63
|
+
"spec/spec_helper.rb",
|
64
|
+
"spec/unit/matchers_spec.rb",
|
65
|
+
"spec/unit/mock_broker_spec.rb",
|
66
|
+
"spec/unit/mock_exchange_spec.rb",
|
67
|
+
"spec/unit/mock_headers_spec.rb",
|
68
|
+
"spec/unit/mock_queue_spec.rb",
|
69
|
+
"spec/unit/moqueue_spec.rb",
|
70
|
+
"spec/unit/object_methods_spec.rb",
|
71
|
+
"spec/unit/overloads_spec.rb"
|
72
|
+
]
|
19
73
|
|
20
74
|
if s.respond_to? :specification_version then
|
21
75
|
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
22
76
|
s.specification_version = 3
|
23
77
|
|
24
78
|
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
79
|
+
s.add_runtime_dependency(%q<amqp>, [">= 0"])
|
25
80
|
else
|
81
|
+
s.add_dependency(%q<amqp>, [">= 0"])
|
26
82
|
end
|
27
83
|
else
|
84
|
+
s.add_dependency(%q<amqp>, [">= 0"])
|
28
85
|
end
|
29
86
|
end
|
@@ -2,7 +2,7 @@ require File.dirname(__FILE__) + '/../spec_helper'
|
|
2
2
|
|
3
3
|
describe Moqueue, "when running the logger example" do
|
4
4
|
|
5
|
-
class
|
5
|
+
class MyLoggerRulez
|
6
6
|
def initialize *args, &block
|
7
7
|
opts = args.pop if args.last.is_a? Hash
|
8
8
|
opts ||= {}
|
@@ -51,7 +51,7 @@ describe Moqueue, "when running the logger example" do
|
|
51
51
|
:msg => data)
|
52
52
|
|
53
53
|
print(opts)
|
54
|
-
unless
|
54
|
+
unless MyLoggerRulez.disabled?
|
55
55
|
MQ.fanout('logging', :durable => true).publish Marshal.dump(opts)
|
56
56
|
end
|
57
57
|
|
@@ -98,10 +98,10 @@ describe Moqueue, "when running the logger example" do
|
|
98
98
|
|
99
99
|
def run_client
|
100
100
|
AMQP.start do
|
101
|
-
log =
|
101
|
+
log = MyLoggerRulez.new
|
102
102
|
log.debug 'its working!'
|
103
103
|
|
104
|
-
log =
|
104
|
+
log = MyLoggerRulez.new do |msg|
|
105
105
|
#require 'pp'
|
106
106
|
#pp msg
|
107
107
|
#puts
|
@@ -116,7 +116,7 @@ describe Moqueue, "when running the logger example" do
|
|
116
116
|
log.info '123', :process
|
117
117
|
log.debug 'login', :session => 'abc', :user => 123
|
118
118
|
|
119
|
-
log =
|
119
|
+
log = MyLoggerRulez.new(:webserver, :timestamp, :hostname, &log.printer)
|
120
120
|
log.info 'Request for /', :GET, :session => 'abc'
|
121
121
|
|
122
122
|
#AMQP.stop{ EM.stop }
|
data/spec/spec_helper.rb
CHANGED
data/spec/unit/matchers_spec.rb
CHANGED
@@ -25,6 +25,16 @@ describe Matchers do
|
|
25
25
|
@mock_moqueue.should_not have_received_message("no match")
|
26
26
|
end
|
27
27
|
|
28
|
+
it "should implement Object#should have_exact_routing_key(key)" do
|
29
|
+
@mock_moqueue.expects(:received_routing_key?).with("routing.key").returns(true)
|
30
|
+
@mock_moqueue.should have_received_exact_routing_key("routing.key")
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should implement Object#should_not have_exact_routing_key(key)" do
|
34
|
+
@mock_moqueue.expects(:received_routing_key?).with("routing.key").returns(false)
|
35
|
+
@mock_moqueue.should_not have_received_exact_routing_key("routing.key")
|
36
|
+
end
|
37
|
+
|
28
38
|
it "should have a useful failure message" do
|
29
39
|
@mock_moqueue.expects(:received_message?).with("this fails").returns(false)
|
30
40
|
failing_example = lambda {@mock_moqueue.should have_received_message("this fails")}
|
@@ -44,8 +54,8 @@ describe Matchers do
|
|
44
54
|
Object.new.should have_received_message("foo")
|
45
55
|
rescue => e
|
46
56
|
end
|
47
|
-
e.should be_a
|
48
|
-
e.message.should match
|
57
|
+
e.should be_a(NoMethodError)
|
58
|
+
e.message.should match(/you can't use \`\`should have_received_message\'\' on #\<Object/)
|
49
59
|
end
|
50
60
|
|
51
61
|
it "should alias #have_received_message as #have_received for less verbosity" do
|
@@ -85,8 +95,8 @@ describe Matchers do
|
|
85
95
|
Object.new.should have_received_message("foo")
|
86
96
|
rescue => e
|
87
97
|
end
|
88
|
-
e.should be_a
|
89
|
-
e.message.should match
|
98
|
+
e.should be_a(NoMethodError)
|
99
|
+
e.message.should match(/you can't use \`\`should have_received_message\'\' on #\<Object/)
|
90
100
|
end
|
91
101
|
|
92
102
|
end
|
@@ -19,6 +19,12 @@ describe MockBroker do
|
|
19
19
|
@broker.registered_queues.size.should == 0
|
20
20
|
end
|
21
21
|
|
22
|
+
it "should keep a list of direct exchanges" do
|
23
|
+
exchange = MockExchange.new(:direct => "thundercats")
|
24
|
+
@broker.register_direct_exchange(exchange)
|
25
|
+
@broker.find_direct_exchange("thundercats").should equal(exchange)
|
26
|
+
end
|
27
|
+
|
22
28
|
it "should keep a list of topic exchanges" do
|
23
29
|
exchange = MockExchange.new(:topic => "lolcats")
|
24
30
|
@broker.register_topic_exchange(exchange)
|
@@ -26,6 +26,72 @@ describe MockExchange do
|
|
26
26
|
lambda {@exchange.publish("whateva eva", :key=>"foo.bar")}.should_not raise_error(ArgumentError)
|
27
27
|
end
|
28
28
|
|
29
|
+
it "should emulate direct exchanges" do
|
30
|
+
direct_exchange = MockExchange.new(:direct => "thundercats")
|
31
|
+
direct_exchange.direct.should == "thundercats"
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should register new direct exchanges with the mock broker" do
|
35
|
+
MockBroker.instance.expects(:register_direct_exchange)
|
36
|
+
MockExchange.new(:direct => "lolz")
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should return a previously created direct exchange when asked to create a new one with the same name" do
|
40
|
+
exchange = MockExchange.new(:direct => "smoochie")
|
41
|
+
MockExchange.new(:direct => "smoochie").should equal(exchange)
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should determine if routing keys match exactly on the direct exchange" do
|
45
|
+
exchange = MockExchange.new(:direct => "lolz")
|
46
|
+
key = MockExchange::DirectBindingKey
|
47
|
+
key.new("cats").matches?("cats").should be_true
|
48
|
+
key.new("cats").matches?("dogs").should be_false
|
49
|
+
key.new("cats.*").matches?("cats.fridge").should be_false
|
50
|
+
key.new("cats.evil").matches?("cats.fridge").should be_false
|
51
|
+
key.new("cats.*").matches?("cats.fridge.in_urs").should be_false
|
52
|
+
key.new("cats.#").matches?("cats.fridge.in_urs").should be_false
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should forward messages to a queue only if the keys match exactly when emulating a direct exchange" do
|
56
|
+
ensure_deferred_block_called
|
57
|
+
exchange = MockExchange.new(:direct => "thundercats")
|
58
|
+
queue = MockQueue.new("ho")
|
59
|
+
queue.bind(exchange, :key=>"cats").subscribe do |msg|
|
60
|
+
msg.should == "ohai"
|
61
|
+
deferred_block_called
|
62
|
+
end
|
63
|
+
exchange.publish("ohai", :key => "cats")
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should NOT forward messages to a queue if the keys mismatch when emulating a direct exchange" do
|
67
|
+
ensure_deferred_block_skipped
|
68
|
+
exchange = MockExchange.new(:direct => "thundercats")
|
69
|
+
queue = MockQueue.new("ho")
|
70
|
+
queue.bind(exchange, :key=>"cats").subscribe do |msg|
|
71
|
+
msg.should == "ohai"
|
72
|
+
deferred_block_called # should never execute!
|
73
|
+
end
|
74
|
+
exchange.publish("ohai", :key => "cats.attack")
|
75
|
+
end
|
76
|
+
|
77
|
+
it "should add the routing key to the headers' properties when publishing as a direct exchange" do
|
78
|
+
ensure_deferred_block_called
|
79
|
+
exchange = MockExchange.new(:direct => "thunderdogs")
|
80
|
+
queue = MockQueue.new("dogzh8er").bind(exchange, :key=>"boxers")
|
81
|
+
queue.subscribe do |headers, msg|
|
82
|
+
deferred_block_called
|
83
|
+
headers.routing_key.should == "boxers"
|
84
|
+
msg.should == "Roxie"
|
85
|
+
end
|
86
|
+
exchange.publish("Roxie", :key=>"boxers")
|
87
|
+
end
|
88
|
+
|
89
|
+
it "should NOT raise an error when publishing to a direct exchange without specifying a key" do
|
90
|
+
exchange = MockExchange.new(:direct => "spike")
|
91
|
+
fail_msg = "you must provide a key when publishing to a topic exchange"
|
92
|
+
lambda {exchange.publish("failtacular")}.should_not raise_error(ArgumentError, fail_msg)
|
93
|
+
end
|
94
|
+
|
29
95
|
it "should emulate topic exchanges" do
|
30
96
|
#pending "support for storing and retrieving topic exchanges in MockBroker"
|
31
97
|
topic_exchange = MockExchange.new(:topic => "lolcats")
|
@@ -39,12 +105,12 @@ describe MockExchange do
|
|
39
105
|
|
40
106
|
it "should return a previously created topic exchange when asked to create a new one with the same topic" do
|
41
107
|
exchange = MockExchange.new(:topic => "fails")
|
42
|
-
MockExchange.new(:topic => "fails").should equal
|
108
|
+
MockExchange.new(:topic => "fails").should equal(exchange)
|
43
109
|
end
|
44
110
|
|
45
111
|
it "should determine if routing keys match" do
|
46
112
|
exchange = MockExchange.new(:topic => "lolz")
|
47
|
-
key = MockExchange::
|
113
|
+
key = MockExchange::TopicBindingKey
|
48
114
|
key.new("cats").matches?("cats").should be_true
|
49
115
|
key.new("cats").matches?("cats").should be_true
|
50
116
|
key.new("cats").matches?("dogs").should be_false
|
@@ -96,7 +162,7 @@ describe MockExchange do
|
|
96
162
|
it "should return the exact same fanout exchange if creating one with an identical name" do
|
97
163
|
the_first_fanout = MockExchange.new(:fanout => "pseudo singleton")
|
98
164
|
the_second_one = MockExchange.new(:fanout => "pseudo singleton")
|
99
|
-
the_first_fanout.should equal
|
165
|
+
the_first_fanout.should equal(the_second_one)
|
100
166
|
end
|
101
167
|
|
102
168
|
end
|
@@ -21,6 +21,12 @@ describe MockQueue do
|
|
21
21
|
@exchange.publish("the message")
|
22
22
|
end
|
23
23
|
|
24
|
+
it "should allow retrieval of the headers for any published messages" do
|
25
|
+
@queue.subscribe { |msg| msg }
|
26
|
+
@exchange.publish("the message")
|
27
|
+
@queue.received_headers.first.should be_kind_of(Moqueue::MockHeaders)
|
28
|
+
end
|
29
|
+
|
24
30
|
it "should create mock headers if pop is given a block w/ 2 arity" do
|
25
31
|
pending
|
26
32
|
end
|
@@ -84,7 +90,7 @@ describe MockQueue do
|
|
84
90
|
end
|
85
91
|
|
86
92
|
it "should #unsubscribe" do
|
87
|
-
pending
|
93
|
+
pending("should really remove the association with exchange")
|
88
94
|
@queue.should respond_to(:unsubscribe)
|
89
95
|
end
|
90
96
|
|
@@ -95,7 +101,7 @@ describe MockQueue do
|
|
95
101
|
it "should raise an error on double subscribe" do
|
96
102
|
@queue.subscribe { |msg| "once" }
|
97
103
|
second_subscribe = lambda { @queue.subscribe {|msg| "twice"} }
|
98
|
-
second_subscribe.should raise_error
|
104
|
+
second_subscribe.should raise_error(DoubleSubscribeError)
|
99
105
|
end
|
100
106
|
|
101
107
|
it "should emulate direct exchange publishing" do
|
data/spec/unit/moqueue_spec.rb
CHANGED
@@ -13,7 +13,7 @@ describe ObjectMethods do
|
|
13
13
|
end
|
14
14
|
|
15
15
|
it "should name the queue ``anonymous-RANDOM_GARBAGE'' if not given a name" do
|
16
|
-
@queue.name.should match
|
16
|
+
@queue.name.should match(/anonymous\-[0-9a-f]{0,8}/)
|
17
17
|
end
|
18
18
|
|
19
19
|
it "should name the queue with the name given" do
|
data/spec/unit/overloads_spec.rb
CHANGED
@@ -31,17 +31,25 @@ describe "AMQP and MQ", "when overloaded by moqueue/overloads" do
|
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
34
|
+
it "should create direct exchanges" do
|
35
|
+
MQ.new.direct("directamundo").should == MockExchange.new(:direct => "directamundo")
|
36
|
+
end
|
37
|
+
|
34
38
|
it "should create topic exchanges" do
|
35
39
|
MQ.new.topic("lolzFTW").should == MockExchange.new(:topic => "lolzFTW")
|
36
40
|
end
|
37
41
|
|
42
|
+
it "should provide a MQ.direct class method" do
|
43
|
+
MQ.direct("direct", :durable=>true).should be_a(Moqueue::MockExchange)
|
44
|
+
end
|
45
|
+
|
38
46
|
it "should provide a MQ.fanout class method" do
|
39
|
-
MQ.fanout("fanout", :durable=>true).should be_a
|
47
|
+
MQ.fanout("fanout", :durable=>true).should be_a(Moqueue::MockExchange)
|
40
48
|
end
|
41
49
|
|
42
50
|
it "should create a named fanout queue via MQ.fanout" do
|
43
51
|
fanout = MQ.fanout("SayMyNameSayMyName", :durable=>true)
|
44
|
-
fanout.should be_a
|
52
|
+
fanout.should be_a(Moqueue::MockExchange)
|
45
53
|
fanout.fanout.should == "SayMyNameSayMyName"
|
46
54
|
end
|
47
55
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: danielsdeleo-moqueue
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daniel DeLeo
|
@@ -9,10 +9,19 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-09-21 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
|
-
dependencies:
|
15
|
-
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: amqp
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: "0"
|
24
|
+
version:
|
16
25
|
description: Mocktacular Companion to AMQP Library. Happy TATFTing!
|
17
26
|
email: dan@kallistec.com
|
18
27
|
executables: []
|
@@ -22,13 +31,11 @@ extensions: []
|
|
22
31
|
extra_rdoc_files:
|
23
32
|
- README.rdoc
|
24
33
|
files:
|
25
|
-
-
|
26
|
-
- moqueue.gemspec
|
27
|
-
- Rakefile
|
34
|
+
- CONTRIBUTORS.rdoc
|
28
35
|
- README.rdoc
|
29
|
-
-
|
36
|
+
- Rakefile
|
30
37
|
- VERSION.yml
|
31
|
-
- lib/moqueue
|
38
|
+
- lib/moqueue.rb
|
32
39
|
- lib/moqueue/fibers18.rb
|
33
40
|
- lib/moqueue/matchers.rb
|
34
41
|
- lib/moqueue/mock_broker.rb
|
@@ -37,8 +44,7 @@ files:
|
|
37
44
|
- lib/moqueue/mock_queue.rb
|
38
45
|
- lib/moqueue/object_methods.rb
|
39
46
|
- lib/moqueue/overloads.rb
|
40
|
-
-
|
41
|
-
- spec/examples
|
47
|
+
- moqueue.gemspec
|
42
48
|
- spec/examples/ack_spec.rb
|
43
49
|
- spec/examples/basic_usage_spec.rb
|
44
50
|
- spec/examples/example_helper.rb
|
@@ -47,7 +53,6 @@ files:
|
|
47
53
|
- spec/examples/stocks_spec.rb
|
48
54
|
- spec/spec.opts
|
49
55
|
- spec/spec_helper.rb
|
50
|
-
- spec/unit
|
51
56
|
- spec/unit/matchers_spec.rb
|
52
57
|
- spec/unit/mock_broker_spec.rb
|
53
58
|
- spec/unit/mock_exchange_spec.rb
|
@@ -61,7 +66,6 @@ homepage: http://github.com/danielsdeleo/moqueue
|
|
61
66
|
licenses:
|
62
67
|
post_install_message:
|
63
68
|
rdoc_options:
|
64
|
-
- --inline-source
|
65
69
|
- --charset=UTF-8
|
66
70
|
require_paths:
|
67
71
|
- lib
|
@@ -79,10 +83,24 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
79
83
|
version:
|
80
84
|
requirements: []
|
81
85
|
|
82
|
-
rubyforge_project:
|
86
|
+
rubyforge_project: moqueue
|
83
87
|
rubygems_version: 1.3.5
|
84
88
|
signing_key:
|
85
89
|
specification_version: 3
|
86
90
|
summary: Mocktacular Companion to AMQP Library. Happy TATFTing!
|
87
|
-
test_files:
|
88
|
-
|
91
|
+
test_files:
|
92
|
+
- spec/examples/ack_spec.rb
|
93
|
+
- spec/examples/basic_usage_spec.rb
|
94
|
+
- spec/examples/example_helper.rb
|
95
|
+
- spec/examples/logger_spec.rb
|
96
|
+
- spec/examples/ping_pong_spec.rb
|
97
|
+
- spec/examples/stocks_spec.rb
|
98
|
+
- spec/spec_helper.rb
|
99
|
+
- spec/unit/matchers_spec.rb
|
100
|
+
- spec/unit/mock_broker_spec.rb
|
101
|
+
- spec/unit/mock_exchange_spec.rb
|
102
|
+
- spec/unit/mock_headers_spec.rb
|
103
|
+
- spec/unit/mock_queue_spec.rb
|
104
|
+
- spec/unit/moqueue_spec.rb
|
105
|
+
- spec/unit/object_methods_spec.rb
|
106
|
+
- spec/unit/overloads_spec.rb
|