2020-03-24 11:08:37 -07:00
# Copyright (c) Microsoft Corporation.
2018-02-13 09:23:53 -08:00
# Licensed under the MIT License.
#
2016-08-09 17:03:32 -07:00
# Validates Get-Help for cmdlets in Microsoft.PowerShell.Core.
2016-08-08 22:33:57 -07:00
2019-04-04 23:01:01 -07:00
Import-Module HelpersCommon
2018-04-02 15:32:55 -07:00
$script:cmdletsToSkip = @ (
"Get-PSHostProcessInfo" ,
"Out-Default" ,
"Register-ArgumentCompleter" ,
"New-PSRoleCapabilityFile" ,
"Get-PSSessionCapability" ,
"Disable-PSRemoting" , # Content not available: Issue # https://github.com/PowerShell/PowerShell-Docs/issues/1790
2018-07-06 11:42:50 -07:00
"Enable-PSRemoting" ,
2018-12-05 12:20:58 -08:00
"Get-ExperimentalFeature" ,
"Enable-ExperimentalFeature" ,
2020-08-20 17:41:44 -07:00
"Disable-ExperimentalFeature" ,
2022-01-04 14:09:27 -08:00
"Get-PSSubsystem" ,
"Switch-Process"
2018-04-02 15:32:55 -07:00
)
2016-08-27 02:46:25 +04:00
2018-04-02 15:32:55 -07:00
function UpdateHelpFromLocalContentPath {
param ([ string ] $ModuleName , [ string ] $Scope = 'CurrentUser' )
2016-08-27 02:46:25 +04:00
2018-04-02 15:32:55 -07:00
$helpContentPath = Join-Path $PSScriptRoot "assets"
$helpFiles = @ ( Get-ChildItem " $helpContentPath \*" -ErrorAction SilentlyContinue )
2016-10-17 12:04:37 -07:00
2018-04-02 15:32:55 -07:00
if ( $helpFiles . Count -eq 0 ) {
throw "Unable to find help content at ' $helpContentPath '"
2016-08-27 02:46:25 +04:00
}
2018-04-02 15:32:55 -07:00
2023-05-09 18:46:59 +02:00
# Test files are 'en-US', set explicit culture so test does not fail on non-US systems
2022-08-10 00:51:32 +02:00
Update-Help -Module $ModuleName -SourcePath $helpContentPath -UICulture 'en-US' -Force -ErrorAction Stop -Scope $Scope
2016-08-27 02:46:25 +04:00
}
2018-04-02 15:32:55 -07:00
function GetCurrentUserHelpRoot {
if ([ System.Management.Automation.Platform ]:: IsWindows ) {
$userHelpRoot = Join-Path $HOME "Documents/PowerShell/Help/"
} else {
$userModulesRoot = [ System.Management.Automation.Platform ]:: SelectProductNameForDirectory ([ System . Management . Automation . Platform + XDG_Type ]:: USER_MODULES )
$userHelpRoot = Join-Path $userModulesRoot -ChildPath ".." -AdditionalChildPath "Help"
2016-08-08 22:33:57 -07:00
}
2018-04-02 15:32:55 -07:00
return $userHelpRoot
2016-08-08 22:33:57 -07:00
}
2016-08-09 17:03:32 -07:00
2022-11-15 17:57:03 -08:00
Describe 'Validate HelpInfo type' -Tags @ ( 'CI' ) {
It 'Category should be a string' {
$help = Get-Help *
$category = $help | ForEach-Object { $_ . Category . GetType (). FullName } | Select-Object -Unique
$category . Count | Should -Be 1 -Because 'All help categories should be strings, >1 indicates a type mismatch'
$category | Should -BeExactly 'System.String'
}
}
2017-02-01 17:56:52 -08:00
Describe "Validate that <pshome>/<culture>/default.help.txt is present" -Tags @ ( 'CI' ) {
2018-05-04 21:25:05 +05:00
It "Get-Help returns information about the help system" {
2017-02-01 17:56:52 -08:00
$help = Get-Help
2018-03-14 12:13:32 -07:00
$help . Name | Should -Be "default"
$help . Category | Should -Be "HelpFile"
$help . Synopsis | Should -Match "SHORT DESCRIPTION"
2017-02-01 17:56:52 -08:00
}
}
2018-05-04 21:25:05 +05:00
Describe "Validate that the Help function can Run in strict mode" -Tags @ ( 'CI' ) {
It "Help doesn't fail when strict mode is on" {
2023-01-31 12:06:29 -08:00
if ( Test-IsWindowsArm64 ) {
Set-ItResult -Pending -Because "IOException: The handle is invalid."
}
2018-05-04 21:25:05 +05:00
$help = & {
# run in nested scope to keep strict mode from affecting other tests
2020-02-03 17:44:10 +00:00
Set-StrictMode -Version 3.0
2020-05-07 13:00:30 +01:00
help
2018-05-04 21:25:05 +05:00
}
# the help function renders the help content as text so just verify that there is content
$help | Should -Not -BeNullOrEmpty
}
}
2018-04-02 15:32:55 -07:00
Describe "Validate that get-help works for CurrentUserScope" -Tags @ ( 'CI' ) {
2016-12-06 13:58:57 -08:00
BeforeAll {
$SavedProgressPreference = $ProgressPreference
$ProgressPreference = "SilentlyContinue"
2018-04-02 15:32:55 -07:00
$moduleName = "Microsoft.PowerShell.Core"
2016-12-06 13:58:57 -08:00
}
AfterAll {
$ProgressPreference = $SavedProgressPreference
}
2016-08-09 17:03:32 -07:00
2018-04-02 15:32:55 -07:00
Context "for module : $moduleName " {
BeforeAll {
UpdateHelpFromLocalContentPath $moduleName -Scope 'CurrentUser'
$cmdlets = Get-Command -Module $moduleName
}
$testCases = @ ()
## Just testing first 3 in CI, Feature tests validate full list.
$cmdlets | Where-Object { $script:cmdletsToSkip -notcontains $_ } | Select-Object -First 3 | ForEach-Object { $testCases += @ { cmdletName = $_ . Name }}
It "Validate -Description and -Examples sections in help content. Run 'Get-help -name <cmdletName>" -TestCases $testCases {
param ( $cmdletName )
2020-05-07 13:00:30 +01:00
$help = Get-Help -Name $cmdletName
2020-01-11 15:41:59 +00:00
$help . Description | Out-String | Should -Match $cmdletName
$help . Examples | Out-String | Should -Match $cmdletName
2018-04-02 15:32:55 -07:00
}
2024-01-09 11:21:31 -08:00
It "Validate 'Aliases' is present in help content formatting" {
## The parameter help content should be formatted with the following section:
## Accept pipeline input? xxxx
## Aliases NoOverwrite
## Accept wildcard characters? xxxx
$output = Get-Help Import-Module -Parameter NoClobber | Out-String
$output | Should -Match "Accept pipeline input\?.*\n\s+Aliases\s+NoOverwrite.*\n\s+Accept wildcard characters\?.*"
}
2018-04-02 15:32:55 -07:00
}
2016-08-09 17:03:32 -07:00
}
2016-08-27 02:46:25 +04:00
2019-03-11 19:26:01 +01:00
Describe "Testing Get-Help Progress" -Tags @ ( 'Feature' ) {
It "Last ProgressRecord should be Completed" {
try {
2022-03-23 08:53:12 -07:00
$j = Start-Job { Get-Help ([ guid ]:: NewGuid (). ToString ( "N" )) }
2019-03-11 19:26:01 +01:00
$j | Wait-Job
$j . ChildJobs [ 0 ]. Progress [ -1 ]. RecordType | Should -Be ([ System.Management.Automation.ProgressRecordType ]:: Completed )
}
finally {
$j | Remove-Job
}
}
}
Describe "Validate that get-help works for AllUsers Scope" -Tags @ ( 'Feature' , 'RequireAdminOnWindows' , 'RequireSudoOnUnix' ) {
2016-09-13 09:48:57 +04:00
BeforeAll {
2016-12-06 13:58:57 -08:00
$SavedProgressPreference = $ProgressPreference
$ProgressPreference = "SilentlyContinue"
2018-04-02 15:32:55 -07:00
$moduleName = "Microsoft.PowerShell.Core"
}
AfterAll {
$ProgressPreference = $SavedProgressPreference
}
2016-12-06 13:58:57 -08:00
2018-04-02 15:32:55 -07:00
Context "for module : $moduleName " {
BeforeAll {
2019-04-04 23:01:01 -07:00
if ( Test-CanWriteToPsHome ) {
UpdateHelpFromLocalContentPath $moduleName -Scope 'AllUsers'
}
2018-04-02 15:32:55 -07:00
$cmdlets = Get-Command -Module $moduleName
}
$testCases = @ ()
$cmdlets | Where-Object { $cmdletsToSkip -notcontains $_ } | ForEach-Object { $testCases += @ { cmdletName = $_ . Name }}
2019-04-04 23:01:01 -07:00
It "Validate -Description and -Examples sections in help content. Run 'Get-help -name <cmdletName>" -TestCases $testCases -Skip: (!( Test-CanWriteToPsHome )) {
2018-04-02 15:32:55 -07:00
param ( $cmdletName )
2020-05-07 13:00:30 +01:00
$help = Get-Help -Name $cmdletName
2020-01-11 15:41:59 +00:00
$help . Description | Out-String | Should -Match $cmdletName
$help . Examples | Out-String | Should -Match $cmdletName
2018-04-02 15:32:55 -07:00
}
}
}
Describe "Validate that get-help works for provider specific help" -Tags @ ( 'CI' ) {
BeforeAll {
2016-09-13 09:48:57 +04:00
$namespaces = @ {
command = 'http://schemas.microsoft.com/maml/dev/command/2004/10'
dev = 'http://schemas.microsoft.com/maml/dev/2004/10'
maml = 'http://schemas.microsoft.com/maml/2004/10'
msh = 'http://msh'
}
2018-04-02 15:32:55 -07:00
$helpFileRoot = Join-Path ( GetCurrentUserHelpRoot ) ([ Globalization.CultureInfo ]:: CurrentUICulture )
2016-09-13 09:48:57 +04:00
# Currently these test cases are verified only on Windows, because
# - WSMan:\ and Cert:\ providers are not yet supported on non-Windows platforms.
$testCases = @ (
@ {
2018-04-02 15:32:55 -07:00
helpFile = " $helpFileRoot \System.Management.Automation.dll-help.xml"
path = " $userHelpRoot "
2016-09-13 09:48:57 +04:00
helpContext = "[@id='FileSystem' or @ID='FileSystem']"
verb = 'Add'
noun = 'Content'
2016-08-27 02:46:25 +04:00
}
2016-09-13 09:48:57 +04:00
)
2016-08-27 02:46:25 +04:00
2018-04-02 15:32:55 -07:00
if ( $IsWindows ) {
2016-10-17 12:04:37 -07:00
$testCases += @ (
@ {
2018-04-02 15:32:55 -07:00
helpFile = " $helpFileRoot \Microsoft.WSMan.Management.dll-help.xml"
2016-10-17 12:04:37 -07:00
path = 'WSMan:\localhost\ClientCertificate'
helpContext = "[@id='ClientCertificate' or @ID='ClientCertificate']"
2018-04-02 15:32:55 -07:00
cmdlet = 'New-Item'
2016-10-17 12:04:37 -07:00
}
,
@ {
2018-04-02 15:32:55 -07:00
helpFile = " $helpFileRoot \Microsoft.PowerShell.Security.dll-help.xml"
2016-10-17 12:04:37 -07:00
path = 'Cert:\'
helpContext = $null # CertificateProvider uses only verb and noun in XPath query
verb = 'New'
noun = 'Item'
}
)
2018-04-02 15:32:55 -07:00
UpdateHelpFromLocalContentPath -ModuleName 'Microsoft.WSMan.Management' -Scope 'CurrentUser'
UpdateHelpFromLocalContentPath -ModuleName 'Microsoft.PowerShell.Security' -Scope 'CurrentUser'
2016-10-17 12:04:37 -07:00
}
2018-04-02 15:32:55 -07:00
UpdateHelpFromLocalContentPath -ModuleName 'Microsoft.PowerShell.Core' -Scope 'CurrentUser'
2016-09-13 09:48:57 +04:00
}
2016-08-27 02:46:25 +04:00
2018-04-02 15:32:55 -07:00
## The tests are marked as pending since provider specific help content in not available in PS v6.*
It "Shows contextual help when Get-Help is invoked for provider-specific path (Get-Help -Name <verb>-<noun> -Path <path>)" -TestCases $testCases -Pending {
2016-08-27 02:46:25 +04:00
2018-04-02 15:32:55 -07:00
param (
$helpFile ,
$path ,
$verb ,
$noun
)
2016-08-27 02:46:25 +04:00
2018-04-02 15:32:55 -07:00
# Path should exist or else Get-Help will fallback to default help text
$path | Should -Exist
2016-08-27 02:46:25 +04:00
2018-04-02 15:32:55 -07:00
$xpath = "/msh:helpItems/msh:providerHelp/msh:CmdletHelpPaths/msh:CmdletHelpPath $helpContext /command:command/command:details[command:verb=' $verb ' and command:noun=' $noun ']"
$helpXmlNode = Select-Xml -Path $helpFile -XPath $xpath -Namespace $namespaces | Select-Object -ExpandProperty Node
2017-01-04 22:09:07 +04:00
2018-04-02 15:32:55 -07:00
# Synopsis comes from command:command/command:details/maml:description
$expected = Get-Help -Name " $verb - $noun " -Path $path | Select-Object -ExpandProperty Synopsis
2017-01-04 22:09:07 +04:00
2018-04-02 15:32:55 -07:00
# System.Management.Automation.ProviderContext.GetProviderSpecificHelpInfo ignores extra whitespace, line breaks and
# comments when loading help XML, but Select-Xml can not; use BeLikeExactly operator to omit trailing line breaks:
$helpXmlNode . description . para -clike " $expected *" | Should -BeTrue
2016-08-27 02:46:25 +04:00
}
}
2017-03-28 15:07:42 -07:00
2018-02-26 12:35:05 -08:00
Describe "Validate about_help.txt under culture specific folder works" -Tags @ ( 'CI' , 'RequireAdminOnWindows' , 'RequireSudoOnUnix' ) {
2017-03-28 15:07:42 -07:00
BeforeAll {
2020-01-13 19:35:33 +00:00
$modulePath = " $PSHOME \Modules\Test"
2019-04-04 23:01:01 -07:00
if ( Test-CanWriteToPsHome ) {
$null = New-Item -Path $modulePath \ en-US -ItemType Directory -Force
New-ModuleManifest -Path $modulePath \ test . psd1 -RootModule test . psm1
Set-Content -Path $modulePath \ test . psm1 -Value "function foo{}"
Set-Content -Path $modulePath \ en-US \ about_testhelp . help . txt -Value "Hello" -NoNewline
}
2017-11-15 16:29:04 -08:00
2018-04-02 15:32:55 -07:00
$aboutHelpPath = Join-Path ( GetCurrentUserHelpRoot ) ( Get-Culture ). Name
2017-11-15 16:29:04 -08:00
## If help content does not exist, update it first.
2018-04-02 15:32:55 -07:00
if ( -not ( Test-Path ( Join-Path $aboutHelpPath "about_Variables.help.txt" ))) {
UpdateHelpFromLocalContentPath -ModuleName 'Microsoft.PowerShell.Core' -Scope 'CurrentUser'
2017-11-15 16:29:04 -08:00
}
2017-03-28 15:07:42 -07:00
}
AfterAll {
2019-04-04 23:01:01 -07:00
if ( Test-CanWriteToPsHome ) {
Remove-Item $modulePath -Recurse -Force
}
2017-10-13 13:54:43 -07:00
# Remove all the help content.
2018-04-02 15:32:55 -07:00
Get-ChildItem -Path $aboutHelpPath -Include @ ( 'about_*.txt' , "*help.xml" ) -Recurse | Remove-Item -Force -ErrorAction SilentlyContinue
2017-03-28 15:07:42 -07:00
}
2020-01-13 19:35:33 +00:00
It "Get-Help should return help text and not multiple HelpInfo objects when help is under `$ PSHOME path" -Skip: (!( Test-CanWriteToPsHome )) {
2017-03-28 15:07:42 -07:00
$help = Get-Help about_testhelp
2018-03-14 12:13:32 -07:00
$help . count | Should -Be 1
$help | Should -BeExactly "Hello"
2017-03-28 15:07:42 -07:00
}
2017-06-18 18:27:34 -07:00
It "Get-Help for about_Variable should return only one help object" {
$help = Get-Help about_Variables
2018-03-14 12:13:32 -07:00
$help . count | Should -Be 1
2017-06-18 18:27:34 -07:00
}
2017-03-28 15:07:42 -07:00
}
2017-05-01 13:54:01 -07:00
2018-04-02 15:32:55 -07:00
Describe "About help files can be found in AllUsers scope" -Tags @ ( 'Feature' , 'RequireAdminOnWindows' , 'RequireSudoOnUnix' ) {
BeforeAll {
$aboutHelpPath = Join-Path $PSHOME ( Get-Culture ). Name
##clean up any CurrentUser if exists.
$userHelpRoot = GetCurrentUserHelpRoot
if ( Test-Path $userHelpRoot ) {
Remove-Item $userHelpRoot -Force -Recurse -ErrorAction Stop
}
2019-04-04 23:01:01 -07:00
if ( Test-CanWriteToPsHome ) {
UpdateHelpFromLocalContentPath -ModuleName 'Microsoft.PowerShell.Core' -Scope 'AllUsers'
}
2018-04-02 15:32:55 -07:00
}
2019-04-04 23:01:01 -07:00
It "Get-Help for about_Variable should return only one help object" -Skip: (!( Test-CanWriteToPsHome )) {
2018-04-02 15:32:55 -07:00
$help = Get-Help about_Variables
2020-01-11 15:41:59 +00:00
$help . count | Should -Be 1
2018-04-02 15:32:55 -07:00
}
}
Describe "Get-Help should find help info within help files" -Tags @ ( 'CI' ) {
2017-05-01 13:54:01 -07:00
It "Get-Help should find help files under pshome" {
$helpFile = "about_testCase.help.txt"
2018-04-02 15:32:55 -07:00
$helpFolderPath = Join-Path ( GetCurrentUserHelpRoot ) ( Get-Culture ). Name
2017-05-01 13:54:01 -07:00
$helpFilePath = Join-Path $helpFolderPath $helpFile
2018-04-02 15:32:55 -07:00
if (!( Test-Path $helpFolderPath )) {
2017-05-01 13:54:01 -07:00
$null = New-Item -ItemType Directory -Path $helpFolderPath -ErrorAction SilentlyContinue
}
2017-09-29 14:35:13 -07:00
2018-04-02 15:32:55 -07:00
try {
2017-05-01 13:54:01 -07:00
$null = New-Item -ItemType File -Path $helpFilePath -Value "about_test" -ErrorAction SilentlyContinue
$helpContent = Get-Help about_testCase
2018-03-14 12:13:32 -07:00
$helpContent | Should -Match "about_test"
2018-04-02 15:32:55 -07:00
} finally {
2017-05-01 13:54:01 -07:00
Remove-Item $helpFilePath -Force -ErrorAction SilentlyContinue
}
}
}
2017-06-06 18:06:51 -07:00
Describe "Get-Help should find pattern help files" -Tags "CI" {
2017-09-29 14:35:13 -07:00
2018-04-02 15:32:55 -07:00
BeforeAll {
$helpFile1 = "about_testCase1.help.txt"
$helpFile2 = "about_testCase.2.help.txt"
$helpFolderPath = Join-Path ( GetCurrentUserHelpRoot ) ( Get-Culture ). Name
$helpFilePath1 = Join-Path $helpFolderPath $helpFile1
$helpFilePath2 = Join-Path $helpFolderPath $helpFile2
$null = New-Item -ItemType Directory -Path $helpFolderPath -ErrorAction SilentlyContinue -Force
# Create at least one help file matches "about*" pattern
$null = New-Item -ItemType File -Path $helpFilePath1 -Value "about_test1" -ErrorAction SilentlyContinue
$null = New-Item -ItemType File -Path $helpFilePath2 -Value "about_test2" -ErrorAction SilentlyContinue
}
2017-06-06 18:06:51 -07:00
2018-04-02 15:32:55 -07:00
# Remove the test files
AfterAll {
Remove-Item $helpFilePath1 -Force -ErrorAction SilentlyContinue
Remove-Item $helpFilePath2 -Force -ErrorAction SilentlyContinue
}
2017-06-06 18:06:51 -07:00
2018-06-28 23:29:12 -07:00
BeforeEach {
$currentPSModulePath = $env:PSModulePath
}
AfterEach {
$env:PSModulePath = $currentPSModulePath
}
2018-04-02 15:32:55 -07:00
$testcases = @ (
@ { command = { Get-Help about_testCas ? 1 }; testname = "test ? pattern" ; result = "about_test1" }
@ { command = { Get-Help about_testCase .?}; testname = "test ? pattern with dot" ; result = "about_test2" }
@ { command = {( Get-Help about_testCase *). Count }; testname = "test * pattern" ; result = "2" }
@ { command = { Get-Help about_testCas ? .2 *}; testname = "test ?, * pattern with dot" ; result = "about_test2" }
)
2017-06-06 18:06:51 -07:00
2023-01-10 03:10:03 +00:00
It "Get-Help should find pattern help files - <testname>" -TestCases $testcases {
2018-04-02 15:32:55 -07:00
param (
2017-06-06 18:06:51 -07:00
$command ,
$result
)
2018-03-14 12:13:32 -07:00
$command . Invoke () | Should -Be $result
2017-06-06 18:06:51 -07:00
}
2018-06-28 23:29:12 -07:00
It "Get-Help should fail expectedly searching for class help with hidden members" {
$testModule = @'
class foo
{
hidden static $monthNames = @('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun','Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec')
}
'@
$modulesFolder = Join-Path $TestDrive "Modules"
$modulePath = Join-Path $modulesFolder "TestModule"
New-Item -ItemType Directory -Path $modulePath -Force > $null
Set-Content -Path ( Join-Path $modulePath "TestModule.psm1" ) -Value $testModule
$env:PSModulePath += [ System.IO.Path ]:: PathSeparator + $modulesFolder
{ Get-Help -Category Class -Name foo -ErrorAction Stop } | Should -Throw -ErrorId "HelpNotFound,Microsoft.PowerShell.Commands.GetHelpCommand"
}
2017-09-28 08:47:42 -07:00
}
2017-11-06 11:19:39 -07:00
Describe "Get-Help should find pattern alias" -Tags "CI" {
2019-01-07 13:39:57 -08:00
BeforeAll {
Set-Alias -Name testAlias1 -Value Where-Object
}
2017-09-28 08:47:42 -07:00
AfterAll {
2017-09-29 14:35:13 -07:00
Remove-Item alias : \ testAlias1 -ErrorAction SilentlyContinue
2017-09-28 08:47:42 -07:00
}
2017-09-29 14:35:13 -07:00
2017-09-28 08:47:42 -07:00
It "Get-Help should find alias as command" {
2018-04-02 15:32:55 -07:00
( Get-Help where ). Name | Should -BeExactly "Where-Object"
2017-09-28 08:47:42 -07:00
}
It "Get-Help should find alias with ? pattern" {
2018-04-02 15:32:55 -07:00
$help = Get-Help wher ?
$help . Category | Should -BeExactly "Alias"
$help . Synopsis | Should -BeExactly "Where-Object"
2017-09-28 08:47:42 -07:00
}
It "Get-Help should find alias with * pattern" {
2018-04-02 15:32:55 -07:00
$help = Get-Help testAlias1 *
$help . Category | Should -BeExactly "Alias"
$help . Synopsis | Should -BeExactly "Where-Object"
2017-09-28 08:47:42 -07:00
}
2019-01-07 13:39:57 -08:00
It "Help alias should be same as Get-Help alias" {
$help1 = Get-Help testAlias *
$help2 = help testAlias *
Compare-Object $help1 $help2 | Should -BeNullOrEmpty
}
2017-11-06 11:19:39 -07:00
}
2017-06-06 18:06:51 -07:00
2017-11-06 11:19:39 -07:00
Describe "help function uses full view by default" -Tags "CI" {
It "help should return full view without -Full switch" {
2023-01-31 12:06:29 -08:00
if ( Test-IsWindowsArm64 ) {
Set-ItResult -Pending -Because "IOException: The handle is invalid."
}
2017-11-06 11:19:39 -07:00
$gpsHelp = ( help Microsoft . PowerShell . Management \ Get-Process )
2018-03-14 12:13:32 -07:00
$gpsHelp | Where-Object { $_ -cmatch '^PARAMETERS' } | Should -Not -BeNullOrEmpty
2017-11-06 11:19:39 -07:00
}
It "help should return full view even with -Full switch" {
2023-01-31 12:06:29 -08:00
if ( Test-IsWindowsArm64 ) {
Set-ItResult -Pending -Because "IOException: The handle is invalid."
}
2017-11-06 11:19:39 -07:00
$gpsHelp = ( help Microsoft . PowerShell . Management \ Get-Process -Full )
2018-03-14 12:13:32 -07:00
$gpsHelp | Where-Object { $_ -cmatch '^PARAMETERS' } | Should -Not -BeNullOrEmpty
2017-11-06 11:19:39 -07:00
}
It "help should not append -Full when not using AllUsersView parameter set" {
2023-01-31 12:06:29 -08:00
if ( Test-IsWindowsArm64 ) {
Set-ItResult -Pending -Because "IOException: The handle is invalid."
}
2017-11-06 11:19:39 -07:00
$gpsHelp = ( help Microsoft . PowerShell . Management \ Get-Process -Parameter Name )
2018-03-14 12:13:32 -07:00
$gpsHelp | Where-Object { $_ -cmatch '^PARAMETERS' } | Should -BeNullOrEmpty
2017-11-06 11:19:39 -07:00
}
2017-06-06 18:06:51 -07:00
}
2018-04-02 15:32:55 -07:00
Describe 'help can be found for CurrentUser Scope' -Tags 'CI' {
BeforeAll {
$userHelpRoot = GetCurrentUserHelpRoot
## Clear all help from user scope.
Remove-Item $userHelpRoot -Force -ErrorAction SilentlyContinue -Recurse
UpdateHelpFromLocalContentPath -ModuleName 'Microsoft.PowerShell.Core' -Scope 'CurrentUser'
UpdateHelpFromLocalContentPath -ModuleName 'Microsoft.PowerShell.Management' -Scope 'CurrentUser'
2018-11-30 09:49:32 -08:00
UpdateHelpFromLocalContentPath -ModuleName 'Microsoft.PowerShell.Archive' -Scope 'CurrentUser' -Force
2018-04-02 15:32:55 -07:00
UpdateHelpFromLocalContentPath -ModuleName 'PackageManagement' -Scope CurrentUser -Force
## Delete help from global scope if it exists.
$currentCulture = ( Get-Culture ). Name
$managementHelpFilePath = Join-Path $PSHOME -ChildPath $currentCulture -AdditionalChildPath 'Microsoft.PowerShell.Commands.Management.dll-Help.xml'
if ( Test-Path $managementHelpFilePath ) {
Remove-Item $managementHelpFilePath -Force -ErrorAction SilentlyContinue
}
$coreHelpFilePath = Join-Path $PSHOME -ChildPath $currentCulture -AdditionalChildPath 'System.Management.Automation.dll-Help.xml'
if ( Test-Path $coreHelpFilePath ) {
Remove-Item $coreHelpFilePath -Force -ErrorAction SilentlyContinue
}
2018-11-30 09:49:32 -08:00
$archiveHelpFilePath = Join-Path ( Get-Module Microsoft . PowerShell . Archive -ListAvailable ). ModuleBase -ChildPath $currentCulture -AdditionalChildPath 'Microsoft.PowerShell.Archive-help.xml'
if ( Test-Path $archiveHelpFilePath ) {
Remove-Item $archiveHelpFilePath -Force -ErrorAction SilentlyContinue
2018-04-02 15:32:55 -07:00
}
$TestCases = @ (
@ { TestName = 'module under $PSHOME' ; CmdletName = 'Add-Content' }
@ { TestName = 'module is a PSSnapin' ; CmdletName = 'Get-Command' }
2018-11-30 09:49:32 -08:00
@ { TestName = 'module is under $PSHOME\Modules' ; CmdletName = 'Compress-Archive' }
2018-04-02 15:32:55 -07:00
@ { TestName = 'module has a version folder' ; CmdletName = 'Find-Package' }
)
}
It 'help in user scope be found for <TestName>' -TestCases $TestCases {
param ( $CmdletName )
$helpObj = Get-Help -Name $CmdletName -Full
$helpObj . description | Out-String | Should -Match $CmdletName
}
}
Describe 'help can be found for AllUsers Scope' -Tags @ ( 'Feature' , 'RequireAdminOnWindows' , 'RequireSudoOnUnix' ) {
BeforeAll {
$userHelpRoot = GetCurrentUserHelpRoot
## Clear all help from user scope.
Remove-Item $userHelpRoot -Force -ErrorAction SilentlyContinue -Recurse
## Delete help from global scope if it exists.
$currentCulture = ( Get-Culture ). Name
2019-04-04 23:01:01 -07:00
if ( Test-CanWriteToPsHome ) {
$managementHelpFilePath = Join-Path $PSHOME -ChildPath $currentCulture -AdditionalChildPath 'Microsoft.PowerShell.Commands.Management.dll-Help.xml'
if ( Test-Path $managementHelpFilePath ) {
Remove-Item $managementHelpFilePath -Force -ErrorAction SilentlyContinue
}
2018-04-02 15:32:55 -07:00
2019-04-04 23:01:01 -07:00
$coreHelpFilePath = Join-Path $PSHOME -ChildPath $currentCulture -AdditionalChildPath 'System.Management.Automation.dll-Help.xml'
if ( Test-Path $coreHelpFilePath ) {
Remove-Item $coreHelpFilePath -Force -ErrorAction SilentlyContinue
}
2018-04-02 15:32:55 -07:00
2019-04-04 23:01:01 -07:00
$archiveHelpFilePath = Join-Path ( Get-Module Microsoft . PowerShell . Archive -ListAvailable ). ModuleBase -ChildPath $currentCulture -AdditionalChildPath 'Microsoft.PowerShell.Archive-help.xml'
if ( Test-Path $archiveHelpFilePath ) {
Remove-Item $archiveHelpFilePath -Force -ErrorAction SilentlyContinue
}
2018-04-02 15:32:55 -07:00
2019-04-04 23:01:01 -07:00
UpdateHelpFromLocalContentPath -ModuleName 'Microsoft.PowerShell.Core' -Scope 'AllUsers'
UpdateHelpFromLocalContentPath -ModuleName 'Microsoft.PowerShell.Management' -Scope 'AllUsers'
UpdateHelpFromLocalContentPath -ModuleName 'Microsoft.PowerShell.Archive' -Scope 'AllUsers' -Force
UpdateHelpFromLocalContentPath -ModuleName 'PackageManagement' -Scope 'AllUsers' -Force
}
2018-04-02 15:32:55 -07:00
$TestCases = @ (
@ { TestName = 'module under $PSHOME' ; CmdletName = 'Add-Content' }
@ { TestName = 'module is a PSSnapin' ; CmdletName = 'Get-Command' }
2018-11-30 09:49:32 -08:00
@ { TestName = 'module is under $PSHOME\Modules' ; CmdletName = 'Compress-Archive' }
2018-04-02 15:32:55 -07:00
@ { TestName = 'module has a version folder' ; CmdletName = 'Find-Package' }
)
}
2019-04-04 23:01:01 -07:00
It 'help in user scope be found for <TestName>' -TestCases $TestCases -Skip: (!( Test-CanWriteToPsHome )) {
2018-04-02 15:32:55 -07:00
param ( $CmdletName )
$helpObj = Get-Help -Name $CmdletName -Full
$helpObj . description | Out-String | Should -Match $CmdletName
}
}
2019-01-08 09:56:56 -08:00
2019-01-16 03:25:49 +03:00
Describe "Get-Help should accept arrays as the -Parameter parameter value" -Tags @ ( 'CI' ) {
BeforeAll {
$userHelpRoot = GetCurrentUserHelpRoot
## Clear all help from user scope.
Remove-Item $userHelpRoot -Force -ErrorAction SilentlyContinue -Recurse
UpdateHelpFromLocalContentPath -ModuleName 'Microsoft.PowerShell.Core' -Scope 'CurrentUser'
## Delete help from global scope if it exists.
$currentCulture = ( Get-Culture ). Name
$coreHelpFilePath = Join-Path $PSHOME -ChildPath $currentCulture -AdditionalChildPath 'System.Management.Automation.dll-Help.xml'
if ( Test-Path $coreHelpFilePath ) {
Remove-Item $coreHelpFilePath -Force -ErrorAction SilentlyContinue
}
}
It "Should return help objects for two parameters" {
$help = Get-Help -Name Get-Command -Parameter Verb , Noun
$help | Should -HaveCount 2
$help [ 0 ]. Name | Should -BeExactly 'Verb'
$help [ 1 ]. Name | Should -BeExactly 'Noun'
}
}
2019-01-30 17:55:33 +01:00
Describe "Get-Help for function parameter should be consistent" -Tags 'CI' {
BeforeAll {
$test1 = @'
function test1 {
param (
$First
)
}
'@
$test2 = @'
function test2 {
param (
$First,
$Second
)
}
'@
$test1Path = Join-Path $TestDrive "test1.ps1"
Set-Content -Path $test1Path -Value $test1
$test2Path = Join-Path $TestDrive "test2.ps1"
Set-Content -Path $test2Path -Value $test2
Import-Module $test1Path
Import-Module $test2Path
}
AfterAll {
Remove-Module -Name "test1"
Remove-Module -Name "test2"
}
It "Get-Help for function parameter should be consistent" {
$test1HelpPSType = ( Get-Help test1 -Parameter First ). PSTypeNames
$test2HelpPSType = ( Get-Help test2 -Parameter First ). PSTypeNames
$test1HelpPSType | Should -BeExactly $test2HelpPSType
}
}
2019-01-08 09:56:56 -08:00
Describe "Help failure cases" -Tags Feature {
It "An error is returned for a topic that doesn't exist: <command>" -TestCases @ (
@ { command = "help" },
@ { command = "get-help" }
2019-03-11 19:26:01 +01:00
) {
2019-01-08 09:56:56 -08:00
param ( $command )
2022-03-18 16:15:59 -07:00
# under some conditions this does not throw, so include what we actually got
2022-03-23 08:53:12 -07:00
$helpTopic = [ guid ]:: NewGuid (). ToString ( "N" )
2022-05-11 12:30:22 -07:00
{ & $command $helpTopic -ErrorAction Stop } | Should -Throw -ErrorId "HelpNotFound,Microsoft.PowerShell.Commands.GetHelpCommand" -Because "A help topic was unexpectantly found for $helpTopic "
2019-01-08 09:56:56 -08:00
}
}
2019-01-17 00:14:44 +01:00
Describe 'help renders when using a PAGER with a space in the path' -Tags 'CI' {
BeforeAll {
$fakePager = @'
param(
[Parameter]
$customCommandArgs,
[Parameter(ValueFromPipelineByPropertyName)]
$Name
)
$b = [System.Text.Encoding]::UTF8.GetBytes($Name)
return [System.Convert]::ToBase64String($b)
'@
$fakePagerFolder = Join-Path $TestDrive "path with space"
$fakePagerPath = Join-Path $fakePagerFolder "fakepager.ps1"
New-Item -ItemType File -Path $fakePagerPath -Force > $null
Set-Content -Path $fakePagerPath -Value $fakePager
$SavedEnvPager = $env:PAGER
$env:PAGER = $fakePagerPath
}
AfterAll {
$env:PAGER = $SavedEnvPager
}
It 'help renders when using a PAGER with a space in the path' {
help Get-Command | Should -Be "R2V0LUNvbW1hbmQ="
}
}
2023-05-09 18:46:59 +02:00
Describe 'Update-Help allows partial culture matches' -Tags 'CI' {
BeforeAll {
function Test-UpdateHelpAux($UICulture , $Pass )
{
# If null (in system culture tests), omit entirely
$CultureArg = $UICulture ? @ { UICulture = $UICulture } : @ {}
$Args = @ {
Module = 'Microsoft.PowerShell.Core'
SourcePath = Join-Path $PSScriptRoot 'assets'
Force = $true
ErrorAction = $Pass ? 'Stop' : 'SilentlyContinue'
ErrorVariable = 'ErrorVariable'
}
Update-Help @Args @CultureArg
if ( -not $Pass ) {
$ErrorVariable | Should -Match 'Failed to update Help for the module.*'
}
}
}
AfterEach {
[ System.Management.Automation.Internal.InternalTestHooks ]:: SetTestHook ( 'CurrentUICulture' , $null )
}
It 'Checks culture match against en-US: <UICulture>' -TestCases @ (
@ { UICulture = 'en-US' }
@ { UICulture = 'en' }
@ { UICulture = 'en-GB' ; Pass = $false }
@ { UICulture = 'de-DE' ; Pass = $false }
) {
param ( $UICulture , $Pass = $true )
Test-UpdateHelpAux $UICulture $Pass
}
# When using system culture, "en-GB" will use "en" as fallback, so passes
It 'Checks system culture match against en-US: <UICulture>' -TestCases @ (
@ { UICulture = 'en-US' }
@ { UICulture = 'en' }
@ { UICulture = 'en-GB' }
@ { UICulture = 'de-DE' ; Pass = $false }
) {
param ( $UICulture , $Pass = $true )
[ System.Management.Automation.Internal.InternalTestHooks ]:: SetTestHook ( 'CurrentUICulture' , [ System.Globalization.CultureInfo ]:: new ( $UICulture ))
Test-UpdateHelpAux $null $Pass
}
}