feat(tui): 控制台列宽表(第一轮第一块)

整个 TUI 的地基:位置、对齐、边框都靠它。而它算错了**不会报错** —— 表现只是菜单右边框歪一点、光标偏一列,所以每条边界都在断言里钉住。

为什么必须自己算:.Length 是 UTF-16 code unit 的个数(汉字 1 个 char、2 列);而 $Host.UI.RawUI.LengthInBufferCells 在 PowerShell 7 上对、在 5.1 上错(实测 中文 返回 2、字体边框字符 返回 6),且不抛错 —— 这种"一边对一边错"的 API 比两边都错更危险。

表里三个边界是实测踩过的:半角片假名 U+FF61–FF9F 是 1 列(不能划进全角区);全角拉丁 U+FF00–FF60 是 2 列;emoji 是代理对,按一个码点算。

验收:断言 8 条(含空串与控制字符);test.ps1 9/9 全绿(5.1 与 7)。
This commit is contained in:
Shuery committed 2026-09-27 15:31:26 +08:00
1 parent 60f2ae3e0f
commit 8a0924330a
23 files changed
+86 -19

No files matched your search

+12
View File
@@ -1420,6 +1420,18 @@ Test-Case '结果汇总:分类列出成功/跳过/失败,带原因与失败
}
}
Test-Case '控制台列宽:中文 2 列、半角片假名 1 列、emoji 按一个码点算、控制字符 0 列' {
# 这张表算错了不会报错,只会让菜单右边框歪一点 —— 所以每条边界都钉一个断言。
Assert-Equal 8 (Get-BakNRetCellWidth -Text '12345678') '8 个 ASCII = 8 列'
Assert-Equal 4 (Get-BakNRetCellWidth -Text '中文') '2 个汉字 = 4 列(.Length 是 2)'
Assert-Equal 3 (Get-BakNRetCellWidth -Text ([string]::new([char[]]@(0x250C, 0x2500, 0x2510)))) '字体边框字符 = 1 列/个(5.1 的 LengthInBufferCells 在这里会返回 6)'
Assert-Equal 4 (Get-BakNRetCellWidth -Text ([string]::new([char[]]@(0xFF21, 0xFF22)))) '全角拉丁 = 2 列/个'
Assert-Equal 2 (Get-BakNRetCellWidth -Text ([string]::new([char[]]@(0xFF71, 0xFF72)))) '半角片假名 = 1 列/个(不能划进全角区)'
Assert-Equal 2 (Get-BakNRetCellWidth -Text ([char]::ConvertFromUtf32(0x1F600))) 'emoji = 一个码点 2 列'
Assert-Equal 0 (Get-BakNRetCellWidth -Text ([string]::new([char[]]@(9, 10)))) '控制字符 = 0 列'
Assert-Equal 0 (Get-BakNRetCellWidth -Text '') '空串 = 0 列'
}
# ============================================================================
Remove-Item -LiteralPath $sandbox -Recurse -Force -ErrorAction SilentlyContinue
Remove-Item -LiteralPath $itemSandbox -Recurse -Force -ErrorAction SilentlyContinue