@jterrazz/test 4.0.1 → 5.1.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 +68 -48
- package/dist/index.cjs +410 -268
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +178 -109
- package/dist/index.d.ts +178 -109
- package/dist/index.js +410 -271
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -39,7 +39,7 @@ test("creates a user", async () => {
|
|
|
39
39
|
.run();
|
|
40
40
|
|
|
41
41
|
// Then — user created
|
|
42
|
-
result.status.toBe(201);
|
|
42
|
+
expect(result.status).toBe(201);
|
|
43
43
|
await result.table("users").toMatch({
|
|
44
44
|
columns: ["name"],
|
|
45
45
|
rows: [["Alice"], ["Bob"]],
|
|
@@ -69,11 +69,11 @@ test("builds the project", async () => {
|
|
|
69
69
|
const result = await spec("build").project("sample-app").exec("build").run();
|
|
70
70
|
|
|
71
71
|
// Then — ESM output with source maps
|
|
72
|
-
result.exitCode.toBe(0);
|
|
73
|
-
result.stdout.toContain("Build completed");
|
|
74
|
-
result.file("dist/index.js").
|
|
75
|
-
result.file("dist/index.cjs").
|
|
76
|
-
result.file("dist/index.js").toContain("Hello");
|
|
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
|
|
|
@@ -157,50 +157,69 @@ Every test follows the same pattern: `spec("label") → setup → action → ass
|
|
|
157
157
|
|
|
158
158
|
**CLI:**
|
|
159
159
|
|
|
160
|
-
| Method | Description
|
|
161
|
-
| -------------------------------------- |
|
|
162
|
-
| `.exec("args")` | Run command (blocking)
|
|
163
|
-
| `.exec(["build", "start"])` | Run commands sequentially in same directory
|
|
164
|
-
| `.spawn("args", { waitFor, timeout })` | Run long-lived process, resolve on pattern match or timeout
|
|
160
|
+
| Method | Description |
|
|
161
|
+
| -------------------------------------- | ------------------------------------------------------------------------------------- |
|
|
162
|
+
| `.exec("args")` | Run command (blocking) |
|
|
163
|
+
| `.exec(["build", "start"])` | Run commands sequentially in same directory |
|
|
164
|
+
| `.spawn("args", { waitFor, timeout })` | Run long-lived process, resolve on pattern match or timeout |
|
|
165
|
+
| `.env({ KEY: "value" })` | Set env vars on the child process (`null` unsets, `$WORKDIR` expands to the temp cwd) |
|
|
165
166
|
|
|
166
167
|
### Assertions
|
|
167
168
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
**
|
|
171
|
-
|
|
172
|
-
|
|
|
173
|
-
|
|
|
174
|
-
| `result.
|
|
175
|
-
| `result.
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
|
182
|
-
|
|
|
183
|
-
| `result.
|
|
184
|
-
| `result.
|
|
185
|
-
| `result.
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
|
190
|
-
|
|
|
191
|
-
| `result.
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
169
|
+
Result properties are raw values — use vitest `expect()` for assertions. Database and response file assertions use custom async methods.
|
|
170
|
+
|
|
171
|
+
**Raw values (vitest expect):**
|
|
172
|
+
|
|
173
|
+
| Expression | Description |
|
|
174
|
+
| -------------------------------------------- | --------------------------- |
|
|
175
|
+
| `expect(result.exitCode).toBe(0)` | CLI exit code |
|
|
176
|
+
| `expect(result.status).toBe(201)` | HTTP status code |
|
|
177
|
+
| `expect(result.stdout).toContain("hello")` | CLI stdout contains string |
|
|
178
|
+
| `expect(result.stderr).not.toContain("err")` | CLI stderr does not contain |
|
|
179
|
+
|
|
180
|
+
**Files (result.file returns {exists, content}):**
|
|
181
|
+
|
|
182
|
+
| Expression | Description |
|
|
183
|
+
| ----------------------------------------------------------------- | --------------------------- |
|
|
184
|
+
| `expect(result.file("dist/index.js").exists).toBe(true)` | Assert file exists |
|
|
185
|
+
| `expect(result.file("dist/index.js").content).toContain("Hello")` | Assert file contains string |
|
|
186
|
+
| `expect(result.file("dist/index.cjs").exists).toBe(false)` | Assert file does not exist |
|
|
187
|
+
|
|
188
|
+
**Directories (CLI scaffolding / codegen output):**
|
|
189
|
+
|
|
190
|
+
| Expression | Description |
|
|
191
|
+
| ----------------------------------------------------------------- | ------------------------------------------------------------------------------ |
|
|
192
|
+
| `await result.directory("out").toMatchFixture("go-api")` | Snapshot the tree against `expected/go-api/`, structured diff on mismatch |
|
|
193
|
+
| `await result.directory().toMatchFixture("scaffold", { ignore })` | Pass extra ignore patterns; defaults already skip `.git`, `node_modules`, etc. |
|
|
194
|
+
| `await result.directory("out").files()` | List all files (recursive, sorted) for ad-hoc assertions |
|
|
195
|
+
|
|
196
|
+
Run with `JTERRAZZ_TEST_UPDATE=1` (or vitest `-u`) to overwrite fixtures with the current output. Fixtures live at `{test}/expected/{name}/` — same convention as `responses/` for HTTP bodies.
|
|
197
|
+
|
|
198
|
+
**Grep (scoped text matching):**
|
|
199
|
+
|
|
200
|
+
```typescript
|
|
201
|
+
import { grep } from "@jterrazz/test";
|
|
202
|
+
|
|
203
|
+
expect(grep(result.stdout, "unused-var.ts")).toContain("no-unused-vars");
|
|
204
|
+
expect(grep(result.stdout, "valid/sorted.ts")).not.toContain("sort-imports");
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
`grep(output, pattern)` filters multi-line output to the block matching `pattern`, returning a string for vitest assertions.
|
|
208
|
+
|
|
209
|
+
**Response (HTTP body):**
|
|
210
|
+
|
|
211
|
+
| Expression | Description |
|
|
212
|
+
| ----------------------------------------------- | --------------------------------------------------------------------------- |
|
|
213
|
+
| `result.response.toMatchFile("expected.json")` | Custom — compares body to `responses/expected.json`, shows diff on mismatch |
|
|
214
|
+
| `expect(result.response.body).toEqual({ ... })` | Raw body object for vitest assertions |
|
|
215
|
+
|
|
216
|
+
**Tables (custom async — database queries):**
|
|
217
|
+
|
|
218
|
+
| Expression | Description |
|
|
219
|
+
| ------------------------------------------------------------------------------- | ------------------------------ |
|
|
220
|
+
| `await result.table("users").toMatch({ columns: ["name"], rows: [["Alice"]] })` | Assert database table contents |
|
|
221
|
+
| `await result.table("events", { service: "analytics-db" }).toMatch({ ... })` | Assert on a specific database |
|
|
222
|
+
| `await result.table("users").toBeEmpty()` | Assert database table is empty |
|
|
204
223
|
|
|
205
224
|
## Multi-database support
|
|
206
225
|
|
|
@@ -221,6 +240,7 @@ const result = await spec("cross-db")
|
|
|
221
240
|
.post("/users", "request.json")
|
|
222
241
|
.run();
|
|
223
242
|
|
|
243
|
+
expect(result.status).toBe(201);
|
|
224
244
|
await result.table("users").toMatch({ columns: ["name"], rows: [["Alice"]] });
|
|
225
245
|
await result.table("events", { service: "analytics-db" }).toMatch({
|
|
226
246
|
columns: ["type"],
|
|
@@ -306,7 +326,7 @@ test("creates a user and returns 201", async () => {
|
|
|
306
326
|
.run();
|
|
307
327
|
|
|
308
328
|
// Then — user created with all three in table
|
|
309
|
-
result.status.toBe(201);
|
|
329
|
+
expect(result.status).toBe(201);
|
|
310
330
|
await result.table("users").toMatch({
|
|
311
331
|
columns: ["name"],
|
|
312
332
|
rows: [["Alice"], ["Bob"], ["Charlie"]],
|