From b45fd588249265c3ad811ed70b062fa23cfb81fd Mon Sep 17 00:00:00 2001 From: Stian Didriksen Date: Sun, 18 Feb 2018 00:03:55 +0100 Subject: [PATCH 01/25] Jump start using the work from #4246 --- .../generate_coverage_for_files.test.js.snap | 54 ++++++++++++++ .../generate_coverage_for_files.test.js | 71 +++++++++++++++++++ .../snapshot/__tests__/snapshot.test_copy.js | 42 +++++++++++ .../error-thrown-before-snapshot.test.js.snap | 7 ++ .../error-thrown-before-snapshot.test.js | 4 ++ packages/jest-cli/src/cli/args.js | 6 ++ packages/jest-config/src/normalize.js | 15 ++++ types/Argv.js | 1 + 8 files changed, 200 insertions(+) create mode 100644 integration-tests/__tests__/__snapshots__/generate_coverage_for_files.test.js.snap create mode 100644 integration-tests/__tests__/generate_coverage_for_files.test.js create mode 100644 integration-tests/snapshot/__tests__/snapshot.test_copy.js create mode 100644 integration-tests/toMatchSnapshot/__tests__/__snapshots__/error-thrown-before-snapshot.test.js.snap create mode 100644 integration-tests/toMatchSnapshot/__tests__/error-thrown-before-snapshot.test.js diff --git a/integration-tests/__tests__/__snapshots__/generate_coverage_for_files.test.js.snap b/integration-tests/__tests__/__snapshots__/generate_coverage_for_files.test.js.snap new file mode 100644 index 000000000000..7b5a049d36a2 --- /dev/null +++ b/integration-tests/__tests__/__snapshots__/generate_coverage_for_files.test.js.snap @@ -0,0 +1,54 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`--generateCoverageForFiles 1`] = ` +"Test Suites: 2 passed, 2 total +Tests: 2 passed, 2 total +Snapshots: 0 total +Time: <> +Ran all test suites. +" +`; + +exports[`--generateCoverageForFiles 2`] = ` +" + +PASS __tests__/a.test.js +PASS __tests__/b.test.js" +`; + +exports[`--generateCoverageForFiles 3`] = ` +"----------|----------|----------|----------|----------|----------------| +File | % Stmts | % Branch | % Funcs | % Lines |Uncovered Lines | +----------|----------|----------|----------|----------|----------------| +All files | 100 | 100 | 100 | 100 | | + a.js | 100 | 100 | 100 | 100 | | + b.js | 100 | 100 | 100 | 100 | | +----------|----------|----------|----------|----------|----------------| +" +`; + +exports[`--generateCoverageForFiles 4`] = ` +"Test Suites: 1 passed, 1 total +Tests: 1 passed, 1 total +Snapshots: 0 total +Time: <> +Ran all test suites related to files matching /a.js/i. +" +`; + +exports[`--generateCoverageForFiles 5`] = ` +"PASS __tests__/a.test.js + ✓ a + +" +`; + +exports[`--generateCoverageForFiles 6`] = ` +"----------|----------|----------|----------|----------|----------------| +File | % Stmts | % Branch | % Funcs | % Lines |Uncovered Lines | +----------|----------|----------|----------|----------|----------------| +All files | 100 | 100 | 100 | 100 | | + a.js | 100 | 100 | 100 | 100 | | +----------|----------|----------|----------|----------|----------------| +" +`; diff --git a/integration-tests/__tests__/generate_coverage_for_files.test.js b/integration-tests/__tests__/generate_coverage_for_files.test.js new file mode 100644 index 000000000000..b126efa99960 --- /dev/null +++ b/integration-tests/__tests__/generate_coverage_for_files.test.js @@ -0,0 +1,71 @@ +/** + * Copyright (c) 2014-present, Facebook, Inc. All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @flow + */ + +'use strict'; + +const path = require('path'); +const os = require('os'); +const SkipOnWindows = require('../../scripts/SkipOnWindows'); +const {cleanup, writeFiles, extractSummary} = require('../utils'); +const runJest = require('../runJest'); + +const DIR = path.resolve(os.tmpdir(), 'generate_coverage_for_files_test'); + +SkipOnWindows.suite(); + +beforeEach(() => cleanup(DIR)); +afterAll(() => cleanup(DIR)); + +test('--generateCoverageForFiles', () => { + writeFiles(DIR, { + '.watchmanconfig': '', + '__tests__/a.test.js': ` + require('../a'); + require('../b'); + test('a', () => expect(1).toBe(1)); + `, + '__tests__/b.test.js': ` + require('../b'); + test('b', () => expect(1).toBe(1)); + `, + 'a.js': 'module.exports = {}', + 'b.js': 'module.exports = {}', + 'package.json': JSON.stringify({jest: {testEnvironment: 'node'}}), + }); + + let stdout; + let stderr; + + ({stdout, stderr} = runJest(DIR, ['--coverage'])); + let summary; + let rest; + ({summary, rest} = extractSummary(stderr)); + expect(summary).toMatchSnapshot(); + expect( + rest + .split('\n') + .map(s => s.trim()) + .sort() + .join('\n'), + ).toMatchSnapshot(); + + // both a.js and b.js should be in the coverage + expect(stdout).toMatchSnapshot(); + + ({stdout, stderr} = runJest(DIR, ['--generateCoverageForFiles', 'a.js'])); + + ({summary, rest} = extractSummary(stderr)); + + expect(summary).toMatchSnapshot(); + // should only run a.js + expect(rest).toMatchSnapshot(); + // coverage should be collected only for a.js + expect(stdout).toMatchSnapshot(); +}); diff --git a/integration-tests/snapshot/__tests__/snapshot.test_copy.js b/integration-tests/snapshot/__tests__/snapshot.test_copy.js new file mode 100644 index 000000000000..b5293518b9d9 --- /dev/null +++ b/integration-tests/snapshot/__tests__/snapshot.test_copy.js @@ -0,0 +1,42 @@ +/** + * 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. + * + * @emails oncall+jsinfra + */ +'use strict'; + +describe('snapshot', () => { + it('works with plain objects and the title has `escape` characters', () => { + const test = { + a: 1, + b: '2', + c: 'three`', + }; + expect(test).toMatchSnapshot(); + test.d = '4'; + expect(test).toMatchSnapshot(); + }); + + it('is not influenced by previous counter', () => { + const test = { + a: 43, + b: '43', + c: 'fourtythree', + }; + expect(test).toMatchSnapshot(); + }); + + it('cannot be used with .not', () => { + expect(() => expect('').not.toMatchSnapshot()).toThrow( + 'Jest: `.not` cannot be used with `.toMatchSnapshot()`.' + ); + }); + + // Issue reported here: https://github.com/facebook/jest/issues/2969 + it('works with \\r\\n', () => { + expect('
\r\n
').toMatchSnapshot(); + }); +}); diff --git a/integration-tests/toMatchSnapshot/__tests__/__snapshots__/error-thrown-before-snapshot.test.js.snap b/integration-tests/toMatchSnapshot/__tests__/__snapshots__/error-thrown-before-snapshot.test.js.snap new file mode 100644 index 000000000000..51819108bc97 --- /dev/null +++ b/integration-tests/toMatchSnapshot/__tests__/__snapshots__/error-thrown-before-snapshot.test.js.snap @@ -0,0 +1,7 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`snapshots 1`] = ` +Object { + "a": "original", +} +`; diff --git a/integration-tests/toMatchSnapshot/__tests__/error-thrown-before-snapshot.test.js b/integration-tests/toMatchSnapshot/__tests__/error-thrown-before-snapshot.test.js new file mode 100644 index 000000000000..e6950f2e859c --- /dev/null +++ b/integration-tests/toMatchSnapshot/__tests__/error-thrown-before-snapshot.test.js @@ -0,0 +1,4 @@ +test('snapshots', () => { + expect(false).toBeTruthy(); + expect({a: "original"}).toMatchSnapshot(); + }); \ No newline at end of file diff --git a/packages/jest-cli/src/cli/args.js b/packages/jest-cli/src/cli/args.js index 41f3ce44e0c4..0655fabb637b 100644 --- a/packages/jest-cli/src/cli/args.js +++ b/packages/jest-cli/src/cli/args.js @@ -254,6 +254,12 @@ export const options = { 'adequately cleaned up.', type: 'boolean', }, + generateCoverageForFiles: { + description: + 'Run related tests for a list of source files that were passed in as ' + + 'arguments and collect coverage for them', + type: 'boolean', + }, globalSetup: { description: 'The path to a module that runs before All Tests.', type: 'string', diff --git a/packages/jest-config/src/normalize.js b/packages/jest-config/src/normalize.js index 7e0827c67fc2..0666c4e3f11c 100644 --- a/packages/jest-config/src/normalize.js +++ b/packages/jest-config/src/normalize.js @@ -599,6 +599,21 @@ export default function normalize(options: InitialOptions, argv: Argv) { ); } + // generateCoverageForFiles is an alias for + // `--findRelatedTests '/rootDir/file1.js' --coverage --collectCoverageFrom 'file1.js'` + // where arguments to `--collectCoverageFrom` should be globs (or relative + // paths to the rootDir) + if (argv.generateCoverageForFiles) { + newOptions.findRelatedTests = true; + newOptions.collectCoverage = true; + newOptions.collectCoverageFrom = argv._.map(filename => { + filename = _replaceRootDirInPath(options.rootDir, filename); + return path.isAbsolute(filename) + ? path.relative(options.rootDir, filename) + : filename; + }); + } + return { hasDeprecationWarnings, options: newOptions, diff --git a/types/Argv.js b/types/Argv.js index 71b3388b123f..ace53ec33387 100644 --- a/types/Argv.js +++ b/types/Argv.js @@ -34,6 +34,7 @@ export type Argv = {| expand: boolean, findRelatedTests: boolean, forceExit: boolean, + generateCoverageForFiles: boolean, globalSetup: ?string, globalTeardown: ?string, globals: string, From 0a3990384a7e1691a6c5db703be5c78d442d1246 Mon Sep 17 00:00:00 2001 From: Stian Didriksen Date: Sun, 18 Feb 2018 00:22:50 +0100 Subject: [PATCH 02/25] checking how it looks without an extra flag --- .../__tests__/generate_coverage_for_files.test.js | 8 +++++--- packages/jest-config/src/normalize.js | 10 +++++----- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/integration-tests/__tests__/generate_coverage_for_files.test.js b/integration-tests/__tests__/generate_coverage_for_files.test.js index b126efa99960..ce0bd9621f01 100644 --- a/integration-tests/__tests__/generate_coverage_for_files.test.js +++ b/integration-tests/__tests__/generate_coverage_for_files.test.js @@ -37,13 +37,15 @@ test('--generateCoverageForFiles', () => { `, 'a.js': 'module.exports = {}', 'b.js': 'module.exports = {}', - 'package.json': JSON.stringify({jest: {testEnvironment: 'node'}}), + 'package.json': JSON.stringify({ + jest: {collectCoverage: true, testEnvironment: 'node'}, + }), }); let stdout; let stderr; - ({stdout, stderr} = runJest(DIR, ['--coverage'])); + ({stdout, stderr} = runJest(DIR)); let summary; let rest; ({summary, rest} = extractSummary(stderr)); @@ -59,7 +61,7 @@ test('--generateCoverageForFiles', () => { // both a.js and b.js should be in the coverage expect(stdout).toMatchSnapshot(); - ({stdout, stderr} = runJest(DIR, ['--generateCoverageForFiles', 'a.js'])); + ({stdout, stderr} = runJest(DIR, ['--findRelatedTests', 'a.js'])); ({summary, rest} = extractSummary(stderr)); diff --git a/packages/jest-config/src/normalize.js b/packages/jest-config/src/normalize.js index 0666c4e3f11c..01681e9f7b86 100644 --- a/packages/jest-config/src/normalize.js +++ b/packages/jest-config/src/normalize.js @@ -599,13 +599,13 @@ export default function normalize(options: InitialOptions, argv: Argv) { ); } - // generateCoverageForFiles is an alias for - // `--findRelatedTests '/rootDir/file1.js' --coverage --collectCoverageFrom 'file1.js'` + // If collectCoverage is enabled while using --findRelatedTests we need to + // avoid having false negatives in the generated coverage report. + // The following: `--findRelatedTests '/rootDir/file1.js' --coverage` + // Is transformed to: `--findRelatedTests '/rootDir/file1.js' --coverage --collectCoverageFrom 'file1.js'` // where arguments to `--collectCoverageFrom` should be globs (or relative // paths to the rootDir) - if (argv.generateCoverageForFiles) { - newOptions.findRelatedTests = true; - newOptions.collectCoverage = true; + if (newOptions.collectCoverage && argv.findRelatedTests) { newOptions.collectCoverageFrom = argv._.map(filename => { filename = _replaceRootDirInPath(options.rootDir, filename); return path.isAbsolute(filename) From 055177ceb75439fe8079a6b5719aa779fbee3b7c Mon Sep 17 00:00:00 2001 From: Stian Didriksen Date: Sun, 18 Feb 2018 00:49:08 +0100 Subject: [PATCH 03/25] makes more sense to colocate the test here --- ...s.snap => find_related_files.test.js.snap} | 12 +-- .../__tests__/find_related_files.test.js | 77 +++++++++++++++---- .../generate_coverage_for_files.test.js | 73 ------------------ packages/jest-config/src/normalize.js | 2 +- 4 files changed, 71 insertions(+), 93 deletions(-) rename integration-tests/__tests__/__snapshots__/{generate_coverage_for_files.test.js.snap => find_related_files.test.js.snap} (74%) delete mode 100644 integration-tests/__tests__/generate_coverage_for_files.test.js diff --git a/integration-tests/__tests__/__snapshots__/generate_coverage_for_files.test.js.snap b/integration-tests/__tests__/__snapshots__/find_related_files.test.js.snap similarity index 74% rename from integration-tests/__tests__/__snapshots__/generate_coverage_for_files.test.js.snap rename to integration-tests/__tests__/__snapshots__/find_related_files.test.js.snap index 7b5a049d36a2..8798eff0d548 100644 --- a/integration-tests/__tests__/__snapshots__/generate_coverage_for_files.test.js.snap +++ b/integration-tests/__tests__/__snapshots__/find_related_files.test.js.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`--generateCoverageForFiles 1`] = ` +exports[`--findRelatedTests flag generates coverage report for filename 1`] = ` "Test Suites: 2 passed, 2 total Tests: 2 passed, 2 total Snapshots: 0 total @@ -9,14 +9,14 @@ Ran all test suites. " `; -exports[`--generateCoverageForFiles 2`] = ` +exports[`--findRelatedTests flag generates coverage report for filename 2`] = ` " PASS __tests__/a.test.js PASS __tests__/b.test.js" `; -exports[`--generateCoverageForFiles 3`] = ` +exports[`--findRelatedTests flag generates coverage report for filename 3`] = ` "----------|----------|----------|----------|----------|----------------| File | % Stmts | % Branch | % Funcs | % Lines |Uncovered Lines | ----------|----------|----------|----------|----------|----------------| @@ -27,7 +27,7 @@ All files | 100 | 100 | 100 | 100 | | " `; -exports[`--generateCoverageForFiles 4`] = ` +exports[`--findRelatedTests flag generates coverage report for filename 4`] = ` "Test Suites: 1 passed, 1 total Tests: 1 passed, 1 total Snapshots: 0 total @@ -36,14 +36,14 @@ Ran all test suites related to files matching /a.js/i. " `; -exports[`--generateCoverageForFiles 5`] = ` +exports[`--findRelatedTests flag generates coverage report for filename 5`] = ` "PASS __tests__/a.test.js ✓ a " `; -exports[`--generateCoverageForFiles 6`] = ` +exports[`--findRelatedTests flag generates coverage report for filename 6`] = ` "----------|----------|----------|----------|----------|----------------| File | % Stmts | % Branch | % Funcs | % Lines |Uncovered Lines | ----------|----------|----------|----------|----------|----------------| diff --git a/integration-tests/__tests__/find_related_files.test.js b/integration-tests/__tests__/find_related_files.test.js index 18a25d08ef86..ffa924d257ff 100644 --- a/integration-tests/__tests__/find_related_files.test.js +++ b/integration-tests/__tests__/find_related_files.test.js @@ -13,7 +13,7 @@ import runJest from '../runJest'; import os from 'os'; import path from 'path'; -const {cleanup, writeFiles} = require('../Utils'); +const {cleanup, writeFiles, extractSummary} = require('../Utils'); const SkipOnWindows = require('../../scripts/SkipOnWindows'); const DIR = path.resolve(os.tmpdir(), 'find_related_tests_test'); @@ -23,23 +23,74 @@ SkipOnWindows.suite(); beforeEach(() => cleanup(DIR)); afterEach(() => cleanup(DIR)); -test('runs tests related to filename', () => { - writeFiles(DIR, { - '.watchmanconfig': '', - '__tests__/test.test.js': ` +describe('--findRelatedTests flag', () => { + test('runs tests related to filename', () => { + writeFiles(DIR, { + '.watchmanconfig': '', + '__tests__/test.test.js': ` const a = require('../a'); test('a', () => {}); `, - 'a.js': 'module.exports = {};', - 'package.json': JSON.stringify({jest: {testEnvironment: 'node'}}), + 'a.js': 'module.exports = {};', + 'package.json': JSON.stringify({jest: {testEnvironment: 'node'}}), + }); + + const {stdout} = runJest(DIR, ['a.js']); + expect(stdout).toMatch(''); + + const {stderr} = runJest(DIR, ['--findRelatedTests', 'a.js']); + expect(stderr).toMatch('PASS __tests__/test.test.js'); + + const summaryMsg = 'Ran all test suites related to files matching /a.js/i.'; + expect(stderr).toMatch(summaryMsg); }); - const {stdout} = runJest(DIR, ['a.js']); - expect(stdout).toMatch(''); + test('generates coverage report for filename', () => { + writeFiles(DIR, { + '.watchmanconfig': '', + '__tests__/a.test.js': ` + require('../a'); + require('../b'); + test('a', () => expect(1).toBe(1)); + `, + '__tests__/b.test.js': ` + require('../b'); + test('b', () => expect(1).toBe(1)); + `, + 'a.js': 'module.exports = {}', + 'b.js': 'module.exports = {}', + 'package.json': JSON.stringify({ + jest: {collectCoverage: true, testEnvironment: 'node'}, + }), + }); + + let stdout; + let stderr; - const {stderr} = runJest(DIR, ['--findRelatedTests', 'a.js']); - expect(stderr).toMatch('PASS __tests__/test.test.js'); + ({stdout, stderr} = runJest(DIR)); + let summary; + let rest; + ({summary, rest} = extractSummary(stderr)); + expect(summary).toMatchSnapshot(); + expect( + rest + .split('\n') + .map(s => s.trim()) + .sort() + .join('\n'), + ).toMatchSnapshot(); - const summaryMsg = 'Ran all test suites related to files matching /a.js/i.'; - expect(stderr).toMatch(summaryMsg); + // both a.js and b.js should be in the coverage + expect(stdout).toMatchSnapshot(); + + ({stdout, stderr} = runJest(DIR, ['--findRelatedTests', 'a.js'])); + + ({summary, rest} = extractSummary(stderr)); + + expect(summary).toMatchSnapshot(); + // should only run a.js + expect(rest).toMatchSnapshot(); + // coverage should be collected only for a.js + expect(stdout).toMatchSnapshot(); + }); }); diff --git a/integration-tests/__tests__/generate_coverage_for_files.test.js b/integration-tests/__tests__/generate_coverage_for_files.test.js deleted file mode 100644 index ce0bd9621f01..000000000000 --- a/integration-tests/__tests__/generate_coverage_for_files.test.js +++ /dev/null @@ -1,73 +0,0 @@ -/** - * Copyright (c) 2014-present, Facebook, Inc. All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @flow - */ - -'use strict'; - -const path = require('path'); -const os = require('os'); -const SkipOnWindows = require('../../scripts/SkipOnWindows'); -const {cleanup, writeFiles, extractSummary} = require('../utils'); -const runJest = require('../runJest'); - -const DIR = path.resolve(os.tmpdir(), 'generate_coverage_for_files_test'); - -SkipOnWindows.suite(); - -beforeEach(() => cleanup(DIR)); -afterAll(() => cleanup(DIR)); - -test('--generateCoverageForFiles', () => { - writeFiles(DIR, { - '.watchmanconfig': '', - '__tests__/a.test.js': ` - require('../a'); - require('../b'); - test('a', () => expect(1).toBe(1)); - `, - '__tests__/b.test.js': ` - require('../b'); - test('b', () => expect(1).toBe(1)); - `, - 'a.js': 'module.exports = {}', - 'b.js': 'module.exports = {}', - 'package.json': JSON.stringify({ - jest: {collectCoverage: true, testEnvironment: 'node'}, - }), - }); - - let stdout; - let stderr; - - ({stdout, stderr} = runJest(DIR)); - let summary; - let rest; - ({summary, rest} = extractSummary(stderr)); - expect(summary).toMatchSnapshot(); - expect( - rest - .split('\n') - .map(s => s.trim()) - .sort() - .join('\n'), - ).toMatchSnapshot(); - - // both a.js and b.js should be in the coverage - expect(stdout).toMatchSnapshot(); - - ({stdout, stderr} = runJest(DIR, ['--findRelatedTests', 'a.js'])); - - ({summary, rest} = extractSummary(stderr)); - - expect(summary).toMatchSnapshot(); - // should only run a.js - expect(rest).toMatchSnapshot(); - // coverage should be collected only for a.js - expect(stdout).toMatchSnapshot(); -}); diff --git a/packages/jest-config/src/normalize.js b/packages/jest-config/src/normalize.js index 01681e9f7b86..c53628be20d4 100644 --- a/packages/jest-config/src/normalize.js +++ b/packages/jest-config/src/normalize.js @@ -605,7 +605,7 @@ export default function normalize(options: InitialOptions, argv: Argv) { // Is transformed to: `--findRelatedTests '/rootDir/file1.js' --coverage --collectCoverageFrom 'file1.js'` // where arguments to `--collectCoverageFrom` should be globs (or relative // paths to the rootDir) - if (newOptions.collectCoverage && argv.findRelatedTests) { + if (newOptions.collectCoverage && newOptions.findRelatedTests) { newOptions.collectCoverageFrom = argv._.map(filename => { filename = _replaceRootDirInPath(options.rootDir, filename); return path.isAbsolute(filename) From e1472a3aa7bb855e8aa02d03f3ccef978f6a6073 Mon Sep 17 00:00:00 2001 From: Stian Didriksen Date: Sun, 18 Feb 2018 00:50:24 +0100 Subject: [PATCH 04/25] remove mystery files --- .../snapshot/__tests__/snapshot.test_copy.js | 42 ------------------- .../error-thrown-before-snapshot.test.js.snap | 7 ---- .../error-thrown-before-snapshot.test.js | 4 -- 3 files changed, 53 deletions(-) delete mode 100644 integration-tests/snapshot/__tests__/snapshot.test_copy.js delete mode 100644 integration-tests/toMatchSnapshot/__tests__/__snapshots__/error-thrown-before-snapshot.test.js.snap delete mode 100644 integration-tests/toMatchSnapshot/__tests__/error-thrown-before-snapshot.test.js diff --git a/integration-tests/snapshot/__tests__/snapshot.test_copy.js b/integration-tests/snapshot/__tests__/snapshot.test_copy.js deleted file mode 100644 index b5293518b9d9..000000000000 --- a/integration-tests/snapshot/__tests__/snapshot.test_copy.js +++ /dev/null @@ -1,42 +0,0 @@ -/** - * 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. - * - * @emails oncall+jsinfra - */ -'use strict'; - -describe('snapshot', () => { - it('works with plain objects and the title has `escape` characters', () => { - const test = { - a: 1, - b: '2', - c: 'three`', - }; - expect(test).toMatchSnapshot(); - test.d = '4'; - expect(test).toMatchSnapshot(); - }); - - it('is not influenced by previous counter', () => { - const test = { - a: 43, - b: '43', - c: 'fourtythree', - }; - expect(test).toMatchSnapshot(); - }); - - it('cannot be used with .not', () => { - expect(() => expect('').not.toMatchSnapshot()).toThrow( - 'Jest: `.not` cannot be used with `.toMatchSnapshot()`.' - ); - }); - - // Issue reported here: https://github.com/facebook/jest/issues/2969 - it('works with \\r\\n', () => { - expect('
\r\n
').toMatchSnapshot(); - }); -}); diff --git a/integration-tests/toMatchSnapshot/__tests__/__snapshots__/error-thrown-before-snapshot.test.js.snap b/integration-tests/toMatchSnapshot/__tests__/__snapshots__/error-thrown-before-snapshot.test.js.snap deleted file mode 100644 index 51819108bc97..000000000000 --- a/integration-tests/toMatchSnapshot/__tests__/__snapshots__/error-thrown-before-snapshot.test.js.snap +++ /dev/null @@ -1,7 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`snapshots 1`] = ` -Object { - "a": "original", -} -`; diff --git a/integration-tests/toMatchSnapshot/__tests__/error-thrown-before-snapshot.test.js b/integration-tests/toMatchSnapshot/__tests__/error-thrown-before-snapshot.test.js deleted file mode 100644 index e6950f2e859c..000000000000 --- a/integration-tests/toMatchSnapshot/__tests__/error-thrown-before-snapshot.test.js +++ /dev/null @@ -1,4 +0,0 @@ -test('snapshots', () => { - expect(false).toBeTruthy(); - expect({a: "original"}).toMatchSnapshot(); - }); \ No newline at end of file From 8f073bc11e3db35551124a0637c2d26d3dfc0787 Mon Sep 17 00:00:00 2001 From: Stian Didriksen Date: Sun, 18 Feb 2018 00:51:31 +0100 Subject: [PATCH 05/25] remove references to the flag --- packages/jest-cli/src/cli/args.js | 6 ------ types/Argv.js | 1 - 2 files changed, 7 deletions(-) diff --git a/packages/jest-cli/src/cli/args.js b/packages/jest-cli/src/cli/args.js index 0655fabb637b..41f3ce44e0c4 100644 --- a/packages/jest-cli/src/cli/args.js +++ b/packages/jest-cli/src/cli/args.js @@ -254,12 +254,6 @@ export const options = { 'adequately cleaned up.', type: 'boolean', }, - generateCoverageForFiles: { - description: - 'Run related tests for a list of source files that were passed in as ' + - 'arguments and collect coverage for them', - type: 'boolean', - }, globalSetup: { description: 'The path to a module that runs before All Tests.', type: 'string', diff --git a/types/Argv.js b/types/Argv.js index ace53ec33387..71b3388b123f 100644 --- a/types/Argv.js +++ b/types/Argv.js @@ -34,7 +34,6 @@ export type Argv = {| expand: boolean, findRelatedTests: boolean, forceExit: boolean, - generateCoverageForFiles: boolean, globalSetup: ?string, globalTeardown: ?string, globals: string, From 61937f5ae97cea30d05c8b09d787e7f3b5fe240a Mon Sep 17 00:00:00 2001 From: Stian Didriksen Date: Sun, 18 Feb 2018 01:10:16 +0100 Subject: [PATCH 06/25] update docs --- docs/CLI.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/CLI.md b/docs/CLI.md index ad98e977b092..e30350ad48c2 100644 --- a/docs/CLI.md +++ b/docs/CLI.md @@ -189,7 +189,9 @@ Alias: `-e`. Use this flag to show full diffs and errors instead of a patch. Find and run the tests that cover a space separated list of source files that were passed in as arguments. Useful for pre-commit hook integration to run the -minimal amount of tests necessary. +minimal amount of tests necessary. Can be used together with `--coverage` to +include a test coverage for the source files, no duplicate +`--collectCoverageFrom` arguments needed. ### `--forceExit` From b2532103047d39e42e139a061b9eadcf7ce82a5e Mon Sep 17 00:00:00 2001 From: Stian Didriksen Date: Sun, 18 Feb 2018 01:34:20 +0100 Subject: [PATCH 07/25] add test case for --onlyChanged and --coverage --- .../__snapshots__/only_changed.test.js.snap | 55 +++++++++++++++++ .../__tests__/only_changed.test.js | 60 ++++++++++++++++++- 2 files changed, 114 insertions(+), 1 deletion(-) create mode 100644 integration-tests/__tests__/__snapshots__/only_changed.test.js.snap diff --git a/integration-tests/__tests__/__snapshots__/only_changed.test.js.snap b/integration-tests/__tests__/__snapshots__/only_changed.test.js.snap new file mode 100644 index 000000000000..79d2f2297b3b --- /dev/null +++ b/integration-tests/__tests__/__snapshots__/only_changed.test.js.snap @@ -0,0 +1,55 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`report test coverage for only changed files 1`] = ` +"Test Suites: 2 passed, 2 total +Tests: 2 passed, 2 total +Snapshots: 0 total +Time: <> +Ran all test suites. +" +`; + +exports[`report test coverage for only changed files 2`] = ` +" + +PASS __tests__/a.test.js +PASS __tests__/b.test.js" +`; + +exports[`report test coverage for only changed files 3`] = ` +"----------|----------|----------|----------|----------|----------------| +File | % Stmts | % Branch | % Funcs | % Lines |Uncovered Lines | +----------|----------|----------|----------|----------|----------------| +All files | 100 | 100 | 100 | 100 | | + a.js | 100 | 100 | 100 | 100 | | + b.js | 100 | 100 | 100 | 100 | | +----------|----------|----------|----------|----------|----------------| +" +`; + +exports[`report test coverage for only changed files 4`] = ` +"Test Suites: 1 passed, 1 total +Tests: 1 passed, 1 total +Snapshots: 0 total +Time: <> +Ran all test suites related to changed files. +" +`; + +exports[`report test coverage for only changed files 5`] = ` +"PASS __tests__/a.test.js + ✓ a + +" +`; + +exports[`report test coverage for only changed files 6`] = ` +"----------|----------|----------|----------|----------|----------------| +File | % Stmts | % Branch | % Funcs | % Lines |Uncovered Lines | +----------|----------|----------|----------|----------|----------------| +All files | 100 | 100 | 100 | 100 | | + a.js | 100 | 100 | 100 | 100 | | + b.js | 100 | 100 | 100 | 100 | | +----------|----------|----------|----------|----------|----------------| +" +`; diff --git a/integration-tests/__tests__/only_changed.test.js b/integration-tests/__tests__/only_changed.test.js index 16ff3e633b7a..da0fc0337d71 100644 --- a/integration-tests/__tests__/only_changed.test.js +++ b/integration-tests/__tests__/only_changed.test.js @@ -12,7 +12,7 @@ import runJest from '../runJest'; import os from 'os'; import path from 'path'; -const {cleanup, run, writeFiles} = require('../Utils'); +const {cleanup, run, writeFiles, extractSummary} = require('../Utils'); const DIR = path.resolve(os.tmpdir(), 'jest_only_changed'); const GIT = 'git -c user.name=jest_test -c user.email=jest_test@test.com'; @@ -73,6 +73,64 @@ test('run only changed files', () => { expect(stderr).toMatch(/PASS __tests__(\/|\\)file3.test.js/); }); +test('report test coverage for only changed files', () => { + writeFiles(DIR, { + '__tests__/a.test.js': ` + require('../a'); + require('../b'); + test('a', () => expect(1).toBe(1)); + `, + '__tests__/b.test.js': ` + require('../b'); + test('b', () => expect(1).toBe(1)); + `, + 'a.js': 'module.exports = {}', + 'b.js': 'module.exports = {}', + 'package.json': JSON.stringify({ + jest: {collectCoverage: true, testEnvironment: 'node'}, + }), + }); + + run(`${GIT} init`, DIR); + run(`${GIT} add .`, DIR); + run(`${GIT} commit -m "first"`, DIR); + + writeFiles(DIR, { + 'a.js': 'module.exports = {modified: true}', + }); + + let stdout; + let stderr; + + ({stdout, stderr} = runJest(DIR)); + let summary; + let rest; + ({summary, rest} = extractSummary(stderr)); + expect(summary).toMatchSnapshot(); + expect( + rest + .split('\n') + .map(s => s.trim()) + .sort() + .join('\n'), + ).toMatchSnapshot(); + + // both a.js and b.js should be in the coverage + expect(stdout).toMatchSnapshot(); + + ({stdout, stderr} = runJest(DIR, ['-o'])); + + ({summary, rest} = extractSummary(stderr)); + + expect(summary).toMatchSnapshot(); + // should only run a.js + expect(rest).toMatchSnapshot(); + // coverage should be collected only for a.js + expect(stdout).toMatchSnapshot(); + // coverage for b.js should not be in the report + expect(stdout).not.toMatch('b.js'); +}); + test('onlyChanged in config is overwritten by --all or testPathPattern', () => { writeFiles(DIR, { '.watchmanconfig': '', From 812e46fe85757d62dd1ce8fbdd11a64ab6f3a3bc Mon Sep 17 00:00:00 2001 From: Stian Didriksen Date: Sun, 18 Feb 2018 01:45:53 +0100 Subject: [PATCH 08/25] update snapshot to what it should be --- .../__tests__/__snapshots__/only_changed.test.js.snap | 1 - 1 file changed, 1 deletion(-) diff --git a/integration-tests/__tests__/__snapshots__/only_changed.test.js.snap b/integration-tests/__tests__/__snapshots__/only_changed.test.js.snap index 79d2f2297b3b..b49a4c427579 100644 --- a/integration-tests/__tests__/__snapshots__/only_changed.test.js.snap +++ b/integration-tests/__tests__/__snapshots__/only_changed.test.js.snap @@ -49,7 +49,6 @@ File | % Stmts | % Branch | % Funcs | % Lines |Uncovered Lines | ----------|----------|----------|----------|----------|----------------| All files | 100 | 100 | 100 | 100 | | a.js | 100 | 100 | 100 | 100 | | - b.js | 100 | 100 | 100 | 100 | | ----------|----------|----------|----------|----------|----------------| " `; From 5b82b3469f8941d78cc0868c4f50e236c2d7d1ac Mon Sep 17 00:00:00 2001 From: Stian Didriksen Date: Sun, 18 Feb 2018 04:01:36 +0100 Subject: [PATCH 09/25] apply collectCoverageFrom patterns after finding tests --- packages/jest-cli/src/run_jest.js | 37 +++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/packages/jest-cli/src/run_jest.js b/packages/jest-cli/src/run_jest.js index 8a3df9a0900d..a99e689ef975 100644 --- a/packages/jest-cli/src/run_jest.js +++ b/packages/jest-cli/src/run_jest.js @@ -13,6 +13,7 @@ import type {GlobalConfig} from 'types/Config'; import type {AggregatedResult} from 'types/TestResult'; import type TestWatcher from './test_watcher'; +import micromatch from 'micromatch'; import chalk from 'chalk'; import path from 'path'; import {Console, formatTestResults} from 'jest-util'; @@ -131,6 +132,8 @@ export default (async function runJest({ } } + let collectCoverageFrom = []; + const testRunData = await Promise.all( contexts.map(async context => { const matches = await getTestPaths( @@ -141,10 +144,44 @@ export default (async function runJest({ jestHooks, ); allTests = allTests.concat(matches.tests); + + if (matches.collectCoverageFrom) { + collectCoverageFrom = collectCoverageFrom.concat( + matches.collectCoverageFrom.filter(filename => { + if ( + globalConfig.collectCoverageFrom && + !micromatch( + [path.relative(globalConfig.rootDir, filename)], + globalConfig.collectCoverageFrom, + ).length + ) { + return false; + } + + if ( + globalConfig.coveragePathIgnorePatterns && + globalConfig.coveragePathIgnorePatterns.some(pattern => + filename.match(pattern), + ) + ) { + return false; + } + + return true; + }), + ); + } + return {context, matches}; }), ); + if (collectCoverageFrom.length) { + globalConfig = Object.freeze( + Object.assign({}, globalConfig, {collectCoverageFrom}), + ); + } + allTests = sequencer.sort(allTests); if (globalConfig.listTests) { From 139ed5a1164dd0e244ef793d32c4465d82a8bafb Mon Sep 17 00:00:00 2001 From: Stian Didriksen Date: Sun, 18 Feb 2018 04:04:03 +0100 Subject: [PATCH 10/25] Collect possible coverage patterns while searching for tests --- packages/jest-cli/src/search_source.js | 64 ++++++++++++++++++-------- 1 file changed, 46 insertions(+), 18 deletions(-) diff --git a/packages/jest-cli/src/search_source.js b/packages/jest-cli/src/search_source.js index 1b5c7e06039b..88632224c217 100644 --- a/packages/jest-cli/src/search_source.js +++ b/packages/jest-cli/src/search_source.js @@ -17,6 +17,7 @@ import micromatch from 'micromatch'; import DependencyResolver from 'jest-resolve-dependencies'; import testPathPatternToRegExp from './test_path_pattern_to_regexp'; import {escapePathForRegex} from 'jest-regex-util'; +import {_replaceRootDirInPath} from 'jest-config'; type SearchResult = {| noSCM?: boolean, @@ -140,23 +141,42 @@ export default class SearchSource { return this._getAllTestPaths(testPathPattern); } - findRelatedTests(allPaths: Set): SearchResult { + findRelatedTests( + allPaths: Set, + collectCoverage: boolean, + ): SearchResult { const dependencyResolver = new DependencyResolver( this._context.resolver, this._context.hasteFS, ); - return { - tests: toTests( - this._context, - dependencyResolver.resolveInverse( - allPaths, - this.isTestFilePath.bind(this), - { - skipNodeResolution: this._context.config.skipNodeResolution, - }, - ), + + const tests = toTests( + this._context, + dependencyResolver.resolveInverse( + allPaths, + this.isTestFilePath.bind(this), + { + skipNodeResolution: this._context.config.skipNodeResolution, + }, ), - }; + ); + + // If we are collecting coverage, also return collectCoverageFrom patterns + if (collectCoverage) { + const collectCoverageFrom = Array.from(allPaths).map(filename => { + filename = _replaceRootDirInPath( + this._context.config.rootDir, + filename, + ); + return path.isAbsolute(filename) + ? path.relative(this._context.config.rootDir, filename) + : filename; + }); + + return {collectCoverageFrom, tests}; + } + + return {tests}; } findTestsByPaths(paths: Array): SearchResult { @@ -170,24 +190,27 @@ export default class SearchSource { }; } - findRelatedTestsFromPattern(paths: Array): SearchResult { + findRelatedTestsFromPattern( + paths: Array, + collectCoverage: boolean, + ): SearchResult { if (Array.isArray(paths) && paths.length) { const resolvedPaths = paths.map(p => path.resolve(process.cwd(), p)); - return this.findRelatedTests(new Set(resolvedPaths)); + return this.findRelatedTests(new Set(resolvedPaths), collectCoverage); } return {tests: []}; } async findTestRelatedToChangedFiles( changedFilesPromise: ChangedFilesPromise, + collectCoverage: boolean, ) { const {repos, changedFiles} = await changedFilesPromise; - // no SCM (git/hg/...) is found in any of the roots. const noSCM = Object.keys(repos).every(scm => repos[scm].size === 0); return noSCM ? {noSCM: true, tests: []} - : this.findRelatedTests(changedFiles); + : this.findRelatedTests(changedFiles, collectCoverage); } async getTestPaths( @@ -200,11 +223,16 @@ export default class SearchSource { throw new Error('This promise must be present when running with -o.'); } - return this.findTestRelatedToChangedFiles(changedFilesPromise); + return this.findTestRelatedToChangedFiles( + changedFilesPromise, + globalConfig.collectCoverage, + ); } else if (globalConfig.runTestsByPath && paths && paths.length) { return Promise.resolve(this.findTestsByPaths(paths)); } else if (globalConfig.findRelatedTests && paths && paths.length) { - return Promise.resolve(this.findRelatedTestsFromPattern(paths)); + return Promise.resolve( + this.findRelatedTestsFromPattern(paths, globalConfig.collectCoverage), + ); } else if (globalConfig.testPathPattern != null) { return Promise.resolve( this.findMatchingTests(globalConfig.testPathPattern), From 63243a56bfcf626513ea250be4a9b7297f7ea6f8 Mon Sep 17 00:00:00 2001 From: Stian Didriksen Date: Sun, 18 Feb 2018 04:04:45 +0100 Subject: [PATCH 11/25] improve test results --- integration-tests/__tests__/only_changed.test.js | 6 +++++- packages/jest-config/src/index.js | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/integration-tests/__tests__/only_changed.test.js b/integration-tests/__tests__/only_changed.test.js index da0fc0337d71..fbb05e777df7 100644 --- a/integration-tests/__tests__/only_changed.test.js +++ b/integration-tests/__tests__/only_changed.test.js @@ -87,7 +87,11 @@ test('report test coverage for only changed files', () => { 'a.js': 'module.exports = {}', 'b.js': 'module.exports = {}', 'package.json': JSON.stringify({ - jest: {collectCoverage: true, testEnvironment: 'node'}, + jest: { + collectCoverage: true, + coverageReporters: ['text'], + testEnvironment: 'node', + }, }), }); diff --git a/packages/jest-config/src/index.js b/packages/jest-config/src/index.js index 62b469cc580c..4601ecf48d86 100644 --- a/packages/jest-config/src/index.js +++ b/packages/jest-config/src/index.js @@ -24,6 +24,7 @@ import readConfigFileAndSetRootDir from './read_config_file_and_set_root_dir'; export {getTestEnvironment, isJSONString} from './utils'; export {default as normalize} from './normalize'; export {default as deprecationEntries} from './deprecated'; +export {_replaceRootDirInPath} from './utils'; export function readConfig( argv: Argv, From a5891dbf243314b5e83a4409f18c49def3be43d3 Mon Sep 17 00:00:00 2001 From: Stian Didriksen Date: Sun, 18 Feb 2018 04:21:59 +0100 Subject: [PATCH 12/25] hi there flow --- packages/jest-cli/src/search_source.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/jest-cli/src/search_source.js b/packages/jest-cli/src/search_source.js index 88632224c217..37be70636fc3 100644 --- a/packages/jest-cli/src/search_source.js +++ b/packages/jest-cli/src/search_source.js @@ -22,6 +22,7 @@ import {_replaceRootDirInPath} from 'jest-config'; type SearchResult = {| noSCM?: boolean, stats?: {[key: string]: number}, + collectCoverageFrom?: Array, tests: Array, total?: number, |}; From a61c7dd911839fc8a452b5f7acfd13e56c5b68d8 Mon Sep 17 00:00:00 2001 From: Stian Didriksen Date: Sun, 18 Feb 2018 04:34:15 +0100 Subject: [PATCH 13/25] skip on windows --- integration-tests/__tests__/only_changed.test.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/integration-tests/__tests__/only_changed.test.js b/integration-tests/__tests__/only_changed.test.js index fbb05e777df7..f61cd1e0eaac 100644 --- a/integration-tests/__tests__/only_changed.test.js +++ b/integration-tests/__tests__/only_changed.test.js @@ -74,6 +74,11 @@ test('run only changed files', () => { }); test('report test coverage for only changed files', () => { + if (process.platform === 'win32') { + // This have snapshots with file paths that use directory separators that fail on windows + return; + } + writeFiles(DIR, { '__tests__/a.test.js': ` require('../a'); From 7556f024fe3753d56eccd6629f64923f01b93d82 Mon Sep 17 00:00:00 2001 From: Stian Didriksen Date: Sun, 18 Feb 2018 04:45:09 +0100 Subject: [PATCH 14/25] will the windows build pass this time? --- .../__snapshots__/only_changed.test.js.snap | 53 ++++++++ .../__tests__/only_changed.test.js | 113 +++++++++--------- 2 files changed, 110 insertions(+), 56 deletions(-) diff --git a/integration-tests/__tests__/__snapshots__/only_changed.test.js.snap b/integration-tests/__tests__/__snapshots__/only_changed.test.js.snap index b49a4c427579..3ec8fdc04edc 100644 --- a/integration-tests/__tests__/__snapshots__/only_changed.test.js.snap +++ b/integration-tests/__tests__/__snapshots__/only_changed.test.js.snap @@ -1,5 +1,58 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`--onlyChanged --coverage report test coverage for only changed files 1`] = ` +"Test Suites: 2 passed, 2 total +Tests: 2 passed, 2 total +Snapshots: 0 total +Time: <> +Ran all test suites. +" +`; + +exports[`--onlyChanged --coverage report test coverage for only changed files 2`] = ` +" + +PASS __tests__/a.test.js +PASS __tests__/b.test.js" +`; + +exports[`--onlyChanged --coverage report test coverage for only changed files 3`] = ` +"----------|----------|----------|----------|----------|----------------| +File | % Stmts | % Branch | % Funcs | % Lines |Uncovered Lines | +----------|----------|----------|----------|----------|----------------| +All files | 100 | 100 | 100 | 100 | | + a.js | 100 | 100 | 100 | 100 | | + b.js | 100 | 100 | 100 | 100 | | +----------|----------|----------|----------|----------|----------------| +" +`; + +exports[`--onlyChanged --coverage report test coverage for only changed files 4`] = ` +"Test Suites: 1 passed, 1 total +Tests: 1 passed, 1 total +Snapshots: 0 total +Time: <> +Ran all test suites related to changed files. +" +`; + +exports[`--onlyChanged --coverage report test coverage for only changed files 5`] = ` +"PASS __tests__/a.test.js + ✓ a + +" +`; + +exports[`--onlyChanged --coverage report test coverage for only changed files 6`] = ` +"----------|----------|----------|----------|----------|----------------| +File | % Stmts | % Branch | % Funcs | % Lines |Uncovered Lines | +----------|----------|----------|----------|----------|----------------| +All files | 100 | 100 | 100 | 100 | | + a.js | 100 | 100 | 100 | 100 | | +----------|----------|----------|----------|----------|----------------| +" +`; + exports[`report test coverage for only changed files 1`] = ` "Test Suites: 2 passed, 2 total Tests: 2 passed, 2 total diff --git a/integration-tests/__tests__/only_changed.test.js b/integration-tests/__tests__/only_changed.test.js index f61cd1e0eaac..d4d975efab96 100644 --- a/integration-tests/__tests__/only_changed.test.js +++ b/integration-tests/__tests__/only_changed.test.js @@ -13,6 +13,7 @@ import runJest from '../runJest'; import os from 'os'; import path from 'path'; const {cleanup, run, writeFiles, extractSummary} = require('../Utils'); +const SkipOnWindows = require('../../scripts/SkipOnWindows'); const DIR = path.resolve(os.tmpdir(), 'jest_only_changed'); const GIT = 'git -c user.name=jest_test -c user.email=jest_test@test.com'; @@ -73,71 +74,71 @@ test('run only changed files', () => { expect(stderr).toMatch(/PASS __tests__(\/|\\)file3.test.js/); }); -test('report test coverage for only changed files', () => { - if (process.platform === 'win32') { - // This have snapshots with file paths that use directory separators that fail on windows - return; - } +describe('--onlyChanged --coverage', () => { + // Is there a better way to do this? + SkipOnWindows.suite(); - writeFiles(DIR, { - '__tests__/a.test.js': ` + test('report test coverage for only changed files', () => { + writeFiles(DIR, { + '__tests__/a.test.js': ` require('../a'); require('../b'); test('a', () => expect(1).toBe(1)); `, - '__tests__/b.test.js': ` + '__tests__/b.test.js': ` require('../b'); test('b', () => expect(1).toBe(1)); `, - 'a.js': 'module.exports = {}', - 'b.js': 'module.exports = {}', - 'package.json': JSON.stringify({ - jest: { - collectCoverage: true, - coverageReporters: ['text'], - testEnvironment: 'node', - }, - }), - }); - - run(`${GIT} init`, DIR); - run(`${GIT} add .`, DIR); - run(`${GIT} commit -m "first"`, DIR); - - writeFiles(DIR, { - 'a.js': 'module.exports = {modified: true}', + 'a.js': 'module.exports = {}', + 'b.js': 'module.exports = {}', + 'package.json': JSON.stringify({ + jest: { + collectCoverage: true, + coverageReporters: ['text'], + testEnvironment: 'node', + }, + }), + }); + + run(`${GIT} init`, DIR); + run(`${GIT} add .`, DIR); + run(`${GIT} commit -m "first"`, DIR); + + writeFiles(DIR, { + 'a.js': 'module.exports = {modified: true}', + }); + + let stdout; + let stderr; + + ({stdout, stderr} = runJest(DIR)); + let summary; + let rest; + ({summary, rest} = extractSummary(stderr)); + expect(summary).toMatchSnapshot(); + expect( + rest + .split('\n') + .map(s => s.trim()) + .sort() + .join('\n'), + ).toMatchSnapshot(); + + // both a.js and b.js should be in the coverage + expect(stdout).toMatchSnapshot(); + + ({stdout, stderr} = runJest(DIR, ['-o'])); + + ({summary, rest} = extractSummary(stderr)); + + expect(summary).toMatchSnapshot(); + // should only run a.js + expect(rest).toMatchSnapshot(); + // coverage should be collected only for a.js + expect(stdout).toMatchSnapshot(); + // coverage for b.js should not be in the report + expect(stdout).not.toMatch('b.js'); }); - - let stdout; - let stderr; - - ({stdout, stderr} = runJest(DIR)); - let summary; - let rest; - ({summary, rest} = extractSummary(stderr)); - expect(summary).toMatchSnapshot(); - expect( - rest - .split('\n') - .map(s => s.trim()) - .sort() - .join('\n'), - ).toMatchSnapshot(); - - // both a.js and b.js should be in the coverage - expect(stdout).toMatchSnapshot(); - - ({stdout, stderr} = runJest(DIR, ['-o'])); - - ({summary, rest} = extractSummary(stderr)); - - expect(summary).toMatchSnapshot(); - // should only run a.js - expect(rest).toMatchSnapshot(); - // coverage should be collected only for a.js - expect(stdout).toMatchSnapshot(); - // coverage for b.js should not be in the report - expect(stdout).not.toMatch('b.js'); }); test('onlyChanged in config is overwritten by --all or testPathPattern', () => { From 644efaf313668d6b79a97e242623d81e15e1e9c7 Mon Sep 17 00:00:00 2001 From: Simen Bekkhus Date: Sun, 18 Feb 2018 10:10:32 +0100 Subject: [PATCH 15/25] fix test on windows --- integration-tests/Utils.js | 1 - .../__snapshots__/only_changed.test.js.snap | 55 +-------- .../__tests__/only_changed.test.js | 115 +++++++++--------- 3 files changed, 59 insertions(+), 112 deletions(-) diff --git a/integration-tests/Utils.js b/integration-tests/Utils.js index bad044ad6faf..899145fafe6b 100644 --- a/integration-tests/Utils.js +++ b/integration-tests/Utils.js @@ -166,7 +166,6 @@ const cleanupStackTrace = (output: string) => { module.exports = { cleanup, - cleanupStackTrace, copyDir, createEmptyPackage, extractSummary, diff --git a/integration-tests/__tests__/__snapshots__/only_changed.test.js.snap b/integration-tests/__tests__/__snapshots__/only_changed.test.js.snap index 3ec8fdc04edc..afcc2f123b48 100644 --- a/integration-tests/__tests__/__snapshots__/only_changed.test.js.snap +++ b/integration-tests/__tests__/__snapshots__/only_changed.test.js.snap @@ -1,58 +1,5 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`--onlyChanged --coverage report test coverage for only changed files 1`] = ` -"Test Suites: 2 passed, 2 total -Tests: 2 passed, 2 total -Snapshots: 0 total -Time: <> -Ran all test suites. -" -`; - -exports[`--onlyChanged --coverage report test coverage for only changed files 2`] = ` -" - -PASS __tests__/a.test.js -PASS __tests__/b.test.js" -`; - -exports[`--onlyChanged --coverage report test coverage for only changed files 3`] = ` -"----------|----------|----------|----------|----------|----------------| -File | % Stmts | % Branch | % Funcs | % Lines |Uncovered Lines | -----------|----------|----------|----------|----------|----------------| -All files | 100 | 100 | 100 | 100 | | - a.js | 100 | 100 | 100 | 100 | | - b.js | 100 | 100 | 100 | 100 | | -----------|----------|----------|----------|----------|----------------| -" -`; - -exports[`--onlyChanged --coverage report test coverage for only changed files 4`] = ` -"Test Suites: 1 passed, 1 total -Tests: 1 passed, 1 total -Snapshots: 0 total -Time: <> -Ran all test suites related to changed files. -" -`; - -exports[`--onlyChanged --coverage report test coverage for only changed files 5`] = ` -"PASS __tests__/a.test.js - ✓ a - -" -`; - -exports[`--onlyChanged --coverage report test coverage for only changed files 6`] = ` -"----------|----------|----------|----------|----------|----------------| -File | % Stmts | % Branch | % Funcs | % Lines |Uncovered Lines | -----------|----------|----------|----------|----------|----------------| -All files | 100 | 100 | 100 | 100 | | - a.js | 100 | 100 | 100 | 100 | | -----------|----------|----------|----------|----------|----------------| -" -`; - exports[`report test coverage for only changed files 1`] = ` "Test Suites: 2 passed, 2 total Tests: 2 passed, 2 total @@ -91,7 +38,7 @@ Ran all test suites related to changed files. exports[`report test coverage for only changed files 5`] = ` "PASS __tests__/a.test.js - ✓ a + √ a " `; diff --git a/integration-tests/__tests__/only_changed.test.js b/integration-tests/__tests__/only_changed.test.js index d4d975efab96..44cf4b340802 100644 --- a/integration-tests/__tests__/only_changed.test.js +++ b/integration-tests/__tests__/only_changed.test.js @@ -13,7 +13,6 @@ import runJest from '../runJest'; import os from 'os'; import path from 'path'; const {cleanup, run, writeFiles, extractSummary} = require('../Utils'); -const SkipOnWindows = require('../../scripts/SkipOnWindows'); const DIR = path.resolve(os.tmpdir(), 'jest_only_changed'); const GIT = 'git -c user.name=jest_test -c user.email=jest_test@test.com'; @@ -74,71 +73,73 @@ test('run only changed files', () => { expect(stderr).toMatch(/PASS __tests__(\/|\\)file3.test.js/); }); -describe('--onlyChanged --coverage', () => { - // Is there a better way to do this? - SkipOnWindows.suite(); +test('report test coverage for only changed files', () => { + const windowsSlashRegex = new RegExp(`__tests__\\${path.win32.sep}`, 'g'); - test('report test coverage for only changed files', () => { - writeFiles(DIR, { - '__tests__/a.test.js': ` + writeFiles(DIR, { + '__tests__/a.test.js': ` require('../a'); require('../b'); test('a', () => expect(1).toBe(1)); `, - '__tests__/b.test.js': ` + '__tests__/b.test.js': ` require('../b'); test('b', () => expect(1).toBe(1)); `, - 'a.js': 'module.exports = {}', - 'b.js': 'module.exports = {}', - 'package.json': JSON.stringify({ - jest: { - collectCoverage: true, - coverageReporters: ['text'], - testEnvironment: 'node', - }, - }), - }); - - run(`${GIT} init`, DIR); - run(`${GIT} add .`, DIR); - run(`${GIT} commit -m "first"`, DIR); - - writeFiles(DIR, { - 'a.js': 'module.exports = {modified: true}', - }); - - let stdout; - let stderr; - - ({stdout, stderr} = runJest(DIR)); - let summary; - let rest; - ({summary, rest} = extractSummary(stderr)); - expect(summary).toMatchSnapshot(); - expect( - rest - .split('\n') - .map(s => s.trim()) - .sort() - .join('\n'), - ).toMatchSnapshot(); - - // both a.js and b.js should be in the coverage - expect(stdout).toMatchSnapshot(); - - ({stdout, stderr} = runJest(DIR, ['-o'])); - - ({summary, rest} = extractSummary(stderr)); - - expect(summary).toMatchSnapshot(); - // should only run a.js - expect(rest).toMatchSnapshot(); - // coverage should be collected only for a.js - expect(stdout).toMatchSnapshot(); - // coverage for b.js should not be in the report - expect(stdout).not.toMatch('b.js'); + 'a.js': 'module.exports = {}', + 'b.js': 'module.exports = {}', + 'package.json': JSON.stringify({ + jest: { + collectCoverage: true, + coverageReporters: ['text'], + testEnvironment: 'node', + }, + }), + }); + + run(`${GIT} init`, DIR); + run(`${GIT} add .`, DIR); + run(`${GIT} commit -m "first"`, DIR); + + writeFiles(DIR, { + 'a.js': 'module.exports = {modified: true}', }); + + let stdout; + let stderr; + + ({stdout, stderr} = runJest(DIR)); + let summary; + let rest; + ({summary, rest} = extractSummary(stderr)); + expect(summary).toMatchSnapshot(); + expect( + rest + .split('\n') + .map(s => s.trim()) + .sort() + .join('\n') + .replace(windowsSlashRegex, '__tests__/'), + ).toMatchSnapshot(); + + // both a.js and b.js should be in the coverage + expect(stdout).toMatchSnapshot(); + + ({stdout, stderr} = runJest(DIR, ['-o'])); + + ({summary, rest} = extractSummary(stderr)); + + expect(summary).toMatchSnapshot(); + // should only run a.js + expect( + rest + .replace(windowsSlashRegex, '__tests__/') + .replace(new RegExp('✓', 'g'), '√'), + ).toMatchSnapshot(); + // coverage should be collected only for a.js + expect(stdout).toMatchSnapshot(); + // coverage for b.js should not be in the report + expect(stdout).not.toMatch('b.js'); }); test('onlyChanged in config is overwritten by --all or testPathPattern', () => { From 26b919b2647f1ed58159d18ada67003307a3cb72 Mon Sep 17 00:00:00 2001 From: Stian Didriksen Date: Sun, 18 Feb 2018 19:21:01 +0100 Subject: [PATCH 16/25] remove underscore as it's no longer a private api --- packages/jest-cli/src/search_source.js | 7 ++----- packages/jest-config/src/index.js | 2 +- packages/jest-config/src/normalize.js | 16 ++++++++-------- packages/jest-config/src/utils.js | 8 ++++---- 4 files changed, 15 insertions(+), 18 deletions(-) diff --git a/packages/jest-cli/src/search_source.js b/packages/jest-cli/src/search_source.js index 37be70636fc3..b7ab2b6332ae 100644 --- a/packages/jest-cli/src/search_source.js +++ b/packages/jest-cli/src/search_source.js @@ -17,7 +17,7 @@ import micromatch from 'micromatch'; import DependencyResolver from 'jest-resolve-dependencies'; import testPathPatternToRegExp from './test_path_pattern_to_regexp'; import {escapePathForRegex} from 'jest-regex-util'; -import {_replaceRootDirInPath} from 'jest-config'; +import {replaceRootDirInPath} from 'jest-config'; type SearchResult = {| noSCM?: boolean, @@ -165,10 +165,7 @@ export default class SearchSource { // If we are collecting coverage, also return collectCoverageFrom patterns if (collectCoverage) { const collectCoverageFrom = Array.from(allPaths).map(filename => { - filename = _replaceRootDirInPath( - this._context.config.rootDir, - filename, - ); + filename = replaceRootDirInPath(this._context.config.rootDir, filename); return path.isAbsolute(filename) ? path.relative(this._context.config.rootDir, filename) : filename; diff --git a/packages/jest-config/src/index.js b/packages/jest-config/src/index.js index 4601ecf48d86..88afaedfb6c4 100644 --- a/packages/jest-config/src/index.js +++ b/packages/jest-config/src/index.js @@ -24,7 +24,7 @@ import readConfigFileAndSetRootDir from './read_config_file_and_set_root_dir'; export {getTestEnvironment, isJSONString} from './utils'; export {default as normalize} from './normalize'; export {default as deprecationEntries} from './deprecated'; -export {_replaceRootDirInPath} from './utils'; +export {replaceRootDirInPath} from './utils'; export function readConfig( argv: Argv, diff --git a/packages/jest-config/src/normalize.js b/packages/jest-config/src/normalize.js index c53628be20d4..a58f39aee71a 100644 --- a/packages/jest-config/src/normalize.js +++ b/packages/jest-config/src/normalize.js @@ -23,7 +23,7 @@ import {replacePathSepForRegex} from 'jest-regex-util'; import { BULLET, DOCUMENTATION_NOTE, - _replaceRootDirInPath, + replaceRootDirInPath, _replaceRootDirTags, escapeGlobCharacters, getTestEnvironment, @@ -66,7 +66,7 @@ const setupPreset = ( optionsPreset: string, ): InitialOptions => { let preset; - const presetPath = _replaceRootDirInPath(options.rootDir, optionsPreset); + const presetPath = replaceRootDirInPath(options.rootDir, optionsPreset); const presetModule = Resolver.findNodeModule( presetPath.endsWith(JSON_EXTENSION) ? presetPath @@ -146,7 +146,7 @@ const normalizeCollectCoverageOnlyFrom = ( return collectCoverageOnlyFrom.reduce((map, filePath) => { filePath = path.resolve( options.rootDir, - _replaceRootDirInPath(options.rootDir, filePath), + replaceRootDirInPath(options.rootDir, filePath), ); map[filePath] = true; return map; @@ -271,7 +271,7 @@ const normalizeReporters = (options: InitialOptions, basedir) => { [reporterConfig, {}] : reporterConfig; - const reporterPath = _replaceRootDirInPath( + const reporterPath = replaceRootDirInPath( options.rootDir, normalizedReporterConfig[0], ); @@ -391,7 +391,7 @@ export default function normalize(options: InitialOptions, argv: Argv) { options[key].map(filePath => path.resolve( options.rootDir, - _replaceRootDirInPath(options.rootDir, filePath), + replaceRootDirInPath(options.rootDir, filePath), ), ); break; @@ -404,7 +404,7 @@ export default function normalize(options: InitialOptions, argv: Argv) { options[key] && path.resolve( options.rootDir, - _replaceRootDirInPath(options.rootDir, options[key]), + replaceRootDirInPath(options.rootDir, options[key]), ); break; case 'globalSetup': @@ -449,7 +449,7 @@ export default function normalize(options: InitialOptions, argv: Argv) { value.hasteImplModulePath = resolve( options.rootDir, 'haste.hasteImplModulePath', - _replaceRootDirInPath(options.rootDir, value.hasteImplModulePath), + replaceRootDirInPath(options.rootDir, value.hasteImplModulePath), ); } break; @@ -607,7 +607,7 @@ export default function normalize(options: InitialOptions, argv: Argv) { // paths to the rootDir) if (newOptions.collectCoverage && newOptions.findRelatedTests) { newOptions.collectCoverageFrom = argv._.map(filename => { - filename = _replaceRootDirInPath(options.rootDir, filename); + filename = replaceRootDirInPath(options.rootDir, filename); return path.isAbsolute(filename) ? path.relative(options.rootDir, filename) : filename; diff --git a/packages/jest-config/src/utils.js b/packages/jest-config/src/utils.js index 8831b25c0233..c85998edbfe4 100644 --- a/packages/jest-config/src/utils.js +++ b/packages/jest-config/src/utils.js @@ -30,7 +30,7 @@ const createValidationError = (message: string) => { export const resolve = (rootDir: string, key: string, filePath: Path) => { const module = Resolver.findNodeModule( - _replaceRootDirInPath(rootDir, filePath), + replaceRootDirInPath(rootDir, filePath), { basedir: rootDir, }, @@ -52,7 +52,7 @@ export const escapeGlobCharacters = (path: Path): Glob => { return path.replace(/([()*{}\[\]!?\\])/g, '\\$1'); }; -export const _replaceRootDirInPath = ( +export const replaceRootDirInPath = ( rootDir: string, filePath: Path, ): string => { @@ -91,7 +91,7 @@ export const _replaceRootDirTags = (rootDir: string, config: any) => { } return _replaceRootDirInObject(rootDir, config); case 'string': - return _replaceRootDirInPath(rootDir, config); + return replaceRootDirInPath(rootDir, config); } return config; }; @@ -105,7 +105,7 @@ export const _replaceRootDirTags = (rootDir: string, config: any) => { * 1. looks for relative to Jest. */ export const getTestEnvironment = (config: Object) => { - const env = _replaceRootDirInPath(config.rootDir, config.testEnvironment); + const env = replaceRootDirInPath(config.rootDir, config.testEnvironment); let module = Resolver.findNodeModule(`jest-environment-${env}`, { basedir: config.rootDir, }); From 1e46f07e3261e5891a8f68b525fc877623a07499 Mon Sep 17 00:00:00 2001 From: Stian Didriksen Date: Sun, 18 Feb 2018 19:23:07 +0100 Subject: [PATCH 17/25] polymorphing --- packages/jest-cli/src/search_source.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/packages/jest-cli/src/search_source.js b/packages/jest-cli/src/search_source.js index b7ab2b6332ae..e574c8e5fc48 100644 --- a/packages/jest-cli/src/search_source.js +++ b/packages/jest-cli/src/search_source.js @@ -161,20 +161,19 @@ export default class SearchSource { }, ), ); + let collectCoverageFrom; // If we are collecting coverage, also return collectCoverageFrom patterns if (collectCoverage) { - const collectCoverageFrom = Array.from(allPaths).map(filename => { + collectCoverageFrom = Array.from(allPaths).map(filename => { filename = replaceRootDirInPath(this._context.config.rootDir, filename); return path.isAbsolute(filename) ? path.relative(this._context.config.rootDir, filename) : filename; }); - - return {collectCoverageFrom, tests}; } - return {tests}; + return {collectCoverageFrom, tests}; } findTestsByPaths(paths: Array): SearchResult { From cddc4bd637351ff08008e67b3f7653779b4a37a4 Mon Sep 17 00:00:00 2001 From: Stian Didriksen Date: Sun, 18 Feb 2018 23:54:03 +0100 Subject: [PATCH 18/25] simplify test --- .../__snapshots__/only_changed.test.js.snap | 54 ------------------- .../__tests__/only_changed.test.js | 36 +++---------- 2 files changed, 6 insertions(+), 84 deletions(-) delete mode 100644 integration-tests/__tests__/__snapshots__/only_changed.test.js.snap diff --git a/integration-tests/__tests__/__snapshots__/only_changed.test.js.snap b/integration-tests/__tests__/__snapshots__/only_changed.test.js.snap deleted file mode 100644 index afcc2f123b48..000000000000 --- a/integration-tests/__tests__/__snapshots__/only_changed.test.js.snap +++ /dev/null @@ -1,54 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`report test coverage for only changed files 1`] = ` -"Test Suites: 2 passed, 2 total -Tests: 2 passed, 2 total -Snapshots: 0 total -Time: <> -Ran all test suites. -" -`; - -exports[`report test coverage for only changed files 2`] = ` -" - -PASS __tests__/a.test.js -PASS __tests__/b.test.js" -`; - -exports[`report test coverage for only changed files 3`] = ` -"----------|----------|----------|----------|----------|----------------| -File | % Stmts | % Branch | % Funcs | % Lines |Uncovered Lines | -----------|----------|----------|----------|----------|----------------| -All files | 100 | 100 | 100 | 100 | | - a.js | 100 | 100 | 100 | 100 | | - b.js | 100 | 100 | 100 | 100 | | -----------|----------|----------|----------|----------|----------------| -" -`; - -exports[`report test coverage for only changed files 4`] = ` -"Test Suites: 1 passed, 1 total -Tests: 1 passed, 1 total -Snapshots: 0 total -Time: <> -Ran all test suites related to changed files. -" -`; - -exports[`report test coverage for only changed files 5`] = ` -"PASS __tests__/a.test.js - √ a - -" -`; - -exports[`report test coverage for only changed files 6`] = ` -"----------|----------|----------|----------|----------|----------------| -File | % Stmts | % Branch | % Funcs | % Lines |Uncovered Lines | -----------|----------|----------|----------|----------|----------------| -All files | 100 | 100 | 100 | 100 | | - a.js | 100 | 100 | 100 | 100 | | -----------|----------|----------|----------|----------|----------------| -" -`; diff --git a/integration-tests/__tests__/only_changed.test.js b/integration-tests/__tests__/only_changed.test.js index 44cf4b340802..ed51ea3bd13a 100644 --- a/integration-tests/__tests__/only_changed.test.js +++ b/integration-tests/__tests__/only_changed.test.js @@ -12,7 +12,7 @@ import runJest from '../runJest'; import os from 'os'; import path from 'path'; -const {cleanup, run, writeFiles, extractSummary} = require('../Utils'); +const {cleanup, run, writeFiles} = require('../Utils'); const DIR = path.resolve(os.tmpdir(), 'jest_only_changed'); const GIT = 'git -c user.name=jest_test -c user.email=jest_test@test.com'; @@ -74,8 +74,6 @@ test('run only changed files', () => { }); test('report test coverage for only changed files', () => { - const windowsSlashRegex = new RegExp(`__tests__\\${path.win32.sep}`, 'g'); - writeFiles(DIR, { '__tests__/a.test.js': ` require('../a'); @@ -106,39 +104,17 @@ test('report test coverage for only changed files', () => { }); let stdout; - let stderr; - ({stdout, stderr} = runJest(DIR)); - let summary; - let rest; - ({summary, rest} = extractSummary(stderr)); - expect(summary).toMatchSnapshot(); - expect( - rest - .split('\n') - .map(s => s.trim()) - .sort() - .join('\n') - .replace(windowsSlashRegex, '__tests__/'), - ).toMatchSnapshot(); + ({stdout} = runJest(DIR)); // both a.js and b.js should be in the coverage - expect(stdout).toMatchSnapshot(); + expect(stdout).toMatch('a.js'); + expect(stdout).toMatch('b.js'); - ({stdout, stderr} = runJest(DIR, ['-o'])); - - ({summary, rest} = extractSummary(stderr)); + ({stdout} = runJest(DIR, ['-o'])); - expect(summary).toMatchSnapshot(); - // should only run a.js - expect( - rest - .replace(windowsSlashRegex, '__tests__/') - .replace(new RegExp('✓', 'g'), '√'), - ).toMatchSnapshot(); // coverage should be collected only for a.js - expect(stdout).toMatchSnapshot(); - // coverage for b.js should not be in the report + expect(stdout).toMatch('a.js'); expect(stdout).not.toMatch('b.js'); }); From 1b8e4bea6e45486e23aa03730c2d1b954711e04d Mon Sep 17 00:00:00 2001 From: Stian Didriksen Date: Thu, 22 Feb 2018 22:20:10 +0100 Subject: [PATCH 19/25] increase test coverage in jest-config/normalize --- .../src/__tests__/normalize.test.js | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/packages/jest-config/src/__tests__/normalize.test.js b/packages/jest-config/src/__tests__/normalize.test.js index 0eeb2fed1791..581a5b2be99c 100644 --- a/packages/jest-config/src/__tests__/normalize.test.js +++ b/packages/jest-config/src/__tests__/normalize.test.js @@ -211,6 +211,31 @@ describe('collectCoverageFrom', () => { }); }); +describe('findRelatedTests', () => { + it('it generates --coverageCoverageFrom patterns when needed', () => { + const sourceFile = 'file1.js'; + + const {options} = normalize( + { + collectCoverage: true, + rootDir: '/root/path/foo/', + }, + { + findRelatedTests: true, + _: [ + `/root/path/${sourceFile}`, + sourceFile, + `/bar/${sourceFile}`, + ], + }, + ); + + const expected = [`../${sourceFile}`, `${sourceFile}`, `bar/${sourceFile}`]; + + expect(options.collectCoverageFrom).toEqual(expected); + }); +}); + function testPathArray(key) { it('normalizes all paths relative to rootDir', () => { const {options} = normalize( From 0cbaf3a41dfed3b1d2777c5f6cb31e3305c6ade2 Mon Sep 17 00:00:00 2001 From: Stian Didriksen Date: Thu, 22 Feb 2018 22:23:44 +0100 Subject: [PATCH 20/25] make the linter happy again --- packages/jest-config/src/__tests__/normalize.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/jest-config/src/__tests__/normalize.test.js b/packages/jest-config/src/__tests__/normalize.test.js index 581a5b2be99c..94003c410899 100644 --- a/packages/jest-config/src/__tests__/normalize.test.js +++ b/packages/jest-config/src/__tests__/normalize.test.js @@ -221,12 +221,12 @@ describe('findRelatedTests', () => { rootDir: '/root/path/foo/', }, { - findRelatedTests: true, _: [ `/root/path/${sourceFile}`, sourceFile, `/bar/${sourceFile}`, ], + findRelatedTests: true, }, ); From 0e234b6b32d37a0d0dfc52a285c7cb37a57f071f Mon Sep 17 00:00:00 2001 From: Stian Didriksen Date: Thu, 22 Feb 2018 22:42:30 +0100 Subject: [PATCH 21/25] should use argv as it's not a config option --- packages/jest-config/src/normalize.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/jest-config/src/normalize.js b/packages/jest-config/src/normalize.js index a58f39aee71a..b53185643f3f 100644 --- a/packages/jest-config/src/normalize.js +++ b/packages/jest-config/src/normalize.js @@ -605,7 +605,7 @@ export default function normalize(options: InitialOptions, argv: Argv) { // Is transformed to: `--findRelatedTests '/rootDir/file1.js' --coverage --collectCoverageFrom 'file1.js'` // where arguments to `--collectCoverageFrom` should be globs (or relative // paths to the rootDir) - if (newOptions.collectCoverage && newOptions.findRelatedTests) { + if (newOptions.collectCoverage && argv.findRelatedTests) { newOptions.collectCoverageFrom = argv._.map(filename => { filename = replaceRootDirInPath(options.rootDir, filename); return path.isAbsolute(filename) From 35f367bcafc78f69a07229b0415a90a17b3fcb1b Mon Sep 17 00:00:00 2001 From: Stian Didriksen Date: Sun, 18 Mar 2018 01:43:02 +0100 Subject: [PATCH 22/25] test coverage for run_jest --- .../__tests__/run_jest_with_coverage.test.js | 109 ++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 packages/jest-cli/src/__tests__/run_jest_with_coverage.test.js diff --git a/packages/jest-cli/src/__tests__/run_jest_with_coverage.test.js b/packages/jest-cli/src/__tests__/run_jest_with_coverage.test.js new file mode 100644 index 000000000000..a529fa94f4fb --- /dev/null +++ b/packages/jest-cli/src/__tests__/run_jest_with_coverage.test.js @@ -0,0 +1,109 @@ +import runJest from '../run_jest'; + +jest.mock('jest-util'); + +jest.mock( + '../test_scheduler', + () => + class { + constructor(globalConfig) { + this._globalConfig = globalConfig; + } + + scheduleTests() { + return {_globalConfig: this._globalConfig}; + } + }, +); + +jest.mock( + '../test_sequencer', + () => + class { + sort(allTests) { + return allTests; + } + cacheResults() {} + }, +); + +jest.mock( + '../search_source', + () => + class { + constructor(context) { + this._context = context; + } + + async getTestPaths(globalConfig, changedFilesPromise) { + const {files} = await changedFilesPromise; + const paths = files.filter(path => path.match(/__tests__/)); + + return { + collectCoverageFrom: files.filter(path => !path.match(/__tests__/)), + tests: paths.map(path => ({ + context: this._context, + duration: null, + path, + })), + }; + } + }, +); + +const config = {roots: [], testPathIgnorePatterns: [], testRegex: ''}; +let globalConfig; +const defaults = { + changedFilesPromise: Promise.resolve({ + files: ['foo.js', '__tests__/foo-test.js', 'dont/cover.js'], + }), + contexts: [{config}], + onComplete: runResults => (globalConfig = runResults._globalConfig), + outputStream: {}, + startRun: {}, + testWatcher: {isInterrupted: () => false}, +}; + +describe('collectCoverageFrom patterns', () => { + it('should apply collectCoverageFrom patterns coming from SearchSource', async () => { + expect.assertions(1); + + await runJest({ + ...defaults, + globalConfig: { + rootDir: '', + }, + }); + expect(globalConfig.collectCoverageFrom).toEqual([ + 'foo.js', + 'dont/cover.js', + ]); + }); + + it('excludes coverage from files outside the global collectCoverageFrom config', async () => { + expect.assertions(1); + + await runJest({ + ...defaults, + globalConfig: { + collectCoverageFrom: ['**/dont/*.js'], + rootDir: '', + }, + }); + expect(globalConfig.collectCoverageFrom).toEqual(['dont/cover.js']); + }); + + it('respects coveragePathIgnorePatterns', async () => { + expect.assertions(1); + + await runJest({ + ...defaults, + globalConfig: { + collectCoverageFrom: ['**/*.js'], + coveragePathIgnorePatterns: ['dont'], + rootDir: '', + }, + }); + expect(globalConfig.collectCoverageFrom).toEqual(['foo.js']); + }); +}); From 7e92015514b3854df7bf33c6429f2c09b8628731 Mon Sep 17 00:00:00 2001 From: Stian Didriksen Date: Sun, 18 Mar 2018 01:44:40 +0100 Subject: [PATCH 23/25] update snapshots --- .../find_related_files.test.js.snap | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/integration-tests/__tests__/__snapshots__/find_related_files.test.js.snap b/integration-tests/__tests__/__snapshots__/find_related_files.test.js.snap index 8798eff0d548..cdddb39ad81b 100644 --- a/integration-tests/__tests__/__snapshots__/find_related_files.test.js.snap +++ b/integration-tests/__tests__/__snapshots__/find_related_files.test.js.snap @@ -17,13 +17,13 @@ PASS __tests__/b.test.js" `; exports[`--findRelatedTests flag generates coverage report for filename 3`] = ` -"----------|----------|----------|----------|----------|----------------| -File | % Stmts | % Branch | % Funcs | % Lines |Uncovered Lines | -----------|----------|----------|----------|----------|----------------| -All files | 100 | 100 | 100 | 100 | | - a.js | 100 | 100 | 100 | 100 | | - b.js | 100 | 100 | 100 | 100 | | -----------|----------|----------|----------|----------|----------------| +"----------|----------|----------|----------|----------|-------------------| +File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s | +----------|----------|----------|----------|----------|-------------------| +All files | 100 | 100 | 100 | 100 | | + a.js | 100 | 100 | 100 | 100 | | + b.js | 100 | 100 | 100 | 100 | | +----------|----------|----------|----------|----------|-------------------| " `; @@ -44,11 +44,11 @@ exports[`--findRelatedTests flag generates coverage report for filename 5`] = ` `; exports[`--findRelatedTests flag generates coverage report for filename 6`] = ` -"----------|----------|----------|----------|----------|----------------| -File | % Stmts | % Branch | % Funcs | % Lines |Uncovered Lines | -----------|----------|----------|----------|----------|----------------| -All files | 100 | 100 | 100 | 100 | | - a.js | 100 | 100 | 100 | 100 | | -----------|----------|----------|----------|----------|----------------| +"----------|----------|----------|----------|----------|-------------------| +File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s | +----------|----------|----------|----------|----------|-------------------| +All files | 100 | 100 | 100 | 100 | | + a.js | 100 | 100 | 100 | 100 | | +----------|----------|----------|----------|----------|-------------------| " `; From 988081b95dac2b63acd36599666ed3371e29a24c Mon Sep 17 00:00:00 2001 From: Stian Didriksen Date: Sun, 18 Mar 2018 21:55:28 +0100 Subject: [PATCH 24/25] remove object spread, replaced with Object.assign --- .../__tests__/run_jest_with_coverage.test.js | 45 ++++++++++--------- 1 file changed, 24 insertions(+), 21 deletions(-) diff --git a/packages/jest-cli/src/__tests__/run_jest_with_coverage.test.js b/packages/jest-cli/src/__tests__/run_jest_with_coverage.test.js index a529fa94f4fb..9df75caec40d 100644 --- a/packages/jest-cli/src/__tests__/run_jest_with_coverage.test.js +++ b/packages/jest-cli/src/__tests__/run_jest_with_coverage.test.js @@ -68,12 +68,13 @@ describe('collectCoverageFrom patterns', () => { it('should apply collectCoverageFrom patterns coming from SearchSource', async () => { expect.assertions(1); - await runJest({ - ...defaults, - globalConfig: { - rootDir: '', - }, - }); + await runJest( + Object.assign({}, defaults, { + globalConfig: { + rootDir: '', + }, + }), + ); expect(globalConfig.collectCoverageFrom).toEqual([ 'foo.js', 'dont/cover.js', @@ -83,27 +84,29 @@ describe('collectCoverageFrom patterns', () => { it('excludes coverage from files outside the global collectCoverageFrom config', async () => { expect.assertions(1); - await runJest({ - ...defaults, - globalConfig: { - collectCoverageFrom: ['**/dont/*.js'], - rootDir: '', - }, - }); + await runJest( + Object.assign({}, defaults, { + globalConfig: { + collectCoverageFrom: ['**/dont/*.js'], + rootDir: '', + }, + }), + ); expect(globalConfig.collectCoverageFrom).toEqual(['dont/cover.js']); }); it('respects coveragePathIgnorePatterns', async () => { expect.assertions(1); - await runJest({ - ...defaults, - globalConfig: { - collectCoverageFrom: ['**/*.js'], - coveragePathIgnorePatterns: ['dont'], - rootDir: '', - }, - }); + await runJest( + Object.assign({}, defaults, { + globalConfig: { + collectCoverageFrom: ['**/*.js'], + coveragePathIgnorePatterns: ['dont'], + rootDir: '', + }, + }), + ); expect(globalConfig.collectCoverageFrom).toEqual(['foo.js']); }); }); From 7d83ec842275902195a7c2fb88a9fbefec00fc9d Mon Sep 17 00:00:00 2001 From: Stian Didriksen Date: Sun, 18 Mar 2018 23:02:26 +0100 Subject: [PATCH 25/25] add changelog entry --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a5fe04d618ee..9399452de15f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ ### Features +* `[jest-cli]` Add support for using `--coverage` in combination with watch + mode, `--onlyChanged`, `--findRelatedTests` and more + ([#5601](https://github.com/facebook/jest/pull/5601)) * `[jest-jasmine2]` Adds error throwing and descriptive errors to `it`/ `test` for invalid arguments. `[jest-circus]` Adds error throwing and descriptive errors to `it`/ `test` for invalid arguments