UNPKG

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