Skip to content

Commit b5762b5

Browse files
committed
wip: add tests + skip fragment end anchor
1 parent 04eadd8 commit b5762b5

File tree

2 files changed

+194
-2
lines changed

2 files changed

+194
-2
lines changed

packages/runtime-vapor/__tests__/hydration.spec.ts

+189
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,48 @@ describe('Vapor Mode hydration', () => {
264264
)
265265
})
266266

267+
test('nested components with anchor insertion', async () => {
268+
const { container, data } = await testHydration(
269+
`
270+
<template><components.Parent/></template>
271+
`,
272+
{
273+
Parent: `<template><div><span/><components.Child/><span/></div></template>`,
274+
Child: `<template><div>{{ data }}</div></template>`,
275+
},
276+
)
277+
expect(container.innerHTML).toMatchInlineSnapshot(
278+
`"<div><span></span><div>foo</div><span></span></div>"`,
279+
)
280+
281+
data.value = 'bar'
282+
await nextTick()
283+
expect(container.innerHTML).toMatchInlineSnapshot(
284+
`"<div><span></span><div>bar</div><span></span></div>"`,
285+
)
286+
})
287+
288+
test('nested components with multi level anchor insertion', async () => {
289+
const { container, data } = await testHydration(
290+
`
291+
<template><div><span></span><components.Parent/><span></span></div></template>
292+
`,
293+
{
294+
Parent: `<template><div><span/><components.Child/><span/></div></template>`,
295+
Child: `<template><div>{{ data }}</div></template>`,
296+
},
297+
)
298+
expect(container.innerHTML).toMatchInlineSnapshot(
299+
`"<div><span></span><div><span></span><div>foo</div><span></span></div><span></span></div>"`,
300+
)
301+
302+
data.value = 'bar'
303+
await nextTick()
304+
expect(container.innerHTML).toMatchInlineSnapshot(
305+
`"<div><span></span><div><span></span><div>bar</div><span></span></div><span></span></div>"`,
306+
)
307+
})
308+
267309
test('consecutive components with anchor insertion', async () => {
268310
const { container, data } = await testHydration(
269311
`<template>
@@ -290,6 +332,48 @@ describe('Vapor Mode hydration', () => {
290332
)
291333
})
292334

335+
test('nested consecutive components with anchor insertion', async () => {
336+
const { container, data } = await testHydration(
337+
`
338+
<template><components.Parent/></template>
339+
`,
340+
{
341+
Parent: `<template><div><span/><components.Child/><components.Child/><span/></div></template>`,
342+
Child: `<template><div>{{ data }}</div></template>`,
343+
},
344+
)
345+
expect(container.innerHTML).toMatchInlineSnapshot(
346+
`"<div><span></span><div>foo</div><!--[[--><div>foo</div><!--]]--><span></span></div>"`,
347+
)
348+
349+
data.value = 'bar'
350+
await nextTick()
351+
expect(container.innerHTML).toMatchInlineSnapshot(
352+
`"<div><span></span><div>bar</div><!--[[--><div>bar</div><!--]]--><span></span></div>"`,
353+
)
354+
})
355+
356+
test('nested consecutive components with multi level anchor insertion', async () => {
357+
const { container, data } = await testHydration(
358+
`
359+
<template><div><span></span><components.Parent/><span></span></div></template>
360+
`,
361+
{
362+
Parent: `<template><div><span/><components.Child/><components.Child/><span/></div></template>`,
363+
Child: `<template><div>{{ data }}</div></template>`,
364+
},
365+
)
366+
expect(container.innerHTML).toMatchInlineSnapshot(
367+
`"<div><span></span><div><span></span><div>foo</div><!--[[--><div>foo</div><!--]]--><span></span></div><span></span></div>"`,
368+
)
369+
370+
data.value = 'bar'
371+
await nextTick()
372+
expect(container.innerHTML).toMatchInlineSnapshot(
373+
`"<div><span></span><div><span></span><div>bar</div><!--[[--><div>bar</div><!--]]--><span></span></div><span></span></div>"`,
374+
)
375+
})
376+
293377
test('mixed component and element with anchor insertion', async () => {
294378
const { container, data } = await testHydration(
295379
`<template>
@@ -369,6 +453,48 @@ describe('Vapor Mode hydration', () => {
369453
)
370454
})
371455

456+
test('nested fragment component with anchor insertion', async () => {
457+
const { container, data } = await testHydration(
458+
`
459+
<template><components.Parent/></template>
460+
`,
461+
{
462+
Parent: `<template><div><span/><components.Child/><span/></div></template>`,
463+
Child: `<template><div>{{ data }}</div>-{{ data }}-</template>`,
464+
},
465+
)
466+
expect(container.innerHTML).toMatchInlineSnapshot(
467+
`"<div><span></span><!--[--><div>foo</div>-foo-<!--]--><span></span></div>"`,
468+
)
469+
470+
data.value = 'bar'
471+
await nextTick()
472+
expect(container.innerHTML).toMatchInlineSnapshot(
473+
`"<div><span></span><!--[--><div>bar</div>-bar-<!--]--><span></span></div>"`,
474+
)
475+
})
476+
477+
test('nested fragment component with multi level anchor insertion', async () => {
478+
const { container, data } = await testHydration(
479+
`
480+
<template><div><span/><components.Parent/><span/></div></template>
481+
`,
482+
{
483+
Parent: `<template><div><span/><components.Child/><span/></div></template>`,
484+
Child: `<template><div>{{ data }}</div>-{{ data }}-</template>`,
485+
},
486+
)
487+
expect(container.innerHTML).toMatchInlineSnapshot(
488+
`"<div><span></span><div><span></span><!--[--><div>foo</div>-foo-<!--]--><span></span></div><span></span></div>"`,
489+
)
490+
491+
data.value = 'bar'
492+
await nextTick()
493+
expect(container.innerHTML).toMatchInlineSnapshot(
494+
`"<div><span></span><div><span></span><!--[--><div>bar</div>-bar-<!--]--><span></span></div><span></span></div>"`,
495+
)
496+
})
497+
372498
test('consecutive fragment components with anchor insertion', async () => {
373499
const { container, data } = await testHydration(
374500
`<template>
@@ -395,6 +521,69 @@ describe('Vapor Mode hydration', () => {
395521
)
396522
})
397523

524+
test('nested consecutive fragment components with anchor insertion', async () => {
525+
const { container, data } = await testHydration(
526+
`
527+
<template><components.Parent/></template>
528+
`,
529+
{
530+
Parent: `<template><div><span/><components.Child/><components.Child/><span/></div></template>`,
531+
Child: `<template><div>{{ data }}</div>-{{ data }}-</template>`,
532+
},
533+
)
534+
expect(container.innerHTML).toMatchInlineSnapshot(
535+
`"<div><span></span><!--[--><div>foo</div>-foo-<!--]--><!--[[--><!--[--><div>foo</div>-foo-<!--]--><!--]]--><span></span></div>"`,
536+
)
537+
538+
data.value = 'bar'
539+
await nextTick()
540+
expect(container.innerHTML).toMatchInlineSnapshot(
541+
`"<div><span></span><!--[--><div>bar</div>-bar-<!--]--><!--[[--><!--[--><div>bar</div>-bar-<!--]--><!--]]--><span></span></div>"`,
542+
)
543+
})
544+
545+
test('nested consecutive fragment components with multi level anchor insertion', async () => {
546+
const { container, data } = await testHydration(
547+
`
548+
<template><div><span></span><components.Parent/><span></span></div></template>
549+
`,
550+
{
551+
Parent: `<template><div><span/><components.Child/><components.Child/><span/></div></template>`,
552+
Child: `<template><div>{{ data }}</div>-{{ data }}-</template>`,
553+
},
554+
)
555+
expect(container.innerHTML).toMatchInlineSnapshot(
556+
`"<div><span></span><div><span></span><!--[--><div>foo</div>-foo-<!--]--><!--[[--><!--[--><div>foo</div>-foo-<!--]--><!--]]--><span></span></div><span></span></div>"`,
557+
)
558+
559+
data.value = 'bar'
560+
await nextTick()
561+
expect(container.innerHTML).toMatchInlineSnapshot(
562+
`"<div><span></span><div><span></span><!--[--><div>bar</div>-bar-<!--]--><!--[[--><!--[--><div>bar</div>-bar-<!--]--><!--]]--><span></span></div><span></span></div>"`,
563+
)
564+
})
565+
566+
test('nested consecutive fragment components with root level anchor insertion', async () => {
567+
const { container, data } = await testHydration(
568+
`
569+
<template><div><span></span><components.Parent/><span></span></div></template>
570+
`,
571+
{
572+
Parent: `<template><components.Child/><components.Child/></template>`,
573+
Child: `<template><div>{{ data }}</div>-{{ data }}-</template>`,
574+
},
575+
)
576+
expect(container.innerHTML).toMatchInlineSnapshot(
577+
`"<div><span></span><!--[--><!--[--><div>foo</div>-foo-<!--]--><!--[--><div>foo</div>-foo-<!--]--><!--]--><span></span></div>"`,
578+
)
579+
580+
data.value = 'bar'
581+
await nextTick()
582+
expect(container.innerHTML).toMatchInlineSnapshot(
583+
`"<div><span></span><!--[--><!--[--><div>bar</div>-bar-<!--]--><!--[--><div>bar</div>-bar-<!--]--><!--]--><span></span></div>"`,
584+
)
585+
})
586+
398587
test('mixed fragment component and element with anchor insertion', async () => {
399588
const { container, data } = await testHydration(
400589
`<template>

packages/runtime-vapor/src/dom/node.ts

+5-2
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,11 @@ function __next(node: Node): Node {
5353
}
5454

5555
let n = node.nextSibling!
56-
// skip dynamic anchors and empty text nodes
57-
while (n && (isDynamicAnchor(n) || isEmptyText(n))) {
56+
// skip if:
57+
// - dynamic anchors (<!--[[-->, <!--]]-->)
58+
// - fragment end anchor (`<!--]-->`)
59+
// - empty text nodes
60+
while (n && (isDynamicAnchor(n) || isComment(n, ']') || isEmptyText(n))) {
5861
n = n.nextSibling!
5962
}
6063
return n

0 commit comments

Comments
 (0)