27
"github.com/stretchr/testify/require"
30
type mockResponseWriter struct {
36
var _ http.ResponseWriter = (*mockResponseWriter)(nil)
38
func (m *mockResponseWriter) Header() (h http.Header) {
40
m.headers = http.Header{}
45
func (m *mockResponseWriter) Write(p []byte) (n int, err error) {
50
func (m *mockResponseWriter) WriteHeader(status int) {
54
func (m *mockResponseWriter) ToResponse() *http.Response {
55
return &http.Response{
57
ContentLength: int64(len(m.body)),
58
Body: io.NopCloser(bytes.NewReader(m.body)),
62
func TestServerRouterBase(t *testing.T) {
70
router.Use(func(c *Context) {
75
router.Use(func(c *Context) {
80
router.Handle(http.MethodGet, "/foo/:bar", func(c *Context) {
81
if err := c.ParseArgs(args); err != nil {
87
w := new(mockResponseWriter)
88
req, _ := http.NewRequest(http.MethodGet, "/foo/you", nil)
89
router.Router.ServeHTTP(w, req)
91
require.Equal(t, "you", args.Bar)
92
require.Equal(t, "13you42", str)
95
func TestServerAbort(t *testing.T) {
98
router.Use(func(c *Context) {
102
require.True(t, c.IsAborted())
103
val, ok := c.Get("Abort")
105
require.Equal(t, int(1), val.(int))
109
router.Use(func(c *Context) {
116
router.Handle(http.MethodGet, "/foo/:bar", func(c *Context) {
120
w := new(mockResponseWriter)
121
req, _ := http.NewRequest(http.MethodGet, "/foo/you", nil)
122
router.Router.ServeHTTP(w, req)
124
require.Equal(t, "1342", str)
127
func TestServerAbortStatus(t *testing.T) {
128
resp := func(r *Router) *mockResponseWriter {
129
w := new(mockResponseWriter)
130
req, _ := http.NewRequest(http.MethodGet, "/", nil)
131
r.Router.ServeHTTP(w, req)
137
router.Use(func(c *Context) {
140
router.Handle(http.MethodGet, "/", func(c *Context) { c.Respond() })
142
require.Equal(t, 200, w.status)
143
require.Equal(t, "0", w.Header().Get(HeaderContentLength))
147
router.Use(func(c *Context) {
150
router.Handle(http.MethodGet, "/", func(c *Context) { c.RespondStatus(200) })
152
require.Equal(t, 200, w.status)
153
require.Equal(t, "", w.Header().Get(HeaderContentLength))
157
router.Use(func(c *Context) {
160
router.Handle(http.MethodGet, "/", func(c *Context) {
164
require.Equal(t, 200, w.status)
165
require.Equal(t, "", w.Header().Get(HeaderContentLength))
169
router.Use(func(c *Context) { c.Abort() })
170
router.Handle(http.MethodGet, "/", func(c *Context) { c.RespondStatus(204) })
172
require.Equal(t, 200, w.status)
176
router.Use(func(c *Context) { c.AbortWithStatus(400) })
177
router.Handle(http.MethodGet, "/", func(c *Context) { c.RespondStatus(204) })
179
require.Equal(t, 400, w.status)
183
router.Use(func(c *Context) { c.AbortWithStatusJSON(399, struct{ I int }{10}) })
184
router.Handle(http.MethodGet, "/", func(c *Context) { c.RespondStatus(204) })
186
require.Equal(t, 399, w.status)
190
router.Use(func(c *Context) { c.AbortWithError(&Error{Status: 412}) })
191
router.Handle(http.MethodGet, "/", func(c *Context) { c.RespondStatus(204) })
193
require.Equal(t, 412, w.status)
197
func TestServerOptArgs(t *testing.T) {
201
body := "{\"bar\": \"bodybar\"}"
205
router.Handle(http.MethodGet, "/:bar", func(c *Context) {
206
if err := c.ArgsBody(args); err != nil {
211
w := new(mockResponseWriter)
212
req, _ := http.NewRequest(http.MethodGet, "/uribar?bar=querybar", bytes.NewBufferString(body))
213
req.Header.Set(HeaderContentLength, strconv.Itoa(len(body)))
214
router.Router.ServeHTTP(w, req)
216
require.Equal(t, "bodybar", args.Bar)
221
router.Handle(http.MethodGet, "/:bar", func(c *Context) {
222
if err := c.ArgsURI(args); err != nil {
227
w := new(mockResponseWriter)
228
req, _ := http.NewRequest(http.MethodGet, "/uribar?bar=querybar", bytes.NewBufferString(body))
229
req.Header.Set(HeaderContentLength, strconv.Itoa(len(body)))
230
router.Router.ServeHTTP(w, req)
232
require.Equal(t, "uribar", args.Bar)
237
router.Handle(http.MethodGet, "/:bar", func(c *Context) {
238
if err := c.ArgsQuery(args); err != nil {
243
w := new(mockResponseWriter)
244
req, _ := http.NewRequest(http.MethodGet, "/uribar?bar=querybar", bytes.NewBufferString(body))
245
req.Header.Set(HeaderContentLength, strconv.Itoa(len(body)))
246
router.Router.ServeHTTP(w, req)
248
require.Equal(t, "querybar", args.Bar)
253
router.Handle(http.MethodPost, "/:bar", func(c *Context) {
254
if err := c.ArgsForm(args); err != nil {
260
form.Set("bar", "formbar")
261
w := new(mockResponseWriter)
262
req, _ := http.NewRequest(http.MethodPost, "/uribar?bar=querybar", nil)
264
router.Router.ServeHTTP(w, req)
266
require.Equal(t, "formbar", args.Bar)
271
router.Handle(http.MethodPost, "/:bar", func(c *Context) {
272
if err := c.ArgsPostForm(args); err != nil {
278
form.Set("bar", "formbar")
279
postForm := url.Values{}
280
postForm.Set("bar", "postformbar")
281
w := new(mockResponseWriter)
282
req, _ := http.NewRequest(http.MethodPost, "/uribar?bar=querybar", nil)
284
req.PostForm = postForm
285
router.Router.ServeHTTP(w, req)
287
require.Equal(t, "postformbar", args.Bar)
291
func TestServerOptMetaCapacity(t *testing.T) {
293
router.Handle(http.MethodGet, "/none", func(c *Context) {
294
if c.opts.metaCapacity != 0 {
295
panic(c.opts.metaCapacity)
297
}, OptMetaCapacity(-199))
298
router.Handle(http.MethodGet, "/1024", func(c *Context) {
299
if c.opts.metaCapacity != 1024 {
300
panic(c.opts.metaCapacity)
302
}, OptMetaCapacity(1024))
305
w := new(mockResponseWriter)
306
req, _ := http.NewRequest(http.MethodGet, "/none", nil)
307
router.ServeHTTP(w, req)
310
w := new(mockResponseWriter)
311
req, _ := http.NewRequest(http.MethodGet, "/1024", nil)
312
router.ServeHTTP(w, req)
316
type marshalData struct {
321
func (d *marshalData) Marshal() ([]byte, string, error) {
324
return nil, "", &Error{Status: 204, Err: errors.New("none")}
326
return []byte(d.S), MIMEStream, nil
328
return nil, "", &Error{Status: 400, Err: errors.New("fake error")}
331
func (d *marshalData) Unmarshal(buff []byte) error {
332
for i, j := 0, len(buff)-1; i < j; i, j = i+1, j-1 {
333
buff[i], buff[j] = buff[j], buff[i]
339
type marshalToData struct {
344
func (d *marshalToData) MarshalTo(w io.Writer) (string, error) {
347
return MIMEPlain, nil
349
return "", &Error{Status: 400, Err: errors.New("fake error")}
352
func (d *marshalToData) UnmarshalFrom(r io.Reader) error {
353
buff, _ := io.ReadAll(r)
354
if string(buff) == "error" {
355
return errors.New("unmarshaler from error")
357
for i, j := 0, len(buff)-1; i < j; i, j = i+1, j-1 {
358
buff[i], buff[j] = buff[j], buff[i]
364
func TestServerResponseWith(t *testing.T) {
365
resp := func(r *Router) *mockResponseWriter {
366
w := new(mockResponseWriter)
367
req, _ := http.NewRequest(http.MethodGet, "/", nil)
368
r.Router.ServeHTTP(w, req)
374
router.Use(func(c *Context) {
377
router.Handle(http.MethodGet, "/", func(c *Context) { c.Respond() })
379
require.Equal(t, 0, len(w.body))
383
router.Use(func(c *Context) { c.AbortWithStatusJSON(400, "bad") })
384
router.Handle(http.MethodGet, "/", func(c *Context) { c.RespondStatus(204) })
386
require.Equal(t, "\"bad\"", string(w.body))
390
router.Use(func(c *Context) {
393
router.Handle(http.MethodGet, "/", func(c *Context) { c.RespondStatusData(255, nil) })
395
require.Equal(t, 255, w.status)
396
require.Equal(t, "null", string(w.body))
400
router.Use(func(c *Context) {
403
router.Handle(http.MethodGet, "/", func(c *Context) { c.RespondStatusData(255, NoneBody) })
405
require.Equal(t, 255, w.status)
406
require.Equal(t, "", string(w.body))
410
router.Handle(http.MethodGet, "/", func(c *Context) {
411
c.RespondJSON(&marshalData{I: 11, S: "foo bar"})
414
require.Equal(t, 200, w.status)
415
require.Equal(t, "foo bar", string(w.body))
419
router.Handle(http.MethodGet, "/", func(c *Context) {
420
c.RespondJSON(&marshalData{I: -11, S: "foo bar"})
423
require.Equal(t, 400, w.status)
425
ret := new(errorResponse)
426
err := json.Unmarshal(w.body, ret)
427
require.NoError(t, err)
428
require.Equal(t, "", ret.Code)
429
require.Equal(t, "fake error", ret.Error)
433
router.Handle(http.MethodGet, "/", func(c *Context) {
434
c.RespondJSON(marshalData{I: 11, S: "foo bar"})
437
require.Equal(t, 200, w.status)
439
ret := new(marshalData)
440
err := json.Unmarshal(w.body, ret)
441
require.NoError(t, err)
442
require.Equal(t, 11, ret.I)
443
require.Equal(t, "foo bar", ret.S)
448
router.Handle(http.MethodGet, "/", func(c *Context) {
449
c.RespondJSON(&marshalToData{I: 11, S: "bar foo"})
452
require.Equal(t, 200, w.status)
453
require.Equal(t, MIMEPlain, w.headers.Get(HeaderContentType))
454
require.Equal(t, "bar foo", string(w.body))
458
router.Handle(http.MethodGet, "/", func(c *Context) {
459
c.RespondJSON(&marshalToData{I: -11, S: "bar foo"})
462
require.Equal(t, 400, w.status)
464
ret := new(errorResponse)
465
err := json.Unmarshal(w.body, ret)
466
require.NoError(t, err)
467
require.Equal(t, "", ret.Code)
468
require.Equal(t, "fake error", ret.Error)
473
router.Handle(http.MethodGet, "/", func(c *Context) {
474
c.RespondJSON(&marshalData{I: 100, S: "foo bar"})
476
resp := resp(router).ToResponse()
477
require.Equal(t, 204, resp.StatusCode)
479
err := parseData(resp, nil)
480
require.Error(t, err)
484
router.Handle(http.MethodGet, "/", func(c *Context) {
485
c.RespondJSON(&marshalData{I: 11, S: "foo bar"})
487
resp := resp(router).ToResponse()
488
require.Equal(t, 200, resp.StatusCode)
491
err := parseData(resp, &r)
492
require.NoError(t, err)
493
require.Equal(t, "rab oof", r.S)
495
resp.Body = io.NopCloser(bytes.NewBuffer(nil))
496
err = parseData(resp, &r)
497
require.Error(t, err)
501
router.Handle(http.MethodGet, "/", func(c *Context) {
502
c.RespondJSON(&marshalToData{I: 1, S: "bar foo"})
504
resp := resp(router).ToResponse()
505
require.Equal(t, 200, resp.StatusCode)
508
err := parseData(resp, &r)
509
require.NoError(t, err)
510
require.Equal(t, "oof rab", r.S)
514
router.Handle(http.MethodGet, "/", func(c *Context) {
515
c.RespondJSON(&marshalToData{I: 1, S: "error"})
517
resp := resp(router).ToResponse()
518
require.Equal(t, 200, resp.StatusCode)
521
err := parseData(resp, &r)
522
require.Error(t, err)
526
func BenchmarkServerBase(b *testing.B) {
528
router.Use(func(c *Context) { c.Next() })
529
router.Use(func(c *Context) { c.Next() })
530
router.Handle(http.MethodGet, "/", func(c *Context) { c.Respond() })
534
for ii := 0; ii < b.N; ii++ {
535
w := new(mockResponseWriter)
536
req, _ := http.NewRequest(http.MethodGet, "/", nil)
537
router.ServeHTTP(w, req)