Files
BakNRet/tests/TestHelpers.psm1
Shuery 232a82cd3c style: 逐条修静态分析告警(706 → 44),并把 MaxDepth 这条假承诺删掉
修掉的:空 catch 5 处;名词白名单 7 处;default-value 开关、自带 -WhatIf、lab 的明文口令与 irm|iex 各挂抑制并写明理由。

MaxDepth:它是分析器拓出来的真 bug —— 参数声明了却从未使用,也就是配置里的 CatalogMaxDepth 是假的,前缀补全实际只查 1 层,而配置注释与 README 都承诺「向下找几层」。按确认过的原则处理:**先让文档不撒谎**,所以把整条链路去掉(配置默认值、三个函数的参数、70 处实参、配置注释),而不是留一个假旋钮。零行为变化。想真的支持多层补全时,那是一个独立决定。

剩下 3 条都是分析器的误判,而且我实测确认过其中一条:$sourcePath 被报「赋值后从未使用」,我照着改成 $null = 之后,Set-StrictMode -Version 3.0 下读未定义变量直接抛错,Security 套件的 BeforeAll 挂掉、4 条用例连带失败。恢复后才绿。

这一类误判有共同成因:静态分析看不到「在传给 Test-Case / It / Where-Object 的 scriptblock 里被使用」。所以我只对能证明是误判的挂抑制并写明理由,不为了数字好看去改代码。

验收:test.ps1 9/9 全绿(7 与 5.1)、100 个文件两版解析零错、Run-RealSmoke 4/4。
2026-09-27 10:16:10 +08:00

116 lines
3.6 KiB
PowerShell
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<#
.SYNOPSIS
BakNRet 测试用的极简断言运行器(零依赖,PS 5.1 / 7.x 通用)。
.DESCRIPTION
不用 Pester:本机只装了 3.4.0,缺少 `Should -Be` 这类 Pester 4+ 语法,
为跑几个测试去装 Pester 5 不划算。这里只需要 Test-Case + Assert-* 就够。
#>
$script:Passed = 0
$script:Failed = 0
$script:Failures = @()
function Reset-TestResult {
$script:Passed = 0
$script:Failed = 0
$script:Failures = @()
}
function Get-TestResult {
return [pscustomobject]@{
Passed = $script:Passed
Failed = $script:Failed
Failures = @($script:Failures)
}
}
function Test-Case {
param([string]$Name, [scriptblock]$Body)
try {
& $Body
$script:Passed++
Write-Host " [PASS] $Name" -ForegroundColor Green
}
catch {
$script:Failed++
$script:Failures += "$Name —— $($_.Exception.Message)"
Write-Host " [FAIL] $Name" -ForegroundColor Red
Write-Host " $($_.Exception.Message)" -ForegroundColor DarkGray
}
}
function Assert-Equal {
param($Expected, $Actual, [string]$Because)
if ($Expected -ne $Actual) {
throw ("期望 [{0}],实际 [{1}]{2}" -f $Expected, $Actual, $(if ($Because) { "($Because)" } else { '' }))
}
}
function Assert-True {
param($Condition, [string]$Because)
if (-not $Condition) { throw ("断言为真失败{0}" -f $(if ($Because) { ":$Because" } else { '' })) }
}
function Assert-False {
param($Condition, [string]$Because)
if ($Condition) { throw ("断言为假失败{0}" -f $(if ($Because) { ":$Because" } else { '' })) }
}
function Assert-Null {
param($Value, [string]$Because)
if ($null -ne $Value) {
throw ("期望为 null,实际 [{0}]{1}" -f $Value, $(if ($Because) { "($Because)" } else { '' }))
}
}
function Assert-FileExists {
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseSingularNouns', '',
Justification = '误判:规则把结尾的 s 当复数,而这里的名词是 FileExists(Exists 不是复数)。')]
param([string]$Path, [string]$Because)
if (-not (Test-Path -LiteralPath $Path)) {
throw ("文件应当存在但不存在:{0}{1}" -f $Path, $(if ($Because) { "($Because)" } else { '' }))
}
}
function Assert-FileMissing {
param([string]$Path, [string]$Because)
if (Test-Path -LiteralPath $Path) {
throw ("文件不应存在但存在:{0}{1}" -f $Path, $(if ($Because) { "($Because)" } else { '' }))
}
}
function Assert-FileHashEqual {
param([string]$ExpectedPath, [string]$ActualPath)
Assert-FileExists $ExpectedPath
Assert-FileExists $ActualPath
$a = (Get-FileHash -LiteralPath $ExpectedPath -Algorithm SHA256).Hash
$b = (Get-FileHash -LiteralPath $ActualPath -Algorithm SHA256).Hash
if ($a -ne $b) { throw ("内容不一致:{0} vs {1}" -f $ExpectedPath, $ActualPath) }
}
function Write-TestSummary {
param([string]$Title = '测试')
Write-Host ""
Write-Host ("=" * 60)
if ($script:Failed -eq 0) {
Write-Host "$Title 全部通过:$($script:Passed) 项" -ForegroundColor Green
}
else {
Write-Host "$Title 通过 $($script:Passed) 项,失败 $($script:Failed) 项" -ForegroundColor Red
foreach ($failure in $script:Failures) { Write-Host " - $failure" -ForegroundColor Red }
}
Write-Host ("=" * 60)
return $script:Failed
}
Export-ModuleMember -Function @(
'Reset-TestResult', 'Get-TestResult', 'Test-Case',
'Assert-Equal', 'Assert-True', 'Assert-False', 'Assert-Null',
'Assert-FileExists', 'Assert-FileMissing', 'Assert-FileHashEqual',
'Write-TestSummary'
)