yeoman-test 7.3.0 → 8.0.0-alpha.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 +54 -1
- package/dist/helpers.d.ts +8 -4
- package/dist/helpers.js +14 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/run-context.d.ts +21 -6
- package/dist/run-context.js +72 -33
- package/dist/run-result.d.ts +3 -3
- package/dist/run-result.js +5 -4
- package/dist/test-context.d.ts +9 -3
- package/dist/test-context.js +23 -1
- package/package.json +8 -11
package/README.md
CHANGED
|
@@ -25,6 +25,8 @@ $ npm install --save-dev yeoman-generator@xxx yeoman-environment@xxx
|
|
|
25
25
|
Usage:
|
|
26
26
|
|
|
27
27
|
```js
|
|
28
|
+
import helpers from 'yeoman-test';
|
|
29
|
+
|
|
28
30
|
describe('generator test', () => {
|
|
29
31
|
describe('test', () => {
|
|
30
32
|
let runResult;
|
|
@@ -36,12 +38,22 @@ describe('generator test', () => {
|
|
|
36
38
|
{} // environment options
|
|
37
39
|
)
|
|
38
40
|
[.cd(dir)] // runs the test inside a non temporary dir
|
|
39
|
-
[.
|
|
41
|
+
[.onTargetDirectory(dir => {}) // prepares the test dir
|
|
40
42
|
[.withGenerators([])] // registers additional generators
|
|
41
43
|
[.withLookups({})] // runs Environment lookups
|
|
42
44
|
[.withOptions({})] // passes options to the generator
|
|
43
45
|
[.withLocalConfig({})] // sets the generator config as soon as it is instantiated
|
|
44
46
|
[.withAnswers()] // simulates the prompt answers
|
|
47
|
+
[.withMockedGenerators(['namespace', ...])] // adds a mocked generator to the namespaces
|
|
48
|
+
[.withFiles({
|
|
49
|
+
'foo.txt': 'bar',
|
|
50
|
+
'test.json', { content: true },
|
|
51
|
+
})] // add files to mem-fs
|
|
52
|
+
[.withYoRc({ 'generator-foo': { bar: {} } })] // add config to .yo-rc.json
|
|
53
|
+
[.withYoRcConfig('generator-foo.bar', { : {} })] // same as above
|
|
54
|
+
[.commitFiles()] // commit mem-fs files to disk
|
|
55
|
+
[.onGenerator(gen => {})] // do something with the generator
|
|
56
|
+
[.onEnvironment(env => {})] // do something with the environment
|
|
45
57
|
[.build(runContext => { // instantiates Environment/Generator
|
|
46
58
|
[runContext.env...] // does something with the environment
|
|
47
59
|
[runContext.generator...] // does something with the generator
|
|
@@ -51,6 +63,7 @@ describe('generator test', () => {
|
|
|
51
63
|
);
|
|
52
64
|
afterEach(() => {
|
|
53
65
|
if (runResult) {
|
|
66
|
+
// Optional if context is executed at a temporary folder
|
|
54
67
|
runResult.restore();
|
|
55
68
|
}
|
|
56
69
|
});
|
|
@@ -68,6 +81,46 @@ describe('generator test', () => {
|
|
|
68
81
|
});
|
|
69
82
|
```
|
|
70
83
|
|
|
84
|
+
Convenience last RunResult instance:
|
|
85
|
+
|
|
86
|
+
```js
|
|
87
|
+
import helpers, { result } from 'yeoman-test';
|
|
88
|
+
|
|
89
|
+
describe('generator test', () => {
|
|
90
|
+
before(() => helpers.run('namespace'));
|
|
91
|
+
it('test', () => {
|
|
92
|
+
result.assert...;
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Generator compose:
|
|
98
|
+
|
|
99
|
+
```js
|
|
100
|
+
import assert from 'assert';
|
|
101
|
+
import helpers, { result } from 'yeoman-test';
|
|
102
|
+
|
|
103
|
+
describe('my-gen', () => {
|
|
104
|
+
before(() => helpers.run('my-gen').withMockedGenerator(['composed-gen']));
|
|
105
|
+
it('should compose with composed-gen', () => {
|
|
106
|
+
assert(result.mockedGenerators['composed-gen'].calledOnce);
|
|
107
|
+
});
|
|
108
|
+
});
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Generic test folder:
|
|
112
|
+
|
|
113
|
+
```js
|
|
114
|
+
import helpers, { result } from 'yeoman-test';
|
|
115
|
+
|
|
116
|
+
describe('generic test', () => {
|
|
117
|
+
before(() => helpers.prepareTemporaryDir());
|
|
118
|
+
it('test', () => {
|
|
119
|
+
result.assert...;
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
```
|
|
123
|
+
|
|
71
124
|
[See our api documentation](https://yeoman.github.io/yeoman-test) for latest yeoman-test release.
|
|
72
125
|
|
|
73
126
|
[See our api documentation](https://yeoman.github.io/yeoman-test/5.0.1) for yeoman-test 5.0.1. Use 5.x for yeoman-environment 2.x support.
|
package/dist/helpers.d.ts
CHANGED
|
@@ -4,8 +4,7 @@ import type { GeneratorOptions } from 'yeoman-generator';
|
|
|
4
4
|
import type { Options, createEnv } from 'yeoman-environment';
|
|
5
5
|
import type { SinonSpiedInstance } from 'sinon';
|
|
6
6
|
import { type DummyPromptOptions } from './adapter.js';
|
|
7
|
-
import RunContext from './run-context.js';
|
|
8
|
-
import type { RunContextSettings } from './run-context.js';
|
|
7
|
+
import RunContext, { BasicRunContext, type RunContextSettings } from './run-context.js';
|
|
9
8
|
/**
|
|
10
9
|
* Dependencies can be path (autodiscovery) or an array [<generator>, <name>]
|
|
11
10
|
*/
|
|
@@ -144,7 +143,12 @@ export declare class YeomanTest {
|
|
|
144
143
|
* @return {RunContext}
|
|
145
144
|
*/
|
|
146
145
|
create<GeneratorType extends YeomanGenerator = YeomanGenerator>(GeneratorOrNamespace: string | GeneratorConstructor<GeneratorType>, settings?: RunContextSettings, envOptions?: Options): RunContext<GeneratorType>;
|
|
146
|
+
/**
|
|
147
|
+
* Prepare temporary dir without generator support.
|
|
148
|
+
* Generator and environment will be undefined.
|
|
149
|
+
*/
|
|
150
|
+
prepareTemporaryDir(settings?: RunContextSettings): BasicRunContext;
|
|
147
151
|
}
|
|
148
|
-
declare const
|
|
149
|
-
export default
|
|
152
|
+
declare const defaultHelpers: YeomanTest;
|
|
153
|
+
export default defaultHelpers;
|
|
150
154
|
export declare const createHelpers: (options: any) => YeomanTest;
|
package/dist/helpers.js
CHANGED
|
@@ -7,7 +7,7 @@ import { spy as sinonSpy, stub as sinonStub } from 'sinon';
|
|
|
7
7
|
import YeomanGenerator from 'yeoman-generator';
|
|
8
8
|
import Environment from 'yeoman-environment';
|
|
9
9
|
import { DummyPrompt, TestAdapter } from './adapter.js';
|
|
10
|
-
import RunContext from './run-context.js';
|
|
10
|
+
import RunContext, { BasicRunContext } from './run-context.js';
|
|
11
11
|
import testContext from './test-context.js';
|
|
12
12
|
const { cloneDeep } = _;
|
|
13
13
|
/**
|
|
@@ -261,8 +261,20 @@ export class YeomanTest {
|
|
|
261
261
|
create(GeneratorOrNamespace, settings, envOptions) {
|
|
262
262
|
return this.run(GeneratorOrNamespace, settings, envOptions);
|
|
263
263
|
}
|
|
264
|
+
/**
|
|
265
|
+
* Prepare temporary dir without generator support.
|
|
266
|
+
* Generator and environment will be undefined.
|
|
267
|
+
*/
|
|
268
|
+
prepareTemporaryDir(settings) {
|
|
269
|
+
const context = new BasicRunContext(undefined, settings);
|
|
270
|
+
if (settings?.autoCleanup !== false) {
|
|
271
|
+
testContext.startNewContext(context);
|
|
272
|
+
}
|
|
273
|
+
return context;
|
|
274
|
+
}
|
|
264
275
|
}
|
|
265
|
-
|
|
276
|
+
const defaultHelpers = new YeomanTest();
|
|
277
|
+
export default defaultHelpers;
|
|
266
278
|
export const createHelpers = options => {
|
|
267
279
|
const helpers = new YeomanTest();
|
|
268
280
|
Object.assign(helpers, options);
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { default, createHelpers, YeomanTest, type Dependency } from './helpers.js';
|
|
2
2
|
export { default as RunContext, RunContextBase, type RunContextSettings } from './run-context.js';
|
|
3
3
|
export { default as RunResult, type RunResultOptions } from './run-result.js';
|
|
4
|
-
export { default as context } from './test-context.js';
|
|
4
|
+
export { default as context, result } from './test-context.js';
|
|
5
5
|
export { DummyPrompt, TestAdapter } from './adapter.js';
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { default, createHelpers, YeomanTest } from './helpers.js';
|
|
2
2
|
export { default as RunContext, RunContextBase } from './run-context.js';
|
|
3
3
|
export { default as RunResult } from './run-result.js';
|
|
4
|
-
export { default as context } from './test-context.js';
|
|
4
|
+
export { default as context, result } from './test-context.js';
|
|
5
5
|
export { DummyPrompt, TestAdapter } from './adapter.js';
|
package/dist/run-context.d.ts
CHANGED
|
@@ -3,8 +3,9 @@ import { EventEmitter } from 'node:events';
|
|
|
3
3
|
import type Generator from 'yeoman-generator';
|
|
4
4
|
import type Environment from 'yeoman-environment';
|
|
5
5
|
import { type LookupOptions, type Options } from 'yeoman-environment';
|
|
6
|
-
import MemFsEditor from 'mem-fs-editor';
|
|
7
|
-
import
|
|
6
|
+
import { type MemFsEditor, type VinylMemFsEditorFile } from 'mem-fs-editor';
|
|
7
|
+
import { type Store } from 'mem-fs';
|
|
8
|
+
import RunResult, { type RunResultOptions } from './run-result.js';
|
|
8
9
|
import { type GeneratorConstructor, type Dependency, type YeomanTest } from './helpers.js';
|
|
9
10
|
import { type DummyPromptOptions } from './adapter.js';
|
|
10
11
|
/**
|
|
@@ -20,6 +21,7 @@ export type RunContextSettings = {
|
|
|
20
21
|
oldCwd?: string;
|
|
21
22
|
forwardCwd?: boolean;
|
|
22
23
|
autoCleanup?: boolean;
|
|
24
|
+
memFs?: Store;
|
|
23
25
|
/**
|
|
24
26
|
* File path to the generator (only used if Generator is a constructor)
|
|
25
27
|
*/
|
|
@@ -31,6 +33,7 @@ export type RunContextSettings = {
|
|
|
31
33
|
namespace?: string;
|
|
32
34
|
};
|
|
33
35
|
type PromiseRunResult<GeneratorType extends Generator> = Promise<RunResult<GeneratorType>>;
|
|
36
|
+
type MockedGeneratorFactory = (GeneratorClass?: typeof Generator) => typeof Generator;
|
|
34
37
|
export declare class RunContextBase<GeneratorType extends Generator = Generator> extends EventEmitter {
|
|
35
38
|
readonly mockedGenerators: Record<string, Generator>;
|
|
36
39
|
env: Environment;
|
|
@@ -39,16 +42,19 @@ export declare class RunContextBase<GeneratorType extends Generator = Generator>
|
|
|
39
42
|
readonly envOptions: Environment.Options;
|
|
40
43
|
completed: boolean;
|
|
41
44
|
targetDirectory?: string;
|
|
42
|
-
editor: MemFsEditor
|
|
45
|
+
editor: MemFsEditor;
|
|
46
|
+
memFs: Store<VinylMemFsEditorFile>;
|
|
47
|
+
mockedGeneratorFactory: MockedGeneratorFactory;
|
|
43
48
|
protected environmentPromise?: PromiseRunResult<GeneratorType>;
|
|
44
49
|
private args;
|
|
45
50
|
private options;
|
|
46
51
|
private answers?;
|
|
52
|
+
private keepFsState?;
|
|
47
53
|
private readonly onGeneratorCallbacks;
|
|
48
54
|
private readonly onTargetDirectoryCallbacks;
|
|
49
55
|
private readonly onEnvironmentCallbacks;
|
|
50
56
|
private readonly inDirCallbacks;
|
|
51
|
-
private readonly Generator
|
|
57
|
+
private readonly Generator?;
|
|
52
58
|
private readonly helpers;
|
|
53
59
|
private readonly temporaryDir;
|
|
54
60
|
private oldCwd?;
|
|
@@ -67,7 +73,7 @@ export declare class RunContextBase<GeneratorType extends Generator = Generator>
|
|
|
67
73
|
* @param settings
|
|
68
74
|
* @return {this}
|
|
69
75
|
*/
|
|
70
|
-
constructor(generatorType
|
|
76
|
+
constructor(generatorType?: string | GeneratorConstructor<GeneratorType> | typeof Generator, settings?: RunContextSettings, envOptions?: Options, helpers?: YeomanTest);
|
|
71
77
|
/**
|
|
72
78
|
* Run the generator on the environment and promises a RunResult instance.
|
|
73
79
|
* @return {PromiseRunResult} Promise a RunResult instance.
|
|
@@ -188,6 +194,7 @@ export declare class RunContextBase<GeneratorType extends Generator = Generator>
|
|
|
188
194
|
* });
|
|
189
195
|
*/
|
|
190
196
|
withGenerators(dependencies: Dependency[]): this;
|
|
197
|
+
withMockedGeneratorFactory(mockedGeneratorFactory: MockedGeneratorFactory): this;
|
|
191
198
|
/**
|
|
192
199
|
* Create mocked generators
|
|
193
200
|
* @param namespaces - namespaces of mocked generators
|
|
@@ -210,6 +217,10 @@ export declare class RunContextBase<GeneratorType extends Generator = Generator>
|
|
|
210
217
|
* @param localConfig - should look just like if called config.getAll()
|
|
211
218
|
*/
|
|
212
219
|
withLocalConfig(localConfig: Record<string, unknown>): this;
|
|
220
|
+
/**
|
|
221
|
+
* Don't reset mem-fs state cleared to aggregate snapshots from multiple runs.
|
|
222
|
+
*/
|
|
223
|
+
withKeepFsState(): this;
|
|
213
224
|
/**
|
|
214
225
|
* Add files to mem-fs.
|
|
215
226
|
* Files will be resolved relative to targetDir.
|
|
@@ -252,6 +263,7 @@ export declare class RunContextBase<GeneratorType extends Generator = Generator>
|
|
|
252
263
|
* @returns
|
|
253
264
|
*/
|
|
254
265
|
onEnvironment(callback: (this: this, env: Environment) => any): this;
|
|
266
|
+
prepare(): Promise<void>;
|
|
255
267
|
protected assertNotBuild(): void;
|
|
256
268
|
/**
|
|
257
269
|
* Build the generator and the environment.
|
|
@@ -263,6 +275,7 @@ export declare class RunContextBase<GeneratorType extends Generator = Generator>
|
|
|
263
275
|
* @return Promise resolved on end or rejected on error
|
|
264
276
|
*/
|
|
265
277
|
protected toPromise(): PromiseRunResult<GeneratorType>;
|
|
278
|
+
protected _createRunResultOptions(): RunResultOptions<GeneratorType>;
|
|
266
279
|
/**
|
|
267
280
|
* Keeps compatibility with events
|
|
268
281
|
*/
|
|
@@ -275,7 +288,6 @@ export declare class RunContextBase<GeneratorType extends Generator = Generator>
|
|
|
275
288
|
* @return {this} run context instance
|
|
276
289
|
*/
|
|
277
290
|
private setDir;
|
|
278
|
-
private _createRunResultOptions;
|
|
279
291
|
}
|
|
280
292
|
export default class RunContext<GeneratorType extends Generator = Generator> extends RunContextBase<GeneratorType> implements Promise<RunResult<GeneratorType>> {
|
|
281
293
|
then<TResult1 = RunResult<GeneratorType>, TResult2 = never>(onfulfilled?: ((value: RunResult<GeneratorType>) => TResult1 | PromiseLike<TResult1>) | undefined | undefined, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined | undefined): Promise<TResult1 | TResult2>;
|
|
@@ -283,4 +295,7 @@ export default class RunContext<GeneratorType extends Generator = Generator> ext
|
|
|
283
295
|
finally(onfinally?: (() => void) | undefined | undefined): Promise<RunResult<GeneratorType>>;
|
|
284
296
|
get [Symbol.toStringTag](): string;
|
|
285
297
|
}
|
|
298
|
+
export declare class BasicRunContext extends RunContext {
|
|
299
|
+
run(): PromiseRunResult<any>;
|
|
300
|
+
}
|
|
286
301
|
export {};
|
package/dist/run-context.js
CHANGED
|
@@ -6,9 +6,13 @@ import { EventEmitter } from 'node:events';
|
|
|
6
6
|
import process from 'node:process';
|
|
7
7
|
import _ from 'lodash';
|
|
8
8
|
import tempDirectory from 'temp-dir';
|
|
9
|
-
import
|
|
9
|
+
import { create as createMemFsEditor } from 'mem-fs-editor';
|
|
10
|
+
// eslint-disable-next-line n/file-extension-in-import
|
|
11
|
+
import { resetFileCommitStates } from 'mem-fs-editor/state';
|
|
12
|
+
import { create as createMemFs } from 'mem-fs';
|
|
10
13
|
import RunResult from './run-result.js';
|
|
11
14
|
import defaultHelpers from './helpers.js';
|
|
15
|
+
import testContext from './test-context.js';
|
|
12
16
|
const { camelCase, kebabCase, merge: lodashMerge, set: lodashSet } = _;
|
|
13
17
|
export class RunContextBase extends EventEmitter {
|
|
14
18
|
mockedGenerators = {};
|
|
@@ -19,10 +23,13 @@ export class RunContextBase extends EventEmitter {
|
|
|
19
23
|
completed = false;
|
|
20
24
|
targetDirectory;
|
|
21
25
|
editor;
|
|
26
|
+
memFs;
|
|
27
|
+
mockedGeneratorFactory;
|
|
22
28
|
environmentPromise;
|
|
23
29
|
args = [];
|
|
24
30
|
options = {};
|
|
25
31
|
answers;
|
|
32
|
+
keepFsState;
|
|
26
33
|
onGeneratorCallbacks = [];
|
|
27
34
|
onTargetDirectoryCallbacks = [];
|
|
28
35
|
onEnvironmentCallbacks = [];
|
|
@@ -63,6 +70,8 @@ export class RunContextBase extends EventEmitter {
|
|
|
63
70
|
this.cd(this.settings.cwd);
|
|
64
71
|
}
|
|
65
72
|
this.helpers = helpers;
|
|
73
|
+
this.memFs = settings?.memFs ?? createMemFs();
|
|
74
|
+
this.mockedGeneratorFactory = this.helpers.createMockedGenerator;
|
|
66
75
|
}
|
|
67
76
|
/**
|
|
68
77
|
* Run the generator on the environment and promises a RunResult instance.
|
|
@@ -80,7 +89,9 @@ export class RunContextBase extends EventEmitter {
|
|
|
80
89
|
this.helpers.restorePrompt(this.env);
|
|
81
90
|
this.completed = true;
|
|
82
91
|
}
|
|
83
|
-
|
|
92
|
+
const runResult = new RunResult(this._createRunResultOptions());
|
|
93
|
+
testContext.runResult = runResult;
|
|
94
|
+
return runResult;
|
|
84
95
|
}
|
|
85
96
|
// If any event listeners is added, setup event listeners emitters
|
|
86
97
|
on(eventName, listener) {
|
|
@@ -304,6 +315,10 @@ export class RunContextBase extends EventEmitter {
|
|
|
304
315
|
}
|
|
305
316
|
});
|
|
306
317
|
}
|
|
318
|
+
withMockedGeneratorFactory(mockedGeneratorFactory) {
|
|
319
|
+
this.mockedGeneratorFactory = mockedGeneratorFactory;
|
|
320
|
+
return this;
|
|
321
|
+
}
|
|
307
322
|
/**
|
|
308
323
|
* Create mocked generators
|
|
309
324
|
* @param namespaces - namespaces of mocked generators
|
|
@@ -322,7 +337,7 @@ export class RunContextBase extends EventEmitter {
|
|
|
322
337
|
*/
|
|
323
338
|
withMockedGenerators(namespaces) {
|
|
324
339
|
assert(Array.isArray(namespaces), 'namespaces should be an array');
|
|
325
|
-
const dependencies = namespaces.map(namespace => [this.
|
|
340
|
+
const dependencies = namespaces.map(namespace => [this.mockedGeneratorFactory(), namespace]);
|
|
326
341
|
const entries = dependencies.map(([generator, namespace]) => [namespace, generator]);
|
|
327
342
|
Object.assign(this.mockedGenerators, Object.fromEntries(entries));
|
|
328
343
|
return this.withGenerators(dependencies);
|
|
@@ -335,6 +350,13 @@ export class RunContextBase extends EventEmitter {
|
|
|
335
350
|
assert(typeof localConfig === 'object', 'config should be an object');
|
|
336
351
|
return this.onGenerator(generator => generator.config.defaults(localConfig));
|
|
337
352
|
}
|
|
353
|
+
/**
|
|
354
|
+
* Don't reset mem-fs state cleared to aggregate snapshots from multiple runs.
|
|
355
|
+
*/
|
|
356
|
+
withKeepFsState() {
|
|
357
|
+
this.keepFsState = true;
|
|
358
|
+
return this;
|
|
359
|
+
}
|
|
338
360
|
withFiles(relativePath, files) {
|
|
339
361
|
return this.onTargetDirectory(function () {
|
|
340
362
|
const targetDirectory = typeof relativePath === 'string' ? pathJoin(this.targetDirectory, relativePath) : this.targetDirectory;
|
|
@@ -409,16 +431,7 @@ export class RunContextBase extends EventEmitter {
|
|
|
409
431
|
this.onEnvironmentCallbacks.push(callback);
|
|
410
432
|
return this;
|
|
411
433
|
}
|
|
412
|
-
|
|
413
|
-
if (this.built || this.completed) {
|
|
414
|
-
throw new Error('The context is already built');
|
|
415
|
-
}
|
|
416
|
-
}
|
|
417
|
-
/**
|
|
418
|
-
* Build the generator and the environment.
|
|
419
|
-
* @return {RunContext|false} this
|
|
420
|
-
*/
|
|
421
|
-
async build() {
|
|
434
|
+
async prepare() {
|
|
422
435
|
this.assertNotBuild();
|
|
423
436
|
this.built = true;
|
|
424
437
|
if (!this.targetDirectory && this.settings.tmpdir !== false) {
|
|
@@ -437,17 +450,35 @@ export class RunContextBase extends EventEmitter {
|
|
|
437
450
|
if (!this.targetDirectory) {
|
|
438
451
|
throw new Error('targetDirectory is required');
|
|
439
452
|
}
|
|
453
|
+
if (!this.keepFsState) {
|
|
454
|
+
this.memFs.each(file => {
|
|
455
|
+
resetFileCommitStates(file);
|
|
456
|
+
});
|
|
457
|
+
}
|
|
458
|
+
this.editor = createMemFsEditor(this.memFs);
|
|
459
|
+
for (const onTargetDirectory of this.onTargetDirectoryCallbacks) {
|
|
460
|
+
// eslint-disable-next-line no-await-in-loop
|
|
461
|
+
await onTargetDirectory.call(this, this.targetDirectory);
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
assertNotBuild() {
|
|
465
|
+
if (this.built || this.completed) {
|
|
466
|
+
throw new Error('The context is already built');
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
/**
|
|
470
|
+
* Build the generator and the environment.
|
|
471
|
+
* @return {RunContext|false} this
|
|
472
|
+
*/
|
|
473
|
+
async build() {
|
|
474
|
+
await this.prepare();
|
|
440
475
|
const testEnv = await this.helpers.createTestEnv(this.envOptions.createEnv, {
|
|
441
476
|
cwd: this.settings.forwardCwd ? this.targetDirectory : undefined,
|
|
477
|
+
sharedFs: this.memFs,
|
|
442
478
|
...this.options,
|
|
443
479
|
...this.envOptions,
|
|
444
480
|
});
|
|
445
481
|
this.env = this.envCB ? (await this.envCB(testEnv)) ?? testEnv : testEnv;
|
|
446
|
-
this.editor = MemFsEditor.create(this.env.sharedFs);
|
|
447
|
-
for (const onTargetDirectory of this.onTargetDirectoryCallbacks) {
|
|
448
|
-
// eslint-disable-next-line no-await-in-loop
|
|
449
|
-
await onTargetDirectory.call(this, this.targetDirectory);
|
|
450
|
-
}
|
|
451
482
|
for (const onEnvironmentCallback of this.onEnvironmentCallbacks) {
|
|
452
483
|
// eslint-disable-next-line no-await-in-loop
|
|
453
484
|
await onEnvironmentCallback.call(this, this.env);
|
|
@@ -475,6 +506,21 @@ export class RunContextBase extends EventEmitter {
|
|
|
475
506
|
async toPromise() {
|
|
476
507
|
return this.environmentPromise ?? this.run();
|
|
477
508
|
}
|
|
509
|
+
_createRunResultOptions() {
|
|
510
|
+
return {
|
|
511
|
+
env: this.env,
|
|
512
|
+
generator: this.generator,
|
|
513
|
+
memFs: this.env?.sharedFs ?? this.memFs,
|
|
514
|
+
settings: {
|
|
515
|
+
...this.settings,
|
|
516
|
+
},
|
|
517
|
+
oldCwd: this.oldCwd,
|
|
518
|
+
cwd: this.targetDirectory,
|
|
519
|
+
envOptions: this.envOptions,
|
|
520
|
+
mockedGenerators: this.mockedGenerators,
|
|
521
|
+
helpers: this.helpers,
|
|
522
|
+
};
|
|
523
|
+
}
|
|
478
524
|
/**
|
|
479
525
|
* Keeps compatibility with events
|
|
480
526
|
*/
|
|
@@ -522,21 +568,6 @@ export class RunContextBase extends EventEmitter {
|
|
|
522
568
|
this.targetDirectory = dirPath;
|
|
523
569
|
return this;
|
|
524
570
|
}
|
|
525
|
-
_createRunResultOptions() {
|
|
526
|
-
return {
|
|
527
|
-
env: this.env,
|
|
528
|
-
generator: this.generator,
|
|
529
|
-
memFs: this.env.sharedFs,
|
|
530
|
-
settings: {
|
|
531
|
-
...this.settings,
|
|
532
|
-
},
|
|
533
|
-
oldCwd: this.oldCwd,
|
|
534
|
-
cwd: this.targetDirectory,
|
|
535
|
-
envOptions: this.envOptions,
|
|
536
|
-
mockedGenerators: this.mockedGenerators,
|
|
537
|
-
helpers: this.helpers,
|
|
538
|
-
};
|
|
539
|
-
}
|
|
540
571
|
}
|
|
541
572
|
export default class RunContext extends RunContextBase {
|
|
542
573
|
// eslint-disable-next-line unicorn/no-thenable
|
|
@@ -553,3 +584,11 @@ export default class RunContext extends RunContextBase {
|
|
|
553
584
|
return `RunContext`;
|
|
554
585
|
}
|
|
555
586
|
}
|
|
587
|
+
export class BasicRunContext extends RunContext {
|
|
588
|
+
async run() {
|
|
589
|
+
await this.prepare();
|
|
590
|
+
const runResult = new RunResult(this._createRunResultOptions());
|
|
591
|
+
testContext.runResult = runResult;
|
|
592
|
+
return runResult;
|
|
593
|
+
}
|
|
594
|
+
}
|
package/dist/run-result.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { type MemFsEditor } from 'mem-fs-editor';
|
|
2
2
|
import type { Store } from 'mem-fs';
|
|
3
3
|
import type Environment from 'yeoman-environment';
|
|
4
4
|
import type Generator from 'yeoman-generator';
|
|
@@ -26,7 +26,7 @@ export type RunResultOptions<GeneratorType extends Generator> = {
|
|
|
26
26
|
* The file-system of the generator.
|
|
27
27
|
*/
|
|
28
28
|
memFs: Store;
|
|
29
|
-
fs?: MemFsEditor
|
|
29
|
+
fs?: MemFsEditor;
|
|
30
30
|
/**
|
|
31
31
|
* The mocked generators of the context.
|
|
32
32
|
*/
|
|
@@ -43,7 +43,7 @@ export default class RunResult<GeneratorType extends Generator = Generator> {
|
|
|
43
43
|
cwd: string;
|
|
44
44
|
oldCwd: string;
|
|
45
45
|
memFs: Store;
|
|
46
|
-
fs:
|
|
46
|
+
fs: MemFsEditor;
|
|
47
47
|
mockedGenerators: any;
|
|
48
48
|
options: RunResultOptions<GeneratorType>;
|
|
49
49
|
constructor(options: RunResultOptions<GeneratorType>);
|
package/dist/run-result.js
CHANGED
|
@@ -2,7 +2,7 @@ import assert from 'node:assert';
|
|
|
2
2
|
import { existsSync, readFileSync, rmSync } from 'node:fs';
|
|
3
3
|
import path from 'node:path';
|
|
4
4
|
import process from 'node:process';
|
|
5
|
-
import
|
|
5
|
+
import { create as createMemFsEditor } from 'mem-fs-editor';
|
|
6
6
|
const isObject = object => typeof object === 'object' && object !== null && object !== undefined;
|
|
7
7
|
function convertArgs(args) {
|
|
8
8
|
if (args.length > 1) {
|
|
@@ -32,7 +32,7 @@ export default class RunResult {
|
|
|
32
32
|
this.cwd = options.cwd ?? process.cwd();
|
|
33
33
|
this.oldCwd = options.oldCwd;
|
|
34
34
|
this.memFs = options.memFs;
|
|
35
|
-
this.fs = this.memFs &&
|
|
35
|
+
this.fs = this.memFs && createMemFsEditor(this.memFs);
|
|
36
36
|
this.mockedGenerators = options.mockedGenerators || {};
|
|
37
37
|
this.options = options;
|
|
38
38
|
}
|
|
@@ -45,9 +45,10 @@ export default class RunResult {
|
|
|
45
45
|
...this.options.settings,
|
|
46
46
|
cwd: this.cwd,
|
|
47
47
|
oldCwd: this.oldCwd,
|
|
48
|
+
memFs: this.memFs,
|
|
48
49
|
...settings,
|
|
49
50
|
autoCleanup: false,
|
|
50
|
-
}, { ...this.options.envOptions,
|
|
51
|
+
}, { ...this.options.envOptions, ...envOptions });
|
|
51
52
|
}
|
|
52
53
|
/**
|
|
53
54
|
* Return an object with fs changes.
|
|
@@ -120,7 +121,7 @@ export default class RunResult {
|
|
|
120
121
|
}
|
|
121
122
|
_readFile(filename, json) {
|
|
122
123
|
filename = this._fileName(filename);
|
|
123
|
-
const file = this.fs ? this.fs.read(filename) : readFileSync(filename, 'utf8');
|
|
124
|
+
const file = (this.fs ? this.fs.read(filename) : undefined) ?? readFileSync(filename, 'utf8');
|
|
124
125
|
return json ? JSON.parse(file) : file;
|
|
125
126
|
}
|
|
126
127
|
_exists(filename) {
|
package/dist/test-context.d.ts
CHANGED
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
import type RunContext from './run-context.js';
|
|
2
|
+
import type RunResult from './run-result.js';
|
|
2
3
|
declare class TestContext {
|
|
4
|
+
runResult?: RunResult;
|
|
3
5
|
private runContext?;
|
|
4
|
-
startNewContext(runContext
|
|
6
|
+
startNewContext(runContext?: RunContext<any>): void;
|
|
5
7
|
}
|
|
6
|
-
declare const
|
|
7
|
-
export default
|
|
8
|
+
declare const testContext: TestContext;
|
|
9
|
+
export default testContext;
|
|
10
|
+
/**
|
|
11
|
+
* Provides a proxy for last executed context result.
|
|
12
|
+
*/
|
|
13
|
+
export declare const result: RunResult;
|
package/dist/test-context.js
CHANGED
|
@@ -1,8 +1,30 @@
|
|
|
1
|
+
import process from 'node:process';
|
|
1
2
|
class TestContext {
|
|
3
|
+
runResult;
|
|
2
4
|
runContext;
|
|
3
5
|
startNewContext(runContext) {
|
|
4
6
|
this.runContext?.cleanupTemporaryDir();
|
|
5
7
|
this.runContext = runContext;
|
|
8
|
+
this.runResult = undefined;
|
|
6
9
|
}
|
|
7
10
|
}
|
|
8
|
-
|
|
11
|
+
const testContext = new TestContext();
|
|
12
|
+
const cleanupTemporaryDir = () => {
|
|
13
|
+
testContext.startNewContext();
|
|
14
|
+
};
|
|
15
|
+
process.on('exit', cleanupTemporaryDir);
|
|
16
|
+
process.on('SIGINT', cleanupTemporaryDir);
|
|
17
|
+
process.on('SIGTERM', cleanupTemporaryDir);
|
|
18
|
+
export default testContext;
|
|
19
|
+
const handler2 = {
|
|
20
|
+
get(_target, prop, receiver) {
|
|
21
|
+
if (testContext.runResult === undefined) {
|
|
22
|
+
throw new Error('Last result is missing.');
|
|
23
|
+
}
|
|
24
|
+
return Reflect.get(testContext.runResult, prop, receiver);
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Provides a proxy for last executed context result.
|
|
29
|
+
*/
|
|
30
|
+
export const result = new Proxy({}, handler2);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "yeoman-test",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "8.0.0-alpha.0",
|
|
4
4
|
"description": "Test utilities for Yeoman generators",
|
|
5
5
|
"homepage": "http://yeoman.io/authoring/testing.html",
|
|
6
6
|
"author": "The Yeoman Team",
|
|
@@ -20,22 +20,20 @@
|
|
|
20
20
|
"repository": "yeoman/yeoman-test",
|
|
21
21
|
"license": "MIT",
|
|
22
22
|
"engines": {
|
|
23
|
-
"node": "^
|
|
23
|
+
"node": "^16.17.0 || >=18.12.0"
|
|
24
24
|
},
|
|
25
25
|
"config": {
|
|
26
26
|
"doc_path": "../yeoman-test-doc"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
|
-
"@node
|
|
30
|
-
"@types/mocha": "^10.0.0",
|
|
29
|
+
"@types/node": "^16.18.19",
|
|
31
30
|
"@types/sinon": "^10.0.13",
|
|
31
|
+
"c8": "^7.13.0",
|
|
32
32
|
"coveralls": "^3.1.1",
|
|
33
|
+
"esmocha": "^0.1.4",
|
|
33
34
|
"husky": "^8.0.2",
|
|
34
35
|
"jsdoc": "^3.6.10",
|
|
35
36
|
"lint-staged": "^13.0.3",
|
|
36
|
-
"mem-fs": "^2.2.1",
|
|
37
|
-
"mocha": "^10.1.0",
|
|
38
|
-
"mocha-expect-snapshot": "^7.0.0",
|
|
39
37
|
"prettier": "^2.2.1",
|
|
40
38
|
"prettier-plugin-packagejson": "^2.3.0",
|
|
41
39
|
"tui-jsdoc-template": "^1.2.2",
|
|
@@ -46,22 +44,21 @@
|
|
|
46
44
|
},
|
|
47
45
|
"dependencies": {
|
|
48
46
|
"@types/inquirer": "^8.2.5",
|
|
49
|
-
"@types/mem-fs-editor": "^7.0.2",
|
|
50
47
|
"@types/yeoman-environment": "^2.10.8",
|
|
51
48
|
"@types/yeoman-generator": "^5.2.11",
|
|
52
49
|
"inquirer": "^8.2.5",
|
|
53
50
|
"lodash": "^4.17.21",
|
|
54
|
-
"mem-fs
|
|
51
|
+
"mem-fs": "^3.0.0",
|
|
52
|
+
"mem-fs-editor": "^10.0.1",
|
|
55
53
|
"sinon": "^14.0.2",
|
|
56
54
|
"temp-dir": "^3.0.0"
|
|
57
55
|
},
|
|
58
56
|
"peerDependencies": {
|
|
59
|
-
"mem-fs": "^2.2.1",
|
|
60
57
|
"yeoman-environment": "^3.13.0",
|
|
61
58
|
"yeoman-generator": "*"
|
|
62
59
|
},
|
|
63
60
|
"scripts": {
|
|
64
|
-
"test": "
|
|
61
|
+
"test": "c8 esmocha",
|
|
65
62
|
"build": "tsc",
|
|
66
63
|
"prepare": "npm run build",
|
|
67
64
|
"pretest": "xo",
|