mirror of
https://github.com/samber/lo.git
synced 2025-10-04 23:52:41 +08:00
chore: test coverage improvement (#240)
* chore: improves channel functions test coverage * chore: improves errors functions test coverage * chore: improves map functions test coverage * chore: improves parallel slice functions test coverage * chore: improves slice functions test coverage * fix: uses atomic counter on parallel/slice_test * Update channel_test.go Co-authored-by: Samuel Berthe <dev@samuel-berthe.fr>
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
package lo
|
package lo
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"math/rand"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -111,7 +112,21 @@ func TestDispatchingStrategyRoundRobin(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestDispatchingStrategyRandom(t *testing.T) {
|
func TestDispatchingStrategyRandom(t *testing.T) {
|
||||||
// @TODO
|
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[int](42, 0, rochildren))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDispatchingStrategyWeightedRandom(t *testing.T) {
|
func TestDispatchingStrategyWeightedRandom(t *testing.T) {
|
||||||
|
@@ -53,6 +53,13 @@ func TestMust(t *testing.T) {
|
|||||||
is.PanicsWithValue("operation should fail: assert.AnError general error for testing", func() {
|
is.PanicsWithValue("operation should fail: assert.AnError general error for testing", func() {
|
||||||
Must0(cb(), "operation should fail")
|
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) {
|
func TestMustX(t *testing.T) {
|
||||||
@@ -264,7 +271,11 @@ func TestTry(t *testing.T) {
|
|||||||
func TestTryX(t *testing.T) {
|
func TestTryX(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
is := assert.New(t)
|
is := assert.New(t)
|
||||||
|
|
||||||
|
is.True(Try1(func() error {
|
||||||
|
return nil
|
||||||
|
}))
|
||||||
|
|
||||||
is.True(Try2(func() (string, error) {
|
is.True(Try2(func() (string, error) {
|
||||||
return "", nil
|
return "", nil
|
||||||
}))
|
}))
|
||||||
@@ -284,7 +295,11 @@ func TestTryX(t *testing.T) {
|
|||||||
is.True(Try6(func() (string, string, string, string, string, error) {
|
is.True(Try6(func() (string, string, string, string, string, error) {
|
||||||
return "", "", "", "", "", nil
|
return "", "", "", "", "", nil
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
is.False(Try1(func() error {
|
||||||
|
panic("error")
|
||||||
|
}))
|
||||||
|
|
||||||
is.False(Try2(func() (string, error) {
|
is.False(Try2(func() (string, error) {
|
||||||
panic("error")
|
panic("error")
|
||||||
}))
|
}))
|
||||||
@@ -304,7 +319,11 @@ func TestTryX(t *testing.T) {
|
|||||||
is.False(Try6(func() (string, string, string, string, string, error) {
|
is.False(Try6(func() (string, string, string, string, string, error) {
|
||||||
panic("error")
|
panic("error")
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
is.False(Try1(func() error {
|
||||||
|
return errors.New("foo")
|
||||||
|
}))
|
||||||
|
|
||||||
is.False(Try2(func() (string, error) {
|
is.False(Try2(func() (string, error) {
|
||||||
return "", errors.New("foo")
|
return "", errors.New("foo")
|
||||||
}))
|
}))
|
||||||
@@ -489,11 +508,18 @@ func TestTryWithErrorValue(t *testing.T) {
|
|||||||
is := assert.New(t)
|
is := assert.New(t)
|
||||||
|
|
||||||
err, ok := TryWithErrorValue(func() error {
|
err, ok := TryWithErrorValue(func() error {
|
||||||
|
// getting error in case of panic, using recover function
|
||||||
panic("error")
|
panic("error")
|
||||||
})
|
})
|
||||||
is.False(ok)
|
is.False(ok)
|
||||||
is.Equal("error", err)
|
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 {
|
err, ok = TryWithErrorValue(func() error {
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
45
map_test.go
45
map_test.go
@@ -108,10 +108,31 @@ func TestEntries(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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) {
|
func TestFromEntries(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
is := assert.New(t)
|
is := assert.New(t)
|
||||||
|
|
||||||
r1 := FromEntries([]Entry[string, int]{
|
r1 := FromEntries([]Entry[string, int]{
|
||||||
{
|
{
|
||||||
Key: "foo",
|
Key: "foo",
|
||||||
@@ -128,10 +149,30 @@ func TestFromEntries(t *testing.T) {
|
|||||||
is.Equal(r1["bar"], 2)
|
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) {
|
func TestInvert(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
is := assert.New(t)
|
is := assert.New(t)
|
||||||
|
|
||||||
r1 := Invert(map[string]int{"a": 1, "b": 2})
|
r1 := Invert(map[string]int{"a": 1, "b": 2})
|
||||||
r2 := Invert(map[string]int{"a": 1, "b": 2, "c": 1})
|
r2 := Invert(map[string]int{"a": 1, "b": 2, "c": 1})
|
||||||
|
|
||||||
|
@@ -3,52 +3,65 @@ package parallel
|
|||||||
import (
|
import (
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"sync/atomic"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestMap(t *testing.T) {
|
func TestMap(t *testing.T) {
|
||||||
is := assert.New(t)
|
is := assert.New(t)
|
||||||
|
|
||||||
result1 := Map([]int{1, 2, 3, 4}, func(x int, _ int) string {
|
result1 := Map([]int{1, 2, 3, 4}, func(x int, _ int) string {
|
||||||
return "Hello"
|
return "Hello"
|
||||||
})
|
})
|
||||||
result2 := Map([]int64{1, 2, 3, 4}, func(x int64, _ int) string {
|
result2 := Map([]int64{1, 2, 3, 4}, func(x int64, _ int) string {
|
||||||
return strconv.FormatInt(x, 10)
|
return strconv.FormatInt(x, 10)
|
||||||
})
|
})
|
||||||
|
|
||||||
is.Equal(len(result1), 4)
|
is.Equal(len(result1), 4)
|
||||||
is.Equal(len(result2), 4)
|
is.Equal(len(result2), 4)
|
||||||
is.Equal(result1, []string{"Hello", "Hello", "Hello", "Hello"})
|
is.Equal(result1, []string{"Hello", "Hello", "Hello", "Hello"})
|
||||||
is.Equal(result2, []string{"1", "2", "3", "4"})
|
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) {
|
func TestTimes(t *testing.T) {
|
||||||
is := assert.New(t)
|
is := assert.New(t)
|
||||||
|
|
||||||
result1 := Times(3, func(i int) string {
|
result1 := Times(3, func(i int) string {
|
||||||
return strconv.FormatInt(int64(i), 10)
|
return strconv.FormatInt(int64(i), 10)
|
||||||
})
|
})
|
||||||
|
|
||||||
is.Equal(len(result1), 3)
|
is.Equal(len(result1), 3)
|
||||||
is.Equal(result1, []string{"0", "1", "2"})
|
is.Equal(result1, []string{"0", "1", "2"})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGroupBy(t *testing.T) {
|
func TestGroupBy(t *testing.T) {
|
||||||
is := assert.New(t)
|
is := assert.New(t)
|
||||||
|
|
||||||
result1 := GroupBy([]int{0, 1, 2, 3, 4, 5}, func(i int) int {
|
result1 := GroupBy([]int{0, 1, 2, 3, 4, 5}, func(i int) int {
|
||||||
return i % 3
|
return i % 3
|
||||||
})
|
})
|
||||||
|
|
||||||
// order
|
// order
|
||||||
for x := range result1 {
|
for x := range result1 {
|
||||||
sort.Slice(result1[x], func(i, j int) bool {
|
sort.Slice(result1[x], func(i, j int) bool {
|
||||||
return result1[x][i] < result1[x][j]
|
return result1[x][i] < result1[x][j]
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
is.EqualValues(len(result1), 3)
|
is.EqualValues(len(result1), 3)
|
||||||
is.EqualValues(result1, map[int][]int{
|
is.EqualValues(result1, map[int][]int{
|
||||||
0: {0, 3},
|
0: {0, 3},
|
||||||
@@ -59,7 +72,7 @@ func TestGroupBy(t *testing.T) {
|
|||||||
|
|
||||||
func TestPartitionBy(t *testing.T) {
|
func TestPartitionBy(t *testing.T) {
|
||||||
is := assert.New(t)
|
is := assert.New(t)
|
||||||
|
|
||||||
oddEven := func(x int) string {
|
oddEven := func(x int) string {
|
||||||
if x < 0 {
|
if x < 0 {
|
||||||
return "negative"
|
return "negative"
|
||||||
@@ -68,10 +81,10 @@ func TestPartitionBy(t *testing.T) {
|
|||||||
}
|
}
|
||||||
return "odd"
|
return "odd"
|
||||||
}
|
}
|
||||||
|
|
||||||
result1 := PartitionBy([]int{-2, -1, 0, 1, 2, 3, 4, 5}, oddEven)
|
result1 := PartitionBy([]int{-2, -1, 0, 1, 2, 3, 4, 5}, oddEven)
|
||||||
result2 := PartitionBy([]int{}, oddEven)
|
result2 := PartitionBy([]int{}, oddEven)
|
||||||
|
|
||||||
// order
|
// order
|
||||||
sort.Slice(result1, func(i, j int) bool {
|
sort.Slice(result1, func(i, j int) bool {
|
||||||
return result1[i][0] < result1[j][0]
|
return result1[i][0] < result1[j][0]
|
||||||
@@ -81,7 +94,7 @@ func TestPartitionBy(t *testing.T) {
|
|||||||
return result1[x][i] < result1[x][j]
|
return result1[x][i] < result1[x][j]
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
is.ElementsMatch(result1, [][]int{{-2, -1}, {0, 2, 4}, {1, 3, 5}})
|
is.ElementsMatch(result1, [][]int{{-2, -1}, {0, 2, 4}, {1, 3, 5}})
|
||||||
is.Equal(result2, [][]int{})
|
is.Equal(result2, [][]int{})
|
||||||
}
|
}
|
||||||
|
@@ -197,6 +197,9 @@ func TestChunk(t *testing.T) {
|
|||||||
is.Equal(result2, [][]int{{0, 1}, {2, 3}, {4, 5}, {6}})
|
is.Equal(result2, [][]int{{0, 1}, {2, 3}, {4, 5}, {6}})
|
||||||
is.Equal(result3, [][]int{})
|
is.Equal(result3, [][]int{})
|
||||||
is.Equal(result4, [][]int{{0}})
|
is.Equal(result4, [][]int{{0}})
|
||||||
|
is.PanicsWithValue("Second parameter must be greater than 0", func() {
|
||||||
|
Chunk([]int{0}, 0)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPartitionBy(t *testing.T) {
|
func TestPartitionBy(t *testing.T) {
|
||||||
@@ -383,6 +386,41 @@ func TestAssociate(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestSliceToMap(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
type foo struct {
|
||||||
|
baz string
|
||||||
|
bar int
|
||||||
|
}
|
||||||
|
transform := func(f *foo) (string, int) {
|
||||||
|
return f.baz, f.bar
|
||||||
|
}
|
||||||
|
testCases := []struct {
|
||||||
|
in []*foo
|
||||||
|
expect map[string]int
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
in: []*foo{{baz: "apple", bar: 1}},
|
||||||
|
expect: map[string]int{"apple": 1},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
in: []*foo{{baz: "apple", bar: 1}, {baz: "banana", bar: 2}},
|
||||||
|
expect: map[string]int{"apple": 1, "banana": 2},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
in: []*foo{{baz: "apple", bar: 1}, {baz: "apple", bar: 2}},
|
||||||
|
expect: map[string]int{"apple": 2},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for i, testCase := range testCases {
|
||||||
|
t.Run(fmt.Sprintf("test_%d", i), func(t *testing.T) {
|
||||||
|
is := assert.New(t)
|
||||||
|
is.Equal(SliceToMap(testCase.in, transform), testCase.expect)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestDrop(t *testing.T) {
|
func TestDrop(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
is := assert.New(t)
|
is := assert.New(t)
|
||||||
@@ -584,7 +622,8 @@ func TestSlice(t *testing.T) {
|
|||||||
out12 := Slice(in, 1, 0)
|
out12 := Slice(in, 1, 0)
|
||||||
out13 := Slice(in, 5, 0)
|
out13 := Slice(in, 5, 0)
|
||||||
out14 := Slice(in, 6, 4)
|
out14 := Slice(in, 6, 4)
|
||||||
|
out15 := Slice(in, 6, 7)
|
||||||
|
|
||||||
is.Equal([]int{}, out1)
|
is.Equal([]int{}, out1)
|
||||||
is.Equal([]int{0}, out2)
|
is.Equal([]int{0}, out2)
|
||||||
is.Equal([]int{0, 1, 2, 3, 4}, out3)
|
is.Equal([]int{0, 1, 2, 3, 4}, out3)
|
||||||
@@ -599,6 +638,7 @@ func TestSlice(t *testing.T) {
|
|||||||
is.Equal([]int{}, out12)
|
is.Equal([]int{}, out12)
|
||||||
is.Equal([]int{}, out13)
|
is.Equal([]int{}, out13)
|
||||||
is.Equal([]int{}, out14)
|
is.Equal([]int{}, out14)
|
||||||
|
is.Equal([]int{}, out15)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestReplace(t *testing.T) {
|
func TestReplace(t *testing.T) {
|
||||||
|
Reference in New Issue
Block a user