From 45dd7776938fddc914e8a2fe60367a3eb99e1e53 Mon Sep 17 00:00:00 2001 From: Manu Mtz-Almeida Date: Sun, 7 Jun 2015 04:20:39 +0200 Subject: [PATCH 1/3] List of routes --- gin.go | 28 ++++++++++++++++++++++++++++ gin_test.go | 48 +++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 75 insertions(+), 1 deletion(-) diff --git a/gin.go b/gin.go index d2887ed2..cf48c337 100644 --- a/gin.go +++ b/gin.go @@ -60,6 +60,11 @@ type ( // handler. HandleMethodNotAllowed bool } + + RouteInfo struct { + Method string + Path string + } ) // Returns a new blank Engine instance without any middleware attached. @@ -169,6 +174,29 @@ func (engine *Engine) addRoute(method, path string, handlers HandlersChain) { root.addRoute(path, handlers) } +func (engine *Engine) Routes() (routes []RouteInfo) { + for _, tree := range engine.trees { + for _, path := range iterate("", nil, tree.root) { + routes = append(routes, RouteInfo{ + Method: tree.method, + Path: path, + }) + } + } + return routes +} + +func iterate(path string, routes []string, root *node) []string { + path += root.path + if root.handlers != nil { + routes = append(routes, path) + } + for _, node := range root.children { + routes = iterate(path, routes, node) + } + return routes +} + // The router is attached to a http.Server and starts listening and serving HTTP requests. // It is a shortcut for http.ListenAndServe(addr, router) // Note: this method will block the calling goroutine undefinitelly unless an error happens. diff --git a/gin_test.go b/gin_test.go index 28bba734..76be3b9a 100644 --- a/gin_test.go +++ b/gin_test.go @@ -14,7 +14,6 @@ import ( //TODO // func (engine *Engine) LoadHTMLGlob(pattern string) { // func (engine *Engine) LoadHTMLFiles(files ...string) { -// func (engine *Engine) Run(addr string) error { // func (engine *Engine) RunTLS(addr string, cert string, key string) error { func init() { @@ -180,3 +179,50 @@ func compareFunc(t *testing.T, a, b interface{}) { t.Error("different functions") } } + +func TestListOfRoutes(t *testing.T) { + handler := func(c *Context){} + router := New() + router.GET("/favicon.ico", handler) + router.GET("/", handler) + group := router.Group("/users") + { + group.GET("/", handler) + group.GET("/:id", handler) + group.POST("/:id", handler) + } + router.Static("/static", ".") + + list := router.Routes() + + assert.Len(t, list, 7) + assert.Contains(t, list, RouteInfo{ + Method: "GET", + Path: "/favicon.ico", + }) + assert.Contains(t, list, RouteInfo{ + Method: "GET", + Path: "/", + }) + assert.Contains(t, list, RouteInfo{ + Method: "GET", + Path: "/users/", + }) + assert.Contains(t, list, RouteInfo{ + Method: "GET", + Path: "/users/:id", + }) + assert.Contains(t, list, RouteInfo{ + Method: "POST", + Path: "/users/:id", + }) + assert.Contains(t, list, RouteInfo{ + Method: "GET", + Path: "/static/*filepath", + }) + assert.Contains(t, list, RouteInfo{ + Method: "HEAD", + Path: "/static/*filepath", + }) + +} From c7d2d82d01da99450a7f862a1cce41efff9b5c81 Mon Sep 17 00:00:00 2001 From: Manu Mtz-Almeida Date: Sun, 7 Jun 2015 04:26:30 +0200 Subject: [PATCH 2/3] gofmt --- gin.go | 2 +- gin_test.go | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/gin.go b/gin.go index cf48c337..5a87d566 100644 --- a/gin.go +++ b/gin.go @@ -63,7 +63,7 @@ type ( RouteInfo struct { Method string - Path string + Path string } ) diff --git a/gin_test.go b/gin_test.go index 76be3b9a..9d8fffa1 100644 --- a/gin_test.go +++ b/gin_test.go @@ -181,7 +181,7 @@ func compareFunc(t *testing.T, a, b interface{}) { } func TestListOfRoutes(t *testing.T) { - handler := func(c *Context){} + handler := func(c *Context) {} router := New() router.GET("/favicon.ico", handler) router.GET("/", handler) @@ -198,31 +198,31 @@ func TestListOfRoutes(t *testing.T) { assert.Len(t, list, 7) assert.Contains(t, list, RouteInfo{ Method: "GET", - Path: "/favicon.ico", + Path: "/favicon.ico", }) assert.Contains(t, list, RouteInfo{ Method: "GET", - Path: "/", + Path: "/", }) assert.Contains(t, list, RouteInfo{ Method: "GET", - Path: "/users/", + Path: "/users/", }) assert.Contains(t, list, RouteInfo{ Method: "GET", - Path: "/users/:id", + Path: "/users/:id", }) assert.Contains(t, list, RouteInfo{ Method: "POST", - Path: "/users/:id", + Path: "/users/:id", }) assert.Contains(t, list, RouteInfo{ Method: "GET", - Path: "/static/*filepath", + Path: "/static/*filepath", }) assert.Contains(t, list, RouteInfo{ Method: "HEAD", - Path: "/static/*filepath", + Path: "/static/*filepath", }) } From 74fe36fa484deba4f9fa2ef8683c6223b5294acd Mon Sep 17 00:00:00 2001 From: Manu Mtz-Almeida Date: Sun, 7 Jun 2015 13:49:36 +0200 Subject: [PATCH 3/3] Routes() returns the function name of the main handler --- debug.go | 2 +- gin.go | 32 ++++++++++++++++++++------------ 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/debug.go b/debug.go index a0b99f43..e5b39cc2 100644 --- a/debug.go +++ b/debug.go @@ -16,7 +16,7 @@ func IsDebugging() bool { func debugPrintRoute(httpMethod, absolutePath string, handlers HandlersChain) { if IsDebugging() { nuHandlers := len(handlers) - handlerName := nameOfFunction(handlers[nuHandlers-1]) + handlerName := nameOfFunction(handlers.Last()) debugPrint("%-5s %-25s --> %s (%d handlers)\n", httpMethod, absolutePath, handlerName, nuHandlers) } } diff --git a/gin.go b/gin.go index 5a87d566..30c43202 100644 --- a/gin.go +++ b/gin.go @@ -62,11 +62,20 @@ type ( } RouteInfo struct { - Method string - Path string + Method string + Path string + Handler string } ) +func (c HandlersChain) Last() HandlerFunc { + length := len(c) + if length > 0 { + return c[length-1] + } + return nil +} + // Returns a new blank Engine instance without any middleware attached. // The most basic configuration func New() *Engine { @@ -176,23 +185,22 @@ func (engine *Engine) addRoute(method, path string, handlers HandlersChain) { func (engine *Engine) Routes() (routes []RouteInfo) { for _, tree := range engine.trees { - for _, path := range iterate("", nil, tree.root) { - routes = append(routes, RouteInfo{ - Method: tree.method, - Path: path, - }) - } + routes = iterate("", tree.method, routes, tree.root) } return routes } -func iterate(path string, routes []string, root *node) []string { +func iterate(path, method string, routes []RouteInfo, root *node) []RouteInfo { path += root.path - if root.handlers != nil { - routes = append(routes, path) + if len(root.handlers) > 0 { + routes = append(routes, RouteInfo{ + Method: method, + Path: path, + Handler: nameOfFunction(root.handlers.Last()), + }) } for _, node := range root.children { - routes = iterate(path, routes, node) + routes = iterate(path, method, routes, node) } return routes }