Skip to content

Commit

Permalink
More tests
Browse files Browse the repository at this point in the history
  • Loading branch information
trowski committed Dec 17, 2016
1 parent 11f1c7e commit 8ef760f
Show file tree
Hide file tree
Showing 3 changed files with 352 additions and 1 deletion.
39 changes: 39 additions & 0 deletions test/CallableMakerTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php declare(strict_types = 1);

namespace Amp\Test;

class CallableMaker {
use \Amp\CallableMaker {
callableFromInstanceMethod as public;
callableFromStaticMethod as public;
}

public function instanceMethod() {
return __METHOD__;
}

public static function staticMethod() {
return __METHOD__;
}
}

class CallableMakerTest extends \PHPUnit_Framework_TestCase {
/** @var \Amp\Test\CallableMaker */
private $maker;

public function setUp() {
$this->maker = new CallableMaker;
}

public function testCallableFromInstanceMethod() {
$callable = $this->maker->callableFromInstanceMethod("instanceMethod");
$this->assertInternalType("callable", $callable);
$this->assertSame(\sprintf("%s::%s", CallableMaker::class, "instanceMethod"), $callable());
}

public function testCallableFromStaticMethod() {
$callable = $this->maker->callableFromInstanceMethod("staticMethod");
$this->assertInternalType("callable", $callable);
$this->assertSame(\sprintf("%s::%s", CallableMaker::class, "staticMethod"), $callable());
}
}
67 changes: 66 additions & 1 deletion test/CoroutineTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,71 @@ public function testInvalidYieldAfterYieldPromise() {

$this->assertInstanceOf(InvalidYieldError::class, $reason);
}

/**
* @depends testInvalidYield
*/
public function testInvalidYieldCatchingThrownException() {
$generator = function () {
try {
yield 1;
} catch (\Error $exception) {
// No further yields.
}
};

$coroutine = new Coroutine($generator());

$coroutine->when(function ($exception) use (&$reason) {
$reason = $exception;
});

$this->assertInstanceOf(InvalidYieldError::class, $reason);
}

/**
* @depends testInvalidYieldCatchingThrownException
*/
public function testInvalidYieldCatchingThrownExceptionAndYieldingAgain() {
$generator = function () {
try {
yield 1;
} catch (\Error $exception) {
yield new Success;
}
};

$coroutine = new Coroutine($generator());

$coroutine->when(function ($exception) use (&$reason) {
$reason = $exception;
});

$this->assertInstanceOf(InvalidYieldError::class, $reason);
}

/**
* @depends testInvalidYieldCatchingThrownException
*/
public function testInvalidYieldCatchingThrownExceptionAndThrowing() {
$exception = new \Exception;
$generator = function () use ($exception) {
try {
yield 1;
} catch (\Error $error) {
throw $exception;
}
};

$coroutine = new Coroutine($generator());

$coroutine->when(function ($exception) use (&$reason) {
$reason = $exception;
});

$this->assertInstanceOf(InvalidYieldError::class, $reason);
$this->assertSame($exception, $reason->getPrevious());
}

/**
* @depends testInvalidYield
Expand Down Expand Up @@ -296,7 +361,7 @@ public function testGeneratorThrowingExceptionWithFinallyYieldingPendingPromise(
try {
throw $exception;
} finally {
$yielded = (yield new Pause(self::TIMEOUT, $value));
$yielded = yield new Pause(self::TIMEOUT, $value);
}
};

Expand Down
247 changes: 247 additions & 0 deletions test/ProducerTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,247 @@
<?php declare(strict_types = 1);

namespace Amp\Test;

use Amp\{ Deferred, Failure, Success };
use Interop\Async\{ Loop, Promise };

class Producer {
use \Amp\Internal\Producer {
emit as public;
resolve as public;
fail as public;
}
}

class ProducerTest extends \PHPUnit_Framework_TestCase {
/** @var \Amp\Test\Producer */
private $producer;

public function setUp() {
$this->producer = new Producer;
}

public function testEmit() {
$invoked = false;
$value = 1;

$callback = function ($emitted) use (&$invoked, $value) {
$invoked = true;
$this->assertSame($emitted, $value);
};

$this->producer->subscribe($callback);
$promise = $this->producer->emit($value);

$this->assertInstanceOf(Promise::class, $promise);
$this->assertTrue($invoked);
}

