import { assert } from 'chai'; import { create, assign } from '../../../../../../lib/core/object'; import { MetaContext } from '../../../../../../lib/experimental/meta/MetaContext'; import { $EQUAL, withEqual } from '../../../../../../lib/experimental/meta/operations/base/$equal'; import builtins from '../../../../../../lib/experimental/meta/operations/builtins/$equal'; const equal = (function () { const context = new (withEqual(MetaContext))(); context.registerAll(builtins); return function equal(lhs: T, rhs: T) { return context[$EQUAL](lhs, rhs); }; })(); describe('experimental.meta.operations.builtins.$equal', () => { describe('string', () => { test.each([ ['', '', true], ['abc', 'abc', true], ['abc', 'abd', false], ['abd', 'abc', false], ['abcd', 'abc', false], ['abc', 'abcd', false], ['abcd', 'abcd', true] ])('string#%#', (lhs: string, rhs: string, result: boolean) => { assert.strictEqual(equal(lhs, rhs), result); }); }); describe('String', () => { test.each([ ['', '', true], ['abc', 'abc', true], ['abc', 'abd', false], ['abd', 'abc', false], ['abcd', 'abc', false], ['abc', 'abcd', false], ['abcd', 'abcd', true], [123, '123', true], [1234, '123', false], ])('String#%#', (lhsValue: string, rhsValue: string, result: boolean) => { const lhs = new String(lhsValue); const rhs = new String(rhsValue); assert.strictEqual(equal(lhs, rhs), result); }); }); describe('number', () => { test.each([ [0, 0, true], [1, 1, true], [1, -1, false], [-1, -1, true], [3.1415, 3.1415, true], [3.1415, 3.141592, false], ])('number#%#', (lhs: number, rhs: number, result: boolean) => { assert.strictEqual(equal(lhs, rhs), result); }); }); describe('Number', () => { test.each([ [0, 0, true], [1, 1, true], [1, -1, false], [-1, -1, true], [3.1415, 3.1415, true], [3.1415, 3.141592, false], ['123', 123, true], ['1234', 123, false], ])('Number#%#', (lhsValue: number, rhsValue: number, result: boolean) => { const lhs = new Number(lhsValue); const rhs = new Number(rhsValue); assert.strictEqual(equal(lhs, rhs), result); }); }); describe('boolean', () => { test.each([ [false, false, true], [false, true, false], [true, false, false], [true, true, true], ])('boolean#%#', (lhs: boolean, rhs: boolean, result: boolean) => { assert.strictEqual(equal(lhs, rhs), result); }); }); describe('Boolean', () => { test.each([ [false, false, true], [false, true, false], [true, false, false], [true, true, true], ['', false, true], ['abc', false, false], ])('Boolean#%#', (lhsValue: boolean, rhsValue: boolean, result: boolean) => { const lhs = new Boolean(lhsValue); const rhs = new Boolean(rhsValue); assert.strictEqual(equal(lhs, rhs), result); }); }); describe('undefined', () => { it('undefined', () => { assert.isTrue(equal(undefined, undefined)); assert.isFalse(equal(undefined, null)); }); }); describe('null', () => { it('null', () => { assert.isTrue(equal(null, null)); assert.isFalse(equal(null, undefined)); }); }); describe('function', () => { it('function', () => { function add(a: number, b: number) { return a + b; } function mul(a: number, b: number) { return a * b; } assert.isTrue(equal(add, add)); assert.isFalse(equal(add, mul)); }); }); describe('Date', () => { const now = Date.now(); test.each([ [now, now, true], [now, now + 100, false], [now + 100, now, false], [now + 100, now + 100, true], ['1995-12-17T03:24:00', 'December 17, 1995 03:24:00', true], ['1995-12-17T03:24:00', 'December 17, 1995 03:24:01', false], ])('Date#%#', (lhsValue: any, rhsValue: any, result: boolean) => { const lhs = new Date(lhsValue); const rhs = new Date(rhsValue); assert.strictEqual(equal(lhs, rhs), result); }); }); describe('Array', () => { test.each([ [[], [], true], [[1, 2], [1, 2], true], [[1, 2], [2, 3], false], [[1, 2], [1, 2, 3], false], [[1, 2, 3], [1, 2], false], [[1, 'foo', { x: 1, y: 2 }], [1, 'foo', { x: 1, y: 2 }], true], [[1, 'foo', { x: 1, y: 2 }], [1, 'bar', { x: 1, y: 2 }], false], [[1, 'foo', { x: 1, y: 2 }], [1, 'foo', { x: 2, y: 3 }], false], [[[]], [], false], [[[]], [[]], true], [[[1, 2]], [[1, 2]], true], [[[2, 3]], [[1, 2]], false], ])('Array#%#', (lhs: any[], rhs: any[], result: boolean) => { assert.strictEqual(equal(lhs, rhs), result); }); }); describe('Object', () => { test.each([ [{}, {}, true], [{ 'a': 1 }, {}, false], [{}, { 'a': 1 }, false], [{ 'a': 1 }, { 'a': 1 }, true], [{ 'a': 1 }, { 'a': 2 }, false], [{ 'a': 1 }, { 'b': 1 }, false], [{ 'a': 1, 'b': 2 }, { 'a': 1 }, false], [{ 'a': 1, 'b': 2 }, { 'a': 1, 'b': 2 }, true], [{ 'a': 1, 'b': 2 }, { 'a': 1, 'b': 2, 'c': 3 }, false], [{ 'a': 1, 'b': 2, 'c': 3 }, { 'a': 1, 'b': 2, 'c': 3 }, true], [{ 'c': 3, 'a': 1, 'b': 2 }, { 'a': 1, 'b': 2, 'c': 3 }, true], [{ 'a': 1, 'c': 3, 'b': 2 }, { 'a': 1, 'b': 2, 'c': 3 }, true], [{ 'a': 1, 'b': 2, 'c': 3 }, { 'c': 3, 'a': 1, 'b': 2 }, true], [{ 'a': 1, 'b': 2, 'c': 3 }, { 'a': 1, 'c': 3, 'b': 2 }, true], [{ '1': 'a' }, { 1: 'a' }, true], [{ 1: 'a' }, { 1: 'a' }, true], [{ 'str': 'foo', 'arr': [1, 2, 3], 'num': 3.1415 }, { 'str': 'foo', 'arr': [1, 2, 3], 'num': 3.1415 }, true], [{ 'str': 'foo', 'arr': [1, 3, 2], 'num': 3.1415 }, { 'str': 'foo', 'arr': [1, 2, 3], 'num': 3.1415 }, false], [{ 'a': -1, 'b': -2, 'd': -4 }, { 'a': -1, 'b': -2, 'd': -4 }, true], ])('Object#%#', (lhs: any, rhs: any, result: boolean) => { assert.strictEqual(equal(lhs, rhs), result); }); }); describe('object', () => { test.each([ [{}, {}, true], [{ 'a': 1 }, {}, false], [{}, { 'a': 1 }, false], [{ 'a': 1 }, { 'a': 1 }, true], [{ 'a': 1 }, { 'a': 2 }, false], [{ 'a': 1 }, { 'b': 1 }, false], [{ 'a': 1, 'b': 2 }, { 'a': 1 }, false], [{ 'a': 1, 'b': 2 }, { 'a': 1, 'b': 2 }, true], [{ 'a': 1, 'b': 2 }, { 'a': 1, 'b': 2, 'c': 3 }, false], [{ 'a': 1, 'b': 2, 'c': 3 }, { 'a': 1, 'b': 2, 'c': 3 }, true], [{ 'c': 3, 'a': 1, 'b': 2 }, { 'a': 1, 'b': 2, 'c': 3 }, true], [{ 'a': 1, 'c': 3, 'b': 2 }, { 'a': 1, 'b': 2, 'c': 3 }, true], [{ 'a': 1, 'b': 2, 'c': 3 }, { 'c': 3, 'a': 1, 'b': 2 }, true], [{ 'a': 1, 'b': 2, 'c': 3 }, { 'a': 1, 'c': 3, 'b': 2 }, true], [{ '1': 'a' }, { 1: 'a' }, true], [{ 1: 'a' }, { 1: 'a' }, true], [{ 'str': 'foo', 'arr': [1, 2, 3], 'num': 3.1415 }, { 'str': 'foo', 'arr': [1, 2, 3], 'num': 3.1415 }, true], [{ 'str': 'foo', 'arr': [1, 3, 2], 'num': 3.1415 }, { 'str': 'foo', 'arr': [1, 2, 3], 'num': 3.1415 }, false], [{ 'a': -1, 'b': -2, 'd': -4 }, { 'a': -1, 'b': -2, 'd': -4 }, true], ])('object#%#', (lhsData: any, rhsData: any, result: boolean) => { const lhs = assign(create(), lhsData); const rhs = assign(create(), rhsData); assert.strictEqual(equal(lhs, rhs), result); }); }); describe('Map', () => { const p1 = { x: 1, y: 2 }; test.each([ [[], [], true], [[['a', 1]], [], false], [[], [['a', 1]], false], [[['a', 1]], [['a', 1]], true], [[['a', 1]], [['a', 2]], false], [[['a', 1]], [['b', 1]], false], [[['a', 1], ['b', 2]], [['a', 1]], false], [[['a', 1], ['b', 2]], [['a', 1], ['b', 2]], true], [[['a', 1], ['b', 2]], [['a', 1], ['b', 2], ['c', 3]], false], [[['a', 1], ['b', 2], ['c', 3]], [['a', 1], ['b', 2], ['c', 3]], true], [[['c', 3], ['a', 1], ['b', 2]], [['a', 1], ['b', 2], ['c', 3]], true], [[['a', 1], ['c', 3], ['b', 2]], [['a', 1], ['b', 2], ['c', 3]], true], [[['a', 1], ['b', 2], ['c', 3]], [['c', 3], ['a', 1], ['b', 2]], true], [[['a', 1], ['b', 2], ['c', 3]], [['a', 1], ['c', 3], ['b', 2]], true], [[[1, 'a']], [['1', 'a']], false], [[[1, 'a']], [[1, 'a']], true], [[['str', 'foo'], ['arr', [1, 2, 3]], ['num', 3.1415]], [['str', 'foo'], ['arr', [1, 2, 3]], ['num', 3.1415]], true], [[['str', 'foo'], ['arr', [1, 3, 2]], ['num', 3.1415]], [['str', 'foo'], ['arr', [1, 2, 3]], ['num', 3.1415]], false], [[['a', -1], ['b', -2], ['d', -4]], [['a', -1], ['b', -2], ['d', -4]], true], [[[1, 'a'], ['1', 'b']], [[1, 'a'], ['1', 'b']], true], [[[{ x: 1, y: 2 }, 3]], [[{ x: 1, y: 2 }, 3]], false], [[[p1, 3]], [[p1, 3]], true], ])('Map#%#', (lhsValue: [any, any][], rhsValue: [any, any][], result: boolean) => { const lhs = new Map(lhsValue); const rhs = new Map(rhsValue); assert.strictEqual(equal(lhs, rhs), result); }); }); describe('Set', () => { const p1 = { x: 1, y: 2 }; const p2 = { x: 3, y: 4 }; test.each([ [[], [], true], [[1], [], false], [[], [1], false], [[1], [1], true], [[1, 2, 3], [1, 2, 3], true], [[1, 2, 3], [3, 1, 2], true], [[1, 2, 3], [2, 3, 1], true], [[3, 1, 2], [1, 2, 3], true], [[2, 3, 1], [1, 2, 3], true], [[1, 2, 3], [1, 2, 2], false], [[1, 2, 3], [1, '2', 3], false], [[1, '2', 3], [1, '2', 3], true], [['a', 'b', 'c'], ['a', 'b', 'c'], true], [['a', 'b', 'c'], [], false], [[], ['a', 'b', 'c'], false], [[{ x: 1, y: 2 }], [{ x: 1, y: 2 }], false], [[p1], [p1], true], [[p1, p2], [p2, p1], true], ])('Set#%#', (lhsValue: any[], rhsValue: any[], result: boolean) => { const lhs = new Set(lhsValue); const rhs = new Set(rhsValue); assert.strictEqual(equal(lhs, rhs), result); }); }); describe('TypedArrays', () => { describe('Uint8Array', () => { test.each([ [[], [], true], [[21, 31], [21, 31], true], [[21, 31], [22, 31], false], [[22, 31], [21, 31], false], [[21, 31], [21, 31, 41], false], [[21, 31, 41], [21, 31], false], [[21, 31, 41], [21, 31, 41], true], ])('Uint8Array#%#', (lhsValue: number[], rhsValue: number[], result: boolean) => { const lhs = new Uint8Array(lhsValue); const rhs = new Uint8Array(rhsValue); assert.strictEqual(equal(lhs, rhs), result); }); }); }); });