destructr/tests/Drivers/AbstractSQLDriverTest.php

197 lines
6.5 KiB
PHP
Raw Normal View History

2018-08-17 17:32:10 +00:00
<?php
/* Destructr | https://github.com/jobyone/destructr | MIT License */
declare(strict_types=1);
2018-08-17 22:32:26 +00:00
namespace Destructr\Drivers;
2018-08-17 17:32:10 +00:00
2018-08-17 22:32:26 +00:00
use Destructr\DSO;
2020-08-27 17:42:11 +00:00
use Destructr\Factory;
2018-08-17 22:32:26 +00:00
use Destructr\Search;
use PHPUnit\DbUnit\TestCaseTrait;
use PHPUnit\Framework\TestCase;
2018-08-17 17:32:10 +00:00
/**
* 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 AbstractSQLDriverIntegrationTest that tests drivers
2018-08-17 17:32:10 +00:00
* 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 AbstractSQLDriverTest extends TestCase
2018-08-17 17:32:10 +00:00
{
use TestCaseTrait;
abstract protected static function DRIVER_DSN();
protected static function DRIVER_USERNAME()
{
return null;
}
protected static function DRIVER_PASSWORD()
{
return null;
}
protected static function DRIVER_OPTIONS()
{
return null;
}
2018-08-17 17:32:10 +00:00
/*
In actual practice, these would come from a Factory
*/
protected $schema = [
2018-08-17 17:32:10 +00:00
'dso.id' => [
'name' => 'dso_id',
'type' => 'VARCHAR(16)',
2018-08-17 17:32:10 +00:00
'index' => 'BTREE',
'unique' => true,
2018-08-17 17:32:10 +00:00
],
'dso.type' => [
'name' => 'dso_type',
'type' => 'VARCHAR(30)',
'index' => 'BTREE',
2018-08-17 17:32:10 +00:00
],
'dso.deleted' => [
'name' => 'dso_deleted',
'type' => 'BIGINT',
'index' => 'BTREE',
],
2018-08-17 17:32:10 +00:00
];
public function testPrepareEnvironment()
2018-08-17 17:32:10 +00:00
{
$driver = $this->createDriver();
$this->assertFalse($driver->tableExists('testPrepareEnvironment'));
$this->assertFalse($driver->tableExists(AbstractDriver::SCHEMA_TABLE));
$driver->prepareEnvironment('testPrepareEnvironment', $this->schema);
$this->assertTrue($driver->tableExists(AbstractDriver::SCHEMA_TABLE));
$this->assertTrue($driver->tableExists('testPrepareEnvironment'));
$this->assertEquals(1, $this->getConnection()->getRowCount(AbstractDriver::SCHEMA_TABLE));
$this->assertEquals(0, $this->getConnection()->getRowCount('testPrepareEnvironment'));
2018-08-17 17:32:10 +00:00
}
public function testInsert()
{
$driver = $this->createDriver();
$driver->prepareEnvironment('testInsert', $this->schema);
2018-08-17 17:32:10 +00:00
//test inserting an object
$o = new DSO(['dso.id' => 'first-inserted'], new Factory($driver, 'no_table'));
2018-08-17 17:32:10 +00:00
$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'], new Factory($driver, 'no_table'));
2018-08-17 17:32:10 +00:00
$this->assertTrue($driver->insert('testInsert', $o));
$this->assertEquals(2, $this->getConnection()->getRowCount('testInsert'));
}
public function testSelect()
{
$driver = $this->createDriver();
$driver->prepareEnvironment('testSelect', $this->schema);
2018-08-17 17:32:10 +00:00
//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']);
2018-08-17 17:32:10 +00:00
$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']);
2018-08-17 17:32:10 +00:00
$this->assertSame(0, count($results));
}
protected function setup_testSelect()
{
$driver = $this->createDriver();
$driver->insert('testSelect', new DSO([
'dso' => ['id' => 'item-a-1', 'type' => 'type-a'],
'foo' => 'bar',
'sort' => 'a',
], new Factory($driver, 'no_table')));
2018-08-17 17:32:10 +00:00
$driver->insert('testSelect', new DSO([
'dso' => ['id' => 'item-a-2', 'type' => 'type-a'],
'foo' => 'baz',
'sort' => 'c',
], new Factory($driver, 'no_table')));
2018-08-17 17:32:10 +00:00
$driver->insert('testSelect', new DSO([
'dso' => ['id' => 'item-b-1', 'type' => 'type-b'],
'foo' => 'buz',
'sort' => 'b',
], new Factory($driver, 'no_table')));
2018-08-17 17:32:10 +00:00
$driver->insert('testSelect', new DSO([
'dso' => ['id' => 'item-b-2', 'type' => 'type-b', 'deleted' => 100],
'foo' => 'quz',
'sort' => 'd',
], new Factory($driver, 'no_table')));
2018-08-17 17:32:10 +00:00
}
/**
* 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()
2018-08-17 17:32:10 +00:00
);
}
public static function setUpBeforeClass()
{
$pdo = static::createPDO();
$pdo->exec('DROP TABLE testPrepareEnvironment');
2018-08-17 17:32:10 +00:00
$pdo->exec('DROP TABLE testInsert');
$pdo->exec('DROP TABLE testSelect');
$pdo->exec('DROP TABLE destructr_schema');
2018-08-17 17:32:10 +00:00
}
protected static function createPDO()
{
return new \PDO(
static::DRIVER_DSN(),
static::DRIVER_USERNAME(),
static::DRIVER_PASSWORD(),
static::DRIVER_OPTIONS()
2018-08-17 17:32:10 +00:00
);
}
public function getConnection()
{
return $this->createDefaultDBConnection($this->createPDO(), 'phpunit');
}
public function getDataSet()
{
return new \PHPUnit\DbUnit\DataSet\DefaultDataSet();
}
}