Skip to content

Commit 30211ee

Browse files
authored
Merge pull request #11 from proposal-signals/reorganize-tests
Reorganize and split tests
2 parents c01bdd3 + 64fe8d8 commit 30211ee

17 files changed

+1062
-1053
lines changed

src/wrapper.spec.ts

-1,052
This file was deleted.

tests/Signal/computed.test.ts

+74
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import { describe, expect, it } from "vitest";
2+
import { Signal } from "../../src/wrapper.js";
3+
4+
describe("Computed", () => {
5+
it("should work", () => {
6+
const stateSignal = new Signal.State(1);
7+
8+
const computedSignal = new Signal.Computed(() => {
9+
const f = stateSignal.get() * 2;
10+
return f;
11+
});
12+
13+
expect(computedSignal.get()).toEqual(2);
14+
15+
stateSignal.set(5);
16+
17+
expect(stateSignal.get()).toEqual(5);
18+
expect(computedSignal.get()).toEqual(10);
19+
});
20+
21+
describe("Comparison semantics", () => {
22+
it("should track Computed by Object.is", () => {
23+
const state = new Signal.State(1);
24+
let value = 5;
25+
let calls = 0;
26+
const computed = new Signal.Computed(() => (state.get(), value));
27+
const c2 = new Signal.Computed(() => (calls++, computed.get()));
28+
29+
expect(calls).toBe(0);
30+
expect(c2.get()).toBe(5);
31+
expect(calls).toBe(1);
32+
state.set(2);
33+
expect(c2.get()).toBe(5);
34+
expect(calls).toBe(1);
35+
value = NaN;
36+
expect(c2.get()).toBe(5);
37+
expect(calls).toBe(1);
38+
state.set(3);
39+
expect(c2.get()).toBe(NaN);
40+
expect(calls).toBe(2);
41+
state.set(4);
42+
expect(c2.get()).toBe(NaN);
43+
expect(calls).toBe(2);
44+
});
45+
46+
it("applies custom equality in Computed", () => {
47+
const s = new Signal.State(5);
48+
let ecalls = 0;
49+
const c1 = new Signal.Computed(() => (s.get(), 1), {
50+
equals() {
51+
ecalls++;
52+
return false;
53+
},
54+
});
55+
let calls = 0;
56+
const c2 = new Signal.Computed(() => {
57+
calls++;
58+
return c1.get();
59+
});
60+
61+
expect(calls).toBe(0);
62+
expect(ecalls).toBe(0);
63+
64+
expect(c2.get()).toBe(1);
65+
expect(ecalls).toBe(0);
66+
expect(calls).toBe(1);
67+
68+
s.set(10);
69+
expect(c2.get()).toBe(1);
70+
expect(ecalls).toBe(1);
71+
expect(calls).toBe(2);
72+
});
73+
});
74+
});

