0
# Utilities
1
2
Core utility functions and wrapper classes for Jest integration, version handling, coverage validation, and configuration enhancement.
3
4
## Capabilities
5
6
### Jest Configuration Enhancement Functions
7
8
Functions that modify Jest configuration for Stryker-specific functionality including coverage analysis and hit limiting.
9
10
```typescript { .api }
11
/**
12
* Configures Jest config with coverage analysis support
13
* Overrides test environment with Stryker-enhanced environment for coverage tracking
14
* @param jestConfig - Base Jest configuration
15
* @param coverageAnalysis - Coverage analysis mode ('off', 'all', or 'perTest')
16
* @param jestWrapper - Jest wrapper for version detection
17
* @returns Enhanced Jest configuration with coverage analysis setup
18
*/
19
export function withCoverageAnalysis(
20
jestConfig: Config.InitialOptions,
21
coverageAnalysis: CoverageAnalysis,
22
jestWrapper: JestWrapper
23
): Config.InitialOptions;
24
25
/**
26
* Configures Jest config with hit limit functionality
27
* Prevents infinite loops during mutation testing by limiting execution counts
28
* @param jestConfig - Base Jest configuration
29
* @param hitLimit - Maximum number of hits before timeout (undefined disables)
30
* @param jestWrapper - Jest wrapper for version detection
31
* @returns Enhanced Jest configuration with hit limiting support
32
*/
33
export function withHitLimit(
34
jestConfig: Config.InitialOptions,
35
hitLimit: number | undefined,
36
jestWrapper: JestWrapper
37
): Config.InitialOptions;
38
```
39
40
**Usage Examples:**
41
42
```typescript
43
import { withCoverageAnalysis, withHitLimit } from "@stryker-mutator/jest-runner";
44
45
// Enable per-test coverage analysis
46
const configWithCoverage = withCoverageAnalysis(
47
baseJestConfig,
48
'perTest',
49
jestWrapper
50
);
51
52
// Apply hit limit for mutation testing
53
const configWithHitLimit = withHitLimit(
54
baseJestConfig,
55
1000,
56
jestWrapper
57
);
58
59
// Chain configuration enhancements
60
const enhancedConfig = withHitLimit(
61
withCoverageAnalysis(baseJestConfig, 'perTest', jestWrapper),
62
500,
63
jestWrapper
64
);
65
```
66
67
### Coverage Validation
68
69
Function that validates test coverage completeness for Stryker integration.
70
71
```typescript { .api }
72
/**
73
* Validates that all test files have coverage data from Stryker environment
74
* Used to ensure proper integration between Jest and Stryker instrumenter
75
* @param jestResult - Jest test execution results
76
* @param testFilesWithStrykerEnvironment - Set of files that have Stryker integration
77
* @returns Error message if validation fails, undefined if successful
78
*/
79
export function verifyAllTestFilesHaveCoverage(
80
jestResult: AggregatedResult,
81
testFilesWithStrykerEnvironment: Set<string>
82
): string | undefined;
83
```
84
85
**Usage Example:**
86
87
```typescript
88
import { verifyAllTestFilesHaveCoverage } from "@stryker-mutator/jest-runner";
89
90
// Validate coverage after test execution
91
const errorMessage = verifyAllTestFilesHaveCoverage(
92
jestExecutionResult,
93
filesWithStrykerEnv
94
);
95
96
if (errorMessage) {
97
// Handle coverage validation failure
98
throw new Error(errorMessage);
99
}
100
```
101
102
### Jest Wrapper Classes
103
104
Wrapper classes for Jest operations and configuration management.
105
106
```typescript { .api }
107
/**
108
* Wrapper for Jest operations and version detection
109
* Provides abstraction over different Jest versions and capabilities
110
*/
111
export class JestWrapper {
112
/**
113
* Get the current Jest version
114
* @returns Jest version string (e.g., "29.5.0")
115
*/
116
getVersion(): string;
117
}
118
119
/**
120
* Wrapper for Jest configuration loading and manipulation
121
* Handles configuration resolution and merging
122
*/
123
export class JestConfigWrapper {
124
// Implementation details depend on internal Jest configuration handling
125
}
126
```
127
128
**Usage Examples:**
129
130
```typescript
131
import { JestWrapper, JestConfigWrapper } from "@stryker-mutator/jest-runner";
132
133
// Check Jest version for compatibility
134
const jestWrapper = new JestWrapper();
135
const version = jestWrapper.getVersion();
136
const isModern = semver.gte(version, '27.0.0');
137
138
// Use config wrapper for configuration handling
139
const configWrapper = new JestConfigWrapper();
140
// Configuration operations handled internally
141
```
142
143
### Jest Override Options
144
145
Constant defining default Jest configuration overrides applied by Stryker for optimal mutation testing performance.
146
147
```typescript { .api }
148
/**
149
* Default Jest configuration overrides for Stryker integration
150
* Disables Jest features that interfere with or slow down mutation testing
151
*/
152
export const JEST_OVERRIDE_OPTIONS: Readonly<Config.InitialOptions>;
153
```
154
155
The override options include:
156
157
```typescript
158
const JEST_OVERRIDE_OPTIONS = {
159
// Prevent conflicts with Stryker's result processing
160
testResultsProcessor: undefined,
161
162
// Disable Jest's built-in coverage (Stryker handles coverage)
163
collectCoverage: false,
164
165
// Reduce output noise during mutation testing
166
verbose: false,
167
168
// Disable desktop notifications during testing
169
notify: false,
170
171
// Ensure all tests run (bail not supported programmatically)
172
bail: false,
173
174
// Disable default reporters for cleaner output
175
reporters: [],
176
};
177
```
178
179
### Dependency Injection Tokens
180
181
Token definitions for Stryker's dependency injection system used by the Jest runner.
182
183
```typescript { .api }
184
/**
185
* Dependency injection tokens for Jest runner components
186
* Used by Stryker's plugin system for dependency resolution
187
*/
188
export const pluginTokens: {
189
readonly requireFromCwd: 'requireFromCwd';
190
readonly resolve: 'resolve';
191
readonly resolveFromDirectory: 'resolveFromDirectory';
192
readonly configLoader: 'configLoader';
193
readonly processEnv: 'processEnv';
194
readonly jestTestAdapter: 'jestTestAdapter';
195
readonly globalNamespace: 'globalNamespace';
196
readonly jestWrapper: 'jestWrapper';
197
readonly jestConfigWrapper: 'jestConfigWrapper';
198
};
199
200
/**
201
* Plugin context interface for dependency injection
202
* Defines available dependencies for Jest runner components
203
*/
204
export interface JestPluginContext extends PluginContext {
205
[pluginTokens.jestWrapper]: JestWrapper;
206
[pluginTokens.resolve]: RequireResolve;
207
[pluginTokens.requireFromCwd]: typeof requireResolve;
208
[pluginTokens.processEnv]: typeof process.env;
209
[pluginTokens.jestConfigWrapper]: JestConfigWrapper;
210
}
211
```
212
213
**Usage Example:**
214
215
```typescript
216
// Used internally by Stryker's dependency injection system
217
// Typically not used directly by end users
218
219
// Example of how tokens are used in factory functions
220
function someFactory(
221
jestWrapper: JestWrapper,
222
configLoader: JestConfigLoader
223
) {
224
// Factory implementation
225
}
226
227
someFactory.inject = tokens(
228
pluginTokens.jestWrapper,
229
pluginTokens.configLoader
230
);
231
```
232
233
## Types
234
235
### Configuration Enhancement Types
236
237
```typescript { .api }
238
type CoverageAnalysis = 'off' | 'all' | 'perTest';
239
240
namespace Config {
241
interface InitialOptions {
242
testEnvironment?: string;
243
testRunner?: string;
244
setupFiles?: string[];
245
setupFilesAfterEnv?: string[];
246
testMatch?: string[];
247
collectCoverage?: boolean;
248
verbose?: boolean;
249
notify?: boolean;
250
bail?: boolean;
251
reporters?: any[];
252
globals?: { [key: string]: any };
253
// ... other Jest configuration options
254
}
255
}
256
```
257
258
### Jest Result Types
259
260
```typescript { .api }
261
import type { AggregatedResult } from '@jest/test-result';
262
263
// AggregatedResult contains complete Jest test execution results
264
// including test suites, individual test results, and coverage data
265
```
266
267
### Utility Function Types
268
269
```typescript { .api }
270
type RequireResolve = (id: string) => string;
271
272
interface PluginContext {
273
// Base Stryker plugin context
274
}
275
```
276
277
## Implementation Details
278
279
### Environment Override Strategy
280
281
The configuration enhancement functions use a layered approach:
282
283
1. **Base Configuration**: Start with user's Jest configuration
284
2. **Coverage Enhancement**: Override test environment with Stryker-enhanced version
285
3. **Framework Setup**: Configure appropriate test framework for coverage tracking
286
4. **Hit Limit Integration**: Add hit counting capabilities when needed
287
288
### Version Compatibility
289
290
The utilities handle Jest version differences:
291
292
- **Jest <27**: Uses `jest-jasmine2` test runner with custom setup files
293
- **Jest ≥27**: Uses `jest-circus` test runner with event handlers
294
- **Automatic Detection**: `JestWrapper.getVersion()` determines appropriate strategy
295
296
### Coverage Validation Process
297
298
The coverage validation ensures proper Stryker integration:
299
300
1. **File Registration**: Test files register with Stryker environment during execution
301
2. **Coverage Collection**: Instrumenter tracks which tests execute which code
302
3. **Validation**: Confirms all test files have proper Stryker environment integration
303
4. **Error Reporting**: Provides detailed error messages for integration issues
304
305
### Performance Optimizations
306
307
The override options are specifically chosen for mutation testing performance:
308
309
- **Disabled Coverage**: Jest's built-in coverage conflicts with Stryker's instrumenter
310
- **No Reporters**: Default reporters slow down test execution significantly
311
- **Quiet Output**: Verbose logging creates unnecessary overhead
312
- **No Notifications**: Desktop notifications interrupt automated testing workflows