hydration.spec.js 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. import { patch } from 'web/runtime/patch'
  2. import * as nodeOps from 'web/runtime/node-ops'
  3. import VNode from 'core/vdom/vnode'
  4. describe('hydration', () => {
  5. let vnode0
  6. beforeEach(() => {
  7. vnode0 = new VNode('p', { attrs: { id: '1' }}, [createTextVNode('hello world')])
  8. patch(null, vnode0)
  9. })
  10. it('should hydrate elements when server-rendered DOM tree is same as virtual DOM tree', () => {
  11. const result = []
  12. function init (vnode) { result.push(vnode) }
  13. function createServerRenderedDOM () {
  14. const root = nodeOps.createElement('div')
  15. root.setAttribute('server-rendered', 'true')
  16. const span = nodeOps.createElement('span')
  17. root.appendChild(span)
  18. const div = nodeOps.createElement('div')
  19. const child1 = nodeOps.createElement('span')
  20. const child2 = nodeOps.createElement('span')
  21. div.appendChild(child1)
  22. div.appendChild(child2)
  23. root.appendChild(div)
  24. return root
  25. }
  26. const node0 = createServerRenderedDOM()
  27. const vnode1 = new VNode('div', {}, [
  28. new VNode('span', {}),
  29. new VNode('div', { hook: { init }}, [
  30. new VNode('span', {}),
  31. new VNode('span', {})
  32. ])
  33. ])
  34. patch(node0, vnode1)
  35. expect(result.length).toBe(1)
  36. function traverseAndAssert (vnode, element) {
  37. expect(vnode.elm).toBe(element)
  38. if (vnode.children) {
  39. vnode.children.forEach((node, i) => {
  40. traverseAndAssert(node, element.childNodes[i])
  41. })
  42. }
  43. }
  44. // ensure vnodes are correctly associated with actual DOM
  45. traverseAndAssert(vnode1, node0)
  46. // check update
  47. const vnode2 = new VNode('div', { props: { id: 'foo' }}, [
  48. new VNode('span', { props: { id: 'bar' }}),
  49. new VNode('div', { hook: { init }}, [
  50. new VNode('span', {}),
  51. new VNode('span', {})
  52. ])
  53. ])
  54. patch(vnode1, vnode2)
  55. expect(node0.id).toBe('foo')
  56. expect(node0.children[0].id).toBe('bar')
  57. })
  58. it('should hydrate components when server-rendered DOM tree is same as virtual DOM tree', () => {
  59. const result = []
  60. function init (vnode) { result.push(vnode) }
  61. function createServerRenderedDOM () {
  62. const root = nodeOps.createElement('vue-component-1')
  63. root.setAttribute('server-rendered', 'true')
  64. const span = nodeOps.createElement('span')
  65. root.appendChild(span)
  66. const div = nodeOps.createElement('div')
  67. const child1 = nodeOps.createElement('span')
  68. const child2 = nodeOps.createElement('span')
  69. div.appendChild(child1)
  70. div.appendChild(child2)
  71. root.appendChild(div)
  72. return root
  73. }
  74. const node0 = createServerRenderedDOM()
  75. const vnode1 = new VNode('vue-component-1', {}, [
  76. new VNode('span', {}),
  77. new VNode('div', { hook: { init }}, [
  78. new VNode('span', {}),
  79. new VNode('span', {})
  80. ])
  81. ])
  82. patch(node0, vnode1)
  83. expect(result.length).toBe(1)
  84. })
  85. it('should warn message that virtual DOM tree is not matching when hydrate element', () => {
  86. function createServerRenderedDOM () {
  87. const root = nodeOps.createElement('div')
  88. root.setAttribute('server-rendered', 'true')
  89. const span = nodeOps.createElement('span')
  90. root.appendChild(span)
  91. const div = nodeOps.createElement('div')
  92. const child1 = nodeOps.createElement('span')
  93. div.appendChild(child1)
  94. root.appendChild(div)
  95. return root
  96. }
  97. const node0 = createServerRenderedDOM()
  98. const vnode1 = new VNode('div', {}, [
  99. new VNode('span', {}),
  100. new VNode('div', {}, [
  101. new VNode('span', {}),
  102. new VNode('span', {})
  103. ])
  104. ])
  105. patch(node0, vnode1)
  106. expect('The client-side rendered virtual DOM tree is not matching').toHaveBeenWarned()
  107. })
  108. })