/
child-process-test-runner-decorator.spec.ts
115 lines (102 loc) · 4.37 KB
/
child-process-test-runner-decorator.spec.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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
import { LogLevel, StrykerOptions } from '@stryker-mutator/api/core';
import { strykerOptions } from '@stryker-mutator/test-helpers/src/factory';
import { expect } from 'chai';
import * as sinon from 'sinon';
import { Task } from '@stryker-mutator/util';
import { TestRunner } from '@stryker-mutator/api/test-runner';
import { factory } from '@stryker-mutator/test-helpers';
import ChildProcessCrashedError from '../../../src/child-proxy/child-process-crashed-error';
import ChildProcessProxy from '../../../src/child-proxy/child-process-proxy';
import { LoggingClientContext } from '../../../src/logging';
import ChildProcessTestRunnerDecorator from '../../../src/test-runner/child-process-test-runner-decorator';
import { ChildProcessTestRunnerWorker } from '../../../src/test-runner/child-process-test-runner-worker';
describe(ChildProcessTestRunnerDecorator.name, () => {
let options: StrykerOptions;
let childProcessProxyMock: {
proxy: sinon.SinonStubbedInstance<Required<TestRunner>>;
dispose: sinon.SinonStub;
};
let childProcessProxyCreateStub: sinon.SinonStub;
let loggingContext: LoggingClientContext;
let clock: sinon.SinonFakeTimers;
beforeEach(() => {
clock = sinon.useFakeTimers();
childProcessProxyMock = {
dispose: sinon.stub(),
proxy: factory.testRunner(),
};
childProcessProxyCreateStub = sinon.stub(ChildProcessProxy, 'create');
childProcessProxyCreateStub.returns(childProcessProxyMock);
options = strykerOptions({
plugins: ['foo-plugin', 'bar-plugin'],
});
loggingContext = { port: 4200, level: LogLevel.Fatal };
});
function createSut(): ChildProcessTestRunnerDecorator {
return new ChildProcessTestRunnerDecorator(options, 'a working directory', loggingContext);
}
it('should create the child process proxy', () => {
options.testRunnerNodeArgs = ['--inspect', '--no-warnings'];
createSut();
expect(childProcessProxyCreateStub).calledWithExactly(
require.resolve('../../../src/test-runner/child-process-test-runner-worker.js'),
loggingContext,
options,
{},
'a working directory',
ChildProcessTestRunnerWorker,
['--inspect', '--no-warnings']
);
});
it('should forward `init` calls', () => {
const sut = createSut();
childProcessProxyMock.proxy.init.resolves(42);
return expect(sut.init()).eventually.eq(42);
});
it('should forward `dryRun` calls', async () => {
const sut = createSut();
const expectedResult = factory.completeDryRunResult({ mutantCoverage: factory.mutantCoverage() });
childProcessProxyMock.proxy.dryRun.resolves(expectedResult);
const runOptions = factory.dryRunOptions({
timeout: 234,
});
const actualResult = await sut.dryRun(runOptions);
expect(actualResult).eq(expectedResult);
expect(childProcessProxyMock.proxy.dryRun).calledWith(runOptions);
});
it('should forward `mutantRun` calls', async () => {
const sut = createSut();
const expectedResult = factory.survivedMutantRunResult();
childProcessProxyMock.proxy.mutantRun.resolves(expectedResult);
const runOptions = factory.mutantRunOptions({
timeout: 234,
});
const actualResult = await sut.mutantRun(runOptions);
expect(actualResult).eq(expectedResult);
expect(childProcessProxyMock.proxy.mutantRun).calledWith(runOptions);
});
describe('dispose', () => {
it('should dispose the test runner before disposing the child process itself on `dispose`', async () => {
const sut = createSut();
childProcessProxyMock.proxy.dispose.resolves();
await sut.dispose();
expect(childProcessProxyMock.proxy.dispose).calledBefore(childProcessProxyMock.dispose);
});
it('should not reject when the child process is down', async () => {
const sut = createSut();
childProcessProxyMock.proxy.dispose.rejects(new ChildProcessCrashedError(1, '1'));
await sut.dispose();
expect(childProcessProxyMock.dispose).called;
});
it('should only wait 2 seconds for the test runner to be disposed', async () => {
const sut = createSut();
const testRunnerDisposeTask = new Task();
childProcessProxyMock.proxy.dispose.returns(testRunnerDisposeTask.promise);
const disposePromise = sut.dispose();
clock.tick(2001);
await disposePromise;
expect(childProcessProxyMock.dispose).called;
testRunnerDisposeTask.resolve(undefined);
});
});
});