directives.spec.ts 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. import {
  2. h,
  3. applyDirectives,
  4. ref,
  5. render,
  6. nodeOps,
  7. DirectiveHook,
  8. VNode,
  9. DirectiveBinding,
  10. nextTick
  11. } from '@vue/runtime-test'
  12. import { currentInstance, ComponentInternalInstance } from '../src/component'
  13. describe('directives', () => {
  14. it('should work', async () => {
  15. const count = ref(0)
  16. function assertBindings(binding: DirectiveBinding) {
  17. expect(binding.value).toBe(count.value)
  18. expect(binding.arg).toBe('foo')
  19. expect(binding.instance).toBe(_instance && _instance.renderProxy)
  20. expect(binding.modifiers && binding.modifiers.ok).toBe(true)
  21. }
  22. const beforeMount = jest.fn(((el, binding, vnode, prevVNode) => {
  23. expect(el.tag).toBe('div')
  24. // should not be inserted yet
  25. expect(el.parentNode).toBe(null)
  26. expect(root.children.length).toBe(0)
  27. assertBindings(binding)
  28. expect(vnode).toBe(_vnode)
  29. expect(prevVNode).toBe(null)
  30. }) as DirectiveHook)
  31. const mounted = jest.fn(((el, binding, vnode, prevVNode) => {
  32. expect(el.tag).toBe('div')
  33. // should be inserted now
  34. expect(el.parentNode).toBe(root)
  35. expect(root.children[0]).toBe(el)
  36. assertBindings(binding)
  37. expect(vnode).toBe(_vnode)
  38. expect(prevVNode).toBe(null)
  39. }) as DirectiveHook)
  40. const beforeUpdate = jest.fn(((el, binding, vnode, prevVNode) => {
  41. expect(el.tag).toBe('div')
  42. expect(el.parentNode).toBe(root)
  43. expect(root.children[0]).toBe(el)
  44. // node should not have been updated yet
  45. expect(el.children[0].text).toBe(`${count.value - 1}`)
  46. assertBindings(binding)
  47. expect(vnode).toBe(_vnode)
  48. expect(prevVNode).toBe(_prevVnode)
  49. }) as DirectiveHook)
  50. const updated = jest.fn(((el, binding, vnode, prevVNode) => {
  51. expect(el.tag).toBe('div')
  52. expect(el.parentNode).toBe(root)
  53. expect(root.children[0]).toBe(el)
  54. // node should have been updated
  55. expect(el.children[0].text).toBe(`${count.value}`)
  56. assertBindings(binding)
  57. expect(vnode).toBe(_vnode)
  58. expect(prevVNode).toBe(_prevVnode)
  59. }) as DirectiveHook)
  60. const beforeUnmount = jest.fn(((el, binding, vnode, prevVNode) => {
  61. expect(el.tag).toBe('div')
  62. // should be removed now
  63. expect(el.parentNode).toBe(root)
  64. expect(root.children[0]).toBe(el)
  65. assertBindings(binding)
  66. expect(vnode).toBe(_vnode)
  67. expect(prevVNode).toBe(null)
  68. }) as DirectiveHook)
  69. const unmounted = jest.fn(((el, binding, vnode, prevVNode) => {
  70. expect(el.tag).toBe('div')
  71. // should have been removed
  72. expect(el.parentNode).toBe(null)
  73. expect(root.children.length).toBe(0)
  74. assertBindings(binding)
  75. expect(vnode).toBe(_vnode)
  76. expect(prevVNode).toBe(null)
  77. }) as DirectiveHook)
  78. let _instance: ComponentInternalInstance | null = null
  79. let _vnode: VNode | null = null
  80. let _prevVnode: VNode | null = null
  81. const Comp = {
  82. setup() {
  83. _instance = currentInstance
  84. },
  85. render() {
  86. _prevVnode = _vnode
  87. _vnode = applyDirectives(h('div', count.value), [
  88. [
  89. {
  90. beforeMount,
  91. mounted,
  92. beforeUpdate,
  93. updated,
  94. beforeUnmount,
  95. unmounted
  96. },
  97. // value
  98. count.value,
  99. // argument
  100. 'foo',
  101. // modifiers
  102. { ok: true }
  103. ]
  104. ])
  105. return _vnode
  106. }
  107. }
  108. const root = nodeOps.createElement('div')
  109. render(h(Comp), root)
  110. expect(beforeMount).toHaveBeenCalled()
  111. expect(mounted).toHaveBeenCalled()
  112. count.value++
  113. await nextTick()
  114. expect(beforeUpdate).toHaveBeenCalled()
  115. expect(updated).toHaveBeenCalled()
  116. render(null, root)
  117. expect(beforeUnmount).toHaveBeenCalled()
  118. expect(unmounted).toHaveBeenCalled()
  119. })
  120. })