| '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; |
|
|