github.com/teacat/go-davai@v1.1.1-0.20200831221114-b14311e2e4c9/main_test.go (about) 1 package davai 2 3 import ( 4 "net/http" 5 "os" 6 "path/filepath" 7 "sort" 8 "strings" 9 "testing" 10 "time" 11 12 "context" 13 14 rcontext "github.com/gorilla/context" 15 "github.com/parnurzeal/gorequest" 16 "github.com/stretchr/testify/assert" 17 ) 18 19 const ( 20 methodPost = "POST" 21 methodGet = "GET" 22 methodDelete = "DELETE" 23 methodOptions = "OPTIONS" 24 methodPut = "PUT" 25 methodPatch = "PATCH" 26 ) 27 28 type testRequest struct { 29 Path string 30 Method string 31 StatusCode int 32 Body string 33 } 34 35 func sendTestRequests(a *assert.Assertions, reqs []testRequest) { 36 request := gorequest.New() 37 for _, r := range reqs { 38 if r.StatusCode == 0 { 39 r.StatusCode = http.StatusOK 40 } 41 if r.Method == "" { 42 r.Method = methodGet 43 } 44 var resp gorequest.Response 45 var body string 46 var errs []error 47 switch r.Method { 48 case methodGet: 49 resp, body, errs = request.Get(r.Path).End() 50 case methodPost: 51 resp, body, errs = request.Post(r.Path).End() 52 case methodDelete: 53 resp, body, errs = request.Delete(r.Path).End() 54 case methodOptions: 55 resp, body, errs = request.Options(r.Path).End() 56 case methodPut: 57 resp, body, errs = request.Put(r.Path).End() 58 case methodPatch: 59 resp, body, errs = request.Patch(r.Path).End() 60 } 61 a.Len(errs, 0) 62 a.Equal(r.Body, body) 63 a.NotNil(resp) 64 a.Equal(r.StatusCode, resp.StatusCode, r.Path) 65 } 66 } 67 68 func varsToString(vars map[string]string) string { 69 var slice []string 70 71 for _, v := range vars { 72 slice = append(slice, v) 73 } 74 sort.Slice(slice, func(i, j int) bool { 75 return slice[i] < slice[j] 76 }) 77 a := strings.Join(slice, ",") 78 return a 79 } 80 81 func TestBasicRoute(t *testing.T) { 82 assert := assert.New(t) 83 r := New() 84 r.Get("/", func(w http.ResponseWriter, r *http.Request) { 85 w.Write([]byte("Root")) 86 }) 87 r.Get("/one", func(w http.ResponseWriter, r *http.Request) { 88 w.Write([]byte("One")) 89 }) 90 r.Get("/one/two", func(w http.ResponseWriter, r *http.Request) { 91 w.Write([]byte("Two")) 92 }) 93 r.Get("/one/two/three", func(w http.ResponseWriter, r *http.Request) { 94 w.Write([]byte("Three")) 95 }) 96 r.Get("/four-four", func(w http.ResponseWriter, r *http.Request) { 97 w.Write([]byte("Four")) 98 }) 99 r.Get("/five-five/five-five", func(w http.ResponseWriter, r *http.Request) { 100 w.Write([]byte("Five")) 101 }) 102 r.Get("/six_six", func(w http.ResponseWriter, r *http.Request) { 103 w.Write([]byte("Six")) 104 }) 105 r.Get("/seven_", func(w http.ResponseWriter, r *http.Request) { 106 w.Write([]byte("Seven")) 107 }) 108 go func() { 109 err := r.Run() 110 if err != nil && err != http.ErrServerClosed { 111 assert.NoError(err) 112 } 113 }() 114 <-time.After(time.Millisecond * 200) 115 sendTestRequests(assert, []testRequest{ 116 { 117 Path: "http://localhost:8080/", 118 Body: "Root", 119 }, 120 { 121 Path: "http://localhost:8080/one", 122 Body: "One", 123 }, 124 { 125 Path: "http://localhost:8080/one/two", 126 Body: "Two", 127 }, 128 { 129 Path: "http://localhost:8080/one/two/three", 130 Body: "Three", 131 }, 132 { 133 Path: "http://localhost:8080/four-four", 134 Body: "Four", 135 }, 136 { 137 Path: "http://localhost:8080/five-five/five-five", 138 Body: "Five", 139 }, 140 { 141 Path: "http://localhost:8080/six_six", 142 Body: "Six", 143 }, 144 { 145 Path: "http://localhost:8080/seven_", 146 Body: "Seven", 147 }, 148 { 149 Path: "http://localhost:8080/one/two/three/four", 150 StatusCode: http.StatusNotFound, 151 Body: "404 page not found\n", 152 }, 153 }) 154 r.Shutdown(context.Background()) 155 <-time.After(time.Millisecond * 200) 156 } 157 158 func TestAddPriority(t *testing.T) { 159 assert := assert.New(t) 160 r := New() 161 r.Get("/", func(w http.ResponseWriter, r *http.Request) { 162 w.Write([]byte("Root")) 163 }) 164 r.Get("/{a}", func(w http.ResponseWriter, r *http.Request) { 165 w.Write([]byte("a")) 166 }).AddPriority(100) 167 r.Get("/{a}/{*:b}", func(w http.ResponseWriter, r *http.Request) { 168 w.Write([]byte("a|b")) 169 }) 170 go func() { 171 err := r.Run() 172 if err != nil && err != http.ErrServerClosed { 173 assert.NoError(err) 174 } 175 }() 176 <-time.After(time.Millisecond * 200) 177 sendTestRequests(assert, []testRequest{ 178 { 179 Path: "http://localhost:8080/", 180 Body: "Root", 181 }, 182 { 183 Path: "http://localhost:8080/one", 184 Body: "a", 185 }, 186 { 187 Path: "http://localhost:8080/one/two", 188 Body: "a|b", 189 }, 190 { 191 Path: "http://localhost:8080/one/two/three", 192 Body: "a|b", 193 }, 194 }) 195 r.Shutdown(context.Background()) 196 <-time.After(time.Millisecond * 200) 197 198 r = New() 199 r.Get("/", func(w http.ResponseWriter, r *http.Request) { 200 w.Write([]byte("Root")) 201 }) 202 r.Get("/{a}", func(w http.ResponseWriter, r *http.Request) { 203 w.Write([]byte("a")) 204 }) 205 r.Get("/{a}/{*:b}", func(w http.ResponseWriter, r *http.Request) { 206 w.Write([]byte("a|b")) 207 }) 208 go func() { 209 err := r.Run() 210 if err != nil && err != http.ErrServerClosed { 211 assert.NoError(err) 212 } 213 }() 214 <-time.After(time.Millisecond * 200) 215 sendTestRequests(assert, []testRequest{ 216 { 217 Path: "http://localhost:8080/", 218 Body: "Root", 219 }, 220 { 221 Path: "http://localhost:8080/one", 222 Body: "a|b", 223 }, 224 { 225 Path: "http://localhost:8080/one/two", 226 Body: "a|b", 227 }, 228 { 229 Path: "http://localhost:8080/one/two/three", 230 Body: "a|b", 231 }, 232 }) 233 r.Shutdown(context.Background()) 234 <-time.After(time.Millisecond * 200) 235 } 236 237 func TestBasicMethodRoute(t *testing.T) { 238 assert := assert.New(t) 239 r := New() 240 r.Get("/get", func(w http.ResponseWriter, r *http.Request) { 241 w.Write([]byte("Get")) 242 }) 243 r.Post("/post", func(w http.ResponseWriter, r *http.Request) { 244 w.Write([]byte("Post")) 245 }) 246 r.Put("/put", func(w http.ResponseWriter, r *http.Request) { 247 w.Write([]byte("Put")) 248 }) 249 r.Patch("/patch", func(w http.ResponseWriter, r *http.Request) { 250 w.Write([]byte("Patch")) 251 }) 252 r.Delete("/delete", func(w http.ResponseWriter, r *http.Request) { 253 w.Write([]byte("Delete")) 254 }) 255 r.Options("/options", func(w http.ResponseWriter, r *http.Request) { 256 w.Write([]byte("Options")) 257 }) 258 go func() { 259 err := r.Run() 260 if err != nil && err != http.ErrServerClosed { 261 assert.NoError(err) 262 } 263 }() 264 <-time.After(time.Millisecond * 200) 265 sendTestRequests(assert, []testRequest{ 266 { 267 Path: "http://localhost:8080/get", 268 Body: "Get", 269 }, 270 { 271 Path: "http://localhost:8080/post", 272 Method: methodPost, 273 Body: "Post", 274 }, 275 { 276 Path: "http://localhost:8080/put", 277 Method: methodPut, 278 Body: "Put", 279 }, 280 { 281 Path: "http://localhost:8080/patch", 282 Method: methodPatch, 283 Body: "Patch", 284 }, 285 { 286 Path: "http://localhost:8080/delete", 287 Method: methodDelete, 288 Body: "Delete", 289 }, 290 { 291 Path: "http://localhost:8080/options", 292 Method: methodOptions, 293 Body: "Options", 294 }, 295 { 296 Path: "http://localhost:8080/post", 297 Method: methodGet, 298 StatusCode: http.StatusNotFound, 299 Body: "404 page not found\n", 300 }, 301 }) 302 r.Shutdown(context.Background()) 303 <-time.After(time.Millisecond * 200) 304 } 305 306 func TestParamRoute(t *testing.T) { 307 assert := assert.New(t) 308 r := New() 309 r.Get("/", func(w http.ResponseWriter, r *http.Request) { 310 w.Write([]byte("Root")) 311 }) 312 r.Get("/{one}", func(w http.ResponseWriter, r *http.Request) { 313 w.Write([]byte(varsToString(Vars(r)))) 314 }) 315 r.Get("/{one}/{two}", func(w http.ResponseWriter, r *http.Request) { 316 w.Write([]byte(varsToString(Vars(r)))) 317 }) 318 r.Get("/{one}/{two}/{three}", func(w http.ResponseWriter, r *http.Request) { 319 w.Write([]byte(varsToString(Vars(r)))) 320 }) 321 go func() { 322 err := r.Run() 323 if err != nil && err != http.ErrServerClosed { 324 assert.NoError(err) 325 } 326 }() 327 <-time.After(time.Millisecond * 200) 328 sendTestRequests(assert, []testRequest{ 329 { 330 Path: "http://localhost:8080/", 331 Body: "Root", 332 }, 333 { 334 Path: "http://localhost:8080/1", 335 Body: "1", 336 }, 337 { 338 Path: "http://localhost:8080/1/2", 339 Body: "1,2", 340 }, 341 { 342 Path: "http://localhost:8080/1/2/3", 343 Body: "1,2,3", 344 }, 345 { 346 Path: "http://localhost:8080/1/2/3/4", 347 StatusCode: http.StatusNotFound, 348 Body: "404 page not found\n", 349 }, 350 }) 351 r.Shutdown(context.Background()) 352 <-time.After(time.Millisecond * 200) 353 } 354 355 func TestOptionalParamRoute(t *testing.T) { 356 assert := assert.New(t) 357 r := New() 358 r.Get("/{one?}", func(w http.ResponseWriter, r *http.Request) { 359 w.Write([]byte("one:" + varsToString(Vars(r)))) 360 }) 361 r.Get("/{one}/{two?}", func(w http.ResponseWriter, r *http.Request) { 362 w.Write([]byte("two:" + varsToString(Vars(r)))) 363 }) 364 r.Get("/{one}/{two}/{three?}", func(w http.ResponseWriter, r *http.Request) { 365 w.Write([]byte("three:" + varsToString(Vars(r)))) 366 }) 367 go func() { 368 err := r.Run() 369 if err != nil && err != http.ErrServerClosed { 370 assert.NoError(err) 371 } 372 }() 373 <-time.After(time.Millisecond * 200) 374 sendTestRequests(assert, []testRequest{ 375 { 376 Path: "http://localhost:8080/", 377 Body: "one:", 378 }, 379 { 380 Path: "http://localhost:8080/1", 381 Body: "two:,1", 382 }, 383 { 384 Path: "http://localhost:8080/1/2", 385 Body: "three:,1,2", 386 }, 387 { 388 Path: "http://localhost:8080/1/2/3", 389 Body: "three:1,2,3", 390 }, 391 { 392 Path: "http://localhost:8080/1/2/3/4", 393 StatusCode: http.StatusNotFound, 394 Body: "404 page not found\n", 395 }, 396 }) 397 r.Shutdown(context.Background()) 398 <-time.After(time.Millisecond * 200) 399 } 400 401 func TestOptionalParamRoute2(t *testing.T) { 402 assert := assert.New(t) 403 r := New() 404 r.Get("/fixed/{one?}", func(w http.ResponseWriter, r *http.Request) { 405 w.Write([]byte("one:" + varsToString(Vars(r)))) 406 }) 407 r.Get("/fixed/{one}/fixed", func(w http.ResponseWriter, r *http.Request) { 408 w.Write([]byte("one/fixed:" + varsToString(Vars(r)))) 409 }) 410 r.Get("/fixed/{one}/fixed/{two?}", func(w http.ResponseWriter, r *http.Request) { 411 w.Write([]byte("two:" + varsToString(Vars(r)))) 412 }) 413 r.Get("/fixed/{one}/fixed/{two}/fixed", func(w http.ResponseWriter, r *http.Request) { 414 w.Write([]byte("two/fixed:" + varsToString(Vars(r)))) 415 }) 416 r.Get("/fixed/{one}/fixed/{two}/fixed/{three?}", func(w http.ResponseWriter, r *http.Request) { 417 w.Write([]byte("three:" + varsToString(Vars(r)))) 418 }) 419 go func() { 420 err := r.Run() 421 if err != nil && err != http.ErrServerClosed { 422 assert.NoError(err) 423 } 424 }() 425 <-time.After(time.Millisecond * 200) 426 sendTestRequests(assert, []testRequest{ 427 { 428 Path: "http://localhost:8080/", 429 StatusCode: http.StatusNotFound, 430 Body: "404 page not found\n", 431 }, 432 { 433 Path: "http://localhost:8080/fixed", 434 Body: "one:", 435 }, 436 { 437 Path: "http://localhost:8080/fixed/1", 438 Body: "one:1", 439 }, 440 { 441 Path: "http://localhost:8080/fixed/1/fixed", 442 Body: "two:,1", 443 }, 444 { 445 Path: "http://localhost:8080/fixed/1/fixed/2", 446 Body: "two:1,2", 447 }, 448 { 449 Path: "http://localhost:8080/fixed/1/fixed/2/fixed", 450 Body: "three:,1,2", 451 }, 452 { 453 Path: "http://localhost:8080/fixed/1/fixed/2/fixed/3", 454 Body: "three:1,2,3", 455 }, 456 { 457 Path: "http://localhost:8080/fixed/1/fixed/2/fixed/3/fixed", 458 StatusCode: http.StatusNotFound, 459 Body: "404 page not found\n", 460 }, 461 }) 462 r.Shutdown(context.Background()) 463 <-time.After(time.Millisecond * 200) 464 } 465 466 func TestRegExParamRoute(t *testing.T) { 467 assert := assert.New(t) 468 r := New() 469 r.Rule("a", "[A-Za-z]+") 470 r.Get("/", func(w http.ResponseWriter, r *http.Request) { 471 w.Write([]byte("Root")) 472 }) 473 r.Get("/{i:one}", func(w http.ResponseWriter, r *http.Request) { 474 w.Write([]byte("i|one:" + varsToString(Vars(r)))) 475 }) 476 r.Get("/{a:one}", func(w http.ResponseWriter, r *http.Request) { 477 w.Write([]byte("a|one:" + varsToString(Vars(r)))) 478 }) 479 r.Get("/{i:one}/{i:two}", func(w http.ResponseWriter, r *http.Request) { 480 w.Write([]byte("i|two:" + varsToString(Vars(r)))) 481 }) 482 r.Get("/{i:one}/{a:two}", func(w http.ResponseWriter, r *http.Request) { 483 w.Write([]byte("a|two:" + varsToString(Vars(r)))) 484 }) 485 r.Get("/{i:one}/{a:two}/{i:three}", func(w http.ResponseWriter, r *http.Request) { 486 w.Write([]byte("i|three:" + varsToString(Vars(r)))) 487 }) 488 r.Get("/{i:one}/{a:two}/{a:three}", func(w http.ResponseWriter, r *http.Request) { 489 w.Write([]byte("a|three:" + varsToString(Vars(r)))) 490 }) 491 go func() { 492 err := r.Run() 493 if err != nil && err != http.ErrServerClosed { 494 assert.NoError(err) 495 } 496 }() 497 <-time.After(time.Millisecond * 200) 498 sendTestRequests(assert, []testRequest{ 499 { 500 Path: "http://localhost:8080/", 501 Body: "Root", 502 }, 503 { 504 Path: "http://localhost:8080/1", 505 Body: "i|one:1", 506 }, 507 { 508 Path: "http://localhost:8080/a", 509 Body: "a|one:a", 510 }, 511 { 512 Path: "http://localhost:8080/1/2", 513 Body: "i|two:1,2", 514 }, 515 { 516 Path: "http://localhost:8080/1/b", 517 Body: "a|two:1,b", 518 }, 519 { 520 Path: "http://localhost:8080/1/b/3", 521 Body: "i|three:1,3,b", 522 }, 523 { 524 Path: "http://localhost:8080/1/b/c", 525 Body: "a|three:1,b,c", 526 }, 527 { 528 Path: "http://localhost:8080/測試", 529 StatusCode: http.StatusNotFound, 530 Body: "404 page not found\n", 531 }, 532 { 533 Path: "http://localhost:8080/a/2", 534 StatusCode: http.StatusNotFound, 535 Body: "404 page not found\n", 536 }, 537 }) 538 r.Shutdown(context.Background()) 539 <-time.After(time.Millisecond * 200) 540 } 541 542 func TestOptionalRegExParamRoute(t *testing.T) { 543 assert := assert.New(t) 544 r := New() 545 r.Get("/{i:one?}", func(w http.ResponseWriter, r *http.Request) { 546 w.Write([]byte("one:" + varsToString(Vars(r)))) 547 }) 548 r.Get("/{i:one}/{i:two?}", func(w http.ResponseWriter, r *http.Request) { 549 w.Write([]byte("two:" + varsToString(Vars(r)))) 550 }) 551 r.Get("/{i:one}/{i:two}/{i:three?}", func(w http.ResponseWriter, r *http.Request) { 552 w.Write([]byte("three:" + varsToString(Vars(r)))) 553 }) 554 go func() { 555 err := r.Run() 556 if err != nil && err != http.ErrServerClosed { 557 assert.NoError(err) 558 } 559 }() 560 <-time.After(time.Millisecond * 200) 561 sendTestRequests(assert, []testRequest{ 562 { 563 Path: "http://localhost:8080/", 564 Body: "one:", 565 }, 566 { 567 Path: "http://localhost:8080/1", 568 Body: "two:,1", 569 }, 570 { 571 Path: "http://localhost:8080/1/2", 572 Body: "three:,1,2", 573 }, 574 { 575 Path: "http://localhost:8080/1/2/3", 576 Body: "three:1,2,3", 577 }, 578 { 579 Path: "http://localhost:8080/a", 580 StatusCode: http.StatusNotFound, 581 Body: "404 page not found\n", 582 }, 583 { 584 Path: "http://localhost:8080/a/2", 585 StatusCode: http.StatusNotFound, 586 Body: "404 page not found\n", 587 }, 588 { 589 Path: "http://localhost:8080/a/b/3", 590 StatusCode: http.StatusNotFound, 591 Body: "404 page not found\n", 592 }, 593 { 594 Path: "http://localhost:8080/a/b/c/d", 595 StatusCode: http.StatusNotFound, 596 Body: "404 page not found\n", 597 }, 598 }) 599 r.Shutdown(context.Background()) 600 <-time.After(time.Millisecond * 200) 601 } 602 603 func TestAnyRegExParamRoute(t *testing.T) { 604 assert := assert.New(t) 605 r := New() 606 r.Get("/", func(w http.ResponseWriter, r *http.Request) { 607 w.Write([]byte("Root")) 608 }) 609 r.Get("/{*:one}", func(w http.ResponseWriter, r *http.Request) { 610 w.Write([]byte("*|one:" + varsToString(Vars(r)))) 611 }) 612 r.Get("/two", func(w http.ResponseWriter, r *http.Request) { 613 w.Write([]byte("two:" + varsToString(Vars(r)))) 614 }) 615 r.Get("/two/{*:three}", func(w http.ResponseWriter, r *http.Request) { 616 w.Write([]byte("two,*|three:" + varsToString(Vars(r)))) 617 }) 618 r.Get("/{one}/two/{*:three}", func(w http.ResponseWriter, r *http.Request) { 619 w.Write([]byte("*|three:" + varsToString(Vars(r)))) 620 }) 621 r.Get("/{one}/two/three/four/{*:five?}", func(w http.ResponseWriter, r *http.Request) { 622 w.Write([]byte("*|five:" + varsToString(Vars(r)))) 623 }) 624 go func() { 625 err := r.Run() 626 if err != nil && err != http.ErrServerClosed { 627 assert.NoError(err) 628 } 629 }() 630 <-time.After(time.Millisecond * 200) 631 sendTestRequests(assert, []testRequest{ 632 { 633 Path: "http://localhost:8080/", 634 Body: "Root", 635 }, 636 { 637 Path: "http://localhost:8080/one", 638 Body: "*|one:one", 639 }, 640 { 641 Path: "http://localhost:8080/two", 642 Body: "two:", 643 }, 644 { 645 Path: "http://localhost:8080/two/three", 646 Body: "two,*|three:three", 647 }, 648 { 649 Path: "http://localhost:8080/one/two/three", 650 Body: "*|three:one,three", 651 }, 652 { 653 Path: "http://localhost:8080/one/two/three/three/three", 654 Body: "*|three:one,three/three/three", 655 }, 656 { 657 Path: "http://localhost:8080/one/two/three/four", 658 Body: "*|five:,one", 659 }, 660 { 661 Path: "http://localhost:8080/1/two/three/four/5", 662 Body: "*|five:1,5", 663 }, 664 { 665 Path: "http://localhost:8080/1/two/three/four/5/6", 666 Body: "*|five:1,5/6", 667 }, 668 }) 669 r.Shutdown(context.Background()) 670 <-time.After(time.Millisecond * 200) 671 } 672 673 func TestPrefixSuffixRoute(t *testing.T) { 674 assert := assert.New(t) 675 r := New() 676 r.Get("/", func(w http.ResponseWriter, r *http.Request) { 677 w.Write([]byte("Root")) 678 }) 679 r.Get("/{one}.sub", func(w http.ResponseWriter, r *http.Request) { 680 w.Write([]byte(varsToString(Vars(r)))) 681 }) 682 r.Get("/pre.{one}.suf", func(w http.ResponseWriter, r *http.Request) { 683 w.Write([]byte(varsToString(Vars(r)))) 684 }) 685 r.Get("/pre.{one}.suf/pre.{two}.suf", func(w http.ResponseWriter, r *http.Request) { 686 w.Write([]byte(varsToString(Vars(r)))) 687 }) 688 go func() { 689 err := r.Run() 690 if err != nil && err != http.ErrServerClosed { 691 assert.NoError(err) 692 } 693 }() 694 <-time.After(time.Millisecond * 200) 695 sendTestRequests(assert, []testRequest{ 696 { 697 Path: "http://localhost:8080/", 698 Body: "Root", 699 }, 700 { 701 Path: "http://localhost:8080/1.sub", 702 Body: "1", 703 }, 704 { 705 Path: "http://localhost:8080/pre.1.suf", 706 Body: "1", 707 }, 708 { 709 Path: "http://localhost:8080/pre.1.suf/pre.2.suf", 710 Body: "1,2", 711 }, 712 { 713 Path: "http://localhost:8080/1", 714 StatusCode: http.StatusNotFound, 715 Body: "404 page not found\n", 716 }, 717 { 718 Path: "http://localhost:8080/.sub", 719 StatusCode: http.StatusNotFound, 720 Body: "404 page not found\n", 721 }, 722 { 723 Path: "http://localhost:8080/pre..suf", 724 StatusCode: http.StatusNotFound, 725 Body: "404 page not found\n", 726 }, 727 { 728 Path: "http://localhost:8080/pre..suf/pre.1.suf", 729 StatusCode: http.StatusNotFound, 730 Body: "404 page not found\n", 731 }, 732 { 733 Path: "http://localhost:8080/pre..suf/pre..suf", 734 StatusCode: http.StatusNotFound, 735 Body: "404 page not found\n", 736 }, 737 }) 738 r.Shutdown(context.Background()) 739 <-time.After(time.Millisecond * 200) 740 } 741 742 func TestOptionalPrefixSuffixRoute(t *testing.T) { 743 assert := assert.New(t) 744 r := New() 745 r.Get("/", func(w http.ResponseWriter, r *http.Request) { 746 w.Write([]byte("Root")) 747 }) 748 r.Get("/{one?}.sub", func(w http.ResponseWriter, r *http.Request) { 749 w.Write([]byte(varsToString(Vars(r)))) 750 }) 751 r.Get("/pre.{one?}.suf", func(w http.ResponseWriter, r *http.Request) { 752 w.Write([]byte(varsToString(Vars(r)))) 753 }) 754 r.Get("/pre.{one?}.suf/pre.{two?}.suf", func(w http.ResponseWriter, r *http.Request) { 755 w.Write([]byte(varsToString(Vars(r)))) 756 }) 757 r.Get("/pre.{one}.suf/pre.{two}.suf/pre.{three}.suf/pre.{four?}.suf", func(w http.ResponseWriter, r *http.Request) { 758 w.Write([]byte(varsToString(Vars(r)))) 759 }) 760 go func() { 761 err := r.Run() 762 if err != nil && err != http.ErrServerClosed { 763 assert.NoError(err) 764 } 765 }() 766 <-time.After(time.Millisecond * 200) 767 sendTestRequests(assert, []testRequest{ 768 { 769 Path: "http://localhost:8080/", 770 Body: "Root", 771 }, 772 { 773 Path: "http://localhost:8080/1.sub", 774 Body: "1", 775 }, 776 { 777 Path: "http://localhost:8080/.sub", 778 Body: "", 779 }, 780 { 781 Path: "http://localhost:8080/pre.1.suf", 782 Body: ",1", 783 }, 784 { 785 Path: "http://localhost:8080/pre..suf", 786 Body: "", 787 }, 788 { 789 Path: "http://localhost:8080/pre.1.suf/pre.2.suf", 790 Body: "1,2", 791 }, 792 { 793 Path: "http://localhost:8080/pre..suf/pre..suf", 794 Body: ",", 795 }, 796 { 797 Path: "http://localhost:8080/pre.1.suf/pre.2.suf/pre.3.suf/pre..suf", 798 Body: ",1,2,3", 799 }, 800 { 801 Path: "http://localhost:8080/pre.1.suf/pre.2.suf/pre.3.suf/pre.4.suf", 802 Body: "1,2,3,4", 803 }, 804 { 805 Path: "http://localhost:8080/1", 806 StatusCode: http.StatusNotFound, 807 Body: "404 page not found\n", 808 }, 809 { 810 Path: "http://localhost:8080/1/2", 811 StatusCode: http.StatusNotFound, 812 Body: "404 page not found\n", 813 }, 814 { 815 Path: "http://localhost:8080/pre.1", 816 StatusCode: http.StatusNotFound, 817 Body: "404 page not found\n", 818 }, 819 { 820 Path: "http://localhost:8080/pre.1/pre.2.suf", 821 StatusCode: http.StatusNotFound, 822 Body: "404 page not found\n", 823 }, 824 }) 825 r.Shutdown(context.Background()) 826 <-time.After(time.Millisecond * 200) 827 } 828 829 func TestPrefixSuffixRegExRoute(t *testing.T) { 830 assert := assert.New(t) 831 r := New() 832 r.Rule("a", "[A-Za-z]+") 833 r.Get("/", func(w http.ResponseWriter, r *http.Request) { 834 w.Write([]byte("Root")) 835 }) 836 r.Get("/{a:one?}.sub", func(w http.ResponseWriter, r *http.Request) { 837 w.Write([]byte(varsToString(Vars(r)))) 838 }) 839 r.Get("/pre.{a:one?}.suf", func(w http.ResponseWriter, r *http.Request) { 840 w.Write([]byte(varsToString(Vars(r)))) 841 }) 842 r.Get("/foo.{a:one}.bar", func(w http.ResponseWriter, r *http.Request) { 843 w.Write([]byte(varsToString(Vars(r)))) 844 }) 845 go func() { 846 err := r.Run() 847 if err != nil && err != http.ErrServerClosed { 848 assert.NoError(err) 849 } 850 }() 851 <-time.After(time.Millisecond * 200) 852 sendTestRequests(assert, []testRequest{ 853 { 854 Path: "http://localhost:8080/", 855 Body: "Root", 856 }, 857 { 858 Path: "http://localhost:8080/a.sub", 859 Body: "a", 860 }, 861 { 862 Path: "http://localhost:8080/.sub", 863 Body: "", 864 }, 865 { 866 Path: "http://localhost:8080/pre.a.suf", 867 Body: "a", 868 }, 869 { 870 Path: "http://localhost:8080/pre..suf", 871 Body: "", 872 }, 873 { 874 Path: "http://localhost:8080/foo.a.bar", 875 Body: "a", 876 }, 877 { 878 Path: "http://localhost:8080/1", 879 StatusCode: http.StatusNotFound, 880 Body: "404 page not found\n", 881 }, 882 { 883 Path: "http://localhost:8080/1.sub", 884 StatusCode: http.StatusNotFound, 885 Body: "404 page not found\n", 886 }, 887 { 888 Path: "http://localhost:8080/pre.1.suf", 889 StatusCode: http.StatusNotFound, 890 Body: "404 page not found\n", 891 }, 892 { 893 Path: "http://localhost:8080/foo..bar", 894 StatusCode: http.StatusNotFound, 895 Body: "404 page not found\n", 896 }, 897 { 898 Path: "http://localhost:8080/foo.1.bar", 899 StatusCode: http.StatusNotFound, 900 Body: "404 page not found\n", 901 }, 902 }) 903 r.Shutdown(context.Background()) 904 <-time.After(time.Millisecond * 200) 905 } 906 907 func TestLookbehindRoute(t *testing.T) { 908 assert := assert.New(t) 909 r := New() 910 r.Get("/", func(w http.ResponseWriter, r *http.Request) { 911 w.Write([]byte("Root")) 912 }) 913 r.Rule("e", "(?:.html)") 914 r.Get("/detail{e:one}", func(w http.ResponseWriter, r *http.Request) { 915 w.Write([]byte(varsToString(Vars(r)))) 916 }) 917 r.Rule("u", "(?:.html)?") 918 r.Get("/user{u:one}", func(w http.ResponseWriter, r *http.Request) { 919 w.Write([]byte(varsToString(Vars(r)))) 920 }) 921 go func() { 922 err := r.Run() 923 if err != nil && err != http.ErrServerClosed { 924 assert.NoError(err) 925 } 926 }() 927 <-time.After(time.Millisecond * 200) 928 sendTestRequests(assert, []testRequest{ 929 { 930 Path: "http://localhost:8080/", 931 Body: "Root", 932 }, 933 { 934 Path: "http://localhost:8080/detail.html", 935 Body: ".html", 936 }, 937 { 938 Path: "http://localhost:8080/user", 939 Body: "", 940 }, 941 { 942 Path: "http://localhost:8080/user.html", 943 Body: ".html", 944 }, 945 { 946 Path: "http://localhost:8080/detail", 947 StatusCode: http.StatusNotFound, 948 Body: "404 page not found\n", 949 }, 950 { 951 Path: "http://localhost:8080/user.htmli", 952 StatusCode: http.StatusNotFound, 953 Body: "404 page not found\n", 954 }, 955 { 956 Path: "http://localhost:8080/user.htm", 957 StatusCode: http.StatusNotFound, 958 Body: "404 page not found\n", 959 }, 960 }) 961 r.Shutdown(context.Background()) 962 <-time.After(time.Millisecond * 200) 963 } 964 func TestMiddleware(t *testing.T) { 965 assert := assert.New(t) 966 r := New() 967 middleware := func(next http.Handler) http.Handler { 968 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 969 rcontext.Set(r, "foo1", "bar1") 970 next.ServeHTTP(w, r) 971 }) 972 } 973 middleware2 := func(next http.Handler) http.Handler { 974 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 975 rcontext.Set(r, "foo2", "bar2") 976 next.ServeHTTP(w, r) 977 }) 978 } 979 r.Get("/", middleware, middleware2, func(w http.ResponseWriter, r *http.Request) { 980 w.Write([]byte(rcontext.Get(r, "foo1").(string) + rcontext.Get(r, "foo2").(string))) 981 }) 982 go func() { 983 err := r.Run() 984 if err != nil && err != http.ErrServerClosed { 985 assert.NoError(err) 986 } 987 }() 988 <-time.After(time.Millisecond * 200) 989 sendTestRequests(assert, []testRequest{ 990 { 991 Path: "http://localhost:8080/", 992 Body: "bar1bar2", 993 }, 994 }) 995 r.Shutdown(context.Background()) 996 <-time.After(time.Millisecond * 200) 997 } 998 999 func TestRouteGroup(t *testing.T) { 1000 assert := assert.New(t) 1001 r := New() 1002 handler := func(w http.ResponseWriter, r *http.Request) { 1003 w.Write([]byte("OK")) 1004 } 1005 v1 := r.Group("/v1") 1006 { 1007 v1.Get("/", handler) 1008 v1.Get("/user/{id}", handler) 1009 v1.Get("/post/{title?}", handler) 1010 v1.Get("/login", handler) 1011 } 1012 v2 := r.Group("/v2") 1013 { 1014 v2.Get("/", handler) 1015 v2.Get("/user/{id}", handler) 1016 v2.Get("/post/{title?}", handler) 1017 v2.Get("/login", handler) 1018 } 1019 go func() { 1020 err := r.Run() 1021 if err != nil && err != http.ErrServerClosed { 1022 assert.NoError(err) 1023 } 1024 }() 1025 <-time.After(time.Millisecond * 200) 1026 sendTestRequests(assert, []testRequest{ 1027 { 1028 Path: "http://localhost:8080/v1/user/123", 1029 Body: "OK", 1030 }, 1031 { 1032 Path: "http://localhost:8080/v1", 1033 Body: "OK", 1034 }, 1035 { 1036 Path: "http://localhost:8080/v1/post", 1037 Body: "OK", 1038 }, 1039 { 1040 Path: "http://localhost:8080/v1/post/1234", 1041 Body: "OK", 1042 }, 1043 { 1044 Path: "http://localhost:8080/v1/login", 1045 Body: "OK", 1046 }, 1047 { 1048 Path: "http://localhost:8080/v2/user/123", 1049 Body: "OK", 1050 }, 1051 { 1052 Path: "http://localhost:8080/v2", 1053 Body: "OK", 1054 }, 1055 { 1056 Path: "http://localhost:8080/v2/post", 1057 Body: "OK", 1058 }, 1059 { 1060 Path: "http://localhost:8080/v2/post/1234", 1061 Body: "OK", 1062 }, 1063 { 1064 Path: "http://localhost:8080/v2/login", 1065 Body: "OK", 1066 }, 1067 { 1068 Path: "http://localhost:8080/v1/user", 1069 StatusCode: http.StatusNotFound, 1070 Body: "404 page not found\n", 1071 }, 1072 { 1073 Path: "http://localhost:8080/v1/post/123/456", 1074 StatusCode: http.StatusNotFound, 1075 Body: "404 page not found\n", 1076 }, 1077 }) 1078 r.Shutdown(context.Background()) 1079 <-time.After(time.Millisecond * 200) 1080 } 1081 1082 func TestRouteGroupMiddleware(t *testing.T) { 1083 assert := assert.New(t) 1084 r := New() 1085 handler := func(w http.ResponseWriter, r *http.Request) { 1086 w.Write([]byte(rcontext.Get(r, "foo1").(string) + rcontext.Get(r, "foo2").(string) + rcontext.Get(r, "foo3").(string))) 1087 } 1088 middleware := func(next http.Handler) http.Handler { 1089 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 1090 rcontext.Set(r, "foo1", "bar1") 1091 next.ServeHTTP(w, r) 1092 }) 1093 } 1094 middleware2 := func(next http.Handler) http.Handler { 1095 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 1096 rcontext.Set(r, "foo2", "bar2") 1097 next.ServeHTTP(w, r) 1098 }) 1099 } 1100 middleware3 := func(next http.Handler) http.Handler { 1101 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 1102 rcontext.Set(r, "foo3", "bar3") 1103 next.ServeHTTP(w, r) 1104 }) 1105 } 1106 v1 := r.Group("/v1", middleware, middleware2) 1107 { 1108 v1.Get("/user/{id}", middleware3, handler) 1109 v1.Get("/post/{title?}", middleware3, handler) 1110 v1.Get("/login", middleware3, handler) 1111 } 1112 go func() { 1113 err := r.Run() 1114 if err != nil && err != http.ErrServerClosed { 1115 assert.NoError(err) 1116 } 1117 }() 1118 <-time.After(time.Millisecond * 200) 1119 sendTestRequests(assert, []testRequest{ 1120 { 1121 Path: "http://localhost:8080/v1/user/123", 1122 Body: "bar1bar2bar3", 1123 }, 1124 { 1125 Path: "http://localhost:8080/v1/post", 1126 Body: "bar1bar2bar3", 1127 }, 1128 { 1129 Path: "http://localhost:8080/v1/post/1234", 1130 Body: "bar1bar2bar3", 1131 }, 1132 { 1133 Path: "http://localhost:8080/v1/login", 1134 Body: "bar1bar2bar3", 1135 }, 1136 }) 1137 r.Shutdown(context.Background()) 1138 <-time.After(time.Millisecond * 200) 1139 } 1140 1141 func TestGlobalMiddleware(t *testing.T) { 1142 assert := assert.New(t) 1143 r := New() 1144 handler := func(w http.ResponseWriter, r *http.Request) { 1145 w.Write([]byte(rcontext.Get(r, "foo1").(string) + rcontext.Get(r, "foo2").(string) + rcontext.Get(r, "foo3").(string))) 1146 } 1147 middleware := func(next http.Handler) http.Handler { 1148 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 1149 rcontext.Set(r, "foo1", "bar1") 1150 next.ServeHTTP(w, r) 1151 }) 1152 } 1153 middleware2 := func(next http.Handler) http.Handler { 1154 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 1155 rcontext.Set(r, "foo2", "bar2") 1156 next.ServeHTTP(w, r) 1157 }) 1158 } 1159 middleware3 := func(next http.Handler) http.Handler { 1160 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 1161 rcontext.Set(r, "foo3", "bar3") 1162 next.ServeHTTP(w, r) 1163 }) 1164 } 1165 r.Use(middleware) 1166 r.Get("/", middleware2, middleware3, handler) 1167 v1 := r.Group("/foo", middleware2) 1168 { 1169 v1.Get("/bar", middleware3, handler) 1170 } 1171 go func() { 1172 err := r.Run() 1173 if err != nil && err != http.ErrServerClosed { 1174 assert.NoError(err) 1175 } 1176 }() 1177 <-time.After(time.Millisecond * 200) 1178 sendTestRequests(assert, []testRequest{ 1179 { 1180 Path: "http://localhost:8080/", 1181 Body: "bar1bar2bar3", 1182 }, 1183 { 1184 Path: "http://localhost:8080/foo/bar", 1185 Body: "bar1bar2bar3", 1186 }, 1187 }) 1188 r.Shutdown(context.Background()) 1189 <-time.After(time.Millisecond * 200) 1190 } 1191 1192 func TestGenerateRoute(t *testing.T) { 1193 assert := assert.New(t) 1194 r := New() 1195 r.Get("/one", func(w http.ResponseWriter, r *http.Request) {}).Name("One") 1196 r.Get("/one/two", func(w http.ResponseWriter, r *http.Request) {}).Name("Two") 1197 r.Get("/one/two/{three}", func(w http.ResponseWriter, r *http.Request) {}).Name("Three") 1198 r.Get("/one/two/{three}/{four}", func(w http.ResponseWriter, r *http.Request) {}).Name("Four") 1199 r.Get("/one/two/{three}/{four}/{five?}", func(w http.ResponseWriter, r *http.Request) {}).Name("Five") 1200 r.Get("/one/two/{three}/{four}/{five?}/{s:six}", func(w http.ResponseWriter, r *http.Request) {}).Name("Six") 1201 go func() { 1202 err := r.Run() 1203 if err != nil && err != http.ErrServerClosed { 1204 assert.NoError(err) 1205 } 1206 }() 1207 <-time.After(time.Millisecond * 200) 1208 sendTestRequests(assert, []testRequest{ 1209 { 1210 Path: "http://localhost:8080/one", 1211 Body: "", 1212 }, 1213 }) 1214 assert.Equal("/one", r.Generate("One")) 1215 assert.Equal("/one/two", r.Generate("Two")) 1216 assert.Panics(func() { 1217 r.Generate("Three") 1218 }) 1219 assert.Equal("/one/two/1", r.Generate("Three", map[string]string{ 1220 "three": "1", 1221 })) 1222 assert.Equal("/one/two/1/2", r.Generate("Four", map[string]string{ 1223 "three": "1", 1224 "four": "2", 1225 })) 1226 assert.Panics(func() { 1227 r.Generate("Five") 1228 }) 1229 assert.Panics(func() { 1230 r.Generate("Five", map[string]string{ 1231 "three": "1", 1232 }) 1233 }) 1234 assert.Panics(func() { 1235 r.Generate("Five", map[string]string{ 1236 "three": "1", 1237 "four": "2", 1238 }) 1239 }) 1240 assert.Equal("/one/two/1/2/3", r.Generate("Five", map[string]string{ 1241 "three": "1", 1242 "four": "2", 1243 "five": "3", 1244 })) 1245 assert.Equal("/one/two/1/2/3/4", r.Generate("Six", map[string]string{ 1246 "three": "1", 1247 "four": "2", 1248 "five": "3", 1249 "six": "4", 1250 })) 1251 r.Shutdown(context.Background()) 1252 <-time.After(time.Millisecond * 200) 1253 } 1254 1255 func TestStaticDirRoute(t *testing.T) { 1256 assert := assert.New(t) 1257 r := New() 1258 f, err := filepath.Abs(".") 1259 assert.NoError(err) 1260 assert.NoError(os.Chdir(f)) 1261 r.Get("/{*:filename}", http.FileServer(http.Dir("test"))) 1262 r.Get("/static/{*:filename}", http.StripPrefix("/static", http.FileServer(http.Dir("test")))) 1263 r.Get("/prefix/{*:filename}", http.StripPrefix("/prefix", http.FileServer(http.Dir(".")))) 1264 go func() { 1265 err := r.Run() 1266 if err != nil && err != http.ErrServerClosed { 1267 assert.NoError(err) 1268 } 1269 }() 1270 <-time.After(time.Millisecond * 200) 1271 sendTestRequests(assert, []testRequest{ 1272 { 1273 Path: "http://localhost:8080/file.txt", 1274 Body: "This is file.txt.", 1275 }, 1276 { 1277 Path: "http://localhost:8080/file.txt/", 1278 Body: "This is file.txt.", 1279 }, 1280 { 1281 Path: "http://localhost:8080/directory/file.txt", 1282 Body: "This is directory/file.txt.", 1283 }, 1284 { 1285 Path: "http://localhost:8080/directory/file.txt/", 1286 Body: "This is directory/file.txt.", 1287 }, 1288 { 1289 Path: "http://localhost:8080/static/file.txt", 1290 Body: "This is file.txt.", 1291 }, 1292 { 1293 Path: "http://localhost:8080/static/file.txt/", 1294 Body: "This is file.txt.", 1295 }, 1296 { 1297 Path: "http://localhost:8080/static/directory/file.txt", 1298 Body: "This is directory/file.txt.", 1299 }, 1300 { 1301 Path: "http://localhost:8080/static/directory/file.txt/", 1302 Body: "This is directory/file.txt.", 1303 }, 1304 { 1305 Path: "http://localhost:8080/prefix/test/file.txt", 1306 Body: "This is file.txt.", 1307 }, 1308 { 1309 Path: "http://localhost:8080/prefix/test/file.txt/", 1310 Body: "This is file.txt.", 1311 }, 1312 { 1313 Path: "http://localhost:8080/prefix/test/directory/file.txt", 1314 Body: "This is directory/file.txt.", 1315 }, 1316 { 1317 Path: "http://localhost:8080/prefix/test/directory/file.txt/", 1318 Body: "This is directory/file.txt.", 1319 }, 1320 { 1321 Path: "http://localhost:8080", 1322 Body: "<pre>\n<a href=\"directory/\">directory/</a>\n<a href=\"file.txt\">file.txt</a>\n<a href=\"main.go\">main.go</a>\n</pre>\n", 1323 }, 1324 { 1325 Path: "http://localhost:8080/", 1326 Body: "<pre>\n<a href=\"directory/\">directory/</a>\n<a href=\"file.txt\">file.txt</a>\n<a href=\"main.go\">main.go</a>\n</pre>\n", 1327 }, 1328 { 1329 Path: "http://localhost:8080/static", 1330 Body: "<pre>\n<a href=\"directory/\">directory/</a>\n<a href=\"file.txt\">file.txt</a>\n<a href=\"main.go\">main.go</a>\n</pre>\n", 1331 }, 1332 { 1333 Path: "http://localhost:8080/static/", 1334 Body: "<pre>\n<a href=\"directory/\">directory/</a>\n<a href=\"file.txt\">file.txt</a>\n<a href=\"main.go\">main.go</a>\n</pre>\n", 1335 }, 1336 { 1337 Path: "http://localhost:8080/prefix/test", 1338 Body: "<pre>\n<a href=\"directory/\">directory/</a>\n<a href=\"file.txt\">file.txt</a>\n<a href=\"main.go\">main.go</a>\n</pre>\n", 1339 }, 1340 { 1341 Path: "http://localhost:8080/prefix/test/", 1342 Body: "<pre>\n<a href=\"directory/\">directory/</a>\n<a href=\"file.txt\">file.txt</a>\n<a href=\"main.go\">main.go</a>\n</pre>\n", 1343 }, 1344 { 1345 Path: "http://localhost:8080/wow.txt", 1346 StatusCode: http.StatusNotFound, 1347 Body: "404 page not found\n", 1348 }, 1349 }) 1350 r.Shutdown(context.Background()) 1351 <-time.After(time.Millisecond * 200) 1352 } 1353 1354 func TestServeFilesDirRoute(t *testing.T) { 1355 assert := assert.New(t) 1356 r := New() 1357 f, err := filepath.Abs(".") 1358 assert.NoError(err) 1359 assert.NoError(os.Chdir(f)) 1360 r.ServeFiles("/", http.Dir("test")) 1361 r.ServeFiles("/static", http.Dir("test")) 1362 r.ServeFiles("/prefix", http.Dir(".")) 1363 go func() { 1364 err := r.Run() 1365 if err != nil && err != http.ErrServerClosed { 1366 assert.NoError(err) 1367 } 1368 }() 1369 <-time.After(time.Millisecond * 200) 1370 sendTestRequests(assert, []testRequest{ 1371 { 1372 Path: "http://localhost:8080/file.txt", 1373 Body: "This is file.txt.", 1374 }, 1375 { 1376 Path: "http://localhost:8080/file.txt/", 1377 Body: "This is file.txt.", 1378 }, 1379 { 1380 Path: "http://localhost:8080/directory/file.txt", 1381 Body: "This is directory/file.txt.", 1382 }, 1383 { 1384 Path: "http://localhost:8080/directory/file.txt/", 1385 Body: "This is directory/file.txt.", 1386 }, 1387 { 1388 Path: "http://localhost:8080/static/file.txt", 1389 Body: "This is file.txt.", 1390 }, 1391 { 1392 Path: "http://localhost:8080/static/file.txt/", 1393 Body: "This is file.txt.", 1394 }, 1395 { 1396 Path: "http://localhost:8080/static/directory/file.txt", 1397 Body: "This is directory/file.txt.", 1398 }, 1399 { 1400 Path: "http://localhost:8080/static/directory/file.txt/", 1401 Body: "This is directory/file.txt.", 1402 }, 1403 { 1404 Path: "http://localhost:8080/prefix/test/file.txt", 1405 Body: "This is file.txt.", 1406 }, 1407 { 1408 Path: "http://localhost:8080/prefix/test/file.txt/", 1409 Body: "This is file.txt.", 1410 }, 1411 { 1412 Path: "http://localhost:8080/prefix/test/directory/file.txt", 1413 Body: "This is directory/file.txt.", 1414 }, 1415 { 1416 Path: "http://localhost:8080/prefix/test/directory/file.txt/", 1417 Body: "This is directory/file.txt.", 1418 }, 1419 { 1420 Path: "http://localhost:8080", 1421 Body: "<pre>\n<a href=\"directory/\">directory/</a>\n<a href=\"file.txt\">file.txt</a>\n<a href=\"main.go\">main.go</a>\n</pre>\n", 1422 }, 1423 { 1424 Path: "http://localhost:8080/", 1425 Body: "<pre>\n<a href=\"directory/\">directory/</a>\n<a href=\"file.txt\">file.txt</a>\n<a href=\"main.go\">main.go</a>\n</pre>\n", 1426 }, 1427 { 1428 Path: "http://localhost:8080/static", 1429 Body: "<pre>\n<a href=\"directory/\">directory/</a>\n<a href=\"file.txt\">file.txt</a>\n<a href=\"main.go\">main.go</a>\n</pre>\n", 1430 }, 1431 { 1432 Path: "http://localhost:8080/static/", 1433 Body: "<pre>\n<a href=\"directory/\">directory/</a>\n<a href=\"file.txt\">file.txt</a>\n<a href=\"main.go\">main.go</a>\n</pre>\n", 1434 }, 1435 { 1436 Path: "http://localhost:8080/prefix/test", 1437 Body: "<pre>\n<a href=\"directory/\">directory/</a>\n<a href=\"file.txt\">file.txt</a>\n<a href=\"main.go\">main.go</a>\n</pre>\n", 1438 }, 1439 { 1440 Path: "http://localhost:8080/prefix/test/", 1441 Body: "<pre>\n<a href=\"directory/\">directory/</a>\n<a href=\"file.txt\">file.txt</a>\n<a href=\"main.go\">main.go</a>\n</pre>\n", 1442 }, 1443 { 1444 Path: "http://localhost:8080/wow.txt", 1445 StatusCode: http.StatusNotFound, 1446 Body: "404 page not found\n", 1447 }, 1448 }) 1449 r.Shutdown(context.Background()) 1450 <-time.After(time.Millisecond * 200) 1451 } 1452 1453 func TestServeFilesRoute(t *testing.T) { 1454 assert := assert.New(t) 1455 r := New() 1456 f, err := filepath.Abs(".") 1457 assert.NoError(err) 1458 assert.NoError(os.Chdir(f)) 1459 r.ServeFiles("/", "test").DirectoryListing = true 1460 r.ServeFiles("/static", "test").DirectoryListing = true 1461 r.ServeFiles("/prefix", ".").DirectoryListing = true 1462 r.ServeFiles("/nolisting", "test") 1463 go func() { 1464 err := r.Run() 1465 if err != nil && err != http.ErrServerClosed { 1466 assert.NoError(err) 1467 } 1468 }() 1469 <-time.After(time.Millisecond * 200) 1470 sendTestRequests(assert, []testRequest{ 1471 { 1472 Path: "http://localhost:8080/file.txt", 1473 Body: "This is file.txt.", 1474 }, 1475 { 1476 Path: "http://localhost:8080/file.txt/", 1477 Body: "This is file.txt.", 1478 }, 1479 { 1480 Path: "http://localhost:8080/directory/file.txt", 1481 Body: "This is directory/file.txt.", 1482 }, 1483 { 1484 Path: "http://localhost:8080/directory/file.txt/", 1485 Body: "This is directory/file.txt.", 1486 }, 1487 { 1488 Path: "http://localhost:8080/static/file.txt", 1489 Body: "This is file.txt.", 1490 }, 1491 { 1492 Path: "http://localhost:8080/static/file.txt/", 1493 Body: "This is file.txt.", 1494 }, 1495 { 1496 Path: "http://localhost:8080/static/directory/file.txt", 1497 Body: "This is directory/file.txt.", 1498 }, 1499 { 1500 Path: "http://localhost:8080/static/directory/file.txt/", 1501 Body: "This is directory/file.txt.", 1502 }, 1503 { 1504 Path: "http://localhost:8080/prefix/test/file.txt", 1505 Body: "This is file.txt.", 1506 }, 1507 { 1508 Path: "http://localhost:8080/prefix/test/file.txt/", 1509 Body: "This is file.txt.", 1510 }, 1511 { 1512 Path: "http://localhost:8080/prefix/test/directory/file.txt", 1513 Body: "This is directory/file.txt.", 1514 }, 1515 { 1516 Path: "http://localhost:8080/prefix/test/directory/file.txt/", 1517 Body: "This is directory/file.txt.", 1518 }, 1519 { 1520 Path: "http://localhost:8080", 1521 Body: "<pre>\n<a href=\"directory/\">directory/</a>\n<a href=\"file.txt\">file.txt</a>\n<a href=\"main.go\">main.go</a>\n</pre>\n", 1522 }, 1523 { 1524 Path: "http://localhost:8080/", 1525 Body: "<pre>\n<a href=\"directory/\">directory/</a>\n<a href=\"file.txt\">file.txt</a>\n<a href=\"main.go\">main.go</a>\n</pre>\n", 1526 }, 1527 { 1528 Path: "http://localhost:8080/static", 1529 Body: "<pre>\n<a href=\"directory/\">directory/</a>\n<a href=\"file.txt\">file.txt</a>\n<a href=\"main.go\">main.go</a>\n</pre>\n", 1530 }, 1531 { 1532 Path: "http://localhost:8080/static/", 1533 Body: "<pre>\n<a href=\"directory/\">directory/</a>\n<a href=\"file.txt\">file.txt</a>\n<a href=\"main.go\">main.go</a>\n</pre>\n", 1534 }, 1535 { 1536 Path: "http://localhost:8080/prefix/test", 1537 Body: "<pre>\n<a href=\"directory/\">directory/</a>\n<a href=\"file.txt\">file.txt</a>\n<a href=\"main.go\">main.go</a>\n</pre>\n", 1538 }, 1539 { 1540 Path: "http://localhost:8080/prefix/test/", 1541 Body: "<pre>\n<a href=\"directory/\">directory/</a>\n<a href=\"file.txt\">file.txt</a>\n<a href=\"main.go\">main.go</a>\n</pre>\n", 1542 }, 1543 { 1544 Path: "http://localhost:8080/nolisting/file.txt", 1545 Body: "This is file.txt.", 1546 }, 1547 { 1548 Path: "http://localhost:8080/nolisting/directory/file.txt", 1549 Body: "This is directory/file.txt.", 1550 }, 1551 { 1552 Path: "http://localhost:8080/wow.txt", 1553 StatusCode: http.StatusNotFound, 1554 Body: "404 page not found\n", 1555 }, 1556 { 1557 Path: "http://localhost:8080/nolisting", 1558 StatusCode: http.StatusForbidden, 1559 Body: "", 1560 }, 1561 { 1562 Path: "http://localhost:8080/nolisting/", 1563 StatusCode: http.StatusForbidden, 1564 Body: "", 1565 }, 1566 { 1567 Path: "http://localhost:8080/nolisting/directory", 1568 StatusCode: http.StatusForbidden, 1569 Body: "", 1570 }, 1571 { 1572 Path: "http://localhost:8080/nolisting/directory/", 1573 StatusCode: http.StatusForbidden, 1574 Body: "", 1575 }, 1576 }) 1577 r.Shutdown(context.Background()) 1578 <-time.After(time.Millisecond * 200) 1579 } 1580 1581 func TestServeFileRoute(t *testing.T) { 1582 assert := assert.New(t) 1583 r := New() 1584 f, err := filepath.Abs(".") 1585 assert.NoError(err) 1586 assert.NoError(os.Chdir(f)) 1587 r.ServeFile("/one", "test/file.txt") 1588 r.ServeFile("/one/two", "test/directory/file.txt") 1589 go func() { 1590 err := r.Run() 1591 if err != nil && err != http.ErrServerClosed { 1592 assert.NoError(err) 1593 } 1594 }() 1595 <-time.After(time.Millisecond * 200) 1596 <-time.After(time.Millisecond * 200) 1597 sendTestRequests(assert, []testRequest{ 1598 { 1599 Path: "http://localhost:8080/one", 1600 Body: "This is file.txt.", 1601 }, 1602 { 1603 Path: "http://localhost:8080/one/", 1604 Body: "This is file.txt.", 1605 }, 1606 { 1607 Path: "http://localhost:8080/one//", 1608 Body: "This is file.txt.", 1609 }, 1610 { 1611 Path: "http://localhost:8080/one/two", 1612 Body: "This is directory/file.txt.", 1613 }, 1614 { 1615 Path: "http://localhost:8080/one/two/", 1616 Body: "This is directory/file.txt.", 1617 }, 1618 { 1619 Path: "http://localhost:8080/one/two//", 1620 Body: "This is directory/file.txt.", 1621 }, 1622 { 1623 Path: "http://localhost:8080/wow.txt", 1624 StatusCode: http.StatusNotFound, 1625 Body: "404 page not found\n", 1626 }, 1627 }) 1628 r.Shutdown(context.Background()) 1629 <-time.After(time.Millisecond * 200) 1630 } 1631 1632 func TestServeFilesAndStaticRoute(t *testing.T) { 1633 assert := assert.New(t) 1634 r := New() 1635 f, err := filepath.Abs(".") 1636 assert.NoError(err) 1637 assert.NoError(os.Chdir(f)) 1638 r.Get("/one", func(w http.ResponseWriter, r *http.Request) { 1639 w.Write([]byte("One")) 1640 }) 1641 r.Get("/{i:one}", func(w http.ResponseWriter, r *http.Request) { 1642 w.Write([]byte("{i:one}")) 1643 }) 1644 r.ServeFiles("/", http.Dir("test")) 1645 r.ServeFiles("/resource/static", http.Dir("test")) 1646 r.ServeFiles("/static", http.Dir("test")) 1647 r.ServeFiles("/prefix", http.Dir(".")) 1648 go func() { 1649 err := r.Run() 1650 if err != nil && err != http.ErrServerClosed { 1651 assert.NoError(err) 1652 } 1653 }() 1654 <-time.After(time.Millisecond * 200) 1655 sendTestRequests(assert, []testRequest{ 1656 { 1657 Path: "http://localhost:8080/one", 1658 Body: "One", 1659 }, 1660 { 1661 Path: "http://localhost:8080/123", 1662 Body: "{i:one}", 1663 }, 1664 { 1665 Path: "http://localhost:8080/file.txt", 1666 Body: "This is file.txt.", 1667 }, 1668 { 1669 Path: "http://localhost:8080/file.txt/", 1670 Body: "This is file.txt.", 1671 }, 1672 { 1673 Path: "http://localhost:8080/directory/file.txt", 1674 Body: "This is directory/file.txt.", 1675 }, 1676 { 1677 Path: "http://localhost:8080/directory/file.txt/", 1678 Body: "This is directory/file.txt.", 1679 }, 1680 { 1681 Path: "http://localhost:8080/static/file.txt", 1682 Body: "This is file.txt.", 1683 }, 1684 { 1685 Path: "http://localhost:8080/static/file.txt/", 1686 Body: "This is file.txt.", 1687 }, 1688 { 1689 Path: "http://localhost:8080/static/directory/file.txt", 1690 Body: "This is directory/file.txt.", 1691 }, 1692 { 1693 Path: "http://localhost:8080/static/directory/file.txt/", 1694 Body: "This is directory/file.txt.", 1695 }, 1696 { 1697 Path: "http://localhost:8080/prefix/test/file.txt", 1698 Body: "This is file.txt.", 1699 }, 1700 { 1701 Path: "http://localhost:8080/prefix/test/file.txt/", 1702 Body: "This is file.txt.", 1703 }, 1704 { 1705 Path: "http://localhost:8080/prefix/test/directory/file.txt", 1706 Body: "This is directory/file.txt.", 1707 }, 1708 { 1709 Path: "http://localhost:8080/prefix/test/directory/file.txt/", 1710 Body: "This is directory/file.txt.", 1711 }, 1712 { 1713 Path: "http://localhost:8080/resource/static/file.txt", 1714 Body: "This is file.txt.", 1715 }, 1716 { 1717 Path: "http://localhost:8080", 1718 Body: "<pre>\n<a href=\"directory/\">directory/</a>\n<a href=\"file.txt\">file.txt</a>\n<a href=\"main.go\">main.go</a>\n</pre>\n", 1719 }, 1720 { 1721 Path: "http://localhost:8080/", 1722 Body: "<pre>\n<a href=\"directory/\">directory/</a>\n<a href=\"file.txt\">file.txt</a>\n<a href=\"main.go\">main.go</a>\n</pre>\n", 1723 }, 1724 { 1725 Path: "http://localhost:8080/static", 1726 Body: "<pre>\n<a href=\"directory/\">directory/</a>\n<a href=\"file.txt\">file.txt</a>\n<a href=\"main.go\">main.go</a>\n</pre>\n", 1727 }, 1728 { 1729 Path: "http://localhost:8080/static/", 1730 Body: "<pre>\n<a href=\"directory/\">directory/</a>\n<a href=\"file.txt\">file.txt</a>\n<a href=\"main.go\">main.go</a>\n</pre>\n", 1731 }, 1732 { 1733 Path: "http://localhost:8080/prefix/test", 1734 Body: "<pre>\n<a href=\"directory/\">directory/</a>\n<a href=\"file.txt\">file.txt</a>\n<a href=\"main.go\">main.go</a>\n</pre>\n", 1735 }, 1736 { 1737 Path: "http://localhost:8080/prefix/test/", 1738 Body: "<pre>\n<a href=\"directory/\">directory/</a>\n<a href=\"file.txt\">file.txt</a>\n<a href=\"main.go\">main.go</a>\n</pre>\n", 1739 }, 1740 { 1741 Path: "http://localhost:8080/wow.txt", 1742 StatusCode: http.StatusNotFound, 1743 Body: "404 page not found\n", 1744 }, 1745 }) 1746 r.Shutdown(context.Background()) 1747 <-time.After(time.Millisecond * 200) 1748 } 1749 1750 func TestTrailingSlashesRoute(t *testing.T) { 1751 assert := assert.New(t) 1752 r := New() 1753 r.Get("/", func(w http.ResponseWriter, r *http.Request) { 1754 w.Write([]byte("Root")) 1755 }) 1756 r.Get("/one", func(w http.ResponseWriter, r *http.Request) { 1757 w.Write([]byte("One")) 1758 }) 1759 r.Get("/one/two", func(w http.ResponseWriter, r *http.Request) { 1760 w.Write([]byte("Two")) 1761 }) 1762 go func() { 1763 err := r.Run() 1764 if err != nil && err != http.ErrServerClosed { 1765 assert.NoError(err) 1766 } 1767 }() 1768 <-time.After(time.Millisecond * 200) 1769 sendTestRequests(assert, []testRequest{ 1770 { 1771 Path: "http://localhost:8080", 1772 Body: "Root", 1773 }, 1774 { 1775 Path: "http://localhost:8080/", 1776 Body: "Root", 1777 }, 1778 { 1779 Path: "http://localhost:8080/one", 1780 Body: "One", 1781 }, 1782 { 1783 Path: "http://localhost:8080/one/", 1784 Body: "One", 1785 }, 1786 { 1787 Path: "http://localhost:8080/one/two", 1788 Body: "Two", 1789 }, 1790 { 1791 Path: "http://localhost:8080/one/two/", 1792 Body: "Two", 1793 }, 1794 }) 1795 r.Shutdown(context.Background()) 1796 <-time.After(time.Millisecond * 200) 1797 }