amqp-spec 0.0.4 → 0.1.7

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/HISTORY CHANGED
@@ -17,3 +17,35 @@
17
17
  == 0.0.4 / 2010-10-14
18
18
 
19
19
  * Problems with default_options resolved
20
+
21
+ == 0.1.0 / 2010-10-15
22
+
23
+ * Monkeypatched start/stop_connection into AMQP
24
+
25
+ == 0.1.1 / 2010-10-15
26
+
27
+ * Cleanup in AMQP.cleanup
28
+
29
+ == 0.1.2 / 2010-10-15
30
+
31
+ * Cleanup in AMQP.cleanup
32
+
33
+ == 0.1.3 / 2010-10-15
34
+
35
+ * Make sure Thread.current[:mq] state is cleaned after each example
36
+
37
+ == 0.1.4 / 2010-10-15
38
+
39
+ * Problematic tests fixed
40
+
41
+ == 0.1.5 / 2010-10-15
42
+
43
+ * Clean up debugging output
44
+
45
+ == 0.1.6 / 2010-10-15
46
+
47
+ * README tweaked
48
+
49
+ == 0.1.7 / 2010-10-15
50
+
51
+ * em interface improved for timeout arg
@@ -32,13 +32,19 @@ There are several ways to use amqp-spec. To use it as a helper, include AMQP::Sp
32
32
  You then use either 'amqp' or 'em' methods to wrap your evented test code. Inside the amqp/em block, you must call
33
33
  #done after your expectations. Everything works normally otherwise. You can use default_timeout and default_options
34
34
  macros to avoid manually setting AMQP options in each example. However, if you DO manually set options inside
35
- the example, they override the defaults. Only one set of default options and default timeout is used across groups,
36
- it is not possible to have separate defaults for separate groups.
35
+ the example, they override the defaults. Only default options and default timeout are global across groups,
36
+ it is currently impossible to have separate defaults for separate groups.
37
37
 
38
38
  require "amqp-spec/rspec"
39
39
  describe AMQP do
40
40
  include AMQP::SpecHelper
41
41
 
42
+ default_options :host => 'my.amqp.broker.org', :port => '21118'
43
+ # Can be used to set default options for all your amqp{} event loops
44
+
45
+ default_timeout 1
46
+ # Can be used to set default :spec_timeout for all your amqp-based specs
47
+
42
48
  before(:each) do
43
49
  puts EM.reactor_running?
44
50
  end
@@ -71,7 +77,6 @@ it is not possible to have separate defaults for separate groups.
71
77
  }.should raise_error SpecTimeoutExceededError
72
78
  end
73
79
 
74
- default_timeout 1 # Can be used to set default :spec_timeout for all your amqp-based specs
75
80
  end
76
81
 
77
82
  Another option is to include AMQP::Spec in your describe block. This will patch Rspec so that all of your
@@ -91,9 +96,6 @@ inside the EM loop but before/after AMQP loop (these hooks are currently not imp
91
96
  done
92
97
  end
93
98
 
94
- default_options :host => 'my.amqp.broker.org', :port => '21118'
95
- # Can be used to set default options for all your (implied) amqp{} event loops
96
-
97
99
  it "requires a call to #done in every example" do
98
100
  1.should == 1
99
101
  done
@@ -139,9 +141,6 @@ when including AMQP::Spec, and same caution about using them applies.
139
141
  done
140
142
  }
141
143
  end
142
-
143
- default_timeout 1
144
- # Default spec timeouts can be used same as with AMQP::Spec, default_options (if defined) are not used
145
144
  end
146
145
 
147
146
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.4
1
+ 0.1.7
@@ -3,9 +3,6 @@ require 'version'
3
3
  module AMQP
4
4
  module Spec
5
5
 
6
- # require "bundler"
7
- # Bundler.setup
8
-
9
6
  # Requires ruby source file(s). Accepts either single filename/glob or Array of filenames/globs.
10
7
  # Accepts following options:
11
8
  # :*file*:: Lib(s) required relative to this file - defaults to __FILE__
@@ -1,5 +1,5 @@
1
- require 'mq'
2
1
  require 'fiber' unless Fiber.respond_to?(:current)
2
+ require 'mq'
3
3
 
4
4
  # You can include one of the following modules into your example groups:
5
5
  # AMQP::SpecHelper
