Skip to content

Commit c8bb0a7

Browse files
authored
Fix bug: MPR executes tests multiple times (#5335)
1 parent bb21f0b commit c8bb0a7

File tree

5 files changed

+88
-2
lines changed

5 files changed

+88
-2
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
### Fixes
44

5+
* `[jest-cli]` Check if the file belongs to the checked project before adding it
6+
to the list ([#5335](https://github.com/facebook/jest/pull/5335))
57
* `[jest-cli]` Fix `EISDIR` when a directory is passed as an argument to `jest`.
68
([#5317](https://github.com/facebook/jest/pull/5317))
79
* `[jest-config]` Added restoreMocks config option.
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`Tests are executed only once even in an MPR 1`] = `
4+
"PASS foo/folder/my-test-bar.js
5+
✓ bar
6+
7+
"
8+
`;

integration-tests/__tests__/cli-accepts-exact-filenames.test.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,11 @@ test('CLI accepts exact filenames', () => {
4040
'./foo/baz.js',
4141
'./foo',
4242
]);
43-
const {rest, summary} = extractSummary(stderr);
43+
4444
expect(status).toBe(0);
45+
46+
const {rest, summary} = extractSummary(stderr);
47+
4548
expect(rest).toMatchSnapshot();
4649
expect(summary).toMatchSnapshot();
4750
expect(stdout).toMatchSnapshot();
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/**
2+
* Copyright (c) 2017-present, Facebook, Inc. All rights reserved.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*
7+
* @flow
8+
*/
9+
10+
'use strict';
11+
12+
const path = require('path');
13+
const skipOnWindows = require('../../scripts/skip_on_windows');
14+
const {extractSummary, cleanup, writeFiles} = require('../utils');
15+
const runJest = require('../runJest');
16+
17+
const DIR = path.resolve(__dirname, '../execute-tests-once-in-mpr');
18+
19+
skipOnWindows.suite();
20+
21+
beforeEach(() => cleanup(DIR));
22+
afterAll(() => cleanup(DIR));
23+
24+
test('Tests are executed only once even in an MPR', () => {
25+
// Make a global config that ignores all sub-projects.
26+
const config = {
27+
jest: {
28+
projects: ['<rootDir>/foo/*/'],
29+
testPathIgnorePatterns: ['/foo/'],
30+
},
31+
};
32+
33+
// Make a child config with a special regexp to ensure we execute the tests.
34+
const childConfig = {
35+
jest: {
36+
testRegex: /my-test-.*\.js/.source,
37+
},
38+
};
39+
40+
/* eslint-disable sort-keys */
41+
writeFiles(DIR, {
42+
'foo/folder/my-test-bar.js': `test('bar', () => console.log('Bar!'));`,
43+
'foo/folder/package.json': JSON.stringify(childConfig, null, 2),
44+
45+
'foo/directory/my-test-baz.js': `test('baz', () => console.log('Baz!'));`,
46+
'foo/directory/package.json': JSON.stringify(childConfig, null, 2),
47+
48+
'foo/whatever/my-test-qux.js': `test('qux', () => console.log('Qux!'));`,
49+
'foo/whatever/package.json': JSON.stringify(childConfig, null, 2),
50+
51+
'package.json': JSON.stringify(config, null, 2),
52+
});
53+
/* eslint-enable sort-keys */
54+
55+
const {stderr, status} = runJest(DIR, ['foo/folder/my-test-bar.js']);
56+
57+
expect(status).toBe(0);
58+
59+
const {rest, summary} = extractSummary(stderr);
60+
61+
// We have only one test passed, so total should equal to one, despite we have
62+
// three projects.
63+
expect(rest).toMatchSnapshot();
64+
expect(summary).toMatch(/1 total/);
65+
});

packages/jest-cli/src/search_source.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,14 +209,22 @@ export default class SearchSource {
209209
} else if (globalConfig.findRelatedTests && paths && paths.length) {
210210
return Promise.resolve(this.findRelatedTestsFromPattern(paths));
211211
} else {
212+
const allFiles = new Set(this._context.hasteFS.getAllFiles());
212213
const validTestPaths =
213214
paths &&
214215
paths.filter(name => {
215216
try {
216-
return fs.lstatSync(name).isFile();
217+
if (!fs.lstatSync(name).isFile()) {
218+
// It exists, but it is not a file; return false.
219+
return false;
220+
}
217221
} catch (e) {
222+
// It does not exist; return false.
218223
return false;
219224
}
225+
226+
// It exists and it is a file; return true if it's in the project.
227+
return allFiles.has(path.resolve(name));
220228
});
221229

222230
if (validTestPaths && validTestPaths.length) {

0 commit comments

Comments
 (0)