v / vlib / builtin
Raw file | 1254 loc (1118 sloc) | 22.56 KB | Latest commit hash 17d65db82
1// Copyright (c) 2019-2023 Alexander Medvednikov. All rights reserved.
2// Use of this source code is governed by an MIT license
3// that can be found in the LICENSE file.
4
5struct Foo {
6 bar int
7mut:
8 str string
9}
10
11fn test_add() {
12 mut a := 'a'
13 a += 'b'
14 assert a == ('ab')
15 a = 'a'
16 for i := 1; i < 1000; i++ {
17 a += 'b'
18 }
19 assert a.len == 1000
20 assert a.ends_with('bbbbb')
21 a += '123'
22 assert a.ends_with('3')
23}
24
25fn test_len_utf8() {
26 assert 'Vlang'.len_utf8() == 5
27 assert 'María'.len_utf8() == 5
28 assert '姓名'.len_utf8() == 2
29 assert 'Слово'.len_utf8() == 5
30 assert 'Λέξη'.len_utf8() == 4
31}
32
33fn test_ends_with() {
34 a := 'browser.v'
35 assert a.ends_with('.v')
36
37 s := 'V Programming Language'
38 assert s.ends_with('guage') == true
39 assert s.ends_with('Language') == true
40 assert s.ends_with('Programming Language') == true
41 assert s.ends_with('V') == false
42}
43
44fn test_between() {
45 s := 'hello [man] how you doing'
46 assert s.find_between('[', ']') == 'man'
47}
48
49fn test_compare() {
50 a := 'Music'
51 b := 'src'
52 assert b >= a
53}
54
55fn test_lt() {
56 a := ''
57 b := 'a'
58 c := 'a'
59 d := 'b'
60 e := 'aa'
61 f := 'ab'
62 assert a < b
63 assert !(b < c)
64 assert c < d
65 assert !(d < e)
66 assert c < e
67 assert e < f
68}
69
70fn test_ge() {
71 a := 'aa'
72 b := 'aa'
73 c := 'ab'
74 d := 'abc'
75 e := 'aaa'
76 assert b >= a
77 assert c >= b
78 assert d >= c
79 assert !(c >= d)
80 assert e >= a
81}
82
83fn test_compare_strings() {
84 a := 'aa'
85 b := 'aa'
86 c := 'ab'
87 d := 'abc'
88 e := 'aaa'
89 assert compare_strings(a, b) == 0
90 assert compare_strings(b, c) == -1
91 assert compare_strings(c, d) == -1
92 assert compare_strings(d, e) == 1
93 assert compare_strings(a, e) == -1
94 assert compare_strings(e, a) == 1
95}
96
97fn test_sort() {
98 mut vals := [
99 'arr',
100 'an',
101 'a',
102 'any',
103 ]
104 len := vals.len
105 vals.sort()
106 assert len == vals.len
107 assert vals[0] == 'a'
108 assert vals[1] == 'an'
109 assert vals[2] == 'any'
110 assert vals[3] == 'arr'
111}
112
113fn test_sort_reverse() {
114 mut vals := [
115 'arr',
116 'an',
117 'a',
118 'any',
119 ]
120 len := vals.len
121 vals.sort(b > a)
122 assert len == vals.len
123 assert vals[0] == 'a'
124 assert vals[1] == 'an'
125 assert vals[2] == 'any'
126 assert vals[3] == 'arr'
127}
128
129fn test_ranges() {
130 s := 'test'
131 s1 := s[0..20] or { 'both' }
132 s2 := s[..20] or { 'last' }
133 s3 := s[10..] or { 'first' }
134 s4 := ranges_propagate_both(s) or { 'both' }
135 s5 := ranges_propagate_last(s) or { 'last' }
136 s6 := ranges_propagate_first(s) or { 'first' }
137 assert s1 == 'both'
138 assert s2 == 'last'
139 assert s3 == 'first'
140 assert s4 == 'both'
141 assert s5 == 'last'
142 assert s6 == 'first'
143}
144
145fn ranges_propagate_first(s string) !string {
146 return s[10..]!
147}
148
149fn ranges_propagate_last(s string) !string {
150 return s[..20]!
151}
152
153fn ranges_propagate_both(s string) !string {
154 return s[1..20]!
155}
156
157fn test_split_nth() {
158 a := '1,2,3'
159 assert a.split(',').len == 3
160 assert a.split_nth(',', -1).len == 3
161 assert a.split_nth(',', 0).len == 3
162 assert a.split_nth(',', 1).len == 1
163 assert a.split_nth(',', 2).len == 2
164 assert a.split_nth(',', 10).len == 3
165 b := '1::2::3'
166 assert b.split('::').len == 3
167 assert b.split_nth('::', -1).len == 3
168 assert b.split_nth('::', 0).len == 3
169 assert b.split_nth('::', 1).len == 1
170 assert b.split_nth('::', 2).len == 2
171 assert b.split_nth('::', 10).len == 3
172 c := 'ABCDEF'
173 assert c.split('').len == 6
174 assert c.split_nth('', 3).len == 3
175 assert c.split_nth('BC', -1).len == 2
176 d := ','
177 assert d.split(',').len == 2
178 assert d.split_nth('', 3).len == 1
179 assert d.split_nth(',', -1).len == 2
180 assert d.split_nth(',', 3).len == 2
181 e := ',,,0,,,,,a,,b,'
182 assert e.split(',,').len == 5
183 assert e.split_nth(',,', 3).len == 3
184 assert e.split_nth(',', -1).len == 12
185 assert e.split_nth(',', 3).len == 3
186 f := '1:2:3'
187 assert f.split_nth(':', 2) == ['1', '2:3']
188 assert f.rsplit_nth(':', 2) == ['3', '1:2']
189 g := '123'
190 assert g.split_nth('', 2) == ['1', '23']
191 assert g.rsplit_nth('', 2) == ['3', '12']
192 h := ''
193 assert h.split_nth('', 2) == []
194 assert h.rsplit_nth('', 2) == []
195}
196
197fn test_rsplit_nth() {
198 a := '1,2,3'
199 assert a.rsplit(',').len == 3
200 assert a.rsplit_nth(',', -1).len == 3
201 assert a.rsplit_nth(',', 0).len == 3
202 assert a.rsplit_nth(',', 1).len == 1
203 assert a.rsplit_nth(',', 2).len == 2
204 assert a.rsplit_nth(',', 10).len == 3
205 b := '1::2::3'
206 assert b.rsplit('::').len == 3
207 assert b.rsplit_nth('::', -1).len == 3
208 assert b.rsplit_nth('::', 0).len == 3
209 assert b.rsplit_nth('::', 1).len == 1
210 assert b.rsplit_nth('::', 2).len == 2
211 assert b.rsplit_nth('::', 10).len == 3
212 c := 'ABCDEF'
213 assert c.rsplit('').len == 6
214 assert c.rsplit_nth('', 3).len == 3
215 assert c.rsplit_nth('BC', -1).len == 2
216 d := ','
217 assert d.rsplit(',').len == 2
218 assert d.rsplit_nth('', 3).len == 1
219 assert d.rsplit_nth(',', -1).len == 2
220 assert d.rsplit_nth(',', 3).len == 2
221 e := ',,,0,,,,,a,,b,'
222 assert e.rsplit(',,').len == 5
223 assert e.rsplit_nth(',,', 3).len == 3
224 assert e.rsplit_nth(',', -1).len == 12
225 assert e.rsplit_nth(',', 3).len == 3
226}
227
228fn test_split_nth_values() {
229 line := 'CMD=eprintln(phase=1)'
230
231 a0 := line.split_nth('=', 0)
232 assert a0.len == 3
233 assert a0[0] == 'CMD'
234 assert a0[1] == 'eprintln(phase'
235 assert a0[2] == '1)'
236
237 a1 := line.split_nth('=', 1)
238 assert a1.len == 1
239 assert a1[0] == 'CMD=eprintln(phase=1)'
240
241 a2 := line.split_nth('=', 2)
242 assert a2.len == 2
243 assert a2[0] == 'CMD'
244 assert a2[1] == 'eprintln(phase=1)'
245
246 a3 := line.split_nth('=', 3)
247 assert a3.len == 3
248 assert a3[0] == 'CMD'
249 assert a3[1] == 'eprintln(phase'
250 assert a3[2] == '1)'
251
252 a4 := line.split_nth('=', 4)
253 assert a4.len == 3
254 assert a4[0] == 'CMD'
255 assert a4[1] == 'eprintln(phase'
256 assert a4[2] == '1)'
257}
258
259fn test_rsplit_nth_values() {
260 line := 'CMD=eprintln(phase=1)'
261
262 a0 := line.rsplit_nth('=', 0)
263 assert a0.len == 3
264 assert a0[0] == '1)'
265 assert a0[1] == 'eprintln(phase'
266 assert a0[2] == 'CMD'
267
268 a1 := line.rsplit_nth('=', 1)
269 assert a1.len == 1
270 assert a1[0] == 'CMD=eprintln(phase=1)'
271
272 a2 := line.rsplit_nth('=', 2)
273 assert a2.len == 2
274 assert a2[0] == '1)'
275 assert a2[1] == 'CMD=eprintln(phase'
276
277 a3 := line.rsplit_nth('=', 3)
278 assert a3.len == 3
279 assert a0[0] == '1)'
280 assert a0[1] == 'eprintln(phase'
281 assert a0[2] == 'CMD'
282
283 a4 := line.rsplit_nth('=', 4)
284 assert a4.len == 3
285 assert a0[0] == '1)'
286 assert a0[1] == 'eprintln(phase'
287 assert a0[2] == 'CMD'
288}
289
290fn test_split() {
291 mut s := 'volt/twitch.v:34'
292 mut vals := s.split(':')
293 assert vals.len == 2
294 assert vals[0] == 'volt/twitch.v'
295 assert vals[1] == '34'
296 // /////////
297 s = '2018-01-01z13:01:02'
298 vals = s.split('z')
299 assert vals.len == 2
300 assert vals[0] == '2018-01-01'
301 assert vals[1] == '13:01:02'
302 // //////////
303 s = '4627a862c3dec29fb3182a06b8965e0025759e18___1530207969___blue'
304 vals = s.split('___')
305 assert vals.len == 3
306 assert vals[0] == '4627a862c3dec29fb3182a06b8965e0025759e18'
307 assert vals[1] == '1530207969'
308 assert vals[2] == 'blue'
309 // /////////
310 s = 'lalala'
311 vals = s.split('a')
312 assert vals.len == 4
313 assert vals[0] == 'l'
314 assert vals[1] == 'l'
315 assert vals[2] == 'l'
316 assert vals[3] == ''
317 // /////////
318 s = 'awesome'
319 a := s.split('')
320 assert a.len == 7
321 assert a[0] == 'a'
322 assert a[1] == 'w'
323 assert a[2] == 'e'
324 assert a[3] == 's'
325 assert a[4] == 'o'
326 assert a[5] == 'm'
327 assert a[6] == 'e'
328 // /////////
329 s = 'wavy turquoise bags'
330 vals = s.split(' bags')
331 assert vals.len == 2
332 assert vals[0] == 'wavy turquoise'
333 assert vals[1] == ''
334}
335
336fn test_rsplit() {
337 mut s := 'volt/twitch.v:34'
338 mut vals := s.rsplit(':')
339 assert vals.len == 2
340 assert vals[0] == '34'
341 assert vals[1] == 'volt/twitch.v'
342 // /////////
343 s = '2018-01-01z13:01:02'
344 vals = s.rsplit('z')
345 assert vals.len == 2
346 assert vals[0] == '13:01:02'
347 assert vals[1] == '2018-01-01'
348 // //////////
349 s = '4627a862c3dec29fb3182a06b8965e0025759e18___1530207969___blue'
350 vals = s.rsplit('___')
351 assert vals.len == 3
352 assert vals[0] == 'blue'
353 assert vals[1] == '1530207969'
354 assert vals[2] == '4627a862c3dec29fb3182a06b8965e0025759e18'
355 // /////////
356 s = 'lalala'
357 vals = s.rsplit('a')
358 assert vals.len == 4
359 assert vals[0] == ''
360 assert vals[1] == 'l'
361 assert vals[2] == 'l'
362 assert vals[3] == 'l'
363 // /////////
364 s = 'awesome'
365 a := s.rsplit('')
366 assert a.len == 7
367 assert a[0] == 'e'
368 assert a[1] == 'm'
369 assert a[2] == 'o'
370 assert a[3] == 's'
371 assert a[4] == 'e'
372 assert a[5] == 'w'
373 assert a[6] == 'a'
374 // /////////
375 s = 'wavy turquoise bags'
376 vals = s.rsplit('wavy ')
377 assert vals.len == 2
378 assert vals[0] == 'turquoise bags'
379 assert vals[1] == ''
380}
381
382fn test_split_any() {
383 assert 'ABC'.split_any('') == ['A', 'B', 'C']
384 assert ''.split_any(' ') == []
385 assert ' '.split_any(' ') == ['']
386 assert ' '.split_any(' ') == ['', '']
387 assert 'Ciao come stai? '.split_any(' ') == ['Ciao', 'come', 'stai?']
388 assert 'Ciao+come*stai? '.split_any('+*') == ['Ciao', 'come', 'stai? ']
389 assert 'Ciao+come*stai? '.split_any('+* ') == ['Ciao', 'come', 'stai?']
390 assert 'first row\nsecond row'.split_any(' \n') == ['first', 'row', 'second', 'row']
391}
392
393fn test_rsplit_any() {
394 assert 'ABC'.rsplit_any('') == ['C', 'B', 'A']
395 assert ''.rsplit_any(' ') == []
396 assert ' '.rsplit_any(' ') == ['']
397 assert ' '.rsplit_any(' ') == ['', '']
398 assert ' Ciao come stai?'.rsplit_any(' ') == ['stai?', 'come', 'Ciao']
399 assert ' Ciao+come*stai?'.rsplit_any('+*') == ['stai?', 'come', ' Ciao']
400 assert ' Ciao+come*stai?'.rsplit_any('+* ') == ['stai?', 'come', 'Ciao']
401 assert 'first row\nsecond row'.rsplit_any(' \n') == ['row', 'second', 'row', 'first']
402}
403
404fn test_split_once() ? {
405 path1, ext1 := 'home/dir/lang.zip'.split_once('.')?
406 assert path1 == 'home/dir/lang'
407 assert ext1 == 'zip'
408 path2, ext2 := 'home/dir/lang.ts.dts'.split_once('.')?
409 assert path2 == 'home/dir/lang'
410 assert ext2 == 'ts.dts'
411 path3, ext3 := 'home/dir'.split_once('.') or { '', '' }
412 assert path3 == ''
413 assert ext3 == ''
414}
415
416fn test_rsplit_once() ? {
417 path1, ext1 := 'home/dir/lang.zip'.rsplit_once('.')?
418 assert path1 == 'home/dir/lang'
419 assert ext1 == 'zip'
420 path2, ext2 := 'home/dir/lang.ts.dts'.rsplit_once('.')?
421 assert path2 == 'home/dir/lang.ts'
422 assert ext2 == 'dts'
423 path3, ext3 := 'home/dir'.rsplit_once('.') or { '', '' }
424 assert path3 == ''
425 assert ext3 == ''
426}
427
428fn test_trim_space() {
429 a := ' a '
430 assert a.trim_space() == 'a'
431 code := '
432
433fn main() {
434 println(2)
435}
436
437'
438 code_clean := 'fn main() {
439 println(2)
440}'
441 assert code.trim_space() == code_clean
442}
443
444fn test_join() {
445 mut strs := ['a', 'b', 'c']
446 mut s := strs.join(' ')
447 assert s == 'a b c'
448 strs = [
449 'one
450two ',
451 'three!
452four!',
453 ]
454 s = strs.join(' ')
455 assert s.contains('one') && s.contains('two ') && s.contains('four')
456 empty := []string{len: 0}
457 assert empty.join('A') == ''
458}
459
460fn test_clone() {
461 mut a := 'a'
462 a += 'a'
463 a += 'a'
464 b := a
465 c := a.clone()
466 assert c == a
467 assert c == 'aaa'
468 assert b == 'aaa'
469}
470
471fn test_replace() {
472 a := 'hello man!'
473 mut b := a.replace('man', 'world')
474 assert b == ('hello world!')
475 b = b.replace('!', '')
476 assert b == ('hello world')
477 b = b.replace('h', 'H')
478 assert b == ('Hello world')
479 b = b.replace('foo', 'bar')
480 assert b == ('Hello world')
481 s := 'hey man how are you'
482 assert s.replace('man ', '') == 'hey how are you'
483 lol := 'lol lol lol'
484 assert lol.replace('lol', 'LOL') == 'LOL LOL LOL'
485 b = 'oneBtwoBBthree'
486 assert b.replace('B', '') == 'onetwothree'
487 b = '*charptr'
488 assert b.replace('charptr', 'byteptr') == '*byteptr'
489 c := 'abc'
490 assert c.replace('', '-') == c
491 v := 'a b c d'
492 assert v.replace(' ', ' ') == 'a b c d'
493}
494
495fn test_replace_each() {
496 s := 'hello man man :)'
497 q := s.replace_each([
498 'man',
499 'dude',
500 'hello',
501 'hey',
502 ])
503 assert q == 'hey dude dude :)'
504 bb := '[b]bold[/b] [code]code[/code]'
505 assert bb.replace_each([
506 '[b]',
507 '<b>',
508 '[/b]',
509 '</b>',
510 '[code]',
511 '<code>',
512 '[/code]',
513 '</code>',
514 ]) == '<b>bold</b> <code>code</code>'
515 bb2 := '[b]cool[/b]'
516 assert bb2.replace_each([
517 '[b]',
518 '<b>',
519 '[/b]',
520 '</b>',
521 ]) == '<b>cool</b>'
522 t := 'aaaaaaaa'
523 y := t.replace_each([
524 'aa',
525 'b',
526 ])
527 assert y == 'bbbb'
528 s2 := 'hello_world hello'
529 assert s2.replace_each(['hello_world', 'aaa', 'hello', 'bbb']) == 'aaa bbb'
530}
531
532fn test_replace_char() {
533 assert 'azert'.replace_char(`z`, `s`, 2) == 'assert'
534 assert '\rHello!\r'.replace_char(`\r`, `\n`, 1) == '\nHello!\n'
535 assert 'Hello!'.replace_char(`l`, `e`, 4) == 'Heeeeeeeeeo!'
536 assert '1141'.replace_char(`1`, `8`, 2) == '8888488'
537}
538
539fn test_normalize_tabs() {
540 assert '\t\tHello!'.normalize_tabs(4) == ' Hello!'
541 assert '\t\tHello!\t; greeting'.normalize_tabs(1) == ' Hello! ; greeting'
542}
543
544fn test_itoa() {
545 num := 777
546 assert num.str() == '777'
547 big := 7779998
548 assert big.str() == '7779998'
549 a := 3
550 assert a.str() == '3'
551 b := 5555
552 assert b.str() == '5555'
553 zero := 0
554 assert zero.str() == '0'
555 neg := -7
556 assert neg.str() == '-7'
557}
558
559fn test_reassign() {
560 a := 'hi'
561 mut b := a
562 b += '!'
563 assert a == 'hi'
564 assert b == 'hi!'
565}
566
567fn test_runes() {
568 s := 'привет'
569 assert s.len == 12
570 s2 := 'privet'
571 assert s2.len == 6
572 u := s.runes()
573 assert u.len == 6
574 assert s2.substr(1, 4).len == 3
575 assert s2.substr(1, 4) == 'riv'
576 assert s2[1..4].len == 3
577 assert s2[1..4] == 'riv'
578 assert s2[..4].len == 4
579 assert s2[..4] == 'priv'
580 assert s2[2..].len == 4
581 assert s2[2..] == 'ivet'
582 assert u[1..4].string().len == 6
583 assert u[1..4].string() == 'рив'
584 assert s2.substr(1, 2) == 'r'
585 assert u[1..2].string() == 'р'
586 assert s2.runes()[1] == `r`
587 assert u[1] == `р`
588 first := u[0]
589 last := u[u.len - 1]
590 assert first.str().len == 2
591 assert last.str().len == 2
592}
593
594fn test_contains() {
595 s := 'view.v'
596 assert s.contains('vi')
597 assert !s.contains('random')
598 assert ''.contains('')
599 assert 'abc'.contains('')
600}
601
602fn test_contains_any() {
603 assert !'team'.contains_any('i')
604 assert 'fail'.contains_any('ui')
605 assert 'ure'.contains_any('ui')
606 assert 'failure'.contains_any('ui')
607 assert !'foo'.contains_any('')
608 assert !''.contains_any('')
609}
610
611fn test_contains_only() {
612 assert '23885'.contains_only('0123456789')
613 assert '23gg885'.contains_only('01g23456789')
614 assert !'hello;'.contains_only('hello')
615 assert !''.contains_only('')
616}
617
618fn test_contains_any_substr() {
619 s := 'Some random text'
620 assert s.contains_any_substr(['false', 'not', 'rand'])
621 assert !s.contains_any_substr(['ABC', 'invalid'])
622 assert ''.contains_any_substr([])
623 assert 'abc'.contains_any_substr([''])
624}
625
626fn test_arr_contains() {
627 a := ['a', 'b', 'c']
628 assert a.contains('b')
629 ints := [1, 2, 3]
630 assert ints.contains(2)
631}
632
633fn test_to_num() {
634 s := '7'
635 assert s.int() == 7
636 assert s.u8() == 7
637 assert s.u64() == 7
638 f := '71.5 hasdf'
639 // QTODO
640 assert f.f32() == 71.5
641 vals := ['9']
642 assert vals[0].int() == 9
643 big := '93993993939322'
644 assert big.u64() == 93993993939322
645 assert big.i64() == 93993993939322
646}
647
648fn test_inter_format_string() {
649 float_num := 1.52345
650 float_num_string := '-${float_num:.3f}-'
651 assert float_num_string == '-1.523-'
652 int_num := 7
653 int_num_string := '-${int_num:03d}-'
654 assert int_num_string == '-007-'
655 ch := `a`
656 ch_string := '-${ch:c}-'
657 assert ch_string == '-a-'
658 hex_n := 192
659 hex_n_string := '-${hex_n:x}-'
660 assert hex_n_string == '-c0-'
661 oct_n := 192
662 oct_n_string := '-${oct_n:o}-'
663 assert oct_n_string == '-300-'
664 str := 'abc'
665 str_string := '-${str:s}-'
666 assert str_string == '-abc-'
667}
668
669fn test_hash() {
670 s := '10000'
671 assert s.hash() == 46730161
672 s2 := '24640'
673 assert s2.hash() == 47778736
674 s3 := 'Content-Type'
675 assert s3.hash() == 949037134
676 s4 := 'bad_key'
677 assert s4.hash() == -346636507
678 s5 := '24640'
679 // From a map collision test
680 assert s5.hash() % ((1 << 20) - 1) == s.hash() % ((1 << 20) - 1)
681 assert s5.hash() % ((1 << 20) - 1) == 592861
682}
683
684fn test_trim() {
685 assert 'banana'.trim('bna') == ''
686 assert 'abc'.trim('ac') == 'b'
687 assert 'aaabccc'.trim('ac') == 'b'
688}
689
690fn test_trim_indexes() {
691 mut left, mut right := 0, 0
692 left, right = '- -- - '.trim_indexes(' -')
693 assert left == 0 && right == 0
694 left, right = '- hello-world!\t'.trim_indexes(' -\t')
695 assert left == 2 && right == 14
696 left, right = 'abc'.trim_indexes('ac')
697 assert left == 1 && right == 2
698}
699
700fn test_trim_left() {
701 mut s := 'module main'
702 assert s.trim_left(' ') == 'module main'
703 s = ' module main'
704 assert s.trim_left(' ') == 'module main'
705 // test cutset
706 s = 'banana'
707 assert s.trim_left('ba') == 'nana'
708 assert s.trim_left('ban') == ''
709}
710
711fn test_trim_right() {
712 mut s := 'module main'
713 assert s.trim_right(' ') == 'module main'
714 s = 'module main '
715 assert s.trim_right(' ') == 'module main'
716 // test cutset
717 s = 'banana'
718 assert s.trim_right('na') == 'b'
719 assert s.trim_right('ban') == ''
720}
721
722fn test_all_before() {
723 s := 'fn hello fn'
724 assert s.all_before(' ') == 'fn'
725 assert s.all_before('2') == s
726 assert s.all_before('') == s
727}
728
729fn test_all_before_last() {
730 s := 'fn hello fn'
731 assert s.all_before_last(' ') == 'fn hello'
732 assert s.all_before_last('2') == s
733 assert s.all_before_last('') == s
734}
735
736fn test_all_after() {
737 s := 'fn hello'
738 assert s.all_after('fn ') == 'hello'
739 assert s.all_after('test') == s
740 assert s.all_after('') == s
741 assert s.after('e') == 'llo'
742 x := s.after('e')
743 assert x == 'llo'
744}
745
746fn test_reverse() {
747 assert 'hello'.reverse() == 'olleh'
748 assert ''.reverse() == ''
749 assert 'a'.reverse() == 'a'
750}
751
752fn test_bytes_to_string() {
753 mut buf := vcalloc(10)
754 unsafe {
755 buf[0] = `h`
756 buf[1] = `e`
757 buf[2] = `l`
758 buf[3] = `l`
759 buf[4] = `o`
760 }
761 assert unsafe { buf.vstring() } == 'hello'
762 assert unsafe { buf.vstring_with_len(2) } == 'he'
763 bytes := [u8(`h`), `e`, `l`, `l`, `o`]
764 assert bytes.bytestr() == 'hello'
765}
766
767fn test_charptr() {
768 foo := &char('VLANG'.str)
769 assert typeof(foo).name == '&char'
770 assert unsafe { foo.vstring() } == 'VLANG'
771 assert unsafe { foo.vstring_with_len(3) } == 'VLA'
772}
773
774fn test_count() {
775 assert ''.count('') == 0
776 assert ''.count('a') == 0
777 assert 'a'.count('') == 0
778 assert 'aa'.count('a') == 2
779 assert 'aa'.count('aa') == 1
780 assert 'aabbaa'.count('aa') == 2
781 assert 'bbaabb'.count('aa') == 1
782}
783
784fn test_lower() {
785 mut s := 'A'
786 assert !s.is_lower()
787 assert s.to_lower() == 'a'
788 assert s.to_lower().len == 1
789 s = 'HELLO'
790 assert !s.is_lower()
791 assert s.to_lower() == 'hello'
792 assert s.to_lower().len == 5
793 s = 'Aloha'
794 assert !s.is_lower()
795 assert s.to_lower() == 'aloha'
796 s = 'Have A nice Day!'
797 assert !s.is_lower()
798 assert s.to_lower() == 'have a nice day!'
799 s = 'hi'
800 assert s.is_lower()
801 assert s.to_lower() == 'hi'
802 assert 'aloha!'[0] == `a`
803 assert 'aloha!'[5] == `!`
804}
805
806fn test_upper() {
807 mut s := 'a'
808 assert !s.is_upper()
809 assert s.to_upper() == 'A'
810 assert s.to_upper().len == 1
811 s = 'hello'
812 assert !s.is_upper()
813 assert s.to_upper() == 'HELLO'
814 assert s.to_upper().len == 5
815 s = 'Aloha'
816 assert !s.is_upper()
817 assert s.to_upper() == 'ALOHA'
818 s = 'have a nice day!'
819 assert !s.is_upper()
820 assert s.to_upper() == 'HAVE A NICE DAY!'
821 s = 'HI'
822 assert s.is_upper()
823 assert s.to_upper() == 'HI'
824}
825
826fn test_capitalize() {
827 mut s := 'hello'
828 assert !s.is_capital()
829 assert s.capitalize() == 'Hello'
830 s = 'test'
831 assert !s.is_capital()
832 assert s.capitalize() == 'Test'
833 s = 'i am ray'
834 assert !s.is_capital()
835 assert s.capitalize() == 'I am ray'
836 s = ''
837 assert !s.is_capital()
838 assert s.capitalize() == ''
839 s = 'TEST IT'
840 assert !s.is_capital()
841 assert s.capitalize() == 'TEST IT'
842 s = 'Test it'
843 assert s.is_capital()
844 assert s.capitalize() == 'Test it'
845 assert 'GameMission_t'.capitalize() == 'GameMission_t'
846}
847
848fn test_title() {
849 mut s := 'hello world'
850 assert !s.is_title()
851 assert s.title() == 'Hello World'
852 s = 'HELLO WORLD'
853 assert !s.is_title()
854 assert s.title() == 'HELLO WORLD'
855 s = 'Hello World'
856 assert s.is_title()
857 assert s.title() == 'Hello World'
858}
859
860fn test_for_loop() {
861 mut i := 0
862 s := 'abcd'
863
864 for c in s {
865 assert c == s[i]
866 i++
867 }
868}
869
870fn test_for_loop_two() {
871 s := 'abcd'
872
873 for i, c in s {
874 assert c == s[i]
875 }
876}
877
878fn test_quote() {
879 a := `'`
880 b := 'hi'
881 assert b == 'hi'
882 assert a.str() == "'"
883}
884
885fn test_limit() {
886 s := 'hello'
887 assert s.limit(2) == 'he'
888 assert s.limit(9) == s
889 assert s.limit(0) == ''
890 // assert s.limit(-1) == ''
891}
892
893fn test_repeat() {
894 s1 := 'V! '
895 assert s1.repeat(5) == 'V! V! V! V! V! '
896 assert s1.repeat(1) == s1
897 assert s1.repeat(0) == ''
898 s2 := ''
899 assert s2.repeat(5) == s2
900 assert s2.repeat(1) == s2
901 assert s2.repeat(0) == s2
902 // TODO Add test for negative values
903}
904
905fn test_starts_with() {
906 s := 'V Programming Language'
907 assert s.starts_with('V') == true
908 assert s.starts_with('V Programming') == true
909 assert s.starts_with('Language') == false
910}
911
912fn test_starts_with_capital() {
913 assert 'A sentence'.starts_with_capital()
914 assert 'A paragraph. It also does.'.starts_with_capital()
915 assert ''.starts_with_capital() == false
916 assert 'no'.starts_with_capital() == false
917 assert ' No'.starts_with_capital() == false
918}
919
920fn test_trim_string_left() {
921 s := 'V Programming Language'
922 assert s.trim_string_left('V ') == 'Programming Language'
923 assert s.trim_string_left('V Programming ') == 'Language'
924 assert s.trim_string_left('Language') == s
925
926 s2 := 'TestTestTest'
927 assert s2.trim_string_left('Test') == 'TestTest'
928 assert s2.trim_string_left('TestTest') == 'Test'
929
930 s3 := '123Test123Test'
931 assert s3.trim_string_left('123') == 'Test123Test'
932 assert s3.trim_string_left('123Test') == '123Test'
933}
934
935fn test_trim_string_right() {
936 s := 'V Programming Language'
937 assert s.trim_string_right(' Language') == 'V Programming'
938 assert s.trim_string_right(' Programming Language') == 'V'
939 assert s.trim_string_right('V') == s
940
941 s2 := 'TestTestTest'
942 assert s2.trim_string_right('Test') == 'TestTest'
943 assert s2.trim_string_right('TestTest') == 'Test'
944
945 s3 := '123Test123Test'
946 assert s3.trim_string_right('123') == s3
947 assert s3.trim_string_right('123Test') == '123Test'
948}
949
950fn test_raw() {
951 raw := r'raw\nstring'
952 lines := raw.split('\n')
953 assert lines.len == 1
954
955 raw2 := r'Hello V\0'
956 assert raw2[7] == `\\`
957 assert raw2[8] == `0`
958
959 raw3 := r'Hello V\x00'
960 assert raw3[7] == `\\`
961 assert raw3[8] == `x`
962 assert raw3[9] == `0`
963 assert raw3[10] == `0`
964}
965
966fn test_raw_with_quotes() {
967 raw := r"some'" + r'"thing' // " should be escaped in the generated C code
968 assert raw[0] == `s`
969 assert raw[5] == `"`
970 assert raw[6] == `t`
971}
972
973fn test_escape() {
974 a := 10
975 assert "\"${a}" == '"10'
976}
977
978fn test_atoi() {
979 assert '234232'.int() == 234232
980 assert '-9009'.int() == -9009
981 assert '0'.int() == 0
982 for n in -10000 .. 100000 {
983 s := n.str()
984 assert s.int() == n
985 }
986}
987
988fn test_raw_inter() {
989 world := 'world'
990 s := r'hello\n$world'
991 assert s == r'hello\n$world'
992 assert s.contains('$')
993}
994
995fn test_c_r() {
996 // This used to break because of r'' and c''
997 c := 42
998 cs := '${c}'
999 r := 50
1000 rs := '${r}'
1001}
1002
1003fn test_inter_before_comptime_if() {
1004 s := '123'
1005 // This used to break ('123 $....')
1006 $if linux {
1007 }
1008 assert s == '123'
1009}
1010
1011fn test_double_quote_inter() {
1012 a := 1
1013 b := 2
1014 assert '${a} ${b}' == '1 2'
1015 assert '${a} ${b}' == '1 2'
1016}
1017
1018fn foo(b u8) u8 {
1019 return b - 10
1020}
1021
1022fn filter(b u8) bool {
1023 return b != `a`
1024}
1025
1026fn test_split_into_lines() {
1027 line_content := 'line content'
1028
1029 text_cr := '${line_content}\r${line_content}\r${line_content}'
1030 lines_cr := text_cr.split_into_lines()
1031
1032 assert lines_cr.len == 3
1033 for line in lines_cr {
1034 assert line == line_content
1035 }
1036
1037 text_crlf := '${line_content}\r\n${line_content}\r\n${line_content}'
1038 lines_crlf := text_crlf.split_into_lines()
1039
1040 assert lines_crlf.len == 3
1041 for line in lines_crlf {
1042 assert line == line_content
1043 }
1044
1045 text_lf := '${line_content}\n${line_content}\n${line_content}'
1046 lines_lf := text_lf.split_into_lines()
1047
1048 assert lines_lf.len == 3
1049 for line in lines_lf {
1050 assert line == line_content
1051 }
1052
1053 text_mixed := '${line_content}\n${line_content}\r${line_content}'
1054 lines_mixed := text_mixed.split_into_lines()
1055
1056 assert lines_mixed.len == 3
1057 for line in lines_mixed {
1058 assert line == line_content
1059 }
1060
1061 text_mixed_trailers := '${line_content}\n${line_content}\r${line_content}\r\r\r\n\n\n\r\r'
1062 lines_mixed_trailers := text_mixed_trailers.split_into_lines()
1063
1064 assert lines_mixed_trailers.len == 9
1065 for line in lines_mixed_trailers {
1066 assert line == line_content || line == ''
1067 }
1068}
1069
1070fn test_string_literal_with_backslash() {
1071 a := 'HelloWorld'
1072 assert a == 'HelloWorld'
1073
1074 b := 'OneTwoThree'
1075 assert b == 'OneTwoThree'
1076}
1077
1078/*
1079type MyString = string
1080
1081fn test_string_alias() {
1082 s := MyString('hi')
1083 ss := s + '!'
1084}
1085*/
1086
1087// sort an array of structs, by their string field values
1088
1089struct Ka {
1090 s string
1091 i int
1092}
1093
1094fn test_sorter() {
1095 mut arr := [
1096 Ka{
1097 s: 'bbb'
1098 i: 100
1099 },
1100 Ka{
1101 s: 'aaa'
1102 i: 101
1103 },
1104 Ka{
1105 s: 'ccc'
1106 i: 102
1107 },
1108 ]
1109 cmp := fn (a &Ka, b &Ka) int {
1110 return compare_strings(a.s, b.s)
1111 }
1112 arr.sort_with_compare(cmp)
1113 assert arr[0].s == 'aaa'
1114 assert arr[0].i == 101
1115 assert arr[1].s == 'bbb'
1116 assert arr[1].i == 100
1117 assert arr[2].s == 'ccc'
1118 assert arr[2].i == 102
1119}
1120
1121fn test_fields() {
1122 assert 'a bcde'.fields() == ['a', 'bcde']
1123 assert ' sss \t ssss '.fields() == ['sss', 'ssss']
1124 assert '\n xyz \t abc def'.fields() == ['xyz', 'abc', 'def']
1125 assert 'hello'.fields() == ['hello']
1126 assert ''.fields() == []
1127}
1128
1129fn test_interpolation_after_quoted_variable_still_works() {
1130 rr := 'abc'
1131 tt := 'xyz'
1132
1133 // Basic interpolation, no internal quotes
1134 yy := 'Replacing ${rr} with ${tt}'
1135 assert yy == 'Replacing abc with xyz'
1136
1137 // Interpolation after quoted variable ending with 'r'quote
1138 // that may be mistaken with the start of a raw string,
1139 // ensure that it is not.
1140 ss := 'Replacing "${rr}" with "${tt}"'
1141 assert ss == 'Replacing "abc" with "xyz"'
1142 zz := "Replacing '${rr}' with '${tt}'"
1143 assert zz == "Replacing 'abc' with 'xyz'"
1144
1145 // Interpolation after quoted variable ending with 'c'quote
1146 // may be mistaken with the start of a c string, so
1147 // check it is not.
1148 cc := 'abc'
1149 ccc := "Replacing '${cc}' with '${tt}'"
1150 assert ccc == "Replacing 'abc' with 'xyz'"
1151 cccq := 'Replacing "${cc}" with "${tt}"'
1152 assert cccq == 'Replacing "abc" with "xyz"'
1153}
1154
1155fn test_emoji_to_runes() {
1156 x := '👋'
1157 assert x.runes()[0] == `👋`
1158}
1159
1160fn test_string_to_rune() {
1161 x := 'Hello World 👋'
1162 assert x.runes().len == 13
1163}
1164
1165fn test_index_any() {
1166 x := 'abcdefghij'
1167 assert x.index_any('ef') == 4
1168 assert x.index_any('fe') == 4
1169}
1170
1171fn test_string_f64() {
1172 assert ''.f64() == 0
1173 assert '123'.f64() == 123
1174 assert '-123'.f64() == -123
1175 assert '-123.456'.f64() == -123.456
1176}
1177
1178const f32_epsilon = 0.0000000001
1179
1180fn test_string_f32() {
1181 assert ''.f32() - 0 <= f32_epsilon
1182 assert '123'.f32() - 123 < f32_epsilon
1183 assert '-123'.f32() - (-123) < f32_epsilon
1184 assert '-123.456'.f32() - (-123.456) <= f32_epsilon
1185}
1186
1187fn test_string_is_ascii() {
1188 assert ''.is_ascii() == true
1189 assert ' '.is_ascii() == true
1190 assert '~~'.is_ascii() == true
1191 assert ' Az~'.is_ascii() == true
1192 assert ' Aö~'.is_ascii() == false
1193 assert '👋'.is_ascii() == false
1194 assert 'a👋bc'.is_ascii() == false
1195}
1196
1197fn test_string_with_zero_byte_escape() {
1198 assert '\x00'.bytes() == [u8(0)]
1199}
1200
1201fn test_is_blank() {
1202 assert ''.is_blank()
1203 assert ' '.is_blank()
1204 assert ' \t'.is_blank()
1205 assert ' \t
1206
1207'.is_blank()
1208 assert ' \t\r'.is_blank()
1209 assert ' \t\r
1210
1211'.is_blank()
1212}
1213
1214fn test_indent_width() {
1215 assert 'abc'.indent_width() == 0
1216 assert ' abc'.indent_width() == 1
1217 assert ' abc'.indent_width() == 2
1218 assert '\tabc'.indent_width() == 1
1219 assert '\t abc'.indent_width() == 2
1220 assert '\t\tabc'.indent_width() == 2
1221 assert '\t\t abc'.indent_width() == 3
1222}
1223
1224fn test_index_u8() {
1225 assert 'abcabca'.index_u8(`a`) == 0
1226 assert 'abcabca'.index_u8(`b`) == 1
1227 assert 'abcabca'.index_u8(`c`) == 2
1228 //
1229 assert 'abc'.index_u8(`d`) == -1
1230 assert 'abc'.index_u8(`A`) == -1
1231 assert 'abc'.index_u8(`B`) == -1
1232 assert 'abc'.index_u8(`C`) == -1
1233 //
1234}
1235
1236fn test_last_index_u8() {
1237 assert 'abcabca'.last_index_u8(`a`) == 6
1238 assert 'abcabca'.last_index_u8(`c`) == 5
1239 assert 'abcabca'.last_index_u8(`b`) == 4
1240 assert 'Zabcabca'.last_index_u8(`Z`) == 0
1241 //
1242 assert 'abc'.index_u8(`d`) == -1
1243 assert 'abc'.index_u8(`A`) == -1
1244 assert 'abc'.index_u8(`B`) == -1
1245 assert 'abc'.index_u8(`C`) == -1
1246}
1247
1248fn test_contains_byte() {
1249 assert 'abc abca'.contains_u8(`a`)
1250 assert 'abc abca'.contains_u8(`b`)
1251 assert 'abc abca'.contains_u8(`c`)
1252 assert 'abc abca'.contains_u8(` `)
1253 assert !'abc abca'.contains_u8(`A`)
1254}