@@ -260,6 +260,61 @@ module Concurrent
260260 end
261261 end
262262
263+ describe '#flat_map' do
264+
265+ it 'returns a promise' do
266+ child = empty_root . flat_map { nil }
267+ expect ( child ) . to be_a Promise
268+ expect ( child ) . not_to be empty_root
269+ end
270+
271+ it 'succeeds if both promises succeed' do
272+ child = Promise . new ( executor : executor ) { 1 } .
273+ flat_map { |v | Promise . new ( executor : executor ) { v + 10 } } . execute . wait
274+
275+ expect ( child . value! ) . to eq ( 11 )
276+ end
277+
278+ it 'fails if the left promise fails' do
279+ child = Promise . new ( executor : executor ) { fail } .
280+ flat_map { |v | Promise . new ( executor : executor ) { v + 10 } } . execute . wait
281+
282+ expect ( child ) . to be_rejected
283+ end
284+
285+ it 'fails if the right promise fails' do
286+ child = Promise . new ( executor : executor ) { 1 } .
287+ flat_map { |v | Promise . new ( executor : executor ) { fail } } . execute . wait
288+
289+ expect ( child ) . to be_rejected
290+ end
291+
292+ it 'fails if the generating block fails' do
293+ child = Promise . new ( executor : executor ) { } . flat_map { fail } . execute . wait
294+
295+ expect ( child ) . to be_rejected
296+ end
297+
298+ end
299+
300+ describe '#zip' do
301+ let ( :promise1 ) { Promise . new ( executor : executor ) { 1 } }
302+ let ( :promise2 ) { Promise . new ( executor : executor ) { 2 } }
303+ let ( :promise3 ) { Promise . new ( executor : executor ) { [ 3 ] } }
304+
305+ it 'yields the results as an array' do
306+ composite = promise1 . zip ( promise2 , promise3 ) . execute . wait
307+
308+ expect ( composite . value ) . to eq ( [ 1 , 2 , [ 3 ] ] )
309+ end
310+
311+ it 'fails if one component fails' do
312+ composite = promise1 . zip ( promise2 , rejected_subject , promise3 ) . execute . wait
313+
314+ expect ( composite ) . to be_rejected
315+ end
316+ end
317+
263318 context 'fulfillment' do
264319
265320 it 'passes the result of each block to all its children' do
0 commit comments