@@ -3137,6 +3137,163 @@ func BenchmarkPopulateContext(b *testing.B) {
3137
3137
}
3138
3138
}
3139
3139
3140
+ // testOptionsMiddleWare returns 200 on an OPTIONS request
3141
+ func testOptionsMiddleWare (inner http.Handler ) http.Handler {
3142
+ return http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
3143
+ if r .Method == http .MethodOptions {
3144
+ w .WriteHeader (http .StatusOK )
3145
+ return
3146
+ }
3147
+ inner .ServeHTTP (w , r )
3148
+ })
3149
+ }
3150
+
3151
+ // TestRouterOrder Should Pass whichever order route is defined
3152
+ func TestRouterOrder (t * testing.T ) {
3153
+ type requestCase struct {
3154
+ request * http.Request
3155
+ expCode int
3156
+ }
3157
+
3158
+ tests := []struct {
3159
+ name string
3160
+ routes []* Route
3161
+ customMiddleware MiddlewareFunc
3162
+ requests []requestCase
3163
+ }{
3164
+ {
3165
+ name : "Routes added with same method and intersecting path regex" ,
3166
+ routes : []* Route {
3167
+ new (Route ).Path ("/a/b" ).Handler (http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
3168
+ w .WriteHeader (http .StatusNotFound )
3169
+ })).Methods (http .MethodGet ),
3170
+ new (Route ).Path ("/a/{a}" ).Handler (http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
3171
+ w .WriteHeader (http .StatusOK )
3172
+ })).Methods (http .MethodGet ),
3173
+ },
3174
+ requests : []requestCase {
3175
+ {
3176
+ request : newRequest (http .MethodGet , "/a/b" ),
3177
+ expCode : http .StatusNotFound ,
3178
+ },
3179
+ {
3180
+ request : newRequest (http .MethodGet , "/a/a" ),
3181
+ expCode : http .StatusOK ,
3182
+ },
3183
+ },
3184
+ },
3185
+ {
3186
+ name : "Routes added with same method and intersecting path regex, path with pathVariable first" ,
3187
+ routes : []* Route {
3188
+ new (Route ).Path ("/a/{a}" ).Handler (http .HandlerFunc (
3189
+ func (w http.ResponseWriter , r * http.Request ) {
3190
+ w .WriteHeader (http .StatusOK )
3191
+ })).Methods (http .MethodGet ),
3192
+ new (Route ).Path ("/a/b" ).Handler (http .HandlerFunc (
3193
+ func (w http.ResponseWriter , r * http.Request ) {
3194
+ w .WriteHeader (http .StatusNotFound )
3195
+ })).Methods (http .MethodGet ),
3196
+ },
3197
+ requests : []requestCase {
3198
+ {
3199
+ request : newRequest (http .MethodGet , "/a/b" ),
3200
+ expCode : http .StatusOK ,
3201
+ },
3202
+ {
3203
+ request : newRequest (http .MethodGet , "/a/a" ),
3204
+ expCode : http .StatusOK ,
3205
+ },
3206
+ },
3207
+ },
3208
+ {
3209
+ name : "Routes added same path - different methods, no path variables" ,
3210
+ routes : []* Route {
3211
+ new (Route ).Path ("/a/b" ).Handler (http .HandlerFunc (
3212
+ func (w http.ResponseWriter , r * http.Request ) {
3213
+ w .WriteHeader (http .StatusOK )
3214
+ })).Methods (http .MethodGet ),
3215
+ new (Route ).Path ("/a/b" ).Handler (http .HandlerFunc (
3216
+ func (w http.ResponseWriter , r * http.Request ) {
3217
+ w .WriteHeader (http .StatusNotFound )
3218
+ })).Methods (http .MethodOptions ),
3219
+ },
3220
+ requests : []requestCase {
3221
+ {
3222
+ request : newRequest (http .MethodGet , "/a/b" ),
3223
+ expCode : http .StatusOK ,
3224
+ },
3225
+ {
3226
+ request : newRequest (http .MethodOptions , "/a/b" ),
3227
+ expCode : http .StatusNotFound ,
3228
+ },
3229
+ },
3230
+ },
3231
+ {
3232
+ name : "Routes added same path - different methods, with path variables and middleware" ,
3233
+ routes : []* Route {
3234
+ new (Route ).Path ("/a/{a}" ).Handler (http .HandlerFunc (
3235
+ func (w http.ResponseWriter , r * http.Request ) {
3236
+ w .WriteHeader (http .StatusNotFound )
3237
+ })).Methods (http .MethodGet ),
3238
+ new (Route ).Path ("/a/b" ).Handler (nil ).Methods (http .MethodOptions ),
3239
+ },
3240
+ customMiddleware : testOptionsMiddleWare ,
3241
+ requests : []requestCase {
3242
+ {
3243
+ request : newRequest (http .MethodGet , "/a/b" ),
3244
+ expCode : http .StatusNotFound ,
3245
+ },
3246
+ {
3247
+ request : newRequest (http .MethodOptions , "/a/b" ),
3248
+ expCode : http .StatusOK ,
3249
+ },
3250
+ },
3251
+ },
3252
+ {
3253
+ name : "Routes added same path - different methods, with path variables and middleware order reversed" ,
3254
+ routes : []* Route {
3255
+ new (Route ).Path ("/a/b" ).Handler (nil ).Methods (http .MethodOptions ),
3256
+ new (Route ).Path ("/a/{a}" ).Handler (http .HandlerFunc (
3257
+ func (w http.ResponseWriter , r * http.Request ) {
3258
+ w .WriteHeader (http .StatusNotFound )
3259
+ })).Methods (http .MethodGet ),
3260
+ },
3261
+ customMiddleware : testOptionsMiddleWare ,
3262
+ requests : []requestCase {
3263
+ {
3264
+ request : newRequest (http .MethodGet , "/a/b" ),
3265
+ expCode : http .StatusNotFound ,
3266
+ },
3267
+ {
3268
+ request : newRequest (http .MethodOptions , "/a/b" ),
3269
+ expCode : http .StatusOK ,
3270
+ },
3271
+ },
3272
+ },
3273
+ }
3274
+
3275
+ for _ , test := range tests {
3276
+ t .Run (test .name , func (t * testing.T ) {
3277
+ router := NewRouter ()
3278
+
3279
+ if test .customMiddleware != nil {
3280
+ router .Use (test .customMiddleware )
3281
+ }
3282
+
3283
+ router .routes = test .routes
3284
+ w := NewRecorder ()
3285
+
3286
+ for _ , requestCase := range test .requests {
3287
+ router .ServeHTTP (w , requestCase .request )
3288
+
3289
+ if w .Code != requestCase .expCode {
3290
+ t .Fatalf ("Expected status code %d (got %d)" , requestCase .expCode , w .Code )
3291
+ }
3292
+ }
3293
+ })
3294
+ }
3295
+ }
3296
+
3140
3297
// mapToPairs converts a string map to a slice of string pairs
3141
3298
func mapToPairs (m map [string ]string ) []string {
3142
3299
var i int
0 commit comments