Files
fiber/adapter_test.go

979 lines
23 KiB
Go

package fiber
import (
"errors"
"fmt"
"io"
"net/http"
"net/http/httptest"
"os"
"reflect"
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/valyala/fasthttp"
)
func TestToFiberHandler_Nil(t *testing.T) {
t.Parallel()
var handler Handler
converted, ok := toFiberHandler(handler)
require.False(t, ok)
require.Nil(t, converted)
}
func TestToFiberHandler_FiberHandler(t *testing.T) {
t.Parallel()
fiberHandler := func(c Ctx) error { return c.SendStatus(http.StatusAccepted) }
converted, ok := toFiberHandler(fiberHandler)
require.True(t, ok)
require.NotNil(t, converted)
require.Equal(t, reflect.ValueOf(fiberHandler).Pointer(), reflect.ValueOf(converted).Pointer())
}
func TestToFiberHandler_FiberHandlerNoErrorReturn(t *testing.T) {
t.Parallel()
app, ctx := newTestCtx(t)
handler := func(c Ctx) {
require.Equal(t, app, c.App())
c.Set("X-Handler", "ok")
}
converted, ok := toFiberHandler(handler)
require.True(t, ok)
require.NotNil(t, converted)
require.NoError(t, converted(ctx))
require.Equal(t, "ok", string(ctx.Response().Header.Peek("X-Handler")))
}
func TestNewTestCtx_ReturnsDefaultCtx(t *testing.T) {
t.Parallel()
app, ctx := newTestCtx(t)
require.NotNil(t, app)
require.NotNil(t, ctx)
require.Equal(t, app, ctx.App())
}
func newTestCtx(t *testing.T) (*App, *DefaultCtx) {
t.Helper()
app := New()
fasthttpCtx := &fasthttp.RequestCtx{}
customCtx := app.AcquireCtx(fasthttpCtx)
ctx, ok := customCtx.(*DefaultCtx)
require.True(t, ok)
t.Cleanup(func() {
app.ReleaseCtx(customCtx)
})
return app, ctx
}
func withRouteHandlers(t *testing.T, ctx *DefaultCtx, handlers ...Handler) {
t.Helper()
ctx.route = &Route{Handlers: handlers}
ctx.indexHandler = 0
t.Cleanup(func() {
ctx.route = nil
ctx.indexHandler = 0
})
}
func TestToFiberHandler_ExpressTwoParamsWithError(t *testing.T) {
t.Parallel()
app, ctx := newTestCtx(t)
handler := func(req Req, res Res) error {
assert.Equal(t, app, req.App())
assert.Equal(t, app, res.App())
return res.SendString("express")
}
converted, ok := toFiberHandler(handler)
require.True(t, ok)
require.NoError(t, converted(ctx))
require.Equal(t, "express", string(ctx.Response().Body()))
}
func TestToFiberHandler_ExpressTwoParamsWithoutError(t *testing.T) {
t.Parallel()
app, ctx := newTestCtx(t)
handler := func(req Req, res Res) {
assert.Equal(t, app, req.App())
require.NoError(t, res.SendStatus(http.StatusCreated))
}
converted, ok := toFiberHandler(handler)
require.True(t, ok)
require.NoError(t, converted(ctx))
require.Equal(t, http.StatusCreated, ctx.Response().StatusCode())
}
func TestToFiberHandler_ExpressThreeParamsWithError(t *testing.T) {
t.Parallel()
app, ctx := newTestCtx(t)
handler := func(req Req, res Res, next func() error) error {
assert.Equal(t, app, req.App())
assert.Equal(t, app, res.App())
return next()
}
converted, ok := toFiberHandler(handler)
require.True(t, ok)
nextErr := errors.New("next")
nextCalled := false
nextHandler := func(_ Ctx) error {
nextCalled = true
return nextErr
}
withRouteHandlers(t, ctx, converted, nextHandler)
err := converted(ctx)
require.ErrorIs(t, err, nextErr)
require.True(t, nextCalled)
}
func TestToFiberHandler_ExpressThreeParamsWithoutError(t *testing.T) {
t.Parallel()
app, ctx := newTestCtx(t)
handler := func(req Req, _ Res, next func() error) {
assert.Equal(t, app, req.App())
err := next()
require.Error(t, err)
assert.EqualError(t, err, "next without error")
}
converted, ok := toFiberHandler(handler)
require.True(t, ok)
nextHandler := func(_ Ctx) error {
return errors.New("next without error")
}
withRouteHandlers(t, ctx, converted, nextHandler)
err := converted(ctx)
require.EqualError(t, err, "next without error")
}
func TestToFiberHandler_ExpressNextNoArgWithErrorReturn(t *testing.T) {
t.Parallel()
app, ctx := newTestCtx(t)
handler := func(req Req, res Res, next func()) error {
assert.Equal(t, app, req.App())
assert.Equal(t, app, res.App())
next()
return nil
}
converted, ok := toFiberHandler(handler)
require.True(t, ok)
nextErr := errors.New("next without return value")
nextCalled := false
nextHandler := func(_ Ctx) error {
nextCalled = true
return nextErr
}
withRouteHandlers(t, ctx, converted, nextHandler)
err := converted(ctx)
require.ErrorIs(t, err, nextErr)
require.True(t, nextCalled)
}
func TestToFiberHandler_ExpressNextWithErrorContinuesOnNil(t *testing.T) {
t.Parallel()
app, ctx := newTestCtx(t)
handler := func(req Req, res Res, next func(error)) {
assert.Equal(t, app, req.App())
assert.Equal(t, app, res.App())
next(nil)
}
converted, ok := toFiberHandler(handler)
require.True(t, ok)
nextCalled := false
nextHandler := func(_ Ctx) error {
nextCalled = true
return nil
}
withRouteHandlers(t, ctx, converted, nextHandler)
err := converted(ctx)
require.NoError(t, err)
require.True(t, nextCalled)
}
func TestToFiberHandler_ExpressNextWithErrorShortCircuitsOnError(t *testing.T) {
t.Parallel()
app, ctx := newTestCtx(t)
handler := func(req Req, res Res, next func(error)) {
assert.Equal(t, app, req.App())
assert.Equal(t, app, res.App())
next(errors.New("next error"))
}
converted, ok := toFiberHandler(handler)
require.True(t, ok)
nextCalled := false
nextHandler := func(_ Ctx) error {
nextCalled = true
return nil
}
withRouteHandlers(t, ctx, converted, nextHandler)
err := converted(ctx)
require.EqualError(t, err, "next error")
require.False(t, nextCalled)
}
func TestToFiberHandler_ExpressNextWithErrorReturn_ShortCircuitsOnNextError(t *testing.T) {
t.Parallel()
app, ctx := newTestCtx(t)
handler := func(req Req, res Res, next func(error)) error {
assert.Equal(t, app, req.App())
assert.Equal(t, app, res.App())
next(errors.New("next error"))
return nil
}
converted, ok := toFiberHandler(handler)
require.True(t, ok)
nextCalled := false
nextHandler := func(_ Ctx) error {
nextCalled = true
return nil
}
withRouteHandlers(t, ctx, converted, nextHandler)
err := converted(ctx)
require.EqualError(t, err, "next error")
require.False(t, nextCalled)
}
func TestToFiberHandler_ExpressNextWithErrorReturnCallback_PropagatesNextError(t *testing.T) {
t.Parallel()
app, ctx := newTestCtx(t)
handler := func(req Req, res Res, next func(error) error) {
assert.Equal(t, app, req.App())
assert.Equal(t, app, res.App())
require.EqualError(t, next(nil), "next error")
}
converted, ok := toFiberHandler(handler)
require.True(t, ok)
nextErr := errors.New("next error")
nextCalled := false
nextHandler := func(_ Ctx) error {
nextCalled = true
return nextErr
}
withRouteHandlers(t, ctx, converted, nextHandler)
err := converted(ctx)
require.ErrorIs(t, err, nextErr)
require.True(t, nextCalled)
}
func TestToFiberHandler_ExpressNextWithErrorReturnCallback_ShortCircuitsOnNextError(t *testing.T) {
t.Parallel()
app, ctx := newTestCtx(t)
handler := func(req Req, res Res, next func(error) error) {
assert.Equal(t, app, req.App())
assert.Equal(t, app, res.App())
require.EqualError(t, next(errors.New("next error")), "next error")
}
converted, ok := toFiberHandler(handler)
require.True(t, ok)
nextCalled := false
nextHandler := func(_ Ctx) error {
nextCalled = true
return nil
}
withRouteHandlers(t, ctx, converted, nextHandler)
err := converted(ctx)
require.EqualError(t, err, "next error")
require.False(t, nextCalled)
}
func TestToFiberHandler_ExpressNextWithErrorReturn_PrefersHandlerErrorOverNextError(t *testing.T) {
t.Parallel()
app, ctx := newTestCtx(t)
handler := func(req Req, res Res, next func(error) error) error {
assert.Equal(t, app, req.App())
assert.Equal(t, app, res.App())
require.EqualError(t, next(errors.New("next error")), "next error")
return errors.New("handler error")
}
converted, ok := toFiberHandler(handler)
require.True(t, ok)
nextCalled := false
nextHandler := func(_ Ctx) error {
nextCalled = true
return nil
}
withRouteHandlers(t, ctx, converted, nextHandler)
err := converted(ctx)
require.EqualError(t, err, "handler error")
require.False(t, nextCalled)
}
func TestToFiberHandler_ExpressNextWithErrorReturn_PropagatesNextErrorWhenNoReturnError(t *testing.T) {
t.Parallel()
app, ctx := newTestCtx(t)
handler := func(req Req, res Res, next func(error) error) error {
assert.Equal(t, app, req.App())
assert.Equal(t, app, res.App())
return next(errors.New("next error"))
}
converted, ok := toFiberHandler(handler)
require.True(t, ok)
nextCalled := false
nextHandler := func(_ Ctx) error {
nextCalled = true
return nil
}
withRouteHandlers(t, ctx, converted, nextHandler)
err := converted(ctx)
require.EqualError(t, err, "next error")
require.False(t, nextCalled)
}
func TestToFiberHandler_ExpressNextWithErrorReturnCallback_StopsChainWithoutNextCall(t *testing.T) {
t.Parallel()
app, ctx := newTestCtx(t)
handler := func(req Req, res Res, _ func(error) error) {
assert.Equal(t, app, req.App())
assert.Equal(t, app, res.App())
// Intentionally do not call next.
}
converted, ok := toFiberHandler(handler)
require.True(t, ok)
nextCalled := false
nextHandler := func(_ Ctx) error {
nextCalled = true
return errors.New("should not be called")
}
withRouteHandlers(t, ctx, converted, nextHandler)
err := converted(ctx)
require.NoError(t, err)
require.False(t, nextCalled)
}
func TestAdapter_MixedHandlerIntegration(t *testing.T) {
app := New()
app.Use(func(c Ctx) error {
c.Set("X-Middleware", "fiber")
return c.Next()
})
app.Use(func(_ Req, res Res, next func() error) error {
res.Set("X-Express", "middleware")
return next()
})
app.Get("/fiber", func(c Ctx) error {
c.Set("X-Route", "fiber")
return c.SendString("fiber handler")
})
app.Post("/express", func(_ Req, res Res) error {
res.Set("X-Route", "express")
return res.SendString("express handler")
})
var httpHandlerWriteErr error
app.Put("/http", func(w http.ResponseWriter, _ *http.Request) {
w.Header().Set("X-Route", "http")
w.WriteHeader(http.StatusAccepted)
_, httpHandlerWriteErr = w.Write([]byte("http handler"))
})
app.Delete("/fasthttp", func(ctx *fasthttp.RequestCtx) error {
ctx.Response.Header.Set("X-Route", "fasthttp")
ctx.SetStatusCode(http.StatusCreated)
ctx.SetBodyString("fasthttp handler")
return nil
})
run := func(name string, buildRequest func() *http.Request, expectStatus int, expectBody, expectRoute string) {
t.Run(name, func(t *testing.T) {
req := buildRequest()
resp, err := app.Test(req)
require.NoError(t, err)
t.Cleanup(func() {
require.NoError(t, resp.Body.Close())
})
body, err := io.ReadAll(resp.Body)
require.NoError(t, err)
require.Equal(t, expectStatus, resp.StatusCode)
require.Equal(t, expectBody, string(body))
require.Equal(t, "fiber", resp.Header.Get("X-Middleware"))
require.Equal(t, "middleware", resp.Header.Get("X-Express"))
require.Equal(t, expectRoute, resp.Header.Get("X-Route"))
})
}
run("fiber", func() *http.Request {
return httptest.NewRequest(http.MethodGet, "/fiber", http.NoBody)
}, http.StatusOK, "fiber handler", "fiber")
run("express", func() *http.Request {
return httptest.NewRequest(http.MethodPost, "/express", http.NoBody)
}, http.StatusOK, "express handler", "express")
run("net/http", func() *http.Request {
return httptest.NewRequest(http.MethodPut, "/http", http.NoBody)
}, http.StatusAccepted, "http handler", "http")
require.NoError(t, httpHandlerWriteErr)
run("fasthttp", func() *http.Request {
return httptest.NewRequest(http.MethodDelete, "/fasthttp", http.NoBody)
}, http.StatusCreated, "fasthttp handler", "fasthttp")
}
func TestToFiberHandler_ExpressNextNoArgPropagatesError(t *testing.T) {
t.Parallel()
app, ctx := newTestCtx(t)
handler := func(req Req, res Res, next func()) {
assert.Equal(t, app, req.App())
assert.Equal(t, app, res.App())
next()
}
converted, ok := toFiberHandler(handler)
require.True(t, ok)
nextErr := errors.New("next without return value")
nextCalled := false
nextHandler := func(_ Ctx) error {
nextCalled = true
return nextErr
}
withRouteHandlers(t, ctx, converted, nextHandler)
err := converted(ctx)
require.ErrorIs(t, err, nextErr)
require.True(t, nextCalled)
}
func TestToFiberHandler_ExpressNextNoArgStopsChain(t *testing.T) {
t.Parallel()
app, ctx := newTestCtx(t)
handler := func(req Req, res Res, _ func()) {
assert.Equal(t, app, req.App())
assert.Equal(t, app, res.App())
// Intentionally do not call next().
}
converted, ok := toFiberHandler(handler)
require.True(t, ok)
nextCalled := false
nextHandler := func(_ Ctx) error {
nextCalled = true
return errors.New("should not be called")
}
withRouteHandlers(t, ctx, converted, nextHandler)
err := converted(ctx)
require.NoError(t, err)
require.False(t, nextCalled)
}
func TestToFiberHandler_ExpressNextNoArgMiddleware(t *testing.T) {
t.Parallel()
app := New()
t.Cleanup(func() {
require.NoError(t, app.Shutdown())
})
callOrder := make([]string, 0, 2)
app.Use(func(req Req, res Res, next func()) {
callOrder = append(callOrder, "middleware")
next()
assert.Equal(t, app, req.App())
assert.Equal(t, app, res.App())
})
app.Get("/", func(c Ctx) error {
callOrder = append(callOrder, "handler")
return c.SendStatus(http.StatusOK)
})
req := httptest.NewRequest(http.MethodGet, "/", http.NoBody)
resp, err := app.Test(req)
require.NoError(t, err)
require.Equal(t, http.StatusOK, resp.StatusCode)
require.NoError(t, resp.Body.Close())
require.Equal(t, []string{"middleware", "handler"}, callOrder)
}
func TestCollectHandlers_HTTPHandler(t *testing.T) {
t.Parallel()
var writeErr error
httpHandler := http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
w.Header().Set("X-HTTP", "ok")
w.WriteHeader(http.StatusTeapot)
_, writeErr = w.Write([]byte("http"))
})
handlers := collectHandlers("test", httpHandler)
require.Len(t, handlers, 1)
converted := handlers[0]
require.NotNil(t, converted)
app := New()
ctx := app.AcquireCtx(&fasthttp.RequestCtx{})
t.Cleanup(func() {
app.ReleaseCtx(ctx)
})
err := converted(ctx)
require.NoError(t, err)
require.Equal(t, http.StatusTeapot, ctx.Response().StatusCode())
require.Equal(t, "ok", string(ctx.Response().Header.Peek("X-HTTP")))
require.Equal(t, "http", string(ctx.Response().Body()))
require.NoError(t, writeErr)
}
func TestToFiberHandler_HTTPHandler(t *testing.T) {
t.Parallel()
var writeErr error
var handler http.Handler = http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
w.Header().Set("X-HTTP", "handler")
_, writeErr = w.Write([]byte("through"))
})
converted, ok := toFiberHandler(handler)
require.True(t, ok)
require.NotNil(t, converted)
app := New()
ctx := app.AcquireCtx(&fasthttp.RequestCtx{})
t.Cleanup(func() {
app.ReleaseCtx(ctx)
})
err := converted(ctx)
require.NoError(t, err)
require.Equal(t, "handler", string(ctx.Response().Header.Peek("X-HTTP")))
require.Equal(t, "through", string(ctx.Response().Body()))
require.NoError(t, writeErr)
}
func TestToFiberHandler_FasthttpHandlerWithError(t *testing.T) {
t.Parallel()
_, ctx := newTestCtx(t)
fasthttpHandler := func(fctx *fasthttp.RequestCtx) error {
fctx.Response.Header.Set("X-FASTHTTP", "error")
return errors.New("fasthttp error")
}
converted, ok := toFiberHandler(fasthttpHandler)
require.True(t, ok)
require.NotNil(t, converted)
err := converted(ctx)
require.EqualError(t, err, "fasthttp error")
require.Equal(t, "error", string(ctx.Response().Header.Peek("X-FASTHTTP")))
}
func TestToFiberHandler_HTTPHandler_Flush(t *testing.T) {
t.Parallel()
var handler http.Handler = http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
w.Header().Set("X-HTTP", "handler")
_, err := w.Write([]byte("through"))
flusher, ok := w.(http.Flusher)
assert.True(t, ok, "w does not implement http.Flusher")
flusher.Flush()
assert.NoError(t, err)
})
converted, ok := toFiberHandler(handler)
require.True(t, ok)
require.NotNil(t, converted)
app := New()
ctx := app.AcquireCtx(&fasthttp.RequestCtx{})
t.Cleanup(func() {
app.ReleaseCtx(ctx)
})
err := converted(ctx)
require.NoError(t, err)
require.Equal(t, "handler", string(ctx.Response().Header.Peek("X-HTTP")))
require.Equal(t, "through", string(ctx.Response().Body()))
}
func TestWrapHTTPHandler_Flush_App_Test(t *testing.T) {
t.Parallel()
app := New()
app.Get("/", func(w http.ResponseWriter, _ *http.Request) {
flusher, ok := w.(http.Flusher)
if !ok {
t.Fatal("w does not implement http.Flusher")
}
w.WriteHeader(StatusOK)
fmt.Fprintf(w, "Hello ")
flusher.Flush()
fmt.Fprintf(w, "World!")
})
resp, err := app.Test(httptest.NewRequest(MethodGet, "/", http.NoBody))
require.NoError(t, err)
defer resp.Body.Close() //nolint:errcheck // not needed
require.Equal(t, StatusOK, resp.StatusCode)
body, err := io.ReadAll(resp.Body)
require.NoError(t, err)
require.Equal(t, "Hello World!", string(body))
}
func Test_HTTPHandler_App_Test_Interrupted(t *testing.T) {
t.Parallel()
app := New()
app.Get("/", func(w http.ResponseWriter, _ *http.Request) {
flusher, ok := w.(http.Flusher)
if !ok {
t.Fatal("w does not implement http.Flusher")
}
w.WriteHeader(StatusOK)
fmt.Fprintf(w, "Hello ")
flusher.Flush()
time.Sleep(500 * time.Millisecond)
fmt.Fprintf(w, "World!")
})
resp, err := app.Test(httptest.NewRequest(MethodGet, "/", http.NoBody), TestConfig{
Timeout: 200 * time.Millisecond,
FailOnTimeout: true, // Changed to true to test interrupted behavior
})
// With FailOnTimeout: true, we should get a timeout error
require.ErrorIs(t, err, os.ErrDeadlineExceeded)
require.Nil(t, resp)
}
func TestToFiberHandler_HTTPHandlerFunc(t *testing.T) {
t.Parallel()
httpFunc := func(w http.ResponseWriter, _ *http.Request) {
w.WriteHeader(http.StatusNoContent)
}
converted, ok := toFiberHandler(httpFunc)
require.True(t, ok)
require.NotNil(t, converted)
app := New()
ctx := app.AcquireCtx(&fasthttp.RequestCtx{})
t.Cleanup(func() {
app.ReleaseCtx(ctx)
})
err := converted(ctx)
require.NoError(t, err)
require.Equal(t, http.StatusNoContent, ctx.Response().StatusCode())
}
func TestWrapHTTPHandler_Nil(t *testing.T) {
t.Parallel()
require.Nil(t, wrapHTTPHandler(nil))
}
func TestCollectHandlers_InvalidType(t *testing.T) {
t.Parallel()
require.PanicsWithValue(t, "context: invalid handler #0 (int)\n", func() {
collectHandlers("context", 42)
})
}
func TestCollectHandlers_TypedNilHTTPHandlers(t *testing.T) {
t.Parallel()
var handlerFunc http.HandlerFunc
var handler http.Handler
var raw func(http.ResponseWriter, *http.Request)
tests := []struct {
handler any
name string
}{
{
name: "HandlerFunc",
handler: handlerFunc,
},
{
name: "Handler",
handler: handler,
},
{
name: "Function",
handler: raw,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
expected := fmt.Sprintf("context: invalid handler #0 (%T)\n", tt.handler)
require.PanicsWithValue(t, expected, func() {
collectHandlers("context", tt.handler)
})
})
}
}
type dummyHandler struct{}
func (dummyHandler) ServeHTTP(http.ResponseWriter, *http.Request) {}
type dummyFuncHandler func(http.ResponseWriter, *http.Request)
func (handler dummyFuncHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if handler == nil {
return
}
handler(w, r)
}
func TestCollectHandlers_TypedNilPointerHTTPHandler(t *testing.T) {
t.Parallel()
var handler http.Handler = (*dummyHandler)(nil)
require.PanicsWithValue(t, "context: invalid handler #0 (*fiber.dummyHandler)\n", func() {
collectHandlers("context", handler)
})
}
func TestCollectHandlers_TypedNilFuncHTTPHandler(t *testing.T) {
t.Parallel()
var handler http.Handler = dummyFuncHandler(nil)
expected := fmt.Sprintf("context: invalid handler #0 (%T)\n", handler)
require.PanicsWithValue(t, expected, func() {
collectHandlers("context", handler)
})
}
func TestCollectHandlers_TypedNilFasthttpHandlers(t *testing.T) {
t.Parallel()
var requestHandler fasthttp.RequestHandler
var requestHandlerWithError func(*fasthttp.RequestCtx) error
tests := []struct {
handler any
name string
}{
{
name: "RequestHandler",
handler: requestHandler,
},
{
name: "RequestHandlerWithError",
handler: requestHandlerWithError,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
expected := fmt.Sprintf("context: invalid handler #0 (%T)\n", tt.handler)
require.PanicsWithValue(t, expected, func() {
collectHandlers("context", tt.handler)
})
})
}
}
func TestCollectHandlers_FasthttpHandler(t *testing.T) {
t.Parallel()
before := func(c Ctx) error {
c.Set("X-Before", "fiber")
return nil
}
fasthttpHandler := fasthttp.RequestHandler(func(ctx *fasthttp.RequestCtx) {
ctx.Response.Header.Set("X-FASTHTTP", "ok")
ctx.SetBody([]byte("done"))
})
handlers := collectHandlers("fasthttp", before, fasthttpHandler)
require.Len(t, handlers, 2)
app := New()
ctx := app.AcquireCtx(&fasthttp.RequestCtx{})
t.Cleanup(func() {
app.ReleaseCtx(ctx)
})
for _, handler := range handlers {
require.NoError(t, handler(ctx))
}
require.Equal(t, "fiber", string(ctx.Response().Header.Peek("X-Before")))
require.Equal(t, "ok", string(ctx.Response().Header.Peek("X-FASTHTTP")))
require.Equal(t, "done", string(ctx.Response().Body()))
}
func TestCollectHandlers_FiberHandlerNoErrorReturn(t *testing.T) {
t.Parallel()
noError := func(c Ctx) {
c.Set("X-Handler", "fiber")
}
handlers := collectHandlers("ctx", noError)
require.Len(t, handlers, 1)
app := New()
ctx := app.AcquireCtx(&fasthttp.RequestCtx{})
t.Cleanup(func() {
app.ReleaseCtx(ctx)
})
require.NoError(t, handlers[0](ctx))
require.Equal(t, "fiber", string(ctx.Response().Header.Peek("X-Handler")))
}
func TestCollectHandlers_MixedHandlers(t *testing.T) {
t.Parallel()
before := func(c Ctx) error {
c.Set("X-Before", "fiber")
return nil
}
var writeErr error
httpHandler := http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
_, writeErr = w.Write([]byte("done"))
})
handlers := collectHandlers("test", before, httpHandler)
require.Len(t, handlers, 2)
require.Equal(t, reflect.ValueOf(before).Pointer(), reflect.ValueOf(handlers[0]).Pointer())
require.NotNil(t, handlers[1])
app := New()
ctx := app.AcquireCtx(&fasthttp.RequestCtx{})
t.Cleanup(func() {
app.ReleaseCtx(ctx)
})
err := handlers[0](ctx)
require.NoError(t, err)
err = handlers[1](ctx)
require.NoError(t, err)
require.Equal(t, "done", string(ctx.Response().Body()))
require.Equal(t, "fiber", string(ctx.Response().Header.Peek("X-Before")))
require.NoError(t, writeErr)
}
func TestCollectHandlers_Nil(t *testing.T) {
t.Parallel()
require.PanicsWithValue(t, "nil: invalid handler #0 (<nil>)\n", func() {
collectHandlers("nil", nil)
})
}