amqp-spec 0.0.4 → 0.1.7

Sign up to get free protection for your applications and to get access to all the features.
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