@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 CHANGED
@@ -1,96 +1,145 @@
1
- # Package Typescript Test
1
+ # @jterrazz/test
2
2
 
3
- This package provides Vitest configuration and testing utilities for TypeScript projects, including MSW (Mock Service Worker) setup for API mocking.
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
- ## Usage
11
+ Requires Docker.
14
12
 
15
- 1. Set up MSW for API mocking:
13
+ ## Specification runners
16
14
 
17
- ```typescript
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
- 2. You can now write your tests using Vitest and MSW!
17
+ ### Integration (testcontainers, in-process app)
34
18
 
35
19
  ```typescript
36
- import { describe, test, expect } from '@jterrazz/test';
37
- import { server } from './handlers';
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
- describe('API Tests', () => {
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
- expect(data).toEqual({ data: 'example' });
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
- 3. Using Date Mocking:
36
+ ### E2E (docker compose up, real HTTP)
50
37
 
51
38
  ```typescript
52
- import { mockOfDate } from '@jterrazz/test';
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
- describe('Date Tests', () => {
55
- test('should mock dates', () => {
56
- const fixedDate = new Date('2024-01-01');
57
- mockOfDate.set(fixedDate);
47
+ afterAll(() => spec.cleanup());
48
+ ```
58
49
 
59
- expect(new Date()).toEqual(fixedDate);
50
+ ### Usage
60
51
 
61
- // Reset the mock after your test
62
- mockOfDate.reset();
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
- 4. Using Extended Mocking:
70
+ ## Service factories
68
71
 
69
72
  ```typescript
70
- import { mockOf } from '@jterrazz/test';
73
+ import { postgres, redis } from "@jterrazz/test";
71
74
 
72
- interface UserService {
73
- getUser: (id: string) => Promise<{ id: string; name: string }>;
74
- }
75
+ const db = postgres({ compose: "db" }); // Reads config from docker/compose.test.yaml
76
+ const cache = redis({ compose: "cache" });
77
+ ```
75
78
 
76
- describe('Mock Tests', () => {
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
- // Setup mock behavior
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
- ## Features
92
+ **Setup:** `.seed("file.sql")`, `.mock("file.json")`
90
93
 
91
- - Vitest configuration with TypeScript support
92
- - MSW integration for API mocking
93
- - Mock date utilities for time-based testing
94
- - Extended mocking capabilities with vitest-mock-extended
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
- Happy testing! 🚀
142
+ | Export | Description |
143
+ | ------------- | ---------------------------------------- |
144
+ | `mockOfDate` | Date mocking — `set(date)` and `reset()` |
145
+ | `mockOf<T>()` | Deep mock of any interface |