Browse Source

Take a different tack on shared database tests

Tests for different drivers will have their own files, but all derive
from a common prototype test series where applicable, similar to the
existing arrangement for database function tests. However, the prototype
will reside with other test cases rather than in the library path. The
database function test series will hopefully be moved as well in time.
tags/0.6.0
J. King 6 months ago
parent
commit
aa1b65b5d4

+ 2
- 1
composer.json View File

@@ -42,7 +42,8 @@
42 42
     },
43 43
     "autoload-dev": {
44 44
         "psr-4": {
45
-            "JKingWeb\\Arsse\\Test\\": "tests/lib/"
45
+            "JKingWeb\\Arsse\\Test\\": "tests/lib/",
46
+            "JKingWeb\\Arsse\\TestCase\\": "tests/cases/"
46 47
         }
47 48
     }
48 49
 }

+ 357
- 0
tests/cases/Db/BaseDriver.php View File

@@ -0,0 +1,357 @@
1
+<?php
2
+/** @license MIT
3
+ * Copyright 2017 J. King, Dustin Wilson et al.
4
+ * See LICENSE and AUTHORS files for details */
5
+
6
+declare(strict_types=1);
7
+namespace JKingWeb\Arsse\TestCase\Db;
8
+
9
+use JKingWeb\Arsse\Db\Statement;
10
+use JKingWeb\Arsse\Db\Result;
11
+
12
+
13
+abstract class BaseDriver extends \JKingWeb\Arsse\Test\AbstractTest {
14
+    protected $drv;
15
+    protected $interface;
16
+    protected $create;
17
+    protected $lock;
18
+    protected $setVersion;
19
+    protected $conf = [
20
+        'dbTimeoutExec' => 0.5,
21
+        'dbSQLite3Timeout' => 0,
22
+    ];
23
+    
24
+    public function setUp() {
25
+        $this->setConf($this->conf);
26
+        $this->interface = $this->getDbInterface($this->implementation);
27
+        if (!$this->interface) {
28
+            $this->markTestSkipped("$this->implementation database driver not available");
29
+        }
30
+        $this->drv = $this->getDbDriver($this->implementation);
31
+        $this->exec("DROP TABLE IF EXISTS arsse_test");
32
+        $this->exec("DROP TABLE IF EXISTS arsse_meta");
33
+        $this->exec("CREATE TABLE arsse_meta(key varchar(255) primary key not null, value text)");
34
+        $this->exec("INSERT INTO arsse_meta(key,value) values('schema_version','0')");
35
+    }
36
+
37
+    public function tearDown() {
38
+        unset($this->drv);
39
+        try {
40
+            $this->exec("ROLLBACK");
41
+        } catch(\Throwable $e) {
42
+        }
43
+        $this->exec("DROP TABLE IF EXISTS arsse_meta");
44
+        $this->exec("DROP TABLE IF EXISTS arsse_test");
45
+    }
46
+
47
+    protected function exec(string $q): bool {
48
+        // PDO implementation
49
+        $this->interface->exec($q);
50
+        return true;
51
+    }
52
+
53
+    protected function query(string $q) {
54
+        // PDO implementation
55
+        return $this->interface->query($q)->fetchColumn();
56
+    }
57
+
58
+    # TESTS 
59
+    
60
+    public function testFetchDriverName() {
61
+        $class = get_class($this->drv);
62
+        $this->assertTrue(strlen($class::driverName()) > 0);
63
+    }
64
+
65
+    public function testCheckCharacterSetAcceptability() {
66
+        $this->assertTrue($this->drv->charsetAcceptable());
67
+    }
68
+
69
+    public function testExecAValidStatement() {
70
+        $this->assertTrue($this->drv->exec($this->create));
71
+    }
72
+
73
+    public function testExecAnInvalidStatement() {
74
+        $this->assertException("engineErrorGeneral", "Db");
75
+        $this->drv->exec("And the meek shall inherit the earth...");
76
+    }
77
+
78
+    public function testExecMultipleStatements() {
79
+        $this->assertTrue($this->drv->exec("$this->create; INSERT INTO arsse_test(id) values(2112)"));
80
+        $this->assertEquals(2112, $this->query("SELECT id from arsse_test"));
81
+    }
82
+
83
+    public function testExecTimeout() {
84
+        $this->exec($this->create);
85
+        $this->exec($this->lock);
86
+        $this->assertException("general", "Db", "ExceptionTimeout");
87
+        $this->drv->exec($this->lock);
88
+    }
89
+
90
+    public function testExecConstraintViolation() {
91
+        $this->drv->exec("CREATE TABLE arsse_test(id varchar(255) not null)");
92
+        $this->assertException("constraintViolation", "Db", "ExceptionInput");
93
+        $this->drv->exec("INSERT INTO arsse_test default values");
94
+    }
95
+
96
+    public function testExecTypeViolation() {
97
+        $this->drv->exec($this->create);
98
+        $this->assertException("typeViolation", "Db", "ExceptionInput");
99
+        $this->drv->exec("INSERT INTO arsse_test(id) values('ook')");
100
+    }
101
+
102
+    public function testMakeAValidQuery() {
103
+        $this->assertInstanceOf(Result::class, $this->drv->query("SELECT 1"));
104
+    }
105
+
106
+    public function testMakeAnInvalidQuery() {
107
+        $this->assertException("engineErrorGeneral", "Db");
108
+        $this->drv->query("Apollo was astonished; Dionysus thought me mad");
109
+    }
110
+
111
+    public function testQueryTimeout() {
112
+        $this->exec($this->create);
113
+        $this->exec($this->lock);
114
+        $this->assertException("general", "Db", "ExceptionTimeout");
115
+        $this->drv->exec($this->lock);
116
+    }
117
+
118
+    public function testQueryConstraintViolation() {
119
+        $this->drv->exec("CREATE TABLE arsse_test(id integer not null)");
120
+        $this->assertException("constraintViolation", "Db", "ExceptionInput");
121
+        $this->drv->query("INSERT INTO arsse_test default values");
122
+    }
123
+
124
+    public function testQueryTypeViolation() {
125
+        $this->drv->exec($this->create);
126
+        $this->assertException("typeViolation", "Db", "ExceptionInput");
127
+        $this->drv->query("INSERT INTO arsse_test(id) values('ook')");
128
+    }
129
+
130
+    public function testPrepareAValidQuery() {
131
+        $s = $this->drv->prepare("SELECT ?, ?", "int", "int");
132
+        $this->assertInstanceOf(Statement::class, $s);
133
+    }
134
+
135
+    public function testPrepareAnInvalidQuery() {
136
+        $this->assertException("engineErrorGeneral", "Db");
137
+        $s = $this->drv->prepare("This is an invalid query", "int", "int")->run();
138
+    }
139
+
140
+    public function testCreateASavepoint() {
141
+        $this->assertEquals(1, $this->drv->savepointCreate());
142
+        $this->assertEquals(2, $this->drv->savepointCreate());
143
+        $this->assertEquals(3, $this->drv->savepointCreate());
144
+    }
145
+
146
+    public function testReleaseASavepoint() {
147
+        $this->assertEquals(1, $this->drv->savepointCreate());
148
+        $this->assertEquals(true, $this->drv->savepointRelease());
149
+        $this->assertException("savepointInvalid", "Db");
150
+        $this->drv->savepointRelease();
151
+    }
152
+
153
+    public function testUndoASavepoint() {
154
+        $this->assertEquals(1, $this->drv->savepointCreate());
155
+        $this->assertEquals(true, $this->drv->savepointUndo());
156
+        $this->assertException("savepointInvalid", "Db");
157
+        $this->drv->savepointUndo();
158
+    }
159
+
160
+    public function testManipulateSavepoints() {
161
+        $this->assertEquals(1, $this->drv->savepointCreate());
162
+        $this->assertEquals(2, $this->drv->savepointCreate());
163
+        $this->assertEquals(3, $this->drv->savepointCreate());
164
+        $this->assertEquals(4, $this->drv->savepointCreate());
165
+        $this->assertEquals(5, $this->drv->savepointCreate());
166
+        $this->assertTrue($this->drv->savepointUndo(3));
167
+        $this->assertFalse($this->drv->savepointRelease(4));
168
+        $this->assertEquals(6, $this->drv->savepointCreate());
169
+        $this->assertFalse($this->drv->savepointRelease(5));
170
+        $this->assertTrue($this->drv->savepointRelease(6));
171
+        $this->assertEquals(3, $this->drv->savepointCreate());
172
+        $this->assertTrue($this->drv->savepointRelease(2));
173
+        $this->assertException("savepointStale", "Db");
174
+        $this->drv->savepointRelease(2);
175
+    }
176
+
177
+    public function testManipulateSavepointsSomeMore() {
178
+        $this->assertEquals(1, $this->drv->savepointCreate());
179
+        $this->assertEquals(2, $this->drv->savepointCreate());
180
+        $this->assertEquals(3, $this->drv->savepointCreate());
181
+        $this->assertEquals(4, $this->drv->savepointCreate());
182
+        $this->assertTrue($this->drv->savepointRelease(2));
183
+        $this->assertFalse($this->drv->savepointUndo(3));
184
+        $this->assertException("savepointStale", "Db");
185
+        $this->drv->savepointUndo(2);
186
+    }
187
+
188
+    public function testBeginATransaction() {
189
+        $select = "SELECT count(*) FROM arsse_test";
190
+        $insert = "INSERT INTO arsse_test default values";
191
+        $this->drv->exec($this->create);
192
+        $tr = $this->drv->begin();
193
+        $this->drv->query($insert);
194
+        $this->assertEquals(1, $this->drv->query($select)->getValue());
195
+        $this->assertEquals(0, $this->query($select));
196
+        $this->drv->query($insert);
197
+        $this->assertEquals(2, $this->drv->query($select)->getValue());
198
+        $this->assertEquals(0, $this->query($select));
199
+    }
200
+
201
+    public function testCommitATransaction() {
202
+        $select = "SELECT count(*) FROM arsse_test";
203
+        $insert = "INSERT INTO arsse_test default values";
204
+        $this->drv->exec($this->create);
205
+        $tr = $this->drv->begin();
206
+        $this->drv->query($insert);
207
+        $this->assertEquals(1, $this->drv->query($select)->getValue());
208
+        $this->assertEquals(0, $this->query($select));
209
+        $tr->commit();
210
+        $this->assertEquals(1, $this->drv->query($select)->getValue());
211
+        $this->assertEquals(1, $this->query($select));
212
+    }
213
+
214
+    public function testRollbackATransaction() {
215
+        $select = "SELECT count(*) FROM arsse_test";
216
+        $insert = "INSERT INTO arsse_test default values";
217
+        $this->drv->exec($this->create);
218
+        $tr = $this->drv->begin();
219
+        $this->drv->query($insert);
220
+        $this->assertEquals(1, $this->drv->query($select)->getValue());
221
+        $this->assertEquals(0, $this->query($select));
222
+        $tr->rollback();
223
+        $this->assertEquals(0, $this->drv->query($select)->getValue());
224
+        $this->assertEquals(0, $this->query($select));
225
+    }
226
+
227
+    public function testBeginChainedTransactions() {
228
+        $select = "SELECT count(*) FROM arsse_test";
229
+        $insert = "INSERT INTO arsse_test default values";
230
+        $this->drv->exec($this->create);
231
+        $tr1 = $this->drv->begin();
232
+        $this->drv->query($insert);
233
+        $this->assertEquals(1, $this->drv->query($select)->getValue());
234
+        $this->assertEquals(0, $this->query($select));
235
+        $tr2 = $this->drv->begin();
236
+        $this->drv->query($insert);
237
+        $this->assertEquals(2, $this->drv->query($select)->getValue());
238
+        $this->assertEquals(0, $this->query($select));
239
+    }
240
+
241
+    public function testCommitChainedTransactions() {
242
+        $select = "SELECT count(*) FROM arsse_test";
243
+        $insert = "INSERT INTO arsse_test default values";
244
+        $this->drv->exec($this->create);
245
+        $tr1 = $this->drv->begin();
246
+        $this->drv->query($insert);
247
+        $this->assertEquals(1, $this->drv->query($select)->getValue());
248
+        $this->assertEquals(0, $this->query($select));
249
+        $tr2 = $this->drv->begin();
250
+        $this->drv->query($insert);
251
+        $this->assertEquals(2, $this->drv->query($select)->getValue());
252
+        $this->assertEquals(0, $this->query($select));
253
+        $tr2->commit();
254
+        $this->assertEquals(0, $this->query($select));
255
+        $tr1->commit();
256
+        $this->assertEquals(2, $this->query($select));
257
+    }
258
+
259
+    public function testCommitChainedTransactionsOutOfOrder() {
260
+        $select = "SELECT count(*) FROM arsse_test";
261
+        $insert = "INSERT INTO arsse_test default values";
262
+        $this->drv->exec($this->create);
263
+        $tr1 = $this->drv->begin();
264
+        $this->drv->query($insert);
265
+        $this->assertEquals(1, $this->drv->query($select)->getValue());
266
+        $this->assertEquals(0, $this->query($select));
267
+        $tr2 = $this->drv->begin();
268
+        $this->drv->query($insert);
269
+        $this->assertEquals(2, $this->drv->query($select)->getValue());
270
+        $this->assertEquals(0, $this->query($select));
271
+        $tr1->commit();
272
+        $this->assertEquals(2, $this->query($select));
273
+        $tr2->commit();
274
+    }
275
+
276
+    public function testRollbackChainedTransactions() {
277
+        $select = "SELECT count(*) FROM arsse_test";
278
+        $insert = "INSERT INTO arsse_test default values";
279
+        $this->drv->exec($this->create);
280
+        $tr1 = $this->drv->begin();
281
+        $this->drv->query($insert);
282
+        $this->assertEquals(1, $this->drv->query($select)->getValue());
283
+        $this->assertEquals(0, $this->query($select));
284
+        $tr2 = $this->drv->begin();
285
+        $this->drv->query($insert);
286
+        $this->assertEquals(2, $this->drv->query($select)->getValue());
287
+        $this->assertEquals(0, $this->query($select));
288
+        $tr2->rollback();
289
+        $this->assertEquals(1, $this->drv->query($select)->getValue());
290
+        $this->assertEquals(0, $this->query($select));
291
+        $tr1->rollback();
292
+        $this->assertEquals(0, $this->drv->query($select)->getValue());
293
+        $this->assertEquals(0, $this->query($select));
294
+    }
295
+
296
+    public function testRollbackChainedTransactionsOutOfOrder() {
297
+        $select = "SELECT count(*) FROM arsse_test";
298
+        $insert = "INSERT INTO arsse_test default values";
299
+        $this->drv->exec($this->create);
300
+        $tr1 = $this->drv->begin();
301
+        $this->drv->query($insert);
302
+        $this->assertEquals(1, $this->drv->query($select)->getValue());
303
+        $this->assertEquals(0, $this->query($select));
304
+        $tr2 = $this->drv->begin();
305
+        $this->drv->query($insert);
306
+        $this->assertEquals(2, $this->drv->query($select)->getValue());
307
+        $this->assertEquals(0, $this->query($select));
308
+        $tr1->rollback();
309
+        $this->assertEquals(0, $this->drv->query($select)->getValue());
310
+        $this->assertEquals(0, $this->query($select));
311
+        $tr2->rollback();
312
+        $this->assertEquals(0, $this->drv->query($select)->getValue());
313
+        $this->assertEquals(0, $this->query($select));
314
+    }
315
+
316
+    public function testPartiallyRollbackChainedTransactions() {
317
+        $select = "SELECT count(*) FROM arsse_test";
318
+        $insert = "INSERT INTO arsse_test default values";
319
+        $this->drv->exec($this->create);
320
+        $tr1 = $this->drv->begin();
321
+        $this->drv->query($insert);
322
+        $this->assertEquals(1, $this->drv->query($select)->getValue());
323
+        $this->assertEquals(0, $this->query($select));
324
+        $tr2 = $this->drv->begin();
325
+        $this->drv->query($insert);
326
+        $this->assertEquals(2, $this->drv->query($select)->getValue());
327
+        $this->assertEquals(0, $this->query($select));
328
+        $tr2->rollback();
329
+        $this->assertEquals(1, $this->drv->query($select)->getValue());
330
+        $this->assertEquals(0, $this->query($select));
331
+        $tr1->commit();
332
+        $this->assertEquals(1, $this->drv->query($select)->getValue());
333
+        $this->assertEquals(1, $this->query($select));
334
+    }
335
+
336
+    public function testFetchSchemaVersion() {
337
+        $this->assertSame(0, $this->drv->schemaVersion());
338
+        $this->drv->exec(str_replace("#", "1", $this->setVersion));
339
+        $this->assertSame(1, $this->drv->schemaVersion());
340
+        $this->drv->exec(str_replace("#", "2", $this->setVersion));
341
+        $this->assertSame(2, $this->drv->schemaVersion());
342
+    }
343
+
344
+    public function testLockTheDatabase() {
345
+        $this->drv->savepointCreate(true);
346
+        $this->assertException();
347
+        $this->exec($this->create);
348
+    }
349
+
350
+    public function testUnlockTheDatabase() {
351
+        $this->drv->savepointCreate(true);
352
+        $this->drv->savepointRelease();
353
+        $this->drv->savepointCreate(true);
354
+        $this->drv->savepointUndo();
355
+        $this->assertTrue($this->exec($this->create));
356
+    }
357
+}

