compile.spec.ts 5.8 KB

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