diff --git a/CHANGELOG.md b/CHANGELOG.md index 1173fdfe4ff2..43ccd59c4691 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ - `[jest-runtime]` Allow json file as manual mock ([#8159](https://github.com/facebook/jest/pull/8159)) - `[pretty-format]` Print `BigInt` as a readable number instead of `{}` ([#8138](https://github.com/facebook/jest/pull/8138)) - `[jest-core]` Fix ability to transform dependencies required from globalSetup script [#8143](https://github.com/facebook/jest/pull/8143) +- `[@jest/reporters]` Fix Cannot read property converageData of null ([#8168](https://github.com/facebook/jest/pull/8168)) ### Chore & Maintenance diff --git a/packages/jest-reporters/src/__tests__/__snapshots__/generateEmptyCoverage.test.js.snap b/packages/jest-reporters/src/__tests__/__snapshots__/generateEmptyCoverage.test.js.snap index efa311c86a6e..ede240cf808b 100644 --- a/packages/jest-reporters/src/__tests__/__snapshots__/generateEmptyCoverage.test.js.snap +++ b/packages/jest-reporters/src/__tests__/__snapshots__/generateEmptyCoverage.test.js.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`generates an empty coverage object for a file without running it 1`] = ` +exports[`generateEmptyCoverage generates an empty coverage object for a file without running it 1`] = ` Object { "b": Object { "0": Array [ @@ -13,32 +13,32 @@ Object { "line": 5, "loc": Object { "end": Object { - "column": 3, + "column": 7, "line": 9, }, "start": Object { - "column": 2, + "column": 6, "line": 5, }, }, "locations": Array [ Object { "end": Object { - "column": 3, + "column": 7, "line": 9, }, "start": Object { - "column": 2, + "column": 6, "line": 5, }, }, Object { "end": Object { - "column": 3, + "column": 7, "line": 9, }, "start": Object { - "column": 2, + "column": 6, "line": 5, }, }, @@ -53,22 +53,22 @@ Object { "0": Object { "decl": Object { "end": Object { - "column": 11, + "column": 15, "line": 4, }, "start": Object { - "column": 10, + "column": 14, "line": 4, }, }, "line": 4, "loc": Object { "end": Object { - "column": 1, + "column": 5, "line": 10, }, "start": Object { - "column": 20, + "column": 24, "line": 4, }, }, @@ -87,61 +87,61 @@ Object { "statementMap": Object { "0": Object { "end": Object { - "column": 45, + "column": 49, "line": 2, }, "start": Object { - "column": 0, + "column": 4, "line": 2, }, }, "1": Object { "end": Object { - "column": 1, + "column": 5, "line": 10, }, "start": Object { - "column": 10, + "column": 14, "line": 4, }, }, "2": Object { "end": Object { - "column": 3, + "column": 7, "line": 9, }, "start": Object { - "column": 2, + "column": 6, "line": 5, }, }, "3": Object { "end": Object { - "column": 13, + "column": 17, "line": 6, }, "start": Object { - "column": 4, + "column": 8, "line": 6, }, }, "4": Object { "end": Object { - "column": 13, + "column": 17, "line": 8, }, "start": Object { - "column": 4, + "column": 8, "line": 8, }, }, "5": Object { "end": Object { - "column": 2, + "column": 6, "line": 14, }, "start": Object { - "column": 0, + "column": 4, "line": 12, }, }, diff --git a/packages/jest-reporters/src/__tests__/generateEmptyCoverage.test.js b/packages/jest-reporters/src/__tests__/generateEmptyCoverage.test.js index 678913cab672..8fa2ae4fe1bc 100644 --- a/packages/jest-reporters/src/__tests__/generateEmptyCoverage.test.js +++ b/packages/jest-reporters/src/__tests__/generateEmptyCoverage.test.js @@ -5,6 +5,7 @@ * LICENSE file in the root directory of this source tree. */ +import {shouldInstrument} from '@jest/transform'; import istanbulCoverage from 'istanbul-lib-coverage'; import libSourceMaps from 'istanbul-lib-source-maps'; import generateEmptyCoverage from '../generateEmptyCoverage'; @@ -15,51 +16,113 @@ import {makeGlobalConfig, makeProjectConfig} from '../../../../TestUtils'; jest.mock('@jest/transform', () => ({ ...jest.requireActual('@jest/transform'), - shouldInstrument: () => true, + shouldInstrument: jest.fn(), })); -const src = ` -throw new Error('this should not be thrown'); - -const a = (b, c) => { - if (b) { - return c; - } else { - return b; - } -}; - -module.exports = { - a, -};`; - -it('generates an empty coverage object for a file without running it', () => { +describe('generateEmptyCoverage', () => { const coverageMap = istanbulCoverage.createCoverageMap({}); const sourceMapStore = libSourceMaps.createSourceMapStore(); const rootDir = '/tmp'; const filepath = path.join(rootDir, './sum.js'); - const emptyCoverage = generateEmptyCoverage( - src, - filepath, - makeGlobalConfig(), - makeProjectConfig({ - cacheDirectory: os.tmpdir(), - rootDir, - transform: [['^.+\\.js$', require.resolve('babel-jest')]], - }), - ); + it('generates an empty coverage object for a file without running it', () => { + const src = ` + throw new Error('this should not be thrown'); + + const a = (b, c) => { + if (b) { + return c; + } else { + return b; + } + }; + + module.exports = { + a, + };`; + + shouldInstrument.mockReturnValueOnce(true); + + const emptyCoverage = generateEmptyCoverage( + src, + filepath, + makeGlobalConfig(), + makeProjectConfig({ + cacheDirectory: os.tmpdir(), + rootDir, + transform: [['^.+\\.js$', require.resolve('babel-jest')]], + }), + ); + + expect(emptyCoverage).not.toBeNull(); + expect(typeof emptyCoverage).toBe('object'); + + let coverage = emptyCoverage.coverage; + + if (emptyCoverage.sourceMapPath) { + coverageMap.addFileCoverage(emptyCoverage.coverage); + sourceMapStore.registerURL(filepath, emptyCoverage.sourceMapPath); + + coverage = sourceMapStore.transformCoverage(coverageMap).map; + } + + expect(coverage.data).toMatchSnapshot({path: expect.any(String)}); + }); + + it('generates a null coverage result when using /* istanbul ignore file */', () => { + const src = ` + /* istanbul ignore file */ + const a = (b, c) => { + if (b) { + return c; + } else { + return b; + } + }; + module.exports = { a }; + `; + + shouldInstrument.mockReturnValueOnce(true); + + const nullCoverage = generateEmptyCoverage( + src, + filepath, + makeGlobalConfig(), + makeProjectConfig({ + cacheDirectory: os.tmpdir(), + rootDir, + transform: [['^.+\\.js$', require.resolve('babel-jest')]], + }), + ); - expect(typeof emptyCoverage).toBe('object'); + expect(nullCoverage).toBeNull(); + }); - let coverage = emptyCoverage && emptyCoverage.coverage; + it('generates a null coverage result when collectCoverage global config is false', () => { + const src = ` + const a = (b, c) => { + if (b) { + return c; + } else { + return b; + } + }; + module.exports = { a }; + `; - if (emptyCoverage && emptyCoverage.sourceMapPath) { - coverageMap.addFileCoverage(emptyCoverage.coverage); - sourceMapStore.registerURL(filepath, emptyCoverage.sourceMapPath); + shouldInstrument.mockReturnValueOnce(false); - coverage = sourceMapStore.transformCoverage(coverageMap).map; - } + const nullCoverage = generateEmptyCoverage( + src, + filepath, + makeGlobalConfig(), + makeProjectConfig({ + cacheDirectory: os.tmpdir(), + rootDir, + transform: [['^.+\\.js$', require.resolve('babel-jest')]], + }), + ); - expect(coverage.data).toMatchSnapshot({path: expect.any(String)}); + expect(nullCoverage).toBeNull(); + }); }); diff --git a/packages/jest-reporters/src/generateEmptyCoverage.ts b/packages/jest-reporters/src/generateEmptyCoverage.ts index 59e87304dfe3..763bb119f42d 100644 --- a/packages/jest-reporters/src/generateEmptyCoverage.ts +++ b/packages/jest-reporters/src/generateEmptyCoverage.ts @@ -33,18 +33,20 @@ export default function( collectCoverageFrom: globalConfig.collectCoverageFrom, collectCoverageOnlyFrom: globalConfig.collectCoverageOnlyFrom, }; + let coverageWorkerResult: CoverageWorkerResult | null = null; if (shouldInstrument(filename, coverageOptions, config)) { // Transform file with instrumentation to make sure initial coverage data is well mapped to original code. const {code, mapCoverage, sourceMapPath} = new ScriptTransformer( config, ).transformSource(filename, source, true); const extracted = readInitialCoverage(code); - - return { - coverage: new FileCoverage(extracted.coverageData), - sourceMapPath: mapCoverage ? sourceMapPath : null, - }; - } else { - return null; + // Check extracted initial coverage is not null, this can happen when using /* istanbul ignore file */ + if (extracted) { + coverageWorkerResult = { + coverage: new FileCoverage(extracted.coverageData), + sourceMapPath: mapCoverage ? sourceMapPath : null, + }; + } } + return coverageWorkerResult; }