@@ -10,7 +10,11 @@ function pickPathsAndParams(routes: RouteObject[], pathname: string) {
10
10
let matches = matchRoutes ( routes , pathname ) ;
11
11
return (
12
12
matches &&
13
- matches . map ( ( match ) => ( { path : match . route . path , params : match . params } ) )
13
+ matches . map ( ( match ) => ( {
14
+ ...( match . route . index ? { index : match . route . index } : { } ) ,
15
+ ...( match . route . path ? { path : match . route . path } : { } ) ,
16
+ params : match . params ,
17
+ } ) )
14
18
) ;
15
19
}
16
20
@@ -329,7 +333,7 @@ describe("path matching with splats", () => {
329
333
} ) ;
330
334
} ) ;
331
335
332
- describe ( "path matchine with optional segments" , ( ) => {
336
+ describe ( "path matching with optional segments" , ( ) => {
333
337
test ( "optional static segment at the start of the path" , ( ) => {
334
338
let routes = [
335
339
{
@@ -409,6 +413,24 @@ describe("path matchine with optional segments", () => {
409
413
} ,
410
414
] ) ;
411
415
} ) ;
416
+
417
+ test ( "optional static segment in nested routes" , ( ) => {
418
+ let nested = [
419
+ {
420
+ path : "/en?" ,
421
+ children : [
422
+ {
423
+ path : "abc" ,
424
+ } ,
425
+ ] ,
426
+ } ,
427
+ ] ;
428
+
429
+ expect ( pickPathsAndParams ( nested , "/en/abc" ) ) . toEqual ( [
430
+ { path : "/en?" , params : { } } ,
431
+ { path : "abc" , params : { } } ,
432
+ ] ) ;
433
+ } ) ;
412
434
} ) ;
413
435
414
436
describe ( "path matching with optional dynamic segments" , ( ) => {
@@ -491,4 +513,312 @@ describe("path matching with optional dynamic segments", () => {
491
513
} ,
492
514
] ) ;
493
515
} ) ;
516
+
517
+ test ( "consecutive optional dynamic segments in nested routes" , ( ) => {
518
+ let nested = [
519
+ {
520
+ path : "/one/:two?" ,
521
+ children : [
522
+ {
523
+ path : "three/:four?" ,
524
+ children : [
525
+ {
526
+ path : ":five?" ,
527
+ } ,
528
+ ] ,
529
+ } ,
530
+ ] ,
531
+ } ,
532
+ ] ;
533
+ expect ( pickPathsAndParams ( nested , "/one/dos/three/cuatro/cinco" ) ) . toEqual ( [
534
+ {
535
+ path : "/one/:two?" ,
536
+ params : { two : "dos" , four : "cuatro" , five : "cinco" } ,
537
+ } ,
538
+ {
539
+ path : "three/:four?" ,
540
+ params : { two : "dos" , four : "cuatro" , five : "cinco" } ,
541
+ } ,
542
+ { path : ":five?" , params : { two : "dos" , four : "cuatro" , five : "cinco" } } ,
543
+ ] ) ;
544
+ expect ( pickPathsAndParams ( nested , "/one/dos/three/cuatro" ) ) . toEqual ( [
545
+ {
546
+ path : "/one/:two?" ,
547
+ params : { two : "dos" , four : "cuatro" } ,
548
+ } ,
549
+ {
550
+ path : "three/:four?" ,
551
+ params : { two : "dos" , four : "cuatro" } ,
552
+ } ,
553
+ {
554
+ path : ":five?" ,
555
+ params : { two : "dos" , four : "cuatro" } ,
556
+ } ,
557
+ ] ) ;
558
+ expect ( pickPathsAndParams ( nested , "/one/dos/three" ) ) . toEqual ( [
559
+ {
560
+ path : "/one/:two?" ,
561
+ params : { two : "dos" } ,
562
+ } ,
563
+ {
564
+ path : "three/:four?" ,
565
+ params : { two : "dos" } ,
566
+ } ,
567
+ // Matches into 5 because it's just like if we did path=""
568
+ {
569
+ path : ":five?" ,
570
+ params : { two : "dos" } ,
571
+ } ,
572
+ ] ) ;
573
+ expect ( pickPathsAndParams ( nested , "/one/dos" ) ) . toEqual ( [
574
+ {
575
+ path : "/one/:two?" ,
576
+ params : { two : "dos" } ,
577
+ } ,
578
+ ] ) ;
579
+ expect ( pickPathsAndParams ( nested , "/one" ) ) . toEqual ( [
580
+ {
581
+ path : "/one/:two?" ,
582
+ params : { } ,
583
+ } ,
584
+ ] ) ;
585
+ expect ( pickPathsAndParams ( nested , "/one/three/cuatro/cinco" ) ) . toEqual ( [
586
+ {
587
+ path : "/one/:two?" ,
588
+ params : { four : "cuatro" , five : "cinco" } ,
589
+ } ,
590
+ {
591
+ path : "three/:four?" ,
592
+ params : { four : "cuatro" , five : "cinco" } ,
593
+ } ,
594
+ { path : ":five?" , params : { four : "cuatro" , five : "cinco" } } ,
595
+ ] ) ;
596
+ expect ( pickPathsAndParams ( nested , "/one/three/cuatro" ) ) . toEqual ( [
597
+ {
598
+ path : "/one/:two?" ,
599
+ params : { four : "cuatro" } ,
600
+ } ,
601
+ {
602
+ path : "three/:four?" ,
603
+ params : { four : "cuatro" } ,
604
+ } ,
605
+ {
606
+ path : ":five?" ,
607
+ params : { four : "cuatro" } ,
608
+ } ,
609
+ ] ) ;
610
+ expect ( pickPathsAndParams ( nested , "/one/three" ) ) . toEqual ( [
611
+ {
612
+ path : "/one/:two?" ,
613
+ params : { } ,
614
+ } ,
615
+ {
616
+ path : "three/:four?" ,
617
+ params : { } ,
618
+ } ,
619
+ // Matches into 5 because it's just like if we did path=""
620
+ {
621
+ path : ":five?" ,
622
+ params : { } ,
623
+ } ,
624
+ ] ) ;
625
+ expect ( pickPathsAndParams ( nested , "/one" ) ) . toEqual ( [
626
+ {
627
+ path : "/one/:two?" ,
628
+ params : { } ,
629
+ } ,
630
+ ] ) ;
631
+ } ) ;
632
+
633
+ test ( "prefers optional static over optional dynamic segments" , ( ) => {
634
+ let nested = [
635
+ {
636
+ path : "/one" ,
637
+ children : [
638
+ {
639
+ path : ":param?" ,
640
+ children : [
641
+ {
642
+ path : "three" ,
643
+ } ,
644
+ ] ,
645
+ } ,
646
+ {
647
+ path : "two?" ,
648
+ children : [
649
+ {
650
+ path : "three" ,
651
+ } ,
652
+ ] ,
653
+ } ,
654
+ ] ,
655
+ } ,
656
+ ] ;
657
+
658
+ // static `two` segment should win
659
+ expect ( pickPathsAndParams ( nested , "/one/two/three" ) ) . toEqual ( [
660
+ {
661
+ params : { } ,
662
+ path : "/one" ,
663
+ } ,
664
+ {
665
+ params : { } ,
666
+ path : "two?" ,
667
+ } ,
668
+ {
669
+ params : { } ,
670
+ path : "three" ,
671
+ } ,
672
+ ] ) ;
673
+
674
+ // fall back to param when no static match
675
+ expect ( pickPathsAndParams ( nested , "/one/not-two/three" ) ) . toEqual ( [
676
+ {
677
+ params : {
678
+ param : "not-two" ,
679
+ } ,
680
+ path : "/one" ,
681
+ } ,
682
+ {
683
+ params : {
684
+ param : "not-two" ,
685
+ } ,
686
+ path : ":param?" ,
687
+ } ,
688
+ {
689
+ params : {
690
+ param : "not-two" ,
691
+ } ,
692
+ path : "three" ,
693
+ } ,
694
+ ] ) ;
695
+
696
+ // No optional segment provided - earlier "dup" route should win
697
+ expect ( pickPathsAndParams ( nested , "/one/three" ) ) . toEqual ( [
698
+ {
699
+ params : { } ,
700
+ path : "/one" ,
701
+ } ,
702
+ {
703
+ params : { } ,
704
+ path : ":param?" ,
705
+ } ,
706
+ {
707
+ params : { } ,
708
+ path : "three" ,
709
+ } ,
710
+ ] ) ;
711
+ } ) ;
712
+
713
+ test ( "prefers index routes over optional static segments" , ( ) => {
714
+ let nested = [
715
+ {
716
+ path : "/one" ,
717
+ children : [
718
+ {
719
+ path : ":param?" ,
720
+ children : [
721
+ {
722
+ path : "three?" ,
723
+ } ,
724
+ {
725
+ index : true ,
726
+ } ,
727
+ ] ,
728
+ } ,
729
+ ] ,
730
+ } ,
731
+ ] ;
732
+
733
+ expect ( pickPathsAndParams ( nested , "/one/two" ) ) . toEqual ( [
734
+ {
735
+ params : {
736
+ param : "two" ,
737
+ } ,
738
+ path : "/one" ,
739
+ } ,
740
+ {
741
+ params : {
742
+ param : "two" ,
743
+ } ,
744
+ path : ":param?" ,
745
+ } ,
746
+ {
747
+ index : true ,
748
+ params : {
749
+ param : "two" ,
750
+ } ,
751
+ } ,
752
+ ] ) ;
753
+ expect ( pickPathsAndParams ( nested , "/one" ) ) . toEqual ( [
754
+ {
755
+ params : { } ,
756
+ path : "/one" ,
757
+ } ,
758
+ {
759
+ params : { } ,
760
+ path : ":param?" ,
761
+ } ,
762
+ {
763
+ index : true ,
764
+ params : { } ,
765
+ } ,
766
+ ] ) ;
767
+ } ) ;
768
+
769
+ test ( "prefers index routes over optional dynamic segments" , ( ) => {
770
+ let nested = [
771
+ {
772
+ path : "/one" ,
773
+ children : [
774
+ {
775
+ path : ":param?" ,
776
+ children : [
777
+ {
778
+ path : ":three?" ,
779
+ } ,
780
+ {
781
+ index : true ,
782
+ } ,
783
+ ] ,
784
+ } ,
785
+ ] ,
786
+ } ,
787
+ ] ;
788
+
789
+ expect ( pickPathsAndParams ( nested , "/one/two" ) ) . toEqual ( [
790
+ {
791
+ params : {
792
+ param : "two" ,
793
+ } ,
794
+ path : "/one" ,
795
+ } ,
796
+ {
797
+ params : {
798
+ param : "two" ,
799
+ } ,
800
+ path : ":param?" ,
801
+ } ,
802
+ {
803
+ index : true ,
804
+ params : {
805
+ param : "two" ,
806
+ } ,
807
+ } ,
808
+ ] ) ;
809
+ expect ( pickPathsAndParams ( nested , "/one" ) ) . toEqual ( [
810
+ {
811
+ params : { } ,
812
+ path : "/one" ,
813
+ } ,
814
+ {
815
+ params : { } ,
816
+ path : ":param?" ,
817
+ } ,
818
+ {
819
+ index : true ,
820
+ params : { } ,
821
+ } ,
822
+ ] ) ;
823
+ } ) ;
494
824
} ) ;
0 commit comments