time-to-botec

Benchmark sampling in different programming languages
Log | Files | Refs | README

main.js (2950B)


      1 /**
      2 * @license Apache-2.0
      3 *
      4 * Copyright (c) 2018 The Stdlib Authors.
      5 *
      6 * Licensed under the Apache License, Version 2.0 (the "License");
      7 * you may not use this file except in compliance with the License.
      8 * You may obtain a copy of the License at
      9 *
     10 *    http://www.apache.org/licenses/LICENSE-2.0
     11 *
     12 * Unless required by applicable law or agreed to in writing, software
     13 * distributed under the License is distributed on an "AS IS" BASIS,
     14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     15 * See the License for the specific language governing permissions and
     16 * limitations under the License.
     17 */
     18 
     19 'use strict';
     20 
     21 // MODULES //
     22 
     23 var objectKeys = require( '@stdlib/utils/keys' );
     24 var getPrototypeOf = require( '@stdlib/utils/get-prototype-of' );
     25 var isDate = require( './../../is-date-object' );
     26 var isError = require( './../../is-error' );
     27 var isBuffer = require( './../../is-buffer' );
     28 var isRegExp = require( './../../is-regexp' );
     29 
     30 
     31 // MAIN //
     32 
     33 /**
     34 * Tests for deep equality between two values.
     35 *
     36 * @param {*} a - first comparison value
     37 * @param {*} b - second comparison value
     38 * @returns {boolean} boolean indicating if `a` is deep equal to `b`
     39 *
     40 * @example
     41 * var bool = deepEqual( [ 1, 2, 3 ], [ 1, 2, 3 ] );
     42 * // returns true
     43 *
     44 * @example
     45 * var bool = deepEqual( [ 1, 2, 3 ], [ 1, 2, '3' ] );
     46 * // returns false
     47 *
     48 * @example
     49 * var bool = deepEqual( { 'a': 2 }, { 'a': [ 2 ] } );
     50 * // returns false
     51 *
     52 * @example
     53 * var bool = deepEqual( [], {} );
     54 * // returns false
     55 *
     56 * @example
     57 * var bool = deepEqual( null, null );
     58 * // returns true
     59 */
     60 function deepEqual( a, b ) {
     61 	var aKeys;
     62 	var bKeys;
     63 	var typeA;
     64 	var typeB;
     65 	var key;
     66 	var i;
     67 
     68 	typeA = typeof a;
     69 	typeB = typeof b;
     70 	if ( a === null || typeA !== 'object' ) {
     71 		if ( b === null || typeB !== 'object' ) {
     72 			return a === b;
     73 		}
     74 		return false;
     75 	}
     76 	// Case: `a` is of type 'object'
     77 	if ( typeB !== 'object' ) {
     78 		return false;
     79 	}
     80 	if ( getPrototypeOf( a ) !== getPrototypeOf( b ) ) {
     81 		return false;
     82 	}
     83 	if ( isDate( a ) ) {
     84 		return a.getTime() === b.getTime();
     85 	}
     86 	if ( isRegExp( a ) ) {
     87 		return a.source === b.source && a.flags === b.flags;
     88 	}
     89 	if ( isError( a ) ) {
     90 		if ( a.message !== b.message || a.name !== b.name ) {
     91 			return false;
     92 		}
     93 	}
     94 	if ( isBuffer( a ) ) {
     95 		if ( a.length !== b.length ) {
     96 			return false;
     97 		}
     98 		for ( i = 0; i < a.length; i++ ) {
     99 			if ( a[ i ] !== b[ i ] ) {
    100 				return false;
    101 			}
    102 		}
    103 		return true;
    104 	}
    105 	aKeys = objectKeys( a );
    106 	bKeys = objectKeys( b );
    107 	if ( aKeys.length !== bKeys.length ) {
    108 		return false;
    109 	}
    110 	aKeys.sort();
    111 	bKeys.sort();
    112 
    113 	// Cheap key test:
    114 	for ( i = 0; i < aKeys.length; i++ ) {
    115 		if ( aKeys[ i ] !== bKeys[ i ] ) {
    116 			return false;
    117 		}
    118 	}
    119 	// Possibly expensive deep equality test for each corresponding key:
    120 	for ( i = 0; i < aKeys.length; i++ ) {
    121 		key = aKeys[ i ];
    122 		if ( !deepEqual( a[ key ], b[ key ] ) ) {
    123 			return false;
    124 		}
    125 	}
    126 	return typeA === typeB;
    127 }
    128 
    129 
    130 // EXPORTS //
    131 
    132 module.exports = deepEqual;