import {Suite, expect} from "cynic" import {Signal} from "./signal.js" import {SignalTower} from "./tower.js" export default { "standalone signals": { "we can change a value": async() => { const signal = new Signal(0) expect(signal.value).equals(0) signal.value++ expect(signal.value).equals(1) signal.value++ expect(signal.value).equals(2) }, "we can subscribe to a signal": async() => { const signal = new Signal(0) let calls = 0 signal.subscribe(() => calls++) signal.value++ await signal.wait expect(calls).equals(1) }, "we can stop a subscription": async() => { const signal = new Signal(0) let calls = 0 const untrack = signal.subscribe(() => calls++) signal.value++ await signal.wait expect(calls).equals(1) untrack() signal.value++ await signal.wait expect(calls).equals(1) }, "changes to signal values are debounced": async() => { const signal = new Signal(0) let calls = 0 signal.subscribe(() => calls++) signal.value++ signal.value++ await signal.wait expect(calls).equals(1) }, "we can wait for debounced signals": async() => { const signal = new Signal(0) let calls = 0 signal.subscribe(() => calls++) signal.value++ signal.value++ expect(calls).equals(0) await signal.wait expect(calls).equals(1) }, }, "signal tower": { "tower can track multiple signals": async() => { const tower = new SignalTower() const alpha = tower.signal(0) const bravo = tower.signal(0) let calls = 0 tower.reaction( () => { void alpha.value void bravo.value }, () => calls++, ) expect(calls).equals(0) alpha.value++ await tower.wait expect(calls).equals(1) bravo.value++ await tower.wait expect(calls).equals(2) }, "tower can track signals progressively": async() => { const tower = new SignalTower() const alpha = tower.signal(0) const bravo = tower.signal(0) let calls = 0 tower.reaction( () => { if (alpha.value > 0) void bravo.value }, () => calls++, ) expect(calls).equals(0) bravo.value++ await tower.wait expect(calls).equals(0) alpha.value++ await tower.wait expect(calls).equals(1) bravo.value++ await tower.wait expect(calls).equals(2) }, "tower can wait for ongoing publishing": async() => { const tower = new SignalTower() const count = tower.signal(0) let calls = 0 tower.reaction( () => void count.value, () => calls++, ) expect(calls).equals(0) count.value++ await tower.wait expect(calls).equals(1) }, "tower track passes payload": async() => { const tower = new SignalTower() const count = tower.signal(1) let reaction = 0 tower.reaction( () => count.value * 2, doubled => reaction = doubled, ) count.value = 5 await tower.wait expect(reaction).equals(10) count.value = 10 await tower.wait expect(reaction).equals(20) }, "tower track with single argument syntax": async() => { const tower = new SignalTower() const count = tower.signal(0) let calls = 0 tower.reaction(() => { void count.value calls++ }) expect(calls).equals(1) count.value++ await tower.wait expect(calls).equals(2) }, "computed values are updated": async() => { const tower = new SignalTower() const count = tower.signal(1) const doubled = tower.computed(() => count.value * 2) let count_calls = 0 let doubled_calls = 0 tower.reaction(() => { void count.value count_calls++ }) tower.reaction(() => { void doubled.value doubled_calls++ }) await tower.wait expect(count.value).equals(1) expect(doubled.value).equals(2) expect(count_calls).equals(1) expect(doubled_calls).equals(1) count.value = 5 await tower.wait expect(count.value).equals(5) expect(doubled.value).equals(10) expect(count_calls).equals(2) expect(doubled_calls).equals(2) }, "lean tracking": async() => { const tower = new SignalTower() const alpha = tower.signal(0) let collector_calls = 0 let responder_calls = 0 const collect = () => { void alpha.value collector_calls++ } const lean = tower.lean(() => responder_calls++) expect(collector_calls).equals(0) expect(responder_calls).equals(0) lean.collect(collect) expect(collector_calls).equals(1) expect(responder_calls).equals(0) alpha.value++ await tower.wait expect(collector_calls).equals(1) expect(responder_calls).equals(1) alpha.value++ await tower.wait expect(collector_calls).equals(1) expect(responder_calls).equals(2) }, }, }