@@ -6297,4 +6297,201 @@ describe("getDefaultFormState2()", () => {
6297
6297
empty : null ,
6298
6298
} ) ;
6299
6299
} ) ;
6300
+
6301
+ describe ( "array object reference sharing fix (issue #4756)" , ( ) => {
6302
+ const schema : Schema = {
6303
+ type : "object" ,
6304
+ properties : {
6305
+ config : {
6306
+ oneOf : [
6307
+ {
6308
+ title : "List Configuration" ,
6309
+ properties : {
6310
+ items : {
6311
+ type : "array" ,
6312
+ minItems : 2 ,
6313
+ items : {
6314
+ type : "object" ,
6315
+ properties : {
6316
+ field : {
6317
+ type : "string" ,
6318
+ } ,
6319
+ } ,
6320
+ } ,
6321
+ } ,
6322
+ } ,
6323
+ required : [ "items" ] ,
6324
+ } ,
6325
+ ] ,
6326
+ } ,
6327
+ } ,
6328
+ } ;
6329
+
6330
+ it ( "should create independent object instances for array items via getDefaultFormState" , ( ) => {
6331
+ const result = getDefaultFormState (
6332
+ testValidator ,
6333
+ defaultMerger ,
6334
+ schema ,
6335
+ undefined ,
6336
+ schema
6337
+ ) as any ;
6338
+
6339
+ expect ( result ) . toStrictEqual ( { config : { items : [ { } , { } ] } } ) ;
6340
+
6341
+ // Verify that modifying properties of one array item doesn't affect others
6342
+ expect ( result . config . items ) . toBeDefined ( ) ;
6343
+ expect ( Array . isArray ( result . config . items ) ) . toBe ( true ) ;
6344
+
6345
+ // Verify objects are independent instances - modifying one shouldn't affect the other
6346
+ ( result . config . items [ 0 ] as any ) . field = "test-value-1" ;
6347
+ expect ( ( result . config . items [ 1 ] as any ) . field ) . toBeUndefined ( ) ;
6348
+ expect ( result . config . items [ 0 ] ) . not . toBe ( result . config . items [ 1 ] ) ;
6349
+ } ) ;
6350
+
6351
+ it ( "should create independent object instances for array items via computeDefaults" , ( ) => {
6352
+ const result = computeDefaults ( testValidator , defaultMerger , schema , {
6353
+ ...defaults ,
6354
+ rootSchema : schema ,
6355
+ } ) as any ;
6356
+
6357
+ expect ( result ) . toStrictEqual ( { config : { items : [ { } , { } ] } } ) ;
6358
+
6359
+ // Verify that modifying properties of one array item doesn't affect others
6360
+ expect ( result . config . items ) . toBeDefined ( ) ;
6361
+ expect ( Array . isArray ( result . config . items ) ) . toBe ( true ) ;
6362
+
6363
+ // Verify objects are independent instances - modifying one shouldn't affect the other
6364
+ ( result . config . items [ 0 ] as any ) . field = "test-value-1" ;
6365
+ expect ( ( result . config . items [ 1 ] as any ) . field ) . toBeUndefined ( ) ;
6366
+ expect ( result . config . items [ 0 ] ) . not . toBe ( result . config . items [ 1 ] ) ;
6367
+ } ) ;
6368
+
6369
+ it ( "should create independent object instances for array items via getArrayDefaults" , ( ) => {
6370
+ const arraySchema : Schema = {
6371
+ type : "array" ,
6372
+ minItems : 3 ,
6373
+ items : {
6374
+ type : "object" ,
6375
+ properties : {
6376
+ field : {
6377
+ type : "string" ,
6378
+ } ,
6379
+ } ,
6380
+ } ,
6381
+ } ;
6382
+
6383
+ const result = getArrayDefaults (
6384
+ testValidator ,
6385
+ defaultMerger ,
6386
+ arraySchema ,
6387
+ {
6388
+ ...defaults ,
6389
+ rootSchema : arraySchema ,
6390
+ } ,
6391
+ undefined
6392
+ ) as any ;
6393
+
6394
+ expect ( result ) . toStrictEqual ( [ { } , { } , { } ] ) ;
6395
+
6396
+ // Verify that array exists and objects are independent
6397
+ expect ( result ) . toBeDefined ( ) ;
6398
+ expect ( Array . isArray ( result ) ) . toBe ( true ) ;
6399
+
6400
+ // Verify objects are independent instances
6401
+ ( result [ 0 ] as any ) . field = "test-value-1" ;
6402
+ ( result [ 1 ] as any ) . field = "test-value-2" ;
6403
+ expect ( ( result [ 2 ] as any ) . field ) . toBeUndefined ( ) ;
6404
+ expect ( result [ 0 ] ) . not . toBe ( result [ 1 ] ) ;
6405
+ expect ( result [ 1 ] ) . not . toBe ( result [ 2 ] ) ;
6406
+ expect ( result [ 0 ] ) . not . toBe ( result [ 2 ] ) ;
6407
+ } ) ;
6408
+
6409
+ it ( "should ensure array items with default values are independent instances" , ( ) => {
6410
+ const arraySchemaWithDefaults : Schema = {
6411
+ type : "array" ,
6412
+ minItems : 2 ,
6413
+ items : {
6414
+ type : "object" ,
6415
+ properties : {
6416
+ field : {
6417
+ type : "string" ,
6418
+ default : "default-value" ,
6419
+ } ,
6420
+ } ,
6421
+ } ,
6422
+ } ;
6423
+
6424
+ const result = getArrayDefaults (
6425
+ testValidator ,
6426
+ defaultMerger ,
6427
+ arraySchemaWithDefaults ,
6428
+ {
6429
+ ...defaults ,
6430
+ rootSchema : arraySchemaWithDefaults ,
6431
+ } ,
6432
+ undefined
6433
+ ) as any ;
6434
+
6435
+ expect ( result ) . toStrictEqual ( [
6436
+ { field : "default-value" } ,
6437
+ { field : "default-value" } ,
6438
+ ] ) ;
6439
+
6440
+ // Verify that array exists and objects are independent
6441
+ expect ( result ) . toBeDefined ( ) ;
6442
+ expect ( Array . isArray ( result ) ) . toBe ( true ) ;
6443
+
6444
+ // Verify objects are independent instances - modifying one shouldn't affect the other
6445
+ ( result [ 0 ] as any ) . field = "modified-value" ;
6446
+ expect ( ( result [ 1 ] as any ) . field ) . toBe ( "default-value" ) ;
6447
+ expect ( result [ 0 ] ) . not . toBe ( result [ 1 ] ) ;
6448
+ } ) ;
6449
+
6450
+ it ( "should ensure nested objects in arrays are independent instances" , ( ) => {
6451
+ const nestedObjectSchema : Schema = {
6452
+ type : "array" ,
6453
+ minItems : 2 ,
6454
+ items : {
6455
+ type : "object" ,
6456
+ properties : {
6457
+ nested : {
6458
+ type : "object" ,
6459
+ properties : {
6460
+ value : {
6461
+ type : "string" ,
6462
+ default : "nested-default" ,
6463
+ } ,
6464
+ } ,
6465
+ } ,
6466
+ } ,
6467
+ } ,
6468
+ } ;
6469
+
6470
+ const result = getArrayDefaults (
6471
+ testValidator ,
6472
+ defaultMerger ,
6473
+ nestedObjectSchema ,
6474
+ {
6475
+ ...defaults ,
6476
+ rootSchema : nestedObjectSchema ,
6477
+ } ,
6478
+ undefined
6479
+ ) as any ;
6480
+
6481
+ expect ( result ) . toStrictEqual ( [
6482
+ { nested : { value : "nested-default" } } ,
6483
+ { nested : { value : "nested-default" } } ,
6484
+ ] ) ;
6485
+
6486
+ // Verify that array exists and nested objects are independent
6487
+ expect ( result ) . toBeDefined ( ) ;
6488
+ expect ( Array . isArray ( result ) ) . toBe ( true ) ;
6489
+
6490
+ // Verify nested objects are independent instances
6491
+ ( result [ 0 ] as any ) . nested . value = "modified-nested-value" ;
6492
+ expect ( ( result [ 1 ] as any ) . nested . value ) . toBe ( "nested-default" ) ;
6493
+ expect ( result [ 0 ] ) . not . toBe ( result [ 1 ] ) ;
6494
+ expect ( ( result [ 0 ] as any ) . nested ) . not . toBe ( ( result [ 1 ] as any ) . nested ) ;
6495
+ } ) ;
6496
+ } ) ;
6300
6497
} ) ;
0 commit comments