@split-tests/jest
Version:
Splits test files in Jest and ensures all parallel jobs finish work at a similar time
69 lines (65 loc) • 2.72 kB
JavaScript
import Sequencer from '@jest/test-sequencer';
import { loadXML, findFilenameInJUnit, removeDeletedFiles, addNewFiles, distribute } from '@split-tests/core';
import path from 'path';
function junitAdapter(globalConfig, options) {
const rootDir = globalConfig.rootDir;
const junitPath = options.junit;
const junitFile = path.resolve(junitPath.replace("<rootDir>", rootDir));
const junit = loadXML(junitFile);
const summary = junit.testsuites;
return summary.testsuite.map((t) => {
const file = findFilenameInJUnit(t);
return {
path: path.resolve(rootDir, file),
time: parseFloat(t.time),
};
});
}
function getArg(name) {
const arg = process.argv.find((val) => val.startsWith(`--${name}`));
if (arg) {
return arg.replace(`--${name}=`, "");
}
}
class JobSequencer extends Sequencer {
// @ts-ignore
async sort(tests) {
if (process.env.JEST_JOBS_TOTAL || getArg("jobsTotal")) {
let total = parseInt(process.env.JEST_JOBS_TOTAL || getArg("jobsTotal"), 10);
let index = parseInt(process.env.JEST_JOBS_INDEX || getArg("jobsIndex"), 10);
if (process.env.JEST_NORMAL) {
return tests
.sort((a, b) => (a.path < b.path ? -1 : 1))
.filter((_, i) => i % total === index);
}
const config = tests[0].context.config;
let reports = [];
const normalizedTests = tests.sort((a, b) => (a.path < b.path ? -1 : 1));
if (config.globals && config.globals["split-tests"]) {
const options = config.globals["split-tests"];
if (options.junit) {
reports = junitAdapter(config, options);
}
else if (typeof options.reader === "function") {
// we might need to use absolute paths here
reports = await options.reader(normalizedTests);
}
if (options.jobs) {
if (options.jobs.total) {
total = options.jobs.total();
}
if (options.jobs.index) {
index = options.jobs.index();
}
}
}
reports = removeDeletedFiles(reports, normalizedTests);
reports = addNewFiles(reports, normalizedTests);
const groups = distribute(reports, total);
return groups[index].files.map((testFile) => normalizedTests.find((t) => t.path === testFile));
}
return tests;
}
}
export default JobSequencer;
//# sourceMappingURL=index.esm.js.map