directive_spec.js 3.3 KB

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