Skip to content

Commit b859b5e

Browse files
committed
Refactor tests
1 parent 638b837 commit b859b5e

File tree

6 files changed

+216
-182
lines changed

6 files changed

+216
-182
lines changed

tests/Help.tests.ps1

Lines changed: 94 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -1,101 +1,117 @@
11
# Taken with love from @juneb_get_help (https://raw.githubusercontent.com/juneb/PesterTDD/master/Module.Help.Tests.ps1)
22

3-
Describe 'Help' {
4-
Set-BuildEnvironment -Force
5-
$moduleName = $env:BHProjectName
6-
$manifest = Import-PowerShellDataFile -Path $env:BHPSModuleManifest
7-
$outputDir = [IO.Path]::Combine($env:BHProjectPath, 'Output')
8-
$outputModDir = [IO.Path]::Combine($outputDir, $env:BHProjectName)
9-
$outputModVerDir = [IO.Path]::Combine($outputModDir, $manifest.ModuleVersion)
10-
$outputManifestPath = [IO.Path]::Combine($outputModVerDir, "$($moduleName).psd1")
11-
Import-Module $outputManifestPath
12-
$testCases = Get-Command -Module $env:BHProjectName -CommandType Cmdlet, Function | ForEach-Object {
13-
@{
14-
Name = $_.Name
15-
Command = $_
16-
}
3+
BeforeDiscovery {
4+
5+
function script:FilterOutCommonParams {
6+
param ($Params)
7+
$commonParams = @(
8+
'Debug', 'ErrorAction', 'ErrorVariable', 'InformationAction', 'InformationVariable',
9+
'OutBuffer', 'OutVariable', 'PipelineVariable', 'Verbose', 'WarningAction',
10+
'WarningVariable', 'Confirm', 'Whatif'
11+
)
12+
$params | Where-Object { $_.Name -notin $commonParams } | Sort-Object -Property Name -Unique
13+
}
14+
15+
$manifest = Import-PowerShellDataFile -Path $env:BHPSModuleManifest
16+
$outputDir = Join-Path -Path $env:BHProjectPath -ChildPath 'Output'
17+
$outputModDir = Join-Path -Path $outputDir -ChildPath $env:BHProjectName
18+
$outputModVerDir = Join-Path -Path $outputModDir -ChildPath $manifest.ModuleVersion
19+
$outputModVerManifest = Join-Path -Path $outputModVerDir -ChildPath "$($env:BHProjectName).psd1"
20+
21+
# Get module commands
22+
# Remove all versions of the module from the session. Pester can't handle multiple versions.
23+
Get-Module $env:BHProjectName | Remove-Module -Force -ErrorAction Ignore
24+
Import-Module -Name $outputModVerManifest -Verbose:$false -ErrorAction Stop
25+
$params = @{
26+
Module = (Get-Module $env:BHProjectName)
27+
CommandType = [System.Management.Automation.CommandTypes[]]'Cmdlet, Function' # Not alias
28+
}
29+
if ($PSVersionTable.PSVersion.Major -lt 6) {
30+
$params.CommandType[0] += 'Workflow'
31+
}
32+
$commands = Get-Command @params
33+
34+
## When testing help, remember that help is cached at the beginning of each session.
35+
## To test, restart session.
36+
}
37+
38+
Describe "Test help for <_.Name>" -ForEach $commands {
39+
40+
BeforeDiscovery {
41+
# Get command help, parameters, and links
42+
$command = $_
43+
$commandHelp = Get-Help $command.Name -ErrorAction SilentlyContinue
44+
$commandParameters = script:FilterOutCommonParams -Params $command.ParameterSets.Parameters
45+
$commandParameterNames = $commandParameters.Name
46+
$helpLinks = $commandHelp.relatedLinks.navigationLink.uri
1747
}
1848

1949
BeforeAll {
20-
$commonParameters = 'Debug', 'ErrorAction', 'ErrorVariable', 'InformationAction', 'InformationVariable', 'OutBuffer',
21-
'OutVariable', 'PipelineVariable', 'Verbose', 'WarningAction', 'WarningVariable', 'Confirm', 'Whatif'
50+
# These vars are needed in both discovery and test phases so we need to duplicate them here
51+
$command = $_
52+
$commandName = $_.Name
53+
$commandHelp = Get-Help $command.Name -ErrorAction SilentlyContinue
54+
$commandParameters = script:FilterOutCommonParams -Params $command.ParameterSets.Parameters
55+
$commandParameterNames = $commandParameters.Name
56+
$helpParameters = script:FilterOutCommonParams -Params $commandHelp.Parameters.Parameter
57+
$helpParameterNames = $helpParameters.Name
58+
}
59+
60+
# If help is not found, synopsis in auto-generated help is the syntax diagram
61+
It 'Help is not auto-generated' {
62+
$commandHelp.Synopsis | Should -Not -BeLike '*`[`<CommonParameters`>`]*'
2263
}
2364

24-
# No auto-generated help
25-
Context 'Auto-generation' {
26-
it 'Help for [<Name>] should not be auto-generated' -TestCases $testCases {
27-
param($Name, $Command)
65+
# Should be a description for every function
66+
It "Has description" {
67+
$commandHelp.Description | Should -Not -BeNullOrEmpty
68+
}
2869

29-
$help = Get-Help $Name -ErrorAction SilentlyContinue
30-
$help.Synopsis | Should -Not -BeLike '*`[`<CommonParameters`>`]*'
31-
}
70+
# Should be at least one example
71+
It "Has example code" {
72+
($commandHelp.Examples.Example | Select-Object -First 1).Code | Should -Not -BeNullOrEmpty
73+
}
74+
75+
# Should be at least one example description
76+
It "Has example help" {
77+
($commandHelp.Examples.Example.Remarks | Select-Object -First 1).Text | Should -Not -BeNullOrEmpty
3278
}
3379

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

35-
# Should have a description for every function
36-
Context 'Help description' {
37-
It 'Help for [<Name>] has a description' -TestCases $testCases {
38-
param($Name, $Command)
84+
Context "Parameter <_.Name>" -Foreach $commandParameters {
3985

40-
$help = Get-Help $Name -ErrorAction SilentlyContinue
41-
$help.Description | Should -Not -BeNullOrEmpty
86+
BeforeAll {
87+
$parameter = $_
88+
$parameterName = $parameter.Name
89+
$parameterHelp = $commandHelp.parameters.parameter | Where-Object Name -eq $parameterName
90+
$parameterHelpType = if ($parameterHelp.ParameterValue) { $parameterHelp.ParameterValue.Trim() }
4291
}
43-
}
4492

45-
# Should be at least one example per command
46-
Context 'Examples' {
47-
It 'Help for [<Name>] has example code' -TestCases $testCases {
48-
param($Name, $Command)
93+
# Should be a description for every parameter
94+
It "Has description" {
95+
$parameterHelp.Description.Text | Should -Not -BeNullOrEmpty
96+
}
4997

50-
$help = Get-Help $Name -ErrorAction SilentlyContinue
51-
($help.Examples.Example | Select-Object -First 1).Code | Should -Not -BeNullOrEmpty
98+
# Required value in Help should match IsMandatory property of parameter
99+
It "Has correct [mandatory] value" {
100+
$codeMandatory = $_.IsMandatory.toString()
101+
$parameterHelp.Required | Should -Be $codeMandatory
52102
}
53-
}
54103

55-
# Parameter help
56-
Context 'Parameter help' {
57-
It '[<Name>] has help for every parameter' -TestCases $testCases {
58-
param($Name, $Command)
59-
60-
$help = Get-Help $Name -ErrorAction SilentlyContinue
61-
$parameters = $Command.ParameterSets.Parameters |
62-
Sort-Object -Property Name -Unique |
63-
Where-Object { $_.Name -notin $commonParameters }
64-
$parameterNames = $parameters.Name
65-
66-
# Without the filter, WhatIf and Confirm parameters are still flagged in "finds help parameter in code" test
67-
$helpParameters = $help.Parameters.Parameter |
68-
Where-Object { $_.Name -notin $commonParameters } |
69-
Sort-Object -Property Name -Unique
70-
$helpParameterNames = $helpParameters.Name
71-
72-
foreach ($parameter in $parameters) {
73-
$parameterName = $parameter.Name
74-
$parameterHelp = $help.parameters.parameter | Where-Object Name -eq $parameterName
75-
$parameterHelp.Description.Text | Should -Not -BeNullOrEmpty
76-
77-
$codeMandatory = $parameter.IsMandatory.toString()
78-
$parameterHelp.Required | Should -Be $codeMandatory
79-
80-
$codeType = $parameter.ParameterType.Name
81-
# To avoid calling Trim method on a null object.
82-
$helpType = if ($parameterHelp.parameterValue) { $parameterHelp.parameterValue.Trim() }
83-
$helpType | Should -Be $codeType
84-
}
104+
# Parameter type in help should match code
105+
It "Has correct parameter type" {
106+
$parameterHelpType | Should -Be $parameter.ParameterType.Name
85107
}
86108
}
87109

88-
# Links are valid
89-
Context 'Links' {
90-
It 'Help for [<Name>] has valid links' -TestCases $testCases {
91-
param($Name, $Command)
92-
93-
$help = Get-Help $Name -ErrorAction SilentlyContinue
94-
$link = $help.relatedLinks.navigationLink.uri
95-
foreach ($link in $links) {
96-
$Results = Invoke-WebRequest -Uri $link -UseBasicParsing
97-
$Results.StatusCode | Should -Be '200'
98-
}
110+
Context "Test <_> help parameter help for <commandName>" -Foreach $helpParameterNames {
111+
112+
# Shouldn't find extra parameters in help.
113+
It "finds help parameter in code: <_>" {
114+
$_ -in $parameterNames | Should -Be $true
99115
}
100116
}
101117
}

tests/IBTasks.tests.ps1

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,21 @@ Describe 'Invoke-Build Tasks' {
1414
It 'IB.tasks.ps1 exists' {
1515
Test-Path $IBTasksFilePath | Should -Be $true
1616
}
17+
1718
It 'Parseable by invoke-build' {
18-
#Invoke-Build whatif still outputs in Appveyor in Pester even when directed to out-null. This doesn't happen locally. Redirecting all output to null
19-
Invoke-Build -file $IBTasksFilePath -whatif -result IBTasksResult -ErrorAction Stop *>$null
19+
# Run IB in job to not pollute the environment
20+
# Invoke-Build whatif still outputs in Appveyor in Pester even when directed to out-null. This doesn't happen locally. Redirecting all output to null
21+
$IBTasksResult = Start-Job -ScriptBlock {
22+
Invoke-Build -File $using:IBTasksFilePath -Whatif -Result IBTasksResult -ErrorAction Stop *>$null
23+
$IBTasksResult
24+
} | Wait-Job | Receive-Job
25+
2026
$IBTasksResult | Should -Not -BeNullOrEmpty
2127
}
2228
It 'Contains all the tasks that were in the Psake file' {
23-
#Invoke-PSake Fails in Pester Scope, have to run it in a completely separate runspace
29+
# Run psake in job to not pollute the environment
2430
$psakeTaskNames = Start-Job -ScriptBlock {
25-
Invoke-PSake -docs -buildfile $USING:psakeFilePath | Where-Object name -notmatch '^(default|\?)$' | ForEach-Object name
31+
Invoke-PSake -docs -buildfile $using:psakeFilePath | Where-Object name -notmatch '^(default|\?)$' | ForEach-Object name
2632
} | Wait-Job | Receive-Job
2733

2834
$IBTaskNames = $IBTasksResult.all.name

tests/Manifest.tests.ps1

Lines changed: 57 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,89 +1,86 @@
1-
Describe 'Module manifest' {
2-
3-
BeforeAll {
4-
Set-BuildEnvironment -Force
5-
6-
$moduleName = $env:BHProjectName
7-
$manifest = Import-PowerShellDataFile -Path $env:BHPSModuleManifest
8-
$outputDir = [IO.Path]::Combine($env:BHProjectPath, 'Output')
9-
$outputModDir = [IO.Path]::Combine($outputDir, $env:BHProjectName)
10-
$outputModVerDir = [IO.Path]::Combine($outputModDir, $manifest.ModuleVersion)
11-
$outputManifestPath = [IO.Path]::Combine($outputModVerDir, "$($moduleName).psd1")
12-
$changelogPath = [IO.Path]::Combine($env:BHProjectPath, 'CHANGELOG.md')
1+
BeforeAll {
2+
Set-BuildEnvironment -Force
3+
$moduleName = $env:BHProjectName
4+
$manifest = Import-PowerShellDataFile -Path $env:BHPSModuleManifest
5+
$outputDir = Join-Path -Path $ENV:BHProjectPath -ChildPath 'Output'
6+
$outputModDir = Join-Path -Path $outputDir -ChildPath $env:BHProjectName
7+
$outputModVerDir = Join-Path -Path $outputModDir -ChildPath $manifest.ModuleVersion
8+
$outputManifestPath = Join-Path -Path $outputModVerDir -Child "$($moduleName).psd1"
9+
$manifestData = Test-ModuleManifest -Path $outputManifestPath -Verbose:$false -ErrorAction Stop -WarningAction SilentlyContinue
10+
11+
$changelogPath = Join-Path -Path $env:BHProjectPath -Child 'CHANGELOG.md'
12+
$changelogVersion = Get-Content $changelogPath | ForEach-Object {
13+
if ($_ -match "^##\s\[(?<Version>(\d+\.){1,3}\d+)\]") {
14+
$changelogVersion = $matches.Version
15+
break
16+
}
1317
}
1418

15-
Context 'Validation' {
19+
$script:manifest = $null
20+
}
21+
Describe 'Module manifest' {
1622

17-
$script:manifest = $null
23+
Context 'Validation' {
1824

19-
It 'has a valid manifest' {
20-
{
21-
$script:manifest = Test-ModuleManifest -Path $outputManifestPath -Verbose:$false -ErrorAction Stop -WarningAction SilentlyContinue
22-
} | Should -Not -Throw
25+
It 'Has a valid manifest' {
26+
$manifestData | Should -Not -BeNullOrEmpty
2327
}
2428

25-
It 'has a valid name in the manifest' {
26-
$script:manifest.Name | Should -Be $env:BHProjectName
29+
It 'Has a valid name in the manifest' {
30+
$manifestData.Name | Should -Be $moduleName
2731
}
2832

29-
It 'has a valid root module' {
30-
$script:manifest.RootModule | Should -Be "$($moduleName).psm1"
33+
It 'Has a valid root module' {
34+
$manifestData.RootModule | Should -Be "$($moduleName).psm1"
3135
}
3236

33-
It 'has a valid version in the manifest' {
34-
$script:manifest.Version -as [Version] | Should -Not -BeNullOrEmpty
37+
It 'Has a valid version in the manifest' {
38+
$manifestData.Version -as [Version] | Should -Not -BeNullOrEmpty
3539
}
3640

37-
It 'has a valid description' {
38-
$script:manifest.Description | Should -Not -BeNullOrEmpty
41+
It 'Has a valid description' {
42+
$manifestData.Description | Should -Not -BeNullOrEmpty
3943
}
4044

41-
It 'has a valid author' {
42-
$script:manifest.Author | Should -Not -BeNullOrEmpty
45+
It 'Has a valid author' {
46+
$manifestData.Author | Should -Not -BeNullOrEmpty
4347
}
4448

45-
It 'has a valid guid' {
46-
{
47-
[guid]::Parse($script:manifest.Guid)
48-
} | Should -Not -Throw
49+
It 'Has a valid guid' {
50+
{[guid]::Parse($manifestData.Guid)} | Should -Not -Throw
4951
}
5052

51-
It 'has a valid copyright' {
52-
$script:manifest.CopyRight | Should -Not -BeNullOrEmpty
53+
It 'Has a valid copyright' {
54+
$manifestData.CopyRight | Should -Not -BeNullOrEmpty
5355
}
5456

55-
$script:changelogVersion = $null
56-
It 'has a valid version in the changelog' {
57-
foreach ($line in (Get-Content $changelogPath)) {
58-
if ($line -match "^##\s\[(?<Version>(\d+\.){1,3}\d+)\]") {
59-
$script:changelogVersion = $matches.Version
60-
break
61-
}
62-
}
63-
$script:changelogVersion | Should -Not -BeNullOrEmpty
64-
$script:changelogVersion -as [Version] | Should -Not -BeNullOrEmpty
57+
It 'Has a valid version in the changelog' {
58+
$changelogVersion | Should -Not -BeNullOrEmpty
59+
$changelogVersion -as [Version] | Should -Not -BeNullOrEmpty
6560
}
6661

67-
It 'changelog and manifest versions are the same' {
68-
$script:changelogVersion -as [Version] | Should -Be ($script:manifest.Version -as [Version])
62+
It 'Changelog and manifest versions are the same' {
63+
$changelogVersion -as [Version] | Should -Be ( $manifestData.Version -as [Version] )
6964
}
65+
}
66+
}
7067

71-
if (Get-Command git.exe -ErrorAction SilentlyContinue) {
72-
$script:tagVersion = $null
73-
It 'is tagged with a valid version' -skip {
74-
$thisCommit = git.exe log --decorate --oneline HEAD~1..HEAD
68+
Describe 'Git tagging' -Skip {
69+
BeforeAll {
70+
$gitTagVersion = $null
7571

76-
if ($thisCommit -match 'tag:\s*(\d+(?:\.\d+)*)') {
77-
$script:tagVersion = $matches[1]
78-
}
72+
if ($git = Get-Command git -CommandType Application -ErrorAction SilentlyContinue) {
73+
$thisCommit = & $git log --decorate --oneline HEAD~1..HEAD
74+
if ($thisCommit -match 'tag:\s*(\d+(?:\.\d+)*)') { $gitTagVersion = $matches[1] }
75+
}
76+
}
7977

80-
$script:tagVersion | Should -Not -BeNullOrEmpty
81-
$script:tagVersion -as [Version] | Should -Not -BeNullOrEmpty
82-
}
78+
It 'Is tagged with a valid version' {
79+
$gitTagVersion | Should -Not -BeNullOrEmpty
80+
$gitTagVersion -as [Version] | Should -Not -BeNullOrEmpty
81+
}
8382

84-
It 'all versions are the same' {
85-
$script:changelogVersion -as [Version] | Should -Be ( $script:manifest.Version -as [Version] )
86-
}
87-
}
83+
It 'Matches manifest version' {
84+
$manifestData.Version -as [Version] | Should -Be ( $gitTagVersion -as [Version])
8885
}
8986
}

0 commit comments

Comments
 (0)