bump v1.50.0

This commit is contained in:
samber
2025-04-26 17:26:18 +00:00
parent 4a43ff68b4
commit 5c8d84b205
39 changed files with 0 additions and 10446 deletions

View File

@@ -1,427 +0,0 @@
package lo
import (
"context"
"math/rand"
"testing"
"time"
"github.com/stretchr/testify/assert"
)
func TestChannelDispatcher(t *testing.T) {
t.Parallel()
testWithTimeout(t, 100*time.Millisecond)
is := assert.New(t)
ch := make(chan int, 10)
ch <- 0
ch <- 1
ch <- 2
ch <- 3
is.Equal(4, len(ch))
children := ChannelDispatcher(ch, 5, 10, DispatchingStrategyRoundRobin[int])
time.Sleep(10 * time.Millisecond)
// check channels allocation
is.Equal(5, len(children))
is.Equal(10, cap(children[0]))
is.Equal(10, cap(children[1]))
is.Equal(10, cap(children[2]))
is.Equal(10, cap(children[3]))
is.Equal(10, cap(children[4]))
is.Equal(1, len(children[0]))
is.Equal(1, len(children[1]))
is.Equal(1, len(children[2]))
is.Equal(1, len(children[3]))
is.Equal(0, len(children[4]))
// check channels content
is.Equal(0, len(ch))
msg0, ok0 := <-children[0]
is.Equal(ok0, true)
is.Equal(msg0, 0)
msg1, ok1 := <-children[1]
is.Equal(ok1, true)
is.Equal(msg1, 1)
msg2, ok2 := <-children[2]
is.Equal(ok2, true)
is.Equal(msg2, 2)
msg3, ok3 := <-children[3]
is.Equal(ok3, true)
is.Equal(msg3, 3)
// msg4, ok4 := <-children[4]
// is.Equal(ok4, false)
// is.Equal(msg4, 0)
// is.Nil(children[4])
// check it is closed
close(ch)
time.Sleep(10 * time.Millisecond)
is.Panics(func() {
ch <- 42
})
msg0, ok0 = <-children[0]
is.Equal(ok0, false)
is.Equal(msg0, 0)
msg1, ok1 = <-children[1]
is.Equal(ok1, false)
is.Equal(msg1, 0)
msg2, ok2 = <-children[2]
is.Equal(ok2, false)
is.Equal(msg2, 0)
msg3, ok3 = <-children[3]
is.Equal(ok3, false)
is.Equal(msg3, 0)
msg4, ok4 := <-children[4]
is.Equal(ok4, false)
is.Equal(msg4, 0)
// unbuffered channels
children = ChannelDispatcher(ch, 5, 0, DispatchingStrategyRoundRobin[int])
is.Equal(0, cap(children[0]))
}
func TestDispatchingStrategyRoundRobin(t *testing.T) {
t.Parallel()
testWithTimeout(t, 10*time.Millisecond)
is := assert.New(t)
children := createChannels[int](3, 2)
rochildren := channelsToReadOnly(children)
defer closeChannels(children)
is.Equal(0, DispatchingStrategyRoundRobin(42, 0, rochildren))
is.Equal(1, DispatchingStrategyRoundRobin(42, 1, rochildren))
is.Equal(2, DispatchingStrategyRoundRobin(42, 2, rochildren))
is.Equal(0, DispatchingStrategyRoundRobin(42, 3, rochildren))
}
func TestDispatchingStrategyRandom(t *testing.T) {
testWithTimeout(t, 10*time.Millisecond)
is := assert.New(t)
// with this seed, the order of random channels are: 1 - 0
rand.Seed(14)
children := createChannels[int](2, 2)
rochildren := channelsToReadOnly(children)
defer closeChannels(children)
for i := 0; i < 2; i++ {
children[1] <- i
}
is.Equal(0, DispatchingStrategyRandom(42, 0, rochildren))
}
func TestDispatchingStrategyWeightedRandom(t *testing.T) {
t.Parallel()
testWithTimeout(t, 10*time.Millisecond)
is := assert.New(t)
children := createChannels[int](2, 2)
rochildren := channelsToReadOnly(children)
defer closeChannels(children)
dispatcher := DispatchingStrategyWeightedRandom[int]([]int{0, 42})
is.Equal(1, dispatcher(42, 0, rochildren))
children[0] <- 0
is.Equal(1, dispatcher(42, 0, rochildren))
children[1] <- 1
is.Equal(1, dispatcher(42, 0, rochildren))
}
func TestDispatchingStrategyFirst(t *testing.T) {
t.Parallel()
testWithTimeout(t, 10*time.Millisecond)
is := assert.New(t)
children := createChannels[int](2, 2)
rochildren := channelsToReadOnly(children)
defer closeChannels(children)
is.Equal(0, DispatchingStrategyFirst(42, 0, rochildren))
children[0] <- 0
is.Equal(0, DispatchingStrategyFirst(42, 0, rochildren))
children[0] <- 1
is.Equal(1, DispatchingStrategyFirst(42, 0, rochildren))
}
func TestDispatchingStrategyLeast(t *testing.T) {
t.Parallel()
testWithTimeout(t, 10*time.Millisecond)
is := assert.New(t)
children := createChannels[int](2, 2)
rochildren := channelsToReadOnly(children)
defer closeChannels(children)
is.Equal(0, DispatchingStrategyLeast(42, 0, rochildren))
children[0] <- 0
is.Equal(1, DispatchingStrategyLeast(42, 0, rochildren))
children[1] <- 0
is.Equal(0, DispatchingStrategyLeast(42, 0, rochildren))
children[0] <- 1
is.Equal(1, DispatchingStrategyLeast(42, 0, rochildren))
children[1] <- 1
is.Equal(0, DispatchingStrategyLeast(42, 0, rochildren))
}
func TestDispatchingStrategyMost(t *testing.T) {
t.Parallel()
testWithTimeout(t, 10*time.Millisecond)
is := assert.New(t)
children := createChannels[int](2, 2)
rochildren := channelsToReadOnly(children)
defer closeChannels(children)
is.Equal(0, DispatchingStrategyMost(42, 0, rochildren))
children[0] <- 0
is.Equal(0, DispatchingStrategyMost(42, 0, rochildren))
children[1] <- 0
is.Equal(0, DispatchingStrategyMost(42, 0, rochildren))
children[0] <- 1
is.Equal(0, DispatchingStrategyMost(42, 0, rochildren))
children[1] <- 1
is.Equal(0, DispatchingStrategyMost(42, 0, rochildren))
}
func TestSliceToChannel(t *testing.T) {
t.Parallel()
testWithTimeout(t, 10*time.Millisecond)
is := assert.New(t)
ch := SliceToChannel(2, []int{1, 2, 3})
r1, ok1 := <-ch
r2, ok2 := <-ch
r3, ok3 := <-ch
is.True(ok1)
is.Equal(1, r1)
is.True(ok2)
is.Equal(2, r2)
is.True(ok3)
is.Equal(3, r3)
_, ok4 := <-ch
is.False(ok4)
}
func TestChannelToSlice(t *testing.T) {
t.Parallel()
testWithTimeout(t, 10*time.Millisecond)
is := assert.New(t)
ch := SliceToChannel(2, []int{1, 2, 3})
items := ChannelToSlice(ch)
is.Equal([]int{1, 2, 3}, items)
}
func TestGenerate(t *testing.T) {
t.Parallel()
testWithTimeout(t, 10*time.Millisecond)
is := assert.New(t)
generator := func(yield func(int)) {
yield(0)
yield(1)
yield(2)
yield(3)
}
i := 0
for v := range Generator(2, generator) {
is.Equal(i, v)
i++
}
is.Equal(i, 4)
}
func TestBuffer(t *testing.T) {
t.Parallel()
testWithTimeout(t, 10*time.Millisecond)
is := assert.New(t)
ch := SliceToChannel(2, []int{1, 2, 3})
items1, length1, _, ok1 := Buffer(ch, 2)
items2, length2, _, ok2 := Buffer(ch, 2)
items3, length3, _, ok3 := Buffer(ch, 2)
is.Equal([]int{1, 2}, items1)
is.Equal(2, length1)
is.True(ok1)
is.Equal([]int{3}, items2)
is.Equal(1, length2)
is.False(ok2)
is.Equal([]int{}, items3)
is.Equal(0, length3)
is.False(ok3)
}
func TestBufferWithContext(t *testing.T) {
t.Parallel()
testWithTimeout(t, 200*time.Millisecond)
is := assert.New(t)
ch1 := make(chan int, 10)
ctx, cancel := context.WithCancel(context.Background())
go func() {
ch1 <- 0
ch1 <- 1
ch1 <- 2
time.Sleep(5 * time.Millisecond)
cancel()
ch1 <- 3
ch1 <- 4
ch1 <- 5
close(ch1)
}()
items1, length1, _, ok1 := BufferWithContext(ctx, ch1, 20)
is.Equal([]int{0, 1, 2}, items1)
is.Equal(3, length1)
is.True(ok1)
ch2 := make(chan int, 10)
ctx, cancel = context.WithCancel(context.Background())
defer cancel()
defer close(ch2)
for i := 0; i < 10; i++ {
ch2 <- i
}
items2, length2, _, ok2 := BufferWithContext(ctx, ch2, 5)
is.Equal([]int{0, 1, 2, 3, 4}, items2)
is.Equal(5, length2)
is.True(ok2)
}
func TestBufferWithTimeout(t *testing.T) {
t.Parallel()
testWithTimeout(t, 200*time.Millisecond)
is := assert.New(t)
generator := func(yield func(int)) {
for i := 0; i < 5; i++ {
yield(i)
time.Sleep(10 * time.Millisecond)
}
}
ch := Generator(0, generator)
items1, length1, _, ok1 := BufferWithTimeout(ch, 20, 15*time.Millisecond)
is.Equal([]int{0, 1}, items1)
is.Equal(2, length1)
is.True(ok1)
items2, length2, _, ok2 := BufferWithTimeout(ch, 20, 2*time.Millisecond)
is.Equal([]int{}, items2)
is.Equal(0, length2)
is.True(ok2)
items3, length3, _, ok3 := BufferWithTimeout(ch, 1, 30*time.Millisecond)
is.Equal([]int{2}, items3)
is.Equal(1, length3)
is.True(ok3)
items4, length4, _, ok4 := BufferWithTimeout(ch, 2, 25*time.Millisecond)
is.Equal([]int{3, 4}, items4)
is.Equal(2, length4)
is.True(ok4)
items5, length5, _, ok5 := BufferWithTimeout(ch, 3, 25*time.Millisecond)
is.Equal([]int{}, items5)
is.Equal(0, length5)
is.False(ok5)
}
func TestFanIn(t *testing.T) {
t.Parallel()
testWithTimeout(t, 100*time.Millisecond)
is := assert.New(t)
upstreams := createChannels[int](3, 10)
roupstreams := channelsToReadOnly(upstreams)
for i := range roupstreams {
go func(i int) {
upstreams[i] <- 1
upstreams[i] <- 1
close(upstreams[i])
}(i)
}
out := FanIn(10, roupstreams...)
time.Sleep(10 * time.Millisecond)
// check input channels
is.Equal(0, len(roupstreams[0]))
is.Equal(0, len(roupstreams[1]))
is.Equal(0, len(roupstreams[2]))
// check channels allocation
is.Equal(6, len(out))
is.Equal(10, cap(out))
// check channels content
for i := 0; i < 6; i++ {
msg0, ok0 := <-out
is.Equal(true, ok0)
is.Equal(1, msg0)
}
// check it is closed
time.Sleep(10 * time.Millisecond)
msg0, ok0 := <-out
is.Equal(false, ok0)
is.Equal(0, msg0)
}
func TestFanOut(t *testing.T) {
t.Parallel()
testWithTimeout(t, 100*time.Millisecond)
is := assert.New(t)
upstream := SliceToChannel(10, []int{0, 1, 2, 3, 4, 5})
rodownstreams := FanOut(3, 10, upstream)
time.Sleep(10 * time.Millisecond)
// check output channels
is.Equal(3, len(rodownstreams))
// check channels allocation
for i := range rodownstreams {
is.Equal(6, len(rodownstreams[i]))
is.Equal(10, cap(rodownstreams[i]))
is.Equal([]int{0, 1, 2, 3, 4, 5}, ChannelToSlice(rodownstreams[i]))
}
// check it is closed
time.Sleep(10 * time.Millisecond)
// check channels allocation
for i := range rodownstreams {
msg, ok := <-rodownstreams[i]
is.Equal(false, ok)
is.Equal(0, msg)
}
}

View File

@@ -1,413 +0,0 @@
package lo
import (
"context"
"sync"
"testing"
"time"
"github.com/stretchr/testify/assert"
)
func TestSynchronize(t *testing.T) {
t.Parallel()
testWithTimeout(t, 100*time.Millisecond)
is := assert.New(t)
// check that callbacks are not executed concurrently
{
start := time.Now()
wg := sync.WaitGroup{}
wg.Add(10)
s := Synchronize()
for i := 0; i < 10; i++ {
go s.Do(func() {
time.Sleep(5 * time.Millisecond)
wg.Done()
})
}
wg.Wait()
duration := time.Since(start)
is.Greater(duration, 50*time.Millisecond)
is.Less(duration, 60*time.Millisecond)
}
// check locker is locked
{
mu := &sync.Mutex{}
s := Synchronize(mu)
s.Do(func() {
is.False(mu.TryLock())
})
is.True(mu.TryLock())
Try0(func() {
mu.Unlock()
})
}
// check we don't accept multiple arguments
{
is.PanicsWithValue("unexpected arguments", func() {
mu := &sync.Mutex{}
Synchronize(mu, mu, mu)
})
}
}
func TestAsync(t *testing.T) {
t.Parallel()
testWithTimeout(t, 100*time.Millisecond)
is := assert.New(t)
sync := make(chan struct{})
ch := Async(func() int {
<-sync
return 10
})
sync <- struct{}{}
select {
case result := <-ch:
is.Equal(result, 10)
case <-time.After(time.Millisecond):
is.Fail("Async should not block")
}
}
func TestAsyncX(t *testing.T) {
t.Parallel()
testWithTimeout(t, 100*time.Millisecond)
is := assert.New(t)
{
sync := make(chan struct{})
ch := Async0(func() {
<-sync
})
sync <- struct{}{}
select {
case <-ch:
case <-time.After(time.Millisecond):
is.Fail("Async0 should not block")
}
}
{
sync := make(chan struct{})
ch := Async1(func() int {
<-sync
return 10
})
sync <- struct{}{}
select {
case result := <-ch:
is.Equal(result, 10)
case <-time.After(time.Millisecond):
is.Fail("Async1 should not block")
}
}
{
sync := make(chan struct{})
ch := Async2(func() (int, string) {
<-sync
return 10, "Hello"
})
sync <- struct{}{}
select {
case result := <-ch:
is.Equal(result, Tuple2[int, string]{10, "Hello"})
case <-time.After(time.Millisecond):
is.Fail("Async2 should not block")
}
}
{
sync := make(chan struct{})
ch := Async3(func() (int, string, bool) {
<-sync
return 10, "Hello", true
})
sync <- struct{}{}
select {
case result := <-ch:
is.Equal(result, Tuple3[int, string, bool]{10, "Hello", true})
case <-time.After(time.Millisecond):
is.Fail("Async3 should not block")
}
}
{
sync := make(chan struct{})
ch := Async4(func() (int, string, bool, float64) {
<-sync
return 10, "Hello", true, 3.14
})
sync <- struct{}{}
select {
case result := <-ch:
is.Equal(result, Tuple4[int, string, bool, float64]{10, "Hello", true, 3.14})
case <-time.After(time.Millisecond):
is.Fail("Async4 should not block")
}
}
{
sync := make(chan struct{})
ch := Async5(func() (int, string, bool, float64, string) {
<-sync
return 10, "Hello", true, 3.14, "World"
})
sync <- struct{}{}
select {
case result := <-ch:
is.Equal(result, Tuple5[int, string, bool, float64, string]{10, "Hello", true, 3.14, "World"})
case <-time.After(time.Millisecond):
is.Fail("Async5 should not block")
}
}
{
sync := make(chan struct{})
ch := Async6(func() (int, string, bool, float64, string, int) {
<-sync
return 10, "Hello", true, 3.14, "World", 100
})
sync <- struct{}{}
select {
case result := <-ch:
is.Equal(result, Tuple6[int, string, bool, float64, string, int]{10, "Hello", true, 3.14, "World", 100})
case <-time.After(time.Millisecond):
is.Fail("Async6 should not block")
}
}
}
func TestWaitFor(t *testing.T) {
t.Parallel()
testTimeout := 100 * time.Millisecond
longTimeout := 2 * testTimeout
shortTimeout := 4 * time.Millisecond
t.Run("exist condition works", func(t *testing.T) {
t.Parallel()
testWithTimeout(t, testTimeout)
is := assert.New(t)
laterTrue := func(i int) bool {
return i >= 5
}
iter, duration, ok := WaitFor(laterTrue, longTimeout, time.Millisecond)
is.Equal(6, iter, "unexpected iteration count")
is.InEpsilon(6*time.Millisecond, duration, float64(500*time.Microsecond))
is.True(ok)
})
t.Run("counter is incremented", func(t *testing.T) {
t.Parallel()
testWithTimeout(t, testTimeout)
is := assert.New(t)
counter := 0
alwaysFalse := func(i int) bool {
is.Equal(counter, i)
counter++
return false
}
iter, duration, ok := WaitFor(alwaysFalse, shortTimeout, 1050*time.Microsecond)
is.Equal(counter, iter, "unexpected iteration count")
is.InEpsilon(10*time.Millisecond, duration, float64(500*time.Microsecond))
is.False(ok)
})
alwaysTrue := func(_ int) bool { return true }
alwaysFalse := func(_ int) bool { return false }
t.Run("short timeout works", func(t *testing.T) {
t.Parallel()
testWithTimeout(t, testTimeout)
is := assert.New(t)
iter, duration, ok := WaitFor(alwaysFalse, shortTimeout, 10*time.Millisecond)
is.Equal(0, iter, "unexpected iteration count")
is.InEpsilon(10*time.Millisecond, duration, float64(500*time.Microsecond))
is.False(ok)
})
t.Run("timeout works", func(t *testing.T) {
t.Parallel()
testWithTimeout(t, testTimeout)
is := assert.New(t)
shortTimeout := 4 * time.Millisecond
iter, duration, ok := WaitFor(alwaysFalse, shortTimeout, 10*time.Millisecond)
is.Equal(0, iter, "unexpected iteration count")
is.InEpsilon(10*time.Millisecond, duration, float64(500*time.Microsecond))
is.False(ok)
})
t.Run("exist on first condition", func(t *testing.T) {
t.Parallel()
testWithTimeout(t, testTimeout)
is := assert.New(t)
iter, duration, ok := WaitFor(alwaysTrue, 10*time.Millisecond, time.Millisecond)
is.Equal(1, iter, "unexpected iteration count")
is.InEpsilon(time.Millisecond, duration, float64(5*time.Microsecond))
is.True(ok)
})
}
func TestWaitForWithContext(t *testing.T) {
t.Parallel()
testTimeout := 100 * time.Millisecond
longTimeout := 2 * testTimeout
shortTimeout := 4 * time.Millisecond
t.Run("exist condition works", func(t *testing.T) {
t.Parallel()
testWithTimeout(t, testTimeout)
is := assert.New(t)
laterTrue := func(_ context.Context, i int) bool {
return i >= 5
}
iter, duration, ok := WaitForWithContext(context.Background(), laterTrue, longTimeout, time.Millisecond)
is.Equal(6, iter, "unexpected iteration count")
is.InEpsilon(6*time.Millisecond, duration, float64(500*time.Microsecond))
is.True(ok)
})
t.Run("counter is incremented", func(t *testing.T) {
t.Parallel()
testWithTimeout(t, testTimeout)
is := assert.New(t)
counter := 0
alwaysFalse := func(_ context.Context, i int) bool {
is.Equal(counter, i)
counter++
return false
}
iter, duration, ok := WaitForWithContext(context.Background(), alwaysFalse, shortTimeout, 1050*time.Microsecond)
is.Equal(counter, iter, "unexpected iteration count")
is.InEpsilon(10*time.Millisecond, duration, float64(500*time.Microsecond))
is.False(ok)
})
alwaysTrue := func(_ context.Context, _ int) bool { return true }
alwaysFalse := func(_ context.Context, _ int) bool { return false }
t.Run("short timeout works", func(t *testing.T) {
t.Parallel()
testWithTimeout(t, testTimeout)
is := assert.New(t)
iter, duration, ok := WaitForWithContext(context.Background(), alwaysFalse, shortTimeout, 10*time.Millisecond)
is.Equal(0, iter, "unexpected iteration count")
is.InEpsilon(10*time.Millisecond, duration, float64(500*time.Microsecond))
is.False(ok)
})
t.Run("timeout works", func(t *testing.T) {
t.Parallel()
testWithTimeout(t, testTimeout)
is := assert.New(t)
shortTimeout := 4 * time.Millisecond
iter, duration, ok := WaitForWithContext(context.Background(), alwaysFalse, shortTimeout, 10*time.Millisecond)
is.Equal(0, iter, "unexpected iteration count")
is.InEpsilon(10*time.Millisecond, duration, float64(500*time.Microsecond))
is.False(ok)
})
t.Run("exist on first condition", func(t *testing.T) {
t.Parallel()
testWithTimeout(t, testTimeout)
is := assert.New(t)
iter, duration, ok := WaitForWithContext(context.Background(), alwaysTrue, 10*time.Millisecond, time.Millisecond)
is.Equal(1, iter, "unexpected iteration count")
is.InEpsilon(time.Millisecond, duration, float64(5*time.Microsecond))
is.True(ok)
})
t.Run("context cancellation stops everything", func(t *testing.T) {
t.Parallel()
testWithTimeout(t, testTimeout)
is := assert.New(t)
expiringCtx, clean := context.WithTimeout(context.Background(), 8*time.Millisecond)
t.Cleanup(func() {
clean()
})
iter, duration, ok := WaitForWithContext(expiringCtx, alwaysFalse, 100*time.Millisecond, 3*time.Millisecond)
is.Equal(2, iter, "unexpected iteration count")
is.InEpsilon(10*time.Millisecond, duration, float64(500*time.Microsecond))
is.False(ok)
})
t.Run("canceled context stops everything", func(t *testing.T) {
t.Parallel()
testWithTimeout(t, testTimeout)
is := assert.New(t)
canceledCtx, cancel := context.WithCancel(context.Background())
cancel()
iter, duration, ok := WaitForWithContext(canceledCtx, alwaysFalse, 100*time.Millisecond, 1050*time.Microsecond)
is.Equal(0, iter, "unexpected iteration count")
is.InEpsilon(1*time.Millisecond, duration, float64(5*time.Microsecond))
is.False(ok)
})
}

View File

@@ -1,489 +0,0 @@
package lo
import (
"fmt"
)
func ExampleTernary() {
result := Ternary(true, "a", "b")
fmt.Printf("%v", result)
// Output: a
}
func ExampleTernaryF() {
result := TernaryF(true, func() string { return "a" }, func() string { return "b" })
fmt.Printf("%v", result)
// Output: a
}
func ExampleIf() {
result1 := If(true, 1).
ElseIf(false, 2).
Else(3)
result2 := If(false, 1).
ElseIf(true, 2).
Else(3)
result3 := If(false, 1).
ElseIf(false, 2).
Else(3)
result4 := IfF(true, func() int { return 1 }).
ElseIfF(false, func() int { return 2 }).
ElseF(func() int { return 3 })
result5 := IfF(false, func() int { return 1 }).
ElseIfF(true, func() int { return 2 }).
ElseF(func() int { return 3 })
result6 := IfF(false, func() int { return 1 }).
ElseIfF(false, func() int { return 2 }).
ElseF(func() int { return 3 })
fmt.Printf("%v\n", result1)
fmt.Printf("%v\n", result2)
fmt.Printf("%v\n", result3)
fmt.Printf("%v\n", result4)
fmt.Printf("%v\n", result5)
fmt.Printf("%v\n", result6)
// Output:
// 1
// 2
// 3
// 1
// 2
// 3
}
func ExampleIfF() {
result1 := If(true, 1).
ElseIf(false, 2).
Else(3)
result2 := If(false, 1).
ElseIf(true, 2).
Else(3)
result3 := If(false, 1).
ElseIf(false, 2).
Else(3)
result4 := IfF(true, func() int { return 1 }).
ElseIfF(false, func() int { return 2 }).
ElseF(func() int { return 3 })
result5 := IfF(false, func() int { return 1 }).
ElseIfF(true, func() int { return 2 }).
ElseF(func() int { return 3 })
result6 := IfF(false, func() int { return 1 }).
ElseIfF(false, func() int { return 2 }).
ElseF(func() int { return 3 })
fmt.Printf("%v\n", result1)
fmt.Printf("%v\n", result2)
fmt.Printf("%v\n", result3)
fmt.Printf("%v\n", result4)
fmt.Printf("%v\n", result5)
fmt.Printf("%v\n", result6)
// Output:
// 1
// 2
// 3
// 1
// 2
// 3
}
func Example_ifElse_ElseIf() {
result1 := If(true, 1).
ElseIf(false, 2).
Else(3)
result2 := If(false, 1).
ElseIf(true, 2).
Else(3)
result3 := If(false, 1).
ElseIf(false, 2).
Else(3)
result4 := IfF(true, func() int { return 1 }).
ElseIfF(false, func() int { return 2 }).
ElseF(func() int { return 3 })
result5 := IfF(false, func() int { return 1 }).
ElseIfF(true, func() int { return 2 }).
ElseF(func() int { return 3 })
result6 := IfF(false, func() int { return 1 }).
ElseIfF(false, func() int { return 2 }).
ElseF(func() int { return 3 })
fmt.Printf("%v\n", result1)
fmt.Printf("%v\n", result2)
fmt.Printf("%v\n", result3)
fmt.Printf("%v\n", result4)
fmt.Printf("%v\n", result5)
fmt.Printf("%v\n", result6)
// Output:
// 1
// 2
// 3
// 1
// 2
// 3
}
func Example_ifElse_ElseIfF() {
result1 := If(true, 1).
ElseIf(false, 2).
Else(3)
result2 := If(false, 1).
ElseIf(true, 2).
Else(3)
result3 := If(false, 1).
ElseIf(false, 2).
Else(3)
result4 := IfF(true, func() int { return 1 }).
ElseIfF(false, func() int { return 2 }).
ElseF(func() int { return 3 })
result5 := IfF(false, func() int { return 1 }).
ElseIfF(true, func() int { return 2 }).
ElseF(func() int { return 3 })
result6 := IfF(false, func() int { return 1 }).
ElseIfF(false, func() int { return 2 }).
ElseF(func() int { return 3 })
fmt.Printf("%v\n", result1)
fmt.Printf("%v\n", result2)
fmt.Printf("%v\n", result3)
fmt.Printf("%v\n", result4)
fmt.Printf("%v\n", result5)
fmt.Printf("%v\n", result6)
// Output:
// 1
// 2
// 3
// 1
// 2
// 3
}
func Example_ifElse_Else() {
result1 := If(true, 1).
ElseIf(false, 2).
Else(3)
result2 := If(false, 1).
ElseIf(true, 2).
Else(3)
result3 := If(false, 1).
ElseIf(false, 2).
Else(3)
result4 := IfF(true, func() int { return 1 }).
ElseIfF(false, func() int { return 2 }).
ElseF(func() int { return 3 })
result5 := IfF(false, func() int { return 1 }).
ElseIfF(true, func() int { return 2 }).
ElseF(func() int { return 3 })
result6 := IfF(false, func() int { return 1 }).
ElseIfF(false, func() int { return 2 }).
ElseF(func() int { return 3 })
fmt.Printf("%v\n", result1)
fmt.Printf("%v\n", result2)
fmt.Printf("%v\n", result3)
fmt.Printf("%v\n", result4)
fmt.Printf("%v\n", result5)
fmt.Printf("%v\n", result6)
// Output:
// 1
// 2
// 3
// 1
// 2
// 3
}
func Example_ifElse_ElseF() {
result1 := If(true, 1).
ElseIf(false, 2).
Else(3)
result2 := If(false, 1).
ElseIf(true, 2).
Else(3)
result3 := If(false, 1).
ElseIf(false, 2).
Else(3)
result4 := IfF(true, func() int { return 1 }).
ElseIfF(false, func() int { return 2 }).
ElseF(func() int { return 3 })
result5 := IfF(false, func() int { return 1 }).
ElseIfF(true, func() int { return 2 }).
ElseF(func() int { return 3 })
result6 := IfF(false, func() int { return 1 }).
ElseIfF(false, func() int { return 2 }).
ElseF(func() int { return 3 })
fmt.Printf("%v\n", result1)
fmt.Printf("%v\n", result2)
fmt.Printf("%v\n", result3)
fmt.Printf("%v\n", result4)
fmt.Printf("%v\n", result5)
fmt.Printf("%v\n", result6)
// Output:
// 1
// 2
// 3
// 1
// 2
// 3
}
func ExampleSwitch() {
result1 := Switch[int, string](1).
Case(1, "1").
Case(2, "2").
Default("3")
result2 := Switch[int, string](2).
Case(1, "1").
Case(2, "2").
Default("3")
result3 := Switch[int, string](42).
Case(1, "1").
Case(2, "2").
Default("3")
result4 := Switch[int, string](1).
CaseF(1, func() string { return "1" }).
CaseF(2, func() string { return "2" }).
DefaultF(func() string { return "3" })
result5 := Switch[int, string](2).
CaseF(1, func() string { return "1" }).
CaseF(2, func() string { return "2" }).
DefaultF(func() string { return "3" })
result6 := Switch[int, string](42).
CaseF(1, func() string { return "1" }).
CaseF(2, func() string { return "2" }).
DefaultF(func() string { return "3" })
fmt.Printf("%v\n", result1)
fmt.Printf("%v\n", result2)
fmt.Printf("%v\n", result3)
fmt.Printf("%v\n", result4)
fmt.Printf("%v\n", result5)
fmt.Printf("%v\n", result6)
// Output:
// 1
// 2
// 3
// 1
// 2
// 3
}
func Example_switchCase_Case() {
result1 := Switch[int, string](1).
Case(1, "1").
Case(2, "2").
Default("3")
result2 := Switch[int, string](2).
Case(1, "1").
Case(2, "2").
Default("3")
result3 := Switch[int, string](42).
Case(1, "1").
Case(2, "2").
Default("3")
result4 := Switch[int, string](1).
CaseF(1, func() string { return "1" }).
CaseF(2, func() string { return "2" }).
DefaultF(func() string { return "3" })
result5 := Switch[int, string](2).
CaseF(1, func() string { return "1" }).
CaseF(2, func() string { return "2" }).
DefaultF(func() string { return "3" })
result6 := Switch[int, string](42).
CaseF(1, func() string { return "1" }).
CaseF(2, func() string { return "2" }).
DefaultF(func() string { return "3" })
fmt.Printf("%v\n", result1)
fmt.Printf("%v\n", result2)
fmt.Printf("%v\n", result3)
fmt.Printf("%v\n", result4)
fmt.Printf("%v\n", result5)
fmt.Printf("%v\n", result6)
// Output:
// 1
// 2
// 3
// 1
// 2
// 3
}
func Example_switchCase_CaseF() {
result1 := Switch[int, string](1).
Case(1, "1").
Case(2, "2").
Default("3")
result2 := Switch[int, string](2).
Case(1, "1").
Case(2, "2").
Default("3")
result3 := Switch[int, string](42).
Case(1, "1").
Case(2, "2").
Default("3")
result4 := Switch[int, string](1).
CaseF(1, func() string { return "1" }).
CaseF(2, func() string { return "2" }).
DefaultF(func() string { return "3" })
result5 := Switch[int, string](2).
CaseF(1, func() string { return "1" }).
CaseF(2, func() string { return "2" }).
DefaultF(func() string { return "3" })
result6 := Switch[int, string](42).
CaseF(1, func() string { return "1" }).
CaseF(2, func() string { return "2" }).
DefaultF(func() string { return "3" })
fmt.Printf("%v\n", result1)
fmt.Printf("%v\n", result2)
fmt.Printf("%v\n", result3)
fmt.Printf("%v\n", result4)
fmt.Printf("%v\n", result5)
fmt.Printf("%v\n", result6)
// Output:
// 1
// 2
// 3
// 1
// 2
// 3
}
func Example_switchCase_Default() {
result1 := Switch[int, string](1).
Case(1, "1").
Case(2, "2").
Default("3")
result2 := Switch[int, string](2).
Case(1, "1").
Case(2, "2").
Default("3")
result3 := Switch[int, string](42).
Case(1, "1").
Case(2, "2").
Default("3")
result4 := Switch[int, string](1).
CaseF(1, func() string { return "1" }).
CaseF(2, func() string { return "2" }).
DefaultF(func() string { return "3" })
result5 := Switch[int, string](2).
CaseF(1, func() string { return "1" }).
CaseF(2, func() string { return "2" }).
DefaultF(func() string { return "3" })
result6 := Switch[int, string](42).
CaseF(1, func() string { return "1" }).
CaseF(2, func() string { return "2" }).
DefaultF(func() string { return "3" })
fmt.Printf("%v\n", result1)
fmt.Printf("%v\n", result2)
fmt.Printf("%v\n", result3)
fmt.Printf("%v\n", result4)
fmt.Printf("%v\n", result5)
fmt.Printf("%v\n", result6)
// Output:
// 1
// 2
// 3
// 1
// 2
// 3
}
func Example_switchCase_DefaultF() {
result1 := Switch[int, string](1).
Case(1, "1").
Case(2, "2").
Default("3")
result2 := Switch[int, string](2).
Case(1, "1").
Case(2, "2").
Default("3")
result3 := Switch[int, string](42).
Case(1, "1").
Case(2, "2").
Default("3")
result4 := Switch[int, string](1).
CaseF(1, func() string { return "1" }).
CaseF(2, func() string { return "2" }).
DefaultF(func() string { return "3" })
result5 := Switch[int, string](2).
CaseF(1, func() string { return "1" }).
CaseF(2, func() string { return "2" }).
DefaultF(func() string { return "3" })
result6 := Switch[int, string](42).
CaseF(1, func() string { return "1" }).
CaseF(2, func() string { return "2" }).
DefaultF(func() string { return "3" })
fmt.Printf("%v\n", result1)
fmt.Printf("%v\n", result2)
fmt.Printf("%v\n", result3)
fmt.Printf("%v\n", result4)
fmt.Printf("%v\n", result5)
fmt.Printf("%v\n", result6)
// Output:
// 1
// 2
// 3
// 1
// 2
// 3
}

