mirror of
https://github.com/samber/lo.git
synced 2025-09-26 20:11:13 +08:00
bump v1.50.0
This commit is contained in:
427
channel_test.go
427
channel_test.go
@@ -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)
|
||||
}
|
||||
}
|
@@ -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)
|
||||
})
|
||||
}
|
@@ -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
|
||||
}
|
@@ -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)
|
||||
}
|
@@ -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
|
@@ -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
|
||||
}
|
599
errors_test.go
599
errors_test.go
@@ -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)
|
||||
}
|
783
find_test.go
783
find_test.go
@@ -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")
|
||||
}
|
80
func_test.go
80
func_test.go
@@ -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
2
go.mod
@@ -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
8
go.sum
@@ -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=
|
||||
|
@@ -1,2 +0,0 @@
|
||||
|
||||
Credits goes to https://gopherize.me/
|
Binary file not shown.
Before Width: | Height: | Size: 563 KiB |
Binary file not shown.
BIN
img/logo.png
BIN
img/logo.png
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.
@@ -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}]
|
||||
}
|
@@ -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 },
|
||||
))
|
||||
}
|
31
lo_test.go
31
lo_test.go
@@ -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}
|
||||
}
|
11
main_test.go
11
main_test.go
@@ -1,11 +0,0 @@
|
||||
package lo
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"go.uber.org/goleak"
|
||||
)
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
goleak.VerifyTestMain(m)
|
||||
}
|
@@ -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
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
@@ -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]
|
||||
}
|
595
map_test.go
595
map_test.go
@@ -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
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
}
|
@@ -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
|
||||
}
|
173
math_test.go
173
math_test.go
@@ -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))
|
||||
}
|
@@ -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")
|
||||
}
|
@@ -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
|
||||
}
|
643
retry_test.go
643
retry_test.go
@@ -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)
|
||||
}
|
@@ -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)
|
||||
}
|
||||
}
|
@@ -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
|
||||
}
|
1146
slice_test.go
1146
slice_test.go
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
}
|
503
string_test.go
503
string_test.go
@@ -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))
|
||||
}
|
149
time_test.go
149
time_test.go
@@ -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)
|
||||
}
|
||||
}
|
@@ -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
|
||||
}
|
593
tuples_test.go
593
tuples_test.go
@@ -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)
|
||||
}
|
@@ -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)
|
||||
}
|
Reference in New Issue
Block a user