deep-eql
Advanced tools
Comparing version 4.0.0 to 4.0.1
852
deep-eql.js
@@ -1,851 +0,1 @@ | ||
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.deepEqual = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){ | ||
'use strict'; | ||
/* globals Symbol: false, Uint8Array: false, WeakMap: false */ | ||
/*! | ||
* deep-eql | ||
* Copyright(c) 2013 Jake Luer <jake@alogicalparadox.com> | ||
* MIT Licensed | ||
*/ | ||
var type = require('type-detect'); | ||
function FakeMap() { | ||
this._key = 'chai/deep-eql__' + Math.random() + Date.now(); | ||
} | ||
FakeMap.prototype = { | ||
get: function getMap(key) { | ||
return key[this._key]; | ||
}, | ||
set: function setMap(key, value) { | ||
if (Object.isExtensible(key)) { | ||
Object.defineProperty(key, this._key, { | ||
value: value, | ||
configurable: true, | ||
}); | ||
} | ||
}, | ||
}; | ||
var MemoizeMap = typeof WeakMap === 'function' ? WeakMap : FakeMap; | ||
/*! | ||
* Check to see if the MemoizeMap has recorded a result of the two operands | ||
* | ||
* @param {Mixed} leftHandOperand | ||
* @param {Mixed} rightHandOperand | ||
* @param {MemoizeMap} memoizeMap | ||
* @returns {Boolean|null} result | ||
*/ | ||
function memoizeCompare(leftHandOperand, rightHandOperand, memoizeMap) { | ||
// Technically, WeakMap keys can *only* be objects, not primitives. | ||
if (!memoizeMap || isPrimitive(leftHandOperand) || isPrimitive(rightHandOperand)) { | ||
return null; | ||
} | ||
var leftHandMap = memoizeMap.get(leftHandOperand); | ||
if (leftHandMap) { | ||
var result = leftHandMap.get(rightHandOperand); | ||
if (typeof result === 'boolean') { | ||
return result; | ||
} | ||
} | ||
return null; | ||
} | ||
/*! | ||
* Set the result of the equality into the MemoizeMap | ||
* | ||
* @param {Mixed} leftHandOperand | ||
* @param {Mixed} rightHandOperand | ||
* @param {MemoizeMap} memoizeMap | ||
* @param {Boolean} result | ||
*/ | ||
function memoizeSet(leftHandOperand, rightHandOperand, memoizeMap, result) { | ||
// Technically, WeakMap keys can *only* be objects, not primitives. | ||
if (!memoizeMap || isPrimitive(leftHandOperand) || isPrimitive(rightHandOperand)) { | ||
return; | ||
} | ||
var leftHandMap = memoizeMap.get(leftHandOperand); | ||
if (leftHandMap) { | ||
leftHandMap.set(rightHandOperand, result); | ||
} else { | ||
leftHandMap = new MemoizeMap(); | ||
leftHandMap.set(rightHandOperand, result); | ||
memoizeMap.set(leftHandOperand, leftHandMap); | ||
} | ||
} | ||
/*! | ||
* Primary Export | ||
*/ | ||
module.exports = deepEqual; | ||
module.exports.MemoizeMap = MemoizeMap; | ||
/** | ||
* Assert deeply nested sameValue equality between two objects of any type. | ||
* | ||
* @param {Mixed} leftHandOperand | ||
* @param {Mixed} rightHandOperand | ||
* @param {Object} [options] (optional) Additional options | ||
* @param {Array} [options.comparator] (optional) Override default algorithm, determining custom equality. | ||
* @param {Array} [options.memoize] (optional) Provide a custom memoization object which will cache the results of | ||
complex objects for a speed boost. By passing `false` you can disable memoization, but this will cause circular | ||
references to blow the stack. | ||
* @return {Boolean} equal match | ||
*/ | ||
function deepEqual(leftHandOperand, rightHandOperand, options) { | ||
// If we have a comparator, we can't assume anything; so bail to its check first. | ||
if (options && options.comparator) { | ||
return extensiveDeepEqual(leftHandOperand, rightHandOperand, options); | ||
} | ||
var simpleResult = simpleEqual(leftHandOperand, rightHandOperand); | ||
if (simpleResult !== null) { | ||
return simpleResult; | ||
} | ||
// Deeper comparisons are pushed through to a larger function | ||
return extensiveDeepEqual(leftHandOperand, rightHandOperand, options); | ||
} | ||
/** | ||
* Many comparisons can be canceled out early via simple equality or primitive checks. | ||
* @param {Mixed} leftHandOperand | ||
* @param {Mixed} rightHandOperand | ||
* @return {Boolean|null} equal match | ||
*/ | ||
function simpleEqual(leftHandOperand, rightHandOperand) { | ||
// Equal references (except for Numbers) can be returned early | ||
if (leftHandOperand === rightHandOperand) { | ||
// Handle +-0 cases | ||
return leftHandOperand !== 0 || 1 / leftHandOperand === 1 / rightHandOperand; | ||
} | ||
// handle NaN cases | ||
if ( | ||
leftHandOperand !== leftHandOperand && // eslint-disable-line no-self-compare | ||
rightHandOperand !== rightHandOperand // eslint-disable-line no-self-compare | ||
) { | ||
return true; | ||
} | ||
// Anything that is not an 'object', i.e. symbols, functions, booleans, numbers, | ||
// strings, and undefined, can be compared by reference. | ||
if (isPrimitive(leftHandOperand) || isPrimitive(rightHandOperand)) { | ||
// Easy out b/c it would have passed the first equality check | ||
return false; | ||
} | ||
return null; | ||
} | ||
/*! | ||
* The main logic of the `deepEqual` function. | ||
* | ||
* @param {Mixed} leftHandOperand | ||
* @param {Mixed} rightHandOperand | ||
* @param {Object} [options] (optional) Additional options | ||
* @param {Array} [options.comparator] (optional) Override default algorithm, determining custom equality. | ||
* @param {Array} [options.memoize] (optional) Provide a custom memoization object which will cache the results of | ||
complex objects for a speed boost. By passing `false` you can disable memoization, but this will cause circular | ||
references to blow the stack. | ||
* @return {Boolean} equal match | ||
*/ | ||
function extensiveDeepEqual(leftHandOperand, rightHandOperand, options) { | ||
options = options || {}; | ||
options.memoize = options.memoize === false ? false : options.memoize || new MemoizeMap(); | ||
var comparator = options && options.comparator; | ||
// Check if a memoized result exists. | ||
var memoizeResultLeft = memoizeCompare(leftHandOperand, rightHandOperand, options.memoize); | ||
if (memoizeResultLeft !== null) { | ||
return memoizeResultLeft; | ||
} | ||
var memoizeResultRight = memoizeCompare(rightHandOperand, leftHandOperand, options.memoize); | ||
if (memoizeResultRight !== null) { | ||
return memoizeResultRight; | ||
} | ||
// If a comparator is present, use it. | ||
if (comparator) { | ||
var comparatorResult = comparator(leftHandOperand, rightHandOperand); | ||
// Comparators may return null, in which case we want to go back to default behavior. | ||
if (comparatorResult === false || comparatorResult === true) { | ||
memoizeSet(leftHandOperand, rightHandOperand, options.memoize, comparatorResult); | ||
return comparatorResult; | ||
} | ||
// To allow comparators to override *any* behavior, we ran them first. Since it didn't decide | ||
// what to do, we need to make sure to return the basic tests first before we move on. | ||
var simpleResult = simpleEqual(leftHandOperand, rightHandOperand); | ||
if (simpleResult !== null) { | ||
// Don't memoize this, it takes longer to set/retrieve than to just compare. | ||
return simpleResult; | ||
} | ||
} | ||
var leftHandType = type(leftHandOperand); | ||
if (leftHandType !== type(rightHandOperand)) { | ||
memoizeSet(leftHandOperand, rightHandOperand, options.memoize, false); | ||
return false; | ||
} | ||
// Temporarily set the operands in the memoize object to prevent blowing the stack | ||
memoizeSet(leftHandOperand, rightHandOperand, options.memoize, true); | ||
var result = extensiveDeepEqualByType(leftHandOperand, rightHandOperand, leftHandType, options); | ||
memoizeSet(leftHandOperand, rightHandOperand, options.memoize, result); | ||
return result; | ||
} | ||
function extensiveDeepEqualByType(leftHandOperand, rightHandOperand, leftHandType, options) { | ||
switch (leftHandType) { | ||
case 'String': | ||
case 'Number': | ||
case 'Boolean': | ||
case 'Date': | ||
// If these types are their instance types (e.g. `new Number`) then re-deepEqual against their values | ||
return deepEqual(leftHandOperand.valueOf(), rightHandOperand.valueOf()); | ||
case 'Promise': | ||
case 'Symbol': | ||
case 'function': | ||
case 'WeakMap': | ||
case 'WeakSet': | ||
return leftHandOperand === rightHandOperand; | ||
case 'Error': | ||
return keysEqual(leftHandOperand, rightHandOperand, [ 'name', 'message', 'code' ], options); | ||
case 'Arguments': | ||
case 'Int8Array': | ||
case 'Uint8Array': | ||
case 'Uint8ClampedArray': | ||
case 'Int16Array': | ||
case 'Uint16Array': | ||
case 'Int32Array': | ||
case 'Uint32Array': | ||
case 'Float32Array': | ||
case 'Float64Array': | ||
case 'Array': | ||
return iterableEqual(leftHandOperand, rightHandOperand, options); | ||
case 'RegExp': | ||
return regexpEqual(leftHandOperand, rightHandOperand); | ||
case 'Generator': | ||
return generatorEqual(leftHandOperand, rightHandOperand, options); | ||
case 'DataView': | ||
return iterableEqual(new Uint8Array(leftHandOperand.buffer), new Uint8Array(rightHandOperand.buffer), options); | ||
case 'ArrayBuffer': | ||
return iterableEqual(new Uint8Array(leftHandOperand), new Uint8Array(rightHandOperand), options); | ||
case 'Set': | ||
return entriesEqual(leftHandOperand, rightHandOperand, options); | ||
case 'Map': | ||
return entriesEqual(leftHandOperand, rightHandOperand, options); | ||
default: | ||
return objectEqual(leftHandOperand, rightHandOperand, options); | ||
} | ||
} | ||
/*! | ||
* Compare two Regular Expressions for equality. | ||
* | ||
* @param {RegExp} leftHandOperand | ||
* @param {RegExp} rightHandOperand | ||
* @return {Boolean} result | ||
*/ | ||
function regexpEqual(leftHandOperand, rightHandOperand) { | ||
return leftHandOperand.toString() === rightHandOperand.toString(); | ||
} | ||
/*! | ||
* Compare two Sets/Maps for equality. Faster than other equality functions. | ||
* | ||
* @param {Set} leftHandOperand | ||
* @param {Set} rightHandOperand | ||
* @param {Object} [options] (Optional) | ||
* @return {Boolean} result | ||
*/ | ||
function entriesEqual(leftHandOperand, rightHandOperand, options) { | ||
// IE11 doesn't support Set#entries or Set#@@iterator, so we need manually populate using Set#forEach | ||
if (leftHandOperand.size !== rightHandOperand.size) { | ||
return false; | ||
} | ||
if (leftHandOperand.size === 0) { | ||
return true; | ||
} | ||
var leftHandItems = []; | ||
var rightHandItems = []; | ||
leftHandOperand.forEach(function gatherEntries(key, value) { | ||
leftHandItems.push([ key, value ]); | ||
}); | ||
rightHandOperand.forEach(function gatherEntries(key, value) { | ||
rightHandItems.push([ key, value ]); | ||
}); | ||
return iterableEqual(leftHandItems.sort(), rightHandItems.sort(), options); | ||
} | ||
/*! | ||
* Simple equality for flat iterable objects such as Arrays, TypedArrays or Node.js buffers. | ||
* | ||
* @param {Iterable} leftHandOperand | ||
* @param {Iterable} rightHandOperand | ||
* @param {Object} [options] (Optional) | ||
* @return {Boolean} result | ||
*/ | ||
function iterableEqual(leftHandOperand, rightHandOperand, options) { | ||
var length = leftHandOperand.length; | ||
if (length !== rightHandOperand.length) { | ||
return false; | ||
} | ||
if (length === 0) { | ||
return true; | ||
} | ||
var index = -1; | ||
while (++index < length) { | ||
if (deepEqual(leftHandOperand[index], rightHandOperand[index], options) === false) { | ||
return false; | ||
} | ||
} | ||
return true; | ||
} | ||
/*! | ||
* Simple equality for generator objects such as those returned by generator functions. | ||
* | ||
* @param {Iterable} leftHandOperand | ||
* @param {Iterable} rightHandOperand | ||
* @param {Object} [options] (Optional) | ||
* @return {Boolean} result | ||
*/ | ||
function generatorEqual(leftHandOperand, rightHandOperand, options) { | ||
return iterableEqual(getGeneratorEntries(leftHandOperand), getGeneratorEntries(rightHandOperand), options); | ||
} | ||
/*! | ||
* Determine if the given object has an @@iterator function. | ||
* | ||
* @param {Object} target | ||
* @return {Boolean} `true` if the object has an @@iterator function. | ||
*/ | ||
function hasIteratorFunction(target) { | ||
return typeof Symbol !== 'undefined' && | ||
typeof target === 'object' && | ||
typeof Symbol.iterator !== 'undefined' && | ||
typeof target[Symbol.iterator] === 'function'; | ||
} | ||
/*! | ||
* Gets all iterator entries from the given Object. If the Object has no @@iterator function, returns an empty array. | ||
* This will consume the iterator - which could have side effects depending on the @@iterator implementation. | ||
* | ||
* @param {Object} target | ||
* @returns {Array} an array of entries from the @@iterator function | ||
*/ | ||
function getIteratorEntries(target) { | ||
if (hasIteratorFunction(target)) { | ||
try { | ||
return getGeneratorEntries(target[Symbol.iterator]()); | ||
} catch (iteratorError) { | ||
return []; | ||
} | ||
} | ||
return []; | ||
} | ||
/*! | ||
* Gets all entries from a Generator. This will consume the generator - which could have side effects. | ||
* | ||
* @param {Generator} target | ||
* @returns {Array} an array of entries from the Generator. | ||
*/ | ||
function getGeneratorEntries(generator) { | ||
var generatorResult = generator.next(); | ||
var accumulator = [ generatorResult.value ]; | ||
while (generatorResult.done === false) { | ||
generatorResult = generator.next(); | ||
accumulator.push(generatorResult.value); | ||
} | ||
return accumulator; | ||
} | ||
/*! | ||
* Gets all own and inherited enumerable keys from a target. | ||
* | ||
* @param {Object} target | ||
* @returns {Array} an array of own and inherited enumerable keys from the target. | ||
*/ | ||
function getEnumerableKeys(target) { | ||
var keys = []; | ||
for (var key in target) { | ||
keys.push(key); | ||
} | ||
return keys; | ||
} | ||
/*! | ||
* Determines if two objects have matching values, given a set of keys. Defers to deepEqual for the equality check of | ||
* each key. If any value of the given key is not equal, the function will return false (early). | ||
* | ||
* @param {Mixed} leftHandOperand | ||
* @param {Mixed} rightHandOperand | ||
* @param {Array} keys An array of keys to compare the values of leftHandOperand and rightHandOperand against | ||
* @param {Object} [options] (Optional) | ||
* @return {Boolean} result | ||
*/ | ||
function keysEqual(leftHandOperand, rightHandOperand, keys, options) { | ||
var length = keys.length; | ||
if (length === 0) { | ||
return true; | ||
} | ||
for (var i = 0; i < length; i += 1) { | ||
if (deepEqual(leftHandOperand[keys[i]], rightHandOperand[keys[i]], options) === false) { | ||
return false; | ||
} | ||
} | ||
return true; | ||
} | ||
/*! | ||
* Recursively check the equality of two Objects. Once basic sameness has been established it will defer to `deepEqual` | ||
* for each enumerable key in the object. | ||
* | ||
* @param {Mixed} leftHandOperand | ||
* @param {Mixed} rightHandOperand | ||
* @param {Object} [options] (Optional) | ||
* @return {Boolean} result | ||
*/ | ||
function objectEqual(leftHandOperand, rightHandOperand, options) { | ||
var leftHandKeys = getEnumerableKeys(leftHandOperand); | ||
var rightHandKeys = getEnumerableKeys(rightHandOperand); | ||
if (leftHandKeys.length && leftHandKeys.length === rightHandKeys.length) { | ||
leftHandKeys.sort(); | ||
rightHandKeys.sort(); | ||
if (iterableEqual(leftHandKeys, rightHandKeys) === false) { | ||
return false; | ||
} | ||
return keysEqual(leftHandOperand, rightHandOperand, leftHandKeys, options); | ||
} | ||
var leftHandEntries = getIteratorEntries(leftHandOperand); | ||
var rightHandEntries = getIteratorEntries(rightHandOperand); | ||
if (leftHandEntries.length && leftHandEntries.length === rightHandEntries.length) { | ||
leftHandEntries.sort(); | ||
rightHandEntries.sort(); | ||
return iterableEqual(leftHandEntries, rightHandEntries, options); | ||
} | ||
if (leftHandKeys.length === 0 && | ||
leftHandEntries.length === 0 && | ||
rightHandKeys.length === 0 && | ||
rightHandEntries.length === 0) { | ||
return true; | ||
} | ||
return false; | ||
} | ||
/*! | ||
* Returns true if the argument is a primitive. | ||
* | ||
* This intentionally returns true for all objects that can be compared by reference, | ||
* including functions and symbols. | ||
* | ||
* @param {Mixed} value | ||
* @return {Boolean} result | ||
*/ | ||
function isPrimitive(value) { | ||
return value === null || typeof value !== 'object'; | ||
} | ||
},{"type-detect":2}],2:[function(require,module,exports){ | ||
(function (global){ | ||
(function (global, factory) { | ||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : | ||
typeof define === 'function' && define.amd ? define(factory) : | ||
(global.typeDetect = factory()); | ||
}(this, (function () { 'use strict'; | ||
/* ! | ||
* type-detect | ||
* Copyright(c) 2013 jake luer <jake@alogicalparadox.com> | ||
* MIT Licensed | ||
*/ | ||
var promiseExists = typeof Promise === 'function'; | ||
/* eslint-disable no-undef */ | ||
var globalObject = typeof self === 'object' ? self : global; // eslint-disable-line id-blacklist | ||
var symbolExists = typeof Symbol !== 'undefined'; | ||
var mapExists = typeof Map !== 'undefined'; | ||
var setExists = typeof Set !== 'undefined'; | ||
var weakMapExists = typeof WeakMap !== 'undefined'; | ||
var weakSetExists = typeof WeakSet !== 'undefined'; | ||
var dataViewExists = typeof DataView !== 'undefined'; | ||
var symbolIteratorExists = symbolExists && typeof Symbol.iterator !== 'undefined'; | ||
var symbolToStringTagExists = symbolExists && typeof Symbol.toStringTag !== 'undefined'; | ||
var setEntriesExists = setExists && typeof Set.prototype.entries === 'function'; | ||
var mapEntriesExists = mapExists && typeof Map.prototype.entries === 'function'; | ||
var setIteratorPrototype = setEntriesExists && Object.getPrototypeOf(new Set().entries()); | ||
var mapIteratorPrototype = mapEntriesExists && Object.getPrototypeOf(new Map().entries()); | ||
var arrayIteratorExists = symbolIteratorExists && typeof Array.prototype[Symbol.iterator] === 'function'; | ||
var arrayIteratorPrototype = arrayIteratorExists && Object.getPrototypeOf([][Symbol.iterator]()); | ||
var stringIteratorExists = symbolIteratorExists && typeof String.prototype[Symbol.iterator] === 'function'; | ||
var stringIteratorPrototype = stringIteratorExists && Object.getPrototypeOf(''[Symbol.iterator]()); | ||
var toStringLeftSliceLength = 8; | ||
var toStringRightSliceLength = -1; | ||
/** | ||
* ### typeOf (obj) | ||
* | ||
* Uses `Object.prototype.toString` to determine the type of an object, | ||
* normalising behaviour across engine versions & well optimised. | ||
* | ||
* @param {Mixed} object | ||
* @return {String} object type | ||
* @api public | ||
*/ | ||
function typeDetect(obj) { | ||
/* ! Speed optimisation | ||
* Pre: | ||
* string literal x 3,039,035 ops/sec ±1.62% (78 runs sampled) | ||
* boolean literal x 1,424,138 ops/sec ±4.54% (75 runs sampled) | ||
* number literal x 1,653,153 ops/sec ±1.91% (82 runs sampled) | ||
* undefined x 9,978,660 ops/sec ±1.92% (75 runs sampled) | ||
* function x 2,556,769 ops/sec ±1.73% (77 runs sampled) | ||
* Post: | ||
* string literal x 38,564,796 ops/sec ±1.15% (79 runs sampled) | ||
* boolean literal x 31,148,940 ops/sec ±1.10% (79 runs sampled) | ||
* number literal x 32,679,330 ops/sec ±1.90% (78 runs sampled) | ||
* undefined x 32,363,368 ops/sec ±1.07% (82 runs sampled) | ||
* function x 31,296,870 ops/sec ±0.96% (83 runs sampled) | ||
*/ | ||
var typeofObj = typeof obj; | ||
if (typeofObj !== 'object') { | ||
return typeofObj; | ||
} | ||
/* ! Speed optimisation | ||
* Pre: | ||
* null x 28,645,765 ops/sec ±1.17% (82 runs sampled) | ||
* Post: | ||
* null x 36,428,962 ops/sec ±1.37% (84 runs sampled) | ||
*/ | ||
if (obj === null) { | ||
return 'null'; | ||
} | ||
/* ! Spec Conformance | ||
* Test: `Object.prototype.toString.call(window)`` | ||
* - Node === "[object global]" | ||
* - Chrome === "[object global]" | ||
* - Firefox === "[object Window]" | ||
* - PhantomJS === "[object Window]" | ||
* - Safari === "[object Window]" | ||
* - IE 11 === "[object Window]" | ||
* - IE Edge === "[object Window]" | ||
* Test: `Object.prototype.toString.call(this)`` | ||
* - Chrome Worker === "[object global]" | ||
* - Firefox Worker === "[object DedicatedWorkerGlobalScope]" | ||
* - Safari Worker === "[object DedicatedWorkerGlobalScope]" | ||
* - IE 11 Worker === "[object WorkerGlobalScope]" | ||
* - IE Edge Worker === "[object WorkerGlobalScope]" | ||
*/ | ||
if (obj === globalObject) { | ||
return 'global'; | ||
} | ||
/* ! Speed optimisation | ||
* Pre: | ||
* array literal x 2,888,352 ops/sec ±0.67% (82 runs sampled) | ||
* Post: | ||
* array literal x 22,479,650 ops/sec ±0.96% (81 runs sampled) | ||
*/ | ||
if ( | ||
Array.isArray(obj) && | ||
(symbolToStringTagExists === false || !(Symbol.toStringTag in obj)) | ||
) { | ||
return 'Array'; | ||
} | ||
// Not caching existence of `window` and related properties due to potential | ||
// for `window` to be unset before tests in quasi-browser environments. | ||
if (typeof window === 'object' && window !== null) { | ||
/* ! Spec Conformance | ||
* (https://html.spec.whatwg.org/multipage/browsers.html#location) | ||
* WhatWG HTML$7.7.3 - The `Location` interface | ||
* Test: `Object.prototype.toString.call(window.location)`` | ||
* - IE <=11 === "[object Object]" | ||
* - IE Edge <=13 === "[object Object]" | ||
*/ | ||
if (typeof window.location === 'object' && obj === window.location) { | ||
return 'Location'; | ||
} | ||
/* ! Spec Conformance | ||
* (https://html.spec.whatwg.org/#document) | ||
* WhatWG HTML$3.1.1 - The `Document` object | ||
* Note: Most browsers currently adher to the W3C DOM Level 2 spec | ||
* (https://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-26809268) | ||
* which suggests that browsers should use HTMLTableCellElement for | ||
* both TD and TH elements. WhatWG separates these. | ||
* WhatWG HTML states: | ||
* > For historical reasons, Window objects must also have a | ||
* > writable, configurable, non-enumerable property named | ||
* > HTMLDocument whose value is the Document interface object. | ||
* Test: `Object.prototype.toString.call(document)`` | ||
* - Chrome === "[object HTMLDocument]" | ||
* - Firefox === "[object HTMLDocument]" | ||
* - Safari === "[object HTMLDocument]" | ||
* - IE <=10 === "[object Document]" | ||
* - IE 11 === "[object HTMLDocument]" | ||
* - IE Edge <=13 === "[object HTMLDocument]" | ||
*/ | ||
if (typeof window.document === 'object' && obj === window.document) { | ||
return 'Document'; | ||
} | ||
if (typeof window.navigator === 'object') { | ||
/* ! Spec Conformance | ||
* (https://html.spec.whatwg.org/multipage/webappapis.html#mimetypearray) | ||
* WhatWG HTML$8.6.1.5 - Plugins - Interface MimeTypeArray | ||
* Test: `Object.prototype.toString.call(navigator.mimeTypes)`` | ||
* - IE <=10 === "[object MSMimeTypesCollection]" | ||
*/ | ||
if (typeof window.navigator.mimeTypes === 'object' && | ||
obj === window.navigator.mimeTypes) { | ||
return 'MimeTypeArray'; | ||
} | ||
/* ! Spec Conformance | ||
* (https://html.spec.whatwg.org/multipage/webappapis.html#pluginarray) | ||
* WhatWG HTML$8.6.1.5 - Plugins - Interface PluginArray | ||
* Test: `Object.prototype.toString.call(navigator.plugins)`` | ||
* - IE <=10 === "[object MSPluginsCollection]" | ||
*/ | ||
if (typeof window.navigator.plugins === 'object' && | ||
obj === window.navigator.plugins) { | ||
return 'PluginArray'; | ||
} | ||
} | ||
if ((typeof window.HTMLElement === 'function' || | ||
typeof window.HTMLElement === 'object') && | ||
obj instanceof window.HTMLElement) { | ||
/* ! Spec Conformance | ||
* (https://html.spec.whatwg.org/multipage/webappapis.html#pluginarray) | ||
* WhatWG HTML$4.4.4 - The `blockquote` element - Interface `HTMLQuoteElement` | ||
* Test: `Object.prototype.toString.call(document.createElement('blockquote'))`` | ||
* - IE <=10 === "[object HTMLBlockElement]" | ||
*/ | ||
if (obj.tagName === 'BLOCKQUOTE') { | ||
return 'HTMLQuoteElement'; | ||
} | ||
/* ! Spec Conformance | ||
* (https://html.spec.whatwg.org/#htmltabledatacellelement) | ||
* WhatWG HTML$4.9.9 - The `td` element - Interface `HTMLTableDataCellElement` | ||
* Note: Most browsers currently adher to the W3C DOM Level 2 spec | ||
* (https://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-82915075) | ||
* which suggests that browsers should use HTMLTableCellElement for | ||
* both TD and TH elements. WhatWG separates these. | ||
* Test: Object.prototype.toString.call(document.createElement('td')) | ||
* - Chrome === "[object HTMLTableCellElement]" | ||
* - Firefox === "[object HTMLTableCellElement]" | ||
* - Safari === "[object HTMLTableCellElement]" | ||
*/ | ||
if (obj.tagName === 'TD') { | ||
return 'HTMLTableDataCellElement'; | ||
} | ||
/* ! Spec Conformance | ||
* (https://html.spec.whatwg.org/#htmltableheadercellelement) | ||
* WhatWG HTML$4.9.9 - The `td` element - Interface `HTMLTableHeaderCellElement` | ||
* Note: Most browsers currently adher to the W3C DOM Level 2 spec | ||
* (https://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-82915075) | ||
* which suggests that browsers should use HTMLTableCellElement for | ||
* both TD and TH elements. WhatWG separates these. | ||
* Test: Object.prototype.toString.call(document.createElement('th')) | ||
* - Chrome === "[object HTMLTableCellElement]" | ||
* - Firefox === "[object HTMLTableCellElement]" | ||
* - Safari === "[object HTMLTableCellElement]" | ||
*/ | ||
if (obj.tagName === 'TH') { | ||
return 'HTMLTableHeaderCellElement'; | ||
} | ||
} | ||
} | ||
/* ! Speed optimisation | ||
* Pre: | ||
* Float64Array x 625,644 ops/sec ±1.58% (80 runs sampled) | ||
* Float32Array x 1,279,852 ops/sec ±2.91% (77 runs sampled) | ||
* Uint32Array x 1,178,185 ops/sec ±1.95% (83 runs sampled) | ||
* Uint16Array x 1,008,380 ops/sec ±2.25% (80 runs sampled) | ||
* Uint8Array x 1,128,040 ops/sec ±2.11% (81 runs sampled) | ||
* Int32Array x 1,170,119 ops/sec ±2.88% (80 runs sampled) | ||
* Int16Array x 1,176,348 ops/sec ±5.79% (86 runs sampled) | ||
* Int8Array x 1,058,707 ops/sec ±4.94% (77 runs sampled) | ||
* Uint8ClampedArray x 1,110,633 ops/sec ±4.20% (80 runs sampled) | ||
* Post: | ||
* Float64Array x 7,105,671 ops/sec ±13.47% (64 runs sampled) | ||
* Float32Array x 5,887,912 ops/sec ±1.46% (82 runs sampled) | ||
* Uint32Array x 6,491,661 ops/sec ±1.76% (79 runs sampled) | ||
* Uint16Array x 6,559,795 ops/sec ±1.67% (82 runs sampled) | ||
* Uint8Array x 6,463,966 ops/sec ±1.43% (85 runs sampled) | ||
* Int32Array x 5,641,841 ops/sec ±3.49% (81 runs sampled) | ||
* Int16Array x 6,583,511 ops/sec ±1.98% (80 runs sampled) | ||
* Int8Array x 6,606,078 ops/sec ±1.74% (81 runs sampled) | ||
* Uint8ClampedArray x 6,602,224 ops/sec ±1.77% (83 runs sampled) | ||
*/ | ||
var stringTag = (symbolToStringTagExists && obj[Symbol.toStringTag]); | ||
if (typeof stringTag === 'string') { | ||
return stringTag; | ||
} | ||
var objPrototype = Object.getPrototypeOf(obj); | ||
/* ! Speed optimisation | ||
* Pre: | ||
* regex literal x 1,772,385 ops/sec ±1.85% (77 runs sampled) | ||
* regex constructor x 2,143,634 ops/sec ±2.46% (78 runs sampled) | ||
* Post: | ||
* regex literal x 3,928,009 ops/sec ±0.65% (78 runs sampled) | ||
* regex constructor x 3,931,108 ops/sec ±0.58% (84 runs sampled) | ||
*/ | ||
if (objPrototype === RegExp.prototype) { | ||
return 'RegExp'; | ||
} | ||
/* ! Speed optimisation | ||
* Pre: | ||
* date x 2,130,074 ops/sec ±4.42% (68 runs sampled) | ||
* Post: | ||
* date x 3,953,779 ops/sec ±1.35% (77 runs sampled) | ||
*/ | ||
if (objPrototype === Date.prototype) { | ||
return 'Date'; | ||
} | ||
/* ! Spec Conformance | ||
* (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-promise.prototype-@@tostringtag) | ||
* ES6$25.4.5.4 - Promise.prototype[@@toStringTag] should be "Promise": | ||
* Test: `Object.prototype.toString.call(Promise.resolve())`` | ||
* - Chrome <=47 === "[object Object]" | ||
* - Edge <=20 === "[object Object]" | ||
* - Firefox 29-Latest === "[object Promise]" | ||
* - Safari 7.1-Latest === "[object Promise]" | ||
*/ | ||
if (promiseExists && objPrototype === Promise.prototype) { | ||
return 'Promise'; | ||
} | ||
/* ! Speed optimisation | ||
* Pre: | ||
* set x 2,222,186 ops/sec ±1.31% (82 runs sampled) | ||
* Post: | ||
* set x 4,545,879 ops/sec ±1.13% (83 runs sampled) | ||
*/ | ||
if (setExists && objPrototype === Set.prototype) { | ||
return 'Set'; | ||
} | ||
/* ! Speed optimisation | ||
* Pre: | ||
* map x 2,396,842 ops/sec ±1.59% (81 runs sampled) | ||
* Post: | ||
* map x 4,183,945 ops/sec ±6.59% (82 runs sampled) | ||
*/ | ||
if (mapExists && objPrototype === Map.prototype) { | ||
return 'Map'; | ||
} | ||
/* ! Speed optimisation | ||
* Pre: | ||
* weakset x 1,323,220 ops/sec ±2.17% (76 runs sampled) | ||
* Post: | ||
* weakset x 4,237,510 ops/sec ±2.01% (77 runs sampled) | ||
*/ | ||
if (weakSetExists && objPrototype === WeakSet.prototype) { | ||
return 'WeakSet'; | ||
} | ||
/* ! Speed optimisation | ||
* Pre: | ||
* weakmap x 1,500,260 ops/sec ±2.02% (78 runs sampled) | ||
* Post: | ||
* weakmap x 3,881,384 ops/sec ±1.45% (82 runs sampled) | ||
*/ | ||
if (weakMapExists && objPrototype === WeakMap.prototype) { | ||
return 'WeakMap'; | ||
} | ||
/* ! Spec Conformance | ||
* (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-dataview.prototype-@@tostringtag) | ||
* ES6$24.2.4.21 - DataView.prototype[@@toStringTag] should be "DataView": | ||
* Test: `Object.prototype.toString.call(new DataView(new ArrayBuffer(1)))`` | ||
* - Edge <=13 === "[object Object]" | ||
*/ | ||
if (dataViewExists && objPrototype === DataView.prototype) { | ||
return 'DataView'; | ||
} | ||
/* ! Spec Conformance | ||
* (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-%mapiteratorprototype%-@@tostringtag) | ||
* ES6$23.1.5.2.2 - %MapIteratorPrototype%[@@toStringTag] should be "Map Iterator": | ||
* Test: `Object.prototype.toString.call(new Map().entries())`` | ||
* - Edge <=13 === "[object Object]" | ||
*/ | ||
if (mapExists && objPrototype === mapIteratorPrototype) { | ||
return 'Map Iterator'; | ||
} | ||
/* ! Spec Conformance | ||
* (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-%setiteratorprototype%-@@tostringtag) | ||
* ES6$23.2.5.2.2 - %SetIteratorPrototype%[@@toStringTag] should be "Set Iterator": | ||
* Test: `Object.prototype.toString.call(new Set().entries())`` | ||
* - Edge <=13 === "[object Object]" | ||
*/ | ||
if (setExists && objPrototype === setIteratorPrototype) { | ||
return 'Set Iterator'; | ||
} | ||
/* ! Spec Conformance | ||
* (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-%arrayiteratorprototype%-@@tostringtag) | ||
* ES6$22.1.5.2.2 - %ArrayIteratorPrototype%[@@toStringTag] should be "Array Iterator": | ||
* Test: `Object.prototype.toString.call([][Symbol.iterator]())`` | ||
* - Edge <=13 === "[object Object]" | ||
*/ | ||
if (arrayIteratorExists && objPrototype === arrayIteratorPrototype) { | ||
return 'Array Iterator'; | ||
} | ||
/* ! Spec Conformance | ||
* (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-%stringiteratorprototype%-@@tostringtag) | ||
* ES6$21.1.5.2.2 - %StringIteratorPrototype%[@@toStringTag] should be "String Iterator": | ||
* Test: `Object.prototype.toString.call(''[Symbol.iterator]())`` | ||
* - Edge <=13 === "[object Object]" | ||
*/ | ||
if (stringIteratorExists && objPrototype === stringIteratorPrototype) { | ||
return 'String Iterator'; | ||
} | ||
/* ! Speed optimisation | ||
* Pre: | ||
* object from null x 2,424,320 ops/sec ±1.67% (76 runs sampled) | ||
* Post: | ||
* object from null x 5,838,000 ops/sec ±0.99% (84 runs sampled) | ||
*/ | ||
if (objPrototype === null) { | ||
return 'Object'; | ||
} | ||
return Object | ||
.prototype | ||
.toString | ||
.call(obj) | ||
.slice(toStringLeftSliceLength, toStringRightSliceLength); | ||
} | ||
return typeDetect; | ||
}))); | ||
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) | ||
},{}]},{},[1])(1) | ||
}); | ||
(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({},{},[]) |
17
index.js
@@ -15,6 +15,6 @@ 'use strict'; | ||
FakeMap.prototype = { | ||
get: function getMap(key) { | ||
get: function get(key) { | ||
return key[this._key]; | ||
}, | ||
set: function setMap(key, value) { | ||
set: function set(key, value) { | ||
if (Object.isExtensible(key)) { | ||
@@ -383,2 +383,7 @@ Object.defineProperty(key, this._key, { | ||
function getNonEnumerableSymbols(target) { | ||
var keys = Object.getOwnPropertySymbols(target); | ||
return keys; | ||
} | ||
/*! | ||
@@ -419,2 +424,10 @@ * Determines if two objects have matching values, given a set of keys. Defers to deepEqual for the equality check of | ||
var rightHandKeys = getEnumerableKeys(rightHandOperand); | ||
var leftHandSymbols = getNonEnumerableSymbols(leftHandOperand); | ||
var rightHandSymbols = getNonEnumerableSymbols(rightHandOperand); | ||
if (leftHandSymbols) { | ||
leftHandKeys = leftHandKeys.concat(leftHandSymbols); | ||
} | ||
if (rightHandSymbols) { | ||
rightHandKeys = rightHandKeys.concat(rightHandSymbols); | ||
} | ||
if (leftHandKeys.length && leftHandKeys.length === rightHandKeys.length) { | ||
@@ -421,0 +434,0 @@ leftHandKeys.sort(); |
@@ -60,27 +60,23 @@ { | ||
"benchmark": "^2.1.0", | ||
"browserify": "^13.0.0", | ||
"browserify-istanbul": "^1.0.0", | ||
"component": "*", | ||
"coveralls": "2.11.8", | ||
"eslint": "^2.4.0", | ||
"eslint-config-strict": "^8.5.0", | ||
"eslint-plugin-filenames": "^0.2.0", | ||
"ghooks": "^1.0.1", | ||
"browserify": "^17.0.0", | ||
"browserify-istanbul": "^3.0.1", | ||
"coveralls": "^3.1.1", | ||
"eslint": "^7.32.0", | ||
"eslint-config-strict": "^14.0.1", | ||
"eslint-plugin-filenames": "^1.3.2", | ||
"ghooks": "^2.0.4", | ||
"istanbul": "^0.4.2", | ||
"karma": "^0.13.22", | ||
"karma-browserify": "^5.0.2", | ||
"karma-coverage": "^0.5.5", | ||
"karma-mocha": "^0.2.2", | ||
"karma-phantomjs-launcher": "^1.0.0", | ||
"karma-sauce-launcher": "^0.3.1", | ||
"kewlr": "^0.3.1", | ||
"lcov-result-merger": "^1.0.2", | ||
"karma": "^6.3.4", | ||
"karma-browserify": "^8.1.0", | ||
"karma-chrome-launcher": "^3.1.0", | ||
"karma-coverage": "^2.0.3", | ||
"karma-mocha": "^2.0.1", | ||
"karma-sauce-launcher": "^4.3.6", | ||
"kewlr": "^0.4.1", | ||
"lcov-result-merger": "^3.1.0", | ||
"lodash.isequal": "^4.4.0", | ||
"mocha": "^3.1.2", | ||
"phantomjs-prebuilt": "^2.1.5", | ||
"semantic-release": "^4.3.5", | ||
"mocha": "^9.1.1", | ||
"semantic-release": "^18.0.0", | ||
"simple-assert": "^1.0.0", | ||
"travis-after-all": "^1.4.4", | ||
"validate-commit-msg": "^2.3.1", | ||
"watchify": "^3.7.0" | ||
"validate-commit-msg": "^2.3.1" | ||
}, | ||
@@ -90,3 +86,3 @@ "engines": { | ||
}, | ||
"version": "4.0.0" | ||
} | ||
"version": "4.0.1" | ||
} |
<h1 align=center> | ||
<a href="http://chaijs.com" title="Chai Documentation"> | ||
<img alt="ChaiJS" src="http://chaijs.com/img/chai-logo.png"/> deep-eql | ||
<img alt="deep-eql" src="https://raw.githubusercontent.com/chaijs/deep-eql/main/deep-eql-logo.svg"/> | ||
</a> | ||
@@ -8,20 +8,10 @@ </h1> | ||
<p align=center> | ||
Improved deep equality testing for [node](http://nodejs.org) and the browser. | ||
Improved deep equality testing for <a href="http://nodejs.org/">node</a> and the browser. | ||
</p> | ||
<p align=center> | ||
<a href="./LICENSE"> | ||
<a href="https://github.com/chaijs/deep-eql/actions"> | ||
<img | ||
alt="license:mit" | ||
src="https://img.shields.io/badge/license-mit-green.svg?style=flat-square" | ||
/> | ||
</a><a href="https://github.com/chaijs/deep-eql/releases"> | ||
<img | ||
alt="tag:?" | ||
src="https://img.shields.io/github/tag/chaijs/deep-eql.svg?style=flat-square" | ||
/> | ||
</a><a href="https://travis-ci.org/chaijs/deep-eql"> | ||
<img | ||
alt="build:?" | ||
src="https://img.shields.io/travis/chaijs/deep-eql/master.svg?style=flat-square" | ||
src="https://github.com/chaijs/deep-eql/workflows/Build/badge.svg" | ||
/> | ||
@@ -35,7 +25,2 @@ </a><a href="https://coveralls.io/r/chaijs/deep-eql"> | ||
<img | ||
alt="code quality:?" | ||
src="https://img.shields.io/codacy/6de187aa62274dbea6e69a3c27e798da.svg?style=flat-square" | ||
/> | ||
</a><a href="https://www.npmjs.com/packages/deep-eql"> | ||
<img | ||
alt="dependencies:?" | ||
@@ -49,15 +34,3 @@ src="https://img.shields.io/npm/dm/deep-eql.svg?style=flat-square" | ||
/> | ||
</a><a href="https://github.com/nodejs/LTS#lts-schedule1"> | ||
<img | ||
alt="Supported Node Version: 4+" | ||
src="https://img.shields.io/badge/node-4+-43853d.svg?style=flat-square" | ||
/> | ||
</a> | ||
<br/> | ||
<a href="https://saucelabs.com/u/chaijs-deep-eql"> | ||
<img | ||
alt="Selenium Test Status" | ||
src="https://saucelabs.com/browser-matrix/chaijs-deep-eql.svg" | ||
/> | ||
</a> | ||
<br> | ||
@@ -64,0 +37,0 @@ <a href="https://chai-slack.herokuapp.com/"> |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
Found 1 instance in 1 package
22
23552
430
1
94
2