]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
test(runtime-core): tests for vnode hooks
authorEvan You <yyx990803@gmail.com>
Wed, 18 Mar 2020 20:35:04 +0000 (16:35 -0400)
committerEvan You <yyx990803@gmail.com>
Wed, 18 Mar 2020 20:35:04 +0000 (16:35 -0400)
packages/runtime-core/__tests__/vnodeHooks.spec.ts [new file with mode: 0644]
packages/runtime-core/src/renderer.ts

diff --git a/packages/runtime-core/__tests__/vnodeHooks.spec.ts b/packages/runtime-core/__tests__/vnodeHooks.spec.ts
new file mode 100644 (file)
index 0000000..44ed343
--- /dev/null
@@ -0,0 +1,98 @@
+import {
+  h,
+  render,
+  nodeOps,
+  VNodeProps,
+  TestElement,
+  NodeTypes,
+  VNode
+} from '@vue/runtime-test'
+
+describe('renderer: vnode hooks', () => {
+  function assertHooks(hooks: VNodeProps, vnode1: VNode, vnode2: VNode) {
+    const root = nodeOps.createElement('div')
+    render(vnode1, root)
+    expect(hooks.onVnodeBeforeMount).toHaveBeenCalledWith(vnode1, null)
+    expect(hooks.onVnodeMounted).toHaveBeenCalledWith(vnode1, null)
+    expect(hooks.onVnodeBeforeUpdate).not.toHaveBeenCalled()
+    expect(hooks.onVnodeUpdated).not.toHaveBeenCalled()
+    expect(hooks.onVnodeBeforeUnmount).not.toHaveBeenCalled()
+    expect(hooks.onVnodeUnmounted).not.toHaveBeenCalled()
+
+    // update
+    render(vnode2, root)
+    expect(hooks.onVnodeBeforeMount).toHaveBeenCalledTimes(1)
+    expect(hooks.onVnodeMounted).toHaveBeenCalledTimes(1)
+    expect(hooks.onVnodeBeforeUpdate).toHaveBeenCalledWith(vnode2, vnode1)
+    expect(hooks.onVnodeUpdated).toHaveBeenCalledWith(vnode2, vnode1)
+    expect(hooks.onVnodeBeforeUnmount).not.toHaveBeenCalled()
+    expect(hooks.onVnodeUnmounted).not.toHaveBeenCalled()
+
+    // unmount
+    render(null, root)
+    expect(hooks.onVnodeBeforeMount).toHaveBeenCalledTimes(1)
+    expect(hooks.onVnodeMounted).toHaveBeenCalledTimes(1)
+    expect(hooks.onVnodeBeforeUpdate).toHaveBeenCalledTimes(1)
+    expect(hooks.onVnodeUpdated).toHaveBeenCalledTimes(1)
+    expect(hooks.onVnodeBeforeUnmount).toHaveBeenCalledWith(vnode2, null)
+    expect(hooks.onVnodeUnmounted).toHaveBeenCalledWith(vnode2, null)
+  }
+
+  test('should work on element', () => {
+    const hooks: VNodeProps = {
+      onVnodeBeforeMount: jest.fn(),
+      onVnodeMounted: jest.fn(),
+      onVnodeBeforeUpdate: jest.fn(vnode => {
+        expect((vnode.el as TestElement).children[0]).toMatchObject({
+          type: NodeTypes.TEXT,
+          text: 'foo'
+        })
+      }),
+      onVnodeUpdated: jest.fn(vnode => {
+        expect((vnode.el as TestElement).children[0]).toMatchObject({
+          type: NodeTypes.TEXT,
+          text: 'bar'
+        })
+      }),
+      onVnodeBeforeUnmount: jest.fn(),
+      onVnodeUnmounted: jest.fn()
+    }
+
+    assertHooks(hooks, h('div', hooks, 'foo'), h('div', hooks, 'bar'))
+  })
+
+  test('should work on component', () => {
+    const Comp = (props: { msg: string }) => props.msg
+
+    const hooks: VNodeProps = {
+      onVnodeBeforeMount: jest.fn(),
+      onVnodeMounted: jest.fn(),
+      onVnodeBeforeUpdate: jest.fn(vnode => {
+        expect(vnode.el as TestElement).toMatchObject({
+          type: NodeTypes.TEXT,
+          text: 'foo'
+        })
+      }),
+      onVnodeUpdated: jest.fn(vnode => {
+        expect(vnode.el as TestElement).toMatchObject({
+          type: NodeTypes.TEXT,
+          text: 'bar'
+        })
+      }),
+      onVnodeBeforeUnmount: jest.fn(),
+      onVnodeUnmounted: jest.fn()
+    }
+
+    assertHooks(
+      hooks,
+      h(Comp, {
+        ...hooks,
+        msg: 'foo'
+      }),
+      h(Comp, {
+        ...hooks,
+        msg: 'bar'
+      })
+    )
+  })
+})
index 7b25f23dd79458d31148c2afadf71189d6cdf031..c8788352d3208b1f2f1cf744c1726e087ba1b442 100644 (file)
@@ -1152,6 +1152,7 @@ function baseCreateRenderer<
         const nextTree = renderComponentRoot(instance)
         const prevTree = instance.subTree
         instance.subTree = nextTree
