Commit 1a2af5f
Changed files (2)
pkg
pkg/x/option.go
@@ -5,7 +5,10 @@ type Option[T any] func(T) T
type Factory[T any] func() T
func New[T any](options ...Option[T]) T {
- item := Default[T]()
+ return NewWith[T](Default[T](), options...)
+}
+
+func NewWith[T any](item T, options ...Option[T]) T {
for _, option := range options {
item = option(item)
}
pkg/x/option_test.go
@@ -0,0 +1,81 @@
+package x
+
+import (
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+)
+
+type person struct {
+ name string
+ age int
+}
+
+func withName(name string) Option[*person] {
+ return With(func(person *person) {
+ person.name = name
+ })
+}
+
+func withAge(age int) Option[*person] {
+ return With(func(person *person) {
+ person.age = age
+ })
+}
+
+func TestOption(t *testing.T) {
+ t.Run("New", func(t *testing.T) {
+ t.Run("without options", func(t *testing.T) {
+ item := New[*person]()
+
+ require.NotNil(t, item)
+ assert.Equal(t, "", item.name)
+ assert.Zero(t, item.age)
+ })
+
+ t.Run("with name", func(t *testing.T) {
+ item := New[*person](withName("mo"))
+
+ require.NotNil(t, item)
+ assert.Equal(t, "mo", item.name)
+ })
+
+ t.Run("with age", func(t *testing.T) {
+ item := New[*person](withAge(42))
+
+ require.NotNil(t, item)
+ assert.Equal(t, 42, item.age)
+ })
+ })
+
+ t.Run("NewWith", func(t *testing.T) {
+ t.Run("without options", func(t *testing.T) {
+ p := &person{}
+ item := NewWith[*person](p)
+
+ require.NotNil(t, item)
+ require.Same(t, p, item)
+ assert.Equal(t, "", item.name)
+ assert.Zero(t, item.age)
+ })
+
+ t.Run("with name", func(t *testing.T) {
+ p := &person{}
+ item := NewWith[*person](p, withName("mo"))
+
+ require.NotNil(t, item)
+ require.Same(t, p, item)
+ assert.Equal(t, "mo", item.name)
+ })
+
+ t.Run("with age", func(t *testing.T) {
+ p := &person{}
+ item := NewWith[*person](p, withAge(42))
+
+ require.NotNil(t, item)
+ require.Same(t, p, item)
+ assert.Equal(t, 42, item.age)
+ })
+ })
+}