Browse Source

Generic database interface creation in tests

microsub
J. King 6 years ago
parent
commit
4e444fd86c
  1. 64
      tests/cases/Db/TestResult.php
  2. 73
      tests/cases/Db/TestStatement.php
  3. 55
      tests/lib/AbstractTest.php

64
tests/cases/Db/TestResult.php

@ -16,37 +16,35 @@ use JKingWeb\Arsse\Db\SQLite3\PDODriver;
* @covers \JKingWeb\Arsse\Db\SQLite3\Result<extended>
*/
class TestResult extends \JKingWeb\Arsse\Test\AbstractTest {
public function provideDrivers() {
public function provideResults() {
$this->setConf();
$drvSqlite3 = (function() {
if (\JKingWeb\Arsse\Db\SQLite3\Driver::requirementsMet()) {
$d = new \SQLite3(Arsse::$conf->dbSQLite3File);
$d->enableExceptions(true);
return $d;
}
})();
$drvPdo = (function() {
if (\JKingWeb\Arsse\Db\SQLite3\PDODriver::requirementsMet()) {
return new \PDO("sqlite:".Arsse::$conf->dbSQLite3File, "", "", [\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION]);
}
})();
return [
'SQLite 3' => [isset($drvSqlite3), false, \JKingWeb\Arsse\Db\SQLite3\Result::class, function(string $query) use($drvSqlite3) {
$set = $drvSqlite3->query($query);
$rows = $drvSqlite3->changes();
$id = $drvSqlite3->lastInsertRowID();
$interfaces = $this->provideDbInterfaces();
$constructors = [
'SQLite 3' => function(string $query) use($interfaces) {
$drv = $interfaces['SQLite 3']['interface'];
$set = $drv->query($query);
$rows = $drv->changes();
$id = $drv->lastInsertRowID();
return [$set, [$rows, $id]];
}],
'PDO' => [isset($drvPdo), true, \JKingWeb\Arsse\Db\PDOResult::class, function(string $query) use($drvPdo) {
$set = $drvPdo->query($query);
$rows = $set->rowCount();
$id = $drvPdo->lastInsertID();
return [$set, [$rows, $id]];
}],
},
];
foreach ($constructors as $drv => $func) {
yield $drv => [isset($interfaces[$drv]['interface']), $interfaces[$drv]['stringOutput'], $interfaces[$drv]['result'], $func];
}
// there is only one PDO result implementation, so we test the first implementation we find
$pdo = array_reduce($interfaces, function ($carry, $item) {
return $carry ?? ($item['interface'] instanceof \PDO ? $item : null);
}) ?? $interfaces['PDO SQLite 3'];
yield "PDO" => [isset($pdo['interface']), $pdo['stringOutput'], $pdo['result'], function(string $query) use($pdo) {
$drv = $pdo['interface'];
$set = $drv->query($query);
$rows = $set->rowCount();
$id = $drv->lastInsertID();
return [$set, [$rows, $id]];
}];
}
/** @dataProvider provideDrivers */
/** @dataProvider provideResults */
public function testConstructResult(bool $driverTestable, bool $stringCoersion, string $class, \Closure $func) {
if (!$driverTestable) {
$this->markTestSkipped();
@ -54,7 +52,7 @@ class TestResult extends \JKingWeb\Arsse\Test\AbstractTest {
$this->assertInstanceOf(Result::class, new $class(...$func("SELECT 1")));
}
/** @dataProvider provideDrivers */
/** @dataProvider provideResults */
public function testGetChangeCountAndLastInsertId(bool $driverTestable, bool $stringCoersion, string $class, \Closure $func) {
if (!$driverTestable) {
$this->markTestSkipped();
@ -68,7 +66,7 @@ class TestResult extends \JKingWeb\Arsse\Test\AbstractTest {
$this->assertSame((int) $id, $r->lastId());
}
/** @dataProvider provideDrivers */
/** @dataProvider provideResults */
public function testIterateOverResults(bool $driverTestable, bool $stringCoersion, string $class, \Closure $func) {
if (!$driverTestable) {
$this->markTestSkipped();
@ -81,7 +79,7 @@ class TestResult extends \JKingWeb\Arsse\Test\AbstractTest {
$this->assertSame($exp, $rows);
}
/** @dataProvider provideDrivers */
/** @dataProvider provideResults */
public function testIterateOverResultsTwice(bool $driverTestable, bool $stringCoersion, string $class, \Closure $func) {
if (!$driverTestable) {
$this->markTestSkipped();
@ -99,7 +97,7 @@ class TestResult extends \JKingWeb\Arsse\Test\AbstractTest {
}
}
/** @dataProvider provideDrivers */
/** @dataProvider provideResults */
public function testGetSingleValues(bool $driverTestable, bool $stringCoersion, string $class, \Closure $func) {
if (!$driverTestable) {
$this->markTestSkipped();
@ -113,7 +111,7 @@ class TestResult extends \JKingWeb\Arsse\Test\AbstractTest {
$this->assertSame(null, $test->getValue());
}
/** @dataProvider provideDrivers */
/** @dataProvider provideResults */
public function testGetFirstValuesOnly(bool $driverTestable, bool $stringCoersion, string $class, \Closure $func) {
if (!$driverTestable) {
$this->markTestSkipped();
@ -127,7 +125,7 @@ class TestResult extends \JKingWeb\Arsse\Test\AbstractTest {
$this->assertSame(null, $test->getValue());
}
/** @dataProvider provideDrivers */
/** @dataProvider provideResults */
public function testGetRows(bool $driverTestable, bool $stringCoersion, string $class, \Closure $func) {
if (!$driverTestable) {
$this->markTestSkipped();
@ -142,7 +140,7 @@ class TestResult extends \JKingWeb\Arsse\Test\AbstractTest {
$this->assertSame(null, $test->getRow());
}
/** @dataProvider provideDrivers */
/** @dataProvider provideResults */
public function testGetAllRows(bool $driverTestable, bool $stringCoersion, string $class, \Closure $func) {
if (!$driverTestable) {
$this->markTestSkipped();

73
tests/cases/Db/TestStatement.php

@ -16,47 +16,28 @@ use JKingWeb\Arsse\Db\PDOStatement;
* @covers \JKingWeb\Arsse\Db\PDOStatement<extended>
* @covers \JKingWeb\Arsse\Db\PDOError */
class TestStatement extends \JKingWeb\Arsse\Test\AbstractTest {
public function provideDrivers() {
$this->setConf();
$drvSqlite3 = (function() {
if (\JKingWeb\Arsse\Db\SQLite3\Driver::requirementsMet()) {
$d = new \SQLite3(Arsse::$conf->dbSQLite3File);
$d->enableExceptions(true);
return $d;
}
})();
$drvPgsql = (function() {
if (\JKingWeb\Arsse\Db\PostgreSQL\PDODriver::requirementsMet()) {
$connString = \JKingWeb\Arsse\Db\PostgreSQL\Driver::makeConnectionString(true, Arsse::$conf->dbPostgreSQLUser, Arsse::$conf->dbPostgreSQLPass, Arsse::$conf->dbPostgreSQLDb, Arsse::$conf->dbPostgreSQLHost, Arsse::$conf->dbPostgreSQLPort, "");
$c = new \PDO("pgsql:".$connString, Arsse::$conf->dbPostgreSQLUser, Arsse::$conf->dbPostgreSQLPass, [\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION]);
foreach (\JKingWeb\Arsse\Db\PostgreSQL\PDODriver::makeSetupQueries(Arsse::$conf->dbPostgreSQLSchema) as $q) {
$c->exec($q);
}
return $c;
}
})();
$drvPdo = (function() {
if (\JKingWeb\Arsse\Db\SQLite3\PDODriver::requirementsMet()) {
return new \PDO("sqlite:".Arsse::$conf->dbSQLite3File, "", "", [\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION]);
}
})();
return [
'SQLite 3' => [isset($drvSqlite3), false, \JKingWeb\Arsse\Db\SQLite3\Statement::class, function(string $query, array $types = []) use($drvSqlite3) {
$s = $drvSqlite3->prepare($query);
return [$drvSqlite3, $s, $types];
}],
'PDO SQLite 3' => [isset($drvPdo), true, \JKingWeb\Arsse\Db\PDOStatement::class, function(string $query, array $types = []) use($drvPdo) {
$s = $drvPdo->prepare($query);
return [$drvPdo, $s, $types];
}],
'PDO PostgreSQL' => [isset($drvPgsql), true, \JKingWeb\Arsse\Db\PDOStatement::class, function(string $query, array $types = []) use($drvPgsql) {
$s = $drvPgsql->prepare($query);
return [$drvPgsql, $s, $types];
}],
public function provideStatements() {
$interfaces = $this->provideDbInterfaces();
$constructors = [
'SQLite 3' => function(string $query, array $types = []) use($interfaces) {
$s = $interfaces['SQLite 3']['interface']->prepare($query);
return [$interfaces['SQLite 3']['interface'], $s, $types];
},
'PDO SQLite 3' => function(string $query, array $types = []) use($interfaces) {
$s = $interfaces['PDO SQLite 3']['interface']->prepare($query);
return [$interfaces['PDO SQLite 3']['interface'], $s, $types];
},
'PDO PostgreSQL' => function(string $query, array $types = []) use($interfaces) {
$s = $interfaces['PDO PostgreSQL']['interface']->prepare($query);
return [$interfaces['PDO PostgreSQL']['interface'], $s, $types];
},
];
foreach ($constructors as $drv => $func) {
yield $drv => [isset($interfaces[$drv]['interface']), $interfaces[$drv]['stringOutput'], $interfaces[$drv]['statement'], $func];
}
}
/** @dataProvider provideDrivers */
/** @dataProvider provideStatements */
public function testConstructStatement(bool $driverTestable, bool $stringCoersion, string $class, \Closure $func) {
if (!$driverTestable) {
$this->markTestSkipped();
@ -98,7 +79,7 @@ class TestStatement extends \JKingWeb\Arsse\Test\AbstractTest {
$this->assertTrue((bool) $act);
}
/** @dataProvider provideDrivers */
/** @dataProvider provideStatements */
public function testBindMissingValue(bool $driverTestable, bool $stringCoersion, string $class, \Closure $func) {
if (!$driverTestable) {
$this->markTestSkipped();
@ -108,7 +89,7 @@ class TestStatement extends \JKingWeb\Arsse\Test\AbstractTest {
$this->assertSame(null, $val);
}
/** @dataProvider provideDrivers */
/** @dataProvider provideStatements */
public function testBindMultipleValues(bool $driverTestable, bool $stringCoersion, string $class, \Closure $func) {
if (!$driverTestable) {
$this->markTestSkipped();
@ -123,7 +104,7 @@ class TestStatement extends \JKingWeb\Arsse\Test\AbstractTest {
$this->assertSame($exp, $val);
}
/** @dataProvider provideDrivers */
/** @dataProvider provideStatements */
public function testBindRecursively(bool $driverTestable, bool $stringCoersion, string $class, \Closure $func) {
if (!$driverTestable) {
$this->markTestSkipped();
@ -140,7 +121,7 @@ class TestStatement extends \JKingWeb\Arsse\Test\AbstractTest {
$this->assertSame($exp, $val);
}
/** @dataProvider provideDrivers */
/** @dataProvider provideStatements */
public function testBindWithoutType(bool $driverTestable, bool $stringCoersion, string $class, \Closure $func) {
if (!$driverTestable) {
$this->markTestSkipped();
@ -150,7 +131,7 @@ class TestStatement extends \JKingWeb\Arsse\Test\AbstractTest {
$s->runArray([1]);
}
/** @dataProvider provideDrivers */
/** @dataProvider provideStatements */
public function testViolateConstraint(bool $driverTestable, bool $stringCoersion, string $class, \Closure $func) {
if (!$driverTestable) {
$this->markTestSkipped();
@ -161,7 +142,7 @@ class TestStatement extends \JKingWeb\Arsse\Test\AbstractTest {
$s->runArray([null]);
}
/** @dataProvider provideDrivers */
/** @dataProvider provideStatements */
public function testMismatchTypes(bool $driverTestable, bool $stringCoersion, string $class, \Closure $func) {
if (!$driverTestable) {
$this->markTestSkipped();
@ -309,7 +290,7 @@ class TestStatement extends \JKingWeb\Arsse\Test\AbstractTest {
'DateTimeImmutable as strict boolean' => [$dateImmutable, "strict boolean", "1"],
];
$decorators = $this->provideSyntaxDecorators();
foreach ($this->provideDrivers() as $drvName => list($drv, $stringCoersion, $class, $func)) {
foreach ($this->provideStatements() as $drvName => list($drv, $stringCoersion, $class, $func)) {
$conv = $decorators[$drvName] ?? $conv = $decorators[''];
foreach ($tests as $index => list($value, $type, $exp)) {
$t = preg_replace("<^strict >", "", $type);
@ -364,7 +345,7 @@ class TestStatement extends \JKingWeb\Arsse\Test\AbstractTest {
'DateTimeImmutable as strict binary' => [$dateImmutable, "strict binary", "x'".bin2hex($dateUTC->format("Y-m-d H:i:s"))."'"],
];
$decorators = $this->provideSyntaxDecorators();
foreach ($this->provideDrivers() as $drvName => list($drv, $stringCoersion, $class, $func)) {
foreach ($this->provideStatements() as $drvName => list($drv, $stringCoersion, $class, $func)) {
$conv = $decorators[$drvName] ?? $conv = $decorators[''];
if ($drvName=="PDO PostgreSQL") {
// skip PostgreSQL for these tests

55
tests/lib/AbstractTest.php

@ -125,4 +125,59 @@ abstract class AbstractTest extends \PHPUnit\Framework\TestCase {
}
return $value;
}
public function provideDbInterfaces(array $conf = []): array {
$this->setConf($conf);
return [
'SQLite 3' => [
'interface' => (function() {
if (\JKingWeb\Arsse\Db\SQLite3\Driver::requirementsMet()) {
try {
$d = new \SQLite3(Arsse::$conf->dbSQLite3File);
} catch (\Exception $e) {
return;
}
$d->enableExceptions(true);
return $d;
}
})(),
'statement' => \JKingWeb\Arsse\Db\SQLite3\Statement::class,
'result' => \JKingWeb\Arsse\Db\SQLite3\Result::class,
'stringOutput' => false,
],
'PDO SQLite 3' => [
'interface' => (function() {
if (\JKingWeb\Arsse\Db\SQLite3\PDODriver::requirementsMet()) {
try {
return new \PDO("sqlite:".Arsse::$conf->dbSQLite3File, "", "", [\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION]);
} catch (\PDOException $e) {
return;
}
}
})(),
'statement' => \JKingWeb\Arsse\Db\PDOStatement::class,
'result' => \JKingWeb\Arsse\Db\PDOResult::class,
'stringOutput' => true,
],
'PDO PostgreSQL' => [
'interface' => (function() {
if (\JKingWeb\Arsse\Db\PostgreSQL\PDODriver::requirementsMet()) {
$connString = \JKingWeb\Arsse\Db\PostgreSQL\Driver::makeConnectionString(true, Arsse::$conf->dbPostgreSQLUser, Arsse::$conf->dbPostgreSQLPass, Arsse::$conf->dbPostgreSQLDb, Arsse::$conf->dbPostgreSQLHost, Arsse::$conf->dbPostgreSQLPort, "");
try {
$c = new \PDO("pgsql:".$connString, Arsse::$conf->dbPostgreSQLUser, Arsse::$conf->dbPostgreSQLPass, [\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION]);
} catch (\PDOException $e) {
return;
}
foreach (\JKingWeb\Arsse\Db\PostgreSQL\PDODriver::makeSetupQueries(Arsse::$conf->dbPostgreSQLSchema) as $q) {
$c->exec($q);
}
return $c;
}
})(),
'statement' => \JKingWeb\Arsse\Db\PDOStatement::class,
'result' => \JKingWeb\Arsse\Db\PDOResult::class,
'stringOutput' => true,
],
];
}
}

Loading…
Cancel
Save