Caching and cultcache-ts tests: slot-nil rows for a four-byte UTF-8 character in a string slot and in a byte[] slot

The C# cases and the TS assertions are here; the vector file is written from the reference in the next commit, so the
slot-nil tests of both runtimes fail at this commit.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
Meta Vens 2026-10-12 00:08:23 +02:00
commit c114820c0c
3 changed files with 13 additions and 4 deletions

View file

@ -772,7 +772,7 @@ test("slots read and rewrite exactly what the C# reference does for nil, a str i
4: ["l", list(string), () => []],
});
const rows = readWire(new Uint8Array(await readFile(join(vectors, "..", "slot-nil", "reads.msgpack")))) as [string, Uint8Array, boolean, Uint8Array][];
assert.equal(rows.length, 15);
assert.equal(rows.length, 17);
let accepted = 0;
for (const [name, payload, wasAccepted, rewritten] of rows) {
if (wasAccepted) {
@ -782,7 +782,14 @@ test("slots read and rewrite exactly what the C# reference does for nil, a str i
assert.throws(() => probe.decode(readWire(payload)), (error: Error) => !error.message.includes(hex(payload).slice(2)), name);
}
}
assert.equal(accepted, 13);
assert.equal(accepted, 15);
// A character outside the BMP is four UTF-8 bytes (U+1F600 is f0 9f 98 80); a CESU-8 reader, or one with no four-byte
// branch, fails here against the bytes the C# reference wrote.
const astral = rows.find(([name]) => name === "string-astral")!;
assert.equal(probe.decode(readWire(astral[1])).s, "\u{1F600}");
assert.equal(hex(writeWire(probe.encode(probe.decode(readWire(astral[1]))))), hex(astral[3]));
const astralInBytes = rows.find(([name]) => name === "bytes-str-astral")!;
assert.equal(hex(probe.decode(readWire(astralInBytes[1])).b), "f09f9880");
});
test("a nil reads as null and writes as nil in every reference slot, and a value slot refuses it", () => {

View file

@ -44,6 +44,8 @@ namespace GameCult.Caching.Tests
("nil-int", "95a161c0c4026162c090"),
("bytes-str", "95a16107a3616263c090"),
("bytes-str-euro", "95a16107a3e282acc090"),
("string-astral", "95a4f09f988007c4026162c090"),
("bytes-str-astral", "95a16107a4f09f9880c090"),
("bytes-bin", "95a16107c403616263c090"),
("short-0", "90"),
("short-1", "91a161"),

View file

@ -8,5 +8,5 @@ A record of five slots: `S` string, `I` int, `B` byte[], `R` a record of one str
- `reads.msgpack`: an array of `[name, payload, accepted, rewritten]`. `payload` (bin) is the record fed to the
reference; `accepted` is whether it read; `rewritten` (bin) is what the reference writes after reading it, and empty
when refused. It covers a nil in each kind of slot, a MessagePack str in the byte[] slot, and records short of their
last slots.
when refused. It covers a nil in each kind of slot, a MessagePack str in the byte[] slot, a four-byte UTF-8 character
(U+1F600) as the string slot and as a str in the byte[] slot, and records short of their last slots.