forked from Expensify/react-native-onyx
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathmemoizedShallowEqualTest.ts
More file actions
76 lines (63 loc) · 3.33 KB
/
Copy pathmemoizedShallowEqualTest.ts
File metadata and controls
76 lines (63 loc) · 3.33 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
import memoizedShallowEqual from '../../lib/memoizedShallowEqual';
describe('memoizedShallowEqual', () => {
describe('shallowEqual semantics', () => {
it('should return true for the same reference', () => {
const obj = {a: 1};
expect(memoizedShallowEqual(obj, obj)).toBe(true);
});
it('should return true for different references with shallowly-equal content', () => {
const member = {name: 'John'};
expect(memoizedShallowEqual({a: 1, member}, {a: 1, member})).toBe(true);
});
it('should return false when a top-level value differs', () => {
expect(memoizedShallowEqual({a: 1}, {a: 2})).toBe(false);
});
it('should return false when key counts differ', () => {
expect(memoizedShallowEqual({a: 1}, {a: 1, b: 2})).toBe(false);
});
it('should return false for equal deep content with different nested references', () => {
// Shallow, not deep: nested objects are compared by reference.
expect(memoizedShallowEqual({member: {name: 'John'}}, {member: {name: 'John'}})).toBe(false);
});
it('should handle non-object inputs', () => {
expect(memoizedShallowEqual(undefined, undefined)).toBe(true);
expect(memoizedShallowEqual(undefined, {})).toBe(false);
expect(memoizedShallowEqual('a', 'a')).toBe(true);
expect(memoizedShallowEqual('a', 'b')).toBe(false);
expect(memoizedShallowEqual(1, 1)).toBe(true);
expect(memoizedShallowEqual(NaN, NaN)).toBe(true);
});
it('should handle arrays', () => {
expect(memoizedShallowEqual([1, 2], [1, 2])).toBe(true);
expect(memoizedShallowEqual([1, 2], [1, 3])).toBe(false);
});
});
describe('memoization', () => {
it('should return the cached verdict for the same object pair without re-comparing', () => {
const a = {name: 'John'};
const b = {name: 'Jane'};
expect(memoizedShallowEqual(a, b)).toBe(false);
// Mutate `b` so the objects are now content-equal. Onyx values are immutable,
// so the memo is expected to keep returning the verdict computed for this exact
// (a, b) pair — proving the second call resolved from the cache, not a re-compare.
b.name = 'John';
expect(memoizedShallowEqual(a, b)).toBe(false);
});
it('should cache verdicts per pair, not per object', () => {
const a = {x: 1};
const equalToA = {x: 1};
const differentFromA = {x: 2};
expect(memoizedShallowEqual(a, equalToA)).toBe(true);
expect(memoizedShallowEqual(a, differentFromA)).toBe(false);
// Both verdicts are retained independently for the same `a`.
expect(memoizedShallowEqual(a, equalToA)).toBe(true);
expect(memoizedShallowEqual(a, differentFromA)).toBe(false);
});
it('should not memoize non-object inputs', () => {
// Primitives cannot be WeakMap keys; these calls must not throw and must compare directly.
expect(memoizedShallowEqual(1, {})).toBe(false);
expect(memoizedShallowEqual({}, 1)).toBe(false);
expect(memoizedShallowEqual(null, null)).toBe(true);
});
});
});