diff --git a/echo_test.go b/echo_test.go index 57c257b17..b7f32017a 100644 --- a/echo_test.go +++ b/echo_test.go @@ -1598,6 +1598,11 @@ func TestEchoReverse(t *testing.T) { whenParams []interface{} expect string }{ + { + name: "ok, not existing path returns empty url", + whenRouteName: "not-existing", + expect: "", + }, { name: "ok,static with no params", whenRouteName: "/static", diff --git a/router.go b/router.go index a3e258e49..03267315d 100644 --- a/router.go +++ b/router.go @@ -185,8 +185,18 @@ func (r *Router) Reverse(name string, params ...interface{}) string { return uri.String() } +func normalizePathSlash(path string) string { + if path == "" { + path = "/" + } else if path[0] != '/' { + path = "/" + path + } + return path +} + func (r *Router) add(method, path, name string, h HandlerFunc) *Route { - r.Add(method, path, h) + path = normalizePathSlash(path) + r.insert(method, path, h) route := &Route{ Method: method, @@ -199,13 +209,11 @@ func (r *Router) add(method, path, name string, h HandlerFunc) *Route { // Add registers a new route for method and path with matching handler. func (r *Router) Add(method, path string, h HandlerFunc) { - // Validate path - if path == "" { - path = "/" - } - if path[0] != '/' { - path = "/" + path - } + r.insert(method, normalizePathSlash(path), h) +} + +func (r *Router) insert(method, path string, h HandlerFunc) { + path = normalizePathSlash(path) pnames := []string{} // Param names ppath := path // Pristine path @@ -224,7 +232,7 @@ func (r *Router) Add(method, path string, h HandlerFunc) { } j := i + 1 - r.insert(method, path[:i], staticKind, routeMethod{}) + r.insertNode(method, path[:i], staticKind, routeMethod{}) for ; i < lcpIndex && path[i] != '/'; i++ { } @@ -234,21 +242,21 @@ func (r *Router) Add(method, path string, h HandlerFunc) { if i == lcpIndex { // path node is last fragment of route path. ie. `/users/:id` - r.insert(method, path[:i], paramKind, routeMethod{ppath, pnames, h}) + r.insertNode(method, path[:i], paramKind, routeMethod{ppath, pnames, h}) } else { - r.insert(method, path[:i], paramKind, routeMethod{}) + r.insertNode(method, path[:i], paramKind, routeMethod{}) } } else if path[i] == '*' { - r.insert(method, path[:i], staticKind, routeMethod{}) + r.insertNode(method, path[:i], staticKind, routeMethod{}) pnames = append(pnames, "*") - r.insert(method, path[:i+1], anyKind, routeMethod{ppath, pnames, h}) + r.insertNode(method, path[:i+1], anyKind, routeMethod{ppath, pnames, h}) } } - r.insert(method, path, staticKind, routeMethod{ppath, pnames, h}) + r.insertNode(method, path, staticKind, routeMethod{ppath, pnames, h}) } -func (r *Router) insert(method, path string, t kind, rm routeMethod) { +func (r *Router) insertNode(method, path string, t kind, rm routeMethod) { // Adjust max param paramLen := len(rm.pnames) if *r.echo.maxParam < paramLen { diff --git a/router_test.go b/router_test.go index 52d9a0abb..dca0d47bc 100644 --- a/router_test.go +++ b/router_test.go @@ -2770,6 +2770,22 @@ func TestRouter_Routes(t *testing.T) { } } +func TestRouter_addEmptyPathToSlashReverse(t *testing.T) { + e := New() + r := e.router + r.add(http.MethodGet, "", "empty", handlerFunc) // emtpy path is normalized to `/` + + assert.Equal(t, "/", r.Reverse("empty")) +} + +func TestRouter_ReverseNotFound(t *testing.T) { + e := New() + r := e.router + r.add(http.MethodGet, "", "empty", handlerFunc) + + assert.Equal(t, "", r.Reverse("not-existing")) +} + func TestRouter_Reverse(t *testing.T) { e := New() r := e.router