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.
@@ -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