Skip to content

Commit b2714ce

Browse files
committed
test(runtime-vapor): add slots test case for complex level slot
related issue: vuejs/vue-vapor#242
1 parent ef6986f commit b2714ce

File tree

1 file changed

+203
-1
lines changed

1 file changed

+203
-1
lines changed

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

+203-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import {
44
createComponent,
5+
createFor,
56
createForSlots,
67
createIf,
78
createSlot,
@@ -13,7 +14,14 @@ import {
1314
setText,
1415
template,
1516
} from '../src'
16-
import { currentInstance, nextTick, ref } from '@vue/runtime-dom'
17+
import {
18+
type ComponentInternalInstance,
19+
currentInstance,
20+
getCurrentInstance,
21+
nextTick,
22+
ref,
23+
useSlots,
24+
} from '@vue/runtime-dom'
1725
import { makeRender } from './_utils'
1826

1927
const define = makeRender<any>()
@@ -334,6 +342,200 @@ describe('component: slots', () => {
334342
expect(host.innerHTML).toBe('<div>fallback<!--slot--></div>')
335343
})
336344

345+
// test case could be previewed at
346+
// https://deploy-preview-241--vapor-repl.netlify.app/#__VAPOR__eNp9VMtu2zAQ/JWFcrAMOBKC9JRKQR/IoT00RVP0YuWgSCuFNkUK4kq1Yfjfu6QefsQNYAPi7nC4HM7uzvtc10HXonfnRSZrRE1gkNoaZKrKOPHIJN59okRV64bgq65qKBpdwSwI7cJunX2c8jtosID9ALG5RCUq08oQEG4IYgvwZzkWaStpNh+TadMMueXNYkov4PaZIYkqWpWR0ApIl6VEfw67RAGIAnzeGXSpbDGQqEp6hTiO4XYAgCXu00y/vHm2wT2gNHgZcHq2QyeKf1HYi8NS8IKwqmVKyCuASKi6JeiuK52jtJLxRRMPwj5rVXJf/D3ug6vhlCEBYCglkcEQHuDhyTkAb1iW9qjniSTfqrRilt2uF3vPhb8hOifprgvdcNWCIyCU1YOLv1ra9YFaal3fWWIHu0hsl9Nlo5eWiN/rUyZFtraiuIdjL/UfUdgDGHxC4i08oXLcBK9UySNP0rZGZmGJW8cy1sUeGJ2XNcgcf1JesqePTRh2NshWPNtjYaOZhzY4Ap3y+fyfB5VuFfmzq7SuZ/PJE1EuOhA518dxLi4KOXDPVyHD7i5EGayMVnwbZ7nEy1glIbF5rK2nucFY2eGFvVRK/fe7i1HT4mKMZ6+YrS/EV2ZjY4n3s0GDTcfiTDlKmxLZijb98PTD2XJKjlK+k/yFRsvW1tjDvrQq57KPcK7ab05Nocrf5mFDqMx4KVuoayGHTzzW1xrkf1c/lHsbfBhbj1Uc58z5iDqMpR20Bp+kJnPh2Xk6jVPGOEg8of1p/qxxaxM8WOJ7eHxZYUaBjfluC8PeGQDcFQ46H/rC2WFsK86ALgbAZNzI0sIdt6t1NScP88J557wr9v8AXg7dEA==
347+
test('should not delete new rendered slot when the old slot is removed in loop slot', async () => {
348+
const loop = ref([1, 'default', 3])
349+
350+
let childInstance
351+
const t0 = template('<div></div>')
352+
const { component: Child } = define({
353+
setup() {
354+
childInstance = getCurrentInstance()
355+
const slots = useSlots()
356+
const keys = () => Object.keys(slots)
357+
return {
358+
keys,
359+
slots,
360+
}
361+
},
362+
render: (_ctx: any) => {
363+
const n0 = createFor(
364+
() => _ctx.keys(),
365+
(_ctx0: any) => {
366+
const n5 = t0()
367+
const n4 = createSlot(() => _ctx0[0])
368+
insert(n4, n5 as ParentNode)
369+
return n5
370+
},
371+
)
372+
return n0
373+
},
374+
})
375+
376+
const t1 = template(' static default ')
377+
const { render } = define({
378+
setup() {
379+
return createComponent(
380+
Child,
381+
{},
382+
{
383+
default: () => {
384+
return t1()
385+
},
386+
$: [
387+
() =>
388+
// @ts-expect-error TODO createForSlots
389+
createForSlots(loop.value, (item, i) => ({
390+
name: item,
391+
fn: () => template(item)(),
392+
})),
393+
],
394+
},
395+
)
396+
},
397+
})
398+
const { html } = render()
399+
400+
expect(childInstance!.slots).toHaveProperty('1')
401+
expect(childInstance!.slots).toHaveProperty('default')
402+
expect(childInstance!.slots).toHaveProperty('3')
403+
expect(html()).toBe(
404+
'<div>1<!--slot--></div><div>3<!--slot--></div><div>default<!--slot--></div><!--for-->',
405+
)
406+
loop.value = [1]
407+
await nextTick()
408+
expect(childInstance!.slots).toHaveProperty('1')
409+
expect(childInstance!.slots).toHaveProperty('default')
410+
expect(childInstance!.slots).not.toHaveProperty('3')
411+
expect(html()).toBe(
412+
'<div>1<!--slot--></div><div> static default <!--slot--></div><!--for-->',
413+
)
414+
})
415+
416+
test('should cleanup all slots when loop slot has same key', async () => {
417+
const loop = ref([1, 1, 1])
418+
419+
let childInstance
420+
const t0 = template('<div></div>')
421+
const { component: Child } = define({
422+
setup() {
423+
childInstance = getCurrentInstance()
424+
const slots = useSlots()
425+
const keys = () => Object.keys(slots)
426+
return {
427+
keys,
428+
slots,
429+
}
430+
},
431+
render: (_ctx: any) => {
432+
const n0 = createFor(
433+
() => _ctx.keys(),
434+
(_ctx0: any) => {
435+
const n5 = t0()
436+
const n4 = createSlot(() => _ctx0[0])
437+
insert(n4, n5 as ParentNode)
438+
return n5
439+
},
440+
)
441+
return n0
442+
},
443+
})
444+
445+
const t1 = template(' static default ')
446+
const { render } = define({
447+
setup() {
448+
return createComponent(
449+
Child,
450+
{},
451+
{
452+
default: () => {
453+
return t1()
454+
},
455+
$: [
456+
() =>
457+
// @ts-expect-error TODO createForSlots
458+
createForSlots(loop.value, (item, i) => ({
459+
name: item,
460+
fn: () => template(item)(),
461+
})),
462+
],
463+
},
464+
)
465+
},
466+
})
467+
const { html } = render()
468+
expect(childInstance!.slots).toHaveProperty('1')
469+
expect(childInstance!.slots).toHaveProperty('default')
470+
expect(html()).toBe(
471+
'<div>1<!--slot--></div><div> static default <!--slot--></div><!--for-->',
472+
)
473+
loop.value = [1]
474+
await nextTick()
475+
expect(childInstance!.slots).toHaveProperty('1')
476+
expect(childInstance!.slots).toHaveProperty('default')
477+
expect(html()).toBe(
478+
'<div>1<!--slot--></div><div> static default <!--slot--></div><!--for-->',
479+
)
480+
loop.value = [1, 2, 3]
481+
await nextTick()
482+
expect(childInstance!.slots).toHaveProperty('1')
483+
expect(childInstance!.slots).toHaveProperty('2')
484+
expect(childInstance!.slots).toHaveProperty('3')
485+
expect(childInstance!.slots).toHaveProperty('default')
486+
expect(html()).toBe(
487+
'<div>1<!--slot--></div><div>2<!--slot--></div><div>3<!--slot--></div><div> static default <!--slot--></div><!--for-->',
488+
)
489+
})
490+
491+
test('dynamicSlots should not cover high level slots', async () => {
492+
const dynamicFlag = ref(true)
493+
494+
let instance: ComponentInternalInstance
495+
const { component: Child } = define({
496+
render() {
497+
instance = getCurrentInstance()!
498+
return [createSlot('default'), createSlot('others')]
499+
},
500+
})
501+
502+
const { render, html } = define({
503+
render() {
504+
return createComponent(
505+
Child,
506+
{},
507+
{
508+
default: () => template('default')(),
509+
$: [
510+
() =>
511+
dynamicFlag.value
512+
? {
513+
name: 'default',
514+
fn: () => template('dynamic default')(),
515+
}
516+
: { name: 'others', fn: () => template('others')() },
517+
],
518+
},
519+
)
520+
},
521+
})
522+
523+
render()
524+
525+
expect(html()).toBe('default<!--slot--><!--slot-->')
526+
527+
dynamicFlag.value = false
528+
await nextTick()
529+
530+
expect(html()).toBe('default<!--slot-->others<!--slot-->')
531+
expect(instance!.slots).haveOwnProperty('others')
532+
533+
dynamicFlag.value = true
534+
await nextTick()
535+
expect(html()).toBe('default<!--slot--><!--slot-->')
536+
expect(instance!.slots).not.haveOwnProperty('others')
537+
})
538+
337539
test('dynamic slot should be updated correctly', async () => {
338540
const flag1 = ref(true)
339541

0 commit comments

Comments
 (0)