@@ -19,9 +19,37 @@ require 'fiber' unless Fiber.respond_to?(:current)
19
19
  # For example, if you are using subscribe block that tests expectations on messages, 'done' should be
20
20
  # probably called at the end of this block.
21
21
  #
22
- # TODO: Define 'async' method wrapping async requests and returning results... 'async_loop' too for subscribe?
22
+ # TODO: Define 'async' method wrapping async requests and returning results... 'async_loop' too for subscribe block?
23
23
  # TODO: 'evented_before', 'evented_after' that will be run inside EM before the example
24
24
  module AMQP
25
+
26
+ # Initializes new AMQP client/connection without starting another EM loop
27
+ def self.start_connection opts={}, &block
28
+ # puts "!!!!!!!!! Existing connection: #{@conn}" if @conn
29
+ @conn = connect opts
30
+ @conn.callback(&block) if block
31
+ end
32
+
33
+ # Closes AMQP connection and raises optional exception AFTER the AMQP connection is 100% closed
34
+ def self.stop_connection
35
+ if AMQP.conn and not AMQP.closing
36
+ # MQ.reset ?
37
+ @closing = true
38
+ @conn.close {
39
+ yield if block_given?
40
+ cleanup_state
41
+ }
42
+ end
43
+ end
44
+
45
+ def self.cleanup_state
46
+ # MQ.reset ?
47
+ Thread.current[:mq] = nil
48
+ Thread.current[:mq_id] = nil
49
+ @conn = nil
50
+ @closing = false
51
+ end
52
+
25
53
  module SpecHelper
26
54
 
27
55
  SpecTimeoutExceededError = Class.new(RuntimeError)
@@ -40,6 +68,7 @@ module AMQP
40
68
  @@_em_default_timeout
41
69
  end
42
70
  end
71
+
43
72
  alias default_timeout default_spec_timeout
44
73
 
45
74
  def self.default_options(opts=nil)
@@ -66,31 +95,37 @@ module AMQP
66
95
 
67
96
  def amqp opts={}, &block
68
97
  opts = @@_em_default_options.merge opts
69
- EM.run do
98
+ begin
99
+ EM.run do
70
100
  # begin ?
71
- @_em_spec_with_amqp = true
72
- @_em_spec_exception = nil
73
- spec_timeout = opts.delete(:spec_timeout) || @@_em_default_timeout
74
- timeout(spec_timeout) if spec_timeout
75
- @_em_spec_fiber = Fiber.new do
76
- begin
77
- amqp_start opts, &block
78
- rescue Exception => @_em_spec_exception
79
- p @_em_spec_exception
80
- done
101
+ @_em_spec_with_amqp = true
102
+ @_em_spec_exception = nil
103
+ spec_timeout = opts.delete(:spec_timeout) || @@_em_default_timeout
104
+ timeout(spec_timeout) if spec_timeout
105
+ @_em_spec_fiber = Fiber.new do
106
+ begin
107
+ AMQP.start_connection opts, &block
108
+ rescue Exception => @_em_spec_exception
109
+ # p "inner", @_em_spec_exception
110
+ done
111
+ end
112
+ Fiber.yield
81
113
  end
82
- Fiber.yield
83
- end
84
114
 
85
- @_em_spec_fiber.resume
86
- # raise @_em_spec_exception if @_em_spec_exception
115
+ @_em_spec_fiber.resume
116
+ end
117
+ rescue Exception => outer_spec_exception
118
+ # p "outer", outer_spec_exception unless outer_spec_exception.is_a? SpecTimeoutExceededError
119
+ # Makes sure AMQP state is cleaned even after Rspec failures
120
+ AMQP.cleanup_state
121
+ raise outer_spec_exception
87
122
  end
88
123
  end
89
124
 
90
125
  # Yields to block inside EM loop, :spec_timeout option (in seconds) is used to force spec to timeout
91
126
  # if something goes wrong and EM/AMQP loop hangs for some reason. SpecTimeoutExceededError is raised.
92
- # TODO: accept :spec_timeout =>1 as a Hash for compatibility with amqp interface
93
127
  def em(spec_timeout = @@_em_default_timeout, &block)
128
+ spec_timeout = spec_timeout[:spec_timeout] || @@_em_default_timeout if spec_timeout.is_a?(Hash)
94
129
  EM.run do
95
130
  @_em_spec_with_amqp = false
96
131
  @_em_spec_exception = nil
@@ -117,53 +152,31 @@ module AMQP
117
152
  end
