danielsdeleo-moqueue 0.1.3 → 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,3 @@
1
+ = Contributors
2
+ * larrytheliquid (Larry Diehl) & Engine Yard http://github.com/larrytheliquid
3
+ * mattmatt (Mathias Meyer) & Peritor Consulting http://github.com/mattmatt
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
@@ -1,4 +1,4 @@
1
1
  ---
2
- :major: 0
3
2
  :minor: 1
4
- :patch: 3
3
+ :patch: 4
4
+ :major: 0
@@ -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
 
@@ -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, BindingKey.new(opts[:key])]
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
- BindingKey.new(binding_key).matches?(message_key)
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
- class BindingKey
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
@@ -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
@@ -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
@@ -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.3"
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-07-29}
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 = ["README.rdoc"]
13
- s.files = ["lib", "moqueue.gemspec", "Rakefile", "README.rdoc", "spec", "VERSION.yml", "lib/moqueue", "lib/moqueue/fibers18.rb", "lib/moqueue/matchers.rb", "lib/moqueue/mock_broker.rb", "lib/moqueue/mock_exchange.rb", "lib/moqueue/mock_headers.rb", "lib/moqueue/mock_queue.rb", "lib/moqueue/object_methods.rb", "lib/moqueue/overloads.rb", "lib/moqueue.rb", "spec/examples", "spec/examples/ack_spec.rb", "spec/examples/basic_usage_spec.rb", "spec/examples/example_helper.rb", "spec/examples/logger_spec.rb", "spec/examples/ping_pong_spec.rb", "spec/examples/stocks_spec.rb", "spec/spec.opts", "spec/spec_helper.rb", "spec/unit", "spec/unit/matchers_spec.rb", "spec/unit/mock_broker_spec.rb", "spec/unit/mock_exchange_spec.rb", "spec/unit/mock_headers_spec.rb", "spec/unit/mock_queue_spec.rb", "spec/unit/moqueue_spec.rb", "spec/unit/object_methods_spec.rb", "spec/unit/overloads_spec.rb"]
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 = ["--inline-source", "--charset=UTF-8"]
51
+ s.rdoc_options = ["--charset=UTF-8"]
16
52
  s.require_paths = ["lib"]
17
- s.rubygems_version = %q{1.3.3}
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 Logger
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 Logger.disabled?
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 = Logger.new
101
+ log = MyLoggerRulez.new
102
102
  log.debug 'its working!'
103
103
 
104
- log = Logger.new do |msg|
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 = Logger.new(:webserver, :timestamp, :hostname, &log.printer)
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 }
@@ -18,4 +18,9 @@ def deferred_block_called
18
18
  true
19
19
  end
20
20
 
21
+ def ensure_deferred_block_skipped
22
+ @skip_me = mock("poke_me")
23
+ @skip_me.expects(:deferred_block_called).times(0)
24
+ end
25
+
21
26
  include Moqueue
@@ -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 NoMethodError
48
- e.message.should match /you can't use \`\`should have_received_message\'\' on #\<Object/
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 NoMethodError
89
- e.message.should match /you can't use \`\`should have_received_message\'\' on #\<Object/
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 exchange
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::BindingKey
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 the_second_one
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 ("should really remove the association with exchange")
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 DoubleSubscribeError
104
+ second_subscribe.should raise_error(DoubleSubscribeError)
99
105
  end
100
106
 
101
107
  it "should emulate direct exchange publishing" do
@@ -2,8 +2,4 @@ require File.dirname(__FILE__) + '/../spec_helper'
2
2
 
3
3
  describe Moqueue do
4
4
 
5
- it "should have mocha-like #expects_message('message content') expectations" do
6
- pending("after refactoring: I'm ugly on the inside. like Hollywood")
7
- end
8
-
9
5
  end
@@ -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 /anonymous\-[0-9a-f]{0,8}/
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
@@ -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 Moqueue::MockExchange
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 Moqueue::MockExchange
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.3
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-07-29 00:00:00 -07:00
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
- - lib
26
- - moqueue.gemspec
27
- - Rakefile
34
+ - CONTRIBUTORS.rdoc
28
35
  - README.rdoc
29
- - spec
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
- - lib/moqueue.rb
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