tree_test.go 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. // Copyright 2014 Unknwon
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License"): you may
  4. // not use this file except in compliance with the License. You may obtain
  5. // a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  11. // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  12. // License for the specific language governing permissions and limitations
  13. // under the License.
  14. package macaron
  15. import (
  16. // "net/http"
  17. "strings"
  18. "testing"
  19. . "github.com/smartystreets/goconvey/convey"
  20. )
  21. func Test_splitSegment(t *testing.T) {
  22. type result struct {
  23. Ok bool
  24. Parts []string
  25. Regex string
  26. }
  27. cases := map[string]result{
  28. "admin": result{false, nil, ""},
  29. ":id": result{true, []string{":id"}, ""},
  30. "?:id": result{true, []string{":", ":id"}, ""},
  31. ":id:int": result{true, []string{":id"}, "([0-9]+)"},
  32. ":name:string": result{true, []string{":name"}, `([\w]+)`},
  33. ":id([0-9]+)": result{true, []string{":id"}, "([0-9]+)"},
  34. ":id([0-9]+)_:name": result{true, []string{":id", ":name"}, "([0-9]+)_(.+)"},
  35. "cms_:id_:page.html": result{true, []string{":id", ":page"}, "cms_(.+)_(.+).html"},
  36. "*": result{true, []string{":splat"}, ""},
  37. "*.*": result{true, []string{".", ":path", ":ext"}, ""},
  38. }
  39. Convey("Splits segment into parts", t, func() {
  40. for key, result := range cases {
  41. ok, parts, regex := splitSegment(key)
  42. So(ok, ShouldEqual, result.Ok)
  43. if result.Parts == nil {
  44. So(parts, ShouldBeNil)
  45. } else {
  46. So(parts, ShouldNotBeNil)
  47. So(strings.Join(parts, " "), ShouldEqual, strings.Join(result.Parts, " "))
  48. }
  49. So(regex, ShouldEqual, result.Regex)
  50. }
  51. })
  52. }
  53. func Test_Tree_Match(t *testing.T) {
  54. type result struct {
  55. pattern string
  56. reqUrl string
  57. params map[string]string
  58. }
  59. cases := []result{
  60. {"/:id", "/123", map[string]string{":id": "123"}},
  61. {"/hello/?:id", "/hello", map[string]string{":id": ""}},
  62. {"/", "/", nil},
  63. {"", "", nil},
  64. {"/customer/login", "/customer/login", nil},
  65. {"/customer/login", "/customer/login.json", map[string]string{":ext": "json"}},
  66. {"/*", "/customer/123", map[string]string{":splat": "customer/123"}},
  67. {"/*", "/customer/2009/12/11", map[string]string{":splat": "customer/2009/12/11"}},
  68. {"/aa/*/bb", "/aa/2009/bb", map[string]string{":splat": "2009"}},
  69. {"/cc/*/dd", "/cc/2009/11/dd", map[string]string{":splat": "2009/11"}},
  70. {"/ee/:year/*/ff", "/ee/2009/11/ff", map[string]string{":year": "2009", ":splat": "11"}},
  71. {"/thumbnail/:size/uploads/*", "/thumbnail/100x100/uploads/items/2014/04/20/dPRCdChkUd651t1Hvs18.jpg",
  72. map[string]string{":size": "100x100", ":splat": "items/2014/04/20/dPRCdChkUd651t1Hvs18.jpg"}},
  73. {"/*.*", "/nice/api.json", map[string]string{":path": "nice/api", ":ext": "json"}},
  74. {"/:name/*.*", "/nice/api.json", map[string]string{":name": "nice", ":path": "api", ":ext": "json"}},
  75. {"/:name/test/*.*", "/nice/test/api.json", map[string]string{":name": "nice", ":path": "api", ":ext": "json"}},
  76. {"/dl/:width:int/:height:int/*.*", "/dl/48/48/05ac66d9bda00a3acf948c43e306fc9a.jpg",
  77. map[string]string{":width": "48", ":height": "48", ":ext": "jpg", ":path": "05ac66d9bda00a3acf948c43e306fc9a"}},
  78. {"/v1/shop/:id:int", "/v1/shop/123", map[string]string{":id": "123"}},
  79. {"/:year:int/:month:int/:id/:endid", "/1111/111/aaa/aaa", map[string]string{":year": "1111", ":month": "111", ":id": "aaa", ":endid": "aaa"}},
  80. {"/v1/shop/:id/:name", "/v1/shop/123/nike", map[string]string{":id": "123", ":name": "nike"}},
  81. {"/v1/shop/:id/account", "/v1/shop/123/account", map[string]string{":id": "123"}},
  82. {"/v1/shop/:name:string", "/v1/shop/nike", map[string]string{":name": "nike"}},
  83. {"/v1/shop/:id([0-9]+)", "/v1/shop//123", map[string]string{":id": "123"}},
  84. {"/v1/shop/:id([0-9]+)_:name", "/v1/shop/123_nike", map[string]string{":id": "123", ":name": "nike"}},
  85. {"/v1/shop/:id(.+)_cms.html", "/v1/shop/123_cms.html", map[string]string{":id": "123"}},
  86. {"/v1/shop/cms_:id(.+)_:page(.+).html", "/v1/shop/cms_123_1.html", map[string]string{":id": "123", ":page": "1"}},
  87. {"/v1/:v/cms/aaa_:id(.+)_:page(.+).html", "/v1/2/cms/aaa_123_1.html", map[string]string{":v": "2", ":id": "123", ":page": "1"}},
  88. {"/v1/:v/cms_:id(.+)_:page(.+).html", "/v1/2/cms_123_1.html", map[string]string{":v": "2", ":id": "123", ":page": "1"}},
  89. {"/v1/:v(.+)_cms/ttt_:id(.+)_:page(.+).html", "/v1/2_cms/ttt_123_1.html", map[string]string{":v": "2", ":id": "123", ":page": "1"}},
  90. }
  91. Convey("Match routers in tree", t, func() {
  92. for _, c := range cases {
  93. t := NewTree()
  94. t.AddRouter(c.pattern, nil)
  95. _, params := t.Match(c.reqUrl)
  96. if params != nil {
  97. for k, v := range c.params {
  98. vv, ok := params[k]
  99. So(ok, ShouldBeTrue)
  100. So(vv, ShouldEqual, v)
  101. }
  102. }
  103. }
  104. })
  105. }