directive_spec.js 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  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. d._bind()
  35. // properties
  36. expect(d.el).toBe(el)
  37. expect(d.name).toBe('test')
  38. expect(d.vm).toBe(vm)
  39. expect(d.arg).toBe('someArg')
  40. expect(d.expression).toBe('a')
  41. // init calls
  42. expect(def.bind).toHaveBeenCalled()
  43. expect(def.update).toHaveBeenCalledWith(2)
  44. expect(d._bound).toBe(true)
  45. // update
  46. vm.a = 2
  47. nextTick(function () {
  48. expect(def.update).toHaveBeenCalledWith(4, 2)
  49. // teardown
  50. d._teardown()
  51. expect(def.unbind).toHaveBeenCalled()
  52. expect(d._bound).toBe(false)
  53. expect(d._watcher).toBe(null)
  54. done()
  55. })
  56. })
  57. it('static literal', function () {
  58. def.isLiteral = true
  59. var d = new Directive('test', el, vm, {
  60. expression: 'a'
  61. }, def)
  62. d._bind()
  63. expect(d._watcher).toBeUndefined()
  64. expect(d.expression).toBe('a')
  65. expect(d.bind).toHaveBeenCalled()
  66. expect(d.update).not.toHaveBeenCalled()
  67. })
  68. it('static literal, interpolate with no update', function () {
  69. def.isLiteral = true
  70. delete def.update
  71. var d = new Directive('test', el, vm, {
  72. expression: '{{a}}'
  73. }, def)
  74. d._bind()
  75. expect(d._watcher).toBeUndefined()
  76. expect(d.expression).toBe(1)
  77. expect(d.bind).toHaveBeenCalled()
  78. })
  79. it('dynamic literal', function (done) {
  80. vm.a = '' // #468 dynamic literals with falsy initial
  81. // should still create the watcher.
  82. def.isLiteral = true
  83. var d = new Directive('test', el, vm, {
  84. expression: '{{a}}'
  85. }, def)
  86. d._bind()
  87. expect(d._watcher).toBeDefined()
  88. expect(d.expression).toBe('')
  89. expect(def.bind).toHaveBeenCalled()
  90. expect(def.update).toHaveBeenCalledWith('')
  91. vm.a = 'aa'
  92. nextTick(function () {
  93. expect(def.update).toHaveBeenCalledWith('aa', '')
  94. done()
  95. })
  96. })
  97. it('inline statement', function () {
  98. def.acceptStatement = true
  99. var spy = jasmine.createSpy()
  100. vm.$options.filters.test = function (fn) {
  101. spy()
  102. return function () {
  103. // call it twice
  104. fn()
  105. fn()
  106. }
  107. }
  108. var d = new Directive('test', el, vm, {
  109. expression: 'a++',
  110. filters: [{name: 'test'}]
  111. }, def)
  112. d._bind()
  113. expect(d._watcher).toBeUndefined()
  114. expect(d.bind).toHaveBeenCalled()
  115. var wrappedFn = d.update.calls.argsFor(0)[0]
  116. expect(typeof wrappedFn).toBe('function')
  117. // test invoke the wrapped fn
  118. wrappedFn()
  119. expect(vm.a).toBe(3)
  120. })
  121. it('two-way', function (done) {
  122. def.twoWay = true
  123. vm.$options.filters.test = {
  124. write: function (v) {
  125. return v * 3
  126. }
  127. }
  128. var d = new Directive('test', el, vm, {
  129. expression: 'a',
  130. filters: [{name: 'test'}]
  131. }, def)
  132. d._bind()
  133. d.set(2)
  134. expect(vm.a).toBe(6)
  135. nextTick(function () {
  136. // should have no update calls
  137. expect(def.update.calls.count()).toBe(1)
  138. done()
  139. })
  140. })
  141. it('deep', function (done) {
  142. def.deep = true
  143. var d = new Directive('test', el, vm, {
  144. expression: 'b'
  145. }, def)
  146. d._bind()
  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. d._bind()
  158. expect(d.update).toBe(def.update)
  159. expect(def.update).toHaveBeenCalled()
  160. })
  161. it('literal (new syntax)', function () {
  162. var d = new Directive('test', el, vm, {
  163. raw: 'a'
  164. }, def.update, null, null, null, null, true)
  165. d._bind()
  166. expect(def.update).toHaveBeenCalledWith('a')
  167. })
  168. })