diff --git a/pester-extensions.psm1 b/pester-extensions.psm1 index 82c40b3..2531af4 100644 --- a/pester-extensions.psm1 +++ b/pester-extensions.psm1 @@ -4,30 +4,51 @@ Pester extension that allows to run command and validate exit code .EXAMPLE "python file.py" | Should -ReturnZeroExitCode #> + +function Get-CommandResult { + param ( + [Parameter(Mandatory=$true)] + [string] $Command, + [switch] $Multiline + ) + # Bash trick to suppress and show error output because some commands write to stderr (for example, "python --version") + if ($IsWindows) { + [string[]]$stdout = & $env:comspec /c "$Command 2>&1" + } else { + $stdout = & bash -c "$Command 2>&1" + } + $exitCode = $LASTEXITCODE + return @{ + Output = If ($Multiline -eq $true) { $stdout } else { [string]$stdout } + ExitCode = $exitCode + } +} + function ShouldReturnZeroExitCode { Param( - [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] - [String]$ActualValue, - [switch]$Negate + [String] $ActualValue, + [switch] $Negate, + [string] $Because # This parameter is unused by we need it to match Pester asserts signature ) - Write-Host "Run command '${ActualValue}'" - Invoke-Expression -Command $ActualValue | ForEach-Object { Write-Host $_ } - $actualExitCode = $LASTEXITCODE + $result = Get-CommandResult $ActualValue - [bool]$succeeded = $actualExitCode -eq 0 + [bool]$succeeded = $result.ExitCode -eq 0 if ($Negate) { $succeeded = -not $succeeded } if (-not $succeeded) { - $failureMessage = "Command '${ActualValue}' has finished with exit code ${actualExitCode}" + $commandOutputIndent = " " * 4 + $commandOutput = ($result.Output | ForEach-Object { "${commandOutputIndent}${_}" }) -join "`n" + $failureMessage = "Command '${ActualValue}' has finished with exit code ${actualExitCode}`n${commandOutput}" } - return New-Object PSObject -Property @{ + return [PSCustomObject] @{ Succeeded = $succeeded FailureMessage = $failureMessage } } -Add-AssertionOperator -Name ReturnZeroExitCode ` - -Test $function:ShouldReturnZeroExitCode \ No newline at end of file +if (Get-Command -Name Add-AssertionOperator -ErrorAction SilentlyContinue) { + Add-AssertionOperator -Name ReturnZeroExitCode -InternalName ShouldReturnZeroExitCode -Test ${function:ShouldReturnZeroExitCode} +}