From da0eee88388e4e75b5f63a31dcfc900f7b06acba Mon Sep 17 00:00:00 2001 From: cqh963852 Date: Wed, 31 Jan 2024 20:24:52 +0800 Subject: [PATCH] chore: add reactive test --- .../inula-reactive/tests/reactive.test.ts | 241 ++++++++++++++++++ 1 file changed, 241 insertions(+) diff --git a/packages/inula-reactive/tests/reactive.test.ts b/packages/inula-reactive/tests/reactive.test.ts index 76442260..01e36bb0 100644 --- a/packages/inula-reactive/tests/reactive.test.ts +++ b/packages/inula-reactive/tests/reactive.test.ts @@ -189,3 +189,244 @@ describe('test reactive', () => { rObj.items[0].id.set(111); }); }); + +describe('computed with reactive', () => { + it('computed val', () => { + const stateA = reactive({ val: 1 }); + const computedA = computed(() => { + const value = stateA.val.get() + 1; + return value; + }); + + expect(computedA.get()).toBe(2); + + stateA.val.set(stateA.val.get()+1); + + expect(computedA.get()).toBe(3); + }); + + it('computed object', () => { + const stateA = reactive<{ val: { count: number } }>(); + const computedA = computed(() => { + const value = (stateA.val?.count.get() ?? 0) + 1; + return value; + }); + + expect(computedA.get()).toBe(1); + stateA.val.set({ count: 1 }); + stateA.val.count.set(stateA.val.count.get()+1); + + expect(stateA.val?.count).toBe(2); + expect(computedA.get()).toBe(3); + }); + + it('computed array with push value', () => { + const stateA = reactive([1, 2, 3]); + const computedA = computed(() => { + return stateA.get().reduce((p, c) => p + c); + }); + expect(computedA.get()).toBe(6); + stateA.set([1,2,3,4]); + expect(computedA.get()).toBe(10); + }); + + it('computed array with reduce', () => { + const stateA = reactive([{ count: 1 }, { count: 2 }, { count: 3 }]); + const computedA = computed(() => { + return stateA.get().reduce((p, c) => p + c.count, 0); + }); + expect(computedA.get()).toBe(6); + stateA[3].set({ count: 4 }); + expect(computedA.get()).toBe(10); + stateA[0].count.set(6); + expect(computedA.get()).toBe(15); + }); + + it('computed array with map', () => { + const stateA = reactive([{ count: 1 }, { count: 2 }, { count: 3 }]); + const computedA = computed(() => { + return stateA.get().map((p) => p.count); + }); + expect(computedA.get()).toMatchInlineSnapshot(` + bound Array [ + 1, + 2, + 3, + ] + `); + stateA[3].set({ count: 4 }); + expect(computedA.get()).toMatchInlineSnapshot(` + bound Array [ + 1, + 2, + 3, + 4, + ] + `); + stateA[0].count.set(6); + expect(computedA.get()).toMatchInlineSnapshot(` + bound Array [ + 6, + 2, + 3, + 4, + ] + `); + }); + + it('computed array with foreach', () => { + const stateA = reactive([{ count: 1 }, { count: 2 }, { count: 3 }]); + const computedA = computed(() => { + const value: number[] = []; + stateA.read().forEach((v) => value.push(v.count)); + return value; + }); + expect(computedA.get()).toMatchInlineSnapshot(` + bound Array [ + 1, + 2, + 3, + ] + `); + stateA[3].set({ count: 4 }); + expect(computedA.get()).toMatchInlineSnapshot(` + bound Array [ + 1, + 2, + 3, + 4, + ] + `); + stateA[0].count.set(6); + expect(computedA.get()).toMatchInlineSnapshot(` + bound Array [ + 6, + 2, + 3, + 4, + ] + `); + }); + + it('computed object with initial value', () => { + const stateA = reactive<{ val: { count: number } }>({ + val: { count: 0 }, + }); + const computedA = computed(() => { + const value = stateA.val.count + 1; + return value; + }); + + expect(computedA.get()).toBe(1); + + stateA.val.count.set(stateA.val.count.get()+1); + + expect(stateA.val.count).toBe(1); + expect(computedA.get()).toBe(2); + }); + + it('compute computed', () => { + const stateA = reactive({ val: 1 }); + const computedA = computed(() => { + return stateA.val.get() + 1; + }); + + const computeddB = computed(() => { + return computedA.get() * computedA.get(); + }); + + expect(computeddB.get()).toBe(4); + + stateA.val.set(stateA.val.get()+1); + + expect(computeddB.get()).toBe(9); + }); +}); + +describe('watch with reactive', () => { + + // it('effect with timer', () => { + // jest.useFakeTimers(); + // const stubFn = jest.fn(); + // const interval = reactive({ val: 1000 }); + // const subscriber = watch(() => { + // const handler = setInterval(stubFn, interval.val); + // return () => { + // clearInterval(handler); + // }; + // }); + // jest.advanceTimersToNextTimer(); + // expect(stubFn).toBeCalledTimes(1); + + // // Note that a effect clear is done here + // subscriber.val.?.(); + + // interval.val = 2000; + // jest.advanceTimersByTime(2000); + + // // effect won't be reexecute due to effect clear + // expect(stubFn).toBeCalledTimes(1); + // }); + + it('effect with two reactive object', () => { + const count = reactive({ val: 0 }); + const hidden = reactive({ val: false }); + const mockFnA = jest.fn((v, v2) => {}); + watch(() => { + mockFnA(count.val.get(), hidden.val.get()); + }); + count.val.set(count.val.get()+1); + hidden.val.set(!hidden.val.get()); + expect(mockFnA).toBeCalledTimes(3); + count.val.set(count.val.get()+1); + hidden.val.set(!hidden.val.get()); + expect(mockFnA).toBeCalledTimes(5); + }); + + it('effect with condition', () => { + const count = reactive({ val: 0 }); + const hidden = reactive({ val: false }); + const mockFnA = jest.fn(); + const mockFnB = jest.fn(); + watch(() => { + mockFnB(); + if (!hidden.val.get()) { + mockFnA(count.val.get()); + } + }); + count.val.set(count.val.get()+1); + hidden.val.set(!hidden.val.get()); + expect(mockFnA).toBeCalledTimes(2); + expect(mockFnB).toBeCalledTimes(3); + count.val.set(count.val.get()+1); + hidden.val.set(!hidden.val.get()); + expect(mockFnA).toBeCalledTimes(3); + expect(mockFnB).toBeCalledTimes(4); + }); + + // it('effect with complex object', () => { + // const stateA = reactive({ + // val: { value: { data: { count: 1 }, count: 1 } }, + // }); + // const mockFnA = jest.fn((v) => {}); + // const mockFnB = jest.fn((v) => {}); + + // watch(() => { + // mockFnA(stateA.val.value.count.get()); + // }); + // watch(() => { + // mockFnB(stateA.val.value.data.count.get()); + // }); + // expect(mockFnA).toBeCalledTimes(1); + // expect(mockFnB).toBeCalledTimes(1); + + // stateA.val.value.count.set(stateA.val.value.count.get()+1); + // expect(mockFnA).toBeCalledTimes(2); + // expect(mockFnB).toBeCalledTimes(1); + // expect(stateA.val.get()).toMatchInlineSnapshot(); + // stateA.val.value.data.count.set(stateA.val.value.data.count.get()+1); + // expect(mockFnA).toBeCalledTimes(2); + // expect(mockFnB).toBeCalledTimes(3); + // expect(stateA.val.get()).toMatchInlineSnapshot(); + // }); +}); -- Gitee