lint: unit test improvements (#674)

* lint: pin golangci-lint version

* lint: use is.Empty where possible

* lint: use is.ElementsMatch for unsorted slices

* lint: remove redundant is.Len assertions

* lint: use is.Zero to assert zero structs

* fix: misc assertion issues

* lint: more consistent test case pattern

* fix: reversed expect/actual assert values

* lint: use is.ErrorIs and is.EqualError for errors

* Update golangci-lint version in workflow

---------

Co-authored-by: Samuel Berthe <dev@samuel-berthe.fr>
This commit is contained in:
Nathan Baulch
2025-09-25 05:02:52 +10:00
committed by GitHub
parent b5e290abe0
commit 7170719ec0
11 changed files with 275 additions and 405 deletions

View File

@@ -275,7 +275,7 @@ func TestBuffer(t *testing.T) {
is.Equal([]int{3}, items2)
is.Equal(1, length2)
is.False(ok2)
is.Equal([]int{}, items3)
is.Empty(items3)
is.Zero(length3)
is.False(ok3)
}
@@ -335,7 +335,7 @@ func TestBufferWithTimeout(t *testing.T) {
is.True(ok1)
items2, length2, _, ok2 := BufferWithTimeout(ch, 20, 2*time.Millisecond)
is.Equal([]int{}, items2)
is.Empty(items2)
is.Zero(length2)
is.True(ok2)
@@ -350,7 +350,7 @@ func TestBufferWithTimeout(t *testing.T) {
is.True(ok4)
items5, length5, _, ok5 := BufferWithTimeout(ch, 3, 25*time.Millisecond)
is.Equal([]int{}, items5)
is.Empty(items5)
is.Zero(length5)
is.False(ok5)
}

View File

@@ -1,9 +1,7 @@
package lo
import (
"fmt"
"math/rand"
"sort"
"testing"
"time"
@@ -74,7 +72,7 @@ func TestFindIndexOf(t *testing.T) {
is.Equal(1, index1)
is.Empty(item2)
is.False(ok2)
is.Equal(index2, -1)
is.Equal(-1, index2)
}
func TestFindLastIndexOf(t *testing.T) {
@@ -97,7 +95,7 @@ func TestFindLastIndexOf(t *testing.T) {
is.Equal(4, index1)
is.Empty(item2)
is.False(ok2)
is.Equal(index2, -1)
is.Equal(-1, index2)
}
func TestFindOrElse(t *testing.T) {
@@ -166,24 +164,16 @@ func TestFindUniques(t *testing.T) {
is := assert.New(t)
result1 := FindUniques([]int{1, 2, 3})
is.Len(result1, 3)
is.Equal([]int{1, 2, 3}, result1)
result2 := FindUniques([]int{1, 2, 2, 3, 1, 2})
is.Len(result2, 1)
is.Equal([]int{3}, result2)
result3 := FindUniques([]int{1, 2, 2, 1})
is.Empty(result3)
is.Equal([]int{}, result3)
result4 := FindUniques([]int{})
is.Empty(result4)
is.Equal([]int{}, result4)
type myStrings []string
allStrings := myStrings{"", "foo", "bar"}
@@ -198,30 +188,22 @@ func TestFindUniquesBy(t *testing.T) {
result1 := FindUniquesBy([]int{0, 1, 2}, func(i int) int {
return i % 3
})
is.Len(result1, 3)
is.Equal([]int{0, 1, 2}, result1)
result2 := FindUniquesBy([]int{0, 1, 2, 3, 4}, func(i int) int {
return i % 3
})
is.Len(result2, 1)
is.Equal([]int{2}, result2)
result3 := FindUniquesBy([]int{0, 1, 2, 3, 4, 5}, func(i int) int {
return i % 3
})
is.Empty(result3)
is.Equal([]int{}, result3)
result4 := FindUniquesBy([]int{}, func(i int) int {
return i % 3
})
is.Empty(result4)
is.Equal([]int{}, result4)
type myStrings []string
allStrings := myStrings{"", "foo", "bar"}
@@ -236,19 +218,13 @@ func TestFindDuplicates(t *testing.T) {
is := assert.New(t)
result1 := FindDuplicates([]int{1, 2, 2, 1, 2, 3})
is.Len(result1, 2)
is.Equal([]int{1, 2}, result1)
result2 := FindDuplicates([]int{1, 2, 3})
is.Empty(result2)
is.Equal([]int{}, result2)
result3 := FindDuplicates([]int{})
is.Empty(result3)
is.Equal([]int{}, result3)
type myStrings []string
allStrings := myStrings{"", "foo", "bar"}
@@ -263,23 +239,17 @@ func TestFindDuplicatesBy(t *testing.T) {
result1 := FindDuplicatesBy([]int{3, 4, 5, 6, 7}, func(i int) int {
return i % 3
})
is.Len(result1, 2)
is.Equal([]int{3, 4}, result1)
result2 := FindDuplicatesBy([]int{0, 1, 2, 3, 4}, func(i int) int {
return i % 5
})
is.Empty(result2)
is.Equal([]int{}, result2)
result3 := FindDuplicatesBy([]int{}, func(i int) int {
return i % 3
})
is.Empty(result3)
is.Equal([]int{}, result3)
type myStrings []string
allStrings := myStrings{"", "foo", "bar"}
@@ -323,7 +293,7 @@ func TestMinIndex(t *testing.T) {
is.Zero(index3)
is.Zero(result4)
is.Equal(index4, -1)
is.Equal(-1, index4)
}
func TestMinBy(t *testing.T) {
@@ -366,7 +336,7 @@ func TestMinIndexBy(t *testing.T) {
is.Equal(2, index2)
is.Empty(result3)
is.Equal(index3, -1)
is.Equal(-1, index3)
}
func TestEarliest(t *testing.T) {
@@ -379,7 +349,7 @@ func TestEarliest(t *testing.T) {
result2 := Earliest()
is.Equal(a, result1)
is.Equal(time.Time{}, result2)
is.Zero(result2)
}
func TestEarliestBy(t *testing.T) {
@@ -405,7 +375,7 @@ func TestEarliestBy(t *testing.T) {
is.Equal(foo{t3}, result1)
is.Equal(foo{t1}, result2)
is.Equal(foo{}, result3)
is.Zero(result3)
}
func TestMax(t *testing.T) {
@@ -442,7 +412,7 @@ func TestMaxIndex(t *testing.T) {
is.Equal(2, index3)
is.Zero(result4)
is.Equal(index4, -1)
is.Equal(-1, index4)
}
func TestMaxBy(t *testing.T) {
@@ -485,7 +455,7 @@ func TestMaxIndexBy(t *testing.T) {
is.Zero(index2)
is.Empty(result3)
is.Equal(index3, -1)
is.Equal(-1, index3)
}
func TestLatest(t *testing.T) {
@@ -498,7 +468,7 @@ func TestLatest(t *testing.T) {
result2 := Latest()
is.Equal(b, result1)
is.Equal(time.Time{}, result2)
is.Zero(result2)
}
func TestLatestBy(t *testing.T) {
@@ -524,7 +494,7 @@ func TestLatestBy(t *testing.T) {
is.Equal(foo{t2}, result1)
is.Equal(foo{t1}, result2)
is.Equal(foo{}, result3)
is.Zero(result3)
}
func TestFirst(t *testing.T) {
@@ -621,9 +591,9 @@ func TestNth(t *testing.T) {
is.Equal(2, result2)
is.NoError(err2)
is.Zero(result3)
is.Equal(err3, fmt.Errorf("nth: 42 out of slice bounds"))
is.EqualError(err3, "nth: 42 out of slice bounds")
is.Zero(result4)
is.Equal(err4, fmt.Errorf("nth: 0 out of slice bounds"))
is.EqualError(err4, "nth: 0 out of slice bounds")
is.Equal(42, result5)
is.NoError(err5)
is.Equal(42, result6)
@@ -631,9 +601,10 @@ func TestNth(t *testing.T) {
}
func TestNthOr(t *testing.T) {
t.Run("Integers", func(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}
@@ -643,6 +614,9 @@ func TestNthOr(t *testing.T) {
})
t.Run("Strings", func(t *testing.T) {
t.Parallel()
is := assert.New(t)
const defaultValue = "none"
strSlice := []string{"apple", "banana", "cherry", "date"}
@@ -652,6 +626,9 @@ func TestNthOr(t *testing.T) {
})
t.Run("Structs", func(t *testing.T) {
t.Parallel()
is := assert.New(t)
type User struct {
ID int
Name string
@@ -674,27 +651,32 @@ func TestNthOr(t *testing.T) {
}
func TestNthOrEmpty(t *testing.T) {
t.Run("Integers", func(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))
is.Zero(NthOrEmpty(intSlice, 10))
})
t.Run("Strings", func(t *testing.T) {
const defaultValue = ""
t.Parallel()
is := assert.New(t)
strSlice := []string{"apple", "banana", "cherry", "date"}
is.Equal("banana", NthOrEmpty(strSlice, 1))
is.Equal("cherry", NthOrEmpty(strSlice, -2))
is.Equal(defaultValue, NthOrEmpty(strSlice, 10))
is.Empty(NthOrEmpty(strSlice, 10))
})
t.Run("Structs", func(t *testing.T) {
t.Parallel()
is := assert.New(t)
type User struct {
ID int
Name string
@@ -711,8 +693,7 @@ func TestNthOrEmpty(t *testing.T) {
expectedUser = User{ID: 3, Name: "Charlie"}
is.Equal(expectedUser, NthOrEmpty(userSlice, -1))
expectedUser = User{ID: 0, Name: ""}
is.Equal(expectedUser, NthOrEmpty(userSlice, 10))
is.Zero(NthOrEmpty(userSlice, 10))
})
}
@@ -751,10 +732,8 @@ func TestSamples(t *testing.T) {
result1 := Samples([]string{"a", "b", "c"}, 3)
result2 := Samples([]string{}, 3)
sort.Strings(result1)
is.Equal([]string{"a", "b", "c"}, result1)
is.Equal([]string{}, result2)
is.ElementsMatch(result1, []string{"a", "b", "c"})
is.Empty(result2)
type myStrings []string
allStrings := myStrings{"", "foo", "bar"}
@@ -771,10 +750,8 @@ func TestSamplesBy(t *testing.T) {
result1 := SamplesBy([]string{"a", "b", "c"}, 3, r.Intn)
result2 := SamplesBy([]string{}, 3, r.Intn)
sort.Strings(result1)
is.Equal([]string{"a", "b", "c"}, result1)
is.Equal([]string{}, result2)
is.ElementsMatch(result1, []string{"a", "b", "c"})
is.Empty(result2)
type myStrings []string
allStrings := myStrings{"", "foo", "bar"}

View File

@@ -184,7 +184,7 @@ func TestIntersect(t *testing.T) {
is.Equal([]int{0, 2}, result1)
is.Equal([]int{0}, result2)
is.Equal([]int{}, result3)
is.Empty(result3)
is.Equal([]int{0}, result4)
is.Equal([]int{0}, result5)
@@ -207,8 +207,8 @@ func TestDifference(t *testing.T) {
is.Equal([]int{0, 6}, right2)
left3, right3 := Difference([]int{0, 1, 2, 3, 4, 5}, []int{0, 1, 2, 3, 4, 5})
is.Equal([]int{}, left3)
is.Equal([]int{}, right3)
is.Empty(left3)
is.Empty(right3)
type myStrings []string
allStrings := myStrings{"", "foo", "bar"}
@@ -232,7 +232,7 @@ func TestUnion(t *testing.T) {
is.Equal([]int{0, 1, 2, 3, 4, 5}, result3)
is.Equal([]int{0, 1, 2, 3}, result4)
is.Equal([]int{0, 1, 2}, result5)
is.Equal([]int{}, result6)
is.Empty(result6)
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})
@@ -243,7 +243,7 @@ func TestUnion(t *testing.T) {
is.Equal([]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, result12)
is.Equal([]int{0, 1, 2, 3, 4, 5}, result13)
is.Equal([]int{0, 1, 2}, result14)
is.Equal([]int{}, result15)
is.Empty(result15)
type myStrings []string
allStrings := myStrings{"", "foo", "bar"}
@@ -262,9 +262,9 @@ func TestWithout(t *testing.T) {
result5 := Without([]int{})
is.Equal([]int{10}, result1)
is.Equal([]int{7}, result2)
is.Equal([]int{}, result3)
is.Equal([]int{}, result4)
is.Equal([]int{}, result5)
is.Empty(result3)
is.Empty(result4)
is.Empty(result5)
type myStrings []string
allStrings := myStrings{"", "foo", "bar"}
@@ -288,8 +288,8 @@ func TestWithoutBy(t *testing.T) {
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([]User{{Name: "peter"}}, result1)
is.Equal([]User{}, result2)
is.Equal([]User{}, result3)
is.Empty(result2)
is.Empty(result3)
}
func TestWithoutEmpty(t *testing.T) {
@@ -302,7 +302,7 @@ func TestWithoutEmpty(t *testing.T) {
result4 := WithoutEmpty([]*int{ToPtr(0), ToPtr(1), nil, ToPtr(2)})
is.Equal([]int{1, 2}, result1)
is.Equal([]int{1, 2}, result2)
is.Equal([]int{}, result3)
is.Empty(result3)
is.Equal([]*int{ToPtr(0), ToPtr(1), ToPtr(2)}, result4)
type myStrings []string
@@ -322,7 +322,7 @@ func TestWithoutNth(t *testing.T) {
is.Equal([]int{1, 2}, result2)
result3 := WithoutNth([]int{})
is.Equal([]int{}, result3)
is.Empty(result3)
result4 := WithoutNth([]int{0, 1, 2, 3}, -1, 4)
is.Equal([]int{0, 1, 2, 3}, result4)

View File

@@ -2,7 +2,6 @@ package lo
import (
"fmt"
"sort"
"strconv"
"testing"
@@ -14,22 +13,19 @@ func TestKeys(t *testing.T) {
is := assert.New(t)
r1 := Keys(map[string]int{"foo": 1, "bar": 2})
sort.Strings(r1)
is.Equal([]string{"bar", "foo"}, r1)
is.ElementsMatch(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([]string{"bar", "baz", "foo"}, r3)
is.ElementsMatch(r3, []string{"bar", "baz", "foo"})
r4 := Keys[string, int]()
is.Equal([]string{}, r4)
is.Empty(r4)
r5 := Keys(map[string]int{"foo": 1, "bar": 2}, map[string]int{"bar": 3})
sort.Strings(r5)
is.Equal([]string{"bar", "bar", "foo"}, r5)
is.ElementsMatch(r5, []string{"bar", "bar", "foo"})
}
func TestUniqKeys(t *testing.T) {
@@ -37,22 +33,19 @@ func TestUniqKeys(t *testing.T) {
is := assert.New(t)
r1 := UniqKeys(map[string]int{"foo": 1, "bar": 2})
sort.Strings(r1)
is.Equal([]string{"bar", "foo"}, r1)
is.ElementsMatch(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([]string{"bar", "baz", "foo"}, r3)
is.ElementsMatch(r3, []string{"bar", "baz", "foo"})
r4 := UniqKeys[string, int]()
is.Equal([]string{}, r4)
is.Empty(r4)
r5 := UniqKeys(map[string]int{"foo": 1, "bar": 2}, map[string]int{"foo": 1, "bar": 3})
sort.Strings(r5)
is.Equal([]string{"bar", "foo"}, r5)
is.ElementsMatch(r5, []string{"bar", "foo"})
// check order
r6 := UniqKeys(map[string]int{"foo": 1}, map[string]int{"bar": 3})
@@ -75,22 +68,19 @@ func TestValues(t *testing.T) {
is := assert.New(t)
r1 := Values(map[string]int{"foo": 1, "bar": 2})
sort.Ints(r1)
is.Equal([]int{1, 2}, r1)
is.ElementsMatch(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([]int{1, 2, 3}, r3)
is.ElementsMatch(r3, []int{1, 2, 3})
r4 := Values[string, int]()
is.Equal([]int{}, r4)
is.Empty(r4)
r5 := Values(map[string]int{"foo": 1, "bar": 2}, map[string]int{"foo": 1, "bar": 3})
sort.Ints(r5)
is.Equal([]int{1, 1, 2, 3}, r5)
is.ElementsMatch(r5, []int{1, 1, 2, 3})
}
func TestUniqValues(t *testing.T) {
@@ -98,26 +88,22 @@ func TestUniqValues(t *testing.T) {
is := assert.New(t)
r1 := UniqValues(map[string]int{"foo": 1, "bar": 2})
sort.Ints(r1)
is.Equal([]int{1, 2}, r1)
is.ElementsMatch(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([]int{1, 2, 3}, r3)
is.ElementsMatch(r3, []int{1, 2, 3})
r4 := UniqValues[string, int]()
is.Equal([]int{}, r4)
is.Empty(r4)
r5 := UniqValues(map[string]int{"foo": 1, "bar": 2}, map[string]int{"foo": 1, "bar": 3})
sort.Ints(r5)
is.Equal([]int{1, 2, 3}, r5)
is.ElementsMatch(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([]int{1, 3}, r6)
is.ElementsMatch(r6, []int{1, 3})
// check order
r7 := UniqValues(map[string]int{"foo": 1}, map[string]int{"bar": 3})
@@ -228,11 +214,7 @@ func TestEntries(t *testing.T) {
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.Equal([]Entry[string, int]{
is.ElementsMatch(r1, []Entry[string, int]{
{
Key: "foo",
Value: 1,
@@ -241,7 +223,7 @@ func TestEntries(t *testing.T) {
Key: "bar",
Value: 2,
},
}, r1)
})
}
func TestToPairs(t *testing.T) {
@@ -249,11 +231,7 @@ func TestToPairs(t *testing.T) {
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.Equal([]Entry[string, int]{
is.ElementsMatch(r1, []Entry[string, int]{
{
Key: "baz",
Value: 3,
@@ -262,7 +240,7 @@ func TestToPairs(t *testing.T) {
Key: "qux",
Value: 4,
},
}, r1)
})
}
func TestFromEntries(t *testing.T) {
@@ -312,7 +290,6 @@ func TestInvert(t *testing.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.Equal(map[int]string{1: "a", 2: "b"}, r1)
is.Len(r2, 2)
}
@@ -322,8 +299,6 @@ func TestAssign(t *testing.T) {
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(map[string]int{"a": 1, "b": 3, "c": 4}, result1)
type myMap map[string]int
@@ -342,17 +317,11 @@ func TestChunkEntries(t *testing.T) {
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.Len(result1, 3)
is.Len(result2, 2)
is.Empty(result3)
is.Len(result4, 1)
is.Len(result5, 2)
is.PanicsWithValue("lo.ChunkEntries: size must be greater than 0", func() {
ChunkEntries(map[string]int{"a": 1}, 0)
@@ -390,7 +359,6 @@ func TestMapKeys(t *testing.T) {
})
is.Len(result1, 1)
is.Len(result2, 4)
is.Equal(map[string]int{"1": 1, "2": 2, "3": 3, "4": 4}, result2)
}
@@ -405,8 +373,6 @@ func TestMapValues(t *testing.T) {
return strconv.FormatInt(int64(x), 10)
})
is.Len(result1, 4)
is.Len(result2, 4)
is.Equal(map[int]string{1: "Hello", 2: "Hello", 3: "Hello", 4: "Hello"}, result1)
is.Equal(map[int]string{1: "1", 2: "2", 3: "3", 4: "4"}, result2)
}
@@ -507,8 +473,6 @@ func TestMapToSlice(t *testing.T) {
return strconv.FormatInt(int64(k), 10)
})
is.Len(result1, 4)
is.Len(result2, 4)
is.ElementsMatch(result1, []string{"1_5", "2_6", "3_7", "4_8"})
is.ElementsMatch(result2, []string{"1", "2", "3", "4"})
}
@@ -524,8 +488,6 @@ func TestFilterMapToSlice(t *testing.T) {
return strconv.FormatInt(int64(k), 10), k%2 == 0
})
is.Len(result1, 2)
is.Len(result2, 2)
is.ElementsMatch(result1, []string{"2_6", "4_8"})
is.ElementsMatch(result2, []string{"2", "4"})
}
@@ -538,12 +500,10 @@ func TestFilterKeys(t *testing.T) {
return v == "foo"
})
is.Equal([]int{1}, result1)
is.Len(result1, 1)
result2 := FilterKeys(map[string]int{"foo": 1, "bar": 2, "baz": 3}, func(k string, v int) bool {
return false
})
is.Equal([]string{}, result2)
is.Empty(result2)
}
@@ -555,12 +515,10 @@ func TestFilterValues(t *testing.T) {
return v == "foo"
})
is.Equal([]string{"foo"}, result1)
is.Len(result1, 1)
result2 := FilterValues(map[string]int{"foo": 1, "bar": 2, "baz": 3}, func(k string, v int) bool {
return false
})
is.Equal([]int{}, result2)
is.Empty(result2)
}
@@ -606,19 +564,19 @@ func BenchmarkAssign(b *testing.B) {
sameMap := allTheSameMap(b, count)
b.Run(fmt.Sprintf("%d", count), func(b *testing.B) {
testcase := []struct {
testCases := []struct {
name string
maps []map[string]int
in []map[string]int
}{
{"different", differentMap},
{"same", sameMap},
}
for _, tc := range testcase {
for _, tc := range testCases {
b.Run(tc.name, func(b *testing.B) {
b.ResetTimer()
for n := 0; n < b.N; n++ {
result := Assign(tc.maps...)
result := Assign(tc.in...)
_ = result
}
})

View File

@@ -15,7 +15,7 @@ func TestRange(t *testing.T) {
result3 := Range(0)
is.Equal([]int{0, 1, 2, 3}, result1)
is.Equal([]int{0, -1, -2, -3}, result2)
is.Equal([]int{}, result3)
is.Empty(result3)
}
func TestRangeFrom(t *testing.T) {
@@ -29,7 +29,7 @@ func TestRangeFrom(t *testing.T) {
result5 := RangeFrom(-2.0, -3)
is.Equal([]int{1, 2, 3, 4, 5}, result1)
is.Equal([]int{-1, -2, -3, -4, -5}, result2)
is.Equal([]int{}, result3)
is.Empty(result3)
is.Equal([]float64{2.0, 3.0, 4.0}, result4)
is.Equal([]float64{-2.0, -3.0, -4.0}, result5)
}
@@ -45,9 +45,9 @@ func TestRangeClose(t *testing.T) {
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.Empty(result2)
is.Empty(result3)
is.Empty(result4)
is.Equal([]float64{1.0, 3.0}, result5)
is.Equal([]float32{-1.0, -2.0, -3.0}, result6)
}
@@ -185,6 +185,6 @@ func TestMode(t *testing.T) {
is.Equal([]float32{3.3}, result1)
is.Equal([]int32{2}, result2)
is.Equal([]uint32{2, 3}, result3)
is.Equal([]uint32{}, result4)
is.Empty(result4)
is.Equal([]int{1, 2, 3, 4, 5, 6, 7, 8, 9}, result5)
}

View File

@@ -47,14 +47,12 @@ func TestMap(t *testing.T) {
Map(list, func(x int) int {
return x * 2
})
is.Len(list, 4)
is.Equal([]int{2, 4, 6, 8}, list)
list = []int{1, 2, 3, 4}
Map(list, func(x int) int {
return x * 4
})
is.Len(list, 4)
is.Equal([]int{4, 8, 12, 16}, list)
}
@@ -67,7 +65,6 @@ func TestMapI(t *testing.T) {
is.Equal(index, x-1)
return x * 2
})
is.Len(list, 4)
is.Equal([]int{2, 4, 6, 8}, list)
list = []int{1, 2, 3, 4}
@@ -75,7 +72,6 @@ func TestMapI(t *testing.T) {
is.Equal(index, x-1)
return x * 4
})
is.Len(list, 4)
is.Equal([]int{4, 8, 12, 16}, list)
}
@@ -89,7 +85,7 @@ func TestShuffle(t *testing.T) {
list = []int{}
Shuffle(list)
is.Equal([]int{}, list)
is.Empty(list)
}
func TestReverse(t *testing.T) {
@@ -106,7 +102,7 @@ func TestReverse(t *testing.T) {
list = []int{}
Reverse(list)
is.Equal([]int{}, list)
is.Empty(list)
type myStrings []string
allStrings := myStrings{"", "foo", "bar"}
@@ -124,5 +120,5 @@ func TestFill(t *testing.T) {
list2 := []string{}
Fill(list2, "b")
is.Equal([]string{}, list2)
is.Empty(list2)
}

View File

@@ -19,8 +19,6 @@ func TestMap(t *testing.T) {
return strconv.FormatInt(x, 10)
})
is.Len(result1, 4)
is.Len(result2, 4)
is.Equal([]string{"Hello", "Hello", "Hello", "Hello"}, result1)
is.Equal([]string{"1", "2", "3", "4"}, result2)
}
@@ -44,7 +42,6 @@ func TestTimes(t *testing.T) {
return strconv.FormatInt(int64(i), 10)
})
is.Len(result1, 3)
is.Equal([]string{"0", "1", "2"}, result1)
}
@@ -57,12 +54,9 @@ func TestGroupBy(t *testing.T) {
// order
for x := range result1 {
sort.Slice(result1[x], func(i, j int) bool {
return result1[x][i] < result1[x][j]
})
sort.Ints(result1[x])
}
is.Len(result1, 3)
is.Equal(map[int][]int{
0: {0, 3},
1: {1, 4},
@@ -97,13 +91,11 @@ func TestPartitionBy(t *testing.T) {
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]
})
sort.Ints(result1[x])
}
is.ElementsMatch(result1, [][]int{{-2, -1}, {0, 2, 4}, {1, 3, 5}})
is.Equal([][]int{}, result2)
is.Empty(result2)
type myStrings []string
allStrings := myStrings{"", "foo", "bar"}

View File

@@ -45,7 +45,7 @@ func TestAttempt(t *testing.T) {
is.Equal(6, iter2)
is.NoError(err2)
is.Equal(2, iter3)
is.Equal(err3, err)
is.ErrorIs(err3, err)
is.Equal(43, iter4)
is.NoError(err4)
}
@@ -92,7 +92,7 @@ func TestAttemptWithDelay(t *testing.T) {
is.Equal(2, iter3)
is.Greater(dur3, 10*time.Millisecond)
is.Less(dur3, 20*time.Millisecond)
is.Equal(err3, err)
is.ErrorIs(err3, err)
is.Equal(11, iter4)
is.Greater(dur4, 100*time.Millisecond)
is.Less(dur4, 115*time.Millisecond)
@@ -131,7 +131,7 @@ func TestAttemptWhile(t *testing.T) {
})
is.Equal(2, iter3)
is.Equal(err3, err)
is.ErrorIs(err3, err)
iter4, err4 := AttemptWhile(0, func(i int) (error, bool) {
if i < 42 {
@@ -215,7 +215,7 @@ func TestAttemptWhileWithDelay(t *testing.T) {
is.Equal(2, iter3)
is.Greater(dur3, 10*time.Millisecond)
is.Less(dur3, 20*time.Millisecond)
is.Equal(err3, err)
is.ErrorIs(err3, err)
iter4, dur4, err4 := AttemptWhileWithDelay(0, 10*time.Millisecond, func(i int, d time.Duration) (error, bool) {
if i < 10 {
@@ -462,7 +462,7 @@ func TestTransaction(t *testing.T) {
state, err := transaction.Process(21)
is.Equal(21, state)
is.Equal(assert.AnError, err)
is.ErrorIs(err, assert.AnError)
}
// with error + update value
@@ -495,7 +495,7 @@ func TestTransaction(t *testing.T) {
state, err := transaction.Process(21)
is.Equal(42, state)
is.Equal(assert.AnError, err)
is.ErrorIs(err, assert.AnError)
}
}

View File

@@ -3,7 +3,6 @@ package lo
import (
"fmt"
"math"
"reflect"
"strconv"
"strings"
"testing"
@@ -44,8 +43,6 @@ func TestMap(t *testing.T) {
return strconv.FormatInt(x, 10)
})
is.Len(result1, 4)
is.Len(result2, 4)
is.Equal([]string{"Hello", "Hello", "Hello", "Hello"}, result1)
is.Equal([]string{"1", "2", "3", "4"}, result2)
}
@@ -84,8 +81,6 @@ func TestFilterMap(t *testing.T) {
return "", false
})
is.Len(r1, 2)
is.Len(r2, 2)
is.Equal([]string{"2", "4"}, r1)
is.Equal([]string{"xpu", "xpu"}, r2)
}
@@ -105,8 +100,6 @@ func TestFlatMap(t *testing.T) {
return result
})
is.Len(result1, 5)
is.Len(result2, 10)
is.Equal([]string{"Hello", "Hello", "Hello", "Hello", "Hello"}, result1)
is.Equal([]string{"1", "2", "2", "3", "3", "3", "4", "4", "4", "4"}, result2)
}
@@ -118,8 +111,6 @@ func TestTimes(t *testing.T) {
result1 := Times(3, func(i int) string {
return strconv.FormatInt(int64(i), 10)
})
is.Len(result1, 3)
is.Equal([]string{"0", "1", "2"}, result1)
}
@@ -169,8 +160,8 @@ func TestForEach(t *testing.T) {
callParams2 = append(callParams2, i)
})
is.ElementsMatch([]string{"a", "b", "c"}, callParams1)
is.ElementsMatch([]int{0, 1, 2}, callParams2)
is.Equal([]string{"a", "b", "c"}, callParams1)
is.Equal([]int{0, 1, 2}, callParams2)
is.IsIncreasing(callParams2)
}
@@ -192,8 +183,8 @@ func TestForEachWhile(t *testing.T) {
return true
})
is.ElementsMatch([]string{"a", "b"}, callParams1)
is.ElementsMatch([]int{0, 1}, callParams2)
is.Equal([]string{"a", "b"}, callParams1)
is.Equal([]int{0, 1}, callParams2)
is.IsIncreasing(callParams2)
}
@@ -202,8 +193,6 @@ func TestUniq(t *testing.T) {
is := assert.New(t)
result1 := Uniq([]int{1, 2, 2, 1})
is.Len(result1, 2)
is.Equal([]int{1, 2}, result1)
type myStrings []string
@@ -219,8 +208,6 @@ func TestUniqBy(t *testing.T) {
result1 := UniqBy([]int{0, 1, 2, 3, 4, 5}, func(i int) int {
return i % 3
})
is.Len(result1, 3)
is.Equal([]int{0, 1, 2}, result1)
type myStrings []string
@@ -238,8 +225,6 @@ func TestGroupBy(t *testing.T) {
result1 := GroupBy([]int{0, 1, 2, 3, 4, 5}, func(i int) int {
return i % 3
})
is.Len(result1, 3)
is.Equal(map[int][]int{
0: {0, 3},
1: {1, 4},
@@ -261,8 +246,6 @@ func TestGroupByMap(t *testing.T) {
result1 := GroupByMap([]int{0, 1, 2, 3, 4, 5}, func(i int) (int, string) {
return i % 3, strconv.Itoa(i)
})
is.Len(result1, 3)
is.Equal(map[int][]string{
0: {"0", "3"},
1: {"1", "4"},
@@ -274,8 +257,6 @@ func TestGroupByMap(t *testing.T) {
result2 := GroupByMap(myInts{1, 0, 2, 3, 4, 5}, func(i myInt) (int, string) {
return int(i % 3), strconv.Itoa(int(i))
})
is.Len(result2, 3)
is.Equal(map[int][]string{
0: {"0", "3"},
1: {"1", "4"},
@@ -296,8 +277,6 @@ func TestGroupByMap(t *testing.T) {
result3 := GroupByMap(products, func(item product) (int64, string) {
return item.CategoryID, "Product " + strconv.FormatInt(item.ID, 10)
})
is.Len(result3, 3)
is.Equal(map[int64][]string{
1: {"Product 1", "Product 2"},
2: {"Product 3"},
@@ -316,7 +295,7 @@ func TestChunk(t *testing.T) {
is.Equal([][]int{{0, 1}, {2, 3}, {4, 5}}, result1)
is.Equal([][]int{{0, 1}, {2, 3}, {4, 5}, {6}}, result2)
is.Equal([][]int{}, result3)
is.Empty(result3)
is.Equal([][]int{{0}}, result4)
is.PanicsWithValue("lo.Chunk: size must be greater than 0", func() {
Chunk([]int{0}, 0)
@@ -351,7 +330,7 @@ func TestPartitionBy(t *testing.T) {
result2 := PartitionBy([]int{}, oddEven)
is.Equal([][]int{{-2, -1}, {0, 2, 4}, {1, 3, 5}}, result1)
is.Equal([][]int{}, result2)
is.Empty(result2)
type myStrings []string
allStrings := myStrings{"", "foo", "bar"}
@@ -378,9 +357,9 @@ func TestFlatten(t *testing.T) {
func TestInterleave(t *testing.T) {
is := assert.New(t)
tests := []struct {
testCases := []struct {
name string
collections [][]int
in [][]int
want []int
}{
{
@@ -414,11 +393,11 @@ func TestInterleave(t *testing.T) {
[]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := Interleave(tt.collections...); !reflect.DeepEqual(got, tt.want) {
t.Errorf("Interleave() = %v, want %v", got, tt.want)
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
tc := tc
t.Parallel()
assert.Equal(t, tc.want, Interleave(tc.in...))
})
}
@@ -436,7 +415,7 @@ func TestShuffle(t *testing.T) {
result2 := Shuffle([]int{})
is.NotEqual([]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, result1)
is.Equal([]int{}, result2)
is.Empty(result2)
type myStrings []string
allStrings := myStrings{"", "foo", "bar"}
@@ -454,7 +433,7 @@ func TestReverse(t *testing.T) {
is.Equal([]int{5, 4, 3, 2, 1, 0}, result1)
is.Equal([]int{6, 5, 4, 3, 2, 1, 0}, result2)
is.Equal([]int{}, result3)
is.Empty(result3)
type myStrings []string
allStrings := myStrings{"", "foo", "bar"}
@@ -470,7 +449,7 @@ func TestFill(t *testing.T) {
result2 := Fill([]foo{}, foo{"a"})
is.Equal([]foo{{"b"}, {"b"}}, result1)
is.Equal([]foo{}, result2)
is.Empty(result2)
}
func TestRepeat(t *testing.T) {
@@ -481,7 +460,7 @@ func TestRepeat(t *testing.T) {
result2 := Repeat(0, foo{"a"})
is.Equal([]foo{{"a"}, {"a"}}, result1)
is.Equal([]foo{}, result2)
is.Empty(result2)
}
func TestRepeatBy(t *testing.T) {
@@ -496,7 +475,7 @@ func TestRepeatBy(t *testing.T) {
result2 := RepeatBy(2, cb)
result3 := RepeatBy(5, cb)
is.Equal([]int{}, result1)
is.Empty(result1)
is.Equal([]int{0, 1}, result2)
is.Equal([]int{0, 1, 4, 9, 16}, result3)
}
@@ -524,25 +503,26 @@ func TestAssociate(t *testing.T) {
}
testCases := []struct {
in []*foo
expect map[string]int
want map[string]int
}{
{
in: []*foo{{baz: "apple", bar: 1}},
expect: map[string]int{"apple": 1},
want: map[string]int{"apple": 1},
},
{
in: []*foo{{baz: "apple", bar: 1}, {baz: "banana", bar: 2}},
expect: map[string]int{"apple": 1, "banana": 2},
want: map[string]int{"apple": 1, "banana": 2},
},
{
in: []*foo{{baz: "apple", bar: 1}, {baz: "apple", bar: 2}},
expect: map[string]int{"apple": 2},
want: map[string]int{"apple": 2},
},
}
for i, testCase := range testCases {
for i, tc := range testCases {
t.Run(fmt.Sprintf("test_%d", i), func(t *testing.T) {
is := assert.New(t)
is.Equal(Associate(testCase.in, transform), testCase.expect)
tc := tc
t.Parallel()
assert.Equal(t, tc.want, Associate(tc.in, transform))
})
}
}
@@ -559,25 +539,26 @@ func TestSliceToMap(t *testing.T) {
}
testCases := []struct {
in []*foo
expect map[string]int
want map[string]int
}{
{
in: []*foo{{baz: "apple", bar: 1}},
expect: map[string]int{"apple": 1},
want: map[string]int{"apple": 1},
},
{
in: []*foo{{baz: "apple", bar: 1}, {baz: "banana", bar: 2}},
expect: map[string]int{"apple": 1, "banana": 2},
want: map[string]int{"apple": 1, "banana": 2},
},
{
in: []*foo{{baz: "apple", bar: 1}, {baz: "apple", bar: 2}},
expect: map[string]int{"apple": 2},
want: map[string]int{"apple": 2},
},
}
for i, testCase := range testCases {
for i, tc := 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)
tc := tc
t.Parallel()
assert.Equal(t, tc.want, SliceToMap(tc.in, transform))
})
}
}
@@ -594,25 +575,26 @@ func TestFilterSliceToMap(t *testing.T) {
}
testCases := []struct {
in []*foo
expect map[string]int
want map[string]int
}{
{
in: []*foo{{baz: "apple", bar: 1}},
expect: map[string]int{},
want: map[string]int{},
},
{
in: []*foo{{baz: "apple", bar: 1}, {baz: "banana", bar: 2}},
expect: map[string]int{"banana": 2},
want: map[string]int{"banana": 2},
},
{
in: []*foo{{baz: "apple", bar: 1}, {baz: "apple", bar: 2}},
expect: map[string]int{"apple": 2},
want: map[string]int{"apple": 2},
},
}
for i, testCase := range testCases {
for i, tc := range testCases {
t.Run(fmt.Sprintf("test_%d", i), func(t *testing.T) {
is := assert.New(t)
is.Equal(FilterSliceToMap(testCase.in, transform), testCase.expect)
tc := tc
t.Parallel()
assert.Equal(t, tc.want, FilterSliceToMap(tc.in, transform))
})
}
}
@@ -626,7 +608,7 @@ func TestKeyify(t *testing.T) {
result3 := Keyify([]int{})
is.Equal(map[int]struct{}{1: {}, 2: {}, 3: {}, 4: {}}, result1)
is.Equal(map[int]struct{}{1: {}, 2: {}}, result2)
is.Equal(map[int]struct{}{}, result3)
is.Empty(result3)
}
func TestDrop(t *testing.T) {
@@ -637,8 +619,8 @@ func TestDrop(t *testing.T) {
is.Equal([]int{2, 3, 4}, Drop([]int{0, 1, 2, 3, 4}, 2))
is.Equal([]int{3, 4}, Drop([]int{0, 1, 2, 3, 4}, 3))
is.Equal([]int{4}, Drop([]int{0, 1, 2, 3, 4}, 4))
is.Equal([]int{}, Drop([]int{0, 1, 2, 3, 4}, 5))
is.Equal([]int{}, Drop([]int{0, 1, 2, 3, 4}, 6))
is.Empty(Drop([]int{0, 1, 2, 3, 4}, 5))
is.Empty(Drop([]int{0, 1, 2, 3, 4}, 6))
type myStrings []string
allStrings := myStrings{"", "foo", "bar"}
@@ -654,8 +636,8 @@ func TestDropRight(t *testing.T) {
is.Equal([]int{0, 1, 2}, DropRight([]int{0, 1, 2, 3, 4}, 2))
is.Equal([]int{0, 1}, DropRight([]int{0, 1, 2, 3, 4}, 3))
is.Equal([]int{0}, DropRight([]int{0, 1, 2, 3, 4}, 4))
is.Equal([]int{}, DropRight([]int{0, 1, 2, 3, 4}, 5))
is.Equal([]int{}, DropRight([]int{0, 1, 2, 3, 4}, 6))
is.Empty(DropRight([]int{0, 1, 2, 3, 4}, 5))
is.Empty(DropRight([]int{0, 1, 2, 3, 4}, 6))
type myStrings []string
allStrings := myStrings{"", "foo", "bar"}
@@ -671,7 +653,7 @@ func TestDropWhile(t *testing.T) {
return t != 4
}))
is.Equal([]int{}, DropWhile([]int{0, 1, 2, 3, 4, 5, 6}, func(t int) bool {
is.Empty(DropWhile([]int{0, 1, 2, 3, 4, 5, 6}, func(t int) bool {
return true
}))
@@ -703,7 +685,7 @@ func TestDropRightWhile(t *testing.T) {
return t == 10
}))
is.Equal([]int{}, DropRightWhile([]int{0, 1, 2, 3, 4, 5, 6}, func(t int) bool {
is.Empty(DropRightWhile([]int{0, 1, 2, 3, 4, 5, 6}, func(t int) bool {
return t != 10
}))
@@ -729,11 +711,11 @@ func TestDropByIndex(t *testing.T) {
is.Equal([]int{0, 1, 2, 3, 4}, DropByIndex([]int{0, 1, 2, 3, 4}, 5))
is.Equal([]int{0, 1, 2, 3, 4}, DropByIndex([]int{0, 1, 2, 3, 4}, 100))
is.Equal([]int{0, 1, 2, 3}, DropByIndex([]int{0, 1, 2, 3, 4}, -1))
is.Equal([]int{}, DropByIndex([]int{}, 0, 1))
is.Equal([]int{}, DropByIndex([]int{42}, 0, 1))
is.Equal([]int{}, DropByIndex([]int{42}, 1, 0))
is.Equal([]int{}, DropByIndex([]int{}, 1))
is.Equal([]int{}, DropByIndex([]int{1}, 0))
is.Empty(DropByIndex([]int{}, 0, 1))
is.Empty(DropByIndex([]int{42}, 0, 1))
is.Empty(DropByIndex([]int{42}, 1, 0))
is.Empty(DropByIndex([]int{}, 1))
is.Empty(DropByIndex([]int{1}, 0))
}
func TestReject(t *testing.T) {
@@ -777,8 +759,6 @@ func TestRejectMap(t *testing.T) {
return "", true
})
is.Len(r1, 2)
is.Len(r2, 2)
is.Equal([]string{"2", "4"}, r1)
is.Equal([]string{"xpu", "xpu"}, r2)
}
@@ -848,7 +828,7 @@ func TestCountValues(t *testing.T) {
t.Parallel()
is := assert.New(t)
is.Equal(map[int]int{}, CountValues([]int{}))
is.Empty(CountValues([]int{}))
is.Equal(map[int]int{1: 1, 2: 1}, CountValues([]int{1, 2}))
is.Equal(map[int]int{1: 1, 2: 2}, CountValues([]int{1, 2, 2}))
is.Equal(map[string]int{"": 1, "foo": 1, "bar": 1}, CountValues([]string{"foo", "bar", ""}))
@@ -872,7 +852,7 @@ func TestCountValuesBy(t *testing.T) {
result4 := CountValuesBy([]string{"foo", "bar", ""}, length)
result5 := CountValuesBy([]string{"foo", "bar", "bar"}, length)
is.Equal(map[bool]int{}, result1)
is.Empty(result1)
is.Equal(map[bool]int{true: 1, false: 1}, result2)
is.Equal(map[bool]int{true: 2, false: 1}, result3)
is.Equal(map[int]int{0: 1, 3: 2}, result4)
@@ -898,8 +878,8 @@ func TestSubset(t *testing.T) {
out11 := Subset(in, -4, 1)
out12 := Subset(in, -4, math.MaxUint)
is.Equal([]int{}, out1)
is.Equal([]int{}, out2)
is.Empty(out1)
is.Empty(out2)
is.Equal([]int{0, 1}, out3)
is.Equal([]int{0, 1, 2, 3, 4}, out4)
is.Equal([]int{0, 1}, out5)
@@ -942,21 +922,21 @@ func TestSlice(t *testing.T) {
out17 := Slice(in, -1, 3)
out18 := Slice(in, -10, 7)
is.Equal([]int{}, out1)
is.Empty(out1)
is.Equal([]int{0}, out2)
is.Equal([]int{0, 1, 2, 3, 4}, out3)
is.Equal([]int{0, 1, 2, 3, 4}, out4)
is.Equal([]int{}, out5)
is.Empty(out5)
is.Equal([]int{1, 2, 3, 4}, out6)
is.Equal([]int{1, 2, 3, 4}, out7)
is.Equal([]int{4}, out8)
is.Equal([]int{}, out9)
is.Equal([]int{}, out10)
is.Equal([]int{}, out11)
is.Equal([]int{}, out12)
is.Equal([]int{}, out13)
is.Equal([]int{}, out14)
is.Equal([]int{}, out15)
is.Empty(out9)
is.Empty(out10)
is.Empty(out11)
is.Empty(out12)
is.Empty(out13)
is.Empty(out14)
is.Empty(out15)
is.Equal([]int{0}, out16)
is.Equal([]int{0, 1, 2}, out17)
is.Equal([]int{0, 1, 2, 3, 4}, out18)

View File

@@ -110,309 +110,308 @@ func TestAllCase(t *testing.T) {
KebabCase string
SnakeCase string
}
name := ""
tests := []struct {
testCases := []struct {
name string
input string
output output
in string
want output
}{
{name: name, output: output{}},
{name: name, input: ".", output: output{}},
{name: name, input: "Hello world!", output: output{
{want: output{}},
{in: ".", want: output{}},
{in: "Hello world!", want: output{
PascalCase: "HelloWorld",
CamelCase: "helloWorld",
KebabCase: "hello-world",
SnakeCase: "hello_world",
}},
{name: name, input: "A", output: output{
{in: "A", want: output{
PascalCase: "A",
CamelCase: "a",
KebabCase: "a",
SnakeCase: "a",
}},
{name: name, input: "a", output: output{
{in: "a", want: output{
PascalCase: "A",
CamelCase: "a",
KebabCase: "a",
SnakeCase: "a",
}},
{name: name, input: "foo", output: output{
{in: "foo", want: output{
PascalCase: "Foo",
CamelCase: "foo",
KebabCase: "foo",
SnakeCase: "foo",
}},
{name: name, input: "snake_case", output: output{
{in: "snake_case", want: output{
PascalCase: "SnakeCase",
CamelCase: "snakeCase",
KebabCase: "snake-case",
SnakeCase: "snake_case",
}},
{name: name, input: "SNAKE_CASE", output: output{
{in: "SNAKE_CASE", want: output{
PascalCase: "SnakeCase",
CamelCase: "snakeCase",
KebabCase: "snake-case",
SnakeCase: "snake_case",
}},
{name: name, input: "kebab-case", output: output{
{in: "kebab-case", want: output{
PascalCase: "KebabCase",
CamelCase: "kebabCase",
KebabCase: "kebab-case",
SnakeCase: "kebab_case",
}},
{name: name, input: "PascalCase", output: output{
{in: "PascalCase", want: output{
PascalCase: "PascalCase",
CamelCase: "pascalCase",
KebabCase: "pascal-case",
SnakeCase: "pascal_case",
}},
{name: name, input: "camelCase", output: output{
{in: "camelCase", want: output{
PascalCase: "CamelCase",
CamelCase: "camelCase",
KebabCase: `camel-case`,
SnakeCase: "camel_case",
}},
{name: name, input: "Title Case", output: output{
{in: "Title Case", want: output{
PascalCase: "TitleCase",
CamelCase: "titleCase",
KebabCase: "title-case",
SnakeCase: "title_case",
}},
{name: name, input: "point.case", output: output{
{in: "point.case", want: output{
PascalCase: "PointCase",
CamelCase: "pointCase",
KebabCase: "point-case",
SnakeCase: "point_case",
}},
{name: name, input: "snake_case_with_more_words", output: output{
{in: "snake_case_with_more_words", want: 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{
{in: "SNAKE_CASE_WITH_MORE_WORDS", want: 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{
{in: "kebab-case-with-more-words", want: output{
PascalCase: "KebabCaseWithMoreWords",
CamelCase: "kebabCaseWithMoreWords",
KebabCase: "kebab-case-with-more-words",
SnakeCase: "kebab_case_with_more_words",
}},
{name: name, input: "PascalCaseWithMoreWords", output: output{
{in: "PascalCaseWithMoreWords", want: output{
PascalCase: "PascalCaseWithMoreWords",
CamelCase: "pascalCaseWithMoreWords",
KebabCase: "pascal-case-with-more-words",
SnakeCase: "pascal_case_with_more_words",
}},
{name: name, input: "camelCaseWithMoreWords", output: output{
{in: "camelCaseWithMoreWords", want: 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{
{in: "Title Case With More Words", want: 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{
{in: "point.case.with.more.words", want: 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{
{in: "snake_case__with___multiple____delimiters", want: 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{
{in: "SNAKE_CASE__WITH___multiple____DELIMITERS", want: 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{
{in: "kebab-case--with---multiple----delimiters", want: 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{
{in: "Title Case With Multiple Delimiters", want: 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{
{in: "point.case..with...multiple....delimiters", want: output{
PascalCase: "PointCaseWithMultipleDelimiters",
CamelCase: "pointCaseWithMultipleDelimiters",
KebabCase: "point-case-with-multiple-delimiters",
SnakeCase: "point_case_with_multiple_delimiters",
}},
{name: name, input: " leading space", output: output{
{in: " leading space", want: output{
PascalCase: "LeadingSpace",
CamelCase: "leadingSpace",
KebabCase: "leading-space",
SnakeCase: "leading_space",
}},
{name: name, input: " leading spaces", output: output{
{in: " leading spaces", want: output{
PascalCase: "LeadingSpaces",
CamelCase: "leadingSpaces",
KebabCase: "leading-spaces",
SnakeCase: "leading_spaces",
}},
{name: name, input: "\t\t\r\n leading whitespaces", output: output{
{in: "\t\t\r\n leading whitespaces", want: output{
PascalCase: "LeadingWhitespaces",
CamelCase: "leadingWhitespaces",
KebabCase: "leading-whitespaces",
SnakeCase: "leading_whitespaces",
}},
{name: name, input: "trailing space ", output: output{
{in: "trailing space ", want: output{
PascalCase: "TrailingSpace",
CamelCase: "trailingSpace",
KebabCase: "trailing-space",
SnakeCase: "trailing_space",
}},
{name: name, input: "trailing spaces ", output: output{
{in: "trailing spaces ", want: output{
PascalCase: "TrailingSpaces",
CamelCase: "trailingSpaces",
KebabCase: "trailing-spaces",
SnakeCase: "trailing_spaces",
}},
{name: name, input: "trailing whitespaces\t\t\r\n", output: output{
{in: "trailing whitespaces\t\t\r\n", want: output{
PascalCase: "TrailingWhitespaces",
CamelCase: "trailingWhitespaces",
KebabCase: "trailing-whitespaces",
SnakeCase: "trailing_whitespaces",
}},
{name: name, input: " on both sides ", output: output{
{in: " on both sides ", want: output{
PascalCase: "OnBothSides",
CamelCase: "onBothSides",
KebabCase: "on-both-sides",
SnakeCase: "on_both_sides",
}},
{name: name, input: " many on both sides ", output: output{
{in: " many on both sides ", want: 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{
{in: "\r whitespaces on both sides\t\t\r\n", want: 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{
{in: " extraSpaces in_This TestCase Of MIXED_CASES\t", want: 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{
{in: "CASEBreak", want: output{
PascalCase: "CaseBreak",
CamelCase: "caseBreak",
KebabCase: "case-break",
SnakeCase: "case_break",
}},
{name: name, input: "ID", output: output{
{in: "ID", want: output{
PascalCase: "Id",
CamelCase: "id",
KebabCase: "id",
SnakeCase: "id",
}},
{name: name, input: "userID", output: output{
{in: "userID", want: output{
PascalCase: "UserId",
CamelCase: "userId",
KebabCase: "user-id",
SnakeCase: "user_id",
}},
{name: name, input: "JSON_blob", output: output{
{in: "JSON_blob", want: output{
PascalCase: "JsonBlob",
CamelCase: "jsonBlob",
KebabCase: "json-blob",
SnakeCase: "json_blob",
}},
{name: name, input: "HTTPStatusCode", output: output{
{in: "HTTPStatusCode", want: 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{
{in: "FreeBSD and SSLError are not golang initialisms", want: 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{
{in: "David's Computer", want: output{
PascalCase: "DavidSComputer",
CamelCase: "davidSComputer",
KebabCase: "david-s-computer",
SnakeCase: "david_s_computer",
}},
{name: name, input: "http200", output: output{
{in: "http200", want: output{
PascalCase: "Http200",
CamelCase: "http200",
KebabCase: "http-200",
SnakeCase: "http_200",
}},
{name: name, input: "NumberSplittingVersion1.0r3", output: output{
{in: "NumberSplittingVersion1.0r3", want: 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{
{in: "When you have a comma, odd results", want: 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{
{in: "Ordinal numbers work: 1st 2nd and 3rd place", want: 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{
{in: "BadUTF8\xe2\xe2\xa1", want: output{
PascalCase: "BadUtf8",
CamelCase: "badUtf8",
KebabCase: "bad-utf-8",
SnakeCase: "bad_utf_8",
}},
{name: name, input: "IDENT3", output: output{
{in: "IDENT3", want: output{
PascalCase: "Ident3",
CamelCase: "ident3",
KebabCase: "ident-3",
SnakeCase: "ident_3",
}},
{name: name, input: "LogRouterS3BucketName", output: output{
{in: "LogRouterS3BucketName", want: output{
PascalCase: "LogRouterS3BucketName",
CamelCase: "logRouterS3BucketName",
KebabCase: "log-router-s3-bucket-name",
SnakeCase: "log_router_s3_bucket_name",
}},
{name: name, input: "PINEAPPLE", output: output{
{in: "PINEAPPLE", want: output{
PascalCase: "Pineapple",
CamelCase: "pineapple",
KebabCase: "pineapple",
SnakeCase: "pineapple",
}},
{name: name, input: "Int8Value", output: output{
{in: "Int8Value", want: output{
PascalCase: "Int8Value",
CamelCase: "int8Value",
KebabCase: "int-8-value",
SnakeCase: "int_8_value",
}},
{name: name, input: "first.last", output: output{
{in: "first.last", want: output{
PascalCase: "FirstLast",
CamelCase: "firstLast",
KebabCase: "first-last",
@@ -420,68 +419,56 @@ func TestAllCase(t *testing.T) {
}},
}
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)
}
for _, tc := range testCases {
t.Run(tc.in, func(t *testing.T) {
tc := tc
t.Parallel()
is := assert.New(t)
is.Equalf(tc.want.PascalCase, PascalCase(tc.in), "PascalCase(%v)", tc.in)
is.Equalf(tc.want.CamelCase, CamelCase(tc.in), "CamelCase(%v)", tc.in)
is.Equalf(tc.want.KebabCase, KebabCase(tc.in), "KebabCase(%v)", tc.in)
is.Equalf(tc.want.SnakeCase, SnakeCase(tc.in), "SnakeCase(%v)", tc.in)
})
}
}
func TestWords(t *testing.T) {
type args struct {
str string
}
tests := []struct {
name string
args args
testCases := []struct {
in string
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"}},
{"PascalCase", []string{"Pascal", "Case"}},
{"camelCase", []string{"camel", "Case"}},
{"snake_case", []string{"snake", "case"}},
{"kebab_case", []string{"kebab", "case"}},
{"_test text_", []string{"test", "text"}},
{"UPPERCASE", []string{"UPPERCASE"}},
{"HTTPCode", []string{"HTTP", "Code"}},
{"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)
for _, tc := range testCases {
t.Run(tc.in, func(t *testing.T) {
tc := tc
t.Parallel()
assert.Equalf(t, tc.want, Words(tc.in), "Words(%v)", tc.in)
})
}
}
func TestCapitalize(t *testing.T) {
type args struct {
word string
}
tests := []struct {
testCases := []struct {
name string
args args
in string
want string
}{
{"", args{"hello"}, "Hello"},
{"", args{"heLLO"}, "Hello"},
{"lower case", "hello", "Hello"},
{"mixed case", "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)
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
tc := tc
t.Parallel()
assert.Equalf(t, tc.want, Capitalize(tc.in), "Capitalize(%v)", tc.in)
})
}
}

View File

@@ -96,10 +96,10 @@ func TestEmptyableToPtr(t *testing.T) {
is.Equal(42, *EmptyableToPtr(42))
is.Equal("nonempty", *EmptyableToPtr("nonempty"))
is.Equal([]int{}, *EmptyableToPtr([]int{}))
is.Empty(*EmptyableToPtr([]int{}))
is.Equal([]int{1, 2}, *EmptyableToPtr([]int{1, 2}))
is.Equal(map[int]int{}, *EmptyableToPtr(map[int]int{}))
is.Equal(*EmptyableToPtr(assert.AnError), assert.AnError)
is.Empty(*EmptyableToPtr(map[int]int{}))
is.Equal(assert.AnError, *EmptyableToPtr(assert.AnError))
}
func TestFromPtr(t *testing.T) {
@@ -175,7 +175,7 @@ func TestToAnySlice(t *testing.T) {
out2 := ToAnySlice(in2)
is.Equal([]any{0, 1, 2, 3}, out1)
is.Equal([]any{}, out2)
is.Empty(out2)
}
func TestFromAnySlice(t *testing.T) {
@@ -186,7 +186,7 @@ func TestFromAnySlice(t *testing.T) {
out1, ok1 := FromAnySlice[string]([]any{"foobar", 42})
out2, ok2 := FromAnySlice[string]([]any{"foobar", "42"})
is.Equal([]string{}, out1)
is.Empty(out1)
is.False(ok1)
is.Equal([]string{"foobar", "42"}, out2)
is.True(ok2)
@@ -363,27 +363,22 @@ func TestCoalesceSlice(t *testing.T) {
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)
@@ -429,19 +424,14 @@ func TestCoalesceSliceOrEmpty(t *testing.T) {
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)
@@ -476,27 +466,22 @@ func TestCoalesceMap(t *testing.T) {
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)
@@ -542,19 +527,14 @@ func TestCoalesceMapOrEmpty(t *testing.T) {
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)