118
153
  end
119
154
 
120
- # Stops AMQP and EM event loop
155
+ # Stops EM event loop, for amqp specs stops AMQP and cleans up its state
121
156
  def done
122
157
  EM.next_tick do
123
158
  if @_em_spec_with_amqp
124
- amqp_stop(@_em_spec_exception) do
125
- finish_em_spec_fiber
159
+ if AMQP.conn and not AMQP.closing
160
+ AMQP.stop_connection do
161
+ finish_em_spec_fiber { AMQP.cleanup_state }
162
+ end
163
+ else
164
+ finish_em_spec_fiber { AMQP.cleanup_state }
126
165
  end
127
166
  else
128
167
  finish_em_spec_fiber
129
- raise @_em_spec_exception if @_em_spec_exception
130
168
  end
131
169
  end
132
170
  end
133
171
 
134
172
  private
135
173
 
174
+ # Stops EM loop, executes optional block, finishes off fiber and raises exception if any
136
175
  def finish_em_spec_fiber
137
176
  EM.stop_event_loop if EM.reactor_running?
138
- # p Thread.current, Thread.current[:mq], __LINE__
177
+ yield if block_given?
139
178
  @_em_spec_fiber.resume if @_em_spec_fiber.alive?
140
- end
141
-
142
- # Private method that initializes AMQP client/connection without starting another EM loop
143
- def amqp_start opts={}, &block
144
- AMQP.instance_exec do
145
- # p Thread.current, Thread.current[:mq]
146
- puts "!!!!!!!!! Existing connection: #{@conn}" if @conn
147
- @conn = connect opts
148
- # @conn ||= connect opts
149
- @conn.callback(&block) if block
150
- end
151
- end
152
-
153
- # Private method that closes AMQP connection and raises optional
154
- # exception AFTER the AMQP connection is 100% closed
155
- def amqp_stop exception
156
- if AMQP.conn and not AMQP.closing
157
- AMQP.instance_exec do #(@_em_spec_exception) do |exception|
158
- @closing = true
159
- @conn.close {
160
- yield if block_given?
161
- @conn = nil
162
- @closing = false
163
- raise exception if exception
164
- }
165
- end
166
- end
179
+ raise @_em_spec_exception if @_em_spec_exception
167
180
  end
168
181
  end
169
182
 
@@ -191,5 +204,3 @@ module AMQP
191
204
  end
192
205
  end
193
206
  end
194
-
195
-
@@ -0,0 +1,5 @@
1
+ require_relative 'spec_helper.rb'
2
+
3
+ context '!!!!!!!!! LEAKING OR PROBLEMATIC EXAMPLES !!!!!!!!!' do
4
+ end
5
+
@@ -6,185 +6,71 @@ describe 'Rspec' do
6
6
  end
7
7
  end
8
8
 
9
+ def publish_and_consume_once(queue_name="test_sink", data="data")
10
+ amqp do
11
+ q = MQ.queue(queue_name)
12
+ q.subscribe do |hdr, msg|
13
+ hdr.should be_an MQ::Header
14
+ msg.should == data
15
+ EM.next_tick {
16
+ q.unsubscribe; q.delete
17
+ done
18
+ }
19
+ end
20
+ EM.add_timer(0.2) do
21
+ MQ.queue(queue_name).publish data
22
+ end
23
+ end
24
+ end
25
+
9
26
  context 'Evented AMQP specs' do
10
27
  describe AMQP, " when testing with AMQP::SpecHelper" do
11
28
  include AMQP::SpecHelper
12
- after(:each) do
13
- EM.reactor_running?.should == false
14
- AMQP.conn.should be_nil
15
- end
16
29
 
17
30
  default_options AMQP_OPTS if defined? AMQP_OPTS
18
31
  default_timeout 1 # Can be used to set default :spec_timeout for all your amqp-based specs
19
32
 
