Skip to content

Commit 3f1b19f

Browse files
committed
chore: expanded test suite to test blobs and sahpool pause & unpause functionality
1 parent 02d0849 commit 3f1b19f

File tree

4 files changed

+127
-8
lines changed

4 files changed

+127
-8
lines changed

src/__tests__/bundler-compatibility.test.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,10 @@ describe('Vite bundler compatibility', () => {
1414
}
1515

1616
// Run vite build
17-
execSync('npx vite build', { cwd: testDir, stdio: 'inherit' });
17+
execSync('npx vite build --logLevel error', {
18+
cwd: testDir,
19+
stdio: 'inherit',
20+
});
1821

1922
// 1. Check if hashed WASM file exists in dist/assets
2023
const assetsDir = path.resolve(distDir, 'assets');

src/__tests__/sqlite3-node.test.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,30 @@ test('Node.js build sanity check', async () => {
135135
expect(
136136
typeof db.selectValue('SELECT sqlite_offset(id) FROM off_test'),
137137
).toBe('number');
138+
139+
// 13. Blobs
140+
const blobData = new Uint8Array([0x00, 0xff, 0xaa, 0x55]);
141+
db.exec({
142+
sql: 'CREATE TABLE blobs (data BLOB)',
143+
});
144+
db.exec({
145+
sql: 'INSERT INTO blobs (data) VALUES (?)',
146+
bind: [blobData],
147+
});
148+
const retrievedBlob = db.selectValue('SELECT data FROM blobs');
149+
expect(retrievedBlob).toBeInstanceOf(Uint8Array);
150+
expect(retrievedBlob).toEqual(blobData);
151+
152+
// 14. Error handling
153+
expect(() => {
154+
db.exec('INVALID SQL');
155+
}).toThrow();
156+
157+
db.exec('CREATE TABLE unique_test (id INTEGER PRIMARY KEY)');
158+
db.exec('INSERT INTO unique_test VALUES (1)');
159+
expect(() => {
160+
db.exec('INSERT INTO unique_test VALUES (1)');
161+
}).toThrow(/UNIQUE constraint failed/);
138162
} finally {
139163
// 11. Close the database
140164
db.close();

src/__tests__/sqlite3-oo1.browser.test.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,30 @@ test('Bundler-friendly OO1 API sanity check (browser)', async () => {
135135
expect(
136136
typeof db.selectValue('SELECT sqlite_offset(id) FROM off_test'),
137137
).toBe('number');
138+
139+
// 13. Blobs
140+
const blobData = new Uint8Array([0x00, 0xff, 0xaa, 0x55]);
141+
db.exec({
142+
sql: 'CREATE TABLE blobs (data BLOB)',
143+
});
144+
db.exec({
145+
sql: 'INSERT INTO blobs (data) VALUES (?)',
146+
bind: [blobData],
147+
});
148+
const retrievedBlob = db.selectValue('SELECT data FROM blobs');
149+
expect(retrievedBlob).toBeInstanceOf(Uint8Array);
150+
expect(retrievedBlob).toEqual(blobData);
151+
152+
// 14. Error handling
153+
expect(() => {
154+
db.exec('INVALID SQL');
155+
}).toThrow();
156+
157+
db.exec('CREATE TABLE unique_test (id INTEGER PRIMARY KEY)');
158+
db.exec('INSERT INTO unique_test VALUES (1)');
159+
expect(() => {
160+
db.exec('INSERT INTO unique_test VALUES (1)');
161+
}).toThrow(/UNIQUE constraint failed/);
138162
} finally {
139163
db.close();
140164
expect(db.isOpen()).toBe(false);

src/__tests__/workers/sqlite3-sahpool.worker.js

Lines changed: 75 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import sqlite3InitModule from '../../bin/sqlite3-bundler-friendly.mjs';
22

3-
self.onmessage = async (e) => {
3+
self.onmessage = async () => {
44
try {
55
const sqlite3 = await sqlite3InitModule();
66
const opfsSahPool = await sqlite3.installOpfsSAHPoolVfs();
7-
const db = new opfsSahPool.OpfsSAHPoolDb('/test-sahpool-worker.sqlite3');
7+
let db = new opfsSahPool.OpfsSAHPoolDb('/test-sahpool-worker.sqlite3');
88

99
try {
1010
// 1. Basic CRUD
@@ -29,6 +29,15 @@ self.onmessage = async (e) => {
2929
throw new Error('CRUD check failed');
3030
}
3131

32+
db.close();
33+
34+
// Reopen to check persistence
35+
db = new opfsSahPool.OpfsSAHPoolDb('/test-sahpool-worker.sqlite3');
36+
const count = db.selectValue('SELECT count(*) FROM test');
37+
if (count !== 2) {
38+
throw new Error('Persistence check failed');
39+
}
40+
3241
// 2. Joins
3342
db.exec(
3443
'CREATE TABLE orders (id INTEGER PRIMARY KEY, user_id INTEGER, product TEXT)',
@@ -42,30 +51,89 @@ self.onmessage = async (e) => {
4251
rowMode: 'object',
4352
callback: (row) => joinedRows.push(row),
4453
});
45-
if (joinedRows.length !== 2) throw new Error('Join check failed');
54+
if (joinedRows.length !== 2) {
55+
throw new Error('Join check failed');
56+
}
4657

4758
// 3. CTE
4859
const cteCount = db.selectValue(
4960
'WITH RECURSIVE cnt(x) AS (SELECT 1 UNION ALL SELECT x+1 FROM cnt LIMIT 5) SELECT count(*) FROM cnt',
5061
);
51-
if (cteCount !== 5) throw new Error('CTE check failed');
62+
if (cteCount !== 5) {
63+
throw new Error('CTE check failed');
64+
}
5265

5366
// 4. FTS5
5467
db.exec('CREATE VIRTUAL TABLE docs USING fts5(content)');
5568
db.exec("INSERT INTO docs (content) VALUES ('sqlite is great')");
5669
const ftsResult = db.selectValue(
5770
"SELECT content FROM docs WHERE docs MATCH 'sqlite'",
5871
);
59-
if (ftsResult !== 'sqlite is great') throw new Error('FTS5 check failed');
72+
if (ftsResult !== 'sqlite is great') {
73+
throw new Error('FTS5 check failed');
74+
}
6075

6176
// 5. Math Functions
6277
const cosResult = db.selectValue('SELECT cos(0)');
63-
if (cosResult !== 1) throw new Error('Math functions check failed');
78+
if (cosResult !== 1) {
79+
throw new Error('Math functions check failed');
80+
}
6481

6582
// 6. Percentile
6683
db.exec('CREATE TABLE p(x); INSERT INTO p VALUES (1),(2),(3),(4),(5);');
6784
const perc = db.selectValue('SELECT percentile(x, 50) FROM p');
68-
if (perc !== 3) throw new Error('Percentile check failed');
85+
if (perc !== 3) {
86+
throw new Error('Percentile check failed');
87+
}
88+
89+
// 7. pauseVfs and unpauseVfs
90+
// Ensure it's not paused initially
91+
if (opfsSahPool.isPaused()) {
92+
throw new Error('VFS should not be paused initially');
93+
}
94+
95+
db.close(); // Must close DB before pausing if it's the only one using it,
96+
// or at least ensures no open file handles.
97+
// Actually, pauseVfs throws if there are open file handles.
98+
99+
opfsSahPool.pauseVfs();
100+
if (!opfsSahPool.isPaused()) {
101+
throw new Error('VFS should be paused after pauseVfs()');
102+
}
103+
104+
// Attempting to open a DB with a paused VFS should fail
105+
try {
106+
new opfsSahPool.OpfsSAHPoolDb('/test-sahpool-worker.sqlite3');
107+
throw new Error('Opening DB should have failed while VFS is paused');
108+
} catch (e) {
109+
// Expected error
110+
}
111+
112+
await opfsSahPool.unpauseVfs();
113+
if (opfsSahPool.isPaused()) {
114+
throw new Error('VFS should not be paused after unpauseVfs()');
115+
}
116+
117+
// Test that pauseVfs() throws if there are open file handles
118+
db = new opfsSahPool.OpfsSAHPoolDb('/test-sahpool-worker.sqlite3');
119+
try {
120+
opfsSahPool.pauseVfs();
121+
throw new Error('pauseVfs should have failed with open DB handles');
122+
} catch (e) {
123+
if (!e.message.includes('Cannot pause VFS')) {
124+
throw new Error(
125+
'pauseVfs failed with unexpected error: ' + e.message,
126+
);
127+
}
128+
}
129+
db.close();
130+
131+
// Now it should work again
132+
db = new opfsSahPool.OpfsSAHPoolDb('/test-sahpool-worker.sqlite3');
133+
const count2 = db.selectValue('SELECT count(*) FROM test');
134+
if (count2 !== 2) {
135+
throw new Error('Persistence check after unpause failed');
136+
}
69137

70138
self.postMessage({ type: 'success' });
71139
} finally {

0 commit comments

Comments
 (0)