2015-03-16 20:04:01 +01:00
|
|
|
<?php
|
|
|
|
|
|
|
|
namespace Amp\Test;
|
|
|
|
|
|
|
|
use Amp\NativeReactor;
|
|
|
|
|
|
|
|
abstract class PromisorTest extends \PHPUnit_Framework_TestCase {
|
|
|
|
abstract protected function getPromisor();
|
|
|
|
|
|
|
|
public function testWhenInvokesCallbackWithResultIfAlreadySucceeded() {
|
|
|
|
$invoked = 0;
|
|
|
|
$promisor = $this->getPromisor();
|
|
|
|
$promise = $promisor->promise();
|
|
|
|
$promisor->succeed(42);
|
|
|
|
$promise->when(function($e, $r) use (&$invoked) {
|
|
|
|
$this->assertSame(42, $r);
|
|
|
|
$this->assertNull($e);
|
|
|
|
++$invoked;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testWhenInvokesCallbackWithErrorIfAlreadyFailed() {
|
|
|
|
$promisor = $this->getPromisor();
|
|
|
|
$promise = $promisor->promise();
|
|
|
|
$exception = new \Exception('test');
|
|
|
|
$promisor->fail($exception);
|
|
|
|
$promise->when(function($e, $r) use ($exception) {
|
|
|
|
$this->assertSame($exception, $e);
|
|
|
|
$this->assertNull($r);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @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) {
|
|
|
|
$next = $this->getPromisor();
|
|
|
|
$promisor = $this->getPromisor();
|
|
|
|
$promisor->succeed($next->promise());
|
|
|
|
$once = function() use ($next) { $next->succeed(42); };
|
|
|
|
$reactor->once($once, $msDelay = 10);
|
|
|
|
yield;
|
2015-04-30 19:41:14 +02:00
|
|
|
$result = (yield $promisor->promise());
|
2015-03-16 20:04:01 +01:00
|
|
|
$this->assertSame(42, $result);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @expectedException \RuntimeException
|
|
|
|
* @expectedExceptionMessage fugazi
|
|
|
|
*/
|
|
|
|
public function testFailingWithPromisePipelinesResult() {
|
|
|
|
(new NativeReactor)->run(function($reactor) {
|
|
|
|
$promisor = $this->getPromisor();
|
|
|
|
$next = $this->getPromisor();
|
|
|
|
$once = function() use ($next) { $next->fail(new \RuntimeException('fugazi')); };
|
|
|
|
$reactor->once($once, $msDelay = 10);
|
|
|
|
yield;
|
|
|
|
$promisor->succeed($next->promise());
|
|
|
|
|
|
|
|
yield $promisor->promise();
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testUpdate() {
|
|
|
|
$updatable = 0;
|
|
|
|
(new NativeReactor)->run(function($reactor) use (&$updatable) {
|
|
|
|
$i = 0;
|
|
|
|
$promisor = $this->getPromisor();
|
|
|
|
$updater = function($reactor, $watcherId) use ($promisor, &$i) {
|
|
|
|
$promisor->update(++$i);
|
|
|
|
if ($i === 3) {
|
|
|
|
$reactor->cancel($watcherId);
|
|
|
|
// reactor run loop should now be able to exit
|
|
|
|
}
|
|
|
|
};
|
|
|
|
$promise = $promisor->promise();
|
|
|
|
|
|
|
|
$promise->watch(function($updateData) use (&$updatable) {
|
|
|
|
$updatable += $updateData;
|
|
|
|
});
|
|
|
|
$reactor->repeat($updater, $msDelay = 10);
|
|
|
|
});
|
|
|
|
|
|
|
|
$this->assertSame(6, $updatable);
|
|
|
|
}
|
|
|
|
}
|