Skip to content

Commit

Permalink
feat: add tests demonstrating before vs after behavior by allowing th…
Browse files Browse the repository at this point in the history
…e default compare logic to customizable
  • Loading branch information
sghoweri committed Sep 26, 2022
1 parent 31a0a01 commit 5067445
Showing 1 changed file with 44 additions and 0 deletions.
44 changes: 44 additions & 0 deletions packages/core/test/signal.test.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { signal, computed, effect, batch, Signal } from "@preact/signals-core";
import fastEqual from "fast-deep-equal/es6";

describe("signal", () => {
it("should return value", () => {
Expand Down Expand Up @@ -1711,4 +1712,47 @@ describe("batch/transaction", () => {
});
expect(callCount).to.equal(1);
});

it("allows customizing the default shouldUpdate compare method", () => {
const mapA = new Map<string, string>();
const a = signal(mapA);
const spy1 = sinon.spy(() => a.value);
effect(spy1);

// before: re-renders every time, even if the value doesn't change
a.value = new Map(a.peek()).set("foo", "bar");
a.value = new Map(a.peek()).set("foo", "baz");
a.value = new Map(a.peek()).set("foo", "baz");
a.value = new Map(a.peek()).set("foo", "baz");

// should have been called twice but instead re-renders regardless on value pass in (without specifying a custom shouldUpdate method)
expect(spy1.callCount).to.equal(5);

Signal.prototype.shouldUpdate = (oldValue, newValue) => {
if (oldValue instanceof Map && newValue instanceof Map) {
return fastEqual(oldValue, newValue) === false;
}
return oldValue !== newValue;
};

function signal2<T>(value: T): Signal<T> {
return new Signal(value);
}

const mapB = new Map<string, string>();
const b = signal2(mapB);
const spy2 = sinon.spy(() => b.value);
effect(spy2);

// after: only re-renders if the value changes (via custom shouldUpdate method)
b.value = new Map(b.peek()).set("foo", "bar");
b.value = new Map(b.peek()).set("foo", "baz");
b.value = new Map(b.peek()).set("foo", "baz");
b.value = new Map(b.peek()).set("foo", "baz");

// setting up the initial empty Map --> update #1
// adding foo, bar to empty map --> update #2
// updating foo, bar to foo, baz --> update #3
expect(spy2.callCount).to.equal(3);
});
});

0 comments on commit 5067445

Please sign in to comment.