@jterrazz/test 3.1.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 CHANGED
@@ -1,8 +1,6 @@
1
- *Hey there – I’m Jean-Baptiste, just another developer doing weird things with code. All my projects live on [jterrazz.com](https://jterrazz.com) – complete with backstories and lessons learned. Feel free to poke around – you might just find something useful!*
2
-
3
1
  # @jterrazz/test
4
2
 
5
- Mocking utilities for TypeScript testing.
3
+ Testing framework for the @jterrazz ecosystem — declarative Docker infrastructure, specification runners, and conventions that all projects follow.
6
4
 
7
5
  ## Installation
8
6
 
@@ -10,66 +8,138 @@ Mocking utilities for TypeScript testing.
10
8
  npm install -D @jterrazz/test vitest
11
9
  ```
12
10
 
13
- **Optional:** For API mocking with MSW:
11
+ Requires Docker.
14
12
 
15
- ```bash
16
- npm install -D msw
17
- ```
13
+ ## Specification runners
18
14
 
19
- ## Usage
15
+ Declare services, provide an app factory, the framework starts containers and wires everything.
20
16
 
21
- ### Date Mocking
17
+ ### Integration (testcontainers, in-process app)
22
18
 
23
19
  ```typescript
24
- import { describe, test, expect, afterEach } from 'vitest';
25
- import { mockOfDate } from '@jterrazz/test';
26
-
27
- describe('Date Tests', () => {
28
- afterEach(() => {
29
- mockOfDate.reset();
30
- });
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";
31
24
 
32
- test('should mock dates', () => {
33
- const fixedDate = new Date('2024-01-01');
34
- mockOfDate.set(fixedDate);
25
+ const db = postgres({ compose: "db" });
35
26
 
36
- expect(new Date()).toEqual(fixedDate);
37
- });
27
+ export const spec = await integration({
28
+ services: [db],
29
+ app: () => createApp({ databaseUrl: db.connectionString }),
30
+ root: "../../",
38
31
  });
32
+
33
+ afterAll(() => spec.cleanup());
39
34
  ```
40
35
 
41
- ### Deep Mocking
36
+ ### E2E (docker compose up, real HTTP)
42
37
 
43
38
  ```typescript
44
- import { describe, test, expect } from 'vitest';
45
- import { mockOf } from '@jterrazz/test';
39
+ // tests/e2e/e2e.specification.ts
40
+ import { afterAll } from "vitest";
41
+ import { e2e } from "@jterrazz/test";
46
42
 
47
- interface UserService {
48
- getUser: (id: string) => Promise<{ id: string; name: string }>;
49
- }
43
+ export const spec = await e2e({
44
+ root: "../../",
45
+ });
50
46
 
51
- describe('Mock Tests', () => {
52
- test('should use deep mocks', async () => {
53
- const mockUserService = mockOf<UserService>();
47
+ afterAll(() => spec.cleanup());
48
+ ```
54
49
 
55
- mockUserService.getUser.mockResolvedValue({ id: '1', name: 'John' });
50
+ ### Usage
56
51
 
57
- const user = await mockUserService.getUser('1');
58
- expect(user).toEqual({ id: '1', name: 'John' });
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"]],
59
66
  });
60
67
  });
61
68
  ```
62
69
 
63
- ## API
70
+ ## Service factories
71
+
72
+ ```typescript
73
+ import { postgres, redis } from "@jterrazz/test";
74
+
75
+ const db = postgres({ compose: "db" }); // Reads config from docker/compose.test.yaml
76
+ const cache = redis({ compose: "cache" });
77
+ ```
78
+
79
+ After `await integration()`, service handles have `.connectionString` populated from running containers.
64
80
 
65
- | Export | Description |
66
- |--------|-------------|
67
- | `mockOfDate` | Date mocking utilities (`set`, `reset`) |
68
- | `mockOf<T>()` | Create deep mock of any interface |
69
- | `MockDatePort` | Type interface for date mocking |
70
- | `MockPort` | Type interface for deep mocking |
81
+ ## Docker convention
71
82
 
72
- ## Peer Dependencies
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
91
+
92
+ **Setup:** `.seed("file.sql")`, `.mock("file.json")`
93
+
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
+ ```
73
141
 
74
- - `vitest` (required)
75
- - `msw` (optional)
142
+ | Export | Description |
143
+ | ------------- | ---------------------------------------- |
144
+ | `mockOfDate` | Date mocking — `set(date)` and `reset()` |
145
+ | `mockOf<T>()` | Deep mock of any interface |