Skip to content

Commit 527ad25

Browse files
committed
test robustness
1 parent 619f01f commit 527ad25

File tree

6 files changed

+139
-68
lines changed

6 files changed

+139
-68
lines changed

bindings/test/config.test.ts

Lines changed: 78 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -25,59 +25,92 @@ suite('config', () => {
2525
});
2626
test('default duckdb_api without explicit config', async () => {
2727
const db = await duckdb.open();
28-
const connection = await duckdb.connect(db);
29-
const result = await duckdb.query(
30-
connection,
31-
`select current_setting('duckdb_api') as duckdb_api`,
32-
);
33-
await expectResult(result, {
34-
chunkCount: 1,
35-
rowCount: 1,
36-
columns: [
37-
{ name: 'duckdb_api', logicalType: { typeId: duckdb.Type.VARCHAR } },
38-
],
39-
chunks: [
40-
{ rowCount: 1, vectors: [data(16, [true], ['node-neo-bindings'])] },
41-
],
42-
});
28+
try {
29+
const connection = await duckdb.connect(db);
30+
try {
31+
const result = await duckdb.query(
32+
connection,
33+
`select current_setting('duckdb_api') as duckdb_api`,
34+
);
35+
await expectResult(result, {
36+
chunkCount: 1,
37+
rowCount: 1,
38+
columns: [
39+
{
40+
name: 'duckdb_api',
41+
logicalType: { typeId: duckdb.Type.VARCHAR },
42+
},
43+
],
44+
chunks: [
45+
{ rowCount: 1, vectors: [data(16, [true], ['node-neo-bindings'])] },
46+
],
47+
});
48+
} finally {
49+
duckdb.disconnect_sync(connection);
50+
}
51+
} finally {
52+
duckdb.close_sync(db);
53+
}
4354
});
4455
test('default duckdb_api with explicit config', async () => {
4556
const config = duckdb.create_config();
4657
const db = await duckdb.open(undefined, config);
47-
const connection = await duckdb.connect(db);
48-
const result = await duckdb.query(
49-
connection,
50-
`select current_setting('duckdb_api') as duckdb_api`,
51-
);
52-
await expectResult(result, {
53-
chunkCount: 1,
54-
rowCount: 1,
55-
columns: [
56-
{ name: 'duckdb_api', logicalType: { typeId: duckdb.Type.VARCHAR } },
57-
],
58-
chunks: [
59-
{ rowCount: 1, vectors: [data(16, [true], ['node-neo-bindings'])] },
60-
],
61-
});
58+
try {
59+
const connection = await duckdb.connect(db);
60+
try {
61+
const result = await duckdb.query(
62+
connection,
63+
`select current_setting('duckdb_api') as duckdb_api`,
64+
);
65+
await expectResult(result, {
66+
chunkCount: 1,
67+
rowCount: 1,
68+
columns: [
69+
{
70+
name: 'duckdb_api',
71+
logicalType: { typeId: duckdb.Type.VARCHAR },
72+
},
73+
],
74+
chunks: [
75+
{ rowCount: 1, vectors: [data(16, [true], ['node-neo-bindings'])] },
76+
],
77+
});
78+
} finally {
79+
duckdb.disconnect_sync(connection);
80+
}
81+
} finally {
82+
duckdb.close_sync(db);
83+
}
6284
});
6385
test('overriding duckdb_api', async () => {
6486
const config = duckdb.create_config();
6587
duckdb.set_config(config, 'duckdb_api', 'custom-duckdb-api');
6688
const db = await duckdb.open(undefined, config);
67-
const connection = await duckdb.connect(db);
68-
const result = await duckdb.query(
69-
connection,
70-
`select current_setting('duckdb_api') as duckdb_api`,
71-
);
72-
await expectResult(result, {
73-
chunkCount: 1,
74-
rowCount: 1,
75-
columns: [
76-
{ name: 'duckdb_api', logicalType: { typeId: duckdb.Type.VARCHAR } },
77-
],
78-
chunks: [
79-
{ rowCount: 1, vectors: [data(16, [true], ['custom-duckdb-api'])] },
80-
],
81-
});
89+
try {
90+
const connection = await duckdb.connect(db);
91+
try {
92+
const result = await duckdb.query(
93+
connection,
94+
`select current_setting('duckdb_api') as duckdb_api`,
95+
);
96+
await expectResult(result, {
97+
chunkCount: 1,
98+
rowCount: 1,
99+
columns: [
100+
{
101+
name: 'duckdb_api',
102+
logicalType: { typeId: duckdb.Type.VARCHAR },
103+
},
104+
],
105+
chunks: [
106+
{ rowCount: 1, vectors: [data(16, [true], ['custom-duckdb-api'])] },
107+
],
108+
});
109+
} finally {
110+
duckdb.disconnect_sync(connection);
111+
}
112+
} finally {
113+
duckdb.close_sync(db);
114+
}
82115
});
83116
});

bindings/test/errors.test.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
import duckdb from '@duckdb/node-bindings';
22
import { expect, suite, test } from 'vitest';
3+
import { withDatabase } from './utils/withDatabase';
34

