Last active
July 29, 2020 17:40
-
-
Save fhpriamo/798d87da4ebe39a345152022d1d9a2d0 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const assert = require('assert'); | |
/** | |
* Compares 2 arrays in any order. | |
*/ | |
function arrayEquals(arr1, arr2) { | |
if (arr1.length !== arr2.length) { | |
return false; | |
} | |
return arr1.every((el1) => arr2.some((el2) => compare(el1, el2))); | |
} | |
/** | |
* Checks if a value is an object. | |
*/ | |
function isObject(value) { | |
return !Array.isArray(value) && value != null && typeof value == 'object'; | |
} | |
/** | |
* Compares 2 objects structuraly. | |
*/ | |
function objectEquals(obj1, obj2) { | |
if (Object.is(obj1, obj2)) { | |
return true; | |
} | |
const entries1 = Object.entries(obj1); | |
const entries2 = Object.entries(obj2); | |
if (entries1.length !== entries2.length) { | |
return false; | |
} | |
return entries1.every(([k, v]) => compare(obj2[k], v)); | |
} | |
/** | |
* Compares 2 values of any type. | |
*/ | |
function compare(a, b) { | |
if (Array.isArray(a) && Array.isArray(b)) { | |
return arrayEquals(a, b); | |
} | |
if (isObject(a) && isObject(b)) { | |
return objectEquals(a, b); | |
} | |
return Object.is(a, b); | |
} | |
// | |
// Tests | |
// | |
function fun1() {} | |
function fun2() {} | |
const obj = {}; | |
assert.strictEqual(compare(1, 1), true); | |
assert.strictEqual(compare(3, 1), false); | |
assert.strictEqual(compare([], []), true); | |
assert.strictEqual(compare([], ['a']), false); | |
assert.strictEqual(compare(['b'], ['a']), false); | |
assert.strictEqual(compare(['b'], 'b'), false); | |
assert.strictEqual(compare(['a', 'b'], ['a']), false); | |
assert.strictEqual(compare(['a'], ['a', 'b']), false); | |
assert.strictEqual(compare(['a'], null), false); | |
assert.strictEqual(compare([null], [undefined]), false); | |
assert.strictEqual(compare([], {}), false); | |
assert.strictEqual(compare(null, null), true); | |
assert.strictEqual(compare(true, true), true); | |
assert.strictEqual(compare(true, false), false); | |
assert.strictEqual(compare(undefined, null), false); | |
assert.strictEqual(compare(['a', 'b'], ['b', 'a']), true); | |
assert.strictEqual(compare(['a', ['c', 'd']], [['c', 'd'], 'a']), true); | |
assert.strictEqual(compare(['a', ['c', 'K']], [['c', 'd'], 'a']), false); | |
assert.strictEqual(compare(['a', ['c', 'K']], [['c', 'd'], 'a']), false); | |
assert.strictEqual( | |
compare([null, 3, null, false], [3, false, null, null]), | |
true, | |
); | |
assert.strictEqual(compare([undefined], []), false); | |
assert.strictEqual(compare({}, {}), true); | |
assert.strictEqual(compare(obj, obj), true); | |
assert.strictEqual(compare(obj, {}), true); | |
assert.strictEqual(compare({ a: 'A' }, {}), false); | |
assert.strictEqual(compare({ a: 'A' }, { b: 'B' }), false); | |
assert.strictEqual(compare({ a: 'A' }, { a: 'A', b: 'B' }), false); | |
assert.strictEqual(compare({ a: 'A', b: 'B' }, { b: 'B', a: 'A' }), true); | |
assert.strictEqual(compare(NaN, NaN), true); | |
assert.strictEqual(compare(NaN, 1), false); | |
assert.strictEqual(compare(fun1, fun1), true); | |
assert.strictEqual(compare(fun1, fun2), false); | |
assert.strictEqual(compare(+Infinity, +Infinity), true); | |
assert.strictEqual(compare(+Infinity, -Infinity), false); | |
assert.strictEqual(compare(-Infinity, -Infinity), true); | |
assert.strictEqual(compare('1', 1), false); | |
assert.strictEqual(compare('somestring', 'somestring'), true); | |
assert.strictEqual( | |
compare({ a: 'A', b: ['b', 'c'] }, { a: 'A', b: ['c', 'b'] }), | |
true, | |
); | |
assert.strictEqual( | |
compare( | |
{ a: 'A', b: ['b', 'c', { k: 'asdf', y: ['b'], z: 124 }] }, | |
{ a: 'A', b: ['b', 'c', { k: 'asdf', y: ['b'], z: 124 }] }, | |
), | |
true, | |
); | |
assert.strictEqual( | |
compare( | |
{ | |
a: 'A', | |
b: ['b', 'c', { k: 'asdf', y: [null, 'b', null, true], z: 124 }], | |
}, | |
{ | |
b: ['b', 'c', { k: 'asdf', y: ['b', null, null, true], z: 124 }], | |
a: 'A', | |
}, | |
), | |
true, | |
); | |
assert.strictEqual( | |
compare( | |
{ a: 'A', b: ['b', 'c', { k: 'asdf', y: [null, 'b'], z: 124 }] }, | |
{ b: ['b', 'c', { k: 'asdf', y: ['b', undefined, null], z: 124 }], a: 'A' }, | |
), | |
false, | |
); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment