Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Error Cannot read property converageData of null #7758 #8168

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -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

Expand Down
@@ -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 [
Expand All @@ -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,
},
},
Expand All @@ -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,
},
},
Expand All @@ -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,
},
},
Expand Down
133 changes: 98 additions & 35 deletions packages/jest-reporters/src/__tests__/generateEmptyCoverage.test.js
Expand Up @@ -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';
Expand All @@ -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();
});
});
16 changes: 9 additions & 7 deletions packages/jest-reporters/src/generateEmptyCoverage.ts
Expand Up @@ -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;
}