tests/Signal/state.test.ts

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import { describe, expect, it } from "vitest";
2+
import { Signal } from "../../src/wrapper.js";
3+
4+
describe("Signal.State", () => {
5+
it("should work", () => {
6+
const stateSignal = new Signal.State(0);
7+
expect(stateSignal.get()).toEqual(0);
8+
9+
stateSignal.set(10);
10+
11+
expect(stateSignal.get()).toEqual(10);
12+
});
13+
14+
describe("Comparison semantics", () => {
15+
it("should cache State by Object.is", () => {
16+
const state = new Signal.State(NaN);
17+
let calls = 0;
18+
const computed = new Signal.Computed(() => {
19+
calls++;
20+
return state.get();
21+
});
22+
expect(calls).toBe(0);
23+
expect(computed.get()).toBe(NaN);
24+
expect(calls).toBe(1);
25+
state.set(NaN);
26+
expect(computed.get()).toBe(NaN);
27+
expect(calls).toBe(1);
28+
});
29+
30+
it("applies custom equality in State", () => {
31+
let ecalls = 0;
32+
const state = new Signal.State(1, {
33+
equals() {
34+
ecalls++;
35+
return false;
36+
},
37+
});
38+
let calls = 0;
39+
const computed = new Signal.Computed(() => {
40+
calls++;
41+
return state.get();
42+
});
43+
44+
expect(calls).toBe(0);
45+
expect(ecalls).toBe(0);
46+
47+
expect(computed.get()).toBe(1);
48+
expect(ecalls).toBe(0);
49+
expect(calls).toBe(1);
50+
51+
state.set(1);
52+
expect(computed.get()).toBe(1);
53+
expect(ecalls).toBe(1);
54+
expect(calls).toBe(2);
55+
});
56+
});
57+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { describe, expect, it } from "vitest";
2+
import { Signal } from "../../../src/wrapper.js";
3+
4+
describe("currentComputed", () => {
5+
it("works", () => {
6+
expect(Signal.subtle.currentComputed()).toBe(undefined);
7+
let context;
8+
let c = new Signal.Computed(
9+
() => (context = Signal.subtle.currentComputed()),
10+
);
11+
c.get();
12+
expect(c).toBe(context);
13+
});
14+
});

tests/Signal/subtle/untrack.test.ts

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { describe, expect, it } from "vitest";
2+
import { Signal } from "../../../src/wrapper.js";
3+
4+
describe("Untrack", () => {
5+
it("works", () => {
6+
const state = new Signal.State(1);
7+
const computed = new Signal.Computed(() =>
8+
Signal.subtle.untrack(() => state.get()),
9+
);
10+
expect(computed.get()).toBe(1);
11+
state.set(2);
12+
expect(computed.get()).toBe(1);
13+
});
14+
15+
it("works differently without untrack", () => {
16+
const state = new Signal.State(1);
17+
const computed = new Signal.Computed(() => state.get());
18+
expect(computed.get()).toBe(1);
19+
state.set(2);
20+
expect(computed.get()).toBe(2);
21+
});
22+
});
+163
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
import { describe, expect, it } from "vitest";
2+
import { Signal } from "../../../src/wrapper.js";
3+
4+
describe("watch and unwatch", () => {
5+
it("handles multiple watchers well", () => {
6+
const s = new Signal.State(1);
7+
const s2 = new Signal.State(2);
8+
let n = 0;
9+
const w = new Signal.subtle.Watcher(() => n++);
10+
w.watch(s, s2);
11+
12+
s.set(4);
13+
expect(n).toBe(1);
14+
expect(w.getPending()).toStrictEqual([]);
15+
16+
w.watch();
17+
s2.set(8);
18+
expect(n).toBe(2);
19+
20+
w.unwatch(s);
21+
s.set(3);
22+
expect(n).toBe(2);
23+
24+
w.watch();
25+
s2.set(3);
26+
expect(n).toBe(3);
27+
28+
w.watch();
29+
s.set(2);
30+
expect(n).toBe(3);
31+
});
32+
it("understands dynamic dependency sets", () => {
33+
let w1 = 0,
34+
u1 = 0,
35+
w2 = 0,
36+
u2 = 0,
37+
n = 0,
38+
d = 0;
39+
let s1 = new Signal.State(1, {
40+
[Signal.subtle.watched]() {
41+
w1++;
42+
},
43+
[Signal.subtle.unwatched]() {
44+
u1++;
45+
},
46+
});
47+
let s2 = new Signal.State(2, {
48+
[Signal.subtle.watched]() {
49+
w2++;
50+
},
51+
[Signal.subtle.unwatched]() {
52+
u2++;
53+
},
54+
});
55+
let which: { get(): number } = s1;
56+
let c = new Signal.Computed(() => (d++, which.get()));
57+
let w = new Signal.subtle.Watcher(() => n++);
58+
59+
w.watch(c);
60+
expect(w1 + w2 + u1 + u2 + n + d).toBe(0);
61+
expect(Signal.subtle.hasSinks(s1)).toBe(false);
62+
expect(Signal.subtle.hasSinks(s2)).toBe(false);
63+
expect(w.getPending()).toStrictEqual([c]);
64+
65+
expect(c.get()).toBe(1);
66+
expect(w1).toBe(1);
67+
expect(u1).toBe(0);
68+
expect(w2).toBe(0);
69+
expect(u2).toBe(0);
70+
expect(n).toBe(0);
71+
expect(Signal.subtle.hasSinks(s1)).toBe(true);
72+
expect(Signal.subtle.hasSinks(s2)).toBe(false);
73+
expect(w.getPending()).toStrictEqual([]);
74+
expect(d).toBe(1);
75+
76+
s1.set(3);
77+
expect(w1).toBe(1);
78+
expect(u1).toBe(0);
79+
expect(w2).toBe(0);
80+
expect(u2).toBe(0);
81+
expect(n).toBe(1);
82+
expect(Signal.subtle.hasSinks(s1)).toBe(true);
83+
expect(Signal.subtle.hasSinks(s2)).toBe(false);
84+
expect(w.getPending()).toStrictEqual([c]);
85+
expect(d).toBe(1);
86+
87+
expect(c.get()).toBe(3);
88+
expect(w1).toBe(1);
89+
expect(u1).toBe(0);
90+
expect(w2).toBe(0);
91+
expect(u2).toBe(0);
92+
expect(n).toBe(1);
93+
expect(Signal.subtle.hasSinks(s1)).toBe(true);
94+
expect(Signal.subtle.hasSinks(s2)).toBe(false);
95+
expect(w.getPending()).toStrictEqual([]);
96+
expect(d).toBe(2);
97+
98+
which = s2;
99+
w.watch();
100+
s1.set(4);
101+
expect(w1).toBe(1);
102+
expect(u1).toBe(0);
103+
expect(w2).toBe(0);
104+
expect(u2).toBe(0);
105+
expect(n).toBe(2);
106+
expect(Signal.subtle.hasSinks(s1)).toBe(true);
107+
expect(Signal.subtle.hasSinks(s2)).toBe(false);
108+
expect(w.getPending()).toStrictEqual([c]);
109+
expect(d).toBe(2);
110+
111+
expect(c.get()).toBe(2);
112+
expect(w1).toBe(1);
113+
expect(u1).toBe(1);
114+
expect(w2).toBe(1);
115+
expect(u2).toBe(0);
116+
expect(n).toBe(2);
117+
expect(Signal.subtle.hasSinks(s1)).toBe(false);
118+
expect(Signal.subtle.hasSinks(s2)).toBe(true);
119+
expect(w.getPending()).toStrictEqual([]);
120+
expect(d).toBe(3);
121+
122+
w.watch();
123+
which = {
124+
get() {
125+
return 10;
126+
},
127+
};
128+
s1.set(5);
129+
expect(c.get()).toBe(2);
130+
expect(w1).toBe(1);
131+
expect(u1).toBe(1);
132+
expect(w2).toBe(1);
133+
expect(u2).toBe(0);
134+
expect(n).toBe(2);
135+
expect(Signal.subtle.hasSinks(s1)).toBe(false);
136+
expect(Signal.subtle.hasSinks(s2)).toBe(true);
137+
expect(w.getPending()).toStrictEqual([]);
138+
expect(d).toBe(3);
139+
140+
w.watch();
141+
s2.set(0);
142+
expect(w1).toBe(1);
143+
expect(u1).toBe(1);
144+
expect(w2).toBe(1);
145+
expect(u2).toBe(0);
146+
expect(n).toBe(3);
147+
expect(Signal.subtle.hasSinks(s1)).toBe(false);
148+
expect(Signal.subtle.hasSinks(s2)).toBe(true);
149+
expect(w.getPending()).toStrictEqual([c]);
150+
expect(d).toBe(3);
151+
152+
expect(c.get()).toBe(10);
153+
expect(w1).toBe(1);
154+
expect(u1).toBe(1);
155+
expect(w2).toBe(1);
156+
expect(u2).toBe(1);
157+
expect(n).toBe(3);
158+
expect(Signal.subtle.hasSinks(s1)).toBe(false);
159+
expect(Signal.subtle.hasSinks(s2)).toBe(false);
160+
expect(w.getPending()).toStrictEqual([]);
161+
expect(d).toBe(4);
162+
});
163+
});

0 commit comments

Comments
 (0)