20
- p default_timeout, default_options
21
-
22
- it "should not require a call to done when #em/#amqp is not used" do
23
- 1.should == 1
24
- end
25
-
26
- it "should properly work" do
27
- amqp do
28
- done
29
- end
30
- end
31
-
32
- it "should have timers" do
33
- amqp do
34
- start = Time.now
35
-
36
- EM.add_timer(0.5) {
37
- (Time.now-start).should be_close(0.5, 0.1)
38
- done
39
- }
40
- end
41
- end
42
-
43
- it "should run AMQP.start loop with options given to #amqp" do
44
- amqp(:vhost => '/', :user => 'guest') do
45
- AMQP.conn.should be_connected
46
- done
47
- end
48
- end
49
-
50
- it "should properly close AMQP connection if block completes normally" do
51
- amqp do
52
- AMQP.conn.should be_connected
53
- done
54
- end
55
- AMQP.conn.should be_nil
56
- end
57
-
58
- it 'should have deferrables' do
59
- amqp do
60
- defr = EM::DefaultDeferrable.new
61
- defr.timeout(0.5)
62
- defr.errback {
63
- done
64
- }
65
- end
66
- end
67
-
68
- context 'on exceptions/failures' do
69
- # default_timeout 1 # Can be used to set default :spec_timeout for all your amqp-based specs
33
+ puts "Default timeout: #{default_timeout.inspect}, Default options:"
34
+ p default_options
70
35
 
36
+ it_should_behave_like 'SpecHelper examples'
37
+ it_should_behave_like 'timeout examples'
71
38
 
39
+ context 'inside embedded context / example group' do
40
+ it_should_behave_like 'SpecHelper examples'
41
+ it_should_behave_like 'timeout examples'
72
42
  end
73
43
  end
74
44
 
75
45
  describe AMQP, " when testing with AMQP::Spec" do
76
46
  include AMQP::Spec
77
- after(:each) do
78
- EM.reactor_running?.should == true
79
- done
80
- end
81
-
82
- it 'should work' do
83
- done
84
- end
47
+ it_should_behave_like 'Spec examples'
85
48
 
86
- it 'should have timers' do
87
- start = Time.now
88
-
89
- EM.add_timer(0.5) {
90
- (Time.now-start).should be_close(0.5, 0.1)
91
- done
92
- }
93
- end
94
-
95
- it 'should have periodic timers' do
96
- num = 0
97
- start = Time.now
98
-
99
- timer = EM.add_periodic_timer(0.25) {
100
- if (num += 1) == 2
101
- (Time.now-start).should be_close(0.5, 0.1)
102
- EM.cancel_timer timer
103
- done
104
- end
105
- }
106
- end
107
-
108
- it 'should have deferrables' do
109
- defr = EM::DefaultDeferrable.new
110
- defr.timeout(0.5)
111
- defr.errback {
112
- done
113
- }
49
+ context 'inside embedded context / example group' do
50
+ it_should_behave_like 'Spec examples'
114
51
  end
115
52
  end
116
53
 
117
- shared_examples_for 'timeout examples' do
54
+ describe AMQP, " tested with AMQP::SpecHelper when Rspec failures occur" do
118
55
  include AMQP::SpecHelper
119
- before(:each) { @start = Time.now }
120
56
 
121
- it 'should timeout before reaching done because of default spec timeout' do
57
+ it "bubbles failing expectations up to Rspec" do
122
58
  proc {
123
59
  amqp do
124
- EM.add_timer(2) { done }
125
- end
126
- }.should raise_error SpecTimeoutExceededError
127
- (Time.now-@start).should be_close(1.0, 0.1)
128
- end
129
-
130
- it 'should timeout before reaching done because of explicit in-loop timeout' do
131
- proc {
132
- amqp do
133
- timeout(0.2)
134
- EM.add_timer(0.5) { done }
60
+ :this.should == :fail
135
61
  end
136
- }.should raise_error SpecTimeoutExceededError
137
- (Time.now-@start).should be_close(0.2, 0.1)
138
- end
139
-
140
- specify "spec timeout given in amqp options has higher priority than default" do
141
- proc {
142
- amqp(:spec_timeout => 0.2) {}
143
- }.should raise_error SpecTimeoutExceededError
144
- (Time.now-@start).should be_close(0.2, 0.1)
62
+ }.should raise_error Spec::Expectations::ExpectationNotMetError
63
+ AMQP.conn.should == nil
145
64
  end
146
65
 
