@@ -30,6 +30,132 @@ describe('Path parser', () => {
3030 ] )
3131 } )
3232
33+ it ( 'escapes non-colon char after param' , ( ) => {
34+ expect ( tokenizePath ( '/:foo\\-abc' ) ) . toEqual ( [
35+ [
36+ {
37+ type : TokenType . Param ,
38+ value : 'foo' ,
39+ regexp : '' ,
40+ repeatable : false ,
41+ optional : false ,
42+ } ,
43+ { type : TokenType . Static , value : '-abc' } ,
44+ ] ,
45+ ] )
46+ } )
47+
48+ it ( 'escapes ) inside custom re to allow nested groups' , ( ) => {
49+ expect ( tokenizePath ( '/:id((?:a-[^/]+\\)?)' ) ) . toEqual ( [
50+ [
51+ {
52+ type : TokenType . Param ,
53+ value : 'id' ,
54+ regexp : '(?:a-[^/]+)?' ,
55+ repeatable : false ,
56+ optional : false ,
57+ } ,
58+ ] ,
59+ ] )
60+ } )
61+
62+ it ( 'escapes + after empty custom re' , ( ) => {
63+ expect ( tokenizePath ( '/:p()\\+' ) ) . toEqual ( [
64+ [
65+ {
66+ type : TokenType . Param ,
67+ value : 'p' ,
68+ regexp : '' ,
69+ repeatable : false ,
70+ optional : false ,
71+ } ,
72+ { type : TokenType . Static , value : '+' } ,
73+ ] ,
74+ ] )
75+ } )
76+
77+ it ( 'escapes + after param' , ( ) => {
78+ expect ( tokenizePath ( '/:p\\+' ) ) . toEqual ( [
79+ [
80+ {
81+ type : TokenType . Param ,
82+ value : 'p' ,
83+ regexp : '' ,
84+ repeatable : false ,
85+ optional : false ,
86+ } ,
87+ { type : TokenType . Static , value : '+' } ,
88+ ] ,
89+ ] )
90+ } )
91+
92+ it ( 'escapes : after optional param with custom re' , ( ) => {
93+ expect ( tokenizePath ( '/:foo([^:]+)?\\:abc' ) ) . toEqual ( [
94+ [
95+ {
96+ type : TokenType . Param ,
97+ value : 'foo' ,
98+ regexp : '[^:]+' ,
99+ repeatable : false ,
100+ optional : true ,
101+ } ,
102+ { type : TokenType . Static , value : ':abc' } ,
103+ ] ,
104+ ] )
105+ } )
106+
107+ it ( 'escapes : after param' , ( ) => {
108+ expect ( tokenizePath ( '/:foo\\:abc' ) ) . toEqual ( [
109+ [
110+ {
111+ type : TokenType . Param ,
112+ value : 'foo' ,
113+ regexp : '' ,
114+ repeatable : false ,
115+ optional : false ,
116+ } ,
117+ { type : TokenType . Static , value : ':abc' } ,
118+ ] ,
119+ ] )
120+ } )
121+
122+ it ( 'escapes : after param with custom re' , ( ) => {
123+ expect ( tokenizePath ( '/:foo([^:]+)\\:abc' ) ) . toEqual ( [
124+ [
125+ {
126+ type : TokenType . Param ,
127+ value : 'foo' ,
128+ regexp : '[^:]+' ,
129+ repeatable : false ,
130+ optional : false ,
131+ } ,
132+ { type : TokenType . Static , value : ':abc' } ,
133+ ] ,
134+ ] )
135+ } )
136+
137+ it ( 'escapes : between two params' , ( ) => {
138+ expect ( tokenizePath ( '/:foo([^:]+)\\::bar' ) ) . toEqual ( [
139+ [
140+ {
141+ type : TokenType . Param ,
142+ value : 'foo' ,
143+ regexp : '[^:]+' ,
144+ repeatable : false ,
145+ optional : false ,
146+ } ,
147+ { type : TokenType . Static , value : ':' } ,
148+ {
149+ type : TokenType . Param ,
150+ value : 'bar' ,
151+ regexp : '' ,
152+ repeatable : false ,
153+ optional : false ,
154+ } ,
155+ ] ,
156+ ] )
157+ } )
158+
33159 // not sure how useful this is and if it's worth supporting because of the
34160 // cost to support the ranking as well
35161 it . skip ( 'groups' , ( ) => {
@@ -808,6 +934,24 @@ describe('Path parser', () => {
808934 } )
809935 } )
810936
937+ it ( 'param followed by escaped colon and static' , ( ) => {
938+ matchParams ( '/:foo\\:abc' , '/section:abc' , { foo : 'section' } )
939+ matchParams ( '/:foo\\:abc' , '/sectionabc' , null )
940+ } )
941+
942+ it ( 'param with custom re followed by escaped colon and another param' , ( ) => {
943+ matchParams ( '/:foo([^:]+)\\::bar' , '/section:aaabbbccc' , {
944+ foo : 'section' ,
945+ bar : 'aaabbbccc' ,
946+ } )
947+ } )
948+
949+ it ( 'escaped + becomes part of static path, not a repeat modifier' , ( ) => {
950+ matchParams ( '/:p\\+' , '/abc+' , { p : 'abc' } )
951+ matchParams ( '/:p\\+' , '/abc' , null )
952+ matchParams ( '/:p()\\+' , '/abc+' , { p : 'abc' } )
953+ } )
954+
811955 // end of parsing urls
812956 } )
813957
0 commit comments