@@ -179,10 +179,10 @@ public void MergeWithSnapshot_CoreFunctionality_InsertsNewReplacesExistingKeepsU
179179 new FactoryState ( new Dictionary < int , FactoryPartState > ( ) ) ,
180180 new Dictionary < int , byte [ ] >
181181 {
182- { 1 , new byte [ ] { 1 , 1 , 1 } } , // Will stay UNTOUCHED
183- { 2 , new byte [ ] { 2 , 2 , 2 } } , // Will be REPLACED
184- { 3 , new byte [ ] { 3 , 3 , 3 } } , // Will stay UNTOUCHED
185- { 4 , new byte [ ] { 4 , 4 , 4 } } , // Will be REPLACED
182+ { 1 , new byte [ ] { 1 , 1 , 1 } } , // Will stay UNTOUCHED
183+ { 2 , new byte [ ] { 2 , 2 , 2 } } , // Will be REPLACED
184+ { 3 , new byte [ ] { 3 , 3 , 3 } } , // Will stay UNTOUCHED
185+ { 4 , new byte [ ] { 4 , 4 , 4 } } , // Will be REPLACED
186186 } ,
187187 null ) ;
188188
@@ -374,13 +374,20 @@ public void MergeWithSnapshot_WithNullReceivedData_DoesNotModifyCurrentData()
374374 public void MergeWithSnapshot_RemovesDataOfDestroyedObjects ( )
375375 {
376376 var currentSnapshot = new ElympicsSnapshot (
377- - 1 ,
377+ 1 ,
378378 default ,
379- new ( new ( ) { { 0 , new ( 32 , new ( 2 , new ( )
379+ new ( new ( )
380380 {
381- { 30 , new ( 30 , 29 , "path1" ) } ,
382- { 31 , new ( 31 , 30 , "path2" ) }
383- } ) ) } } ) ,
381+ {
382+ 0 , new ( 32 ,
383+ new ( 2 ,
384+ new ( )
385+ {
386+ { 30 , new ( 30 , 29 , "path1" ) } ,
387+ { 31 , new ( 31 , 30 , "path2" ) }
388+ } ) )
389+ }
390+ } ) ,
384391 new Dictionary < int , byte [ ] >
385392 {
386393 { 30 , new byte [ 0 ] } ,
@@ -389,12 +396,19 @@ public void MergeWithSnapshot_RemovesDataOfDestroyedObjects()
389396 null ) ;
390397
391398 var receivedSnapshot = new ElympicsSnapshot (
392- - 1 ,
399+ 2 ,
393400 default ,
394- new ( new ( ) { { 0 , new ( 32 , new ( 2 , new ( )
401+ new ( new ( )
395402 {
396- { 31 , new ( 31 , 30 , "path2" ) }
397- } ) ) } } ) ,
403+ {
404+ 0 , new ( 32 ,
405+ new ( 2 ,
406+ new ( )
407+ {
408+ { 31 , new ( 31 , 30 , "path2" ) }
409+ } ) )
410+ }
411+ } ) ,
398412 new Dictionary < int , byte [ ] > ( ) ,
399413 null ) ;
400414
@@ -404,5 +418,72 @@ public void MergeWithSnapshot_RemovesDataOfDestroyedObjects()
404418 Assert . AreEqual ( 1 , currentSnapshot . Data ! . Count ) ;
405419 Assert . AreEqual ( 31 , currentSnapshot . Data . First ( ) . Key ) ;
406420 }
421+
422+ [ Test ]
423+ public void MergeWithSnapshot_CalledTwiceWithSameSnapshot_ShouldNotThrow ( )
424+ {
425+ var currentSnapshot = new ElympicsSnapshot (
426+ 10 ,
427+ default ,
428+ new FactoryState ( new Dictionary < int , FactoryPartState > ( ) ) ,
429+ null , // Data is null - this triggers aliasing on first merge
430+ null ) ;
431+
432+ var receivedSnapshot = new ElympicsSnapshot (
433+ 20 ,
434+ DateTime . UtcNow ,
435+ new FactoryState ( new Dictionary < int , FactoryPartState > ( ) ) ,
436+ new Dictionary < int , byte [ ] >
437+ {
438+ { 1 , new byte [ ] { 1 , 2 , 3 } } ,
439+ { 2 , new byte [ ] { 4 , 5 , 6 } } ,
440+ { 3 , new byte [ ] { 7 , 8 , 9 } } ,
441+ } ,
442+ null ) ;
443+
444+ currentSnapshot . MergeWithSnapshot ( receivedSnapshot ) ;
445+
446+ Assert . That ( currentSnapshot . Data ,
447+ Is . SameAs ( receivedSnapshot . Data ) ,
448+ "After first merge with null Data, currentSnapshot.Data should be aliased to receivedSnapshot.Data" ) ;
449+
450+ Assert . DoesNotThrow ( ( ) => currentSnapshot . MergeWithSnapshot ( receivedSnapshot ) ,
451+ "MergeWithSnapshot should not throw when called twice with the same snapshot" ) ;
452+
453+ // Verify data integrity after both merges
454+ Assert . That ( currentSnapshot . Data ! . Count , Is . EqualTo ( 3 ) ) ;
455+ Assert . That ( currentSnapshot . Tick , Is . EqualTo ( 20 ) ) ;
456+ }
457+
458+ [ Test ]
459+ public void MergeWithSnapshot_CalledTwiceWithSameSnapshot_DataIntegrity ( )
460+ {
461+ var currentSnapshot = new ElympicsSnapshot (
462+ 10 ,
463+ default ,
464+ new FactoryState ( new Dictionary < int , FactoryPartState > ( ) ) ,
465+ null ,
466+ null ) ;
467+
468+ var receivedSnapshot = new ElympicsSnapshot (
469+ 20 ,
470+ DateTime . UtcNow ,
471+ new FactoryState ( new Dictionary < int , FactoryPartState > ( ) ) ,
472+ new Dictionary < int , byte [ ] >
473+ {
474+ { 1 , new byte [ ] { 10 } } ,
475+ { 2 , new byte [ ] { 20 } } ,
476+ } ,
477+ null ) ;
478+
479+ currentSnapshot . MergeWithSnapshot ( receivedSnapshot ) ;
480+ currentSnapshot . MergeWithSnapshot ( receivedSnapshot ) ;
481+ currentSnapshot . MergeWithSnapshot ( receivedSnapshot ) ;
482+
483+ Assert . That ( currentSnapshot . Data ! . Count , Is . EqualTo ( 2 ) ) ;
484+ var dataDict = currentSnapshot . Data . ToDictionary ( kvp => kvp . Key , kvp => kvp . Value ) ;
485+ Assert . That ( dataDict [ 1 ] , Is . EqualTo ( new byte [ ] { 10 } ) ) ;
486+ Assert . That ( dataDict [ 2 ] , Is . EqualTo ( new byte [ ] { 20 } ) ) ;
487+ }
407488 }
408489}
0 commit comments