in packages/jest-reporters/src/CoverageReporter.ts [117:227]
private async _addUntestedFiles(contexts: Set<Context>): Promise<void> {
const files: Array<{config: Config.ProjectConfig; path: string}> = [];
contexts.forEach(context => {
const config = context.config;
if (
this._globalConfig.collectCoverageFrom &&
this._globalConfig.collectCoverageFrom.length
) {
context.hasteFS
.matchFilesWithGlob(
this._globalConfig.collectCoverageFrom,
config.rootDir,
)
.forEach(filePath =>
files.push({
config,
path: filePath,
}),
);
}
});
if (!files.length) {
return;
}
if (isInteractive) {
process.stderr.write(
RUNNING_TEST_COLOR('Running coverage on untested files...'),
);
}
let worker: CoverageWorker | Worker;
if (this._globalConfig.maxWorkers <= 1) {
worker = require('./CoverageWorker');
} else {
worker = new Worker(require.resolve('./CoverageWorker'), {
exposedMethods: ['worker'],
maxRetries: 2,
numWorkers: this._globalConfig.maxWorkers,
});
}
const instrumentation = files.map(async fileObj => {
const filename = fileObj.path;
const config = fileObj.config;
const hasCoverageData = this._v8CoverageResults.some(v8Res =>
v8Res.some(innerRes => innerRes.result.url === filename),
);
if (
!hasCoverageData &&
!this._coverageMap.data[filename] &&
'worker' in worker
) {
try {
const result = await worker.worker({
config,
globalConfig: this._globalConfig,
options: {
...this._options,
changedFiles:
this._options.changedFiles &&
Array.from(this._options.changedFiles),
sourcesRelatedToTestsInChangedFiles:
this._options.sourcesRelatedToTestsInChangedFiles &&
Array.from(this._options.sourcesRelatedToTestsInChangedFiles),
},
path: filename,
});
if (result) {
if (result.kind === 'V8Coverage') {
this._v8CoverageResults.push([
{codeTransformResult: undefined, result: result.result},
]);
} else {
this._coverageMap.addFileCoverage(result.coverage);
}
}
} catch (error: any) {
console.error(
chalk.red(
[
`Failed to collect coverage from ${filename}`,
`ERROR: ${error.message}`,
`STACK: ${error.stack}`,
].join('\n'),
),
);
}
}
});
try {
await Promise.all(instrumentation);
} catch {
// Do nothing; errors were reported earlier to the console.
}
if (isInteractive) {
clearLine(process.stderr);
}
if (worker && 'end' in worker && typeof worker.end === 'function') {
await worker.end();
}
}