github.com/gofiber/fiber/v2@v2.47.0/path_testcases_test.go (about) 1 // ⚡️ Fiber is an Express inspired web framework written in Go with ☕️ 2 // 📝 Github Repository: https://github.com/gofiber/fiber 3 // 📌 API Documentation: https://docs.gofiber.io 4 5 package fiber 6 7 import ( 8 "strings" 9 ) 10 11 type routeTestCase struct { 12 url string 13 match bool 14 params []string 15 partialCheck bool 16 } 17 18 type routeCaseCollection struct { 19 pattern string 20 testCases []routeTestCase 21 } 22 23 var ( 24 benchmarkCases []routeCaseCollection 25 routeTestCases []routeCaseCollection 26 ) 27 28 func init() { 29 // smaller list for benchmark cases 30 benchmarkCases = []routeCaseCollection{ 31 { 32 pattern: "/api/v1/const", 33 testCases: []routeTestCase{ 34 {url: "/api/v1/const", params: []string{}, match: true}, 35 {url: "/api/v1", params: nil, match: false}, 36 {url: "/api/v1/", params: nil, match: false}, 37 {url: "/api/v1/something", params: nil, match: false}, 38 }, 39 }, 40 { 41 pattern: "/api/:param/fixedEnd", 42 testCases: []routeTestCase{ 43 {url: "/api/abc/fixedEnd", params: []string{"abc"}, match: true}, 44 {url: "/api/abc/def/fixedEnd", params: nil, match: false}, 45 }, 46 }, 47 { 48 pattern: "/api/v1/:param/*", 49 testCases: []routeTestCase{ 50 {url: "/api/v1/entity", params: []string{"entity", ""}, match: true}, 51 {url: "/api/v1/entity/", params: []string{"entity", ""}, match: true}, 52 {url: "/api/v1/entity/1", params: []string{"entity", "1"}, match: true}, 53 {url: "/api/v", params: nil, match: false}, 54 {url: "/api/v2", params: nil, match: false}, 55 {url: "/api/v1/", params: nil, match: false}, 56 }, 57 }, 58 } 59 60 // combine benchmark cases and other cases 61 routeTestCases = benchmarkCases 62 routeTestCases = append( 63 routeTestCases, 64 []routeCaseCollection{ 65 { 66 pattern: "/api/v1/:param/+", 67 testCases: []routeTestCase{ 68 {url: "/api/v1/entity", params: nil, match: false}, 69 {url: "/api/v1/entity/", params: nil, match: false}, 70 {url: "/api/v1/entity/1", params: []string{"entity", "1"}, match: true}, 71 {url: "/api/v", params: nil, match: false}, 72 {url: "/api/v2", params: nil, match: false}, 73 {url: "/api/v1/", params: nil, match: false}, 74 }, 75 }, 76 { 77 pattern: "/api/v1/:param?", 78 testCases: []routeTestCase{ 79 {url: "/api/v1", params: []string{""}, match: true}, 80 {url: "/api/v1/", params: []string{""}, match: true}, 81 {url: "/api/v1/optional", params: []string{"optional"}, match: true}, 82 {url: "/api/v", params: nil, match: false}, 83 {url: "/api/v2", params: nil, match: false}, 84 {url: "/api/xyz", params: nil, match: false}, 85 }, 86 }, 87 { 88 pattern: "/v1/some/resource/name\\:customVerb", 89 testCases: []routeTestCase{ 90 {url: "/v1/some/resource/name:customVerb", params: nil, match: true}, 91 {url: "/v1/some/resource/name:test", params: nil, match: false}, 92 }, 93 }, 94 { 95 pattern: "/v1/some/resource/:name\\:customVerb", 96 testCases: []routeTestCase{ 97 {url: "/v1/some/resource/test:customVerb", params: []string{"test"}, match: true}, 98 {url: "/v1/some/resource/test:test", params: nil, match: false}, 99 }, 100 }, 101 { 102 pattern: "/v1/some/resource/name\\\\:customVerb?\\?/:param/*", 103 testCases: []routeTestCase{ 104 {url: "/v1/some/resource/name:customVerb??/test/optionalWildCard/character", params: []string{"test", "optionalWildCard/character"}, match: true}, 105 {url: "/v1/some/resource/name:customVerb??/test", params: []string{"test", ""}, match: true}, 106 }, 107 }, 108 { 109 pattern: "/api/v1/*", 110 testCases: []routeTestCase{ 111 {url: "/api/v1", params: []string{""}, match: true}, 112 {url: "/api/v1/", params: []string{""}, match: true}, 113 {url: "/api/v1/entity", params: []string{"entity"}, match: true}, 114 {url: "/api/v1/entity/1/2", params: []string{"entity/1/2"}, match: true}, 115 {url: "/api/v1/Entity/1/2", params: []string{"Entity/1/2"}, match: true}, 116 {url: "/api/v", params: nil, match: false}, 117 {url: "/api/v2", params: nil, match: false}, 118 {url: "/api/abc", params: nil, match: false}, 119 }, 120 }, 121 { 122 pattern: "/api/v1/:param", 123 testCases: []routeTestCase{ 124 {url: "/api/v1/entity", params: []string{"entity"}, match: true}, 125 {url: "/api/v1/entity/8728382", params: nil, match: false}, 126 {url: "/api/v1", params: nil, match: false}, 127 {url: "/api/v1/", params: nil, match: false}, 128 }, 129 }, 130 { 131 pattern: "/api/v1/:param-:param2", 132 testCases: []routeTestCase{ 133 {url: "/api/v1/entity-entity2", params: []string{"entity", "entity2"}, match: true}, 134 {url: "/api/v1/entity/8728382", params: nil, match: false}, 135 {url: "/api/v1/entity-8728382", params: []string{"entity", "8728382"}, match: true}, 136 {url: "/api/v1", params: nil, match: false}, 137 {url: "/api/v1/", params: nil, match: false}, 138 }, 139 }, 140 { 141 pattern: "/api/v1/:filename.:extension", 142 testCases: []routeTestCase{ 143 {url: "/api/v1/test.pdf", params: []string{"test", "pdf"}, match: true}, 144 {url: "/api/v1/test/pdf", params: nil, match: false}, 145 {url: "/api/v1/test-pdf", params: nil, match: false}, 146 {url: "/api/v1/test_pdf", params: nil, match: false}, 147 {url: "/api/v1", params: nil, match: false}, 148 {url: "/api/v1/", params: nil, match: false}, 149 }, 150 }, 151 { 152 pattern: "/shop/product/::filter/color::color/size::size", 153 testCases: []routeTestCase{ 154 {url: "/shop/product/:test/color:blue/size:xs", params: []string{"test", "blue", "xs"}, match: true}, 155 {url: "/shop/product/test/color:blue/size:xs", params: nil, match: false}, 156 }, 157 }, 158 { 159 pattern: "/::param?", 160 testCases: []routeTestCase{ 161 {url: "/:hello", params: []string{"hello"}, match: true}, 162 {url: "/:", params: []string{""}, match: true}, 163 {url: "/", params: nil, match: false}, 164 }, 165 }, 166 // successive parameters, each take one character and the last parameter gets everything 167 { 168 pattern: "/test:sign:param", 169 testCases: []routeTestCase{ 170 {url: "/test-abc", params: []string{"-", "abc"}, match: true}, 171 {url: "/test", params: nil, match: false}, 172 }, 173 }, 174 // optional parameters are not greedy 175 { 176 pattern: "/:param1:param2?:param3", 177 testCases: []routeTestCase{ 178 {url: "/abbbc", params: []string{"a", "b", "bbc"}, match: true}, 179 // {url: "/ac", testCases: []string{"a", "", "c"}, match: true}, // TODO: fix it 180 {url: "/test", params: []string{"t", "e", "st"}, match: true}, 181 }, 182 }, 183 { 184 pattern: "/test:optional?:mandatory", 185 testCases: []routeTestCase{ 186 // {url: "/testo", testCases: []string{"", "o"}, match: true}, // TODO: fix it 187 {url: "/testoaaa", params: []string{"o", "aaa"}, match: true}, 188 {url: "/test", params: nil, match: false}, 189 }, 190 }, 191 { 192 pattern: "/test:optional?:optional2?", 193 testCases: []routeTestCase{ 194 {url: "/testo", params: []string{"o", ""}, match: true}, 195 {url: "/testoaaa", params: []string{"o", "aaa"}, match: true}, 196 {url: "/test", params: []string{"", ""}, match: true}, 197 {url: "/tes", params: nil, match: false}, 198 }, 199 }, 200 { 201 pattern: "/foo:param?bar", 202 testCases: []routeTestCase{ 203 {url: "/foofaselbar", params: []string{"fasel"}, match: true}, 204 {url: "/foobar", params: []string{""}, match: true}, 205 {url: "/fooba", params: nil, match: false}, 206 {url: "/fobar", params: nil, match: false}, 207 }, 208 }, 209 { 210 pattern: "/foo*bar", 211 testCases: []routeTestCase{ 212 {url: "/foofaselbar", params: []string{"fasel"}, match: true}, 213 {url: "/foobar", params: []string{""}, match: true}, 214 {url: "/", params: nil, match: false}, 215 }, 216 }, 217 { 218 pattern: "/foo+bar", 219 testCases: []routeTestCase{ 220 {url: "/foofaselbar", params: []string{"fasel"}, match: true}, 221 {url: "/foobar", params: nil, match: false}, 222 {url: "/", params: nil, match: false}, 223 }, 224 }, 225 { 226 pattern: "/a*cde*g/", 227 testCases: []routeTestCase{ 228 {url: "/abbbcdefffg", params: []string{"bbb", "fff"}, match: true}, 229 {url: "/acdeg", params: []string{"", ""}, match: true}, 230 {url: "/", params: nil, match: false}, 231 }, 232 }, 233 { 234 pattern: "/*v1*/proxy", 235 testCases: []routeTestCase{ 236 {url: "/customer/v1/cart/proxy", params: []string{"customer/", "/cart"}, match: true}, 237 {url: "/v1/proxy", params: []string{"", ""}, match: true}, 238 {url: "/v1/", params: nil, match: false}, 239 }, 240 }, 241 // successive wildcard -> first wildcard is greedy 242 { 243 pattern: "/foo***bar", 244 testCases: []routeTestCase{ 245 {url: "/foo*abar", params: []string{"*a", "", ""}, match: true}, 246 {url: "/foo*bar", params: []string{"*", "", ""}, match: true}, 247 {url: "/foobar", params: []string{"", "", ""}, match: true}, 248 {url: "/fooba", params: nil, match: false}, 249 }, 250 }, 251 // chars in front of an parameter 252 { 253 pattern: "/name::name", 254 testCases: []routeTestCase{ 255 {url: "/name:john", params: []string{"john"}, match: true}, 256 }, 257 }, 258 { 259 pattern: "/@:name", 260 testCases: []routeTestCase{ 261 {url: "/@john", params: []string{"john"}, match: true}, 262 }, 263 }, 264 { 265 pattern: "/-:name", 266 testCases: []routeTestCase{ 267 {url: "/-john", params: []string{"john"}, match: true}, 268 }, 269 }, 270 { 271 pattern: "/.:name", 272 testCases: []routeTestCase{ 273 {url: "/.john", params: []string{"john"}, match: true}, 274 }, 275 }, 276 { 277 pattern: "/api/v1/:param/abc/*", 278 testCases: []routeTestCase{ 279 {url: "/api/v1/well/abc/wildcard", params: []string{"well", "wildcard"}, match: true}, 280 {url: "/api/v1/well/abc/", params: []string{"well", ""}, match: true}, 281 {url: "/api/v1/well/abc", params: []string{"well", ""}, match: true}, 282 {url: "/api/v1/well/ttt", params: nil, match: false}, 283 }, 284 }, 285 { 286 pattern: "/api/:day/:month?/:year?", 287 testCases: []routeTestCase{ 288 {url: "/api/1", params: []string{"1", "", ""}, match: true}, 289 {url: "/api/1/", params: []string{"1", "", ""}, match: true}, 290 {url: "/api/1//", params: []string{"1", "", ""}, match: true}, 291 {url: "/api/1/-/", params: []string{"1", "-", ""}, match: true}, 292 {url: "/api/1-", params: []string{"1-", "", ""}, match: true}, 293 {url: "/api/1.", params: []string{"1.", "", ""}, match: true}, 294 {url: "/api/1/2", params: []string{"1", "2", ""}, match: true}, 295 {url: "/api/1/2/3", params: []string{"1", "2", "3"}, match: true}, 296 {url: "/api/", params: nil, match: false}, 297 }, 298 }, 299 { 300 pattern: "/api/:day.:month?.:year?", 301 testCases: []routeTestCase{ 302 {url: "/api/1", params: nil, match: false}, 303 {url: "/api/1/", params: nil, match: false}, 304 {url: "/api/1.", params: nil, match: false}, 305 {url: "/api/1..", params: []string{"1", "", ""}, match: true}, 306 {url: "/api/1.2", params: nil, match: false}, 307 {url: "/api/1.2.", params: []string{"1", "2", ""}, match: true}, 308 {url: "/api/1.2.3", params: []string{"1", "2", "3"}, match: true}, 309 {url: "/api/", params: nil, match: false}, 310 }, 311 }, 312 { 313 pattern: "/api/:day-:month?-:year?", 314 testCases: []routeTestCase{ 315 {url: "/api/1", params: nil, match: false}, 316 {url: "/api/1/", params: nil, match: false}, 317 {url: "/api/1-", params: nil, match: false}, 318 {url: "/api/1--", params: []string{"1", "", ""}, match: true}, 319 {url: "/api/1-/", params: nil, match: false}, 320 // {url: "/api/1-/-", testCases: nil, match: false}, // TODO: fix this part 321 {url: "/api/1-2", params: nil, match: false}, 322 {url: "/api/1-2-", params: []string{"1", "2", ""}, match: true}, 323 {url: "/api/1-2-3", params: []string{"1", "2", "3"}, match: true}, 324 {url: "/api/", params: nil, match: false}, 325 }, 326 }, 327 { 328 pattern: "/api/*", 329 testCases: []routeTestCase{ 330 {url: "/api/", params: []string{""}, match: true}, 331 {url: "/api/joker", params: []string{"joker"}, match: true}, 332 {url: "/api", params: []string{""}, match: true}, 333 {url: "/api/v1/entity", params: []string{"v1/entity"}, match: true}, 334 {url: "/api2/v1/entity", params: nil, match: false}, 335 {url: "/api_ignore/v1/entity", params: nil, match: false}, 336 }, 337 }, 338 { 339 pattern: "/partialCheck/foo/bar/:param", 340 testCases: []routeTestCase{ 341 {url: "/partialCheck/foo/bar/test", params: []string{"test"}, match: true, partialCheck: true}, 342 {url: "/partialCheck/foo/bar/test/test2", params: []string{"test"}, match: true, partialCheck: true}, 343 {url: "/partialCheck/foo/bar", params: nil, match: false, partialCheck: true}, 344 {url: "/partiaFoo", params: nil, match: false, partialCheck: true}, 345 }, 346 }, 347 { 348 pattern: "/", 349 testCases: []routeTestCase{ 350 {url: "/api", params: nil, match: false}, 351 {url: "", params: []string{}, match: true}, 352 {url: "/", params: []string{}, match: true}, 353 }, 354 }, 355 { 356 pattern: "/config/abc.json", 357 testCases: []routeTestCase{ 358 {url: "/config/abc.json", params: []string{}, match: true}, 359 {url: "config/abc.json", params: nil, match: false}, 360 {url: "/config/efg.json", params: nil, match: false}, 361 {url: "/config", params: nil, match: false}, 362 }, 363 }, 364 { 365 pattern: "/config/*.json", 366 testCases: []routeTestCase{ 367 {url: "/config/abc.json", params: []string{"abc"}, match: true}, 368 {url: "/config/efg.json", params: []string{"efg"}, match: true}, 369 {url: "/config/.json", params: []string{""}, match: true}, 370 {url: "/config/efg.csv", params: nil, match: false}, 371 {url: "config/abc.json", params: nil, match: false}, 372 {url: "/config", params: nil, match: false}, 373 }, 374 }, 375 { 376 pattern: "/config/+.json", 377 testCases: []routeTestCase{ 378 {url: "/config/abc.json", params: []string{"abc"}, match: true}, 379 {url: "/config/.json", params: nil, match: false}, 380 {url: "/config/efg.json", params: []string{"efg"}, match: true}, 381 {url: "/config/efg.csv", params: nil, match: false}, 382 {url: "config/abc.json", params: nil, match: false}, 383 {url: "/config", params: nil, match: false}, 384 }, 385 }, 386 { 387 pattern: "/xyz", 388 testCases: []routeTestCase{ 389 {url: "xyz", params: nil, match: false}, 390 {url: "xyz/", params: nil, match: false}, 391 }, 392 }, 393 { 394 pattern: "/api/*/:param?", 395 testCases: []routeTestCase{ 396 {url: "/api/", params: []string{"", ""}, match: true}, 397 {url: "/api/joker", params: []string{"joker", ""}, match: true}, 398 {url: "/api/joker/batman", params: []string{"joker", "batman"}, match: true}, 399 {url: "/api/joker//batman", params: []string{"joker/", "batman"}, match: true}, 400 {url: "/api/joker/batman/robin", params: []string{"joker/batman", "robin"}, match: true}, 401 {url: "/api/joker/batman/robin/1", params: []string{"joker/batman/robin", "1"}, match: true}, 402 {url: "/api/joker/batman/robin/1/", params: []string{"joker/batman/robin/1", ""}, match: true}, 403 {url: "/api/joker-batman/robin/1", params: []string{"joker-batman/robin", "1"}, match: true}, 404 {url: "/api/joker-batman-robin/1", params: []string{"joker-batman-robin", "1"}, match: true}, 405 {url: "/api/joker-batman-robin-1", params: []string{"joker-batman-robin-1", ""}, match: true}, 406 {url: "/api", params: []string{"", ""}, match: true}, 407 }, 408 }, 409 { 410 pattern: "/api/*/:param", 411 testCases: []routeTestCase{ 412 {url: "/api/test/abc", params: []string{"test", "abc"}, match: true}, 413 {url: "/api/joker/batman", params: []string{"joker", "batman"}, match: true}, 414 {url: "/api/joker/batman/robin", params: []string{"joker/batman", "robin"}, match: true}, 415 {url: "/api/joker/batman/robin/1", params: []string{"joker/batman/robin", "1"}, match: true}, 416 {url: "/api/joker/batman-robin/1", params: []string{"joker/batman-robin", "1"}, match: true}, 417 {url: "/api/joker-batman-robin-1", params: nil, match: false}, 418 {url: "/api", params: nil, match: false}, 419 }, 420 }, 421 { 422 pattern: "/api/+/:param", 423 testCases: []routeTestCase{ 424 {url: "/api/test/abc", params: []string{"test", "abc"}, match: true}, 425 {url: "/api/joker/batman/robin/1", params: []string{"joker/batman/robin", "1"}, match: true}, 426 {url: "/api/joker", params: nil, match: false}, 427 {url: "/api", params: nil, match: false}, 428 }, 429 }, 430 { 431 pattern: "/api/*/:param/:param2", 432 testCases: []routeTestCase{ 433 {url: "/api/test/abc/1", params: []string{"test", "abc", "1"}, match: true}, 434 {url: "/api/joker/batman", params: nil, match: false}, 435 {url: "/api/joker/batman-robin/1", params: []string{"joker", "batman-robin", "1"}, match: true}, 436 {url: "/api/joker-batman-robin-1", params: nil, match: false}, 437 {url: "/api/test/abc", params: nil, match: false}, 438 {url: "/api/joker/batman/robin", params: []string{"joker", "batman", "robin"}, match: true}, 439 {url: "/api/joker/batman/robin/1", params: []string{"joker/batman", "robin", "1"}, match: true}, 440 {url: "/api/joker/batman/robin/1/2", params: []string{"joker/batman/robin", "1", "2"}, match: true}, 441 {url: "/api", params: nil, match: false}, 442 {url: "/api/:test", params: nil, match: false}, 443 }, 444 }, 445 { 446 pattern: "/api/v1/:param<int>", 447 testCases: []routeTestCase{ 448 {url: "/api/v1/entity", params: nil, match: false}, 449 {url: "/api/v1/8728382", params: []string{"8728382"}, match: true}, 450 {url: "/api/v1/true", params: nil, match: false}, 451 }, 452 }, 453 { 454 pattern: "/api/v1/:param<bool>", 455 testCases: []routeTestCase{ 456 {url: "/api/v1/entity", params: nil, match: false}, 457 {url: "/api/v1/8728382", params: nil, match: false}, 458 {url: "/api/v1/true", params: []string{"true"}, match: true}, 459 }, 460 }, 461 { 462 pattern: "/api/v1/:param<float>", 463 testCases: []routeTestCase{ 464 {url: "/api/v1/entity", params: nil, match: false}, 465 {url: "/api/v1/8728382", params: []string{"8728382"}, match: true}, 466 {url: "/api/v1/8728382.5", params: []string{"8728382.5"}, match: true}, 467 {url: "/api/v1/true", params: nil, match: false}, 468 }, 469 }, 470 { 471 pattern: "/api/v1/:param<alpha>", 472 testCases: []routeTestCase{ 473 {url: "/api/v1/entity", params: []string{"entity"}, match: true}, 474 {url: "/api/v1/#!?", params: nil, match: false}, 475 {url: "/api/v1/8728382", params: nil, match: false}, 476 }, 477 }, 478 { 479 pattern: "/api/v1/:param<guid>", 480 testCases: []routeTestCase{ 481 {url: "/api/v1/entity", params: nil, match: false}, 482 {url: "/api/v1/8728382", params: nil, match: false}, 483 {url: "/api/v1/f0fa66cc-d22e-445b-866d-1d76e776371d", params: []string{"f0fa66cc-d22e-445b-866d-1d76e776371d"}, match: true}, 484 }, 485 }, 486 { 487 pattern: "/api/v1/:param<minLen>", 488 testCases: []routeTestCase{ 489 {url: "/api/v1/entity", params: nil, match: false}, 490 {url: "/api/v1/8728382", params: nil, match: false}, 491 }, 492 }, 493 { 494 pattern: "/api/v1/:param<minLen(5)>", 495 testCases: []routeTestCase{ 496 {url: "/api/v1/entity", params: []string{"entity"}, match: true}, 497 {url: "/api/v1/ent", params: nil, match: false}, 498 {url: "/api/v1/8728382", params: []string{"8728382"}, match: true}, 499 {url: "/api/v1/123", params: nil, match: false}, 500 {url: "/api/v1/12345", params: []string{"12345"}, match: true}, 501 }, 502 }, 503 { 504 pattern: "/api/v1/:param<maxLen(5)>", 505 testCases: []routeTestCase{ 506 {url: "/api/v1/entity", params: nil, match: false}, 507 {url: "/api/v1/ent", params: []string{"ent"}, match: true}, 508 {url: "/api/v1/8728382", params: nil, match: false}, 509 {url: "/api/v1/123", params: []string{"123"}, match: true}, 510 {url: "/api/v1/12345", params: []string{"12345"}, match: true}, 511 }, 512 }, 513 { 514 pattern: "/api/v1/:param<len(5)>", 515 testCases: []routeTestCase{ 516 {url: "/api/v1/ent", params: nil, match: false}, 517 {url: "/api/v1/123", params: nil, match: false}, 518 {url: "/api/v1/12345", params: []string{"12345"}, match: true}, 519 }, 520 }, 521 { 522 pattern: "/api/v1/:param<betweenLen(1)>", 523 testCases: []routeTestCase{ 524 {url: "/api/v1/entity", params: nil, match: false}, 525 {url: "/api/v1/ent", params: nil, match: false}, 526 }, 527 }, 528 { 529 pattern: "/api/v1/:param<betweenLen(2,5)>", 530 testCases: []routeTestCase{ 531 {url: "/api/v1/e", params: nil, match: false}, 532 {url: "/api/v1/en", params: []string{"en"}, match: true}, 533 {url: "/api/v1/8728382", params: nil, match: false}, 534 {url: "/api/v1/123", params: []string{"123"}, match: true}, 535 {url: "/api/v1/12345", params: []string{"12345"}, match: true}, 536 }, 537 }, 538 { 539 pattern: "/api/v1/:param<betweenLen(2,5)>", 540 testCases: []routeTestCase{ 541 {url: "/api/v1/e", params: nil, match: false}, 542 {url: "/api/v1/en", params: []string{"en"}, match: true}, 543 {url: "/api/v1/8728382", params: nil, match: false}, 544 {url: "/api/v1/123", params: []string{"123"}, match: true}, 545 {url: "/api/v1/12345", params: []string{"12345"}, match: true}, 546 }, 547 }, 548 { 549 pattern: "/api/v1/:param<min(5)>", 550 testCases: []routeTestCase{ 551 {url: "/api/v1/ent", params: nil, match: false}, 552 {url: "/api/v1/1", params: nil, match: false}, 553 {url: "/api/v1/5", params: []string{"5"}, match: true}, 554 }, 555 }, 556 { 557 pattern: "/api/v1/:param<max(5)>", 558 testCases: []routeTestCase{ 559 {url: "/api/v1/ent", params: nil, match: false}, 560 {url: "/api/v1/1", params: []string{"1"}, match: true}, 561 {url: "/api/v1/5", params: []string{"5"}, match: true}, 562 {url: "/api/v1/15", params: nil, match: false}, 563 }, 564 }, 565 { 566 pattern: "/api/v1/:param<range(5,10)>", 567 testCases: []routeTestCase{ 568 {url: "/api/v1/ent", params: nil, match: false}, 569 {url: "/api/v1/9", params: []string{"9"}, match: true}, 570 {url: "/api/v1/5", params: []string{"5"}, match: true}, 571 {url: "/api/v1/15", params: nil, match: false}, 572 }, 573 }, 574 { 575 pattern: "/api/v1/:param<datetime(2006\\-01\\-02)>", 576 testCases: []routeTestCase{ 577 {url: "/api/v1/entity", params: nil, match: false}, 578 {url: "/api/v1/8728382", params: nil, match: false}, 579 {url: "/api/v1/2005-11-01", params: []string{"2005-11-01"}, match: true}, 580 }, 581 }, 582 { 583 pattern: "/api/v1/:param<regex(p([a-z]+)ch)>", 584 testCases: []routeTestCase{ 585 {url: "/api/v1/ent", params: nil, match: false}, 586 {url: "/api/v1/15", params: nil, match: false}, 587 {url: "/api/v1/peach", params: []string{"peach"}, match: true}, 588 {url: "/api/v1/p34ch", params: nil, match: false}, 589 }, 590 }, 591 { 592 pattern: "/api/v1/:param<regex(^[a-z0-9]([a-z0-9-]{1,61}[a-z0-9])?$)>", 593 testCases: []routeTestCase{ 594 {url: "/api/v1/12", params: nil, match: false}, 595 {url: "/api/v1/xy", params: nil, match: false}, 596 {url: "/api/v1/test", params: []string{"test"}, match: true}, 597 {url: "/api/v1/" + strings.Repeat("a", 64), params: nil, match: false}, 598 }, 599 }, 600 { 601 pattern: "/api/v1/:param<regex(\\d{4}-\\d{2}-\\d{2})}>", 602 testCases: []routeTestCase{ 603 {url: "/api/v1/ent", params: nil, match: false}, 604 {url: "/api/v1/15", params: nil, match: false}, 605 {url: "/api/v1/2022-08-27", params: []string{"2022-08-27"}, match: true}, 606 {url: "/api/v1/2022/08-27", params: nil, match: false}, 607 }, 608 }, 609 { 610 pattern: "/api/v1/:param<int;bool((>", 611 testCases: []routeTestCase{ 612 {url: "/api/v1/entity", params: nil, match: false}, 613 {url: "/api/v1/8728382", params: []string{"8728382"}, match: true}, 614 {url: "/api/v1/true", params: nil, match: false}, 615 }, 616 }, 617 { 618 pattern: "/api/v1/:param<int;max(3000)>", 619 testCases: []routeTestCase{ 620 {url: "/api/v1/entity", params: nil, match: false}, 621 {url: "/api/v1/8728382", params: nil, match: false}, 622 {url: "/api/v1/123", params: []string{"123"}, match: true}, 623 {url: "/api/v1/true", params: nil, match: false}, 624 }, 625 }, 626 { 627 pattern: "/api/v1/:param<int;maxLen(10)>", 628 testCases: []routeTestCase{ 629 {url: "/api/v1/entity", params: nil, match: false}, 630 {url: "/api/v1/87283827683", params: nil, match: false}, 631 {url: "/api/v1/123", params: []string{"123"}, match: true}, 632 {url: "/api/v1/true", params: nil, match: false}, 633 }, 634 }, 635 { 636 pattern: "/api/v1/:param<int;range(10,30)>", 637 testCases: []routeTestCase{ 638 {url: "/api/v1/entity", params: nil, match: false}, 639 {url: "/api/v1/87283827683", params: nil, match: false}, 640 {url: "/api/v1/25", params: []string{"25"}, match: true}, 641 {url: "/api/v1/true", params: nil, match: false}, 642 }, 643 }, 644 { 645 pattern: "/api/v1/:param<int\\;range(10,30)>", 646 testCases: []routeTestCase{ 647 {url: "/api/v1/entity", params: []string{"entity"}, match: true}, 648 {url: "/api/v1/87283827683", params: []string{"87283827683"}, match: true}, 649 {url: "/api/v1/25", params: []string{"25"}, match: true}, 650 {url: "/api/v1/true", params: []string{"true"}, match: true}, 651 }, 652 }, 653 { 654 pattern: "/api/v1/:param<range(10\\,30,1500)>", 655 testCases: []routeTestCase{ 656 {url: "/api/v1/entity", params: nil, match: false}, 657 {url: "/api/v1/87283827683", params: nil, match: false}, 658 {url: "/api/v1/25", params: []string{"25"}, match: true}, 659 {url: "/api/v1/1200", params: []string{"1200"}, match: true}, 660 {url: "/api/v1/true", params: nil, match: false}, 661 }, 662 }, 663 { 664 pattern: "/api/v1/:lang<len(2)>/videos/:page<range(100,1500)>", 665 testCases: []routeTestCase{ 666 {url: "/api/v1/try/videos/200", params: nil, match: false}, 667 {url: "/api/v1/tr/videos/1800", params: nil, match: false}, 668 {url: "/api/v1/tr/videos/100", params: []string{"tr", "100"}, match: true}, 669 {url: "/api/v1/e/videos/10", params: nil, match: false}, 670 }, 671 }, 672 { 673 pattern: "/api/v1/:lang<len(2)>/:page<range(100,1500)>", 674 testCases: []routeTestCase{ 675 {url: "/api/v1/try/200", params: nil, match: false}, 676 {url: "/api/v1/tr/1800", params: nil, match: false}, 677 {url: "/api/v1/tr/100", params: []string{"tr", "100"}, match: true}, 678 {url: "/api/v1/e/10", params: nil, match: false}, 679 }, 680 }, 681 { 682 pattern: "/api/v1/:lang/:page<range(100,1500)>", 683 testCases: []routeTestCase{ 684 {url: "/api/v1/try/200", params: []string{"try", "200"}, match: true}, 685 {url: "/api/v1/tr/1800", params: nil, match: false}, 686 {url: "/api/v1/tr/100", params: []string{"tr", "100"}, match: true}, 687 {url: "/api/v1/e/10", params: nil, match: false}, 688 }, 689 }, 690 { 691 pattern: "/api/v1/:lang<len(2)>/:page", 692 testCases: []routeTestCase{ 693 {url: "/api/v1/try/200", params: nil, match: false}, 694 {url: "/api/v1/tr/1800", params: []string{"tr", "1800"}, match: true}, 695 {url: "/api/v1/tr/100", params: []string{"tr", "100"}, match: true}, 696 {url: "/api/v1/e/10", params: nil, match: false}, 697 }, 698 }, 699 { 700 pattern: "/api/v1/:date<datetime(2006\\-01\\-02)>/:regex<regex(p([a-z]+)ch)>", 701 testCases: []routeTestCase{ 702 {url: "/api/v1/2005-11-01/a", params: nil, match: false}, 703 {url: "/api/v1/2005-1101/paach", params: nil, match: false}, 704 {url: "/api/v1/2005-11-01/peach", params: []string{"2005-11-01", "peach"}, match: true}, 705 }, 706 }, 707 { 708 pattern: "/api/v1/:param<int>?", 709 testCases: []routeTestCase{ 710 {url: "/api/v1/entity", params: nil, match: false}, 711 {url: "/api/v1/8728382", params: []string{"8728382"}, match: true}, 712 {url: "/api/v1/true", params: nil, match: false}, 713 {url: "/api/v1/", params: []string{""}, match: true}, 714 }, 715 }, 716 }..., 717 ) 718 }