yeoman-test 8.0.0-beta.6 → 8.0.0-beta.7
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.d.ts +14 -5
- package/dist/adapter.js +22 -36
- package/dist/helpers.d.ts +5 -2
- package/dist/helpers.js +8 -11
- package/dist/run-context.d.ts +8 -3
- package/dist/run-context.js +12 -7
- package/package.json +4 -3
package/dist/adapter.d.ts
CHANGED
|
@@ -1,22 +1,31 @@
|
|
|
1
1
|
import type { PromptAnswers, PromptQuestion, Logger, InputOutputAdapter, PromptQuestions } from '@yeoman/types';
|
|
2
2
|
import { type PromptModule } from 'inquirer';
|
|
3
|
+
export type DummyPromptCallback = (answer: any, { question, answers }: {
|
|
4
|
+
question: PromptQuestion;
|
|
5
|
+
answers: PromptAnswers;
|
|
6
|
+
}) => any;
|
|
3
7
|
export type DummyPromptOptions = {
|
|
4
|
-
|
|
8
|
+
mockedAnswers?: PromptAnswers;
|
|
9
|
+
callback?: DummyPromptCallback;
|
|
5
10
|
throwOnMissingAnswer?: boolean;
|
|
6
11
|
};
|
|
12
|
+
export type TestAdapterOptions = DummyPromptOptions & {
|
|
13
|
+
log?: any;
|
|
14
|
+
};
|
|
7
15
|
export declare class DummyPrompt {
|
|
8
16
|
answers: PromptAnswers;
|
|
9
17
|
question: PromptQuestion;
|
|
10
|
-
callback:
|
|
18
|
+
callback: DummyPromptCallback;
|
|
11
19
|
throwOnMissingAnswer: boolean;
|
|
12
|
-
constructor(question: PromptQuestion, _rl: any, answers: PromptAnswers,
|
|
13
|
-
run(): Promise<
|
|
20
|
+
constructor(question: PromptQuestion, _rl: any, answers: PromptAnswers, options?: DummyPromptOptions);
|
|
21
|
+
run(): Promise<any>;
|
|
14
22
|
}
|
|
15
23
|
export declare class TestAdapter implements InputOutputAdapter {
|
|
16
24
|
promptModule: PromptModule;
|
|
17
25
|
diff: any;
|
|
18
26
|
log: Logger;
|
|
19
|
-
|
|
27
|
+
registerDummyPrompt: (promptName: string, customPromptOptions?: DummyPromptOptions) => PromptModule;
|
|
28
|
+
constructor(options?: TestAdapterOptions);
|
|
20
29
|
close(): void;
|
|
21
30
|
prompt<A extends PromptAnswers = PromptAnswers>(questions: PromptQuestions<A>, initialAnswers?: Partial<A> | undefined): Promise<A>;
|
|
22
31
|
}
|
package/dist/adapter.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
/* eslint-disable max-params */
|
|
2
1
|
import events from 'node:events';
|
|
3
2
|
import { PassThrough } from 'node:stream';
|
|
3
|
+
import { createLogger } from '@yeoman/adapter';
|
|
4
4
|
import { spy as sinonSpy, stub as sinonStub } from 'sinon';
|
|
5
5
|
import { createPromptModule } from 'inquirer';
|
|
6
6
|
export class DummyPrompt {
|
|
@@ -8,21 +8,12 @@ export class DummyPrompt {
|
|
|
8
8
|
question;
|
|
9
9
|
callback;
|
|
10
10
|
throwOnMissingAnswer = false;
|
|
11
|
-
constructor(question, _rl, answers,
|
|
11
|
+
constructor(question, _rl, answers, options = {}) {
|
|
12
|
+
const { mockedAnswers, callback, throwOnMissingAnswer } = options;
|
|
12
13
|
this.answers = { ...answers, ...mockedAnswers };
|
|
13
14
|
this.question = question;
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
}
|
|
17
|
-
else if (options) {
|
|
18
|
-
if (options.callback) {
|
|
19
|
-
this.callback = options.callback;
|
|
20
|
-
}
|
|
21
|
-
if (options.throwOnMissingAnswer !== undefined) {
|
|
22
|
-
this.throwOnMissingAnswer = options.throwOnMissingAnswer;
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
this.callback = this.callback || (answers => answers);
|
|
15
|
+
this.callback = callback ?? (answers => answers);
|
|
16
|
+
this.throwOnMissingAnswer = throwOnMissingAnswer ?? false;
|
|
26
17
|
}
|
|
27
18
|
async run() {
|
|
28
19
|
let answer = this.answers[this.question.name];
|
|
@@ -56,45 +47,40 @@ export class DummyPrompt {
|
|
|
56
47
|
answer = true;
|
|
57
48
|
}
|
|
58
49
|
}
|
|
59
|
-
return this.callback(answer);
|
|
50
|
+
return this.callback(answer, { question: this.question, answers: this.answers });
|
|
60
51
|
}
|
|
61
52
|
}
|
|
62
53
|
export class TestAdapter {
|
|
63
54
|
promptModule;
|
|
64
55
|
diff;
|
|
65
56
|
log;
|
|
66
|
-
|
|
57
|
+
registerDummyPrompt;
|
|
58
|
+
constructor(options = {}) {
|
|
59
|
+
const { log = createLogger(), ...promptOptions } = options;
|
|
67
60
|
this.promptModule = createPromptModule({
|
|
68
61
|
input: new PassThrough(),
|
|
69
62
|
output: new PassThrough(),
|
|
70
63
|
skipTTYChecks: true,
|
|
71
64
|
});
|
|
65
|
+
const actualRegisterPrompt = this.promptModule.registerPrompt.bind(this.promptModule);
|
|
66
|
+
this.registerDummyPrompt = (promptModuleName, customPromptOptions) => actualRegisterPrompt(promptModuleName, class CustomDummyPrompt extends DummyPrompt {
|
|
67
|
+
constructor(question, rl, answers) {
|
|
68
|
+
super(question, rl, answers, customPromptOptions ?? promptOptions);
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
this.promptModule.registerPrompt = (name) => this.registerDummyPrompt(name);
|
|
72
72
|
for (const promptName of Object.keys(this.promptModule.prompts)) {
|
|
73
|
-
this.promptModule.registerPrompt(promptName,
|
|
74
|
-
constructor(question, rl, answers) {
|
|
75
|
-
super(question, rl, answers, mockedAnswers);
|
|
76
|
-
}
|
|
77
|
-
});
|
|
73
|
+
this.promptModule.registerPrompt(promptName, undefined);
|
|
78
74
|
}
|
|
79
75
|
this.diff = sinonSpy();
|
|
80
76
|
this.log = sinonSpy();
|
|
81
77
|
Object.assign(this.log, events.EventEmitter.prototype);
|
|
78
|
+
const descriptors = Object.getOwnPropertyDescriptors(log);
|
|
82
79
|
// Make sure all log methods are defined
|
|
83
|
-
const
|
|
84
|
-
'
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
'error',
|
|
88
|
-
'skip',
|
|
89
|
-
'force',
|
|
90
|
-
'create',
|
|
91
|
-
'invoke',
|
|
92
|
-
'conflict',
|
|
93
|
-
'identical',
|
|
94
|
-
'info',
|
|
95
|
-
'table',
|
|
96
|
-
];
|
|
97
|
-
for (const methodName of adapterMethods) {
|
|
80
|
+
const logMethods = Object.entries(descriptors)
|
|
81
|
+
.filter(([method, desc]) => typeof desc.value === 'function' && !Object.getOwnPropertyDescriptor(this.log, method))
|
|
82
|
+
.map(([method]) => method);
|
|
83
|
+
for (const methodName of logMethods) {
|
|
98
84
|
this.log[methodName] = sinonStub().returns(this.log);
|
|
99
85
|
}
|
|
100
86
|
}
|
package/dist/helpers.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { BaseEnvironment, BaseEnvironmentOptions, BaseGenerator, BaseGeneratorOptions, GetGeneratorConstructor,
|
|
1
|
+
import type { BaseEnvironment, BaseEnvironmentOptions, BaseGenerator, BaseGeneratorOptions, GetGeneratorConstructor, InstantiateOptions, PromptAnswers } from '@yeoman/types';
|
|
2
2
|
import type { SinonSpiedInstance } from 'sinon';
|
|
3
3
|
import type { DefaultEnvironmentApi, DefaultGeneratorApi } from '../types/type-helpers.js';
|
|
4
4
|
import { type DummyPromptOptions } from './adapter.js';
|
|
@@ -90,7 +90,10 @@ export declare class YeomanTest {
|
|
|
90
90
|
* ];
|
|
91
91
|
* var angular = createGenerator('angular:app', deps);
|
|
92
92
|
*/
|
|
93
|
-
createGenerator<GeneratorType extends BaseGenerator = DefaultGeneratorApi>(name: string
|
|
93
|
+
createGenerator<GeneratorType extends BaseGenerator = DefaultGeneratorApi>(name: string | GetGeneratorConstructor<GeneratorType>, options?: {
|
|
94
|
+
dependencies?: Dependency[];
|
|
95
|
+
localConfigOnly?: boolean;
|
|
96
|
+
} & InstantiateOptions<GeneratorType>): Promise<GeneratorType>;
|
|
94
97
|
/**
|
|
95
98
|
* Shortcut to the Environment's createEnv.
|
|
96
99
|
*
|
package/dist/helpers.js
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
/* eslint-disable max-params */
|
|
2
1
|
import { mkdirSync, existsSync, rmSync } from 'node:fs';
|
|
3
2
|
import { resolve } from 'node:path';
|
|
4
3
|
import process from 'node:process';
|
|
5
4
|
import _ from 'lodash';
|
|
6
5
|
import { spy as sinonSpy, stub as sinonStub } from 'sinon';
|
|
7
|
-
import {
|
|
6
|
+
import { TestAdapter } from './adapter.js';
|
|
8
7
|
import RunContext, { BasicRunContext } from './run-context.js';
|
|
9
8
|
import testContext from './test-context.js';
|
|
10
9
|
import { createEnv } from './default-environment.js';
|
|
@@ -84,13 +83,10 @@ export class YeomanTest {
|
|
|
84
83
|
if (!environment.adapter) {
|
|
85
84
|
throw new Error('environment is not an Environment instance');
|
|
86
85
|
}
|
|
87
|
-
const
|
|
86
|
+
const testAdapter = environment.adapter;
|
|
87
|
+
const { promptModule } = testAdapter;
|
|
88
88
|
for (const name of Object.keys(promptModule.prompts)) {
|
|
89
|
-
|
|
90
|
-
constructor(question, rl, answers) {
|
|
91
|
-
super(question, rl, answers, mockedAnswers, options);
|
|
92
|
-
}
|
|
93
|
-
});
|
|
89
|
+
testAdapter.registerDummyPrompt(name, { ...options, mockedAnswers });
|
|
94
90
|
}
|
|
95
91
|
}
|
|
96
92
|
/**
|
|
@@ -170,7 +166,8 @@ export class YeomanTest {
|
|
|
170
166
|
* ];
|
|
171
167
|
* var angular = createGenerator('angular:app', deps);
|
|
172
168
|
*/
|
|
173
|
-
async createGenerator(name,
|
|
169
|
+
async createGenerator(name, options = {}) {
|
|
170
|
+
const { dependencies = [], localConfigOnly = true, ...instantiateOptions } = options;
|
|
174
171
|
const env = await this.createEnv({ sharedOptions: { localConfigOnly } });
|
|
175
172
|
for (const dependency of dependencies) {
|
|
176
173
|
if (typeof dependency === 'string') {
|
|
@@ -180,7 +177,7 @@ export class YeomanTest {
|
|
|
180
177
|
env.register(...dependency);
|
|
181
178
|
}
|
|
182
179
|
}
|
|
183
|
-
return env.create(name,
|
|
180
|
+
return env.create(name, instantiateOptions);
|
|
184
181
|
}
|
|
185
182
|
/**
|
|
186
183
|
* Shortcut to the Environment's createEnv.
|
|
@@ -231,7 +228,7 @@ export class YeomanTest {
|
|
|
231
228
|
...options,
|
|
232
229
|
};
|
|
233
230
|
}
|
|
234
|
-
return envContructor({
|
|
231
|
+
return envContructor({ adapter: new TestAdapter(), ...envOptions });
|
|
235
232
|
}
|
|
236
233
|
/**
|
|
237
234
|
* Get RunContext type
|
package/dist/run-context.d.ts
CHANGED
|
@@ -6,7 +6,7 @@ import { type MemFsEditorFile, type MemFsEditor } from 'mem-fs-editor';
|
|
|
6
6
|
import type { DefaultGeneratorApi, DefaultEnvironmentApi } from '../types/type-helpers.js';
|
|
7
7
|
import RunResult, { type RunResultOptions } from './run-result.js';
|
|
8
8
|
import { type CreateEnv, type Dependency, type YeomanTest } from './helpers.js';
|
|
9
|
-
import { type DummyPromptOptions } from './adapter.js';
|
|
9
|
+
import { type DummyPromptOptions, type TestAdapterOptions } from './adapter.js';
|
|
10
10
|
/**
|
|
11
11
|
* Provides settings for creating a `RunContext`.
|
|
12
12
|
*/
|
|
@@ -51,6 +51,7 @@ export declare class RunContextBase<GeneratorType extends BaseGenerator = Defaul
|
|
|
51
51
|
private args;
|
|
52
52
|
private options;
|
|
53
53
|
private answers?;
|
|
54
|
+
private readonly adapterOptions?;
|
|
54
55
|
private keepFsState?;
|
|
55
56
|
private readonly onGeneratorCallbacks;
|
|
56
57
|
private readonly onTargetDirectoryCallbacks;
|
|
@@ -136,6 +137,10 @@ export declare class RunContextBase<GeneratorType extends BaseGenerator = Defaul
|
|
|
136
137
|
* @param force - force directory cleanup for not tmpdir
|
|
137
138
|
*/
|
|
138
139
|
cleanTestDirectory(force?: boolean): void;
|
|
140
|
+
/**
|
|
141
|
+
* TestAdapter options.
|
|
142
|
+
*/
|
|
143
|
+
withAdapterOptions(options: Omit<TestAdapterOptions, 'mockedAnswers'>): this;
|
|
139
144
|
/**
|
|
140
145
|
* Create an environment
|
|
141
146
|
*
|
|
@@ -172,14 +177,14 @@ export declare class RunContextBase<GeneratorType extends BaseGenerator = Defaul
|
|
|
172
177
|
* @param {Boolean} [options.throwOnMissingAnswer] - Throw if a answer is missing.
|
|
173
178
|
* @return {this}
|
|
174
179
|
*/
|
|
175
|
-
withPrompts(answers: PromptAnswers, options?: DummyPromptOptions): this;
|
|
180
|
+
withPrompts(answers: PromptAnswers, options?: Omit<DummyPromptOptions, 'mockedAnswers'>): this;
|
|
176
181
|
/**
|
|
177
182
|
* Mock answers for prompts
|
|
178
183
|
* @param answers - Answers to the prompt questions
|
|
179
184
|
* @param options - Options or callback.
|
|
180
185
|
* @return {this}
|
|
181
186
|
*/
|
|
182
|
-
withAnswers(answers: PromptAnswers, options?: DummyPromptOptions): this;
|
|
187
|
+
withAnswers(answers: PromptAnswers, options?: Omit<DummyPromptOptions, 'mockedAnswers'>): this;
|
|
183
188
|
/**
|
|
184
189
|
* Provide dependent generators
|
|
185
190
|
* @param {Array} dependencies - paths to the generators dependencies
|
package/dist/run-context.js
CHANGED
|
@@ -12,6 +12,7 @@ import tempDirectory from 'temp-dir';
|
|
|
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
|
+
import { TestAdapter } from './adapter.js';
|
|
15
16
|
import testContext from './test-context.js';
|
|
16
17
|
const { camelCase, kebabCase, merge: lodashMerge, set: lodashSet } = _;
|
|
17
18
|
export class RunContextBase extends EventEmitter {
|
|
@@ -29,6 +30,7 @@ export class RunContextBase extends EventEmitter {
|
|
|
29
30
|
args = [];
|
|
30
31
|
options = {};
|
|
31
32
|
answers;
|
|
33
|
+
adapterOptions = {};
|
|
32
34
|
keepFsState;
|
|
33
35
|
onGeneratorCallbacks = [];
|
|
34
36
|
onTargetDirectoryCallbacks = [];
|
|
@@ -194,6 +196,13 @@ export class RunContextBase extends EventEmitter {
|
|
|
194
196
|
rmSync(this.targetDirectory, { recursive: true });
|
|
195
197
|
}
|
|
196
198
|
}
|
|
199
|
+
/**
|
|
200
|
+
* TestAdapter options.
|
|
201
|
+
*/
|
|
202
|
+
withAdapterOptions(options) {
|
|
203
|
+
Object.assign(this.adapterOptions, options);
|
|
204
|
+
return this;
|
|
205
|
+
}
|
|
197
206
|
/**
|
|
198
207
|
* Create an environment
|
|
199
208
|
*
|
|
@@ -268,13 +277,9 @@ export class RunContextBase extends EventEmitter {
|
|
|
268
277
|
* @return {this}
|
|
269
278
|
*/
|
|
270
279
|
withAnswers(answers, options) {
|
|
271
|
-
const callbackSet = Boolean(this.answers);
|
|
272
280
|
this.answers = { ...this.answers, ...answers };
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
return this.onEnvironment(env => {
|
|
276
|
-
this.helpers.mockPrompt(env, this.answers, options);
|
|
277
|
-
});
|
|
281
|
+
Object.assign(this.adapterOptions, options);
|
|
282
|
+
return this;
|
|
278
283
|
}
|
|
279
284
|
/**
|
|
280
285
|
* Provide dependent generators
|
|
@@ -485,7 +490,7 @@ export class RunContextBase extends EventEmitter {
|
|
|
485
490
|
force: true,
|
|
486
491
|
skipCache: true,
|
|
487
492
|
skipInstall: true,
|
|
488
|
-
...this.
|
|
493
|
+
adapter: new TestAdapter({ ...this.adapterOptions, mockedAnswers: this.answers }),
|
|
489
494
|
...this.envOptions,
|
|
490
495
|
});
|
|
491
496
|
this.env = this.envCB ? (await this.envCB(testEnv)) ?? testEnv : testEnv;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "yeoman-test",
|
|
3
|
-
"version": "8.0.0-beta.
|
|
3
|
+
"version": "8.0.0-beta.7",
|
|
4
4
|
"description": "Test utilities for Yeoman generators",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"yeoman",
|
|
@@ -36,11 +36,12 @@
|
|
|
36
36
|
"doc_path": "../yeoman-test-doc"
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
|
+
"@yeoman/adapter": "^1.0.2",
|
|
39
40
|
"inquirer": "^9.2.2",
|
|
40
41
|
"lodash": "^4.17.21",
|
|
41
42
|
"mem-fs": "^3.0.0",
|
|
42
43
|
"mem-fs-editor": "^10.0.2",
|
|
43
|
-
"sinon": "^
|
|
44
|
+
"sinon": "^15.1.0",
|
|
44
45
|
"temp-dir": "^3.0.0",
|
|
45
46
|
"type-fest": "^3.10.0"
|
|
46
47
|
},
|
|
@@ -52,7 +53,7 @@
|
|
|
52
53
|
"coveralls": "^3.1.1",
|
|
53
54
|
"esmocha": "^1.0.1",
|
|
54
55
|
"husky": "^8.0.2",
|
|
55
|
-
"jsdoc": "^
|
|
56
|
+
"jsdoc": "^4.0.2",
|
|
56
57
|
"lint-staged": "^13.0.3",
|
|
57
58
|
"prettier": "^2.2.1",
|
|
58
59
|
"prettier-plugin-packagejson": "^2.3.0",
|