Documentation
¶
Overview ¶
Package factory builds models with fake data for tests and seeders:
var Users = factory.New(func(f *factory.Faker) models.User {
return models.User{Name: f.Name(), Email: f.Email()}
})
admins, err := Users.Count(3).State(func(u *models.User) { u.Role = "admin" }).Create(ctx, db)
Factories are values: State, Count, Seed and AfterCreate return copies, so a base factory can be shared. Make builds values in memory; Create also inserts them through orm.Create, CreateMany in batches through orm.CreateMany. A Faker seeded per factory makes the data reproducible (Seed), which seeders and golden tests rely on.
See https://github.com/AlexGalhardo/vukem/blob/main/docs/database.md#factories-and-seeders.
Index ¶
- func Pick[T any](f *Faker, items ...T) T
- type Factory
- func (f Factory[T]) AfterCreate(fn func(ctx context.Context, ex database.Executor, m *T) error) Factory[T]
- func (f Factory[T]) Count(n int) Factory[T]
- func (f Factory[T]) Create(ctx context.Context, ex database.Executor) ([]T, error)
- func (f Factory[T]) CreateMany(ctx context.Context, ex database.Executor) ([]T, error)
- func (f Factory[T]) CreateOne(ctx context.Context, ex database.Executor) (T, error)
- func (f Factory[T]) Locale(l Locale) Factory[T]
- func (f Factory[T]) Make() []T
- func (f Factory[T]) MakeOne() T
- func (f Factory[T]) Seed(seed uint64) Factory[T]
- func (f Factory[T]) State(fn func(*T)) Factory[T]
- type Faker
- func (f *Faker) Address() string
- func (f *Faker) Bool() bool
- func (f *Faker) Category() string
- func (f *Faker) City() string
- func (f *Faker) Company() string
- func (f *Faker) Email() string
- func (f *Faker) EmailFor(name string) string
- func (f *Faker) FakeCPF() string
- func (f *Faker) FirstName() string
- func (f *Faker) Float(lo, hi float64) float64
- func (f *Faker) Int(lo, hi int) int
- func (f *Faker) LastName() string
- func (f *Faker) Locale() Locale
- func (f *Faker) Name() string
- func (f *Faker) Paragraph() string
- func (f *Faker) PostalCode() string
- func (f *Faker) ProductDescription() string
- func (f *Faker) ProductTitle() string
- func (f *Faker) Sentence() string
- func (f *Faker) Seq() int
- func (f *Faker) Slug() string
- func (f *Faker) State() string
- func (f *Faker) StreetAddress() string
- func (f *Faker) Time(from, to time.Time) time.Time
- func (f *Faker) URL() string
- func (f *Faker) UUID() string
- func (f *Faker) Username() string
- func (f *Faker) WithLocale(l Locale) *Faker
- func (f *Faker) Word() string
- func (f *Faker) Words(n int) string
- type Locale
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
Types ¶
type Factory ¶
type Factory[T any] struct { // contains filtered or unexported fields }
Factory builds T values.
func (Factory[T]) AfterCreate ¶
func (f Factory[T]) AfterCreate(fn func(ctx context.Context, ex database.Executor, m *T) error) Factory[T]
AfterCreate runs fn for every created model, inside Create; use it to create related models:
Users.AfterCreate(func(ctx context.Context, ex database.Executor, u *User) error {
_, err := Posts.Count(2).State(func(p *Post) { p.UserID = u.ID }).Create(ctx, ex)
return err
})
func (Factory[T]) Create ¶
Create builds and inserts Count models (in a transaction when ex is a *database.DB), then runs AfterCreate hooks.
Example ¶
package main
import (
"context"
"fmt"
"github.com/AlexGalhardo/vukem/database"
"github.com/AlexGalhardo/vukem/factory"
"github.com/AlexGalhardo/vukem/orm"
)
type User struct {
orm.Model
Name string
Role string
}
func main() {
ctx := context.Background()
db, _ := database.Open(ctx, ":memory:")
defer db.Close()
_, _ = db.ExecContext(ctx, `CREATE TABLE users (id INTEGER PRIMARY KEY AUTOINCREMENT,
created_at TIMESTAMP, updated_at TIMESTAMP, name TEXT, role TEXT)`)
users := factory.New(func(f *factory.Faker) User {
return User{Name: f.Name(), Role: "member"}
})
created, err := users.Count(3).Create(ctx, db)
if err != nil {
fmt.Println(err)
return
}
n, _ := orm.QueryOf[User](db).Count(ctx)
fmt.Println(len(created), n, created[0].ID > 0)
}
Output: 3 3 true
func (Factory[T]) CreateMany ¶ added in v0.27.0
CreateMany builds Count models and inserts them with orm.CreateMany: multi-row INSERTs split under the dialect's bound-parameter limit, with the generated ids written back (RETURNING on PostgreSQL and SQLite, one INSERT per row on MySQL). AfterCreate hooks run once every row is stored, in order, inside the same transaction.
Given a *database.DB, CreateMany opens that transaction and an insert or hook error rolls back every row. Given a *database.Tx it joins it: the error is returned and the caller owns the rollback (db.Tx rolls back when its function returns the error).
Prefer it to Create for seeding many rows; Create inserts one row at a time and runs each model's hooks right after its insert.
func (Factory[T]) Locale ¶ added in v0.27.0
Locale makes the definition's Faker generate data in l:
Products.Locale(factory.LocalePTBR()).Seed(42).Count(100).Make()
func (Factory[T]) Make ¶
func (f Factory[T]) Make() []T
Make builds Count models without saving them.
Example ¶
package main
import (
"fmt"
"github.com/AlexGalhardo/vukem/factory"
"github.com/AlexGalhardo/vukem/orm"
)
type User struct {
orm.Model
Name string
Role string
}
func main() {
users := factory.New(func(f *factory.Faker) User {
return User{Name: f.Name(), Role: "member"}
})
admins := users.Count(2).State(func(u *User) { u.Role = "admin" }).Make()
for _, u := range admins {
fmt.Println(u.Role, u.Name != "")
}
}
Output: admin true admin true
func (Factory[T]) MakeOne ¶
func (f Factory[T]) MakeOne() T
MakeOne builds one model without saving it.
type Faker ¶
type Faker struct {
// contains filtered or unexported fields
}
Faker generates fake data. It is deterministic for a given seed; it is not cryptographically secure and must never produce secrets.
func NewFaker ¶
NewFaker returns a Faker seeded with seed, with the zero Locale (the original data set; see Locale). Choose a locale with WithLocale:
f := factory.NewFaker(42).WithLocale(factory.LocalePTBR())
func (*Faker) Address ¶ added in v0.27.0
Address returns a one-line postal address whose city and state match.
func (*Faker) Category ¶ added in v0.27.0
Category returns a store category ("Home & Kitchen", "Casa e Cozinha").
func (*Faker) Company ¶ added in v0.27.0
Company returns a company name ("Baker Logistics LLC", "Silva & Costa Comércio Ltda").
func (*Faker) Email ¶
Email returns an address on a reserved example domain, unique within one Make and unlikely to collide across Makes.
func (*Faker) EmailFor ¶ added in v0.27.0
EmailFor returns an address on a reserved example domain whose local part is derived from name ("Ana Luíza" gives ana.luiza.…), unique within one Make like Email.
func (*Faker) FakeCPF ¶ added in v0.27.0
FakeCPF returns a string in the Brazilian CPF format ("123.456.789-09") whose first check digit is always wrong: it can never be a real person's CPF, and every standard CPF validator rejects it. Seed CPF columns directly; do not send it through validation meant for real documents.
func (*Faker) PostalCode ¶ added in v0.27.0
PostalCode returns a ZIP code (en) or a CEP (pt-BR, "01310-100").
func (*Faker) ProductDescription ¶ added in v0.27.0
ProductDescription returns a one-line product description built on ProductTitle.
func (*Faker) ProductTitle ¶ added in v0.27.0
ProductTitle returns a product title for a listing ("Rustic Oak Desk", "Cadeira Ergonômica de Aço").
func (*Faker) State ¶ added in v0.27.0
State returns a state code ("IL", "SP"), independent of City; Address keeps the two consistent.
func (*Faker) StreetAddress ¶ added in v0.27.0
StreetAddress returns a street and number ("742 Maple Ave", "Rua das Flores, 120").
func (*Faker) WithLocale ¶ added in v0.27.0
WithLocale makes f generate names, words, companies, products and addresses in l, and returns f. It consumes no randomness, so the output stays reproducible for the seed.
Example ¶
package main
import (
"fmt"
"github.com/AlexGalhardo/vukem/factory"
)
func main() {
f := factory.NewFaker(2026).WithLocale(factory.LocalePTBR())
fmt.Println(f.Name())
fmt.Println(f.ProductTitle())
fmt.Println(f.Category())
fmt.Println(f.Address())
}
Output: Arthur Dias Mochila Rústica de Cerâmica Beleza Avenida Getúlio Vargas, 748 - Manaus/AM, 37267-205
type Locale ¶ added in v0.27.0
type Locale struct {
// contains filtered or unexported fields
}
Locale selects the language and country of the data a Faker generates.
The zero Locale is not English: it is the original data set (a mixed list of mostly Brazilian first names, lorem ipsum words), kept so that NewFaker(seed) and Factory.Seed(n) produce the same rows they did before locales existed. Only the methods that data set never had (Company, ProductTitle, ProductDescription, Category and the address methods) use English data there. Pass LocaleEN or LocalePTBR for one consistent language.
func LocaleEN ¶ added in v0.27.0
func LocaleEN() Locale
LocaleEN returns the English (United States) locale.
func LocalePTBR ¶ added in v0.27.0
func LocalePTBR() Locale
LocalePTBR returns the Brazilian Portuguese locale.