| |
| |
| |
| |
| import { charIndexForByteLimit } from "../../shared/cross/semanticUtils"; |
|
|
| let passed = 0; |
| let failed = 0; |
|
|
| function assert(desc: string, actual: number, expected: number) { |
| if (actual === expected) { |
| console.log(` ✓ ${desc}`); |
| passed++; |
| } else { |
| console.error(` ✗ ${desc} — expected ${expected}, got ${actual}`); |
| failed++; |
| } |
| } |
|
|
| const enc = new TextEncoder(); |
| function bytes(s: string) { return enc.encode(s).byteLength; } |
|
|
| |
| console.log("1. 基本边界"); |
| assert("空字符串,limit=0", charIndexForByteLimit("", 0, 0), 0); |
| assert("空字符串,limit=10", charIndexForByteLimit("", 0, 10), 0); |
| assert("limit=0 时立刻停止", charIndexForByteLimit("abc", 0, 0), 0); |
| assert("limit 恰好等于全文字节数", charIndexForByteLimit("abc", 0, 3), 3); |
| assert("limit 大于全文字节数", charIndexForByteLimit("abc", 0, 100), 3); |
|
|
| |
| console.log("2. 纯 ASCII"); |
| assert("limit=1 取 1 字符", charIndexForByteLimit("hello", 0, 1), 1); |
| assert("limit=3 取 3 字符", charIndexForByteLimit("hello", 0, 3), 3); |
| assert("limit=5 取全部", charIndexForByteLimit("hello", 0, 5), 5); |
| assert("start=2,limit=2", charIndexForByteLimit("hello", 2, 2), 4); |
|
|
| |
| console.log("3. CJK 字符(3 字节/字)"); |
| const cjk = "你好世界"; |
| assert("limit=3 → 1 字符", charIndexForByteLimit(cjk, 0, 3), 1); |
| assert("limit=4 → 1 字符(中间切不开)", charIndexForByteLimit(cjk, 0, 4), 1); |
| assert("limit=6 → 2 字符", charIndexForByteLimit(cjk, 0, 6), 2); |
| assert("limit=11 → 3 字符", charIndexForByteLimit(cjk, 0, 11), 3); |
| assert("limit=12 → 4 字符", charIndexForByteLimit(cjk, 0, 12), 4); |
| assert("start=1,limit=3 → idx=2", charIndexForByteLimit(cjk, 1, 3), 2); |
|
|
| |
| console.log("4. Emoji(4 字节/字,JS charLen=2)"); |
| const emoji = "😀🎉🚀"; |
| assert("emoji limit=4 → idx=2(1 emoji)", charIndexForByteLimit(emoji, 0, 4), 2); |
| assert("emoji limit=5 → idx=2(切不开)", charIndexForByteLimit(emoji, 0, 5), 2); |
| assert("emoji limit=8 → idx=4(2 emoji)", charIndexForByteLimit(emoji, 0, 8), 4); |
| assert("emoji limit=12 → idx=6(全部)", charIndexForByteLimit(emoji, 0, 12), 6); |
| assert("emoji start=2,limit=4 → idx=4", charIndexForByteLimit(emoji, 2, 4), 4); |
|
|
| |
| console.log("5. 混合字符"); |
| |
| const mixed = "A好😀"; |
| assert("混合 limit=1 → 1(A)", charIndexForByteLimit(mixed, 0, 1), 1); |
| assert("混合 limit=3 → 1(A不够好)", charIndexForByteLimit(mixed, 0, 3), 1); |
| assert("混合 limit=4 → 2(A好)", charIndexForByteLimit(mixed, 0, 4), 2); |
| assert("混合 limit=7 → 2(不够emoji)",charIndexForByteLimit(mixed, 0, 7), 2); |
| assert("混合 limit=8 → 4(全部)", charIndexForByteLimit(mixed, 0, 8), 4); |
| assert("混合 start=1,limit=3 → 2(好)", charIndexForByteLimit(mixed, 1, 3), 2); |
|
|
| |
| console.log("6. start >= text.length"); |
| assert("start=5 on 'abc' → 5", charIndexForByteLimit("abc", 5, 10), 5); |
|
|
| |
| console.log("7. 含换行符"); |
| const nl = "a\nb\n"; |
| assert("换行 limit=2 → 2", charIndexForByteLimit(nl, 0, 2), 2); |
| assert("换行 limit=3 → 3", charIndexForByteLimit(nl, 0, 3), 3); |
|
|
| |
| console.log(`\n结果: ${passed} 通过 / ${failed} 失败`); |
| if (failed > 0) process.exit(1); |
|
|