View File

@@ -1,88 +0,0 @@
package lo
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestTernary(t *testing.T) {
t.Parallel()
is := assert.New(t)
result1 := Ternary(true, "a", "b")
result2 := Ternary(false, "a", "b")
is.Equal(result1, "a")
is.Equal(result2, "b")
}
func TestTernaryF(t *testing.T) {
is := assert.New(t)
result1 := TernaryF(true, func() string { return "a" }, func() string { return "b" })
result2 := TernaryF(false, func() string { return "a" }, func() string { return "b" })
is.Equal(result1, "a")
is.Equal(result2, "b")
}
func TestIfElse(t *testing.T) {
t.Parallel()
is := assert.New(t)
result1 := If(true, 1).ElseIf(false, 2).Else(3)
result2 := If(true, 1).ElseIf(true, 2).Else(3)
result3 := If(false, 1).ElseIf(true, 2).Else(3)
result4 := If(false, 1).ElseIf(false, 2).Else(3)
is.Equal(result1, 1)
is.Equal(result2, 1)
is.Equal(result3, 2)
is.Equal(result4, 3)
}
func TestIfFElseF(t *testing.T) {
t.Parallel()
is := assert.New(t)
result1 := IfF(true, func() int { return 1 }).ElseIfF(false, func() int { return 2 }).ElseF(func() int { return 3 })
result2 := IfF(true, func() int { return 1 }).ElseIfF(true, func() int { return 2 }).ElseF(func() int { return 3 })
result3 := IfF(false, func() int { return 1 }).ElseIfF(true, func() int { return 2 }).ElseF(func() int { return 3 })
result4 := IfF(false, func() int { return 1 }).ElseIfF(false, func() int { return 2 }).ElseF(func() int { return 3 })
is.Equal(result1, 1)
is.Equal(result2, 1)
is.Equal(result3, 2)
is.Equal(result4, 3)
}
func TestSwitchCase(t *testing.T) {
t.Parallel()
is := assert.New(t)
result1 := Switch[int, int](42).Case(42, 1).Case(1, 2).Default(3)
result2 := Switch[int, int](42).Case(42, 1).Case(42, 2).Default(3)
result3 := Switch[int, int](42).Case(1, 1).Case(42, 2).Default(3)
result4 := Switch[int, int](42).Case(1, 1).Case(1, 2).Default(3)
is.Equal(result1, 1)
is.Equal(result2, 1)
is.Equal(result3, 2)
is.Equal(result4, 3)
}
func TestSwitchCaseF(t *testing.T) {
t.Parallel()
is := assert.New(t)
result1 := Switch[int, int](42).CaseF(42, func() int { return 1 }).CaseF(1, func() int { return 2 }).DefaultF(func() int { return 3 })
result2 := Switch[int, int](42).CaseF(42, func() int { return 1 }).CaseF(42, func() int { return 2 }).DefaultF(func() int { return 3 })
result3 := Switch[int, int](42).CaseF(1, func() int { return 1 }).CaseF(42, func() int { return 2 }).DefaultF(func() int { return 3 })
result4 := Switch[int, int](42).CaseF(1, func() int { return 1 }).CaseF(1, func() int { return 2 }).DefaultF(func() int { return 3 })
is.Equal(result1, 1)
is.Equal(result2, 1)
is.Equal(result3, 2)
is.Equal(result4, 3)
}

View File

@@ -1,9 +0,0 @@
version: '3'
services:
dev:
image: golang:1.18-bullseye
volumes:
- ./:/go/src/github.com/samber/lo
working_dir: /go/src/github.com/samber/lo
command: make watch-test

View File

@@ -1,429 +0,0 @@
package lo
import (
"fmt"
)
func ExampleValidate() {
i := 42
err1 := Validate(i < 0, "expected %d < 0", i)
err2 := Validate(i > 0, "expected %d > 0", i)
fmt.Printf("%v\n%v", err1, err2)
// Output:
// expected 42 < 0
// <nil>
}
func ExampleMust() {
defer func() {
_ = recover()
}()
// won't panic
Must(42, nil)
// won't panic
cb := func() (int, error) {
return 42, nil
}
Must(cb())
// will panic
Must(42, fmt.Errorf("my error"))
// will panic with error message
Must(42, fmt.Errorf("world"), "hello")
}
func ExampleMust0() {
defer func() {
_ = recover()
}()
// won't panic
Must0(nil)
// will panic
Must0(fmt.Errorf("my error"))
// will panic with error message
Must0(fmt.Errorf("world"), "hello")
}
func ExampleMust1() {
defer func() {
_ = recover()
}()
// won't panic
Must1(42, nil)
// won't panic
cb := func() (int, error) {
return 42, nil
}
Must1(cb())
// will panic
Must1(42, fmt.Errorf("my error"))
// will panic with error message
Must1(42, fmt.Errorf("world"), "hello")
}
func ExampleMust2() {
defer func() {
_ = recover()
}()
// won't panic
Must2(42, "hello", nil)
// will panic
Must2(42, "hello", fmt.Errorf("my error"))
// will panic with error message
Must2(42, "hello", fmt.Errorf("world"), "hello")
}
func ExampleMust3() {
defer func() {
_ = recover()
}()
// won't panic
Must3(42, "hello", 4.2, nil)
// will panic
Must3(42, "hello", 4.2, fmt.Errorf("my error"))
// will panic with error message
Must3(42, "hello", 4.2, fmt.Errorf("world"), "hello")
}
func ExampleMust4() {
defer func() {
_ = recover()
}()
// won't panic
Must4(42, "hello", 4.2, true, nil)
// will panic
Must4(42, "hello", 4.2, true, fmt.Errorf("my error"))
// will panic with error message
Must4(42, "hello", 4.2, true, fmt.Errorf("world"), "hello")
}
func ExampleMust5() {
defer func() {
_ = recover()
}()
// won't panic
Must5(42, "hello", 4.2, true, foo{}, nil)
// will panic
Must5(42, "hello", 4.2, true, foo{}, fmt.Errorf("my error"))
// will panic with error message
Must5(42, "hello", 4.2, true, foo{}, fmt.Errorf("world"), "hello")
}
func ExampleMust6() {
defer func() {
_ = recover()
}()
// won't panic
Must5(42, "hello", 4.2, true, foo{}, "foobar", nil)
// will panic
Must5(42, "hello", 4.2, true, foo{}, "foobar", fmt.Errorf("my error"))
// will panic with error message
Must5(42, "hello", 4.2, true, foo{}, "foobar", fmt.Errorf("world"), "hello")
}
func ExampleTry() {
ok1 := Try(func() error {
return nil
})
ok2 := Try(func() error {
return fmt.Errorf("my error")
})
ok3 := Try(func() error {
panic("my error")
})
fmt.Printf("%v\n", ok1)
fmt.Printf("%v\n", ok2)
fmt.Printf("%v\n", ok3)
// Output:
// true
// false
// false
}
func ExampleTry1() {
ok1 := Try1(func() error {
return nil
})
ok2 := Try1(func() error {
return fmt.Errorf("my error")
})
ok3 := Try1(func() error {
panic("my error")
})
fmt.Printf("%v\n", ok1)
fmt.Printf("%v\n", ok2)
fmt.Printf("%v\n", ok3)
// Output:
// true
// false
// false
}
func ExampleTry2() {
ok1 := Try2(func() (int, error) {
return 42, nil
})
ok2 := Try2(func() (int, error) {
return 42, fmt.Errorf("my error")
})
ok3 := Try2(func() (int, error) {
panic("my error")
})
fmt.Printf("%v\n", ok1)
fmt.Printf("%v\n", ok2)
fmt.Printf("%v\n", ok3)
// Output:
// true
// false
// false
}
func ExampleTry3() {
ok1 := Try3(func() (int, string, error) {
return 42, "foobar", nil
})
ok2 := Try3(func() (int, string, error) {
return 42, "foobar", fmt.Errorf("my error")
})
ok3 := Try3(func() (int, string, error) {
panic("my error")
})
fmt.Printf("%v\n", ok1)
fmt.Printf("%v\n", ok2)
fmt.Printf("%v\n", ok3)
// Output:
// true
// false
// false
}
func ExampleTry4() {
ok1 := Try4(func() (int, string, float64, error) {
return 42, "foobar", 4.2, nil
})
ok2 := Try4(func() (int, string, float64, error) {
return 42, "foobar", 4.2, fmt.Errorf("my error")
})
ok3 := Try4(func() (int, string, float64, error) {
panic("my error")
})
fmt.Printf("%v\n", ok1)
fmt.Printf("%v\n", ok2)
fmt.Printf("%v\n", ok3)
// Output:
// true
// false
// false
}
func ExampleTry5() {
ok1 := Try5(func() (int, string, float64, bool, error) {
return 42, "foobar", 4.2, true, nil
})
ok2 := Try5(func() (int, string, float64, bool, error) {
return 42, "foobar", 4.2, true, fmt.Errorf("my error")
})
ok3 := Try5(func() (int, string, float64, bool, error) {
panic("my error")
})
fmt.Printf("%v\n", ok1)
fmt.Printf("%v\n", ok2)
fmt.Printf("%v\n", ok3)
// Output:
// true
// false
// false
}
func ExampleTry6() {
ok1 := Try6(func() (int, string, float64, bool, foo, error) {
return 42, "foobar", 4.2, true, foo{}, nil
})
ok2 := Try6(func() (int, string, float64, bool, foo, error) {
return 42, "foobar", 4.2, true, foo{}, fmt.Errorf("my error")
})
ok3 := Try6(func() (int, string, float64, bool, foo, error) {
panic("my error")
})
fmt.Printf("%v\n", ok1)
fmt.Printf("%v\n", ok2)
fmt.Printf("%v\n", ok3)
// Output:
// true
// false
// false
}
func ExampleTryOr() {
value1, ok1 := TryOr(func() (int, error) {
return 42, nil
}, 21)
value2, ok2 := TryOr(func() (int, error) {
return 42, fmt.Errorf("my error")
}, 21)
value3, ok3 := TryOr(func() (int, error) {
panic("my error")
}, 21)
fmt.Printf("%v %v\n", value1, ok1)
fmt.Printf("%v %v\n", value2, ok2)
fmt.Printf("%v %v\n", value3, ok3)
// Output:
// 42 true
// 21 false
// 21 false
}
func ExampleTryOr1() {
value1, ok1 := TryOr1(func() (int, error) {
return 42, nil
}, 21)
value2, ok2 := TryOr1(func() (int, error) {
return 42, fmt.Errorf("my error")
}, 21)
value3, ok3 := TryOr1(func() (int, error) {
panic("my error")
}, 21)
fmt.Printf("%v %v\n", value1, ok1)
fmt.Printf("%v %v\n", value2, ok2)
fmt.Printf("%v %v\n", value3, ok3)
// Output:
// 42 true
// 21 false
// 21 false
}
func ExampleTryOr2() {
value1, value2, ok3 := TryOr2(func() (int, string, error) {
panic("my error")
}, 21, "hello")
fmt.Printf("%v %v %v\n", value1, value2, ok3)
// Output: 21 hello false
}
func ExampleTryOr3() {
value1, value2, value3, ok3 := TryOr3(func() (int, string, bool, error) {
panic("my error")
}, 21, "hello", false)
fmt.Printf("%v %v %v %v\n", value1, value2, value3, ok3)
// Output: 21 hello false false
}
func ExampleTryOr4() {
value1, value2, value3, value4, ok3 := TryOr4(func() (int, string, bool, foo, error) {
panic("my error")
}, 21, "hello", false, foo{bar: "bar"})
fmt.Printf("%v %v %v %v %v\n", value1, value2, value3, value4, ok3)
// Output: 21 hello false {bar} false
}
func ExampleTryOr5() {
value1, value2, value3, value4, value5, ok3 := TryOr5(func() (int, string, bool, foo, float64, error) {
panic("my error")
}, 21, "hello", false, foo{bar: "bar"}, 4.2)
fmt.Printf("%v %v %v %v %v %v\n", value1, value2, value3, value4, value5, ok3)
// Output: 21 hello false {bar} 4.2 false
}
func ExampleTryOr6() {
value1, value2, value3, value4, value5, value6, ok3 := TryOr6(func() (int, string, bool, foo, float64, string, error) {
panic("my error")
}, 21, "hello", false, foo{bar: "bar"}, 4.2, "world")
fmt.Printf("%v %v %v %v %v %v %v\n", value1, value2, value3, value4, value5, value6, ok3)
// Output: 21 hello false {bar} 4.2 world false
}
func ExampleTryWithErrorValue() {
err1, ok1 := TryWithErrorValue(func() error {
return nil
})
err2, ok2 := TryWithErrorValue(func() error {
return fmt.Errorf("my error")
})
err3, ok3 := TryWithErrorValue(func() error {
panic("my error")
})
fmt.Printf("%v %v\n", err1, ok1)
fmt.Printf("%v %v\n", err2, ok2)
fmt.Printf("%v %v\n", err3, ok3)
// Output:
// <nil> true
// my error false
// my error false
}
func ExampleTryCatchWithErrorValue() {
TryCatchWithErrorValue(
func() error {
panic("trigger an error")
},
func(err any) {
fmt.Printf("catch: %s", err)
},
)
// Output: catch: trigger an error
}
type myError struct{}
func (e myError) Error() string {
return "my error"
}
func ExampleErrorsAs() {
doSomething := func() error {
return &myError{}
}
err := doSomething()
if rateLimitErr, ok := ErrorsAs[*myError](err); ok {
fmt.Printf("is type myError, err: %s", rateLimitErr.Error())
} else {
fmt.Printf("is not type myError")
}
// Output: is type myError, err: my error
}

View File

@@ -1,599 +0,0 @@
package lo
import (
"errors"
"fmt"
"testing"
"github.com/stretchr/testify/assert"
)
func TestValidate(t *testing.T) {
is := assert.New(t)
slice := []string{"a"}
result1 := Validate(len(slice) == 0, "Slice should be empty but contains %v", slice)
slice = []string{}
result2 := Validate(len(slice) == 0, "Slice should be empty but contains %v", slice)
is.Error(result1)
is.NoError(result2)
}
func TestMust(t *testing.T) {
t.Parallel()
is := assert.New(t)
is.Equal("foo", Must("foo", nil))
is.PanicsWithValue("something went wrong", func() {
Must("", errors.New("something went wrong"))
})
is.PanicsWithValue("operation shouldn't fail: something went wrong", func() {
Must("", errors.New("something went wrong"), "operation shouldn't fail")
})
is.PanicsWithValue("operation shouldn't fail with foo: something went wrong", func() {
Must("", errors.New("something went wrong"), "operation shouldn't fail with %s", "foo")
})
is.Equal(1, Must(1, true))
is.PanicsWithValue("not ok", func() {
Must(1, false)
})
is.PanicsWithValue("operation shouldn't fail", func() {
Must(1, false, "operation shouldn't fail")
})
is.PanicsWithValue("operation shouldn't fail with foo", func() {
Must(1, false, "operation shouldn't fail with %s", "foo")
})
cb := func() error {
return assert.AnError
}
is.PanicsWithValue("operation should fail: assert.AnError general error for testing", func() {
Must0(cb(), "operation should fail")
})
is.PanicsWithValue("must: invalid err type 'int', should either be a bool or an error", func() {
Must0(0)
})
is.PanicsWithValue("must: invalid err type 'string', should either be a bool or an error", func() {
Must0("error")
})
}
func TestMustX(t *testing.T) {
t.Parallel()
is := assert.New(t)
{
is.PanicsWithValue("something went wrong", func() {
Must0(errors.New("something went wrong"))
})
is.PanicsWithValue("operation shouldn't fail with foo: something went wrong", func() {
Must0(errors.New("something went wrong"), "operation shouldn't fail with %s", "foo")
})
is.NotPanics(func() {
Must0(nil)
})
}
{
val1 := Must1(1, nil)
is.Equal(1, val1)
is.PanicsWithValue("something went wrong", func() {
Must1(1, errors.New("something went wrong"))
})
is.PanicsWithValue("operation shouldn't fail with foo: something went wrong", func() {
Must1(1, errors.New("something went wrong"), "operation shouldn't fail with %s", "foo")
})
}
{
val1, val2 := Must2(1, 2, nil)
is.Equal(1, val1)
is.Equal(2, val2)
is.PanicsWithValue("something went wrong", func() {
Must2(1, 2, errors.New("something went wrong"))
})
is.PanicsWithValue("operation shouldn't fail with foo: something went wrong", func() {
Must2(1, 2, errors.New("something went wrong"), "operation shouldn't fail with %s", "foo")
})
}
{
val1, val2, val3 := Must3(1, 2, 3, nil)
is.Equal(1, val1)
is.Equal(2, val2)
is.Equal(3, val3)
is.PanicsWithValue("something went wrong", func() {
Must3(1, 2, 3, errors.New("something went wrong"))
})
is.PanicsWithValue("operation shouldn't fail with foo: something went wrong", func() {
Must3(1, 2, 3, errors.New("something went wrong"), "operation shouldn't fail with %s", "foo")
})
}
{
val1, val2, val3, val4 := Must4(1, 2, 3, 4, nil)
is.Equal(1, val1)
is.Equal(2, val2)
is.Equal(3, val3)
is.Equal(4, val4)
is.PanicsWithValue("something went wrong", func() {
Must4(1, 2, 3, 4, errors.New("something went wrong"))
})
is.PanicsWithValue("operation shouldn't fail with foo: something went wrong", func() {
Must4(1, 2, 3, 4, errors.New("something went wrong"), "operation shouldn't fail with %s", "foo")
})
}
{
val1, val2, val3, val4, val5 := Must5(1, 2, 3, 4, 5, nil)
is.Equal(1, val1)
is.Equal(2, val2)
is.Equal(3, val3)
is.Equal(4, val4)
is.Equal(5, val5)
is.PanicsWithValue("something went wrong", func() {
Must5(1, 2, 3, 4, 5, errors.New("something went wrong"))
})
is.PanicsWithValue("operation shouldn't fail with foo: something went wrong", func() {
Must5(1, 2, 3, 4, 5, errors.New("something went wrong"), "operation shouldn't fail with %s", "foo")
})
}
{
val1, val2, val3, val4, val5, val6 := Must6(1, 2, 3, 4, 5, 6, nil)
is.Equal(1, val1)
is.Equal(2, val2)
is.Equal(3, val3)
is.Equal(4, val4)
is.Equal(5, val5)
is.Equal(6, val6)
is.PanicsWithValue("something went wrong", func() {
Must6(1, 2, 3, 4, 5, 6, errors.New("something went wrong"))
})
is.PanicsWithValue("operation shouldn't fail with foo: something went wrong", func() {
Must6(1, 2, 3, 4, 5, 6, errors.New("something went wrong"), "operation shouldn't fail with %s", "foo")
})
}
{
is.PanicsWithValue("not ok", func() {
Must0(false)
})
is.PanicsWithValue("operation shouldn't fail with foo", func() {
Must0(false, "operation shouldn't fail with %s", "foo")
})
is.NotPanics(func() {
Must0(true)
})
}
{
val1 := Must1(1, true)
is.Equal(1, val1)
is.PanicsWithValue("not ok", func() {
Must1(1, false)
})
is.PanicsWithValue("operation shouldn't fail with foo", func() {
Must1(1, false, "operation shouldn't fail with %s", "foo")
})
}
{
val1, val2 := Must2(1, 2, true)
is.Equal(1, val1)
is.Equal(2, val2)
is.PanicsWithValue("not ok", func() {
Must2(1, 2, false)
})
is.PanicsWithValue("operation shouldn't fail with foo", func() {
Must2(1, 2, false, "operation shouldn't fail with %s", "foo")
})
}
{
val1, val2, val3 := Must3(1, 2, 3, true)
is.Equal(1, val1)
is.Equal(2, val2)
is.Equal(3, val3)
is.PanicsWithValue("not ok", func() {
Must3(1, 2, 3, false)
})
is.PanicsWithValue("operation shouldn't fail with foo", func() {
Must3(1, 2, 3, false, "operation shouldn't fail with %s", "foo")
})
}
{
val1, val2, val3, val4 := Must4(1, 2, 3, 4, true)
is.Equal(1, val1)
is.Equal(2, val2)
is.Equal(3, val3)
is.Equal(4, val4)
is.PanicsWithValue("not ok", func() {
Must4(1, 2, 3, 4, false)
})
is.PanicsWithValue("operation shouldn't fail with foo", func() {
Must4(1, 2, 3, 4, false, "operation shouldn't fail with %s", "foo")
})
}
{
val1, val2, val3, val4, val5 := Must5(1, 2, 3, 4, 5, true)
is.Equal(1, val1)
is.Equal(2, val2)
is.Equal(3, val3)
is.Equal(4, val4)
is.Equal(5, val5)
is.PanicsWithValue("not ok", func() {
Must5(1, 2, 3, 4, 5, false)
})
is.PanicsWithValue("operation shouldn't fail with foo", func() {
Must5(1, 2, 3, 4, 5, false, "operation shouldn't fail with %s", "foo")
})
}
{
val1, val2, val3, val4, val5, val6 := Must6(1, 2, 3, 4, 5, 6, true)
is.Equal(1, val1)
is.Equal(2, val2)
is.Equal(3, val3)
is.Equal(4, val4)
is.Equal(5, val5)
is.Equal(6, val6)
is.PanicsWithValue("not ok", func() {
Must6(1, 2, 3, 4, 5, 6, false)
})
is.PanicsWithValue("operation shouldn't fail with foo", func() {
Must6(1, 2, 3, 4, 5, 6, false, "operation shouldn't fail with %s", "foo")
})
}
}
func TestTry(t *testing.T) {
t.Parallel()
is := assert.New(t)
is.False(Try(func() error {
panic("error")
}))
is.True(Try(func() error {
return nil
}))
is.False(Try(func() error {
return fmt.Errorf("fail")
}))
}
func TestTryX(t *testing.T) {
t.Parallel()
is := assert.New(t)
is.True(Try1(func() error {
return nil
}))
is.True(Try2(func() (string, error) {
return "", nil
}))
is.True(Try3(func() (string, string, error) {
return "", "", nil
}))
is.True(Try4(func() (string, string, string, error) {
return "", "", "", nil
}))
is.True(Try5(func() (string, string, string, string, error) {
return "", "", "", "", nil
}))
is.True(Try6(func() (string, string, string, string, string, error) {
return "", "", "", "", "", nil
}))
is.False(Try1(func() error {
panic("error")
}))
is.False(Try2(func() (string, error) {
panic("error")
}))
is.False(Try3(func() (string, string, error) {
panic("error")
}))
is.False(Try4(func() (string, string, string, error) {
panic("error")
}))
is.False(Try5(func() (string, string, string, string, error) {
panic("error")
}))
is.False(Try6(func() (string, string, string, string, string, error) {
panic("error")
}))
is.False(Try1(func() error {
return errors.New("foo")
}))
is.False(Try2(func() (string, error) {
return "", errors.New("foo")
}))
is.False(Try3(func() (string, string, error) {
return "", "", errors.New("foo")
}))
is.False(Try4(func() (string, string, string, error) {
return "", "", "", errors.New("foo")
}))
is.False(Try5(func() (string, string, string, string, error) {
return "", "", "", "", errors.New("foo")
}))
is.False(Try6(func() (string, string, string, string, string, error) {
return "", "", "", "", "", errors.New("foo")
}))
}
func TestTryOr(t *testing.T) {
t.Parallel()
is := assert.New(t)
a1, ok1 := TryOr(func() (int, error) { panic("error") }, 42)
a2, ok2 := TryOr(func() (int, error) { return 21, assert.AnError }, 42)
a3, ok3 := TryOr(func() (int, error) { return 21, nil }, 42)
is.Equal(42, a1)
is.False(ok1)
is.Equal(42, a2)
is.False(ok2)
is.Equal(21, a3)
is.True(ok3)
}
func TestTryOrX(t *testing.T) {
t.Parallel()
is := assert.New(t)
{
a1, ok1 := TryOr1(func() (int, error) { panic("error") }, 42)
a2, ok2 := TryOr1(func() (int, error) { return 21, assert.AnError }, 42)
a3, ok3 := TryOr1(func() (int, error) { return 21, nil }, 42)
is.Equal(42, a1)
is.False(ok1)
is.Equal(42, a2)
is.False(ok2)
is.Equal(21, a3)
is.True(ok3)
}
{
a1, b1, ok1 := TryOr2(func() (int, string, error) { panic("error") }, 42, "hello")
a2, b2, ok2 := TryOr2(func() (int, string, error) { return 21, "world", assert.AnError }, 42, "hello")
a3, b3, ok3 := TryOr2(func() (int, string, error) { return 21, "world", nil }, 42, "hello")
is.Equal(42, a1)
is.Equal("hello", b1)
is.False(ok1)
is.Equal(42, a2)
is.Equal("hello", b2)
is.False(ok2)
is.Equal(21, a3)
is.Equal("world", b3)
is.True(ok3)
}
{
a1, b1, c1, ok1 := TryOr3(func() (int, string, bool, error) { panic("error") }, 42, "hello", false)
a2, b2, c2, ok2 := TryOr3(func() (int, string, bool, error) { return 21, "world", true, assert.AnError }, 42, "hello", false)
a3, b3, c3, ok3 := TryOr3(func() (int, string, bool, error) { return 21, "world", true, nil }, 42, "hello", false)
is.Equal(42, a1)
is.Equal("hello", b1)
is.Equal(false, c1)
is.False(ok1)
is.Equal(42, a2)
is.Equal("hello", b2)
is.Equal(false, c2)
is.False(ok2)
is.Equal(21, a3)
is.Equal("world", b3)
is.Equal(true, c3)
is.True(ok3)
}
{
a1, b1, c1, d1, ok1 := TryOr4(func() (int, string, bool, int, error) { panic("error") }, 42, "hello", false, 42)
a2, b2, c2, d2, ok2 := TryOr4(func() (int, string, bool, int, error) { return 21, "world", true, 21, assert.AnError }, 42, "hello", false, 42)
a3, b3, c3, d3, ok3 := TryOr4(func() (int, string, bool, int, error) { return 21, "world", true, 21, nil }, 42, "hello", false, 42)
is.Equal(42, a1)
is.Equal("hello", b1)
is.Equal(false, c1)
is.Equal(42, d1)
is.False(ok1)
is.Equal(42, a2)
is.Equal("hello", b2)
is.Equal(false, c2)
is.Equal(42, d2)
is.False(ok2)
is.Equal(21, a3)
is.Equal("world", b3)
is.Equal(true, c3)
is.Equal(21, d3)
is.True(ok3)
}
{
a1, b1, c1, d1, e1, ok1 := TryOr5(func() (int, string, bool, int, int, error) { panic("error") }, 42, "hello", false, 42, 42)
a2, b2, c2, d2, e2, ok2 := TryOr5(func() (int, string, bool, int, int, error) { return 21, "world", true, 21, 21, assert.AnError }, 42, "hello", false, 42, 42)
a3, b3, c3, d3, e3, ok3 := TryOr5(func() (int, string, bool, int, int, error) { return 21, "world", true, 21, 21, nil }, 42, "hello", false, 42, 42)
is.Equal(42, a1)
is.Equal("hello", b1)
is.Equal(false, c1)
is.Equal(42, d1)
is.Equal(42, e1)
is.False(ok1)
is.Equal(42, a2)
is.Equal("hello", b2)
is.Equal(false, c2)
is.Equal(42, d2)
is.Equal(42, e2)
is.False(ok2)
is.Equal(21, a3)
is.Equal("world", b3)
is.Equal(true, c3)
is.Equal(21, d3)
is.Equal(21, e3)
is.True(ok3)
}
{
a1, b1, c1, d1, e1, f1, ok1 := TryOr6(func() (int, string, bool, int, int, int, error) { panic("error") }, 42, "hello", false, 42, 42, 42)
a2, b2, c2, d2, e2, f2, ok2 := TryOr6(func() (int, string, bool, int, int, int, error) { return 21, "world", true, 21, 21, 21, assert.AnError }, 42, "hello", false, 42, 42, 42)
a3, b3, c3, d3, e3, f3, ok3 := TryOr6(func() (int, string, bool, int, int, int, error) { return 21, "world", true, 21, 21, 21, nil }, 42, "hello", false, 42, 42, 42)
is.Equal(42, a1)
is.Equal("hello", b1)
is.Equal(false, c1)
is.Equal(42, d1)
is.Equal(42, e1)
is.Equal(42, f1)
is.False(ok1)
is.Equal(42, a2)
is.Equal("hello", b2)
is.Equal(false, c2)
is.Equal(42, d2)
is.Equal(42, e2)
is.Equal(42, f2)
is.False(ok2)
is.Equal(21, a3)
is.Equal("world", b3)
is.Equal(true, c3)
is.Equal(21, d3)
is.Equal(21, e3)
is.Equal(21, f3)
is.True(ok3)
}
}
func TestTryWithErrorValue(t *testing.T) {
t.Parallel()
is := assert.New(t)
err, ok := TryWithErrorValue(func() error {
// getting error in case of panic, using recover function
panic("error")
})
is.False(ok)
is.Equal("error", err)
err, ok = TryWithErrorValue(func() error {
return errors.New("foo")
})
is.False(ok)
is.EqualError(err.(error), "foo")
err, ok = TryWithErrorValue(func() error {
return nil
})
is.True(ok)
is.Equal(nil, err)
}
func TestTryCatch(t *testing.T) {
t.Parallel()
is := assert.New(t)
caught := false
TryCatch(func() error {
panic("error")
}, func() {
// error was caught
caught = true
})
is.True(caught)
caught = false
TryCatch(func() error {
return nil
}, func() {
// no error to be caught
caught = true
})
is.False(caught)
}
func TestTryCatchWithErrorValue(t *testing.T) {
t.Parallel()
is := assert.New(t)
caught := false
TryCatchWithErrorValue(func() error {
panic("error")
}, func(val any) {
// error was caught
caught = val == "error"
})
is.True(caught)
caught = false
TryCatchWithErrorValue(func() error {
return nil
}, func(val any) {
// no error to be caught
caught = true
})
is.False(caught)
}
type internalError struct {
foobar string
}
func (e *internalError) Error() string {
return "internal error"
}
func TestErrorsAs(t *testing.T) {
t.Parallel()
is := assert.New(t)
err, ok := ErrorsAs[*internalError](fmt.Errorf("hello world"))
is.False(ok)
is.Nil(nil, err)
err, ok = ErrorsAs[*internalError](&internalError{foobar: "foobar"})
is.True(ok)
is.Equal(&internalError{foobar: "foobar"}, err)
err, ok = ErrorsAs[*internalError](nil)
is.False(ok)
is.Nil(nil, err)
}

View File

