@stryker-mutator/karma-runner
Version:
A plugin to use the karma test runner in Stryker, the JavaScript mutation testing framework
105 lines • 4.35 kB
JavaScript
import path from 'path';
import url, { fileURLToPath } from 'url';
import { INSTRUMENTER_CONSTANTS } from '@stryker-mutator/api/core';
import { escapeRegExpLiteral } from '@stryker-mutator/util';
export const TEST_HOOKS_FILE_NAME = path.resolve(path.dirname(fileURLToPath(import.meta.url)), 'test-hooks-middleware-21f23d35-a4c9-4b01-aeff-da9c99c3ffc0.js');
const TEST_HOOKS_FILE_BASE_NAME = path.basename(TEST_HOOKS_FILE_NAME);
const SUPPORTED_FRAMEWORKS = Object.freeze(['mocha', 'jasmine']);
function isSupportedFramework(framework) {
return SUPPORTED_FRAMEWORKS.includes(framework);
}
/**
* Keep in sync with StrykerMutantCoverageAdapter.ts
*/
const SHOULD_REPORT_COVERAGE_FLAG = '__strykerShouldReportCoverage__';
const { ACTIVE_MUTANT, NAMESPACE, CURRENT_TEST_ID, HIT_COUNT, HIT_LIMIT } = INSTRUMENTER_CONSTANTS;
export class TestHooksMiddleware {
static _instance;
testFramework;
currentTestHooks = '';
static get instance() {
if (!this._instance) {
this._instance = new TestHooksMiddleware();
}
return this._instance;
}
configureTestFramework(frameworks) {
this.testFramework = frameworks?.find(isSupportedFramework);
}
configureCoverageAnalysis(coverageAnalysis) {
switch (coverageAnalysis) {
case 'perTest':
this.configurePerTestCoverageAnalysis();
break;
case 'all':
this.currentTestHooks = `window.${SHOULD_REPORT_COVERAGE_FLAG} = true;`;
break;
case 'off':
this.currentTestHooks = `window.${SHOULD_REPORT_COVERAGE_FLAG} = false;`;
break;
}
}
configureMutantRun({ activeMutant, testFilter, hitLimit }) {
this.configureCoverageAnalysis('off');
this.currentTestHooks += `window.${NAMESPACE} = window.${NAMESPACE} || {};`;
this.currentTestHooks += this.configureHitLimit(hitLimit);
this.currentTestHooks += `window.${NAMESPACE}.${ACTIVE_MUTANT} = "${activeMutant.id}";`;
if (testFilter) {
switch (this.testFramework) {
case 'jasmine':
this.currentTestHooks += `jasmine.getEnv().configure({ specFilter: function(spec) {
return ${JSON.stringify(testFilter)}.indexOf(spec.id) !== -1;
}})`;
break;
case 'mocha': {
const metaRegExp = testFilter.map((testId) => `(${escapeRegExpLiteral(testId)})`).join('|');
this.currentTestHooks += `mocha.grep(/${metaRegExp}/)`;
break;
}
default:
}
}
}
configureHitLimit(hitLimit) {
return `window.${NAMESPACE}.${HIT_COUNT} = ${hitLimit === undefined ? undefined : 0};
window.${NAMESPACE}.${HIT_LIMIT} = ${hitLimit};`;
}
configurePerTestCoverageAnalysis() {
this.currentTestHooks = `
window.${SHOULD_REPORT_COVERAGE_FLAG} = true;
window.${NAMESPACE} = window.${NAMESPACE} || {};`;
switch (this.testFramework) {
case 'jasmine':
this.currentTestHooks += `
jasmine.getEnv().addReporter({
specStarted: function (spec) {
window.${NAMESPACE}.${CURRENT_TEST_ID} = spec.id;
}
});`;
break;
case 'mocha':
this.currentTestHooks += `
beforeEach(function() {
window.${NAMESPACE}.${CURRENT_TEST_ID} = this.currentTest && this.currentTest.fullTitle();
});
`;
break;
case undefined:
throw new Error(`Could not configure coverageAnalysis "perTest". Your test framework is not supported by the \`@stryker-mutator/karma-runner\`. Supported test frameworks: ${SUPPORTED_FRAMEWORKS.join(', ')}.`);
}
}
handler = (request, response, next) => {
const pathName = url.parse(request.url).pathname;
if (pathName?.endsWith(TEST_HOOKS_FILE_BASE_NAME)) {
response.writeHead(200, {
'Cache-Control': 'no-cache',
'Content-Type': 'application/javascript',
});
response.end(this.currentTestHooks);
}
else {
next();
}
};
}
//# sourceMappingURL=test-hooks-middleware.js.map