Skip to content

Commit 1499940

Browse files
committed
03/02(wip): add auto fixture example
1 parent a160138 commit 1499940

File tree

7 files changed

+1468
-23
lines changed

7 files changed

+1468
-23
lines changed

exercises/03.context/02.solution.automatic-fixtures/package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,8 @@
99
"devDependencies": {
1010
"vite": "^6.0.7",
1111
"vitest": "^3.0.5"
12+
},
13+
"dependencies": {
14+
"sqlite3": "^5.1.7"
1215
}
1316
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import sqlite3, { type Database } from 'sqlite3'
2+
3+
export class DatabaseClient {
4+
constructor(private readonly db: Database) {}
5+
6+
public async query(query: string, params: Array<unknown>): Promise<any> {
7+
return new Promise((resolve, reject) => {
8+
this.db.get(query, params, function (error, row) {
9+
if (error) {
10+
return reject(error)
11+
}
12+
13+
resolve(row)
14+
})
15+
})
16+
}
17+
}
18+
19+
export const client = new DatabaseClient(new sqlite3.Database(':memory:'))
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { test } from '../test-extend'
2+
3+
test('throws if the user is not found', async () => {
4+
const { queryUser } = await import('./query-user')
5+
6+
await expect(queryUser('abc-123')).resolves.toBeUndefined()
7+
})
8+
9+
test('returns the user by id', async ({ createMockDatabase }) => {
10+
const { queryUser } = await import('./query-user')
11+
12+
await createMockDatabase((db, done) => {
13+
db.run(
14+
'INSERT INTO users (id, name) VALUES (?, ?)',
15+
['abc-123', 'John Doe'],
16+
done,
17+
)
18+
})
19+
20+
await expect(queryUser('abc-123')).resolves.toEqual({
21+
id: 'abc-123',
22+
name: 'John Doe',
23+
})
24+
})
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { client } from './db'
2+
3+
export interface User {
4+
id: string
5+
name: string
6+
}
7+
8+
export async function queryUser(id: string): Promise<User> {
9+
return await client.query(`SELECT * FROM users WHERE id = ?`, [id])
10+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import { test as testBase } from 'vitest'
2+
import sqlite3, { type Database } from 'sqlite3'
3+
4+
interface Fixtures {
5+
createMockDatabase: (
6+
init: (database: Database, done: () => void) => void,
7+
) => Promise<void>
8+
}
9+
10+
export const test = testBase.extend<Fixtures>({
11+
createMockDatabase: [
12+
async ({ task }, use) => {
13+
const db = new sqlite3.Database(':memory:')
14+
15+
vi.doMock(import('./src/db'), async (importOriginal) => {
16+
const original = await importOriginal()
17+
const mockClient = new original.DatabaseClient(db)
18+
19+
return {
20+
...original,
21+
client: mockClient,
22+
}
23+
})
24+
25+
await new Promise<void>((resolve) => {
26+
db.serialize(() => {
27+
db.run('CREATE TABLE users (id TEXT, name TEXT)', resolve)
28+
})
29+
})
30+
31+
await use((initDatabase) => {
32+
return new Promise((resolve) => {
33+
initDatabase(db, resolve)
34+
})
35+
})
36+
37+
await new Promise<void>((resolve) => {
38+
db.close(() => resolve())
39+
})
40+
vi.doUnmock(import('./src/db'))
41+
},
42+
{
43+
auto: true,
44+
},
45+
],
46+
})

exercises/03.context/02.solution.automatic-fixtures/tsconfig.test.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"extends": "./tsconfig.app.json",
3-
"include": ["src/**/*", "src/**/*.test.ts*"],
3+
"include": ["test-extend.ts", "src/**/*", "src/**/*.test.ts*"],
44
"exclude": [],
55
"compilerOptions": {
66
"types": ["vitest/globals"]

0 commit comments

Comments
 (0)