From d0b57b1987bb27c9018018e06df2239d74c57d84 Mon Sep 17 00:00:00 2001 From: Kenrick Date: Sat, 31 Aug 2019 00:24:21 +0800 Subject: [PATCH] fix: Jest mutli-project-runner still cannot handle exactly one project Add failing test case Explicitly distinguish if project has been added using process.cwd Fix CI errors --- e2e/__tests__/multiProjectRunner.test.ts | 30 ++++++++++++++++------ packages/jest-cli/src/cli/index.ts | 18 ++++++++++--- packages/jest-config/src/index.ts | 32 ++++++++++++++---------- packages/jest-core/src/cli/index.ts | 2 ++ 4 files changed, 57 insertions(+), 25 deletions(-) diff --git a/e2e/__tests__/multiProjectRunner.test.ts b/e2e/__tests__/multiProjectRunner.test.ts index 77b2a374ccd0..8ead1d9da2af 100644 --- a/e2e/__tests__/multiProjectRunner.test.ts +++ b/e2e/__tests__/multiProjectRunner.test.ts @@ -170,28 +170,42 @@ test('"No tests found" message for projects', () => { ); }); -test.each([{projectPath: 'packages/somepackage'}, {projectPath: 'packages/*'}])( - 'allows a single non-root project', - ({projectPath}: {projectPath: string}) => { +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": { - "testMatch": ["/packages/somepackage/test.js"], "projects": [ "${projectPath}" ] } } `, - 'packages/somepackage/package.json': ` + 'packages/p1/package.json': ` { "jest": { - "displayName": "somepackage" + "displayName": "p1" } } `, - 'packages/somepackage/test.js': ` + '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); }); @@ -199,7 +213,7 @@ 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 ${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-cli/src/cli/index.ts b/packages/jest-cli/src/cli/index.ts index c4024ea7aab1..96d817616ae8 100644 --- a/packages/jest-cli/src/cli/index.ts +++ b/packages/jest-cli/src/cli/index.ts @@ -28,9 +28,16 @@ export async function run(maybeArgv?: Array, project?: Config.Path) { return; } - const projects = getProjectListFromCLIArgs(argv, project); - - const {results, globalConfig} = await runCLI(argv, projects); + const {isGlobalProject, projects} = getProjectListFromCLIArgs( + argv, + project, + ); + + const {results, globalConfig} = await runCLI( + argv, + projects, + isGlobalProject, + ); readResultsAndExit(results, globalConfig); } catch (error) { clearLine(process.stderr); @@ -83,6 +90,7 @@ const getProjectListFromCLIArgs = ( argv: Config.Argv, project?: Config.Path, ) => { + let isGlobalProject = false; const projects = argv.projects ? argv.projects : []; if (project) { @@ -92,6 +100,7 @@ const getProjectListFromCLIArgs = ( if (!projects.length && process.platform === 'win32') { try { projects.push(realpath(process.cwd())); + isGlobalProject = true; } catch (err) { // do nothing, just catch error // process.binding('fs').realpath can throw, e.g. on mapped drives @@ -99,10 +108,11 @@ const getProjectListFromCLIArgs = ( } if (!projects.length) { + isGlobalProject = true; projects.push(process.cwd()); } - return projects; + return {isGlobalProject, projects}; }; const readResultsAndExit = ( diff --git a/packages/jest-config/src/index.ts b/packages/jest-config/src/index.ts index fc796086e2a1..8b65985db130 100644 --- a/packages/jest-config/src/index.ts +++ b/packages/jest-config/src/index.ts @@ -263,6 +263,7 @@ This usually means that your ${chalk.bold( export function readConfigs( argv: Config.Argv, projectPaths: Array, + isGlobalProject: boolean, ): { globalConfig: Config.GlobalConfig; configs: Array; @@ -278,26 +279,19 @@ 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 parsedConfigs = projects .filter(root => { // Ignore globbed files that cannot be `require`d. @@ -313,9 +307,21 @@ export function readConfigs( return true; }) - .map((root, projectIndex) => - readConfig(argv, root, true, configPath, projectIndex), - ); + .map((root, projectIndex) => { + // Skip on all except: projectIndex === 0, and isGlobalProject, and projects.length === 1 + const skipArgvConfigOption = !( + projectIndex === 0 && + isGlobalProject && + projects.length === 1 + ); + return readConfig( + argv, + root, + skipArgvConfigOption, + configPath, + projectIndex, + ); + }); ensureNoDuplicateConfigs(parsedConfigs, projects); configs = parsedConfigs.map(({projectConfig}) => projectConfig); diff --git a/packages/jest-core/src/cli/index.ts b/packages/jest-core/src/cli/index.ts index ad2f2e2bea73..2a730bdd5d6b 100644 --- a/packages/jest-core/src/cli/index.ts +++ b/packages/jest-core/src/cli/index.ts @@ -34,6 +34,7 @@ type OnCompleteCallback = (results: AggregatedResult) => void; export const runCLI = async ( argv: Config.Argv, projects: Array, + isGlobalProject: boolean, ): Promise<{ results: AggregatedResult; globalConfig: Config.GlobalConfig; @@ -52,6 +53,7 @@ export const runCLI = async ( const {globalConfig, configs, hasDeprecationWarnings} = readConfigs( argv, projects, + isGlobalProject, ); if (argv.debug) {