Skip to content

Commit

Permalink
Updated to Pester v5
Browse files Browse the repository at this point in the history
  • Loading branch information
markwragg committed Sep 15, 2024
1 parent c4f1b10 commit c1fda84
Show file tree
Hide file tree
Showing 7 changed files with 200 additions and 172 deletions.
2 changes: 1 addition & 1 deletion Build/build.depend.psd1
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

# Common modules
BuildHelpers = '2.0.1'
Pester = '4.6.0'
Pester = '5.5.0'
PlatyPS = '0.12.0'
psake = '4.7.4'
PSDeploy = '1.0.1'
Expand Down
2 changes: 1 addition & 1 deletion PSHipChat/PShipchat.psd1
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
RootModule = 'PSHipchat.psm1'

# Version number of this module.
ModuleVersion = '1.0.39'
ModuleVersion = '1.0.40'

# Supported PSEditions
# CompatiblePSEditions = @()
Expand Down
5 changes: 3 additions & 2 deletions PSScriptAnalyzerSettings.psd1
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
@{
ExcludeRules = @(
'PSUseDeclaredVarsMoreThanAssignments',
'PSUseDeclaredVarsMoreThanAssignments'
'PSAvoidTrailingWhitespace'
'PSAvoidOverwritingBuiltInCmdlets'
)

Severity = @(
"Warning",
"Warning"
"Error"
)

Expand Down
183 changes: 100 additions & 83 deletions Tests/Common/Help.Tests.ps1
Original file line number Diff line number Diff line change
@@ -1,100 +1,117 @@
# Taken with love from @juneb_get_help (https://raw.githubusercontent.com/juneb/PesterTDD/master/Module.Help.Tests.ps1)
# Import module
if (-not (Get-Module -Name $env:BHProjectName -ListAvailable)) {
Import-Module -Name $env:BHPSModuleManifest -ErrorAction 'Stop' -Force

BeforeDiscovery {
function global:FilterOutCommonParams {
param ($Params)
$commonParams = @(
'Debug', 'ErrorAction', 'ErrorVariable', 'InformationAction', 'InformationVariable',
'OutBuffer', 'OutVariable', 'PipelineVariable', 'Verbose', 'WarningAction',
'WarningVariable', 'Confirm', 'Whatif', 'ProgressAction'
)
$params | Where-Object { $_.Name -notin $commonParams } | Sort-Object -Property Name -Unique
}

$env:BHProjectName = (Get-ChildItem $PSScriptRoot/../../*.psm1 -Recurse).BaseName

# Get module commands
# Remove all versions of the module from the session. Pester can't handle multiple versions.
Get-Module $env:BHProjectName | Remove-Module -Force -ErrorAction Ignore
Import-Module -Name $PSScriptRoot/../../$env:BHProjectName -Verbose:$false -ErrorAction Stop
$params = @{
Module = (Get-Module $env:BHProjectName)
CommandType = [System.Management.Automation.CommandTypes[]]'Cmdlet, Function' # Not alias
}
if ($PSVersionTable.PSVersion.Major -lt 6) {
$params.CommandType[0] += 'Workflow'
}
$commands = Get-Command @params

## When testing help, remember that help is cached at the beginning of each session.
## To test, restart session.
}
$commands = Get-Command -Module $env:BHProjectName -CommandType Cmdlet, Function, Workflow -ErrorAction 'Stop' # Not alias

## When testing help, remember that help is cached at the beginning of each session.
## To test, restart session.
foreach ($command in $commands) {
$commandName = $command.Name
AfterAll {
Remove-Item Function:/FilterOutCommonParams
Get-Module $env:BHProjectName | Remove-Module -Force -ErrorAction Ignore
}

# The module-qualified command fails on Microsoft.PowerShell.Archive cmdlets
$help = Get-Help $commandName -ErrorAction SilentlyContinue
Describe "Test help for <_.Name>" -ForEach $commands {

Describe "Test help for $commandName" {
BeforeDiscovery {
# Get command help, parameters, and links
$command = $_
$commandHelp = Get-Help $command.Name -ErrorAction SilentlyContinue
$commandParameters = global:FilterOutCommonParams -Params $command.ParameterSets.Parameters
$commandParameterNames = $commandParameters.Name
$helpLinks = $commandHelp.relatedLinks.navigationLink.uri
}

# If help is not found, synopsis in auto-generated help is the syntax diagram
It 'Should not be auto-generated' {
$help.Synopsis | Should Not BeLike '*`[`<CommonParameters`>`]*'
}
BeforeAll {
# These vars are needed in both discovery and test phases so we need to duplicate them here
$command = $_
$commandName = $_.Name
$commandHelp = Get-Help $command.Name -ErrorAction SilentlyContinue
$commandParameters = global:FilterOutCommonParams -Params $command.ParameterSets.Parameters
$commandParameterNames = $commandParameters.Name
$helpParameters = global:FilterOutCommonParams -Params $commandHelp.Parameters.Parameter
$helpParameterNames = $helpParameters.Name
}

# If help is not found, synopsis in auto-generated help is the syntax diagram
It 'Help is not auto-generated' {
$commandHelp.Synopsis | Should -Not -BeLike '*`[`<CommonParameters`>`]*'
}

# Should be a description for every function
It "Gets description for $commandName" {
$help.Description | Should Not BeNullOrEmpty
# Should be a description for every function
It "Has description" {
$commandHelp.Description | Should -Not -BeNullOrEmpty
}

# Should be at least one example
It "Has example code" {
($commandHelp.Examples.Example | Select-Object -First 1).Code | Should -Not -BeNullOrEmpty
}

# Should be at least one example description
It "Has example help" {
($commandHelp.Examples.Example.Remarks | Select-Object -First 1).Text | Should -Not -BeNullOrEmpty
}

It "Help link <_> is valid" -ForEach $helpLinks {
(Invoke-WebRequest -Uri $_ -UseBasicParsing).StatusCode | Should -Be '200'
}

Context "Parameter <_.Name>" -Foreach $commandParameters {

BeforeAll {
$parameter = $_
$parameterName = $parameter.Name
$parameterHelp = $commandHelp.parameters.parameter | Where-Object Name -eq $parameterName
$parameterHelpType = if ($parameterHelp.ParameterValue) { $parameterHelp.ParameterValue.Trim() }
}

# Should be at least one example
It "Gets example code from $commandName" {
($help.Examples.Example | Select-Object -First 1).Code | Should Not BeNullOrEmpty
# Should be a description for every parameter
It "Has description" {
$parameterHelp.Description.Text | Should -Not -BeNullOrEmpty
}

# Should be at least one example description
It "Gets example help from $commandName" {
($help.Examples.Example.Remarks | Select-Object -First 1).Text | Should Not BeNullOrEmpty
# Required value in Help should match IsMandatory property of parameter
It "Has correct [mandatory] value" {
$codeMandatory = $_.IsMandatory.toString()
$parameterHelp.Required | Should -Be $codeMandatory
}

Context "Test parameter help for $commandName" {

$common = 'Debug', 'ErrorAction', 'ErrorVariable', 'InformationAction', 'InformationVariable', 'OutBuffer',
'OutVariable', 'PipelineVariable', 'Verbose', 'WarningAction', 'WarningVariable', 'Confirm', 'Whatif'

$parameters = $command.ParameterSets.Parameters |
Sort-Object -Property Name -Unique |
Where-Object { $_.Name -notin $common }
$parameterNames = $parameters.Name

## Without the filter, WhatIf and Confirm parameters are still flagged in "finds help parameter in code" test
$helpParameters = $help.Parameters.Parameter |
Where-Object { $_.Name -notin $common } |
Sort-Object -Property Name -Unique
$helpParameterNames = $helpParameters.Name

foreach ($parameter in $parameters) {
$parameterName = $parameter.Name
$parameterHelp = $help.parameters.parameter | Where-Object Name -EQ $parameterName

# Should be a description for every parameter
It "Gets help for parameter: $parameterName : in $commandName" {
$parameterHelp.Description.Text | Should Not BeNullOrEmpty
}

# Required value in Help should match IsMandatory property of parameter
It "Help for $parameterName parameter in $commandName has correct Mandatory value" {
$codeMandatory = $parameter.IsMandatory.toString()
$parameterHelp.Required | Should Be $codeMandatory
}

# Parameter type in Help should match code
# It "help for $commandName has correct parameter type for $parameterName" {
# $codeType = $parameter.ParameterType.Name
# # To avoid calling Trim method on a null object.
# $helpType = if ($parameterHelp.parameterValue) { $parameterHelp.parameterValue.Trim() }
# $helpType | Should be $codeType
# }
}

foreach ($helpParm in $HelpParameterNames) {
# Shouldn't find extra parameters in help.
It "Finds help parameter in code: $helpParm" {
$helpParm -in $parameterNames | Should Be $true
}
}
# Parameter type in help should match code
It "Has correct parameter type" {
$parameterHelpType | Should -Be $parameter.ParameterType.Name
}
}

Context "Test <_> help parameter help for <commandName>" -Foreach $helpParameterNames {

Context "Help Links should be Valid for $commandName" {
$link = $help.relatedLinks.navigationLink.uri

foreach ($link in $links) {
if ($link) {
# Should have a valid uri if one is provided.
It "[$link] should have 200 Status Code for $commandName" {
$Results = Invoke-WebRequest -Uri $link -UseBasicParsing
$Results.StatusCode | Should Be '200'
}
}
}
# Shouldn't find extra parameters in help.
It "finds help parameter in code: <_>" {
$_ -in $parameterNames | Should -Be $true
}
}
}
}
99 changes: 52 additions & 47 deletions Tests/Common/Manifest.Tests.ps1
Original file line number Diff line number Diff line change
@@ -1,83 +1,88 @@
# Vars
$changelogPath = Join-Path -Path $env:BHProjectPath -Child 'CHANGELOG.md'
BeforeAll {
$env:BHProjectPath = Join-Path $PSScriptRoot "../../"
$env:BHProjectName = (Get-ChildItem $env:BHProjectPath -Filter '*.psm1' -Recurse).BaseName
$env:BHPSModuleManifest = (Get-ChildItem $env:BHProjectPath -Filter "${env:BHProjectName}.psd1" -Recurse).FullName

$moduleName = $env:BHProjectName
$manifest = Import-PowerShellDataFile -Path $env:BHPSModuleManifest
$outputManifestPath = Join-Path -Path (Join-Path $env:BHProjectPath $env:BHProjectName) "$($moduleName).psd1"
$manifestData = Test-ModuleManifest -Path $outputManifestPath -Verbose:$false -ErrorAction Stop -WarningAction SilentlyContinue

$changelogPath = Join-Path -Path $env:BHProjectPath -Child 'CHANGELOG.md'
$changelogVersion = Get-Content $changelogPath | ForEach-Object {
if ($_ -match "^##\s\[(?<Version>(\d+\.){1,3}\d+)\]") {
$changelogVersion = $matches.Version
break
}
}

$script:manifest = $null
}

Describe 'Module manifest' {
Context 'Validation' {

$script:manifest = $null
Context 'Validation' {

It 'Has a valid manifest' {
{
$script:manifest = Test-ModuleManifest -Path $env:BHPSModuleManifest -Verbose:$false -ErrorAction 'Stop' -WarningAction 'SilentlyContinue'
} | Should Not Throw
$manifestData | Should -Not -BeNullOrEmpty
}

It 'Has a valid name in the manifest' {
$script:manifest.Name | Should Be $env:BHProjectName
$manifestData.Name | Should -Be $moduleName
}

It 'Has a valid root module' {
$script:manifest.RootModule | Should Be "$($env:BHProjectName).psm1"
$manifestData.RootModule | Should -Be "$($moduleName).psm1"
}

It 'Has a valid version in the manifest' {
$script:manifest.Version -as [Version] | Should Not BeNullOrEmpty
$manifestData.Version -as [Version] | Should -Not -BeNullOrEmpty
}

It 'Has a valid description' {
$script:manifest.Description | Should Not BeNullOrEmpty
$manifestData.Description | Should -Not -BeNullOrEmpty
}

It 'Has a valid author' {
$script:manifest.Author | Should Not BeNullOrEmpty
$manifestData.Author | Should -Not -BeNullOrEmpty
}

It 'Has a valid guid' {
{
[guid]::Parse($script:manifest.Guid)
} | Should Not throw
{ [guid]::Parse($manifestData.Guid) } | Should -Not -Throw
}

It 'Has a valid copyright' {
$script:manifest.CopyRight | Should Not BeNullOrEmpty
$manifestData.CopyRight | Should -Not -BeNullOrEmpty
}

# Only for DSC modules
# It 'exports DSC resources' {
# $dscResources = ($Manifest.psobject.Properties | Where Name -eq 'ExportedDscResources').Value
# @($dscResources).Count | Should Not Be 0
# }

$script:changelogVersion = $null
It 'Has a valid version in the changelog' -Skip {
foreach ($line in (Get-Content $changelogPath)) {
if ($line -match "^##\s\[(?<Version>(\d+\.){1,3}\d+)\]") {
$script:changelogVersion = $matches.Version
break
}
}
$script:changelogVersion | Should Not BeNullOrEmpty
$script:changelogVersion -as [Version] | Should Not BeNullOrEmpty
It 'Has a valid version in the changelog' {
$changelogVersion | Should -Not -BeNullOrEmpty
$changelogVersion -as [Version] | Should -Not -BeNullOrEmpty
}

It 'Has matching changelog and manifest versions' -Skip {
$script:changelogVersion -as [Version] | Should be ( $script:manifest.Version -as [Version] )
It 'Changelog and manifest versions are the same' {
$changelogVersion -as [Version] | Should -Be ( $manifestData.Version -as [Version] )
}
}
}

if (Get-Command -Name 'git.exe' -ErrorAction 'SilentlyContinue') {
$script:tagVersion = $null
Describe 'Git tagging' -Skip {

BeforeAll {
$gitTagVersion = $null

# Skipped as we tag as part of CI build
It 'Is tagged with a valid version' -skip {
$thisCommit = git.exe log --decorate --oneline HEAD~1..HEAD
if ($git = Get-Command git -CommandType Application -ErrorAction SilentlyContinue) {
$thisCommit = & $git log --decorate --oneline HEAD~1..HEAD
if ($thisCommit -match 'tag:\s*(\d+(?:\.\d+)*)') { $gitTagVersion = $matches[1] }
}
}

if ($thisCommit -match 'tag:\s*(\d+(?:\.\d+)*)') {
$script:tagVersion = $matches[1]
}
It 'Is tagged with a valid version' {
$gitTagVersion | Should -Not -BeNullOrEmpty
$gitTagVersion -as [Version] | Should -Not -BeNullOrEmpty
}

$script:tagVersion | Should Not BeNullOrEmpty
$script:tagVersion -as [Version] | Should Not BeNullOrEmpty
}
}
It 'Matches manifest version' {
$manifestData.Version -as [Version] | Should -Be ( $gitTagVersion -as [Version])
}
}
}
Loading

0 comments on commit c1fda84

Please sign in to comment.