@@ -35,12 +35,12 @@ module Concurrent
35
35
# dereferenceable
36
36
37
37
def dereferenceable_subject ( value , opts = { } )
38
- opts = opts . merge ( executor : executor )
38
+ opts = opts . merge ( executor : Concurrent :: ImmediateExecutor . new )
39
39
Agent . new ( value , opts )
40
40
end
41
41
42
42
def dereferenceable_observable ( opts = { } )
43
- opts = opts . merge ( executor : executor )
43
+ opts = opts . merge ( executor : Concurrent :: ImmediateExecutor . new )
44
44
Agent . new ( 0 , opts )
45
45
end
46
46
@@ -211,201 +211,187 @@ def trigger_observable(observable)
211
211
context 'fulfillment' do
212
212
213
213
it 'process each block in the queue' do
214
- @expected = [ ]
215
- subject . post { @expected << 1 }
216
- subject . post { @expected << 2 }
217
- subject . post { @expected << 3 }
218
- sleep ( 0.1 )
219
- @expected . sort . should eq [ 1 , 2 , 3 ]
214
+ latch = Concurrent ::CountDownLatch . new ( 3 )
215
+ subject . post { latch . count_down }
216
+ subject . post { latch . count_down }
217
+ subject . post { latch . count_down }
218
+ latch . wait ( 1 ) . should be_true
220
219
end
221
220
222
221
it 'passes the current value to the handler' do
223
- @expected = nil
224
- Agent . new ( 10 , executor : executor ) . post { |i | @expected = i }
225
- sleep ( 0.1 )
226
- @expected . should eq 10
222
+ latch = Concurrent ::CountDownLatch . new ( 5 )
223
+ Agent . new ( latch . count , executor : executor ) . post do |i |
224
+ i . times { latch . count_down }
225
+ end
226
+ latch . wait ( 1 ) . should be_true
227
227
end
228
228
229
229
it 'sets the value to the handler return value on success' do
230
- subject . post { 100 }
231
- sleep ( 0.1 )
232
- subject . value . should eq 100
230
+ agent = Agent . new ( 10 , executor : Concurrent ::ImmediateExecutor . new )
231
+ agent . value . should eq 10
232
+ agent . post { 100 }
233
+ agent . value . should eq 100
233
234
end
234
235
235
236
it 'rejects the handler after timeout reached' do
236
237
agent = Agent . new ( 0 , timeout : 0.1 , executor : executor )
237
238
agent . post { sleep ( 1 ) ; 10 }
239
+ sleep ( 0.2 )
238
240
agent . value . should eq 0
239
241
end
240
242
end
241
243
242
244
context 'validation' do
243
245
244
246
it 'processes the validator when present' do
245
- @expected = nil
246
- subject . validate { @expected = 10 ; true }
247
+ latch = Concurrent :: CountDownLatch . new ( 1 )
248
+ subject . validate { latch . count_down ; true }
247
249
subject . post { nil }
248
- sleep ( 0.1 )
249
- @expected . should eq 10
250
+ latch . wait ( 1 ) . should be_true
250
251
end
251
252
252
253
it 'passes the new value to the validator' do
253
- @expected = nil
254
- subject . validate { |v | @expected = v ; true }
254
+ expected = Concurrent ::AtomicFixnum . new ( 0 )
255
+ latch = Concurrent ::CountDownLatch . new ( 1 )
256
+ subject . validate { |v | expected . value = v ; latch . count_down ; true }
255
257
subject . post { 10 }
256
- sleep ( 0. 1)
257
- @ expected. should eq 10
258
+ latch . wait ( 1 )
259
+ expected . value . should eq 10
258
260
end
259
261
260
262
it 'sets the new value when the validator returns true' do
261
- agent = Agent . new ( 0 , executor : executor ) . validate { true }
263
+ agent = Agent . new ( 0 , executor : Concurrent :: ImmediateExecutor . new ) . validate { true }
262
264
agent . post { 10 }
263
- sleep ( 0.1 )
264
265
agent . value . should eq 10
265
266
end
266
267
267
268
it 'does not change the value when the validator returns false' do
268
- agent = Agent . new ( 0 , executor : executor ) . validate { false }
269
+ agent = Agent . new ( 0 , executor : Concurrent :: ImmediateExecutor . new ) . validate { false }
269
270
agent . post { 10 }
270
- sleep ( 0.1 )
271
271
agent . value . should eq 0
272
272
end
273
273
274
274
it 'does not change the value when the validator raises an exception' do
275
- agent = Agent . new ( 0 , executor : executor ) . validate { raise StandardError }
275
+ agent = Agent . new ( 0 , executor : Concurrent :: ImmediateExecutor . new ) . validate { raise StandardError }
276
276
agent . post { 10 }
277
- sleep ( 0.1 )
278
277
agent . value . should eq 0
279
278
end
280
279
end
281
280
282
281
context 'rejection' do
283
282
284
283
it 'calls the first exception block with a matching class' do
285
- @expected = nil
286
- subject .
287
- rescue ( StandardError ) { |ex | @expected = 1 } .
288
- rescue ( StandardError ) { |ex | @expected = 2 } .
289
- rescue ( StandardError ) { |ex | @expected = 3 }
290
- subject . post { raise StandardError }
291
- sleep ( 0.1 )
292
- @expected . should eq 1
284
+ expected = nil
285
+ agent = Agent . new ( 0 , executor : Concurrent ::ImmediateExecutor . new ) .
286
+ rescue ( StandardError ) { |ex | expected = 1 } .
287
+ rescue ( StandardError ) { |ex | expected = 2 } .
288
+ rescue ( StandardError ) { |ex | expected = 3 }
289
+ agent . post { raise StandardError }
290
+ expected . should eq 1
293
291
end
294
292
295
293
it 'matches all with a rescue with no class given' do
296
- @expected = nil
297
- subject .
298
- rescue ( LoadError ) { |ex | @expected = 1 } .
299
- rescue { |ex | @expected = 2 } .
300
- rescue ( StandardError ) { |ex | @expected = 3 }
301
- subject . post { raise NoMethodError }
302
- sleep ( 0.1 )
303
- @expected . should eq 2
294
+ expected = nil
295
+ agent = Agent . new ( 0 , executor : Concurrent ::ImmediateExecutor . new ) .
296
+ rescue ( LoadError ) { |ex | expected = 1 } .
297
+ rescue { |ex | expected = 2 } .
298
+ rescue ( StandardError ) { |ex | expected = 3 }
299
+ agent . post { raise NoMethodError }
300
+ expected . should eq 2
304
301
end
305
302
306
303
it 'searches associated rescue handlers in order' do
307
- @expected = nil
308
- subject .
309
- rescue ( ArgumentError ) { |ex | @expected = 1 } .
310
- rescue ( LoadError ) { |ex | @expected = 2 } .
311
- rescue ( StandardError ) { |ex | @expected = 3 }
312
- subject . post { raise ArgumentError }
313
- sleep ( 0.1 )
314
- @expected . should eq 1
315
-
316
- @expected = nil
317
- subject .
318
- rescue ( ArgumentError ) { |ex | @expected = 1 } .
319
- rescue ( LoadError ) { |ex | @expected = 2 } .
320
- rescue ( StandardError ) { |ex | @expected = 3 }
321
- subject . post { raise LoadError }
322
- sleep ( 0.1 )
323
- @expected . should eq 2
324
-
325
- @expected = nil
326
- subject .
327
- rescue ( ArgumentError ) { |ex | @expected = 1 } .
328
- rescue ( LoadError ) { |ex | @expected = 2 } .
329
- rescue ( StandardError ) { |ex | @expected = 3 }
330
- subject . post { raise StandardError }
331
- sleep ( 0.1 )
332
- @expected . should eq 3
304
+ expected = nil
305
+ agent = Agent . new ( 0 , executor : Concurrent ::ImmediateExecutor . new ) .
306
+ rescue ( ArgumentError ) { |ex | expected = 1 } .
307
+ rescue ( LoadError ) { |ex | expected = 2 } .
308
+ rescue ( StandardError ) { |ex | expected = 3 }
309
+ agent . post { raise ArgumentError }
310
+ expected . should eq 1
311
+
312
+ expected = nil
313
+ agent = Agent . new ( 0 , executor : Concurrent ::ImmediateExecutor . new ) .
314
+ rescue ( ArgumentError ) { |ex | expected = 1 } .
315
+ rescue ( LoadError ) { |ex | expected = 2 } .
316
+ rescue ( StandardError ) { |ex | expected = 3 }
317
+ agent . post { raise LoadError }
318
+ expected . should eq 2
319
+
320
+ expected = nil
321
+ agent = Agent . new ( 0 , executor : Concurrent ::ImmediateExecutor . new ) .
322
+ rescue ( ArgumentError ) { |ex | expected = 1 } .
323
+ rescue ( LoadError ) { |ex | expected = 2 } .
324
+ rescue ( StandardError ) { |ex | expected = 3 }
325
+ agent . post { raise StandardError }
326
+ expected . should eq 3
333
327
end
334
328
335
329
it 'passes the exception object to the matched block' do
336
- @expected = nil
337
- subject .
338
- rescue ( ArgumentError ) { |ex | @expected = ex } .
339
- rescue ( LoadError ) { |ex | @expected = ex } .
340
- rescue ( StandardError ) { |ex | @expected = ex }
341
- subject . post { raise StandardError }
342
- sleep ( 0.1 )
343
- @expected . should be_a ( StandardError )
330
+ expected = nil
331
+ agent = Agent . new ( 0 , executor : Concurrent ::ImmediateExecutor . new ) .
332
+ rescue ( ArgumentError ) { |ex | expected = ex } .
333
+ rescue ( LoadError ) { |ex | expected = ex } .
334
+ rescue ( StandardError ) { |ex | expected = ex }
335
+ agent . post { raise StandardError }
336
+ expected . should be_a ( StandardError )
344
337
end
345
338
346
339
it 'ignores rescuers without a block' do
347
- @ expected = nil
348
- subject .
340
+ expected = nil
341
+ agent = Agent . new ( 0 , executor : Concurrent :: ImmediateExecutor . new ) .
349
342
rescue ( StandardError ) .
350
- rescue ( StandardError ) { |ex | @expected = ex }
351
- subject . post { raise StandardError }
352
- sleep ( 0.1 )
353
- @expected . should be_a ( StandardError )
343
+ rescue ( StandardError ) { |ex | expected = ex }
344
+ agent . post { raise StandardError }
345
+ expected . should be_a ( StandardError )
354
346
end
355
347
356
348
it 'supresses the exception if no rescue matches' do
357
349
lambda {
358
- subject .
350
+ agent = Agent . new ( 0 , executor : Concurrent :: ImmediateExecutor . new ) .
359
351
rescue ( ArgumentError ) { |ex | @expected = ex } .
360
352
rescue ( NotImplementedError ) { |ex | @expected = ex } .
361
353
rescue ( NoMethodError ) { |ex | @expected = ex }
362
- subject . post { raise StandardError }
363
- sleep ( 0.1 )
354
+ agent . post { raise StandardError }
364
355
} . should_not raise_error
365
356
end
366
357
367
358
it 'suppresses exceptions thrown from rescue handlers' do
368
359
lambda {
369
- subject . rescue ( StandardError ) { raise StandardError }
370
- subject . post { raise ArgumentError }
371
- sleep ( 0.1 )
360
+ agent = Agent . new ( 0 , executor : Concurrent ::ImmediateExecutor . new ) . rescue ( StandardError ) { raise StandardError }
361
+ agent . post { raise ArgumentError }
372
362
} . should_not raise_error
373
363
end
374
364
end
375
365
376
366
context 'observation' do
377
367
378
368
it 'notifies all observers when the value changes' do
379
- agent = Agent . new ( 0 , executor : executor )
369
+ agent = Agent . new ( 0 , executor : Concurrent :: ImmediateExecutor . new )
380
370
agent . add_observer ( observer )
381
371
agent . post { 10 }
382
- sleep ( 0.1 )
383
372
observer . value . should eq 10
384
373
end
385
374
386
375
it 'does not notify removed observers when the value changes' do
387
- agent = Agent . new ( 0 , executor : executor )
376
+ agent = Agent . new ( 0 , executor : Concurrent :: ImmediateExecutor . new )
388
377
agent . add_observer ( observer )
389
378
agent . delete_observer ( observer )
390
379
agent . post { 10 }
391
- sleep ( 0.1 )
392
380
observer . value . should be_nil
393
381
end
394
382
395
383
it 'does not notify observers when validation fails' do
396
- agent = Agent . new ( 0 , executor : executor )
384
+ agent = Agent . new ( 0 , executor : Concurrent :: ImmediateExecutor . new )
397
385
agent . validate { false }
398
386
agent . add_observer ( observer )
399
387
agent . post { 10 }
400
- sleep ( 0.1 )
401
388
observer . value . should be_nil
402
389
end
403
390
404
391
it 'does not notify observers when the handler raises an exception' do
405
- agent = Agent . new ( 0 , executor : executor )
392
+ agent = Agent . new ( 0 , executor : Concurrent :: ImmediateExecutor . new )
406
393
agent . add_observer ( observer )
407
394
agent . post { raise StandardError }
408
- sleep ( 0.1 )
409
395
observer . value . should be_nil
410
396
end
411
397
end
@@ -457,43 +443,40 @@ def trigger_observable(observable)
457
443
end
458
444
459
445
it 'aliases #validates for :validate' do
460
- @expected = nil
461
- subject . validates { |v | @expected = v }
462
- subject . post { 10 }
463
- sleep ( 0.1 )
464
- @expected . should eq 10
446
+ latch = Concurrent ::CountDownLatch . new ( 1 )
447
+ subject . validates { latch . count_down ; true }
448
+ subject . post { nil }
449
+ latch . wait ( 1 ) . should be_true
465
450
end
466
451
467
452
it 'aliases #validate_with for :validate' do
468
- @expected = nil
469
- subject . validate_with { |v | @expected = v }
470
- subject . post { 10 }
471
- sleep ( 0.1 )
472
- @expected . should eq 10
453
+ latch = Concurrent ::CountDownLatch . new ( 1 )
454
+ subject . validate_with { latch . count_down ; true }
455
+ subject . post { nil }
456
+ latch . wait ( 1 ) . should be_true
473
457
end
474
458
475
459
it 'aliases #validates_with for :validate' do
476
- @expected = nil
477
- subject . validates_with { |v | @expected = v }
478
- subject . post { 10 }
479
- sleep ( 0.1 )
480
- @expected . should eq 10
460
+ latch = Concurrent ::CountDownLatch . new ( 1 )
461
+ subject . validates_with { latch . count_down ; true }
462
+ subject . post { nil }
463
+ latch . wait ( 1 ) . should be_true
481
464
end
482
465
483
466
it 'aliases #catch for #rescue' do
484
- @expected = nil
485
- subject . catch { @ expected = true }
486
- subject . post { raise StandardError }
487
- sleep ( 0.1 )
488
- @expected . should be_true
467
+ agent = Agent . new ( 0 , executor : Concurrent :: ImmediateExecutor . new )
468
+ expected = nil
469
+ agent . catch { expected = true }
470
+ agent . post { raise StandardError }
471
+ agent . should be_true
489
472
end
490
473
491
474
it 'aliases #on_error for #rescue' do
492
- @expected = nil
493
- subject . on_error { @ expected = true }
494
- subject . post { raise StandardError }
495
- sleep ( 0.1 )
496
- @expected . should be_true
475
+ agent = Agent . new ( 0 , executor : Concurrent :: ImmediateExecutor . new )
476
+ expected = nil
477
+ agent . on_error { expected = true }
478
+ agent . post { raise StandardError }
479
+ agent . should be_true
497
480
end
498
481
end
499
482
end
0 commit comments