11require 'spec_helper'
22require_relative 'obligation_shared'
3- require_relative 'uses_global_thread_pool_shared'
43
54module Concurrent
65
76 describe Promise do
87
9- let! ( :thread_pool_user ) { Promise }
10- it_should_behave_like Concurrent ::UsesGlobalThreadPool
8+ let ( :executor ) { PerThreadExecutor . new }
119
12- let ( :empty_root ) { Promise . new { nil } }
10+ let ( :empty_root ) { Promise . new ( executor : executor ) { nil } }
1311 let! ( :fulfilled_value ) { 10 }
1412 let! ( :rejected_reason ) { StandardError . new ( 'mojo jojo' ) }
1513
1614 let ( :pending_subject ) do
17- Promise . new { sleep ( 0.3 ) ; fulfilled_value } . execute
15+ Promise . new ( executor : executor ) { sleep ( 0.3 ) ; fulfilled_value } . execute
1816 end
1917
2018 let ( :fulfilled_subject ) do
21- Promise . fulfill ( fulfilled_value )
19+ Promise . fulfill ( fulfilled_value , executor : executor )
2220 end
2321
2422 let ( :rejected_subject ) do
25- Promise . reject ( rejected_reason )
26- end
27-
28- before ( :each ) do
29- Promise . thread_pool = PerThreadExecutor . new
23+ Promise . reject ( rejected_reason , executor : executor )
3024 end
3125
3226 it_should_behave_like :obligation
@@ -74,28 +68,28 @@ module Concurrent
7468
7569 describe '.new' do
7670 it 'should return an unscheduled Promise' do
77- p = Promise . new { nil }
71+ p = Promise . new ( executor : executor ) { nil }
7872 p . should be_unscheduled
7973 end
8074 end
8175
8276 describe '.execute' do
8377 it 'creates a new Promise' do
84- p = Promise . execute { nil }
78+ p = Promise . execute ( executor : executor ) { nil }
8579 p . should be_a ( Promise )
8680 end
8781
8882 it 'passes the block to the new Promise' do
89- p = Promise . execute { 20 }
83+ p = Promise . execute ( executor : executor ) { 20 }
9084 sleep ( 0.1 )
9185 p . value . should eq 20
9286 end
9387
9488 it 'calls #execute on the new Promise' do
9589 p = double ( 'promise' )
96- Promise . stub ( :new ) . with ( any_args ) . and_return ( p )
90+ Promise . stub ( :new ) . with ( { executor : executor } ) . and_return ( p )
9791 p . should_receive ( :execute ) . with ( no_args )
98- Promise . execute { nil }
92+ Promise . execute ( executor : executor ) { nil }
9993 end
10094 end
10195 end
@@ -105,15 +99,14 @@ module Concurrent
10599 context 'unscheduled' do
106100
107101 it 'sets the promise to :pending' do
108- p = Promise . new { sleep ( 0.1 ) } . execute
102+ p = Promise . new ( executor : executor ) { sleep ( 0.1 ) } . execute
109103 p . should be_pending
110104 end
111105
112106 it 'posts the block given in construction' do
113- Promise . thread_pool . should_receive ( :post ) . with ( any_args )
114- Promise . new { nil } . execute
107+ executor . should_receive ( :post ) . with ( any_args )
108+ Promise . new ( executor : executor ) { nil } . execute
115109 end
116-
117110 end
118111
119112 context 'pending' do
@@ -124,16 +117,14 @@ module Concurrent
124117 end
125118
126119 it 'does not posts again' do
127- Promise . thread_pool . should_receive ( :post ) . with ( any_args ) . once
120+ executor . should_receive ( :post ) . with ( any_args ) . once
128121 pending_subject . execute
129122 end
130-
131123 end
132124
133-
134125 describe 'with children' do
135126
136- let ( :root ) { Promise . new { sleep ( 0.1 ) ; nil } }
127+ let ( :root ) { Promise . new ( executor : executor ) { sleep ( 0.1 ) ; nil } }
137128 let ( :c1 ) { root . then { nil } }
138129 let ( :c2 ) { root . then { nil } }
139130 let ( :c2_1 ) { c2 . then { nil } }
@@ -157,7 +148,6 @@ module Concurrent
157148 [ root , c1 , c2 , c2_1 ] . each { |p | p . should be_pending }
158149 end
159150 end
160-
161151 end
162152 end
163153
@@ -187,7 +177,7 @@ module Concurrent
187177
188178 context 'unscheduled' do
189179
190- let ( :p1 ) { Promise . new { nil } }
180+ let ( :p1 ) { Promise . new ( executor : executor ) { nil } }
191181 let ( :child ) { p1 . then { } }
192182
193183 it 'returns a new promise' do
@@ -226,7 +216,6 @@ module Concurrent
226216 child = fulfilled_subject . then ( Proc . new { 7 } ) { |v | v + 5 }
227217 child . value . should eq fulfilled_value + 5
228218 end
229-
230219 end
231220
232221 context 'rejected' do
@@ -241,7 +230,6 @@ module Concurrent
241230 child = rejected_subject . then ( Proc . new { 7 } ) { |v | v + 5 }
242231 child . value . should eq 7
243232 end
244-
245233 end
246234
247235 it 'can be called more than once' do
@@ -277,40 +265,40 @@ module Concurrent
277265
278266 it 'passes the result of each block to all its children' do
279267 expected = nil
280- Promise . new { 20 } . then { |result | expected = result } . execute
268+ Promise . new ( executor : executor ) { 20 } . then { |result | expected = result } . execute
281269 sleep ( 0.1 )
282270 expected . should eq 20
283271 end
284272
285273 it 'sets the promise value to the result if its block' do
286- root = Promise . new { 20 }
274+ root = Promise . new ( executor : executor ) { 20 }
287275 p = root . then { |result | result * 2 } . execute
288276 sleep ( 0.1 )
289277 root . value . should eq 20
290278 p . value . should eq 40
291279 end
292280
293281 it 'sets the promise state to :fulfilled if the block completes' do
294- p = Promise . new { 10 * 2 } . then { |result | result * 2 } . execute
282+ p = Promise . new ( executor : executor ) { 10 * 2 } . then { |result | result * 2 } . execute
295283 sleep ( 0.1 )
296284 p . should be_fulfilled
297285 end
298286
299287 it 'passes the last result through when a promise has no block' do
300288 expected = nil
301- Promise . new { 20 } . then ( Proc . new { } ) . then { |result | expected = result } . execute
289+ Promise . new ( executor : executor ) { 20 } . then ( Proc . new { } ) . then { |result | expected = result } . execute
302290 sleep ( 0.1 )
303291 expected . should eq 20
304292 end
305293
306294 it 'uses result as fulfillment value when a promise has no block' do
307- p = Promise . new { 20 } . then ( Proc . new { } ) . execute
295+ p = Promise . new ( executor : executor ) { 20 } . then ( Proc . new { } ) . execute
308296 sleep ( 0.1 )
309297 p . value . should eq 20
310298 end
311299
312300 it 'can manage long chain' do
313- root = Promise . new { 20 }
301+ root = Promise . new ( executor : executor ) { 20 }
314302 p1 = root . then { |b | b * 3 }
315303 p2 = root . then { |c | c + 2 }
316304 p3 = p1 . then { |d | d + 7 }
@@ -329,27 +317,27 @@ module Concurrent
329317
330318 it 'passes the reason to all its children' do
331319 expected = nil
332- Promise . new { raise ArgumentError } . then ( Proc . new { |reason | expected = reason } ) . execute
320+ Promise . new ( executor : executor ) { raise ArgumentError } . then ( Proc . new { |reason | expected = reason } ) . execute
333321 sleep ( 0.1 )
334322 expected . should be_a ArgumentError
335323 end
336324
337325 it 'sets the promise value to the result if its block' do
338- root = Promise . new { raise ArgumentError }
326+ root = Promise . new ( executor : executor ) { raise ArgumentError }
339327 p = root . then ( Proc . new { |reason | 42 } ) . execute
340328 sleep ( 0.1 )
341329 p . value . should eq 42
342330 end
343331
344332 it 'sets the promise state to :rejected if the block completes' do
345- p = Promise . new { raise ArgumentError } . execute
333+ p = Promise . new ( executor : executor ) { raise ArgumentError } . execute
346334 sleep ( 0.1 )
347335 p . should be_rejected
348336 end
349337
350338 it 'uses reason as rejection reason when a promise has no rescue callable' do
351339 pending ( 'intermittently failing' )
352- p = Promise . new { raise ArgumentError } . then { |val | val } . execute
340+ p = Promise . new ( executor : executor ) { raise ArgumentError } . then { |val | val } . execute
353341 sleep ( 0.1 )
354342 p . should be_rejected
355343 p . reason . should be_a ArgumentError
0 commit comments