claude-split-empty-separator-units — rts_diverge
Category: other. Fixture: tests/cross-runtime/string/claude-split-empty-separator-units.ts
Test code
// Cross-runtime: split("") splits by UTF-16 code UNIT, not by code point.
// Surrogate pairs are torn apart into lone halves — unlike [...str] / for..of.
const emoji = "a\u{1F600}b"; // 'a', surrogate hi, surrogate lo, 'b'
// --- length by unit vs by code point ---
console.log("split-len=" + emoji.split("").length);
console.log("spread-len=" + [...emoji].length);
console.log("str-len=" + emoji.length);
// --- each unit's code, in hex ---
const units = emoji.split("");
console.log("units=" + units.map((c) => c.charCodeAt(0).toString(16)).join(","));
// --- each split piece has length 1 (a single code unit) ---
console.log("piece-lens=" + units.map((c) => c.length).join(","));
// --- rejoining by unit round-trips; the halves are individually lone ---
console.log("rejoin-eq=" + (units.join("") === emoji));
console.log("half-hi-isLone=" + (units[1].charCodeAt(0) >= 0xd800 && units[1].charCodeAt(0) <= 0xdbff));
console.log("half-lo-isLone=" + (units[2].charCodeAt(0) >= 0xdc00 && units[2].charCodeAt(0) <= 0xdfff));
// --- codePointAt on a lone half returns the half itself, not the pair ---
console.log("half-hi-cp=" + units[1].codePointAt(0).toString(16));
console.log("full-cp=" + emoji.codePointAt(1).toString(16));
// --- contrast: spread iterates by code point, keeping the pair whole ---
const pts = [...emoji];
console.log("spread-lens=" + pts.map((c) => c.length).join(","));
console.log("spread-cps=" + pts.map((c) => c.codePointAt(0).toString(16)).join(","));
// --- multiple surrogate pairs ---
const two = "\u{1F600}\u{1F601}";
console.log("two-split-len=" + two.split("").length);
console.log("two-spread-len=" + [...two].length);
// --- BMP astral boundary: U+FFFF is one unit, U+10000 is two ---
console.log("ffff-split=" + String.fromCharCode(0xFFFF).split("").length);
console.log("10000-split=" + "\u{10000}".split("").length);
// --- combining marks are separate units either way (no grapheme clustering) ---
const combining = "e" + String.fromCharCode(0x0301); // e + combining acute
console.log("combining-split=" + combining.split("").length);
console.log("combining-spread=" + [...combining].length);
// --- empty string and ASCII baselines ---
console.log("empty-split-len=" + "".split("").length);
console.log("ascii-split=" + "abc".split("").join("|"));
// --- split("") with a limit still counts units ---
console.log("limit=" + emoji.split("", 3).map((c) => c.charCodeAt(0).toString(16)).join(","));
console.log("limit0-len=" + emoji.split("", 0).length);
Outputs
Bun:
split-len=4
spread-len=3
str-len=4
units=61,d83d,de00,62
piece-lens=1,1,1,1
rejoin-eq=true
half-hi-isLone=true
half-lo-isLone=true
half-hi-cp=d83d
full-cp=1f600
spread-lens=1,2,1
spread-cps=61,1f600,62
two-split-len=4
two-spread-len=2
ffff-split=1
10000-split=2
combining-split=2
combining-spread=2
empty-split-len=0
ascii-split=a|b|c
limit=61,d83d,de00
limit0-len=0
Node:
split-len=4
spread-len=3
str-len=4
units=61,d83d,de00,62
piece-lens=1,1,1,1
rejoin-eq=true
half-hi-isLone=true
half-lo-isLone=true
half-hi-cp=d83d
full-cp=1f600
spread-lens=1,2,1
spread-cps=61,1f600,62
two-split-len=4
two-spread-len=2
ffff-split=1
10000-split=2
combining-split=2
combining-spread=2
empty-split-len=0
ascii-split=a|b|c
limit=61,d83d,de00
limit0-len=0
RTS:
split-len=3
spread-len=3
str-len=4
units=61,d83d,62
piece-lens=1,2,1
rejoin-eq=true
half-hi-isLone=true
half-lo-isLone=false
half-hi-cp=1f600
full-cp=1f600
spread-lens=1,2,1
spread-cps=61,1f600,62
two-split-len=2
two-spread-len=2
ffff-split=1
10000-split=1
combining-split=2
combining-spread=2
empty-split-len=0
ascii-split=a|b|c
limit=61,d83d,62
limit0-len=0
Detected on: 2026-07-20
Run: https://github.com/UrubuCode/rts/actions/runs/29724727560
claude-split-empty-separator-units— rts_divergeCategory:
other. Fixture:tests/cross-runtime/string/claude-split-empty-separator-units.tsTest code
Outputs
Bun:
Node:
RTS:
Detected on: 2026-07-20
Run: https://github.com/UrubuCode/rts/actions/runs/29724727560