From 50d2cc188e68556d448333cb2ade575655c13645 Mon Sep 17 00:00:00 2001 From: Simen Bekkhus Date: Sun, 19 Jan 2020 19:35:34 +0100 Subject: [PATCH 1/9] feat: add support for .mjs config --- CHANGELOG.md | 1 + babel.config.js | 16 ++ e2e/__tests__/cjsConfigFile.test.ts | 21 -- e2e/__tests__/esmConfigFile.test.ts | 38 ++++ .../cjs}/__tests__/test.js | 0 .../cjs}/jest.config.cjs | 0 .../cjs}/package.json | 0 e2e/esm-config/mjs/__tests__/test.js | 10 + e2e/esm-config/mjs/jest.config.mjs | 11 + e2e/esm-config/mjs/package.json | 3 + .../__tests__/__snapshots__/init.test.js.snap | 201 ++++++++++++++++++ .../has_jest_config_file_mjs/jest.config.mjs | 8 + .../has_jest_config_file_mjs/package.json | 1 + .../fixtures/type_module/package.json | 7 + .../jest-cli/src/init/__tests__/init.test.js | 19 +- packages/jest-cli/src/init/constants.ts | 17 -- .../jest-cli/src/init/generate_config_file.ts | 7 +- packages/jest-cli/src/init/index.ts | 24 ++- packages/jest-config/src/constants.ts | 2 + packages/jest-config/src/index.ts | 73 ++++--- .../src/readConfigFileAndSetRootDir.ts | 53 +++-- packages/jest-core/src/cli/index.ts | 2 +- packages/jest-runtime/src/cli/index.ts | 46 ++-- 23 files changed, 441 insertions(+), 119 deletions(-) delete mode 100644 e2e/__tests__/cjsConfigFile.test.ts create mode 100644 e2e/__tests__/esmConfigFile.test.ts rename e2e/{cjs-config => esm-config/cjs}/__tests__/test.js (100%) rename e2e/{cjs-config => esm-config/cjs}/jest.config.cjs (100%) rename e2e/{cjs-config => esm-config/cjs}/package.json (100%) create mode 100644 e2e/esm-config/mjs/__tests__/test.js create mode 100644 e2e/esm-config/mjs/jest.config.mjs create mode 100644 e2e/esm-config/mjs/package.json create mode 100644 packages/jest-cli/src/init/__tests__/fixtures/has_jest_config_file_mjs/jest.config.mjs create mode 100644 packages/jest-cli/src/init/__tests__/fixtures/has_jest_config_file_mjs/package.json create mode 100644 packages/jest-cli/src/init/__tests__/fixtures/type_module/package.json delete mode 100644 packages/jest-cli/src/init/constants.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index b2a023fa86dd..2d617f54617b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ - `[jest-config]` [**BREAKING**] Set default display name color based on runner ([#8689](https://github.com/facebook/jest/pull/8689)) - `[jest-config]` Merge preset globals with project globals ([#9027](https://github.com/facebook/jest/pull/9027)) - `[jest-config]` Support `.cjs` config files ([#9291](https://github.com/facebook/jest/pull/9291)) +- `[jest-config]` [**BREAKING**] Support `.mjs` config files ([#9431](https://github.com/facebook/jest/pull/9431)) - `[jest-core]` Support reporters as default exports ([#9161](https://github.com/facebook/jest/pull/9161)) - `[jest-core]` Support `--findRelatedTests` paths case insensitivity on Windows ([#8900](https://github.com/facebook/jest/issues/8900)) - `[jest-diff]` Add options for colors and symbols ([#8841](https://github.com/facebook/jest/pull/8841)) diff --git a/babel.config.js b/babel.config.js index 1269fe3b0744..20a40063a2fb 100644 --- a/babel.config.js +++ b/babel.config.js @@ -19,6 +19,22 @@ module.exports = { presets: ['@babel/preset-typescript'], test: /\.tsx?$/, }, + // we want this file to keep `import()`, so exclude the transform for it + { + plugins: ['@babel/plugin-syntax-dynamic-import'], + presets: [ + '@babel/preset-typescript', + [ + '@babel/preset-env', + { + exclude: ['@babel/plugin-proposal-dynamic-import'], + shippedProposals: true, + targets: {node: 8}, + }, + ], + ], + test: 'packages/jest-config/src/readConfigFileAndSetRootDir.ts', + }, ], plugins: [ ['@babel/plugin-transform-modules-commonjs', {allowTopLevelThis: true}], diff --git a/e2e/__tests__/cjsConfigFile.test.ts b/e2e/__tests__/cjsConfigFile.test.ts deleted file mode 100644 index 9c6b1345ef4e..000000000000 --- a/e2e/__tests__/cjsConfigFile.test.ts +++ /dev/null @@ -1,21 +0,0 @@ -/** - * 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 {json as runWithJson} from '../runJest'; - -test('reads config from cjs file', () => { - const {json, exitCode} = runWithJson('cjs-config', ['--show-config'], { - skipPkgJsonCheck: true, - }); - - expect(exitCode).toBe(0); - expect(json.configs).toHaveLength(1); - expect(json.configs[0].displayName).toEqual({ - color: 'white', - name: 'Config from cjs file', - }); -}); diff --git a/e2e/__tests__/esmConfigFile.test.ts b/e2e/__tests__/esmConfigFile.test.ts new file mode 100644 index 000000000000..dde3552cbd8b --- /dev/null +++ b/e2e/__tests__/esmConfigFile.test.ts @@ -0,0 +1,38 @@ +/** + * 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 {onNodeVersions} from '@jest/test-utils'; +import {json as runWithJson} from '../runJest'; + +test('reads config from cjs file', () => { + const {json, exitCode} = runWithJson('esm-config/cjs', ['--show-config'], { + skipPkgJsonCheck: true, + }); + + expect(exitCode).toBe(0); + expect(json.configs).toHaveLength(1); + expect(json.configs[0].displayName).toEqual({ + color: 'white', + name: 'Config from cjs file', + }); +}); + +// not unflagged for other versions yet. Update this range if that changes +onNodeVersions('^13.2.0', () => { + test('reads config from mjs file', () => { + const {json, exitCode} = runWithJson('esm-config/mjs', ['--show-config'], { + skipPkgJsonCheck: true, + }); + + expect(exitCode).toBe(0); + expect(json.configs).toHaveLength(1); + expect(json.configs[0].displayName).toEqual({ + color: 'white', + name: 'Config from mjs file', + }); + }); +}); diff --git a/e2e/cjs-config/__tests__/test.js b/e2e/esm-config/cjs/__tests__/test.js similarity index 100% rename from e2e/cjs-config/__tests__/test.js rename to e2e/esm-config/cjs/__tests__/test.js diff --git a/e2e/cjs-config/jest.config.cjs b/e2e/esm-config/cjs/jest.config.cjs similarity index 100% rename from e2e/cjs-config/jest.config.cjs rename to e2e/esm-config/cjs/jest.config.cjs diff --git a/e2e/cjs-config/package.json b/e2e/esm-config/cjs/package.json similarity index 100% rename from e2e/cjs-config/package.json rename to e2e/esm-config/cjs/package.json diff --git a/e2e/esm-config/mjs/__tests__/test.js b/e2e/esm-config/mjs/__tests__/test.js new file mode 100644 index 000000000000..2b4a7ced6f45 --- /dev/null +++ b/e2e/esm-config/mjs/__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/esm-config/mjs/jest.config.mjs b/e2e/esm-config/mjs/jest.config.mjs new file mode 100644 index 000000000000..3cec62f2d4ac --- /dev/null +++ b/e2e/esm-config/mjs/jest.config.mjs @@ -0,0 +1,11 @@ +/** + * 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. + */ + +export default { + displayName: 'Config from mjs file', + testEnvironment: 'node', +}; diff --git a/e2e/esm-config/mjs/package.json b/e2e/esm-config/mjs/package.json new file mode 100644 index 000000000000..586d4ca6b75c --- /dev/null +++ b/e2e/esm-config/mjs/package.json @@ -0,0 +1,3 @@ +{ + "jest": {} +} diff --git a/packages/jest-cli/src/init/__tests__/__snapshots__/init.test.js.snap b/packages/jest-cli/src/init/__tests__/__snapshots__/init.test.js.snap index 1ca7d79a90dc..3476e83a17c8 100644 --- a/packages/jest-cli/src/init/__tests__/__snapshots__/init.test.js.snap +++ b/packages/jest-cli/src/init/__tests__/__snapshots__/init.test.js.snap @@ -36,6 +36,207 @@ Object { } `; +exports[`init has-jest-config-file-mjs ask the user whether to override config or not user answered with "Yes" 1`] = ` +Object { + "initial": true, + "message": "It seems that you already have a jest configuration, do you want to override it?", + "name": "continue", + "type": "confirm", +} +`; + +exports[`init project with package.json and no jest config all questions answered with answer: "No" should generate empty config with mjs extension 1`] = ` +"// For a detailed explanation regarding each configuration property, visit: +// https://jestjs.io/docs/en/configuration.html + +export default { + // All imported modules in your tests should be mocked automatically + // automock: false, + + // Stop running tests after \`n\` failures + // bail: 0, + + // Respect \\"browser\\" field in package.json when resolving modules + // browser: false, + + // The directory where Jest should store its cached dependency information + // cacheDirectory: \\"/tmp/jest\\", + + // Automatically clear mock calls and instances between every test + // clearMocks: false, + + // Indicates whether the coverage information should be collected while executing the test + // collectCoverage: false, + + // An array of glob patterns indicating a set of files for which coverage information should be collected + // collectCoverageFrom: undefined, + + // The directory where Jest should output its coverage files + // coverageDirectory: undefined, + + // An array of regexp pattern strings used to skip coverage collection + // coveragePathIgnorePatterns: [ + // \\"/node_modules/\\" + // ], + + // A list of reporter names that Jest uses when writing coverage reports + // coverageReporters: [ + // \\"json\\", + // \\"text\\", + // \\"lcov\\", + // \\"clover\\" + // ], + + // An object that configures minimum threshold enforcement for coverage results + // coverageThreshold: undefined, + + // A path to a custom dependency extractor + // dependencyExtractor: undefined, + + // Make calling deprecated APIs throw helpful error messages + // errorOnDeprecated: false, + + // Force coverage collection from ignored files using an array of glob patterns + // forceCoverageMatch: [], + + // A path to a module which exports an async function that is triggered once before all test suites + // globalSetup: undefined, + + // A path to a module which exports an async function that is triggered once after all test suites + // globalTeardown: undefined, + + // A set of global variables that need to be available in all test environments + // globals: {}, + + // The maximum amount of workers used to run your tests. Can be specified as % or a number. E.g. maxWorkers: 10% will use 10% of your CPU amount + 1 as the maximum worker number. maxWorkers: 2 will use a maximum of 2 workers. + // maxWorkers: \\"50%\\", + + // An array of directory names to be searched recursively up from the requiring module's location + // moduleDirectories: [ + // \\"node_modules\\" + // ], + + // An array of file extensions your modules use + // moduleFileExtensions: [ + // \\"js\\", + // \\"json\\", + // \\"jsx\\", + // \\"ts\\", + // \\"tsx\\", + // \\"node\\" + // ], + + // A map from regular expressions to module names that allow to stub out resources with a single module + // moduleNameMapper: {}, + + // An array of regexp pattern strings, matched against all module paths before considered 'visible' to the module loader + // modulePathIgnorePatterns: [], + + // Activates notifications for test results + // notify: false, + + // An enum that specifies notification mode. Requires { notify: true } + // notifyMode: \\"failure-change\\", + + // A preset that is used as a base for Jest's configuration + // preset: undefined, + + // Run tests from one or more projects + // projects: undefined, + + // Use this configuration option to add custom reporters to Jest + // reporters: undefined, + + // Automatically reset mock state between every test + // resetMocks: false, + + // Reset the module registry before running each individual test + // resetModules: false, + + // A path to a custom resolver + // resolver: undefined, + + // Automatically restore mock state between every test + // restoreMocks: false, + + // The root directory that Jest should scan for tests and modules within + // rootDir: undefined, + + // A list of paths to directories that Jest should use to search for files in + // roots: [ + // \\"\\" + // ], + + // Allows you to use a custom runner instead of Jest's default test runner + // runner: \\"jest-runner\\", + + // The paths to modules that run some code to configure or set up the testing environment before each test + // setupFiles: [], + + // A list of paths to modules that run some code to configure or set up the testing framework before each test + // setupFilesAfterEnv: [], + + // A list of paths to snapshot serializer modules Jest should use for snapshot testing + // snapshotSerializers: [], + + // The test environment that will be used for testing + // testEnvironment: \\"jest-environment-jsdom\\", + + // Options that will be passed to the testEnvironment + // testEnvironmentOptions: {}, + + // Adds a location field to test results + // testLocationInResults: false, + + // The glob patterns Jest uses to detect test files + // testMatch: [ + // \\"**/__tests__/**/*.[jt]s?(x)\\", + // \\"**/?(*.)+(spec|test).[tj]s?(x)\\" + // ], + + // An array of regexp pattern strings that are matched against all test paths, matched tests are skipped + // testPathIgnorePatterns: [ + // \\"/node_modules/\\" + // ], + + // The regexp pattern or array of patterns that Jest uses to detect test files + // testRegex: [], + + // This option allows the use of a custom results processor + // testResultsProcessor: undefined, + + // This option allows use of a custom test runner + // testRunner: \\"jasmine2\\", + + // This option sets the URL for the jsdom environment. It is reflected in properties such as location.href + // testURL: \\"http://localhost\\", + + // Setting this value to \\"fake\\" allows the use of fake timers for functions such as \\"setTimeout\\" + // timers: \\"real\\", + + // A map from regular expressions to paths to transformers + // transform: undefined, + + // An array of regexp pattern strings that are matched against all source file paths, matched files will skip transformation + // transformIgnorePatterns: [ + // \\"/node_modules/\\" + // ], + + // An array of regexp pattern strings that are matched against all modules before the module loader will automatically return a mock for them + // unmockedModulePathPatterns: undefined, + + // Indicates whether each individual test should be reported during the run + // verbose: undefined, + + // An array of regexp patterns that are matched against all source file paths before re-running tests in watch mode + // watchPathIgnorePatterns: [], + + // Whether to use watchman for file crawling + // watchman: true, +}; +" +`; + exports[`init project with package.json and no jest config all questions answered with answer: "No" should return the default configuration (an empty config) 1`] = ` "// For a detailed explanation regarding each configuration property, visit: // https://jestjs.io/docs/en/configuration.html diff --git a/packages/jest-cli/src/init/__tests__/fixtures/has_jest_config_file_mjs/jest.config.mjs b/packages/jest-cli/src/init/__tests__/fixtures/has_jest_config_file_mjs/jest.config.mjs new file mode 100644 index 000000000000..d291155b7a10 --- /dev/null +++ b/packages/jest-cli/src/init/__tests__/fixtures/has_jest_config_file_mjs/jest.config.mjs @@ -0,0 +1,8 @@ +/** + * 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. + */ + +export default {}; diff --git a/packages/jest-cli/src/init/__tests__/fixtures/has_jest_config_file_mjs/package.json b/packages/jest-cli/src/init/__tests__/fixtures/has_jest_config_file_mjs/package.json new file mode 100644 index 000000000000..0967ef424bce --- /dev/null +++ b/packages/jest-cli/src/init/__tests__/fixtures/has_jest_config_file_mjs/package.json @@ -0,0 +1 @@ +{} diff --git a/packages/jest-cli/src/init/__tests__/fixtures/type_module/package.json b/packages/jest-cli/src/init/__tests__/fixtures/type_module/package.json new file mode 100644 index 000000000000..a6893e57d0df --- /dev/null +++ b/packages/jest-cli/src/init/__tests__/fixtures/type_module/package.json @@ -0,0 +1,7 @@ +{ + "name": "type_module", + "scripts": { + "test": "different-test-runner" + }, + "type": "module" +} diff --git a/packages/jest-cli/src/init/__tests__/init.test.js b/packages/jest-cli/src/init/__tests__/init.test.js index 6a6768f83779..8425b726deea 100644 --- a/packages/jest-cli/src/init/__tests__/init.test.js +++ b/packages/jest-cli/src/init/__tests__/init.test.js @@ -9,8 +9,11 @@ import * as fs from 'fs'; import * as path from 'path'; import prompts from 'prompts'; +import {constants} from 'jest-config'; import init from '../'; -import {JEST_CONFIG_EXT_ORDER} from '../constants'; +import {onNodeVersions} from '@jest/test-utils'; + +const {JEST_CONFIG_EXT_ORDER} = constants; jest.mock('prompts'); jest.mock('../../../../jest-config/build/getCacheDirectory', () => () => @@ -52,6 +55,20 @@ describe('init', () => { expect(evaluatedConfig).toEqual({}); }); + + onNodeVersions('^13.1.0', () => { + it('should generate empty config with mjs extension', async () => { + prompts.mockReturnValueOnce({}); + + await init(resolveFromFixture('type_module')); + + expect(fs.writeFileSync.mock.calls[0][0].endsWith('.mjs')).toBe(true); + + const writtenJestConfig = fs.writeFileSync.mock.calls[0][1]; + + expect(writtenJestConfig).toMatchSnapshot(); + }); + }); }); describe('some questions answered with answer: "Yes"', () => { diff --git a/packages/jest-cli/src/init/constants.ts b/packages/jest-cli/src/init/constants.ts deleted file mode 100644 index b7c3ed5e25ff..000000000000 --- a/packages/jest-cli/src/init/constants.ts +++ /dev/null @@ -1,17 +0,0 @@ -/** - * 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. - */ - -export const PACKAGE_JSON = 'package.json'; -export const JEST_CONFIG_BASE_NAME = 'jest.config'; -export const JEST_CONFIG_EXT_CJS = '.cjs'; -export const JEST_CONFIG_EXT_JS = '.js'; -export const JEST_CONFIG_EXT_JSON = '.json'; -export const JEST_CONFIG_EXT_ORDER = Object.freeze([ - JEST_CONFIG_EXT_JS, - JEST_CONFIG_EXT_CJS, - JEST_CONFIG_EXT_JSON, -]); diff --git a/packages/jest-cli/src/init/generate_config_file.ts b/packages/jest-cli/src/init/generate_config_file.ts index f53393d3fbc4..93389b9d6e3c 100644 --- a/packages/jest-cli/src/init/generate_config_file.ts +++ b/packages/jest-cli/src/init/generate_config_file.ts @@ -31,7 +31,10 @@ const stringifyOption = ( ); }; -const generateConfigFile = (results: Record): string => { +const generateConfigFile = ( + results: Record, + generateEsm = false, +): string => { const {coverage, clearMocks, environment} = results; const overrides: Record = {}; @@ -75,7 +78,7 @@ const generateConfigFile = (results: Record): string => { return ( '// For a detailed explanation regarding each configuration property, visit:\n' + '// https://jestjs.io/docs/en/configuration.html\n\n' + - 'module.exports = {\n' + + (generateEsm ? 'export default {\n' : 'module.exports = {\n') + properties.join('\n') + '};\n' ); diff --git a/packages/jest-cli/src/init/index.ts b/packages/jest-cli/src/init/index.ts index ffc8e1a2e30a..2b1816fd4d0a 100644 --- a/packages/jest-cli/src/init/index.ts +++ b/packages/jest-cli/src/init/index.ts @@ -10,18 +10,20 @@ import * as path from 'path'; import chalk = require('chalk'); import prompts = require('prompts'); import {sync as realpath} from 'realpath-native'; +import {constants} from 'jest-config'; import defaultQuestions, {testScriptQuestion} from './questions'; import {MalformedPackageJsonError, NotFoundPackageJsonError} from './errors'; -import { +import generateConfigFile from './generate_config_file'; +import modifyPackageJson from './modify_package_json'; +import {ProjectPackageJson} from './types'; + +const { JEST_CONFIG_BASE_NAME, - JEST_CONFIG_EXT_CJS, + JEST_CONFIG_EXT_MJS, JEST_CONFIG_EXT_JS, JEST_CONFIG_EXT_ORDER, PACKAGE_JSON, -} from './constants'; -import generateConfigFile from './generate_config_file'; -import modifyPackageJson from './modify_package_json'; -import {ProjectPackageJson} from './types'; +} = constants; type PromptsResults = { clearMocks: boolean; @@ -56,6 +58,8 @@ export default async (rootDir: string = realpath(process.cwd())) => { hasJestProperty = true; } + console.log(projectPackageJson) + const existingJestConfigPath = JEST_CONFIG_EXT_ORDER.find(ext => fs.existsSync(path.join(rootDir, getConfigFilename(ext))), ); @@ -65,7 +69,7 @@ export default async (rootDir: string = realpath(process.cwd())) => { rootDir, getConfigFilename( projectPackageJson.type === 'module' - ? JEST_CONFIG_EXT_CJS + ? JEST_CONFIG_EXT_MJS : JEST_CONFIG_EXT_JS, ), ); @@ -131,7 +135,11 @@ export default async (rootDir: string = realpath(process.cwd())) => { console.log(`✏️ Modified ${chalk.cyan(projectPackageJsonPath)}`); } - const generatedConfig = generateConfigFile(results); + const generatedConfig = generateConfigFile( + results, + projectPackageJson.type === 'module' || + jestConfigPath.endsWith(JEST_CONFIG_EXT_MJS), + ); fs.writeFileSync(jestConfigPath, generatedConfig); diff --git a/packages/jest-config/src/constants.ts b/packages/jest-config/src/constants.ts index 08c0128a534a..3ae6c9701ece 100644 --- a/packages/jest-config/src/constants.ts +++ b/packages/jest-config/src/constants.ts @@ -13,10 +13,12 @@ export const DEFAULT_REPORTER_LABEL = 'default'; export const PACKAGE_JSON = 'package.json'; export const JEST_CONFIG_BASE_NAME = 'jest.config'; export const JEST_CONFIG_EXT_CJS = '.cjs'; +export const JEST_CONFIG_EXT_MJS = '.mjs'; export const JEST_CONFIG_EXT_JS = '.js'; export const JEST_CONFIG_EXT_JSON = '.json'; export const JEST_CONFIG_EXT_ORDER = Object.freeze([ JEST_CONFIG_EXT_JS, + JEST_CONFIG_EXT_MJS, JEST_CONFIG_EXT_CJS, JEST_CONFIG_EXT_JSON, ]); diff --git a/packages/jest-config/src/index.ts b/packages/jest-config/src/index.ts index faf1a3deb1a0..495879ce59ed 100644 --- a/packages/jest-config/src/index.ts +++ b/packages/jest-config/src/index.ts @@ -20,7 +20,8 @@ export {default as deprecationEntries} from './Deprecated'; export {replaceRootDirInPath} from './utils'; export {default as defaults} from './Defaults'; export {default as descriptions} from './Descriptions'; -import {JEST_CONFIG_EXT_ORDER} from './constants'; +import * as constants from './constants'; +export {constants}; type ReadConfig = { configPath: Config.Path | null | undefined; @@ -29,7 +30,7 @@ type ReadConfig = { projectConfig: Config.ProjectConfig; }; -export function readConfig( +export async function readConfig( argv: Config.Argv, packageRootOrConfig: Config.Path | Config.InitialOptions, // Whether it needs to look into `--config` arg passed to CLI. @@ -39,7 +40,7 @@ export function readConfig( skipArgvConfigOption?: boolean, parentConfigPath?: Config.Path | null, projectIndex: number = Infinity, -): ReadConfig { +): Promise { let rawOptions; let configPath = null; @@ -74,11 +75,11 @@ export function readConfig( // or a path to directory containing `package.json` or `jest.config.js` } else if (!skipArgvConfigOption && typeof argv.config == 'string') { configPath = resolveConfigPath(argv.config, process.cwd()); - rawOptions = readConfigFileAndSetRootDir(configPath); + rawOptions = await readConfigFileAndSetRootDir(configPath); } else { // Otherwise just try to find config in the current rootDir. configPath = resolveConfigPath(packageRootOrConfig, process.cwd()); - rawOptions = readConfigFileAndSetRootDir(configPath); + rawOptions = await readConfigFileAndSetRootDir(configPath); } const {options, hasDeprecationWarnings} = normalize( @@ -262,14 +263,14 @@ This usually means that your ${chalk.bold( // // If no projects are specified, process.cwd() will be used as the default // (and only) project. -export function readConfigs( +export async function readConfigs( argv: Config.Argv, projectPaths: Array, -): { +): Promise<{ globalConfig: Config.GlobalConfig; configs: Array; hasDeprecationWarnings: boolean; -} { +}> { let globalConfig; let hasDeprecationWarnings; let configs: Array = []; @@ -277,7 +278,7 @@ export function readConfigs( let configPath: Config.Path | null | undefined; if (projectPaths.length === 1) { - const parsedConfig = readConfig(argv, projects[0]); + const parsedConfig = await readConfig(argv, projects[0]); configPath = parsedConfig.configPath; hasDeprecationWarnings = parsedConfig.hasDeprecationWarnings; @@ -298,33 +299,37 @@ export function readConfigs( ? projects[0] === realpath(process.cwd()) : projects[0] === process.cwd(); - const parsedConfigs = projects - .filter(root => { - // Ignore globbed files that cannot be `require`d. - if ( - typeof root === 'string' && - fs.existsSync(root) && - !fs.lstatSync(root).isDirectory() && - !JEST_CONFIG_EXT_ORDER.some(ext => root.endsWith(ext)) - ) { - return false; - } + const parsedConfigs = await Promise.all( + projects + .filter(root => { + // Ignore globbed files that cannot be `require`d. + if ( + typeof root === 'string' && + fs.existsSync(root) && + !fs.lstatSync(root).isDirectory() && + !constants.JEST_CONFIG_EXT_ORDER.some(ext => root.endsWith(ext)) + ) { + return false; + } - return true; - }) - .map((root, projectIndex) => { - const projectIsTheOnlyProject = - projectIndex === 0 && projects.length === 1; - const skipArgvConfigOption = !(projectIsTheOnlyProject && projectIsCwd); + return true; + }) + .map((root, projectIndex) => { + const projectIsTheOnlyProject = + projectIndex === 0 && projects.length === 1; + const skipArgvConfigOption = !( + projectIsTheOnlyProject && projectIsCwd + ); - return readConfig( - argv, - root, - skipArgvConfigOption, - configPath, - projectIndex, - ); - }); + return readConfig( + argv, + root, + skipArgvConfigOption, + configPath, + projectIndex, + ); + }), + ); ensureNoDuplicateConfigs(parsedConfigs, projects); configs = parsedConfigs.map(({projectConfig}) => projectConfig); diff --git a/packages/jest-config/src/readConfigFileAndSetRootDir.ts b/packages/jest-config/src/readConfigFileAndSetRootDir.ts index 1eb08ca7a75e..81d2fef9a7d8 100644 --- a/packages/jest-config/src/readConfigFileAndSetRootDir.ts +++ b/packages/jest-config/src/readConfigFileAndSetRootDir.ts @@ -10,26 +10,55 @@ import * as fs from 'fs'; import {Config} from '@jest/types'; // @ts-ignore: vendored import jsonlint from './vendor/jsonlint'; -import {PACKAGE_JSON} from './constants'; +import { + JEST_CONFIG_EXT_JSON, + JEST_CONFIG_EXT_MJS, + PACKAGE_JSON, +} from './constants'; // Read the configuration and set its `rootDir` // 1. If it's a `package.json` file, we look into its "jest" property // 2. For any other file, we just require it. -export default (configPath: Config.Path): Config.InitialOptions => { - const isJSON = configPath.endsWith('.json'); +export default async ( + configPath: Config.Path, +): Promise => { + const isJSON = configPath.endsWith(JEST_CONFIG_EXT_JSON); + const isMjs = configPath.endsWith(JEST_CONFIG_EXT_MJS); let configObject; - try { - configObject = require(configPath); - } catch (error) { - if (isJSON) { - throw new Error( - `Jest: Failed to parse config file ${configPath}\n` + - ` ${jsonlint.errors(fs.readFileSync(configPath, 'utf8'))}`, - ); - } else { + if (isMjs) { + try { + const importedConfig = await import(configPath); + + if (!importedConfig.default) { + throw new Error( + `Jest: Failed to load mjs config file ${configPath} - did you use a default export?`, + ); + } + + configObject = importedConfig.default; + } catch (error) { + if (error.message === 'Not supported') { + throw new Error( + `Jest: Your version of Node does not support dynamic import - please enable it or use a .cjs file extension for file ${configPath}`, + ); + } + throw error; } + } else { + try { + configObject = require(configPath); + } catch (error) { + if (isJSON) { + throw new Error( + `Jest: Failed to parse config file ${configPath}\n` + + ` ${jsonlint.errors(fs.readFileSync(configPath, 'utf8'))}`, + ); + } else { + throw error; + } + } } if (configPath.endsWith(PACKAGE_JSON)) { diff --git a/packages/jest-core/src/cli/index.ts b/packages/jest-core/src/cli/index.ts index da079919a161..eea54b856180 100644 --- a/packages/jest-core/src/cli/index.ts +++ b/packages/jest-core/src/cli/index.ts @@ -49,7 +49,7 @@ export const runCLI = async ( const outputStream = argv.json || argv.useStderr ? process.stderr : process.stdout; - const {globalConfig, configs, hasDeprecationWarnings} = readConfigs( + const {globalConfig, configs, hasDeprecationWarnings} = await readConfigs( argv, projects, ); diff --git a/packages/jest-runtime/src/cli/index.ts b/packages/jest-runtime/src/cli/index.ts index 22ed107ffb99..3d1a9ddd2b03 100644 --- a/packages/jest-runtime/src/cli/index.ts +++ b/packages/jest-runtime/src/cli/index.ts @@ -20,7 +20,7 @@ import {VERSION} from '../version'; import {Context} from '../types'; import * as args from './args'; -export function run(cliArgv?: Config.Argv, cliInfo?: Array) { +export async function run(cliArgv?: Config.Argv, cliInfo?: Array) { const realFs = require('fs'); const fs = require('graceful-fs'); fs.gracefulify(realFs); @@ -62,7 +62,7 @@ export function run(cliArgv?: Config.Argv, cliInfo?: Array) { const info = cliInfo ? ', ' + cliInfo.join(', ') : ''; console.log(`Using Jest Runtime v${VERSION}${info}`); } - const options = readConfig(argv, root); + const options = await readConfig(argv, root); const globalConfig = options.globalConfig; // Always disable automocking in scripts. const config: Config.ProjectConfig = { @@ -73,26 +73,26 @@ export function run(cliArgv?: Config.Argv, cliInfo?: Array) { // Break circular dependency const Runtime: any = require('..'); - (Runtime.createContext(config, { - maxWorkers: Math.max(cpus().length - 1, 1), - watchman: globalConfig.watchman, - }) as Promise) - .then(hasteMap => { - const Environment: typeof JestEnvironment = require(config.testEnvironment); - const environment = new Environment(config); - setGlobal( - environment.global, - 'console', - new CustomConsole(process.stdout, process.stderr), - ); - setGlobal(environment.global, 'jestProjectConfig', config); - setGlobal(environment.global, 'jestGlobalConfig', globalConfig); - - const runtime = new Runtime(config, environment, hasteMap.resolver); - runtime.requireModule(filePath); - }) - .catch(e => { - console.error(chalk.red(e.stack || e)); - process.on('exit', () => (process.exitCode = 1)); + try { + const hasteMap: Context = await Runtime.createContext(config, { + maxWorkers: Math.max(cpus().length - 1, 1), + watchman: globalConfig.watchman, }); + + const Environment: typeof JestEnvironment = require(config.testEnvironment); + const environment = new Environment(config); + setGlobal( + environment.global, + 'console', + new CustomConsole(process.stdout, process.stderr), + ); + setGlobal(environment.global, 'jestProjectConfig', config); + setGlobal(environment.global, 'jestGlobalConfig', globalConfig); + + const runtime = new Runtime(config, environment, hasteMap.resolver); + runtime.requireModule(filePath); + } catch (e) { + console.error(chalk.red(e.stack || e)); + process.on('exit', () => (process.exitCode = 1)); + } } From 6c4e636810b0161b294a38504932f81b879890b1 Mon Sep 17 00:00:00 2001 From: Simen Bekkhus Date: Sun, 19 Jan 2020 20:16:25 +0100 Subject: [PATCH 2/9] use corret unflagged node version --- packages/jest-cli/src/init/__tests__/init.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/jest-cli/src/init/__tests__/init.test.js b/packages/jest-cli/src/init/__tests__/init.test.js index 8425b726deea..91cf49818744 100644 --- a/packages/jest-cli/src/init/__tests__/init.test.js +++ b/packages/jest-cli/src/init/__tests__/init.test.js @@ -56,7 +56,7 @@ describe('init', () => { expect(evaluatedConfig).toEqual({}); }); - onNodeVersions('^13.1.0', () => { + onNodeVersions('^13.2.0', () => { it('should generate empty config with mjs extension', async () => { prompts.mockReturnValueOnce({}); From bfee78c68329d5dfd51de05bfe7d17b606340ef6 Mon Sep 17 00:00:00 2001 From: Simen Bekkhus Date: Sun, 19 Jan 2020 20:22:12 +0100 Subject: [PATCH 3/9] name function for minimally prettier stack trace --- packages/jest-config/src/readConfigFileAndSetRootDir.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/jest-config/src/readConfigFileAndSetRootDir.ts b/packages/jest-config/src/readConfigFileAndSetRootDir.ts index 81d2fef9a7d8..b0b2a8479ea1 100644 --- a/packages/jest-config/src/readConfigFileAndSetRootDir.ts +++ b/packages/jest-config/src/readConfigFileAndSetRootDir.ts @@ -19,9 +19,9 @@ import { // Read the configuration and set its `rootDir` // 1. If it's a `package.json` file, we look into its "jest" property // 2. For any other file, we just require it. -export default async ( +export default async function readConfigFileAndSetRootDir( configPath: Config.Path, -): Promise => { +): Promise { const isJSON = configPath.endsWith(JEST_CONFIG_EXT_JSON); const isMjs = configPath.endsWith(JEST_CONFIG_EXT_MJS); let configObject; @@ -82,4 +82,4 @@ export default async ( } return configObject; -}; +} From 2e0d77e8d9935c1b20e4df2543a2bfe42082cb76 Mon Sep 17 00:00:00 2001 From: Simen Bekkhus Date: Sun, 19 Jan 2020 20:23:37 +0100 Subject: [PATCH 4/9] remove stray console.log --- packages/jest-cli/src/init/index.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/jest-cli/src/init/index.ts b/packages/jest-cli/src/init/index.ts index 2b1816fd4d0a..faafb4792bf8 100644 --- a/packages/jest-cli/src/init/index.ts +++ b/packages/jest-cli/src/init/index.ts @@ -58,8 +58,6 @@ export default async (rootDir: string = realpath(process.cwd())) => { hasJestProperty = true; } - console.log(projectPackageJson) - const existingJestConfigPath = JEST_CONFIG_EXT_ORDER.find(ext => fs.existsSync(path.join(rootDir, getConfigFilename(ext))), ); From b218ce1c276c2a994c794cd978878b555bed8a84 Mon Sep 17 00:00:00 2001 From: Simen Bekkhus Date: Sun, 19 Jan 2020 20:40:06 +0100 Subject: [PATCH 5/9] fix support for node 8 --- babel.config.js | 2 +- packages/jest-config/src/importMjs.ts | 10 ++++++++++ .../jest-config/src/readConfigFileAndSetRootDir.ts | 3 ++- scripts/build.js | 9 ++++++++- 4 files changed, 21 insertions(+), 3 deletions(-) create mode 100644 packages/jest-config/src/importMjs.ts diff --git a/babel.config.js b/babel.config.js index 20a40063a2fb..82b13d097f49 100644 --- a/babel.config.js +++ b/babel.config.js @@ -33,7 +33,7 @@ module.exports = { }, ], ], - test: 'packages/jest-config/src/readConfigFileAndSetRootDir.ts', + test: 'packages/jest-config/src/importMjs.ts', }, ], plugins: [ diff --git a/packages/jest-config/src/importMjs.ts b/packages/jest-config/src/importMjs.ts new file mode 100644 index 000000000000..d04ddf5525d3 --- /dev/null +++ b/packages/jest-config/src/importMjs.ts @@ -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. + */ + +// this is in a separate file so that node 8 don't explode with a syntax error. +// Remove this file when we drop support for Node 8 +export default (specifier: string) => import(specifier); diff --git a/packages/jest-config/src/readConfigFileAndSetRootDir.ts b/packages/jest-config/src/readConfigFileAndSetRootDir.ts index b0b2a8479ea1..96576e9c28e9 100644 --- a/packages/jest-config/src/readConfigFileAndSetRootDir.ts +++ b/packages/jest-config/src/readConfigFileAndSetRootDir.ts @@ -15,6 +15,7 @@ import { JEST_CONFIG_EXT_MJS, PACKAGE_JSON, } from './constants'; +import importMjs from './importMjs'; // Read the configuration and set its `rootDir` // 1. If it's a `package.json` file, we look into its "jest" property @@ -28,7 +29,7 @@ export default async function readConfigFileAndSetRootDir( if (isMjs) { try { - const importedConfig = await import(configPath); + const importedConfig = await importMjs(configPath); if (!importedConfig.default) { throw new Error( diff --git a/scripts/build.js b/scripts/build.js index 2930ee8804e2..3dee896a034f 100644 --- a/scripts/build.js +++ b/scripts/build.js @@ -149,7 +149,14 @@ function buildFile(file, silent) { Array.isArray(plugin) && plugin[0] === '@babel/plugin-transform-modules-commonjs' ) { - return [plugin[0], Object.assign({}, plugin[1], {lazy: true})]; + return [ + plugin[0], + Object.assign({}, plugin[1], { + lazy: string => + // we want to lazyload all non-local modules plus `importMjs` - the latter to avoid syntax errors. Set to just `true` when we drop support for node 8 + !string.startsWith('./') || string === './importMjs', + }), + ]; } return plugin; From 4be75d52a26b7a3460d427949aeacceb9cd49252 Mon Sep 17 00:00:00 2001 From: Simen Bekkhus Date: Sun, 19 Jan 2020 20:45:43 +0100 Subject: [PATCH 6/9] fix unit tests --- packages/jest-config/src/__tests__/readConfig.test.ts | 8 ++++---- packages/jest-config/src/__tests__/readConfigs.test.ts | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/jest-config/src/__tests__/readConfig.test.ts b/packages/jest-config/src/__tests__/readConfig.test.ts index 63d81ce7e751..8566c78423e2 100644 --- a/packages/jest-config/src/__tests__/readConfig.test.ts +++ b/packages/jest-config/src/__tests__/readConfig.test.ts @@ -7,16 +7,16 @@ import {readConfig} from '../index'; -test('readConfig() throws when an object is passed without a file path', () => { - expect(() => { +test('readConfig() throws when an object is passed without a file path', async () => { + await expect( readConfig( // @ts-ignore null /* argv */, {} /* packageRootOrConfig */, false /* skipArgvConfigOption */, null /* parentConfigPath */, - ); - }).toThrowError( + ), + ).rejects.toThrowError( 'Jest: Cannot use configuration as an object without a file path', ); }); diff --git a/packages/jest-config/src/__tests__/readConfigs.test.ts b/packages/jest-config/src/__tests__/readConfigs.test.ts index 298f0f29625a..be939256c090 100644 --- a/packages/jest-config/src/__tests__/readConfigs.test.ts +++ b/packages/jest-config/src/__tests__/readConfigs.test.ts @@ -7,9 +7,9 @@ import {readConfigs} from '../index'; -test('readConfigs() throws when called without project paths', () => { - expect(() => { +test('readConfigs() throws when called without project paths', async () => { + await expect( // @ts-ignore - readConfigs(null /* argv */, [] /* projectPaths */); - }).toThrowError('jest: No configuration found for any project.'); + readConfigs(null /* argv */, [] /* projectPaths */), + ).rejects.toThrowError('jest: No configuration found for any project.'); }); From 5dab199838eb055f3b65ff6b031c3f94d9fec6b6 Mon Sep 17 00:00:00 2001 From: Simen Bekkhus Date: Sun, 19 Jan 2020 22:29:29 +0100 Subject: [PATCH 7/9] test cannot be snapshot --- .../__tests__/__snapshots__/init.test.js.snap | 192 ------------------ .../jest-cli/src/init/__tests__/init.test.js | 8 +- 2 files changed, 5 insertions(+), 195 deletions(-) diff --git a/packages/jest-cli/src/init/__tests__/__snapshots__/init.test.js.snap b/packages/jest-cli/src/init/__tests__/__snapshots__/init.test.js.snap index 3476e83a17c8..bb0ef6886d5f 100644 --- a/packages/jest-cli/src/init/__tests__/__snapshots__/init.test.js.snap +++ b/packages/jest-cli/src/init/__tests__/__snapshots__/init.test.js.snap @@ -45,198 +45,6 @@ Object { } `; -exports[`init project with package.json and no jest config all questions answered with answer: "No" should generate empty config with mjs extension 1`] = ` -"// For a detailed explanation regarding each configuration property, visit: -// https://jestjs.io/docs/en/configuration.html - -export default { - // All imported modules in your tests should be mocked automatically - // automock: false, - - // Stop running tests after \`n\` failures - // bail: 0, - - // Respect \\"browser\\" field in package.json when resolving modules - // browser: false, - - // The directory where Jest should store its cached dependency information - // cacheDirectory: \\"/tmp/jest\\", - - // Automatically clear mock calls and instances between every test - // clearMocks: false, - - // Indicates whether the coverage information should be collected while executing the test - // collectCoverage: false, - - // An array of glob patterns indicating a set of files for which coverage information should be collected - // collectCoverageFrom: undefined, - - // The directory where Jest should output its coverage files - // coverageDirectory: undefined, - - // An array of regexp pattern strings used to skip coverage collection - // coveragePathIgnorePatterns: [ - // \\"/node_modules/\\" - // ], - - // A list of reporter names that Jest uses when writing coverage reports - // coverageReporters: [ - // \\"json\\", - // \\"text\\", - // \\"lcov\\", - // \\"clover\\" - // ], - - // An object that configures minimum threshold enforcement for coverage results - // coverageThreshold: undefined, - - // A path to a custom dependency extractor - // dependencyExtractor: undefined, - - // Make calling deprecated APIs throw helpful error messages - // errorOnDeprecated: false, - - // Force coverage collection from ignored files using an array of glob patterns - // forceCoverageMatch: [], - - // A path to a module which exports an async function that is triggered once before all test suites - // globalSetup: undefined, - - // A path to a module which exports an async function that is triggered once after all test suites - // globalTeardown: undefined, - - // A set of global variables that need to be available in all test environments - // globals: {}, - - // The maximum amount of workers used to run your tests. Can be specified as % or a number. E.g. maxWorkers: 10% will use 10% of your CPU amount + 1 as the maximum worker number. maxWorkers: 2 will use a maximum of 2 workers. - // maxWorkers: \\"50%\\", - - // An array of directory names to be searched recursively up from the requiring module's location - // moduleDirectories: [ - // \\"node_modules\\" - // ], - - // An array of file extensions your modules use - // moduleFileExtensions: [ - // \\"js\\", - // \\"json\\", - // \\"jsx\\", - // \\"ts\\", - // \\"tsx\\", - // \\"node\\" - // ], - - // A map from regular expressions to module names that allow to stub out resources with a single module - // moduleNameMapper: {}, - - // An array of regexp pattern strings, matched against all module paths before considered 'visible' to the module loader - // modulePathIgnorePatterns: [], - - // Activates notifications for test results - // notify: false, - - // An enum that specifies notification mode. Requires { notify: true } - // notifyMode: \\"failure-change\\", - - // A preset that is used as a base for Jest's configuration - // preset: undefined, - - // Run tests from one or more projects - // projects: undefined, - - // Use this configuration option to add custom reporters to Jest - // reporters: undefined, - - // Automatically reset mock state between every test - // resetMocks: false, - - // Reset the module registry before running each individual test - // resetModules: false, - - // A path to a custom resolver - // resolver: undefined, - - // Automatically restore mock state between every test - // restoreMocks: false, - - // The root directory that Jest should scan for tests and modules within - // rootDir: undefined, - - // A list of paths to directories that Jest should use to search for files in - // roots: [ - // \\"\\" - // ], - - // Allows you to use a custom runner instead of Jest's default test runner - // runner: \\"jest-runner\\", - - // The paths to modules that run some code to configure or set up the testing environment before each test - // setupFiles: [], - - // A list of paths to modules that run some code to configure or set up the testing framework before each test - // setupFilesAfterEnv: [], - - // A list of paths to snapshot serializer modules Jest should use for snapshot testing - // snapshotSerializers: [], - - // The test environment that will be used for testing - // testEnvironment: \\"jest-environment-jsdom\\", - - // Options that will be passed to the testEnvironment - // testEnvironmentOptions: {}, - - // Adds a location field to test results - // testLocationInResults: false, - - // The glob patterns Jest uses to detect test files - // testMatch: [ - // \\"**/__tests__/**/*.[jt]s?(x)\\", - // \\"**/?(*.)+(spec|test).[tj]s?(x)\\" - // ], - - // An array of regexp pattern strings that are matched against all test paths, matched tests are skipped - // testPathIgnorePatterns: [ - // \\"/node_modules/\\" - // ], - - // The regexp pattern or array of patterns that Jest uses to detect test files - // testRegex: [], - - // This option allows the use of a custom results processor - // testResultsProcessor: undefined, - - // This option allows use of a custom test runner - // testRunner: \\"jasmine2\\", - - // This option sets the URL for the jsdom environment. It is reflected in properties such as location.href - // testURL: \\"http://localhost\\", - - // Setting this value to \\"fake\\" allows the use of fake timers for functions such as \\"setTimeout\\" - // timers: \\"real\\", - - // A map from regular expressions to paths to transformers - // transform: undefined, - - // An array of regexp pattern strings that are matched against all source file paths, matched files will skip transformation - // transformIgnorePatterns: [ - // \\"/node_modules/\\" - // ], - - // An array of regexp pattern strings that are matched against all modules before the module loader will automatically return a mock for them - // unmockedModulePathPatterns: undefined, - - // Indicates whether each individual test should be reported during the run - // verbose: undefined, - - // An array of regexp patterns that are matched against all source file paths before re-running tests in watch mode - // watchPathIgnorePatterns: [], - - // Whether to use watchman for file crawling - // watchman: true, -}; -" -`; - exports[`init project with package.json and no jest config all questions answered with answer: "No" should return the default configuration (an empty config) 1`] = ` "// For a detailed explanation regarding each configuration property, visit: // https://jestjs.io/docs/en/configuration.html diff --git a/packages/jest-cli/src/init/__tests__/init.test.js b/packages/jest-cli/src/init/__tests__/init.test.js index 91cf49818744..afc2acdca315 100644 --- a/packages/jest-cli/src/init/__tests__/init.test.js +++ b/packages/jest-cli/src/init/__tests__/init.test.js @@ -62,11 +62,13 @@ describe('init', () => { await init(resolveFromFixture('type_module')); - expect(fs.writeFileSync.mock.calls[0][0].endsWith('.mjs')).toBe(true); - + const writtenJestConfigFilename = fs.writeFileSync.mock.calls[0][0]; const writtenJestConfig = fs.writeFileSync.mock.calls[0][1]; - expect(writtenJestConfig).toMatchSnapshot(); + expect(writtenJestConfigFilename.endsWith('.mjs')).toBe(true); + + expect(typeof writtenJestConfig).toBe('string'); + expect(writtenJestConfig.split('\n')[3]).toBe('export default {'); }); }); }); From c2474b7ad95d31201b535a69e4530c65ec1b4b5e Mon Sep 17 00:00:00 2001 From: Simen Bekkhus Date: Mon, 20 Jan 2020 01:15:21 +0100 Subject: [PATCH 8/9] mock importer in tests --- packages/jest-config/src/__tests__/Defaults.test.ts | 2 ++ packages/jest-config/src/__tests__/readConfig.test.ts | 2 ++ packages/jest-config/src/__tests__/readConfigs.test.ts | 2 ++ 3 files changed, 6 insertions(+) diff --git a/packages/jest-config/src/__tests__/Defaults.test.ts b/packages/jest-config/src/__tests__/Defaults.test.ts index 31eda54e2efe..c985aca3090c 100644 --- a/packages/jest-config/src/__tests__/Defaults.test.ts +++ b/packages/jest-config/src/__tests__/Defaults.test.ts @@ -7,6 +7,8 @@ import {defaults} from '../index'; +jest.mock('../importMjs', () => (s: string) => import(s)); + test('get configuration defaults', () => { expect(defaults).toBeDefined(); }); diff --git a/packages/jest-config/src/__tests__/readConfig.test.ts b/packages/jest-config/src/__tests__/readConfig.test.ts index 8566c78423e2..a8bc5ef553d7 100644 --- a/packages/jest-config/src/__tests__/readConfig.test.ts +++ b/packages/jest-config/src/__tests__/readConfig.test.ts @@ -7,6 +7,8 @@ import {readConfig} from '../index'; +jest.mock('../importMjs', () => (s: string) => import(s)); + test('readConfig() throws when an object is passed without a file path', async () => { await expect( readConfig( diff --git a/packages/jest-config/src/__tests__/readConfigs.test.ts b/packages/jest-config/src/__tests__/readConfigs.test.ts index be939256c090..d15082bab409 100644 --- a/packages/jest-config/src/__tests__/readConfigs.test.ts +++ b/packages/jest-config/src/__tests__/readConfigs.test.ts @@ -7,6 +7,8 @@ import {readConfigs} from '../index'; +jest.mock('../importMjs', () => (s: string) => import(s)); + test('readConfigs() throws when called without project paths', async () => { await expect( // @ts-ignore From 115d2110f1171d842ce75f0665313721ac2d3f82 Mon Sep 17 00:00:00 2001 From: Simen Bekkhus Date: Tue, 21 Jan 2020 12:29:14 +0100 Subject: [PATCH 9/9] mention in docs --- docs/Configuration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Configuration.md b/docs/Configuration.md index 50e03f28b87a..9f0d18868b53 100644 --- a/docs/Configuration.md +++ b/docs/Configuration.md @@ -3,7 +3,7 @@ id: configuration title: Configuring Jest --- -Jest's configuration can be defined in the `package.json` file of your project, or through a `jest.config.js` file or through the `--config ` option. If you'd like to use your `package.json` to store Jest's config, the "jest" key should be used on the top level so Jest will know how to find your settings: +Jest's configuration can be defined in the `package.json` file of your project, or through a `jest.config.js` file or through the `--config ` option. If you'd like to use your `package.json` to store Jest's config, the `"jest"` key should be used on the top level so Jest will know how to find your settings: ```json {