or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

configuration.mdenvironment-integration.mdindex.mdplugin-integration.mdtest-runner.mdutilities.md

environment-integration.mddocs/

0

# Environment Integration

1

2

Jest environment enhancement utilities that provide Stryker-specific functionality including instrumenter context sharing and test event handling for coverage analysis.

3

4

## Capabilities

5

6

### Jest Environment Mixin

7

8

Enhances Jest environment classes with Stryker integration for mutation testing and coverage analysis.

9

10

```typescript { .api }

11

/**

12

* Mixin function that enhances a Jest environment class with Stryker functionality

13

* Adds instrumenter context sharing and test event handling for coverage analysis

14

* @param JestEnvironmentClass - Jest environment class to enhance

15

* @returns Enhanced Jest environment class with Stryker integration

16

*/

17

export function mixinJestEnvironment<T extends typeof JestEnvironment>(

18

JestEnvironmentClass: T & { [STRYKER_JEST_ENV]?: true }

19

): T;

20

```

21

22

**Usage Examples:**

23

24

```typescript

25

import { mixinJestEnvironment } from "@stryker-mutator/jest-runner";

26

import NodeEnvironment from "jest-environment-node";

27

import JSDOMEnvironment from "jest-environment-jsdom";

28

29

// Enhance Node.js environment

30

const StrykerNodeEnvironment = mixinJestEnvironment(NodeEnvironment);

31

32

// Enhance JSDOM environment

33

const StrykerJSDOMEnvironment = mixinJestEnvironment(JSDOMEnvironment);

34

35

// Use in Jest configuration

36

module.exports = {

37

testEnvironment: StrykerNodeEnvironment,

38

// or

39

testEnvironment: "./custom-stryker-environment.js"

40

};

41

```

42

43

```typescript

44

// custom-stryker-environment.js

45

const { mixinJestEnvironment } = require("@stryker-mutator/jest-runner");

46

const NodeEnvironment = require("jest-environment-node").default;

47

48

module.exports = mixinJestEnvironment(NodeEnvironment);

49

```

50

51

### Pre-built Environment Exports

52

53

The package provides pre-built Jest environments with Stryker integration for common use cases.

54

55

```typescript { .api }

56

// Available as CommonJS exports through package.json exports map

57

58

// Node.js environment with Stryker integration

59

"@stryker-mutator/jest-runner/jest-env/node"

60

61

// JSDOM environment with Stryker integration

62

"@stryker-mutator/jest-runner/jest-env/jsdom"

63

64

// JSDOM v16 environment with Stryker integration

65

"@stryker-mutator/jest-runner/jest-env/jsdom-sixteen"

66

```

67

68

**Usage Examples:**

69

70

```javascript

71

// Jest configuration using pre-built environments

72

module.exports = {

73

// Use Node.js environment

74

testEnvironment: "@stryker-mutator/jest-runner/jest-env/node",

75

76

// Use JSDOM environment

77

testEnvironment: "@stryker-mutator/jest-runner/jest-env/jsdom",

78

79

// Use JSDOM v16 environment

80

testEnvironment: "@stryker-mutator/jest-runner/jest-env/jsdom-sixteen"

81

};

82

```

83

84

```typescript

85

// Import for programmatic use

86

const StrykerNodeEnv = require("@stryker-mutator/jest-runner/jest-env/node");

87

const StrykerJSDOMEnv = require("@stryker-mutator/jest-runner/jest-env/jsdom");

88

```

89

90

## Types

91

92

### Jest Environment Types

93

94

```typescript { .api }

95

import type {

96

JestEnvironment,

97

EnvironmentContext,

98

JestEnvironmentConfig,

99

} from '@jest/environment';

100

import type { Circus } from '@jest/types';

101

102

interface StrykerJestEnvironment extends JestEnvironment {

103

readonly [STRYKER_JEST_ENV]: true;

104

handleTestEvent: Circus.EventHandler;

105

}

106

107

interface EnvironmentContext {

108

testPath: string;

109

docblockPragmas: Record<string, string | string[]>;

110

console: Console;

111

}

112

113

interface JestEnvironmentConfig {

114

projectConfig: Config.ProjectConfig;

115

globalConfig: Config.GlobalConfig;

116

}

117

```

118

119

### Test Event Types

120

121

```typescript { .api }

122

namespace Circus {

123

interface Event {

124

name: string;

125

test?: TestEntry;

126

}

127

128

interface TestEntry {

129

name: string;

130

parent: DescribeBlock;

131

}

132

133

interface DescribeBlock {

134

name: string;

135

parent?: DescribeBlock;

136

}

137

138

interface State {

139

currentDescribeBlock: DescribeBlock;

140

currentlyRunningTest?: TestEntry;

141

}

142

143

type EventHandler = (event: Event, state: State) => Promise<void> | void;

144

}

145

```

146

147

### Instrumenter Context

148

149

```typescript { .api }

150

interface InstrumenterContext {

151

currentTestId?: string;

152

hitCount?: number;

153

hitLimit?: number;

154

activeMutant?: Mutant;

155

mutantCoverage?: MutantCoverage;

156

}

157

```

158

159

## Implementation Details

160

161

### Instrumenter Context Sharing

162

163

The mixin creates a shared context between the test environment and Stryker's instrumenter:

164

165

- **Global Access**: Available as `global.__stryker__` or custom namespace

166

- **Test Tracking**: Tracks current test ID for per-test coverage

167

- **Hit Limiting**: Monitors execution counts to prevent infinite loops

168

- **Mutant State**: Shares active mutant information during mutation testing

169

170

### Test Event Handling

171

172

The enhanced environment intercepts Jest test events for coverage analysis:

173

174

- **test_start**: Sets current test ID for coverage tracking

175

- **test_done**: Clears current test ID when test completes

176

- **Async Support**: Handles both synchronous and asynchronous test events

177

- **Event Forwarding**: Preserves original environment's event handling

178

179

### Coverage Analysis Integration

180

181

Per-test coverage analysis requires the environment mixin to:

182

183

1. **Track Test Execution**: Identify which test is currently running

184

2. **Associate Coverage**: Link code execution to specific tests

185

3. **Aggregate Results**: Collect coverage data across all tests

186

4. **Report Coverage**: Provide coverage information to Stryker

187

188

### Environment Compatibility

189

190

The mixin is designed to work with any Jest environment:

191

192

- **Node.js Environment**: Server-side testing with full Node.js APIs

193

- **JSDOM Environment**: Browser simulation with DOM APIs

194

- **Custom Environments**: Any environment extending Jest's base environment

195

- **Backward Compatibility**: Preserves existing environment functionality

196

197

### Test File Registration

198

199

The environment automatically registers test files with Stryker:

200

201

```typescript

202

// Tracks which test files have Stryker environment integration

203

state.testFilesWithStrykerEnvironment.add(context.testPath);

204

```

205

206

This information is used for:

207

- Coverage verification

208

- Test file validation

209

- Mutation testing optimization

210

- Error reporting and debugging

211

212

### Global Namespace Configuration

213

214

The environment respects custom global namespaces:

215

216

```typescript

217

// Uses configured namespace or defaults to '__stryker__'

218

const namespace = this.global.__strykerGlobalNamespace__ ?? '__stryker__';

219

this.#strykerContext = this.global[namespace] = state.instrumenterContext;

220

```

221

222

This allows for:

223

- Custom instrumenter configurations

224

- Avoiding naming conflicts

225

- Supporting multiple Stryker instances

226

- Compatibility with different Stryker versions