package mooh import ( "fmt" "net/http" "net/url" "regexp" "testing" ) func testRoute(req *Request) (Response, error) { resp := Response{} return resp, nil } func TestBasic(t *testing.T) { router := BuildDispatcher() 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 := BuildDispatcher() 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 := BuildDispatcher() 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.Path)) } } } func TestMatchOptional(t *testing.T) { router := BuildDispatcher() 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.Path)) } } } func TestAmbigiousSimple(t *testing.T) { router := BuildDispatcher() 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.Path)) } } func TestAmbigiousFail(t *testing.T) { router := BuildDispatcher() 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) }