|
1 | 1 | # Taken with love from @juneb_get_help (https://raw.githubusercontent.com/juneb/PesterTDD/master/Module.Help.Tests.ps1)
|
2 | 2 |
|
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 |
17 | 47 | }
|
18 | 48 |
|
19 | 49 | 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`>`]*' |
22 | 63 | }
|
23 | 64 |
|
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 | + } |
28 | 69 |
|
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 |
32 | 78 | }
|
33 | 79 |
|
| 80 | + It "Help link <_> is valid" -ForEach $helpLinks { |
| 81 | + (Invoke-WebRequest -Uri $_ -UseBasicParsing).StatusCode | Should -Be '200' |
| 82 | + } |
34 | 83 |
|
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 { |
39 | 85 |
|
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() } |
42 | 91 | }
|
43 |
| - } |
44 | 92 |
|
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 | + } |
49 | 97 |
|
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 |
52 | 102 | }
|
53 |
| - } |
54 | 103 |
|
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 |
85 | 107 | }
|
86 | 108 | }
|
87 | 109 |
|
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 |
99 | 115 | }
|
100 | 116 | }
|
101 | 117 | }
|
0 commit comments