| | 'use strict'; |
| |
|
| | Object.defineProperty(exports, '__esModule', { |
| | value: true |
| | }); |
| | exports.arrayBufferEquality = void 0; |
| | exports.emptyObject = emptyObject; |
| | exports.typeEquality = |
| | exports.subsetEquality = |
| | exports.sparseArrayEquality = |
| | exports.pathAsArray = |
| | exports.partition = |
| | exports.iterableEquality = |
| | exports.isOneline = |
| | exports.isError = |
| | exports.getPath = |
| | exports.getObjectSubset = |
| | exports.getObjectKeys = |
| | void 0; |
| | var _jestGetType = require('jest-get-type'); |
| | var _immutableUtils = require('./immutableUtils'); |
| | var _jasmineUtils = require('./jasmineUtils'); |
| | var Symbol = globalThis['jest-symbol-do-not-touch'] || globalThis.Symbol; |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | const hasPropertyInObject = (object, key) => { |
| | const shouldTerminate = |
| | !object || typeof object !== 'object' || object === Object.prototype; |
| | if (shouldTerminate) { |
| | return false; |
| | } |
| | return ( |
| | Object.prototype.hasOwnProperty.call(object, key) || |
| | hasPropertyInObject(Object.getPrototypeOf(object), key) |
| | ); |
| | }; |
| |
|
| | |
| | |
| | |
| | |
| | const getObjectKeys = object => [ |
| | ...Object.keys(object), |
| | ...Object.getOwnPropertySymbols(object) |
| | ]; |
| | exports.getObjectKeys = getObjectKeys; |
| | const getPath = (object, propertyPath) => { |
| | if (!Array.isArray(propertyPath)) { |
| | propertyPath = pathAsArray(propertyPath); |
| | } |
| | if (propertyPath.length) { |
| | const lastProp = propertyPath.length === 1; |
| | const prop = propertyPath[0]; |
| | const newObject = object[prop]; |
| | if (!lastProp && (newObject === null || newObject === undefined)) { |
| | |
| | |
| | |
| | return { |
| | hasEndProp: false, |
| | lastTraversedObject: object, |
| | traversedPath: [] |
| | }; |
| | } |
| | const result = getPath(newObject, propertyPath.slice(1)); |
| | if (result.lastTraversedObject === null) { |
| | result.lastTraversedObject = object; |
| | } |
| | result.traversedPath.unshift(prop); |
| | if (lastProp) { |
| | |
| | |
| | |
| | result.endPropIsDefined = |
| | !(0, _jestGetType.isPrimitive)(object) && prop in object; |
| | result.hasEndProp = newObject !== undefined || result.endPropIsDefined; |
| | if (!result.hasEndProp) { |
| | result.traversedPath.shift(); |
| | } |
| | } |
| | return result; |
| | } |
| | return { |
| | lastTraversedObject: null, |
| | traversedPath: [], |
| | value: object |
| | }; |
| | }; |
| |
|
| | |
| | |
| | |
| | exports.getPath = getPath; |
| | const getObjectSubset = ( |
| | object, |
| | subset, |
| | customTesters = [], |
| | seenReferences = new WeakMap() |
| | ) => { |
| | |
| | if (Array.isArray(object)) { |
| | if (Array.isArray(subset) && subset.length === object.length) { |
| | |
| | return subset.map((sub, i) => |
| | getObjectSubset(object[i], sub, customTesters) |
| | ); |
| | } |
| | } else if (object instanceof Date) { |
| | return object; |
| | } else if (isObject(object) && isObject(subset)) { |
| | if ( |
| | (0, _jasmineUtils.equals)(object, subset, [ |
| | ...customTesters, |
| | iterableEquality, |
| | subsetEquality |
| | ]) |
| | ) { |
| | |
| | return subset; |
| | } |
| | const trimmed = {}; |
| | seenReferences.set(object, trimmed); |
| | getObjectKeys(object) |
| | .filter(key => hasPropertyInObject(subset, key)) |
| | .forEach(key => { |
| | trimmed[key] = seenReferences.has(object[key]) |
| | ? seenReferences.get(object[key]) |
| | : getObjectSubset( |
| | object[key], |
| | subset[key], |
| | customTesters, |
| | seenReferences |
| | ); |
| | }); |
| | if (getObjectKeys(trimmed).length > 0) { |
| | return trimmed; |
| | } |
| | } |
| | return object; |
| | }; |
| | exports.getObjectSubset = getObjectSubset; |
| | const IteratorSymbol = Symbol.iterator; |
| | const hasIterator = object => !!(object != null && object[IteratorSymbol]); |
| |
|
| | |
| | const iterableEquality = ( |
| | a, |
| | b, |
| | customTesters = [] , |
| | aStack = [], |
| | bStack = [] |
| | ) => { |
| | if ( |
| | typeof a !== 'object' || |
| | typeof b !== 'object' || |
| | Array.isArray(a) || |
| | Array.isArray(b) || |
| | !hasIterator(a) || |
| | !hasIterator(b) |
| | ) { |
| | return undefined; |
| | } |
| | if (a.constructor !== b.constructor) { |
| | return false; |
| | } |
| | let length = aStack.length; |
| | while (length--) { |
| | |
| | |
| | |
| | |
| | if (aStack[length] === a) { |
| | return bStack[length] === b; |
| | } |
| | } |
| | aStack.push(a); |
| | bStack.push(b); |
| | const iterableEqualityWithStack = (a, b) => |
| | iterableEquality( |
| | a, |
| | b, |
| | [...filteredCustomTesters], |
| | [...aStack], |
| | [...bStack] |
| | ); |
| |
|
| | |
| | |
| | const filteredCustomTesters = [ |
| | ...customTesters.filter(t => t !== iterableEquality), |
| | iterableEqualityWithStack |
| | ]; |
| | if (a.size !== undefined) { |
| | if (a.size !== b.size) { |
| | return false; |
| | } else if ( |
| | (0, _jasmineUtils.isA)('Set', a) || |
| | (0, _immutableUtils.isImmutableUnorderedSet)(a) |
| | ) { |
| | let allFound = true; |
| | for (const aValue of a) { |
| | if (!b.has(aValue)) { |
| | let has = false; |
| | for (const bValue of b) { |
| | const isEqual = (0, _jasmineUtils.equals)( |
| | aValue, |
| | bValue, |
| | filteredCustomTesters |
| | ); |
| | if (isEqual === true) { |
| | has = true; |
| | } |
| | } |
| | if (has === false) { |
| | allFound = false; |
| | break; |
| | } |
| | } |
| | } |
| | |
| | aStack.pop(); |
| | bStack.pop(); |
| | return allFound; |
| | } else if ( |
| | (0, _jasmineUtils.isA)('Map', a) || |
| | (0, _immutableUtils.isImmutableUnorderedKeyed)(a) |
| | ) { |
| | let allFound = true; |
| | for (const aEntry of a) { |
| | if ( |
| | !b.has(aEntry[0]) || |
| | !(0, _jasmineUtils.equals)( |
| | aEntry[1], |
| | b.get(aEntry[0]), |
| | filteredCustomTesters |
| | ) |
| | ) { |
| | let has = false; |
| | for (const bEntry of b) { |
| | const matchedKey = (0, _jasmineUtils.equals)( |
| | aEntry[0], |
| | bEntry[0], |
| | filteredCustomTesters |
| | ); |
| | let matchedValue = false; |
| | if (matchedKey === true) { |
| | matchedValue = (0, _jasmineUtils.equals)( |
| | aEntry[1], |
| | bEntry[1], |
| | filteredCustomTesters |
| | ); |
| | } |
| | if (matchedValue === true) { |
| | has = true; |
| | } |
| | } |
| | if (has === false) { |
| | allFound = false; |
| | break; |
| | } |
| | } |
| | } |
| | |
| | aStack.pop(); |
| | bStack.pop(); |
| | return allFound; |
| | } |
| | } |
| | const bIterator = b[IteratorSymbol](); |
| | for (const aValue of a) { |
| | const nextB = bIterator.next(); |
| | if ( |
| | nextB.done || |
| | !(0, _jasmineUtils.equals)(aValue, nextB.value, filteredCustomTesters) |
| | ) { |
| | return false; |
| | } |
| | } |
| | if (!bIterator.next().done) { |
| | return false; |
| | } |
| | if ( |
| | !(0, _immutableUtils.isImmutableList)(a) && |
| | !(0, _immutableUtils.isImmutableOrderedKeyed)(a) && |
| | !(0, _immutableUtils.isImmutableOrderedSet)(a) && |
| | !(0, _immutableUtils.isImmutableRecord)(a) |
| | ) { |
| | const aEntries = Object.entries(a); |
| | const bEntries = Object.entries(b); |
| | if (!(0, _jasmineUtils.equals)(aEntries, bEntries)) { |
| | return false; |
| | } |
| | } |
| |
|
| | |
| | aStack.pop(); |
| | bStack.pop(); |
| | return true; |
| | }; |
| | exports.iterableEquality = iterableEquality; |
| | const isObject = a => a !== null && typeof a === 'object'; |
| | const isObjectWithKeys = a => |
| | isObject(a) && |
| | !(a instanceof Error) && |
| | !(a instanceof Array) && |
| | !(a instanceof Date); |
| | const subsetEquality = (object, subset, customTesters = []) => { |
| | const filteredCustomTesters = customTesters.filter(t => t !== subsetEquality); |
| |
|
| | |
| | |
| | |
| | const subsetEqualityWithContext = |
| | (seenReferences = new WeakMap()) => |
| | (object, subset) => { |
| | if (!isObjectWithKeys(subset)) { |
| | return undefined; |
| | } |
| | return getObjectKeys(subset).every(key => { |
| | if (isObjectWithKeys(subset[key])) { |
| | if (seenReferences.has(subset[key])) { |
| | return (0, _jasmineUtils.equals)( |
| | object[key], |
| | subset[key], |
| | filteredCustomTesters |
| | ); |
| | } |
| | seenReferences.set(subset[key], true); |
| | } |
| | const result = |
| | object != null && |
| | hasPropertyInObject(object, key) && |
| | (0, _jasmineUtils.equals)(object[key], subset[key], [ |
| | ...filteredCustomTesters, |
| | subsetEqualityWithContext(seenReferences) |
| | ]); |
| | |
| | |
| | |
| | |
| | |
| | seenReferences.delete(subset[key]); |
| | return result; |
| | }); |
| | }; |
| | return subsetEqualityWithContext()(object, subset); |
| | }; |
| |
|
| | |
| | exports.subsetEquality = subsetEquality; |
| | const typeEquality = (a, b) => { |
| | if ( |
| | a == null || |
| | b == null || |
| | a.constructor === b.constructor || |
| | |
| | |
| | |
| | |
| | (Array.isArray(a) && Array.isArray(b)) |
| | ) { |
| | return undefined; |
| | } |
| | return false; |
| | }; |
| | exports.typeEquality = typeEquality; |
| | const arrayBufferEquality = (a, b) => { |
| | if (!(a instanceof ArrayBuffer) || !(b instanceof ArrayBuffer)) { |
| | return undefined; |
| | } |
| | const dataViewA = new DataView(a); |
| | const dataViewB = new DataView(b); |
| |
|
| | |
| | if (dataViewA.byteLength !== dataViewB.byteLength) { |
| | return false; |
| | } |
| |
|
| | |
| | for (let i = 0; i < dataViewA.byteLength; i++) { |
| | if (dataViewA.getUint8(i) !== dataViewB.getUint8(i)) { |
| | return false; |
| | } |
| | } |
| | return true; |
| | }; |
| | exports.arrayBufferEquality = arrayBufferEquality; |
| | const sparseArrayEquality = (a, b, customTesters = []) => { |
| | if (!Array.isArray(a) || !Array.isArray(b)) { |
| | return undefined; |
| | } |
| |
|
| | |
| | const aKeys = Object.keys(a); |
| | const bKeys = Object.keys(b); |
| | return ( |
| | (0, _jasmineUtils.equals)( |
| | a, |
| | b, |
| | customTesters.filter(t => t !== sparseArrayEquality), |
| | true |
| | ) && (0, _jasmineUtils.equals)(aKeys, bKeys) |
| | ); |
| | }; |
| | exports.sparseArrayEquality = sparseArrayEquality; |
| | const partition = (items, predicate) => { |
| | const result = [[], []]; |
| | items.forEach(item => result[predicate(item) ? 0 : 1].push(item)); |
| | return result; |
| | }; |
| | exports.partition = partition; |
| | const pathAsArray = propertyPath => { |
| | const properties = []; |
| | if (propertyPath === '') { |
| | properties.push(''); |
| | return properties; |
| | } |
| |
|
| | |
| | const pattern = RegExp('[^.[\\]]+|(?=(?:\\.)(?:\\.|$))', 'g'); |
| |
|
| | |
| | if (propertyPath[0] === '.') { |
| | properties.push(''); |
| | } |
| | propertyPath.replace(pattern, match => { |
| | properties.push(match); |
| | return match; |
| | }); |
| | return properties; |
| | }; |
| |
|
| | |
| | exports.pathAsArray = pathAsArray; |
| | const isError = value => { |
| | switch (Object.prototype.toString.call(value)) { |
| | case '[object Error]': |
| | case '[object Exception]': |
| | case '[object DOMException]': |
| | return true; |
| | default: |
| | return value instanceof Error; |
| | } |
| | }; |
| | exports.isError = isError; |
| | function emptyObject(obj) { |
| | return obj && typeof obj === 'object' ? !Object.keys(obj).length : false; |
| | } |
| | const MULTILINE_REGEXP = /[\r\n]/; |
| | const isOneline = (expected, received) => |
| | typeof expected === 'string' && |
| | typeof received === 'string' && |
| | (!MULTILINE_REGEXP.test(expected) || !MULTILINE_REGEXP.test(received)); |
| | exports.isOneline = isOneline; |
| |
|