compile.spec.ts 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. import { compile } from '../src'
  2. import { SourceMapConsumer, RawSourceMap } from 'source-map'
  3. describe('compiler: integration tests', () => {
  4. const source = `
  5. <div id="foo" :class="bar">
  6. {{ world }}
  7. <div v-if="ok">yes</div>
  8. <template v-else>no</template>
  9. <div v-for="(value, index) in list"><span>{{ value + index }}</span></div>
  10. </div>
  11. `.trim()
  12. function getPositionInCode(code: string, token: string) {
  13. const generatedOffset = code.indexOf(token)
  14. let line = 1
  15. let lastNewLinePos = -1
  16. for (let i = 0; i < generatedOffset; i++) {
  17. if (code.charCodeAt(i) === 10 /* newline char code */) {
  18. line++
  19. lastNewLinePos = i
  20. }
  21. }
  22. return {
  23. line,
  24. column:
  25. lastNewLinePos === -1
  26. ? generatedOffset
  27. : generatedOffset - lastNewLinePos - 1
  28. }
  29. }
  30. test('function mode', async () => {
  31. const { code, map } = compile(source, {
  32. sourceMap: true,
  33. filename: `foo.vue`
  34. })
  35. expect(code).toMatch(
  36. `const { createVNode: _createVNode, toString: _toString, renderList: _renderList } = _Vue`
  37. )
  38. expect(code).toMatchSnapshot()
  39. expect(map!.sources).toEqual([`foo.vue`])
  40. expect(map!.sourcesContent).toEqual([source])
  41. const consumer = await new SourceMapConsumer(map as RawSourceMap)
  42. expect(
  43. consumer.originalPositionFor(getPositionInCode(code, `id`))
  44. ).toMatchObject(getPositionInCode(source, `id`))
  45. expect(
  46. consumer.originalPositionFor(getPositionInCode(code, `"foo"`))
  47. ).toMatchObject(getPositionInCode(source, `"foo"`))
  48. expect(
  49. consumer.originalPositionFor(getPositionInCode(code, `class:`))
  50. ).toMatchObject(getPositionInCode(source, `class=`))
  51. expect(
  52. consumer.originalPositionFor(getPositionInCode(code, `bar`))
  53. ).toMatchObject(getPositionInCode(source, `bar`))
  54. expect(
  55. consumer.originalPositionFor(getPositionInCode(code, `world`))
  56. ).toMatchObject(getPositionInCode(source, `{{ world }}`))
  57. expect(
  58. consumer.originalPositionFor(getPositionInCode(code, `ok`))
  59. ).toMatchObject(getPositionInCode(source, `ok`))
  60. expect(
  61. consumer.originalPositionFor(getPositionInCode(code, `list`))
  62. ).toMatchObject(getPositionInCode(source, `list`))
  63. expect(
  64. consumer.originalPositionFor(getPositionInCode(code, `value`))
  65. ).toMatchObject(getPositionInCode(source, `value`))
  66. expect(
  67. consumer.originalPositionFor(getPositionInCode(code, `index`))
  68. ).toMatchObject(getPositionInCode(source, `index`))
  69. expect(
  70. consumer.originalPositionFor(getPositionInCode(code, `value + index`))
  71. ).toMatchObject(getPositionInCode(source, `{{ value + index }}`))
  72. })
  73. test('function mode w/ prefixIdentifiers: true', async () => {
  74. const { code, map } = compile(source, {
  75. sourceMap: true,
  76. filename: `foo.vue`,
  77. prefixIdentifiers: true
  78. })
  79. expect(code).toMatch(`const { createVNode, toString, renderList } = Vue`)
  80. expect(code).toMatchSnapshot()
  81. expect(map!.sources).toEqual([`foo.vue`])
  82. expect(map!.sourcesContent).toEqual([source])
  83. const consumer = await new SourceMapConsumer(map as RawSourceMap)
  84. expect(
  85. consumer.originalPositionFor(getPositionInCode(code, `id`))
  86. ).toMatchObject(getPositionInCode(source, `id`))
  87. expect(
  88. consumer.originalPositionFor(getPositionInCode(code, `"foo"`))
  89. ).toMatchObject(getPositionInCode(source, `"foo"`))
  90. expect(
  91. consumer.originalPositionFor(getPositionInCode(code, `class:`))
  92. ).toMatchObject(getPositionInCode(source, `class=`))
  93. expect(
  94. consumer.originalPositionFor(getPositionInCode(code, `bar`))
  95. ).toMatchObject(getPositionInCode(source, `bar`))
  96. expect(
  97. consumer.originalPositionFor(getPositionInCode(code, `_ctx.bar`))
  98. ).toMatchObject(getPositionInCode(source, `bar`))
  99. expect(
  100. consumer.originalPositionFor(getPositionInCode(code, `world`))
  101. ).toMatchObject(getPositionInCode(source, `{{ world }}`))
  102. expect(
  103. consumer.originalPositionFor(getPositionInCode(code, `_ctx.world`))
  104. ).toMatchObject(getPositionInCode(source, `{{ world }}`))
  105. expect(
  106. consumer.originalPositionFor(getPositionInCode(code, `ok`))
  107. ).toMatchObject(getPositionInCode(source, `ok`))
  108. expect(
  109. consumer.originalPositionFor(getPositionInCode(code, `_ctx.ok`))
  110. ).toMatchObject(getPositionInCode(source, `ok`))
  111. expect(
  112. consumer.originalPositionFor(getPositionInCode(code, `list`))
  113. ).toMatchObject(getPositionInCode(source, `list`))
  114. expect(
  115. consumer.originalPositionFor(getPositionInCode(code, `_ctx.list`))
  116. ).toMatchObject(getPositionInCode(source, `list`))
  117. expect(
  118. consumer.originalPositionFor(getPositionInCode(code, `value`))
  119. ).toMatchObject(getPositionInCode(source, `value`))
  120. expect(
  121. consumer.originalPositionFor(getPositionInCode(code, `index`))
  122. ).toMatchObject(getPositionInCode(source, `index`))
  123. expect(
  124. consumer.originalPositionFor(getPositionInCode(code, `value + index`))
  125. ).toMatchObject(getPositionInCode(source, `value + index`))
  126. })
  127. test('module mode', async () => {
  128. const { code, map } = compile(source, {
  129. mode: 'module',
  130. sourceMap: true,
  131. filename: `foo.vue`
  132. })
  133. expect(code).toMatch(
  134. `import { createVNode, toString, renderList } from "vue"`
  135. )
  136. expect(code).toMatchSnapshot()
  137. expect(map!.sources).toEqual([`foo.vue`])
  138. expect(map!.sourcesContent).toEqual([source])
  139. const consumer = await new SourceMapConsumer(map as RawSourceMap)
  140. expect(
  141. consumer.originalPositionFor(getPositionInCode(code, `id`))
  142. ).toMatchObject(getPositionInCode(source, `id`))
  143. expect(
  144. consumer.originalPositionFor(getPositionInCode(code, `"foo"`))
  145. ).toMatchObject(getPositionInCode(source, `"foo"`))
  146. expect(
  147. consumer.originalPositionFor(getPositionInCode(code, `class:`))
  148. ).toMatchObject(getPositionInCode(source, `class=`))
  149. expect(
  150. consumer.originalPositionFor(getPositionInCode(code, `bar`))
  151. ).toMatchObject(getPositionInCode(source, `bar`))
  152. expect(
  153. consumer.originalPositionFor(getPositionInCode(code, `_ctx.bar`))
  154. ).toMatchObject(getPositionInCode(source, `bar`))
  155. expect(
  156. consumer.originalPositionFor(getPositionInCode(code, `world`))
  157. ).toMatchObject(getPositionInCode(source, `{{ world }}`))
  158. expect(
  159. consumer.originalPositionFor(getPositionInCode(code, `_ctx.world`))
  160. ).toMatchObject(getPositionInCode(source, `{{ world }}`))
  161. expect(
  162. consumer.originalPositionFor(getPositionInCode(code, `ok`))
  163. ).toMatchObject(getPositionInCode(source, `ok`))
  164. expect(
  165. consumer.originalPositionFor(getPositionInCode(code, `_ctx.ok`))
  166. ).toMatchObject(getPositionInCode(source, `ok`))
  167. expect(
  168. consumer.originalPositionFor(getPositionInCode(code, `list`))
  169. ).toMatchObject(getPositionInCode(source, `list`))
  170. expect(
  171. consumer.originalPositionFor(getPositionInCode(code, `_ctx.list`))
  172. ).toMatchObject(getPositionInCode(source, `list`))
  173. expect(
  174. consumer.originalPositionFor(getPositionInCode(code, `value`))
  175. ).toMatchObject(getPositionInCode(source, `value`))
  176. expect(
  177. consumer.originalPositionFor(getPositionInCode(code, `index`))
  178. ).toMatchObject(getPositionInCode(source, `index`))
  179. expect(
  180. consumer.originalPositionFor(getPositionInCode(code, `value + index`))
  181. ).toMatchObject(getPositionInCode(source, `value + index`))
  182. })
  183. })