@@ -97,28 +97,27 @@ def get_ivar_from_args(opts)
97
97
98
98
describe '.new' do
99
99
it 'should return an unscheduled Promise' do
100
- p = Promise . new ( executor : executor ) { nil }
100
+ p = Promise . new ( executor : :immediate ) { nil }
101
101
expect ( p ) . to be_unscheduled
102
102
end
103
103
end
104
104
105
105
describe '.execute' do
106
106
it 'creates a new Promise' do
107
- p = Promise . execute ( executor : executor ) { nil }
107
+ p = Promise . execute ( executor : :immediate ) { nil }
108
108
expect ( p ) . to be_a ( Promise )
109
109
end
110
110
111
111
it 'passes the block to the new Promise' do
112
- p = Promise . execute ( executor : executor ) { 20 }
113
- sleep ( 0.1 )
112
+ p = Promise . execute ( executor : :immediate ) { 20 }
114
113
expect ( p . value ) . to eq 20
115
114
end
116
115
117
116
it 'calls #execute on the new Promise' do
118
117
p = double ( 'promise' )
119
- allow ( Promise ) . to receive ( :new ) . with ( { executor : executor } ) . and_return ( p )
118
+ allow ( Promise ) . to receive ( :new ) . with ( any_args ) . and_return ( p )
120
119
expect ( p ) . to receive ( :execute ) . with ( no_args )
121
- Promise . execute ( executor : executor ) { nil }
120
+ Promise . execute ( executor : :immediate ) { nil }
122
121
end
123
122
end
124
123
end
@@ -128,12 +127,21 @@ def get_ivar_from_args(opts)
128
127
context 'unscheduled' do
129
128
130
129
it 'sets the promise to :pending' do
131
- p = Promise . new ( executor : executor ) { sleep ( 0.1 ) } . execute
130
+ start_latch = CountDownLatch . new
131
+ end_latch = CountDownLatch . new
132
+ p = Promise . new ( executor : executor ) do
133
+ start_latch . count_down
134
+ end_latch . wait ( 1 )
135
+ end
136
+ start_latch . wait ( 1 )
137
+ p . execute
132
138
expect ( p ) . to be_pending
139
+ end_latch . count_down
133
140
end
134
141
135
142
it 'posts the block given in construction' do
136
- expect ( executor ) . to receive ( :post ) . with ( any_args )
143
+ executor = ImmediateExecutor . new
144
+ expect ( executor ) . to receive ( :post ) . with ( any_args ) . and_call_original
137
145
Promise . new ( executor : executor ) { nil } . execute
138
146
end
139
147
end
@@ -153,27 +161,28 @@ def get_ivar_from_args(opts)
153
161
154
162
describe 'with children' do
155
163
156
- let ( :root ) { Promise . new ( executor : executor ) { sleep ( 0.1 ) ; nil } }
157
- let ( :c1 ) { root . then { sleep ( 0.1 ) ; nil } }
158
- let ( :c2 ) { root . then { sleep ( 0.1 ) ; nil } }
159
- let ( :c2_1 ) { c2 . then { sleep ( 0.1 ) ; nil } }
164
+ let ( :start_latch ) { CountDownLatch . new ( 4 ) }
165
+ let ( :end_latch ) { CountDownLatch . new ( 1 ) }
166
+ let ( :root ) { Promise . new ( executor : executor ) { start_latch . count_down ; end_latch . wait ( 5 ) } }
167
+ let ( :c1 ) { root . then { start_latch . count_down ; end_latch . wait ( 5 ) } }
168
+ let ( :c2 ) { root . then { start_latch . count_down ; end_latch . wait ( 5 ) } }
169
+ let ( :c2_1 ) { c2 . then { start_latch . count_down ; end_latch . wait ( 5 ) } }
160
170
161
171
context 'when called on the root' do
162
172
it 'should set all promises to :pending' do
163
173
root . execute
164
-
165
- expect ( c1 ) . to be_pending
166
- expect ( c2 ) . to be_pending
167
- expect ( c2_1 ) . to be_pending
174
+ start_latch . wait ( 1 )
168
175
[ root , c1 , c2 , c2_1 ] . each { |p | expect ( p ) . to be_pending }
176
+ end_latch . count_down
169
177
end
170
178
end
171
179
172
180
context 'when called on a child' do
173
181
it 'should set all promises to :pending' do
174
182
c2_1 . execute
175
-
183
+ start_latch . wait ( 1 )
176
184
[ root , c1 , c2 , c2_1 ] . each { |p | expect ( p ) . to be_pending }
185
+ end_latch . count_down
177
186
end
178
187
end
179
188
end
@@ -298,38 +307,38 @@ def get_ivar_from_args(opts)
298
307
end
299
308
300
309
it 'succeeds if both promises succeed' do
301
- child = Promise . new ( executor : executor ) { 1 } .
302
- flat_map { |v | Promise . new ( executor : executor ) { v + 10 } } . execute . wait
310
+ child = Promise . new ( executor : :immediate ) { 1 } .
311
+ flat_map { |v | Promise . new ( executor : :immediate ) { v + 10 } } . execute . wait
303
312
304
313
expect ( child . value! ) . to eq ( 11 )
305
314
end
306
315
307
316
it 'fails if the left promise fails' do
308
- child = Promise . new ( executor : executor ) { fail } .
309
- flat_map { |v | Promise . new ( executor : executor ) { v + 10 } } . execute . wait
317
+ child = Promise . new ( executor : :immediate ) { fail } .
318
+ flat_map { |v | Promise . new ( executor : :immediate ) { v + 10 } } . execute . wait
310
319
311
320
expect ( child ) . to be_rejected
312
321
end
313
322
314
323
it 'fails if the right promise fails' do
315
- child = Promise . new ( executor : executor ) { 1 } .
316
- flat_map { |v | Promise . new ( executor : executor ) { fail } } . execute . wait
324
+ child = Promise . new ( executor : :immediate ) { 1 } .
325
+ flat_map { |v | Promise . new ( executor : :immediate ) { fail } } . execute . wait
317
326
318
327
expect ( child ) . to be_rejected
319
328
end
320
329
321
330
it 'fails if the generating block fails' do
322
- child = Promise . new ( executor : executor ) { } . flat_map { fail } . execute . wait
331
+ child = Promise . new ( executor : :immediate ) { } . flat_map { fail } . execute . wait
323
332
324
333
expect ( child ) . to be_rejected
325
334
end
326
335
327
336
end
328
337
329
338
describe '#zip' do
330
- let ( :promise1 ) { Promise . new ( executor : executor ) { 1 } }
331
- let ( :promise2 ) { Promise . new ( executor : executor ) { 2 } }
332
- let ( :promise3 ) { Promise . new ( executor : executor ) { [ 3 ] } }
339
+ let ( :promise1 ) { Promise . new ( executor : :immediate ) { 1 } }
340
+ let ( :promise2 ) { Promise . new ( executor : :immediate ) { 2 } }
341
+ let ( :promise3 ) { Promise . new ( executor : :immediate ) { [ 3 ] } }
333
342
334
343
it 'yields the results as an array' do
335
344
composite = promise1 . zip ( promise2 , promise3 ) . execute . wait
@@ -345,9 +354,9 @@ def get_ivar_from_args(opts)
345
354
end
346
355
347
356
describe '.zip' do
348
- let ( :promise1 ) { Promise . new ( executor : executor ) { 1 } }
349
- let ( :promise2 ) { Promise . new ( executor : executor ) { 2 } }
350
- let ( :promise3 ) { Promise . new ( executor : executor ) { [ 3 ] } }
357
+ let ( :promise1 ) { Promise . new ( executor : :immediate ) { 1 } }
358
+ let ( :promise2 ) { Promise . new ( executor : :immediate ) { 2 } }
359
+ let ( :promise3 ) { Promise . new ( executor : :immediate ) { [ 3 ] } }
351
360
352
361
it 'yields the results as an array' do
353
362
composite = Promise . zip ( promise1 , promise2 , promise3 ) . execute . wait
@@ -364,9 +373,9 @@ def get_ivar_from_args(opts)
364
373
365
374
describe 'aggregators' do
366
375
367
- let ( :promise1 ) { Promise . new ( executor : executor ) { 1 } }
368
- let ( :promise2 ) { Promise . new ( executor : executor ) { 2 } }
369
- let ( :promise3 ) { Promise . new ( executor : executor ) { [ 3 ] } }
376
+ let ( :promise1 ) { Promise . new ( executor : :immediate ) { 1 } }
377
+ let ( :promise2 ) { Promise . new ( executor : :immediate ) { 2 } }
378
+ let ( :promise3 ) { Promise . new ( executor : :immediate ) { [ 3 ] } }
370
379
371
380
describe '.all?' do
372
381
@@ -386,7 +395,7 @@ def get_ivar_from_args(opts)
386
395
387
396
composite = Promise . all? ( promise1 , promise2 , promise3 ) .
388
397
then { counter . up ; latch . count_down } .
389
- rescue { counter . down ; latch . count_down } .
398
+ rescue { counter . down ; latch . count_down } .
390
399
execute
391
400
392
401
latch . wait ( 1 )
@@ -400,7 +409,7 @@ def get_ivar_from_args(opts)
400
409
401
410
composite = Promise . all? .
402
411
then { counter . up ; latch . count_down } .
403
- rescue { counter . down ; latch . count_down } .
412
+ rescue { counter . down ; latch . count_down } .
404
413
execute
405
414
406
415
latch . wait ( 1 )
@@ -414,7 +423,7 @@ def get_ivar_from_args(opts)
414
423
415
424
composite = Promise . all? ( promise1 , promise2 , rejected_subject , promise3 ) .
416
425
then { counter . up ; latch . count_down } .
417
- rescue { counter . down ; latch . count_down } .
426
+ rescue { counter . down ; latch . count_down } .
418
427
execute
419
428
420
429
latch . wait ( 1 )
@@ -441,7 +450,7 @@ def get_ivar_from_args(opts)
441
450
442
451
composite = Promise . any? ( promise1 , promise2 , rejected_subject , promise3 ) .
443
452
then { counter . up ; latch . count_down } .
444
- rescue { counter . down ; latch . count_down } .
453
+ rescue { counter . down ; latch . count_down } .
445
454
execute
446
455
447
456
latch . wait ( 1 )
@@ -455,7 +464,7 @@ def get_ivar_from_args(opts)
455
464
456
465
composite = Promise . any? .
457
466
then { counter . up ; latch . count_down } .
458
- rescue { counter . down ; latch . count_down } .
467
+ rescue { counter . down ; latch . count_down } .
459
468
execute
460
469
461
470
latch . wait ( 1 )
@@ -469,7 +478,7 @@ def get_ivar_from_args(opts)
469
478
470
479
composite = Promise . any? ( rejected_subject , rejected_subject , rejected_subject , rejected_subject ) .
471
480
then { counter . up ; latch . count_down } .
472
- rescue { counter . down ; latch . count_down } .
481
+ rescue { counter . down ; latch . count_down } .
473
482
execute
474
483
475
484
latch . wait ( 1 )
@@ -500,7 +509,7 @@ def get_ivar_from_args(opts)
500
509
end
501
510
502
511
it 'can be called with a block' do
503
- p = Promise . new ( executor : executor )
512
+ p = Promise . new ( executor : :immediate )
504
513
ch = p . then ( &:to_s )
505
514
p . set { :value }
506
515
@@ -533,46 +542,40 @@ def get_ivar_from_args(opts)
533
542
534
543
it 'passes the result of each block to all its children' do
535
544
expected = nil
536
- Promise . new ( executor : executor ) { 20 } . then { |result | expected = result } . execute
537
- sleep ( 0.1 )
545
+ Promise . new ( executor : :immediate ) { 20 } . then { |result | expected = result } . execute
538
546
expect ( expected ) . to eq 20
539
547
end
540
548
541
549
it 'sets the promise value to the result if its block' do
542
- root = Promise . new ( executor : executor ) { 20 }
550
+ root = Promise . new ( executor : :immediate ) { 20 }
543
551
p = root . then { |result | result * 2 } . execute
544
- sleep ( 0.1 )
545
552
expect ( root . value ) . to eq 20
546
553
expect ( p . value ) . to eq 40
547
554
end
548
555
549
556
it 'sets the promise state to :fulfilled if the block completes' do
550
- p = Promise . new ( executor : executor ) { 10 * 2 } . then { |result | result * 2 } . execute
551
- sleep ( 0.1 )
557
+ p = Promise . new ( executor : :immediate ) { 10 * 2 } . then { |result | result * 2 } . execute
552
558
expect ( p ) . to be_fulfilled
553
559
end
554
560
555
561
it 'passes the last result through when a promise has no block' do
556
562
expected = nil
557
- Promise . new ( executor : executor ) { 20 } . then ( Proc . new { } ) . then { |result | expected = result } . execute
558
- sleep ( 0.1 )
563
+ Promise . new ( executor : :immediate ) { 20 } . then ( Proc . new { } ) . then { |result | expected = result } . execute
559
564
expect ( expected ) . to eq 20
560
565
end
561
566
562
567
it 'uses result as fulfillment value when a promise has no block' do
563
- p = Promise . new ( executor : executor ) { 20 } . then ( Proc . new { } ) . execute
564
- sleep ( 0.1 )
568
+ p = Promise . new ( executor : :immediate ) { 20 } . then ( Proc . new { } ) . execute
565
569
expect ( p . value ) . to eq 20
566
570
end
567
571
568
572
it 'can manage long chain' do
569
- root = Promise . new ( executor : executor ) { 20 }
573
+ root = Promise . new ( executor : :immediate ) { 20 }
570
574
p1 = root . then { |b | b * 3 }
571
575
p2 = root . then { |c | c + 2 }
572
576
p3 = p1 . then { |d | d + 7 }
573
577
574
578
root . execute
575
- sleep ( 0.1 )
576
579
577
580
expect ( root . value ) . to eq 20
578
581
expect ( p1 . value ) . to eq 60
@@ -585,27 +588,24 @@ def get_ivar_from_args(opts)
585
588
586
589
it 'passes the reason to all its children' do
587
590
expected = nil
588
- Promise . new ( executor : executor ) { raise ArgumentError } . then ( Proc . new { |reason | expected = reason } ) . execute
589
- sleep ( 0.1 )
591
+ handler = proc { |reason | expected = reason }
592
+ Promise . new ( executor : :immediate ) { raise ArgumentError } . then ( handler ) . execute
590
593
expect ( expected ) . to be_a ArgumentError
591
594
end
592
595
593
596
it 'sets the promise value to the result if its block' do
594
- root = Promise . new ( executor : executor ) { raise ArgumentError }
597
+ root = Promise . new ( executor : :immediate ) { raise ArgumentError }
595
598
p = root . then ( Proc . new { |reason | 42 } ) . execute
596
- sleep ( 0.1 )
597
599
expect ( p . value ) . to eq 42
598
600
end
599
601
600
602
it 'sets the promise state to :rejected if the block completes' do
601
- p = Promise . new ( executor : executor ) { raise ArgumentError } . execute
602
- sleep ( 0.1 )
603
+ p = Promise . new ( executor : :immediate ) { raise ArgumentError } . execute
603
604
expect ( p ) . to be_rejected
604
605
end
605
606
606
607
it 'uses reason as rejection reason when a promise has no rescue callable' do
607
- p = Promise . new ( executor : ImmediateExecutor . new ) { raise ArgumentError } . then { |val | val } . execute
608
- sleep ( 0.1 )
608
+ p = Promise . new ( executor : :immediate ) { raise ArgumentError } . then { |val | val } . execute
609
609
expect ( p ) . to be_rejected
610
610
expect ( p . reason ) . to be_a ArgumentError
611
611
end
0 commit comments