v4 / vlib / v / tests / builtin_arrays / array_init_with_spread_test.v
113 lines · 97 sloc · 2.59 KB · 56e61c291d14aa83e2a8a3d362011bbe61149957
Raw
1const base_array = [
2 1,
3 2,
4]
5
6const base_strings = ['a', 'b']
7
8struct Point {
9 x int
10 y int
11}
12
13const base_points = [Point{1, 2}, Point{3, 4}]
14
15fn test_array_init_with_spread() {
16 complete := [...base_array,
17 3,
18 4,
19 ]
20 assert base_array == [1, 2]
21 assert complete == [1, 2, 3, 4]
22 assert complete.len == 4
23
24 second := [...base_array, 5, 6, 7]
25 assert second == [1, 2, 5, 6, 7]
26}
27
28fn test_array_init_with_only_spread() {
29 mut copy := [...base_array]
30 assert copy == [1, 2]
31 copy << 99
32 // spread produces an independent copy
33 assert base_array == [1, 2]
34 assert copy == [1, 2, 99]
35}
36
37fn test_array_spread_strings() {
38 merged := [...base_strings, 'c', 'd']
39 assert merged == ['a', 'b', 'c', 'd']
40}
41
42fn test_array_spread_structs() {
43 pts := [...base_points, Point{5, 6}]
44 assert pts.len == 3
45 assert pts[0] == Point{1, 2}
46 assert pts[1] == Point{3, 4}
47 assert pts[2] == Point{5, 6}
48}
49
50fn test_array_spread_local_var() {
51 v_arr := [7, 8, 9]
52 x := [...v_arr, 100]
53 assert v_arr == [7, 8, 9]
54 assert x == [7, 8, 9, 100]
55}
56
57fn test_array_spread_chained() {
58 first := [...base_array, 3]
59 second := [...first, 4]
60 assert second == [1, 2, 3, 4]
61}
62
63// Regression: `[...base]` should produce an independent deep copy. Modifying
64// an inner []int after the spread must not affect the base.
65fn test_array_spread_nested_arrays_are_deep_cloned() {
66 mut base := [[1, 2], [3, 4]]
67 mut copy := [...base]
68 copy[0] << 99
69 assert base[0] == [1, 2]
70 assert copy[0] == [1, 2, 99]
71}
72
73// Regression: assigning into a nested element of the spread copy must not
74// mutate the base. Catches shallow-copy regressions in any backend that
75// reuses the base's inner storage.
76fn test_array_spread_nested_element_assignment_isolated() {
77 mut base := [[1, 2]]
78 mut b := [...base]
79 b[0][0] = 9
80 assert base[0][0] == 1
81 assert b[0][0] == 9
82}
83
84// Regression: indexing a spread literal inline (`[...base, 3][0]`) must keep
85// the spread base in the AST instead of dropping it during parsing.
86fn test_array_spread_indexed_inline() {
87 assert [...base_array, 3][0] == 1
88 assert [...base_array, 3][1] == 2
89 assert [...base_array, 3][2] == 3
90}
91
92// Regression: appended string variables must be cloned, matching the
93// behavior of the regular `[s1, s2]` array-literal path.
94fn test_array_spread_appended_string_variable() {
95 base := ['a', 'b']
96 mut s := 'c'
97 arr := [...base, s]
98 s = 'mutated'
99 assert arr == ['a', 'b', 'c']
100}
101
102type Ints = []int
103
104// Regression: type-alias of an array should be accepted as a spread base.
105fn test_array_spread_alias_base() {
106 a := Ints([10, 20, 30])
107 b := [...a, 40]
108 assert b.len == 4
109 assert b[0] == 10
110 assert b[3] == 40
111 c := [...a]
112 assert c.len == 3
113}
114