diff --git a/CHANGELOG.md b/CHANGELOG.md index c12bd0ed0e2c..5d686959f485 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ - `[jest-reporters]` Fix issue where console output not displayed for GHA reporter even with `silent: false` option ([#15864](https://github.com/jestjs/jest/pull/15864)) - `[jest-runtime]` Fix issue where user cannot utilize dynamic import despite specifying `--experimental-vm-modules` Node option ([#15842](https://github.com/jestjs/jest/pull/15842)) - `[jest-test-sequencer]` Fix issue where failed tests due to compilation errors not getting re-executed even with `--onlyFailures` CLI option ([#15851](https://github.com/jestjs/jest/pull/15851)) +- `[jest-runner, jest-transform]` Fix coverage report doesn't show correct code coverage when using `projects` config option ([#15880](https://github.com/jestjs/jest/pull/15880)), fixes ([#5417](https://github.com/jestjs/jest/issues/5417)) ### Chore & Maintenance diff --git a/e2e/__tests__/__snapshots__/coverageReport.test.ts.snap b/e2e/__tests__/__snapshots__/coverageReport.test.ts.snap index c37043ff20e4..5f2f5bb23612 100644 --- a/e2e/__tests__/__snapshots__/coverageReport.test.ts.snap +++ b/e2e/__tests__/__snapshots__/coverageReport.test.ts.snap @@ -138,3 +138,15 @@ Functions : 50% ( 3/6 ) Lines : 60% ( 12/20 ) ================================================================================" `; + +exports[`outputs coverage report with projects option 1`] = ` +"------------|---------|----------|---------|---------|------------------- +File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s +------------|---------|----------|---------|---------|------------------- +All files | 66.66 | 100 | 50 | 66.66 | + client | 66.66 | 100 | 50 | 66.66 | + client.js | 66.66 | 100 | 50 | 66.66 | 13 + server | 66.66 | 100 | 50 | 66.66 | + server.js | 66.66 | 100 | 50 | 66.66 | 13 +------------|---------|----------|---------|---------|-------------------" +`; diff --git a/e2e/__tests__/coverageReport.test.ts b/e2e/__tests__/coverageReport.test.ts index e3bffe332dac..5fece54c050a 100644 --- a/e2e/__tests__/coverageReport.test.ts +++ b/e2e/__tests__/coverageReport.test.ts @@ -189,3 +189,13 @@ test('generates coverage when using the testRegex config param ', () => { expect(stdout).toMatchSnapshot(); expect(exitCode).toBe(0); }); + +test('outputs coverage report with projects option', () => { + const projectDir = path.resolve(__dirname, '../coverage-with-projects'); + const {stdout, exitCode} = runJest(projectDir, ['--no-cache', '--coverage'], { + stripAnsi: true, + }); + + expect(stdout).toMatchSnapshot(); + expect(exitCode).toBe(0); +}); diff --git a/e2e/coverage-with-projects/package.json b/e2e/coverage-with-projects/package.json new file mode 100644 index 000000000000..28758c7b462c --- /dev/null +++ b/e2e/coverage-with-projects/package.json @@ -0,0 +1,13 @@ +{ + "jest": { + "projects": [ + "/packages/client", + "/packages/server" + ], + "collectCoverageFrom": [ + "packages/client/**/*.js", + "packages/server/**/*.js" + ], + "testEnvironment": "node" + } +} diff --git a/e2e/coverage-with-projects/packages/client/client.js b/e2e/coverage-with-projects/packages/client/client.js new file mode 100644 index 000000000000..a2149737f1f3 --- /dev/null +++ b/e2e/coverage-with-projects/packages/client/client.js @@ -0,0 +1,16 @@ +/** + * 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 add(a, b) { + return a + b; +} + +function subtract(a, b) { + return a - b; +} + +module.exports = {add, subtract}; diff --git a/e2e/coverage-with-projects/packages/client/client.test.js b/e2e/coverage-with-projects/packages/client/client.test.js new file mode 100644 index 000000000000..a18e3e852208 --- /dev/null +++ b/e2e/coverage-with-projects/packages/client/client.test.js @@ -0,0 +1,12 @@ +/** + * 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 {add} = require('./client'); + +test('add function', () => { + expect(add(1, 2)).toBe(3); +}); diff --git a/e2e/coverage-with-projects/packages/client/package.json b/e2e/coverage-with-projects/packages/client/package.json new file mode 100644 index 000000000000..148788b25446 --- /dev/null +++ b/e2e/coverage-with-projects/packages/client/package.json @@ -0,0 +1,5 @@ +{ + "jest": { + "testEnvironment": "node" + } +} diff --git a/e2e/coverage-with-projects/packages/server/package.json b/e2e/coverage-with-projects/packages/server/package.json new file mode 100644 index 000000000000..148788b25446 --- /dev/null +++ b/e2e/coverage-with-projects/packages/server/package.json @@ -0,0 +1,5 @@ +{ + "jest": { + "testEnvironment": "node" + } +} diff --git a/e2e/coverage-with-projects/packages/server/server.js b/e2e/coverage-with-projects/packages/server/server.js new file mode 100644 index 000000000000..c6c8991cab8f --- /dev/null +++ b/e2e/coverage-with-projects/packages/server/server.js @@ -0,0 +1,16 @@ +/** + * 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 multiply(a, b) { + return a * b; +} + +function divide(a, b) { + return a / b; +} + +module.exports = {divide, multiply}; diff --git a/e2e/coverage-with-projects/packages/server/server.test.js b/e2e/coverage-with-projects/packages/server/server.test.js new file mode 100644 index 000000000000..7ca7622f7676 --- /dev/null +++ b/e2e/coverage-with-projects/packages/server/server.test.js @@ -0,0 +1,12 @@ +/** + * 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 {multiply} = require('./server'); + +test('multiply function', () => { + expect(multiply(2, 3)).toBe(6); +}); diff --git a/packages/jest-runner/src/runTest.ts b/packages/jest-runner/src/runTest.ts index 05256db47aa7..f3cf9472ea6b 100644 --- a/packages/jest-runner/src/runTest.ts +++ b/packages/jest-runner/src/runTest.ts @@ -197,6 +197,7 @@ async function runTestInternal( collectCoverage: globalConfig.collectCoverage, collectCoverageFrom: globalConfig.collectCoverageFrom, coverageProvider: globalConfig.coverageProvider, + globalRootDir: globalConfig.rootDir, sourcesRelatedToTestsInChangedFiles: context.sourcesRelatedToTestsInChangedFiles, }, diff --git a/packages/jest-transform/src/__tests__/shouldInstrument.test.ts b/packages/jest-transform/src/__tests__/shouldInstrument.test.ts index e48229f06a6f..12b5b8175d97 100644 --- a/packages/jest-transform/src/__tests__/shouldInstrument.test.ts +++ b/packages/jest-transform/src/__tests__/shouldInstrument.test.ts @@ -125,6 +125,28 @@ describe('shouldInstrument', () => { forceCoverageMatch: ['**/do/**/*.json'], }); }); + + it('when using projects with globalRootDir and file matches collectCoverageFrom', () => { + testShouldInstrument( + '/root/packages/server/server.js', + { + collectCoverageFrom: ['server/**/*.js'], + globalRootDir: '/root/packages', + }, + {rootDir: '/root/packages/server'}, + ); + }); + + it('when using projects with globalRootDir and file matches collectCoverageFrom with multiple patterns', () => { + testShouldInstrument( + '/root/packages/client/client.js', + { + collectCoverageFrom: ['client/**/*.js', 'server/**/*.js'], + globalRootDir: '/root/packages', + }, + {rootDir: '/root/packages/client'}, + ); + }); }); describe('should return false', () => { @@ -259,5 +281,16 @@ describe('shouldInstrument', () => { defaultConfig, ); }); + + it('when using projects with globalRootDir and file does not match collectCoverageFrom', () => { + testShouldInstrument( + '/root/packages/utils/utils.js', + { + collectCoverageFrom: ['client/**/*.js', 'server/**/*.js'], + globalRootDir: '/root/packages', + }, + {rootDir: '/root/packages/utils'}, + ); + }); }); }); diff --git a/packages/jest-transform/src/shouldInstrument.ts b/packages/jest-transform/src/shouldInstrument.ts index 511a7f5e1f3d..b7dda3d61459 100644 --- a/packages/jest-transform/src/shouldInstrument.ts +++ b/packages/jest-transform/src/shouldInstrument.ts @@ -73,7 +73,9 @@ export default function shouldInstrument( // still cover if `only` is specified options.collectCoverageFrom.length > 0 && !globsToMatcher(options.collectCoverageFrom)( - replacePathSepForGlob(path.relative(config.rootDir, filename)), + replacePathSepForGlob( + path.relative(options.globalRootDir ?? config.rootDir, filename), + ), ) ) { return false; diff --git a/packages/jest-transform/src/types.ts b/packages/jest-transform/src/types.ts index aa37fa5b450a..eee2455eb951 100644 --- a/packages/jest-transform/src/types.ts +++ b/packages/jest-transform/src/types.ts @@ -15,6 +15,7 @@ export interface ShouldInstrumentOptions > { changedFiles?: Set; sourcesRelatedToTestsInChangedFiles?: Set; + globalRootDir?: string; } export interface Options