@benev/slate
Version:
frontend web stuff
155 lines • 5.24 kB
JavaScript
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