index.js 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479
  1. 'use strict';
  2. Object.defineProperty(exports, '__esModule', {
  3. value: true
  4. });
  5. exports.readConfig = readConfig;
  6. exports.readConfigs = readConfigs;
  7. Object.defineProperty(exports, 'normalize', {
  8. enumerable: true,
  9. get: function () {
  10. return _normalize.default;
  11. }
  12. });
  13. Object.defineProperty(exports, 'getTestEnvironment', {
  14. enumerable: true,
  15. get: function () {
  16. return _utils.getTestEnvironment;
  17. }
  18. });
  19. Object.defineProperty(exports, 'isJSONString', {
  20. enumerable: true,
  21. get: function () {
  22. return _utils.isJSONString;
  23. }
  24. });
  25. Object.defineProperty(exports, 'replaceRootDirInPath', {
  26. enumerable: true,
  27. get: function () {
  28. return _utils.replaceRootDirInPath;
  29. }
  30. });
  31. Object.defineProperty(exports, 'deprecationEntries', {
  32. enumerable: true,
  33. get: function () {
  34. return _Deprecated.default;
  35. }
  36. });
  37. Object.defineProperty(exports, 'defaults', {
  38. enumerable: true,
  39. get: function () {
  40. return _Defaults.default;
  41. }
  42. });
  43. Object.defineProperty(exports, 'descriptions', {
  44. enumerable: true,
  45. get: function () {
  46. return _Descriptions.default;
  47. }
  48. });
  49. exports.constants = void 0;
  50. function path() {
  51. const data = _interopRequireWildcard(require('path'));
  52. path = function () {
  53. return data;
  54. };
  55. return data;
  56. }
  57. function _chalk() {
  58. const data = _interopRequireDefault(require('chalk'));
  59. _chalk = function () {
  60. return data;
  61. };
  62. return data;
  63. }
  64. function fs() {
  65. const data = _interopRequireWildcard(require('graceful-fs'));
  66. fs = function () {
  67. return data;
  68. };
  69. return data;
  70. }
  71. function _jestUtil() {
  72. const data = require('jest-util');
  73. _jestUtil = function () {
  74. return data;
  75. };
  76. return data;
  77. }
  78. var constants = _interopRequireWildcard(require('./constants'));
  79. exports.constants = constants;
  80. var _normalize = _interopRequireDefault(require('./normalize'));
  81. var _readConfigFileAndSetRootDir = _interopRequireDefault(
  82. require('./readConfigFileAndSetRootDir')
  83. );
  84. var _resolveConfigPath = _interopRequireDefault(require('./resolveConfigPath'));
  85. var _utils = require('./utils');
  86. var _Deprecated = _interopRequireDefault(require('./Deprecated'));
  87. var _Defaults = _interopRequireDefault(require('./Defaults'));
  88. var _Descriptions = _interopRequireDefault(require('./Descriptions'));
  89. function _interopRequireDefault(obj) {
  90. return obj && obj.__esModule ? obj : {default: obj};
  91. }
  92. function _getRequireWildcardCache() {
  93. if (typeof WeakMap !== 'function') return null;
  94. var cache = new WeakMap();
  95. _getRequireWildcardCache = function () {
  96. return cache;
  97. };
  98. return cache;
  99. }
  100. function _interopRequireWildcard(obj) {
  101. if (obj && obj.__esModule) {
  102. return obj;
  103. }
  104. if (obj === null || (typeof obj !== 'object' && typeof obj !== 'function')) {
  105. return {default: obj};
  106. }
  107. var cache = _getRequireWildcardCache();
  108. if (cache && cache.has(obj)) {
  109. return cache.get(obj);
  110. }
  111. var newObj = {};
  112. var hasPropertyDescriptor =
  113. Object.defineProperty && Object.getOwnPropertyDescriptor;
  114. for (var key in obj) {
  115. if (Object.prototype.hasOwnProperty.call(obj, key)) {
  116. var desc = hasPropertyDescriptor
  117. ? Object.getOwnPropertyDescriptor(obj, key)
  118. : null;
  119. if (desc && (desc.get || desc.set)) {
  120. Object.defineProperty(newObj, key, desc);
  121. } else {
  122. newObj[key] = obj[key];
  123. }
  124. }
  125. }
  126. newObj.default = obj;
  127. if (cache) {
  128. cache.set(obj, newObj);
  129. }
  130. return newObj;
  131. }
  132. /**
  133. * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
  134. *
  135. * This source code is licensed under the MIT license found in the
  136. * LICENSE file in the root directory of this source tree.
  137. */
  138. async function readConfig(
  139. argv,
  140. packageRootOrConfig, // Whether it needs to look into `--config` arg passed to CLI.
  141. // It only used to read initial config. If the initial config contains
  142. // `project` property, we don't want to read `--config` value and rather
  143. // read individual configs for every project.
  144. skipArgvConfigOption,
  145. parentConfigPath,
  146. projectIndex = Infinity
  147. ) {
  148. let rawOptions;
  149. let configPath = null;
  150. if (typeof packageRootOrConfig !== 'string') {
  151. if (parentConfigPath) {
  152. const parentConfigDirname = path().dirname(parentConfigPath);
  153. rawOptions = packageRootOrConfig;
  154. rawOptions.rootDir = rawOptions.rootDir
  155. ? (0, _utils.replaceRootDirInPath)(
  156. parentConfigDirname,
  157. rawOptions.rootDir
  158. )
  159. : parentConfigDirname;
  160. } else {
  161. throw new Error(
  162. 'Jest: Cannot use configuration as an object without a file path.'
  163. );
  164. }
  165. } else if ((0, _utils.isJSONString)(argv.config)) {
  166. // A JSON string was passed to `--config` argument and we can parse it
  167. // and use as is.
  168. let config;
  169. try {
  170. config = JSON.parse(argv.config);
  171. } catch {
  172. throw new Error(
  173. 'There was an error while parsing the `--config` argument as a JSON string.'
  174. );
  175. } // NOTE: we might need to resolve this dir to an absolute path in the future
  176. config.rootDir = config.rootDir || packageRootOrConfig;
  177. rawOptions = config; // A string passed to `--config`, which is either a direct path to the config
  178. // or a path to directory containing `package.json`, `jest.config.js` or `jest.config.ts`
  179. } else if (!skipArgvConfigOption && typeof argv.config == 'string') {
  180. configPath = (0, _resolveConfigPath.default)(argv.config, process.cwd());
  181. rawOptions = await (0, _readConfigFileAndSetRootDir.default)(configPath);
  182. } else {
  183. // Otherwise just try to find config in the current rootDir.
  184. configPath = (0, _resolveConfigPath.default)(
  185. packageRootOrConfig,
  186. process.cwd()
  187. );
  188. rawOptions = await (0, _readConfigFileAndSetRootDir.default)(configPath);
  189. }
  190. if (typeof rawOptions === 'function') {
  191. rawOptions = await rawOptions();
  192. }
  193. const {options, hasDeprecationWarnings} = (0, _normalize.default)(
  194. rawOptions,
  195. argv,
  196. configPath,
  197. projectIndex
  198. );
  199. const {globalConfig, projectConfig} = groupOptions(options);
  200. return {
  201. configPath,
  202. globalConfig,
  203. hasDeprecationWarnings,
  204. projectConfig
  205. };
  206. }
  207. const groupOptions = options => ({
  208. globalConfig: Object.freeze({
  209. bail: options.bail,
  210. changedFilesWithAncestor: options.changedFilesWithAncestor,
  211. changedSince: options.changedSince,
  212. collectCoverage: options.collectCoverage,
  213. collectCoverageFrom: options.collectCoverageFrom,
  214. collectCoverageOnlyFrom: options.collectCoverageOnlyFrom,
  215. coverageDirectory: options.coverageDirectory,
  216. coverageProvider: options.coverageProvider,
  217. coverageReporters: options.coverageReporters,
  218. coverageThreshold: options.coverageThreshold,
  219. detectLeaks: options.detectLeaks,
  220. detectOpenHandles: options.detectOpenHandles,
  221. enabledTestsMap: options.enabledTestsMap,
  222. errorOnDeprecated: options.errorOnDeprecated,
  223. expand: options.expand,
  224. filter: options.filter,
  225. findRelatedTests: options.findRelatedTests,
  226. forceExit: options.forceExit,
  227. globalSetup: options.globalSetup,
  228. globalTeardown: options.globalTeardown,
  229. json: options.json,
  230. lastCommit: options.lastCommit,
  231. listTests: options.listTests,
  232. logHeapUsage: options.logHeapUsage,
  233. maxConcurrency: options.maxConcurrency,
  234. maxWorkers: options.maxWorkers,
  235. noSCM: undefined,
  236. noStackTrace: options.noStackTrace,
  237. nonFlagArgs: options.nonFlagArgs,
  238. notify: options.notify,
  239. notifyMode: options.notifyMode,
  240. onlyChanged: options.onlyChanged,
  241. onlyFailures: options.onlyFailures,
  242. outputFile: options.outputFile,
  243. passWithNoTests: options.passWithNoTests,
  244. projects: options.projects,
  245. replname: options.replname,
  246. reporters: options.reporters,
  247. rootDir: options.rootDir,
  248. runTestsByPath: options.runTestsByPath,
  249. silent: options.silent,
  250. skipFilter: options.skipFilter,
  251. testFailureExitCode: options.testFailureExitCode,
  252. testNamePattern: options.testNamePattern,
  253. testPathPattern: options.testPathPattern,
  254. testResultsProcessor: options.testResultsProcessor,
  255. testSequencer: options.testSequencer,
  256. testTimeout: options.testTimeout,
  257. updateSnapshot: options.updateSnapshot,
  258. useStderr: options.useStderr,
  259. verbose: options.verbose,
  260. watch: options.watch,
  261. watchAll: options.watchAll,
  262. watchPlugins: options.watchPlugins,
  263. watchman: options.watchman
  264. }),
  265. projectConfig: Object.freeze({
  266. automock: options.automock,
  267. cache: options.cache,
  268. cacheDirectory: options.cacheDirectory,
  269. clearMocks: options.clearMocks,
  270. coveragePathIgnorePatterns: options.coveragePathIgnorePatterns,
  271. cwd: options.cwd,
  272. dependencyExtractor: options.dependencyExtractor,
  273. detectLeaks: options.detectLeaks,
  274. detectOpenHandles: options.detectOpenHandles,
  275. displayName: options.displayName,
  276. errorOnDeprecated: options.errorOnDeprecated,
  277. extraGlobals: options.extraGlobals,
  278. filter: options.filter,
  279. forceCoverageMatch: options.forceCoverageMatch,
  280. globalSetup: options.globalSetup,
  281. globalTeardown: options.globalTeardown,
  282. globals: options.globals,
  283. haste: options.haste,
  284. injectGlobals: options.injectGlobals,
  285. moduleDirectories: options.moduleDirectories,
  286. moduleFileExtensions: options.moduleFileExtensions,
  287. moduleLoader: options.moduleLoader,
  288. moduleNameMapper: options.moduleNameMapper,
  289. modulePathIgnorePatterns: options.modulePathIgnorePatterns,
  290. modulePaths: options.modulePaths,
  291. name: options.name,
  292. prettierPath: options.prettierPath,
  293. resetMocks: options.resetMocks,
  294. resetModules: options.resetModules,
  295. resolver: options.resolver,
  296. restoreMocks: options.restoreMocks,
  297. rootDir: options.rootDir,
  298. roots: options.roots,
  299. runner: options.runner,
  300. setupFiles: options.setupFiles,
  301. setupFilesAfterEnv: options.setupFilesAfterEnv,
  302. skipFilter: options.skipFilter,
  303. skipNodeResolution: options.skipNodeResolution,
  304. slowTestThreshold: options.slowTestThreshold,
  305. snapshotResolver: options.snapshotResolver,
  306. snapshotSerializers: options.snapshotSerializers,
  307. testEnvironment: options.testEnvironment,
  308. testEnvironmentOptions: options.testEnvironmentOptions,
  309. testLocationInResults: options.testLocationInResults,
  310. testMatch: options.testMatch,
  311. testPathIgnorePatterns: options.testPathIgnorePatterns,
  312. testRegex: options.testRegex,
  313. testRunner: options.testRunner,
  314. testURL: options.testURL,
  315. timers: options.timers,
  316. transform: options.transform,
  317. transformIgnorePatterns: options.transformIgnorePatterns,
  318. unmockedModulePathPatterns: options.unmockedModulePathPatterns,
  319. watchPathIgnorePatterns: options.watchPathIgnorePatterns
  320. })
  321. });
  322. const ensureNoDuplicateConfigs = (parsedConfigs, projects) => {
  323. if (projects.length <= 1) {
  324. return;
  325. }
  326. const configPathMap = new Map();
  327. for (const config of parsedConfigs) {
  328. const {configPath} = config;
  329. if (configPathMap.has(configPath)) {
  330. const message = `Whoops! Two projects resolved to the same config path: ${_chalk().default.bold(
  331. String(configPath)
  332. )}:
  333. Project 1: ${_chalk().default.bold(
  334. projects[parsedConfigs.findIndex(x => x === config)]
  335. )}
  336. Project 2: ${_chalk().default.bold(
  337. projects[parsedConfigs.findIndex(x => x === configPathMap.get(configPath))]
  338. )}
  339. This usually means that your ${_chalk().default.bold(
  340. '"projects"'
  341. )} config includes a directory that doesn't have any configuration recognizable by Jest. Please fix it.
  342. `;
  343. throw new Error(message);
  344. }
  345. if (configPath !== null) {
  346. configPathMap.set(configPath, config);
  347. }
  348. }
  349. }; // Possible scenarios:
  350. // 1. jest --config config.json
  351. // 2. jest --projects p1 p2
  352. // 3. jest --projects p1 p2 --config config.json
  353. // 4. jest --projects p1
  354. // 5. jest
  355. //
  356. // If no projects are specified, process.cwd() will be used as the default
  357. // (and only) project.
  358. async function readConfigs(argv, projectPaths) {
  359. let globalConfig;
  360. let hasDeprecationWarnings;
  361. let configs = [];
  362. let projects = projectPaths;
  363. let configPath;
  364. if (projectPaths.length === 1) {
  365. const parsedConfig = await readConfig(argv, projects[0]);
  366. configPath = parsedConfig.configPath;
  367. hasDeprecationWarnings = parsedConfig.hasDeprecationWarnings;
  368. globalConfig = parsedConfig.globalConfig;
  369. configs = [parsedConfig.projectConfig];
  370. if (globalConfig.projects && globalConfig.projects.length) {
  371. // Even though we had one project in CLI args, there might be more
  372. // projects defined in the config.
  373. // In other words, if this was a single project,
  374. // and its config has `projects` settings, use that value instead.
  375. projects = globalConfig.projects;
  376. }
  377. }
  378. if (projects.length > 0) {
  379. const projectIsCwd =
  380. process.platform === 'win32'
  381. ? projects[0] === (0, _jestUtil().tryRealpath)(process.cwd())
  382. : projects[0] === process.cwd();
  383. const parsedConfigs = await Promise.all(
  384. projects
  385. .filter(root => {
  386. // Ignore globbed files that cannot be `require`d.
  387. if (
  388. typeof root === 'string' &&
  389. fs().existsSync(root) &&
  390. !fs().lstatSync(root).isDirectory() &&
  391. !constants.JEST_CONFIG_EXT_ORDER.some(ext => root.endsWith(ext))
  392. ) {
  393. return false;
  394. }
  395. return true;
  396. })
  397. .map((root, projectIndex) => {
  398. const projectIsTheOnlyProject =
  399. projectIndex === 0 && projects.length === 1;
  400. const skipArgvConfigOption = !(
  401. projectIsTheOnlyProject && projectIsCwd
  402. );
  403. return readConfig(
  404. argv,
  405. root,
  406. skipArgvConfigOption,
  407. configPath,
  408. projectIndex
  409. );
  410. })
  411. );
  412. ensureNoDuplicateConfigs(parsedConfigs, projects);
  413. configs = parsedConfigs.map(({projectConfig}) => projectConfig);
  414. if (!hasDeprecationWarnings) {
  415. hasDeprecationWarnings = parsedConfigs.some(
  416. ({hasDeprecationWarnings}) => !!hasDeprecationWarnings
  417. );
  418. } // If no config was passed initially, use the one from the first project
  419. if (!globalConfig) {
  420. globalConfig = parsedConfigs[0].globalConfig;
  421. }
  422. }
  423. if (!globalConfig || !configs.length) {
  424. throw new Error('jest: No configuration found for any project.');
  425. }
  426. return {
  427. configs,
  428. globalConfig,
  429. hasDeprecationWarnings: !!hasDeprecationWarnings
  430. };
  431. }