From 40ad51c14718b3660d78a27a4ea2fa4061536523 Mon Sep 17 00:00:00 2001 From: Simen Bekkhus Date: Sat, 14 Nov 2020 12:37:38 +0100 Subject: [PATCH] fix(reporters): make sure to handle empty files in v8 coverage --- CHANGELOG.md | 1 + .../__snapshots__/v8Coverage.test.ts.snap | 15 ++++++++++++--- e2e/__tests__/v8Coverage.test.ts | 18 ++++++++++++++++-- .../empty-sourcemap/babel.config.js | 3 +++ e2e/v8-coverage/empty-sourcemap/package.json | 7 +++++++ e2e/v8-coverage/empty-sourcemap/test.ts | 5 +++++ e2e/v8-coverage/empty-sourcemap/types.ts | 2 ++ .../jest-reporters/src/CoverageReporter.ts | 9 +++++---- 8 files changed, 51 insertions(+), 9 deletions(-) create mode 100644 e2e/v8-coverage/empty-sourcemap/babel.config.js create mode 100644 e2e/v8-coverage/empty-sourcemap/package.json create mode 100644 e2e/v8-coverage/empty-sourcemap/test.ts create mode 100644 e2e/v8-coverage/empty-sourcemap/types.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 8cbfb7b613fa..25f7b3a3b2e5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ - `[jest-console]` `console.dir` now respects the second argument correctly ([#10638](https://github.com/facebook/jest/pull/10638)) - `[expect]` [**BREAKING**] Revise `expect.not.objectContaining()` to be the inverse of `expect.objectContaining()`, as documented. ([#10708](https://github.com/facebook/jest/pull/10708)) +- `[jest-reporter]` Handle empty files when reporting code coverage with V8 ([#10819](https://github.com/facebook/jest/pull/10819)) - `[jest-resolve]` Replace read-pkg-up with escalade package ([#10781](https://github.com/facebook/jest/pull/10781)) - `[jest-runtime]` [**BREAKING**] Do not inject `global` variable into module wrapper ([#10644](https://github.com/facebook/jest/pull/10644)) - `[jest-runtime]` [**BREAKING**] remove long-deprecated `jest.addMatchers`, `jest.resetModuleRegistry`, and `jest.runTimersToTime` ([#9853](https://github.com/facebook/jest/pull/9853)) diff --git a/e2e/__tests__/__snapshots__/v8Coverage.test.ts.snap b/e2e/__tests__/__snapshots__/v8Coverage.test.ts.snap index e17b18a3ceec..b2ec317a31d6 100644 --- a/e2e/__tests__/__snapshots__/v8Coverage.test.ts.snap +++ b/e2e/__tests__/__snapshots__/v8Coverage.test.ts.snap @@ -1,7 +1,16 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`prints coverage 1`] = ` -" console.log +exports[`prints coverage with empty sourcemaps 1`] = ` +----------|---------|----------|---------|---------|------------------- +File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s +----------|---------|----------|---------|---------|------------------- +All files | 100 | 100 | 100 | 100 | + types.ts | 100 | 100 | 100 | 100 | +----------|---------|----------|---------|---------|------------------- +`; + +exports[`prints coverage with missing sourcemaps 1`] = ` + console.log 42 at Object.log (__tests__/Thing.test.js:10:9) @@ -12,5 +21,5 @@ File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s All files | 100 | 100 | 100 | 100 | Thing.js | 100 | 100 | 100 | 100 | x.css | 100 | 100 | 100 | 100 | -----------|---------|----------|---------|---------|-------------------" +----------|---------|----------|---------|---------|------------------- `; diff --git a/e2e/__tests__/v8Coverage.test.ts b/e2e/__tests__/v8Coverage.test.ts index b2cb96d3576b..199420b0fb84 100644 --- a/e2e/__tests__/v8Coverage.test.ts +++ b/e2e/__tests__/v8Coverage.test.ts @@ -6,11 +6,12 @@ */ import * as path from 'path'; +import wrap from 'jest-snapshot-serializer-raw'; import runJest from '../runJest'; const DIR = path.resolve(__dirname, '../v8-coverage'); -test('prints coverage', () => { +test('prints coverage with missing sourcemaps', () => { const sourcemapDir = path.join(DIR, 'no-sourcemap'); const {stdout, exitCode} = runJest( @@ -20,5 +21,18 @@ test('prints coverage', () => { ); expect(exitCode).toBe(0); - expect(stdout).toMatchSnapshot(); + expect(wrap(stdout)).toMatchSnapshot(); +}); + +test('prints coverage with empty sourcemaps', () => { + const sourcemapDir = path.join(DIR, 'empty-sourcemap'); + + const {stdout, exitCode} = runJest( + sourcemapDir, + ['--coverage', '--coverage-provider', 'v8'], + {stripAnsi: true}, + ); + + expect(exitCode).toBe(0); + expect(wrap(stdout)).toMatchSnapshot(); }); diff --git a/e2e/v8-coverage/empty-sourcemap/babel.config.js b/e2e/v8-coverage/empty-sourcemap/babel.config.js new file mode 100644 index 000000000000..27db1891d41a --- /dev/null +++ b/e2e/v8-coverage/empty-sourcemap/babel.config.js @@ -0,0 +1,3 @@ +module.exports = { + presets: ['@babel/preset-env', '@babel/preset-typescript'], +}; diff --git a/e2e/v8-coverage/empty-sourcemap/package.json b/e2e/v8-coverage/empty-sourcemap/package.json new file mode 100644 index 000000000000..d3ae283aee02 --- /dev/null +++ b/e2e/v8-coverage/empty-sourcemap/package.json @@ -0,0 +1,7 @@ +{ + "name": "empty-sourcemap", + "version": "1.0.0", + "jest": { + "testEnvironment": "node" + } +} diff --git a/e2e/v8-coverage/empty-sourcemap/test.ts b/e2e/v8-coverage/empty-sourcemap/test.ts new file mode 100644 index 000000000000..00dcc1c84eea --- /dev/null +++ b/e2e/v8-coverage/empty-sourcemap/test.ts @@ -0,0 +1,5 @@ +import * as types from './types'; + +test('dummy-test', () => { + expect(types).toEqual({default: {}}); +}); diff --git a/e2e/v8-coverage/empty-sourcemap/types.ts b/e2e/v8-coverage/empty-sourcemap/types.ts new file mode 100644 index 000000000000..59ed75ba3197 --- /dev/null +++ b/e2e/v8-coverage/empty-sourcemap/types.ts @@ -0,0 +1,2 @@ +export interface obj {} + diff --git a/packages/jest-reporters/src/CoverageReporter.ts b/packages/jest-reporters/src/CoverageReporter.ts index c10511911034..73687e1f77b5 100644 --- a/packages/jest-reporters/src/CoverageReporter.ts +++ b/packages/jest-reporters/src/CoverageReporter.ts @@ -37,7 +37,7 @@ import type { // This is fixed in a newer versions of source-map, but our dependencies are still stuck on old versions interface FixedRawSourceMap extends Omit { version: number; - file: string; + file?: string; } const FAIL_COLOR = chalk.bold.red; @@ -442,8 +442,7 @@ export default class CoverageReporter extends BaseReporter { let sourcemapContent: FixedRawSourceMap | undefined = undefined; if ( - fileTransform && - fileTransform.sourceMapPath && + fileTransform?.sourceMapPath && fs.existsSync(fileTransform.sourceMapPath) ) { sourcemapContent = JSON.parse( @@ -458,7 +457,9 @@ export default class CoverageReporter extends BaseReporter { ? { originalSource: fileTransform.originalCode, source: fileTransform.code, - sourceMap: {sourcemap: sourcemapContent}, + sourceMap: { + sourcemap: {file: res.url, ...sourcemapContent}, + }, } : {source: fs.readFileSync(res.url, 'utf8')}, );