package opt_test import ( "errors" "strconv" "testing" "go.jolheiser.com/opt" "github.com/matryer/is" ) func TestOptions(t *testing.T) { assert := is.New(t) f := NewFoo(WithBar("bar")) assert.Equal(f.Bar, "bar") // Option should set bar opt.Apply(f, WithBaz(100)) assert.Equal(f.Baz, 100) // Apply should set Baz _, err := NewErrorFoo(WithBarErr("bar")) assert.True(err != nil) // ErrorOption should return error assert.Equal(err.Error(), "bar") // ErrorOption error should be bar err = opt.ApplyError(f, WithBazErr(100)) assert.True(err != nil) // ApplyError should return error assert.Equal(err.Error(), "100") // ApplyError error should be 100 } type Foo struct { Bar string Baz int } func WithBar(b string) opt.Func[Foo] { return func(f *Foo) { f.Bar = b } } func WithBaz(b int) opt.Func[Foo] { return func(f *Foo) { f.Baz = b } } func NewFoo(opts ...opt.Func[Foo]) *Foo { f := &Foo{ /** some defaults **/ } opt.Apply(f, opts...) return f } func NewErrorFoo(opts ...opt.ErrorFunc[Foo]) (*Foo, error) { f := &Foo{ /** some defaults **/ } return f, opt.ApplyError(f, opts...) } func WithBarErr(b string) opt.ErrorFunc[Foo] { return func(f *Foo) error { return errors.New(b) } } func WithBazErr(b int) opt.ErrorFunc[Foo] { return func(f *Foo) error { return errors.New(strconv.Itoa(b)) } }