diff options
| author | 2025-05-16 16:58:40 +0000 | |
|---|---|---|
| committer | 2025-05-16 16:58:40 +0000 | |
| commit | 0b05141b033043c5f7bcd72048a48eef6531ea6c (patch) | |
| tree | af6336ad8f5f7000cbaf92180469b65a2e940e32 /bench/src/tests.zig | |
| parent | Update README.md (diff) | |
| parent | Fix benchmarks (diff) | |
| download | zg-0b05141b033043c5f7bcd72048a48eef6531ea6c.tar.gz zg-0b05141b033043c5f7bcd72048a48eef6531ea6c.tar.xz zg-0b05141b033043c5f7bcd72048a48eef6531ea6c.zip | |
Merge pull request 'Fix benchmarks' (#56) from jacobsandlund/zg:benchmarks into v0.14-betav0.14v0.14-beta
Reviewed-on: https://codeberg.org/atman/zg/pulls/56
Reviewed-by: atman <atman@noreply.codeberg.org>
Diffstat (limited to 'bench/src/tests.zig')
| -rw-r--r-- | bench/src/tests.zig | 177 |
1 files changed, 85 insertions, 92 deletions
diff --git a/bench/src/tests.zig b/bench/src/tests.zig index a8a2a98..cf62709 100644 --- a/bench/src/tests.zig +++ b/bench/src/tests.zig | |||
| @@ -6,140 +6,133 @@ const expectEqualStrings = testing.expectEqualStrings; | |||
| 6 | 6 | ||
| 7 | const allocator = testing.allocator; | 7 | const allocator = testing.allocator; |
| 8 | 8 | ||
| 9 | const GenCatData = @import("GenCatData"); | 9 | const GeneralCategories = @import("GeneralCategories"); |
| 10 | 10 | ||
| 11 | test "General Category" { | 11 | test GeneralCategories { |
| 12 | const gcd = try GenCatData.init(allocator); | 12 | const gen_cat = try GeneralCategories.init(allocator); |
| 13 | defer gcd.deinit(); | 13 | defer gen_cat.deinit(allocator); |
| 14 | 14 | ||
| 15 | try expect(gcd.gc('A') == .Lu); // Lu: uppercase letter | 15 | try expect(gen_cat.gc('A') == .Lu); // Lu: uppercase letter |
| 16 | try expect(gcd.gc('3') == .Nd); // Nd: Decimal number | 16 | try expect(gen_cat.gc('3') == .Nd); // Nd: Decimal number |
| 17 | try expect(gcd.isControl(0)); | 17 | try expect(gen_cat.isControl(0)); |
| 18 | try expect(gcd.isLetter('z')); | 18 | try expect(gen_cat.isLetter('z')); |
| 19 | try expect(gcd.isMark('\u{301}')); | 19 | try expect(gen_cat.isMark('\u{301}')); |
| 20 | try expect(gcd.isNumber('3')); | 20 | try expect(gen_cat.isNumber('3')); |
| 21 | try expect(gcd.isPunctuation('[')); | 21 | try expect(gen_cat.isPunctuation('[')); |
| 22 | try expect(gcd.isSeparator(' ')); | 22 | try expect(gen_cat.isSeparator(' ')); |
| 23 | try expect(gcd.isSymbol('©')); | 23 | try expect(gen_cat.isSymbol('©')); |
| 24 | } | 24 | } |
| 25 | 25 | ||
| 26 | const PropsData = @import("PropsData"); | 26 | const Properties = @import("Properties"); |
| 27 | 27 | ||
| 28 | test "Properties" { | 28 | test Properties { |
| 29 | const pd = try PropsData.init(allocator); | 29 | const props = try Properties.init(allocator); |
| 30 | defer pd.deinit(); | 30 | defer props.deinit(allocator); |
| 31 | 31 | ||
| 32 | try expect(pd.isMath('+')); | 32 | try expect(props.isMath('+')); |
| 33 | try expect(pd.isAlphabetic('Z')); | 33 | try expect(props.isAlphabetic('Z')); |
| 34 | try expect(pd.isWhitespace(' ')); | 34 | try expect(props.isWhitespace(' ')); |
| 35 | try expect(pd.isHexDigit('f')); | 35 | try expect(props.isHexDigit('f')); |
| 36 | try expect(!pd.isHexDigit('z')); | 36 | try expect(!props.isHexDigit('z')); |
| 37 | 37 | ||
| 38 | try expect(pd.isDiacritic('\u{301}')); | 38 | try expect(props.isDiacritic('\u{301}')); |
| 39 | try expect(pd.isIdStart('Z')); // Identifier start character | 39 | try expect(props.isIdStart('Z')); // Identifier start character |
| 40 | try expect(!pd.isIdStart('1')); | 40 | try expect(!props.isIdStart('1')); |
| 41 | try expect(pd.isIdContinue('1')); | 41 | try expect(props.isIdContinue('1')); |
| 42 | try expect(pd.isXidStart('\u{b33}')); // Extended identifier start character | 42 | try expect(props.isXidStart('\u{b33}')); // Extended identifier start character |
| 43 | try expect(pd.isXidContinue('\u{e33}')); | 43 | try expect(props.isXidContinue('\u{e33}')); |
| 44 | try expect(!pd.isXidStart('1')); | 44 | try expect(!props.isXidStart('1')); |
| 45 | 45 | ||
| 46 | // Note surprising Unicode numeric types! | 46 | // Note surprising Unicode numeric types! |
| 47 | try expect(pd.isNumeric('\u{277f}')); | 47 | try expect(props.isNumeric('\u{277f}')); |
| 48 | try expect(!pd.isNumeric('3')); | 48 | try expect(!props.isNumeric('3')); |
| 49 | try expect(pd.isDigit('\u{2070}')); | 49 | try expect(props.isDigit('\u{2070}')); |
| 50 | try expect(!pd.isDigit('3')); | 50 | try expect(!props.isDigit('3')); |
| 51 | try expect(pd.isDecimal('3')); | 51 | try expect(props.isDecimal('3')); |
| 52 | } | 52 | } |
| 53 | 53 | ||
| 54 | const CaseData = @import("CaseData"); | 54 | const LetterCasing = @import("LetterCasing"); |
| 55 | 55 | ||
| 56 | test "Case" { | 56 | test LetterCasing { |
| 57 | const cd = try CaseData.init(allocator); | 57 | const case = try LetterCasing.init(allocator); |
| 58 | defer cd.deinit(); | 58 | defer case.deinit(allocator); |
| 59 | 59 | ||
| 60 | try expect(cd.isUpper('A')); | 60 | try expect(case.isUpper('A')); |
| 61 | try expect('A' == cd.toUpper('a')); | 61 | try expect('A' == case.toUpper('a')); |
| 62 | try expect(cd.isLower('a')); | 62 | try expect(case.isLower('a')); |
| 63 | try expect('a' == cd.toLower('A')); | 63 | try expect('a' == case.toLower('A')); |
| 64 | 64 | ||
| 65 | try expect(cd.isCased('É')); | 65 | try expect(case.isCased('É')); |
| 66 | try expect(!cd.isCased('3')); | 66 | try expect(!case.isCased('3')); |
| 67 | 67 | ||
| 68 | try expect(cd.isUpperStr("HELLO 123!")); | 68 | try expect(case.isUpperStr("HELLO 123!")); |
| 69 | const ucased = try cd.toUpperStr(allocator, "hello 123"); | 69 | const ucased = try case.toUpperStr(allocator, "hello 123"); |
| 70 | defer allocator.free(ucased); | 70 | defer allocator.free(ucased); |
| 71 | try expectEqualStrings("HELLO 123", ucased); | 71 | try expectEqualStrings("HELLO 123", ucased); |
| 72 | 72 | ||
| 73 | try expect(cd.isLowerStr("hello 123!")); | 73 | try expect(case.isLowerStr("hello 123!")); |
| 74 | const lcased = try cd.toLowerStr(allocator, "HELLO 123"); | 74 | const lcased = try case.toLowerStr(allocator, "HELLO 123"); |
| 75 | defer allocator.free(lcased); | 75 | defer allocator.free(lcased); |
| 76 | try expectEqualStrings("hello 123", lcased); | 76 | try expectEqualStrings("hello 123", lcased); |
| 77 | } | 77 | } |
| 78 | 78 | ||
| 79 | const Normalize = @import("Normalize"); | 79 | const Normalize = @import("Normalize"); |
| 80 | 80 | ||
| 81 | test "Normalization" { | 81 | test Normalize { |
| 82 | var norm_data = try Normalize.NormData.init(allocator); | 82 | const normalize = try Normalize.init(allocator); |
| 83 | defer norm_data.deinit(); | 83 | defer normalize.deinit(allocator); |
| 84 | const n = Normalize{ .norm_data = &norm_data }; | ||
| 85 | 84 | ||
| 86 | // NFD: Canonical decomposition | 85 | // NFD: Canonical decomposition |
| 87 | const nfd_result = try n.nfd(allocator, "Héllo World! \u{3d3}"); | 86 | const nfd_result = try normalize.nfd(allocator, "Héllo World! \u{3d3}"); |
| 88 | defer nfd_result.deinit(); | 87 | defer nfd_result.deinit(allocator); |
| 89 | try expectEqualStrings("He\u{301}llo World! \u{3d2}\u{301}", nfd_result.slice); | 88 | try expectEqualStrings("He\u{301}llo World! \u{3d2}\u{301}", nfd_result.slice); |
| 90 | 89 | ||
| 91 | // NFKD: Compatibility decomposition | 90 | // NFKD: Compatibility decomposition |
| 92 | const nfkd_result = try n.nfkd(allocator, "Héllo World! \u{3d3}"); | 91 | const nfkd_result = try normalize.nfkd(allocator, "Héllo World! \u{3d3}"); |
| 93 | defer nfkd_result.deinit(); | 92 | defer nfkd_result.deinit(allocator); |
| 94 | try expectEqualStrings("He\u{301}llo World! \u{3a5}\u{301}", nfkd_result.slice); | 93 | try expectEqualStrings("He\u{301}llo World! \u{3a5}\u{301}", nfkd_result.slice); |
| 95 | 94 | ||
| 96 | // NFC: Canonical composition | 95 | // NFC: Canonical composition |
| 97 | const nfc_result = try n.nfc(allocator, "Complex char: \u{3D2}\u{301}"); | 96 | const nfc_result = try normalize.nfc(allocator, "Complex char: \u{3D2}\u{301}"); |
| 98 | defer nfc_result.deinit(); | 97 | defer nfc_result.deinit(allocator); |
| 99 | try expectEqualStrings("Complex char: \u{3D3}", nfc_result.slice); | 98 | try expectEqualStrings("Complex char: \u{3D3}", nfc_result.slice); |
| 100 | 99 | ||
| 101 | // NFKC: Compatibility composition | 100 | // NFKC: Compatibility composition |
| 102 | const nfkc_result = try n.nfkc(allocator, "Complex char: \u{03A5}\u{0301}"); | 101 | const nfkc_result = try normalize.nfkc(allocator, "Complex char: \u{03A5}\u{0301}"); |
| 103 | defer nfkc_result.deinit(); | 102 | defer nfkc_result.deinit(allocator); |
| 104 | try expectEqualStrings("Complex char: \u{038E}", nfkc_result.slice); | 103 | try expectEqualStrings("Complex char: \u{038E}", nfkc_result.slice); |
| 105 | 104 | ||
| 106 | // Test for equality of two strings after normalizing to NFC. | 105 | // Test for equality of two strings after normalizing to NFC. |
| 107 | try expect(try n.eql(allocator, "foé", "foe\u{0301}")); | 106 | try expect(try normalize.eql(allocator, "foé", "foe\u{0301}")); |
| 108 | try expect(try n.eql(allocator, "foϓ", "fo\u{03D2}\u{0301}")); | 107 | try expect(try normalize.eql(allocator, "foϓ", "fo\u{03D2}\u{0301}")); |
| 109 | } | 108 | } |
| 110 | 109 | ||
| 111 | const CaseFold = @import("CaseFold"); | 110 | const CaseFolding = @import("CaseFolding"); |
| 112 | 111 | ||
| 113 | test "Caseless matching" { | 112 | test CaseFolding { |
| 114 | var norm_data = try Normalize.NormData.init(allocator); | 113 | const case_fold = try CaseFolding.init(allocator); |
| 115 | defer norm_data.deinit(); | 114 | defer case_fold.deinit(allocator); |
| 116 | const n = Normalize{ .norm_data = &norm_data }; | ||
| 117 | |||
| 118 | const cfd = try CaseFold.FoldData.init(allocator); | ||
| 119 | defer cfd.deinit(); | ||
| 120 | const cf = CaseFold{ .fold_data = &cfd }; | ||
| 121 | 115 | ||
| 122 | // compatCaselessMatch provides the deepest level of caseless | 116 | // compatCaselessMatch provides the deepest level of caseless |
| 123 | // matching because it decomposes and composes fully to NFKC. | 117 | // matching because it decomposes and composes fully to NFKC. |
| 124 | const a = "Héllo World! \u{3d3}"; | 118 | const a = "Héllo World! \u{3d3}"; |
| 125 | const b = "He\u{301}llo World! \u{3a5}\u{301}"; | 119 | const b = "He\u{301}llo World! \u{3a5}\u{301}"; |
| 126 | try expect(try cf.compatCaselessMatch(allocator, &n, a, b)); | 120 | try expect(try case_fold.compatCaselessMatch(allocator, a, b)); |
| 127 | 121 | ||
| 128 | const c = "He\u{301}llo World! \u{3d2}\u{301}"; | 122 | const c = "He\u{301}llo World! \u{3d2}\u{301}"; |
| 129 | try expect(try cf.compatCaselessMatch(allocator, &n, a, c)); | 123 | try expect(try case_fold.compatCaselessMatch(allocator, a, c)); |
| 130 | 124 | ||
| 131 | // canonCaselessMatch isn't as comprehensive as compatCaselessMatch | 125 | // canonCaselessMatch isn't as comprehensive as compatCaselessMatch |
| 132 | // because it only decomposes and composes to NFC. But it's faster. | 126 | // because it only decomposes and composes to NFC. But it's faster. |
| 133 | try expect(!try cf.canonCaselessMatch(allocator, &n, a, b)); | 127 | try expect(!try case_fold.canonCaselessMatch(allocator, a, b)); |
| 134 | try expect(try cf.canonCaselessMatch(allocator, &n, a, c)); | 128 | try expect(try case_fold.canonCaselessMatch(allocator, a, c)); |
| 135 | } | 129 | } |
| 136 | 130 | ||
| 137 | const DisplayWidth = @import("DisplayWidth"); | 131 | const DisplayWidth = @import("DisplayWidth"); |
| 138 | 132 | ||
| 139 | test "Display width" { | 133 | test DisplayWidth { |
| 140 | const dwd = try DisplayWidth.DisplayWidthData.init(allocator); | 134 | const dw = try DisplayWidth.init(allocator); |
| 141 | defer dwd.deinit(); | 135 | defer dw.deinit(allocator); |
| 142 | const dw = DisplayWidth{ .data = &dwd }; | ||
| 143 | 136 | ||
| 144 | // String display width | 137 | // String display width |
| 145 | try expectEqual(@as(usize, 5), dw.strWidth("Hello\r\n")); | 138 | try expectEqual(@as(usize, 5), dw.strWidth("Hello\r\n")); |
| @@ -197,13 +190,13 @@ test "Code point iterator" { | |||
| 197 | } | 190 | } |
| 198 | } | 191 | } |
| 199 | 192 | ||
| 200 | const grapheme = @import("grapheme"); | 193 | const Graphemes = @import("Graphemes"); |
| 201 | 194 | ||
| 202 | test "Grapheme cluster iterator" { | 195 | test "Grapheme cluster iterator" { |
| 203 | const gd = try grapheme.GraphemeData.init(allocator); | 196 | const graphemes = try Graphemes.init(allocator); |
| 204 | defer gd.deinit(); | 197 | defer graphemes.deinit(allocator); |
| 205 | const str = "He\u{301}"; // Hé | 198 | const str = "He\u{301}"; // Hé |
| 206 | var iter = grapheme.Iterator.init(str, &gd); | 199 | var iter = graphemes.iterator(str); |
| 207 | var i: usize = 0; | 200 | var i: usize = 0; |
| 208 | 201 | ||
| 209 | while (iter.next()) |gc| : (i += 1) { | 202 | while (iter.next()) |gc| : (i += 1) { |
| @@ -217,13 +210,13 @@ test "Grapheme cluster iterator" { | |||
| 217 | } | 210 | } |
| 218 | } | 211 | } |
| 219 | 212 | ||
| 220 | const ScriptsData = @import("ScriptsData"); | 213 | const Scripts = @import("Scripts"); |
| 221 | 214 | ||
| 222 | test "Scripts" { | 215 | test Scripts { |
| 223 | const sd = try ScriptsData.init(allocator); | 216 | const scripts = try Scripts.init(allocator); |
| 224 | defer sd.deinit(); | 217 | defer scripts.deinit(allocator); |
| 225 | 218 | ||
| 226 | try expect(sd.script('A') == .Latin); | 219 | try expect(scripts.script('A') == .Latin); |
| 227 | try expect(sd.script('Ω') == .Greek); | 220 | try expect(scripts.script('Ω') == .Greek); |
| 228 | try expect(sd.script('צ') == .Hebrew); | 221 | try expect(scripts.script('צ') == .Hebrew); |
| 229 | } | 222 | } |