UNPKG

6.51 kBJavaScriptView Raw
1'use strict';
2
3Object.defineProperty(exports, '__esModule', {
4 value: true
5});
6exports.default = void 0;
7
8function path() {
9 const data = _interopRequireWildcard(require('path'));
10
11 path = function () {
12 return data;
13 };
14
15 return data;
16}
17
18function _chalk() {
19 const data = _interopRequireDefault(require('chalk'));
20
21 _chalk = function () {
22 return data;
23 };
24
25 return data;
26}
27
28function fs() {
29 const data = _interopRequireWildcard(require('graceful-fs'));
30
31 fs = function () {
32 return data;
33 };
34
35 return data;
36}
37
38function _slash() {
39 const data = _interopRequireDefault(require('slash'));
40
41 _slash = function () {
42 return data;
43 };
44
45 return data;
46}
47
48var _constants = require('./constants');
49
50function _interopRequireDefault(obj) {
51 return obj && obj.__esModule ? obj : {default: obj};
52}
53
54function _getRequireWildcardCache(nodeInterop) {
55 if (typeof WeakMap !== 'function') return null;
56 var cacheBabelInterop = new WeakMap();
57 var cacheNodeInterop = new WeakMap();
58 return (_getRequireWildcardCache = function (nodeInterop) {
59 return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
60 })(nodeInterop);
61}
62
63function _interopRequireWildcard(obj, nodeInterop) {
64 if (!nodeInterop && obj && obj.__esModule) {
65 return obj;
66 }
67 if (obj === null || (typeof obj !== 'object' && typeof obj !== 'function')) {
68 return {default: obj};
69 }
70 var cache = _getRequireWildcardCache(nodeInterop);
71 if (cache && cache.has(obj)) {
72 return cache.get(obj);
73 }
74 var newObj = {};
75 var hasPropertyDescriptor =
76 Object.defineProperty && Object.getOwnPropertyDescriptor;
77 for (var key in obj) {
78 if (key !== 'default' && Object.prototype.hasOwnProperty.call(obj, key)) {
79 var desc = hasPropertyDescriptor
80 ? Object.getOwnPropertyDescriptor(obj, key)
81 : null;
82 if (desc && (desc.get || desc.set)) {
83 Object.defineProperty(newObj, key, desc);
84 } else {
85 newObj[key] = obj[key];
86 }
87 }
88 }
89 newObj.default = obj;
90 if (cache) {
91 cache.set(obj, newObj);
92 }
93 return newObj;
94}
95
96/**
97 * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
98 *
99 * This source code is licensed under the MIT license found in the
100 * LICENSE file in the root directory of this source tree.
101 */
102const isFile = filePath =>
103 fs().existsSync(filePath) && !fs().lstatSync(filePath).isDirectory();
104
105const getConfigFilename = ext => _constants.JEST_CONFIG_BASE_NAME + ext;
106
107var _default = (pathToResolve, cwd, skipMultipleConfigWarning = false) => {
108 if (!path().isAbsolute(cwd)) {
109 throw new Error(`"cwd" must be an absolute path. cwd: ${cwd}`);
110 }
111
112 const absolutePath = path().isAbsolute(pathToResolve)
113 ? pathToResolve
114 : path().resolve(cwd, pathToResolve);
115
116 if (isFile(absolutePath)) {
117 return absolutePath;
118 } // This is a guard against passing non existing path as a project/config,
119 // that will otherwise result in a very confusing situation.
120 // e.g.
121 // With a directory structure like this:
122 // my_project/
123 // packcage.json
124 //
125 // Passing a `my_project/some_directory_that_doesnt_exist` as a project
126 // name will resolve into a (possibly empty) `my_project/package.json` and
127 // try to run all tests it finds under `my_project` directory.
128
129 if (!fs().existsSync(absolutePath)) {
130 throw new Error(
131 `Can't find a root directory while resolving a config file path.\n` +
132 `Provided path to resolve: ${pathToResolve}\n` +
133 `cwd: ${cwd}`
134 );
135 }
136
137 return resolveConfigPathByTraversing(
138 absolutePath,
139 pathToResolve,
140 cwd,
141 skipMultipleConfigWarning
142 );
143};
144
145exports.default = _default;
146
147const resolveConfigPathByTraversing = (
148 pathToResolve,
149 initialPath,
150 cwd,
151 skipMultipleConfigWarning
152) => {
153 const configFiles = _constants.JEST_CONFIG_EXT_ORDER.map(ext =>
154 path().resolve(pathToResolve, getConfigFilename(ext))
155 ).filter(isFile);
156
157 const packageJson = findPackageJson(pathToResolve);
158
159 if (packageJson && hasPackageJsonJestKey(packageJson)) {
160 configFiles.push(packageJson);
161 }
162
163 if (!skipMultipleConfigWarning && configFiles.length > 1) {
164 console.warn(makeMultipleConfigsWarning(configFiles));
165 }
166
167 if (configFiles.length > 0 || packageJson) {
168 var _configFiles$;
169
170 return (_configFiles$ = configFiles[0]) !== null && _configFiles$ !== void 0
171 ? _configFiles$
172 : packageJson;
173 } // This is the system root.
174 // We tried everything, config is nowhere to be found ¯\_(ツ)_/¯
175
176 if (pathToResolve === path().dirname(pathToResolve)) {
177 throw new Error(makeResolutionErrorMessage(initialPath, cwd));
178 } // go up a level and try it again
179
180 return resolveConfigPathByTraversing(
181 path().dirname(pathToResolve),
182 initialPath,
183 cwd,
184 skipMultipleConfigWarning
185 );
186};
187
188const findPackageJson = pathToResolve => {
189 const packagePath = path().resolve(pathToResolve, _constants.PACKAGE_JSON);
190
191 if (isFile(packagePath)) {
192 return packagePath;
193 }
194
195 return undefined;
196};
197
198const hasPackageJsonJestKey = packagePath => {
199 const content = fs().readFileSync(packagePath, 'utf8');
200
201 try {
202 return 'jest' in JSON.parse(content);
203 } catch {
204 // If package is not a valid JSON
205 return false;
206 }
207};
208
209const makeResolutionErrorMessage = (initialPath, cwd) =>
210 'Could not find a config file based on provided values:\n' +
211 `path: "${initialPath}"\n` +
212 `cwd: "${cwd}"\n` +
213 'Config paths must be specified by either a direct path to a config\n' +
214 'file, or a path to a directory. If directory is given, Jest will try to\n' +
215 `traverse directory tree up, until it finds one of those files in exact order: ${_constants.JEST_CONFIG_EXT_ORDER.map(
216 ext => `"${getConfigFilename(ext)}"`
217 ).join(' or ')}.`;
218
219function extraIfPackageJson(configPath) {
220 if (configPath.endsWith(_constants.PACKAGE_JSON)) {
221 return '`jest` key in ';
222 }
223
224 return '';
225}
226
227const makeMultipleConfigsWarning = configPaths =>
228 _chalk().default.yellow(
229 [
230 _chalk().default.bold('\u25cf Multiple configurations found:'),
231 ...configPaths.map(
232 configPath =>
233 ` * ${extraIfPackageJson(configPath)}${(0, _slash().default)(
234 configPath
235 )}`
236 ),
237 '',
238 ' Implicit config resolution does not allow multiple configuration files.',
239 ' Either remove unused config files or select one explicitly with `--config`.',
240 '',
241 ' Configuration Documentation:',
242 ' https://jestjs.io/docs/configuration.html',
243 ''
244 ].join('\n')
245 );