0
# Test Result Assertions
1
2
The RunResult class provides comprehensive assertion utilities for verifying file creation, content validation, JSON structure testing, and generator behavior. It supports both individual and batch operations with detailed error reporting and file system snapshot capabilities.
3
4
## Result Properties
5
6
The RunResult exposes several properties for advanced test inspection:
7
8
```typescript { .api }
9
interface RunResult<GeneratorType extends BaseGenerator> {
10
/** The generator instance that was tested */
11
generator: GeneratorType;
12
13
/** The Yeoman environment instance */
14
env: DefaultEnvironmentApi;
15
16
/** Current working directory after test */
17
cwd: string;
18
19
/** Original working directory before test */
20
oldCwd: string;
21
22
/** Memory file system store */
23
memFs: Store<MemFsEditorFile>;
24
25
/** Memory file system editor */
26
fs: MemFsEditor;
27
28
/** Mocked generators from the test context */
29
mockedGenerators: Record<string, BaseGenerator>;
30
31
/** Mock spawn stub if spawn mocking was used */
32
spawnStub?: any;
33
34
/** Questions asked during prompt simulation */
35
readonly askedQuestions: AskedQuestions;
36
37
/** Complete run options used for this result */
38
options: RunResultOptions<GeneratorType>;
39
}
40
```
41
42
## Capabilities
43
44
### File Existence Assertions
45
46
Verify that files and directories exist or don't exist after generator execution.
47
48
```typescript { .api }
49
/**
50
* Assert that a file exists
51
* @param path - Path to a file or array of paths
52
* @throws AssertionError if file doesn't exist
53
*/
54
assertFile(path: string | string[]): void;
55
56
/**
57
* Assert that a file doesn't exist
58
* @param files - Path to a file or array of paths
59
* @throws AssertionError if file exists
60
*/
61
assertNoFile(files: string | string[]): void;
62
```
63
64
**Usage Examples:**
65
66
```typescript
67
import { result } from "yeoman-test";
68
69
// Single file
70
result.assertFile("package.json");
71
result.assertNoFile("temp-file.txt");
72
73
// Multiple files
74
result.assertFile([
75
"src/index.ts",
76
"test/index.test.ts",
77
"README.md"
78
]);
79
80
result.assertNoFile([
81
"temp.log",
82
"debug.tmp"
83
]);
84
```
85
86
### File Content Assertions
87
88
Verify file contents match expected patterns, strings, or exact content.
89
90
```typescript { .api }
91
/**
92
* Assert that a file's content matches a regex or string
93
* @param file - Path to a file
94
* @param reg - Regex or string to search for
95
* @throws AssertionError if content doesn't match
96
*/
97
assertFileContent(file: string, reg: string | RegExp): void;
98
99
/**
100
* Assert multiple file-regex pairs
101
* @param pairs - Array of [file, regex] pairs
102
*/
103
assertFileContent(pairs: Array<[string, string | RegExp]>): void;
104
105
/**
106
* Assert that a file's content is exactly equal to the given string
107
* @param file - Path to a file
108
* @param expectedContent - Expected exact content
109
*/
110
assertEqualsFileContent(file: string, expectedContent: string): void;
111
112
/**
113
* Assert multiple file-content pairs for exact equality
114
* @param pairs - Array of [file, expectedContent] pairs
115
*/
116
assertEqualsFileContent(pairs: Array<[string, string]>): void;
117
118
/**
119
* Assert that a file's content does not match a regex or string
120
* @param file - Path to a file
121
* @param reg - Regex or string that should not be found
122
*/
123
assertNoFileContent(file: string, reg: RegExp | string): void;
124
125
/**
126
* Assert multiple file-regex pairs do not match
127
* @param pairs - Array of [file, regex] pairs
128
*/
129
assertNoFileContent(pairs: Array<[string, string | RegExp]>): void;
130
```
131
132
**Usage Examples:**
133
134
```typescript
135
// Pattern matching
136
result.assertFileContent("package.json", /"name": "my-app"/);
137
result.assertFileContent("src/index.ts", /export class MyApp/);
138
139
// String matching
140
result.assertFileContent("README.md", "# My Application");
141
142
// Multiple files
143
result.assertFileContent([
144
["package.json", /"version": "1\.0\.0"/],
145
["src/index.ts", /import.*express/]
146
]);
147
148
// Exact content matching
149
result.assertEqualsFileContent(
150
"config.json",
151
'{\n "env": "development"\n}'
152
);
153
154
// Negative assertions
155
result.assertNoFileContent("package.json", /debug/);
156
result.assertNoFileContent("src/index.ts", "console.log");
157
```
158
159
### JSON File Assertions
160
161
Specialized assertions for JSON file structure and content validation.
162
163
```typescript { .api }
164
/**
165
* Assert a JSON file contains the provided keys and values
166
* @param filename - Path to JSON file
167
* @param content - Object with expected key/value pairs
168
* @throws AssertionError if JSON doesn't contain expected content
169
*/
170
assertJsonFileContent(filename: string, content: Record<string, any>): void;
171
172
/**
173
* Assert a JSON file does not contain the provided keys and values
174
* @param filename - Path to JSON file
175
* @param content - Object with key/value pairs that should not exist
176
*/
177
assertNoJsonFileContent(filename: string, content: Record<string, any>): void;
178
```
179
180
**Usage Examples:**
181
182
```typescript
183
// Assert JSON structure
184
result.assertJsonFileContent("package.json", {
185
name: "my-app",
186
version: "1.0.0",
187
dependencies: {
188
express: "^4.18.0"
189
}
190
});
191
192
// Nested object assertions
193
result.assertJsonFileContent("config.json", {
194
database: {
195
host: "localhost",
196
port: 5432
197
}
198
});
199
200
// Negative JSON assertions
201
result.assertNoJsonFileContent("package.json", {
202
devDependencies: {
203
nodemon: "^2.0.0"
204
}
205
});
206
```
207
208
### Object Content Assertions
209
210
General object structure validation utilities used internally by JSON assertions.
211
212
```typescript { .api }
213
/**
214
* Assert an object contains the provided keys and values
215
* @param object - Object to check
216
* @param content - Expected key/value pairs
217
* @throws AssertionError if object doesn't contain expected content
218
*/
219
assertObjectContent(object: Record<string, unknown>, content: Record<string, any>): void;
220
221
/**
222
* Assert an object does not contain the provided keys and values
223
* @param object - Object to check
224
* @param content - Key/value pairs that should not exist
225
*/
226
assertNoObjectContent(object: Record<string, unknown>, content: Record<string, any>): void;
227
```
228
229
### Text Comparison Utilities
230
231
Utility for comparing text with normalized newlines.
232
233
```typescript { .api }
234
/**
235
* Assert that two strings are equal after standardization of newlines
236
* @param value - Actual string value
237
* @param expected - Expected string value
238
* @throws AssertionError if strings don't match after normalization
239
*/
240
assertTextEqual(value: string, expected: string): void;
241
```
242
243
**Usage Examples:**
244
245
```typescript
246
const actualContent = "Line 1\r\nLine 2\nLine 3";
247
const expectedContent = "Line 1\nLine 2\nLine 3";
248
249
result.assertTextEqual(actualContent, expectedContent); // Passes
250
```
251
252
### Generator Composition Assertions
253
254
Verify generator composition behavior when using mocked generators.
255
256
```typescript { .api }
257
/**
258
* Assert that a generator was composed (called) during execution
259
* @param generator - Namespace of the mocked generator
260
* @throws AssertionError if generator was not composed
261
*/
262
assertGeneratorComposed(generator: string): void;
263
264
/**
265
* Assert that a generator was not composed during execution
266
* @param generator - Namespace of the mocked generator
267
* @throws AssertionError if generator was composed
268
*/
269
assertGeneratorNotComposed(generator: string): void;
270
271
/**
272
* Assert that a generator was composed exactly once
273
* @param generator - Namespace of the mocked generator
274
* @throws AssertionError if generator was not composed exactly once
275
*/
276
assertGeneratorComposedOnce(generator: string): void;
277
278
/**
279
* Get the number of times a mocked generator was composed
280
* @param generator - Namespace of the mocked generator
281
* @returns Number of times the generator was composed
282
* @throws Error if generator is not mocked
283
*/
284
getGeneratorComposeCount(generator: string): number;
285
286
/**
287
* Get the generator mock object for detailed inspection
288
* @param generator - Namespace of the mocked generator
289
* @returns Mock object with call information
290
* @throws Error if generator is not mocked
291
*/
292
getGeneratorMock(generator: string): ReturnType<typeof mock.fn>['mock'];
293
294
/**
295
* Get array of all composed generator names
296
* @returns Array of generator namespaces that were composed
297
*/
298
getComposedGenerators(): string[];
299
```
300
301
**Usage Examples:**
302
303
```typescript
304
// Setup mocked generators in test
305
await helpers.run("my-generator")
306
.withMockedGenerators([
307
"sub:app",
308
"common:util",
309
"optional:feature"
310
]);
311
312
// Test composition behavior
313
result.assertGeneratorComposed("sub:app");
314
result.assertGeneratorComposedOnce("common:util");
315
result.assertGeneratorNotComposed("optional:feature");
316
317
// Detailed mock inspection
318
const composeCount = result.getGeneratorComposeCount("sub:app");
319
expect(composeCount).toBe(2);
320
321
const mock = result.getGeneratorMock("sub:app");
322
expect(mock.callCount()).toBe(2);
323
expect(mock.calls[0].arguments).toEqual([/* expected args */]);
324
325
// Get all composed generators
326
const composed = result.getComposedGenerators();
327
expect(composed).toEqual(["sub:app", "common:util"]);
328
```
329
330
### File System Snapshots
331
332
Capture and inspect the complete file system state after generator execution.
333
334
```typescript { .api }
335
/**
336
* Return an object with filesystem changes
337
* @param filter - Optional filter function passed to mem-fs-editor dump
338
* @returns Object mapping file paths to content and state information
339
*/
340
getSnapshot(filter?: Function): Record<string, { contents: string; stateCleared: string }>;
341
342
/**
343
* Return an object with filenames and their state information
344
* @param filter - Optional filter function
345
* @returns Object mapping file paths to state information only
346
*/
347
getStateSnapshot(filter?: Function): Record<string, { stateCleared?: string; state?: string }>;
348
```
349
350
**Usage Examples:**
351
352
```typescript
353
// Get complete file system snapshot
354
const snapshot = result.getSnapshot();
355
356
// Inspect specific files
357
expect(snapshot["package.json"].contents).toContain('"name": "my-app"');
358
expect(snapshot["src/index.ts"].stateCleared).toBe("modified");
359
360
// Filtered snapshot
361
const jsFiles = result.getSnapshot(file => file.path.endsWith('.js'));
362
363
// State-only snapshot
364
const stateSnapshot = result.getStateSnapshot();
365
expect(stateSnapshot["package.json"].state).toBe("modified");
366
```
367
368
### Debug and Inspection Utilities
369
370
Utilities for debugging and inspecting file system state during test development.
371
372
```typescript { .api }
373
/**
374
* Dump file contents to console for debugging
375
* @param files - Optional file paths to dump (dumps all files if none specified)
376
* @returns this for method chaining
377
*/
378
dumpFiles(...files: string[]): this;
379
380
/**
381
* Dump all filenames to console
382
* @returns this for method chaining
383
*/
384
dumpFilenames(): this;
385
```
386
387
**Usage Examples:**
388
389
```typescript
390
// Dump specific files
391
result.dumpFiles("package.json", "src/index.ts");
392
393
// Dump all files
394
result.dumpFiles();
395
396
// Dump only filenames
397
result.dumpFilenames();
398
```
399
400
### Context Management
401
402
Create new test contexts and manage working directory state.
403
404
```typescript { .api }
405
/**
406
* Create another RunContext reusing the current settings
407
* @param GeneratorOrNamespace - Generator constructor or namespace
408
* @param settings - Optional settings override
409
* @param environmentOptions - Optional environment options override
410
* @returns New RunContext instance
411
*/
412
create<G extends BaseGenerator = GeneratorType>(
413
GeneratorOrNamespace: string | GetGeneratorConstructor<G>,
414
settings?: RunContextSettings,
415
environmentOptions?: BaseEnvironmentOptions
416
): RunContext<G>;
417
418
/**
419
* Deletes the test directory recursively
420
* @returns this for method chaining
421
*/
422
cleanup(): this;
423
424
/**
425
* Restore original working directory
426
* @returns this for method chaining
427
*/
428
restore(): this;
429
```
430
431
**Usage Examples:**
432
433
```typescript
434
// Create follow-up test in same directory
435
const secondResult = await result
436
.create("another-generator")
437
.withOptions({ extend: true })
438
.run();
439
440
// Cleanup after manual testing
441
result.cleanup();
442
443
// Restore working directory
444
result.restore();
445
```
446
447
### Spawn Mock Utilities
448
449
Access spawn call information when using spawn mocking.
450
451
```typescript { .api }
452
/**
453
* Get spawn call arguments when using default spawn implementation
454
* @returns Array of call arguments for each spawn invocation
455
* @throws Error if spawn stub was not configured
456
*/
457
getSpawnArgsUsingDefaultImplementation(): any[][];
458
```
459
460
**Usage Examples:**
461
462
```typescript
463
// Setup spawn mocking in test context
464
await helpers.run("my-generator")
465
.withSpawnMock();
466
467
// Access spawn calls
468
const spawnCalls = result.getSpawnArgsUsingDefaultImplementation();
469
470
// Verify expected commands were run
471
expect(spawnCalls).toHaveLength(2);
472
expect(spawnCalls[0]).toEqual(["spawnCommand", "npm", ["install"]]);
473
expect(spawnCalls[1]).toEqual(["spawnCommand", "git", ["init"]]);
474
```
475
476
## Result Proxy
477
478
The `result` export provides convenient access to the last executed test result:
479
480
```typescript { .api }
481
/**
482
* Proxy object providing access to the last RunResult instance
483
* All RunResult methods are available directly on this object
484
*/
485
export const result: RunResult;
486
```
487
488
**Usage Examples:**
489
490
```typescript
491
import helpers, { result } from "yeoman-test";
492
493
describe("generator test", () => {
494
beforeEach(async () => {
495
await helpers.run("my-generator")
496
.withOptions({ skipInstall: true });
497
});
498
499
it("creates expected files", () => {
500
// result automatically refers to the last execution
501
result.assertFile("package.json");
502
result.assertFileContent("package.json", /"name"/);
503
});
504
});
505
```