create-element.spec.js 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. import Vue from 'vue'
  2. import { renderState } from 'core/instance/render'
  3. import { createElement } from 'core/vdom/create-element'
  4. import { emptyVNode } from 'core/vdom/vnode'
  5. import { bind } from 'shared/util'
  6. describe('create-element', () => {
  7. afterEach(() => {
  8. renderState.activeInstance = null
  9. })
  10. it('render vnode with basic reserved tag using createElement', () => {
  11. const vm = new Vue({
  12. data: { msg: 'hello world' }
  13. })
  14. const h = bind(createElement, vm)
  15. renderState.activeInstance = vm
  16. const vnode = h('p', {})
  17. expect(vnode.tag).toBe('p')
  18. expect(vnode.data).toEqual({})
  19. expect(vnode.children).toBeUndefined()
  20. expect(vnode.text).toBeUndefined()
  21. expect(vnode.elm).toBeUndefined()
  22. expect(vnode.ns).toBeUndefined()
  23. expect(vnode.context).toEqual(vm)
  24. })
  25. it('render vnode with component using createElement', () => {
  26. const vm = new Vue({
  27. data: { message: 'hello world' },
  28. components: {
  29. 'my-component': {
  30. props: ['msg']
  31. }
  32. }
  33. })
  34. const h = bind(createElement, vm)
  35. renderState.activeInstance = vm
  36. const vnode = h('my-component', { props: { msg: vm.message }})
  37. expect(vnode.tag).toMatch(/vue-component-[0-9]+/)
  38. expect(vnode.componentOptions.propsData).toEqual({ msg: vm.message })
  39. expect(vnode.children).toBeUndefined()
  40. expect(vnode.text).toBeUndefined()
  41. expect(vnode.elm).toBeUndefined()
  42. expect(vnode.ns).toBeUndefined()
  43. expect(vnode.context).toEqual(vm)
  44. })
  45. it('render vnode with custom tag using createElement', () => {
  46. const vm = new Vue({
  47. data: { msg: 'hello world' }
  48. })
  49. const h = bind(createElement, vm)
  50. const tag = 'custom-tag'
  51. renderState.activeInstance = vm
  52. const vnode = h(tag, {})
  53. expect(vnode.tag).toBe('custom-tag')
  54. expect(vnode.data).toEqual({})
  55. expect(vnode.children).toBeUndefined()
  56. expect(vnode.text).toBeUndefined()
  57. expect(vnode.elm).toBeUndefined()
  58. expect(vnode.ns).toBeUndefined()
  59. expect(vnode.context).toEqual(vm)
  60. expect(vnode.componentOptions).toBeUndefined()
  61. })
  62. it('render empty vnode with falsy tag using createElement', () => {
  63. const vm = new Vue({
  64. data: { msg: 'hello world' }
  65. })
  66. const h = bind(createElement, vm)
  67. renderState.activeInstance = vm
  68. const vnode = h(null, {})
  69. expect(vnode).toEqual(emptyVNode())
  70. })
  71. it('render vnode with not string tag using createElement', () => {
  72. const vm = new Vue({
  73. data: { msg: 'hello world' }
  74. })
  75. const h = bind(createElement, vm)
  76. renderState.activeInstance = vm
  77. const vnode = h(Vue.extend({ // Component class
  78. props: ['msg']
  79. }), { props: { msg: vm.message }})
  80. expect(vnode.tag).toMatch(/vue-component-[0-9]+/)
  81. expect(vnode.componentOptions.propsData).toEqual({ msg: vm.message })
  82. expect(vnode.children).toBeUndefined()
  83. expect(vnode.text).toBeUndefined()
  84. expect(vnode.elm).toBeUndefined()
  85. expect(vnode.ns).toBeUndefined()
  86. expect(vnode.context).toEqual(vm)
  87. })
  88. it('warn message that createElement cannot called when using createElement', () => {
  89. const vm = new Vue({
  90. data: { msg: 'hello world' }
  91. })
  92. const h = bind(createElement, vm)
  93. h('p', {})
  94. expect('createElement cannot be called outside of component').toHaveBeenWarned()
  95. })
  96. it('render vnode with createElement with children', () => {
  97. const vm = new Vue({})
  98. const h = bind(createElement, vm)
  99. renderState.activeInstance = vm
  100. const vnode = h('p', void 0, [h('br'), 'hello world', h('br')])
  101. expect(vnode.children[0].tag).toBe('br')
  102. expect(vnode.children[1].text).toBe('hello world')
  103. expect(vnode.children[2].tag).toBe('br')
  104. })
  105. it('render vnode with children, omitting data', () => {
  106. const vm = new Vue({})
  107. const h = bind(createElement, vm)
  108. renderState.activeInstance = vm
  109. const vnode = h('p', [h('br'), 'hello world', h('br')])
  110. expect(vnode.children[0].tag).toBe('br')
  111. expect(vnode.children[1].text).toBe('hello world')
  112. expect(vnode.children[2].tag).toBe('br')
  113. })
  114. it('warn message when using non-thunk children for component', () => {
  115. const vm = new Vue({
  116. data: { message: 'hello world' },
  117. components: {
  118. 'my-component': {
  119. props: ['msg']
  120. }
  121. }
  122. })
  123. const h = bind(createElement, vm)
  124. renderState.activeInstance = vm
  125. const vnode = h('my-component', { props: { msg: vm.message }}, [h('br'), 'hello world', h('br')])
  126. expect(vnode.componentOptions.children[0].tag).toBe('br')
  127. expect(vnode.componentOptions.children[1]).toBe('hello world')
  128. expect(vnode.componentOptions.children[2].tag).toBe('br')
  129. expect('A component\'s children should be a function').toHaveBeenWarned()
  130. })
  131. it('render svg elements with correct namespace', () => {
  132. const vm = new Vue({})
  133. const h = bind(createElement, vm)
  134. renderState.activeInstance = vm
  135. const vnode = h('svg', [h('a', [h('foo', [h('bar')])])])
  136. expect(vnode.ns).toBe('svg')
  137. // should apply ns to children recursively
  138. expect(vnode.children[0].ns).toBe('svg')
  139. expect(vnode.children[0].children[0].ns).toBe('svg')
  140. expect(vnode.children[0].children[0].children[0].ns).toBe('svg')
  141. })
  142. it('render MathML elements with correct namespace', () => {
  143. const vm = new Vue({})
  144. const h = bind(createElement, vm)
  145. renderState.activeInstance = vm
  146. const vnode = h('math', [h('matrix')])
  147. expect(vnode.ns).toBe('math')
  148. // should apply ns to children
  149. expect(vnode.children[0].ns).toBe('math')
  150. // although not explicitly listed, elements nested under <math>
  151. // should not be treated as component
  152. expect(vnode.children[0].componentOptions).toBeUndefined()
  153. })
  154. })