diff --git a/lib/Db/AbstractDriver.php b/lib/Db/AbstractDriver.php index 7893f13..71cf368 100644 --- a/lib/Db/AbstractDriver.php +++ b/lib/Db/AbstractDriver.php @@ -4,10 +4,13 @@ namespace JKingWeb\Arsse\Db; use JKingWeb\DrUUID\UUID as UUID; abstract class AbstractDriver implements Driver { + protected $locked = false; protected $transDepth = 0; protected $transStatus = []; public abstract function prepareArray(string $query, array $paramTypes): Statement; + protected abstract function lock(): bool; + protected abstract function unlock(bool $rollback = false) : bool; public function schemaVersion(): int { try { @@ -17,11 +20,15 @@ abstract class AbstractDriver implements Driver { } } - public function begin(): Transaction { - return new Transaction($this); + public function begin(bool $lock = false): Transaction { + return new Transaction($this, $lock); } - public function savepointCreate(): int { + public function savepointCreate(bool $lock = false): int { + if($lock && !$this->transDepth) { + $this->lock(); + $this->locked = true; + } $this->exec("SAVEPOINT arsse_".(++$this->transDepth)); $this->transStatus[$this->transDepth] = self::TR_PEND; return $this->transDepth; @@ -60,6 +67,10 @@ abstract class AbstractDriver implements Driver { $this->transDepth--; } } + if(!$this->transDepth && $this->locked) { + $this->unlock(); + $this->locked = false; + } return $out; } else { throw new ExceptionSavepoint("invalid", ['action' => "commit", 'index' => $index]); @@ -100,36 +111,16 @@ abstract class AbstractDriver implements Driver { $this->transDepth--; } } + if(!$this->transDepth && $this->locked) { + $this->unlock(true); + $this->locked = false; + } return $out; } else { throw new ExceptionSavepoint("invalid", ['action' => "rollback", 'index' => $index]); } } - public function lock(): bool { - if($this->schemaVersion() < 1) return true; - if($this->isLocked()) return false; - $uuid = UUID::mintStr(); - try { - $this->prepare("INSERT INTO arsse_meta(key,value) values(?,?)", "str", "str")->run("lock", $uuid); - } catch(ExceptionInput $e) { - return false; - } - sleep(1); - return ($this->query("SELECT value from arsse_meta where key is 'lock'")->getValue() == $uuid); - } - - public function unlock(): bool { - if($this->schemaVersion() < 1) return true; - $this->exec("DELETE from arsse_meta where key is 'lock'"); - return true; - } - - public function isLocked(): bool { - if($this->schemaVersion() < 1) return false; - return ($this->query("SELECT count(*) from arsse_meta where key is 'lock'")->getValue() > 0); - } - public function prepare(string $query, ...$paramType): Statement { return $this->prepareArray($query, $paramType); } diff --git a/lib/Db/AbstractStatement.php b/lib/Db/AbstractStatement.php index 649a5d8..e3ebacb 100644 --- a/lib/Db/AbstractStatement.php +++ b/lib/Db/AbstractStatement.php @@ -59,25 +59,17 @@ abstract class AbstractStatement implements Statement { case "string": case "boolean": if($t=="binary") $t = "string"; - $value = $v; - try{ - settype($value, $t); - } catch(\Throwable $e) { - // handle objects - $value = $v; - if($value instanceof \DateTimeInterface) { - if($t=="string") { - $value = $this->dateTransform($value, "sql"); - } else { - $value = $value->getTimestamp(); - settype($value, $t); - } + if($v instanceof \DateTimeInterface) { + if($t=="string") { + return $this->dateTransform($v, "sql"); } else { - $value = null; - settype($value, $t); + $v = $v->getTimestamp(); + settype($v, $t); } + } else { + settype($v, $t); } - return $value; + return $v; default: throw new Exception("paramTypeUnknown", $type); } diff --git a/lib/Db/Driver.php b/lib/Db/Driver.php index 579d69e..57cf873 100644 --- a/lib/Db/Driver.php +++ b/lib/Db/Driver.php @@ -15,17 +15,13 @@ interface Driver { // returns the version of the scheme of the opened database; if uninitialized should return 0 function schemaVersion(): int; // return a Transaction object - function begin(): Transaction; + function begin(bool $lock = false): Transaction; // manually begin a real or synthetic transactions, with real or synthetic nesting function savepointCreate(): int; // manually commit either the latest or all pending nested transactions function savepointRelease(int $index = null): bool; // manually rollback either the latest or all pending nested transactions function savepointUndo(int $index = null): bool; - // attempt to advise other processes that they should not attempt to access the database; used during live upgrades - function lock(): bool; - function unlock(): bool; - function isLocked(): bool; // attempt to perform an in-place upgrade of the database schema; this may be a no-op which always throws an exception function schemaUpdate(int $to): bool; // execute one or more unsanitized SQL queries and return an indication of success diff --git a/lib/Db/SQLite3/Driver.php b/lib/Db/SQLite3/Driver.php index 88b1a5f..342569b 100644 --- a/lib/Db/SQLite3/Driver.php +++ b/lib/Db/SQLite3/Driver.php @@ -22,7 +22,7 @@ class Driver extends \JKingWeb\Arsse\Db\AbstractDriver { $file = Data::$conf->dbSQLite3File; // if the file exists (or we're initializing the database), try to open it try { - $this->db = new \SQLite3($file, ($install) ? \SQLITE3_OPEN_READWRITE | \SQLITE3_OPEN_CREATE : \SQLITE3_OPEN_READWRITE, Data::$conf->dbSQLite3Key); + $this->db = $this->makeConnection($file, ($install) ? \SQLITE3_OPEN_READWRITE | \SQLITE3_OPEN_CREATE : \SQLITE3_OPEN_READWRITE, Data::$conf->dbSQLite3Key); } catch(\Throwable $e) { // if opening the database doesn't work, check various pre-conditions to find out what the problem might be if(!file_exists($file)) { @@ -46,6 +46,10 @@ class Driver extends \JKingWeb\Arsse\Db\AbstractDriver { } } + protected function makeConnection(string $file, int $opts, string $key): \SQLite3 { + return new \SQLite3($file, $opts, $key); + } + public function __destruct() { try{$this->db->close();} catch(\Exception $e) {} unset($this->db); @@ -66,9 +70,9 @@ class Driver extends \JKingWeb\Arsse\Db\AbstractDriver { if($ver >= $to) throw new Exception("updateTooNew", ['difference' => ($ver - $to), 'current' => $ver, 'target' => $to, 'driver_name' => $this->driverName()]); $sep = \DIRECTORY_SEPARATOR; $path = Data::$conf->dbSchemaBase.$sep."SQLite3".$sep; - $this->lock(); - $tr = $this->savepointCreate(); - for($a = $ver; $a < $to; $a++) { + // lock the database + $this->savepointCreate(true); + for($a = $this->schemaVersion(); $a < $to; $a++) { $this->savepointCreate(); try { $file = $path.$a.".sql"; @@ -78,7 +82,7 @@ class Driver extends \JKingWeb\Arsse\Db\AbstractDriver { if($sql===false) throw new Exception("updateFileUnusable", ['file' => $file, 'driver_name' => $this->driverName(), 'current' => $a]); try { $this->exec($sql); - } catch(\Exception $e) { + } catch(\Throwable $e) { throw new Exception("updateFileError", ['file' => $file, 'driver_name' => $this->driverName(), 'current' => $a, 'message' => $this->getError()]); } if($this->schemaVersion() != $a+1) throw new Exception("updateFileIncomplete", ['file' => $file, 'driver_name' => $this->driverName(), 'current' => $a]); @@ -86,14 +90,12 @@ class Driver extends \JKingWeb\Arsse\Db\AbstractDriver { // undo any partial changes from the failed update $this->savepointUndo(); // commit any successful updates if updating by more than one version - $this->unlock(); $this->savepointRelease(); // throw the error received throw $e; } $this->savepointRelease(); } - $this->unlock(); $this->savepointRelease(); return true; } @@ -132,4 +134,14 @@ class Driver extends \JKingWeb\Arsse\Db\AbstractDriver { } return new Statement($this->db, $s, $paramTypes); } + + protected function lock(): bool { + $this->exec("BEGIN EXCLUSIVE TRANSACTION"); + return true; + } + + protected function unlock(bool $rollback = false): bool { + $this->exec((!$rollback) ? "COMMIT" : "ROLLBACK"); + return true; + } } \ No newline at end of file diff --git a/lib/Db/Transaction.php b/lib/Db/Transaction.php index 81f6125..964a358 100644 --- a/lib/Db/Transaction.php +++ b/lib/Db/Transaction.php @@ -7,8 +7,8 @@ class Transaction { protected $pending = false; protected $drv; - function __construct(Driver $drv) { - $this->index = $drv->savepointCreate(); + function __construct(Driver $drv, bool $lock = false) { + $this->index = $drv->savepointCreate($lock); $this->drv = $drv; $this->pending = true; } diff --git a/lib/Misc/Context.php b/lib/Misc/Context.php index 41a490c..fe084ec 100644 --- a/lib/Misc/Context.php +++ b/lib/Misc/Context.php @@ -43,13 +43,8 @@ class Context { continue; } if(is_string($id)) { - try { - $ch1 = strval(intval($id)); - $ch2 = strval($id); - } catch(\Throwable $e) { - $ch1 = true; - $ch2 = false; - } + $ch1 = strval(@intval($id)); + $ch2 = strval($id); if($ch1 !== $ch2 || $id < 1) $id = 0; } else { $id = 0; diff --git a/lib/REST/AbstractHandler.php b/lib/REST/AbstractHandler.php index 7d610b8..3d8f31f 100644 --- a/lib/REST/AbstractHandler.php +++ b/lib/REST/AbstractHandler.php @@ -32,12 +32,8 @@ abstract class AbstractHandler implements Handler { } protected function validateInt($id): bool { - try { - $ch1 = strval(intval($id)); - $ch2 = strval($id); - } catch(\Throwable $e) { - return false; - } + $ch1 = strval(@intval($id)); + $ch2 = strval($id); return ($ch1 === $ch2); } diff --git a/lib/REST/NextCloudNews/V1_2.php b/lib/REST/NextCloudNews/V1_2.php index cf62db0..a43692e 100644 --- a/lib/REST/NextCloudNews/V1_2.php +++ b/lib/REST/NextCloudNews/V1_2.php @@ -46,9 +46,8 @@ class V1_2 extends \JKingWeb\Arsse\REST\AbstractHandler { if($req->body) { // if the entity body is not JSON according to content type, return "415 Unsupported Media Type" if(!preg_match("<^application/json\b|^$>", $req->type)) return new Response(415, "", "", ['Accept: application/json']); - try { - $data = json_decode($req->body, true); - } catch(\Throwable $e) { + $data = @json_decode($req->body, true); + if(json_last_error() != \JSON_ERROR_NONE) { // if the body could not be parsed as JSON, return "400 Bad Request" return new Response(400); } diff --git a/tests/Conf/TestConf.php b/tests/Conf/TestConf.php index b53ad72..587bb68 100644 --- a/tests/Conf/TestConf.php +++ b/tests/Conf/TestConf.php @@ -4,9 +4,7 @@ namespace JKingWeb\Arsse; use org\bovigo\vfs\vfsStream; -class TestConf extends \PHPUnit\Framework\TestCase { - use Test\Tools; - +class TestConf extends Test\AbstractTest { static $vfs; static $path; diff --git a/tests/Db/SQLite3/Database/TestDatabaseArticleSQLite3.php b/tests/Db/SQLite3/Database/TestDatabaseArticleSQLite3.php index 5da9784..e27b59a 100644 --- a/tests/Db/SQLite3/Database/TestDatabaseArticleSQLite3.php +++ b/tests/Db/SQLite3/Database/TestDatabaseArticleSQLite3.php @@ -2,8 +2,8 @@ declare(strict_types=1); namespace JKingWeb\Arsse; -class TestDatabaseArticleSQLite3 extends \PHPUnit\Framework\TestCase { - use Test\Tools, Test\Database\Setup; +class TestDatabaseArticleSQLite3 extends Test\AbstractTest { + use Test\Database\Setup; use Test\Database\DriverSQLite3; use Test\Database\SeriesArticle; } \ No newline at end of file diff --git a/tests/Db/SQLite3/Database/TestDatabaseFeedSQLite3.php b/tests/Db/SQLite3/Database/TestDatabaseFeedSQLite3.php index 1da51df..10d663e 100644 --- a/tests/Db/SQLite3/Database/TestDatabaseFeedSQLite3.php +++ b/tests/Db/SQLite3/Database/TestDatabaseFeedSQLite3.php @@ -2,8 +2,8 @@ declare(strict_types=1); namespace JKingWeb\Arsse; -class TestDatabaseFeedSQLite3 extends \PHPUnit\Framework\TestCase { - use Test\Tools, Test\Database\Setup; +class TestDatabaseFeedSQLite3 extends Test\AbstractTest { + use Test\Database\Setup; use Test\Database\DriverSQLite3; use Test\Database\SeriesFeed; } \ No newline at end of file diff --git a/tests/Db/SQLite3/Database/TestDatabaseFolderSQLite3.php b/tests/Db/SQLite3/Database/TestDatabaseFolderSQLite3.php index dea9c11..2476f53 100644 --- a/tests/Db/SQLite3/Database/TestDatabaseFolderSQLite3.php +++ b/tests/Db/SQLite3/Database/TestDatabaseFolderSQLite3.php @@ -2,8 +2,8 @@ declare(strict_types=1); namespace JKingWeb\Arsse; -class TestDatabaseFolderSQLite3 extends \PHPUnit\Framework\TestCase { - use Test\Tools, Test\Database\Setup; +class TestDatabaseFolderSQLite3 extends Test\AbstractTest { + use Test\Database\Setup; use Test\Database\DriverSQLite3; use Test\Database\SeriesFolder; } \ No newline at end of file diff --git a/tests/Db/SQLite3/Database/TestDatabaseSubscriptionSQLite3.php b/tests/Db/SQLite3/Database/TestDatabaseSubscriptionSQLite3.php index bb77181..a9f9d39 100644 --- a/tests/Db/SQLite3/Database/TestDatabaseSubscriptionSQLite3.php +++ b/tests/Db/SQLite3/Database/TestDatabaseSubscriptionSQLite3.php @@ -2,8 +2,8 @@ declare(strict_types=1); namespace JKingWeb\Arsse; -class TestDatabaseSubscriptionSQLite3 extends \PHPUnit\Framework\TestCase { - use Test\Tools, Test\Database\Setup; +class TestDatabaseSubscriptionSQLite3 extends Test\AbstractTest { + use Test\Database\Setup; use Test\Database\DriverSQLite3; use Test\Database\SeriesSubscription; } \ No newline at end of file diff --git a/tests/Db/SQLite3/Database/TestDatabaseUserSQLite3.php b/tests/Db/SQLite3/Database/TestDatabaseUserSQLite3.php index 35c55c7..d1e63b6 100644 --- a/tests/Db/SQLite3/Database/TestDatabaseUserSQLite3.php +++ b/tests/Db/SQLite3/Database/TestDatabaseUserSQLite3.php @@ -2,8 +2,8 @@ declare(strict_types=1); namespace JKingWeb\Arsse; -class TestDatabaseUserSQLite3 extends \PHPUnit\Framework\TestCase { - use Test\Tools, Test\Database\Setup; +class TestDatabaseUserSQLite3 extends Test\AbstractTest { + use Test\Database\Setup; use Test\Database\DriverSQLite3; use Test\Database\SeriesUser; } \ No newline at end of file diff --git a/tests/Db/SQLite3/TestDbDriverSQLite3.php b/tests/Db/SQLite3/TestDbDriverSQLite3.php index acd31f5..cfbdfbd 100644 --- a/tests/Db/SQLite3/TestDbDriverSQLite3.php +++ b/tests/Db/SQLite3/TestDbDriverSQLite3.php @@ -3,9 +3,7 @@ declare(strict_types=1); namespace JKingWeb\Arsse; -class TestDbDriverSQLite3 extends \PHPUnit\Framework\TestCase { - use Test\Tools; - +class TestDbDriverSQLite3 extends Test\AbstractTest { protected $data; protected $drv; protected $ch; @@ -21,6 +19,7 @@ class TestDbDriverSQLite3 extends \PHPUnit\Framework\TestCase { Data::$conf = $conf; $this->drv = new Db\SQLite3\Driver(true); $this->ch = new \SQLite3(Data::$conf->dbSQLite3File); + $this->ch->enableExceptions(true); } function tearDown() { @@ -68,7 +67,7 @@ class TestDbDriverSQLite3 extends \PHPUnit\Framework\TestCase { } function testMakeAValidQuery() { - $this->assertInstanceOf(Db\SQLite3\Result::class, $this->drv->query("SELECT 1")); + $this->assertInstanceOf(Db\Result::class, $this->drv->query("SELECT 1")); } function testMakeAnInvalidQuery() { @@ -96,7 +95,7 @@ class TestDbDriverSQLite3 extends \PHPUnit\Framework\TestCase { function testPrepareAValidQuery() { $s = $this->drv->prepare("SELECT ?, ?", "int", "int"); - $this->assertInstanceOf(Db\SQLite3\Statement::class, $s); + $this->assertInstanceOf(Db\Statement::class, $s); } function testPrepareAnInvalidQuery() { @@ -295,25 +294,17 @@ class TestDbDriverSQLite3 extends \PHPUnit\Framework\TestCase { $this->assertSame(1, $this->drv->schemaVersion()); $this->drv->exec("PRAGMA user_version=2"); $this->assertSame(2, $this->drv->schemaVersion()); + } + function testLockTheDatabase() { + $this->drv->savepointCreate(true); + $this->assertException(); + $this->ch->exec("CREATE TABLE test(id integer primary key)"); } - function testManipulateAdvisoryLock() { - $this->assertTrue($this->drv->unlock()); - $this->assertFalse($this->drv->isLocked()); - $this->assertTrue($this->drv->lock()); - $this->assertFalse($this->drv->isLocked()); - $this->drv->exec("CREATE TABLE arsse_meta(key text primary key, value text); PRAGMA user_version=1"); - $this->assertTrue($this->drv->lock()); - $this->assertTrue($this->drv->isLocked()); - $this->assertFalse($this->drv->lock()); - $this->drv->exec("PRAGMA user_version=0"); - $this->assertFalse($this->drv->isLocked()); - $this->assertTrue($this->drv->lock()); - $this->assertFalse($this->drv->isLocked()); - $this->drv->exec("PRAGMA user_version=1"); - $this->assertTrue($this->drv->isLocked()); - $this->assertTrue($this->drv->unlock()); - $this->assertFalse($this->drv->isLocked()); + function testUnlockTheDatabase() { + $this->drv->savepointCreate(true); + $this->drv->savepointRelease(); + $this->assertSame(true, $this->ch->exec("CREATE TABLE test(id integer primary key)")); } } \ No newline at end of file diff --git a/tests/Db/SQLite3/TestDbResultSQLite3.php b/tests/Db/SQLite3/TestDbResultSQLite3.php index 73d530b..e9aaf13 100644 --- a/tests/Db/SQLite3/TestDbResultSQLite3.php +++ b/tests/Db/SQLite3/TestDbResultSQLite3.php @@ -3,8 +3,7 @@ declare(strict_types=1); namespace JKingWeb\Arsse; -class TestDbResultSQLite3 extends \PHPUnit\Framework\TestCase { - use Test\Tools; +class TestDbResultSQLite3 extends Test\AbstractTest { protected $c; diff --git a/tests/Db/SQLite3/TestDbStatementSQLite3.php b/tests/Db/SQLite3/TestDbStatementSQLite3.php index b45aaf4..50b6cfe 100644 --- a/tests/Db/SQLite3/TestDbStatementSQLite3.php +++ b/tests/Db/SQLite3/TestDbStatementSQLite3.php @@ -4,8 +4,8 @@ namespace JKingWeb\Arsse; use JKingWeb\Arsse\Db\Statement; -class TestDbStatementSQLite3 extends \PHPUnit\Framework\TestCase { - use Test\Tools, Test\Db\BindingTests; +class TestDbStatementSQLite3 extends Test\AbstractTest { + use Test\Db\BindingTests; protected $c; static protected $imp = Db\SQLite3\Statement::class; @@ -20,7 +20,6 @@ class TestDbStatementSQLite3 extends \PHPUnit\Framework\TestCase { } function tearDown() { - try {$this->s->close();} catch(\Exception $e) {} $this->c->close(); unset($this->c); } @@ -32,7 +31,7 @@ class TestDbStatementSQLite3 extends \PHPUnit\Framework\TestCase { foreach($types as $type) { $s->rebindArray([$strict ? "strict $type" : $type]); $val = $s->runArray([$input])->getRow()['value']; - $this->assertSame($expectations[$type], $val, "Type $type failed comparison."); + $this->assertSame($expectations[$type], $val, "Binding from type $type failed comparison."); } } diff --git a/tests/Db/SQLite3/TestDbUpdateSQLite3.php b/tests/Db/SQLite3/TestDbUpdateSQLite3.php index 29f9f3e..94ee0f6 100644 --- a/tests/Db/SQLite3/TestDbUpdateSQLite3.php +++ b/tests/Db/SQLite3/TestDbUpdateSQLite3.php @@ -4,9 +4,7 @@ namespace JKingWeb\Arsse; use org\bovigo\vfs\vfsStream; -class TestDbUpdateSQLite3 extends \PHPUnit\Framework\TestCase { - use Test\Tools; - +class TestDbUpdateSQLite3 extends Test\AbstractTest { protected $data; protected $drv; protected $vfs; diff --git a/tests/Exception/TestException.php b/tests/Exception/TestException.php index 27c1318..4a453b2 100644 --- a/tests/Exception/TestException.php +++ b/tests/Exception/TestException.php @@ -4,9 +4,7 @@ namespace JKingWeb\Arsse; Use Phake; -class TestException extends \PHPUnit\Framework\TestCase { - use Test\Tools; - +class TestException extends Test\AbstractTest { function setUp() { $this->clearData(false); // create a mock Lang object so as not to create a dependency loop diff --git a/tests/Feed/TestFeed.php b/tests/Feed/TestFeed.php index 72b139f..3497919 100644 --- a/tests/Feed/TestFeed.php +++ b/tests/Feed/TestFeed.php @@ -4,9 +4,7 @@ namespace JKingWeb\Arsse; Use Phake; -class TestFeed extends \PHPUnit\Framework\TestCase { - use Test\Tools; - +class TestFeed extends Test\AbstractTest { protected static $host = "http://localhost:8000/"; protected $base = ""; protected $latest = [ diff --git a/tests/Feed/TestFeedFetching.php b/tests/Feed/TestFeedFetching.php index 8b038eb..d673af7 100644 --- a/tests/Feed/TestFeedFetching.php +++ b/tests/Feed/TestFeedFetching.php @@ -4,9 +4,7 @@ namespace JKingWeb\Arsse; Use Phake; -class TestFeedFetching extends \PHPUnit\Framework\TestCase { - use Test\Tools; - +class TestFeedFetching extends Test\AbstractTest { protected static $host = "http://localhost:8000/"; protected $base = ""; diff --git a/tests/Lang/TestLang.php b/tests/Lang/TestLang.php index 54b94a8..6cb6726 100644 --- a/tests/Lang/TestLang.php +++ b/tests/Lang/TestLang.php @@ -4,8 +4,8 @@ namespace JKingWeb\Arsse; use org\bovigo\vfs\vfsStream; -class TestLang extends \PHPUnit\Framework\TestCase { - use Test\Tools, Test\Lang\Setup; +class TestLang extends Test\AbstractTest { + use Test\Lang\Setup; public $files; public $path; diff --git a/tests/Lang/TestLangErrors.php b/tests/Lang/TestLangErrors.php index 6a09685..966f653 100644 --- a/tests/Lang/TestLangErrors.php +++ b/tests/Lang/TestLangErrors.php @@ -4,8 +4,8 @@ namespace JKingWeb\Arsse; use org\bovigo\vfs\vfsStream; -class TestLangErrors extends \PHPUnit\Framework\TestCase { - use Test\Tools, Test\Lang\Setup; +class TestLangErrors extends Test\AbstractTest { + use Test\Lang\Setup; public $files; public $path; diff --git a/tests/Lang/testLangComplex.php b/tests/Lang/testLangComplex.php index 253d141..d4436fc 100644 --- a/tests/Lang/testLangComplex.php +++ b/tests/Lang/testLangComplex.php @@ -4,8 +4,8 @@ namespace JKingWeb\Arsse; use org\bovigo\vfs\vfsStream; -class TestLangComplex extends \PHPUnit\Framework\TestCase { - use Test\Tools, Test\Lang\Setup; +class TestLangComplex extends Test\AbstractTest { + use Test\Lang\Setup; public $files; public $path; diff --git a/tests/Misc/TestContext.php b/tests/Misc/TestContext.php index 9eb70b2..cebb02c 100644 --- a/tests/Misc/TestContext.php +++ b/tests/Misc/TestContext.php @@ -4,9 +4,7 @@ namespace JKingWeb\Arsse; use JKingWeb\Arsse\Misc\Context; -class TestContext extends \PHPUnit\Framework\TestCase { - use Test\Tools; - +class TestContext extends Test\AbstractTest { function testVerifyInitialState() { $c = new Context; foreach((new \ReflectionObject($c))->getMethods(\ReflectionMethod::IS_PUBLIC) as $m) { diff --git a/tests/REST/NextCloudNews/TestNCNV1_2.php b/tests/REST/NextCloudNews/TestNCNV1_2.php index 03eb714..854f268 100644 --- a/tests/REST/NextCloudNews/TestNCNV1_2.php +++ b/tests/REST/NextCloudNews/TestNCNV1_2.php @@ -8,9 +8,7 @@ use JKingWeb\Arsse\Misc\Context; use Phake; -class TestNCNV1_2 extends \PHPUnit\Framework\TestCase { - use Test\Tools; - +class TestNCNV1_2 extends Test\AbstractTest { protected $h; protected $feeds = [ // expected sample output of a feed list from the database, and the resultant expected transformation by the REST handler 'db' => [ @@ -25,7 +23,7 @@ class TestNCNV1_2 extends \PHPUnit\Framework\TestCase { 'err_count' => 0, 'err_msg' => '', 'order_type' => 0, - 'added' => 1495287354, + 'added' => '2017-05-20 13:35:54', 'title' => 'First example feed', 'unread' => 50048, ], @@ -40,7 +38,7 @@ class TestNCNV1_2 extends \PHPUnit\Framework\TestCase { 'err_count' => 0, 'err_msg' => '', 'order_type' => 2, - 'added' => 1495287354, + 'added' => '2017-05-20 13:35:54', 'title' => 'Second example feed', 'unread' => 23, ], diff --git a/tests/REST/NextCloudNews/TestNCNVersionDiscovery.php b/tests/REST/NextCloudNews/TestNCNVersionDiscovery.php index 4612209..58e5e8d 100644 --- a/tests/REST/NextCloudNews/TestNCNVersionDiscovery.php +++ b/tests/REST/NextCloudNews/TestNCNVersionDiscovery.php @@ -5,9 +5,7 @@ use JKingWeb\Arsse\REST\Request; use JKingWeb\Arsse\REST\Response; -class TestNCNVersionDiscovery extends \PHPUnit\Framework\TestCase { - use Test\Tools; - +class TestNCNVersionDiscovery extends Test\AbstractTest { function setUp() { $this->clearData(); } diff --git a/tests/User/TestAuthorization.php b/tests/User/TestAuthorization.php index 7ababbb..f8e322f 100644 --- a/tests/User/TestAuthorization.php +++ b/tests/User/TestAuthorization.php @@ -4,9 +4,7 @@ namespace JKingWeb\Arsse; use Phake; -class TestAuthorization extends \PHPUnit\Framework\TestCase { - use Test\Tools; - +class TestAuthorization extends Test\AbstractTest { const USERS = [ 'user@example.com' => User\Driver::RIGHTS_NONE, 'user@example.org' => User\Driver::RIGHTS_NONE, diff --git a/tests/User/TestUserInternalDriver.php b/tests/User/TestUserInternalDriver.php index 03d8b3a..b4d441d 100644 --- a/tests/User/TestUserInternalDriver.php +++ b/tests/User/TestUserInternalDriver.php @@ -3,8 +3,8 @@ declare(strict_types=1); namespace JKingWeb\Arsse; -class TestUserInternalDriver extends \PHPUnit\Framework\TestCase { - use Test\Tools, Test\User\CommonTests; +class TestUserInternalDriver extends Test\AbstractTest { + use Test\User\CommonTests; const USER1 = "john.doe@example.com"; const USER2 = "jane.doe@example.com"; diff --git a/tests/User/TestUserMockExternal.php b/tests/User/TestUserMockExternal.php index a399013..6836642 100644 --- a/tests/User/TestUserMockExternal.php +++ b/tests/User/TestUserMockExternal.php @@ -3,8 +3,8 @@ declare(strict_types=1); namespace JKingWeb\Arsse; -class TestUserMockExternal extends \PHPUnit\Framework\TestCase { - use Test\Tools, Test\User\CommonTests; +class TestUserMockExternal extends Test\AbstractTest { + use Test\User\CommonTests; const USER1 = "john.doe@example.com"; const USER2 = "jane.doe@example.com"; diff --git a/tests/User/TestUserMockInternal.php b/tests/User/TestUserMockInternal.php index 1574434..8f8e91b 100644 --- a/tests/User/TestUserMockInternal.php +++ b/tests/User/TestUserMockInternal.php @@ -3,8 +3,8 @@ declare(strict_types=1); namespace JKingWeb\Arsse; -class TestUserMockInternal extends \PHPUnit\Framework\TestCase { - use Test\Tools, Test\User\CommonTests; +class TestUserMockInternal extends Test\AbstractTest { + use Test\User\CommonTests; const USER1 = "john.doe@example.com"; const USER2 = "jane.doe@example.com"; diff --git a/tests/lib/AbstractTest.php b/tests/lib/AbstractTest.php new file mode 100644 index 0000000..b234ee1 --- /dev/null +++ b/tests/lib/AbstractTest.php @@ -0,0 +1,44 @@ +expectException($class); + $this->expectExceptionCode($code); + } else { + // expecting a standard PHP exception + $this->expectException(\Exception::class); + } + } + + function assertTime($exp, $test) { + $exp = $this->dateTransform($exp, "unix"); + $test = $this->dateTransform($test, "unix"); + $this->assertSame($exp, $test); + } + + function clearData(bool $loadLang = true): bool { + $r = new \ReflectionClass(\JKingWeb\Arsse\Data::class); + $props = array_keys($r->getStaticProperties()); + foreach($props as $prop) { + Data::$$prop = null; + } + if($loadLang) { + Data::$l = new \JKingWeb\Arsse\Lang(); + } + return true; + } +} \ No newline at end of file diff --git a/tests/lib/Tools.php b/tests/lib/Tools.php deleted file mode 100644 index 20905f4..0000000 --- a/tests/lib/Tools.php +++ /dev/null @@ -1,39 +0,0 @@ -expectException($class); - $this->expectExceptionCode($code); - } - - function assertTime($exp, $test) { - $exp = $this->dateTransform($exp, "unix"); - $test = $this->dateTransform($test, "unix"); - $this->assertSame($exp, $test); - } - - function clearData(bool $loadLang = true): bool { - $r = new \ReflectionClass(\JKingWeb\Arsse\Data::class); - $props = array_keys($r->getStaticProperties()); - foreach($props as $prop) { - Data::$$prop = null; - } - if($loadLang) { - Data::$l = new \JKingWeb\Arsse\Lang(); - } - return true; - } -} \ No newline at end of file diff --git a/tests/phpunit.xml b/tests/phpunit.xml index 6263443..27b7b20 100644 --- a/tests/phpunit.xml +++ b/tests/phpunit.xml @@ -2,9 +2,9 @@