Skip to content

Commit af7c21b

Browse files
committed
up
1 parent 83e438d commit af7c21b

File tree

2 files changed

+105
-85
lines changed

2 files changed

+105
-85
lines changed

tests/derived.test.ts

Lines changed: 99 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -33,16 +33,16 @@ describe("derived", () => {
3333
const spyEffect = jest.fn(() => d());
3434
effect(spyEffect);
3535

36-
expectSpy(spyEffect, 1, { args: [] });
37-
expectSpy(spyDerived, 1, { args: [], result: 2 });
36+
expectSpy(spyEffect, 1);
37+
expectSpy(spyDerived, 1, { result: 2 });
3838
state.a = 3;
3939
await waitScheduler();
40-
expectSpy(spyEffect, 2, { args: [] });
41-
expectSpy(spyDerived, 2, { args: [], result: 6 });
40+
expectSpy(spyEffect, 2);
41+
expectSpy(spyDerived, 2, { result: 6 });
4242
state.b = 4;
4343
await waitScheduler();
44-
expectSpy(spyEffect, 3, { args: [] });
45-
expectSpy(spyDerived, 3, { args: [], result: 12 });
44+
expectSpy(spyEffect, 3);
45+
expectSpy(spyDerived, 3, { result: 12 });
4646
});
4747

