Skip to content

Commit 5067445

Browse files
committed
feat: add tests demonstrating before vs after behavior by allowing the default compare logic to customizable
1 parent 31a0a01 commit 5067445

File tree

1 file changed

+44
-0
lines changed

1 file changed

+44
-0
lines changed

packages/core/test/signal.test.tsx

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { signal, computed, effect, batch, Signal } from "@preact/signals-core";
2+
import fastEqual from "fast-deep-equal/es6";
23

34
describe("signal", () => {
45
it("should return value", () => {
@@ -1711,4 +1712,47 @@ describe("batch/transaction", () => {
17111712
});
17121713
expect(callCount).to.equal(1);
17131714
});
1715+
1716+
it("allows customizing the default shouldUpdate compare method", () => {
1717+
const mapA = new Map<string, string>();
1718+
const a = signal(mapA);
1719+
const spy1 = sinon.spy(() => a.value);
1720+
effect(spy1);
1721+
1722+
// before: re-renders every time, even if the value doesn't change
1723+
a.value = new Map(a.peek()).set("foo", "bar");
1724+
a.value = new Map(a.peek()).set("foo", "baz");
1725+
a.value = new Map(a.peek()).set("foo", "baz");
1726+
a.value = new Map(a.peek()).set("foo", "baz");
1727+
1728+
// should have been called twice but instead re-renders regardless on value pass in (without specifying a custom shouldUpdate method)
1729+
expect(spy1.callCount).to.equal(5);
1730+
1731+
Signal.prototype.shouldUpdate = (oldValue, newValue) => {
1732+
if (oldValue instanceof Map && newValue instanceof Map) {
1733+
return fastEqual(oldValue, newValue) === false;
1734+
}
1735+
return oldValue !== newValue;
1736+
};
1737+
1738+
function signal2<T>(value: T): Signal<T> {
1739+
return new Signal(value);
1740+
}
1741+
1742+
const mapB = new Map<string, string>();
1743+
const b = signal2(mapB);
1744+
const spy2 = sinon.spy(() => b.value);
1745+
effect(spy2);
1746+
1747+
// after: only re-renders if the value changes (via custom shouldUpdate method)
1748+
b.value = new Map(b.peek()).set("foo", "bar");
1749+
b.value = new Map(b.peek()).set("foo", "baz");
1750+
b.value = new Map(b.peek()).set("foo", "baz");
1751+
b.value = new Map(b.peek()).set("foo", "baz");
1752+
1753+
// setting up the initial empty Map --> update #1
1754+
// adding foo, bar to empty map --> update #2
1755+
// updating foo, bar to foo, baz --> update #3
1756+
expect(spy2.callCount).to.equal(3);
1757+
});
17141758
});

0 commit comments

Comments
 (0)