+        next.el = vnode.el
         // beforeUpdate hook
         if (bu !== null) {
           invokeHooks(bu)
@@ -1673,36 +1674,40 @@ function baseCreateRenderer<
       setRef(ref, null, parentComponent, null)
     }
 
+    if ((vnodeHook = props && props.onVnodeBeforeUnmount) != null) {
+      invokeVNodeHook(vnodeHook, parentComponent, vnode)
+    }
+
     if (shapeFlag & ShapeFlags.COMPONENT) {
       if (shapeFlag & ShapeFlags.COMPONENT_SHOULD_KEEP_ALIVE) {
         ;(parentComponent!.sink as KeepAliveSink).deactivate(vnode)
       } else {
         unmountComponent(vnode.component!, parentSuspense, doRemove)
       }
-      return
-    }
-
-    if (__FEATURE_SUSPENSE__ && shapeFlag & ShapeFlags.SUSPENSE) {
-      vnode.suspense!.unmount(parentSuspense, doRemove)
-      return
-    }
+    } else {
+      if (__FEATURE_SUSPENSE__ && shapeFlag & ShapeFlags.SUSPENSE) {
+        vnode.suspense!.unmount(parentSuspense, doRemove)
+        return
+      }
 
-    if ((vnodeHook = props && props.onVnodeBeforeUnmount) != null) {
-      invokeVNodeHook(vnodeHook, parentComponent, vnode)
-    }
-    if (shouldInvokeDirs) {
-      invokeDirectiveHook(vnode, null, parentComponent, 'beforeUnmount')
-    }
+      if (shouldInvokeDirs) {
+        invokeDirectiveHook(vnode, null, parentComponent, 'beforeUnmount')
+      }
 
-    if (dynamicChildren != null) {
-      // fast path for block nodes: only need to unmount dynamic children.
-      unmountChildren(dynamicChildren, parentComponent, parentSuspense)
-    } else if (shapeFlag & ShapeFlags.ARRAY_CHILDREN) {
-      unmountChildren(children as HostVNode[], parentComponent, parentSuspense)
-    }
+      if (dynamicChildren != null) {
+        // fast path for block nodes: only need to unmount dynamic children.
+        unmountChildren(dynamicChildren, parentComponent, parentSuspense)
+      } else if (shapeFlag & ShapeFlags.ARRAY_CHILDREN) {
+        unmountChildren(
+          children as HostVNode[],
+          parentComponent,
+          parentSuspense
+        )
+      }
 
-    if (doRemove) {
-      remove(vnode)
+      if (doRemove) {
+        remove(vnode)
+      }
     }
 
     if (