compile_spec.js 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. var Vue = require('../../../../src/vue')
  2. var _ = require('../../../../src/util')
  3. var dirParser = require('../../../../src/parse/directive')
  4. var merge = require('../../../../src/util/merge-option')
  5. var compile = require('../../../../src/compile/compile')
  6. if (_.inBrowser) {
  7. describe('Compile', function () {
  8. var vm, el, data
  9. beforeEach(function () {
  10. // We mock vms here so we can assert what the generated
  11. // linker functions do.
  12. el = document.createElement('div')
  13. data = {}
  14. vm = {
  15. _bindDir: jasmine.createSpy(),
  16. $set: jasmine.createSpy(),
  17. $eval: function (value) {
  18. return data[value]
  19. },
  20. $interpolate: function (value) {
  21. value = value.replace(/\{|\}/g, '')
  22. return data[value]
  23. }
  24. }
  25. spyOn(vm, '$eval').and.callThrough()
  26. spyOn(vm, '$interpolate').and.callThrough()
  27. })
  28. it('normal directives', function () {
  29. el.setAttribute('v-a', 'b')
  30. el.innerHTML = '<p v-a="a" v-b="b">hello</p><div v-b="b"></div>'
  31. var defA = { priority: 1 }
  32. var defB = { priority: 2 }
  33. var descriptorA = dirParser.parse('a')[0]
  34. var descriptorB = dirParser.parse('b')[0]
  35. var options = merge(Vue.options, {
  36. directives: {
  37. a: defA,
  38. b: defB
  39. }
  40. })
  41. var linker = compile(el, options)
  42. expect(typeof linker).toBe('function')
  43. // should remove attributes
  44. expect(el.attributes.length).toBe(0)
  45. expect(el.firstChild.attributes.length).toBe(0)
  46. expect(el.lastChild.attributes.length).toBe(0)
  47. linker(vm, el)
  48. expect(vm._bindDir.calls.count()).toBe(4)
  49. expect(vm._bindDir).toHaveBeenCalledWith('a', el, descriptorB, defA)
  50. expect(vm._bindDir).toHaveBeenCalledWith('a', el.firstChild, descriptorA, defA)
  51. expect(vm._bindDir).toHaveBeenCalledWith('b', el.firstChild, descriptorB, defB)
  52. expect(vm._bindDir).toHaveBeenCalledWith('b', el.lastChild, descriptorB, defB)
  53. // check the priority sorting
  54. // the "b" on the firstNode should be called first!
  55. expect(vm._bindDir.calls.argsFor(1)[0]).toBe('b')
  56. })
  57. it('text interpolation', function () {
  58. data.b = 'yeah'
  59. el.innerHTML = '{{a}} and {{*b}}'
  60. var def = Vue.options.directives.text
  61. var linker = compile(el, Vue.options)
  62. linker(vm, el)
  63. // expect 1 call because one-time bindings do not generate a directive.
  64. expect(vm._bindDir.calls.count()).toBe(1)
  65. var args = vm._bindDir.calls.argsFor(0)
  66. expect(args[0]).toBe('text')
  67. // skip the node because it's generated in the linker fn via cloneNode
  68. expect(args[2]).toBe(dirParser.parse('a')[0])
  69. expect(args[3]).toBe(def)
  70. // expect $eval to be called during onetime
  71. expect(vm.$eval).toHaveBeenCalledWith('b')
  72. // {{a}} is mocked so it's a space.
  73. // but we want to make sure {{*b}} worked.
  74. expect(el.innerHTML).toBe(' and yeah')
  75. })
  76. it('inline html and partial', function () {
  77. data.html = 'yoyoyo'
  78. el.innerHTML = '{{{html}}} {{{*html}}} {{>partial}}'
  79. var htmlDef = Vue.options.directives.html
  80. var partialDef = Vue.options.directives.partial
  81. var htmlDesc = dirParser.parse('html')[0]
  82. var partialDesc = dirParser.parse('partial')[0]
  83. var linker = compile(el, Vue.options)
  84. linker(vm, el)
  85. expect(vm._bindDir.calls.count()).toBe(2)
  86. var htmlArgs = vm._bindDir.calls.argsFor(0)
  87. expect(htmlArgs[0]).toBe('html')
  88. expect(htmlArgs[2]).toBe(htmlDesc)
  89. expect(htmlArgs[3]).toBe(htmlDef)
  90. var partialArgs = vm._bindDir.calls.argsFor(1)
  91. expect(partialArgs[0]).toBe('partial')
  92. expect(partialArgs[2]).toBe(partialDesc)
  93. expect(partialArgs[3]).toBe(partialDef)
  94. expect(vm.$eval).toHaveBeenCalledWith('html')
  95. // with placeholder comments & interpolated one-time html
  96. expect(el.innerHTML).toBe('<!--v-html--> yoyoyo <!--v-partial-->')
  97. })
  98. it('terminal directives', function () {
  99. el.innerHTML = '<div v-repeat="items"><p v-a="b"></p></div>'
  100. var def = Vue.options.directives.repeat
  101. var descriptor = dirParser.parse('items')[0]
  102. var linker = compile(el, Vue.options)
  103. linker(vm, el)
  104. // expect 1 call because terminal should return early and let
  105. // the directive handle the rest.
  106. expect(vm._bindDir.calls.count()).toBe(1)
  107. expect(vm._bindDir).toHaveBeenCalledWith('repeat', el.firstChild, descriptor, def)
  108. })
  109. it('custom element components', function () {
  110. // body...
  111. })
  112. it('attribute interpolation', function () {
  113. // body...
  114. })
  115. it('param attributes', function () {
  116. // body...
  117. })
  118. it('DocumentFragment', function () {
  119. // body...
  120. })
  121. it('template elements', function () {
  122. // body...
  123. })
  124. })
  125. }