directives.spec.js 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. import Vue from 'vue'
  2. describe('Options directives', () => {
  3. it('basic usage', done => {
  4. const bindSpy = jasmine.createSpy('bind')
  5. const updateSpy = jasmine.createSpy('update')
  6. const componentUpdatedSpy = jasmine.createSpy('componentUpdated')
  7. const unbindSpy = jasmine.createSpy('unbind')
  8. const assertContext = (el, binding, vnode) => {
  9. expect(vnode.context).toBe(vm)
  10. expect(binding.arg).toBe('arg')
  11. expect(binding.modifiers).toEqual({ hello: true })
  12. }
  13. const vm = new Vue({
  14. template: '<div v-if="ok" v-test:arg.hello="a">{{ msg }}</div>',
  15. data: {
  16. msg: 'hi',
  17. a: 'foo',
  18. ok: true
  19. },
  20. directives: {
  21. test: {
  22. bind (el, binding, vnode) {
  23. bindSpy()
  24. assertContext(el, binding, vnode)
  25. expect(binding.value).toBe('foo')
  26. expect(binding.expression).toBe('a')
  27. expect(binding.oldValue).toBeUndefined()
  28. },
  29. update (el, binding, vnode, oldVnode) {
  30. updateSpy()
  31. assertContext(el, binding, vnode)
  32. expect(el).toBe(vm.$el)
  33. expect(oldVnode).not.toBe(vnode)
  34. expect(binding.expression).toBe('a')
  35. if (binding.value !== binding.oldValue) {
  36. expect(binding.value).toBe('bar')
  37. expect(binding.oldValue).toBe('foo')
  38. }
  39. },
  40. componentUpdated (el, binding, vnode) {
  41. componentUpdatedSpy()
  42. assertContext(el, binding, vnode)
  43. },
  44. unbind (el, binding, vnode) {
  45. unbindSpy()
  46. assertContext(el, binding, vnode)
  47. }
  48. }
  49. }
  50. })
  51. vm.$mount()
  52. expect(bindSpy).toHaveBeenCalled()
  53. expect(updateSpy).not.toHaveBeenCalled()
  54. expect(componentUpdatedSpy).not.toHaveBeenCalled()
  55. expect(unbindSpy).not.toHaveBeenCalled()
  56. vm.a = 'bar'
  57. waitForUpdate(() => {
  58. expect(updateSpy).toHaveBeenCalled()
  59. expect(componentUpdatedSpy).toHaveBeenCalled()
  60. expect(unbindSpy).not.toHaveBeenCalled()
  61. vm.msg = 'bye'
  62. }).then(() => {
  63. expect(componentUpdatedSpy.calls.count()).toBe(2)
  64. vm.ok = false
  65. }).then(() => {
  66. expect(unbindSpy).toHaveBeenCalled()
  67. }).then(done)
  68. })
  69. it('function shorthand', done => {
  70. const spy = jasmine.createSpy('directive')
  71. const vm = new Vue({
  72. template: '<div v-test:arg.hello="a"></div>',
  73. data: { a: 'foo' },
  74. directives: {
  75. test (el, binding, vnode) {
  76. expect(vnode.context).toBe(vm)
  77. expect(binding.arg).toBe('arg')
  78. expect(binding.modifiers).toEqual({ hello: true })
  79. spy(binding.value, binding.oldValue)
  80. }
  81. }
  82. })
  83. vm.$mount()
  84. expect(spy).toHaveBeenCalledWith('foo', undefined)
  85. vm.a = 'bar'
  86. waitForUpdate(() => {
  87. expect(spy).toHaveBeenCalledWith('bar', 'foo')
  88. }).then(done)
  89. })
  90. it('function shorthand (global)', done => {
  91. const spy = jasmine.createSpy('directive')
  92. Vue.directive('test', function (el, binding, vnode) {
  93. expect(vnode.context).toBe(vm)
  94. expect(binding.arg).toBe('arg')
  95. expect(binding.modifiers).toEqual({ hello: true })
  96. spy(binding.value, binding.oldValue)
  97. })
  98. const vm = new Vue({
  99. template: '<div v-test:arg.hello="a"></div>',
  100. data: { a: 'foo' }
  101. })
  102. vm.$mount()
  103. expect(spy).toHaveBeenCalledWith('foo', undefined)
  104. vm.a = 'bar'
  105. waitForUpdate(() => {
  106. expect(spy).toHaveBeenCalledWith('bar', 'foo')
  107. delete Vue.options.directives.test
  108. }).then(done)
  109. })
  110. it('should teardown directives on old vnodes when new vnodes have none', done => {
  111. const vm = new Vue({
  112. data: {
  113. ok: true
  114. },
  115. template: `
  116. <div>
  117. <div v-if="ok" v-test>a</div>
  118. <div v-else class="b">b</div>
  119. </div>
  120. `,
  121. directives: {
  122. test: {
  123. bind: el => { el.id = 'a' },
  124. unbind: el => { el.id = '' }
  125. }
  126. }
  127. }).$mount()
  128. expect(vm.$el.children[0].id).toBe('a')
  129. vm.ok = false
  130. waitForUpdate(() => {
  131. expect(vm.$el.children[0].id).toBe('')
  132. expect(vm.$el.children[0].className).toBe('b')
  133. }).then(done)
  134. })
  135. it('warn non-existent', () => {
  136. new Vue({
  137. template: '<div v-test></div>'
  138. }).$mount()
  139. expect('Failed to resolve directive: test').toHaveBeenWarned()
  140. })
  141. })