@@ -210,6 +210,142 @@ describe('Renderer', () => {
210210 createElementSpy . mockRestore ( ) ;
211211 } ) ;
212212
213+ it ( 'should handle multiple instances of the same component with correct streamStatus' , ( ) => {
214+ const components = {
215+ 'multi-instance' : MockComponent ,
216+ } ;
217+
218+ const renderer = new Renderer ( { components } ) ;
219+ const createElementSpy = jest . spyOn ( React , 'createElement' ) ;
220+
221+ // Scenario: First instance is closed (done), second instance is open (loading)
222+ const html = '<multi-instance>Instance 1</multi-instance><multi-instance>Instance 2' ;
223+ renderer . processHtml ( html ) ;
224+
225+ // Filter calls to MockComponent
226+ const calls = createElementSpy . mock . calls . filter ( ( call ) => call [ 0 ] === MockComponent ) ;
227+
228+ expect ( calls . length ) . toBe ( 2 ) ;
229+
230+ // First instance should be done
231+ expect ( calls [ 0 ] [ 1 ] ) . toEqual (
232+ expect . objectContaining ( {
233+ streamStatus : 'done' ,
234+ } ) ,
235+ ) ;
236+
237+ // Second instance should be loading
238+ expect ( calls [ 1 ] [ 1 ] ) . toEqual (
239+ expect . objectContaining ( {
240+ streamStatus : 'loading' ,
241+ } ) ,
242+ ) ;
243+
244+ createElementSpy . mockRestore ( ) ;
245+ } ) ;
246+
247+ it ( 'should mark all instances as done when all are closed' , ( ) => {
248+ const components = {
249+ 'multi-instance' : MockComponent ,
250+ } ;
251+
252+ const renderer = new Renderer ( { components } ) ;
253+ const createElementSpy = jest . spyOn ( React , 'createElement' ) ;
254+
255+ const html =
256+ '<multi-instance>Instance 1</multi-instance><multi-instance>Instance 2</multi-instance>' ;
257+ renderer . processHtml ( html ) ;
258+
259+ const calls = createElementSpy . mock . calls . filter ( ( call ) => call [ 0 ] === MockComponent ) ;
260+
261+ expect ( calls . length ) . toBe ( 2 ) ;
262+ expect ( calls [ 0 ] [ 1 ] ) . toEqual ( expect . objectContaining ( { streamStatus : 'done' } ) ) ;
263+ expect ( calls [ 1 ] [ 1 ] ) . toEqual ( expect . objectContaining ( { streamStatus : 'done' } ) ) ;
264+
265+ createElementSpy . mockRestore ( ) ;
266+ } ) ;
267+
268+ it ( 'should handle nested instances of the same component correctly' , ( ) => {
269+ const components = {
270+ 'multi-instance' : MockComponent ,
271+ } ;
272+
273+ const renderer = new Renderer ( { components } ) ;
274+ const createElementSpy = jest . spyOn ( React , 'createElement' ) ;
275+
276+ // Outer open, Inner closed
277+ const html = '<multi-instance>Outer <multi-instance>Inner</multi-instance>' ;
278+ renderer . processHtml ( html ) ;
279+
280+ const calls = createElementSpy . mock . calls . filter ( ( call ) => call [ 0 ] === MockComponent ) ;
281+ expect ( calls . length ) . toBe ( 2 ) ;
282+
283+ // Inner instance (processed first as children are created before parent)
284+ expect ( calls [ 0 ] [ 1 ] ) . toEqual ( expect . objectContaining ( { streamStatus : 'done' } ) ) ;
285+ // Outer instance
286+ expect ( calls [ 1 ] [ 1 ] ) . toEqual ( expect . objectContaining ( { streamStatus : 'loading' } ) ) ;
287+
288+ createElementSpy . mockRestore ( ) ;
289+ } ) ;
290+
291+ it ( 'should handle deep nesting with mixed states' , ( ) => {
292+ const components = {
293+ 'multi-instance' : MockComponent ,
294+ } ;
295+
296+ const renderer = new Renderer ( { components } ) ;
297+ const createElementSpy = jest . spyOn ( React , 'createElement' ) ;
298+
299+ // Level 1: Open
300+ // Level 2: Open
301+ // Level 3: Closed
302+ const html = '<multi-instance>1<multi-instance>2<multi-instance>3</multi-instance>' ;
303+ renderer . processHtml ( html ) ;
304+
305+ const calls = createElementSpy . mock . calls . filter ( ( call ) => call [ 0 ] === MockComponent ) ;
306+ expect ( calls . length ) . toBe ( 3 ) ;
307+
308+ // Level 3 (Inner most) - Done
309+ expect ( calls [ 0 ] [ 1 ] ) . toEqual ( expect . objectContaining ( { streamStatus : 'done' } ) ) ;
310+
311+ // Level 2 - Loading
312+ expect ( calls [ 1 ] [ 1 ] ) . toEqual ( expect . objectContaining ( { streamStatus : 'loading' } ) ) ;
313+
314+ // Level 1 - Loading
315+ expect ( calls [ 2 ] [ 1 ] ) . toEqual ( expect . objectContaining ( { streamStatus : 'loading' } ) ) ;
316+
317+ createElementSpy . mockRestore ( ) ;
318+ } ) ;
319+
320+ it ( 'should handle interleaved components correctly' , ( ) => {
321+ const components = {
322+ 'comp-a' : MockComponent ,
323+ 'comp-b' : MockComponent ,
324+ } ;
325+ const renderer = new Renderer ( { components } ) ;
326+ const createElementSpy = jest . spyOn ( React , 'createElement' ) ;
327+
328+ // comp-a closed, comp-b closed, comp-a open
329+ const html = '<comp-a>A1</comp-a><comp-b>B1</comp-b><comp-a>A2' ;
330+ renderer . processHtml ( html ) ;
331+
332+ const callsA = createElementSpy . mock . calls . filter (
333+ ( call ) => call [ 0 ] === MockComponent && ( call [ 1 ] as any ) . domNode . name === 'comp-a' ,
334+ ) ;
335+ const callsB = createElementSpy . mock . calls . filter (
336+ ( call ) => call [ 0 ] === MockComponent && ( call [ 1 ] as any ) . domNode . name === 'comp-b' ,
337+ ) ;
338+
339+ expect ( callsA . length ) . toBe ( 2 ) ;
340+ expect ( callsB . length ) . toBe ( 1 ) ;
341+
342+ expect ( callsA [ 0 ] [ 1 ] ) . toEqual ( expect . objectContaining ( { streamStatus : 'done' } ) ) ;
343+ expect ( callsB [ 0 ] [ 1 ] ) . toEqual ( expect . objectContaining ( { streamStatus : 'done' } ) ) ;
344+ expect ( callsA [ 1 ] [ 1 ] ) . toEqual ( expect . objectContaining ( { streamStatus : 'loading' } ) ) ;
345+
346+ createElementSpy . mockRestore ( ) ;
347+ } ) ;
348+
213349 it ( 'should merge class and className attributes correctly' , ( ) => {
214350 const components = {
215351 'test-component' : MockComponent ,
0 commit comments