Documentation
¶
Overview ¶
Package factory provides Rails-style fixture / factory helpers for GoFastr tests and dev-time seeders. Each Factory binds to one entity's CRUD handler and produces fresh row bodies — typically by layering caller overrides on top of a base function — so test setup reads "make me a user with admin=true" instead of "construct a map with every required field by hand."
The package leans on the in-process crud.CrudHandler.CreateOne API so factories run through the exact same Before/After hook chain, transaction, and event emission as real HTTP traffic. That keeps integration-style tests close to production behaviour.
Wiring:
users := framework.NewApp(...).Entity("users", ...) // registers CRUD
userFactory := factory.New(app.Registry, "users", func() map[string]any {
n := userSeq.Next()
return map[string]any{
"email": fmt.Sprintf("user%d@example.com", n),
"name": fmt.Sprintf("User %d", n),
}
})
u, _ := userFactory.Create(ctx)
admin, _ := userFactory.Create(ctx, map[string]any{"role": "admin"})
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type BaseFunc ¶
BaseFunc returns a fresh body map. Called for each Create / Build — returning a new map each time keeps tests independent of each other.
type EntityRegistry ¶
EntityRegistry is the minimal surface the factory needs from the framework's registry — a way to look up an entity by name. The factory accepts the interface so tests can supply a hand-rolled registry; in production this is the App.Registry.
type Factory ¶
type Factory struct {
// contains filtered or unexported fields
}
Factory builds and persists rows for one entity. Construct via New.
The handler defaults to the entity's bundled CRUD handler. Override it via WithHandler when your tests need a different DB connection (sandboxed schema, in-memory fork, …).
func New ¶
New constructs a Factory bound to the named entity in the registry. The base function MUST return a fresh map per call — sharing a map would let later overrides leak into earlier factory results.
Returns an error when the entity is unknown or has no DB attached.
func (*Factory) Build ¶
Build returns the row body that Create would insert — useful when a test wants to assert on the request shape without actually hitting the database. Overrides apply left-to-right; later overrides win on key conflict.
func (*Factory) Create ¶
Create inserts a fresh row through the full CRUD pipeline (Before hooks → INSERT → After hooks → event emission) and returns the persisted record as a snake_cased map.
func (*Factory) CreateMany ¶
func (f *Factory) CreateMany(ctx context.Context, n int, perIndex func(i int) map[string]any) ([]map[string]any, error)
CreateMany inserts n rows. The optional perIndex callback runs once per row and its return is merged on top of base + caller overrides — handy when each row needs a unique value derived from its index (e.g. ordering tests).
type Option ¶
type Option func(*Factory)
Option configures a Factory.
func WithHandler ¶
func WithHandler(h *crud.CrudHandler) Option
WithHandler overrides the CRUD handler the factory dispatches through. Useful when tests build their own handler with a custom DB connection.
type Registry ¶
type Registry struct {
// contains filtered or unexported fields
}
Registry is the optional collection of named factories shared across a test suite. Use [Suite] as the entry point in tests.
func (*Registry) Create ¶
func (r *Registry) Create(ctx context.Context, name string, overrides ...map[string]any) (map[string]any, error)
Create looks up the named factory and creates one row. Convenience wrapper for tests that don't keep a local Factory reference.
func (*Registry) MustGet ¶
MustGet returns the factory or panics. Tests are the only real caller; production code should use Registry.Get instead.
type Sequence ¶
type Sequence struct {
// contains filtered or unexported fields
}
Sequence is a tiny atomic counter for unique base values inside factory BaseFuncs. Concurrent-test-safe: Next never returns the same integer twice within a process lifetime.
func (*Sequence) NextString ¶
NextString returns "prefix" + Next() as a string. Useful for per-row unique fields like email addresses.