Browse Source

add custom route register

bergquist 8 years ago
parent
commit
f842265388
2 changed files with 105 additions and 56 deletions
  1. 35 33
      pkg/api/route_register.go
  2. 70 23
      pkg/api/route_register_test.go

+ 35 - 33
pkg/api/route_register.go

@@ -6,18 +6,26 @@ import (
 	macaron "gopkg.in/macaron.v1"
 )
 
+type Router interface {
+	Route(pattern, method string, handlers ...macaron.Handler)
+}
+
 type RouteRegister interface {
 	Get(string, ...macaron.Handler)
 	Post(string, ...macaron.Handler)
 	Delete(string, ...macaron.Handler)
 	Put(string, ...macaron.Handler)
+
 	Group(string, func(RouteRegister), ...macaron.Handler)
+
+	Register(Router)
 }
 
-func newRouteRegister(rr *macaron.Router) RouteRegister {
+func newRouteRegister() RouteRegister {
 	return &routeRegister{
-		prefix: "",
-		routes: []route{},
+		prefix:         "",
+		routes:         []route{},
+		subfixHandlers: []macaron.Handler{},
 	}
 }
 
@@ -31,56 +39,50 @@ type routeRegister struct {
 	prefix         string
 	subfixHandlers []macaron.Handler
 	routes         []route
+	groups         []*routeRegister
 }
 
 func (rr *routeRegister) Group(pattern string, fn func(rr RouteRegister), handlers ...macaron.Handler) {
 	group := &routeRegister{
 		prefix:         rr.prefix + pattern,
-		subfixHandlers: handlers,
-		routes:         rr.routes,
+		subfixHandlers: append(rr.subfixHandlers, handlers...),
+		routes:         []route{},
 	}
 
 	fn(group)
+	rr.groups = append(rr.groups, group)
 }
 
-func (rr *routeRegister) Get(pattern string, handlers ...macaron.Handler) {
-	rr.routes = append(rr.routes, route{
-		method:   http.MethodGet,
-		pattern:  rr.prefix + pattern,
-		handlers: handlers,
-	})
-	println("get: get ", len(rr.routes))
-	rr.routes = rr.routes[:len(rr.routes)-1]
+func (rr *routeRegister) Register(router Router) {
+	for _, r := range rr.routes {
+		router.Route(r.pattern, r.method, r.handlers...)
+	}
+
+	for _, g := range rr.groups {
+		g.Register(router)
+	}
 }
 
-func (rr *routeRegister) Post(pattern string, handlers ...macaron.Handler) {
+func (rr *routeRegister) route(pattern, method string, handlers ...macaron.Handler) {
 	rr.routes = append(rr.routes, route{
-		method:   http.MethodPost,
+		method:   method,
 		pattern:  rr.prefix + pattern,
-		handlers: handlers,
+		handlers: append(rr.subfixHandlers, handlers...),
 	})
-	println("get: post ", len(rr.routes))
+}
 
-	rr.routes = rr.routes[:len(rr.routes)-1]
+func (rr *routeRegister) Get(pattern string, handlers ...macaron.Handler) {
+	rr.route(pattern, http.MethodGet, handlers...)
 }
 
-func (rr *routeRegister) Delete(pattern string, handlers ...macaron.Handler) {
-	rr.routes = append(rr.routes, route{
-		method:   http.MethodDelete,
-		pattern:  rr.prefix + pattern,
-		handlers: handlers,
-	})
-	println("get: delete ", len(rr.routes))
+func (rr *routeRegister) Post(pattern string, handlers ...macaron.Handler) {
+	rr.route(pattern, http.MethodPost, handlers...)
+}
 
-	rr.routes = rr.routes[:len(rr.routes)-1]
+func (rr *routeRegister) Delete(pattern string, handlers ...macaron.Handler) {
+	rr.route(pattern, http.MethodDelete, handlers...)
 }
 
 func (rr *routeRegister) Put(pattern string, handlers ...macaron.Handler) {
-	rr.routes = append(rr.routes, route{
-		method:   http.MethodPut,
-		pattern:  rr.prefix + pattern,
-		handlers: handlers,
-	})
-
-	rr.routes = rr.routes[:len(rr.routes)-1]
+	rr.route(pattern, http.MethodPut, handlers...)
 }

+ 70 - 23
pkg/api/route_register_test.go

@@ -1,39 +1,86 @@
 package api
 
-import "testing"
+import (
+	"strconv"
+	"testing"
 
-func TestRouteRegister(t *testing.T) {
-
-	rr := &routeRegister{
-		prefix: "",
-		routes: []route{},
-	}
+	macaron "gopkg.in/macaron.v1"
+)
 
-	rr.Delete("/admin")
-	rr.Get("/down")
+type fakeRouter struct {
+	route []route
+}
 
-	rr.Group("/user", func(innerRR RouteRegister) {
-		innerRR.Delete("")
-		innerRR.Get("/friends")
+func (fr *fakeRouter) Route(pattern, method string, handlers ...macaron.Handler) {
+	fr.route = append(fr.route, route{
+		pattern:  pattern,
+		method:   method,
+		handlers: handlers,
 	})
+}
 
-	println("len", len(rr.routes))
-
-	if rr.routes[0].pattern != "/admin" && rr.routes[0].method != "DELETE" {
-		t.Errorf("expected first route to be DELETE /admin")
+func emptyHandlers(n int) []macaron.Handler {
+	res := []macaron.Handler{}
+	for i := 1; n >= i; i++ {
+		res = append(res, emptyHandler(strconv.Itoa(i)))
 	}
+	return res
+}
+
+func emptyHandler(name string) macaron.Handler {
+	return struct{ name string }{name: name}
+}
 
-	if rr.routes[1].pattern != "/down" && rr.routes[1].method != "GET" {
-		t.Errorf("expected first route to be GET /down")
+func TestRouteRegister(t *testing.T) {
+	testTable := []route{
+		{method: "DELETE", pattern: "/admin", handlers: emptyHandlers(1)},
+		{method: "GET", pattern: "/down", handlers: emptyHandlers(2)},
+		{method: "POST", pattern: "/user", handlers: emptyHandlers(1)},
+		{method: "PUT", pattern: "/user/friends", handlers: emptyHandlers(1)},
+		{method: "DELETE", pattern: "/user/admin", handlers: emptyHandlers(2)},
+		{method: "GET", pattern: "/user/admin/all", handlers: emptyHandlers(4)},
 	}
 
-	println("len", len(rr.routes))
+	// Setup
+	rr := newRouteRegister()
+
+	rr.Delete("/admin", emptyHandler("1"))
+	rr.Get("/down", emptyHandler("1"), emptyHandler("2"))
+
+	rr.Group("/user", func(user RouteRegister) {
+		user.Post("", emptyHandler("1"))
+		user.Put("/friends", emptyHandler("2"))
 
-	if rr.routes[2].pattern != "/user" && rr.routes[2].method != "DELETE" {
-		t.Errorf("expected first route to be DELETE /admin")
+		user.Group("/admin", func(admin RouteRegister) {
+			admin.Delete("", emptyHandler("3"))
+			admin.Get("/all", emptyHandler("3"), emptyHandler("4"), emptyHandler("5"))
+
+		}, emptyHandler("3"))
+	})
+
+	fr := &fakeRouter{}
+	rr.Register(fr)
+
+	// Validation
+	if len(fr.route) != len(testTable) {
+		t.Errorf("want %v routes, got %v", len(testTable), len(fr.route))
 	}
 
-	if rr.routes[3].pattern != "/user/friends" && rr.routes[3].method != "GET" {
-		t.Errorf("expected first route to be GET /down")
+	for i, _ := range testTable {
+		if testTable[i].method != fr.route[i].method {
+			t.Errorf("want %s got %v", testTable[i].method, fr.route[i].method)
+		}
+
+		if testTable[i].pattern != fr.route[i].pattern {
+			t.Errorf("want %s got %v", testTable[i].pattern, fr.route[i].pattern)
+		}
+
+		if len(testTable[i].handlers) != len(fr.route[i].handlers) {
+			t.Errorf("want %d handlers got %d handlers \ntestcase: %v\nroute: %v\n",
+				len(testTable[i].handlers),
+				len(fr.route[i].handlers),
+				testTable[i],
+				fr.route[i])
+		}
 	}
 }