SearchSource.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425
  1. 'use strict';
  2. Object.defineProperty(exports, '__esModule', {
  3. value: true
  4. });
  5. exports.default = void 0;
  6. function _path() {
  7. const data = _interopRequireDefault(require('path'));
  8. _path = function _path() {
  9. return data;
  10. };
  11. return data;
  12. }
  13. function _micromatch() {
  14. const data = _interopRequireDefault(require('micromatch'));
  15. _micromatch = function _micromatch() {
  16. return data;
  17. };
  18. return data;
  19. }
  20. function _jestResolveDependencies() {
  21. const data = _interopRequireDefault(require('jest-resolve-dependencies'));
  22. _jestResolveDependencies = function _jestResolveDependencies() {
  23. return data;
  24. };
  25. return data;
  26. }
  27. function _jestRegexUtil() {
  28. const data = require('jest-regex-util');
  29. _jestRegexUtil = function _jestRegexUtil() {
  30. return data;
  31. };
  32. return data;
  33. }
  34. function _jestConfig() {
  35. const data = require('jest-config');
  36. _jestConfig = function _jestConfig() {
  37. return data;
  38. };
  39. return data;
  40. }
  41. function _jestSnapshot() {
  42. const data = require('jest-snapshot');
  43. _jestSnapshot = function _jestSnapshot() {
  44. return data;
  45. };
  46. return data;
  47. }
  48. function _jestUtil() {
  49. const data = require('jest-util');
  50. _jestUtil = function _jestUtil() {
  51. return data;
  52. };
  53. return data;
  54. }
  55. function _interopRequireDefault(obj) {
  56. return obj && obj.__esModule ? obj : {default: obj};
  57. }
  58. function _objectSpread(target) {
  59. for (var i = 1; i < arguments.length; i++) {
  60. var source = arguments[i] != null ? arguments[i] : {};
  61. var ownKeys = Object.keys(source);
  62. if (typeof Object.getOwnPropertySymbols === 'function') {
  63. ownKeys = ownKeys.concat(
  64. Object.getOwnPropertySymbols(source).filter(function(sym) {
  65. return Object.getOwnPropertyDescriptor(source, sym).enumerable;
  66. })
  67. );
  68. }
  69. ownKeys.forEach(function(key) {
  70. _defineProperty(target, key, source[key]);
  71. });
  72. }
  73. return target;
  74. }
  75. function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
  76. try {
  77. var info = gen[key](arg);
  78. var value = info.value;
  79. } catch (error) {
  80. reject(error);
  81. return;
  82. }
  83. if (info.done) {
  84. resolve(value);
  85. } else {
  86. Promise.resolve(value).then(_next, _throw);
  87. }
  88. }
  89. function _asyncToGenerator(fn) {
  90. return function() {
  91. var self = this,
  92. args = arguments;
  93. return new Promise(function(resolve, reject) {
  94. var gen = fn.apply(self, args);
  95. function _next(value) {
  96. asyncGeneratorStep(gen, resolve, reject, _next, _throw, 'next', value);
  97. }
  98. function _throw(err) {
  99. asyncGeneratorStep(gen, resolve, reject, _next, _throw, 'throw', err);
  100. }
  101. _next(undefined);
  102. });
  103. };
  104. }
  105. function _defineProperty(obj, key, value) {
  106. if (key in obj) {
  107. Object.defineProperty(obj, key, {
  108. value: value,
  109. enumerable: true,
  110. configurable: true,
  111. writable: true
  112. });
  113. } else {
  114. obj[key] = value;
  115. }
  116. return obj;
  117. }
  118. const globsToMatcher = globs => path =>
  119. _micromatch().default.some(
  120. (0, _jestUtil().replacePathSepForGlob)(path),
  121. globs,
  122. {
  123. dot: true
  124. }
  125. );
  126. const regexToMatcher = testRegex => path =>
  127. testRegex.some(testRegex => new RegExp(testRegex).test(path));
  128. const toTests = (context, tests) =>
  129. tests.map(path => ({
  130. context,
  131. duration: undefined,
  132. path
  133. }));
  134. class SearchSource {
  135. constructor(context) {
  136. _defineProperty(this, '_context', void 0);
  137. _defineProperty(this, '_testPathCases', []);
  138. const config = context.config;
  139. this._context = context;
  140. const rootPattern = new RegExp(
  141. config.roots
  142. .map(dir =>
  143. (0, _jestRegexUtil().escapePathForRegex)(dir + _path().default.sep)
  144. )
  145. .join('|')
  146. );
  147. this._testPathCases.push({
  148. isMatch: path => rootPattern.test(path),
  149. stat: 'roots'
  150. });
  151. if (config.testMatch.length) {
  152. this._testPathCases.push({
  153. isMatch: globsToMatcher(config.testMatch),
  154. stat: 'testMatch'
  155. });
  156. }
  157. if (config.testPathIgnorePatterns.length) {
  158. const testIgnorePatternsRegex = new RegExp(
  159. config.testPathIgnorePatterns.join('|')
  160. );
  161. this._testPathCases.push({
  162. isMatch: path => !testIgnorePatternsRegex.test(path),
  163. stat: 'testPathIgnorePatterns'
  164. });
  165. }
  166. if (config.testRegex.length) {
  167. this._testPathCases.push({
  168. isMatch: regexToMatcher(config.testRegex),
  169. stat: 'testRegex'
  170. });
  171. }
  172. }
  173. _filterTestPathsWithStats(allPaths, testPathPattern) {
  174. const data = {
  175. stats: {
  176. roots: 0,
  177. testMatch: 0,
  178. testPathIgnorePatterns: 0,
  179. testRegex: 0
  180. },
  181. tests: [],
  182. total: allPaths.length
  183. };
  184. const testCases = Array.from(this._testPathCases); // clone
  185. if (testPathPattern) {
  186. const regex = (0, _jestUtil().testPathPatternToRegExp)(testPathPattern);
  187. testCases.push({
  188. isMatch: path => regex.test(path),
  189. stat: 'testPathPattern'
  190. });
  191. data.stats.testPathPattern = 0;
  192. }
  193. data.tests = allPaths.filter(test => {
  194. let filterResult = true;
  195. for (var _i = 0; _i < testCases.length; _i++) {
  196. const _testCases$_i = testCases[_i],
  197. isMatch = _testCases$_i.isMatch,
  198. stat = _testCases$_i.stat;
  199. if (isMatch(test.path)) {
  200. data.stats[stat]++;
  201. } else {
  202. filterResult = false;
  203. }
  204. }
  205. return filterResult;
  206. });
  207. return data;
  208. }
  209. _getAllTestPaths(testPathPattern) {
  210. return this._filterTestPathsWithStats(
  211. toTests(this._context, this._context.hasteFS.getAllFiles()),
  212. testPathPattern
  213. );
  214. }
  215. isTestFilePath(path) {
  216. return this._testPathCases.every(testCase => testCase.isMatch(path));
  217. }
  218. findMatchingTests(testPathPattern) {
  219. return this._getAllTestPaths(testPathPattern);
  220. }
  221. findRelatedTests(allPaths, collectCoverage) {
  222. const dependencyResolver = new (_jestResolveDependencies()).default(
  223. this._context.resolver,
  224. this._context.hasteFS,
  225. (0, _jestSnapshot().buildSnapshotResolver)(this._context.config)
  226. );
  227. if (!collectCoverage) {
  228. return {
  229. tests: toTests(
  230. this._context,
  231. dependencyResolver.resolveInverse(
  232. allPaths,
  233. this.isTestFilePath.bind(this),
  234. {
  235. skipNodeResolution: this._context.config.skipNodeResolution
  236. }
  237. )
  238. )
  239. };
  240. }
  241. const testModulesMap = dependencyResolver.resolveInverseModuleMap(
  242. allPaths,
  243. this.isTestFilePath.bind(this),
  244. {
  245. skipNodeResolution: this._context.config.skipNodeResolution
  246. }
  247. );
  248. const allPathsAbsolute = Array.from(allPaths).map(p =>
  249. _path().default.resolve(p)
  250. );
  251. const collectCoverageFrom = new Set();
  252. testModulesMap.forEach(testModule => {
  253. if (!testModule.dependencies) {
  254. return;
  255. }
  256. testModule.dependencies
  257. .filter(p => allPathsAbsolute.includes(p))
  258. .map(filename => {
  259. filename = (0, _jestConfig().replaceRootDirInPath)(
  260. this._context.config.rootDir,
  261. filename
  262. );
  263. return _path().default.isAbsolute(filename)
  264. ? _path().default.relative(this._context.config.rootDir, filename)
  265. : filename;
  266. })
  267. .forEach(filename => collectCoverageFrom.add(filename));
  268. });
  269. return {
  270. collectCoverageFrom,
  271. tests: toTests(
  272. this._context,
  273. testModulesMap.map(testModule => testModule.file)
  274. )
  275. };
  276. }
  277. findTestsByPaths(paths) {
  278. return {
  279. tests: toTests(
  280. this._context,
  281. paths
  282. .map(p => _path().default.resolve(this._context.config.cwd, p))
  283. .filter(this.isTestFilePath.bind(this))
  284. )
  285. };
  286. }
  287. findRelatedTestsFromPattern(paths, collectCoverage) {
  288. if (Array.isArray(paths) && paths.length) {
  289. const resolvedPaths = paths.map(p =>
  290. _path().default.resolve(this._context.config.cwd, p)
  291. );
  292. return this.findRelatedTests(new Set(resolvedPaths), collectCoverage);
  293. }
  294. return {
  295. tests: []
  296. };
  297. }
  298. findTestRelatedToChangedFiles(changedFilesInfo, collectCoverage) {
  299. const repos = changedFilesInfo.repos,
  300. changedFiles = changedFilesInfo.changedFiles; // no SCM (git/hg/...) is found in any of the roots.
  301. const noSCM = Object.keys(repos).every(scm => repos[scm].size === 0);
  302. return noSCM
  303. ? {
  304. noSCM: true,
  305. tests: []
  306. }
  307. : this.findRelatedTests(changedFiles, collectCoverage);
  308. }
  309. _getTestPaths(globalConfig, changedFiles) {
  310. const paths = globalConfig.nonFlagArgs;
  311. if (globalConfig.onlyChanged) {
  312. if (!changedFiles) {
  313. throw new Error('Changed files must be set when running with -o.');
  314. }
  315. return this.findTestRelatedToChangedFiles(
  316. changedFiles,
  317. globalConfig.collectCoverage
  318. );
  319. } else if (globalConfig.runTestsByPath && paths && paths.length) {
  320. return this.findTestsByPaths(paths);
  321. } else if (globalConfig.findRelatedTests && paths && paths.length) {
  322. return this.findRelatedTestsFromPattern(
  323. paths,
  324. globalConfig.collectCoverage
  325. );
  326. } else if (globalConfig.testPathPattern != null) {
  327. return this.findMatchingTests(globalConfig.testPathPattern);
  328. } else {
  329. return {
  330. tests: []
  331. };
  332. }
  333. }
  334. getTestPaths(globalConfig, changedFiles, filter) {
  335. var _this = this;
  336. return _asyncToGenerator(function*() {
  337. const searchResult = _this._getTestPaths(globalConfig, changedFiles);
  338. const filterPath = globalConfig.filter;
  339. if (filter) {
  340. const tests = searchResult.tests;
  341. const filterResult = yield filter(tests.map(test => test.path));
  342. if (!Array.isArray(filterResult.filtered)) {
  343. throw new Error(
  344. `Filter ${filterPath} did not return a valid test list`
  345. );
  346. }
  347. const filteredSet = new Set(
  348. filterResult.filtered.map(result => result.test)
  349. );
  350. return _objectSpread({}, searchResult, {
  351. tests: tests.filter(test => filteredSet.has(test.path))
  352. });
  353. }
  354. return searchResult;
  355. })();
  356. }
  357. }
  358. exports.default = SearchSource;