@@ -1,783 +0,0 @@
package lo
import (
"fmt"
"math/rand"
"sort"
"testing"
"time"
"github.com/stretchr/testify/assert"
)
func TestIndexOf(t *testing.T) {
t.Parallel()
is := assert.New(t)
result1 := IndexOf([]int{0, 1, 2, 1, 2, 3}, 2)
result2 := IndexOf([]int{0, 1, 2, 1, 2, 3}, 6)
is.Equal(result1, 2)
is.Equal(result2, -1)
}
func TestLastIndexOf(t *testing.T) {
t.Parallel()
is := assert.New(t)
result1 := LastIndexOf([]int{0, 1, 2, 1, 2, 3}, 2)
result2 := LastIndexOf([]int{0, 1, 2, 1, 2, 3}, 6)
is.Equal(result1, 4)
is.Equal(result2, -1)
}
func TestFind(t *testing.T) {
t.Parallel()
is := assert.New(t)
index := 0
result1, ok1 := Find([]string{"a", "b", "c", "d"}, func(item string) bool {
is.Equal([]string{"a", "b", "c", "d"}[index], item)
index++
return item == "b"
})
result2, ok2 := Find([]string{"foobar"}, func(item string) bool {
is.Equal("foobar", item)
return item == "b"
})
is.Equal(ok1, true)
is.Equal(result1, "b")
is.Equal(ok2, false)
is.Equal(result2, "")
}
func TestFindIndexOf(t *testing.T) {
t.Parallel()
is := assert.New(t)
index := 0
item1, index1, ok1 := FindIndexOf([]string{"a", "b", "c", "d", "b"}, func(item string) bool {
is.Equal([]string{"a", "b", "c", "d", "b"}[index], item)
index++
return item == "b"
})
item2, index2, ok2 := FindIndexOf([]string{"foobar"}, func(item string) bool {
is.Equal("foobar", item)
return item == "b"
})
is.Equal(item1, "b")
is.Equal(ok1, true)
is.Equal(index1, 1)
is.Equal(item2, "")
is.Equal(ok2, false)
is.Equal(index2, -1)
}
func TestFindLastIndexOf(t *testing.T) {
t.Parallel()
is := assert.New(t)
index := 0
item1, index1, ok1 := FindLastIndexOf([]string{"a", "b", "c", "d", "b"}, func(item string) bool {
is.Equal([]string{"b", "d", "c", "b", "a"}[index], item)
index++
return item == "b"
})
item2, index2, ok2 := FindLastIndexOf([]string{"foobar"}, func(item string) bool {
is.Equal("foobar", item)
return item == "b"
})
is.Equal(item1, "b")
is.Equal(ok1, true)
is.Equal(index1, 4)
is.Equal(item2, "")
is.Equal(ok2, false)
is.Equal(index2, -1)
}
func TestFindOrElse(t *testing.T) {
t.Parallel()
is := assert.New(t)
index := 0
result1 := FindOrElse([]string{"a", "b", "c", "d"}, "x", func(item string) bool {
is.Equal([]string{"a", "b", "c", "d"}[index], item)
index++
return item == "b"
})
result2 := FindOrElse([]string{"foobar"}, "x", func(item string) bool {
is.Equal("foobar", item)
return item == "b"
})
is.Equal(result1, "b")
is.Equal(result2, "x")
}
func TestFindKey(t *testing.T) {
t.Parallel()
is := assert.New(t)
result1, ok1 := FindKey(map[string]int{"foo": 1, "bar": 2, "baz": 3}, 2)
is.Equal("bar", result1)
is.True(ok1)
result2, ok2 := FindKey(map[string]int{"foo": 1, "bar": 2, "baz": 3}, 42)
is.Equal("", result2)
is.False(ok2)
type test struct {
foobar string
}
result3, ok3 := FindKey(map[string]test{"foo": {"foo"}, "bar": {"bar"}, "baz": {"baz"}}, test{"foo"})
is.Equal("foo", result3)
is.True(ok3)
result4, ok4 := FindKey(map[string]test{"foo": {"foo"}, "bar": {"bar"}, "baz": {"baz"}}, test{"hello world"})
is.Equal("", result4)
is.False(ok4)
}
func TestFindKeyBy(t *testing.T) {
t.Parallel()
is := assert.New(t)
result1, ok1 := FindKeyBy(map[string]int{"foo": 1, "bar": 2, "baz": 3}, func(k string, v int) bool {
return k == "foo"
})
is.Equal("foo", result1)
is.True(ok1)
result2, ok2 := FindKeyBy(map[string]int{"foo": 1, "bar": 2, "baz": 3}, func(k string, v int) bool {
return false
})
is.Equal("", result2)
is.False(ok2)
}
func TestFindUniques(t *testing.T) {
t.Parallel()
is := assert.New(t)
result1 := FindUniques([]int{1, 2, 3})
is.Equal(3, len(result1))
is.Equal([]int{1, 2, 3}, result1)
result2 := FindUniques([]int{1, 2, 2, 3, 1, 2})
is.Equal(1, len(result2))
is.Equal([]int{3}, result2)
result3 := FindUniques([]int{1, 2, 2, 1})
is.Equal(0, len(result3))
is.Equal([]int{}, result3)
result4 := FindUniques([]int{})
is.Equal(0, len(result4))
is.Equal([]int{}, result4)
type myStrings []string
allStrings := myStrings{"", "foo", "bar"}
nonempty := FindUniques(allStrings)
is.IsType(nonempty, allStrings, "type preserved")
}
func TestFindUniquesBy(t *testing.T) {
t.Parallel()
is := assert.New(t)
result1 := FindUniquesBy([]int{0, 1, 2}, func(i int) int {
return i % 3
})
is.Equal(3, len(result1))
is.Equal([]int{0, 1, 2}, result1)
result2 := FindUniquesBy([]int{0, 1, 2, 3, 4}, func(i int) int {
return i % 3
})
is.Equal(1, len(result2))
is.Equal([]int{2}, result2)
result3 := FindUniquesBy([]int{0, 1, 2, 3, 4, 5}, func(i int) int {
return i % 3
})
is.Equal(0, len(result3))
is.Equal([]int{}, result3)
result4 := FindUniquesBy([]int{}, func(i int) int {
return i % 3
})
is.Equal(0, len(result4))
is.Equal([]int{}, result4)
type myStrings []string
allStrings := myStrings{"", "foo", "bar"}
nonempty := FindUniquesBy(allStrings, func(i string) string {
return i
})
is.IsType(nonempty, allStrings, "type preserved")
}
func TestFindDuplicates(t *testing.T) {
t.Parallel()
is := assert.New(t)
result1 := FindDuplicates([]int{1, 2, 2, 1, 2, 3})
is.Equal(2, len(result1))
is.Equal([]int{1, 2}, result1)
result2 := FindDuplicates([]int{1, 2, 3})
is.Equal(0, len(result2))
is.Equal([]int{}, result2)
result3 := FindDuplicates([]int{})
is.Equal(0, len(result3))
is.Equal([]int{}, result3)
type myStrings []string
allStrings := myStrings{"", "foo", "bar"}
nonempty := FindDuplicates(allStrings)
is.IsType(nonempty, allStrings, "type preserved")
}
func TestFindDuplicatesBy(t *testing.T) {
t.Parallel()
is := assert.New(t)
result1 := FindDuplicatesBy([]int{3, 4, 5, 6, 7}, func(i int) int {
return i % 3
})
is.Equal(2, len(result1))
is.Equal([]int{3, 4}, result1)
result2 := FindDuplicatesBy([]int{0, 1, 2, 3, 4}, func(i int) int {
return i % 5
})
is.Equal(0, len(result2))
is.Equal([]int{}, result2)
result3 := FindDuplicatesBy([]int{}, func(i int) int {
return i % 3
})
is.Equal(0, len(result3))
is.Equal([]int{}, result3)
type myStrings []string
allStrings := myStrings{"", "foo", "bar"}
nonempty := FindDuplicatesBy(allStrings, func(i string) string {
return i
})
is.IsType(nonempty, allStrings, "type preserved")
}
func TestMin(t *testing.T) {
t.Parallel()
is := assert.New(t)
result1 := Min([]int{1, 2, 3})
result2 := Min([]int{3, 2, 1})
result3 := Min([]time.Duration{time.Second, time.Minute, time.Hour})
result4 := Min([]int{})
is.Equal(result1, 1)
is.Equal(result2, 1)
is.Equal(result3, time.Second)
is.Equal(result4, 0)
}
func TestMinIndex(t *testing.T) {
t.Parallel()
is := assert.New(t)
result1, index1 := MinIndex([]int{1, 2, 3})
result2, index2 := MinIndex([]int{3, 2, 1})
result3, index3 := MinIndex([]time.Duration{time.Second, time.Minute, time.Hour})
result4, index4 := MinIndex([]int{})
is.Equal(result1, 1)
is.Equal(index1, 0)
is.Equal(result2, 1)
is.Equal(index2, 2)
is.Equal(result3, time.Second)
is.Equal(index3, 0)
is.Equal(result4, 0)
is.Equal(index4, -1)
}
func TestMinBy(t *testing.T) {
t.Parallel()
is := assert.New(t)
result1 := MinBy([]string{"s1", "string2", "s3"}, func(item string, min string) bool {
return len(item) < len(min)
})
result2 := MinBy([]string{"string1", "string2", "s3"}, func(item string, min string) bool {
return len(item) < len(min)
})
result3 := MinBy([]string{}, func(item string, min string) bool {
return len(item) < len(min)
})
is.Equal(result1, "s1")
is.Equal(result2, "s3")
is.Equal(result3, "")
}
func TestMinIndexBy(t *testing.T) {
t.Parallel()
is := assert.New(t)
result1, index1 := MinIndexBy([]string{"s1", "string2", "s3"}, func(item string, min string) bool {
return len(item) < len(min)
})
result2, index2 := MinIndexBy([]string{"string1", "string2", "s3"}, func(item string, min string) bool {
return len(item) < len(min)
})
result3, index3 := MinIndexBy([]string{}, func(item string, min string) bool {
return len(item) < len(min)
})
is.Equal(result1, "s1")
is.Equal(index1, 0)
is.Equal(result2, "s3")
is.Equal(index2, 2)
is.Equal(result3, "")
is.Equal(index3, -1)
}
func TestEarliest(t *testing.T) {
t.Parallel()
is := assert.New(t)
a := time.Now()
b := a.Add(time.Hour)
result1 := Earliest(a, b)
result2 := Earliest()
is.Equal(result1, a)
is.Equal(result2, time.Time{})
}
func TestEarliestBy(t *testing.T) {
t.Parallel()
is := assert.New(t)
type foo struct {
bar time.Time
}
t1 := time.Now()
t2 := t1.Add(time.Hour)
t3 := t1.Add(-time.Hour)
result1 := EarliestBy([]foo{{t1}, {t2}, {t3}}, func(i foo) time.Time {
return i.bar
})
result2 := EarliestBy([]foo{{t1}}, func(i foo) time.Time {
return i.bar
})
result3 := EarliestBy([]foo{}, func(i foo) time.Time {
return i.bar
})
is.Equal(result1, foo{t3})
is.Equal(result2, foo{t1})
is.Equal(result3, foo{})
}
func TestMax(t *testing.T) {
t.Parallel()
is := assert.New(t)
result1 := Max([]int{1, 2, 3})
result2 := Max([]int{3, 2, 1})
result3 := Max([]time.Duration{time.Second, time.Minute, time.Hour})
result4 := Max([]int{})
is.Equal(result1, 3)
is.Equal(result2, 3)
is.Equal(result3, time.Hour)
is.Equal(result4, 0)
}
func TestMaxIndex(t *testing.T) {
t.Parallel()
is := assert.New(t)
result1, index1 := MaxIndex([]int{1, 2, 3})
result2, index2 := MaxIndex([]int{3, 2, 1})
result3, index3 := MaxIndex([]time.Duration{time.Second, time.Minute, time.Hour})
result4, index4 := MaxIndex([]int{})
is.Equal(result1, 3)
is.Equal(index1, 2)
is.Equal(result2, 3)
is.Equal(index2, 0)
is.Equal(result3, time.Hour)
is.Equal(index3, 2)
is.Equal(result4, 0)
is.Equal(index4, -1)
}
func TestMaxBy(t *testing.T) {
t.Parallel()
is := assert.New(t)
result1 := MaxBy([]string{"s1", "string2", "s3"}, func(item string, max string) bool {
return len(item) > len(max)
})
result2 := MaxBy([]string{"string1", "string2", "s3"}, func(item string, max string) bool {
return len(item) > len(max)
})
result3 := MaxBy([]string{}, func(item string, max string) bool {
return len(item) > len(max)
})
is.Equal(result1, "string2")
is.Equal(result2, "string1")
is.Equal(result3, "")
}
func TestMaxIndexBy(t *testing.T) {
t.Parallel()
is := assert.New(t)
result1, index1 := MaxIndexBy([]string{"s1", "string2", "s3"}, func(item string, max string) bool {
return len(item) > len(max)
})
result2, index2 := MaxIndexBy([]string{"string1", "string2", "s3"}, func(item string, max string) bool {
return len(item) > len(max)
})
result3, index3 := MaxIndexBy([]string{}, func(item string, max string) bool {
return len(item) > len(max)
})
is.Equal(result1, "string2")
is.Equal(index1, 1)
is.Equal(result2, "string1")
is.Equal(index2, 0)
is.Equal(result3, "")
is.Equal(index3, -1)
}
func TestLatest(t *testing.T) {
t.Parallel()
is := assert.New(t)
a := time.Now()
b := a.Add(time.Hour)
result1 := Latest(a, b)
result2 := Latest()
is.Equal(result1, b)
is.Equal(result2, time.Time{})
}
func TestLatestBy(t *testing.T) {
t.Parallel()
is := assert.New(t)
type foo struct {
bar time.Time
}
t1 := time.Now()
t2 := t1.Add(time.Hour)
t3 := t1.Add(-time.Hour)
result1 := LatestBy([]foo{{t1}, {t2}, {t3}}, func(i foo) time.Time {
return i.bar
})
result2 := LatestBy([]foo{{t1}}, func(i foo) time.Time {
return i.bar
})
result3 := LatestBy([]foo{}, func(i foo) time.Time {
return i.bar
})
is.Equal(result1, foo{t2})
is.Equal(result2, foo{t1})
is.Equal(result3, foo{})
}
func TestFirst(t *testing.T) {
t.Parallel()
is := assert.New(t)
result1, ok1 := First([]int{1, 2, 3})
result2, ok2 := First([]int{})
is.Equal(result1, 1)
is.Equal(ok1, true)
is.Equal(result2, 0)
is.Equal(ok2, false)
}
func TestFirstOrEmpty(t *testing.T) {
t.Parallel()
is := assert.New(t)
result1 := FirstOrEmpty([]int{1, 2, 3})
result2 := FirstOrEmpty([]int{})
result3 := FirstOrEmpty([]string{})
is.Equal(result1, 1)
is.Equal(result2, 0)
is.Equal(result3, "")
}
func TestFirstOr(t *testing.T) {
t.Parallel()
is := assert.New(t)
result1 := FirstOr([]int{1, 2, 3}, 63)
result2 := FirstOr([]int{}, 23)
result3 := FirstOr([]string{}, "test")
is.Equal(result1, 1)
is.Equal(result2, 23)
is.Equal(result3, "test")
}
func TestLast(t *testing.T) {
t.Parallel()
is := assert.New(t)
result1, ok1 := Last([]int{1, 2, 3})
result2, ok2 := Last([]int{})
is.Equal(result1, 3)
is.True(ok1)
is.Equal(result2, 0)
is.False(ok2)
}
func TestLastOrEmpty(t *testing.T) {
t.Parallel()
is := assert.New(t)
result1 := LastOrEmpty([]int{1, 2, 3})
result2 := LastOrEmpty([]int{})
result3 := LastOrEmpty([]string{})
is.Equal(result1, 3)
is.Equal(result2, 0)
is.Equal(result3, "")
}
func TestLastOr(t *testing.T) {
t.Parallel()
is := assert.New(t)
result1 := LastOr([]int{1, 2, 3}, 63)
result2 := LastOr([]int{}, 23)
result3 := LastOr([]string{}, "test")
is.Equal(result1, 3)
is.Equal(result2, 23)
is.Equal(result3, "test")
}
func TestNth(t *testing.T) {
t.Parallel()
is := assert.New(t)
result1, err1 := Nth([]int{0, 1, 2, 3}, 2)
result2, err2 := Nth([]int{0, 1, 2, 3}, -2)
result3, err3 := Nth([]int{0, 1, 2, 3}, 42)
result4, err4 := Nth([]int{}, 0)
result5, err5 := Nth([]int{42}, 0)
result6, err6 := Nth([]int{42}, -1)
is.Equal(result1, 2)
is.Equal(err1, nil)
is.Equal(result2, 2)
is.Equal(err2, nil)
is.Equal(result3, 0)
is.Equal(err3, fmt.Errorf("nth: 42 out of slice bounds"))
is.Equal(result4, 0)
is.Equal(err4, fmt.Errorf("nth: 0 out of slice bounds"))
is.Equal(result5, 42)
is.Equal(err5, nil)
is.Equal(result6, 42)
is.Equal(err6, nil)
}
func TestNthOr(t *testing.T) {
t.Parallel()
is := assert.New(t)
t.Run("Integers", func(t *testing.T) {
const defaultValue = -1
intSlice := []int{10, 20, 30, 40, 50}
is.Equal(30, NthOr(intSlice, 2, defaultValue))
is.Equal(50, NthOr(intSlice, -1, defaultValue))
is.Equal(defaultValue, NthOr(intSlice, 5, defaultValue))
})
t.Run("Strings", func(t *testing.T) {
const defaultValue = "none"
strSlice := []string{"apple", "banana", "cherry", "date"}
is.Equal("banana", NthOr(strSlice, 1, defaultValue)) // Index 1, expected "banana"
is.Equal("cherry", NthOr(strSlice, -2, defaultValue)) // Negative index -2, expected "cherry"
is.Equal(defaultValue, NthOr(strSlice, 10, defaultValue)) // Out of bounds, fallback "none"
})
t.Run("Structs", func(t *testing.T) {
type User struct {
ID int
Name string
}
userSlice := []User{
{ID: 1, Name: "Alice"},
{ID: 2, Name: "Bob"},
{ID: 3, Name: "Charlie"},
}
expectedUser := User{ID: 1, Name: "Alice"}
is.Equal(expectedUser, NthOr(userSlice, 0, User{ID: 0, Name: "Unknown"}))
expectedUser = User{ID: 3, Name: "Charlie"}
is.Equal(expectedUser, NthOr(userSlice, -1, User{ID: 0, Name: "Unknown"}))
expectedUser = User{ID: 0, Name: "Unknown"}
is.Equal(expectedUser, NthOr(userSlice, 10, User{ID: 0, Name: "Unknown"}))
})
}
func TestNthOrEmpty(t *testing.T) {
t.Parallel()
is := assert.New(t)
t.Run("Integers", func(t *testing.T) {
const defaultValue = 0
intSlice := []int{10, 20, 30, 40, 50}
is.Equal(30, NthOrEmpty(intSlice, 2))
is.Equal(50, NthOrEmpty(intSlice, -1))
is.Equal(defaultValue, NthOrEmpty(intSlice, 10))
})
t.Run("Strings", func(t *testing.T) {
const defaultValue = ""
strSlice := []string{"apple", "banana", "cherry", "date"}
is.Equal("banana", NthOrEmpty(strSlice, 1))
is.Equal("cherry", NthOrEmpty(strSlice, -2))
is.Equal(defaultValue, NthOrEmpty(strSlice, 10))
})
t.Run("Structs", func(t *testing.T) {
type User struct {
ID int
Name string
}
userSlice := []User{
{ID: 1, Name: "Alice"},
{ID: 2, Name: "Bob"},
{ID: 3, Name: "Charlie"},
}
expectedUser := User{ID: 1, Name: "Alice"}
is.Equal(expectedUser, NthOrEmpty(userSlice, 0))
expectedUser = User{ID: 3, Name: "Charlie"}
is.Equal(expectedUser, NthOrEmpty(userSlice, -1))
expectedUser = User{ID: 0, Name: ""}
is.Equal(expectedUser, NthOrEmpty(userSlice, 10))
})
}
func TestSample(t *testing.T) {
t.Parallel()
is := assert.New(t)
rand.Seed(time.Now().UnixNano())
result1 := Sample([]string{"a", "b", "c"})
result2 := Sample([]string{})
is.True(Contains([]string{"a", "b", "c"}, result1))
is.Equal(result2, "")
}
func TestSampleBy(t *testing.T) {
t.Parallel()
is := assert.New(t)
r := rand.New(rand.NewSource(42))
result1 := SampleBy([]string{"a", "b", "c"}, r.Intn)
result2 := SampleBy([]string{}, rand.Intn)
is.True(Contains([]string{"a", "b", "c"}, result1))
is.Equal(result2, "")
}
func TestSamples(t *testing.T) {
t.Parallel()
is := assert.New(t)
rand.Seed(time.Now().UnixNano())
result1 := Samples([]string{"a", "b", "c"}, 3)
result2 := Samples([]string{}, 3)
sort.Strings(result1)
is.Equal(result1, []string{"a", "b", "c"})
is.Equal(result2, []string{})
type myStrings []string
allStrings := myStrings{"", "foo", "bar"}
nonempty := Samples(allStrings, 2)
is.IsType(nonempty, allStrings, "type preserved")
}
func TestSamplesBy(t *testing.T) {
t.Parallel()
is := assert.New(t)
r := rand.New(rand.NewSource(42))
result1 := SamplesBy([]string{"a", "b", "c"}, 3, r.Intn)
result2 := SamplesBy([]string{}, 3, r.Intn)
sort.Strings(result1)
is.Equal(result1, []string{"a", "b", "c"})
is.Equal(result2, []string{})
type myStrings []string
allStrings := myStrings{"", "foo", "bar"}
nonempty := SamplesBy(allStrings, 2, r.Intn)
is.IsType(nonempty, allStrings, "type preserved")
}

View File

@@ -1,80 +0,0 @@
package lo
import (
"strconv"
"testing"
"github.com/stretchr/testify/assert"
)
func TestPartial(t *testing.T) {
t.Parallel()
is := assert.New(t)
add := func(x float64, y int) string {
return strconv.Itoa(int(x) + y)
}
f := Partial(add, 5)
is.Equal("15", f(10))
is.Equal("0", f(-5))
}
func TestPartial1(t *testing.T) {
t.Parallel()
is := assert.New(t)
add := func(x float64, y int) string {
return strconv.Itoa(int(x) + y)
}
f := Partial1(add, 5)
is.Equal("15", f(10))
is.Equal("0", f(-5))
}
func TestPartial2(t *testing.T) {
t.Parallel()
is := assert.New(t)
add := func(x float64, y int, z int) string {
return strconv.Itoa(int(x) + y + z)
}
f := Partial2(add, 5)
is.Equal("24", f(10, 9))
is.Equal("8", f(-5, 8))
}
func TestPartial3(t *testing.T) {
t.Parallel()
is := assert.New(t)
add := func(x float64, y int, z int, a float32) string {
return strconv.Itoa(int(x) + y + z + int(a))
}
f := Partial3(add, 5)
is.Equal("21", f(10, 9, -3))
is.Equal("15", f(-5, 8, 7))
}
func TestPartial4(t *testing.T) {
t.Parallel()
is := assert.New(t)
add := func(x float64, y int, z int, a float32, b int32) string {
return strconv.Itoa(int(x) + y + z + int(a) + int(b))
}
f := Partial4(add, 5)
is.Equal("21", f(10, 9, -3, 0))
is.Equal("14", f(-5, 8, 7, -1))
}
func TestPartial5(t *testing.T) {
t.Parallel()
is := assert.New(t)
add := func(x float64, y int, z int, a float32, b int32, c int) string {
return strconv.Itoa(int(x) + y + z + int(a) + int(b) + c)
}
f := Partial5(add, 5)
is.Equal("26", f(10, 9, -3, 0, 5))
is.Equal("21", f(-5, 8, 7, -1, 7))
}

2
go.mod
View File

@@ -8,8 +8,6 @@ go 1.18
require (
github.com/stretchr/testify v1.10.0
github.com/thoas/go-funk v0.9.3
go.uber.org/goleak v1.2.1
golang.org/x/text v0.22.0
)

8
go.sum
View File

@@ -1,5 +1,4 @@
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
@@ -10,19 +9,12 @@ github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWb
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/thoas/go-funk v0.9.3 h1:7+nAEx3kn5ZJcnDm2Bh23N2yOtweO14bi//dvRtgLpw=
github.com/thoas/go-funk v0.9.3/go.mod h1:+IWnUfUmFO1+WVYQWQtIJHeRRdaIyyYglZN7xzUPe4Q=
go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A=
go.uber.org/goleak v1.2.1/go.mod h1:qlT2yGI9QafXHhZZLxlSuNsMw3FFLxBr+tBRlmO1xH4=
golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View File

@@ -1,2 +0,0 @@
Credits goes to https://gopherize.me/

Binary file not shown.

Before

Width:  |  Height:  |  Size: 563 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 235 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 87 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 662 KiB

Binary file not shown.

View File

@@ -1,34 +0,0 @@
package lo
import (
"fmt"
)
func ExampleWithoutBy() {
type User struct {
ID int
Name string
}
// original users
users := []User{
{ID: 1, Name: "Alice"},
{ID: 2, Name: "Bob"},
{ID: 3, Name: "Charlie"},
}
// exclude users with IDs 2 and 3
excludedIDs := []int{2, 3}
// extract function to get the user ID
extractID := func(user User) int {
return user.ID
}
// filtering users
filteredUsers := WithoutBy(users, extractID, excludedIDs...)
// output the filtered users
fmt.Printf("%v\n", filteredUsers)
// Output:
// [{1 Alice}]
}

View File

@@ -1,363 +0,0 @@
package lo
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestContains(t *testing.T) {
t.Parallel()
is := assert.New(t)
result1 := Contains([]int{0, 1, 2, 3, 4, 5}, 5)
result2 := Contains([]int{0, 1, 2, 3, 4, 5}, 6)
is.Equal(result1, true)
is.Equal(result2, false)
}
func TestContainsBy(t *testing.T) {
t.Parallel()
is := assert.New(t)
type a struct {
A int
B string
}
a1 := []a{{A: 1, B: "1"}, {A: 2, B: "2"}, {A: 3, B: "3"}}
result1 := ContainsBy(a1, func(t a) bool { return t.A == 1 && t.B == "2" })
result2 := ContainsBy(a1, func(t a) bool { return t.A == 2 && t.B == "2" })
a2 := []string{"aaa", "bbb", "ccc"}
result3 := ContainsBy(a2, func(t string) bool { return t == "ccc" })
result4 := ContainsBy(a2, func(t string) bool { return t == "ddd" })
is.Equal(result1, false)
is.Equal(result2, true)
is.Equal(result3, true)
is.Equal(result4, false)
}
func TestEvery(t *testing.T) {
t.Parallel()
is := assert.New(t)
result1 := Every([]int{0, 1, 2, 3, 4, 5}, []int{0, 2})
result2 := Every([]int{0, 1, 2, 3, 4, 5}, []int{0, 6})
result3 := Every([]int{0, 1, 2, 3, 4, 5}, []int{-1, 6})
result4 := Every([]int{0, 1, 2, 3, 4, 5}, []int{})
is.True(result1)
is.False(result2)
is.False(result3)
is.True(result4)
}
func TestEveryBy(t *testing.T) {
t.Parallel()
is := assert.New(t)
result1 := EveryBy([]int{1, 2, 3, 4}, func(x int) bool {
return x < 5
})
is.True(result1)
result2 := EveryBy([]int{1, 2, 3, 4}, func(x int) bool {
return x < 3
})
is.False(result2)
result3 := EveryBy([]int{1, 2, 3, 4}, func(x int) bool {
return x < 0
})
is.False(result3)
result4 := EveryBy([]int{}, func(x int) bool {
return x < 5
})
is.True(result4)
}
func TestSome(t *testing.T) {
t.Parallel()
is := assert.New(t)
result1 := Some([]int{0, 1, 2, 3, 4, 5}, []int{0, 2})
result2 := Some([]int{0, 1, 2, 3, 4, 5}, []int{0, 6})
result3 := Some([]int{0, 1, 2, 3, 4, 5}, []int{-1, 6})
result4 := Some([]int{0, 1, 2, 3, 4, 5}, []int{})
is.True(result1)
is.True(result2)
is.False(result3)
is.False(result4)
}
func TestSomeBy(t *testing.T) {
t.Parallel()
is := assert.New(t)
result1 := SomeBy([]int{1, 2, 3, 4}, func(x int) bool {
return x < 5
})
is.True(result1)
result2 := SomeBy([]int{1, 2, 3, 4}, func(x int) bool {
return x < 3
})
is.True(result2)
result3 := SomeBy([]int{1, 2, 3, 4}, func(x int) bool {
return x < 0
})
is.False(result3)
result4 := SomeBy([]int{}, func(x int) bool {
return x < 5
})
is.False(result4)
}
func TestNone(t *testing.T) {
t.Parallel()
is := assert.New(t)
result1 := None([]int{0, 1, 2, 3, 4, 5}, []int{0, 2})
result2 := None([]int{0, 1, 2, 3, 4, 5}, []int{0, 6})
result3 := None([]int{0, 1, 2, 3, 4, 5}, []int{-1, 6})
result4 := None([]int{0, 1, 2, 3, 4, 5}, []int{})
is.False(result1)
is.False(result2)
is.True(result3)
is.True(result4)
}
func TestNoneBy(t *testing.T) {
t.Parallel()
is := assert.New(t)
result1 := NoneBy([]int{1, 2, 3, 4}, func(x int) bool {
return x < 5
})
is.False(result1)
result2 := NoneBy([]int{1, 2, 3, 4}, func(x int) bool {
return x < 3
})
is.False(result2)
result3 := NoneBy([]int{1, 2, 3, 4}, func(x int) bool {
return x < 0
})
is.True(result3)
result4 := NoneBy([]int{}, func(x int) bool {
return x < 5
})
is.True(result4)
}
func TestIntersect(t *testing.T) {
t.Parallel()
is := assert.New(t)
result1 := Intersect([]int{0, 1, 2, 3, 4, 5}, []int{0, 2})
result2 := Intersect([]int{0, 1, 2, 3, 4, 5}, []int{0, 6})
result3 := Intersect([]int{0, 1, 2, 3, 4, 5}, []int{-1, 6})
result4 := Intersect([]int{0, 6}, []int{0, 1, 2, 3, 4, 5})
result5 := Intersect([]int{0, 6, 0}, []int{0, 1, 2, 3, 4, 5})
is.Equal(result1, []int{0, 2})
is.Equal(result2, []int{0})
is.Equal(result3, []int{})
is.Equal(result4, []int{0})
is.Equal(result5, []int{0})
type myStrings []string
allStrings := myStrings{"", "foo", "bar"}
nonempty := Intersect(allStrings, allStrings)
is.IsType(nonempty, allStrings, "type preserved")
}
func TestDifference(t *testing.T) {
t.Parallel()
is := assert.New(t)
left1, right1 := Difference([]int{0, 1, 2, 3, 4, 5}, []int{0, 2, 6})
is.Equal(left1, []int{1, 3, 4, 5})
is.Equal(right1, []int{6})
left2, right2 := Difference([]int{1, 2, 3, 4, 5}, []int{0, 6})
is.Equal(left2, []int{1, 2, 3, 4, 5})
is.Equal(right2, []int{0, 6})
left3, right3 := Difference([]int{0, 1, 2, 3, 4, 5}, []int{0, 1, 2, 3, 4, 5})
is.Equal(left3, []int{})
is.Equal(right3, []int{})
type myStrings []string
allStrings := myStrings{"", "foo", "bar"}
a, b := Difference(allStrings, allStrings)
is.IsType(a, allStrings, "type preserved")
is.IsType(b, allStrings, "type preserved")
}
func TestUnion(t *testing.T) {
t.Parallel()
is := assert.New(t)
result1 := Union([]int{0, 1, 2, 3, 4, 5}, []int{0, 2, 10})
result2 := Union([]int{0, 1, 2, 3, 4, 5}, []int{6, 7})
result3 := Union([]int{0, 1, 2, 3, 4, 5}, []int{})
result4 := Union([]int{0, 1, 2}, []int{0, 1, 2})
result5 := Union([]int{}, []int{})
is.Equal(result1, []int{0, 1, 2, 3, 4, 5, 10})
is.Equal(result2, []int{0, 1, 2, 3, 4, 5, 6, 7})
is.Equal(result3, []int{0, 1, 2, 3, 4, 5})
is.Equal(result4, []int{0, 1, 2})
is.Equal(result5, []int{})
result11 := Union([]int{0, 1, 2, 3, 4, 5}, []int{0, 2, 10}, []int{0, 1, 11})
result12 := Union([]int{0, 1, 2, 3, 4, 5}, []int{6, 7}, []int{8, 9})
result13 := Union([]int{0, 1, 2, 3, 4, 5}, []int{}, []int{})
result14 := Union([]int{0, 1, 2}, []int{0, 1, 2}, []int{0, 1, 2})
result15 := Union([]int{}, []int{}, []int{})
is.Equal(result11, []int{0, 1, 2, 3, 4, 5, 10, 11})
is.Equal(result12, []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9})
is.Equal(result13, []int{0, 1, 2, 3, 4, 5})
is.Equal(result14, []int{0, 1, 2})
is.Equal(result15, []int{})
type myStrings []string
allStrings := myStrings{"", "foo", "bar"}
nonempty := Union(allStrings, allStrings)
is.IsType(nonempty, allStrings, "type preserved")
}
func TestWithout(t *testing.T) {
t.Parallel()
is := assert.New(t)
result1 := Without([]int{0, 2, 10}, 0, 1, 2, 3, 4, 5)
result2 := Without([]int{0, 7}, 0, 1, 2, 3, 4, 5)
result3 := Without([]int{}, 0, 1, 2, 3, 4, 5)
result4 := Without([]int{0, 1, 2}, 0, 1, 2)
result5 := Without([]int{})
is.Equal(result1, []int{10})
is.Equal(result2, []int{7})
is.Equal(result3, []int{})
is.Equal(result4, []int{})
is.Equal(result5, []int{})
type myStrings []string
allStrings := myStrings{"", "foo", "bar"}
nonempty := Without(allStrings, "")
is.IsType(nonempty, allStrings, "type preserved")
}
func TestWithoutBy(t *testing.T) {
t.Parallel()
is := assert.New(t)
type User struct {
Name string
Age int
}
result1 := WithoutBy([]User{{Name: "nick"}, {Name: "peter"}},
func(item User) string {
return item.Name
}, "nick", "lily")
result2 := WithoutBy([]User{}, func(item User) int { return item.Age }, 1, 2, 3)
result3 := WithoutBy([]User{}, func(item User) string { return item.Name })
is.Equal(result1, []User{{Name: "peter"}})
is.Equal(result2, []User{})
is.Equal(result3, []User{})
}
func TestWithoutEmpty(t *testing.T) {
t.Parallel()
is := assert.New(t)
result1 := WithoutEmpty([]int{0, 1, 2})
result2 := WithoutEmpty([]int{1, 2})
result3 := WithoutEmpty([]int{})
result4 := WithoutEmpty([]*int{ToPtr(0), ToPtr(1), nil, ToPtr(2)})
is.Equal(result1, []int{1, 2})
is.Equal(result2, []int{1, 2})
is.Equal(result3, []int{})
is.Equal(result4, []*int{ToPtr(0), ToPtr(1), ToPtr(2)})
type myStrings []string
allStrings := myStrings{"", "foo", "bar"}
nonempty := WithoutEmpty(allStrings)
is.IsType(nonempty, allStrings, "type preserved")
}
func TestWithoutNth(t *testing.T) {
t.Parallel()
is := assert.New(t)
result1 := WithoutNth([]int{5, 6, 7}, 1, 0)
is.Equal([]int{7}, result1)
result2 := WithoutNth([]int{1, 2})
is.Equal([]int{1, 2}, result2)
result3 := WithoutNth([]int{})
is.Equal([]int{}, result3)
result4 := WithoutNth([]int{0, 1, 2, 3}, -1, 4)
is.Equal([]int{0, 1, 2, 3}, result4)
type myStrings []string
allStrings := myStrings{"", "foo", "bar"}
nonempty := WithoutNth(allStrings)
is.IsType(nonempty, allStrings, "type preserved")
}
func TestElementsMatch(t *testing.T) {
t.Parallel()
is := assert.New(t)
is.False(ElementsMatch([]int{}, []int{1}))
is.False(ElementsMatch([]int{1}, []int{2}))
is.False(ElementsMatch([]int{1}, []int{1, 2}))
is.False(ElementsMatch([]int{1, 1, 2}, []int{2, 2, 1}))
is.True(ElementsMatch([]int{}, nil))
is.True(ElementsMatch([]int{1}, []int{1}))
is.True(ElementsMatch([]int{1, 1}, []int{1, 1}))
is.True(ElementsMatch([]int{1, 2}, []int{2, 1}))
is.True(ElementsMatch([]int{1, 1, 2}, []int{1, 2, 1}))
}
func TestElementsMatchBy(t *testing.T) {
t.Parallel()
is := assert.New(t)
type someType struct {
key string
}
is.True(ElementsMatchBy(
[]someType{{key: "a"}, {key: "b"}},
[]someType{{key: "b"}, {key: "a"}},
func(item someType) string { return item.key },
))
}

