UNPKG

@benev/slate

Version:
155 lines 5.24 kB
import { expect } from "cynic"; import { WatchTower } from "./tower.js"; import { SignalTower } from "../signals/tower.js"; function setup() { const signals = new SignalTower(); const watch = new WatchTower(signals); const tree = watch.stateTree({ count: 0, group: { greeting: "hello", active: false, }, }); return { watch, tree }; } export default { "we can read state": async () => { const { tree } = setup(); expect(tree.state.count).equals(0); expect(tree.state.group.greeting).equals("hello"); }, "we can change state via transmute": async () => { const { tree } = setup(); expect(tree.state.count).equals(0); tree.transmute(state => { state.count++; state.group.greeting = "bonjour"; return state; }); expect(tree.state.count).equals(1); expect(tree.state.group.greeting).equals("bonjour"); }, "we cannot change state outside transmute": async () => { const { tree } = setup(); expect(tree.state.count).equals(0); expect(() => { tree.state.count++; }).throws(); expect(tree.state.count).equals(0); }, "we can track changes to state": async () => { const { watch, tree } = setup(); let calls = 0; let lastCount = 0; watch.track(() => tree.state.count, count => { calls++; lastCount = count; }); expect(calls).equals(1); expect(lastCount).equals(0); tree.transmute(state => { state.count++; return state; }); await watch.wait; expect(calls).equals(2); expect(lastCount).equals(1); }, "we can unsubscribe from a track to stop listening": async () => { const { watch, tree } = setup(); let calls = 0; let lastCount = 0; const untrack = watch.track(() => tree.state.count, count => { calls++; lastCount = count; }); expect(calls).equals(1); expect(lastCount).equals(0); untrack(); tree.transmute(state => { state.count++; return state; }); expect(calls).equals(1); expect(lastCount).equals(0); }, "we can track changes to specific state": async () => { const { watch, tree } = setup(); let updates_for_count = 0; let updates_for_greeting = 0; let updates_for_active = 0; let updates_for_group = 0; watch.track(() => tree.state.count, () => { updates_for_count++; }); watch.track(() => tree.state.group.greeting, () => { updates_for_greeting++; }); watch.track(() => tree.state.group.active, () => { updates_for_active++; }); watch.track(() => tree.state.group, () => { updates_for_group++; }); function reset_counters() { updates_for_count = 0; updates_for_greeting = 0; updates_for_active = 0; updates_for_group = 0; } reset_counters(); tree.transmute(state => { state.count++; return state; }); await watch.wait; expect(updates_for_count).equals(1); expect(updates_for_greeting).equals(0); expect(updates_for_active).equals(0); expect(updates_for_group).equals(0); reset_counters(); tree.transmute(state => { state.group.greeting = "bonjour"; return state; }); await watch.wait; expect(updates_for_count).equals(0); expect(updates_for_greeting).equals(1); expect(updates_for_active).equals(0); expect(updates_for_group).equals(1); reset_counters(); tree.transmute(state => { state.group.active = true; return state; }); await watch.wait; expect(updates_for_count).equals(0); expect(updates_for_greeting).equals(0); expect(updates_for_active).equals(1); expect(updates_for_group).equals(1); }, "we can make slices of the state": async () => { const { tree, watch } = setup(); let calls_alpha = 0; watch.track(() => tree.state.group.greeting, () => { calls_alpha++; }); expect(calls_alpha).equals(1); const slice = tree.slice({ getter: (state) => state.group, setter: (state, group) => { state.group = group; return state; }, }); let calls_bravo = 0; watch.track(() => slice.state.greeting, () => { calls_bravo++; }); expect(calls_bravo).equals(1); slice.transmute(state => { state.greeting = "bonjour"; return state; }); await watch.wait; expect(calls_alpha).equals(2); expect(calls_bravo).equals(2); tree.transmute(state => { state.group.greeting = "hola"; return state; }); await watch.wait; expect(calls_alpha).equals(3); expect(calls_bravo).equals(3); }, }; //# sourceMappingURL=watch.test.js.map