aboutsummaryrefslogtreecommitdiff
path: root/node_modules/jest-snapshot/build/utils.js
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/jest-snapshot/build/utils.js')
-rw-r--r--node_modules/jest-snapshot/build/utils.js460
1 files changed, 460 insertions, 0 deletions
diff --git a/node_modules/jest-snapshot/build/utils.js b/node_modules/jest-snapshot/build/utils.js
new file mode 100644
index 0000000..3c6b4ba
--- /dev/null
+++ b/node_modules/jest-snapshot/build/utils.js
@@ -0,0 +1,460 @@
+'use strict';
+
+Object.defineProperty(exports, '__esModule', {
+ value: true
+});
+exports.testNameToKey =
+ exports.serialize =
+ exports.saveSnapshotFile =
+ exports.removeLinesBeforeExternalMatcherTrap =
+ exports.removeExtraLineBreaks =
+ exports.minify =
+ exports.keyToTestName =
+ exports.getSnapshotData =
+ exports.escapeBacktickString =
+ exports.ensureDirectoryExists =
+ exports.deserializeString =
+ exports.deepMerge =
+ exports.addExtraLineBreaks =
+ exports.SNAPSHOT_VERSION_WARNING =
+ exports.SNAPSHOT_VERSION =
+ exports.SNAPSHOT_GUIDE_LINK =
+ void 0;
+
+var path = _interopRequireWildcard(require('path'));
+
+var _chalk = _interopRequireDefault(require('chalk'));
+
+var fs = _interopRequireWildcard(require('graceful-fs'));
+
+var _naturalCompare = _interopRequireDefault(require('natural-compare'));
+
+var _prettyFormat = require('pretty-format');
+
+var _plugins = require('./plugins');
+
+function _interopRequireDefault(obj) {
+ return obj && obj.__esModule ? obj : {default: obj};
+}
+
+function _getRequireWildcardCache(nodeInterop) {
+ if (typeof WeakMap !== 'function') return null;
+ var cacheBabelInterop = new WeakMap();
+ var cacheNodeInterop = new WeakMap();
+ return (_getRequireWildcardCache = function (nodeInterop) {
+ return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
+ })(nodeInterop);
+}
+
+function _interopRequireWildcard(obj, nodeInterop) {
+ if (!nodeInterop && obj && obj.__esModule) {
+ return obj;
+ }
+ if (obj === null || (typeof obj !== 'object' && typeof obj !== 'function')) {
+ return {default: obj};
+ }
+ var cache = _getRequireWildcardCache(nodeInterop);
+ if (cache && cache.has(obj)) {
+ return cache.get(obj);
+ }
+ var newObj = {};
+ var hasPropertyDescriptor =
+ Object.defineProperty && Object.getOwnPropertyDescriptor;
+ for (var key in obj) {
+ if (key !== 'default' && Object.prototype.hasOwnProperty.call(obj, key)) {
+ var desc = hasPropertyDescriptor
+ ? Object.getOwnPropertyDescriptor(obj, key)
+ : null;
+ if (desc && (desc.get || desc.set)) {
+ Object.defineProperty(newObj, key, desc);
+ } else {
+ newObj[key] = obj[key];
+ }
+ }
+ }
+ newObj.default = obj;
+ if (cache) {
+ cache.set(obj, newObj);
+ }
+ return newObj;
+}
+
+var global = (function () {
+ if (typeof globalThis !== 'undefined') {
+ return globalThis;
+ } else if (typeof global !== 'undefined') {
+ return global;
+ } else if (typeof self !== 'undefined') {
+ return self;
+ } else if (typeof window !== 'undefined') {
+ return window;
+ } else {
+ return Function('return this')();
+ }
+})();
+
+var Symbol = global['jest-symbol-do-not-touch'] || global.Symbol;
+
+var global = (function () {
+ if (typeof globalThis !== 'undefined') {
+ return globalThis;
+ } else if (typeof global !== 'undefined') {
+ return global;
+ } else if (typeof self !== 'undefined') {
+ return self;
+ } else if (typeof window !== 'undefined') {
+ return window;
+ } else {
+ return Function('return this')();
+ }
+})();
+
+var Symbol = global['jest-symbol-do-not-touch'] || global.Symbol;
+
+var global = (function () {
+ if (typeof globalThis !== 'undefined') {
+ return globalThis;
+ } else if (typeof global !== 'undefined') {
+ return global;
+ } else if (typeof self !== 'undefined') {
+ return self;
+ } else if (typeof window !== 'undefined') {
+ return window;
+ } else {
+ return Function('return this')();
+ }
+})();
+
+var jestWriteFile =
+ global[Symbol.for('jest-native-write-file')] || fs.writeFileSync;
+
+var global = (function () {
+ if (typeof globalThis !== 'undefined') {
+ return globalThis;
+ } else if (typeof global !== 'undefined') {
+ return global;
+ } else if (typeof self !== 'undefined') {
+ return self;
+ } else if (typeof window !== 'undefined') {
+ return window;
+ } else {
+ return Function('return this')();
+ }
+})();
+
+var Symbol = global['jest-symbol-do-not-touch'] || global.Symbol;
+
+var global = (function () {
+ if (typeof globalThis !== 'undefined') {
+ return globalThis;
+ } else if (typeof global !== 'undefined') {
+ return global;
+ } else if (typeof self !== 'undefined') {
+ return self;
+ } else if (typeof window !== 'undefined') {
+ return window;
+ } else {
+ return Function('return this')();
+ }
+})();
+
+var jestReadFile =
+ global[Symbol.for('jest-native-read-file')] || fs.readFileSync;
+
+var global = (function () {
+ if (typeof globalThis !== 'undefined') {
+ return globalThis;
+ } else if (typeof global !== 'undefined') {
+ return global;
+ } else if (typeof self !== 'undefined') {
+ return self;
+ } else if (typeof window !== 'undefined') {
+ return window;
+ } else {
+ return Function('return this')();
+ }
+})();
+
+var Symbol = global['jest-symbol-do-not-touch'] || global.Symbol;
+
+var global = (function () {
+ if (typeof globalThis !== 'undefined') {
+ return globalThis;
+ } else if (typeof global !== 'undefined') {
+ return global;
+ } else if (typeof self !== 'undefined') {
+ return self;
+ } else if (typeof window !== 'undefined') {
+ return window;
+ } else {
+ return Function('return this')();
+ }
+})();
+
+var jestExistsFile =
+ global[Symbol.for('jest-native-exists-file')] || fs.existsSync;
+const SNAPSHOT_VERSION = '1';
+exports.SNAPSHOT_VERSION = SNAPSHOT_VERSION;
+const SNAPSHOT_VERSION_REGEXP = /^\/\/ Jest Snapshot v(.+),/;
+const SNAPSHOT_GUIDE_LINK = 'https://goo.gl/fbAQLP';
+exports.SNAPSHOT_GUIDE_LINK = SNAPSHOT_GUIDE_LINK;
+
+const SNAPSHOT_VERSION_WARNING = _chalk.default.yellow(
+ `${_chalk.default.bold('Warning')}: Before you upgrade snapshots, ` +
+ 'we recommend that you revert any local changes to tests or other code, ' +
+ 'to ensure that you do not store invalid state.'
+);
+
+exports.SNAPSHOT_VERSION_WARNING = SNAPSHOT_VERSION_WARNING;
+
+const writeSnapshotVersion = () =>
+ `// Jest Snapshot v${SNAPSHOT_VERSION}, ${SNAPSHOT_GUIDE_LINK}`;
+
+const validateSnapshotVersion = snapshotContents => {
+ const versionTest = SNAPSHOT_VERSION_REGEXP.exec(snapshotContents);
+ const version = versionTest && versionTest[1];
+
+ if (!version) {
+ return new Error(
+ _chalk.default.red(
+ `${_chalk.default.bold(
+ 'Outdated snapshot'
+ )}: No snapshot header found. ` +
+ 'Jest 19 introduced versioned snapshots to ensure all developers ' +
+ 'on a project are using the same version of Jest. ' +
+ 'Please update all snapshots during this upgrade of Jest.\n\n'
+ ) + SNAPSHOT_VERSION_WARNING
+ );
+ }
+
+ if (version < SNAPSHOT_VERSION) {
+ return new Error(
+ _chalk.default.red(
+ `${_chalk.default.red.bold(
+ 'Outdated snapshot'
+ )}: The version of the snapshot ` +
+ 'file associated with this test is outdated. The snapshot file ' +
+ 'version ensures that all developers on a project are using ' +
+ 'the same version of Jest. ' +
+ 'Please update all snapshots during this upgrade of Jest.\n\n'
+ ) +
+ `Expected: v${SNAPSHOT_VERSION}\n` +
+ `Received: v${version}\n\n` +
+ SNAPSHOT_VERSION_WARNING
+ );
+ }
+
+ if (version > SNAPSHOT_VERSION) {
+ return new Error(
+ _chalk.default.red(
+ `${_chalk.default.red.bold(
+ 'Outdated Jest version'
+ )}: The version of this ` +
+ 'snapshot file indicates that this project is meant to be used ' +
+ 'with a newer version of Jest. The snapshot file version ensures ' +
+ 'that all developers on a project are using the same version of ' +
+ 'Jest. Please update your version of Jest and re-run the tests.\n\n'
+ ) +
+ `Expected: v${SNAPSHOT_VERSION}\n` +
+ `Received: v${version}`
+ );
+ }
+
+ return null;
+};
+
+function isObject(item) {
+ return item != null && typeof item === 'object' && !Array.isArray(item);
+}
+
+const testNameToKey = (testName, count) => testName + ' ' + count;
+
+exports.testNameToKey = testNameToKey;
+
+const keyToTestName = key => {
+ if (!/ \d+$/.test(key)) {
+ throw new Error('Snapshot keys must end with a number.');
+ }
+
+ return key.replace(/ \d+$/, '');
+};
+
+exports.keyToTestName = keyToTestName;
+
+const getSnapshotData = (snapshotPath, update) => {
+ const data = Object.create(null);
+ let snapshotContents = '';
+ let dirty = false;
+
+ if (jestExistsFile(snapshotPath)) {
+ try {
+ snapshotContents = jestReadFile(snapshotPath, 'utf8'); // eslint-disable-next-line no-new-func
+
+ const populate = new Function('exports', snapshotContents);
+ populate(data);
+ } catch {}
+ }
+
+ const validationResult = validateSnapshotVersion(snapshotContents);
+ const isInvalid = snapshotContents && validationResult;
+
+ if (update === 'none' && isInvalid) {
+ throw validationResult;
+ }
+
+ if ((update === 'all' || update === 'new') && isInvalid) {
+ dirty = true;
+ }
+
+ return {
+ data,
+ dirty
+ };
+}; // Add extra line breaks at beginning and end of multiline snapshot
+// to make the content easier to read.
+
+exports.getSnapshotData = getSnapshotData;
+
+const addExtraLineBreaks = string =>
+ string.includes('\n') ? `\n${string}\n` : string; // Remove extra line breaks at beginning and end of multiline snapshot.
+// Instead of trim, which can remove additional newlines or spaces
+// at beginning or end of the content from a custom serializer.
+
+exports.addExtraLineBreaks = addExtraLineBreaks;
+
+const removeExtraLineBreaks = string =>
+ string.length > 2 && string.startsWith('\n') && string.endsWith('\n')
+ ? string.slice(1, -1)
+ : string;
+
+exports.removeExtraLineBreaks = removeExtraLineBreaks;
+
+const removeLinesBeforeExternalMatcherTrap = stack => {
+ const lines = stack.split('\n');
+
+ for (let i = 0; i < lines.length; i += 1) {
+ // It's a function name specified in `packages/expect/src/index.ts`
+ // for external custom matchers.
+ if (lines[i].includes('__EXTERNAL_MATCHER_TRAP__')) {
+ return lines.slice(i + 1).join('\n');
+ }
+ }
+
+ return stack;
+};
+
+exports.removeLinesBeforeExternalMatcherTrap =
+ removeLinesBeforeExternalMatcherTrap;
+const escapeRegex = true;
+const printFunctionName = false;
+
+const serialize = (val, indent = 2, formatOverrides = {}) =>
+ normalizeNewlines(
+ (0, _prettyFormat.format)(val, {
+ escapeRegex,
+ indent,
+ plugins: (0, _plugins.getSerializers)(),
+ printFunctionName,
+ ...formatOverrides
+ })
+ );
+
+exports.serialize = serialize;
+
+const minify = val =>
+ (0, _prettyFormat.format)(val, {
+ escapeRegex,
+ min: true,
+ plugins: (0, _plugins.getSerializers)(),
+ printFunctionName
+ }); // Remove double quote marks and unescape double quotes and backslashes.
+
+exports.minify = minify;
+
+const deserializeString = stringified =>
+ stringified.slice(1, -1).replace(/\\("|\\)/g, '$1');
+
+exports.deserializeString = deserializeString;
+
+const escapeBacktickString = str => str.replace(/`|\\|\${/g, '\\$&');
+
+exports.escapeBacktickString = escapeBacktickString;
+
+const printBacktickString = str => '`' + escapeBacktickString(str) + '`';
+
+const ensureDirectoryExists = filePath => {
+ try {
+ fs.mkdirSync(path.join(path.dirname(filePath)), {
+ recursive: true
+ });
+ } catch {}
+};
+
+exports.ensureDirectoryExists = ensureDirectoryExists;
+
+const normalizeNewlines = string => string.replace(/\r\n|\r/g, '\n');
+
+const saveSnapshotFile = (snapshotData, snapshotPath) => {
+ const snapshots = Object.keys(snapshotData)
+ .sort(_naturalCompare.default)
+ .map(
+ key =>
+ 'exports[' +
+ printBacktickString(key) +
+ '] = ' +
+ printBacktickString(normalizeNewlines(snapshotData[key])) +
+ ';'
+ );
+ ensureDirectoryExists(snapshotPath);
+ jestWriteFile(
+ snapshotPath,
+ writeSnapshotVersion() + '\n\n' + snapshots.join('\n\n') + '\n'
+ );
+};
+
+exports.saveSnapshotFile = saveSnapshotFile;
+
+const deepMergeArray = (target, source) => {
+ const mergedOutput = Array.from(target);
+ source.forEach((sourceElement, index) => {
+ const targetElement = mergedOutput[index];
+
+ if (Array.isArray(target[index])) {
+ mergedOutput[index] = deepMergeArray(target[index], sourceElement);
+ } else if (isObject(targetElement)) {
+ mergedOutput[index] = deepMerge(target[index], sourceElement);
+ } else {
+ // Source does not exist in target or target is primitive and cannot be deep merged
+ mergedOutput[index] = sourceElement;
+ }
+ });
+ return mergedOutput;
+}; // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
+
+const deepMerge = (target, source) => {
+ if (isObject(target) && isObject(source)) {
+ const mergedOutput = {...target};
+ Object.keys(source).forEach(key => {
+ if (isObject(source[key]) && !source[key].$$typeof) {
+ if (!(key in target))
+ Object.assign(mergedOutput, {
+ [key]: source[key]
+ });
+ else mergedOutput[key] = deepMerge(target[key], source[key]);
+ } else if (Array.isArray(source[key])) {
+ mergedOutput[key] = deepMergeArray(target[key], source[key]);
+ } else {
+ Object.assign(mergedOutput, {
+ [key]: source[key]
+ });
+ }
+ });
+ return mergedOutput;
+ } else if (Array.isArray(target) && Array.isArray(source)) {
+ return deepMergeArray(target, source);
+ }
+
+ return target;
+};
+
+exports.deepMerge = deepMerge;