Source file
src/slices/iter_test.go
1
2
3
4
5 package slices_test
6
7 import (
8 "iter"
9 "math/rand/v2"
10 . "slices"
11 "testing"
12 )
13
14 func TestAll(t *testing.T) {
15 for size := 0; size < 10; size++ {
16 var s []int
17 for i := range size {
18 s = append(s, i)
19 }
20 ei, ev := 0, 0
21 cnt := 0
22 for i, v := range All(s) {
23 if i != ei || v != ev {
24 t.Errorf("at iteration %d got %d, %d want %d, %d", cnt, i, v, ei, ev)
25 }
26 ei++
27 ev++
28 cnt++
29 }
30 if cnt != size {
31 t.Errorf("read %d values expected %d", cnt, size)
32 }
33 }
34 }
35
36 func TestBackward(t *testing.T) {
37 for size := 0; size < 10; size++ {
38 var s []int
39 for i := range size {
40 s = append(s, i)
41 }
42 ei, ev := size-1, size-1
43 cnt := 0
44 for i, v := range Backward(s) {
45 if i != ei || v != ev {
46 t.Errorf("at iteration %d got %d, %d want %d, %d", cnt, i, v, ei, ev)
47 }
48 ei--
49 ev--
50 cnt++
51 }
52 if cnt != size {
53 t.Errorf("read %d values expected %d", cnt, size)
54 }
55 }
56 }
57
58 func TestValues(t *testing.T) {
59 for size := 0; size < 10; size++ {
60 var s []int
61 for i := range size {
62 s = append(s, i)
63 }
64 ev := 0
65 cnt := 0
66 for v := range Values(s) {
67 if v != ev {
68 t.Errorf("at iteration %d got %d want %d", cnt, v, ev)
69 }
70 ev++
71 cnt++
72 }
73 if cnt != size {
74 t.Errorf("read %d values expected %d", cnt, size)
75 }
76 }
77 }
78
79 func testSeq(yield func(int) bool) {
80 for i := 0; i < 10; i += 2 {
81 if !yield(i) {
82 return
83 }
84 }
85 }
86
87 var testSeqResult = []int{0, 2, 4, 6, 8}
88
89 func TestAppendSeq(t *testing.T) {
90 s := AppendSeq([]int{1, 2}, testSeq)
91 want := append([]int{1, 2}, testSeqResult...)
92 if !Equal(s, want) {
93 t.Errorf("got %v, want %v", s, want)
94 }
95 }
96
97 func TestCollect(t *testing.T) {
98 s := Collect(testSeq)
99 want := testSeqResult
100 if !Equal(s, want) {
101 t.Errorf("got %v, want %v", s, want)
102 }
103 }
104
105 var iterTests = [][]string{
106 nil,
107 {"a"},
108 {"a", "b"},
109 {"b", "a"},
110 strs[:],
111 }
112
113 func TestValuesAppendSeq(t *testing.T) {
114 for _, prefix := range iterTests {
115 for _, s := range iterTests {
116 got := AppendSeq(prefix, Values(s))
117 want := append(prefix, s...)
118 if !Equal(got, want) {
119 t.Errorf("AppendSeq(%v, Values(%v)) == %v, want %v", prefix, s, got, want)
120 }
121 }
122 }
123 }
124
125 func TestValuesCollect(t *testing.T) {
126 for _, s := range iterTests {
127 got := Collect(Values(s))
128 if !Equal(got, s) {
129 t.Errorf("Collect(Values(%v)) == %v, want %v", s, got, s)
130 }
131 }
132 }
133
134 func TestSorted(t *testing.T) {
135 s := Sorted(Values(ints[:]))
136 if !IsSorted(s) {
137 t.Errorf("sorted %v", ints)
138 t.Errorf(" got %v", s)
139 }
140 }
141
142 func TestSortedFunc(t *testing.T) {
143 s := SortedFunc(Values(ints[:]), func(a, b int) int { return a - b })
144 if !IsSorted(s) {
145 t.Errorf("sorted %v", ints)
146 t.Errorf(" got %v", s)
147 }
148 }
149
150 func TestSortedStableFunc(t *testing.T) {
151 n, m := 1000, 100
152 data := make(intPairs, n)
153 for i := range data {
154 data[i].a = rand.IntN(m)
155 }
156 data.initB()
157
158 s := intPairs(SortedStableFunc(Values(data), intPairCmp))
159 if !IsSortedFunc(s, intPairCmp) {
160 t.Errorf("SortedStableFunc didn't sort %d ints", n)
161 }
162 if !s.inOrder(false) {
163 t.Errorf("SortedStableFunc wasn't stable on %d ints", n)
164 }
165
166
167 iterVal := func(seq iter.Seq2[int, intPair]) iter.Seq[intPair] {
168 return func(yield func(intPair) bool) {
169 for _, v := range seq {
170 if !yield(v) {
171 return
172 }
173 }
174 }
175 }
176
177 s = intPairs(SortedStableFunc(iterVal(Backward(data)), intPairCmp))
178 if !IsSortedFunc(s, intPairCmp) {
179 t.Errorf("SortedStableFunc didn't sort %d reverse ints", n)
180 }
181 if !s.inOrder(true) {
182 t.Errorf("SortedStableFunc wasn't stable on %d reverse ints", n)
183 }
184 }
185
186 func TestChunk(t *testing.T) {
187 cases := []struct {
188 name string
189 s []int
190 n int
191 chunks [][]int
192 }{
193 {
194 name: "nil",
195 s: nil,
196 n: 1,
197 chunks: nil,
198 },
199 {
200 name: "empty",
201 s: []int{},
202 n: 1,
203 chunks: nil,
204 },
205 {
206 name: "short",
207 s: []int{1, 2},
208 n: 3,
209 chunks: [][]int{{1, 2}},
210 },
211 {
212 name: "one",
213 s: []int{1, 2},
214 n: 2,
215 chunks: [][]int{{1, 2}},
216 },
217 {
218 name: "even",
219 s: []int{1, 2, 3, 4},
220 n: 2,
221 chunks: [][]int{{1, 2}, {3, 4}},
222 },
223 {
224 name: "odd",
225 s: []int{1, 2, 3, 4, 5},
226 n: 2,
227 chunks: [][]int{{1, 2}, {3, 4}, {5}},
228 },
229 }
230
231 for _, tc := range cases {
232 t.Run(tc.name, func(t *testing.T) {
233 var chunks [][]int
234 for c := range Chunk(tc.s, tc.n) {
235 chunks = append(chunks, c)
236 }
237
238 if !chunkEqual(chunks, tc.chunks) {
239 t.Errorf("Chunk(%v, %d) = %v, want %v", tc.s, tc.n, chunks, tc.chunks)
240 }
241
242 if len(chunks) == 0 {
243 return
244 }
245
246
247
248 s := Clone(tc.s)
249 chunks[0] = append(chunks[0], -1)
250 if !Equal(s, tc.s) {
251 t.Errorf("slice was clobbered: %v, want %v", s, tc.s)
252 }
253 })
254 }
255 }
256
257 func TestChunkPanics(t *testing.T) {
258 for _, test := range []struct {
259 name string
260 x []struct{}
261 n int
262 }{
263 {
264 name: "cannot be less than 1",
265 x: make([]struct{}, 0),
266 n: 0,
267 },
268 } {
269 if !panics(func() { _ = Chunk(test.x, test.n) }) {
270 t.Errorf("Chunk %s: got no panic, want panic", test.name)
271 }
272 }
273 }
274
275 func TestChunkRange(t *testing.T) {
276
277 var got [][]int
278 for c := range Chunk([]int{1, 2, 3, 4, -100}, 2) {
279 if len(got) == 2 {
280
281 break
282 }
283
284 got = append(got, c)
285 }
286
287 if want := [][]int{{1, 2}, {3, 4}}; !chunkEqual(got, want) {
288 t.Errorf("Chunk iteration did not stop, got %v, want %v", got, want)
289 }
290 }
291
292 func chunkEqual[Slice ~[]E, E comparable](s1, s2 []Slice) bool {
293 return EqualFunc(s1, s2, Equal[Slice])
294 }
295
View as plain text