or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

generator-helpers.mdindex.mdrun-context.mdrun-result.mdtest-adapter.mdtest-environment.md

test-environment.mddocs/

0

# Test Environment Setup

1

2

The test environment functionality provides utilities for creating and configuring Yeoman environments specifically optimized for testing. This includes custom test adapters, shared file systems, and environment-specific configuration options that ensure isolated and predictable test execution.

3

4

## Capabilities

5

6

### Environment Creation

7

8

Create Yeoman environments configured for testing scenarios.

9

10

```typescript { .api }

11

/**

12

* Create a standard Yeoman environment

13

* @param options - Base environment options

14

* @returns Promise resolving to environment instance

15

*/

16

async createEnv(options: BaseEnvironmentOptions): Promise<DefaultEnvironmentApi>;

17

18

/**

19

* Creates a test environment with TestAdapter and testing-specific configuration

20

* @param environmentConstructor - Optional custom environment constructor

21

* @param options - Environment options (defaults include localConfigOnly: true)

22

* @returns Promise resolving to configured test environment

23

*/

24

async createTestEnv(

25

environmentConstructor?: CreateEnv,

26

options?: BaseEnvironmentOptions

27

): Promise<DefaultEnvironmentApi>;

28

29

type CreateEnv = (options: BaseEnvironmentOptions) => Promise<BaseEnvironment>;

30

```

31

32

**Usage Examples:**

33

34

```typescript

35

import helpers from "yeoman-test";

36

37

// Basic environment

38

const env = await helpers.createEnv({

39

cwd: process.cwd(),

40

force: true

41

});

42

43

// Test environment with defaults

44

const testEnv = await helpers.createTestEnv();

45

46

// Custom test environment

47

const customTestEnv = await helpers.createTestEnv(

48

// Custom environment constructor

49

(options) => new CustomEnvironment(options),

50

// Custom options

51

{

52

localConfigOnly: false,

53

skipCache: false,

54

cwd: "/custom/path"

55

}

56

);

57

```

58

59

### Test Adapter Creation

60

61

Create and configure TestAdapter instances for prompt mocking and interaction simulation.

62

63

```typescript { .api }

64

/**

65

* Creates a TestAdapter using default options

66

* @param options - Optional adapter configuration

67

* @returns TestAdapter instance configured for testing

68

*/

69

createTestAdapter(options?: TestAdapterOptions): TestAdapter;

70

71

class TestAdapter extends BaseTestAdapter {

72

constructor(options?: TestAdapterOptions);

73

}

74

```

75

76

**Usage Examples:**

77

78

```typescript

79

import helpers from "yeoman-test";

80

81

// Basic test adapter

82

const adapter = helpers.createTestAdapter();

83

84

// Configured test adapter

85

const adapter = helpers.createTestAdapter({

86

mockedAnswers: {

87

projectName: "test-app",

88

features: ["typescript", "testing"]

89

},

90

throwOnMissingAnswer: true,

91

callback: (answer, options) => {

92

console.log(`Answered ${options.question.name}: ${answer}`);

93

return answer;

94

}

95

});

96

97

// Use with custom environment

98

const env = await helpers.createEnv({

99

adapter,

100

force: true

101

});

102

```

103

104

## Environment Configuration Options

105

106

### BaseEnvironmentOptions

107

108

Standard Yeoman environment options that can be used with test environments.

109

110

```typescript { .api }

111

interface BaseEnvironmentOptions {

112

/** Current working directory for the environment */

113

cwd?: string;

114

115

/** Force overwrite existing files */

116

force?: boolean;

117

118

/** Skip generator lookup caching */

119

skipCache?: boolean;

120

121

/** Skip automatic npm/yarn install */

122

skipInstall?: boolean;

123

124

/** Use local configuration only */

125

localConfigOnly?: boolean;

126

127

/** Custom adapter instance */

128

adapter?: any;

129

130

/** Shared file system instance */

131

sharedFs?: any;

132

133

/** Additional shared options for generators */

134

sharedOptions?: Record<string, any>;

135

136

/** Enable new error handler */

137

newErrorHandler?: boolean;

138

}

139

```

140

141

### TestAdapterOptions

142

143

Configuration options specific to the TestAdapter for prompt mocking.

144

145

```typescript { .api }

146

interface TestAdapterOptions {

147

/** Pre-configured answers for prompts */

148

mockedAnswers?: PromptAnswers;

149

150

/** Throw error if no answer provided for a prompt */

151

throwOnMissingAnswer?: boolean;

152

153

/** Callback function called for each prompt answer */

154

callback?: DummyPromptCallback;

155

156

/** Custom spy factory for creating mocks */

157

spyFactory?: (options: { returns?: any }) => any;

158

}

159

160

type DummyPromptCallback = (

161

this: any,

162

answer: any,

163

options: { question: any }

164

) => any;

165

166

type PromptAnswers = Record<string, any>;

167

```

