From 5a06b1cdc144d87e0d0fb5b05115393f7ea6bc40 Mon Sep 17 00:00:00 2001 From: Aaron Piotrowski Date: Tue, 19 Jul 2016 00:05:40 -0500 Subject: [PATCH] Update tests and remove unused tests --- phpunit.xml | 12 - test/BaseTest.php | 9 - test/EvReactorTest.php | 61 --- test/FunctionsTest.php | 905 -------------------------------- test/LibeventReactorTest.php | 22 - test/NativeReactorTest.php | 31 -- test/PauseTest.php | 39 +- test/PlaceholderPrivateTest.php | 9 - test/PlaceholderPublicTest.php | 9 - test/PlaceholderTest.php | 123 ----- test/PromiseStreamTest.php | 135 ----- test/PromisorPrivateTest.php | 12 - test/PromisorPublicTest.php | 35 -- test/PromisorTest.php | 157 ------ test/ReactorTest.php | 716 ------------------------- test/StructTest.php | 5 + test/UvReactorTest.php | 55 -- test/bootstrap.php | 18 - 18 files changed, 26 insertions(+), 2327 deletions(-) delete mode 100644 phpunit.xml delete mode 100644 test/BaseTest.php delete mode 100644 test/EvReactorTest.php delete mode 100644 test/FunctionsTest.php delete mode 100644 test/LibeventReactorTest.php delete mode 100644 test/NativeReactorTest.php delete mode 100644 test/PlaceholderPrivateTest.php delete mode 100644 test/PlaceholderPublicTest.php delete mode 100644 test/PlaceholderTest.php delete mode 100644 test/PromiseStreamTest.php delete mode 100644 test/PromisorPrivateTest.php delete mode 100644 test/PromisorPublicTest.php delete mode 100644 test/PromisorTest.php delete mode 100644 test/ReactorTest.php delete mode 100644 test/UvReactorTest.php delete mode 100644 test/bootstrap.php diff --git a/phpunit.xml b/phpunit.xml deleted file mode 100644 index 2751c1d..0000000 --- a/phpunit.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - ./test - - - - - ./lib - - - diff --git a/test/BaseTest.php b/test/BaseTest.php deleted file mode 100644 index ef40392..0000000 --- a/test/BaseTest.php +++ /dev/null @@ -1,9 +0,0 @@ -markTestSkipped( - "ev extension not loaded" - ); - } - } - - public function testGetLoop() { - $result = \Amp\reactor()->getLoop(); - $this->assertInstanceOf("EvLoop", $result); - } - - /** - * We take care to cancel the signal watcher because Ev spazzes if - * multiple watchers exist for the same signal in different loops - */ - public function testOnSignalWatcherKeepAliveRunResult() { - if (!\extension_loaded("pcntl")) { - $this->markTestSkipped("ext/pcntl required to test onSignal() registration"); - } - - $watcherId = null; - \Amp\run(function () use (&$watcherId) { - $watcherId = \Amp\onSignal(SIGUSR1, function () { - // empty - }, $options = ["keep_alive" => false]); - }); - - \Amp\cancel($watcherId); - } - - public function testImmediateCoroutineResolutionError() { - if (\extension_loaded("xdebug")) { - $this->markTestSkipped( - "Cannot run this test with xdebug enabled: it causes zend_mm_heap corrupted" - ); - } else { - parent::testImmediateCoroutineResolutionError(); - } - } - - public function testOnErrorFailure() { - if (\extension_loaded("xdebug")) { - $this->markTestSkipped( - "Cannot run this test with xdebug enabled: it causes zend_mm_heap corrupted" - ); - } else { - parent::testImmediateCoroutineResolutionError(); - } - } -} diff --git a/test/FunctionsTest.php b/test/FunctionsTest.php deleted file mode 100644 index 5a2c61b..0000000 --- a/test/FunctionsTest.php +++ /dev/null @@ -1,905 +0,0 @@ -when(function ($e, $r) use (&$error, &$result) { - $error = $e; - $result = $r; - }); - - $this->assertNull($error); - $this->assertSame(["TEST1", "TEST2", "TEST3"], $result); - } - - public function testMapReturnsEmptySuccessOnEmptyInput() { - $promise = \Amp\map([], function () {}); - $this->assertInstanceOf('Amp\Success', $promise); - $error = null; - $result = null; - $promise->when(function ($e, $r) use (&$error, &$result) { - $error = $e; - $result = $r; - }); - - $this->assertNull($error); - $this->assertSame([], $result); - } - - /** - * @expectedException Exception - * @expectedExceptionMessage hulk smash - */ - public function testMapFailsIfFunctorThrowsOnUnwrappedValue() { - \Amp\run(function () { - yield \Amp\map(["test"], function () { throw new \Exception("hulk smash"); }); - }); - } - - /** - * @expectedException Exception - * @expectedExceptionMessage hulk smash - */ - public function testMapFailsIfFunctorThrowsOnResolvedValue() { - \Amp\run(function () { - $promises = [new Success("test")]; - yield \Amp\map($promises, function () { throw new \Exception("hulk smash"); }); - }); - } - - public function testMapFailsIfAnyPromiseFails() { - $e = new \RuntimeException( - "true progress is to know more, and be more, and to do more" - ); - $promise = \Amp\map([new Failure($e)], function () {}); - - $error = null; - $result = null; - $promise->when(function ($e, $r) use (&$error, &$result) { - $error = $e; - $result = $r; - }); - - $this->assertSame($e, $error); - $this->assertNull($result); - } - - public function testMapIgnoresFurtherResultsOnceFailed() { - $completed = false; - \Amp\run(function () use (&$completed) { - $p1 = new Deferred; - \Amp\once(function () use ($p1) { - $p1->succeed("woot"); - }, 50); - - $e = new \RuntimeException( - "true progress is to know more, and be more, and to do more" - ); - - $p2 = new Deferred; - \Amp\once(function () use ($p2, $e) { - $p2->fail($e); - }, 10); - - $toMap = \Amp\promises([$p1, $p2]); - - try { - yield \Amp\map($toMap, "strtoupper"); - $this->fail("this line should not be reached"); - } catch (\RuntimeException $error) { - $this->assertSame($e, $error); - } - - yield $p1->promise(); - - $completed = true; - }); - - $this->assertTrue($completed); - } - - public function testFilter() { - $promises = ["test1", new Success("test2"), new Success("test2"), "test2"]; - $functor = function ($el) { return $el === "test2"; }; - $promise = \Amp\filter($promises, $functor); - $error = null; - $result = null; - $promise->when(function ($e, $r) use (&$error, &$result) { - $error = $e; - $result = $r; - }); - - $this->assertNull($error); - $this->assertSame([1=>"test2", 2=>"test2", 3=>"test2"], $result); - } - - public function testFilterUsesBoolComparisonOnUnspecifiedFunctor() { - $promises = ["test1", new Success, null, false, 0, new Success("test2"), new Success(0), new Success(false) ]; - $promise = \Amp\filter($promises); - $error = null; - $result = null; - $promise->when(function ($e, $r) use (&$error, &$result) { - $error = $e; - $result = $r; - }); - - $this->assertNull($error); - $this->assertSame([0=>"test1", 5=>"test2"], $result); - } - - public function testFilter2() { - $promises = ["test1", "test2", new Success("test2"), new Success("test2")]; - $functor = function ($el) { return $el === "test2"; }; - $promise = \Amp\filter($promises, $functor); - $error = null; - $result = null; - $promise->when(function ($e, $r) use (&$error, &$result) { - $error = $e; - $result = $r; - }); - - $this->assertNull($error); - $this->assertSame([1=>"test2", 2=>"test2", 3=>"test2"], $result); - } - - public function testFilterReturnsEmptySuccessOnEmptyInput() { - $promise = \Amp\filter([], function () {}); - $this->assertInstanceOf('Amp\Success', $promise); - $error = null; - $result = null; - $promise->when(function ($e, $r) use (&$error, &$result) { - $error = $e; - $result = $r; - }); - - $this->assertNull($error); - $this->assertSame([], $result); - } - - /** - * @expectedException Exception - * @expectedExceptionMessage hulk smash - */ - public function testFilterFailsIfFunctorThrowsOnUnwrappedValue() { - \Amp\run(function () { - yield \Amp\filter(["test"], function () { throw new \Exception("hulk smash"); }); - }); - } - - /** - * @expectedException Exception - * @expectedExceptionMessage hulk smash - */ - public function testFilterFailsIfFunctorThrowsOnResolvedValue() { - \Amp\run(function () { - $promises = [new Success("test")]; - yield \Amp\filter($promises, function () { throw new \Exception("hulk smash"); }); - }); - } - - public function testFilterFailsIfAnyPromiseFails() { - $e = new \RuntimeException( - "true progress is to know more, and be more, and to do more" - ); - $promise = \Amp\filter([new Failure($e)], function () {}); - - $error = null; - $result = null; - $promise->when(function ($e, $r) use (&$error, &$result) { - $error = $e; - $result = $r; - }); - - $this->assertSame($e, $error); - $this->assertNull($result); - } - - public function testFilterIgnoresFurtherResultsOnceFailed() { - $completed = false; - \Amp\run(function () use (&$completed) { - $p1 = new Deferred; - $p2 = new Deferred; - $e = new \RuntimeException( - "true progress is to know more, and be more, and to do more" - ); - \Amp\once(function () use ($p1, $p2, $e) { - $p2->fail($e); - \Amp\immediately(function () use ($p1) { - $p1->succeed("woot"); - }); - }, 10); - - $toMap = \Amp\promises([$p1, $p2]); - $functor = function () { return true; }; - - try { - yield \Amp\filter($toMap, $functor); - $this->fail("this line should not be reached"); - } catch (\RuntimeException $error) { - $this->assertSame($e, $error); - } - - yield $p1->promise(); - - $completed = true; - }); - - $this->assertTrue($completed); - } - - public function testPipeWrapsRawValue() { - $invoked = 0; - $promise = \Amp\pipe(21, function ($r) { return $r * 2; }); - $promise->when(function ($e, $r) use (&$invoked) { - $invoked++; - $this->assertSame(42, $r); - }); - $this->assertSame(1, $invoked); - } - - public function testPipeTransformsEventualPromiseResult() { - $result = 0; - \Amp\run(function () use (&$result) { - $promisor = new Deferred; - \Amp\once(function () use ($promisor) { - $promisor->succeed("woot"); - }, 10); - - $promise = $promisor->promise(); - $result = (yield \Amp\pipe($promise, "strtoupper")); - }); - - $this->assertSame("WOOT", $result); - } - - public function testPipeAbortsIfOriginalPromiseFails() { - $invoked = 0; - $failure = new Failure(new \RuntimeException); - $promise = \Amp\pipe($failure, function (){}); - $promise->when(function ($e, $r) use (&$invoked) { - $invoked++; - $this->assertInstanceOf("RuntimeException", $e); - }); - $this->assertSame(1, $invoked); - } - - public function testPipeAbortsIfFunctorThrowsOnRawValue() { - $invoked = 0; - $promise = \Amp\pipe(42, function (){ throw new \RuntimeException; }); - $promise->when(function ($e, $r) use (&$invoked) { - $invoked++; - $this->assertInstanceOf("RuntimeException", $e); - }); - $this->assertSame(1, $invoked); - } - - public function testPipeAbortsIfFunctorThrows() { - $invoked = 0; - $promise = \Amp\pipe(new Success(42), function (){ throw new \RuntimeException; }); - $promise->when(function ($e, $r) use (&$invoked) { - $invoked++; - $this->assertInstanceOf("RuntimeException", $e); - }); - $this->assertSame(1, $invoked); - } - - public function testSomeResolutionWhenAllPromisesFail() { - $ex1 = new \RuntimeException("1"); - $ex2 = new \RuntimeException("2"); - $promises = [new Failure($ex1), new Failure($ex2)]; - \Amp\some($promises)->when(function ($e, $r) use ($ex1, $ex2) { - $this->assertNull($r); - $this->assertInstanceOf(CombinatorException::class, $e); - $this->assertSame($e->getExceptions()[0], $ex1); - $this->assertSame($e->getExceptions()[1], $ex2); - }); - } - - public function testAllResolutionWhenNoPromiseInstancesCombined() { - $promises = [null, 1, 2, true]; - \Amp\all($promises)->when(function ($e, $r) { - list($a, $b, $c, $d) = $r; - $this->assertNull($a); - $this->assertSame(1, $b); - $this->assertSame(2, $c); - $this->assertSame(true, $d); - }); - } - - public function testSomeResolutionWhenNoPromiseInstancesCombined() { - $promises = [null, 1, 2, true]; - \Amp\some($promises)->when(function ($e, $r) { - list($errors, $results) = $r; - list($a, $b, $c, $d) = $results; - $this->assertNull($a); - $this->assertSame(1, $b); - $this->assertSame(2, $c); - $this->assertSame(true, $d); - }); - } - - public function testAnyResolutionWhenNoPromiseInstancesCombined() { - $promises = [null, 1, 2, true]; - \Amp\any($promises)->when(function ($e, $r) { - list($errors, $results) = $r; - list($a, $b, $c, $d) = $results; - $this->assertNull($a); - $this->assertSame(1, $b); - $this->assertSame(2, $c); - $this->assertSame(true, $d); - }); - } - - public function testAnyReturnsImmediatelyOnEmptyPromiseArray() { - $promise = \Amp\any([]); - $this->assertInstanceOf('Amp\Success', $promise); - $error = null; - $result = null; - $promise->when(function ($e, $r) use (&$error, &$result) { - $error = $e; - $result = $r; - }); - $this->assertNull($error); - $this->assertSame([[], []], $result); - } - - public function testAllResolvesWithArrayOfResults() { - \Amp\all(['r1' => 42, 'r2' => new Success(41)])->when(function ($error, $result) { - $expected = ['r1' => 42, 'r2' => 41]; - $this->assertSame($expected, $result); - }); - } - - public function testAllReturnsImmediatelyOnEmptyPromiseArray() { - $promise = \Amp\all([]); - $this->assertInstanceOf('Amp\Success', $promise); - $error = null; - $result = null; - $promise->when(function ($e, $r) use (&$error, &$result) { - $error = $e; - $result = $r; - }); - $this->assertNull($error); - $this->assertSame([], $result); - } - - /** - * @expectedException \RuntimeException - * @expectedExceptionMessage zanzibar - */ - public function testAllThrowsIfAnyIndividualPromiseFails() { - $exception = new \RuntimeException('zanzibar'); - \Amp\all([ - 'r1' => new Success(42), - 'r2' => new Failure($exception), - 'r3' => new Success(40), - ])->when(function (\Exception $error) { - throw $error; - }); - } - - public function testSomeReturnsArrayOfErrorsAndResults() { - $exception = new \RuntimeException('zanzibar'); - \Amp\some([ - 'r1' => new Success(42), - 'r2' => new Failure($exception), - 'r3' => new Success(40), - ])->when(function ($error, $result) use ($exception) { - $this->assertNull($error); - list($errors, $results) = $result; - $this->assertSame(['r2' => $exception], $errors); - $this->assertSame(['r1' => 42, 'r3' => 40], $results); - }); - } - - public function testSomeFailsImmediatelyOnEmptyPromiseArrayInput() { - $promise = \Amp\some([]); - $this->assertInstanceOf('Amp\Failure', $promise); - $error = null; - $result = null; - $promise->when(function ($e, $r) use (&$error, &$result) { - $error = $e; - $result = $r; - }); - $this->assertNull($result); - $this->assertInstanceOf('\LogicException', $error); - $this->assertSame("No promises or values provided for resolution", $error->getMessage()); - } - - /** - * @expectedException \Amp\CombinatorException - */ - public function testSomeThrowsIfNoPromisesResolveSuccessfully() { - \Amp\some([ - 'r1' => new Failure(new \RuntimeException), - 'r2' => new Failure(new \RuntimeException), - ])->when(function ($error) { - throw $error; - }); - } - - public function testFirstFailsImmediatelyOnEmptyPromiseArrayInput() { - $promise = \Amp\first([]); - $this->assertInstanceOf('Amp\Failure', $promise); - $error = null; - $result = null; - $promise->when(function ($e, $r) use (&$error, &$result) { - $error = $e; - $result = $r; - }); - $this->assertNull($result); - $this->assertInstanceOf('\LogicException', $error); - $this->assertSame("No promises or values provided", $error->getMessage()); - } - - public function testFirst() { - $resolutionCount = 0; - $result = 0; - \Amp\run(function () use (&$resolutionCount, &$result) { - $p1 = new Deferred; - \Amp\once(function () use ($p1, &$resolutionCount) { - $p1->succeed(1); - $resolutionCount++; - }, 10); - - $p2 = new Deferred; - \Amp\once(function () use ($p2, &$resolutionCount) { - $p2->succeed(2); - $resolutionCount++; - }, 20); - - $p3 = new Deferred; - \Amp\once(function () use ($p3, &$resolutionCount) { - $p3->succeed(3); - $resolutionCount++; - }, 30); - - $promises = [$p1->promise(), $p2->promise(), $p3->promise()]; - $allPromise = \Amp\all($promises); - $allPromise->when('\Amp\stop'); - - $result = (yield \Amp\first($promises)); - }); - - $this->assertSame(3, $resolutionCount); - $this->assertSame(1, $result); - } - - public function testNonPromiseValueImmediatelyResolvesFirstCombinator() { - $result = 0; - \Amp\run(function () use (&$result) { - $p1 = 42; - $p2 = (new Deferred)->promise(); - $result = (yield \Amp\first([$p1, $p2])); - }); - $this->assertSame(42, $result); - } - - /** - * @expectedException \Amp\CombinatorException - * @expectedExceptionMessage All promises failed - */ - public function testFirstFailsIfAllPromisesFail() { - \Amp\run(function () use (&$result) { - $e1 = new \Exception("foo"); - $e2 = new \Exception("bar"); - $promises = [new Failure($e1), new Failure($e2)]; - yield \Amp\first($promises); - }); - } - - /** - * @expectedException \Amp\TimeoutException - * @expectedExceptionMessage Promise resolution timed out - */ - public function testTimeout() { - \Amp\run(function () { - $pause = new \Amp\Pause(3000); - yield \Amp\timeout($pause, 10); - }); - } - - public function testTimeoutOnSuccess() { - $invoked = false; - \Amp\run(function () use (&$invoked) { - $promisor = new Deferred; - \Amp\once(function () use ($promisor) { - $promisor->succeed(42); - }, 10); - - $result = (yield \Amp\timeout($promisor->promise(), 10000)); - $this->assertSame(42, $result); - $invoked = true; - }); - - $this->assertTrue($invoked); - } - - /** - * @expectedException \RuntimeException - * @expectedExceptionMessage nothing that is worth knowing can be taught - */ - public function testTimeoutOnFailure() { - \Amp\run(function () { - $promisor = new Deferred; - \Amp\once(function () use ($promisor) { - $promisor->fail(new \RuntimeException( - "nothing that is worth knowing can be taught" - )); - }, 10); - - $result = (yield \Amp\timeout($promisor->promise(), 10000)); - }); - } - - public function testTimeoutIgnoresResultIfAlreadyComplete() { - $invoked = false; - \Amp\run(function () use (&$invoked) { - $promisor = new Deferred; - \Amp\once(function () use ($promisor) { - $promisor->succeed(42); - }, 100); - try { - $result = (yield \Amp\timeout($promisor->promise(), 10)); - } catch (\RuntimeException $e) { - // ignore this - } - yield $promisor->promise(); - $invoked = true; - }); - - $this->assertTrue($invoked); - } - - public function testAllCombinatorResolution() { - $invoked = 0; - \Amp\run(function () use (&$invoked) { - list($a, $b) = (yield \Amp\all([ - new Success(21), - new Success(2), - ])); - - $result = ($a * $b); - $this->assertSame(42, $result); - $invoked++; - }); - $this->assertSame(1, $invoked); - } - - public function testAllCombinatorResolutionWithNonPromises() { - $invoked = 0; - \Amp\run(function () use (&$invoked) { - list($a, $b, $c) = (yield \Amp\all([new Success(21), new Success(2), 10])); - $result = ($a * $b * $c); - $this->assertSame(420, $result); - $invoked++; - }); - $this->assertSame(1, $invoked); - } - - /** - * @expectedException \Exception - * @expectedExceptionMessage When in the chronicle of wasted time - */ - public function testAllCombinatorResolutionThrowsIfAnyOnePromiseFails() { - \Amp\run(function () { - list($a, $b) = (yield \Amp\all([ - new Success(21), - new Failure(new \Exception('When in the chronicle of wasted time')), - ])); - }); - } - - public function testExplicitAllCombinatorResolution() { - $invoked = 0; - \Amp\run(function () use (&$invoked) { - list($a, $b, $c) = (yield \Amp\all([ - new Success(21), - new Success(2), - 10 - ])); - - $this->assertSame(420, ($a * $b * $c)); - $invoked++; - }); - $this->assertSame(1, $invoked); - } - - public function testExplicitAnyCombinatorResolution() { - $invoked = 0; - \Amp\run(function () use (&$invoked) { - list($errors, $results) = (yield \Amp\any([ - 'a' => new Success(21), - 'b' => new Failure(new \Exception('test')), - ])); - $this->assertSame('test', $errors['b']->getMessage()); - $this->assertSame(21, $results['a']); - $invoked++; - }); - $this->assertSame(1, $invoked); - } - - /** - * @expectedException \Amp\CombinatorException - */ - public function testExplicitSomeCombinatorResolutionFailsOnError() { - \Amp\run(function () { - yield \Amp\some([ - 'r1' => new Failure(new \RuntimeException), - 'r2' => new Failure(new \RuntimeException), - ]); - }); - } - - public function testPromisesNormalization() { - $completed = false; - \Amp\run(function () use (&$completed) { - $promisor = new Deferred; - $promisor->succeed(41); - $values = [ - $promisor, - 42, - new Success(43), - ]; - - list($a, $b, $c) = (yield \Amp\all(\Amp\promises($values))); - $this->assertSame(41, $a); - $this->assertSame(42, $b); - $this->assertSame(43, $c); - $completed = true; - }); - $this->assertTrue($completed); - } - - public function testCoroutine() { - $invoked = 0; - \Amp\run(function () use (&$invoked) { - $co = function () use (&$invoked) { - yield new Success; - yield; - yield new Pause(25); - $invoked++; - }; - $wrapped = \Amp\coroutine($co); - $wrapped(); - }); - $this->assertSame(1, $invoked); - } - - public function testCoroutineWrapsNonGeneratorReturnInPromise() { - $co = \Amp\coroutine(function () { - return 42; - }); - $out = $co(); - $this->assertInstanceOf("\Amp\Success", $out); - $invoked = false; - $out->when(function ($error, $result) use (&$invoked) { - $this->assertNull($error); - $this->assertSame(42, $result); - $invoked = true; - }); - $this->assertTrue($invoked); - } - - public function testCoroutineReturnsPromiseResultUnmodified() { - $success = new \Amp\Success; - $co = \Amp\coroutine(function () use ($success) { - return $success; - }); - $out = $co(); - $this->assertSame($success, $out); - } - - public function testNestedCoroutineResolutionContinuation() { - $invoked = 0; - \Amp\run(function () use (&$invoked) { - $co = function () use (&$invoked) { - yield new Success; - yield new Success; - yield new Success; - yield new Success; - yield new Success; - yield new CoroutineResult(42); - $invoked++; - }; - $result = (yield \Amp\resolve($co())); - $this->assertSame(42, $result); - }); - $this->assertSame(1, $invoked); - } - - public function testCoroutineFauxReturnValue() { - $invoked = 0; - \Amp\run(function () use (&$invoked) { - $co = function () use (&$invoked) { - yield; - yield new CoroutineResult(42); - yield; - $invoked++; - }; - $result = (yield \Amp\resolve($co())); - $this->assertSame(42, $result); - }); - $this->assertSame(1, $invoked); - } - - public function testResolveAcceptsGeneratorCallable() { - \Amp\run(function() { - $result = (yield \Amp\resolve(function () { - yield new CoroutineResult(42); - })); - $this->assertSame(42, $result); - }); - } - - /** - * @expectedException \LogicException - */ - public function testResolveNonGeneratorCallableThrows() { - \Amp\run(function() { - yield \Amp\resolve(function () { - return 42; - }); - }); - } - - /** - * @expectedException \InvalidArgumentException - */ - public function testResolveInvalidArgumentThrows() { - \Amp\run(function() { - yield \Amp\resolve(42); - }); - } - - public function testResolutionFailuresAreThrownIntoGeneratorCoroutine() { - $invoked = 0; - \Amp\run(function () use (&$invoked) { - $foo = function () { - $a = (yield new Success(21)); - $b = 1; - try { - yield new Failure(new \Exception("test")); - $this->fail("Code path should not be reached"); - } catch (\Exception $e) { - $this->assertSame("test", $e->getMessage()); - $b = 2; - } - }; - $result = (yield \Amp\resolve($foo())); - $invoked++; - }); - $this->assertSame(1, $invoked); - } - - /** - * @expectedException \Exception - * @expectedExceptionMessage a moveable feast - */ - public function testExceptionOnInitialAdvanceFailsCoroutineResolution() { - \Amp\run(function () use (&$invoked) { - $co = function () { - throw new \Exception("a moveable feast"); - yield; - }; - $result = (yield \Amp\resolve($co())); - }); - } - - /** - * @dataProvider provideInvalidYields - */ - public function testInvalidYieldFailsCoroutineResolution($badYield) { - try { - \Amp\run(function () use (&$invoked, $badYield) { - $gen = function () use ($badYield) { - yield; - yield $badYield; - yield; - }; - yield \Amp\resolve($gen()); - }); - $this->fail("execution should not reach this point"); - } catch (\DomainException $e) { - $pos = strpos($e->getMessage(), "Unexpected yield (Promise|CoroutineResult|null expected);"); - $this->assertSame(0, $pos); - return; - } - $this->fail("execution should not reach this point"); - } - - public function provideInvalidYields() { - return [ - [42], - [3.14], - ["string"], - [true], - [new \StdClass], - ]; - } - - /** - * @expectedException \Exception - * @expectedExceptionMessage When in the chronicle of wasted time - */ - public function testUncaughtGeneratorExceptionFailsCoroutineResolution() { - $invoked = 0; - \Amp\run(function () use (&$invoked) { - $gen = function () { - yield; - throw new \Exception("When in the chronicle of wasted time"); - yield; - }; - - yield \Amp\resolve($gen()); - $invoked++; - }); - $this->assertSame(1, $invoked); - } - - public function testWait() { - $promisor = new Deferred; - \Amp\once(function () use ($promisor) { - $promisor->succeed(42); - }, 10); - - $result = \Amp\wait($promisor->promise()); - $this->assertSame(42, $result); - } - - /** - * @expectedException \Exception - * @expectedExceptionMessage If the reader prefers, this code may be regarded as fiction - */ - public function testWaitError() { - $promisor = new Deferred; - \Amp\once(function () use ($promisor) { - $promisor->fail(new \Exception( - "If the reader prefers, this code may be regarded as fiction" - )); - }, 10); - - \Amp\wait($promisor->promise()); - } -} - - - - - - - - - - - - - - - - - - - - - - diff --git a/test/LibeventReactorTest.php b/test/LibeventReactorTest.php deleted file mode 100644 index d00d097..0000000 --- a/test/LibeventReactorTest.php +++ /dev/null @@ -1,22 +0,0 @@ -markTestSkipped( - "libevent extension not loaded" - ); - } - } - - public function testGetLoop() { - $result = \Amp\reactor()->getLoop(); - $this->assertInternalType("resource", $result); - } -} diff --git a/test/NativeReactorTest.php b/test/NativeReactorTest.php deleted file mode 100644 index e9d5575..0000000 --- a/test/NativeReactorTest.php +++ /dev/null @@ -1,31 +0,0 @@ -markTestSkipped( - "ext/pcntl required to test onSignal() capture" - ); - } else { - parent::testOnSignalWatcher(); - } - } - - public function testInitiallyDisabledOnSignalWatcher() { - if (!\extension_loaded("pcntl")) { - $this->markTestSkipped( - "ext/pcntl required to test onSignal() capture" - ); - } else { - parent::testInitiallyDisabledOnSignalWatcher(); - } - } -} diff --git a/test/PauseTest.php b/test/PauseTest.php index 05daacc..bfc2006 100644 --- a/test/PauseTest.php +++ b/test/PauseTest.php @@ -2,39 +2,42 @@ namespace Amp\Test; +use Amp; use Amp\Pause; -use Amp\NativeReactor; +use Interop\Async\Loop; class PauseTest extends \PHPUnit_Framework_TestCase { - protected function setUp() { - \Amp\reactor($assign = new NativeReactor); - } - /** * @dataProvider provideBadMillisecondArgs - * @expectedException \DomainException - * @expectedExceptionMessage Pause timeout must be greater than or equal to 1 millisecond + * @expectedException \InvalidArgumentException */ public function testCtorThrowsOnBadMillisecondParam($arg) { - \Amp\run(function () use ($arg) { - new Pause($arg); - }); + $pause = new Pause($arg); } public function provideBadMillisecondArgs() { return [ - [0], + [-3.14], [-1], ]; } - public function testPauseYield() { - $endReached = false; - \Amp\run(function () use (&$endReached) { - $result = (yield new Pause(1)); - $this->assertNull($result); - $endReached = true; + public function testPause() { + $time = 100; + $value = "test"; + $start = microtime(true); + + Loop::execute(function () use (&$result, $time, $value) { + $awaitable = new Pause($time, $value); + + $callback = function ($exception, $value) use (&$result) { + $result = $value; + }; + + $awaitable->when($callback); }); - $this->assertTrue($endReached); + + $this->assertLessThanOrEqual($time, microtime(true) - $start); + $this->assertSame($value, $result); } } diff --git a/test/PlaceholderPrivateTest.php b/test/PlaceholderPrivateTest.php deleted file mode 100644 index 1ba7600..0000000 --- a/test/PlaceholderPrivateTest.php +++ /dev/null @@ -1,9 +0,0 @@ -getPromisor(); - $promise = $promisor->promise(); - $promisor->succeed(42); - $promise->when(function($e, $r, $d) use (&$invoked) { - $this->assertNull($e); - $this->assertSame(42, $r); - $this->assertSame("zanzibar", $d); - ++$invoked; - }, "zanzibar"); - $this->assertSame(1, $invoked); - } - - public function testWatchCallbackDataPassed() { - $invoked = 0; - $promisor = $this->getPromisor(); - $promise = $promisor->promise(); - $promise->watch(function($p, $d) use (&$invoked) { - $this->assertSame(42, $p); - $this->assertSame("zanzibar", $d); - $invoked++; - }, "zanzibar"); - $promisor->update(42); - $promisor->update(42); - $this->assertSame(2, $invoked); - } - - public function testWatchCallbackNotInvokedIfAlreadySucceeded() { - $invoked = 0; - $promisor = $this->getPromisor(); - $promise = $promisor->promise(); - $promisor->succeed(42); - $promise->watch(function($p, $d) use (&$invoked) { - $invoked++; - }); - $this->assertSame(0, $invoked); - } - - public function testWatchCallbackNotInvokedIfAlreadyFailed() { - $invoked = 0; - $promisor = $this->getPromisor(); - $promise = $promisor->promise(); - $exception = new \Exception('test'); - $promisor->fail($exception); - $promise->watch(function($p, $d) use (&$invoked) { - $invoked++; - }); - $this->assertSame(0, $invoked); - } - - /** - * @expectedException \LogicException - * @expectedExceptionMessage Promise already resolved - */ - public function testSucceedThrowsIfAlreadyResolved() { - $promisor = $this->getPromisor(); - $promisor->succeed(42); - $promisor->succeed('zanzibar'); - } - - /** - * @expectedException \LogicException - * @expectedExceptionMessage A Promise cannot act as its own resolution result - */ - public function testSucceedThrowsIfPromiseIsTheResolutionValue() { - $promisor = $this->getPromisor(); - $promise = $promisor->promise(); - $promisor->succeed($promise); - } - - /** - * @expectedException \LogicException - * @expectedExceptionMessage Promise already resolved - */ - public function testFailThrowsIfAlreadyResolved() { - $promisor = $this->getPromisor(); - $promisor->succeed(42); - $promisor->fail(new \Exception); - } - - public function testSucceedingWithPromisePipelinesResult() { - (new NativeReactor)->run(function($reactor) { - $promisor = $this->getPromisor(); - $next = $this->getPromisor(); - - $reactor->once(function() use ($next) { - $next->succeed(42); - }, $msDelay = 1); - - $promisor->succeed($next->promise()); - - $this->assertSame(42, (yield $promisor->promise())); - }); - } - - /** - * @expectedException \RuntimeException - * @expectedExceptionMessage fugazi - */ - public function testFailingWithPromisePipelinesResult() { - (new NativeReactor)->run(function($reactor) { - $promisor = $this->getPromisor(); - $next = $this->getPromisor(); - - $reactor->once(function() use ($next) { - $next->fail(new \RuntimeException('fugazi')); - }, $msDelay = 10); - - $promisor->succeed($next->promise()); - yield $promisor->promise(); - }); - } -} diff --git a/test/PromiseStreamTest.php b/test/PromiseStreamTest.php deleted file mode 100644 index ecd40be..0000000 --- a/test/PromiseStreamTest.php +++ /dev/null @@ -1,135 +0,0 @@ -promise()); - $i = 0; - \Amp\repeat(function ($watcherId) use ($promisor, &$i) { - $i++; - $promisor->update("test{$i}"); - if ($i === 3) { - $promisor->succeed(); - \Amp\cancel($watcherId); - } - }, 10); - - $results = []; - while (yield $stream->valid()) { - $results[] = $stream->consume(); - } - - $this->assertSame(["test1", "test2", "test3"], $results); - $endReached = true; - }); - $this->assertTrue($endReached); - } - - public function testStreamReturnsPromiseResolutionForFirstConsumeCallAfterSuccess() { - $endReached = false; - \Amp\run(function () use (&$endReached) { - $promisor = new \Amp\Deferred; - $stream = new \Amp\PromiseStream($promisor->promise()); - $i = 0; - \Amp\repeat(function ($watcherId) use ($promisor, &$i) { - $i++; - $promisor->update("test{$i}"); - if ($i === 3) { - $promisor->succeed(42); - \Amp\cancel($watcherId); - } - }, 10); - - $results = []; - while (yield $stream->valid()) { - $stream->consume(); - } - - $this->assertSame(42, $stream->consume()); - $endReached = true; - }); - $this->assertTrue($endReached); - } - - public function testStreamRetainsUpdatesUntilInitialized() { - $endReached = false; - \Amp\run(function () use (&$endReached) { - $promisor = new \Amp\Deferred; - $stream = new \Amp\PromiseStream($promisor->promise()); - $promisor->update("foo"); - $promisor->update("bar"); - $promisor->update("baz"); - $promisor->succeed(); - - $results = []; - while (yield $stream->valid()) { - $results[] = $stream->consume(); - } - $endReached = true; - $this->assertSame(["foo", "bar", "baz"], $results); - }); - $this->assertTrue($endReached); - } - - /** - * @expectedException \Exception - * @expectedExceptionMessage test - */ - public function testStreamThrowsIfPromiseFails() { - \Amp\run(function () { - $i = 0; - $promisor = new \Amp\Deferred; - \Amp\repeat(function ($watcherId) use (&$i, $promisor) { - $i++; - $promisor->update($i); - if ($i === 2) { - \Amp\cancel($watcherId); - $promisor->fail(new \Exception( - "test" - )); - } - }, 10); - - $stream = new \Amp\PromiseStream($promisor->promise()); - - $results = []; - while (yield $stream->valid()) { - $results[] = $stream->consume(); - } - }); - } - - /** - * @expectedException \LogicException - * @expectedExceptionMessage Cannot advance PromiseStream beyond unresolved index 0 - */ - public function testPrematureConsumptionThrows() { - \Amp\run(function () { - $promisor = new \Amp\Deferred; - $stream = new \Amp\PromiseStream($promisor->promise()); - $results = []; - $stream->consume(); - }); - } - - /** - * @expectedException \LogicException - * @expectedExceptionMessage Cannot advance PromiseStream beyond completed index 1 - */ - public function testConsumeAfterStreamCompletionThrows() { - \Amp\run(function () { - $promisor = new \Amp\Deferred; - $promisor->update(0); - $promisor->succeed(1); - $stream = new \Amp\PromiseStream($promisor->promise()); - $results = []; - $stream->consume(); - $stream->consume(); - $stream->consume(); - }); - } -} diff --git a/test/PromisorPrivateTest.php b/test/PromisorPrivateTest.php deleted file mode 100644 index 0dfb6b1..0000000 --- a/test/PromisorPrivateTest.php +++ /dev/null @@ -1,12 +0,0 @@ -assertSame($promisor, $promisor->promise()); - } - - /** - * @expectedException \InvalidArgumentException - * @expectedExceptionMessage Throwable Exception instance required to fail a promise - * @dataProvider provideBadFailureArguments - */ - public function testResolvingErrorWithNonExceptionThrows($badArg) { - $promisor = $this->getPromisor(); - $promisor->fail($badArg); - } - - public function provideBadFailureArguments() { - return [ - [1], - [true], - [new \StdClass], - ]; - } -} diff --git a/test/PromisorTest.php b/test/PromisorTest.php deleted file mode 100644 index 2164550..0000000 --- a/test/PromisorTest.php +++ /dev/null @@ -1,157 +0,0 @@ -getPromisor(); - $promise = $promisor->promise(); - $promisor->succeed(42); - $promise->when(function ($e, $r) use (&$invoked) { - $this->assertSame(42, $r); - $this->assertNull($e); - ++$invoked; - }); - $this->assertSame(1, $invoked); - } - - public function testWhenInvokesCallbackWithErrorIfAlreadyFailed() { - $invoked = 0; - $promisor = $this->getPromisor(); - $promise = $promisor->promise(); - $exception = new \Exception('test'); - $promisor->fail($exception); - $promise->when(function ($e, $r) use ($exception, &$invoked) { - $invoked++; - $this->assertSame($exception, $e); - $this->assertNull($r); - }); - $this->assertSame(1, $invoked); - } - - /** - * @expectedException \LogicException - * @expectedExceptionMessage Promise already resolved - */ - public function testSucceedThrowsIfAlreadyResolved() { - $promisor = $this->getPromisor(); - $promisor->succeed(42); - $promisor->succeed('zanzibar'); - } - - /** - * @expectedException \LogicException - * @expectedExceptionMessage A Promise cannot act as its own resolution result - */ - public function testSucceedThrowsIfPromiseIsTheResolutionValue() { - $promisor = $this->getPromisor(); - $promise = $promisor->promise(); - $promisor->succeed($promise); - } - - /** - * @expectedException \LogicException - * @expectedExceptionMessage Promise already resolved - */ - public function testFailThrowsIfAlreadyResolved() { - $promisor = $this->getPromisor(); - $promisor->succeed(42); - $promisor->fail(new \Exception); - } - - public function testSucceedingWithPromisePipelinesResult() { - \Amp\run(function () { - $next = $this->getPromisor(); - $promisor = $this->getPromisor(); - $promisor->succeed($next->promise()); - \Amp\once(function () use ($next) { - $next->succeed(42); - }, $msDelay = 10); - yield; - $result = (yield $promisor->promise()); - $this->assertSame(42, $result); - }); - } - - /** - * @expectedException \RuntimeException - * @expectedExceptionMessage fugazi - */ - public function testFailingWithPromisePipelinesResult() { - \Amp\run(function () { - $promisor = $this->getPromisor(); - $next = $this->getPromisor(); - \Amp\once(function () use ($next) { - $next->fail(new \RuntimeException('fugazi')); - }, $msDelay = 10); - yield; - $promisor->succeed($next->promise()); - yield $promisor->promise(); - }); - } - - public function testUpdate() { - $updatable = 0; - \Amp\run(function () use (&$updatable) { - $i = 0; - $promisor = $this->getPromisor(); - $updater = function ($watcherId) use ($promisor, &$i) { - $promisor->update(++$i); - if ($i === 3) { - \Amp\cancel($watcherId); - // reactor run loop should now be able to exit - } - }; - $promise = $promisor->promise(); - - $promise->watch(function ($updateData) use (&$updatable) { - $updatable += $updateData; - }); - \Amp\repeat($updater, $msDelay = 10); - }); - - $this->assertSame(6, $updatable); - } - - public function testUpdateArgs() { - $updates = new \StdClass; - $updates->arr = []; - - $promisor = $this->getPromisor(); - $promise = $promisor->promise(); - $promise->watch(function ($progress, $cbData) use ($updates) { - $updates->arr[] = \func_get_args(); - }, "cb_data"); - - $promisor->update(1); - $promisor->update(2); - $promisor->update(3); - - $expected = [ - [1, "cb_data"], - [2, "cb_data"], - [3, "cb_data"], - ]; - - $this->assertSame($expected, $updates->arr); - } - - /** - * @expectedException \LogicException - * @expectedExceptionMessage Cannot update resolved promise - */ - public function testUpdateThrowsIfPromiseAlreadyResolved() { - $promisor = $this->getPromisor(); - $promisor->succeed(); - $promisor->update(42); - } -} diff --git a/test/ReactorTest.php b/test/ReactorTest.php deleted file mode 100644 index 6fda528..0000000 --- a/test/ReactorTest.php +++ /dev/null @@ -1,716 +0,0 @@ - false]); - }); - $this->assertFalse($invoked); - } - - public function testOnceWatcherKeepAliveRunResult() { - $invoked = false; - \Amp\run(function () use (&$invoked) { - \Amp\once(function () use (&$invoked) { - $invoked = true; - }, 2000, $options = ["keep_alive" => false]); - }); - $this->assertFalse($invoked); - } - - public function testRepeatWatcherKeepAliveRunResult() { - $invoked = false; - \Amp\run(function () use (&$invoked) { - \Amp\repeat(function () use (&$invoked) { - $invoked = true; - }, 2000, $options = ["keep_alive" => false]); - }); - $this->assertFalse($invoked); - } - - public function testOnReadableWatcherKeepAliveRunResult() { - \Amp\run(function () { - \Amp\onReadable(STDIN, function () { - // empty - }, $options = ["keep_alive" => false]); - }); - } - - public function testOnWritableWatcherKeepAliveRunResult() { - \Amp\run(function () { - \Amp\onWritable(STDOUT, function () { - // empty - }, $options = ["keep_alive" => false]); - }); - } - - public function testOnSignalWatcherKeepAliveRunResult() { - if (!\extension_loaded("pcntl") && !\Amp\reactor() instanceof UvReactor) { - $this->markTestSkipped("ext/pcntl or UvReactor required to test onSignal() registration"); - } - - \Amp\run(function () { - \Amp\onSignal(SIGUSR1, function () { - // empty - }, $options = ["keep_alive" => false]); - }); - } - - /** - * @dataProvider provideRegistrationArgs - */ - public function testWatcherKeepAliveRegistrationInfo($type, $args) { - if ($type === "onSignal") { - if (!\extension_loaded("pcntl") && !\Amp\reactor() instanceof UvReactor) { - $this->markTestSkipped("ext/pcntl or UvReactor required to test onSignal() registration"); - } - $requiresCancel = true; - } else { - $requiresCancel = false; - } - - $func = '\Amp\\' . $type; - if (substr($type, 0, 2) === "on" && $type !== "once") { - $type = "on_" . lcfirst(substr($type, 2)); - } - - // keep_alive is the default - $watcherId1 = \call_user_func_array($func, $args); - $info = \Amp\info(); - $expected = ["enabled" => 1, "disabled" => 0]; - $this->assertSame($expected, $info[$type]); - $this->assertSame(1, $info["keep_alive"]); - - // explicitly keep_alive even though it's the default setting - $argsCopy = $args; - $argsCopy[] = ["keep_alive" => true]; - $watcherId2 = \call_user_func_array($func, $argsCopy); - $info = \Amp\info(); - $expected = ["enabled" => 2, "disabled" => 0]; - $this->assertSame($expected, $info[$type]); - $this->assertSame(2, $info["keep_alive"]); - - // disabling a keep_alive watcher should decrement the count - \Amp\disable($watcherId2); - $info = \Amp\info(); - $this->assertSame(1, $info["keep_alive"]); - - // enabling a keep_alive watcher should increment the count - \Amp\enable($watcherId2); - $info = \Amp\info(); - $this->assertSame(2, $info["keep_alive"]); - - // cancelling a keep_alive watcher should decrement the count - \Amp\cancel($watcherId2); - $info = \Amp\info(); - $this->assertSame(1, $info["keep_alive"]); - - // keep_alive => false should leave the count untouched - $argsCopy = $args; - $argsCopy[] = ["keep_alive" => false]; - $watcherId2 = \call_user_func_array($func, $argsCopy); - $info = \Amp\info(); - $expected = ["enabled" => 2, "disabled" => 0]; - $this->assertSame($expected, $info[$type]); - $this->assertSame(1, $info["keep_alive"]); - - if ($requiresCancel) { - \Amp\cancel($watcherId1); - \Amp\cancel($watcherId2); - } - } - - public function provideRegistrationArgs() { - $args = [ - ["immediately", [function () {}]], - ["once", [function () {}, 5000]], - ["repeat", [function () {}, 5000]], - ["onWritable", [\STDOUT, function () {}]], - ["onReadable", [\STDIN, function () {}]], - ]; - - $args[] = ["onSignal", [defined('SIGUSR1') ? \SIGUSR1 : -1, function () {}]]; - - return $args; - } - - /** - * @dataProvider provideRegistrationArgs - */ - public function testWatcherRegistrationAndCancellationInfo($type, $args) { - if ($type === "onSignal") { - if (!\extension_loaded("pcntl") && !\Amp\reactor() instanceof UvReactor) { - $this->markTestSkipped("ext/pcntl or UvReactor required to test onSignal() registration"); - } - } - - $func = '\Amp\\' . $type; - if (substr($type, 0, 2) === "on" && $type !== "once") { - $type = "on_" . lcfirst(substr($type, 2)); - } - - $watcherId = \call_user_func_array($func, $args); - $this->assertInternalType("string", $watcherId); - $info = \Amp\info(); - $expected = ["enabled" => 1, "disabled" => 0]; - $this->assertSame($expected, $info[$type]); - - // invoke enable() on active watcher to ensure it has no side-effects - \Amp\enable($watcherId); - $info = \Amp\info(); - $expected = ["enabled" => 1, "disabled" => 0]; - $this->assertSame($expected, $info[$type]); - - // invoke disable() twice to ensure it has no side-effects - \Amp\disable($watcherId); - \Amp\disable($watcherId); - - $info = \Amp\info(); - $expected = ["enabled" => 0, "disabled" => 1]; - $this->assertSame($expected, $info[$type]); - - \Amp\cancel($watcherId); - $info = \Amp\info(); - $expected = ["enabled" => 0, "disabled" => 0]; - $this->assertSame($expected, $info[$type]); - - $watcherId = \call_user_func_array($func, $args); - $info = \Amp\info(); - $expected = ["enabled" => 1, "disabled" => 0]; - $this->assertSame($expected, $info[$type]); - - \Amp\disable($watcherId); - $info = \Amp\info(); - $expected = ["enabled" => 0, "disabled" => 1]; - $this->assertSame($expected, $info[$type]); - - \Amp\enable($watcherId); - $info = \Amp\info(); - $expected = ["enabled" => 1, "disabled" => 0]; - $this->assertSame($expected, $info[$type]); - - \Amp\cancel($watcherId); - $info = \Amp\info(); - $expected = ["enabled" => 0, "disabled" => 0]; - $this->assertSame($expected, $info[$type]); - - // invoke cancel() again to ensure it has no side-effects - \Amp\cancel($watcherId); - } - - public function testEnableHasNoEffectOnNonexistentWatcher() { - \Amp\enable("nonexistentWatcher"); - } - - public function testDisableHasNoEffectOnNonexistentWatcher() { - \Amp\disable("nonexistentWatcher"); - } - - public function testCancelHasNoEffectOnNonexistentWatcher() { - \Amp\cancel("nonexistentWatcher"); - } - - /** - * @expectedException \Exception - * @expectedExceptionMessage coroutine error - */ - public function testImmediateCoroutineResolutionError() { - \Amp\run(function () { - yield; - yield new \Amp\Pause(10); - throw new \Exception("coroutine error"); - }); - } - - public function testOnErrorCapturesUncaughtException() { - $msg = ""; - \Amp\onError(function ($error) use (&$msg) { - $msg = $error->getMessage(); - }); - \Amp\run(function () { - throw new \Exception("coroutine error"); - }); - $this->assertSame("coroutine error", $msg); - } - - /** - * @expectedException \Exception - * @expectedExceptionMessage errorception - */ - public function testOnErrorFailure() { - \Amp\onError(function () { - throw new \Exception("errorception"); - }); - \Amp\run(function () { - yield; - yield new \Amp\Pause(10); - throw new \Exception("coroutine error"); - }); - } - - public function testEnablingWatcherAllowsSubsequentInvocation() { - $increment = 0; - $watcherId = \Amp\immediately(function () use (&$increment) { - $increment++; - }); - \Amp\disable($watcherId); - \Amp\once('\Amp\stop', $msDelay = 50); - \Amp\run(); - $this->assertEquals(0, $increment); - \Amp\enable($watcherId); - \Amp\once('\Amp\stop', $msDelay = 50); - \Amp\run(); - $this->assertEquals(1, $increment); - } - - public function testUnresolvedEventsAreReenabledOnRunFollowingPreviousStop() { - $increment = 0; - \Amp\once(function () use (&$increment) { - $increment++; - \Amp\stop(); - }, $msDelay = 150); - - \Amp\run('\Amp\stop'); - - $this->assertEquals(0, $increment); - \usleep(150000); - \Amp\run(); - $this->assertEquals(1, $increment); - } - - public function testTimerWatcherParameterOrder() { - $counter = 0; - \Amp\immediately(function ($watcherId) use (&$counter) { - $this->assertInternalType("string", $watcherId); - if (++$counter === 3) { - \Amp\stop(); - } - }); - \Amp\once(function ($watcherId) use (&$counter) { - $this->assertInternalType("string", $watcherId); - if (++$counter === 3) { - \Amp\stop(); - } - }, $msDelay = 1); - \Amp\repeat(function ($watcherId) use (&$counter) { - $this->assertInternalType("string", $watcherId); - \Amp\cancel($watcherId); - if (++$counter === 3) { - \Amp\stop(); - } - }, $msDelay = 1); - - \Amp\run(); - } - - public function testStreamWatcherParameterOrder() { - $invoked = 0; - \Amp\onWritable(STDOUT, function ($watcherId, $stream) use (&$invoked) { - $this->assertInternalType("string", $watcherId); - $this->assertSame(STDOUT, $stream); - $invoked++; - \Amp\cancel($watcherId); - }); - \Amp\run(); - $this->assertSame(1, $invoked); - } - - public function testDisablingWatcherPreventsSubsequentInvocation() { - $increment = 0; - $watcherId = \Amp\immediately(function () use (&$increment) { - $increment++; - }); - - \Amp\disable($watcherId); - \Amp\once('\Amp\stop', $msDelay = 50); - \Amp\run(); - - $this->assertEquals(0, $increment); - } - - public function testImmediateExecution() { - $increment = 0; - \Amp\immediately(function () use (&$increment) { - $increment++; - }); - \Amp\tick(); - - $this->assertEquals(1, $increment); - } - - public function testImmediatelyCallbacksDontRecurseInSameTick() { - $increment = 0; - \Amp\immediately(function () use (&$increment) { - $increment++; - \Amp\immediately(function () use (&$increment) { - $increment++; - }); - }); - \Amp\tick(); - $this->assertEquals(1, $increment); - } - - public function testTickExecutesReadyEvents() { - $increment = 0; - \Amp\immediately(function () use (&$increment) { - $increment++; - }); - \Amp\tick(); - $this->assertEquals(1, $increment); - } - - public function testRunExecutesEventsUntilExplicitlyStopped() { - $increment = 0; - \Amp\repeat(function ($watcherId) use (&$increment) { - $increment++; - if ($increment === 10) { - \Amp\cancel($watcherId); - } - }, $msInterval = 5); - \Amp\run(); - $this->assertEquals(10, $increment); - } - - /** - * @expectedException RuntimeException - * @expectedExceptionMessage test - */ - public function testReactorAllowsExceptionToBubbleUpDuringTick() { - \Amp\immediately(function () { - throw new \RuntimeException("test"); - }); - \Amp\tick(); - } - - /** - * @expectedException RuntimeException - * @expectedExceptionMessage test - */ - public function testReactorAllowsExceptionToBubbleUpDuringRun() { - \Amp\immediately(function () { - throw new \RuntimeException("test"); - }); - \Amp\run(); - } - - /** - * @expectedException RuntimeException - * @expectedExceptionMessage test - */ - public function testReactorAllowsExceptionToBubbleUpFromRepeatingAlarmDuringRun() { - \Amp\repeat(function () { - throw new \RuntimeException("test"); - }, $msInterval = 0); - \Amp\run(); - } - - public function testOnSignalWatcher() { - if (!\extension_loaded("posix") || !(\extension_loaded("pcntl") || \Amp\reactor() instanceof UvReactor)) { - $this->markTestSkipped( - "ext/posix and UvReactor or ext/pcntl required to test onSignal() capture" - ); - } - $this->expectOutputString("caught SIGUSR1"); - \Amp\run(function () { - \Amp\once(function () { - \posix_kill(\getmypid(), \SIGUSR1); - \Amp\once(function () { - \Amp\stop(); - }, 100); - }, 1); - - \Amp\onSignal(SIGUSR1, function ($watcherId) { - \Amp\cancel($watcherId); - echo "caught SIGUSR1"; - }); - }); - } - - public function testInitiallyDisabledOnSignalWatcher() { - if (!\extension_loaded("posix") || !(\extension_loaded("pcntl") || \Amp\reactor() instanceof UvReactor)) { - $this->markTestSkipped( - "ext/posix and UvReactor or ext/pcntl required to test onSignal() capture" - ); - } - $this->expectOutputString("caught SIGUSR1"); - - \Amp\run(function () { - $sigWatcherId = \Amp\onSignal(SIGUSR1, function () { - echo "caught SIGUSR1"; - \Amp\stop(); - }, $options = ["enable" => false]); - - \Amp\once(function () use ($sigWatcherId) { - \Amp\enable($sigWatcherId); - \Amp\once(function () use ($sigWatcherId) { - \posix_kill(\getmypid(), \SIGUSR1); - }, 10); - }, 10); - }); - } - - public function testCancelRemovesWatcher() { - $watcherId = \Amp\once(function (){ - $this->fail('Watcher was not cancelled as expected'); - }, $msDelay = 20); - - \Amp\immediately(function () use ($watcherId) { - \Amp\cancel($watcherId); - }); - \Amp\once('\Amp\stop', $msDelay = 5); - \Amp\run(); - } - - public function testOnWritableWatcher() { - $flag = false; - \Amp\onWritable(STDOUT, function () use (&$flag) { - $flag = true; - \Amp\stop(); - }); - \Amp\once('\Amp\stop', $msDelay = 50); - - \Amp\run(); - $this->assertTrue($flag); - } - - public function testInitiallyDisabledWriteWatcher() { - $increment = 0; - $options = ["enable" => false]; - \Amp\onWritable(STDOUT, function () use (&$increment) { - $increment++; - }, $options); - \Amp\once('\Amp\stop', $msDelay = 50); - \Amp\run(); - - $this->assertSame(0, $increment); - } - - public function testInitiallyDisabledWriteWatcherIsTriggeredOnceEnabled() { - $increment = 0; - $options = ["enable" => false]; - $watcherId = \Amp\onWritable(STDOUT, function () use (&$increment) { - $increment++; - }, $options); - \Amp\immediately(function () use ($watcherId) { - \Amp\enable($watcherId); - }); - - \Amp\once('\Amp\stop', $msDelay = 250); - \Amp\run(); - - $this->assertTrue($increment > 0); - } - - /** - * @expectedException RuntimeException - */ - public function testStreamWatcherDoesntSwallowExceptions() { - \Amp\onWritable(STDOUT, function () { throw new \RuntimeException; }); - \Amp\once('\Amp\stop', $msDelay = 50); - \Amp\run(); - } - - public function testGarbageCollection() { - \Amp\once('\Amp\stop', $msDelay = 100); - \Amp\run(); - } - - public function testOnStartGeneratorResolvesAutomatically() { - $test = ''; - \Amp\run(function () use (&$test) { - yield; - $test = "Thus Spake Zarathustra"; - \Amp\once('\Amp\stop', 1); - }); - $this->assertSame("Thus Spake Zarathustra", $test); - } - - public function testImmediatelyGeneratorResolvesAutomatically() { - $test = ''; - \Amp\immediately(function () use (&$test) { - yield; - $test = "The abyss will gaze back into you"; - \Amp\once('\Amp\stop', 50); - }); - \Amp\run(); - $this->assertSame("The abyss will gaze back into you", $test); - } - - public function testOnceGeneratorResolvesAutomatically() { - $test = ''; - $gen = function () use (&$test) { - yield; - $test = "There are no facts, only interpretations."; - \Amp\once('\Amp\stop', 50); - }; - \Amp\once($gen, 1); - \Amp\run(); - $this->assertSame("There are no facts, only interpretations.", $test); - } - - public function testRepeatGeneratorResolvesAutomatically() { - $test = ''; - $gen = function ($watcherId) use (&$test) { - \Amp\cancel($watcherId); - yield; - $test = "Art is the supreme task"; - \Amp\stop(); - }; - \Amp\repeat($gen, 50); - \Amp\run(); - $this->assertSame("Art is the supreme task", $test); - } - - public function testOnErrorCallbackInterceptsUncaughtException() { - $var = null; - \Amp\onError(function ($e) use (&$var) { - $var = $e->getMessage(); - }); - \Amp\run(function () { throw new \Exception('test'); }); - $this->assertSame('test', $var); - } - - public function testReactorRunsUntilNoWatchersRemain() { - $var1 = 0; - \Amp\repeat(function ($watcherId) use (&$var1) { - if (++$var1 === 3) { - \Amp\cancel($watcherId); - } - }, 0); - - $var2 = 0; - \Amp\onWritable(STDOUT, function ($watcherId) use (&$var2) { - if (++$var2 === 4) { - \Amp\cancel($watcherId); - } - }); - - \Amp\run(); - - $this->assertSame(3, $var1); - $this->assertSame(4, $var2); - } - - public function testReactorRunsUntilNoWatchersRemainWhenStartedImmediately() { - $var1 = 0; - $var2 = 0; - \Amp\run(function () use (&$var1, &$var2) { - \Amp\repeat(function ($watcherId) use (&$var1) { - if (++$var1 === 3) { - \Amp\cancel($watcherId); - } - }, 0); - - \Amp\onWritable(STDOUT, function ($watcherId) use (&$var2) { - if (++$var2 === 4) { - \Amp\cancel($watcherId); - } - }); - }); - - $this->assertSame(3, $var1); - $this->assertSame(4, $var2); - } - - public function testOptionalCallbackDataPassedOnInvocation() { - $callbackData = new \StdClass; - $options = ["cb_data" => $callbackData]; - - \Amp\immediately(function ($watcherId, $callbackData) { - $callbackData->immediately = true; - }, $options); - \Amp\once(function ($watcherId, $callbackData) { - $callbackData->once = true; - }, 1, $options); - \Amp\repeat(function ($watcherId, $callbackData) { - $callbackData->repeat = true; - \Amp\cancel($watcherId); - }, 1, $options); - \Amp\onWritable(STDERR, function ($watcherId, $stream, $callbackData) { - $callbackData->onWritable = true; - \Amp\cancel($watcherId); - }, $options); - \Amp\run(); - - $this->assertTrue($callbackData->immediately); - $this->assertTrue($callbackData->once); - $this->assertTrue($callbackData->repeat); - $this->assertTrue($callbackData->onWritable); - } - - public function testOptionalRepeatWatcherDelay() { - $invoked = false; - \Amp\repeat(function ($watcherId) use (&$invoked) { - $invoked = true; - \Amp\cancel($watcherId); - }, $msInterval = 10000, $options = ["ms_delay" => 1]); - \Amp\once('\Amp\stop', 50); - \Amp\run(); - $this->assertTrue($invoked); - } - - public function testOptionalDisable() { - $options = ["enable" => false]; - - \Amp\immediately(function ($watcherId, $callbackData) { - $this->fail("disabled watcher should not invoke callback"); - }, $options); - \Amp\once(function ($watcherId, $callbackData) { - $this->fail("disabled watcher should not invoke callback"); - }, 1, $options); - \Amp\repeat(function ($watcherId, $callbackData) { - $this->fail("disabled watcher should not invoke callback"); - \Amp\cancel($watcherId); - }, 1, $options); - \Amp\onWritable(STDERR, function ($watcherId, $stream, $callbackData) { - $this->fail("disabled watcher should not invoke callback"); - \Amp\cancel($watcherId); - }, $options); - - \Amp\run(); - } -} diff --git a/test/StructTest.php b/test/StructTest.php index 3f9627a..187d1a3 100644 --- a/test/StructTest.php +++ b/test/StructTest.php @@ -2,6 +2,11 @@ namespace Amp\Test; +class StructTestFixture { + use \Amp\Struct; + public $callback; +} + class StructTest extends \PHPUnit_Framework_TestCase { /** * @expectedException \DomainException diff --git a/test/UvReactorTest.php b/test/UvReactorTest.php deleted file mode 100644 index 4dc5414..0000000 --- a/test/UvReactorTest.php +++ /dev/null @@ -1,55 +0,0 @@ -markTestSkipped( - "php-uv extension not loaded" - ); - } - } - - public function testGetLoop() { - $result = \Amp\reactor()->getLoop(); - $this->assertInternalType("resource", $result); - } - - public function testOnSignalWatcherKeepAliveRunResult() { - \Amp\run(function () { - \Amp\onSignal(\Uv::SIGUSR1, function () { - // empty - }, $options = ["keep_alive" => false]); - }); - } - - /** - * We need to override the default ReactorTest function to use the correct signal constant - */ - public function provideRegistrationArgs() { - $result = [ - ["immediately", [function () {}]], - ["once", [function () {}, 5000]], - ["repeat", [function () {}, 5000]], - ["onWritable", [\STDOUT, function () {}]], - ["onReadable", [\STDIN, function () {}]], - ]; - - if (\extension_loaded("uv")) { - $result[] = ["onSignal", [\Uv::SIGUSR1, function () {}]]; - } - - return $result; - } -} diff --git a/test/bootstrap.php b/test/bootstrap.php deleted file mode 100644 index 6a22524..0000000 --- a/test/bootstrap.php +++ /dev/null @@ -1,18 +0,0 @@ -