]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
test: test for computed optimization
authorEvan You <yyx990803@gmail.com>
Wed, 7 Jul 2021 14:10:56 +0000 (10:10 -0400)
committerEvan You <yyx990803@gmail.com>
Fri, 16 Jul 2021 18:30:49 +0000 (14:30 -0400)
packages/reactivity/__tests__/computed.spec.ts
packages/runtime-core/__tests__/rendererComponent.spec.ts

index 6811f1029e531398bab699b0afa60163a16cd6f1..112af2826dab77e9a446aa2df8f280f903bb49fc 100644 (file)
@@ -4,7 +4,8 @@ import {
   effect,
   ref,
   WritableComputedRef,
-  isReadonly
+  isReadonly,
+  setComputedScheduler
 } from '../src'
 
 describe('reactivity/computed', () => {
@@ -198,4 +199,58 @@ describe('reactivity/computed', () => {
     x.effect.stop()
     expect(x.value).toBe(1)
   })
+
+  describe('with scheduler', () => {
+    const p = Promise.resolve()
+    const defer = (fn?: any) => (fn ? p.then(fn) : p)
+    beforeEach(() => {
+      setComputedScheduler(defer)
+    })
+
+    afterEach(() => {
+      setComputedScheduler(undefined)
+    })
+
+    test('should only trigger once on multiple mutations', async () => {
+      const src = ref(0)
+      const c = computed(() => src.value)
+      const spy = jest.fn()
+      effect(() => {
+        spy(c.value)
+      })
+      expect(spy).toHaveBeenCalledTimes(1)
+      src.value = 1
+      src.value = 2
+      src.value = 3
+      // not called yet
+      expect(spy).toHaveBeenCalledTimes(1)
+      await defer()
+      // should only trigger once
+      expect(spy).toHaveBeenCalledTimes(2)
+      expect(spy).toHaveBeenCalledWith(c.value)
+    })
+
+    test('should not trigger if value did not change', async () => {
+      const src = ref(0)
+      const c = computed(() => src.value % 2)
+      const spy = jest.fn()
+      effect(() => {
+        spy(c.value)
+      })
+      expect(spy).toHaveBeenCalledTimes(1)
+      src.value = 1
+      src.value = 2
+
+      await defer()
+      // should not trigger
+      expect(spy).toHaveBeenCalledTimes(1)
+
+      src.value = 3
+      src.value = 4
+      src.value = 5
+      await defer()
+      // should trigger because latest value changes
+      expect(spy).toHaveBeenCalledTimes(2)
+    })
+  })
 })
index 4d20ca80b60b2cea81e075dfcb60d58e9a7f3611..889ec05131ca957448778b4f2be2422a2da1762c 100644 (file)
@@ -10,7 +10,8 @@ import {
   inject,
   Ref,
   watch,
-  SetupContext
+  SetupContext,
+  computed
 } from '@vue/runtime-test'
 
 describe('renderer: component', () => {
@@ -321,4 +322,36 @@ describe('renderer: component', () => {
     expect(serializeInner(root)).toBe(``)
     expect(ids).toEqual([ids[0], ids[0] + 1, ids[0] + 2])
   })
+
+  test('computed that did not change should not trigger re-render', async () => {
+    const src = ref(0)
+    const c = computed(() => src.value % 2)
+    const spy = jest.fn()
+    const App = {
+      render() {
+        spy()
+        return c.value
+      }
+    }
+
+    const root = nodeOps.createElement('div')
+    render(h(App), root)
+    expect(serializeInner(root)).toBe(`0`)
+    expect(spy).toHaveBeenCalledTimes(1)
+
+    // verify it updates
+    src.value = 1
+    src.value = 2
+    src.value = 3
+    await nextTick()
+    expect(serializeInner(root)).toBe(`1`)
+    expect(spy).toHaveBeenCalledTimes(2) // should only update once
+
+    // verify it updates
+    src.value = 4
+    src.value = 5
+    await nextTick()
+    expect(serializeInner(root)).toBe(`1`)
+    expect(spy).toHaveBeenCalledTimes(2) // should not need to update
+  })
 })