45
suite('errors', () => {
56
test('wrong external type', async () => {
6-
const db = await duckdb.open();
7-
expect(() => duckdb.query(db as unknown as duckdb.Connection, 'select 1')).toThrowError(/^Invalid connection argument$/);
7+
await withDatabase({}, async (db) => {
8+
expect(() =>
9+
duckdb.query(db as unknown as duckdb.Connection, 'select 1'),
10+
).toThrowError(/^Invalid connection argument$/);
11+
});
812
});
913
});

bindings/test/open.test.ts

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,29 +4,42 @@ import { expect, suite, test } from 'vitest';
44
suite('open', () => {
55
test('no args', async () => {
66
const db = await duckdb.open();
7-
expect(db).toBeTruthy();
8-
duckdb.close_sync(db);
7+
try {
8+
expect(db).toBeTruthy();
9+
} finally {
10+
duckdb.close_sync(db);
11+
}
912
});
1013
test('memory arg', async () => {
1114
const db = await duckdb.open(':memory:');
12-
expect(db).toBeTruthy();
13-
duckdb.close_sync(db);
15+
try {
16+
expect(db).toBeTruthy();
17+
} finally {
18+
duckdb.close_sync(db);
19+
}
1420
});
1521
test('with config', async () => {
1622
const config = duckdb.create_config();
1723
duckdb.set_config(config, 'custom_user_agent', 'my_user_agent');
1824
const db = await duckdb.open(':memory:', config);
19-
expect(db).toBeTruthy();
20-
duckdb.close_sync(db);
25+
try {
26+
expect(db).toBeTruthy();
27+
} finally {
28+
duckdb.close_sync(db);
29+
}
2130
});
2231
test('close', async () => {
2332
const db = await duckdb.open();
24-
expect(db).toBeTruthy();
25-
duckdb.close_sync(db);
26-
await expect(async () => await duckdb.connect(db)).rejects.toStrictEqual(
27-
new Error('Failed to connect: instance closed')
28-
);
29-
// double-close should be a no-op
30-
duckdb.close_sync(db);
33+
try {
34+
expect(db).toBeTruthy();
35+
duckdb.close_sync(db);
36+
await expect(async () => await duckdb.connect(db)).rejects.toStrictEqual(
37+
new Error('Failed to connect: instance closed'),
38+
);
39+
// double-close should be a no-op
40+
duckdb.close_sync(db);
41+
} finally {
42+
duckdb.close_sync(db);
43+
}
3144
});
3245
});

bindings/test/scalar_functions.test.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@ suite('scalar functions', () => {
229229

230230
await expect(
231231
duckdb.query(connection, 'select my_func()'),
232-
).rejects.toThrow('Invalid Input Error: my_error');
232+
).rejects.toThrow('my_error');
233233
});
234234
});
235235
test('error handling (set error in main func)', async () => {
@@ -249,7 +249,7 @@ suite('scalar functions', () => {
249249

250250
await expect(
251251
duckdb.query(connection, 'select my_func()'),
252-
).rejects.toThrow('Invalid Input Error: my_error');
252+
).rejects.toThrow('my_error');
253253
});
254254
});
255255
test('error handling (exception in bind func)', async () => {
@@ -272,7 +272,7 @@ suite('scalar functions', () => {
272272

273273
await expect(
274274
duckdb.query(connection, 'select my_func()'),
275-
).rejects.toThrow('Binder Error: my_bind_error');
275+
).rejects.toThrow('my_bind_error');
276276
});
277277
});
278278
test('error handling (set error in bind func)', async () => {
@@ -295,7 +295,7 @@ suite('scalar functions', () => {
295295

296296
await expect(
297297
duckdb.query(connection, 'select my_func()'),
298-
).rejects.toThrow('Binder Error: my_bind_error');
298+
).rejects.toThrow('my_bind_error');
299299
});
300300
});
301301
test('parameters (fixed, volatile)', async () => {
Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,15 @@
11
import duckdb from '@duckdb/node-bindings';
2+
import { withDatabase } from './withDatabase';
23

3-
export async function withConnection(fn: (connection: duckdb.Connection) => Promise<void>): Promise<void> {
4-
const db = await duckdb.open();
5-
const connection = await duckdb.connect(db);
6-
await fn(connection);
4+
export async function withConnection(
5+
fn: (connection: duckdb.Connection, db: duckdb.Database) => Promise<void>,
6+
): Promise<void> {
7+
await withDatabase({}, async (db) => {
8+
const connection = await duckdb.connect(db);
9+
try {
10+
await fn(connection, db);
11+
} finally {
12+
duckdb.disconnect_sync(connection);
13+
}
14+
});
715
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import duckdb from '@duckdb/node-bindings';
2+
3+
export async function withDatabase(
4+
{ path, config }: { path?: string; config?: duckdb.Config },
5+
fn: (db: duckdb.Database) => Promise<void>,
6+
): Promise<void> {
7+
const db = await duckdb.open(path, config);
8+
try {
9+
await fn(db);
10+
} finally {
11+
duckdb.close_sync(db);
12+
}
13+
}

0 commit comments

Comments
 (0)