Skip to content

Instantly share code, notes, and snippets.

@fhpriamo
Last active July 29, 2020 17:40
Show Gist options
  • Save fhpriamo/798d87da4ebe39a345152022d1d9a2d0 to your computer and use it in GitHub Desktop.
Save fhpriamo/798d87da4ebe39a345152022d1d9a2d0 to your computer and use it in GitHub Desktop.
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