slice_test.go 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. package fn
  2. import (
  3. "fmt"
  4. "slices"
  5. "testing"
  6. "github.com/stretchr/testify/require"
  7. )
  8. func even(a int) bool { return a%2 == 0 }
  9. func odd(a int) bool { return a%2 != 0 }
  10. func TestAll(t *testing.T) {
  11. x := []int{0, 2, 4, 6, 8}
  12. require.True(t, All(even, x))
  13. require.False(t, All(odd, x))
  14. y := []int{1, 3, 5, 7, 9}
  15. require.False(t, All(even, y))
  16. require.True(t, All(odd, y))
  17. z := []int{0, 2, 4, 6, 9}
  18. require.False(t, All(even, z))
  19. require.False(t, All(odd, z))
  20. }
  21. func TestAny(t *testing.T) {
  22. x := []int{1, 3, 5, 7, 9}
  23. require.False(t, Any(even, x))
  24. require.True(t, Any(odd, x))
  25. y := []int{0, 3, 5, 7, 9}
  26. require.True(t, Any(even, y))
  27. require.True(t, Any(odd, y))
  28. z := []int{0, 2, 4, 6, 8}
  29. require.True(t, Any(even, z))
  30. require.False(t, Any(odd, z))
  31. }
  32. func TestMap(t *testing.T) {
  33. inc := func(i int) int { return i + 1 }
  34. x := []int{0, 2, 4, 6, 8}
  35. y := Map(inc, x)
  36. z := []int{1, 3, 5, 7, 9}
  37. require.True(t, slices.Equal(y, z))
  38. }
  39. func TestFilter(t *testing.T) {
  40. x := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
  41. y := Filter(even, x)
  42. require.True(t, All(even, y))
  43. z := Filter(odd, y)
  44. require.Zero(t, len(z))
  45. }
  46. func TestFoldl(t *testing.T) {
  47. seed := []int{}
  48. stupid := func(s []int, a int) []int { return append(s, a) }
  49. x := []int{0, 1, 2, 3, 4}
  50. r := Foldl(stupid, seed, x)
  51. require.True(t, slices.Equal(x, r))
  52. }
  53. func TestFoldr(t *testing.T) {
  54. seed := []int{}
  55. stupid := func(a int, s []int) []int { return append(s, a) }
  56. x := []int{0, 1, 2, 3, 4}
  57. z := Foldr(stupid, seed, x)
  58. slices.Reverse[[]int](x)
  59. require.True(t, slices.Equal(x, z))
  60. }
  61. func TestFind(t *testing.T) {
  62. x := []int{10, 11, 12, 13, 14, 15}
  63. div3 := func(a int) bool { return a%3 == 0 }
  64. div8 := func(a int) bool { return a%8 == 0 }
  65. require.Equal(t, Find(div3, x), Some(12))
  66. require.Equal(t, Find(div8, x), None[int]())
  67. }
  68. func TestFlatten(t *testing.T) {
  69. x := [][]int{{0}, {1}, {2}}
  70. y := Flatten(x)
  71. require.True(t, slices.Equal(y, []int{0, 1, 2}))
  72. }
  73. func TestReplicate(t *testing.T) {
  74. require.True(t, slices.Equal([]int{1, 1, 1, 1, 1}, Replicate(5, 1)))
  75. }
  76. func TestSpan(t *testing.T) {
  77. x := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
  78. lt5 := func(a int) bool { return a < 5 }
  79. low, high := Span(lt5, x)
  80. require.True(t, slices.Equal(low, []int{0, 1, 2, 3, 4}))
  81. require.True(t, slices.Equal(high, []int{5, 6, 7, 8, 9}))
  82. }
  83. func TestSplitAt(t *testing.T) {
  84. x := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
  85. fst, snd := SplitAt(5, x)
  86. require.True(t, slices.Equal(fst, []int{0, 1, 2, 3, 4}))
  87. require.True(t, slices.Equal(snd, []int{5, 6, 7, 8, 9}))
  88. }
  89. func TestZipWith(t *testing.T) {
  90. eq := func(a, b int) bool { return a == b }
  91. x := []int{0, 1, 2, 3, 4}
  92. y := Replicate(5, 1)
  93. z := ZipWith(eq, x, y)
  94. require.True(t, slices.Equal(
  95. z, []bool{false, true, false, false, false},
  96. ))
  97. }
  98. // TestSum checks if the Sum function correctly calculates the sum of the
  99. // numbers in the slice.
  100. func TestSum(t *testing.T) {
  101. tests := []struct {
  102. name string
  103. items interface{}
  104. result interface{}
  105. }{
  106. {
  107. name: "Sum of positive integers",
  108. items: []int{1, 2, 3},
  109. result: 6,
  110. },
  111. {
  112. name: "Sum of negative integers",
  113. items: []int{-1, -2, -3},
  114. result: -6,
  115. },
  116. {
  117. name: "Sum of float numbers",
  118. items: []float64{1.1, 2.2, 3.3},
  119. result: 6.6,
  120. },
  121. {
  122. name: "Sum of complex numbers",
  123. items: []complex128{
  124. complex(1, 1),
  125. complex(2, 2),
  126. complex(3, 3),
  127. },
  128. result: complex(6, 6),
  129. },
  130. }
  131. for _, tt := range tests {
  132. t.Run(tt.name, func(t *testing.T) {
  133. switch v := tt.items.(type) {
  134. case []int:
  135. require.Equal(t, tt.result, Sum(v))
  136. case []float64:
  137. require.Equal(t, tt.result, Sum(v))
  138. case []complex128:
  139. require.Equal(t, tt.result, Sum(v))
  140. }
  141. })
  142. }
  143. }
  144. // TestSliceToMap tests the SliceToMap function.
  145. func TestSliceToMap(t *testing.T) {
  146. tests := []struct {
  147. name string
  148. slice []int
  149. keyFunc func(int) int
  150. valueFunc func(int) string
  151. expected map[int]string
  152. }{
  153. {
  154. name: "Integers to string map",
  155. slice: []int{1, 2, 3},
  156. keyFunc: func(a int) int { return a },
  157. valueFunc: func(a int) string {
  158. return fmt.Sprintf("Value%d", a)
  159. },
  160. expected: map[int]string{
  161. 1: "Value1",
  162. 2: "Value2",
  163. 3: "Value3",
  164. },
  165. },
  166. {
  167. name: "Duplicates in slice",
  168. slice: []int{1, 2, 2, 3},
  169. keyFunc: func(a int) int { return a },
  170. valueFunc: func(a int) string {
  171. return fmt.Sprintf("Value%d", a)
  172. },
  173. expected: map[int]string{
  174. 1: "Value1",
  175. 2: "Value2",
  176. 3: "Value3",
  177. },
  178. },
  179. {
  180. name: "Empty slice",
  181. slice: []int{},
  182. keyFunc: func(a int) int { return a },
  183. valueFunc: func(a int) string {
  184. return fmt.Sprintf("Value%d", a)
  185. },
  186. expected: map[int]string{},
  187. },
  188. }
  189. for _, tt := range tests {
  190. t.Run(tt.name, func(t *testing.T) {
  191. require.Equal(
  192. t, tt.expected,
  193. SliceToMap(tt.slice, tt.keyFunc, tt.valueFunc),
  194. )
  195. })
  196. }
  197. }
  198. // TestHasDuplicates tests the HasDuplicates function.
  199. func TestHasDuplicates(t *testing.T) {
  200. // Define test cases.
  201. testCases := []struct {
  202. name string
  203. items []int
  204. want bool
  205. }{
  206. {
  207. name: "All unique",
  208. items: []int{1, 2, 3, 4, 5},
  209. want: false,
  210. },
  211. {
  212. name: "Some duplicates",
  213. items: []int{1, 2, 2, 3, 4},
  214. want: true,
  215. },
  216. {
  217. name: "No items",
  218. items: []int{},
  219. want: false,
  220. },
  221. {
  222. name: "All duplicates",
  223. items: []int{1, 1, 1, 1},
  224. want: true,
  225. },
  226. }
  227. // Execute each test case.
  228. for _, tc := range testCases {
  229. t.Run(tc.name, func(t *testing.T) {
  230. got := HasDuplicates(tc.items)
  231. require.Equal(t, tc.want, got)
  232. })
  233. }
  234. }