From 07d0dccd89e16cef4aaf3df423ed7a40a3c42831 Mon Sep 17 00:00:00 2001 From: Jason li Date: Wed, 6 Jan 2021 12:51:54 +0800 Subject: [PATCH 1/8] finish router get example --- server/web/router.go | 90 +++++++++++++++++++++++++++++++++++++++++++- server/web/server.go | 20 ++++++++++ 2 files changed, 109 insertions(+), 1 deletion(-) diff --git a/server/web/router.go b/server/web/router.go index 613c4172..d3bb13ad 100644 --- a/server/web/router.go +++ b/server/web/router.go @@ -20,6 +20,7 @@ import ( "net/http" "path" "reflect" + "runtime" "strconv" "strings" "sync" @@ -275,7 +276,7 @@ func (p *ControllerRegister) addWithMethodParams(pattern string, c ControllerInt for i := range opts { opts[i](route) } - + globalSessionOn := p.cfg.WebConfig.Session.SessionOn if !globalSessionOn && route.sessionOn { logs.Warn("global sessionOn is false, sessionOn of router [%s] can't be set to true", route.pattern) @@ -332,6 +333,93 @@ func (p *ControllerRegister) GiveBackContext(ctx *beecontext.Context) { p.pool.Put(ctx) } +// RouterGet add post method +// usage: +// type MyController struct { +// web.Controller +// } +// func (m MyController) Ping() { +// m.Ctx.Output.Body([]byte("hello world")) +// } +// +// RouterGet("/api/:id", MyController.Ping) +func (p *ControllerRegister) RouterGet(pattern string, f interface{}) { + p.AddRouterMethod(http.MethodGet, pattern, f) +} + +// AddRouterMethod add http method router +// usage: +// type MyController struct { +// web.Controller +// } +// func (m MyController) Ping() { +// m.Ctx.Output.Body([]byte("hello world")) +// } +// +// AddRouterMethod("get","/api/:id", MyController.Ping) +func (p *ControllerRegister) AddRouterMethod(method, pattern string, f interface{}) { + method = strings.ToUpper(method) + if method != "*" && !HTTPMETHOD[method] { + panic("not support http method: " + method) + } + + ct, methodName := getReflectTypeAndMethod(f) + route := &ControllerInfo{} + route.pattern = pattern + route.routerType = routerTypeBeego + route.sessionOn = p.cfg.WebConfig.Session.SessionOn + route.controllerType = ct + route.methods = map[string]string{method: methodName} + p.addToRouter(method, pattern, route) +} + +// get reflect controller type and method by controller method expression +func getReflectTypeAndMethod(f interface{}) (controllerType reflect.Type, method string) { + // check f is a function + funcType := reflect.TypeOf(f) + if funcType.Kind() != reflect.Func { + panic("not a method") + } + + // get function name + funcObj := runtime.FuncForPC(reflect.ValueOf(f).Pointer()) + if funcObj == nil { + panic("cannot find the method") + } + funcNameSli := strings.Split(funcObj.Name(), ".") + lFuncSli := len(funcNameSli) + if lFuncSli == 0 { + panic("invalid method full name: " + funcObj.Name()) + } + + method = funcNameSli[lFuncSli-1] + if len(method) == 0 { + panic("method name is empty") + } else if method[0] > 96 || method[0] < 65 { + panic("not a public method") + } + + // check only one param which is the method receiver + if numIn := funcType.NumIn(); numIn != 1 { + panic("invalid number of param in") + } + + // check the receiver implement ControllerInterface + controllerType = funcType.In(0) + _, ok := reflect.New(controllerType).Interface().(ControllerInterface) + if !ok { + panic(controllerType.String() + " is not implemented ControllerInterface") + } + + // check controller has the method + _, exists := controllerType.MethodByName(method) + if !exists { + panic(controllerType.String() + " has no method " + method) + } + + return +} + // Get add get method // usage: // Get("/", func(ctx *context.Context){ diff --git a/server/web/server.go b/server/web/server.go index 6c4eaf9e..bcfcda77 100644 --- a/server/web/server.go +++ b/server/web/server.go @@ -461,6 +461,26 @@ func (app *HttpServer) AutoPrefix(prefix string, c ControllerInterface) *HttpSer return app } +// RouterGet see HttpServer.RouterGet +func RouterGet(rootpath string, f interface{}) { + BeeApp.RouterGet(rootpath, f) +} + +// RouterGet used to register router for RouterGet method +// usage: +// type MyController struct { +// web.Controller +// } +// func (m MyController) Ping() { +// m.Ctx.Output.Body([]byte("hello world")) +// } +// +// RouterGet("/api/:id", MyController.Ping) +func (app *HttpServer) RouterGet(rootpath string, f interface{}) *HttpServer { + app.Handlers.RouterGet(rootpath, f) + return app +} + // Get see HttpServer.Get func Get(rootpath string, f FilterFunc) *HttpServer { return BeeApp.Get(rootpath, f) From cbbc296efbaac976566cc2f80d1b25e5c8684779 Mon Sep 17 00:00:00 2001 From: Jason li Date: Thu, 7 Jan 2021 19:29:22 +0800 Subject: [PATCH 2/8] add all router methods and functions --- server/web/namespace.go | 104 +++++++++++++++++++++++++++++ server/web/router.go | 100 +++++++++++++++++++++++++++- server/web/server.go | 140 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 343 insertions(+), 1 deletion(-) diff --git a/server/web/namespace.go b/server/web/namespace.go index 892f648a..0df72b01 100644 --- a/server/web/namespace.go +++ b/server/web/namespace.go @@ -187,6 +187,54 @@ func (n *Namespace) Include(cList ...ControllerInterface) *Namespace { return n } +// RouterGet same as beego.RouterGet +func (n *Namespace) RouterGet(rootpath string, f interface{}) *Namespace { + n.handlers.RouterGet(rootpath, f) + return n +} + +// RouterPost same as beego.RouterPost +func (n *Namespace) RouterPost(rootpath string, f interface{}) *Namespace { + n.handlers.RouterPost(rootpath, f) + return n +} + +// RouterDelete same as beego.RouterDelete +func (n *Namespace) RouterDelete(rootpath string, f interface{}) *Namespace { + n.handlers.RouterDelete(rootpath, f) + return n +} + +// RouterPut same as beego.RouterPut +func (n *Namespace) RouterPut(rootpath string, f interface{}) *Namespace { + n.handlers.RouterPut(rootpath, f) + return n +} + +// RouterHead same as beego.RouterHead +func (n *Namespace) RouterHead(rootpath string, f interface{}) *Namespace { + n.handlers.RouterHead(rootpath, f) + return n +} + +// RouterOptions same as beego.RouterOptions +func (n *Namespace) RouterOptions(rootpath string, f interface{}) *Namespace { + n.handlers.RouterOptions(rootpath, f) + return n +} + +// RouterPatch same as beego.RouterPatch +func (n *Namespace) RouterPatch(rootpath string, f interface{}) *Namespace { + n.handlers.RouterPatch(rootpath, f) + return n +} + +// Any same as beego.RouterAny +func (n *Namespace) RouterAny(rootpath string, f interface{}) *Namespace { + n.handlers.RouterAny(rootpath, f) + return n +} + // Namespace add nest Namespace // usage: // ns := beego.NewNamespace(“/v1”). @@ -366,6 +414,62 @@ func NSPatch(rootpath string, f FilterFunc) LinkNamespace { } } +// NSRouterGet call Namespace RouterGet +func NSRouterGet(rootpath string, f interface{}) LinkNamespace { + return func(ns *Namespace) { + ns.RouterGet(rootpath, f) + } +} + +// NSPost call Namespace RouterPost +func NSRouterPost(rootpath string, f interface{}) LinkNamespace { + return func(ns *Namespace) { + ns.RouterPost(rootpath, f) + } +} + +// NSRouterHead call Namespace RouterHead +func NSRouterHead(rootpath string, f interface{}) LinkNamespace { + return func(ns *Namespace) { + ns.RouterHead(rootpath, f) + } +} + +// NSRouterPut call Namespace RouterPut +func NSRouterPut(rootpath string, f interface{}) LinkNamespace { + return func(ns *Namespace) { + ns.RouterPut(rootpath, f) + } +} + +// NSRouterDelete call Namespace RouterDelete +func NSRouterDelete(rootpath string, f interface{}) LinkNamespace { + return func(ns *Namespace) { + ns.RouterDelete(rootpath, f) + } +} + +// NSRouterAny call Namespace RouterAny +func NSRouterAny(rootpath string, f interface{}) LinkNamespace { + return func(ns *Namespace) { + ns.RouterAny(rootpath, f) + } +} + +// NSRouterOptions call Namespace RouterOptions +func NSRouterOptions(rootpath string, f interface{}) LinkNamespace { + return func(ns *Namespace) { + ns.RouterOptions(rootpath, f) + } +} + +// NSRouterPatch call Namespace RouterPatch +func NSRouterPatch(rootpath string, f interface{}) LinkNamespace { + return func(ns *Namespace) { + ns.RouterPatch(rootpath, f) + } +} + // NSAutoRouter call Namespace AutoRouter func NSAutoRouter(c ControllerInterface) LinkNamespace { return func(ns *Namespace) { diff --git a/server/web/router.go b/server/web/router.go index d3bb13ad..af143d1a 100644 --- a/server/web/router.go +++ b/server/web/router.go @@ -333,7 +333,7 @@ func (p *ControllerRegister) GiveBackContext(ctx *beecontext.Context) { p.pool.Put(ctx) } -// RouterGet add post method +// RouterGet add get method // usage: // type MyController struct { // web.Controller @@ -347,6 +347,104 @@ func (p *ControllerRegister) RouterGet(pattern string, f interface{}) { p.AddRouterMethod(http.MethodGet, pattern, f) } +// RouterPost add post method +// usage: +// type MyController struct { +// web.Controller +// } +// func (m MyController) Ping() { +// m.Ctx.Output.Body([]byte("hello world")) +// } +// +// RouterPost("/api/:id", MyController.Ping) +func (p *ControllerRegister) RouterPost(pattern string, f interface{}) { + p.AddRouterMethod(http.MethodPost, pattern, f) +} + +// RouterHead add post method +// usage: +// type MyController struct { +// web.Controller +// } +// func (m MyController) Ping() { +// m.Ctx.Output.Body([]byte("hello world")) +// } +// +// RouterHead("/api/:id", MyController.Ping) +func (p *ControllerRegister) RouterHead(pattern string, f interface{}) { + p.AddRouterMethod(http.MethodHead, pattern, f) +} + +// RouterPut add post method +// usage: +// type MyController struct { +// web.Controller +// } +// func (m MyController) Ping() { +// m.Ctx.Output.Body([]byte("hello world")) +// } +// +// RouterPut("/api/:id", MyController.Ping) +func (p *ControllerRegister) RouterPut(pattern string, f interface{}) { + p.AddRouterMethod(http.MethodPut, pattern, f) +} + +// RouterPatch add post method +// usage: +// type MyController struct { +// web.Controller +// } +// func (m MyController) Ping() { +// m.Ctx.Output.Body([]byte("hello world")) +// } +// +// RouterPatch("/api/:id", MyController.Ping) +func (p *ControllerRegister) RouterPatch(pattern string, f interface{}) { + p.AddRouterMethod(http.MethodPatch, pattern, f) +} + +// RouterDelete add post method +// usage: +// type MyController struct { +// web.Controller +// } +// func (m MyController) Ping() { +// m.Ctx.Output.Body([]byte("hello world")) +// } +// +// RouterDelete("/api/:id", MyController.Ping) +func (p *ControllerRegister) RouterDelete(pattern string, f interface{}) { + p.AddRouterMethod(http.MethodDelete, pattern, f) +} + +// RouterOptions add post method +// usage: +// type MyController struct { +// web.Controller +// } +// func (m MyController) Ping() { +// m.Ctx.Output.Body([]byte("hello world")) +// } +// +// RouterOptions("/api/:id", MyController.Ping) +func (p *ControllerRegister) RouterOptions(pattern string, f interface{}) { + p.AddRouterMethod(http.MethodOptions, pattern, f) +} + +// RouterAny add post method +// usage: +// type MyController struct { +// web.Controller +// } +// func (m MyController) Ping() { +// m.Ctx.Output.Body([]byte("hello world")) +// } +// +// RouterAny("/api/:id", MyController.Ping) +func (p *ControllerRegister) RouterAny(pattern string, f interface{}) { + p.AddRouterMethod("*", pattern, f) +} + // AddRouterMethod add http method router // usage: // type MyController struct { diff --git a/server/web/server.go b/server/web/server.go index bcfcda77..b61b85de 100644 --- a/server/web/server.go +++ b/server/web/server.go @@ -481,6 +481,146 @@ func (app *HttpServer) RouterGet(rootpath string, f interface{}) *HttpServer { return app } +// RouterPost see HttpServer.RouterGet +func RouterPost(rootpath string, f interface{}) { + BeeApp.RouterPost(rootpath, f) +} + +// RouterPost used to register router for RouterPost method +// usage: +// type MyController struct { +// web.Controller +// } +// func (m MyController) Ping() { +// m.Ctx.Output.Body([]byte("hello world")) +// } +// +// RouterPost("/api/:id", MyController.Ping) +func (app *HttpServer) RouterPost(rootpath string, f interface{}) *HttpServer { + app.Handlers.RouterPost(rootpath, f) + return app +} + +// RouterHead see HttpServer.RouterHead +func RouterHead(rootpath string, f interface{}) { + BeeApp.RouterPost(rootpath, f) +} + +// RouterHead used to register router for RouterHead method +// usage: +// type MyController struct { +// web.Controller +// } +// func (m MyController) Ping() { +// m.Ctx.Output.Body([]byte("hello world")) +// } +// +// RouterHead("/api/:id", MyController.Ping) +func (app *HttpServer) RouterHead(rootpath string, f interface{}) *HttpServer { + app.Handlers.RouterHead(rootpath, f) + return app +} + +// RouterPut see HttpServer.RouterPut +func RouterPut(rootpath string, f interface{}) { + BeeApp.RouterPost(rootpath, f) +} + +// RouterPut used to register router for RouterPut method +// usage: +// type MyController struct { +// web.Controller +// } +// func (m MyController) Ping() { +// m.Ctx.Output.Body([]byte("hello world")) +// } +// +// RouterPut("/api/:id", MyController.Ping) +func (app *HttpServer) RouterPut(rootpath string, f interface{}) *HttpServer { + app.Handlers.RouterPut(rootpath, f) + return app +} + +// RouterPatch see HttpServer.RouterPatch +func RouterPatch(rootpath string, f interface{}) { + BeeApp.RouterPatch(rootpath, f) +} + +// RouterPatch used to register router for RouterPatch method +// usage: +// type MyController struct { +// web.Controller +// } +// func (m MyController) Ping() { +// m.Ctx.Output.Body([]byte("hello world")) +// } +// +// RouterPatch("/api/:id", MyController.Ping) +func (app *HttpServer) RouterPatch(rootpath string, f interface{}) *HttpServer { + app.Handlers.RouterPatch(rootpath, f) + return app +} + +// RouterDelete see HttpServer.RouterDelete +func RouterDelete(rootpath string, f interface{}) { + BeeApp.RouterDelete(rootpath, f) +} + +// RouterDelete used to register router for RouterDelete method +// usage: +// type MyController struct { +// web.Controller +// } +// func (m MyController) Ping() { +// m.Ctx.Output.Body([]byte("hello world")) +// } +// +// RouterDelete("/api/:id", MyController.Ping) +func (app *HttpServer) RouterDelete(rootpath string, f interface{}) *HttpServer { + app.Handlers.RouterDelete(rootpath, f) + return app +} + +// RouterOptions see HttpServer.RouterOptions +func RouterOptions(rootpath string, f interface{}) { + BeeApp.RouterOptions(rootpath, f) +} + +// RouterOptions used to register router for RouterOptions method +// usage: +// type MyController struct { +// web.Controller +// } +// func (m MyController) Ping() { +// m.Ctx.Output.Body([]byte("hello world")) +// } +// +// RouterOptions("/api/:id", MyController.Ping) +func (app *HttpServer) RouterOptions(rootpath string, f interface{}) *HttpServer { + app.Handlers.RouterOptions(rootpath, f) + return app +} + +// RouterAny see HttpServer.RouterAny +func RouterAny(rootpath string, f interface{}) { + BeeApp.RouterOptions(rootpath, f) +} + +// RouterAny used to register router for RouterAny method +// usage: +// type MyController struct { +// web.Controller +// } +// func (m MyController) Ping() { +// m.Ctx.Output.Body([]byte("hello world")) +// } +// +// RouterAny("/api/:id", MyController.Ping) +func (app *HttpServer) RouterAny(rootpath string, f interface{}) *HttpServer { + app.Handlers.RouterAny(rootpath, f) + return app +} + // Get see HttpServer.Get func Get(rootpath string, f FilterFunc) *HttpServer { return BeeApp.Get(rootpath, f) From 76b352cf8a30678efee19c4ce74e99406e0be2eb Mon Sep 17 00:00:00 2001 From: Jason li Date: Thu, 7 Jan 2021 21:12:36 +0800 Subject: [PATCH 3/8] add unit test and fix typos --- server/web/namespace_test.go | 226 +++++++++++++++++++++++++++++++++++ server/web/router.go | 28 +++-- server/web/router_test.go | 167 +++++++++++++++++++++++++- server/web/server.go | 6 +- server/web/server_test.go | 81 +++++++++++++ 5 files changed, 496 insertions(+), 12 deletions(-) diff --git a/server/web/namespace_test.go b/server/web/namespace_test.go index 05042c96..2bf2480e 100644 --- a/server/web/namespace_test.go +++ b/server/web/namespace_test.go @@ -23,6 +23,20 @@ import ( "github.com/beego/beego/v2/server/web/context" ) +const exampleBody = "hello world" + +type ExampleController struct { + Controller +} + +func (m ExampleController) Ping() { + m.Ctx.Output.Body([]byte(exampleBody)) +} + +func (m ExampleController) ping() { + m.Ctx.Output.Body([]byte(exampleBody)) +} + func TestNamespaceGet(t *testing.T) { r, _ := http.NewRequest("GET", "/v1/user", nil) w := httptest.NewRecorder() @@ -166,3 +180,215 @@ func TestNamespaceInside(t *testing.T) { t.Errorf("TestNamespaceInside can't run, get the response is " + w.Body.String()) } } + +func TestNamespaceRouterGet(t *testing.T) { + r, _ := http.NewRequest(http.MethodGet, "/v1/user", nil) + w := httptest.NewRecorder() + + ns := NewNamespace("/v1") + ns.RouterGet("/user", ExampleController.Ping) + AddNamespace(ns) + BeeApp.Handlers.ServeHTTP(w, r) + if w.Body.String() != exampleBody { + t.Errorf("TestNamespaceRouterGet can't run, get the response is " + w.Body.String()) + } +} + +func TestNamespaceRouterPost(t *testing.T) { + r, _ := http.NewRequest(http.MethodPost, "/v1/user", nil) + w := httptest.NewRecorder() + + ns := NewNamespace("/v1") + ns.RouterPost("/user", ExampleController.Ping) + AddNamespace(ns) + BeeApp.Handlers.ServeHTTP(w, r) + if w.Body.String() != exampleBody { + t.Errorf("TestNamespaceRouterPost can't run, get the response is " + w.Body.String()) + } +} + +func TestNamespaceRouterDelete(t *testing.T) { + r, _ := http.NewRequest(http.MethodDelete, "/v1/user", nil) + w := httptest.NewRecorder() + + ns := NewNamespace("/v1") + ns.RouterDelete("/user", ExampleController.Ping) + AddNamespace(ns) + BeeApp.Handlers.ServeHTTP(w, r) + if w.Body.String() != exampleBody { + t.Errorf("TestNamespaceRouterDelete can't run, get the response is " + w.Body.String()) + } +} + +func TestNamespaceRouterPut(t *testing.T) { + r, _ := http.NewRequest(http.MethodPut, "/v1/user", nil) + w := httptest.NewRecorder() + + ns := NewNamespace("/v1") + ns.RouterPut("/user", ExampleController.Ping) + AddNamespace(ns) + BeeApp.Handlers.ServeHTTP(w, r) + if w.Body.String() != exampleBody { + t.Errorf("TestNamespaceRouterPut can't run, get the response is " + w.Body.String()) + } +} + +func TestNamespaceRouterHead(t *testing.T) { + r, _ := http.NewRequest(http.MethodHead, "/v1/user", nil) + w := httptest.NewRecorder() + + ns := NewNamespace("/v1") + ns.RouterHead("/user", ExampleController.Ping) + AddNamespace(ns) + BeeApp.Handlers.ServeHTTP(w, r) + if w.Body.String() != exampleBody { + t.Errorf("TestNamespaceRouterHead can't run, get the response is " + w.Body.String()) + } +} + +func TestNamespaceRouterOptions(t *testing.T) { + r, _ := http.NewRequest(http.MethodOptions, "/v1/user", nil) + w := httptest.NewRecorder() + + ns := NewNamespace("/v1") + ns.RouterOptions("/user", ExampleController.Ping) + AddNamespace(ns) + BeeApp.Handlers.ServeHTTP(w, r) + if w.Body.String() != exampleBody { + t.Errorf("TestNamespaceRouterOptions can't run, get the response is " + w.Body.String()) + } +} + +func TestNamespaceRouterPatch(t *testing.T) { + r, _ := http.NewRequest(http.MethodPatch, "/v1/user", nil) + w := httptest.NewRecorder() + + ns := NewNamespace("/v1") + ns.RouterPatch("/user", ExampleController.Ping) + AddNamespace(ns) + BeeApp.Handlers.ServeHTTP(w, r) + if w.Body.String() != exampleBody { + t.Errorf("TestNamespaceRouterPatch can't run, get the response is " + w.Body.String()) + } +} + +func TestNamespaceRouterAny(t *testing.T) { + ns := NewNamespace("/v1") + ns.RouterAny("/user", ExampleController.Ping) + AddNamespace(ns) + + for method, _ := range HTTPMETHOD { + w := httptest.NewRecorder() + r, _ := http.NewRequest(method, "/v1/user", nil) + BeeApp.Handlers.ServeHTTP(w, r) + if w.Body.String() != exampleBody { + t.Errorf("TestNamespaceRouterAny can't run, get the response is " + w.Body.String()) + } + } +} + +func TestNamespaceNSRouterGet(t *testing.T) { + r, _ := http.NewRequest(http.MethodGet, "/v1/user", nil) + w := httptest.NewRecorder() + + ns := NewNamespace("/v1") + NSRouterGet("/user", ExampleController.Ping)(ns) + AddNamespace(ns) + BeeApp.Handlers.ServeHTTP(w, r) + if w.Body.String() != exampleBody { + t.Errorf("TestNamespaceRouterGet can't run, get the response is " + w.Body.String()) + } +} + +func TestNamespaceNSRouterPost(t *testing.T) { + r, _ := http.NewRequest(http.MethodPost, "/v1/user", nil) + w := httptest.NewRecorder() + + ns := NewNamespace("/v1") + NSRouterPost("/user", ExampleController.Ping)(ns) + AddNamespace(ns) + BeeApp.Handlers.ServeHTTP(w, r) + if w.Body.String() != exampleBody { + t.Errorf("TestNamespaceRouterPost can't run, get the response is " + w.Body.String()) + } +} + +func TestNamespaceNSRouterDelete(t *testing.T) { + r, _ := http.NewRequest(http.MethodDelete, "/v1/user", nil) + w := httptest.NewRecorder() + + ns := NewNamespace("/v1") + NSRouterDelete("/user", ExampleController.Ping)(ns) + AddNamespace(ns) + BeeApp.Handlers.ServeHTTP(w, r) + if w.Body.String() != exampleBody { + t.Errorf("TestNamespaceRouterDelete can't run, get the response is " + w.Body.String()) + } +} + +func TestNamespaceNSRouterPut(t *testing.T) { + r, _ := http.NewRequest(http.MethodPut, "/v1/user", nil) + w := httptest.NewRecorder() + + ns := NewNamespace("/v1") + NSRouterPut("/user", ExampleController.Ping)(ns) + AddNamespace(ns) + BeeApp.Handlers.ServeHTTP(w, r) + if w.Body.String() != exampleBody { + t.Errorf("TestNamespaceRouterPut can't run, get the response is " + w.Body.String()) + } +} + +func TestNamespaceNSRouterHead(t *testing.T) { + r, _ := http.NewRequest(http.MethodHead, "/v1/user", nil) + w := httptest.NewRecorder() + + ns := NewNamespace("/v1") + NSRouterHead("/user", ExampleController.Ping)(ns) + AddNamespace(ns) + BeeApp.Handlers.ServeHTTP(w, r) + if w.Body.String() != exampleBody { + t.Errorf("TestNamespaceRouterHead can't run, get the response is " + w.Body.String()) + } +} + +func TestNamespaceNSRouterOptions(t *testing.T) { + r, _ := http.NewRequest(http.MethodOptions, "/v1/user", nil) + w := httptest.NewRecorder() + + ns := NewNamespace("/v1") + NSRouterOptions("/user", ExampleController.Ping)(ns) + AddNamespace(ns) + BeeApp.Handlers.ServeHTTP(w, r) + if w.Body.String() != exampleBody { + t.Errorf("TestNamespaceRouterOptions can't run, get the response is " + w.Body.String()) + } +} + +func TestNamespaceNSRouterPatch(t *testing.T) { + r, _ := http.NewRequest(http.MethodPatch, "/v1/user", nil) + w := httptest.NewRecorder() + + ns := NewNamespace("/v1") + NSRouterPatch("/user", ExampleController.Ping)(ns) + AddNamespace(ns) + BeeApp.Handlers.ServeHTTP(w, r) + if w.Body.String() != exampleBody { + t.Errorf("TestNamespaceRouterPatch can't run, get the response is " + w.Body.String()) + } +} + +func TestNamespaceNSRouterAny(t *testing.T) { + ns := NewNamespace("/v1") + NSRouterAny("/user", ExampleController.Ping)(ns) + AddNamespace(ns) + + for method, _ := range HTTPMETHOD { + w := httptest.NewRecorder() + r, _ := http.NewRequest(method, "/v1/user", nil) + BeeApp.Handlers.ServeHTTP(w, r) + if w.Body.String() != exampleBody { + t.Errorf("TestNamespaceRouterAny can't run, get the response is " + w.Body.String()) + } + } +} diff --git a/server/web/router.go b/server/web/router.go index af143d1a..0eb93d5a 100644 --- a/server/web/router.go +++ b/server/web/router.go @@ -361,7 +361,7 @@ func (p *ControllerRegister) RouterPost(pattern string, f interface{}) { p.AddRouterMethod(http.MethodPost, pattern, f) } -// RouterHead add post method +// RouterHead add head method // usage: // type MyController struct { // web.Controller @@ -375,7 +375,7 @@ func (p *ControllerRegister) RouterHead(pattern string, f interface{}) { p.AddRouterMethod(http.MethodHead, pattern, f) } -// RouterPut add post method +// RouterPut add put method // usage: // type MyController struct { // web.Controller @@ -389,7 +389,7 @@ func (p *ControllerRegister) RouterPut(pattern string, f interface{}) { p.AddRouterMethod(http.MethodPut, pattern, f) } -// RouterPatch add post method +// RouterPatch add patch method // usage: // type MyController struct { // web.Controller @@ -403,7 +403,7 @@ func (p *ControllerRegister) RouterPatch(pattern string, f interface{}) { p.AddRouterMethod(http.MethodPatch, pattern, f) } -// RouterDelete add post method +// RouterDelete add delete method // usage: // type MyController struct { // web.Controller @@ -417,7 +417,7 @@ func (p *ControllerRegister) RouterDelete(pattern string, f interface{}) { p.AddRouterMethod(http.MethodDelete, pattern, f) } -// RouterOptions add post method +// RouterOptions add options method // usage: // type MyController struct { // web.Controller @@ -431,7 +431,7 @@ func (p *ControllerRegister) RouterOptions(pattern string, f interface{}) { p.AddRouterMethod(http.MethodOptions, pattern, f) } -// RouterAny add post method +// RouterAny add all method // usage: // type MyController struct { // web.Controller @@ -467,8 +467,20 @@ func (p *ControllerRegister) AddRouterMethod(method, pattern string, f interface route.routerType = routerTypeBeego route.sessionOn = p.cfg.WebConfig.Session.SessionOn route.controllerType = ct - route.methods = map[string]string{method: methodName} - p.addToRouter(method, pattern, route) + + methods := make(map[string]string) + if method == "*" { + for val := range HTTPMETHOD { + methods[val] = methodName + } + } else { + methods[method] = methodName + } + route.methods = methods + + for method, _ := range methods { + p.addToRouter(method, pattern, route) + } } // get reflect controller type and method by controller method expression diff --git a/server/web/router_test.go b/server/web/router_test.go index 474405e8..9e5ee79d 100644 --- a/server/web/router_test.go +++ b/server/web/router_test.go @@ -16,6 +16,7 @@ package web import ( "bytes" + "fmt" "net/http" "net/http/httptest" "strings" @@ -34,6 +35,12 @@ func (ptc *PrefixTestController) PrefixList() { ptc.Ctx.Output.Body([]byte("i am list in prefix test")) } +type TestControllerWithInterface struct { +} + +func (m TestControllerWithInterface) Ping() { +} + type TestController struct { Controller } @@ -95,7 +102,7 @@ func (jc *JSONController) Get() { jc.Ctx.Output.Body([]byte("ok")) } -func TestPrefixUrlFor(t *testing.T){ +func TestPrefixUrlFor(t *testing.T) { handler := NewControllerRegister() handler.Add("/my/prefix/list", &PrefixTestController{}, WithRouterMethods(&PrefixTestController{}, "get:PrefixList")) @@ -828,3 +835,161 @@ func TestRouterSessionSet(t *testing.T) { } } + +func TestRouterRouterGet(t *testing.T) { + r, _ := http.NewRequest(http.MethodGet, "/user", nil) + w := httptest.NewRecorder() + + handler := NewControllerRegister() + handler.RouterGet("/user", ExampleController.Ping) + handler.ServeHTTP(w, r) + if w.Body.String() != exampleBody { + t.Errorf("TestRouterRouterGet can't run") + } +} + +func TestRouterRouterPost(t *testing.T) { + r, _ := http.NewRequest(http.MethodPost, "/user", nil) + w := httptest.NewRecorder() + + handler := NewControllerRegister() + handler.RouterPost("/user", ExampleController.Ping) + handler.ServeHTTP(w, r) + if w.Body.String() != exampleBody { + t.Errorf("TestRouterRouterPost can't run") + } +} + +func TestRouterRouterHead(t *testing.T) { + r, _ := http.NewRequest(http.MethodHead, "/user", nil) + w := httptest.NewRecorder() + + handler := NewControllerRegister() + handler.RouterHead("/user", ExampleController.Ping) + handler.ServeHTTP(w, r) + if w.Body.String() != exampleBody { + t.Errorf("TestRouterRouterHead can't run") + } +} + +func TestRouterRouterPut(t *testing.T) { + r, _ := http.NewRequest(http.MethodPut, "/user", nil) + w := httptest.NewRecorder() + + handler := NewControllerRegister() + handler.RouterPut("/user", ExampleController.Ping) + handler.ServeHTTP(w, r) + if w.Body.String() != exampleBody { + t.Errorf("TestRouterRouterPut can't run") + } +} + +func TestRouterRouterPatch(t *testing.T) { + r, _ := http.NewRequest(http.MethodPatch, "/user", nil) + w := httptest.NewRecorder() + + handler := NewControllerRegister() + handler.RouterPatch("/user", ExampleController.Ping) + handler.ServeHTTP(w, r) + if w.Body.String() != exampleBody { + t.Errorf("TestRouterRouterPatch can't run") + } +} + +func TestRouterRouterDelete(t *testing.T) { + r, _ := http.NewRequest(http.MethodDelete, "/user", nil) + w := httptest.NewRecorder() + + handler := NewControllerRegister() + handler.RouterDelete("/user", ExampleController.Ping) + handler.ServeHTTP(w, r) + if w.Body.String() != exampleBody { + t.Errorf("TestRouterRouterDelete can't run") + } +} + +func TestRouterRouterAny(t *testing.T) { + handler := NewControllerRegister() + handler.RouterAny("/user", ExampleController.Ping) + + for method, _ := range HTTPMETHOD { + w := httptest.NewRecorder() + r, _ := http.NewRequest(method, "/user", nil) + handler.ServeHTTP(w, r) + if w.Body.String() != exampleBody { + t.Errorf("TestRouterRouterAny can't run, get the response is " + w.Body.String()) + } + } +} + +func TestRouterAddRouterMethodPanicInvalidMethod(t *testing.T) { + method := "some random method" + message := "not support http method: " + strings.ToUpper(method) + defer func() { + err := recover() + if err != nil { //产生了panic异常 + errStr, ok := err.(string) + if ok && errStr == message { + return + } + } + t.Errorf(fmt.Sprintf("TestRouterAddRouterMethodPanicInvalidMethod failed: %v", err)) + }() + + handler := NewControllerRegister() + handler.AddRouterMethod(method, "/user", ExampleController.Ping) +} + +func TestRouterAddRouterMethodPanicNotAMethod(t *testing.T) { + method := http.MethodGet + message := "not a method" + defer func() { + err := recover() + if err != nil { //产生了panic异常 + errStr, ok := err.(string) + if ok && errStr == message { + return + } + } + t.Errorf(fmt.Sprintf("TestRouterAddRouterMethodPanicInvalidMethod failed: %v", err)) + }() + + handler := NewControllerRegister() + handler.AddRouterMethod(method, "/user", ExampleController{}) +} + +func TestRouterAddRouterMethodPanicNotPublicMethod(t *testing.T) { + method := http.MethodGet + message := "not a public method" + defer func() { + err := recover() + if err != nil { //产生了panic异常 + errStr, ok := err.(string) + if ok && errStr == message { + return + } + } + t.Errorf(fmt.Sprintf("TestRouterAddRouterMethodPanicInvalidMethod failed: %v", err)) + }() + + handler := NewControllerRegister() + handler.AddRouterMethod(method, "/user", ExampleController.ping) +} + +func TestRouterAddRouterMethodPanicNotImplementInterface(t *testing.T) { + method := http.MethodGet + message := "web.TestControllerWithInterface is not implemented ControllerInterface" + defer func() { + err := recover() + if err != nil { //产生了panic异常 + errStr, ok := err.(string) + if ok && errStr == message { + return + } + } + t.Errorf(fmt.Sprintf("TestRouterAddRouterMethodPanicInvalidNumberParamIn failed: %v", err)) + }() + + handler := NewControllerRegister() + handler.AddRouterMethod(method, "/user", TestControllerWithInterface.Ping) +} diff --git a/server/web/server.go b/server/web/server.go index b61b85de..be8ec228 100644 --- a/server/web/server.go +++ b/server/web/server.go @@ -503,7 +503,7 @@ func (app *HttpServer) RouterPost(rootpath string, f interface{}) *HttpServer { // RouterHead see HttpServer.RouterHead func RouterHead(rootpath string, f interface{}) { - BeeApp.RouterPost(rootpath, f) + BeeApp.RouterHead(rootpath, f) } // RouterHead used to register router for RouterHead method @@ -523,7 +523,7 @@ func (app *HttpServer) RouterHead(rootpath string, f interface{}) *HttpServer { // RouterPut see HttpServer.RouterPut func RouterPut(rootpath string, f interface{}) { - BeeApp.RouterPost(rootpath, f) + BeeApp.RouterPut(rootpath, f) } // RouterPut used to register router for RouterPut method @@ -603,7 +603,7 @@ func (app *HttpServer) RouterOptions(rootpath string, f interface{}) *HttpServer // RouterAny see HttpServer.RouterAny func RouterAny(rootpath string, f interface{}) { - BeeApp.RouterOptions(rootpath, f) + BeeApp.RouterAny(rootpath, f) } // RouterAny used to register router for RouterAny method diff --git a/server/web/server_test.go b/server/web/server_test.go index 0b0c601c..bdc5b008 100644 --- a/server/web/server_test.go +++ b/server/web/server_test.go @@ -15,6 +15,8 @@ package web import ( + "net/http" + "net/http/httptest" "testing" "github.com/stretchr/testify/assert" @@ -28,3 +30,82 @@ func TestNewHttpServerWithCfg(t *testing.T) { assert.Equal(t, "hello", BConfig.AppName) } + +func TestServerRouterGet(t *testing.T) { + r, _ := http.NewRequest(http.MethodGet, "/user", nil) + w := httptest.NewRecorder() + + RouterGet("/user", ExampleController.Ping) + BeeApp.Handlers.ServeHTTP(w, r) + if w.Body.String() != exampleBody { + t.Errorf("TestServerRouterGet can't run") + } +} + +func TestServerRouterPost(t *testing.T) { + r, _ := http.NewRequest(http.MethodPost, "/user", nil) + w := httptest.NewRecorder() + + RouterPost("/user", ExampleController.Ping) + BeeApp.Handlers.ServeHTTP(w, r) + if w.Body.String() != exampleBody { + t.Errorf("TestServerRouterPost can't run") + } +} + +func TestServerRouterHead(t *testing.T) { + r, _ := http.NewRequest(http.MethodHead, "/user", nil) + w := httptest.NewRecorder() + + RouterHead("/user", ExampleController.Ping) + BeeApp.Handlers.ServeHTTP(w, r) + if w.Body.String() != exampleBody { + t.Errorf("TestServerRouterHead can't run") + } +} + +func TestServerRouterPut(t *testing.T) { + r, _ := http.NewRequest(http.MethodPut, "/user", nil) + w := httptest.NewRecorder() + + RouterPut("/user", ExampleController.Ping) + BeeApp.Handlers.ServeHTTP(w, r) + if w.Body.String() != exampleBody { + t.Errorf("TestServerRouterPut can't run") + } +} + +func TestServerRouterPatch(t *testing.T) { + r, _ := http.NewRequest(http.MethodPatch, "/user", nil) + w := httptest.NewRecorder() + + RouterPatch("/user", ExampleController.Ping) + BeeApp.Handlers.ServeHTTP(w, r) + if w.Body.String() != exampleBody { + t.Errorf("TestServerRouterPatch can't run") + } +} + +func TestServerRouterDelete(t *testing.T) { + r, _ := http.NewRequest(http.MethodDelete, "/user", nil) + w := httptest.NewRecorder() + + RouterDelete("/user", ExampleController.Ping) + BeeApp.Handlers.ServeHTTP(w, r) + if w.Body.String() != exampleBody { + t.Errorf("TestServerRouterDelete can't run") + } +} + +func TestServerRouterAny(t *testing.T) { + RouterAny("/user", ExampleController.Ping) + + for method, _ := range HTTPMETHOD { + r, _ := http.NewRequest(method, "/user", nil) + w := httptest.NewRecorder() + BeeApp.Handlers.ServeHTTP(w, r) + if w.Body.String() != exampleBody { + t.Errorf("TestServerRouterAny can't run") + } + } +} From 5b46a08b796e298e0b5d8155eb784d9548d495fe Mon Sep 17 00:00:00 2001 From: Jason li Date: Thu, 7 Jan 2021 21:38:50 +0800 Subject: [PATCH 4/8] fix lint and fix test case --- server/web/namespace_test.go | 95 +++++++++++++++++++----------------- server/web/router.go | 2 +- server/web/router_test.go | 2 +- server/web/server_test.go | 2 +- 4 files changed, 54 insertions(+), 47 deletions(-) diff --git a/server/web/namespace_test.go b/server/web/namespace_test.go index 2bf2480e..3e1f7a8a 100644 --- a/server/web/namespace_test.go +++ b/server/web/namespace_test.go @@ -15,6 +15,7 @@ package web import ( + "fmt" "net/http" "net/http/httptest" "strconv" @@ -30,11 +31,17 @@ type ExampleController struct { } func (m ExampleController) Ping() { - m.Ctx.Output.Body([]byte(exampleBody)) + err := m.Ctx.Output.Body([]byte(exampleBody)) + if err != nil { + fmt.Println(err) + } } func (m ExampleController) ping() { - m.Ctx.Output.Body([]byte(exampleBody)) + err := m.Ctx.Output.Body([]byte(exampleBody)) + if err != nil { + fmt.Println(err) + } } func TestNamespaceGet(t *testing.T) { @@ -182,10 +189,10 @@ func TestNamespaceInside(t *testing.T) { } func TestNamespaceRouterGet(t *testing.T) { - r, _ := http.NewRequest(http.MethodGet, "/v1/user", nil) + r, _ := http.NewRequest(http.MethodGet, "/router/user", nil) w := httptest.NewRecorder() - ns := NewNamespace("/v1") + ns := NewNamespace("/router") ns.RouterGet("/user", ExampleController.Ping) AddNamespace(ns) BeeApp.Handlers.ServeHTTP(w, r) @@ -195,10 +202,10 @@ func TestNamespaceRouterGet(t *testing.T) { } func TestNamespaceRouterPost(t *testing.T) { - r, _ := http.NewRequest(http.MethodPost, "/v1/user", nil) + r, _ := http.NewRequest(http.MethodPost, "/router/user", nil) w := httptest.NewRecorder() - ns := NewNamespace("/v1") + ns := NewNamespace("/router") ns.RouterPost("/user", ExampleController.Ping) AddNamespace(ns) BeeApp.Handlers.ServeHTTP(w, r) @@ -208,10 +215,10 @@ func TestNamespaceRouterPost(t *testing.T) { } func TestNamespaceRouterDelete(t *testing.T) { - r, _ := http.NewRequest(http.MethodDelete, "/v1/user", nil) + r, _ := http.NewRequest(http.MethodDelete, "/router/user", nil) w := httptest.NewRecorder() - ns := NewNamespace("/v1") + ns := NewNamespace("/router") ns.RouterDelete("/user", ExampleController.Ping) AddNamespace(ns) BeeApp.Handlers.ServeHTTP(w, r) @@ -221,10 +228,10 @@ func TestNamespaceRouterDelete(t *testing.T) { } func TestNamespaceRouterPut(t *testing.T) { - r, _ := http.NewRequest(http.MethodPut, "/v1/user", nil) + r, _ := http.NewRequest(http.MethodPut, "/router/user", nil) w := httptest.NewRecorder() - ns := NewNamespace("/v1") + ns := NewNamespace("/router") ns.RouterPut("/user", ExampleController.Ping) AddNamespace(ns) BeeApp.Handlers.ServeHTTP(w, r) @@ -234,10 +241,10 @@ func TestNamespaceRouterPut(t *testing.T) { } func TestNamespaceRouterHead(t *testing.T) { - r, _ := http.NewRequest(http.MethodHead, "/v1/user", nil) + r, _ := http.NewRequest(http.MethodHead, "/router/user", nil) w := httptest.NewRecorder() - ns := NewNamespace("/v1") + ns := NewNamespace("/router") ns.RouterHead("/user", ExampleController.Ping) AddNamespace(ns) BeeApp.Handlers.ServeHTTP(w, r) @@ -247,10 +254,10 @@ func TestNamespaceRouterHead(t *testing.T) { } func TestNamespaceRouterOptions(t *testing.T) { - r, _ := http.NewRequest(http.MethodOptions, "/v1/user", nil) + r, _ := http.NewRequest(http.MethodOptions, "/router/user", nil) w := httptest.NewRecorder() - ns := NewNamespace("/v1") + ns := NewNamespace("/router") ns.RouterOptions("/user", ExampleController.Ping) AddNamespace(ns) BeeApp.Handlers.ServeHTTP(w, r) @@ -260,10 +267,10 @@ func TestNamespaceRouterOptions(t *testing.T) { } func TestNamespaceRouterPatch(t *testing.T) { - r, _ := http.NewRequest(http.MethodPatch, "/v1/user", nil) + r, _ := http.NewRequest(http.MethodPatch, "/router/user", nil) w := httptest.NewRecorder() - ns := NewNamespace("/v1") + ns := NewNamespace("/router") ns.RouterPatch("/user", ExampleController.Ping) AddNamespace(ns) BeeApp.Handlers.ServeHTTP(w, r) @@ -273,13 +280,13 @@ func TestNamespaceRouterPatch(t *testing.T) { } func TestNamespaceRouterAny(t *testing.T) { - ns := NewNamespace("/v1") + ns := NewNamespace("/router") ns.RouterAny("/user", ExampleController.Ping) AddNamespace(ns) - for method, _ := range HTTPMETHOD { + for method := range HTTPMETHOD { w := httptest.NewRecorder() - r, _ := http.NewRequest(method, "/v1/user", nil) + r, _ := http.NewRequest(method, "/router/user", nil) BeeApp.Handlers.ServeHTTP(w, r) if w.Body.String() != exampleBody { t.Errorf("TestNamespaceRouterAny can't run, get the response is " + w.Body.String()) @@ -288,107 +295,107 @@ func TestNamespaceRouterAny(t *testing.T) { } func TestNamespaceNSRouterGet(t *testing.T) { - r, _ := http.NewRequest(http.MethodGet, "/v1/user", nil) + r, _ := http.NewRequest(http.MethodGet, "/router/user", nil) w := httptest.NewRecorder() - ns := NewNamespace("/v1") + ns := NewNamespace("/router") NSRouterGet("/user", ExampleController.Ping)(ns) AddNamespace(ns) BeeApp.Handlers.ServeHTTP(w, r) if w.Body.String() != exampleBody { - t.Errorf("TestNamespaceRouterGet can't run, get the response is " + w.Body.String()) + t.Errorf("TestNamespaceNSRouterGet can't run, get the response is " + w.Body.String()) } } func TestNamespaceNSRouterPost(t *testing.T) { - r, _ := http.NewRequest(http.MethodPost, "/v1/user", nil) + r, _ := http.NewRequest(http.MethodPost, "/router/user", nil) w := httptest.NewRecorder() - ns := NewNamespace("/v1") + ns := NewNamespace("/router") NSRouterPost("/user", ExampleController.Ping)(ns) AddNamespace(ns) BeeApp.Handlers.ServeHTTP(w, r) if w.Body.String() != exampleBody { - t.Errorf("TestNamespaceRouterPost can't run, get the response is " + w.Body.String()) + t.Errorf("TestNamespaceNSRouterPost can't run, get the response is " + w.Body.String()) } } func TestNamespaceNSRouterDelete(t *testing.T) { - r, _ := http.NewRequest(http.MethodDelete, "/v1/user", nil) + r, _ := http.NewRequest(http.MethodDelete, "/router/user", nil) w := httptest.NewRecorder() - ns := NewNamespace("/v1") + ns := NewNamespace("/router") NSRouterDelete("/user", ExampleController.Ping)(ns) AddNamespace(ns) BeeApp.Handlers.ServeHTTP(w, r) if w.Body.String() != exampleBody { - t.Errorf("TestNamespaceRouterDelete can't run, get the response is " + w.Body.String()) + t.Errorf("TestNamespaceNSRouterDelete can't run, get the response is " + w.Body.String()) } } func TestNamespaceNSRouterPut(t *testing.T) { - r, _ := http.NewRequest(http.MethodPut, "/v1/user", nil) + r, _ := http.NewRequest(http.MethodPut, "/router/user", nil) w := httptest.NewRecorder() - ns := NewNamespace("/v1") + ns := NewNamespace("/router") NSRouterPut("/user", ExampleController.Ping)(ns) AddNamespace(ns) BeeApp.Handlers.ServeHTTP(w, r) if w.Body.String() != exampleBody { - t.Errorf("TestNamespaceRouterPut can't run, get the response is " + w.Body.String()) + t.Errorf("TestNamespaceNSRouterPut can't run, get the response is " + w.Body.String()) } } func TestNamespaceNSRouterHead(t *testing.T) { - r, _ := http.NewRequest(http.MethodHead, "/v1/user", nil) + r, _ := http.NewRequest(http.MethodHead, "/router/user", nil) w := httptest.NewRecorder() - ns := NewNamespace("/v1") + ns := NewNamespace("/router") NSRouterHead("/user", ExampleController.Ping)(ns) AddNamespace(ns) BeeApp.Handlers.ServeHTTP(w, r) if w.Body.String() != exampleBody { - t.Errorf("TestNamespaceRouterHead can't run, get the response is " + w.Body.String()) + t.Errorf("TestNamespaceNSRouterHead can't run, get the response is " + w.Body.String()) } } func TestNamespaceNSRouterOptions(t *testing.T) { - r, _ := http.NewRequest(http.MethodOptions, "/v1/user", nil) + r, _ := http.NewRequest(http.MethodOptions, "/router/user", nil) w := httptest.NewRecorder() - ns := NewNamespace("/v1") + ns := NewNamespace("/router") NSRouterOptions("/user", ExampleController.Ping)(ns) AddNamespace(ns) BeeApp.Handlers.ServeHTTP(w, r) if w.Body.String() != exampleBody { - t.Errorf("TestNamespaceRouterOptions can't run, get the response is " + w.Body.String()) + t.Errorf("TestNamespaceNSRouterOptions can't run, get the response is " + w.Body.String()) } } func TestNamespaceNSRouterPatch(t *testing.T) { - r, _ := http.NewRequest(http.MethodPatch, "/v1/user", nil) + r, _ := http.NewRequest(http.MethodPatch, "/router/user", nil) w := httptest.NewRecorder() - ns := NewNamespace("/v1") + ns := NewNamespace("/router") NSRouterPatch("/user", ExampleController.Ping)(ns) AddNamespace(ns) BeeApp.Handlers.ServeHTTP(w, r) if w.Body.String() != exampleBody { - t.Errorf("TestNamespaceRouterPatch can't run, get the response is " + w.Body.String()) + t.Errorf("TestNamespaceNSRouterPatch can't run, get the response is " + w.Body.String()) } } func TestNamespaceNSRouterAny(t *testing.T) { - ns := NewNamespace("/v1") + ns := NewNamespace("/router") NSRouterAny("/user", ExampleController.Ping)(ns) AddNamespace(ns) - for method, _ := range HTTPMETHOD { + for method := range HTTPMETHOD { w := httptest.NewRecorder() - r, _ := http.NewRequest(method, "/v1/user", nil) + r, _ := http.NewRequest(method, "/router/user", nil) BeeApp.Handlers.ServeHTTP(w, r) if w.Body.String() != exampleBody { - t.Errorf("TestNamespaceRouterAny can't run, get the response is " + w.Body.String()) + t.Errorf("TestNamespaceNSRouterAny can't run, get the response is " + w.Body.String()) } } } diff --git a/server/web/router.go b/server/web/router.go index 0eb93d5a..09988bf7 100644 --- a/server/web/router.go +++ b/server/web/router.go @@ -478,7 +478,7 @@ func (p *ControllerRegister) AddRouterMethod(method, pattern string, f interface } route.methods = methods - for method, _ := range methods { + for method := range methods { p.addToRouter(method, pattern, route) } } diff --git a/server/web/router_test.go b/server/web/router_test.go index 9e5ee79d..22eac660 100644 --- a/server/web/router_test.go +++ b/server/web/router_test.go @@ -912,7 +912,7 @@ func TestRouterRouterAny(t *testing.T) { handler := NewControllerRegister() handler.RouterAny("/user", ExampleController.Ping) - for method, _ := range HTTPMETHOD { + for method := range HTTPMETHOD { w := httptest.NewRecorder() r, _ := http.NewRequest(method, "/user", nil) handler.ServeHTTP(w, r) diff --git a/server/web/server_test.go b/server/web/server_test.go index bdc5b008..0734be77 100644 --- a/server/web/server_test.go +++ b/server/web/server_test.go @@ -100,7 +100,7 @@ func TestServerRouterDelete(t *testing.T) { func TestServerRouterAny(t *testing.T) { RouterAny("/user", ExampleController.Ping) - for method, _ := range HTTPMETHOD { + for method := range HTTPMETHOD { r, _ := http.NewRequest(method, "/user", nil) w := httptest.NewRecorder() BeeApp.Handlers.ServeHTTP(w, r) From 0429838598b21fc45cf3b66f2c48cbbad507d0ae Mon Sep 17 00:00:00 2001 From: Jason li Date: Mon, 11 Jan 2021 09:56:48 +0800 Subject: [PATCH 5/8] refactor code for add beego type router --- server/web/router.go | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/server/web/router.go b/server/web/router.go index 09988bf7..f321a031 100644 --- a/server/web/router.go +++ b/server/web/router.go @@ -455,13 +455,18 @@ func (p *ControllerRegister) RouterAny(pattern string, f interface{}) { // } // // AddRouterMethod("get","/api/:id", MyController.Ping) -func (p *ControllerRegister) AddRouterMethod(method, pattern string, f interface{}) { - method = strings.ToUpper(method) - if method != "*" && !HTTPMETHOD[method] { - panic("not support http method: " + method) +func (p *ControllerRegister) AddRouterMethod(httpMethod, pattern string, f interface{}) { + httpMethod = strings.ToUpper(httpMethod) + if httpMethod != "*" && !HTTPMETHOD[httpMethod] { + panic("not support http method: " + httpMethod) } ct, methodName := getReflectTypeAndMethod(f) + p.addBeegoTypeRouter(ct, methodName, httpMethod, pattern) +} + +// addBeegoTypeRouter add beego type router +func (p *ControllerRegister) addBeegoTypeRouter(ct reflect.Type, ctMethod, httpMethod, pattern string) { route := &ControllerInfo{} route.pattern = pattern route.routerType = routerTypeBeego @@ -469,18 +474,16 @@ func (p *ControllerRegister) AddRouterMethod(method, pattern string, f interface route.controllerType = ct methods := make(map[string]string) - if method == "*" { + if httpMethod == "*" { for val := range HTTPMETHOD { - methods[val] = methodName + methods[val] = ctMethod } } else { - methods[method] = methodName + methods[httpMethod] = ctMethod } route.methods = methods - for method := range methods { - p.addToRouter(method, pattern, route) - } + p.addRouterForMethod(route) } // get reflect controller type and method by controller method expression From f50476e063232ed93534d5b0c6dc02857bb18483 Mon Sep 17 00:00:00 2001 From: Jason li Date: Mon, 11 Jan 2021 10:13:57 +0800 Subject: [PATCH 6/8] add change log --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 222046bc..b177e912 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,4 +7,5 @@ - Using fixed name `commentRouter.go` as generated file name. [4385](https://github.com/beego/beego/pull/4385) - Fix 4383: ORM Adapter produces panic when using orm.RegisterModelWithPrefix. [4386](https://github.com/beego/beego/pull/4386) - Support 4144: Add new api for order by for supporting multiple way to query [4294](https://github.com/beego/beego/pull/4294) -- Support session Filter chain. [4404](https://github.com/beego/beego/pull/4404) \ No newline at end of file +- Support session Filter chain. [4404](https://github.com/beego/beego/pull/4404) +- Feature issue #4402 finish router get example. [4416](https://github.com/beego/beego/pull/4416) \ No newline at end of file From d2cfd884c804db28b4152b9f126297d4c8b84637 Mon Sep 17 00:00:00 2001 From: Jason li Date: Mon, 11 Jan 2021 10:41:35 +0800 Subject: [PATCH 7/8] fix sonar cloud problems --- server/web/namespace_test.go | 102 ++++++++++++++++++----------------- server/web/router_test.go | 7 +-- 2 files changed, 58 insertions(+), 51 deletions(-) diff --git a/server/web/namespace_test.go b/server/web/namespace_test.go index 3e1f7a8a..84e7aca5 100644 --- a/server/web/namespace_test.go +++ b/server/web/namespace_test.go @@ -24,7 +24,13 @@ import ( "github.com/beego/beego/v2/server/web/context" ) -const exampleBody = "hello world" +const ( + exampleBody = "hello world" + + nsNamespace = "/router" + nsPath = "/user" + nsNamespacePath = "/router/user" +) type ExampleController struct { Controller @@ -38,7 +44,7 @@ func (m ExampleController) Ping() { } func (m ExampleController) ping() { - err := m.Ctx.Output.Body([]byte(exampleBody)) + err := m.Ctx.Output.Body([]byte("ping method")) if err != nil { fmt.Println(err) } @@ -189,11 +195,11 @@ func TestNamespaceInside(t *testing.T) { } func TestNamespaceRouterGet(t *testing.T) { - r, _ := http.NewRequest(http.MethodGet, "/router/user", nil) + r, _ := http.NewRequest(http.MethodGet, nsNamespacePath, nil) w := httptest.NewRecorder() - ns := NewNamespace("/router") - ns.RouterGet("/user", ExampleController.Ping) + ns := NewNamespace(nsNamespace) + ns.RouterGet(nsPath, ExampleController.Ping) AddNamespace(ns) BeeApp.Handlers.ServeHTTP(w, r) if w.Body.String() != exampleBody { @@ -202,11 +208,11 @@ func TestNamespaceRouterGet(t *testing.T) { } func TestNamespaceRouterPost(t *testing.T) { - r, _ := http.NewRequest(http.MethodPost, "/router/user", nil) + r, _ := http.NewRequest(http.MethodPost, nsNamespacePath, nil) w := httptest.NewRecorder() - ns := NewNamespace("/router") - ns.RouterPost("/user", ExampleController.Ping) + ns := NewNamespace(nsNamespace) + ns.RouterPost(nsPath, ExampleController.Ping) AddNamespace(ns) BeeApp.Handlers.ServeHTTP(w, r) if w.Body.String() != exampleBody { @@ -215,11 +221,11 @@ func TestNamespaceRouterPost(t *testing.T) { } func TestNamespaceRouterDelete(t *testing.T) { - r, _ := http.NewRequest(http.MethodDelete, "/router/user", nil) + r, _ := http.NewRequest(http.MethodDelete, nsNamespacePath, nil) w := httptest.NewRecorder() - ns := NewNamespace("/router") - ns.RouterDelete("/user", ExampleController.Ping) + ns := NewNamespace(nsNamespace) + ns.RouterDelete(nsPath, ExampleController.Ping) AddNamespace(ns) BeeApp.Handlers.ServeHTTP(w, r) if w.Body.String() != exampleBody { @@ -228,11 +234,11 @@ func TestNamespaceRouterDelete(t *testing.T) { } func TestNamespaceRouterPut(t *testing.T) { - r, _ := http.NewRequest(http.MethodPut, "/router/user", nil) + r, _ := http.NewRequest(http.MethodPut, nsNamespacePath, nil) w := httptest.NewRecorder() - ns := NewNamespace("/router") - ns.RouterPut("/user", ExampleController.Ping) + ns := NewNamespace(nsNamespace) + ns.RouterPut(nsPath, ExampleController.Ping) AddNamespace(ns) BeeApp.Handlers.ServeHTTP(w, r) if w.Body.String() != exampleBody { @@ -241,11 +247,11 @@ func TestNamespaceRouterPut(t *testing.T) { } func TestNamespaceRouterHead(t *testing.T) { - r, _ := http.NewRequest(http.MethodHead, "/router/user", nil) + r, _ := http.NewRequest(http.MethodHead, nsNamespacePath, nil) w := httptest.NewRecorder() - ns := NewNamespace("/router") - ns.RouterHead("/user", ExampleController.Ping) + ns := NewNamespace(nsNamespace) + ns.RouterHead(nsPath, ExampleController.Ping) AddNamespace(ns) BeeApp.Handlers.ServeHTTP(w, r) if w.Body.String() != exampleBody { @@ -254,11 +260,11 @@ func TestNamespaceRouterHead(t *testing.T) { } func TestNamespaceRouterOptions(t *testing.T) { - r, _ := http.NewRequest(http.MethodOptions, "/router/user", nil) + r, _ := http.NewRequest(http.MethodOptions, nsNamespacePath, nil) w := httptest.NewRecorder() - ns := NewNamespace("/router") - ns.RouterOptions("/user", ExampleController.Ping) + ns := NewNamespace(nsNamespace) + ns.RouterOptions(nsPath, ExampleController.Ping) AddNamespace(ns) BeeApp.Handlers.ServeHTTP(w, r) if w.Body.String() != exampleBody { @@ -267,11 +273,11 @@ func TestNamespaceRouterOptions(t *testing.T) { } func TestNamespaceRouterPatch(t *testing.T) { - r, _ := http.NewRequest(http.MethodPatch, "/router/user", nil) + r, _ := http.NewRequest(http.MethodPatch, nsNamespacePath, nil) w := httptest.NewRecorder() - ns := NewNamespace("/router") - ns.RouterPatch("/user", ExampleController.Ping) + ns := NewNamespace(nsNamespace) + ns.RouterPatch(nsPath, ExampleController.Ping) AddNamespace(ns) BeeApp.Handlers.ServeHTTP(w, r) if w.Body.String() != exampleBody { @@ -280,13 +286,13 @@ func TestNamespaceRouterPatch(t *testing.T) { } func TestNamespaceRouterAny(t *testing.T) { - ns := NewNamespace("/router") - ns.RouterAny("/user", ExampleController.Ping) + ns := NewNamespace(nsNamespace) + ns.RouterAny(nsPath, ExampleController.Ping) AddNamespace(ns) for method := range HTTPMETHOD { w := httptest.NewRecorder() - r, _ := http.NewRequest(method, "/router/user", nil) + r, _ := http.NewRequest(method, nsNamespacePath, nil) BeeApp.Handlers.ServeHTTP(w, r) if w.Body.String() != exampleBody { t.Errorf("TestNamespaceRouterAny can't run, get the response is " + w.Body.String()) @@ -295,11 +301,11 @@ func TestNamespaceRouterAny(t *testing.T) { } func TestNamespaceNSRouterGet(t *testing.T) { - r, _ := http.NewRequest(http.MethodGet, "/router/user", nil) + r, _ := http.NewRequest(http.MethodGet, nsNamespacePath, nil) w := httptest.NewRecorder() - ns := NewNamespace("/router") - NSRouterGet("/user", ExampleController.Ping)(ns) + ns := NewNamespace(nsNamespace) + NSRouterGet(nsPath, ExampleController.Ping)(ns) AddNamespace(ns) BeeApp.Handlers.ServeHTTP(w, r) if w.Body.String() != exampleBody { @@ -308,11 +314,11 @@ func TestNamespaceNSRouterGet(t *testing.T) { } func TestNamespaceNSRouterPost(t *testing.T) { - r, _ := http.NewRequest(http.MethodPost, "/router/user", nil) + r, _ := http.NewRequest(http.MethodPost, nsNamespacePath, nil) w := httptest.NewRecorder() ns := NewNamespace("/router") - NSRouterPost("/user", ExampleController.Ping)(ns) + NSRouterPost(nsPath, ExampleController.Ping)(ns) AddNamespace(ns) BeeApp.Handlers.ServeHTTP(w, r) if w.Body.String() != exampleBody { @@ -321,11 +327,11 @@ func TestNamespaceNSRouterPost(t *testing.T) { } func TestNamespaceNSRouterDelete(t *testing.T) { - r, _ := http.NewRequest(http.MethodDelete, "/router/user", nil) + r, _ := http.NewRequest(http.MethodDelete, nsNamespacePath, nil) w := httptest.NewRecorder() - ns := NewNamespace("/router") - NSRouterDelete("/user", ExampleController.Ping)(ns) + ns := NewNamespace(nsNamespace) + NSRouterDelete(nsPath, ExampleController.Ping)(ns) AddNamespace(ns) BeeApp.Handlers.ServeHTTP(w, r) if w.Body.String() != exampleBody { @@ -334,11 +340,11 @@ func TestNamespaceNSRouterDelete(t *testing.T) { } func TestNamespaceNSRouterPut(t *testing.T) { - r, _ := http.NewRequest(http.MethodPut, "/router/user", nil) + r, _ := http.NewRequest(http.MethodPut, nsNamespacePath, nil) w := httptest.NewRecorder() - ns := NewNamespace("/router") - NSRouterPut("/user", ExampleController.Ping)(ns) + ns := NewNamespace(nsNamespace) + NSRouterPut(nsPath, ExampleController.Ping)(ns) AddNamespace(ns) BeeApp.Handlers.ServeHTTP(w, r) if w.Body.String() != exampleBody { @@ -347,11 +353,11 @@ func TestNamespaceNSRouterPut(t *testing.T) { } func TestNamespaceNSRouterHead(t *testing.T) { - r, _ := http.NewRequest(http.MethodHead, "/router/user", nil) + r, _ := http.NewRequest(http.MethodHead, nsNamespacePath, nil) w := httptest.NewRecorder() - ns := NewNamespace("/router") - NSRouterHead("/user", ExampleController.Ping)(ns) + ns := NewNamespace(nsNamespace) + NSRouterHead(nsPath, ExampleController.Ping)(ns) AddNamespace(ns) BeeApp.Handlers.ServeHTTP(w, r) if w.Body.String() != exampleBody { @@ -360,11 +366,11 @@ func TestNamespaceNSRouterHead(t *testing.T) { } func TestNamespaceNSRouterOptions(t *testing.T) { - r, _ := http.NewRequest(http.MethodOptions, "/router/user", nil) + r, _ := http.NewRequest(http.MethodOptions, nsNamespacePath, nil) w := httptest.NewRecorder() - ns := NewNamespace("/router") - NSRouterOptions("/user", ExampleController.Ping)(ns) + ns := NewNamespace(nsNamespace) + NSRouterOptions(nsPath, ExampleController.Ping)(ns) AddNamespace(ns) BeeApp.Handlers.ServeHTTP(w, r) if w.Body.String() != exampleBody { @@ -373,10 +379,10 @@ func TestNamespaceNSRouterOptions(t *testing.T) { } func TestNamespaceNSRouterPatch(t *testing.T) { - r, _ := http.NewRequest(http.MethodPatch, "/router/user", nil) + r, _ := http.NewRequest(http.MethodPatch, nsNamespacePath, nil) w := httptest.NewRecorder() - ns := NewNamespace("/router") + ns := NewNamespace(nsNamespace) NSRouterPatch("/user", ExampleController.Ping)(ns) AddNamespace(ns) BeeApp.Handlers.ServeHTTP(w, r) @@ -386,13 +392,13 @@ func TestNamespaceNSRouterPatch(t *testing.T) { } func TestNamespaceNSRouterAny(t *testing.T) { - ns := NewNamespace("/router") - NSRouterAny("/user", ExampleController.Ping)(ns) + ns := NewNamespace(nsNamespace) + NSRouterAny(nsPath, ExampleController.Ping)(ns) AddNamespace(ns) for method := range HTTPMETHOD { w := httptest.NewRecorder() - r, _ := http.NewRequest(method, "/router/user", nil) + r, _ := http.NewRequest(method, nsNamespacePath, nil) BeeApp.Handlers.ServeHTTP(w, r) if w.Body.String() != exampleBody { t.Errorf("TestNamespaceNSRouterAny can't run, get the response is " + w.Body.String()) diff --git a/server/web/router_test.go b/server/web/router_test.go index 22eac660..7b8ebb6c 100644 --- a/server/web/router_test.go +++ b/server/web/router_test.go @@ -39,6 +39,7 @@ type TestControllerWithInterface struct { } func (m TestControllerWithInterface) Ping() { + fmt.Println("pong") } type TestController struct { @@ -951,7 +952,7 @@ func TestRouterAddRouterMethodPanicNotAMethod(t *testing.T) { return } } - t.Errorf(fmt.Sprintf("TestRouterAddRouterMethodPanicInvalidMethod failed: %v", err)) + t.Errorf(fmt.Sprintf("TestRouterAddRouterMethodPanicNotAMethod failed: %v", err)) }() handler := NewControllerRegister() @@ -969,7 +970,7 @@ func TestRouterAddRouterMethodPanicNotPublicMethod(t *testing.T) { return } } - t.Errorf(fmt.Sprintf("TestRouterAddRouterMethodPanicInvalidMethod failed: %v", err)) + t.Errorf(fmt.Sprintf("TestRouterAddRouterMethodPanicNotPublicMethod failed: %v", err)) }() handler := NewControllerRegister() @@ -987,7 +988,7 @@ func TestRouterAddRouterMethodPanicNotImplementInterface(t *testing.T) { return } } - t.Errorf(fmt.Sprintf("TestRouterAddRouterMethodPanicInvalidNumberParamIn failed: %v", err)) + t.Errorf(fmt.Sprintf("TestRouterAddRouterMethodPanicNotImplementInterface failed: %v", err)) }() handler := NewControllerRegister() From 40d3954f429f074b9a8857e7230164b6030071e2 Mon Sep 17 00:00:00 2001 From: Jason li Date: Tue, 12 Jan 2021 12:44:18 +0800 Subject: [PATCH 8/8] change comment for --- server/web/namespace.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/web/namespace.go b/server/web/namespace.go index 0df72b01..96037b4d 100644 --- a/server/web/namespace.go +++ b/server/web/namespace.go @@ -421,7 +421,7 @@ func NSRouterGet(rootpath string, f interface{}) LinkNamespace { } } -// NSPost call Namespace RouterPost +// NSRouterPost call Namespace RouterPost func NSRouterPost(rootpath string, f interface{}) LinkNamespace { return func(ns *Namespace) { ns.RouterPost(rootpath, f)