View File

@@ -1,31 +0,0 @@
package lo
import (
"testing"
"time"
)
// https://github.com/stretchr/testify/issues/1101
func testWithTimeout(t *testing.T, timeout time.Duration) {
t.Helper()
testFinished := make(chan struct{})
t.Cleanup(func() { close(testFinished) })
go func() { //nolint:staticcheck
select {
case <-testFinished:
case <-time.After(timeout):
t.Errorf("test timed out after %s", timeout)
t.FailNow() //nolint:govet,staticcheck
}
}()
}
type foo struct {
bar string
}
func (f foo) Clone() foo {
return foo{f.bar}
}

View File

@@ -1,11 +0,0 @@
package lo
import (
"testing"
"go.uber.org/goleak"
)
func TestMain(m *testing.M) {
goleak.VerifyTestMain(m)
}

View File

@@ -1,124 +0,0 @@
package lo
import (
"math/rand"
"strconv"
"testing"
"time"
lop "github.com/samber/lo/parallel"
"github.com/thoas/go-funk"
)
func sliceGenerator(size uint) []int64 {
r := rand.New(rand.NewSource(time.Now().Unix()))
result := make([]int64, size)
for i := uint(0); i < size; i++ {
result[i] = r.Int63()
}
return result
}
func mapGenerator(size uint) map[int64]int64 {
r := rand.New(rand.NewSource(time.Now().Unix()))
result := make(map[int64]int64, size)
for i := uint(0); i < size; i++ {
result[int64(i)] = r.Int63()
}
return result
}
func BenchmarkMap(b *testing.B) {
arr := sliceGenerator(1000000)
b.Run("lo.Map", func(b *testing.B) {
for n := 0; n < b.N; n++ {
_ = Map(arr, func(x int64, i int) string {
return strconv.FormatInt(x, 10)
})
}
})
b.Run("lop.Map", func(b *testing.B) {
for n := 0; n < b.N; n++ {
_ = lop.Map(arr, func(x int64, i int) string {
return strconv.FormatInt(x, 10)
})
}
})
b.Run("reflect", func(b *testing.B) {
for n := 0; n < b.N; n++ {
_ = funk.Map(arr, func(x int64) string {
return strconv.FormatInt(x, 10)
})
}
})
b.Run("for", func(b *testing.B) {
for n := 0; n < b.N; n++ {
results := make([]string, len(arr))
for i, item := range arr {
result := strconv.FormatInt(item, 10)
results[i] = result
}
}
})
}
// also apply to UniqValues
func BenchmarkUniqKeys(b *testing.B) {
m := []map[int64]int64{
mapGenerator(100000),
mapGenerator(100000),
mapGenerator(100000),
}
// allocate just in time + ordered
b.Run("lo.UniqKeys.jit-alloc", func(b *testing.B) {
for n := 0; n < b.N; n++ {
seen := make(map[int64]struct{})
result := make([]int64, 0)
for i := range m {
for k := range m[i] {
if _, exists := seen[k]; exists {
continue
}
seen[k] = struct{}{}
result = append(result, k) //nolint:staticcheck
}
}
}
})
// preallocate + unordered
b.Run("lo.UniqKeys.preallocate", func(b *testing.B) {
for n := 0; n < b.N; n++ {
size := 0
for i := range m {
size += len(m[i])
}
seen := make(map[int64]struct{}, size)
for i := range m {
for k := range m[i] {
seen[k] = struct{}{}
}
}
result := make([]int64, 0, len(seen))
for k := range seen {
result = append(result, k) //nolint:staticcheck
}
}
})
}

View File

@@ -1,246 +0,0 @@
package lo
import (
"fmt"
"sort"
"strconv"
"strings"
)
func ExampleKeys() {
kv := map[string]int{"foo": 1, "bar": 2}
kv2 := map[string]int{"baz": 3}
result := Keys(kv, kv2)
sort.Strings(result)
fmt.Printf("%v", result)
// Output: [bar baz foo]
}
func ExampleUniqKeys() {
kv := map[string]int{"foo": 1, "bar": 2}
kv2 := map[string]int{"bar": 3}
result := UniqKeys(kv, kv2)
sort.Strings(result)
fmt.Printf("%v", result)
// Output: [bar foo]
}
func ExampleValues() {
kv := map[string]int{"foo": 1, "bar": 2}
kv2 := map[string]int{"baz": 3}
result := Values(kv, kv2)
sort.Ints(result)
fmt.Printf("%v", result)
// Output: [1 2 3]
}
func ExampleUniqValues() {
kv := map[string]int{"foo": 1, "bar": 2}
kv2 := map[string]int{"baz": 2}
result := UniqValues(kv, kv2)
sort.Ints(result)
fmt.Printf("%v", result)
// Output: [1 2]
}
func ExampleValueOr() {
kv := map[string]int{"foo": 1, "bar": 2}
result1 := ValueOr(kv, "foo", 42)
result2 := ValueOr(kv, "baz", 42)
fmt.Printf("%v %v", result1, result2)
// Output: 1 42
}
func ExamplePickBy() {
kv := map[string]int{"foo": 1, "bar": 2, "baz": 3}
result := PickBy(kv, func(key string, value int) bool {
return value%2 == 1
})
fmt.Printf("%v %v %v", len(result), result["foo"], result["baz"])
// Output: 2 1 3
}
func ExamplePickByKeys() {
kv := map[string]int{"foo": 1, "bar": 2, "baz": 3}
result := PickByKeys(kv, []string{"foo", "baz"})
fmt.Printf("%v %v %v", len(result), result["foo"], result["baz"])
// Output: 2 1 3
}
func ExamplePickByValues() {
kv := map[string]int{"foo": 1, "bar": 2, "baz": 3}
result := PickByValues(kv, []int{1, 3})
fmt.Printf("%v %v %v", len(result), result["foo"], result["baz"])
// Output: 2 1 3
}
func ExampleOmitBy() {
kv := map[string]int{"foo": 1, "bar": 2, "baz": 3}
result := OmitBy(kv, func(key string, value int) bool {
return value%2 == 1
})
fmt.Printf("%v", result)
// Output: map[bar:2]
}
func ExampleOmitByKeys() {
kv := map[string]int{"foo": 1, "bar": 2, "baz": 3}
result := OmitByKeys(kv, []string{"foo", "baz"})
fmt.Printf("%v", result)
// Output: map[bar:2]
}
func ExampleOmitByValues() {
kv := map[string]int{"foo": 1, "bar": 2, "baz": 3}
result := OmitByValues(kv, []int{1, 3})
fmt.Printf("%v", result)
// Output: map[bar:2]
}
func ExampleEntries() {
kv := map[string]int{"foo": 1, "bar": 2, "baz": 3}
result := Entries(kv)
sort.Slice(result, func(i, j int) bool {
return strings.Compare(result[i].Key, result[j].Key) < 0
})
fmt.Printf("%v", result)
// Output: [{bar 2} {baz 3} {foo 1}]
}
func ExampleFromEntries() {
result := FromEntries([]Entry[string, int]{
{
Key: "foo",
Value: 1,
},
{
Key: "bar",
Value: 2,
},
{
Key: "baz",
Value: 3,
},
})
fmt.Printf("%v %v %v %v", len(result), result["foo"], result["bar"], result["baz"])
// Output: 3 1 2 3
}
func ExampleInvert() {
kv := map[string]int{"foo": 1, "bar": 2, "baz": 3}
result := Invert(kv)
fmt.Printf("%v %v %v %v", len(result), result[1], result[2], result[3])
// Output: 3 foo bar baz
}
func ExampleAssign() {
result := Assign(
map[string]int{"a": 1, "b": 2},
map[string]int{"b": 3, "c": 4},
)
fmt.Printf("%v %v %v %v", len(result), result["a"], result["b"], result["c"])
// Output: 3 1 3 4
}
func ExampleChunkEntries() {
result := ChunkEntries(
map[string]int{
"a": 1,
"b": 2,
"c": 3,
"d": 4,
"e": 5,
},
3,
)
for i := range result {
fmt.Printf("%d\n", len(result[i]))
}
// Output:
// 3
// 2
}
func ExampleMapKeys() {
kv := map[int]int{1: 1, 2: 2, 3: 3, 4: 4}
result := MapKeys(kv, func(_ int, k int) string {
return strconv.FormatInt(int64(k), 10)
})
fmt.Printf("%v %v %v %v %v", len(result), result["1"], result["2"], result["3"], result["4"])
// Output: 4 1 2 3 4
}
func ExampleMapValues() {
kv := map[int]int{1: 1, 2: 2, 3: 3, 4: 4}
result := MapValues(kv, func(v int, _ int) string {
return strconv.FormatInt(int64(v), 10)
})
fmt.Printf("%v %q %q %q %q", len(result), result[1], result[2], result[3], result[4])
// Output: 4 "1" "2" "3" "4"
}
func ExampleMapEntries() {
kv := map[string]int{"foo": 1, "bar": 2}
result := MapEntries(kv, func(k string, v int) (int, string) {
return v, k
})
fmt.Printf("%v\n", result)
// Output: map[1:foo 2:bar]
}
func ExampleMapToSlice() {
kv := map[int]int64{1: 1, 2: 2, 3: 3, 4: 4}
result := MapToSlice(kv, func(k int, v int64) string {
return fmt.Sprintf("%d_%d", k, v)
})
sort.StringSlice(result).Sort()
fmt.Printf("%v", result)
// Output: [1_1 2_2 3_3 4_4]
}
func ExampleFilterMapToSlice() {
kv := map[int]int64{1: 1, 2: 2, 3: 3, 4: 4}
result := FilterMapToSlice(kv, func(k int, v int64) (string, bool) {
return fmt.Sprintf("%d_%d", k, v), k%2 == 0
})
sort.StringSlice(result).Sort()
fmt.Printf("%v", result)
// Output: [2_2 4_4]
}

View File

@@ -1,595 +0,0 @@
package lo
import (
"fmt"
"sort"
"strconv"
"testing"
"github.com/stretchr/testify/assert"
)
func TestKeys(t *testing.T) {
t.Parallel()
is := assert.New(t)
r1 := Keys(map[string]int{"foo": 1, "bar": 2})
sort.Strings(r1)
is.Equal(r1, []string{"bar", "foo"})
r2 := Keys(map[string]int{})
is.Empty(r2)
r3 := Keys(map[string]int{"foo": 1, "bar": 2}, map[string]int{"baz": 3})
sort.Strings(r3)
is.Equal(r3, []string{"bar", "baz", "foo"})
r4 := Keys[string, int]()
is.Equal(r4, []string{})
r5 := Keys(map[string]int{"foo": 1, "bar": 2}, map[string]int{"bar": 3})
sort.Strings(r5)
is.Equal(r5, []string{"bar", "bar", "foo"})
}
func TestUniqKeys(t *testing.T) {
t.Parallel()
is := assert.New(t)
r1 := UniqKeys(map[string]int{"foo": 1, "bar": 2})
sort.Strings(r1)
is.Equal(r1, []string{"bar", "foo"})
r2 := UniqKeys(map[string]int{})
is.Empty(r2)
r3 := UniqKeys(map[string]int{"foo": 1, "bar": 2}, map[string]int{"baz": 3})
sort.Strings(r3)
is.Equal(r3, []string{"bar", "baz", "foo"})
r4 := UniqKeys[string, int]()
is.Equal(r4, []string{})
r5 := UniqKeys(map[string]int{"foo": 1, "bar": 2}, map[string]int{"foo": 1, "bar": 3})
sort.Strings(r5)
is.Equal(r5, []string{"bar", "foo"})
// check order
r6 := UniqKeys(map[string]int{"foo": 1}, map[string]int{"bar": 3})
is.Equal(r6, []string{"foo", "bar"})
}
func TestHasKey(t *testing.T) {
t.Parallel()
is := assert.New(t)
r1 := HasKey(map[string]int{"foo": 1}, "bar")
is.False(r1)
r2 := HasKey(map[string]int{"foo": 1}, "foo")
is.True(r2)
}
func TestValues(t *testing.T) {
t.Parallel()
is := assert.New(t)
r1 := Values(map[string]int{"foo": 1, "bar": 2})
sort.Ints(r1)
is.Equal(r1, []int{1, 2})
r2 := Values(map[string]int{})
is.Empty(r2)
r3 := Values(map[string]int{"foo": 1, "bar": 2}, map[string]int{"baz": 3})
sort.Ints(r3)
is.Equal(r3, []int{1, 2, 3})
r4 := Values[string, int]()
is.Equal(r4, []int{})
r5 := Values(map[string]int{"foo": 1, "bar": 2}, map[string]int{"foo": 1, "bar": 3})
sort.Ints(r5)
is.Equal(r5, []int{1, 1, 2, 3})
}
func TestUniqValues(t *testing.T) {
t.Parallel()
is := assert.New(t)
r1 := UniqValues(map[string]int{"foo": 1, "bar": 2})
sort.Ints(r1)
is.Equal(r1, []int{1, 2})
r2 := UniqValues(map[string]int{})
is.Empty(r2)
r3 := UniqValues(map[string]int{"foo": 1, "bar": 2}, map[string]int{"baz": 3})
sort.Ints(r3)
is.Equal(r3, []int{1, 2, 3})
r4 := UniqValues[string, int]()
is.Equal(r4, []int{})
r5 := UniqValues(map[string]int{"foo": 1, "bar": 2}, map[string]int{"foo": 1, "bar": 3})
sort.Ints(r5)
is.Equal(r5, []int{1, 2, 3})
r6 := UniqValues(map[string]int{"foo": 1, "bar": 1}, map[string]int{"foo": 1, "bar": 3})
sort.Ints(r6)
is.Equal(r6, []int{1, 3})
// check order
r7 := UniqValues(map[string]int{"foo": 1}, map[string]int{"bar": 3})
is.Equal(r7, []int{1, 3})
}
func TestValueOr(t *testing.T) {
t.Parallel()
is := assert.New(t)
r1 := ValueOr(map[string]int{"foo": 1}, "bar", 2)
is.Equal(r1, 2)
r2 := ValueOr(map[string]int{"foo": 1}, "foo", 2)
is.Equal(r2, 1)
}
func TestPickBy(t *testing.T) {
t.Parallel()
is := assert.New(t)
r1 := PickBy(map[string]int{"foo": 1, "bar": 2, "baz": 3}, func(key string, value int) bool {
return value%2 == 1
})
is.Equal(r1, map[string]int{"foo": 1, "baz": 3})
type myMap map[string]int
before := myMap{"": 0, "foobar": 6, "baz": 3}
after := PickBy(before, func(key string, value int) bool { return true })
is.IsType(after, before, "type preserved")
}
func TestPickByKeys(t *testing.T) {
t.Parallel()
is := assert.New(t)
r1 := PickByKeys(map[string]int{"foo": 1, "bar": 2, "baz": 3}, []string{"foo", "baz", "qux"})
is.Equal(r1, map[string]int{"foo": 1, "baz": 3})
type myMap map[string]int
before := myMap{"": 0, "foobar": 6, "baz": 3}
after := PickByKeys(before, []string{"foobar", "baz"})
is.IsType(after, before, "type preserved")
}
func TestPickByValues(t *testing.T) {
t.Parallel()
is := assert.New(t)
r1 := PickByValues(map[string]int{"foo": 1, "bar": 2, "baz": 3}, []int{1, 3})
is.Equal(r1, map[string]int{"foo": 1, "baz": 3})
type myMap map[string]int
before := myMap{"": 0, "foobar": 6, "baz": 3}
after := PickByValues(before, []int{0, 3})
is.IsType(after, before, "type preserved")
}
func TestOmitBy(t *testing.T) {
t.Parallel()
is := assert.New(t)
r1 := OmitBy(map[string]int{"foo": 1, "bar": 2, "baz": 3}, func(key string, value int) bool {
return value%2 == 1
})
is.Equal(r1, map[string]int{"bar": 2})
type myMap map[string]int
before := myMap{"": 0, "foobar": 6, "baz": 3}
after := PickBy(before, func(key string, value int) bool { return true })
is.IsType(after, before, "type preserved")
}
func TestOmitByKeys(t *testing.T) {
t.Parallel()
is := assert.New(t)
r1 := OmitByKeys(map[string]int{"foo": 1, "bar": 2, "baz": 3}, []string{"foo", "baz", "qux"})
is.Equal(r1, map[string]int{"bar": 2})
type myMap map[string]int
before := myMap{"": 0, "foobar": 6, "baz": 3}
after := OmitByKeys(before, []string{"foobar", "baz"})
is.IsType(after, before, "type preserved")
}
func TestOmitByValues(t *testing.T) {
t.Parallel()
is := assert.New(t)
r1 := OmitByValues(map[string]int{"foo": 1, "bar": 2, "baz": 3}, []int{1, 3})
is.Equal(r1, map[string]int{"bar": 2})
type myMap map[string]int
before := myMap{"": 0, "foobar": 6, "baz": 3}
after := OmitByValues(before, []int{0, 3})
is.IsType(after, before, "type preserved")
}
func TestEntries(t *testing.T) {
t.Parallel()
is := assert.New(t)
r1 := Entries(map[string]int{"foo": 1, "bar": 2})
sort.Slice(r1, func(i, j int) bool {
return r1[i].Value < r1[j].Value
})
is.EqualValues(r1, []Entry[string, int]{
{
Key: "foo",
Value: 1,
},
{
Key: "bar",
Value: 2,
},
})
}
func TestToPairs(t *testing.T) {
t.Parallel()
is := assert.New(t)
r1 := ToPairs(map[string]int{"baz": 3, "qux": 4})
sort.Slice(r1, func(i, j int) bool {
return r1[i].Value < r1[j].Value
})
is.EqualValues(r1, []Entry[string, int]{
{
Key: "baz",
Value: 3,
},
{
Key: "qux",
Value: 4,
},
})
}
func TestFromEntries(t *testing.T) {
t.Parallel()
is := assert.New(t)
r1 := FromEntries([]Entry[string, int]{
{
Key: "foo",
Value: 1,
},
{
Key: "bar",
Value: 2,
},
})
is.Len(r1, 2)
is.Equal(r1["foo"], 1)
is.Equal(r1["bar"], 2)
}
func TestFromPairs(t *testing.T) {
t.Parallel()
is := assert.New(t)
r1 := FromPairs([]Entry[string, int]{
{
Key: "baz",
Value: 3,
},
{
Key: "qux",
Value: 4,
},
})
is.Len(r1, 2)
is.Equal(r1["baz"], 3)
is.Equal(r1["qux"], 4)
}
func TestInvert(t *testing.T) {
t.Parallel()
is := assert.New(t)
r1 := Invert(map[string]int{"a": 1, "b": 2})
r2 := Invert(map[string]int{"a": 1, "b": 2, "c": 1})
is.Len(r1, 2)
is.EqualValues(map[int]string{1: "a", 2: "b"}, r1)
is.Len(r2, 2)
}
func TestAssign(t *testing.T) {
t.Parallel()
is := assert.New(t)
result1 := Assign(map[string]int{"a": 1, "b": 2}, map[string]int{"b": 3, "c": 4})
is.Len(result1, 3)
is.Equal(result1, map[string]int{"a": 1, "b": 3, "c": 4})
type myMap map[string]int
before := myMap{"": 0, "foobar": 6, "baz": 3}
after := Assign(before, before)
is.IsType(after, before, "type preserved")
}
func TestChunkEntries(t *testing.T) {
t.Parallel()
is := assert.New(t)
result1 := ChunkEntries(map[string]int{"a": 1, "b": 2, "c": 3, "d": 4, "e": 5}, 2)
result2 := ChunkEntries(map[string]int{"a": 1, "b": 2, "c": 3, "d": 4, "e": 5}, 3)
result3 := ChunkEntries(map[string]int{}, 2)
result4 := ChunkEntries(map[string]int{"a": 1}, 2)
result5 := ChunkEntries(map[string]int{"a": 1, "b": 2}, 1)
expectedCount1 := 3
expectedCount2 := 2
expectedCount3 := 0
expectedCount4 := 1
expectedCount5 := 2
is.Len(result1, expectedCount1)
is.Len(result2, expectedCount2)
is.Len(result3, expectedCount3)
is.Len(result4, expectedCount4)
is.Len(result5, expectedCount5)
is.PanicsWithValue("The chunk size must be greater than 0", func() {
ChunkEntries(map[string]int{"a": 1}, 0)
})
is.PanicsWithValue("The chunk size must be greater than 0", func() {
ChunkEntries(map[string]int{"a": 1}, -1)
})
type myStruct struct {
Name string
Value int
}
allStructs := []myStruct{{"one", 1}, {"two", 2}, {"three", 3}}
nonempty := ChunkEntries(map[string]myStruct{"a": allStructs[0], "b": allStructs[1], "c": allStructs[2]}, 2)
is.Len(nonempty, 2)
originalMap := map[string]int{"a": 1, "b": 2, "c": 3, "d": 4, "e": 5}
result6 := ChunkEntries(originalMap, 2)
for k := range result6[0] {
result6[0][k] = 10
}
is.Equal(originalMap, map[string]int{"a": 1, "b": 2, "c": 3, "d": 4, "e": 5})
}
func TestMapKeys(t *testing.T) {
t.Parallel()
is := assert.New(t)
result1 := MapKeys(map[int]int{1: 1, 2: 2, 3: 3, 4: 4}, func(x int, _ int) string {
return "Hello"
})
result2 := MapKeys(map[int]int{1: 1, 2: 2, 3: 3, 4: 4}, func(_ int, v int) string {
return strconv.FormatInt(int64(v), 10)
})
is.Equal(len(result1), 1)
is.Equal(len(result2), 4)
is.Equal(result2, map[string]int{"1": 1, "2": 2, "3": 3, "4": 4})
}
func TestMapValues(t *testing.T) {
t.Parallel()
is := assert.New(t)
result1 := MapValues(map[int]int{1: 1, 2: 2, 3: 3, 4: 4}, func(x int, _ int) string {
return "Hello"
})
result2 := MapValues(map[int]int{1: 1, 2: 2, 3: 3, 4: 4}, func(x int, _ int) string {
return strconv.FormatInt(int64(x), 10)
})
is.Equal(len(result1), 4)
is.Equal(len(result2), 4)
is.Equal(result1, map[int]string{1: "Hello", 2: "Hello", 3: "Hello", 4: "Hello"})
is.Equal(result2, map[int]string{1: "1", 2: "2", 3: "3", 4: "4"})
}
func mapEntriesTest[I any, O any](t *testing.T, in map[string]I, iteratee func(string, I) (string, O), expected map[string]O) {
is := assert.New(t)
result := MapEntries(in, iteratee)
is.Equal(result, expected)
}
func TestMapEntries(t *testing.T) {
mapEntriesTest(t, map[string]int{"foo": 1, "bar": 2}, func(k string, v int) (string, int) {
return k, v + 1
}, map[string]int{"foo": 2, "bar": 3})
mapEntriesTest(t, map[string]int{"foo": 1, "bar": 2}, func(k string, v int) (string, string) {
return k, k + strconv.Itoa(v)
}, map[string]string{"foo": "foo1", "bar": "bar2"})
mapEntriesTest(t, map[string]int{"foo": 1, "bar": 2}, func(k string, v int) (string, string) {
return k, strconv.Itoa(v) + k
}, map[string]string{"foo": "1foo", "bar": "2bar"})
// NoMutation
{
is := assert.New(t)
r1 := map[string]int{"foo": 1, "bar": 2}
MapEntries(r1, func(k string, v int) (string, string) {
return k, strconv.Itoa(v) + "!!"
})
is.Equal(r1, map[string]int{"foo": 1, "bar": 2})
}
// EmptyInput
{
mapEntriesTest(t, map[string]int{}, func(k string, v int) (string, string) {
return k, strconv.Itoa(v) + "!!"
}, map[string]string{})
mapEntriesTest(t, map[string]any{}, func(k string, v any) (string, any) {
return k, v
}, map[string]any{})
}
// Identity
{
mapEntriesTest(t, map[string]int{"foo": 1, "bar": 2}, func(k string, v int) (string, int) {
return k, v
}, map[string]int{"foo": 1, "bar": 2})
mapEntriesTest(t, map[string]any{"foo": 1, "bar": "2", "ccc": true}, func(k string, v any) (string, any) {
return k, v
}, map[string]any{"foo": 1, "bar": "2", "ccc": true})
}
// ToConstantEntry
{
mapEntriesTest(t, map[string]any{"foo": 1, "bar": "2", "ccc": true}, func(k string, v any) (string, any) {
return "key", "value"
}, map[string]any{"key": "value"})
mapEntriesTest(t, map[string]any{"foo": 1, "bar": "2", "ccc": true}, func(k string, v any) (string, any) {
return "b", 5
}, map[string]any{"b": 5})
}
//// OverlappingKeys
//// because using range over map, the order is not guaranteed
//// this test is not deterministic
//{
// mapEntriesTest(t, map[string]any{"foo": 1, "foo2": 2, "Foo": 2, "Foo2": "2", "bar": "2", "ccc": true}, func(k string, v any) (string, any) {
// return string(k[0]), v
// }, map[string]any{"F": "2", "b": "2", "c": true, "f": 2})
// mapEntriesTest(t, map[string]string{"foo": "1", "foo2": "2", "Foo": "2", "Foo2": "2", "bar": "2", "ccc": "true"}, func(k string, v string) (string, string) {
// return v, k
// }, map[string]string{"1": "foo", "2": "bar", "true": "ccc"})
//}
//NormalMappers
{
mapEntriesTest(t, map[string]string{"foo": "1", "foo2": "2", "Foo": "2", "Foo2": "2", "bar": "2", "ccc": "true"}, func(k string, v string) (string, string) {
return k, k + v
}, map[string]string{"Foo": "Foo2", "Foo2": "Foo22", "bar": "bar2", "ccc": "ccctrue", "foo": "foo1", "foo2": "foo22"})
mapEntriesTest(t, map[string]struct {
name string
age int
}{"1-11-1": {name: "foo", age: 1}, "2-22-2": {name: "bar", age: 2}}, func(k string, v struct {
name string
age int
},
) (string, string) {
return v.name, k
}, map[string]string{"bar": "2-22-2", "foo": "1-11-1"})
}
}
func TestMapToSlice(t *testing.T) {
t.Parallel()
is := assert.New(t)
result1 := MapToSlice(map[int]int{1: 5, 2: 6, 3: 7, 4: 8}, func(k int, v int) string {
return fmt.Sprintf("%d_%d", k, v)
})
result2 := MapToSlice(map[int]int{1: 5, 2: 6, 3: 7, 4: 8}, func(k int, _ int) string {
return strconv.FormatInt(int64(k), 10)
})
is.Equal(len(result1), 4)
is.Equal(len(result2), 4)
is.ElementsMatch(result1, []string{"1_5", "2_6", "3_7", "4_8"})
is.ElementsMatch(result2, []string{"1", "2", "3", "4"})
}
func TestFilterMapToSlice(t *testing.T) {
t.Parallel()
is := assert.New(t)
result1 := FilterMapToSlice(map[int]int{1: 5, 2: 6, 3: 7, 4: 8}, func(k int, v int) (string, bool) {
return fmt.Sprintf("%d_%d", k, v), k%2 == 0
})
result2 := FilterMapToSlice(map[int]int{1: 5, 2: 6, 3: 7, 4: 8}, func(k int, _ int) (string, bool) {
return strconv.FormatInt(int64(k), 10), k%2 == 0
})
is.Equal(len(result1), 2)
is.Equal(len(result2), 2)
is.ElementsMatch(result1, []string{"2_6", "4_8"})
is.ElementsMatch(result2, []string{"2", "4"})
}
func BenchmarkAssign(b *testing.B) {
counts := []int{32768, 1024, 128, 32, 2}
allDifferentMap := func(b *testing.B, n int) []map[string]int {
defer b.ResetTimer()
m := make([]map[string]int, 0)
for i := 0; i < n; i++ {
m = append(m, map[string]int{
strconv.Itoa(i): i,
strconv.Itoa(i): i,
strconv.Itoa(i): i,
strconv.Itoa(i): i,
strconv.Itoa(i): i,
strconv.Itoa(i): i,
},
)
}
return m
}
allTheSameMap := func(b *testing.B, n int) []map[string]int {
defer b.ResetTimer()
m := make([]map[string]int, 0)
for i := 0; i < n; i++ {
m = append(m, map[string]int{
"a": 1,
"b": 2,
"c": 3,
"d": 4,
"e": 5,
"f": 6,
},
)
}
return m
}
for _, count := range counts {
differentMap := allDifferentMap(b, count)
sameMap := allTheSameMap(b, count)
b.Run(fmt.Sprintf("%d", count), func(b *testing.B) {
testcase := []struct {
name string
maps []map[string]int
}{
{"different", differentMap},
{"same", sameMap},
}
for _, tc := range testcase {
b.Run(tc.name, func(b *testing.B) {
b.ResetTimer()
for n := 0; n < b.N; n++ {
result := Assign(tc.maps...)
_ = result
}
})
}
})
}
}

View File

@@ -1,108 +0,0 @@
package lo
import (
"fmt"
)
func ExampleRange() {
result1 := Range(4)
result2 := Range(-4)
result3 := RangeFrom(1, 5)
result4 := RangeFrom(1.0, 5)
result5 := RangeWithSteps(0, 20, 5)
result6 := RangeWithSteps[float32](-1.0, -4.0, -1.0)
result7 := RangeWithSteps(1, 4, -1)
result8 := Range(0)
fmt.Printf("%v\n", result1)
fmt.Printf("%v\n", result2)
fmt.Printf("%v\n", result3)
fmt.Printf("%v\n", result4)
fmt.Printf("%v\n", result5)
fmt.Printf("%v\n", result6)
fmt.Printf("%v\n", result7)
fmt.Printf("%v\n", result8)
// Output:
// [0 1 2 3]
// [0 -1 -2 -3]
// [1 2 3 4 5]
// [1 2 3 4 5]
// [0 5 10 15]
// [-1 -2 -3]
// []
// []
}
func ExampleClamp() {
result1 := Clamp(0, -10, 10)
result2 := Clamp(-42, -10, 10)
result3 := Clamp(42, -10, 10)
fmt.Printf("%v\n", result1)
fmt.Printf("%v\n", result2)
fmt.Printf("%v\n", result3)
// Output:
// 0
// -10
// 10
}
func ExampleSum() {
list := []int{1, 2, 3, 4, 5}
sum := Sum(list)
fmt.Printf("%v", sum)
// Output: 15
}
func ExampleSumBy() {
list := []string{"foo", "bar"}
result := SumBy(list, func(item string) int {
return len(item)
})
fmt.Printf("%v", result)
// Output: 6
}
func ExampleProduct() {
list := []int{1, 2, 3, 4, 5}
result := Product(list)
fmt.Printf("%v", result)
// Output: 120
}
func ExampleProductBy() {
list := []string{"foo", "bar"}
result := ProductBy(list, func(item string) int {
return len(item)
})
fmt.Printf("%v", result)
// Output: 9
}
func ExampleMean() {
list := []int{1, 2, 3, 4, 5}
result := Mean(list)
fmt.Printf("%v", result)
// Output: 3
}
func ExampleMeanBy() {
list := []string{"foo", "bar"}
result := MeanBy(list, func(item string) int {
return len(item)
})
fmt.Printf("%v", result)
// Output: 3
}

View File

