component-async.spec.js 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. import Vue from 'vue'
  2. import { Promise } from 'es6-promise'
  3. describe('Component async', () => {
  4. it('normal', done => {
  5. const vm = new Vue({
  6. template: '<div><test></test></div>',
  7. components: {
  8. test: (resolve) => {
  9. setTimeout(() => {
  10. resolve({
  11. template: '<div>hi</div>'
  12. })
  13. // wait for parent update
  14. Vue.nextTick(next)
  15. }, 0)
  16. }
  17. }
  18. }).$mount()
  19. expect(vm.$el.innerHTML).toBe('')
  20. expect(vm.$children.length).toBe(0)
  21. function next () {
  22. expect(vm.$el.innerHTML).toBe('<div>hi</div>')
  23. expect(vm.$children.length).toBe(1)
  24. done()
  25. }
  26. })
  27. it('as root', done => {
  28. const vm = new Vue({
  29. template: '<test></test>',
  30. components: {
  31. test: resolve => {
  32. setTimeout(() => {
  33. resolve({
  34. template: '<div>hi</div>'
  35. })
  36. // wait for parent update
  37. Vue.nextTick(next)
  38. }, 0)
  39. }
  40. }
  41. }).$mount()
  42. expect(vm.$el.nodeType).toBe(8)
  43. expect(vm.$children.length).toBe(0)
  44. function next () {
  45. expect(vm.$el.nodeType).toBe(1)
  46. expect(vm.$el.outerHTML).toBe('<div>hi</div>')
  47. expect(vm.$children.length).toBe(1)
  48. done()
  49. }
  50. })
  51. it('dynamic', done => {
  52. var vm = new Vue({
  53. template: '<component :is="view"></component>',
  54. data: {
  55. view: 'view-a'
  56. },
  57. components: {
  58. 'view-a': resolve => {
  59. setTimeout(() => {
  60. resolve({
  61. template: '<div>A</div>'
  62. })
  63. Vue.nextTick(step1)
  64. }, 0)
  65. },
  66. 'view-b': resolve => {
  67. setTimeout(() => {
  68. resolve({
  69. template: '<p>B</p>'
  70. })
  71. Vue.nextTick(step2)
  72. }, 0)
  73. }
  74. }
  75. }).$mount()
  76. var aCalled = false
  77. function step1 () {
  78. // ensure A is resolved only once
  79. expect(aCalled).toBe(false)
  80. aCalled = true
  81. expect(vm.$el.tagName).toBe('DIV')
  82. expect(vm.$el.textContent).toBe('A')
  83. vm.view = 'view-b'
  84. }
  85. function step2 () {
  86. expect(vm.$el.tagName).toBe('P')
  87. expect(vm.$el.textContent).toBe('B')
  88. vm.view = 'view-a'
  89. waitForUpdate(function () {
  90. expect(vm.$el.tagName).toBe('DIV')
  91. expect(vm.$el.textContent).toBe('A')
  92. }).then(done)
  93. }
  94. })
  95. it('warn reject', () => {
  96. new Vue({
  97. template: '<test></test>',
  98. components: {
  99. test: (resolve, reject) => {
  100. reject('nooooo')
  101. }
  102. }
  103. }).$mount()
  104. expect('Reason: nooooo').toHaveBeenWarned()
  105. })
  106. it('with v-for', done => {
  107. const vm = new Vue({
  108. template: '<div><test v-for="n in list" :n="n"></test></div>',
  109. data: {
  110. list: [1, 2, 3]
  111. },
  112. components: {
  113. test: resolve => {
  114. setTimeout(() => {
  115. resolve({
  116. props: ['n'],
  117. template: '<div>{{n}}</div>'
  118. })
  119. Vue.nextTick(next)
  120. }, 0)
  121. }
  122. }
  123. }).$mount()
  124. function next () {
  125. expect(vm.$el.innerHTML).toBe('<div>1</div><div>2</div><div>3</div>')
  126. done()
  127. }
  128. })
  129. it('returning Promise', done => {
  130. const vm = new Vue({
  131. template: '<div><test></test></div>',
  132. components: {
  133. test: () => {
  134. return new Promise(resolve => {
  135. setTimeout(() => {
  136. resolve({
  137. template: '<div>hi</div>'
  138. })
  139. // wait for promise resolve and then parent update
  140. Promise.resolve().then(() => {
  141. Vue.nextTick(next)
  142. })
  143. }, 0)
  144. })
  145. }
  146. }
  147. }).$mount()
  148. expect(vm.$el.innerHTML).toBe('')
  149. expect(vm.$children.length).toBe(0)
  150. function next () {
  151. expect(vm.$el.innerHTML).toBe('<div>hi</div>')
  152. expect(vm.$children.length).toBe(1)
  153. done()
  154. }
  155. })
  156. })