Skip to content

Commit 838acbe

Browse files
committed
Adding tests: avoid recomputing when not needed (back to previous value)
1 parent 2dd56f8 commit 838acbe

File tree

2 files changed

+68
-0
lines changed

2 files changed

+68
-0
lines changed

tests/Signal/computed.test.ts

+31
Original file line numberDiff line numberDiff line change
@@ -71,4 +71,35 @@ describe('Computed', () => {
7171
expect(calls).toBe(2);
7272
});
7373
});
74+
75+
it('should not recompute when the dependent values go back to the ones used for last computation', () => {
76+
const s = new Signal.State(0);
77+
let n = 0;
78+
const c = new Signal.Computed(() => (n++, s.get()));
79+
expect(n).toBe(0);
80+
expect(c.get()).toBe(0);
81+
expect(n).toBe(1);
82+
s.set(1);
83+
expect(n).toBe(1);
84+
s.set(0);
85+
expect(n).toBe(1);
86+
expect(c.get()).toBe(0); // the last time c was computed was with s = 0, no need to recompute
87+
expect(n).toBe(1);
88+
});
89+
90+
it('should not recompute when the dependent values go back to the ones used for last computation (with extra computed)', () => {
91+
const s = new Signal.State(0);
92+
let n = 0;
93+
const extra = new Signal.Computed(() => s.get());
94+
const c = new Signal.Computed(() => (n++, extra.get()));
95+
expect(n).toBe(0);
96+
expect(c.get()).toBe(0);
97+
expect(n).toBe(1);
98+
s.set(1);
99+
expect(n).toBe(1);
100+
s.set(0);
101+
expect(n).toBe(1);
102+
expect(c.get()).toBe(0); // the last time c was computed was with s = 0, no need to recompute
103+
expect(n).toBe(1);
104+
});
74105
});

tests/behaviors/custom-equality.test.ts

+37
Original file line numberDiff line numberDiff line change
@@ -105,4 +105,41 @@ describe('Custom equality', () => {
105105
expect(outerFn).toBeCalledTimes(2);
106106
expect(cutoff).toBeCalledTimes(2);
107107
});
108+
109+
it('should not call equal multiple times for the same comparison', () => {
110+
let equalCalls: [number, number][] = [];
111+
const equals = (a: number, b: number) => {
112+
equalCalls.push([a, b]);
113+
return a === b;
114+
};
115+
const s = new Signal.State<number>(0, {equals});
116+
let n1 = 0;
117+
let n2 = 0;
118+
const c1 = new Signal.Computed(() => (n1++, s.get()));
119+
const c2 = new Signal.Computed(() => (n2++, s.get()));
120+
expect(equalCalls).toEqual([]);
121+
expect(n1).toBe(0);
122+
expect(c1.get()).toBe(0);
123+
expect(n1).toBe(1);
124+
expect(n2).toBe(0);
125+
expect(c2.get()).toBe(0);
126+
expect(n2).toBe(1);
127+
s.set(1);
128+
expect(equalCalls).toEqual([[0, 1]]);
129+
equalCalls = [];
130+
expect(n1).toBe(1);
131+
expect(n2).toBe(1);
132+
s.set(0);
133+
expect(equalCalls).toEqual([[1, 0]]);
134+
equalCalls = [];
135+
expect(n1).toBe(1);
136+
expect(n2).toBe(1);
137+
expect(c1.get()).toBe(0); // the last time c1 was computed was with s = 0, no need to recompute
138+
expect(equalCalls).toEqual([[0, 0]]); // equal should have been called
139+
equalCalls = [];
140+
expect(c2.get()).toBe(0); // the last time c2 was computed was with s = 0, no need to recompute
141+
expect(equalCalls).toEqual([]); // equal should not have been called again
142+
expect(n1).toBe(1);
143+
expect(n2).toBe(1);
144+
});
108145
});

0 commit comments

Comments
 (0)