mirror of
https://github.com/gin-gonic/gin.git
synced 2025-10-15 21:06:39 +08:00
Merge 7010af371d4b01e29ce4b1bf06afbab2f7955069 into 61fae4997db3dc0011e9015f4f69f57c81e9ce4a
This commit is contained in:
commit
27a633365e
27
function.go
Normal file
27
function.go
Normal file
@ -0,0 +1,27 @@
|
||||
package gin
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
type Function struct {
|
||||
Name string
|
||||
File string
|
||||
Line int
|
||||
}
|
||||
|
||||
func parseFunction(f interface{}) Function {
|
||||
ptr := reflect.ValueOf(f).Pointer()
|
||||
fu := runtime.FuncForPC(ptr)
|
||||
file, line := fu.FileLine(ptr)
|
||||
return Function{
|
||||
Name: fu.Name(),
|
||||
File: file,
|
||||
Line: line,
|
||||
}
|
||||
}
|
||||
|
||||
func nameOfFunction(f interface{}) string {
|
||||
return parseFunction(f).Name
|
||||
}
|
23
function_test.go
Normal file
23
function_test.go
Normal file
@ -0,0 +1,23 @@
|
||||
package gin
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func someFunction() {
|
||||
// this empty function is used by TestFunctionName()
|
||||
}
|
||||
|
||||
func TestParseFunction(t *testing.T) {
|
||||
f := parseFunction(someFunction)
|
||||
assert.Equal(t, "github.com/gin-gonic/gin.someFunction", f.Name)
|
||||
assert.Equal(t, "function_test.go", filepath.Base(f.File))
|
||||
assert.Equal(t, 12, f.Line)
|
||||
}
|
||||
|
||||
func TestFunctionName(t *testing.T) {
|
||||
assert.Equal(t, nameOfFunction(someFunction), "github.com/gin-gonic/gin.someFunction")
|
||||
}
|
7
gin.go
7
gin.go
@ -38,6 +38,8 @@ type (
|
||||
Method string
|
||||
Path string
|
||||
Handler string
|
||||
File string
|
||||
Line int
|
||||
}
|
||||
|
||||
// Engine is the framework's instance, it contains the muxer, middleware and configuration settings.
|
||||
@ -213,10 +215,13 @@ func (engine *Engine) Routes() (routes RoutesInfo) {
|
||||
func iterate(path, method string, routes RoutesInfo, root *node) RoutesInfo {
|
||||
path += root.path
|
||||
if len(root.handlers) > 0 {
|
||||
funcInfo := parseFunction(root.handlers.Last())
|
||||
routes = append(routes, RouteInfo{
|
||||
Method: method,
|
||||
Path: path,
|
||||
Handler: nameOfFunction(root.handlers.Last()),
|
||||
Handler: funcInfo.Name,
|
||||
File: funcInfo.File,
|
||||
Line: funcInfo.Line,
|
||||
})
|
||||
}
|
||||
for _, child := range root.children {
|
||||
|
40
gin_test.go
40
gin_test.go
@ -5,6 +5,7 @@
|
||||
package gin
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
@ -214,31 +215,20 @@ func TestListOfRoutes(t *testing.T) {
|
||||
list := router.Routes()
|
||||
|
||||
assert.Len(t, list, 7)
|
||||
assert.Contains(t, list, RouteInfo{
|
||||
Method: "GET",
|
||||
Path: "/favicon.ico",
|
||||
Handler: "github.com/gin-gonic/gin.handler_test1",
|
||||
})
|
||||
assert.Contains(t, list, RouteInfo{
|
||||
Method: "GET",
|
||||
Path: "/",
|
||||
Handler: "github.com/gin-gonic/gin.handler_test1",
|
||||
})
|
||||
assert.Contains(t, list, RouteInfo{
|
||||
Method: "GET",
|
||||
Path: "/users/",
|
||||
Handler: "github.com/gin-gonic/gin.handler_test2",
|
||||
})
|
||||
assert.Contains(t, list, RouteInfo{
|
||||
Method: "GET",
|
||||
Path: "/users/:id",
|
||||
Handler: "github.com/gin-gonic/gin.handler_test1",
|
||||
})
|
||||
assert.Contains(t, list, RouteInfo{
|
||||
Method: "POST",
|
||||
Path: "/users/:id",
|
||||
Handler: "github.com/gin-gonic/gin.handler_test2",
|
||||
})
|
||||
assertRoute(t, list, "GET", "/favicon.ico", "github.com/gin-gonic/gin.handler_test1", "gin_test.go")
|
||||
assertRoute(t, list, "GET", "/", "github.com/gin-gonic/gin.handler_test1", "gin_test.go")
|
||||
assertRoute(t, list, "GET", "/users/", "github.com/gin-gonic/gin.handler_test2", "gin_test.go")
|
||||
assertRoute(t, list, "GET", "/users/:id", "github.com/gin-gonic/gin.handler_test1", "gin_test.go")
|
||||
assertRoute(t, list, "POST", "/users/:id", "github.com/gin-gonic/gin.handler_test2", "gin_test.go")
|
||||
}
|
||||
|
||||
func assertRoute(t *testing.T, list RoutesInfo, method, path, handler, filename string) {
|
||||
for _, r := range list {
|
||||
if r.Method == method && r.Path == path && r.Handler == handler && filepath.Base(r.File) == filename {
|
||||
return
|
||||
}
|
||||
}
|
||||
t.Fatalf("Routes info doesn't include route information: [%s] %s: %s at %s\n%v", method, path, handler, filename, list)
|
||||
}
|
||||
|
||||
func handler_test1(c *Context) {}
|
||||
|
5
utils.go
5
utils.go
@ -10,7 +10,6 @@ import (
|
||||
"os"
|
||||
"path"
|
||||
"reflect"
|
||||
"runtime"
|
||||
"strings"
|
||||
)
|
||||
|
||||
@ -114,10 +113,6 @@ func lastChar(str string) uint8 {
|
||||
return str[size-1]
|
||||
}
|
||||
|
||||
func nameOfFunction(f interface{}) string {
|
||||
return runtime.FuncForPC(reflect.ValueOf(f).Pointer()).Name()
|
||||
}
|
||||
|
||||
func joinPaths(absolutePath, relativePath string) string {
|
||||
if len(relativePath) == 0 {
|
||||
return absolutePath
|
||||
|
@ -77,14 +77,6 @@ func TestFilterFlags(t *testing.T) {
|
||||
assert.Equal(t, result, "text/html")
|
||||
}
|
||||
|
||||
func TestFunctionName(t *testing.T) {
|
||||
assert.Equal(t, nameOfFunction(somefunction), "github.com/gin-gonic/gin.somefunction")
|
||||
}
|
||||
|
||||
func somefunction() {
|
||||
// this empty function is used by TestFunctionName()
|
||||
}
|
||||
|
||||
func TestJoinPaths(t *testing.T) {
|
||||
assert.Equal(t, joinPaths("", ""), "")
|
||||
assert.Equal(t, joinPaths("", "/"), "/")
|
||||
|
Loading…
x
Reference in New Issue
Block a user