Download server/src/__tests__/db/node-sqlite.test.ts from automindy/fokemal: direct link, hf CLI and curl.
- Browser
- Download file 3.48 kB
-
https://huggingface.co/spaces/automindy/fokemal/resolve/main/server/src/__tests__/db/node-sqlite.test.ts
- Command line
-
hf download hf://spaces/automindy/fokemal/server/src/__tests__/db/node-sqlite.test.ts
-
curl -L -o node-sqlite.test.ts https://huggingface.co/spaces/automindy/fokemal/resolve/main/server/src/__tests__/db/node-sqlite.test.ts
3.48 kB
| import { afterEach, describe, expect, it } from 'vitest'; | |
| import fs from 'node:fs'; | |
| import os from 'node:os'; | |
| import path from 'node:path'; | |
| import { createRequire } from 'node:module'; | |
| // node:sqlite ships in Node 22.13+. CI also tests Node 20, where the built-in | |
| // module (and therefore the Android fallback) does not exist — skip the tests | |
| // that open a database there; the factory-selection test still runs everywhere. | |
| const hasNodeSqlite = (() => { | |
| try { | |
| createRequire(import.meta.url)('node:sqlite'); | |
| return true; | |
| } catch { | |
| return false; | |
| } | |
| })(); | |
| const itWithSqlite = it.skipIf(!hasNodeSqlite); | |
| import { connectDb, defaultDbFactory } from '../../db/index.js'; | |
| import { nodeSqliteFactory } from '../../db/node-sqlite.js'; | |
| import { runMigrationsSync } from '../../db/migrate/runner.js'; | |
| import type { Db } from '../../db/types.js'; | |
| describe('node:sqlite Android fallback', () => { | |
| let db: Db | undefined; | |
| const tempDirs: string[] = []; | |
| afterEach(() => { | |
| db?.close?.(); | |
| db = undefined; | |
| for (const dir of tempDirs.splice(0)) fs.rmSync(dir, { recursive: true, force: true }); | |
| }); | |
| it('is selected only for Android', () => { | |
| expect(defaultDbFactory('android')).toBe(nodeSqliteFactory); | |
| expect(defaultDbFactory('darwin')).not.toBe(nodeSqliteFactory); | |
| expect(defaultDbFactory('linux')).not.toBe(nodeSqliteFactory); | |
| }); | |
| itWithSqlite('runs the complete application migration set', () => { | |
| db = connectDb(':memory:', { factory: nodeSqliteFactory, ensureDir: false }); | |
| runMigrationsSync(db, 'up'); | |
| const tables = db.prepare("SELECT name FROM sqlite_master WHERE type = 'table'").all() as { name: string }[]; | |
| expect(tables.map((row) => row.name)).toContain('api_keys'); | |
| expect((db.prepare('SELECT COUNT(*) AS count FROM models').get() as { count: number }).count).toBeGreaterThan(0); | |
| }); | |
| itWithSqlite('opens a file-backed database with WAL and file metadata', () => { | |
| const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'freellmapi-node-sqlite-')); | |
| tempDirs.push(dir); | |
| const dbPath = path.join(dir, 'freeapi.db'); | |
| db = connectDb(dbPath, { factory: nodeSqliteFactory }); | |
| db.exec('CREATE TABLE sample (id INTEGER PRIMARY KEY, value TEXT NOT NULL)'); | |
| db.prepare('INSERT INTO sample (value) VALUES (?)').run('persisted'); | |
| expect(db.name).toBe(dbPath); | |
| expect(db.memory).toBe(false); | |
| expect(fs.existsSync(dbPath)).toBe(true); | |
| expect(db.pragma('journal_mode')).toEqual([{ journal_mode: 'wal' }]); | |
| }); | |
| itWithSqlite('supports nested transaction commit and rollback semantics', () => { | |
| db = connectDb(':memory:', { factory: nodeSqliteFactory, ensureDir: false }); | |
| db.exec('CREATE TABLE items (id INTEGER PRIMARY KEY, value TEXT NOT NULL)'); | |
| const outer = db.transaction(() => { | |
| db!.prepare('INSERT INTO items (value) VALUES (?)').run('outer'); | |
| db!.transaction(() => { | |
| db!.prepare('INSERT INTO items (value) VALUES (?)').run('inner'); | |
| })(); | |
| try { | |
| db!.transaction(() => { | |
| db!.prepare('INSERT INTO items (value) VALUES (?)').run('rolled-back'); | |
| throw new Error('rollback inner savepoint'); | |
| })(); | |
| } catch { | |
| // The outer transaction remains usable and commits. | |
| } | |
| }); | |
| outer(); | |
| const rows = db.prepare('SELECT value FROM items ORDER BY id').all() as { value: string }[]; | |
| expect(rows.map((row) => row.value)).toEqual(['outer', 'inner']); | |
| }); | |
| }); | |