compile.spec.ts 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. import { BindingTypes, type RootNode } from '@vue/compiler-dom'
  2. import { type CompilerOptions, compile as _compile } from '../src'
  3. function compile(template: string | RootNode, options: CompilerOptions = {}) {
  4. let { code } = _compile(template, {
  5. ...options,
  6. mode: 'module',
  7. prefixIdentifiers: true,
  8. })
  9. return code
  10. }
  11. describe('compile', () => {
  12. test('static template', () => {
  13. const code = compile(
  14. `<div>
  15. <p>hello</p>
  16. <input />
  17. <span />
  18. </div>`,
  19. )
  20. expect(code).matchSnapshot()
  21. })
  22. test('dynamic root', () => {
  23. const code = compile(`{{ 1 }}{{ 2 }}`)
  24. expect(code).matchSnapshot()
  25. })
  26. test('dynamic root nodes and interpolation', () => {
  27. const code = compile(
  28. `<button @click="handleClick" :id="count">{{count}}foo{{count}}foo{{count}} </button>`,
  29. )
  30. expect(code).matchSnapshot()
  31. })
  32. test('static + dynamic root', () => {
  33. const code = compile(
  34. `{{ 1 }}{{ 2 }}3{{ 4 }}{{ 5 }}6{{ 7 }}{{ 8 }}9{{ 'A' }}{{ 'B' }}`,
  35. )
  36. expect(code).matchSnapshot()
  37. })
  38. test('fragment', () => {
  39. const code = compile(`<p/><span/><div/>`)
  40. expect(code).matchSnapshot()
  41. })
  42. test('bindings', () => {
  43. const code = compile(`<div>count is {{ count }}.</div>`, {
  44. bindingMetadata: {
  45. count: BindingTypes.SETUP_REF,
  46. },
  47. })
  48. expect(code).matchSnapshot()
  49. })
  50. describe('directives', () => {
  51. describe('v-pre', () => {
  52. test('basic', () => {
  53. const code = compile(`<div v-pre :id="foo"><Comp/>{{ bar }}</div>\n`, {
  54. bindingMetadata: {
  55. foo: BindingTypes.SETUP_REF,
  56. bar: BindingTypes.SETUP_REF,
  57. },
  58. })
  59. expect(code).toMatchSnapshot()
  60. expect(code).contains(
  61. JSON.stringify('<div :id="foo"><Comp></Comp>{{ bar }}</div>'),
  62. )
  63. expect(code).not.contains('effect')
  64. })
  65. test('should not affect siblings after it', () => {
  66. const code = compile(
  67. `<div v-pre :id="foo"><Comp/>{{ bar }}</div>\n` +
  68. `<div :id="foo"><Comp/>{{ bar }}</div>`,
  69. {
  70. bindingMetadata: {
  71. foo: BindingTypes.SETUP_REF,
  72. bar: BindingTypes.SETUP_REF,
  73. },
  74. },
  75. )
  76. expect(code).toMatchSnapshot()
  77. // Waiting for TODO, There should be more here.
  78. })
  79. })
  80. describe('v-cloak', () => {
  81. test('basic', () => {
  82. const code = compile(`<div v-cloak>test</div>`)
  83. expect(code).toMatchSnapshot()
  84. expect(code).not.contains('v-cloak')
  85. })
  86. })
  87. describe('custom directive', () => {
  88. test('basic', () => {
  89. const code = compile(`<div v-example></div>`, {
  90. bindingMetadata: {
  91. vExample: BindingTypes.SETUP_CONST,
  92. },
  93. })
  94. expect(code).matchSnapshot()
  95. })
  96. test('binding value', () => {
  97. const code = compile(`<div v-example="msg"></div>`, {
  98. bindingMetadata: {
  99. msg: BindingTypes.SETUP_REF,
  100. vExample: BindingTypes.SETUP_CONST,
  101. },
  102. })
  103. expect(code).matchSnapshot()
  104. })
  105. test('static parameters', () => {
  106. const code = compile(`<div v-example:foo="msg"></div>`, {
  107. bindingMetadata: {
  108. msg: BindingTypes.SETUP_REF,
  109. vExample: BindingTypes.SETUP_CONST,
  110. },
  111. })
  112. expect(code).matchSnapshot()
  113. })
  114. test('modifiers', () => {
  115. const code = compile(`<div v-example.bar="msg"></div>`, {
  116. bindingMetadata: {
  117. msg: BindingTypes.SETUP_REF,
  118. vExample: BindingTypes.SETUP_CONST,
  119. },
  120. })
  121. expect(code).matchSnapshot()
  122. })
  123. test('modifiers w/o binding', () => {
  124. const code = compile(`<div v-example.foo-bar></div>`, {
  125. bindingMetadata: {
  126. vExample: BindingTypes.SETUP_CONST,
  127. },
  128. })
  129. expect(code).matchSnapshot()
  130. })
  131. test('static parameters and modifiers', () => {
  132. const code = compile(`<div v-example:foo.bar="msg"></div>`, {
  133. bindingMetadata: {
  134. msg: BindingTypes.SETUP_REF,
  135. vExample: BindingTypes.SETUP_CONST,
  136. },
  137. })
  138. expect(code).matchSnapshot()
  139. })
  140. test('dynamic parameters', () => {
  141. const code = compile(`<div v-example:[foo]="msg"></div>`, {
  142. bindingMetadata: {
  143. foo: BindingTypes.SETUP_REF,
  144. vExample: BindingTypes.SETUP_CONST,
  145. },
  146. })
  147. expect(code).matchSnapshot()
  148. })
  149. })
  150. })
  151. describe('expression parsing', () => {
  152. test('interpolation', () => {
  153. const code = compile(`{{ a + b }}`, {
  154. inline: true,
  155. bindingMetadata: {
  156. b: BindingTypes.SETUP_REF,
  157. },
  158. })
  159. expect(code).matchSnapshot()
  160. expect(code).contains('a + b.value')
  161. })
  162. test('v-bind', () => {
  163. const code = compile(`<div :[key+1]="foo[key+1]()" />`, {
  164. inline: true,
  165. bindingMetadata: {
  166. key: BindingTypes.SETUP_REF,
  167. foo: BindingTypes.SETUP_MAYBE_REF,
  168. },
  169. })
  170. expect(code).matchSnapshot()
  171. expect(code).contains('key.value+1')
  172. expect(code).contains('_unref(foo)[key.value+1]()')
  173. })
  174. // TODO: add more test for expression parsing (v-on, v-slot, v-for)
  175. })
  176. describe('custom directive', () => {
  177. test('basic', () => {
  178. const code = compile(`<div v-test v-hello.world />`)
  179. expect(code).matchSnapshot()
  180. })
  181. test('component', () => {
  182. const code = compile(`
  183. <Comp v-test>
  184. <div v-if="true">
  185. <Bar v-hello.world />
  186. </div>
  187. </Comp>
  188. `)
  189. expect(code).matchSnapshot()
  190. })
  191. })
  192. })