index.js
1 'use strict'; 2 3 Object.defineProperty(exports, '__esModule', { 4 value: true 5 }); 6 Object.defineProperty(exports, 'DIFF_DELETE', { 7 enumerable: true, 8 get: function () { 9 return _cleanupSemantic.DIFF_DELETE; 10 } 11 }); 12 Object.defineProperty(exports, 'DIFF_EQUAL', { 13 enumerable: true, 14 get: function () { 15 return _cleanupSemantic.DIFF_EQUAL; 16 } 17 }); 18 Object.defineProperty(exports, 'DIFF_INSERT', { 19 enumerable: true, 20 get: function () { 21 return _cleanupSemantic.DIFF_INSERT; 22 } 23 }); 24 Object.defineProperty(exports, 'Diff', { 25 enumerable: true, 26 get: function () { 27 return _cleanupSemantic.Diff; 28 } 29 }); 30 Object.defineProperty(exports, 'diffLinesRaw', { 31 enumerable: true, 32 get: function () { 33 return _diffLines.diffLinesRaw; 34 } 35 }); 36 Object.defineProperty(exports, 'diffLinesUnified', { 37 enumerable: true, 38 get: function () { 39 return _diffLines.diffLinesUnified; 40 } 41 }); 42 Object.defineProperty(exports, 'diffLinesUnified2', { 43 enumerable: true, 44 get: function () { 45 return _diffLines.diffLinesUnified2; 46 } 47 }); 48 Object.defineProperty(exports, 'diffStringsRaw', { 49 enumerable: true, 50 get: function () { 51 return _printDiffs.diffStringsRaw; 52 } 53 }); 54 Object.defineProperty(exports, 'diffStringsUnified', { 55 enumerable: true, 56 get: function () { 57 return _printDiffs.diffStringsUnified; 58 } 59 }); 60 exports.default = void 0; 61 62 var _chalk = _interopRequireDefault(require('chalk')); 63 64 var _jestGetType = _interopRequireDefault(require('jest-get-type')); 65 66 var _prettyFormat = _interopRequireDefault(require('pretty-format')); 67 68 var _cleanupSemantic = require('./cleanupSemantic'); 69 70 var _constants = require('./constants'); 71 72 var _diffLines = require('./diffLines'); 73 74 var _normalizeDiffOptions = require('./normalizeDiffOptions'); 75 76 var _printDiffs = require('./printDiffs'); 77 78 function _interopRequireDefault(obj) { 79 return obj && obj.__esModule ? obj : {default: obj}; 80 } 81 82 var Symbol = global['jest-symbol-do-not-touch'] || global.Symbol; 83 84 const getCommonMessage = (message, options) => { 85 const {commonColor} = (0, _normalizeDiffOptions.normalizeDiffOptions)( 86 options 87 ); 88 return commonColor(message); 89 }; 90 91 const { 92 AsymmetricMatcher, 93 DOMCollection, 94 DOMElement, 95 Immutable, 96 ReactElement, 97 ReactTestComponent 98 } = _prettyFormat.default.plugins; 99 const PLUGINS = [ 100 ReactTestComponent, 101 ReactElement, 102 DOMElement, 103 DOMCollection, 104 Immutable, 105 AsymmetricMatcher 106 ]; 107 const FORMAT_OPTIONS = { 108 plugins: PLUGINS 109 }; 110 const FORMAT_OPTIONS_0 = {...FORMAT_OPTIONS, indent: 0}; 111 const FALLBACK_FORMAT_OPTIONS = { 112 callToJSON: false, 113 maxDepth: 10, 114 plugins: PLUGINS 115 }; 116 const FALLBACK_FORMAT_OPTIONS_0 = {...FALLBACK_FORMAT_OPTIONS, indent: 0}; // Generate a string that will highlight the difference between two values 117 // with green and red. (similar to how github does code diffing) 118 // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types 119 120 function diff(a, b, options) { 121 if (Object.is(a, b)) { 122 return getCommonMessage(_constants.NO_DIFF_MESSAGE, options); 123 } 124 125 const aType = (0, _jestGetType.default)(a); 126 let expectedType = aType; 127 let omitDifference = false; 128 129 if (aType === 'object' && typeof a.asymmetricMatch === 'function') { 130 if (a.$$typeof !== Symbol.for('jest.asymmetricMatcher')) { 131 // Do not know expected type of user-defined asymmetric matcher. 132 return null; 133 } 134 135 if (typeof a.getExpectedType !== 'function') { 136 // For example, expect.anything() matches either null or undefined 137 return null; 138 } 139 140 expectedType = a.getExpectedType(); // Primitive types boolean and number omit difference below. 141 // For example, omit difference for expect.stringMatching(regexp) 142 143 omitDifference = expectedType === 'string'; 144 } 145 146 if (expectedType !== (0, _jestGetType.default)(b)) { 147 return ( 148 ' Comparing two different types of values.' + 149 ` Expected ${_chalk.default.green(expectedType)} but ` + 150 `received ${_chalk.default.red((0, _jestGetType.default)(b))}.` 151 ); 152 } 153 154 if (omitDifference) { 155 return null; 156 } 157 158 switch (aType) { 159 case 'string': 160 return (0, _diffLines.diffLinesUnified)( 161 a.split('\n'), 162 b.split('\n'), 163 options 164 ); 165 166 case 'boolean': 167 case 'number': 168 return comparePrimitive(a, b, options); 169 170 case 'map': 171 return compareObjects(sortMap(a), sortMap(b), options); 172 173 case 'set': 174 return compareObjects(sortSet(a), sortSet(b), options); 175 176 default: 177 return compareObjects(a, b, options); 178 } 179 } 180 181 function comparePrimitive(a, b, options) { 182 const aFormat = (0, _prettyFormat.default)(a, FORMAT_OPTIONS); 183 const bFormat = (0, _prettyFormat.default)(b, FORMAT_OPTIONS); 184 return aFormat === bFormat 185 ? getCommonMessage(_constants.NO_DIFF_MESSAGE, options) 186 : (0, _diffLines.diffLinesUnified)( 187 aFormat.split('\n'), 188 bFormat.split('\n'), 189 options 190 ); 191 } 192 193 function sortMap(map) { 194 return new Map(Array.from(map.entries()).sort()); 195 } 196 197 function sortSet(set) { 198 return new Set(Array.from(set.values()).sort()); 199 } 200 201 function compareObjects(a, b, options) { 202 let difference; 203 let hasThrown = false; 204 const noDiffMessage = getCommonMessage(_constants.NO_DIFF_MESSAGE, options); 205 206 try { 207 const aCompare = (0, _prettyFormat.default)(a, FORMAT_OPTIONS_0); 208 const bCompare = (0, _prettyFormat.default)(b, FORMAT_OPTIONS_0); 209 210 if (aCompare === bCompare) { 211 difference = noDiffMessage; 212 } else { 213 const aDisplay = (0, _prettyFormat.default)(a, FORMAT_OPTIONS); 214 const bDisplay = (0, _prettyFormat.default)(b, FORMAT_OPTIONS); 215 difference = (0, _diffLines.diffLinesUnified2)( 216 aDisplay.split('\n'), 217 bDisplay.split('\n'), 218 aCompare.split('\n'), 219 bCompare.split('\n'), 220 options 221 ); 222 } 223 } catch { 224 hasThrown = true; 225 } // If the comparison yields no results, compare again but this time 226 // without calling `toJSON`. It's also possible that toJSON might throw. 227 228 if (difference === undefined || difference === noDiffMessage) { 229 const aCompare = (0, _prettyFormat.default)(a, FALLBACK_FORMAT_OPTIONS_0); 230 const bCompare = (0, _prettyFormat.default)(b, FALLBACK_FORMAT_OPTIONS_0); 231 232 if (aCompare === bCompare) { 233 difference = noDiffMessage; 234 } else { 235 const aDisplay = (0, _prettyFormat.default)(a, FALLBACK_FORMAT_OPTIONS); 236 const bDisplay = (0, _prettyFormat.default)(b, FALLBACK_FORMAT_OPTIONS); 237 difference = (0, _diffLines.diffLinesUnified2)( 238 aDisplay.split('\n'), 239 bDisplay.split('\n'), 240 aCompare.split('\n'), 241 bCompare.split('\n'), 242 options 243 ); 244 } 245 246 if (difference !== noDiffMessage && !hasThrown) { 247 difference = 248 getCommonMessage(_constants.SIMILAR_MESSAGE, options) + 249 '\n\n' + 250 difference; 251 } 252 } 253 254 return difference; 255 } 256 257 var _default = diff; 258 exports.default = _default;