test(database): verify upgraded schemas against current contract

This commit is contained in:
4gray committed 2026-09-11 00:24:57 +02:00
1 parent 84bb1b836d
commit f386d64472
2 files changed
+37 -1

No files matched your search

+2 -1
View File
@@ -66,7 +66,8 @@ The #1580 index-ordering fix is included in 0.24 through PR #1550.
`src/lib/connection-upgrades.spec.ts` exercises `initDatabase()` with real
SQLite under the Electron runtime, using fresh-install schema snapshots from
tags 0.19–0.23 and a fresh current database. The `epg_channel_id` column is absent
in 0.19, present from 0.20, and indexed from 0.23. Each case checks preserved user
in 0.19, present from 0.20, and indexed from 0.23. Each case checks current Drizzle
tables, columns/types, and named indexes/uniqueness, as well as preserved user
rows, foreign keys, database integrity, index availability, and repeated startup;
an existing EPG index must keep its definition and root page. Snapshots live in
`src/lib/testing/fixtures/` and are independent of the current schema, so moving
@@ -1,7 +1,9 @@
import assert from 'node:assert/strict';
import { readFileSync } from 'node:fs';
import Database from 'better-sqlite3';
import { getTableConfig } from 'drizzle-orm/sqlite-core';
import { closeDatabase, getDatabasePath, initDatabase } from '../connection';
import * as currentSchema from '../schema';
const tables = [
'playlists',
@@ -54,6 +56,38 @@ function epgIndex(sqlite: Database.Database) {
.get();
}
function verifyCurrentSchema(sqlite: Database.Database) {
for (const table of Object.values(currentSchema)) {
const { name, columns, indexes } = getTableConfig(table);
const actualColumns = sqlite.pragma(`table_info(${name})`) as {
name: string;
type: string;
}[];
assert(actualColumns.length > 0, `Missing current table: ${name}`);
for (const column of columns) {
const actual = actualColumns.find(
(item) => item.name === column.name
);
assert(actual, `Missing current column: ${name}.${column.name}`);
assert.equal(
actual.type.toLowerCase(),
column.getSQLType().toLowerCase()
);
}
const actualIndexes = sqlite.pragma(`index_list(${name})`) as {
name: string;
unique: number;
}[];
for (const { config } of indexes) {
const actual = actualIndexes.find(
(item) => item.name === config.name
);
assert(actual, `Missing current index: ${config.name}`);
assert.equal(actual.unique, Number(config.unique), config.name);
}
}
}
async function main() {
const fixture = process.argv[2];
assert(
@@ -83,6 +117,7 @@ async function main() {
await initDatabase();
const sqlite = new Database(databasePath, { readonly: true });
try {
verifyCurrentSchema(sqlite);
for (const { query, rows } of before) {
assert.deepEqual(sqlite.prepare(query).all(), rows, query);
}