From 33928a00dc58250e24da1dae4e5db17e7b598d70 Mon Sep 17 00:00:00 2001 From: Laurenz Date: Thu, 3 Nov 2022 16:50:26 +0100 Subject: Tidy up library --- tests/ref/base/blind.png | Bin 0 -> 27575 bytes tests/ref/base/collection.png | Bin 0 -> 1384 bytes tests/ref/base/color.png | Bin 0 -> 595 bytes tests/ref/base/data.png | Bin 0 -> 8603 bytes tests/ref/base/eval.png | Bin 0 -> 5429 bytes tests/ref/base/numbering.png | Bin 0 -> 10634 bytes tests/ref/base/string.png | Bin 0 -> 10614 bytes tests/ref/layout/math.png | Bin 0 -> 6554 bytes tests/ref/math/basic.png | Bin 6554 -> 0 bytes tests/ref/text/basic.png | Bin 58344 -> 0 bytes tests/ref/text/plain.png | Bin 0 -> 58344 bytes tests/ref/utility/blind.png | Bin 27575 -> 0 bytes tests/ref/utility/collection.png | Bin 1384 -> 0 bytes tests/ref/utility/color.png | Bin 595 -> 0 bytes tests/ref/utility/data.png | Bin 8603 -> 0 bytes tests/ref/utility/eval.png | Bin 5429 -> 0 bytes tests/ref/utility/numbering.png | Bin 10634 -> 0 bytes tests/ref/utility/string.png | Bin 10614 -> 0 bytes tests/src/benches.rs | 3 +- tests/src/tests.rs | 5 +- tests/typ/base/assert.typ | 23 ++++++ tests/typ/base/blind.typ | 32 ++++++++ tests/typ/base/calc.typ | 117 ++++++++++++++++++++++++++++ tests/typ/base/collection.typ | 115 ++++++++++++++++++++++++++++ tests/typ/base/color.typ | 63 +++++++++++++++ tests/typ/base/data.typ | 58 ++++++++++++++ tests/typ/base/eval.typ | 52 +++++++++++++ tests/typ/base/string.typ | 161 +++++++++++++++++++++++++++++++++++++++ tests/typ/base/type.typ | 7 ++ tests/typ/layout/math.typ | 20 +++++ tests/typ/math/basic.typ | 20 ----- tests/typ/text/basic.typ | 20 ----- tests/typ/text/plain.typ | 20 +++++ tests/typ/utility/basics.typ | 24 ------ tests/typ/utility/blind.typ | 32 -------- tests/typ/utility/collection.typ | 115 ---------------------------- tests/typ/utility/color.typ | 63 --------------- tests/typ/utility/data.typ | 58 -------------- tests/typ/utility/eval.typ | 52 ------------- tests/typ/utility/math.typ | 117 ---------------------------- tests/typ/utility/string.typ | 161 --------------------------------------- 41 files changed, 671 insertions(+), 667 deletions(-) create mode 100644 tests/ref/base/blind.png create mode 100644 tests/ref/base/collection.png create mode 100644 tests/ref/base/color.png create mode 100644 tests/ref/base/data.png create mode 100644 tests/ref/base/eval.png create mode 100644 tests/ref/base/numbering.png create mode 100644 tests/ref/base/string.png create mode 100644 tests/ref/layout/math.png delete mode 100644 tests/ref/math/basic.png delete mode 100644 tests/ref/text/basic.png create mode 100644 tests/ref/text/plain.png delete mode 100644 tests/ref/utility/blind.png delete mode 100644 tests/ref/utility/collection.png delete mode 100644 tests/ref/utility/color.png delete mode 100644 tests/ref/utility/data.png delete mode 100644 tests/ref/utility/eval.png delete mode 100644 tests/ref/utility/numbering.png delete mode 100644 tests/ref/utility/string.png create mode 100644 tests/typ/base/assert.typ create mode 100644 tests/typ/base/blind.typ create mode 100644 tests/typ/base/calc.typ create mode 100644 tests/typ/base/collection.typ create mode 100644 tests/typ/base/color.typ create mode 100644 tests/typ/base/data.typ create mode 100644 tests/typ/base/eval.typ create mode 100644 tests/typ/base/string.typ create mode 100644 tests/typ/base/type.typ create mode 100644 tests/typ/layout/math.typ delete mode 100644 tests/typ/math/basic.typ delete mode 100644 tests/typ/text/basic.typ create mode 100644 tests/typ/text/plain.typ delete mode 100644 tests/typ/utility/basics.typ delete mode 100644 tests/typ/utility/blind.typ delete mode 100644 tests/typ/utility/collection.typ delete mode 100644 tests/typ/utility/color.typ delete mode 100644 tests/typ/utility/data.typ delete mode 100644 tests/typ/utility/eval.typ delete mode 100644 tests/typ/utility/math.typ delete mode 100644 tests/typ/utility/string.typ (limited to 'tests') diff --git a/tests/ref/base/blind.png b/tests/ref/base/blind.png new file mode 100644 index 00000000..e972567e Binary files /dev/null and b/tests/ref/base/blind.png differ diff --git a/tests/ref/base/collection.png b/tests/ref/base/collection.png new file mode 100644 index 00000000..e93e2beb Binary files /dev/null and b/tests/ref/base/collection.png differ diff --git a/tests/ref/base/color.png b/tests/ref/base/color.png new file mode 100644 index 00000000..496013bb Binary files /dev/null and b/tests/ref/base/color.png differ diff --git a/tests/ref/base/data.png b/tests/ref/base/data.png new file mode 100644 index 00000000..69e0ae38 Binary files /dev/null and b/tests/ref/base/data.png differ diff --git a/tests/ref/base/eval.png b/tests/ref/base/eval.png new file mode 100644 index 00000000..38c1d64e Binary files /dev/null and b/tests/ref/base/eval.png differ diff --git a/tests/ref/base/numbering.png b/tests/ref/base/numbering.png new file mode 100644 index 00000000..d4d575d9 Binary files /dev/null and b/tests/ref/base/numbering.png differ diff --git a/tests/ref/base/string.png b/tests/ref/base/string.png new file mode 100644 index 00000000..02184316 Binary files /dev/null and b/tests/ref/base/string.png differ diff --git a/tests/ref/layout/math.png b/tests/ref/layout/math.png new file mode 100644 index 00000000..902354df Binary files /dev/null and b/tests/ref/layout/math.png differ diff --git a/tests/ref/math/basic.png b/tests/ref/math/basic.png deleted file mode 100644 index 902354df..00000000 Binary files a/tests/ref/math/basic.png and /dev/null differ diff --git a/tests/ref/text/basic.png b/tests/ref/text/basic.png deleted file mode 100644 index bfdf47a2..00000000 Binary files a/tests/ref/text/basic.png and /dev/null differ diff --git a/tests/ref/text/plain.png b/tests/ref/text/plain.png new file mode 100644 index 00000000..bfdf47a2 Binary files /dev/null and b/tests/ref/text/plain.png differ diff --git a/tests/ref/utility/blind.png b/tests/ref/utility/blind.png deleted file mode 100644 index e972567e..00000000 Binary files a/tests/ref/utility/blind.png and /dev/null differ diff --git a/tests/ref/utility/collection.png b/tests/ref/utility/collection.png deleted file mode 100644 index e93e2beb..00000000 Binary files a/tests/ref/utility/collection.png and /dev/null differ diff --git a/tests/ref/utility/color.png b/tests/ref/utility/color.png deleted file mode 100644 index 496013bb..00000000 Binary files a/tests/ref/utility/color.png and /dev/null differ diff --git a/tests/ref/utility/data.png b/tests/ref/utility/data.png deleted file mode 100644 index 69e0ae38..00000000 Binary files a/tests/ref/utility/data.png and /dev/null differ diff --git a/tests/ref/utility/eval.png b/tests/ref/utility/eval.png deleted file mode 100644 index 38c1d64e..00000000 Binary files a/tests/ref/utility/eval.png and /dev/null differ diff --git a/tests/ref/utility/numbering.png b/tests/ref/utility/numbering.png deleted file mode 100644 index d4d575d9..00000000 Binary files a/tests/ref/utility/numbering.png and /dev/null differ diff --git a/tests/ref/utility/string.png b/tests/ref/utility/string.png deleted file mode 100644 index 02184316..00000000 Binary files a/tests/ref/utility/string.png and /dev/null differ diff --git a/tests/src/benches.rs b/tests/src/benches.rs index 3af2db6e..e3c276bc 100644 --- a/tests/src/benches.rs +++ b/tests/src/benches.rs @@ -2,13 +2,12 @@ use std::path::{Path, PathBuf}; use comemo::{Prehashed, Track, Tracked}; use iai::{black_box, main, Iai}; -use unscanny::Scanner; - use typst::diag::{FileError, FileResult}; use typst::font::{Font, FontBook}; use typst::syntax::{Source, SourceId, TokenMode, Tokens}; use typst::util::Buffer; use typst::{Config, World}; +use unscanny::Scanner; const TEXT: &str = include_str!("../typ/benches/bench.typ"); const FONT: &[u8] = include_bytes!("../../fonts/IBMPlexSans-Regular.ttf"); diff --git a/tests/src/tests.rs b/tests/src/tests.rs index 620c1e7b..54afd034 100644 --- a/tests/src/tests.rs +++ b/tests/src/tests.rs @@ -11,9 +11,6 @@ use comemo::Prehashed; use elsa::FrozenVec; use once_cell::unsync::OnceCell; use tiny_skia as sk; -use unscanny::Scanner; -use walkdir::WalkDir; - use typst::diag::{bail, FileError, FileResult}; use typst::font::{Font, FontBook}; use typst::frame::{Element, Frame}; @@ -24,6 +21,8 @@ use typst::util::{Buffer, PathExt}; use typst::{Config, World}; use typst_library::layout::PageNode; use typst_library::text::{TextNode, TextSize}; +use unscanny::Scanner; +use walkdir::WalkDir; const TYP_DIR: &str = "typ"; const REF_DIR: &str = "ref"; diff --git a/tests/typ/base/assert.typ b/tests/typ/base/assert.typ new file mode 100644 index 00000000..b0c8aafd --- /dev/null +++ b/tests/typ/base/assert.typ @@ -0,0 +1,23 @@ +// Test the `assert` function. +// Ref: false + +--- +#assert(1 + 1 == 2) +#assert(range(2, 5) == (2, 3, 4)) +#assert(not false) + +--- +// Test failing assertions. +// Error: 9-15 assertion failed +#assert(1 == 2) + +--- +// Test failing assertions. +// Error: 9-15 expected boolean, found string +#assert("true") + +--- +// Test the `type` function. +#test(type(1), "integer") +#test(type(ltr), "direction") +#test(type(10 / 3), "float") diff --git a/tests/typ/base/blind.typ b/tests/typ/base/blind.typ new file mode 100644 index 00000000..17452dec --- /dev/null +++ b/tests/typ/base/blind.typ @@ -0,0 +1,32 @@ +// Test blind text. + +--- +// Test basic call. +#lorem(19) + +--- +// Test custom paragraphs with user code. +#set text(8pt) + +{ + let sentences = lorem(59) + .split(".") + .filter(s => s != "") + .map(s => s + ".") + + let used = 0 + for s in sentences { + if used < 2 { + used += 1 + } else { + parbreak() + used = 0 + } + s.trim() + [ ] + } +} + +--- +// Error: 7-9 missing argument: number of words +#lorem() diff --git a/tests/typ/base/calc.typ b/tests/typ/base/calc.typ new file mode 100644 index 00000000..4ccefa22 --- /dev/null +++ b/tests/typ/base/calc.typ @@ -0,0 +1,117 @@ +// Test math functions. +// Ref: false + +--- +// Test conversion to numbers. +#test(int(false), 0) +#test(int(true), 1) +#test(int(10), 10) +#test(int("150"), 150) +#test(int(10 / 3), 3) +#test(float(10), 10.0) +#test(float("31.4e-1"), 3.14) +#test(type(float(10)), "float") + +--- +// Error: 6-10 cannot convert length to integer +#int(10pt) + +--- +// Error: 8-13 cannot convert function to float +#float(float) + +--- +// Error: 6-12 invalid integer +#int("nope") + +--- +// Error: 8-15 invalid float +#float("1.2.3") + +--- +// Test the `abs` function. +#test(abs(-3), 3) +#test(abs(3), 3) +#test(abs(-0.0), 0.0) +#test(abs(0.0), -0.0) +#test(abs(-3.14), 3.14) +#test(abs(50%), 50%) +#test(abs(-25%), 25%) + +--- +// Error: 6-17 expected numeric value, found string +#abs("no number") + +--- +// Error: 6-11 cannot take absolute value of a length +#abs(-12pt) + +--- +// Error: 6-16 cannot take absolute value of a length +#abs(50% - 12pt) + +--- +// Test the `even` and `odd` functions. +#test(even(2), true) +#test(odd(2), false) +#test(odd(-1), true) +#test(even(-11), false) + +--- +// Test the `mod` function. +#test(mod(1, 1), 0) +#test(mod(5, 3), 2) +#test(mod(5, -3), 2) +#test(mod(22.5, 10), 2.5) +#test(mod(9, 4.5), 0) + +--- +// Error: 9-10 divisor must not be zero +#mod(5, 0) + +--- +// Error: 11-14 divisor must not be zero +#mod(3.0, 0.0) + +--- +// Test the `min` and `max` functions. +#test(min(2, -4), -4) +#test(min(3.5, 1e2, -0.1, 3), -0.1) +#test(max(-3, 11), 11) +#test(min("hi"), "hi") + +--- +// Error: 5-7 missing argument: value +#min() + +--- +// Error: 9-13 cannot compare integer and string +#min(1, "hi") + +--- +// Test the `range` function. +#test(range(4), (0, 1, 2, 3)) +#test(range(1, 4), (1, 2, 3)) +#test(range(-4, 2), (-4, -3, -2, -1, 0, 1)) +#test(range(10, 5), ()) +#test(range(10, step: 3), (0, 3, 6, 9)) +#test(range(1, 4, step: 1), (1, 2, 3)) +#test(range(1, 8, step: 2), (1, 3, 5, 7)) +#test(range(5, 2, step: -1), (5, 4, 3)) +#test(range(10, 0, step: -3), (10, 7, 4, 1)) + +--- +// Error: 7-9 missing argument: end +#range() + +--- +// Error: 11-14 expected integer, found float +#range(1, 2.0) + +--- +// Error: 17-22 expected integer, found string +#range(4, step: "one") + +--- +// Error: 18-19 step must not be zero +#range(10, step: 0) diff --git a/tests/typ/base/collection.typ b/tests/typ/base/collection.typ new file mode 100644 index 00000000..46ff97ab --- /dev/null +++ b/tests/typ/base/collection.typ @@ -0,0 +1,115 @@ +// Test collection functions. +// Ref: false + +--- +// Test the `len` method. +#test(().len(), 0) +#test(("A", "B", "C").len(), 3) +#test("Hello World!".len(), 12) +#test((a: 1, b: 2).len(), 2) + +--- +// The the `first` and `last` methods. +#test(().first(), none) +#test(().last(), none) +#test((1,).first(), 1) +#test((2,).last(), 2) +#test((1, 2, 3).first(), 1) +#test((1, 2, 3).last(), 3) + +--- +// Test the `push` and `pop` methods. +{ + let tasks = (a: (1, 2, 3), b: (4, 5, 6)) + tasks("a").pop() + tasks("b").push(7) + test(tasks("a"), (1, 2)) + test(tasks("b"), (4, 5, 6, 7)) +} + +--- +// Test the `insert` and `remove` methods. +{ + let array = (0, 1, 2, 4, 5) + array.insert(3, 3) + test(array, range(6)) + array.remove(1) + test(array, (0, 2, 3, 4, 5)) +} + +--- +// Error: 2:17-2:19 missing argument: index +#let numbers = () +{ numbers.insert() } + +--- +// Test the `slice` method. +#test((1, 2, 3, 4).slice(2), (3, 4)) +#test(range(10).slice(2, 6), (2, 3, 4, 5)) +#test(range(10).slice(4, count: 3), (4, 5, 6)) +#test(range(10).slice(-5, count: 2), (5, 6)) +#test((1, 2, 3).slice(2, -2), ()) +#test((1, 2, 3).slice(-2, 2), (2,)) +#test((1, 2, 3).slice(-3, 2), (1, 2)) +#test("ABCD".split("").slice(1, -1).join("-"), "A-B-C-D") + +--- +// Error: 3-31 array index out of bounds (index: 12, len: 10) +{ range(10).slice(9, count: 3) } + +--- +// Error: 3-25 array index out of bounds (index: -4, len: 3) +{ (1, 2, 3).slice(0, -4) } + +--- +// Test the `position` method. +#test(("Hi", "❤️", "Love").position(s => s == "❤️"), 1) +#test(("Bye", "💘", "Apart").position(s => s == "❤️"), none) +#test(("A", "B", "CDEF", "G").position(v => v.len() > 2), 2) + +--- +// Test the `rev` method. +#test(range(3).rev(), (2, 1, 0)) + +--- +// Test the `join` method. +#test(().join(), none) +#test((1,).join(), 1) +#test(("a", "b", "c").join(), "abc") +#test("(" + ("a", "b", "c").join(", ") + ")", "(a, b, c)") + +--- +// Error: 2-22 cannot join boolean with boolean +{(true, false).join()} + +--- +// Error: 2-20 cannot join string with integer +{("a", "b").join(1)} + +--- +// Test joining content. +// Ref: true +{([One], [Two], [Three]).join([, ], last: [ and ])}. + +--- +// Test the `sorted` method. +#test(().sorted(), ()) +#test(((true, false) * 10).sorted(), (false,) * 10 + (true,) * 10) +#test(("it", "the", "hi", "text").sorted(), ("hi", "it", "text", "the")) +#test((2, 1, 3, 10, 5, 8, 6, -7, 2).sorted(), (-7, 1, 2, 2, 3, 5, 6, 8, 10)) + +--- +// Error: 2-26 cannot order content and content +{([Hi], [There]).sorted()} + +--- +// Test dictionary methods. +#let dict = (a: 3, c: 2, b: 1) +#test("c" in dict, true) +#test(dict.len(), 3) +#test(dict.values(), (3, 1, 2)) +#test(dict.pairs((k, v) => k + str(v)).join(), "a3b1c2") + +{ dict.remove("c") } +#test("c" in dict, false) +#test(dict, (a: 3, b: 1)) diff --git a/tests/typ/base/color.typ b/tests/typ/base/color.typ new file mode 100644 index 00000000..96d76063 --- /dev/null +++ b/tests/typ/base/color.typ @@ -0,0 +1,63 @@ +// Test color creation functions. +// Ref: false + +--- +// Compare both ways. +#test(rgb(0%, 30%, 70%), rgb("004db3")) + +// Alpha channel. +#test(rgb(255, 0, 0, 50%), rgb("ff000080")) + +// Test color modification methods. +#test(rgb(25, 35, 45).lighten(10%), rgb(48, 57, 66)) +#test(rgb(40, 30, 20).darken(10%), rgb(36, 27, 18)) +#test(rgb("#133337").negate(), rgb(236, 204, 200)) +#test(white.lighten(100%), white) + +--- +// Test gray color conversion. +// Ref: true +#rect(fill: luma(0)) +#rect(fill: luma(80%)) + +--- +// Test gray color modification. +#test(luma(20%).lighten(50%), luma(60%)) +#test(luma(80%).darken(20%), luma(63.9%)) +#test(luma(80%).negate(), luma(20%)) + +--- +// Test CMYK color conversion. +// Ref: true +#let c = cmyk(50%, 64%, 16%, 17%) +#rect(width: 1cm, fill: cmyk(69%, 11%, 69%, 41%)) +#rect(width: 1cm, fill: c) +#rect(width: 1cm, fill: c.negate()) + +#for x in range(0, 11) { + square(width: 9pt, fill: c.lighten(x * 10%)) +} +#for x in range(0, 11) { + square(width: 9pt, fill: c.darken(x * 10%)) +} + +--- +// Error for values that are out of range. +// Error: 11-14 must be between 0 and 255 +#test(rgb(-30, 15, 50)) + +--- +// Error: 6-11 string contains non-hexadecimal letters +#rgb("lol") + +--- +// Error: 5-7 missing argument: red component +#rgb() + +--- +// Error: 5-11 missing argument: blue component +#rgb(0, 1) + +--- +// Error: 21-26 expected integer or ratio, found boolean +#rgb(10%, 20%, 30%, false) diff --git a/tests/typ/base/data.typ b/tests/typ/base/data.typ new file mode 100644 index 00000000..96b12ff5 --- /dev/null +++ b/tests/typ/base/data.typ @@ -0,0 +1,58 @@ +// Test reading structured data. +// Ref: false + +--- +// Test reading CSV data. +// Ref: true +#set page(width: auto) +#let data = csv("/res/zoo.csv") +#let cells = data(0).map(strong) + data.slice(1).flatten() +#table(columns: data(0).len(), ..cells) + +--- +// Error: 6-16 file not found (searched at typ/base/nope.csv) +#csv("nope.csv") + +--- +// Error: 6-20 failed to parse csv file: found 3 instead of 2 fields in line 3 +#csv("/res/bad.csv") + +--- +// Test reading JSON data. +#let data = json("/res/zoo.json") +#test(data.len(), 3) +#test(data(0).name, "Debby") +#test(data(2).weight, 150) + +--- +// Error: 7-22 failed to parse json file: syntax error in line 3 +#json("/res/bad.json") + +--- +// Test reading XML data. +#let data = xml("/res/data.xml") +#test(data, (( + tag: "data", + attrs: (:), + children: ( + "\n ", + (tag: "hello", attrs: (name: "hi"), children: ("1",)), + "\n ", + ( + tag: "data", + attrs: (:), + children: ( + "\n ", + (tag: "hello", attrs: (:), children: ("World",)), + "\n ", + (tag: "hello", attrs: (:), children: ("World",)), + "\n ", + ), + ), + "\n", + ), +),)) + +--- +// Error: 6-20 failed to parse xml file: found closing tag 'data' instead of 'hello' in line 3 +#xml("/res/bad.xml") diff --git a/tests/typ/base/eval.typ b/tests/typ/base/eval.typ new file mode 100644 index 00000000..86b1f0c4 --- /dev/null +++ b/tests/typ/base/eval.typ @@ -0,0 +1,52 @@ +// Test the `eval` function. + +--- +#eval("_Hello" + " World!_") + +--- +// Error: 7-13 expected identifier +#eval("#let") + +--- +#set raw(around: none) +#show it: raw as text("IBM Plex Sans", eval(it.text)) + +Interacting +``` +#set text(blue) +Blue #move(dy: -0.15em)[🌊] +``` + +--- +// Error: 7-19 cannot continue outside of loop +#eval("{continue}") + +--- +// Error: 7-33 cannot access file system from here +#eval("#include \"../coma.typ\"") + +--- +// Error: 7-35 cannot access file system from here +#eval("#image(\"/res/tiger.jpg\")") + +--- +// Error: 23-30 cannot access file system from here +#show it: raw as eval(it.text) + +``` +#show strong as image("/res/tiger.jpg") +*No absolute tiger!* +``` + +--- +// Error: 23-30 cannot access file system from here +#show it: raw as eval(it.text) + +``` +#show emph as image("../../res/giraffe.jpg") +_No relative giraffe!_ +``` + +--- +// Error: 7-16 expected comma +#eval("{(1 2)}") diff --git a/tests/typ/base/string.typ b/tests/typ/base/string.typ new file mode 100644 index 00000000..3104a3ea --- /dev/null +++ b/tests/typ/base/string.typ @@ -0,0 +1,161 @@ +// Test string related methods. +// Ref: false + +--- +// Test conversion to string. +#test(str(123), "123") +#test(str(50.14), "50.14") +#test(str(10 / 3).len() > 10, true) +#test(repr(ltr), "ltr") +#test(repr((1, 2, false, )), "(1, 2, false)") + +--- +// Error: 6-8 cannot convert content to string +#str([]) + +--- +// Test the `slice` method. +#test("abc".slice(1, 2), "b") +#test("abc🏡def".slice(2, 7), "c🏡") +#test("abc🏡def".slice(2, -2), "c🏡d") +#test("abc🏡def".slice(-3, -1), "de") + +--- +// Test the `contains` method. +#test("abc".contains("b"), true) +#test("b" in "abc", true) +#test("1234f".contains(regex("\d")), true) +#test(regex("\d") in "1234f", true) +#test("abc".contains("d"), false) +#test("1234g" in "1234f", false) +#test("abc".contains(regex("^[abc]$")), false) +#test("abc".contains(regex("^[abc]+$")), true) + +--- +// Test the `starts-with` and `ends-with` methods. +#test("Typst".starts-with("Ty"), true) +#test("Typst".starts-with(regex("[Tt]ys")), false) +#test("Typst".starts-with("st"), false) +#test("Typst".ends-with("st"), true) +#test("Typst".ends-with(regex("\d*")), true) +#test("Typst".ends-with(regex("\d+")), false) +#test("Typ12".ends-with(regex("\d+")), true) + +--- +// Test the `find` and `position` methods. +#let date = regex("\d{2}:\d{2}") +#test("Hello World".find("World"), "World") +#test("Hello World".position("World"), 6) +#test("It's 12:13 now".find(date), "12:13") +#test("It's 12:13 now".position(date), 5) + +--- +// Test the `match` method. +#test("Is there a".match("for this?"), none) +#test( + "The time of my life.".match(regex("[mit]+e")), + (start: 4, end: 8, text: "time", captures: ()), +) + +// Test the `matches` method. +#test("Hello there".matches("\d"), ()) +#test("Day by Day.".matches("Day"), ( + (start: 0, end: 3, text: "Day", captures: ()), + (start: 7, end: 10, text: "Day", captures: ()), +)) + +// Compute the sum of all timestamps in the text. +#let timesum(text) = { + let time = 0 + for match in text.matches(regex("(\d+):(\d+)")) { + let caps = match.captures + time += 60 * int(caps(0)) + int(caps(1)) + } + str(int(time / 60)) + ":" + str(mod(time, 60)) +} + +#test(timesum(""), "0:0") +#test(timesum("2:70"), "3:10") +#test(timesum("1:20, 2:10, 0:40"), "4:10") + +--- +// Test the `replace` method. +#test("ABC".replace("", "-"), "-A-B-C-") +#test("Ok".replace("Ok", "Nope", count: 0), "Ok") +#test("to add?".replace("", "How ", count: 1), "How to add?") +#test("AB C DEF GH J".replace(" ", ",", count: 2), "AB,C,DEF GH J") +#test("Walcemo" + .replace("o", "k") + .replace("e", "o") + .replace("k", "e") + .replace("a", "e"), + "Welcome" +) +#test("123".replace(regex("\d$"), "_"), "12_") +#test("123".replace(regex("\d{1,2}$"), "__"), "1__") + +--- +// Test the `trim` method. +#let str = "Typst, LaTeX, Word, InDesign" +#let array = ("Typst", "LaTeX", "Word", "InDesign") +#test(str.split(",").map(s => s.trim()), array) +#test("".trim(), "") +#test(" abc ".trim(at: start), "abc ") +#test(" abc ".trim(at: end, repeat: true), " abc") +#test(" abc".trim(at: start, repeat: false), "abc") +#test("aabcaa".trim("a", repeat: false), "abca") +#test("aabca".trim("a", at: start), "bca") +#test("aabcaa".trim("a", at: end, repeat: false), "aabca") +#test("".trim(regex(".")), "") +#test("123abc456".trim(regex("\d")), "abc") +#test("123abc456".trim(regex("\d"), repeat: false), "23abc45") +#test("123a4b5c678".trim(regex("\d"), repeat: true), "a4b5c") +#test("123a4b5c678".trim(regex("\d"), repeat: false), "23a4b5c67") +#test("123abc456".trim(regex("\d"), at: start), "abc456") +#test("123abc456".trim(regex("\d"), at: end), "123abc") +#test("123abc456".trim(regex("\d+"), at: end, repeat: false), "123abc") +#test("123abc456".trim(regex("\d{1,2}$"), repeat: false), "123abc4") +#test("hello world".trim(regex(".")), "") + +--- +// Error: 17-21 expected either `start` or `end` +{"abc".trim(at: left)} + +--- +// Test the `split` method. +#test("abc".split(""), ("", "a", "b", "c", "")) +#test("abc".split("b"), ("a", "c")) +#test("a123c".split(regex("\d")), ("a", "", "", "c")) +#test("a123c".split(regex("\d+")), ("a", "c")) + +--- +// Test the `upper` and `lower` functions. +#let memes = "ArE mEmEs gReAt?"; +#test(lower(memes), "are memes great?") +#test(upper(memes), "ARE MEMES GREAT?") +#test(upper("Ελλάδα"), "ΕΛΛΆΔΑ") + +--- +// Test integrated lower, upper and symbols. +// Ref: true + +#upper("Abc 8") +#upper[def] + +#lower("SCREAMING MUST BE SILENCED in " + roman(1672) + " years") + +#for i in range(9) { + symbol(i) + [ and ] + roman(i) + [ for #i] + parbreak() +} + +--- +// Error: 8-9 expected string or content, found integer +#upper(1) + +--- +// Error: 9-11 must be at least zero +#symbol(-1) diff --git a/tests/typ/base/type.typ b/tests/typ/base/type.typ new file mode 100644 index 00000000..37cf8623 --- /dev/null +++ b/tests/typ/base/type.typ @@ -0,0 +1,7 @@ +// Test the `type` function. +// Ref: false + +--- +#test(type(1), "integer") +#test(type(ltr), "direction") +#test(type(10 / 3), "float") diff --git a/tests/typ/layout/math.typ b/tests/typ/layout/math.typ new file mode 100644 index 00000000..55a853cf --- /dev/null +++ b/tests/typ/layout/math.typ @@ -0,0 +1,20 @@ +// Test math formulas. + +--- +The sum of $a$ and $b$ is $a + b$. + +--- +We will show that: +$ a^2 + b^2 = c^2 $ + +--- +Prove by induction: +$ sum_(k=0)^n k = (n(n+1))/2 $ + +--- +// Test that blackboard style looks nice. +$ f: NN arrow RR $ + +--- +// Error: 1:3 expected dollar sign +$a diff --git a/tests/typ/math/basic.typ b/tests/typ/math/basic.typ deleted file mode 100644 index 55a853cf..00000000 --- a/tests/typ/math/basic.typ +++ /dev/null @@ -1,20 +0,0 @@ -// Test math formulas. - ---- -The sum of $a$ and $b$ is $a + b$. - ---- -We will show that: -$ a^2 + b^2 = c^2 $ - ---- -Prove by induction: -$ sum_(k=0)^n k = (n(n+1))/2 $ - ---- -// Test that blackboard style looks nice. -$ f: NN arrow RR $ - ---- -// Error: 1:3 expected dollar sign -$a diff --git a/tests/typ/text/basic.typ b/tests/typ/text/basic.typ deleted file mode 100644 index a074a046..00000000 --- a/tests/typ/text/basic.typ +++ /dev/null @@ -1,20 +0,0 @@ -// Test simple text. - ---- -#set page(width: 250pt, height: 120pt) - -But, soft! what light through yonder window breaks? It is the east, and Juliet -is the sun. Arise, fair sun, and kill the envious moon, Who is already sick and -pale with grief, That thou her maid art far more fair than she: Be not her maid, -since she is envious; Her vestal livery is but sick and green And none but fools -do wear it; cast it off. It is my lady, O, it is my love! O, that she knew she -were! She speaks yet she says nothing: what of that? Her eye discourses; I will -answer it. - -I am too bold, 'tis not to me she speaks: Two of the fairest stars in all the -heaven, Having some business, do entreat her eyes To twinkle in their spheres -till they return. What if her eyes were there, they in her head? The brightness -of her cheek would shame those stars, As daylight doth a lamp; her eyes in -heaven Would through the airy region stream so bright That birds would sing and -think it were not night. See, how she leans her cheek upon her hand! O, that I -were a glove upon that hand, That I might touch that cheek! diff --git a/tests/typ/text/plain.typ b/tests/typ/text/plain.typ new file mode 100644 index 00000000..34a2d626 --- /dev/null +++ b/tests/typ/text/plain.typ @@ -0,0 +1,20 @@ +// Test plain text. + +--- +#set page(width: 250pt, height: 120pt) + +But, soft! what light through yonder window breaks? It is the east, and Juliet +is the sun. Arise, fair sun, and kill the envious moon, Who is already sick and +pale with grief, That thou her maid art far more fair than she: Be not her maid, +since she is envious; Her vestal livery is but sick and green And none but fools +do wear it; cast it off. It is my lady, O, it is my love! O, that she knew she +were! She speaks yet she says nothing: what of that? Her eye discourses; I will +answer it. + +I am too bold, 'tis not to me she speaks: Two of the fairest stars in all the +heaven, Having some business, do entreat her eyes To twinkle in their spheres +till they return. What if her eyes were there, they in her head? The brightness +of her cheek would shame those stars, As daylight doth a lamp; her eyes in +heaven Would through the airy region stream so bright That birds would sing and +think it were not night. See, how she leans her cheek upon her hand! O, that I +were a glove upon that hand, That I might touch that cheek! diff --git a/tests/typ/utility/basics.typ b/tests/typ/utility/basics.typ deleted file mode 100644 index 83d192c4..00000000 --- a/tests/typ/utility/basics.typ +++ /dev/null @@ -1,24 +0,0 @@ -// Test basic functions. -// Ref: false - ---- -// Test the `assert` function. -#assert(1 + 1 == 2) -#assert(range(2, 5) == (2, 3, 4)) -#assert(not false) - ---- -// Test failing assertions. -// Error: 9-15 assertion failed -#assert(1 == 2) - ---- -// Test failing assertions. -// Error: 9-15 expected boolean, found string -#assert("true") - ---- -// Test the `type` function. -#test(type(1), "integer") -#test(type(ltr), "direction") -#test(type(10 / 3), "float") diff --git a/tests/typ/utility/blind.typ b/tests/typ/utility/blind.typ deleted file mode 100644 index 17452dec..00000000 --- a/tests/typ/utility/blind.typ +++ /dev/null @@ -1,32 +0,0 @@ -// Test blind text. - ---- -// Test basic call. -#lorem(19) - ---- -// Test custom paragraphs with user code. -#set text(8pt) - -{ - let sentences = lorem(59) - .split(".") - .filter(s => s != "") - .map(s => s + ".") - - let used = 0 - for s in sentences { - if used < 2 { - used += 1 - } else { - parbreak() - used = 0 - } - s.trim() - [ ] - } -} - ---- -// Error: 7-9 missing argument: number of words -#lorem() diff --git a/tests/typ/utility/collection.typ b/tests/typ/utility/collection.typ deleted file mode 100644 index 46ff97ab..00000000 --- a/tests/typ/utility/collection.typ +++ /dev/null @@ -1,115 +0,0 @@ -// Test collection functions. -// Ref: false - ---- -// Test the `len` method. -#test(().len(), 0) -#test(("A", "B", "C").len(), 3) -#test("Hello World!".len(), 12) -#test((a: 1, b: 2).len(), 2) - ---- -// The the `first` and `last` methods. -#test(().first(), none) -#test(().last(), none) -#test((1,).first(), 1) -#test((2,).last(), 2) -#test((1, 2, 3).first(), 1) -#test((1, 2, 3).last(), 3) - ---- -// Test the `push` and `pop` methods. -{ - let tasks = (a: (1, 2, 3), b: (4, 5, 6)) - tasks("a").pop() - tasks("b").push(7) - test(tasks("a"), (1, 2)) - test(tasks("b"), (4, 5, 6, 7)) -} - ---- -// Test the `insert` and `remove` methods. -{ - let array = (0, 1, 2, 4, 5) - array.insert(3, 3) - test(array, range(6)) - array.remove(1) - test(array, (0, 2, 3, 4, 5)) -} - ---- -// Error: 2:17-2:19 missing argument: index -#let numbers = () -{ numbers.insert() } - ---- -// Test the `slice` method. -#test((1, 2, 3, 4).slice(2), (3, 4)) -#test(range(10).slice(2, 6), (2, 3, 4, 5)) -#test(range(10).slice(4, count: 3), (4, 5, 6)) -#test(range(10).slice(-5, count: 2), (5, 6)) -#test((1, 2, 3).slice(2, -2), ()) -#test((1, 2, 3).slice(-2, 2), (2,)) -#test((1, 2, 3).slice(-3, 2), (1, 2)) -#test("ABCD".split("").slice(1, -1).join("-"), "A-B-C-D") - ---- -// Error: 3-31 array index out of bounds (index: 12, len: 10) -{ range(10).slice(9, count: 3) } - ---- -// Error: 3-25 array index out of bounds (index: -4, len: 3) -{ (1, 2, 3).slice(0, -4) } - ---- -// Test the `position` method. -#test(("Hi", "❤️", "Love").position(s => s == "❤️"), 1) -#test(("Bye", "💘", "Apart").position(s => s == "❤️"), none) -#test(("A", "B", "CDEF", "G").position(v => v.len() > 2), 2) - ---- -// Test the `rev` method. -#test(range(3).rev(), (2, 1, 0)) - ---- -// Test the `join` method. -#test(().join(), none) -#test((1,).join(), 1) -#test(("a", "b", "c").join(), "abc") -#test("(" + ("a", "b", "c").join(", ") + ")", "(a, b, c)") - ---- -// Error: 2-22 cannot join boolean with boolean -{(true, false).join()} - ---- -// Error: 2-20 cannot join string with integer -{("a", "b").join(1)} - ---- -// Test joining content. -// Ref: true -{([One], [Two], [Three]).join([, ], last: [ and ])}. - ---- -// Test the `sorted` method. -#test(().sorted(), ()) -#test(((true, false) * 10).sorted(), (false,) * 10 + (true,) * 10) -#test(("it", "the", "hi", "text").sorted(), ("hi", "it", "text", "the")) -#test((2, 1, 3, 10, 5, 8, 6, -7, 2).sorted(), (-7, 1, 2, 2, 3, 5, 6, 8, 10)) - ---- -// Error: 2-26 cannot order content and content -{([Hi], [There]).sorted()} - ---- -// Test dictionary methods. -#let dict = (a: 3, c: 2, b: 1) -#test("c" in dict, true) -#test(dict.len(), 3) -#test(dict.values(), (3, 1, 2)) -#test(dict.pairs((k, v) => k + str(v)).join(), "a3b1c2") - -{ dict.remove("c") } -#test("c" in dict, false) -#test(dict, (a: 3, b: 1)) diff --git a/tests/typ/utility/color.typ b/tests/typ/utility/color.typ deleted file mode 100644 index 96d76063..00000000 --- a/tests/typ/utility/color.typ +++ /dev/null @@ -1,63 +0,0 @@ -// Test color creation functions. -// Ref: false - ---- -// Compare both ways. -#test(rgb(0%, 30%, 70%), rgb("004db3")) - -// Alpha channel. -#test(rgb(255, 0, 0, 50%), rgb("ff000080")) - -// Test color modification methods. -#test(rgb(25, 35, 45).lighten(10%), rgb(48, 57, 66)) -#test(rgb(40, 30, 20).darken(10%), rgb(36, 27, 18)) -#test(rgb("#133337").negate(), rgb(236, 204, 200)) -#test(white.lighten(100%), white) - ---- -// Test gray color conversion. -// Ref: true -#rect(fill: luma(0)) -#rect(fill: luma(80%)) - ---- -// Test gray color modification. -#test(luma(20%).lighten(50%), luma(60%)) -#test(luma(80%).darken(20%), luma(63.9%)) -#test(luma(80%).negate(), luma(20%)) - ---- -// Test CMYK color conversion. -// Ref: true -#let c = cmyk(50%, 64%, 16%, 17%) -#rect(width: 1cm, fill: cmyk(69%, 11%, 69%, 41%)) -#rect(width: 1cm, fill: c) -#rect(width: 1cm, fill: c.negate()) - -#for x in range(0, 11) { - square(width: 9pt, fill: c.lighten(x * 10%)) -} -#for x in range(0, 11) { - square(width: 9pt, fill: c.darken(x * 10%)) -} - ---- -// Error for values that are out of range. -// Error: 11-14 must be between 0 and 255 -#test(rgb(-30, 15, 50)) - ---- -// Error: 6-11 string contains non-hexadecimal letters -#rgb("lol") - ---- -// Error: 5-7 missing argument: red component -#rgb() - ---- -// Error: 5-11 missing argument: blue component -#rgb(0, 1) - ---- -// Error: 21-26 expected integer or ratio, found boolean -#rgb(10%, 20%, 30%, false) diff --git a/tests/typ/utility/data.typ b/tests/typ/utility/data.typ deleted file mode 100644 index e90c1b0d..00000000 --- a/tests/typ/utility/data.typ +++ /dev/null @@ -1,58 +0,0 @@ -// Test reading structured data. -// Ref: false - ---- -// Test reading CSV data. -// Ref: true -#set page(width: auto) -#let data = csv("/res/zoo.csv") -#let cells = data(0).map(strong) + data.slice(1).flatten() -#table(columns: data(0).len(), ..cells) - ---- -// Error: 6-16 file not found (searched at typ/utility/nope.csv) -#csv("nope.csv") - ---- -// Error: 6-20 failed to parse csv file: found 3 instead of 2 fields in line 3 -#csv("/res/bad.csv") - ---- -// Test reading JSON data. -#let data = json("/res/zoo.json") -#test(data.len(), 3) -#test(data(0).name, "Debby") -#test(data(2).weight, 150) - ---- -// Error: 7-22 failed to parse json file: syntax error in line 3 -#json("/res/bad.json") - ---- -// Test reading XML data. -#let data = xml("/res/data.xml") -#test(data, (( - tag: "data", - attrs: (:), - children: ( - "\n ", - (tag: "hello", attrs: (name: "hi"), children: ("1",)), - "\n ", - ( - tag: "data", - attrs: (:), - children: ( - "\n ", - (tag: "hello", attrs: (:), children: ("World",)), - "\n ", - (tag: "hello", attrs: (:), children: ("World",)), - "\n ", - ), - ), - "\n", - ), -),)) - ---- -// Error: 6-20 failed to parse xml file: found closing tag 'data' instead of 'hello' in line 3 -#xml("/res/bad.xml") diff --git a/tests/typ/utility/eval.typ b/tests/typ/utility/eval.typ deleted file mode 100644 index 86b1f0c4..00000000 --- a/tests/typ/utility/eval.typ +++ /dev/null @@ -1,52 +0,0 @@ -// Test the `eval` function. - ---- -#eval("_Hello" + " World!_") - ---- -// Error: 7-13 expected identifier -#eval("#let") - ---- -#set raw(around: none) -#show it: raw as text("IBM Plex Sans", eval(it.text)) - -Interacting -``` -#set text(blue) -Blue #move(dy: -0.15em)[🌊] -``` - ---- -// Error: 7-19 cannot continue outside of loop -#eval("{continue}") - ---- -// Error: 7-33 cannot access file system from here -#eval("#include \"../coma.typ\"") - ---- -// Error: 7-35 cannot access file system from here -#eval("#image(\"/res/tiger.jpg\")") - ---- -// Error: 23-30 cannot access file system from here -#show it: raw as eval(it.text) - -``` -#show strong as image("/res/tiger.jpg") -*No absolute tiger!* -``` - ---- -// Error: 23-30 cannot access file system from here -#show it: raw as eval(it.text) - -``` -#show emph as image("../../res/giraffe.jpg") -_No relative giraffe!_ -``` - ---- -// Error: 7-16 expected comma -#eval("{(1 2)}") diff --git a/tests/typ/utility/math.typ b/tests/typ/utility/math.typ deleted file mode 100644 index 4ccefa22..00000000 --- a/tests/typ/utility/math.typ +++ /dev/null @@ -1,117 +0,0 @@ -// Test math functions. -// Ref: false - ---- -// Test conversion to numbers. -#test(int(false), 0) -#test(int(true), 1) -#test(int(10), 10) -#test(int("150"), 150) -#test(int(10 / 3), 3) -#test(float(10), 10.0) -#test(float("31.4e-1"), 3.14) -#test(type(float(10)), "float") - ---- -// Error: 6-10 cannot convert length to integer -#int(10pt) - ---- -// Error: 8-13 cannot convert function to float -#float(float) - ---- -// Error: 6-12 invalid integer -#int("nope") - ---- -// Error: 8-15 invalid float -#float("1.2.3") - ---- -// Test the `abs` function. -#test(abs(-3), 3) -#test(abs(3), 3) -#test(abs(-0.0), 0.0) -#test(abs(0.0), -0.0) -#test(abs(-3.14), 3.14) -#test(abs(50%), 50%) -#test(abs(-25%), 25%) - ---- -// Error: 6-17 expected numeric value, found string -#abs("no number") - ---- -// Error: 6-11 cannot take absolute value of a length -#abs(-12pt) - ---- -// Error: 6-16 cannot take absolute value of a length -#abs(50% - 12pt) - ---- -// Test the `even` and `odd` functions. -#test(even(2), true) -#test(odd(2), false) -#test(odd(-1), true) -#test(even(-11), false) - ---- -// Test the `mod` function. -#test(mod(1, 1), 0) -#test(mod(5, 3), 2) -#test(mod(5, -3), 2) -#test(mod(22.5, 10), 2.5) -#test(mod(9, 4.5), 0) - ---- -// Error: 9-10 divisor must not be zero -#mod(5, 0) - ---- -// Error: 11-14 divisor must not be zero -#mod(3.0, 0.0) - ---- -// Test the `min` and `max` functions. -#test(min(2, -4), -4) -#test(min(3.5, 1e2, -0.1, 3), -0.1) -#test(max(-3, 11), 11) -#test(min("hi"), "hi") - ---- -// Error: 5-7 missing argument: value -#min() - ---- -// Error: 9-13 cannot compare integer and string -#min(1, "hi") - ---- -// Test the `range` function. -#test(range(4), (0, 1, 2, 3)) -#test(range(1, 4), (1, 2, 3)) -#test(range(-4, 2), (-4, -3, -2, -1, 0, 1)) -#test(range(10, 5), ()) -#test(range(10, step: 3), (0, 3, 6, 9)) -#test(range(1, 4, step: 1), (1, 2, 3)) -#test(range(1, 8, step: 2), (1, 3, 5, 7)) -#test(range(5, 2, step: -1), (5, 4, 3)) -#test(range(10, 0, step: -3), (10, 7, 4, 1)) - ---- -// Error: 7-9 missing argument: end -#range() - ---- -// Error: 11-14 expected integer, found float -#range(1, 2.0) - ---- -// Error: 17-22 expected integer, found string -#range(4, step: "one") - ---- -// Error: 18-19 step must not be zero -#range(10, step: 0) diff --git a/tests/typ/utility/string.typ b/tests/typ/utility/string.typ deleted file mode 100644 index 3104a3ea..00000000 --- a/tests/typ/utility/string.typ +++ /dev/null @@ -1,161 +0,0 @@ -// Test string related methods. -// Ref: false - ---- -// Test conversion to string. -#test(str(123), "123") -#test(str(50.14), "50.14") -#test(str(10 / 3).len() > 10, true) -#test(repr(ltr), "ltr") -#test(repr((1, 2, false, )), "(1, 2, false)") - ---- -// Error: 6-8 cannot convert content to string -#str([]) - ---- -// Test the `slice` method. -#test("abc".slice(1, 2), "b") -#test("abc🏡def".slice(2, 7), "c🏡") -#test("abc🏡def".slice(2, -2), "c🏡d") -#test("abc🏡def".slice(-3, -1), "de") - ---- -// Test the `contains` method. -#test("abc".contains("b"), true) -#test("b" in "abc", true) -#test("1234f".contains(regex("\d")), true) -#test(regex("\d") in "1234f", true) -#test("abc".contains("d"), false) -#test("1234g" in "1234f", false) -#test("abc".contains(regex("^[abc]$")), false) -#test("abc".contains(regex("^[abc]+$")), true) - ---- -// Test the `starts-with` and `ends-with` methods. -#test("Typst".starts-with("Ty"), true) -#test("Typst".starts-with(regex("[Tt]ys")), false) -#test("Typst".starts-with("st"), false) -#test("Typst".ends-with("st"), true) -#test("Typst".ends-with(regex("\d*")), true) -#test("Typst".ends-with(regex("\d+")), false) -#test("Typ12".ends-with(regex("\d+")), true) - ---- -// Test the `find` and `position` methods. -#let date = regex("\d{2}:\d{2}") -#test("Hello World".find("World"), "World") -#test("Hello World".position("World"), 6) -#test("It's 12:13 now".find(date), "12:13") -#test("It's 12:13 now".position(date), 5) - ---- -// Test the `match` method. -#test("Is there a".match("for this?"), none) -#test( - "The time of my life.".match(regex("[mit]+e")), - (start: 4, end: 8, text: "time", captures: ()), -) - -// Test the `matches` method. -#test("Hello there".matches("\d"), ()) -#test("Day by Day.".matches("Day"), ( - (start: 0, end: 3, text: "Day", captures: ()), - (start: 7, end: 10, text: "Day", captures: ()), -)) - -// Compute the sum of all timestamps in the text. -#let timesum(text) = { - let time = 0 - for match in text.matches(regex("(\d+):(\d+)")) { - let caps = match.captures - time += 60 * int(caps(0)) + int(caps(1)) - } - str(int(time / 60)) + ":" + str(mod(time, 60)) -} - -#test(timesum(""), "0:0") -#test(timesum("2:70"), "3:10") -#test(timesum("1:20, 2:10, 0:40"), "4:10") - ---- -// Test the `replace` method. -#test("ABC".replace("", "-"), "-A-B-C-") -#test("Ok".replace("Ok", "Nope", count: 0), "Ok") -#test("to add?".replace("", "How ", count: 1), "How to add?") -#test("AB C DEF GH J".replace(" ", ",", count: 2), "AB,C,DEF GH J") -#test("Walcemo" - .replace("o", "k") - .replace("e", "o") - .replace("k", "e") - .replace("a", "e"), - "Welcome" -) -#test("123".replace(regex("\d$"), "_"), "12_") -#test("123".replace(regex("\d{1,2}$"), "__"), "1__") - ---- -// Test the `trim` method. -#let str = "Typst, LaTeX, Word, InDesign" -#let array = ("Typst", "LaTeX", "Word", "InDesign") -#test(str.split(",").map(s => s.trim()), array) -#test("".trim(), "") -#test(" abc ".trim(at: start), "abc ") -#test(" abc ".trim(at: end, repeat: true), " abc") -#test(" abc".trim(at: start, repeat: false), "abc") -#test("aabcaa".trim("a", repeat: false), "abca") -#test("aabca".trim("a", at: start), "bca") -#test("aabcaa".trim("a", at: end, repeat: false), "aabca") -#test("".trim(regex(".")), "") -#test("123abc456".trim(regex("\d")), "abc") -#test("123abc456".trim(regex("\d"), repeat: false), "23abc45") -#test("123a4b5c678".trim(regex("\d"), repeat: true), "a4b5c") -#test("123a4b5c678".trim(regex("\d"), repeat: false), "23a4b5c67") -#test("123abc456".trim(regex("\d"), at: start), "abc456") -#test("123abc456".trim(regex("\d"), at: end), "123abc") -#test("123abc456".trim(regex("\d+"), at: end, repeat: false), "123abc") -#test("123abc456".trim(regex("\d{1,2}$"), repeat: false), "123abc4") -#test("hello world".trim(regex(".")), "") - ---- -// Error: 17-21 expected either `start` or `end` -{"abc".trim(at: left)} - ---- -// Test the `split` method. -#test("abc".split(""), ("", "a", "b", "c", "")) -#test("abc".split("b"), ("a", "c")) -#test("a123c".split(regex("\d")), ("a", "", "", "c")) -#test("a123c".split(regex("\d+")), ("a", "c")) - ---- -// Test the `upper` and `lower` functions. -#let memes = "ArE mEmEs gReAt?"; -#test(lower(memes), "are memes great?") -#test(upper(memes), "ARE MEMES GREAT?") -#test(upper("Ελλάδα"), "ΕΛΛΆΔΑ") - ---- -// Test integrated lower, upper and symbols. -// Ref: true - -#upper("Abc 8") -#upper[def] - -#lower("SCREAMING MUST BE SILENCED in " + roman(1672) + " years") - -#for i in range(9) { - symbol(i) - [ and ] - roman(i) - [ for #i] - parbreak() -} - ---- -// Error: 8-9 expected string or content, found integer -#upper(1) - ---- -// Error: 9-11 must be at least zero -#symbol(-1) -- cgit v1.2.3