diff --git a/gin.go b/gin.go index 1e126179..dec69592 100644 --- a/gin.go +++ b/gin.go @@ -42,10 +42,11 @@ func (c HandlersChain) Last() HandlerFunc { // RouteInfo represents a request route's specification which contains method and path and its handler. type RouteInfo struct { - Method string - Path string - Handler string - HandlerFunc HandlerFunc + Method string + Path string + Handler string + HandlerFunc HandlerFunc + HandlersChain HandlersChain } // RoutesInfo defines a RouteInfo array. @@ -287,10 +288,11 @@ func iterate(path, method string, routes RoutesInfo, root *node) RoutesInfo { if len(root.handlers) > 0 { handlerFunc := root.handlers.Last() routes = append(routes, RouteInfo{ - Method: method, - Path: path, - Handler: nameOfFunction(handlerFunc), - HandlerFunc: handlerFunc, + Method: method, + Path: path, + Handler: nameOfFunction(handlerFunc), + HandlerFunc: handlerFunc, + HandlersChain: root.handlers, }) } for _, child := range root.children { diff --git a/gin_test.go b/gin_test.go index 11bdd79c..7a4fe04b 100644 --- a/gin_test.go +++ b/gin_test.go @@ -18,6 +18,7 @@ import ( "time" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func formatAsDate(t time.Time) string { @@ -437,9 +438,13 @@ func compareFunc(t *testing.T, a, b interface{}) { } func TestListOfRoutes(t *testing.T) { + handlerTest1 := func(c *Context) {} + handlerTest2 := func(c *Context) {} + router := New() router.GET("/favicon.ico", handlerTest1) router.GET("/", handlerTest1) + router.GET("/example", handlerTest1, handlerTest2) group := router.Group("/users") { group.GET("/", handlerTest2) @@ -450,32 +455,67 @@ func TestListOfRoutes(t *testing.T) { list := router.Routes() - assert.Len(t, list, 7) - assertRoutePresent(t, list, RouteInfo{ - Method: "GET", - Path: "/favicon.ico", - Handler: "^(.*/vendor/)?github.com/gin-gonic/gin.handlerTest1$", - }) - assertRoutePresent(t, list, RouteInfo{ - Method: "GET", - Path: "/", - Handler: "^(.*/vendor/)?github.com/gin-gonic/gin.handlerTest1$", - }) - assertRoutePresent(t, list, RouteInfo{ - Method: "GET", - Path: "/users/", - Handler: "^(.*/vendor/)?github.com/gin-gonic/gin.handlerTest2$", - }) - assertRoutePresent(t, list, RouteInfo{ - Method: "GET", - Path: "/users/:id", - Handler: "^(.*/vendor/)?github.com/gin-gonic/gin.handlerTest1$", - }) - assertRoutePresent(t, list, RouteInfo{ - Method: "POST", - Path: "/users/:id", - Handler: "^(.*/vendor/)?github.com/gin-gonic/gin.handlerTest2$", - }) + assert.Len(t, list, 8) + + testCases := []RouteInfo{ + { + Method: "GET", + Path: "/favicon.ico", + Handler: "github.com/gin-gonic/gin.TestListOfRoutes.func1", + HandlersChain: HandlersChain{handlerTest1}, + }, + { + Method: "GET", + Path: "/", + Handler: "github.com/gin-gonic/gin.TestListOfRoutes.func1", + HandlersChain: HandlersChain{handlerTest1}, + }, + { + Method: "GET", + Path: "/example", + Handler: "github.com/gin-gonic/gin.TestListOfRoutes.func2", + HandlersChain: HandlersChain{handlerTest1, handlerTest2}, + }, + { + Method: "GET", + Path: "/users/", + Handler: "github.com/gin-gonic/gin.TestListOfRoutes.func2", + HandlersChain: HandlersChain{handlerTest2}, + }, + { + Method: "GET", + Path: "/users/:id", + Handler: "github.com/gin-gonic/gin.TestListOfRoutes.func1", + HandlersChain: HandlersChain{handlerTest1}, + }, + { + Method: "POST", + Path: "/users/:id", + Handler: "github.com/gin-gonic/gin.TestListOfRoutes.func2", + HandlersChain: HandlersChain{handlerTest2}, + }, + } + + for _, tc := range testCases { + t.Run(tc.Path, func(t *testing.T) { + for _, gotRoute := range list { + if gotRoute.Path == tc.Path && gotRoute.Method == tc.Method { + assert.Equal(t, tc.Handler, gotRoute.Handler) + require.Equal(t, len(tc.HandlersChain), len(gotRoute.HandlersChain)) + for i := range tc.HandlersChain { + assert.Equal( + t, + reflect.ValueOf(tc.HandlersChain[i]).Pointer(), + reflect.ValueOf(gotRoute.HandlersChain[i]).Pointer(), + ) + } + + return + } + } + t.Errorf("route not found: %v", tc) + }) + } } func TestEngineHandleContext(t *testing.T) { @@ -531,16 +571,3 @@ func TestEngineHandleContextManyReEntries(t *testing.T) { assert.Equal(t, int64(expectValue), handlerCounter) assert.Equal(t, int64(expectValue), middlewareCounter) } - -func assertRoutePresent(t *testing.T, gotRoutes RoutesInfo, wantRoute RouteInfo) { - for _, gotRoute := range gotRoutes { - if gotRoute.Path == wantRoute.Path && gotRoute.Method == wantRoute.Method { - assert.Regexp(t, wantRoute.Handler, gotRoute.Handler) - return - } - } - t.Errorf("route not found: %v", wantRoute) -} - -func handlerTest1(c *Context) {} -func handlerTest2(c *Context) {}