directives.spec.ts 3.8 KB

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