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 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 }) => (returns ? sinonStub().returns(returns) : sinonSpy()),
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('@yeoman/types').BaseEnvironmentOptions): import('@yeoman/types').BaseEnvironment;
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 DynamicEnv = await import('yeoman-environment');
7
- if (typeof DynamicEnv === 'function') {
8
- return new DynamicEnv(options);
6
+ const DynamicEnvironment = await import('yeoman-environment');
7
+ if (typeof DynamicEnvironment === 'function') {
8
+ return new DynamicEnvironment(options);
9
9
  }
10
- if (typeof DynamicEnv.default === 'function') {
11
- // eslint-disable-next-line new-cap
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, cb?: (error?: any) => unknown): unknown;
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(envOrGenerator: BaseGenerator | DefaultEnvironmentApi, mockedAnswers?: PromptAnswers, options?: DummyPromptOptions): void;
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(envOrGenerator: BaseGenerator | DefaultEnvironmentApi): void;
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): SinonSpiedInstance<DefaultGeneratorApi>;
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, (...args: any[]) => void>): new (...args: any[]) => GenParameter;
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(envContructor?: CreateEnv, options?: BaseEnvironmentOptions): Promise<BaseEnvironment>;
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, envOptions?: BaseEnvironmentOptions): RunContext<GeneratorType>;
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, envOptions?: BaseEnvironmentOptions): RunContext<GeneratorType>;
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 { mkdirSync, existsSync, rmSync } from 'node:fs';
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, cb) {
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 cb?.();
66
+ return callback?.();
65
67
  }