+ 76
- 318
tests/cases/Db/SQLite3/TestDriver.php View File

@@ -6,338 +6,96 @@
6 6
 declare(strict_types=1);
7 7
 namespace JKingWeb\Arsse\TestCase\Db\SQLite3;
8 8
 
9
-use JKingWeb\Arsse\Arsse;
10
-use JKingWeb\Arsse\Conf;
11
-use JKingWeb\Arsse\Database;
12
-use JKingWeb\Arsse\Db\SQLite3\Driver;
13
-use JKingWeb\Arsse\Db\Result;
14
-use JKingWeb\Arsse\Db\Statement;
15
-
16 9
 /**
17 10
  * @covers \JKingWeb\Arsse\Db\SQLite3\Driver<extended>
18 11
  * @covers \JKingWeb\Arsse\Db\SQLite3\ExceptionBuilder */
19
-class TestDriver extends \JKingWeb\Arsse\Test\AbstractTest {
20
-    protected $data;
21
-    protected $drv;
22
-    protected $ch;
23
-
24
-    public function setUp() {
25
-        if (!Driver::requirementsMet()) {
26
-            $this->markTestSkipped("SQLite extension not loaded");
27
-        }
28
-        $this->clearData();
29
-        $this->setConf([
30
-            'dbDriver' => Driver::class,
31
-            'dbSQLite3Timeout' => 0,
32
-            'dbSQLite3File' => tempnam(sys_get_temp_dir(), 'ook'),
33
-        ]);
34
-        $this->drv = new Driver();
35
-        $this->ch = new \SQLite3(Arsse::$conf->dbSQLite3File);
36
-        $this->ch->enableExceptions(true);
37
-    }
38
-
39
-    public function tearDown() {
40
-        unset($this->drv);
41
-        unset($this->ch);
42
-        if (isset(Arsse::$conf)) {
43
-            unlink(Arsse::$conf->dbSQLite3File);
44
-        }
45
-        $this->clearData();
46
-    }
47
-
48
-    public function testFetchDriverName() {
49
-        $class = Arsse::$conf->dbDriver;
50
-        $this->assertTrue(strlen($class::driverName()) > 0);
51
-    }
52
-
53
-    public function testCheckCharacterSetAcceptability() {
54
-        $this->assertTrue($this->drv->charsetAcceptable());
55
-    }
56
-
57
-    public function testExecAValidStatement() {
58
-        $this->assertTrue($this->drv->exec("CREATE TABLE test(id integer primary key)"));
59
-    }
60
-
61
-    public function testExecAnInvalidStatement() {
62
-        $this->assertException("engineErrorGeneral", "Db");
63
-        $this->drv->exec("And the meek shall inherit the earth...");
64
-    }
65
-
66
-    public function testExecMultipleStatements() {
67
-        $this->assertTrue($this->drv->exec("CREATE TABLE test(id integer primary key); INSERT INTO test(id) values(2112)"));
68
-        $this->assertEquals(2112, $this->ch->querySingle("SELECT id from test"));
69
-    }
70
-
71
-    public function testExecTimeout() {
72
-        $this->ch->exec("BEGIN EXCLUSIVE TRANSACTION");
73
-        $this->assertException("general", "Db", "ExceptionTimeout");
74
-        $this->drv->exec("CREATE TABLE test(id integer primary key)");
75
-    }
76
-
77
-    public function testExecConstraintViolation() {
78
-        $this->drv->exec("CREATE TABLE test(id integer not null)");
79
-        $this->assertException("constraintViolation", "Db", "ExceptionInput");
80
-        $this->drv->exec("INSERT INTO test(id) values(null)");
81
-    }
12
+class TestDriver extends \JKingWeb\Arsse\TestCase\Db\BaseDriver {
13
+    protected $implementation = "SQLite 3";
14
+    protected $create = "CREATE TABLE arsse_test(id integer primary key)";
15
+    protected $lock = "BEGIN EXCLUSIVE TRANSACTION";
16
+    protected $setVersion = "PRAGMA user_version=#";
17
+    protected static $file;
82 18
 
83
-    public function testExecTypeViolation() {
84
-        $this->drv->exec("CREATE TABLE test(id integer primary key)");
85
-        $this->assertException("typeViolation", "Db", "ExceptionInput");
86
-        $this->drv->exec("INSERT INTO test(id) values('ook')");
19
+    public static function setUpBeforeClass() {
20
+        self::$file = tempnam(sys_get_temp_dir(), 'ook');
87 21
     }
88 22
 
89
-    public function testMakeAValidQuery() {
90
-        $this->assertInstanceOf(Result::class, $this->drv->query("SELECT 1"));
23
+    public static function tearDownAfterClass() {
24
+        @unlink(self::$file);
25
+        self::$file = null;
91 26
     }
92
-
93
-    public function testMakeAnInvalidQuery() {
94
-        $this->assertException("engineErrorGeneral", "Db");
95
-        $this->drv->query("Apollo was astonished; Dionysus thought me mad");
96
-    }
97
-
98
-    public function testQueryTimeout() {
99
-        $this->ch->exec("BEGIN EXCLUSIVE TRANSACTION");
100
-        $this->assertException("general", "Db", "ExceptionTimeout");
101
-        $this->drv->query("CREATE TABLE test(id integer primary key)");
102
-    }
103
-
104
-    public function testQueryConstraintViolation() {
105
-        $this->drv->exec("CREATE TABLE test(id integer not null)");
106
-        $this->assertException("constraintViolation", "Db", "ExceptionInput");
107
-        $this->drv->query("INSERT INTO test(id) values(null)");
108
-    }
109
-
110
-    public function testQueryTypeViolation() {
111
-        $this->drv->exec("CREATE TABLE test(id integer primary key)");
112
-        $this->assertException("typeViolation", "Db", "ExceptionInput");
113
-        $this->drv->query("INSERT INTO test(id) values('ook')");
114
-    }
115
-
116
-    public function testPrepareAValidQuery() {
117
-        $s = $this->drv->prepare("SELECT ?, ?", "int", "int");
118
-        $this->assertInstanceOf(Statement::class, $s);
119
-    }
120
-
121
-    public function testPrepareAnInvalidQuery() {
122
-        $this->assertException("engineErrorGeneral", "Db");
123
-        $s = $this->drv->prepare("This is an invalid query", "int", "int");
124
-    }
125
-
126
-    public function testCreateASavepoint() {
127
-        $this->assertEquals(1, $this->drv->savepointCreate());
128
-        $this->assertEquals(2, $this->drv->savepointCreate());
129
-        $this->assertEquals(3, $this->drv->savepointCreate());
130
-    }
131
-
132
-    public function testReleaseASavepoint() {
133
-        $this->assertEquals(1, $this->drv->savepointCreate());
134
-        $this->assertEquals(true, $this->drv->savepointRelease());
135
-        $this->assertException("savepointInvalid", "Db");
136
-        $this->drv->savepointRelease();
137
-    }
138
-
139
-    public function testUndoASavepoint() {
140
-        $this->assertEquals(1, $this->drv->savepointCreate());
141
-        $this->assertEquals(true, $this->drv->savepointUndo());
142
-        $this->assertException("savepointInvalid", "Db");
143
-        $this->drv->savepointUndo();
144
-    }
145
-
146
-    public function testManipulateSavepoints() {
147
-        $this->assertEquals(1, $this->drv->savepointCreate());
148
-        $this->assertEquals(2, $this->drv->savepointCreate());
149
-        $this->assertEquals(3, $this->drv->savepointCreate());
150
-        $this->assertEquals(4, $this->drv->savepointCreate());
151
-        $this->assertEquals(5, $this->drv->savepointCreate());
152
-        $this->assertTrue($this->drv->savepointUndo(3));
153
-        $this->assertFalse($this->drv->savepointRelease(4));
154
-        $this->assertEquals(6, $this->drv->savepointCreate());
155
-        $this->assertFalse($this->drv->savepointRelease(5));
156
-        $this->assertTrue($this->drv->savepointRelease(6));
157
-        $this->assertEquals(3, $this->drv->savepointCreate());
158
-        $this->assertTrue($this->drv->savepointRelease(2));
159
-        $this->assertException("savepointStale", "Db");
160
-        $this->drv->savepointRelease(2);
161
-    }
162
-
163
-    public function testManipulateSavepointsSomeMore() {
164
-        $this->assertEquals(1, $this->drv->savepointCreate());
165
-        $this->assertEquals(2, $this->drv->savepointCreate());
166
-        $this->assertEquals(3, $this->drv->savepointCreate());
167
-        $this->assertEquals(4, $this->drv->savepointCreate());
168
-        $this->assertTrue($this->drv->savepointRelease(2));
169
-        $this->assertFalse($this->drv->savepointUndo(3));
170
-        $this->assertException("savepointStale", "Db");
171
-        $this->drv->savepointUndo(2);
172
-    }
173
-
174
-    public function testBeginATransaction() {
175
-        $select = "SELECT count(*) FROM test";
176
-        $insert = "INSERT INTO test(id) values(null)";
177
-        $this->drv->exec("CREATE TABLE test(id integer primary key)");
178
-        $tr = $this->drv->begin();
179
-        $this->drv->query($insert);
180
-        $this->assertEquals(1, $this->drv->query($select)->getValue());
181
-        $this->assertEquals(0, $this->ch->querySingle($select));
182
-        $this->drv->query($insert);
183
-        $this->assertEquals(2, $this->drv->query($select)->getValue());
184
-        $this->assertEquals(0, $this->ch->querySingle($select));
185
-    }
186
-
187
-    public function testCommitATransaction() {
188
-        $select = "SELECT count(*) FROM test";
189
-        $insert = "INSERT INTO test(id) values(null)";
190
-        $this->drv->exec("CREATE TABLE test(id integer primary key)");
191
-        $tr = $this->drv->begin();
192
-        $this->drv->query($insert);
193
-        $this->assertEquals(1, $this->drv->query($select)->getValue());
194
-        $this->assertEquals(0, $this->ch->querySingle($select));
195
-        $tr->commit();
196
-        $this->assertEquals(1, $this->drv->query($select)->getValue());
197
-        $this->assertEquals(1, $this->ch->querySingle($select));
198
-    }
199
-
200
-    public function testRollbackATransaction() {
201
-        $select = "SELECT count(*) FROM test";
202
-        $insert = "INSERT INTO test(id) values(null)";
203
-        $this->drv->exec("CREATE TABLE test(id integer primary key)");
204
-        $tr = $this->drv->begin();
205
-        $this->drv->query($insert);
206
-        $this->assertEquals(1, $this->drv->query($select)->getValue());
207
-        $this->assertEquals(0, $this->ch->querySingle($select));
208
-        $tr->rollback();
209
-        $this->assertEquals(0, $this->drv->query($select)->getValue());
210
-        $this->assertEquals(0, $this->ch->querySingle($select));
211
-    }
212
-
213
-    public function testBeginChainedTransactions() {
214
-        $select = "SELECT count(*) FROM test";
215
-        $insert = "INSERT INTO test(id) values(null)";
216
-        $this->drv->exec("CREATE TABLE test(id integer primary key)");
217
-        $tr1 = $this->drv->begin();
218
-        $this->drv->query($insert);
219
-        $this->assertEquals(1, $this->drv->query($select)->getValue());
220
-        $this->assertEquals(0, $this->ch->querySingle($select));
221
-        $tr2 = $this->drv->begin();
222
-        $this->drv->query($insert);
223
-        $this->assertEquals(2, $this->drv->query($select)->getValue());
224
-        $this->assertEquals(0, $this->ch->querySingle($select));
225
-    }
226
-
227
-    public function testCommitChainedTransactions() {
228
-        $select = "SELECT count(*) FROM test";
229
-        $insert = "INSERT INTO test(id) values(null)";
230
-        $this->drv->exec("CREATE TABLE test(id integer primary key)");
231
-        $tr1 = $this->drv->begin();
232
-        $this->drv->query($insert);
233
-        $this->assertEquals(1, $this->drv->query($select)->getValue());
234
-        $this->assertEquals(0, $this->ch->querySingle($select));
235
-        $tr2 = $this->drv->begin();
236
-        $this->drv->query($insert);
237
-        $this->assertEquals(2, $this->drv->query($select)->getValue());
238
-        $this->assertEquals(0, $this->ch->querySingle($select));
239
-        $tr2->commit();
240
-        $this->assertEquals(0, $this->ch->querySingle($select));
241
-        $tr1->commit();
242
-        $this->assertEquals(2, $this->ch->querySingle($select));
243
-    }
244
-
245
-    public function testCommitChainedTransactionsOutOfOrder() {
246
-        $select = "SELECT count(*) FROM test";
247
-        $insert = "INSERT INTO test(id) values(null)";
248
-        $this->drv->exec("CREATE TABLE test(id integer primary key)");
249
-        $tr1 = $this->drv->begin();
250
-        $this->drv->query($insert);
251
-        $this->assertEquals(1, $this->drv->query($select)->getValue());
252
-        $this->assertEquals(0, $this->ch->querySingle($select));
253
-        $tr2 = $this->drv->begin();
254
-        $this->drv->query($insert);
255
-        $this->assertEquals(2, $this->drv->query($select)->getValue());
256
-        $this->assertEquals(0, $this->ch->querySingle($select));
257
-        $tr1->commit();
258
-        $this->assertEquals(2, $this->ch->querySingle($select));
259
-        $tr2->commit();
260
-    }
261
-
262
-    public function testRollbackChainedTransactions() {
263
-        $select = "SELECT count(*) FROM test";
264
-        $insert = "INSERT INTO test(id) values(null)";
265
-        $this->drv->exec("CREATE TABLE test(id integer primary key)");
266
-        $tr1 = $this->drv->begin();
267
-        $this->drv->query($insert);
268
-        $this->assertEquals(1, $this->drv->query($select)->getValue());
269
-        $this->assertEquals(0, $this->ch->querySingle($select));
270
-        $tr2 = $this->drv->begin();
271
-        $this->drv->query($insert);
272
-        $this->assertEquals(2, $this->drv->query($select)->getValue());
273
-        $this->assertEquals(0, $this->ch->querySingle($select));
274
-        $tr2->rollback();
275
-        $this->assertEquals(1, $this->drv->query($select)->getValue());
276
-        $this->assertEquals(0, $this->ch->querySingle($select));
277
-        $tr1->rollback();
278
-        $this->assertEquals(0, $this->drv->query($select)->getValue());
279
-        $this->assertEquals(0, $this->ch->querySingle($select));
280
-    }
281
-
282
-    public function testRollbackChainedTransactionsOutOfOrder() {
283
-        $select = "SELECT count(*) FROM test";
284
-        $insert = "INSERT INTO test(id) values(null)";
285
-        $this->drv->exec("CREATE TABLE test(id integer primary key)");
286
-        $tr1 = $this->drv->begin();
287
-        $this->drv->query($insert);
288
-        $this->assertEquals(1, $this->drv->query($select)->getValue());
289
-        $this->assertEquals(0, $this->ch->querySingle($select));
290
-        $tr2 = $this->drv->begin();
291
-        $this->drv->query($insert);
292
-        $this->assertEquals(2, $this->drv->query($select)->getValue());
293
-        $this->assertEquals(0, $this->ch->querySingle($select));
294
-        $tr1->rollback();
295
-        $this->assertEquals(0, $this->drv->query($select)->getValue());
296
-        $this->assertEquals(0, $this->ch->querySingle($select));
297
-        $tr2->rollback();
298
-        $this->assertEquals(0, $this->drv->query($select)->getValue());
299
-        $this->assertEquals(0, $this->ch->querySingle($select));
27
+    
28
+    public function setUp() {
29
+        $this->conf['dbSQLite3File'] = self::$file;
30
+        parent::setUp();
31
+        $this->exec("PRAGMA user_version=0");
300 32
     }
301 33
 
302
-    public function testPartiallyRollbackChainedTransactions() {
303
-        $select = "SELECT count(*) FROM test";
304
-        $insert = "INSERT INTO test(id) values(null)";
305
-        $this->drv->exec("CREATE TABLE test(id integer primary key)");
306
-        $tr1 = $this->drv->begin();
307
-        $this->drv->query($insert);
308
-        $this->assertEquals(1, $this->drv->query($select)->getValue());
309
-        $this->assertEquals(0, $this->ch->querySingle($select));
310
-        $tr2 = $this->drv->begin();
311
-        $this->drv->query($insert);
312
-        $this->assertEquals(2, $this->drv->query($select)->getValue());
313
-        $this->assertEquals(0, $this->ch->querySingle($select));
314
-        $tr2->rollback();
315
-        $this->assertEquals(1, $this->drv->query($select)->getValue());
316
-        $this->assertEquals(0, $this->ch->querySingle($select));
317
-        $tr1->commit();
318
-        $this->assertEquals(1, $this->drv->query($select)->getValue());
319
-        $this->assertEquals(1, $this->ch->querySingle($select));
34
+    public function tearDown() {
35
+        parent::tearDown();
36
+        $this->exec("PRAGMA user_version=0");
37
+        $this->interface->close();
38
+        unset($this->interface);
320 39
     }
321 40
 
322
-    public function testFetchSchemaVersion() {
323
-        $this->assertSame(0, $this->drv->schemaVersion());
324
-        $this->drv->exec("PRAGMA user_version=1");
325
-        $this->assertSame(1, $this->drv->schemaVersion());
326
-        $this->drv->exec("PRAGMA user_version=2");
327
-        $this->assertSame(2, $this->drv->schemaVersion());
41
+    protected function exec(string $q): bool {
42
+        $this->interface->exec($q);
43
+        return true;
328 44
     }
329 45
 
330
-    public function testLockTheDatabase() {
331
-        $this->drv->savepointCreate(true);
332
-        $this->assertException();
333
-        $this->ch->exec("CREATE TABLE test(id integer primary key)");
46
+    protected function query(string $q) {
47
+        return $this->interface->querySingle($q);
334 48
     }
335 49
 
336
-    public function testUnlockTheDatabase() {
337
-        $this->drv->savepointCreate(true);
338
-        $this->drv->savepointRelease();
339
-        $this->drv->savepointCreate(true);
340
-        $this->drv->savepointUndo();
341
-        $this->assertSame(true, $this->ch->exec("CREATE TABLE test(id integer primary key)"));
50
+    public function provideDrivers() {
51
+        $this->clearData();
52
+        $this->setConf([
53
+            'dbTimeoutExec' => 0.5,
54
+            'dbSQLite3Timeout' => 0,
55
+            'dbSQLite3File' => tempnam(sys_get_temp_dir(), 'ook'),
56
+        ]);
57
+        $i = $this->provideDbInterfaces();
58
+        $d = $this->provideDbDrivers();
59
+        $pdoExec = function (string $q) {
60
+            $this->interface->exec($q);
61
+            return true;
62
+        };
63
+        $pdoQuery = function (string $q) {
64
+            return $this->interface->query($q)->fetchColumn();
65
+        };
66
+        return [
67
+            'SQLite 3' => [
68
+                $i['SQLite 3']['interface'], 
69
+                $d['SQLite 3'], 
70
+                "CREATE TABLE arsse_test(id integer primary key)", 
71
+                "BEGIN EXCLUSIVE TRANSACTION",
72
+                "PRAGMA user_version=#",
73
+                function (string $q) {
74
+                    $this->interface->exec($q);
75
+                    return true;
76
+                },
77
+                function (string $q) {
78
+                    return $this->interface->querySingle($q);
79
+                },
80
+            ],
81
+            'PDO SQLite 3' => [
82
+                $i['PDO SQLite 3']['interface'], 
83
+                $d['PDO SQLite 3'], 
84
+                "CREATE TABLE arsse_test(id integer primary key)", 
85
+                "BEGIN EXCLUSIVE TRANSACTION",
86
+                "PRAGMA user_version=#",
87
+                $pdoExec,
88
+                $pdoQuery,
89
+            ],
90
+            'PDO PostgreSQL' => [
91
+                $i['PDO PostgreSQL']['interface'], 
92
+                $d['PDO PostgreSQL'], 
93
+                "CREATE TABLE arsse_test(id bigserial primary key)", 
94
+                "BEGIN; LOCK TABLE arsse_test IN EXCLUSIVE MODE NOWAIT",
95
+                "UPDATE arsse_meta set value = '#' where key = 'schema_version'",
96
+                $pdoExec,
97
+                $pdoQuery,
98
+            ],
99
+        ];
342 100
     }
343 101
 }

+ 20
- 324
tests/cases/Db/SQLite3PDO/TestDriver.php View File

@@ -6,339 +6,35 @@
6 6
 declare(strict_types=1);
7 7
 namespace JKingWeb\Arsse\TestCase\Db\SQLite3PDO;
8 8
 
9
-use JKingWeb\Arsse\Arsse;
10
-use JKingWeb\Arsse\Conf;
11
-use JKingWeb\Arsse\Database;
12
-use JKingWeb\Arsse\Db\SQLite3\PDODriver;
13
-use JKingWeb\Arsse\Db\Result;
14
-use JKingWeb\Arsse\Db\Statement;
15
-
16 9
 /**
17 10
  * @covers \JKingWeb\Arsse\Db\SQLite3\PDODriver<extended>
18 11
  * @covers \JKingWeb\Arsse\Db\PDODriver
19 12
  * @covers \JKingWeb\Arsse\Db\PDOError */
20
-class TestDriver extends \JKingWeb\Arsse\Test\AbstractTest {
21
-    protected $data;
22
-    protected $drv;
23
-    protected $ch;
24
-
25
-    public function setUp() {
26
-        if (!PDODriver::requirementsMet()) {
27
-            $this->markTestSkipped("PDO-SQLite extension not loaded");
28
-        }
29
-        $this->clearData();
30
-        $this->setConf([
31
-            'dbDriver' => PDODriver::class,
32
-            'dbSQLite3Timeout' => 0,
33
-            'dbSQLite3File' => tempnam(sys_get_temp_dir(), 'ook'),
34
-        ]);
35
-        $this->drv = new PDODriver();
36
-        $this->ch = new \PDO("sqlite:".Arsse::$conf->dbSQLite3File, "", "", [\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION]);
37
-    }
38
-
39
-    public function tearDown() {
40
-        unset($this->drv);
41
-        unset($this->ch);
42
-        if (isset(Arsse::$conf)) {
43
-            unlink(Arsse::$conf->dbSQLite3File);
44
-        }
45
-        $this->clearData();
46
-    }
47
-
48
-    public function testFetchDriverName() {
49
-        $class = Arsse::$conf->dbDriver;
50
-        $this->assertTrue(strlen($class::driverName()) > 0);
51
-    }
52
-
53
-    public function testCheckCharacterSetAcceptability() {
54
-        $this->assertTrue($this->drv->charsetAcceptable());
55
-    }
56
-
57
-    public function testExecAValidStatement() {
58
-        $this->assertTrue($this->drv->exec("CREATE TABLE test(id integer primary key)"));
59
-    }
60
-
61
-    public function testExecAnInvalidStatement() {
62
-        $this->assertException("engineErrorGeneral", "Db");
63
-        $this->drv->exec("And the meek shall inherit the earth...");
64
-    }
65
-
66
-    public function testExecMultipleStatements() {
67
-        $this->assertTrue($this->drv->exec("CREATE TABLE test(id integer primary key); INSERT INTO test(id) values(2112)"));
68
-        $this->assertEquals(2112, $this->ch->query("SELECT id from test")->fetchColumn());
69
-    }
70
-
71
-    public function testExecTimeout() {
72
-        $this->ch->exec("BEGIN EXCLUSIVE TRANSACTION");
73
-        $this->assertException("general", "Db", "ExceptionTimeout");
74
-        $this->drv->exec("CREATE TABLE test(id integer primary key)");
75
-    }
76
-
77
-    public function testExecConstraintViolation() {
78
-        $this->drv->exec("CREATE TABLE test(id integer not null)");
79
-        $this->assertException("constraintViolation", "Db", "ExceptionInput");
80
-        $this->drv->exec("INSERT INTO test(id) values(null)");
81
-    }
82
-
83
-    public function testExecTypeViolation() {
84
-        $this->drv->exec("CREATE TABLE test(id integer primary key)");
85
-        $this->assertException("typeViolation", "Db", "ExceptionInput");
86
-        $this->drv->exec("INSERT INTO test(id) values('ook')");
87
-    }
88
-
89
-    public function testMakeAValidQuery() {
90
-        $this->assertInstanceOf(Result::class, $this->drv->query("SELECT 1"));
91
-    }
92
-
93
-    public function testMakeAnInvalidQuery() {
94
-        $this->assertException("engineErrorGeneral", "Db");
95
-        $this->drv->query("Apollo was astonished; Dionysus thought me mad");
96
-    }
97
-
98
-    public function testQueryTimeout() {
99
-        $this->ch->exec("BEGIN EXCLUSIVE TRANSACTION");
100
-        $this->assertException("general", "Db", "ExceptionTimeout");
101
-        $this->drv->query("CREATE TABLE test(id integer primary key)");
102
-    }
103
-
104
-    public function testQueryConstraintViolation() {
105
-        $this->drv->exec("CREATE TABLE test(id integer not null)");
106
-        $this->assertException("constraintViolation", "Db", "ExceptionInput");
107
-        $this->drv->query("INSERT INTO test(id) values(null)");
108
-    }
109
-
110
-    public function testQueryTypeViolation() {
111
-        $this->drv->exec("CREATE TABLE test(id integer primary key)");
112
-        $this->assertException("typeViolation", "Db", "ExceptionInput");
113
-        $this->drv->query("INSERT INTO test(id) values('ook')");
114
-    }
13
+class TestDriver extends \JKingWeb\Arsse\TestCase\Db\BaseDriver {
14
+    protected $implementation = "PDO SQLite 3";
15
+    protected $create = "CREATE TABLE arsse_test(id integer primary key)";
16
+    protected $lock = "BEGIN EXCLUSIVE TRANSACTION";
17
+    protected $setVersion = "PRAGMA user_version=#";
18
+    protected static $file;
115 19
 
116
-    public function testPrepareAValidQuery() {
117
-        $s = $this->drv->prepare("SELECT ?, ?", "int", "int");
118
-        $this->assertInstanceOf(Statement::class, $s);
20
+    public static function setUpBeforeClass() {
21
+        self::$file = tempnam(sys_get_temp_dir(), 'ook');
119 22
     }
120 23
 
121
-    public function testPrepareAnInvalidQuery() {
122
-        $this->assertException("engineErrorGeneral", "Db");
123
-        $s = $this->drv->prepare("This is an invalid query", "int", "int");
24
+    public static function tearDownAfterClass() {
25
+        @unlink(self::$file);
26
+        self::$file = null;
124 27
     }
125
-
126
-    public function testCreateASavepoint() {
127
-        $this->assertEquals(1, $this->drv->savepointCreate());
128
-        $this->assertEquals(2, $this->drv->savepointCreate());
129
-        $this->assertEquals(3, $this->drv->savepointCreate());
130
-    }
131
-
132
-    public function testReleaseASavepoint() {
133
-        $this->assertEquals(1, $this->drv->savepointCreate());
134
-        $this->assertEquals(true, $this->drv->savepointRelease());
135
-        $this->assertException("savepointInvalid", "Db");
136
-        $this->drv->savepointRelease();
137
-    }
138
-
139
-    public function testUndoASavepoint() {
140
-        $this->assertEquals(1, $this->drv->savepointCreate());
141
-        $this->assertEquals(true, $this->drv->savepointUndo());
142
-        $this->assertException("savepointInvalid", "Db");
143
-        $this->drv->savepointUndo();
144
-    }
145
-
146
-    public function testManipulateSavepoints() {
147
-        $this->assertEquals(1, $this->drv->savepointCreate());
148
-        $this->assertEquals(2, $this->drv->savepointCreate());
149
-        $this->assertEquals(3, $this->drv->savepointCreate());
150
-        $this->assertEquals(4, $this->drv->savepointCreate());
151
-        $this->assertEquals(5, $this->drv->savepointCreate());
152
-        $this->assertTrue($this->drv->savepointUndo(3));
153
-        $this->assertFalse($this->drv->savepointRelease(4));
154
-        $this->assertEquals(6, $this->drv->savepointCreate());
155
-        $this->assertFalse($this->drv->savepointRelease(5));
156
-        $this->assertTrue($this->drv->savepointRelease(6));
157
-        $this->assertEquals(3, $this->drv->savepointCreate());
158
-        $this->assertTrue($this->drv->savepointRelease(2));
159
-        $this->assertException("savepointStale", "Db");
160
-        $this->drv->savepointRelease(2);
161
-    }
162
-
163
-    public function testManipulateSavepointsSomeMore() {
164
-        $this->assertEquals(1, $this->drv->savepointCreate());
165
-        $this->assertEquals(2, $this->drv->savepointCreate());
166
-        $this->assertEquals(3, $this->drv->savepointCreate());
167
-        $this->assertEquals(4, $this->drv->savepointCreate());
168
-        $this->assertTrue($this->drv->savepointRelease(2));
169
-        $this->assertFalse($this->drv->savepointUndo(3));
170
-        $this->assertException("savepointStale", "Db");
171
-        $this->drv->savepointUndo(2);
172
-    }
173
-
174
-    public function testBeginATransaction() {
175
-        $select = "SELECT count(*) FROM test";
176
-        $insert = "INSERT INTO test(id) values(null)";
177
-        $this->drv->exec("CREATE TABLE test(id integer primary key)");
178
-        $tr = $this->drv->begin();
179
-        $this->drv->query($insert);
180
-        $this->assertEquals(1, $this->drv->query($select)->getValue());
181
-        $this->assertEquals(0, $this->ch->query($select)->fetchColumn());
182
-        $this->drv->query($insert);
183
-        $this->assertEquals(2, $this->drv->query($select)->getValue());
184
-        $this->assertEquals(0, $this->ch->query($select)->fetchColumn());
185
-    }
186
-
187
-    public function testCommitATransaction() {
188
-        $select = "SELECT count(*) FROM test";
189
-        $insert = "INSERT INTO test(id) values(null)";
190
-        $this->drv->exec("CREATE TABLE test(id integer primary key)");
191
-        $tr = $this->drv->begin();
192
-        $this->drv->query($insert);
193
-        $this->assertEquals(1, $this->drv->query($select)->getValue());
194
-        $this->assertEquals(0, $this->ch->query($select)->fetchColumn());
195
-        $tr->commit();
196
-        $this->assertEquals(1, $this->drv->query($select)->getValue());
197
-        $this->assertEquals(1, $this->ch->query($select)->fetchColumn());
198
-    }
199
-
200
-    public function testRollbackATransaction() {
201
-        $select = "SELECT count(*) FROM test";
202
-        $insert = "INSERT INTO test(id) values(null)";
203
-        $this->drv->exec("CREATE TABLE test(id integer primary key)");
204
-        $tr = $this->drv->begin();
205
-        $this->drv->query($insert);
206
-        $this->assertEquals(1, $this->drv->query($select)->getValue());
207
-        $this->assertEquals(0, $this->ch->query($select)->fetchColumn());
208
-        $tr->rollback();
209
-        $this->assertEquals(0, $this->drv->query($select)->getValue());
210
-        $this->assertEquals(0, $this->ch->query($select)->fetchColumn());
211
-    }
212
-
213
-    public function testBeginChainedTransactions() {
214
-        $select = "SELECT count(*) FROM test";
215
-        $insert = "INSERT INTO test(id) values(null)";
216
-        $this->drv->exec("CREATE TABLE test(id integer primary key)");
217
-        $tr1 = $this->drv->begin();
218
-        $this->drv->query($insert);
219
-        $this->assertEquals(1, $this->drv->query($select)->getValue());
220
-        $this->assertEquals(0, $this->ch->query($select)->fetchColumn());
221
-        $tr2 = $this->drv->begin();
222
-        $this->drv->query($insert);
223
-        $this->assertEquals(2, $this->drv->query($select)->getValue());
224
-        $this->assertEquals(0, $this->ch->query($select)->fetchColumn());
225
-    }
226
-
227
-    public function testCommitChainedTransactions() {
228
-        $select = "SELECT count(*) FROM test";
229
-        $insert = "INSERT INTO test(id) values(null)";
230
-        $this->drv->exec("CREATE TABLE test(id integer primary key)");
231
-        $tr1 = $this->drv->begin();
232
-        $this->drv->query($insert);
233
-        $this->assertEquals(1, $this->drv->query($select)->getValue());
234
-        $this->assertEquals(0, $this->ch->query($select)->fetchColumn());
235
-        $tr2 = $this->drv->begin();
236
-        $this->drv->query($insert);
237
-        $this->assertEquals(2, $this->drv->query($select)->getValue());
238
-        $this->assertEquals(0, $this->ch->query($select)->fetchColumn());
239
-        $tr2->commit();
240
-        $this->assertEquals(0, $this->ch->query($select)->fetchColumn());
241
-        $tr1->commit();
242
-        $this->assertEquals(2, $this->ch->query($select)->fetchColumn());
243
-    }
244
-
245
-    public function testCommitChainedTransactionsOutOfOrder() {
246
-        $select = "SELECT count(*) FROM test";
247
-        $insert = "INSERT INTO test(id) values(null)";
248
-        $this->drv->exec("CREATE TABLE test(id integer primary key)");
249
-        $tr1 = $this->drv->begin();
250
-        $this->drv->query($insert);
251
-        $this->assertEquals(1, $this->drv->query($select)->getValue());
252
-        $this->assertEquals(0, $this->ch->query($select)->fetchColumn());
253
-        $tr2 = $this->drv->begin();
254
-        $this->drv->query($insert);
255
-        $this->assertEquals(2, $this->drv->query($select)->getValue());
256
-        $this->assertEquals(0, $this->ch->query($select)->fetchColumn());
257
-        $tr1->commit();
258
-        $this->assertEquals(2, $this->ch->query($select)->fetchColumn());
259
-        $tr2->commit();
260
-    }
261
-
262
-    public function testRollbackChainedTransactions() {
263
-        $select = "SELECT count(*) FROM test";
264
-        $insert = "INSERT INTO test(id) values(null)";
265
-        $this->drv->exec("CREATE TABLE test(id integer primary key)");
266
-        $tr1 = $this->drv->begin();
267
-        $this->drv->query($insert);
268
-        $this->assertEquals(1, $this->drv->query($select)->getValue());
269
-        $this->assertEquals(0, $this->ch->query($select)->fetchColumn());
270
-        $tr2 = $this->drv->begin();
271
-        $this->drv->query($insert);
272
-        $this->assertEquals(2, $this->drv->query($select)->getValue());
273
-        $this->assertEquals(0, $this->ch->query($select)->fetchColumn());
274
-        $tr2->rollback();
275
-        $this->assertEquals(1, $this->drv->query($select)->getValue());
276
-        $this->assertEquals(0, $this->ch->query($select)->fetchColumn());
277
-        $tr1->rollback();
278
-        $this->assertEquals(0, $this->drv->query($select)->getValue());
279
-        $this->assertEquals(0, $this->ch->query($select)->fetchColumn());
280
-    }
281
-
282
-    public function testRollbackChainedTransactionsOutOfOrder() {
283
-        $select = "SELECT count(*) FROM test";
284
-        $insert = "INSERT INTO test(id) values(null)";
285
-        $this->drv->exec("CREATE TABLE test(id integer primary key)");
286
-        $tr1 = $this->drv->begin();
287
-        $this->drv->query($insert);
288
-        $this->assertEquals(1, $this->drv->query($select)->getValue());
289
-        $this->assertEquals(0, $this->ch->query($select)->fetchColumn());
290
-        $tr2 = $this->drv->begin();
291
-        $this->drv->query($insert);
292
-        $this->assertEquals(2, $this->drv->query($select)->getValue());
293
-        $this->assertEquals(0, $this->ch->query($select)->fetchColumn());
294
-        $tr1->rollback();
295
-        $this->assertEquals(0, $this->drv->query($select)->getValue());
296
-        $this->assertEquals(0, $this->ch->query($select)->fetchColumn());
297
-        $tr2->rollback();
298
-        $this->assertEquals(0, $this->drv->query($select)->getValue());
299
-        $this->assertEquals(0, $this->ch->query($select)->fetchColumn());
300
-    }
301
-
302
-    public function testPartiallyRollbackChainedTransactions() {
303
-        $select = "SELECT count(*) FROM test";
304
-        $insert = "INSERT INTO test(id) values(null)";
305
-        $this->drv->exec("CREATE TABLE test(id integer primary key)");
306
-        $tr1 = $this->drv->begin();
307
-        $this->drv->query($insert);
308
-        $this->assertEquals(1, $this->drv->query($select)->getValue());
309
-        $this->assertEquals(0, $this->ch->query($select)->fetchColumn());
310
-        $tr2 = $this->drv->begin();
311
-        $this->drv->query($insert);
312
-        $this->assertEquals(2, $this->drv->query($select)->getValue());
313
-        $this->assertEquals(0, $this->ch->query($select)->fetchColumn());
314
-        $tr2->rollback();
315
-        $this->assertEquals(1, $this->drv->query($select)->getValue());
316
-        $this->assertEquals(0, $this->ch->query($select)->fetchColumn());
317
-        $tr1->commit();
318
-        $this->assertEquals(1, $this->drv->query($select)->getValue());
319
-        $this->assertEquals(1, $this->ch->query($select)->fetchColumn());
320
-    }
321
-
322
-    public function testFetchSchemaVersion() {
323
-        $this->assertSame(0, $this->drv->schemaVersion());
324
-        $this->drv->exec("PRAGMA user_version=1");
325
-        $this->assertSame(1, $this->drv->schemaVersion());
326
-        $this->drv->exec("PRAGMA user_version=2");
327
-        $this->assertSame(2, $this->drv->schemaVersion());
328
-    }
329
-
330
-    public function testLockTheDatabase() {
331
-        $this->drv->savepointCreate(true);
332
-        $this->ch->exec("PRAGMA busy_timeout = 0");
333
-        $this->assertException();
334
-        $this->ch->exec("CREATE TABLE test(id integer primary key)");
28
+    
29
+    public function setUp() {
30
+        $this->conf['dbSQLite3File'] = self::$file;
31
+        parent::setUp();
32
+        $this->exec("PRAGMA user_version=0");
335 33
     }
336 34
 
337
-    public function testUnlockTheDatabase() {
338
-        $this->drv->savepointCreate(true);
339
-        $this->drv->savepointRelease();
340
-        $this->drv->savepointCreate(true);
341
-        $this->drv->savepointUndo();
342
-        $this->assertSame(0, $this->ch->exec("CREATE TABLE test(id integer primary key)"));
35
+    public function tearDown() {
36
+        parent::tearDown();
37
+        $this->exec("PRAGMA user_version=0");
38
+        unset($this->interface);
343 39
     }
344 40
 }

+ 108
- 1
tests/lib/AbstractTest.php View File

@@ -43,11 +43,12 @@ abstract class AbstractTest extends \PHPUnit\Framework\TestCase {
43 43
     public function setConf(array $conf = []) {
44 44
         $defaults = [
45 45
             'dbSQLite3File' => ":memory:",
46
+            'dbSQLite3Timeout' => 0,
46 47
             'dbPostgreSQLUser' => "arsse_test",
47 48
             'dbPostgreSQLPass' => "arsse_test",
48 49
             'dbPostgreSQLDb' => "arsse_test",
49 50
         ];
50
-        Arsse::$conf = (new Conf)->import($defaults)->import($conf);
51
+        Arsse::$conf = Arsse::$conf ?? (new Conf)->import($defaults)->import($conf);
51 52
     }
52 53
 
53 54
     public function assertException(string $msg = "", string $prefix = "", string $type = "Exception") {
@@ -126,6 +127,33 @@ abstract class AbstractTest extends \PHPUnit\Framework\TestCase {
126 127
         return $value;
127 128
     }
128 129
 
130
+    public function provideDbDrivers(array $conf = []): array {
131
+        $this->setConf($conf);
132
+        return [
133
+            'SQLite 3' => (function() {
134
+                try {
135
+                    return new \JKingWeb\Arsse\Db\SQLite3\Driver;
136
+                } catch (\Exception $e) {
137
+                    return;
138
+                }
139
+            })(),
140
+            'PDO SQLite 3' => (function() {
141
+                try {
142
+                    return new \JKingWeb\Arsse\Db\SQLite3\PDODriver;
143
+                } catch (\Exception $e) {
144
+                    return;
145
+                }
146
+            })(),
147
+            'PDO PostgreSQL' => (function() {
148
+                try {
149
+                    return new \JKingWeb\Arsse\Db\PostgreSQL\PDODriver;
150
+                } catch (\Exception $e) {
151
+                    return;
152
+                }
153
+            })(),
154
+        ];
155
+    }
156
+
129 157
     public function provideDbInterfaces(array $conf = []): array {
130 158
         $this->setConf($conf);
131 159
         return [
@@ -180,4 +208,83 @@ abstract class AbstractTest extends \PHPUnit\Framework\TestCase {
180 208
             ],
181 209
         ];
182 210
     }
211
+
212
+    public function getDbDriver(string $name, array $conf = []) {
213
+        $this->setConf($conf);
214
+        switch ($name) {
215
+            case 'SQLite 3':
216
+                return (function() {
217
+                    try {
218
+                        return new \JKingWeb\Arsse\Db\SQLite3\Driver;
219
+                    } catch (\Exception $e) {
220
+                        return;
221
+                    }
222
+                })();
223
+            case 'PDO SQLite 3':
224
+                return (function() {
225
+                    try {
226
+                        return new \JKingWeb\Arsse\Db\SQLite3\PDODriver;
227
+                    } catch (\Exception $e) {
228
+                        return;
229
+                    }
230
+                })();
231
+            case 'PDO PostgreSQL':
232
+                return (function() {
233
+                    try {
234
+                        return new \JKingWeb\Arsse\Db\PostgreSQL\PDODriver;
235
+                    } catch (\Exception $e) {
236
+                        return;
237
+                    }
238
+                })();
239
+            default:
240
+                throw new \Exception("Invalid database driver name");
241
+        }
242
+    }
243
+
244
+    public function getDbInterface(string $name, array $conf = []) {
245
+        $this->setConf($conf);
246
+        switch ($name) {
247
+            case 'SQLite 3':
248
+                return (function() {
249
+                    if (\JKingWeb\Arsse\Db\SQLite3\Driver::requirementsMet()) {
250
+                        try {
251
+                            $d = new \SQLite3(Arsse::$conf->dbSQLite3File);
252
+                        } catch (\Exception $e) {
253
+                            return;
254
+                        }
255
+                        $d->enableExceptions(true);
256
+                        return $d;
257
+                    }
258
+                })();
259
+            case 'PDO SQLite 3':
260
+                return (function() {
261
+                    if (\JKingWeb\Arsse\Db\SQLite3\PDODriver::requirementsMet()) {
262
+                        try {
263
+                            $d = new \PDO("sqlite:".Arsse::$conf->dbSQLite3File, "", "", [\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION]);
264
+                            $d->exec("PRAGMA busy_timeout=0");
265
+                            return $d;
266
+                        } catch (\PDOException $e) {
267
+                            return;
268
+                        }
269
+                    }
270
+                })();
271
+            case 'PDO PostgreSQL':
272
+                return (function() {
273
+                    if (\JKingWeb\Arsse\Db\PostgreSQL\PDODriver::requirementsMet()) {
274
+                        $connString = \JKingWeb\Arsse\Db\PostgreSQL\Driver::makeConnectionString(true, Arsse::$conf->dbPostgreSQLUser, Arsse::$conf->dbPostgreSQLPass, Arsse::$conf->dbPostgreSQLDb, Arsse::$conf->dbPostgreSQLHost, Arsse::$conf->dbPostgreSQLPort, "");
275
+                        try {
276
+                            $c = new \PDO("pgsql:".$connString, Arsse::$conf->dbPostgreSQLUser, Arsse::$conf->dbPostgreSQLPass, [\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION]);
277
+                        } catch (\PDOException $e) {
278
+                            return;
279
+                        }
280
+                        foreach (\JKingWeb\Arsse\Db\PostgreSQL\PDODriver::makeSetupQueries(Arsse::$conf->dbPostgreSQLSchema) as $q) {
281
+                            $c->exec($q);
282
+                        }
283
+                        return $c;
284
+                    }
285
+                })();
286
+            default:
287
+                throw new \Exception("Invalid database driver name");
288
+        }
289
+    }
183 290
 }

+ 1
- 0
tests/phpunit.xml View File

@@ -57,6 +57,7 @@
57 57
         <file>cases/Db/SQLite3PDO/TestUpdate.php</file>
58 58
 
59 59
         <file>cases/Db/PostgreSQL/TestCreation.php</file>
60
+        <file>cases/Db/PostgreSQL/TestDriver.php</file>
60 61
     </testsuite>
61 62
     <testsuite name="Database functions">
62 63
         <file>cases/Db/SQLite3/Database/TestMiscellany.php</file>

Loading…
Cancel
Save