Skip to content

Commit 0d88889

Browse files
authored
test(useSlots): add short-circuit and edge case tests
1 parent a1d1272 commit 0d88889

File tree

1 file changed

+168
-0
lines changed

1 file changed

+168
-0
lines changed

packages/react/src/hooks/__tests__/useSlots.test.tsx

Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -534,3 +534,171 @@ test('handles empty slot symbols gracefully', () => {
534534
]
535535
`)
536536
})
537+
538+
test('children after all slots are filled go to rest', () => {
539+
const calls: Array<ReturnType<typeof useSlots>> = []
540+
const children = [
541+
<TestComponentA key="a">Slot A</TestComponentA>,
542+
<div key="extra1">Extra 1</div>,
543+
<div key="extra2">Extra 2</div>,
544+
<span key="extra3">Extra 3</span>,
545+
]
546+
const slotsConfig = {
547+
a: TestComponentA,
548+
}
549+
550+
function TestComponent(_props: {children: React.ReactNode}) {
551+
calls.push(useSlots(children, slotsConfig))
552+
return null
553+
}
554+
555+
render(<TestComponent>{children}</TestComponent>)
556+
557+
expect(calls).toMatchInlineSnapshot(`
558+
[
559+
[
560+
{
561+
"a": <TestComponentA>
562+
Slot A
563+
</TestComponentA>,
564+
},
565+
[
566+
<div>
567+
Extra 1
568+
</div>,
569+
<div>
570+
Extra 2
571+
</div>,
572+
<span>
573+
Extra 3
574+
</span>,
575+
],
576+
],
577+
]
578+
`)
579+
})
580+
581+
test('non-element children are placed in rest', () => {
582+
const calls: Array<ReturnType<typeof useSlots>> = []
583+
const children = [
584+
'plain text',
585+
null,
586+
false,
587+
<TestComponentA key="a">Slot</TestComponentA>,
588+
0,
589+
<div key="div">Content</div>,
590+
]
591+
const slotsConfig = {
592+
a: TestComponentA,
593+
}
594+
595+
function TestComponent(_props: {children: React.ReactNode}) {
596+
calls.push(useSlots(children, slotsConfig))
597+
return null
598+
}
599+
600+
render(<TestComponent>{children}</TestComponent>)
601+
602+
const [slots, rest] = calls[0]
603+
expect(slots.a).toBeDefined()
604+
// Non-element children (strings, numbers, null, false) go to rest
605+
// React.Children.forEach converts false to null
606+
expect(rest).toMatchInlineSnapshot(`
607+
[
608+
"plain text",
609+
null,
610+
null,
611+
0,
612+
<div>
613+
Content
614+
</div>,
615+
]
616+
`)
617+
})
618+
619+
test('slots match regardless of child order', () => {
620+
const calls: Array<ReturnType<typeof useSlots>> = []
621+
const children = [
622+
<div key="text">Text content</div>,
623+
<TestComponentB key="b">B</TestComponentB>,
624+
<TestComponentA key="a">A</TestComponentA>,
625+
]
626+
const slotsConfig = {
627+
a: TestComponentA,
628+
b: TestComponentB,
629+
}
630+
631+
function TestComponent(_props: {children: React.ReactNode}) {
632+
calls.push(useSlots(children, slotsConfig))
633+
return null
634+
}
635+
636+
render(<TestComponent>{children}</TestComponent>)
637+
638+
expect(calls).toMatchInlineSnapshot(`
639+
[
640+
[
641+
{
642+
"a": <TestComponentA>
643+
A
644+
</TestComponentA>,
645+
"b": <TestComponentB>
646+
B
647+
</TestComponentB>,
648+
},
649+
[
650+
<div>
651+
Text content
652+
</div>,
653+
],
654+
],
655+
]
656+
`)
657+
})
658+
659+
test('single slot config short-circuits after first match', () => {
660+
const calls: Array<ReturnType<typeof useSlots>> = []
661+
const children = [
662+
<TestComponentA key="a">Match</TestComponentA>,
663+
<div key="1">One</div>,
664+
<div key="2">Two</div>,
665+
<div key="3">Three</div>,
666+
<div key="4">Four</div>,
667+
]
668+
const slotsConfig = {
669+
a: TestComponentA,
670+
}
671+
672+
function TestComponent(_props: {children: React.ReactNode}) {
673+
calls.push(useSlots(children, slotsConfig))
674+
return null
675+
}
676+
677+
render(<TestComponent>{children}</TestComponent>)
678+
679+
expect(calls).toMatchInlineSnapshot(`
680+
[
681+
[
682+
{
683+
"a": <TestComponentA>
684+
Match
685+
</TestComponentA>,
686+
},
687+
[
688+
<div>
689+
One
690+
</div>,
691+
<div>
692+
Two
693+
</div>,
694+
<div>
695+
Three
696+
</div>,
697+
<div>
698+
Four
699+
</div>,
700+
],
701+
],
702+
]
703+
`)
704+
})

0 commit comments

Comments
 (0)