@@ -1,173 +0,0 @@
package lo
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestRange(t *testing.T) {
t.Parallel()
is := assert.New(t)
result1 := Range(4)
result2 := Range(-4)
result3 := Range(0)
is.Equal(result1, []int{0, 1, 2, 3})
is.Equal(result2, []int{0, -1, -2, -3})
is.Equal(result3, []int{})
}
func TestRangeFrom(t *testing.T) {
t.Parallel()
is := assert.New(t)
result1 := RangeFrom(1, 5)
result2 := RangeFrom(-1, -5)
result3 := RangeFrom(10, 0)
result4 := RangeFrom(2.0, 3)
result5 := RangeFrom(-2.0, -3)
is.Equal(result1, []int{1, 2, 3, 4, 5})
is.Equal(result2, []int{-1, -2, -3, -4, -5})
is.Equal(result3, []int{})
is.Equal(result4, []float64{2.0, 3.0, 4.0})
is.Equal(result5, []float64{-2.0, -3.0, -4.0})
}
func TestRangeClose(t *testing.T) {
t.Parallel()
is := assert.New(t)
result1 := RangeWithSteps(0, 20, 6)
result2 := RangeWithSteps(0, 3, -5)
result3 := RangeWithSteps(1, 1, 0)
result4 := RangeWithSteps(3, 2, 1)
result5 := RangeWithSteps(1.0, 4.0, 2.0)
result6 := RangeWithSteps[float32](-1.0, -4.0, -1.0)
is.Equal([]int{0, 6, 12, 18}, result1)
is.Equal([]int{}, result2)
is.Equal([]int{}, result3)
is.Equal([]int{}, result4)
is.Equal([]float64{1.0, 3.0}, result5)
is.Equal([]float32{-1.0, -2.0, -3.0}, result6)
}
func TestClamp(t *testing.T) {
t.Parallel()
is := assert.New(t)
result1 := Clamp(0, -10, 10)
result2 := Clamp(-42, -10, 10)
result3 := Clamp(42, -10, 10)
is.Equal(result1, 0)
is.Equal(result2, -10)
is.Equal(result3, 10)
}
func TestSum(t *testing.T) {
is := assert.New(t)
result1 := Sum([]float32{2.3, 3.3, 4, 5.3})
result2 := Sum([]int32{2, 3, 4, 5})
result3 := Sum([]uint32{2, 3, 4, 5})
result4 := Sum([]uint32{})
result5 := Sum([]complex128{4_4, 2_2})
is.Equal(result1, float32(14.900001))
is.Equal(result2, int32(14))
is.Equal(result3, uint32(14))
is.Equal(result4, uint32(0))
is.Equal(result5, complex128(6_6))
}
func TestSumBy(t *testing.T) {
t.Parallel()
is := assert.New(t)
result1 := SumBy([]float32{2.3, 3.3, 4, 5.3}, func(n float32) float32 { return n })
result2 := SumBy([]int32{2, 3, 4, 5}, func(n int32) int32 { return n })
result3 := SumBy([]uint32{2, 3, 4, 5}, func(n uint32) uint32 { return n })
result4 := SumBy([]uint32{}, func(n uint32) uint32 { return n })
result5 := SumBy([]complex128{4_4, 2_2}, func(n complex128) complex128 { return n })
is.Equal(result1, float32(14.900001))
is.Equal(result2, int32(14))
is.Equal(result3, uint32(14))
is.Equal(result4, uint32(0))
is.Equal(result5, complex128(6_6))
}
func TestProduct(t *testing.T) {
is := assert.New(t)
result1 := Product([]float32{2.3, 3.3, 4, 5.3})
result2 := Product([]int32{2, 3, 4, 5})
result3 := Product([]int32{7, 8, 9, 0})
result4 := Product([]int32{7, -1, 9, 2})
result5 := Product([]uint32{2, 3, 4, 5})
result6 := Product([]uint32{})
result7 := Product([]complex128{4_4, 2_2})
result8 := Product[uint32](nil)
is.Equal(result1, float32(160.908))
is.Equal(result2, int32(120))
is.Equal(result3, int32(0))
is.Equal(result4, int32(-126))
is.Equal(result5, uint32(120))
is.Equal(result6, uint32(1))
is.Equal(result7, complex128(96_8))
is.Equal(result8, uint32(1))
}
func TestProductBy(t *testing.T) {
is := assert.New(t)
result1 := ProductBy([]float32{2.3, 3.3, 4, 5.3}, func(n float32) float32 { return n })
result2 := ProductBy([]int32{2, 3, 4, 5}, func(n int32) int32 { return n })
result3 := ProductBy([]int32{7, 8, 9, 0}, func(n int32) int32 { return n })
result4 := ProductBy([]int32{7, -1, 9, 2}, func(n int32) int32 { return n })
result5 := ProductBy([]uint32{2, 3, 4, 5}, func(n uint32) uint32 { return n })
result6 := ProductBy([]uint32{}, func(n uint32) uint32 { return n })
result7 := ProductBy([]complex128{4_4, 2_2}, func(n complex128) complex128 { return n })
result8 := ProductBy(nil, func(n uint32) uint32 { return n })
is.Equal(result1, float32(160.908))
is.Equal(result2, int32(120))
is.Equal(result3, int32(0))
is.Equal(result4, int32(-126))
is.Equal(result5, uint32(120))
is.Equal(result6, uint32(1))
is.Equal(result7, complex128(96_8))
is.Equal(result8, uint32(1))
}
func TestMean(t *testing.T) {
t.Parallel()
is := assert.New(t)
result1 := Mean([]float32{2.3, 3.3, 4, 5.3})
result2 := Mean([]int32{2, 3, 4, 5})
result3 := Mean([]uint32{2, 3, 4, 5})
result4 := Mean([]uint32{})
is.Equal(result1, float32(3.7250001))
is.Equal(result2, int32(3))
is.Equal(result3, uint32(3))
is.Equal(result4, uint32(0))
}
func TestMeanBy(t *testing.T) {
t.Parallel()
is := assert.New(t)
result1 := MeanBy([]float32{2.3, 3.3, 4, 5.3}, func(n float32) float32 { return n })
result2 := MeanBy([]int32{2, 3, 4, 5}, func(n int32) int32 { return n })
result3 := MeanBy([]uint32{2, 3, 4, 5}, func(n uint32) uint32 { return n })
result4 := MeanBy([]uint32{}, func(n uint32) uint32 { return n })
is.Equal(result1, float32(3.7250001))
is.Equal(result2, int32(3))
is.Equal(result3, uint32(3))
is.Equal(result4, uint32(0))
}

View File

@@ -1,114 +0,0 @@
package parallel
import (
"sort"
"strconv"
"sync/atomic"
"testing"
"github.com/stretchr/testify/assert"
)
func TestMap(t *testing.T) {
is := assert.New(t)
result1 := Map([]int{1, 2, 3, 4}, func(x int, _ int) string {
return "Hello"
})
result2 := Map([]int64{1, 2, 3, 4}, func(x int64, _ int) string {
return strconv.FormatInt(x, 10)
})
is.Equal(len(result1), 4)
is.Equal(len(result2), 4)
is.Equal(result1, []string{"Hello", "Hello", "Hello", "Hello"})
is.Equal(result2, []string{"1", "2", "3", "4"})
}
func TestForEach(t *testing.T) {
is := assert.New(t)
var counter uint64
collection := []int{1, 2, 3, 4}
ForEach(collection, func(x int, i int) {
atomic.AddUint64(&counter, 1)
})
is.Equal(uint64(4), atomic.LoadUint64(&counter))
}
func TestTimes(t *testing.T) {
is := assert.New(t)
result1 := Times(3, func(i int) string {
return strconv.FormatInt(int64(i), 10)
})
is.Equal(len(result1), 3)
is.Equal(result1, []string{"0", "1", "2"})
}
func TestGroupBy(t *testing.T) {
is := assert.New(t)
result1 := GroupBy([]int{0, 1, 2, 3, 4, 5}, func(i int) int {
return i % 3
})
// order
for x := range result1 {
sort.Slice(result1[x], func(i, j int) bool {
return result1[x][i] < result1[x][j]
})
}
is.EqualValues(len(result1), 3)
is.EqualValues(result1, map[int][]int{
0: {0, 3},
1: {1, 4},
2: {2, 5},
})
type myStrings []string
allStrings := myStrings{"", "foo", "bar"}
nonempty := GroupBy(allStrings, func(i string) int {
return 42
})
is.IsType(nonempty[42], allStrings, "type preserved")
}
func TestPartitionBy(t *testing.T) {
is := assert.New(t)
oddEven := func(x int) string {
if x < 0 {
return "negative"
} else if x%2 == 0 {
return "even"
}
return "odd"
}
result1 := PartitionBy([]int{-2, -1, 0, 1, 2, 3, 4, 5}, oddEven)
result2 := PartitionBy([]int{}, oddEven)
// order
sort.Slice(result1, func(i, j int) bool {
return result1[i][0] < result1[j][0]
})
for x := range result1 {
sort.Slice(result1[x], func(i, j int) bool {
return result1[x][i] < result1[x][j]
})
}
is.ElementsMatch(result1, [][]int{{-2, -1}, {0, 2, 4}, {1, 3, 5}})
is.Equal(result2, [][]int{})
type myStrings []string
allStrings := myStrings{"", "foo", "bar"}
nonempty := PartitionBy(allStrings, func(item string) int {
return len(item)
})
is.IsType(nonempty[0], allStrings, "type preserved")
}

View File

@@ -1,340 +0,0 @@
//go:build !race
// +build !race
package lo
import (
"fmt"
"sync"
"sync/atomic"
"time"
)
func ExampleNewDebounce() {
i := int32(0)
calls := []int32{}
mu := sync.Mutex{}
debounce, cancel := NewDebounce(time.Millisecond, func() {
mu.Lock()
defer mu.Unlock()
calls = append(calls, atomic.LoadInt32(&i))
})
debounce()
atomic.AddInt32(&i, 1)
time.Sleep(5 * time.Millisecond)
debounce()
atomic.AddInt32(&i, 1)
debounce()
atomic.AddInt32(&i, 1)
debounce()
atomic.AddInt32(&i, 1)
time.Sleep(5 * time.Millisecond)
cancel()
mu.Lock()
fmt.Printf("%v", calls)
mu.Unlock()
// Output: [1 4]
}
func ExampleNewDebounceBy() {
calls := map[string][]int{}
mu := sync.Mutex{}
debounce, cancel := NewDebounceBy(time.Millisecond, func(userID string, count int) {
mu.Lock()
defer mu.Unlock()
if _, ok := calls[userID]; !ok {
calls[userID] = []int{}
}
calls[userID] = append(calls[userID], count)
})
debounce("samuel")
debounce("john")
time.Sleep(5 * time.Millisecond)
debounce("john")
debounce("john")
debounce("samuel")
debounce("john")
time.Sleep(5 * time.Millisecond)
cancel("samuel")
cancel("john")
mu.Lock()
fmt.Printf("samuel: %v\n", calls["samuel"])
fmt.Printf("john: %v\n", calls["john"])
mu.Unlock()
// Output:
// samuel: [1 1]
// john: [1 3]
}
func ExampleAttempt() {
count1, err1 := Attempt(2, func(i int) error {
if i == 0 {
return fmt.Errorf("error")
}
return nil
})
count2, err2 := Attempt(2, func(i int) error {
if i < 10 {
return fmt.Errorf("error")
}
return nil
})
fmt.Printf("%v %v\n", count1, err1)
fmt.Printf("%v %v\n", count2, err2)
// Output:
// 2 <nil>
// 2 error
}
func ExampleAttemptWithDelay() {
count1, time1, err1 := AttemptWithDelay(2, time.Millisecond, func(i int, _ time.Duration) error {
if i == 0 {
return fmt.Errorf("error")
}
return nil
})
count2, time2, err2 := AttemptWithDelay(2, time.Millisecond, func(i int, _ time.Duration) error {
if i < 10 {
return fmt.Errorf("error")
}
return nil
})
fmt.Printf("%v %v %v\n", count1, time1.Truncate(time.Millisecond), err1)
fmt.Printf("%v %v %v\n", count2, time2.Truncate(time.Millisecond), err2)
// Output:
// 2 1ms <nil>
// 2 1ms error
}
func ExampleTransaction() {
transaction := NewTransaction[int]().
Then(
func(state int) (int, error) {
fmt.Println("step 1")
return state + 10, nil
},
func(state int) int {
fmt.Println("rollback 1")
return state - 10
},
).
Then(
func(state int) (int, error) {
fmt.Println("step 2")
return state + 15, nil
},
func(state int) int {
fmt.Println("rollback 2")
return state - 15
},
).
Then(
func(state int) (int, error) {
fmt.Println("step 3")
if true {
return state, fmt.Errorf("error")
}
return state + 42, nil
},
func(state int) int {
fmt.Println("rollback 3")
return state - 42
},
)
_, _ = transaction.Process(-5)
// Output:
// step 1
// step 2
// step 3
// rollback 2
// rollback 1
}
func ExampleTransaction_ok() {
transaction := NewTransaction[int]().
Then(
func(state int) (int, error) {
return state + 10, nil
},
func(state int) int {
return state - 10
},
).
Then(
func(state int) (int, error) {
return state + 15, nil
},
func(state int) int {
return state - 15
},
).
Then(
func(state int) (int, error) {
return state + 42, nil
},
func(state int) int {
return state - 42
},
)
state, err := transaction.Process(-5)
fmt.Println(state)
fmt.Println(err)
// Output:
// 62
// <nil>
}
func ExampleTransaction_error() {
transaction := NewTransaction[int]().
Then(
func(state int) (int, error) {
return state + 10, nil
},
func(state int) int {
return state - 10
},
).
Then(
func(state int) (int, error) {
return state, fmt.Errorf("error")
},
func(state int) int {
return state - 15
},
).
Then(
func(state int) (int, error) {
return state + 42, nil
},
func(state int) int {
return state - 42
},
)
state, err := transaction.Process(-5)
fmt.Println(state)
fmt.Println(err)
// Output:
// -5
// error
}
func ExampleNewThrottle() {
throttle, reset := NewThrottle(100*time.Millisecond, func() {
fmt.Println("Called once in every 100ms")
})
for j := 0; j < 10; j++ {
throttle()
time.Sleep(30 * time.Millisecond)
}
reset()
// Output:
// Called once in every 100ms
// Called once in every 100ms
// Called once in every 100ms
}
func ExampleNewThrottleWithCount() {
throttle, reset := NewThrottleWithCount(100*time.Millisecond, 2, func() {
fmt.Println("Called once in every 100ms")
})
for j := 0; j < 10; j++ {
throttle()
time.Sleep(30 * time.Millisecond)
}
reset()
// Output:
// Called once in every 100ms
// Called once in every 100ms
// Called once in every 100ms
// Called once in every 100ms
// Called once in every 100ms
// Called once in every 100ms
}
func ExampleNewThrottleBy() {
throttle, reset := NewThrottleBy(100*time.Millisecond, func(key string) {
fmt.Println(key, "Called once in every 100ms")
})
for j := 0; j < 10; j++ {
throttle("foo")
throttle("bar")
time.Sleep(30 * time.Millisecond)
}
reset()
// Output:
// foo Called once in every 100ms
// bar Called once in every 100ms
// foo Called once in every 100ms
// bar Called once in every 100ms
// foo Called once in every 100ms
// bar Called once in every 100ms
}
func ExampleNewThrottleByWithCount() {
throttle, reset := NewThrottleByWithCount(100*time.Millisecond, 2, func(key string) {
fmt.Println(key, "Called once in every 100ms")
})
for j := 0; j < 10; j++ {
throttle("foo")
throttle("bar")
time.Sleep(30 * time.Millisecond)
}
reset()
// Output:
// foo Called once in every 100ms
// bar Called once in every 100ms
// foo Called once in every 100ms
// bar Called once in every 100ms
// foo Called once in every 100ms
// bar Called once in every 100ms
// foo Called once in every 100ms
// bar Called once in every 100ms
// foo Called once in every 100ms
// bar Called once in every 100ms
// foo Called once in every 100ms
// bar Called once in every 100ms
}

View File

@@ -1,643 +0,0 @@
package lo
import (
"fmt"
"sync"
"testing"
"time"
"github.com/stretchr/testify/assert"
)
func TestAttempt(t *testing.T) {
t.Parallel()
is := assert.New(t)
err := fmt.Errorf("failed")
iter1, err1 := Attempt(42, func(i int) error {
return nil
})
iter2, err2 := Attempt(42, func(i int) error {
if i == 5 {
return nil
}
return err
})
iter3, err3 := Attempt(2, func(i int) error {
if i == 5 {
return nil
}
return err
})
iter4, err4 := Attempt(0, func(i int) error {
if i < 42 {
return err
}
return nil
})
is.Equal(iter1, 1)
is.Equal(err1, nil)
is.Equal(iter2, 6)
is.Equal(err2, nil)
is.Equal(iter3, 2)
is.Equal(err3, err)
is.Equal(iter4, 43)
is.Equal(err4, nil)
}
func TestAttemptWithDelay(t *testing.T) {
t.Parallel()
is := assert.New(t)
err := fmt.Errorf("failed")
iter1, dur1, err1 := AttemptWithDelay(42, 10*time.Millisecond, func(i int, d time.Duration) error {
return nil
})
iter2, dur2, err2 := AttemptWithDelay(42, 10*time.Millisecond, func(i int, d time.Duration) error {
if i == 5 {
return nil
}
return err
})
iter3, dur3, err3 := AttemptWithDelay(2, 10*time.Millisecond, func(i int, d time.Duration) error {
if i == 5 {
return nil
}
return err
})
iter4, dur4, err4 := AttemptWithDelay(0, 10*time.Millisecond, func(i int, d time.Duration) error {
if i < 10 {
return err
}
return nil
})
is.Equal(iter1, 1)
is.GreaterOrEqual(dur1, 0*time.Millisecond)
is.Less(dur1, 1*time.Millisecond)
is.Equal(err1, nil)
is.Equal(iter2, 6)
is.Greater(dur2, 50*time.Millisecond)
is.Less(dur2, 60*time.Millisecond)
is.Equal(err2, nil)
is.Equal(iter3, 2)
is.Greater(dur3, 10*time.Millisecond)
is.Less(dur3, 20*time.Millisecond)
is.Equal(err3, err)
is.Equal(iter4, 11)
is.Greater(dur4, 100*time.Millisecond)
is.Less(dur4, 115*time.Millisecond)
is.Equal(err4, nil)
}
func TestAttemptWhile(t *testing.T) {
is := assert.New(t)
err := fmt.Errorf("failed")
iter1, err1 := AttemptWhile(42, func(i int) (error, bool) {
return nil, true
})
is.Equal(iter1, 1)
is.Nil(err1)
iter2, err2 := AttemptWhile(42, func(i int) (error, bool) {
if i == 5 {
return nil, true
}
return err, true
})
is.Equal(iter2, 6)
is.Nil(err2)
iter3, err3 := AttemptWhile(2, func(i int) (error, bool) {
if i == 5 {
return nil, true
}
return err, true
})
is.Equal(iter3, 2)
is.Equal(err3, err)
iter4, err4 := AttemptWhile(0, func(i int) (error, bool) {
if i < 42 {
return err, true
}
return nil, true
})
is.Equal(iter4, 43)
is.Nil(err4)
iter5, err5 := AttemptWhile(0, func(i int) (error, bool) {
if i == 5 {
return nil, false
}
return err, true
})
is.Equal(iter5, 6)
is.Nil(err5)
iter6, err6 := AttemptWhile(0, func(i int) (error, bool) {
return nil, false
})
is.Equal(iter6, 1)
is.Nil(err6)
iter7, err7 := AttemptWhile(42, func(i int) (error, bool) {
if i == 42 {
return nil, false
}
if i < 41 {
return err, true
}
return nil, true
})
is.Equal(iter7, 42)
is.Nil(err7)
}
func TestAttemptWhileWithDelay(t *testing.T) {
is := assert.New(t)
err := fmt.Errorf("failed")
iter1, dur1, err1 := AttemptWhileWithDelay(42, 10*time.Millisecond, func(i int, d time.Duration) (error, bool) {
return nil, true
})
is.Equal(iter1, 1)
is.GreaterOrEqual(dur1, 0*time.Millisecond)
is.Less(dur1, 1*time.Millisecond)
is.Nil(err1)
iter2, dur2, err2 := AttemptWhileWithDelay(42, 10*time.Millisecond, func(i int, d time.Duration) (error, bool) {
if i == 5 {
return nil, true
}
return err, true
})
is.Equal(iter2, 6)
is.Greater(dur2, 50*time.Millisecond)
is.Less(dur2, 60*time.Millisecond)
is.Nil(err2)
iter3, dur3, err3 := AttemptWhileWithDelay(2, 10*time.Millisecond, func(i int, d time.Duration) (error, bool) {
if i == 5 {
return nil, true
}
return err, true
})
is.Equal(iter3, 2)
is.Greater(dur3, 10*time.Millisecond)
is.Less(dur3, 20*time.Millisecond)
is.Equal(err3, err)
iter4, dur4, err4 := AttemptWhileWithDelay(0, 10*time.Millisecond, func(i int, d time.Duration) (error, bool) {
if i < 10 {
return err, true
}
return nil, true
})
is.Equal(iter4, 11)
is.Greater(dur4, 100*time.Millisecond)
is.Less(dur4, 115*time.Millisecond)
is.Nil(err4)
iter5, dur5, err5 := AttemptWhileWithDelay(0, 10*time.Millisecond, func(i int, d time.Duration) (error, bool) {
if i == 5 {
return nil, false
}
return err, true
})
is.Equal(iter5, 6)
is.Greater(dur5, 10*time.Millisecond)
is.Less(dur5, 115*time.Millisecond)
is.Nil(err5)
iter6, dur6, err6 := AttemptWhileWithDelay(0, 10*time.Millisecond, func(i int, d time.Duration) (error, bool) {
return nil, false
})
is.Equal(iter6, 1)
is.Less(dur6, 10*time.Millisecond)
is.Less(dur6, 115*time.Millisecond)
is.Nil(err6)
iter7, dur7, err7 := AttemptWhileWithDelay(42, 10*time.Millisecond, func(i int, d time.Duration) (error, bool) {
if i == 42 {
return nil, false
}
if i < 41 {
return err, true
}
return nil, true
})
is.Equal(iter7, 42)
is.Less(dur7, 500*time.Millisecond)
is.Nil(err7)
}
func TestDebounce(t *testing.T) {
t.Parallel()
f1 := func() {
println("1. Called once after 10ms when func stopped invoking!")
}
f2 := func() {
println("2. Called once after 10ms when func stopped invoking!")
}
f3 := func() {
println("3. Called once after 10ms when func stopped invoking!")
}
d1, _ := NewDebounce(10*time.Millisecond, f1)
// execute 3 times
for i := 0; i < 3; i++ {
for j := 0; j < 10; j++ {
d1()
}
time.Sleep(20 * time.Millisecond)
}
d2, _ := NewDebounce(10*time.Millisecond, f2)
// execute once because it is always invoked and only last invoke is worked after 100ms
for i := 0; i < 3; i++ {
for j := 0; j < 5; j++ {
d2()
}
time.Sleep(5 * time.Millisecond)
}
time.Sleep(10 * time.Millisecond)
// execute once because it is canceled after 200ms.
d3, cancel := NewDebounce(10*time.Millisecond, f3)
for i := 0; i < 3; i++ {
for j := 0; j < 10; j++ {
d3()
}
time.Sleep(20 * time.Millisecond)
if i == 0 {
cancel()
}
}
}
func TestDebounceBy(t *testing.T) {
t.Parallel()
is := assert.New(t)
mu := sync.Mutex{}
output := map[int]int{0: 0, 1: 0, 2: 0}
f1 := func(key int, count int) {
mu.Lock()
output[key] += count
mu.Unlock()
// fmt.Printf("[key=%d] 1. Called once after 10ms when func stopped invoking!\n", key)
}
f2 := func(key int, count int) {
mu.Lock()
output[key] += count
mu.Unlock()
// fmt.Printf("[key=%d] 2. Called once after 10ms when func stopped invoking!\n", key)
}
f3 := func(key int, count int) {
mu.Lock()
output[key] += count
mu.Unlock()
// fmt.Printf("[key=%d] 3. Called once after 10ms when func stopped invoking!\n", key)
}
d1, _ := NewDebounceBy(10*time.Millisecond, f1)
// execute 3 times
for i := 0; i < 3; i++ {
for j := 0; j < 10; j++ {
for k := 0; k < 3; k++ {
d1(k)
}
}
time.Sleep(20 * time.Millisecond)
}
mu.Lock()
is.EqualValues(output[0], 30)
is.EqualValues(output[1], 30)
is.EqualValues(output[2], 30)
mu.Unlock()
d2, _ := NewDebounceBy(10*time.Millisecond, f2)
// execute once because it is always invoked and only last invoke is worked after 100ms
for i := 0; i < 3; i++ {
for j := 0; j < 5; j++ {
for k := 0; k < 3; k++ {
d2(k)
}
}
time.Sleep(5 * time.Millisecond)
}
time.Sleep(10 * time.Millisecond)
mu.Lock()
is.EqualValues(output[0], 45)
is.EqualValues(output[1], 45)
is.EqualValues(output[2], 45)
mu.Unlock()
// execute once because it is canceled after 200ms.
d3, cancel := NewDebounceBy(10*time.Millisecond, f3)
for i := 0; i < 3; i++ {
for j := 0; j < 10; j++ {
for k := 0; k < 3; k++ {
d3(k)
}
}
time.Sleep(20 * time.Millisecond)
if i == 0 {
for k := 0; k < 3; k++ {
cancel(k)
}
}
}
mu.Lock()
is.EqualValues(output[0], 75)
is.EqualValues(output[1], 75)
is.EqualValues(output[2], 75)
mu.Unlock()
}
func TestTransaction(t *testing.T) {
is := assert.New(t)
// no error
{
transaction := NewTransaction[int]().
Then(
func(state int) (int, error) {
return state + 100, nil
},
func(state int) int {
return state - 100
},
).
Then(
func(state int) (int, error) {
return state + 21, nil
},
func(state int) int {
return state - 21
},
)
state, err := transaction.Process(21)
is.Equal(142, state)
is.Equal(nil, err)
}
// with error
{
transaction := NewTransaction[int]().
Then(
func(state int) (int, error) {
return state + 100, nil
},
func(state int) int {
return state - 100
},
).
Then(
func(state int) (int, error) {
return state, assert.AnError
},
func(state int) int {
return state - 21
},
).
Then(
func(state int) (int, error) {
return state + 42, nil
},
func(state int) int {
return state - 42
},
)
state, err := transaction.Process(21)
is.Equal(21, state)
is.Equal(assert.AnError, err)
}
// with error + update value
{
transaction := NewTransaction[int]().
Then(
func(state int) (int, error) {
return state + 100, nil
},
func(state int) int {
return state - 100
},
).
Then(
func(state int) (int, error) {
return state + 21, assert.AnError
},
func(state int) int {
return state - 21
},
).
Then(
func(state int) (int, error) {
return state + 42, nil
},
func(state int) int {
return state - 42
},
)
state, err := transaction.Process(21)
is.Equal(42, state)
is.Equal(assert.AnError, err)
}
}
func TestNewThrottle(t *testing.T) {
t.Parallel()
is := assert.New(t)
callCount := 0
f1 := func() {
callCount++
}
th, reset := NewThrottle(10*time.Millisecond, f1)
is.Equal(0, callCount)
for j := 0; j < 100; j++ {
th()
}
is.Equal(1, callCount)
time.Sleep(15 * time.Millisecond)
for j := 0; j < 100; j++ {
th()
}
is.Equal(2, callCount)
// reset counter
reset()
th()
is.Equal(3, callCount)
}
func TestNewThrottleWithCount(t *testing.T) {
t.Parallel()
is := assert.New(t)
callCount := 0
f1 := func() {
callCount++
}
th, reset := NewThrottleWithCount(10*time.Millisecond, 3, f1)
// the function does not throttle for initial count number
for i := 0; i < 20; i++ {
th()
}
is.Equal(3, callCount)
time.Sleep(11 * time.Millisecond)
for i := 0; i < 20; i++ {
th()
}
is.Equal(6, callCount)
reset()
for i := 0; i < 20; i++ {
th()
}
is.Equal(9, callCount)
}
func TestNewThrottleBy(t *testing.T) {
t.Parallel()
is := assert.New(t)
callCountA := 0
callCountB := 0
f1 := func(key string) {
if key == "a" {
callCountA++
} else {
callCountB++
}
}
th, reset := NewThrottleBy[string](10*time.Millisecond, f1)
is.Equal(0, callCountA)
is.Equal(0, callCountB)
for j := 0; j < 100; j++ {
th("a")
th("b")
}
is.Equal(1, callCountA)
is.Equal(1, callCountB)
time.Sleep(15 * time.Millisecond)
for j := 0; j < 100; j++ {
th("a")
th("b")
}
is.Equal(2, callCountA)
is.Equal(2, callCountB)
// reset counter
reset()
th("a")
is.Equal(3, callCountA)
is.Equal(2, callCountB)
}
func TestNewThrottleByWithCount(t *testing.T) {
t.Parallel()
is := assert.New(t)
callCountA := 0
callCountB := 0
f1 := func(key string) {
if key == "a" {
callCountA++
} else {
callCountB++
}
}
th, reset := NewThrottleByWithCount(10*time.Millisecond, 3, f1)
// the function does not throttle for initial count number
for i := 0; i < 20; i++ {
th("a")
th("b")
}
is.Equal(3, callCountA)
is.Equal(3, callCountB)
time.Sleep(11 * time.Millisecond)
for i := 0; i < 20; i++ {
th("a")
th("b")
}
is.Equal(6, callCountA)
is.Equal(6, callCountB)
reset()
for i := 0; i < 20; i++ {
th("a")
}
is.Equal(9, callCountA)
is.Equal(6, callCountB)
}

View File

@@ -1,200 +0,0 @@
package lo
import (
"fmt"
"math/rand"
"strconv"
"testing"
)
var lengths = []int{10, 100, 1000}
func BenchmarkChunk(b *testing.B) {
for _, n := range lengths {
strs := genSliceString(n)
b.Run(fmt.Sprintf("strings_%d", n), func(b *testing.B) {
for i := 0; i < b.N; i++ {
_ = Chunk(strs, 5)
}
})
}
for _, n := range lengths {
ints := genSliceInt(n)
b.Run(fmt.Sprintf("ints%d", n), func(b *testing.B) {
for i := 0; i < b.N; i++ {
_ = Chunk(ints, 5)
}
})
}
}
func genSliceString(n int) []string {
res := make([]string, 0, n)
for i := 0; i < n; i++ {
res = append(res, strconv.Itoa(rand.Intn(100_000)))
}
return res
}
func genSliceInt(n int) []int {
res := make([]int, 0, n)
for i := 0; i < n; i++ {
res = append(res, rand.Intn(100_000))
}
return res
}
func BenchmarkFlatten(b *testing.B) {
for _, n := range lengths {
ints := make([][]int, 0, n)
for i := 0; i < n; i++ {
ints = append(ints, genSliceInt(n))
}
b.Run(fmt.Sprintf("ints_%d", n), func(b *testing.B) {
for i := 0; i < b.N; i++ {
_ = Flatten(ints)
}
})
}
for _, n := range lengths {
strs := make([][]string, 0, n)
for i := 0; i < n; i++ {
strs = append(strs, genSliceString(n))
}
b.Run(fmt.Sprintf("strings_%d", n), func(b *testing.B) {
for i := 0; i < b.N; i++ {
_ = Flatten(strs)
}
})
}
}
func BenchmarkDrop(b *testing.B) {
for _, n := range lengths {
strs := genSliceString(n)
b.Run(fmt.Sprintf("strings_%d", n), func(b *testing.B) {
for i := 0; i < b.N; i++ {
_ = Drop(strs, n/4)
}
})
}
for _, n := range lengths {
ints := genSliceInt(n)
b.Run(fmt.Sprintf("ints%d", n), func(b *testing.B) {
for i := 0; i < b.N; i++ {
_ = Drop(ints, n/4)
}
})
}
}
func BenchmarkDropRight(b *testing.B) {
for _, n := range lengths {
strs := genSliceString(n)
b.Run(fmt.Sprintf("strings_%d", n), func(b *testing.B) {
for i := 0; i < b.N; i++ {
_ = DropRight(strs, n/4)
}
})
}
for _, n := range lengths {
ints := genSliceInt(n)
b.Run(fmt.Sprintf("ints%d", n), func(b *testing.B) {
for i := 0; i < b.N; i++ {
_ = DropRight(ints, n/4)
}
})
}
}
func BenchmarkDropWhile(b *testing.B) {
for _, n := range lengths {
strs := genSliceString(n)
b.Run(fmt.Sprintf("strings_%d", n), func(b *testing.B) {
for i := 0; i < b.N; i++ {
_ = DropWhile(strs, func(v string) bool { return len(v) < 4 })
}
})
}
for _, n := range lengths {
ints := genSliceInt(n)
b.Run(fmt.Sprintf("ints%d", n), func(b *testing.B) {
for i := 0; i < b.N; i++ {
_ = DropWhile(ints, func(v int) bool { return i < 10_000 })
}
})
}
}
func BenchmarkDropRightWhile(b *testing.B) {
for _, n := range lengths {
strs := genSliceString(n)
b.Run(fmt.Sprintf("strings_%d", n), func(b *testing.B) {
for i := 0; i < b.N; i++ {
_ = DropRightWhile(strs, func(v string) bool { return len(v) < 4 })
}
})
}
for _, n := range lengths {
ints := genSliceInt(n)
b.Run(fmt.Sprintf("ints%d", n), func(b *testing.B) {
for i := 0; i < b.N; i++ {
_ = DropRightWhile(ints, func(v int) bool { return i < 10_000 })
}
})
}
}
func BenchmarkDropByIndex(b *testing.B) {
for _, n := range lengths {
strs := genSliceString(n)
b.Run(fmt.Sprintf("strings_%d", n), func(b *testing.B) {
for i := 0; i < b.N; i++ {
_ = DropByIndex(strs, n/4)
}
})
}
for _, n := range lengths {
ints := genSliceInt(n)
b.Run(fmt.Sprintf("ints%d", n), func(b *testing.B) {
for i := 0; i < b.N; i++ {
_ = DropByIndex(ints, n/4)
}
})
}
}
func BenchmarkReplace(b *testing.B) {
lengths := []int{1_000, 10_000, 100_000}
for _, n := range lengths {
strs := genSliceString(n)
b.Run(fmt.Sprintf("strings_%d", n), func(b *testing.B) {
for i := 0; i < b.N; i++ {
_ = Replace(strs, strs[n/4], "123123", 10)
}
})
}
for _, n := range lengths {
ints := genSliceInt(n)
b.Run(fmt.Sprintf("ints%d", n), func(b *testing.B) {
for i := 0; i < b.N; i++ {
_ = Replace(ints, ints[n/4], 123123, 10)
}
})
}
}
func BenchmarkToSlicePtr(b *testing.B) {
preallocated := make([]int, 100000)
for i := 0; i < b.N; i++ {
_ = ToSlicePtr(preallocated)
}
}

View File

