From b85b26b5b73ef86c43afc10a670aac5fae7dcd63 Mon Sep 17 00:00:00 2001 From: Jan Kaifer Date: Sat, 2 Oct 2021 14:37:18 +0200 Subject: [PATCH 01/39] chore: throw when there are multiple configs --- .../src/__tests__/resolveConfigPath.test.ts | 13 +++--- packages/jest-config/src/resolveConfigPath.ts | 42 ++++++++++++++++--- 2 files changed, 43 insertions(+), 12 deletions(-) diff --git a/packages/jest-config/src/__tests__/resolveConfigPath.test.ts b/packages/jest-config/src/__tests__/resolveConfigPath.test.ts index 10c45675498d..024e9d4f2003 100644 --- a/packages/jest-config/src/__tests__/resolveConfigPath.test.ts +++ b/packages/jest-config/src/__tests__/resolveConfigPath.test.ts @@ -14,6 +14,7 @@ import resolveConfigPath from '../resolveConfigPath'; const DIR = path.resolve(tmpdir(), 'resolve_config_path_test'); const ERROR_PATTERN = /Could not find a config file based on provided values/; const NO_ROOT_DIR_ERROR_PATTERN = /Can't find a root directory/; +const MULTIPLE_CONFIGS_ERROR_PATTERN = /Multiple configurations found/; beforeEach(() => cleanup(DIR)); afterEach(() => cleanup(DIR)); @@ -66,7 +67,7 @@ describe.each(JEST_CONFIG_EXT_ORDER.slice(0))( resolveConfigPath(path.dirname(relativeJestConfigPath), DIR), ).toThrowError(ERROR_PATTERN); - writeFiles(DIR, {[relativePackageJsonPath]: ''}); + writeFiles(DIR, {[relativePackageJsonPath]: JSON.stringify({jest: {}})}); // absolute expect( @@ -80,17 +81,17 @@ describe.each(JEST_CONFIG_EXT_ORDER.slice(0))( writeFiles(DIR, {[relativeJestConfigPath]: ''}); - // jest.config.js takes precedence + // jest.config.js and package.json are not allowed together // absolute - expect( + expect(() => resolveConfigPath(path.dirname(absolutePackageJsonPath), DIR), - ).toBe(absoluteJestConfigPath); + ).toThrowError(MULTIPLE_CONFIGS_ERROR_PATTERN); // relative - expect( + expect(() => resolveConfigPath(path.dirname(relativePackageJsonPath), DIR), - ).toBe(absoluteJestConfigPath); + ).toThrowError(MULTIPLE_CONFIGS_ERROR_PATTERN); expect(() => { resolveConfigPath( diff --git a/packages/jest-config/src/resolveConfigPath.ts b/packages/jest-config/src/resolveConfigPath.ts index dc8655513858..9bc6c942b9ee 100644 --- a/packages/jest-config/src/resolveConfigPath.ts +++ b/packages/jest-config/src/resolveConfigPath.ts @@ -60,15 +60,17 @@ const resolveConfigPathByTraversing = ( const jestConfig = JEST_CONFIG_EXT_ORDER.map(ext => path.resolve(pathToResolve, getConfigFilename(ext)), ).find(isFile); - if (jestConfig) { - return jestConfig; - } - const packageJson = path.resolve(pathToResolve, PACKAGE_JSON); - if (isFile(packageJson)) { - return packageJson; + const packageJson = findPackageJsonWithJestConfig(pathToResolve); + + // If user has jestConfig and 'jest' in package.json it's probably a mistake. + if (jestConfig && packageJson) { + throw new Error(makeMultipleConfigsErrorMessage(jestConfig, packageJson)); } + const configPath = jestConfig ?? packageJson; + if (configPath) return configPath; + // This is the system root. // We tried everything, config is nowhere to be found ¯\_(ツ)_/¯ if (pathToResolve === path.dirname(pathToResolve)) { @@ -83,6 +85,20 @@ const resolveConfigPathByTraversing = ( ); }; +const findPackageJsonWithJestConfig = (pathToResolve: Config.Path) => { + const packagePath = path.resolve(pathToResolve, PACKAGE_JSON); + if (isFile(packagePath) && 'jest' in parsePackageJson(packagePath)) { + return packagePath; + } + + return undefined; +}; + +const parsePackageJson = (packagePath: Config.Path) => { + const content = String(fs.readFileSync(packagePath)); + return JSON.parse(content); +}; + const makeResolutionErrorMessage = ( initialPath: Config.Path, cwd: Config.Path, @@ -95,3 +111,17 @@ const makeResolutionErrorMessage = ( `traverse directory tree up, until it finds one of those files in exact order: ${JEST_CONFIG_EXT_ORDER.map( ext => `"${getConfigFilename(ext)}"`, ).join(' or ')}.`; + +const makeMultipleConfigsErrorMessage = ( + jestConfigPath: Config.Path, + packagePath: Config.Path, +) => + '● Multiple configurations found:\n\n' + + `Jest will use \`${jestConfigPath}\` for configuration, but Jest also\n` + + `found configuration in \`${packagePath}\`. Delete the \`"jest"\` key\n` + + `in that file to silence this warning, or delete the \`${path.basename( + jestConfigPath, + )}\` file\n` + + `to use the configuration from \`${path.basename(packagePath)}\`.\n\n` + + 'Configuration Documentation:\n' + + 'https://jestjs.io/docs/en/configuration.html\n'; From 4dff740ed75e268486c18580f9a87aa7d05981a8 Mon Sep 17 00:00:00 2001 From: Jan Kaifer Date: Sat, 2 Oct 2021 15:06:57 +0200 Subject: [PATCH 02/39] fix: allowed package.json without 'jest' as valid config --- .../src/__tests__/resolveConfigPath.test.ts | 13 ++++++------- packages/jest-config/src/resolveConfigPath.ts | 17 +++++++++++------ 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/packages/jest-config/src/__tests__/resolveConfigPath.test.ts b/packages/jest-config/src/__tests__/resolveConfigPath.test.ts index 024e9d4f2003..10c45675498d 100644 --- a/packages/jest-config/src/__tests__/resolveConfigPath.test.ts +++ b/packages/jest-config/src/__tests__/resolveConfigPath.test.ts @@ -14,7 +14,6 @@ import resolveConfigPath from '../resolveConfigPath'; const DIR = path.resolve(tmpdir(), 'resolve_config_path_test'); const ERROR_PATTERN = /Could not find a config file based on provided values/; const NO_ROOT_DIR_ERROR_PATTERN = /Can't find a root directory/; -const MULTIPLE_CONFIGS_ERROR_PATTERN = /Multiple configurations found/; beforeEach(() => cleanup(DIR)); afterEach(() => cleanup(DIR)); @@ -67,7 +66,7 @@ describe.each(JEST_CONFIG_EXT_ORDER.slice(0))( resolveConfigPath(path.dirname(relativeJestConfigPath), DIR), ).toThrowError(ERROR_PATTERN); - writeFiles(DIR, {[relativePackageJsonPath]: JSON.stringify({jest: {}})}); + writeFiles(DIR, {[relativePackageJsonPath]: ''}); // absolute expect( @@ -81,17 +80,17 @@ describe.each(JEST_CONFIG_EXT_ORDER.slice(0))( writeFiles(DIR, {[relativeJestConfigPath]: ''}); - // jest.config.js and package.json are not allowed together + // jest.config.js takes precedence // absolute - expect(() => + expect( resolveConfigPath(path.dirname(absolutePackageJsonPath), DIR), - ).toThrowError(MULTIPLE_CONFIGS_ERROR_PATTERN); + ).toBe(absoluteJestConfigPath); // relative - expect(() => + expect( resolveConfigPath(path.dirname(relativePackageJsonPath), DIR), - ).toThrowError(MULTIPLE_CONFIGS_ERROR_PATTERN); + ).toBe(absoluteJestConfigPath); expect(() => { resolveConfigPath( diff --git a/packages/jest-config/src/resolveConfigPath.ts b/packages/jest-config/src/resolveConfigPath.ts index 9bc6c942b9ee..88478b1d46f3 100644 --- a/packages/jest-config/src/resolveConfigPath.ts +++ b/packages/jest-config/src/resolveConfigPath.ts @@ -61,10 +61,10 @@ const resolveConfigPathByTraversing = ( path.resolve(pathToResolve, getConfigFilename(ext)), ).find(isFile); - const packageJson = findPackageJsonWithJestConfig(pathToResolve); + const packageJson = findPackageJson(pathToResolve); // If user has jestConfig and 'jest' in package.json it's probably a mistake. - if (jestConfig && packageJson) { + if (jestConfig && packageJson && hasPackageJsonJestKey(packageJson)) { throw new Error(makeMultipleConfigsErrorMessage(jestConfig, packageJson)); } @@ -85,18 +85,23 @@ const resolveConfigPathByTraversing = ( ); }; -const findPackageJsonWithJestConfig = (pathToResolve: Config.Path) => { +const findPackageJson = (pathToResolve: Config.Path) => { const packagePath = path.resolve(pathToResolve, PACKAGE_JSON); - if (isFile(packagePath) && 'jest' in parsePackageJson(packagePath)) { + if (isFile(packagePath)) { return packagePath; } return undefined; }; -const parsePackageJson = (packagePath: Config.Path) => { +const hasPackageJsonJestKey = (packagePath: Config.Path) => { const content = String(fs.readFileSync(packagePath)); - return JSON.parse(content); + try { + return 'jest' in JSON.parse(content); + } catch { + // If package is not a valid JSON + return false; + } }; const makeResolutionErrorMessage = ( From 227f7d4a30e37e4c52e261721d7b3a5dc6a6ee18 Mon Sep 17 00:00:00 2001 From: Jan Kaifer Date: Sat, 2 Oct 2021 15:14:14 +0200 Subject: [PATCH 03/39] test: unit test for multiple configs error in resolver --- .../src/__tests__/resolveConfigPath.test.ts | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/packages/jest-config/src/__tests__/resolveConfigPath.test.ts b/packages/jest-config/src/__tests__/resolveConfigPath.test.ts index 10c45675498d..566f2602f562 100644 --- a/packages/jest-config/src/__tests__/resolveConfigPath.test.ts +++ b/packages/jest-config/src/__tests__/resolveConfigPath.test.ts @@ -14,6 +14,7 @@ import resolveConfigPath from '../resolveConfigPath'; const DIR = path.resolve(tmpdir(), 'resolve_config_path_test'); const ERROR_PATTERN = /Could not find a config file based on provided values/; const NO_ROOT_DIR_ERROR_PATTERN = /Can't find a root directory/; +const MULTIPLE_CONFIGS_ERROR_PATTERN = /Multiple configurations found/; beforeEach(() => cleanup(DIR)); afterEach(() => cleanup(DIR)); @@ -92,6 +93,20 @@ describe.each(JEST_CONFIG_EXT_ORDER.slice(0))( resolveConfigPath(path.dirname(relativePackageJsonPath), DIR), ).toBe(absoluteJestConfigPath); + // jest.config.js and package.json with 'jest' cannot be used together + + writeFiles(DIR, {[relativePackageJsonPath]: JSON.stringify({jest: {}})}); + + // absolute + expect(() => + resolveConfigPath(path.dirname(absolutePackageJsonPath), DIR), + ).toThrowError(MULTIPLE_CONFIGS_ERROR_PATTERN); + + // relative + expect(() => + resolveConfigPath(path.dirname(relativePackageJsonPath), DIR), + ).toThrowError(MULTIPLE_CONFIGS_ERROR_PATTERN); + expect(() => { resolveConfigPath( path.join(path.dirname(relativePackageJsonPath), 'j/x/b/m/'), From a678d28456fcafd199005f98f4253a8b12cca0ba Mon Sep 17 00:00:00 2001 From: Jan Kaifer Date: Mon, 4 Oct 2021 10:35:19 +0200 Subject: [PATCH 04/39] Apply suggestions from code review Co-authored-by: Simen Bekkhus --- packages/jest-config/src/resolveConfigPath.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/jest-config/src/resolveConfigPath.ts b/packages/jest-config/src/resolveConfigPath.ts index 88478b1d46f3..cdc45a115c3f 100644 --- a/packages/jest-config/src/resolveConfigPath.ts +++ b/packages/jest-config/src/resolveConfigPath.ts @@ -95,7 +95,7 @@ const findPackageJson = (pathToResolve: Config.Path) => { }; const hasPackageJsonJestKey = (packagePath: Config.Path) => { - const content = String(fs.readFileSync(packagePath)); + const content = fs.readFileSync(packagePath, 'utf8'); try { return 'jest' in JSON.parse(content); } catch { @@ -129,4 +129,4 @@ const makeMultipleConfigsErrorMessage = ( )}\` file\n` + `to use the configuration from \`${path.basename(packagePath)}\`.\n\n` + 'Configuration Documentation:\n' + - 'https://jestjs.io/docs/en/configuration.html\n'; + 'https://jestjs.io/docs/configuration.html\n'; From 0f81fe4c5e84895ec7de2136e969d736394c7301 Mon Sep 17 00:00:00 2001 From: Jan Kaifer Date: Mon, 4 Oct 2021 13:01:50 +0200 Subject: [PATCH 05/39] test: fixed integration test --- e2e/Utils.ts | 9 ++++++--- e2e/__tests__/dependencyClash.test.ts | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/e2e/Utils.ts b/e2e/Utils.ts index fd0a591dfa49..e5b44d1a74ca 100644 --- a/e2e/Utils.ts +++ b/e2e/Utils.ts @@ -176,7 +176,6 @@ interface JestPackageJson extends PackageJson { } const DEFAULT_PACKAGE_JSON: JestPackageJson = { - description: 'THIS IS AN AUTOGENERATED FILE AND SHOULD NOT BE ADDED TO GIT', jest: { testEnvironment: 'node', }, @@ -184,12 +183,16 @@ const DEFAULT_PACKAGE_JSON: JestPackageJson = { export const createEmptyPackage = ( directory: Config.Path, - packageJson = DEFAULT_PACKAGE_JSON, + packageJson: PackageJson = DEFAULT_PACKAGE_JSON, ) => { + const packageJsonWithDefaults = { + ...packageJson, + description: 'THIS IS AN AUTOGENERATED FILE AND SHOULD NOT BE ADDED TO GIT', + }; fs.mkdirSync(directory, {recursive: true}); fs.writeFileSync( path.resolve(directory, 'package.json'), - JSON.stringify(packageJson, null, 2), + JSON.stringify(packageJsonWithDefaults, null, 2), ); }; diff --git a/e2e/__tests__/dependencyClash.test.ts b/e2e/__tests__/dependencyClash.test.ts index 87b9c81eee77..d6ea667631a1 100644 --- a/e2e/__tests__/dependencyClash.test.ts +++ b/e2e/__tests__/dependencyClash.test.ts @@ -18,7 +18,7 @@ const hasteImplModulePath = path beforeEach(() => { cleanup(tempDir); - createEmptyPackage(tempDir); + createEmptyPackage(tempDir, {}); }); // This test case is checking that when having both From b6ff8b89f89f9c2b19ef2991f46ac82a7183cd89 Mon Sep 17 00:00:00 2001 From: Jan Kaifer Date: Mon, 4 Oct 2021 13:56:18 +0200 Subject: [PATCH 06/39] tests: fixed config issues in old tests --- e2e/esm-config/cjs/package.json | 4 +--- e2e/esm-config/mjs/package.json | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/e2e/esm-config/cjs/package.json b/e2e/esm-config/cjs/package.json index 586d4ca6b75c..0967ef424bce 100644 --- a/e2e/esm-config/cjs/package.json +++ b/e2e/esm-config/cjs/package.json @@ -1,3 +1 @@ -{ - "jest": {} -} +{} diff --git a/e2e/esm-config/mjs/package.json b/e2e/esm-config/mjs/package.json index 586d4ca6b75c..0967ef424bce 100644 --- a/e2e/esm-config/mjs/package.json +++ b/e2e/esm-config/mjs/package.json @@ -1,3 +1 @@ -{ - "jest": {} -} +{} From 27fdafff87f91cd196721931093f354f32ef9cc7 Mon Sep 17 00:00:00 2001 From: Jan Kaifer Date: Mon, 4 Oct 2021 16:08:13 +0200 Subject: [PATCH 07/39] feat: multiple jest.config.ext files are not allowed --- .../src/__tests__/resolveConfigPath.test.ts | 23 +++++++++ packages/jest-config/src/resolveConfigPath.ts | 47 ++++++++++++------- 2 files changed, 53 insertions(+), 17 deletions(-) diff --git a/packages/jest-config/src/__tests__/resolveConfigPath.test.ts b/packages/jest-config/src/__tests__/resolveConfigPath.test.ts index 566f2602f562..a39c5ea43d48 100644 --- a/packages/jest-config/src/__tests__/resolveConfigPath.test.ts +++ b/packages/jest-config/src/__tests__/resolveConfigPath.test.ts @@ -114,5 +114,28 @@ describe.each(JEST_CONFIG_EXT_ORDER.slice(0))( ); }).toThrowError(NO_ROOT_DIR_ERROR_PATTERN); }); + + describe.each(JEST_CONFIG_EXT_ORDER.slice(0))( + `jest.config.%s and jest.config${extension}`, + extension2 => { + if (extension === extension2) return; + + const relativeJestConfigPaths = [ + `a/b/c/jest.config${extension}`, + `a/b/c/jest.config${extension2}`, + ]; + + writeFiles(DIR, { + [relativeJestConfigPaths[0]]: '', + [relativeJestConfigPaths[1]]: '', + }); + + // multiple configs here, should throw + + expect(() => + resolveConfigPath(path.dirname(relativeJestConfigPaths[0]), DIR), + ).toThrowError(MULTIPLE_CONFIGS_ERROR_PATTERN); + }, + ); }, ); diff --git a/packages/jest-config/src/resolveConfigPath.ts b/packages/jest-config/src/resolveConfigPath.ts index cdc45a115c3f..6a74dd206bc3 100644 --- a/packages/jest-config/src/resolveConfigPath.ts +++ b/packages/jest-config/src/resolveConfigPath.ts @@ -57,19 +57,22 @@ const resolveConfigPathByTraversing = ( initialPath: Config.Path, cwd: Config.Path, ): Config.Path => { - const jestConfig = JEST_CONFIG_EXT_ORDER.map(ext => + const configFiles = JEST_CONFIG_EXT_ORDER.map(ext => path.resolve(pathToResolve, getConfigFilename(ext)), - ).find(isFile); + ).filter(isFile); const packageJson = findPackageJson(pathToResolve); + if (packageJson && hasPackageJsonJestKey(packageJson)) { + configFiles.push(packageJson); + } - // If user has jestConfig and 'jest' in package.json it's probably a mistake. - if (jestConfig && packageJson && hasPackageJsonJestKey(packageJson)) { - throw new Error(makeMultipleConfigsErrorMessage(jestConfig, packageJson)); + if (configFiles.length > 1) { + throw new Error(makeMultipleConfigsError(configFiles)); } - const configPath = jestConfig ?? packageJson; - if (configPath) return configPath; + if (configFiles.length || packageJson) { + return configFiles[0] ?? packageJson; + } // This is the system root. // We tried everything, config is nowhere to be found ¯\_(ツ)_/¯ @@ -117,16 +120,26 @@ const makeResolutionErrorMessage = ( ext => `"${getConfigFilename(ext)}"`, ).join(' or ')}.`; -const makeMultipleConfigsErrorMessage = ( - jestConfigPath: Config.Path, - packagePath: Config.Path, -) => +const makeMultipleConfigsError = (configPaths: Array) => '● Multiple configurations found:\n\n' + - `Jest will use \`${jestConfigPath}\` for configuration, but Jest also\n` + - `found configuration in \`${packagePath}\`. Delete the \`"jest"\` key\n` + - `in that file to silence this warning, or delete the \`${path.basename( - jestConfigPath, - )}\` file\n` + - `to use the configuration from \`${path.basename(packagePath)}\`.\n\n` + + `Jest found configuration in ${concatenateWords( + configPaths.map(wrapInBackticks), + )}.\n` + + 'This is not allowed because it is probably a mistake.\n\n' + 'Configuration Documentation:\n' + 'https://jestjs.io/docs/configuration.html\n'; + +const wrapInBackticks = (word: string) => `\`${word}\``; + +const concatenateWords = (words: Array): string => { + if (words.length === 0) { + throw new Error('Cannot concatenate an empty array.'); + } else if (words.length <= 2) { + return words.join(' and '); + } else { + return concatenateWords([ + words.slice(0, -1).join(', '), + words[words.length - 1], + ]); + } +}; From 0d15a1f266ef93e74d9c8600bf8449a87ab0640f Mon Sep 17 00:00:00 2001 From: Jan Kaifer Date: Mon, 4 Oct 2021 16:24:49 +0200 Subject: [PATCH 08/39] test: added e2e test for --config override --- e2e/__tests__/configOverride.test.ts | 24 +++++++++++++++++++++++ e2e/config-override/__tests__/test.js | 10 ++++++++++ e2e/config-override/different-config.json | 3 +++ e2e/config-override/jest.config.json | 3 +++ e2e/config-override/package.json | 1 + 5 files changed, 41 insertions(+) create mode 100644 e2e/__tests__/configOverride.test.ts create mode 100644 e2e/config-override/__tests__/test.js create mode 100644 e2e/config-override/different-config.json create mode 100644 e2e/config-override/jest.config.json create mode 100644 e2e/config-override/package.json diff --git a/e2e/__tests__/configOverride.test.ts b/e2e/__tests__/configOverride.test.ts new file mode 100644 index 000000000000..0efb17551a6f --- /dev/null +++ b/e2e/__tests__/configOverride.test.ts @@ -0,0 +1,24 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import {getConfig} from '../runJest'; + +test('reads config from cjs file', () => { + const {configs} = getConfig( + 'config-override', + ['--config', 'different-config.json'], + { + skipPkgJsonCheck: true, + }, + ); + + expect(configs).toHaveLength(1); + expect(configs[0].displayName).toEqual({ + color: 'white', + name: 'Config from different-config.json file', + }); +}); diff --git a/e2e/config-override/__tests__/test.js b/e2e/config-override/__tests__/test.js new file mode 100644 index 000000000000..2b4a7ced6f45 --- /dev/null +++ b/e2e/config-override/__tests__/test.js @@ -0,0 +1,10 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. 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. + */ + +test('dummy test', () => { + expect(1).toBe(1); +}); diff --git a/e2e/config-override/different-config.json b/e2e/config-override/different-config.json new file mode 100644 index 000000000000..707a2314b2f1 --- /dev/null +++ b/e2e/config-override/different-config.json @@ -0,0 +1,3 @@ +{ + "displayName": "Config from different-config.json file" +} diff --git a/e2e/config-override/jest.config.json b/e2e/config-override/jest.config.json new file mode 100644 index 000000000000..ac2653d362cb --- /dev/null +++ b/e2e/config-override/jest.config.json @@ -0,0 +1,3 @@ +{ + "displayName": "Config from json file" +} diff --git a/e2e/config-override/package.json b/e2e/config-override/package.json new file mode 100644 index 000000000000..0967ef424bce --- /dev/null +++ b/e2e/config-override/package.json @@ -0,0 +1 @@ +{} From eccf9534ad6873959ef4bba687228b541ca3a282 Mon Sep 17 00:00:00 2001 From: Jan Kaifer Date: Tue, 5 Oct 2021 09:20:38 +0200 Subject: [PATCH 09/39] fix: more explicit expression Co-authored-by: Simen Bekkhus --- packages/jest-config/src/resolveConfigPath.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/jest-config/src/resolveConfigPath.ts b/packages/jest-config/src/resolveConfigPath.ts index 6a74dd206bc3..d54dbd509207 100644 --- a/packages/jest-config/src/resolveConfigPath.ts +++ b/packages/jest-config/src/resolveConfigPath.ts @@ -70,7 +70,7 @@ const resolveConfigPathByTraversing = ( throw new Error(makeMultipleConfigsError(configFiles)); } - if (configFiles.length || packageJson) { + if (configFiles.length > 0 || packageJson) { return configFiles[0] ?? packageJson; } From 3d7158593987a46e2abce782009c77931e59b710 Mon Sep 17 00:00:00 2001 From: Jan Kaifer Date: Tue, 5 Oct 2021 09:21:09 +0200 Subject: [PATCH 10/39] fix: added more real-life package.json example --- e2e/esm-config/cjs/package.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/e2e/esm-config/cjs/package.json b/e2e/esm-config/cjs/package.json index 0967ef424bce..d9f70a793cd8 100644 --- a/e2e/esm-config/cjs/package.json +++ b/e2e/esm-config/cjs/package.json @@ -1 +1,3 @@ -{} +{ + "name": "cjs-config" +} From 752b1f9fca381e439d23a78ad50381f0d110456b Mon Sep 17 00:00:00 2001 From: Jan Kaifer Date: Tue, 5 Oct 2021 09:39:49 +0200 Subject: [PATCH 11/39] test: added snapshot tests for multiple errors --- .../resolveConfigPath.test.ts.snap | 45 +++++++++++++++++++ .../src/__tests__/resolveConfigPath.test.ts | 20 +++++++++ 2 files changed, 65 insertions(+) create mode 100644 packages/jest-config/src/__tests__/__snapshots__/resolveConfigPath.test.ts.snap diff --git a/packages/jest-config/src/__tests__/__snapshots__/resolveConfigPath.test.ts.snap b/packages/jest-config/src/__tests__/__snapshots__/resolveConfigPath.test.ts.snap new file mode 100644 index 000000000000..aa7805c131f1 --- /dev/null +++ b/packages/jest-config/src/__tests__/__snapshots__/resolveConfigPath.test.ts.snap @@ -0,0 +1,45 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[` 1`] = ` +"● Multiple configurations found: + +Jest found configuration in \`/var/folders/14/qp47l23n64j5pyd7vllb78c00000gn/T/resolve_config_path_test/a/b/c/jest.config.js\`, \`/var/folders/14/qp47l23n64j5pyd7vllb78c00000gn/T/resolve_config_path_test/a/b/c/jest.config.ts\`, \`/var/folders/14/qp47l23n64j5pyd7vllb78c00000gn/T/resolve_config_path_test/a/b/c/jest.config.mjs\`, \`/var/folders/14/qp47l23n64j5pyd7vllb78c00000gn/T/resolve_config_path_test/a/b/c/jest.config.cjs\` and \`/var/folders/14/qp47l23n64j5pyd7vllb78c00000gn/T/resolve_config_path_test/a/b/c/jest.config.json\`. +This is not allowed because it is probably a mistake. + +Configuration Documentation: +https://jestjs.io/docs/configuration.html +" +`; + +exports[` 2`] = ` +"● Multiple configurations found: + +Jest found configuration in \`/var/folders/14/qp47l23n64j5pyd7vllb78c00000gn/T/resolve_config_path_test/a/b/c/jest.config.js\`, \`/var/folders/14/qp47l23n64j5pyd7vllb78c00000gn/T/resolve_config_path_test/a/b/c/jest.config.ts\`, \`/var/folders/14/qp47l23n64j5pyd7vllb78c00000gn/T/resolve_config_path_test/a/b/c/jest.config.mjs\`, \`/var/folders/14/qp47l23n64j5pyd7vllb78c00000gn/T/resolve_config_path_test/a/b/c/jest.config.cjs\` and \`/var/folders/14/qp47l23n64j5pyd7vllb78c00000gn/T/resolve_config_path_test/a/b/c/jest.config.json\`. +This is not allowed because it is probably a mistake. + +Configuration Documentation: +https://jestjs.io/docs/configuration.html +" +`; + +exports[` 3`] = ` +"● Multiple configurations found: + +Jest found configuration in \`/var/folders/14/qp47l23n64j5pyd7vllb78c00000gn/T/resolve_config_path_test/a/b/c/jest.config.js\`, \`/var/folders/14/qp47l23n64j5pyd7vllb78c00000gn/T/resolve_config_path_test/a/b/c/jest.config.ts\`, \`/var/folders/14/qp47l23n64j5pyd7vllb78c00000gn/T/resolve_config_path_test/a/b/c/jest.config.mjs\`, \`/var/folders/14/qp47l23n64j5pyd7vllb78c00000gn/T/resolve_config_path_test/a/b/c/jest.config.cjs\` and \`/var/folders/14/qp47l23n64j5pyd7vllb78c00000gn/T/resolve_config_path_test/a/b/c/jest.config.json\`. +This is not allowed because it is probably a mistake. + +Configuration Documentation: +https://jestjs.io/docs/configuration.html +" +`; + +exports[` 4`] = ` +"● Multiple configurations found: + +Jest found configuration in \`/var/folders/14/qp47l23n64j5pyd7vllb78c00000gn/T/resolve_config_path_test/a/b/c/jest.config.js\`, \`/var/folders/14/qp47l23n64j5pyd7vllb78c00000gn/T/resolve_config_path_test/a/b/c/jest.config.ts\`, \`/var/folders/14/qp47l23n64j5pyd7vllb78c00000gn/T/resolve_config_path_test/a/b/c/jest.config.mjs\`, \`/var/folders/14/qp47l23n64j5pyd7vllb78c00000gn/T/resolve_config_path_test/a/b/c/jest.config.cjs\` and \`/var/folders/14/qp47l23n64j5pyd7vllb78c00000gn/T/resolve_config_path_test/a/b/c/jest.config.json\`. +This is not allowed because it is probably a mistake. + +Configuration Documentation: +https://jestjs.io/docs/configuration.html +" +`; diff --git a/packages/jest-config/src/__tests__/resolveConfigPath.test.ts b/packages/jest-config/src/__tests__/resolveConfigPath.test.ts index a39c5ea43d48..1c5b7c7ebd8d 100644 --- a/packages/jest-config/src/__tests__/resolveConfigPath.test.ts +++ b/packages/jest-config/src/__tests__/resolveConfigPath.test.ts @@ -139,3 +139,23 @@ describe.each(JEST_CONFIG_EXT_ORDER.slice(0))( ); }, ); + +describe.each(JEST_CONFIG_EXT_ORDER.map((_, i) => i + 1).filter(i => i >= 2))( + 'multiple errors has correct snapshot with %s config files', + configCount => { + const usedExtensions = JEST_CONFIG_EXT_ORDER.slice(0, configCount); + const relativeJestConfigPaths = usedExtensions.map( + extension => `a/b/c/jest.config${extension}`, + ); + + relativeJestConfigPaths.forEach(configPath => + writeFiles(DIR, { + [configPath]: '', + }), + ); + + expect(() => + resolveConfigPath(path.dirname(relativeJestConfigPaths[0]), DIR), + ).toThrowErrorMatchingSnapshot(); + }, +); From 02b8ef261a9028639c251731ba83a19b4f9792a0 Mon Sep 17 00:00:00 2001 From: Jan Kaifer Date: Tue, 5 Oct 2021 10:16:05 +0200 Subject: [PATCH 12/39] test: moved snapshots from unit tests to e2e tests --- .../__snapshots__/multipleConfigs.ts.snap | 22 +++++++++ e2e/__tests__/multipleConfigs.ts | 21 +++++++++ e2e/multiple-configs/__tests__/test.js | 10 +++++ e2e/multiple-configs/jest.config.js | 3 ++ e2e/multiple-configs/jest.config.json | 3 ++ e2e/multiple-configs/package.json | 3 ++ .../resolveConfigPath.test.ts.snap | 45 ------------------- .../src/__tests__/resolveConfigPath.test.ts | 20 --------- 8 files changed, 62 insertions(+), 65 deletions(-) create mode 100644 e2e/__tests__/__snapshots__/multipleConfigs.ts.snap create mode 100644 e2e/__tests__/multipleConfigs.ts create mode 100644 e2e/multiple-configs/__tests__/test.js create mode 100644 e2e/multiple-configs/jest.config.js create mode 100644 e2e/multiple-configs/jest.config.json create mode 100644 e2e/multiple-configs/package.json delete mode 100644 packages/jest-config/src/__tests__/__snapshots__/resolveConfigPath.test.ts.snap diff --git a/e2e/__tests__/__snapshots__/multipleConfigs.ts.snap b/e2e/__tests__/__snapshots__/multipleConfigs.ts.snap new file mode 100644 index 000000000000..54e4e49f8d75 --- /dev/null +++ b/e2e/__tests__/__snapshots__/multipleConfigs.ts.snap @@ -0,0 +1,22 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`multiple configs will throw matching error 1`] = ` +"Error: ● Multiple configurations found: + +Jest found configuration in \`/jest.config.js\`, \`/jest.config.json\` and \`/package.json\`. +This is not allowed because it is probably a mistake. + +Configuration Documentation: +https://jestjs.io/docs/configuration.html + + at resolveConfigPathByTraversing (/Users/jankaifer/Projects/jest/packages/jest-config/build/resolveConfigPath.js:130:11) + at _default (/Users/jankaifer/Projects/jest/packages/jest-config/build/resolveConfigPath.js:113:10) + at readConfig (/Users/jankaifer/Projects/jest/packages/jest-config/build/index.js:223:49) + at readConfigs (/Users/jankaifer/Projects/jest/packages/jest-config/build/index.js:414:32) + at runCLI (/Users/jankaifer/Projects/jest/packages/jest-core/build/cli/index.js:133:29) + at Object.run (/Users/jankaifer/Projects/jest/packages/jest-cli/build/cli/index.js:155:62) + at Object. (/Users/jankaifer/Projects/jest/packages/jest-cli/bin/jest.js:16:27) + at Module._compile (internal/modules/cjs/loader.js:1072:14) + at Object.Module._extensions..js (internal/modules/cjs/loader.js:1101:10) + at Module.load (internal/modules/cjs/loader.js:937:32)" +`; diff --git a/e2e/__tests__/multipleConfigs.ts b/e2e/__tests__/multipleConfigs.ts new file mode 100644 index 000000000000..282f5e1c93bd --- /dev/null +++ b/e2e/__tests__/multipleConfigs.ts @@ -0,0 +1,21 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import * as path from 'path'; +import runJest from '../runJest'; + +test('multiple configs will throw matching error', () => { + const rootDir = path.resolve(__dirname, '..', 'multiple-configs'); + const {exitCode, stderr} = runJest(rootDir, ['--show-config'], { + skipPkgJsonCheck: true, + }); + + expect(exitCode).not.toBe(0); + expect( + stderr.replace(new RegExp(rootDir, 'g'), ''), + ).toMatchSnapshot(); +}); diff --git a/e2e/multiple-configs/__tests__/test.js b/e2e/multiple-configs/__tests__/test.js new file mode 100644 index 000000000000..2b4a7ced6f45 --- /dev/null +++ b/e2e/multiple-configs/__tests__/test.js @@ -0,0 +1,10 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. 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. + */ + +test('dummy test', () => { + expect(1).toBe(1); +}); diff --git a/e2e/multiple-configs/jest.config.js b/e2e/multiple-configs/jest.config.js new file mode 100644 index 000000000000..f291b6069887 --- /dev/null +++ b/e2e/multiple-configs/jest.config.js @@ -0,0 +1,3 @@ +exports.default = { + displayName: 'Config from js file', +}; diff --git a/e2e/multiple-configs/jest.config.json b/e2e/multiple-configs/jest.config.json new file mode 100644 index 000000000000..ac2653d362cb --- /dev/null +++ b/e2e/multiple-configs/jest.config.json @@ -0,0 +1,3 @@ +{ + "displayName": "Config from json file" +} diff --git a/e2e/multiple-configs/package.json b/e2e/multiple-configs/package.json new file mode 100644 index 000000000000..586d4ca6b75c --- /dev/null +++ b/e2e/multiple-configs/package.json @@ -0,0 +1,3 @@ +{ + "jest": {} +} diff --git a/packages/jest-config/src/__tests__/__snapshots__/resolveConfigPath.test.ts.snap b/packages/jest-config/src/__tests__/__snapshots__/resolveConfigPath.test.ts.snap deleted file mode 100644 index aa7805c131f1..000000000000 --- a/packages/jest-config/src/__tests__/__snapshots__/resolveConfigPath.test.ts.snap +++ /dev/null @@ -1,45 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[` 1`] = ` -"● Multiple configurations found: - -Jest found configuration in \`/var/folders/14/qp47l23n64j5pyd7vllb78c00000gn/T/resolve_config_path_test/a/b/c/jest.config.js\`, \`/var/folders/14/qp47l23n64j5pyd7vllb78c00000gn/T/resolve_config_path_test/a/b/c/jest.config.ts\`, \`/var/folders/14/qp47l23n64j5pyd7vllb78c00000gn/T/resolve_config_path_test/a/b/c/jest.config.mjs\`, \`/var/folders/14/qp47l23n64j5pyd7vllb78c00000gn/T/resolve_config_path_test/a/b/c/jest.config.cjs\` and \`/var/folders/14/qp47l23n64j5pyd7vllb78c00000gn/T/resolve_config_path_test/a/b/c/jest.config.json\`. -This is not allowed because it is probably a mistake. - -Configuration Documentation: -https://jestjs.io/docs/configuration.html -" -`; - -exports[` 2`] = ` -"● Multiple configurations found: - -Jest found configuration in \`/var/folders/14/qp47l23n64j5pyd7vllb78c00000gn/T/resolve_config_path_test/a/b/c/jest.config.js\`, \`/var/folders/14/qp47l23n64j5pyd7vllb78c00000gn/T/resolve_config_path_test/a/b/c/jest.config.ts\`, \`/var/folders/14/qp47l23n64j5pyd7vllb78c00000gn/T/resolve_config_path_test/a/b/c/jest.config.mjs\`, \`/var/folders/14/qp47l23n64j5pyd7vllb78c00000gn/T/resolve_config_path_test/a/b/c/jest.config.cjs\` and \`/var/folders/14/qp47l23n64j5pyd7vllb78c00000gn/T/resolve_config_path_test/a/b/c/jest.config.json\`. -This is not allowed because it is probably a mistake. - -Configuration Documentation: -https://jestjs.io/docs/configuration.html -" -`; - -exports[` 3`] = ` -"● Multiple configurations found: - -Jest found configuration in \`/var/folders/14/qp47l23n64j5pyd7vllb78c00000gn/T/resolve_config_path_test/a/b/c/jest.config.js\`, \`/var/folders/14/qp47l23n64j5pyd7vllb78c00000gn/T/resolve_config_path_test/a/b/c/jest.config.ts\`, \`/var/folders/14/qp47l23n64j5pyd7vllb78c00000gn/T/resolve_config_path_test/a/b/c/jest.config.mjs\`, \`/var/folders/14/qp47l23n64j5pyd7vllb78c00000gn/T/resolve_config_path_test/a/b/c/jest.config.cjs\` and \`/var/folders/14/qp47l23n64j5pyd7vllb78c00000gn/T/resolve_config_path_test/a/b/c/jest.config.json\`. -This is not allowed because it is probably a mistake. - -Configuration Documentation: -https://jestjs.io/docs/configuration.html -" -`; - -exports[` 4`] = ` -"● Multiple configurations found: - -Jest found configuration in \`/var/folders/14/qp47l23n64j5pyd7vllb78c00000gn/T/resolve_config_path_test/a/b/c/jest.config.js\`, \`/var/folders/14/qp47l23n64j5pyd7vllb78c00000gn/T/resolve_config_path_test/a/b/c/jest.config.ts\`, \`/var/folders/14/qp47l23n64j5pyd7vllb78c00000gn/T/resolve_config_path_test/a/b/c/jest.config.mjs\`, \`/var/folders/14/qp47l23n64j5pyd7vllb78c00000gn/T/resolve_config_path_test/a/b/c/jest.config.cjs\` and \`/var/folders/14/qp47l23n64j5pyd7vllb78c00000gn/T/resolve_config_path_test/a/b/c/jest.config.json\`. -This is not allowed because it is probably a mistake. - -Configuration Documentation: -https://jestjs.io/docs/configuration.html -" -`; diff --git a/packages/jest-config/src/__tests__/resolveConfigPath.test.ts b/packages/jest-config/src/__tests__/resolveConfigPath.test.ts index 1c5b7c7ebd8d..a39c5ea43d48 100644 --- a/packages/jest-config/src/__tests__/resolveConfigPath.test.ts +++ b/packages/jest-config/src/__tests__/resolveConfigPath.test.ts @@ -139,23 +139,3 @@ describe.each(JEST_CONFIG_EXT_ORDER.slice(0))( ); }, ); - -describe.each(JEST_CONFIG_EXT_ORDER.map((_, i) => i + 1).filter(i => i >= 2))( - 'multiple errors has correct snapshot with %s config files', - configCount => { - const usedExtensions = JEST_CONFIG_EXT_ORDER.slice(0, configCount); - const relativeJestConfigPaths = usedExtensions.map( - extension => `a/b/c/jest.config${extension}`, - ); - - relativeJestConfigPaths.forEach(configPath => - writeFiles(DIR, { - [configPath]: '', - }), - ); - - expect(() => - resolveConfigPath(path.dirname(relativeJestConfigPaths[0]), DIR), - ).toThrowErrorMatchingSnapshot(); - }, -); From cd7c9c9badea99d2c563b64d9dd6ef5549256435 Mon Sep 17 00:00:00 2001 From: Jan Kaifer Date: Tue, 5 Oct 2021 10:56:10 +0200 Subject: [PATCH 13/39] test: fixed rootDir replacements in snapshots --- .../__snapshots__/multipleConfigs.ts.snap | 16 ++++++++-------- e2e/__tests__/multipleConfigs.ts | 4 ++-- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/e2e/__tests__/__snapshots__/multipleConfigs.ts.snap b/e2e/__tests__/__snapshots__/multipleConfigs.ts.snap index 54e4e49f8d75..0141817754cc 100644 --- a/e2e/__tests__/__snapshots__/multipleConfigs.ts.snap +++ b/e2e/__tests__/__snapshots__/multipleConfigs.ts.snap @@ -3,19 +3,19 @@ exports[`multiple configs will throw matching error 1`] = ` "Error: ● Multiple configurations found: -Jest found configuration in \`/jest.config.js\`, \`/jest.config.json\` and \`/package.json\`. +Jest found configuration in \`/e2e/multiple-configs/jest.config.js\`, \`/e2e/multiple-configs/jest.config.json\` and \`/e2e/multiple-configs/package.json\`. This is not allowed because it is probably a mistake. Configuration Documentation: https://jestjs.io/docs/configuration.html - at resolveConfigPathByTraversing (/Users/jankaifer/Projects/jest/packages/jest-config/build/resolveConfigPath.js:130:11) - at _default (/Users/jankaifer/Projects/jest/packages/jest-config/build/resolveConfigPath.js:113:10) - at readConfig (/Users/jankaifer/Projects/jest/packages/jest-config/build/index.js:223:49) - at readConfigs (/Users/jankaifer/Projects/jest/packages/jest-config/build/index.js:414:32) - at runCLI (/Users/jankaifer/Projects/jest/packages/jest-core/build/cli/index.js:133:29) - at Object.run (/Users/jankaifer/Projects/jest/packages/jest-cli/build/cli/index.js:155:62) - at Object. (/Users/jankaifer/Projects/jest/packages/jest-cli/bin/jest.js:16:27) + at resolveConfigPathByTraversing (/packages/jest-config/build/resolveConfigPath.js:130:11) + at _default (/packages/jest-config/build/resolveConfigPath.js:113:10) + at readConfig (/packages/jest-config/build/index.js:223:49) + at readConfigs (/packages/jest-config/build/index.js:414:32) + at runCLI (/packages/jest-core/build/cli/index.js:133:29) + at Object.run (/packages/jest-cli/build/cli/index.js:155:62) + at Object. (/packages/jest-cli/bin/jest.js:16:27) at Module._compile (internal/modules/cjs/loader.js:1072:14) at Object.Module._extensions..js (internal/modules/cjs/loader.js:1101:10) at Module.load (internal/modules/cjs/loader.js:937:32)" diff --git a/e2e/__tests__/multipleConfigs.ts b/e2e/__tests__/multipleConfigs.ts index 282f5e1c93bd..fafdee1d9b22 100644 --- a/e2e/__tests__/multipleConfigs.ts +++ b/e2e/__tests__/multipleConfigs.ts @@ -9,8 +9,8 @@ import * as path from 'path'; import runJest from '../runJest'; test('multiple configs will throw matching error', () => { - const rootDir = path.resolve(__dirname, '..', 'multiple-configs'); - const {exitCode, stderr} = runJest(rootDir, ['--show-config'], { + const rootDir = path.resolve(__dirname, '..', '..'); + const {exitCode, stderr} = runJest('multiple-configs', ['--show-config'], { skipPkgJsonCheck: true, }); From 9e13ff22a9a264c11b5dd93b96a9bdbdc5f3f771 Mon Sep 17 00:00:00 2001 From: Jan Kaifer Date: Tue, 5 Oct 2021 11:09:47 +0200 Subject: [PATCH 14/39] Apply suggestions from code review Co-authored-by: Simen Bekkhus --- e2e/__tests__/multipleConfigs.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/e2e/__tests__/multipleConfigs.ts b/e2e/__tests__/multipleConfigs.ts index fafdee1d9b22..af3077e3fc57 100644 --- a/e2e/__tests__/multipleConfigs.ts +++ b/e2e/__tests__/multipleConfigs.ts @@ -14,8 +14,7 @@ test('multiple configs will throw matching error', () => { skipPkgJsonCheck: true, }); - expect(exitCode).not.toBe(0); - expect( - stderr.replace(new RegExp(rootDir, 'g'), ''), - ).toMatchSnapshot(); + expect(exitCode).toBe(1); + const cleanStdErr = stderr.replace(new RegExp(rootDir, 'g'), ''); + expect(wrap(cleanStdErr)).toMatchSnapshot(); }); From f30ab9579c76f736d7603ca505475613df73512e Mon Sep 17 00:00:00 2001 From: Jan Kaifer Date: Tue, 5 Oct 2021 11:10:42 +0200 Subject: [PATCH 15/39] added missing import --- e2e/__tests__/multipleConfigs.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/e2e/__tests__/multipleConfigs.ts b/e2e/__tests__/multipleConfigs.ts index af3077e3fc57..dd9c57075b06 100644 --- a/e2e/__tests__/multipleConfigs.ts +++ b/e2e/__tests__/multipleConfigs.ts @@ -6,6 +6,7 @@ */ import * as path from 'path'; +import {wrap} from 'jest-snapshot-serializer-raw'; import runJest from '../runJest'; test('multiple configs will throw matching error', () => { From b931029af13c26e542e095e2954e3f1b781f1219 Mon Sep 17 00:00:00 2001 From: Jan Kaifer Date: Tue, 5 Oct 2021 11:14:41 +0200 Subject: [PATCH 16/39] Change from CR --- e2e/esm-config/mjs/package.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/e2e/esm-config/mjs/package.json b/e2e/esm-config/mjs/package.json index 0967ef424bce..e230b9436a74 100644 --- a/e2e/esm-config/mjs/package.json +++ b/e2e/esm-config/mjs/package.json @@ -1 +1,3 @@ -{} +{ + "name": "mjs-config" +} From f9c515e96e2747c1b3dbc50ba43c2b7b136da176 Mon Sep 17 00:00:00 2001 From: Jan Kaifer Date: Tue, 5 Oct 2021 11:45:06 +0200 Subject: [PATCH 17/39] improved error message --- .../__snapshots__/multipleConfigs.ts.snap | 12 ++++--- packages/jest-config/src/resolveConfigPath.ts | 32 ++++++------------- 2 files changed, 17 insertions(+), 27 deletions(-) diff --git a/e2e/__tests__/__snapshots__/multipleConfigs.ts.snap b/e2e/__tests__/__snapshots__/multipleConfigs.ts.snap index 0141817754cc..c6f0057f4a05 100644 --- a/e2e/__tests__/__snapshots__/multipleConfigs.ts.snap +++ b/e2e/__tests__/__snapshots__/multipleConfigs.ts.snap @@ -1,14 +1,16 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`multiple configs will throw matching error 1`] = ` -"Error: ● Multiple configurations found: +Error: ● Multiple configurations found: + * \`/e2e/multiple-configs/jest.config.js\` + * \`/e2e/multiple-configs/jest.config.json\` + * \`/e2e/multiple-configs/package.json\` -Jest found configuration in \`/e2e/multiple-configs/jest.config.js\`, \`/e2e/multiple-configs/jest.config.json\` and \`/e2e/multiple-configs/package.json\`. -This is not allowed because it is probably a mistake. +Implicit config resolution does not allow multiple configuration files. +Either remove unused config files or select one explicitly with \`--config\`. Configuration Documentation: https://jestjs.io/docs/configuration.html - at resolveConfigPathByTraversing (/packages/jest-config/build/resolveConfigPath.js:130:11) at _default (/packages/jest-config/build/resolveConfigPath.js:113:10) at readConfig (/packages/jest-config/build/index.js:223:49) @@ -18,5 +20,5 @@ https://jestjs.io/docs/configuration.html at Object. (/packages/jest-cli/bin/jest.js:16:27) at Module._compile (internal/modules/cjs/loader.js:1072:14) at Object.Module._extensions..js (internal/modules/cjs/loader.js:1101:10) - at Module.load (internal/modules/cjs/loader.js:937:32)" + at Module.load (internal/modules/cjs/loader.js:937:32) `; diff --git a/packages/jest-config/src/resolveConfigPath.ts b/packages/jest-config/src/resolveConfigPath.ts index d54dbd509207..27e8ff5e1339 100644 --- a/packages/jest-config/src/resolveConfigPath.ts +++ b/packages/jest-config/src/resolveConfigPath.ts @@ -121,25 +121,13 @@ const makeResolutionErrorMessage = ( ).join(' or ')}.`; const makeMultipleConfigsError = (configPaths: Array) => - '● Multiple configurations found:\n\n' + - `Jest found configuration in ${concatenateWords( - configPaths.map(wrapInBackticks), - )}.\n` + - 'This is not allowed because it is probably a mistake.\n\n' + - 'Configuration Documentation:\n' + - 'https://jestjs.io/docs/configuration.html\n'; - -const wrapInBackticks = (word: string) => `\`${word}\``; - -const concatenateWords = (words: Array): string => { - if (words.length === 0) { - throw new Error('Cannot concatenate an empty array.'); - } else if (words.length <= 2) { - return words.join(' and '); - } else { - return concatenateWords([ - words.slice(0, -1).join(', '), - words[words.length - 1], - ]); - } -}; + [ + '● Multiple configurations found:', + ...configPaths.map(configPath => ` * \`${configPath}\``), + '', + 'Implicit config resolution does not allow multiple configuration files.', + 'Either remove unused config files or select one explicitly with `--config`.', + '', + 'Configuration Documentation:', + 'https://jestjs.io/docs/configuration.html', + ].join('\n'); From 3b1c5b8763949e49a27956c1e9cec701849d3066 Mon Sep 17 00:00:00 2001 From: Jan Kaifer Date: Tue, 5 Oct 2021 11:50:16 +0200 Subject: [PATCH 18/39] added test for --config error surpresion --- e2e/__tests__/multipleConfigs.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/e2e/__tests__/multipleConfigs.ts b/e2e/__tests__/multipleConfigs.ts index dd9c57075b06..6e7e5eb70911 100644 --- a/e2e/__tests__/multipleConfigs.ts +++ b/e2e/__tests__/multipleConfigs.ts @@ -19,3 +19,15 @@ test('multiple configs will throw matching error', () => { const cleanStdErr = stderr.replace(new RegExp(rootDir, 'g'), ''); expect(wrap(cleanStdErr)).toMatchSnapshot(); }); + +test('multiple configs error can be remove by --config', () => { + const {exitCode} = runJest( + 'multiple-configs', + ['--config', 'jest.config.json'], + { + skipPkgJsonCheck: true, + }, + ); + + expect(exitCode).toBe(0); +}); From 02338fdb54ad44a00fd27fe514201ec8a6f0c965 Mon Sep 17 00:00:00 2001 From: Jan Kaifer Date: Tue, 5 Oct 2021 11:54:47 +0200 Subject: [PATCH 19/39] added more real life package.json --- e2e/config-override/package.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/e2e/config-override/package.json b/e2e/config-override/package.json index 0967ef424bce..fecde4600298 100644 --- a/e2e/config-override/package.json +++ b/e2e/config-override/package.json @@ -1 +1,3 @@ -{} +{ + "name": "config-override" +} From 2ce0401d7a5d5a471d5b59bef7a3e2e77e4e7659 Mon Sep 17 00:00:00 2001 From: Jan Kaifer Date: Tue, 5 Oct 2021 15:10:06 +0200 Subject: [PATCH 20/39] added more assertions for multiple config errors --- e2e/__tests__/multipleConfigs.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/e2e/__tests__/multipleConfigs.ts b/e2e/__tests__/multipleConfigs.ts index 6e7e5eb70911..0826973cc2f4 100644 --- a/e2e/__tests__/multipleConfigs.ts +++ b/e2e/__tests__/multipleConfigs.ts @@ -9,6 +9,8 @@ import * as path from 'path'; import {wrap} from 'jest-snapshot-serializer-raw'; import runJest from '../runJest'; +const MULTIPLE_CONFIGS_ERROR_TEXT = 'Multiple configurations found'; + test('multiple configs will throw matching error', () => { const rootDir = path.resolve(__dirname, '..', '..'); const {exitCode, stderr} = runJest('multiple-configs', ['--show-config'], { @@ -16,12 +18,14 @@ test('multiple configs will throw matching error', () => { }); expect(exitCode).toBe(1); + expect(stderr).toContain(MULTIPLE_CONFIGS_ERROR_TEXT); + const cleanStdErr = stderr.replace(new RegExp(rootDir, 'g'), ''); expect(wrap(cleanStdErr)).toMatchSnapshot(); }); test('multiple configs error can be remove by --config', () => { - const {exitCode} = runJest( + const {exitCode, stderr} = runJest( 'multiple-configs', ['--config', 'jest.config.json'], { @@ -30,4 +34,5 @@ test('multiple configs error can be remove by --config', () => { ); expect(exitCode).toBe(0); + expect(stderr).not.toContain(MULTIPLE_CONFIGS_ERROR_TEXT); }); From ac00510db1a1025df824912d39b5ba1b7bf54f81 Mon Sep 17 00:00:00 2001 From: Jan Kaifer Date: Tue, 5 Oct 2021 15:11:28 +0200 Subject: [PATCH 21/39] improved formatting of error message --- e2e/__tests__/__snapshots__/multipleConfigs.ts.snap | 6 +++--- packages/jest-config/src/resolveConfigPath.ts | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/e2e/__tests__/__snapshots__/multipleConfigs.ts.snap b/e2e/__tests__/__snapshots__/multipleConfigs.ts.snap index c6f0057f4a05..7e62ba6246dc 100644 --- a/e2e/__tests__/__snapshots__/multipleConfigs.ts.snap +++ b/e2e/__tests__/__snapshots__/multipleConfigs.ts.snap @@ -2,9 +2,9 @@ exports[`multiple configs will throw matching error 1`] = ` Error: ● Multiple configurations found: - * \`/e2e/multiple-configs/jest.config.js\` - * \`/e2e/multiple-configs/jest.config.json\` - * \`/e2e/multiple-configs/package.json\` + * /e2e/multiple-configs/jest.config.js + * /e2e/multiple-configs/jest.config.json + * /e2e/multiple-configs/package.json Implicit config resolution does not allow multiple configuration files. Either remove unused config files or select one explicitly with \`--config\`. diff --git a/packages/jest-config/src/resolveConfigPath.ts b/packages/jest-config/src/resolveConfigPath.ts index 27e8ff5e1339..4b11623feca4 100644 --- a/packages/jest-config/src/resolveConfigPath.ts +++ b/packages/jest-config/src/resolveConfigPath.ts @@ -123,7 +123,7 @@ const makeResolutionErrorMessage = ( const makeMultipleConfigsError = (configPaths: Array) => [ '● Multiple configurations found:', - ...configPaths.map(configPath => ` * \`${configPath}\``), + ...configPaths.map(configPath => ` * ${configPath}`), '', 'Implicit config resolution does not allow multiple configuration files.', 'Either remove unused config files or select one explicitly with `--config`.', From 82d3e44668326a3b38c1b5e9e77cd63e727301de Mon Sep 17 00:00:00 2001 From: Jan Kaifer Date: Tue, 5 Oct 2021 20:57:27 +0200 Subject: [PATCH 22/39] fixed sample jest configs in e2e tests --- e2e/multiple-configs/jest.config.js | 2 +- e2e/multiple-configs/package.json | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/e2e/multiple-configs/jest.config.js b/e2e/multiple-configs/jest.config.js index f291b6069887..0b6b890a0d60 100644 --- a/e2e/multiple-configs/jest.config.js +++ b/e2e/multiple-configs/jest.config.js @@ -1,3 +1,3 @@ -exports.default = { +module.exports = { displayName: 'Config from js file', }; diff --git a/e2e/multiple-configs/package.json b/e2e/multiple-configs/package.json index 586d4ca6b75c..46e3ee413cc7 100644 --- a/e2e/multiple-configs/package.json +++ b/e2e/multiple-configs/package.json @@ -1,3 +1,5 @@ { - "jest": {} + "jest": { + "displayName": "Config from package.json file" + } } From db8c90cc4503f03e39debb7570dea1c9224fb05a Mon Sep 17 00:00:00 2001 From: Jan Kaifer Date: Tue, 5 Oct 2021 21:18:00 +0200 Subject: [PATCH 23/39] wip: changed from error to warning --- .../__snapshots__/multipleConfigs.ts.snap | 46 +++++++++++-------- e2e/__tests__/multipleConfigs.ts | 17 ++++--- packages/jest-config/src/resolveConfigPath.ts | 14 +++--- 3 files changed, 45 insertions(+), 32 deletions(-) diff --git a/e2e/__tests__/__snapshots__/multipleConfigs.ts.snap b/e2e/__tests__/__snapshots__/multipleConfigs.ts.snap index 7e62ba6246dc..892e2d0b0df1 100644 --- a/e2e/__tests__/__snapshots__/multipleConfigs.ts.snap +++ b/e2e/__tests__/__snapshots__/multipleConfigs.ts.snap @@ -1,24 +1,34 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`multiple configs will throw matching error 1`] = ` -Error: ● Multiple configurations found: - * /e2e/multiple-configs/jest.config.js - * /e2e/multiple-configs/jest.config.json - * /e2e/multiple-configs/package.json +"● Multiple configurations found: + * /e2e/multiple-configs/jest.config.js + * /e2e/multiple-configs/jest.config.json + * /e2e/multiple-configs/package.json -Implicit config resolution does not allow multiple configuration files. -Either remove unused config files or select one explicitly with \`--config\`. + Implicit config resolution does not allow multiple configuration files. + Either remove unused config files or select one explicitly with \`--config\`. + + Configuration Documentation: + https://jestjs.io/docs/configuration.html +● Multiple configurations found: + * /e2e/multiple-configs/jest.config.js + * /e2e/multiple-configs/jest.config.json + * /e2e/multiple-configs/package.json -Configuration Documentation: -https://jestjs.io/docs/configuration.html - at resolveConfigPathByTraversing (/packages/jest-config/build/resolveConfigPath.js:130:11) - at _default (/packages/jest-config/build/resolveConfigPath.js:113:10) - at readConfig (/packages/jest-config/build/index.js:223:49) - at readConfigs (/packages/jest-config/build/index.js:414:32) - at runCLI (/packages/jest-core/build/cli/index.js:133:29) - at Object.run (/packages/jest-cli/build/cli/index.js:155:62) - at Object. (/packages/jest-cli/bin/jest.js:16:27) - at Module._compile (internal/modules/cjs/loader.js:1072:14) - at Object.Module._extensions..js (internal/modules/cjs/loader.js:1101:10) - at Module.load (internal/modules/cjs/loader.js:937:32) + Implicit config resolution does not allow multiple configuration files. + Either remove unused config files or select one explicitly with \`--config\`. + + Configuration Documentation: + https://jestjs.io/docs/configuration.html +PASS Config from js file __tests__/test.js + ✓ dummy test" +`; + +exports[`multiple configs will throw matching error 2`] = ` +"Test Suites: 1 passed, 1 total +Tests: 1 passed, 1 total +Snapshots: 0 total +Time: <> +Ran all test suites." `; diff --git a/e2e/__tests__/multipleConfigs.ts b/e2e/__tests__/multipleConfigs.ts index 0826973cc2f4..aed5a9694f13 100644 --- a/e2e/__tests__/multipleConfigs.ts +++ b/e2e/__tests__/multipleConfigs.ts @@ -6,22 +6,25 @@ */ import * as path from 'path'; -import {wrap} from 'jest-snapshot-serializer-raw'; +import {extractSummary} from '../Utils'; import runJest from '../runJest'; -const MULTIPLE_CONFIGS_ERROR_TEXT = 'Multiple configurations found'; +const MULTIPLE_CONFIGS_WARNING_TEXT = 'Multiple configurations found'; test('multiple configs will throw matching error', () => { const rootDir = path.resolve(__dirname, '..', '..'); - const {exitCode, stderr} = runJest('multiple-configs', ['--show-config'], { + const {exitCode, stderr} = runJest('multiple-configs', [], { skipPkgJsonCheck: true, }); - expect(exitCode).toBe(1); - expect(stderr).toContain(MULTIPLE_CONFIGS_ERROR_TEXT); + expect(exitCode).toBe(0); + expect(stderr).toContain(MULTIPLE_CONFIGS_WARNING_TEXT); const cleanStdErr = stderr.replace(new RegExp(rootDir, 'g'), ''); - expect(wrap(cleanStdErr)).toMatchSnapshot(); + const {rest, summary} = extractSummary(cleanStdErr); + + expect(rest).toMatchSnapshot(); + expect(summary).toMatchSnapshot(); }); test('multiple configs error can be remove by --config', () => { @@ -34,5 +37,5 @@ test('multiple configs error can be remove by --config', () => { ); expect(exitCode).toBe(0); - expect(stderr).not.toContain(MULTIPLE_CONFIGS_ERROR_TEXT); + expect(stderr).not.toContain(MULTIPLE_CONFIGS_WARNING_TEXT); }); diff --git a/packages/jest-config/src/resolveConfigPath.ts b/packages/jest-config/src/resolveConfigPath.ts index 4b11623feca4..5f7e143cd1e8 100644 --- a/packages/jest-config/src/resolveConfigPath.ts +++ b/packages/jest-config/src/resolveConfigPath.ts @@ -67,7 +67,7 @@ const resolveConfigPathByTraversing = ( } if (configFiles.length > 1) { - throw new Error(makeMultipleConfigsError(configFiles)); + console.warn(makeMultipleConfigsWarning(configFiles)); } if (configFiles.length > 0 || packageJson) { @@ -120,14 +120,14 @@ const makeResolutionErrorMessage = ( ext => `"${getConfigFilename(ext)}"`, ).join(' or ')}.`; -const makeMultipleConfigsError = (configPaths: Array) => +const makeMultipleConfigsWarning = (configPaths: Array) => [ '● Multiple configurations found:', - ...configPaths.map(configPath => ` * ${configPath}`), + ...configPaths.map(configPath => ` * ${configPath}`), '', - 'Implicit config resolution does not allow multiple configuration files.', - 'Either remove unused config files or select one explicitly with `--config`.', + ' Implicit config resolution does not allow multiple configuration files.', + ' Either remove unused config files or select one explicitly with `--config`.', '', - 'Configuration Documentation:', - 'https://jestjs.io/docs/configuration.html', + ' Configuration Documentation:', + ' https://jestjs.io/docs/configuration.html', ].join('\n'); From ab05377529c8f2ff04c681e3cda5218b45553e0a Mon Sep 17 00:00:00 2001 From: Jan Kaifer Date: Tue, 5 Oct 2021 22:25:40 +0200 Subject: [PATCH 24/39] fixed unit tests for warning --- .../src/__tests__/resolveConfigPath.test.ts | 105 +++++++++++++----- 1 file changed, 75 insertions(+), 30 deletions(-) diff --git a/packages/jest-config/src/__tests__/resolveConfigPath.test.ts b/packages/jest-config/src/__tests__/resolveConfigPath.test.ts index a39c5ea43d48..7fbe8bebbc6e 100644 --- a/packages/jest-config/src/__tests__/resolveConfigPath.test.ts +++ b/packages/jest-config/src/__tests__/resolveConfigPath.test.ts @@ -16,6 +16,16 @@ const ERROR_PATTERN = /Could not find a config file based on provided values/; const NO_ROOT_DIR_ERROR_PATTERN = /Can't find a root directory/; const MULTIPLE_CONFIGS_ERROR_PATTERN = /Multiple configurations found/; +const mockConsoleWarn = () => { + jest.spyOn(console, 'warn'); + const mockedConsoleWarn = console.warn as jest.Mock>; + + // We will mock console.warn because it would produce a lot of noise in the tests + mockedConsoleWarn.mockImplementation(() => {}); + + return mockedConsoleWarn; +}; + beforeEach(() => cleanup(DIR)); afterEach(() => cleanup(DIR)); @@ -46,6 +56,8 @@ describe.each(JEST_CONFIG_EXT_ORDER.slice(0))( }); test(`directory path with "${extension}"`, () => { + const mockedConsoleWarn = mockConsoleWarn(); + const relativePackageJsonPath = 'a/b/c/package.json'; const absolutePackageJsonPath = path.resolve( DIR, @@ -54,9 +66,9 @@ describe.each(JEST_CONFIG_EXT_ORDER.slice(0))( const relativeJestConfigPath = `a/b/c/jest.config${extension}`; const absoluteJestConfigPath = path.resolve(DIR, relativeJestConfigPath); + // no configs yet. should throw writeFiles(DIR, {[`a/b/c/some_random_file${extension}`]: ''}); - // no configs yet. should throw expect(() => // absolute resolveConfigPath(path.dirname(absoluteJestConfigPath), DIR), @@ -69,6 +81,7 @@ describe.each(JEST_CONFIG_EXT_ORDER.slice(0))( writeFiles(DIR, {[relativePackageJsonPath]: ''}); + mockedConsoleWarn.mockClear(); // absolute expect( resolveConfigPath(path.dirname(absolutePackageJsonPath), DIR), @@ -78,11 +91,12 @@ describe.each(JEST_CONFIG_EXT_ORDER.slice(0))( expect( resolveConfigPath(path.dirname(relativePackageJsonPath), DIR), ).toBe(absolutePackageJsonPath); - - writeFiles(DIR, {[relativeJestConfigPath]: ''}); + expect(mockedConsoleWarn).not.toBeCalled(); // jest.config.js takes precedence + writeFiles(DIR, {[relativeJestConfigPath]: ''}); + mockedConsoleWarn.mockClear(); // absolute expect( resolveConfigPath(path.dirname(absolutePackageJsonPath), DIR), @@ -92,20 +106,30 @@ describe.each(JEST_CONFIG_EXT_ORDER.slice(0))( expect( resolveConfigPath(path.dirname(relativePackageJsonPath), DIR), ).toBe(absoluteJestConfigPath); + expect(mockedConsoleWarn).not.toBeCalled(); // jest.config.js and package.json with 'jest' cannot be used together - writeFiles(DIR, {[relativePackageJsonPath]: JSON.stringify({jest: {}})}); // absolute - expect(() => + mockedConsoleWarn.mockClear(); + expect( resolveConfigPath(path.dirname(absolutePackageJsonPath), DIR), - ).toThrowError(MULTIPLE_CONFIGS_ERROR_PATTERN); + ).toBe(absoluteJestConfigPath); + expect(mockedConsoleWarn).toBeCalledTimes(1); + expect(mockedConsoleWarn.mock.calls[0].join()).toMatch( + MULTIPLE_CONFIGS_ERROR_PATTERN, + ); // relative - expect(() => + mockedConsoleWarn.mockClear(); + expect( resolveConfigPath(path.dirname(relativePackageJsonPath), DIR), - ).toThrowError(MULTIPLE_CONFIGS_ERROR_PATTERN); + ).toBe(absoluteJestConfigPath); + expect(mockedConsoleWarn).toBeCalledTimes(1); + expect(mockedConsoleWarn.mock.calls[0].join()).toMatch( + MULTIPLE_CONFIGS_ERROR_PATTERN, + ); expect(() => { resolveConfigPath( @@ -114,28 +138,49 @@ describe.each(JEST_CONFIG_EXT_ORDER.slice(0))( ); }).toThrowError(NO_ROOT_DIR_ERROR_PATTERN); }); + }, +); - describe.each(JEST_CONFIG_EXT_ORDER.slice(0))( - `jest.config.%s and jest.config${extension}`, - extension2 => { - if (extension === extension2) return; - - const relativeJestConfigPaths = [ - `a/b/c/jest.config${extension}`, - `a/b/c/jest.config${extension2}`, - ]; - - writeFiles(DIR, { - [relativeJestConfigPaths[0]]: '', - [relativeJestConfigPaths[1]]: '', - }); - - // multiple configs here, should throw - - expect(() => - resolveConfigPath(path.dirname(relativeJestConfigPaths[0]), DIR), - ).toThrowError(MULTIPLE_CONFIGS_ERROR_PATTERN); - }, - ); +const pickPairsWithSameOrder = (array: ReadonlyArray) => + array + .map((value1, idx, arr) => + arr.slice(idx + 1).map(value2 => [value1, value2]), + ) + .flat(); + +test('pickPairsWithSameOrder', () => { + expect(pickPairsWithSameOrder([1, 2, 3])).toStrictEqual([ + [1, 2], + [1, 3], + [2, 3], + ]); +}); + +describe.each(pickPairsWithSameOrder(JEST_CONFIG_EXT_ORDER))( + 'Using multiple configs shows warning', + (extension1, extension2) => { + test(`Using jest.config${extension1} and jest.config${extension2} shows warning`, () => { + const mockedConsoleWarn = mockConsoleWarn(); + + const relativeJestConfigPaths = [ + `a/b/c/jest.config${extension1}`, + `a/b/c/jest.config${extension2}`, + ]; + + writeFiles(DIR, { + [relativeJestConfigPaths[0]]: '', + [relativeJestConfigPaths[1]]: '', + }); + + // multiple configs here, should print warning + mockedConsoleWarn.mockClear(); + expect( + resolveConfigPath(path.dirname(relativeJestConfigPaths[0]), DIR), + ).toBe(path.resolve(DIR, relativeJestConfigPaths[0])); + expect(mockedConsoleWarn).toBeCalledTimes(1); + expect(mockedConsoleWarn.mock.calls[0].join()).toMatch( + MULTIPLE_CONFIGS_ERROR_PATTERN, + ); + }); }, ); From df0f3a56a1d90aaeacf11240551a32d4031cc716 Mon Sep 17 00:00:00 2001 From: Jan Kaifer Date: Tue, 5 Oct 2021 22:28:52 +0200 Subject: [PATCH 25/39] updated snapshots --- e2e/__tests__/__snapshots__/multipleConfigs.ts.snap | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/e2e/__tests__/__snapshots__/multipleConfigs.ts.snap b/e2e/__tests__/__snapshots__/multipleConfigs.ts.snap index 892e2d0b0df1..4b7f2e4aa0ed 100644 --- a/e2e/__tests__/__snapshots__/multipleConfigs.ts.snap +++ b/e2e/__tests__/__snapshots__/multipleConfigs.ts.snap @@ -8,7 +8,7 @@ exports[`multiple configs will throw matching error 1`] = ` Implicit config resolution does not allow multiple configuration files. Either remove unused config files or select one explicitly with \`--config\`. - + Configuration Documentation: https://jestjs.io/docs/configuration.html ● Multiple configurations found: @@ -18,7 +18,7 @@ exports[`multiple configs will throw matching error 1`] = ` Implicit config resolution does not allow multiple configuration files. Either remove unused config files or select one explicitly with \`--config\`. - + Configuration Documentation: https://jestjs.io/docs/configuration.html PASS Config from js file __tests__/test.js From 1f17accad8e94834e24ee0d9b2694225afb90cb3 Mon Sep 17 00:00:00 2001 From: Simen Bekkhus Date: Wed, 6 Oct 2021 09:08:27 +0200 Subject: [PATCH 26/39] Update CHANGELOG.md --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 828a9175cba3..5e4bfd0c3747 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ### Features +- `[jest-config]` Warn when multiple Jest configs are located ([#11922](https://github.com/facebook/jest/pull/11922)) + ### Fixes - `[@jest/types]` Mark deprecated configuration options as `@deprecated` ([#11913](https://github.com/facebook/jest/pull/11913)) From 2d6efff7632df8d875f92b6a8d34f3595e87d87a Mon Sep 17 00:00:00 2001 From: Jan Kaifer Date: Wed, 6 Oct 2021 09:50:47 +0200 Subject: [PATCH 27/39] Update packages/jest-config/src/resolveConfigPath.ts Co-authored-by: Simen Bekkhus --- packages/jest-config/src/resolveConfigPath.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/jest-config/src/resolveConfigPath.ts b/packages/jest-config/src/resolveConfigPath.ts index 5f7e143cd1e8..2dc1aa0dfe12 100644 --- a/packages/jest-config/src/resolveConfigPath.ts +++ b/packages/jest-config/src/resolveConfigPath.ts @@ -123,7 +123,7 @@ const makeResolutionErrorMessage = ( const makeMultipleConfigsWarning = (configPaths: Array) => [ '● Multiple configurations found:', - ...configPaths.map(configPath => ` * ${configPath}`), + ...configPaths.map(configPath => ` * ${slash(configPath)}`), '', ' Implicit config resolution does not allow multiple configuration files.', ' Either remove unused config files or select one explicitly with `--config`.', From 7727e74b2d1a30aadc4417f4ec080e82cc23837c Mon Sep 17 00:00:00 2001 From: Simen Bekkhus Date: Wed, 6 Oct 2021 10:18:04 +0200 Subject: [PATCH 28/39] add slash import --- packages/jest-config/src/resolveConfigPath.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/jest-config/src/resolveConfigPath.ts b/packages/jest-config/src/resolveConfigPath.ts index 2dc1aa0dfe12..32dac25ae816 100644 --- a/packages/jest-config/src/resolveConfigPath.ts +++ b/packages/jest-config/src/resolveConfigPath.ts @@ -7,6 +7,7 @@ import * as path from 'path'; import * as fs from 'graceful-fs'; +import slash = require('slash'); import type {Config} from '@jest/types'; import { JEST_CONFIG_BASE_NAME, From 9926edf273f2b33723c48f016899b528a9035d8a Mon Sep 17 00:00:00 2001 From: Simen Bekkhus Date: Wed, 6 Oct 2021 10:19:32 +0200 Subject: [PATCH 29/39] no flat in node 10 --- packages/jest-config/src/__tests__/resolveConfigPath.test.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/jest-config/src/__tests__/resolveConfigPath.test.ts b/packages/jest-config/src/__tests__/resolveConfigPath.test.ts index 7fbe8bebbc6e..96db06c9213b 100644 --- a/packages/jest-config/src/__tests__/resolveConfigPath.test.ts +++ b/packages/jest-config/src/__tests__/resolveConfigPath.test.ts @@ -146,7 +146,8 @@ const pickPairsWithSameOrder = (array: ReadonlyArray) => .map((value1, idx, arr) => arr.slice(idx + 1).map(value2 => [value1, value2]), ) - .flat(); + // TODO: use .flat() when we drop Node 10 + .reduce((acc, val) => acc.concat(val), []); test('pickPairsWithSameOrder', () => { expect(pickPairsWithSameOrder([1, 2, 3])).toStrictEqual([ From 91655cecbe71db5c45e2e7f5d8bb38e7412a3a3c Mon Sep 17 00:00:00 2001 From: Simen Bekkhus Date: Wed, 6 Oct 2021 10:20:30 +0200 Subject: [PATCH 30/39] rename tests --- e2e/__tests__/__snapshots__/multipleConfigs.ts.snap | 4 ++-- e2e/__tests__/multipleConfigs.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/e2e/__tests__/__snapshots__/multipleConfigs.ts.snap b/e2e/__tests__/__snapshots__/multipleConfigs.ts.snap index 4b7f2e4aa0ed..0c37768c8bef 100644 --- a/e2e/__tests__/__snapshots__/multipleConfigs.ts.snap +++ b/e2e/__tests__/__snapshots__/multipleConfigs.ts.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`multiple configs will throw matching error 1`] = ` +exports[`multiple configs will warn 1`] = ` "● Multiple configurations found: * /e2e/multiple-configs/jest.config.js * /e2e/multiple-configs/jest.config.json @@ -25,7 +25,7 @@ PASS Config from js file __tests__/test.js ✓ dummy test" `; -exports[`multiple configs will throw matching error 2`] = ` +exports[`multiple configs will warn 2`] = ` "Test Suites: 1 passed, 1 total Tests: 1 passed, 1 total Snapshots: 0 total diff --git a/e2e/__tests__/multipleConfigs.ts b/e2e/__tests__/multipleConfigs.ts index aed5a9694f13..6988d96e4e09 100644 --- a/e2e/__tests__/multipleConfigs.ts +++ b/e2e/__tests__/multipleConfigs.ts @@ -11,7 +11,7 @@ import runJest from '../runJest'; const MULTIPLE_CONFIGS_WARNING_TEXT = 'Multiple configurations found'; -test('multiple configs will throw matching error', () => { +test('multiple configs will warn', () => { const rootDir = path.resolve(__dirname, '..', '..'); const {exitCode, stderr} = runJest('multiple-configs', [], { skipPkgJsonCheck: true, @@ -27,7 +27,7 @@ test('multiple configs will throw matching error', () => { expect(summary).toMatchSnapshot(); }); -test('multiple configs error can be remove by --config', () => { +test('multiple configs warning can be suppressed by using --config', () => { const {exitCode, stderr} = runJest( 'multiple-configs', ['--config', 'jest.config.json'], From d60356f675a3e8053bd326aeee6d4405ad990767 Mon Sep 17 00:00:00 2001 From: Simen Bekkhus Date: Wed, 6 Oct 2021 10:22:25 +0200 Subject: [PATCH 31/39] slash path in e2e test as well --- e2e/__tests__/multipleConfigs.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/e2e/__tests__/multipleConfigs.ts b/e2e/__tests__/multipleConfigs.ts index 6988d96e4e09..84644f94a59f 100644 --- a/e2e/__tests__/multipleConfigs.ts +++ b/e2e/__tests__/multipleConfigs.ts @@ -6,13 +6,14 @@ */ import * as path from 'path'; +import slash = require('slash'); import {extractSummary} from '../Utils'; import runJest from '../runJest'; const MULTIPLE_CONFIGS_WARNING_TEXT = 'Multiple configurations found'; test('multiple configs will warn', () => { - const rootDir = path.resolve(__dirname, '..', '..'); + const rootDir = slash(path.resolve(__dirname, '../..')); const {exitCode, stderr} = runJest('multiple-configs', [], { skipPkgJsonCheck: true, }); From 6a5263449fe96c11aba9b23a2a85252ac35a279e Mon Sep 17 00:00:00 2001 From: Simen Bekkhus Date: Wed, 6 Oct 2021 10:30:58 +0200 Subject: [PATCH 32/39] skip duplicate warning --- .../__snapshots__/multipleConfigs.ts.snap | 9 --------- packages/jest-config/src/index.ts | 15 +++++++++++++-- packages/jest-config/src/resolveConfigPath.ts | 18 +++++++++++++++--- 3 files changed, 28 insertions(+), 14 deletions(-) diff --git a/e2e/__tests__/__snapshots__/multipleConfigs.ts.snap b/e2e/__tests__/__snapshots__/multipleConfigs.ts.snap index 0c37768c8bef..173bba9ed43d 100644 --- a/e2e/__tests__/__snapshots__/multipleConfigs.ts.snap +++ b/e2e/__tests__/__snapshots__/multipleConfigs.ts.snap @@ -11,16 +11,7 @@ exports[`multiple configs will warn 1`] = ` Configuration Documentation: https://jestjs.io/docs/configuration.html -● Multiple configurations found: - * /e2e/multiple-configs/jest.config.js - * /e2e/multiple-configs/jest.config.json - * /e2e/multiple-configs/package.json - - Implicit config resolution does not allow multiple configuration files. - Either remove unused config files or select one explicitly with \`--config\`. - Configuration Documentation: - https://jestjs.io/docs/configuration.html PASS Config from js file __tests__/test.js ✓ dummy test" `; diff --git a/packages/jest-config/src/index.ts b/packages/jest-config/src/index.ts index 364346ecf954..f9b4c8456218 100644 --- a/packages/jest-config/src/index.ts +++ b/packages/jest-config/src/index.ts @@ -44,6 +44,7 @@ export async function readConfig( skipArgvConfigOption?: boolean, parentConfigDirname?: Config.Path | null, projectIndex: number = Infinity, + skipMultipleConfigWarning = false, ): Promise { let rawOptions: Config.InitialOptions; let configPath = null; @@ -77,11 +78,19 @@ export async function readConfig( // A string passed to `--config`, which is either a direct path to the config // or a path to directory containing `package.json`, `jest.config.js` or `jest.config.ts` } else if (!skipArgvConfigOption && typeof argv.config == 'string') { - configPath = resolveConfigPath(argv.config, process.cwd()); + configPath = resolveConfigPath( + argv.config, + process.cwd(), + skipMultipleConfigWarning, + ); rawOptions = await readConfigFileAndSetRootDir(configPath); } else { // Otherwise just try to find config in the current rootDir. - configPath = resolveConfigPath(packageRootOrConfig, process.cwd()); + configPath = resolveConfigPath( + packageRootOrConfig, + process.cwd(), + skipMultipleConfigWarning, + ); rawOptions = await readConfigFileAndSetRootDir(configPath); } @@ -332,6 +341,8 @@ export async function readConfigs( skipArgvConfigOption, configPath ? path.dirname(configPath) : cwd, projectIndex, + // we wanna skip the warning if this is the "main" project + projectIsCwd, ); }), ); diff --git a/packages/jest-config/src/resolveConfigPath.ts b/packages/jest-config/src/resolveConfigPath.ts index 32dac25ae816..802440c123e7 100644 --- a/packages/jest-config/src/resolveConfigPath.ts +++ b/packages/jest-config/src/resolveConfigPath.ts @@ -20,7 +20,11 @@ const isFile = (filePath: Config.Path) => const getConfigFilename = (ext: string) => JEST_CONFIG_BASE_NAME + ext; -export default (pathToResolve: Config.Path, cwd: Config.Path): Config.Path => { +export default ( + pathToResolve: Config.Path, + cwd: Config.Path, + skipMultipleConfigWarning: boolean, +): Config.Path => { if (!path.isAbsolute(cwd)) { throw new Error(`"cwd" must be an absolute path. cwd: ${cwd}`); } @@ -50,13 +54,19 @@ export default (pathToResolve: Config.Path, cwd: Config.Path): Config.Path => { ); } - return resolveConfigPathByTraversing(absolutePath, pathToResolve, cwd); + return resolveConfigPathByTraversing( + absolutePath, + pathToResolve, + cwd, + skipMultipleConfigWarning, + ); }; const resolveConfigPathByTraversing = ( pathToResolve: Config.Path, initialPath: Config.Path, cwd: Config.Path, + skipMultipleConfigWarning: boolean, ): Config.Path => { const configFiles = JEST_CONFIG_EXT_ORDER.map(ext => path.resolve(pathToResolve, getConfigFilename(ext)), @@ -67,7 +77,7 @@ const resolveConfigPathByTraversing = ( configFiles.push(packageJson); } - if (configFiles.length > 1) { + if (!skipMultipleConfigWarning && configFiles.length > 1) { console.warn(makeMultipleConfigsWarning(configFiles)); } @@ -86,6 +96,7 @@ const resolveConfigPathByTraversing = ( path.dirname(pathToResolve), initialPath, cwd, + skipMultipleConfigWarning, ); }; @@ -131,4 +142,5 @@ const makeMultipleConfigsWarning = (configPaths: Array) => '', ' Configuration Documentation:', ' https://jestjs.io/docs/configuration.html', + '', ].join('\n'); From 3505a2c1822ad805b9acd5f3242f6e79647c6451 Mon Sep 17 00:00:00 2001 From: Simen Bekkhus Date: Wed, 6 Oct 2021 10:33:20 +0200 Subject: [PATCH 33/39] add copyright header --- e2e/multiple-configs/jest.config.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/e2e/multiple-configs/jest.config.js b/e2e/multiple-configs/jest.config.js index 0b6b890a0d60..a2876a6ef5e6 100644 --- a/e2e/multiple-configs/jest.config.js +++ b/e2e/multiple-configs/jest.config.js @@ -1,3 +1,10 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. 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. + */ + module.exports = { displayName: 'Config from js file', }; From 80e52de462575e4eb2e3e41af664c4a54436f12c Mon Sep 17 00:00:00 2001 From: Simen Bekkhus Date: Wed, 6 Oct 2021 10:37:16 +0200 Subject: [PATCH 34/39] make warning yellow --- packages/jest-config/src/resolveConfigPath.ts | 25 +++++++++++-------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/packages/jest-config/src/resolveConfigPath.ts b/packages/jest-config/src/resolveConfigPath.ts index 802440c123e7..b4d329afc33a 100644 --- a/packages/jest-config/src/resolveConfigPath.ts +++ b/packages/jest-config/src/resolveConfigPath.ts @@ -6,6 +6,7 @@ */ import * as path from 'path'; +import chalk = require('chalk'); import * as fs from 'graceful-fs'; import slash = require('slash'); import type {Config} from '@jest/types'; @@ -133,14 +134,16 @@ const makeResolutionErrorMessage = ( ).join(' or ')}.`; const makeMultipleConfigsWarning = (configPaths: Array) => - [ - '● Multiple configurations found:', - ...configPaths.map(configPath => ` * ${slash(configPath)}`), - '', - ' Implicit config resolution does not allow multiple configuration files.', - ' Either remove unused config files or select one explicitly with `--config`.', - '', - ' Configuration Documentation:', - ' https://jestjs.io/docs/configuration.html', - '', - ].join('\n'); + chalk.yellow( + [ + chalk.bold('\u25cf Multiple configurations found:'), + ...configPaths.map(configPath => ` * ${slash(configPath)}`), + '', + ' Implicit config resolution does not allow multiple configuration files.', + ' Either remove unused config files or select one explicitly with `--config`.', + '', + ' Configuration Documentation:', + ' https://jestjs.io/docs/configuration.html', + '', + ].join('\n'), + ); From 8abb1c1d1ce355bf435f3413ee87240ae1943ee2 Mon Sep 17 00:00:00 2001 From: Simen Bekkhus Date: Wed, 6 Oct 2021 10:54:36 +0200 Subject: [PATCH 35/39] specify key in pkg.json --- e2e/__tests__/__snapshots__/multipleConfigs.ts.snap | 2 +- packages/jest-config/src/resolveConfigPath.ts | 13 ++++++++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/e2e/__tests__/__snapshots__/multipleConfigs.ts.snap b/e2e/__tests__/__snapshots__/multipleConfigs.ts.snap index 173bba9ed43d..3805df0c73fb 100644 --- a/e2e/__tests__/__snapshots__/multipleConfigs.ts.snap +++ b/e2e/__tests__/__snapshots__/multipleConfigs.ts.snap @@ -4,7 +4,7 @@ exports[`multiple configs will warn 1`] = ` "● Multiple configurations found: * /e2e/multiple-configs/jest.config.js * /e2e/multiple-configs/jest.config.json - * /e2e/multiple-configs/package.json + * \`jest\` key in /e2e/multiple-configs/package.json Implicit config resolution does not allow multiple configuration files. Either remove unused config files or select one explicitly with \`--config\`. diff --git a/packages/jest-config/src/resolveConfigPath.ts b/packages/jest-config/src/resolveConfigPath.ts index b4d329afc33a..d441fa4b62a9 100644 --- a/packages/jest-config/src/resolveConfigPath.ts +++ b/packages/jest-config/src/resolveConfigPath.ts @@ -133,11 +133,22 @@ const makeResolutionErrorMessage = ( ext => `"${getConfigFilename(ext)}"`, ).join(' or ')}.`; +function extraIfPackageJson(configPath: Config.Path) { + if (configPath.endsWith('package.json')) { + return '`jest` key in '; + } + + return ''; +} + const makeMultipleConfigsWarning = (configPaths: Array) => chalk.yellow( [ chalk.bold('\u25cf Multiple configurations found:'), - ...configPaths.map(configPath => ` * ${slash(configPath)}`), + ...configPaths.map( + configPath => + ` * ${extraIfPackageJson(configPath)}${slash(configPath)}`, + ), '', ' Implicit config resolution does not allow multiple configuration files.', ' Either remove unused config files or select one explicitly with `--config`.', From 746f35303f9421bfd7011cba9cfcfe68ddcb9670 Mon Sep 17 00:00:00 2001 From: Simen Bekkhus Date: Wed, 6 Oct 2021 10:55:32 +0200 Subject: [PATCH 36/39] use wrap --- e2e/__tests__/__snapshots__/multipleConfigs.ts.snap | 8 ++++---- e2e/__tests__/multipleConfigs.ts | 5 +++-- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/e2e/__tests__/__snapshots__/multipleConfigs.ts.snap b/e2e/__tests__/__snapshots__/multipleConfigs.ts.snap index 3805df0c73fb..ae086ee790db 100644 --- a/e2e/__tests__/__snapshots__/multipleConfigs.ts.snap +++ b/e2e/__tests__/__snapshots__/multipleConfigs.ts.snap @@ -1,7 +1,7 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`multiple configs will warn 1`] = ` -"● Multiple configurations found: +● Multiple configurations found: * /e2e/multiple-configs/jest.config.js * /e2e/multiple-configs/jest.config.json * \`jest\` key in /e2e/multiple-configs/package.json @@ -13,13 +13,13 @@ exports[`multiple configs will warn 1`] = ` https://jestjs.io/docs/configuration.html PASS Config from js file __tests__/test.js - ✓ dummy test" + ✓ dummy test `; exports[`multiple configs will warn 2`] = ` -"Test Suites: 1 passed, 1 total +Test Suites: 1 passed, 1 total Tests: 1 passed, 1 total Snapshots: 0 total Time: <> -Ran all test suites." +Ran all test suites. `; diff --git a/e2e/__tests__/multipleConfigs.ts b/e2e/__tests__/multipleConfigs.ts index 84644f94a59f..305140510bc3 100644 --- a/e2e/__tests__/multipleConfigs.ts +++ b/e2e/__tests__/multipleConfigs.ts @@ -6,6 +6,7 @@ */ import * as path from 'path'; +import {wrap} from 'jest-snapshot-serializer-raw'; import slash = require('slash'); import {extractSummary} from '../Utils'; import runJest from '../runJest'; @@ -24,8 +25,8 @@ test('multiple configs will warn', () => { const cleanStdErr = stderr.replace(new RegExp(rootDir, 'g'), ''); const {rest, summary} = extractSummary(cleanStdErr); - expect(rest).toMatchSnapshot(); - expect(summary).toMatchSnapshot(); + expect(wrap(rest)).toMatchSnapshot(); + expect(wrap(summary)).toMatchSnapshot(); }); test('multiple configs warning can be suppressed by using --config', () => { From cae826c3bfd182a449c3dca777b84ec2fe2e0e77 Mon Sep 17 00:00:00 2001 From: Jan Kaifer Date: Wed, 6 Oct 2021 10:58:11 +0200 Subject: [PATCH 37/39] removed hardcoded filename --- packages/jest-config/src/resolveConfigPath.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/jest-config/src/resolveConfigPath.ts b/packages/jest-config/src/resolveConfigPath.ts index d441fa4b62a9..57f684c8dfde 100644 --- a/packages/jest-config/src/resolveConfigPath.ts +++ b/packages/jest-config/src/resolveConfigPath.ts @@ -134,7 +134,7 @@ const makeResolutionErrorMessage = ( ).join(' or ')}.`; function extraIfPackageJson(configPath: Config.Path) { - if (configPath.endsWith('package.json')) { + if (configPath.endsWith(PACKAGE_JSON)) { return '`jest` key in '; } From 1de582b3ade4e06e6151bdd0df1c402c0227aa7e Mon Sep 17 00:00:00 2001 From: Jan Kaifer Date: Wed, 6 Oct 2021 11:17:53 +0200 Subject: [PATCH 38/39] made skipMultipleConfigWarning optional --- packages/jest-config/src/resolveConfigPath.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/jest-config/src/resolveConfigPath.ts b/packages/jest-config/src/resolveConfigPath.ts index 57f684c8dfde..29e5a7056dba 100644 --- a/packages/jest-config/src/resolveConfigPath.ts +++ b/packages/jest-config/src/resolveConfigPath.ts @@ -24,7 +24,7 @@ const getConfigFilename = (ext: string) => JEST_CONFIG_BASE_NAME + ext; export default ( pathToResolve: Config.Path, cwd: Config.Path, - skipMultipleConfigWarning: boolean, + skipMultipleConfigWarning: boolean = false, ): Config.Path => { if (!path.isAbsolute(cwd)) { throw new Error(`"cwd" must be an absolute path. cwd: ${cwd}`); From b57cbf5549f9ec26960afc75aa90b9a6a0619b26 Mon Sep 17 00:00:00 2001 From: Simen Bekkhus Date: Wed, 6 Oct 2021 12:03:10 +0200 Subject: [PATCH 39/39] Update packages/jest-config/src/resolveConfigPath.ts --- packages/jest-config/src/resolveConfigPath.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/jest-config/src/resolveConfigPath.ts b/packages/jest-config/src/resolveConfigPath.ts index 29e5a7056dba..0f1439197a36 100644 --- a/packages/jest-config/src/resolveConfigPath.ts +++ b/packages/jest-config/src/resolveConfigPath.ts @@ -24,7 +24,7 @@ const getConfigFilename = (ext: string) => JEST_CONFIG_BASE_NAME + ext; export default ( pathToResolve: Config.Path, cwd: Config.Path, - skipMultipleConfigWarning: boolean = false, + skipMultipleConfigWarning = false, ): Config.Path => { if (!path.isAbsolute(cwd)) { throw new Error(`"cwd" must be an absolute path. cwd: ${cwd}`);