lib/encoding+math tests: hand-main plumbing -> assert (@test conversion B2)

This commit is contained in:
2026-06-10 18:52:53 +09:00
parent 6ef2bbcb95
commit 56450e68ce
6 changed files with 451 additions and 462 deletions

View File

@@ -1,16 +1,12 @@
// utf8test — exercises lib/encoding/utf8. Run with
// `out/bin/ww run lib/encoding/utf8/utf8test.ww`. Same signalled-
// then-fail()-with-+10 pattern as hex / base32 / time tests:
// non-zero exit pinpoints the failing scenario.
// `out/bin/ww run lib/encoding/utf8/utf8test.ww`. A failing row aborts
// via the assert/abort builtin (task #5 @test conversion).
package utf8_test;
import bytes;
import encoding.utf8;
import os;
let signalled: i32 = 0;
fn fail() void = { os.exit(signalled + 10); };
fn streq(a: str, b: str) bool = {
if (a.len != b.len) { return false; };
@@ -27,14 +23,14 @@ fn streq(a: str, b: str) bool = {
// 0x7FF → 2, 0x800 → 3, 0xFFFF → 3, 0x10000 → 4, 0x10FFFF → 4.
@test fn runesz_ranges() void = {
if (utf8.runesz(0u32: rune) != 1) { fail(); };
if (utf8.runesz(0x7Fu32: rune) != 1) { fail(); };
if (utf8.runesz(0x80u32: rune) != 2) { fail(); };
if (utf8.runesz(0x7FFu32: rune) != 2) { fail(); };
if (utf8.runesz(0x800u32: rune) != 3) { fail(); };
if (utf8.runesz(0xFFFFu32: rune) != 3) { fail(); };
if (utf8.runesz(0x10000u32: rune) != 4) { fail(); };
if (utf8.runesz(0x10FFFFu32: rune) != 4) { fail(); };
assert(!(utf8.runesz(0u32: rune) != 1));
assert(!(utf8.runesz(0x7Fu32: rune) != 1));
assert(!(utf8.runesz(0x80u32: rune) != 2));
assert(!(utf8.runesz(0x7FFu32: rune) != 2));
assert(!(utf8.runesz(0x800u32: rune) != 3));
assert(!(utf8.runesz(0xFFFFu32: rune) != 3));
assert(!(utf8.runesz(0x10000u32: rune) != 4));
assert(!(utf8.runesz(0x10FFFFu32: rune) != 4));
};
// ---- utf8sz: start-byte classification --------------------------------
@@ -43,39 +39,39 @@ fn streq(a: str, b: str) bool = {
@test fn utf8sz_classify() void = {
match (utf8.utf8sz(0u8)) {
case let n: i32 => { if (n != 1) { fail(); }; };
case let e: utf8.invalid => { fail(); };
case let n: i32 => { assert(!(n != 1)); };
case let e: utf8.invalid => { abort(); };
};
match (utf8.utf8sz(0x7Fu8)) {
case let n: i32 => { if (n != 1) { fail(); }; };
case let e: utf8.invalid => { fail(); };
case let n: i32 => { assert(!(n != 1)); };
case let e: utf8.invalid => { abort(); };
};
match (utf8.utf8sz(0x80u8)) { // continuation
case let n: i32 => { fail(); };
case let n: i32 => { abort(); };
case let e: utf8.invalid => void;
};
match (utf8.utf8sz(0xC1u8)) { // overlong 2-byte lead
case let n: i32 => { fail(); };
case let n: i32 => { abort(); };
case let e: utf8.invalid => void;
};
match (utf8.utf8sz(0xC2u8)) {
case let n: i32 => { if (n != 2) { fail(); }; };
case let e: utf8.invalid => { fail(); };
case let n: i32 => { assert(!(n != 2)); };
case let e: utf8.invalid => { abort(); };
};
match (utf8.utf8sz(0xE0u8)) {
case let n: i32 => { if (n != 3) { fail(); }; };
case let e: utf8.invalid => { fail(); };
case let n: i32 => { assert(!(n != 3)); };
case let e: utf8.invalid => { abort(); };
};
match (utf8.utf8sz(0xF0u8)) {
case let n: i32 => { if (n != 4) { fail(); }; };
case let e: utf8.invalid => { fail(); };
case let n: i32 => { assert(!(n != 4)); };
case let e: utf8.invalid => { abort(); };
};
match (utf8.utf8sz(0xF8u8)) { // 5-byte lead — illegal in modern UTF-8
case let n: i32 => { fail(); };
case let n: i32 => { abort(); };
case let e: utf8.invalid => void;
};
match (utf8.utf8sz(0xFFu8)) {
case let n: i32 => { fail(); };
case let n: i32 => { abort(); };
case let e: utf8.invalid => void;
};
};
@@ -87,35 +83,35 @@ fn streq(a: str, b: str) bool = {
@test fn encode_ascii() void = {
let out: [4]u8;
let n: i32 = utf8.encoderune(out[0:4], 0x41u32: rune); // 'A'
if (n != 1) { fail(); };
if (out[0] != 0x41u8) { fail(); };
assert(!(n != 1));
assert(!(out[0] != 0x41u8));
};
@test fn encode_two_byte() void = {
let out: [4]u8;
let n: i32 = utf8.encoderune(out[0:4], 0xE9u32: rune); // 'é' U+00E9
if (n != 2) { fail(); };
if (out[0] != 0xC3u8) { fail(); };
if (out[1] != 0xA9u8) { fail(); };
assert(!(n != 2));
assert(!(out[0] != 0xC3u8));
assert(!(out[1] != 0xA9u8));
};
@test fn encode_three_byte() void = {
let out: [4]u8;
let n: i32 = utf8.encoderune(out[0:4], 0x20ACu32: rune); // '€' U+20AC
if (n != 3) { fail(); };
if (out[0] != 0xE2u8) { fail(); };
if (out[1] != 0x82u8) { fail(); };
if (out[2] != 0xACu8) { fail(); };
assert(!(n != 3));
assert(!(out[0] != 0xE2u8));
assert(!(out[1] != 0x82u8));
assert(!(out[2] != 0xACu8));
};
@test fn encode_four_byte() void = {
let out: [4]u8;
let n: i32 = utf8.encoderune(out[0:4], 0x1F980u32: rune); // '🦀' U+1F980
if (n != 4) { fail(); };
if (out[0] != 0xF0u8) { fail(); };
if (out[1] != 0x9Fu8) { fail(); };
if (out[2] != 0xA6u8) { fail(); };
if (out[3] != 0x80u8) { fail(); };
assert(!(n != 4));
assert(!(out[0] != 0xF0u8));
assert(!(out[1] != 0x9Fu8));
assert(!(out[2] != 0xA6u8));
assert(!(out[3] != 0x80u8));
};
// ---- decoder.next: valid 1/2/3/4-byte ---------------------------------
@@ -127,10 +123,10 @@ fn streq(a: str, b: str) bool = {
src[0] = 0x41u8;
let d: utf8.decoder = utf8.decode(src[0:1]);
match (utf8.next(&d)) {
case utf8.done => { fail(); };
case utf8.more => { fail(); };
case let r: utf8.invalid => { fail(); };
case let r: rune => { if (r != 0x41u32: rune) { fail(); }; };
case utf8.done => { abort(); };
case utf8.more => { abort(); };
case let r: utf8.invalid => { abort(); };
case let r: rune => { assert(!(r != 0x41u32: rune)); };
};
};
@@ -139,10 +135,10 @@ fn streq(a: str, b: str) bool = {
src[0] = 0xC3u8; src[1] = 0xA9u8;
let d: utf8.decoder = utf8.decode(src[0:2]);
match (utf8.next(&d)) {
case utf8.done => { fail(); };
case utf8.more => { fail(); };
case let r: utf8.invalid => { fail(); };
case let r: rune => { if (r != 0xE9u32: rune) { fail(); }; };
case utf8.done => { abort(); };
case utf8.more => { abort(); };
case let r: utf8.invalid => { abort(); };
case let r: rune => { assert(!(r != 0xE9u32: rune)); };
};
};
@@ -151,10 +147,10 @@ fn streq(a: str, b: str) bool = {
src[0] = 0xE2u8; src[1] = 0x82u8; src[2] = 0xACu8;
let d: utf8.decoder = utf8.decode(src[0:3]);
match (utf8.next(&d)) {
case utf8.done => { fail(); };
case utf8.more => { fail(); };
case let r: utf8.invalid => { fail(); };
case let r: rune => { if (r != 0x20ACu32: rune) { fail(); }; };
case utf8.done => { abort(); };
case utf8.more => { abort(); };
case let r: utf8.invalid => { abort(); };
case let r: rune => { assert(!(r != 0x20ACu32: rune)); };
};
};
@@ -163,10 +159,10 @@ fn streq(a: str, b: str) bool = {
src[0] = 0xF0u8; src[1] = 0x9Fu8; src[2] = 0xA6u8; src[3] = 0x80u8;
let d: utf8.decoder = utf8.decode(src[0:4]);
match (utf8.next(&d)) {
case utf8.done => { fail(); };
case utf8.more => { fail(); };
case let r: utf8.invalid => { fail(); };
case let r: rune => { if (r != 0x1F980u32: rune) { fail(); }; };
case utf8.done => { abort(); };
case utf8.more => { abort(); };
case let r: utf8.invalid => { abort(); };
case let r: rune => { assert(!(r != 0x1F980u32: rune)); };
};
};
@@ -180,9 +176,9 @@ fn streq(a: str, b: str) bool = {
let d: utf8.decoder = utf8.decode(src[0:3]);
match (utf8.next(&d)) {
case let r: utf8.invalid => void;
case let r: rune => { fail(); };
case utf8.done => { fail(); };
case utf8.more => { fail(); };
case let r: rune => { abort(); };
case utf8.done => { abort(); };
case utf8.more => { abort(); };
};
};
@@ -192,9 +188,9 @@ fn streq(a: str, b: str) bool = {
let d: utf8.decoder = utf8.decode(src[0:4]);
match (utf8.next(&d)) {
case let r: utf8.invalid => void;
case let r: rune => { fail(); };
case utf8.done => { fail(); };
case utf8.more => { fail(); };
case let r: rune => { abort(); };
case utf8.done => { abort(); };
case utf8.more => { abort(); };
};
};
@@ -204,9 +200,9 @@ fn streq(a: str, b: str) bool = {
let d: utf8.decoder = utf8.decode(src[0:4]);
match (utf8.next(&d)) {
case let r: utf8.invalid => void;
case let r: rune => { fail(); };
case utf8.done => { fail(); };
case utf8.more => { fail(); };
case let r: rune => { abort(); };
case utf8.done => { abort(); };
case utf8.more => { abort(); };
};
};
@@ -220,9 +216,9 @@ fn streq(a: str, b: str) bool = {
let d: utf8.decoder = utf8.decode(src[0:2]);
match (utf8.next(&d)) {
case let r: utf8.invalid => void;
case let r: rune => { fail(); };
case utf8.done => { fail(); };
case utf8.more => { fail(); };
case let r: rune => { abort(); };
case utf8.done => { abort(); };
case utf8.more => { abort(); };
};
};
@@ -234,10 +230,10 @@ fn streq(a: str, b: str) bool = {
src[0] = 0xF4u8; src[1] = 0x8Fu8; src[2] = 0xBFu8; src[3] = 0xBFu8;
let d: utf8.decoder = utf8.decode(src[0:4]);
match (utf8.next(&d)) {
case let r: rune => { if (r != 0x10FFFFu32: rune) { fail(); }; };
case let r: utf8.invalid => { fail(); };
case utf8.done => { fail(); };
case utf8.more => { fail(); };
case let r: rune => { assert(!(r != 0x10FFFFu32: rune)); };
case let r: utf8.invalid => { abort(); };
case utf8.done => { abort(); };
case utf8.more => { abort(); };
};
};
@@ -249,9 +245,9 @@ fn streq(a: str, b: str) bool = {
let d: utf8.decoder = utf8.decode(src[0:2]);
match (utf8.next(&d)) {
case utf8.more => void;
case let r: rune => { fail(); };
case utf8.done => { fail(); };
case let r: utf8.invalid => { fail(); };
case let r: rune => { abort(); };
case utf8.done => { abort(); };
case let r: utf8.invalid => { abort(); };
};
};
@@ -262,9 +258,9 @@ fn streq(a: str, b: str) bool = {
let d: utf8.decoder = utf8.decode(src[0:0]);
match (utf8.next(&d)) {
case utf8.done => void;
case let r: rune => { fail(); };
case utf8.more => { fail(); };
case let r: utf8.invalid => { fail(); };
case let r: rune => { abort(); };
case utf8.more => { abort(); };
case let r: utf8.invalid => { abort(); };
};
};
@@ -281,7 +277,7 @@ fn streq(a: str, b: str) bool = {
src[12] = 0xE3u8; src[13] = 0x81u8; src[14] = 0xAFu8; // は
src[15] = 0u8;
match (utf8.validate(src[0:16])) {
case let e: utf8.invalid => { fail(); };
case let e: utf8.invalid => { abort(); };
case void => void;
};
};
@@ -291,14 +287,14 @@ fn streq(a: str, b: str) bool = {
src[0] = 0xEDu8; src[1] = 0xA0u8; src[2] = 0x80u8; // surrogate
match (utf8.validate(src[0:3])) {
case let e: utf8.invalid => void;
case void => { fail(); };
case void => { abort(); };
};
};
@test fn validate_empty_ok() void = {
let src: [1]u8;
match (utf8.validate(src[0:0])) {
case let e: utf8.invalid => { fail(); };
case let e: utf8.invalid => { abort(); };
case void => void;
};
};
@@ -313,9 +309,9 @@ fn streq(a: str, b: str) bool = {
let d: utf8.decoder = utf8.decode(src[0:1]);
match (utf8.prev(&d)) {
case utf8.done => void;
case let r: rune => { fail(); };
case utf8.more => { fail(); };
case let e: utf8.invalid => { fail(); };
case let r: rune => { abort(); };
case utf8.more => { abort(); };
case let e: utf8.invalid => { abort(); };
};
};
@@ -329,11 +325,11 @@ fn streq(a: str, b: str) bool = {
let d: utf8.decoder = utf8.decode(src[0:1]);
match (utf8.next(&d)) {
case let r: rune => void;
case => { fail(); };
case => { abort(); };
};
match (utf8.prev(&d)) {
case let r: rune => { if (r != 0x41u32: rune) { fail(); }; };
case => { fail(); };
case let r: rune => { assert(!(r != 0x41u32: rune)); };
case => { abort(); };
};
};
@@ -343,11 +339,11 @@ fn streq(a: str, b: str) bool = {
let d: utf8.decoder = utf8.decode(src[0:2]);
match (utf8.next(&d)) {
case let r: rune => void;
case => { fail(); };
case => { abort(); };
};
match (utf8.prev(&d)) {
case let r: rune => { if (r != 0xE9u32: rune) { fail(); }; };
case => { fail(); };
case let r: rune => { assert(!(r != 0xE9u32: rune)); };
case => { abort(); };
};
};
@@ -357,11 +353,11 @@ fn streq(a: str, b: str) bool = {
let d: utf8.decoder = utf8.decode(src[0:3]);
match (utf8.next(&d)) {
case let r: rune => void;
case => { fail(); };
case => { abort(); };
};
match (utf8.prev(&d)) {
case let r: rune => { if (r != 0x20ACu32: rune) { fail(); }; };
case => { fail(); };
case let r: rune => { assert(!(r != 0x20ACu32: rune)); };
case => { abort(); };
};
};
@@ -371,11 +367,11 @@ fn streq(a: str, b: str) bool = {
let d: utf8.decoder = utf8.decode(src[0:4]);
match (utf8.next(&d)) {
case let r: rune => void;
case => { fail(); };
case => { abort(); };
};
match (utf8.prev(&d)) {
case let r: rune => { if (r != 0x1F980u32: rune) { fail(); }; };
case => { fail(); };
case let r: rune => { assert(!(r != 0x1F980u32: rune)); };
case => { abort(); };
};
};
@@ -398,24 +394,24 @@ fn streq(a: str, b: str) bool = {
for (i < 6) {
match (utf8.next(&d)) {
case let r: rune => { fwd[i] = r: u32; };
case => { fail(); };
case => { abort(); };
};
i += 1;
};
if (utf8.position(&d) != 16) { fail(); };
assert(!(utf8.position(&d) != 16));
i = 0;
for (i < 6) {
match (utf8.prev(&d)) {
case let r: rune => {
if ((r: u32) != fwd[5 - i]) { fail(); };
assert(!((r: u32) != fwd[5 - i]));
};
case => { fail(); };
case => { abort(); };
};
i += 1;
};
match (utf8.prev(&d)) {
case utf8.done => void;
case => { fail(); };
case => { abort(); };
};
};
@@ -435,9 +431,9 @@ fn streq(a: str, b: str) bool = {
d.offs = 2;
match (utf8.prev(&d)) {
case utf8.more => void;
case let r: rune => { fail(); };
case utf8.done => { fail(); };
case let e: utf8.invalid => { fail(); };
case let r: rune => { abort(); };
case utf8.done => { abort(); };
case let e: utf8.invalid => { abort(); };
};
};
@@ -448,9 +444,9 @@ fn streq(a: str, b: str) bool = {
d.offs = 2;
match (utf8.prev(&d)) {
case let e: utf8.invalid => void;
case let r: rune => { fail(); };
case utf8.done => { fail(); };
case utf8.more => { fail(); };
case let r: rune => { abort(); };
case utf8.done => { abort(); };
case utf8.more => { abort(); };
};
};
@@ -461,9 +457,9 @@ fn streq(a: str, b: str) bool = {
d.offs = 3;
match (utf8.prev(&d)) {
case let e: utf8.invalid => void;
case let r: rune => { fail(); };
case utf8.done => { fail(); };
case utf8.more => { fail(); };
case let r: rune => { abort(); };
case utf8.done => { abort(); };
case utf8.more => { abort(); };
};
};
@@ -474,9 +470,9 @@ fn streq(a: str, b: str) bool = {
d.offs = 4;
match (utf8.prev(&d)) {
case let e: utf8.invalid => void;
case let r: rune => { fail(); };
case utf8.done => { fail(); };
case utf8.more => { fail(); };
case let r: rune => { abort(); };
case utf8.done => { abort(); };
case utf8.more => { abort(); };
};
};
@@ -490,9 +486,9 @@ fn streq(a: str, b: str) bool = {
d.offs = 3;
match (utf8.prev(&d)) {
case let e: utf8.invalid => void;
case let r: rune => { fail(); };
case utf8.done => { fail(); };
case utf8.more => { fail(); };
case let r: rune => { abort(); };
case utf8.done => { abort(); };
case utf8.more => { abort(); };
};
};
@@ -506,10 +502,10 @@ fn streq(a: str, b: str) bool = {
let d: utf8.decoder = utf8.decode(src[0:4]);
d.offs = 4;
match (utf8.prev(&d)) {
case let r: rune => { if (r != 0x10FFFFu32: rune) { fail(); }; };
case let e: utf8.invalid => { fail(); };
case utf8.done => { fail(); };
case utf8.more => { fail(); };
case let r: rune => { assert(!(r != 0x10FFFFu32: rune)); };
case let e: utf8.invalid => { abort(); };
case utf8.done => { abort(); };
case utf8.more => { abort(); };
};
};
@@ -526,9 +522,9 @@ fn streq(a: str, b: str) bool = {
d.offs = 4;
match (utf8.prev(&d)) {
case let e: utf8.invalid => void;
case let r: rune => { fail(); };
case utf8.done => { fail(); };
case utf8.more => { fail(); };
case let r: rune => { abort(); };
case utf8.done => { abort(); };
case utf8.more => { abort(); };
};
};
@@ -551,38 +547,38 @@ fn streq(a: str, b: str) bool = {
let d1: utf8.decoder = utf8.decode(src[0:16]);
let d2: utf8.decoder = utf8.decode(src[0:16]);
if (!bytes.equal(utf8.remaining(&d1), src[0:16])) { fail(); };
if (utf8.slice(&d1, &d2).len != 0) { fail(); };
if (utf8.slice(&d2, &d1).len != 0) { fail(); };
if (utf8.position(&d1) != 0) { fail(); };
assert(!(!bytes.equal(utf8.remaining(&d1), src[0:16])));
assert(!(utf8.slice(&d1, &d2).len != 0));
assert(!(utf8.slice(&d2, &d1).len != 0));
assert(!(utf8.position(&d1) != 0));
let i: i32 = 0;
for (i < 2) {
match (utf8.next(&d1)) { case let r: rune => void; case => { fail(); }; };
match (utf8.next(&d2)) { case let r: rune => void; case => { fail(); }; };
match (utf8.next(&d1)) { case let r: rune => void; case => { abort(); }; };
match (utf8.next(&d2)) { case let r: rune => void; case => { abort(); }; };
i += 1;
};
if (utf8.position(&d1) != 6) { fail(); };
if (!bytes.equal(utf8.remaining(&d1), src[6:16])) { fail(); };
if (utf8.slice(&d1, &d2).len != 0) { fail(); };
assert(!(utf8.position(&d1) != 6));
assert(!(!bytes.equal(utf8.remaining(&d1), src[6:16])));
assert(!(utf8.slice(&d1, &d2).len != 0));
i = 0;
for (i < 3) {
match (utf8.next(&d2)) { case let r: rune => void; case => { fail(); }; };
match (utf8.next(&d2)) { case let r: rune => void; case => { abort(); }; };
i += 1;
};
if (utf8.position(&d2) != 15) { fail(); };
if (!bytes.equal(utf8.remaining(&d2), src[15:16])) { fail(); };
if (!bytes.equal(utf8.slice(&d1, &d2), src[6:15])) { fail(); };
assert(!(utf8.position(&d2) != 15));
assert(!(!bytes.equal(utf8.remaining(&d2), src[15:16])));
assert(!(!bytes.equal(utf8.slice(&d1, &d2), src[6:15])));
i = 0;
for (i < 3) {
match (utf8.next(&d1)) { case let r: rune => void; case => { fail(); }; };
match (utf8.next(&d1)) { case let r: rune => void; case => { abort(); }; };
i += 1;
};
if (utf8.slice(&d1, &d2).len != 0) { fail(); };
match (utf8.next(&d1)) { case let r: rune => void; case => { fail(); }; };
if (utf8.remaining(&d1).len != 0) { fail(); };
assert(!(utf8.slice(&d1, &d2).len != 0));
match (utf8.next(&d1)) { case let r: rune => void; case => { abort(); }; };
assert(!(utf8.remaining(&d1).len != 0));
};
// ---- strerror: constant rendering -------------------------------------
@@ -591,7 +587,7 @@ fn streq(a: str, b: str) bool = {
@test fn strerror_cases() void = {
let e: utf8.invalid;
if (!streq(utf8.strerror(e), "Invalid UTF-8")) { fail(); };
assert(!(!streq(utf8.strerror(e), "Invalid UTF-8")));
};
// ---- round-trip: encode → decode → equal rune --------------------------
@@ -609,52 +605,52 @@ fn streq(a: str, b: str) bool = {
let d: utf8.decoder = utf8.decode(buf[0:n]);
match (utf8.next(&d)) {
case let r: rune => {
if ((r: u32) != runes[i]) { fail(); };
assert(!((r: u32) != runes[i]));
};
case utf8.done => { fail(); };
case utf8.more => { fail(); };
case let e: utf8.invalid => { fail(); };
case utf8.done => { abort(); };
case utf8.more => { abort(); };
case let e: utf8.invalid => { abort(); };
};
i += 1;
};
};
export fn main() i32 = {
signalled = 1; runesz_ranges();
signalled = 2; utf8sz_classify();
signalled = 3; encode_ascii();
signalled = 4; encode_two_byte();
signalled = 5; encode_three_byte();
signalled = 6; encode_four_byte();
signalled = 7; decode_one_byte();
signalled = 8; decode_two_byte();
signalled = 9; decode_three_byte();
signalled = 10; decode_four_byte();
signalled = 11; decode_surrogate();
signalled = 12; decode_overlong();
signalled = 13; decode_out_of_range();
signalled = 14; decode_bad_continuation();
signalled = 15; decode_max_in_range();
signalled = 16; decode_truncated();
signalled = 17; decode_done();
signalled = 18; validate_mixed_ok();
signalled = 19; validate_malformed();
signalled = 20; validate_empty_ok();
signalled = 21; roundtrip();
signalled = 22; prev_done_at_start();
signalled = 23; prev_one_byte();
signalled = 24; prev_two_byte();
signalled = 25; prev_three_byte();
signalled = 26; prev_four_byte();
signalled = 27; prev_mixed_roundtrip();
signalled = 28; prev_continuation_only_more();
signalled = 29; prev_incomplete_invalid();
signalled = 30; prev_surrogate_invalid();
signalled = 31; prev_overlong_invalid();
signalled = 32; prev_extracont_invalid();
signalled = 33; prev_max_in_range();
signalled = 34; prev_min_out_of_range();
signalled = 35; remaining_slice_position();
signalled = 36; strerror_cases();
runesz_ranges();
utf8sz_classify();
encode_ascii();
encode_two_byte();
encode_three_byte();
encode_four_byte();
decode_one_byte();
decode_two_byte();
decode_three_byte();
decode_four_byte();
decode_surrogate();
decode_overlong();
decode_out_of_range();
decode_bad_continuation();
decode_max_in_range();
decode_truncated();
decode_done();
validate_mixed_ok();
validate_malformed();
validate_empty_ok();
roundtrip();
prev_done_at_start();
prev_one_byte();
prev_two_byte();
prev_three_byte();
prev_four_byte();
prev_mixed_roundtrip();
prev_continuation_only_more();
prev_incomplete_invalid();
prev_surrogate_invalid();
prev_overlong_invalid();
prev_extracont_invalid();
prev_max_in_range();
prev_min_out_of_range();
remaining_slice_position();
strerror_cases();
return 0;
};