Skip to content

Commit

Permalink
Added tests
Browse files Browse the repository at this point in the history
  • Loading branch information
khelle committed Jun 24, 2017
1 parent c7ad47a commit 05b8c2b
Show file tree
Hide file tree
Showing 17 changed files with 1,483 additions and 0 deletions.
9 changes: 9 additions & 0 deletions test/Callback.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

namespace Dazzle\Stream\Test;

class Callback
{
public function __invoke()
{}
}
160 changes: 160 additions & 0 deletions test/TModule.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
<?php

namespace Dazzle\Stream\Test;

use Dazzle\Loop\Model\SelectLoop;
use Dazzle\Loop\Loop;
use Dazzle\Loop\LoopExtendedInterface;
use Dazzle\Loop\LoopInterface;
use Dazzle\Stream\Test\_Simulation\Event;
use Dazzle\Stream\Test\_Simulation\Simulation;
use Exception;

class TModule extends TUnit
{
/**
* @var string
*/
const MSG_EVENT_NAME_ASSERTION_FAILED = 'Expected event name mismatch on %s event.';

/**
* @var string
*/
const MSG_EVENT_DATA_ASSERTION_FAILED = 'Expected event data mismatch on %s event.';

/**
* @var string
*/
const MSG_EVENT_GET_ASSERTION_FAILED = "Expected event count mismatch after %s events.\nExpected event %s, got event %s.";

/**
* @var LoopExtendedInterface
*/
private $loop;

/**
* @var Simulation
*/
private $sim;

/**
*
*/
public function setUp()
{
$this->loop = null;
$this->sim = null;
}

/**
*
*/
public function tearDown()
{
unset($this->sim);
unset($this->loop);
}

/**
* @return LoopInterface|null
*/
public function getLoop()
{
return $this->loop;
}

/**
* Run test scenario as simulation.
*
* @param callable(Simulation) $scenario
* @return TModule
*/
public function simulate(callable $scenario)
{
try
{
$this->loop = new Loop(new SelectLoop);
$this->loop->erase(true);

$this->sim = new Simulation($this->loop);
$this->sim->setScenario($scenario);
$this->sim->begin();
}
catch (Exception $ex)
{
$this->fail($ex->getMessage());
}

return $this;
}

/**
* @param $events
* @param int $flags
* @return TModule
*/
public function expect($events, $flags = Simulation::EVENTS_COMPARE_IN_ORDER)
{
$expectedEvents = [];

foreach ($events as $event)
{
$data = isset($event[1]) ? $event[1] : [];
$expectedEvents[] = new Event($event[0], $data);
}

$this->assertEvents(
$this->sim->getExpectations(),
$expectedEvents,
$flags
);

return $this;
}

/**
* @param Event[] $actualEvents
* @param Event[] $expectedEvents
* @param int $flags
*/
public function assertEvents($actualEvents = [], $expectedEvents = [], $flags = Simulation::EVENTS_COMPARE_IN_ORDER)
{
$count = max(count($actualEvents), count($expectedEvents));

if ($flags === Simulation::EVENTS_COMPARE_RANDOMLY)
{
sort($actualEvents);
sort($expectedEvents);
}

for ($i=0; $i<$count; $i++)
{
if (!isset($actualEvents[$i]))
{
$this->fail(
sprintf(self::MSG_EVENT_GET_ASSERTION_FAILED, $i, $expectedEvents[$i]->name(), 'null')
);
}
else if (!isset($expectedEvents[$i]))
{
$this->fail(
sprintf(self::MSG_EVENT_GET_ASSERTION_FAILED, $i, 'null', $actualEvents[$i]->name())
);
}

$actualEvent = $actualEvents[$i];
$expectedEvent = $expectedEvents[$i];

$this->assertSame(
$expectedEvent->name(),
$actualEvent->name(),
sprintf(self::MSG_EVENT_NAME_ASSERTION_FAILED, $i)
);
$this->assertSame(
$expectedEvent->data(),
$actualEvent->data(),
sprintf(self::MSG_EVENT_DATA_ASSERTION_FAILED, $i)
);
}
}
}
106 changes: 106 additions & 0 deletions test/TModule/AsyncStreamTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
<?php

namespace Dazzle\Stream\Test\TModule\Stream;

use Dazzle\Stream\AsyncStreamReaderInterface;
use Dazzle\Stream\AsyncStreamWriterInterface;
use Dazzle\Stream\Test\_Simulation\SimulationInterface;
use Dazzle\Stream\Test\TModule;
use ReflectionClass;

