Repository: swaggest/rest
Pull request #30 (2021-03-20 20:56:05)

Add OpenAPI SecurityMiddleware facade

github-actions[bot]: ### Unit Test Coverage
total:	(statements)	81.3%
<details><summary>Coverage diff with base branch</summary>

```diff
61c61,62
< github.com/swaggest/rest/nethttp/openapi.go	HTTPBasicSecurityMiddleware	88.9%
---
> github.com/swaggest/rest/nethttp/openapi.go	SecurityMiddleware	100.0%
> github.com/swaggest/rest/nethttp/openapi.go	HTTPBasicSecurityMiddleware	100.0%
174c175
< total:	(statements)	81.2%
---
> total:	(statements)	81.3%
```
</details>
<!-- Sticky Pull Request Commentunit-test -->
codecov[bot]: # [Codecov](https://codecov.io/gh/swaggest/rest/pull/30?src=pr&el=h1) Report
> Merging [#30](https://codecov.io/gh/swaggest/rest/pull/30?src=pr&el=desc) (a300e49) into [master](https://codecov.io/gh/swaggest/rest/commit/1928f919b4acbff19e628c26abf340b4529fbdd2?el=desc) (1928f91) will **decrease** coverage by `0.44%`.
> The diff coverage is `100.00%`.

[![Impacted file tree graph](https://codecov.io/gh/swaggest/rest/pull/30/graphs/tree.svg?width=650&height=150&src=pr&token=OpLHxxPdmn)](https://codecov.io/gh/swaggest/rest/pull/30?src=pr&el=tree)

```diff
@@            Coverage Diff             @@
##           master      #30      +/-   ##
==========================================
- Coverage   73.47%   73.03%   -0.45%     
==========================================
  Files          26       26              
  Lines        1508     1450      -58     
==========================================
- Hits         1108     1059      -49     
+ Misses        253      249       -4     
+ Partials      147      142       -5     
```

| Flag | Coverage Δ | |
|---|---|---|
| unittests | `73.03% <100.00%> (-0.45%)` | :arrow_down: |

Flags with carried forward coverage won't be shown. [Click here](https://docs.codecov.io/docs/carryforward-flags#carryforward-flags-in-the-pull-request-comment) to find out more.

| [Impacted Files](https://codecov.io/gh/swaggest/rest/pull/30?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [nethttp/openapi.go](https://codecov.io/gh/swaggest/rest/pull/30/diff?src=pr&el=tree#diff-bmV0aHR0cC9vcGVuYXBpLmdv) | `91.83% <100.00%> (-1.13%)` | :arrow_down: |
| [response/gzip/middleware.go](https://codecov.io/gh/swaggest/rest/pull/30/diff?src=pr&el=tree#diff-cmVzcG9uc2UvZ3ppcC9taWRkbGV3YXJlLmdv) | `79.24% <100.00%> (+0.59%)` | :arrow_up: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/swaggest/rest/pull/30?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/swaggest/rest/pull/30?src=pr&el=footer). Last update [1928f91...a300e49](https://codecov.io/gh/swaggest/rest/pull/30?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).

github-actions[bot]: ### Benchmark Result
<details><summary>Benchmark diff with base branch</summary>

```
name                                    old time/op    new time/op    delta
pkg:github.com/swaggest/rest/jsonschema goos:linux goarch:amd64
RequestValidator_ValidateRequestData-2    1.78µs ± 2%    1.83µs ± 1%  +3.01%  (p=0.029 n=4+4)
pkg:github.com/swaggest/rest/request goos:linux goarch:amd64
Decoder_Decode-2                          1.00µs ± 4%    1.02µs ± 3%    ~     (p=0.238 n=5+5)
DecoderFunc_Decode-2                      2.75µs ± 2%    2.79µs ± 4%    ~     (p=0.421 n=5+5)
Decoder_Decode_json-2                     31.9µs ± 3%    32.0µs ± 2%    ~     (p=0.548 n=5+5)
Decoder_Decode_queryObject-2              7.16µs ± 2%    7.19µs ± 3%    ~     (p=0.841 n=5+5)
Decoder_Decode_jsonParam-2                2.47µs ± 1%    2.46µs ± 1%    ~     (p=0.746 n=5+5)
DecoderFactory_SetDecoderFunc-2           2.29µs ± 3%    2.30µs ± 2%    ~     (p=0.548 n=5+5)
pkg:github.com/swaggest/rest/response/gzip goos:linux goarch:amd64
Middleware-2                              17.2µs ± 2%    17.2µs ± 1%    ~     (p=1.000 n=5+5)
Middleware_control-2                      4.31µs ± 4%    4.24µs ± 2%    ~     (p=0.548 n=5+5)

name                                    old alloc/op   new alloc/op   delta
pkg:github.com/swaggest/rest/jsonschema goos:linux goarch:amd64
RequestValidator_ValidateRequestData-2    2.50kB ± 0%    2.50kB ± 0%    ~     (all equal)
pkg:github.com/swaggest/rest/request goos:linux goarch:amd64
Decoder_Decode-2                            440B ± 0%      440B ± 0%    ~     (all equal)
DecoderFunc_Decode-2                      1.51kB ± 0%    1.51kB ± 0%    ~     (all equal)
Decoder_Decode_json-2                     12.3kB ± 0%    12.3kB ± 0%    ~     (all equal)
Decoder_Decode_queryObject-2              2.00kB ± 0%    2.00kB ± 0%    ~     (all equal)
Decoder_Decode_jsonParam-2                  720B ± 0%      720B ± 0%    ~     (all equal)
DecoderFactory_SetDecoderFunc-2           1.02kB ± 0%    1.02kB ± 0%    ~     (all equal)
pkg:github.com/swaggest/rest/response/gzip goos:linux goarch:amd64
Middleware-2                              1.12kB ± 3%    1.13kB ± 5%    ~     (p=0.984 n=5+5)
Middleware_control-2                      11.2kB ± 0%    11.2kB ± 0%    ~     (all equal)

name                                    old allocs/op  new allocs/op  delta
pkg:github.com/swaggest/rest/jsonschema goos:linux goarch:amd64
RequestValidator_ValidateRequestData-2      8.00 ± 0%      8.00 ± 0%    ~     (all equal)
pkg:github.com/swaggest/rest/request goos:linux goarch:amd64
Decoder_Decode-2                            4.00 ± 0%      4.00 ± 0%    ~     (all equal)
DecoderFunc_Decode-2                        12.0 ± 0%      12.0 ± 0%    ~     (all equal)
Decoder_Decode_json-2                        169 ± 0%       169 ± 0%    ~     (all equal)
Decoder_Decode_queryObject-2                36.0 ± 0%      36.0 ± 0%    ~     (all equal)
Decoder_Decode_jsonParam-2                  12.0 ± 0%      12.0 ± 0%    ~     (all equal)
DecoderFactory_SetDecoderFunc-2             16.0 ± 0%      16.0 ± 0%    ~     (all equal)
pkg:github.com/swaggest/rest/response/gzip goos:linux goarch:amd64
Middleware-2                                11.0 ± 0%      11.0 ± 0%    ~     (all equal)
Middleware_control-2                        9.00 ± 0%      9.00 ± 0%    ~     (all equal)
```
</details>
<!-- Sticky Pull Request Commentbench -->
github-actions[bot]: ### Examples Benchmark Result
<details><summary>Benchmark diff with base branch</summary>

```
name                    old time/op    new time/op    delta
pkg:github.com/swaggest/rest/_examples/advanced goos:linux goarch:amd64
_directGzip-2             25.2µs ± 3%    25.2µs ± 1%    ~     (p=1.000 n=5+5)
_directGzipHead-2         25.0µs ± 4%    24.8µs ± 1%    ~     (p=0.690 n=5+5)
_noDirectGzip-2            142µs ± 2%     143µs ± 2%    ~     (p=0.690 n=5+5)
_directGzip_decode-2       529µs ± 1%     524µs ± 2%    ~     (p=0.310 n=5+5)
_noDirectGzip_decode-2     143µs ± 2%     142µs ± 1%    ~     (p=1.000 n=5+5)
_jsonBody-2               45.1µs ± 1%    44.4µs ± 2%    ~     (p=0.095 n=5+5)
_jsonBodyValidation-2     52.6µs ± 4%    53.3µs ± 4%    ~     (p=0.421 n=5+5)
_outputHeaders-2          23.8µs ± 2%    24.2µs ± 1%    ~     (p=0.056 n=5+5)
_validation-2             49.6µs ± 2%    48.0µs ± 2%  -3.16%  (p=0.008 n=5+5)
pkg:github.com/swaggest/rest/_examples/task-api/internal/infra/nethttp goos:linux goarch:amd64
_notFoundSrv-2            28.3µs ± 0%    28.0µs ± 2%  -1.27%  (p=0.016 n=4+5)
_ok-2                     29.5µs ± 3%    29.5µs ± 2%    ~     (p=0.841 n=5+5)
_invalidBody-2            43.7µs ± 1%    44.2µs ± 1%    ~     (p=0.056 n=5+5)

name                    old B:rcvd/op  new B:rcvd/op  delta
pkg:github.com/swaggest/rest/_examples/advanced goos:linux goarch:amd64
_directGzip-2                639 ± 0%       639 ± 0%    ~     (all equal)
_directGzipHead-2            183 ± 0%       183 ± 0%    ~     (all equal)
_noDirectGzip-2            1.04k ± 0%     1.04k ± 0%    ~     (all equal)
_directGzip_decode-2         639 ± 0%       639 ± 0%    ~     (all equal)
_noDirectGzip_decode-2     1.04k ± 0%     1.04k ± 0%    ~     (all equal)
_jsonBody-2                  208 ± 0%       208 ± 0%    ~     (all equal)
_jsonBodyValidation-2        194 ± 0%       194 ± 0%    ~     (all equal)
_outputHeaders-2             155 ± 0%       155 ± 0%    ~     (all equal)
_validation-2                177 ± 0%       177 ± 0%    ~     (all equal)
pkg:github.com/swaggest/rest/_examples/task-api/internal/infra/nethttp goos:linux goarch:amd64
_notFoundSrv-2               337 ± 0%       337 ± 0%    ~     (all equal)
_ok-2                        359 ± 0%       359 ± 0%    ~     (all equal)
_invalidBody-2               435 ± 0%       435 ± 0%    ~     (all equal)

name                    old B:sent/op  new B:sent/op  delta
pkg:github.com/swaggest/rest/_examples/advanced goos:linux goarch:amd64
_directGzip-2                103 ± 0%       103 ± 0%    ~     (all equal)
_directGzipHead-2            104 ± 0%       104 ± 0%    ~     (all equal)
_noDirectGzip-2              117 ± 0%       117 ± 0%    ~     (all equal)
_directGzip_decode-2         116 ± 0%       116 ± 0%    ~     (all equal)
_noDirectGzip_decode-2       130 ± 0%       130 ± 0%    ~     (all equal)
_jsonBody-2                  188 ± 0%       188 ± 0%    ~     (all equal)
_jsonBodyValidation-2        192 ± 0%       192 ± 0%    ~     (all equal)
_outputHeaders-2            77.0 ± 0%      77.0 ± 0%    ~     (all equal)
_validation-2                170 ± 0%       170 ± 0%    ~     (all equal)
pkg:github.com/swaggest/rest/_examples/task-api/internal/infra/nethttp goos:linux goarch:amd64
_notFoundSrv-2              74.0 ± 0%      74.0 ± 0%    ~     (all equal)
_ok-2                       74.0 ± 0%      74.0 ± 0%    ~     (all equal)
_invalidBody-2               137 ± 0%       137 ± 0%    ~     (all equal)

name                    old rps        new rps        delta
pkg:github.com/swaggest/rest/_examples/advanced goos:linux goarch:amd64
_directGzip-2              39.6k ± 3%     39.7k ± 1%    ~     (p=1.000 n=5+5)
_directGzipHead-2          40.1k ± 4%     40.3k ± 1%    ~     (p=0.690 n=5+5)
_noDirectGzip-2            7.03k ± 2%     7.01k ± 2%    ~     (p=0.690 n=5+5)
_directGzip_decode-2       1.89k ± 1%     1.91k ± 2%    ~     (p=0.310 n=5+5)
_noDirectGzip_decode-2     6.99k ± 2%     7.04k ± 1%    ~     (p=1.000 n=5+5)
_jsonBody-2                22.2k ± 1%     22.5k ± 2%    ~     (p=0.095 n=5+5)
_jsonBodyValidation-2      19.0k ± 4%     18.8k ± 4%    ~     (p=0.421 n=5+5)
_outputHeaders-2           42.0k ± 2%     41.3k ± 1%    ~     (p=0.056 n=5+5)
_validation-2              20.2k ± 2%     20.8k ± 2%  +3.24%  (p=0.008 n=5+5)
pkg:github.com/swaggest/rest/_examples/task-api/internal/infra/nethttp goos:linux goarch:amd64
_notFoundSrv-2             35.3k ± 0%     35.8k ± 2%  +1.30%  (p=0.016 n=4+5)
_ok-2                      33.9k ± 3%     33.9k ± 2%    ~     (p=0.841 n=5+5)
_invalidBody-2             22.9k ± 1%     22.6k ± 1%    ~     (p=0.056 n=5+5)

name                    old alloc/op   new alloc/op   delta
pkg:github.com/swaggest/rest/_examples/advanced goos:linux goarch:amd64
_directGzip-2             3.86kB ± 0%    3.86kB ± 0%    ~     (p=0.190 n=5+5)
_directGzipHead-2         3.86kB ± 0%    3.86kB ± 0%    ~     (p=0.794 n=5+5)
_noDirectGzip-2           6.08kB ±21%    6.21kB ±19%    ~     (p=0.548 n=5+5)
_directGzip_decode-2       402kB ± 0%     402kB ± 0%    ~     (p=1.000 n=5+5)
_noDirectGzip_decode-2    5.23kB ± 5%    5.30kB ± 6%    ~     (p=0.548 n=5+5)
_jsonBody-2               11.7kB ± 0%    11.7kB ± 0%    ~     (p=0.889 n=5+5)
_jsonBodyValidation-2     18.2kB ± 0%    18.2kB ± 0%    ~     (p=0.952 n=4+5)
_outputHeaders-2          3.63kB ± 0%    3.63kB ± 0%    ~     (p=1.000 n=5+5)
_validation-2             16.2kB ± 0%    16.2kB ± 0%    ~     (p=0.984 n=5+5)
pkg:github.com/swaggest/rest/_examples/task-api/internal/infra/nethttp goos:linux goarch:amd64
_notFoundSrv-2            4.81kB ± 0%    4.81kB ± 0%    ~     (p=0.992 n=5+5)
_ok-2                     4.72kB ± 0%    4.72kB ± 0%    ~     (p=0.971 n=4+4)
_invalidBody-2            8.58kB ± 0%    8.58kB ± 0%    ~     (p=0.971 n=4+4)

name                    old allocs/op  new allocs/op  delta
pkg:github.com/swaggest/rest/_examples/advanced goos:linux goarch:amd64
_directGzip-2               40.0 ± 0%      40.0 ± 0%    ~     (all equal)
_directGzipHead-2           40.0 ± 0%      40.0 ± 0%    ~     (all equal)
_noDirectGzip-2             47.6 ± 3%      47.6 ± 3%    ~     (p=1.000 n=5+5)
_directGzip_decode-2         497 ± 0%       497 ± 0%    ~     (all equal)
_noDirectGzip_decode-2      48.0 ± 0%      48.0 ± 0%    ~     (all equal)
_jsonBody-2                  103 ± 0%       103 ± 0%    ~     (all equal)
_jsonBodyValidation-2        144 ± 0%       144 ± 0%    ~     (all equal)
_outputHeaders-2            35.0 ± 0%      35.0 ± 0%    ~     (all equal)
_validation-2                131 ± 0%       131 ± 0%    ~     (all equal)
pkg:github.com/swaggest/rest/_examples/task-api/internal/infra/nethttp goos:linux goarch:amd64
_notFoundSrv-2              52.0 ± 0%      52.0 ± 0%    ~     (all equal)
_ok-2                       48.0 ± 0%      48.0 ± 0%    ~     (all equal)
_invalidBody-2              98.0 ± 0%      98.0 ± 0%    ~     (all equal)
```
</details>
<!-- Sticky Pull Request Commentbench-examples -->

Patch:
diff --git a/Makefile b/Makefile
index 3358680..4be4f3f 100644
--- a/Makefile
+++ b/Makefile
@@ -29,10 +29,10 @@ ifeq ($(DEVGO_PATH),)
 endif
 
 -include $(DEVGO_PATH)/makefiles/main.mk
+-include $(DEVGO_PATH)/makefiles/lint.mk
 -include $(DEVGO_PATH)/makefiles/test-unit.mk
 -include $(DEVGO_PATH)/makefiles/bench.mk
--include $(DEVGO_PATH)/makefiles/lint.mk
--include $(DEVGO_PATH)/makefiles/github-actions.mk
+-include $(DEVGO_PATH)/makefiles/reset-ci.mk
 
 ## Run tests
 test: test-unit test-examples
diff --git a/README.md b/README.md
index ee4fae1..10ad589 100644
--- a/README.md
+++ b/README.md
@@ -365,4 +365,11 @@ func main() {
 
 ```
 
-![Documentation Page](./_examples/basic/screen.png)
\ No newline at end of file
+![Documentation Page](./_examples/basic/screen.png)
+
+## Versioning
+
+This project adheres to [Semantic Versioning](https://semver.org/#semantic-versioning-200).
+
+Before version `1.0.0`, breaking changes are tagged with `MINOR` bump, features and fixes are tagged with `PATCH` bump.
+After version `1.0.0`, breaking changes are tagged with `MAJOR` bump.
\ No newline at end of file
diff --git a/nethttp/openapi.go b/nethttp/openapi.go
index 8c8af97..9d946e2 100644
--- a/nethttp/openapi.go
+++ b/nethttp/openapi.go
@@ -35,26 +35,17 @@ func OpenAPIMiddleware(s *openapi.Collector) func(http.Handler) http.Handler {
 	}
 }
 
-// HTTPBasicSecurityMiddleware creates middleware to expose Basic Security schema.
-func HTTPBasicSecurityMiddleware(
+// SecurityMiddleware creates middleware to expose security scheme.
+func SecurityMiddleware(
 	c *openapi.Collector,
-	name, description string,
+	name string,
+	scheme openapi3.SecurityScheme,
 	options ...func(*MiddlewareConfig),
 ) func(http.Handler) http.Handler {
-	hss := openapi3.HTTPSecurityScheme{}
-
-	hss.WithScheme("basic")
-
-	if description != "" {
-		hss.WithDescription(description)
-	}
-
 	c.Reflector().SpecEns().ComponentsEns().SecuritySchemesEns().WithMapOfSecuritySchemeOrRefValuesItem(
 		name,
 		openapi3.SecuritySchemeOrRef{
-			SecurityScheme: &openapi3.SecurityScheme{
-				HTTPSecurityScheme: &hss,
-			},
+			SecurityScheme: &scheme,
 		},
 	)
 
@@ -67,6 +58,25 @@ func HTTPBasicSecurityMiddleware(
 	return securityMiddleware(c, name, cfg)
 }
 
+// HTTPBasicSecurityMiddleware creates middleware to expose Basic Security schema.
+func HTTPBasicSecurityMiddleware(
+	c *openapi.Collector,
+	name, description string,
+	options ...func(*MiddlewareConfig),
+) func(http.Handler) http.Handler {
+	hss := openapi3.HTTPSecurityScheme{}
+
+	hss.WithScheme("basic")
+
+	if description != "" {
+		hss.WithDescription(description)
+	}
+
+	return SecurityMiddleware(c, name, openapi3.SecurityScheme{
+		HTTPSecurityScheme: &hss,
+	}, options...)
+}
+
 // HTTPBearerSecurityMiddleware creates middleware to expose HTTP Bearer security schema.
 func HTTPBearerSecurityMiddleware(
 	c *openapi.Collector,
@@ -85,22 +95,9 @@ func HTTPBearerSecurityMiddleware(
 		hss.WithDescription(description)
 	}
 
-	c.Reflector().SpecEns().ComponentsEns().SecuritySchemesEns().WithMapOfSecuritySchemeOrRefValuesItem(
-		name,
-		openapi3.SecuritySchemeOrRef{
-			SecurityScheme: &openapi3.SecurityScheme{
-				HTTPSecurityScheme: &hss,
-			},
-		},
-	)
-
-	cfg := MiddlewareConfig{}
-
-	for _, o := range options {
-		o(&cfg)
-	}
-
-	return securityMiddleware(c, name, cfg)
+	return SecurityMiddleware(c, name, openapi3.SecurityScheme{
+		HTTPSecurityScheme: &hss,
+	}, options...)
 }
 
 // AnnotateOpenAPI applies OpenAPI annotation to relevant handlers.
diff --git a/response/gzip/middleware.go b/response/gzip/middleware.go
index ed371a3..7126041 100644
--- a/response/gzip/middleware.go
+++ b/response/gzip/middleware.go
@@ -85,8 +85,7 @@ func maybeGzipResponseWriter(w http.ResponseWriter, r *http.Request) http.Respon
 
 	ae = strings.ToLower(ae)
 
-	n := strings.Index(ae, "gzip")
-	if n < 0 {
+	if n := strings.Index(ae, "gzip"); n < 0 {
 		return w
 	}
 


Test patch:
diff --git a/chirouter/wrapper_test.go b/chirouter/wrapper_test.go
index 1f55b3b..fa9b0c2 100644
--- a/chirouter/wrapper_test.go
+++ b/chirouter/wrapper_test.go
@@ -26,8 +26,7 @@ type HandlerWithBar struct {
 func (h HandlerWithBar) Bar() {}
 
 func (h HandlerWithBar) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
-	_, err := rw.Write([]byte("bar"))
-	if err != nil {
+	if _, err := rw.Write([]byte("bar")); err != nil {
 		panic(err)
 	}
 
diff --git a/dev_test.go b/dev_test.go
new file mode 100644
index 0000000..0cf488a
--- /dev/null
+++ b/dev_test.go
@@ -0,0 +1,3 @@
+package rest_test
+
+import _ "github.com/bool64/dev" // Include CI/Dev scripts to project.
diff --git a/nethttp/example_test.go b/nethttp/example_test.go
new file mode 100644
index 0000000..f522508
--- /dev/null
+++ b/nethttp/example_test.go
@@ -0,0 +1,57 @@
+package nethttp_test
+
+import (
+	"context"
+	"net/http"
+
+	"github.com/go-chi/chi"
+	"github.com/swaggest/openapi-go/openapi3"
+	"github.com/swaggest/rest/chirouter"
+	"github.com/swaggest/rest/nethttp"
+	"github.com/swaggest/rest/openapi"
+	"github.com/swaggest/usecase"
+)
+
+func ExampleSecurityMiddleware() {
+	// Create router.
+	r := chirouter.NewWrapper(chi.NewRouter())
+
+	// Init API documentation schema.
+	apiSchema := &openapi.Collector{}
+
+	// Setup middlewares (non-documentary middlewares omitted for brevity).
+	r.Use(
+		nethttp.OpenAPIMiddleware(apiSchema), // Documentation collector.
+	)
+
+	// Configure an actual security middleware.
+	serviceTokenAuth := func(h http.Handler) http.Handler {
+		return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
+			if req.Header.Get("Authorization") != "<secret>" {
+				http.Error(w, "Authentication failed.", http.StatusUnauthorized)
+
+				return
+			}
+
+			h.ServeHTTP(w, req)
+		})
+	}
+
+	// Configure documentation middleware to describe actual security middleware.
+	serviceTokenDoc := nethttp.SecurityMiddleware(apiSchema, "serviceToken", openapi3.SecurityScheme{
+		APIKeySecurityScheme: &openapi3.APIKeySecurityScheme{
+			Name: "Authorization",
+			In:   openapi3.APIKeySecuritySchemeInHeader,
+		},
+	})
+
+	u := usecase.NewIOI(nil, nil, func(ctx context.Context, input, output interface{}) error {
+		// Do something.
+		return nil
+	})
+
+	// Add use case handler to router with security middleware.
+	r.
+		With(serviceTokenAuth, serviceTokenDoc). // Apply a pair of middlewares: actual security and documentation.
+		Method(http.MethodGet, "/foo", nethttp.NewHandler(u))
+}
diff --git a/tools_test.go b/tools_test.go
deleted file mode 100644
index 5dd5047..0000000
--- a/tools_test.go
+++ /dev/null
@@ -1,3 +0,0 @@
-package rest_test
-
-import _ "github.com/bool64/dev"