@@ -386,6 +386,88 @@ describe('rest query', () => {
386386 }
387387 ) ;
388388 } ) ;
389+
390+ it ( 'battle test parallel include with 100 nested includes' , async ( ) => {
391+ const RootObject = Parse . Object . extend ( 'RootObject' ) ;
392+ const Level1Object = Parse . Object . extend ( 'Level1Object' ) ;
393+ const Level2Object = Parse . Object . extend ( 'Level2Object' ) ;
394+
395+ // Create 100 level2 objects (10 per level1 object)
396+ const level2Objects = [ ] ;
397+ for ( let i = 0 ; i < 100 ; i ++ ) {
398+ const level2 = new Level2Object ( {
399+ index : i ,
400+ value : `level2_${ i } ` ,
401+ } ) ;
402+ level2Objects . push ( level2 ) ;
403+ }
404+ await Parse . Object . saveAll ( level2Objects ) ;
405+
406+ // Create 10 level1 objects, each with 10 pointers to level2 objects
407+ const level1Objects = [ ] ;
408+ for ( let i = 0 ; i < 10 ; i ++ ) {
409+ const level1 = new Level1Object ( {
410+ index : i ,
411+ value : `level1_${ i } ` ,
412+ } ) ;
413+ // Set 10 pointer fields (level2_0 through level2_9)
414+ for ( let j = 0 ; j < 10 ; j ++ ) {
415+ level1 . set ( `level2_${ j } ` , level2Objects [ i * 10 + j ] ) ;
416+ }
417+ level1Objects . push ( level1 ) ;
418+ }
419+ await Parse . Object . saveAll ( level1Objects ) ;
420+
421+ // Create 1 root object with 10 pointers to level1 objects
422+ const rootObject = new RootObject ( {
423+ value : 'root' ,
424+ } ) ;
425+ for ( let i = 0 ; i < 10 ; i ++ ) {
426+ rootObject . set ( `level1_${ i } ` , level1Objects [ i ] ) ;
427+ }
428+ await rootObject . save ( ) ;
429+
430+ // Build include paths: level1_0 through level1_9, and level1_0.level2_0 through level1_9.level2_9
431+ const includePaths = [ ] ;
432+ for ( let i = 0 ; i < 10 ; i ++ ) {
433+ includePaths . push ( `level1_${ i } ` ) ;
434+ for ( let j = 0 ; j < 10 ; j ++ ) {
435+ includePaths . push ( `level1_${ i } .level2_${ j } ` ) ;
436+ }
437+ }
438+
439+ // Query with all includes
440+ const query = new Parse . Query ( RootObject ) ;
441+ query . equalTo ( 'objectId' , rootObject . id ) ;
442+ for ( const path of includePaths ) {
443+ query . include ( path ) ;
444+ }
445+ console . time ( 'query.find' ) ;
446+ const results = await query . find ( ) ;
447+ console . timeEnd ( 'query.find' ) ;
448+ expect ( results . length ) . toBe ( 1 ) ;
449+
450+ const result = results [ 0 ] ;
451+ expect ( result . id ) . toBe ( rootObject . id ) ;
452+
453+ // Verify all 10 level1 objects are included
454+ for ( let i = 0 ; i < 10 ; i ++ ) {
455+ const level1Field = result . get ( `level1_${ i } ` ) ;
456+ expect ( level1Field ) . toBeDefined ( ) ;
457+ expect ( level1Field instanceof Parse . Object ) . toBe ( true ) ;
458+ expect ( level1Field . get ( 'index' ) ) . toBe ( i ) ;
459+ expect ( level1Field . get ( 'value' ) ) . toBe ( `level1_${ i } ` ) ;
460+
461+ // Verify all 10 level2 objects are included for each level1 object
462+ for ( let j = 0 ; j < 10 ; j ++ ) {
463+ const level2Field = level1Field . get ( `level2_${ j } ` ) ;
464+ expect ( level2Field ) . toBeDefined ( ) ;
465+ expect ( level2Field instanceof Parse . Object ) . toBe ( true ) ;
466+ expect ( level2Field . get ( 'index' ) ) . toBe ( i * 10 + j ) ;
467+ expect ( level2Field . get ( 'value' ) ) . toBe ( `level2_${ i * 10 + j } ` ) ;
468+ }
469+ }
470+ } ) ;
389471} ) ;
390472
391473describe ( 'RestQuery.each' , ( ) => {
0 commit comments