SCOrchDev-Exception.tests.ps1
$here = Split-Path -Parent $MyInvocation.MyCommand.Path $manifestPath = "$here\SCOrchDev-Exception.psd1" Import-Module SCOrchDev-Exception -Force Describe -Tags 'VersionChecks' 'SCOrchDev-Exception manifest' { $script:manifest = $null It 'has a valid manifest' { { $script:manifest = Test-ModuleManifest -Path $manifestPath -ErrorAction Stop -WarningAction SilentlyContinue } | Should Not Throw } It 'has a valid name in the manifest' { $script:manifest.Name | Should Be SCOrchDev-Exception } It 'has a valid guid in the manifest' { $script:manifest.Guid | Should Be '41d1dfce-c2f0-42e5-b4b0-43eac2226fcd' } It 'has a valid version in the manifest' { $script:manifest.Version -as [Version] | Should Not BeNullOrEmpty } if (Get-Command git.exe -ErrorAction SilentlyContinue) { $script:tagVersion = $null It 'is tagged with a valid version' { $cwd = get-location Set-Location ($Path -as [System.IO.FileInfo]).Directory $thisCommit = git.exe log --decorate --oneline HEAD~1..HEAD Set-Location $cwd if ($thisCommit -match 'tag:\s*(\d+(?:\.\d+)*)') { $script:tagVersion = $matches[1] } $script:tagVersion | Should Not BeNullOrEmpty $script:tagVersion -as [Version] | Should Not BeNullOrEmpty } It 'all versions are the same' { $script:manifest.Version -as [Version] | Should be ( $script:tagVersion -as [Version] ) } } It 'should have all files listed in the FileList' { $ModuleFiles = (Get-ChildItem -Path $here -Recurse -Exclude .git).FullName $FileDifferences = Compare-Object -ReferenceObject $ModuleFiles -DifferenceObject $script:manifest.FileList if (($FileDifferences -as [array]).Count -gt 0) { Throw-Exception -Type 'MissingFiles' ` -Message 'Files missing or not tracked in FileList' ` -Property @{ 'Missing Files' = ($FileDifferences | Where-Object {$_.SideIndicator -eq '=>'}).InputObject ; 'Non Tracked Files' = ($FileDifferences | Where-Object {$_.SideIndicator -eq '<='}).InputObject ; } } } } if ($PSVersionTable.PSVersion.Major -ge 3) { $error.Clear() Describe 'Clean treatment of the $error variable' { Context 'A Context' { It 'Performs a successful test' { $true | Should Be $true } } It 'Did not add anything to the $error variable' { $error.Count | Should Be 0 } } } Describe 'Style rules' { $SCOrchDevExceptionRoot = (Get-Module SCOrchDev-Exception).ModuleBase $files = @( Get-ChildItem $SCOrchDevExceptionRoot -Include *.ps1,*.psm1 ) It 'Module source files contain no trailing whitespace' { $badLines = @( foreach ($file in $files) { $lines = [System.IO.File]::ReadAllLines($file.FullName) $lineCount = $lines.Count for ($i = 0; $i -lt $lineCount; $i++) { if ($lines[$i] -match '\s+$') { 'File: {0}, Line: {1}' -f $file.FullName, ($i + 1) } } } ) if ($badLines.Count -gt 0) { throw "The following $($badLines.Count) lines contain trailing whitespace: `r`n`r`n$($badLines -join "`r`n")" } } It 'Module Source Files all end with a newline' { $badFiles = @( foreach ($file in $files) { $string = [System.IO.File]::ReadAllText($file.FullName) if ($string.Length -gt 0 -and $string[-1] -ne "`n") { $file.FullName } } ) if ($badFiles.Count -gt 0) { throw "The following files do not end with a newline: `r`n`r`n$($badFiles -join "`r`n")" } } } Describe 'Select-CustomException'{ $ExceptionOutput = '{"__CUSTOM_EXCEPTION__":true,"InnerException":null,"Message":"a","FullyQualifiedErrorId":"a","Type":"a"}' Context 'PSScript' { Function Test-SelectCustomException { try { Throw-Exception -Type 'a' -Message 'a' } catch { Select-CustomException -Exception $_ } } Function Test-SelectNonCustomException { try { Throw 'a' } catch { Select-CustomException -Exception $_ } } It 'Should Detect custom exceptions' { Test-SelectCustomException | Should Be $ExceptionOutput } It 'Should ignore non custom exceptions' { Test-SelectNonCustomException | Should BeNullOrEmpty } } Context 'PSWorkflow' { Workflow Test-SelectCustomException { try { Throw-Exception -Type 'a' -Message 'a' } catch { Select-CustomException -Exception $_ } } Workflow Test-SelectNonCustomException { try { Throw 'a' } catch { Select-CustomException -Exception $_ } } It 'Should Detect custom exceptions' { Test-SelectCustomException | Should Be $ExceptionOutput } It 'Should ignore non custom exceptions' { Test-SelectNonCustomException | Should BeNullOrEmpty } } } Describe 'Get ExceptionInfo' { Context 'PSScript' { $Message = 'a' $Type = 'b' Function Test-GetExceptionInfoCustomException { Param($Message, $Type) try { Throw-Exception -Type $Type -Message $Message } catch { Get-ExceptionInfo -Exception $_ | ConvertTo-JSON -Compress } } Function Test-GetExceptionInfoNonCustomException { Param($Message) try { Throw $Message } catch { Get-ExceptionInfo -Exception $_ | ConvertTo-JSON -Compress } } It 'Custom Exceptions should retain the mesage thrown when intertpreted by Get-ExceptionInfo' { (Test-GetExceptionInfoCustomException -Message $Message -Type $Type | ConvertFrom-JSON).Message | Should Be $Message } It 'Custom Exceptions should retain their type when intertpreted by Get-ExceptionInfo' { (Test-GetExceptionInfoCustomException -Message $Message -Type $Type | ConvertFrom-JSON).Type | Should Be $Type } It 'Non Custom Exceptions should retain the mesage thrown when intertpreted by Get-ExceptionInfo' { (Test-GetExceptionInfoNonCustomException -Message $Message | ConvertFrom-JSON).Message | Should Be $Message } } Context 'PSWorkflow' { $Message = 'a' $Type = 'b' Workflow Test-GetExceptionInfoCustomException { Param($Message, $Type) try { Throw-Exception -Type $Type -Message $Message } catch { Get-ExceptionInfo -Exception $_ | ConvertTo-JSON -Compress } } Workflow Test-GetExceptionInfoNonCustomException { Param($Message) try { Throw $Message } catch { Get-ExceptionInfo -Exception $_ | ConvertTo-JSON -Compress } } It 'Custom Exceptions should retain the mesage thrown when intertpreted by Get-ExceptionInfo' { (Test-GetExceptionInfoCustomException -Message $Message -Type $Type | ConvertFrom-JSON).Message | Should Be $Message } It 'Custom Exceptions should retain their type when intertpreted by Get-ExceptionInfo' { (Test-GetExceptionInfoCustomException -Message $Message -Type $Type | ConvertFrom-JSON).Type | Should Be $Type } It 'Non Custom Exceptions should retain the mesage thrown when intertpreted by Get-ExceptionInfo' { (Test-GetExceptionInfoNonCustomException -Message $Message | ConvertFrom-JSON).Message | Should Be $Message } } } Describe 'Write-Exception' { InModuleScope ScorchDev-Exception { Mock Write-Warning { Param( $Message ) 'Warning' } Mock Write-Verbose { Param( $Message ) 'Verbose' } Mock Write-Error { Param( $Message ) 'Error' } Mock Write-Debug { Param( $Message ) 'Debug' } -ParameterFilter { $Message -like 'Exception information*' } Context 'PowerShell Script' { Function Test-WriteException { Param($ExceptionType, $ExceptionMessage, $ExceptionProperty, $Stream) Try { Throw-Exception -Type 'a' -Message 'b' } Catch { if($Stream -as [bool]) { Write-Exception -Exception $_ -Stream $Stream } else { Write-Exception -Exception $_ } } } It 'Should write to the warning stream properly'{ Test-WriteException @TestParams -Stream Warning | Should Be 'Warning' } It 'Should write to the verbose stream properly'{ Test-WriteException @TestParams -Stream Verbose | Should Be 'Verbose' } It 'Should write to the debug stream properly'{ Test-WriteException @TestParams -Stream Debug | Should Be 'Debug' } It 'Should write to the error stream properly'{ Test-WriteException @TestParams -Stream Error | Should Be 'Error' } It 'Should write to the warning stream if no stream is specified'{ Test-WriteException @TestParams | Should Be 'Warning' } } } } |