1
0
mirror of https://github.com/danog/amp.git synced 2024-12-12 09:29:45 +01:00
amp/test/StreamIteratorTest.php

248 lines
6.8 KiB
PHP
Raw Normal View History

<?php
2016-12-13 22:25:52 +01:00
namespace Amp\Test;
use Amp;
use Amp\Producer;
2017-04-13 18:20:46 +02:00
use Amp\StreamIterator;
use Amp\Pause;
use Amp\Emitter;
use Amp\Loop;
2017-04-13 18:20:46 +02:00
use PHPUnit\Framework\TestCase;
2016-12-13 22:25:52 +01:00
2017-04-13 18:20:46 +02:00
class StreamIteratorTest extends TestCase {
2016-12-13 22:25:52 +01:00
const TIMEOUT = 10;
2017-01-04 02:10:27 +01:00
public function testSingleEmittingStream() {
Loop::run(function () {
2016-12-13 22:25:52 +01:00
$value = 1;
2017-01-04 02:10:27 +01:00
$stream = new Producer(function (callable $emit) use ($value) {
2016-12-13 22:25:52 +01:00
yield $emit($value);
return $value;
});
2017-04-13 18:20:46 +02:00
$streamIterator = new StreamIterator($stream);
2017-04-13 18:20:46 +02:00
while (yield $streamIterator->advance()) {
$this->assertSame($streamIterator->getCurrent(), $value);
2016-12-13 22:25:52 +01:00
}
2017-04-13 18:20:46 +02:00
$this->assertSame($streamIterator->getResult(), $value);
});
2016-12-13 22:25:52 +01:00
}
2016-12-13 22:25:52 +01:00
/**
2017-01-04 02:10:27 +01:00
* @depends testSingleEmittingStream
2016-12-13 22:25:52 +01:00
*/
2017-01-04 02:10:27 +01:00
public function testFastEmittingStream() {
Loop::run(function () {
2016-12-13 22:25:52 +01:00
$count = 10;
2017-01-04 02:10:27 +01:00
$emitter = new Emitter;
2017-04-13 18:20:46 +02:00
$streamIterator = new StreamIterator($emitter->stream());
2016-12-13 22:25:52 +01:00
for ($i = 0; $i < $count; ++$i) {
2017-01-04 02:10:27 +01:00
$promises[] = $emitter->emit($i);
2016-12-13 22:25:52 +01:00
}
2017-01-04 02:10:27 +01:00
$emitter->resolve($i);
2017-04-13 18:20:46 +02:00
for ($i = 0; yield $streamIterator->advance(); ++$i) {
$this->assertSame($streamIterator->getCurrent(), $i);
2016-12-13 22:25:52 +01:00
}
2016-12-13 22:25:52 +01:00
$this->assertSame($count, $i);
2017-04-13 18:20:46 +02:00
$this->assertSame($streamIterator->getResult(), $i);
});
2016-12-13 22:25:52 +01:00
}
2016-12-13 22:25:52 +01:00
/**
2017-01-04 02:10:27 +01:00
* @depends testSingleEmittingStream
2016-12-13 22:25:52 +01:00
*/
2017-01-04 02:10:27 +01:00
public function testSlowEmittingStream() {
Loop::run(function () {
2016-12-13 22:25:52 +01:00
$count = 10;
2017-01-04 02:10:27 +01:00
$stream = new Producer(function (callable $emit) use ($count) {
2016-12-13 22:25:52 +01:00
for ($i = 0; $i < $count; ++$i) {
yield new Pause(self::TIMEOUT);
yield $emit($i);
}
return $i;
});
2017-04-13 18:20:46 +02:00
$streamIterator = new StreamIterator($stream);
2017-04-13 18:20:46 +02:00
for ($i = 0; yield $streamIterator->advance(); ++$i) {
$this->assertSame($streamIterator->getCurrent(), $i);
2016-12-13 22:25:52 +01:00
}
2016-12-13 22:25:52 +01:00
$this->assertSame($count, $i);
2017-04-13 18:20:46 +02:00
$this->assertSame($streamIterator->getResult(), $i);
});
2016-12-13 22:25:52 +01:00
}
2016-12-13 22:25:52 +01:00
/**
2017-01-04 02:10:27 +01:00
* @depends testFastEmittingStream
2016-12-13 22:25:52 +01:00
*/
public function testDrain() {
Loop::run(function () {
2016-12-13 22:25:52 +01:00
$count = 10;
$expected = \range(0, $count - 1);
2017-01-04 02:10:27 +01:00
$emitter = new Emitter;
2017-04-13 18:20:46 +02:00
$streamIterator = new StreamIterator($emitter->stream());
2016-12-13 22:25:52 +01:00
for ($i = 0; $i < $count; ++$i) {
2017-01-04 02:10:27 +01:00
$promises[] = $emitter->emit($i);
2016-12-13 22:25:52 +01:00
}
$value = null;
2017-04-13 18:20:46 +02:00
if (yield $streamIterator->advance()) {
$value = $streamIterator->getCurrent();
}
$this->assertSame(reset($expected), $value);
unset($expected[0]);
2017-01-04 02:10:27 +01:00
$emitter->resolve($i);
2017-04-13 18:20:46 +02:00
$values = $streamIterator->drain();
$this->assertSame($expected, $values);
});
2016-12-13 22:25:52 +01:00
}
2016-12-13 22:25:52 +01:00
/**
* @expectedException \Error
2017-01-04 02:10:27 +01:00
* @expectedExceptionMessage The stream has not resolved
2016-12-13 22:25:52 +01:00
*/
public function testDrainBeforeResolution() {
2017-01-04 02:10:27 +01:00
$emitter = new Emitter;
2017-04-13 18:20:46 +02:00
$streamIterator = new StreamIterator($emitter->stream());
2017-04-13 18:20:46 +02:00
$streamIterator->drain();
2016-12-13 22:25:52 +01:00
}
2017-01-04 02:10:27 +01:00
public function testFailingStream() {
Loop::run(function () {
2016-12-13 22:25:52 +01:00
$exception = new \Exception;
2017-01-04 02:10:27 +01:00
$emitter = new Emitter;
2017-04-13 18:20:46 +02:00
$streamIterator = new StreamIterator($emitter->stream());
2017-01-04 02:10:27 +01:00
$emitter->fail($exception);
2016-12-13 22:25:52 +01:00
try {
2017-04-13 18:20:46 +02:00
while (yield $streamIterator->advance());
$this->fail("StreamIterator::advance() should throw stream failure reason");
2016-12-13 22:25:52 +01:00
} catch (\Exception $reason) {
$this->assertSame($exception, $reason);
}
2016-12-13 22:25:52 +01:00
try {
2017-04-13 18:20:46 +02:00
$streamIterator->getResult();
$this->fail("StreamIterator::getResult() should throw stream failure reason");
2016-12-13 22:25:52 +01:00
} catch (\Exception $reason) {
$this->assertSame($exception, $reason);
}
});
2016-12-13 22:25:52 +01:00
}
2016-12-13 22:25:52 +01:00
/**
* @expectedException \Error
* @expectedExceptionMessage Promise returned from advance() must resolve before calling this method
*/
public function testGetCurrentBeforeAdvanceResolves() {
2017-04-13 18:20:46 +02:00
$streamIterator = new StreamIterator((new Emitter)->stream());
$streamIterator->advance();
$streamIterator->getCurrent();
2016-12-13 22:25:52 +01:00
}
2016-12-13 22:25:52 +01:00
/**
* @expectedException \Error
2017-01-04 02:10:27 +01:00
* @expectedExceptionMessage The stream has resolved
2016-12-13 22:25:52 +01:00
*/
public function testGetCurrentAfterResolution() {
2017-01-04 02:10:27 +01:00
$emitter = new Emitter;
2017-04-13 18:20:46 +02:00
$streamIterator = new StreamIterator($emitter->stream());
2017-01-04 02:10:27 +01:00
$emitter->resolve();
2017-04-13 18:20:46 +02:00
$streamIterator->getCurrent();
2016-12-13 22:25:52 +01:00
}
2016-12-13 22:25:52 +01:00
/**
* @expectedException \Error
2017-01-04 02:10:27 +01:00
* @expectedExceptionMessage The stream has not resolved
2016-12-13 22:25:52 +01:00
*/
public function testGetResultBeforeResolution() {
Loop::run(Amp\wrap(function () {
2017-04-13 18:20:46 +02:00
$streamIterator = new StreamIterator((new Emitter)->stream());
$streamIterator->getResult();
2016-12-29 23:57:08 +01:00
}));
2016-12-13 22:25:52 +01:00
}
/**
* @expectedException \Error
* @expectedExceptionMessage The prior promise returned must resolve before invoking this method again
*/
public function testConsecutiveAdvanceCalls() {
$emitter = new Emitter;
2017-04-13 18:20:46 +02:00
$streamIterator = new StreamIterator($emitter->stream());
$streamIterator->advance();
$streamIterator->advance();
}
2017-04-13 18:20:46 +02:00
public function testStreamIteratorDestroyedAfterEmits() {
$emitter = new Emitter;
2017-04-13 18:20:46 +02:00
$streamIterator = new StreamIterator($emitter->stream());
$promise = $emitter->emit(1);
2017-04-13 18:20:46 +02:00
unset($streamIterator);
$invoked = false;
$promise->onResolve(function () use (&$invoked) {
$invoked = true;
});
$this->assertTrue($invoked);
}
2017-04-13 18:20:46 +02:00
public function testStreamIteratorDestroyedThenStreamEmits() {
$emitter = new Emitter;
2017-04-13 18:20:46 +02:00
$streamIterator = new StreamIterator($emitter->stream());
$emitter->emit(1);
2017-04-13 18:20:46 +02:00
unset($streamIterator);
$promise = $emitter->emit(2);
$invoked = false;
$promise->onResolve(function () use (&$invoked) {
$invoked = true;
});
$this->assertTrue($invoked);
}
2017-04-13 18:20:46 +02:00
public function testStreamFailsWhenStreamIteratorWaiting() {
$exception = new \Exception;
$emitter = new Emitter;
2017-04-13 18:20:46 +02:00
$streamIterator = new StreamIterator($emitter->stream());
2017-04-13 18:20:46 +02:00
$promise = $streamIterator->advance();
$promise->onResolve(function ($exception, $value) use (&$reason) {
$reason = $exception;
});
$emitter->fail($exception);
$this->assertSame($exception, $reason);
}
2016-12-13 22:25:52 +01:00
}