@@ -1,541 +0,0 @@
package lo
import (
"fmt"
"math"
"strconv"
)
func ExampleFilter() {
list := []int64{1, 2, 3, 4}
result := Filter(list, func(nbr int64, index int) bool {
return nbr%2 == 0
})
fmt.Printf("%v", result)
// Output: [2 4]
}
func ExampleMap() {
list := []int64{1, 2, 3, 4}
result := Map(list, func(nbr int64, index int) string {
return strconv.FormatInt(nbr*2, 10)
})
fmt.Printf("%v", result)
// Output: [2 4 6 8]
}
func ExampleUniqMap() {
type User struct {
Name string
Age int
}
users := []User{{Name: "Alex", Age: 10}, {Name: "Alex", Age: 12}, {Name: "Bob", Age: 11}, {Name: "Alice", Age: 20}}
result := UniqMap(users, func(u User, index int) string {
return u.Name
})
fmt.Printf("%v", result)
// Output: [Alex Bob Alice]
}
func ExampleFilterMap() {
list := []int64{1, 2, 3, 4}
result := FilterMap(list, func(nbr int64, index int) (string, bool) {
return strconv.FormatInt(nbr*2, 10), nbr%2 == 0
})
fmt.Printf("%v", result)
// Output: [4 8]
}
func ExampleFlatMap() {
list := []int64{1, 2, 3, 4}
result := FlatMap(list, func(nbr int64, index int) []string {
return []string{
strconv.FormatInt(nbr, 10), // base 10
strconv.FormatInt(nbr, 2), // base 2
}
})
fmt.Printf("%v", result)
// Output: [1 1 2 10 3 11 4 100]
}
func ExampleReduce() {
list := []int64{1, 2, 3, 4}
result := Reduce(list, func(agg int64, item int64, index int) int64 {
return agg + item
}, 0)
fmt.Printf("%v", result)
// Output: 10
}
func ExampleReduceRight() {
list := [][]int{{0, 1}, {2, 3}, {4, 5}}
result := ReduceRight(list, func(agg []int, item []int, index int) []int {
return append(agg, item...)
}, []int{})
fmt.Printf("%v", result)
// Output: [4 5 2 3 0 1]
}
func ExampleForEach() {
list := []int64{1, 2, 3, 4}
ForEach(list, func(x int64, _ int) {
fmt.Println(x)
})
// Output:
// 1
// 2
// 3
// 4
}
func ExampleForEachWhile() {
list := []int64{1, 2, -math.MaxInt, 4}
ForEachWhile(list, func(x int64, _ int) bool {
if x < 0 {
return false
}
fmt.Println(x)
return true
})
// Output:
// 1
// 2
}
func ExampleTimes() {
result := Times(3, func(i int) string {
return strconv.FormatInt(int64(i), 10)
})
fmt.Printf("%v", result)
// Output: [0 1 2]
}
func ExampleUniq() {
list := []int{1, 2, 2, 1}
result := Uniq(list)
fmt.Printf("%v", result)
// Output: [1 2]
}
func ExampleUniqBy() {
list := []int{0, 1, 2, 3, 4, 5}
result := UniqBy(list, func(i int) int {
return i % 3
})
fmt.Printf("%v", result)
// Output: [0 1 2]
}
func ExampleGroupBy() {
list := []int{0, 1, 2, 3, 4, 5}
result := GroupBy(list, func(i int) int {
return i % 3
})
fmt.Printf("%v\n", result[0])
fmt.Printf("%v\n", result[1])
fmt.Printf("%v\n", result[2])
// Output:
// [0 3]
// [1 4]
// [2 5]
}
func ExampleGroupByMap() {
list := []int{0, 1, 2, 3, 4, 5}
result := GroupByMap(list, func(i int) (int, int) {
return i % 3, i * 2
})
fmt.Printf("%v\n", result[0])
fmt.Printf("%v\n", result[1])
fmt.Printf("%v\n", result[2])
// Output:
// [0 6]
// [2 8]
// [4 10]
}
func ExampleChunk() {
list := []int{0, 1, 2, 3, 4}
result := Chunk(list, 2)
for _, item := range result {
fmt.Printf("%v\n", item)
}
// Output:
// [0 1]
// [2 3]
// [4]
}
func ExamplePartitionBy() {
list := []int{-2, -1, 0, 1, 2, 3, 4}
result := PartitionBy(list, func(x int) string {
if x < 0 {
return "negative"
} else if x%2 == 0 {
return "even"
}
return "odd"
})
for _, item := range result {
fmt.Printf("%v\n", item)
}
// Output:
// [-2 -1]
// [0 2 4]
// [1 3]
}
func ExampleFlatten() {
list := [][]int{{0, 1, 2}, {3, 4, 5}}
result := Flatten(list)
fmt.Printf("%v", result)
// Output: [0 1 2 3 4 5]
}
func ExampleInterleave() {
list1 := [][]int{{1, 4, 7}, {2, 5, 8}, {3, 6, 9}}
list2 := [][]int{{1}, {2, 5, 8}, {3, 6}, {4, 7, 9, 10}}
result1 := Interleave(list1...)
result2 := Interleave(list2...)
fmt.Printf("%v\n", result1)
fmt.Printf("%v\n", result2)
// Output:
// [1 2 3 4 5 6 7 8 9]
// [1 2 3 4 5 6 7 8 9 10]
}
func ExampleShuffle() {
list := []int{0, 1, 2, 3, 4, 5}
result := Shuffle(list)
fmt.Printf("%v", result)
}
func ExampleReverse() {
list := []int{0, 1, 2, 3, 4, 5}
result := Reverse(list)
fmt.Printf("%v", result)
// Output: [5 4 3 2 1 0]
}
func ExampleFill() {
list := []foo{{"a"}, {"a"}}
result := Fill(list, foo{"b"})
fmt.Printf("%v", result)
// Output: [{b} {b}]
}
func ExampleRepeat() {
result := Repeat(2, foo{"a"})
fmt.Printf("%v", result)
// Output: [{a} {a}]
}
func ExampleRepeatBy() {
result := RepeatBy(5, func(i int) string {
return strconv.FormatInt(int64(math.Pow(float64(i), 2)), 10)
})
fmt.Printf("%v", result)
// Output: [0 1 4 9 16]
}
func ExampleKeyBy() {
list := []string{"a", "aa", "aaa"}
result := KeyBy(list, func(str string) int {
return len(str)
})
fmt.Printf("%v", result)
// Output: map[1:a 2:aa 3:aaa]
}
func ExampleSliceToMap() {
list := []string{"a", "aa", "aaa"}
result := SliceToMap(list, func(str string) (string, int) {
return str, len(str)
})
fmt.Printf("%v", result)
// Output: map[a:1 aa:2 aaa:3]
}
func ExampleFilterSliceToMap() {
list := []string{"a", "aa", "aaa"}
result := FilterSliceToMap(list, func(str string) (string, int, bool) {
return str, len(str), len(str) > 1
})
fmt.Printf("%v", result)
// Output: map[aa:2 aaa:3]
}
func ExampleKeyify() {
list := []string{"a", "a", "b", "b", "d"}
set := Keyify(list)
_, ok1 := set["a"]
_, ok2 := set["c"]
fmt.Printf("%v\n", ok1)
fmt.Printf("%v\n", ok2)
fmt.Printf("%v\n", set)
// Output:
// true
// false
// map[a:{} b:{} d:{}]
}
func ExampleDrop() {
list := []int{0, 1, 2, 3, 4, 5}
result := Drop(list, 2)
fmt.Printf("%v", result)
// Output: [2 3 4 5]
}
func ExampleDropRight() {
list := []int{0, 1, 2, 3, 4, 5}
result := DropRight(list, 2)
fmt.Printf("%v", result)
// Output: [0 1 2 3]
}
func ExampleDropWhile() {
list := []int{0, 1, 2, 3, 4, 5}
result := DropWhile(list, func(val int) bool {
return val < 2
})
fmt.Printf("%v", result)
// Output: [2 3 4 5]
}
func ExampleDropRightWhile() {
list := []int{0, 1, 2, 3, 4, 5}
result := DropRightWhile(list, func(val int) bool {
return val > 2
})
fmt.Printf("%v", result)
// Output: [0 1 2]
}
func ExampleDropByIndex() {
list := []int{0, 1, 2, 3, 4, 5}
result := DropByIndex(list, 2)
fmt.Printf("%v", result)
// Output: [0 1 3 4 5]
}
func ExampleReject() {
list := []int{0, 1, 2, 3, 4, 5}
result := Reject(list, func(x int, _ int) bool {
return x%2 == 0
})
fmt.Printf("%v", result)
// Output: [1 3 5]
}
func ExampleCount() {
list := []int{0, 1, 2, 3, 4, 5, 0, 1, 2, 3}
result := Count(list, 2)
fmt.Printf("%v", result)
// Output: 2
}
func ExampleCountBy() {
list := []int{0, 1, 2, 3, 4, 5, 0, 1, 2, 3}
result := CountBy(list, func(i int) bool {
return i < 4
})
fmt.Printf("%v", result)
// Output: 8
}
func ExampleCountValues() {
result1 := CountValues([]int{})
result2 := CountValues([]int{1, 2})
result3 := CountValues([]int{1, 2, 2})
result4 := CountValues([]string{"foo", "bar", ""})
result5 := CountValues([]string{"foo", "bar", "bar"})
fmt.Printf("%v\n", result1)
fmt.Printf("%v\n", result2)
fmt.Printf("%v\n", result3)
fmt.Printf("%v\n", result4)
fmt.Printf("%v\n", result5)
// Output:
// map[]
// map[1:1 2:1]
// map[1:1 2:2]
// map[:1 bar:1 foo:1]
// map[bar:2 foo:1]
}
func ExampleCountValuesBy() {
isEven := func(v int) bool {
return v%2 == 0
}
result1 := CountValuesBy([]int{}, isEven)
result2 := CountValuesBy([]int{1, 2}, isEven)
result3 := CountValuesBy([]int{1, 2, 2}, isEven)
length := func(v string) int {
return len(v)
}
result4 := CountValuesBy([]string{"foo", "bar", ""}, length)
result5 := CountValuesBy([]string{"foo", "bar", "bar"}, length)
fmt.Printf("%v\n", result1)
fmt.Printf("%v\n", result2)
fmt.Printf("%v\n", result3)
fmt.Printf("%v\n", result4)
fmt.Printf("%v\n", result5)
// Output:
// map[]
// map[false:1 true:1]
// map[false:1 true:2]
// map[0:1 3:2]
// map[3:3]
}
func ExampleSubset() {
list := []int{0, 1, 2, 3, 4, 5}
result := Subset(list, 2, 3)
fmt.Printf("%v", result)
// Output: [2 3 4]
}
func ExampleSlice() {
list := []int{0, 1, 2, 3, 4, 5}
result := Slice(list, 1, 4)
fmt.Printf("%v\n", result)
result = Slice(list, 4, 1)
fmt.Printf("%v\n", result)
result = Slice(list, 4, 5)
fmt.Printf("%v\n", result)
// Output:
// [1 2 3]
// []
// [4]
}
func ExampleReplace() {
list := []int{0, 1, 0, 1, 2, 3, 0}
result := Replace(list, 0, 42, 1)
fmt.Printf("%v\n", result)
result = Replace(list, -1, 42, 1)
fmt.Printf("%v\n", result)
result = Replace(list, 0, 42, 2)
fmt.Printf("%v\n", result)
result = Replace(list, 0, 42, -1)
fmt.Printf("%v\n", result)
// Output:
// [42 1 0 1 2 3 0]
// [0 1 0 1 2 3 0]
// [42 1 42 1 2 3 0]
// [42 1 42 1 2 3 42]
}
func ExampleReplaceAll() {
list := []string{"", "foo", "", "bar", ""}
result := Compact(list)
fmt.Printf("%v", result)
// Output: [foo bar]
}
func ExampleIsSorted() {
list := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
result := IsSorted(list)
fmt.Printf("%v", result)
// Output: true
}
func ExampleIsSortedByKey() {
list := []string{"a", "bb", "ccc"}
result := IsSortedByKey(list, func(s string) int {
return len(s)
})
fmt.Printf("%v", result)
// Output: true
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,54 +0,0 @@
package lo
import (
"fmt"
"math"
)
func ExampleSubstring() {
result1 := Substring("hello", 2, 3)
result2 := Substring("hello", -4, 3)
result3 := Substring("hello", -2, math.MaxUint)
result4 := Substring("🏠🐶🐱", 0, 2)
result5 := Substring("你好,世界", 0, 3)
fmt.Printf("%v\n", result1)
fmt.Printf("%v\n", result2)
fmt.Printf("%v\n", result3)
fmt.Printf("%v\n", result4)
fmt.Printf("%v\n", result5)
// Output:
// llo
// ell
// lo
// 🏠🐶
// 你好,
}
func ExampleChunkString() {
result1 := ChunkString("123456", 2)
result2 := ChunkString("1234567", 2)
result3 := ChunkString("", 2)
result4 := ChunkString("1", 2)
fmt.Printf("%v\n", result1)
fmt.Printf("%v\n", result2)
fmt.Printf("%v\n", result3)
fmt.Printf("%v\n", result4)
// Output:
// [12 34 56]
// [12 34 56 7]
// []
// [1]
}
func ExampleRuneLength() {
result1, chars1 := RuneLength("hellô"), len("hellô")
result2, chars2 := RuneLength("🤘"), len("🤘")
fmt.Printf("%v %v\n", result1, chars1)
fmt.Printf("%v %v\n", result2, chars2)
// Output:
// 5 6
// 1 4
}

View File

@@ -1,503 +0,0 @@
package lo
import (
"math"
"math/rand"
"testing"
"time"
"github.com/stretchr/testify/assert"
)
func TestRandomString(t *testing.T) {
t.Parallel()
is := assert.New(t)
rand.Seed(time.Now().UnixNano())
str1 := RandomString(100, LowerCaseLettersCharset)
is.Equal(100, RuneLength(str1))
is.Subset(LowerCaseLettersCharset, []rune(str1))
str2 := RandomString(100, LowerCaseLettersCharset)
is.NotEqual(str1, str2)
noneUtf8Charset := []rune("明1好休2林森")
str3 := RandomString(100, noneUtf8Charset)
is.Equal(100, RuneLength(str3))
is.Subset(noneUtf8Charset, []rune(str3))
is.PanicsWithValue("lo.RandomString: Charset parameter must not be empty", func() { RandomString(100, []rune{}) })
is.PanicsWithValue("lo.RandomString: Size parameter must be greater than 0", func() { RandomString(0, LowerCaseLettersCharset) })
}
func TestChunkString(t *testing.T) {
t.Parallel()
is := assert.New(t)
result1 := ChunkString("12345", 2)
is.Equal([]string{"12", "34", "5"}, result1)
result2 := ChunkString("123456", 2)
is.Equal([]string{"12", "34", "56"}, result2)
result3 := ChunkString("123456", 6)
is.Equal([]string{"123456"}, result3)
result4 := ChunkString("123456", 10)
is.Equal([]string{"123456"}, result4)
result5 := ChunkString("", 2)
is.Equal([]string{""}, result5)
result6 := ChunkString("明1好休2林森", 2)
is.Equal([]string{"明1", "好休", "2林", "森"}, result6)
is.Panics(func() {
ChunkString("12345", 0)
})
}
func TestSubstring(t *testing.T) {
t.Parallel()
is := assert.New(t)
str1 := Substring("hello", 0, 0)
str2 := Substring("hello", 10, 2)
str3 := Substring("hello", -10, 2)
str4 := Substring("hello", 0, 10)
str5 := Substring("hello", 0, 2)
str6 := Substring("hello", 2, 2)
str7 := Substring("hello", 2, 5)
str8 := Substring("hello", 2, 3)
str9 := Substring("hello", 2, 4)
str10 := Substring("hello", -2, 4)
str11 := Substring("hello", -4, 1)
str12 := Substring("hello", -4, math.MaxUint)
str13 := Substring("🏠🐶🐱", 0, 2)
str14 := Substring("你好,世界", 0, 3)
str15 := Substring("hello", 5, 1)
is.Equal("", str1)
is.Equal("", str2)
is.Equal("he", str3)
is.Equal("hello", str4)
is.Equal("he", str5)
is.Equal("ll", str6)
is.Equal("llo", str7)
is.Equal("llo", str8)
is.Equal("llo", str9)
is.Equal("lo", str10)
is.Equal("e", str11)
is.Equal("ello", str12)
is.Equal("🏠🐶", str13)
is.Equal("你好,", str14)
is.Equal("", str15)
}
func TestRuneLength(t *testing.T) {
t.Parallel()
is := assert.New(t)
is.Equal(5, RuneLength("hellô"))
is.Equal(6, len("hellô"))
}
func TestAllCase(t *testing.T) {
type output struct {
PascalCase string
CamelCase string
KebabCase string
SnakeCase string
}
name := ""
tests := []struct {
name string
input string
output output
}{
{name: name, output: output{}},
{name: name, input: ".", output: output{}},
{name: name, input: "Hello world!", output: output{
PascalCase: "HelloWorld",
CamelCase: "helloWorld",
KebabCase: "hello-world",
SnakeCase: "hello_world",
}},
{name: name, input: "A", output: output{
PascalCase: "A",
CamelCase: "a",
KebabCase: "a",
SnakeCase: "a",
}},
{name: name, input: "a", output: output{
PascalCase: "A",
CamelCase: "a",
KebabCase: "a",
SnakeCase: "a",
}},
{name: name, input: "foo", output: output{
PascalCase: "Foo",
CamelCase: "foo",
KebabCase: "foo",
SnakeCase: "foo",
}},
{name: name, input: "snake_case", output: output{
PascalCase: "SnakeCase",
CamelCase: "snakeCase",
KebabCase: "snake-case",
SnakeCase: "snake_case",
}},
{name: name, input: "SNAKE_CASE", output: output{
PascalCase: "SnakeCase",
CamelCase: "snakeCase",
KebabCase: "snake-case",
SnakeCase: "snake_case",
}},
{name: name, input: "kebab-case", output: output{
PascalCase: "KebabCase",
CamelCase: "kebabCase",
KebabCase: "kebab-case",
SnakeCase: "kebab_case",
}},
{name: name, input: "PascalCase", output: output{
PascalCase: "PascalCase",
CamelCase: "pascalCase",
KebabCase: "pascal-case",
SnakeCase: "pascal_case",
}},
{name: name, input: "camelCase", output: output{
PascalCase: "CamelCase",
CamelCase: "camelCase",
KebabCase: `camel-case`,
SnakeCase: "camel_case",
}},
{name: name, input: "Title Case", output: output{
PascalCase: "TitleCase",
CamelCase: "titleCase",
KebabCase: "title-case",
SnakeCase: "title_case",
}},
{name: name, input: "point.case", output: output{
PascalCase: "PointCase",
CamelCase: "pointCase",
KebabCase: "point-case",
SnakeCase: "point_case",
}},
{name: name, input: "snake_case_with_more_words", output: output{
PascalCase: "SnakeCaseWithMoreWords",
CamelCase: "snakeCaseWithMoreWords",
KebabCase: "snake-case-with-more-words",
SnakeCase: "snake_case_with_more_words",
}},
{name: name, input: "SNAKE_CASE_WITH_MORE_WORDS", output: output{
PascalCase: "SnakeCaseWithMoreWords",
CamelCase: "snakeCaseWithMoreWords",
KebabCase: "snake-case-with-more-words",
SnakeCase: "snake_case_with_more_words",
}},
{name: name, input: "kebab-case-with-more-words", output: output{
PascalCase: "KebabCaseWithMoreWords",
CamelCase: "kebabCaseWithMoreWords",
KebabCase: "kebab-case-with-more-words",
SnakeCase: "kebab_case_with_more_words",
}},
{name: name, input: "PascalCaseWithMoreWords", output: output{
PascalCase: "PascalCaseWithMoreWords",
CamelCase: "pascalCaseWithMoreWords",
KebabCase: "pascal-case-with-more-words",
SnakeCase: "pascal_case_with_more_words",
}},
{name: name, input: "camelCaseWithMoreWords", output: output{
PascalCase: "CamelCaseWithMoreWords",
CamelCase: "camelCaseWithMoreWords",
KebabCase: "camel-case-with-more-words",
SnakeCase: "camel_case_with_more_words",
}},
{name: name, input: "Title Case With More Words", output: output{
PascalCase: "TitleCaseWithMoreWords",
CamelCase: "titleCaseWithMoreWords",
KebabCase: "title-case-with-more-words",
SnakeCase: "title_case_with_more_words",
}},
{name: name, input: "point.case.with.more.words", output: output{
PascalCase: "PointCaseWithMoreWords",
CamelCase: "pointCaseWithMoreWords",
KebabCase: "point-case-with-more-words",
SnakeCase: "point_case_with_more_words",
}},
{name: name, input: "snake_case__with___multiple____delimiters", output: output{
PascalCase: "SnakeCaseWithMultipleDelimiters",
CamelCase: "snakeCaseWithMultipleDelimiters",
KebabCase: "snake-case-with-multiple-delimiters",
SnakeCase: "snake_case_with_multiple_delimiters",
}},
{name: name, input: "SNAKE_CASE__WITH___multiple____DELIMITERS", output: output{
PascalCase: "SnakeCaseWithMultipleDelimiters",
CamelCase: "snakeCaseWithMultipleDelimiters",
KebabCase: "snake-case-with-multiple-delimiters",
SnakeCase: "snake_case_with_multiple_delimiters",
}},
{name: name, input: "kebab-case--with---multiple----delimiters", output: output{
PascalCase: "KebabCaseWithMultipleDelimiters",
CamelCase: "kebabCaseWithMultipleDelimiters",
KebabCase: "kebab-case-with-multiple-delimiters",
SnakeCase: "kebab_case_with_multiple_delimiters",
}},
{name: name, input: "Title Case With Multiple Delimiters", output: output{
PascalCase: "TitleCaseWithMultipleDelimiters",
CamelCase: "titleCaseWithMultipleDelimiters",
KebabCase: "title-case-with-multiple-delimiters",
SnakeCase: "title_case_with_multiple_delimiters",
}},
{name: name, input: "point.case..with...multiple....delimiters", output: output{
PascalCase: "PointCaseWithMultipleDelimiters",
CamelCase: "pointCaseWithMultipleDelimiters",
KebabCase: "point-case-with-multiple-delimiters",
SnakeCase: "point_case_with_multiple_delimiters",
}},
{name: name, input: " leading space", output: output{
PascalCase: "LeadingSpace",
CamelCase: "leadingSpace",
KebabCase: "leading-space",
SnakeCase: "leading_space",
}},
{name: name, input: " leading spaces", output: output{
PascalCase: "LeadingSpaces",
CamelCase: "leadingSpaces",
KebabCase: "leading-spaces",
SnakeCase: "leading_spaces",
}},
{name: name, input: "\t\t\r\n leading whitespaces", output: output{
PascalCase: "LeadingWhitespaces",
CamelCase: "leadingWhitespaces",
KebabCase: "leading-whitespaces",
SnakeCase: "leading_whitespaces",
}},
{name: name, input: "trailing space ", output: output{
PascalCase: "TrailingSpace",
CamelCase: "trailingSpace",
KebabCase: "trailing-space",
SnakeCase: "trailing_space",
}},
{name: name, input: "trailing spaces ", output: output{
PascalCase: "TrailingSpaces",
CamelCase: "trailingSpaces",
KebabCase: "trailing-spaces",
SnakeCase: "trailing_spaces",
}},
{name: name, input: "trailing whitespaces\t\t\r\n", output: output{
PascalCase: "TrailingWhitespaces",
CamelCase: "trailingWhitespaces",
KebabCase: "trailing-whitespaces",
SnakeCase: "trailing_whitespaces",
}},
{name: name, input: " on both sides ", output: output{
PascalCase: "OnBothSides",
CamelCase: "onBothSides",
KebabCase: "on-both-sides",
SnakeCase: "on_both_sides",
}},
{name: name, input: " many on both sides ", output: output{
PascalCase: "ManyOnBothSides",
CamelCase: "manyOnBothSides",
KebabCase: "many-on-both-sides",
SnakeCase: "many_on_both_sides",
}},
{name: name, input: "\r whitespaces on both sides\t\t\r\n", output: output{
PascalCase: "WhitespacesOnBothSides",
CamelCase: "whitespacesOnBothSides",
KebabCase: "whitespaces-on-both-sides",
SnakeCase: "whitespaces_on_both_sides",
}},
{name: name, input: " extraSpaces in_This TestCase Of MIXED_CASES\t", output: output{
PascalCase: "ExtraSpacesInThisTestCaseOfMixedCases",
CamelCase: "extraSpacesInThisTestCaseOfMixedCases",
KebabCase: "extra-spaces-in-this-test-case-of-mixed-cases",
SnakeCase: "extra_spaces_in_this_test_case_of_mixed_cases",
}},
{name: name, input: "CASEBreak", output: output{
PascalCase: "CaseBreak",
CamelCase: "caseBreak",
KebabCase: "case-break",
SnakeCase: "case_break",
}},
{name: name, input: "ID", output: output{
PascalCase: "Id",
CamelCase: "id",
KebabCase: "id",
SnakeCase: "id",
}},
{name: name, input: "userID", output: output{
PascalCase: "UserId",
CamelCase: "userId",
KebabCase: "user-id",
SnakeCase: "user_id",
}},
{name: name, input: "JSON_blob", output: output{
PascalCase: "JsonBlob",
CamelCase: "jsonBlob",
KebabCase: "json-blob",
SnakeCase: "json_blob",
}},
{name: name, input: "HTTPStatusCode", output: output{
PascalCase: "HttpStatusCode",
CamelCase: "httpStatusCode",
KebabCase: "http-status-code",
SnakeCase: "http_status_code",
}},
{name: name, input: "FreeBSD and SSLError are not golang initialisms", output: output{
PascalCase: "FreeBsdAndSslErrorAreNotGolangInitialisms",
CamelCase: "freeBsdAndSslErrorAreNotGolangInitialisms",
KebabCase: "free-bsd-and-ssl-error-are-not-golang-initialisms",
SnakeCase: "free_bsd_and_ssl_error_are_not_golang_initialisms",
}},
{name: name, input: "David's Computer", output: output{
PascalCase: "DavidSComputer",
CamelCase: "davidSComputer",
KebabCase: "david-s-computer",
SnakeCase: "david_s_computer",
}},
{name: name, input: "http200", output: output{
PascalCase: "Http200",
CamelCase: "http200",
KebabCase: "http-200",
SnakeCase: "http_200",
}},
{name: name, input: "NumberSplittingVersion1.0r3", output: output{
PascalCase: "NumberSplittingVersion10R3",
CamelCase: "numberSplittingVersion10R3",
KebabCase: "number-splitting-version-1-0-r3",
SnakeCase: "number_splitting_version_1_0_r3",
}},
{name: name, input: "When you have a comma, odd results", output: output{
PascalCase: "WhenYouHaveACommaOddResults",
CamelCase: "whenYouHaveACommaOddResults",
KebabCase: "when-you-have-a-comma-odd-results",
SnakeCase: "when_you_have_a_comma_odd_results",
}},
{name: name, input: "Ordinal numbers work: 1st 2nd and 3rd place", output: output{
PascalCase: "OrdinalNumbersWork1St2NdAnd3RdPlace",
CamelCase: "ordinalNumbersWork1St2NdAnd3RdPlace",
KebabCase: "ordinal-numbers-work-1-st-2-nd-and-3-rd-place",
SnakeCase: "ordinal_numbers_work_1_st_2_nd_and_3_rd_place",
}},
{name: name, input: "BadUTF8\xe2\xe2\xa1", output: output{
PascalCase: "BadUtf8",
CamelCase: "badUtf8",
KebabCase: "bad-utf-8",
SnakeCase: "bad_utf_8",
}},
{name: name, input: "IDENT3", output: output{
PascalCase: "Ident3",
CamelCase: "ident3",
KebabCase: "ident-3",
SnakeCase: "ident_3",
}},
{name: name, input: "LogRouterS3BucketName", output: output{
PascalCase: "LogRouterS3BucketName",
CamelCase: "logRouterS3BucketName",
KebabCase: "log-router-s3-bucket-name",
SnakeCase: "log_router_s3_bucket_name",
}},
{name: name, input: "PINEAPPLE", output: output{
PascalCase: "Pineapple",
CamelCase: "pineapple",
KebabCase: "pineapple",
SnakeCase: "pineapple",
}},
{name: name, input: "Int8Value", output: output{
PascalCase: "Int8Value",
CamelCase: "int8Value",
KebabCase: "int-8-value",
SnakeCase: "int_8_value",
}},
{name: name, input: "first.last", output: output{
PascalCase: "FirstLast",
CamelCase: "firstLast",
KebabCase: "first-last",
SnakeCase: "first_last",
}},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
pascal := PascalCase(test.input)
if pascal != test.output.PascalCase {
t.Errorf("PascalCase(%q) = %q; expected %q", test.input, pascal, test.output.PascalCase)
}
camel := CamelCase(test.input)
if camel != test.output.CamelCase {
t.Errorf("CamelCase(%q) = %q; expected %q", test.input, camel, test.output.CamelCase)
}
kebab := KebabCase(test.input)
if kebab != test.output.KebabCase {
t.Errorf("KebabCase(%q) = %q; expected %q", test.input, kebab, test.output.KebabCase)
}
snake := SnakeCase(test.input)
if snake != test.output.SnakeCase {
t.Errorf("SnakeCase(%q) = %q; expected %q", test.input, snake, test.output.SnakeCase)
}
})
}
}
func TestWords(t *testing.T) {
type args struct {
str string
}
tests := []struct {
name string
args args
want []string
}{
{"", args{"PascalCase"}, []string{"Pascal", "Case"}},
{"", args{"camelCase"}, []string{"camel", "Case"}},
{"", args{"snake_case"}, []string{"snake", "case"}},
{"", args{"kebab_case"}, []string{"kebab", "case"}},
{"", args{"_test text_"}, []string{"test", "text"}},
{"", args{"UPPERCASE"}, []string{"UPPERCASE"}},
{"", args{"HTTPCode"}, []string{"HTTP", "Code"}},
{"", args{"Int8Value"}, []string{"Int", "8", "Value"}},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
assert.Equalf(t, tt.want, Words(tt.args.str), "words(%v)", tt.args.str)
})
}
}
func TestCapitalize(t *testing.T) {
type args struct {
word string
}
tests := []struct {
name string
args args
want string
}{
{"", args{"hello"}, "Hello"},
{"", args{"heLLO"}, "Hello"},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
assert.Equalf(t, tt.want, Capitalize(tt.args.word), "Capitalize(%v)", tt.args.word)
})
}
}
func TestEllipsis(t *testing.T) {
t.Parallel()
is := assert.New(t)
is.Equal("12345", Ellipsis("12345", 5))
is.Equal("1...", Ellipsis("12345", 4))
is.Equal("1...", Ellipsis(" 12345 ", 4))
is.Equal("12345", Ellipsis("12345", 6))
is.Equal("12345", Ellipsis("12345", 10))
is.Equal("12345", Ellipsis(" 12345 ", 10))
is.Equal("...", Ellipsis("12345", 3))
is.Equal("...", Ellipsis("12345", 2))
is.Equal("...", Ellipsis("12345", -1))
is.Equal("hello...", Ellipsis(" hello world ", 9))
}

View File

@@ -1,149 +0,0 @@
package lo
import (
"testing"
"time"
"github.com/stretchr/testify/assert"
)
func TestDuration(t *testing.T) {
t.Parallel()
is := assert.New(t)
result := Duration(func() { time.Sleep(10 * time.Millisecond) })
is.InEpsilon(10*time.Millisecond, result, float64(2*time.Millisecond))
}
func TestDurationX(t *testing.T) {
t.Parallel()
is := assert.New(t)
{
result := Duration0(func() { time.Sleep(10 * time.Millisecond) })
is.InEpsilon(10*time.Millisecond, result, float64(2*time.Millisecond))
}
{
a, result := Duration1(func() string { time.Sleep(10 * time.Millisecond); return "a" })
is.InEpsilon(10*time.Millisecond, result, float64(2*time.Millisecond))
is.Equal("a", a)
}
{
a, b, result := Duration2(func() (string, string) { time.Sleep(10 * time.Millisecond); return "a", "b" })
is.InEpsilon(10*time.Millisecond, result, float64(2*time.Millisecond))
is.Equal("a", a)
is.Equal("b", b)
}
{
a, b, c, result := Duration3(func() (string, string, string) { time.Sleep(10 * time.Millisecond); return "a", "b", "c" })
is.InEpsilon(10*time.Millisecond, result, float64(2*time.Millisecond))
is.Equal("a", a)
is.Equal("b", b)
is.Equal("c", c)
}
{
a, b, c, d, result := Duration4(func() (string, string, string, string) { time.Sleep(10 * time.Millisecond); return "a", "b", "c", "d" })
is.InEpsilon(10*time.Millisecond, result, float64(2*time.Millisecond))
is.Equal("a", a)
is.Equal("b", b)
is.Equal("c", c)
is.Equal("d", d)
}
{
a, b, c, d, e, result := Duration5(func() (string, string, string, string, string) {
time.Sleep(10 * time.Millisecond)
return "a", "b", "c", "d", "e"
})
is.InEpsilon(10*time.Millisecond, result, float64(2*time.Millisecond))
is.Equal("a", a)
is.Equal("b", b)
is.Equal("c", c)
is.Equal("d", d)
is.Equal("e", e)
}
{
a, b, c, d, e, f, result := Duration6(func() (string, string, string, string, string, string) {
time.Sleep(10 * time.Millisecond)
return "a", "b", "c", "d", "e", "f"
})
is.InEpsilon(10*time.Millisecond, result, float64(2*time.Millisecond))
is.Equal("a", a)
is.Equal("b", b)
is.Equal("c", c)
is.Equal("d", d)
is.Equal("e", e)
is.Equal("f", f)
}
{
a, b, c, d, e, f, g, result := Duration7(func() (string, string, string, string, string, string, string) {
time.Sleep(10 * time.Millisecond)
return "a", "b", "c", "d", "e", "f", "g"
})
is.InEpsilon(10*time.Millisecond, result, float64(2*time.Millisecond))
is.Equal("a", a)
is.Equal("b", b)
is.Equal("c", c)
is.Equal("d", d)
is.Equal("e", e)
is.Equal("f", f)
is.Equal("g", g)
}
{
a, b, c, d, e, f, g, h, result := Duration8(func() (string, string, string, string, string, string, string, string) {
time.Sleep(10 * time.Millisecond)
return "a", "b", "c", "d", "e", "f", "g", "h"
})
is.InEpsilon(10*time.Millisecond, result, float64(2*time.Millisecond))
is.Equal("a", a)
is.Equal("b", b)
is.Equal("c", c)
is.Equal("d", d)
is.Equal("e", e)
is.Equal("f", f)
is.Equal("g", g)
is.Equal("h", h)
}
{
a, b, c, d, e, f, g, h, i, result := Duration9(func() (string, string, string, string, string, string, string, string, string) {
time.Sleep(10 * time.Millisecond)
return "a", "b", "c", "d", "e", "f", "g", "h", "i"
})
is.InEpsilon(10*time.Millisecond, result, float64(2*time.Millisecond))
is.Equal("a", a)
is.Equal("b", b)
is.Equal("c", c)
is.Equal("d", d)
is.Equal("e", e)
is.Equal("f", f)
is.Equal("g", g)
is.Equal("h", h)
is.Equal("i", i)
}
{
a, b, c, d, e, f, g, h, i, j, result := Duration10(func() (string, string, string, string, string, string, string, string, string, string) {
time.Sleep(10 * time.Millisecond)
return "a", "b", "c", "d", "e", "f", "g", "h", "i", "j"
})
is.InEpsilon(10*time.Millisecond, result, float64(2*time.Millisecond))
is.Equal("a", a)
is.Equal("b", b)
is.Equal("c", c)
is.Equal("d", d)
is.Equal("e", e)
is.Equal("f", f)
is.Equal("g", g)
is.Equal("h", h)
is.Equal("i", i)
is.Equal("j", j)
}
}

