| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399 |
- import { getCompiledString } from './utils'
- import { compile } from '../src'
- describe('ssr: element', () => {
- test('basic elements', () => {
- expect(getCompiledString(`<div></div>`)).toMatchInlineSnapshot(
- `"\`<div></div>\`"`,
- )
- expect(getCompiledString(`<div/>`)).toMatchInlineSnapshot(
- `"\`<div></div>\`"`,
- )
- })
- test('nested elements', () => {
- expect(
- getCompiledString(`<div><span></span><span></span></div>`),
- ).toMatchInlineSnapshot(`"\`<div><span></span><span></span></div>\`"`)
- })
- test('void element', () => {
- expect(getCompiledString(`<input>`)).toMatchInlineSnapshot(`"\`<input>\`"`)
- })
- describe('children override', () => {
- test('v-html', () => {
- expect(getCompiledString(`<div v-html="foo"/>`)).toMatchInlineSnapshot(`
- "\`<div>\${
- (_ctx.foo) ?? ''
- }</div>\`"
- `)
- })
- test('v-text', () => {
- expect(getCompiledString(`<div v-text="foo"/>`)).toMatchInlineSnapshot(`
- "\`<div>\${
- _ssrInterpolate(_ctx.foo)
- }</div>\`"
- `)
- })
- test('<textarea> with dynamic value', () => {
- expect(getCompiledString(`<textarea :value="foo"/>`))
- .toMatchInlineSnapshot(`
- "\`<textarea>\${
- _ssrInterpolate(_ctx.foo)
- }</textarea>\`"
- `)
- })
- test('<textarea> with static value', () => {
- expect(
- getCompiledString(`<textarea value="fo>o"/>`),
- ).toMatchInlineSnapshot(`"\`<textarea>fo>o</textarea>\`"`)
- })
- test('<textarea> with dynamic v-bind', () => {
- expect(compile(`<textarea v-bind="obj">fallback</textarea>`).code)
- .toMatchInlineSnapshot(`
- "const { mergeProps: _mergeProps } = require("vue")
- const { ssrRenderAttrs: _ssrRenderAttrs, ssrInterpolate: _ssrInterpolate } = require("vue/server-renderer")
- return function ssrRender(_ctx, _push, _parent, _attrs) {
- let _temp0
- _push(\`<textarea\${
- _ssrRenderAttrs(_temp0 = _mergeProps(_ctx.obj, _attrs), "textarea")
- }>\${
- _ssrInterpolate(("value" in _temp0) ? _temp0.value : "fallback")
- }</textarea>\`)
- }"
- `)
- })
- test('multiple _ssrInterpolate at parent and child import dependency once', () => {
- expect(
- compile(`<div>{{ hello }}<textarea v-bind="a"></textarea></div>`).code,
- ).toMatchInlineSnapshot(`
- "const { ssrRenderAttrs: _ssrRenderAttrs, ssrInterpolate: _ssrInterpolate } = require("vue/server-renderer")
- return function ssrRender(_ctx, _push, _parent, _attrs) {
- let _temp0
- _push(\`<div\${
- _ssrRenderAttrs(_attrs)
- }>\${
- _ssrInterpolate(_ctx.hello)
- }<textarea\${
- _ssrRenderAttrs(_temp0 = _ctx.a, "textarea")
- }>\${
- _ssrInterpolate(("value" in _temp0) ? _temp0.value : "")
- }</textarea></div>\`)
- }"
- `)
- })
- test('should pass tag to custom elements w/ dynamic v-bind', () => {
- expect(
- compile(`<my-foo v-bind="obj"></my-foo>`, {
- isCustomElement: () => true,
- }).code,
- ).toMatchInlineSnapshot(`
- "const { mergeProps: _mergeProps } = require("vue")
- const { ssrRenderAttrs: _ssrRenderAttrs } = require("vue/server-renderer")
- return function ssrRender(_ctx, _push, _parent, _attrs) {
- _push(\`<my-foo\${_ssrRenderAttrs(_mergeProps(_ctx.obj, _attrs), "my-foo")}></my-foo>\`)
- }"
- `)
- })
- })
- describe('attrs', () => {
- test('static attrs', () => {
- expect(
- getCompiledString(`<div id="foo" class="bar"></div>`),
- ).toMatchInlineSnapshot(`"\`<div id="foo" class="bar"></div>\`"`)
- })
- test('ignore static key/ref', () => {
- expect(
- getCompiledString(`<div key="1" ref="el"></div>`),
- ).toMatchInlineSnapshot(`"\`<div></div>\`"`)
- })
- test('ignore v-bind key/ref', () => {
- expect(
- getCompiledString(`<div :key="1" :ref="el"></div>`),
- ).toMatchInlineSnapshot(`"\`<div></div>\`"`)
- })
- test('v-bind:class', () => {
- expect(getCompiledString(`<div id="foo" :class="bar"></div>`))
- .toMatchInlineSnapshot(`
- "\`<div id="foo" class="\${
- _ssrRenderClass(_ctx.bar)
- }"></div>\`"
- `)
- })
- test('static class + v-bind:class', () => {
- expect(getCompiledString(`<div class="foo" :class="bar"></div>`))
- .toMatchInlineSnapshot(`
- "\`<div class="\${
- _ssrRenderClass([_ctx.bar, "foo"])
- }"></div>\`"
- `)
- })
- test('v-bind:class + static class', () => {
- expect(getCompiledString(`<div :class="bar" class="foo"></div>`))
- .toMatchInlineSnapshot(`
- "\`<div class="\${
- _ssrRenderClass([_ctx.bar, "foo"])
- }"></div>\`"
- `)
- })
- test('v-bind:style', () => {
- expect(getCompiledString(`<div id="foo" :style="bar"></div>`))
- .toMatchInlineSnapshot(`
- "\`<div id="foo" style="\${
- _ssrRenderStyle(_ctx.bar)
- }"></div>\`"
- `)
- })
- test('static style + v-bind:style', () => {
- expect(getCompiledString(`<div style="color:red;" :style="bar"></div>`))
- .toMatchInlineSnapshot(`
- "\`<div style="\${
- _ssrRenderStyle([{"color":"red"}, _ctx.bar])
- }"></div>\`"
- `)
- })
- test('v-bind:arg (boolean)', () => {
- expect(getCompiledString(`<input type="checkbox" :checked="checked">`))
- .toMatchInlineSnapshot(`
- "\`<input type="checkbox"\${
- (_ssrIncludeBooleanAttr(_ctx.checked)) ? " checked" : ""
- }>\`"
- `)
- })
- test('v-bind:arg (non-boolean)', () => {
- expect(getCompiledString(`<div :id="id" class="bar"></div>`))
- .toMatchInlineSnapshot(`
- "\`<div\${
- _ssrRenderAttr("id", _ctx.id)
- } class="bar"></div>\`"
- `)
- })
- test('v-bind:[arg]', () => {
- expect(getCompiledString(`<div v-bind:[key]="value"></div>`))
- .toMatchInlineSnapshot(`
- "\`<div\${
- _ssrRenderAttrs({ [_ctx.key || ""]: _ctx.value })
- }></div>\`"
- `)
- expect(getCompiledString(`<div class="foo" v-bind:[key]="value"></div>`))
- .toMatchInlineSnapshot(`
- "\`<div\${
- _ssrRenderAttrs({
- class: "foo",
- [_ctx.key || ""]: _ctx.value
- })
- }></div>\`"
- `)
- expect(getCompiledString(`<div :id="id" v-bind:[key]="value"></div>`))
- .toMatchInlineSnapshot(`
- "\`<div\${
- _ssrRenderAttrs({
- id: _ctx.id,
- [_ctx.key || ""]: _ctx.value
- })
- }></div>\`"
- `)
- })
- test('v-bind="obj"', () => {
- expect(getCompiledString(`<div v-bind="obj"></div>`))
- .toMatchInlineSnapshot(`
- "\`<div\${
- _ssrRenderAttrs(_ctx.obj)
- }></div>\`"
- `)
- expect(getCompiledString(`<div class="foo" v-bind="obj"></div>`))
- .toMatchInlineSnapshot(`
- "\`<div\${
- _ssrRenderAttrs(_mergeProps({ class: "foo" }, _ctx.obj))
- }></div>\`"
- `)
- expect(getCompiledString(`<div :id="id" v-bind="obj"></div>`))
- .toMatchInlineSnapshot(`
- "\`<div\${
- _ssrRenderAttrs(_mergeProps({ id: _ctx.id }, _ctx.obj))
- }></div>\`"
- `)
- // dynamic key + v-bind="object"
- expect(getCompiledString(`<div :[key]="id" v-bind="obj"></div>`))
- .toMatchInlineSnapshot(`
- "\`<div\${
- _ssrRenderAttrs(_mergeProps({ [_ctx.key || ""]: _ctx.id }, _ctx.obj))
- }></div>\`"
- `)
- // should merge class and :class
- expect(getCompiledString(`<div class="a" :class="b" v-bind="obj"></div>`))
- .toMatchInlineSnapshot(`
- "\`<div\${
- _ssrRenderAttrs(_mergeProps({
- class: ["a", _ctx.b]
- }, _ctx.obj))
- }></div>\`"
- `)
- // should merge style and :style
- expect(
- getCompiledString(
- `<div style="color:red;" :style="b" v-bind="obj"></div>`,
- ),
- ).toMatchInlineSnapshot(`
- "\`<div\${
- _ssrRenderAttrs(_mergeProps({
- style: [{"color":"red"}, _ctx.b]
- }, _ctx.obj))
- }></div>\`"
- `)
- })
- test('should ignore v-on', () => {
- expect(
- getCompiledString(`<div id="foo" @click="bar"/>`),
- ).toMatchInlineSnapshot(`"\`<div id="foo"></div>\`"`)
- expect(
- getCompiledString(`<div id="foo" v-on="bar"/>`),
- ).toMatchInlineSnapshot(`"\`<div id="foo"></div>\`"`)
- expect(getCompiledString(`<div v-bind="foo" v-on="bar"/>`))
- .toMatchInlineSnapshot(`
- "\`<div\${
- _ssrRenderAttrs(_ctx.foo)
- }></div>\`"
- `)
- })
- })
- describe('custom directives', () => {
- // #8112 should respect textContent / innerHTML from directive getSSRProps
- // if the element has no children
- test('custom dir without children', () => {
- expect(getCompiledString(`<div v-xxx:x.y="z" />`)).toMatchInlineSnapshot(`
- "\`<div\${
- _ssrRenderAttrs(_temp0 = _ssrGetDirectiveProps(_ctx, _directive_xxx, _ctx.z, "x", { y: true }))
- }>\${
- ("textContent" in _temp0) ? _ssrInterpolate(_temp0.textContent) : _temp0.innerHTML ?? ''
- }</div>\`"
- `)
- })
- test('custom dir with children', () => {
- expect(getCompiledString(`<div v-xxx:x.y="z">hello</div>`))
- .toMatchInlineSnapshot(`
- "\`<div\${
- _ssrRenderAttrs(_ssrGetDirectiveProps(_ctx, _directive_xxx, _ctx.z, "x", { y: true }))
- }>hello</div>\`"
- `)
- })
- test('custom dir with normal attrs', () => {
- expect(getCompiledString(`<div class="foo" v-xxx />`))
- .toMatchInlineSnapshot(`
- "\`<div\${
- _ssrRenderAttrs(_temp0 = _mergeProps({ class: "foo" }, _ssrGetDirectiveProps(_ctx, _directive_xxx)))
- }>\${
- ("textContent" in _temp0) ? _ssrInterpolate(_temp0.textContent) : _temp0.innerHTML ?? ''
- }</div>\`"
- `)
- })
- test('custom dir with v-bind', () => {
- expect(getCompiledString(`<div :title="foo" :class="bar" v-xxx />`))
- .toMatchInlineSnapshot(`
- "\`<div\${
- _ssrRenderAttrs(_temp0 = _mergeProps({
- title: _ctx.foo,
- class: _ctx.bar
- }, _ssrGetDirectiveProps(_ctx, _directive_xxx)))
- }>\${
- ("textContent" in _temp0) ? _ssrInterpolate(_temp0.textContent) : _temp0.innerHTML ?? ''
- }</div>\`"
- `)
- })
- test('custom dir with v-text', () => {
- expect(getCompiledString(`<div v-xxx v-text="foo" />`))
- .toMatchInlineSnapshot(`
- "\`<div\${
- _ssrRenderAttrs(_ssrGetDirectiveProps(_ctx, _directive_xxx))
- }>\${
- _ssrInterpolate(_ctx.foo)
- }</div>\`"
- `)
- })
- test('custom dir with v-text and normal attrs', () => {
- expect(getCompiledString(`<div class="test" v-xxx v-text="foo" />`))
- .toMatchInlineSnapshot(`
- "\`<div\${
- _ssrRenderAttrs(_mergeProps({ class: "test" }, _ssrGetDirectiveProps(_ctx, _directive_xxx)))
- }>\${
- _ssrInterpolate(_ctx.foo)
- }</div>\`"
- `)
- })
- test('mulptiple custom dirs with v-text', () => {
- expect(getCompiledString(`<div v-xxx v-yyy v-text="foo" />`))
- .toMatchInlineSnapshot(`
- "\`<div\${
- _ssrRenderAttrs(_mergeProps(_ssrGetDirectiveProps(_ctx, _directive_xxx), _ssrGetDirectiveProps(_ctx, _directive_yyy)))
- }>\${
- _ssrInterpolate(_ctx.foo)
- }</div>\`"
- `)
- })
- test('custom dir with object v-bind', () => {
- expect(getCompiledString(`<div v-bind="x" v-xxx />`))
- .toMatchInlineSnapshot(`
- "\`<div\${
- _ssrRenderAttrs(_temp0 = _mergeProps(_ctx.x, _ssrGetDirectiveProps(_ctx, _directive_xxx)))
- }>\${
- ("textContent" in _temp0) ? _ssrInterpolate(_temp0.textContent) : _temp0.innerHTML ?? ''
- }</div>\`"
- `)
- })
- test('custom dir with object v-bind + normal bindings', () => {
- expect(
- getCompiledString(`<div v-bind="x" class="foo" v-xxx title="bar" />`),
- ).toMatchInlineSnapshot(`
- "\`<div\${
- _ssrRenderAttrs(_temp0 = _mergeProps(_ctx.x, {
- class: "foo",
- title: "bar"
- }, _ssrGetDirectiveProps(_ctx, _directive_xxx)))
- }>\${
- ("textContent" in _temp0) ? _ssrInterpolate(_temp0.textContent) : _temp0.innerHTML ?? ''
- }</div>\`"
- `)
- })
- })
- })
|