vnodeHooks.spec.ts 3.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. import {
  2. type TestElement,
  3. TestNodeTypes,
  4. type VNode,
  5. type VNodeProps,
  6. h,
  7. nodeOps,
  8. render,
  9. } from '@vue/runtime-test'
  10. describe('renderer: vnode hooks', () => {
  11. function assertHooks(hooks: VNodeProps, vnode1: VNode, vnode2: VNode) {
  12. const root = nodeOps.createElement('div')
  13. render(vnode1, root)
  14. expect(hooks.onVnodeBeforeMount).toHaveBeenCalledWith(vnode1, null)
  15. expect(hooks.onVnodeMounted).toHaveBeenCalledWith(vnode1, null)
  16. expect(hooks.onVnodeBeforeUpdate).not.toHaveBeenCalled()
  17. expect(hooks.onVnodeUpdated).not.toHaveBeenCalled()
  18. expect(hooks.onVnodeBeforeUnmount).not.toHaveBeenCalled()
  19. expect(hooks.onVnodeUnmounted).not.toHaveBeenCalled()
  20. // update
  21. render(vnode2, root)
  22. expect(hooks.onVnodeBeforeMount).toHaveBeenCalledTimes(1)
  23. expect(hooks.onVnodeMounted).toHaveBeenCalledTimes(1)
  24. expect(hooks.onVnodeBeforeUpdate).toHaveBeenCalledWith(vnode2, vnode1)
  25. expect(hooks.onVnodeUpdated).toHaveBeenCalledWith(vnode2, vnode1)
  26. expect(hooks.onVnodeBeforeUnmount).not.toHaveBeenCalled()
  27. expect(hooks.onVnodeUnmounted).not.toHaveBeenCalled()
  28. // unmount
  29. render(null, root)
  30. expect(hooks.onVnodeBeforeMount).toHaveBeenCalledTimes(1)
  31. expect(hooks.onVnodeMounted).toHaveBeenCalledTimes(1)
  32. expect(hooks.onVnodeBeforeUpdate).toHaveBeenCalledTimes(1)
  33. expect(hooks.onVnodeUpdated).toHaveBeenCalledTimes(1)
  34. expect(hooks.onVnodeBeforeUnmount).toHaveBeenCalledWith(vnode2, null)
  35. expect(hooks.onVnodeUnmounted).toHaveBeenCalledWith(vnode2, null)
  36. }
  37. test('should work on element', () => {
  38. const hooks: VNodeProps = {
  39. onVnodeBeforeMount: vi.fn<(vnode: VNode) => void>(),
  40. onVnodeMounted: vi.fn<(vnode: VNode) => void>(),
  41. onVnodeBeforeUpdate: vi.fn(vnode => {
  42. expect((vnode.el as TestElement).children[0]).toMatchObject({
  43. type: TestNodeTypes.TEXT,
  44. text: 'foo',
  45. })
  46. }),
  47. onVnodeUpdated: vi.fn(vnode => {
  48. expect((vnode.el as TestElement).children[0]).toMatchObject({
  49. type: TestNodeTypes.TEXT,
  50. text: 'bar',
  51. })
  52. }),
  53. onVnodeBeforeUnmount: vi.fn<(vnode: VNode) => void>(),
  54. onVnodeUnmounted: vi.fn<(vnode: VNode) => void>(),
  55. }
  56. assertHooks(hooks, h('div', hooks, 'foo'), h('div', hooks, 'bar'))
  57. })
  58. test('should work on component', () => {
  59. const Comp = (props: { msg: string }) => props.msg
  60. const hooks: VNodeProps = {
  61. onVnodeBeforeMount: vi.fn<(vnode: VNode) => void>(),
  62. onVnodeMounted: vi.fn<(vnode: VNode) => void>(),
  63. onVnodeBeforeUpdate: vi.fn(vnode => {
  64. expect(vnode.el as TestElement).toMatchObject({
  65. type: TestNodeTypes.TEXT,
  66. text: 'foo',
  67. })
  68. }),
  69. onVnodeUpdated: vi.fn(vnode => {
  70. expect(vnode.el as TestElement).toMatchObject({
  71. type: TestNodeTypes.TEXT,
  72. text: 'bar',
  73. })
  74. }),
  75. onVnodeBeforeUnmount: vi.fn<(vnode: VNode) => void>(),
  76. onVnodeUnmounted: vi.fn<(vnode: VNode) => void>(),
  77. }
  78. assertHooks(
  79. hooks,
  80. h(Comp, {
  81. ...hooks,
  82. msg: 'foo',
  83. }),
  84. h(Comp, {
  85. ...hooks,
  86. msg: 'bar',
  87. }),
  88. )
  89. })
  90. })