From 77c3ceedfd61ddc841e11fec7b76e540924d3e60 Mon Sep 17 00:00:00 2001 From: Kenrick Date: Sat, 23 Nov 2019 00:54:49 +0800 Subject: [PATCH] fix: Jest mutli-project-runner should handle exactly one project (#8894) --- CHANGELOG.md | 1 + e2e/__tests__/multiProjectRunner.test.ts | 52 +++++++++++++++++++++++- packages/jest-config/src/index.ts | 35 ++++++++++------ 3 files changed, 74 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 48c5a075b80c..00582f8d818b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -40,6 +40,7 @@ - `[expect]` Consider all RegExp flags for equality ([#9167](https://github.com/facebook/jest/pull/9167)) - `[expect]` [**BREAKING**] Consider primitives different from wrappers instantiated with `new` ([#9167](https://github.com/facebook/jest/pull/9167)) - `[jest-config]` Use half of the available cores when `watchAll` mode is enabled ([#9117](https://github.com/facebook/jest/pull/9117)) +- `[jest-config]` Fix Jest multi project runner still cannot handle exactly one project ([#8894](https://github.com/facebook/jest/pull/8894)) - `[jest-console]` Add missing `console.group` calls to `NullConsole` ([#9024](https://github.com/facebook/jest/pull/9024)) - `[jest-core]` Don't include unref'd timers in --detectOpenHandles results ([#8941](https://github.com/facebook/jest/pull/8941)) - `[jest-diff]` Do not inverse format if line consists of one change ([#8903](https://github.com/facebook/jest/pull/8903)) diff --git a/e2e/__tests__/multiProjectRunner.test.ts b/e2e/__tests__/multiProjectRunner.test.ts index 77b2a374ccd0..ebb995a61f62 100644 --- a/e2e/__tests__/multiProjectRunner.test.ts +++ b/e2e/__tests__/multiProjectRunner.test.ts @@ -199,7 +199,57 @@ test.each([{projectPath: 'packages/somepackage'}, {projectPath: 'packages/*'}])( }); const {stdout, stderr, exitCode} = runJest(DIR, ['--no-watchman']); - expect(stderr).toContain('PASS packages/somepackage/test.js'); + expect(stderr).toContain('PASS somepackage packages/somepackage/test.js'); + expect(stderr).toContain('Test Suites: 1 passed, 1 total'); + expect(stdout).toEqual(''); + expect(exitCode).toEqual(0); + }, +); + +test.each([ + {displayName: 'p1', projectPath: 'packages/p1'}, + {displayName: 'p2', projectPath: 'packages/p2'}, +])( + 'correctly runs a single non-root project', + ({projectPath, displayName}: {projectPath: string; displayName: string}) => { + writeFiles(DIR, { + 'package.json': ` + { + "jest": { + "projects": [ + "${projectPath}" + ] + } + } + `, + 'packages/p1/package.json': ` + { + "jest": { + "displayName": "p1" + } + } + `, + 'packages/p1/test.js': ` + test('1+1', () => { + expect(1).toBe(1); + }); + `, + 'packages/p2/package.json': ` + { + "jest": { + "displayName": "p2" + } + } + `, + 'packages/p2/test.js': ` + test('1+1', () => { + expect(1).toBe(1); + }); + `, + }); + + const {stdout, stderr, exitCode} = runJest(DIR, ['--no-watchman']); + expect(stderr).toContain(`PASS ${displayName} ${projectPath}/test.js`); expect(stderr).toContain('Test Suites: 1 passed, 1 total'); expect(stdout).toEqual(''); expect(exitCode).toEqual(0); diff --git a/packages/jest-config/src/index.ts b/packages/jest-config/src/index.ts index fc796086e2a1..0df90f5d9c39 100644 --- a/packages/jest-config/src/index.ts +++ b/packages/jest-config/src/index.ts @@ -9,6 +9,7 @@ import * as fs from 'fs'; import * as path from 'path'; import {Config} from '@jest/types'; import chalk = require('chalk'); +import {sync as realpath} from 'realpath-native'; import {isJSONString, replaceRootDirInPath} from './utils'; import normalize from './normalize'; import resolveConfigPath from './resolveConfigPath'; @@ -278,26 +279,24 @@ export function readConfigs( const parsedConfig = readConfig(argv, projects[0]); configPath = parsedConfig.configPath; - if (parsedConfig.globalConfig.projects) { - // If this was a single project, and its config has `projects` - // settings, use that value instead. - projects = parsedConfig.globalConfig.projects; - } - hasDeprecationWarnings = parsedConfig.hasDeprecationWarnings; globalConfig = parsedConfig.globalConfig; configs = [parsedConfig.projectConfig]; if (globalConfig.projects && globalConfig.projects.length) { // Even though we had one project in CLI args, there might be more // projects defined in the config. + // In other words, if this was a single project, + // and its config has `projects` settings, use that value instead. projects = globalConfig.projects; } } - if ( - projects.length > 1 || - (projects.length && typeof projects[0] === 'object') - ) { + if (projects.length > 0) { + const projectIsCwd = + process.platform === 'win32' + ? projects[0] === realpath(process.cwd()) + : projects[0] === process.cwd(); + const parsedConfigs = projects .filter(root => { // Ignore globbed files that cannot be `require`d. @@ -313,9 +312,19 @@ export function readConfigs( return true; }) - .map((root, projectIndex) => - readConfig(argv, root, true, configPath, projectIndex), - ); + .map((root, projectIndex) => { + const projectIsTheOnlyProject = + projectIndex === 0 && projects.length === 1; + const skipArgvConfigOption = !(projectIsTheOnlyProject && projectIsCwd); + + return readConfig( + argv, + root, + skipArgvConfigOption, + configPath, + projectIndex, + ); + }); ensureNoDuplicateConfigs(parsedConfigs, projects); configs = parsedConfigs.map(({projectConfig}) => projectConfig);