Skip to content

Commit f026095

Browse files
authored
Merge pull request #704 from streamich/fix-array-check
Improve deep equals array checks
2 parents 511e927 + 4f2c7d1 commit f026095

File tree

5 files changed

+54
-19
lines changed

5 files changed

+54
-19
lines changed

src/json-equal/__bench__/bench.deepEqual.ts

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
1+
// npx ts-node src/json-equal/__bench__/bench.deepEqual.ts
2+
13
/* tslint:disable no-console */
24

35
import * as Benchmark from 'benchmark';
46
import {deepEqual as deepEqualV1} from '../deepEqual/v1';
57
import {deepEqual as deepEqualV2} from '../deepEqual/v2';
68
import {deepEqual as deepEqualV3} from '../deepEqual/v3';
7-
import {deepEqual as deepEqualV4} from '../deepEqual/v3';
9+
import {deepEqual as deepEqualV4} from '../deepEqual/v4';
10+
import {deepEqual as deepEqualV5} from '../deepEqual/v5';
811
import {$$deepEqual} from '../$$deepEqual';
9-
const fastDeepEqual = require('fast-deep-equal/es6');
10-
const fastEquals = require('fast-equals').deepEqual;
11-
const lodashIsEqual = require('lodash').isEqual;
1212

1313
const json1 = {
1414
foo: 'bar',
@@ -39,14 +39,8 @@ suite
3939
.add(`json-joy/json-equal (v4)`, () => {
4040
deepEqualV4(json1, json2);
4141
})
42-
.add(`fast-deep-equal`, () => {
43-
fastDeepEqual(json1, json2);
44-
})
45-
.add(`fast-equals`, () => {
46-
fastEquals(json1, json2);
47-
})
48-
.add(`lodash.isEqual`, () => {
49-
lodashIsEqual(json1, json2);
42+
.add(`json-joy/json-equal (v5)`, () => {
43+
deepEqualV5(json1, json2);
5044
})
5145
.add(`json-joy/json-equal/$$deepEqual`, () => {
5246
equalGenerated1(json2);

src/json-equal/deepEqual/__tests__/deepEqual.fuzzing.spec.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,14 @@ for (let i = 0; i < 100; i++) {
99
const res1 = deepEqual(json1, json1);
1010
const res2 = deepEqual(json1, json2);
1111
const res3 = deepEqual(json2, json1);
12-
expect(res1).toBe(true);
13-
expect(res2).toBe(true);
14-
expect(res3).toBe(true);
12+
try {
13+
expect(res1).toBe(true);
14+
expect(res2).toBe(true);
15+
expect(res3).toBe(true);
16+
} catch (error) {
17+
// tslint:disable-next-line no-console
18+
console.log({json1, json2});
19+
throw error;
20+
}
1521
});
1622
}

src/json-equal/deepEqual/__tests__/runDeepEqualTestSuite.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,13 @@ export const runDeepEqualTestSuite = (deepEqual: (a: unknown, b: unknown) => boo
66
for (const t of s.tests) {
77
test(t.description, () => {
88
const res1 = deepEqual(t.value1, t.value2);
9-
const res2 = deepEqual(t.value1, t.value2);
10-
expect(res1).toBe(t.equal);
11-
expect(res2).toBe(t.equal);
9+
const res2 = deepEqual(t.value2, t.value1);
10+
try {
11+
expect(res1).toBe(t.equal);
12+
expect(res2).toBe(t.equal);
13+
} catch (error) {
14+
throw error;
15+
}
1216
});
1317
}
1418
});

src/json-equal/deepEqual/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
export * from './v1';
1+
export * from './v5';

src/json-equal/deepEqual/v5.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
const isArray = Array.isArray;
2+
3+
export const deepEqual = (a: unknown, b: unknown): boolean => {
4+
// Primitives
5+
if (a === b) return true;
6+
7+
// Arrays
8+
let length, i, keys;
9+
if (isArray(a)) {
10+
if (!isArray(b)) return false;
11+
length = a.length;
12+
if (length !== (b as Array<unknown>).length) return false;
13+
for (i = length; i-- !== 0; ) if (!deepEqual(a[i], (b as Array<unknown>)[i])) return false;
14+
return true;
15+
}
16+
17+
// Objects
18+
if (a && b && typeof a === 'object' && typeof b === 'object') {
19+
keys = Object.keys(a);
20+
length = keys.length;
21+
if (length !== Object.keys(b).length) return false;
22+
if (isArray(b)) return false;
23+
for (i = length; i-- !== 0; ) {
24+
const key = keys[i];
25+
if (!deepEqual((a as Record<string, unknown>)[key], (b as Record<string, unknown>)[key])) return false;
26+
}
27+
return true;
28+
}
29+
30+
return false;
31+
};

0 commit comments

Comments
 (0)