optimizer.spec.js 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. import { parse } from 'compiler/parser/index'
  2. import { optimize } from 'compiler/optimizer'
  3. import directives from 'web/compiler/directives/index'
  4. import { baseOptions } from 'entries/web-compiler'
  5. describe('optimizer', () => {
  6. it('simple', () => {
  7. const ast = parse('<h1 id="section1">hello world</h1>', baseOptions)
  8. optimize(ast, baseOptions)
  9. expect(ast.static).toBe(true) // h1
  10. expect(ast.staticRoot).toBe(true)
  11. expect(ast.children[0].static).toBe(true) // text node
  12. })
  13. it('interpolation', () => {
  14. const ast = parse('<h1>{{msg}}</h1>', baseOptions)
  15. optimize(ast, baseOptions)
  16. expect(ast.static).toBe(false) // h1
  17. expect(ast.children[0].static).toBe(false) // text node with interpolation
  18. })
  19. it('nested elements', () => {
  20. const ast = parse('<ul><li>hello</li><li>world</li></ul>', baseOptions)
  21. optimize(ast, baseOptions)
  22. // ul
  23. expect(ast.static).toBe(true)
  24. expect(ast.staticRoot).toBe(true)
  25. // li
  26. expect(ast.children[0].static).toBe(true) // first
  27. expect(ast.children[1].static).toBe(true) // second
  28. // text node inside li
  29. expect(ast.children[0].children[0].static).toBe(true) // first
  30. expect(ast.children[1].children[0].static).toBe(true) // second
  31. })
  32. it('nested complex elements', () => {
  33. const ast = parse('<ul><li>{{msg1}}</li><li>---</li><li>{{msg2}}</li></ul>', baseOptions)
  34. optimize(ast, baseOptions)
  35. // ul
  36. expect(ast.static).toBe(false) // ul
  37. // li
  38. expect(ast.children[0].static).toBe(false) // firts
  39. expect(ast.children[1].static).toBe(true) // second
  40. expect(ast.children[2].static).toBe(false) // third
  41. // text node inside li
  42. expect(ast.children[0].children[0].static).toBe(false) // first
  43. expect(ast.children[1].children[0].static).toBe(true) // second
  44. expect(ast.children[2].children[0].static).toBe(false) // third
  45. })
  46. it('v-if directive', () => {
  47. const ast = parse('<h1 id="section1" v-if="show">hello world</h1>', baseOptions)
  48. optimize(ast, baseOptions)
  49. expect(ast.static).toBe(false)
  50. expect(ast.children[0].static).toBe(true)
  51. })
  52. it('v-else directive', () => {
  53. const ast = parse('<div><p v-if="show">hello world</p><p v-else>foo bar</p></div>', baseOptions)
  54. optimize(ast, baseOptions)
  55. expect(ast.static).toBe(false)
  56. expect(ast.children[0].static).toBe(false)
  57. expect(ast.children[0].elseBlock.static).toBeUndefined()
  58. })
  59. it('v-pre directive', () => {
  60. const ast = parse('<ul v-pre><li>{{msg}}</li><li>world</li></ul>', baseOptions)
  61. optimize(ast, baseOptions)
  62. expect(ast.static).toBe(true)
  63. expect(ast.staticRoot).toBe(true)
  64. expect(ast.children[0].static).toBe(true)
  65. expect(ast.children[1].static).toBe(true)
  66. expect(ast.children[0].children[0].static).toBe(true)
  67. expect(ast.children[1].children[0].static).toBe(true)
  68. })
  69. it('v-for directive', () => {
  70. const ast = parse('<ul><li v-for="item in items">hello world {{$index}}</li></ul>', baseOptions)
  71. optimize(ast, baseOptions)
  72. // ul
  73. expect(ast.static).toBe(false)
  74. // li with v-for
  75. expect(ast.children[0].static).toBe(false)
  76. expect(ast.children[0].children[0].static).toBe(false)
  77. })
  78. it('v-once directive', () => {
  79. const ast = parse('<p v-once>{{msg}}</p>', baseOptions)
  80. optimize(ast, baseOptions)
  81. expect(ast.static).toBe(false) // p
  82. expect(ast.children[0].static).toBe(false) // text node
  83. })
  84. it('render tag', () => {
  85. const ast = parse('<render :method="onRender"><p>hello</p></render>', baseOptions)
  86. optimize(ast, baseOptions)
  87. expect(ast.static).toBe(false)
  88. expect(ast.children[0].static).toBe(true)
  89. expect(ast.children[0].children[0].static).toBe(true)
  90. })
  91. it('single slot', () => {
  92. const ast = parse('<slot>hello</slot>', baseOptions)
  93. optimize(ast, baseOptions)
  94. expect(ast.static).toBe(false) // slot
  95. expect(ast.children[0].static).toBe(true) // text node
  96. })
  97. it('named slot', () => {
  98. const ast = parse('<slot name="one">hello world</slot>', baseOptions)
  99. optimize(ast, baseOptions)
  100. expect(ast.static).toBe(false) // slot
  101. expect(ast.children[0].static).toBe(true) // text node
  102. })
  103. it('slot target', () => {
  104. const ast = parse('<p slot="one">hello world</p>', baseOptions)
  105. optimize(ast, baseOptions)
  106. expect(ast.static).toBe(false) // slot
  107. expect(ast.children[0].static).toBe(true) // text node
  108. })
  109. it('component', () => {
  110. const ast = parse('<my-component></my-component>', baseOptions)
  111. optimize(ast, baseOptions)
  112. expect(ast.static).toBe(false) // component
  113. })
  114. it('component for inline-template', () => {
  115. const ast = parse('<my-component inline-template><p>hello world</p><p>{{msg}}</p></my-component>', baseOptions)
  116. optimize(ast, baseOptions)
  117. // component
  118. expect(ast.static).toBe(false) // component
  119. // p
  120. expect(ast.children[0].static).toBe(true) // first
  121. expect(ast.children[1].static).toBe(false) // second
  122. // text node inside p
  123. expect(ast.children[0].children[0].static).toBe(true) // first
  124. expect(ast.children[1].children[0].static).toBe(false) // second
  125. })
  126. it('class binding', () => {
  127. const ast = parse('<p :class="class1">hello world</p>', baseOptions)
  128. optimize(ast, baseOptions)
  129. expect(ast.static).toBe(false)
  130. expect(ast.children[0].static).toBe(true)
  131. })
  132. it('style binding', () => {
  133. const ast = parse('<p :style="error">{{msg}}</p>', baseOptions)
  134. optimize(ast, baseOptions)
  135. expect(ast.static).toBe(false)
  136. expect(ast.children[0].static).toBe(false)
  137. })
  138. it('transition', () => {
  139. const ast = parse('<p v-if="show" transition="expand">hello world</p>', baseOptions)
  140. optimize(ast, baseOptions)
  141. expect(ast.static).toBe(false)
  142. expect(ast.children[0].static).toBe(true)
  143. })
  144. it('v-bind directive', () => {
  145. const ast = parse('<input type="text" name="field1" :value="msg">', baseOptions)
  146. optimize(ast, baseOptions)
  147. expect(ast.static).toBe(false)
  148. })
  149. it('v-ref directive', () => {
  150. const ast = parse('<p v-ref:foo>hello world</p>', baseOptions)
  151. optimize(ast, baseOptions)
  152. expect(ast.static).toBe(false)
  153. expect(ast.children[0].static).toBe(true)
  154. })
  155. it('v-on directive', () => {
  156. const ast = parse('<input type="text" name="field1" :value="msg" @input="onInput">', baseOptions)
  157. optimize(ast, baseOptions)
  158. expect(ast.static).toBe(false)
  159. })
  160. it('custom directive', () => {
  161. const ast = parse('<fom><input type="text" name="field1" :value="msg" v-validate:field1="required"></form>', baseOptions)
  162. optimize(ast, baseOptions)
  163. expect(ast.static).toBe(false)
  164. expect(ast.children[0].static).toBe(false)
  165. })
  166. it('not root ast', () => {
  167. const ast = null
  168. optimize(ast, baseOptions)
  169. expect(ast).toBe(null)
  170. })
  171. it('not specified isReservedTag option', () => {
  172. const ast = parse('<h1 id="section1">hello world</h1>', baseOptions)
  173. optimize(ast, {})
  174. expect(ast.static).toBe(false)
  175. })
  176. })