UNPKG

11.3 kBJavaScriptView Raw
1'use strict';
2
3Object.defineProperty(exports, '__esModule', {
4 value: true
5});
6exports.default = void 0;
7
8function os() {
9 const data = _interopRequireWildcard(require('os'));
10
11 os = function () {
12 return data;
13 };
14
15 return data;
16}
17
18function path() {
19 const data = _interopRequireWildcard(require('path'));
20
21 path = function () {
22 return data;
23 };
24
25 return data;
26}
27
28function _micromatch() {
29 const data = _interopRequireDefault(require('micromatch'));
30
31 _micromatch = function () {
32 return data;
33 };
34
35 return data;
36}
37
38function _jestResolveDependencies() {
39 const data = _interopRequireDefault(require('jest-resolve-dependencies'));
40
41 _jestResolveDependencies = function () {
42 return data;
43 };
44
45 return data;
46}
47
48function _jestRegexUtil() {
49 const data = require('jest-regex-util');
50
51 _jestRegexUtil = function () {
52 return data;
53 };
54
55 return data;
56}
57
58function _jestConfig() {
59 const data = require('jest-config');
60
61 _jestConfig = function () {
62 return data;
63 };
64
65 return data;
66}
67
68function _jestSnapshot() {
69 const data = require('jest-snapshot');
70
71 _jestSnapshot = function () {
72 return data;
73 };
74
75 return data;
76}
77
78function _jestUtil() {
79 const data = require('jest-util');
80
81 _jestUtil = function () {
82 return data;
83 };
84
85 return data;
86}
87
88function _interopRequireDefault(obj) {
89 return obj && obj.__esModule ? obj : {default: obj};
90}
91
92function _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
101function _interopRequireWildcard(obj) {
102 if (obj && obj.__esModule) {
103 return obj;
104 }
105 if (obj === null || (typeof obj !== 'object' && typeof obj !== 'function')) {
106 return {default: obj};
107 }
108 var cache = _getRequireWildcardCache();
109 if (cache && cache.has(obj)) {
110 return cache.get(obj);
111 }
112 var newObj = {};
113 var hasPropertyDescriptor =
114 Object.defineProperty && Object.getOwnPropertyDescriptor;
115 for (var key in obj) {
116 if (Object.prototype.hasOwnProperty.call(obj, key)) {
117 var desc = hasPropertyDescriptor
118 ? Object.getOwnPropertyDescriptor(obj, key)
119 : null;
120 if (desc && (desc.get || desc.set)) {
121 Object.defineProperty(newObj, key, desc);
122 } else {
123 newObj[key] = obj[key];
124 }
125 }
126 }
127 newObj.default = obj;
128 if (cache) {
129 cache.set(obj, newObj);
130 }
131 return newObj;
132}
133
134function _defineProperty(obj, key, value) {
135 if (key in obj) {
136 Object.defineProperty(obj, key, {
137 value: value,
138 enumerable: true,
139 configurable: true,
140 writable: true
141 });
142 } else {
143 obj[key] = value;
144 }
145 return obj;
146}
147
148const globsToMatcher = globs => path =>
149 (0, _micromatch().default)(
150 [(0, _jestUtil().replacePathSepForGlob)(path)],
151 globs,
152 {
153 dot: true
154 }
155 ).length > 0;
156
157const regexToMatcher = testRegex => path =>
158 testRegex.some(testRegex => new RegExp(testRegex).test(path));
159
160const toTests = (context, tests) =>
161 tests.map(path => ({
162 context,
163 duration: undefined,
164 path
165 }));
166
167const hasSCM = changedFilesInfo => {
168 const {repos} = changedFilesInfo; // no SCM (git/hg/...) is found in any of the roots.
169
170 const noSCM = Object.values(repos).every(scm => scm.size === 0);
171 return !noSCM;
172};
173
174class SearchSource {
175 constructor(context) {
176 _defineProperty(this, '_context', void 0);
177
178 _defineProperty(this, '_dependencyResolver', void 0);
179
180 _defineProperty(this, '_testPathCases', []);
181
182 const {config} = context;
183 this._context = context;
184 this._dependencyResolver = null;
185 const rootPattern = new RegExp(
186 config.roots
187 .map(dir => (0, _jestRegexUtil().escapePathForRegex)(dir + path().sep))
188 .join('|')
189 );
190
191 this._testPathCases.push({
192 isMatch: path => rootPattern.test(path),
193 stat: 'roots'
194 });
195
196 if (config.testMatch.length) {
197 this._testPathCases.push({
198 isMatch: globsToMatcher(config.testMatch),
199 stat: 'testMatch'
200 });
201 }
202
203 if (config.testPathIgnorePatterns.length) {
204 const testIgnorePatternsRegex = new RegExp(
205 config.testPathIgnorePatterns.join('|')
206 );
207
208 this._testPathCases.push({
209 isMatch: path => !testIgnorePatternsRegex.test(path),
210 stat: 'testPathIgnorePatterns'
211 });
212 }
213
214 if (config.testRegex.length) {
215 this._testPathCases.push({
216 isMatch: regexToMatcher(config.testRegex),
217 stat: 'testRegex'
218 });
219 }
220 }
221
222 _getOrBuildDependencyResolver() {
223 if (!this._dependencyResolver) {
224 this._dependencyResolver = new (_jestResolveDependencies().default)(
225 this._context.resolver,
226 this._context.hasteFS,
227 (0, _jestSnapshot().buildSnapshotResolver)(this._context.config)
228 );
229 }
230
231 return this._dependencyResolver;
232 }
233
234 _filterTestPathsWithStats(allPaths, testPathPattern) {
235 const data = {
236 stats: {
237 roots: 0,
238 testMatch: 0,
239 testPathIgnorePatterns: 0,
240 testRegex: 0
241 },
242 tests: [],
243 total: allPaths.length
244 };
245 const testCases = Array.from(this._testPathCases); // clone
246
247 if (testPathPattern) {
248 const regex = (0, _jestUtil().testPathPatternToRegExp)(testPathPattern);
249 testCases.push({
250 isMatch: path => regex.test(path),
251 stat: 'testPathPattern'
252 });
253 data.stats.testPathPattern = 0;
254 }
255
256 data.tests = allPaths.filter(test => {
257 let filterResult = true;
258
259 for (const {isMatch, stat} of testCases) {
260 if (isMatch(test.path)) {
261 data.stats[stat]++;
262 } else {
263 filterResult = false;
264 }
265 }
266
267 return filterResult;
268 });
269 return data;
270 }
271
272 _getAllTestPaths(testPathPattern) {
273 return this._filterTestPathsWithStats(
274 toTests(this._context, this._context.hasteFS.getAllFiles()),
275 testPathPattern
276 );
277 }
278
279 isTestFilePath(path) {
280 return this._testPathCases.every(testCase => testCase.isMatch(path));
281 }
282
283 findMatchingTests(testPathPattern) {
284 return this._getAllTestPaths(testPathPattern);
285 }
286
287 findRelatedTests(allPaths, collectCoverage) {
288 const dependencyResolver = this._getOrBuildDependencyResolver();
289
290 if (!collectCoverage) {
291 return {
292 tests: toTests(
293 this._context,
294 dependencyResolver.resolveInverse(
295 allPaths,
296 this.isTestFilePath.bind(this),
297 {
298 skipNodeResolution: this._context.config.skipNodeResolution
299 }
300 )
301 )
302 };
303 }
304
305 const testModulesMap = dependencyResolver.resolveInverseModuleMap(
306 allPaths,
307 this.isTestFilePath.bind(this),
308 {
309 skipNodeResolution: this._context.config.skipNodeResolution
310 }
311 );
312 const allPathsAbsolute = Array.from(allPaths).map(p => path().resolve(p));
313 const collectCoverageFrom = new Set();
314 testModulesMap.forEach(testModule => {
315 if (!testModule.dependencies) {
316 return;
317 }
318
319 testModule.dependencies.forEach(p => {
320 if (!allPathsAbsolute.includes(p)) {
321 return;
322 }
323
324 const filename = (0, _jestConfig().replaceRootDirInPath)(
325 this._context.config.rootDir,
326 p
327 );
328 collectCoverageFrom.add(
329 path().isAbsolute(filename)
330 ? path().relative(this._context.config.rootDir, filename)
331 : filename
332 );
333 });
334 });
335 return {
336 collectCoverageFrom,
337 tests: toTests(
338 this._context,
339 testModulesMap.map(testModule => testModule.file)
340 )
341 };
342 }
343
344 findTestsByPaths(paths) {
345 return {
346 tests: toTests(
347 this._context,
348 paths
349 .map(p => path().resolve(this._context.config.cwd, p))
350 .filter(this.isTestFilePath.bind(this))
351 )
352 };
353 }
354
355 findRelatedTestsFromPattern(paths, collectCoverage) {
356 if (Array.isArray(paths) && paths.length) {
357 const resolvedPaths = paths.map(p =>
358 path().resolve(this._context.config.cwd, p)
359 );
360 return this.findRelatedTests(new Set(resolvedPaths), collectCoverage);
361 }
362
363 return {
364 tests: []
365 };
366 }
367
368 findTestRelatedToChangedFiles(changedFilesInfo, collectCoverage) {
369 if (!hasSCM(changedFilesInfo)) {
370 return {
371 noSCM: true,
372 tests: []
373 };
374 }
375
376 const {changedFiles} = changedFilesInfo;
377 return this.findRelatedTests(changedFiles, collectCoverage);
378 }
379
380 _getTestPaths(globalConfig, changedFiles) {
381 if (globalConfig.onlyChanged) {
382 if (!changedFiles) {
383 throw new Error('Changed files must be set when running with -o.');
384 }
385
386 return this.findTestRelatedToChangedFiles(
387 changedFiles,
388 globalConfig.collectCoverage
389 );
390 }
391
392 let paths = globalConfig.nonFlagArgs;
393
394 if (globalConfig.findRelatedTests && 'win32' === os().platform()) {
395 const allFiles = this._context.hasteFS.getAllFiles();
396
397 const options = {
398 nocase: true,
399 windows: false
400 };
401 paths = paths
402 .map(p => {
403 const relativePath = path()
404 .resolve(this._context.config.cwd, p)
405 .replace(/\\/g, '\\\\');
406 const match = (0, _micromatch().default)(
407 allFiles,
408 relativePath,
409 options
410 );
411 return match[0];
412 })
413 .filter(Boolean);
414 }
415
416 if (globalConfig.runTestsByPath && paths && paths.length) {
417 return this.findTestsByPaths(paths);
418 } else if (globalConfig.findRelatedTests && paths && paths.length) {
419 return this.findRelatedTestsFromPattern(
420 paths,
421 globalConfig.collectCoverage
422 );
423 } else if (globalConfig.testPathPattern != null) {
424 return this.findMatchingTests(globalConfig.testPathPattern);
425 } else {
426 return {
427 tests: []
428 };
429 }
430 }
431
432 async getTestPaths(globalConfig, changedFiles, filter) {
433 const searchResult = this._getTestPaths(globalConfig, changedFiles);
434
435 const filterPath = globalConfig.filter;
436
437 if (filter) {
438 const tests = searchResult.tests;
439 const filterResult = await filter(tests.map(test => test.path));
440
441 if (!Array.isArray(filterResult.filtered)) {
442 throw new Error(
443 `Filter ${filterPath} did not return a valid test list`
444 );
445 }
446
447 const filteredSet = new Set(
448 filterResult.filtered.map(result => result.test)
449 );
450 return {
451 ...searchResult,
452 tests: tests.filter(test => filteredSet.has(test.path))
453 };
454 }
455
456 return searchResult;
457 }
458
459 findRelatedSourcesFromTestsInChangedFiles(changedFilesInfo) {
460 if (!hasSCM(changedFilesInfo)) {
461 return [];
462 }
463
464 const {changedFiles} = changedFilesInfo;
465
466 const dependencyResolver = this._getOrBuildDependencyResolver();
467
468 const relatedSourcesSet = new Set();
469 changedFiles.forEach(filePath => {
470 if (this.isTestFilePath(filePath)) {
471 const sourcePaths = dependencyResolver.resolve(filePath, {
472 skipNodeResolution: this._context.config.skipNodeResolution
473 });
474 sourcePaths.forEach(sourcePath => relatedSourcesSet.add(sourcePath));
475 }
476 });
477 return Array.from(relatedSourcesSet);
478 }
479}
480
481exports.default = SearchSource;