index.js 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588
  1. /*!
  2. * /**
  3. * * Copyright (c) Meta Platforms, Inc. and affiliates.
  4. * *
  5. * * This source code is licensed under the MIT license found in the
  6. * * LICENSE file in the root directory of this source tree.
  7. * * /
  8. */
  9. /******/ (() => { // webpackBootstrap
  10. /******/ "use strict";
  11. /******/ var __webpack_modules__ = ({
  12. /***/ "./src/Replaceable.ts":
  13. /***/ ((__unused_webpack_module, exports) => {
  14. Object.defineProperty(exports, "__esModule", ({
  15. value: true
  16. }));
  17. exports["default"] = void 0;
  18. var _getType = require("@jest/get-type");
  19. /**
  20. * Copyright (c) Meta Platforms, Inc. and affiliates.
  21. *
  22. * This source code is licensed under the MIT license found in the
  23. * LICENSE file in the root directory of this source tree.
  24. */
  25. const supportTypes = new Set(['map', 'array', 'object']);
  26. /* eslint-disable @typescript-eslint/explicit-module-boundary-types */
  27. class Replaceable {
  28. object;
  29. type;
  30. constructor(object) {
  31. this.object = object;
  32. this.type = (0, _getType.getType)(object);
  33. if (!supportTypes.has(this.type)) {
  34. throw new Error(`Type ${this.type} is not support in Replaceable!`);
  35. }
  36. }
  37. static isReplaceable(obj1, obj2) {
  38. const obj1Type = (0, _getType.getType)(obj1);
  39. const obj2Type = (0, _getType.getType)(obj2);
  40. return obj1Type === obj2Type && supportTypes.has(obj1Type);
  41. }
  42. forEach(cb) {
  43. if (this.type === 'object') {
  44. const descriptors = Object.getOwnPropertyDescriptors(this.object);
  45. for (const key of [...Object.keys(descriptors), ...Object.getOwnPropertySymbols(descriptors)]
  46. //@ts-expect-error because typescript do not support symbol key in object
  47. //https://github.com/microsoft/TypeScript/issues/1863
  48. .filter(key => descriptors[key].enumerable)) {
  49. cb(this.object[key], key, this.object);
  50. }
  51. } else {
  52. // eslint-disable-next-line unicorn/no-array-for-each
  53. this.object.forEach(cb);
  54. }
  55. }
  56. get(key) {
  57. if (this.type === 'map') {
  58. return this.object.get(key);
  59. }
  60. return this.object[key];
  61. }
  62. set(key, value) {
  63. if (this.type === 'map') {
  64. this.object.set(key, value);
  65. } else {
  66. this.object[key] = value;
  67. }
  68. }
  69. }
  70. /* eslint-enable */
  71. exports["default"] = Replaceable;
  72. /***/ }),
  73. /***/ "./src/deepCyclicCopyReplaceable.ts":
  74. /***/ ((__unused_webpack_module, exports) => {
  75. Object.defineProperty(exports, "__esModule", ({
  76. value: true
  77. }));
  78. exports.SERIALIZABLE_PROPERTIES = void 0;
  79. exports["default"] = deepCyclicCopyReplaceable;
  80. var _prettyFormat = require("pretty-format");
  81. var Symbol = globalThis['jest-symbol-do-not-touch'] || globalThis.Symbol;
  82. /**
  83. * Copyright (c) Meta Platforms, Inc. and affiliates.
  84. *
  85. * This source code is licensed under the MIT license found in the
  86. * LICENSE file in the root directory of this source tree.
  87. */
  88. const builtInObject = [Array, Date, Float32Array, Float64Array, Int16Array, Int32Array, Int8Array, Map, Set, RegExp, Uint16Array, Uint32Array, Uint8Array, Uint8ClampedArray];
  89. if (typeof Buffer !== 'undefined') {
  90. builtInObject.push(Buffer);
  91. }
  92. if (typeof Window !== 'undefined') {
  93. builtInObject.push(Window);
  94. }
  95. const SERIALIZABLE_PROPERTIES = exports.SERIALIZABLE_PROPERTIES = Symbol.for('@jest/serializableProperties');
  96. const isBuiltInObject = object => builtInObject.includes(object.constructor);
  97. const isMap = value => value.constructor === Map;
  98. function deepCyclicCopyReplaceable(value, cycles = new WeakMap()) {
  99. if (typeof value !== 'object' || value === null) {
  100. return value;
  101. } else if (cycles.has(value)) {
  102. return cycles.get(value);
  103. } else if (Array.isArray(value)) {
  104. return deepCyclicCopyArray(value, cycles);
  105. } else if (isMap(value)) {
  106. return deepCyclicCopyMap(value, cycles);
  107. } else if (isBuiltInObject(value)) {
  108. return value;
  109. } else if (_prettyFormat.plugins.DOMElement.test(value)) {
  110. return value.cloneNode(true);
  111. } else {
  112. return deepCyclicCopyObject(value, cycles);
  113. }
  114. }
  115. function deepCyclicCopyObject(object, cycles) {
  116. const newObject = Object.create(Object.getPrototypeOf(object));
  117. let descriptors = {};
  118. let obj = object;
  119. do {
  120. const serializableProperties = getSerializableProperties(obj);
  121. if (serializableProperties === undefined) {
  122. descriptors = Object.assign(Object.create(null), Object.getOwnPropertyDescriptors(obj), descriptors);
  123. } else {
  124. for (const property of serializableProperties) {
  125. if (!descriptors[property]) {
  126. descriptors[property] = Object.getOwnPropertyDescriptor(obj, property);
  127. }
  128. }
  129. }
  130. } while ((obj = Object.getPrototypeOf(obj)) && obj !== Object.getPrototypeOf({}));
  131. cycles.set(object, newObject);
  132. const newDescriptors = [...Object.keys(descriptors), ...Object.getOwnPropertySymbols(descriptors)].reduce(
  133. //@ts-expect-error because typescript do not support symbol key in object
  134. //https://github.com/microsoft/TypeScript/issues/1863
  135. (newDescriptors, key) => {
  136. const enumerable = descriptors[key].enumerable;
  137. newDescriptors[key] = {
  138. configurable: true,
  139. enumerable,
  140. value: deepCyclicCopyReplaceable(
  141. // this accesses the value or getter, depending. We just care about the value anyways, and this allows us to not mess with accessors
  142. // it has the side effect of invoking the getter here though, rather than copying it over
  143. object[key], cycles),
  144. writable: true
  145. };
  146. return newDescriptors;
  147. }, Object.create(null));
  148. //@ts-expect-error because typescript do not support symbol key in object
  149. //https://github.com/microsoft/TypeScript/issues/1863
  150. return Object.defineProperties(newObject, newDescriptors);
  151. }
  152. function deepCyclicCopyArray(array, cycles) {
  153. const newArray = new (Object.getPrototypeOf(array).constructor)(array.length);
  154. const length = array.length;
  155. cycles.set(array, newArray);
  156. for (let i = 0; i < length; i++) {
  157. newArray[i] = deepCyclicCopyReplaceable(array[i], cycles);
  158. }
  159. return newArray;
  160. }
  161. function deepCyclicCopyMap(map, cycles) {
  162. const newMap = new Map();
  163. cycles.set(map, newMap);
  164. for (const [key, value] of map) {
  165. newMap.set(key, deepCyclicCopyReplaceable(value, cycles));
  166. }
  167. return newMap;
  168. }
  169. function getSerializableProperties(obj) {
  170. if (typeof obj !== 'object' || obj === null) {
  171. return;
  172. }
  173. const serializableProperties = obj[SERIALIZABLE_PROPERTIES];
  174. if (!Array.isArray(serializableProperties)) {
  175. return;
  176. }
  177. return serializableProperties.filter(key => typeof key === 'string' || typeof key === 'symbol');
  178. }
  179. /***/ })
  180. /******/ });
  181. /************************************************************************/
  182. /******/ // The module cache
  183. /******/ var __webpack_module_cache__ = {};
  184. /******/
  185. /******/ // The require function
  186. /******/ function __webpack_require__(moduleId) {
  187. /******/ // Check if module is in cache
  188. /******/ var cachedModule = __webpack_module_cache__[moduleId];
  189. /******/ if (cachedModule !== undefined) {
  190. /******/ return cachedModule.exports;
  191. /******/ }
  192. /******/ // Create a new module (and put it into the cache)
  193. /******/ var module = __webpack_module_cache__[moduleId] = {
  194. /******/ // no module.id needed
  195. /******/ // no module.loaded needed
  196. /******/ exports: {}
  197. /******/ };
  198. /******/
  199. /******/ // Execute the module function
  200. /******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
  201. /******/
  202. /******/ // Return the exports of the module
  203. /******/ return module.exports;
  204. /******/ }
  205. /******/
  206. /************************************************************************/
  207. var __webpack_exports__ = {};
  208. // This entry needs to be wrapped in an IIFE because it uses a non-standard name for the exports (exports).
  209. (() => {
  210. var exports = __webpack_exports__;
  211. Object.defineProperty(exports, "__esModule", ({
  212. value: true
  213. }));
  214. exports.RECEIVED_COLOR = exports.INVERTED_COLOR = exports.EXPECTED_COLOR = exports.DIM_COLOR = exports.BOLD_WEIGHT = void 0;
  215. Object.defineProperty(exports, "SERIALIZABLE_PROPERTIES", ({
  216. enumerable: true,
  217. get: function () {
  218. return _deepCyclicCopyReplaceable.SERIALIZABLE_PROPERTIES;
  219. }
  220. }));
  221. exports.printReceived = exports.printExpected = exports.printDiffOrStringify = exports.pluralize = exports.matcherHint = exports.matcherErrorMessage = exports.highlightTrailingWhitespace = exports.getLabelPrinter = exports.ensureNumbers = exports.ensureNoExpected = exports.ensureExpectedIsNumber = exports.ensureExpectedIsNonNegativeInteger = exports.ensureActualIsNumber = exports.diff = exports.SUGGEST_TO_CONTAIN_EQUAL = void 0;
  222. exports.printWithType = printWithType;
  223. exports.replaceMatchedToAsymmetricMatcher = replaceMatchedToAsymmetricMatcher;
  224. exports.stringify = void 0;
  225. var _chalk = _interopRequireDefault(require("chalk"));
  226. var _getType = require("@jest/get-type");
  227. var _jestDiff = require("jest-diff");
  228. var _prettyFormat = require("pretty-format");
  229. var _Replaceable = _interopRequireDefault(__webpack_require__("./src/Replaceable.ts"));
  230. var _deepCyclicCopyReplaceable = _interopRequireWildcard(__webpack_require__("./src/deepCyclicCopyReplaceable.ts"));
  231. function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
  232. function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
  233. /**
  234. * Copyright (c) Meta Platforms, Inc. and affiliates.
  235. *
  236. * This source code is licensed under the MIT license found in the
  237. * LICENSE file in the root directory of this source tree.
  238. */
  239. const {
  240. AsymmetricMatcher,
  241. DOMCollection,
  242. DOMElement,
  243. Immutable,
  244. ReactElement,
  245. ReactTestComponent
  246. } = _prettyFormat.plugins;
  247. const PLUGINS = [ReactTestComponent, ReactElement, DOMElement, DOMCollection, Immutable, AsymmetricMatcher];
  248. // subset of Chalk type
  249. const EXPECTED_COLOR = exports.EXPECTED_COLOR = _chalk.default.green;
  250. const RECEIVED_COLOR = exports.RECEIVED_COLOR = _chalk.default.red;
  251. const INVERTED_COLOR = exports.INVERTED_COLOR = _chalk.default.inverse;
  252. const BOLD_WEIGHT = exports.BOLD_WEIGHT = _chalk.default.bold;
  253. const DIM_COLOR = exports.DIM_COLOR = _chalk.default.dim;
  254. const MULTILINE_REGEXP = /\n/;
  255. const SPACE_SYMBOL = '\u{00B7}'; // middle dot
  256. const NUMBERS = ['zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten', 'eleven', 'twelve', 'thirteen'];
  257. const SUGGEST_TO_CONTAIN_EQUAL = exports.SUGGEST_TO_CONTAIN_EQUAL = _chalk.default.dim('Looks like you wanted to test for object/array equality with the stricter `toContain` matcher. You probably need to use `toContainEqual` instead.');
  258. const stringify = (object, maxDepth = 10, maxWidth = 10) => {
  259. const MAX_LENGTH = 10_000;
  260. let result;
  261. try {
  262. result = (0, _prettyFormat.format)(object, {
  263. maxDepth,
  264. maxWidth,
  265. min: true,
  266. plugins: PLUGINS
  267. });
  268. } catch {
  269. result = (0, _prettyFormat.format)(object, {
  270. callToJSON: false,
  271. maxDepth,
  272. maxWidth,
  273. min: true,
  274. plugins: PLUGINS
  275. });
  276. }
  277. if (result.length >= MAX_LENGTH && maxDepth > 1) {
  278. return stringify(object, Math.floor(maxDepth / 2), maxWidth);
  279. } else if (result.length >= MAX_LENGTH && maxWidth > 1) {
  280. return stringify(object, maxDepth, Math.floor(maxWidth / 2));
  281. } else {
  282. return result;
  283. }
  284. };
  285. exports.stringify = stringify;
  286. const highlightTrailingWhitespace = text => text.replaceAll(/\s+$/gm, _chalk.default.inverse('$&'));
  287. // Instead of inverse highlight which now implies a change,
  288. // replace common spaces with middle dot at the end of any line.
  289. exports.highlightTrailingWhitespace = highlightTrailingWhitespace;
  290. const replaceTrailingSpaces = text => text.replaceAll(/\s+$/gm, spaces => SPACE_SYMBOL.repeat(spaces.length));
  291. const printReceived = object => RECEIVED_COLOR(replaceTrailingSpaces(stringify(object)));
  292. exports.printReceived = printReceived;
  293. const printExpected = value => EXPECTED_COLOR(replaceTrailingSpaces(stringify(value)));
  294. exports.printExpected = printExpected;
  295. function printWithType(name, value, print) {
  296. const type = (0, _getType.getType)(value);
  297. const hasType = type !== 'null' && type !== 'undefined' ? `${name} has type: ${type}\n` : '';
  298. const hasValue = `${name} has value: ${print(value)}`;
  299. return hasType + hasValue;
  300. }
  301. const ensureNoExpected = (expected, matcherName, options) => {
  302. if (expected !== undefined) {
  303. // Prepend maybe not only for backward compatibility.
  304. const matcherString = (options ? '' : '[.not]') + matcherName;
  305. throw new Error(matcherErrorMessage(matcherHint(matcherString, undefined, '', options),
  306. // Because expected is omitted in hint above,
  307. // expected is black instead of green in message below.
  308. 'this matcher must not have an expected argument', printWithType('Expected', expected, printExpected)));
  309. }
  310. };
  311. /**
  312. * Ensures that `actual` is of type `number | bigint`
  313. */
  314. exports.ensureNoExpected = ensureNoExpected;
  315. const ensureActualIsNumber = (actual, matcherName, options) => {
  316. if (typeof actual !== 'number' && typeof actual !== 'bigint') {
  317. // Prepend maybe not only for backward compatibility.
  318. const matcherString = (options ? '' : '[.not]') + matcherName;
  319. throw new Error(matcherErrorMessage(matcherHint(matcherString, undefined, undefined, options), `${RECEIVED_COLOR('received')} value must be a number or bigint`, printWithType('Received', actual, printReceived)));
  320. }
  321. };
  322. /**
  323. * Ensures that `expected` is of type `number | bigint`
  324. */
  325. exports.ensureActualIsNumber = ensureActualIsNumber;
  326. const ensureExpectedIsNumber = (expected, matcherName, options) => {
  327. if (typeof expected !== 'number' && typeof expected !== 'bigint') {
  328. // Prepend maybe not only for backward compatibility.
  329. const matcherString = (options ? '' : '[.not]') + matcherName;
  330. throw new Error(matcherErrorMessage(matcherHint(matcherString, undefined, undefined, options), `${EXPECTED_COLOR('expected')} value must be a number or bigint`, printWithType('Expected', expected, printExpected)));
  331. }
  332. };
  333. /**
  334. * Ensures that `actual` & `expected` are of type `number | bigint`
  335. */
  336. exports.ensureExpectedIsNumber = ensureExpectedIsNumber;
  337. const ensureNumbers = (actual, expected, matcherName, options) => {
  338. ensureActualIsNumber(actual, matcherName, options);
  339. ensureExpectedIsNumber(expected, matcherName, options);
  340. };
  341. exports.ensureNumbers = ensureNumbers;
  342. const ensureExpectedIsNonNegativeInteger = (expected, matcherName, options) => {
  343. if (typeof expected !== 'number' || !Number.isSafeInteger(expected) || expected < 0) {
  344. // Prepend maybe not only for backward compatibility.
  345. const matcherString = (options ? '' : '[.not]') + matcherName;
  346. throw new Error(matcherErrorMessage(matcherHint(matcherString, undefined, undefined, options), `${EXPECTED_COLOR('expected')} value must be a non-negative integer`, printWithType('Expected', expected, printExpected)));
  347. }
  348. };
  349. // Given array of diffs, return concatenated string:
  350. // * include common substrings
  351. // * exclude change substrings which have opposite op
  352. // * include change substrings which have argument op
  353. // with inverse highlight only if there is a common substring
  354. exports.ensureExpectedIsNonNegativeInteger = ensureExpectedIsNonNegativeInteger;
  355. const getCommonAndChangedSubstrings = (diffs, op, hasCommonDiff) => diffs.reduce((reduced, diff) => reduced + (diff[0] === _jestDiff.DIFF_EQUAL ? diff[1] : diff[0] === op ? hasCommonDiff ? INVERTED_COLOR(diff[1]) : diff[1] : ''), '');
  356. const isLineDiffable = (expected, received) => {
  357. const expectedType = (0, _getType.getType)(expected);
  358. const receivedType = (0, _getType.getType)(received);
  359. if (expectedType !== receivedType) {
  360. return false;
  361. }
  362. if ((0, _getType.isPrimitive)(expected)) {
  363. // Print generic line diff for strings only:
  364. // * if neither string is empty
  365. // * if either string has more than one line
  366. return typeof expected === 'string' && typeof received === 'string' && expected.length > 0 && received.length > 0 && (MULTILINE_REGEXP.test(expected) || MULTILINE_REGEXP.test(received));
  367. }
  368. if (expectedType === 'date' || expectedType === 'function' || expectedType === 'regexp') {
  369. return false;
  370. }
  371. if (expected instanceof Error && received instanceof Error) {
  372. return false;
  373. }
  374. if (receivedType === 'object' && typeof received.asymmetricMatch === 'function') {
  375. return false;
  376. }
  377. return true;
  378. };
  379. const MAX_DIFF_STRING_LENGTH = 20_000;
  380. const printDiffOrStringify = (expected, received, expectedLabel, receivedLabel, expand // CLI options: true if `--expand` or false if `--no-expand`
  381. ) => {
  382. if (typeof expected === 'string' && typeof received === 'string' && expected.length > 0 && received.length > 0 && expected.length <= MAX_DIFF_STRING_LENGTH && received.length <= MAX_DIFF_STRING_LENGTH && expected !== received) {
  383. if (expected.includes('\n') || received.includes('\n')) {
  384. return (0, _jestDiff.diffStringsUnified)(expected, received, {
  385. aAnnotation: expectedLabel,
  386. bAnnotation: receivedLabel,
  387. changeLineTrailingSpaceColor: _chalk.default.bgYellow,
  388. commonLineTrailingSpaceColor: _chalk.default.bgYellow,
  389. emptyFirstOrLastLinePlaceholder: '↵',
  390. // U+21B5
  391. expand,
  392. includeChangeCounts: true
  393. });
  394. }
  395. const diffs = (0, _jestDiff.diffStringsRaw)(expected, received, true);
  396. const hasCommonDiff = diffs.some(diff => diff[0] === _jestDiff.DIFF_EQUAL);
  397. const printLabel = getLabelPrinter(expectedLabel, receivedLabel);
  398. const expectedLine = printLabel(expectedLabel) + printExpected(getCommonAndChangedSubstrings(diffs, _jestDiff.DIFF_DELETE, hasCommonDiff));
  399. const receivedLine = printLabel(receivedLabel) + printReceived(getCommonAndChangedSubstrings(diffs, _jestDiff.DIFF_INSERT, hasCommonDiff));
  400. return `${expectedLine}\n${receivedLine}`;
  401. }
  402. if (isLineDiffable(expected, received)) {
  403. const {
  404. replacedExpected,
  405. replacedReceived
  406. } = replaceMatchedToAsymmetricMatcher(expected, received, [], []);
  407. const difference = (0, _jestDiff.diff)(replacedExpected, replacedReceived, {
  408. aAnnotation: expectedLabel,
  409. bAnnotation: receivedLabel,
  410. expand,
  411. includeChangeCounts: true
  412. });
  413. if (typeof difference === 'string' && difference.includes(`- ${expectedLabel}`) && difference.includes(`+ ${receivedLabel}`)) {
  414. return difference;
  415. }
  416. }
  417. const printLabel = getLabelPrinter(expectedLabel, receivedLabel);
  418. const expectedLine = printLabel(expectedLabel) + printExpected(expected);
  419. const receivedLine = printLabel(receivedLabel) + (stringify(expected) === stringify(received) ? 'serializes to the same string' : printReceived(received));
  420. return `${expectedLine}\n${receivedLine}`;
  421. };
  422. // Sometimes, e.g. when comparing two numbers, the output from jest-diff
  423. // does not contain more information than the `Expected:` / `Received:` already gives.
  424. // In those cases, we do not print a diff to make the output shorter and not redundant.
  425. exports.printDiffOrStringify = printDiffOrStringify;
  426. const shouldPrintDiff = (actual, expected) => {
  427. if (typeof actual === 'number' && typeof expected === 'number') {
  428. return false;
  429. }
  430. if (typeof actual === 'bigint' && typeof expected === 'bigint') {
  431. return false;
  432. }
  433. if (typeof actual === 'boolean' && typeof expected === 'boolean') {
  434. return false;
  435. }
  436. return true;
  437. };
  438. function replaceMatchedToAsymmetricMatcher(replacedExpected, replacedReceived, expectedCycles, receivedCycles) {
  439. return _replaceMatchedToAsymmetricMatcher((0, _deepCyclicCopyReplaceable.default)(replacedExpected), (0, _deepCyclicCopyReplaceable.default)(replacedReceived), expectedCycles, receivedCycles);
  440. }
  441. function _replaceMatchedToAsymmetricMatcher(replacedExpected, replacedReceived, expectedCycles, receivedCycles) {
  442. if (!_Replaceable.default.isReplaceable(replacedExpected, replacedReceived)) {
  443. return {
  444. replacedExpected,
  445. replacedReceived
  446. };
  447. }
  448. if (expectedCycles.includes(replacedExpected) || receivedCycles.includes(replacedReceived)) {
  449. return {
  450. replacedExpected,
  451. replacedReceived
  452. };
  453. }
  454. expectedCycles.push(replacedExpected);
  455. receivedCycles.push(replacedReceived);
  456. const expectedReplaceable = new _Replaceable.default(replacedExpected);
  457. const receivedReplaceable = new _Replaceable.default(replacedReceived);
  458. // eslint-disable-next-line unicorn/no-array-for-each
  459. expectedReplaceable.forEach((expectedValue, key) => {
  460. const receivedValue = receivedReplaceable.get(key);
  461. if (isAsymmetricMatcher(expectedValue)) {
  462. if (expectedValue.asymmetricMatch(receivedValue)) {
  463. receivedReplaceable.set(key, expectedValue);
  464. }
  465. } else if (isAsymmetricMatcher(receivedValue)) {
  466. if (receivedValue.asymmetricMatch(expectedValue)) {
  467. expectedReplaceable.set(key, receivedValue);
  468. }
  469. } else if (_Replaceable.default.isReplaceable(expectedValue, receivedValue)) {
  470. const replaced = _replaceMatchedToAsymmetricMatcher(expectedValue, receivedValue, expectedCycles, receivedCycles);
  471. expectedReplaceable.set(key, replaced.replacedExpected);
  472. receivedReplaceable.set(key, replaced.replacedReceived);
  473. }
  474. });
  475. return {
  476. replacedExpected: expectedReplaceable.object,
  477. replacedReceived: receivedReplaceable.object
  478. };
  479. }
  480. function isAsymmetricMatcher(data) {
  481. const type = (0, _getType.getType)(data);
  482. return type === 'object' && typeof data.asymmetricMatch === 'function';
  483. }
  484. const diff = (a, b, options) => shouldPrintDiff(a, b) ? (0, _jestDiff.diff)(a, b, options) : null;
  485. exports.diff = diff;
  486. const pluralize = (word, count) => `${NUMBERS[count] || count} ${word}${count === 1 ? '' : 's'}`;
  487. // To display lines of labeled values as two columns with monospace alignment:
  488. // given the strings which will describe the values,
  489. // return function which given each string, returns the label:
  490. // string, colon, space, and enough padding spaces to align the value.
  491. exports.pluralize = pluralize;
  492. const getLabelPrinter = (...strings) => {
  493. const maxLength = strings.reduce((max, string) => Math.max(string.length, max), 0);
  494. return string => `${string}: ${' '.repeat(maxLength - string.length)}`;
  495. };
  496. exports.getLabelPrinter = getLabelPrinter;
  497. const matcherErrorMessage = (hint, generic, specific // incorrect value returned from call to printWithType
  498. ) => `${hint}\n\n${_chalk.default.bold('Matcher error')}: ${generic}${typeof specific === 'string' ? `\n\n${specific}` : ''}`;
  499. // Display assertion for the report when a test fails.
  500. // New format: rejects/resolves, not, and matcher name have black color
  501. // Old format: matcher name has dim color
  502. exports.matcherErrorMessage = matcherErrorMessage;
  503. const matcherHint = (matcherName, received = 'received', expected = 'expected', options = {}) => {
  504. const {
  505. comment = '',
  506. expectedColor = EXPECTED_COLOR,
  507. isDirectExpectCall = false,
  508. // seems redundant with received === ''
  509. isNot = false,
  510. promise = '',
  511. receivedColor = RECEIVED_COLOR,
  512. secondArgument = '',
  513. secondArgumentColor = EXPECTED_COLOR
  514. } = options;
  515. let hint = '';
  516. let dimString = 'expect'; // concatenate adjacent dim substrings
  517. if (!isDirectExpectCall && received !== '') {
  518. hint += DIM_COLOR(`${dimString}(`) + receivedColor(received);
  519. dimString = ')';
  520. }
  521. if (promise !== '') {
  522. hint += DIM_COLOR(`${dimString}.`) + promise;
  523. dimString = '';
  524. }
  525. if (isNot) {
  526. hint += `${DIM_COLOR(`${dimString}.`)}not`;
  527. dimString = '';
  528. }
  529. if (matcherName.includes('.')) {
  530. // Old format: for backward compatibility,
  531. // especially without promise or isNot options
  532. dimString += matcherName;
  533. } else {
  534. // New format: omit period from matcherName arg
  535. hint += DIM_COLOR(`${dimString}.`) + matcherName;
  536. dimString = '';
  537. }
  538. if (expected === '') {
  539. dimString += '()';
  540. } else {
  541. hint += DIM_COLOR(`${dimString}(`) + expectedColor(expected);
  542. if (secondArgument) {
  543. hint += DIM_COLOR(', ') + secondArgumentColor(secondArgument);
  544. }
  545. dimString = ')';
  546. }
  547. if (comment !== '') {
  548. dimString += ` // ${comment}`;
  549. }
  550. if (dimString !== '') {
  551. hint += DIM_COLOR(dimString);
  552. }
  553. return hint;
  554. };
  555. exports.matcherHint = matcherHint;
  556. })();
  557. module.exports = __webpack_exports__;
  558. /******/ })()
  559. ;