Files
imgproxy/testutil/lazy_obj.go
2025-09-11 18:23:29 +02:00

68 lines
1.4 KiB
Go

package testutil
import (
"context"
"testing"
"github.com/stretchr/testify/require"
)
// LazyObj is a function that returns an object of type T.
type LazyObj[T any] func() T
// LazyObjT is an interface that provides access to the [testing.T] object.
type LazyObjT interface {
T() *testing.T
}
// LazyObjNew is a function that creates and returns an object of type T and an error if any.
type LazyObjNew[T any] func() (T, error)
// LazyObjDrop is a callback that is called when [LazyObj] is reset.
// It receives a pointer to the object being dropped.
// If the object was not yet initialized, the callback is not called.
type LazyObjDrop[T any] func(T) error
// newLazyObj creates a new [LazyObj] that initializes the object on the first call.
// It returns a function that can be called to get the object and a cancel function
// that can be called to reset the object.
func newLazyObj[T any](
s LazyObjT,
newFn LazyObjNew[T],
dropFn ...LazyObjDrop[T],
) (LazyObj[T], context.CancelFunc) {
s.T().Helper()
var obj *T
init := func() T {
if obj != nil {
return *obj
}
o, err := newFn()
require.NoError(s.T(), err, "Failed to initialize lazy object")
obj = &o
return o
}
cancel := func() {
if obj == nil {
return
}
for _, fn := range dropFn {
if fn == nil {
continue
}
require.NoError(s.T(), fn(*obj), "Failed to reset lazy object")
}
obj = nil
}
return init, cancel
}