lifecycle_spec.js 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. var Vue = require('../../../../src/vue')
  2. var _ = require('../../../../src/util')
  3. var compile = require('../../../../src/compile/compile')
  4. if (_.inBrowser) {
  5. describe('Lifecycle API', function () {
  6. describe('$mount', function () {
  7. var el, frag
  8. beforeEach(function () {
  9. el = document.createElement('div')
  10. el.textContent = '{{test}}'
  11. frag = document.createDocumentFragment()
  12. frag.appendChild(el)
  13. spyOn(_, 'warn')
  14. })
  15. it('normal', function () {
  16. var vm = new Vue({
  17. data: {
  18. test: 'hi!'
  19. }
  20. })
  21. vm.$mount(el)
  22. expect(vm.$el).toBe(el)
  23. expect(el.__vue__).toBe(vm)
  24. expect(el.textContent).toBe('hi!')
  25. })
  26. it('selector', function () {
  27. el.id = 'mount-test'
  28. document.body.appendChild(el)
  29. var vm = new Vue({
  30. data: { test: 'hi!' }
  31. })
  32. vm.$mount('#mount-test')
  33. expect(vm.$el).toBe(el)
  34. expect(el.__vue__).toBe(vm)
  35. expect(el.textContent).toBe('hi!')
  36. document.body.removeChild(el)
  37. })
  38. it('warn invalid selector', function () {
  39. var vm = new Vue()
  40. vm.$mount('#none-exist')
  41. expect(_.warn).toHaveBeenCalled()
  42. })
  43. it('replace', function () {
  44. el.className = 'replace-test'
  45. document.body.appendChild(el)
  46. var vm = new Vue({
  47. replace: true,
  48. data: { test: 'hi!' },
  49. template: '<div>{{test}}</div>'
  50. })
  51. vm.$mount(el)
  52. expect(vm.$el).not.toBe(el)
  53. expect(vm.$el.textContent).toBe('hi!')
  54. expect(document.body.contains(el)).toBe(false)
  55. expect(document.body.lastChild).toBe(vm.$el)
  56. expect(vm.$el.className).toBe('replace-test')
  57. document.body.removeChild(vm.$el)
  58. })
  59. it('precompiled linker', function () {
  60. var linker = compile(el, Vue.options)
  61. var vm = new Vue({
  62. _linker: linker,
  63. data: {
  64. test: 'hi!'
  65. }
  66. })
  67. vm.$mount(el)
  68. expect(vm.$el).toBe(el)
  69. expect(el.__vue__).toBe(vm)
  70. expect(el.textContent).toBe('hi!')
  71. })
  72. it('mount to fragment', function () {
  73. var vm = new Vue({
  74. data: { test: 'frag' }
  75. })
  76. vm.$mount(frag)
  77. expect(vm.$el).toBe(vm._blockStart)
  78. expect(vm._blockFragment).toBe(frag)
  79. expect(vm.$el.nextSibling.textContent).toBe('frag')
  80. })
  81. it('replace fragment', function () {
  82. document.body.appendChild(el)
  83. var vm = new Vue({
  84. replace: true,
  85. data: { test: 'hi!' },
  86. template: '<div>{{test}}</div><div>{{test}}</div>'
  87. })
  88. vm.$mount(el)
  89. expect(vm.$el).not.toBe(el)
  90. expect(vm.$el.nextSibling.textContent).toBe('hi!')
  91. expect(vm.$el.nextSibling.nextSibling.textContent).toBe('hi!')
  92. expect(document.body.contains(el)).toBe(false)
  93. expect(document.body.lastChild).toBe(vm._blockEnd)
  94. vm.$remove()
  95. })
  96. it('hooks', function () {
  97. var hooks = ['created', 'beforeCompile', 'compiled', 'attached', 'ready']
  98. var options = {
  99. data: {
  100. test: 'hihi'
  101. }
  102. }
  103. hooks.forEach(function (hook) {
  104. options[hook] = jasmine.createSpy(hook)
  105. })
  106. var vm = new Vue(options)
  107. expect(options.created).toHaveBeenCalled()
  108. expect(options.beforeCompile).not.toHaveBeenCalled()
  109. vm.$mount(el)
  110. expect(options.beforeCompile).toHaveBeenCalled()
  111. expect(options.compiled).toHaveBeenCalled()
  112. expect(options.attached).not.toHaveBeenCalled()
  113. expect(options.ready).not.toHaveBeenCalled()
  114. vm.$appendTo(document.body)
  115. expect(options.attached).toHaveBeenCalled()
  116. expect(options.ready).toHaveBeenCalled()
  117. vm.$remove()
  118. })
  119. it('warn against multiple calls', function () {
  120. var vm = new Vue({
  121. el: el
  122. })
  123. vm.$mount(el)
  124. expect(_.warn).toHaveBeenCalled()
  125. })
  126. })
  127. describe('$destroy', function () {
  128. it('normal', function () {
  129. var vm = new Vue()
  130. expect(vm._isDestroyed).toBe(false)
  131. vm.$destroy()
  132. expect(vm._isDestroyed).toBe(true)
  133. expect(vm._watchers).toBeNull()
  134. expect(vm._userWatchers).toBeNull()
  135. expect(vm._watcherList).toBeNull()
  136. expect(vm.$el).toBeNull()
  137. expect(vm.$parent).toBeNull()
  138. expect(vm.$root).toBeNull()
  139. expect(vm._children).toBeNull()
  140. expect(vm._bindings).toBeNull()
  141. expect(vm._directives).toBeNull()
  142. expect(Object.keys(vm._events).length).toBe(0)
  143. })
  144. it('remove element', function () {
  145. var el = document.createElement('div')
  146. var parent = document.createElement('div')
  147. parent.appendChild(el)
  148. var vm = new Vue({ el: el })
  149. vm.$destroy(true)
  150. expect(parent.childNodes.length).toBe(0)
  151. expect(el.__vue__).toBeNull()
  152. })
  153. it('hooks', function () {
  154. var opts = {
  155. beforeDestroy: jasmine.createSpy(),
  156. destroyed: jasmine.createSpy(),
  157. detached: jasmine.createSpy()
  158. }
  159. var el = opts.el = document.createElement('div')
  160. document.body.appendChild(el)
  161. var vm = new Vue(opts)
  162. vm.$destroy(true)
  163. expect(opts.beforeDestroy).toHaveBeenCalled()
  164. expect(opts.destroyed).toHaveBeenCalled()
  165. expect(opts.detached).toHaveBeenCalled()
  166. })
  167. it('parent', function () {
  168. var parent = new Vue()
  169. var child = parent.$addChild()
  170. expect(parent._children.length).toBe(1)
  171. child.$destroy()
  172. expect(parent._children.length).toBe(0)
  173. })
  174. it('children', function () {
  175. var parent = new Vue()
  176. var child = parent.$addChild()
  177. parent.$destroy()
  178. expect(child._isDestroyed).toBe(true)
  179. })
  180. it('directives', function () {
  181. var spy = jasmine.createSpy('directive unbind')
  182. var vm = new Vue({
  183. el: document.createElement('div'),
  184. template: '<div v-test></div>',
  185. directives: {
  186. test: {
  187. unbind: spy
  188. }
  189. }
  190. })
  191. vm.$destroy()
  192. expect(spy).toHaveBeenCalled()
  193. })
  194. it('watchers', function () {
  195. var vm = new Vue({
  196. el: document.createElement('div'),
  197. template: '{{a}}',
  198. data: { a: 1 }
  199. })
  200. vm.$watch('a', function () {})
  201. var dirWatcher = vm._watcherList[0]
  202. var userWatcher = vm._watcherList[1]
  203. vm.$destroy()
  204. expect(dirWatcher.active).toBe(false)
  205. expect(userWatcher.active).toBe(false)
  206. })
  207. it('refuse multiple calls', function () {
  208. var spy = jasmine.createSpy()
  209. var vm = new Vue({
  210. beforeDestroy: spy
  211. })
  212. vm.$destroy()
  213. vm.$destroy()
  214. expect(spy.calls.count()).toBe(1)
  215. })
  216. })
  217. })
  218. }