mirror of
https://github.com/coder/coder.git
synced 2026-06-02 20:48:20 +00:00
ce935657f6
This PR adds a framework to move to a mocked db. And therefore massively speed up these tests.
68 lines
1.6 KiB
Go
68 lines
1.6 KiB
Go
package testutil
|
|
|
|
import (
|
|
"reflect"
|
|
"testing"
|
|
|
|
"github.com/brianvoe/gofakeit/v7"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
// Fake will populate any zero fields in the provided struct with fake data.
|
|
// Non-zero fields will remain unchanged.
|
|
// Usage:
|
|
//
|
|
// key := Fake(t, faker, database.APIKey{
|
|
// TokenName: "keep-my-name",
|
|
// })
|
|
func Fake[T any](t *testing.T, faker *gofakeit.Faker, seed T) T {
|
|
t.Helper()
|
|
|
|
var tmp T
|
|
err := faker.Struct(&tmp)
|
|
require.NoError(t, err, "failed to generate fake data for type %T", tmp)
|
|
|
|
mergeZero(&seed, tmp)
|
|
return seed
|
|
}
|
|
|
|
// mergeZero merges the fields of src into dst, but only if the field in dst is
|
|
// currently the zero value.
|
|
// Make sure `dst` is a pointer to a struct, otherwise the fields are not assignable.
|
|
func mergeZero(dst any, src any) {
|
|
srcv := reflect.ValueOf(src)
|
|
if srcv.Kind() == reflect.Ptr {
|
|
srcv = srcv.Elem()
|
|
}
|
|
remain := [][2]reflect.Value{
|
|
{reflect.ValueOf(dst).Elem(), srcv},
|
|
}
|
|
|
|
// Traverse the struct fields and set them only if they are currently zero.
|
|
// This is a breadth-first traversal of the struct fields. Struct definitions
|
|
// Should not be that deep, so we should not hit any stack overflow issues.
|
|
for {
|
|
if len(remain) == 0 {
|
|
return
|
|
}
|
|
dv, sv := remain[0][0], remain[0][1]
|
|
remain = remain[1:] //
|
|
for i := 0; i < dv.NumField(); i++ {
|
|
df := dv.Field(i)
|
|
sf := sv.Field(i)
|
|
if !df.CanSet() {
|
|
continue
|
|
}
|
|
if df.IsZero() { // only write if currently zero
|
|
df.Set(sf)
|
|
continue
|
|
}
|
|
|
|
if dv.Field(i).Kind() == reflect.Struct {
|
|
// If the field is a struct, we need to traverse it as well.
|
|
remain = append(remain, [2]reflect.Value{df, sf})
|
|
}
|
|
}
|
|
}
|
|
}
|