@jterrazz/test 5.2.0 → 5.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +72 -72
- package/dist/index.cjs +1051 -1035
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +226 -199
- package/dist/index.d.ts +226 -199
- package/dist/index.js +1040 -1030
- package/dist/index.js.map +1 -1
- package/package.json +58 -54
package/README.md
CHANGED
|
@@ -12,16 +12,16 @@ npm install -D @jterrazz/test vitest
|
|
|
12
12
|
|
|
13
13
|
```typescript
|
|
14
14
|
// tests/setup/integration.specification.ts
|
|
15
|
-
import { afterAll } from
|
|
16
|
-
import { integration, postgres } from
|
|
17
|
-
import { createApp } from
|
|
15
|
+
import { afterAll } from 'vitest';
|
|
16
|
+
import { integration, postgres } from '@jterrazz/test';
|
|
17
|
+
import { createApp } from '../../src/app.js';
|
|
18
18
|
|
|
19
|
-
const db = postgres({ compose:
|
|
19
|
+
const db = postgres({ compose: 'db' });
|
|
20
20
|
|
|
21
21
|
export const spec = await integration({
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
services: [db],
|
|
23
|
+
app: () => createApp({ databaseUrl: db.connectionString }),
|
|
24
|
+
root: '../../',
|
|
25
25
|
});
|
|
26
26
|
|
|
27
27
|
afterAll(() => spec.cleanup());
|
|
@@ -29,21 +29,21 @@ afterAll(() => spec.cleanup());
|
|
|
29
29
|
|
|
30
30
|
```typescript
|
|
31
31
|
// tests/e2e/users/users.e2e.test.ts
|
|
32
|
-
import { spec } from
|
|
33
|
-
|
|
34
|
-
test(
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
32
|
+
import { spec } from '../../setup/integration.specification.js';
|
|
33
|
+
|
|
34
|
+
test('creates a user', async () => {
|
|
35
|
+
// Given — one existing user
|
|
36
|
+
const result = await spec('creates user')
|
|
37
|
+
.seed('initial-users.sql')
|
|
38
|
+
.post('/users', 'new-user.json')
|
|
39
|
+
.run();
|
|
40
|
+
|
|
41
|
+
// Then — user created
|
|
42
|
+
expect(result.status).toBe(201);
|
|
43
|
+
await result.table('users').toMatch({
|
|
44
|
+
columns: ['name'],
|
|
45
|
+
rows: [['Alice'], ['Bob']],
|
|
46
|
+
});
|
|
47
47
|
});
|
|
48
48
|
```
|
|
49
49
|
|
|
@@ -51,29 +51,29 @@ test("creates a user", async () => {
|
|
|
51
51
|
|
|
52
52
|
```typescript
|
|
53
53
|
// tests/setup/cli.specification.ts
|
|
54
|
-
import { resolve } from
|
|
55
|
-
import { cli } from
|
|
54
|
+
import { resolve } from 'node:path';
|
|
55
|
+
import { cli } from '@jterrazz/test';
|
|
56
56
|
|
|
57
57
|
export const spec = await cli({
|
|
58
|
-
|
|
59
|
-
|
|
58
|
+
command: resolve(import.meta.dirname, '../../bin/my-cli.sh'),
|
|
59
|
+
root: '../fixtures',
|
|
60
60
|
});
|
|
61
61
|
```
|
|
62
62
|
|
|
63
63
|
```typescript
|
|
64
64
|
// tests/e2e/build/build.e2e.test.ts
|
|
65
|
-
import { spec } from
|
|
66
|
-
|
|
67
|
-
test(
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
65
|
+
import { spec } from '../../setup/cli.specification.js';
|
|
66
|
+
|
|
67
|
+
test('builds the project', async () => {
|
|
68
|
+
// Given — sample app project
|
|
69
|
+
const result = await spec('build').project('sample-app').exec('build').run();
|
|
70
|
+
|
|
71
|
+
// Then — ESM output with source maps
|
|
72
|
+
expect(result.exitCode).toBe(0);
|
|
73
|
+
expect(result.stdout).toContain('Build completed');
|
|
74
|
+
expect(result.file('dist/index.js').exists).toBe(true);
|
|
75
|
+
expect(result.file('dist/index.cjs').exists).toBe(false);
|
|
76
|
+
expect(result.file('dist/index.js').content).toContain('Hello');
|
|
77
77
|
});
|
|
78
78
|
```
|
|
79
79
|
|
|
@@ -86,15 +86,15 @@ Three modes, same builder API. Each handles infrastructure and cleanup automatic
|
|
|
86
86
|
Starts real containers via testcontainers. App runs in-process (Hono). Fastest feedback loop.
|
|
87
87
|
|
|
88
88
|
```typescript
|
|
89
|
-
import { integration, postgres, redis } from
|
|
89
|
+
import { integration, postgres, redis } from '@jterrazz/test';
|
|
90
90
|
|
|
91
|
-
const db = postgres({ compose:
|
|
92
|
-
const cache = redis({ compose:
|
|
91
|
+
const db = postgres({ compose: 'db' });
|
|
92
|
+
const cache = redis({ compose: 'cache' });
|
|
93
93
|
|
|
94
94
|
export const spec = await integration({
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
95
|
+
services: [db, cache],
|
|
96
|
+
app: () => createApp({ databaseUrl: db.connectionString }),
|
|
97
|
+
root: '../../',
|
|
98
98
|
});
|
|
99
99
|
```
|
|
100
100
|
|
|
@@ -103,10 +103,10 @@ export const spec = await integration({
|
|
|
103
103
|
Starts the full `docker/compose.test.yaml` stack. App URL and databases auto-detected.
|
|
104
104
|
|
|
105
105
|
```typescript
|
|
106
|
-
import { e2e } from
|
|
106
|
+
import { e2e } from '@jterrazz/test';
|
|
107
107
|
|
|
108
108
|
export const spec = await e2e({
|
|
109
|
-
|
|
109
|
+
root: '../../',
|
|
110
110
|
});
|
|
111
111
|
```
|
|
112
112
|
|
|
@@ -115,18 +115,18 @@ export const spec = await e2e({
|
|
|
115
115
|
Runs CLI commands against fixture projects in temp directories. Optionally starts infrastructure.
|
|
116
116
|
|
|
117
117
|
```typescript
|
|
118
|
-
import { cli } from
|
|
118
|
+
import { cli } from '@jterrazz/test';
|
|
119
119
|
|
|
120
120
|
export const spec = await cli({
|
|
121
|
-
|
|
122
|
-
|
|
121
|
+
command: resolve(import.meta.dirname, '../../bin/my-cli.sh'),
|
|
122
|
+
root: '../fixtures',
|
|
123
123
|
});
|
|
124
124
|
|
|
125
125
|
// With infrastructure (CLI that needs a database)
|
|
126
126
|
export const spec = await cli({
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
127
|
+
command: 'my-migrate-tool',
|
|
128
|
+
root: '../fixtures',
|
|
129
|
+
services: [db],
|
|
130
130
|
});
|
|
131
131
|
```
|
|
132
132
|
|
|
@@ -200,10 +200,10 @@ Run with `JTERRAZZ_TEST_UPDATE=1` (or vitest `-u`) to overwrite fixtures with th
|
|
|
200
200
|
**Grep (scoped text matching):**
|
|
201
201
|
|
|
202
202
|
```typescript
|
|
203
|
-
import { grep } from
|
|
203
|
+
import { grep } from '@jterrazz/test';
|
|
204
204
|
|
|
205
|
-
expect(grep(result.stdout,
|
|
206
|
-
expect(grep(result.stdout,
|
|
205
|
+
expect(grep(result.stdout, 'unused-var.ts')).toContain('no-unused-vars');
|
|
206
|
+
expect(grep(result.stdout, 'valid/sorted.ts')).not.toContain('sort-imports');
|
|
207
207
|
```
|
|
208
208
|
|
|
209
209
|
`grep(output, pattern)` filters multi-line output to the block matching `pattern`, returning a string for vitest assertions.
|
|
@@ -253,10 +253,10 @@ await result.table("events", { service: "analytics-db" }).toMatch({
|
|
|
253
253
|
## Service factories
|
|
254
254
|
|
|
255
255
|
```typescript
|
|
256
|
-
import { postgres, redis } from
|
|
256
|
+
import { postgres, redis } from '@jterrazz/test';
|
|
257
257
|
|
|
258
|
-
const db = postgres({ compose:
|
|
259
|
-
const cache = redis({ compose:
|
|
258
|
+
const db = postgres({ compose: 'db' });
|
|
259
|
+
const cache = redis({ compose: 'cache' });
|
|
260
260
|
```
|
|
261
261
|
|
|
262
262
|
Service handles read image and environment from `docker/compose.test.yaml`. After the runner starts, `.connectionString` is populated from the running container.
|
|
@@ -269,7 +269,7 @@ Service handles read image and environment from `docker/compose.test.yaml`. Afte
|
|
|
269
269
|
## Mocking utilities
|
|
270
270
|
|
|
271
271
|
```typescript
|
|
272
|
-
import { mockOf, mockOfDate } from
|
|
272
|
+
import { mockOf, mockOfDate } from '@jterrazz/test';
|
|
273
273
|
```
|
|
274
274
|
|
|
275
275
|
| Export | Description |
|
|
@@ -320,19 +320,19 @@ tests/
|
|
|
320
320
|
Every test uses `// Given` and `// Then` comments. Always both, never one without the other.
|
|
321
321
|
|
|
322
322
|
```typescript
|
|
323
|
-
test(
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
323
|
+
test('creates a user and returns 201', async () => {
|
|
324
|
+
// Given — two existing users
|
|
325
|
+
const result = await spec('creates user')
|
|
326
|
+
.seed('initial-users.sql')
|
|
327
|
+
.post('/users', 'new-user.json')
|
|
328
|
+
.run();
|
|
329
|
+
|
|
330
|
+
// Then — user created with all three in table
|
|
331
|
+
expect(result.status).toBe(201);
|
|
332
|
+
await result.table('users').toMatch({
|
|
333
|
+
columns: ['name'],
|
|
334
|
+
rows: [['Alice'], ['Bob'], ['Charlie']],
|
|
335
|
+
});
|
|
336
336
|
});
|
|
337
337
|
```
|
|
338
338
|
|