4848
test("derived does not update when unrelated property changes, but updates when dependencies change", async () => {
@@ -52,77 +52,82 @@ describe("derived", () => {
5252
const spyEffect = jest.fn(() => d());
5353
effect(spyEffect);
5454

55-
expectSpy(spyEffect, 1, { args: [] });
56-
expectSpy(spyDerived, 1, { args: [], result: 3 });
55+
expectSpy(spyEffect, 1);
56+
expectSpy(spyDerived, 1, { result: 3 });
5757

5858
state.c = 10;
5959
await waitScheduler();
60-
expectSpy(spyEffect, 1, { args: [] });
61-
expectSpy(spyDerived, 1, { args: [], result: 3 });
60+
expectSpy(spyEffect, 1);
61+
expectSpy(spyDerived, 1, { result: 3 });
6262
});
6363

6464
test("derived does not notify when value is unchanged", async () => {
6565
const state = reactive({ a: 1, b: 2 });
66-
const d = derived(() => state.a + state.b);
67-
const spy = jest.fn();
68-
effect(() => spy(d()));
69-
expectSpy(spy, 1, { args: [3] });
66+
const spyDerived = jest.fn(() => state.a + state.b);
67+
const d = derived(spyDerived);
68+
const spyEffect = jest.fn(() => d());
69+
effect(spyEffect);
70+
expectSpy(spyEffect, 1);
71+
expectSpy(spyDerived, 1, { result: 3 });
7072
state.a = 1;
7173
state.b = 2;
7274
await waitScheduler();
73-
expectSpy(spy, 1, { args: [3] });
75+
expectSpy(spyEffect, 1);
76+
expectSpy(spyDerived, 1, { result: 3 });
7477
});
7578

7679
test("multiple deriveds can depend on same state", async () => {
7780
const state = reactive({ a: 1, b: 2 });
78-
const d1 = derived(() => state.a + state.b);
79-
const d2 = derived(() => state.a * state.b);
80-
const spy1 = jest.fn();
81-
const spy2 = jest.fn();
82-
effect(() => spy1(d1()));
83-
effect(() => spy2(d2()));
84-
expectSpy(spy1, 1, { args: [3] });
85-
expectSpy(spy2, 1, { args: [2] });
81+
const spyDerived1 = jest.fn(() => state.a + state.b);
82+
const d1 = derived(spyDerived1);
83+
const spyDerived2 = jest.fn(() => state.a * state.b);
84+
const d2 = derived(spyDerived2);
85+
const spyEffect1 = jest.fn(() => d1());
86+
const spyEffect2 = jest.fn(() => d2());
87+
effect(spyEffect1);
88+
effect(spyEffect2);
89+
expectSpy(spyEffect1, 1);
90+
expectSpy(spyDerived1, 1, { result: 3 });
91+
expectSpy(spyEffect2, 1);
92+
expectSpy(spyDerived2, 1, { result: 2 });
8693
state.a = 3;
8794
await waitScheduler();
88-
expectSpy(spy1, 2, { args: [5] });
89-
expectSpy(spy2, 2, { args: [6] });
90-
});
91-
92-
test("derived can return objects", async () => {
93-
const state = reactive({ a: 1, b: 2 });
94-
const d = derived(() => state.a + state.b);
95-
const spy = jest.fn();
96-
effect(() => spy(d()));
97-
expectSpy(spy, 1, { args: [3] });
98-
state.a = 5;
99-
await waitScheduler();
100-
expectSpy(spy, 2, { args: [7] });
95+
expectSpy(spyEffect1, 2);
96+
expectSpy(spyDerived1, 2, { result: 5 });
97+
expectSpy(spyEffect2, 2);
98+
expectSpy(spyDerived2, 2, { result: 6 });
10199
});
102100

103101
test("derived can depend on arrays", async () => {
104102
const state = reactive({ arr: [1, 2, 3] });
105-
const d = derived(() => state.arr.reduce((a, b) => a + b, 0));
106-
const spy = jest.fn();
107-
effect(() => spy(d()));
108-
expectSpy(spy, 1, { args: [6] });
103+
const spyDerived = jest.fn(() => state.arr.reduce((a, b) => a + b, 0));
104+
const d = derived(spyDerived);
105+
const spyEffect = jest.fn(() => d());
106+
effect(spyEffect);
107+
expectSpy(spyEffect, 1);
108+
expectSpy(spyDerived, 1, { result: 6 });
109109
state.arr.push(4);
110110
await waitScheduler();
111-
expectSpy(spy, 2, { args: [10] });
111+
expectSpy(spyEffect, 2);
112+
expectSpy(spyDerived, 2, { result: 10 });
112113
state.arr[0] = 10;
113114
await waitScheduler();
114-
expectSpy(spy, 3, { args: [19] });
115+
expectSpy(spyEffect, 3);
116+
expectSpy(spyDerived, 3, { result: 19 });
115117
});
116118

117119
test("derived can depend on nested reactives", async () => {
118120
const state = reactive({ nested: { a: 1 } });
119-
const d = derived(() => state.nested.a * 2);
120-
const spy = jest.fn();
121-
effect(() => spy(d()));
122-
expectSpy(spy, 1, { args: [2] });
121+
const spyDerived = jest.fn(() => state.nested.a * 2);
122+
const d = derived(spyDerived);
123+
const spyEffect = jest.fn(() => d());
124+
effect(spyEffect);
125+
expectSpy(spyEffect, 1);
126+
expectSpy(spyDerived, 1, { result: 2 });
123127
state.nested.a = 5;
124128
await waitScheduler();
125-
expectSpy(spy, 2, { args: [10] });
129+
expectSpy(spyEffect, 2);
130+
expectSpy(spyDerived, 2, { result: 10 });
126131
});
127132

128133
test("derived can be called multiple times and returns same value if unchanged", async () => {
@@ -132,87 +137,98 @@ describe("derived", () => {
132137
const d = derived(spy);
133138
expect(spy).not.toHaveBeenCalled();
134139
expect(d()).toBe(3);
135-
expect(spy).toHaveBeenCalledTimes(1);
136-
expect(spy).toHaveReturnedWith(3);
140+
expectSpy(spy, 1, { result: 3 });
137141
expect(d()).toBe(3);
138-
expect(spy).toHaveBeenCalledTimes(1);
139-
expect(spy).toHaveReturnedWith(3);
142+
expectSpy(spy, 1, { result: 3 });
140143
state.a = 2;
141144
await waitScheduler();
142-
expect(spy).toHaveBeenCalledTimes(1);
145+
expectSpy(spy, 1, { result: 3 });
143146
expect(d()).toBe(4);
144-
expect(spy).toHaveBeenCalledTimes(2);
145-
expect(spy).toHaveReturnedWith(4);
147+
expectSpy(spy, 2, { result: 4 });
146148
expect(d()).toBe(4);
147-
expect(spy).toHaveBeenCalledTimes(2);
148-
expect(spy).toHaveReturnedWith(4);
149+
expectSpy(spy, 2, { result: 4 });
149150
});
150151

151152
test("derived should not subscribe to change if no effect is using it", async () => {
152153
const state = reactive({ a: 1, b: 10 });
153-
const spy = jest.fn();
154-
const d = derived(() => spy(state.a));
155-
expect(spy).not.toHaveBeenCalled();
156-
const unsubscribe = effect(() => {
154+
const spyDerived = jest.fn(() => state.a);
155+
const d = derived(spyDerived);
156+
expect(spyDerived).not.toHaveBeenCalled();
157+
const spyEffect = jest.fn(() => {
157158
d();
158159
});
159-
expectSpy(spy, 1, { args: [1] });
160+
const unsubscribe = effect(spyEffect);
161+
expectSpy(spyEffect, 1);
162+
expectSpy(spyDerived, 1, { result: 1 });
160163
state.a = 2;
161164
await waitScheduler();
162-
expectSpy(spy, 2, { args: [2] });
165+
expectSpy(spyEffect, 2);
166+
expectSpy(spyDerived, 2, { result: 2 });
163167
unsubscribe();
164168
state.a = 3;
165169
await waitScheduler();
166-
expectSpy(spy, 2, { args: [2] });
170+
expectSpy(spyEffect, 2);
171+
expectSpy(spyDerived, 2, { result: 2 });
167172
});
168173

169174
test("derived should not be recomputed when called from effect if none of its source changed", async () => {
170175
const state = reactive({ a: 1 });
171-
const spy = jest.fn(() => state.a * 0);
172-
const d = derived(spy);
173-
expect(spy).not.toHaveBeenCalled();
174-
effect(() => {
176+
const spyDerived = jest.fn(() => state.a * 0);
177+
const d = derived(spyDerived);
178+
expect(spyDerived).not.toHaveBeenCalled();
179+
const spyEffect = jest.fn(() => {
175180
d();
176181
});
177-
expect(spy).toHaveBeenCalledTimes(1);
182+
effect(spyEffect);
183+
expectSpy(spyEffect, 1);
184+
expectSpy(spyDerived, 1, { result: 0 });
178185
state.a = 2;
179186
await waitScheduler();
180-
expect(spy).toHaveBeenCalledTimes(2);
187+
expectSpy(spyEffect, 2);
188+
expectSpy(spyDerived, 2, { result: 0 });
181189
});
182190
});
183191
describe("unsubscription", () => {
184-
const memos: Derived<any, any>[] = [];
192+
const deriveds: Derived<any, any>[] = [];
185193
beforeAll(() => {
186-
setSignalHooks({ onDerived: (m: Derived<any, any>) => memos.push(m) });
194+
setSignalHooks({ onDerived: (m: Derived<any, any>) => deriveds.push(m) });
187195
});
188196
afterAll(() => {
189197
resetSignalHooks();
190198
});
191199
afterEach(() => {
192-
memos.length = 0;
200+
deriveds.length = 0;
193201
});
194202

195203
test("derived shoud unsubscribes from dependencies when effect is unsubscribed", async () => {
196204
const state = reactive({ a: 1, b: 2 });
197-
const d = derived(() => state.a + state.b);
205+
const spyDerived = jest.fn(() => state.a + state.b);
206+
const d = derived(spyDerived);
207+
const spyEffect = jest.fn(() => d());
198208
d();
199-
expect(memos[0]!.observers.size).toBe(0);
200-
const unsubscribe = effect(() => d());
201-
expect(memos[0]!.observers.size).toBe(1);
209+
expect(deriveds[0]!.observers.size).toBe(0);
210+
const unsubscribe = effect(spyEffect);
211+
expect(deriveds[0]!.observers.size).toBe(1);
202212
unsubscribe();
203-
expect(memos[0]!.observers.size).toBe(0);
213+
expect(deriveds[0]!.observers.size).toBe(0);
204214
});
205215
});
206216
describe("nested derived", () => {
207217
test("derived can depend on another derived", async () => {
208218
const state = reactive({ a: 1, b: 2 });
209-
const d1 = derived(() => state.a + state.b);
210-
const d2 = derived(() => d1() * 2);
211-
const spy = jest.fn();
212-
effect(() => spy(d2()));
213-
expectSpy(spy, 1, { args: [6] });
219+
const spyDerived1 = jest.fn(() => state.a + state.b);
220+
const d1 = derived(spyDerived1);
221+
const spyDerived2 = jest.fn(() => d1() * 2);
222+
const d2 = derived(spyDerived2);
223+
const spyEffect = jest.fn(() => d2());
224+
effect(spyEffect);
225+
expectSpy(spyEffect, 1);
226+
expectSpy(spyDerived1, 1, { result: 3 });
227+
expectSpy(spyDerived2, 1, { result: 6 });
214228
state.a = 3;
215229
await waitScheduler();
216-
expectSpy(spy, 2, { args: [10] });
230+
expectSpy(spyEffect, 2);
231+
expectSpy(spyDerived1, 2, { result: 5 });
232+
expectSpy(spyDerived2, 2, { result: 10 });
217233
});
218234
});

tests/helpers.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -219,9 +219,13 @@ export async function editInput(input: HTMLInputElement | HTMLTextAreaElement, v
219219
return nextTick();
220220
}
221221

222-
export function expectSpy(spy: jest.Mock, count: number, opt: { args: any[]; result?: any }): void {
222+
export function expectSpy(
223+
spy: jest.Mock,
224+
count: number,
225+
opt: { args?: any[]; result?: any } = {}
226+
): void {
223227
expect(spy).toHaveBeenCalledTimes(count);
224-
if ("args" in opt) expect(spy).lastCalledWith(...opt.args);
228+
if ("args" in opt) expect(spy).lastCalledWith(...opt.args!);
225229
if ("result" in opt) expect(spy).toHaveReturnedWith(opt.result);
226230
}
227231

0 commit comments

Comments
 (0)