feat(tui): 清单行表与单行替换(第一轮第五块·核心)
外科式改写的地基(ADR-0013):Get-BakNRetBackupListRow 把清单文本拆成带**行号**的行表,Get-BakNRetBackupListRow 之外的行一字节不动。行表刻意保留注释与空行 —— 只在表里放"真正的条目"会让行号错位,改一行就会连锁改掉别处。 解析器给的 Record.Raw 就是原始行文本,所以"没被编辑的行写回原样"是天然的:注释、对齐、$( ) 表达式、跨行拼接都不会被碰到。这也是它比"解析成对象再序列化"安全的地方。 行号越界**抛错**而不是静默不动:静默不动会制造"保存成功但其实没改",而用户看到的是一份以为改过、其实没改的配置。 判据是 spec 里那条往返断言的文本层形式:每行原样写回后**文本逐字节相同**;改一行时只有那一行不同、注释行数不变、原文本不被就地改动。 验收:断言 13 条;test.ps1 9/9 全绿(5.1 与 7)。
This commit is contained in:
1 parent
835fb0cf2b
commit
54972ab341
5 files changed
+110
No files matched your search
@@ -1556,6 +1556,47 @@ Test-Case '菜单循环:按数量分档验(0 项 / 1 项 / 3 项),单键
|
||||
Assert-Equal 'empty' $empty.Reason '原因标为 empty'
|
||||
}
|
||||
|
||||
Test-Case '清单行表与单行替换:只动那一行,注释与其它行逐字节不变' {
|
||||
$text = @(
|
||||
'# 注释一',
|
||||
'Edge',
|
||||
'',
|
||||
'+WindowsTerminal :encrypt',
|
||||
'# 注释二',
|
||||
'-OldApp :- logs\'
|
||||
) -join "`n"
|
||||
|
||||
# 行表必须包含注释与空行,否则行号会错位(外科式改写按行号动手)
|
||||
$rows = Get-BakNRetBackupListRow -Text $text
|
||||
Assert-Equal 6 $rows.Count '总行数'
|
||||
Assert-Equal 1 $rows[0].Line '首行行号是 1'
|
||||
Assert-True ($null -eq $rows[0].Record) '注释行不解析'
|
||||
Assert-True ($null -eq $rows[2].Record) '空行不解析'
|
||||
Assert-Equal 'Edge' $rows[1].Record.Path '第 2 行是条目'
|
||||
Assert-Equal 'backup' $rows[3].Record.Direction '第 4 行方向是 backup'
|
||||
Assert-Equal 'Edge' $rows[1].Raw 'Raw 是原始行文本'
|
||||
|
||||
# 往返:每一行原样写回 → 文本必须逐字节相同(这是"外科式"的最强形式)
|
||||
$same = $text
|
||||
foreach ($row in $rows) { $same = Set-BakNRetBackupListRow -Text $same -Line $row.Line -NewText $row.Raw }
|
||||
Assert-Equal $text $same '每行原样写回后文本逐字节相同'
|
||||
|
||||
# 改一行:只有那一行不同,注释行数不变,原文本不被就地改动
|
||||
$edited = Set-BakNRetBackupListRow -Text $text -Line 2 -NewText '-Edge'
|
||||
$before = @($text -split "`n")
|
||||
$after = @($edited -split "`n")
|
||||
Assert-Equal $before.Count $after.Count '行数不变'
|
||||
Assert-Equal '-Edge' $after[1] '第 2 行改成了 -Edge'
|
||||
Assert-Equal 2 @(Compare-Object -ReferenceObject $before -DifferenceObject $after).Count '只应当有一行不同'
|
||||
Assert-Equal 2 @($after | Where-Object { $_.Trim().StartsWith('#') }).Count '注释行数不变'
|
||||
Assert-Equal 'Edge' $before[1] '原文本没有被就地改动'
|
||||
|
||||
# 行号越界必须抛错:静默不动会让"保存成功但其实没改"发生
|
||||
$threw = $false
|
||||
try { Set-BakNRetBackupListRow -Text $text -Line 99 -NewText 'x' | Out-Null } catch { $threw = $true }
|
||||
Assert-True $threw '行号越界必须抛错'
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
Remove-Item -LiteralPath $sandbox -Recurse -Force -ErrorAction SilentlyContinue
|
||||
Remove-Item -LiteralPath $itemSandbox -Recurse -Force -ErrorAction SilentlyContinue
|
||||
|
||||
Reference in new issue
Block a user