ssrElement.spec.ts 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. import { getCompiledString } from './utils'
  2. import { compile } from '../src'
  3. describe('ssr: element', () => {
  4. test('basic elements', () => {
  5. expect(getCompiledString(`<div></div>`)).toMatchInlineSnapshot(
  6. `"\`<div></div>\`"`
  7. )
  8. expect(getCompiledString(`<div/>`)).toMatchInlineSnapshot(
  9. `"\`<div></div>\`"`
  10. )
  11. })
  12. test('nested elements', () => {
  13. expect(
  14. getCompiledString(`<div><span></span><span></span></div>`)
  15. ).toMatchInlineSnapshot(`"\`<div><span></span><span></span></div>\`"`)
  16. })
  17. test('void element', () => {
  18. expect(getCompiledString(`<input>`)).toMatchInlineSnapshot(`"\`<input>\`"`)
  19. })
  20. describe('children override', () => {
  21. test('v-html', () => {
  22. expect(getCompiledString(`<div v-html="foo"/>`)).toMatchInlineSnapshot(`
  23. "\`<div>\${
  24. _ctx.foo
  25. }</div>\`"
  26. `)
  27. })
  28. test('v-text', () => {
  29. expect(getCompiledString(`<div v-text="foo"/>`)).toMatchInlineSnapshot(`
  30. "\`<div>\${
  31. _ssrInterpolate(_ctx.foo)
  32. }</div>\`"
  33. `)
  34. })
  35. test('<textarea> with dynamic value', () => {
  36. expect(getCompiledString(`<textarea :value="foo"/>`))
  37. .toMatchInlineSnapshot(`
  38. "\`<textarea>\${
  39. _ssrInterpolate(_ctx.foo)
  40. }</textarea>\`"
  41. `)
  42. })
  43. test('<textarea> with static value', () => {
  44. expect(
  45. getCompiledString(`<textarea value="fo&gt;o"/>`)
  46. ).toMatchInlineSnapshot(`"\`<textarea>fo&gt;o</textarea>\`"`)
  47. })
  48. test('<textarea> with dynamic v-bind', () => {
  49. expect(compile(`<textarea v-bind="obj">fallback</textarea>`).code)
  50. .toMatchInlineSnapshot(`
  51. "const { mergeProps: _mergeProps } = require(\\"vue\\")
  52. const { ssrRenderAttrs: _ssrRenderAttrs, ssrInterpolate: _ssrInterpolate } = require(\\"@vue/server-renderer\\")
  53. return function ssrRender(_ctx, _push, _parent, _attrs) {
  54. let _temp0
  55. _push(\`<textarea\${
  56. _ssrRenderAttrs(_temp0 = _mergeProps(_ctx.obj, _attrs), \\"textarea\\")
  57. }>\${
  58. _ssrInterpolate((\\"value\\" in _temp0) ? _temp0.value : \\"fallback\\")
  59. }</textarea>\`)
  60. }"
  61. `)
  62. })
  63. test("multiple _ssrInterpolate at parent and child import dependency once", () => {
  64. expect( compile(`<div>{{ hello }}<textarea v-bind="a"></textarea></div>`).code)
  65. .toMatchInlineSnapshot(`
  66. "const { ssrRenderAttrs: _ssrRenderAttrs, ssrInterpolate: _ssrInterpolate } = require(\\"@vue/server-renderer\\")
  67. return function ssrRender(_ctx, _push, _parent, _attrs) {
  68. let _temp0
  69. _push(\`<div\${
  70. _ssrRenderAttrs(_attrs)
  71. }>\${
  72. _ssrInterpolate(_ctx.hello)
  73. }<textarea\${
  74. _ssrRenderAttrs(_temp0 = _ctx.a, \\"textarea\\")
  75. }>\${
  76. _ssrInterpolate((\\"value\\" in _temp0) ? _temp0.value : \\"\\")
  77. }</textarea></div>\`)
  78. }"
  79. `);
  80. });
  81. test('should pass tag to custom elements w/ dynamic v-bind', () => {
  82. expect(
  83. compile(`<my-foo v-bind="obj"></my-foo>`, {
  84. isCustomElement: () => true
  85. }).code
  86. ).toMatchInlineSnapshot(`
  87. "const { mergeProps: _mergeProps } = require(\\"vue\\")
  88. const { ssrRenderAttrs: _ssrRenderAttrs } = require(\\"@vue/server-renderer\\")
  89. return function ssrRender(_ctx, _push, _parent, _attrs) {
  90. _push(\`<my-foo\${_ssrRenderAttrs(_mergeProps(_ctx.obj, _attrs), \\"my-foo\\")}></my-foo>\`)
  91. }"
  92. `)
  93. })
  94. })
  95. describe('attrs', () => {
  96. test('static attrs', () => {
  97. expect(
  98. getCompiledString(`<div id="foo" class="bar"></div>`)
  99. ).toMatchInlineSnapshot(`"\`<div id=\\"foo\\" class=\\"bar\\"></div>\`"`)
  100. })
  101. test('ignore static key/ref', () => {
  102. expect(
  103. getCompiledString(`<div key="1" ref="el"></div>`)
  104. ).toMatchInlineSnapshot(`"\`<div></div>\`"`)
  105. })
  106. test('ignore v-bind key/ref', () => {
  107. expect(
  108. getCompiledString(`<div :key="1" :ref="el"></div>`)
  109. ).toMatchInlineSnapshot(`"\`<div></div>\`"`)
  110. })
  111. test('v-bind:class', () => {
  112. expect(getCompiledString(`<div id="foo" :class="bar"></div>`))
  113. .toMatchInlineSnapshot(`
  114. "\`<div id=\\"foo\\" class=\\"\${
  115. _ssrRenderClass(_ctx.bar)
  116. }\\"></div>\`"
  117. `)
  118. })
  119. test('static class + v-bind:class', () => {
  120. expect(getCompiledString(`<div class="foo" :class="bar"></div>`))
  121. .toMatchInlineSnapshot(`
  122. "\`<div class=\\"\${
  123. _ssrRenderClass([_ctx.bar, \\"foo\\"])
  124. }\\"></div>\`"
  125. `)
  126. })
  127. test('v-bind:class + static class', () => {
  128. expect(getCompiledString(`<div :class="bar" class="foo"></div>`))
  129. .toMatchInlineSnapshot(`
  130. "\`<div class=\\"\${
  131. _ssrRenderClass([_ctx.bar, \\"foo\\"])
  132. }\\"></div>\`"
  133. `)
  134. })
  135. test('v-bind:style', () => {
  136. expect(getCompiledString(`<div id="foo" :style="bar"></div>`))
  137. .toMatchInlineSnapshot(`
  138. "\`<div id=\\"foo\\" style=\\"\${
  139. _ssrRenderStyle(_ctx.bar)
  140. }\\"></div>\`"
  141. `)
  142. })
  143. test('static style + v-bind:style', () => {
  144. expect(getCompiledString(`<div style="color:red;" :style="bar"></div>`))
  145. .toMatchInlineSnapshot(`
  146. "\`<div style=\\"\${
  147. _ssrRenderStyle([{\\"color\\":\\"red\\"}, _ctx.bar])
  148. }\\"></div>\`"
  149. `)
  150. })
  151. test('v-bind:arg (boolean)', () => {
  152. expect(getCompiledString(`<input type="checkbox" :checked="checked">`))
  153. .toMatchInlineSnapshot(`
  154. "\`<input type=\\"checkbox\\"\${
  155. (_ctx.checked) ? \\" checked\\" : \\"\\"
  156. }>\`"
  157. `)
  158. })
  159. test('v-bind:arg (non-boolean)', () => {
  160. expect(getCompiledString(`<div :id="id" class="bar"></div>`))
  161. .toMatchInlineSnapshot(`
  162. "\`<div\${
  163. _ssrRenderAttr(\\"id\\", _ctx.id)
  164. } class=\\"bar\\"></div>\`"
  165. `)
  166. })
  167. test('v-bind:[arg]', () => {
  168. expect(getCompiledString(`<div v-bind:[key]="value"></div>`))
  169. .toMatchInlineSnapshot(`
  170. "\`<div\${
  171. _ssrRenderAttrs({ [_ctx.key || \\"\\"]: _ctx.value })
  172. }></div>\`"
  173. `)
  174. expect(getCompiledString(`<div class="foo" v-bind:[key]="value"></div>`))
  175. .toMatchInlineSnapshot(`
  176. "\`<div\${
  177. _ssrRenderAttrs({
  178. class: \\"foo\\",
  179. [_ctx.key || \\"\\"]: _ctx.value
  180. })
  181. }></div>\`"
  182. `)
  183. expect(getCompiledString(`<div :id="id" v-bind:[key]="value"></div>`))
  184. .toMatchInlineSnapshot(`
  185. "\`<div\${
  186. _ssrRenderAttrs({
  187. id: _ctx.id,
  188. [_ctx.key || \\"\\"]: _ctx.value
  189. })
  190. }></div>\`"
  191. `)
  192. })
  193. test('v-bind="obj"', () => {
  194. expect(getCompiledString(`<div v-bind="obj"></div>`))
  195. .toMatchInlineSnapshot(`
  196. "\`<div\${
  197. _ssrRenderAttrs(_ctx.obj)
  198. }></div>\`"
  199. `)
  200. expect(getCompiledString(`<div class="foo" v-bind="obj"></div>`))
  201. .toMatchInlineSnapshot(`
  202. "\`<div\${
  203. _ssrRenderAttrs(_mergeProps({ class: \\"foo\\" }, _ctx.obj))
  204. }></div>\`"
  205. `)
  206. expect(getCompiledString(`<div :id="id" v-bind="obj"></div>`))
  207. .toMatchInlineSnapshot(`
  208. "\`<div\${
  209. _ssrRenderAttrs(_mergeProps({ id: _ctx.id }, _ctx.obj))
  210. }></div>\`"
  211. `)
  212. // dynamic key + v-bind="object"
  213. expect(getCompiledString(`<div :[key]="id" v-bind="obj"></div>`))
  214. .toMatchInlineSnapshot(`
  215. "\`<div\${
  216. _ssrRenderAttrs(_mergeProps({ [_ctx.key || \\"\\"]: _ctx.id }, _ctx.obj))
  217. }></div>\`"
  218. `)
  219. // should merge class and :class
  220. expect(getCompiledString(`<div class="a" :class="b" v-bind="obj"></div>`))
  221. .toMatchInlineSnapshot(`
  222. "\`<div\${
  223. _ssrRenderAttrs(_mergeProps({
  224. class: [\\"a\\", _ctx.b]
  225. }, _ctx.obj))
  226. }></div>\`"
  227. `)
  228. // should merge style and :style
  229. expect(
  230. getCompiledString(
  231. `<div style="color:red;" :style="b" v-bind="obj"></div>`
  232. )
  233. ).toMatchInlineSnapshot(`
  234. "\`<div\${
  235. _ssrRenderAttrs(_mergeProps({
  236. style: [{\\"color\\":\\"red\\"}, _ctx.b]
  237. }, _ctx.obj))
  238. }></div>\`"
  239. `)
  240. })
  241. test('should ignore v-on', () => {
  242. expect(
  243. getCompiledString(`<div id="foo" @click="bar"/>`)
  244. ).toMatchInlineSnapshot(`"\`<div id=\\"foo\\"></div>\`"`)
  245. expect(
  246. getCompiledString(`<div id="foo" v-on="bar"/>`)
  247. ).toMatchInlineSnapshot(`"\`<div id=\\"foo\\"></div>\`"`)
  248. expect(getCompiledString(`<div v-bind="foo" v-on="bar"/>`))
  249. .toMatchInlineSnapshot(`
  250. "\`<div\${
  251. _ssrRenderAttrs(_ctx.foo)
  252. }></div>\`"
  253. `)
  254. })
  255. })
  256. })