diff --git a/collection/collection.go b/collection/collection.go index 1149b9c7..b21d0cc9 100644 --- a/collection/collection.go +++ b/collection/collection.go @@ -166,3 +166,18 @@ func (c *Collection[T]) SortBy(fn func(T, T) bool) *Collection[T] { func (c *Collection[T]) Dump() { debug.Dump(c.items) } + +func (c *Collection[T]) When(condition bool, fns ...func(*Collection[T])) *Collection[T] { + if condition { + for _, fn := range fns { + if fn != nil { + fn(c) + } + } + } + return c +} + +func (c *Collection[T]) Unless(condition bool, fns ...func(*Collection[T])) *Collection[T] { + return c.When(!condition, fns...) +} diff --git a/collection/collection_test.go b/collection/collection_test.go index ffdbe347..f5cded80 100644 --- a/collection/collection_test.go +++ b/collection/collection_test.go @@ -316,3 +316,31 @@ func TestCollection_Ptr(t *testing.T) { c.Dump() }) } + +func TestCollection_When(t *testing.T) { + c := New([]int{1, 2, 3}) + c.When(true, func(c *Collection[int]) { + c.Add(4) + }) + assert.Equal(t, 4, c.Len()) + assert.Equal(t, []int{1, 2, 3, 4}, c.Items()) + c.When(false, func(c *Collection[int]) { + c.Add(5) + }) + assert.Equal(t, 4, c.Len()) + assert.Equal(t, []int{1, 2, 3, 4}, c.Items()) +} + +func TestCollection_Unless(t *testing.T) { + c := New([]int{1, 2, 3}) + c.Unless(false, func(c *Collection[int]) { + c.Add(4) + }) + assert.Equal(t, 4, c.Len()) + assert.Equal(t, []int{1, 2, 3, 4}, c.Items()) + c.Unless(true, func(c *Collection[int]) { + c.Add(5) + }) + assert.Equal(t, 4, c.Len()) + assert.Equal(t, []int{1, 2, 3, 4}, c.Items()) +} diff --git a/helper/helper_test.go b/helper/helper_test.go index d7fd06ed..8e0932df 100644 --- a/helper/helper_test.go +++ b/helper/helper_test.go @@ -112,7 +112,7 @@ func TestWhen(t *testing.T) { assert.Equal(t, 18, f2.Age) f3 := When(f, false, func(f *foo) *foo { - f.Name = "baz" + f.Name = "baz" //nolint:goconst f.Age = 20 return f }) diff --git a/helper/proxy.go b/helper/proxy.go new file mode 100644 index 00000000..bd4c9371 --- /dev/null +++ b/helper/proxy.go @@ -0,0 +1,47 @@ +package helper + +type Proxy[T any] struct { + target T +} + +func NewProxy[T any](target T) *Proxy[T] { + return &Proxy[T]{ + target: target, + } +} + +func (p *Proxy[T]) Tap(callbacks ...func(T)) T { + for _, callback := range callbacks { + if callback != nil { + callback(p.target) + } + } + + return p.target +} + +func (p *Proxy[T]) With(callbacks ...func(T) T) T { + for _, callback := range callbacks { + if callback != nil { + p.target = callback(p.target) + } + } + + return p.target +} + +func (p *Proxy[T]) When(condition bool, callbacks ...func(T) T) T { + if condition { + return p.With(callbacks...) + } + + return p.target +} + +func (p *Proxy[T]) Unless(condition bool, callbacks ...func(T) T) T { + return p.When(!condition, callbacks...) +} + +func (p *Proxy[T]) Target() T { + return p.target +} diff --git a/helper/proxy_test.go b/helper/proxy_test.go new file mode 100644 index 00000000..cac6ebb9 --- /dev/null +++ b/helper/proxy_test.go @@ -0,0 +1,101 @@ +package helper + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +type proxyMock struct { + Name string + Age int +} + +func TestProxy_Point(t *testing.T) { + mock := &proxyMock{Name: "foo"} + + proxy := NewProxy(mock) + assert.Equal(t, "foo", proxy.target.Name) + assert.Equal(t, 0, proxy.target.Age) + + mock2 := proxy.Tap(func(p *proxyMock) { + p.Name = "bar" + p.Age = 18 + }) + assert.Equal(t, "bar", proxy.target.Name) + assert.Equal(t, 18, proxy.target.Age) + assert.Equal(t, "bar", mock.Name) + assert.Equal(t, mock, mock2) + + mock3 := proxy.With(func(p *proxyMock) *proxyMock { + p.Name = "baz" + p.Age = 20 + return p + }) + assert.Equal(t, "baz", proxy.target.Name) + assert.Equal(t, 20, proxy.target.Age) + assert.Equal(t, "baz", mock.Name) + assert.Equal(t, mock, mock3) + + mock4 := proxy.When(true, func(p *proxyMock) *proxyMock { + p.Name = "qux" + p.Age = 22 + return p + }) + assert.Equal(t, "qux", proxy.target.Name) + assert.Equal(t, 22, proxy.target.Age) + assert.Equal(t, "qux", mock.Name) + assert.Equal(t, mock, mock4) + + mock5 := proxy.Target() + assert.Equal(t, mock, mock5) +} + +func TestProxy_Struct(t *testing.T) { + mock := proxyMock{Name: "foo"} + + proxy := NewProxy(mock) + assert.Equal(t, "foo", proxy.target.Name) + assert.Equal(t, 0, proxy.target.Age) + + mock2 := proxy.Tap(func(p proxyMock) { + p.Name = "bar" + p.Age = 18 + }) + assert.Equal(t, "foo", proxy.target.Name) + assert.Equal(t, 0, proxy.target.Age) + assert.Equal(t, "foo", mock2.Name) + + mock3 := proxy.With(func(p proxyMock) proxyMock { + p.Name = "baz" + p.Age = 20 + return p + }) + assert.Equal(t, "baz", proxy.target.Name) + assert.Equal(t, 20, proxy.target.Age) + assert.Equal(t, "baz", mock3.Name) + assert.NotEqual(t, mock, mock3) + + mock4 := proxy.When(true, func(p proxyMock) proxyMock { + p.Name = "qux" + p.Age = 22 + return p + }) + assert.Equal(t, "qux", proxy.target.Name) + assert.Equal(t, 22, proxy.target.Age) + assert.Equal(t, "qux", mock4.Name) + assert.NotEqual(t, mock, mock4) + + mock5 := proxy.Target() + assert.NotEqual(t, mock, mock5) + + mock6 := proxy.Unless(true, func(p proxyMock) proxyMock { + p.Name = "quux" + p.Age = 24 + return p + }) + assert.Equal(t, "qux", proxy.target.Name) + assert.Equal(t, 22, proxy.target.Age) + assert.Equal(t, "qux", mock6.Name) + assert.NotEqual(t, mock, mock6) +}