1
0
mirror of https://github.com/labstack/echo.git synced 2025-11-27 22:38:25 +02:00
Signed-off-by: Vishal Rana <vr@labstack.com>
This commit is contained in:
Vishal Rana
2015-06-01 00:07:53 -07:00
parent b65641350e
commit aab17b9f69
4 changed files with 373 additions and 340 deletions

87
echo.go
View File

@@ -22,7 +22,6 @@ import (
type ( type (
Echo struct { Echo struct {
router *Router
prefix string prefix string
middleware []MiddlewareFunc middleware []MiddlewareFunc
http2 bool http2 bool
@@ -32,9 +31,15 @@ type (
httpErrorHandler HTTPErrorHandler httpErrorHandler HTTPErrorHandler
binder BindFunc binder BindFunc
renderer Renderer renderer Renderer
uris map[Handler]string
pool sync.Pool pool sync.Pool
debug bool debug bool
router *Router
}
Route struct {
Method string
Path string
Handler Handler
} }
HTTPError struct { HTTPError struct {
@@ -136,9 +141,7 @@ var (
// New creates an Echo instance. // New creates an Echo instance.
func New() (e *Echo) { func New() (e *Echo) {
e = &Echo{ e = &Echo{}
uris: make(map[Handler]string),
}
e.router = NewRouter(e) e.router = NewRouter(e)
e.pool.New = func() interface{} { e.pool.New = func() interface{} {
return NewContext(nil, new(Response), e) return NewContext(nil, new(Response), e)
@@ -295,8 +298,12 @@ func (e *Echo) WebSocket(path string, h HandlerFunc) {
func (e *Echo) add(method, path string, h Handler) { func (e *Echo) add(method, path string, h Handler) {
path = e.prefix + path path = e.prefix + path
e.router.Add(method, path, wrapHandler(h), e) e.router.Add(method, path, wrapHandler(h), e)
key := runtime.FuncForPC(reflect.ValueOf(h).Pointer()).Name() r := Route{
e.uris[key] = path Method: method,
Path: path,
Handler: runtime.FuncForPC(reflect.ValueOf(h).Pointer()).Name(),
}
e.router.routes = append(e.router.routes, r)
} }
// Index serves index file. // Index serves index file.
@@ -345,33 +352,6 @@ func serveFile(dir, file string, c *Context) error {
return nil return nil
} }
// URI generates a URI from handler.
func (e *Echo) URI(h Handler, params ...interface{}) string {
uri := new(bytes.Buffer)
lp := len(params)
n := 0
key := runtime.FuncForPC(reflect.ValueOf(h).Pointer()).Name()
if path, ok := e.uris[key]; ok {
for i, l := 0, len(path); i < l; i++ {
if path[i] == ':' && n < lp {
for ; i < l && path[i] != '/'; i++ {
}
uri.WriteString(fmt.Sprintf("%v", params[n]))
n++
}
if i < l {
uri.WriteByte(path[i])
}
}
}
return uri.String()
}
// URL is an alias for URI
func (e *Echo) URL(h Handler, params ...interface{}) string {
return e.URI(h, params...)
}
// Group creates a new sub router with prefix. It inherits all properties from // Group creates a new sub router with prefix. It inherits all properties from
// the parent. Passing middleware overrides parent middleware. // the parent. Passing middleware overrides parent middleware.
func (e *Echo) Group(prefix string, m ...Middleware) *Group { func (e *Echo) Group(prefix string, m ...Middleware) *Group {
@@ -384,6 +364,41 @@ func (e *Echo) Group(prefix string, m ...Middleware) *Group {
return g return g
} }
// URI generates a URI from handler.
func (e *Echo) URI(h Handler, params ...interface{}) string {
uri := new(bytes.Buffer)
pl := len(params)
n := 0
hn := runtime.FuncForPC(reflect.ValueOf(h).Pointer()).Name()
for _, r := range e.router.routes {
if r.Handler == hn {
for i, l := 0, len(r.Path); i < l; i++ {
if r.Path[i] == ':' && n < pl {
for ; i < l && r.Path[i] != '/'; i++ {
}
uri.WriteString(fmt.Sprintf("%v", params[n]))
n++
}
if i < l {
uri.WriteByte(r.Path[i])
}
}
break
}
}
return uri.String()
}
// URL is an alias for URI
func (e *Echo) URL(h Handler, params ...interface{}) string {
return e.URI(h, params...)
}
// Routes returns the registered routes.
func (e *Echo) Routes() []Route {
return e.router.routes
}
func (e *Echo) ServeHTTP(w http.ResponseWriter, r *http.Request) { func (e *Echo) ServeHTTP(w http.ResponseWriter, r *http.Request) {
c := e.pool.Get().(*Context) c := e.pool.Get().(*Context)
h, echo := e.router.Find(r.Method, r.URL.Path, c) h, echo := e.router.Find(r.Method, r.URL.Path, c)
@@ -401,8 +416,8 @@ func (e *Echo) ServeHTTP(w http.ResponseWriter, r *http.Request) {
} }
// Execute chain // Execute chain
if he := h(c); he != nil { if err := h(c); err != nil {
e.httpErrorHandler(he, c) e.httpErrorHandler(err, c)
} }
e.pool.Put(c) e.pool.Put(c)

View File

@@ -197,59 +197,6 @@ func TestEchoHandler(t *testing.T) {
}) })
} }
func TestEchoGroup(t *testing.T) {
e := New()
buf := new(bytes.Buffer)
e.Use(func(*Context) error {
buf.WriteString("0")
return nil
})
h := func(*Context) error { return nil }
//--------
// Routes
//--------
e.Get("/users", h)
// Group
g1 := e.Group("/group1")
g1.Use(func(*Context) error {
buf.WriteString("1")
return nil
})
g1.Get("/", h)
// Group with no parent middleware
g2 := e.Group("/group2", func(*Context) error {
buf.WriteString("2")
return nil
})
g2.Get("/", h)
// Nested groups
g3 := e.Group("/group3")
g4 := g3.Group("/group4")
g4.Get("/", func(c *Context) error {
return c.NoContent(http.StatusOK)
})
request(GET, "/users", e)
assert.Equal(t, "0", buf.String())
buf.Reset()
request(GET, "/group1/", e)
assert.Equal(t, "01", buf.String())
buf.Reset()
request(GET, "/group2/", e)
assert.Equal(t, "2", buf.String())
buf.Reset()
c, _ := request(GET, "/group3/group4/", e)
assert.Equal(t, http.StatusOK, c)
}
func TestEchoConnect(t *testing.T) { func TestEchoConnect(t *testing.T) {
e := New() e := New()
testMethod(t, CONNECT, "/", e) testMethod(t, CONNECT, "/", e)
@@ -335,6 +282,80 @@ func TestEchoURL(t *testing.T) {
assert.Equal(t, "/group/users/1/files/1", e.URL(getFile, "1", "1")) assert.Equal(t, "/group/users/1/files/1", e.URL(getFile, "1", "1"))
} }
func TestEchoRoutes(t *testing.T) {
e := New()
h := func(*Context) error { return nil }
routes := []Route{
{GET, "/users/:user/events", h},
{GET, "/users/:user/events/public", h},
{POST, "/repos/:owner/:repo/git/refs", h},
{POST, "/repos/:owner/:repo/git/tags", h},
}
for _, r := range routes {
e.add(r.Method, r.Path, h)
}
for i, r := range e.Routes() {
assert.Equal(t, routes[i].Method, r.Method)
assert.Equal(t, routes[i].Path, r.Path)
}
}
func TestEchoGroup(t *testing.T) {
e := New()
buf := new(bytes.Buffer)
e.Use(func(*Context) error {
buf.WriteString("0")
return nil
})
h := func(*Context) error { return nil }
//--------
// Routes
//--------
e.Get("/users", h)
// Group
g1 := e.Group("/group1")
g1.Use(func(*Context) error {
buf.WriteString("1")
return nil
})
g1.Get("/", h)
// Group with no parent middleware
g2 := e.Group("/group2", func(*Context) error {
buf.WriteString("2")
return nil
})
g2.Get("/", h)
// Nested groups
g3 := e.Group("/group3")
g4 := g3.Group("/group4")
g4.Get("/", func(c *Context) error {
return c.NoContent(http.StatusOK)
})
request(GET, "/users", e)
// println(len(e.middleware))
assert.Equal(t, "0", buf.String())
buf.Reset()
request(GET, "/group1/", e)
// println(len(g1.echo.middleware))
assert.Equal(t, "01", buf.String())
buf.Reset()
request(GET, "/group2/", e)
assert.Equal(t, "2", buf.String())
buf.Reset()
c, _ := request(GET, "/group3/group4/", e)
assert.Equal(t, http.StatusOK, c)
}
func TestEchoNotFound(t *testing.T) { func TestEchoNotFound(t *testing.T) {
e := New() e := New()
r, _ := http.NewRequest(GET, "/files", nil) r, _ := http.NewRequest(GET, "/files", nil)

View File

@@ -4,8 +4,9 @@ import "net/http"
type ( type (
Router struct { Router struct {
trees map[string]*node trees map[string]*node
echo *Echo routes []Route
echo *Echo
} }
node struct { node struct {
typ ntype typ ntype
@@ -29,8 +30,9 @@ const (
func NewRouter(e *Echo) (r *Router) { func NewRouter(e *Echo) (r *Router) {
r = &Router{ r = &Router{
trees: make(map[string]*node), trees: make(map[string]*node),
echo: e, routes: []Route{},
echo: e,
} }
for _, m := range methods { for _, m := range methods {
r.trees[m] = &node{ r.trees[m] = &node{

View File

@@ -9,274 +9,269 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
type route struct {
method string
path string
}
var ( var (
context = NewContext(nil, nil, New()) context = NewContext(nil, nil, New())
api = []route{ api = []Route{
// OAuth Authorizations // OAuth Authorizations
{"GET", "/authorizations"}, {"GET", "/authorizations", nil},
{"GET", "/authorizations/:id"}, {"GET", "/authorizations/:id", nil},
{"POST", "/authorizations"}, {"POST", "/authorizations", nil},
//{"PUT", "/authorizations/clients/:client_id"}, //{"PUT", "/authorizations/clients/:client_id", nil},
//{"PATCH", "/authorizations/:id"}, //{"PATCH", "/authorizations/:id", nil},
{"DELETE", "/authorizations/:id"}, {"DELETE", "/authorizations/:id", nil},
{"GET", "/applications/:client_id/tokens/:access_token"}, {"GET", "/applications/:client_id/tokens/:access_token", nil},
{"DELETE", "/applications/:client_id/tokens"}, {"DELETE", "/applications/:client_id/tokens", nil},
{"DELETE", "/applications/:client_id/tokens/:access_token"}, {"DELETE", "/applications/:client_id/tokens/:access_token", nil},
// Activity // Activity
{"GET", "/events"}, {"GET", "/events", nil},
{"GET", "/repos/:owner/:repo/events"}, {"GET", "/repos/:owner/:repo/events", nil},
{"GET", "/networks/:owner/:repo/events"}, {"GET", "/networks/:owner/:repo/events", nil},
{"GET", "/orgs/:org/events"}, {"GET", "/orgs/:org/events", nil},
{"GET", "/users/:user/received_events"}, {"GET", "/users/:user/received_events", nil},
{"GET", "/users/:user/received_events/public"}, {"GET", "/users/:user/received_events/public", nil},
{"GET", "/users/:user/events"}, {"GET", "/users/:user/events", nil},
{"GET", "/users/:user/events/public"}, {"GET", "/users/:user/events/public", nil},
{"GET", "/users/:user/events/orgs/:org"}, {"GET", "/users/:user/events/orgs/:org", nil},
{"GET", "/feeds"}, {"GET", "/feeds", nil},
{"GET", "/notifications"}, {"GET", "/notifications", nil},
{"GET", "/repos/:owner/:repo/notifications"}, {"GET", "/repos/:owner/:repo/notifications", nil},
{"PUT", "/notifications"}, {"PUT", "/notifications", nil},
{"PUT", "/repos/:owner/:repo/notifications"}, {"PUT", "/repos/:owner/:repo/notifications", nil},
{"GET", "/notifications/threads/:id"}, {"GET", "/notifications/threads/:id", nil},
//{"PATCH", "/notifications/threads/:id"}, //{"PATCH", "/notifications/threads/:id", nil},
{"GET", "/notifications/threads/:id/subscription"}, {"GET", "/notifications/threads/:id/subscription", nil},
{"PUT", "/notifications/threads/:id/subscription"}, {"PUT", "/notifications/threads/:id/subscription", nil},
{"DELETE", "/notifications/threads/:id/subscription"}, {"DELETE", "/notifications/threads/:id/subscription", nil},
{"GET", "/repos/:owner/:repo/stargazers"}, {"GET", "/repos/:owner/:repo/stargazers", nil},
{"GET", "/users/:user/starred"}, {"GET", "/users/:user/starred", nil},
{"GET", "/user/starred"}, {"GET", "/user/starred", nil},
{"GET", "/user/starred/:owner/:repo"}, {"GET", "/user/starred/:owner/:repo", nil},
{"PUT", "/user/starred/:owner/:repo"}, {"PUT", "/user/starred/:owner/:repo", nil},
{"DELETE", "/user/starred/:owner/:repo"}, {"DELETE", "/user/starred/:owner/:repo", nil},
{"GET", "/repos/:owner/:repo/subscribers"}, {"GET", "/repos/:owner/:repo/subscribers", nil},
{"GET", "/users/:user/subscriptions"}, {"GET", "/users/:user/subscriptions", nil},
{"GET", "/user/subscriptions"}, {"GET", "/user/subscriptions", nil},
{"GET", "/repos/:owner/:repo/subscription"}, {"GET", "/repos/:owner/:repo/subscription", nil},
{"PUT", "/repos/:owner/:repo/subscription"}, {"PUT", "/repos/:owner/:repo/subscription", nil},
{"DELETE", "/repos/:owner/:repo/subscription"}, {"DELETE", "/repos/:owner/:repo/subscription", nil},
{"GET", "/user/subscriptions/:owner/:repo"}, {"GET", "/user/subscriptions/:owner/:repo", nil},
{"PUT", "/user/subscriptions/:owner/:repo"}, {"PUT", "/user/subscriptions/:owner/:repo", nil},
{"DELETE", "/user/subscriptions/:owner/:repo"}, {"DELETE", "/user/subscriptions/:owner/:repo", nil},
// Gists // Gists
{"GET", "/users/:user/gists"}, {"GET", "/users/:user/gists", nil},
{"GET", "/gists"}, {"GET", "/gists", nil},
//{"GET", "/gists/public"}, //{"GET", "/gists/public", nil},
//{"GET", "/gists/starred"}, //{"GET", "/gists/starred", nil},
{"GET", "/gists/:id"}, {"GET", "/gists/:id", nil},
{"POST", "/gists"}, {"POST", "/gists", nil},
//{"PATCH", "/gists/:id"}, //{"PATCH", "/gists/:id", nil},
{"PUT", "/gists/:id/star"}, {"PUT", "/gists/:id/star", nil},
{"DELETE", "/gists/:id/star"}, {"DELETE", "/gists/:id/star", nil},
{"GET", "/gists/:id/star"}, {"GET", "/gists/:id/star", nil},
{"POST", "/gists/:id/forks"}, {"POST", "/gists/:id/forks", nil},
{"DELETE", "/gists/:id"}, {"DELETE", "/gists/:id", nil},
// Git Data // Git Data
{"GET", "/repos/:owner/:repo/git/blobs/:sha"}, {"GET", "/repos/:owner/:repo/git/blobs/:sha", nil},
{"POST", "/repos/:owner/:repo/git/blobs"}, {"POST", "/repos/:owner/:repo/git/blobs", nil},
{"GET", "/repos/:owner/:repo/git/commits/:sha"}, {"GET", "/repos/:owner/:repo/git/commits/:sha", nil},
{"POST", "/repos/:owner/:repo/git/commits"}, {"POST", "/repos/:owner/:repo/git/commits", nil},
//{"GET", "/repos/:owner/:repo/git/refs/*ref"}, //{"GET", "/repos/:owner/:repo/git/refs/*ref", nil},
{"GET", "/repos/:owner/:repo/git/refs"}, {"GET", "/repos/:owner/:repo/git/refs", nil},
{"POST", "/repos/:owner/:repo/git/refs"}, {"POST", "/repos/:owner/:repo/git/refs", nil},
//{"PATCH", "/repos/:owner/:repo/git/refs/*ref"}, //{"PATCH", "/repos/:owner/:repo/git/refs/*ref", nil},
//{"DELETE", "/repos/:owner/:repo/git/refs/*ref"}, //{"DELETE", "/repos/:owner/:repo/git/refs/*ref", nil},
{"GET", "/repos/:owner/:repo/git/tags/:sha"}, {"GET", "/repos/:owner/:repo/git/tags/:sha", nil},
{"POST", "/repos/:owner/:repo/git/tags"}, {"POST", "/repos/:owner/:repo/git/tags", nil},
{"GET", "/repos/:owner/:repo/git/trees/:sha"}, {"GET", "/repos/:owner/:repo/git/trees/:sha", nil},
{"POST", "/repos/:owner/:repo/git/trees"}, {"POST", "/repos/:owner/:repo/git/trees", nil},
// Issues // Issues
{"GET", "/issues"}, {"GET", "/issues", nil},
{"GET", "/user/issues"}, {"GET", "/user/issues", nil},
{"GET", "/orgs/:org/issues"}, {"GET", "/orgs/:org/issues", nil},
{"GET", "/repos/:owner/:repo/issues"}, {"GET", "/repos/:owner/:repo/issues", nil},
{"GET", "/repos/:owner/:repo/issues/:number"}, {"GET", "/repos/:owner/:repo/issues/:number", nil},
{"POST", "/repos/:owner/:repo/issues"}, {"POST", "/repos/:owner/:repo/issues", nil},
//{"PATCH", "/repos/:owner/:repo/issues/:number"}, //{"PATCH", "/repos/:owner/:repo/issues/:number", nil},
{"GET", "/repos/:owner/:repo/assignees"}, {"GET", "/repos/:owner/:repo/assignees", nil},
{"GET", "/repos/:owner/:repo/assignees/:assignee"}, {"GET", "/repos/:owner/:repo/assignees/:assignee", nil},
{"GET", "/repos/:owner/:repo/issues/:number/comments"}, {"GET", "/repos/:owner/:repo/issues/:number/comments", nil},
//{"GET", "/repos/:owner/:repo/issues/comments"}, //{"GET", "/repos/:owner/:repo/issues/comments", nil},
//{"GET", "/repos/:owner/:repo/issues/comments/:id"}, //{"GET", "/repos/:owner/:repo/issues/comments/:id", nil},
{"POST", "/repos/:owner/:repo/issues/:number/comments"}, {"POST", "/repos/:owner/:repo/issues/:number/comments", nil},
//{"PATCH", "/repos/:owner/:repo/issues/comments/:id"}, //{"PATCH", "/repos/:owner/:repo/issues/comments/:id", nil},
//{"DELETE", "/repos/:owner/:repo/issues/comments/:id"}, //{"DELETE", "/repos/:owner/:repo/issues/comments/:id", nil},
{"GET", "/repos/:owner/:repo/issues/:number/events"}, {"GET", "/repos/:owner/:repo/issues/:number/events", nil},
//{"GET", "/repos/:owner/:repo/issues/events"}, //{"GET", "/repos/:owner/:repo/issues/events", nil},
//{"GET", "/repos/:owner/:repo/issues/events/:id"}, //{"GET", "/repos/:owner/:repo/issues/events/:id", nil},
{"GET", "/repos/:owner/:repo/labels"}, {"GET", "/repos/:owner/:repo/labels", nil},
{"GET", "/repos/:owner/:repo/labels/:name"}, {"GET", "/repos/:owner/:repo/labels/:name", nil},
{"POST", "/repos/:owner/:repo/labels"}, {"POST", "/repos/:owner/:repo/labels", nil},
//{"PATCH", "/repos/:owner/:repo/labels/:name"}, //{"PATCH", "/repos/:owner/:repo/labels/:name", nil},
{"DELETE", "/repos/:owner/:repo/labels/:name"}, {"DELETE", "/repos/:owner/:repo/labels/:name", nil},
{"GET", "/repos/:owner/:repo/issues/:number/labels"}, {"GET", "/repos/:owner/:repo/issues/:number/labels", nil},
{"POST", "/repos/:owner/:repo/issues/:number/labels"}, {"POST", "/repos/:owner/:repo/issues/:number/labels", nil},
{"DELETE", "/repos/:owner/:repo/issues/:number/labels/:name"}, {"DELETE", "/repos/:owner/:repo/issues/:number/labels/:name", nil},
{"PUT", "/repos/:owner/:repo/issues/:number/labels"}, {"PUT", "/repos/:owner/:repo/issues/:number/labels", nil},
{"DELETE", "/repos/:owner/:repo/issues/:number/labels"}, {"DELETE", "/repos/:owner/:repo/issues/:number/labels", nil},
{"GET", "/repos/:owner/:repo/milestones/:number/labels"}, {"GET", "/repos/:owner/:repo/milestones/:number/labels", nil},
{"GET", "/repos/:owner/:repo/milestones"}, {"GET", "/repos/:owner/:repo/milestones", nil},
{"GET", "/repos/:owner/:repo/milestones/:number"}, {"GET", "/repos/:owner/:repo/milestones/:number", nil},
{"POST", "/repos/:owner/:repo/milestones"}, {"POST", "/repos/:owner/:repo/milestones", nil},
//{"PATCH", "/repos/:owner/:repo/milestones/:number"}, //{"PATCH", "/repos/:owner/:repo/milestones/:number", nil},
{"DELETE", "/repos/:owner/:repo/milestones/:number"}, {"DELETE", "/repos/:owner/:repo/milestones/:number", nil},
// Miscellaneous // Miscellaneous
{"GET", "/emojis"}, {"GET", "/emojis", nil},
{"GET", "/gitignore/templates"}, {"GET", "/gitignore/templates", nil},
{"GET", "/gitignore/templates/:name"}, {"GET", "/gitignore/templates/:name", nil},
{"POST", "/markdown"}, {"POST", "/markdown", nil},
{"POST", "/markdown/raw"}, {"POST", "/markdown/raw", nil},
{"GET", "/meta"}, {"GET", "/meta", nil},
{"GET", "/rate_limit"}, {"GET", "/rate_limit", nil},
// Organizations // Organizations
{"GET", "/users/:user/orgs"}, {"GET", "/users/:user/orgs", nil},
{"GET", "/user/orgs"}, {"GET", "/user/orgs", nil},
{"GET", "/orgs/:org"}, {"GET", "/orgs/:org", nil},
//{"PATCH", "/orgs/:org"}, //{"PATCH", "/orgs/:org", nil},
{"GET", "/orgs/:org/members"}, {"GET", "/orgs/:org/members", nil},
{"GET", "/orgs/:org/members/:user"}, {"GET", "/orgs/:org/members/:user", nil},
{"DELETE", "/orgs/:org/members/:user"}, {"DELETE", "/orgs/:org/members/:user", nil},
{"GET", "/orgs/:org/public_members"}, {"GET", "/orgs/:org/public_members", nil},
{"GET", "/orgs/:org/public_members/:user"}, {"GET", "/orgs/:org/public_members/:user", nil},
{"PUT", "/orgs/:org/public_members/:user"}, {"PUT", "/orgs/:org/public_members/:user", nil},
{"DELETE", "/orgs/:org/public_members/:user"}, {"DELETE", "/orgs/:org/public_members/:user", nil},
{"GET", "/orgs/:org/teams"}, {"GET", "/orgs/:org/teams", nil},
{"GET", "/teams/:id"}, {"GET", "/teams/:id", nil},
{"POST", "/orgs/:org/teams"}, {"POST", "/orgs/:org/teams", nil},
//{"PATCH", "/teams/:id"}, //{"PATCH", "/teams/:id", nil},
{"DELETE", "/teams/:id"}, {"DELETE", "/teams/:id", nil},
{"GET", "/teams/:id/members"}, {"GET", "/teams/:id/members", nil},
{"GET", "/teams/:id/members/:user"}, {"GET", "/teams/:id/members/:user", nil},
{"PUT", "/teams/:id/members/:user"}, {"PUT", "/teams/:id/members/:user", nil},
{"DELETE", "/teams/:id/members/:user"}, {"DELETE", "/teams/:id/members/:user", nil},
{"GET", "/teams/:id/repos"}, {"GET", "/teams/:id/repos", nil},
{"GET", "/teams/:id/repos/:owner/:repo"}, {"GET", "/teams/:id/repos/:owner/:repo", nil},
{"PUT", "/teams/:id/repos/:owner/:repo"}, {"PUT", "/teams/:id/repos/:owner/:repo", nil},
{"DELETE", "/teams/:id/repos/:owner/:repo"}, {"DELETE", "/teams/:id/repos/:owner/:repo", nil},
{"GET", "/user/teams"}, {"GET", "/user/teams", nil},
// Pull Requests // Pull Requests
{"GET", "/repos/:owner/:repo/pulls"}, {"GET", "/repos/:owner/:repo/pulls", nil},
{"GET", "/repos/:owner/:repo/pulls/:number"}, {"GET", "/repos/:owner/:repo/pulls/:number", nil},
{"POST", "/repos/:owner/:repo/pulls"}, {"POST", "/repos/:owner/:repo/pulls", nil},
//{"PATCH", "/repos/:owner/:repo/pulls/:number"}, //{"PATCH", "/repos/:owner/:repo/pulls/:number", nil},
{"GET", "/repos/:owner/:repo/pulls/:number/commits"}, {"GET", "/repos/:owner/:repo/pulls/:number/commits", nil},
{"GET", "/repos/:owner/:repo/pulls/:number/files"}, {"GET", "/repos/:owner/:repo/pulls/:number/files", nil},
{"GET", "/repos/:owner/:repo/pulls/:number/merge"}, {"GET", "/repos/:owner/:repo/pulls/:number/merge", nil},
{"PUT", "/repos/:owner/:repo/pulls/:number/merge"}, {"PUT", "/repos/:owner/:repo/pulls/:number/merge", nil},
{"GET", "/repos/:owner/:repo/pulls/:number/comments"}, {"GET", "/repos/:owner/:repo/pulls/:number/comments", nil},
//{"GET", "/repos/:owner/:repo/pulls/comments"}, //{"GET", "/repos/:owner/:repo/pulls/comments", nil},
//{"GET", "/repos/:owner/:repo/pulls/comments/:number"}, //{"GET", "/repos/:owner/:repo/pulls/comments/:number", nil},
{"PUT", "/repos/:owner/:repo/pulls/:number/comments"}, {"PUT", "/repos/:owner/:repo/pulls/:number/comments", nil},
//{"PATCH", "/repos/:owner/:repo/pulls/comments/:number"}, //{"PATCH", "/repos/:owner/:repo/pulls/comments/:number", nil},
//{"DELETE", "/repos/:owner/:repo/pulls/comments/:number"}, //{"DELETE", "/repos/:owner/:repo/pulls/comments/:number", nil},
// Repositories // Repositories
{"GET", "/user/repos"}, {"GET", "/user/repos", nil},
{"GET", "/users/:user/repos"}, {"GET", "/users/:user/repos", nil},
{"GET", "/orgs/:org/repos"}, {"GET", "/orgs/:org/repos", nil},
{"GET", "/repositories"}, {"GET", "/repositories", nil},
{"POST", "/user/repos"}, {"POST", "/user/repos", nil},
{"POST", "/orgs/:org/repos"}, {"POST", "/orgs/:org/repos", nil},
{"GET", "/repos/:owner/:repo"}, {"GET", "/repos/:owner/:repo", nil},
//{"PATCH", "/repos/:owner/:repo"}, //{"PATCH", "/repos/:owner/:repo", nil},
{"GET", "/repos/:owner/:repo/contributors"}, {"GET", "/repos/:owner/:repo/contributors", nil},
{"GET", "/repos/:owner/:repo/languages"}, {"GET", "/repos/:owner/:repo/languages", nil},
{"GET", "/repos/:owner/:repo/teams"}, {"GET", "/repos/:owner/:repo/teams", nil},
{"GET", "/repos/:owner/:repo/tags"}, {"GET", "/repos/:owner/:repo/tags", nil},
{"GET", "/repos/:owner/:repo/branches"}, {"GET", "/repos/:owner/:repo/branches", nil},
{"GET", "/repos/:owner/:repo/branches/:branch"}, {"GET", "/repos/:owner/:repo/branches/:branch", nil},
{"DELETE", "/repos/:owner/:repo"}, {"DELETE", "/repos/:owner/:repo", nil},
{"GET", "/repos/:owner/:repo/collaborators"}, {"GET", "/repos/:owner/:repo/collaborators", nil},
{"GET", "/repos/:owner/:repo/collaborators/:user"}, {"GET", "/repos/:owner/:repo/collaborators/:user", nil},
{"PUT", "/repos/:owner/:repo/collaborators/:user"}, {"PUT", "/repos/:owner/:repo/collaborators/:user", nil},
{"DELETE", "/repos/:owner/:repo/collaborators/:user"}, {"DELETE", "/repos/:owner/:repo/collaborators/:user", nil},
{"GET", "/repos/:owner/:repo/comments"}, {"GET", "/repos/:owner/:repo/comments", nil},
{"GET", "/repos/:owner/:repo/commits/:sha/comments"}, {"GET", "/repos/:owner/:repo/commits/:sha/comments", nil},
{"POST", "/repos/:owner/:repo/commits/:sha/comments"}, {"POST", "/repos/:owner/:repo/commits/:sha/comments", nil},
{"GET", "/repos/:owner/:repo/comments/:id"}, {"GET", "/repos/:owner/:repo/comments/:id", nil},
//{"PATCH", "/repos/:owner/:repo/comments/:id"}, //{"PATCH", "/repos/:owner/:repo/comments/:id", nil},
{"DELETE", "/repos/:owner/:repo/comments/:id"}, {"DELETE", "/repos/:owner/:repo/comments/:id", nil},
{"GET", "/repos/:owner/:repo/commits"}, {"GET", "/repos/:owner/:repo/commits", nil},
{"GET", "/repos/:owner/:repo/commits/:sha"}, {"GET", "/repos/:owner/:repo/commits/:sha", nil},
{"GET", "/repos/:owner/:repo/readme"}, {"GET", "/repos/:owner/:repo/readme", nil},
//{"GET", "/repos/:owner/:repo/contents/*path"}, //{"GET", "/repos/:owner/:repo/contents/*path", nil},
//{"PUT", "/repos/:owner/:repo/contents/*path"}, //{"PUT", "/repos/:owner/:repo/contents/*path", nil},
//{"DELETE", "/repos/:owner/:repo/contents/*path"}, //{"DELETE", "/repos/:owner/:repo/contents/*path", nil},
//{"GET", "/repos/:owner/:repo/:archive_format/:ref"}, //{"GET", "/repos/:owner/:repo/:archive_format/:ref", nil},
{"GET", "/repos/:owner/:repo/keys"}, {"GET", "/repos/:owner/:repo/keys", nil},
{"GET", "/repos/:owner/:repo/keys/:id"}, {"GET", "/repos/:owner/:repo/keys/:id", nil},
{"POST", "/repos/:owner/:repo/keys"}, {"POST", "/repos/:owner/:repo/keys", nil},
//{"PATCH", "/repos/:owner/:repo/keys/:id"}, //{"PATCH", "/repos/:owner/:repo/keys/:id", nil},
{"DELETE", "/repos/:owner/:repo/keys/:id"}, {"DELETE", "/repos/:owner/:repo/keys/:id", nil},
{"GET", "/repos/:owner/:repo/downloads"}, {"GET", "/repos/:owner/:repo/downloads", nil},
{"GET", "/repos/:owner/:repo/downloads/:id"}, {"GET", "/repos/:owner/:repo/downloads/:id", nil},
{"DELETE", "/repos/:owner/:repo/downloads/:id"}, {"DELETE", "/repos/:owner/:repo/downloads/:id", nil},
{"GET", "/repos/:owner/:repo/forks"}, {"GET", "/repos/:owner/:repo/forks", nil},
{"POST", "/repos/:owner/:repo/forks"}, {"POST", "/repos/:owner/:repo/forks", nil},
{"GET", "/repos/:owner/:repo/hooks"}, {"GET", "/repos/:owner/:repo/hooks", nil},
{"GET", "/repos/:owner/:repo/hooks/:id"}, {"GET", "/repos/:owner/:repo/hooks/:id", nil},
{"POST", "/repos/:owner/:repo/hooks"}, {"POST", "/repos/:owner/:repo/hooks", nil},
//{"PATCH", "/repos/:owner/:repo/hooks/:id"}, //{"PATCH", "/repos/:owner/:repo/hooks/:id", nil},
{"POST", "/repos/:owner/:repo/hooks/:id/tests"}, {"POST", "/repos/:owner/:repo/hooks/:id/tests", nil},
{"DELETE", "/repos/:owner/:repo/hooks/:id"}, {"DELETE", "/repos/:owner/:repo/hooks/:id", nil},
{"POST", "/repos/:owner/:repo/merges"}, {"POST", "/repos/:owner/:repo/merges", nil},
{"GET", "/repos/:owner/:repo/releases"}, {"GET", "/repos/:owner/:repo/releases", nil},
{"GET", "/repos/:owner/:repo/releases/:id"}, {"GET", "/repos/:owner/:repo/releases/:id", nil},
{"POST", "/repos/:owner/:repo/releases"}, {"POST", "/repos/:owner/:repo/releases", nil},
//{"PATCH", "/repos/:owner/:repo/releases/:id"}, //{"PATCH", "/repos/:owner/:repo/releases/:id", nil},
{"DELETE", "/repos/:owner/:repo/releases/:id"}, {"DELETE", "/repos/:owner/:repo/releases/:id", nil},
{"GET", "/repos/:owner/:repo/releases/:id/assets"}, {"GET", "/repos/:owner/:repo/releases/:id/assets", nil},
{"GET", "/repos/:owner/:repo/stats/contributors"}, {"GET", "/repos/:owner/:repo/stats/contributors", nil},
{"GET", "/repos/:owner/:repo/stats/commit_activity"}, {"GET", "/repos/:owner/:repo/stats/commit_activity", nil},
{"GET", "/repos/:owner/:repo/stats/code_frequency"}, {"GET", "/repos/:owner/:repo/stats/code_frequency", nil},
{"GET", "/repos/:owner/:repo/stats/participation"}, {"GET", "/repos/:owner/:repo/stats/participation", nil},
{"GET", "/repos/:owner/:repo/stats/punch_card"}, {"GET", "/repos/:owner/:repo/stats/punch_card", nil},
{"GET", "/repos/:owner/:repo/statuses/:ref"}, {"GET", "/repos/:owner/:repo/statuses/:ref", nil},
{"POST", "/repos/:owner/:repo/statuses/:ref"}, {"POST", "/repos/:owner/:repo/statuses/:ref", nil},
// Search // Search
{"GET", "/search/repositories"}, {"GET", "/search/repositories", nil},
{"GET", "/search/code"}, {"GET", "/search/code", nil},
{"GET", "/search/issues"}, {"GET", "/search/issues", nil},
{"GET", "/search/users"}, {"GET", "/search/users", nil},
{"GET", "/legacy/issues/search/:owner/:repository/:state/:keyword"}, {"GET", "/legacy/issues/search/:owner/:repository/:state/:keyword", nil},
{"GET", "/legacy/repos/search/:keyword"}, {"GET", "/legacy/repos/search/:keyword", nil},
{"GET", "/legacy/user/search/:keyword"}, {"GET", "/legacy/user/search/:keyword", nil},
{"GET", "/legacy/user/email/:email"}, {"GET", "/legacy/user/email/:email", nil},
// Users // Users
{"GET", "/users/:user"}, {"GET", "/users/:user", nil},
{"GET", "/user"}, {"GET", "/user", nil},
//{"PATCH", "/user"}, //{"PATCH", "/user", nil},
{"GET", "/users"}, {"GET", "/users", nil},
{"GET", "/user/emails"}, {"GET", "/user/emails", nil},
{"POST", "/user/emails"}, {"POST", "/user/emails", nil},
{"DELETE", "/user/emails"}, {"DELETE", "/user/emails", nil},
{"GET", "/users/:user/followers"}, {"GET", "/users/:user/followers", nil},
{"GET", "/user/followers"}, {"GET", "/user/followers", nil},
{"GET", "/users/:user/following"}, {"GET", "/users/:user/following", nil},
{"GET", "/user/following"}, {"GET", "/user/following", nil},
{"GET", "/user/following/:user"}, {"GET", "/user/following/:user", nil},
{"GET", "/users/:user/following/:target_user"}, {"GET", "/users/:user/following/:target_user", nil},
{"PUT", "/user/following/:user"}, {"PUT", "/user/following/:user", nil},
{"DELETE", "/user/following/:user"}, {"DELETE", "/user/following/:user", nil},
{"GET", "/users/:user/keys"}, {"GET", "/users/:user/keys", nil},
{"GET", "/user/keys"}, {"GET", "/user/keys", nil},
{"GET", "/user/keys/:id"}, {"GET", "/user/keys/:id", nil},
{"POST", "/user/keys"}, {"POST", "/user/keys", nil},
//{"PATCH", "/user/keys/:id"}, //{"PATCH", "/user/keys/:id", nil},
{"DELETE", "/user/keys/:id"}, {"DELETE", "/user/keys/:id", nil},
} }
) )
@@ -506,7 +501,7 @@ func TestRouterParamNames(t *testing.T) {
func TestRouterAPI(t *testing.T) { func TestRouterAPI(t *testing.T) {
r := New().router r := New().router
for _, route := range api { for _, route := range api {
r.Add(route.method, route.path, func(c *Context) error { r.Add(route.Method, route.Path, func(c *Context) error {
for i, n := range c.pnames { for i, n := range c.pnames {
if assert.NotEmpty(t, n) { if assert.NotEmpty(t, n) {
assert.Equal(t, ":"+n, c.P(uint8(i))) assert.Equal(t, ":"+n, c.P(uint8(i)))
@@ -514,7 +509,7 @@ func TestRouterAPI(t *testing.T) {
} }
return nil return nil
}, nil) }, nil)
h, _ := r.Find(route.method, route.path, context) h, _ := r.Find(route.Method, route.Path, context)
if assert.NotNil(t, h) { if assert.NotNil(t, h) {
h(context) h(context)
} }