@stryker-mutator/vitest-runner
Version:
A plugin to use the vitest test runner and framework in Stryker, the JavaScript mutation testing framework
110 lines (97 loc) • 2.91 kB
text/typescript
import type { MutantCoverage } from '@stryker-mutator/api/core';
import type { MutantActivation } from '@stryker-mutator/api/test-runner';
import {
beforeEach,
afterAll,
beforeAll,
afterEach,
inject,
RunnerTestSuite,
RunnerTestCase,
} from 'vitest';
// This file is copied to the sandbox dir, don't import anything local!
// See https://github.com/stryker-mutator/stryker-js/issues/5305
const globalNamespace = inject('globalNamespace');
const mutantActivation = inject('mutantActivation');
const mode = inject('mode');
const ns = globalThis[globalNamespace] || (globalThis[globalNamespace] = {});
ns.hitLimit = inject('hitLimit');
const isGreaterThanVitest4Point1 = inject('isGreaterThanVitest4Point1');
if (mode === 'mutant') {
beforeAll(() => {
ns.hitCount = 0;
});
if (mutantActivation === 'static') {
ns.activeMutant = inject('activeMutant');
} else {
beforeAll(() => {
ns.activeMutant = inject('activeMutant');
});
}
if (isGreaterThanVitest4Point1) {
// Vitest's hooks API requires this empty destructure to allow access to suite.meta
// eslint-disable-next-line no-empty-pattern
afterAll(({}, suite) => {
suite.meta.hitCount = ns.hitCount;
});
} else {
// @ts-expect-error This was changed in Vitest v4.1
afterAll(({ meta }) => {
meta.hitCount = ns.hitCount;
});
}
} else {
ns.activeMutant = undefined;
beforeEach(({ task }) => {
ns.currentTestId = toRawTestId(task);
});
afterEach(() => {
ns.currentTestId = undefined;
});
if (isGreaterThanVitest4Point1) {
// Vitest's hooks API requires this empty destructure to allow access to suite.meta
// eslint-disable-next-line no-empty-pattern
afterAll(({}, suite) => {
suite.meta.mutantCoverage = ns.mutantCoverage;
});
} else {
// @ts-expect-error This was changed in Vitest v4.1
afterAll(({ meta }) => {
meta.mutantCoverage = ns.mutantCoverage;
});
}
}
// Stryker disable all: this file is copied to the sandbox dir
function collectTestName({
name,
suite,
}: {
name: string;
suite?: RunnerTestSuite;
}): string {
const nameParts = [name];
let currentSuite = suite;
while (currentSuite) {
nameParts.unshift(currentSuite.name);
currentSuite = currentSuite.suite;
}
return nameParts.join(' ').trim();
}
function toRawTestId(test: RunnerTestCase): string {
return `${test.file?.filepath ?? 'unknown.js'}#${collectTestName(test)}`;
}
// Stryker restore all
declare module 'vitest' {
interface ProvidedContext {
globalNamespace: '__stryker__' | '__stryker2__';
hitLimit: number | undefined;
mutantActivation: MutantActivation;
activeMutant: string | undefined;
mode: 'mutant' | 'dry-run';
isGreaterThanVitest4Point1: boolean;
}
interface TaskMeta {
hitCount: number | undefined;
mutantCoverage: MutantCoverage | undefined;
}
}