View File

@@ -1,581 +0,0 @@
package lo
import (
"fmt"
)
func ExampleT2() {
result := T2("hello", 2)
fmt.Printf("%v %v", result.A, result.B)
// Output: hello 2
}
func ExampleT3() {
result := T3("hello", 2, true)
fmt.Printf("%v %v %v", result.A, result.B, result.C)
// Output: hello 2 true
}
func ExampleT4() {
result := T4("hello", 2, true, foo{bar: "bar"})
fmt.Printf("%v %v %v %v", result.A, result.B, result.C, result.D)
// Output: hello 2 true {bar}
}
func ExampleT5() {
result := T5("hello", 2, true, foo{bar: "bar"}, 4.2)
fmt.Printf("%v %v %v %v %v", result.A, result.B, result.C, result.D, result.E)
// Output: hello 2 true {bar} 4.2
}
func ExampleT6() {
result := T6("hello", 2, true, foo{bar: "bar"}, 4.2, "plop")
fmt.Printf("%v %v %v %v %v %v", result.A, result.B, result.C, result.D, result.E, result.F)
// Output: hello 2 true {bar} 4.2 plop
}
func ExampleT7() {
result := T7("hello", 2, true, foo{bar: "bar"}, 4.2, "plop", false)
fmt.Printf("%v %v %v %v %v %v %v", result.A, result.B, result.C, result.D, result.E, result.F, result.G)
// Output: hello 2 true {bar} 4.2 plop false
}
func ExampleT8() {
result := T8("hello", 2, true, foo{bar: "bar"}, 4.2, "plop", false, 42)
fmt.Printf("%v %v %v %v %v %v %v %v", result.A, result.B, result.C, result.D, result.E, result.F, result.G, result.H)
// Output: hello 2 true {bar} 4.2 plop false 42
}
func ExampleT9() {
result := T9("hello", 2, true, foo{bar: "bar"}, 4.2, "plop", false, 42, "hello world")
fmt.Printf("%v %v %v %v %v %v %v %v %v", result.A, result.B, result.C, result.D, result.E, result.F, result.G, result.H, result.I)
// Output: hello 2 true {bar} 4.2 plop false 42 hello world
}
func ExampleUnpack2() {
a, b := Unpack2(T2("hello", 2))
fmt.Printf("%v %v", a, b)
// Output: hello 2
}
func ExampleUnpack3() {
a, b, c := Unpack3(T3("hello", 2, true))
fmt.Printf("%v %v %v", a, b, c)
// Output: hello 2 true
}
func ExampleUnpack4() {
a, b, c, d := Unpack4(T4("hello", 2, true, foo{bar: "bar"}))
fmt.Printf("%v %v %v %v", a, b, c, d)
// Output: hello 2 true {bar}
}
func ExampleUnpack5() {
a, b, c, d, e := Unpack5(T5("hello", 2, true, foo{bar: "bar"}, 4.2))
fmt.Printf("%v %v %v %v %v", a, b, c, d, e)
// Output: hello 2 true {bar} 4.2
}
func ExampleUnpack6() {
a, b, c, d, e, f := Unpack6(T6("hello", 2, true, foo{bar: "bar"}, 4.2, "plop"))
fmt.Printf("%v %v %v %v %v %v", a, b, c, d, e, f)
// Output: hello 2 true {bar} 4.2 plop
}
func ExampleUnpack7() {
a, b, c, d, e, f, g := Unpack7(T7("hello", 2, true, foo{bar: "bar"}, 4.2, "plop", false))
fmt.Printf("%v %v %v %v %v %v %v", a, b, c, d, e, f, g)
// Output: hello 2 true {bar} 4.2 plop false
}
func ExampleUnpack8() {
a, b, c, d, e, f, g, h := Unpack8(T8("hello", 2, true, foo{bar: "bar"}, 4.2, "plop", false, 42))
fmt.Printf("%v %v %v %v %v %v %v %v", a, b, c, d, e, f, g, h)
// Output: hello 2 true {bar} 4.2 plop false 42
}
func ExampleUnpack9() {
a, b, c, d, e, f, g, h, i := Unpack9(T9("hello", 2, true, foo{bar: "bar"}, 4.2, "plop", false, 42, "hello world"))
fmt.Printf("%v %v %v %v %v %v %v %v %v", a, b, c, d, e, f, g, h, i)
// Output: hello 2 true {bar} 4.2 plop false 42 hello world
}
func ExampleZip2() {
result := Zip2([]string{"hello"}, []int{2})
fmt.Printf("%v", result)
// Output: [{hello 2}]
}
func ExampleZip3() {
result := Zip3([]string{"hello"}, []int{2}, []bool{true})
fmt.Printf("%v", result)
// Output: [{hello 2 true}]
}
func ExampleZip4() {
result := Zip4([]string{"hello"}, []int{2}, []bool{true}, []foo{{bar: "bar"}})
fmt.Printf("%v", result)
// Output: [{hello 2 true {bar}}]
}
func ExampleZip5() {
result := Zip5([]string{"hello"}, []int{2}, []bool{true}, []foo{{bar: "bar"}}, []float64{4.2})
fmt.Printf("%v", result)
// Output: [{hello 2 true {bar} 4.2}]
}
func ExampleZip6() {
result := Zip6([]string{"hello"}, []int{2}, []bool{true}, []foo{{bar: "bar"}}, []float64{4.2}, []string{"plop"})
fmt.Printf("%v", result)
// Output: [{hello 2 true {bar} 4.2 plop}]
}
func ExampleZip7() {
result := Zip7([]string{"hello"}, []int{2}, []bool{true}, []foo{{bar: "bar"}}, []float64{4.2}, []string{"plop"}, []bool{false})
fmt.Printf("%v", result)
// Output: [{hello 2 true {bar} 4.2 plop false}]
}
func ExampleZip8() {
result := Zip8([]string{"hello"}, []int{2}, []bool{true}, []foo{{bar: "bar"}}, []float64{4.2}, []string{"plop"}, []bool{false}, []int{42})
fmt.Printf("%v", result)
// Output: [{hello 2 true {bar} 4.2 plop false 42}]
}
func ExampleZip9() {
result := Zip9([]string{"hello"}, []int{2}, []bool{true}, []foo{{bar: "bar"}}, []float64{4.2}, []string{"plop"}, []bool{false}, []int{42}, []string{"hello world"})
fmt.Printf("%v", result)
// Output: [{hello 2 true {bar} 4.2 plop false 42 hello world}]
}
func ExampleUnzip2() {
a, b := Unzip2([]Tuple2[string, int]{T2("hello", 2)})
fmt.Printf("%v %v", a, b)
// Output: [hello] [2]
}
func ExampleUnzip3() {
a, b, c := Unzip3([]Tuple3[string, int, bool]{T3("hello", 2, true)})
fmt.Printf("%v %v %v", a, b, c)
// Output: [hello] [2] [true]
}
func ExampleUnzip4() {
a, b, c, d := Unzip4([]Tuple4[string, int, bool, foo]{T4("hello", 2, true, foo{bar: "bar"})})
fmt.Printf("%v %v %v %v", a, b, c, d)
// Output: [hello] [2] [true] [{bar}]
}
func ExampleUnzip5() {
a, b, c, d, e := Unzip5([]Tuple5[string, int, bool, foo, float64]{T5("hello", 2, true, foo{bar: "bar"}, 4.2)})
fmt.Printf("%v %v %v %v %v", a, b, c, d, e)
// Output: [hello] [2] [true] [{bar}] [4.2]
}
func ExampleUnzip6() {
a, b, c, d, e, f := Unzip6([]Tuple6[string, int, bool, foo, float64, string]{T6("hello", 2, true, foo{bar: "bar"}, 4.2, "plop")})
fmt.Printf("%v %v %v %v %v %v", a, b, c, d, e, f)
// Output: [hello] [2] [true] [{bar}] [4.2] [plop]
}
func ExampleUnzip7() {
a, b, c, d, e, f, g := Unzip7([]Tuple7[string, int, bool, foo, float64, string, bool]{T7("hello", 2, true, foo{bar: "bar"}, 4.2, "plop", false)})
fmt.Printf("%v %v %v %v %v %v %v", a, b, c, d, e, f, g)
// Output: [hello] [2] [true] [{bar}] [4.2] [plop] [false]
}
func ExampleUnzip8() {
a, b, c, d, e, f, g, h := Unzip8([]Tuple8[string, int, bool, foo, float64, string, bool, int]{T8("hello", 2, true, foo{bar: "bar"}, 4.2, "plop", false, 42)})
fmt.Printf("%v %v %v %v %v %v %v %v", a, b, c, d, e, f, g, h)
// Output: [hello] [2] [true] [{bar}] [4.2] [plop] [false] [42]
}
func ExampleUnzip9() {
a, b, c, d, e, f, g, h, i := Unzip9([]Tuple9[string, int, bool, foo, float64, string, bool, int, string]{T9("hello", 2, true, foo{bar: "bar"}, 4.2, "plop", false, 42, "hello world")})
fmt.Printf("%v %v %v %v %v %v %v %v %v", a, b, c, d, e, f, g, h, i)
// Output: [hello] [2] [true] [{bar}] [4.2] [plop] [false] [42] [hello world]
}
func ExampleCrossJoin2() {
result := CrossJoin2([]string{"a", "b"}, []int{1, 2, 3, 4})
for _, r := range result {
fmt.Printf("%v\n", r)
}
// Output:
// {a 1}
// {a 2}
// {a 3}
// {a 4}
// {b 1}
// {b 2}
// {b 3}
// {b 4}
}
func ExampleCrossJoin3() {
result := CrossJoin3([]string{"a", "b"}, []int{1, 2, 3, 4}, []bool{true, false})
for _, r := range result {
fmt.Printf("%v\n", r)
}
// Output:
// {a 1 true}
// {a 1 false}
// {a 2 true}
// {a 2 false}
// {a 3 true}
// {a 3 false}
// {a 4 true}
// {a 4 false}
// {b 1 true}
// {b 1 false}
// {b 2 true}
// {b 2 false}
// {b 3 true}
// {b 3 false}
// {b 4 true}
// {b 4 false}
}
func ExampleCrossJoin4() {
result := CrossJoin4([]string{"a", "b"}, []int{1, 2, 3, 4}, []bool{true, false}, []foo{{bar: "bar"}})
for _, r := range result {
fmt.Printf("%v\n", r)
}
// Output:
// {a 1 true {bar}}
// {a 1 false {bar}}
// {a 2 true {bar}}
// {a 2 false {bar}}
// {a 3 true {bar}}
// {a 3 false {bar}}
// {a 4 true {bar}}
// {a 4 false {bar}}
// {b 1 true {bar}}
// {b 1 false {bar}}
// {b 2 true {bar}}
// {b 2 false {bar}}
// {b 3 true {bar}}
// {b 3 false {bar}}
// {b 4 true {bar}}
// {b 4 false {bar}}
}
func ExampleCrossJoin5() {
result := CrossJoin5([]string{"a", "b"}, []int{1, 2, 3, 4}, []bool{true, false}, []foo{{bar: "bar"}}, []float64{4.2})
for _, r := range result {
fmt.Printf("%v\n", r)
}
// Output:
// {a 1 true {bar} 4.2}
// {a 1 false {bar} 4.2}
// {a 2 true {bar} 4.2}
// {a 2 false {bar} 4.2}
// {a 3 true {bar} 4.2}
// {a 3 false {bar} 4.2}
// {a 4 true {bar} 4.2}
// {a 4 false {bar} 4.2}
// {b 1 true {bar} 4.2}
// {b 1 false {bar} 4.2}
// {b 2 true {bar} 4.2}
// {b 2 false {bar} 4.2}
// {b 3 true {bar} 4.2}
// {b 3 false {bar} 4.2}
// {b 4 true {bar} 4.2}
// {b 4 false {bar} 4.2}
}
func ExampleCrossJoin6() {
result := CrossJoin6([]string{"a", "b"}, []int{1, 2, 3, 4}, []bool{true, false}, []foo{{bar: "bar"}}, []float64{4.2}, []string{"plop"})
for _, r := range result {
fmt.Printf("%v\n", r)
}
// Output:
// {a 1 true {bar} 4.2 plop}
// {a 1 false {bar} 4.2 plop}
// {a 2 true {bar} 4.2 plop}
// {a 2 false {bar} 4.2 plop}
// {a 3 true {bar} 4.2 plop}
// {a 3 false {bar} 4.2 plop}
// {a 4 true {bar} 4.2 plop}
// {a 4 false {bar} 4.2 plop}
// {b 1 true {bar} 4.2 plop}
// {b 1 false {bar} 4.2 plop}
// {b 2 true {bar} 4.2 plop}
// {b 2 false {bar} 4.2 plop}
// {b 3 true {bar} 4.2 plop}
// {b 3 false {bar} 4.2 plop}
// {b 4 true {bar} 4.2 plop}
// {b 4 false {bar} 4.2 plop}
}
func ExampleCrossJoin7() {
result := CrossJoin7([]string{"a", "b"}, []int{1, 2, 3, 4}, []bool{true, false}, []foo{{bar: "bar"}}, []float64{4.2}, []string{"plop"}, []bool{false})
for _, r := range result {
fmt.Printf("%v\n", r)
}
// Output:
// {a 1 true {bar} 4.2 plop false}
// {a 1 false {bar} 4.2 plop false}
// {a 2 true {bar} 4.2 plop false}
// {a 2 false {bar} 4.2 plop false}
// {a 3 true {bar} 4.2 plop false}
// {a 3 false {bar} 4.2 plop false}
// {a 4 true {bar} 4.2 plop false}
// {a 4 false {bar} 4.2 plop false}
// {b 1 true {bar} 4.2 plop false}
// {b 1 false {bar} 4.2 plop false}
// {b 2 true {bar} 4.2 plop false}
// {b 2 false {bar} 4.2 plop false}
// {b 3 true {bar} 4.2 plop false}
// {b 3 false {bar} 4.2 plop false}
// {b 4 true {bar} 4.2 plop false}
// {b 4 false {bar} 4.2 plop false}
}
func ExampleCrossJoin8() {
result := CrossJoin8([]string{"a", "b"}, []int{1, 2, 3, 4}, []bool{true, false}, []foo{{bar: "bar"}}, []float64{4.2}, []string{"plop"}, []bool{false}, []int{42})
for _, r := range result {
fmt.Printf("%v\n", r)
}
// Output:
// {a 1 true {bar} 4.2 plop false 42}
// {a 1 false {bar} 4.2 plop false 42}
// {a 2 true {bar} 4.2 plop false 42}
// {a 2 false {bar} 4.2 plop false 42}
// {a 3 true {bar} 4.2 plop false 42}
// {a 3 false {bar} 4.2 plop false 42}
// {a 4 true {bar} 4.2 plop false 42}
// {a 4 false {bar} 4.2 plop false 42}
// {b 1 true {bar} 4.2 plop false 42}
// {b 1 false {bar} 4.2 plop false 42}
// {b 2 true {bar} 4.2 plop false 42}
// {b 2 false {bar} 4.2 plop false 42}
// {b 3 true {bar} 4.2 plop false 42}
// {b 3 false {bar} 4.2 plop false 42}
// {b 4 true {bar} 4.2 plop false 42}
// {b 4 false {bar} 4.2 plop false 42}
}
func ExampleCrossJoin9() {
result := CrossJoin9([]string{"a", "b"}, []int{1, 2, 3, 4}, []bool{true, false}, []foo{{bar: "bar"}}, []float64{4.2}, []string{"plop"}, []bool{false}, []int{42}, []string{"hello world"})
for _, r := range result {
fmt.Printf("%v\n", r)
}
// Output:
// {a 1 true {bar} 4.2 plop false 42 hello world}
// {a 1 false {bar} 4.2 plop false 42 hello world}
// {a 2 true {bar} 4.2 plop false 42 hello world}
// {a 2 false {bar} 4.2 plop false 42 hello world}
// {a 3 true {bar} 4.2 plop false 42 hello world}
// {a 3 false {bar} 4.2 plop false 42 hello world}
// {a 4 true {bar} 4.2 plop false 42 hello world}
// {a 4 false {bar} 4.2 plop false 42 hello world}
// {b 1 true {bar} 4.2 plop false 42 hello world}
// {b 1 false {bar} 4.2 plop false 42 hello world}
// {b 2 true {bar} 4.2 plop false 42 hello world}
// {b 2 false {bar} 4.2 plop false 42 hello world}
// {b 3 true {bar} 4.2 plop false 42 hello world}
// {b 3 false {bar} 4.2 plop false 42 hello world}
// {b 4 true {bar} 4.2 plop false 42 hello world}
// {b 4 false {bar} 4.2 plop false 42 hello world}
}
func ExampleCrossJoinBy2() {
result := CrossJoinBy2([]string{"a", "b"}, []int{1, 2, 3, 4}, func(a string, b int) string {
return fmt.Sprintf("%v-%v", a, b)
})
for _, r := range result {
fmt.Printf("%v\n", r)
}
// Output:
// a-1
// a-2
// a-3
// a-4
// b-1
// b-2
// b-3
// b-4
}
func ExampleCrossJoinBy3() {
result := CrossJoinBy3([]string{"a", "b"}, []int{1, 2, 3, 4}, []bool{true, false}, func(a string, b int, c bool) string {
return fmt.Sprintf("%v-%v-%v", a, b, c)
})
for _, r := range result {
fmt.Printf("%v\n", r)
}
// Output:
// a-1-true
// a-1-false
// a-2-true
// a-2-false
// a-3-true
// a-3-false
// a-4-true
// a-4-false
// b-1-true
// b-1-false
// b-2-true
// b-2-false
// b-3-true
// b-3-false
// b-4-true
// b-4-false
}
func ExampleCrossJoinBy4() {
result := CrossJoinBy4([]string{"a", "b"}, []int{1, 2, 3, 4}, []bool{true, false}, []foo{{bar: "bar"}}, func(a string, b int, c bool, d foo) string {
return fmt.Sprintf("%v-%v-%v-%v", a, b, c, d)
})
for _, r := range result {
fmt.Printf("%v\n", r)
}
// Output:
// a-1-true-{bar}
// a-1-false-{bar}
// a-2-true-{bar}
// a-2-false-{bar}
// a-3-true-{bar}
// a-3-false-{bar}
// a-4-true-{bar}
// a-4-false-{bar}
// b-1-true-{bar}
// b-1-false-{bar}
// b-2-true-{bar}
// b-2-false-{bar}
// b-3-true-{bar}
// b-3-false-{bar}
// b-4-true-{bar}
// b-4-false-{bar}
}
func ExampleCrossJoinBy5() {
result := CrossJoinBy5([]string{"a", "b"}, []int{1, 2, 3, 4}, []bool{true, false}, []foo{{bar: "bar"}}, []float64{4.2}, func(a string, b int, c bool, d foo, e float64) string {
return fmt.Sprintf("%v-%v-%v-%v-%v", a, b, c, d, e)
})
for _, r := range result {
fmt.Printf("%v\n", r)
}
// Output:
// a-1-true-{bar}-4.2
// a-1-false-{bar}-4.2
// a-2-true-{bar}-4.2
// a-2-false-{bar}-4.2
// a-3-true-{bar}-4.2
// a-3-false-{bar}-4.2
// a-4-true-{bar}-4.2
// a-4-false-{bar}-4.2
// b-1-true-{bar}-4.2
// b-1-false-{bar}-4.2
// b-2-true-{bar}-4.2
// b-2-false-{bar}-4.2
// b-3-true-{bar}-4.2
// b-3-false-{bar}-4.2
// b-4-true-{bar}-4.2
// b-4-false-{bar}-4.2
}
func ExampleCrossJoinBy6() {
result := CrossJoinBy6([]string{"a", "b"}, []int{1, 2, 3, 4}, []bool{true, false}, []foo{{bar: "bar"}}, []float64{4.2}, []string{"plop"}, func(a string, b int, c bool, d foo, e float64, f string) string {
return fmt.Sprintf("%v-%v-%v-%v-%v-%v", a, b, c, d, e, f)
})
for _, r := range result {
fmt.Printf("%v\n", r)
}
// Output:
// a-1-true-{bar}-4.2-plop
// a-1-false-{bar}-4.2-plop
// a-2-true-{bar}-4.2-plop
// a-2-false-{bar}-4.2-plop
// a-3-true-{bar}-4.2-plop
// a-3-false-{bar}-4.2-plop
// a-4-true-{bar}-4.2-plop
// a-4-false-{bar}-4.2-plop
// b-1-true-{bar}-4.2-plop
// b-1-false-{bar}-4.2-plop
// b-2-true-{bar}-4.2-plop
// b-2-false-{bar}-4.2-plop
// b-3-true-{bar}-4.2-plop
// b-3-false-{bar}-4.2-plop
// b-4-true-{bar}-4.2-plop
// b-4-false-{bar}-4.2-plop
}
func ExampleCrossJoinBy7() {
result := CrossJoinBy7([]string{"a", "b"}, []int{1, 2, 3, 4}, []bool{true, false}, []foo{{bar: "bar"}}, []float64{4.2}, []string{"plop"}, []bool{false}, func(a string, b int, c bool, d foo, e float64, f string, g bool) string {
return fmt.Sprintf("%v-%v-%v-%v-%v-%v-%v", a, b, c, d, e, f, g)
})
for _, r := range result {
fmt.Printf("%v\n", r)
}
// Output:
// a-1-true-{bar}-4.2-plop-false
// a-1-false-{bar}-4.2-plop-false
// a-2-true-{bar}-4.2-plop-false
// a-2-false-{bar}-4.2-plop-false
// a-3-true-{bar}-4.2-plop-false
// a-3-false-{bar}-4.2-plop-false
// a-4-true-{bar}-4.2-plop-false
// a-4-false-{bar}-4.2-plop-false
// b-1-true-{bar}-4.2-plop-false
// b-1-false-{bar}-4.2-plop-false
// b-2-true-{bar}-4.2-plop-false
// b-2-false-{bar}-4.2-plop-false
// b-3-true-{bar}-4.2-plop-false
// b-3-false-{bar}-4.2-plop-false
// b-4-true-{bar}-4.2-plop-false
// b-4-false-{bar}-4.2-plop-false
}
func ExampleCrossJoinBy8() {
result := CrossJoinBy8([]string{"a", "b"}, []int{1, 2, 3, 4}, []bool{true, false}, []foo{{bar: "bar"}}, []float64{4.2}, []string{"plop"}, []bool{false}, []int{42}, func(a string, b int, c bool, d foo, e float64, f string, g bool, h int) string {
return fmt.Sprintf("%v-%v-%v-%v-%v-%v-%v-%v", a, b, c, d, e, f, g, h)
})
for _, r := range result {
fmt.Printf("%v\n", r)
}
// Output:
// a-1-true-{bar}-4.2-plop-false-42
// a-1-false-{bar}-4.2-plop-false-42
// a-2-true-{bar}-4.2-plop-false-42
// a-2-false-{bar}-4.2-plop-false-42
// a-3-true-{bar}-4.2-plop-false-42
// a-3-false-{bar}-4.2-plop-false-42
// a-4-true-{bar}-4.2-plop-false-42
// a-4-false-{bar}-4.2-plop-false-42
// b-1-true-{bar}-4.2-plop-false-42
// b-1-false-{bar}-4.2-plop-false-42
// b-2-true-{bar}-4.2-plop-false-42
// b-2-false-{bar}-4.2-plop-false-42
// b-3-true-{bar}-4.2-plop-false-42
// b-3-false-{bar}-4.2-plop-false-42
// b-4-true-{bar}-4.2-plop-false-42
// b-4-false-{bar}-4.2-plop-false-42
}
func ExampleCrossJoinBy9() {
result := CrossJoinBy9([]string{"a", "b"}, []int{1, 2, 3, 4}, []bool{true, false}, []foo{{bar: "bar"}}, []float64{4.2}, []string{"plop"}, []bool{false}, []int{42}, []string{"hello world"}, func(a string, b int, c bool, d foo, e float64, f string, g bool, h int, i string) string {
return fmt.Sprintf("%v-%v-%v-%v-%v-%v-%v-%v-%v", a, b, c, d, e, f, g, h, i)
})
for _, r := range result {
fmt.Printf("%v\n", r)
}
// Output:
// a-1-true-{bar}-4.2-plop-false-42-hello world
// a-1-false-{bar}-4.2-plop-false-42-hello world
// a-2-true-{bar}-4.2-plop-false-42-hello world
// a-2-false-{bar}-4.2-plop-false-42-hello world
// a-3-true-{bar}-4.2-plop-false-42-hello world
// a-3-false-{bar}-4.2-plop-false-42-hello world
// a-4-true-{bar}-4.2-plop-false-42-hello world
// a-4-false-{bar}-4.2-plop-false-42-hello world
// b-1-true-{bar}-4.2-plop-false-42-hello world
// b-1-false-{bar}-4.2-plop-false-42-hello world
// b-2-true-{bar}-4.2-plop-false-42-hello world
// b-2-false-{bar}-4.2-plop-false-42-hello world
// b-3-true-{bar}-4.2-plop-false-42-hello world
// b-3-false-{bar}-4.2-plop-false-42-hello world
// b-4-true-{bar}-4.2-plop-false-42-hello world
// b-4-false-{bar}-4.2-plop-false-42-hello world
}

View File

