-
Thomas Flori authoredUnverified715349a6
TestCase.php 4.80 KiB
<?php
namespace Breyta\Test;
use Breyta\AbstractMigration;
use Breyta\AdapterInterface;
use Breyta\BasicAdapter;
use Breyta\Migration\CreateMigrationTable;
use Breyta\Migrations;
use Breyta\Model\Migration;
use Breyta\Model\Statement;
use Mockery\Adapter\Phpunit\MockeryTestCase;
use Mockery as m;
abstract class TestCase extends MockeryTestCase
{
/** @var m\Mock */
protected $pdo;
/** @var m\Mock|\PDOStatement */
protected $statement;
/** @var m\Mock|Migrations */
protected $migrations;
/** @var m\Mock */
protected $resolver;
/** @var callable */
protected $executor;
protected function setUp()
{
date_default_timezone_set('UTC');
$pdo = $this->pdo = m::mock(\PDO::class);
$pdo->shouldReceive('setAttribute')->andReturn(true)->byDefault();
$pdo->shouldReceive('beginTransaction')->byDefault();
$pdo->shouldReceive('commit')->byDefault();
$pdo->shouldReceive('rollback')->byDefault();
$pdo->shouldReceive('query')->andReturn(false)->byDefault();
$this->mockPreparedStatement('/^insert into migrations/i', true);
$this->mockPreparedStatement('/^update migrations set/i', true, 0);
$resolver = $this->resolver = m::spy(function ($class, ...$args) {
return new $class(...$args);
});
$this->migrations = m::mock(Migrations::class, [$this->pdo, __DIR__ . '/Example', $resolver])
->makePartial();
$resolver->shouldReceive('__invoke')->with(AdapterInterface::class, m::type(\Closure::class))
->andReturnUsing(function ($class, callable $executor) {
$this->executor = m::spy($executor);
return new BasicAdapter($this->executor);
})->byDefault();
}
protected function mockPreparedStatement(string $pattern, $byDefault = false, $defaultResult = 1)
{
$statement = m::mock(\PDOStatement::class);
$statement->shouldReceive('execute')->byDefault()->andReturn($defaultResult);
$expectation = $this->pdo->shouldReceive('prepare')->with(m::pattern($pattern));
if ($byDefault) {
$expectation->byDefault()->andReturn($statement);
} else {
$expectation->once()->andReturn($statement);
}
return $statement;
}
protected function mockMigration(string $file, string $class, string $status = 'new'): \stdClass
{
return $this->mockMigrations(['file' => $file, 'class' => $class, 'status' => $status])[0];
}
protected function mockMigrations(...$migrationProperties)
{
$migrations = [];
foreach ($migrationProperties as $migration) {
$migrations[] = (object)[
'model' => isset($migration['model']) ? $migration['model'] : Migration::createInstance([
'file' => $migration['file'],
'status' => $migration['status'],
'executed' => $migration['status'] === 'new' ? null : date('c', strtotime('-1 hour')),
]),
'mock' => $mock = m::mock($migration['class']),
];
$this->resolver->shouldReceive('__invoke')->with($migration['class'], m::type(AdapterInterface::class))
->andReturn($mock);
}
return $migrations;
}
protected function mockExecuteStatement(Statement $statement, $result = 1)
{
$this->mockExecuteStatementOn(
$this->mockMigration('@breyta/CreateMigrationTable.php', CreateMigrationTable::class),
'up',
$statement,
$result
);
}
protected function mockExecuteStatementOn(
\stdClass $migration,
string $direction,
Statement $statement,
$result = 1
) {
$migration->mock->shouldReceive($direction)->with()
->once()->andReturnUsing(function () use ($statement) {
call_user_func($this->executor, $statement);
})->ordered();
$expectation = $this->pdo->shouldReceive('exec')->with($statement->raw)
->once();
if ($result instanceof \Exception) {
$expectation->andThrow($result);
} else {
$expectation->andReturn($result);
}
$this->migrations->$direction($migration->model);
}
protected function setProtectedProperty($obj, $propertyName, $value)
{
$reflection = new \ReflectionClass($obj);
$property = $reflection->getProperty($propertyName);
$property->setAccessible(true);
$property->setValue($obj, $value);
}
protected function getProtectedProperty($obj, $propertyName)
{
$reflection = new \ReflectionClass($obj);
$property = $reflection->getProperty($propertyName);
$property->setAccessible(true);
return $property->getValue($obj);
}
}