Skip to content

Commit 1d83254

Browse files
committed
Fix [undefined] vs. []
1 parent 89dd333 commit 1d83254

File tree

2 files changed

+56
-11
lines changed

2 files changed

+56
-11
lines changed
Lines changed: 46 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,48 @@
1-
import { expect, test } from '@jest/globals';
1+
import { beforeEach, describe, expect, test } from '@jest/globals';
22
import iterateEquals from './iterateEquals';
33

4-
test('comparing empty arrays', () => expect(iterateEquals([].values(), [].values())).toBe(true));
5-
test('comparing different arrays', () => expect(iterateEquals([1].values(), [2].values())).toBe(false));
6-
test('comparing bigger array to smaller array', () => expect(iterateEquals([1, 2].values(), [1].values())).toBe(false));
7-
test('comparing smaller array to bigger array', () => expect(iterateEquals([1].values(), [1, 2].values())).toBe(false));
8-
test('comparing non-empty array to empty array', () => expect(iterateEquals([1].values(), [].values())).toBe(false));
9-
test('comparing empty array to non-empty array', () => expect(iterateEquals([].values(), [1].values())).toBe(false));
4+
const iterateEqualsFlip: typeof iterateEquals = (x, y) => iterateEquals(y, x);
5+
6+
describe.each([['normal'], ['flip']])('with %s order', mode => {
7+
let fn: typeof iterateEqualsFlip;
8+
9+
beforeEach(() => {
10+
fn = mode === 'normal' ? iterateEquals : iterateEqualsFlip;
11+
});
12+
13+
test('should throw on same iterator instance', () => {
14+
const iterator = [1, 2, 3].values();
15+
16+
expect(() => fn(iterator, iterator)).toThrow();
17+
});
18+
19+
test('should return true on same iterable instance', () => {
20+
const iterator = [1, 2, 3];
21+
22+
expect(fn(iterator, iterator)).toBe(true);
23+
});
24+
25+
test('should return true on same value', () => {
26+
expect(fn([1, 2, 3].values(), [1, 2, 3].values())).toBe(true);
27+
});
28+
29+
test('should return false on shorter start', () => {
30+
expect(fn([1, 2, 3].values(), [2, 3].values())).toBe(false);
31+
});
32+
33+
test('should return false on shorter end', () => {
34+
expect(fn([1, 2, 3].values(), [1, 2].values())).toBe(false);
35+
});
36+
37+
test('should return false against empty array', () => {
38+
expect(fn([1, 2, 3].values(), [].values())).toBe(false);
39+
});
40+
41+
test('undefined should be treated as an element', () => {
42+
expect(fn([].values(), [undefined].values())).toBe(false);
43+
});
44+
45+
test('null should be treated as an element', () => {
46+
expect(fn([].values(), [null].values())).toBe(false);
47+
});
48+
});

packages/base/src/utils/iterateEquals.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,21 @@ export default function iterateEquals<T>(x: Iterable<T>, y: Iterable<T>): boolea
44
const xIterator = x[Symbol.iterator]();
55
const yIterator = y[Symbol.iterator]();
66

7+
if (Object.is(xIterator, yIterator)) {
8+
throw new Error('Must not pass same instance twice');
9+
}
10+
11+
// eslint-disable-next-line no-magic-numbers
712
for (let count = 0; count < MAX_ITERATION; count++) {
813
const resultX = xIterator.next();
914
const resultY = yIterator.next();
1015

11-
if (resultX.done && resultY.done) {
12-
return true;
13-
}
16+
const { done: xDone } = resultX;
17+
const { done: yDone } = resultY;
1418

15-
if (!Object.is(resultX.value, resultY.value)) {
19+
if (xDone && yDone) {
20+
return true;
21+
} else if (xDone || yDone || !Object.is(resultX.value, resultY.value)) {
1622
break;
1723
}
1824
}

0 commit comments

Comments
 (0)