feat(tui): 读键归一化与 -InputScript 输入缝(第一轮第二块)

三层拆开,让唯一能无控制台测试的那层露出来:Get-BakNRetKeyName 纯映射(键码→键名)、New-BakNRetInputDriver 造驱动对象、Read-BakNRetKey 取下一个键。门禁把方向键/回车/空格/字母全钉住,只把"真的读到一个键"留给人工。

两条"不猜"的设计:序列用尽必须抛错(绝不退回去读真终端 —— 门禁挂起比变红糟得多);没有控制台也没有序列时不返回任何默认键(没人按键却继续执行,在备份工具里等于替你做了决定)。

这块连撞三个"看起来该有值、其实是空的"坑,全被"绿了才提交"拦在提交之外:① 键名少写冒号;② @($null) 造出含 $null 的单元素数组,"空序列"被当成"有一个键",且两版本表现不同(7 静默返回、5.1 抛错);③ **多行插入时换行被折成空格**,于是注释与 `Script = $scriptKeys` 一起落进同一行注释,那条赋值从未执行 —— 症状是"对象一个属性都没有"。教训:往文件里插多行代码不能靠拼接字符串,写文件就整份重写。

验收:断言 15 条(含驱动序列消费与两条必须报错);两版本手工输出一致;test.ps1 9/9 全绿。
This commit is contained in:
Shuery committed 2026-09-27 15:49:20 +08:00
1 parent 8a0924330a
commit f2959a4279
6 files changed
+145

No files matched your search

+33
View File
@@ -1432,6 +1432,39 @@ Test-Case '控制台列宽:中文 2 列、半角片假名 1 列、emoji 按一
Assert-Equal 0 (Get-BakNRetCellWidth -Text '') '空串 = 0 列'
}
Test-Case '按键归一化与输入缝:映射可无控制台测,序列用尽必须报错而不是挂起' {
# 纯映射:整个 TUI 里唯一能无控制台测的部分,所以每条路径都钉住。
Assert-Equal 'Up' (Get-BakNRetKeyName -VirtualKeyCode 38) '上'
Assert-Equal 'Down' (Get-BakNRetKeyName -VirtualKeyCode 40) '下'
Assert-Equal 'Left' (Get-BakNRetKeyName -VirtualKeyCode 37) '左'
Assert-Equal 'Right' (Get-BakNRetKeyName -VirtualKeyCode 39) '右'
Assert-Equal 'Enter' (Get-BakNRetKeyName -VirtualKeyCode 13) '回车'
Assert-Equal 'Esc' (Get-BakNRetKeyName -VirtualKeyCode 27) 'Esc'
Assert-Equal 'Space' (Get-BakNRetKeyName -VirtualKeyCode 32) '空格'
Assert-Equal 'Char:k' (Get-BakNRetKeyName -VirtualKeyCode 75 -Character 'K') '字母统一成小写,且带冒号前缀'
Assert-Equal 'Unknown255' (Get-BakNRetKeyName -VirtualKeyCode 255) '未知键也要有稳定名字,不能返回空'
# 驱动:按序列顺序消费(这一条曾经因为 Script 被折进注释而静默变成"没有序列")
$driver = New-BakNRetInputDriver -Script @('Down', 'Enter')
Assert-Equal 2 $driver.Script.Count '驱动里应当有两个键'
Assert-Equal 'Down' (Read-BakNRetKey -Driver $driver) '第一个键'
Assert-Equal 'Enter' (Read-BakNRetKey -Driver $driver) '第二个键'
# 关键一条:序列用尽必须失败。门禁里挂起比变红糟得多,而"退回去读真终端"正是挂起的成因。
$threw = $false
try { Read-BakNRetKey -Driver $driver | Out-Null } catch { $threw = $true }
Assert-True $threw '按键序列用尽后必须抛错'
# 另一个"不猜"的路径:没有控制台也没有序列时,不能静默返回一个默认键
$threw2 = $false
try {
$driver2 = New-BakNRetInputDriver -NonInteractive
Assert-Equal 0 $driver2.Script.Count '空序列必须是 0 个元素(不能是含 $null 的单元素数组)'
Read-BakNRetKey -Driver $driver2 | Out-Null
} catch { $threw2 = $true }
Assert-True $threw2 '没有任何输入来源时必须抛错'
}
# ============================================================================
Remove-Item -LiteralPath $sandbox -Recurse -Force -ErrorAction SilentlyContinue
Remove-Item -LiteralPath $itemSandbox -Recurse -Force -ErrorAction SilentlyContinue