@stryker-mutator/core
Version:
The extendable JavaScript mutation testing framework
94 lines • 4.76 kB
JavaScript
import { DryRunStatus, MutantRunStatus, } from '@stryker-mutator/api/test-runner';
import { expect } from 'chai';
import sinon from 'sinon';
import { factory } from '@stryker-mutator/test-helpers';
import { TimeoutDecorator } from '../../../src/test-runner/timeout-decorator.js';
describe(TimeoutDecorator.name, () => {
let sut;
let sandbox;
let clock;
let testRunner1;
let testRunner2;
let availableTestRunners;
beforeEach(() => {
sandbox = sinon.createSandbox();
clock = sinon.useFakeTimers();
testRunner1 = factory.testRunner();
testRunner2 = factory.testRunner();
availableTestRunners = [testRunner1, testRunner2];
sut = new TimeoutDecorator(() => { var _a; return (_a = availableTestRunners.shift()) !== null && _a !== void 0 ? _a : expect.fail('test runners are empty'); });
});
afterEach(() => sandbox.restore());
function itShouldProxyRequests(action, methodName) {
it('should proxy the request', () => {
testRunner1[methodName].resolves();
const promise = action();
expect(testRunner1[methodName]).to.have.been.called;
expect(promise === null || promise === void 0 ? void 0 : promise.then, `timeoutDecorator.${methodName} did not provide a promise`).ok;
});
it('should resolve when inner promise resolves', () => {
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
testRunner1[methodName].resolves('str');
const promise = action();
return expect(promise).to.eventually.eq('str');
});
it('should reject when inner promise rejects', () => {
testRunner1[methodName].rejects(new Error('some error'));
const promise = action();
return expect(promise).to.be.rejectedWith('some error');
});
}
describe('dryRun', () => {
itShouldProxyRequests(() => sut.dryRun(factory.dryRunOptions({ coverageAnalysis: 'all', timeout: 20 })), 'dryRun');
it('should not handle timeouts premature', () => {
// eslint-disable-next-line @typescript-eslint/no-empty-function
let resolve = () => { };
const expectedResult = factory.completeDryRunResult();
testRunner1.dryRun.returns(new Promise((res) => (resolve = res)));
const runPromise = sut.dryRun(factory.dryRunOptions({ timeout: 20 }));
clock.tick(19);
resolve(expectedResult);
return expect(runPromise).to.eventually.be.eq(expectedResult);
});
it('should handle timeouts', async () => {
testRunner1.dryRun.returns(
// eslint-disable-next-line @typescript-eslint/no-empty-function
new Promise(() => { }));
const runPromise = sut.dryRun(factory.dryRunOptions({ timeout: 20 }));
clock.tick(20);
const result = await runPromise;
const expectedTimeoutResult = { status: DryRunStatus.Timeout };
expect(result).deep.eq(expectedTimeoutResult);
expect(availableTestRunners).to.have.lengthOf(0);
expect(testRunner1.dispose).to.have.been.called;
expect(testRunner2.init).to.have.been.called;
});
});
describe('mutantRun', () => {
itShouldProxyRequests(() => sut.mutantRun(factory.mutantRunOptions({ timeout: 20 })), 'mutantRun');
it('should not handle timeouts premature', () => {
// eslint-disable-next-line @typescript-eslint/no-empty-function
let resolve = () => { };
const expectedResult = factory.killedMutantRunResult();
testRunner1.mutantRun.returns(new Promise((res) => (resolve = res)));
const runPromise = sut.mutantRun(factory.mutantRunOptions({ timeout: 20 }));
clock.tick(19);
resolve(expectedResult);
return expect(runPromise).to.eventually.be.eq(expectedResult);
});
it('should handle timeouts', async () => {
testRunner1.mutantRun.returns(
// eslint-disable-next-line @typescript-eslint/no-empty-function
new Promise(() => { }));
const runPromise = sut.mutantRun(factory.mutantRunOptions({ timeout: 20 }));
clock.tick(20);
const result = await runPromise;
const expectedTimeoutResult = { status: MutantRunStatus.Timeout };
expect(result).deep.eq(expectedTimeoutResult);
expect(availableTestRunners).to.have.lengthOf(0);
expect(testRunner1.dispose).to.have.been.called;
expect(testRunner2.init).to.have.been.called;
});
});
});
//# sourceMappingURL=timeout-decorator.spec.js.map