LibreDevOpsHelpers.Pester/LibreDevOpsHelpers.Pester.psm1
############################################################################### # Assertion helper – “Should ReturnZeroExitCode” ############################################################################### function ShouldReturnZeroExitCode { [CmdletBinding()] param ( [Parameter(Mandatory)][string] $ActualValue, [switch] $Negate, [string] $Because # kept for Pester signature parity ) $inv = $MyInvocation.MyCommand.Name _LogMessage -Level 'DEBUG' -Message "Checking exit-code for: $ActualValue" -InvocationName $inv try { $result = Get-CommandResult -Command $ActualValue -ValidateExitCode:$false $succeeded = ($result.ExitCode -eq 0) if ($Negate) { $succeeded = -not $succeeded } if (-not $succeeded) { $indented = $result.Output | ForEach-Object { " $_" } | Out-String $failureMessage = "Command '`"$ActualValue`"' returned exit-code $( $result.ExitCode ). Output:`n$indented" } } catch { _LogMessage -Level 'ERROR' -Message $_.Exception.Message -InvocationName $inv $succeeded = $false $failureMessage = "Exception thrown while executing '$ActualValue' – $( $_.Exception.Message )" } [PSCustomObject]@{ Succeeded = $succeeded FailureMessage = $failureMessage } } ############################################################################### # Assertion helper – “Should MatchCommandOutput” ############################################################################### function ShouldMatchCommandOutput { [CmdletBinding()] param ( [Parameter(Mandatory)][string] $ActualValue, [Parameter(Mandatory)][string] $RegularExpression, [switch] $Negate ) $inv = $MyInvocation.MyCommand.Name _LogMessage -Level 'DEBUG' -Message "Matching output for: $ActualValue (regex = $RegularExpression)" -InvocationName $inv try { $output = (Get-CommandResult -Command $ActualValue -ValidateExitCode:$false).Output -join "`n" $succeeded = ($output -cmatch $RegularExpression) if ($Negate) { $succeeded = -not $succeeded } if (-not $succeeded) { $notText = if ($Negate) { 'not ' } else { '' } $failureMessage = "Expected '`"$ActualValue`"' output to ${notText}match regex '`"$RegularExpression`"', but it did${notText}." } } catch { _LogMessage -Level 'ERROR' -Message $_.Exception.Message -InvocationName $inv $succeeded = $false $failureMessage = "Exception thrown while executing '$ActualValue' – $( $_.Exception.Message )" } [PSCustomObject]@{ Succeeded = $succeeded FailureMessage = $failureMessage } } ############################################################################### # Helper – run a single Pester file (mirrors your logging / error style) ############################################################################### function Invoke-PesterTests { [CmdletBinding()] param ( [Parameter(Mandatory)][string] $TestFile, # without *.Tests.ps1 [string] $TestName ) $inv = $MyInvocation.MyCommand.Name $testPath = Join-Path -Path (Join-Path $PSScriptRoot '..\Tests') -ChildPath "${TestFile}.Tests.ps1" if (-not (Test-Path $testPath)) { $msg = "Unable to find test file '$TestFile' at '$testPath'." _LogMessage -Level 'ERROR' -Message $msg -InvocationName $inv throw $msg } _LogMessage -Level 'INFO' -Message "Running Pester tests in $testPath" -InvocationName $inv if (-not (Get-Module Pester)) { Import-Module Pester } $configuration = [PesterConfiguration]@{ Run = @{ Path = $testPath; PassThru = $true } Output = @{ Verbosity = 'Normal' } } if ($TestName) { $config.Filter.FullName = $TestName } # Fail hard on silent errors inside the tests $oldPref = $ErrorActionPreference $ErrorActionPreference = 'Stop' $results = Invoke-Pester -Configuration $config $ErrorActionPreference = $oldPref if (-not ($results.FailedCount -eq 0 -and $results.TotalCount -gt 0)) { _LogMessage -Level 'ERROR' -Message 'One or more tests failed.' -InvocationName $inv $results | Format-List | Out-String | _LogMessage -Level 'DEBUG' -InvocationName $inv throw 'Test run has failed.' } _LogMessage -Level 'INFO' -Message "All $( $results.PassedCount ) tests passed." -InvocationName $inv } ############################################################################### # Public surface ############################################################################### Export-ModuleMember -Function ` ShouldReturnZeroExitCode, ` ShouldMatchCommandOutput, ` Invoke-PesterTests |