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. // RouteInfo represents a request route's specification which contains method and path and its handler.
type RouteInfo struct { type RouteInfo struct {
Method string Method string
Path string Path string
Handler string Handler string
HandlerFunc HandlerFunc HandlerFunc HandlerFunc
HandlersChain HandlersChain
} }
// RoutesInfo defines a RouteInfo array. // RoutesInfo defines a RouteInfo array.
@ -287,10 +288,11 @@ func iterate(path, method string, routes RoutesInfo, root *node) RoutesInfo {
if len(root.handlers) > 0 { if len(root.handlers) > 0 {
handlerFunc := root.handlers.Last() handlerFunc := root.handlers.Last()
routes = append(routes, RouteInfo{ routes = append(routes, RouteInfo{
Method: method, Method: method,
Path: path, Path: path,
Handler: nameOfFunction(handlerFunc), Handler: nameOfFunction(handlerFunc),
HandlerFunc: handlerFunc, HandlerFunc: handlerFunc,
HandlersChain: root.handlers,
}) })
} }
for _, child := range root.children { for _, child := range root.children {

View File

@ -18,6 +18,7 @@ import (
"time" "time"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
) )
func formatAsDate(t time.Time) string { func formatAsDate(t time.Time) string {
@ -437,9 +438,13 @@ func compareFunc(t *testing.T, a, b interface{}) {
} }
func TestListOfRoutes(t *testing.T) { func TestListOfRoutes(t *testing.T) {
handlerTest1 := func(c *Context) {}
handlerTest2 := func(c *Context) {}
router := New() router := New()
router.GET("/favicon.ico", handlerTest1) router.GET("/favicon.ico", handlerTest1)
router.GET("/", handlerTest1) router.GET("/", handlerTest1)
router.GET("/example", handlerTest1, handlerTest2)
group := router.Group("/users") group := router.Group("/users")
{ {
group.GET("/", handlerTest2) group.GET("/", handlerTest2)
@ -450,32 +455,67 @@ func TestListOfRoutes(t *testing.T) {
list := router.Routes() list := router.Routes()
assert.Len(t, list, 7) assert.Len(t, list, 8)
assertRoutePresent(t, list, RouteInfo{
Method: "GET", testCases := []RouteInfo{
Path: "/favicon.ico", {
Handler: "^(.*/vendor/)?github.com/gin-gonic/gin.handlerTest1$", Method: "GET",
}) Path: "/favicon.ico",
assertRoutePresent(t, list, RouteInfo{ Handler: "github.com/gin-gonic/gin.TestListOfRoutes.func1",
Method: "GET", HandlersChain: HandlersChain{handlerTest1},
Path: "/", },
Handler: "^(.*/vendor/)?github.com/gin-gonic/gin.handlerTest1$", {
}) Method: "GET",
assertRoutePresent(t, list, RouteInfo{ Path: "/",
Method: "GET", Handler: "github.com/gin-gonic/gin.TestListOfRoutes.func1",
Path: "/users/", HandlersChain: HandlersChain{handlerTest1},
Handler: "^(.*/vendor/)?github.com/gin-gonic/gin.handlerTest2$", },
}) {
assertRoutePresent(t, list, RouteInfo{ Method: "GET",
Method: "GET", Path: "/example",
Path: "/users/:id", Handler: "github.com/gin-gonic/gin.TestListOfRoutes.func2",
Handler: "^(.*/vendor/)?github.com/gin-gonic/gin.handlerTest1$", HandlersChain: HandlersChain{handlerTest1, handlerTest2},
}) },
assertRoutePresent(t, list, RouteInfo{ {
Method: "POST", Method: "GET",
Path: "/users/:id", Path: "/users/",
Handler: "^(.*/vendor/)?github.com/gin-gonic/gin.handlerTest2$", 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) { 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), handlerCounter)
assert.Equal(t, int64(expectValue), middlewareCounter) 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) {}