RoutesInfo: HandlersChain support for routes behavior better testing

This commit is contained in:
Kirill Belov 2021-02-12 11:11:03 +02:00
parent 1bdf86b722
commit 9fd784da0c
2 changed files with 76 additions and 47 deletions

18
gin.go
View File

@ -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 {

View File

@ -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) {}