343 lines
8.7 KiB
JavaScript
343 lines
8.7 KiB
JavaScript
|
|
'use strict';
|
||
|
|
|
||
|
|
Object.defineProperty(exports, '__esModule', {
|
||
|
|
value: true
|
||
|
|
});
|
||
|
|
|
||
|
|
var _path;
|
||
|
|
|
||
|
|
function _load_path() {
|
||
|
|
return (_path = _interopRequireDefault(require('path')));
|
||
|
|
}
|
||
|
|
|
||
|
|
var _micromatch;
|
||
|
|
|
||
|
|
function _load_micromatch() {
|
||
|
|
return (_micromatch = _interopRequireDefault(require('micromatch')));
|
||
|
|
}
|
||
|
|
|
||
|
|
var _jestResolveDependencies;
|
||
|
|
|
||
|
|
function _load_jestResolveDependencies() {
|
||
|
|
return (_jestResolveDependencies = _interopRequireDefault(
|
||
|
|
require('jest-resolve-dependencies')
|
||
|
|
));
|
||
|
|
}
|
||
|
|
|
||
|
|
var _testPathPatternToRegexp;
|
||
|
|
|
||
|
|
function _load_testPathPatternToRegexp() {
|
||
|
|
return (_testPathPatternToRegexp = _interopRequireDefault(
|
||
|
|
require('./testPathPatternToRegexp')
|
||
|
|
));
|
||
|
|
}
|
||
|
|
|
||
|
|
var _jestRegexUtil;
|
||
|
|
|
||
|
|
function _load_jestRegexUtil() {
|
||
|
|
return (_jestRegexUtil = require('jest-regex-util'));
|
||
|
|
}
|
||
|
|
|
||
|
|
var _jestConfig;
|
||
|
|
|
||
|
|
function _load_jestConfig() {
|
||
|
|
return (_jestConfig = require('jest-config'));
|
||
|
|
}
|
||
|
|
|
||
|
|
function _interopRequireDefault(obj) {
|
||
|
|
return obj && obj.__esModule ? obj : {default: obj};
|
||
|
|
}
|
||
|
|
|
||
|
|
function _asyncToGenerator(fn) {
|
||
|
|
return function() {
|
||
|
|
var gen = fn.apply(this, arguments);
|
||
|
|
return new Promise(function(resolve, reject) {
|
||
|
|
function step(key, arg) {
|
||
|
|
try {
|
||
|
|
var info = gen[key](arg);
|
||
|
|
var value = info.value;
|
||
|
|
} catch (error) {
|
||
|
|
reject(error);
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
if (info.done) {
|
||
|
|
resolve(value);
|
||
|
|
} else {
|
||
|
|
return Promise.resolve(value).then(
|
||
|
|
function(value) {
|
||
|
|
step('next', value);
|
||
|
|
},
|
||
|
|
function(err) {
|
||
|
|
step('throw', err);
|
||
|
|
}
|
||
|
|
);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return step('next');
|
||
|
|
});
|
||
|
|
};
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Copyright (c) 2014-present, Facebook, Inc. 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.
|
||
|
|
*
|
||
|
|
*
|
||
|
|
*/
|
||
|
|
|
||
|
|
const globsToMatcher = globs => {
|
||
|
|
if (globs == null || globs.length === 0) {
|
||
|
|
return () => true;
|
||
|
|
}
|
||
|
|
|
||
|
|
return path =>
|
||
|
|
(0, (_micromatch || _load_micromatch()).default)([path], globs, {dot: true})
|
||
|
|
.length > 0;
|
||
|
|
};
|
||
|
|
|
||
|
|
const regexToMatcher = testRegex => {
|
||
|
|
if (!testRegex) {
|
||
|
|
return () => true;
|
||
|
|
}
|
||
|
|
|
||
|
|
const regex = new RegExp(testRegex);
|
||
|
|
return path => regex.test(path);
|
||
|
|
};
|
||
|
|
|
||
|
|
const toTests = (context, tests) =>
|
||
|
|
tests.map(path => ({
|
||
|
|
context: context,
|
||
|
|
duration: undefined,
|
||
|
|
path: path
|
||
|
|
}));
|
||
|
|
|
||
|
|
class SearchSource {
|
||
|
|
constructor(context) {
|
||
|
|
const config = context.config;
|
||
|
|
|
||
|
|
this._context = context;
|
||
|
|
this._rootPattern = new RegExp(
|
||
|
|
config.roots
|
||
|
|
.map(dir =>
|
||
|
|
(0, (_jestRegexUtil || _load_jestRegexUtil()).escapePathForRegex)(
|
||
|
|
dir + (_path || _load_path()).default.sep
|
||
|
|
)
|
||
|
|
)
|
||
|
|
.join('|')
|
||
|
|
);
|
||
|
|
|
||
|
|
const ignorePattern = config.testPathIgnorePatterns;
|
||
|
|
this._testIgnorePattern = ignorePattern.length
|
||
|
|
? new RegExp(ignorePattern.join('|'))
|
||
|
|
: null;
|
||
|
|
|
||
|
|
this._testPathCases = {
|
||
|
|
roots: path => this._rootPattern.test(path),
|
||
|
|
testMatch: globsToMatcher(config.testMatch),
|
||
|
|
testPathIgnorePatterns: path =>
|
||
|
|
!this._testIgnorePattern || !this._testIgnorePattern.test(path),
|
||
|
|
testRegex: regexToMatcher(config.testRegex)
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
_filterTestPathsWithStats(allPaths, testPathPattern) {
|
||
|
|
const data = {
|
||
|
|
stats: {},
|
||
|
|
tests: [],
|
||
|
|
total: allPaths.length
|
||
|
|
};
|
||
|
|
|
||
|
|
const testCases = Object.assign({}, this._testPathCases);
|
||
|
|
if (testPathPattern) {
|
||
|
|
const regex = (0,
|
||
|
|
(_testPathPatternToRegexp || _load_testPathPatternToRegexp()).default)(
|
||
|
|
testPathPattern
|
||
|
|
);
|
||
|
|
testCases.testPathPattern = path => regex.test(path);
|
||
|
|
}
|
||
|
|
|
||
|
|
const testCasesKeys = Object.keys(testCases);
|
||
|
|
data.tests = allPaths.filter(test =>
|
||
|
|
testCasesKeys.reduce((flag, key) => {
|
||
|
|
if (testCases[key](test.path)) {
|
||
|
|
data.stats[key] = ++data.stats[key] || 1;
|
||
|
|
return flag && true;
|
||
|
|
}
|
||
|
|
data.stats[key] = data.stats[key] || 0;
|
||
|
|
return false;
|
||
|
|
}, true)
|
||
|
|
);
|
||
|
|
|
||
|
|
return data;
|
||
|
|
}
|
||
|
|
|
||
|
|
_getAllTestPaths(testPathPattern) {
|
||
|
|
return this._filterTestPathsWithStats(
|
||
|
|
toTests(this._context, this._context.hasteFS.getAllFiles()),
|
||
|
|
testPathPattern
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
isTestFilePath(path) {
|
||
|
|
return Object.keys(this._testPathCases).every(key =>
|
||
|
|
this._testPathCases[key](path)
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
findMatchingTests(testPathPattern) {
|
||
|
|
return this._getAllTestPaths(testPathPattern);
|
||
|
|
}
|
||
|
|
|
||
|
|
findRelatedTests(allPaths, collectCoverage) {
|
||
|
|
const dependencyResolver = new (
|
||
|
|
_jestResolveDependencies || _load_jestResolveDependencies()
|
||
|
|
).default(this._context.resolver, this._context.hasteFS);
|
||
|
|
|
||
|
|
const tests = toTests(
|
||
|
|
this._context,
|
||
|
|
dependencyResolver.resolveInverse(
|
||
|
|
allPaths,
|
||
|
|
this.isTestFilePath.bind(this),
|
||
|
|
{
|
||
|
|
skipNodeResolution: this._context.config.skipNodeResolution
|
||
|
|
}
|
||
|
|
)
|
||
|
|
);
|
||
|
|
let collectCoverageFrom;
|
||
|
|
|
||
|
|
// If we are collecting coverage, also return collectCoverageFrom patterns
|
||
|
|
if (collectCoverage) {
|
||
|
|
collectCoverageFrom = Array.from(allPaths).map(filename => {
|
||
|
|
filename = (0,
|
||
|
|
(_jestConfig || _load_jestConfig()).replaceRootDirInPath)(
|
||
|
|
this._context.config.rootDir,
|
||
|
|
filename
|
||
|
|
);
|
||
|
|
return (_path || _load_path()).default.isAbsolute(filename)
|
||
|
|
? (_path || _load_path()).default.relative(
|
||
|
|
this._context.config.rootDir,
|
||
|
|
filename
|
||
|
|
)
|
||
|
|
: filename;
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
return {collectCoverageFrom: collectCoverageFrom, tests: tests};
|
||
|
|
}
|
||
|
|
|
||
|
|
findTestsByPaths(paths) {
|
||
|
|
return {
|
||
|
|
tests: toTests(
|
||
|
|
this._context,
|
||
|
|
paths
|
||
|
|
.map(p => (_path || _load_path()).default.resolve(process.cwd(), p))
|
||
|
|
.filter(this.isTestFilePath.bind(this))
|
||
|
|
)
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
findRelatedTestsFromPattern(paths, collectCoverage) {
|
||
|
|
if (Array.isArray(paths) && paths.length) {
|
||
|
|
const resolvedPaths = paths.map(p =>
|
||
|
|
(_path || _load_path()).default.resolve(process.cwd(), p)
|
||
|
|
);
|
||
|
|
return this.findRelatedTests(new Set(resolvedPaths), collectCoverage);
|
||
|
|
}
|
||
|
|
return {tests: []};
|
||
|
|
}
|
||
|
|
|
||
|
|
findTestRelatedToChangedFiles(changedFilesPromise, collectCoverage) {
|
||
|
|
var _this = this;
|
||
|
|
|
||
|
|
return _asyncToGenerator(function*() {
|
||
|
|
var _ref = yield changedFilesPromise;
|
||
|
|
|
||
|
|
const repos = _ref.repos,
|
||
|
|
changedFiles = _ref.changedFiles;
|
||
|
|
// no SCM (git/hg/...) is found in any of the roots.
|
||
|
|
|
||
|
|
const noSCM = Object.keys(repos).every(function(scm) {
|
||
|
|
return repos[scm].size === 0;
|
||
|
|
});
|
||
|
|
return noSCM
|
||
|
|
? {noSCM: true, tests: []}
|
||
|
|
: _this.findRelatedTests(changedFiles, collectCoverage);
|
||
|
|
})();
|
||
|
|
}
|
||
|
|
|
||
|
|
_getTestPaths(globalConfig, changedFilesPromise) {
|
||
|
|
const paths = globalConfig.nonFlagArgs;
|
||
|
|
|
||
|
|
if (globalConfig.onlyChanged) {
|
||
|
|
if (!changedFilesPromise) {
|
||
|
|
throw new Error('This promise must be present when running with -o.');
|
||
|
|
}
|
||
|
|
|
||
|
|
return this.findTestRelatedToChangedFiles(
|
||
|
|
changedFilesPromise,
|
||
|
|
globalConfig.collectCoverage
|
||
|
|
);
|
||
|
|
} else if (globalConfig.runTestsByPath && paths && paths.length) {
|
||
|
|
return Promise.resolve(this.findTestsByPaths(paths));
|
||
|
|
} else if (globalConfig.findRelatedTests && paths && paths.length) {
|
||
|
|
return Promise.resolve(
|
||
|
|
this.findRelatedTestsFromPattern(paths, globalConfig.collectCoverage)
|
||
|
|
);
|
||
|
|
} else if (globalConfig.testPathPattern != null) {
|
||
|
|
return Promise.resolve(
|
||
|
|
this.findMatchingTests(globalConfig.testPathPattern)
|
||
|
|
);
|
||
|
|
} else {
|
||
|
|
return Promise.resolve({tests: []});
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
getTestPaths(globalConfig, changedFilesPromise) {
|
||
|
|
var _this2 = this;
|
||
|
|
|
||
|
|
return _asyncToGenerator(function*() {
|
||
|
|
const searchResult = yield _this2._getTestPaths(
|
||
|
|
globalConfig,
|
||
|
|
changedFilesPromise
|
||
|
|
);
|
||
|
|
|
||
|
|
const filterPath = globalConfig.filter;
|
||
|
|
|
||
|
|
if (filterPath && !globalConfig.skipFilter) {
|
||
|
|
const tests = searchResult.tests;
|
||
|
|
|
||
|
|
// $FlowFixMe: dynamic require.
|
||
|
|
const filter = require(filterPath);
|
||
|
|
const filterResult = yield filter(
|
||
|
|
tests.map(function(test) {
|
||
|
|
return test.path;
|
||
|
|
})
|
||
|
|
);
|
||
|
|
|
||
|
|
if (!Array.isArray(filterResult.filtered)) {
|
||
|
|
throw new Error(
|
||
|
|
`Filter ${filterPath} did not return a valid test list`
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
const filteredSet = new Set(
|
||
|
|
filterResult.filtered.map(function(result) {
|
||
|
|
return result.test;
|
||
|
|
})
|
||
|
|
);
|
||
|
|
|
||
|
|
// $FlowFixMe: Object.assign with empty object causes troubles to Flow.
|
||
|
|
return Object.assign({}, searchResult, {
|
||
|
|
tests: tests.filter(function(test) {
|
||
|
|
return filteredSet.has(test.path);
|
||
|
|
})
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
return searchResult;
|
||
|
|
})();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
exports.default = SearchSource;
|