directive_spec.js 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. var Vue = require('../../../src/vue')
  2. var Directive = require('../../../src/directive')
  3. var nextTick = Vue.nextTick
  4. describe('Directive', function () {
  5. var el = {} // simply a mock to be able to run in Node
  6. var vm, def
  7. beforeEach(function () {
  8. def = {
  9. bind: jasmine.createSpy('bind'),
  10. update: jasmine.createSpy('update'),
  11. unbind: jasmine.createSpy('unbind')
  12. }
  13. vm = new Vue({
  14. data:{
  15. a:1,
  16. b: { c: { d: 2 }}
  17. },
  18. filters: {
  19. test: function (v) {
  20. return v * 2
  21. }
  22. },
  23. directives: {
  24. test: def
  25. }
  26. })
  27. })
  28. it('normal', function (done) {
  29. var d = new Directive('test', el, vm, {
  30. expression: 'a',
  31. arg: 'someArg',
  32. filters: [{name:'test'}]
  33. }, def)
  34. // properties
  35. expect(d.el).toBe(el)
  36. expect(d.name).toBe('test')
  37. expect(d.vm).toBe(vm)
  38. expect(d.arg).toBe('someArg')
  39. expect(d.expression).toBe('a')
  40. // init calls
  41. expect(def.bind).toHaveBeenCalled()
  42. expect(def.update).toHaveBeenCalledWith(2)
  43. expect(d._bound).toBe(true)
  44. // update
  45. vm.a = 2
  46. nextTick(function () {
  47. expect(def.update).toHaveBeenCalledWith(4, 2)
  48. // teardown
  49. d._teardown()
  50. expect(def.unbind).toHaveBeenCalled()
  51. expect(d._bound).toBe(false)
  52. expect(d._watcher).toBe(null)
  53. done()
  54. })
  55. })
  56. it('static literal', function () {
  57. def.isLiteral = true
  58. var d = new Directive('test', el, vm, {
  59. expression: 'a'
  60. }, def)
  61. expect(d._watcher).toBeUndefined()
  62. expect(d.expression).toBe('a')
  63. expect(d.bind).toHaveBeenCalled()
  64. expect(d.update).not.toHaveBeenCalled()
  65. })
  66. it('static literal, interpolate with no update', function () {
  67. def.isLiteral = true
  68. delete def.update
  69. var d = new Directive('test', el, vm, {
  70. expression: '{{a}}'
  71. }, def)
  72. expect(d._watcher).toBeUndefined()
  73. expect(d.expression).toBe(1)
  74. expect(d.bind).toHaveBeenCalled()
  75. })
  76. it('dynamic literal', function (done) {
  77. vm.a = '' // #468 dynamic literals with falsy initial
  78. // should still create the watcher.
  79. def.isLiteral = true
  80. var d = new Directive('test', el, vm, {
  81. expression: '{{a}}'
  82. }, def)
  83. expect(d._watcher).toBeDefined()
  84. expect(d.expression).toBe('')
  85. expect(def.bind).toHaveBeenCalled()
  86. expect(def.update).toHaveBeenCalledWith('')
  87. vm.a = 'aa'
  88. nextTick(function () {
  89. expect(def.update).toHaveBeenCalledWith('aa', '')
  90. done()
  91. })
  92. })
  93. it('inline statement', function () {
  94. def.acceptStatement = true
  95. var spy = jasmine.createSpy()
  96. vm.$options.filters.test = function (fn) {
  97. spy()
  98. return function () {
  99. // call it twice
  100. fn()
  101. fn()
  102. }
  103. }
  104. var d = new Directive('test', el, vm, {
  105. expression: 'a++',
  106. filters: [{name:'test'}]
  107. }, def)
  108. expect(d._watcher).toBeUndefined()
  109. expect(d.bind).toHaveBeenCalled()
  110. var wrappedFn = d.update.calls.argsFor(0)[0]
  111. expect(typeof wrappedFn).toBe('function')
  112. // test invoke the wrapped fn
  113. wrappedFn()
  114. expect(vm.a).toBe(3)
  115. })
  116. it('two-way', function (done) {
  117. def.twoWay = true
  118. vm.$options.filters.test = {
  119. write: function (v) {
  120. return v * 3
  121. }
  122. }
  123. var d = new Directive('test', el, vm, {
  124. expression: 'a',
  125. filters: [{name:'test'}]
  126. }, def)
  127. d.set(2)
  128. expect(vm.a).toBe(6)
  129. nextTick(function () {
  130. expect(def.update.calls.count()).toBe(2)
  131. expect(def.update).toHaveBeenCalledWith(6, 1)
  132. // locked set
  133. d.set(3, true)
  134. expect(vm.a).toBe(9)
  135. nextTick(function () {
  136. // should have no update calls
  137. expect(def.update.calls.count()).toBe(2)
  138. done()
  139. })
  140. })
  141. })
  142. it('deep', function (done) {
  143. def.deep = true
  144. var d = new Directive('test', el, vm, {
  145. expression: 'b'
  146. }, def)
  147. vm.b.c.d = 3
  148. nextTick(function () {
  149. expect(def.update.calls.count()).toBe(2)
  150. done()
  151. })
  152. })
  153. it('function def', function () {
  154. var d = new Directive('test', el, vm, {
  155. expression: 'a'
  156. }, def.update)
  157. expect(d.update).toBe(def.update)
  158. expect(def.update).toHaveBeenCalled()
  159. })
  160. it('reuse the same watcher', function (done) {
  161. var d = new Directive('test', el, vm, {
  162. expression: 'a',
  163. }, def)
  164. var d2 = new Directive('test', el, vm, {
  165. expression: 'a',
  166. }, def)
  167. expect(vm._watcherList.length).toBe(1)
  168. expect(d._watcher).toBe(d2._watcher)
  169. d2._teardown()
  170. expect(d2._watcher).toBeNull()
  171. expect(vm._watcherList.length).toBe(1)
  172. vm.a = 2
  173. nextTick(function () {
  174. expect(def.update).toHaveBeenCalledWith(2, 1)
  175. d._teardown()
  176. expect(vm._watcherList.length).toBe(0)
  177. done()
  178. })
  179. })
  180. })