lifecycle_spec.js 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  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.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.textContent).toBe('hi!')
  91. expect(vm.$el.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. var data = vm._data
  132. expect(data.__ob__.vms.length).toBe(1)
  133. vm.$destroy()
  134. expect(data.__ob__.vms.length).toBe(0)
  135. expect(vm._isDestroyed).toBe(true)
  136. expect(vm._watchers).toBeNull()
  137. expect(vm._userWatchers).toBeNull()
  138. expect(vm._watcherList).toBeNull()
  139. expect(vm.$el).toBeNull()
  140. expect(vm.$parent).toBeNull()
  141. expect(vm.$root).toBeNull()
  142. expect(vm._children).toBeNull()
  143. expect(vm._bindings).toBeNull()
  144. expect(vm._directives).toBeNull()
  145. expect(Object.keys(vm._events).length).toBe(0)
  146. })
  147. it('remove element', function () {
  148. var el = document.createElement('div')
  149. var parent = document.createElement('div')
  150. parent.appendChild(el)
  151. var vm = new Vue({ el: el })
  152. vm.$destroy(true)
  153. expect(parent.childNodes.length).toBe(0)
  154. expect(el.__vue__).toBeNull()
  155. })
  156. it('hooks', function () {
  157. var opts = {
  158. beforeDestroy: jasmine.createSpy(),
  159. destroyed: jasmine.createSpy(),
  160. detached: jasmine.createSpy()
  161. }
  162. var el = opts.el = document.createElement('div')
  163. document.body.appendChild(el)
  164. var vm = new Vue(opts)
  165. vm.$destroy(true)
  166. expect(opts.beforeDestroy).toHaveBeenCalled()
  167. expect(opts.destroyed).toHaveBeenCalled()
  168. expect(opts.detached).toHaveBeenCalled()
  169. })
  170. it('parent', function () {
  171. var parent = new Vue()
  172. var child = parent.$addChild()
  173. expect(parent._children.length).toBe(1)
  174. child.$destroy()
  175. expect(parent._children.length).toBe(0)
  176. })
  177. it('children', function () {
  178. var parent = new Vue()
  179. var child = parent.$addChild()
  180. parent.$destroy()
  181. expect(child._isDestroyed).toBe(true)
  182. })
  183. it('directives', function () {
  184. var spy = jasmine.createSpy('directive unbind')
  185. var vm = new Vue({
  186. el: document.createElement('div'),
  187. template: '<div v-test></div>',
  188. directives: {
  189. test: {
  190. unbind: spy
  191. }
  192. }
  193. })
  194. vm.$destroy()
  195. expect(spy).toHaveBeenCalled()
  196. })
  197. it('watchers', function () {
  198. var vm = new Vue({
  199. el: document.createElement('div'),
  200. template: '{{a}}',
  201. data: { a: 1 }
  202. })
  203. vm.$watch('a', function () {})
  204. var dirWatcher = vm._watcherList[0]
  205. var userWatcher = vm._watcherList[1]
  206. vm.$destroy()
  207. expect(dirWatcher.active).toBe(false)
  208. expect(userWatcher.active).toBe(false)
  209. })
  210. it('refuse multiple calls', function () {
  211. var spy = jasmine.createSpy()
  212. var vm = new Vue({
  213. beforeDestroy: spy
  214. })
  215. vm.$destroy()
  216. vm.$destroy()
  217. expect(spy.calls.count()).toBe(1)
  218. })
  219. })
  220. })
  221. }