147
- specify "but timeout call inside amqp loop has even higher priority" do
66
+ it "should NOT ignore failing expectations after 'done'" do
148
67
  proc {
149
- amqp(:spec_timeout => 0.5) { timeout(0.2) }
150
- }.should raise_error SpecTimeoutExceededError
151
- (Time.now-@start).should be_close(0.2, 0.1)
152
- end
153
-
154
- specify "AMQP connection should not leak between examples" do
155
- AMQP.conn.should be_nil
156
- end
157
- end
158
-
159
- describe AMQP, " when testing with AMQP::SpecHelper with spec timeouts" do
160
- it_should_behave_like 'timeout examples'
161
-
162
- context 'inside embedded context / example group' do
163
- it_should_behave_like 'timeout examples'
164
- # it "should properly timeout " do
165
- # amqp do
166
- # timeout(0.2)
167
- # end
168
- # end
169
- # it "should properly timeout inside embedded context/describe blocks" do
170
- # amqp do
171
- # end
172
- # end
173
- end
174
- end
175
-
176
- # PROBLEMATIC !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
177
- describe AMQP, " when testing with AMQP::SpecHelper with spec timeouts" do
178
- include AMQP::SpecHelper
179
-
180
- it "should fail to provide context to next spec" do
181
- begin
182
68
  amqp do
69
+ done
183
70
  :this.should == :fail
184
71
  end
185
- rescue => e
186
- p e
187
- end
72
+ }.should raise_error Spec::Expectations::ExpectationNotMetError
73
+ AMQP.conn.should == nil
188
74
  end
189
75
 
190
76
  it "should properly close AMQP connection after Rspec failures" do
@@ -192,80 +78,23 @@ context 'Evented AMQP specs' do
192
78
  end
193
79
  end
194
80
 
195
- # describe MQ, " when MQ.queue or MQ.fanout etc is trying to access Thread-local mq across examples" do
196
- # include AMQP::SpecHelper
197
- #
198
- # default_timeout 1
199
- #
200
- # it 'sends data to queue' do
201
- # amqp do
202
- # q = MQ.new.queue("test_sink")
203
- # q.subscribe do |hdr, data|
204
- # p hdr, data
205
- # EM.next_tick {
206
- # q.unsubscribe; q.delete
207
- # AMQP.stop { EM.stop_event_loop }
208
- # }
209
- # end
210
- # EM.add_timer(0.2) do
211
- # p Thread.current, Thread.current[:mq]
212
- # MQ.queue('test_sink').publish 'data' # MQ.new. !!!!!!!!!!!
213
- # end
214
- # end
215
- # end
216
- #
217
- # it 'sends data to queue' do
218
- # amqp do
219
- # q = MQ.new.queue("test_sink")
220
- # q.subscribe do |hdr, data|
221
- # p hdr, data
222
- # EM.next_tick {
223
- # q.unsubscribe; q.delete
224
- # AMQP.stop { EM.stop_event_loop }
225
- # }
226
- # end
227
- # EM.add_timer(0.2) do
228
- # p Thread.current, Thread.current[:mq]
229
- # MQ.queue('test_sink').publish 'data' # MQ.new. !!!!!!!!!!!
230
- # end
231
- # end
232
- # end
233
- #
234
- # end
235
- end
236
-
237
- context '!!!!!!!!!!! LEAKING !!!!!!!!!!!!!!!!!!' do
238
- describe EventMachine, " when running failing examples" do
81
+ describe 'MQ', " when MQ.queue/fanout/topic tries to access Thread.current[:mq] across examples" do
239
82
  include AMQP::SpecHelper
240
83
 
241
- it "should not bubble failures beyond rspec" do
242
- amqp do
243
- EM.add_timer(0.1) do
244
- :should_not_bubble.should == :failures
245
- done
246
- end
247
- end
248
- AMQP.conn.should == nil
84
+ it 'sends data to queue' do
85
+ publish_and_consume_once
249
86
  end
250
87
 
251
- it "should not block on failure" do
252
- 1.should == 2
88
+ it 'sends data to queue, again' do
89
+ publish_and_consume_once
253
90
  end
254
- end
255
-
256
- describe EventMachine, " when testing with AMQP::Spec with a maximum execution time per test" do
257
91
 
258
- include AMQP::Spec
259
-
260
- it 'should timeout before reaching done' do
261
- EM.add_timer(2) {
262
- done
263
- }
92
+ it 'cleans Thread.current[:mq] after pubsub examples' do
93
+ Thread.current[:mq].should be_nil
264
94
  end
265
95
  end
266
96
  end
267
97
 
268
-
269
98
  describe "Rspec", " when running an example group after another group that uses AMQP-Spec " do
270
99
  it "should work normally" do
271
100
  :does_not_hang.should_not be_false
@@ -18,44 +18,38 @@ context 'Plain EM, no AMQP' do
18
18
  }
