tests/InModule.Help.Tests.ps1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
<#
 .NOTES
  ===========================================================================
  Created with: SAPIEN Technologies, Inc., PowerShell Studio 2016 v5.2.119
  Created on: 4/12/2016 1:11 PM
  Created by: June Blender
  Organization: SAPIEN Technologies, Inc
  Filename: *.Help.Tests.ps1
  ===========================================================================
 .DESCRIPTION
 To test help for the commands in a module, place this file in the module folder.
 To test any module from any path, use https://github.com/juneb/PesterTDD/Module.Help.Tests.ps1
#>


$ModuleBase = Split-Path -Parent $MyInvocation.MyCommand.Path
. "$ModuleBase\InModule.Help.Exceptions.ps1"

# For tests in .\Tests subdirectory
if ((Split-Path $ModuleBase -Leaf) -eq 'Tests')
{
$ModuleBase = Split-Path $ModuleBase -Parent
}

# Handles modules in version directories
$leaf = Split-Path $ModuleBase -Leaf
$parent = Split-Path $ModuleBase -Parent
$parsedVersion = $null
if ([System.Version]::TryParse($leaf, [ref]$parsedVersion))
{
$ModuleName = Split-Path $parent -Leaf
}
else
{
$ModuleName = $leaf
}

# Removes all versions of the module from the session before importing
Get-Module $ModuleName | Remove-Module

# Because ModuleBase includes version number, this imports the required version
# of the module
$Module = Import-Module $ModuleBase\$ModuleName.psd1 -PassThru -ErrorAction Stop
$commands = Get-Command -Module $module -CommandType Cmdlet, Function, Workflow  # 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
    
    # Skip all functions that are on the exclusions list
    if ($global:FunctionHelpTestExceptions -contains $commandName) { continue }
    
    # The module-qualified command fails on Microsoft.PowerShell.Archive cmdlets
$Help = Get-Help $commandName -ErrorAction SilentlyContinue

Describe "Test help for $commandName" {

# 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`>`]*'
}

# Should be a description for every function
It "gets description for $commandName" {
$Help.Description | Should Not BeNullOrEmpty
}

# 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 at least one example description
It "gets example help from $commandName" {
($Help.Examples.Example.Remarks | Select-Object -First 1).Text | Should Not BeNullOrEmpty
}

Context "Test parameter help for $commandName" {

$Common = 'Debug', 'ErrorAction', 'ErrorVariable', 'InformationAction', 'InformationVariable', 'OutBuffer', 'OutVariable',
'PipelineVariable', 'Verbose', 'WarningAction', 'WarningVariable'

$parameters = $command.ParameterSets.Parameters | Sort-Object -Property Name -Unique | Where-Object Name -notin $common
$parameterNames = $parameters.Name
$HelpParameterNames = $Help.Parameters.Parameter.Name | Sort-Object -Unique

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
}
}
}
}
}