Skip to content

Commit

Permalink
Allow passing multiple arrays of promises to map()
Browse files Browse the repository at this point in the history
  • Loading branch information
trowski committed Aug 17, 2015
1 parent 5b629bc commit 509202d
Show file tree
Hide file tree
Showing 2 changed files with 139 additions and 7 deletions.
19 changes: 13 additions & 6 deletions src/Promise/functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,13 @@ function lift(callable $worker)
* @return \Icicle\Promise\PromiseInterface
*/
return function (/* ...$args */) use ($worker) {
return all(func_get_args())->splat($worker);
$args = func_get_args();

if (1 === count($args)) {
return resolve($args[0])->then($worker);
}

return all($args)->splat($worker);
};
}

Expand Down Expand Up @@ -313,15 +319,16 @@ function choose(array $promises)
* have been resolved.
*
* @param callable<(mixed $value): mixed> $callback
* @param mixed[] $promises Promises or values (passed through resolve() to create promises).
* @param mixed[] ...$promises Promises or values (passed through resolve() to create promises).
*
* @return \Icicle\Promise\PromiseInterface[] Array of promises resolved with the result of the mapped function.
*/
function map(callable $callback, array $promises)
function map(callable $callback /* array ...$promises */)
{
return array_map(function ($promise) use ($callback) {
return resolve($promise)->then($callback);
}, $promises);
$args = func_get_args();
$args[0] = lift($args[0]);

return call_user_func_array('array_map', $args);
}

/**
Expand Down
127 changes: 126 additions & 1 deletion tests/Promise/PromiseMapTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -167,4 +167,129 @@ public function testCallbackThrowingExceptionRejectsPromises()
}
}
}
}

public function testMultipleArrays()
{
$values1 = [1, 2, 3];
$values2 = [3, 2, 1];

$callback = $this->createCallback(3);
$callback = function ($value1, $value2) use ($callback) {
$callback();
return $value1 + $value2;
};

$result = Promise\map($callback, $values1, $values2);

foreach ($result as $key => $promise) {
$this->assertInstanceOf(PromiseInterface::class, $promise);
$this->assertTrue($promise->isPending());
}

Loop\run();

foreach ($result as $promise) {
$this->assertInstanceOf(PromiseInterface::class, $promise);
$this->assertSame(4, $promise->wait());
}
}

/**
* @depends testMultipleArrays
*/
public function testMultipleArraysWithPromises()
{
$promises1 = [Promise\resolve(1), Promise\resolve(2), Promise\resolve(3)];
$promises2 = [Promise\resolve(3), Promise\resolve(2), Promise\resolve(1)];

$callback = $this->createCallback(3);
$callback = function ($value1, $value2) use ($callback) {
$callback();
return $value1 + $value2;
};

$result = Promise\map($callback, $promises1, $promises2);

foreach ($result as $key => $promise) {
$this->assertInstanceOf(PromiseInterface::class, $promise);
$this->assertTrue($promise->isPending());
}

Loop\run();

foreach ($result as $promise) {
$this->assertInstanceOf(PromiseInterface::class, $promise);
$this->assertSame(4, $promise->wait());
}
}

/**
* @depends testMultipleArrays
*/
public function testMultipleArraysWithPendingPromises()
{
$promises1 = [
Promise\resolve(1)->delay(0.2),
Promise\resolve(2)->delay(0.3),
Promise\resolve(3)->delay(0.1)
];
$promises2 = [
Promise\resolve(3)->delay(0.1),
Promise\resolve(2)->delay(0.2),
Promise\resolve(1)->delay(0.3)
];

$callback = $this->createCallback(3);
$callback = function ($value1, $value2) use ($callback) {
$callback();
return $value1 + $value2;
};

$result = Promise\map($callback, $promises1, $promises2);

foreach ($result as $key => $promise) {
$this->assertInstanceOf(PromiseInterface::class, $promise);
$this->assertTrue($promise->isPending());
}

Loop\run();

foreach ($result as $promise) {
$this->assertInstanceOf(PromiseInterface::class, $promise);
$this->assertSame(4, $promise->wait());
}
}

/**
* @depends testMultipleArrays
*/
public function testMultipleArraysWithRejectedPromises()
{
$exception = new Exception();

$promises1 = [
Promise\reject($exception),
Promise\resolve(2),
Promise\reject($exception)
];
$promises2 = [
Promise\resolve(3),
Promise\reject($exception),
Promise\reject(new Exception())
];

$callback = $this->createCallback(0);

$result = Promise\map($callback, $promises1, $promises2);

Loop\run();

foreach ($result as $key => $promise) {
$this->assertTrue($promise->isRejected());
try {
$promise->wait();
} catch (Exception $reason) {
$this->assertSame($exception, $reason);
}
}
}}

0 comments on commit 509202d

Please sign in to comment.