diff options
Diffstat (limited to 'node_modules/jest-snapshot/build')
22 files changed, 3119 insertions, 0 deletions
diff --git a/node_modules/jest-snapshot/build/InlineSnapshots.d.ts b/node_modules/jest-snapshot/build/InlineSnapshots.d.ts new file mode 100644 index 0000000..a93ff53 --- /dev/null +++ b/node_modules/jest-snapshot/build/InlineSnapshots.d.ts @@ -0,0 +1,15 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. 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. + */ +import type { Expression } from '@babel/types'; +import type { Config } from '@jest/types'; +import type { Frame } from 'jest-message-util'; +export declare type InlineSnapshot = { + snapshot: string; + frame: Frame; + node?: Expression; +}; +export declare function saveInlineSnapshots(snapshots: Array<InlineSnapshot>, prettierPath: Config.Path): void; diff --git a/node_modules/jest-snapshot/build/InlineSnapshots.js b/node_modules/jest-snapshot/build/InlineSnapshots.js new file mode 100644 index 0000000..8e20fe9 --- /dev/null +++ b/node_modules/jest-snapshot/build/InlineSnapshots.js @@ -0,0 +1,503 @@ +'use strict'; + +Object.defineProperty(exports, '__esModule', { + value: true +}); +exports.saveInlineSnapshots = saveInlineSnapshots; + +var path = _interopRequireWildcard(require('path')); + +var fs = _interopRequireWildcard(require('graceful-fs')); + +var _semver = _interopRequireDefault(require('semver')); + +var _utils = 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 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; + +// prettier-ignore +const babelTraverse = // @ts-expect-error requireOutside Babel transform +require(require.resolve('@babel/traverse', { + [(global['jest-symbol-do-not-touch'] || global.Symbol).for('jest-resolve-outside-vm-option')]: true +})).default; // prettier-ignore + +const generate = require(require.resolve('@babel/generator', { // @ts-expect-error requireOutside Babel transform + [(global['jest-symbol-do-not-touch'] || global.Symbol).for( + 'jest-resolve-outside-vm-option' + )]: true +})).default; // @ts-expect-error requireOutside Babel transform + +const {file, templateElement, templateLiteral} = require(require.resolve( + '@babel/types', + { + [(global['jest-symbol-do-not-touch'] || global.Symbol).for( + 'jest-resolve-outside-vm-option' + )]: true + } +)); // @ts-expect-error requireOutside Babel transform + +const {parseSync} = require(require.resolve('@babel/core', { + [(global['jest-symbol-do-not-touch'] || global.Symbol).for( + 'jest-resolve-outside-vm-option' + )]: true +})); + +function saveInlineSnapshots(snapshots, prettierPath) { + let prettier = null; + + if (prettierPath) { + try { + // @ts-expect-error requireOutside Babel transform + prettier = require(require.resolve(prettierPath, { + [(global['jest-symbol-do-not-touch'] || global.Symbol).for( + 'jest-resolve-outside-vm-option' + )]: true + })); + } catch { + // Continue even if prettier is not installed. + } + } + + const snapshotsByFile = groupSnapshotsByFile(snapshots); + + for (const sourceFilePath of Object.keys(snapshotsByFile)) { + saveSnapshotsForFile( + snapshotsByFile[sourceFilePath], + sourceFilePath, + prettier && _semver.default.gte(prettier.version, '1.5.0') + ? prettier + : undefined + ); + } +} + +const saveSnapshotsForFile = (snapshots, sourceFilePath, prettier) => { + const sourceFile = jestReadFile(sourceFilePath, 'utf8'); // TypeScript projects may not have a babel config; make sure they can be parsed anyway. + + const presets = [require.resolve('babel-preset-current-node-syntax')]; + const plugins = []; + + if (/\.tsx?$/.test(sourceFilePath)) { + plugins.push([ + require.resolve('@babel/plugin-syntax-typescript'), + { + isTSX: sourceFilePath.endsWith('x') + }, // unique name to make sure Babel does not complain about a possible duplicate plugin. + 'TypeScript syntax plugin added by Jest snapshot' + ]); + } // Record the matcher names seen during traversal and pass them down one + // by one to formatting parser. + + const snapshotMatcherNames = []; + const ast = parseSync(sourceFile, { + filename: sourceFilePath, + plugins, + presets, + root: path.dirname(sourceFilePath) + }); + + if (!ast) { + throw new Error(`jest-snapshot: Failed to parse ${sourceFilePath}`); + } + + traverseAst(snapshots, ast, snapshotMatcherNames); // substitute in the snapshots in reverse order, so slice calculations aren't thrown off. + + const sourceFileWithSnapshots = snapshots.reduceRight( + (sourceSoFar, nextSnapshot) => { + if ( + !nextSnapshot.node || + typeof nextSnapshot.node.start !== 'number' || + typeof nextSnapshot.node.end !== 'number' + ) { + throw new Error('Jest: no snapshot insert location found'); + } + + return ( + sourceSoFar.slice(0, nextSnapshot.node.start) + + generate(nextSnapshot.node, { + retainLines: true + }).code.trim() + + sourceSoFar.slice(nextSnapshot.node.end) + ); + }, + sourceFile + ); + const newSourceFile = prettier + ? runPrettier( + prettier, + sourceFilePath, + sourceFileWithSnapshots, + snapshotMatcherNames + ) + : sourceFileWithSnapshots; + + if (newSourceFile !== sourceFile) { + jestWriteFile(sourceFilePath, newSourceFile); + } +}; + +const groupSnapshotsBy = createKey => snapshots => + snapshots.reduce((object, inlineSnapshot) => { + const key = createKey(inlineSnapshot); + return {...object, [key]: (object[key] || []).concat(inlineSnapshot)}; + }, {}); + +const groupSnapshotsByFrame = groupSnapshotsBy(({frame: {line, column}}) => + typeof line === 'number' && typeof column === 'number' + ? `${line}:${column - 1}` + : '' +); +const groupSnapshotsByFile = groupSnapshotsBy(({frame: {file}}) => file); + +const indent = (snapshot, numIndents, indentation) => { + const lines = snapshot.split('\n'); // Prevent re-indentation of inline snapshots. + + if ( + lines.length >= 2 && + lines[1].startsWith(indentation.repeat(numIndents + 1)) + ) { + return snapshot; + } + + return lines + .map((line, index) => { + if (index === 0) { + // First line is either a 1-line snapshot or a blank line. + return line; + } else if (index !== lines.length - 1) { + // Do not indent empty lines. + if (line === '') { + return line; + } // Not last line, indent one level deeper than expect call. + + return indentation.repeat(numIndents + 1) + line; + } else { + // The last line should be placed on the same level as the expect call. + return indentation.repeat(numIndents) + line; + } + }) + .join('\n'); +}; + +const resolveAst = fileOrProgram => { + // Flow uses a 'Program' parent node, babel expects a 'File'. + let ast = fileOrProgram; + + if (ast.type !== 'File') { + ast = file(ast, ast.comments, ast.tokens); + delete ast.program.comments; + } + + return ast; +}; + +const traverseAst = (snapshots, fileOrProgram, snapshotMatcherNames) => { + const ast = resolveAst(fileOrProgram); + const groupedSnapshots = groupSnapshotsByFrame(snapshots); + const remainingSnapshots = new Set(snapshots.map(({snapshot}) => snapshot)); + babelTraverse(ast, { + CallExpression({node}) { + const {arguments: args, callee} = node; + + if ( + callee.type !== 'MemberExpression' || + callee.property.type !== 'Identifier' || + callee.property.loc == null + ) { + return; + } + + const {line, column} = callee.property.loc.start; + const snapshotsForFrame = groupedSnapshots[`${line}:${column}`]; + + if (!snapshotsForFrame) { + return; + } + + if (snapshotsForFrame.length > 1) { + throw new Error( + 'Jest: Multiple inline snapshots for the same call are not supported.' + ); + } + + snapshotMatcherNames.push(callee.property.name); + const snapshotIndex = args.findIndex( + ({type}) => type === 'TemplateLiteral' + ); + const values = snapshotsForFrame.map(inlineSnapshot => { + inlineSnapshot.node = node; + const {snapshot} = inlineSnapshot; + remainingSnapshots.delete(snapshot); + return templateLiteral( + [ + templateElement({ + raw: (0, _utils.escapeBacktickString)(snapshot) + }) + ], + [] + ); + }); + const replacementNode = values[0]; + + if (snapshotIndex > -1) { + args[snapshotIndex] = replacementNode; + } else { + args.push(replacementNode); + } + } + }); + + if (remainingSnapshots.size) { + throw new Error("Jest: Couldn't locate all inline snapshots."); + } +}; + +const runPrettier = ( + prettier, + sourceFilePath, + sourceFileWithSnapshots, + snapshotMatcherNames +) => { + // Resolve project configuration. + // For older versions of Prettier, do not load configuration. + const config = prettier.resolveConfig + ? prettier.resolveConfig.sync(sourceFilePath, { + editorconfig: true + }) + : null; // Detect the parser for the test file. + // For older versions of Prettier, fallback to a simple parser detection. + // @ts-expect-error + + const inferredParser = prettier.getFileInfo + ? prettier.getFileInfo.sync(sourceFilePath).inferredParser + : (config && typeof config.parser === 'string' && config.parser) || + simpleDetectParser(sourceFilePath); + + if (!inferredParser) { + throw new Error( + `Could not infer Prettier parser for file ${sourceFilePath}` + ); + } // Snapshots have now been inserted. Run prettier to make sure that the code is + // formatted, except snapshot indentation. Snapshots cannot be formatted until + // after the initial format because we don't know where the call expression + // will be placed (specifically its indentation), so we have to do two + // prettier.format calls back-to-back. + + return prettier.format( + prettier.format(sourceFileWithSnapshots, { + ...config, + filepath: sourceFilePath + }), + { + ...config, + filepath: sourceFilePath, + parser: createFormattingParser(snapshotMatcherNames, inferredParser) + } + ); +}; // This parser formats snapshots to the correct indentation. + +const createFormattingParser = + (snapshotMatcherNames, inferredParser) => (text, parsers, options) => { + // Workaround for https://github.com/prettier/prettier/issues/3150 + options.parser = inferredParser; + const ast = resolveAst(parsers[inferredParser](text, options)); + babelTraverse(ast, { + CallExpression({node: {arguments: args, callee}}) { + var _options$tabWidth, _options$tabWidth2; + + if ( + callee.type !== 'MemberExpression' || + callee.property.type !== 'Identifier' || + !snapshotMatcherNames.includes(callee.property.name) || + !callee.loc || + callee.computed + ) { + return; + } + + let snapshotIndex; + let snapshot; + + for (let i = 0; i < args.length; i++) { + const node = args[i]; + + if (node.type === 'TemplateLiteral') { + snapshotIndex = i; + snapshot = node.quasis[0].value.raw; + } + } + + if (snapshot === undefined || snapshotIndex === undefined) { + return; + } + + const useSpaces = !options.useTabs; + snapshot = indent( + snapshot, + Math.ceil( + useSpaces + ? callee.loc.start.column / + ((_options$tabWidth = options.tabWidth) !== null && + _options$tabWidth !== void 0 + ? _options$tabWidth + : 1) + : callee.loc.start.column / 2 // Each tab is 2 characters. + ), + useSpaces + ? ' '.repeat( + (_options$tabWidth2 = options.tabWidth) !== null && + _options$tabWidth2 !== void 0 + ? _options$tabWidth2 + : 1 + ) + : '\t' + ); + const replacementNode = templateLiteral( + [ + templateElement({ + raw: snapshot + }) + ], + [] + ); + args[snapshotIndex] = replacementNode; + } + }); + return ast; + }; + +const simpleDetectParser = filePath => { + const extname = path.extname(filePath); + + if (/\.tsx?$/.test(extname)) { + return 'typescript'; + } + + return 'babel'; +}; diff --git a/node_modules/jest-snapshot/build/SnapshotResolver.d.ts b/node_modules/jest-snapshot/build/SnapshotResolver.d.ts new file mode 100644 index 0000000..2214a1f --- /dev/null +++ b/node_modules/jest-snapshot/build/SnapshotResolver.d.ts @@ -0,0 +1,18 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. 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. + */ +import type { Config } from '@jest/types'; +export declare type SnapshotResolver = { + testPathForConsistencyCheck: string; + resolveSnapshotPath(testPath: Config.Path, extension?: string): Config.Path; + resolveTestPath(snapshotPath: Config.Path, extension?: string): Config.Path; +}; +export declare const EXTENSION = "snap"; +export declare const DOT_EXTENSION: string; +export declare const isSnapshotPath: (path: string) => boolean; +declare type LocalRequire = (module: string) => unknown; +export declare const buildSnapshotResolver: (config: Config.ProjectConfig, localRequire?: Promise<LocalRequire> | LocalRequire) => Promise<SnapshotResolver>; +export {}; diff --git a/node_modules/jest-snapshot/build/SnapshotResolver.js b/node_modules/jest-snapshot/build/SnapshotResolver.js new file mode 100644 index 0000000..b4692fe --- /dev/null +++ b/node_modules/jest-snapshot/build/SnapshotResolver.js @@ -0,0 +1,179 @@ +'use strict'; + +Object.defineProperty(exports, '__esModule', { + value: true +}); +exports.isSnapshotPath = + exports.buildSnapshotResolver = + exports.EXTENSION = + exports.DOT_EXTENSION = + void 0; + +var path = _interopRequireWildcard(require('path')); + +var _chalk = _interopRequireDefault(require('chalk')); + +var _transform = require('@jest/transform'); + +var _jestUtil = require('jest-util'); + +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; +} + +/** + * Copyright (c) Facebook, Inc. and its affiliates. 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 EXTENSION = 'snap'; +exports.EXTENSION = EXTENSION; +const DOT_EXTENSION = '.' + EXTENSION; +exports.DOT_EXTENSION = DOT_EXTENSION; + +const isSnapshotPath = path => path.endsWith(DOT_EXTENSION); + +exports.isSnapshotPath = isSnapshotPath; +const cache = new Map(); + +const buildSnapshotResolver = async ( + config, + localRequire = (0, _transform.createTranspilingRequire)(config) +) => { + var _cache$get; + + const key = config.rootDir; + const resolver = + (_cache$get = cache.get(key)) !== null && _cache$get !== void 0 + ? _cache$get + : await createSnapshotResolver( + await localRequire, + config.snapshotResolver + ); + cache.set(key, resolver); + return resolver; +}; + +exports.buildSnapshotResolver = buildSnapshotResolver; + +async function createSnapshotResolver(localRequire, snapshotResolverPath) { + return typeof snapshotResolverPath === 'string' + ? await createCustomSnapshotResolver(snapshotResolverPath, localRequire) + : createDefaultSnapshotResolver(); +} + +function createDefaultSnapshotResolver() { + return { + resolveSnapshotPath: testPath => + path.join( + path.join(path.dirname(testPath), '__snapshots__'), + path.basename(testPath) + DOT_EXTENSION + ), + resolveTestPath: snapshotPath => + path.resolve( + path.dirname(snapshotPath), + '..', + path.basename(snapshotPath, DOT_EXTENSION) + ), + testPathForConsistencyCheck: path.posix.join( + 'consistency_check', + '__tests__', + 'example.test.js' + ) + }; +} + +async function createCustomSnapshotResolver( + snapshotResolverPath, + localRequire +) { + const custom = (0, _jestUtil.interopRequireDefault)( + await localRequire(snapshotResolverPath) + ).default; + const keys = [ + ['resolveSnapshotPath', 'function'], + ['resolveTestPath', 'function'], + ['testPathForConsistencyCheck', 'string'] + ]; + keys.forEach(([propName, requiredType]) => { + if (typeof custom[propName] !== requiredType) { + throw new TypeError(mustImplement(propName, requiredType)); + } + }); + const customResolver = { + resolveSnapshotPath: testPath => + custom.resolveSnapshotPath(testPath, DOT_EXTENSION), + resolveTestPath: snapshotPath => + custom.resolveTestPath(snapshotPath, DOT_EXTENSION), + testPathForConsistencyCheck: custom.testPathForConsistencyCheck + }; + verifyConsistentTransformations(customResolver); + return customResolver; +} + +function mustImplement(propName, requiredType) { + return ( + _chalk.default.bold( + `Custom snapshot resolver must implement a \`${propName}\` as a ${requiredType}.` + ) + + '\nDocumentation: https://jestjs.io/docs/configuration#snapshotresolver-string' + ); +} + +function verifyConsistentTransformations(custom) { + const resolvedSnapshotPath = custom.resolveSnapshotPath( + custom.testPathForConsistencyCheck + ); + const resolvedTestPath = custom.resolveTestPath(resolvedSnapshotPath); + + if (resolvedTestPath !== custom.testPathForConsistencyCheck) { + throw new Error( + _chalk.default.bold( + `Custom snapshot resolver functions must transform paths consistently, i.e. expects resolveTestPath(resolveSnapshotPath('${custom.testPathForConsistencyCheck}')) === ${resolvedTestPath}` + ) + ); + } +} diff --git a/node_modules/jest-snapshot/build/State.d.ts b/node_modules/jest-snapshot/build/State.d.ts new file mode 100644 index 0000000..86d7ae5 --- /dev/null +++ b/node_modules/jest-snapshot/build/State.d.ts @@ -0,0 +1,62 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. 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. + */ +import type { Config } from '@jest/types'; +import type { OptionsReceived as PrettyFormatOptions } from 'pretty-format'; +export declare type SnapshotStateOptions = { + updateSnapshot: Config.SnapshotUpdateState; + prettierPath: Config.Path; + expand?: boolean; + snapshotFormat: PrettyFormatOptions; +}; +export declare type SnapshotMatchOptions = { + testName: string; + received: unknown; + key?: string; + inlineSnapshot?: string; + isInline: boolean; + error?: Error; +}; +declare type SnapshotReturnOptions = { + actual: string; + count: number; + expected?: string; + key: string; + pass: boolean; +}; +declare type SaveStatus = { + deleted: boolean; + saved: boolean; +}; +export default class SnapshotState { + private _counters; + private _dirty; + private _index; + private _updateSnapshot; + private _snapshotData; + private _initialData; + private _snapshotPath; + private _inlineSnapshots; + private _uncheckedKeys; + private _prettierPath; + private _snapshotFormat; + added: number; + expand: boolean; + matched: number; + unmatched: number; + updated: number; + constructor(snapshotPath: Config.Path, options: SnapshotStateOptions); + markSnapshotsAsCheckedForTest(testName: string): void; + private _addSnapshot; + clear(): void; + save(): SaveStatus; + getUncheckedCount(): number; + getUncheckedKeys(): Array<string>; + removeUncheckedKeys(): void; + match({ testName, received, key, inlineSnapshot, isInline, error, }: SnapshotMatchOptions): SnapshotReturnOptions; + fail(testName: string, _received: unknown, key?: string): string; +} +export {}; diff --git a/node_modules/jest-snapshot/build/State.js b/node_modules/jest-snapshot/build/State.js new file mode 100644 index 0000000..6148b78 --- /dev/null +++ b/node_modules/jest-snapshot/build/State.js @@ -0,0 +1,389 @@ +'use strict'; + +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; +Object.defineProperty(exports, '__esModule', { + value: true +}); +exports.default = void 0; + +var fs = _interopRequireWildcard(require('graceful-fs')); + +var _jestMessageUtil = require('jest-message-util'); + +var _InlineSnapshots = require('./InlineSnapshots'); + +var _utils = require('./utils'); + +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 jestExistsFile = + global[Symbol.for('jest-native-exists-file')] || fs.existsSync; + +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; +} + +class SnapshotState { + // @ts-expect-error + constructor(snapshotPath, options) { + _defineProperty(this, '_counters', void 0); + + _defineProperty(this, '_dirty', void 0); + + _defineProperty(this, '_index', void 0); + + _defineProperty(this, '_updateSnapshot', void 0); + + _defineProperty(this, '_snapshotData', void 0); + + _defineProperty(this, '_initialData', void 0); + + _defineProperty(this, '_snapshotPath', void 0); + + _defineProperty(this, '_inlineSnapshots', void 0); + + _defineProperty(this, '_uncheckedKeys', void 0); + + _defineProperty(this, '_prettierPath', void 0); + + _defineProperty(this, '_snapshotFormat', void 0); + + _defineProperty(this, 'added', void 0); + + _defineProperty(this, 'expand', void 0); + + _defineProperty(this, 'matched', void 0); + + _defineProperty(this, 'unmatched', void 0); + + _defineProperty(this, 'updated', void 0); + + this._snapshotPath = snapshotPath; + const {data, dirty} = (0, _utils.getSnapshotData)( + this._snapshotPath, + options.updateSnapshot + ); + this._initialData = data; + this._snapshotData = data; + this._dirty = dirty; + this._prettierPath = options.prettierPath; + this._inlineSnapshots = []; + this._uncheckedKeys = new Set(Object.keys(this._snapshotData)); + this._counters = new Map(); + this._index = 0; + this.expand = options.expand || false; + this.added = 0; + this.matched = 0; + this.unmatched = 0; + this._updateSnapshot = options.updateSnapshot; + this.updated = 0; + this._snapshotFormat = options.snapshotFormat; + } + + markSnapshotsAsCheckedForTest(testName) { + this._uncheckedKeys.forEach(uncheckedKey => { + if ((0, _utils.keyToTestName)(uncheckedKey) === testName) { + this._uncheckedKeys.delete(uncheckedKey); + } + }); + } + + _addSnapshot(key, receivedSerialized, options) { + this._dirty = true; + + if (options.isInline) { + const error = options.error || new Error(); + const lines = (0, _jestMessageUtil.getStackTraceLines)( + (0, _utils.removeLinesBeforeExternalMatcherTrap)(error.stack || '') + ); + const frame = (0, _jestMessageUtil.getTopFrame)(lines); + + if (!frame) { + throw new Error( + "Jest: Couldn't infer stack frame for inline snapshot." + ); + } + + this._inlineSnapshots.push({ + frame, + snapshot: receivedSerialized + }); + } else { + this._snapshotData[key] = receivedSerialized; + } + } + + clear() { + this._snapshotData = this._initialData; + this._inlineSnapshots = []; + this._counters = new Map(); + this._index = 0; + this.added = 0; + this.matched = 0; + this.unmatched = 0; + this.updated = 0; + } + + save() { + const hasExternalSnapshots = Object.keys(this._snapshotData).length; + const hasInlineSnapshots = this._inlineSnapshots.length; + const isEmpty = !hasExternalSnapshots && !hasInlineSnapshots; + const status = { + deleted: false, + saved: false + }; + + if ((this._dirty || this._uncheckedKeys.size) && !isEmpty) { + if (hasExternalSnapshots) { + (0, _utils.saveSnapshotFile)(this._snapshotData, this._snapshotPath); + } + + if (hasInlineSnapshots) { + (0, _InlineSnapshots.saveInlineSnapshots)( + this._inlineSnapshots, + this._prettierPath + ); + } + + status.saved = true; + } else if (!hasExternalSnapshots && jestExistsFile(this._snapshotPath)) { + if (this._updateSnapshot === 'all') { + fs.unlinkSync(this._snapshotPath); + } + + status.deleted = true; + } + + return status; + } + + getUncheckedCount() { + return this._uncheckedKeys.size || 0; + } + + getUncheckedKeys() { + return Array.from(this._uncheckedKeys); + } + + removeUncheckedKeys() { + if (this._updateSnapshot === 'all' && this._uncheckedKeys.size) { + this._dirty = true; + + this._uncheckedKeys.forEach(key => delete this._snapshotData[key]); + + this._uncheckedKeys.clear(); + } + } + + match({testName, received, key, inlineSnapshot, isInline, error}) { + this._counters.set(testName, (this._counters.get(testName) || 0) + 1); + + const count = Number(this._counters.get(testName)); + + if (!key) { + key = (0, _utils.testNameToKey)(testName, count); + } // Do not mark the snapshot as "checked" if the snapshot is inline and + // there's an external snapshot. This way the external snapshot can be + // removed with `--updateSnapshot`. + + if (!(isInline && this._snapshotData[key] !== undefined)) { + this._uncheckedKeys.delete(key); + } + + const receivedSerialized = (0, _utils.addExtraLineBreaks)( + (0, _utils.serialize)(received, undefined, this._snapshotFormat) + ); + const expected = isInline ? inlineSnapshot : this._snapshotData[key]; + const pass = expected === receivedSerialized; + const hasSnapshot = expected !== undefined; + const snapshotIsPersisted = isInline || fs.existsSync(this._snapshotPath); + + if (pass && !isInline) { + // Executing a snapshot file as JavaScript and writing the strings back + // when other snapshots have changed loses the proper escaping for some + // characters. Since we check every snapshot in every test, use the newly + // generated formatted string. + // Note that this is only relevant when a snapshot is added and the dirty + // flag is set. + this._snapshotData[key] = receivedSerialized; + } // These are the conditions on when to write snapshots: + // * There's no snapshot file in a non-CI environment. + // * There is a snapshot file and we decided to update the snapshot. + // * There is a snapshot file, but it doesn't have this snaphsot. + // These are the conditions on when not to write snapshots: + // * The update flag is set to 'none'. + // * There's no snapshot file or a file without this snapshot on a CI environment. + + if ( + (hasSnapshot && this._updateSnapshot === 'all') || + ((!hasSnapshot || !snapshotIsPersisted) && + (this._updateSnapshot === 'new' || this._updateSnapshot === 'all')) + ) { + if (this._updateSnapshot === 'all') { + if (!pass) { + if (hasSnapshot) { + this.updated++; + } else { + this.added++; + } + + this._addSnapshot(key, receivedSerialized, { + error, + isInline + }); + } else { + this.matched++; + } + } else { + this._addSnapshot(key, receivedSerialized, { + error, + isInline + }); + + this.added++; + } + + return { + actual: '', + count, + expected: '', + key, + pass: true + }; + } else { + if (!pass) { + this.unmatched++; + return { + actual: (0, _utils.removeExtraLineBreaks)(receivedSerialized), + count, + expected: + expected !== undefined + ? (0, _utils.removeExtraLineBreaks)(expected) + : undefined, + key, + pass: false + }; + } else { + this.matched++; + return { + actual: '', + count, + expected: '', + key, + pass: true + }; + } + } + } + + fail(testName, _received, key) { + this._counters.set(testName, (this._counters.get(testName) || 0) + 1); + + const count = Number(this._counters.get(testName)); + + if (!key) { + key = (0, _utils.testNameToKey)(testName, count); + } + + this._uncheckedKeys.delete(key); + + this.unmatched++; + return key; + } +} + +exports.default = SnapshotState; diff --git a/node_modules/jest-snapshot/build/colors.d.ts b/node_modules/jest-snapshot/build/colors.d.ts new file mode 100644 index 0000000..23e2905 --- /dev/null +++ b/node_modules/jest-snapshot/build/colors.d.ts @@ -0,0 +1,15 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. 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. + */ +export declare const aForeground2 = 90; +export declare const aBackground2 = 225; +export declare const bForeground2 = 23; +export declare const bBackground2 = 195; +export declare type RGB = [number, number, number]; +export declare const aForeground3: RGB; +export declare const aBackground3: RGB; +export declare const bForeground3: RGB; +export declare const bBackground3: RGB; diff --git a/node_modules/jest-snapshot/build/colors.js b/node_modules/jest-snapshot/build/colors.js new file mode 100644 index 0000000..897ea87 --- /dev/null +++ b/node_modules/jest-snapshot/build/colors.js @@ -0,0 +1,38 @@ +'use strict'; + +Object.defineProperty(exports, '__esModule', { + value: true +}); +exports.bForeground3 = + exports.bForeground2 = + exports.bBackground3 = + exports.bBackground2 = + exports.aForeground3 = + exports.aForeground2 = + exports.aBackground3 = + exports.aBackground2 = + void 0; + +/** + * Copyright (c) Facebook, Inc. and its affiliates. 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. + */ +// https://jonasjacek.github.io/colors/ +const aForeground2 = 90; +exports.aForeground2 = aForeground2; +const aBackground2 = 225; +exports.aBackground2 = aBackground2; +const bForeground2 = 23; +exports.bForeground2 = bForeground2; +const bBackground2 = 195; +exports.bBackground2 = bBackground2; +const aForeground3 = [0x80, 0, 0x80]; +exports.aForeground3 = aForeground3; +const aBackground3 = [0xff, 0xd7, 0xff]; +exports.aBackground3 = aBackground3; +const bForeground3 = [0, 0x5f, 0x5f]; +exports.bForeground3 = bForeground3; +const bBackground3 = [0xd7, 0xff, 0xff]; +exports.bBackground3 = bBackground3; diff --git a/node_modules/jest-snapshot/build/dedentLines.d.ts b/node_modules/jest-snapshot/build/dedentLines.d.ts new file mode 100644 index 0000000..1ebd410 --- /dev/null +++ b/node_modules/jest-snapshot/build/dedentLines.d.ts @@ -0,0 +1,7 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. 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. + */ +export declare const dedentLines: (input: Array<string>) => Array<string> | null; diff --git a/node_modules/jest-snapshot/build/dedentLines.js b/node_modules/jest-snapshot/build/dedentLines.js new file mode 100644 index 0000000..b860c4d --- /dev/null +++ b/node_modules/jest-snapshot/build/dedentLines.js @@ -0,0 +1,149 @@ +'use strict'; + +Object.defineProperty(exports, '__esModule', { + value: true +}); +exports.dedentLines = void 0; + +/** + * Copyright (c) Facebook, Inc. and its affiliates. 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 getIndentationLength = line => { + const result = /^( {2})+/.exec(line); + return result === null ? 0 : result[0].length; +}; + +const dedentLine = line => line.slice(getIndentationLength(line)); // Return true if: +// "key": "value has multiple lines\n… +// "key has multiple lines\n… + +const hasUnmatchedDoubleQuoteMarks = string => { + let n = 0; + let i = string.indexOf('"', 0); + + while (i !== -1) { + if (i === 0 || string[i - 1] !== '\\') { + n += 1; + } + + i = string.indexOf('"', i + 1); + } + + return n % 2 !== 0; +}; + +const isFirstLineOfTag = line => /^( {2})*\</.test(line); // The length of the output array is the index of the next input line. +// Push dedented lines of start tag onto output and return true; +// otherwise return false because: +// * props include a multiline string (or text node, if props have markup) +// * start tag does not close + +const dedentStartTag = (input, output) => { + let line = input[output.length]; + output.push(dedentLine(line)); + + if (line.includes('>')) { + return true; + } + + while (output.length < input.length) { + line = input[output.length]; + + if (hasUnmatchedDoubleQuoteMarks(line)) { + return false; // because props include a multiline string + } else if (isFirstLineOfTag(line)) { + // Recursion only if props have markup. + if (!dedentMarkup(input, output)) { + return false; + } + } else { + output.push(dedentLine(line)); + + if (line.includes('>')) { + return true; + } + } + } + + return false; +}; // Push dedented lines of markup onto output and return true; +// otherwise return false because: +// * props include a multiline string +// * text has more than one adjacent line +// * markup does not close + +const dedentMarkup = (input, output) => { + let line = input[output.length]; + + if (!dedentStartTag(input, output)) { + return false; + } + + if (input[output.length - 1].includes('/>')) { + return true; + } + + let isText = false; + const stack = []; + stack.push(getIndentationLength(line)); + + while (stack.length > 0 && output.length < input.length) { + line = input[output.length]; + + if (isFirstLineOfTag(line)) { + if (line.includes('</')) { + output.push(dedentLine(line)); + stack.pop(); + } else { + if (!dedentStartTag(input, output)) { + return false; + } + + if (!input[output.length - 1].includes('/>')) { + stack.push(getIndentationLength(line)); + } + } + + isText = false; + } else { + if (isText) { + return false; // because text has more than one adjacent line + } + + const indentationLengthOfTag = stack[stack.length - 1]; + output.push(line.slice(indentationLengthOfTag + 2)); + isText = true; + } + } + + return stack.length === 0; +}; // Return lines unindented by heuristic; +// otherwise return null because: +// * props include a multiline string +// * text has more than one adjacent line +// * markup does not close + +const dedentLines = input => { + const output = []; + + while (output.length < input.length) { + const line = input[output.length]; + + if (hasUnmatchedDoubleQuoteMarks(line)) { + return null; + } else if (isFirstLineOfTag(line)) { + if (!dedentMarkup(input, output)) { + return null; + } + } else { + output.push(dedentLine(line)); + } + } + + return output; +}; + +exports.dedentLines = dedentLines; diff --git a/node_modules/jest-snapshot/build/index.d.ts b/node_modules/jest-snapshot/build/index.d.ts new file mode 100644 index 0000000..adbd406 --- /dev/null +++ b/node_modules/jest-snapshot/build/index.d.ts @@ -0,0 +1,34 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. 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. + */ +import type { Config } from '@jest/types'; +import type { FS as HasteFS } from 'jest-haste-map'; +import { SnapshotResolver as JestSnapshotResolver } from './SnapshotResolver'; +import SnapshotState from './State'; +import type { Context, ExpectationResult } from './types'; +import * as utils from './utils'; +declare const JestSnapshot: { + EXTENSION: string; + SnapshotState: typeof SnapshotState; + addSerializer: (plugin: import("pretty-format").Plugin) => void; + buildSnapshotResolver: (config: Config.ProjectConfig, localRequire?: ((module: string) => unknown) | Promise<(module: string) => unknown>) => Promise<JestSnapshotResolver>; + cleanup: (hasteFS: HasteFS, update: Config.SnapshotUpdateState, snapshotResolver: JestSnapshotResolver, testPathIgnorePatterns?: string[] | undefined) => { + filesRemoved: number; + filesRemovedList: Array<string>; + }; + getSerializers: () => import("pretty-format").Plugins; + isSnapshotPath: (path: string) => boolean; + toMatchInlineSnapshot: (this: Context, received: unknown, propertiesOrSnapshot?: string | object | undefined, inlineSnapshot?: string | undefined) => ExpectationResult; + toMatchSnapshot: (this: Context, received: unknown, propertiesOrHint?: string | object | undefined, hint?: string | undefined) => ExpectationResult; + toThrowErrorMatchingInlineSnapshot: (this: Context, received: unknown, inlineSnapshot?: string | undefined, fromPromise?: boolean | undefined) => ExpectationResult; + toThrowErrorMatchingSnapshot: (this: Context, received: unknown, hint: string | undefined, fromPromise: boolean) => ExpectationResult; + utils: typeof utils; +}; +declare namespace JestSnapshot { + type SnapshotResolver = JestSnapshotResolver; + type SnapshotStateType = SnapshotState; +} +export = JestSnapshot; 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; diff --git a/node_modules/jest-snapshot/build/mockSerializer.d.ts b/node_modules/jest-snapshot/build/mockSerializer.d.ts new file mode 100644 index 0000000..828986e --- /dev/null +++ b/node_modules/jest-snapshot/build/mockSerializer.d.ts @@ -0,0 +1,11 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. 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. + */ +import type { NewPlugin } from 'pretty-format'; +export declare const serialize: NewPlugin['serialize']; +export declare const test: NewPlugin['test']; +declare const plugin: NewPlugin; +export default plugin; diff --git a/node_modules/jest-snapshot/build/mockSerializer.js b/node_modules/jest-snapshot/build/mockSerializer.js new file mode 100644 index 0000000..bf1c78d --- /dev/null +++ b/node_modules/jest-snapshot/build/mockSerializer.js @@ -0,0 +1,52 @@ +'use strict'; + +Object.defineProperty(exports, '__esModule', { + value: true +}); +exports.test = exports.serialize = exports.default = void 0; + +/** + * Copyright (c) Facebook, Inc. and its affiliates. 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 serialize = (val, config, indentation, depth, refs, printer) => { + // Serialize a non-default name, even if config.printFunctionName is false. + const name = val.getMockName(); + const nameString = name === 'jest.fn()' ? '' : ' ' + name; + let callsString = ''; + + if (val.mock.calls.length !== 0) { + const indentationNext = indentation + config.indent; + callsString = + ' {' + + config.spacingOuter + + indentationNext + + '"calls": ' + + printer(val.mock.calls, config, indentationNext, depth, refs) + + (config.min ? ', ' : ',') + + config.spacingOuter + + indentationNext + + '"results": ' + + printer(val.mock.results, config, indentationNext, depth, refs) + + (config.min ? '' : ',') + + config.spacingOuter + + indentation + + '}'; + } + + return '[MockFunction' + nameString + ']' + callsString; +}; + +exports.serialize = serialize; + +const test = val => val && !!val._isMockFunction; + +exports.test = test; +const plugin = { + serialize, + test +}; +var _default = plugin; +exports.default = _default; diff --git a/node_modules/jest-snapshot/build/plugins.d.ts b/node_modules/jest-snapshot/build/plugins.d.ts new file mode 100644 index 0000000..89b6d48 --- /dev/null +++ b/node_modules/jest-snapshot/build/plugins.d.ts @@ -0,0 +1,9 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. 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. + */ +import { Plugin as PrettyFormatPlugin, Plugins as PrettyFormatPlugins } from 'pretty-format'; +export declare const addSerializer: (plugin: PrettyFormatPlugin) => void; +export declare const getSerializers: () => PrettyFormatPlugins; diff --git a/node_modules/jest-snapshot/build/plugins.js b/node_modules/jest-snapshot/build/plugins.js new file mode 100644 index 0000000..6a3625b --- /dev/null +++ b/node_modules/jest-snapshot/build/plugins.js @@ -0,0 +1,48 @@ +'use strict'; + +Object.defineProperty(exports, '__esModule', { + value: true +}); +exports.getSerializers = exports.addSerializer = void 0; + +var _prettyFormat = require('pretty-format'); + +var _mockSerializer = _interopRequireDefault(require('./mockSerializer')); + +function _interopRequireDefault(obj) { + return obj && obj.__esModule ? obj : {default: obj}; +} + +/** + * Copyright (c) Facebook, Inc. and its affiliates. 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 { + DOMCollection, + DOMElement, + Immutable, + ReactElement, + ReactTestComponent, + AsymmetricMatcher +} = _prettyFormat.plugins; +let PLUGINS = [ + ReactTestComponent, + ReactElement, + DOMElement, + DOMCollection, + Immutable, + _mockSerializer.default, + AsymmetricMatcher +]; // Prepend to list so the last added is the first tested. + +const addSerializer = plugin => { + PLUGINS = [plugin].concat(PLUGINS); +}; + +exports.addSerializer = addSerializer; + +const getSerializers = () => PLUGINS; + +exports.getSerializers = getSerializers; diff --git a/node_modules/jest-snapshot/build/printSnapshot.d.ts b/node_modules/jest-snapshot/build/printSnapshot.d.ts new file mode 100644 index 0000000..0325346 --- /dev/null +++ b/node_modules/jest-snapshot/build/printSnapshot.d.ts @@ -0,0 +1,24 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. 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. + */ +import chalk = require('chalk'); +import { DiffOptionsColor } from 'jest-diff'; +import type { MatchSnapshotConfig } from './types'; +declare type Chalk = chalk.Chalk; +export declare const getSnapshotColorForChalkInstance: (chalkInstance: Chalk) => DiffOptionsColor; +export declare const getReceivedColorForChalkInstance: (chalkInstance: Chalk) => DiffOptionsColor; +export declare const aSnapshotColor: DiffOptionsColor; +export declare const bReceivedColor: DiffOptionsColor; +export declare const noColor: (string: string) => string; +export declare const HINT_ARG = "hint"; +export declare const SNAPSHOT_ARG = "snapshot"; +export declare const PROPERTIES_ARG = "properties"; +export declare const matcherHintFromConfig: ({ context: { isNot, promise }, hint, inlineSnapshot, matcherName, properties, }: MatchSnapshotConfig, isUpdatable: boolean) => string; +export declare const printExpected: (val: unknown) => string; +export declare const printReceived: (val: unknown) => string; +export declare const printPropertiesAndReceived: (properties: object, received: object, expand: boolean) => string; +export declare const printSnapshotAndReceived: (a: string, b: string, received: unknown, expand: boolean) => string; +export {}; diff --git a/node_modules/jest-snapshot/build/printSnapshot.js b/node_modules/jest-snapshot/build/printSnapshot.js new file mode 100644 index 0000000..c5f186c --- /dev/null +++ b/node_modules/jest-snapshot/build/printSnapshot.js @@ -0,0 +1,407 @@ +'use strict'; + +Object.defineProperty(exports, '__esModule', { + value: true +}); +exports.printSnapshotAndReceived = + exports.printReceived = + exports.printPropertiesAndReceived = + exports.printExpected = + exports.noColor = + exports.matcherHintFromConfig = + exports.getSnapshotColorForChalkInstance = + exports.getReceivedColorForChalkInstance = + exports.bReceivedColor = + exports.aSnapshotColor = + exports.SNAPSHOT_ARG = + exports.PROPERTIES_ARG = + exports.HINT_ARG = + void 0; + +var _chalk = _interopRequireDefault(require('chalk')); + +var _utils = require('expect/build/utils'); + +var _jestDiff = require('jest-diff'); + +var _jestGetType = require('jest-get-type'); + +var _jestMatcherUtils = require('jest-matcher-utils'); + +var _prettyFormat = require('pretty-format'); + +var _colors = require('./colors'); + +var _dedentLines = require('./dedentLines'); + +var _utils2 = require('./utils'); + +function _interopRequireDefault(obj) { + return obj && obj.__esModule ? obj : {default: obj}; +} + +/** + * Copyright (c) Facebook, Inc. and its affiliates. 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. + */ + +/* eslint-disable local/ban-types-eventually */ +// Temporary hack because getObjectSubset has known limitations, +// is not in the public interface of the expect package, +// and the long-term goal is to use a non-serialization diff. +// Make sure to remove file from `exports` in `expect/package.json`. +const getSnapshotColorForChalkInstance = chalkInstance => { + const level = chalkInstance.level; + + if (level === 3) { + return chalkInstance + .rgb( + _colors.aForeground3[0], + _colors.aForeground3[1], + _colors.aForeground3[2] + ) + .bgRgb( + _colors.aBackground3[0], + _colors.aBackground3[1], + _colors.aBackground3[2] + ); + } + + if (level === 2) { + return chalkInstance + .ansi256(_colors.aForeground2) + .bgAnsi256(_colors.aBackground2); + } + + return chalkInstance.magenta.bgYellowBright; +}; + +exports.getSnapshotColorForChalkInstance = getSnapshotColorForChalkInstance; + +const getReceivedColorForChalkInstance = chalkInstance => { + const level = chalkInstance.level; + + if (level === 3) { + return chalkInstance + .rgb( + _colors.bForeground3[0], + _colors.bForeground3[1], + _colors.bForeground3[2] + ) + .bgRgb( + _colors.bBackground3[0], + _colors.bBackground3[1], + _colors.bBackground3[2] + ); + } + + if (level === 2) { + return chalkInstance + .ansi256(_colors.bForeground2) + .bgAnsi256(_colors.bBackground2); + } + + return chalkInstance.cyan.bgWhiteBright; // also known as teal +}; + +exports.getReceivedColorForChalkInstance = getReceivedColorForChalkInstance; +const aSnapshotColor = getSnapshotColorForChalkInstance(_chalk.default); +exports.aSnapshotColor = aSnapshotColor; +const bReceivedColor = getReceivedColorForChalkInstance(_chalk.default); +exports.bReceivedColor = bReceivedColor; + +const noColor = string => string; + +exports.noColor = noColor; +const HINT_ARG = 'hint'; +exports.HINT_ARG = HINT_ARG; +const SNAPSHOT_ARG = 'snapshot'; +exports.SNAPSHOT_ARG = SNAPSHOT_ARG; +const PROPERTIES_ARG = 'properties'; +exports.PROPERTIES_ARG = PROPERTIES_ARG; + +const matcherHintFromConfig = ( + {context: {isNot, promise}, hint, inlineSnapshot, matcherName, properties}, + isUpdatable +) => { + const options = { + isNot, + promise + }; + + if (isUpdatable) { + options.receivedColor = bReceivedColor; + } + + let expectedArgument = ''; + + if (typeof properties === 'object') { + expectedArgument = PROPERTIES_ARG; + + if (isUpdatable) { + options.expectedColor = noColor; + } + + if (typeof hint === 'string' && hint.length !== 0) { + options.secondArgument = HINT_ARG; + options.secondArgumentColor = _jestMatcherUtils.BOLD_WEIGHT; + } else if (typeof inlineSnapshot === 'string') { + options.secondArgument = SNAPSHOT_ARG; + + if (isUpdatable) { + options.secondArgumentColor = aSnapshotColor; + } else { + options.secondArgumentColor = noColor; + } + } + } else { + if (typeof hint === 'string' && hint.length !== 0) { + expectedArgument = HINT_ARG; + options.expectedColor = _jestMatcherUtils.BOLD_WEIGHT; + } else if (typeof inlineSnapshot === 'string') { + expectedArgument = SNAPSHOT_ARG; + + if (isUpdatable) { + options.expectedColor = aSnapshotColor; + } + } + } + + return (0, _jestMatcherUtils.matcherHint)( + matcherName, + undefined, + expectedArgument, + options + ); +}; // Given array of diffs, return string: +// * include common substrings +// * exclude change substrings which have opposite op +// * include change substrings which have argument op +// with change color only if there is a common substring + +exports.matcherHintFromConfig = matcherHintFromConfig; + +const joinDiffs = (diffs, op, hasCommon) => + diffs.reduce( + (reduced, diff) => + reduced + + (diff[0] === _jestDiff.DIFF_EQUAL + ? diff[1] + : diff[0] !== op + ? '' + : hasCommon + ? (0, _jestMatcherUtils.INVERTED_COLOR)(diff[1]) + : diff[1]), + '' + ); + +const isLineDiffable = received => { + const receivedType = (0, _jestGetType.getType)(received); + + if ((0, _jestGetType.isPrimitive)(received)) { + return typeof received === 'string'; + } + + if ( + receivedType === 'date' || + receivedType === 'function' || + receivedType === 'regexp' + ) { + return false; + } + + if (received instanceof Error) { + return false; + } + + if ( + receivedType === 'object' && + typeof received.asymmetricMatch === 'function' + ) { + return false; + } + + return true; +}; + +const printExpected = val => + (0, _jestMatcherUtils.EXPECTED_COLOR)((0, _utils2.minify)(val)); + +exports.printExpected = printExpected; + +const printReceived = val => + (0, _jestMatcherUtils.RECEIVED_COLOR)((0, _utils2.minify)(val)); + +exports.printReceived = printReceived; + +const printPropertiesAndReceived = ( + properties, + received, + expand // CLI options: true if `--expand` or false if `--no-expand` +) => { + const aAnnotation = 'Expected properties'; + const bAnnotation = 'Received value'; + + if (isLineDiffable(properties) && isLineDiffable(received)) { + return (0, _jestDiff.diffLinesUnified)( + (0, _utils2.serialize)(properties).split('\n'), + (0, _utils2.serialize)( + (0, _utils.getObjectSubset)(received, properties) + ).split('\n'), + { + aAnnotation, + aColor: _jestMatcherUtils.EXPECTED_COLOR, + bAnnotation, + bColor: _jestMatcherUtils.RECEIVED_COLOR, + changeLineTrailingSpaceColor: _chalk.default.bgYellow, + commonLineTrailingSpaceColor: _chalk.default.bgYellow, + emptyFirstOrLastLinePlaceholder: '↵', + // U+21B5 + expand, + includeChangeCounts: true + } + ); + } + + const printLabel = (0, _jestMatcherUtils.getLabelPrinter)( + aAnnotation, + bAnnotation + ); + return ( + printLabel(aAnnotation) + + printExpected(properties) + + '\n' + + printLabel(bAnnotation) + + printReceived(received) + ); +}; + +exports.printPropertiesAndReceived = printPropertiesAndReceived; +const MAX_DIFF_STRING_LENGTH = 20000; + +const printSnapshotAndReceived = ( + a, + b, + received, + expand // CLI options: true if `--expand` or false if `--no-expand` +) => { + const aAnnotation = 'Snapshot'; + const bAnnotation = 'Received'; + const aColor = aSnapshotColor; + const bColor = bReceivedColor; + const options = { + aAnnotation, + aColor, + bAnnotation, + bColor, + changeLineTrailingSpaceColor: noColor, + commonLineTrailingSpaceColor: _chalk.default.bgYellow, + emptyFirstOrLastLinePlaceholder: '↵', + // U+21B5 + expand, + includeChangeCounts: true + }; + + if (typeof received === 'string') { + if ( + a.length >= 2 && + a.startsWith('"') && + a.endsWith('"') && + b === (0, _prettyFormat.format)(received) + ) { + // If snapshot looks like default serialization of a string + // and received is string which has default serialization. + if (!a.includes('\n') && !b.includes('\n')) { + // If neither string is multiline, + // display as labels and quoted strings. + let aQuoted = a; + let bQuoted = b; + + if ( + a.length - 2 <= MAX_DIFF_STRING_LENGTH && + b.length - 2 <= MAX_DIFF_STRING_LENGTH + ) { + const diffs = (0, _jestDiff.diffStringsRaw)( + a.slice(1, -1), + b.slice(1, -1), + true + ); + const hasCommon = diffs.some( + diff => diff[0] === _jestDiff.DIFF_EQUAL + ); + aQuoted = + '"' + joinDiffs(diffs, _jestDiff.DIFF_DELETE, hasCommon) + '"'; + bQuoted = + '"' + joinDiffs(diffs, _jestDiff.DIFF_INSERT, hasCommon) + '"'; + } + + const printLabel = (0, _jestMatcherUtils.getLabelPrinter)( + aAnnotation, + bAnnotation + ); + return ( + printLabel(aAnnotation) + + aColor(aQuoted) + + '\n' + + printLabel(bAnnotation) + + bColor(bQuoted) + ); + } // Else either string is multiline, so display as unquoted strings. + + a = (0, _utils2.deserializeString)(a); // hypothetical expected string + + b = received; // not serialized + } // Else expected had custom serialization or was not a string + // or received has custom serialization. + + return a.length <= MAX_DIFF_STRING_LENGTH && + b.length <= MAX_DIFF_STRING_LENGTH + ? (0, _jestDiff.diffStringsUnified)(a, b, options) + : (0, _jestDiff.diffLinesUnified)(a.split('\n'), b.split('\n'), options); + } + + if (isLineDiffable(received)) { + const aLines2 = a.split('\n'); + const bLines2 = b.split('\n'); // Fall through to fix a regression for custom serializers + // like jest-snapshot-serializer-raw that ignore the indent option. + + const b0 = (0, _utils2.serialize)(received, 0); + + if (b0 !== b) { + const aLines0 = (0, _dedentLines.dedentLines)(aLines2); + + if (aLines0 !== null) { + // Compare lines without indentation. + const bLines0 = b0.split('\n'); + return (0, _jestDiff.diffLinesUnified2)( + aLines2, + bLines2, + aLines0, + bLines0, + options + ); + } + } // Fall back because: + // * props include a multiline string + // * text has more than one adjacent line + // * markup does not close + + return (0, _jestDiff.diffLinesUnified)(aLines2, bLines2, options); + } + + const printLabel = (0, _jestMatcherUtils.getLabelPrinter)( + aAnnotation, + bAnnotation + ); + return ( + printLabel(aAnnotation) + + aColor(a) + + '\n' + + printLabel(bAnnotation) + + bColor(b) + ); +}; + +exports.printSnapshotAndReceived = printSnapshotAndReceived; diff --git a/node_modules/jest-snapshot/build/types.d.ts b/node_modules/jest-snapshot/build/types.d.ts new file mode 100644 index 0000000..627f1ac --- /dev/null +++ b/node_modules/jest-snapshot/build/types.d.ts @@ -0,0 +1,25 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. 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. + */ +import type { MatcherState } from 'expect'; +import type SnapshotState from './State'; +export declare type Context = MatcherState & { + snapshotState: SnapshotState; +}; +export declare type MatchSnapshotConfig = { + context: Context; + hint?: string; + inlineSnapshot?: string; + isInline: boolean; + matcherName: string; + properties?: object; + received: any; +}; +export declare type SnapshotData = Record<string, string>; +export declare type ExpectationResult = { + pass: boolean; + message: () => string; +}; diff --git a/node_modules/jest-snapshot/build/types.js b/node_modules/jest-snapshot/build/types.js new file mode 100644 index 0000000..ad9a93a --- /dev/null +++ b/node_modules/jest-snapshot/build/types.js @@ -0,0 +1 @@ +'use strict'; diff --git a/node_modules/jest-snapshot/build/utils.d.ts b/node_modules/jest-snapshot/build/utils.d.ts new file mode 100644 index 0000000..3b17cc2 --- /dev/null +++ b/node_modules/jest-snapshot/build/utils.d.ts @@ -0,0 +1,28 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. 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. + */ +import type { Config } from '@jest/types'; +import { OptionsReceived as PrettyFormatOptions } from 'pretty-format'; +import type { SnapshotData } from './types'; +export declare const SNAPSHOT_VERSION = "1"; +export declare const SNAPSHOT_GUIDE_LINK = "https://goo.gl/fbAQLP"; +export declare const SNAPSHOT_VERSION_WARNING: string; +export declare const testNameToKey: (testName: Config.Path, count: number) => string; +export declare const keyToTestName: (key: string) => string; +export declare const getSnapshotData: (snapshotPath: Config.Path, update: Config.SnapshotUpdateState) => { + data: SnapshotData; + dirty: boolean; +}; +export declare const addExtraLineBreaks: (string: string) => string; +export declare const removeExtraLineBreaks: (string: string) => string; +export declare const removeLinesBeforeExternalMatcherTrap: (stack: string) => string; +export declare const serialize: (val: unknown, indent?: number, formatOverrides?: PrettyFormatOptions) => string; +export declare const minify: (val: unknown) => string; +export declare const deserializeString: (stringified: string) => string; +export declare const escapeBacktickString: (str: string) => string; +export declare const ensureDirectoryExists: (filePath: Config.Path) => void; +export declare const saveSnapshotFile: (snapshotData: SnapshotData, snapshotPath: Config.Path) => void; +export declare const deepMerge: (target: any, source: any) => any; 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; |