/**
* @depends testEmit
*/
public function testEmitSuccessfulPromise() {
$invoked = false;
$value = 1;
$promise = new Success($value);

$callback = function ($emitted) use (&$invoked, $value) {
$invoked = true;
$this->assertSame($emitted, $value);
};

$this->producer->subscribe($callback);
$this->producer->emit($promise);

$this->assertTrue($invoked);
}

/**
* @depends testEmit
*/
public function testEmitFailedPromise() {
$invoked = false;
$exception = new \Exception;
$promise = new Failure($exception);

$callback = function ($emitted) use (&$invoked) {
$invoked = true;
};

$this->producer->subscribe($callback);
$this->producer->emit($promise);

$this->assertFalse($invoked);

$this->producer->when(function ($exception) use (&$invoked, &$reason) {
$invoked = true;
$reason = $exception;
});

$this->assertTrue($invoked);
$this->assertSame($exception, $reason);
}

/**
* @depends testEmit
*/
public function testEmitPendingPromise() {
$invoked = false;
$value = 1;
$deferred = new Deferred;

$callback = function ($emitted) use (&$invoked) {
$invoked = true;
};

$callback = function ($emitted) use (&$invoked, $value) {
$invoked = true;
$this->assertSame($emitted, $value);
};

$this->producer->subscribe($callback);
$this->producer->emit($deferred->promise());

$this->assertFalse($invoked);

$deferred->resolve($value);

$this->assertTrue($invoked);
}

/**
* @depends testEmit
*/
public function testEmitPendingPromiseThenNonPromise() {
$invoked = false;
$deferred = new Deferred;

$callback = function ($emitted) use (&$invoked, &$result) {
$invoked = true;
$result = $emitted;
};

$this->producer->subscribe($callback);
$this->producer->emit($deferred->promise());

$this->assertFalse($invoked);

$this->producer->emit(2);
$this->assertTrue($invoked);
$this->assertSame(2, $result);

$deferred->resolve(1);
$this->assertSame(1, $result);
}

/**
* @depends testEmit
* @expectedException \Error
* @expectedExceptionMessage The observable has been resolved; cannot emit more values
*/
public function testEmitAfterResolve() {
$this->producer->resolve();
$this->producer->emit(1);
}

/**
* @depends testEmit
* @expectedException \Error
* @expectedExceptionMessage The observable was resolved before the promise result could be emitted
*/
public function testEmitPendingPromiseThenResolve() {
$invoked = false;
$deferred = new Deferred;

$promise = $this->producer->emit($deferred->promise());

$this->producer->resolve();
$deferred->resolve();

$promise->when(function ($exception) use (&$invoked, &$reason) {
$invoked = true;
$reason = $exception;
});

$this->assertTrue($invoked);
throw $reason;
}

/**
* @depends testEmit
* @expectedException \Error
* @expectedExceptionMessage The observable was resolved before the promise result could be emitted
*/
public function testEmitPendingPromiseThenFail() {
$invoked = false;
$deferred = new Deferred;

$promise = $this->producer->emit($deferred->promise());

$this->producer->resolve();
$deferred->fail(new \Exception);

$promise->when(function ($exception) use (&$invoked, &$reason) {
$invoked = true;
$reason = $exception;
});

$this->assertTrue($invoked);
throw $reason;
}

public function testSubscriberThrows() {
$exception = new \Exception;

try {
Loop::execute(function () use ($exception) {
$this->producer->subscribe(function () use ($exception) {
throw $exception;
});

$this->producer->emit(1);
});
} catch (\Exception $caught) {
$this->assertSame($exception, $caught);
}
}

public function testSubscriberReturnsSuccessfulPromise() {
$invoked = true;
$value = 1;
$promise = new Success($value);

$this->producer->subscribe(function () use ($promise) {
return $promise;
});

$promise = $this->producer->emit(1);
$promise->when(function () use (&$invoked) {
$invoked = true;
});

$this->assertTrue($invoked);
}

public function testSubscriberReturnsFailedPromise() {
$exception = new \Exception;
$promise = new Failure($exception);

try {
Loop::execute(function () use ($exception, $promise) {
$this->producer->subscribe(function () use ($promise) {
return $promise;
});

$promise = $this->producer->emit(1);
$promise->when(function () use (&$invoked) {
$invoked = true;
});

$this->assertTrue($invoked);
});
} catch (\Exception $caught) {
$this->assertSame($exception, $caught);
}
}
}

0 comments on commit 8ef760f

Please sign in to comment.