directive_spec.js 3.4 KB

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