1
1
Fork 0
mirror of https://code.mensbeam.com/MensBeam/Arsse.git synced 2024-12-22 21:22:40 +00:00

Align result tests with driver tests

This commit is contained in:
J. King 2018-11-22 19:55:54 -05:00
parent aa1b65b5d4
commit f22e53fdc9
25 changed files with 358 additions and 379 deletions

View file

@ -8,7 +8,7 @@ namespace JKingWeb\Arsse\TestCase\Db;
use JKingWeb\Arsse\Db\Statement;
use JKingWeb\Arsse\Db\Result;
use JKingWeb\Arsse\Test\DatabaseInformation;
abstract class BaseDriver extends \JKingWeb\Arsse\Test\AbstractTest {
protected $drv;
@ -22,12 +22,13 @@ abstract class BaseDriver extends \JKingWeb\Arsse\Test\AbstractTest {
];
public function setUp() {
$this->setConf($this->conf);
$this->interface = $this->getDbInterface($this->implementation);
self::setConf($this->conf);
$info = new DatabaseInformation($this->implementation);
$this->interface = ($info->interfaceConstructor)();
if (!$this->interface) {
$this->markTestSkipped("$this->implementation database driver not available");
}
$this->drv = $this->getDbDriver($this->implementation);
$this->drv = new $info->driverClass;
$this->exec("DROP TABLE IF EXISTS arsse_test");
$this->exec("DROP TABLE IF EXISTS arsse_meta");
$this->exec("CREATE TABLE arsse_meta(key varchar(255) primary key not null, value text)");

View file

@ -0,0 +1,112 @@
<?php
/** @license MIT
* Copyright 2017 J. King, Dustin Wilson et al.
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse\TestCase\Db;
use JKingWeb\Arsse\Db\Result;
use JKingWeb\Arsse\Test\DatabaseInformation;
abstract class BaseResult extends \JKingWeb\Arsse\Test\AbstractTest {
protected $resultClass;
protected $stringOutput;
protected $interface;
abstract protected function exec(string $q);
abstract protected function makeResult(string $q): array;
public function setUp() {
self::setConf();
$info = new DatabaseInformation($this->implementation);
$this->interface = ($info->interfaceConstructor)();
if (!$this->interface) {
$this->markTestSkipped("$this->implementation database driver not available");
}
$this->resultClass = $info->resultClass;
$this->stringOutput = $info->stringOutput;
$this->exec("DROP TABLE IF EXISTS arsse_meta");
}
public function tearDown() {
$this->exec("DROP TABLE IF EXISTS arsse_meta");
}
public function testConstructResult() {
$this->assertInstanceOf(Result::class, new $this->resultClass(...$this->makeResult("SELECT 1")));
}
public function testGetChangeCountAndLastInsertId() {
$this->makeResult("CREATE TABLE arsse_meta(key varchar(255) primary key not null, value text)");
$out = $this->makeResult("INSERT INTO arsse_meta(key,value) values('test', 1)");
$rows = $out[1][0];
$id = $out[1][1];
$r = new $this->resultClass(...$out);
$this->assertSame((int) $rows, $r->changes());
$this->assertSame((int) $id, $r->lastId());
}
public function testIterateOverResults() {
$exp = [0 => 1, 1 => 2, 2 => 3];
$exp = $this->stringOutput ? $this->stringify($exp) : $exp;
foreach (new $this->resultClass(...$this->makeResult("SELECT 1 as col union select 2 as col union select 3 as col")) as $index => $row) {
$rows[$index] = $row['col'];
}
$this->assertSame($exp, $rows);
}
public function testIterateOverResultsTwice() {
$exp = [0 => 1, 1 => 2, 2 => 3];
$exp = $this->stringOutput ? $this->stringify($exp) : $exp;
$result = new $this->resultClass(...$this->makeResult("SELECT 1 as col union select 2 as col union select 3 as col"));
foreach ($result as $index => $row) {
$rows[$index] = $row['col'];
}
$this->assertSame($exp, $rows);
$this->assertException("resultReused", "Db");
foreach ($result as $row) {
$rows[] = $row['col'];
}
}
public function testGetSingleValues() {
$exp = [1867, 1970, 2112];
$exp = $this->stringOutput ? $this->stringify($exp) : $exp;
$test = new $this->resultClass(...$this->makeResult("SELECT 1867 as year union select 1970 as year union select 2112 as year"));
$this->assertSame($exp[0], $test->getValue());
$this->assertSame($exp[1], $test->getValue());
$this->assertSame($exp[2], $test->getValue());
$this->assertSame(null, $test->getValue());
}
public function testGetFirstValuesOnly() {
$exp = [1867, 1970, 2112];
$exp = $this->stringOutput ? $this->stringify($exp) : $exp;
$test = new $this->resultClass(...$this->makeResult("SELECT 1867 as year, 19 as century union select 1970 as year, 20 as century union select 2112 as year, 22 as century"));
$this->assertSame($exp[0], $test->getValue());
$this->assertSame($exp[1], $test->getValue());
$this->assertSame($exp[2], $test->getValue());
$this->assertSame(null, $test->getValue());
}
public function testGetRows() {
$exp = [
['album' => '2112', 'track' => '2112'],
['album' => 'Clockwork Angels', 'track' => 'The Wreckers'],
];
$test = new $this->resultClass(...$this->makeResult("SELECT '2112' as album, '2112' as track union select 'Clockwork Angels' as album, 'The Wreckers' as track"));
$this->assertSame($exp[0], $test->getRow());
$this->assertSame($exp[1], $test->getRow());
$this->assertSame(null, $test->getRow());
}
public function testGetAllRows() {
$exp = [
['album' => '2112', 'track' => '2112'],
['album' => 'Clockwork Angels', 'track' => 'The Wreckers'],
];
$test = new $this->resultClass(...$this->makeResult("SELECT '2112' as album, '2112' as track union select 'Clockwork Angels' as album, 'The Wreckers' as track"));
$this->assertEquals($exp, $test->getAll());
}
}

View file

@ -14,7 +14,7 @@ use JKingWeb\Arsse\Db\PostgreSQL\Driver;
class TestCreation extends \JKingWeb\Arsse\Test\AbstractTest {
/** @dataProvider provideConnectionStrings */
public function testGenerateConnectionString(bool $pdo, string $user, string $pass, string $db, string $host, int $port, string $service, string $exp) {
$this->setConf();
self::setConf();
$timeout = (string) ceil(Arsse::$conf->dbTimeoutConnect ?? 0);
$postfix = "application_name='arsse' client_encoding='UTF8' connect_timeout='$timeout'";
$act = Driver::makeConnectionString($pdo, $user, $pass, $db, $host, $port, $service);

View file

@ -107,7 +107,7 @@ class TestCreation extends \JKingWeb\Arsse\Test\AbstractTest {
chmod($path."Awal/arsse.db-wal", 0111);
chmod($path."Ashm/arsse.db-shm", 0111);
// set up configuration
$this->setConf();
self::setConf();
}
public function tearDown() {

View file

@ -49,7 +49,7 @@ class TestDriver extends \JKingWeb\Arsse\TestCase\Db\BaseDriver {
public function provideDrivers() {
$this->clearData();
$this->setConf([
self::setConf([
'dbTimeoutExec' => 0.5,
'dbSQLite3Timeout' => 0,
'dbSQLite3File' => tempnam(sys_get_temp_dir(), 'ook'),

View file

@ -0,0 +1,33 @@
<?php
/** @license MIT
* Copyright 2017 J. King, Dustin Wilson et al.
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse\TestCase\Db\SQLite3;
use JKingWeb\Arsse\Test\DatabaseInformation;
/**
* @covers \JKingWeb\Arsse\Db\SQLite3\Result<extended>
*/
class TestResult extends \JKingWeb\Arsse\TestCase\Db\BaseResult {
protected $implementation = "SQLite 3";
public function tearDown() {
parent::tearDown();
$this->interface->close();
unset($this->interface);
}
protected function exec(string $q) {
$this->interface->exec($q);
}
protected function makeResult(string $q): array {
$set = $this->interface->query($q);
$rows = $this->interface->changes();
$id = $this->interface->lastInsertRowID();
return [$set, [$rows, $id]];
}
}

View file

@ -31,7 +31,7 @@ class TestUpdate extends \JKingWeb\Arsse\Test\AbstractTest {
}
$this->clearData();
$this->vfs = vfsStream::setup("schemata", null, ['SQLite3' => []]);
$this->setConf($conf);
self::setConf($conf);
$this->base = $this->vfs->url();
$this->path = $this->base."/SQLite3/";
$this->drv = new Driver();

View file

@ -108,7 +108,7 @@ class TestCreation extends \JKingWeb\Arsse\Test\AbstractTest {
chmod($path."Awal/arsse.db-wal", 0111);
chmod($path."Ashm/arsse.db-shm", 0111);
// set up configuration
$this->setConf();
self::setConf();
}
public function tearDown() {

View file

@ -32,7 +32,7 @@ class TestUpdate extends \JKingWeb\Arsse\Test\AbstractTest {
$this->clearData();
$this->vfs = vfsStream::setup("schemata", null, ['SQLite3' => []]);
$conf['dbDriver'] = PDODriver::class;
$this->setConf($conf);
self::setConf($conf);
$this->base = $this->vfs->url();
$this->path = $this->base."/SQLite3/";
$this->drv = new PDODriver();

View file

@ -1,155 +0,0 @@
<?php
/** @license MIT
* Copyright 2017 J. King, Dustin Wilson et al.
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse\TestCase\Db;
use JKingWeb\Arsse\Arsse;
use JKingWeb\Arsse\Db\Result;
use JKingWeb\Arsse\Db\PDOResult;
use JKingWeb\Arsse\Db\SQLite3\PDODriver;
/**
* @covers \JKingWeb\Arsse\Db\PDOResult<extended>
* @covers \JKingWeb\Arsse\Db\SQLite3\Result<extended>
*/
class TestResult extends \JKingWeb\Arsse\Test\AbstractTest {
public function provideResults() {
$this->setConf();
$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]];
},
];
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 provideResults */
public function testConstructResult(bool $driverTestable, bool $stringCoersion, string $class, \Closure $func) {
if (!$driverTestable) {
$this->markTestSkipped();
}
$this->assertInstanceOf(Result::class, new $class(...$func("SELECT 1")));
}
/** @dataProvider provideResults */
public function testGetChangeCountAndLastInsertId(bool $driverTestable, bool $stringCoersion, string $class, \Closure $func) {
if (!$driverTestable) {
$this->markTestSkipped();
}
$func("CREATE TABLE if not exists arsse_meta(key varchar(255) primary key not null, value text)");
$out = $func("INSERT INTO arsse_meta(key,value) values('test', 1)");
$rows = $out[1][0];
$id = $out[1][1];
$r = new $class(...$out);
$this->assertSame((int) $rows, $r->changes());
$this->assertSame((int) $id, $r->lastId());
}
/** @dataProvider provideResults */
public function testIterateOverResults(bool $driverTestable, bool $stringCoersion, string $class, \Closure $func) {
if (!$driverTestable) {
$this->markTestSkipped();
}
$exp = [0 => 1, 1 => 2, 2 => 3];
$exp = $stringCoersion ? $this->stringify($exp) : $exp;
foreach (new $class(...$func("SELECT 1 as col union select 2 as col union select 3 as col")) as $index => $row) {
$rows[$index] = $row['col'];
}
$this->assertSame($exp, $rows);
}
/** @dataProvider provideResults */
public function testIterateOverResultsTwice(bool $driverTestable, bool $stringCoersion, string $class, \Closure $func) {
if (!$driverTestable) {
$this->markTestSkipped();
}
$exp = [0 => 1, 1 => 2, 2 => 3];
$exp = $stringCoersion ? $this->stringify($exp) : $exp;
$result = new $class(...$func("SELECT 1 as col union select 2 as col union select 3 as col"));
foreach ($result as $index => $row) {
$rows[$index] = $row['col'];
}
$this->assertSame($exp, $rows);
$this->assertException("resultReused", "Db");
foreach ($result as $row) {
$rows[] = $row['col'];
}
}
/** @dataProvider provideResults */
public function testGetSingleValues(bool $driverTestable, bool $stringCoersion, string $class, \Closure $func) {
if (!$driverTestable) {
$this->markTestSkipped();
}
$exp = [1867, 1970, 2112];
$exp = $stringCoersion ? $this->stringify($exp) : $exp;
$test = new $class(...$func("SELECT 1867 as year union select 1970 as year union select 2112 as year"));
$this->assertSame($exp[0], $test->getValue());
$this->assertSame($exp[1], $test->getValue());
$this->assertSame($exp[2], $test->getValue());
$this->assertSame(null, $test->getValue());
}
/** @dataProvider provideResults */
public function testGetFirstValuesOnly(bool $driverTestable, bool $stringCoersion, string $class, \Closure $func) {
if (!$driverTestable) {
$this->markTestSkipped();
}
$exp = [1867, 1970, 2112];
$exp = $stringCoersion ? $this->stringify($exp) : $exp;
$test = new $class(...$func("SELECT 1867 as year, 19 as century union select 1970 as year, 20 as century union select 2112 as year, 22 as century"));
$this->assertSame($exp[0], $test->getValue());
$this->assertSame($exp[1], $test->getValue());
$this->assertSame($exp[2], $test->getValue());
$this->assertSame(null, $test->getValue());
}
/** @dataProvider provideResults */
public function testGetRows(bool $driverTestable, bool $stringCoersion, string $class, \Closure $func) {
if (!$driverTestable) {
$this->markTestSkipped();
}
$exp = [
['album' => '2112', 'track' => '2112'],
['album' => 'Clockwork Angels', 'track' => 'The Wreckers'],
];
$test = new $class(...$func("SELECT '2112' as album, '2112' as track union select 'Clockwork Angels' as album, 'The Wreckers' as track"));
$this->assertSame($exp[0], $test->getRow());
$this->assertSame($exp[1], $test->getRow());
$this->assertSame(null, $test->getRow());
}
/** @dataProvider provideResults */
public function testGetAllRows(bool $driverTestable, bool $stringCoersion, string $class, \Closure $func) {
if (!$driverTestable) {
$this->markTestSkipped();
}
$exp = [
['album' => '2112', 'track' => '2112'],
['album' => 'Clockwork Angels', 'track' => 'The Wreckers'],
];
$test = new $class(...$func("SELECT '2112' as album, '2112' as track union select 'Clockwork Angels' as album, 'The Wreckers' as track"));
$this->assertEquals($exp, $test->getAll());
}
}

View file

@ -0,0 +1,52 @@
<?php
/** @license MIT
* Copyright 2017 J. King, Dustin Wilson et al.
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse\TestCase\Db;
use JKingWeb\Arsse\Test\DatabaseInformation;
/**
* @covers \JKingWeb\Arsse\Db\PDOResult<extended>
*/
class TestResultPDO extends \JKingWeb\Arsse\TestCase\Db\BaseResult {
protected static $firstAvailableDriver;
public static function setUpBeforeClass() {
self::setConf();
// we only need to test one PDO implementation (they all use the same result class), so we find the first usable one
$drivers = DatabaseInformation::listPDO();
self::$firstAvailableDriver = $drivers[0];
foreach ($drivers as $driver) {
$info = new DatabaseInformation($driver);
$interface = ($info->interfaceConstructor)();
if ($interface) {
self::$firstAvailableDriver = $driver;
break;
}
}
}
public function setUp() {
$this->implementation = self::$firstAvailableDriver;
parent::setUp();
}
public function tearDown() {
parent::tearDown();
unset($this->interface);
}
protected function exec(string $q) {
$this->interface->exec($q);
}
protected function makeResult(string $q): array {
$set = $this->interface->query($q);
$rows = $set->rowCount();
$id = $this->interface->lastInsertID();
return [$set, [$rows, $id]];
}
}

View file

@ -38,18 +38,14 @@ class TestStatement extends \JKingWeb\Arsse\Test\AbstractTest {
}
/** @dataProvider provideStatements */
public function testConstructStatement(bool $driverTestable, bool $stringCoersion, string $class, \Closure $func) {
if (!$driverTestable) {
$this->markTestSkipped();
}
public function testConstructStatement() {
$class = $this->statementClass;
$this->assertInstanceOf(Statement::class, new $class(...$func("SELECT ? as value")));
}
/** @dataProvider provideBindings */
public function testBindATypedValue(bool $driverTestable, string $class, \Closure $func, $value, string $type, string $exp) {
if (!$driverTestable) {
$this->markTestSkipped();
}
$class = $this->statementClass;
if ($exp=="null") {
$query = "SELECT (cast(? as text) is null) as pass";
} else {
@ -63,10 +59,8 @@ class TestStatement extends \JKingWeb\Arsse\Test\AbstractTest {
}
/** @dataProvider provideBinaryBindings */
public function testHandleBinaryData(bool $driverTestable, string $class, \Closure $func, $value, string $type, string $exp) {
if (!$driverTestable) {
$this->markTestSkipped();
}
public function testHandleBinaryData($value, string $type, string $exp) {
$class = $this->statementClass;
if ($exp=="null") {
$query = "SELECT (cast(? as text) is null) as pass";
} else {
@ -80,20 +74,16 @@ class TestStatement extends \JKingWeb\Arsse\Test\AbstractTest {
}
/** @dataProvider provideStatements */
public function testBindMissingValue(bool $driverTestable, bool $stringCoersion, string $class, \Closure $func) {
if (!$driverTestable) {
$this->markTestSkipped();
}
public function testBindMissingValue() {
$class = $this->statementClass;
$s = new $class(...$func("SELECT ? as value", ["int"]));
$val = $s->runArray()->getRow()['value'];
$this->assertSame(null, $val);
}
/** @dataProvider provideStatements */
public function testBindMultipleValues(bool $driverTestable, bool $stringCoersion, string $class, \Closure $func) {
if (!$driverTestable) {
$this->markTestSkipped();
}
public function testBindMultipleValues() {
$class = $this->statementClass;
$exp = [
'one' => 1,
'two' => 2,
@ -105,10 +95,8 @@ class TestStatement extends \JKingWeb\Arsse\Test\AbstractTest {
}
/** @dataProvider provideStatements */
public function testBindRecursively(bool $driverTestable, bool $stringCoersion, string $class, \Closure $func) {
if (!$driverTestable) {
$this->markTestSkipped();
}
public function testBindRecursively() {
$class = $this->statementClass;
$exp = [
'one' => 1,
'two' => 2,
@ -122,20 +110,16 @@ class TestStatement extends \JKingWeb\Arsse\Test\AbstractTest {
}
/** @dataProvider provideStatements */
public function testBindWithoutType(bool $driverTestable, bool $stringCoersion, string $class, \Closure $func) {
if (!$driverTestable) {
$this->markTestSkipped();
}
public function testBindWithoutType() {
$class = $this->statementClass;
$this->assertException("paramTypeMissing", "Db");
$s = new $class(...$func("SELECT ? as value", []));
$s->runArray([1]);
}
/** @dataProvider provideStatements */
public function testViolateConstraint(bool $driverTestable, bool $stringCoersion, string $class, \Closure $func) {
if (!$driverTestable) {
$this->markTestSkipped();
}
public function testViolateConstraint() {
$class = $this->statementClass;
(new $class(...$func("CREATE TABLE if not exists arsse_meta(key varchar(255) primary key not null, value text)")))->run();
$s = new $class(...$func("INSERT INTO arsse_meta(key) values(?)", ["str"]));
$this->assertException("constraintViolation", "Db", "ExceptionInput");
@ -143,10 +127,8 @@ class TestStatement extends \JKingWeb\Arsse\Test\AbstractTest {
}
/** @dataProvider provideStatements */
public function testMismatchTypes(bool $driverTestable, bool $stringCoersion, string $class, \Closure $func) {
if (!$driverTestable) {
$this->markTestSkipped();
}
public function testMismatchTypes() {
$class = $this->statementClass;
(new $class(...$func("CREATE TABLE if not exists arsse_feeds(id integer primary key not null, url text not null)")))->run();
$s = new $class(...$func("INSERT INTO arsse_feeds(id,url) values(?,?)", ["str", "str"]));
$this->assertException("typeViolation", "Db", "ExceptionInput");

View file

@ -96,7 +96,7 @@ class TestFeed extends \JKingWeb\Arsse\Test\AbstractTest {
}
$this->base = self::$host."Feed/";
$this->clearData();
$this->setConf();
self::setConf();
Arsse::$db = Phake::mock(Database::class);
}

View file

@ -26,7 +26,7 @@ class TestFetching extends \JKingWeb\Arsse\Test\AbstractTest {
}
$this->base = self::$host."Feed/";
$this->clearData();
$this->setConf();
self::setConf();
}
public function testHandle400() {

View file

@ -340,7 +340,7 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
public function setUp() {
$this->clearData();
$this->setConf();
self::setConf();
// create a mock user manager
Arsse::$user = Phake::mock(User::class);
Phake::when(Arsse::$user)->auth->thenReturn(true);

View file

@ -95,7 +95,7 @@ class TestREST extends \JKingWeb\Arsse\Test\AbstractTest {
}
public function testSendAuthenticationChallenges() {
$this->setConf();
self::setConf();
$r = new REST();
$in = new EmptyResponse(401);
$exp = $in->withHeader("WWW-Authenticate", 'Basic realm="OOK"');
@ -151,7 +151,7 @@ class TestREST extends \JKingWeb\Arsse\Test\AbstractTest {
/** @dataProvider provideCorsNegotiations */
public function testNegotiateCors($origin, bool $exp, string $allowed = null, string $denied = null) {
$this->setConf();
self::setConf();
$r = Phake::partialMock(REST::class);
Phake::when($r)->corsNormalizeOrigin->thenReturnCallback(function ($origin) {
return $origin;

View file

@ -177,7 +177,7 @@ LONG_STRING;
public function setUp() {
$this->clearData();
$this->setConf();
self::setConf();
// create a mock user manager
Arsse::$user = Phake::mock(User::class);
Phake::when(Arsse::$user)->auth->thenReturn(true);
@ -225,7 +225,7 @@ LONG_STRING;
/** @dataProvider provideLoginRequests */
public function testLogIn(array $conf, $httpUser, array $data, $sessions) {
Arsse::$user->id = null;
$this->setConf($conf);
self::setConf($conf);
Phake::when(Arsse::$user)->auth->thenReturn(false);
Phake::when(Arsse::$user)->auth("john.doe@example.com", "secret")->thenReturn(true);
Phake::when(Arsse::$user)->auth("jane.doe@example.com", "superman")->thenReturn(true);
@ -259,7 +259,7 @@ LONG_STRING;
/** @dataProvider provideResumeRequests */
public function testValidateASession(array $conf, $httpUser, string $data, $result) {
Arsse::$user->id = null;
$this->setConf($conf);
self::setConf($conf);
Phake::when(Arsse::$db)->sessionResume("PriestsOfSyrinx")->thenReturn([
'id' => "PriestsOfSyrinx",
'created' => "2000-01-01 00:00:00",

View file

@ -24,7 +24,7 @@ class TestIcon extends \JKingWeb\Arsse\Test\AbstractTest {
public function setUp() {
$this->clearData();
$this->setConf();
self::setConf();
// create a mock user manager
Arsse::$user = Phake::mock(User::class);
// create a mock database interface
@ -108,7 +108,7 @@ class TestIcon extends \JKingWeb\Arsse\Test\AbstractTest {
$this->assertMessage($exp, $this->reqAuthFailed("42.ico"));
$this->assertMessage($exp, $this->reqAuthFailed("1337.ico"));
// with HTTP auth required, only authenticated requests should succeed
$this->setConf(['userHTTPAuthRequired' => true]);
self::setConf(['userHTTPAuthRequired' => true]);
$exp = new Response(301, ['Location' => "http://example.org/icon.gif"]);
$this->assertMessage($exp, $this->reqAuth("42.ico"));
$this->assertMessage($exp, $this->reqAuth("1337.ico"));

View file

@ -19,7 +19,7 @@ class TestService extends \JKingWeb\Arsse\Test\AbstractTest {
public function setUp() {
$this->clearData();
$this->setConf();
self::setConf();
Arsse::$db = Phake::mock(Database::class);
$this->srv = new Service();
}

View file

@ -20,7 +20,7 @@ class TestInternal extends \JKingWeb\Arsse\Test\AbstractTest {
public function setUp() {
$this->clearData();
$this->setConf();
self::setConf();
// create a mock database interface
Arsse::$db = Phake::mock(Database::class);
Phake::when(Arsse::$db)->begin->thenReturn(Phake::mock(\JKingWeb\Arsse\Db\Transaction::class));

View file

@ -20,7 +20,7 @@ class TestUser extends \JKingWeb\Arsse\Test\AbstractTest {
public function setUp() {
$this->clearData();
$this->setConf();
self::setConf();
// create a mock database interface
Arsse::$db = Phake::mock(Database::class);
Phake::when(Arsse::$db)->begin->thenReturn(Phake::mock(\JKingWeb\Arsse\Db\Transaction::class));

View file

@ -40,7 +40,7 @@ abstract class AbstractTest extends \PHPUnit\Framework\TestCase {
}
}
public function setConf(array $conf = []) {
public static function setConf(array $conf = []) {
$defaults = [
'dbSQLite3File' => ":memory:",
'dbSQLite3Timeout' => 0,
@ -126,165 +126,4 @@ abstract class AbstractTest extends \PHPUnit\Framework\TestCase {
}
return $value;
}
public function provideDbDrivers(array $conf = []): array {
$this->setConf($conf);
return [
'SQLite 3' => (function() {
try {
return new \JKingWeb\Arsse\Db\SQLite3\Driver;
} catch (\Exception $e) {
return;
}
})(),
'PDO SQLite 3' => (function() {
try {
return new \JKingWeb\Arsse\Db\SQLite3\PDODriver;
} catch (\Exception $e) {
return;
}
})(),
'PDO PostgreSQL' => (function() {
try {
return new \JKingWeb\Arsse\Db\PostgreSQL\PDODriver;
} catch (\Exception $e) {
return;
}
})(),
];
}
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,
],
];
}
public function getDbDriver(string $name, array $conf = []) {
$this->setConf($conf);
switch ($name) {
case 'SQLite 3':
return (function() {
try {
return new \JKingWeb\Arsse\Db\SQLite3\Driver;
} catch (\Exception $e) {
return;
}
})();
case 'PDO SQLite 3':
return (function() {
try {
return new \JKingWeb\Arsse\Db\SQLite3\PDODriver;
} catch (\Exception $e) {
return;
}
})();
case 'PDO PostgreSQL':
return (function() {
try {
return new \JKingWeb\Arsse\Db\PostgreSQL\PDODriver;
} catch (\Exception $e) {
return;
}
})();
default:
throw new \Exception("Invalid database driver name");
}
}
public function getDbInterface(string $name, array $conf = []) {
$this->setConf($conf);
switch ($name) {
case 'SQLite 3':
return (function() {
if (\JKingWeb\Arsse\Db\SQLite3\Driver::requirementsMet()) {
try {
$d = new \SQLite3(Arsse::$conf->dbSQLite3File);
} catch (\Exception $e) {
return;
}
$d->enableExceptions(true);
return $d;
}
})();
case 'PDO SQLite 3':
return (function() {
if (\JKingWeb\Arsse\Db\SQLite3\PDODriver::requirementsMet()) {
try {
$d = new \PDO("sqlite:".Arsse::$conf->dbSQLite3File, "", "", [\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION]);
$d->exec("PRAGMA busy_timeout=0");
return $d;
} catch (\PDOException $e) {
return;
}
}
})();
case 'PDO PostgreSQL':
return (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;
}
})();
default:
throw new \Exception("Invalid database driver name");
}
}
}

View file

@ -22,7 +22,7 @@ trait Setup {
public function setUp() {
// establish a clean baseline
$this->clearData();
$this->setConf();
self::setConf();
// configure and create the relevant database driver
$this->setUpDriver();
// create the database interface with the suitable driver

View file

@ -0,0 +1,111 @@
<?php
/** @license MIT
* Copyright 2017 J. King, Dustin Wilson et al.
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse\Test;
use JKingWeb\Arsse\Arsse;
class DatabaseInformation {
public $name;
public $backend;
public $pdo;
public $resultClass;
public $statementClass;
public $driverClass;
public $stringOutput;
public $interfaceConstructor;
protected static $data;
public function __construct(string $name) {
if (!isset(self::$data)) {
self::$data = self::getData();
}
if (!isset(self::$data[$name])) {
throw new \Exception("Invalid database driver name");
}
$this->name = $name;
foreach (self::$data[$name] as $key => $value) {
$this->$key = $value;
}
}
public static function list(): array {
if (!isset(self::$data)) {
self::$data = self::getData();
}
return array_keys(self::$data);
}
public static function listPDO(): array {
if (!isset(self::$data)) {
self::$data = self::getData();
}
return array_values(array_filter(array_keys(self::$data), function($k) {
return self::$data[$k]['pdo'];
}));
}
protected static function getData() {
return [
'SQLite 3' => [
'pdo' => false,
'backend' => "SQLite 3",
'statementClass' => \JKingWeb\Arsse\Db\SQLite3\Statement::class,
'resultClass' => \JKingWeb\Arsse\Db\SQLite3\Result::class,
'driverClass' => \JKingWeb\Arsse\Db\SQLite3\Driver::class,
'stringOutput' => false,
'interfaceConstructor' => function() {
try {
$d = new \SQLite3(Arsse::$conf->dbSQLite3File);
} catch (\Throwable $e) {
return;
}
$d->enableExceptions(true);
return $d;
},
],
'PDO SQLite 3' => [
'pdo' => true,
'backend' => "SQLite 3",
'statementClass' => \JKingWeb\Arsse\Db\PDOStatement::class,
'resultClass' => \JKingWeb\Arsse\Db\PDOResult::class,
'driverClass' => \JKingWeb\Arsse\Db\SQLite3\PDODriver::class,
'stringOutput' => true,
'interfaceConstructor' => function() {
try {
$d = new \PDO("sqlite:".Arsse::$conf->dbSQLite3File, "", "", [\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION]);
$d->exec("PRAGMA busy_timeout=0");
return $d;
} catch (\Throwable $e) {
return;
}
},
],
'PDO PostgreSQL' => [
'pdo' => true,
'backend' => "PostgreSQL",
'statementClass' => \JKingWeb\Arsse\Db\PDOStatement::class,
'resultClass' => \JKingWeb\Arsse\Db\PDOResult::class,
'driverClass' => \JKingWeb\Arsse\Db\PostgreSQL\PDODriver::class,
'stringOutput' => true,
'interfaceConstructor' => function() {
$connString = \JKingWeb\Arsse\Db\PostgreSQL\Driver::makeConnectionString(true, Arsse::$conf->dbPostgreSQLUser, Arsse::$conf->dbPostgreSQLPass, Arsse::$conf->dbPostgreSQLDb, Arsse::$conf->dbPostgreSQLHost, Arsse::$conf->dbPostgreSQLPort, "");
try {
$d = new \PDO("pgsql:".$connString, Arsse::$conf->dbPostgreSQLUser, Arsse::$conf->dbPostgreSQLPass, [\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION]);
} catch (\Throwable $e) {
return;
}
foreach (\JKingWeb\Arsse\Db\PostgreSQL\PDODriver::makeSetupQueries(Arsse::$conf->dbPostgreSQLSchema) as $q) {
$d->exec($q);
}
return $d;
},
],
];
}
}

View file

@ -45,19 +45,23 @@
<file>cases/Db/TestTransaction.php</file>
<file>cases/Db/TestResultAggregate.php</file>
<file>cases/Db/TestResultEmpty.php</file>
<file>cases/Db/TestResult.php</file>
<file>cases/Db/TestStatement.php</file>
<file>cases/Db/TestResultPDO.php</file>
<file>cases/Db/SQLite3/TestResult.php</file>
<file>cases/Db/SQLite3/TestStatement.php</file>
<file>cases/Db/SQLite3/TestCreation.php</file>
<file>cases/Db/SQLite3/TestDriver.php</file>
<file>cases/Db/SQLite3/TestUpdate.php</file>
<file>cases/Db/SQLite3PDO/TestStatement.php</file>
<file>cases/Db/SQLite3PDO/TestCreation.php</file>
<file>cases/Db/SQLite3PDO/TestDriver.php</file>
<file>cases/Db/SQLite3PDO/TestUpdate.php</file>
<file>cases/Db/PostgreSQL/TestStatement.php</file>
<file>cases/Db/PostgreSQL/TestCreation.php</file>
<file>cases/Db/PostgreSQL/TestDriver.php</file>
<!--<file>cases/Db/PostgreSQL/TestDriver.php</file>-->
<!--<file>cases/Db/PostgreSQL/TestUpdate.php</file>-->
</testsuite>
<testsuite name="Database functions">
<file>cases/Db/SQLite3/Database/TestMiscellany.php</file>