feat(tui): 菜单状态机(第一轮第四块·上)
把菜单拆成"纯状态机 + 薄渲染":状态机进断言,渲染只需人肉看长相。规则:Up/k 上移、Down/j 下移、到头绕回;Space 只切换当前项(单选模式无效);Enter=confirm、Esc=cancel;返回新对象而不就地改(状态属于调用方,ADR-0011)。 特别钉住空菜单:第一次使用时归档目录就是空的,菜单打开就是空菜单 —— 方向键与空格都不该抛错,只有 Esc 能退出。这类"初始状态为空"的路径最容易在真终端里才被发现,而那时已经晚了。 验收:断言 16 条;两版手工输出一致;test.ps1 9/9 全绿。
This commit is contained in:
1 parent
d9d7967e64
commit
347959d677
4 files changed
+101
No files matched your search
@@ -1490,6 +1490,36 @@ Test-Case 'TUI 文本对齐:按列宽补齐/裁剪,绝不切开宽字符,
|
||||
Assert-True (-not $threw) '没有控制台且坐标越界时也不能抛错(TUI 画得难看,好过运行失败)'
|
||||
}
|
||||
|
||||
Test-Case '菜单状态机:绕回、空格切换、确认/取消、空菜单不崩' {
|
||||
$items = @([pscustomobject]@{ Key = 'a' }, [pscustomobject]@{ Key = 'b' }, [pscustomobject]@{ Key = 'c' })
|
||||
|
||||
# 到头绕回(菜单短的时候比夹住好用)
|
||||
Assert-Equal 2 (Update-BakNRetMenuState -Items $items -Index 0 -Key 'Up').Index '从第一个往上绕到最后一个'
|
||||
Assert-Equal 0 (Update-BakNRetMenuState -Items $items -Index 2 -Key 'Down').Index '从最后一个往下绕回第一个'
|
||||
Assert-Equal 1 (Update-BakNRetMenuState -Items $items -Index 0 -Key 'Down').Index '往下走一格'
|
||||
Assert-Equal 2 (Update-BakNRetMenuState -Items $items -Index 0 -Key 'Char:k').Index 'vim 的 k = 上'
|
||||
Assert-Equal 1 (Update-BakNRetMenuState -Items $items -Index 0 -Key 'Char:j').Index 'vim 的 j = 下'
|
||||
|
||||
# 空格只切换当前项,再按一次取消
|
||||
$s1 = Update-BakNRetMenuState -Items $items -Index 1 -Key 'Space'
|
||||
Assert-Equal 1 @($s1.Checked.Keys).Count '勾选一项'
|
||||
Assert-True $s1.Checked.ContainsKey('b') '勾的是当前项'
|
||||
$s2 = Update-BakNRetMenuState -Items $items -Index 1 -Key 'Space' -Checked $s1.Checked
|
||||
Assert-Equal 0 @($s2.Checked.Keys).Count '再按一次取消勾选'
|
||||
Assert-Equal 0 @(Update-BakNRetMenuState -Items $items -Index 0 -Key 'Space' -MultiSelect $false).Checked.Keys.Count '单选模式下空格不勾选'
|
||||
|
||||
# 确认 / 取消 / 其它键
|
||||
Assert-Equal 'confirm' (Update-BakNRetMenuState -Items $items -Key 'Enter').Action '回车 = 确认'
|
||||
Assert-Equal 'cancel' (Update-BakNRetMenuState -Items $items -Key 'Esc').Action 'Esc = 取消'
|
||||
Assert-Equal 'none' (Update-BakNRetMenuState -Items $items -Key 'Char:z').Action '别的键什么都不做'
|
||||
|
||||
# 空菜单:第一次使用时归档目录就是空的,打开菜单不该崩
|
||||
$empty = @()
|
||||
Assert-Equal 0 (Update-BakNRetMenuState -Items $empty -Key 'Down').Index '空菜单按方向键不抛错'
|
||||
Assert-Equal 0 @(Update-BakNRetMenuState -Items $empty -Key 'Space').Checked.Keys.Count '空菜单按空格不抛错'
|
||||
Assert-Equal 'cancel' (Update-BakNRetMenuState -Items $empty -Key 'Esc').Action '空菜单仍然能退出'
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
Remove-Item -LiteralPath $sandbox -Recurse -Force -ErrorAction SilentlyContinue
|
||||
Remove-Item -LiteralPath $itemSandbox -Recurse -Force -ErrorAction SilentlyContinue
|
||||
|
||||
Reference in new issue
Block a user