Skip to content

Commit

Permalink
Merge branch 'routes-list'
Browse files Browse the repository at this point in the history
  • Loading branch information
manucorporat committed Jun 18, 2015
2 parents d6425f1 + 74fe36f commit 451f3b9
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 2 deletions.
2 changes: 1 addition & 1 deletion debug.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
}
Expand Down
36 changes: 36 additions & 0 deletions gin.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,22 @@ type (
HandleMethodNotAllowed bool
ForwardedByClientIP bool
}

RouteInfo struct {
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 {
Expand Down Expand Up @@ -181,6 +195,28 @@ func (engine *Engine) addRoute(method, path string, handlers HandlersChain) {
root.addRoute(path, handlers)
}

func (engine *Engine) Routes() (routes []RouteInfo) {
for _, tree := range engine.trees {
routes = iterate("", tree.method, routes, tree.root)
}
return routes
}

func iterate(path, method string, routes []RouteInfo, root *node) []RouteInfo {
path += root.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, method, 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.
Expand Down
48 changes: 47 additions & 1 deletion gin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down Expand Up @@ -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",
})

}

0 comments on commit 451f3b9

Please sign in to comment.