@@ -1,593 +0,0 @@
package lo
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestT(t *testing.T) {
t.Parallel()
is := assert.New(t)
r1 := T2("a", 1)
r2 := T3[string, int, float32]("b", 2, 3.0)
r3 := T4[string, int, float32]("c", 3, 4.0, true)
r4 := T5[string, int, float32]("d", 4, 5.0, false, "e")
r5 := T6[string, int, float32]("f", 5, 6.0, true, "g", 7)
r6 := T7[string, int, float32]("h", 6, 7.0, false, "i", 8, 9.0)
r7 := T8[string, int, float32]("j", 7, 8.0, true, "k", 9, 10.0, false)
r8 := T9[string, int, float32]("l", 8, 9.0, false, "m", 10, 11.0, true, "n")
is.Equal(r1, Tuple2[string, int]{A: "a", B: 1})
is.Equal(r2, Tuple3[string, int, float32]{A: "b", B: 2, C: 3.0})
is.Equal(r3, Tuple4[string, int, float32, bool]{A: "c", B: 3, C: 4.0, D: true})
is.Equal(r4, Tuple5[string, int, float32, bool, string]{A: "d", B: 4, C: 5.0, D: false, E: "e"})
is.Equal(r5, Tuple6[string, int, float32, bool, string, int]{A: "f", B: 5, C: 6.0, D: true, E: "g", F: 7})
is.Equal(r6, Tuple7[string, int, float32, bool, string, int, float64]{A: "h", B: 6, C: 7.0, D: false, E: "i", F: 8, G: 9.0})
is.Equal(r7, Tuple8[string, int, float32, bool, string, int, float64, bool]{A: "j", B: 7, C: 8.0, D: true, E: "k", F: 9, G: 10.0, H: false})
is.Equal(r8, Tuple9[string, int, float32, bool, string, int, float64, bool, string]{A: "l", B: 8, C: 9.0, D: false, E: "m", F: 10, G: 11.0, H: true, I: "n"})
}
func TestUnpack(t *testing.T) {
t.Parallel()
is := assert.New(t)
{
tuple := Tuple2[string, int]{"a", 1}
r1, r2 := Unpack2(tuple)
is.Equal("a", r1)
is.Equal(1, r2)
r1, r2 = tuple.Unpack()
is.Equal("a", r1)
is.Equal(1, r2)
}
{
tuple := Tuple3[string, int, float64]{"a", 1, 1.0}
r1, r2, r3 := Unpack3(tuple)
is.Equal("a", r1)
is.Equal(1, r2)
is.Equal(1.0, r3)
r1, r2, r3 = tuple.Unpack()
is.Equal("a", r1)
is.Equal(1, r2)
is.Equal(1.0, r3)
}
{
tuple := Tuple4[string, int, float64, bool]{"a", 1, 1.0, true}
r1, r2, r3, r4 := Unpack4(tuple)
is.Equal("a", r1)
is.Equal(1, r2)
is.Equal(1.0, r3)
is.Equal(true, r4)
r1, r2, r3, r4 = tuple.Unpack()
is.Equal("a", r1)
is.Equal(1, r2)
is.Equal(1.0, r3)
is.Equal(true, r4)
}
{
tuple := Tuple5[string, int, float64, bool, string]{"a", 1, 1.0, true, "b"}
r1, r2, r3, r4, r5 := Unpack5(tuple)
is.Equal("a", r1)
is.Equal(1, r2)
is.Equal(1.0, r3)
is.Equal(true, r4)
is.Equal("b", r5)
r1, r2, r3, r4, r5 = tuple.Unpack()
is.Equal("a", r1)
is.Equal(1, r2)
is.Equal(1.0, r3)
is.Equal(true, r4)
is.Equal("b", r5)
}
{
tuple := Tuple6[string, int, float64, bool, string, int]{"a", 1, 1.0, true, "b", 2}
r1, r2, r3, r4, r5, r6 := Unpack6(tuple)
is.Equal("a", r1)
is.Equal(1, r2)
is.Equal(1.0, r3)
is.Equal(true, r4)
is.Equal("b", r5)
is.Equal(2, r6)
r1, r2, r3, r4, r5, r6 = tuple.Unpack()
is.Equal("a", r1)
is.Equal(1, r2)
is.Equal(1.0, r3)
is.Equal(true, r4)
is.Equal("b", r5)
is.Equal(2, r6)
}
{
tuple := Tuple7[string, int, float64, bool, string, int, float64]{"a", 1, 1.0, true, "b", 2, 3.0}
r1, r2, r3, r4, r5, r6, r7 := Unpack7(tuple)
is.Equal("a", r1)
is.Equal(1, r2)
is.Equal(1.0, r3)
is.Equal(true, r4)
is.Equal("b", r5)
is.Equal(2, r6)
is.Equal(3.0, r7)
r1, r2, r3, r4, r5, r6, r7 = tuple.Unpack()
is.Equal("a", r1)
is.Equal(1, r2)
is.Equal(1.0, r3)
is.Equal(true, r4)
is.Equal("b", r5)
is.Equal(2, r6)
is.Equal(3.0, r7)
}
{
tuple := Tuple8[string, int, float64, bool, string, int, float64, bool]{"a", 1, 1.0, true, "b", 2, 3.0, true}
r1, r2, r3, r4, r5, r6, r7, r8 := Unpack8(tuple)
is.Equal("a", r1)
is.Equal(1, r2)
is.Equal(1.0, r3)
is.Equal(true, r4)
is.Equal("b", r5)
is.Equal(2, r6)
is.Equal(3.0, r7)
is.Equal(true, r8)
r1, r2, r3, r4, r5, r6, r7, r8 = tuple.Unpack()
is.Equal("a", r1)
is.Equal(1, r2)
is.Equal(1.0, r3)
is.Equal(true, r4)
is.Equal("b", r5)
is.Equal(2, r6)
is.Equal(3.0, r7)
is.Equal(true, r8)
}
{
tuple := Tuple9[string, int, float64, bool, string, int, float64, bool, string]{"a", 1, 1.0, true, "b", 2, 3.0, true, "c"}
r1, r2, r3, r4, r5, r6, r7, r8, r9 := Unpack9(tuple)
is.Equal("a", r1)
is.Equal(1, r2)
is.Equal(1.0, r3)
is.Equal(true, r4)
is.Equal("b", r5)
is.Equal(2, r6)
is.Equal(3.0, r7)
is.Equal(true, r8)
is.Equal("c", r9)
r1, r2, r3, r4, r5, r6, r7, r8, r9 = tuple.Unpack()
is.Equal("a", r1)
is.Equal(1, r2)
is.Equal(1.0, r3)
is.Equal(true, r4)
is.Equal("b", r5)
is.Equal(2, r6)
is.Equal(3.0, r7)
is.Equal(true, r8)
is.Equal("c", r9)
}
}
func TestZip(t *testing.T) {
t.Parallel()
is := assert.New(t)
r1 := Zip2(
[]string{"a", "b"},
[]int{1, 2},
)
r2 := Zip3(
[]string{"a", "b", "c"},
[]int{1, 2, 3},
[]int{4, 5, 6},
)
r3 := Zip4(
[]string{"a", "b", "c", "d"},
[]int{1, 2, 3, 4},
[]int{5, 6, 7, 8},
[]bool{true, true, true, true},
)
r4 := Zip5(
[]string{"a", "b", "c", "d", "e"},
[]int{1, 2, 3, 4, 5},
[]int{6, 7, 8, 9, 10},
[]bool{true, true, true, true, true},
[]float32{0.1, 0.2, 0.3, 0.4, 0.5},
)
r5 := Zip6(
[]string{"a", "b", "c", "d", "e", "f"},
[]int{1, 2, 3, 4, 5, 6},
[]int{7, 8, 9, 10, 11, 12},
[]bool{true, true, true, true, true, true},
[]float32{0.1, 0.2, 0.3, 0.4, 0.5, 0.6},
[]float64{0.01, 0.02, 0.03, 0.04, 0.05, 0.06},
)
r6 := Zip7(
[]string{"a", "b", "c", "d", "e", "f", "g"},
[]int{1, 2, 3, 4, 5, 6, 7},
[]int{8, 9, 10, 11, 12, 13, 14},
[]bool{true, true, true, true, true, true, true},
[]float32{0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7},
[]float64{0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07},
[]int8{1, 2, 3, 4, 5, 6, 7},
)
r7 := Zip8(
[]string{"a", "b", "c", "d", "e", "f", "g", "h"},
[]int{1, 2, 3, 4, 5, 6, 7, 8},
[]int{9, 10, 11, 12, 13, 14, 15, 16},
[]bool{true, true, true, true, true, true, true, true},
[]float32{0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8},
[]float64{0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08},
[]int8{1, 2, 3, 4, 5, 6, 7, 8},
[]int16{1, 2, 3, 4, 5, 6, 7, 8},
)
r8 := Zip9(
[]string{"a", "b", "c", "d", "e", "f", "g", "h", "i"},
[]int{1, 2, 3, 4, 5, 6, 7, 8, 9},
[]int{10, 11, 12, 13, 14, 15, 16, 17, 18},
[]bool{true, true, true, true, true, true, true, true, true},
[]float32{0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9},
[]float64{0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08, 0.09},
[]int8{1, 2, 3, 4, 5, 6, 7, 8, 9},
[]int16{1, 2, 3, 4, 5, 6, 7, 8, 9},
[]int32{1, 2, 3, 4, 5, 6, 7, 8, 9},
)
is.Equal(r1, []Tuple2[string, int]{
{A: "a", B: 1},
{A: "b", B: 2},
})
is.Equal(r2, []Tuple3[string, int, int]{
{A: "a", B: 1, C: 4},
{A: "b", B: 2, C: 5},
{A: "c", B: 3, C: 6},
})
is.Equal(r3, []Tuple4[string, int, int, bool]{
{A: "a", B: 1, C: 5, D: true},
{A: "b", B: 2, C: 6, D: true},
{A: "c", B: 3, C: 7, D: true},
{A: "d", B: 4, C: 8, D: true},
})
is.Equal(r4, []Tuple5[string, int, int, bool, float32]{
{A: "a", B: 1, C: 6, D: true, E: 0.1},
{A: "b", B: 2, C: 7, D: true, E: 0.2},
{A: "c", B: 3, C: 8, D: true, E: 0.3},
{A: "d", B: 4, C: 9, D: true, E: 0.4},
{A: "e", B: 5, C: 10, D: true, E: 0.5},
})
is.Equal(r5, []Tuple6[string, int, int, bool, float32, float64]{
{A: "a", B: 1, C: 7, D: true, E: 0.1, F: 0.01},
{A: "b", B: 2, C: 8, D: true, E: 0.2, F: 0.02},
{A: "c", B: 3, C: 9, D: true, E: 0.3, F: 0.03},
{A: "d", B: 4, C: 10, D: true, E: 0.4, F: 0.04},
{A: "e", B: 5, C: 11, D: true, E: 0.5, F: 0.05},
{A: "f", B: 6, C: 12, D: true, E: 0.6, F: 0.06},
})
is.Equal(r6, []Tuple7[string, int, int, bool, float32, float64, int8]{
{A: "a", B: 1, C: 8, D: true, E: 0.1, F: 0.01, G: 1},
{A: "b", B: 2, C: 9, D: true, E: 0.2, F: 0.02, G: 2},
{A: "c", B: 3, C: 10, D: true, E: 0.3, F: 0.03, G: 3},
{A: "d", B: 4, C: 11, D: true, E: 0.4, F: 0.04, G: 4},
{A: "e", B: 5, C: 12, D: true, E: 0.5, F: 0.05, G: 5},
{A: "f", B: 6, C: 13, D: true, E: 0.6, F: 0.06, G: 6},
{A: "g", B: 7, C: 14, D: true, E: 0.7, F: 0.07, G: 7},
})
is.Equal(r7, []Tuple8[string, int, int, bool, float32, float64, int8, int16]{
{A: "a", B: 1, C: 9, D: true, E: 0.1, F: 0.01, G: 1, H: 1},
{A: "b", B: 2, C: 10, D: true, E: 0.2, F: 0.02, G: 2, H: 2},
{A: "c", B: 3, C: 11, D: true, E: 0.3, F: 0.03, G: 3, H: 3},
{A: "d", B: 4, C: 12, D: true, E: 0.4, F: 0.04, G: 4, H: 4},
{A: "e", B: 5, C: 13, D: true, E: 0.5, F: 0.05, G: 5, H: 5},
{A: "f", B: 6, C: 14, D: true, E: 0.6, F: 0.06, G: 6, H: 6},
{A: "g", B: 7, C: 15, D: true, E: 0.7, F: 0.07, G: 7, H: 7},
{A: "h", B: 8, C: 16, D: true, E: 0.8, F: 0.08, G: 8, H: 8},
})
is.Equal(r8, []Tuple9[string, int, int, bool, float32, float64, int8, int16, int32]{
{A: "a", B: 1, C: 10, D: true, E: 0.1, F: 0.01, G: 1, H: 1, I: 1},
{A: "b", B: 2, C: 11, D: true, E: 0.2, F: 0.02, G: 2, H: 2, I: 2},
{A: "c", B: 3, C: 12, D: true, E: 0.3, F: 0.03, G: 3, H: 3, I: 3},
{A: "d", B: 4, C: 13, D: true, E: 0.4, F: 0.04, G: 4, H: 4, I: 4},
{A: "e", B: 5, C: 14, D: true, E: 0.5, F: 0.05, G: 5, H: 5, I: 5},
{A: "f", B: 6, C: 15, D: true, E: 0.6, F: 0.06, G: 6, H: 6, I: 6},
{A: "g", B: 7, C: 16, D: true, E: 0.7, F: 0.07, G: 7, H: 7, I: 7},
{A: "h", B: 8, C: 17, D: true, E: 0.8, F: 0.08, G: 8, H: 8, I: 8},
{A: "i", B: 9, C: 18, D: true, E: 0.9, F: 0.09, G: 9, H: 9, I: 9},
})
}
func TestZipBy(t *testing.T) {
t.Parallel()
is := assert.New(t)
r1 := ZipBy2(
[]string{"a", "b"},
[]int{1, 2},
func(a string, b int) Tuple2[string, int] {
return T2(a, b)
},
)
r2 := ZipBy3(
[]string{"a", "b", "c"},
[]int{1, 2, 3},
[]int{4, 5, 6},
func(a string, b int, c int) Tuple3[string, int, int] {
return T3(a, b, c)
},
)
r3 := ZipBy4(
[]string{"a", "b", "c", "d"},
[]int{1, 2, 3, 4},
[]int{5, 6, 7, 8},
[]bool{true, true, true, true},
func(a string, b int, c int, d bool) Tuple4[string, int, int, bool] {
return T4(a, b, c, d)
},
)
r4 := ZipBy5(
[]string{"a", "b", "c", "d", "e"},
[]int{1, 2, 3, 4, 5},
[]int{6, 7, 8, 9, 10},
[]bool{true, true, true, true, true},
[]float32{0.1, 0.2, 0.3, 0.4, 0.5},
func(a string, b int, c int, d bool, e float32) Tuple5[string, int, int, bool, float32] {
return T5(a, b, c, d, e)
},
)
r5 := ZipBy6(
[]string{"a", "b", "c", "d", "e", "f"},
[]int{1, 2, 3, 4, 5, 6},
[]int{7, 8, 9, 10, 11, 12},
[]bool{true, true, true, true, true, true},
[]float32{0.1, 0.2, 0.3, 0.4, 0.5, 0.6},
[]float64{0.01, 0.02, 0.03, 0.04, 0.05, 0.06},
func(a string, b int, c int, d bool, e float32, f float64) Tuple6[string, int, int, bool, float32, float64] {
return T6(a, b, c, d, e, f)
},
)
r6 := ZipBy7(
[]string{"a", "b", "c", "d", "e", "f", "g"},
[]int{1, 2, 3, 4, 5, 6, 7},
[]int{8, 9, 10, 11, 12, 13, 14},
[]bool{true, true, true, true, true, true, true},
[]float32{0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7},
[]float64{0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07},
[]int8{1, 2, 3, 4, 5, 6, 7},
func(a string, b int, c int, d bool, e float32, f float64, g int8) Tuple7[string, int, int, bool, float32, float64, int8] {
return T7(a, b, c, d, e, f, g)
},
)
r7 := ZipBy8(
[]string{"a", "b", "c", "d", "e", "f", "g", "h"},
[]int{1, 2, 3, 4, 5, 6, 7, 8},
[]int{9, 10, 11, 12, 13, 14, 15, 16},
[]bool{true, true, true, true, true, true, true, true},
[]float32{0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8},
[]float64{0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08},
[]int8{1, 2, 3, 4, 5, 6, 7, 8},
[]int16{1, 2, 3, 4, 5, 6, 7, 8},
func(a string, b int, c int, d bool, e float32, f float64, g int8, h int16) Tuple8[string, int, int, bool, float32, float64, int8, int16] {
return T8(a, b, c, d, e, f, g, h)
},
)
r8 := ZipBy9(
[]string{"a", "b", "c", "d", "e", "f", "g", "h", "i"},
[]int{1, 2, 3, 4, 5, 6, 7, 8, 9},
[]int{10, 11, 12, 13, 14, 15, 16, 17, 18},
[]bool{true, true, true, true, true, true, true, true, true},
[]float32{0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9},
[]float64{0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08, 0.09},
[]int8{1, 2, 3, 4, 5, 6, 7, 8, 9},
[]int16{1, 2, 3, 4, 5, 6, 7, 8, 9},
[]int32{1, 2, 3, 4, 5, 6, 7, 8, 9},
func(a string, b int, c int, d bool, e float32, f float64, g int8, h int16, i int32) Tuple9[string, int, int, bool, float32, float64, int8, int16, int32] {
return T9(a, b, c, d, e, f, g, h, i)
},
)
is.Equal(r1, []Tuple2[string, int]{
{A: "a", B: 1},
{A: "b", B: 2},
})
is.Equal(r2, []Tuple3[string, int, int]{
{A: "a", B: 1, C: 4},
{A: "b", B: 2, C: 5},
{A: "c", B: 3, C: 6},
})
is.Equal(r3, []Tuple4[string, int, int, bool]{
{A: "a", B: 1, C: 5, D: true},
{A: "b", B: 2, C: 6, D: true},
{A: "c", B: 3, C: 7, D: true},
{A: "d", B: 4, C: 8, D: true},
})
is.Equal(r4, []Tuple5[string, int, int, bool, float32]{
{A: "a", B: 1, C: 6, D: true, E: 0.1},
{A: "b", B: 2, C: 7, D: true, E: 0.2},
{A: "c", B: 3, C: 8, D: true, E: 0.3},
{A: "d", B: 4, C: 9, D: true, E: 0.4},
{A: "e", B: 5, C: 10, D: true, E: 0.5},
})
is.Equal(r5, []Tuple6[string, int, int, bool, float32, float64]{
{A: "a", B: 1, C: 7, D: true, E: 0.1, F: 0.01},
{A: "b", B: 2, C: 8, D: true, E: 0.2, F: 0.02},
{A: "c", B: 3, C: 9, D: true, E: 0.3, F: 0.03},
{A: "d", B: 4, C: 10, D: true, E: 0.4, F: 0.04},
{A: "e", B: 5, C: 11, D: true, E: 0.5, F: 0.05},
{A: "f", B: 6, C: 12, D: true, E: 0.6, F: 0.06},
})
is.Equal(r6, []Tuple7[string, int, int, bool, float32, float64, int8]{
{A: "a", B: 1, C: 8, D: true, E: 0.1, F: 0.01, G: 1},
{A: "b", B: 2, C: 9, D: true, E: 0.2, F: 0.02, G: 2},
{A: "c", B: 3, C: 10, D: true, E: 0.3, F: 0.03, G: 3},
{A: "d", B: 4, C: 11, D: true, E: 0.4, F: 0.04, G: 4},
{A: "e", B: 5, C: 12, D: true, E: 0.5, F: 0.05, G: 5},
{A: "f", B: 6, C: 13, D: true, E: 0.6, F: 0.06, G: 6},
{A: "g", B: 7, C: 14, D: true, E: 0.7, F: 0.07, G: 7},
})
is.Equal(r7, []Tuple8[string, int, int, bool, float32, float64, int8, int16]{
{A: "a", B: 1, C: 9, D: true, E: 0.1, F: 0.01, G: 1, H: 1},
{A: "b", B: 2, C: 10, D: true, E: 0.2, F: 0.02, G: 2, H: 2},
{A: "c", B: 3, C: 11, D: true, E: 0.3, F: 0.03, G: 3, H: 3},
{A: "d", B: 4, C: 12, D: true, E: 0.4, F: 0.04, G: 4, H: 4},
{A: "e", B: 5, C: 13, D: true, E: 0.5, F: 0.05, G: 5, H: 5},
{A: "f", B: 6, C: 14, D: true, E: 0.6, F: 0.06, G: 6, H: 6},
{A: "g", B: 7, C: 15, D: true, E: 0.7, F: 0.07, G: 7, H: 7},
{A: "h", B: 8, C: 16, D: true, E: 0.8, F: 0.08, G: 8, H: 8},
})
is.Equal(r8, []Tuple9[string, int, int, bool, float32, float64, int8, int16, int32]{
{A: "a", B: 1, C: 10, D: true, E: 0.1, F: 0.01, G: 1, H: 1, I: 1},
{A: "b", B: 2, C: 11, D: true, E: 0.2, F: 0.02, G: 2, H: 2, I: 2},
{A: "c", B: 3, C: 12, D: true, E: 0.3, F: 0.03, G: 3, H: 3, I: 3},
{A: "d", B: 4, C: 13, D: true, E: 0.4, F: 0.04, G: 4, H: 4, I: 4},
{A: "e", B: 5, C: 14, D: true, E: 0.5, F: 0.05, G: 5, H: 5, I: 5},
{A: "f", B: 6, C: 15, D: true, E: 0.6, F: 0.06, G: 6, H: 6, I: 6},
{A: "g", B: 7, C: 16, D: true, E: 0.7, F: 0.07, G: 7, H: 7, I: 7},
{A: "h", B: 8, C: 17, D: true, E: 0.8, F: 0.08, G: 8, H: 8, I: 8},
{A: "i", B: 9, C: 18, D: true, E: 0.9, F: 0.09, G: 9, H: 9, I: 9},
})
}
func TestUnzip(t *testing.T) {
t.Parallel()
is := assert.New(t)
r1, r2 := Unzip2([]Tuple2[string, int]{{A: "a", B: 1}, {A: "b", B: 2}})
is.Equal(r1, []string{"a", "b"})
is.Equal(r2, []int{1, 2})
}
func TestUnzipBy(t *testing.T) {
t.Parallel()
is := assert.New(t)
r1, r2 := UnzipBy2([]Tuple2[string, int]{{A: "a", B: 1}, {A: "b", B: 2}}, func(i Tuple2[string, int]) (a string, b int) {
return i.A + i.A, i.B + i.B
})
is.Equal(r1, []string{"aa", "bb"})
is.Equal(r2, []int{2, 4})
}
func TestCrossJoin(t *testing.T) {
t.Parallel()
is := assert.New(t)
listOne := []string{"a", "b", "c"}
listTwo := []int{1, 2, 3}
emptyList := []any{}
mixedList := []any{9.6, 4, "foobar"}
results1 := CrossJoin2(emptyList, listTwo)
is.Len(results1, 0)
results2 := CrossJoin2(listOne, emptyList)
is.Len(results2, 0)
results3 := CrossJoin2(emptyList, emptyList)
is.Len(results3, 0)
results4 := CrossJoin2([]string{"a"}, listTwo)
is.Equal([]Tuple2[string, int]{T2("a", 1), T2("a", 2), T2("a", 3)}, results4)
results5 := CrossJoin2(listOne, []int{1})
is.Equal([]Tuple2[string, int]{T2("a", 1), T2("b", 1), T2("c", 1)}, results5)
results6 := CrossJoin2(listOne, listTwo)
is.Equal([]Tuple2[string, int]{T2("a", 1), T2("a", 2), T2("a", 3), T2("b", 1), T2("b", 2), T2("b", 3), T2("c", 1), T2("c", 2), T2("c", 3)}, results6)
results7 := CrossJoin2(listOne, mixedList)
is.Equal([]Tuple2[string, any]{T2[string, any]("a", 9.6), T2[string, any]("a", 4), T2[string, any]("a", "foobar"), T2[string, any]("b", 9.6), T2[string, any]("b", 4), T2[string, any]("b", "foobar"), T2[string, any]("c", 9.6), T2[string, any]("c", 4), T2[string, any]("c", "foobar")}, results7)
}
func TestCrossJoinBy(t *testing.T) {
t.Parallel()
is := assert.New(t)
listOne := []string{"a", "b", "c"}
listTwo := []int{1, 2, 3}
emptyList := []any{}
mixedList := []any{9.6, 4, "foobar"}
results1 := CrossJoinBy2(emptyList, listTwo, T2[any, int])
is.Len(results1, 0)
results2 := CrossJoinBy2(listOne, emptyList, T2[string, any])
is.Len(results2, 0)
results3 := CrossJoinBy2(emptyList, emptyList, T2[any, any])
is.Len(results3, 0)
results4 := CrossJoinBy2([]string{"a"}, listTwo, T2[string, int])
is.Equal([]Tuple2[string, int]{T2("a", 1), T2("a", 2), T2("a", 3)}, results4)
results5 := CrossJoinBy2(listOne, []int{1}, T2[string, int])
is.Equal([]Tuple2[string, int]{T2("a", 1), T2("b", 1), T2("c", 1)}, results5)
results6 := CrossJoinBy2(listOne, listTwo, T2[string, int])
is.Equal([]Tuple2[string, int]{T2("a", 1), T2("a", 2), T2("a", 3), T2("b", 1), T2("b", 2), T2("b", 3), T2("c", 1), T2("c", 2), T2("c", 3)}, results6)
results7 := CrossJoinBy2(listOne, mixedList, T2[string, any])
is.Equal([]Tuple2[string, any]{T2[string, any]("a", 9.6), T2[string, any]("a", 4), T2[string, any]("a", "foobar"), T2[string, any]("b", 9.6), T2[string, any]("b", 4), T2[string, any]("b", "foobar"), T2[string, any]("c", 9.6), T2[string, any]("c", 4), T2[string, any]("c", "foobar")}, results7)
}

View File

@@ -1,568 +0,0 @@
package lo
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestIsNil(t *testing.T) {
t.Parallel()
is := assert.New(t)
var x int
is.False(IsNil(x))
var k struct{}
is.False(IsNil(k))
var s *string
is.True(IsNil(s))
var i *int
is.True(IsNil(i))
var b *bool
is.True(IsNil(b))
var ifaceWithNilValue any = (*string)(nil) //nolint:staticcheck
is.True(IsNil(ifaceWithNilValue))
is.False(ifaceWithNilValue == nil) //nolint:staticcheck
}
func TestIsNotNil(t *testing.T) {
t.Parallel()
is := assert.New(t)
var x int
is.True(IsNotNil(x))
var k struct{}
is.True(IsNotNil(k))
var s *string
is.False(IsNotNil(s))
var i *int
is.False(IsNotNil(i))
var b *bool
is.False(IsNotNil(b))
var ifaceWithNilValue any = (*string)(nil) //nolint:staticcheck
is.False(IsNotNil(ifaceWithNilValue))
is.True(ifaceWithNilValue != nil) //nolint:staticcheck
}
func TestToPtr(t *testing.T) {
t.Parallel()
is := assert.New(t)
result1 := ToPtr([]int{1, 2})
is.Equal(*result1, []int{1, 2})
}
func TestNil(t *testing.T) {
t.Parallel()
is := assert.New(t)
nilFloat64 := Nil[float64]()
var expNilFloat64 *float64
nilString := Nil[string]()
var expNilString *string
is.Equal(expNilFloat64, nilFloat64)
is.Nil(nilFloat64)
is.NotEqual(nil, nilFloat64)
is.Equal(expNilString, nilString)
is.Nil(nilString)
is.NotEqual(nil, nilString)
is.NotEqual(nilString, nilFloat64)
}
func TestEmptyableToPtr(t *testing.T) {
t.Parallel()
is := assert.New(t)
is.Nil(EmptyableToPtr(0))
is.Nil(EmptyableToPtr(""))
is.Nil(EmptyableToPtr[[]int](nil))
is.Nil(EmptyableToPtr[map[int]int](nil))
is.Nil(EmptyableToPtr[error](nil))
is.Equal(*EmptyableToPtr(42), 42)
is.Equal(*EmptyableToPtr("nonempty"), "nonempty")
is.Equal(*EmptyableToPtr([]int{}), []int{})
is.Equal(*EmptyableToPtr([]int{1, 2}), []int{1, 2})
is.Equal(*EmptyableToPtr(map[int]int{}), map[int]int{})
is.Equal(*EmptyableToPtr(assert.AnError), assert.AnError)
}
func TestFromPtr(t *testing.T) {
t.Parallel()
is := assert.New(t)
str1 := "foo"
ptr := &str1
is.Equal("foo", FromPtr(ptr))
is.Equal("", FromPtr[string](nil))
is.Equal(0, FromPtr[int](nil))
is.Nil(FromPtr[*string](nil))
is.EqualValues(ptr, FromPtr(&ptr))
}
func TestFromPtrOr(t *testing.T) {
t.Parallel()
is := assert.New(t)
const fallbackStr = "fallback"
str := "foo"
ptrStr := &str
const fallbackInt = -1
i := 9
ptrInt := &i
is.Equal(str, FromPtrOr(ptrStr, fallbackStr))
is.Equal(fallbackStr, FromPtrOr(nil, fallbackStr))
is.Equal(i, FromPtrOr(ptrInt, fallbackInt))
is.Equal(fallbackInt, FromPtrOr(nil, fallbackInt))
}
func TestToSlicePtr(t *testing.T) {
t.Parallel()
is := assert.New(t)
str1 := "foo"
str2 := "bar"
result1 := ToSlicePtr([]string{str1, str2})
is.Equal(result1, []*string{&str1, &str2})
}
func TestFromSlicePtr(t *testing.T) {
is := assert.New(t)
str1 := "foo"
str2 := "bar"
result1 := FromSlicePtr([]*string{&str1, &str2, nil})
is.Equal(result1, []string{str1, str2, ""})
}
func TestFromSlicePtrOr(t *testing.T) {
is := assert.New(t)
str1 := "foo"
str2 := "bar"
result1 := FromSlicePtrOr([]*string{&str1, &str2, nil}, "fallback")
is.Equal(result1, []string{str1, str2, "fallback"})
}
func TestToAnySlice(t *testing.T) {
t.Parallel()
is := assert.New(t)
in1 := []int{0, 1, 2, 3}
in2 := []int{}
out1 := ToAnySlice(in1)
out2 := ToAnySlice(in2)
is.Equal([]any{0, 1, 2, 3}, out1)
is.Equal([]any{}, out2)
}
func TestFromAnySlice(t *testing.T) {
t.Parallel()
is := assert.New(t)
is.NotPanics(func() {
out1, ok1 := FromAnySlice[string]([]any{"foobar", 42})
out2, ok2 := FromAnySlice[string]([]any{"foobar", "42"})
is.Equal([]string{}, out1)
is.False(ok1)
is.Equal([]string{"foobar", "42"}, out2)
is.True(ok2)
})
}
func TestEmpty(t *testing.T) {
t.Parallel()
is := assert.New(t)
//nolint:unused
type test struct{}
is.Empty(Empty[string]())
is.Empty(Empty[int64]())
is.Empty(Empty[test]())
is.Empty(Empty[chan string]())
is.Nil(Empty[[]int]())
is.Nil(Empty[map[string]int]())
}
func TestIsEmpty(t *testing.T) {
t.Parallel()
is := assert.New(t)
//nolint:unused
type test struct {
foobar string
}
is.True(IsEmpty(""))
is.False(IsEmpty("foo"))
is.True(IsEmpty[int64](0))
is.False(IsEmpty[int64](42))
is.True(IsEmpty(test{foobar: ""}))
is.False(IsEmpty(test{foobar: "foo"}))
}
func TestIsNotEmpty(t *testing.T) {
t.Parallel()
is := assert.New(t)
//nolint:unused
type test struct {
foobar string
}
is.False(IsNotEmpty(""))
is.True(IsNotEmpty("foo"))
is.False(IsNotEmpty[int64](0))
is.True(IsNotEmpty[int64](42))
is.False(IsNotEmpty(test{foobar: ""}))
is.True(IsNotEmpty(test{foobar: "foo"}))
}
func TestCoalesce(t *testing.T) {
t.Parallel()
is := assert.New(t)
newStr := func(v string) *string { return &v }
var nilStr *string
str1 := newStr("str1")
str2 := newStr("str2")
type structType struct {
field1 int
field2 float64
}
var zeroStruct structType
struct1 := structType{1, 1.0}
struct2 := structType{2, 2.0}
result1, ok1 := Coalesce[int]()
result2, ok2 := Coalesce(3)
result3, ok3 := Coalesce(nil, nilStr)
result4, ok4 := Coalesce(nilStr, str1)
result5, ok5 := Coalesce(nilStr, str1, str2)
result6, ok6 := Coalesce(str1, str2, nilStr)
result7, ok7 := Coalesce(0, 1, 2, 3)
result8, ok8 := Coalesce(zeroStruct)
result9, ok9 := Coalesce(zeroStruct, struct1)
result10, ok10 := Coalesce(zeroStruct, struct1, struct2)
is.Equal(0, result1)
is.False(ok1)
is.Equal(3, result2)
is.True(ok2)
is.Nil(result3)
is.False(ok3)
is.Equal(str1, result4)
is.True(ok4)
is.Equal(str1, result5)
is.True(ok5)
is.Equal(str1, result6)
is.True(ok6)
is.Equal(result7, 1)
is.True(ok7)
is.Equal(result8, zeroStruct)
is.False(ok8)
is.Equal(result9, struct1)
is.True(ok9)
is.Equal(result10, struct1)
is.True(ok10)
}
func TestCoalesceOrEmpty(t *testing.T) {
t.Parallel()
is := assert.New(t)
newStr := func(v string) *string { return &v }
var nilStr *string
str1 := newStr("str1")
str2 := newStr("str2")
type structType struct {
field1 int
field2 float64
}
var zeroStruct structType
struct1 := structType{1, 1.0}
struct2 := structType{2, 2.0}
result1 := CoalesceOrEmpty[int]()
result2 := CoalesceOrEmpty(3)
result3 := CoalesceOrEmpty(nil, nilStr)
result4 := CoalesceOrEmpty(nilStr, str1)
result5 := CoalesceOrEmpty(nilStr, str1, str2)
result6 := CoalesceOrEmpty(str1, str2, nilStr)
result7 := CoalesceOrEmpty(0, 1, 2, 3)
result8 := CoalesceOrEmpty(zeroStruct)
result9 := CoalesceOrEmpty(zeroStruct, struct1)
result10 := CoalesceOrEmpty(zeroStruct, struct1, struct2)
is.Equal(0, result1)
is.Equal(3, result2)
is.Nil(result3)
is.Equal(str1, result4)
is.Equal(str1, result5)
is.Equal(str1, result6)
is.Equal(result7, 1)
is.Equal(result8, zeroStruct)
is.Equal(result9, struct1)
is.Equal(result10, struct1)
}
func TestCoalesceSlice(t *testing.T) {
t.Parallel()
is := assert.New(t)
var sliceNil []int
slice0 := []int{}
slice1 := []int{1}
slice2 := []int{1, 2}
result1, ok1 := CoalesceSlice[int]()
result2, ok2 := CoalesceSlice[int](nil)
result3, ok3 := CoalesceSlice(sliceNil)
result4, ok4 := CoalesceSlice(slice0)
result5, ok5 := CoalesceSlice(nil, sliceNil, slice0)
result6, ok6 := CoalesceSlice(slice2)
result7, ok7 := CoalesceSlice(slice1)
result8, ok8 := CoalesceSlice(slice1, slice2)
result9, ok9 := CoalesceSlice(slice2, slice1)
result10, ok10 := CoalesceSlice(sliceNil, slice0, slice1, slice2)
is.NotNil(result1)
is.Empty(result1)
is.Equal([]int{}, result1)
is.False(ok1)
is.NotNil(result2)
is.Empty(result2)
is.Equal([]int{}, result2)
is.False(ok2)
is.NotNil(result3)
is.Empty(result3)
is.Equal([]int{}, result3)
is.False(ok3)
is.NotNil(result4)
is.Empty(result4)
is.Equal([]int{}, result4)
is.False(ok4)
is.NotNil(result5)
is.Empty(result5)
is.Equal([]int{}, result5)
is.False(ok5)
is.NotNil(result6)
is.Equal(slice2, result6)
is.True(ok6)
is.NotNil(result7)
is.Equal(slice1, result7)
is.True(ok7)
is.NotNil(result8)
is.Equal(slice1, result8)
is.True(ok8)
is.NotNil(result9)
is.Equal(slice2, result9)
is.True(ok9)
is.NotNil(result10)
is.Equal(slice1, result10)
is.True(ok10)
}
func TestCoalesceSliceOrEmpty(t *testing.T) {
t.Parallel()
is := assert.New(t)
var sliceNil []int
slice0 := []int{}
slice1 := []int{1}
slice2 := []int{1, 2}
result1 := CoalesceSliceOrEmpty[int]()
result2 := CoalesceSliceOrEmpty[int](nil)
result3 := CoalesceSliceOrEmpty(sliceNil)
result4 := CoalesceSliceOrEmpty(slice0)
result5 := CoalesceSliceOrEmpty(nil, sliceNil, slice0)
result6 := CoalesceSliceOrEmpty(slice2)
result7 := CoalesceSliceOrEmpty(slice1)
result8 := CoalesceSliceOrEmpty(slice1, slice2)
result9 := CoalesceSliceOrEmpty(slice2, slice1)
result10 := CoalesceSliceOrEmpty(sliceNil, slice0, slice1, slice2)
is.NotNil(result1)
is.Empty(result1)
is.Equal([]int{}, result1)
is.NotNil(result2)
is.Empty(result2)
is.Equal([]int{}, result2)
is.NotNil(result3)
is.Empty(result3)
is.Equal([]int{}, result3)
is.NotNil(result4)
is.Empty(result4)
is.Equal([]int{}, result4)
is.NotNil(result5)
is.Empty(result5)
is.Equal([]int{}, result5)
is.NotNil(result6)
is.Equal(slice2, result6)
is.NotNil(result7)
is.Equal(slice1, result7)
is.NotNil(result8)
is.Equal(slice1, result8)
is.NotNil(result9)
is.Equal(slice2, result9)
is.NotNil(result10)
is.Equal(slice1, result10)
}
func TestCoalesceMap(t *testing.T) {
t.Parallel()
is := assert.New(t)
var mapNil map[int]int
map0 := map[int]int{}
map1 := map[int]int{1: 1}
map2 := map[int]int{1: 1, 2: 2}
result1, ok1 := CoalesceMap[int, int]()
result2, ok2 := CoalesceMap[int, int](nil)
result3, ok3 := CoalesceMap(mapNil)
result4, ok4 := CoalesceMap(map0)
result5, ok5 := CoalesceMap(nil, mapNil, map0)
result6, ok6 := CoalesceMap(map2)
result7, ok7 := CoalesceMap(map1)
result8, ok8 := CoalesceMap(map1, map2)
result9, ok9 := CoalesceMap(map2, map1)
result10, ok10 := CoalesceMap(mapNil, map0, map1, map2)
is.NotNil(result1)
is.Empty(result1)
is.Equal(map[int]int{}, result1)
is.False(ok1)
is.NotNil(result2)
is.Empty(result2)
is.Equal(map[int]int{}, result2)
is.False(ok2)
is.NotNil(result3)
is.Empty(result3)
is.Equal(map[int]int{}, result3)
is.False(ok3)
is.NotNil(result4)
is.Empty(result4)
is.Equal(map[int]int{}, result4)
is.False(ok4)
is.NotNil(result5)
is.Empty(result5)
is.Equal(map[int]int{}, result5)
is.False(ok5)
is.NotNil(result6)
is.Equal(map2, result6)
is.True(ok6)
is.NotNil(result7)
is.Equal(map1, result7)
is.True(ok7)
is.NotNil(result8)
is.Equal(map1, result8)
is.True(ok8)
is.NotNil(result9)
is.Equal(map2, result9)
is.True(ok9)
is.NotNil(result10)
is.Equal(map1, result10)
is.True(ok10)
}
func TestCoalesceMapOrEmpty(t *testing.T) {
t.Parallel()
is := assert.New(t)
var mapNil map[int]int
map0 := map[int]int{}
map1 := map[int]int{1: 1}
map2 := map[int]int{1: 1, 2: 2}
result1 := CoalesceMapOrEmpty[int, int]()
result2 := CoalesceMapOrEmpty[int, int](nil)
result3 := CoalesceMapOrEmpty(mapNil)
result4 := CoalesceMapOrEmpty(map0)
result5 := CoalesceMapOrEmpty(nil, mapNil, map0)
result6 := CoalesceMapOrEmpty(map2)
result7 := CoalesceMapOrEmpty(map1)
result8 := CoalesceMapOrEmpty(map1, map2)
result9 := CoalesceMapOrEmpty(map2, map1)
result10 := CoalesceMapOrEmpty(mapNil, map0, map1, map2)
is.NotNil(result1)
is.Empty(result1)
is.Equal(map[int]int{}, result1)
is.NotNil(result2)
is.Empty(result2)
is.Equal(map[int]int{}, result2)
is.NotNil(result3)
is.Empty(result3)
is.Equal(map[int]int{}, result3)
is.NotNil(result4)
is.Empty(result4)
is.Equal(map[int]int{}, result4)
is.NotNil(result5)
is.Empty(result5)
is.Equal(map[int]int{}, result5)
is.NotNil(result6)
is.Equal(map2, result6)
is.NotNil(result7)
is.Equal(map1, result7)
is.NotNil(result8)
is.Equal(map1, result8)
is.NotNil(result9)
is.Equal(map2, result9)
is.NotNil(result10)
is.Equal(map1, result10)
}