destructr/tests/Drivers/AbstractDriverTest.php
2018-08-17 16:32:26 -06:00

218 lines
7.3 KiB
PHP

<?php
/* Destructr | https://gitlab.com/byjoby/destructr | MIT License */
declare(strict_types=1);
namespace Destructr\Drivers;
use PHPUnit\Framework\TestCase;
use PHPUnit\DbUnit\TestCaseTrait;
use Destructr\DSO;
use Destructr\Search;
/**
* This class tests a factory in isolation. In the name of simplicity it's a bit
* simplistic, because it doesn't get the help of the Factory.
*
* There is also a class called AbstractDriverIntegrationTest that tests drivers
* through a Factory. The results of that are harder to interpret, but more
* properly and thoroughly test the Drivers in a real environment.
*/
abstract class AbstractDriverTest extends TestCase
{
use TestCaseTrait;
/*
In actual practice, these would come from a Factory
*/
protected $virtualColumns = [
'dso.id' => [
'name'=>'dso_id',
'type'=>'VARCHAR(16)',
'index' => 'BTREE',
'unique' => true
],
'dso.type' => [
'name'=>'dso_type',
'type'=>'VARCHAR(30)',
'index'=>'BTREE'
],
'dso.deleted' => [
'name'=>'dso_deleted',
'type'=>'BIGINT',
'index'=>'BTREE'
]
];
public function testCreateTable()
{
$driver = $this->createDriver();
$res = $driver->createTable('testCreateTable', $this->virtualColumns);
$this->assertTrue($res);
$this->assertEquals(0, $this->getConnection()->getRowCount('testCreateTable'));
$this->assertFalse($driver->createTable('testCreateTable', $this->virtualColumns));
}
public function testInsert()
{
$driver = $this->createDriver();
$driver->createTable('testInsert', $this->virtualColumns);
//test inserting an object
$o = new DSO(['dso.id'=>'first-inserted']);
$this->assertTrue($driver->insert('testInsert', $o));
$this->assertEquals(1, $this->getConnection()->getRowCount('testInsert'));
//test inserting a second object
$o = new DSO(['dso.id'=>'second-inserted']);
$this->assertTrue($driver->insert('testInsert', $o));
$this->assertEquals(2, $this->getConnection()->getRowCount('testInsert'));
//test inserting a second object with an existing id, it shouldn't work
$o = new DSO(['dso.id'=>'first-inserted']);
$this->assertFalse($driver->insert('testInsert', $o));
$this->assertEquals(2, $this->getConnection()->getRowCount('testInsert'));
}
public function testSelect()
{
$driver = $this->createDriver();
$driver->createTable('testSelect', $this->virtualColumns);
//set up dummy data
$this->setup_testSelect();
//empty search
$search = new Search();
$results = $driver->select('testSelect', $search, []);
$this->assertSame(4, count($results));
//sorting by json value sort
$search = new Search();
$search->order('${sort} asc');
$results = $driver->select('testSelect', $search, []);
$this->assertSame(4, count($results));
$results = array_map(
function ($a) {
return json_decode($a['json_data'], true);
},
$results
);
$this->assertSame('item-a-1', $results[0]['dso']['id']);
$this->assertSame('item-b-1', $results[1]['dso']['id']);
$this->assertSame('item-a-2', $results[2]['dso']['id']);
$this->assertSame('item-b-2', $results[3]['dso']['id']);
// search with no results, searching by virtual column
$search = new Search();
$search->where('`dso_type` = :param');
$results = $driver->select('testSelect', $search, [':param'=>'type-none']);
$this->assertSame(0, count($results));
// search with no results, searching by json field
$search = new Search();
$search->where('${foo} = :param');
$results = $driver->select('testSelect', $search, [':param'=>'nonexistent foo value']);
$this->assertSame(0, count($results));
}
public function testDelete()
{
$driver = $this->createDriver();
$driver->createTable('testDelete', $this->virtualColumns);
//set up dummy data
$this->setup_testDelete();
//try deleting an item
$dso = new DSO(['dso.id'=>'item-a-1']);
$driver->delete('testDelete', $dso);
$this->assertEquals(3, $this->getConnection()->getRowCount('testDelete'));
//try deleting an item at the other end of the table
$dso = new DSO(['dso.id'=>'item-b-2']);
$driver->delete('testDelete', $dso);
$this->assertEquals(2, $this->getConnection()->getRowCount('testDelete'));
}
protected function setup_testDelete()
{
$driver = $this->createDriver();
$driver->insert('testDelete', new DSO([
'dso'=>['id'=>'item-a-1','type'=>'type-a'],
'foo'=>'bar',
'sort'=>'a'
]));
$driver->insert('testDelete', new DSO([
'dso'=>['id'=>'item-a-2','type'=>'type-a'],
'foo'=>'baz',
'sort'=>'c'
]));
$driver->insert('testDelete', new DSO([
'dso'=>['id'=>'item-b-1','type'=>'type-b'],
'foo'=>'buz',
'sort'=>'b'
]));
$driver->insert('testDelete', new DSO([
'dso'=>['id'=>'item-b-2','type'=>'type-b','deleted'=>100],
'foo'=>'quz',
'sort'=>'d'
]));
}
protected function setup_testSelect()
{
$driver = $this->createDriver();
$driver->insert('testSelect', new DSO([
'dso'=>['id'=>'item-a-1','type'=>'type-a'],
'foo'=>'bar',
'sort'=>'a'
]));
$driver->insert('testSelect', new DSO([
'dso'=>['id'=>'item-a-2','type'=>'type-a'],
'foo'=>'baz',
'sort'=>'c'
]));
$driver->insert('testSelect', new DSO([
'dso'=>['id'=>'item-b-1','type'=>'type-b'],
'foo'=>'buz',
'sort'=>'b'
]));
$driver->insert('testSelect', new DSO([
'dso'=>['id'=>'item-b-2','type'=>'type-b','deleted'=>100],
'foo'=>'quz',
'sort'=>'d'
]));
}
/**
* Creates a Driver from class constants, so extending classes can test
* different databases.
*/
public function createDriver()
{
$class = static::DRIVER_CLASS;
return new $class(
static::DRIVER_DSN,
static::DRIVER_USERNAME,
static::DRIVER_PASSWORD,
static::DRIVER_OPTIONS
);
}
public static function setUpBeforeClass()
{
$pdo = static::createPDO();
$pdo->exec('DROP TABLE testCreateTable');
$pdo->exec('DROP TABLE testInsert');
$pdo->exec('DROP TABLE testSelect');
$pdo->exec('DROP TABLE testDelete');
}
protected static function createPDO()
{
return new \PDO(
static::DRIVER_DSN,
static::DRIVER_USERNAME,
static::DRIVER_PASSWORD,
static::DRIVER_OPTIONS
);
}
public function getConnection()
{
return $this->createDefaultDBConnection($this->createPDO(), 'phpunit');
}
public function getDataSet()
{
return new \PHPUnit\DbUnit\DataSet\DefaultDataSet();
}
}