Help us shape the future of Go! Take the 2026 Go Developer Survey

factory

package
v0.5.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 3, 2026 License: MIT Imports: 12 Imported by: 0

Documentation

Overview

Package factory builds typed ORM drafts and persists them through the ordinary model lifecycle. It never resets data or substitutes raw inserts.

Index

Constants

View Source
const MaxHooks = 16

MaxHooks bounds a factory's after-create hooks.

View Source
const MaxStates = 64

Variables

This section is empty.

Functions

func CreateFor

func CreateFor[M, D, P, PD any](ctx context.Context, writer database.Transactor, child *Factory[M, D], parent *Factory[P, PD], assign func(D, P) D) (M, P, error)

CreateFor creates one parent through its own factory, then one model that belongs to it. assign copies the parent's key into the child's draft, for example `func(d PostDraft, u User) PostDraft { return d.SetAuthorID(u.ID) }`. Both inserts use writer and their ordinary model lifecycle.

func CreateHas

func CreateHas[M, D, C, CD any](ctx context.Context, writer database.Transactor, f *Factory[M, D], child *Factory[C, CD], count int, assign func(CD, M) CD) (M, []C, error)

CreateHas creates one model through f, then count children that belong to it through the child factory in one bounded CreateMany batch.

func Pick

func Pick[T any](f *Faker, items ...T) T

Pick returns one of items; it panics when items is empty, like an index.

Types

type AfterCreate

type AfterCreate[M any] func(context.Context, database.Transactor, M) (M, error)

AfterCreate runs after a model was inserted, inside the transaction that inserted it; writer is that transaction. It can create related records or return a reloaded model. A returned error or panic rolls back the insert, the hooks' own writes and, for CreateMany, the whole batch.

type Build

type Build[D any] func(context.Context, Sequence) (D, error)

Build constructs factory data using a context and sequence number.

type Factory

type Factory[M, D any] struct {
	// contains filtered or unexported fields
}

Factory owns a sequence and immutable state callbacks. Derived states share their parent's sequence, preventing accidental reuse across variants. Each Define call has independent state. Callbacks must themselves support concurrent calls when the factory is shared; each invocation returns its own draft.

func Define

func Define[M any, K comparable](table orm.Table[M, K], build Build[[]orm.Assignment[M]]) (*Factory[M, []orm.Assignment[M]], error)

Define builds an ORM factory from an explicit table and typed assignments. States, composition and after-create hooks share the ordinary factory contract. Example: factory.Define(Users.Table,func(ctx context.Context,n factory.Sequence)([]orm.Assignment[User],error){return []orm.Assignment[User]{orm.TextSet(Users.Name, "Ada")},nil}).

func (*Factory[M, D]) AfterCreating

func (f *Factory[M, D]) AfterCreating(hooks ...AfterCreate[M]) (*Factory[M, D], error)

AfterCreating returns a derived factory that runs hooks, in order, after each Create and after every model of CreateMany. The factory is unchanged.

func (*Factory[M, D]) Create

func (f *Factory[M, D]) Create(ctx context.Context, writer database.Transactor) (M, error)

Create uses normal defaults/UUID preparation, field transformations, model observers, timestamps and the caller's actual transaction owner. With AfterCreating hooks, the insert and every hook share one transaction (a savepoint inside the caller's transaction), so a failing hook leaves no row.

func (*Factory[M, D]) CreateMany

func (f *Factory[M, D]) CreateMany(ctx context.Context, writer database.Transactor, count int) ([]M, error)

CreateMany is atomic, bounded and ordered. Every input executes its normal model hooks through InsertEach, and AfterCreating hooks run in the same transaction (a savepoint inside the caller's transaction). A later failure, including a failing hook, rolls back the whole batch and its after-commit work; factories never switch to the hook-free bulk API.

func (*Factory[M, D]) CreateWith

func (f *Factory[M, D]) CreateWith(ctx context.Context, writer database.Transactor, overrides ...State[D]) (M, error)

CreateWith creates one model with per-call attribute overrides, for example `func(_ context.Context, d UserDraft) (UserDraft, error) { return d.SetName("Ada"), nil }`. The overrides are not retained by the factory.

func (*Factory[M, D]) Draft

func (f *Factory[M, D]) Draft(ctx context.Context) (D, error)

Draft performs no database work. An attempted build consumes its sequence number even on failure; numbers are never reset or silently reused.

func (*Factory[M, D]) DraftWith

func (f *Factory[M, D]) DraftWith(ctx context.Context, overrides ...State[D]) (D, error)

DraftWith builds one draft with per-call states applied after the factory's own states. The overrides are not retained.

func (*Factory[M, D]) WithStates

func (f *Factory[M, D]) WithStates(states ...State[D]) (*Factory[M, D], error)

WithStates appends immutable draft transformations in declaration order.

type Faker

type Faker struct {
	// contains filtered or unexported fields
}

Faker produces deterministic synthetic test values from a seed, so a failing test can be reproduced. It is safe for concurrent use; concurrent callers share one stream, so their interleaving decides which values each receives. Values are fictional and use reserved example domains; never production data.

func NewFaker

func NewFaker(seed uint64) *Faker

NewFaker returns an independent generator for seed.

func (*Faker) Bool

func (f *Faker) Bool() bool

Bool returns true or false with equal probability.

func (*Faker) Email

func (f *Faker) Email() string

Email returns an address at the reserved example.test domain. Addresses from one Faker are unique because each carries a per-generator counter.

func (*Faker) FirstName

func (f *Faker) FirstName() string

FirstName, LastName and Name return fictional personal names.

func (*Faker) Float

func (f *Faker) Float() float64

Float returns a value in [0, 1).

func (*Faker) IntBetween

func (f *Faker) IntBetween(low, high int64) int64

IntBetween returns an integer in the inclusive range [low, high].

func (*Faker) LastName

func (f *Faker) LastName() string

LastName selects a last name from the fake name list.

func (*Faker) Name

func (f *Faker) Name() string

Name returns a fake first and last name separated by a space.

func (*Faker) Sentence

func (f *Faker) Sentence() string

Sentence returns a capitalized sentence of four to ten words.

func (*Faker) TimeBetween

func (f *Faker) TimeBetween(from, to time.Time) time.Time

TimeBetween returns an instant in [from, to), truncated to microseconds so it round-trips through PostgreSQL timestamps.

func (*Faker) Word

func (f *Faker) Word() string

Word returns one lowercase word; Words returns count words.

func (*Faker) Words

func (f *Faker) Words(count int) []string

Words returns the requested number of fake words, or an empty slice for a negative count.

type Sequence

type Sequence uint64

Sequence is a factory sequence number.

type State

type State[D any] func(context.Context, D) (D, error)

State transforms factory data using a context.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL