@jterrazz/test 3.0.0 → 3.2.0
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 +109 -60
- package/dist/assets/cpufeatures-B-FC6C9Z.node +0 -0
- package/dist/assets/sshcrypto-D82met6T.node +0 -0
- package/dist/build.cjs +122200 -0
- package/dist/build.cjs.map +1 -0
- package/dist/build.js +122193 -0
- package/dist/build.js.map +1 -0
- package/dist/chunk.cjs +64 -0
- package/dist/chunk.js +37 -0
- package/dist/dist.cjs +6587 -0
- package/dist/dist.cjs.map +1 -0
- package/dist/dist.js +6582 -0
- package/dist/dist.js.map +1 -0
- package/dist/dist2.cjs +20838 -0
- package/dist/dist2.cjs.map +1 -0
- package/dist/dist2.js +20834 -0
- package/dist/dist2.js.map +1 -0
- package/dist/index.cjs +5129 -15
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +316 -0
- package/dist/index.d.ts +316 -2
- package/dist/index.js +5119 -2
- package/dist/index.js.map +1 -1
- package/package.json +37 -17
- package/dist/msw/main.d.ts +0 -2
- package/dist/msw/main.js +0 -4
- package/dist/msw/main.js.map +0 -1
- package/dist/vitest/main.d.ts +0 -9
- package/dist/vitest/main.js +0 -9
- package/dist/vitest/main.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,96 +1,145 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @jterrazz/test
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Testing framework for the @jterrazz ecosystem — declarative Docker infrastructure, specification runners, and conventions that all projects follow.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
7
|
-
Install the package using npm:
|
|
8
|
-
|
|
9
7
|
```bash
|
|
10
|
-
npm install -D @jterrazz/test
|
|
8
|
+
npm install -D @jterrazz/test vitest
|
|
11
9
|
```
|
|
12
10
|
|
|
13
|
-
|
|
11
|
+
Requires Docker.
|
|
14
12
|
|
|
15
|
-
|
|
13
|
+
## Specification runners
|
|
16
14
|
|
|
17
|
-
|
|
18
|
-
// handlers.ts
|
|
19
|
-
import { http } from 'msw';
|
|
20
|
-
import { setupServer } from '@jterrazz/test';
|
|
21
|
-
|
|
22
|
-
// Define your API handlers
|
|
23
|
-
const handlers = [
|
|
24
|
-
http.get('/api/example', () => {
|
|
25
|
-
return new Response(JSON.stringify({ data: 'example' }));
|
|
26
|
-
}),
|
|
27
|
-
];
|
|
28
|
-
|
|
29
|
-
// Setup MSW server
|
|
30
|
-
export const server = setupServer(...handlers);
|
|
31
|
-
```
|
|
15
|
+
Declare services, provide an app factory, the framework starts containers and wires everything.
|
|
32
16
|
|
|
33
|
-
|
|
17
|
+
### Integration (testcontainers, in-process app)
|
|
34
18
|
|
|
35
19
|
```typescript
|
|
36
|
-
|
|
37
|
-
import {
|
|
20
|
+
// tests/integration/integration.specification.ts
|
|
21
|
+
import { afterAll } from "vitest";
|
|
22
|
+
import { integration, postgres } from "@jterrazz/test";
|
|
23
|
+
import { createApp } from "../../src/app.js";
|
|
38
24
|
|
|
39
|
-
|
|
40
|
-
test('should handle API requests', async () => {
|
|
41
|
-
const response = await fetch('/api/example');
|
|
42
|
-
const data = await response.json();
|
|
25
|
+
const db = postgres({ compose: "db" });
|
|
43
26
|
|
|
44
|
-
|
|
45
|
-
|
|
27
|
+
export const spec = await integration({
|
|
28
|
+
services: [db],
|
|
29
|
+
app: () => createApp({ databaseUrl: db.connectionString }),
|
|
30
|
+
root: "../../",
|
|
46
31
|
});
|
|
32
|
+
|
|
33
|
+
afterAll(() => spec.cleanup());
|
|
47
34
|
```
|
|
48
35
|
|
|
49
|
-
|
|
36
|
+
### E2E (docker compose up, real HTTP)
|
|
50
37
|
|
|
51
38
|
```typescript
|
|
52
|
-
|
|
39
|
+
// tests/e2e/e2e.specification.ts
|
|
40
|
+
import { afterAll } from "vitest";
|
|
41
|
+
import { e2e } from "@jterrazz/test";
|
|
42
|
+
|
|
43
|
+
export const spec = await e2e({
|
|
44
|
+
root: "../../",
|
|
45
|
+
});
|
|
53
46
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
const fixedDate = new Date('2024-01-01');
|
|
57
|
-
mockOfDate.set(fixedDate);
|
|
47
|
+
afterAll(() => spec.cleanup());
|
|
48
|
+
```
|
|
58
49
|
|
|
59
|
-
|
|
50
|
+
### Usage
|
|
60
51
|
|
|
61
|
-
|
|
62
|
-
|
|
52
|
+
```typescript
|
|
53
|
+
import { spec } from "../integration.specification.js";
|
|
54
|
+
|
|
55
|
+
test("creates company", async () => {
|
|
56
|
+
const result = await spec("creates company")
|
|
57
|
+
.seed("transactions.sql")
|
|
58
|
+
.post("/api/analyze", "request.json")
|
|
59
|
+
.run();
|
|
60
|
+
|
|
61
|
+
result.expectStatus(201);
|
|
62
|
+
result.expectResponse("created.response.json");
|
|
63
|
+
await result.expectTable("company_profile", {
|
|
64
|
+
columns: ["name"],
|
|
65
|
+
rows: [["TEST COMPANY"]],
|
|
63
66
|
});
|
|
64
67
|
});
|
|
65
68
|
```
|
|
66
69
|
|
|
67
|
-
|
|
70
|
+
## Service factories
|
|
68
71
|
|
|
69
72
|
```typescript
|
|
70
|
-
import {
|
|
73
|
+
import { postgres, redis } from "@jterrazz/test";
|
|
71
74
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
+
const db = postgres({ compose: "db" }); // Reads config from docker/compose.test.yaml
|
|
76
|
+
const cache = redis({ compose: "cache" });
|
|
77
|
+
```
|
|
75
78
|
|
|
76
|
-
|
|
77
|
-
test('should use extended mocks', async () => {
|
|
78
|
-
const mockUserService = mockOf<UserService>();
|
|
79
|
+
After `await integration()`, service handles have `.connectionString` populated from running containers.
|
|
79
80
|
|
|
80
|
-
|
|
81
|
-
mockUserService.getUser.mockResolvedValue({ id: '1', name: 'John' });
|
|
81
|
+
## Docker convention
|
|
82
82
|
|
|
83
|
-
const user = await mockUserService.getUser('1');
|
|
84
|
-
expect(user).toEqual({ id: '1', name: 'John' });
|
|
85
|
-
});
|
|
86
|
-
});
|
|
87
83
|
```
|
|
84
|
+
docker/
|
|
85
|
+
├── compose.test.yaml # Source of truth for test infrastructure
|
|
86
|
+
├── postgres/
|
|
87
|
+
│ └── init.sql # Auto-run on container start
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## Builder API
|
|
88
91
|
|
|
89
|
-
|
|
92
|
+
**Setup:** `.seed("file.sql")`, `.mock("file.json")`
|
|
90
93
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
94
|
+
**Action:** `.get(path)`, `.post(path, "body.json")`, `.put(path, "body.json")`, `.delete(path)`
|
|
95
|
+
|
|
96
|
+
**Assertions:** `.expectStatus(code)`, `.expectResponse("file.json")`, `.expectTable(table, { columns, rows })`
|
|
97
|
+
|
|
98
|
+
## Test structure
|
|
99
|
+
|
|
100
|
+
```
|
|
101
|
+
tests/
|
|
102
|
+
├── setup/ # Infrastructure (DB init, Docker config)
|
|
103
|
+
├── fixtures/ # Shared fake things to test against
|
|
104
|
+
├── helpers/ # Shared test utilities
|
|
105
|
+
├── integration/
|
|
106
|
+
│ ├── integration.specification.ts
|
|
107
|
+
│ └── api/
|
|
108
|
+
│ └── {feature}/
|
|
109
|
+
│ ├── {feature}.integration.test.ts
|
|
110
|
+
│ ├── seeds/
|
|
111
|
+
│ ├── requests/
|
|
112
|
+
│ └── responses/
|
|
113
|
+
└── e2e/
|
|
114
|
+
├── e2e.specification.ts
|
|
115
|
+
└── api/...
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## Test data (colocated per test)
|
|
119
|
+
|
|
120
|
+
| Folder | Purpose |
|
|
121
|
+
| ------------ | ---------------------------------- |
|
|
122
|
+
| `seeds/` | Database state setup |
|
|
123
|
+
| `mock/` | Mocked external API responses |
|
|
124
|
+
| `requests/` | Request bodies |
|
|
125
|
+
| `responses/` | Expected API responses |
|
|
126
|
+
| `expected/` | Expected output to compare against |
|
|
127
|
+
|
|
128
|
+
## File naming
|
|
129
|
+
|
|
130
|
+
| Type | Suffix | Location |
|
|
131
|
+
| ----------- | ---------------------- | --------------------- |
|
|
132
|
+
| Unit | `.test.ts` | Colocated with source |
|
|
133
|
+
| Integration | `.integration.test.ts` | `tests/integration/` |
|
|
134
|
+
| E2E | `.e2e.test.ts` | `tests/e2e/` |
|
|
135
|
+
|
|
136
|
+
## Mocking utilities
|
|
137
|
+
|
|
138
|
+
```typescript
|
|
139
|
+
import { mockOf, mockOfDate } from "@jterrazz/test";
|
|
140
|
+
```
|
|
95
141
|
|
|
96
|
-
|
|
142
|
+
| Export | Description |
|
|
143
|
+
| ------------- | ---------------------------------------- |
|
|
144
|
+
| `mockOfDate` | Date mocking — `set(date)` and `reset()` |
|
|
145
|
+
| `mockOf<T>()` | Deep mock of any interface |
|
|
Binary file
|
|
Binary file
|