diff options
Diffstat (limited to 'node_modules/jest-snapshot/build/index.js')
-rw-r--r-- | node_modules/jest-snapshot/build/index.js | 645 |
1 files changed, 645 insertions, 0 deletions
diff --git a/node_modules/jest-snapshot/build/index.js b/node_modules/jest-snapshot/build/index.js new file mode 100644 index 0000000..50fbbc5 --- /dev/null +++ b/node_modules/jest-snapshot/build/index.js @@ -0,0 +1,645 @@ +'use strict'; + +var fs = _interopRequireWildcard(require('graceful-fs')); + +var _jestMatcherUtils = require('jest-matcher-utils'); + +var _SnapshotResolver = require('./SnapshotResolver'); + +var _State = _interopRequireDefault(require('./State')); + +var _plugins = require('./plugins'); + +var _printSnapshot = require('./printSnapshot'); + +var utils = _interopRequireWildcard(require('./utils')); + +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 jestExistsFile = + global[Symbol.for('jest-native-exists-file')] || fs.existsSync; +const DID_NOT_THROW = 'Received function did not throw'; // same as toThrow + +const NOT_SNAPSHOT_MATCHERS = `Snapshot matchers cannot be used with ${(0, +_jestMatcherUtils.BOLD_WEIGHT)('not')}`; +const INDENTATION_REGEX = /^([^\S\n]*)\S/m; // Display name in report when matcher fails same as in snapshot file, +// but with optional hint argument in bold weight. + +const printSnapshotName = (concatenatedBlockNames = '', hint = '', count) => { + const hasNames = concatenatedBlockNames.length !== 0; + const hasHint = hint.length !== 0; + return ( + 'Snapshot name: `' + + (hasNames ? utils.escapeBacktickString(concatenatedBlockNames) : '') + + (hasNames && hasHint ? ': ' : '') + + (hasHint + ? (0, _jestMatcherUtils.BOLD_WEIGHT)(utils.escapeBacktickString(hint)) + : '') + + ' ' + + count + + '`' + ); +}; + +function stripAddedIndentation(inlineSnapshot) { + // Find indentation if exists. + const match = inlineSnapshot.match(INDENTATION_REGEX); + + if (!match || !match[1]) { + // No indentation. + return inlineSnapshot; + } + + const indentation = match[1]; + const lines = inlineSnapshot.split('\n'); + + if (lines.length <= 2) { + // Must be at least 3 lines. + return inlineSnapshot; + } + + if (lines[0].trim() !== '' || lines[lines.length - 1].trim() !== '') { + // If not blank first and last lines, abort. + return inlineSnapshot; + } + + for (let i = 1; i < lines.length - 1; i++) { + if (lines[i] !== '') { + if (lines[i].indexOf(indentation) !== 0) { + // All lines except first and last should either be blank or have the same + // indent as the first line (or more). If this isn't the case we don't + // want to touch the snapshot at all. + return inlineSnapshot; + } + + lines[i] = lines[i].substring(indentation.length); + } + } // Last line is a special case because it won't have the same indent as others + // but may still have been given some indent to line up. + + lines[lines.length - 1] = ''; // Return inline snapshot, now at indent 0. + + inlineSnapshot = lines.join('\n'); + return inlineSnapshot; +} + +const fileExists = (filePath, hasteFS) => + hasteFS.exists(filePath) || jestExistsFile(filePath); + +const cleanup = (hasteFS, update, snapshotResolver, testPathIgnorePatterns) => { + const pattern = '\\.' + _SnapshotResolver.EXTENSION + '$'; + const files = hasteFS.matchFiles(pattern); + let testIgnorePatternsRegex = null; + + if (testPathIgnorePatterns && testPathIgnorePatterns.length > 0) { + testIgnorePatternsRegex = new RegExp(testPathIgnorePatterns.join('|')); + } + + const list = files.filter(snapshotFile => { + const testPath = snapshotResolver.resolveTestPath(snapshotFile); // ignore snapshots of ignored tests + + if (testIgnorePatternsRegex && testIgnorePatternsRegex.test(testPath)) { + return false; + } + + if (!fileExists(testPath, hasteFS)) { + if (update === 'all') { + fs.unlinkSync(snapshotFile); + } + + return true; + } + + return false; + }); + return { + filesRemoved: list.length, + filesRemovedList: list + }; +}; + +const toMatchSnapshot = function (received, propertiesOrHint, hint) { + const matcherName = 'toMatchSnapshot'; + let properties; + const length = arguments.length; + + if (length === 2 && typeof propertiesOrHint === 'string') { + hint = propertiesOrHint; + } else if (length >= 2) { + if (typeof propertiesOrHint !== 'object' || propertiesOrHint === null) { + const options = { + isNot: this.isNot, + promise: this.promise + }; + let printedWithType = (0, _jestMatcherUtils.printWithType)( + 'Expected properties', + propertiesOrHint, + _printSnapshot.printExpected + ); + + if (length === 3) { + options.secondArgument = 'hint'; + options.secondArgumentColor = _jestMatcherUtils.BOLD_WEIGHT; + + if (propertiesOrHint == null) { + printedWithType += + "\n\nTo provide a hint without properties: toMatchSnapshot('hint')"; + } + } + + throw new Error( + (0, _jestMatcherUtils.matcherErrorMessage)( + (0, _jestMatcherUtils.matcherHint)( + matcherName, + undefined, + _printSnapshot.PROPERTIES_ARG, + options + ), + `Expected ${(0, _jestMatcherUtils.EXPECTED_COLOR)( + 'properties' + )} must be an object`, + printedWithType + ) + ); + } // Future breaking change: Snapshot hint must be a string + // if (arguments.length === 3 && typeof hint !== 'string') {} + + properties = propertiesOrHint; + } + + return _toMatchSnapshot({ + context: this, + hint, + isInline: false, + matcherName, + properties, + received + }); +}; + +const toMatchInlineSnapshot = function ( + received, + propertiesOrSnapshot, + inlineSnapshot +) { + const matcherName = 'toMatchInlineSnapshot'; + let properties; + const length = arguments.length; + + if (length === 2 && typeof propertiesOrSnapshot === 'string') { + inlineSnapshot = propertiesOrSnapshot; + } else if (length >= 2) { + const options = { + isNot: this.isNot, + promise: this.promise + }; + + if (length === 3) { + options.secondArgument = _printSnapshot.SNAPSHOT_ARG; + options.secondArgumentColor = _printSnapshot.noColor; + } + + if ( + typeof propertiesOrSnapshot !== 'object' || + propertiesOrSnapshot === null + ) { + throw new Error( + (0, _jestMatcherUtils.matcherErrorMessage)( + (0, _jestMatcherUtils.matcherHint)( + matcherName, + undefined, + _printSnapshot.PROPERTIES_ARG, + options + ), + `Expected ${(0, _jestMatcherUtils.EXPECTED_COLOR)( + 'properties' + )} must be an object`, + (0, _jestMatcherUtils.printWithType)( + 'Expected properties', + propertiesOrSnapshot, + _printSnapshot.printExpected + ) + ) + ); + } + + if (length === 3 && typeof inlineSnapshot !== 'string') { + throw new Error( + (0, _jestMatcherUtils.matcherErrorMessage)( + (0, _jestMatcherUtils.matcherHint)( + matcherName, + undefined, + _printSnapshot.PROPERTIES_ARG, + options + ), + 'Inline snapshot must be a string', + (0, _jestMatcherUtils.printWithType)( + 'Inline snapshot', + inlineSnapshot, + utils.serialize + ) + ) + ); + } + + properties = propertiesOrSnapshot; + } + + return _toMatchSnapshot({ + context: this, + inlineSnapshot: + inlineSnapshot !== undefined + ? stripAddedIndentation(inlineSnapshot) + : undefined, + isInline: true, + matcherName, + properties, + received + }); +}; + +const _toMatchSnapshot = config => { + const {context, hint, inlineSnapshot, isInline, matcherName, properties} = + config; + let {received} = config; + context.dontThrow && context.dontThrow(); + const {currentTestName, isNot, snapshotState} = context; + + if (isNot) { + throw new Error( + (0, _jestMatcherUtils.matcherErrorMessage)( + (0, _printSnapshot.matcherHintFromConfig)(config, false), + NOT_SNAPSHOT_MATCHERS + ) + ); + } + + if (snapshotState == null) { + // Because the state is the problem, this is not a matcher error. + // Call generic stringify from jest-matcher-utils package + // because uninitialized snapshot state does not need snapshot serializers. + throw new Error( + (0, _printSnapshot.matcherHintFromConfig)(config, false) + + '\n\n' + + 'Snapshot state must be initialized' + + '\n\n' + + (0, _jestMatcherUtils.printWithType)( + 'Snapshot state', + snapshotState, + _jestMatcherUtils.stringify + ) + ); + } + + const fullTestName = + currentTestName && hint + ? `${currentTestName}: ${hint}` + : currentTestName || ''; // future BREAKING change: || hint + + if (typeof properties === 'object') { + if (typeof received !== 'object' || received === null) { + throw new Error( + (0, _jestMatcherUtils.matcherErrorMessage)( + (0, _printSnapshot.matcherHintFromConfig)(config, false), + `${(0, _jestMatcherUtils.RECEIVED_COLOR)( + 'received' + )} value must be an object when the matcher has ${(0, + _jestMatcherUtils.EXPECTED_COLOR)('properties')}`, + (0, _jestMatcherUtils.printWithType)( + 'Received', + received, + _printSnapshot.printReceived + ) + ) + ); + } + + const propertyPass = context.equals(received, properties, [ + context.utils.iterableEquality, + context.utils.subsetEquality + ]); + + if (!propertyPass) { + const key = snapshotState.fail(fullTestName, received); + const matched = /(\d+)$/.exec(key); + const count = matched === null ? 1 : Number(matched[1]); + + const message = () => + (0, _printSnapshot.matcherHintFromConfig)(config, false) + + '\n\n' + + printSnapshotName(currentTestName, hint, count) + + '\n\n' + + (0, _printSnapshot.printPropertiesAndReceived)( + properties, + received, + snapshotState.expand + ); + + return { + message, + name: matcherName, + pass: false + }; + } else { + received = utils.deepMerge(received, properties); + } + } + + const result = snapshotState.match({ + error: context.error, + inlineSnapshot, + isInline, + received, + testName: fullTestName + }); + const {actual, count, expected, pass} = result; + + if (pass) { + return { + message: () => '', + pass: true + }; + } + + const message = + expected === undefined + ? () => + (0, _printSnapshot.matcherHintFromConfig)(config, true) + + '\n\n' + + printSnapshotName(currentTestName, hint, count) + + '\n\n' + + `New snapshot was ${(0, _jestMatcherUtils.BOLD_WEIGHT)( + 'not written' + )}. The update flag ` + + 'must be explicitly passed to write a new snapshot.\n\n' + + 'This is likely because this test is run in a continuous integration ' + + '(CI) environment in which snapshots are not written by default.\n\n' + + `Received:${actual.includes('\n') ? '\n' : ' '}${(0, + _printSnapshot.bReceivedColor)(actual)}` + : () => + (0, _printSnapshot.matcherHintFromConfig)(config, true) + + '\n\n' + + printSnapshotName(currentTestName, hint, count) + + '\n\n' + + (0, _printSnapshot.printSnapshotAndReceived)( + expected, + actual, + received, + snapshotState.expand + ); // Passing the actual and expected objects so that a custom reporter + // could access them, for example in order to display a custom visual diff, + // or create a different error message + + return { + actual, + expected, + message, + name: matcherName, + pass: false + }; +}; + +const toThrowErrorMatchingSnapshot = function ( + received, + hint, // because error TS1016 for hint?: string + fromPromise +) { + const matcherName = 'toThrowErrorMatchingSnapshot'; // Future breaking change: Snapshot hint must be a string + // if (hint !== undefined && typeof hint !== string) {} + + return _toThrowErrorMatchingSnapshot( + { + context: this, + hint, + isInline: false, + matcherName, + received + }, + fromPromise + ); +}; + +const toThrowErrorMatchingInlineSnapshot = function ( + received, + inlineSnapshot, + fromPromise +) { + const matcherName = 'toThrowErrorMatchingInlineSnapshot'; + + if (inlineSnapshot !== undefined && typeof inlineSnapshot !== 'string') { + const options = { + expectedColor: _printSnapshot.noColor, + isNot: this.isNot, + promise: this.promise + }; + throw new Error( + (0, _jestMatcherUtils.matcherErrorMessage)( + (0, _jestMatcherUtils.matcherHint)( + matcherName, + undefined, + _printSnapshot.SNAPSHOT_ARG, + options + ), + 'Inline snapshot must be a string', + (0, _jestMatcherUtils.printWithType)( + 'Inline snapshot', + inlineSnapshot, + utils.serialize + ) + ) + ); + } + + return _toThrowErrorMatchingSnapshot( + { + context: this, + inlineSnapshot: + inlineSnapshot !== undefined + ? stripAddedIndentation(inlineSnapshot) + : undefined, + isInline: true, + matcherName, + received + }, + fromPromise + ); +}; + +const _toThrowErrorMatchingSnapshot = (config, fromPromise) => { + const {context, hint, inlineSnapshot, isInline, matcherName, received} = + config; + context.dontThrow && context.dontThrow(); + const {isNot, promise} = context; + + if (!fromPromise) { + if (typeof received !== 'function') { + const options = { + isNot, + promise + }; + throw new Error( + (0, _jestMatcherUtils.matcherErrorMessage)( + (0, _jestMatcherUtils.matcherHint)( + matcherName, + undefined, + '', + options + ), + `${(0, _jestMatcherUtils.RECEIVED_COLOR)( + 'received' + )} value must be a function`, + (0, _jestMatcherUtils.printWithType)( + 'Received', + received, + _printSnapshot.printReceived + ) + ) + ); + } + } + + if (isNot) { + throw new Error( + (0, _jestMatcherUtils.matcherErrorMessage)( + (0, _printSnapshot.matcherHintFromConfig)(config, false), + NOT_SNAPSHOT_MATCHERS + ) + ); + } + + let error; + + if (fromPromise) { + error = received; + } else { + try { + received(); + } catch (e) { + error = e; + } + } + + if (error === undefined) { + // Because the received value is a function, this is not a matcher error. + throw new Error( + (0, _printSnapshot.matcherHintFromConfig)(config, false) + + '\n\n' + + DID_NOT_THROW + ); + } + + return _toMatchSnapshot({ + context, + hint, + inlineSnapshot, + isInline, + matcherName, + received: error.message + }); +}; + +const JestSnapshot = { + EXTENSION: _SnapshotResolver.EXTENSION, + SnapshotState: _State.default, + addSerializer: _plugins.addSerializer, + buildSnapshotResolver: _SnapshotResolver.buildSnapshotResolver, + cleanup, + getSerializers: _plugins.getSerializers, + isSnapshotPath: _SnapshotResolver.isSnapshotPath, + toMatchInlineSnapshot, + toMatchSnapshot, + toThrowErrorMatchingInlineSnapshot, + toThrowErrorMatchingSnapshot, + utils +}; +module.exports = JestSnapshot; |