From d04a4f9cb098925b7c723daf33d431419290a273 Mon Sep 17 00:00:00 2001 From: Evan You Date: Mon, 26 Aug 2019 22:47:38 -0400 Subject: [PATCH] test: (wip) test for watch api --- .../runtime-core/__tests__/apiWatch.spec.ts | 150 +++++++++++++++++- packages/runtime-core/src/apiWatch.ts | 9 +- 2 files changed, 156 insertions(+), 3 deletions(-) diff --git a/packages/runtime-core/__tests__/apiWatch.spec.ts b/packages/runtime-core/__tests__/apiWatch.spec.ts index 9270aed5..c3f9c7d2 100644 --- a/packages/runtime-core/__tests__/apiWatch.spec.ts +++ b/packages/runtime-core/__tests__/apiWatch.spec.ts @@ -1,5 +1,153 @@ +import { watch, reactive, computed, nextTick, ref } from '../src/index' + // reference: https://vue-composition-api-rfc.netlify.com/api.html#watch describe('api: watch', () => { - test.todo('should work') + it('basic usage', async () => { + const state = reactive({ count: 0 }) + let dummy + watch(() => { + dummy = state.count + }) + await nextTick() + expect(dummy).toBe(0) + + state.count++ + await nextTick() + expect(dummy).toBe(1) + }) + + it('watching single source: getter', async () => { + const state = reactive({ count: 0 }) + let dummy + watch( + () => state.count, + (count, prevCount) => { + dummy = [count, prevCount] + } + ) + await nextTick() + expect(dummy).toMatchObject([0, undefined]) + + state.count++ + await nextTick() + expect(dummy).toMatchObject([1, 0]) + }) + + it('watching single source: ref', async () => { + const count = ref(0) + let dummy + watch(count, (count, prevCount) => { + dummy = [count, prevCount] + }) + await nextTick() + expect(dummy).toMatchObject([0, undefined]) + + count.value++ + await nextTick() + expect(dummy).toMatchObject([1, 0]) + }) + + it('watching single source: computed ref', async () => { + const count = ref(0) + const plus = computed(() => count.value + 1) + let dummy + watch(plus, (count, prevCount) => { + dummy = [count, prevCount] + }) + await nextTick() + expect(dummy).toMatchObject([1, undefined]) + + count.value++ + await nextTick() + expect(dummy).toMatchObject([2, 1]) + }) + + it('watching multiple sources', async () => { + const state = reactive({ count: 1 }) + const count = ref(1) + const plus = computed(() => count.value + 1) + + let dummy + watch([() => state.count, count, plus], (vals, oldVals) => { + dummy = [vals, oldVals] + }) + await nextTick() + expect(dummy).toMatchObject([[1, 1, 2], []]) + + state.count++ + count.value++ + await nextTick() + expect(dummy).toMatchObject([[2, 2, 3], [1, 1, 2]]) + }) + + it('stopping the watcher', async () => { + const state = reactive({ count: 0 }) + let dummy + const stop = watch(() => { + dummy = state.count + }) + await nextTick() + expect(dummy).toBe(0) + + stop() + state.count++ + await nextTick() + // should not update + expect(dummy).toBe(0) + }) + + it('cleanup registration (basic)', async () => { + const state = reactive({ count: 0 }) + const cleanup = jest.fn() + let dummy + const stop = watch(onCleanup => { + onCleanup(cleanup) + dummy = state.count + }) + await nextTick() + expect(dummy).toBe(0) + + state.count++ + await nextTick() + expect(cleanup).toHaveBeenCalledTimes(1) + expect(dummy).toBe(1) + + stop() + expect(cleanup).toHaveBeenCalledTimes(2) + }) + + it('cleanup registration (with source)', async () => { + const count = ref(0) + const cleanup = jest.fn() + let dummy + const stop = watch(count, (count, prevCount, onCleanup) => { + onCleanup(cleanup) + dummy = count + }) + await nextTick() + expect(dummy).toBe(0) + + count.value++ + await nextTick() + expect(cleanup).toHaveBeenCalledTimes(1) + expect(dummy).toBe(1) + + stop() + expect(cleanup).toHaveBeenCalledTimes(2) + }) + + it('flush timing: post', () => {}) + + it('flush timing: pre', () => {}) + + it('flush timing: sync', () => {}) + + it('deep', () => {}) + + it('lazy', () => {}) + + it('onTrack', () => {}) + + it('onTrigger', () => {}) }) diff --git a/packages/runtime-core/src/apiWatch.ts b/packages/runtime-core/src/apiWatch.ts index 1053a67f..bc042173 100644 --- a/packages/runtime-core/src/apiWatch.ts +++ b/packages/runtime-core/src/apiWatch.ts @@ -81,7 +81,12 @@ function doWatch( ? () => source.map(s => (isRef(s) ? s.value : s())) : isRef(source) ? () => source.value - : () => source(registerCleanup) + : () => { + if (cleanup) { + cleanup() + } + return source(registerCleanup) + } const getter = deep ? () => traverse(baseGetter()) : baseGetter let cleanup: any @@ -90,7 +95,7 @@ function doWatch( cleanup = runner.onStop = fn } - let oldValue: any + let oldValue = isArray(source) ? [] : undefined const applyCb = cb ? () => { const newValue = runner()