161 lines
5.9 KiB
JavaScript
161 lines
5.9 KiB
JavaScript
// Generated, do not edit. sha256:db9b5ce5c6a3dba8e3c23b58d01a079d11c9184ff6a8915c824e00ac45006d20
|
|
import { describe, it, before, after, beforeEach, afterEach } from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import { DatabaseSync } from 'node:sqlite';
|
|
import { mkdtemp, rm } from 'node:fs/promises';
|
|
import { tmpdir } from 'node:os';
|
|
import { join } from 'node:path';
|
|
import {
|
|
openDatabase, closeDatabase, database, pragmaStand,
|
|
run, all, one, lastId, BUSY_TIMEOUT_MS,
|
|
} from '../../server/db/conn.mjs';
|
|
|
|
const DDL = `
|
|
CREATE TABLE Ouder (id INTEGER PRIMARY KEY, naam TEXT NOT NULL) STRICT;
|
|
CREATE TABLE Kind (
|
|
id INTEGER PRIMARY KEY,
|
|
ouderId INTEGER NOT NULL REFERENCES Ouder(id) ON DELETE CASCADE,
|
|
tekst TEXT NOT NULL
|
|
) STRICT;
|
|
CREATE INDEX IxKindOuder ON Kind (ouderId);
|
|
`;
|
|
|
|
describe('server/db/conn: de verbinding en zijn PRAGMA\'s', () => {
|
|
beforeEach(() => { openDatabase(':memory:'); run(DDL); });
|
|
afterEach(() => closeDatabase());
|
|
|
|
it('dwingt foreign keys écht af, en niet alleen op papier', () => {
|
|
run(`INSERT INTO Ouder (naam) VALUES (?)`, ['een']);
|
|
const ouderId = lastId();
|
|
run(`INSERT INTO Kind (ouderId, tekst) VALUES (?,?)`, [ouderId, 'hoort erbij']);
|
|
|
|
assert.throws(
|
|
() => run(`INSERT INTO Kind (ouderId, tekst) VALUES (?,?)`, [9999, 'wees']),
|
|
/FOREIGN KEY constraint failed/);
|
|
|
|
run(`DELETE FROM Ouder WHERE id = ?`, [ouderId]);
|
|
assert.equal(all(`SELECT * FROM Kind`).length, 0);
|
|
});
|
|
|
|
it('TEGENPROEF: zonder handhaving slaagt exact dezelfde INSERT', () => {
|
|
const zonder = new DatabaseSync(':memory:', { enableForeignKeyConstraints: false });
|
|
zonder.exec(DDL);
|
|
zonder.prepare(`INSERT INTO Kind (ouderId, tekst) VALUES (?,?)`).run(9999n, 'wees');
|
|
assert.equal(zonder.prepare(`SELECT COUNT(*) AS n FROM Kind`).get().n, 1,
|
|
'zonder handhaving hoort de wees er gewoon in te staan; anders bewijst de test hierboven niets');
|
|
zonder.close();
|
|
});
|
|
|
|
it('zet de vier PRAGMA\'s op de verbinding', () => {
|
|
const stand = pragmaStand();
|
|
assert.equal(stand.foreignKeys, true);
|
|
assert.equal(stand.journalMode, 'memory');
|
|
assert.equal(stand.synchronous, 1);
|
|
assert.equal(stand.busyTimeout, BUSY_TIMEOUT_MS);
|
|
});
|
|
|
|
it('weigert een tweede verbinding zolang de eerste openstaat', () => {
|
|
assert.throws(() => openDatabase(':memory:'), /already open/);
|
|
});
|
|
|
|
it('geeft gewone objecten terug, geen rijen met null-prototype', () => {
|
|
run(`INSERT INTO Ouder (naam) VALUES (?)`, ['een']);
|
|
const rij = one(`SELECT * FROM Ouder`);
|
|
assert.equal(Object.getPrototypeOf(rij), Object.prototype);
|
|
assert.deepEqual(rij, { id: 1, naam: 'een' });
|
|
});
|
|
|
|
it('geeft null bij one() zonder treffer, en null uit lastId() zonder insert', () => {
|
|
assert.equal(one(`SELECT * FROM Ouder WHERE id = ?`, [404]), null);
|
|
});
|
|
});
|
|
|
|
describe('server/db/conn: bindwaarden gelijk aan wat de browser deed', () => {
|
|
beforeEach(() => {
|
|
openDatabase(':memory:');
|
|
run(`CREATE TABLE Waarde (id INTEGER PRIMARY KEY, tekst TEXT, getal INTEGER) STRICT;`);
|
|
});
|
|
afterEach(() => closeDatabase());
|
|
|
|
it('maakt van undefined een NULL in plaats van te gooien', () => {
|
|
run(`INSERT INTO Waarde (tekst, getal) VALUES (?,?)`, [undefined, 1]);
|
|
assert.equal(one(`SELECT tekst FROM Waarde`).tekst, null);
|
|
});
|
|
|
|
it('maakt van true/false een 1/0', () => {
|
|
run(`INSERT INTO Waarde (tekst, getal) VALUES (?,?)`, ['x', true]);
|
|
run(`INSERT INTO Waarde (tekst, getal) VALUES (?,?)`, ['y', false]);
|
|
assert.deepEqual(all(`SELECT getal FROM Waarde ORDER BY id`).map(r => r.getal), [1, 0]);
|
|
});
|
|
|
|
it('schrijft een heel getal in een TEXT-kolom als \'1\' en niet als \'1.0\'', () => {
|
|
run(`INSERT INTO Waarde (tekst) VALUES (?)`, [1]);
|
|
assert.equal(one(`SELECT tekst FROM Waarde`).tekst, '1');
|
|
});
|
|
});
|
|
|
|
describe('server/db/conn: run() zonder params voert meerdere statements uit', () => {
|
|
beforeEach(() => openDatabase(':memory:'));
|
|
afterEach(() => closeDatabase());
|
|
|
|
it('voert een meerdelige DDL-string volledig uit', () => {
|
|
run(DDL);
|
|
const tabellen = all(`SELECT name FROM sqlite_master WHERE type = 'table' ORDER BY name`).map(r => r.name);
|
|
assert.deepEqual(tabellen, ['Kind', 'Ouder']);
|
|
});
|
|
|
|
it('voert met params alleen het eerste statement uit', () => {
|
|
run(`CREATE TABLE A (id INTEGER PRIMARY KEY, t TEXT) STRICT;`);
|
|
run(`INSERT INTO A (t) VALUES (?); INSERT INTO A (t) VALUES ('tweede');`, ['eerste']);
|
|
assert.deepEqual(all(`SELECT t FROM A`).map(r => r.t), ['eerste']);
|
|
});
|
|
});
|
|
|
|
describe('server/db/conn: op een echt bestand', () => {
|
|
let dir, pad;
|
|
|
|
before(async () => {
|
|
dir = await mkdtemp(join(tmpdir(), 'assetapp-db-'));
|
|
pad = join(dir, 'test.sqlite');
|
|
});
|
|
after(async () => {
|
|
closeDatabase();
|
|
await rm(dir, { recursive: true, force: true });
|
|
});
|
|
|
|
it('zet WAL aan, en die blijft in het bestand staan', () => {
|
|
openDatabase(pad);
|
|
run(DDL);
|
|
assert.equal(pragmaStand().journalMode, 'wal');
|
|
closeDatabase();
|
|
|
|
const kaal = new DatabaseSync(pad);
|
|
assert.equal(kaal.prepare(`PRAGMA journal_mode`).get().journal_mode, 'wal');
|
|
kaal.close();
|
|
});
|
|
|
|
it('zet synchronous en busy_timeout élke keer opnieuw, want die zijn NIET persistent', () => {
|
|
const kaal = new DatabaseSync(pad);
|
|
assert.equal(kaal.prepare(`PRAGMA synchronous`).get().synchronous, 2);
|
|
assert.equal(kaal.prepare(`PRAGMA busy_timeout`).get().timeout, 0);
|
|
kaal.close();
|
|
|
|
openDatabase(pad);
|
|
const stand = pragmaStand();
|
|
assert.equal(stand.synchronous, 1);
|
|
assert.equal(stand.busyTimeout, BUSY_TIMEOUT_MS);
|
|
closeDatabase();
|
|
});
|
|
|
|
it('bewaart de data tussen twee sessies door, zonder persist()', () => {
|
|
openDatabase(pad);
|
|
run(`INSERT INTO Ouder (naam) VALUES (?)`, ['blijft staan']);
|
|
closeDatabase();
|
|
|
|
openDatabase(pad);
|
|
assert.equal(one(`SELECT naam FROM Ouder ORDER BY id DESC`).naam, 'blijft staan');
|
|
assert.equal(database().constructor.name, 'DatabaseSync');
|
|
closeDatabase();
|
|
});
|
|
});
|