mirror of https://github.com/vuejs/core.git
wip: test hydrate v-if in PROD
This commit is contained in:
parent
e9c9e4903d
commit
612cde76ce
|
@ -78,6 +78,15 @@ const triggerEvent = (type: string, el: Element) => {
|
||||||
el.dispatchEvent(event)
|
el.dispatchEvent(event)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function runWithEnv(isProd: boolean, fn: () => Promise<void>) {
|
||||||
|
if (isProd) __DEV__ = false
|
||||||
|
try {
|
||||||
|
await fn()
|
||||||
|
} finally {
|
||||||
|
if (isProd) __DEV__ = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
describe('Vapor Mode hydration', () => {
|
describe('Vapor Mode hydration', () => {
|
||||||
delegateEvents('click')
|
delegateEvents('click')
|
||||||
|
|
||||||
|
@ -639,7 +648,19 @@ describe('Vapor Mode hydration', () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('if', () => {
|
describe('if', () => {
|
||||||
|
describe('DEV mode', () => {
|
||||||
|
runTests()
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('PROD mode', () => {
|
||||||
|
runTests(true)
|
||||||
|
})
|
||||||
|
|
||||||
|
function runTests(isProd: boolean = false) {
|
||||||
|
const anchorLabel = isProd ? '$' : 'if'
|
||||||
|
|
||||||
test('basic toggle - true -> false', async () => {
|
test('basic toggle - true -> false', async () => {
|
||||||
|
runWithEnv(isProd, async () => {
|
||||||
const data = ref(true)
|
const data = ref(true)
|
||||||
const { container } = await testHydration(
|
const { container } = await testHydration(
|
||||||
`<template>
|
`<template>
|
||||||
|
@ -648,16 +669,22 @@ describe('Vapor Mode hydration', () => {
|
||||||
undefined,
|
undefined,
|
||||||
data,
|
data,
|
||||||
)
|
)
|
||||||
expect(container.innerHTML).toMatchInlineSnapshot(
|
expect(container.innerHTML).toBe(
|
||||||
`"<div>foo</div><!--if-->"`,
|
`<div>foo</div><!--${anchorLabel}-->`,
|
||||||
)
|
)
|
||||||
|
|
||||||
data.value = false
|
data.value = false
|
||||||
await nextTick()
|
await nextTick()
|
||||||
expect(container.innerHTML).toMatchInlineSnapshot(`"<!--if-->"`)
|
expect(container.innerHTML).toBe(`<!--${anchorLabel}-->`)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
test('basic toggle - false -> true', async () => {
|
test('basic toggle - false -> true', async () => {
|
||||||
|
runWithEnv(isProd, async () => {
|
||||||
|
// v-if="false" is rendered as <!----> in the server-rendered HTML
|
||||||
|
// it reused as anchor, so the anchor label is empty in PROD
|
||||||
|
let anchorLabel = isProd ? '' : 'if'
|
||||||
|
if (isProd) __DEV__ = false
|
||||||
const data = ref(false)
|
const data = ref(false)
|
||||||
const { container } = await testHydration(
|
const { container } = await testHydration(
|
||||||
`<template>
|
`<template>
|
||||||
|
@ -666,16 +693,18 @@ describe('Vapor Mode hydration', () => {
|
||||||
undefined,
|
undefined,
|
||||||
data,
|
data,
|
||||||
)
|
)
|
||||||
expect(container.innerHTML).toMatchInlineSnapshot(`"<!--if-->"`)
|
expect(container.innerHTML).toBe(`<!--${anchorLabel}-->`)
|
||||||
|
|
||||||
data.value = true
|
data.value = true
|
||||||
await nextTick()
|
await nextTick()
|
||||||
expect(container.innerHTML).toMatchInlineSnapshot(
|
expect(container.innerHTML).toBe(
|
||||||
`"<div>foo</div><!--if-->"`,
|
`<div>foo</div><!--${anchorLabel}-->`,
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
})
|
||||||
|
|
||||||
test('v-if/else-if/else chain - switch branches', async () => {
|
test('v-if/else-if/else chain - switch branches', async () => {
|
||||||
|
runWithEnv(isProd, async () => {
|
||||||
const data = ref('a')
|
const data = ref('a')
|
||||||
const { container } = await testHydration(
|
const { container } = await testHydration(
|
||||||
`<template>
|
`<template>
|
||||||
|
@ -686,24 +715,35 @@ describe('Vapor Mode hydration', () => {
|
||||||
undefined,
|
undefined,
|
||||||
data,
|
data,
|
||||||
)
|
)
|
||||||
expect(container.innerHTML).toMatchInlineSnapshot(
|
expect(container.innerHTML).toBe(
|
||||||
`"<div>foo</div><!--if-->"`,
|
`<div>foo</div><!--${anchorLabel}-->`,
|
||||||
)
|
)
|
||||||
|
|
||||||
data.value = 'b'
|
data.value = 'b'
|
||||||
await nextTick()
|
await nextTick()
|
||||||
expect(container.innerHTML).toMatchInlineSnapshot(
|
// In PROD, the anchor of v-else-if (DynamicFragment) is an empty text node,
|
||||||
`"<div>bar</div><!--if--><!--if-->"`,
|
// so it won't be rendered
|
||||||
|
expect(container.innerHTML).toBe(
|
||||||
|
`<div>bar</div><!--${anchorLabel}-->${isProd ? '' : `<!--${anchorLabel}-->`}`,
|
||||||
)
|
)
|
||||||
|
|
||||||
data.value = 'c'
|
data.value = 'c'
|
||||||
await nextTick()
|
await nextTick()
|
||||||
expect(container.innerHTML).toMatchInlineSnapshot(
|
// same as above
|
||||||
`"<div>baz</div><!--if--><!--if-->"`,
|
expect(container.innerHTML).toBe(
|
||||||
|
`<div>baz</div><!--${anchorLabel}-->${isProd ? '' : `<!--${anchorLabel}-->`}`,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
data.value = 'a'
|
||||||
|
await nextTick()
|
||||||
|
expect(container.innerHTML).toBe(
|
||||||
|
`<div>foo</div><!--${anchorLabel}-->`,
|
||||||
|
)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
test('nested if', async () => {
|
test('nested if', async () => {
|
||||||
|
runWithEnv(isProd, async () => {
|
||||||
const data = reactive({ outer: true, inner: true })
|
const data = reactive({ outer: true, inner: true })
|
||||||
const { container } = await testHydration(
|
const { container } = await testHydration(
|
||||||
`<template>
|
`<template>
|
||||||
|
@ -715,22 +755,30 @@ describe('Vapor Mode hydration', () => {
|
||||||
undefined,
|
undefined,
|
||||||
data,
|
data,
|
||||||
)
|
)
|
||||||
expect(container.innerHTML).toMatchInlineSnapshot(
|
expect(container.innerHTML).toBe(
|
||||||
`"<div><span>outer</span><div>inner</div><!--if--></div><!--if-->"`,
|
`<div>` +
|
||||||
|
`<span>outer</span>` +
|
||||||
|
`<div>inner</div><!--${anchorLabel}-->` +
|
||||||
|
`</div><!--${anchorLabel}-->`,
|
||||||
)
|
)
|
||||||
|
|
||||||
data.inner = false
|
data.inner = false
|
||||||
await nextTick()
|
await nextTick()
|
||||||
expect(container.innerHTML).toMatchInlineSnapshot(
|
expect(container.innerHTML).toBe(
|
||||||
`"<div><span>outer</span><!--if--></div><!--if-->"`,
|
`<div>` +
|
||||||
|
`<span>outer</span>` +
|
||||||
|
`<!--${anchorLabel}-->` +
|
||||||
|
`</div><!--${anchorLabel}-->`,
|
||||||
)
|
)
|
||||||
|
|
||||||
data.outer = false
|
data.outer = false
|
||||||
await nextTick()
|
await nextTick()
|
||||||
expect(container.innerHTML).toMatchInlineSnapshot(`"<!--if-->"`)
|
expect(container.innerHTML).toBe(`<!--${anchorLabel}-->`)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
test('on component', async () => {
|
test('on component', async () => {
|
||||||
|
runWithEnv(isProd, async () => {
|
||||||
const data = ref(true)
|
const data = ref(true)
|
||||||
const { container } = await testHydration(
|
const { container } = await testHydration(
|
||||||
`<template>
|
`<template>
|
||||||
|
@ -739,14 +787,59 @@ describe('Vapor Mode hydration', () => {
|
||||||
{ Child: `<template>foo</template>` },
|
{ Child: `<template>foo</template>` },
|
||||||
data,
|
data,
|
||||||
)
|
)
|
||||||
expect(container.innerHTML).toMatchInlineSnapshot(`"foo<!--if-->"`)
|
expect(container.innerHTML).toBe(`foo<!--${anchorLabel}-->`)
|
||||||
|
|
||||||
data.value = false
|
data.value = false
|
||||||
await nextTick()
|
await nextTick()
|
||||||
expect(container.innerHTML).toMatchInlineSnapshot(`"<!--if-->"`)
|
expect(container.innerHTML).toBe(`<!--${anchorLabel}-->`)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
test('v-if/else-if/else chain on component - switch branches', async () => {
|
||||||
|
runWithEnv(isProd, async () => {
|
||||||
|
const data = ref('a')
|
||||||
|
const { container } = await testHydration(
|
||||||
|
`<template>
|
||||||
|
<components.Child1 v-if="data === 'a'"/>
|
||||||
|
<components.Child2 v-else-if="data === 'b'"/>
|
||||||
|
<components.Child3 v-else/>
|
||||||
|
</template>`,
|
||||||
|
{
|
||||||
|
Child1: `<template><span>{{data}} child1</span></template>`,
|
||||||
|
Child2: `<template><span>{{data}} child2</span></template>`,
|
||||||
|
Child3: `<template><span>{{data}} child3</span></template>`,
|
||||||
|
},
|
||||||
|
data,
|
||||||
|
)
|
||||||
|
expect(container.innerHTML).toBe(
|
||||||
|
`<span>a child1</span><!--${anchorLabel}-->`,
|
||||||
|
)
|
||||||
|
|
||||||
|
data.value = 'b'
|
||||||
|
await nextTick()
|
||||||
|
// In PROD, the anchor of v-else-if (DynamicFragment) is an empty text node,
|
||||||
|
// so it won't be rendered
|
||||||
|
expect(container.innerHTML).toBe(
|
||||||
|
`<span>b child2</span><!--${anchorLabel}-->${isProd ? '' : `<!--${anchorLabel}-->`}`,
|
||||||
|
)
|
||||||
|
|
||||||
|
data.value = 'c'
|
||||||
|
await nextTick()
|
||||||
|
// same as above
|
||||||
|
expect(container.innerHTML).toBe(
|
||||||
|
`<span>c child3</span><!--${anchorLabel}-->${isProd ? '' : `<!--${anchorLabel}-->`}`,
|
||||||
|
)
|
||||||
|
|
||||||
|
data.value = 'a'
|
||||||
|
await nextTick()
|
||||||
|
expect(container.innerHTML).toBe(
|
||||||
|
`<span>a child1</span><!--${anchorLabel}-->`,
|
||||||
|
)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
test('on component with anchor insertion', async () => {
|
test('on component with anchor insertion', async () => {
|
||||||
|
runWithEnv(isProd, async () => {
|
||||||
const data = ref(true)
|
const data = ref(true)
|
||||||
const { container } = await testHydration(
|
const { container } = await testHydration(
|
||||||
`<template>
|
`<template>
|
||||||
|
@ -759,18 +852,28 @@ describe('Vapor Mode hydration', () => {
|
||||||
{ Child: `<template>foo</template>` },
|
{ Child: `<template>foo</template>` },
|
||||||
data,
|
data,
|
||||||
)
|
)
|
||||||
expect(container.innerHTML).toMatchInlineSnapshot(
|
expect(container.innerHTML).toBe(
|
||||||
`"<div><span></span>foo<!--if--><span></span></div>"`,
|
`<div>` +
|
||||||
|
`<span></span>` +
|
||||||
|
`foo<!--${anchorLabel}-->` +
|
||||||
|
`<span></span>` +
|
||||||
|
`</div>`,
|
||||||
)
|
)
|
||||||
|
|
||||||
data.value = false
|
data.value = false
|
||||||
await nextTick()
|
await nextTick()
|
||||||
expect(container.innerHTML).toMatchInlineSnapshot(
|
expect(container.innerHTML).toBe(
|
||||||
`"<div><span></span><!--if--><span></span></div>"`,
|
`<div>` +
|
||||||
|
`<span></span>` +
|
||||||
|
`<!--${anchorLabel}-->` +
|
||||||
|
`<span></span>` +
|
||||||
|
`</div>`,
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
})
|
||||||
|
|
||||||
test('consecutive v-if on component with anchor insertion', async () => {
|
test('consecutive v-if on component with anchor insertion', async () => {
|
||||||
|
runWithEnv(isProd, async () => {
|
||||||
const data = ref(true)
|
const data = ref(true)
|
||||||
const { container } = await testHydration(
|
const { container } = await testHydration(
|
||||||
`<template>
|
`<template>
|
||||||
|
@ -784,18 +887,30 @@ describe('Vapor Mode hydration', () => {
|
||||||
{ Child: `<template>foo</template>` },
|
{ Child: `<template>foo</template>` },
|
||||||
data,
|
data,
|
||||||
)
|
)
|
||||||
expect(container.innerHTML).toMatchInlineSnapshot(
|
expect(container.innerHTML).toBe(
|
||||||
`"<div><span></span>foo<!--if-->foo<!--if--><span></span></div>"`,
|
`<div>` +
|
||||||
|
`<span></span>` +
|
||||||
|
`foo<!--${anchorLabel}-->` +
|
||||||
|
`foo<!--${anchorLabel}-->` +
|
||||||
|
`<span></span>` +
|
||||||
|
`</div>`,
|
||||||
)
|
)
|
||||||
|
|
||||||
data.value = false
|
data.value = false
|
||||||
await nextTick()
|
await nextTick()
|
||||||
expect(container.innerHTML).toMatchInlineSnapshot(
|
expect(container.innerHTML).toBe(
|
||||||
`"<div><span></span><!--if--><!--if--><span></span></div>"`,
|
`<div>` +
|
||||||
|
`<span></span>` +
|
||||||
|
`<!--${anchorLabel}-->` +
|
||||||
|
`<!--${anchorLabel}-->` +
|
||||||
|
`<span></span>` +
|
||||||
|
`</div>`,
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
})
|
||||||
|
|
||||||
test('consecutive v-if on fragment component with anchor insertion', async () => {
|
test('consecutive v-if on fragment component with anchor insertion', async () => {
|
||||||
|
runWithEnv(isProd, async () => {
|
||||||
const data = ref(true)
|
const data = ref(true)
|
||||||
const { container } = await testHydration(
|
const { container } = await testHydration(
|
||||||
`<template>
|
`<template>
|
||||||
|
@ -811,17 +926,29 @@ describe('Vapor Mode hydration', () => {
|
||||||
},
|
},
|
||||||
data,
|
data,
|
||||||
)
|
)
|
||||||
expect(container.innerHTML).toMatchInlineSnapshot(
|
expect(container.innerHTML).toBe(
|
||||||
`"<div><span></span><!--[--><div>true</div>-true-<!--]--><!--if--><!--[--><div>true</div>-true-<!--]--><!--if--><span></span></div>"`,
|
`<div>` +
|
||||||
|
`<span></span>` +
|
||||||
|
`<!--[--><div>true</div>-true-<!--]--><!--${anchorLabel}-->` +
|
||||||
|
`<!--[--><div>true</div>-true-<!--]--><!--${anchorLabel}-->` +
|
||||||
|
`<span></span>` +
|
||||||
|
`</div>`,
|
||||||
)
|
)
|
||||||
|
|
||||||
data.value = false
|
data.value = false
|
||||||
await nextTick()
|
await nextTick()
|
||||||
expect(container.innerHTML).toMatchInlineSnapshot(
|
expect(container.innerHTML).toBe(
|
||||||
`"<div><span></span><!--[--><!--]--><!--if--><!--[--><!--]--><!--if--><span></span></div>"`,
|
`<div>` +
|
||||||
|
`<span></span>` +
|
||||||
|
`<!--[--><!--]--><!--${anchorLabel}-->` +
|
||||||
|
`<!--[--><!--]--><!--${anchorLabel}-->` +
|
||||||
|
`<span></span>` +
|
||||||
|
`</div>`,
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
test.todo('for')
|
test.todo('for')
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ import {
|
||||||
mountComponent,
|
mountComponent,
|
||||||
unmountComponent,
|
unmountComponent,
|
||||||
} from './component'
|
} from './component'
|
||||||
import { createComment, createTextNode, next } from './dom/node'
|
import { createComment, createTextNode, nextSiblingAnchor } from './dom/node'
|
||||||
import { EffectScope, pauseTracking, resetTracking } from '@vue/reactivity'
|
import { EffectScope, pauseTracking, resetTracking } from '@vue/reactivity'
|
||||||
import { currentHydrationNode, isComment, isHydrating } from './dom/hydration'
|
import { currentHydrationNode, isComment, isHydrating } from './dom/hydration'
|
||||||
import { isDynamicFragmentEndAnchor, warn } from '@vue/runtime-dom'
|
import { isDynamicFragmentEndAnchor, warn } from '@vue/runtime-dom'
|
||||||
|
@ -88,8 +88,9 @@ export class DynamicFragment extends VaporFragment {
|
||||||
if (isComment(currentHydrationNode!, '')) {
|
if (isComment(currentHydrationNode!, '')) {
|
||||||
this.anchor = currentHydrationNode
|
this.anchor = currentHydrationNode
|
||||||
} else {
|
} else {
|
||||||
const anchor = next(currentHydrationNode!)
|
// find next sibling `<!--$-->` as anchor
|
||||||
if (isDynamicFragmentEndAnchor(anchor)) {
|
const anchor = nextSiblingAnchor(currentHydrationNode!, '$')!
|
||||||
|
if (anchor && isDynamicFragmentEndAnchor(anchor)) {
|
||||||
this.anchor = anchor
|
this.anchor = anchor
|
||||||
} else if (__DEV__) {
|
} else if (__DEV__) {
|
||||||
// TODO warning
|
// TODO warning
|
||||||
|
|
|
@ -46,16 +46,8 @@ function _next(node: Node): Node {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! #__NO_SIDE_EFFECTS__ */
|
/*! #__NO_SIDE_EFFECTS__ */
|
||||||
function __next(node: Node): Node {
|
export function __next(node: Node): Node {
|
||||||
// treat dynamic node (<!--[[-->...<!--]]-->) as a single node
|
node = handleWrappedNode(node)
|
||||||
if (isComment(node, '[[')) {
|
|
||||||
node = locateEndAnchor(node, '[[', ']]')!
|
|
||||||
}
|
|
||||||
|
|
||||||
// treat dynamic node (<!--[-->...<!--]-->) as a single node
|
|
||||||
else if (isComment(node, '[')) {
|
|
||||||
node = locateEndAnchor(node)!
|
|
||||||
}
|
|
||||||
|
|
||||||
let n = node.nextSibling!
|
let n = node.nextSibling!
|
||||||
while (n && isNonHydrationNode(n)) {
|
while (n && isNonHydrationNode(n)) {
|
||||||
|
@ -109,12 +101,12 @@ export function disableHydrationNodeLookup(): void {
|
||||||
|
|
||||||
/*! #__NO_SIDE_EFFECTS__ */
|
/*! #__NO_SIDE_EFFECTS__ */
|
||||||
export function prev(node: Node): Node | null {
|
export function prev(node: Node): Node | null {
|
||||||
// treat dynamic node (<!--[[-->...<!--]]-->) as a single node
|
// process dynamic node (<!--[[-->...<!--]]-->) as a single one
|
||||||
if (isComment(node, ']]')) {
|
if (isComment(node, ']]')) {
|
||||||
node = locateStartAnchor(node, '[[', ']]')!
|
node = locateStartAnchor(node, '[[', ']]')!
|
||||||
}
|
}
|
||||||
|
|
||||||
// treat dynamic node (<!--[-->...<!--]-->) as a single node
|
// process fragment node (<!--[-->...<!--]-->) as a single one
|
||||||
else if (isComment(node, ']')) {
|
else if (isComment(node, ']')) {
|
||||||
node = locateStartAnchor(node)!
|
node = locateStartAnchor(node)!
|
||||||
}
|
}
|
||||||
|
@ -134,12 +126,8 @@ function isNonHydrationNode(node: Node) {
|
||||||
isDynamicAnchor(node) ||
|
isDynamicAnchor(node) ||
|
||||||
// fragment end anchor (`<!--]-->`)
|
// fragment end anchor (`<!--]-->`)
|
||||||
isComment(node, ']') ||
|
isComment(node, ']') ||
|
||||||
isDynamicFragmentAnchor(node)
|
// dynamic fragment anchors
|
||||||
)
|
(__DEV__
|
||||||
}
|
|
||||||
|
|
||||||
function isDynamicFragmentAnchor(node: Node) {
|
|
||||||
return __DEV__
|
|
||||||
? // v-if anchor (`<!--if-->`)
|
? // v-if anchor (`<!--if-->`)
|
||||||
isComment(node, 'if') ||
|
isComment(node, 'if') ||
|
||||||
// v-for anchor (`<!--for-->`)
|
// v-for anchor (`<!--for-->`)
|
||||||
|
@ -148,6 +136,35 @@ function isDynamicFragmentAnchor(node: Node) {
|
||||||
isComment(node, 'slot') ||
|
isComment(node, 'slot') ||
|
||||||
// dynamic-component anchor (`<!--dynamic-component-->`)
|
// dynamic-component anchor (`<!--dynamic-component-->`)
|
||||||
isComment(node, 'dynamic-component')
|
isComment(node, 'dynamic-component')
|
||||||
: // TODO ?
|
: isComment(node, '$'))
|
||||||
isComment(node, '$')
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function nextSiblingAnchor(
|
||||||
|
node: Node,
|
||||||
|
anchorLabel: string,
|
||||||
|
): Comment | null {
|
||||||
|
node = handleWrappedNode(node)
|
||||||
|
|
||||||
|
let n = node.nextSibling
|
||||||
|
while (n) {
|
||||||
|
if (isComment(n, anchorLabel)) return n
|
||||||
|
n = n.nextSibling
|
||||||
|
}
|
||||||
|
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleWrappedNode(node: Node): Node {
|
||||||
|
// process dynamic node (<!--[[-->...<!--]]-->) as a single one
|
||||||
|
if (isComment(node, '[[')) {
|
||||||
|
return locateEndAnchor(node, '[[', ']]')!
|
||||||
|
}
|
||||||
|
|
||||||
|
// process fragment (<!--[-->...<!--]-->) as a single one
|
||||||
|
else if (isComment(node, '[')) {
|
||||||
|
return locateEndAnchor(node)!
|
||||||
|
}
|
||||||
|
|
||||||
|
return node
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ describe('ssr: attr fallthrough', () => {
|
||||||
template: `<child :ok="ok" class="bar"/>`,
|
template: `<child :ok="ok" class="bar"/>`,
|
||||||
}
|
}
|
||||||
expect(await renderToString(createApp(Parent, { ok: true }))).toBe(
|
expect(await renderToString(createApp(Parent, { ok: true }))).toBe(
|
||||||
`<div class="foo bar"></div>`,
|
`<div class="foo bar"></div><!--$-->`,
|
||||||
)
|
)
|
||||||
expect(await renderToString(createApp(Parent, { ok: false }))).toBe(
|
expect(await renderToString(createApp(Parent, { ok: false }))).toBe(
|
||||||
`<span class="bar"></span>`,
|
`<span class="bar"></span>`,
|
||||||
|
|
|
@ -94,7 +94,7 @@ describe('ssr: slot', () => {
|
||||||
template: `<one><template v-if="true">hello</template></one>`,
|
template: `<one><template v-if="true">hello</template></one>`,
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
).toBe(`<div><!--[--><!--[-->hello<!--]--><!--]--></div>`)
|
).toBe(`<div><!--[--><!--[-->hello<!--]--><!--$--><!--]--></div>`)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('fragment slot (template v-if + multiple elements)', async () => {
|
test('fragment slot (template v-if + multiple elements)', async () => {
|
||||||
|
@ -106,7 +106,7 @@ describe('ssr: slot', () => {
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
).toBe(
|
).toBe(
|
||||||
`<div><!--[--><!--[--><div>one</div><div>two</div><!--]--><!--]--></div>`,
|
`<div><!--[--><!--[--><div>one</div><div>two</div><!--]--><!--$--><!--]--></div>`,
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -135,7 +135,7 @@ describe('ssr: slot', () => {
|
||||||
template: `<one><div v-if="true">foo</div></one>`,
|
template: `<one><div v-if="true">foo</div></one>`,
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
).toBe(`<div>foo</div>`)
|
).toBe(`<div>foo</div><!--$-->`)
|
||||||
})
|
})
|
||||||
|
|
||||||
// #9933
|
// #9933
|
||||||
|
|
Loading…
Reference in New Issue