From e6ac2a09f6d4587dcfb7ab37853eae21a3ce702e Mon Sep 17 00:00:00 2001 From: Jeffery Date: Fri, 26 Jun 2026 15:21:45 +0800 Subject: [PATCH] =?UTF-8?q?test(calculate-version):=20=E8=A3=9C=20truncate?= =?UTF-8?q?String=20=E5=A4=9A=E4=BD=8D=E5=85=83=E7=B5=84=E5=AD=97=E5=85=83?= =?UTF-8?q?=E6=88=AA=E6=96=B7=E6=B8=AC=E8=A9=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新增以 emoji(代理對)驗證截斷不拆分多位元組字元、不殘留落單代理碼元的測試。 Co-Authored-By: Claude Opus 4.8 (1M context) --- app/test/releases.test.js | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/app/test/releases.test.js b/app/test/releases.test.js index 3f24e04..e9a7c2c 100644 --- a/app/test/releases.test.js +++ b/app/test/releases.test.js @@ -3,7 +3,7 @@ const test = require('node:test'); const assert = require('node:assert/strict'); -const { fetchReleases } = require('../releases'); +const { fetchReleases, truncateString } = require('../releases'); // 以可控的假回應替換全域 fetch,並於結束後還原 function withFetch(handler, run) { @@ -77,6 +77,15 @@ test('fetchReleases 對無法解析的 JSON 回應拋錯', async () => { ); }); +test('truncateString 以字元截斷且不拆分多位元組字元(emoji 代理對)', () => { + const emojis = '😀'.repeat(25); + const result = truncateString(emojis, 10); + // 應得到完整 10 個 emoji(以 code point 計),不殘留落單的代理碼元 + assert.equal(Array.from(result).length, 10); + assert.equal(result, '😀'.repeat(10)); + assert.ok(!/[\uD800-\uDBFF](?![\uDC00-\uDFFF])/.test(result), '不應殘留落單的高代理碼元'); +}); + test('fetchReleases 解析失敗時截斷過長的回應片段', async () => { const huge = `{${'x'.repeat(5000)}`; await withFetch(