1
0
mirror of https://github.com/danog/amp.git synced 2024-12-03 18:07:57 +01:00
amp/test/EmitSourceTest.php

214 lines
5.3 KiB
PHP
Raw Normal View History

2020-05-13 17:15:21 +02:00
<?php
namespace Amp\Test;
use Amp\DisposedException;
2020-05-28 19:59:55 +02:00
use Amp\Internal\EmitSource;
2020-05-21 17:11:22 +02:00
use Amp\PHPUnit\AsyncTestCase;
2020-05-13 17:15:21 +02:00
use Amp\Promise;
use Amp\Success;
2020-05-28 19:59:55 +02:00
class EmitSourceTest extends AsyncTestCase
2020-05-13 17:15:21 +02:00
{
2020-05-28 19:59:55 +02:00
/** @var EmitSource */
2020-05-13 17:15:21 +02:00
private $source;
public function setUp()
{
2020-05-21 17:11:22 +02:00
parent::setUp();
2020-05-28 19:59:55 +02:00
$this->source = new EmitSource;
2020-05-13 17:15:21 +02:00
}
2020-05-28 19:59:55 +02:00
public function testEmit()
2020-05-13 17:15:21 +02:00
{
2020-05-28 19:59:55 +02:00
$value = 'Emited Value';
2020-05-13 17:15:21 +02:00
2020-05-28 19:59:55 +02:00
$promise = $this->source->emit($value);
2020-05-21 17:11:22 +02:00
$stream = $this->source->stream();
2020-05-13 17:15:21 +02:00
2020-05-21 17:11:22 +02:00
$this->assertSame($value, yield $stream->continue());
2020-05-28 19:59:55 +02:00
$continue = $stream->continue(); // Promise will not resolve until another value is emitted or stream completed.
2020-05-21 17:11:22 +02:00
$this->assertInstanceOf(Promise::class, $promise);
$this->assertNull(yield $promise);
$this->source->complete();
2020-05-13 17:15:21 +02:00
2020-05-21 17:11:22 +02:00
$this->assertNull(yield $continue);
2020-05-13 17:15:21 +02:00
}
/**
2020-05-28 19:59:55 +02:00
* @depends testEmit
2020-05-13 17:15:21 +02:00
*/
2020-05-28 19:59:55 +02:00
public function testEmitAfterComplete()
2020-05-13 17:15:21 +02:00
{
$this->expectException(\Error::class);
2020-05-28 19:59:55 +02:00
$this->expectExceptionMessage('Streams cannot emit values after calling complete');
2020-05-13 17:15:21 +02:00
$this->source->complete();
2020-05-28 19:59:55 +02:00
$this->source->emit(1);
2020-05-13 17:15:21 +02:00
}
/**
2020-05-28 19:59:55 +02:00
* @depends testEmit
2020-05-13 17:15:21 +02:00
*/
2020-05-28 19:59:55 +02:00
public function testEmitingNull()
2020-05-13 17:15:21 +02:00
{
2020-05-21 17:11:22 +02:00
$this->expectException(\TypeError::class);
2020-05-28 19:59:55 +02:00
$this->expectExceptionMessage('Streams cannot emit NULL');
2020-05-21 17:11:22 +02:00
2020-05-28 19:59:55 +02:00
$this->source->emit(null);
2020-05-13 17:15:21 +02:00
}
/**
2020-05-28 19:59:55 +02:00
* @depends testEmit
2020-05-13 17:15:21 +02:00
*/
2020-05-28 19:59:55 +02:00
public function testEmitingPromise()
2020-05-13 17:15:21 +02:00
{
2020-05-21 17:11:22 +02:00
$this->expectException(\TypeError::class);
2020-05-28 19:59:55 +02:00
$this->expectExceptionMessage('Streams cannot emit promises');
2020-05-13 17:15:21 +02:00
2020-05-28 19:59:55 +02:00
$this->source->emit(new Success);
2020-05-13 17:15:21 +02:00
}
public function testDoubleComplete()
{
$this->expectException(\Error::class);
$this->expectExceptionMessage('Stream has already been completed');
$this->source->complete();
$this->source->complete();
}
public function testDoubleFail()
{
$this->expectException(\Error::class);
$this->expectExceptionMessage('Stream has already been completed');
$this->source->fail(new \Exception);
$this->source->fail(new \Exception);
}
public function testDoubleStart()
{
$stream = $this->source->stream();
2020-05-13 17:15:21 +02:00
$this->expectException(\Error::class);
$this->expectExceptionMessage('A stream may be started only once');
$stream = $this->source->stream();
2020-05-13 17:15:21 +02:00
}
2020-05-28 19:59:55 +02:00
public function testEmitAfterContinue()
2020-05-13 17:15:21 +02:00
{
2020-05-28 19:59:55 +02:00
$value = 'Emited Value';
2020-05-21 17:11:22 +02:00
$stream = $this->source->stream();
2020-05-13 17:15:21 +02:00
2020-05-21 17:11:22 +02:00
$promise = $stream->continue();
$this->assertInstanceOf(Promise::class, $promise);
2020-05-13 17:15:21 +02:00
2020-05-28 19:59:55 +02:00
$backPressure = $this->source->emit($value);
2020-05-13 17:15:21 +02:00
2020-05-21 17:11:22 +02:00
$this->assertSame($value, yield $promise);
2020-05-13 17:15:21 +02:00
2020-05-21 17:11:22 +02:00
$stream->continue();
$this->assertNull(yield $backPressure);
2020-05-13 17:15:21 +02:00
}
public function testContinueAfterComplete()
{
2020-05-21 17:11:22 +02:00
$stream = $this->source->stream();
2020-05-13 17:15:21 +02:00
2020-05-21 17:11:22 +02:00
$this->source->complete();
2020-05-13 17:15:21 +02:00
2020-05-21 17:11:22 +02:00
$promise = $stream->continue();
$this->assertInstanceOf(Promise::class, $promise);
2020-05-13 17:15:21 +02:00
2020-05-21 17:11:22 +02:00
$this->assertNull(yield $promise);
2020-05-13 17:15:21 +02:00
}
public function testContinueAfterFail()
{
2020-05-21 17:11:22 +02:00
$stream = $this->source->stream();
2020-05-13 17:15:21 +02:00
2020-05-21 17:11:22 +02:00
$this->source->fail(new \Exception('Stream failed'));
2020-05-13 17:15:21 +02:00
2020-05-21 17:11:22 +02:00
$promise = $stream->continue();
$this->assertInstanceOf(Promise::class, $promise);
2020-05-13 17:15:21 +02:00
2020-05-21 17:11:22 +02:00
$this->expectException(\Exception::class);
$this->expectExceptionMessage('Stream failed');
2020-05-13 17:15:21 +02:00
2020-05-21 17:11:22 +02:00
yield $promise;
2020-05-13 17:15:21 +02:00
}
public function testCompleteAfterContinue()
{
2020-05-21 17:11:22 +02:00
$stream = $this->source->stream();
2020-05-13 17:15:21 +02:00
2020-05-21 17:11:22 +02:00
$promise = $stream->continue();
$this->assertInstanceOf(Promise::class, $promise);
2020-05-13 17:15:21 +02:00
2020-05-21 17:11:22 +02:00
$this->source->complete();
2020-05-13 17:15:21 +02:00
2020-05-21 17:11:22 +02:00
$this->assertNull(yield $promise);
2020-05-13 17:15:21 +02:00
}
public function testDestroyingStreamRelievesBackPressure()
{
$stream = $this->source->stream();
2020-05-13 17:15:21 +02:00
$invoked = 0;
$onResolved = function () use (&$invoked) {
$invoked++;
};
foreach (\range(1, 5) as $value) {
2020-05-28 19:59:55 +02:00
$promise = $this->source->emit($value);
2020-05-13 17:15:21 +02:00
$promise->onResolve($onResolved);
}
$this->assertSame(0, $invoked);
unset($stream); // Should relieve all back-pressure.
$this->assertSame(5, $invoked);
$this->source->complete(); // Should not throw.
$this->expectException(\Error::class);
$this->expectExceptionMessage('Stream has already been completed');
$this->source->complete(); // Should throw.
}
2020-05-28 19:59:55 +02:00
public function testEmitAfterDisposal()
2020-05-13 17:15:21 +02:00
{
$this->expectException(DisposedException::class);
$this->expectExceptionMessage('The stream has been disposed');
2020-05-21 17:11:22 +02:00
$stream = $this->source->stream();
2020-05-28 19:59:55 +02:00
$promise = $this->source->emit(1);
2020-05-21 17:11:22 +02:00
$stream->dispose();
$this->assertNull(yield $promise);
2020-05-28 19:59:55 +02:00
yield $this->source->emit(1);
}
2020-05-28 19:59:55 +02:00
public function testEmitAfterDestruct()
{
$this->expectException(DisposedException::class);
$this->expectExceptionMessage('The stream has been disposed');
2020-05-21 17:11:22 +02:00
$stream = $this->source->stream();
2020-05-28 19:59:55 +02:00
$promise = $this->source->emit(1);
2020-05-21 17:11:22 +02:00
unset($stream);
$this->assertNull(yield $promise);
2020-05-28 19:59:55 +02:00
yield $this->source->emit(1);
2020-05-13 17:15:21 +02:00
}
}