66
68
  catch (error) {
67
- return cb?.(error);
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(envOrGenerator, mockedAnswers, options) {
82
- const environment = 'env' in envOrGenerator ? envOrGenerator.env : envOrGenerator;
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(envOrGenerator) {
98
- const environment = envOrGenerator.env ?? envOrGenerator;
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 = sinonSpy(MockedGenerator);
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: sinonStub(),
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(...args) {
134
- const optIndex = Array.isArray(args[0]) ? 1 : 0;
135
- args[optIndex] = args[optIndex] ?? {};
136
- const options = args[optIndex];
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(...args);
141
+ super(...arguments_);
140
142
  }
141
143
  }
142
- for (const [propName, propValue] of Object.entries(contents)) {
143
- Object.defineProperty(DummyGenerator.prototype, propName, {
144
- value: propValue ?? Object.create(null),
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 env = await this.createEnv({ sharedOptions: { localConfigOnly } });
173
+ const environment = await this.createEnv({ sharedOptions: { localConfigOnly } });
172
174
  for (const dependency of dependencies) {
173
175
  if (typeof dependency === 'string') {
174
- env.register(dependency);
176
+ environment.register(dependency);
175
177
  }
176
178
  else {
177
- env.register(...dependency);
179
+ environment.register(...dependency);
178
180
  }
179
181
  }
180
- return env.create(name, instantiateOptions);
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 createEnv(options);
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(envContructor = this.createEnv, options = { localConfigOnly: true }) {
208
- let envOptions = cloneDeep(this.environmentOptions ?? {});
209
+ async createTestEnv(environmentContructor = this.createEnv, options = { localConfigOnly: true }) {
210
+ let environmentOptions = cloneDeep(this.environmentOptions ?? {});
209
211
  if (typeof options === 'boolean') {
210
- envOptions = {
212
+ environmentOptions = {
211
213
  newErrorHandler: true,
212
- ...envOptions,
214
+ ...environmentOptions,
213
215
  sharedOptions: {
214
216
  localConfigOnly: options,
215
- ...envOptions.sharedOptions,
217
+ ...environmentOptions.sharedOptions,
216
218
  },
217
219
  };
218
220
  }
219
221
  else {
220
- envOptions.sharedOptions = {
222
+ environmentOptions.sharedOptions = {
221
223
  localConfigOnly: true,
222
- ...envOptions.sharedOptions,
224
+ ...environmentOptions.sharedOptions,
223
225
  ...options.sharedOptions,
224
226
  };
225
- envOptions = {
227
+ environmentOptions = {
226
228
  newErrorHandler: true,
227
- ...envOptions,
229
+ ...environmentOptions,
228
230
  ...options,
229
231
  };
230
232
  }
231
- return envContructor({ adapter: this.createTestAdapter(), ...envOptions });
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, envOptions) {
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 }, envOptions, this).withOptions(generatorOptions);
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, envOptions) {
266
- return this.run(GeneratorOrNamespace, settings, envOptions);
267
+ create(GeneratorOrNamespace, settings, environmentOptions) {
268
+ return this.run(GeneratorOrNamespace, settings, environmentOptions);
267
269
  }
268
270
  /**
269
271
  * Prepare temporary dir without generator support.
@@ -0,0 +1,3 @@
1
+ export namespace mochaHooks {
2
+ function afterAll(): void;
3
+ }
@@ -0,0 +1,6 @@
1
+ import { context } from './index.js';
2
+ export const mochaHooks = {
3
+ afterAll() {
4
+ context.startNewContext();
5
+ },
6
+ };
@@ -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, PromptAnswers, LookupOptions } from '@yeoman/types';
5
- import { type MemFsEditorFile, type MemFsEditor } from 'mem-fs-editor';
6
- import type { DefaultGeneratorApi, DefaultEnvironmentApi } from '../types/type-helpers.js';
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 EnvOptions = BaseEnvironmentOptions & {
37
- createEnv?: 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: 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, envOptions?: EnvOptions, helpers?: YeomanTest);
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: (...args: any[]) => void): this;
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, cb?: (folderPath: string) => void): this;
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(cb: (folderPath: string) => void): this;
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(cb?: (folderPath: string) => void): this;
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(cb: any): this;
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(args: string | string[]): this;
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?: ((...args: any[]) => any) | {
208
- stub?: (...args: any[]) => any;
209
- registerSinonDefaults?: boolean;
210
- callback?: (stub: any) => void | Promise<void>;
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, env: DefaultEnvironmentApi) => any): this;
289
+ onEnvironment(callback: (this: this, environment: DefaultEnvironmentApi) => any): this;
287
290
  prepare(): Promise<void>;
288
291
  protected assertNotBuild(): void;
289
292
  /**
@@ -1,19 +1,18 @@
1
1
  import crypto from 'node:crypto';
2
2
  import { existsSync, rmSync } from 'node:fs';
3
- import path, { resolve, isAbsolute, join as pathJoin } from 'node: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, envOptions = {}, helpers = defaultHelpers) {
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 = 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, cb) {
111
+ inDir(dirPath, callback) {
114
112
  this.setDir(dirPath, true);
115
- this.helpers.testDirectory(dirPath, () => cb?.call(this, path.resolve(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(cb) {
124
- this.inDirCallbacks.push(cb);
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(cb) {
156
- return this.inDir(this.temporaryDir, cb);
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(cb) {
217
- this.envCB = cb;
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 (env) => {
224
+ return this.onEnvironment(async (environment) => {
227
225
  lookups = Array.isArray(lookups) ? lookups : [lookups];
228
226
  for (const lookup of lookups) {
229
- // eslint-disable-next-line no-await-in-loop
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(args) {
239
- const argsArray = typeof args === 'string' ? args.split(' ') : args;
240
- assert(Array.isArray(argsArray), 'args should be either a string separated by spaces or an array');
241
- this.args = this.args.concat(argsArray);
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 (env) => {
300
+ return this.onEnvironment(async (environment) => {
304
301
  for (const dependency of dependencies) {
305
302
  if (typeof dependency === 'string') {
306
- env.register(dependency);
303
+ environment.register(dependency);
307
304
  }
308
305
  else {
309
- env.register(...dependency);
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 stub = typeof options === 'function' ? options : options?.stub ?? sinonStub();
319
- const registerSinonDefaults = typeof options === 'function' ? false : options?.registerSinonDefaults ?? true;
320
- const callback = typeof options === 'function' ? undefined : options?.callback;
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
- const stubFn = stub;
326
- // eslint-disable-next-line @typescript-eslint/promise-function-async
327
- stubFn.withArgs('spawnCommand').callsFake(() => Object.assign(Promise.resolve({ ...defaultReturn }), defaultChild));
328
- // eslint-disable-next-line @typescript-eslint/promise-function-async
329
- stubFn.withArgs('spawn').callsFake(() => Object.assign(Promise.resolve({ ...defaultReturn }), defaultChild));
330
- stubFn.withArgs('spawnCommandSync').callsFake(() => ({ ...defaultReturn }));
331
- stubFn.withArgs('spawnSync').callsFake(() => ({ ...defaultReturn }));
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(env => {
340
- env.on('compose', (_namespace, generator) => {
341
- const createCallback = method => function (...args) {
342
- return stub.call(this, method, ...args);
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 cb of this.beforePrepareCallbacks) {
480
- // eslint-disable-next-line no-await-in-loop
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 cb of this.inDirCallbacks) {
495
- // eslint-disable-next-line no-await-in-loop
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 testEnv = await this.helpers.createTestEnv(this.envOptions.createEnv, {
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(testEnv)) ?? testEnv : testEnv;
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 function () {
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
  }
@@ -1,5 +1,5 @@
1
1
  import type { Store } from 'mem-fs';
2
- import { type MemFsEditorFile, type MemFsEditor } from 'mem-fs-editor';
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, envOptions?: BaseEnvironmentOptions): import("./run-context.js").default<GeneratorType>;
60
- getSpawnArgsUsingDefaultImplementation(): any;
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
@@ -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
- function convertArgs(args) {
8
- if (args.length > 1) {
9
- return [[...args]];
7
+ const convertArguments = arguments_ => {
8
+ if (arguments_.length > 1) {
9
+ return [[...arguments_]];
10
10
  }
11
- const arg = args[0];
12
- return Array.isArray(arg) ? arg : [arg];
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, envOptions) {
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, ...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.getCalls().map(call => call.args);
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 convertArgs([path])) {
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 convertArgs([files])) {
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(...args) {
182
- for (const pair of convertArgs(args)) {
183
- const file = pair[0];
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(...args) {
193
- for (const pair of convertArgs(args)) {
194
- const file = pair[0];
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(...args) {
201
- for (const pair of convertArgs(args)) {
202
- const file = pair[0];
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') {
@@ -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?: RunContext<any>): void;
8
+ startNewContext(runContext?: any, autoCleanup?: boolean): void;
7
9
  }
8
10
  declare const testContext: TestContext;
9
11
  export default testContext;
@@ -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.runContext?.cleanupTemporaryDir();
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
- const cleanupTemporaryDir = () => {
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, prop, receiver) {
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, prop, receiver);
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": "8.3.0",
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
- "types": "./dist/index.d.ts",
16
- "import": "./dist/index.js"
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": "xo",
33
- "test": "c8 esmocha --forbid-only"
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.4.0",
40
- "inquirer": "^9.2.2",
45
+ "@yeoman/adapter": "^1.6.0",
41
46
  "lodash-es": "^4.17.21",
42
- "mem-fs-editor": "^10.0.3",
43
- "sinon": "^16.0.0",
47
+ "mem-fs-editor": "^11.1.1",
48
+ "signal-exit": "^4.1.0",
44
49
  "temp-dir": "^3.0.0",
45
- "type-fest": "^4.3.1"
50
+ "type-fest": "^4.25.0"
46
51
  },
47
52
  "devDependencies": {
48
- "@types/inquirer": "^9.0.3",
49
- "@types/lodash": "^4.14.195",
50
- "@types/node": "^16.18.19",
51
- "@types/sinon": "^10.0.13",
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
- "esmocha": "^1.0.1",
55
- "husky": "^8.0.2",
58
+ "husky": "^9.1.5",
56
59
  "jsdoc": "^4.0.2",
57
- "lint-staged": "^14.0.1",
58
- "prettier": "^3.0.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": "~5.2.2",
62
- "xo": "0.56.0",
63
- "yeoman-environment": "^3.18.3",
64
- "yeoman-generator": "^5.9.0"
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.1.0",
68
- "mem-fs": "^3.0.0",
69
- "yeoman-environment": "^3.18.3",
70
- "yeoman-generator": "^5.9.0 || >=6.0.0"
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": "^16.17.0 || >=18.12.0"
84
+ "node": "^18.19.0 || >= 20.6.1"
87
85
  }
88
86
  }
@@ -1,6 +1,6 @@
1
- import type { BaseGenerator, BaseEnvironment } from '@yeoman/types';
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, @typescript-eslint/prefer-ts-expect-error
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';