mirror of
https://github.com/oxynote/oxynote.git
synced 2026-10-19 03:45:58 +02:00
148 lines
3.8 KiB
Go
148 lines
3.8 KiB
Go
// Package testutil implements helper functions for more convenient testing
|
|
// and may be imported in '_test.go' files only.
|
|
// Usage of some of these functions would have to be replaced by the ones
|
|
// provided by the official testing toolkit packages, should they decide
|
|
// to include helper functions of similar logic and kind.
|
|
package testutil
|
|
|
|
import (
|
|
"bufio"
|
|
"bytes"
|
|
"context"
|
|
"fmt"
|
|
"net/http"
|
|
"reflect"
|
|
"sync"
|
|
"testing"
|
|
|
|
"github.com/go-chi/chi/v5"
|
|
"github.com/google/go-cmp/cmp"
|
|
"github.com/google/go-cmp/cmp/cmpopts"
|
|
"github.com/jarcoal/httpmock"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
"go.uber.org/goleak"
|
|
)
|
|
|
|
// IgnoreBleveWorkers ignores the analysis workers bleve starts when it is
|
|
// loaded and never stops, for goleak.VerifyTestMain in every package that
|
|
// links the search index.
|
|
func IgnoreBleveWorkers() goleak.Option {
|
|
return goleak.IgnoreTopFunction("github.com/blevesearch/bleve_index_api.AnalysisWorker")
|
|
}
|
|
|
|
// AddChiCtx adds the provided URL parameter to the context's chi route
|
|
// context, creating one when the context doesn't carry it yet.
|
|
func AddChiCtx(ctx context.Context, key, value string) context.Context {
|
|
rctx, ok := ctx.Value(chi.RouteCtxKey).(*chi.Context)
|
|
if !ok {
|
|
rctx = chi.NewRouteContext()
|
|
ctx = context.WithValue(ctx, chi.RouteCtxKey, rctx)
|
|
}
|
|
|
|
rctx.URLParams.Add(key, value)
|
|
|
|
return ctx
|
|
}
|
|
|
|
// AssertEqualError uses testify's assert package to check if errors
|
|
// are equal or, if assert.AnError is expected, whether an error exists
|
|
// or not.
|
|
func AssertEqualError(t *testing.T, exp, err error) {
|
|
t.Helper()
|
|
|
|
if exp != nil {
|
|
if exp == assert.AnError { //nolint:err113,errorlint // direct check is needed
|
|
assert.Error(t, err)
|
|
return
|
|
}
|
|
|
|
assert.Equal(t, exp, err)
|
|
|
|
return
|
|
}
|
|
|
|
assert.NoError(t, err)
|
|
}
|
|
|
|
// RequireEqualError uses testify's require package to check if errors
|
|
// are equal or, if assert.AnError is expected, whether an error exists
|
|
// or not.
|
|
func RequireEqualError(t *testing.T, exp, err error) {
|
|
t.Helper()
|
|
|
|
if exp != nil {
|
|
if exp == assert.AnError { //nolint:err113,errorlint // direct check is needed
|
|
require.Error(t, err)
|
|
return
|
|
}
|
|
|
|
require.Equal(t, exp, err)
|
|
|
|
return
|
|
}
|
|
|
|
require.NoError(t, err)
|
|
}
|
|
|
|
// FilterEqual asserts that two objects are equal.
|
|
// All ignored types found on any of the provided objects will not be compared.
|
|
func FilterEqual(v1, v2 any, ignoreTypes ...any) error {
|
|
diff := cmp.Diff(v1, v2, cmpopts.IgnoreTypes(ignoreTypes...),
|
|
cmp.Exporter(func(reflect.Type) bool { return true }))
|
|
if diff != "" {
|
|
return fmt.Errorf("not equal:\n%s", diff)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// AssertFilterEqual asserts that two objects are equal.
|
|
// All ignored types found on any of the provided objects will not be compared.
|
|
func AssertFilterEqual(t *testing.T, v1, v2 any, ignoreTypes ...any) {
|
|
t.Helper()
|
|
|
|
if err := FilterEqual(v1, v2, ignoreTypes...); err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
// MockHTTP creates an HTTP client backed by an isolated httpmock
|
|
// transport, so tests never activate httpmock globally.
|
|
func MockHTTP() (*http.Client, *httpmock.MockTransport) {
|
|
mt := httpmock.NewMockTransport()
|
|
|
|
return &http.Client{Transport: mt}, mt
|
|
}
|
|
|
|
// NewBuffer creates a fresh instance of concurrent writer and its buffer.
|
|
func NewBuffer() (*Writer, *bytes.Buffer) {
|
|
b := &bytes.Buffer{}
|
|
out := bufio.NewWriter(b)
|
|
|
|
return &Writer{out: out}, b
|
|
}
|
|
|
|
// Writer wraps the underlying bufio.Writer to allow concurrently safe
|
|
// access.
|
|
type Writer struct {
|
|
out *bufio.Writer
|
|
mu sync.Mutex
|
|
}
|
|
|
|
// Write writes the contents of p into the buffer.
|
|
func (w *Writer) Write(p []byte) (n int, err error) {
|
|
w.mu.Lock()
|
|
defer w.mu.Unlock()
|
|
|
|
return w.out.Write(p)
|
|
}
|
|
|
|
// Flush writes any buffered data to the underlying io.Writer.
|
|
func (w *Writer) Flush() error {
|
|
w.mu.Lock()
|
|
defer w.mu.Unlock()
|
|
|
|
return w.out.Flush()
|
|
}
|