19
19
  end
20
20
  end
21
- end
22
-
23
- describe EventMachine, " when testing with AMQP::Spec" do
24
- include AMQP::EMSpec
25
21
 
26
- it 'should work' do
27
- done
28
- end
29
-
30
- it 'should have timers' do
22
+ it "should be possible to set spec timeouts as a number of secounds" do
31
23
  start = Time.now
24
+ proc {
25
+ em(0.5) do
32
26
 
33
- EM.add_timer(0.5) {
34
- (Time.now-start).should be_close(0.5, 0.1)
35
- done
36
- }
27
+ EM.add_timer(1) {
28
+ done
29
+ }
30
+ end
31
+ }.should raise_error SpecTimeoutExceededError
32
+ (Time.now-start).should be_close(0.5, 0.1)
37
33
  end
38
34
 
39
- it 'should have periodic timers' do
40
- num = 0
35
+ it "should be possible to set spec timeout as an option (amqp interface compatibility)" do
41
36
  start = Time.now
37
+ proc {
38
+ em(0.5) do
42
39
 
43
- timer = EM.add_periodic_timer(0.2) {
44
- if (num += 1) == 2
45
- (Time.now-start).should be_close(0.4, 0.1)
46
- EM.__send__ :cancel_timer, timer
47
- done
40
+ EM.add_timer(1) {
41
+ done
42
+ }
48
43
  end
49
- }
44
+ }.should raise_error SpecTimeoutExceededError
45
+ (Time.now-start).should be_close(0.5, 0.1)
50
46
  end
47
+ end
51
48
 
52
- it 'should have deferrables' do
53
- defr = EM::DefaultDeferrable.new
54
- defr.timeout(0.5)
55
- defr.errback {
56
- done
57
- }
58
- end
49
+ describe EventMachine, " when testing with AMQP::Spec" do
50
+ include AMQP::EMSpec
51
+
52
+ it_should_behave_like 'Spec examples'
59
53
 
60
54
  end
61
55
  end
