yeoman-test 7.1.0 → 7.3.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 CHANGED
@@ -41,7 +41,7 @@ describe('generator test', () => {
41
41
  [.withLookups({})] // runs Environment lookups
42
42
  [.withOptions({})] // passes options to the generator
43
43
  [.withLocalConfig({})] // sets the generator config as soon as it is instantiated
44
- [.withPrompts()] // simulates the prompt answers
44
+ [.withAnswers()] // simulates the prompt answers
45
45
  [.build(runContext => { // instantiates Environment/Generator
46
46
  [runContext.env...] // does something with the environment
47
47
  [runContext.generator...] // does something with the generator
package/dist/helpers.d.ts CHANGED
@@ -9,9 +9,9 @@ import type { RunContextSettings } from './run-context.js';
9
9
  /**
10
10
  * Dependencies can be path (autodiscovery) or an array [<generator>, <name>]
11
11
  */
12
- export type Dependency = string | Parameters<Environment['registerStub']>;
13
- type GeneratorNew<GenParameter extends YeomanGenerator = YeomanGenerator> = new (...args: ConstructorParameters<typeof YeomanGenerator<GenParameter['options']>>) => YeomanGenerator<GenParameter['options']>;
14
- type GeneratorBuilder<GenParameter extends YeomanGenerator = YeomanGenerator> = (...args: ConstructorParameters<typeof YeomanGenerator<GenParameter['options']>>) => YeomanGenerator<GenParameter['options']>;
12
+ export type Dependency = string | Parameters<Environment['registerStub']> | Parameters<Environment['register']>;
13
+ type GeneratorNew<GenParameter extends YeomanGenerator = YeomanGenerator> = new (...args: ConstructorParameters<typeof YeomanGenerator<GenParameter['options']>>) => GenParameter;
14
+ type GeneratorBuilder<GenParameter extends YeomanGenerator = YeomanGenerator> = (...args: ConstructorParameters<typeof YeomanGenerator<GenParameter['options']>>) => GenParameter;
15
15
  export type GeneratorConstructor<GenParameter extends YeomanGenerator = YeomanGenerator> = GeneratorNew<GenParameter> | GeneratorBuilder<GenParameter>;
16
16
  /**
17
17
  * Collection of unit test helpers. (mostly related to Mocha syntax)
@@ -137,13 +137,13 @@ export declare class YeomanTest {
137
137
  * Run the provided Generator
138
138
  * @param GeneratorOrNamespace - Generator constructor or namespace
139
139
  */
140
- run<GeneratorType extends YeomanGenerator = YeomanGenerator>(GeneratorOrNamespace: string | GeneratorConstructor, settings?: RunContextSettings, envOptions?: Options): RunContext<GeneratorType>;
140
+ run<GeneratorType extends YeomanGenerator = YeomanGenerator>(GeneratorOrNamespace: string | GeneratorConstructor<GeneratorType>, settings?: RunContextSettings, envOptions?: Options): RunContext<GeneratorType>;
141
141
  /**
142
142
  * Prepare a run context
143
143
  * @param {String|Function} GeneratorOrNamespace - Generator constructor or namespace
144
144
  * @return {RunContext}
145
145
  */
146
- create<GeneratorType extends YeomanGenerator = YeomanGenerator>(GeneratorOrNamespace: string | GeneratorConstructor, settings?: RunContextSettings, envOptions?: Options): RunContext<GeneratorType>;
146
+ create<GeneratorType extends YeomanGenerator = YeomanGenerator>(GeneratorOrNamespace: string | GeneratorConstructor<GeneratorType>, settings?: RunContextSettings, envOptions?: Options): RunContext<GeneratorType>;
147
147
  }
148
148
  declare const _default: YeomanTest;
149
149
  export default _default;
package/dist/helpers.js CHANGED
@@ -9,6 +9,7 @@ import Environment from 'yeoman-environment';
9
9
  import { DummyPrompt, TestAdapter } from './adapter.js';
10
10
  import RunContext from './run-context.js';
11
11
  import testContext from './test-context.js';
12
+ const { cloneDeep } = _;
12
13
  /**
13
14
  * Collection of unit test helpers. (mostly related to Mocha syntax)
14
15
  * @class YeomanTest
@@ -168,7 +169,12 @@ export class YeomanTest {
168
169
  registerDependencies(env, dependencies) {
169
170
  for (const dependency of dependencies) {
170
171
  if (Array.isArray(dependency)) {
171
- env.registerStub(dependency[0], dependency[1]);
172
+ if (typeof dependency[0] === 'string') {
173
+ env.register(...dependency);
174
+ }
175
+ else {
176
+ env.registerStub(...dependency);
177
+ }
172
178
  }
173
179
  else {
174
180
  env.register(dependency);
@@ -201,7 +207,7 @@ export class YeomanTest {
201
207
  * const env = createTestEnv(require('yeoman-environment').createEnv);
202
208
  */
203
209
  createTestEnv(envContructor = this.createEnv, options = { localConfigOnly: true }) {
204
- const envOptions = _.cloneDeep(this.environmentOptions ?? {});
210
+ const envOptions = cloneDeep(this.environmentOptions ?? {});
205
211
  if (typeof options === 'boolean') {
206
212
  options = {
207
213
  newErrorHandler: true,
@@ -238,8 +244,8 @@ export class YeomanTest {
238
244
  * @param GeneratorOrNamespace - Generator constructor or namespace
239
245
  */
240
246
  run(GeneratorOrNamespace, settings, envOptions) {
241
- const contextSettings = _.cloneDeep(this.settings ?? {});
242
- const generatorOptions = _.cloneDeep(this.generatorOptions ?? {});
247
+ const contextSettings = cloneDeep(this.settings ?? {});
248
+ const generatorOptions = cloneDeep(this.generatorOptions ?? {});
243
249
  const RunContext = this.getRunContextType();
244
250
  const runContext = new RunContext(GeneratorOrNamespace, { ...contextSettings, ...settings }, envOptions, this).withOptions(generatorOptions);
245
251
  if (settings?.autoCleanup !== false) {
@@ -31,7 +31,7 @@ export type RunContextSettings = {
31
31
  namespace?: string;
32
32
  };
33
33
  type PromiseRunResult<GeneratorType extends Generator> = Promise<RunResult<GeneratorType>>;
34
- export declare class RunContextBase<GeneratorType extends Generator> extends EventEmitter {
34
+ export declare class RunContextBase<GeneratorType extends Generator = Generator> extends EventEmitter {
35
35
  readonly mockedGenerators: Record<string, Generator>;
36
36
  env: Environment;
37
37
  generator: GeneratorType;
@@ -54,6 +54,7 @@ export declare class RunContextBase<GeneratorType extends Generator> extends Eve
54
54
  private oldCwd?;
55
55
  private eventListenersSet;
56
56
  private envCB;
57
+ private built;
57
58
  private ran;
58
59
  private errored;
59
60
  /**
@@ -66,7 +67,7 @@ export declare class RunContextBase<GeneratorType extends Generator> extends Eve
66
67
  * @param settings
67
68
  * @return {this}
68
69
  */
69
- constructor(generatorType: string | GeneratorConstructor | typeof Generator, settings?: RunContextSettings, envOptions?: Options, helpers?: YeomanTest);
70
+ constructor(generatorType: string | GeneratorConstructor<GeneratorType> | typeof Generator, settings?: RunContextSettings, envOptions?: Options, helpers?: YeomanTest);
70
71
  /**
71
72
  * Run the generator on the environment and promises a RunResult instance.
72
73
  * @return {PromiseRunResult} Promise a RunResult instance.
@@ -212,7 +213,9 @@ export declare class RunContextBase<GeneratorType extends Generator> extends Eve
212
213
  /**
213
214
  * Add files to mem-fs.
214
215
  * Files will be resolved relative to targetDir.
215
- * @param files
216
+ *
217
+ * Files with Object content will be merged to existing content.
218
+ * To avoid merging, `JSON.stringify` the content.
216
219
  */
217
220
  withFiles(files: Record<string, string | Record<string, unknown>>): this;
218
221
  withFiles(relativePath: string, files: Record<string, string | Record<string, unknown>>): this;
@@ -223,6 +226,10 @@ export declare class RunContextBase<GeneratorType extends Generator> extends Eve
223
226
  * @returns
224
227
  */
225
228
  withYoRc(content: string | Record<string, unknown>): this;
229
+ /**
230
+ * Add a generator config to .yo-rc.json
231
+ */
232
+ withYoRcConfig(key: string, content: Record<string, unknown>): this;
226
233
  /**
227
234
  * Commit mem-fs files.
228
235
  */
@@ -270,7 +277,7 @@ export declare class RunContextBase<GeneratorType extends Generator> extends Eve
270
277
  private setDir;
271
278
  private _createRunResultOptions;
272
279
  }
273
- export default class RunContext<GeneratorType extends Generator> extends RunContextBase<GeneratorType> implements Promise<RunResult<GeneratorType>> {
280
+ export default class RunContext<GeneratorType extends Generator = Generator> extends RunContextBase<GeneratorType> implements Promise<RunResult<GeneratorType>> {
274
281
  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>;
275
282
  catch<TResult = never>(onrejected?: ((reason: any) => TResult | PromiseLike<TResult>) | undefined | undefined): Promise<RunResult<GeneratorType> | TResult>;
276
283
  finally(onfinally?: (() => void) | undefined | undefined): Promise<RunResult<GeneratorType>>;
@@ -9,6 +9,7 @@ import tempDirectory from 'temp-dir';
9
9
  import MemFsEditor from 'mem-fs-editor';
10
10
  import RunResult from './run-result.js';
11
11
  import defaultHelpers from './helpers.js';
12
+ const { camelCase, kebabCase, merge: lodashMerge, set: lodashSet } = _;
12
13
  export class RunContextBase extends EventEmitter {
13
14
  mockedGenerators = {};
14
15
  env;
@@ -32,6 +33,7 @@ export class RunContextBase extends EventEmitter {
32
33
  oldCwd;
33
34
  eventListenersSet = false;
34
35
  envCB;
36
+ built = false;
35
37
  ran = false;
36
38
  errored = false;
37
39
  /**
@@ -47,14 +49,9 @@ export class RunContextBase extends EventEmitter {
47
49
  constructor(generatorType, settings, envOptions = {}, helpers = defaultHelpers) {
48
50
  super();
49
51
  this.settings = {
50
- namespace: 'gen:test',
51
52
  ...settings,
52
53
  };
53
54
  this.Generator = generatorType;
54
- if (typeof generatorType !== 'string') {
55
- const { namespace, resolved } = this.settings;
56
- this.withGenerators([[generatorType, namespace, resolved]]);
57
- }
58
55
  this.envOptions = envOptions;
59
56
  this.withOptions({
60
57
  force: true,
@@ -72,7 +69,8 @@ export class RunContextBase extends EventEmitter {
72
69
  * @return {PromiseRunResult} Promise a RunResult instance.
73
70
  */
74
71
  async run() {
75
- if (!this.ran) {
72
+ this.ran = true;
73
+ if (!this.built) {
76
74
  await this.build();
77
75
  }
78
76
  try {
@@ -237,8 +235,8 @@ export class RunContextBase extends EventEmitter {
237
235
  // Add options as both kebab and camel case. This is to stay backward compatibles with
238
236
  // the switch we made to meow for options parsing.
239
237
  for (const key of Object.keys(options)) {
240
- options[_.camelCase(key)] = options[key];
241
- options[_.kebabCase(key)] = options[key];
238
+ options[camelCase(key)] = options[key];
239
+ options[kebabCase(key)] = options[key];
242
240
  }
243
241
  this.options = { ...this.options, ...options };
244
242
  return this;
@@ -288,13 +286,20 @@ export class RunContextBase extends EventEmitter {
288
286
  */
289
287
  withGenerators(dependencies) {
290
288
  assert(Array.isArray(dependencies), 'dependencies should be an array');
291
- return this.onEnvironment(env => {
289
+ return this.onEnvironment(async (env) => {
292
290
  for (const dependency of dependencies) {
293
291
  if (Array.isArray(dependency)) {
294
- env.registerStub(...dependency);
292
+ if (typeof dependency[0] === 'string') {
293
+ // eslint-disable-next-line no-await-in-loop, @typescript-eslint/await-thenable
294
+ await env.register(...dependency);
295
+ }
296
+ else {
297
+ env.registerStub(...dependency);
298
+ }
295
299
  }
296
300
  else {
297
- env.register(dependency);
301
+ // eslint-disable-next-line no-await-in-loop, @typescript-eslint/await-thenable
302
+ await env.register(dependency);
298
303
  }
299
304
  }
300
305
  });
@@ -342,7 +347,8 @@ export class RunContextBase extends EventEmitter {
342
347
  this.editor.write(resolvedFile, content);
343
348
  }
344
349
  else {
345
- this.editor.writeJSON(resolvedFile, content);
350
+ const fileContent = this.editor.readJSON(resolvedFile, {});
351
+ this.editor.writeJSON(resolvedFile, lodashMerge(fileContent, content));
346
352
  }
347
353
  }
348
354
  });
@@ -358,6 +364,13 @@ export class RunContextBase extends EventEmitter {
358
364
  '.yo-rc.json': content,
359
365
  });
360
366
  }
367
+ /**
368
+ * Add a generator config to .yo-rc.json
369
+ */
370
+ withYoRcConfig(key, content) {
371
+ const yoRcContent = lodashSet({}, key, content);
372
+ return this.withYoRc(yoRcContent);
373
+ }
361
374
  /**
362
375
  * Commit mem-fs files.
363
376
  */
@@ -397,7 +410,7 @@ export class RunContextBase extends EventEmitter {
397
410
  return this;
398
411
  }
399
412
  assertNotBuild() {
400
- if (this.ran || this.completed) {
413
+ if (this.built || this.completed) {
401
414
  throw new Error('The context is already built');
402
415
  }
403
416
  }
@@ -407,7 +420,7 @@ export class RunContextBase extends EventEmitter {
407
420
  */
408
421
  async build() {
409
422
  this.assertNotBuild();
410
- this.ran = true;
423
+ this.built = true;
411
424
  if (!this.targetDirectory && this.settings.tmpdir !== false) {
412
425
  this.inTmpDir();
413
426
  }
@@ -439,13 +452,14 @@ export class RunContextBase extends EventEmitter {
439
452
  // eslint-disable-next-line no-await-in-loop
440
453
  await onEnvironmentCallback.call(this, this.env);
441
454
  }
442
- let { namespace } = this.settings;
443
- if (typeof this.Generator === 'string') {
444
- namespace = this.env.namespace(this.Generator);
445
- if (namespace !== this.Generator) {
446
- // Generator is a file path, it should be registered.
447
- this.env.register(this.Generator);
448
- }
455
+ const { namespace = typeof this.Generator === 'string' ? this.env.namespace(this.Generator) : 'gen:test' } = this.settings;
456
+ if (typeof this.Generator === 'string' && namespace !== this.Generator) {
457
+ // Generator is a file path, it should be registered.
458
+ this.env.register(this.Generator, namespace);
459
+ }
460
+ else if (typeof this.Generator !== 'string') {
461
+ const { resolved } = this.settings;
462
+ this.env.registerStub(this.Generator, namespace, resolved);
449
463
  }
450
464
  // eslint-disable-next-line @typescript-eslint/await-thenable
451
465
  this.generator = (await this.env.create(namespace, this.args, this.options));
@@ -37,7 +37,7 @@ export type RunResultOptions<GeneratorType extends Generator> = {
37
37
  /**
38
38
  * This class provides utilities for testing generated content.
39
39
  */
40
- export default class RunResult<GeneratorType extends Generator> {
40
+ export default class RunResult<GeneratorType extends Generator = Generator> {
41
41
  env: any;
42
42
  generator: GeneratorType;
43
43
  cwd: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "yeoman-test",
3
- "version": "7.1.0",
3
+ "version": "7.3.0",
4
4
  "description": "Test utilities for Yeoman generators",
5
5
  "homepage": "http://yeoman.io/authoring/testing.html",
6
6
  "author": "The Yeoman Team",