ssrElement.spec.ts 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  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>\${_ctx.foo}</div>\`"`
  24. )
  25. })
  26. test('v-text', () => {
  27. expect(getCompiledString(`<div v-text="foo"/>`)).toMatchInlineSnapshot(
  28. `"\`<div>\${_ssrInterpolate(_ctx.foo)}</div>\`"`
  29. )
  30. })
  31. test('<textarea> with dynamic value', () => {
  32. expect(
  33. getCompiledString(`<textarea :value="foo"/>`)
  34. ).toMatchInlineSnapshot(
  35. `"\`<textarea>\${_ssrInterpolate(_ctx.foo)}</textarea>\`"`
  36. )
  37. })
  38. test('<textarea> with static value', () => {
  39. expect(
  40. getCompiledString(`<textarea value="fo&gt;o"/>`)
  41. ).toMatchInlineSnapshot(`"\`<textarea>fo&gt;o</textarea>\`"`)
  42. })
  43. test('<textarea> with dynamic v-bind', () => {
  44. expect(compile(`<textarea v-bind="obj">fallback</textarea>`).code)
  45. .toMatchInlineSnapshot(`
  46. "const { ssrRenderAttrs: _ssrRenderAttrs, ssrInterpolate: _ssrInterpolate } = require(\\"@vue/server-renderer\\")
  47. return function ssrRender(_ctx, _push, _parent) {
  48. let _temp0
  49. _push(\`<textarea\${
  50. _ssrRenderAttrs(_temp0 = _ctx.obj, \\"textarea\\")
  51. }>\${
  52. _ssrInterpolate((\\"value\\" in _temp0) ? _temp0.value : \\"fallback\\")
  53. }</textarea>\`)
  54. }"
  55. `)
  56. })
  57. test('should pass tag to custom elements w/ dynamic v-bind', () => {
  58. expect(
  59. compile(`<my-foo v-bind="obj"></my-foo>`, {
  60. isCustomElement: () => true
  61. }).code
  62. ).toMatchInlineSnapshot(`
  63. "const { ssrRenderAttrs: _ssrRenderAttrs } = require(\\"@vue/server-renderer\\")
  64. return function ssrRender(_ctx, _push, _parent) {
  65. _push(\`<my-foo\${_ssrRenderAttrs(_ctx.obj, \\"my-foo\\")}></my-foo>\`)
  66. }"
  67. `)
  68. })
  69. })
  70. describe('attrs', () => {
  71. test('static attrs', () => {
  72. expect(
  73. getCompiledString(`<div id="foo" class="bar"></div>`)
  74. ).toMatchInlineSnapshot(`"\`<div id=\\"foo\\" class=\\"bar\\"></div>\`"`)
  75. })
  76. test('v-bind:class', () => {
  77. expect(
  78. getCompiledString(`<div id="foo" :class="bar"></div>`)
  79. ).toMatchInlineSnapshot(
  80. `"\`<div id=\\"foo\\" class=\\"\${_ssrRenderClass(_ctx.bar)}\\"></div>\`"`
  81. )
  82. })
  83. test('static class + v-bind:class', () => {
  84. expect(
  85. getCompiledString(`<div class="foo" :class="bar"></div>`)
  86. ).toMatchInlineSnapshot(
  87. `"\`<div class=\\"\${_ssrRenderClass([_ctx.bar, \\"foo\\"])}\\"></div>\`"`
  88. )
  89. })
  90. test('v-bind:style', () => {
  91. expect(
  92. getCompiledString(`<div id="foo" :style="bar"></div>`)
  93. ).toMatchInlineSnapshot(
  94. `"\`<div id=\\"foo\\" style=\\"\${_ssrRenderStyle(_ctx.bar)}\\"></div>\`"`
  95. )
  96. })
  97. test('static style + v-bind:style', () => {
  98. expect(
  99. getCompiledString(`<div style="color:red;" :style="bar"></div>`)
  100. ).toMatchInlineSnapshot(
  101. `"\`<div style=\\"\${_ssrRenderStyle([{\\"color\\":\\"red\\"}, _ctx.bar])}\\"></div>\`"`
  102. )
  103. })
  104. test('v-bind:key (boolean)', () => {
  105. expect(
  106. getCompiledString(`<input type="checkbox" :checked="checked">`)
  107. ).toMatchInlineSnapshot(
  108. `"\`<input type=\\"checkbox\\"\${(_ctx.checked) ? \\" checked\\" : \\"\\"}>\`"`
  109. )
  110. })
  111. test('v-bind:key (non-boolean)', () => {
  112. expect(
  113. getCompiledString(`<div :id="id" class="bar"></div>`)
  114. ).toMatchInlineSnapshot(
  115. `"\`<div\${_ssrRenderAttr(\\"id\\", _ctx.id)} class=\\"bar\\"></div>\`"`
  116. )
  117. })
  118. test('v-bind:[key]', () => {
  119. expect(
  120. getCompiledString(`<div v-bind:[key]="value"></div>`)
  121. ).toMatchInlineSnapshot(
  122. `"\`<div\${_ssrRenderAttrs({ [_ctx.key]: _ctx.value })}></div>\`"`
  123. )
  124. expect(getCompiledString(`<div class="foo" v-bind:[key]="value"></div>`))
  125. .toMatchInlineSnapshot(`
  126. "\`<div\${_ssrRenderAttrs({
  127. class: \\"foo\\",
  128. [_ctx.key]: _ctx.value
  129. })}></div>\`"
  130. `)
  131. expect(getCompiledString(`<div :id="id" v-bind:[key]="value"></div>`))
  132. .toMatchInlineSnapshot(`
  133. "\`<div\${_ssrRenderAttrs({
  134. id: _ctx.id,
  135. [_ctx.key]: _ctx.value
  136. })}></div>\`"
  137. `)
  138. })
  139. test('v-bind="obj"', () => {
  140. expect(
  141. getCompiledString(`<div v-bind="obj"></div>`)
  142. ).toMatchInlineSnapshot(`"\`<div\${_ssrRenderAttrs(_ctx.obj)}></div>\`"`)
  143. expect(
  144. getCompiledString(`<div class="foo" v-bind="obj"></div>`)
  145. ).toMatchInlineSnapshot(
  146. `"\`<div\${_ssrRenderAttrs(_mergeProps({ class: \\"foo\\" }, _ctx.obj))}></div>\`"`
  147. )
  148. expect(
  149. getCompiledString(`<div :id="id" v-bind="obj"></div>`)
  150. ).toMatchInlineSnapshot(
  151. `"\`<div\${_ssrRenderAttrs(_mergeProps({ id: _ctx.id }, _ctx.obj))}></div>\`"`
  152. )
  153. // dynamic key + v-bind="object"
  154. expect(
  155. getCompiledString(`<div :[key]="id" v-bind="obj"></div>`)
  156. ).toMatchInlineSnapshot(
  157. `"\`<div\${_ssrRenderAttrs(_mergeProps({ [_ctx.key]: _ctx.id }, _ctx.obj))}></div>\`"`
  158. )
  159. // should merge class and :class
  160. expect(getCompiledString(`<div class="a" :class="b" v-bind="obj"></div>`))
  161. .toMatchInlineSnapshot(`
  162. "\`<div\${_ssrRenderAttrs(_mergeProps({
  163. class: [\\"a\\", _ctx.b]
  164. }, _ctx.obj))}></div>\`"
  165. `)
  166. // should merge style and :style
  167. expect(
  168. getCompiledString(
  169. `<div style="color:red;" :style="b" v-bind="obj"></div>`
  170. )
  171. ).toMatchInlineSnapshot(`
  172. "\`<div\${_ssrRenderAttrs(_mergeProps({
  173. style: [{\\"color\\":\\"red\\"}, _ctx.b]
  174. }, _ctx.obj))}></div>\`"
  175. `)
  176. })
  177. test('should ignore v-on', () => {
  178. expect(
  179. getCompiledString(`<div id="foo" @click="bar"/>`)
  180. ).toMatchInlineSnapshot(`"\`<div id=\\"foo\\"></div>\`"`)
  181. expect(
  182. getCompiledString(`<div id="foo" v-on="bar"/>`)
  183. ).toMatchInlineSnapshot(`"\`<div id=\\"foo\\"></div>\`"`)
  184. expect(
  185. getCompiledString(`<div v-bind="foo" v-on="bar"/>`)
  186. ).toMatchInlineSnapshot(`"\`<div\${_ssrRenderAttrs(_ctx.foo)}></div>\`"`)
  187. })
  188. })
  189. })