Skip to content

Commit 0d3296a

Browse files
5ZYSZ3Kjsamr
authored andcommitted
fix: add tests for key generation
1 parent a555d6c commit 0d3296a

1 file changed

Lines changed: 138 additions & 0 deletions

File tree

packages/render/src/__tests__/component.render-html.test.tsx

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -893,4 +893,142 @@ describe('RenderHTML', () => {
893893
expect(queryByText('\n', { normalizer: (s) => s })).toBeNull();
894894
});
895895
});
896+
describe('regarding key generation in renderChildren', () => {
897+
it('should generate unique keys for sibling elements with the same tag name', () => {
898+
const capturedKeys: string[] = [];
899+
const renderChild = jest.fn(({ key }) => {
900+
capturedKeys.push(key);
901+
return null;
902+
});
903+
const DivRenderer: CustomTextualRenderer = jest.fn(function DivRenderer({
904+
TDefaultRenderer,
905+
...props
906+
}) {
907+
return (
908+
<TDefaultRenderer {...props}>
909+
<TNodeChildrenRenderer
910+
renderChild={renderChild}
911+
tnode={props.tnode}
912+
/>
913+
</TDefaultRenderer>
914+
);
915+
});
916+
render(
917+
<RenderHTML
918+
source={{
919+
html: '<div><p>One</p><p>Two</p></div>'
920+
}}
921+
debug={false}
922+
renderers={{ div: DivRenderer }}
923+
contentWidth={100}
924+
/>
925+
);
926+
expect(capturedKeys.length).toBeGreaterThanOrEqual(2);
927+
expect(new Set(capturedKeys).size).toBe(capturedKeys.length);
928+
});
929+
it('should generate unique keys for elements with the same tag and same nodeIndex in different subtrees', () => {
930+
const capturedKeys: string[] = [];
931+
const renderChild = jest.fn(({ key }) => {
932+
capturedKeys.push(key);
933+
return null;
934+
});
935+
const DivRenderer: CustomTextualRenderer = jest.fn(function DivRenderer({
936+
TDefaultRenderer,
937+
...props
938+
}) {
939+
return (
940+
<TDefaultRenderer {...props}>
941+
<TNodeChildrenRenderer
942+
renderChild={renderChild}
943+
tnode={props.tnode}
944+
/>
945+
</TDefaultRenderer>
946+
);
947+
});
948+
render(
949+
<RenderHTML
950+
source={{
951+
html: '<div><div><p>Nested One</p></div><div><p>Nested Two</p></div></div>'
952+
}}
953+
debug={false}
954+
renderers={{ div: DivRenderer }}
955+
contentWidth={100}
956+
/>
957+
);
958+
expect(new Set(capturedKeys).size).toBe(capturedKeys.length);
959+
});
960+
it('should generate a key matching the exact expected string including parent path', () => {
961+
const capturedKeys: string[] = [];
962+
const renderChild = jest.fn(({ key }) => {
963+
capturedKeys.push(key);
964+
return null;
965+
});
966+
const DivRenderer: CustomTextualRenderer = jest.fn(function DivRenderer({
967+
TDefaultRenderer,
968+
...props
969+
}) {
970+
return (
971+
<TDefaultRenderer {...props}>
972+
<TNodeChildrenRenderer
973+
renderChild={renderChild}
974+
tnode={props.tnode}
975+
/>
976+
</TDefaultRenderer>
977+
);
978+
});
979+
render(
980+
<RenderHTML
981+
source={{
982+
html: '<div><p>One</p><p>Two</p></div>'
983+
}}
984+
debug={false}
985+
renderers={{ div: DivRenderer }}
986+
contentWidth={100}
987+
/>
988+
);
989+
// The key encodes the full ancestor path: <p> at index 0 inside <div> at index 0
990+
// inside synthetic <body> at index 0 inside TDocument (tagName "html") at index 0
991+
expect(capturedKeys[0]).toBe(
992+
'tnode_childTnode--p-0-div-0-body-0-html-0'
993+
);
994+
// Second <p> differs only in its own nodeIndex (1 instead of 0)
995+
expect(capturedKeys[1]).toBe(
996+
'tnode_childTnode--p-1-div-0-body-0-html-0'
997+
);
998+
});
999+
it('should generate keys with the tnode_childTnode- prefix', () => {
1000+
const capturedKeys: string[] = [];
1001+
const renderChild = jest.fn(({ key }) => {
1002+
capturedKeys.push(key);
1003+
return null;
1004+
});
1005+
const DivRenderer: CustomTextualRenderer = jest.fn(function DivRenderer({
1006+
TDefaultRenderer,
1007+
...props
1008+
}) {
1009+
return (
1010+
<TDefaultRenderer {...props}>
1011+
<TNodeChildrenRenderer
1012+
renderChild={renderChild}
1013+
tnode={props.tnode}
1014+
/>
1015+
</TDefaultRenderer>
1016+
);
1017+
});
1018+
render(
1019+
<RenderHTML
1020+
source={{
1021+
html: '<div><p>One</p><p>Two</p></div>'
1022+
}}
1023+
debug={false}
1024+
renderers={{ div: DivRenderer }}
1025+
contentWidth={100}
1026+
/>
1027+
);
1028+
expect(capturedKeys.length).toBeGreaterThan(0);
1029+
for (const key of capturedKeys) {
1030+
expect(key).toMatch(/^tnode_childTnode-/);
1031+
}
1032+
});
1033+
});
8961034
});

0 commit comments

Comments
 (0)