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 55af22c commit 9ca0c7c
Show file tree
Hide file tree
Showing 8 changed files with 752 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\Zmq\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\Zmq\Test;

use Dazzle\Loop\Model\SelectLoop;
use Dazzle\Loop\Loop;
use Dazzle\Loop\LoopExtendedInterface;
use Dazzle\Loop\LoopInterface;
use Dazzle\Zmq\Test\_Simulation\Event;
use Dazzle\Zmq\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)
);
}
}
}
211 changes: 211 additions & 0 deletions test/TUnit.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
<?php

namespace Dazzle\Zmq\Test;

use Dazzle\Loop\LoopInterface;
use ReflectionClass;

class TUnit extends \PHPUnit_Framework_TestCase
{
/**
* Return project root.
*
* @return string
*/
public function basePath()
{
return realpath(__DIR__ . '/..');
}

/**
* @return TUnit
*/
public function getTest()
{
return $this;
}

/**
* @return \PHPUnit_Framework_MockObject_Matcher_InvokedCount
*/
public function twice()
{
return $this->exactly(2);
}

/**
* Creates a callback that must be called $amount times or the test will fail.
*
* @param $amount
* @return callable|\PHPUnit_Framework_MockObject_MockObject
*/
public function expectCallableExactly($amount)
{
$mock = $this->createCallableMock();
$mock
->expects($this->exactly($amount))
->method('__invoke');

return $mock;
}

/**
* Creates a callback that must be called once.
*
* @return callable|\PHPUnit_Framework_MockObject_MockObject
*/
public function expectCallableOnce()
{
$mock = $this->createCallableMock();
$mock
->expects($this->once())
->method('__invoke');

return $mock;
}

/**
* Creates a callback that must be called twice.
*
* @return callable|\PHPUnit_Framework_MockObject_MockObject
*/
public function expectCallableTwice()
{
$mock = $this->createCallableMock();
$mock
->expects($this->exactly(2))
->method('__invoke');

return $mock;
}

/**
* Creates a callable that must not be called once.
*
* @return callable|\PHPUnit_Framework_MockObject_MockObject
*/
public function expectCallableNever()
{
$mock = $this->createCallableMock();
$mock
->expects($this->never())
->method('__invoke');

return $mock;
}

/**
* Creates a callable mock.
*
* @return callable|\PHPUnit_Framework_MockObject_MockObject
*/
public function createCallableMock()
{
return $this->getMock(Callback::class);
}

/**
* @return LoopInterface|\PHPUnit_Framework_MockObject_MockObject
*/
public function createLoopMock()
{
return $this->getMock('Dazzle\Loop\LoopInterface');
}

/**
* @return LoopInterface|\PHPUnit_Framework_MockObject_MockObject
*/
public function createWritableLoopMock()
{
$loop = $this->createLoopMock();
$loop
->expects($this->once())
->method('addWriteStream')
->will($this->returnCallback(function($stream, $listener) {
call_user_func($listener, $stream);
}));

return $loop;
}

/**
* @return LoopInterface|\PHPUnit_Framework_MockObject_MockObject
*/
public function createReadableLoopMock()
{
$loop = $this->createLoopMock();
$loop
->expects($this->once())
->method('addReadStream')
->will($this->returnCallback(function($stream, $listener) {
call_user_func($listener, $stream);
}));

return $loop;
}

/**
* Check if protected property exists.
*
* @param object $object
* @param string $property
* @return bool
*/
public function existsProtectedProperty($object, $property)
{
$reflection = new ReflectionClass($object);
return $reflection->hasProperty($property);
}

/**
* Get protected property from given object via reflection.
*
* @param object $object
* @param string $property
* @return mixed
*/
public function getProtectedProperty($object, $property)
{
$reflection = new ReflectionClass($object);
$reflection_property = $reflection->getProperty($property);
$reflection_property->setAccessible(true);

return $reflection_property->getValue($object);
}

/**
* Set protected property on a given object via reflection.
*
* @param object $object
* @param string $property
* @param mixed $value
* @return object
*/
public function setProtectedProperty($object, $property, $value)
{
$reflection = new ReflectionClass($object);
$reflection_property = $reflection->getProperty($property);
$reflection_property->setAccessible(true);
$reflection_property->setValue($object, $value);

return $object;
}

/**
* Call protected method on a given object via reflection.
*
* @param object|string $objectOrClass
* @param string $method
* @param mixed[] $args
* @return mixed
*/
public function callProtectedMethod($objectOrClass, $method, $args = [])
{
$reflection = new ReflectionClass($objectOrClass);
$reflectionMethod = $reflection->getMethod($method);
$reflectionMethod->setAccessible(true);
$reflectionTarget = is_object($objectOrClass) ? $objectOrClass : null;

return $reflectionMethod->invokeArgs($reflectionTarget, $args);
}
}
Loading

0 comments on commit 9ca0c7c

Please sign in to comment.