Skip to content

Commit

Permalink
Incorrect empty file coverage (#7388)
Browse files Browse the repository at this point in the history
  • Loading branch information
mengdage authored and SimenB committed Dec 24, 2018
1 parent 1dd4949 commit f7f65bf
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 13 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@

### Fixes

- `[jest-cli]` Fix empty coverage data for untested files ([#7388](https://github.com/facebook/jest/pull/7388))
- `[jest-cli]` [**BREAKING**] Do not use `text-summary` coverage reporter by default if other reporters are configured ([#7058](https://github.com/facebook/jest/pull/7058))
- `[jest-mock]` [**BREAKING**] Fix bugs with mock/spy result tracking of recursive functions ([#6381](https://github.com/facebook/jest/pull/6381))
- `[jest-haste-map]` [**BREAKING**] Recover files correctly after haste name collisions are fixed ([#7329](https://github.com/facebook/jest/pull/7329))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ Object {
"name": "(anonymous_0)",
},
},
"path": "/sum.js",
"path": "/tmp/sum.js",
"s": Object {
"0": 0,
"1": 0,
Expand Down
27 changes: 24 additions & 3 deletions packages/jest-cli/src/__tests__/generateEmptyCoverage.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,12 @@
*/
'use strict';

import istanbulCoverage from 'istanbul-lib-coverage';
import libSourceMaps from 'istanbul-lib-source-maps';
import generateEmptyCoverage from '../generateEmptyCoverage';
import Runtime from 'jest-runtime';

const path = require('path');
const os = require('os');
const {makeGlobalConfig, makeProjectConfig} = require('../../../../TestUtils');

Expand All @@ -32,14 +35,32 @@ module.exports = {
};`;

it('generates an empty coverage object for a file without running it', () => {
const coverageMap = istanbulCoverage.createCoverageMap({});
const sourceMapStore = libSourceMaps.createSourceMapStore();
const rootDir = '/tmp';
const filepath = path.join(rootDir, './sum.js');

const emptyCoverage = generateEmptyCoverage(
src,
'/sum.js',
filepath,
makeGlobalConfig(),
makeProjectConfig({
cacheDirectory: os.tmpdir(),
rootDir: os.tmpdir(),
rootDir,
transform: [['^.+\\.js$', require.resolve('babel-jest')]],
}),
);
expect(emptyCoverage && emptyCoverage.coverage).toMatchSnapshot();

expect(typeof emptyCoverage).toBe('object');

let coverage = emptyCoverage && emptyCoverage.coverage;

if (emptyCoverage && emptyCoverage.sourceMapPath) {
coverageMap.addFileCoverage(emptyCoverage.coverage);
sourceMapStore.registerURL(filepath, emptyCoverage.sourceMapPath);

coverage = sourceMapStore.transformCoverage(coverageMap).map;
}

expect(coverage).toMatchSnapshot();
});
20 changes: 11 additions & 9 deletions packages/jest-cli/src/generateEmptyCoverage.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,17 @@

import type {GlobalConfig, ProjectConfig, Path} from 'types/Config';

import {createInstrumenter} from 'istanbul-lib-instrument';
import {readInitialCoverage} from 'istanbul-lib-instrument';
import {classes} from 'istanbul-lib-coverage';
import Runtime from 'jest-runtime';

export type CoverageWorkerResult = {|
coverage: any,
sourceMapPath: ?string,
|};

const {FileCoverage} = classes;

export default function(
source: string,
filename: Path,
Expand All @@ -29,16 +32,15 @@ export default function(
collectCoverageOnlyFrom: globalConfig.collectCoverageOnlyFrom,
};
if (Runtime.shouldInstrument(filename, coverageOptions, config)) {
// Transform file without instrumentation first, to make sure produced
// source code is ES6 (no flowtypes etc.) and can be instrumented
const transformResult = new Runtime.ScriptTransformer(
// Transform file with instrumentation to make sure initial coverage data is well mapped to original code.
const {code, mapCoverage, sourceMapPath} = new Runtime.ScriptTransformer(
config,
).transformSource(filename, source, false);
const instrumenter = createInstrumenter();
instrumenter.instrumentSync(transformResult.code, filename);
).transformSource(filename, source, true);
const extracted = readInitialCoverage(code);

return {
coverage: instrumenter.fileCoverage,
sourceMapPath: transformResult.sourceMapPath,
coverage: new FileCoverage(extracted.coverageData),
sourceMapPath: mapCoverage ? sourceMapPath : null,
};
} else {
return null;
Expand Down

0 comments on commit f7f65bf

Please sign in to comment.