v2 / vlib / v / tests / conditions / matches / match_test.v
335 lines · 288 sloc · 3.84 KB · 8e35f4d9848f7ad35d857a187dddbfd2eca5e19d
Raw
1enum Color {
2 red
3 green
4 blue
5}
6
7pub fn (c Color) str() string {
8 return 'tmp'
9}
10
11fn test_match_integers() {
12 mut a := 3
13 mut b := 0
14 match a {
15 2 {
16 println('two')
17 }
18 3 {
19 println('three')
20 b = 3
21 }
22 int(4) {
23 println('four')
24 }
25 else {
26 println('???')
27 }
28 }
29
30 assert b == 3
31 assert match 2 {
32 1 { 2 }
33 2 { 3 }
34 else { 5 }
35 } == 3
36 assert match 0 {
37 1 { 2 }
38 2 { 3 }
39 else { 5 }
40 } == 5
41 assert match 1 {
42 2 { 0 }
43 else { 5 }
44 } == 5
45 a = 0
46 match 2 {
47 0 {
48 a = 1
49 }
50 1 {
51 a = 2
52 }
53 else {
54 a = 3
55 println('a is ${a}')
56 }
57 }
58
59 assert a == 3
60 a = 0
61 match 1 {
62 0 {
63 a = 1
64 }
65 1 {
66 a = 2
67 a = a + 2
68 a = a + 2
69 }
70 else {}
71 }
72
73 assert a == 6
74 a = 0
75 match 1 {
76 0 {}
77 else { a = -2 }
78 }
79
80 assert a == -2
81}
82
83fn test_match_multiple() {
84 assert match 9 {
85 1, 2, 3 { '1-3' }
86 4, 5 { '4-5' }
87 6...9 { '6-9' }
88 else { 'other' }
89 } == '6-9'
90}
91
92fn test_match_range() {
93 assert match `f` {
94 `0`...`9` { 'digit' }
95 `A`...`Z` { 'uppercase' }
96 `a`...`z` { 'lowercase' }
97 else { 'other' }
98 } == 'lowercase'
99}
100
101fn test_match_enums() {
102 mut b := Color.red
103 match b {
104 .red {
105 b = .green
106 }
107 .green {
108 b = .blue
109 }
110 else {
111 println('b is ${b.str()}')
112 b = .red
113 }
114 }
115
116 assert b == .green
117 match b {
118 .red {
119 b = .green
120 }
121 else {
122 println('b is ${b.str()}')
123 b = .blue
124 }
125 }
126
127 assert b == .blue
128}
129
130struct Counter {
131mut:
132 val int
133}
134
135fn (mut c Counter) next() int {
136 c.val++
137 return c.val
138}
139
140fn test_method_call() {
141 mut c := Counter{
142 val: 1
143 }
144 assert match c.next() {
145 1 { false }
146 2 { true }
147 3 { false }
148 else { true }
149 }
150}
151
152type Sum = A1 | B1
153
154struct A1 {
155 pos int
156}
157
158struct B1 {
159 val string
160}
161
162fn f(s Sum) string {
163 match s {
164 A1 { return typeof(s).name }
165 B1 { return '' }
166 }
167
168 return ''
169}
170
171fn test_sum_type_name() {
172 a := A1{
173 pos: 22
174 }
175 assert f(a) == 'A1'
176}
177
178fn f_else(s Sum) string {
179 match s {
180 A1 { return typeof(s).name }
181 else { return '' }
182 }
183}
184
185fn test_sum_type_else() {
186 a := A1{
187 pos: 22
188 }
189 assert f_else(a) == 'A1'
190}
191
192struct Alfa {
193 char rune = `a`
194}
195
196fn (a Alfa) letter() rune {
197 return a.char
198}
199
200struct Bravo {
201 // A field so that Alfa and Bravo structures aren't the same
202 dummy_field int
203pub mut:
204 // Note: the `char` field is not `pub` or `mut` in all sumtype variants, but using it in aggregates should still work
205 char rune = `b`
206}
207
208fn (b Bravo) letter() rune {
209 return b.char
210}
211
212struct Charlie {
213 char rune = `c`
214}
215
216type NATOAlphabet = Alfa | Bravo | Charlie
217
218fn test_match_sumtype_multiple_types() {
219 a := Alfa{}
220 l := NATOAlphabet(a)
221 match l {
222 Alfa, Bravo {
223 assert l.char == `a`
224 // TODO: make methods work
225 // assert l.letter() == `a`
226 }
227 Charlie {
228 assert false
229 }
230 }
231
232 // test one branch
233 match l {
234 Alfa, Bravo, Charlie {
235 assert l.char == `a`
236 }
237 }
238}
239
240fn test_sub_expression() {
241 b := false && match 1 {
242 0 { true }
243 else { true }
244 }
245
246 assert !b
247 c := true || match 1 {
248 0 { false }
249 else { false }
250 }
251
252 assert c
253}
254
255const one = 'one'
256
257fn test_match_constant_string() {
258 s := one
259 match s {
260 one {
261 assert true
262 }
263 else {
264 assert false
265 }
266 }
267}
268
269type WithArray = []WithArray | int
270
271fn test_sumtype_with_array() {
272 fa := [WithArray(0)]
273 f := WithArray(fa)
274 match f {
275 []WithArray {
276 assert true
277 }
278 int {
279 assert false
280 }
281 }
282
283 match f {
284 int {
285 assert false
286 }
287 []WithArray {
288 assert true
289 }
290 }
291}
292
293fn test_match_expression_add() {
294 a := match true {
295 true { 1 }
296 false { 2 }
297 } + 3
298 assert a == 4
299}
300
301type LeType = int | string
302
303fn test_noreturn() {
304 t := LeType(3)
305 _ := match t {
306 int {
307 'test'
308 }
309 string {
310 exit(0)
311 }
312 }
313}
314
315// for test the returns both interface and non-interface
316interface Any {}
317
318fn test_returns_both_interface_and_non_interface() {
319 any := Any('abc')
320
321 mut res := match any {
322 string { any }
323 else { 'literal' }
324 }
325
326 assert res == 'abc'
327
328 variable := ''
329 res = match any {
330 string { any }
331 else { variable }
332 }
333
334 assert res == 'abc'
335}
336