Added test to ensure that release notes are parsed properly Updated to latest dependencies to fix security vulnerability Updated GH Actions Workflow to run test before updating tag Updated README.md to reflect proper whatsnew documentation.
864 lines
21 KiB
JavaScript
864 lines
21 KiB
JavaScript
'use strict';
|
|
|
|
Object.defineProperty(exports, '__esModule', {
|
|
value: true
|
|
});
|
|
exports.default = void 0;
|
|
|
|
function _crypto() {
|
|
const data = _interopRequireDefault(require('crypto'));
|
|
|
|
_crypto = function _crypto() {
|
|
return data;
|
|
};
|
|
|
|
return data;
|
|
}
|
|
|
|
function _path() {
|
|
const data = _interopRequireDefault(require('path'));
|
|
|
|
_path = function _path() {
|
|
return data;
|
|
};
|
|
|
|
return data;
|
|
}
|
|
|
|
function _vm() {
|
|
const data = _interopRequireDefault(require('vm'));
|
|
|
|
_vm = function _vm() {
|
|
return data;
|
|
};
|
|
|
|
return data;
|
|
}
|
|
|
|
function _jestUtil() {
|
|
const data = require('jest-util');
|
|
|
|
_jestUtil = function _jestUtil() {
|
|
return data;
|
|
};
|
|
|
|
return data;
|
|
}
|
|
|
|
function _gracefulFs() {
|
|
const data = _interopRequireDefault(require('graceful-fs'));
|
|
|
|
_gracefulFs = function _gracefulFs() {
|
|
return data;
|
|
};
|
|
|
|
return data;
|
|
}
|
|
|
|
function _core() {
|
|
const data = require('@babel/core');
|
|
|
|
_core = function _core() {
|
|
return data;
|
|
};
|
|
|
|
return data;
|
|
}
|
|
|
|
function _babelPluginIstanbul() {
|
|
const data = _interopRequireDefault(require('babel-plugin-istanbul'));
|
|
|
|
_babelPluginIstanbul = function _babelPluginIstanbul() {
|
|
return data;
|
|
};
|
|
|
|
return data;
|
|
}
|
|
|
|
function _convertSourceMap() {
|
|
const data = _interopRequireDefault(require('convert-source-map'));
|
|
|
|
_convertSourceMap = function _convertSourceMap() {
|
|
return data;
|
|
};
|
|
|
|
return data;
|
|
}
|
|
|
|
function _jestHasteMap() {
|
|
const data = _interopRequireDefault(require('jest-haste-map'));
|
|
|
|
_jestHasteMap = function _jestHasteMap() {
|
|
return data;
|
|
};
|
|
|
|
return data;
|
|
}
|
|
|
|
function _fastJsonStableStringify() {
|
|
const data = _interopRequireDefault(require('fast-json-stable-stringify'));
|
|
|
|
_fastJsonStableStringify = function _fastJsonStableStringify() {
|
|
return data;
|
|
};
|
|
|
|
return data;
|
|
}
|
|
|
|
function _slash() {
|
|
const data = _interopRequireDefault(require('slash'));
|
|
|
|
_slash = function _slash() {
|
|
return data;
|
|
};
|
|
|
|
return data;
|
|
}
|
|
|
|
function _writeFileAtomic() {
|
|
const data = _interopRequireDefault(require('write-file-atomic'));
|
|
|
|
_writeFileAtomic = function _writeFileAtomic() {
|
|
return data;
|
|
};
|
|
|
|
return data;
|
|
}
|
|
|
|
function _realpathNative() {
|
|
const data = require('realpath-native');
|
|
|
|
_realpathNative = function _realpathNative() {
|
|
return data;
|
|
};
|
|
|
|
return data;
|
|
}
|
|
|
|
function _pirates() {
|
|
const data = require('pirates');
|
|
|
|
_pirates = function _pirates() {
|
|
return data;
|
|
};
|
|
|
|
return data;
|
|
}
|
|
|
|
var _shouldInstrument = _interopRequireDefault(require('./shouldInstrument'));
|
|
|
|
var _enhanceUnexpectedTokenMessage = _interopRequireDefault(
|
|
require('./enhanceUnexpectedTokenMessage')
|
|
);
|
|
|
|
function _interopRequireDefault(obj) {
|
|
return obj && obj.__esModule ? obj : {default: obj};
|
|
}
|
|
|
|
function _defineProperty(obj, key, value) {
|
|
if (key in obj) {
|
|
Object.defineProperty(obj, key, {
|
|
value: value,
|
|
enumerable: true,
|
|
configurable: true,
|
|
writable: true
|
|
});
|
|
} else {
|
|
obj[key] = value;
|
|
}
|
|
return obj;
|
|
}
|
|
|
|
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
|
|
try {
|
|
var info = gen[key](arg);
|
|
var value = info.value;
|
|
} catch (error) {
|
|
reject(error);
|
|
return;
|
|
}
|
|
if (info.done) {
|
|
resolve(value);
|
|
} else {
|
|
Promise.resolve(value).then(_next, _throw);
|
|
}
|
|
}
|
|
|
|
function _asyncToGenerator(fn) {
|
|
return function() {
|
|
var self = this,
|
|
args = arguments;
|
|
return new Promise(function(resolve, reject) {
|
|
var gen = fn.apply(self, args);
|
|
function _next(value) {
|
|
asyncGeneratorStep(gen, resolve, reject, _next, _throw, 'next', value);
|
|
}
|
|
function _throw(err) {
|
|
asyncGeneratorStep(gen, resolve, reject, _next, _throw, 'throw', err);
|
|
}
|
|
_next(undefined);
|
|
});
|
|
};
|
|
}
|
|
|
|
// Use `require` to avoid TS rootDir
|
|
const _require = require('../package.json'),
|
|
VERSION = _require.version; // This data structure is used to avoid recalculating some data every time that
|
|
// we need to transform a file. Since ScriptTransformer is instantiated for each
|
|
// file we need to keep this object in the local scope of this module.
|
|
|
|
const projectCaches = new WeakMap(); // To reset the cache for specific changesets (rather than package version).
|
|
|
|
const CACHE_VERSION = '1';
|
|
|
|
function waitForPromiseWithCleanup(_x, _x2) {
|
|
return _waitForPromiseWithCleanup.apply(this, arguments);
|
|
}
|
|
|
|
function _waitForPromiseWithCleanup() {
|
|
_waitForPromiseWithCleanup = _asyncToGenerator(function*(promise, cleanup) {
|
|
try {
|
|
yield promise;
|
|
} finally {
|
|
cleanup();
|
|
}
|
|
});
|
|
return _waitForPromiseWithCleanup.apply(this, arguments);
|
|
}
|
|
|
|
class ScriptTransformer {
|
|
constructor(config) {
|
|
_defineProperty(this, '_cache', void 0);
|
|
|
|
_defineProperty(this, '_config', void 0);
|
|
|
|
_defineProperty(this, '_transformCache', void 0);
|
|
|
|
_defineProperty(this, '_transformConfigCache', void 0);
|
|
|
|
this._config = config;
|
|
this._transformCache = new Map();
|
|
this._transformConfigCache = new Map();
|
|
let projectCache = projectCaches.get(config);
|
|
|
|
if (!projectCache) {
|
|
projectCache = {
|
|
configString: (0, _fastJsonStableStringify().default)(this._config),
|
|
ignorePatternsRegExp: calcIgnorePatternRegExp(this._config),
|
|
transformRegExp: calcTransformRegExp(this._config),
|
|
transformedFiles: new Map()
|
|
};
|
|
projectCaches.set(config, projectCache);
|
|
}
|
|
|
|
this._cache = projectCache;
|
|
}
|
|
|
|
_getCacheKey(fileData, filename, instrument) {
|
|
const configString = this._cache.configString;
|
|
|
|
const transformer = this._getTransformer(filename);
|
|
|
|
if (transformer && typeof transformer.getCacheKey === 'function') {
|
|
return _crypto()
|
|
.default.createHash('md5')
|
|
.update(
|
|
transformer.getCacheKey(fileData, filename, configString, {
|
|
config: this._config,
|
|
instrument,
|
|
rootDir: this._config.rootDir
|
|
})
|
|
)
|
|
.update(CACHE_VERSION)
|
|
.digest('hex');
|
|
} else {
|
|
return _crypto()
|
|
.default.createHash('md5')
|
|
.update(fileData)
|
|
.update(configString)
|
|
.update(instrument ? 'instrument' : '')
|
|
.update(filename)
|
|
.update(CACHE_VERSION)
|
|
.digest('hex');
|
|
}
|
|
}
|
|
|
|
_getFileCachePath(filename, content, instrument) {
|
|
const baseCacheDir = _jestHasteMap().default.getCacheFilePath(
|
|
this._config.cacheDirectory,
|
|
'jest-transform-cache-' + this._config.name,
|
|
VERSION
|
|
);
|
|
|
|
const cacheKey = this._getCacheKey(content, filename, instrument); // Create sub folders based on the cacheKey to avoid creating one
|
|
// directory with many files.
|
|
|
|
const cacheDir = _path().default.join(
|
|
baseCacheDir,
|
|
cacheKey[0] + cacheKey[1]
|
|
);
|
|
|
|
const cacheFilenamePrefix = _path()
|
|
.default.basename(filename, _path().default.extname(filename))
|
|
.replace(/\W/g, '');
|
|
|
|
const cachePath = (0, _slash().default)(
|
|
_path().default.join(cacheDir, cacheFilenamePrefix + '_' + cacheKey)
|
|
);
|
|
(0, _jestUtil().createDirectory)(cacheDir);
|
|
return cachePath;
|
|
}
|
|
|
|
_getTransformPath(filename) {
|
|
const transformRegExp = this._cache.transformRegExp;
|
|
|
|
if (!transformRegExp) {
|
|
return undefined;
|
|
}
|
|
|
|
for (let i = 0; i < transformRegExp.length; i++) {
|
|
if (transformRegExp[i][0].test(filename)) {
|
|
const transformPath = transformRegExp[i][1];
|
|
|
|
this._transformConfigCache.set(transformPath, transformRegExp[i][2]);
|
|
|
|
return transformPath;
|
|
}
|
|
}
|
|
|
|
return undefined;
|
|
}
|
|
|
|
_getTransformer(filename) {
|
|
let transform = null;
|
|
|
|
if (!this._config.transform || !this._config.transform.length) {
|
|
return null;
|
|
}
|
|
|
|
const transformPath = this._getTransformPath(filename);
|
|
|
|
if (transformPath) {
|
|
const transformer = this._transformCache.get(transformPath);
|
|
|
|
if (transformer != null) {
|
|
return transformer;
|
|
}
|
|
|
|
transform = require(transformPath);
|
|
|
|
const transformerConfig = this._transformConfigCache.get(transformPath);
|
|
|
|
if (typeof transform.createTransformer === 'function') {
|
|
transform = transform.createTransformer(transformerConfig);
|
|
}
|
|
|
|
if (typeof transform.process !== 'function') {
|
|
throw new TypeError(
|
|
'Jest: a transform must export a `process` function.'
|
|
);
|
|
}
|
|
|
|
this._transformCache.set(transformPath, transform);
|
|
}
|
|
|
|
return transform;
|
|
}
|
|
|
|
_instrumentFile(filename, content) {
|
|
const result = (0, _core().transformSync)(content, {
|
|
auxiliaryCommentBefore: ' istanbul ignore next ',
|
|
babelrc: false,
|
|
caller: {
|
|
name: '@jest/transform',
|
|
supportsStaticESM: false
|
|
},
|
|
configFile: false,
|
|
filename,
|
|
plugins: [
|
|
[
|
|
_babelPluginIstanbul().default,
|
|
{
|
|
compact: false,
|
|
// files outside `cwd` will not be instrumented
|
|
cwd: this._config.rootDir,
|
|
exclude: [],
|
|
useInlineSourceMaps: false
|
|
}
|
|
]
|
|
]
|
|
});
|
|
|
|
if (result) {
|
|
const code = result.code;
|
|
|
|
if (code) {
|
|
return code;
|
|
}
|
|
}
|
|
|
|
return content;
|
|
}
|
|
|
|
_getRealPath(filepath) {
|
|
try {
|
|
return (0, _realpathNative().sync)(filepath) || filepath;
|
|
} catch (err) {
|
|
return filepath;
|
|
}
|
|
} // We don't want to expose transformers to the outside - this function is just
|
|
// to warm up `this._transformCache`
|
|
|
|
preloadTransformer(filepath) {
|
|
this._getTransformer(filepath);
|
|
}
|
|
|
|
transformSource(filepath, content, instrument) {
|
|
const filename = this._getRealPath(filepath);
|
|
|
|
const transform = this._getTransformer(filename);
|
|
|
|
const cacheFilePath = this._getFileCachePath(filename, content, instrument);
|
|
|
|
let sourceMapPath = cacheFilePath + '.map'; // Ignore cache if `config.cache` is set (--no-cache)
|
|
|
|
let code = this._config.cache ? readCodeCacheFile(cacheFilePath) : null;
|
|
const shouldCallTransform = transform && this.shouldTransform(filename); // That means that the transform has a custom instrumentation
|
|
// logic and will handle it based on `config.collectCoverage` option
|
|
|
|
const transformWillInstrument =
|
|
shouldCallTransform && transform && transform.canInstrument; // If we handle the coverage instrumentation, we should try to map code
|
|
// coverage against original source with any provided source map
|
|
|
|
const mapCoverage = instrument && !transformWillInstrument;
|
|
|
|
if (code) {
|
|
// This is broken: we return the code, and a path for the source map
|
|
// directly from the cache. But, nothing ensures the source map actually
|
|
// matches that source code. They could have gotten out-of-sync in case
|
|
// two separate processes write concurrently to the same cache files.
|
|
return {
|
|
code,
|
|
mapCoverage,
|
|
sourceMapPath
|
|
};
|
|
}
|
|
|
|
let transformed = {
|
|
code: content,
|
|
map: null
|
|
};
|
|
|
|
if (transform && shouldCallTransform) {
|
|
const processed = transform.process(content, filename, this._config, {
|
|
instrument
|
|
});
|
|
|
|
if (typeof processed === 'string') {
|
|
transformed.code = processed;
|
|
} else if (processed != null && typeof processed.code === 'string') {
|
|
transformed = processed;
|
|
} else {
|
|
throw new TypeError(
|
|
"Jest: a transform's `process` function must return a string, " +
|
|
'or an object with `code` key containing this string.'
|
|
);
|
|
}
|
|
}
|
|
|
|
if (!transformed.map) {
|
|
//Could be a potential freeze here.
|
|
//See: https://github.com/facebook/jest/pull/5177#discussion_r158883570
|
|
const inlineSourceMap = _convertSourceMap().default.fromSource(
|
|
transformed.code
|
|
);
|
|
|
|
if (inlineSourceMap) {
|
|
transformed.map = inlineSourceMap.toJSON();
|
|
}
|
|
}
|
|
|
|
if (!transformWillInstrument && instrument) {
|
|
code = this._instrumentFile(filename, transformed.code);
|
|
} else {
|
|
code = transformed.code;
|
|
}
|
|
|
|
if (transformed.map) {
|
|
const sourceMapContent =
|
|
typeof transformed.map === 'string'
|
|
? transformed.map
|
|
: JSON.stringify(transformed.map);
|
|
writeCacheFile(sourceMapPath, sourceMapContent);
|
|
} else {
|
|
sourceMapPath = null;
|
|
}
|
|
|
|
writeCodeCacheFile(cacheFilePath, code);
|
|
return {
|
|
code,
|
|
mapCoverage,
|
|
sourceMapPath
|
|
};
|
|
}
|
|
|
|
_transformAndBuildScript(filename, options, instrument, fileSource) {
|
|
const isInternalModule = !!(options && options.isInternalModule);
|
|
const isCoreModule = !!(options && options.isCoreModule);
|
|
const content = stripShebang(
|
|
fileSource || _gracefulFs().default.readFileSync(filename, 'utf8')
|
|
);
|
|
let wrappedCode;
|
|
let sourceMapPath = null;
|
|
let mapCoverage = false;
|
|
const willTransform =
|
|
!isInternalModule &&
|
|
!isCoreModule &&
|
|
(this.shouldTransform(filename) || instrument);
|
|
|
|
try {
|
|
const extraGlobals = (options && options.extraGlobals) || [];
|
|
|
|
if (willTransform) {
|
|
const transformedSource = this.transformSource(
|
|
filename,
|
|
content,
|
|
instrument
|
|
);
|
|
wrappedCode = wrap(transformedSource.code, ...extraGlobals);
|
|
sourceMapPath = transformedSource.sourceMapPath;
|
|
mapCoverage = transformedSource.mapCoverage;
|
|
} else {
|
|
wrappedCode = wrap(content, ...extraGlobals);
|
|
}
|
|
|
|
return {
|
|
mapCoverage,
|
|
script: new (_vm()).default.Script(wrappedCode, {
|
|
displayErrors: true,
|
|
filename: isCoreModule ? 'jest-nodejs-core-' + filename : filename
|
|
}),
|
|
sourceMapPath
|
|
};
|
|
} catch (e) {
|
|
if (e.codeFrame) {
|
|
e.stack = e.message + '\n' + e.codeFrame;
|
|
}
|
|
|
|
if (
|
|
e instanceof SyntaxError &&
|
|
e.message.includes('Unexpected token') &&
|
|
!e.message.includes(' expected')
|
|
) {
|
|
throw (0, _enhanceUnexpectedTokenMessage.default)(e);
|
|
}
|
|
|
|
throw e;
|
|
}
|
|
}
|
|
|
|
transform(filename, options, fileSource) {
|
|
let scriptCacheKey = undefined;
|
|
let instrument = false;
|
|
|
|
if (!options.isCoreModule) {
|
|
instrument = (0, _shouldInstrument.default)(
|
|
filename,
|
|
options,
|
|
this._config
|
|
);
|
|
scriptCacheKey = getScriptCacheKey(filename, instrument);
|
|
|
|
const result = this._cache.transformedFiles.get(scriptCacheKey);
|
|
|
|
if (result) {
|
|
return result;
|
|
}
|
|
}
|
|
|
|
const result = this._transformAndBuildScript(
|
|
filename,
|
|
options,
|
|
instrument,
|
|
fileSource
|
|
);
|
|
|
|
if (scriptCacheKey) {
|
|
this._cache.transformedFiles.set(scriptCacheKey, result);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
transformJson(filename, options, fileSource) {
|
|
const isInternalModule = options.isInternalModule;
|
|
const isCoreModule = options.isCoreModule;
|
|
const willTransform =
|
|
!isInternalModule && !isCoreModule && this.shouldTransform(filename);
|
|
|
|
if (willTransform) {
|
|
const _this$transformSource = this.transformSource(
|
|
filename,
|
|
fileSource,
|
|
false
|
|
),
|
|
transformedJsonSource = _this$transformSource.code;
|
|
|
|
return transformedJsonSource;
|
|
}
|
|
|
|
return fileSource;
|
|
}
|
|
|
|
requireAndTranspileModule(moduleName, callback) {
|
|
// Load the transformer to avoid a cycle where we need to load a
|
|
// transformer in order to transform it in the require hooks
|
|
this.preloadTransformer(moduleName);
|
|
let transforming = false;
|
|
const revertHook = (0, _pirates().addHook)(
|
|
(code, filename) => {
|
|
try {
|
|
transforming = true;
|
|
return this.transformSource(filename, code, false).code || code;
|
|
} finally {
|
|
transforming = false;
|
|
}
|
|
},
|
|
{
|
|
exts: [_path().default.extname(moduleName)],
|
|
ignoreNodeModules: false,
|
|
matcher: filename => {
|
|
if (transforming) {
|
|
// Don't transform any dependency required by the transformer itself
|
|
return false;
|
|
}
|
|
|
|
return this.shouldTransform(filename);
|
|
}
|
|
}
|
|
);
|
|
|
|
const module = require(moduleName);
|
|
|
|
if (!callback) {
|
|
revertHook();
|
|
return module;
|
|
}
|
|
|
|
try {
|
|
const cbResult = callback(module);
|
|
|
|
if ((0, _jestUtil().isPromise)(cbResult)) {
|
|
return waitForPromiseWithCleanup(cbResult, revertHook).then(
|
|
() => module
|
|
);
|
|
}
|
|
} finally {
|
|
revertHook();
|
|
}
|
|
|
|
return module;
|
|
}
|
|
/**
|
|
* @deprecated use `this.shouldTransform` instead
|
|
*/
|
|
// @ts-ignore: Unused and private - remove in Jest 25
|
|
|
|
_shouldTransform(filename) {
|
|
return this.shouldTransform(filename);
|
|
}
|
|
|
|
shouldTransform(filename) {
|
|
const ignoreRegexp = this._cache.ignorePatternsRegExp;
|
|
const isIgnored = ignoreRegexp ? ignoreRegexp.test(filename) : false;
|
|
return (
|
|
!!this._config.transform && !!this._config.transform.length && !isIgnored
|
|
);
|
|
}
|
|
}
|
|
|
|
exports.default = ScriptTransformer;
|
|
|
|
_defineProperty(ScriptTransformer, 'EVAL_RESULT_VARIABLE', void 0);
|
|
|
|
const removeFile = path => {
|
|
try {
|
|
_gracefulFs().default.unlinkSync(path);
|
|
} catch (e) {}
|
|
};
|
|
|
|
const stripShebang = content => {
|
|
// If the file data starts with a shebang remove it. Leaves the empty line
|
|
// to keep stack trace line numbers correct.
|
|
if (content.startsWith('#!')) {
|
|
return content.replace(/^#!.*/, '');
|
|
} else {
|
|
return content;
|
|
}
|
|
};
|
|
/**
|
|
* This is like `writeCacheFile` but with an additional sanity checksum. We
|
|
* cannot use the same technique for source maps because we expose source map
|
|
* cache file paths directly to callsites, with the expectation they can read
|
|
* it right away. This is not a great system, because source map cache file
|
|
* could get corrupted, out-of-sync, etc.
|
|
*/
|
|
|
|
function writeCodeCacheFile(cachePath, code) {
|
|
const checksum = _crypto()
|
|
.default.createHash('md5')
|
|
.update(code)
|
|
.digest('hex');
|
|
|
|
writeCacheFile(cachePath, checksum + '\n' + code);
|
|
}
|
|
/**
|
|
* Read counterpart of `writeCodeCacheFile`. We verify that the content of the
|
|
* file matches the checksum, in case some kind of corruption happened. This
|
|
* could happen if an older version of `jest-runtime` writes non-atomically to
|
|
* the same cache, for example.
|
|
*/
|
|
|
|
function readCodeCacheFile(cachePath) {
|
|
const content = readCacheFile(cachePath);
|
|
|
|
if (content == null) {
|
|
return null;
|
|
}
|
|
|
|
const code = content.substr(33);
|
|
|
|
const checksum = _crypto()
|
|
.default.createHash('md5')
|
|
.update(code)
|
|
.digest('hex');
|
|
|
|
if (checksum === content.substr(0, 32)) {
|
|
return code;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
/**
|
|
* Writing to the cache atomically relies on 'rename' being atomic on most
|
|
* file systems. Doing atomic write reduces the risk of corruption by avoiding
|
|
* two processes to write to the same file at the same time. It also reduces
|
|
* the risk of reading a file that's being overwritten at the same time.
|
|
*/
|
|
|
|
const writeCacheFile = (cachePath, fileData) => {
|
|
try {
|
|
_writeFileAtomic().default.sync(cachePath, fileData, {
|
|
encoding: 'utf8'
|
|
});
|
|
} catch (e) {
|
|
if (cacheWriteErrorSafeToIgnore(e, cachePath)) {
|
|
return;
|
|
}
|
|
|
|
e.message =
|
|
'jest: failed to cache transform results in: ' +
|
|
cachePath +
|
|
'\nFailure message: ' +
|
|
e.message;
|
|
removeFile(cachePath);
|
|
throw e;
|
|
}
|
|
};
|
|
/**
|
|
* On Windows, renames are not atomic, leading to EPERM exceptions when two
|
|
* processes attempt to rename to the same target file at the same time.
|
|
* If the target file exists we can be reasonably sure another process has
|
|
* legitimately won a cache write race and ignore the error.
|
|
*/
|
|
|
|
const cacheWriteErrorSafeToIgnore = (e, cachePath) =>
|
|
process.platform === 'win32' &&
|
|
e.code === 'EPERM' &&
|
|
_gracefulFs().default.existsSync(cachePath);
|
|
|
|
const readCacheFile = cachePath => {
|
|
if (!_gracefulFs().default.existsSync(cachePath)) {
|
|
return null;
|
|
}
|
|
|
|
let fileData;
|
|
|
|
try {
|
|
fileData = _gracefulFs().default.readFileSync(cachePath, 'utf8');
|
|
} catch (e) {
|
|
e.message =
|
|
'jest: failed to read cache file: ' +
|
|
cachePath +
|
|
'\nFailure message: ' +
|
|
e.message;
|
|
removeFile(cachePath);
|
|
throw e;
|
|
}
|
|
|
|
if (fileData == null) {
|
|
// We must have somehow created the file but failed to write to it,
|
|
// let's delete it and retry.
|
|
removeFile(cachePath);
|
|
}
|
|
|
|
return fileData;
|
|
};
|
|
|
|
const getScriptCacheKey = (filename, instrument) => {
|
|
const mtime = _gracefulFs().default.statSync(filename).mtime;
|
|
|
|
return filename + '_' + mtime.getTime() + (instrument ? '_instrumented' : '');
|
|
};
|
|
|
|
const calcIgnorePatternRegExp = config => {
|
|
if (
|
|
!config.transformIgnorePatterns ||
|
|
config.transformIgnorePatterns.length === 0
|
|
) {
|
|
return undefined;
|
|
}
|
|
|
|
return new RegExp(config.transformIgnorePatterns.join('|'));
|
|
};
|
|
|
|
const calcTransformRegExp = config => {
|
|
if (!config.transform.length) {
|
|
return undefined;
|
|
}
|
|
|
|
const transformRegexp = [];
|
|
|
|
for (let i = 0; i < config.transform.length; i++) {
|
|
transformRegexp.push([
|
|
new RegExp(config.transform[i][0]),
|
|
config.transform[i][1],
|
|
config.transform[i][2]
|
|
]);
|
|
}
|
|
|
|
return transformRegexp;
|
|
};
|
|
|
|
const wrap = (content, ...extras) => {
|
|
const globals = new Set([
|
|
'module',
|
|
'exports',
|
|
'require',
|
|
'__dirname',
|
|
'__filename',
|
|
'global',
|
|
'jest',
|
|
...extras
|
|
]);
|
|
return (
|
|
'({"' +
|
|
ScriptTransformer.EVAL_RESULT_VARIABLE +
|
|
`":function(${Array.from(globals).join(',')}){` +
|
|
content +
|
|
'\n}});'
|
|
);
|
|
}; // TODO: Can this be added to the static property?
|
|
|
|
ScriptTransformer.EVAL_RESULT_VARIABLE = 'Object.<anonymous>';
|