/**
* @runTestsInSeparateProcesses
* @preserveGlobalState disabled
*/
class AsyncStreamTest extends TModule
{
public function tearDown()
{
$local = $this->basePath();
unlink("$local/temp");
}

/**
* @dataProvider asyncStreamPairProvider
* @param string $readerClass
* @param string $writerClass
*/
public function testAsyncStream_WritesAndReadsDataCorrectly($readerClass, $writerClass)
{
$this
->simulate(function(SimulationInterface $sim) use($readerClass, $writerClass) {
$loop = $sim->getLoop();
$local = $this->basePath();
$cnt = 0;

$reader = (new ReflectionClass($readerClass))->newInstance(
fopen("file://$local/temp", 'w+'),
$loop
);
$reader->on('data', function(AsyncStreamReaderInterface $conn, $data) use($sim) {
$sim->expect('data', $data);
$conn->close();
});
$reader->on('end', $this->expectCallableOnce());
$reader->on('drain', $this->expectCallableNever());
$reader->on('finish', $this->expectCallableNever());
$reader->on('error', $this->expectCallableNever());
$reader->on('close', function() use($sim, &$cnt) {
$sim->expect('close');
if (++$cnt === 2)
{
$sim->done();
}
});

$writer = (new ReflectionClass($writerClass))->newInstance(
fopen("file://$local/temp", 'r+'),
$loop
);
$writer->on('data', $this->expectCallableNever());
$writer->on('end', $this->expectCallableNever());
$writer->on('drain', function(AsyncStreamWriterInterface $writer) use($sim) {
$sim->expect('drain');
$writer->close();
});
$writer->on('finish', $this->expectCallableOnce());
$writer->on('error', $this->expectCallableNever());
$writer->on('close', function() use($sim, &$cnt) {
$sim->expect('close');
if (++$cnt === 2)
{
$sim->done();
}
});

$writer->write('message!');
$reader->read();
})
->expect([
[ 'drain' ],
[ 'close' ],
[ 'data', 'message!' ],
[ 'close' ]
])
;
}

/**
* Provider classes of AsyncStream.
*
* @return string[][]
*/
public function asyncStreamPairProvider()
{
return [
[
'Dazzle\Stream\AsyncStream',
'Dazzle\Stream\AsyncStream'
],
[
'Dazzle\Stream\AsyncStreamReader',
'Dazzle\Stream\AsyncStreamWriter'
]
];
}
}
87 changes: 87 additions & 0 deletions test/TModule/StreamTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
<?php

namespace Dazzle\Stream\Test\TModule\Stream;

use Dazzle\Stream\Stream;
use Dazzle\Stream\StreamReader;
use Dazzle\Stream\StreamWriter;
use Dazzle\Stream\Test\TModule;

/**
* @runTestsInSeparateProcesses
* @preserveGlobalState disabled
*/
class StreamTest extends TModule
{
public function tearDown()
{
$local = $this->basePath();
unlink("$local/temp");

parent::tearDown();
}

public function testStream_WriteAndReadDataScenario()
{
$local = $this->basePath();
$writer = new Stream(fopen("file://$local/temp", 'w+'));
$reader = new Stream(fopen("file://$local/temp", 'r+'));

$expectedData = "qwertyuiop\n";
$capturedData = null;
$readData = null;

$reader->on('data', function($origin, $data) use(&$capturedData) {
$capturedData = $data;
});
$reader->on('end', $this->expectCallableOnce());
$reader->on('error', $this->expectCallableNever());
$reader->on('close', $this->expectCallableOnce());

$writer->on('drain', $this->expectCallableOnce());
$writer->on('finish', $this->expectCallableOnce());
$writer->on('error', $this->expectCallableNever());
$writer->on('close', $this->expectCallableOnce());

$writer->write($expectedData);
$readData = $reader->read();

$writer->close();
$reader->close();

$this->assertEquals($expectedData, $readData);
$this->assertEquals($expectedData, $capturedData);
}

public function testStreamReader_StreamWriter_WriteAndReadDataScenario()
{
$local = $this->basePath();
$writer = new StreamWriter(fopen("file://$local/temp", 'w+'));
$reader = new StreamReader(fopen("file://$local/temp", 'r+'));

$expectedData = "qwertyuiop\n";
$capturedData = null;
$readData = null;

$reader->on('data', function($origin, $data) use(&$capturedData) {
$capturedData = $data;
});
$reader->on('drain', $this->expectCallableNever());
$reader->on('error', $this->expectCallableNever());
$reader->on('close', $this->expectCallableOnce());

$writer->on('data', $this->expectCallableNever());
$writer->on('drain', $this->expectCallableOnce());
$writer->on('error', $this->expectCallableNever());
$writer->on('close', $this->expectCallableOnce());

$writer->write($expectedData);
$readData = $reader->read();

$writer->close();
$reader->close();

$this->assertEquals($expectedData, $readData);
$this->assertEquals($expectedData, $capturedData);
}
}
Loading

0 comments on commit 05b8c2b

Please sign in to comment.