Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [v0.2.0] - 2025-10-02

### Changed
- `fix.New` now returns a function instead of an interface
- `fix.Fixture` type is now a function type instead of an interface


## [v0.1.1] - 2025-09-18

### Added
- Support for `go 1.25`


## [v0.1.0] - 2025-07-31

### Added
- `fix.New` function for creating new fixtures
- `fix.Fixture` interface
18 changes: 9 additions & 9 deletions examples/userstore_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,37 +11,37 @@ func TestUserStore(t *testing.T) {
t.Run("Creates user", func(t *testing.T) {
// given
name := "John"
store := fixtureUserStore.Value(t)
store := fixtureUserStore(t)

// when
err := store.CreateUser(name)

// then
equal(t, nil, err)
statements := *fixtureStatements.Value(t)
statements := *fixtureStatements(t)
equal(t, 1, len(statements))
equal(t, "INSERT "+name, statements[0])
})

t.Run("Deletes user", func(t *testing.T) {
// given
name := fixtureExistingUser.Value(t)
store := fixtureUserStore.Value(t)
name := fixtureExistingUser(t)
store := fixtureUserStore(t)

// when
err := store.DeleteUser(name)

// then
equal(t, nil, err)
statements := *fixtureStatements.Value(t)
statements := *fixtureStatements(t)
equal(t, 1, len(statements))
equal(t, "DELETE "+name, statements[0])
})
}

var fixtureExistingUser = fix.New(func(t *testing.T) string {
t.Helper()
userStore := fixtureUserStore.Value(t)
userStore := fixtureUserStore(t)

username := "Doe"
err := userStore.CreateUser(username)
Expand All @@ -51,22 +51,22 @@ var fixtureExistingUser = fix.New(func(t *testing.T) string {
return ""
}

statements := fixtureStatements.Value(t)
statements := fixtureStatements(t)
*statements = []string{}

return username
})

var fixtureUserStore = fix.New(func(t *testing.T) examples.UserStore {
t.Helper()
db := fixtureMockDB.Value(t)
db := fixtureMockDB(t)

return examples.NewUserStore(db)
})

var fixtureMockDB = fix.New(func(t *testing.T) examples.DB {
t.Helper()
statements := fixtureStatements.Value(t)
statements := fixtureStatements(t)

return examples.NewMockDB(func(statement string) error {
*statements = append(*statements, statement)
Expand Down
12 changes: 7 additions & 5 deletions fixture.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,21 @@ import (

var ctxOffset int

type Fixture[V any] interface {
Value(t *testing.T) V
}
type Fixture[V any] func(t *testing.T) V

func New[V any](createValue func(t *testing.T) V) Fixture[V] {
return &fixture[V]{createValue}
f := &fixture[V]{createValue}

return func(t *testing.T) V {
return f.value(t)
}
}

type fixture[V any] struct {
createValue func(t *testing.T) V
}

func (f *fixture[V]) Value(t *testing.T) V {
func (f *fixture[V]) value(t *testing.T) V {
if value, ok := t.Context().Value(f).(V); ok {
return value
}
Expand Down
18 changes: 9 additions & 9 deletions fixture_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ func TestFixture(topT *testing.T) {
})

// when
result := fixture.Value(t)
result := fixture(t)

// then
equal(t, "haha", result)
Expand All @@ -29,8 +29,8 @@ func TestFixture(topT *testing.T) {
})

// when
fixture.Value(t)
fixture.Value(t)
fixture(t)
fixture(t)

// then
equal(t, 1, fixtureCreationCount)
Expand All @@ -43,11 +43,11 @@ func TestFixture(topT *testing.T) {
})

fixture2 := fix.New(func(t *testing.T) int {
return fixture1.Value(t) + 2
return fixture1(t) + 2
})

// when
result := fixture2.Value(t)
result := fixture2(t)

// then
equal(t, 3, result)
Expand All @@ -62,15 +62,15 @@ func TestFixture(topT *testing.T) {
topT.Run("Mixed scope fixtures are working", func(t *testing.T) {
// given
fixture1 := fix.New(func(t *testing.T) string {
return topLevelFixture.Value(topT) + " this works too "
return topLevelFixture(topT) + " this works too "
})

fixture2 := fix.New(func(t *testing.T) string {
return fixture1.Value(t) + topLevelFixture.Value(topT)
return fixture1(t) + topLevelFixture(topT)
})

// when
result := fixture2.Value(t)
result := fixture2(t)

// then
equal(t, "!yay! this works too !yay!", result)
Expand All @@ -84,7 +84,7 @@ func TestFixture(topT *testing.T) {
return nil
})

fixture.Value(t)
fixture(t)
equal(t, 0, counter)
})

Expand Down