yeoman-test 8.3.0 → 9.0.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/dist/adapter.js +4 -2
- package/dist/default-environment.d.ts +1 -1
- package/dist/default-environment.js +5 -6
- package/dist/helpers.d.ts +9 -9
- package/dist/helpers.js +42 -40
- package/dist/mocha-cleanup.hooks.d.ts +3 -0
- package/dist/mocha-cleanup.hooks.js +6 -0
- package/dist/run-context.d.ts +23 -20
- package/dist/run-context.js +47 -56
- package/dist/run-result.d.ts +3 -3
- package/dist/run-result.js +20 -23
- package/dist/test-context.d.ts +4 -2
- package/dist/test-context.js +22 -9
- package/package.json +32 -34
- package/types/type-helpers.d.ts +2 -2
package/dist/adapter.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
+
import { mock } from 'node:test';
|
|
1
2
|
import { TestAdapter as BaseTestAdapter } from '@yeoman/adapter/testing';
|
|
2
|
-
import { spy as sinonSpy, stub as sinonStub } from 'sinon';
|
|
3
3
|
export class TestAdapter extends BaseTestAdapter {
|
|
4
4
|
constructor(options = {}) {
|
|
5
5
|
super({
|
|
6
|
-
spyFactory: ({ returns }) =>
|
|
6
|
+
spyFactory: ({ returns }) => returns
|
|
7
|
+
? mock.fn(() => { }, () => returns)
|
|
8
|
+
: mock.fn(),
|
|
7
9
|
...options,
|
|
8
10
|
});
|
|
9
11
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export function createEnv(options: import(
|
|
1
|
+
export function createEnv(options: import("@yeoman/types").BaseEnvironmentOptions): import("@yeoman/types").BaseEnvironment;
|
|
@@ -3,13 +3,12 @@
|
|
|
3
3
|
* @returns {import('@yeoman/types').BaseEnvironment}
|
|
4
4
|
*/
|
|
5
5
|
export const createEnv = async (options) => {
|
|
6
|
-
const
|
|
7
|
-
if (typeof
|
|
8
|
-
return new
|
|
6
|
+
const DynamicEnvironment = await import('yeoman-environment');
|
|
7
|
+
if (typeof DynamicEnvironment === 'function') {
|
|
8
|
+
return new DynamicEnvironment(options);
|
|
9
9
|
}
|
|
10
|
-
if (typeof
|
|
11
|
-
|
|
12
|
-
return new DynamicEnv.default(options);
|
|
10
|
+
if (typeof DynamicEnvironment.default === 'function') {
|
|
11
|
+
return new DynamicEnvironment.default(options);
|
|
13
12
|
}
|
|
14
13
|
throw new Error(`'yeoman-environment' didn't returned a constructor`);
|
|
15
14
|
};
|
package/dist/helpers.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import { mock } from 'node:test';
|
|
1
2
|
import type { BaseEnvironment, BaseEnvironmentOptions, BaseGenerator, BaseGeneratorOptions, GetGeneratorConstructor, InstantiateOptions, PromptAnswers } from '@yeoman/types';
|
|
2
|
-
import type { SinonSpiedInstance } from 'sinon';
|
|
3
3
|
import type { DefaultEnvironmentApi, DefaultGeneratorApi } from '../types/type-helpers.js';
|
|
4
4
|
import { type DummyPromptOptions, TestAdapter, type TestAdapterOptions } from './adapter.js';
|
|
5
5
|
import RunContext, { BasicRunContext, type RunContextSettings } from './run-context.js';
|
|
@@ -38,7 +38,7 @@ export declare class YeomanTest {
|
|
|
38
38
|
* fs.writeFileSync('testfile', 'Roses are red.');
|
|
39
39
|
* });
|
|
40
40
|
*/
|
|
41
|
-
testDirectory(dir: string,
|
|
41
|
+
testDirectory(dir: string, callback?: (error?: any) => unknown): unknown;
|
|
42
42
|
/**
|
|
43
43
|
* @deprecated
|
|
44
44
|
* Answer prompt questions for the passed-in generator
|
|
@@ -50,13 +50,13 @@ export declare class YeomanTest {
|
|
|
50
50
|
* @example
|
|
51
51
|
* mockPrompt(angular, {'bootstrap': 'Y', 'compassBoostrap': 'Y'});
|
|
52
52
|
*/
|
|
53
|
-
mockPrompt(
|
|
53
|
+
mockPrompt(environmentOrGenerator: BaseGenerator | DefaultEnvironmentApi, mockedAnswers?: PromptAnswers, options?: DummyPromptOptions): void;
|
|
54
54
|
/**
|
|
55
55
|
* @deprecated
|
|
56
56
|
* Restore defaults prompts on a generator.
|
|
57
57
|
* @param generator or environment
|
|
58
58
|
*/
|
|
59
|
-
restorePrompt(
|
|
59
|
+
restorePrompt(environmentOrGenerator: BaseGenerator | DefaultEnvironmentApi): void;
|
|
60
60
|
/**
|
|
61
61
|
* @deprecated
|
|
62
62
|
* Provide mocked values to the config
|
|
@@ -67,11 +67,11 @@ export declare class YeomanTest {
|
|
|
67
67
|
/**
|
|
68
68
|
* Create a mocked generator
|
|
69
69
|
*/
|
|
70
|
-
createMockedGenerator(GeneratorClass?: any):
|
|
70
|
+
createMockedGenerator(GeneratorClass?: any): ReturnType<typeof mock.fn>;
|
|
71
71
|
/**
|
|
72
72
|
* Create a simple, dummy generator
|
|
73
73
|
*/
|
|
74
|
-
createDummyGenerator<GenParameter extends BaseGenerator = DefaultGeneratorApi>(Generator?: GetGeneratorConstructor<GenParameter>, contents?: Record<string, (...
|
|
74
|
+
createDummyGenerator<GenParameter extends BaseGenerator = DefaultGeneratorApi>(Generator?: GetGeneratorConstructor<GenParameter>, contents?: Record<string, (...arguments_: any[]) => void>): new (...arguments_: any[]) => GenParameter;
|
|
75
75
|
/**
|
|
76
76
|
* Create a generator, using the given dependencies and controller arguments
|
|
77
77
|
* Dependecies can be path (autodiscovery) or an array [{generator}, {name}]
|
|
@@ -118,7 +118,7 @@ export declare class YeomanTest {
|
|
|
118
118
|
* @param {Object} - Options to be passed to the environment
|
|
119
119
|
* const env = createTestEnv(require('yeoman-environment').createEnv);
|
|
120
120
|
*/
|
|
121
|
-
createTestEnv(
|
|
121
|
+
createTestEnv(environmentContructor?: CreateEnv, options?: BaseEnvironmentOptions): Promise<BaseEnvironment>;
|
|
122
122
|
/**
|
|
123
123
|
* Creates a TestAdapter using helpers default options.
|
|
124
124
|
*/
|
|
@@ -132,13 +132,13 @@ export declare class YeomanTest {
|
|
|
132
132
|
* Run the provided Generator
|
|
133
133
|
* @param GeneratorOrNamespace - Generator constructor or namespace
|
|
134
134
|
*/
|
|
135
|
-
run<GeneratorType extends BaseGenerator = DefaultGeneratorApi>(GeneratorOrNamespace: string | GetGeneratorConstructor<GeneratorType>, settings?: RunContextSettings,
|
|
135
|
+
run<GeneratorType extends BaseGenerator = DefaultGeneratorApi>(GeneratorOrNamespace: string | GetGeneratorConstructor<GeneratorType>, settings?: RunContextSettings, environmentOptions?: BaseEnvironmentOptions): RunContext<GeneratorType>;
|
|
136
136
|
/**
|
|
137
137
|
* Prepare a run context
|
|
138
138
|
* @param {String|Function} GeneratorOrNamespace - Generator constructor or namespace
|
|
139
139
|
* @return {RunContext}
|
|
140
140
|
*/
|
|
141
|
-
create<GeneratorType extends BaseGenerator = DefaultGeneratorApi>(GeneratorOrNamespace: string | GetGeneratorConstructor<GeneratorType>, settings?: RunContextSettings,
|
|
141
|
+
create<GeneratorType extends BaseGenerator = DefaultGeneratorApi>(GeneratorOrNamespace: string | GetGeneratorConstructor<GeneratorType>, settings?: RunContextSettings, environmentOptions?: BaseEnvironmentOptions): RunContext<GeneratorType>;
|
|
142
142
|
/**
|
|
143
143
|
* Prepare temporary dir without generator support.
|
|
144
144
|
* Generator and environment will be undefined.
|
package/dist/helpers.js
CHANGED
|
@@ -1,18 +1,20 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { existsSync, mkdirSync, rmSync } from 'node:fs';
|
|
2
2
|
import { resolve } from 'node:path';
|
|
3
3
|
import process from 'node:process';
|
|
4
|
+
import { mock } from 'node:test';
|
|
4
5
|
import { cloneDeep } from 'lodash-es';
|
|
5
|
-
import { spy as sinonSpy, stub as sinonStub } from 'sinon';
|
|
6
6
|
import { TestAdapter } from './adapter.js';
|
|
7
7
|
import RunContext, { BasicRunContext } from './run-context.js';
|
|
8
8
|
import testContext from './test-context.js';
|
|
9
|
-
import { createEnv } from './default-environment.js';
|
|
9
|
+
import { createEnv as createEnvironment } from './default-environment.js';
|
|
10
10
|
let GeneratorImplementation;
|
|
11
11
|
try {
|
|
12
12
|
const GeneratorImport = await import('yeoman-generator');
|
|
13
13
|
GeneratorImplementation = GeneratorImport.default ?? GeneratorImport;
|
|
14
14
|
}
|
|
15
|
-
catch {
|
|
15
|
+
catch {
|
|
16
|
+
// Ignore error
|
|
17
|
+
}
|
|
16
18
|
/**
|
|
17
19
|
* Collection of unit test helpers. (mostly related to Mocha syntax)
|
|
18
20
|
* @class YeomanTest
|
|
@@ -47,7 +49,7 @@ export class YeomanTest {
|
|
|
47
49
|
* fs.writeFileSync('testfile', 'Roses are red.');
|
|
48
50
|
* });
|
|
49
51
|
*/
|
|
50
|
-
testDirectory(dir,
|
|
52
|
+
testDirectory(dir, callback) {
|
|
51
53
|
if (!dir) {
|
|
52
54
|
throw new Error('Missing directory');
|
|
53
55
|
}
|
|
@@ -61,10 +63,10 @@ export class YeomanTest {
|
|
|
61
63
|
}
|
|
62
64
|
mkdirSync(dir, { recursive: true });
|
|
63
65
|
process.chdir(dir);
|
|
64
|
-
return
|
|
66
|
+
return callback?.();
|
|
65
67
|
}
|
|
66
68
|
catch (error) {
|
|
67
|
-
return
|
|
69
|
+
return callback?.(error);
|
|
68
70
|
}
|
|
69
71
|
}
|
|
70
72
|
/**
|
|
@@ -78,8 +80,8 @@ export class YeomanTest {
|
|
|
78
80
|
* @example
|
|
79
81
|
* mockPrompt(angular, {'bootstrap': 'Y', 'compassBoostrap': 'Y'});
|
|
80
82
|
*/
|
|
81
|
-
mockPrompt(
|
|
82
|
-
const environment = 'env' in
|
|
83
|
+
mockPrompt(environmentOrGenerator, mockedAnswers, options) {
|
|
84
|
+
const environment = 'env' in environmentOrGenerator ? environmentOrGenerator.env : environmentOrGenerator;
|
|
83
85
|
if (!environment.adapter) {
|
|
84
86
|
throw new Error('environment is not an Environment instance');
|
|
85
87
|
}
|
|
@@ -94,8 +96,8 @@ export class YeomanTest {
|
|
|
94
96
|
* Restore defaults prompts on a generator.
|
|
95
97
|
* @param generator or environment
|
|
96
98
|
*/
|
|
97
|
-
restorePrompt(
|
|
98
|
-
const environment =
|
|
99
|
+
restorePrompt(environmentOrGenerator) {
|
|
100
|
+
const environment = environmentOrGenerator.env ?? environmentOrGenerator;
|
|
99
101
|
environment.adapter.close();
|
|
100
102
|
}
|
|
101
103
|
/**
|
|
@@ -113,10 +115,10 @@ export class YeomanTest {
|
|
|
113
115
|
createMockedGenerator(GeneratorClass = GeneratorImplementation) {
|
|
114
116
|
class MockedGenerator extends GeneratorClass {
|
|
115
117
|
}
|
|
116
|
-
const generator =
|
|
118
|
+
const generator = mock.fn(MockedGenerator);
|
|
117
119
|
for (const methodName of ['run', 'queueTasks', 'runWithOptions', 'queueOwnTasks']) {
|
|
118
120
|
Object.defineProperty(MockedGenerator.prototype, methodName, {
|
|
119
|
-
value:
|
|
121
|
+
value: mock.fn(),
|
|
120
122
|
});
|
|
121
123
|
}
|
|
122
124
|
return generator;
|
|
@@ -130,18 +132,18 @@ export class YeomanTest {
|
|
|
130
132
|
},
|
|
131
133
|
}) {
|
|
132
134
|
class DummyGenerator extends Generator {
|
|
133
|
-
constructor(...
|
|
134
|
-
const optIndex = Array.isArray(
|
|
135
|
-
|
|
136
|
-
const options =
|
|
135
|
+
constructor(...arguments_) {
|
|
136
|
+
const optIndex = Array.isArray(arguments_[0]) ? 1 : 0;
|
|
137
|
+
arguments_[optIndex] = arguments_[optIndex] ?? {};
|
|
138
|
+
const options = arguments_[optIndex];
|
|
137
139
|
options.namespace = options.namespace ?? 'dummy';
|
|
138
140
|
options.resolved = options.resolved ?? 'dummy';
|
|
139
|
-
super(...
|
|
141
|
+
super(...arguments_);
|
|
140
142
|
}
|
|
141
143
|
}
|
|
142
|
-
for (const [
|
|
143
|
-
Object.defineProperty(DummyGenerator.prototype,
|
|
144
|
-
value:
|
|
144
|
+
for (const [propertyName, propertyValue] of Object.entries(contents)) {
|
|
145
|
+
Object.defineProperty(DummyGenerator.prototype, propertyName, {
|
|
146
|
+
value: propertyValue ?? Object.create(null),
|
|
145
147
|
writable: true,
|
|
146
148
|
});
|
|
147
149
|
}
|
|
@@ -168,16 +170,16 @@ export class YeomanTest {
|
|
|
168
170
|
*/
|
|
169
171
|
async createGenerator(name, options = {}) {
|
|
170
172
|
const { dependencies = [], localConfigOnly = true, ...instantiateOptions } = options;
|
|
171
|
-
const
|
|
173
|
+
const environment = await this.createEnv({ sharedOptions: { localConfigOnly } });
|
|
172
174
|
for (const dependency of dependencies) {
|
|
173
175
|
if (typeof dependency === 'string') {
|
|
174
|
-
|
|
176
|
+
environment.register(dependency);
|
|
175
177
|
}
|
|
176
178
|
else {
|
|
177
|
-
|
|
179
|
+
environment.register(...dependency);
|
|
178
180
|
}
|
|
179
181
|
}
|
|
180
|
-
return
|
|
182
|
+
return environment.create(name, instantiateOptions);
|
|
181
183
|
}
|
|
182
184
|
/**
|
|
183
185
|
* Shortcut to the Environment's createEnv.
|
|
@@ -195,7 +197,7 @@ export class YeomanTest {
|
|
|
195
197
|
* });
|
|
196
198
|
*/
|
|
197
199
|
async createEnv(options) {
|
|
198
|
-
return
|
|
200
|
+
return createEnvironment(options);
|
|
199
201
|
}
|
|
200
202
|
/**
|
|
201
203
|
* Creates a test environment.
|
|
@@ -204,31 +206,31 @@ export class YeomanTest {
|
|
|
204
206
|
* @param {Object} - Options to be passed to the environment
|
|
205
207
|
* const env = createTestEnv(require('yeoman-environment').createEnv);
|
|
206
208
|
*/
|
|
207
|
-
async createTestEnv(
|
|
208
|
-
let
|
|
209
|
+
async createTestEnv(environmentContructor = this.createEnv, options = { localConfigOnly: true }) {
|
|
210
|
+
let environmentOptions = cloneDeep(this.environmentOptions ?? {});
|
|
209
211
|
if (typeof options === 'boolean') {
|
|
210
|
-
|
|
212
|
+
environmentOptions = {
|
|
211
213
|
newErrorHandler: true,
|
|
212
|
-
...
|
|
214
|
+
...environmentOptions,
|
|
213
215
|
sharedOptions: {
|
|
214
216
|
localConfigOnly: options,
|
|
215
|
-
...
|
|
217
|
+
...environmentOptions.sharedOptions,
|
|
216
218
|
},
|
|
217
219
|
};
|
|
218
220
|
}
|
|
219
221
|
else {
|
|
220
|
-
|
|
222
|
+
environmentOptions.sharedOptions = {
|
|
221
223
|
localConfigOnly: true,
|
|
222
|
-
...
|
|
224
|
+
...environmentOptions.sharedOptions,
|
|
223
225
|
...options.sharedOptions,
|
|
224
226
|
};
|
|
225
|
-
|
|
227
|
+
environmentOptions = {
|
|
226
228
|
newErrorHandler: true,
|
|
227
|
-
...
|
|
229
|
+
...environmentOptions,
|
|
228
230
|
...options,
|
|
229
231
|
};
|
|
230
232
|
}
|
|
231
|
-
return
|
|
233
|
+
return environmentContructor({ adapter: this.createTestAdapter(), ...environmentOptions });
|
|
232
234
|
}
|
|
233
235
|
/**
|
|
234
236
|
* Creates a TestAdapter using helpers default options.
|
|
@@ -247,11 +249,11 @@ export class YeomanTest {
|
|
|
247
249
|
* Run the provided Generator
|
|
248
250
|
* @param GeneratorOrNamespace - Generator constructor or namespace
|
|
249
251
|
*/
|
|
250
|
-
run(GeneratorOrNamespace, settings,
|
|
252
|
+
run(GeneratorOrNamespace, settings, environmentOptions) {
|
|
251
253
|
const contextSettings = cloneDeep(this.settings ?? {});
|
|
252
254
|
const generatorOptions = cloneDeep(this.generatorOptions ?? {});
|
|
253
255
|
const RunContext = this.getRunContextType();
|
|
254
|
-
const runContext = new RunContext(GeneratorOrNamespace, { ...contextSettings, ...settings },
|
|
256
|
+
const runContext = new RunContext(GeneratorOrNamespace, { ...contextSettings, ...settings }, environmentOptions, this).withOptions(generatorOptions);
|
|
255
257
|
if (settings?.autoCleanup !== false) {
|
|
256
258
|
testContext.startNewContext(runContext);
|
|
257
259
|
}
|
|
@@ -262,8 +264,8 @@ export class YeomanTest {
|
|
|
262
264
|
* @param {String|Function} GeneratorOrNamespace - Generator constructor or namespace
|
|
263
265
|
* @return {RunContext}
|
|
264
266
|
*/
|
|
265
|
-
create(GeneratorOrNamespace, settings,
|
|
266
|
-
return this.run(GeneratorOrNamespace, settings,
|
|
267
|
+
create(GeneratorOrNamespace, settings, environmentOptions) {
|
|
268
|
+
return this.run(GeneratorOrNamespace, settings, environmentOptions);
|
|
267
269
|
}
|
|
268
270
|
/**
|
|
269
271
|
* Prepare temporary dir without generator support.
|
package/dist/run-context.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
/// <reference types="node" resolution-mode="require"/>
|
|
2
1
|
import { EventEmitter } from 'node:events';
|
|
2
|
+
import { mock } from 'node:test';
|
|
3
3
|
import { type Store } from 'mem-fs';
|
|
4
|
-
import type { BaseEnvironmentOptions, BaseGenerator, GetGeneratorConstructor, GetGeneratorOptions,
|
|
5
|
-
import { type
|
|
6
|
-
import type {
|
|
4
|
+
import type { BaseEnvironmentOptions, BaseGenerator, GetGeneratorConstructor, GetGeneratorOptions, LookupOptions, PromptAnswers } from '@yeoman/types';
|
|
5
|
+
import { type MemFsEditor, type MemFsEditorFile } from 'mem-fs-editor';
|
|
6
|
+
import type { DefaultEnvironmentApi, DefaultGeneratorApi } from '../types/type-helpers.js';
|
|
7
7
|
import RunResult, { type RunResultOptions } from './run-result.js';
|
|
8
|
-
import { type CreateEnv, type Dependency, type YeomanTest } from './helpers.js';
|
|
8
|
+
import { type CreateEnv as CreateEnvironment, type Dependency, type YeomanTest } from './helpers.js';
|
|
9
9
|
import { type AskedQuestions, type DummyPromptOptions, type TestAdapterOptions } from './adapter.js';
|
|
10
10
|
/**
|
|
11
11
|
* Provides settings for creating a `RunContext`.
|
|
@@ -33,15 +33,15 @@ export type RunContextSettings = {
|
|
|
33
33
|
};
|
|
34
34
|
type PromiseRunResult<GeneratorType extends BaseGenerator> = Promise<RunResult<GeneratorType>>;
|
|
35
35
|
type MockedGeneratorFactory<GenParameter extends BaseGenerator = DefaultGeneratorApi> = (GeneratorClass?: GetGeneratorConstructor<GenParameter>) => GetGeneratorConstructor<GenParameter>;
|
|
36
|
-
type
|
|
37
|
-
createEnv?:
|
|
36
|
+
type EnvironmentOptions = BaseEnvironmentOptions & {
|
|
37
|
+
createEnv?: CreateEnvironment;
|
|
38
38
|
};
|
|
39
39
|
export declare class RunContextBase<GeneratorType extends BaseGenerator = DefaultGeneratorApi> extends EventEmitter {
|
|
40
40
|
readonly mockedGenerators: Record<string, BaseGenerator>;
|
|
41
41
|
env: DefaultEnvironmentApi;
|
|
42
42
|
generator: GeneratorType;
|
|
43
43
|
readonly settings: RunContextSettings;
|
|
44
|
-
readonly envOptions:
|
|
44
|
+
readonly envOptions: EnvironmentOptions;
|
|
45
45
|
completed: boolean;
|
|
46
46
|
targetDirectory?: string;
|
|
47
47
|
editor: MemFsEditor;
|
|
@@ -79,13 +79,13 @@ export declare class RunContextBase<GeneratorType extends BaseGenerator = Defaul
|
|
|
79
79
|
* @param settings
|
|
80
80
|
* @return {this}
|
|
81
81
|
*/
|
|
82
|
-
constructor(generatorType?: string | GetGeneratorConstructor<GeneratorType>, settings?: RunContextSettings,
|
|
82
|
+
constructor(generatorType?: string | GetGeneratorConstructor<GeneratorType>, settings?: RunContextSettings, environmentOptions?: EnvironmentOptions, helpers?: YeomanTest);
|
|
83
83
|
/**
|
|
84
84
|
* Run the generator on the environment and promises a RunResult instance.
|
|
85
85
|
* @return {PromiseRunResult} Promise a RunResult instance.
|
|
86
86
|
*/
|
|
87
87
|
run(): PromiseRunResult<GeneratorType>;
|
|
88
|
-
on(eventName: string | symbol, listener: (...
|
|
88
|
+
on(eventName: string | symbol, listener: (...arguments_: any[]) => void): this;
|
|
89
89
|
/**
|
|
90
90
|
* @deprecated
|
|
91
91
|
* Clean the provided directory, then change directory into it
|
|
@@ -94,13 +94,13 @@ export declare class RunContextBase<GeneratorType extends BaseGenerator = Defaul
|
|
|
94
94
|
* @param [cb] - callback who'll receive the folder path as argument
|
|
95
95
|
* @return run context instance
|
|
96
96
|
*/
|
|
97
|
-
inDir(dirPath: string,
|
|
97
|
+
inDir(dirPath: string, callback?: (folderPath: string) => void): this;
|
|
98
98
|
/**
|
|
99
99
|
* Register an callback to prepare the destination folder.
|
|
100
100
|
* @param [cb] - callback who'll receive the folder path as argument
|
|
101
101
|
* @return this - run context instance
|
|
102
102
|
*/
|
|
103
|
-
doInDir(
|
|
103
|
+
doInDir(callback: (folderPath: string) => void): this;
|
|
104
104
|
/**
|
|
105
105
|
* @deprecated
|
|
106
106
|
* Change directory without deleting directory content.
|
|
@@ -118,7 +118,7 @@ export declare class RunContextBase<GeneratorType extends BaseGenerator = Defaul
|
|
|
118
118
|
* @param [cb] - callback who'll receive the folder path as argument
|
|
119
119
|
* @return this - run context instance
|
|
120
120
|
*/
|
|
121
|
-
inTmpDir(
|
|
121
|
+
inTmpDir(callback?: (folderPath: string) => void): this;
|
|
122
122
|
/**
|
|
123
123
|
* Restore cwd to initial cwd.
|
|
124
124
|
* @return {this} run context instance
|
|
@@ -152,7 +152,7 @@ export declare class RunContextBase<GeneratorType extends BaseGenerator = Defaul
|
|
|
152
152
|
* @param {Function} [cb] - callback who'll receive the folder path as argument
|
|
153
153
|
* @return {this} run context instance
|
|
154
154
|
*/
|
|
155
|
-
withEnvironment(
|
|
155
|
+
withEnvironment(callback: any): this;
|
|
156
156
|
/**
|
|
157
157
|
* Run lookup on the environment.
|
|
158
158
|
*
|
|
@@ -163,7 +163,7 @@ export declare class RunContextBase<GeneratorType extends BaseGenerator = Defaul
|
|
|
163
163
|
* Provide arguments to the run context
|
|
164
164
|
* @param args - command line arguments as Array or space separated string
|
|
165
165
|
*/
|
|
166
|
-
withArguments(
|
|
166
|
+
withArguments(arguments_: string | string[]): this;
|
|
167
167
|
/**
|
|
168
168
|
* Provide options to the run context
|
|
169
169
|
* @param {Object} options - command line options (e.g. `--opt-one=foo`)
|
|
@@ -204,10 +204,13 @@ export declare class RunContextBase<GeneratorType extends BaseGenerator = Defaul
|
|
|
204
204
|
* });
|
|
205
205
|
*/
|
|
206
206
|
withGenerators(dependencies: Dependency[]): this;
|
|
207
|
-
withSpawnMock(options?: ((...
|
|
208
|
-
stub?: (...
|
|
209
|
-
|
|
210
|
-
callback?: (stub
|
|
207
|
+
withSpawnMock<StubType = ReturnType<typeof mock.fn>>(options?: ((...arguments_: any[]) => any) | {
|
|
208
|
+
stub?: (...arguments_: any[]) => any;
|
|
209
|
+
registerNodeMockDefaults?: boolean;
|
|
210
|
+
callback?: ({ stub, implementation }: {
|
|
211
|
+
stub: StubType;
|
|
212
|
+
implementation: any;
|
|
213
|
+
}) => void | Promise<void>;
|
|
211
214
|
}): this;
|
|
212
215
|
withMockedGeneratorFactory(mockedGeneratorFactory: MockedGeneratorFactory): this;
|
|
213
216
|
/**
|
|
@@ -283,7 +286,7 @@ export declare class RunContextBase<GeneratorType extends BaseGenerator = Defaul
|
|
|
283
286
|
* @param callback
|
|
284
287
|
* @returns
|
|
285
288
|
*/
|
|
286
|
-
onEnvironment(callback: (this: this,
|
|
289
|
+
onEnvironment(callback: (this: this, environment: DefaultEnvironmentApi) => any): this;
|
|
287
290
|
prepare(): Promise<void>;
|
|
288
291
|
protected assertNotBuild(): void;
|
|
289
292
|
/**
|
package/dist/run-context.js
CHANGED
|
@@ -1,19 +1,18 @@
|
|
|
1
1
|
import crypto from 'node:crypto';
|
|
2
2
|
import { existsSync, rmSync } from 'node:fs';
|
|
3
|
-
import path, {
|
|
3
|
+
import path, { isAbsolute, join as pathJoin, resolve } from 'node:path';
|
|
4
4
|
import assert from 'node:assert';
|
|
5
5
|
import { EventEmitter } from 'node:events';
|
|
6
6
|
import process from 'node:process';
|
|
7
|
+
import { mock } from 'node:test';
|
|
7
8
|
import { camelCase, kebabCase, merge as lodashMerge, set as lodashSet } from 'lodash-es';
|
|
8
9
|
import { resetFileCommitStates } from 'mem-fs-editor/state';
|
|
9
10
|
import { create as createMemFs } from 'mem-fs';
|
|
10
11
|
import tempDirectory from 'temp-dir';
|
|
11
|
-
import { stub as sinonStub } from 'sinon';
|
|
12
12
|
import { create as createMemFsEditor } from 'mem-fs-editor';
|
|
13
13
|
import RunResult from './run-result.js';
|
|
14
14
|
import defaultHelpers from './helpers.js';
|
|
15
15
|
import testContext from './test-context.js';
|
|
16
|
-
// eslint-disable-next-line unicorn/prefer-event-target
|
|
17
16
|
export class RunContextBase extends EventEmitter {
|
|
18
17
|
mockedGenerators = {};
|
|
19
18
|
env;
|
|
@@ -57,13 +56,13 @@ export class RunContextBase extends EventEmitter {
|
|
|
57
56
|
* @param settings
|
|
58
57
|
* @return {this}
|
|
59
58
|
*/
|
|
60
|
-
constructor(generatorType, settings,
|
|
59
|
+
constructor(generatorType, settings, environmentOptions = {}, helpers = defaultHelpers) {
|
|
61
60
|
super();
|
|
62
61
|
this.settings = {
|
|
63
62
|
...settings,
|
|
64
63
|
};
|
|
65
64
|
this.Generator = generatorType;
|
|
66
|
-
this.envOptions =
|
|
65
|
+
this.envOptions = environmentOptions;
|
|
67
66
|
this.oldCwd = this.settings.oldCwd;
|
|
68
67
|
if (this.settings.cwd) {
|
|
69
68
|
this.cd(this.settings.cwd);
|
|
@@ -97,7 +96,6 @@ export class RunContextBase extends EventEmitter {
|
|
|
97
96
|
super.on(eventName, listener);
|
|
98
97
|
// Don't setup emitters if on generator envent.
|
|
99
98
|
if (eventName !== 'generator') {
|
|
100
|
-
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
101
99
|
this.setupEventListeners();
|
|
102
100
|
}
|
|
103
101
|
return this;
|
|
@@ -110,9 +108,9 @@ export class RunContextBase extends EventEmitter {
|
|
|
110
108
|
* @param [cb] - callback who'll receive the folder path as argument
|
|
111
109
|
* @return run context instance
|
|
112
110
|
*/
|
|
113
|
-
inDir(dirPath,
|
|
111
|
+
inDir(dirPath, callback) {
|
|
114
112
|
this.setDir(dirPath, true);
|
|
115
|
-
this.helpers.testDirectory(dirPath, () =>
|
|
113
|
+
this.helpers.testDirectory(dirPath, () => callback?.call(this, path.resolve(dirPath)));
|
|
116
114
|
return this;
|
|
117
115
|
}
|
|
118
116
|
/**
|
|
@@ -120,8 +118,8 @@ export class RunContextBase extends EventEmitter {
|
|
|
120
118
|
* @param [cb] - callback who'll receive the folder path as argument
|
|
121
119
|
* @return this - run context instance
|
|
122
120
|
*/
|
|
123
|
-
doInDir(
|
|
124
|
-
this.inDirCallbacks.push(
|
|
121
|
+
doInDir(callback) {
|
|
122
|
+
this.inDirCallbacks.push(callback);
|
|
125
123
|
return this;
|
|
126
124
|
}
|
|
127
125
|
/**
|
|
@@ -152,8 +150,8 @@ export class RunContextBase extends EventEmitter {
|
|
|
152
150
|
* @param [cb] - callback who'll receive the folder path as argument
|
|
153
151
|
* @return this - run context instance
|
|
154
152
|
*/
|
|
155
|
-
inTmpDir(
|
|
156
|
-
return this.inDir(this.temporaryDir,
|
|
153
|
+
inTmpDir(callback) {
|
|
154
|
+
return this.inDir(this.temporaryDir, callback);
|
|
157
155
|
}
|
|
158
156
|
/**
|
|
159
157
|
* Restore cwd to initial cwd.
|
|
@@ -213,8 +211,8 @@ export class RunContextBase extends EventEmitter {
|
|
|
213
211
|
* @param {Function} [cb] - callback who'll receive the folder path as argument
|
|
214
212
|
* @return {this} run context instance
|
|
215
213
|
*/
|
|
216
|
-
withEnvironment(
|
|
217
|
-
this.envCB =
|
|
214
|
+
withEnvironment(callback) {
|
|
215
|
+
this.envCB = callback;
|
|
218
216
|
return this;
|
|
219
217
|
}
|
|
220
218
|
/**
|
|
@@ -223,11 +221,10 @@ export class RunContextBase extends EventEmitter {
|
|
|
223
221
|
* @param lookups - lookup to run.
|
|
224
222
|
*/
|
|
225
223
|
withLookups(lookups) {
|
|
226
|
-
return this.onEnvironment(async (
|
|
224
|
+
return this.onEnvironment(async (environment) => {
|
|
227
225
|
lookups = Array.isArray(lookups) ? lookups : [lookups];
|
|
228
226
|
for (const lookup of lookups) {
|
|
229
|
-
|
|
230
|
-
await env.lookup(lookup);
|
|
227
|
+
await environment.lookup(lookup);
|
|
231
228
|
}
|
|
232
229
|
});
|
|
233
230
|
}
|
|
@@ -235,10 +232,10 @@ export class RunContextBase extends EventEmitter {
|
|
|
235
232
|
* Provide arguments to the run context
|
|
236
233
|
* @param args - command line arguments as Array or space separated string
|
|
237
234
|
*/
|
|
238
|
-
withArguments(
|
|
239
|
-
const
|
|
240
|
-
assert(Array.isArray(
|
|
241
|
-
this.args = this.args
|
|
235
|
+
withArguments(arguments_) {
|
|
236
|
+
const argumentsArray = typeof arguments_ === 'string' ? arguments_.split(' ') : arguments_;
|
|
237
|
+
assert(Array.isArray(argumentsArray), 'args should be either a string separated by spaces or an array');
|
|
238
|
+
this.args = [...this.args, ...argumentsArray];
|
|
242
239
|
return this;
|
|
243
240
|
}
|
|
244
241
|
/**
|
|
@@ -300,13 +297,13 @@ export class RunContextBase extends EventEmitter {
|
|
|
300
297
|
*/
|
|
301
298
|
withGenerators(dependencies) {
|
|
302
299
|
assert(Array.isArray(dependencies), 'dependencies should be an array');
|
|
303
|
-
return this.onEnvironment(async (
|
|
300
|
+
return this.onEnvironment(async (environment) => {
|
|
304
301
|
for (const dependency of dependencies) {
|
|
305
302
|
if (typeof dependency === 'string') {
|
|
306
|
-
|
|
303
|
+
environment.register(dependency);
|
|
307
304
|
}
|
|
308
305
|
else {
|
|
309
|
-
|
|
306
|
+
environment.register(...dependency);
|
|
310
307
|
}
|
|
311
308
|
}
|
|
312
309
|
});
|
|
@@ -315,31 +312,33 @@ export class RunContextBase extends EventEmitter {
|
|
|
315
312
|
if (this.spawnStub) {
|
|
316
313
|
throw new Error('Multiple withSpawnMock calls');
|
|
317
314
|
}
|
|
318
|
-
const
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
if (registerSinonDefaults) {
|
|
322
|
-
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
315
|
+
const registerNodeMockDefaults = typeof options === 'function' ? false : (options?.registerNodeMockDefaults ?? true);
|
|
316
|
+
let implementation;
|
|
317
|
+
if (registerNodeMockDefaults) {
|
|
323
318
|
const defaultChild = { stdout: { on() { } }, stderr: { on() { } } };
|
|
324
319
|
const defaultReturn = { exitCode: 0, stdout: '', stderr: '' };
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
320
|
+
implementation = (...arguments_) => {
|
|
321
|
+
const [methodName] = arguments_;
|
|
322
|
+
if (methodName === 'spawnCommand' || methodName === 'spawn') {
|
|
323
|
+
return Object.assign(Promise.resolve({ ...defaultReturn }), defaultChild);
|
|
324
|
+
}
|
|
325
|
+
if (methodName === 'spawnCommandSync' || methodName === 'spawnSync') {
|
|
326
|
+
return { ...defaultReturn };
|
|
327
|
+
}
|
|
328
|
+
};
|
|
332
329
|
}
|
|
330
|
+
const stub = typeof options === 'function' ? options : (options?.stub ?? mock.fn(() => { }, implementation));
|
|
331
|
+
const callback = typeof options === 'function' ? undefined : options?.callback;
|
|
333
332
|
if (callback) {
|
|
334
333
|
this.onBeforePrepare(async () => {
|
|
335
|
-
await callback(stub);
|
|
334
|
+
await callback({ stub, implementation });
|
|
336
335
|
});
|
|
337
336
|
}
|
|
338
337
|
this.spawnStub = stub;
|
|
339
|
-
return this.onEnvironment(
|
|
340
|
-
|
|
341
|
-
const createCallback = method => function (...
|
|
342
|
-
return stub.call(this, method, ...
|
|
338
|
+
return this.onEnvironment(environment => {
|
|
339
|
+
environment.on('compose', (_namespace, generator) => {
|
|
340
|
+
const createCallback = method => function (...arguments_) {
|
|
341
|
+
return stub.call(this, method, ...arguments_);
|
|
343
342
|
};
|
|
344
343
|
generator.spawnCommand = createCallback('spawnCommand');
|
|
345
344
|
generator.spawnCommandSync = createCallback('spawnCommandSync');
|
|
@@ -476,9 +475,8 @@ export class RunContextBase extends EventEmitter {
|
|
|
476
475
|
}
|
|
477
476
|
async prepare() {
|
|
478
477
|
if (this.beforePrepareCallbacks.length > 0) {
|
|
479
|
-
for (const
|
|
480
|
-
|
|
481
|
-
await cb.call(this);
|
|
478
|
+
for (const callback of this.beforePrepareCallbacks) {
|
|
479
|
+
await callback.call(this);
|
|
482
480
|
}
|
|
483
481
|
}
|
|
484
482
|
this.assertNotBuild();
|
|
@@ -491,9 +489,8 @@ export class RunContextBase extends EventEmitter {
|
|
|
491
489
|
}
|
|
492
490
|
if (this.inDirCallbacks.length > 0) {
|
|
493
491
|
const targetDirectory = path.resolve(this.targetDirectory);
|
|
494
|
-
for (const
|
|
495
|
-
|
|
496
|
-
await cb(targetDirectory);
|
|
492
|
+
for (const callback of this.inDirCallbacks) {
|
|
493
|
+
await callback(targetDirectory);
|
|
497
494
|
}
|
|
498
495
|
}
|
|
499
496
|
if (!this.targetDirectory) {
|
|
@@ -506,7 +503,6 @@ export class RunContextBase extends EventEmitter {
|
|
|
506
503
|
}
|
|
507
504
|
this.editor = createMemFsEditor(this.memFs);
|
|
508
505
|
for (const onTargetDirectory of this.onTargetDirectoryCallbacks) {
|
|
509
|
-
// eslint-disable-next-line no-await-in-loop
|
|
510
506
|
await onTargetDirectory.call(this, this.targetDirectory);
|
|
511
507
|
}
|
|
512
508
|
}
|
|
@@ -519,7 +515,6 @@ export class RunContextBase extends EventEmitter {
|
|
|
519
515
|
* Build the generator and the environment.
|
|
520
516
|
* @return {RunContext|false} this
|
|
521
517
|
*/
|
|
522
|
-
// eslint-disable-next-line @typescript-eslint/member-ordering
|
|
523
518
|
async build() {
|
|
524
519
|
await this.prepare();
|
|
525
520
|
const { askedQuestions, adapterOptions } = this;
|
|
@@ -530,7 +525,7 @@ export class RunContextBase extends EventEmitter {
|
|
|
530
525
|
}
|
|
531
526
|
return adapterOptions?.callback ? adapterOptions.callback.call(this, answer, options) : answer;
|
|
532
527
|
};
|
|
533
|
-
const
|
|
528
|
+
const testEnvironment = await this.helpers.createTestEnv(this.envOptions.createEnv, {
|
|
534
529
|
cwd: this.settings.forwardCwd ? this.targetDirectory : undefined,
|
|
535
530
|
sharedFs: this.memFs,
|
|
536
531
|
force: true,
|
|
@@ -539,9 +534,8 @@ export class RunContextBase extends EventEmitter {
|
|
|
539
534
|
adapter: this.helpers.createTestAdapter({ ...this.adapterOptions, mockedAnswers: this.answers, callback: promptCallback }),
|
|
540
535
|
...this.envOptions,
|
|
541
536
|
});
|
|
542
|
-
this.env = this.envCB ? (await this.envCB(
|
|
537
|
+
this.env = this.envCB ? ((await this.envCB(testEnvironment)) ?? testEnvironment) : testEnvironment;
|
|
543
538
|
for (const onEnvironmentCallback of this.onEnvironmentCallbacks) {
|
|
544
|
-
// eslint-disable-next-line no-await-in-loop
|
|
545
539
|
await onEnvironmentCallback.call(this, this.env);
|
|
546
540
|
}
|
|
547
541
|
const { namespace = typeof this.Generator === 'string' ? this.env.namespace(this.Generator) : 'gen:test' } = this.settings;
|
|
@@ -563,7 +557,6 @@ export class RunContextBase extends EventEmitter {
|
|
|
563
557
|
},
|
|
564
558
|
});
|
|
565
559
|
for (const onGeneratorCallback of this.onGeneratorCallbacks) {
|
|
566
|
-
// eslint-disable-next-line no-await-in-loop
|
|
567
560
|
await onGeneratorCallback.call(this, this.generator);
|
|
568
561
|
}
|
|
569
562
|
}
|
|
@@ -605,8 +598,7 @@ export class RunContextBase extends EventEmitter {
|
|
|
605
598
|
.catch(error => {
|
|
606
599
|
if (this.listenerCount('end') === 0 && this.listenerCount('error') === 0) {
|
|
607
600
|
// When there is no listeners throw a unhandled rejection.
|
|
608
|
-
setImmediate(async
|
|
609
|
-
// eslint-disable-next-line @typescript-eslint/no-throw-literal
|
|
601
|
+
setImmediate(async () => {
|
|
610
602
|
throw error;
|
|
611
603
|
});
|
|
612
604
|
}
|
|
@@ -640,7 +632,6 @@ export class RunContextBase extends EventEmitter {
|
|
|
640
632
|
}
|
|
641
633
|
}
|
|
642
634
|
export default class RunContext extends RunContextBase {
|
|
643
|
-
// eslint-disable-next-line unicorn/no-thenable
|
|
644
635
|
async then(onfulfilled, onrejected) {
|
|
645
636
|
return this.toPromise().then(onfulfilled, onrejected);
|
|
646
637
|
}
|
package/dist/run-result.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Store } from 'mem-fs';
|
|
2
|
-
import { type
|
|
2
|
+
import { type MemFsEditor, type MemFsEditorFile } from 'mem-fs-editor';
|
|
3
3
|
import type { BaseEnvironmentOptions, BaseGenerator, GetGeneratorConstructor } from '@yeoman/types';
|
|
4
4
|
import type { DefaultEnvironmentApi, DefaultGeneratorApi } from '../types/type-helpers.js';
|
|
5
5
|
import { type RunContextSettings } from './run-context.js';
|
|
@@ -56,8 +56,8 @@ export default class RunResult<GeneratorType extends BaseGenerator = BaseGenerat
|
|
|
56
56
|
* Create another RunContext reusing the settings.
|
|
57
57
|
* See helpers.create api
|
|
58
58
|
*/
|
|
59
|
-
create<GeneratorType extends BaseGenerator = DefaultGeneratorApi>(GeneratorOrNamespace: string | GetGeneratorConstructor<GeneratorType>, settings?: RunContextSettings,
|
|
60
|
-
getSpawnArgsUsingDefaultImplementation():
|
|
59
|
+
create<GeneratorType extends BaseGenerator = DefaultGeneratorApi>(GeneratorOrNamespace: string | GetGeneratorConstructor<GeneratorType>, settings?: RunContextSettings, environmentOptions?: BaseEnvironmentOptions): import("./run-context.js").default<GeneratorType>;
|
|
60
|
+
getSpawnArgsUsingDefaultImplementation(): unknown[][];
|
|
61
61
|
/**
|
|
62
62
|
* Return an object with fs changes.
|
|
63
63
|
* @param {Function} filter - parameter forwarded to mem-fs-editor#dump
|
package/dist/run-result.js
CHANGED
|
@@ -4,13 +4,13 @@ import path from 'node:path';
|
|
|
4
4
|
import process from 'node:process';
|
|
5
5
|
import { create as createMemFsEditor } from 'mem-fs-editor';
|
|
6
6
|
const isObject = object => typeof object === 'object' && object !== null && object !== undefined;
|
|
7
|
-
|
|
8
|
-
if (
|
|
9
|
-
return [[...
|
|
7
|
+
const convertArguments = arguments_ => {
|
|
8
|
+
if (arguments_.length > 1) {
|
|
9
|
+
return [[...arguments_]];
|
|
10
10
|
}
|
|
11
|
-
const
|
|
12
|
-
return Array.isArray(
|
|
13
|
-
}
|
|
11
|
+
const [argument] = arguments_;
|
|
12
|
+
return Array.isArray(argument) ? argument : [argument];
|
|
13
|
+
};
|
|
14
14
|
/**
|
|
15
15
|
* This class provides utilities for testing generated content.
|
|
16
16
|
*/
|
|
@@ -44,7 +44,7 @@ export default class RunResult {
|
|
|
44
44
|
* Create another RunContext reusing the settings.
|
|
45
45
|
* See helpers.create api
|
|
46
46
|
*/
|
|
47
|
-
create(GeneratorOrNamespace, settings,
|
|
47
|
+
create(GeneratorOrNamespace, settings, environmentOptions) {
|
|
48
48
|
return this.options.helpers.create(GeneratorOrNamespace, {
|
|
49
49
|
...this.options.settings,
|
|
50
50
|
cwd: this.cwd,
|
|
@@ -52,13 +52,13 @@ export default class RunResult {
|
|
|
52
52
|
memFs: this.memFs,
|
|
53
53
|
...settings,
|
|
54
54
|
autoCleanup: false,
|
|
55
|
-
}, { ...this.options.envOptions, ...
|
|
55
|
+
}, { ...this.options.envOptions, ...environmentOptions });
|
|
56
56
|
}
|
|
57
57
|
getSpawnArgsUsingDefaultImplementation() {
|
|
58
58
|
if (!this.spawnStub) {
|
|
59
59
|
throw new Error('Spawn stub was not found');
|
|
60
60
|
}
|
|
61
|
-
return this.spawnStub.
|
|
61
|
+
return this.spawnStub.mock.calls.map(call => call.arguments);
|
|
62
62
|
}
|
|
63
63
|
/**
|
|
64
64
|
* Return an object with fs changes.
|
|
@@ -154,7 +154,7 @@ export default class RunResult {
|
|
|
154
154
|
* result.assertFile(['templates/user.hbs', 'templates/user/edit.hbs']);
|
|
155
155
|
*/
|
|
156
156
|
assertFile(path) {
|
|
157
|
-
for (const file of
|
|
157
|
+
for (const file of convertArguments([path])) {
|
|
158
158
|
const here = this._exists(file);
|
|
159
159
|
assert.ok(here, `${file}, no such file or directory`);
|
|
160
160
|
}
|
|
@@ -173,15 +173,14 @@ export default class RunResult {
|
|
|
173
173
|
* result.assertNoFile(['templates/user.hbs', 'templates/user/edit.hbs']);
|
|
174
174
|
*/
|
|
175
175
|
assertNoFile(files) {
|
|
176
|
-
for (const file of
|
|
176
|
+
for (const file of convertArguments([files])) {
|
|
177
177
|
const here = this._exists(file);
|
|
178
178
|
assert.ok(!here, `${file} exists`);
|
|
179
179
|
}
|
|
180
180
|
}
|
|
181
|
-
assertFileContent(...
|
|
182
|
-
for (const pair of
|
|
183
|
-
const file = pair
|
|
184
|
-
const regex = pair[1];
|
|
181
|
+
assertFileContent(...arguments_) {
|
|
182
|
+
for (const pair of convertArguments(arguments_)) {
|
|
183
|
+
const [file, regex] = pair;
|
|
185
184
|
this.assertFile(file);
|
|
186
185
|
const body = this._readFile(file);
|
|
187
186
|
let match = false;
|
|
@@ -189,18 +188,16 @@ export default class RunResult {
|
|
|
189
188
|
assert(match, `${file} did not match '${regex}'. Contained:\n\n${body}`);
|
|
190
189
|
}
|
|
191
190
|
}
|
|
192
|
-
assertEqualsFileContent(...
|
|
193
|
-
for (const pair of
|
|
194
|
-
const file = pair
|
|
195
|
-
const expectedContent = pair[1];
|
|
191
|
+
assertEqualsFileContent(...arguments_) {
|
|
192
|
+
for (const pair of convertArguments(arguments_)) {
|
|
193
|
+
const [file, expectedContent] = pair;
|
|
196
194
|
this.assertFile(file);
|
|
197
195
|
this.assertTextEqual(this._readFile(file), expectedContent);
|
|
198
196
|
}
|
|
199
197
|
}
|
|
200
|
-
assertNoFileContent(...
|
|
201
|
-
for (const pair of
|
|
202
|
-
const file = pair
|
|
203
|
-
const regex = pair[1];
|
|
198
|
+
assertNoFileContent(...arguments_) {
|
|
199
|
+
for (const pair of convertArguments(arguments_)) {
|
|
200
|
+
const [file, regex] = pair;
|
|
204
201
|
this.assertFile(file);
|
|
205
202
|
const body = this._readFile(file);
|
|
206
203
|
if (typeof regex === 'string') {
|
package/dist/test-context.d.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import type RunContext from './run-context.js';
|
|
2
1
|
import type RunResult from './run-result.js';
|
|
3
2
|
declare class TestContext {
|
|
3
|
+
beforeCwd?: string;
|
|
4
|
+
autoRestore: boolean;
|
|
5
|
+
autoCleanup?: boolean;
|
|
4
6
|
runResult?: RunResult;
|
|
5
7
|
private runContext?;
|
|
6
|
-
startNewContext(runContext?:
|
|
8
|
+
startNewContext(runContext?: any, autoCleanup?: boolean): void;
|
|
7
9
|
}
|
|
8
10
|
declare const testContext: TestContext;
|
|
9
11
|
export default testContext;
|
package/dist/test-context.js
CHANGED
|
@@ -1,27 +1,40 @@
|
|
|
1
1
|
import process from 'node:process';
|
|
2
|
+
import { onExit } from 'signal-exit';
|
|
2
3
|
class TestContext {
|
|
4
|
+
beforeCwd;
|
|
5
|
+
autoRestore = true;
|
|
6
|
+
autoCleanup;
|
|
3
7
|
runResult;
|
|
4
8
|
runContext;
|
|
5
|
-
startNewContext(runContext) {
|
|
6
|
-
this.
|
|
9
|
+
startNewContext(runContext, autoCleanup = true) {
|
|
10
|
+
if (this.beforeCwd !== process.cwd()) {
|
|
11
|
+
if (this.autoCleanup) {
|
|
12
|
+
this.runContext?.cleanupTemporaryDir();
|
|
13
|
+
}
|
|
14
|
+
else if (this.autoRestore) {
|
|
15
|
+
this.runContext?.restore();
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
if (this.beforeCwd && this.beforeCwd !== process.cwd()) {
|
|
19
|
+
console.log('Test failed to restore context', this.beforeCwd, process.cwd());
|
|
20
|
+
}
|
|
21
|
+
this.autoCleanup = autoCleanup;
|
|
22
|
+
this.beforeCwd = runContext ? process.cwd() : undefined;
|
|
7
23
|
this.runContext = runContext;
|
|
8
24
|
this.runResult = undefined;
|
|
9
25
|
}
|
|
10
26
|
}
|
|
11
27
|
const testContext = new TestContext();
|
|
12
|
-
|
|
28
|
+
onExit(() => {
|
|
13
29
|
testContext.startNewContext();
|
|
14
|
-
};
|
|
15
|
-
process.on('exit', cleanupTemporaryDir);
|
|
16
|
-
process.on('SIGINT', cleanupTemporaryDir);
|
|
17
|
-
process.on('SIGTERM', cleanupTemporaryDir);
|
|
30
|
+
});
|
|
18
31
|
export default testContext;
|
|
19
32
|
const handler2 = {
|
|
20
|
-
get(_target,
|
|
33
|
+
get(_target, property, receiver) {
|
|
21
34
|
if (testContext.runResult === undefined) {
|
|
22
35
|
throw new Error('Last result is missing.');
|
|
23
36
|
}
|
|
24
|
-
return Reflect.get(testContext.runResult,
|
|
37
|
+
return Reflect.get(testContext.runResult, property, receiver);
|
|
25
38
|
},
|
|
26
39
|
};
|
|
27
40
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "yeoman-test",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "9.0.0",
|
|
4
4
|
"description": "Test utilities for Yeoman generators",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"yeoman",
|
|
@@ -12,8 +12,13 @@
|
|
|
12
12
|
"author": "The Yeoman Team",
|
|
13
13
|
"type": "module",
|
|
14
14
|
"exports": {
|
|
15
|
-
"
|
|
16
|
-
|
|
15
|
+
"./mocha-cleanup": {
|
|
16
|
+
"import": "./dist/mocha-cleanup.hooks.js"
|
|
17
|
+
},
|
|
18
|
+
".": {
|
|
19
|
+
"types": "./dist/index.d.ts",
|
|
20
|
+
"import": "./dist/index.js"
|
|
21
|
+
}
|
|
17
22
|
},
|
|
18
23
|
"types": "./dist/index.d.ts",
|
|
19
24
|
"files": [
|
|
@@ -27,52 +32,45 @@
|
|
|
27
32
|
"doc:fix": "sed -i -e 's:^[[:space:]]*<!--[[:space:]]*$::g' -e 's:^[[:space:]]*-->[[:space:]]*$::g' $npm_package_config_doc_path/global.html",
|
|
28
33
|
"doc:generate": "jsdoc -c jsdoc.json -d $npm_package_config_doc_path",
|
|
29
34
|
"doc:prettier": "prettier $npm_package_config_doc_path --write --ignore-path .prettierignore-doc",
|
|
35
|
+
"fix": "prettier . --write && eslint . --fix",
|
|
30
36
|
"precommit": "lint-staged",
|
|
31
|
-
"prepare": "npm run build",
|
|
32
|
-
"pretest": "
|
|
33
|
-
"test": "
|
|
37
|
+
"prepare": "npm run build && husky",
|
|
38
|
+
"pretest": "eslint .",
|
|
39
|
+
"test": "vitest run --coverage"
|
|
34
40
|
},
|
|
35
41
|
"config": {
|
|
36
42
|
"doc_path": "../yeoman-test-doc"
|
|
37
43
|
},
|
|
38
44
|
"dependencies": {
|
|
39
|
-
"@yeoman/adapter": "^1.
|
|
40
|
-
"inquirer": "^9.2.2",
|
|
45
|
+
"@yeoman/adapter": "^1.6.0",
|
|
41
46
|
"lodash-es": "^4.17.21",
|
|
42
|
-
"mem-fs-editor": "^
|
|
43
|
-
"
|
|
47
|
+
"mem-fs-editor": "^11.1.1",
|
|
48
|
+
"signal-exit": "^4.1.0",
|
|
44
49
|
"temp-dir": "^3.0.0",
|
|
45
|
-
"type-fest": "^4.
|
|
50
|
+
"type-fest": "^4.25.0"
|
|
46
51
|
},
|
|
47
52
|
"devDependencies": {
|
|
48
|
-
"@types/
|
|
49
|
-
"@types/
|
|
50
|
-
"@
|
|
51
|
-
"@
|
|
52
|
-
"c8": "^8.0.0",
|
|
53
|
+
"@types/lodash-es": "^4.17.12",
|
|
54
|
+
"@types/node": "^18.19.46",
|
|
55
|
+
"@vitest/coverage-v8": "^2.0.5",
|
|
56
|
+
"@yeoman/eslint": "0.2.0",
|
|
53
57
|
"coveralls": "^3.1.1",
|
|
54
|
-
"
|
|
55
|
-
"husky": "^8.0.2",
|
|
58
|
+
"husky": "^9.1.5",
|
|
56
59
|
"jsdoc": "^4.0.2",
|
|
57
|
-
"lint-staged": "^
|
|
58
|
-
"prettier": "^3.
|
|
60
|
+
"lint-staged": "^15.2.9",
|
|
61
|
+
"prettier": "^3.3.3",
|
|
59
62
|
"prettier-plugin-packagejson": "^2.3.0",
|
|
60
63
|
"tui-jsdoc-template": "^1.2.2",
|
|
61
|
-
"typescript": "
|
|
62
|
-
"
|
|
63
|
-
"yeoman-environment": "^
|
|
64
|
-
"yeoman-generator": "^
|
|
64
|
+
"typescript": "^5.5.4",
|
|
65
|
+
"vitest": "^2.0.5",
|
|
66
|
+
"yeoman-environment": "^4.4.1",
|
|
67
|
+
"yeoman-generator": "^7.3.2"
|
|
65
68
|
},
|
|
66
69
|
"peerDependencies": {
|
|
67
|
-
"@yeoman/types": "^1.
|
|
68
|
-
"mem-fs": "^
|
|
69
|
-
"yeoman-environment": "^
|
|
70
|
-
"yeoman-generator": "^
|
|
71
|
-
},
|
|
72
|
-
"acceptDependencies": {
|
|
73
|
-
"mem-fs": "^4.0.0-beta.1",
|
|
74
|
-
"yeoman-environment": ">=4.0.0-beta.6",
|
|
75
|
-
"yeoman-generator": ">=6.0.0"
|
|
70
|
+
"@yeoman/types": "^1.4.0",
|
|
71
|
+
"mem-fs": "^4.1.0",
|
|
72
|
+
"yeoman-environment": "^4.0.0",
|
|
73
|
+
"yeoman-generator": "^7.0.0"
|
|
76
74
|
},
|
|
77
75
|
"peerDependenciesMeta": {
|
|
78
76
|
"yeoman-environment": {
|
|
@@ -83,6 +81,6 @@
|
|
|
83
81
|
}
|
|
84
82
|
},
|
|
85
83
|
"engines": {
|
|
86
|
-
"node": "^
|
|
84
|
+
"node": "^18.19.0 || >= 20.6.1"
|
|
87
85
|
}
|
|
88
86
|
}
|
package/types/type-helpers.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { BaseEnvironment, BaseGenerator } from '@yeoman/types';
|
|
2
2
|
import type GeneratorImplementation from 'yeoman-generator';
|
|
3
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
3
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
4
4
|
// @ts-ignore
|
|
5
5
|
import type EnvironmentImplementation from 'yeoman-environment';
|
|
6
6
|
import type { IfAny } from 'type-fest';
|