1 # This file contains auto-generated tests from the examples in api/*.yaml
5 assert Bool.parse("yes") == yes
6 assert Bool.parse("no") == no
7 assert Bool.parse("???") == none
9 assert Bool.parse("yesJUNK") == none
11 assert Bool.parse("yesJUNK", &remainder) == yes
12 assert remainder == "JUNK"
14 do # Test Byte.get_bit
15 assert Byte(6).get_bit(1) == no
16 assert Byte(6).get_bit(2) == yes
17 assert Byte(6).get_bit(3) == yes
18 assert Byte(6).get_bit(4) == no
21 assert Byte(18).hex(prefix=yes) == "0x12"
23 do # Test Byte.is_between
24 assert Byte(7).is_between(1, 10) == yes
25 assert Byte(7).is_between(10, 1) == yes
26 assert Byte(7).is_between(100, 200) == no
27 assert Byte(7).is_between(1, 7) == yes
30 assert Byte.parse("5") == Byte(5)
31 assert Byte.parse("asdf") == none
32 assert Byte.parse("123xyz") == none
35 assert Byte.parse("123xyz", remainder=&remainder) == Byte(123)
36 assert remainder == "xyz"
40 assert iter() == Byte(2)
41 assert iter() == Byte(3)
42 assert iter() == Byte(4)
45 assert [x for x in Byte(2).to(5)] == [Byte(2), Byte(3), Byte(4), Byte(5)]
46 assert [x for x in Byte(5).to(2)] == [Byte(5), Byte(4), Byte(3), Byte(2)]
47 assert [x for x in Byte(2).to(5, step=2)] == [Byte(2), Byte(4)]
49 do # Test CString.as_text
50 assert CString("Hello").as_text() == "Hello"
52 do # Test CString.join
53 assert CString(",").join([CString("a"), CString("b")]) == CString("a,b")
56 assert (-10).abs() == 10
59 assert 4.choose(2) == 6
62 assert 2.clamped(5, 10) == 5
64 do # Test Int.factorial
65 assert 10.factorial() == 3628800
68 assert 6.get_bit(1) == no
69 assert 6.get_bit(2) == yes
70 assert 6.get_bit(3) == yes
71 assert 6.get_bit(4) == no
74 assert 255.hex(digits=4, uppercase=yes, prefix=yes) == "0x00FF"
76 do # Test Int.is_between
77 assert 7.is_between(1, 10) == yes
78 assert 7.is_between(10, 1) == yes
79 assert 7.is_between(100, 200) == no
80 assert 7.is_between(1, 7) == yes
82 do # Test Int.is_prime
83 assert 7.is_prime() == yes
84 assert 6.is_prime() == no
86 do # Test Int.next_prime
87 assert 11.next_prime() == 13
90 assert 64.octal(digits=4, prefix=yes) == "0o0100"
97 assert nums[] == [5, 6, 7, 8, 9, 10]
100 assert Int.parse("123") == 123
101 assert Int.parse("0xFF") == 255
102 assert Int.parse("123xyz") == none
104 assert Int.parse("123xyz", remainder=&remainder) == 123
105 assert remainder == "xyz"
108 assert Int.parse("asdf") == none
110 # Outside valid range:
111 assert Int8.parse("9999999") == none
113 # Explicitly specifying base:
114 assert Int.parse("10", base=16) == 16
117 assert 16.sqrt() == 4
118 assert 17.sqrt() == 4
126 assert iter() == none
128 assert [x for x in 2.to(5)] == [2, 3, 4, 5]
129 assert [x for x in 5.to(2)] == [5, 4, 3, 2]
130 assert [x for x in 2.to(5, step=2)] == [2, 4]
132 do # Test List.binary_search
133 assert [1, 3, 5, 7, 9].binary_search(5) == 3
134 assert [1, 3, 5, 7, 9].binary_search(-999) == 1
135 assert [1, 3, 5, 7, 9].binary_search(999) == 6
138 assert [1, 2, 3, 4, 5, 6].by(2) == [1, 3, 5]
145 do # Test List.counts
146 assert [10, 20, 30, 30, 30].counts() == {10:1, 20:1, 30:3}
149 assert [10, 20, 30, 40, 50].find(20) == 2
150 assert [10, 20, 30, 40, 50].find(9999) == none
153 assert [10, 20, 30, 40, 50].from(3) == [30, 40, 50]
156 assert [10, 20, 30].has(20) == yes
158 do # Test List.heap_pop
159 my_heap := &[30, 10, 20]
161 assert my_heap.heap_pop() == 10
163 do # Test List.heap_push
165 my_heap.heap_push(10)
166 assert my_heap.heap_pop() == 10
168 do # Test List.heapify
169 my_heap := &[30, 10, 20]
172 do # Test List.insert
175 assert list == [10, 20, 30]
177 list.insert(999, at=2)
178 assert list == [10, 999, 20, 30]
180 do # Test List.insert_all
182 list.insert_all([30, 40])
183 assert list == [10, 20, 30, 40]
185 list.insert_all([99, 100], at=2)
186 assert list == [10, 99, 100, 20, 30, 40]
189 list := &[10, 20, 30, 40]
191 assert list.pop() == 40
192 assert list[] == [10, 20, 30]
194 assert list.pop(index=2) == 20
195 assert list[] == [10, 30]
197 do # Test List.random
199 pick := nums.random()!
200 assert nums.has(pick)
202 assert empty.random() == none
204 do # Test List.remove_at
205 list := &[10, 20, 30, 40, 50]
207 assert list == [10, 30, 40, 50]
209 list.remove_at(2, count=2)
210 assert list == [10, 50]
212 do # Test List.remove_item
213 list := &[10, 20, 10, 20, 30]
215 assert list == [20, 20, 30]
217 list.remove_item(20, max_count=1)
218 assert list == [20, 30]
220 do # Test List.reversed
221 assert [10, 20, 30].reversed() == [30, 20, 10]
223 do # Test List.sample
224 _ := [10, 20, 30].sample(2, weights=[90%, 5%, 5%]) # E.g. [10, 10]
226 do # Test List.shuffle
227 nums := &[10, 20, 30, 40]
229 # E.g. [20, 40, 10, 30]
231 do # Test List.shuffled
232 nums := [10, 20, 30, 40]
234 # E.g. [20, 40, 10, 30]
237 assert [10, 20, 30, 40, 50].slice(2, 4) == [20, 30, 40]
238 assert [10, 20, 30, 40, 50].slice(-3, -2) == [30, 40]
241 list := &[40, 10, -30, 20]
243 assert list == [-30, 10, 20, 40]
245 list.sort(func(a,b:&Int) a.abs() <> b.abs())
246 assert list == [10, 20, -30, 40]
248 do # Test List.sorted
249 assert [40, 10, -30, 20].sorted() == [-30, 10, 20, 40]
250 assert [40, 10, -30, 20].sorted(
251 func(a,b:&Int) a.abs() <> b.abs()
252 ) == [10, 20, -30, 40]
255 assert [10, 20, 30, 40, 50].to(3) == [10, 20, 30]
256 assert [10, 20, 30, 40, 50].to(-2) == [10, 20, 30, 40]
258 do # Test List.unique
259 assert [10, 20, 10, 10, 30].unique() == {10, 20, 30}
262 assert ["BC", "ABC", "CD"].where(func(t:&Text) t.starts_with("A")) == 2
263 assert ["BC", "ABC", "CD"].where(func(t:&Text) t.starts_with("X")) == none
266 assert (-3.5).abs() == 3.5
269 assert (0.0).acos().near(1.5707963267948966)
272 assert (1.0).acosh() == 0
275 assert (0.5).asin().near(0.5235987755982989)
278 assert (0.0).asinh() == 0
281 assert (1.0).atan().near(0.7853981633974483)
284 assert Num.atan2(1, 1).near(0.7853981633974483)
287 assert (0.5).atanh().near(0.5493061443340549)
290 assert (27.0).cbrt() == 3
293 assert (3.2).ceil() == 4
295 do # Test Num.clamped
296 assert (2.5).clamped(5.5, 10.5) == 5.5
298 do # Test Num.copysign
299 assert (3.0).copysign(-1) == -3
302 assert (0.0).cos() == 1
305 assert (0.0).cosh() == 1
308 assert (0.0).erf() == 0
311 assert (0.0).erfc() == 1
314 assert (1.0).exp().near(2.718281828459045)
317 assert (3.0).exp2() == 8
320 assert (1.0).expm1().near(1.7182818284590453)
323 assert (5.0).fdim(3) == 2
326 assert (3.7).floor() == 3
329 assert Num.hypot(3, 4) == 5
331 do # Test Num.is_between
332 assert (7.5).is_between(1, 10) == yes
333 assert (7.5).is_between(10, 1) == yes
334 assert (7.5).is_between(100, 200) == no
335 assert (7.5).is_between(1, 7.5) == yes
337 do # Test Num.isfinite
338 assert (1.0).isfinite() == yes
339 assert Num.INF.isfinite() == no
342 assert Num.INF.isinf() == yes
343 assert (1.0).isinf() == no
346 assert (0.0).j0() == 1
349 assert (0.0).j1() == 0
352 assert Num.E.log() == 1
355 assert (100.0).log10() == 2
358 assert (1.0).log1p().near(0.6931471805599453)
361 assert (8.0).log2() == 3
364 assert (8.0).logb() == 3
367 assert (0.5).mix(10, 20) == 15
368 assert (0.25).mix(10, 20) == 12.5
371 assert (1.0).near(1.000000001) == yes
372 assert (100.0).near(110, ratio=0.1) == yes
373 assert (5.0).near(5.1, min_epsilon=0.1) == yes
375 do # Test Num.nextafter
376 assert (1.0).nextafter(1.1) == 1.0000000000000002
379 assert Num.parse("3.14") == 3.14
380 assert Num.parse("1e3") == 1000
381 assert Num.parse("1.5junk") == none
383 assert Num.parse("1.5junk", &remainder) == 1.5
384 assert remainder == "junk"
386 do # Test Num.percent
387 assert (0.5).percent() == "50%"
388 assert (1./3.).percent(2) == "34%"
389 assert (1./3.).percent(precision=0.0001) == "33.3333%"
390 assert (1./3.).percent(precision=10.) == "30%"
393 assert (3.5).rint() == 4
394 assert (2.5).rint() == 2
397 assert (2.3).round() == 2
398 assert (2.7).round() == 3
400 do # Test Num.significand
401 assert (1234.567).significand() == 1.2056318359375
404 assert (0.0).sin() == 0
407 assert (0.0).sinh() == 0
410 assert (16.0).sqrt() == 4
413 assert (0.0).tan() == 0
416 assert (0.0).tanh() == 0
419 assert (1.0).tgamma() == 1
422 assert (3.7).trunc() == 3
423 assert (-3.7).trunc() == -3
425 do # Test Num.with_precision
426 assert (0.1234567).with_precision(0.01) == 0.12
427 assert (123456.).with_precision(100) == 123500
428 assert (1234567.).with_precision(5) == 1234565
431 assert (1.0).y0().near(0.08825696421567698)
434 assert (1.0).y1().near(-0.7812128213002887)
436 if no # Test Path.accessed
437 assert (./file.txt).accessed() == Int64(1704221100)
438 assert (./not-a-file).accessed() == none
440 if no # Test Path.append
441 (./log.txt).append("extra line\n")!
443 if no # Test Path.append_bytes
444 (./log.txt).append_bytes([104, 105])!
446 if no # Test Path.base_name
447 assert (./path/to/file.txt).base_name() == "file.txt"
449 if no # Test Path.by_line
450 # Safely handle file not being readable:
451 if lines := (./file.txt).by_line()
455 say("Couldn't read file!")
457 # Assume the file is readable and error if that's not the case:
458 for line in (/dev/stdin).by_line()!
461 if no # Test Path.byte_writer
462 write := (./file.txt).byte_writer()
463 write("Hello\n".utf8())!
464 write("world\n".utf8(), close=yes)!
466 if no # Test Path.can_execute
467 assert (/bin/sh).can_execute() == yes
468 assert (/usr/include/stdlib.h).can_execute() == no
469 assert (/non/existant/file).can_execute() == no
471 if no # Test Path.can_read
472 assert (/usr/include/stdlib.h).can_read() == yes
473 assert (/etc/shadow).can_read() == no
474 assert (/non/existant/file).can_read() == no
476 if no # Test Path.can_write
477 assert (/tmp).can_write() == yes
478 assert (/etc/passwd).can_write() == no
479 assert (/non/existant/file).can_write() == no
481 if no # Test Path.changed
482 assert (./file.txt).changed() == Int64(1704221100)
483 assert (./not-a-file).changed() == none
485 if no # Test Path.child
486 assert (./directory).child("file.txt") == (./directory/file.txt)
488 if no # Test Path.children
489 assert (./directory).children(include_hidden=yes) == [(./directory/.git), (./directory/foo.txt)]
491 if no # Test Path.create_directory
492 (./new_directory).create_directory()!
494 if no # Test Path.current_dir
495 assert Path.current_dir() == (/home/user/tomo)
497 if no # Test Path.each_child
498 for child in (/dir).each_child()
501 if no # Test Path.exists
502 assert (/).exists() == yes
504 if no # Test Path.expand_home
505 # Assume current user is 'user'
506 assert (~/foo).expand_home() == (/home/user/foo)
508 assert (/foo).expand_home() == (/foo)
510 if no # Test Path.extension
511 assert (./file.tar.gz).extension() == "tar.gz"
512 assert (./file.tar.gz).extension(full=no) == "gz"
513 assert (/foo).extension() == ""
514 assert (./.git).extension() == ""
516 if no # Test Path.files
517 assert (./directory).files(include_hidden=yes) == [(./directory/file1.txt), (./directory/file2.txt)]
519 if no # Test Path.glob
520 # Current directory includes: foo.txt, baz.txt, qux.jpg, .hidden
521 assert (./*).glob() == [(./foo.txt), (./baz.txt), (./qux.jpg)]
522 assert (./*.txt).glob() == [(./foo.txt), (./baz.txt)]
523 assert (./*.{txt,jpg}).glob() == [(./foo.txt), (./baz.txt), (./qux.jpg)]
524 assert (./.*).glob() == [(./.hidden)]
526 # Globs with no matches return an empty list:
527 assert (./*.xxx).glob() == []
529 if no # Test Path.group
530 assert (/bin).group() == "root"
531 assert (/non/existent/file).group() == none
533 if no # Test Path.has_extension
534 assert (/foo.txt).has_extension("txt") == yes
535 assert (/foo.txt).has_extension(".txt") == yes
536 assert (/foo.tar.gz).has_extension("gz") == yes
537 assert (/foo.tar.gz).has_extension("zip") == no
539 if no # Test Path.is_directory
540 assert (./directory/).is_directory() == yes
541 assert (./file.txt).is_directory() == no
543 if no # Test Path.is_file
544 assert (./file.txt).is_file() == yes
545 assert (./directory/).is_file() == no
547 if no # Test Path.is_socket
548 assert (./socket).is_socket() == yes
550 if no # Test Path.is_symlink
551 assert (./link).is_symlink() == yes
553 if no # Test Path.lines
554 lines := (./file.txt).lines()!
556 if no # Test Path.matches_glob
557 assert (./file.txt).matches_glob("*.txt")
558 assert (./file.c).matches_glob("*.{c,h}")
560 if no # Test Path.modified
561 assert (./file.txt).modified() == Int64(1704221100)
562 assert (./not-a-file).modified() == none
564 if no # Test Path.move
565 (./file.txt).move(/tmp/renamed.txt)!
567 if no # Test Path.owner
568 assert (/bin).owner() == "root"
569 assert (/non/existent/file).owner() == none
571 if no # Test Path.parent
572 assert (./path/to/file.txt).parent() == (./path/to/)
574 if no # Test Path.read
575 assert (./hello.txt).read() == "Hello"
576 assert (./nosuchfile.xxx).read() == none
578 if no # Test Path.read_bytes
579 assert (./hello.txt).read_bytes()! == [72, 101, 108, 108, 111]
580 assert (./nosuchfile.xxx).read_bytes() == none
582 if no # Test Path.relative_to
583 assert (./path/to/file.txt).relative_to((./path)) == (./to/file.txt)
584 assert (/tmp/foo).relative_to((/tmp)) == (./foo)
586 if no # Test Path.remove
587 (./file.txt).remove()!
589 if no # Test Path.resolved
590 assert (~/foo).resolved() == (/home/user/foo)
591 assert (./path/to/file.txt).resolved(relative_to=(/foo)) == (/foo/path/to/file.txt)
593 if no # Test Path.set_owner
594 (./file.txt).set_owner(owner="root", group="wheel")!
596 if no # Test Path.sibling
597 assert (/foo/baz).sibling("doop") == (/foo/doop)
599 if no # Test Path.subdirectories
600 assert (./directory).subdirectories() == [(./directory/subdir1), (./directory/subdir2)]
601 assert (./directory).subdirectories(include_hidden=yes) == [(./directory/.git), (./directory/subdir1), (./directory/subdir2)]
603 if no # Test Path.unique_directory
604 created := (/tmp/my-dir.XXXXXX).unique_directory()
605 assert created.is_directory() == yes
608 if no # Test Path.walk
609 for p in (/tmp).walk()
610 say("File or dir: $p")
612 # The path itself is always included:
613 assert [p for p in (./file.txt).walk()] == [(./file.txt)]
615 if no # Test Path.write
616 (./file.txt).write("Hello, world!")!
618 if no # Test Path.write_bytes
619 (./file.txt).write_bytes([104, 105])!
621 if no # Test Path.write_unique
622 created := (./file-XXXXXX.txt).write_unique("Hello, world!")!
623 assert created == (./file-27QHtq.txt)
624 assert created.read()! == "Hello, world!"
627 if no # Test Path.write_unique_bytes
628 created := (./file-XXXXXX.txt).write_unique_bytes([1, 2, 3])!
629 assert created == (./file-27QHtq.txt)
630 assert created.read_bytes()! == [1, 2, 3]
633 if no # Test Path.writer
634 write := (./file.txt).writer()
636 write("world\n", close=yes)!
638 do # Test Table.clear
643 do # Test Table.difference
644 t1 := {"A": 1, "B": 2, "C": 3}
645 t2 := {"B": 2, "C":30, "D": 40}
646 assert t1.difference(t2) == {"A": 1, "D": 40}
649 t := {"A": 1, "B": 2}
650 assert t.get("A") == 1
651 assert t.get("????") == none
652 assert t.get("A")! == 1
653 assert t.get("????") or 0 == 0
655 do # Test Table.get_or_set
656 t := &{"A": @[1, 2, 3]; default=@[]}
657 t.get_or_set("A").insert(4)
658 t.get_or_set("B").insert(99)
659 assert t["A"][] == [1, 2, 3, 4]
660 assert t["B"][] == [99]
661 assert t.get_or_set("C", @[0, 0, 0])[] == [0, 0, 0]
664 assert {"A": 1, "B": 2}.has("A") == yes
665 assert {"A": 1, "B": 2}.has("xxx") == no
667 do # Test Table.intersection
668 t1 := {"A": 1, "B": 2, "C": 3}
669 t2 := {"B": 2, "C":30, "D": 40}
670 assert t1.intersection(t2) == {"B": 2}
672 do # Test Table.remove
673 t := &{"A": 1, "B": 2}
678 t := &{"A": 1, "B": 2}
680 assert t == {"A": 1, "B": 2, "C": 3}
683 t := {"A": 1, "B": 2}
684 assert t.with({"B": 20, "C": 30}) == {"A": 1, "B": 20, "C": 30}
686 do # Test Table.with_fallback
687 t := {"A": 1; fallback={"B": 2}}
688 t2 := t.with_fallback({"B": 3})
690 t3 := t.with_fallback(none)
691 assert t3["B"] == none
693 do # Test Table.without
694 t := {"A": 1, "B": 2, "C": 3}
695 assert t.without({"B": 2, "C": 30, "D": 40}) == {"A": 1, "C": 3}
697 do # Test Text.as_c_string
698 assert "Hello".as_c_string() == CString("Hello")
701 assert "Amélie".at(3) == "é"
703 do # Test Text.by_line
708 lines := [line for line in text.by_line()]
709 assert lines == ["line one", "line two"]
711 do # Test Text.by_split
712 text := "one,two,three"
713 chunks := [chunk for chunk in text.by_split(",")]
714 assert chunks == ["one", "two", "three"]
716 do # Test Text.by_split_any
717 text := "one,two,;,three"
718 chunks := [chunk for chunk in text.by_split_any(",;")]
719 assert chunks == ["one", "two", "three"]
721 do # Test Text.caseless_equals
722 assert "A".caseless_equals("a") == yes
724 # Turkish lowercase "I" is "ı" (dotless I), not "i"
725 assert "I".caseless_equals("i", language="tr_TR") == no
727 do # Test Text.codepoint_names
728 assert "Amélie".codepoint_names() == [
729 "LATIN CAPITAL LETTER A",
730 "LATIN SMALL LETTER M",
731 "LATIN SMALL LETTER E WITH ACUTE",
732 "LATIN SMALL LETTER L",
733 "LATIN SMALL LETTER I",
734 "LATIN SMALL LETTER E",
737 do # Test Text.distance
738 assert "hello".distance("hello") == 0
739 texts := &["goodbye", "hello", "hallo"]
740 texts.sort(func(a,b:&Text) a.distance("hello") <> b.distance("hello"))
741 assert texts == ["hello", "hallo", "goodbye"]
743 do # Test Text.ends_with
744 assert "hello world".ends_with("world") == yes
746 assert "hello world".ends_with("world", &remainder) == yes
747 assert remainder == "hello "
750 assert "one two".find("one") == 1
751 assert "one two".find("two") == 5
752 assert "one two".find("three") == none
753 assert "one two".find("o", start=2) == 7
756 assert "hello".from(2) == "ello"
757 assert "hello".from(-2) == "lo"
759 do # Test Text.from_c_string
760 assert Text.from_c_string(CString("Hello")) == "Hello"
762 do # Test Text.from_codepoint_names
763 text := Text.from_codepoint_names([
764 "LATIN CAPITAL LETTER A WITH RING ABOVE",
765 "LATIN SMALL LETTER K",
766 "LATIN SMALL LETTER E",
770 do # Test Text.from_utf16
771 assert Text.from_utf16([197, 107, 101]) == "Åke"
772 assert Text.from_utf16([12371, 12435, 12395, 12385, 12399, 19990, 30028]) == "こんにちは世界"
774 do # Test Text.from_utf32
775 assert Text.from_utf32([197, 107, 101]) == "Åke"
777 do # Test Text.from_utf8
778 assert Text.from_utf8([195, 133, 107, 101]) == "Åke"
781 assert "hello world".has("wo") == yes
782 assert "hello world".has("xxx") == no
785 assert ", ".join(["one", "two", "three"]) == "one, two, three"
787 do # Test Text.left_pad
788 assert "x".left_pad(5) == " x"
789 assert "x".left_pad(5, "ABC") == "ABCAx"
792 assert "one\ntwo\nthree".lines() == ["one", "two", "three"]
793 assert "one\ntwo\nthree\n".lines() == ["one", "two", "three"]
794 assert "one\ntwo\nthree\n\n".lines() == ["one", "two", "three", ""]
795 assert "one\r\ntwo\r\nthree\r\n".lines() == ["one", "two", "three"]
796 assert "".lines() == []
799 assert "AMÉLIE".lower() == "amélie"
800 assert "I".lower(language="tr_TR") == "ı"
802 do # Test Text.matches_glob
803 assert "hello world".matches_glob("h* *d")
805 do # Test Text.middle_pad
806 assert "x".middle_pad(6) == " x "
807 assert "x".middle_pad(10, "ABC") == "ABCAxABCAB"
809 do # Test Text.quoted
810 assert "one\ntwo".quoted() == "\"one\\ntwo\""
812 do # Test Text.repeat
813 assert "Abc".repeat(3) == "AbcAbcAbc"
815 do # Test Text.replace
816 assert "Hello world".replace("world", "there") == "Hello there"
818 do # Test Text.reversed
819 assert "Abc".reversed() == "cbA"
821 do # Test Text.right_pad
822 assert "x".right_pad(5) == "x "
823 assert "x".right_pad(5, "ABC") == "xABCA"
826 assert "hello".slice(2, 3) == "el"
827 assert "hello".slice(to=-2) == "hell"
828 assert "hello".slice(from=2) == "ello"
831 assert "one,two,,three".split(",") == ["one", "two", "", "three"]
832 assert "abc".split() == ["a", "b", "c"]
834 do # Test Text.split_any
835 assert "one, two,,three".split_any(", ") == ["one", "two", "three"]
837 do # Test Text.starts_with
838 assert "hello world".starts_with("hello") == yes
840 assert "hello world".starts_with("hello", &remainder) == yes
841 assert remainder == " world"
844 assert "amélie".title() == "Amélie"
846 # In Turkish, uppercase "i" is "İ"
847 assert "i".title(language="tr_TR") == "İ"
850 assert "goodbye".to(3) == "goo"
851 assert "goodbye".to(-2) == "goodby"
853 do # Test Text.translate
854 text := "A <tag> & an ampersand".translate({
861 assert text == "A <tag> & an ampersand"
864 assert " x y z \n".trim() == "x y z"
865 assert "one,".trim(",") == "one"
866 assert " xyz ".trim(right=no) == "xyz "
869 assert "amélie".upper() == "AMÉLIE"
871 # In Turkish, uppercase "i" is "İ"
872 assert "i".upper(language="tr_TR") == "İ"
875 assert "Åke".utf16() == [197, 107, 101]
876 assert "こんにちは世界".utf16() == [12371, 12435, 12395, 12385, 12399, 19990, 30028]
879 assert "Amélie".utf32() == [65, 109, 233, 108, 105, 101]
882 assert "Amélie".utf8() == [65, 109, 195, 169, 108, 105, 101]
885 assert "Amélie".width() == 6
886 assert "🤠".width() == 2
888 do # Test Text.without_prefix
889 assert "foo:baz".without_prefix("foo:") == "baz"
890 assert "qux".without_prefix("foo:") == "qux"
892 do # Test Text.without_suffix
893 assert "baz.foo".without_suffix(".foo") == "baz"
894 assert "qux".without_suffix(".foo") == "qux"
897 assert ask("What's your name? ") == "Arthur Dent"
899 if no # Test at_cleanup
901 _ := (/tmp/file.txt).remove(ignore_missing=yes)
905 exit("Goodbye forever!", Int32(1))
911 assert getenv("TERM") == "xterm-256color"
912 assert getenv("not_a_variable") == none
915 print("Hello ", newline=no)
919 say("Hello ", newline=no)
923 setenv("FOOBAR", "xyz")