diff --git a/lib/functions.php b/lib/functions.php index e550c6b..8137681 100644 --- a/lib/functions.php +++ b/lib/functions.php @@ -388,29 +388,22 @@ function first(array $awaitables) { } /** - * Returns a awaitable that succeeds when $required number of awaitables succeed. The awaitable fails if $required - * number of awaitables can no longer succeed. + * Resolves with a two-item array delineating successful and failed Awaitable results. * + * The returned awaitable will only fail if ALL of the awaitables fail. + * @param Awaitable[] $awaitables - * @param int $required Number of awaitables that must succeed to succeed the returned awaitable. * * @return \Interop\Async\Awaitable */ -function some(array $awaitables, $required) { - $required = (int) $required; - - if (0 >= $required) { - return new Success([]); +function some(array $awaitables) { + if (empty($awaitables)) { + throw new \InvalidArgumentException("No awaitables provided"); } $pending = \count($awaitables); - if ($required > $pending) { - throw new \InvalidArgumentException("Too few awaitables provided"); - } - $deferred = new Deferred; - $resolved = false; $values = []; $exceptions = []; @@ -419,27 +412,20 @@ function some(array $awaitables, $required) { throw new \InvalidArgumentException("Non-awaitable provided"); } - $awaitable->when(function ($exception, $value) use ( - &$values, &$exceptions, &$pending, &$resolved, &$required, $key, $deferred - ) { - if ($resolved) { - return; - } - + $awaitable->when(function ($exception, $value) use (&$values, &$exceptions, &$pending, $key, $deferred) { if ($exception) { $exceptions[$key] = $exception; - if ($required > --$pending) { - $resolved = true; - $deferred->fail(new MultiReasonException($exceptions)); - } - return; + } else { + $values[$key] = $value; } - $values[$key] = $value; - --$pending; - if (0 === --$required) { - $resolved = true; - $deferred->resolve($values); + if (0 === --$pending) { + if (empty($values)) { + $deferred->fail(new MultiReasonException($exceptions)); + return; + } + + $deferred->resolve([$exceptions, $values]); } }); } diff --git a/test/SomeTest.php b/test/SomeTest.php index 9a58236..d63ebe1 100644 --- a/test/SomeTest.php +++ b/test/SomeTest.php @@ -14,7 +14,7 @@ class SomeTest extends \PHPUnit_Framework_TestCase { * @expectedException \InvalidArgumentException */ public function testEmptyArray() { - Amp\some([], 1); + Amp\some([]); } public function testSuccessfulAwaitablesArray() { @@ -24,39 +24,22 @@ class SomeTest extends \PHPUnit_Framework_TestCase { $result = $value; }; - Amp\some($awaitables, 2)->when($callback); + Amp\some($awaitables)->when($callback); - $this->assertSame([1, 2], $result); + $this->assertSame([[], [1, 2, 3]], $result); } public function testSuccessfulAndFailedAwaitablesArray() { - $awaitables = [new Failure(new \Exception), new Failure(new \Exception), new Success(3)]; + $exception = new \Exception; + $awaitables = [new Failure($exception), new Failure($exception), new Success(3)]; $callback = function ($exception, $value) use (&$result) { $result = $value; }; - Amp\some($awaitables, 1)->when($callback); + Amp\some($awaitables)->when($callback); - $this->assertSame([2 => 3], $result); - } - - public function testTooManyFailedAwaitables() { - $awaitables = [new Failure(new \Exception), new Failure(new \Exception), new Success(3)]; - - $callback = function ($exception, $value) use (&$reason) { - $reason = $exception; - }; - - Amp\some($awaitables, 2)->when($callback); - - $this->assertInstanceOf(MultiReasonException::class, $reason); - - $reasons = $reason->getReasons(); - - foreach ($reasons as $reason) { - $this->assertInstanceOf(\Exception::class, $reason); - } + $this->assertSame([[0 => $exception, 1 => $exception], [2 => 3]], $result); } public function testPendingAwatiablesArray() { @@ -71,14 +54,14 @@ class SomeTest extends \PHPUnit_Framework_TestCase { $result = $value; }; - Amp\some($awaitables, 2)->when($callback); + Amp\some($awaitables)->when($callback); }); - $this->assertEquals([0 => 1, 2 => 3], $result); + $this->assertEquals([[], [0 => 1, 1 => 2, 2 => 3]], $result); } public function testArrayKeysPreserved() { - $expected = ['one' => 1, 'two' => 2, 'three' => 3]; + $expected = [[], ['one' => 1, 'two' => 2, 'three' => 3]]; Loop::execute(function () use (&$result) { $awaitables = [ @@ -91,7 +74,7 @@ class SomeTest extends \PHPUnit_Framework_TestCase { $result = $value; }; - Amp\some($awaitables, 3)->when($callback); + Amp\some($awaitables)->when($callback); }); $this->assertEquals($expected, $result); @@ -101,6 +84,6 @@ class SomeTest extends \PHPUnit_Framework_TestCase { * @expectedException \InvalidArgumentException */ public function testNonAwaitable() { - Amp\some([1], 1); + Amp\some([1]); } }