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

#5067 Add forceCoverageRegex configuration option #5081

Merged
merged 1 commit into from
Dec 18, 2017
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
## master

None
* `[jest-config]` Add `forceCoverageMatch` to allow collecting coverage from
ignored files. ([#5081](https://github.com/facebook/jest/pull/5081))

## jest 22.0.0

Expand Down
35 changes: 35 additions & 0 deletions docs/Configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,41 @@ Jest will fail if:
* The `./src/api/very-important-module.js` file has less than 100% coverage.
* Every remaining file combined has less than 50% coverage (`global`).

### `forceCoverageMatch` [array<string>]

Default: `['']`

Test files are normally ignored from collecting code coverage. With this option,
you can overwrite this behavior and include otherwise ignored files in code coverage.

For example, if you have tests in source files named with `.t.js` extension as
following:

```javascript
// sum.t.js

export function sum(a,b) {
return a + b;
}

if (process.env.NODE_ENV === 'test') {
test('sum', () => {
expect(sum(1, 2)).toBe(3);
});
}
```

You can collect coverage from those files with setting `forceCoverageMatch`.
```json
{
...
"jest": {
"forceCoverageMatch": ["**/*.t.js"]
}
}
```


### `globals` [object]

Default: `{}`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ exports[`--showConfig outputs config info and exits 1`] = `
\\"/node_modules/\\"
],
\\"detectLeaks\\": false,
\\"forceCoverageMatch\\": [],
\\"globals\\": {},
\\"haste\\": {
\\"providesModuleNodeModules\\": []
Expand Down
1 change: 1 addition & 0 deletions packages/jest-config/src/defaults.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ export default ({
coverageReporters: ['json', 'text', 'lcov', 'clover'],
detectLeaks: false,
expand: false,
forceCoverageMatch: [],
globalSetup: null,
globalTeardown: null,
globals: {},
Expand Down
1 change: 1 addition & 0 deletions packages/jest-config/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ const getConfigs = (
cwd: options.cwd,
detectLeaks: options.detectLeaks,
displayName: options.displayName,
forceCoverageMatch: options.forceCoverageMatch,
globals: options.globals,
haste: options.haste,
moduleDirectories: options.moduleDirectories,
Expand Down
1 change: 1 addition & 0 deletions packages/jest-config/src/normalize.js
Original file line number Diff line number Diff line change
Expand Up @@ -459,6 +459,7 @@ export default function normalize(options: InitialOptions, argv: Argv) {
case 'expand':
case 'globals':
case 'findRelatedTests':
case 'forceCoverageMatch':
case 'forceExit':
case 'listTests':
case 'logHeapUsage':
Expand Down
1 change: 1 addition & 0 deletions packages/jest-config/src/valid_config.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ export default ({
},
displayName: 'project-name',
expand: false,
forceCoverageMatch: ['**/*.t.js'],
forceExit: false,
globalSetup: 'setup.js',
globalTeardown: 'teardown.js',
Expand Down
151 changes: 151 additions & 0 deletions packages/jest-runtime/src/__tests__/should_instrument.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
/**
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/

import shouldInstrument from '../should_instrument';

describe('should_instrument', () => {
const defaultFilename = 'source_file.test.js';
const defaultOptions = {
collectCoverage: true,
};
const defaultConfig = {
rootDir: '/',
};

describe('should return true', () => {
const testShouldInstrument = (
filename = defaultFilename,
options = defaultOptions,
config = defaultConfig,
) => {
const result = shouldInstrument(filename, options, config);
expect(result).toBe(true);
};

it('when testRegex provided and file is not a test file', () => {
testShouldInstrument('source_file.js', defaultOptions, {
testRegex: '.*\\.(test)\\.(js)$',
});
});

it('when testMatch is provided and file is not a test file', () => {
testShouldInstrument('source_file.js', defaultOptions, {
testMatch: ['**/?(*.)(test).js'],
});
});

it('should return true when file is in collectCoverageOnlyFrom when provided', () => {
testShouldInstrument(
'collect/only/from/here.js',

{
collectCoverage: true,
collectCoverageOnlyFrom: {'collect/only/from/here.js': true},
},
defaultConfig,
);
});

it('should return true when filename matches collectCoverageFrom', () => {
testShouldInstrument(
'do/collect/coverage.js',
{
collectCoverage: true,
collectCoverageFrom: ['!**/dont/**/*.js', '**/do/**/*.js'],
},
defaultConfig,
);
});

it('should return true if the file is not in coveragePathIgnorePatterns', () => {
testShouldInstrument('do/collect/coverage.js', defaultOptions, {
coveragePathIgnorePatterns: ['dont'],
rootDir: '/',
});
});

it('should return true if file is a testfile but forceCoverageMatch is set', () => {
testShouldInstrument('do/collect/sum.coverage.test.js', defaultOptions, {
forceCoverageMatch: ['**/*.(coverage).(test).js'],
rootDir: '/',
testRegex: '.*\\.(test)\\.(js)$',
});
});
});

describe('should return false', () => {
const testShouldInstrument = (
filename = defaultFilename,
options = defaultOptions,
config = defaultConfig,
) => {
const result = shouldInstrument(filename, options, config);
expect(result).toBe(false);
};

it('if collectCoverage is falsy', () => {
testShouldInstrument(
'source_file.js',
{
collectCoverage: false,
},
defaultConfig,
);
});

it('when testRegex provided and filename is a test file', () => {
testShouldInstrument(defaultFilename, defaultOptions, {
testRegex: '.*\\.(test)\\.(js)$',
});
});

it('when testMatch is provided and file is a test file', () => {
testShouldInstrument(defaultFilename, defaultOptions, {
testMatch: ['**/?(*.)(test).js'],
});
});

it('when file is not in collectCoverageOnlyFrom when provided', () => {
testShouldInstrument(
'source_file.js',
{
collectCoverage: true,
collectCoverageOnlyFrom: {'collect/only/from/here.js': true},
},
defaultConfig,
);
});

it('when filename does not match collectCoverageFrom', () => {
testShouldInstrument(
'dont/collect/coverage.js',
{
collectCoverage: true,
collectCoverageFrom: ['!**/dont/**/*.js', '**/do/**/*.js'],
},
defaultConfig,
);
});

it('if the file is in coveragePathIgnorePatterns', () => {
testShouldInstrument('dont/collect/coverage.js', defaultOptions, {
coveragePathIgnorePatterns: ['dont'],
rootDir: '/',
});
});

it('if file is in mock patterns', () => {
const filename =
process.platform === 'win32'
? 'dont\\__mocks__\\collect\\coverage.js'
: 'dont/__mocks__/collect/coverage.js';

testShouldInstrument(filename, defaultOptions, defaultConfig);
});
});
});
8 changes: 8 additions & 0 deletions packages/jest-runtime/src/should_instrument.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,14 @@ export default function shouldInstrument(
return false;
}

if (
config.forceCoverageMatch &&
config.forceCoverageMatch.length &&
micromatch.any(filename, config.forceCoverageMatch)
) {
return true;
}

if (config.testRegex && filename.match(config.testRegex)) {
return false;
}
Expand Down
1 change: 1 addition & 0 deletions test_utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ const DEFAULT_PROJECT_CONFIG: ProjectConfig = {
cwd: '/test_root_dir/',
detectLeaks: false,
displayName: undefined,
forceCoverageMatch: [],
globals: {},
haste: {
providesModuleNodeModules: [],
Expand Down
3 changes: 3 additions & 0 deletions types/Config.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export type DefaultOptions = {|
coveragePathIgnorePatterns: Array<string>,
coverageReporters: Array<string>,
expand: boolean,
forceCoverageMatch: Array<Glob>,
globals: ConfigGlobals,
globalSetup: ?string,
globalTeardown: ?string,
Expand Down Expand Up @@ -86,6 +87,7 @@ export type InitialOptions = {
displayName?: string,
expand?: boolean,
findRelatedTests?: boolean,
forceCoverageMatch?: Array<Glob>,
forceExit?: boolean,
json?: boolean,
globals?: ConfigGlobals,
Expand Down Expand Up @@ -212,6 +214,7 @@ export type ProjectConfig = {|
cwd: Path,
detectLeaks: boolean,
displayName: ?string,
forceCoverageMatch: Array<Glob>,
globals: ConfigGlobals,
haste: HasteConfig,
moduleDirectories: Array<string>,
Expand Down