168

169

## Advanced Environment Patterns

170

171

### Custom Environment Integration

172

173

```typescript

174

import helpers from "yeoman-test";

175

import CustomEnvironment from "./custom-environment";

176

177

// Use custom environment class

178

const env = await helpers.createTestEnv(

179

(options) => new CustomEnvironment(options),

180

{

181

cwd: process.cwd(),

182

customFeature: true

183

}

184

);

185

186

// Register generators

187

env.register("./path/to/generator", { namespace: "my:gen" });

188

189

// Create generator instance

190

const generator = await env.create("my:gen", {

191

generatorArgs: ["init"],

192

generatorOptions: { force: true }

193

});

194

```

195

196

### Shared File System Configuration

197

198

```typescript

199

import { create as createMemFs } from "mem-fs";

200

import helpers from "yeoman-test";

201

202

// Create shared file system

203

const sharedFs = createMemFs();

204

205

// Use with multiple environments

206

const env1 = await helpers.createTestEnv(undefined, {

207

sharedFs,

208

cwd: "/test/dir1"

209

});

210

211

const env2 = await helpers.createTestEnv(undefined, {

212

sharedFs,

213

cwd: "/test/dir2"

214

});

215

216

// Both environments share the same file system

217

```

218

219

### Environment Event Handling

220

221

```typescript

222

const env = await helpers.createTestEnv();

223

224

// Listen for environment events

225

env.on("compose", (namespace, generator) => {

226

console.log(`Composing with ${namespace}`);

227

});

228

229

env.on("error", (error) => {

230

console.error("Environment error:", error);

231

});

232

233

// Register and run generator

234

env.register("./my-generator", { namespace: "my:app" });

235

const generator = await env.create("my:app");

236

await env.runGenerator(generator);

237

```

238

239

### Prompt Mock Configuration

240

241

```typescript

242

import helpers from "yeoman-test";

243

244

// Advanced prompt mocking

245

const adapter = helpers.createTestAdapter({

246

mockedAnswers: {

247

projectName: "my-project",

248

features: ["typescript", "testing"],

249

author: "Test Author"

250

},

251

252

throwOnMissingAnswer: true,

253

254

callback: (answer, { question }) => {

255

// Log all prompt interactions

256

console.log(`Question: ${question.message}`);

257

console.log(`Answer: ${answer}`);

258

259

// Modify answers based on question

260

if (question.name === "projectName") {

261

return answer.toLowerCase().replace(/\s+/g, "-");

262

}

263

264

return answer;

265

}

266

});

267

268

const env = await helpers.createTestEnv(undefined, { adapter });

269

```

270

271

## Integration with RunContext

272

273

The test environment functionality integrates seamlessly with RunContext:

274

275

```typescript

276

import helpers from "yeoman-test";

277

278

// Environment configuration flows through to RunContext

279

await helpers.run("my-generator", {

280

// RunContext settings

281

tmpdir: true,

282

namespace: "my:app"

283

}, {

284

// Environment options

285

localConfigOnly: false,

286

skipInstall: false,

287

force: true

288

});

289

290

// Custom environment constructor

291

const customEnvFactory = (options) => new CustomEnvironment(options);

292

293

await helpers.run("my-generator", {}, {

294

createEnv: customEnvFactory,

295

cwd: "/custom/path"

296

});

297

```

298

299

## Testing Environment Behavior

300

301

```typescript

302

describe("environment behavior", () => {

303

let env: DefaultEnvironmentApi;

304

305

beforeEach(async () => {

306

env = await helpers.createTestEnv({

307

localConfigOnly: true,

308

force: true

309

});

310

});

311

312

it("registers generators correctly", () => {

313

env.register("./path/to/generator", { namespace: "my:gen" });

314

315

const registered = env.getRegisteredPackages();

316

expect(registered).toHaveProperty("my:gen");

317

});

318

319

it("creates generators with options", async () => {

320

env.register("./my-generator", { namespace: "my:app" });

321

322

const generator = await env.create("my:app", {

323

generatorArgs: ["init", "--force"],

324

generatorOptions: { skipInstall: true }

325

});

326

327

expect(generator.options.skipInstall).toBe(true);

328

});

329

});

330

```

331

332

## Default Environment Behavior

333

334

Test environments created with `createTestEnv` include these defaults:

335

336

- **TestAdapter**: Automatically configured for prompt mocking

337

- **localConfigOnly: true**: Prevents global configuration interference

338

- **newErrorHandler: true**: Enhanced error handling for better test debugging

339

- **Isolated file system**: Uses mem-fs for safe file operations

340

- **Skip behaviors**: Cache and install skipping enabled by default

341

342

These defaults ensure consistent, isolated test execution while maintaining the flexibility to override any behavior when needed.