-
Notifications
You must be signed in to change notification settings - Fork 241
/
2-MutantInstrumenterExecutor.ts
66 lines (54 loc) · 3.01 KB
/
2-MutantInstrumenterExecutor.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
import { Injector, tokens, commonTokens } from '@stryker-mutator/api/plugin';
import { Instrumenter, InstrumentResult } from '@stryker-mutator/instrumenter';
import { File, StrykerOptions } from '@stryker-mutator/api/core';
import { MainContext, coreTokens } from '../di';
import InputFileCollection from '../input/InputFileCollection';
import { Sandbox } from '../sandbox/sandbox';
import { LoggingClientContext } from '../logging';
import { ConcurrencyTokenProvider, createCheckerPool } from '../concurrent';
import { createCheckerFactory } from '../checker/CheckerFacade';
import { createPreprocessor } from '../sandbox';
import { DryRunContext } from './3-DryRunExecutor';
export interface MutantInstrumenterContext extends MainContext {
[coreTokens.inputFiles]: InputFileCollection;
[coreTokens.loggingContext]: LoggingClientContext;
}
export class MutantInstrumenterExecutor {
public static readonly inject = tokens(commonTokens.injector, coreTokens.inputFiles, commonTokens.options);
constructor(
private readonly injector: Injector<MutantInstrumenterContext>,
private readonly inputFiles: InputFileCollection,
private readonly options: StrykerOptions
) {}
public async execute(): Promise<Injector<DryRunContext>> {
// Create the checker and instrumenter
const instrumenter = this.injector.injectClass(Instrumenter);
// Instrument files in-memory
const instrumentResult = await instrumenter.instrument(this.inputFiles.filesToMutate, { plugins: this.options.mutator.plugins });
// Preprocess sandbox files
const preprocess = this.injector.injectFunction(createPreprocessor);
const files = await preprocess.preprocess(this.replaceInstrumentedFiles(instrumentResult));
// Initialize the checker pool
const concurrencyTokenProviderProvider = this.injector.provideClass(coreTokens.concurrencyTokenProvider, ConcurrencyTokenProvider);
const concurrencyTokenProvider = concurrencyTokenProviderProvider.resolve(coreTokens.concurrencyTokenProvider);
const checkerPoolProvider = concurrencyTokenProviderProvider
.provideValue(coreTokens.checkerConcurrencyTokens, concurrencyTokenProvider.checkerToken$)
.provideFactory(coreTokens.checkerFactory, createCheckerFactory)
.provideFactory(coreTokens.checkerPool, createCheckerPool);
const checkerPool = checkerPoolProvider.resolve(coreTokens.checkerPool);
await checkerPool.init();
// Feed the sandbox
const sandbox = await this.injector.provideValue(coreTokens.files, files).injectFunction(Sandbox.create);
return checkerPoolProvider.provideValue(coreTokens.sandbox, sandbox).provideValue(coreTokens.mutants, instrumentResult.mutants);
}
private replaceInstrumentedFiles(instrumentResult: InstrumentResult): File[] {
return this.inputFiles.files.map((inputFile) => {
const instrumentedFile = instrumentResult.files.find((instrumentedFile) => instrumentedFile.name === inputFile.name);
if (instrumentedFile) {
return instrumentedFile;
} else {
return inputFile;
}
});
}
}