v2 / vlib / arrays / arrays_test.v
606 lines · 526 sloc · 13.42 KB · 4b1035f7ba94a1d247e4be3c4636f0b6fcab210c
Raw
1module arrays
2
3fn test_min() {
4 a := [8, 2, 6, 4]
5 mut ri := min(a)!
6 assert ri == 2
7 ri = min(a[2..])!
8 assert ri == 4
9 b := [f32(5.1), 3.1, 1.1, 9.1]
10 mut rf := min(b)!
11 assert rf == f32(1.1)
12 rf = min(b[..2])!
13 assert rf == f32(3.1)
14 c := [u8(4), 9, 3, 1]
15 mut rb := min(c)!
16 assert rb == u8(1)
17 rb = min(c[..3])!
18 assert rb == u8(3)
19}
20
21fn test_max() {
22 a := [8, 2, 6, 4]
23 mut ri := max(a)!
24 assert ri == 8
25 ri = max(a[1..])!
26 assert ri == 6
27 b := [f32(5.1), 3.1, 1.1, 9.1]
28 mut rf := max(b)!
29 assert rf == f32(9.1)
30 rf = max(b[..3])!
31 assert rf == f32(5.1)
32 c := [u8(4), 9, 3, 1]
33 mut rb := max(c)!
34 assert rb == u8(9)
35 rb = max(c[2..])!
36 assert rb == u8(3)
37}
38
39fn test_idx_min() {
40 a := [8, 2, 6, 4]
41 ri := idx_min(a)!
42 assert ri == 1
43 b := [f32(5.1), 3.1, 1.1, 9.1]
44 rf := idx_min(b)!
45 assert rf == 2
46 c := [u8(4), 9, 3, 1]
47 rb := idx_min(c)!
48 assert rb == 3
49}
50
51fn test_idx_max() {
52 a := [8, 2, 6, 4]
53 ri := idx_max(a)!
54 assert ri == 0
55 b := [f32(5.1), 3.1, 1.1, 9.1]
56 rf := idx_max(b)!
57 assert rf == 3
58 c := [u8(4), 9, 3, 1]
59 rb := idx_max(c)!
60 assert rb == 1
61}
62
63fn test_merge() {
64 a := [1, 3, 5, 5, 7]
65 b := [2, 4, 4, 5, 6, 8]
66 c := []int{}
67 d := []int{}
68 assert merge[int](a, b) == [1, 2, 3, 4, 4, 5, 5, 5, 6, 7, 8]
69 assert merge[int](c, d) == []
70 assert merge[int](a, c) == a
71 assert merge[int](d, b) == b
72}
73
74fn test_append() {
75 a := [1, 3, 5, 5, 7]
76 b := [2, 4, 4, 5, 6, 8]
77 assert append(a, b) == [1, 3, 5, 5, 7, 2, 4, 4, 5, 6, 8]
78 assert append(b, a) == [2, 4, 4, 5, 6, 8, 1, 3, 5, 5, 7]
79 assert append(a, []int{}) == a
80 assert append([]int{}, b) == b
81}
82
83fn test_fixed_array_assignment() {
84 mut a := [2]int{}
85 a[0] = 111
86 a[1] = 222
87 b := a
88 assert b[0] == a[0]
89 assert b[1] == a[1]
90 mut c := [2]int{}
91 c = a
92 assert c[0] == a[0]
93 assert c[1] == a[1]
94 d := [3]int{init: 333}
95 for val in d {
96 assert val == 333
97 }
98 e := [3]string{init: 'vlang'}
99 for val in e {
100 assert val == 'vlang'
101 }
102}
103
104fn test_array_flat_map() {
105 a := ['Hello V', 'Hello World', 'V Lang']
106 assert flat_map[string, string](a, fn (e string) []string {
107 return e.split(' ')
108 }) == ['Hello', 'V', 'Hello', 'World', 'V', 'Lang']
109}
110
111fn test_array_flat_map_indexed() {
112 a := ['AB', 'CD', 'EF']
113 assert flat_map_indexed[string, string](a, fn (i int, e string) []string {
114 mut arr := [i.str()]
115 arr << e.split('')
116 return arr
117 }) == ['0', 'A', 'B', '1', 'C', 'D', '2', 'E', 'F']
118}
119
120fn test_map_indexed() {
121 a := [1, 2, 3]
122 assert map_indexed[int, int](a, fn (i int, e int) int {
123 return i + e * e
124 }) == [1, 5, 11]
125}
126
127fn test_group() {
128 x := [4, 5, 6]
129 y := [2, 1, 3]
130
131 z := group[int](x, y)
132 assert z == [[4, 2], [5, 1], [6, 3]]
133 x2 := [8, 9]
134 z2 := group[int](x2, y)
135 assert z2 == [[8, 2], [9, 1]]
136 assert group[int](x, []int{}) == [][]int{}
137}
138
139fn test_chunk() {
140 x := [1, 2, 3, 4, 5]
141 y := ['a', 'b', 'c', 'd', 'e', 'f']
142
143 z1 := chunk[int](x, 2)
144 assert z1 == [[1, 2], [3, 4], [5]]
145 z2 := chunk[string](y, 3)
146 assert z2 == [['a', 'b', 'c'], ['d', 'e', 'f']]
147 assert chunk[int]([]int{}, 2) == [][]int{}
148}
149
150fn test_chunk_while() {
151 assert chunk_while([0, 9, 2, 2, 3, 2, 7, 5, 9, 5], fn (x int, y int) bool {
152 return x == y
153 }) == [[0], [9], [2, 2], [3], [2], [7], [5], [9], [5]]
154
155 assert chunk_while([0, 9, 2, 2, 3, 2, 7, 5, 9, 5], fn (x int, y int) bool {
156 return x <= y
157 }) == [[0, 9], [2, 2, 3], [2, 7], [5, 9], [5]]
158
159 assert chunk_while('aaaabbbcca'.runes(), fn (x rune, y rune) bool {
160 return x == y
161 }).map({
162 it[0]: it.len
163 }).str() == '[{`a`: 4}, {`b`: 3}, {`c`: 2}, {`a`: 1}]'
164}
165
166fn test_window() {
167 x := [1, 2, 3, 4, 5, 6]
168
169 assert window[int](x, size: 3) == [[1, 2, 3], [2, 3, 4], [3, 4, 5],
170 [4, 5, 6]]
171 assert window[int](x, size: 3, step: 2) == [[1, 2, 3], [3, 4, 5]]
172 assert window[int]([]int{}, size: 2) == [][]int{}
173}
174
175/////////////////////////////
176type MyAlias = i64
177
178fn (a MyAlias) + (b MyAlias) MyAlias {
179 return MyAlias(i64(a) * 10 + i64(b) * 10)
180}
181
182struct MyStruct {
183 x int = 5
184}
185
186fn (a MyStruct) + (b MyStruct) MyStruct {
187 return MyStruct{
188 x: a.x + b.x
189 }
190}
191
192fn test_sum() {
193 assert sum([1, 2, 3, 4, 5]) or { 0 } == 15
194 assert sum([1.0, 2.5, 3.5, 4.0]) or { 0.0 } == 11.0
195 assert sum([]int{}) or { 0 } == 0
196 // test summing of a struct, with an overloaded + operator:
197 s := [MyStruct{
198 x: 30
199 }, MyStruct{
200 x: 20
201 }, MyStruct{
202 x: 10
203 }]
204 assert sum(s)! == MyStruct{
205 x: 60
206 }
207 // test summing of a number type alias with an overloaded + operator:
208 assert sum([MyAlias(5), MyAlias(7), MyAlias(3)])! == MyAlias((5 * 10 + 7 * 10) * 10 + 3 * 10)
209}
210
211/////////////////////////////
212fn test_reduce() {
213 x := [1, 2, 3, 4, 5]
214
215 assert reduce[int](x, fn (t1 int, t2 int) int {
216 return t1 + t2
217 }) or { 0 } == 15
218 assert reduce[string](['H', 'e', 'l', 'l', 'o'], fn (t1 string, t2 string) string {
219 return t1 + t2
220 }) or { '' } == 'Hello' // For the sake please use array's join instead.
221 assert reduce[int]([]int{}, fn (t1 int, t2 int) int {
222 return 0
223 }) or { -1 } == -1
224}
225
226fn test_reduce_indexed() {
227 x := [1, 2, 3, 4, 5]
228 assert reduce_indexed[int](x, fn (idx int, t1 int, t2 int) int {
229 return idx + t1 + t2
230 }) or { 0 } == 25
231}
232
233fn test_filter_indexed() {
234 x := [0, 1, 2, 3, 4, 5]
235
236 assert filter_indexed[int](x, fn (idx int, e int) bool {
237 return idx % 2 == 0
238 }) == [0, 2, 4]
239}
240
241fn test_fold() {
242 x := [1, 2, 3, 4, 5]
243
244 assert fold[int, int](x, 5, fn (r int, t int) int {
245 return r + t
246 }) == 20
247 assert fold[string, int](['H', 'e', 'l', 'l', 'l'], 0, fn (r int, t string) int {
248 return r + t[0]
249 }) == 497
250 assert fold[int, int]([]int{}, -1, fn (t1 int, t2 int) int {
251 return 0
252 }) == -1
253}
254
255fn test_fold_indexed() {
256 x := [1, 2, 3, 4, 5]
257
258 assert fold_indexed[int, int](x, 5, fn (idx int, r int, t int) int {
259 return idx + r + t
260 }) == 30
261}
262
263fn test_flatten() {
264 x := [[1, 2, 3], [4, 5, 6]]
265
266 assert flatten[int](x) == [1, 2, 3, 4, 5, 6]
267 assert flatten[int]([[]int{}]) == []
268}
269
270fn test_group_by() {
271 x := ['H', 'el', 'l', 'o ']
272
273 assert group_by[int, string](x, fn (v string) int {
274 return v.len
275 }) == {
276 1: ['H', 'l']
277 2: ['el', 'o ']
278 }
279 assert group_by[int, int]([]int{}, fn (v int) int {
280 return 0
281 }) == map[int][]int{}
282}
283
284fn test_concat_int() {
285 mut a := [1, 2, 3]
286 mut b := [3, 2, 1]
287
288 assert concat(a, ...b) == [1, 2, 3, 3, 2, 1]
289}
290
291fn test_concat_string() {
292 mut a := ['1', '2', '3']
293 mut b := ['3', '2', '1']
294
295 assert concat(a, ...b) == ['1', '2', '3', '3', '2', '1']
296}
297
298fn test_binary_search() {
299 a := [1, 3, 3, 4, 5, 6, 7, 8, 10]
300 assert binary_search(a, 3)! == 1
301 assert (binary_search(a, 0) or { -1 }) == -1
302}
303
304fn test_lower_bound() {
305 a := [1, 3, 3, 4, 5, 6, 7, 8, 10]
306 b := []int{}
307 c := [1, 2, 3]
308 assert lower_bound(a, 2)! == 3
309 assert (lower_bound(b, 4) or { -1 }) == -1
310 assert lower_bound(c, 3)! == 3
311}
312
313fn test_upper_bound() {
314 a := [1, 3, 3, 4, 5, 6, 7, 8, 10]
315 b := []int{}
316 c := [1, 2, 3]
317 assert upper_bound(a, 9)! == 8
318 assert (upper_bound(b, 4) or { -1 }) == -1
319 assert upper_bound(c, 2)! == 2
320}
321
322fn test_rotate_right() {
323 mut x := [1, 2, 3, 4, 5, 6]
324 rotate_right(mut x, 2)
325 assert x == [5, 6, 1, 2, 3, 4]
326}
327
328fn test_rotate_right_long() {
329 mut x := []u64{len: 128, init: 255}
330 x[0] = 0
331 x[1] = 0
332 x[2] = 0
333 rotate_right(mut x, 64)
334 assert x.len == 128
335 idx := index_of_first(x, fn (idx int, x u64) bool {
336 return x == 0
337 })
338 assert idx == 64
339 assert x[idx - 1] == 255
340 assert x[idx] == 0
341 assert x[idx + 1] == 0
342 assert x[idx + 2] == 0
343 assert x[idx + 3] == 255
344}
345
346fn test_rotate_left() {
347 mut x := [1, 2, 3, 4, 5, 6]
348 rotate_left(mut x, 2)
349 assert x == [3, 4, 5, 6, 1, 2]
350}
351
352struct Abc {
353 x u64 = 1
354 y u64 = 2
355 z u64 = 3
356}
357
358fn test_rotate_right_struct() {
359 mut x := [Abc{1, 0, 1}, Abc{2, 0, 1}, Abc{3, 0, 1}, Abc{4, 0, 1},
360 Abc{5, 0, 1}, Abc{6, 0, 1}]
361 rotate_right(mut x, 2)
362 assert x == [Abc{5, 0, 1}, Abc{6, 0, 1}, Abc{1, 0, 1}, Abc{2, 0, 1},
363 Abc{3, 0, 1}, Abc{4, 0, 1}]
364}
365
366fn test_rotate_left_struct() {
367 mut x := [Abc{1, 0, 1}, Abc{2, 0, 1}, Abc{3, 0, 1}, Abc{4, 0, 1},
368 Abc{5, 0, 1}, Abc{6, 0, 1}]
369 rotate_left(mut x, 2)
370 assert x == [Abc{3, 0, 1}, Abc{4, 0, 1}, Abc{5, 0, 1}, Abc{6, 0, 1},
371 Abc{1, 0, 1}, Abc{2, 0, 1}]
372}
373
374fn test_rotate_right_string() {
375 mut x := ['x1', 'x2', 'x3', 'x4', 'x5', 'x6']
376 rotate_right(mut x, 2)
377 assert x == ['x5', 'x6', 'x1', 'x2', 'x3', 'x4']
378}
379
380fn test_rotate_left_string() {
381 mut x := ['x1', 'x2', 'x3', 'x4', 'x5', 'x6']
382 rotate_left(mut x, 2)
383 assert x == ['x3', 'x4', 'x5', 'x6', 'x1', 'x2']
384}
385
386fn test_copy() {
387 mut a := [1, 2, 3]
388 mut b := [4, 5, 6]
389 assert copy(mut b, a) == 3
390 assert b == [1, 2, 3]
391 // check independent copies
392 b[0] = 99
393 assert a[0] == 1
394 // check longer src
395 b << 7
396 assert copy(mut a, b) == 3
397 assert a == [99, 2, 3]
398 // check longer dst
399 assert copy(mut b, [8, 9]) == 2
400 assert b == [8, 9, 3, 7]
401}
402
403fn test_can_copy_bits() {
404 assert can_copy_bits[u8]()
405 assert can_copy_bits[int]()
406 assert can_copy_bits[voidptr]()
407 assert can_copy_bits[&u8]()
408 // autofree needs to intercept assign
409 assert !can_copy_bits[string]()
410 assert !can_copy_bits[[]int]()
411 // map not copyable
412 assert !can_copy_bits[map[string]int]()
413}
414
415type Str = string
416
417fn test_alias_string_contains() {
418 names := [Str('')]
419 assert (Str('') in names) == true
420}
421
422struct XYZ {}
423
424fn test_array_append_empty_struct() {
425 mut names := []XYZ{cap: 2}
426 names << XYZ{}
427 assert (XYZ{} in names) == true
428
429 // test fixed array
430 array := [XYZ{}]!
431 assert (XYZ{} in names) == true
432}
433
434fn test_index_of_first() {
435 // vfmt off
436 assert index_of_first([1], fn (idx int, x int) bool { return x == 0 }) == -1
437 assert index_of_first([4, 5, 0, 7, 0, 9], fn (idx int, x int) bool { return x == 0 }) == 2
438 assert index_of_first([4, 5, 0, 7, 0, 9], fn (idx int, x int) bool { return x == 4 }) == 0
439 // vfmt on
440}
441
442fn test_index_of_last() {
443 // vfmt off
444 assert index_of_last([1], fn (idx int, x int) bool { return x == 0 }) == -1
445 assert index_of_last([4, 5, 0, 7, 0, 9], fn (idx int, x int) bool { return x == 0 }) == 4
446 assert index_of_last([4, 5, 0, 7, 0, 9], fn (idx int, x int) bool { return x == 4 }) == 0
447 // vfmt on
448}
449
450fn test_map_of_indexes() {
451 // vfmt off
452 assert arrays.map_of_indexes([]int{}) == {}
453 assert arrays.map_of_indexes([1]) == {1: [0]}
454 assert arrays.map_of_indexes([1, 2, 3, 999]) == {1: [0], 2: [1], 3: [2], 999: [3]}
455 assert arrays.map_of_indexes([999, 1, 2, 3]) == {1: [1], 2: [2], 3: [3], 999: [0]}
456 assert arrays.map_of_indexes([1, 2, 3, 4, 4, 2, 1, 4, 4, 999]) == {1: [0, 6], 2: [1, 5], 3: [2], 4: [3, 4, 7, 8], 999: [9]}
457
458 assert arrays.map_of_indexes([]string{}) == {}
459 assert arrays.map_of_indexes(['abc']) == {'abc': [0]}
460 assert arrays.map_of_indexes(['abc', 'abc']) == {'abc': [0, 1]}
461 assert arrays.map_of_indexes(['abc', 'def', 'abc']) == {'abc': [0, 2], 'def': [1]}
462 // vfmt on
463}
464
465fn test_map_of_counts() {
466 // vfmt off
467 assert map_of_counts([]int{}) == {}
468 assert map_of_counts([1]) == {1: 1}
469 assert map_of_counts([1, 2, 3, 999]) == {1: 1, 2: 1, 3: 1, 999: 1}
470 assert map_of_counts([999, 1, 2, 3]) == {1: 1, 2: 1, 3: 1, 999: 1}
471 assert map_of_counts([1, 2, 3, 4, 4, 2, 1, 4, 4, 999]) == {1: 2, 2: 2, 3: 1, 4: 4, 999: 1}
472
473 assert map_of_counts([]string{}) == {}
474 assert map_of_counts(['abc']) == {'abc': 1}
475 assert map_of_counts(['abc', 'abc']) == {'abc': 2}
476 assert map_of_counts(['abc', 'def', 'abc']) == {'abc': 2, 'def': 1}
477 // vfmt on
478}
479
480struct FindTest {
481 name string
482 age int
483}
484
485const test_structs = [FindTest{'one', 1}, FindTest{'two', 2},
486 FindTest{'three', 3}, FindTest{'one', 4}]
487
488fn test_find_first() {
489 // element in array
490 a := [1, 2, 3, 4, 5]
491 assert find_first[int](a, fn (arr int) bool {
492 return arr == 3
493 })? == 3, 'find element couldnt find the right element'
494
495 // find struct
496 find_by_name := find_first(test_structs, fn (arr FindTest) bool {
497 return arr.name == 'one'
498 })?
499 assert find_by_name == FindTest{'one', 1}
500
501 // not found
502 if _ := find_first(test_structs, fn (arr FindTest) bool {
503 return arr.name == 'nothing'
504 })
505 {
506 assert false
507 } else {
508 assert true
509 }
510}
511
512fn test_find_last() {
513 // // element in array
514 a := [1, 2, 3, 4, 5]
515 assert find_last[int](a, fn (arr int) bool {
516 return arr == 3
517 })? == 3, 'find element couldnt find the right element'
518
519 // find struct
520 find_by_name := find_last(test_structs, fn (arr FindTest) bool {
521 return arr.name == 'one'
522 })?
523 assert find_by_name == FindTest{'one', 4}
524
525 // not found
526 if _ := find_last(test_structs, fn (arr FindTest) bool {
527 return arr.name == 'nothing'
528 })
529 {
530 assert false
531 } else {
532 assert true
533 }
534}
535
536fn test_join_to_string() {
537 assert join_to_string[FindTest](test_structs, ':', fn (it FindTest) string {
538 return it.name
539 }) == 'one:two:three:one'
540 assert join_to_string[FindTest](test_structs, '', fn (it FindTest) string {
541 return it.name
542 }) == 'onetwothreeone'
543 assert join_to_string[int]([]int{}, ':', fn (it int) string {
544 return '1'
545 }) == ''
546}
547
548fn test_partition() {
549 a := [1, 2, 3, 4, 5, 6, 7, 8]
550 lower, upper := partition(a, fn (it int) bool {
551 return it < 5
552 })
553 assert lower.len == 4
554 assert upper.len == 4
555 assert lower == [1, 2, 3, 4]
556 assert upper == [5, 6, 7, 8]
557
558 lower2, upper2 := partition(a, fn (it int) bool {
559 return it < 1
560 })
561 assert lower2.len == 0
562 assert upper2.len == 8
563}
564
565fn test_each() {
566 a := [99, 1, 2, 3, 4, 5, 6, 7, 8, 1001]
567 mut control_sum := 0
568 for x in a {
569 control_sum += x
570 }
571
572 each(a, fn (x int) {
573 println(x)
574 })
575 mut sum := 0
576 mut psum := &sum
577 each(a, fn [mut psum] (x int) {
578 unsafe {
579 *psum += x
580 }
581 })
582 assert control_sum == sum
583}
584
585fn test_each_indexed() {
586 a := [99, 1, 2, 3, 4, 5, 6, 7, 8, 1001]
587 mut control_sum := 0
588 f := fn (idx int, x int) int {
589 return (idx + 1) * 1000_000 + x
590 }
591 for idx, x in a {
592 control_sum += f(idx, x)
593 }
594
595 each_indexed(a, fn (idx int, x int) {
596 println('idx: ${idx}, x: ${x}')
597 })
598 mut sum := 0
599 mut psum := &sum
600 each_indexed(a, fn [mut psum, f] (idx int, x int) {
601 unsafe {
602 *psum += f(idx, x)
603 }
604 })
605 assert control_sum == sum
606}
607