| 'use strict'; |
| |
| Object.defineProperty(exports, '__esModule', { |
| value: true |
| }); |
| exports.printSnapshotAndReceived = exports.printPropertiesAndReceived = exports.printReceived = exports.printExpected = exports.matcherHintFromConfig = exports.PROPERTIES_ARG = exports.SNAPSHOT_ARG = exports.HINT_ARG = exports.noColor = exports.bReceivedColor = exports.aSnapshotColor = exports.getReceivedColorForChalkInstance = exports.getSnapshotColorForChalkInstance = void 0; |
| |
| var _chalk = _interopRequireDefault(require('chalk')); |
| |
| var _utils = require('expect/build/utils'); |
| |
| var _jestDiff = require('jest-diff'); |
| |
| var _jestGetType = _interopRequireDefault(require('jest-get-type')); |
| |
| var _jestMatcherUtils = require('jest-matcher-utils'); |
| |
| var _prettyFormat = _interopRequireDefault(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. |
| 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.default)(received); |
| |
| if (_jestGetType.default.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) => { |
| 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) => { |
| 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.default)(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; |