deferred 0.5.3

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,297 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Deferred::InstanceMethods' do
4
+ # test Deferred::Default, as it mixes this in
5
+
6
+ before do
7
+ @dd = Deferred::Default.new
8
+ end
9
+
10
+ it %[should set a callback and return self] do
11
+ cb_called = nil
12
+
13
+ rval = @dd.callback { cb_called = true }
14
+ rval.should == @dd
15
+
16
+ @dd.succeed
17
+ cb_called.should be_true
18
+ end
19
+
20
+ it %[should set an errback and return self] do
21
+ eb_called = nil
22
+
23
+ rval = @dd.errback { eb_called = true }
24
+ rval.should == @dd
25
+
26
+ @dd.fail
27
+ eb_called.should be_true
28
+ end
29
+
30
+ describe 'ensure_that' do
31
+ before do
32
+ @block_called = false
33
+ @rval = @dd.ensure_that { @block_called = true }
34
+ end
35
+
36
+ it %[should return self] do
37
+ @rval.should == @dd
38
+ end
39
+
40
+ it %[should set a callback] do
41
+ @dd.succeed
42
+ @block_called.should be_true
43
+ end
44
+
45
+ it %[should set an errback] do
46
+ @dd.fail
47
+ @block_called.should be_true
48
+ end
49
+ end
50
+
51
+ describe 'errback_on_exception' do
52
+ it %[should fire the errback with the exception instance as an argument] do
53
+ @dd.errback do |exc|
54
+ exc.should be_instance_of(RuntimeError)
55
+ end
56
+
57
+ @dd.errback_on_exception do
58
+ raise "Oh noes!"
59
+ end
60
+ end
61
+
62
+ it %[should do the right thing when errback is a proc] do
63
+ eb = proc do |exc|
64
+ exc.should be_instance_of(RuntimeError)
65
+ end
66
+
67
+ @dd.errback(&eb)
68
+
69
+ @dd.errback_on_exception do
70
+ raise "Oh noes!"
71
+ end
72
+ end
73
+
74
+ it %[should do the right thing when errback is a lambda] do
75
+ eb = lambda do |exc|
76
+ exc.should be_instance_of(RuntimeError)
77
+ end
78
+
79
+ @dd.errback(&eb)
80
+
81
+ @dd.errback_on_exception do
82
+ raise "Oh noes!"
83
+ end
84
+ end
85
+ end
86
+
87
+ describe 'timeout' do
88
+ include EventedSpec::SpecHelper
89
+ default_timeout 1.0
90
+
91
+ class TestTimeoutError < StandardError; end
92
+ class OtherTestTimeoutError < StandardError; end
93
+
94
+ it %[should fire the errback with no arguments if an exception_klass is not given] do
95
+ @dd.errback do |*a|
96
+ a.should be_empty
97
+ done
98
+ end
99
+
100
+ em do
101
+ @dd.timeout(0.01)
102
+ end
103
+ end
104
+
105
+ it %[should fire the errback with an instance of the given klass if given] do
106
+ @dd.errback do |*a|
107
+ a.length.should == 1
108
+ exc = a.first
109
+ exc.should be_kind_of(TestTimeoutError)
110
+ exc.backtrace.should_not be_nil
111
+
112
+ done
113
+ end
114
+
115
+ em do
116
+ @dd.timeout(0.01, TestTimeoutError)
117
+ end
118
+
119
+ end
120
+
121
+ # make sure this is compatible with the rest of EM::Deferrable
122
+ it %[should not fire the timeout if cancel_timeout is called] do
123
+ @dd.errback { raise "This should not have been called" }
124
+ @dd.callback { done }
125
+
126
+ em do
127
+ @dd.timeout(0.3) # set the timeout
128
+
129
+ delayed(0.1) { @dd.cancel_timeout }
130
+ delayed(0.4) { @dd.succeed }
131
+ end
132
+ end
133
+
134
+ it %[should reset the timeout if timeout is called a second time] do
135
+ @dd.errback do |e|
136
+ e.should be_kind_of(OtherTestTimeoutError)
137
+ done
138
+ end
139
+
140
+ em do
141
+ @dd.timeout(0.2, TestTimeoutError) # set the first timeout
142
+
143
+ # cancel the first timeout before it can fire, raise a different error
144
+ delayed(0.1) { @dd.timeout(0, OtherTestTimeoutError) }
145
+ end
146
+ end
147
+ end # describe timeout
148
+
149
+ describe 'chain_to' do
150
+ before do
151
+ @one = Deferred::Default.new
152
+ @two = Deferred::Default.new
153
+ end
154
+
155
+ it %[should call the second's callbacks with the results of the first] do
156
+ @two.chain_to(@one)
157
+
158
+ callback_called = nil
159
+
160
+ @two.callback do |*args|
161
+ args.should_not be_empty
162
+ args.first.should == 'boogers'
163
+ callback_called = true
164
+ end
165
+
166
+ @one.succeed('boogers')
167
+ callback_called.should be_true
168
+ end
169
+
170
+ it %[should call the second's errbacks with the fail of the first] do
171
+ @two.chain_to(@one)
172
+
173
+ errback_called = nil
174
+
175
+ @two.errback do |*args|
176
+ args.should_not be_empty
177
+ args.first.should == 'boogers'
178
+ errback_called = true
179
+ end
180
+
181
+ @one.fail('boogers')
182
+ errback_called.should be_true
183
+ end
184
+
185
+ it %[should return self] do
186
+ @two.chain_to(@one).should == @two
187
+ end
188
+
189
+ it %[should not add the errback if :ignore_errors is true] do
190
+ @two.chain_to(@one, :ignore_errors => true)
191
+
192
+ one_errback_called = two_errback_called = false
193
+
194
+ @two.callback do |*a|
195
+ callback_called = true
196
+ end
197
+
198
+ @two.errback do |*args|
199
+ args.should_not be_empty
200
+ args.first.should == 'boogers'
201
+ two_errback_called = true
202
+ end
203
+
204
+ @one.errback do |*a|
205
+ one_errback_called = true
206
+ end
207
+
208
+ @one.fail('boogers')
209
+ one_errback_called.should be_true
210
+ two_errback_called.should be_false
211
+ end
212
+
213
+ it %[should add the errback if :only_errors is true] do
214
+ @two.chain_to(@one, :only_errors => true)
215
+
216
+ one_errback_called = two_errback_called = false
217
+
218
+ @one.errback do |*a|
219
+ one_errback_called = true
220
+ end
221
+
222
+ @two.errback do |*args|
223
+ args.should_not be_empty
224
+ args.first.should == 'boogers'
225
+ two_errback_called = true
226
+ end
227
+
228
+ @one.fail('boogers')
229
+
230
+ one_errback_called.should be_true
231
+ two_errback_called.should be_true
232
+ end
233
+
234
+ it %[should not add the callback if :only_errors is true] do
235
+ @two.chain_to(@one, :only_errors => true)
236
+
237
+ one_errback_called = two_errback_called =
238
+ one_callback_called = two_callback_called = false
239
+
240
+ @one.errback { |*| one_errback_called = true }
241
+ @one.callback { |*| one_callback_called = true }
242
+ @two.errback { |*| two_errback_called = true }
243
+ @two.callback { |*| two_callback_called = true }
244
+
245
+ @one.succeed('boogers')
246
+
247
+ one_callback_called.should be_true
248
+ two_callback_called.should be_false
249
+ end
250
+ end
251
+
252
+ describe 'chain_err' do
253
+ before do
254
+ @one = Deferred::Default.new
255
+ @two = Deferred::Default.new
256
+ end
257
+
258
+ it %[should chain the errbacks] do
259
+ @two.chain_to(@one, :only_errors => true)
260
+
261
+ one_errback_called = two_errback_called = false
262
+
263
+ @one.errback do |*a|
264
+ one_errback_called = true
265
+ end
266
+
267
+ @two.errback do |*args|
268
+ args.should_not be_empty
269
+ args.first.should == 'boogers'
270
+ two_errback_called = true
271
+ end
272
+
273
+ @one.fail('boogers')
274
+
275
+ one_errback_called.should be_true
276
+ two_errback_called.should be_true
277
+ end
278
+
279
+ it %[should not add the callback if :only_errors is true] do
280
+ @two.chain_to(@one, :only_errors => true)
281
+
282
+ one_errback_called = two_errback_called =
283
+ one_callback_called = two_callback_called = false
284
+
285
+ @one.errback { |*| one_errback_called = true }
286
+ @one.callback { |*| one_callback_called = true }
287
+ @two.errback { |*| two_errback_called = true }
288
+ @two.callback { |*| two_callback_called = true }
289
+
290
+ @one.succeed('boogers')
291
+
292
+ one_callback_called.should be_true
293
+ two_callback_called.should be_false
294
+ end
295
+ end
296
+ end
297
+
@@ -0,0 +1,172 @@
1
+ require 'spec_helper'
2
+
3
+ describe Deferred::ThreadpoolJob do
4
+
5
+ describe 'defer!' do
6
+ include EventedSpec::SpecHelper
7
+ default_timeout 3.0
8
+
9
+ it %[should barf with an OnRunBlockNotRegisteredError if on_run was not called] do
10
+ tpj = Deferred::DefaultThreadpoolJob.new
11
+ lambda { tpj.defer! }.should raise_error(Deferred::OnRunBlockNotRegisteredError)
12
+ end
13
+
14
+ it %[should use a block passed to new as the on_run_block] do
15
+ orb = lambda { $stderr.puts "hooray!" }
16
+ tpj = Deferred::DefaultThreadpoolJob.new(&orb)
17
+
18
+ tpj.on_run_block.should == orb
19
+ end
20
+
21
+ describe 'success' do
22
+ before do
23
+ @rval = %w[foo bar]
24
+ @tpj = Deferred::DefaultThreadpoolJob.new { @rval }
25
+ end
26
+
27
+ it %[should call the callback if the block succeeds] do
28
+ cb_called = false
29
+
30
+ @tpj.callback do |result|
31
+ cb_called = true
32
+ result.should == @rval
33
+ done
34
+ end
35
+
36
+ em do
37
+ @tpj.defer!
38
+ end
39
+
40
+ cb_called.should be_true
41
+ end
42
+
43
+ it %[should fire the before_run callbacks before deferring the job] do
44
+ cb_ary = []
45
+
46
+ @tpj.before_run do
47
+ cb_ary << :before_run
48
+ end
49
+
50
+ @tpj.callback do |*a|
51
+ cb_ary << :after_run
52
+ end
53
+
54
+ @tpj.ensure_that do
55
+ cb_ary.should == [:before_run, :after_run]
56
+ done
57
+ end
58
+
59
+ em do
60
+ @tpj.defer!
61
+ end
62
+ end
63
+ end
64
+
65
+ describe 'failure' do
66
+ before do
67
+ @tpj = Deferred::DefaultThreadpoolJob.new { raise BollocksError }
68
+ end
69
+
70
+ it %[should fire the errbacks in the chain] do
71
+ @tpj.errback do |exc|
72
+ exc.should be_instance_of(BollocksError)
73
+ done
74
+ end
75
+
76
+ em do
77
+ @tpj.defer!
78
+ end
79
+ end
80
+ end # describe 'failure'
81
+
82
+ describe 'on_run returns a ThreadpoolJob' do
83
+ describe 'success' do
84
+ before do
85
+ @rval = %w[one two]
86
+ @sub_job = Deferred::DefaultThreadpoolJob.new { @rval }
87
+ @first_job = Deferred::DefaultThreadpoolJob.new { @sub_job }
88
+ end
89
+
90
+ it %[should return the sub_job rval to the callback] do
91
+ @first_job.callback do |result|
92
+ result.should == @rval
93
+ done
94
+ end
95
+
96
+ em { @first_job.defer! }
97
+ end # it
98
+ end # describe 'success'
99
+
100
+ describe 'failure' do
101
+ before do
102
+ @rval = %w[one two]
103
+ @sub_job = Deferred::DefaultThreadpoolJob.new { raise BollocksError }
104
+ @first_job = Deferred::DefaultThreadpoolJob.new { @sub_job }
105
+ end
106
+
107
+ it %[should fire the errback on the first_job] do
108
+ @first_job.errback do |exc|
109
+ exc.should be_instance_of(BollocksError)
110
+ done
111
+ end
112
+
113
+ em { @first_job.defer! }
114
+ end
115
+ end
116
+
117
+ describe 'before_run' do
118
+
119
+ it %[should call the before_run callbacks in the reactor thread] do
120
+ rval = "hooray"
121
+
122
+ sub_job = Deferred::DefaultThreadpoolJob.new { rval }
123
+
124
+ sub_job.before_run { EM.reactor_thread?.should be_true }
125
+ sub_job.callback { |*| done }
126
+
127
+ first_job = Deferred::DefaultThreadpoolJob.new { sub_job }
128
+
129
+ em { first_job.defer! }
130
+ end
131
+ end
132
+ end # describe returns a ThreadpoolJob
133
+
134
+ describe 'on_run returns a Deferred' do
135
+ before do
136
+ @rval = %w[one two]
137
+ @deferred = Deferred::Default.new
138
+ @sub_job = Deferred::DefaultThreadpoolJob.new { @deferred }
139
+ @first_job = Deferred::DefaultThreadpoolJob.new { @sub_job }
140
+ end
141
+
142
+ it %[should chain the deferred's callback] do
143
+ EM.next_tick do
144
+ @deferred.succeed(*@rval)
145
+ end
146
+
147
+ @first_job.callback do |*a|
148
+ a.should == @rval
149
+ done
150
+ end
151
+
152
+ em { @first_job.defer! }
153
+ end
154
+
155
+ it %[should chain the deferred's errback] do
156
+ exc = BollocksError.new
157
+
158
+ @first_job.errback do |e|
159
+ e.should == exc
160
+ done
161
+ end
162
+
163
+ EM.next_tick do
164
+ @deferred.fail(exc)
165
+ end
166
+
167
+ em { @first_job.defer! }
168
+ end
169
+ end
170
+ end # describe 'defer!'
171
+ end
172
+