Clean unneeded Handle function.

This commit is contained in:
2020-12-14 23:55:23 -08:00
parent 0a6b9b2d0a
commit 05f90673c5
3 changed files with 81 additions and 31 deletions

View File

@ -14,7 +14,7 @@ Inside the handler function you provide, access path parameters with the `PathPa
```go
router.AddRoute(http.MethodGet, "user/:userID", func(w http.ResponseWriter, r *http.Request) {
params, _ := router.PathParams(requestMethod, requestPath)
params, _ := PathParams(r)
userID := params["userID"]
})
@ -23,3 +23,7 @@ router.AddRoute(http.MethodGet, "user/:userID", func(w http.ResponseWriter, r *h
## Not Found Handler
If Router.NotFoundHandler is not a set, a default handler will be called when a route is not found. If you want to set your own handler, set Router.NotFoundHandler with the http.Handler you would prefer.
## Public consumption
I have included a license but this really isn't for public consumption. If you have found this repository somehow and you want to use it, understand that you are on your own in terms of getting it working, fixing issues, adding features, etc. Use at your own risk.

View File

@ -112,31 +112,6 @@ func (r *Router) AddRoute(method string, path string, callback http.HandlerFunc)
return
}
// Handler returns the Handler to use for the given request, consulting r.Method, r.URL.Path. It
// always returns a non-nil Handler.
//
// Handler also returns the path which it matched.
//
// If there is no registered Handler that applies to the request, Handler returns a ``page not
// found'' Handler and an empty pattern.
func (r *Router) Handler(req *http.Request) (h http.Handler, pattern string) {
method := req.Method
path := req.URL.Path
if r.NotFoundHandler == nil {
h = NotFoundHandler
}
endpoint, _, err := r.getEndpoint(method, path)
if err == nil {
h = endpoint.callback
pattern = endpoint.path
}
return
}
// ServeHTTP is the function that is required by http.Handler. It takes an http.ResponseWriter which
// it uses to write to a response object that will construct a response for the user. It also takes
// an *http.Request which describes the request the user has made.
@ -151,15 +126,13 @@ func (r Router) ServeHTTP(w http.ResponseWriter, req *http.Request) {
endpoint, params, err := r.getEndpoint(method, path)
if err != nil {
handler = NotFoundHandler
handler = r.NotFoundHandler
} else {
handler = endpoint.callback
ctx := context.WithValue(context.Background(), paramsKey, params)
req = req.WithContext(ctx)
}
handler, _ = r.Handler(req)
handler.ServeHTTP(w, req)
return
@ -233,6 +206,8 @@ func (r *Router) getEndpoint(method string, path string) (end *endpoint, params
seg, paramName := getChild(key, curr)
if seg == nil {
err = errors.New("route not found")
return
}

View File

@ -18,7 +18,7 @@ func TestAddRouter(t *testing.T) {
testAddRoot(router, t)
testAddOneSegment(router, t)
testAddManySegments(router, t)
// TODO: add test for error when trying duplicate method + path
testAddDuplicateEndpoint(router, t)
}
func TestServeHTTP(t *testing.T) {
@ -29,6 +29,8 @@ func TestServeHTTP(t *testing.T) {
testMatchesRoot(router, t)
testMatchesLongPath(router, t)
testMatchesPathParam(router, t)
testDefaultNotFound(router, t)
testCustomNotFound(router, t)
}
func TestPathParams(t *testing.T) {
@ -108,7 +110,7 @@ func matchAndCheckRoute(r *Router, method string, path string, expectedBody stri
r.ServeHTTP(rr, request)
if rr.Code != expectedCode {
err = fmt.Errorf("The returned callback did not write 200 to the header. Found %d", rr.Code)
err = fmt.Errorf("The returned callback did not write %d to the header. Found %d", expectedCode, rr.Code)
return
}
@ -128,6 +130,28 @@ func matchAndCheckRoute(r *Router, method string, path string, expectedBody stri
return
}
func testAddDuplicateEndpoint(router Router, t *testing.T) {
defer testOutcome("add duplicate endpoints", t)
err := addAndCheckRoute(&router, http.MethodGet, "/dupe", func(http.ResponseWriter, *http.Request) {})
if err != nil {
t.Error("The route was not correctly added to the routoer", err)
}
err = addAndCheckRoute(&router, http.MethodPost, "/dupe", func(http.ResponseWriter, *http.Request) {})
if err != nil {
t.Error("The route was not correctly added to the routoer", err)
}
err = addAndCheckRoute(&router, http.MethodGet, "/dupe", func(http.ResponseWriter, *http.Request) {})
if err == nil {
t.Error("Adding a duplicate route should throw an error.")
}
}
func testAddManySegments(router Router, t *testing.T) {
defer testOutcome("add many multiple segments", t)
@ -170,6 +194,53 @@ func testAddRoot(router Router, t *testing.T) {
}
}
func testCustomNotFound(router Router, t *testing.T) {
defer testOutcome("custom NotFoundHandler", t)
expectedBody := "Forbidden"
expectedCode := 401
path := "/actual/path"
router.AddRoute(http.MethodPatch, path, func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(404)
w.Write([]byte("Not found."))
})
router.NotFoundHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(expectedCode)
w.Write([]byte(expectedBody))
})
err := matchAndCheckRoute(&router, http.MethodPatch, "/gibberish/forbidden", expectedBody, expectedCode)
if err != nil {
t.Error("Did not call the custom handler.", err)
return
}
}
func testDefaultNotFound(router Router, t *testing.T) {
defer testOutcome("default NotFoundHandler", t)
expectedBody := "Not Found."
expectedCode := 404
path := "/gibberish"
router.AddRoute(http.MethodDelete, path, func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(expectedCode)
w.Write([]byte(expectedBody))
})
err := matchAndCheckRoute(&router, http.MethodDelete, "/gibberish", expectedBody, expectedCode)
if err != nil {
t.Error("Did not find the expected callback handler", err)
return
}
}
func testMatchesLongPath(router Router, t *testing.T) {
defer testOutcome("match long path", t)