mirror of https://github.com/facebook/jest.git
fix(jest-runtime, @jest/transform): allow V8 coverage provider to collect coverage from files which were not loaded explicitly (#13974)
Co-authored-by: GP4cK <gautier.bayzelon@gmail.com>
This commit is contained in:
parent
679b5adc1f
commit
0060728fe5
|
@ -11,6 +11,7 @@
|
|||
- `[jest-message-util]` Add support for [AggregateError](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/AggregateError) ([#13946](https://github.com/facebook/jest/pull/13946) & [#13947](https://github.com/facebook/jest/pull/13947))
|
||||
- `[jest-message-util]` Add support for [Error causes](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/cause) in `test` and `it` ([#13935](https://github.com/facebook/jest/pull/13935) & [#13966](https://github.com/facebook/jest/pull/13966))
|
||||
- `[jest-reporters]` Add `summaryThreshold` option to summary reporter to allow overriding the internal threshold that is used to print the summary of all failed tests when the number of test suites surpasses it ([#13895](https://github.com/facebook/jest/pull/13895))
|
||||
- `[jest-runtime, @jest/transform]` Allow V8 coverage provider to collect coverage from files which were not loaded explicitly ([#13974](https://github.com/facebook/jest/pull/13974))
|
||||
- `[jest-snapshot]` Add support to `cts` and `mts` TypeScript files to inline snapshots ([#13975](https://github.com/facebook/jest/pull/13975))
|
||||
- `[jest-worker]` Add `start` method to worker farms ([#13937](https://github.com/facebook/jest/pull/13937))
|
||||
|
||||
|
|
|
@ -105,3 +105,12 @@ All files | 59.37 | 33.33 | 33.33 | 59.37 |
|
|||
uncovered.js | 0 | 0 | 0 | 0 | 1-8
|
||||
--------------|---------|----------|---------|---------|-------------------"
|
||||
`;
|
||||
|
||||
exports[`vm script coverage generator 1`] = `
|
||||
"-------------|---------|----------|---------|---------|-------------------
|
||||
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
|
||||
-------------|---------|----------|---------|---------|-------------------
|
||||
All files | 88.88 | 100 | 66.66 | 88.88 |
|
||||
vmscript.js | 88.88 | 100 | 66.66 | 88.88 | 20-22
|
||||
-------------|---------|----------|---------|---------|-------------------"
|
||||
`;
|
||||
|
|
|
@ -106,3 +106,15 @@ test('prints correct coverage report, if a TS module is transpiled by custom tra
|
|||
expect(exitCode).toBe(0);
|
||||
expect(stdout).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('vm script coverage generator', () => {
|
||||
const dir = path.resolve(__dirname, '../vmscript-coverage');
|
||||
const {stdout, exitCode} = runJest(
|
||||
dir,
|
||||
['--coverage', '--coverage-provider', 'v8'],
|
||||
{stripAnsi: true},
|
||||
);
|
||||
|
||||
expect(exitCode).toBe(0);
|
||||
expect(stdout).toMatchSnapshot();
|
||||
});
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const vm = require('vm');
|
||||
const filePath = path.resolve(__dirname, '../package/vmscript.js');
|
||||
|
||||
test('extract coverage', () => {
|
||||
const content = fs.readFileSync(filePath, {encoding: 'utf8'});
|
||||
|
||||
const case1 = vm.runInNewContext(
|
||||
content,
|
||||
{
|
||||
inputObject: {
|
||||
number: 0,
|
||||
},
|
||||
},
|
||||
{
|
||||
filename: filePath,
|
||||
},
|
||||
);
|
||||
|
||||
const case2 = vm.runInNewContext(
|
||||
content,
|
||||
{
|
||||
inputObject: {
|
||||
number: 7,
|
||||
},
|
||||
},
|
||||
{
|
||||
filename: filePath,
|
||||
},
|
||||
);
|
||||
|
||||
expect(case1).toBe(false);
|
||||
expect(case2).toBe(true);
|
||||
});
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"jest": {
|
||||
"rootDir": "./",
|
||||
"testEnvironment": "node",
|
||||
"collectCoverageFrom": [
|
||||
"package/**/*.js"
|
||||
]
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
function addOne(inputNumber) {
|
||||
return ++inputNumber;
|
||||
}
|
||||
|
||||
function isEven(inputNumber) {
|
||||
if (inputNumber % 2 === 0) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function notCovered() {
|
||||
return 'not covered';
|
||||
}
|
||||
|
||||
/* global inputObject */
|
||||
if (inputObject.number / 1 === inputObject.number) {
|
||||
isEven(addOne(inputObject.number));
|
||||
}
|
|
@ -1267,8 +1267,12 @@ export default class Runtime {
|
|||
res =>
|
||||
// TODO: will this work on windows? It might be better if `shouldInstrument` deals with it anyways
|
||||
res.url.startsWith(this._config.rootDir) &&
|
||||
this._v8CoverageSources!.has(res.url) &&
|
||||
shouldInstrument(res.url, this._coverageOptions, this._config),
|
||||
shouldInstrument(
|
||||
res.url,
|
||||
this._coverageOptions,
|
||||
this._config,
|
||||
/* loadedFilenames */ Array.from(this._v8CoverageSources!.keys()),
|
||||
),
|
||||
)
|
||||
.map(result => {
|
||||
const transformedFile = this._v8CoverageSources!.get(result.url);
|
||||
|
|
|
@ -24,11 +24,13 @@ describe('shouldInstrument', () => {
|
|||
filename = defaultFilename,
|
||||
options: Partial<Options>,
|
||||
config: Partial<Config.ProjectConfig>,
|
||||
loadedFilenames?: Array<string>,
|
||||
) => {
|
||||
const result = shouldInstrument(
|
||||
filename,
|
||||
{...defaultOptions, ...options},
|
||||
{...defaultConfig, ...config},
|
||||
loadedFilenames,
|
||||
);
|
||||
expect(result).toBe(true);
|
||||
};
|
||||
|
@ -99,6 +101,24 @@ describe('shouldInstrument', () => {
|
|||
testRegex: ['.*\\.(test)\\.(js)$'],
|
||||
});
|
||||
});
|
||||
|
||||
it('when file is in loadedFilenames list', () => {
|
||||
testShouldInstrument(
|
||||
'do/collect/coverage.js',
|
||||
defaultOptions,
|
||||
defaultConfig,
|
||||
['do/collect/coverage.js'],
|
||||
);
|
||||
});
|
||||
|
||||
it('when file is in not loadedFilenames list, but matches collectCoverageFrom', () => {
|
||||
testShouldInstrument(
|
||||
'do/collect/coverage.js',
|
||||
{collectCoverageFrom: ['!**/dont/**/*.js', '**/do/**/*.js']},
|
||||
defaultConfig,
|
||||
['dont/collect/coverage.js'],
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('should return false', () => {
|
||||
|
@ -106,11 +126,13 @@ describe('shouldInstrument', () => {
|
|||
filename = defaultFilename,
|
||||
options: Partial<Options>,
|
||||
config: Partial<Config.ProjectConfig>,
|
||||
loadedFilenames?: Array<string>,
|
||||
) => {
|
||||
const result = shouldInstrument(
|
||||
filename,
|
||||
{...defaultOptions, ...options},
|
||||
{...defaultConfig, ...config},
|
||||
loadedFilenames,
|
||||
);
|
||||
expect(result).toBe(false);
|
||||
};
|
||||
|
@ -205,5 +227,23 @@ describe('shouldInstrument', () => {
|
|||
setupFilesAfterEnv: ['setupTest.js'],
|
||||
});
|
||||
});
|
||||
|
||||
it('when file is not in loadedFilenames list', () => {
|
||||
testShouldInstrument(
|
||||
'dont/collect/coverage.js',
|
||||
defaultOptions,
|
||||
defaultConfig,
|
||||
['do/collect/coverage.js'],
|
||||
);
|
||||
});
|
||||
|
||||
it('when file is in not loadedFilenames list and does not match collectCoverageFrom', () => {
|
||||
testShouldInstrument(
|
||||
'dont/collect/coverage.js',
|
||||
{collectCoverageFrom: ['!**/dont/**/*.js', '**/do/**/*.js']},
|
||||
defaultConfig,
|
||||
['do/collect/coverage.js'],
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -34,6 +34,7 @@ export default function shouldInstrument(
|
|||
filename: string,
|
||||
options: ShouldInstrumentOptions,
|
||||
config: Config.ProjectConfig,
|
||||
loadedFilenames?: Array<string>,
|
||||
): boolean {
|
||||
if (!options.collectCoverage) {
|
||||
return false;
|
||||
|
@ -60,6 +61,14 @@ export default function shouldInstrument(
|
|||
}
|
||||
}
|
||||
|
||||
if (
|
||||
options.collectCoverageFrom.length === 0 &&
|
||||
loadedFilenames != null &&
|
||||
!loadedFilenames.includes(filename)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (
|
||||
// still cover if `only` is specified
|
||||
options.collectCoverageFrom.length &&
|
||||
|
|
Loading…
Reference in New Issue