expect
Version:
1,077 lines (1,040 loc) • 113 kB
JavaScript
/*!
* /**
* * Copyright (c) Meta Platforms, Inc. and affiliates.
* *
* * This source code is licensed under the MIT license found in the
* * LICENSE file in the root directory of this source tree.
* * /
*/
/******/ (() => { // webpackBootstrap
/******/ "use strict";
/******/ var __webpack_modules__ = ({
/***/ "./src/asymmetricMatchers.ts":
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
Object.defineProperty(exports, "__esModule", ({
value: true
}));
exports.closeTo = exports.arrayOf = exports.arrayNotContaining = exports.arrayContaining = exports.anything = exports.any = exports.AsymmetricMatcher = void 0;
exports.hasProperty = hasProperty;
exports.stringNotMatching = exports.stringNotContaining = exports.stringMatching = exports.stringContaining = exports.objectNotContaining = exports.objectContaining = exports.notCloseTo = exports.notArrayOf = void 0;
var _expectUtils = require("@jest/expect-utils");
var matcherUtils = _interopRequireWildcard(require("jest-matcher-utils"));
var _jestUtil = require("jest-util");
var _jestMatchersObject = __webpack_require__("./src/jestMatchersObject.ts");
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); }
var Symbol = globalThis['jest-symbol-do-not-touch'] || globalThis.Symbol;
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
const functionToString = Function.prototype.toString;
function fnNameFor(func) {
if (func.name) {
return func.name;
}
const matches = functionToString.call(func).match(/^(?:async)?\s*function\s*\*?\s*([\w$]+)\s*\(/);
return matches ? matches[1] : '<anonymous>';
}
const utils = Object.freeze({
...matcherUtils,
iterableEquality: _expectUtils.iterableEquality,
subsetEquality: _expectUtils.subsetEquality
});
function hasProperty(obj, property) {
if (!obj) {
return false;
}
if (Object.prototype.hasOwnProperty.call(obj, property)) {
return true;
}
return hasProperty(Object.getPrototypeOf(obj), property);
}
class AsymmetricMatcher {
$$typeof = Symbol.for('jest.asymmetricMatcher');
constructor(sample, inverse = false) {
this.sample = sample;
this.inverse = inverse;
}
getMatcherContext() {
return {
customTesters: (0, _jestMatchersObject.getCustomEqualityTesters)(),
// eslint-disable-next-line @typescript-eslint/no-empty-function
dontThrow: () => {},
...(0, _jestMatchersObject.getState)(),
equals: _expectUtils.equals,
isNot: this.inverse,
utils
};
}
}
exports.AsymmetricMatcher = AsymmetricMatcher;
class Any extends AsymmetricMatcher {
constructor(sample) {
if (sample === undefined) {
throw new TypeError('any() expects to be passed a constructor function. ' + 'Please pass one or use anything() to match any object.');
}
super(sample);
}
asymmetricMatch(other) {
if (this.sample === String) {
// eslint-disable-next-line unicorn/no-instanceof-builtins
return typeof other === 'string' || other instanceof String;
}
if (this.sample === Number) {
// eslint-disable-next-line unicorn/no-instanceof-builtins
return typeof other === 'number' || other instanceof Number;
}
if (this.sample === Function) {
// eslint-disable-next-line unicorn/no-instanceof-builtins
return typeof other === 'function' || other instanceof Function;
}
if (this.sample === Boolean) {
// eslint-disable-next-line unicorn/no-instanceof-builtins
return typeof other === 'boolean' || other instanceof Boolean;
}
if (this.sample === BigInt) {
// eslint-disable-next-line unicorn/no-instanceof-builtins
return typeof other === 'bigint' || other instanceof BigInt;
}
if (this.sample === Symbol) {
// eslint-disable-next-line unicorn/no-instanceof-builtins
return typeof other === 'symbol' || other instanceof Symbol;
}
if (this.sample === Object) {
return typeof other === 'object';
}
if (this.sample === Array) {
return Array.isArray(other);
}
return other instanceof this.sample;
}
toString() {
return 'Any';
}
getExpectedType() {
if (this.sample === String) {
return 'string';
}
if (this.sample === Number) {
return 'number';
}
if (this.sample === Function) {
return 'function';
}
if (this.sample === Object) {
return 'object';
}
if (this.sample === Boolean) {
return 'boolean';
}
if (this.sample === Array) {
return 'array';
}
return fnNameFor(this.sample);
}
toAsymmetricMatcher() {
return `Any<${fnNameFor(this.sample)}>`;
}
}
class Anything extends AsymmetricMatcher {
asymmetricMatch(other) {
return other != null;
}
toString() {
return 'Anything';
}
// No getExpectedType method, because it matches either null or undefined.
toAsymmetricMatcher() {
return 'Anything';
}
}
class ArrayContaining extends AsymmetricMatcher {
constructor(sample, inverse = false) {
super(sample, inverse);
}
asymmetricMatch(other) {
if (!Array.isArray(this.sample)) {
throw new TypeError(`You must provide an array to ${this.toString()}, not '${typeof this.sample}'.`);
}
const matcherContext = this.getMatcherContext();
const result = this.sample.length === 0 || Array.isArray(other) && this.sample.every(item => other.some(another => (0, _expectUtils.equals)(item, another, matcherContext.customTesters)));
return this.inverse ? !result : result;
}
toString() {
return `Array${this.inverse ? 'Not' : ''}Containing`;
}
getExpectedType() {
return 'array';
}
}
class ArrayOf extends AsymmetricMatcher {
asymmetricMatch(other) {
const matcherContext = this.getMatcherContext();
const result = Array.isArray(other) && other.every(item => (0, _expectUtils.equals)(this.sample, item, matcherContext.customTesters));
return this.inverse ? !result : result;
}
toString() {
return `${this.inverse ? 'Not' : ''}ArrayOf`;
}
getExpectedType() {
return 'array';
}
}
class ObjectContaining extends AsymmetricMatcher {
constructor(sample, inverse = false) {
super(sample, inverse);
}
asymmetricMatch(other) {
// Ensures that the argument passed to the objectContaining method is an object
if (typeof this.sample !== 'object') {
throw new TypeError(`You must provide an object to ${this.toString()}, not '${typeof this.sample}'.`);
}
// Ensures that the argument passed to the expect function is an object
// This is necessary to avoid matching of non-object values
// Arrays are a special type of object, but having a valid match with a standard object
// does not make sense, hence we do a simple array check
if (typeof other !== 'object' || Array.isArray(other)) {
return false;
}
let result = true;
const matcherContext = this.getMatcherContext();
const objectKeys = (0, _expectUtils.getObjectKeys)(this.sample);
for (const key of objectKeys) {
if (!hasProperty(other, key) || !(0, _expectUtils.equals)(this.sample[key], other[key], matcherContext.customTesters)) {
result = false;
break;
}
}
return this.inverse ? !result : result;
}
toString() {
return `Object${this.inverse ? 'Not' : ''}Containing`;
}
getExpectedType() {
return 'object';
}
}
class StringContaining extends AsymmetricMatcher {
constructor(sample, inverse = false) {
if (!(0, _expectUtils.isA)('String', sample)) {
throw new Error('Expected is not a string');
}
super(sample, inverse);
}
asymmetricMatch(other) {
const result = (0, _expectUtils.isA)('String', other) && other.includes(this.sample);
return this.inverse ? !result : result;
}
toString() {
return `String${this.inverse ? 'Not' : ''}Containing`;
}
getExpectedType() {
return 'string';
}
}
class StringMatching extends AsymmetricMatcher {
constructor(sample, inverse = false) {
if (!(0, _expectUtils.isA)('String', sample) && !(0, _expectUtils.isA)('RegExp', sample)) {
throw new Error('Expected is not a String or a RegExp');
}
super(new RegExp(sample), inverse);
}
asymmetricMatch(other) {
const result = (0, _expectUtils.isA)('String', other) && this.sample.test(other);
return this.inverse ? !result : result;
}
toString() {
return `String${this.inverse ? 'Not' : ''}Matching`;
}
getExpectedType() {
return 'string';
}
}
class CloseTo extends AsymmetricMatcher {
precision;
constructor(sample, precision = 2, inverse = false) {
if (!(0, _expectUtils.isA)('Number', sample)) {
throw new Error('Expected is not a Number');
}
if (!(0, _expectUtils.isA)('Number', precision)) {
throw new Error('Precision is not a Number');
}
super(sample);
this.inverse = inverse;
this.precision = precision;
}
asymmetricMatch(other) {
if (!(0, _expectUtils.isA)('Number', other)) {
return false;
}
let result = false;
if (other === Number.POSITIVE_INFINITY && this.sample === Number.POSITIVE_INFINITY) {
result = true; // Infinity - Infinity is NaN
} else if (other === Number.NEGATIVE_INFINITY && this.sample === Number.NEGATIVE_INFINITY) {
result = true; // -Infinity - -Infinity is NaN
} else {
result = Math.abs(this.sample - other) < Math.pow(10, -this.precision) / 2;
}
return this.inverse ? !result : result;
}
toString() {
return `Number${this.inverse ? 'Not' : ''}CloseTo`;
}
getExpectedType() {
return 'number';
}
toAsymmetricMatcher() {
return [this.toString(), this.sample, `(${(0, _jestUtil.pluralize)('digit', this.precision)})`].join(' ');
}
}
const any = expectedObject => new Any(expectedObject);
exports.any = any;
const anything = () => new Anything();
exports.anything = anything;
const arrayContaining = sample => new ArrayContaining(sample);
exports.arrayContaining = arrayContaining;
const arrayNotContaining = sample => new ArrayContaining(sample, true);
exports.arrayNotContaining = arrayNotContaining;
const arrayOf = sample => new ArrayOf(sample);
exports.arrayOf = arrayOf;
const notArrayOf = sample => new ArrayOf(sample, true);
exports.notArrayOf = notArrayOf;
const objectContaining = sample => new ObjectContaining(sample);
exports.objectContaining = objectContaining;
const objectNotContaining = sample => new ObjectContaining(sample, true);
exports.objectNotContaining = objectNotContaining;
const stringContaining = expected => new StringContaining(expected);
exports.stringContaining = stringContaining;
const stringNotContaining = expected => new StringContaining(expected, true);
exports.stringNotContaining = stringNotContaining;
const stringMatching = expected => new StringMatching(expected);
exports.stringMatching = stringMatching;
const stringNotMatching = expected => new StringMatching(expected, true);
exports.stringNotMatching = stringNotMatching;
const closeTo = (expected, precision) => new CloseTo(expected, precision);
exports.closeTo = closeTo;
const notCloseTo = (expected, precision) => new CloseTo(expected, precision, true);
exports.notCloseTo = notCloseTo;
/***/ }),
/***/ "./src/extractExpectedAssertionsErrors.ts":
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
Object.defineProperty(exports, "__esModule", ({
value: true
}));
exports["default"] = void 0;
var _jestMatcherUtils = require("jest-matcher-utils");
var _jestMatchersObject = __webpack_require__("./src/jestMatchersObject.ts");
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
const resetAssertionsLocalState = () => {
(0, _jestMatchersObject.setState)({
assertionCalls: 0,
expectedAssertionsNumber: null,
isExpectingAssertions: false,
numPassingAsserts: 0
});
};
// Create and format all errors related to the mismatched number of `expect`
// calls and reset the matcher's state.
const extractExpectedAssertionsErrors = () => {
const result = [];
const {
assertionCalls,
expectedAssertionsNumber,
expectedAssertionsNumberError,
isExpectingAssertions,
isExpectingAssertionsError
} = (0, _jestMatchersObject.getState)();
resetAssertionsLocalState();
if (typeof expectedAssertionsNumber === 'number' && assertionCalls !== expectedAssertionsNumber) {
const numOfAssertionsExpected = (0, _jestMatcherUtils.EXPECTED_COLOR)((0, _jestMatcherUtils.pluralize)('assertion', expectedAssertionsNumber));
expectedAssertionsNumberError.message = `${(0, _jestMatcherUtils.matcherHint)('.assertions', '', expectedAssertionsNumber.toString(), {
isDirectExpectCall: true
})}\n\n` + `Expected ${numOfAssertionsExpected} to be called but received ${(0, _jestMatcherUtils.RECEIVED_COLOR)((0, _jestMatcherUtils.pluralize)('assertion call', assertionCalls || 0))}.`;
result.push({
actual: assertionCalls.toString(),
error: expectedAssertionsNumberError,
expected: expectedAssertionsNumber.toString()
});
}
if (isExpectingAssertions && assertionCalls === 0) {
const expected = (0, _jestMatcherUtils.EXPECTED_COLOR)('at least one assertion');
const received = (0, _jestMatcherUtils.RECEIVED_COLOR)('received none');
isExpectingAssertionsError.message = `${(0, _jestMatcherUtils.matcherHint)('.hasAssertions', '', '', {
isDirectExpectCall: true
})}\n\nExpected ${expected} to be called but ${received}.`;
result.push({
actual: 'none',
error: isExpectingAssertionsError,
expected: 'at least one'
});
}
return result;
};
var _default = exports["default"] = extractExpectedAssertionsErrors;
/***/ }),
/***/ "./src/jestMatchersObject.ts":
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
Object.defineProperty(exports, "__esModule", ({
value: true
}));
exports.setState = exports.setMatchers = exports.getState = exports.getMatchers = exports.getCustomEqualityTesters = exports.addCustomEqualityTesters = exports.INTERNAL_MATCHER_FLAG = void 0;
var _getType = require("@jest/get-type");
var _asymmetricMatchers = __webpack_require__("./src/asymmetricMatchers.ts");
var Symbol = globalThis['jest-symbol-do-not-touch'] || globalThis.Symbol;
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
// Global matchers object holds the list of available matchers and
// the state, that can hold matcher specific values that change over time.
const JEST_MATCHERS_OBJECT = Symbol.for('$$jest-matchers-object');
// Notes a built-in/internal Jest matcher.
// Jest may override the stack trace of Errors thrown by internal matchers.
const INTERNAL_MATCHER_FLAG = exports.INTERNAL_MATCHER_FLAG = Symbol.for('$$jest-internal-matcher');
if (!Object.prototype.hasOwnProperty.call(globalThis, JEST_MATCHERS_OBJECT)) {
const defaultState = {
assertionCalls: 0,
expectedAssertionsNumber: null,
isExpectingAssertions: false,
numPassingAsserts: 0,
suppressedErrors: [] // errors that are not thrown immediately.
};
Object.defineProperty(globalThis, JEST_MATCHERS_OBJECT, {
value: {
customEqualityTesters: [],
matchers: Object.create(null),
state: defaultState
}
});
}
const getState = () => globalThis[JEST_MATCHERS_OBJECT].state;
exports.getState = getState;
const setState = state => {
Object.assign(globalThis[JEST_MATCHERS_OBJECT].state, state);
};
exports.setState = setState;
const getMatchers = () => globalThis[JEST_MATCHERS_OBJECT].matchers;
exports.getMatchers = getMatchers;
const setMatchers = (matchers, isInternal, expect) => {
for (const key of Object.keys(matchers)) {
const matcher = matchers[key];
if (typeof matcher !== 'function') {
throw new TypeError(`expect.extend: \`${key}\` is not a valid matcher. Must be a function, is "${(0, _getType.getType)(matcher)}"`);
}
Object.defineProperty(matcher, INTERNAL_MATCHER_FLAG, {
value: isInternal
});
if (!isInternal) {
// expect is defined
class CustomMatcher extends _asymmetricMatchers.AsymmetricMatcher {
constructor(inverse = false, ...sample) {
super(sample, inverse);
}
asymmetricMatch(other) {
const {
pass
} = matcher.call(this.getMatcherContext(), other, ...this.sample);
return this.inverse ? !pass : pass;
}
toString() {
return `${this.inverse ? 'not.' : ''}${key}`;
}
getExpectedType() {
return 'any';
}
toAsymmetricMatcher() {
return `${this.toString()}<${this.sample.map(String).join(', ')}>`;
}
}
Object.defineProperty(expect, key, {
configurable: true,
enumerable: true,
value: (...sample) => new CustomMatcher(false, ...sample),
writable: true
});
Object.defineProperty(expect.not, key, {
configurable: true,
enumerable: true,
value: (...sample) => new CustomMatcher(true, ...sample),
writable: true
});
}
}
Object.assign(globalThis[JEST_MATCHERS_OBJECT].matchers, matchers);
};
exports.setMatchers = setMatchers;
const getCustomEqualityTesters = () => globalThis[JEST_MATCHERS_OBJECT].customEqualityTesters;
exports.getCustomEqualityTesters = getCustomEqualityTesters;
const addCustomEqualityTesters = newTesters => {
if (!Array.isArray(newTesters)) {
throw new TypeError(`expect.customEqualityTesters: Must be set to an array of Testers. Was given "${(0, _getType.getType)(newTesters)}"`);
}
globalThis[JEST_MATCHERS_OBJECT].customEqualityTesters.push(...newTesters);
};
exports.addCustomEqualityTesters = addCustomEqualityTesters;
/***/ }),
/***/ "./src/matchers.ts":
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
Object.defineProperty(exports, "__esModule", ({
value: true
}));
exports["default"] = void 0;
var _expectUtils = require("@jest/expect-utils");
var _getType = require("@jest/get-type");
var _jestMatcherUtils = require("jest-matcher-utils");
var _print = __webpack_require__("./src/print.ts");
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
// Omit colon and one or more spaces, so can call getLabelPrinter.
const EXPECTED_LABEL = 'Expected';
const RECEIVED_LABEL = 'Received';
const EXPECTED_VALUE_LABEL = 'Expected value';
const RECEIVED_VALUE_LABEL = 'Received value';
// The optional property of matcher context is true if undefined.
const isExpand = expand => expand !== false;
const toStrictEqualTesters = [_expectUtils.iterableEquality, _expectUtils.typeEquality, _expectUtils.sparseArrayEquality, _expectUtils.arrayBufferEquality];
const matchers = {
toBe(received, expected) {
const matcherName = 'toBe';
const options = {
comment: 'Object.is equality',
isNot: this.isNot,
promise: this.promise
};
const pass = Object.is(received, expected);
const message = pass ? () =>
// eslint-disable-next-line prefer-template
(0, _jestMatcherUtils.matcherHint)(matcherName, undefined, undefined, options) + '\n\n' + `Expected: not ${(0, _jestMatcherUtils.printExpected)(expected)}` : () => {
const expectedType = (0, _getType.getType)(expected);
let deepEqualityName = null;
if (expectedType !== 'map' && expectedType !== 'set') {
// If deep equality passes when referential identity fails,
// but exclude map and set until review of their equality logic.
if ((0, _expectUtils.equals)(received, expected, [...this.customTesters, ...toStrictEqualTesters], true)) {
deepEqualityName = 'toStrictEqual';
} else if ((0, _expectUtils.equals)(received, expected, [...this.customTesters, _expectUtils.iterableEquality])) {
deepEqualityName = 'toEqual';
}
}
return (
// eslint-disable-next-line prefer-template
(0, _jestMatcherUtils.matcherHint)(matcherName, undefined, undefined, options) + '\n\n' + (deepEqualityName === null ? '' : `${(0, _jestMatcherUtils.DIM_COLOR)(`If it should pass with deep equality, replace "${matcherName}" with "${deepEqualityName}"`)}\n\n`) + (0, _jestMatcherUtils.printDiffOrStringify)(expected, received, EXPECTED_LABEL, RECEIVED_LABEL, isExpand(this.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: received,
expected,
message,
name: matcherName,
pass
};
},
toBeCloseTo(received, expected, precision = 2) {
const matcherName = 'toBeCloseTo';
const secondArgument = arguments.length === 3 ? 'precision' : undefined;
const isNot = this.isNot;
const options = {
isNot,
promise: this.promise,
secondArgument,
secondArgumentColor: arg => arg
};
if (typeof expected !== 'number') {
throw new TypeError((0, _jestMatcherUtils.matcherErrorMessage)((0, _jestMatcherUtils.matcherHint)(matcherName, undefined, undefined, options), `${(0, _jestMatcherUtils.EXPECTED_COLOR)('expected')} value must be a number`, (0, _jestMatcherUtils.printWithType)('Expected', expected, _jestMatcherUtils.printExpected)));
}
if (typeof received !== 'number') {
throw new TypeError((0, _jestMatcherUtils.matcherErrorMessage)((0, _jestMatcherUtils.matcherHint)(matcherName, undefined, undefined, options), `${(0, _jestMatcherUtils.RECEIVED_COLOR)('received')} value must be a number`, (0, _jestMatcherUtils.printWithType)('Received', received, _jestMatcherUtils.printReceived)));
}
let pass = false;
let expectedDiff = 0;
let receivedDiff = 0;
if (received === Number.POSITIVE_INFINITY && expected === Number.POSITIVE_INFINITY) {
pass = true; // Infinity - Infinity is NaN
} else if (received === Number.NEGATIVE_INFINITY && expected === Number.NEGATIVE_INFINITY) {
pass = true; // -Infinity - -Infinity is NaN
} else {
expectedDiff = Math.pow(10, -precision) / 2;
receivedDiff = Math.abs(expected - received);
pass = receivedDiff < expectedDiff;
}
const message = pass ? () =>
// eslint-disable-next-line prefer-template
(0, _jestMatcherUtils.matcherHint)(matcherName, undefined, undefined, options) + '\n\n' + `Expected: not ${(0, _jestMatcherUtils.printExpected)(expected)}\n` + (receivedDiff === 0 ? '' : `Received: ${(0, _jestMatcherUtils.printReceived)(received)}\n` + `\n${(0, _print.printCloseTo)(receivedDiff, expectedDiff, precision, isNot)}`) : () =>
// eslint-disable-next-line prefer-template
(0, _jestMatcherUtils.matcherHint)(matcherName, undefined, undefined, options) + '\n\n' + `Expected: ${(0, _jestMatcherUtils.printExpected)(expected)}\n` + `Received: ${(0, _jestMatcherUtils.printReceived)(received)}\n` + '\n' + (0, _print.printCloseTo)(receivedDiff, expectedDiff, precision, isNot);
return {
message,
pass
};
},
toBeDefined(received, expected) {
const matcherName = 'toBeDefined';
const options = {
isNot: this.isNot,
promise: this.promise
};
(0, _jestMatcherUtils.ensureNoExpected)(expected, matcherName, options);
const pass = received !== void 0;
const message = () =>
// eslint-disable-next-line prefer-template
(0, _jestMatcherUtils.matcherHint)(matcherName, undefined, '', options) + '\n\n' + `Received: ${(0, _jestMatcherUtils.printReceived)(received)}`;
return {
message,
pass
};
},
toBeFalsy(received, expected) {
const matcherName = 'toBeFalsy';
const options = {
isNot: this.isNot,
promise: this.promise
};
(0, _jestMatcherUtils.ensureNoExpected)(expected, matcherName, options);
const pass = !received;
const message = () =>
// eslint-disable-next-line prefer-template
(0, _jestMatcherUtils.matcherHint)(matcherName, undefined, '', options) + '\n\n' + `Received: ${(0, _jestMatcherUtils.printReceived)(received)}`;
return {
message,
pass
};
},
toBeGreaterThan(received, expected) {
const matcherName = 'toBeGreaterThan';
const isNot = this.isNot;
const options = {
isNot,
promise: this.promise
};
(0, _jestMatcherUtils.ensureNumbers)(received, expected, matcherName, options);
const pass = received > expected;
const message = () =>
// eslint-disable-next-line prefer-template
(0, _jestMatcherUtils.matcherHint)(matcherName, undefined, undefined, options) + '\n\n' + `Expected:${isNot ? ' not' : ''} > ${(0, _jestMatcherUtils.printExpected)(expected)}\n` + `Received:${isNot ? ' ' : ''} ${(0, _jestMatcherUtils.printReceived)(received)}`;
return {
message,
pass
};
},
toBeGreaterThanOrEqual(received, expected) {
const matcherName = 'toBeGreaterThanOrEqual';
const isNot = this.isNot;
const options = {
isNot,
promise: this.promise
};
(0, _jestMatcherUtils.ensureNumbers)(received, expected, matcherName, options);
const pass = received >= expected;
const message = () =>
// eslint-disable-next-line prefer-template
(0, _jestMatcherUtils.matcherHint)(matcherName, undefined, undefined, options) + '\n\n' + `Expected:${isNot ? ' not' : ''} >= ${(0, _jestMatcherUtils.printExpected)(expected)}\n` + `Received:${isNot ? ' ' : ''} ${(0, _jestMatcherUtils.printReceived)(received)}`;
return {
message,
pass
};
},
toBeInstanceOf(received, expected) {
const matcherName = 'toBeInstanceOf';
const options = {
isNot: this.isNot,
promise: this.promise
};
if (typeof expected !== 'function') {
throw new TypeError((0, _jestMatcherUtils.matcherErrorMessage)((0, _jestMatcherUtils.matcherHint)(matcherName, undefined, undefined, options), `${(0, _jestMatcherUtils.EXPECTED_COLOR)('expected')} value must be a function`, (0, _jestMatcherUtils.printWithType)('Expected', expected, _jestMatcherUtils.printExpected)));
}
const pass = received instanceof expected;
const message = pass ? () =>
// eslint-disable-next-line prefer-template
(0, _jestMatcherUtils.matcherHint)(matcherName, undefined, undefined, options) + '\n\n' + (0, _print.printExpectedConstructorNameNot)('Expected constructor', expected) + (typeof received.constructor === 'function' && received.constructor !== expected ? (0, _print.printReceivedConstructorNameNot)('Received constructor', received.constructor, expected) : '') : () =>
// eslint-disable-next-line prefer-template
(0, _jestMatcherUtils.matcherHint)(matcherName, undefined, undefined, options) + '\n\n' + (0, _print.printExpectedConstructorName)('Expected constructor', expected) + ((0, _getType.isPrimitive)(received) || Object.getPrototypeOf(received) === null ? `\nReceived value has no prototype\nReceived value: ${(0, _jestMatcherUtils.printReceived)(received)}` : typeof received.constructor === 'function' ? (0, _print.printReceivedConstructorName)('Received constructor', received.constructor) : `\nReceived value: ${(0, _jestMatcherUtils.printReceived)(received)}`);
return {
message,
pass
};
},
toBeLessThan(received, expected) {
const matcherName = 'toBeLessThan';
const isNot = this.isNot;
const options = {
isNot,
promise: this.promise
};
(0, _jestMatcherUtils.ensureNumbers)(received, expected, matcherName, options);
const pass = received < expected;
const message = () =>
// eslint-disable-next-line prefer-template
(0, _jestMatcherUtils.matcherHint)(matcherName, undefined, undefined, options) + '\n\n' + `Expected:${isNot ? ' not' : ''} < ${(0, _jestMatcherUtils.printExpected)(expected)}\n` + `Received:${isNot ? ' ' : ''} ${(0, _jestMatcherUtils.printReceived)(received)}`;
return {
message,
pass
};
},
toBeLessThanOrEqual(received, expected) {
const matcherName = 'toBeLessThanOrEqual';
const isNot = this.isNot;
const options = {
isNot,
promise: this.promise
};
(0, _jestMatcherUtils.ensureNumbers)(received, expected, matcherName, options);
const pass = received <= expected;
const message = () =>
// eslint-disable-next-line prefer-template
(0, _jestMatcherUtils.matcherHint)(matcherName, undefined, undefined, options) + '\n\n' + `Expected:${isNot ? ' not' : ''} <= ${(0, _jestMatcherUtils.printExpected)(expected)}\n` + `Received:${isNot ? ' ' : ''} ${(0, _jestMatcherUtils.printReceived)(received)}`;
return {
message,
pass
};
},
toBeNaN(received, expected) {
const matcherName = 'toBeNaN';
const options = {
isNot: this.isNot,
promise: this.promise
};
(0, _jestMatcherUtils.ensureNoExpected)(expected, matcherName, options);
const pass = Number.isNaN(received);
const message = () =>
// eslint-disable-next-line prefer-template
(0, _jestMatcherUtils.matcherHint)(matcherName, undefined, '', options) + '\n\n' + `Received: ${(0, _jestMatcherUtils.printReceived)(received)}`;
return {
message,
pass
};
},
toBeNull(received, expected) {
const matcherName = 'toBeNull';
const options = {
isNot: this.isNot,
promise: this.promise
};
(0, _jestMatcherUtils.ensureNoExpected)(expected, matcherName, options);
const pass = received === null;
const message = () =>
// eslint-disable-next-line prefer-template
(0, _jestMatcherUtils.matcherHint)(matcherName, undefined, '', options) + '\n\n' + `Received: ${(0, _jestMatcherUtils.printReceived)(received)}`;
return {
message,
pass
};
},
toBeTruthy(received, expected) {
const matcherName = 'toBeTruthy';
const options = {
isNot: this.isNot,
promise: this.promise
};
(0, _jestMatcherUtils.ensureNoExpected)(expected, matcherName, options);
const pass = !!received;
const message = () =>
// eslint-disable-next-line prefer-template
(0, _jestMatcherUtils.matcherHint)(matcherName, undefined, '', options) + '\n\n' + `Received: ${(0, _jestMatcherUtils.printReceived)(received)}`;
return {
message,
pass
};
},
toBeUndefined(received, expected) {
const matcherName = 'toBeUndefined';
const options = {
isNot: this.isNot,
promise: this.promise
};
(0, _jestMatcherUtils.ensureNoExpected)(expected, matcherName, options);
const pass = received === void 0;
const message = () =>
// eslint-disable-next-line prefer-template
(0, _jestMatcherUtils.matcherHint)(matcherName, undefined, '', options) + '\n\n' + `Received: ${(0, _jestMatcherUtils.printReceived)(received)}`;
return {
message,
pass
};
},
toContain(received, expected) {
const matcherName = 'toContain';
const isNot = this.isNot;
const options = {
comment: 'indexOf',
isNot,
promise: this.promise
};
if (received == null) {
throw new Error((0, _jestMatcherUtils.matcherErrorMessage)((0, _jestMatcherUtils.matcherHint)(matcherName, undefined, undefined, options), `${(0, _jestMatcherUtils.RECEIVED_COLOR)('received')} value must not be null nor undefined`, (0, _jestMatcherUtils.printWithType)('Received', received, _jestMatcherUtils.printReceived)));
}
if (typeof received === 'string') {
const wrongTypeErrorMessage = `${(0, _jestMatcherUtils.EXPECTED_COLOR)('expected')} value must be a string if ${(0, _jestMatcherUtils.RECEIVED_COLOR)('received')} value is a string`;
if (typeof expected !== 'string') {
throw new TypeError((0, _jestMatcherUtils.matcherErrorMessage)((0, _jestMatcherUtils.matcherHint)(matcherName, received, String(expected), options), wrongTypeErrorMessage,
// eslint-disable-next-line prefer-template
(0, _jestMatcherUtils.printWithType)('Expected', expected, _jestMatcherUtils.printExpected) + '\n' + (0, _jestMatcherUtils.printWithType)('Received', received, _jestMatcherUtils.printReceived)));
}
const index = received.indexOf(String(expected));
const pass = index !== -1;
const message = () => {
const labelExpected = `Expected ${typeof expected === 'string' ? 'substring' : 'value'}`;
const labelReceived = 'Received string';
const printLabel = (0, _jestMatcherUtils.getLabelPrinter)(labelExpected, labelReceived);
return (
// eslint-disable-next-line prefer-template
(0, _jestMatcherUtils.matcherHint)(matcherName, undefined, undefined, options) + '\n\n' + `${printLabel(labelExpected)}${isNot ? 'not ' : ''}${(0, _jestMatcherUtils.printExpected)(expected)}\n` + `${printLabel(labelReceived)}${isNot ? ' ' : ''}${isNot ? (0, _print.printReceivedStringContainExpectedSubstring)(received, index, String(expected).length) : (0, _jestMatcherUtils.printReceived)(received)}`
);
};
return {
message,
pass
};
}
const indexable = [...received];
const index = indexable.indexOf(expected);
const pass = index !== -1;
const message = () => {
const labelExpected = 'Expected value';
const labelReceived = `Received ${(0, _getType.getType)(received)}`;
const printLabel = (0, _jestMatcherUtils.getLabelPrinter)(labelExpected, labelReceived);
return (
// eslint-disable-next-line prefer-template
(0, _jestMatcherUtils.matcherHint)(matcherName, undefined, undefined, options) + '\n\n' + `${printLabel(labelExpected)}${isNot ? 'not ' : ''}${(0, _jestMatcherUtils.printExpected)(expected)}\n` + `${printLabel(labelReceived)}${isNot ? ' ' : ''}${isNot && Array.isArray(received) ? (0, _print.printReceivedArrayContainExpectedItem)(received, index) : (0, _jestMatcherUtils.printReceived)(received)}` + (!isNot && indexable.some(item => (0, _expectUtils.equals)(item, expected, [...this.customTesters, _expectUtils.iterableEquality])) ? `\n\n${_jestMatcherUtils.SUGGEST_TO_CONTAIN_EQUAL}` : '')
);
};
return {
message,
pass
};
},
toContainEqual(received, expected) {
const matcherName = 'toContainEqual';
const isNot = this.isNot;
const options = {
comment: 'deep equality',
isNot,
promise: this.promise
};
if (received == null) {
throw new Error((0, _jestMatcherUtils.matcherErrorMessage)((0, _jestMatcherUtils.matcherHint)(matcherName, undefined, undefined, options), `${(0, _jestMatcherUtils.RECEIVED_COLOR)('received')} value must not be null nor undefined`, (0, _jestMatcherUtils.printWithType)('Received', received, _jestMatcherUtils.printReceived)));
}
const index = [...received].findIndex(item => (0, _expectUtils.equals)(item, expected, [...this.customTesters, _expectUtils.iterableEquality]));
const pass = index !== -1;
const message = () => {
const labelExpected = 'Expected value';
const labelReceived = `Received ${(0, _getType.getType)(received)}`;
const printLabel = (0, _jestMatcherUtils.getLabelPrinter)(labelExpected, labelReceived);
return (
// eslint-disable-next-line prefer-template
(0, _jestMatcherUtils.matcherHint)(matcherName, undefined, undefined, options) + '\n\n' + `${printLabel(labelExpected)}${isNot ? 'not ' : ''}${(0, _jestMatcherUtils.printExpected)(expected)}\n` + `${printLabel(labelReceived)}${isNot ? ' ' : ''}${isNot && Array.isArray(received) ? (0, _print.printReceivedArrayContainExpectedItem)(received, index) : (0, _jestMatcherUtils.printReceived)(received)}`
);
};
return {
message,
pass
};
},
toEqual(received, expected) {
const matcherName = 'toEqual';
const options = {
comment: 'deep equality',
isNot: this.isNot,
promise: this.promise
};
const pass = (0, _expectUtils.equals)(received, expected, [...this.customTesters, _expectUtils.iterableEquality]);
const message = pass ? () =>
// eslint-disable-next-line prefer-template
(0, _jestMatcherUtils.matcherHint)(matcherName, undefined, undefined, options) + '\n\n' + `Expected: not ${(0, _jestMatcherUtils.printExpected)(expected)}\n` + ((0, _jestMatcherUtils.stringify)(expected) === (0, _jestMatcherUtils.stringify)(received) ? '' : `Received: ${(0, _jestMatcherUtils.printReceived)(received)}`) : () =>
// eslint-disable-next-line prefer-template
(0, _jestMatcherUtils.matcherHint)(matcherName, undefined, undefined, options) + '\n\n' + (0, _jestMatcherUtils.printDiffOrStringify)(expected, received, EXPECTED_LABEL, RECEIVED_LABEL, isExpand(this.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: received,
expected,
message,
name: matcherName,
pass
};
},
toHaveLength(received, expected) {
const matcherName = 'toHaveLength';
const isNot = this.isNot;
const options = {
isNot,
promise: this.promise
};
if (typeof received?.length !== 'number') {
throw new TypeError((0, _jestMatcherUtils.matcherErrorMessage)((0, _jestMatcherUtils.matcherHint)(matcherName, undefined, undefined, options), `${(0, _jestMatcherUtils.RECEIVED_COLOR)('received')} value must have a length property whose value must be a number`, (0, _jestMatcherUtils.printWithType)('Received', received, _jestMatcherUtils.printReceived)));
}
(0, _jestMatcherUtils.ensureExpectedIsNonNegativeInteger)(expected, matcherName, options);
const pass = received.length === expected;
const message = () => {
const labelExpected = 'Expected length';
const labelReceivedLength = 'Received length';
const labelReceivedValue = `Received ${(0, _getType.getType)(received)}`;
const printLabel = (0, _jestMatcherUtils.getLabelPrinter)(labelExpected, labelReceivedLength, labelReceivedValue);
return (
// eslint-disable-next-line prefer-template
(0, _jestMatcherUtils.matcherHint)(matcherName, undefined, undefined, options) + '\n\n' + `${printLabel(labelExpected)}${isNot ? 'not ' : ''}${(0, _jestMatcherUtils.printExpected)(expected)}\n` + (isNot ? '' : `${printLabel(labelReceivedLength)}${(0, _jestMatcherUtils.printReceived)(received.length)}\n`) + `${printLabel(labelReceivedValue)}${isNot ? ' ' : ''}${(0, _jestMatcherUtils.printReceived)(received)}`
);
};
return {
message,
pass
};
},
toHaveProperty(received, expectedPath, expectedValue) {
const matcherName = 'toHaveProperty';
const expectedArgument = 'path';
const hasValue = arguments.length === 3;
const options = {
isNot: this.isNot,
promise: this.promise,
secondArgument: hasValue ? 'value' : ''
};
if (received === null || received === undefined) {
throw new Error((0, _jestMatcherUtils.matcherErrorMessage)((0, _jestMatcherUtils.matcherHint)(matcherName, undefined, expectedArgument, options), `${(0, _jestMatcherUtils.RECEIVED_COLOR)('received')} value must not be null nor undefined`, (0, _jestMatcherUtils.printWithType)('Received', received, _jestMatcherUtils.printReceived)));
}
const expectedPathType = (0, _getType.getType)(expectedPath);
if (expectedPathType !== 'string' && expectedPathType !== 'array') {
throw new Error((0, _jestMatcherUtils.matcherErrorMessage)((0, _jestMatcherUtils.matcherHint)(matcherName, undefined, expectedArgument, options), `${(0, _jestMatcherUtils.EXPECTED_COLOR)('expected')} path must be a string or array`, (0, _jestMatcherUtils.printWithType)('Expected', expectedPath, _jestMatcherUtils.printExpected)));
}
const expectedPathLength = typeof expectedPath === 'string' ? (0, _expectUtils.pathAsArray)(expectedPath).length : expectedPath.length;
if (expectedPathType === 'array' && expectedPathLength === 0) {
throw new Error((0, _jestMatcherUtils.matcherErrorMessage)((0, _jestMatcherUtils.matcherHint)(matcherName, undefined, expectedArgument, options), `${(0, _jestMatcherUtils.EXPECTED_COLOR)('expected')} path must not be an empty array`, (0, _jestMatcherUtils.printWithType)('Expected', expectedPath, _jestMatcherUtils.printExpected)));
}
const result = (0, _expectUtils.getPath)(received, expectedPath);
const {
lastTraversedObject,
endPropIsDefined,
hasEndProp,
value
} = result;
const receivedPath = result.traversedPath;
const hasCompletePath = receivedPath.length === expectedPathLength;
const receivedValue = hasCompletePath ? result.value : lastTraversedObject;
const pass = hasValue && endPropIsDefined ? (0, _expectUtils.equals)(value, expectedValue, [...this.customTesters, _expectUtils.iterableEquality]) : Boolean(hasEndProp);
const message = pass ? () =>
// eslint-disable-next-line prefer-template
(0, _jestMatcherUtils.matcherHint)(matcherName, undefined, expectedArgument, options) + '\n\n' + (hasValue ? `Expected path: ${(0, _jestMatcherUtils.printExpected)(expectedPath)}\n\n` + `Expected value: not ${(0, _jestMatcherUtils.printExpected)(expectedValue)}${(0, _jestMatcherUtils.stringify)(expectedValue) === (0, _jestMatcherUtils.stringify)(receivedValue) ? '' : `\nReceived value: ${(0, _jestMatcherUtils.printReceived)(receivedValue)}`}` : `Expected path: not ${(0, _jestMatcherUtils.printExpected)(expectedPath)}\n\n` + `Received value: ${(0, _jestMatcherUtils.printReceived)(receivedValue)}`) : () =>
// eslint-disable-next-line prefer-template
(0, _jestMatcherUtils.matcherHint)(matcherName, undefined, expectedArgument, options) + '\n\n' + `Expected path: ${(0, _jestMatcherUtils.printExpected)(expectedPath)}\n` + (hasCompletePath ? `\n${(0, _jestMatcherUtils.printDiffOrStringify)(expectedValue, receivedValue, EXPECTED_VALUE_LABEL, RECEIVED_VALUE_LABEL, isExpand(this.expand))}` : `Received path: ${(0, _jestMatcherUtils.printReceived)(expectedPathType === 'array' || receivedPath.length === 0 ? receivedPath : receivedPath.join('.'))}\n\n${hasValue ? `Expected value: ${(0, _jestMatcherUtils.printExpected)(expectedValue)}\n` : ''}Received value: ${(0, _jestMatcherUtils.printReceived)(receivedValue)}`);
return {
message,
pass
};
},
toMatch(received, expected) {
const matcherName = 'toMatch';
const options = {
isNot: this.isNot,
promise: this.promise
};
if (typeof received !== 'string') {
throw new TypeError((0, _jestMatcherUtils.matcherErrorMessage)((0, _jestMatcherUtils.matcherHint)(matcherName, undefined, undefined, options), `${(0, _jestMatcherUtils.RECEIVED_COLOR)('received')} value must be a string`, (0, _jestMatcherUtils.printWithType)('Received', received, _jestMatcherUtils.printReceived)));
}
if (!(typeof expected === 'string') && !(expected && typeof expected.test === 'function')) {
throw new Error((0, _jestMatcherUtils.matcherErrorMessage)((0, _jestMatcherUtils.matcherHint)(matcherName, undefined, undefined, options), `${(0, _jestMatcherUtils.EXPECTED_COLOR)('expected')} value must be a string or regular expression`, (0, _jestMatcherUtils.printWithType)('Expected', expected, _jestMatcherUtils.printExpected)));
}
const pass = typeof expected === 'string' ? received.includes(expected) : new RegExp(expected).test(received);
const message = pass ? () => typeof expected === 'string' ?
// eslint-disable-next-line prefer-template
(0, _jestMatcherUtils.matcherHint)(matcherName, undefined, undefined, options) + '\n\n' + `Expected substring: not ${(0, _jestMatcherUtils.printExpected)(expected)}\n` + `Received string: ${(0, _print.printReceivedStringContainExpectedSubstring)(received, received.indexOf(expected), expected.length)}` :
// eslint-disable-next-line prefer-template
(0, _jestMatcherUtils.matcherHint)(matcherName, undefined, undefined, options) + '\n\n' + `Expected pattern: not ${(0, _jestMatcherUtils.printExpected)(expected)}\n` + `Received string: ${(0, _print.printReceivedStringContainExpectedResult)(received, typeof expected.exec === 'function' ? expected.exec(received) : null)}` : () => {
const labelExpected = `Expected ${typeof expected === 'string' ? 'substring' : 'pattern'}`;
const labelReceived = 'Received string';
const printLabel = (0, _jestMatcherUtils.getLabelPrinter)(labelExpected, labelReceived);
return (
// eslint-disable-next-line prefer-template
(0, _jestMatcherUtils.matcherHint)(matcherName, undefined, undefined, options) + '\n\n' + `${printLabel(labelExpected)}${(0, _jestMatcherUtils.printExpected)(expected)}\n` + `${printLabel(labelReceived)}${(0, _jestMatcherUtils.printReceived)(received)}`
);
};
return {
message,
pass
};
},
toMatchObject(received, expected) {
const matcherName = 'toMatchObject';
const options = {
isNot: this.isNot,
promise: this.promise
};
if (typeof received !== 'object' || received === null) {
throw new Error((0, _jestMatcherUtils.matcherErrorMessage)((0, _jestMatcherUtils.matcherHint)(matcherName, undefined, undefined, options), `${(0, _jestMatcherUtils.RECEIVED_COLOR)('received')} value must be a non-null object`, (0, _jestMatcherUtils.printWithType)('Received', received, _jestMatcherUtils.printReceived)));
}
if (typeof expected !== 'object' || expected === null) {
throw new Error((0, _jestMatcherUtils.matcherErrorMessage)((0, _jestMatcherUtils.matcherHint)(matcherName, undefined, undefined, options), `${(0, _jestMatcherUtils.EXPECTED_COLOR)('expected')} value must be a non-null object`, (0, _jestMatcherUtils.printWithType)('Expected', expected, _jestMatcherUtils.printExpected)));
}
const pass = (0, _expectUtils.equals)(received, expected, [...this.customTesters, _expectUtils.iterableEquality, _expectUtils.subsetEquality]);
const message = pass ? () =>
// eslint-disable-next-line prefer-template
(0, _jestMatcherUtils.matcherHint)(matcherName, undefined, undefined, options) + '\n\n' + `Expected: not ${(0, _jestMatcherUtils.printExpected)(expected)}` + ((0, _jestMatcherUtils.stringify)(expected) === (0, _jestMatcherUtils.stringify)(received) ? '' : `\nReceived: ${(0, _jestMatcherUtils.printReceived)(received)}`) : () =>
// eslint-disable-next-line prefer-template
(0, _jestMatcherUtils.matcherHint)(matcherName, undefined, undefined, options) + '\n\n' + (0, _jestMatcherUtils.printDiffOrStringify)(expected, (0, _expectUtils.getObjectSubset)(received, expected, this.customTesters), EXPECTED_LABEL, RECEIVED_LABEL, isExpand(this.expand));
return {
message,
pass
};
},
toStrictEqual(received, expected) {
const matcherName = 'toStrictEqual';
const options = {
comment: 'deep equality',
isNot: this.isNot,
promise: this.promise
};
const pass = (0, _expectUtils.equals)(received, expected, [...this.customTesters, ...toStrictEqualTesters], true);
const message = pass ? () =>
// eslint-disable-next-line prefer-template
(0, _jestMatcherUtils.matcherHint)(matcherName, undefined, undefined, options) + '\n\n' + `Expected: not ${(0, _jestMatcherUtils.printExpected)(expected)}\n` + ((0, _jestMatcherUtils.stringify)(expected) === (0, _jestMatcherUtils.stringify)(received) ? '' : `Received: ${(0, _jestMatcherUtils.printReceived)(received)}`) : () =>
// eslint-disable-next-line prefer-template
(0, _jestMatcherUtils.matcherHint)(matcherName, undefined, undefined, options) + '\n\n' + (0, _jestMatcherUtils.printDiffOrStringify)(expected, received, EXPECTED_LABEL, RECEIVED_LABEL, isExpand(this.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: received,
expected,
message,
name: matcherName,
pass
};
}
};
var _default = exports["default"] = matchers;
/***/ }),
/***/ "./src/print.ts":
/***/ ((__unused_webpack_module, exports) => {
Object.defineProperty(exports, "__esModule", ({
value: true
}));
exports.printReceivedStringContainExpectedSubstring = exports.printReceivedStringContainExpectedResult = exports.printReceivedConstructorNameNot = exports.printReceivedConstructorName = exports.printReceivedArrayContainExpectedItem = exports.printExpectedConstructorNameNot = exports.printExpectedConstructorName = exports.printCloseTo = void 0;
var _jestMatcherUtils = require("jest-matcher-utils");
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
// Format substring but do not enclose in double quote marks.
// The replacement is compati