@@ -0,0 +1,147 @@
1
+ shared_examples_for 'SpecHelper examples' do
2
+ after(:each) do
3
+ EM.reactor_running?.should == false
4
+ AMQP.conn.should be_nil
5
+ end
6
+
7
+ it "should not require a call to done when #em/#amqp is not used" do
8
+ 1.should == 1
9
+ end
10
+
11
+ it "should properly work" do
12
+ amqp do
13
+ done
14
+ end
15
+ end
16
+
17
+ it "should have timers" do
18
+ amqp do
19
+ start = Time.now
20
+
21
+ EM.add_timer(0.5) {
22
+ (Time.now-start).should be_close(0.5, 0.1)
23
+ done
24
+ }
25
+ end
26
+ end
27
+
28
+ it 'should have deferrables' do
29
+ amqp do
30
+ defr = EM::DefaultDeferrable.new
31
+ defr.timeout(0.5)
32
+ defr.errback {
33
+ done
34
+ }
35
+ end
36
+ end
37
+
38
+ it "should run AMQP.start loop with options given to #amqp" do
39
+ amqp(:vhost => '/', :user => 'guest') do
40
+ AMQP.conn.should be_connected
41
+ done
42
+ end
43
+ end
44
+
45
+ it "should properly close AMQP connection if block completes normally" do
46
+ amqp do
47
+ AMQP.conn.should be_connected
48
+ done
49
+ end
50
+ AMQP.conn.should be_nil
51
+ end
52
+
53
+ it "should gracefully exit if no AMQP connection was made" do
54
+ proc {
55
+ amqp(:host => 'Impossible') do
56
+ AMQP.conn.should be_nil
57
+ done
58
+ end
59
+ }.should raise_error EventMachine::ConnectionError
60
+ AMQP.conn.should be_nil
61
+ end
62
+ end
63
+
64
+ shared_examples_for 'Spec examples' do
65
+ after(:each) do
66
+ EM.reactor_running?.should == true
67
+ # AMQP.conn.should be_nil # You're inside running amqp block, stupid!
68
+ done
69
+ end
70
+
71
+ it 'should work' do
72
+ done
73
+ end
74
+
75
+ it 'should have timers' do
76
+ start = Time.now
77
+
78
+ EM.add_timer(0.5) {
79
+ (Time.now-start).should be_close(0.5, 0.1)
80
+ done
81
+ }
82
+ end
83
+
84
+ it 'should have periodic timers' do
85
+ num = 0
86
+ start = Time.now
87
+
88
+ timer = EM.add_periodic_timer(0.25) {
89
+ if (num += 1) == 2
90
+ (Time.now-start).should be_close(0.5, 0.1)
91
+ EM.cancel_timer timer
92
+ done
93
+ end
94
+ }
95
+ end
96
+
97
+ it 'should have deferrables' do
98
+ defr = EM::DefaultDeferrable.new
99
+ defr.timeout(0.5)
100
+ defr.errback {
101
+ done
102
+ }
103
+ end
104
+ end
105
+
106
+ shared_examples_for 'timeout examples' do
107
+ before(:each) { @start = Time.now }
108
+
109
+ it 'should timeout before reaching done because of default spec timeout' do
110
+ proc {
111
+ amqp do
112
+ EM.add_timer(2) { done }
113
+ end
114
+ }.should raise_error SpecTimeoutExceededError
115
+ (Time.now-@start).should be_close(1.0, 0.1)
116
+ end
117
+
118
+ it 'should timeout before reaching done because of explicit in-loop timeout' do
119
+ proc {
120
+ amqp do
121
+ timeout(0.2)
122
+ EM.add_timer(0.5) { done }
123
+ end
124
+ }.should raise_error SpecTimeoutExceededError
125
+ (Time.now-@start).should be_close(0.2, 0.1)
126
+ end
127
+
128
+ specify "spec timeout given in amqp options has higher priority than default" do
129
+ proc {
130
+ amqp(:spec_timeout => 0.2) {}
131
+ }.should raise_error SpecTimeoutExceededError
132
+ (Time.now-@start).should be_close(0.2, 0.1)
133
+ end
134
+
135
+ specify "but timeout call inside amqp loop has even higher priority" do
136
+ proc {
137
+ amqp(:spec_timeout => 0.5) { timeout(0.2) }
138
+ }.should raise_error SpecTimeoutExceededError
139
+ (Time.now-@start).should be_close(0.2, 0.1)
140
+ end
141
+
142
+ specify "AMQP connection should not leak between examples" do
143
+ AMQP.conn.should be_nil
144
+ end
145
+ end
146
+
147
+
@@ -5,7 +5,9 @@ $LOAD_PATH << "." unless $LOAD_PATH.include? "." # moronic 1.9.2 breaks things b
5
5
  require 'spec'
6
6
  require 'yaml'
7
7
 
8
- require File.join(File.dirname(__FILE__), '..', 'lib', 'amqp-spec', 'rspec.rb')
8
+ require 'amqp-spec/rspec'
9
+ require 'shared_examples'
10
+ #require File.join(File.dirname(__FILE__), '..', 'lib', 'amqp-spec', 'rspec.rb')
9
11
 
10
12
  amqp_config = File.dirname(__FILE__) + '/amqp.yml'
11
13
  if File.exists? amqp_config
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: amqp-spec
3
3
  version: !ruby/object:Gem::Version
4
- hash: 23
4
+ hash: 21
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
- - 0
9
- - 4
10
- version: 0.0.4
8
+ - 1
9
+ - 7
10
+ version: 0.1.7
11
11
  platform: ruby
12
12
  authors:
13
13
  - Arvicco
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-10-14 00:00:00 +04:00
18
+ date: 2010-10-15 00:00:00 +04:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -50,8 +50,10 @@ files:
50
50
  - lib/version.rb
51
51
  - spec/amqp.yml
52
52
  - spec/failing_rspec_spec.rb
53
+ - spec/problematic_rspec_spec.rb
53
54
  - spec/rspec_amqp_spec.rb
54
55
  - spec/rspec_em_spec.rb
56
+ - spec/shared_examples.rb
55
57
  - spec/spec.opts
56
58
  - spec/spec_helper.rb
57
59
  - tasks/common.rake
@@ -108,7 +110,9 @@ summary: Simple API for writing (asynchronous) AMQP specs
108
110
  test_files:
109
111
  - spec/amqp.yml
110
112
  - spec/failing_rspec_spec.rb
113
+ - spec/problematic_rspec_spec.rb
111
114
  - spec/rspec_amqp_spec.rb
112
115
  - spec/rspec_em_spec.rb
116
+ - spec/shared_examples.rb
113
117
  - spec/spec.opts
114
118
  - spec/spec_helper.rb