package router import ( "fmt" "github.com/franckcuny/web-request" "net/http" "net/url" "regexp" "testing" ) func testRoute(req *request.Request, resp *request.Response) error { return nil } func TestBasic(t *testing.T) { router := BuildRouter() router.AddRoute(&Route{Method: "GET", Path: "/", Code: testRoute}) router.AddRoute(&Route{ Method: "GET", Path: "/blog/{year}/{month}/{day}", Code: testRoute, Validations: map[string]*regexp.Regexp{ "year": regexp.MustCompile("[\\d]{4}"), "month": regexp.MustCompile("[\\d]{2}"), "day": regexp.MustCompile("[\\d]{2}"), }, }) router.AddRoute(&Route{Method: "GET", Path: "/blog", Code: testRoute}) if router.routes[0].Path != "/" { t.Fatal() } if router.routes[1].Path != "/blog/{year}/{month}/{day}" { t.Fatal() } if router.routes[2].Path != "/blog" { t.Fatal() } } func TestWithSimleValidation(t *testing.T) { router := BuildRouter() router.AddRoute(&Route{ Path: "/users/{id}", Method: "GET", Code: testRoute, Validations: map[string]*regexp.Regexp{ "id": regexp.MustCompile("[\\d]{1}"), }, }) router.AddRoute(&Route{ Path: "/users/{name}", Method: "GET", Code: testRoute, Validations: map[string]*regexp.Regexp{ "name": regexp.MustCompile("[a-zA-Z]+"), }, }) r := &http.Request{Method: "GET", URL: &url.URL{Path: "/users/1"}} m, _ := router.Match(r) if m == nil { t.Fatal() } if m.Route.Path != "/users/{id}" { t.Fatal() } r = &http.Request{Method: "GET", URL: &url.URL{Path: "/users/foo"}} m, _ = router.Match(r) if m == nil { t.Fatal() } if m.Route.Path != "/users/{name}" { t.Fatal() } } func TestMatch(t *testing.T) { router := BuildRouter() router.AddRoute(&Route{ Method: "GET", Path: "/blog/{year}/{month}/{day}", Code: testRoute, Validations: map[string]*regexp.Regexp{ "year": regexp.MustCompile("[\\d]{4}"), "month": regexp.MustCompile("[\\d]{2}"), "day": regexp.MustCompile("[\\d]{2}"), }, }) router.AddRoute(&Route{Method: "GET", Path: "/blog", Code: testRoute}) pathToTests := []url.URL{ url.URL{Path: "/blog"}, url.URL{Path: "/blog"}, url.URL{Path: "/blog/2013/04/21"}, url.URL{Path: "/blog/2013/21/04"}, } for _, p := range pathToTests { r := &http.Request{URL: &p, Method: "GET"} m, _ := router.Match(r) if m == nil { t.Fatal() } else { fmt.Println(fmt.Sprintf("%s match for %s", p.Path, m.GetPath())) } } } func TestMatchOptional(t *testing.T) { router := BuildRouter() router.AddRoute(&Route{ Path: "/blog/?{year}", Method: "GET", Code: testRoute, Validations: map[string]*regexp.Regexp{ "year": regexp.MustCompile("[\\d]{4}"), }, }) router.AddRoute(&Route{ Path: "/blog/{year}/?{month}", Method: "GET", Code: testRoute, Validations: map[string]*regexp.Regexp{ "year": regexp.MustCompile("[\\d]{4}"), "month": regexp.MustCompile("[\\d]{2}"), }, }) pathToTests := []url.URL{ url.URL{Path: "/blog"}, url.URL{Path: "/blog"}, url.URL{Path: "/blog/2013"}, url.URL{Path: "/blog/2013/21"}, } for _, p := range pathToTests { r := &http.Request{URL: &p, Method: "GET"} m, _ := router.Match(r) if m == nil { t.Fatal() } else { fmt.Println(fmt.Sprintf("%s match for %s", p.Path, m.GetPath())) } } } func TestAmbigiousSimple(t *testing.T) { router := BuildRouter() router.AddRoute(&Route{Path: "/foo/bar", Method: "GET", Code: testRoute}) router.AddRoute(&Route{ Path: "/foo/{bar}", Method: "GET", Code: testRoute, Validations: map[string]*regexp.Regexp{ "bar": regexp.MustCompile("[a-zA-Z]{3}"), }, }) r := &http.Request{Method: "GET", URL: &url.URL{Path: "/foo/bar"}} m, _ := router.Match(r) if m == nil { t.Fatal() } else { fmt.Println(fmt.Sprintf("%s match for %s", r.URL.Path, m.GetPath())) } } func TestAmbigiousFail(t *testing.T) { router := BuildRouter() router.AddRoute(&Route{ Path: "/foo/{bar}", Method: "GET", Code: testRoute, Validations: map[string]*regexp.Regexp{ "bar": regexp.MustCompile("[a-zA-Z]{3}"), }, }) router.AddRoute(&Route{ Path: "/{foo}/bar", Method: "GET", Code: testRoute, Validations: map[string]*regexp.Regexp{ "foo": regexp.MustCompile("[a-zA-Z]{3}"), }, }) r := &http.Request{Method: "GET", URL: &url.URL{Path: "/foo/bar"}} m, err := router.Match(r) if m != nil { t.Fatal() } if err == nil { t.Fatal() } fmt.Println(err) } func TestWithDefaults(t *testing.T) { router := BuildRouter() router.AddRoute(&Route{ Path: "/foo/{bar}", Method: "GET", Code: testRoute, Defaults: map[string]string{ "bar": "baz", }, }) r := &http.Request{Method: "GET", URL: &url.URL{Path: "/foo/"}} m, err := router.Match(r) if m == nil { t.Fatal() } if err != nil { t.Fatal() } } func TestWithDefaultNoMatch(t *testing.T) { router := BuildRouter() router.AddRoute(&Route{ Path: "/foo/{bar}", Method: "GET", Code: testRoute, Defaults: map[string]string{ "bar": "baz", }, }) r := &http.Request{Method: "GET", URL: &url.URL{Path: "/foo"}} m, _ := router.Match(r) if m != nil { t.Fatal() } }