From 2811ab7f84e39495ae5ae96b98d13d1e0d636652 Mon Sep 17 00:00:00 2001 From: Christoph Bergmeister Date: Sun, 12 Apr 2020 21:00:59 +0100 Subject: [PATCH 01/76] Replace usage of $MyInvocation.MyCommand.Pat with $PSScriptRoot and cleanup tests --- .../Documentation/RuleDocumentation.tests.ps1 | 8 +- Tests/Engine/CustomizedRule.tests.ps1 | 85 +++++++--------- Tests/Engine/EditableText.tests.ps1 | 8 +- Tests/Engine/Extensions.tests.ps1 | 3 +- Tests/Engine/GetScriptAnalyzerRule.tests.ps1 | 13 ++- Tests/Engine/GlobalSuppression.test.ps1 | 25 +++-- Tests/Engine/InvokeFormatter.tests.ps1 | 3 +- Tests/Engine/InvokeScriptAnalyzer.tests.ps1 | 97 +++++++++---------- Tests/Engine/LibraryUsage.tests.ps1 | 44 ++++----- .../Engine/ModuleDependencyHandler.tests.ps1 | 8 +- Tests/Engine/RuleSuppression.tests.ps1 | 9 +- Tests/Engine/RuleSuppressionClass.tests.ps1 | 9 +- Tests/Engine/Settings.tests.ps1 | 3 +- .../Rules/AlignAssignmentStatement.tests.ps1 | 3 +- ...nvertToSecureStringWithPlainText.tests.ps1 | 5 +- ...dDefaultTrueValueSwitchParameter.tests.ps1 | 5 +- Tests/Rules/AvoidEmptyCatchBlock.tests.ps1 | 7 +- Tests/Rules/AvoidGlobalAliases.tests.ps1 | 7 +- Tests/Rules/AvoidGlobalFunctions.tests.ps1 | 5 +- Tests/Rules/AvoidGlobalVars.tests.ps1 | 5 +- .../Rules/AvoidInvokingEmptyMembers.tests.ps1 | 5 +- ...dNullOrEmptyHelpMessageAttribute.tests.ps1 | 5 +- .../Rules/AvoidPositionalParameters.tests.ps1 | 7 +- Tests/Rules/AvoidReservedParams.tests.ps1 | 5 +- .../AvoidShouldContinueWithoutForce.tests.ps1 | 5 +- Tests/Rules/AvoidTrailingWhitespace.tests.ps1 | 4 +- ...OrMissingRequiredFieldInManifest.tests.ps1 | 25 +++-- .../AvoidUserNameAndPasswordParams.tests.ps1 | 5 +- Tests/Rules/AvoidUsingAlias.tests.ps1 | 9 +- .../AvoidUsingComputerNameHardcoded.tests.ps1 | 5 +- ...oidUsingDeprecatedManifestFields.tests.ps1 | 9 +- .../AvoidUsingInvokeExpression.tests.ps1 | 5 +- .../AvoidUsingPlainTextForPassword.tests.ps1 | 7 +- .../AvoidUsingReservedCharNames.tests.ps1 | 5 +- Tests/Rules/AvoidUsingWMICmdlet.tests.ps1 | 7 +- Tests/Rules/AvoidUsingWriteHost.tests.ps1 | 5 +- Tests/Rules/DscExamplesPresent.tests.ps1 | 9 +- Tests/Rules/DscTestsPresent.tests.ps1 | 9 +- Tests/Rules/MisleadingBacktick.tests.ps1 | 9 +- Tests/Rules/PSCredentialType.tests.ps1 | 7 +- Tests/Rules/PlaceCloseBrace.tests.ps1 | 4 +- ...sibleIncorrectComparisonWithNull.tests.ps1 | 5 +- Tests/Rules/ProvideCommentHelp.tests.ps1 | 10 +- ...eturnCorrectTypesForDSCFunctions.tests.ps1 | 9 +- .../UseBOMForUnicodeEncodedFile.tests.ps1 | 9 +- Tests/Rules/UseCmdletCorrectly.tests.ps1 | 5 +- Tests/Rules/UseCompatibleCmdlets.tests.ps1 | 5 +- .../Rules/UseConsistentIndentation.tests.ps1 | 4 +- Tests/Rules/UseConsistentWhitespace.tests.ps1 | 4 +- Tests/Rules/UseDSCResourceFunctions.tests.ps1 | 9 +- ...eDeclaredVarsMoreThanAssignments.tests.ps1 | 8 +- ...enticalMandatoryParametersForDSC.tests.ps1 | 3 +- .../Rules/UseIdenticalParametersDSC.tests.ps1 | 7 +- Tests/Rules/UseOutputTypeCorrectly.tests.ps1 | 7 +- .../Rules/UseShouldProcessCorrectly.tests.ps1 | 17 ++-- ...ProcessForStateChangingFunctions.tests.ps1 | 5 +- .../UseSingularNounsReservedVerbs.tests.ps1 | 10 +- .../Rules/UseSupportsShouldProcess.tests.ps1 | 4 +- .../UseToExportFieldsInManifest.tests.ps1 | 9 +- .../UseUTF8EncodingForHelpFile.tests.ps1 | 9 +- .../UseVerboseMessageInDSCResource.Tests.ps1 | 7 +- 61 files changed, 281 insertions(+), 368 deletions(-) diff --git a/Tests/Documentation/RuleDocumentation.tests.ps1 b/Tests/Documentation/RuleDocumentation.tests.ps1 index ca41f4819..6b0d93a51 100644 --- a/Tests/Documentation/RuleDocumentation.tests.ps1 +++ b/Tests/Documentation/RuleDocumentation.tests.ps1 @@ -1,10 +1,6 @@ -$directory = Split-Path -Parent $MyInvocation.MyCommand.Path -$testRootDirectory = Split-Path -Parent $directory -$repoRootDirectory = Split-Path -Parent $testRootDirectory -$ruleDocDirectory = Join-Path $repoRootDirectory RuleDocumentation - Describe "Validate rule documentation files" { BeforeAll { + $ruleDocDirectory = Join-Path $PSScriptRoot '../../RuleDocumentation' $docs = Get-ChildItem $ruleDocDirectory/*.md -Exclude README.md | ForEach-Object { "PS" + $_.BaseName} | Sort-Object @@ -56,7 +52,7 @@ Describe "Validate rule documentation files" { $filePath | Should -Exist } } - + It "Every rule name in the rule documentation README.md file must match the documentation file's basename" { foreach ($key in $readmeLinks.Keys) { $link = $readmeLinks[$key] diff --git a/Tests/Engine/CustomizedRule.tests.ps1 b/Tests/Engine/CustomizedRule.tests.ps1 index dbc295e50..af10ba5fd 100644 --- a/Tests/Engine/CustomizedRule.tests.ps1 +++ b/Tests/Engine/CustomizedRule.tests.ps1 @@ -1,8 +1,4 @@ -$directory = Split-Path -Parent $MyInvocation.MyCommand.Path -$testRootDirectory = Split-Path -Parent $directory -Import-Module (Join-Path $testRootDirectory 'PSScriptAnalyzerTestHelper.psm1') - -if (-not (Test-PSEditionCoreCLR)) +if (-not ([bool] $IsCoreCLR)) { # Force Get-Help not to prompt for interactive input to download help using Update-Help # By adding this registry key we turn off Get-Help interactivity logic during ScriptRule parsing @@ -25,7 +21,7 @@ $measure = "Measure-RequiresRunAsAdministrator" Describe "Test importing customized rules with null return results" { Context "Test Get-ScriptAnalyzer with customized rules" { It "will not terminate the engine" { - $customizedRulePath = Get-ScriptAnalyzerRule -CustomizedRulePath $directory\samplerule\SampleRulesWithErrors.psm1 | Where-Object {$_.RuleName -eq $measure} + $customizedRulePath = Get-ScriptAnalyzerRule -CustomizedRulePath $PSScriptRoot\samplerule\SampleRulesWithErrors.psm1 | Where-Object {$_.RuleName -eq $measure} $customizedRulePath.Count | Should -Be 1 } @@ -33,7 +29,7 @@ Describe "Test importing customized rules with null return results" { Context "Test Invoke-ScriptAnalyzer with customized rules" { It "will not terminate the engine" { - $customizedRulePath = Invoke-ScriptAnalyzer $directory\TestScript.ps1 -CustomizedRulePath $directory\samplerule\SampleRulesWithErrors.psm1 | Where-Object {$_.RuleName -eq $measure} + $customizedRulePath = Invoke-ScriptAnalyzer $PSScriptRoot\TestScript.ps1 -CustomizedRulePath $PSScriptRoot\samplerule\SampleRulesWithErrors.psm1 | Where-Object {$_.RuleName -eq $measure} $customizedRulePath.Count | Should -Be 0 } } @@ -42,7 +38,7 @@ Describe "Test importing customized rules with null return results" { Describe "Test importing correct customized rules" { - if(-not (Test-PSEditionCoreCLR)) + if(-not ([bool] $IsCoreCLR)) { Context "Test Get-Help functionality in ScriptRule parsing logic" { It "ScriptRule help section must be correctly processed when Get-Help is called for the first time" { @@ -58,7 +54,7 @@ Describe "Test importing correct customized rules" { } } - $customizedRulePath = Invoke-ScriptAnalyzer $directory\TestScript.ps1 -CustomizedRulePath $directory\samplerule\samplerule.psm1 | Where-Object {$_.Message -eq $message} + $customizedRulePath = Invoke-ScriptAnalyzer $PSScriptRoot\TestScript.ps1 -CustomizedRulePath $PSScriptRoot\samplerule\samplerule.psm1 | Where-Object {$_.Message -eq $message} $customizedRulePath.Count | Should -Be 1 # Force Get-Help not to prompt for interactive input to download help using Update-Help @@ -79,70 +75,65 @@ Describe "Test importing correct customized rules" { Context "Test Get-ScriptAnalyzer with customized rules" { It "will show the custom rule" { - $customizedRulePath = Get-ScriptAnalyzerRule -CustomizedRulePath $directory\samplerule\samplerule.psm1 | Where-Object {$_.RuleName -eq $measure} + $customizedRulePath = Get-ScriptAnalyzerRule -CustomizedRulePath $PSScriptRoot\samplerule\samplerule.psm1 | Where-Object {$_.RuleName -eq $measure} $customizedRulePath.Count | Should -Be 1 } It "will show the custom rule when given a rule folder path" { - $customizedRulePath = Get-ScriptAnalyzerRule -CustomizedRulePath $directory\samplerule | Where-Object {$_.RuleName -eq $measure} + $customizedRulePath = Get-ScriptAnalyzerRule -CustomizedRulePath $PSScriptRoot\samplerule | Where-Object {$_.RuleName -eq $measure} $customizedRulePath.Count | Should -Be 1 } It "will show the custom rule when given a rule folder path with trailing backslash" -skip:$($IsLinux -or $IsMacOS) { - $customizedRulePath = Get-ScriptAnalyzerRule -CustomizedRulePath $directory/samplerule/ | Where-Object {$_.RuleName -eq $measure} + $customizedRulePath = Get-ScriptAnalyzerRule -CustomizedRulePath $PSScriptRoot/samplerule/ | Where-Object {$_.RuleName -eq $measure} $customizedRulePath.Count | Should -Be 1 } It "will show the custom rules when given a glob" { - # needs fixing for Linux - $expectedNumRules = 4 - $customizedRulePath = Get-ScriptAnalyzerRule -CustomizedRulePath $directory\samplerule\samplerule* | Where-Object {$_.RuleName -match $measure} + $customizedRulePath = Get-ScriptAnalyzerRule -CustomizedRulePath $PSScriptRoot\samplerule\samplerule* | Where-Object {$_.RuleName -match $measure} $customizedRulePath.Count | Should -Be 4 } It "will show the custom rules when given recurse switch" { - $customizedRulePath = Get-ScriptAnalyzerRule -RecurseCustomRulePath -CustomizedRulePath "$directory\samplerule", "$directory\samplerule\samplerule2" | Where-Object {$_.RuleName -eq $measure} + $customizedRulePath = Get-ScriptAnalyzerRule -RecurseCustomRulePath -CustomizedRulePath "$PSScriptRoot\samplerule", "$PSScriptRoot\samplerule\samplerule2" | Where-Object {$_.RuleName -eq $measure} $customizedRulePath.Count | Should -Be 5 } It "will show the custom rules when given glob with recurse switch" { - # needs fixing for Linux - $expectedNumRules = 5 - $customizedRulePath = Get-ScriptAnalyzerRule -RecurseCustomRulePath -CustomizedRulePath $directory\samplerule\samplerule* | Where-Object {$_.RuleName -eq $measure} + $customizedRulePath = Get-ScriptAnalyzerRule -RecurseCustomRulePath -CustomizedRulePath $PSScriptRoot\samplerule\samplerule* | Where-Object {$_.RuleName -eq $measure} $customizedRulePath.Count | Should -Be 5 } It "will show the custom rules when given glob with recurse switch" { - $customizedRulePath = Get-ScriptAnalyzerRule -RecurseCustomRulePath -CustomizedRulePath $directory\samplerule* | Where-Object {$_.RuleName -eq $measure} + $customizedRulePath = Get-ScriptAnalyzerRule -RecurseCustomRulePath -CustomizedRulePath $PSScriptRoot\samplerule* | Where-Object {$_.RuleName -eq $measure} $customizedRulePath.Count | Should -Be 3 } } Context "Test Invoke-ScriptAnalyzer with customized rules" { It "will show the custom rule in the results" { - $customizedRulePath = Invoke-ScriptAnalyzer $directory\TestScript.ps1 -CustomizedRulePath $directory\samplerule\samplerule.psm1 | Where-Object {$_.Message -eq $message} + $customizedRulePath = Invoke-ScriptAnalyzer $PSScriptRoot\TestScript.ps1 -CustomizedRulePath $PSScriptRoot\samplerule\samplerule.psm1 | Where-Object {$_.Message -eq $message} $customizedRulePath.Count | Should -Be 1 } It "will show the custom rule in the results when given a rule folder path" { - $customizedRulePath = Invoke-ScriptAnalyzer $directory\TestScript.ps1 -CustomizedRulePath $directory\samplerule | Where-Object {$_.Message -eq $message} + $customizedRulePath = Invoke-ScriptAnalyzer $PSScriptRoot\TestScript.ps1 -CustomizedRulePath $PSScriptRoot\samplerule | Where-Object {$_.Message -eq $message} $customizedRulePath.Count | Should -Be 1 } It "will set ScriptName property to the target file name" { - $violations = Invoke-ScriptAnalyzer $directory\TestScript.ps1 -CustomizedRulePath $directory\samplerule + $violations = Invoke-ScriptAnalyzer $PSScriptRoot\TestScript.ps1 -CustomizedRulePath $PSScriptRoot\samplerule $violations[0].ScriptName | Should -Be 'TestScript.ps1' } It "will set ScriptPath property to the target file path" { - $violations = Invoke-ScriptAnalyzer $directory\TestScript.ps1 -CustomizedRulePath $directory\samplerule - $expectedScriptPath = Join-Path $directory 'TestScript.ps1' + $violations = Invoke-ScriptAnalyzer $PSScriptRoot\TestScript.ps1 -CustomizedRulePath $PSScriptRoot\samplerule + $expectedScriptPath = Join-Path $PSScriptRoot 'TestScript.ps1' $violations[0].ScriptPath | Should -Be $expectedScriptPath } It "will set SuggestedCorrections" { - $violations = Invoke-ScriptAnalyzer $directory\TestScript.ps1 -CustomizedRulePath $directory\samplerule - $expectedScriptPath = Join-Path $directory 'TestScript.ps1' + $violations = Invoke-ScriptAnalyzer $PSScriptRoot\TestScript.ps1 -CustomizedRulePath $PSScriptRoot\samplerule $violations[0].SuggestedCorrections | Should -Not -BeNullOrEmpty $violations[0].SuggestedCorrections.StartLineNumber | Should -Be 1 $violations[0].SuggestedCorrections.EndLineNumber | Should -Be 2 @@ -158,7 +149,7 @@ Describe "Test importing correct customized rules" { $testScriptPath = "TestDrive:\SuppressedCustomRule.ps1" Set-Content -Path $testScriptPath -Value $script - $customizedRulePath = Invoke-ScriptAnalyzer -Path $testScriptPath -CustomizedRulePath $directory\samplerule\samplerule.psm1 | + $customizedRulePath = Invoke-ScriptAnalyzer -Path $testScriptPath -CustomizedRulePath $PSScriptRoot\samplerule\samplerule.psm1 | Where-Object { $_.Message -eq $message } $customizedRulePath.Count | Should -Be 0 @@ -202,7 +193,7 @@ Describe "Test importing correct customized rules" { } It "will set RuleSuppressionID" { - $violations = Invoke-ScriptAnalyzer $directory\TestScript.ps1 -CustomizedRulePath $directory\samplerule + $violations = Invoke-ScriptAnalyzer $PSScriptRoot\TestScript.ps1 -CustomizedRulePath $PSScriptRoot\samplerule $violations[0].RuleSuppressionID | Should -Be "MyRuleSuppressionID" } @@ -212,63 +203,61 @@ Describe "Test importing correct customized rules" { # needs fixing for Linux if (!$IsLinux -and !$IsMacOS) { - $customizedRulePath = Invoke-ScriptAnalyzer $directory\TestScript.ps1 -CustomizedRulePath $directory\samplerule\ | Where-Object {$_.Message -eq $message} + $customizedRulePath = Invoke-ScriptAnalyzer $PSScriptRoot\TestScript.ps1 -CustomizedRulePath $PSScriptRoot\samplerule\ | Where-Object {$_.Message -eq $message} $customizedRulePath.Count | Should -Be 1 } } It "will show the custom rules when given a glob" { - $customizedRulePath = Invoke-ScriptAnalyzer $directory\TestScript.ps1 -CustomizedRulePath $directory\samplerule\samplerule* | Where-Object {$_.Message -eq $message} + $customizedRulePath = Invoke-ScriptAnalyzer $PSScriptRoot\TestScript.ps1 -CustomizedRulePath $PSScriptRoot\samplerule\samplerule* | Where-Object {$_.Message -eq $message} $customizedRulePath.Count | Should -Be 3 } It "will show the custom rules when given recurse switch" { - $customizedRulePath = Invoke-ScriptAnalyzer $directory\TestScript.ps1 -RecurseCustomRulePath -CustomizedRulePath $directory\samplerule | Where-Object {$_.Message -eq $message} + $customizedRulePath = Invoke-ScriptAnalyzer $PSScriptRoot\TestScript.ps1 -RecurseCustomRulePath -CustomizedRulePath $PSScriptRoot\samplerule | Where-Object {$_.Message -eq $message} $customizedRulePath.Count | Should -Be 3 } It "will show the custom rules when given glob with recurse switch" { - $customizedRulePath = Invoke-ScriptAnalyzer $directory\TestScript.ps1 -RecurseCustomRulePath -CustomizedRulePath $directory\samplerule\samplerule* | Where-Object {$_.Message -eq $message} + $customizedRulePath = Invoke-ScriptAnalyzer $PSScriptRoot\TestScript.ps1 -RecurseCustomRulePath -CustomizedRulePath $PSScriptRoot\samplerule\samplerule* | Where-Object {$_.Message -eq $message} $customizedRulePath.Count | Should -Be 4 } It "will show the custom rules when given glob with recurse switch" { - $customizedRulePath = Invoke-ScriptAnalyzer $directory\TestScript.ps1 -RecurseCustomRulePath -CustomizedRulePath $directory\samplerule* | Where-Object {$_.Message -eq $message} + $customizedRulePath = Invoke-ScriptAnalyzer $PSScriptRoot\TestScript.ps1 -RecurseCustomRulePath -CustomizedRulePath $PSScriptRoot\samplerule* | Where-Object {$_.Message -eq $message} $customizedRulePath.Count | Should -Be 3 } It "Using IncludeDefaultRules Switch with CustomRulePath" { - $customizedRulePath = Invoke-ScriptAnalyzer $directory\TestScript.ps1 -CustomRulePath $directory\samplerule\samplerule.psm1 -IncludeDefaultRules + $customizedRulePath = Invoke-ScriptAnalyzer $PSScriptRoot\TestScript.ps1 -CustomRulePath $PSScriptRoot\samplerule\samplerule.psm1 -IncludeDefaultRules $customizedRulePath.Count | Should -Be 2 } It "Using IncludeDefaultRules Switch without CustomRulePath" { - $customizedRulePath = Invoke-ScriptAnalyzer $directory\TestScript.ps1 -IncludeDefaultRules + $customizedRulePath = Invoke-ScriptAnalyzer $PSScriptRoot\TestScript.ps1 -IncludeDefaultRules $customizedRulePath.Count | Should -Be 1 } It "Not Using IncludeDefaultRules Switch and without CustomRulePath" { - $customizedRulePath = Invoke-ScriptAnalyzer $directory\TestScript.ps1 + $customizedRulePath = Invoke-ScriptAnalyzer $PSScriptRoot\TestScript.ps1 $customizedRulePath.Count | Should -Be 1 } It "loads custom rules that contain version in their path" -Skip:($PSVersionTable.PSVersion -lt [Version]'5.0.0') { - $customizedRulePath = Invoke-ScriptAnalyzer $directory\TestScript.ps1 -CustomRulePath $directory\VersionedSampleRule\SampleRuleWithVersion - $customizedRulePath.Count | Should -Be 1 + $customizedRulePath = Invoke-ScriptAnalyzer $PSScriptRoot\TestScript.ps1 -CustomRulePath $PSScriptRoot\VersionedSampleRule\SampleRuleWithVersion + $customizedRulePath.Count | Should -Be 1 - $customizedRulePath = Get-ScriptAnalyzerRule -CustomRulePath $directory\VersionedSampleRule\SampleRuleWithVersion - $customizedRulePath.Count | Should -Be 1 + $customizedRulePath = Get-ScriptAnalyzerRule -CustomRulePath $PSScriptRoot\VersionedSampleRule\SampleRuleWithVersion + $customizedRulePath.Count | Should -Be 1 } It "loads custom rules that contain version in their path with the RecurseCustomRule switch" -Skip:($PSVersionTable.PSVersion -lt [Version]'5.0.0') { - $customizedRulePath = Invoke-ScriptAnalyzer $directory\TestScript.ps1 -CustomRulePath $directory\VersionedSampleRule -RecurseCustomRulePath - $customizedRulePath.Count | Should -Be 1 + $customizedRulePath = Invoke-ScriptAnalyzer $PSScriptRoot\TestScript.ps1 -CustomRulePath $PSScriptRoot\VersionedSampleRule -RecurseCustomRulePath + $customizedRulePath.Count | Should -Be 1 - $customizedRulePath = Get-ScriptAnalyzerRule -CustomRulePath $directory\VersionedSampleRule -RecurseCustomRulePath - $customizedRulePath.Count | Should -Be 1 - } + $customizedRulePath = Get-ScriptAnalyzerRule -CustomRulePath $PSScriptRoot\VersionedSampleRule -RecurseCustomRulePath + $customizedRulePath.Count | Should -Be 1 + } } - } } - diff --git a/Tests/Engine/EditableText.tests.ps1 b/Tests/Engine/EditableText.tests.ps1 index 4c941b6e8..eb0222e94 100644 --- a/Tests/Engine/EditableText.tests.ps1 +++ b/Tests/Engine/EditableText.tests.ps1 @@ -1,13 +1,10 @@ -$directory = Split-Path -Parent $MyInvocation.MyCommand.Path -$testRootDirectory = Split-Path -Parent $directory - +$testRootDirectory = Split-Path -Parent $PSScriptRoot Import-Module (Join-Path $testRootDirectory "PSScriptAnalyzerTestHelper.psm1") - $editableTextType = "Microsoft.Windows.PowerShell.ScriptAnalyzer.EditableText" $textEditType = "Microsoft.Windows.PowerShell.ScriptAnalyzer.TextEdit" Describe "EditableText class" { - Context "When a sigle edit is given for application" { + Context "When a single edit is given for application" { It "Should replace in a single line string in the middle" { $def = 'This is just a single line.' $edit = New-Object -TypeName $textEditType -ArgumentList 1,14,1,22,"one" @@ -93,7 +90,6 @@ function foo { } '@ # Editor does not allow trailing white-spaces, hence this weird construct. - $s = ' ' $newText = @" [CmdletBinding()] diff --git a/Tests/Engine/Extensions.tests.ps1 b/Tests/Engine/Extensions.tests.ps1 index 72456b402..875c8ce96 100644 --- a/Tests/Engine/Extensions.tests.ps1 +++ b/Tests/Engine/Extensions.tests.ps1 @@ -1,5 +1,4 @@ -$directory = Split-Path -Parent $MyInvocation.MyCommand.Path -$testRootDirectory = Split-Path -Parent $directory +$testRootDirectory = Split-Path -Parent $PSScriptRoot Import-Module (Join-Path $testRootDirectory "PSScriptAnalyzerTestHelper.psm1") function Get-Extent { diff --git a/Tests/Engine/GetScriptAnalyzerRule.tests.ps1 b/Tests/Engine/GetScriptAnalyzerRule.tests.ps1 index d94d419c7..53ffe5e63 100644 --- a/Tests/Engine/GetScriptAnalyzerRule.tests.ps1 +++ b/Tests/Engine/GetScriptAnalyzerRule.tests.ps1 @@ -1,5 +1,4 @@ -$directory = Split-Path -Parent $MyInvocation.MyCommand.Path -$testRootDirectory = Split-Path -Parent $directory +$testRootDirectory = Split-Path -Parent $PSScriptRoot Import-Module (Join-Path $testRootDirectory 'PSScriptAnalyzerTestHelper.psm1') $sa = Get-Command Get-ScriptAnalyzerRule @@ -105,28 +104,28 @@ Describe "Test RuleExtension" { $expectedNumCommunityRules = 12 } It "with the module folder path" { - $ruleExtension = Get-ScriptAnalyzerRule -CustomizedRulePath $directory\CommunityAnalyzerRules | Where-Object {$_.SourceName -eq $community} + $ruleExtension = Get-ScriptAnalyzerRule -CustomizedRulePath $PSScriptRoot\CommunityAnalyzerRules | Where-Object {$_.SourceName -eq $community} $ruleExtension.Count | Should -Be $expectedNumCommunityRules } It "with the psd1 path" { - $ruleExtension = Get-ScriptAnalyzerRule -CustomizedRulePath $directory\CommunityAnalyzerRules\CommunityAnalyzerRules.psd1 | Where-Object {$_.SourceName -eq $community} + $ruleExtension = Get-ScriptAnalyzerRule -CustomizedRulePath $PSScriptRoot\CommunityAnalyzerRules\CommunityAnalyzerRules.psd1 | Where-Object {$_.SourceName -eq $community} $ruleExtension.Count | Should -Be $expectedNumCommunityRules } It "with the psm1 path" { - $ruleExtension = Get-ScriptAnalyzerRule -CustomizedRulePath $directory\CommunityAnalyzerRules\CommunityAnalyzerRules.psm1 | Where-Object {$_.SourceName -eq $community} + $ruleExtension = Get-ScriptAnalyzerRule -CustomizedRulePath $PSScriptRoot\CommunityAnalyzerRules\CommunityAnalyzerRules.psm1 | Where-Object {$_.SourceName -eq $community} $ruleExtension.Count | Should -Be $expectedNumCommunityRules } It "with Name of a built-in rules" { - $ruleExtension = Get-ScriptAnalyzerRule -CustomizedRulePath $directory\CommunityAnalyzerRules\CommunityAnalyzerRules.psm1 -Name $singularNouns + $ruleExtension = Get-ScriptAnalyzerRule -CustomizedRulePath $PSScriptRoot\CommunityAnalyzerRules\CommunityAnalyzerRules.psm1 -Name $singularNouns $ruleExtension.Count | Should -Be 0 } It "with Names of built-in, DSC and non-built-in rules" { - $ruleExtension = Get-ScriptAnalyzerRule -CustomizedRulePath $directory\CommunityAnalyzerRules\CommunityAnalyzerRules.psm1 -Name $singularNouns, $measureRequired, $dscIdentical + $ruleExtension = Get-ScriptAnalyzerRule -CustomizedRulePath $PSScriptRoot\CommunityAnalyzerRules\CommunityAnalyzerRules.psm1 -Name $singularNouns, $measureRequired, $dscIdentical $ruleExtension.Count | Should -Be 1 ($ruleExtension | Where-Object {$_.RuleName -eq $measureRequired}).Count | Should -Be 1 ($ruleExtension | Where-Object {$_.RuleName -eq $singularNouns}).Count | Should -Be 0 diff --git a/Tests/Engine/GlobalSuppression.test.ps1 b/Tests/Engine/GlobalSuppression.test.ps1 index 74e23fc48..76da8fc36 100644 --- a/Tests/Engine/GlobalSuppression.test.ps1 +++ b/Tests/Engine/GlobalSuppression.test.ps1 @@ -6,11 +6,10 @@ if (!(Get-Module PSScriptAnalyzer) -and !$testingLibraryUsage) Import-Module -Verbose PSScriptAnalyzer } -$directory = Split-Path -Parent $MyInvocation.MyCommand.Path -$violations = Invoke-ScriptAnalyzer "$directory\GlobalSuppression.ps1" -$violationsUsingScriptDefinition = Invoke-ScriptAnalyzer -ScriptDefinition (Get-Content -Raw "$directory\GlobalSuppression.ps1") -$suppression = Invoke-ScriptAnalyzer "$directory\GlobalSuppression.ps1" -Profile "$directory\Profile.ps1" -$suppressionUsingScriptDefinition = Invoke-ScriptAnalyzer -ScriptDefinition (Get-Content -Raw "$directory\GlobalSuppression.ps1") -Profile "$directory\Profile.ps1" +$violations = Invoke-ScriptAnalyzer "$PSScriptRoot\GlobalSuppression.ps1" +$violationsUsingScriptDefinition = Invoke-ScriptAnalyzer -ScriptDefinition (Get-Content -Raw "$PSScriptRoot\GlobalSuppression.ps1") +$suppression = Invoke-ScriptAnalyzer "$PSScriptRoot\GlobalSuppression.ps1" -Profile "$PSScriptRoot\Profile.ps1" +$suppressionUsingScriptDefinition = Invoke-ScriptAnalyzer -ScriptDefinition (Get-Content -Raw "$PSScriptRoot\GlobalSuppression.ps1") -Profile "$PSScriptRoot\Profile.ps1" Describe "GlobalSuppression" { Context "Exclude Rule" { @@ -29,11 +28,11 @@ Describe "GlobalSuppression" { } It "Does not raise any violation for cmdlet alias using configuration hashtable" { - $hashtableConfiguration = Invoke-ScriptAnalyzer "$directory\GlobalSuppression.ps1" -Configuration @{"excluderules" = "PSAvoidUsingCmdletAliases"} | + $hashtableConfiguration = Invoke-ScriptAnalyzer "$PSScriptRoot\GlobalSuppression.ps1" -Configuration @{"excluderules" = "PSAvoidUsingCmdletAliases"} | Where-Object { $_.RuleName -eq "PSAvoidUsingCmdletAliases"} $hashtableConfiguration.Count | Should -Be 0 - $hashtableConfiguration = Invoke-ScriptAnalyzer -ScriptDefinition (Get-Content -Raw "$directory\GlobalSuppression.ps1") -Configuration @{"excluderules" = "PSAvoidUsingCmdletAliases"} | + $hashtableConfiguration = Invoke-ScriptAnalyzer -ScriptDefinition (Get-Content -Raw "$PSScriptRoot\GlobalSuppression.ps1") -Configuration @{"excluderules" = "PSAvoidUsingCmdletAliases"} | Where-Object { $_.RuleName -eq "PSAvoidUsingCmdletAliases"} $hashtableConfiguration.Count | Should -Be 0 } @@ -53,9 +52,9 @@ Describe "GlobalSuppression" { $withProfile = $suppressionUsingScriptDefinition | Where-Object { $_.RuleName -eq "PSAvoidUsingComputerNameHardcoded" } $withProfile.Count | Should -Be 0 } - + It "Does not raise any violation for computername hard-coded using configuration hashtable" { - $hashtableConfiguration = Invoke-ScriptAnalyzer "$directory\GlobalSuppression.ps1" -Settings @{"includerules" = @("PSAvoidUsingCmdletAliases", "PSUseOutputTypeCorrectly")} | + $hashtableConfiguration = Invoke-ScriptAnalyzer "$PSScriptRoot\GlobalSuppression.ps1" -Settings @{"includerules" = @("PSAvoidUsingCmdletAliases", "PSUseOutputTypeCorrectly")} | Where-Object { $_.RuleName -eq "PSAvoidUsingComputerNameHardcoded"} $hashtableConfiguration.Count | Should -Be 0 } @@ -77,7 +76,7 @@ Describe "GlobalSuppression" { } It "Does not raise any violation for use output type correctly with configuration hashtable" { - $hashtableConfiguration = Invoke-ScriptAnalyzer "$directory\GlobalSuppression.ps1" -Settings @{"severity" = "warning"} | + $hashtableConfiguration = Invoke-ScriptAnalyzer "$PSScriptRoot\GlobalSuppression.ps1" -Settings @{"severity" = "warning"} | Where-Object {$_.RuleName -eq "PSUseOutputTypeCorrectly"} $hashtableConfiguration.Count | Should -Be 0 } @@ -85,19 +84,19 @@ Describe "GlobalSuppression" { Context "Error Case" { It "Raises Error for file not found" { - $invokeWithError = Invoke-ScriptAnalyzer "$directory\GlobalSuppression.ps1" -Settings ".\ThisFileDoesNotExist.ps1" -ErrorAction SilentlyContinue + $invokeWithError = Invoke-ScriptAnalyzer "$PSScriptRoot\GlobalSuppression.ps1" -Settings ".\ThisFileDoesNotExist.ps1" -ErrorAction SilentlyContinue $invokeWithError.Count | Should -Be 0 $Error[0].FullyQualifiedErrorId | Should -Match "SettingsFileNotFound,Microsoft.Windows.PowerShell.ScriptAnalyzer.Commands.InvokeScriptAnalyzerCommand" } It "Raises Error for file with no hash table" { - $invokeWithError = Invoke-ScriptAnalyzer "$directory\GlobalSuppression.ps1" -Settings "$directory\GlobalSuppression.ps1" -ErrorAction SilentlyContinue + $invokeWithError = Invoke-ScriptAnalyzer "$PSScriptRoot\GlobalSuppression.ps1" -Settings "$PSScriptRoot\GlobalSuppression.ps1" -ErrorAction SilentlyContinue $invokeWithError.Count | Should -Be 0 $Error[0].FullyQualifiedErrorId | Should -Match "SettingsFileHasNoHashTable,Microsoft.Windows.PowerShell.ScriptAnalyzer.Commands.InvokeScriptAnalyzerCommand" } It "Raises Error for wrong profile" { - $invokeWithError = Invoke-ScriptAnalyzer "$directory\GlobalSuppression.ps1" -Settings "$directory\WrongProfile.ps1" -ErrorAction SilentlyContinue + $invokeWithError = Invoke-ScriptAnalyzer "$PSScriptRoot\GlobalSuppression.ps1" -Settings "$PSScriptRoot\WrongProfile.ps1" -ErrorAction SilentlyContinue $invokeWithError.Count | Should -Be 0 $Error[0].FullyQualifiedErrorId | Should -Match "WrongSettingsKey,Microsoft.Windows.PowerShell.ScriptAnalyzer.Commands.InvokeScriptAnalyzerCommand" } diff --git a/Tests/Engine/InvokeFormatter.tests.ps1 b/Tests/Engine/InvokeFormatter.tests.ps1 index e1c51be1a..39f248865 100644 --- a/Tests/Engine/InvokeFormatter.tests.ps1 +++ b/Tests/Engine/InvokeFormatter.tests.ps1 @@ -1,5 +1,4 @@ -$directory = Split-Path -Parent $MyInvocation.MyCommand.Path -$testRootDirectory = Split-Path -Parent $directory +$testRootDirectory = Split-Path -Parent $PSScriptRoot Import-Module (Join-Path $testRootDirectory "PSScriptAnalyzerTestHelper.psm1") Describe "Invoke-Formatter Cmdlet" { diff --git a/Tests/Engine/InvokeScriptAnalyzer.tests.ps1 b/Tests/Engine/InvokeScriptAnalyzer.tests.ps1 index 3cc9351af..15cae10e5 100644 --- a/Tests/Engine/InvokeScriptAnalyzer.tests.ps1 +++ b/Tests/Engine/InvokeScriptAnalyzer.tests.ps1 @@ -1,5 +1,4 @@ $sa = Get-Command Invoke-ScriptAnalyzer -$directory = Split-Path -Parent $MyInvocation.MyCommand.Path $singularNouns = "PSUseSingularNouns" $approvedVerb = "PSUseApprovedVerbs" $rules = Get-ScriptAnalyzerRule -Name ($singularNouns, "PSUseApprovedVerbs") @@ -125,7 +124,7 @@ Describe "Test ScriptDefinition" { Describe "Test Path" { Context "When given a single file" { It "Has the same effect as without Path parameter" { - $scriptPath = Join-Path $directory "TestScript.ps1" + $scriptPath = Join-Path $PSScriptRoot "TestScript.ps1" $withPath = Invoke-ScriptAnalyzer $scriptPath $withoutPath = Invoke-ScriptAnalyzer -Path $scriptPath $withPath.Count | Should -Be $withoutPath.Count @@ -144,8 +143,8 @@ Describe "Test Path" { Context "DiagnosticRecord " { It "has valid ScriptPath and ScriptName properties when an input file is given" { $scriptName = "TestScript.ps1" - $scriptPath = Join-Path $directory $scriptName - $expectedScriptPath = Resolve-Path $directory\TestScript.ps1 + $scriptPath = Join-Path $PSScriptRoot $scriptName + $expectedScriptPath = Resolve-Path $PSScriptRoot\TestScript.ps1 $diagnosticRecords = Invoke-ScriptAnalyzer $scriptPath -IncludeRule "PSAvoidUsingEmptyCatchBlock" $diagnosticRecords[0].ScriptPath | Should -Be $expectedScriptPath.Path $diagnosticRecords[0].ScriptName | Should -Be $scriptName @@ -175,8 +174,8 @@ Describe "Test Path" { Context "When given a glob" { It "Invokes on all the matching files" { - $numFilesResult = (Invoke-ScriptAnalyzer -Path $directory\TestTestPath*.ps1 | Select-Object -Property ScriptName -Unique).Count - $numFilesExpected = (Get-ChildItem -Path $directory\TestTestPath*.ps1).Count + $numFilesResult = (Invoke-ScriptAnalyzer -Path $PSScriptRoot\TestTestPath*.ps1 | Select-Object -Property ScriptName -Unique).Count + $numFilesExpected = (Get-ChildItem -Path $PSScriptRoot\TestTestPath*.ps1).Count $numFilesResult | Should -Be $numFilesExpected } } @@ -185,7 +184,7 @@ Describe "Test Path" { It "Recognizes the path" { $freeDriveNameLen = 2 $freeDrive, $freeDriveName = GetFreeDrive $freeDriveNameLen - New-PSDrive -Name $freeDriveName -PSProvider FileSystem -Root $directory + New-PSDrive -Name $freeDriveName -PSProvider FileSystem -Root $PSScriptRoot $numFilesExpected = (Get-ChildItem -Path $freeDrive\TestTestPath*.ps1).Count $numFilesResult = (Invoke-ScriptAnalyzer -Path $freeDrive\TestTestPath*.ps1 | Select-Object -Property ScriptName -Unique).Count Remove-PSDrive $freeDriveName @@ -195,23 +194,23 @@ Describe "Test Path" { Context "When piping in files" { It "Can be piped in from a string" { - $piped = ("$directory\TestScript.ps1" | Invoke-ScriptAnalyzer) - $explicit = Invoke-ScriptAnalyzer -Path $directory\TestScript.ps1 + $piped = ("$PSScriptRoot\TestScript.ps1" | Invoke-ScriptAnalyzer) + $explicit = Invoke-ScriptAnalyzer -Path $PSScriptRoot\TestScript.ps1 $piped.Count | Should Be $explicit.Count } It "Can be piped from Get-ChildItem" { - $piped = ( Get-ChildItem -Path $directory -Filter TestTestPath*.ps1 | Invoke-ScriptAnalyzer) - $explicit = Invoke-ScriptAnalyzer -Path $directory\TestTestPath*.ps1 + $piped = ( Get-ChildItem -Path $PSScriptRoot -Filter TestTestPath*.ps1 | Invoke-ScriptAnalyzer) + $explicit = Invoke-ScriptAnalyzer -Path $PSScriptRoot\TestTestPath*.ps1 $piped.Count | Should Be $explicit.Count } } } Context "When given a directory" { - $withoutPathWithDirectory = Invoke-ScriptAnalyzer -Recurse $directory\RecursionDirectoryTest - $withPathWithDirectory = Invoke-ScriptAnalyzer -Recurse -Path $directory\RecursionDirectoryTest + $withoutPathWithDirectory = Invoke-ScriptAnalyzer -Recurse $PSScriptRoot\RecursionDirectoryTest + $withPathWithDirectory = Invoke-ScriptAnalyzer -Recurse -Path $PSScriptRoot\RecursionDirectoryTest It "Has the same count as without Path parameter"{ $withoutPathWithDirectory.Count -eq $withPathWithDirectory.Count | Should -BeTrue @@ -232,27 +231,27 @@ Describe "Test Path" { Describe "Test ExcludeRule" { Context "When used correctly" { It "excludes 1 rule" { - $noViolations = Invoke-ScriptAnalyzer $directory\..\Rules\BadCmdlet.ps1 -ExcludeRule $singularNouns | Where-Object {$_.RuleName -eq $singularNouns} + $noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\..\Rules\BadCmdlet.ps1 -ExcludeRule $singularNouns | Where-Object {$_.RuleName -eq $singularNouns} $noViolations.Count | Should -Be 0 } It "excludes 3 rules" { - $noViolations = Invoke-ScriptAnalyzer $directory\..\Rules\BadCmdlet.ps1 -ExcludeRule $rules | Where-Object {$rules -contains $_.RuleName} + $noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\..\Rules\BadCmdlet.ps1 -ExcludeRule $rules | Where-Object {$rules -contains $_.RuleName} $noViolations.Count | Should -Be 0 } } Context "When used incorrectly" { It "does not exclude any rules" { - $noExclude = Invoke-ScriptAnalyzer $directory\..\Rules\BadCmdlet.ps1 - $withExclude = Invoke-ScriptAnalyzer $directory\..\Rules\BadCmdlet.ps1 -ExcludeRule "This is a wrong rule" + $noExclude = Invoke-ScriptAnalyzer $PSScriptRoot\..\Rules\BadCmdlet.ps1 + $withExclude = Invoke-ScriptAnalyzer $PSScriptRoot\..\Rules\BadCmdlet.ps1 -ExcludeRule "This is a wrong rule" $withExclude.Count -eq $noExclude.Count | Should -BeTrue } } Context "Support wild card" { It "supports wild card exclusions of input rules"{ - $excludeWildCard = Invoke-ScriptAnalyzer $directory\..\Rules\BadCmdlet.ps1 -ExcludeRule $avoidRules | Where-Object {$_.RuleName -match $avoidRules} + $excludeWildCard = Invoke-ScriptAnalyzer $PSScriptRoot\..\Rules\BadCmdlet.ps1 -ExcludeRule $avoidRules | Where-Object {$_.RuleName -match $avoidRules} } } @@ -261,44 +260,44 @@ Describe "Test ExcludeRule" { Describe "Test IncludeRule" { Context "When used correctly" { It "includes 1 rule" { - $violations = Invoke-ScriptAnalyzer $directory\..\Rules\BadCmdlet.ps1 -IncludeRule $approvedVerb | Where-Object {$_.RuleName -eq $approvedVerb} + $violations = Invoke-ScriptAnalyzer $PSScriptRoot\..\Rules\BadCmdlet.ps1 -IncludeRule $approvedVerb | Where-Object {$_.RuleName -eq $approvedVerb} $violations.Count | Should -Be 1 } It "includes the given rules" { # CoreCLR version of PSScriptAnalyzer does not contain PSUseSingularNouns rule $expectedNumViolations = 2 - if ((Test-PSEditionCoreCLR)) + if ([bool] $IsCoreCLR) { $expectedNumViolations = 1 } - $violations = Invoke-ScriptAnalyzer $directory\..\Rules\BadCmdlet.ps1 -IncludeRule $rules + $violations = Invoke-ScriptAnalyzer $PSScriptRoot\..\Rules\BadCmdlet.ps1 -IncludeRule $rules $violations.Count | Should -Be $expectedNumViolations } } Context "When used incorrectly" { It "does not include any rules" { - $wrongInclude = Invoke-ScriptAnalyzer $directory\..\Rules\BadCmdlet.ps1 -IncludeRule "This is a wrong rule" + $wrongInclude = Invoke-ScriptAnalyzer $PSScriptRoot\..\Rules\BadCmdlet.ps1 -IncludeRule "This is a wrong rule" $wrongInclude.Count | Should -Be 0 } } Context "IncludeRule supports wild card" { It "includes 1 wildcard rule"{ - $includeWildcard = Invoke-ScriptAnalyzer $directory\..\Rules\BadCmdlet.ps1 -IncludeRule $avoidRules + $includeWildcard = Invoke-ScriptAnalyzer $PSScriptRoot\..\Rules\BadCmdlet.ps1 -IncludeRule $avoidRules $includeWildcard.Count | Should -Be 0 } it "includes 2 wildcardrules" { # CoreCLR version of PSScriptAnalyzer does not contain PSUseSingularNouns rule $expectedNumViolations = 4 - if ((Test-PSEditionCoreCLR)) + if ([bool] $IsCoreCLR) { $expectedNumViolations = 3 } - $includeWildcard = Invoke-ScriptAnalyzer $directory\..\Rules\BadCmdlet.ps1 -IncludeRule $avoidRules - $includeWildcard += Invoke-ScriptAnalyzer $directory\..\Rules\BadCmdlet.ps1 -IncludeRule $useRules + $includeWildcard = Invoke-ScriptAnalyzer $PSScriptRoot\..\Rules\BadCmdlet.ps1 -IncludeRule $avoidRules + $includeWildcard += Invoke-ScriptAnalyzer $PSScriptRoot\..\Rules\BadCmdlet.ps1 -IncludeRule $useRules $includeWildcard.Count | Should -Be $expectedNumViolations } } @@ -306,12 +305,12 @@ Describe "Test IncludeRule" { Describe "Test Exclude And Include" {1 It "Exclude and Include different rules" { - $violations = Invoke-ScriptAnalyzer $directory\TestScript.ps1 -IncludeRule "PSAvoidUsingEmptyCatchBlock" -ExcludeRule "PSAvoidUsingPositionalParameters" + $violations = Invoke-ScriptAnalyzer $PSScriptRoot\TestScript.ps1 -IncludeRule "PSAvoidUsingEmptyCatchBlock" -ExcludeRule "PSAvoidUsingPositionalParameters" $violations.Count | Should -Be 1 } It "Exclude and Include the same rule" { - $violations = Invoke-ScriptAnalyzer $directory\TestScript.ps1 -IncludeRule "PSAvoidUsingEmptyCatchBlock" -ExcludeRule "PSAvoidUsingEmptyCatchBlock" + $violations = Invoke-ScriptAnalyzer $PSScriptRoot\TestScript.ps1 -IncludeRule "PSAvoidUsingEmptyCatchBlock" -ExcludeRule "PSAvoidUsingEmptyCatchBlock" $violations.Count | Should -Be 0 } } @@ -345,22 +344,22 @@ Describe "Test Severity" { Context "When used correctly" { It "works with one argument" { - $errors = Invoke-ScriptAnalyzer $directory\TestScript.ps1 -Severity Information + $errors = Invoke-ScriptAnalyzer $PSScriptRoot\TestScript.ps1 -Severity Information $errors.Count | Should -Be 0 } It "works with 2 arguments" { - $errors = Invoke-ScriptAnalyzer $directory\TestScript.ps1 -Severity Information, Warning + $errors = Invoke-ScriptAnalyzer $PSScriptRoot\TestScript.ps1 -Severity Information, Warning $errors.Count | Should -Be 1 } It "works with lowercase argument"{ - $errors = Invoke-ScriptAnalyzer $directory\TestScript.ps1 -Severity information, warning + $errors = Invoke-ScriptAnalyzer $PSScriptRoot\TestScript.ps1 -Severity information, warning $errors.Count | Should -Be 1 } It "works for dsc rules" { - $testDataPath = [System.IO.Path]::Combine($(Split-Path $directory -Parent), ` + $testDataPath = [System.IO.Path]::Combine($(Split-Path $PSScriptRoot -Parent), ` 'Rules', ` 'DSCResourceModule', ` 'DSCResources', ` @@ -383,7 +382,7 @@ Describe "Test Severity" { Context "When used incorrectly" { It "throws error" { - { Invoke-ScriptAnalyzer -Severity "Wrong" $directory\TestScript.ps1 } | Should -Throw + { Invoke-ScriptAnalyzer -Severity "Wrong" $PSScriptRoot\TestScript.ps1 } | Should -Throw } } } @@ -392,33 +391,33 @@ Describe "Test CustomizedRulePath" { $measureRequired = "CommunityAnalyzerRules\Measure-RequiresModules" Context "When used correctly" { It "with the module folder path" { - $customizedRulePath = Invoke-ScriptAnalyzer $directory\TestScript.ps1 -CustomizedRulePath $directory\CommunityAnalyzerRules | Where-Object {$_.RuleName -eq $measureRequired} + $customizedRulePath = Invoke-ScriptAnalyzer $PSScriptRoot\TestScript.ps1 -CustomizedRulePath $PSScriptRoot\CommunityAnalyzerRules | Where-Object {$_.RuleName -eq $measureRequired} $customizedRulePath.Count | Should -Be 1 } It "with the psd1 path" { - $customizedRulePath = Invoke-ScriptAnalyzer $directory\TestScript.ps1 -CustomizedRulePath $directory\CommunityAnalyzerRules\CommunityAnalyzerRules.psd1 | Where-Object {$_.RuleName -eq $measureRequired} + $customizedRulePath = Invoke-ScriptAnalyzer $PSScriptRoot\TestScript.ps1 -CustomizedRulePath $PSScriptRoot\CommunityAnalyzerRules\CommunityAnalyzerRules.psd1 | Where-Object {$_.RuleName -eq $measureRequired} $customizedRulePath.Count | Should -Be 1 } It "with the psm1 path" { - $customizedRulePath = Invoke-ScriptAnalyzer $directory\TestScript.ps1 -CustomizedRulePath $directory\CommunityAnalyzerRules\CommunityAnalyzerRules.psm1 | Where-Object {$_.RuleName -eq $measureRequired} + $customizedRulePath = Invoke-ScriptAnalyzer $PSScriptRoot\TestScript.ps1 -CustomizedRulePath $PSScriptRoot\CommunityAnalyzerRules\CommunityAnalyzerRules.psm1 | Where-Object {$_.RuleName -eq $measureRequired} $customizedRulePath.Count | Should -Be 1 } It "with IncludeRule" { - $customizedRulePathInclude = Invoke-ScriptAnalyzer $directory\TestScript.ps1 -CustomizedRulePath $directory\CommunityAnalyzerRules\CommunityAnalyzerRules.psm1 -IncludeRule "Measure-RequiresModules" + $customizedRulePathInclude = Invoke-ScriptAnalyzer $PSScriptRoot\TestScript.ps1 -CustomizedRulePath $PSScriptRoot\CommunityAnalyzerRules\CommunityAnalyzerRules.psm1 -IncludeRule "Measure-RequiresModules" $customizedRulePathInclude.Count | Should -Be 1 } It "with ExcludeRule" { - $customizedRulePathExclude = Invoke-ScriptAnalyzer $directory\TestScript.ps1 -CustomizedRulePath $directory\CommunityAnalyzerRules\CommunityAnalyzerRules.psm1 -ExcludeRule "Measure-RequiresModules" | Where-Object {$_.RuleName -eq $measureRequired} + $customizedRulePathExclude = Invoke-ScriptAnalyzer $PSScriptRoot\TestScript.ps1 -CustomizedRulePath $PSScriptRoot\CommunityAnalyzerRules\CommunityAnalyzerRules.psm1 -ExcludeRule "Measure-RequiresModules" | Where-Object {$_.RuleName -eq $measureRequired} $customizedRulePathExclude.Count | Should -Be 0 } It "When supplied with a collection of paths" { - $customizedRulePath = Invoke-ScriptAnalyzer $directory\TestScript.ps1 -CustomRulePath ("$directory\CommunityAnalyzerRules", "$directory\samplerule", "$directory\samplerule\samplerule2") + $customizedRulePath = Invoke-ScriptAnalyzer $PSScriptRoot\TestScript.ps1 -CustomRulePath ("$PSScriptRoot\CommunityAnalyzerRules", "$PSScriptRoot\samplerule", "$PSScriptRoot\samplerule\samplerule2") $customizedRulePath.Count | Should -Be 3 } } @@ -457,34 +456,34 @@ Describe "Test CustomizedRulePath" { It "Should use the CustomRulePath parameter" { $settings = @{ - CustomRulePath = "$directory\CommunityAnalyzerRules" + CustomRulePath = "$PSScriptRoot\CommunityAnalyzerRules" IncludeDefaultRules = $false RecurseCustomRulePath = $false } - $v = Invoke-ScriptAnalyzer -Path $directory\TestScript.ps1 -Settings $settings + $v = Invoke-ScriptAnalyzer -Path $PSScriptRoot\TestScript.ps1 -Settings $settings $v.Count | Should -Be 1 } It "Should use the IncludeDefaultRulePath parameter" { $settings = @{ - CustomRulePath = "$directory\CommunityAnalyzerRules" + CustomRulePath = "$PSScriptRoot\CommunityAnalyzerRules" IncludeDefaultRules = $true RecurseCustomRulePath = $false } - $v = Invoke-ScriptAnalyzer -Path $directory\TestScript.ps1 -Settings $settings + $v = Invoke-ScriptAnalyzer -Path $PSScriptRoot\TestScript.ps1 -Settings $settings $v.Count | Should -Be 2 } It "Should use the RecurseCustomRulePath parameter" { $settings = @{ - CustomRulePath = "$directory\samplerule" + CustomRulePath = "$PSScriptRoot\samplerule" IncludeDefaultRules = $false RecurseCustomRulePath = $true } - $v = Invoke-ScriptAnalyzer -Path $directory\TestScript.ps1 -Settings $settings + $v = Invoke-ScriptAnalyzer -Path $PSScriptRoot\TestScript.ps1 -Settings $settings $v.Count | Should -Be 3 } } @@ -492,18 +491,18 @@ Describe "Test CustomizedRulePath" { Context "When used from settings file and command line simulataneusly" { BeforeAll { $settings = @{ - CustomRulePath = "$directory\samplerule" + CustomRulePath = "$PSScriptRoot\samplerule" IncludeDefaultRules = $false RecurseCustomRulePath = $false } $isaParams = @{ - Path = "$directory\TestScript.ps1" + Path = "$PSScriptRoot\TestScript.ps1" Settings = $settings } } It "Should combine CustomRulePaths" { - $v = Invoke-ScriptAnalyzer @isaParams -CustomRulePath "$directory\CommunityAnalyzerRules" + $v = Invoke-ScriptAnalyzer @isaParams -CustomRulePath "$PSScriptRoot\CommunityAnalyzerRules" $v.Count | Should -Be 2 } @@ -523,7 +522,7 @@ Describe "Test CustomizedRulePath" { It "file cannot be found" { try { - Invoke-ScriptAnalyzer $directory\TestScript.ps1 -CustomRulePath "Invalid CustomRulePath" + Invoke-ScriptAnalyzer $PSScriptRoot\TestScript.ps1 -CustomRulePath "Invalid CustomRulePath" } catch { diff --git a/Tests/Engine/LibraryUsage.tests.ps1 b/Tests/Engine/LibraryUsage.tests.ps1 index dc0c88daa..f479f468c 100644 --- a/Tests/Engine/LibraryUsage.tests.ps1 +++ b/Tests/Engine/LibraryUsage.tests.ps1 @@ -1,17 +1,15 @@ -$directory = Split-Path -Parent $MyInvocation.MyCommand.Path -$testRootDirectory = Split-Path -Parent $directory +$testRootDirectory = Split-Path -Parent $PSScriptRoot Import-Module (Join-Path $testRootDirectory 'PSScriptAnalyzerTestHelper.psm1') # test is meant to verify functionality if csharp apis are used. Hence not if psedition is CoreCLR -if ((Test-PSEditionCoreCLR)) +if (([bool] $IsCoreCLR)) { return } -$directory = Split-Path -Parent $MyInvocation.MyCommand.Path # Overwrite Invoke-ScriptAnalyzer with a version that -# wraps the usage of ScriptAnalyzer as a .NET library +# wraps the usage of ScriptAnalyzer as a .NET library function Invoke-ScriptAnalyzer { param ( [CmdletBinding(DefaultParameterSetName="File", SupportsShouldProcess = $true)] @@ -34,12 +32,12 @@ function Invoke-ScriptAnalyzer { [string[]] $ExcludeRule = $null, [Parameter(Mandatory = $false)] - [string[]] $IncludeRule = $null, + [string[]] $IncludeRule = $null, [ValidateSet("Warning", "Error", "Information", "ParseError", IgnoreCase = $true)] [Parameter(Mandatory = $false)] [string[]] $Severity = $null, - + [Parameter(Mandatory = $false)] [switch] $Recurse, @@ -54,7 +52,7 @@ function Invoke-ScriptAnalyzer { [Parameter(Mandatory = $false)] [switch] $EnableExit, - + [Parameter(Mandatory = $false)] [switch] $ReportSummary ) @@ -63,18 +61,18 @@ function Invoke-ScriptAnalyzer { { $IncludeDefaultRules = $true } - # There is an inconsistency between this implementation and c# implementation of the cmdlet. + # There is an inconsistency between this implementation and c# implementation of the cmdlet. # The CustomRulePath parameter here is of "string[]" type whereas in the c# implementation it is of "string" type. - # If we set the CustomRulePath parameter here to "string[]", then the library usage test fails when run as an administrator. + # If we set the CustomRulePath parameter here to "string[]", then the library usage test fails when run as an administrator. # We want to note that the library usage test doesn't fail when run as a non-admin user. - # The following is the error statement when the test runs as an administrator. + # The following is the error statement when the test runs as an administrator. # Assert failed on "Initialize" with "7" argument(s): "Test failed due to terminating error: The module was expected to contain an assembly manifest. (Exception from HRESULT: 0x80131018)" $scriptAnalyzer = New-Object "Microsoft.Windows.PowerShell.ScriptAnalyzer.ScriptAnalyzer"; $scriptAnalyzer.Initialize( - $runspace, - $testOutputWriter, - $CustomRulePath, + $runspace, + $testOutputWriter, + $CustomRulePath, $IncludeRule, $ExcludeRule, $Severity, @@ -98,7 +96,7 @@ function Invoke-ScriptAnalyzer { { $results = $scriptAnalyzer.AnalyzeScriptDefinition($ScriptDefinition); } - + $results if ($ReportSummary.IsPresent) @@ -113,7 +111,7 @@ function Invoke-ScriptAnalyzer { Write-Host '0 rule violations found.' -ForegroundColor Green } } - + if ($EnableExit.IsPresent -and $null -ne $results) { exit $results.Count @@ -126,7 +124,7 @@ using System.Management.Automation; using System.Management.Automation.Host; using Microsoft.Windows.PowerShell.ScriptAnalyzer; -public class PesterTestOutputWriter : IOutputWriter +public class PesterTestOutputWriter : IOutputWriter { private PSHost psHost; @@ -166,8 +164,8 @@ public class PesterTestOutputWriter : IOutputWriter public void ThrowTerminatingError(ErrorRecord record) { throw new RuntimeException( - "Test failed due to terminating error: \r\n" + record.ToString(), - null, + "Test failed due to terminating error: \r\n" + record.ToString(), + null, record); } } @@ -192,7 +190,7 @@ $null,"Wow6432Node" | ForEach-Object { try { Set-ItemProperty -Name "DisablePromptToUpdateHelp" -Path "HKLM:\SOFTWARE\$($_)\Microsoft\PowerShell" -Value 1 -Force -ErrorAction SilentlyContinue - } + } catch { # Ignore for cases when tests are running in non-elevated more or registry key does not exist or not accessible @@ -200,9 +198,9 @@ $null,"Wow6432Node" | ForEach-Object { } # Invoke existing test files that use Invoke-ScriptAnalyzer -. $directory\InvokeScriptAnalyzer.tests.ps1 -. $directory\RuleSuppression.tests.ps1 -. $directory\CustomizedRule.tests.ps1 +. $PSScriptRoot\InvokeScriptAnalyzer.tests.ps1 +. $PSScriptRoot\RuleSuppression.tests.ps1 +. $PSScriptRoot\CustomizedRule.tests.ps1 # We're done testing library usage $testingLibraryUsage = $false diff --git a/Tests/Engine/ModuleDependencyHandler.tests.ps1 b/Tests/Engine/ModuleDependencyHandler.tests.ps1 index a392150f5..22045644e 100644 --- a/Tests/Engine/ModuleDependencyHandler.tests.ps1 +++ b/Tests/Engine/ModuleDependencyHandler.tests.ps1 @@ -1,5 +1,3 @@ -$directory = Split-Path -Parent $MyInvocation.MyCommand.Path - Describe "Resolve DSC Resource Dependency" { BeforeAll { $skipTest = $false # Test that require DSC to be installed @@ -19,8 +17,8 @@ Describe "Resolve DSC Resource Dependency" { $savedPSModulePath = $env:PSModulePath $violationFileName = 'MissingDSCResource.ps1' - $violationFilePath = Join-Path $directory $violationFileName - $testRootDirectory = Split-Path -Parent $directory + $violationFilePath = Join-Path $PSScriptRoot $violationFileName + $testRootDirectory = Split-Path -Parent $PSScriptRoot Import-Module (Join-Path $testRootDirectory 'PSScriptAnalyzerTestHelper.psm1') Function Test-EnvironmentVariables($oldEnv) @@ -186,7 +184,7 @@ Describe "Resolve DSC Resource Dependency" { if ( $skipTest ) { return } $oldEnvVars = Get-Item Env:\* | Sort-Object -Property Key $moduleName = "MyDscResource" - $modulePath = "$(Split-Path $directory)\Rules\DSCResourceModule\DSCResources\$moduleName" + $modulePath = "$(Split-Path $PSScriptRoot)\Rules\DSCResourceModule\DSCResources\$moduleName" # Save the current environment variables $oldLocalAppDataPath = Get-LocalAppDataFolder diff --git a/Tests/Engine/RuleSuppression.tests.ps1 b/Tests/Engine/RuleSuppression.tests.ps1 index a3fd9a07b..5aeff14e9 100644 --- a/Tests/Engine/RuleSuppression.tests.ps1 +++ b/Tests/Engine/RuleSuppression.tests.ps1 @@ -1,9 +1,8 @@ -$directory = Split-Path -Parent $MyInvocation.MyCommand.Path -$testRootDirectory = Split-Path -Parent $directory +$testRootDirectory = Split-Path -Parent $PSScriptRoot Import-Module (Join-Path $testRootDirectory 'PSScriptAnalyzerTestHelper.psm1') -$violationsUsingScriptDefinition = Invoke-ScriptAnalyzer -ScriptDefinition (Get-Content -Raw "$directory\RuleSuppression.ps1") -$violations = Invoke-ScriptAnalyzer "$directory\RuleSuppression.ps1" +$violationsUsingScriptDefinition = Invoke-ScriptAnalyzer -ScriptDefinition (Get-Content -Raw "$PSScriptRoot\RuleSuppression.ps1") +$violations = Invoke-ScriptAnalyzer "$PSScriptRoot\RuleSuppression.ps1" $ruleSuppressionBad = @' Function do-something @@ -123,7 +122,7 @@ Write-Host "write-host" It "Suppresses violation of an external ast rule" { Invoke-ScriptAnalyzer ` -ScriptDefinition $externalRuleSuppression ` - -CustomRulePath (Join-Path $directory "CommunityAnalyzerRules") ` + -CustomRulePath (Join-Path $PSScriptRoot "CommunityAnalyzerRules") ` -OutVariable ruleViolations ` -SuppressedOnly $ruleViolations.Count | Should -Be 1 diff --git a/Tests/Engine/RuleSuppressionClass.tests.ps1 b/Tests/Engine/RuleSuppressionClass.tests.ps1 index 94d26057b..22e5fcd20 100644 --- a/Tests/Engine/RuleSuppressionClass.tests.ps1 +++ b/Tests/Engine/RuleSuppressionClass.tests.ps1 @@ -3,11 +3,10 @@ if ($PSVersionTable.PSVersion -ge [Version]'5.0.0') { $script:skipForV3V4 = $false } -$directory = Split-Path -Parent $MyInvocation.MyCommand.Path -$violationsUsingScriptDefinition = Invoke-ScriptAnalyzer -ScriptDefinition (Get-Content -Raw "$directory\RuleSuppression.ps1") -$violations = Invoke-ScriptAnalyzer "$directory\RuleSuppression.ps1" +$violationsUsingScriptDefinition = Invoke-ScriptAnalyzer -ScriptDefinition (Get-Content -Raw "$PSScriptRoot\RuleSuppression.ps1") +$violations = Invoke-ScriptAnalyzer "$PSScriptRoot\RuleSuppression.ps1" -Describe "RuleSuppressionWithoutScope" { +Describe "RuleSuppressionWithoutScope" { Context "Class" { It "Does not raise violations" -skip:$script:skipForV3V4 { @@ -24,7 +23,7 @@ Describe "RuleSuppressionWithoutScope" { $suppression.Count | Should -Be 0 $suppression = $violationsUsingScriptDefinition | Where-Object {$_.RuleName -eq "PSAvoidUsingCmdletAliases" } $suppression.Count | Should -Be 0 - } + } } Context "Script" { diff --git a/Tests/Engine/Settings.tests.ps1 b/Tests/Engine/Settings.tests.ps1 index cfd814274..a6fd41eb8 100644 --- a/Tests/Engine/Settings.tests.ps1 +++ b/Tests/Engine/Settings.tests.ps1 @@ -1,5 +1,4 @@ -$directory = Split-Path $MyInvocation.MyCommand.Path -$settingsTestDirectory = [System.IO.Path]::Combine($directory, "SettingsTest") +$settingsTestDirectory = [System.IO.Path]::Combine($PSScriptRoot, "SettingsTest") $project1Root = [System.IO.Path]::Combine($settingsTestDirectory, "Project1") $project2Root = [System.IO.Path]::Combine($settingsTestDirectory, "Project2") $settingsTypeName = 'Microsoft.Windows.PowerShell.ScriptAnalyzer.Settings' diff --git a/Tests/Rules/AlignAssignmentStatement.tests.ps1 b/Tests/Rules/AlignAssignmentStatement.tests.ps1 index 72074f91c..1f3dbad0f 100644 --- a/Tests/Rules/AlignAssignmentStatement.tests.ps1 +++ b/Tests/Rules/AlignAssignmentStatement.tests.ps1 @@ -1,5 +1,4 @@ -$directory = Split-Path -Parent $MyInvocation.MyCommand.Path -$testRootDirectory = Split-Path -Parent $directory +$testRootDirectory = Split-Path -Parent $PSScriptRoot Import-Module (Join-Path $testRootDirectory "PSScriptAnalyzerTestHelper.psm1") diff --git a/Tests/Rules/AvoidConvertToSecureStringWithPlainText.tests.ps1 b/Tests/Rules/AvoidConvertToSecureStringWithPlainText.tests.ps1 index c2a017771..0e7f760cb 100644 --- a/Tests/Rules/AvoidConvertToSecureStringWithPlainText.tests.ps1 +++ b/Tests/Rules/AvoidConvertToSecureStringWithPlainText.tests.ps1 @@ -1,9 +1,8 @@ Set-Alias ctss ConvertTo-SecureString $violationMessage = "File 'AvoidConvertToSecureStringWithPlainText.ps1' uses ConvertTo-SecureString with plaintext. This will expose secure information. Encrypted standard strings should be used instead." $violationName = "PSAvoidUsingConvertToSecureStringWithPlainText" -$directory = Split-Path -Parent $MyInvocation.MyCommand.Path -$violations = Invoke-ScriptAnalyzer $directory\AvoidConvertToSecureStringWithPlainText.ps1 | Where-Object {$_.RuleName -eq $violationName} -$noViolations = Invoke-ScriptAnalyzer $directory\AvoidConvertToSecureStringWithPlainTextNoViolations.ps1 | Where-Object {$_.RuleName -eq $violationName} +$violations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidConvertToSecureStringWithPlainText.ps1 | Where-Object {$_.RuleName -eq $violationName} +$noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidConvertToSecureStringWithPlainTextNoViolations.ps1 | Where-Object {$_.RuleName -eq $violationName} Describe "AvoidConvertToSecureStringWithPlainText" { Context "When there are violations" { diff --git a/Tests/Rules/AvoidDefaultTrueValueSwitchParameter.tests.ps1 b/Tests/Rules/AvoidDefaultTrueValueSwitchParameter.tests.ps1 index 1950bc2fc..6714ace07 100644 --- a/Tests/Rules/AvoidDefaultTrueValueSwitchParameter.tests.ps1 +++ b/Tests/Rules/AvoidDefaultTrueValueSwitchParameter.tests.ps1 @@ -1,8 +1,7 @@ $violationMessage = "File 'AvoidDefaultTrueValueSwitchParameter.ps1' has a switch parameter default to true." $violationName = "PSAvoidDefaultValueSwitchParameter" -$directory = Split-Path -Parent $MyInvocation.MyCommand.Path -$violations = Invoke-ScriptAnalyzer $directory\AvoidDefaultTrueValueSwitchParameter.ps1 | Where-Object {$_.RuleName -eq $violationName} -$noViolations = Invoke-ScriptAnalyzer $directory\AvoidDefaultTrueValueSwitchParameterNoViolations.ps1 | Where-Object {$_.RuleName -eq $violationName} +$violations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidDefaultTrueValueSwitchParameter.ps1 | Where-Object {$_.RuleName -eq $violationName} +$noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidDefaultTrueValueSwitchParameterNoViolations.ps1 | Where-Object {$_.RuleName -eq $violationName} Describe "AvoidDefaultTrueValueSwitchParameter" { Context "When there are violations" { diff --git a/Tests/Rules/AvoidEmptyCatchBlock.tests.ps1 b/Tests/Rules/AvoidEmptyCatchBlock.tests.ps1 index 25215cbef..cdd720e77 100644 --- a/Tests/Rules/AvoidEmptyCatchBlock.tests.ps1 +++ b/Tests/Rules/AvoidEmptyCatchBlock.tests.ps1 @@ -1,8 +1,7 @@ $violationMessage = "Empty catch block is used. Please use Write-Error or throw statements in catch blocks." -$violationName = "PSAvoidUsingEmptyCatchBlock" -$directory = Split-Path -Parent $MyInvocation.MyCommand.Path -$violations = Invoke-ScriptAnalyzer $directory\AvoidEmptyCatchBlock.ps1 | Where-Object {$_.RuleName -eq $violationName} -$noViolations = Invoke-ScriptAnalyzer $directory\AvoidEmptyCatchBlockNoViolations.ps1 | Where-Object {$_.RuleName -eq $violationName} +$violationName = "PSAvoidUsingE +$violations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidEmptyCatchBlock.ps1 | Where-Object {$_.RuleName -eq $violationName} +$noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidEmptyCatchBlockNoViolations.ps1 | Where-Object {$_.RuleName -eq $violationName} Describe "UseDeclaredVarsMoreThanAssignments" { Context "When there are violations" { diff --git a/Tests/Rules/AvoidGlobalAliases.tests.ps1 b/Tests/Rules/AvoidGlobalAliases.tests.ps1 index 8d069c9f8..1b8716236 100644 --- a/Tests/Rules/AvoidGlobalAliases.tests.ps1 +++ b/Tests/Rules/AvoidGlobalAliases.tests.ps1 @@ -1,11 +1,10 @@ -$directory = Split-Path -Parent $MyInvocation.MyCommand.Path -$testRootDirectory = Split-Path -Parent $directory +$testRootDirectory = Split-Path -Parent $PSScriptRoot Import-Module (Join-Path $testRootDirectory 'PSScriptAnalyzerTestHelper.psm1') $AvoidGlobalAliasesError = "Avoid creating aliases with a Global scope." $violationName = "PSAvoidGlobalAliases" -$violations = Invoke-ScriptAnalyzer $directory\AvoidGlobalAliases.psm1 | Where-Object {$_.RuleName -eq $violationName} -$noViolations = Invoke-ScriptAnalyzer $directory\AvoidGlobalAliasesNoViolations.ps1 | Where-Object {$_.RuleName -eq $violationName} +$violations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidGlobalAliases.psm1 | Where-Object {$_.RuleName -eq $violationName} +$noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidGlobalAliasesNoViolations.ps1 | Where-Object {$_.RuleName -eq $violationName} $IsV3OrV4 = (Test-PSVersionV3) -or (Test-PSVersionV4) Describe "$violationName " { diff --git a/Tests/Rules/AvoidGlobalFunctions.tests.ps1 b/Tests/Rules/AvoidGlobalFunctions.tests.ps1 index b1a55847f..b420f5b83 100644 --- a/Tests/Rules/AvoidGlobalFunctions.tests.ps1 +++ b/Tests/Rules/AvoidGlobalFunctions.tests.ps1 @@ -1,9 +1,8 @@ $functionErroMessage = "Avoid creating functions with a Global scope." $violationName = "PSAvoidGlobalFunctions" -$directory = Split-Path -Parent $MyInvocation.MyCommand.Path -$violations = Invoke-ScriptAnalyzer $directory\AvoidGlobalFunctions.psm1 | Where-Object {$_.RuleName -eq $violationName} -$noViolations = Invoke-ScriptAnalyzer $directory\AvoidGlobalFunctionsNoViolations.ps1 | Where-Object {$_.RuleName -eq $violationName} +$violations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidGlobalFunctions.psm1 | Where-Object {$_.RuleName -eq $violationName} +$noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidGlobalFunctionsNoViolations.ps1 | Where-Object {$_.RuleName -eq $violationName} Describe "$violationName " { diff --git a/Tests/Rules/AvoidGlobalVars.tests.ps1 b/Tests/Rules/AvoidGlobalVars.tests.ps1 index 8a4611e52..2b3297bd0 100644 --- a/Tests/Rules/AvoidGlobalVars.tests.ps1 +++ b/Tests/Rules/AvoidGlobalVars.tests.ps1 @@ -2,12 +2,11 @@ $globalName = "PSAvoidGlobalVars" $nonInitializedMessage = "Variable 'globalVars' is not initialized. Non-global variables must be initialized. To fix a violation of this rule, please initialize non-global variables." -$directory = Split-Path -Parent $MyInvocation.MyCommand.Path -$violations = Invoke-ScriptAnalyzer $directory\AvoidGlobalOrUnitializedVars.ps1 +$violations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidGlobalOrUnitializedVars.ps1 $globalViolations = $violations | Where-Object {$_.RuleName -eq $globalName} -$noViolations = Invoke-ScriptAnalyzer $directory\AvoidGlobalOrUnitializedVarsNoViolations.ps1 +$noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidGlobalOrUnitializedVarsNoViolations.ps1 $noGlobalViolations = $noViolations | Where-Object {$_.RuleName -eq $globalName} Describe "AvoidGlobalVars" { diff --git a/Tests/Rules/AvoidInvokingEmptyMembers.tests.ps1 b/Tests/Rules/AvoidInvokingEmptyMembers.tests.ps1 index d9bb76f56..5e8580068 100644 --- a/Tests/Rules/AvoidInvokingEmptyMembers.tests.ps1 +++ b/Tests/Rules/AvoidInvokingEmptyMembers.tests.ps1 @@ -1,8 +1,7 @@ $violationMessage = "() has non-constant members. Invoking non-constant members may cause bugs in the script." $violationName = "PSAvoidInvokingEmptyMembers" -$directory = Split-Path -Parent $MyInvocation.MyCommand.Path -$violations = Invoke-ScriptAnalyzer $directory\AvoidInvokingEmptyMembers.ps1 | Where-Object {$_.RuleName -eq $violationName} -$noViolations = Invoke-ScriptAnalyzer $directory\AvoidInvokingEmptyMembersNonViolations.ps1 | Where-Object {$_.RuleName -eq $violationName} +$violations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidInvokingEmptyMembers.ps1 | Where-Object {$_.RuleName -eq $violationName} +$noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidInvokingEmptyMembersNonViolations.ps1 | Where-Object {$_.RuleName -eq $violationName} Describe "AvoidInvokingEmptyMembers" { Context "When there are violations" { diff --git a/Tests/Rules/AvoidNullOrEmptyHelpMessageAttribute.tests.ps1 b/Tests/Rules/AvoidNullOrEmptyHelpMessageAttribute.tests.ps1 index 909e34289..a710297aa 100644 --- a/Tests/Rules/AvoidNullOrEmptyHelpMessageAttribute.tests.ps1 +++ b/Tests/Rules/AvoidNullOrEmptyHelpMessageAttribute.tests.ps1 @@ -1,8 +1,7 @@ $violationName = "PSAvoidNullOrEmptyHelpMessageAttribute" $violationMessage = "HelpMessage parameter attribute should not be null or empty. To fix a violation of this rule, please set its value to a non-empty string." -$directory = Split-Path -Parent $MyInvocation.MyCommand.Path -$violations = Invoke-ScriptAnalyzer "$directory\AvoidNullOrEmptyHelpMessageAttribute.ps1" -IncludeRule PSAvoidNullOrEmptyHelpMessageAttribute -$noViolations = Invoke-ScriptAnalyzer "$directory\AvoidNullOrEmptyHelpMessageAttributeNoViolations.ps1" -IncludeRule PSAvoidNullOrEmptyHelpMessageAttribute +$violations = Invoke-ScriptAnalyzer "$PSScriptRoot\AvoidNullOrEmptyHelpMessageAttribute.ps1" -IncludeRule PSAvoidNullOrEmptyHelpMessageAttribute +$noViolations = Invoke-ScriptAnalyzer "$PSScriptRoot\AvoidNullOrEmptyHelpMessageAttributeNoViolations.ps1" -IncludeRule PSAvoidNullOrEmptyHelpMessageAttribute Describe "AvoidNullOrEmptyHelpMessageAttribute" { Context "When there are violations" { diff --git a/Tests/Rules/AvoidPositionalParameters.tests.ps1 b/Tests/Rules/AvoidPositionalParameters.tests.ps1 index ded53c954..03f9368fc 100644 --- a/Tests/Rules/AvoidPositionalParameters.tests.ps1 +++ b/Tests/Rules/AvoidPositionalParameters.tests.ps1 @@ -1,9 +1,8 @@ $violationMessage = "Cmdlet 'Get-Command' has positional parameter. Please use named parameters instead of positional parameters when calling a command." $violationName = "PSAvoidUsingPositionalParameters" -$directory = Split-Path -Parent $MyInvocation.MyCommand.Path -$violations = Invoke-ScriptAnalyzer $directory\AvoidPositionalParameters.ps1 | Where-Object {$_.RuleName -eq $violationName} -$noViolations = Invoke-ScriptAnalyzer $directory\AvoidPositionalParametersNoViolations.ps1 | Where-Object {$_.RuleName -eq $violationName} -$noViolationsDSC = Invoke-ScriptAnalyzer -ErrorAction SilentlyContinue $directory\serviceconfigdisabled.ps1 | Where-Object {$_.RuleName -eq $violationName} +$violations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidPositionalParameters.ps1 | Where-Object {$_.RuleName -eq $violationName} +$noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidPositionalParametersNoViolations.ps1 | Where-Object {$_.RuleName -eq $violationName} +$noViolationsDSC = Invoke-ScriptAnalyzer -ErrorAction SilentlyContinue $PSScriptRoot\serviceconfigdisabled.ps1 | Where-Object {$_.RuleName -eq $violationName} Describe "AvoidPositionalParameters" { Context "When there are violations" { diff --git a/Tests/Rules/AvoidReservedParams.tests.ps1 b/Tests/Rules/AvoidReservedParams.tests.ps1 index 358c0e9dd..52020df37 100644 --- a/Tests/Rules/AvoidReservedParams.tests.ps1 +++ b/Tests/Rules/AvoidReservedParams.tests.ps1 @@ -1,8 +1,7 @@ $violationMessage = [regex]::Escape("Verb-Files' defines the reserved common parameter 'Verbose'.") $violationName = "PSReservedParams" -$directory = Split-Path -Parent $MyInvocation.MyCommand.Path -$violations = Invoke-ScriptAnalyzer $directory\BadCmdlet.ps1 | Where-Object {$_.RuleName -eq $violationName} -$noViolations = Invoke-ScriptAnalyzer $directory\GoodCmdlet.ps1 | Where-Object {$_.RuleName -eq $violationName} +$violations = Invoke-ScriptAnalyzer $PSScriptRoot\BadCmdlet.ps1 | Where-Object {$_.RuleName -eq $violationName} +$noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\GoodCmdlet.ps1 | Where-Object {$_.RuleName -eq $violationName} Describe "AvoidReservedParams" { Context "When there are violations" { diff --git a/Tests/Rules/AvoidShouldContinueWithoutForce.tests.ps1 b/Tests/Rules/AvoidShouldContinueWithoutForce.tests.ps1 index 0e8e2dfec..7ebff4de5 100644 --- a/Tests/Rules/AvoidShouldContinueWithoutForce.tests.ps1 +++ b/Tests/Rules/AvoidShouldContinueWithoutForce.tests.ps1 @@ -1,8 +1,7 @@ $violationMessage = "Function 'Verb-Noun2' in file 'AvoidShouldContinueWithoutForce.ps1' uses ShouldContinue but does not have a boolean force parameter. The force parameter will allow users of the script to bypass ShouldContinue prompt" $violationName = "PSAvoidShouldContinueWithoutForce" -$directory = Split-Path -Parent $MyInvocation.MyCommand.Path -$violations = Invoke-ScriptAnalyzer $directory\AvoidShouldContinueWithoutForce.ps1 | Where-Object {$_.RuleName -eq $violationName} -$noViolations = Invoke-ScriptAnalyzer $directory\GoodCmdlet.ps1 | Where-Object {$_.RuleName -eq $violationName} +$violations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidShouldContinueWithoutForce.ps1 | Where-Object {$_.RuleName -eq $violationName} +$noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\GoodCmdlet.ps1 | Where-Object {$_.RuleName -eq $violationName} Describe "AvoidShouldContinueWithoutForce" { Context "When there are violations" { diff --git a/Tests/Rules/AvoidTrailingWhitespace.tests.ps1 b/Tests/Rules/AvoidTrailingWhitespace.tests.ps1 index da722a529..b51398984 100644 --- a/Tests/Rules/AvoidTrailingWhitespace.tests.ps1 +++ b/Tests/Rules/AvoidTrailingWhitespace.tests.ps1 @@ -1,6 +1,4 @@ -$directory = Split-Path -Parent $MyInvocation.MyCommand.Path -$testRootDirectory = Split-Path -Parent $directory - +$testRootDirectory = Split-Path -Parent $PSScriptRoot Import-Module (Join-Path $testRootDirectory "PSScriptAnalyzerTestHelper.psm1") $ruleName = "PSAvoidTrailingWhitespace" diff --git a/Tests/Rules/AvoidUnloadableModuleOrMissingRequiredFieldInManifest.tests.ps1 b/Tests/Rules/AvoidUnloadableModuleOrMissingRequiredFieldInManifest.tests.ps1 index 2198fa178..017382aeb 100644 --- a/Tests/Rules/AvoidUnloadableModuleOrMissingRequiredFieldInManifest.tests.ps1 +++ b/Tests/Rules/AvoidUnloadableModuleOrMissingRequiredFieldInManifest.tests.ps1 @@ -1,17 +1,16 @@ -$directory = Split-Path -Parent $MyInvocation.MyCommand.Path -$testRootDirectory = Split-Path -Parent $directory +$testRootDirectory = Split-Path -Parent $PSScriptRoot Import-Module (Join-Path $testRootDirectory 'PSScriptAnalyzerTestHelper.psm1') $missingMessage = "The member 'ModuleVersion' is not present in the module manifest." $missingMemberRuleName = "PSMissingModuleManifestField" -$violationFilepath = Join-Path $directory "TestBadModule\TestBadModule.psd1" +$violationFilepath = Join-Path $PSScriptRoot "TestBadModule\TestBadModule.psd1" $violations = Invoke-ScriptAnalyzer $violationFilepath | Where-Object {$_.RuleName -eq $missingMemberRuleName} -$noViolations = Invoke-ScriptAnalyzer $directory\TestGoodModule\TestGoodModule.psd1 | Where-Object {$_.RuleName -eq $missingMemberRuleName} -$noHashtableFilepath = Join-Path $directory "TestBadModule\NoHashtable.psd1" +$noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\TestGoodModule\TestGoodModule.psd1 | Where-Object {$_.RuleName -eq $missingMemberRuleName} +$noHashtableFilepath = Join-Path $PSScriptRoot "TestBadModule\NoHashtable.psd1" Describe "MissingRequiredFieldModuleManifest" { BeforeAll { - Import-Module (Join-Path $directory "PSScriptAnalyzerTestHelper.psm1") -Force + Import-Module (Join-Path $PSScriptRoot "PSScriptAnalyzerTestHelper.psm1") -Force } AfterAll{ @@ -55,32 +54,32 @@ Describe "MissingRequiredFieldModuleManifest" { Context "Validate the contents of a .psd1 file" { It "detects a valid module manifest file" { - $filepath = Join-Path $directory "TestManifest/ManifestGood.psd1" + $filepath = Join-Path $PSScriptRoot "TestManifest/ManifestGood.psd1" [Microsoft.Windows.PowerShell.ScriptAnalyzer.Helper]::IsModuleManifest($filepath, [version]"5.0.0") | Should -BeTrue } It "detects a .psd1 file which is not module manifest" { - $filepath = Join-Path $directory "TestManifest/PowerShellDataFile.psd1" + $filepath = Join-Path $PSScriptRoot "TestManifest/PowerShellDataFile.psd1" [Microsoft.Windows.PowerShell.ScriptAnalyzer.Helper]::IsModuleManifest($filepath, [version]"5.0.0") | Should -BeFalse } It "detects valid module manifest file for PSv5" { - $filepath = Join-Path $directory "TestManifest/ManifestGoodPsv5.psd1" + $filepath = Join-Path $PSScriptRoot "TestManifest/ManifestGoodPsv5.psd1" [Microsoft.Windows.PowerShell.ScriptAnalyzer.Helper]::IsModuleManifest($filepath, [version]"5.0.0") | Should -BeTrue } It "does not validate PSv5 module manifest file for PSv3 check" { - $filepath = Join-Path $directory "TestManifest/ManifestGoodPsv5.psd1" + $filepath = Join-Path $PSScriptRoot "TestManifest/ManifestGoodPsv5.psd1" [Microsoft.Windows.PowerShell.ScriptAnalyzer.Helper]::IsModuleManifest($filepath, [version]"3.0.0") | Should -BeFalse } It "detects valid module manifest file for PSv4" { - $filepath = Join-Path $directory "TestManifest/ManifestGoodPsv4.psd1" + $filepath = Join-Path $PSScriptRoot "TestManifest/ManifestGoodPsv4.psd1" [Microsoft.Windows.PowerShell.ScriptAnalyzer.Helper]::IsModuleManifest($filepath, [version]"4.0.0") | Should -BeTrue } It "detects valid module manifest file for PSv3" { - $filepath = Join-Path $directory "TestManifest/ManifestGoodPsv3.psd1" + $filepath = Join-Path $PSScriptRoot "TestManifest/ManifestGoodPsv3.psd1" [Microsoft.Windows.PowerShell.ScriptAnalyzer.Helper]::IsModuleManifest($filepath, [version]"3.0.0") | Should -BeTrue } } @@ -88,7 +87,7 @@ Describe "MissingRequiredFieldModuleManifest" { Context "When given a non module manifest file" { It "does not flag a PowerShell data file" { Invoke-ScriptAnalyzer ` - -Path "$directory/TestManifest/PowerShellDataFile.psd1" ` + -Path "$PSScriptRoot/TestManifest/PowerShellDataFile.psd1" ` -IncludeRule "PSMissingModuleManifestField" ` -OutVariable ruleViolation $ruleViolation.Count | Should -Be 0 diff --git a/Tests/Rules/AvoidUserNameAndPasswordParams.tests.ps1 b/Tests/Rules/AvoidUserNameAndPasswordParams.tests.ps1 index b499205f9..7b3c966e8 100644 --- a/Tests/Rules/AvoidUserNameAndPasswordParams.tests.ps1 +++ b/Tests/Rules/AvoidUserNameAndPasswordParams.tests.ps1 @@ -1,9 +1,8 @@  $violationMessage = "Function 'TestFunction1' has both Username and Password parameters. Either set the type of the Password parameter to SecureString or replace the Username and Password parameters with a Credential parameter of type PSCredential. If using a Credential parameter in PowerShell 4.0 or earlier, please define a credential transformation attribute after the PSCredential type attribute." $violationName = "PSAvoidUsingUserNameAndPasswordParams" -$directory = Split-Path -Parent $MyInvocation.MyCommand.Path -$violations = Invoke-ScriptAnalyzer $directory\AvoidUserNameAndPasswordParams.ps1 | Where-Object {$_.RuleName -eq $violationName} -$noViolations = Invoke-ScriptAnalyzer $directory\AvoidUserNameAndPasswordParamsNoViolations.ps1 | Where-Object {$_.RuleName -eq $violationName} +$violations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidUserNameAndPasswordParams.ps1 | Where-Object {$_.RuleName -eq $violationName} +$noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidUserNameAndPasswordParamsNoViolations.ps1 | Where-Object {$_.RuleName -eq $violationName} Describe "AvoidUserNameAndPasswordParams" { Context "When there are violations" { diff --git a/Tests/Rules/AvoidUsingAlias.tests.ps1 b/Tests/Rules/AvoidUsingAlias.tests.ps1 index 478646c27..cd0ff4a4d 100644 --- a/Tests/Rules/AvoidUsingAlias.tests.ps1 +++ b/Tests/Rules/AvoidUsingAlias.tests.ps1 @@ -1,10 +1,9 @@ $violationMessage = "'cls' is an alias of 'Clear-Host'. Alias can introduce possible problems and make scripts hard to maintain. Please consider changing alias to its full content." $violationName = "PSAvoidUsingCmdletAliases" -$directory = Split-Path -Parent $MyInvocation.MyCommand.Path -$testRootDirectory = Split-Path -Parent $directory -$violationFilepath = Join-Path $directory 'AvoidUsingAlias.ps1' +$testRootDirectory = Split-Path -Parent $PSScriptRoot +$violationFilepath = Join-Path $PSScriptRoot 'AvoidUsingAlias.ps1' $violations = Invoke-ScriptAnalyzer $violationFilepath | Where-Object {$_.RuleName -eq $violationName} -$noViolations = Invoke-ScriptAnalyzer $directory\AvoidUsingAliasNoViolations.ps1 | Where-Object {$_.RuleName -eq $violationName} +$noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidUsingAliasNoViolations.ps1 | Where-Object {$_.RuleName -eq $violationName} Import-Module (Join-Path $testRootDirectory "PSScriptAnalyzerTestHelper.psm1") @@ -90,7 +89,7 @@ Configuration MyDscConfiguration { It "honors the whitelist provided through settings file" { # even though join-path returns string, if we do not use tostring, then invoke-scriptanalyzer cannot cast it to string type - $settingsFilePath = (Join-Path $directory (Join-Path 'TestSettings' 'AvoidAliasSettings.psd1')).ToString() + $settingsFilePath = (Join-Path $PSScriptRoot (Join-Path 'TestSettings' 'AvoidAliasSettings.psd1')).ToString() $violations = Invoke-ScriptAnalyzer -ScriptDefinition $whiteListTestScriptDef -Settings $settingsFilePath -IncludeRule $violationName $violations.Count | Should -Be 1 } diff --git a/Tests/Rules/AvoidUsingComputerNameHardcoded.tests.ps1 b/Tests/Rules/AvoidUsingComputerNameHardcoded.tests.ps1 index 1c87a8068..3c0fc58a7 100644 --- a/Tests/Rules/AvoidUsingComputerNameHardcoded.tests.ps1 +++ b/Tests/Rules/AvoidUsingComputerNameHardcoded.tests.ps1 @@ -1,8 +1,7 @@ $violationMessage = [regex]::Escape("The ComputerName parameter of cmdlet 'Invoke-Command' is hardcoded. This will expose sensitive information about the system if the script is shared.") $violationName = "PSAvoidUsingComputerNameHardcoded" -$directory = Split-Path -Parent $MyInvocation.MyCommand.Path -$violations = Invoke-ScriptAnalyzer $directory\AvoidUsingComputerNameHardcoded.ps1 | Where-Object {$_.RuleName -eq $violationName} -$noViolations = Invoke-ScriptAnalyzer $directory\AvoidUsingComputerNameHardcodedNoViolations.ps1 | Where-Object {$_.RuleName -eq $violationName} +$violations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidUsingComputerNameHardcoded.ps1 | Where-Object {$_.RuleName -eq $violationName} +$noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidUsingComputerNameHardcodedNoViolations.ps1 | Where-Object {$_.RuleName -eq $violationName} Describe "AvoidUsingComputerNameHardcoded" { Context "When there are violations" { diff --git a/Tests/Rules/AvoidUsingDeprecatedManifestFields.tests.ps1 b/Tests/Rules/AvoidUsingDeprecatedManifestFields.tests.ps1 index 8ecae2af1..9a04b96d5 100644 --- a/Tests/Rules/AvoidUsingDeprecatedManifestFields.tests.ps1 +++ b/Tests/Rules/AvoidUsingDeprecatedManifestFields.tests.ps1 @@ -1,8 +1,7 @@ $violationName = "PSAvoidUsingDeprecatedManifestFields" -$directory = Split-Path -Parent $MyInvocation.MyCommand.Path -$violations = Invoke-ScriptAnalyzer "$directory\TestBadModule\TestDeprecatedManifestFields.psd1" | Where-Object {$_.RuleName -eq $violationName} -$noViolations = Invoke-ScriptAnalyzer "$directory\TestGoodModule\TestGoodModule.psd1" | Where-Object {$_.RuleName -eq $violationName} -$noViolations2 = Invoke-ScriptAnalyzer "$directory\TestGoodModule\TestDeprecatedManifestFieldsWithVersion2.psd1" | Where-Object {$_.RuleName -eq $violationName} +$violations = Invoke-ScriptAnalyzer "$PSScriptRoot\TestBadModule\TestDeprecatedManifestFields.psd1" | Where-Object {$_.RuleName -eq $violationName} +$noViolations = Invoke-ScriptAnalyzer "$PSScriptRoot\TestGoodModule\TestGoodModule.psd1" | Where-Object {$_.RuleName -eq $violationName} +$noViolations2 = Invoke-ScriptAnalyzer "$PSScriptRoot\TestGoodModule\TestDeprecatedManifestFieldsWithVersion2.psd1" | Where-Object {$_.RuleName -eq $violationName} Describe "AvoidUsingDeprecatedManifestFields" { Context "When there are violations" { @@ -24,7 +23,7 @@ Describe "AvoidUsingDeprecatedManifestFields" { Context "When given a non module manifest file" { It "does not flag a PowerShell data file" { Invoke-ScriptAnalyzer ` - -Path "$directory/TestManifest/PowerShellDataFile.psd1" ` + -Path "$PSScriptRoot/TestManifest/PowerShellDataFile.psd1" ` -IncludeRule "PSAvoidUsingDeprecatedManifestFields" ` -OutVariable ruleViolation $ruleViolation.Count | Should -Be 0 diff --git a/Tests/Rules/AvoidUsingInvokeExpression.tests.ps1 b/Tests/Rules/AvoidUsingInvokeExpression.tests.ps1 index dc7e38644..322a52b0a 100644 --- a/Tests/Rules/AvoidUsingInvokeExpression.tests.ps1 +++ b/Tests/Rules/AvoidUsingInvokeExpression.tests.ps1 @@ -1,8 +1,7 @@ $violationMessage = "Invoke-Expression is used. Please remove Invoke-Expression from script and find other options instead." $violationName = "PSAvoidUsingInvokeExpression" -$directory = Split-Path -Parent $MyInvocation.MyCommand.Path -$violations = Invoke-ScriptAnalyzer $directory\AvoidUsingInvokeExpression.ps1 | Where-Object {$_.RuleName -eq $violationName} -$noViolations = Invoke-ScriptAnalyzer $directory\AvoidConvertToSecureStringWithPlainTextNoViolations.ps1 | Where-Object {$_.RuleName -eq $violationName} +$violations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidUsingInvokeExpression.ps1 | Where-Object {$_.RuleName -eq $violationName} +$noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidConvertToSecureStringWithPlainTextNoViolations.ps1 | Where-Object {$_.RuleName -eq $violationName} Describe "AvoidUsingInvokeExpression" { Context "When there are violations" { diff --git a/Tests/Rules/AvoidUsingPlainTextForPassword.tests.ps1 b/Tests/Rules/AvoidUsingPlainTextForPassword.tests.ps1 index 44a83d1a0..2824a8088 100644 --- a/Tests/Rules/AvoidUsingPlainTextForPassword.tests.ps1 +++ b/Tests/Rules/AvoidUsingPlainTextForPassword.tests.ps1 @@ -1,10 +1,9 @@ $violationMessage = [regex]::Escape("Parameter '`$password' should use SecureString, otherwise this will expose sensitive information. See ConvertTo-SecureString for more information.") $violationName = "PSAvoidUsingPlainTextForPassword" -$directory = Split-Path -Parent $MyInvocation.MyCommand.Path -$violationFilepath = Join-Path $directory 'AvoidUsingPlainTextForPassword.ps1' +$violationFilepath = Join-Path $PSScriptRoot 'AvoidUsingPlainTextForPassword.ps1' $violations = Invoke-ScriptAnalyzer $violationFilepath | Where-Object {$_.RuleName -eq $violationName} -$noViolations = Invoke-ScriptAnalyzer $directory\AvoidUsingPlainTextForPasswordNoViolations.ps1 | Where-Object {$_.RuleName -eq $violationName} -Import-Module (Join-Path $directory "PSScriptAnalyzerTestHelper.psm1") +$noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidUsingPlainTextForPasswordNoViolations.ps1 | Where-Object {$_.RuleName -eq $violationName} +Import-Module (Join-Path $PSScriptRoot "PSScriptAnalyzerTestHelper.psm1") Describe "AvoidUsingPlainTextForPassword" { Context "When there are violations" { diff --git a/Tests/Rules/AvoidUsingReservedCharNames.tests.ps1 b/Tests/Rules/AvoidUsingReservedCharNames.tests.ps1 index 1b6a32b90..4321c97f9 100644 --- a/Tests/Rules/AvoidUsingReservedCharNames.tests.ps1 +++ b/Tests/Rules/AvoidUsingReservedCharNames.tests.ps1 @@ -1,8 +1,7 @@ $reservedCharMessage = "The cmdlet 'Use-#Reserved' uses a reserved char in its name." $reservedCharName = "PSReservedCmdletChar" -$directory = Split-Path -Parent $MyInvocation.MyCommand.Path -$violations = Invoke-ScriptAnalyzer $directory\AvoidUsingReservedCharNames.ps1 | Where-Object {$_.RuleName -eq $reservedCharName} -$noViolations = Invoke-ScriptAnalyzer $directory\GoodCmdlet.ps1 | Where-Object {$_.RuleName -eq $reservedCharName} +$violations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidUsingReservedCharNames.ps1 | Where-Object {$_.RuleName -eq $reservedCharName} +$noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\GoodCmdlet.ps1 | Where-Object {$_.RuleName -eq $reservedCharName} Describe "Avoid Using Reserved Char" { Context "When there are violations" { diff --git a/Tests/Rules/AvoidUsingWMICmdlet.tests.ps1 b/Tests/Rules/AvoidUsingWMICmdlet.tests.ps1 index b367f11fe..688707121 100644 --- a/Tests/Rules/AvoidUsingWMICmdlet.tests.ps1 +++ b/Tests/Rules/AvoidUsingWMICmdlet.tests.ps1 @@ -1,8 +1,7 @@ $WMIRuleName = "PSAvoidUsingWMICmdlet" $violationMessage = "File 'AvoidUsingWMICmdlet.ps1' uses WMI cmdlet. For PowerShell 3.0 and above, use CIM cmdlet which perform the same tasks as the WMI cmdlets. The CIM cmdlets comply with WS-Management (WSMan) standards and with the Common Information Model (CIM) standard, which enables the cmdlets to use the same techniques to manage Windows computers and those running other operating systems." -$directory = Split-Path -Parent $MyInvocation.MyCommand.Path -$violations = Invoke-ScriptAnalyzer $directory\AvoidUsingWMICmdlet.ps1 -IncludeRule $WMIRuleName -$noViolations = Invoke-ScriptAnalyzer $directory\AvoidUsingWMICmdletNoViolations.ps1 -IncludeRule $WMIRuleName +$violations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidUsingWMICmdlet.ps1 -IncludeRule $WMIRuleName +$noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidUsingWMICmdletNoViolations.ps1 -IncludeRule $WMIRuleName Describe "AvoidUsingWMICmdlet" { Context "Script contains references to WMI cmdlets - Violation" { @@ -11,7 +10,7 @@ Describe "AvoidUsingWMICmdlet" { } It "has the correct description message for WMI rule violation" { - $violations[0].Message | Should -Be $violationMessage + $violations[0].Message | Should -Be $violationMessage } } diff --git a/Tests/Rules/AvoidUsingWriteHost.tests.ps1 b/Tests/Rules/AvoidUsingWriteHost.tests.ps1 index bfb8977d6..947328cdd 100644 --- a/Tests/Rules/AvoidUsingWriteHost.tests.ps1 +++ b/Tests/Rules/AvoidUsingWriteHost.tests.ps1 @@ -1,9 +1,8 @@ Set-Alias ctss ConvertTo-SecureString $writeHostMessage = [Regex]::Escape("File 'AvoidUsingWriteHost.ps1' uses Write-Host. Avoid using Write-Host because it might not work in all hosts, does not work when there is no host, and (prior to PS 5.0) cannot be suppressed, captured, or redirected. Instead, use Write-Output, Write-Verbose, or Write-Information.") $writeHostName = "PSAvoidUsingWriteHost" -$directory = Split-Path -Parent $MyInvocation.MyCommand.Path -$violations = Invoke-ScriptAnalyzer $directory\AvoidUsingWriteHost.ps1 | Where-Object {$_.RuleName -eq $writeHostName} -$noViolations = Invoke-ScriptAnalyzer $directory\AvoidUsingWriteHostNoViolations.ps1 | Where-Object {$_.RuleName -eq $clearHostName} +$violations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidUsingWriteHost.ps1 | Where-Object {$_.RuleName -eq $writeHostName} +$noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidUsingWriteHostNoViolations.ps1 | Where-Object {$_.RuleName -eq $clearHostName} Describe "AvoidUsingWriteHost" { Context "When there are violations" { diff --git a/Tests/Rules/DscExamplesPresent.tests.ps1 b/Tests/Rules/DscExamplesPresent.tests.ps1 index 7436d2b77..c8f52dd85 100644 --- a/Tests/Rules/DscExamplesPresent.tests.ps1 +++ b/Tests/Rules/DscExamplesPresent.tests.ps1 @@ -1,12 +1,11 @@ -$currentPath = Split-Path -Parent $MyInvocation.MyCommand.Path $ruleName = "PSDSCDscExamplesPresent" if ($PSVersionTable.PSVersion -ge [Version]'5.0.0') { Describe "DscExamplesPresent rule in class based resource" { - $examplesPath = "$currentPath\DSCResourceModule\DSCResources\MyDscResource\Examples" - $classResourcePath = "$currentPath\DSCResourceModule\DSCResources\MyDscResource\MyDscResource.psm1" + $examplesPath = "$PSScriptRoot\DSCResourceModule\DSCResources\MyDscResource\Examples" + $classResourcePath = "$PSScriptRoot\DSCResourceModule\DSCResources\MyDscResource\MyDscResource.psm1" Context "When examples absent" { @@ -39,8 +38,8 @@ if ($PSVersionTable.PSVersion -ge [Version]'5.0.0') { Describe "DscExamplesPresent rule in regular (non-class) based resource" { - $examplesPath = "$currentPath\DSCResourceModule\Examples" - $resourcePath = "$currentPath\DSCResourceModule\DSCResources\MSFT_WaitForAll\MSFT_WaitForAll.psm1" + $examplesPath = "$PSScriptRoot\DSCResourceModule\Examples" + $resourcePath = "$PSScriptRoot\DSCResourceModule\DSCResources\MSFT_WaitForAll\MSFT_WaitForAll.psm1" Context "When examples absent" { diff --git a/Tests/Rules/DscTestsPresent.tests.ps1 b/Tests/Rules/DscTestsPresent.tests.ps1 index d90a70f3f..d9af9da94 100644 --- a/Tests/Rules/DscTestsPresent.tests.ps1 +++ b/Tests/Rules/DscTestsPresent.tests.ps1 @@ -1,12 +1,11 @@ -$currentPath = Split-Path -Parent $MyInvocation.MyCommand.Path $ruleName = "PSDSCDscTestsPresent" if ($PSVersionTable.PSVersion -ge [Version]'5.0.0') { Describe "DscTestsPresent rule in class based resource" { - $testsPath = "$currentPath\DSCResourceModule\DSCResources\MyDscResource\Tests" - $classResourcePath = "$currentPath\DSCResourceModule\DSCResources\MyDscResource\MyDscResource.psm1" + $testsPath = "$PSScriptRoot\DSCResourceModule\DSCResources\MyDscResource\Tests" + $classResourcePath = "$PSScriptRoot\DSCResourceModule\DSCResources\MyDscResource\MyDscResource.psm1" Context "When tests absent" { @@ -39,8 +38,8 @@ if ($PSVersionTable.PSVersion -ge [Version]'5.0.0') { Describe "DscTestsPresent rule in regular (non-class) based resource" { - $testsPath = "$currentPath\DSCResourceModule\Tests" - $resourcePath = "$currentPath\DSCResourceModule\DSCResources\MSFT_WaitForAll\MSFT_WaitForAll.psm1" + $testsPath = "$PSScriptRoot\DSCResourceModule\Tests" + $resourcePath = "$PSScriptRoot\DSCResourceModule\DSCResources\MSFT_WaitForAll\MSFT_WaitForAll.psm1" Context "When tests absent" { diff --git a/Tests/Rules/MisleadingBacktick.tests.ps1 b/Tests/Rules/MisleadingBacktick.tests.ps1 index e4cd97195..b640e8b04 100644 --- a/Tests/Rules/MisleadingBacktick.tests.ps1 +++ b/Tests/Rules/MisleadingBacktick.tests.ps1 @@ -1,16 +1,15 @@ $writeHostName = "PSMisleadingBacktick" -$directory = Split-Path -Parent $MyInvocation.MyCommand.Path -$violationFilepath = Join-Path $directory 'MisleadingBacktick.ps1' +$violationFilepath = Join-Path $PSScriptRoot 'MisleadingBacktick.ps1' $violations = Invoke-ScriptAnalyzer $violationFilepath | Where-Object {$_.RuleName -eq $writeHostName} -$noViolations = Invoke-ScriptAnalyzer $directory\NoMisleadingBacktick.ps1 | Where-Object {$_.RuleName -eq $clearHostName} -Import-Module (Join-Path $directory "PSScriptAnalyzerTestHelper.psm1") +$noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\NoMisleadingBacktick.ps1 | Where-Object {$_.RuleName -eq $clearHostName} +Import-Module (Join-Path $PSScriptRoot "PSScriptAnalyzerTestHelper.psm1") Describe "Avoid Misleading Backticks" { Context "When there are violations" { It "has 5 misleading backtick violations" { $violations.Count | Should -Be 5 } - + It "suggests correction" { Test-CorrectionExtent $violationFilepath $violations[0] 1 ' ' '' Test-CorrectionExtent $violationFilepath $violations[1] 1 ' ' '' diff --git a/Tests/Rules/PSCredentialType.tests.ps1 b/Tests/Rules/PSCredentialType.tests.ps1 index 344bfa5fb..fb339d29d 100644 --- a/Tests/Rules/PSCredentialType.tests.ps1 +++ b/Tests/Rules/PSCredentialType.tests.ps1 @@ -1,11 +1,10 @@ -$directory = Split-Path -Parent $MyInvocation.MyCommand.Path -$testRootDirectory = Split-Path -Parent $directory +$testRootDirectory = Split-Path -Parent $PSScriptRoot Import-Module (Join-Path $testRootDirectory 'PSScriptAnalyzerTestHelper.psm1') $violationMessage = "The Credential parameter in 'Credential' must be of type PSCredential. For PowerShell 4.0 and earlier, please define a credential transformation attribute, e.g. [System.Management.Automation.Credential()], after the PSCredential type attribute." $violationName = "PSUsePSCredentialType" -$violations = Invoke-ScriptAnalyzer $directory\PSCredentialType.ps1 | Where-Object {$_.RuleName -eq $violationName} -$noViolations = Invoke-ScriptAnalyzer $directory\PSCredentialTypeNoViolations.ps1 | Where-Object {$_.RuleName -eq $violationName} +$violations = Invoke-ScriptAnalyzer $PSScriptRoot\PSCredentialType.ps1 | Where-Object {$_.RuleName -eq $violationName} +$noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\PSCredentialTypeNoViolations.ps1 | Where-Object {$_.RuleName -eq $violationName} Describe "PSCredentialType" { Context "When there are violations" { diff --git a/Tests/Rules/PlaceCloseBrace.tests.ps1 b/Tests/Rules/PlaceCloseBrace.tests.ps1 index df1be8812..94c65473f 100644 --- a/Tests/Rules/PlaceCloseBrace.tests.ps1 +++ b/Tests/Rules/PlaceCloseBrace.tests.ps1 @@ -1,6 +1,4 @@ -$directory = Split-Path -Parent $MyInvocation.MyCommand.Path -$testRootDirectory = Split-Path -Parent $directory - +$testRootDirectory = Split-Path -Parent $PSScriptRoot Import-Module (Join-Path $testRootDirectory "PSScriptAnalyzerTestHelper.psm1") $ruleConfiguration = @{ diff --git a/Tests/Rules/PossibleIncorrectComparisonWithNull.tests.ps1 b/Tests/Rules/PossibleIncorrectComparisonWithNull.tests.ps1 index 5c9f45553..ff00080d8 100644 --- a/Tests/Rules/PossibleIncorrectComparisonWithNull.tests.ps1 +++ b/Tests/Rules/PossibleIncorrectComparisonWithNull.tests.ps1 @@ -1,8 +1,7 @@ $violationMessage = [regex]::Escape('$null should be on the left side of equality comparisons.') $violationName = "PSPossibleIncorrectComparisonWithNull" -$directory = Split-Path -Parent $MyInvocation.MyCommand.Path -$violations = Invoke-ScriptAnalyzer $directory\PossibleIncorrectComparisonWithNull.ps1 | Where-Object {$_.RuleName -eq $violationName} -$noViolations = Invoke-ScriptAnalyzer $directory\PossibleIncorrectComparisonWithNullNoViolations.ps1 | Where-Object {$_.RuleName -eq $violationName} +$violations = Invoke-ScriptAnalyzer $PSScriptRoot\PossibleIncorrectComparisonWithNull.ps1 | Where-Object {$_.RuleName -eq $violationName} +$noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\PossibleIncorrectComparisonWithNullNoViolations.ps1 | Where-Object {$_.RuleName -eq $violationName} Describe "PossibleIncorrectComparisonWithNull" { Context "When there are violations" { diff --git a/Tests/Rules/ProvideCommentHelp.tests.ps1 b/Tests/Rules/ProvideCommentHelp.tests.ps1 index 51dd2137f..6ab2504e9 100644 --- a/Tests/Rules/ProvideCommentHelp.tests.ps1 +++ b/Tests/Rules/ProvideCommentHelp.tests.ps1 @@ -1,6 +1,4 @@ -$directory = Split-Path -Parent $MyInvocation.MyCommand.Path -$testRootDirectory = Split-Path -Parent $directory - +$testRootDirectory = Split-Path -Parent $PSScriptRoot Import-Module (Join-Path $testRootDirectory "PSScriptAnalyzerTestHelper.psm1") $violationMessage = "The cmdlet 'Comment' does not have a help comment." @@ -18,13 +16,13 @@ $settings = @{ Rules = @{ PSProvideCommentHelp = $ruleSettings } } -$violations = Invoke-ScriptAnalyzer $directory\BadCmdlet.ps1 | Where-Object {$_.RuleName -eq $violationName} +$violations = Invoke-ScriptAnalyzer $PSScriptRoot\BadCmdlet.ps1 | Where-Object {$_.RuleName -eq $violationName} if ($PSVersionTable.PSVersion -ge [Version]'5.0.0') { - $dscViolations = Invoke-ScriptAnalyzer -ErrorAction SilentlyContinue $directory\DSCResourceModule\DSCResources\MyDscResource\MyDscResource.psm1 | Where-Object {$_.RuleName -eq $violationName} + $dscViolations = Invoke-ScriptAnalyzer -ErrorAction SilentlyContinue $PSScriptRoot\DSCResourceModule\DSCResources\MyDscResource\MyDscResource.psm1 | Where-Object {$_.RuleName -eq $violationName} } -$noViolations = Invoke-ScriptAnalyzer $directory\GoodCmdlet.ps1 | Where-Object {$_.RuleName -eq $violationName} +$noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\GoodCmdlet.ps1 | Where-Object {$_.RuleName -eq $violationName} function Test-Correction { param($scriptDef, $expectedCorrection, $settings) diff --git a/Tests/Rules/ReturnCorrectTypesForDSCFunctions.tests.ps1 b/Tests/Rules/ReturnCorrectTypesForDSCFunctions.tests.ps1 index 8d85f81b6..78b5f91e2 100644 --- a/Tests/Rules/ReturnCorrectTypesForDSCFunctions.tests.ps1 +++ b/Tests/Rules/ReturnCorrectTypesForDSCFunctions.tests.ps1 @@ -1,14 +1,13 @@ $violationMessageDSCResource = "Test-TargetResource function in DSC Resource should return object of type System.Boolean instead of System.Collections.Hashtable" $violationMessageDSCClass = "Get function in DSC Class FileResource should return object of type FileResource instead of type System.Collections.Hashtable" $violationName = "PSDSCReturnCorrectTypesForDSCFunctions" -$directory = Split-Path -Parent $MyInvocation.MyCommand.Path -$violations = Invoke-ScriptAnalyzer $directory\DSCResourceModule\DSCResources\MSFT_WaitForAll\MSFT_WaitForAll.psm1 | Where-Object {$_.RuleName -eq $violationName} -$noViolations = Invoke-ScriptAnalyzer $directory\DSCResourceModule\DSCResources\MSFT_WaitForAny\MSFT_WaitForAny.psm1 | Where-Object {$_.RuleName -eq $violationName} +$violations = Invoke-ScriptAnalyzer $PSScriptRoot\DSCResourceModule\DSCResources\MSFT_WaitForAll\MSFT_WaitForAll.psm1 | Where-Object {$_.RuleName -eq $violationName} +$noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\DSCResourceModule\DSCResources\MSFT_WaitForAny\MSFT_WaitForAny.psm1 | Where-Object {$_.RuleName -eq $violationName} if ($PSVersionTable.PSVersion -ge [Version]'5.0.0') { - $classViolations = Invoke-ScriptAnalyzer -ErrorAction SilentlyContinue $directory\DSCResourceModule\DSCResources\BadDscResource\BadDscResource.psm1 | Where-Object {$_.RuleName -eq $violationName} - $noClassViolations = Invoke-ScriptAnalyzer -ErrorAction SilentlyContinue $directory\DSCResourceModule\DSCResources\MyDscResource\MyDscResource.psm1 | Where-Object {$_.RuleName -eq $violationName} + $classViolations = Invoke-ScriptAnalyzer -ErrorAction SilentlyContinue $PSScriptRoot\DSCResourceModule\DSCResources\BadDscResource\BadDscResource.psm1 | Where-Object {$_.RuleName -eq $violationName} + $noClassViolations = Invoke-ScriptAnalyzer -ErrorAction SilentlyContinue $PSScriptRoot\DSCResourceModule\DSCResources\MyDscResource\MyDscResource.psm1 | Where-Object {$_.RuleName -eq $violationName} } Describe "ReturnCorrectTypesForDSCFunctions" { diff --git a/Tests/Rules/UseBOMForUnicodeEncodedFile.tests.ps1 b/Tests/Rules/UseBOMForUnicodeEncodedFile.tests.ps1 index 0aa479ce1..ba992d43e 100644 --- a/Tests/Rules/UseBOMForUnicodeEncodedFile.tests.ps1 +++ b/Tests/Rules/UseBOMForUnicodeEncodedFile.tests.ps1 @@ -1,11 +1,10 @@ $violationMessageOne = "Missing BOM encoding for non-ASCII encoded file 'BOMAbsent_UTF16EncodedScript.ps1'" $violationMessageTwo = "Missing BOM encoding for non-ASCII encoded file 'BOMAbsent_UnknownEncodedScript.ps1'" $violationName = "PSUseBOMForUnicodeEncodedFile" -$directory = Split-Path -Parent $MyInvocation.MyCommand.Path -$violationsOne = Invoke-ScriptAnalyzer "$directory\TestFiles\BOMAbsent_UTF16EncodedScript.ps1" | Where-Object {$_.RuleName -eq $violationName} -$violationsTwo = Invoke-ScriptAnalyzer "$directory\TestFiles\BOMAbsent_UnknownEncodedScript.ps1" | Where-Object {$_.RuleName -eq $violationName} -$noViolationsOne = Invoke-ScriptAnalyzer "$directory\TestFiles\BOMPresent_UTF16EncodedScript.ps1" | Where-Object {$_.RuleName -eq $violationName} -$noViolationsTwo = Invoke-ScriptAnalyzer "$directory\TestFiles\BOMAbsent_ASCIIEncodedScript.ps1" | Where-Object {$_.RuleName -eq $violationName} +$violationsOne = Invoke-ScriptAnalyzer "$PSScriptRoot\TestFiles\BOMAbsent_UTF16EncodedScript.ps1" | Where-Object {$_.RuleName -eq $violationName} +$violationsTwo = Invoke-ScriptAnalyzer "$PSScriptRoot\TestFiles\BOMAbsent_UnknownEncodedScript.ps1" | Where-Object {$_.RuleName -eq $violationName} +$noViolationsOne = Invoke-ScriptAnalyzer "$PSScriptRoot\TestFiles\BOMPresent_UTF16EncodedScript.ps1" | Where-Object {$_.RuleName -eq $violationName} +$noViolationsTwo = Invoke-ScriptAnalyzer "$PSScriptRoot\TestFiles\BOMAbsent_ASCIIEncodedScript.ps1" | Where-Object {$_.RuleName -eq $violationName} Describe "UseBOMForUnicodeEncodedFile" { Context "When there are violations" { diff --git a/Tests/Rules/UseCmdletCorrectly.tests.ps1 b/Tests/Rules/UseCmdletCorrectly.tests.ps1 index 1e2ac6633..207036eb1 100644 --- a/Tests/Rules/UseCmdletCorrectly.tests.ps1 +++ b/Tests/Rules/UseCmdletCorrectly.tests.ps1 @@ -1,8 +1,7 @@ $violationMessage = "Cmdlet 'Write-Warning' may be used incorrectly. Please check that all mandatory parameters are supplied." $violationName = "PSUseCmdletCorrectly" -$directory = Split-Path -Parent $MyInvocation.MyCommand.Path -$violations = Invoke-ScriptAnalyzer $directory\UseCmdletCorrectly.ps1 | Where-Object {$_.RuleName -eq $violationName} -$noViolations = Invoke-ScriptAnalyzer $directory\GoodCmdlet.ps1 | Where-Object {$_.RuleName -eq $violationName} +$violations = Invoke-ScriptAnalyzer $PSScriptRoot\UseCmdletCorrectly.ps1 | Where-Object {$_.RuleName -eq $violationName} +$noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\GoodCmdlet.ps1 | Where-Object {$_.RuleName -eq $violationName} Describe "UseCmdletCorrectly" { Context "When there are violations" { diff --git a/Tests/Rules/UseCompatibleCmdlets.tests.ps1 b/Tests/Rules/UseCompatibleCmdlets.tests.ps1 index 41ff3d420..d4db68502 100644 --- a/Tests/Rules/UseCompatibleCmdlets.tests.ps1 +++ b/Tests/Rules/UseCompatibleCmdlets.tests.ps1 @@ -1,7 +1,6 @@ $ruleName = "PSUseCompatibleCmdlets" -$directory = Split-Path $MyInvocation.MyCommand.Path -Parent -$testRootDirectory = Split-Path -Parent $directory -$ruleTestDirectory = Join-Path $directory 'UseCompatibleCmdlets' +$testRootDirectory = Split-Path -Parent $PSScriptRoot +$ruleTestDirectory = Join-Path $PSScriptRoot 'UseCompatibleCmdlets' Import-Module (Join-Path $testRootDirectory 'PSScriptAnalyzerTestHelper.psm1') diff --git a/Tests/Rules/UseConsistentIndentation.tests.ps1 b/Tests/Rules/UseConsistentIndentation.tests.ps1 index 2e9a03fd7..06dbea290 100644 --- a/Tests/Rules/UseConsistentIndentation.tests.ps1 +++ b/Tests/Rules/UseConsistentIndentation.tests.ps1 @@ -1,6 +1,4 @@ -$directory = Split-Path -Parent $MyInvocation.MyCommand.Path -$testRootDirectory = Split-Path -Parent $directory - +$testRootDirectory = Split-Path -Parent $PSScriptRoot Import-Module (Join-Path $testRootDirectory "PSScriptAnalyzerTestHelper.psm1") diff --git a/Tests/Rules/UseConsistentWhitespace.tests.ps1 b/Tests/Rules/UseConsistentWhitespace.tests.ps1 index 0d1441384..23bf18350 100644 --- a/Tests/Rules/UseConsistentWhitespace.tests.ps1 +++ b/Tests/Rules/UseConsistentWhitespace.tests.ps1 @@ -1,6 +1,4 @@ -$directory = Split-Path -Parent $MyInvocation.MyCommand.Path -$testRootDirectory = Split-Path -Parent $directory - +$testRootDirectory = Split-Path -Parent $PSScriptRoot Import-Module (Join-Path $testRootDirectory "PSScriptAnalyzerTestHelper.psm1") $ruleName = "PSUseConsistentWhitespace" diff --git a/Tests/Rules/UseDSCResourceFunctions.tests.ps1 b/Tests/Rules/UseDSCResourceFunctions.tests.ps1 index 45ebef3d9..f88801a21 100644 --- a/Tests/Rules/UseDSCResourceFunctions.tests.ps1 +++ b/Tests/Rules/UseDSCResourceFunctions.tests.ps1 @@ -2,14 +2,13 @@ $violationMessage = "Missing 'Get-TargetResource' function. DSC Resource must implement Get, Set and Test-TargetResource functions." $classViolationMessage = "Missing 'Set' function. DSC Class must implement Get, Set and Test functions." $violationName = "PSDSCStandardDSCFunctionsInResource" -$directory = Split-Path -Parent $MyInvocation.MyCommand.Path -$violations = Invoke-ScriptAnalyzer $directory\DSCResourceModule\DSCResources\MSFT_WaitForAll\MSFT_WaitForAll.psm1 | Where-Object {$_.RuleName -eq $violationName} -$noViolations = Invoke-ScriptAnalyzer $directory\DSCResourceModule\DSCResources\MSFT_WaitForAny\MSFT_WaitForAny.psm1 | Where-Object {$_.RuleName -eq $violationName} +$violations = Invoke-ScriptAnalyzer $PSScriptRoot\DSCResourceModule\DSCResources\MSFT_WaitForAll\MSFT_WaitForAll.psm1 | Where-Object {$_.RuleName -eq $violationName} +$noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\DSCResourceModule\DSCResources\MSFT_WaitForAny\MSFT_WaitForAny.psm1 | Where-Object {$_.RuleName -eq $violationName} if ($PSVersionTable.PSVersion -ge [Version]'5.0.0') { - $classViolations = Invoke-ScriptAnalyzer -ErrorAction SilentlyContinue $directory\DSCResourceModule\DSCResources\BadDscResource\BadDscResource.psm1 | Where-Object {$_.RuleName -eq $violationName} - $noClassViolations = Invoke-ScriptAnalyzer -ErrorAction SilentlyContinue $directory\DSCResourceModule\DSCResources\MyDscResource\MyDscResource.psm1 | Where-Object {$_.RuleName -eq $violationName} + $classViolations = Invoke-ScriptAnalyzer -ErrorAction SilentlyContinue $PSScriptRoot\DSCResourceModule\DSCResources\BadDscResource\BadDscResource.psm1 | Where-Object {$_.RuleName -eq $violationName} + $noClassViolations = Invoke-ScriptAnalyzer -ErrorAction SilentlyContinue $PSScriptRoot\DSCResourceModule\DSCResources\MyDscResource\MyDscResource.psm1 | Where-Object {$_.RuleName -eq $violationName} } Describe "StandardDSCFunctionsInResource" { diff --git a/Tests/Rules/UseDeclaredVarsMoreThanAssignments.tests.ps1 b/Tests/Rules/UseDeclaredVarsMoreThanAssignments.tests.ps1 index 43775b36d..c81fc74f7 100644 --- a/Tests/Rules/UseDeclaredVarsMoreThanAssignments.tests.ps1 +++ b/Tests/Rules/UseDeclaredVarsMoreThanAssignments.tests.ps1 @@ -1,12 +1,10 @@ -$directory = Split-Path -Parent $MyInvocation.MyCommand.Path -$testRootDirectory = Split-Path -Parent $directory - +$testRootDirectory = Split-Path -Parent $PSScriptRoot Import-Module (Join-Path $testRootDirectory 'PSScriptAnalyzerTestHelper.psm1') $violationMessage = "The variable 'declaredVar2' is assigned but never used." $violationName = "PSUseDeclaredVarsMoreThanAssignments" -$violations = Invoke-ScriptAnalyzer $directory\UseDeclaredVarsMoreThanAssignments.ps1 | Where-Object {$_.RuleName -eq $violationName} -$noViolations = Invoke-ScriptAnalyzer $directory\UseDeclaredVarsMoreThanAssignmentsNoViolations.ps1 | Where-Object {$_.RuleName -eq $violationName} +$violations = Invoke-ScriptAnalyzer $PSScriptRoot\UseDeclaredVarsMoreThanAssignments.ps1 | Where-Object {$_.RuleName -eq $violationName} +$noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\UseDeclaredVarsMoreThanAssignmentsNoViolations.ps1 | Where-Object {$_.RuleName -eq $violationName} Describe "UseDeclaredVarsMoreThanAssignments" { Context "When there are violations" { diff --git a/Tests/Rules/UseIdenticalMandatoryParametersForDSC.tests.ps1 b/Tests/Rules/UseIdenticalMandatoryParametersForDSC.tests.ps1 index 6d49eb4b3..d8e96c709 100644 --- a/Tests/Rules/UseIdenticalMandatoryParametersForDSC.tests.ps1 +++ b/Tests/Rules/UseIdenticalMandatoryParametersForDSC.tests.ps1 @@ -1,6 +1,5 @@ -$directory = Split-Path -Parent $MyInvocation.MyCommand.Path $ruleName = 'PSDSCUseIdenticalMandatoryParametersForDSC' -$resourceBasepath = "$directory\DSCResourceModule\DSCResources" +$resourceBasepath = "$PSScriptRoot\DSCResourceModule\DSCResources" $badResourceFilepath = [System.IO.Path]::Combine( $resourceBasepath, 'MSFT_WaitForAnyNoIdenticalMandatoryParameter', diff --git a/Tests/Rules/UseIdenticalParametersDSC.tests.ps1 b/Tests/Rules/UseIdenticalParametersDSC.tests.ps1 index 55e8e27d4..36250cd04 100644 --- a/Tests/Rules/UseIdenticalParametersDSC.tests.ps1 +++ b/Tests/Rules/UseIdenticalParametersDSC.tests.ps1 @@ -1,12 +1,11 @@ $violationMessage = "The Test and Set-TargetResource functions of DSC Resource must have the same parameters." $violationName = "PSDSCUseIdenticalParametersForDSC" -$directory = Split-Path -Parent $MyInvocation.MyCommand.Path -$violations = Invoke-ScriptAnalyzer $directory\DSCResourceModule\DSCResources\MSFT_WaitForAll\MSFT_WaitForAll.psm1 | Where-Object {$_.RuleName -eq $violationName} -$noViolations = Invoke-ScriptAnalyzer $directory\DSCResourceModule\DSCResources\MSFT_WaitForAny\MSFT_WaitForAny.psm1 | Where-Object {$_.RuleName -eq $violationName} +$violations = Invoke-ScriptAnalyzer $PSScriptRoot\DSCResourceModule\DSCResources\MSFT_WaitForAll\MSFT_WaitForAll.psm1 | Where-Object {$_.RuleName -eq $violationName} +$noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\DSCResourceModule\DSCResources\MSFT_WaitForAny\MSFT_WaitForAny.psm1 | Where-Object {$_.RuleName -eq $violationName} if ($PSVersionTable.PSVersion -ge [Version]'5.0.0') { - $noClassViolations = Invoke-ScriptAnalyzer -ErrorAction SilentlyContinue $directory\DSCResourceModule\DSCResources\MyDscResource\MyDscResource.psm1 | Where-Object {$_.RuleName -eq $violationName} + $noClassViolations = Invoke-ScriptAnalyzer -ErrorAction SilentlyContinue $PSScriptRoot\DSCResourceModule\DSCResources\MyDscResource\MyDscResource.psm1 | Where-Object {$_.RuleName -eq $violationName} } Describe "UseIdenticalParametersDSC" { diff --git a/Tests/Rules/UseOutputTypeCorrectly.tests.ps1 b/Tests/Rules/UseOutputTypeCorrectly.tests.ps1 index 92ab67182..8674643d5 100644 --- a/Tests/Rules/UseOutputTypeCorrectly.tests.ps1 +++ b/Tests/Rules/UseOutputTypeCorrectly.tests.ps1 @@ -1,14 +1,13 @@ $violationMessage = "The cmdlet 'Verb-Files' returns an object of type 'System.Collections.Hashtable' but this type is not declared in the OutputType attribute." $violationName = "PSUseOutputTypeCorrectly" -$directory = Split-Path -Parent $MyInvocation.MyCommand.Path -$violations = Invoke-ScriptAnalyzer $directory\BadCmdlet.ps1 | Where-Object {$_.RuleName -eq $violationName} +$violations = Invoke-ScriptAnalyzer $PSScriptRoot\BadCmdlet.ps1 | Where-Object {$_.RuleName -eq $violationName} if ($PSVersionTable.PSVersion -ge [Version]'5.0.0') { - $dscViolations = Invoke-ScriptAnalyzer -ErrorAction SilentlyContinue $directory\DSCResourceModule\DSCResources\MyDscResource\MyDscResource.psm1 | Where-Object {$_.RuleName -eq $violationName} + $dscViolations = Invoke-ScriptAnalyzer -ErrorAction SilentlyContinue $PSScriptRoot\DSCResourceModule\DSCResources\MyDscResource\MyDscResource.psm1 | Where-Object {$_.RuleName -eq $violationName} } -$noViolations = Invoke-ScriptAnalyzer $directory\GoodCmdlet.ps1 | Where-Object {$_.RuleName -eq $violationName} +$noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\GoodCmdlet.ps1 | Where-Object {$_.RuleName -eq $violationName} Describe "UseOutputTypeCorrectly" { Context "When there are violations" { diff --git a/Tests/Rules/UseShouldProcessCorrectly.tests.ps1 b/Tests/Rules/UseShouldProcessCorrectly.tests.ps1 index cec228f47..4d247ad92 100644 --- a/Tests/Rules/UseShouldProcessCorrectly.tests.ps1 +++ b/Tests/Rules/UseShouldProcessCorrectly.tests.ps1 @@ -1,13 +1,14 @@ -$violationMessage = "'Verb-Files' has the ShouldProcess attribute but does not call ShouldProcess/ShouldContinue." -$violationName = "PSShouldProcess" -$directory = Split-Path -Parent $MyInvocation.MyCommand.Path -$testRootDirectory = Split-Path -Parent $directory +BeforeAll{ + $violationMessage = "'Verb-Files' has the ShouldProcess attribute but does not call ShouldProcess/ShouldContinue." + $violationName = "PSShouldProcess" + $testRootDirectory = Split-Path -Parent $PSScriptRoot -Import-Module (Join-Path $testRootDirectory 'PSScriptAnalyzerTestHelper.psm1') + Import-Module (Join-Path $testRootDirectory 'PSScriptAnalyzerTestHelper.psm1') -$violations = Invoke-ScriptAnalyzer $directory\BadCmdlet.ps1 | Where-Object {$_.RuleName -eq $violationName} -$noViolations = Invoke-ScriptAnalyzer $directory\GoodCmdlet.ps1 | Where-Object {$_.RuleName -eq $violationName} -$IsV3OrV4 = (Test-PSVersionV3) -or (Test-PSVersionV4) + $violations = Invoke-ScriptAnalyzer $PSScriptRoot\BadCmdlet.ps1 | Where-Object {$_.RuleName -eq $violationName} + $noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\GoodCmdlet.ps1 | Where-Object {$_.RuleName -eq $violationName} + $IsV3OrV4 = (Test-PSVersionV3) -or (Test-PSVersionV4) +} Describe "UseShouldProcessCorrectly" { Context "When there are violations" { diff --git a/Tests/Rules/UseShouldProcessForStateChangingFunctions.tests.ps1 b/Tests/Rules/UseShouldProcessForStateChangingFunctions.tests.ps1 index 8d8ae23e4..ed377f1c0 100644 --- a/Tests/Rules/UseShouldProcessForStateChangingFunctions.tests.ps1 +++ b/Tests/Rules/UseShouldProcessForStateChangingFunctions.tests.ps1 @@ -1,8 +1,7 @@ $violationMessage = "Function 'Set-MyObject' has verb that could change system state. Therefore, the function has to support 'ShouldProcess'" $violationName = "PSUseShouldProcessForStateChangingFunctions" -$directory = Split-Path -Parent $MyInvocation.MyCommand.Path -$violations = Invoke-ScriptAnalyzer $directory\UseShouldProcessForStateChangingFunctions.ps1 | Where-Object {$_.RuleName -eq $violationName} -$noViolations = Invoke-ScriptAnalyzer $directory\UseShouldProcessForStateChangingFunctionsNoViolations.ps1 | Where-Object {$_.RuleName -eq $violationName} +$violations = Invoke-ScriptAnalyzer $PSScriptRoot\UseShouldProcessForStateChangingFunctions.ps1 | Where-Object {$_.RuleName -eq $violationName} +$noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\UseShouldProcessForStateChangingFunctionsNoViolations.ps1 | Where-Object {$_.RuleName -eq $violationName} Describe "It checks UseShouldProcess is enabled when there are state changing verbs in the function names" { Context "When function name has state changing verb" { diff --git a/Tests/Rules/UseSingularNounsReservedVerbs.tests.ps1 b/Tests/Rules/UseSingularNounsReservedVerbs.tests.ps1 index e16ee5cc2..66e9bc764 100644 --- a/Tests/Rules/UseSingularNounsReservedVerbs.tests.ps1 +++ b/Tests/Rules/UseSingularNounsReservedVerbs.tests.ps1 @@ -1,20 +1,16 @@ -$directory = Split-Path -Parent $MyInvocation.MyCommand.Path -$testRootDirectory = Split-Path -Parent $directory -Import-Module (Join-Path $testRootDirectory 'PSScriptAnalyzerTestHelper.psm1') - $nounViolationMessage = "The cmdlet 'Verb-Files' uses a plural noun. A singular noun should be used instead." $verbViolationMessage = "The cmdlet 'Verb-Files' uses an unapproved verb." $nounViolationName = "PSUseSingularNouns" $verbViolationName = "PSUseApprovedVerbs" -$violations = Invoke-ScriptAnalyzer $directory\BadCmdlet.ps1 +$violations = Invoke-ScriptAnalyzer $PSScriptRoot\BadCmdlet.ps1 $nounViolations = $violations | Where-Object {$_.RuleName -eq $nounViolationName} $verbViolations = $violations | Where-Object {$_.RuleName -eq $verbViolationName} -$noViolations = Invoke-ScriptAnalyzer $directory\GoodCmdlet.ps1 +$noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\GoodCmdlet.ps1 $nounNoViolations = $noViolations | Where-Object {$_.RuleName -eq $nounViolationName} $verbNoViolations = $noViolations | Where-Object {$_.RuleName -eq $verbViolationName} # this rule doesn't exist in the non desktop version of PSScriptAnalyzer -if (-not (Test-PSEditionCoreCLR)) +if (-not ([bool] $IsCoreCLR)) { Describe "UseSingularNouns" { Context "When there are violations" { diff --git a/Tests/Rules/UseSupportsShouldProcess.tests.ps1 b/Tests/Rules/UseSupportsShouldProcess.tests.ps1 index 91c9865b6..ba43c06b0 100644 --- a/Tests/Rules/UseSupportsShouldProcess.tests.ps1 +++ b/Tests/Rules/UseSupportsShouldProcess.tests.ps1 @@ -1,6 +1,4 @@ -$directory = Split-Path -Parent $MyInvocation.MyCommand.Path -$testRootDirectory = Split-Path -Parent $directory - +$testRootDirectory = Split-Path -Parent $PSScriptRoot Import-Module (Join-Path $testRootDirectory "PSScriptAnalyzerTestHelper.psm1") $settings = @{ diff --git a/Tests/Rules/UseToExportFieldsInManifest.tests.ps1 b/Tests/Rules/UseToExportFieldsInManifest.tests.ps1 index 5285bd6ac..02ad49471 100644 --- a/Tests/Rules/UseToExportFieldsInManifest.tests.ps1 +++ b/Tests/Rules/UseToExportFieldsInManifest.tests.ps1 @@ -1,8 +1,7 @@ -$directory = Split-Path -Parent $MyInvocation.MyCommand.Path -$testRootDirectory = Split-Path -Parent $directory +$testRootDirectory = Split-Path -Parent $PSScriptRoot Import-Module (Join-Path $testRootDirectory 'PSScriptAnalyzerTestHelper.psm1') -$testManifestPath = Join-Path $directory "TestManifest" +$testManifestPath = Join-Path $PSScriptRoot "TestManifest" $testManifestBadFunctionsWildcardPath = "ManifestBadFunctionsWildcard.psd1" $testManifestBadFunctionsWildcardInArrayPath = "ManifestBadFunctionsWildcardInArray.psd1" $testManifestBadFunctionsNullPath = "ManifestBadFunctionsNull.psd1" @@ -12,7 +11,7 @@ $testManifestBadVariablesWildcardPath = "ManifestBadVariablesWildcard.psd1" $testManifestBadAllPath = "ManifestBadAll.psd1" $testManifestGoodPath = "ManifestGood.psd1" $testManifestInvalidPath = "ManifestInvalid.psd1" -Import-Module (Join-Path $directory "PSScriptAnalyzerTestHelper.psm1") +Import-Module (Join-Path $PSScriptRoot "PSScriptAnalyzerTestHelper.psm1") Function Run-PSScriptAnalyzerRule { @@ -104,7 +103,7 @@ Describe "UseManifestExportFields" { Context "When given a non module manifest file" { It "does not flag a PowerShell data file" { Invoke-ScriptAnalyzer ` - -Path "$directory/TestManifest/PowerShellDataFile.psd1" ` + -Path "$PSScriptRoot/TestManifest/PowerShellDataFile.psd1" ` -IncludeRule "PSUseToExportFieldsInManifest" ` -OutVariable ruleViolation $ruleViolation.Count | Should -Be 0 diff --git a/Tests/Rules/UseUTF8EncodingForHelpFile.tests.ps1 b/Tests/Rules/UseUTF8EncodingForHelpFile.tests.ps1 index 1f99549d5..6404dcab8 100644 --- a/Tests/Rules/UseUTF8EncodingForHelpFile.tests.ps1 +++ b/Tests/Rules/UseUTF8EncodingForHelpFile.tests.ps1 @@ -1,11 +1,10 @@ -$directory = Split-Path -Parent $MyInvocation.MyCommand.Path -Describe "UseUTF8EncodingForHelpFile" { +Describe "UseUTF8EncodingForHelpFile" { BeforeAll { $violationMessage = "File about_utf16.help.txt has to use UTF8 instead of System.Text.UTF32Encoding encoding because it is a powershell help file." $violationName = "PSUseUTF8EncodingForHelpFile" - $violations = Invoke-ScriptAnalyzer $directory\about_utf16.help.txt | Where-Object {$_.RuleName -eq $violationName} - $noViolations = Invoke-ScriptAnalyzer $directory\about_utf8.help.txt | Where-Object {$_.RuleName -eq $violationName} - $notHelpFileViolations = Invoke-ScriptAnalyzer $directory\utf16.txt | Where-Object {$_.RuleName -eq $violationName} + $violations = Invoke-ScriptAnalyzer $PSScriptRoot\about_utf16.help.txt | Where-Object {$_.RuleName -eq $violationName} + $noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\about_utf8.help.txt | Where-Object {$_.RuleName -eq $violationName} + $notHelpFileViolations = Invoke-ScriptAnalyzer $PSScriptRoot\utf16.txt | Where-Object {$_.RuleName -eq $violationName} } Context "When there are violations" { diff --git a/Tests/Rules/UseVerboseMessageInDSCResource.Tests.ps1 b/Tests/Rules/UseVerboseMessageInDSCResource.Tests.ps1 index cb5111ed8..c7440c37a 100644 --- a/Tests/Rules/UseVerboseMessageInDSCResource.Tests.ps1 +++ b/Tests/Rules/UseVerboseMessageInDSCResource.Tests.ps1 @@ -1,9 +1,8 @@ $violationMessage = "There is no call to Write-Verbose in DSC function 'Test-TargetResource'. If you are using Write-Verbose in a helper function, suppress this rule application." $violationName = "PSDSCUseVerboseMessageInDSCResource" -$directory = Split-Path -Parent $MyInvocation.MyCommand.Path -$violations = Invoke-ScriptAnalyzer $directory\DSCResourceModule\DSCResources\MSFT_WaitForAll\MSFT_WaitForAll.psm1 | Where-Object {$_.RuleName -eq $violationName} -$noViolations = Invoke-ScriptAnalyzer $directory\DSCResourceModule\DSCResources\MSFT_WaitForAny\MSFT_WaitForAny.psm1 | Where-Object {$_.RuleName -eq $violationName} -$noClassViolations = Invoke-ScriptAnalyzer -ErrorAction SilentlyContinue $directory\DSCResourceModule\DSCResources\MyDscResource\MyDscResource.psm1 | Where-Object {$_.RuleName -eq $violationName} +$violations = Invoke-ScriptAnalyzer $PSScriptRoot\DSCResourceModule\DSCResources\MSFT_WaitForAll\MSFT_WaitForAll.psm1 | Where-Object {$_.RuleName -eq $violationName} +$noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\DSCResourceModule\DSCResources\MSFT_WaitForAny\MSFT_WaitForAny.psm1 | Where-Object {$_.RuleName -eq $violationName} +$noClassViolations = Invoke-ScriptAnalyzer -ErrorAction SilentlyContinue $PSScriptRoot\DSCResourceModule\DSCResources\MyDscResource\MyDscResource.psm1 | Where-Object {$_.RuleName -eq $violationName} Describe "UseVerboseMessageInDSCResource" { Context "When there are violations" { From d4f54f5ac710a884ae2c643787cb2db856c63ac1 Mon Sep 17 00:00:00 2001 From: Christoph Bergmeister Date: Sun, 12 Apr 2020 21:10:30 +0100 Subject: [PATCH 02/76] Fix 2 small mistakes, test should now be green again --- Tests/Rules/AvoidEmptyCatchBlock.tests.ps1 | 2 +- Tests/Rules/UseShouldProcessCorrectly.tests.ps1 | 17 +++++++---------- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/Tests/Rules/AvoidEmptyCatchBlock.tests.ps1 b/Tests/Rules/AvoidEmptyCatchBlock.tests.ps1 index cdd720e77..636075099 100644 --- a/Tests/Rules/AvoidEmptyCatchBlock.tests.ps1 +++ b/Tests/Rules/AvoidEmptyCatchBlock.tests.ps1 @@ -1,5 +1,5 @@ $violationMessage = "Empty catch block is used. Please use Write-Error or throw statements in catch blocks." -$violationName = "PSAvoidUsingE +$violationName = "PSAvoidUsingEmptyCatchBlock" $violations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidEmptyCatchBlock.ps1 | Where-Object {$_.RuleName -eq $violationName} $noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidEmptyCatchBlockNoViolations.ps1 | Where-Object {$_.RuleName -eq $violationName} diff --git a/Tests/Rules/UseShouldProcessCorrectly.tests.ps1 b/Tests/Rules/UseShouldProcessCorrectly.tests.ps1 index 4d247ad92..d870c69ae 100644 --- a/Tests/Rules/UseShouldProcessCorrectly.tests.ps1 +++ b/Tests/Rules/UseShouldProcessCorrectly.tests.ps1 @@ -1,14 +1,11 @@ -BeforeAll{ - $violationMessage = "'Verb-Files' has the ShouldProcess attribute but does not call ShouldProcess/ShouldContinue." - $violationName = "PSShouldProcess" - $testRootDirectory = Split-Path -Parent $PSScriptRoot +$violationMessage = "'Verb-Files' has the ShouldProcess attribute but does not call ShouldProcess/ShouldContinue." +$violationName = "PSShouldProcess" +$testRootDirectory = Split-Path -Parent $PSScriptRoot +Import-Module (Join-Path $testRootDirectory 'PSScriptAnalyzerTestHelper.psm1') - Import-Module (Join-Path $testRootDirectory 'PSScriptAnalyzerTestHelper.psm1') - - $violations = Invoke-ScriptAnalyzer $PSScriptRoot\BadCmdlet.ps1 | Where-Object {$_.RuleName -eq $violationName} - $noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\GoodCmdlet.ps1 | Where-Object {$_.RuleName -eq $violationName} - $IsV3OrV4 = (Test-PSVersionV3) -or (Test-PSVersionV4) -} +$violations = Invoke-ScriptAnalyzer $PSScriptRoot\BadCmdlet.ps1 | Where-Object {$_.RuleName -eq $violationName} +$noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\GoodCmdlet.ps1 | Where-Object {$_.RuleName -eq $violationName} +$IsV3OrV4 = (Test-PSVersionV3) -or (Test-PSVersionV4) Describe "UseShouldProcessCorrectly" { Context "When there are violations" { From eeb251fe7c209a3b5654baafb41defaa7352dd57 Mon Sep 17 00:00:00 2001 From: Christoph Bergmeister Date: Sun, 12 Apr 2020 21:41:43 +0100 Subject: [PATCH 03/76] Adapt build.psm1 --- build.psm1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.psm1 b/build.psm1 index 5a85e3187..b95a98f12 100644 --- a/build.psm1 +++ b/build.psm1 @@ -333,11 +333,11 @@ function Test-ScriptAnalyzer $env:PSModulePath = "${testModulePath}{0}${env:PSModulePath}" -f [System.IO.Path]::PathSeparator if ($ShowAll) { - $scriptBlock = [scriptblock]::Create("Invoke-Pester -Path $testScripts -OutputFormat NUnitXml -OutputFile $testResultsFile") + $scriptBlock = [scriptblock]::Create("Invoke-Pester -Path $testScripts -CI") } else { - $scriptBlock = [scriptblock]::Create("Invoke-Pester -Path $testScripts -OutputFormat NUnitXml -OutputFile $testResultsFile -Show Describe,Summary,Failed") + $scriptBlock = [scriptblock]::Create("Invoke-Pester -Path $testScripts -CI") } if ( $InProcess ) { & $scriptBlock From 36d213aefedaca111beb9713a54e4ffda6ce2215 Mon Sep 17 00:00:00 2001 From: Christoph Bergmeister Date: Sun, 12 Apr 2020 22:31:27 +0100 Subject: [PATCH 04/76] Engine tests migration to Pester v5 --- Tests/Engine/CorrectionExtent.tests.ps1 | 3 + Tests/Engine/CustomizedRule.tests.ps1 | 34 +- Tests/Engine/EditableText.tests.ps1 | 13 +- Tests/Engine/Extensions.tests.ps1 | 54 +-- Tests/Engine/GetScriptAnalyzerRule.tests.ps1 | 44 +- Tests/Engine/GlobalSuppression.test.ps1 | 27 +- Tests/Engine/Helper.tests.ps1 | 3 + Tests/Engine/InvokeFormatter.tests.ps1 | 9 +- Tests/Engine/InvokeScriptAnalyzer.tests.ps1 | 17 +- Tests/Engine/LibraryUsage.tests.ps1 | 387 +++++++++--------- .../Engine/ModuleDependencyHandler.tests.ps1 | 3 + Tests/Engine/ModuleHelp.Tests.ps1 | 3 + Tests/Engine/RuleSuppression.tests.ps1 | 74 ++-- Tests/Engine/RuleSuppressionClass.tests.ps1 | 17 +- 14 files changed, 380 insertions(+), 308 deletions(-) diff --git a/Tests/Engine/CorrectionExtent.tests.ps1 b/Tests/Engine/CorrectionExtent.tests.ps1 index 3959088d5..6ccf14d00 100644 --- a/Tests/Engine/CorrectionExtent.tests.ps1 +++ b/Tests/Engine/CorrectionExtent.tests.ps1 @@ -1,3 +1,6 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + Describe "Correction Extent" { $type = [Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic.CorrectionExtent] diff --git a/Tests/Engine/CustomizedRule.tests.ps1 b/Tests/Engine/CustomizedRule.tests.ps1 index af10ba5fd..9a931afcb 100644 --- a/Tests/Engine/CustomizedRule.tests.ps1 +++ b/Tests/Engine/CustomizedRule.tests.ps1 @@ -1,23 +1,27 @@ -if (-not ([bool] $IsCoreCLR)) -{ - # Force Get-Help not to prompt for interactive input to download help using Update-Help - # By adding this registry key we turn off Get-Help interactivity logic during ScriptRule parsing - $null,"Wow6432Node" | ForEach-Object { - try - { - Set-ItemProperty -Name "DisablePromptToUpdateHelp" -Path "HKLM:\SOFTWARE\$($_)\Microsoft\PowerShell" -Value 1 -Force -ErrorAction SilentlyContinue - } - catch - { - # Ignore for cases when tests are running in non-elevated more or registry key does not exist or not accessible +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +BeforeAll { + if (-not ([bool] $IsCoreCLR)) + { + # Force Get-Help not to prompt for interactive input to download help using Update-Help + # By adding this registry key we turn off Get-Help interactivity logic during ScriptRule parsing + $null,"Wow6432Node" | ForEach-Object { + try + { + Set-ItemProperty -Name "DisablePromptToUpdateHelp" -Path "HKLM:\SOFTWARE\$($_)\Microsoft\PowerShell" -Value 1 -Force -ErrorAction SilentlyContinue + } + catch + { + # Ignore for cases when tests are running in non-elevated more or registry key does not exist or not accessible + } } } + $message = "this is help" + $measure = "Measure-RequiresRunAsAdministrator" } -$message = "this is help" -$measure = "Measure-RequiresRunAsAdministrator" - Describe "Test importing customized rules with null return results" { Context "Test Get-ScriptAnalyzer with customized rules" { It "will not terminate the engine" { diff --git a/Tests/Engine/EditableText.tests.ps1 b/Tests/Engine/EditableText.tests.ps1 index eb0222e94..b973b5cb5 100644 --- a/Tests/Engine/EditableText.tests.ps1 +++ b/Tests/Engine/EditableText.tests.ps1 @@ -1,7 +1,12 @@ -$testRootDirectory = Split-Path -Parent $PSScriptRoot -Import-Module (Join-Path $testRootDirectory "PSScriptAnalyzerTestHelper.psm1") -$editableTextType = "Microsoft.Windows.PowerShell.ScriptAnalyzer.EditableText" -$textEditType = "Microsoft.Windows.PowerShell.ScriptAnalyzer.TextEdit" +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +BeforeAll { + $testRootDirectory = Split-Path -Parent $PSScriptRoot + Import-Module (Join-Path $testRootDirectory "PSScriptAnalyzerTestHelper.psm1") + $editableTextType = "Microsoft.Windows.PowerShell.ScriptAnalyzer.EditableText" + $textEditType = "Microsoft.Windows.PowerShell.ScriptAnalyzer.TextEdit" +} Describe "EditableText class" { Context "When a single edit is given for application" { diff --git a/Tests/Engine/Extensions.tests.ps1 b/Tests/Engine/Extensions.tests.ps1 index 875c8ce96..11ab79147 100644 --- a/Tests/Engine/Extensions.tests.ps1 +++ b/Tests/Engine/Extensions.tests.ps1 @@ -1,30 +1,36 @@ -$testRootDirectory = Split-Path -Parent $PSScriptRoot -Import-Module (Join-Path $testRootDirectory "PSScriptAnalyzerTestHelper.psm1") - -function Get-Extent { - param($line, $startLineNum, $startColumnNum, $endLineNum, $endColumnNum) - $scriptPositionType = 'System.Management.Automation.Language.ScriptPosition' - $scriptExtentType = 'System.Management.Automation.Language.ScriptExtent' - $extentStartPos = New-Object -TypeName $scriptPositionType -ArgumentList $null, $startLineNum, $startColumnNum, $line - $extentEndPos = New-Object -TypeName $scriptPositionType -ArgumentList $null, $endLineNum, $endColumnNum, $line - New-Object -TypeName $scriptExtentType -ArgumentList $extentStartPos, $extentEndPos -} +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +BeforeAll { + $testRootDirectory = Split-Path -Parent $PSScriptRoot + Import-Module (Join-Path $testRootDirectory "PSScriptAnalyzerTestHelper.psm1") + + function Get-Extent { + param($line, $startLineNum, $startColumnNum, $endLineNum, $endColumnNum) + $scriptPositionType = 'System.Management.Automation.Language.ScriptPosition' + $scriptExtentType = 'System.Management.Automation.Language.ScriptExtent' + $extentStartPos = New-Object -TypeName $scriptPositionType -ArgumentList $null, $startLineNum, $startColumnNum, $line + $extentEndPos = New-Object -TypeName $scriptPositionType -ArgumentList $null, $endLineNum, $endColumnNum, $line + New-Object -TypeName $scriptExtentType -ArgumentList $extentStartPos, $extentEndPos + } + + function Test-Extent { + param( + $translatedExtent, + $expectedStartLineNumber, + $expectedStartColumnNumber, + $expectedEndLineNumber, + $expectedEndColumnNumber) + + $translatedExtent.StartLineNumber | Should -Be $expectedStartLineNumber + $translatedExtent.StartColumnNumber | Should -Be $expectedStartColumnNumber + $translatedExtent.EndLineNumber | Should -Be $expectedEndLineNumber + $translatedExtent.EndColumnNumber | Should -Be $expectedEndColumnNumber + } -function Test-Extent { - param( - $translatedExtent, - $expectedStartLineNumber, - $expectedStartColumnNumber, - $expectedEndLineNumber, - $expectedEndColumnNumber) - - $translatedExtent.StartLineNumber | Should -Be $expectedStartLineNumber - $translatedExtent.StartColumnNumber | Should -Be $expectedStartColumnNumber - $translatedExtent.EndLineNumber | Should -Be $expectedEndLineNumber - $translatedExtent.EndColumnNumber | Should -Be $expectedEndColumnNumber + $extNamespace = [Microsoft.Windows.PowerShell.ScriptAnalyzer.Extensions.Extensions] } -$extNamespace = [Microsoft.Windows.PowerShell.ScriptAnalyzer.Extensions.Extensions] Describe "String extension methods" { Context "When a text is given to GetLines" { diff --git a/Tests/Engine/GetScriptAnalyzerRule.tests.ps1 b/Tests/Engine/GetScriptAnalyzerRule.tests.ps1 index 53ffe5e63..1dda8eb9a 100644 --- a/Tests/Engine/GetScriptAnalyzerRule.tests.ps1 +++ b/Tests/Engine/GetScriptAnalyzerRule.tests.ps1 @@ -1,14 +1,22 @@ -$testRootDirectory = Split-Path -Parent $PSScriptRoot -Import-Module (Join-Path $testRootDirectory 'PSScriptAnalyzerTestHelper.psm1') -$sa = Get-Command Get-ScriptAnalyzerRule - -$singularNouns = "PSUseSingularNouns" # this rule does not exist for coreclr version -$approvedVerbs = "PSUseApprovedVerbs" -$cmdletAliases = "PSAvoidUsingCmdletAliases" -$dscIdentical = "PSDSCUseIdenticalParametersForDSC" +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +BeforeAll { + $testRootDirectory = Split-Path -Parent $PSScriptRoot + Import-Module (Join-Path $testRootDirectory 'PSScriptAnalyzerTestHelper.psm1') + $sa = Get-Command Get-ScriptAnalyzerRule + + $singularNouns = "PSUseSingularNouns" # this rule does not exist for coreclr version + $approvedVerbs = "PSUseApprovedVerbs" + $cmdletAliases = "PSAvoidUsingCmdletAliases" + $dscIdentical = "PSDSCUseIdenticalParametersForDSC" +} Describe "Test available parameters" { - $params = $sa.Parameters + BeforeAll { + $params = $sa.Parameters + } + Context "Name parameter" { It "has a RuleName parameter" { $params.ContainsKey("Name") | Should -BeTrue @@ -32,7 +40,6 @@ Describe "Test available parameters" { $params.CustomRulePath.Aliases.Contains("CustomizedRulePath") | Should -BeTrue } } - } Describe "Test Name parameters" { @@ -94,15 +101,16 @@ Describe "Test Name parameters" { } Describe "Test RuleExtension" { - $community = "CommunityAnalyzerRules" - $measureRequired = "Measure-RequiresModules" Context "When used correctly" { - - $expectedNumCommunityRules = 10 - if ($PSVersionTable.PSVersion -ge [Version]'4.0.0') - { - $expectedNumCommunityRules = 12 - } + BeforeAll { + $community = "CommunityAnalyzerRules" + $measureRequired = "Measure-RequiresModules" + $expectedNumCommunityRules = 10 + if ($PSVersionTable.PSVersion -ge [Version]'4.0.0') + { + $expectedNumCommunityRules = 12 + } + } It "with the module folder path" { $ruleExtension = Get-ScriptAnalyzerRule -CustomizedRulePath $PSScriptRoot\CommunityAnalyzerRules | Where-Object {$_.SourceName -eq $community} $ruleExtension.Count | Should -Be $expectedNumCommunityRules diff --git a/Tests/Engine/GlobalSuppression.test.ps1 b/Tests/Engine/GlobalSuppression.test.ps1 index 76da8fc36..02f50ad65 100644 --- a/Tests/Engine/GlobalSuppression.test.ps1 +++ b/Tests/Engine/GlobalSuppression.test.ps1 @@ -1,15 +1,20 @@ -# Check if PSScriptAnalyzer is already loaded so we don't -# overwrite a test version of Invoke-ScriptAnalyzer by -# accident -if (!(Get-Module PSScriptAnalyzer) -and !$testingLibraryUsage) -{ - Import-Module -Verbose PSScriptAnalyzer -} +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +BeforeAll { + # Check if PSScriptAnalyzer is already loaded so we don't + # overwrite a test version of Invoke-ScriptAnalyzer by + # accident + if (!(Get-Module PSScriptAnalyzer) -and !$testingLibraryUsage) + { + Import-Module -Verbose PSScriptAnalyzer + } -$violations = Invoke-ScriptAnalyzer "$PSScriptRoot\GlobalSuppression.ps1" -$violationsUsingScriptDefinition = Invoke-ScriptAnalyzer -ScriptDefinition (Get-Content -Raw "$PSScriptRoot\GlobalSuppression.ps1") -$suppression = Invoke-ScriptAnalyzer "$PSScriptRoot\GlobalSuppression.ps1" -Profile "$PSScriptRoot\Profile.ps1" -$suppressionUsingScriptDefinition = Invoke-ScriptAnalyzer -ScriptDefinition (Get-Content -Raw "$PSScriptRoot\GlobalSuppression.ps1") -Profile "$PSScriptRoot\Profile.ps1" + $violations = Invoke-ScriptAnalyzer "$PSScriptRoot\GlobalSuppression.ps1" + $violationsUsingScriptDefinition = Invoke-ScriptAnalyzer -ScriptDefinition (Get-Content -Raw "$PSScriptRoot\GlobalSuppression.ps1") + $suppression = Invoke-ScriptAnalyzer "$PSScriptRoot\GlobalSuppression.ps1" -Profile "$PSScriptRoot\Profile.ps1" + $suppressionUsingScriptDefinition = Invoke-ScriptAnalyzer -ScriptDefinition (Get-Content -Raw "$PSScriptRoot\GlobalSuppression.ps1") -Profile "$PSScriptRoot\Profile.ps1" +} Describe "GlobalSuppression" { Context "Exclude Rule" { diff --git a/Tests/Engine/Helper.tests.ps1 b/Tests/Engine/Helper.tests.ps1 index 90706c8ca..f5a86ecbc 100644 --- a/Tests/Engine/Helper.tests.ps1 +++ b/Tests/Engine/Helper.tests.ps1 @@ -1,3 +1,6 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + Describe "Test Directed Graph" { Context "When a graph is created" { $digraph = New-Object -TypeName 'Microsoft.Windows.PowerShell.ScriptAnalyzer.DiGraph[string]' diff --git a/Tests/Engine/InvokeFormatter.tests.ps1 b/Tests/Engine/InvokeFormatter.tests.ps1 index 39f248865..7fc0703fc 100644 --- a/Tests/Engine/InvokeFormatter.tests.ps1 +++ b/Tests/Engine/InvokeFormatter.tests.ps1 @@ -1,5 +1,10 @@ -$testRootDirectory = Split-Path -Parent $PSScriptRoot -Import-Module (Join-Path $testRootDirectory "PSScriptAnalyzerTestHelper.psm1") +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +BeforeAll { + $testRootDirectory = Split-Path -Parent $PSScriptRoot + Import-Module (Join-Path $testRootDirectory "PSScriptAnalyzerTestHelper.psm1") +} Describe "Invoke-Formatter Cmdlet" { Context "Cmdlet cleans up and has no knock on effect" { diff --git a/Tests/Engine/InvokeScriptAnalyzer.tests.ps1 b/Tests/Engine/InvokeScriptAnalyzer.tests.ps1 index 15cae10e5..434ed55db 100644 --- a/Tests/Engine/InvokeScriptAnalyzer.tests.ps1 +++ b/Tests/Engine/InvokeScriptAnalyzer.tests.ps1 @@ -1,9 +1,14 @@ -$sa = Get-Command Invoke-ScriptAnalyzer -$singularNouns = "PSUseSingularNouns" -$approvedVerb = "PSUseApprovedVerbs" -$rules = Get-ScriptAnalyzerRule -Name ($singularNouns, "PSUseApprovedVerbs") -$avoidRules = Get-ScriptAnalyzerRule -Name "PSAvoid*" -$useRules = "PSUse*" +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +BeforeAll { + $sa = Get-Command Invoke-ScriptAnalyzer + $singularNouns = "PSUseSingularNouns" + $approvedVerb = "PSUseApprovedVerbs" + $rules = Get-ScriptAnalyzerRule -Name ($singularNouns, "PSUseApprovedVerbs") + $avoidRules = Get-ScriptAnalyzerRule -Name "PSAvoid*" + $useRules = "PSUse*" +} Describe "Test available parameters" { $params = $sa.Parameters diff --git a/Tests/Engine/LibraryUsage.tests.ps1 b/Tests/Engine/LibraryUsage.tests.ps1 index f479f468c..b7078aa12 100644 --- a/Tests/Engine/LibraryUsage.tests.ps1 +++ b/Tests/Engine/LibraryUsage.tests.ps1 @@ -1,212 +1,223 @@ -$testRootDirectory = Split-Path -Parent $PSScriptRoot -Import-Module (Join-Path $testRootDirectory 'PSScriptAnalyzerTestHelper.psm1') +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. -# test is meant to verify functionality if csharp apis are used. Hence not if psedition is CoreCLR -if (([bool] $IsCoreCLR)) -{ - return -} - - -# Overwrite Invoke-ScriptAnalyzer with a version that -# wraps the usage of ScriptAnalyzer as a .NET library -function Invoke-ScriptAnalyzer { - param ( - [CmdletBinding(DefaultParameterSetName="File", SupportsShouldProcess = $true)] - - [parameter(Mandatory = $true, Position = 0, ParameterSetName="File")] - [Alias("PSPath")] - [string] $Path, - - [parameter(Mandatory = $true, ParameterSetName="ScriptDefinition")] - [string] $ScriptDefinition, - - [Parameter(Mandatory = $false)] - [Alias("CustomizedRulePath")] - [string[]] $CustomRulePath = $null, - - [Parameter(Mandatory = $false)] - [switch] $RecurseCustomRulePath, - - [Parameter(Mandatory=$false)] - [string[]] $ExcludeRule = $null, - - [Parameter(Mandatory = $false)] - [string[]] $IncludeRule = $null, - - [ValidateSet("Warning", "Error", "Information", "ParseError", IgnoreCase = $true)] - [Parameter(Mandatory = $false)] - [string[]] $Severity = $null, - - [Parameter(Mandatory = $false)] - [switch] $Recurse, - - [Parameter(Mandatory = $false)] - [switch] $IncludeDefaultRules, - - [Parameter(Mandatory = $false)] - [switch] $SuppressedOnly, - - [Parameter(Mandatory = $false)] - [switch] $Fix, - - [Parameter(Mandatory = $false)] - [switch] $EnableExit, - - [Parameter(Mandatory = $false)] - [switch] $ReportSummary - ) - - if ($null -eq $CustomRulePath) - { - $IncludeDefaultRules = $true - } - # There is an inconsistency between this implementation and c# implementation of the cmdlet. - # The CustomRulePath parameter here is of "string[]" type whereas in the c# implementation it is of "string" type. - # If we set the CustomRulePath parameter here to "string[]", then the library usage test fails when run as an administrator. - # We want to note that the library usage test doesn't fail when run as a non-admin user. - # The following is the error statement when the test runs as an administrator. - # Assert failed on "Initialize" with "7" argument(s): "Test failed due to terminating error: The module was expected to contain an assembly manifest. (Exception from HRESULT: 0x80131018)" - - $scriptAnalyzer = New-Object "Microsoft.Windows.PowerShell.ScriptAnalyzer.ScriptAnalyzer"; - $scriptAnalyzer.Initialize( - $runspace, - $testOutputWriter, - $CustomRulePath, - $IncludeRule, - $ExcludeRule, - $Severity, - $IncludeDefaultRules.IsPresent, - $SuppressedOnly.IsPresent - ); - - if ($PSCmdlet.ParameterSetName -eq "File") - { - $supportsShouldProcessFunc = [Func[string, string, bool]] { return $PSCmdlet.Shouldprocess } - if ($Fix.IsPresent) - { - $results = $scriptAnalyzer.AnalyzeAndFixPath($Path, $supportsShouldProcessFunc, $Recurse.IsPresent); - } - else - { - $results = $scriptAnalyzer.AnalyzePath($Path, $supportsShouldProcessFunc, $Recurse.IsPresent); - } - } - else - { - $results = $scriptAnalyzer.AnalyzeScriptDefinition($ScriptDefinition); - } - - $results - - if ($ReportSummary.IsPresent) - { - if ($null -ne $results) - { - # This is not the exact message that it would print but close enough - Write-Host "$($results.Count) rule violations found. Severity distribution: Error = 1, Warning = 3, Information = 5" -ForegroundColor Red - } - else - { - Write-Host '0 rule violations found.' -ForegroundColor Green - } - } - - if ($EnableExit.IsPresent -and $null -ne $results) - { - exit $results.Count - } -} +BeforeAll { + $testRootDirectory = Split-Path -Parent $PSScriptRoot + Import-Module (Join-Path $testRootDirectory 'PSScriptAnalyzerTestHelper.psm1') -# Define an implementation of the IOutputWriter interface -Add-Type -Language CSharp @" -using System.Management.Automation; -using System.Management.Automation.Host; -using Microsoft.Windows.PowerShell.ScriptAnalyzer; - -public class PesterTestOutputWriter : IOutputWriter -{ - private PSHost psHost; - - public string MostRecentWarningMessage { get; private set; } - - public static PesterTestOutputWriter Create(PSHost psHost) + # test is meant to verify functionality if csharp apis are used. Hence not if psedition is CoreCLR + if (([bool] $IsCoreCLR)) { - PesterTestOutputWriter testOutputWriter = new PesterTestOutputWriter(); - testOutputWriter.psHost = psHost; - return testOutputWriter; + return } - public void WriteError(ErrorRecord error) - { - // We don't write errors to avoid misleading - // error messages in test output + # Overwrite Invoke-ScriptAnalyzer with a version that + # wraps the usage of ScriptAnalyzer as a .NET library + function Invoke-ScriptAnalyzer { + param ( + [CmdletBinding(DefaultParameterSetName="File", SupportsShouldProcess = $true)] + + [parameter(Mandatory = $true, Position = 0, ParameterSetName="File")] + [Alias("PSPath")] + [string] $Path, + + [parameter(Mandatory = $true, ParameterSetName="ScriptDefinition")] + [string] $ScriptDefinition, + + [Parameter(Mandatory = $false)] + [Alias("CustomizedRulePath")] + [string[]] $CustomRulePath = $null, + + [Parameter(Mandatory = $false)] + [switch] $RecurseCustomRulePath, + + [Parameter(Mandatory=$false)] + [string[]] $ExcludeRule = $null, + + [Parameter(Mandatory = $false)] + [string[]] $IncludeRule = $null, + + [ValidateSet("Warning", "Error", "Information", "ParseError", IgnoreCase = $true)] + [Parameter(Mandatory = $false)] + [string[]] $Severity = $null, + + [Parameter(Mandatory = $false)] + [switch] $Recurse, + + [Parameter(Mandatory = $false)] + [switch] $IncludeDefaultRules, + + [Parameter(Mandatory = $false)] + [switch] $SuppressedOnly, + + [Parameter(Mandatory = $false)] + [switch] $Fix, + + [Parameter(Mandatory = $false)] + [switch] $EnableExit, + + [Parameter(Mandatory = $false)] + [switch] $ReportSummary + ) + + if ($null -eq $CustomRulePath) + { + $IncludeDefaultRules = $true + } + # There is an inconsistency between this implementation and c# implementation of the cmdlet. + # The CustomRulePath parameter here is of "string[]" type whereas in the c# implementation it is of "string" type. + # If we set the CustomRulePath parameter here to "string[]", then the library usage test fails when run as an administrator. + # We want to note that the library usage test doesn't fail when run as a non-admin user. + # The following is the error statement when the test runs as an administrator. + # Assert failed on "Initialize" with "7" argument(s): "Test failed due to terminating error: The module was expected to contain an assembly manifest. (Exception from HRESULT: 0x80131018)" + + $scriptAnalyzer = New-Object "Microsoft.Windows.PowerShell.ScriptAnalyzer.ScriptAnalyzer"; + $scriptAnalyzer.Initialize( + $runspace, + $testOutputWriter, + $CustomRulePath, + $IncludeRule, + $ExcludeRule, + $Severity, + $IncludeDefaultRules.IsPresent, + $SuppressedOnly.IsPresent + ); + + if ($PSCmdlet.ParameterSetName -eq "File") + { + $supportsShouldProcessFunc = [Func[string, string, bool]] { return $PSCmdlet.Shouldprocess } + if ($Fix.IsPresent) + { + $results = $scriptAnalyzer.AnalyzeAndFixPath($Path, $supportsShouldProcessFunc, $Recurse.IsPresent); + } + else + { + $results = $scriptAnalyzer.AnalyzePath($Path, $supportsShouldProcessFunc, $Recurse.IsPresent); + } + } + else + { + $results = $scriptAnalyzer.AnalyzeScriptDefinition($ScriptDefinition); + } + + $results + + if ($ReportSummary.IsPresent) + { + if ($null -ne $results) + { + # This is not the exact message that it would print but close enough + Write-Host "$($results.Count) rule violations found. Severity distribution: Error = 1, Warning = 3, Information = 5" -ForegroundColor Red + } + else + { + Write-Host '0 rule violations found.' -ForegroundColor Green + } + } + + if ($EnableExit.IsPresent -and $null -ne $results) + { + exit $results.Count + } } - public void WriteWarning(string message) - { - psHost.UI.WriteWarningLine(message); + # Define an implementation of the IOutputWriter interface + Add-Type -Language CSharp @" + using System.Management.Automation; + using System.Management.Automation.Host; + using Microsoft.Windows.PowerShell.ScriptAnalyzer; - this.MostRecentWarningMessage = message; - } - - public void WriteVerbose(string message) + public class PesterTestOutputWriter : IOutputWriter { - // We don't write verbose output to avoid lots - // of unnecessary messages in test output + private PSHost psHost; + + public string MostRecentWarningMessage { get; private set; } + + public static PesterTestOutputWriter Create(PSHost psHost) + { + PesterTestOutputWriter testOutputWriter = new PesterTestOutputWriter(); + testOutputWriter.psHost = psHost; + return testOutputWriter; + } + + public void WriteError(ErrorRecord error) + { + // We don't write errors to avoid misleading + // error messages in test output + } + + public void WriteWarning(string message) + { + psHost.UI.WriteWarningLine(message); + + this.MostRecentWarningMessage = message; + } + + public void WriteVerbose(string message) + { + // We don't write verbose output to avoid lots + // of unnecessary messages in test output + } + + public void WriteDebug(string message) + { + psHost.UI.WriteDebugLine(message); + } + + public void ThrowTerminatingError(ErrorRecord record) + { + throw new RuntimeException( + "Test failed due to terminating error: \r\n" + record.ToString(), + null, + record); + } } +"@ -ReferencedAssemblies "Microsoft.Windows.PowerShell.ScriptAnalyzer" -ErrorAction SilentlyContinue - public void WriteDebug(string message) + if ($testOutputWriter -eq $null) { - psHost.UI.WriteDebugLine(message); + $testOutputWriter = [PesterTestOutputWriter]::Create($Host); } - public void ThrowTerminatingError(ErrorRecord record) - { - throw new RuntimeException( - "Test failed due to terminating error: \r\n" + record.ToString(), - null, - record); + # Create a fresh runspace to pass into the ScriptAnalyzer class + $initialSessionState = [System.Management.Automation.Runspaces.InitialSessionState]::CreateDefault2(); + $runspace = [System.Management.Automation.Runspaces.RunspaceFactory]::CreateRunspace([System.Management.Automation.Host.PSHost]$Host, [System.Management.Automation.Runspaces.InitialSessionState]$initialSessionState); + $runspace.Open(); + + # Let other test scripts know we are testing library usage now + $testingLibraryUsage = $true + + # Force Get-Help not to prompt for interactive input to download help using Update-Help + # By adding this registry key we force to turn off Get-Help interactivity logic during ScriptRule parsing + $null,"Wow6432Node" | ForEach-Object { + try + { + Set-ItemProperty -Name "DisablePromptToUpdateHelp" -Path "HKLM:\SOFTWARE\$($_)\Microsoft\PowerShell" -Value 1 -Force -ErrorAction SilentlyContinue + } + catch + { + # Ignore for cases when tests are running in non-elevated more or registry key does not exist or not accessible + } } } -"@ -ReferencedAssemblies "Microsoft.Windows.PowerShell.ScriptAnalyzer" -ErrorAction SilentlyContinue - -if ($testOutputWriter -eq $null) -{ - $testOutputWriter = [PesterTestOutputWriter]::Create($Host); -} -# Create a fresh runspace to pass into the ScriptAnalyzer class -$initialSessionState = [System.Management.Automation.Runspaces.InitialSessionState]::CreateDefault2(); -$runspace = [System.Management.Automation.Runspaces.RunspaceFactory]::CreateRunspace([System.Management.Automation.Host.PSHost]$Host, [System.Management.Automation.Runspaces.InitialSessionState]$initialSessionState); -$runspace.Open(); -# Let other test scripts know we are testing library usage now -$testingLibraryUsage = $true - -# Force Get-Help not to prompt for interactive input to download help using Update-Help -# By adding this registry key we force to turn off Get-Help interactivity logic during ScriptRule parsing -$null,"Wow6432Node" | ForEach-Object { - try - { - Set-ItemProperty -Name "DisablePromptToUpdateHelp" -Path "HKLM:\SOFTWARE\$($_)\Microsoft\PowerShell" -Value 1 -Force -ErrorAction SilentlyContinue - } - catch - { - # Ignore for cases when tests are running in non-elevated more or registry key does not exist or not accessible +Describe 'LibraryUsage' { + It 'Invoke-ScriptAnalyzer stub' { + . $PSScriptRoot\InvokeScriptAnalyzer.tests.ps1 + . $PSScriptRoot\RuleSuppression.tests.ps1 + . $PSScriptRoot\CustomizedRule.tests.ps1 } } -# Invoke existing test files that use Invoke-ScriptAnalyzer -. $PSScriptRoot\InvokeScriptAnalyzer.tests.ps1 -. $PSScriptRoot\RuleSuppression.tests.ps1 -. $PSScriptRoot\CustomizedRule.tests.ps1 -# We're done testing library usage -$testingLibraryUsage = $false +AfterAll { + # We're done testing library usage + $testingLibraryUsage = $false -# Clean up the test runspace -$runspace.Dispose(); + # Clean up the test runspace + $runspace.Dispose(); -# Re-import the PSScriptAnalyzer module to overwrite the library test cmdlet -Import-Module PSScriptAnalyzer + # Re-import the PSScriptAnalyzer module to overwrite the library test cmdlet + Import-Module PSScriptAnalyzer +} diff --git a/Tests/Engine/ModuleDependencyHandler.tests.ps1 b/Tests/Engine/ModuleDependencyHandler.tests.ps1 index 22045644e..f56c9820b 100644 --- a/Tests/Engine/ModuleDependencyHandler.tests.ps1 +++ b/Tests/Engine/ModuleDependencyHandler.tests.ps1 @@ -1,3 +1,6 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + Describe "Resolve DSC Resource Dependency" { BeforeAll { $skipTest = $false # Test that require DSC to be installed diff --git a/Tests/Engine/ModuleHelp.Tests.ps1 b/Tests/Engine/ModuleHelp.Tests.ps1 index c84b19cb4..fe6d0e630 100644 --- a/Tests/Engine/ModuleHelp.Tests.ps1 +++ b/Tests/Engine/ModuleHelp.Tests.ps1 @@ -1,3 +1,6 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + <# .SYNOPSIS Tests the PowerShell help for the commands in a module. diff --git a/Tests/Engine/RuleSuppression.tests.ps1 b/Tests/Engine/RuleSuppression.tests.ps1 index 5aeff14e9..7184fb544 100644 --- a/Tests/Engine/RuleSuppression.tests.ps1 +++ b/Tests/Engine/RuleSuppression.tests.ps1 @@ -1,43 +1,49 @@ -$testRootDirectory = Split-Path -Parent $PSScriptRoot -Import-Module (Join-Path $testRootDirectory 'PSScriptAnalyzerTestHelper.psm1') +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. -$violationsUsingScriptDefinition = Invoke-ScriptAnalyzer -ScriptDefinition (Get-Content -Raw "$PSScriptRoot\RuleSuppression.ps1") -$violations = Invoke-ScriptAnalyzer "$PSScriptRoot\RuleSuppression.ps1" +BeforeAll { + $testRootDirectory = Split-Path -Parent $PSScriptRoot + Import-Module (Join-Path $testRootDirectory 'PSScriptAnalyzerTestHelper.psm1') -$ruleSuppressionBad = @' -Function do-something -{ - [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingUserNameAndPassWordParams", "username")] - Param( - $username, - $password - ) -} -'@ + $violationsUsingScriptDefinition = Invoke-ScriptAnalyzer -ScriptDefinition (Get-Content -Raw "$PSScriptRoot\RuleSuppression.ps1") + $violations = Invoke-ScriptAnalyzer "$PSScriptRoot\RuleSuppression.ps1" -$ruleSuppressionInConfiguration = @' -Configuration xFileUpload -{ -[Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingConvertToSecureStringWithPlainText", "")] -param ([string] $decryptedPassword) -$securePassword = ConvertTo-SecureString $decryptedPassword -AsPlainText -Force -} -'@ + $ruleSuppressionBad = @' + Function do-something + { + [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingUserNameAndPassWordParams", "username")] + Param( + $username, + $password + ) + } + '@ -# If function doesn't starts at offset 0, then the test case fails before commit b551211 -$ruleSuppressionAvoidUsernameAndPassword = @' + $ruleSuppressionInConfiguration = @' + Configuration xFileUpload + { + [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingConvertToSecureStringWithPlainText", "")] + param ([string] $decryptedPassword) + $securePassword = ConvertTo-SecureString $decryptedPassword -AsPlainText -Force + } + '@ -function SuppressUserAndPwdRule() -{ - [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingUserNameAndPassWordParams", "")] - [CmdletBinding()] - param - ( - [System.String] $username, - [System.String] $password - ) -} + # If function doesn't starts at offset 0, then the test case fails before commit b551211 + $ruleSuppressionAvoidUsernameAndPassword = @' + + function SuppressUserAndPwdRule() + { + [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingUserNameAndPassWordParams", "")] + [CmdletBinding()] + param + ( + [System.String] $username, + [System.String] $password + ) + } '@ +} + Describe "RuleSuppressionWithoutScope" { Context "Function" { diff --git a/Tests/Engine/RuleSuppressionClass.tests.ps1 b/Tests/Engine/RuleSuppressionClass.tests.ps1 index 22e5fcd20..28c3aad22 100644 --- a/Tests/Engine/RuleSuppressionClass.tests.ps1 +++ b/Tests/Engine/RuleSuppressionClass.tests.ps1 @@ -1,10 +1,15 @@ -$script:skipForV3V4 = $true -if ($PSVersionTable.PSVersion -ge [Version]'5.0.0') { - $script:skipForV3V4 = $false -} +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +BeforeAll { + $script:skipForV3V4 = $true + if ($PSVersionTable.PSVersion -ge [Version]'5.0.0') { + $script:skipForV3V4 = $false + } -$violationsUsingScriptDefinition = Invoke-ScriptAnalyzer -ScriptDefinition (Get-Content -Raw "$PSScriptRoot\RuleSuppression.ps1") -$violations = Invoke-ScriptAnalyzer "$PSScriptRoot\RuleSuppression.ps1" + $violationsUsingScriptDefinition = Invoke-ScriptAnalyzer -ScriptDefinition (Get-Content -Raw "$PSScriptRoot\RuleSuppression.ps1") + $violations = Invoke-ScriptAnalyzer "$PSScriptRoot\RuleSuppression.ps1" +} Describe "RuleSuppressionWithoutScope" { From b25714dc434bfb19f83d64bb138473e5654e6fea Mon Sep 17 00:00:00 2001 From: Christoph Bergmeister Date: Sun, 12 Apr 2020 23:05:56 +0100 Subject: [PATCH 05/76] use pester v5 in ci and always upload test results --- .azure-pipelines-ci/templates/test.yaml | 2 +- tools/appveyor.psm1 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.azure-pipelines-ci/templates/test.yaml b/.azure-pipelines-ci/templates/test.yaml index 2acdcc6f5..0012119bd 100644 --- a/.azure-pipelines-ci/templates/test.yaml +++ b/.azure-pipelines-ci/templates/test.yaml @@ -21,4 +21,4 @@ steps: inputs: testRunner: NUnit testResultsFiles: 'TestResults.xml' - condition: succeededOrFailed() \ No newline at end of file + condition: always() \ No newline at end of file diff --git a/tools/appveyor.psm1 b/tools/appveyor.psm1 index ffbcc415f..36e2e2578 100644 --- a/tools/appveyor.psm1 +++ b/tools/appveyor.psm1 @@ -4,7 +4,7 @@ $ErrorActionPreference = 'Stop' function Install-Pester { - $requiredPesterVersion = '4.10.0' + $requiredPesterVersion = '5.0.0' $pester = Get-Module Pester -ListAvailable | Where-Object { $_.Version -eq $requiredPesterVersion } if ($null -eq $pester) { if ($null -eq (Get-Module -ListAvailable PowershellGet)) { From a49823690c02c398211ad03c9963bcc99a948e6c Mon Sep 17 00:00:00 2001 From: Christoph Bergmeister Date: Sun, 12 Apr 2020 23:35:42 +0100 Subject: [PATCH 06/76] Upgrade Rule tests to Pester v5 using BeforeAll block and addressing some -Skip problems already --- .../Rules/AlignAssignmentStatement.tests.ps1 | 24 +- Tests/Rules/AllCompatibilityRules.Tests.ps1 | 136 ++--- ...oidAssignmentToAutomaticVariable.tests.ps1 | 7 +- ...nvertToSecureStringWithPlainText.tests.ps1 | 15 +- ...dDefaultTrueValueSwitchParameter.tests.ps1 | 13 +- ...efaultValueForMandatoryParameter.tests.ps1 | 7 +- Tests/Rules/AvoidEmptyCatchBlock.tests.ps1 | 13 +- Tests/Rules/AvoidGlobalAliases.tests.ps1 | 19 +- Tests/Rules/AvoidGlobalFunctions.tests.ps1 | 12 +- Tests/Rules/AvoidGlobalVars.tests.ps1 | 19 +- .../Rules/AvoidInvokingEmptyMembers.tests.ps1 | 13 +- Tests/Rules/AvoidLongLines.tests.ps1 | 19 +- ...dNullOrEmptyHelpMessageAttribute.tests.ps1 | 13 +- .../AvoidOverwritingBuiltInCmdlets.tests.ps1 | 45 +- .../Rules/AvoidPositionalParameters.tests.ps1 | 15 +- Tests/Rules/AvoidReservedParams.tests.ps1 | 13 +- .../AvoidShouldContinueWithoutForce.tests.ps1 | 13 +- Tests/Rules/AvoidTrailingWhitespace.tests.ps1 | 15 +- ...OrMissingRequiredFieldInManifest.tests.ps1 | 23 +- .../AvoidUserNameAndPasswordParams.tests.ps1 | 14 +- Tests/Rules/AvoidUsingAlias.tests.ps1 | 20 +- .../AvoidUsingComputerNameHardcoded.tests.ps1 | 13 +- ...oidUsingDeprecatedManifestFields.tests.ps1 | 13 +- .../AvoidUsingInvokeExpression.tests.ps1 | 13 +- .../AvoidUsingPlainTextForPassword.tests.ps1 | 17 +- .../AvoidUsingReservedCharNames.tests.ps1 | 13 +- Tests/Rules/AvoidUsingWMICmdlet.tests.ps1 | 13 +- Tests/Rules/AvoidUsingWriteHost.tests.ps1 | 15 +- Tests/Rules/DscExamplesPresent.tests.ps1 | 33 +- Tests/Rules/DscTestsPresent.tests.ps1 | 46 +- Tests/Rules/MisleadingBacktick.tests.ps1 | 15 +- Tests/Rules/PSCredentialType.tests.ps1 | 17 +- ...sibleIncorrectComparisonWithNull.tests.ps1 | 13 +- ...correctUsageOfAssignmentOperator.tests.ps1 | 7 +- ...orrectUsageOfRedirectionOperator.tests.ps1 | 9 +- Tests/Rules/ProvideCommentHelp.tests.ps1 | 81 +-- ...eturnCorrectTypesForDSCFunctions.tests.ps1 | 29 +- Tests/Rules/ReviewUnusedParameter.tests.ps1 | 3 + .../UseBOMForUnicodeEncodedFile.tests.ps1 | 19 +- Tests/Rules/UseCmdletCorrectly.tests.ps1 | 14 +- Tests/Rules/UseCompatibleCmdlets.tests.ps1 | 12 +- Tests/Rules/UseCompatibleCommands.Tests.ps1 | 475 +++++++++--------- Tests/Rules/UseCompatibleSyntax.Tests.ps1 | 4 +- Tests/Rules/UseCompatibleTypes.Tests.ps1 | 133 ++--- .../Rules/UseConsistentIndentation.tests.ps1 | 8 +- Tests/Rules/UseConsistentWhitespace.tests.ps1 | 42 +- Tests/Rules/UseCorrectCasing.tests.ps1 | 3 + Tests/Rules/UseDSCResourceFunctions.tests.ps1 | 31 +- ...eDeclaredVarsMoreThanAssignments.tests.ps1 | 17 +- ...enticalMandatoryParametersForDSC.tests.ps1 | 20 +- .../Rules/UseIdenticalParametersDSC.tests.ps1 | 22 +- ...seLiteralInitializerForHashtable.tests.ps1 | 7 +- Tests/Rules/UseOutputTypeCorrectly.tests.ps1 | 18 +- ...seProcessBlockForPipelineCommand.tests.ps1 | 5 +- .../Rules/UseShouldProcessCorrectly.tests.ps1 | 19 +- ...ProcessForStateChangingFunctions.tests.ps1 | 13 +- .../UseSingularNounsReservedVerbs.tests.ps1 | 76 +-- .../Rules/UseSupportsShouldProcess.tests.ps1 | 19 +- .../UseToExportFieldsInManifest.tests.ps1 | 56 ++- .../UseUTF8EncodingForHelpFile.tests.ps1 | 5 +- ...UsingScopeModifierInNewRunspaces.tests.ps1 | 11 +- .../UseVerboseMessageInDSCResource.Tests.ps1 | 15 +- 62 files changed, 1071 insertions(+), 791 deletions(-) diff --git a/Tests/Rules/AlignAssignmentStatement.tests.ps1 b/Tests/Rules/AlignAssignmentStatement.tests.ps1 index 1f3dbad0f..9a94f48ce 100644 --- a/Tests/Rules/AlignAssignmentStatement.tests.ps1 +++ b/Tests/Rules/AlignAssignmentStatement.tests.ps1 @@ -1,16 +1,20 @@ -$testRootDirectory = Split-Path -Parent $PSScriptRoot +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. -Import-Module (Join-Path $testRootDirectory "PSScriptAnalyzerTestHelper.psm1") +BeforeAll { + $testRootDirectory = Split-Path -Parent $PSScriptRoot + Import-Module (Join-Path $testRootDirectory "PSScriptAnalyzerTestHelper.psm1") -$ruleConfiguration = @{ - Enable = $true - CheckHashtable = $true -} + $ruleConfiguration = @{ + Enable = $true + CheckHashtable = $true + } -$settings = @{ - IncludeRules = @("PSAlignAssignmentStatement") - Rules = @{ - PSAlignAssignmentStatement = $ruleConfiguration + $settings = @{ + IncludeRules = @("PSAlignAssignmentStatement") + Rules = @{ + PSAlignAssignmentStatement = $ruleConfiguration + } } } diff --git a/Tests/Rules/AllCompatibilityRules.Tests.ps1 b/Tests/Rules/AllCompatibilityRules.Tests.ps1 index 23864cbb5..46d487db0 100644 --- a/Tests/Rules/AllCompatibilityRules.Tests.ps1 +++ b/Tests/Rules/AllCompatibilityRules.Tests.ps1 @@ -1,89 +1,91 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. -$script:fileContent = @' -$assetDir = 'C:\ImportantFiles\' -$archiveDir = 'C:\Archived\' +BeforeAll { + $script:fileContent = @' + $assetDir = 'C:\ImportantFiles\' + $archiveDir = 'C:\Archived\' -$runningOnWindows = -not ($IsLinux -or $IsMacOS) -$zipCompressionLevel = 'Optimal' -$includeBaseDirInZips = $true + $runningOnWindows = -not ($IsLinux -or $IsMacOS) + $zipCompressionLevel = 'Optimal' + $includeBaseDirInZips = $true -if (-not (Test-Path $archiveDir)) -{ - New-Item -Type Directory $archiveDir -} - -Import-Module -FullyQualifiedName @{ ModuleName = 'MyArchiveUtilities'; ModuleVersion = '2.0' } - -$sigs = [System.Collections.Generic.List[System.Management.Automation.Signature]]::new() -$filePattern = [System.Management.Automation.WildcardPattern]::Get('system*') -foreach ($file in Get-ChildItem $assetDir -Recurse -Depth 1) -{ - if (-not $filePattern.IsMatch($file.Name)) + if (-not (Test-Path $archiveDir)) { - continue + New-Item -Type Directory $archiveDir } - if ($file.Name -like '*.dll') - { - $sig = Get-AuthenticodeSignature $file - $sigs.Add($sig) - continue - } + Import-Module -FullyQualifiedName @{ ModuleName = 'MyArchiveUtilities'; ModuleVersion = '2.0' } - if (Test-WithFunctionFromMyModule -File $file) + $sigs = [System.Collections.Generic.List[System.Management.Automation.Signature]]::new() + $filePattern = [System.Management.Automation.WildcardPattern]::Get('system*') + foreach ($file in Get-ChildItem $assetDir -Recurse -Depth 1) { - $destZip = Join-Path $archiveDir $file.BaseName - [System.IO.Compression.ZipFile]::CreateFromDirectory($file.FullName, "$destZip.zip", $zipCompressionLevel, $includeBaseDirInZips) - } -} - -Write-Output $sigs -'@ + if (-not $filePattern.IsMatch($file.Name)) + { + continue + } -$script:settingsContent = @' -@{ - Rules = @{ - PSUseCompatibleCommands = @{ - Enable = $true - TargetProfiles = @( - 'win-8_x64_10.0.17763.0_5.1.17763.316_x64_4.0.30319.42000_framework' # Server 2019 - PS 5.1 (the platform it already runs on) - 'win-8_x64_6.2.9200.0_3.0_x64_4.0.30319.42000_framework' # Server 2012 - PS 3 - 'ubuntu_x64_18.04_7.0.0_x64_3.1.2_core' # Ubuntu 18.04 - PS 6.1 - ) + if ($file.Name -like '*.dll') + { + $sig = Get-AuthenticodeSignature $file + $sigs.Add($sig) + continue } - PSUseCompatibleTypes = @{ - Enable = $true - # Same as for command targets - TargetProfiles = @( - 'win-8_x64_10.0.17763.0_5.1.17763.316_x64_4.0.30319.42000_framework' - 'win-8_x64_6.2.9200.0_3.0_x64_4.0.30319.42000_framework' - 'ubuntu_x64_18.04_7.0.0_x64_3.1.2_core' - ) + + if (Test-WithFunctionFromMyModule -File $file) + { + $destZip = Join-Path $archiveDir $file.BaseName + [System.IO.Compression.ZipFile]::CreateFromDirectory($file.FullName, "$destZip.zip", $zipCompressionLevel, $includeBaseDirInZips) } - PSUseCompatibleSyntax = @{ - Enable = $true - TargetVersions = @('3.0', '5.1', '7.0') + } + + Write-Output $sigs + '@ + + $script:settingsContent = @' + @{ + Rules = @{ + PSUseCompatibleCommands = @{ + Enable = $true + TargetProfiles = @( + 'win-8_x64_10.0.17763.0_5.1.17763.316_x64_4.0.30319.42000_framework' # Server 2019 - PS 5.1 (the platform it already runs on) + 'win-8_x64_6.2.9200.0_3.0_x64_4.0.30319.42000_framework' # Server 2012 - PS 3 + 'ubuntu_x64_18.04_7.0.0_x64_3.1.2_core' # Ubuntu 18.04 - PS 6.1 + ) + } + PSUseCompatibleTypes = @{ + Enable = $true + # Same as for command targets + TargetProfiles = @( + 'win-8_x64_10.0.17763.0_5.1.17763.316_x64_4.0.30319.42000_framework' + 'win-8_x64_6.2.9200.0_3.0_x64_4.0.30319.42000_framework' + 'ubuntu_x64_18.04_7.0.0_x64_3.1.2_core' + ) + } + PSUseCompatibleSyntax = @{ + Enable = $true + TargetVersions = @('3.0', '5.1', '7.0') + } } } -} '@ -$script:expectedCommandDiagnostics = @( - @{ Command = 'Import-Module'; Parameter = 'FullyQualifiedName'; Line = 13 } - @{ Command = 'Get-ChildItem'; Parameter = 'Depth'; Line = 17 } - @{ Command = 'Get-AuthenticodeSignature'; Line = 26 } -) + $script:expectedCommandDiagnostics = @( + @{ Command = 'Import-Module'; Parameter = 'FullyQualifiedName'; Line = 13 } + @{ Command = 'Get-ChildItem'; Parameter = 'Depth'; Line = 17 } + @{ Command = 'Get-AuthenticodeSignature'; Line = 26 } + ) -$script:expectedTypeDiagnostics = @( - @{ Type = 'System.Management.Automation.WildcardPattern'; Member = 'Get'; Line = 16 } - @{ Type = 'System.IO.Compression.ZipFile'; Line = 34 } -) + $script:expectedTypeDiagnostics = @( + @{ Type = 'System.Management.Automation.WildcardPattern'; Member = 'Get'; Line = 16 } + @{ Type = 'System.IO.Compression.ZipFile'; Line = 34 } + ) -$script:expectedSyntaxDiagnostics = @( - @{ Line = 15; CorrectionText = "New-Object 'System.Collections.Generic.List[System.Management.Automation.Signature]'" } -) + $script:expectedSyntaxDiagnostics = @( + @{ Line = 15; CorrectionText = "New-Object 'System.Collections.Generic.List[System.Management.Automation.Signature]'" } + ) +} Describe "Running all compatibility rules with a settings file" { BeforeAll { diff --git a/Tests/Rules/AvoidAssignmentToAutomaticVariable.tests.ps1 b/Tests/Rules/AvoidAssignmentToAutomaticVariable.tests.ps1 index 127156064..50aea15cd 100644 --- a/Tests/Rules/AvoidAssignmentToAutomaticVariable.tests.ps1 +++ b/Tests/Rules/AvoidAssignmentToAutomaticVariable.tests.ps1 @@ -1,4 +1,9 @@ -$ruleName = "PSAvoidAssignmentToAutomaticVariable" +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +BeforeAll { + $ruleName = "PSAvoidAssignmentToAutomaticVariable" +} Describe "AvoidAssignmentToAutomaticVariables" { Context "ReadOnly Variables" { diff --git a/Tests/Rules/AvoidConvertToSecureStringWithPlainText.tests.ps1 b/Tests/Rules/AvoidConvertToSecureStringWithPlainText.tests.ps1 index 0e7f760cb..773d5f84f 100644 --- a/Tests/Rules/AvoidConvertToSecureStringWithPlainText.tests.ps1 +++ b/Tests/Rules/AvoidConvertToSecureStringWithPlainText.tests.ps1 @@ -1,8 +1,13 @@ -Set-Alias ctss ConvertTo-SecureString -$violationMessage = "File 'AvoidConvertToSecureStringWithPlainText.ps1' uses ConvertTo-SecureString with plaintext. This will expose secure information. Encrypted standard strings should be used instead." -$violationName = "PSAvoidUsingConvertToSecureStringWithPlainText" -$violations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidConvertToSecureStringWithPlainText.ps1 | Where-Object {$_.RuleName -eq $violationName} -$noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidConvertToSecureStringWithPlainTextNoViolations.ps1 | Where-Object {$_.RuleName -eq $violationName} +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +BeforeAll { + Set-Alias ctss ConvertTo-SecureString + $violationMessage = "File 'AvoidConvertToSecureStringWithPlainText.ps1' uses ConvertTo-SecureString with plaintext. This will expose secure information. Encrypted standard strings should be used instead." + $violationName = "PSAvoidUsingConvertToSecureStringWithPlainText" + $violations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidConvertToSecureStringWithPlainText.ps1 | Where-Object {$_.RuleName -eq $violationName} + $noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidConvertToSecureStringWithPlainTextNoViolations.ps1 | Where-Object {$_.RuleName -eq $violationName} +} Describe "AvoidConvertToSecureStringWithPlainText" { Context "When there are violations" { diff --git a/Tests/Rules/AvoidDefaultTrueValueSwitchParameter.tests.ps1 b/Tests/Rules/AvoidDefaultTrueValueSwitchParameter.tests.ps1 index 6714ace07..e28b23985 100644 --- a/Tests/Rules/AvoidDefaultTrueValueSwitchParameter.tests.ps1 +++ b/Tests/Rules/AvoidDefaultTrueValueSwitchParameter.tests.ps1 @@ -1,7 +1,12 @@ -$violationMessage = "File 'AvoidDefaultTrueValueSwitchParameter.ps1' has a switch parameter default to true." -$violationName = "PSAvoidDefaultValueSwitchParameter" -$violations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidDefaultTrueValueSwitchParameter.ps1 | Where-Object {$_.RuleName -eq $violationName} -$noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidDefaultTrueValueSwitchParameterNoViolations.ps1 | Where-Object {$_.RuleName -eq $violationName} +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +BeforeAll { + $violationMessage = "File 'AvoidDefaultTrueValueSwitchParameter.ps1' has a switch parameter default to true." + $violationName = "PSAvoidDefaultValueSwitchParameter" + $violations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidDefaultTrueValueSwitchParameter.ps1 | Where-Object {$_.RuleName -eq $violationName} + $noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidDefaultTrueValueSwitchParameterNoViolations.ps1 | Where-Object {$_.RuleName -eq $violationName} +} Describe "AvoidDefaultTrueValueSwitchParameter" { Context "When there are violations" { diff --git a/Tests/Rules/AvoidDefaultValueForMandatoryParameter.tests.ps1 b/Tests/Rules/AvoidDefaultValueForMandatoryParameter.tests.ps1 index c4fa2258d..a087a97f4 100644 --- a/Tests/Rules/AvoidDefaultValueForMandatoryParameter.tests.ps1 +++ b/Tests/Rules/AvoidDefaultValueForMandatoryParameter.tests.ps1 @@ -1,4 +1,9 @@ -$ruleName = 'PSAvoidDefaultValueForMandatoryParameter' +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +BeforeAll { + $ruleName = 'PSAvoidDefaultValueForMandatoryParameter' +} Describe "AvoidDefaultValueForMandatoryParameter" { Context "When there are violations" { diff --git a/Tests/Rules/AvoidEmptyCatchBlock.tests.ps1 b/Tests/Rules/AvoidEmptyCatchBlock.tests.ps1 index 636075099..8af3df7f5 100644 --- a/Tests/Rules/AvoidEmptyCatchBlock.tests.ps1 +++ b/Tests/Rules/AvoidEmptyCatchBlock.tests.ps1 @@ -1,7 +1,12 @@ -$violationMessage = "Empty catch block is used. Please use Write-Error or throw statements in catch blocks." -$violationName = "PSAvoidUsingEmptyCatchBlock" -$violations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidEmptyCatchBlock.ps1 | Where-Object {$_.RuleName -eq $violationName} -$noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidEmptyCatchBlockNoViolations.ps1 | Where-Object {$_.RuleName -eq $violationName} +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +BeforeAll { + $violationMessage = "Empty catch block is used. Please use Write-Error or throw statements in catch blocks." + $violationName = "PSAvoidUsingEmptyCatchBlock" + $violations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidEmptyCatchBlock.ps1 | Where-Object {$_.RuleName -eq $violationName} + $noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidEmptyCatchBlockNoViolations.ps1 | Where-Object {$_.RuleName -eq $violationName} +} Describe "UseDeclaredVarsMoreThanAssignments" { Context "When there are violations" { diff --git a/Tests/Rules/AvoidGlobalAliases.tests.ps1 b/Tests/Rules/AvoidGlobalAliases.tests.ps1 index 1b8716236..ff1f5d31e 100644 --- a/Tests/Rules/AvoidGlobalAliases.tests.ps1 +++ b/Tests/Rules/AvoidGlobalAliases.tests.ps1 @@ -1,11 +1,16 @@ -$testRootDirectory = Split-Path -Parent $PSScriptRoot -Import-Module (Join-Path $testRootDirectory 'PSScriptAnalyzerTestHelper.psm1') +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. -$AvoidGlobalAliasesError = "Avoid creating aliases with a Global scope." -$violationName = "PSAvoidGlobalAliases" -$violations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidGlobalAliases.psm1 | Where-Object {$_.RuleName -eq $violationName} -$noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidGlobalAliasesNoViolations.ps1 | Where-Object {$_.RuleName -eq $violationName} -$IsV3OrV4 = (Test-PSVersionV3) -or (Test-PSVersionV4) +BeforeAll { + $testRootDirectory = Split-Path -Parent $PSScriptRoot + Import-Module (Join-Path $testRootDirectory 'PSScriptAnalyzerTestHelper.psm1') + + $AvoidGlobalAliasesError = "Avoid creating aliases with a Global scope." + $violationName = "PSAvoidGlobalAliases" + $violations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidGlobalAliases.psm1 | Where-Object {$_.RuleName -eq $violationName} + $noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidGlobalAliasesNoViolations.ps1 | Where-Object {$_.RuleName -eq $violationName} + $IsV3OrV4 = (Test-PSVersionV3) -or (Test-PSVersionV4) +} Describe "$violationName " { Context "When there are violations" { diff --git a/Tests/Rules/AvoidGlobalFunctions.tests.ps1 b/Tests/Rules/AvoidGlobalFunctions.tests.ps1 index b420f5b83..bbeb83279 100644 --- a/Tests/Rules/AvoidGlobalFunctions.tests.ps1 +++ b/Tests/Rules/AvoidGlobalFunctions.tests.ps1 @@ -1,9 +1,13 @@ -$functionErroMessage = "Avoid creating functions with a Global scope." -$violationName = "PSAvoidGlobalFunctions" +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. -$violations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidGlobalFunctions.psm1 | Where-Object {$_.RuleName -eq $violationName} -$noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidGlobalFunctionsNoViolations.ps1 | Where-Object {$_.RuleName -eq $violationName} +BeforeAll { + $functionErroMessage = "Avoid creating functions with a Global scope." + $violationName = "PSAvoidGlobalFunctions" + $violations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidGlobalFunctions.psm1 | Where-Object {$_.RuleName -eq $violationName} + $noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidGlobalFunctionsNoViolations.ps1 | Where-Object {$_.RuleName -eq $violationName} +} Describe "$violationName " { Context "When there are violations" { diff --git a/Tests/Rules/AvoidGlobalVars.tests.ps1 b/Tests/Rules/AvoidGlobalVars.tests.ps1 index 2b3297bd0..3b86a2bad 100644 --- a/Tests/Rules/AvoidGlobalVars.tests.ps1 +++ b/Tests/Rules/AvoidGlobalVars.tests.ps1 @@ -1,13 +1,18 @@ -$globalMessage = "Found global variable 'Global:1'." -$globalName = "PSAvoidGlobalVars" +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. -$nonInitializedMessage = "Variable 'globalVars' is not initialized. Non-global variables must be initialized. To fix a violation of this rule, please initialize non-global variables." -$violations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidGlobalOrUnitializedVars.ps1 +BeforeAll { + $globalMessage = "Found global variable 'Global:1'." + $globalName = "PSAvoidGlobalVars" -$globalViolations = $violations | Where-Object {$_.RuleName -eq $globalName} + $nonInitializedMessage = "Variable 'globalVars' is not initialized. Non-global variables must be initialized. To fix a violation of this rule, please initialize non-global variables." + $violations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidGlobalOrUnitializedVars.ps1 -$noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidGlobalOrUnitializedVarsNoViolations.ps1 -$noGlobalViolations = $noViolations | Where-Object {$_.RuleName -eq $globalName} + $globalViolations = $violations | Where-Object {$_.RuleName -eq $globalName} + + $noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidGlobalOrUnitializedVarsNoViolations.ps1 + $noGlobalViolations = $noViolations | Where-Object {$_.RuleName -eq $globalName} +} Describe "AvoidGlobalVars" { Context "When there are violations" { diff --git a/Tests/Rules/AvoidInvokingEmptyMembers.tests.ps1 b/Tests/Rules/AvoidInvokingEmptyMembers.tests.ps1 index 5e8580068..d1d6d88aa 100644 --- a/Tests/Rules/AvoidInvokingEmptyMembers.tests.ps1 +++ b/Tests/Rules/AvoidInvokingEmptyMembers.tests.ps1 @@ -1,7 +1,12 @@ -$violationMessage = "() has non-constant members. Invoking non-constant members may cause bugs in the script." -$violationName = "PSAvoidInvokingEmptyMembers" -$violations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidInvokingEmptyMembers.ps1 | Where-Object {$_.RuleName -eq $violationName} -$noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidInvokingEmptyMembersNonViolations.ps1 | Where-Object {$_.RuleName -eq $violationName} +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +BeforeAll { + $violationMessage = "() has non-constant members. Invoking non-constant members may cause bugs in the script." + $violationName = "PSAvoidInvokingEmptyMembers" + $violations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidInvokingEmptyMembers.ps1 | Where-Object {$_.RuleName -eq $violationName} + $noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidInvokingEmptyMembersNonViolations.ps1 | Where-Object {$_.RuleName -eq $violationName} +} Describe "AvoidInvokingEmptyMembers" { Context "When there are violations" { diff --git a/Tests/Rules/AvoidLongLines.tests.ps1 b/Tests/Rules/AvoidLongLines.tests.ps1 index 5a6c8e189..b2681bee6 100644 --- a/Tests/Rules/AvoidLongLines.tests.ps1 +++ b/Tests/Rules/AvoidLongLines.tests.ps1 @@ -1,11 +1,16 @@ -$ruleName = "PSAvoidLongLines" +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. -$ruleSettings = @{ - Enable = $true -} -$settings = @{ - IncludeRules = @($ruleName) - Rules = @{ $ruleName = $ruleSettings } +BeforeAll { + $ruleName = "PSAvoidLongLines" + + $ruleSettings = @{ + Enable = $true + } + $settings = @{ + IncludeRules = @($ruleName) + Rules = @{ $ruleName = $ruleSettings } + } } Describe "AvoidLongLines" { diff --git a/Tests/Rules/AvoidNullOrEmptyHelpMessageAttribute.tests.ps1 b/Tests/Rules/AvoidNullOrEmptyHelpMessageAttribute.tests.ps1 index a710297aa..75aee3aff 100644 --- a/Tests/Rules/AvoidNullOrEmptyHelpMessageAttribute.tests.ps1 +++ b/Tests/Rules/AvoidNullOrEmptyHelpMessageAttribute.tests.ps1 @@ -1,7 +1,12 @@ -$violationName = "PSAvoidNullOrEmptyHelpMessageAttribute" -$violationMessage = "HelpMessage parameter attribute should not be null or empty. To fix a violation of this rule, please set its value to a non-empty string." -$violations = Invoke-ScriptAnalyzer "$PSScriptRoot\AvoidNullOrEmptyHelpMessageAttribute.ps1" -IncludeRule PSAvoidNullOrEmptyHelpMessageAttribute -$noViolations = Invoke-ScriptAnalyzer "$PSScriptRoot\AvoidNullOrEmptyHelpMessageAttributeNoViolations.ps1" -IncludeRule PSAvoidNullOrEmptyHelpMessageAttribute +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +BeforeAll { + $violationName = "PSAvoidNullOrEmptyHelpMessageAttribute" + $violationMessage = "HelpMessage parameter attribute should not be null or empty. To fix a violation of this rule, please set its value to a non-empty string." + $violations = Invoke-ScriptAnalyzer "$PSScriptRoot\AvoidNullOrEmptyHelpMessageAttribute.ps1" -IncludeRule PSAvoidNullOrEmptyHelpMessageAttribute + $noViolations = Invoke-ScriptAnalyzer "$PSScriptRoot\AvoidNullOrEmptyHelpMessageAttributeNoViolations.ps1" -IncludeRule PSAvoidNullOrEmptyHelpMessageAttribute +} Describe "AvoidNullOrEmptyHelpMessageAttribute" { Context "When there are violations" { diff --git a/Tests/Rules/AvoidOverwritingBuiltInCmdlets.tests.ps1 b/Tests/Rules/AvoidOverwritingBuiltInCmdlets.tests.ps1 index eedebbd28..306acebe4 100644 --- a/Tests/Rules/AvoidOverwritingBuiltInCmdlets.tests.ps1 +++ b/Tests/Rules/AvoidOverwritingBuiltInCmdlets.tests.ps1 @@ -1,29 +1,34 @@ -$ruleName = "PSAvoidOverwritingBuiltInCmdlets" +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. -$ruleSettingsWindows = @{$ruleName = @{PowerShellVersion = @('desktop-5.1.14393.206-windows') } } -$ruleSettingsCore = @{$ruleName = @{PowerShellVersion = @('core-6.1.0-windows') } } -$ruleSettingsBoth = @{$ruleName = @{PowerShellVersion = @('core-6.1.0-windows', 'desktop-5.1.14393.206-windows') } } +BeforeAll { + $ruleName = "PSAvoidOverwritingBuiltInCmdlets" -$settings = @{ - IncludeRules = @($ruleName) -} + $ruleSettingsWindows = @{$ruleName = @{PowerShellVersion = @('desktop-5.1.14393.206-windows') } } + $ruleSettingsCore = @{$ruleName = @{PowerShellVersion = @('core-6.1.0-windows') } } + $ruleSettingsBoth = @{$ruleName = @{PowerShellVersion = @('core-6.1.0-windows', 'desktop-5.1.14393.206-windows') } } -# Get-Something is not a built in cmdlet on any platform and should never be flagged -# Get-ChildItem is available on all versions of PowerShell and should always be flagged -# Get-Clipboard is available on PowerShell 5 but not 6 and should be flagged conditionally -$scriptDefinition = @" -function Get-Something { - Write-Output "Get-Something" -} + $settings = @{ + IncludeRules = @($ruleName) + } -function Get-ChildItem { - Write-Output "Get-ChildItem" -} + # Get-Something is not a built in cmdlet on any platform and should never be flagged + # Get-ChildItem is available on all versions of PowerShell and should always be flagged + # Get-Clipboard is available on PowerShell 5 but not 6 and should be flagged conditionally + $scriptDefinition = @" + function Get-Something { + Write-Output "Get-Something" + } -function Get-Clipboard { - Write-Output "Get-Clipboard" -} + function Get-ChildItem { + Write-Output "Get-ChildItem" + } + + function Get-Clipboard { + Write-Output "Get-Clipboard" + } "@ +} describe 'AvoidOverwritingBuiltInCmdlets' { context 'No settings specified' { diff --git a/Tests/Rules/AvoidPositionalParameters.tests.ps1 b/Tests/Rules/AvoidPositionalParameters.tests.ps1 index 03f9368fc..73fa5d563 100644 --- a/Tests/Rules/AvoidPositionalParameters.tests.ps1 +++ b/Tests/Rules/AvoidPositionalParameters.tests.ps1 @@ -1,8 +1,13 @@ -$violationMessage = "Cmdlet 'Get-Command' has positional parameter. Please use named parameters instead of positional parameters when calling a command." -$violationName = "PSAvoidUsingPositionalParameters" -$violations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidPositionalParameters.ps1 | Where-Object {$_.RuleName -eq $violationName} -$noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidPositionalParametersNoViolations.ps1 | Where-Object {$_.RuleName -eq $violationName} -$noViolationsDSC = Invoke-ScriptAnalyzer -ErrorAction SilentlyContinue $PSScriptRoot\serviceconfigdisabled.ps1 | Where-Object {$_.RuleName -eq $violationName} +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +BeforeAll { + $violationMessage = "Cmdlet 'Get-Command' has positional parameter. Please use named parameters instead of positional parameters when calling a command." + $violationName = "PSAvoidUsingPositionalParameters" + $violations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidPositionalParameters.ps1 | Where-Object {$_.RuleName -eq $violationName} + $noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidPositionalParametersNoViolations.ps1 | Where-Object {$_.RuleName -eq $violationName} + $noViolationsDSC = Invoke-ScriptAnalyzer -ErrorAction SilentlyContinue $PSScriptRoot\serviceconfigdisabled.ps1 | Where-Object {$_.RuleName -eq $violationName} +} Describe "AvoidPositionalParameters" { Context "When there are violations" { diff --git a/Tests/Rules/AvoidReservedParams.tests.ps1 b/Tests/Rules/AvoidReservedParams.tests.ps1 index 52020df37..b0657429d 100644 --- a/Tests/Rules/AvoidReservedParams.tests.ps1 +++ b/Tests/Rules/AvoidReservedParams.tests.ps1 @@ -1,7 +1,12 @@ -$violationMessage = [regex]::Escape("Verb-Files' defines the reserved common parameter 'Verbose'.") -$violationName = "PSReservedParams" -$violations = Invoke-ScriptAnalyzer $PSScriptRoot\BadCmdlet.ps1 | Where-Object {$_.RuleName -eq $violationName} -$noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\GoodCmdlet.ps1 | Where-Object {$_.RuleName -eq $violationName} +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +BeforeAll { + $violationMessage = [regex]::Escape("Verb-Files' defines the reserved common parameter 'Verbose'.") + $violationName = "PSReservedParams" + $violations = Invoke-ScriptAnalyzer $PSScriptRoot\BadCmdlet.ps1 | Where-Object {$_.RuleName -eq $violationName} + $noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\GoodCmdlet.ps1 | Where-Object {$_.RuleName -eq $violationName} +} Describe "AvoidReservedParams" { Context "When there are violations" { diff --git a/Tests/Rules/AvoidShouldContinueWithoutForce.tests.ps1 b/Tests/Rules/AvoidShouldContinueWithoutForce.tests.ps1 index 7ebff4de5..3d3985d7f 100644 --- a/Tests/Rules/AvoidShouldContinueWithoutForce.tests.ps1 +++ b/Tests/Rules/AvoidShouldContinueWithoutForce.tests.ps1 @@ -1,7 +1,12 @@ -$violationMessage = "Function 'Verb-Noun2' in file 'AvoidShouldContinueWithoutForce.ps1' uses ShouldContinue but does not have a boolean force parameter. The force parameter will allow users of the script to bypass ShouldContinue prompt" -$violationName = "PSAvoidShouldContinueWithoutForce" -$violations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidShouldContinueWithoutForce.ps1 | Where-Object {$_.RuleName -eq $violationName} -$noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\GoodCmdlet.ps1 | Where-Object {$_.RuleName -eq $violationName} +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +BeforeAll { + $violationMessage = "Function 'Verb-Noun2' in file 'AvoidShouldContinueWithoutForce.ps1' uses ShouldContinue but does not have a boolean force parameter. The force parameter will allow users of the script to bypass ShouldContinue prompt" + $violationName = "PSAvoidShouldContinueWithoutForce" + $violations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidShouldContinueWithoutForce.ps1 | Where-Object {$_.RuleName -eq $violationName} + $noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\GoodCmdlet.ps1 | Where-Object {$_.RuleName -eq $violationName} +} Describe "AvoidShouldContinueWithoutForce" { Context "When there are violations" { diff --git a/Tests/Rules/AvoidTrailingWhitespace.tests.ps1 b/Tests/Rules/AvoidTrailingWhitespace.tests.ps1 index b51398984..f130a77c5 100644 --- a/Tests/Rules/AvoidTrailingWhitespace.tests.ps1 +++ b/Tests/Rules/AvoidTrailingWhitespace.tests.ps1 @@ -1,10 +1,15 @@ -$testRootDirectory = Split-Path -Parent $PSScriptRoot -Import-Module (Join-Path $testRootDirectory "PSScriptAnalyzerTestHelper.psm1") +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. -$ruleName = "PSAvoidTrailingWhitespace" +BeforeAll { + $testRootDirectory = Split-Path -Parent $PSScriptRoot + Import-Module (Join-Path $testRootDirectory "PSScriptAnalyzerTestHelper.psm1") -$settings = @{ - IncludeRules = @($ruleName) + $ruleName = "PSAvoidTrailingWhitespace" + + $settings = @{ + IncludeRules = @($ruleName) + } } Describe "AvoidTrailingWhitespace" { diff --git a/Tests/Rules/AvoidUnloadableModuleOrMissingRequiredFieldInManifest.tests.ps1 b/Tests/Rules/AvoidUnloadableModuleOrMissingRequiredFieldInManifest.tests.ps1 index 017382aeb..7fecd1a6a 100644 --- a/Tests/Rules/AvoidUnloadableModuleOrMissingRequiredFieldInManifest.tests.ps1 +++ b/Tests/Rules/AvoidUnloadableModuleOrMissingRequiredFieldInManifest.tests.ps1 @@ -1,12 +1,17 @@ -$testRootDirectory = Split-Path -Parent $PSScriptRoot -Import-Module (Join-Path $testRootDirectory 'PSScriptAnalyzerTestHelper.psm1') - -$missingMessage = "The member 'ModuleVersion' is not present in the module manifest." -$missingMemberRuleName = "PSMissingModuleManifestField" -$violationFilepath = Join-Path $PSScriptRoot "TestBadModule\TestBadModule.psd1" -$violations = Invoke-ScriptAnalyzer $violationFilepath | Where-Object {$_.RuleName -eq $missingMemberRuleName} -$noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\TestGoodModule\TestGoodModule.psd1 | Where-Object {$_.RuleName -eq $missingMemberRuleName} -$noHashtableFilepath = Join-Path $PSScriptRoot "TestBadModule\NoHashtable.psd1" +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +BeforeAll { + $testRootDirectory = Split-Path -Parent $PSScriptRoot + Import-Module (Join-Path $testRootDirectory 'PSScriptAnalyzerTestHelper.psm1') + + $missingMessage = "The member 'ModuleVersion' is not present in the module manifest." + $missingMemberRuleName = "PSMissingModuleManifestField" + $violationFilepath = Join-Path $PSScriptRoot "TestBadModule\TestBadModule.psd1" + $violations = Invoke-ScriptAnalyzer $violationFilepath | Where-Object {$_.RuleName -eq $missingMemberRuleName} + $noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\TestGoodModule\TestGoodModule.psd1 | Where-Object {$_.RuleName -eq $missingMemberRuleName} + $noHashtableFilepath = Join-Path $PSScriptRoot "TestBadModule\NoHashtable.psd1" +} Describe "MissingRequiredFieldModuleManifest" { BeforeAll { diff --git a/Tests/Rules/AvoidUserNameAndPasswordParams.tests.ps1 b/Tests/Rules/AvoidUserNameAndPasswordParams.tests.ps1 index 7b3c966e8..bbadcbc8b 100644 --- a/Tests/Rules/AvoidUserNameAndPasswordParams.tests.ps1 +++ b/Tests/Rules/AvoidUserNameAndPasswordParams.tests.ps1 @@ -1,8 +1,12 @@ - -$violationMessage = "Function 'TestFunction1' has both Username and Password parameters. Either set the type of the Password parameter to SecureString or replace the Username and Password parameters with a Credential parameter of type PSCredential. If using a Credential parameter in PowerShell 4.0 or earlier, please define a credential transformation attribute after the PSCredential type attribute." -$violationName = "PSAvoidUsingUserNameAndPasswordParams" -$violations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidUserNameAndPasswordParams.ps1 | Where-Object {$_.RuleName -eq $violationName} -$noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidUserNameAndPasswordParamsNoViolations.ps1 | Where-Object {$_.RuleName -eq $violationName} +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +BeforeAll { + $violationMessage = "Function 'TestFunction1' has both Username and Password parameters. Either set the type of the Password parameter to SecureString or replace the Username and Password parameters with a Credential parameter of type PSCredential. If using a Credential parameter in PowerShell 4.0 or earlier, please define a credential transformation attribute after the PSCredential type attribute." + $violationName = "PSAvoidUsingUserNameAndPasswordParams" + $violations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidUserNameAndPasswordParams.ps1 | Where-Object {$_.RuleName -eq $violationName} + $noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidUserNameAndPasswordParamsNoViolations.ps1 | Where-Object {$_.RuleName -eq $violationName} +} Describe "AvoidUserNameAndPasswordParams" { Context "When there are violations" { diff --git a/Tests/Rules/AvoidUsingAlias.tests.ps1 b/Tests/Rules/AvoidUsingAlias.tests.ps1 index cd0ff4a4d..bd691f745 100644 --- a/Tests/Rules/AvoidUsingAlias.tests.ps1 +++ b/Tests/Rules/AvoidUsingAlias.tests.ps1 @@ -1,11 +1,15 @@ -$violationMessage = "'cls' is an alias of 'Clear-Host'. Alias can introduce possible problems and make scripts hard to maintain. Please consider changing alias to its full content." -$violationName = "PSAvoidUsingCmdletAliases" -$testRootDirectory = Split-Path -Parent $PSScriptRoot -$violationFilepath = Join-Path $PSScriptRoot 'AvoidUsingAlias.ps1' -$violations = Invoke-ScriptAnalyzer $violationFilepath | Where-Object {$_.RuleName -eq $violationName} -$noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidUsingAliasNoViolations.ps1 | Where-Object {$_.RuleName -eq $violationName} - -Import-Module (Join-Path $testRootDirectory "PSScriptAnalyzerTestHelper.psm1") +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +BeforeAll { + $violationMessage = "'cls' is an alias of 'Clear-Host'. Alias can introduce possible problems and make scripts hard to maintain. Please consider changing alias to its full content." + $violationName = "PSAvoidUsingCmdletAliases" + $testRootDirectory = Split-Path -Parent $PSScriptRoot + $violationFilepath = Join-Path $PSScriptRoot 'AvoidUsingAlias.ps1' + $violations = Invoke-ScriptAnalyzer $violationFilepath | Where-Object {$_.RuleName -eq $violationName} + $noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidUsingAliasNoViolations.ps1 | Where-Object {$_.RuleName -eq $violationName} + Import-Module (Join-Path $testRootDirectory "PSScriptAnalyzerTestHelper.psm1") +} Describe "AvoidUsingAlias" { Context "When there are violations" { diff --git a/Tests/Rules/AvoidUsingComputerNameHardcoded.tests.ps1 b/Tests/Rules/AvoidUsingComputerNameHardcoded.tests.ps1 index 3c0fc58a7..6b9bb30f6 100644 --- a/Tests/Rules/AvoidUsingComputerNameHardcoded.tests.ps1 +++ b/Tests/Rules/AvoidUsingComputerNameHardcoded.tests.ps1 @@ -1,7 +1,12 @@ -$violationMessage = [regex]::Escape("The ComputerName parameter of cmdlet 'Invoke-Command' is hardcoded. This will expose sensitive information about the system if the script is shared.") -$violationName = "PSAvoidUsingComputerNameHardcoded" -$violations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidUsingComputerNameHardcoded.ps1 | Where-Object {$_.RuleName -eq $violationName} -$noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidUsingComputerNameHardcodedNoViolations.ps1 | Where-Object {$_.RuleName -eq $violationName} +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +BeforeAll { + $violationMessage = [regex]::Escape("The ComputerName parameter of cmdlet 'Invoke-Command' is hardcoded. This will expose sensitive information about the system if the script is shared.") + $violationName = "PSAvoidUsingComputerNameHardcoded" + $violations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidUsingComputerNameHardcoded.ps1 | Where-Object {$_.RuleName -eq $violationName} + $noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidUsingComputerNameHardcodedNoViolations.ps1 | Where-Object {$_.RuleName -eq $violationName} +} Describe "AvoidUsingComputerNameHardcoded" { Context "When there are violations" { diff --git a/Tests/Rules/AvoidUsingDeprecatedManifestFields.tests.ps1 b/Tests/Rules/AvoidUsingDeprecatedManifestFields.tests.ps1 index 9a04b96d5..2abd76be8 100644 --- a/Tests/Rules/AvoidUsingDeprecatedManifestFields.tests.ps1 +++ b/Tests/Rules/AvoidUsingDeprecatedManifestFields.tests.ps1 @@ -1,7 +1,12 @@ -$violationName = "PSAvoidUsingDeprecatedManifestFields" -$violations = Invoke-ScriptAnalyzer "$PSScriptRoot\TestBadModule\TestDeprecatedManifestFields.psd1" | Where-Object {$_.RuleName -eq $violationName} -$noViolations = Invoke-ScriptAnalyzer "$PSScriptRoot\TestGoodModule\TestGoodModule.psd1" | Where-Object {$_.RuleName -eq $violationName} -$noViolations2 = Invoke-ScriptAnalyzer "$PSScriptRoot\TestGoodModule\TestDeprecatedManifestFieldsWithVersion2.psd1" | Where-Object {$_.RuleName -eq $violationName} +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +BeforeAll { + $violationName = "PSAvoidUsingDeprecatedManifestFields" + $violations = Invoke-ScriptAnalyzer "$PSScriptRoot\TestBadModule\TestDeprecatedManifestFields.psd1" | Where-Object {$_.RuleName -eq $violationName} + $noViolations = Invoke-ScriptAnalyzer "$PSScriptRoot\TestGoodModule\TestGoodModule.psd1" | Where-Object {$_.RuleName -eq $violationName} + $noViolations2 = Invoke-ScriptAnalyzer "$PSScriptRoot\TestGoodModule\TestDeprecatedManifestFieldsWithVersion2.psd1" | Where-Object {$_.RuleName -eq $violationName} +} Describe "AvoidUsingDeprecatedManifestFields" { Context "When there are violations" { diff --git a/Tests/Rules/AvoidUsingInvokeExpression.tests.ps1 b/Tests/Rules/AvoidUsingInvokeExpression.tests.ps1 index 322a52b0a..2d2fe36a9 100644 --- a/Tests/Rules/AvoidUsingInvokeExpression.tests.ps1 +++ b/Tests/Rules/AvoidUsingInvokeExpression.tests.ps1 @@ -1,7 +1,12 @@ -$violationMessage = "Invoke-Expression is used. Please remove Invoke-Expression from script and find other options instead." -$violationName = "PSAvoidUsingInvokeExpression" -$violations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidUsingInvokeExpression.ps1 | Where-Object {$_.RuleName -eq $violationName} -$noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidConvertToSecureStringWithPlainTextNoViolations.ps1 | Where-Object {$_.RuleName -eq $violationName} +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +BeforeAll { + $violationMessage = "Invoke-Expression is used. Please remove Invoke-Expression from script and find other options instead." + $violationName = "PSAvoidUsingInvokeExpression" + $violations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidUsingInvokeExpression.ps1 | Where-Object {$_.RuleName -eq $violationName} + $noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidConvertToSecureStringWithPlainTextNoViolations.ps1 | Where-Object {$_.RuleName -eq $violationName} +} Describe "AvoidUsingInvokeExpression" { Context "When there are violations" { diff --git a/Tests/Rules/AvoidUsingPlainTextForPassword.tests.ps1 b/Tests/Rules/AvoidUsingPlainTextForPassword.tests.ps1 index 2824a8088..b91b1f10d 100644 --- a/Tests/Rules/AvoidUsingPlainTextForPassword.tests.ps1 +++ b/Tests/Rules/AvoidUsingPlainTextForPassword.tests.ps1 @@ -1,9 +1,14 @@ -$violationMessage = [regex]::Escape("Parameter '`$password' should use SecureString, otherwise this will expose sensitive information. See ConvertTo-SecureString for more information.") -$violationName = "PSAvoidUsingPlainTextForPassword" -$violationFilepath = Join-Path $PSScriptRoot 'AvoidUsingPlainTextForPassword.ps1' -$violations = Invoke-ScriptAnalyzer $violationFilepath | Where-Object {$_.RuleName -eq $violationName} -$noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidUsingPlainTextForPasswordNoViolations.ps1 | Where-Object {$_.RuleName -eq $violationName} -Import-Module (Join-Path $PSScriptRoot "PSScriptAnalyzerTestHelper.psm1") +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +BeforeAll { + $violationMessage = [regex]::Escape("Parameter '`$password' should use SecureString, otherwise this will expose sensitive information. See ConvertTo-SecureString for more information.") + $violationName = "PSAvoidUsingPlainTextForPassword" + $violationFilepath = Join-Path $PSScriptRoot 'AvoidUsingPlainTextForPassword.ps1' + $violations = Invoke-ScriptAnalyzer $violationFilepath | Where-Object {$_.RuleName -eq $violationName} + $noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidUsingPlainTextForPasswordNoViolations.ps1 | Where-Object {$_.RuleName -eq $violationName} + Import-Module (Join-Path $PSScriptRoot "PSScriptAnalyzerTestHelper.psm1") +} Describe "AvoidUsingPlainTextForPassword" { Context "When there are violations" { diff --git a/Tests/Rules/AvoidUsingReservedCharNames.tests.ps1 b/Tests/Rules/AvoidUsingReservedCharNames.tests.ps1 index 4321c97f9..0cd799bec 100644 --- a/Tests/Rules/AvoidUsingReservedCharNames.tests.ps1 +++ b/Tests/Rules/AvoidUsingReservedCharNames.tests.ps1 @@ -1,7 +1,12 @@ -$reservedCharMessage = "The cmdlet 'Use-#Reserved' uses a reserved char in its name." -$reservedCharName = "PSReservedCmdletChar" -$violations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidUsingReservedCharNames.ps1 | Where-Object {$_.RuleName -eq $reservedCharName} -$noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\GoodCmdlet.ps1 | Where-Object {$_.RuleName -eq $reservedCharName} +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +BeforeAll { + $reservedCharMessage = "The cmdlet 'Use-#Reserved' uses a reserved char in its name." + $reservedCharName = "PSReservedCmdletChar" + $violations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidUsingReservedCharNames.ps1 | Where-Object {$_.RuleName -eq $reservedCharName} + $noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\GoodCmdlet.ps1 | Where-Object {$_.RuleName -eq $reservedCharName} +} Describe "Avoid Using Reserved Char" { Context "When there are violations" { diff --git a/Tests/Rules/AvoidUsingWMICmdlet.tests.ps1 b/Tests/Rules/AvoidUsingWMICmdlet.tests.ps1 index 688707121..174adf009 100644 --- a/Tests/Rules/AvoidUsingWMICmdlet.tests.ps1 +++ b/Tests/Rules/AvoidUsingWMICmdlet.tests.ps1 @@ -1,7 +1,12 @@ -$WMIRuleName = "PSAvoidUsingWMICmdlet" -$violationMessage = "File 'AvoidUsingWMICmdlet.ps1' uses WMI cmdlet. For PowerShell 3.0 and above, use CIM cmdlet which perform the same tasks as the WMI cmdlets. The CIM cmdlets comply with WS-Management (WSMan) standards and with the Common Information Model (CIM) standard, which enables the cmdlets to use the same techniques to manage Windows computers and those running other operating systems." -$violations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidUsingWMICmdlet.ps1 -IncludeRule $WMIRuleName -$noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidUsingWMICmdletNoViolations.ps1 -IncludeRule $WMIRuleName +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +BeforeAll { + $WMIRuleName = "PSAvoidUsingWMICmdlet" + $violationMessage = "File 'AvoidUsingWMICmdlet.ps1' uses WMI cmdlet. For PowerShell 3.0 and above, use CIM cmdlet which perform the same tasks as the WMI cmdlets. The CIM cmdlets comply with WS-Management (WSMan) standards and with the Common Information Model (CIM) standard, which enables the cmdlets to use the same techniques to manage Windows computers and those running other operating systems." + $violations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidUsingWMICmdlet.ps1 -IncludeRule $WMIRuleName + $noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidUsingWMICmdletNoViolations.ps1 -IncludeRule $WMIRuleName +} Describe "AvoidUsingWMICmdlet" { Context "Script contains references to WMI cmdlets - Violation" { diff --git a/Tests/Rules/AvoidUsingWriteHost.tests.ps1 b/Tests/Rules/AvoidUsingWriteHost.tests.ps1 index 947328cdd..9d0a0847b 100644 --- a/Tests/Rules/AvoidUsingWriteHost.tests.ps1 +++ b/Tests/Rules/AvoidUsingWriteHost.tests.ps1 @@ -1,8 +1,13 @@ -Set-Alias ctss ConvertTo-SecureString -$writeHostMessage = [Regex]::Escape("File 'AvoidUsingWriteHost.ps1' uses Write-Host. Avoid using Write-Host because it might not work in all hosts, does not work when there is no host, and (prior to PS 5.0) cannot be suppressed, captured, or redirected. Instead, use Write-Output, Write-Verbose, or Write-Information.") -$writeHostName = "PSAvoidUsingWriteHost" -$violations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidUsingWriteHost.ps1 | Where-Object {$_.RuleName -eq $writeHostName} -$noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidUsingWriteHostNoViolations.ps1 | Where-Object {$_.RuleName -eq $clearHostName} +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +BeforeAll { + Set-Alias ctss ConvertTo-SecureString + $writeHostMessage = [Regex]::Escape("File 'AvoidUsingWriteHost.ps1' uses Write-Host. Avoid using Write-Host because it might not work in all hosts, does not work when there is no host, and (prior to PS 5.0) cannot be suppressed, captured, or redirected. Instead, use Write-Output, Write-Verbose, or Write-Information.") + $writeHostName = "PSAvoidUsingWriteHost" + $violations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidUsingWriteHost.ps1 | Where-Object {$_.RuleName -eq $writeHostName} + $noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidUsingWriteHostNoViolations.ps1 | Where-Object {$_.RuleName -eq $clearHostName} +} Describe "AvoidUsingWriteHost" { Context "When there are violations" { diff --git a/Tests/Rules/DscExamplesPresent.tests.ps1 b/Tests/Rules/DscExamplesPresent.tests.ps1 index c8f52dd85..46e51fa26 100644 --- a/Tests/Rules/DscExamplesPresent.tests.ps1 +++ b/Tests/Rules/DscExamplesPresent.tests.ps1 @@ -1,11 +1,15 @@ -$ruleName = "PSDSCDscExamplesPresent" +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. -if ($PSVersionTable.PSVersion -ge [Version]'5.0.0') { - - Describe "DscExamplesPresent rule in class based resource" { +BeforeAll { + $ruleName = "PSDSCDscExamplesPresent" +} - $examplesPath = "$PSScriptRoot\DSCResourceModule\DSCResources\MyDscResource\Examples" - $classResourcePath = "$PSScriptRoot\DSCResourceModule\DSCResources\MyDscResource\MyDscResource.psm1" + Describe "DscExamplesPresent rule in class based resource" -Skip:($PSVersionTable.PSVersion -lt [Version]'5.0.0') { + BeforeAll { + $examplesPath = "$PSScriptRoot\DSCResourceModule\DSCResources\MyDscResource\Examples" + $classResourcePath = "$PSScriptRoot\DSCResourceModule\DSCResources\MyDscResource\MyDscResource.psm1" + } Context "When examples absent" { @@ -33,13 +37,13 @@ if ($PSVersionTable.PSVersion -ge [Version]'5.0.0') { Remove-Item -Path $examplesPath -Recurse -Force } - } } Describe "DscExamplesPresent rule in regular (non-class) based resource" { - - $examplesPath = "$PSScriptRoot\DSCResourceModule\Examples" - $resourcePath = "$PSScriptRoot\DSCResourceModule\DSCResources\MSFT_WaitForAll\MSFT_WaitForAll.psm1" + BeforeAll { + $examplesPath = "$PSScriptRoot\DSCResourceModule\Examples" + $resourcePath = "$PSScriptRoot\DSCResourceModule\DSCResources\MSFT_WaitForAll\MSFT_WaitForAll.psm1" + } Context "When examples absent" { @@ -56,10 +60,11 @@ Describe "DscExamplesPresent rule in regular (non-class) based resource" { } Context "When examples present" { - New-Item -Path $examplesPath -ItemType Directory -force - New-Item -Path "$examplesPath\MSFT_WaitForAll_Example.psm1" -ItemType File -force - - $noViolations = Invoke-ScriptAnalyzer -ErrorAction SilentlyContinue $resourcePath | Where-Object {$_.RuleName -eq $ruleName} + BeforeAll { + New-Item -Path $examplesPath -ItemType Directory -force + New-Item -Path "$examplesPath\MSFT_WaitForAll_Example.psm1" -ItemType File -force + $noViolations = Invoke-ScriptAnalyzer -ErrorAction SilentlyContinue $resourcePath | Where-Object {$_.RuleName -eq $ruleName} + } It "returns no violations" { $noViolations.Count | Should -Be 0 diff --git a/Tests/Rules/DscTestsPresent.tests.ps1 b/Tests/Rules/DscTestsPresent.tests.ps1 index d9af9da94..c6076646f 100644 --- a/Tests/Rules/DscTestsPresent.tests.ps1 +++ b/Tests/Rules/DscTestsPresent.tests.ps1 @@ -1,11 +1,15 @@ -$ruleName = "PSDSCDscTestsPresent" +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. -if ($PSVersionTable.PSVersion -ge [Version]'5.0.0') { - - Describe "DscTestsPresent rule in class based resource" { +BeforeAll { + $ruleName = "PSDSCDscTestsPresent" +} - $testsPath = "$PSScriptRoot\DSCResourceModule\DSCResources\MyDscResource\Tests" - $classResourcePath = "$PSScriptRoot\DSCResourceModule\DSCResources\MyDscResource\MyDscResource.psm1" + Describe "DscTestsPresent rule in class based resource" -Skip:($PSVersionTable.PSVersion -lt [Version]'5.0.0') { + BeforeAll { + $testsPath = "$PSScriptRoot\DSCResourceModule\DSCResources\MyDscResource\Tests" + $classResourcePath = "$PSScriptRoot\DSCResourceModule\DSCResources\MyDscResource\MyDscResource.psm1" + } Context "When tests absent" { @@ -22,10 +26,11 @@ if ($PSVersionTable.PSVersion -ge [Version]'5.0.0') { } Context "When tests present" { - New-Item -Path $testsPath -ItemType Directory -force - New-Item -Path "$testsPath\FileResource_Test.psm1" -ItemType File -force - - $noViolations = Invoke-ScriptAnalyzer -ErrorAction SilentlyContinue $classResourcePath | Where-Object {$_.RuleName -eq $ruleName} + BeforeAll { + New-Item -Path $testsPath -ItemType Directory -force + New-Item -Path "$testsPath\FileResource_Test.psm1" -ItemType File -force + $noViolations = Invoke-ScriptAnalyzer -ErrorAction SilentlyContinue $classResourcePath | Where-Object {$_.RuleName -eq $ruleName} + } It "returns no violations" { $noViolations.Count | Should -Be 0 @@ -33,18 +38,18 @@ if ($PSVersionTable.PSVersion -ge [Version]'5.0.0') { Remove-Item -Path $testsPath -Recurse -Force } - } } Describe "DscTestsPresent rule in regular (non-class) based resource" { - - $testsPath = "$PSScriptRoot\DSCResourceModule\Tests" - $resourcePath = "$PSScriptRoot\DSCResourceModule\DSCResources\MSFT_WaitForAll\MSFT_WaitForAll.psm1" + BeforeAll { + $resourcePath = "$PSScriptRoot\DSCResourceModule\DSCResources\MSFT_WaitForAll\MSFT_WaitForAll.psm1" + } Context "When tests absent" { - - $violations = Invoke-ScriptAnalyzer -ErrorAction SilentlyContinue $resourcePath | Where-Object {$_.RuleName -eq $ruleName} - $violationMessage = "No tests found for resource 'MSFT_WaitForAll'" + BeforeAll { + $violations = Invoke-ScriptAnalyzer -ErrorAction SilentlyContinue $resourcePath | Where-Object {$_.RuleName -eq $ruleName} + $violationMessage = "No tests found for resource 'MSFT_WaitForAll'" + } It "has 1 missing tests violation" { $violations.Count | Should -Be 1 @@ -56,8 +61,11 @@ Describe "DscTestsPresent rule in regular (non-class) based resource" { } Context "When tests present" { - New-Item -Path $testsPath -ItemType Directory -force - New-Item -Path "$testsPath\MSFT_WaitForAll_Test.psm1" -ItemType File -force + BeforeAll { + $testsPath = "$PSScriptRoot\DSCResourceModule\Tests" + New-Item -Path $testsPath -ItemType Directory -force + New-Item -Path "$testsPath\MSFT_WaitForAll_Test.psm1" -ItemType File -force + } $noViolations = Invoke-ScriptAnalyzer -ErrorAction SilentlyContinue $resourcePath | Where-Object {$_.RuleName -eq $ruleName} diff --git a/Tests/Rules/MisleadingBacktick.tests.ps1 b/Tests/Rules/MisleadingBacktick.tests.ps1 index b640e8b04..a042bbb89 100644 --- a/Tests/Rules/MisleadingBacktick.tests.ps1 +++ b/Tests/Rules/MisleadingBacktick.tests.ps1 @@ -1,8 +1,13 @@ -$writeHostName = "PSMisleadingBacktick" -$violationFilepath = Join-Path $PSScriptRoot 'MisleadingBacktick.ps1' -$violations = Invoke-ScriptAnalyzer $violationFilepath | Where-Object {$_.RuleName -eq $writeHostName} -$noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\NoMisleadingBacktick.ps1 | Where-Object {$_.RuleName -eq $clearHostName} -Import-Module (Join-Path $PSScriptRoot "PSScriptAnalyzerTestHelper.psm1") +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +BeforeAll { + $writeHostName = "PSMisleadingBacktick" + $violationFilepath = Join-Path $PSScriptRoot 'MisleadingBacktick.ps1' + $violations = Invoke-ScriptAnalyzer $violationFilepath | Where-Object {$_.RuleName -eq $writeHostName} + $noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\NoMisleadingBacktick.ps1 | Where-Object {$_.RuleName -eq $clearHostName} + Import-Module (Join-Path $PSScriptRoot "PSScriptAnalyzerTestHelper.psm1") +} Describe "Avoid Misleading Backticks" { Context "When there are violations" { diff --git a/Tests/Rules/PSCredentialType.tests.ps1 b/Tests/Rules/PSCredentialType.tests.ps1 index fb339d29d..4128fe9a4 100644 --- a/Tests/Rules/PSCredentialType.tests.ps1 +++ b/Tests/Rules/PSCredentialType.tests.ps1 @@ -1,10 +1,15 @@ -$testRootDirectory = Split-Path -Parent $PSScriptRoot -Import-Module (Join-Path $testRootDirectory 'PSScriptAnalyzerTestHelper.psm1') +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. -$violationMessage = "The Credential parameter in 'Credential' must be of type PSCredential. For PowerShell 4.0 and earlier, please define a credential transformation attribute, e.g. [System.Management.Automation.Credential()], after the PSCredential type attribute." -$violationName = "PSUsePSCredentialType" -$violations = Invoke-ScriptAnalyzer $PSScriptRoot\PSCredentialType.ps1 | Where-Object {$_.RuleName -eq $violationName} -$noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\PSCredentialTypeNoViolations.ps1 | Where-Object {$_.RuleName -eq $violationName} +BeforeAll { + $testRootDirectory = Split-Path -Parent $PSScriptRoot + Import-Module (Join-Path $testRootDirectory 'PSScriptAnalyzerTestHelper.psm1') + + $violationMessage = "The Credential parameter in 'Credential' must be of type PSCredential. For PowerShell 4.0 and earlier, please define a credential transformation attribute, e.g. [System.Management.Automation.Credential()], after the PSCredential type attribute." + $violationName = "PSUsePSCredentialType" + $violations = Invoke-ScriptAnalyzer $PSScriptRoot\PSCredentialType.ps1 | Where-Object {$_.RuleName -eq $violationName} + $noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\PSCredentialTypeNoViolations.ps1 | Where-Object {$_.RuleName -eq $violationName} +} Describe "PSCredentialType" { Context "When there are violations" { diff --git a/Tests/Rules/PossibleIncorrectComparisonWithNull.tests.ps1 b/Tests/Rules/PossibleIncorrectComparisonWithNull.tests.ps1 index ff00080d8..e2d3add21 100644 --- a/Tests/Rules/PossibleIncorrectComparisonWithNull.tests.ps1 +++ b/Tests/Rules/PossibleIncorrectComparisonWithNull.tests.ps1 @@ -1,7 +1,12 @@ -$violationMessage = [regex]::Escape('$null should be on the left side of equality comparisons.') -$violationName = "PSPossibleIncorrectComparisonWithNull" -$violations = Invoke-ScriptAnalyzer $PSScriptRoot\PossibleIncorrectComparisonWithNull.ps1 | Where-Object {$_.RuleName -eq $violationName} -$noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\PossibleIncorrectComparisonWithNullNoViolations.ps1 | Where-Object {$_.RuleName -eq $violationName} +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +BeforeAll { + $violationMessage = [regex]::Escape('$null should be on the left side of equality comparisons.') + $violationName = "PSPossibleIncorrectComparisonWithNull" + $violations = Invoke-ScriptAnalyzer $PSScriptRoot\PossibleIncorrectComparisonWithNull.ps1 | Where-Object {$_.RuleName -eq $violationName} + $noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\PossibleIncorrectComparisonWithNullNoViolations.ps1 | Where-Object {$_.RuleName -eq $violationName} +} Describe "PossibleIncorrectComparisonWithNull" { Context "When there are violations" { diff --git a/Tests/Rules/PossibleIncorrectUsageOfAssignmentOperator.tests.ps1 b/Tests/Rules/PossibleIncorrectUsageOfAssignmentOperator.tests.ps1 index 8d5996965..0612a8922 100644 --- a/Tests/Rules/PossibleIncorrectUsageOfAssignmentOperator.tests.ps1 +++ b/Tests/Rules/PossibleIncorrectUsageOfAssignmentOperator.tests.ps1 @@ -1,4 +1,9 @@ -$ruleName = "PSPossibleIncorrectUsageOfAssignmentOperator" +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +BeforeAll { + $ruleName = "PSPossibleIncorrectUsageOfAssignmentOperator" +} Describe "PossibleIncorrectUsageOfComparisonOperator" { Context "When there are violations" { diff --git a/Tests/Rules/PossibleIncorrectUsageOfRedirectionOperator.tests.ps1 b/Tests/Rules/PossibleIncorrectUsageOfRedirectionOperator.tests.ps1 index 3b1a4791d..4fbf1e4b7 100644 --- a/Tests/Rules/PossibleIncorrectUsageOfRedirectionOperator.tests.ps1 +++ b/Tests/Rules/PossibleIncorrectUsageOfRedirectionOperator.tests.ps1 @@ -1,5 +1,10 @@ -Import-Module PSScriptAnalyzer -$ruleName = "PSPossibleIncorrectUsageOfRedirectionOperator" +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +BeforeAll { + Import-Module PSScriptAnalyzer + $ruleName = "PSPossibleIncorrectUsageOfRedirectionOperator" +} Describe "PossibleIncorrectUsageOfComparisonOperator" { Context "When there are violations" { diff --git a/Tests/Rules/ProvideCommentHelp.tests.ps1 b/Tests/Rules/ProvideCommentHelp.tests.ps1 index 6ab2504e9..ca6fd06a4 100644 --- a/Tests/Rules/ProvideCommentHelp.tests.ps1 +++ b/Tests/Rules/ProvideCommentHelp.tests.ps1 @@ -1,45 +1,50 @@ -$testRootDirectory = Split-Path -Parent $PSScriptRoot -Import-Module (Join-Path $testRootDirectory "PSScriptAnalyzerTestHelper.psm1") - -$violationMessage = "The cmdlet 'Comment' does not have a help comment." -$violationName = "PSProvideCommentHelp" -$ruleSettings = @{ - Enable = $true - ExportedOnly = $false - BlockComment = $true - Placement = "before" - VSCodeSnippetCorrection = $false -} +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +BeforeAll { + $testRootDirectory = Split-Path -Parent $PSScriptRoot + Import-Module (Join-Path $testRootDirectory "PSScriptAnalyzerTestHelper.psm1") + + $violationMessage = "The cmdlet 'Comment' does not have a help comment." + $violationName = "PSProvideCommentHelp" + $ruleSettings = @{ + Enable = $true + ExportedOnly = $false + BlockComment = $true + Placement = "before" + VSCodeSnippetCorrection = $false + } -$settings = @{ - IncludeRules = @("PSProvideCommentHelp") - Rules = @{ PSProvideCommentHelp = $ruleSettings } -} + $settings = @{ + IncludeRules = @("PSProvideCommentHelp") + Rules = @{ PSProvideCommentHelp = $ruleSettings } + } -$violations = Invoke-ScriptAnalyzer $PSScriptRoot\BadCmdlet.ps1 | Where-Object {$_.RuleName -eq $violationName} + $violations = Invoke-ScriptAnalyzer $PSScriptRoot\BadCmdlet.ps1 | Where-Object {$_.RuleName -eq $violationName} -if ($PSVersionTable.PSVersion -ge [Version]'5.0.0') { - $dscViolations = Invoke-ScriptAnalyzer -ErrorAction SilentlyContinue $PSScriptRoot\DSCResourceModule\DSCResources\MyDscResource\MyDscResource.psm1 | Where-Object {$_.RuleName -eq $violationName} -} + if ($PSVersionTable.PSVersion -ge [Version]'5.0.0') { + $dscViolations = Invoke-ScriptAnalyzer -ErrorAction SilentlyContinue $PSScriptRoot\DSCResourceModule\DSCResources\MyDscResource\MyDscResource.psm1 | Where-Object {$_.RuleName -eq $violationName} + } -$noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\GoodCmdlet.ps1 | Where-Object {$_.RuleName -eq $violationName} + $noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\GoodCmdlet.ps1 | Where-Object {$_.RuleName -eq $violationName} -function Test-Correction { - param($scriptDef, $expectedCorrection, $settings) + function Test-Correction { + param($scriptDef, $expectedCorrection, $settings) - $violations = Invoke-ScriptAnalyzer -ScriptDefinition $scriptDef -Settings $settings - $violations.Count | Should -Be 1 + $violations = Invoke-ScriptAnalyzer -ScriptDefinition $scriptDef -Settings $settings + $violations.Count | Should -Be 1 - # We split the lines because appveyor checks out files with "\n" endings - # on windows, which results in inconsistent line endings between corrections - # and result. - $resultLines = $violations[0].SuggestedCorrections[0].Text -split "\r?\n" - $expectedLines = $expectedCorrection -split "\r?\n" - $resultLines.Count | Should -Be $expectedLines.Count - for ($i = 0; $i -lt $resultLines.Count; $i++) { - $resultLine = $resultLines[$i] - $expectedLine = $expectedLines[$i] - $resultLine | Should -Be $expectedLine + # We split the lines because appveyor checks out files with "\n" endings + # on windows, which results in inconsistent line endings between corrections + # and result. + $resultLines = $violations[0].SuggestedCorrections[0].Text -split "\r?\n" + $expectedLines = $expectedCorrection -split "\r?\n" + $resultLines.Count | Should -Be $expectedLines.Count + for ($i = 0; $i -lt $resultLines.Count; $i++) { + $resultLine = $resultLines[$i] + $expectedLine = $expectedLines[$i] + $resultLine | Should -Be $expectedLine + } } } @@ -329,10 +334,8 @@ $s$s$s$s } - if ($PSVersionTable.PSVersion -ge [Version]'5.0.0') { - It "Does not count violation in DSC class" { - $dscViolations.Count | Should -Be 0 - } + It "Does not count violation in DSC class" -Skip:($PSVersionTable.PSVersion -lt [Version]'5.0.0') { + $dscViolations.Count | Should -Be 0 } } diff --git a/Tests/Rules/ReturnCorrectTypesForDSCFunctions.tests.ps1 b/Tests/Rules/ReturnCorrectTypesForDSCFunctions.tests.ps1 index 78b5f91e2..629534ca3 100644 --- a/Tests/Rules/ReturnCorrectTypesForDSCFunctions.tests.ps1 +++ b/Tests/Rules/ReturnCorrectTypesForDSCFunctions.tests.ps1 @@ -1,13 +1,18 @@ -$violationMessageDSCResource = "Test-TargetResource function in DSC Resource should return object of type System.Boolean instead of System.Collections.Hashtable" -$violationMessageDSCClass = "Get function in DSC Class FileResource should return object of type FileResource instead of type System.Collections.Hashtable" -$violationName = "PSDSCReturnCorrectTypesForDSCFunctions" -$violations = Invoke-ScriptAnalyzer $PSScriptRoot\DSCResourceModule\DSCResources\MSFT_WaitForAll\MSFT_WaitForAll.psm1 | Where-Object {$_.RuleName -eq $violationName} -$noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\DSCResourceModule\DSCResources\MSFT_WaitForAny\MSFT_WaitForAny.psm1 | Where-Object {$_.RuleName -eq $violationName} - -if ($PSVersionTable.PSVersion -ge [Version]'5.0.0') -{ - $classViolations = Invoke-ScriptAnalyzer -ErrorAction SilentlyContinue $PSScriptRoot\DSCResourceModule\DSCResources\BadDscResource\BadDscResource.psm1 | Where-Object {$_.RuleName -eq $violationName} - $noClassViolations = Invoke-ScriptAnalyzer -ErrorAction SilentlyContinue $PSScriptRoot\DSCResourceModule\DSCResources\MyDscResource\MyDscResource.psm1 | Where-Object {$_.RuleName -eq $violationName} +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +BeforeAll { + $violationMessageDSCResource = "Test-TargetResource function in DSC Resource should return object of type System.Boolean instead of System.Collections.Hashtable" + $violationMessageDSCClass = "Get function in DSC Class FileResource should return object of type FileResource instead of type System.Collections.Hashtable" + $violationName = "PSDSCReturnCorrectTypesForDSCFunctions" + $violations = Invoke-ScriptAnalyzer $PSScriptRoot\DSCResourceModule\DSCResources\MSFT_WaitForAll\MSFT_WaitForAll.psm1 | Where-Object {$_.RuleName -eq $violationName} + $noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\DSCResourceModule\DSCResources\MSFT_WaitForAny\MSFT_WaitForAny.psm1 | Where-Object {$_.RuleName -eq $violationName} + + if ($PSVersionTable.PSVersion -ge [Version]'5.0.0') + { + $classViolations = Invoke-ScriptAnalyzer -ErrorAction SilentlyContinue $PSScriptRoot\DSCResourceModule\DSCResources\BadDscResource\BadDscResource.psm1 | Where-Object {$_.RuleName -eq $violationName} + $noClassViolations = Invoke-ScriptAnalyzer -ErrorAction SilentlyContinue $PSScriptRoot\DSCResourceModule\DSCResources\MyDscResource\MyDscResource.psm1 | Where-Object {$_.RuleName -eq $violationName} + } } Describe "ReturnCorrectTypesForDSCFunctions" { @@ -28,8 +33,7 @@ Describe "ReturnCorrectTypesForDSCFunctions" { } } -if ($PSVersionTable.PSVersion -ge [Version]'5.0.0') { - Describe "StandardDSCFunctionsInClass" { + Describe "StandardDSCFunctionsInClass" -Skip:($PSVersionTable.PSVersion -lt [Version]'5.0.0') { Context "When there are violations" { It "has 4 return correct types for DSC functions violations" { $classViolations.Count | Should -Be 4 @@ -45,5 +49,4 @@ if ($PSVersionTable.PSVersion -ge [Version]'5.0.0') { $noClassViolations.Count | Should -Be 0 } } - } } diff --git a/Tests/Rules/ReviewUnusedParameter.tests.ps1 b/Tests/Rules/ReviewUnusedParameter.tests.ps1 index f5d6004cc..0b7598e7a 100644 --- a/Tests/Rules/ReviewUnusedParameter.tests.ps1 +++ b/Tests/Rules/ReviewUnusedParameter.tests.ps1 @@ -1,3 +1,6 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + Describe "ReviewUnusedParameter" { BeforeAll { $RuleName = 'PSReviewUnusedParameter' diff --git a/Tests/Rules/UseBOMForUnicodeEncodedFile.tests.ps1 b/Tests/Rules/UseBOMForUnicodeEncodedFile.tests.ps1 index ba992d43e..bf325ef06 100644 --- a/Tests/Rules/UseBOMForUnicodeEncodedFile.tests.ps1 +++ b/Tests/Rules/UseBOMForUnicodeEncodedFile.tests.ps1 @@ -1,10 +1,15 @@ -$violationMessageOne = "Missing BOM encoding for non-ASCII encoded file 'BOMAbsent_UTF16EncodedScript.ps1'" -$violationMessageTwo = "Missing BOM encoding for non-ASCII encoded file 'BOMAbsent_UnknownEncodedScript.ps1'" -$violationName = "PSUseBOMForUnicodeEncodedFile" -$violationsOne = Invoke-ScriptAnalyzer "$PSScriptRoot\TestFiles\BOMAbsent_UTF16EncodedScript.ps1" | Where-Object {$_.RuleName -eq $violationName} -$violationsTwo = Invoke-ScriptAnalyzer "$PSScriptRoot\TestFiles\BOMAbsent_UnknownEncodedScript.ps1" | Where-Object {$_.RuleName -eq $violationName} -$noViolationsOne = Invoke-ScriptAnalyzer "$PSScriptRoot\TestFiles\BOMPresent_UTF16EncodedScript.ps1" | Where-Object {$_.RuleName -eq $violationName} -$noViolationsTwo = Invoke-ScriptAnalyzer "$PSScriptRoot\TestFiles\BOMAbsent_ASCIIEncodedScript.ps1" | Where-Object {$_.RuleName -eq $violationName} +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +BeforeAll { + $violationMessageOne = "Missing BOM encoding for non-ASCII encoded file 'BOMAbsent_UTF16EncodedScript.ps1'" + $violationMessageTwo = "Missing BOM encoding for non-ASCII encoded file 'BOMAbsent_UnknownEncodedScript.ps1'" + $violationName = "PSUseBOMForUnicodeEncodedFile" + $violationsOne = Invoke-ScriptAnalyzer "$PSScriptRoot\TestFiles\BOMAbsent_UTF16EncodedScript.ps1" | Where-Object {$_.RuleName -eq $violationName} + $violationsTwo = Invoke-ScriptAnalyzer "$PSScriptRoot\TestFiles\BOMAbsent_UnknownEncodedScript.ps1" | Where-Object {$_.RuleName -eq $violationName} + $noViolationsOne = Invoke-ScriptAnalyzer "$PSScriptRoot\TestFiles\BOMPresent_UTF16EncodedScript.ps1" | Where-Object {$_.RuleName -eq $violationName} + $noViolationsTwo = Invoke-ScriptAnalyzer "$PSScriptRoot\TestFiles\BOMAbsent_ASCIIEncodedScript.ps1" | Where-Object {$_.RuleName -eq $violationName} +} Describe "UseBOMForUnicodeEncodedFile" { Context "When there are violations" { diff --git a/Tests/Rules/UseCmdletCorrectly.tests.ps1 b/Tests/Rules/UseCmdletCorrectly.tests.ps1 index 207036eb1..145821326 100644 --- a/Tests/Rules/UseCmdletCorrectly.tests.ps1 +++ b/Tests/Rules/UseCmdletCorrectly.tests.ps1 @@ -1,7 +1,13 @@ -$violationMessage = "Cmdlet 'Write-Warning' may be used incorrectly. Please check that all mandatory parameters are supplied." -$violationName = "PSUseCmdletCorrectly" -$violations = Invoke-ScriptAnalyzer $PSScriptRoot\UseCmdletCorrectly.ps1 | Where-Object {$_.RuleName -eq $violationName} -$noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\GoodCmdlet.ps1 | Where-Object {$_.RuleName -eq $violationName} + +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +BeforeAll { + $violationMessage = "Cmdlet 'Write-Warning' may be used incorrectly. Please check that all mandatory parameters are supplied." + $violationName = "PSUseCmdletCorrectly" + $violations = Invoke-ScriptAnalyzer $PSScriptRoot\UseCmdletCorrectly.ps1 | Where-Object {$_.RuleName -eq $violationName} + $noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\GoodCmdlet.ps1 | Where-Object {$_.RuleName -eq $violationName} +} Describe "UseCmdletCorrectly" { Context "When there are violations" { diff --git a/Tests/Rules/UseCompatibleCmdlets.tests.ps1 b/Tests/Rules/UseCompatibleCmdlets.tests.ps1 index d4db68502..b2c055c94 100644 --- a/Tests/Rules/UseCompatibleCmdlets.tests.ps1 +++ b/Tests/Rules/UseCompatibleCmdlets.tests.ps1 @@ -1,8 +1,12 @@ -$ruleName = "PSUseCompatibleCmdlets" -$testRootDirectory = Split-Path -Parent $PSScriptRoot -$ruleTestDirectory = Join-Path $PSScriptRoot 'UseCompatibleCmdlets' +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. -Import-Module (Join-Path $testRootDirectory 'PSScriptAnalyzerTestHelper.psm1') +BeforeAll { + $ruleName = "PSUseCompatibleCmdlets" + $testRootDirectory = Split-Path -Parent $PSScriptRoot + $ruleTestDirectory = Join-Path $PSScriptRoot 'UseCompatibleCmdlets' + Import-Module (Join-Path $testRootDirectory 'PSScriptAnalyzerTestHelper.psm1') +} Describe "UseCompatibleCmdlets" { Context "script has violation" { diff --git a/Tests/Rules/UseCompatibleCommands.Tests.ps1 b/Tests/Rules/UseCompatibleCommands.Tests.ps1 index 2e38ba7e3..78a98c671 100644 --- a/Tests/Rules/UseCompatibleCommands.Tests.ps1 +++ b/Tests/Rules/UseCompatibleCommands.Tests.ps1 @@ -1,242 +1,245 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. -$script:RunningInCIOnUbuntu = $IsLinux -and ($env:TF_BUILD -or $env:APPVEYOR) # some test cases randomly start and stop to fail in Ubuntu CI tests -$script:RuleName = 'PSUseCompatibleCommands' -$script:AnyProfileConfigKey = 'AnyProfilePath' -$script:TargetProfileConfigKey = 'TargetProfiles' - -$script:Srv2012_3_profile = 'win-8_x64_6.2.9200.0_3.0_x64_4.0.30319.42000_framework' -$script:Srv2012r2_4_profile = 'win-8_x64_6.3.9600.0_4.0_x64_4.0.30319.42000_framework' -$script:Srv2016_5_profile = 'win-8_x64_10.0.14393.0_5.1.14393.2791_x64_4.0.30319.42000_framework' -$script:Srv2016_6_2_profile = 'win-8_x64_10.0.14393.0_6.2.4_x64_4.0.30319.42000_core' -$script:Srv2016_7_profile = 'win-8_x64_10.0.14393.0_7.0.0_x64_3.1.2_core' -$script:Srv2019_5_profile = 'win-8_x64_10.0.17763.0_5.1.17763.316_x64_4.0.30319.42000_framework' -$script:Srv2019_6_2_profile = 'win-8_x64_10.0.17763.0_6.2.4_x64_4.0.30319.42000_core' -$script:Srv2019_7_profile = 'win-8_x64_10.0.17763.0_7.0.0_x64_3.1.2_core' -$script:Win10_5_profile = 'win-48_x64_10.0.17763.0_5.1.17763.316_x64_4.0.30319.42000_framework' -$script:Win10_6_2_profile = 'win-4_x64_10.0.18362.0_6.2.4_x64_4.0.30319.42000_core' -$script:Win10_7_profile = 'win-4_x64_10.0.18362.0_7.0.0_x64_3.1.2_core' -$script:Ubuntu1804_6_2_profile = 'ubuntu_x64_18.04_6.2.4_x64_4.0.30319.42000_core' -$script:Ubuntu1804_7_profile = 'ubuntu_x64_18.04_7.0.0_x64_3.1.2_core' - -$script:AzF_profile = (Resolve-Path "$PSScriptRoot/../../PSCompatibilityCollector/optional_profiles/azurefunctions.json").Path -$script:AzA_profile = (Resolve-Path "$PSScriptRoot/../../PSCompatibilityCollector/optional_profiles/azureautomation.json").Path - -$script:CompatibilityTestCases = @( - @{ Target = $script:Srv2012_3_profile; Script = 'Write-Information "Information"'; Commands = @("Write-Information"); Version = "3.0"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2012_3_profile; Script = '"Hello World" | ConvertFrom-String | Get-Member'; Commands = @("ConvertFrom-String"); Version = "3.0"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2012_3_profile; Script = 'Compress-Archive -LiteralPath C:\Reference\Draftdoc.docx, C:\Reference\Images\diagram2.vsd -CompressionLevel Optimal -DestinationPath C:\Archives\Draft.Zip'; Commands = @("Compress-Archive"); Version = "3.0"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2012_3_profile; Script = 'Get-Runspace -Id 2'; Commands = @("Get-Runspace"); Version = "3.0"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2012_3_profile; Script = '$Protected = "Hello World" | Protect-CmsMessage -To "*youralias@emailaddress.com*"'; Commands = @("Protect-CmsMessage"); Version = "3.0"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2012_3_profile; Script = 'Format-Hex -Path "C:\temp\temp.t7f"'; Commands = @("Format-Hex"); Version = "3.0"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2012_3_profile; Script = 'Set-Clipboard -Value "This is a test string"'; Commands = @("Set-Clipboard"); Version = "3.0"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2012_3_profile; Script = 'Clear-RecycleBin -Force'; Commands = @("Clear-RecycleBin"); Version = "3.0"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2012_3_profile; Script = '$TempFile = New-TemporaryFile'; Commands = @("New-TemporaryFile"); Version = "3.0"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2012_3_profile; Script = 'New-Guid | Out-String'; Commands = @("New-Guid"); Version = "3.0"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2012_3_profile; Script = 'Enter-PSHostProcess -Name powershell_ise'; Commands = @("Enter-PSHostProcess"); Version = "3.0"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2012_3_profile; Script = 'Wait-Debugger'; Commands = @("Wait-Debugger"); Version = "3.0"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2012_3_profile; Script = 'Start-Job { Write-Host "Hello" } | Debug-Job'; Commands = @("Debug-Job"); Version = "3.0"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2012_3_profile; Script = 'Get-ItemPropertyValue -Path HKLM:\SOFTWARE\Microsoft\PowerShell\3\PowerShellEngine -Name ApplicationBase'; Commands = @("Get-ItemPropertyValue"); Version = "3.0"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2012_3_profile; Script = 'Get-FileHash $pshome\powershell.exe | Format-List'; Commands = @("Get-FileHash"); Version = "3.0"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2012_3_profile; Script = 'Get-ChildItem ./ | Format-List'; Commands = @(); Version = "3.0"; OS = "Windows"; ProblemCount = 0 } - @{ Target = $script:Srv2012_3_profile; Script = 'Save-Help -Module $m -DestinationPath "C:\SavedHelp"'; Commands = @(); Version = "3.0"; OS = "Windows"; ProblemCount = 0 } - @{ Target = $script:Srv2012_3_profile; Script = 'gci .'; Commands = @(); Version = "3.0"; OS = "Windows"; ProblemCount = 0 } - @{ Target = $script:Srv2012_3_profile; Script = 'iex $expr | % { Transform $_ }'; Commands = @(); Version = "3.0"; OS = "Windows"; ProblemCount = 0 } - - @{ Target = $script:Srv2012r2_4_profile; Script = 'Write-Information "Information"'; Commands = @("Write-Information"); Version = "4.0"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2012r2_4_profile; Script = '"Hello World" | ConvertFrom-String | Get-Member'; Commands = @("ConvertFrom-String"); Version = "4.0"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2012r2_4_profile; Script = 'Compress-Archive -LiteralPath C:\Reference\Draftdoc.docx, C:\Reference\Images\diagram2.vsd -CompressionLevel Optimal -DestinationPath C:\Archives\Draft.Zip'; Commands = @("Compress-Archive"); Version = "4.0"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2012r2_4_profile; Script = 'Get-Runspace -Id 2'; Commands = @("Get-Runspace"); Version = "4.0"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2012r2_4_profile; Script = 'Format-Hex -Path "C:\temp\temp.t7f"'; Commands = @("Format-Hex"); Version = "4.0"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2012r2_4_profile; Script = 'Set-Clipboard -Value "This is a test string"'; Commands = @("Set-Clipboard"); Version = "4.0"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2012r2_4_profile; Script = 'Clear-RecycleBin -Force'; Commands = @("Clear-RecycleBin"); Version = "4.0"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2012r2_4_profile; Script = '$TempFile = New-TemporaryFile'; Commands = @("New-TemporaryFile"); Version = "4.0"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2012r2_4_profile; Script = 'New-Guid | Out-String'; Commands = @("New-Guid"); Version = "4.0"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2012r2_4_profile; Script = 'Enter-PSHostProcess -Name powershell_ise'; Commands = @("Enter-PSHostProcess"); Version = "4.0"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2012r2_4_profile; Script = 'Wait-Debugger'; Commands = @("Wait-Debugger"); Version = "4.0"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2012r2_4_profile; Script = 'Start-Job { Write-Host "Hello" } | Debug-Job'; Commands = @("Debug-Job"); Version = "4.0"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2012r2_4_profile; Script = 'Get-ItemPropertyValue -Path HKLM:\SOFTWARE\Microsoft\PowerShell\3\PowerShellEngine -Name ApplicationBase'; Commands = @("Get-ItemPropertyValue"); Version = "4.0"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2012r2_4_profile; Script = 'Get-ChildItem ./ | Format-List'; Commands = @(); Version = "3.0"; OS = "Windows"; ProblemCount = 0 } - @{ Target = $script:Srv2012r2_4_profile; Script = 'gci .'; Commands = @(); Version = "4.0"; OS = "Windows"; ProblemCount = 0 } - @{ Target = $script:Srv2012r2_4_profile; Script = 'iex $expr | % { Transform $_ }'; Commands = @(); Version = "4.0"; OS = "Windows"; ProblemCount = 0 } - - @{ Target = $script:Srv2019_5_profile; Script = "Remove-Alias gcm"; Commands = @("Remove-Alias"); Version = "5.1"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2019_5_profile; Script = "Get-Uptime"; Commands = @("Get-Uptime"); Version = "5.1"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2019_5_profile; Script = "Remove-Service 'MyService'"; Commands = @("Remove-Service"); Version = "5.1"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2019_5_profile; Script = 'Get-ChildItem ./ | Format-List'; Commands = @(); Version = "3.0"; OS = "Windows"; ProblemCount = 0 } - @{ Target = $script:Srv2019_5_profile; Script = 'gci .'; Commands = @(); Version = "5.1"; OS = "Windows"; ProblemCount = 0 } - @{ Target = $script:Srv2019_5_profile; Script = 'iex $expr | % { Transform $_ }'; Commands = @(); Version = "5.1"; OS = "Windows"; ProblemCount = 0 } - @{ Target = $script:Srv2019_5_profile; Script = 'fhx $filePath'; Commands = @(); Version = "5.1"; OS = "Windows"; ProblemCount = 0 } - - @{ Target = $script:Srv2019_6_2_profile; Script = "Add-PSSnapIn MySnapIn"; Commands = @("Add-PSSnapIn"); Version = "6.2"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2019_6_2_profile; Script = "Get-PSSnapIn MySnapIn"; Commands = @("Get-PSSnapIn"); Version = "6.2"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2019_6_2_profile; Script = "Get-Content $pshome\about_signing.help.txt | Out-Printer"; Commands = @("Out-Printer"); Version = "6.2"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2019_6_2_profile; Script = 'New-PSWorkflowSession -ComputerName "ServerNode01" -Name "WorkflowTests" -SessionOption (New-PSSessionOption -OutputBufferingMode Drop)'; Commands = @("New-PSWorkflowSession"); Version = "6.2"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2019_6_2_profile; Script = "Get-Process | Out-GridView"; Commands = @("Out-GridView"); Version = "6.2"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2019_6_2_profile; Script = "Get-Process | ogv"; Commands = @("ogv"); Version = "6.2"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2019_6_2_profile; Script = "Remove-PSSnapIn MySnapIn"; Commands = @("Remove-PSSnapIn"); Version = "6.2"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2019_6_2_profile; Script = "Show-Command"; Commands = @("Show-Command"); Version = "6.2"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2019_6_2_profile; Script = '$composers | Convert-String -Example "first middle last=last, first"'; Commands = @("Convert-String"); Version = "6.2"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2019_6_2_profile; Script = 'Export-Console -Path $pshome\Consoles\ConsoleS1.psc1'; Commands = @("Export-Console"); Version = "6.2"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2019_6_2_profile; Script = 'Get-Counter "\Processor(*)\% Processor Time" | Export-Counter -Path $home\Counters.blg'; Commands = @("Get-Counter", "Export-Counter"); Version = "6.2"; OS = "Windows"; ProblemCount = 2 } - @{ Target = $script:Srv2019_6_2_profile; Script = 'curl $uri'; Commands = @("curl"); Version = "6.2"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2019_6_2_profile; Script = 'Get-ChildItem ./ | Format-List'; Commands = @(); Version = "3.0"; OS = "Windows"; ProblemCount = 0 } - @{ Target = $script:Srv2019_6_2_profile; Script = 'gci .'; Commands = @(); Version = "6.2"; OS = "Windows"; ProblemCount = 0 } - @{ Target = $script:Srv2016_6_2_profile; Script = 'iex $expr | % { Transform $_ }'; Commands = @(); Version = "6.2"; OS = "Windows"; ProblemCount = 0 } - @{ Target = $script:Srv2019_6_2_profile; Script = 'ConvertFrom-String $str'; Commands = @("ConvertFrom-String"); Version = "6.2"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2019_6_2_profile; Script = "Get-WmiObject -Class Win32_Process"; Commands = @("Get-WmiObject"); Version = "6.2"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2019_6_2_profile; Script = "Invoke-WmiMethod -Path win32_process -Name create -ArgumentList notepad.exe"; Commands = @("Invoke-WmiMethod"); Version = "6.2"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2019_6_2_profile; Script = '$np | Remove-WmiObject'; Commands = @("Remove-WmiObject"); Version = "6.2"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2019_6_2_profile; Script = 'Set-Clipboard -Value "This is a test string"'; Commands = @("Set-Clipboard"); Version = "6.2"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2019_6_2_profile; Script = "Set-WmiInstance -Class Win32_WMISetting -Argument @{LoggingLevel=2}"; Commands = @("Set-WmiInstance"); Version = "6.2"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2019_6_2_profile; Script = 'Add-Computer -DomainName "Domain01" -Restart'; Commands = @("Add-Computer"); Version = "6.2"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2019_6_2_profile; Script = 'Checkpoint-Computer -Description "Install MyApp"'; Commands = @("Checkpoint-Computer"); Version = "6.2"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2019_6_2_profile; Script = 'Clear-EventLog "Windows PowerShell"'; Commands = @("Clear-EventLog"); Version = "6.2"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2019_6_2_profile; Script = 'Clear-RecycleBin'; Commands = @("Clear-RecycleBin"); Version = "6.2"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2019_6_2_profile; Script = 'Start-Transaction; New-Item MyCompany -UseTransaction; Complete-Transaction'; Commands = @("Start-Transaction", "Complete-Transaction"); Version = "6.2"; OS = "Windows"; ProblemCount = 2 } - @{ Target = $script:Srv2019_6_2_profile; Script = 'Disable-ComputerRestore -Drive "C:\"'; Commands = @("Disable-ComputerRestore"); Version = "6.2"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2019_6_2_profile; Script = 'Enable-ComputerRestore -Drive "C:\", "D:\"'; Commands = @("Enable-ComputerRestore"); Version = "6.2"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2019_6_2_profile; Script = 'Get-ControlPanelItem -Name "*Program*", "*App*"'; Commands = @("Get-ControlPanelItem"); Version = "6.2"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2019_6_2_profile; Script = 'Get-EventLog -Newest 5 -LogName "Application"'; Commands = @("Get-EventLog"); Version = "6.2"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2019_6_2_profile; Script = 'Get-HotFix -Description "Security*" -ComputerName "Server01", "Server02" -Cred "Server01\admin01"'; Commands = @("Get-HotFix"); Version = "6.2"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2019_6_2_profile; Script = '$zip = New-WebServiceProxy -Uri "http://www.webservicex.net/uszip.asmx?WSDL"'; Commands = @("New-WebServiceProxy"); Version = "6.2"; OS = "Windows"; ProblemCount = 1 } - - @{ Target = $script:Srv2019_7_profile; Script = "Add-PSSnapIn MySnapIn"; Commands = @("Add-PSSnapIn"); Version = "7.0"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2019_7_profile; Script = "Get-PSSnapIn MySnapIn"; Commands = @("Get-PSSnapIn"); Version = "7.0"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2019_7_profile; Script = "Get-Content $pshome\about_signing.help.txt | Out-Printer"; Commands = @(); Version = "7.0"; OS = "Windows"; ProblemCount = 0 } - @{ Target = $script:Srv2019_7_profile; Script = 'New-PSWorkflowSession -ComputerName "ServerNode01" -Name "WorkflowTests" -SessionOption (New-PSSessionOption -OutputBufferingMode Drop)'; Commands = @("New-PSWorkflowSession"); Version = "7.0"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2019_7_profile; Script = "Get-Process | Out-GridView"; Commands = @(); Version = "7.0"; OS = "Windows"; ProblemCount = 0 } - @{ Target = $script:Srv2019_7_profile; Script = "Get-Process | ogv"; Commands = @(); Version = "7.0"; OS = "Windows"; ProblemCount = 0 } - @{ Target = $script:Srv2019_7_profile; Script = "Remove-PSSnapIn MySnapIn"; Commands = @("Remove-PSSnapIn"); Version = "7.0"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2019_7_profile; Script = "Show-Command"; Commands = @(); Version = "7.0"; OS = "Windows"; ProblemCount = 0 } - @{ Target = $script:Srv2019_7_profile; Script = '$composers | Convert-String -Example "first middle last=last, first"'; Commands = @("Convert-String"); Version = "7.0"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2019_7_profile; Script = 'Export-Console -Path $pshome\Consoles\ConsoleS1.psc1'; Commands = @("Export-Console"); Version = "7.0"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2019_7_profile; Script = 'Get-ChildItem ./ | Format-List'; Commands = @(); Version = "7.0"; OS = "Windows"; ProblemCount = 0 } - @{ Target = $script:Srv2019_7_profile; Script = 'gci .'; Commands = @(); Version = "7.0"; OS = "Windows"; ProblemCount = 0 } - @{ Target = $script:Srv2016_7_profile; Script = 'iex $expr | % { Transform $_ }'; Commands = @(); Version = "7.0"; OS = "Windows"; ProblemCount = 0 } - @{ Target = $script:Srv2019_7_profile; Script = 'ConvertFrom-String $str'; Commands = @("ConvertFrom-String"); Version = "7.0"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2019_7_profile; Script = "Get-WmiObject -Class Win32_Process"; Commands = @("Get-WmiObject"); Version = "7.0"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2019_7_profile; Script = "Invoke-WmiMethod -Path win32_process -Name create -ArgumentList notepad.exe"; Commands = @("Invoke-WmiMethod"); Version = "7.0"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2019_7_profile; Script = '$np | Remove-WmiObject'; Commands = @("Remove-WmiObject"); Version = "7.0"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2019_7_profile; Script = 'Set-Clipboard -Value "This is a test string"'; Commands = @(); Version = "7.0"; OS = "Windows"; ProblemCount = 0 } - @{ Target = $script:Srv2019_7_profile; Script = "Set-WmiInstance -Class Win32_WMISetting -Argument @{LoggingLevel=2}"; Commands = @("Set-WmiInstance"); Version = "7.0"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2019_7_profile; Script = 'Add-Computer -DomainName "Domain01" -Restart'; Commands = @("Add-Computer"); Version = "7.0"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2019_7_profile; Script = 'Checkpoint-Computer -Description "Install MyApp"'; Commands = @("Checkpoint-Computer"); Version = "7.0"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2019_7_profile; Script = 'Clear-EventLog "Windows PowerShell"'; Commands = @("Clear-EventLog"); Version = "7.0"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2019_7_profile; Script = 'Clear-RecycleBin'; Commands = @(); Version = "7.0"; OS = "Windows"; ProblemCount = 0 } - @{ Target = $script:Srv2019_7_profile; Script = 'Start-Transaction; New-Item MyCompany -UseTransaction; Complete-Transaction'; Commands = @("Start-Transaction", "Complete-Transaction"); Version = "7.0"; OS = "Windows"; ProblemCount = 2 } - @{ Target = $script:Srv2019_7_profile; Script = 'Disable-ComputerRestore -Drive "C:\"'; Commands = @("Disable-ComputerRestore"); Version = "7.0"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2019_7_profile; Script = 'Enable-ComputerRestore -Drive "C:\", "D:\"'; Commands = @("Enable-ComputerRestore"); Version = "7.0"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2019_7_profile; Script = 'Get-ControlPanelItem -Name "*Program*", "*App*"'; Commands = @("Get-ControlPanelItem"); Version = "7.0"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2019_7_profile; Script = 'Get-EventLog -Newest 5 -LogName "Application"'; Commands = @("Get-EventLog"); Version = "7.0"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2019_7_profile; Script = 'Get-HotFix -Description "Security*" -ComputerName "Server01", "Server02" -Cred "Server01\admin01"'; Commands = @(); Version = "7.0"; OS = "Windows"; ProblemCount = 0 } - @{ Target = $script:Srv2019_7_profile; Script = '$zip = New-WebServiceProxy -Uri "http://www.webservicex.net/uszip.asmx?WSDL"'; Commands = @("New-WebServiceProxy"); Version = "7.0"; OS = "Windows"; ProblemCount = 1 } - - @{ Target = $script:Ubuntu1804_6_2_profile; Script = 'Get-AuthenticodeSignature ./script.ps1'; Commands = @("Get-AuthenticodeSignature"); Version = "6.2"; OS = "Linux"; ProblemCount = 1 } - @{ Target = $script:Ubuntu1804_6_2_profile; Script = 'Get-Service systemd'; Commands = @("Get-Service"); Version = "6.2"; OS = "Linux"; ProblemCount = 1 } - @{ Target = $script:Ubuntu1804_6_2_profile; Script = 'Start-Service -Name "sshd"'; Commands = @("Start-Service"); Version = "6.2"; OS = "Linux"; ProblemCount = 1 } - @{ Target = $script:Ubuntu1804_6_2_profile; Script = 'Get-PSSessionConfiguration -Name Full | Format-List -Property *'; Commands = @("Get-PSSessionConfiguration"); Version = "6.2"; OS = "Linux"; ProblemCount = 1 } - @{ Target = $script:Ubuntu1804_6_2_profile; Script = 'Get-CimInstance Win32_StartupCommand'; Commands = @("Get-CimInstance"); Version = "6.2"; OS = "Linux"; ProblemCount = 1 } - @{ Target = $script:Ubuntu1804_6_2_profile; Script = 'Get-ChildItem ./ | Format-List'; Commands = @(); Version = "6.2"; OS = "Linux"; ProblemCount = 0 } - @{ Target = $script:Ubuntu1804_6_2_profile; Script = 'gci .'; Commands = @(); Version = "6.2"; OS = "Linux"; ProblemCount = 0 } - @{ Target = $script:Ubuntu1804_6_2_profile; Script = 'iex $expr | % { Transform $_ }'; Commands = @(); Version = "6.2"; OS = "Linux"; ProblemCount = 0 } - - @{ Target = $script:Ubuntu1804_7_profile; Script = 'Get-AuthenticodeSignature ./script.ps1'; Commands = @("Get-AuthenticodeSignature"); Version = "7.0"; OS = "Linux"; ProblemCount = 1 } - @{ Target = $script:Ubuntu1804_7_profile; Script = 'Get-Service systemd'; Commands = @("Get-Service"); Version = "7.0"; OS = "Linux"; ProblemCount = 1 } - @{ Target = $script:Ubuntu1804_7_profile; Script = 'Start-Service -Name "sshd"'; Commands = @("Start-Service"); Version = "7.0"; OS = "Linux"; ProblemCount = 1 } - @{ Target = $script:Ubuntu1804_7_profile; Script = 'Get-PSSessionConfiguration -Name Full | Format-List -Property *'; Commands = @("Get-PSSessionConfiguration"); Version = "7.0"; OS = "Linux"; ProblemCount = 1 } - @{ Target = $script:Ubuntu1804_7_profile; Script = 'Get-CimInstance Win32_StartupCommand'; Commands = @("Get-CimInstance"); Version = "7.0"; OS = "Linux"; ProblemCount = 1 } - @{ Target = $script:Ubuntu1804_7_profile; Script = 'Get-ChildItem ./ | Format-List'; Commands = @(); Version = "7.0"; OS = "Linux"; ProblemCount = 0 } - @{ Target = $script:Ubuntu1804_7_profile; Script = 'gci .'; Commands = @(); Version = "7.0"; OS = "Linux"; ProblemCount = 0 } - @{ Target = $script:Ubuntu1804_7_profile; Script = 'iex $expr | % { Transform $_ }'; Commands = @(); Version = "7.0"; OS = "Linux"; ProblemCount = 0 } - - @{ Target = $script:Srv2019_6_2_profile; Script = 'ConvertFrom-String $str'; Commands = @("ConvertFrom-String"); Version = "6.2"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2019_6_2_profile; Script = "Get-WmiObject -Class Win32_Process"; Commands = @("Get-WmiObject"); Version = "6.2"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2019_6_2_profile; Script = "Invoke-WmiMethod -Path win32_process -Name create -ArgumentList notepad.exe"; Commands = @("Invoke-WmiMethod"); Version = "6.2"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2019_6_2_profile; Script = '$np | Remove-WmiObject'; Commands = @("Remove-WmiObject"); Version = "6.2"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2019_6_2_profile; Script = 'Set-Clipboard -Value "This is a test string"'; Commands = @("Set-Clipboard"); Version = "6.2"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2019_6_2_profile; Script = "Set-WmiInstance -Class Win32_WMISetting -Argument @{LoggingLevel=2}"; Commands = @("Set-WmiInstance"); Version = "6.2"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2019_6_2_profile; Script = 'Add-Computer -DomainName "Domain01" -Restart'; Commands = @("Add-Computer"); Version = "6.2"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2019_6_2_profile; Script = 'Checkpoint-Computer -Description "Install MyApp"'; Commands = @("Checkpoint-Computer"); Version = "6.2"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2019_6_2_profile; Script = 'Clear-EventLog "Windows PowerShell"'; Commands = @("Clear-EventLog"); Version = "6.2"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2019_6_2_profile; Script = 'Clear-RecycleBin'; Commands = @("Clear-RecycleBin"); Version = "6.2"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2019_6_2_profile; Script = 'Start-Transaction; New-Item MyCompany -UseTransaction; Complete-Transaction'; Commands = @("Start-Transaction", "Complete-Transaction"); Version = "6.2"; OS = "Windows"; ProblemCount = 2 } - @{ Target = $script:Srv2019_6_2_profile; Script = 'Disable-ComputerRestore -Drive "C:\"'; Commands = @("Disable-ComputerRestore"); Version = "6.2"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2019_6_2_profile; Script = 'Enable-ComputerRestore -Drive "C:\", "D:\"'; Commands = @("Enable-ComputerRestore"); Version = "6.2"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2019_6_2_profile; Script = 'Get-ControlPanelItem -Name "*Program*", "*App*"'; Commands = @("Get-ControlPanelItem"); Version = "6.2"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2019_6_2_profile; Script = 'Get-EventLog -Newest 5 -LogName "Application"'; Commands = @("Get-EventLog"); Version = "6.2"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2019_6_2_profile; Script = 'Get-HotFix -Description "Security*" -ComputerName "Server01", "Server02" -Cred "Server01\admin01"'; Commands = @("Get-HotFix"); Version = "6.2"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2019_6_2_profile; Script = '$zip = New-WebServiceProxy -Uri "http://www.webservicex.net/uszip.asmx?WSDL"'; Commands = @("New-WebServiceProxy"); Version = "6.2"; OS = "Windows"; ProblemCount = 1 } - - @{ Target = $script:Srv2019_7_profile; Script = 'ConvertFrom-String $str'; Commands = @("ConvertFrom-String"); Version = "7.0"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2019_7_profile; Script = "Get-WmiObject -Class Win32_Process"; Commands = @("Get-WmiObject"); Version = "7.0"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2019_7_profile; Script = "Invoke-WmiMethod -Path win32_process -Name create -ArgumentList notepad.exe"; Commands = @("Invoke-WmiMethod"); Version = "7.0"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2019_7_profile; Script = '$np | Remove-WmiObject'; Commands = @("Remove-WmiObject"); Version = "7.0"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2019_7_profile; Script = 'Set-Clipboard -Value "This is a test string"'; Commands = @(); Version = "7.0"; OS = "Windows"; ProblemCount = 0 } - @{ Target = $script:Srv2019_7_profile; Script = "Set-WmiInstance -Class Win32_WMISetting -Argument @{LoggingLevel=2}"; Commands = @("Set-WmiInstance"); Version = "7.0"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2019_7_profile; Script = 'Add-Computer -DomainName "Domain01" -Restart'; Commands = @("Add-Computer"); Version = "7.0"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2019_7_profile; Script = 'Checkpoint-Computer -Description "Install MyApp"'; Commands = @("Checkpoint-Computer"); Version = "7.0"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2019_7_profile; Script = 'Clear-EventLog "Windows PowerShell"'; Commands = @("Clear-EventLog"); Version = "7.0"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2019_7_profile; Script = 'Clear-RecycleBin'; Commands = @(); Version = "7.0"; OS = "Windows"; ProblemCount = 0 } - @{ Target = $script:Srv2019_7_profile; Script = 'Start-Transaction; New-Item MyCompany -UseTransaction; Complete-Transaction'; Commands = @("Start-Transaction", "Complete-Transaction"); Version = "7.0"; OS = "Windows"; ProblemCount = 2 } - @{ Target = $script:Srv2019_7_profile; Script = 'Disable-ComputerRestore -Drive "C:\"'; Commands = @("Disable-ComputerRestore"); Version = "7.0"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2019_7_profile; Script = 'Enable-ComputerRestore -Drive "C:\", "D:\"'; Commands = @("Enable-ComputerRestore"); Version = "7.0"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2019_7_profile; Script = 'Get-ControlPanelItem -Name "*Program*", "*App*"'; Commands = @("Get-ControlPanelItem"); Version = "7.0"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2019_7_profile; Script = 'Get-EventLog -Newest 5 -LogName "Application"'; Commands = @("Get-EventLog"); Version = "7.0"; OS = "Windows"; ProblemCount = 1 } - @{ Target = $script:Srv2019_7_profile; Script = 'Get-HotFix -Description "Security*" -ComputerName "Server01", "Server02" -Cred "Server01\admin01"'; Commands = @(); Version = "7.0"; OS = "Windows"; ProblemCount = 0 } - @{ Target = $script:Srv2019_7_profile; Script = '$zip = New-WebServiceProxy -Uri "http://www.webservicex.net/uszip.asmx?WSDL"'; Commands = @("New-WebServiceProxy"); Version = "7.0"; OS = "Windows"; ProblemCount = 1 } -) - -$script:ParameterCompatibilityTestCases = @( - @{ Target = $script:Srv2012_3_profile; Script = 'Get-Item -Path ./ -InformationVariable i'; Commands = @('Get-Item'); Parameters = @('InformationVariable'); Version = '3.0'; OS = 'Windows'; ProblemCount = 1 } - @{ Target = $script:Srv2012_3_profile; Script = 'Get-ChildItem -Path ./ -Recurse -Depth 3'; Commands = @('Get-ChildItem'); Parameters = @('Depth'); Version = '3.0'; OS = 'Windows'; ProblemCount = 1 } - @{ Target = $script:Srv2012_3_profile; Script = 'Copy-Item -Path C:\myFile.txt -ToSession $s -DestinationFolder d:\destinationFolder'; Commands = @('Copy-Item', 'Copy-Item'); Parameters = @('ToSession', 'DestinationFolder'); Version = '3.0'; OS = 'Windows'; ProblemCount = 2 } - @{ Target = $script:Srv2012_3_profile; Script = '"File content" | Out-File ./file.txt -NoNewline'; Commands = @('Out-File'); Parameters = @('NoNewline'); Version = '3.0'; OS = 'Windows'; ProblemCount = 1 } - @{ Target = $script:Srv2012_3_profile; Script = 'Set-Content "Hi" -Path C:/path/to/thing.ps1 -NoNewline'; Commands = @('Set-Content'); Parameters = @('NoNewline'); Version = '3.0'; OS = 'Windows'; ProblemCount = 1 } - @{ Target = $script:Srv2012_3_profile; Script = 'Get-Command -ShowCommandInfo'; Commands = @('Get-Command'); Parameters = @('ShowCommandInfo'); Version = '3.0'; OS = 'Windows'; ProblemCount = 1 } - @{ Target = $script:Srv2012_3_profile; Script = 'Import-Module -FullyQualifiedName @{ ModuleName = "PSScriptAnalyzer"; ModuleVersion = "1.17" }'; Commands = @('Import-Module'); Parameters = @('FullyQualifiedName'); Version = '3.0'; OS = 'Windows'; ProblemCount = 1 } - @{ Target = $script:Srv2012_3_profile; Script = 'Remove-Module -FullyQualifiedName @{ ModuleName = "PSScriptAnalyzer"; ModuleVersion = "1.17" }'; Commands = @('Remove-Module'); Parameters = @('FullyQualifiedName'); Version = '3.0'; OS = 'Windows'; ProblemCount = 1 } - @{ Target = $script:Srv2012_3_profile; Script = 'Register-ScheduledJob -RunNow -Trigger $t'; Commands = @('Register-ScheduledJob'); Parameters = @('RunNow'); Version = '3.0'; OS = 'Windows'; ProblemCount = 1 } - @{ Target = $script:Srv2012_3_profile; Script = 'New-JobTrigger -At "1/20/2012 3:00 AM" -RepeatIndefinitely'; Commands = @('New-JobTrigger'); Parameters = @('RepeatIndefinitely'); Version = '3.0'; OS = 'Windows'; ProblemCount = 1 } - @{ Target = $script:Srv2012_3_profile; Script = '$t = Get-ScheduledJob | Get-JobTrigger | Enable-JobTrigger -PassThru'; Commands = @('Enable-JobTrigger'); Parameters = @('PassThru'); Version = '3.0'; OS = 'Windows'; ProblemCount = 1 } - @{ Target = $script:Srv2012_3_profile; Script = 'Save-Help -FullyQualifiedModule @{ ModuleName = "MyModule"; MaximumVersion = "2.7" }'; Commands = @('Save-Help'); Parameters = @('FullyQualifiedModule'); Version = '3.0'; OS = 'Windows'; ProblemCount = 1 } - @{ Target = $script:Srv2012_3_profile; Script = 'Export-PSSession -FullyQualifiedModule @{ ModuleName = "MyModule"; RequiredVersion = $reqVer }'; Commands = @('Export-PSSession'); Parameters = @('FullyQualifiedModule'); Version = '3.0'; OS = 'Windows'; ProblemCount = 1 } - @{ Target = $script:Srv2012_3_profile; Script = 'Get-Command -FullyQualifiedModule @{ ModuleName = $m; MaximumVersion = $maxVer }'; Commands = @('Get-Command'); Parameters = @('FullyQualifiedModule'); Version = '3.0'; OS = 'Windows'; ProblemCount = 1 } - @{ Target = $script:Srv2012_3_profile; Script = 'Get-Module -FullyQualifiedName @{ ModuleName = $m; ModuleVersion = $v }'; Commands = @('Get-Module'); Parameters = @('FullyQualifiedName'); Version = '3.0'; OS = 'Windows'; ProblemCount = 1 } - @{ Target = $script:Srv2012_3_profile; Script = 'Get-Process -PipelineVariable proc | ForEach-Object { Format-Table $Proc }'; Commands = @('Get-Process'); Parameters = @('PipelineVariable'); Version = '3.0'; OS = 'Windows'; ProblemCount = 1 } - @{ Target = $script:Srv2012_3_profile; Script = 'Get-Process -IncludeUserName'; Commands = @('Get-Process'); Parameters = @('IncludeUserName'); Version = '3.0'; OS = 'Windows'; ProblemCount = 1 } - - @{ Target = $script:Srv2012r2_4_profile; Script = 'Get-Item -Path ./ -InformationVariable i'; Commands = @('Get-Item'); Parameters = @('InformationVariable'); Version = '4.0'; OS = 'Windows'; ProblemCount = 1 } - @{ Target = $script:Srv2012r2_4_profile; Script = 'Get-ChildItem -Path ./ -Recurse -Depth 3'; Commands = @('Get-ChildItem'); Parameters = @('Depth'); Version = '4.0'; OS = 'Windows'; ProblemCount = 1 } - @{ Target = $script:Srv2012r2_4_profile; Script = 'Copy-Item -Path C:\myFile.txt -ToSession $s -DestinationFolder d:\destinationFolder'; Commands = @('Copy-Item', 'Copy-Item'); Parameters = @('ToSession', 'DestinationFolder'); Version = '4.0'; OS = 'Windows'; ProblemCount = 2 } - @{ Target = $script:Srv2012r2_4_profile; Script = '"File content" | Out-File ./file.txt -NoNewline'; Commands = @('Out-File'); Parameters = @('NoNewline'); Version = '4.0'; OS = 'Windows'; ProblemCount = 1 } - @{ Target = $script:Srv2012r2_4_profile; Script = 'Set-Content "Hi" -Path C:/path/to/thing.ps1 -NoNewline'; Commands = @('Set-Content'); Parameters = @('NoNewline'); Version = '4.0'; OS = 'Windows'; ProblemCount = 1 } - @{ Target = $script:Srv2012r2_4_profile; Script = 'Get-Command -ShowCommandInfo'; Commands = @('Get-Command'); Parameters = @('ShowCommandInfo'); Version = '4.0'; OS = 'Windows'; ProblemCount = 1 } - @{ Target = $script:Srv2012r2_4_profile; Script = 'Import-Module -FullyQualifiedName @{ ModuleName = "PSScriptAnalyzer"; ModuleVersion = "1.17" }'; Commands = @('Import-Module'); Parameters = @('FullyQualifiedName'); Version = '4.0'; OS = 'Windows'; ProblemCount = 1 } - @{ Target = $script:Srv2012r2_4_profile; Script = 'Remove-Module -FullyQualifiedName @{ ModuleName = "PSScriptAnalyzer"; ModuleVersion = "1.17" }'; Commands = @('Remove-Module'); Parameters = @('FullyQualifiedName'); Version = '4.0'; OS = 'Windows'; ProblemCount = 1 } - @{ Target = $script:Srv2012r2_4_profile; Script = 'Save-Help -FullyQualifiedModule @{ ModuleName = "MyModule"; MaximumVersion = "2.7" }'; Commands = @('Save-Help'); Parameters = @('FullyQualifiedModule'); Version = '4.0'; OS = 'Windows'; ProblemCount = 1 } - @{ Target = $script:Srv2012r2_4_profile; Script = 'Export-PSSession -FullyQualifiedModule @{ ModuleName = "MyModule"; MaximumVersion = "2.7" }'; Commands = @('Export-PSSession'); Parameters = @('FullyQualifiedModule'); Version = '4.0'; OS = 'Windows'; ProblemCount = 1 } - @{ Target = $script:Srv2012r2_4_profile; Script = 'Get-Command -FullyQualifiedModule @{ ModuleName = "MyModule"; MaximumVersion = "2.7" }'; Commands = @('Get-Command'); Parameters = @('FullyQualifiedModule'); Version = '4.0'; OS = 'Windows'; ProblemCount = 1 } - @{ Target = $script:Srv2012r2_4_profile; Script = 'Register-ScheduledJob -RunNow -Trigger $t'; Commands = @('Register-ScheduledJob'); Parameters = @('RunNow'); Version = '4.0'; OS = 'Windows'; ProblemCount = 0 } - @{ Target = $script:Srv2012r2_4_profile; Script = 'Get-Module -FullyQualifiedName @{ ModuleName = $m; ModuleVersion = $v }'; Commands = @('Get-Module'); Parameters = @('FullyQualifiedName'); Version = '4.0'; OS = 'Windows'; ProblemCount = 0 } - - @{ Target = $script:Srv2019_5_profile; Script = 'Invoke-RestMethod "https://example.com" -FollowRelLink -MaximumFollowRelLink 10 -CustomMethod "Squash"'; Commands = @('Invoke-RestMethod', 'Invoke-RestMethod', 'Invoke-RestMethod'); Parameters = @('FollowRelLink', 'MaximumFollowRelLink', 'CustomMethod'); Version = '5.1'; OS = 'Windows'; ProblemCount = 3 } - @{ Target = $script:Srv2019_5_profile; Script = 'Invoke-WebRequest "https://microsoft.com" -NoProxy -ContentType "something-strange" -SkipHeaderValidation'; Commands = @('Invoke-WebRequest', 'Invoke-WebRequest'); Parameters = @('NoProxy', 'SkipHeaderValidation'); Version = '5.1'; OS = 'Windows'; ProblemCount = 2 } - @{ Target = $script:Srv2019_5_profile; Script = 'Invoke-RestMethod "https://mywebsite.com/auth" -Authentication OAuth -Token $tok -ResponseHeadersVariable resp'; Commands = @('Invoke-RestMethod', 'Invoke-RestMethod', 'Invoke-RestMethod'); Parameters = @('Authentication', 'Token', 'ResponseHeadersVariable'); Version = '5.1'; OS = 'Windows'; ProblemCount = 3 } - @{ Target = $script:Srv2019_5_profile; Script = '$obj = ConvertFrom-Json $json -AsHashtable'; Commands = @('ConvertFrom-Json'); Parameters = @('AsHashtable'); Version = '5.1'; OS = 'Windows'; ProblemCount = 1 } - @{ Target = $script:Srv2019_5_profile; Script = 'Get-ChildItem . -FollowSymLink'; Commands = @('Get-ChildItem'); Parameters = @('FollowSymLink'); Version = '5.1'; OS = 'Windows'; ProblemCount = 1 } - @{ Target = $script:Srv2019_5_profile; Script = 'Import-Module "MyModule" -ErrorAction SilentlyContinue'; Commands = @(); Parameters = @(); Version = '5.1'; OS = 'Windows'; ProblemCount = 0 } - @{ Target = $script:Srv2019_5_profile; Script = 'Get-Location | Split-Path -LeafBase'; Commands = @('Split-Path'); Parameters = @('LeafBase'); Version = '5.1'; OS = 'Windows'; ProblemCount = 1 } - @{ Target = $script:Srv2019_5_profile; Script = 'Get-Process | sort PagedMemorySize -Top 10'; Commands = @('sort'); Parameters = @('Top'); Version = '5.1'; OS = 'Windows'; ProblemCount = 1 } - @{ Target = $script:Srv2019_5_profile; Script = 'Get-Process | select -first 1 | Out-String -NoNewline'; Commands = @('Out-String'); Parameters = @('NoNewline'); Version = '5.1'; OS = 'Windows'; ProblemCount = 1 } - - @{ Target = $script:Srv2019_6_2_profile; Script = 'Get-Help "Invoke-WebRequest" -ShowWindow'; Commands = @('Get-Help'); Parameters = @('ShowWindow'); Version = "6.2"; OS = 'Windows'; ProblemCount = 1 } - @{ Target = $script:Srv2019_6_2_profile; Script = 'Start-Service "eventlog" -ComputerName "MyComputer"'; Commands = @('Start-Service'); Parameters = @('ComputerName'); Version = "6.2"; OS = 'Windows'; ProblemCount = 1 } - - @{ Target = $script:Srv2019_7_profile; Script = 'Get-Help "Invoke-WebRequest" -ShowWindow'; Commands = @(); Parameters = @(); Version = "7.0"; OS = 'Windows'; ProblemCount = 0 } - @{ Target = $script:Srv2019_7_profile; Script = 'Start-Service "eventlog" -ComputerName "MyComputer"'; Commands = @('Start-Service'); Parameters = @('ComputerName'); Version = "7.0"; OS = 'Windows'; ProblemCount = 1 } -) +BeforeAll { + $script:RunningInCIOnUbuntu = $IsLinux -and ($env:TF_BUILD -or $env:APPVEYOR) # some test cases randomly start and stop to fail in Ubuntu CI tests + $script:RuleName = 'PSUseCompatibleCommands' + $script:AnyProfileConfigKey = 'AnyProfilePath' + $script:TargetProfileConfigKey = 'TargetProfiles' + + $script:Srv2012_3_profile = 'win-8_x64_6.2.9200.0_3.0_x64_4.0.30319.42000_framework' + $script:Srv2012r2_4_profile = 'win-8_x64_6.3.9600.0_4.0_x64_4.0.30319.42000_framework' + $script:Srv2016_5_profile = 'win-8_x64_10.0.14393.0_5.1.14393.2791_x64_4.0.30319.42000_framework' + $script:Srv2016_6_2_profile = 'win-8_x64_10.0.14393.0_6.2.4_x64_4.0.30319.42000_core' + $script:Srv2016_7_profile = 'win-8_x64_10.0.14393.0_7.0.0_x64_3.1.2_core' + $script:Srv2019_5_profile = 'win-8_x64_10.0.17763.0_5.1.17763.316_x64_4.0.30319.42000_framework' + $script:Srv2019_6_2_profile = 'win-8_x64_10.0.17763.0_6.2.4_x64_4.0.30319.42000_core' + $script:Srv2019_7_profile = 'win-8_x64_10.0.17763.0_7.0.0_x64_3.1.2_core' + $script:Win10_5_profile = 'win-48_x64_10.0.17763.0_5.1.17763.316_x64_4.0.30319.42000_framework' + $script:Win10_6_2_profile = 'win-4_x64_10.0.18362.0_6.2.4_x64_4.0.30319.42000_core' + $script:Win10_7_profile = 'win-4_x64_10.0.18362.0_7.0.0_x64_3.1.2_core' + $script:Ubuntu1804_6_2_profile = 'ubuntu_x64_18.04_6.2.4_x64_4.0.30319.42000_core' + $script:Ubuntu1804_7_profile = 'ubuntu_x64_18.04_7.0.0_x64_3.1.2_core' + + $script:AzF_profile = (Resolve-Path "$PSScriptRoot/../../PSCompatibilityCollector/optional_profiles/azurefunctions.json").Path + $script:AzA_profile = (Resolve-Path "$PSScriptRoot/../../PSCompatibilityCollector/optional_profiles/azureautomation.json").Path + + $script:CompatibilityTestCases = @( + @{ Target = $script:Srv2012_3_profile; Script = 'Write-Information "Information"'; Commands = @("Write-Information"); Version = "3.0"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2012_3_profile; Script = '"Hello World" | ConvertFrom-String | Get-Member'; Commands = @("ConvertFrom-String"); Version = "3.0"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2012_3_profile; Script = 'Compress-Archive -LiteralPath C:\Reference\Draftdoc.docx, C:\Reference\Images\diagram2.vsd -CompressionLevel Optimal -DestinationPath C:\Archives\Draft.Zip'; Commands = @("Compress-Archive"); Version = "3.0"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2012_3_profile; Script = 'Get-Runspace -Id 2'; Commands = @("Get-Runspace"); Version = "3.0"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2012_3_profile; Script = '$Protected = "Hello World" | Protect-CmsMessage -To "*youralias@emailaddress.com*"'; Commands = @("Protect-CmsMessage"); Version = "3.0"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2012_3_profile; Script = 'Format-Hex -Path "C:\temp\temp.t7f"'; Commands = @("Format-Hex"); Version = "3.0"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2012_3_profile; Script = 'Set-Clipboard -Value "This is a test string"'; Commands = @("Set-Clipboard"); Version = "3.0"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2012_3_profile; Script = 'Clear-RecycleBin -Force'; Commands = @("Clear-RecycleBin"); Version = "3.0"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2012_3_profile; Script = '$TempFile = New-TemporaryFile'; Commands = @("New-TemporaryFile"); Version = "3.0"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2012_3_profile; Script = 'New-Guid | Out-String'; Commands = @("New-Guid"); Version = "3.0"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2012_3_profile; Script = 'Enter-PSHostProcess -Name powershell_ise'; Commands = @("Enter-PSHostProcess"); Version = "3.0"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2012_3_profile; Script = 'Wait-Debugger'; Commands = @("Wait-Debugger"); Version = "3.0"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2012_3_profile; Script = 'Start-Job { Write-Host "Hello" } | Debug-Job'; Commands = @("Debug-Job"); Version = "3.0"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2012_3_profile; Script = 'Get-ItemPropertyValue -Path HKLM:\SOFTWARE\Microsoft\PowerShell\3\PowerShellEngine -Name ApplicationBase'; Commands = @("Get-ItemPropertyValue"); Version = "3.0"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2012_3_profile; Script = 'Get-FileHash $pshome\powershell.exe | Format-List'; Commands = @("Get-FileHash"); Version = "3.0"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2012_3_profile; Script = 'Get-ChildItem ./ | Format-List'; Commands = @(); Version = "3.0"; OS = "Windows"; ProblemCount = 0 } + @{ Target = $script:Srv2012_3_profile; Script = 'Save-Help -Module $m -DestinationPath "C:\SavedHelp"'; Commands = @(); Version = "3.0"; OS = "Windows"; ProblemCount = 0 } + @{ Target = $script:Srv2012_3_profile; Script = 'gci .'; Commands = @(); Version = "3.0"; OS = "Windows"; ProblemCount = 0 } + @{ Target = $script:Srv2012_3_profile; Script = 'iex $expr | % { Transform $_ }'; Commands = @(); Version = "3.0"; OS = "Windows"; ProblemCount = 0 } + + @{ Target = $script:Srv2012r2_4_profile; Script = 'Write-Information "Information"'; Commands = @("Write-Information"); Version = "4.0"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2012r2_4_profile; Script = '"Hello World" | ConvertFrom-String | Get-Member'; Commands = @("ConvertFrom-String"); Version = "4.0"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2012r2_4_profile; Script = 'Compress-Archive -LiteralPath C:\Reference\Draftdoc.docx, C:\Reference\Images\diagram2.vsd -CompressionLevel Optimal -DestinationPath C:\Archives\Draft.Zip'; Commands = @("Compress-Archive"); Version = "4.0"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2012r2_4_profile; Script = 'Get-Runspace -Id 2'; Commands = @("Get-Runspace"); Version = "4.0"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2012r2_4_profile; Script = 'Format-Hex -Path "C:\temp\temp.t7f"'; Commands = @("Format-Hex"); Version = "4.0"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2012r2_4_profile; Script = 'Set-Clipboard -Value "This is a test string"'; Commands = @("Set-Clipboard"); Version = "4.0"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2012r2_4_profile; Script = 'Clear-RecycleBin -Force'; Commands = @("Clear-RecycleBin"); Version = "4.0"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2012r2_4_profile; Script = '$TempFile = New-TemporaryFile'; Commands = @("New-TemporaryFile"); Version = "4.0"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2012r2_4_profile; Script = 'New-Guid | Out-String'; Commands = @("New-Guid"); Version = "4.0"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2012r2_4_profile; Script = 'Enter-PSHostProcess -Name powershell_ise'; Commands = @("Enter-PSHostProcess"); Version = "4.0"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2012r2_4_profile; Script = 'Wait-Debugger'; Commands = @("Wait-Debugger"); Version = "4.0"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2012r2_4_profile; Script = 'Start-Job { Write-Host "Hello" } | Debug-Job'; Commands = @("Debug-Job"); Version = "4.0"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2012r2_4_profile; Script = 'Get-ItemPropertyValue -Path HKLM:\SOFTWARE\Microsoft\PowerShell\3\PowerShellEngine -Name ApplicationBase'; Commands = @("Get-ItemPropertyValue"); Version = "4.0"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2012r2_4_profile; Script = 'Get-ChildItem ./ | Format-List'; Commands = @(); Version = "3.0"; OS = "Windows"; ProblemCount = 0 } + @{ Target = $script:Srv2012r2_4_profile; Script = 'gci .'; Commands = @(); Version = "4.0"; OS = "Windows"; ProblemCount = 0 } + @{ Target = $script:Srv2012r2_4_profile; Script = 'iex $expr | % { Transform $_ }'; Commands = @(); Version = "4.0"; OS = "Windows"; ProblemCount = 0 } + + @{ Target = $script:Srv2019_5_profile; Script = "Remove-Alias gcm"; Commands = @("Remove-Alias"); Version = "5.1"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2019_5_profile; Script = "Get-Uptime"; Commands = @("Get-Uptime"); Version = "5.1"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2019_5_profile; Script = "Remove-Service 'MyService'"; Commands = @("Remove-Service"); Version = "5.1"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2019_5_profile; Script = 'Get-ChildItem ./ | Format-List'; Commands = @(); Version = "3.0"; OS = "Windows"; ProblemCount = 0 } + @{ Target = $script:Srv2019_5_profile; Script = 'gci .'; Commands = @(); Version = "5.1"; OS = "Windows"; ProblemCount = 0 } + @{ Target = $script:Srv2019_5_profile; Script = 'iex $expr | % { Transform $_ }'; Commands = @(); Version = "5.1"; OS = "Windows"; ProblemCount = 0 } + @{ Target = $script:Srv2019_5_profile; Script = 'fhx $filePath'; Commands = @(); Version = "5.1"; OS = "Windows"; ProblemCount = 0 } + + @{ Target = $script:Srv2019_6_2_profile; Script = "Add-PSSnapIn MySnapIn"; Commands = @("Add-PSSnapIn"); Version = "6.2"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2019_6_2_profile; Script = "Get-PSSnapIn MySnapIn"; Commands = @("Get-PSSnapIn"); Version = "6.2"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2019_6_2_profile; Script = "Get-Content $pshome\about_signing.help.txt | Out-Printer"; Commands = @("Out-Printer"); Version = "6.2"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2019_6_2_profile; Script = 'New-PSWorkflowSession -ComputerName "ServerNode01" -Name "WorkflowTests" -SessionOption (New-PSSessionOption -OutputBufferingMode Drop)'; Commands = @("New-PSWorkflowSession"); Version = "6.2"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2019_6_2_profile; Script = "Get-Process | Out-GridView"; Commands = @("Out-GridView"); Version = "6.2"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2019_6_2_profile; Script = "Get-Process | ogv"; Commands = @("ogv"); Version = "6.2"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2019_6_2_profile; Script = "Remove-PSSnapIn MySnapIn"; Commands = @("Remove-PSSnapIn"); Version = "6.2"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2019_6_2_profile; Script = "Show-Command"; Commands = @("Show-Command"); Version = "6.2"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2019_6_2_profile; Script = '$composers | Convert-String -Example "first middle last=last, first"'; Commands = @("Convert-String"); Version = "6.2"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2019_6_2_profile; Script = 'Export-Console -Path $pshome\Consoles\ConsoleS1.psc1'; Commands = @("Export-Console"); Version = "6.2"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2019_6_2_profile; Script = 'Get-Counter "\Processor(*)\% Processor Time" | Export-Counter -Path $home\Counters.blg'; Commands = @("Get-Counter", "Export-Counter"); Version = "6.2"; OS = "Windows"; ProblemCount = 2 } + @{ Target = $script:Srv2019_6_2_profile; Script = 'curl $uri'; Commands = @("curl"); Version = "6.2"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2019_6_2_profile; Script = 'Get-ChildItem ./ | Format-List'; Commands = @(); Version = "3.0"; OS = "Windows"; ProblemCount = 0 } + @{ Target = $script:Srv2019_6_2_profile; Script = 'gci .'; Commands = @(); Version = "6.2"; OS = "Windows"; ProblemCount = 0 } + @{ Target = $script:Srv2016_6_2_profile; Script = 'iex $expr | % { Transform $_ }'; Commands = @(); Version = "6.2"; OS = "Windows"; ProblemCount = 0 } + @{ Target = $script:Srv2019_6_2_profile; Script = 'ConvertFrom-String $str'; Commands = @("ConvertFrom-String"); Version = "6.2"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2019_6_2_profile; Script = "Get-WmiObject -Class Win32_Process"; Commands = @("Get-WmiObject"); Version = "6.2"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2019_6_2_profile; Script = "Invoke-WmiMethod -Path win32_process -Name create -ArgumentList notepad.exe"; Commands = @("Invoke-WmiMethod"); Version = "6.2"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2019_6_2_profile; Script = '$np | Remove-WmiObject'; Commands = @("Remove-WmiObject"); Version = "6.2"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2019_6_2_profile; Script = 'Set-Clipboard -Value "This is a test string"'; Commands = @("Set-Clipboard"); Version = "6.2"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2019_6_2_profile; Script = "Set-WmiInstance -Class Win32_WMISetting -Argument @{LoggingLevel=2}"; Commands = @("Set-WmiInstance"); Version = "6.2"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2019_6_2_profile; Script = 'Add-Computer -DomainName "Domain01" -Restart'; Commands = @("Add-Computer"); Version = "6.2"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2019_6_2_profile; Script = 'Checkpoint-Computer -Description "Install MyApp"'; Commands = @("Checkpoint-Computer"); Version = "6.2"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2019_6_2_profile; Script = 'Clear-EventLog "Windows PowerShell"'; Commands = @("Clear-EventLog"); Version = "6.2"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2019_6_2_profile; Script = 'Clear-RecycleBin'; Commands = @("Clear-RecycleBin"); Version = "6.2"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2019_6_2_profile; Script = 'Start-Transaction; New-Item MyCompany -UseTransaction; Complete-Transaction'; Commands = @("Start-Transaction", "Complete-Transaction"); Version = "6.2"; OS = "Windows"; ProblemCount = 2 } + @{ Target = $script:Srv2019_6_2_profile; Script = 'Disable-ComputerRestore -Drive "C:\"'; Commands = @("Disable-ComputerRestore"); Version = "6.2"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2019_6_2_profile; Script = 'Enable-ComputerRestore -Drive "C:\", "D:\"'; Commands = @("Enable-ComputerRestore"); Version = "6.2"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2019_6_2_profile; Script = 'Get-ControlPanelItem -Name "*Program*", "*App*"'; Commands = @("Get-ControlPanelItem"); Version = "6.2"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2019_6_2_profile; Script = 'Get-EventLog -Newest 5 -LogName "Application"'; Commands = @("Get-EventLog"); Version = "6.2"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2019_6_2_profile; Script = 'Get-HotFix -Description "Security*" -ComputerName "Server01", "Server02" -Cred "Server01\admin01"'; Commands = @("Get-HotFix"); Version = "6.2"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2019_6_2_profile; Script = '$zip = New-WebServiceProxy -Uri "http://www.webservicex.net/uszip.asmx?WSDL"'; Commands = @("New-WebServiceProxy"); Version = "6.2"; OS = "Windows"; ProblemCount = 1 } + + @{ Target = $script:Srv2019_7_profile; Script = "Add-PSSnapIn MySnapIn"; Commands = @("Add-PSSnapIn"); Version = "7.0"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2019_7_profile; Script = "Get-PSSnapIn MySnapIn"; Commands = @("Get-PSSnapIn"); Version = "7.0"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2019_7_profile; Script = "Get-Content $pshome\about_signing.help.txt | Out-Printer"; Commands = @(); Version = "7.0"; OS = "Windows"; ProblemCount = 0 } + @{ Target = $script:Srv2019_7_profile; Script = 'New-PSWorkflowSession -ComputerName "ServerNode01" -Name "WorkflowTests" -SessionOption (New-PSSessionOption -OutputBufferingMode Drop)'; Commands = @("New-PSWorkflowSession"); Version = "7.0"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2019_7_profile; Script = "Get-Process | Out-GridView"; Commands = @(); Version = "7.0"; OS = "Windows"; ProblemCount = 0 } + @{ Target = $script:Srv2019_7_profile; Script = "Get-Process | ogv"; Commands = @(); Version = "7.0"; OS = "Windows"; ProblemCount = 0 } + @{ Target = $script:Srv2019_7_profile; Script = "Remove-PSSnapIn MySnapIn"; Commands = @("Remove-PSSnapIn"); Version = "7.0"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2019_7_profile; Script = "Show-Command"; Commands = @(); Version = "7.0"; OS = "Windows"; ProblemCount = 0 } + @{ Target = $script:Srv2019_7_profile; Script = '$composers | Convert-String -Example "first middle last=last, first"'; Commands = @("Convert-String"); Version = "7.0"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2019_7_profile; Script = 'Export-Console -Path $pshome\Consoles\ConsoleS1.psc1'; Commands = @("Export-Console"); Version = "7.0"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2019_7_profile; Script = 'Get-ChildItem ./ | Format-List'; Commands = @(); Version = "7.0"; OS = "Windows"; ProblemCount = 0 } + @{ Target = $script:Srv2019_7_profile; Script = 'gci .'; Commands = @(); Version = "7.0"; OS = "Windows"; ProblemCount = 0 } + @{ Target = $script:Srv2016_7_profile; Script = 'iex $expr | % { Transform $_ }'; Commands = @(); Version = "7.0"; OS = "Windows"; ProblemCount = 0 } + @{ Target = $script:Srv2019_7_profile; Script = 'ConvertFrom-String $str'; Commands = @("ConvertFrom-String"); Version = "7.0"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2019_7_profile; Script = "Get-WmiObject -Class Win32_Process"; Commands = @("Get-WmiObject"); Version = "7.0"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2019_7_profile; Script = "Invoke-WmiMethod -Path win32_process -Name create -ArgumentList notepad.exe"; Commands = @("Invoke-WmiMethod"); Version = "7.0"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2019_7_profile; Script = '$np | Remove-WmiObject'; Commands = @("Remove-WmiObject"); Version = "7.0"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2019_7_profile; Script = 'Set-Clipboard -Value "This is a test string"'; Commands = @(); Version = "7.0"; OS = "Windows"; ProblemCount = 0 } + @{ Target = $script:Srv2019_7_profile; Script = "Set-WmiInstance -Class Win32_WMISetting -Argument @{LoggingLevel=2}"; Commands = @("Set-WmiInstance"); Version = "7.0"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2019_7_profile; Script = 'Add-Computer -DomainName "Domain01" -Restart'; Commands = @("Add-Computer"); Version = "7.0"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2019_7_profile; Script = 'Checkpoint-Computer -Description "Install MyApp"'; Commands = @("Checkpoint-Computer"); Version = "7.0"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2019_7_profile; Script = 'Clear-EventLog "Windows PowerShell"'; Commands = @("Clear-EventLog"); Version = "7.0"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2019_7_profile; Script = 'Clear-RecycleBin'; Commands = @(); Version = "7.0"; OS = "Windows"; ProblemCount = 0 } + @{ Target = $script:Srv2019_7_profile; Script = 'Start-Transaction; New-Item MyCompany -UseTransaction; Complete-Transaction'; Commands = @("Start-Transaction", "Complete-Transaction"); Version = "7.0"; OS = "Windows"; ProblemCount = 2 } + @{ Target = $script:Srv2019_7_profile; Script = 'Disable-ComputerRestore -Drive "C:\"'; Commands = @("Disable-ComputerRestore"); Version = "7.0"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2019_7_profile; Script = 'Enable-ComputerRestore -Drive "C:\", "D:\"'; Commands = @("Enable-ComputerRestore"); Version = "7.0"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2019_7_profile; Script = 'Get-ControlPanelItem -Name "*Program*", "*App*"'; Commands = @("Get-ControlPanelItem"); Version = "7.0"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2019_7_profile; Script = 'Get-EventLog -Newest 5 -LogName "Application"'; Commands = @("Get-EventLog"); Version = "7.0"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2019_7_profile; Script = 'Get-HotFix -Description "Security*" -ComputerName "Server01", "Server02" -Cred "Server01\admin01"'; Commands = @(); Version = "7.0"; OS = "Windows"; ProblemCount = 0 } + @{ Target = $script:Srv2019_7_profile; Script = '$zip = New-WebServiceProxy -Uri "http://www.webservicex.net/uszip.asmx?WSDL"'; Commands = @("New-WebServiceProxy"); Version = "7.0"; OS = "Windows"; ProblemCount = 1 } + + @{ Target = $script:Ubuntu1804_6_2_profile; Script = 'Get-AuthenticodeSignature ./script.ps1'; Commands = @("Get-AuthenticodeSignature"); Version = "6.2"; OS = "Linux"; ProblemCount = 1 } + @{ Target = $script:Ubuntu1804_6_2_profile; Script = 'Get-Service systemd'; Commands = @("Get-Service"); Version = "6.2"; OS = "Linux"; ProblemCount = 1 } + @{ Target = $script:Ubuntu1804_6_2_profile; Script = 'Start-Service -Name "sshd"'; Commands = @("Start-Service"); Version = "6.2"; OS = "Linux"; ProblemCount = 1 } + @{ Target = $script:Ubuntu1804_6_2_profile; Script = 'Get-PSSessionConfiguration -Name Full | Format-List -Property *'; Commands = @("Get-PSSessionConfiguration"); Version = "6.2"; OS = "Linux"; ProblemCount = 1 } + @{ Target = $script:Ubuntu1804_6_2_profile; Script = 'Get-CimInstance Win32_StartupCommand'; Commands = @("Get-CimInstance"); Version = "6.2"; OS = "Linux"; ProblemCount = 1 } + @{ Target = $script:Ubuntu1804_6_2_profile; Script = 'Get-ChildItem ./ | Format-List'; Commands = @(); Version = "6.2"; OS = "Linux"; ProblemCount = 0 } + @{ Target = $script:Ubuntu1804_6_2_profile; Script = 'gci .'; Commands = @(); Version = "6.2"; OS = "Linux"; ProblemCount = 0 } + @{ Target = $script:Ubuntu1804_6_2_profile; Script = 'iex $expr | % { Transform $_ }'; Commands = @(); Version = "6.2"; OS = "Linux"; ProblemCount = 0 } + + @{ Target = $script:Ubuntu1804_7_profile; Script = 'Get-AuthenticodeSignature ./script.ps1'; Commands = @("Get-AuthenticodeSignature"); Version = "7.0"; OS = "Linux"; ProblemCount = 1 } + @{ Target = $script:Ubuntu1804_7_profile; Script = 'Get-Service systemd'; Commands = @("Get-Service"); Version = "7.0"; OS = "Linux"; ProblemCount = 1 } + @{ Target = $script:Ubuntu1804_7_profile; Script = 'Start-Service -Name "sshd"'; Commands = @("Start-Service"); Version = "7.0"; OS = "Linux"; ProblemCount = 1 } + @{ Target = $script:Ubuntu1804_7_profile; Script = 'Get-PSSessionConfiguration -Name Full | Format-List -Property *'; Commands = @("Get-PSSessionConfiguration"); Version = "7.0"; OS = "Linux"; ProblemCount = 1 } + @{ Target = $script:Ubuntu1804_7_profile; Script = 'Get-CimInstance Win32_StartupCommand'; Commands = @("Get-CimInstance"); Version = "7.0"; OS = "Linux"; ProblemCount = 1 } + @{ Target = $script:Ubuntu1804_7_profile; Script = 'Get-ChildItem ./ | Format-List'; Commands = @(); Version = "7.0"; OS = "Linux"; ProblemCount = 0 } + @{ Target = $script:Ubuntu1804_7_profile; Script = 'gci .'; Commands = @(); Version = "7.0"; OS = "Linux"; ProblemCount = 0 } + @{ Target = $script:Ubuntu1804_7_profile; Script = 'iex $expr | % { Transform $_ }'; Commands = @(); Version = "7.0"; OS = "Linux"; ProblemCount = 0 } + + @{ Target = $script:Srv2019_6_2_profile; Script = 'ConvertFrom-String $str'; Commands = @("ConvertFrom-String"); Version = "6.2"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2019_6_2_profile; Script = "Get-WmiObject -Class Win32_Process"; Commands = @("Get-WmiObject"); Version = "6.2"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2019_6_2_profile; Script = "Invoke-WmiMethod -Path win32_process -Name create -ArgumentList notepad.exe"; Commands = @("Invoke-WmiMethod"); Version = "6.2"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2019_6_2_profile; Script = '$np | Remove-WmiObject'; Commands = @("Remove-WmiObject"); Version = "6.2"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2019_6_2_profile; Script = 'Set-Clipboard -Value "This is a test string"'; Commands = @("Set-Clipboard"); Version = "6.2"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2019_6_2_profile; Script = "Set-WmiInstance -Class Win32_WMISetting -Argument @{LoggingLevel=2}"; Commands = @("Set-WmiInstance"); Version = "6.2"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2019_6_2_profile; Script = 'Add-Computer -DomainName "Domain01" -Restart'; Commands = @("Add-Computer"); Version = "6.2"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2019_6_2_profile; Script = 'Checkpoint-Computer -Description "Install MyApp"'; Commands = @("Checkpoint-Computer"); Version = "6.2"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2019_6_2_profile; Script = 'Clear-EventLog "Windows PowerShell"'; Commands = @("Clear-EventLog"); Version = "6.2"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2019_6_2_profile; Script = 'Clear-RecycleBin'; Commands = @("Clear-RecycleBin"); Version = "6.2"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2019_6_2_profile; Script = 'Start-Transaction; New-Item MyCompany -UseTransaction; Complete-Transaction'; Commands = @("Start-Transaction", "Complete-Transaction"); Version = "6.2"; OS = "Windows"; ProblemCount = 2 } + @{ Target = $script:Srv2019_6_2_profile; Script = 'Disable-ComputerRestore -Drive "C:\"'; Commands = @("Disable-ComputerRestore"); Version = "6.2"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2019_6_2_profile; Script = 'Enable-ComputerRestore -Drive "C:\", "D:\"'; Commands = @("Enable-ComputerRestore"); Version = "6.2"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2019_6_2_profile; Script = 'Get-ControlPanelItem -Name "*Program*", "*App*"'; Commands = @("Get-ControlPanelItem"); Version = "6.2"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2019_6_2_profile; Script = 'Get-EventLog -Newest 5 -LogName "Application"'; Commands = @("Get-EventLog"); Version = "6.2"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2019_6_2_profile; Script = 'Get-HotFix -Description "Security*" -ComputerName "Server01", "Server02" -Cred "Server01\admin01"'; Commands = @("Get-HotFix"); Version = "6.2"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2019_6_2_profile; Script = '$zip = New-WebServiceProxy -Uri "http://www.webservicex.net/uszip.asmx?WSDL"'; Commands = @("New-WebServiceProxy"); Version = "6.2"; OS = "Windows"; ProblemCount = 1 } + + @{ Target = $script:Srv2019_7_profile; Script = 'ConvertFrom-String $str'; Commands = @("ConvertFrom-String"); Version = "7.0"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2019_7_profile; Script = "Get-WmiObject -Class Win32_Process"; Commands = @("Get-WmiObject"); Version = "7.0"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2019_7_profile; Script = "Invoke-WmiMethod -Path win32_process -Name create -ArgumentList notepad.exe"; Commands = @("Invoke-WmiMethod"); Version = "7.0"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2019_7_profile; Script = '$np | Remove-WmiObject'; Commands = @("Remove-WmiObject"); Version = "7.0"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2019_7_profile; Script = 'Set-Clipboard -Value "This is a test string"'; Commands = @(); Version = "7.0"; OS = "Windows"; ProblemCount = 0 } + @{ Target = $script:Srv2019_7_profile; Script = "Set-WmiInstance -Class Win32_WMISetting -Argument @{LoggingLevel=2}"; Commands = @("Set-WmiInstance"); Version = "7.0"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2019_7_profile; Script = 'Add-Computer -DomainName "Domain01" -Restart'; Commands = @("Add-Computer"); Version = "7.0"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2019_7_profile; Script = 'Checkpoint-Computer -Description "Install MyApp"'; Commands = @("Checkpoint-Computer"); Version = "7.0"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2019_7_profile; Script = 'Clear-EventLog "Windows PowerShell"'; Commands = @("Clear-EventLog"); Version = "7.0"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2019_7_profile; Script = 'Clear-RecycleBin'; Commands = @(); Version = "7.0"; OS = "Windows"; ProblemCount = 0 } + @{ Target = $script:Srv2019_7_profile; Script = 'Start-Transaction; New-Item MyCompany -UseTransaction; Complete-Transaction'; Commands = @("Start-Transaction", "Complete-Transaction"); Version = "7.0"; OS = "Windows"; ProblemCount = 2 } + @{ Target = $script:Srv2019_7_profile; Script = 'Disable-ComputerRestore -Drive "C:\"'; Commands = @("Disable-ComputerRestore"); Version = "7.0"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2019_7_profile; Script = 'Enable-ComputerRestore -Drive "C:\", "D:\"'; Commands = @("Enable-ComputerRestore"); Version = "7.0"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2019_7_profile; Script = 'Get-ControlPanelItem -Name "*Program*", "*App*"'; Commands = @("Get-ControlPanelItem"); Version = "7.0"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2019_7_profile; Script = 'Get-EventLog -Newest 5 -LogName "Application"'; Commands = @("Get-EventLog"); Version = "7.0"; OS = "Windows"; ProblemCount = 1 } + @{ Target = $script:Srv2019_7_profile; Script = 'Get-HotFix -Description "Security*" -ComputerName "Server01", "Server02" -Cred "Server01\admin01"'; Commands = @(); Version = "7.0"; OS = "Windows"; ProblemCount = 0 } + @{ Target = $script:Srv2019_7_profile; Script = '$zip = New-WebServiceProxy -Uri "http://www.webservicex.net/uszip.asmx?WSDL"'; Commands = @("New-WebServiceProxy"); Version = "7.0"; OS = "Windows"; ProblemCount = 1 } + ) + + $script:ParameterCompatibilityTestCases = @( + @{ Target = $script:Srv2012_3_profile; Script = 'Get-Item -Path ./ -InformationVariable i'; Commands = @('Get-Item'); Parameters = @('InformationVariable'); Version = '3.0'; OS = 'Windows'; ProblemCount = 1 } + @{ Target = $script:Srv2012_3_profile; Script = 'Get-ChildItem -Path ./ -Recurse -Depth 3'; Commands = @('Get-ChildItem'); Parameters = @('Depth'); Version = '3.0'; OS = 'Windows'; ProblemCount = 1 } + @{ Target = $script:Srv2012_3_profile; Script = 'Copy-Item -Path C:\myFile.txt -ToSession $s -DestinationFolder d:\destinationFolder'; Commands = @('Copy-Item', 'Copy-Item'); Parameters = @('ToSession', 'DestinationFolder'); Version = '3.0'; OS = 'Windows'; ProblemCount = 2 } + @{ Target = $script:Srv2012_3_profile; Script = '"File content" | Out-File ./file.txt -NoNewline'; Commands = @('Out-File'); Parameters = @('NoNewline'); Version = '3.0'; OS = 'Windows'; ProblemCount = 1 } + @{ Target = $script:Srv2012_3_profile; Script = 'Set-Content "Hi" -Path C:/path/to/thing.ps1 -NoNewline'; Commands = @('Set-Content'); Parameters = @('NoNewline'); Version = '3.0'; OS = 'Windows'; ProblemCount = 1 } + @{ Target = $script:Srv2012_3_profile; Script = 'Get-Command -ShowCommandInfo'; Commands = @('Get-Command'); Parameters = @('ShowCommandInfo'); Version = '3.0'; OS = 'Windows'; ProblemCount = 1 } + @{ Target = $script:Srv2012_3_profile; Script = 'Import-Module -FullyQualifiedName @{ ModuleName = "PSScriptAnalyzer"; ModuleVersion = "1.17" }'; Commands = @('Import-Module'); Parameters = @('FullyQualifiedName'); Version = '3.0'; OS = 'Windows'; ProblemCount = 1 } + @{ Target = $script:Srv2012_3_profile; Script = 'Remove-Module -FullyQualifiedName @{ ModuleName = "PSScriptAnalyzer"; ModuleVersion = "1.17" }'; Commands = @('Remove-Module'); Parameters = @('FullyQualifiedName'); Version = '3.0'; OS = 'Windows'; ProblemCount = 1 } + @{ Target = $script:Srv2012_3_profile; Script = 'Register-ScheduledJob -RunNow -Trigger $t'; Commands = @('Register-ScheduledJob'); Parameters = @('RunNow'); Version = '3.0'; OS = 'Windows'; ProblemCount = 1 } + @{ Target = $script:Srv2012_3_profile; Script = 'New-JobTrigger -At "1/20/2012 3:00 AM" -RepeatIndefinitely'; Commands = @('New-JobTrigger'); Parameters = @('RepeatIndefinitely'); Version = '3.0'; OS = 'Windows'; ProblemCount = 1 } + @{ Target = $script:Srv2012_3_profile; Script = '$t = Get-ScheduledJob | Get-JobTrigger | Enable-JobTrigger -PassThru'; Commands = @('Enable-JobTrigger'); Parameters = @('PassThru'); Version = '3.0'; OS = 'Windows'; ProblemCount = 1 } + @{ Target = $script:Srv2012_3_profile; Script = 'Save-Help -FullyQualifiedModule @{ ModuleName = "MyModule"; MaximumVersion = "2.7" }'; Commands = @('Save-Help'); Parameters = @('FullyQualifiedModule'); Version = '3.0'; OS = 'Windows'; ProblemCount = 1 } + @{ Target = $script:Srv2012_3_profile; Script = 'Export-PSSession -FullyQualifiedModule @{ ModuleName = "MyModule"; RequiredVersion = $reqVer }'; Commands = @('Export-PSSession'); Parameters = @('FullyQualifiedModule'); Version = '3.0'; OS = 'Windows'; ProblemCount = 1 } + @{ Target = $script:Srv2012_3_profile; Script = 'Get-Command -FullyQualifiedModule @{ ModuleName = $m; MaximumVersion = $maxVer }'; Commands = @('Get-Command'); Parameters = @('FullyQualifiedModule'); Version = '3.0'; OS = 'Windows'; ProblemCount = 1 } + @{ Target = $script:Srv2012_3_profile; Script = 'Get-Module -FullyQualifiedName @{ ModuleName = $m; ModuleVersion = $v }'; Commands = @('Get-Module'); Parameters = @('FullyQualifiedName'); Version = '3.0'; OS = 'Windows'; ProblemCount = 1 } + @{ Target = $script:Srv2012_3_profile; Script = 'Get-Process -PipelineVariable proc | ForEach-Object { Format-Table $Proc }'; Commands = @('Get-Process'); Parameters = @('PipelineVariable'); Version = '3.0'; OS = 'Windows'; ProblemCount = 1 } + @{ Target = $script:Srv2012_3_profile; Script = 'Get-Process -IncludeUserName'; Commands = @('Get-Process'); Parameters = @('IncludeUserName'); Version = '3.0'; OS = 'Windows'; ProblemCount = 1 } + + @{ Target = $script:Srv2012r2_4_profile; Script = 'Get-Item -Path ./ -InformationVariable i'; Commands = @('Get-Item'); Parameters = @('InformationVariable'); Version = '4.0'; OS = 'Windows'; ProblemCount = 1 } + @{ Target = $script:Srv2012r2_4_profile; Script = 'Get-ChildItem -Path ./ -Recurse -Depth 3'; Commands = @('Get-ChildItem'); Parameters = @('Depth'); Version = '4.0'; OS = 'Windows'; ProblemCount = 1 } + @{ Target = $script:Srv2012r2_4_profile; Script = 'Copy-Item -Path C:\myFile.txt -ToSession $s -DestinationFolder d:\destinationFolder'; Commands = @('Copy-Item', 'Copy-Item'); Parameters = @('ToSession', 'DestinationFolder'); Version = '4.0'; OS = 'Windows'; ProblemCount = 2 } + @{ Target = $script:Srv2012r2_4_profile; Script = '"File content" | Out-File ./file.txt -NoNewline'; Commands = @('Out-File'); Parameters = @('NoNewline'); Version = '4.0'; OS = 'Windows'; ProblemCount = 1 } + @{ Target = $script:Srv2012r2_4_profile; Script = 'Set-Content "Hi" -Path C:/path/to/thing.ps1 -NoNewline'; Commands = @('Set-Content'); Parameters = @('NoNewline'); Version = '4.0'; OS = 'Windows'; ProblemCount = 1 } + @{ Target = $script:Srv2012r2_4_profile; Script = 'Get-Command -ShowCommandInfo'; Commands = @('Get-Command'); Parameters = @('ShowCommandInfo'); Version = '4.0'; OS = 'Windows'; ProblemCount = 1 } + @{ Target = $script:Srv2012r2_4_profile; Script = 'Import-Module -FullyQualifiedName @{ ModuleName = "PSScriptAnalyzer"; ModuleVersion = "1.17" }'; Commands = @('Import-Module'); Parameters = @('FullyQualifiedName'); Version = '4.0'; OS = 'Windows'; ProblemCount = 1 } + @{ Target = $script:Srv2012r2_4_profile; Script = 'Remove-Module -FullyQualifiedName @{ ModuleName = "PSScriptAnalyzer"; ModuleVersion = "1.17" }'; Commands = @('Remove-Module'); Parameters = @('FullyQualifiedName'); Version = '4.0'; OS = 'Windows'; ProblemCount = 1 } + @{ Target = $script:Srv2012r2_4_profile; Script = 'Save-Help -FullyQualifiedModule @{ ModuleName = "MyModule"; MaximumVersion = "2.7" }'; Commands = @('Save-Help'); Parameters = @('FullyQualifiedModule'); Version = '4.0'; OS = 'Windows'; ProblemCount = 1 } + @{ Target = $script:Srv2012r2_4_profile; Script = 'Export-PSSession -FullyQualifiedModule @{ ModuleName = "MyModule"; MaximumVersion = "2.7" }'; Commands = @('Export-PSSession'); Parameters = @('FullyQualifiedModule'); Version = '4.0'; OS = 'Windows'; ProblemCount = 1 } + @{ Target = $script:Srv2012r2_4_profile; Script = 'Get-Command -FullyQualifiedModule @{ ModuleName = "MyModule"; MaximumVersion = "2.7" }'; Commands = @('Get-Command'); Parameters = @('FullyQualifiedModule'); Version = '4.0'; OS = 'Windows'; ProblemCount = 1 } + @{ Target = $script:Srv2012r2_4_profile; Script = 'Register-ScheduledJob -RunNow -Trigger $t'; Commands = @('Register-ScheduledJob'); Parameters = @('RunNow'); Version = '4.0'; OS = 'Windows'; ProblemCount = 0 } + @{ Target = $script:Srv2012r2_4_profile; Script = 'Get-Module -FullyQualifiedName @{ ModuleName = $m; ModuleVersion = $v }'; Commands = @('Get-Module'); Parameters = @('FullyQualifiedName'); Version = '4.0'; OS = 'Windows'; ProblemCount = 0 } + + @{ Target = $script:Srv2019_5_profile; Script = 'Invoke-RestMethod "https://example.com" -FollowRelLink -MaximumFollowRelLink 10 -CustomMethod "Squash"'; Commands = @('Invoke-RestMethod', 'Invoke-RestMethod', 'Invoke-RestMethod'); Parameters = @('FollowRelLink', 'MaximumFollowRelLink', 'CustomMethod'); Version = '5.1'; OS = 'Windows'; ProblemCount = 3 } + @{ Target = $script:Srv2019_5_profile; Script = 'Invoke-WebRequest "https://microsoft.com" -NoProxy -ContentType "something-strange" -SkipHeaderValidation'; Commands = @('Invoke-WebRequest', 'Invoke-WebRequest'); Parameters = @('NoProxy', 'SkipHeaderValidation'); Version = '5.1'; OS = 'Windows'; ProblemCount = 2 } + @{ Target = $script:Srv2019_5_profile; Script = 'Invoke-RestMethod "https://mywebsite.com/auth" -Authentication OAuth -Token $tok -ResponseHeadersVariable resp'; Commands = @('Invoke-RestMethod', 'Invoke-RestMethod', 'Invoke-RestMethod'); Parameters = @('Authentication', 'Token', 'ResponseHeadersVariable'); Version = '5.1'; OS = 'Windows'; ProblemCount = 3 } + @{ Target = $script:Srv2019_5_profile; Script = '$obj = ConvertFrom-Json $json -AsHashtable'; Commands = @('ConvertFrom-Json'); Parameters = @('AsHashtable'); Version = '5.1'; OS = 'Windows'; ProblemCount = 1 } + @{ Target = $script:Srv2019_5_profile; Script = 'Get-ChildItem . -FollowSymLink'; Commands = @('Get-ChildItem'); Parameters = @('FollowSymLink'); Version = '5.1'; OS = 'Windows'; ProblemCount = 1 } + @{ Target = $script:Srv2019_5_profile; Script = 'Import-Module "MyModule" -ErrorAction SilentlyContinue'; Commands = @(); Parameters = @(); Version = '5.1'; OS = 'Windows'; ProblemCount = 0 } + @{ Target = $script:Srv2019_5_profile; Script = 'Get-Location | Split-Path -LeafBase'; Commands = @('Split-Path'); Parameters = @('LeafBase'); Version = '5.1'; OS = 'Windows'; ProblemCount = 1 } + @{ Target = $script:Srv2019_5_profile; Script = 'Get-Process | sort PagedMemorySize -Top 10'; Commands = @('sort'); Parameters = @('Top'); Version = '5.1'; OS = 'Windows'; ProblemCount = 1 } + @{ Target = $script:Srv2019_5_profile; Script = 'Get-Process | select -first 1 | Out-String -NoNewline'; Commands = @('Out-String'); Parameters = @('NoNewline'); Version = '5.1'; OS = 'Windows'; ProblemCount = 1 } + + @{ Target = $script:Srv2019_6_2_profile; Script = 'Get-Help "Invoke-WebRequest" -ShowWindow'; Commands = @('Get-Help'); Parameters = @('ShowWindow'); Version = "6.2"; OS = 'Windows'; ProblemCount = 1 } + @{ Target = $script:Srv2019_6_2_profile; Script = 'Start-Service "eventlog" -ComputerName "MyComputer"'; Commands = @('Start-Service'); Parameters = @('ComputerName'); Version = "6.2"; OS = 'Windows'; ProblemCount = 1 } + + @{ Target = $script:Srv2019_7_profile; Script = 'Get-Help "Invoke-WebRequest" -ShowWindow'; Commands = @(); Parameters = @(); Version = "7.0"; OS = 'Windows'; ProblemCount = 0 } + @{ Target = $script:Srv2019_7_profile; Script = 'Start-Service "eventlog" -ComputerName "MyComputer"'; Commands = @('Start-Service'); Parameters = @('ComputerName'); Version = "7.0"; OS = 'Windows'; ProblemCount = 1 } + ) +} + Describe 'UseCompatibleCommands' { Context 'Targeting a single profile' { diff --git a/Tests/Rules/UseCompatibleSyntax.Tests.ps1 b/Tests/Rules/UseCompatibleSyntax.Tests.ps1 index 150ef2ecf..adc5b00fd 100644 --- a/Tests/Rules/UseCompatibleSyntax.Tests.ps1 +++ b/Tests/Rules/UseCompatibleSyntax.Tests.ps1 @@ -1,7 +1,9 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. -$script:RuleName = 'PSUseCompatibleSyntax' +BeforeAll { + $script:RuleName = 'PSUseCompatibleSyntax' +} Describe "PSUseCompatibleSyntax" { BeforeAll { diff --git a/Tests/Rules/UseCompatibleTypes.Tests.ps1 b/Tests/Rules/UseCompatibleTypes.Tests.ps1 index 9d7a191a4..83380c7ae 100644 --- a/Tests/Rules/UseCompatibleTypes.Tests.ps1 +++ b/Tests/Rules/UseCompatibleTypes.Tests.ps1 @@ -1,71 +1,74 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. -$script:RuleName = 'PSUseCompatibleTypes' -$script:AnyProfileConfigKey = 'AnyProfilePath' -$script:TargetProfileConfigKey = 'TargetProfiles' - -$script:Srv2012_3_profile = 'win-8_x64_6.2.9200.0_3.0_x64_4.0.30319.42000_framework' -$script:Srv2012r2_4_profile = 'win-8_x64_6.3.9600.0_4.0_x64_4.0.30319.42000_framework' -$script:Srv2016_5_profile = 'win-8_x64_10.0.14393.0_5.1.14393.2791_x64_4.0.30319.42000_framework' -$script:Srv2016_6_2_profile = 'win-8_x64_10.0.14393.0_6.2.4_x64_4.0.30319.42000_core' -$script:Srv2016_7_profile = 'win-8_x64_10.0.14393.0_7.0.0_x64_3.1.2_core' -$script:Srv2019_5_profile = 'win-8_x64_10.0.17763.0_5.1.17763.316_x64_4.0.30319.42000_framework' -$script:Srv2019_6_2_profile = 'win-8_x64_10.0.17763.0_6.2.4_x64_4.0.30319.42000_core' -$script:Srv2019_7_profile = 'win-8_x64_10.0.17763.0_7.0.0_x64_3.1.2_core' -$script:Win10_5_profile = 'win-48_x64_10.0.17763.0_5.1.17763.316_x64_4.0.30319.42000_framework' -$script:Win10_6_2_profile = 'win-4_x64_10.0.18362.0_6.2.4_x64_4.0.30319.42000_core' -$script:Win10_7_profile = 'win-4_x64_10.0.18362.0_7.0.0_x64_3.1.2_core' -$script:Ubuntu1804_6_2_profile = 'ubuntu_x64_18.04_6.2.4_x64_4.0.30319.42000_core' -$script:Ubuntu1804_7_profile = 'ubuntu_x64_18.04_7.0.0_x64_3.1.2_core' - -$script:AzF_profile = (Resolve-Path "$PSScriptRoot/../../PSCompatibilityCollector/optional_profiles/azurefunctions.json").Path -$script:AzA_profile = (Resolve-Path "$PSScriptRoot/../../PSCompatibilityCollector/optional_profiles/azureautomation.json").Path - -$script:TypeCompatibilityTestCases = @( - @{ Target = $script:Srv2012_3_profile; Script = '[System.Management.Automation.ModuleIntrinsics]::GetModulePath("here", "there", "everywhere")'; Types = @('System.Management.Automation.ModuleIntrinsics'); Version = "3.0"; OS = 'Windows'; ProblemCount = 1 } - @{ Target = $script:Srv2012_3_profile; Script = '$ast -is [System.Management.Automation.Language.FunctionMemberAst]'; Types = @('System.Management.Automation.Language.FunctionMemberAst'); Version = "3.0"; OS = 'Windows'; ProblemCount = 1 } - @{ Target = $script:Srv2012_3_profile; Script = '$version = [System.Management.Automation.SemanticVersion]::Parse($version)'; Types = @('System.Management.Automation.SemanticVersion'); Version = "3.0"; OS = 'Windows'; ProblemCount = 1 } - @{ Target = $script:Srv2012_3_profile; Script = '$kw = New-Object "System.Management.Automation.Language.DynamicKeyword"'; Types = @('System.Management.Automation.Language.DynamicKeyword'); Version = "3.0"; OS = 'Windows'; ProblemCount = 1 } - @{ Target = $script:Srv2012_3_profile; Script = '& { param([Parameter(Position=0)][ArgumentCompleter({"Banana"})][string]$Hello) $Hello } "Banana"'; Types = @('ArgumentCompleter'); Version = "3.0"; OS = 'Windows'; ProblemCount = 1 } - - @{ Target = $script:Srv2012r2_4_profile; Script = '[WildcardPattern]"bicycle*"'; Types = @('WildcardPattern'); Version = "4.0"; OS = 'Windows'; ProblemCount = 1 } - @{ Target = $script:Srv2012r2_4_profile; Script = '$client = [System.Net.Http.HttpClient]::new()'; Types = @('System.Net.Http.HttpClient'); Version = "4.0"; OS = 'Windows'; ProblemCount = 1 } - @{ Target = $script:Srv2012r2_4_profile; Script = '[Microsoft.PowerShell.EditMode]"Vi"'; Types = @('Microsoft.PowerShell.EditMode'); Version = "4.0"; OS = 'Windows'; ProblemCount = 1 } - - @{ Target = $script:Srv2019_5_profile; Script = '[Microsoft.PowerShell.Commands.WebSslProtocol]::Default -eq "Tls12"'; Types = @('Microsoft.PowerShell.Commands.WebSslProtocol'); Version = "5.1"; OS = 'Windows'; ProblemCount = 1 } - @{ Target = $script:Srv2019_5_profile; Script = '[System.Collections.Immutable.ImmutableList[string]]::Empty'; Types = @('System.Collections.Immutable.ImmutableList'); Version = "5.1"; OS = 'Windows'; ProblemCount = 1 } - @{ Target = $script:Srv2019_5_profile; Script = '[System.Collections.Generic.TreeSet[string]]::new(@("duck", "goose", "banana"))'; Types = @('System.Collections.Generic.TreeSet'); Version = "5.1"; OS = 'Windows'; ProblemCount = 1 } - - @{ Target = $script:Srv2019_6_2_profile; Script = 'function CertFunc { param([System.Net.ICertificatePolicy]$Policy) Do-Something $Policy }'; Types = @('System.Net.ICertificatePolicy'); Version = "6.2"; OS = 'Windows'; ProblemCount = 1 } - - @{ Target = $script:Srv2019_7_profile; Script = 'function CertFunc { param([System.Net.ICertificatePolicy]$Policy) Do-Something $Policy }'; Types = @('System.Net.ICertificatePolicy'); Version = "7.0"; OS = 'Windows'; ProblemCount = 1 } - - @{ Target = $script:Ubuntu1804_6_2_profile; Script = '[System.Management.Automation.Security.SystemPolicy]::GetSystemLockdownPolicy()'; Types = @('System.Management.Automation.Security.SystemPolicy'); Version = "6.2"; OS = 'Linux'; ProblemCount = 1 } - @{ Target = $script:Ubuntu1804_6_2_profile; Script = '[System.Management.Automation.Security.SystemPolicy]::GetSystemLockdownPolicy()'; Types = @('System.Management.Automation.Security.SystemPolicy'); Version = "6.2"; OS = 'Linux'; ProblemCount = 1 } - @{ Target = $script:Ubuntu1804_6_2_profile; Script = '[System.Management.Automation.Security.SystemEnforcementMode]$enforcementMode = "Audit"'; Types = @('System.Management.Automation.Security.SystemEnforcementMode'); Version = "6.2"; OS = 'Linux'; ProblemCount = 1 } - @{ Target = $script:Ubuntu1804_6_2_profile; Script = '$ci = New-Object "Microsoft.PowerShell.Commands.ComputerInfo"'; Types = @('Microsoft.PowerShell.Commands.ComputerInfo'); Version = "6.2"; OS = 'Linux'; ProblemCount = 1 } - - @{ Target = $script:Ubuntu1804_7_profile; Script = '[System.Management.Automation.Security.SystemPolicy]::GetSystemLockdownPolicy()'; Types = @('System.Management.Automation.Security.SystemPolicy'); Version = "7.0"; OS = 'Linux'; ProblemCount = 1 } - @{ Target = $script:Ubuntu1804_7_profile; Script = '[System.Management.Automation.Security.SystemPolicy]::GetSystemLockdownPolicy()'; Types = @('System.Management.Automation.Security.SystemPolicy'); Version = "7.0"; OS = 'Linux'; ProblemCount = 1 } - @{ Target = $script:Ubuntu1804_7_profile; Script = '[System.Management.Automation.Security.SystemEnforcementMode]$enforcementMode = "Audit"'; Types = @('System.Management.Automation.Security.SystemEnforcementMode'); Version = "7.0"; OS = 'Linux'; ProblemCount = 1 } - @{ Target = $script:Ubuntu1804_7_profile; Script = '$ci = New-Object "Microsoft.PowerShell.Commands.ComputerInfo"'; Types = @('Microsoft.PowerShell.Commands.ComputerInfo'); Version = "7.0"; OS = 'Linux'; ProblemCount = 1 } -) - -$script:MemberCompatibilityTestCases = @( - @{ Target = $script:Srv2012_3_profile; Script = '[System.Management.Automation.LanguagePrimitives]::ConvertTypeNameToPSTypeName("System.String")'; Types = @('System.Management.Automation.LanguagePrimitives'); Members = @('ConvertTypeNameToPSTypeName'); Version = "3.0"; OS = 'Windows'; ProblemCount = 1 } - @{ Target = $script:Srv2012_3_profile; Script = '[System.Management.Automation.WildcardPattern]::Get("banana*", "None").IsMatch("bananaduck")'; Types = @('System.Management.Automation.WildcardPattern'); Members = @('Get'); Version = "3.0"; OS = 'Windows'; ProblemCount = 1 } - - @{ Target = $script:Srv2012r2_4_profile; Script = 'if (-not [Microsoft.PowerShell.Commands.ModuleSpecification]::TryParse($msStr, [ref]$modSpec)){ throw "Bad!" }'; Types = @('Microsoft.PowerShell.Commands.ModuleSpecification'); Members = @('TryParse'); Version = "4.0"; OS = 'Windows'; ProblemCount = 1 } - @{ Target = $script:Srv2012r2_4_profile; Script = '[System.Management.Automation.LanguagePrimitives]::IsObjectEnumerable($obj)'; Types = @('System.Management.Automation.LanguagePrimitives'); Members = @('IsObjectEnumerable'); Version = "4.0"; OS = 'Windows'; ProblemCount = 1 } - - @{ Target = $script:Srv2019_5_profile; Script = '$socket = [System.Net.WebSockets.WebSocket]::CreateFromStream($stream, $true, "http", [timespan]::FromMinutes(10))'; Types = @('System.Net.WebSockets.WebSocket'); Members = @('CreateFromStream'); Version = "5.1"; OS = 'Windows'; ProblemCount = 1 } - @{ Target = $script:Srv2019_5_profile; Script = '[System.Management.Automation.HostUtilities]::InvokeOnRunspace($command, $runspace)'; Types = @('System.Management.Automation.HostUtilities'); Members = @('InvokeOnRunspace'); Version = "5.1"; OS = 'Windows'; ProblemCount = 1 } - - @{ Target = $script:Ubuntu1804_6_2_profile; Script = '[System.Management.Automation.Tracing.Tracer]::GetExceptionString($e)'; Types = @('System.Management.Automation.Tracing.Tracer'); Members = @('GetExceptionString'); Version = "6.2"; OS = 'Linux'; ProblemCount = 1 } - - @{ Target = $script:Ubuntu1804_7_profile; Script = '[System.Management.Automation.Tracing.Tracer]::GetExceptionString($e)'; Types = @('System.Management.Automation.Tracing.Tracer'); Members = @('GetExceptionString'); Version = "7.0"; OS = 'Linux'; ProblemCount = 1 } -) +BeforeAll { + $script:RuleName = 'PSUseCompatibleTypes' + $script:AnyProfileConfigKey = 'AnyProfilePath' + $script:TargetProfileConfigKey = 'TargetProfiles' + + $script:Srv2012_3_profile = 'win-8_x64_6.2.9200.0_3.0_x64_4.0.30319.42000_framework' + $script:Srv2012r2_4_profile = 'win-8_x64_6.3.9600.0_4.0_x64_4.0.30319.42000_framework' + $script:Srv2016_5_profile = 'win-8_x64_10.0.14393.0_5.1.14393.2791_x64_4.0.30319.42000_framework' + $script:Srv2016_6_2_profile = 'win-8_x64_10.0.14393.0_6.2.4_x64_4.0.30319.42000_core' + $script:Srv2016_7_profile = 'win-8_x64_10.0.14393.0_7.0.0_x64_3.1.2_core' + $script:Srv2019_5_profile = 'win-8_x64_10.0.17763.0_5.1.17763.316_x64_4.0.30319.42000_framework' + $script:Srv2019_6_2_profile = 'win-8_x64_10.0.17763.0_6.2.4_x64_4.0.30319.42000_core' + $script:Srv2019_7_profile = 'win-8_x64_10.0.17763.0_7.0.0_x64_3.1.2_core' + $script:Win10_5_profile = 'win-48_x64_10.0.17763.0_5.1.17763.316_x64_4.0.30319.42000_framework' + $script:Win10_6_2_profile = 'win-4_x64_10.0.18362.0_6.2.4_x64_4.0.30319.42000_core' + $script:Win10_7_profile = 'win-4_x64_10.0.18362.0_7.0.0_x64_3.1.2_core' + $script:Ubuntu1804_6_2_profile = 'ubuntu_x64_18.04_6.2.4_x64_4.0.30319.42000_core' + $script:Ubuntu1804_7_profile = 'ubuntu_x64_18.04_7.0.0_x64_3.1.2_core' + + $script:AzF_profile = (Resolve-Path "$PSScriptRoot/../../PSCompatibilityCollector/optional_profiles/azurefunctions.json").Path + $script:AzA_profile = (Resolve-Path "$PSScriptRoot/../../PSCompatibilityCollector/optional_profiles/azureautomation.json").Path + + $script:TypeCompatibilityTestCases = @( + @{ Target = $script:Srv2012_3_profile; Script = '[System.Management.Automation.ModuleIntrinsics]::GetModulePath("here", "there", "everywhere")'; Types = @('System.Management.Automation.ModuleIntrinsics'); Version = "3.0"; OS = 'Windows'; ProblemCount = 1 } + @{ Target = $script:Srv2012_3_profile; Script = '$ast -is [System.Management.Automation.Language.FunctionMemberAst]'; Types = @('System.Management.Automation.Language.FunctionMemberAst'); Version = "3.0"; OS = 'Windows'; ProblemCount = 1 } + @{ Target = $script:Srv2012_3_profile; Script = '$version = [System.Management.Automation.SemanticVersion]::Parse($version)'; Types = @('System.Management.Automation.SemanticVersion'); Version = "3.0"; OS = 'Windows'; ProblemCount = 1 } + @{ Target = $script:Srv2012_3_profile; Script = '$kw = New-Object "System.Management.Automation.Language.DynamicKeyword"'; Types = @('System.Management.Automation.Language.DynamicKeyword'); Version = "3.0"; OS = 'Windows'; ProblemCount = 1 } + @{ Target = $script:Srv2012_3_profile; Script = '& { param([Parameter(Position=0)][ArgumentCompleter({"Banana"})][string]$Hello) $Hello } "Banana"'; Types = @('ArgumentCompleter'); Version = "3.0"; OS = 'Windows'; ProblemCount = 1 } + + @{ Target = $script:Srv2012r2_4_profile; Script = '[WildcardPattern]"bicycle*"'; Types = @('WildcardPattern'); Version = "4.0"; OS = 'Windows'; ProblemCount = 1 } + @{ Target = $script:Srv2012r2_4_profile; Script = '$client = [System.Net.Http.HttpClient]::new()'; Types = @('System.Net.Http.HttpClient'); Version = "4.0"; OS = 'Windows'; ProblemCount = 1 } + @{ Target = $script:Srv2012r2_4_profile; Script = '[Microsoft.PowerShell.EditMode]"Vi"'; Types = @('Microsoft.PowerShell.EditMode'); Version = "4.0"; OS = 'Windows'; ProblemCount = 1 } + + @{ Target = $script:Srv2019_5_profile; Script = '[Microsoft.PowerShell.Commands.WebSslProtocol]::Default -eq "Tls12"'; Types = @('Microsoft.PowerShell.Commands.WebSslProtocol'); Version = "5.1"; OS = 'Windows'; ProblemCount = 1 } + @{ Target = $script:Srv2019_5_profile; Script = '[System.Collections.Immutable.ImmutableList[string]]::Empty'; Types = @('System.Collections.Immutable.ImmutableList'); Version = "5.1"; OS = 'Windows'; ProblemCount = 1 } + @{ Target = $script:Srv2019_5_profile; Script = '[System.Collections.Generic.TreeSet[string]]::new(@("duck", "goose", "banana"))'; Types = @('System.Collections.Generic.TreeSet'); Version = "5.1"; OS = 'Windows'; ProblemCount = 1 } + + @{ Target = $script:Srv2019_6_2_profile; Script = 'function CertFunc { param([System.Net.ICertificatePolicy]$Policy) Do-Something $Policy }'; Types = @('System.Net.ICertificatePolicy'); Version = "6.2"; OS = 'Windows'; ProblemCount = 1 } + + @{ Target = $script:Srv2019_7_profile; Script = 'function CertFunc { param([System.Net.ICertificatePolicy]$Policy) Do-Something $Policy }'; Types = @('System.Net.ICertificatePolicy'); Version = "7.0"; OS = 'Windows'; ProblemCount = 1 } + + @{ Target = $script:Ubuntu1804_6_2_profile; Script = '[System.Management.Automation.Security.SystemPolicy]::GetSystemLockdownPolicy()'; Types = @('System.Management.Automation.Security.SystemPolicy'); Version = "6.2"; OS = 'Linux'; ProblemCount = 1 } + @{ Target = $script:Ubuntu1804_6_2_profile; Script = '[System.Management.Automation.Security.SystemPolicy]::GetSystemLockdownPolicy()'; Types = @('System.Management.Automation.Security.SystemPolicy'); Version = "6.2"; OS = 'Linux'; ProblemCount = 1 } + @{ Target = $script:Ubuntu1804_6_2_profile; Script = '[System.Management.Automation.Security.SystemEnforcementMode]$enforcementMode = "Audit"'; Types = @('System.Management.Automation.Security.SystemEnforcementMode'); Version = "6.2"; OS = 'Linux'; ProblemCount = 1 } + @{ Target = $script:Ubuntu1804_6_2_profile; Script = '$ci = New-Object "Microsoft.PowerShell.Commands.ComputerInfo"'; Types = @('Microsoft.PowerShell.Commands.ComputerInfo'); Version = "6.2"; OS = 'Linux'; ProblemCount = 1 } + + @{ Target = $script:Ubuntu1804_7_profile; Script = '[System.Management.Automation.Security.SystemPolicy]::GetSystemLockdownPolicy()'; Types = @('System.Management.Automation.Security.SystemPolicy'); Version = "7.0"; OS = 'Linux'; ProblemCount = 1 } + @{ Target = $script:Ubuntu1804_7_profile; Script = '[System.Management.Automation.Security.SystemPolicy]::GetSystemLockdownPolicy()'; Types = @('System.Management.Automation.Security.SystemPolicy'); Version = "7.0"; OS = 'Linux'; ProblemCount = 1 } + @{ Target = $script:Ubuntu1804_7_profile; Script = '[System.Management.Automation.Security.SystemEnforcementMode]$enforcementMode = "Audit"'; Types = @('System.Management.Automation.Security.SystemEnforcementMode'); Version = "7.0"; OS = 'Linux'; ProblemCount = 1 } + @{ Target = $script:Ubuntu1804_7_profile; Script = '$ci = New-Object "Microsoft.PowerShell.Commands.ComputerInfo"'; Types = @('Microsoft.PowerShell.Commands.ComputerInfo'); Version = "7.0"; OS = 'Linux'; ProblemCount = 1 } + ) + + $script:MemberCompatibilityTestCases = @( + @{ Target = $script:Srv2012_3_profile; Script = '[System.Management.Automation.LanguagePrimitives]::ConvertTypeNameToPSTypeName("System.String")'; Types = @('System.Management.Automation.LanguagePrimitives'); Members = @('ConvertTypeNameToPSTypeName'); Version = "3.0"; OS = 'Windows'; ProblemCount = 1 } + @{ Target = $script:Srv2012_3_profile; Script = '[System.Management.Automation.WildcardPattern]::Get("banana*", "None").IsMatch("bananaduck")'; Types = @('System.Management.Automation.WildcardPattern'); Members = @('Get'); Version = "3.0"; OS = 'Windows'; ProblemCount = 1 } + + @{ Target = $script:Srv2012r2_4_profile; Script = 'if (-not [Microsoft.PowerShell.Commands.ModuleSpecification]::TryParse($msStr, [ref]$modSpec)){ throw "Bad!" }'; Types = @('Microsoft.PowerShell.Commands.ModuleSpecification'); Members = @('TryParse'); Version = "4.0"; OS = 'Windows'; ProblemCount = 1 } + @{ Target = $script:Srv2012r2_4_profile; Script = '[System.Management.Automation.LanguagePrimitives]::IsObjectEnumerable($obj)'; Types = @('System.Management.Automation.LanguagePrimitives'); Members = @('IsObjectEnumerable'); Version = "4.0"; OS = 'Windows'; ProblemCount = 1 } + + @{ Target = $script:Srv2019_5_profile; Script = '$socket = [System.Net.WebSockets.WebSocket]::CreateFromStream($stream, $true, "http", [timespan]::FromMinutes(10))'; Types = @('System.Net.WebSockets.WebSocket'); Members = @('CreateFromStream'); Version = "5.1"; OS = 'Windows'; ProblemCount = 1 } + @{ Target = $script:Srv2019_5_profile; Script = '[System.Management.Automation.HostUtilities]::InvokeOnRunspace($command, $runspace)'; Types = @('System.Management.Automation.HostUtilities'); Members = @('InvokeOnRunspace'); Version = "5.1"; OS = 'Windows'; ProblemCount = 1 } + + @{ Target = $script:Ubuntu1804_6_2_profile; Script = '[System.Management.Automation.Tracing.Tracer]::GetExceptionString($e)'; Types = @('System.Management.Automation.Tracing.Tracer'); Members = @('GetExceptionString'); Version = "6.2"; OS = 'Linux'; ProblemCount = 1 } + + @{ Target = $script:Ubuntu1804_7_profile; Script = '[System.Management.Automation.Tracing.Tracer]::GetExceptionString($e)'; Types = @('System.Management.Automation.Tracing.Tracer'); Members = @('GetExceptionString'); Version = "7.0"; OS = 'Linux'; ProblemCount = 1 } + ) +} + Describe 'UseCompatibleTypes' { Context 'Targeting a single profile' { diff --git a/Tests/Rules/UseConsistentIndentation.tests.ps1 b/Tests/Rules/UseConsistentIndentation.tests.ps1 index 06dbea290..011b18fcd 100644 --- a/Tests/Rules/UseConsistentIndentation.tests.ps1 +++ b/Tests/Rules/UseConsistentIndentation.tests.ps1 @@ -1,6 +1,10 @@ -$testRootDirectory = Split-Path -Parent $PSScriptRoot -Import-Module (Join-Path $testRootDirectory "PSScriptAnalyzerTestHelper.psm1") +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. +BeforeAll { + $testRootDirectory = Split-Path -Parent $PSScriptRoot + Import-Module (Join-Path $testRootDirectory "PSScriptAnalyzerTestHelper.psm1") +} Describe "UseConsistentIndentation" { BeforeAll { diff --git a/Tests/Rules/UseConsistentWhitespace.tests.ps1 b/Tests/Rules/UseConsistentWhitespace.tests.ps1 index 23bf18350..8d253f9f4 100644 --- a/Tests/Rules/UseConsistentWhitespace.tests.ps1 +++ b/Tests/Rules/UseConsistentWhitespace.tests.ps1 @@ -1,25 +1,31 @@ -$testRootDirectory = Split-Path -Parent $PSScriptRoot -Import-Module (Join-Path $testRootDirectory "PSScriptAnalyzerTestHelper.psm1") - -$ruleName = "PSUseConsistentWhitespace" -$ruleConfiguration = @{ - Enable = $true - CheckInnerBrace = $false - CheckOpenBrace = $false - CheckOpenParen = $false - CheckOperator = $false - CheckPipe = $false - CheckSeparator = $false - CheckParameter = $false -} +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +BeforeAll { + $testRootDirectory = Split-Path -Parent $PSScriptRoot + Import-Module (Join-Path $testRootDirectory "PSScriptAnalyzerTestHelper.psm1") + + $ruleName = "PSUseConsistentWhitespace" + $ruleConfiguration = @{ + Enable = $true + CheckInnerBrace = $false + CheckOpenBrace = $false + CheckOpenParen = $false + CheckOperator = $false + CheckPipe = $false + CheckSeparator = $false + CheckParameter = $false + } -$settings = @{ - IncludeRules = @($ruleName) - Rules = @{ - PSUseConsistentWhitespace = $ruleConfiguration + $settings = @{ + IncludeRules = @($ruleName) + Rules = @{ + PSUseConsistentWhitespace = $ruleConfiguration + } } } + Describe "UseWhitespace" { Context "When an open brace follows a keyword" { BeforeAll { diff --git a/Tests/Rules/UseCorrectCasing.tests.ps1 b/Tests/Rules/UseCorrectCasing.tests.ps1 index 61d75b408..7343677ff 100644 --- a/Tests/Rules/UseCorrectCasing.tests.ps1 +++ b/Tests/Rules/UseCorrectCasing.tests.ps1 @@ -1,3 +1,6 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + Describe "UseCorrectCasing" { It "corrects case of simple cmdlet" { Invoke-Formatter 'get-childitem' | Should -Be 'Get-ChildItem' diff --git a/Tests/Rules/UseDSCResourceFunctions.tests.ps1 b/Tests/Rules/UseDSCResourceFunctions.tests.ps1 index f88801a21..963bfc20b 100644 --- a/Tests/Rules/UseDSCResourceFunctions.tests.ps1 +++ b/Tests/Rules/UseDSCResourceFunctions.tests.ps1 @@ -1,16 +1,21 @@ - -$violationMessage = "Missing 'Get-TargetResource' function. DSC Resource must implement Get, Set and Test-TargetResource functions." -$classViolationMessage = "Missing 'Set' function. DSC Class must implement Get, Set and Test functions." -$violationName = "PSDSCStandardDSCFunctionsInResource" -$violations = Invoke-ScriptAnalyzer $PSScriptRoot\DSCResourceModule\DSCResources\MSFT_WaitForAll\MSFT_WaitForAll.psm1 | Where-Object {$_.RuleName -eq $violationName} -$noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\DSCResourceModule\DSCResources\MSFT_WaitForAny\MSFT_WaitForAny.psm1 | Where-Object {$_.RuleName -eq $violationName} - -if ($PSVersionTable.PSVersion -ge [Version]'5.0.0') -{ - $classViolations = Invoke-ScriptAnalyzer -ErrorAction SilentlyContinue $PSScriptRoot\DSCResourceModule\DSCResources\BadDscResource\BadDscResource.psm1 | Where-Object {$_.RuleName -eq $violationName} - $noClassViolations = Invoke-ScriptAnalyzer -ErrorAction SilentlyContinue $PSScriptRoot\DSCResourceModule\DSCResources\MyDscResource\MyDscResource.psm1 | Where-Object {$_.RuleName -eq $violationName} +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +BeforeAll { + $violationMessage = "Missing 'Get-TargetResource' function. DSC Resource must implement Get, Set and Test-TargetResource functions." + $classViolationMessage = "Missing 'Set' function. DSC Class must implement Get, Set and Test functions." + $violationName = "PSDSCStandardDSCFunctionsInResource" + $violations = Invoke-ScriptAnalyzer $PSScriptRoot\DSCResourceModule\DSCResources\MSFT_WaitForAll\MSFT_WaitForAll.psm1 | Where-Object {$_.RuleName -eq $violationName} + $noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\DSCResourceModule\DSCResources\MSFT_WaitForAny\MSFT_WaitForAny.psm1 | Where-Object {$_.RuleName -eq $violationName} + + if ($PSVersionTable.PSVersion -ge [Version]'5.0.0') + { + $classViolations = Invoke-ScriptAnalyzer -ErrorAction SilentlyContinue $PSScriptRoot\DSCResourceModule\DSCResources\BadDscResource\BadDscResource.psm1 | Where-Object {$_.RuleName -eq $violationName} + $noClassViolations = Invoke-ScriptAnalyzer -ErrorAction SilentlyContinue $PSScriptRoot\DSCResourceModule\DSCResources\MyDscResource\MyDscResource.psm1 | Where-Object {$_.RuleName -eq $violationName} + } } + Describe "StandardDSCFunctionsInResource" { Context "When there are violations" { It "has 1 missing standard DSC functions violation" { @@ -29,8 +34,7 @@ Describe "StandardDSCFunctionsInResource" { } } -if ($PSVersionTable.PSVersion -ge [Version]'5.0.0') { - Describe "StandardDSCFunctionsInClass" { +Describe "StandardDSCFunctionsInClass" -Skip:($PSVersionTable.PSVersion -lt [Version]'5.0.0') { Context "When there are violations" { It "has 1 missing standard DSC functions violation" { $classViolations.Count | Should -Be 1 @@ -46,5 +50,4 @@ if ($PSVersionTable.PSVersion -ge [Version]'5.0.0') { $noClassViolations.Count | Should -Be 0 } } - } } diff --git a/Tests/Rules/UseDeclaredVarsMoreThanAssignments.tests.ps1 b/Tests/Rules/UseDeclaredVarsMoreThanAssignments.tests.ps1 index c81fc74f7..983ac017f 100644 --- a/Tests/Rules/UseDeclaredVarsMoreThanAssignments.tests.ps1 +++ b/Tests/Rules/UseDeclaredVarsMoreThanAssignments.tests.ps1 @@ -1,10 +1,15 @@ -$testRootDirectory = Split-Path -Parent $PSScriptRoot -Import-Module (Join-Path $testRootDirectory 'PSScriptAnalyzerTestHelper.psm1') +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. -$violationMessage = "The variable 'declaredVar2' is assigned but never used." -$violationName = "PSUseDeclaredVarsMoreThanAssignments" -$violations = Invoke-ScriptAnalyzer $PSScriptRoot\UseDeclaredVarsMoreThanAssignments.ps1 | Where-Object {$_.RuleName -eq $violationName} -$noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\UseDeclaredVarsMoreThanAssignmentsNoViolations.ps1 | Where-Object {$_.RuleName -eq $violationName} +BeforeAll { + $testRootDirectory = Split-Path -Parent $PSScriptRoot + Import-Module (Join-Path $testRootDirectory 'PSScriptAnalyzerTestHelper.psm1') + + $violationMessage = "The variable 'declaredVar2' is assigned but never used." + $violationName = "PSUseDeclaredVarsMoreThanAssignments" + $violations = Invoke-ScriptAnalyzer $PSScriptRoot\UseDeclaredVarsMoreThanAssignments.ps1 | Where-Object {$_.RuleName -eq $violationName} + $noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\UseDeclaredVarsMoreThanAssignmentsNoViolations.ps1 | Where-Object {$_.RuleName -eq $violationName} +} Describe "UseDeclaredVarsMoreThanAssignments" { Context "When there are violations" { diff --git a/Tests/Rules/UseIdenticalMandatoryParametersForDSC.tests.ps1 b/Tests/Rules/UseIdenticalMandatoryParametersForDSC.tests.ps1 index d8e96c709..6e22acc32 100644 --- a/Tests/Rules/UseIdenticalMandatoryParametersForDSC.tests.ps1 +++ b/Tests/Rules/UseIdenticalMandatoryParametersForDSC.tests.ps1 @@ -1,11 +1,15 @@ -$ruleName = 'PSDSCUseIdenticalMandatoryParametersForDSC' -$resourceBasepath = "$PSScriptRoot\DSCResourceModule\DSCResources" -$badResourceFilepath = [System.IO.Path]::Combine( - $resourceBasepath, - 'MSFT_WaitForAnyNoIdenticalMandatoryParameter', - 'MSFT_WaitForAnyNoIdenticalMandatoryParameter.psm1'); -$goodResourceFilepath = [System.IO.Path]::Combine($resourceBasepath,'MSFT_WaitForAny','MSFT_WaitForAny.psm1'); - +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +BeforeAll { + $ruleName = 'PSDSCUseIdenticalMandatoryParametersForDSC' + $resourceBasepath = "$PSScriptRoot\DSCResourceModule\DSCResources" + $badResourceFilepath = [System.IO.Path]::Combine( + $resourceBasepath, + 'MSFT_WaitForAnyNoIdenticalMandatoryParameter', + 'MSFT_WaitForAnyNoIdenticalMandatoryParameter.psm1') + $goodResourceFilepath = [System.IO.Path]::Combine($resourceBasepath,'MSFT_WaitForAny','MSFT_WaitForAny.psm1') +} Describe "UseIdenticalMandatoryParametersForDSC" { Context "When a mandatory parameters are not present" { diff --git a/Tests/Rules/UseIdenticalParametersDSC.tests.ps1 b/Tests/Rules/UseIdenticalParametersDSC.tests.ps1 index 36250cd04..c47a2bf56 100644 --- a/Tests/Rules/UseIdenticalParametersDSC.tests.ps1 +++ b/Tests/Rules/UseIdenticalParametersDSC.tests.ps1 @@ -1,13 +1,19 @@ -$violationMessage = "The Test and Set-TargetResource functions of DSC Resource must have the same parameters." -$violationName = "PSDSCUseIdenticalParametersForDSC" -$violations = Invoke-ScriptAnalyzer $PSScriptRoot\DSCResourceModule\DSCResources\MSFT_WaitForAll\MSFT_WaitForAll.psm1 | Where-Object {$_.RuleName -eq $violationName} -$noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\DSCResourceModule\DSCResources\MSFT_WaitForAny\MSFT_WaitForAny.psm1 | Where-Object {$_.RuleName -eq $violationName} - -if ($PSVersionTable.PSVersion -ge [Version]'5.0.0') -{ - $noClassViolations = Invoke-ScriptAnalyzer -ErrorAction SilentlyContinue $PSScriptRoot\DSCResourceModule\DSCResources\MyDscResource\MyDscResource.psm1 | Where-Object {$_.RuleName -eq $violationName} +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +BeforeAll { + $violationMessage = "The Test and Set-TargetResource functions of DSC Resource must have the same parameters." + $violationName = "PSDSCUseIdenticalParametersForDSC" + $violations = Invoke-ScriptAnalyzer $PSScriptRoot\DSCResourceModule\DSCResources\MSFT_WaitForAll\MSFT_WaitForAll.psm1 | Where-Object {$_.RuleName -eq $violationName} + $noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\DSCResourceModule\DSCResources\MSFT_WaitForAny\MSFT_WaitForAny.psm1 | Where-Object {$_.RuleName -eq $violationName} + + if ($PSVersionTable.PSVersion -ge [Version]'5.0.0') + { + $noClassViolations = Invoke-ScriptAnalyzer -ErrorAction SilentlyContinue $PSScriptRoot\DSCResourceModule\DSCResources\MyDscResource\MyDscResource.psm1 | Where-Object {$_.RuleName -eq $violationName} + } } + Describe "UseIdenticalParametersDSC" { Context "When there are violations" { It "has 1 Use Identical Parameters For DSC violations" { diff --git a/Tests/Rules/UseLiteralInitializerForHashtable.tests.ps1 b/Tests/Rules/UseLiteralInitializerForHashtable.tests.ps1 index 24ce1d574..04a2c55f4 100644 --- a/Tests/Rules/UseLiteralInitializerForHashtable.tests.ps1 +++ b/Tests/Rules/UseLiteralInitializerForHashtable.tests.ps1 @@ -1,4 +1,9 @@ -$ruleName = "PSUseLiteralInitializerForHashtable" +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +BeforeAll { + $ruleName = "PSUseLiteralInitializerForHashtable" +} Describe "UseLiteralInitlializerForHashtable" { Context "When new-object hashtable is used to create a hashtable" { diff --git a/Tests/Rules/UseOutputTypeCorrectly.tests.ps1 b/Tests/Rules/UseOutputTypeCorrectly.tests.ps1 index 8674643d5..8cc657e0b 100644 --- a/Tests/Rules/UseOutputTypeCorrectly.tests.ps1 +++ b/Tests/Rules/UseOutputTypeCorrectly.tests.ps1 @@ -1,13 +1,17 @@ -$violationMessage = "The cmdlet 'Verb-Files' returns an object of type 'System.Collections.Hashtable' but this type is not declared in the OutputType attribute." -$violationName = "PSUseOutputTypeCorrectly" -$violations = Invoke-ScriptAnalyzer $PSScriptRoot\BadCmdlet.ps1 | Where-Object {$_.RuleName -eq $violationName} +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. -if ($PSVersionTable.PSVersion -ge [Version]'5.0.0') -{ - $dscViolations = Invoke-ScriptAnalyzer -ErrorAction SilentlyContinue $PSScriptRoot\DSCResourceModule\DSCResources\MyDscResource\MyDscResource.psm1 | Where-Object {$_.RuleName -eq $violationName} +BeforeAll { + $violationMessage = "The cmdlet 'Verb-Files' returns an object of type 'System.Collections.Hashtable' but this type is not declared in the OutputType attribute." + $violationName = "PSUseOutputTypeCorrectly" + $violations = Invoke-ScriptAnalyzer $PSScriptRoot\BadCmdlet.ps1 | Where-Object {$_.RuleName -eq $violationName} + if ($PSVersionTable.PSVersion -ge [Version]'5.0.0') + { + $dscViolations = Invoke-ScriptAnalyzer -ErrorAction SilentlyContinue $PSScriptRoot\DSCResourceModule\DSCResources\MyDscResource\MyDscResource.psm1 | Where-Object {$_.RuleName -eq $violationName} + } + $noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\GoodCmdlet.ps1 | Where-Object {$_.RuleName -eq $violationName} } -$noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\GoodCmdlet.ps1 | Where-Object {$_.RuleName -eq $violationName} Describe "UseOutputTypeCorrectly" { Context "When there are violations" { diff --git a/Tests/Rules/UseProcessBlockForPipelineCommand.tests.ps1 b/Tests/Rules/UseProcessBlockForPipelineCommand.tests.ps1 index c4caf2c0c..340338a20 100644 --- a/Tests/Rules/UseProcessBlockForPipelineCommand.tests.ps1 +++ b/Tests/Rules/UseProcessBlockForPipelineCommand.tests.ps1 @@ -1,4 +1,7 @@ -Describe "UseProcessBlockForPipelineCommand" { +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +Describe "UseProcessBlockForPipelineCommand" { BeforeAll { $RuleName = 'PSUseProcessBlockForPipelineCommand' } diff --git a/Tests/Rules/UseShouldProcessCorrectly.tests.ps1 b/Tests/Rules/UseShouldProcessCorrectly.tests.ps1 index d870c69ae..fc35051af 100644 --- a/Tests/Rules/UseShouldProcessCorrectly.tests.ps1 +++ b/Tests/Rules/UseShouldProcessCorrectly.tests.ps1 @@ -1,11 +1,16 @@ -$violationMessage = "'Verb-Files' has the ShouldProcess attribute but does not call ShouldProcess/ShouldContinue." -$violationName = "PSShouldProcess" -$testRootDirectory = Split-Path -Parent $PSScriptRoot -Import-Module (Join-Path $testRootDirectory 'PSScriptAnalyzerTestHelper.psm1') +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. -$violations = Invoke-ScriptAnalyzer $PSScriptRoot\BadCmdlet.ps1 | Where-Object {$_.RuleName -eq $violationName} -$noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\GoodCmdlet.ps1 | Where-Object {$_.RuleName -eq $violationName} -$IsV3OrV4 = (Test-PSVersionV3) -or (Test-PSVersionV4) +BeforeAll { + $violationMessage = "'Verb-Files' has the ShouldProcess attribute but does not call ShouldProcess/ShouldContinue." + $violationName = "PSShouldProcess" + $testRootDirectory = Split-Path -Parent $PSScriptRoot + Import-Module (Join-Path $testRootDirectory 'PSScriptAnalyzerTestHelper.psm1') + + $violations = Invoke-ScriptAnalyzer $PSScriptRoot\BadCmdlet.ps1 | Where-Object {$_.RuleName -eq $violationName} + $noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\GoodCmdlet.ps1 | Where-Object {$_.RuleName -eq $violationName} + $IsV3OrV4 = (Test-PSVersionV3) -or (Test-PSVersionV4) +} Describe "UseShouldProcessCorrectly" { Context "When there are violations" { diff --git a/Tests/Rules/UseShouldProcessForStateChangingFunctions.tests.ps1 b/Tests/Rules/UseShouldProcessForStateChangingFunctions.tests.ps1 index ed377f1c0..841a76d3b 100644 --- a/Tests/Rules/UseShouldProcessForStateChangingFunctions.tests.ps1 +++ b/Tests/Rules/UseShouldProcessForStateChangingFunctions.tests.ps1 @@ -1,7 +1,12 @@ -$violationMessage = "Function 'Set-MyObject' has verb that could change system state. Therefore, the function has to support 'ShouldProcess'" -$violationName = "PSUseShouldProcessForStateChangingFunctions" -$violations = Invoke-ScriptAnalyzer $PSScriptRoot\UseShouldProcessForStateChangingFunctions.ps1 | Where-Object {$_.RuleName -eq $violationName} -$noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\UseShouldProcessForStateChangingFunctionsNoViolations.ps1 | Where-Object {$_.RuleName -eq $violationName} +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +BeforeAll { + $violationMessage = "Function 'Set-MyObject' has verb that could change system state. Therefore, the function has to support 'ShouldProcess'" + $violationName = "PSUseShouldProcessForStateChangingFunctions" + $violations = Invoke-ScriptAnalyzer $PSScriptRoot\UseShouldProcessForStateChangingFunctions.ps1 | Where-Object {$_.RuleName -eq $violationName} + $noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\UseShouldProcessForStateChangingFunctionsNoViolations.ps1 | Where-Object {$_.RuleName -eq $violationName} +} Describe "It checks UseShouldProcess is enabled when there are state changing verbs in the function names" { Context "When function name has state changing verb" { diff --git a/Tests/Rules/UseSingularNounsReservedVerbs.tests.ps1 b/Tests/Rules/UseSingularNounsReservedVerbs.tests.ps1 index 66e9bc764..32c7057ea 100644 --- a/Tests/Rules/UseSingularNounsReservedVerbs.tests.ps1 +++ b/Tests/Rules/UseSingularNounsReservedVerbs.tests.ps1 @@ -1,52 +1,54 @@ -$nounViolationMessage = "The cmdlet 'Verb-Files' uses a plural noun. A singular noun should be used instead." -$verbViolationMessage = "The cmdlet 'Verb-Files' uses an unapproved verb." -$nounViolationName = "PSUseSingularNouns" -$verbViolationName = "PSUseApprovedVerbs" -$violations = Invoke-ScriptAnalyzer $PSScriptRoot\BadCmdlet.ps1 -$nounViolations = $violations | Where-Object {$_.RuleName -eq $nounViolationName} -$verbViolations = $violations | Where-Object {$_.RuleName -eq $verbViolationName} -$noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\GoodCmdlet.ps1 -$nounNoViolations = $noViolations | Where-Object {$_.RuleName -eq $nounViolationName} -$verbNoViolations = $noViolations | Where-Object {$_.RuleName -eq $verbViolationName} +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. -# this rule doesn't exist in the non desktop version of PSScriptAnalyzer -if (-not ([bool] $IsCoreCLR)) -{ - Describe "UseSingularNouns" { - Context "When there are violations" { - It "has a cmdlet singular noun violation" { - $nounViolations.Count | Should -Be 1 - } +BeforeAll { + $nounViolationMessage = "The cmdlet 'Verb-Files' uses a plural noun. A singular noun should be used instead." + $verbViolationMessage = "The cmdlet 'Verb-Files' uses an unapproved verb." + $nounViolationName = "PSUseSingularNouns" + $verbViolationName = "PSUseApprovedVerbs" + $violations = Invoke-ScriptAnalyzer $PSScriptRoot\BadCmdlet.ps1 + $nounViolations = $violations | Where-Object {$_.RuleName -eq $nounViolationName} + $verbViolations = $violations | Where-Object {$_.RuleName -eq $verbViolationName} + $noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\GoodCmdlet.ps1 + $nounNoViolations = $noViolations | Where-Object {$_.RuleName -eq $nounViolationName} + $verbNoViolations = $noViolations | Where-Object {$_.RuleName -eq $verbViolationName} +} + +# UseSingularNouns rule doesn't exist in the non desktop version of PSScriptAnalyzer due to missing .Net Pluralization API +Describe "UseSingularNouns" -Skip:([bool] $IsCoreCLR) { + Context "When there are violations" { + It "has a cmdlet singular noun violation" { + $nounViolations.Count | Should -Be 1 + } - It "has the correct description message" { - $nounViolations[0].Message | Should -Match $nounViolationMessage - } + It "has the correct description message" { + $nounViolations[0].Message | Should -Match $nounViolationMessage + } - It "has the correct extent" { - $nounViolations[0].Extent.Text | Should -Be "Verb-Files" - } + It "has the correct extent" { + $nounViolations[0].Extent.Text | Should -Be "Verb-Files" } + } - Context "When function names have nouns from whitelist" { + Context "When function names have nouns from whitelist" { - It "ignores function name ending with Data" { - $nounViolationScript = @' + It "ignores function name ending with Data" { + $nounViolationScript = @' Function Add-SomeData { - Write-Output "Adding some data" +Write-Output "Adding some data" } '@ - Invoke-ScriptAnalyzer -ScriptDefinition $nounViolationScript ` - -IncludeRule "PSUseSingularNouns" ` - -OutVariable violations - $violations.Count | Should -Be 0 - } + Invoke-ScriptAnalyzer -ScriptDefinition $nounViolationScript ` + -IncludeRule "PSUseSingularNouns" ` + -OutVariable violations + $violations.Count | Should -Be 0 } + } - Context "When there are no violations" { - It "returns no violations" { - $nounNoViolations.Count | Should -Be 0 - } + Context "When there are no violations" { + It "returns no violations" { + $nounNoViolations.Count | Should -Be 0 } } } diff --git a/Tests/Rules/UseSupportsShouldProcess.tests.ps1 b/Tests/Rules/UseSupportsShouldProcess.tests.ps1 index ba43c06b0..891ac5e45 100644 --- a/Tests/Rules/UseSupportsShouldProcess.tests.ps1 +++ b/Tests/Rules/UseSupportsShouldProcess.tests.ps1 @@ -1,11 +1,16 @@ -$testRootDirectory = Split-Path -Parent $PSScriptRoot -Import-Module (Join-Path $testRootDirectory "PSScriptAnalyzerTestHelper.psm1") +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. -$settings = @{ - IncludeRules = @("PSUseSupportsShouldProcess") - Rules = @{ - PSUseSupportsShouldProcess = @{ - Enable = $true +BeforeAll { + $testRootDirectory = Split-Path -Parent $PSScriptRoot + Import-Module (Join-Path $testRootDirectory "PSScriptAnalyzerTestHelper.psm1") + + $settings = @{ + IncludeRules = @("PSUseSupportsShouldProcess") + Rules = @{ + PSUseSupportsShouldProcess = @{ + Enable = $true + } } } } diff --git a/Tests/Rules/UseToExportFieldsInManifest.tests.ps1 b/Tests/Rules/UseToExportFieldsInManifest.tests.ps1 index 02ad49471..5fa68aa68 100644 --- a/Tests/Rules/UseToExportFieldsInManifest.tests.ps1 +++ b/Tests/Rules/UseToExportFieldsInManifest.tests.ps1 @@ -1,29 +1,35 @@ -$testRootDirectory = Split-Path -Parent $PSScriptRoot -Import-Module (Join-Path $testRootDirectory 'PSScriptAnalyzerTestHelper.psm1') - -$testManifestPath = Join-Path $PSScriptRoot "TestManifest" -$testManifestBadFunctionsWildcardPath = "ManifestBadFunctionsWildcard.psd1" -$testManifestBadFunctionsWildcardInArrayPath = "ManifestBadFunctionsWildcardInArray.psd1" -$testManifestBadFunctionsNullPath = "ManifestBadFunctionsNull.psd1" -$testManifestBadCmdletsWildcardPath = "ManifestBadCmdletsWildcard.psd1" -$testManifestBadAliasesWildcardPath = "ManifestBadAliasesWildcard.psd1" -$testManifestBadVariablesWildcardPath = "ManifestBadVariablesWildcard.psd1" -$testManifestBadAllPath = "ManifestBadAll.psd1" -$testManifestGoodPath = "ManifestGood.psd1" -$testManifestInvalidPath = "ManifestInvalid.psd1" -Import-Module (Join-Path $PSScriptRoot "PSScriptAnalyzerTestHelper.psm1") - -Function Run-PSScriptAnalyzerRule -{ - Param( - [Parameter(Mandatory)] - [String] $ManifestPath - ) - - Invoke-ScriptAnalyzer -Path (Resolve-Path (Join-Path $testManifestPath $ManifestPath))` - -IncludeRule PSUseToExportFieldsInManifest +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +BeforeAll { + $testRootDirectory = Split-Path -Parent $PSScriptRoot + Import-Module (Join-Path $testRootDirectory 'PSScriptAnalyzerTestHelper.psm1') + + $testManifestPath = Join-Path $PSScriptRoot "TestManifest" + $testManifestBadFunctionsWildcardPath = "ManifestBadFunctionsWildcard.psd1" + $testManifestBadFunctionsWildcardInArrayPath = "ManifestBadFunctionsWildcardInArray.psd1" + $testManifestBadFunctionsNullPath = "ManifestBadFunctionsNull.psd1" + $testManifestBadCmdletsWildcardPath = "ManifestBadCmdletsWildcard.psd1" + $testManifestBadAliasesWildcardPath = "ManifestBadAliasesWildcard.psd1" + $testManifestBadVariablesWildcardPath = "ManifestBadVariablesWildcard.psd1" + $testManifestBadAllPath = "ManifestBadAll.psd1" + $testManifestGoodPath = "ManifestGood.psd1" + $testManifestInvalidPath = "ManifestInvalid.psd1" + Import-Module (Join-Path $PSScriptRoot "PSScriptAnalyzerTestHelper.psm1") + + Function Run-PSScriptAnalyzerRule + { + Param( + [Parameter(Mandatory)] + [String] $ManifestPath + ) + + Invoke-ScriptAnalyzer -Path (Resolve-Path (Join-Path $testManifestPath $ManifestPath))` + -IncludeRule PSUseToExportFieldsInManifest + } } + Describe "UseManifestExportFields" { Context "Invalid manifest file" { @@ -110,5 +116,3 @@ Describe "UseManifestExportFields" { } } } - - diff --git a/Tests/Rules/UseUTF8EncodingForHelpFile.tests.ps1 b/Tests/Rules/UseUTF8EncodingForHelpFile.tests.ps1 index 6404dcab8..b5471f439 100644 --- a/Tests/Rules/UseUTF8EncodingForHelpFile.tests.ps1 +++ b/Tests/Rules/UseUTF8EncodingForHelpFile.tests.ps1 @@ -1,4 +1,7 @@ -Describe "UseUTF8EncodingForHelpFile" { +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +Describe "UseUTF8EncodingForHelpFile" { BeforeAll { $violationMessage = "File about_utf16.help.txt has to use UTF8 instead of System.Text.UTF32Encoding encoding because it is a powershell help file." $violationName = "PSUseUTF8EncodingForHelpFile" diff --git a/Tests/Rules/UseUsingScopeModifierInNewRunspaces.tests.ps1 b/Tests/Rules/UseUsingScopeModifierInNewRunspaces.tests.ps1 index 66452baf6..7ac1870aa 100644 --- a/Tests/Rules/UseUsingScopeModifierInNewRunspaces.tests.ps1 +++ b/Tests/Rules/UseUsingScopeModifierInNewRunspaces.tests.ps1 @@ -1,6 +1,11 @@ -$settings = @{ - IncludeRules = "PSUseUsingScopeModifierInNewRunspaces" - Severity = "warning" # because we need to prevent ParseErrors from being reported, so 'workflow' keyword will not be flagged when running test on Pwsh. +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +BeforeAll { + $settings = @{ + IncludeRules = "PSUseUsingScopeModifierInNewRunspaces" + Severity = "warning" # because we need to prevent ParseErrors from being reported, so 'workflow' keyword will not be flagged when running test on Pwsh. + } } Describe "UseUsingScopeModifierInNewRunspaces" { diff --git a/Tests/Rules/UseVerboseMessageInDSCResource.Tests.ps1 b/Tests/Rules/UseVerboseMessageInDSCResource.Tests.ps1 index c7440c37a..a47ede852 100644 --- a/Tests/Rules/UseVerboseMessageInDSCResource.Tests.ps1 +++ b/Tests/Rules/UseVerboseMessageInDSCResource.Tests.ps1 @@ -1,8 +1,13 @@ -$violationMessage = "There is no call to Write-Verbose in DSC function 'Test-TargetResource'. If you are using Write-Verbose in a helper function, suppress this rule application." -$violationName = "PSDSCUseVerboseMessageInDSCResource" -$violations = Invoke-ScriptAnalyzer $PSScriptRoot\DSCResourceModule\DSCResources\MSFT_WaitForAll\MSFT_WaitForAll.psm1 | Where-Object {$_.RuleName -eq $violationName} -$noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\DSCResourceModule\DSCResources\MSFT_WaitForAny\MSFT_WaitForAny.psm1 | Where-Object {$_.RuleName -eq $violationName} -$noClassViolations = Invoke-ScriptAnalyzer -ErrorAction SilentlyContinue $PSScriptRoot\DSCResourceModule\DSCResources\MyDscResource\MyDscResource.psm1 | Where-Object {$_.RuleName -eq $violationName} +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +BeforeAll { + $violationMessage = "There is no call to Write-Verbose in DSC function 'Test-TargetResource'. If you are using Write-Verbose in a helper function, suppress this rule application." + $violationName = "PSDSCUseVerboseMessageInDSCResource" + $violations = Invoke-ScriptAnalyzer $PSScriptRoot\DSCResourceModule\DSCResources\MSFT_WaitForAll\MSFT_WaitForAll.psm1 | Where-Object {$_.RuleName -eq $violationName} + $noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\DSCResourceModule\DSCResources\MSFT_WaitForAny\MSFT_WaitForAny.psm1 | Where-Object {$_.RuleName -eq $violationName} + $noClassViolations = Invoke-ScriptAnalyzer -ErrorAction SilentlyContinue $PSScriptRoot\DSCResourceModule\DSCResources\MyDscResource\MyDscResource.psm1 | Where-Object {$_.RuleName -eq $violationName} +} Describe "UseVerboseMessageInDSCResource" { Context "When there are violations" { From 765aad31ad065e0290a54d3641990e22bf96e842 Mon Sep 17 00:00:00 2001 From: Christoph Bergmeister Date: Sun, 12 Apr 2020 23:37:14 +0100 Subject: [PATCH 07/76] -AllowPrerelease --- tools/appveyor.psm1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/appveyor.psm1 b/tools/appveyor.psm1 index 36e2e2578..2d7e9d1ae 100644 --- a/tools/appveyor.psm1 +++ b/tools/appveyor.psm1 @@ -15,7 +15,7 @@ function Install-Pester { else { # Visual Studio 2017 build (has already Pester v3, therefore a different installation mechanism is needed to make it also use the new version 4) Write-Verbose -Verbose "Installing Pester via Install-Module" - Install-Module -Name Pester -Force -SkipPublisherCheck -Scope CurrentUser -Repository PSGallery + Install-Module -Name Pester -Force -SkipPublisherCheck -Scope CurrentUser -Repository PSGallery -AllowPrerelease } } } From 7a67f0e428c4768ef2f0339e50d2bfe090ceda76 Mon Sep 17 00:00:00 2001 From: Christoph Bergmeister Date: Sun, 12 Apr 2020 23:38:49 +0100 Subject: [PATCH 08/76] try bootstrap in wmf4 --- tools/appveyor.psm1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/appveyor.psm1 b/tools/appveyor.psm1 index 2d7e9d1ae..f98f8852f 100644 --- a/tools/appveyor.psm1 +++ b/tools/appveyor.psm1 @@ -10,7 +10,7 @@ function Install-Pester { if ($null -eq (Get-Module -ListAvailable PowershellGet)) { # WMF 4 image build Write-Verbose -Verbose "Installing Pester via nuget" - nuget install Pester -Version $requiredPesterVersion -source https://www.powershellgallery.com/api/v2 -outputDirectory "$env:ProgramFiles\WindowsPowerShell\Modules\." -ExcludeVersion + nuget install Pester -Version "${requiredPesterVersion}-rc1" -source https://www.powershellgallery.com/api/v2 -outputDirectory "$env:ProgramFiles\WindowsPowerShell\Modules\." -ExcludeVersion } else { # Visual Studio 2017 build (has already Pester v3, therefore a different installation mechanism is needed to make it also use the new version 4) From 9d1757118c79227c4ff561e2d7477ab5a36b3d3f Mon Sep 17 00:00:00 2001 From: Christoph Bergmeister Date: Sun, 12 Apr 2020 23:53:42 +0100 Subject: [PATCH 09/76] fix invoke-pester call in CI --- tools/appveyor.psm1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/appveyor.psm1 b/tools/appveyor.psm1 index f98f8852f..a37858aa8 100644 --- a/tools/appveyor.psm1 +++ b/tools/appveyor.psm1 @@ -115,7 +115,7 @@ function Invoke-AppveyorTest { [System.Threading.Thread]::CurrentThread.CurrentUICulture = [cultureinfo]::CreateSpecificCulture('tr-TR') # Run all tests - $testResults = Invoke-Pester -Script $testScripts -OutputFormat NUnitXml -OutputFile $testResultsPath -PassThru + $testResults = Invoke-Pester -Path $testScripts -CI # -OutputFormat NUnitXml -OutputFile $testResultsPath -PassThru # Upload the test results if ($env:APPVEYOR) { From 2de4c20fe872728cd085c61d7620379f80b72e55 Mon Sep 17 00:00:00 2001 From: Christoph Bergmeister Date: Sun, 12 Apr 2020 23:59:22 +0100 Subject: [PATCH 10/76] fix CorrectionExtent.tests.ps1 --- Tests/Engine/CorrectionExtent.tests.ps1 | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Tests/Engine/CorrectionExtent.tests.ps1 b/Tests/Engine/CorrectionExtent.tests.ps1 index 6ccf14d00..9269df613 100644 --- a/Tests/Engine/CorrectionExtent.tests.ps1 +++ b/Tests/Engine/CorrectionExtent.tests.ps1 @@ -2,10 +2,9 @@ # Licensed under the MIT License. Describe "Correction Extent" { - $type = [Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic.CorrectionExtent] - Context "Object construction" { It "creates the object with correct properties" { + $type = [Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic.CorrectionExtent] $correctionExtent = $obj = New-Object -TypeName $type -ArgumentList 1, 1, 1, 3, "get-childitem", "newfile", "cool description" $correctionExtent.StartLineNumber | Should -Be 1 From a10983e8a125c6e0561f748a4ecd51561623a57a Mon Sep 17 00:00:00 2001 From: Christoph Bergmeister Date: Mon, 13 Apr 2020 00:02:16 +0100 Subject: [PATCH 11/76] fix Helper.tests.ps1 --- Tests/Engine/Helper.tests.ps1 | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/Tests/Engine/Helper.tests.ps1 b/Tests/Engine/Helper.tests.ps1 index f5a86ecbc..b0932be32 100644 --- a/Tests/Engine/Helper.tests.ps1 +++ b/Tests/Engine/Helper.tests.ps1 @@ -3,16 +3,18 @@ Describe "Test Directed Graph" { Context "When a graph is created" { - $digraph = New-Object -TypeName 'Microsoft.Windows.PowerShell.ScriptAnalyzer.DiGraph[string]' - $digraph.AddVertex('v1'); - $digraph.AddVertex('v2'); - $digraph.AddVertex('v3'); - $digraph.AddVertex('v4'); - $digraph.AddVertex('v5'); + BeforeAll { + $digraph = New-Object -TypeName 'Microsoft.Windows.PowerShell.ScriptAnalyzer.DiGraph[string]' + $digraph.AddVertex('v1'); + $digraph.AddVertex('v2'); + $digraph.AddVertex('v3'); + $digraph.AddVertex('v4'); + $digraph.AddVertex('v5'); - $digraph.AddEdge('v1', 'v2'); - $digraph.AddEdge('v1', 'v5'); - $digraph.AddEdge('v2', 'v4'); + $digraph.AddEdge('v1', 'v2'); + $digraph.AddEdge('v1', 'v5'); + $digraph.AddEdge('v2', 'v4'); + } It "correctly adds the vertices" { $digraph.NumVertices | Should -Be 5 From c6dd64071e2493a227a431776d9140e09c2fcfa4 Mon Sep 17 00:00:00 2001 From: Christoph Bergmeister Date: Mon, 13 Apr 2020 11:39:59 +0100 Subject: [PATCH 12/76] Fix remaining tests with BeforeAll/AfterAll (discovery works now) --- Tests/Engine/InvokeScriptAnalyzer.tests.ps1 | 4 +-- .../Engine/ModuleDependencyHandler.tests.ps1 | 36 +++++++++---------- .../AvoidOverwritingBuiltInCmdlets.tests.ps1 | 18 ++++++---- Tests/Rules/DscExamplesPresent.tests.ps1 | 31 +++++++++------- Tests/Rules/DscTestsPresent.tests.ps1 | 18 ++++++---- 5 files changed, 61 insertions(+), 46 deletions(-) diff --git a/Tests/Engine/InvokeScriptAnalyzer.tests.ps1 b/Tests/Engine/InvokeScriptAnalyzer.tests.ps1 index 434ed55db..45e9df410 100644 --- a/Tests/Engine/InvokeScriptAnalyzer.tests.ps1 +++ b/Tests/Engine/InvokeScriptAnalyzer.tests.ps1 @@ -630,9 +630,9 @@ Describe "Test -EnableExit Switch" { $warnings.RuleName | Should -Be 'TypeNotFound' } - $testFilePath = "TestDrive:\testfile.ps1" - Set-Content $testFilePath -value $script It "does not throw and detect one expected warning after the parse error has occured when using -Path parameter set" { + $testFilePath = "TestDrive:\testfile.ps1" + Set-Content $testFilePath -value $script $warnings = Invoke-ScriptAnalyzer -Path $testFilePath $warnings.Count | Should -Be 1 $warnings.RuleName | Should -Be 'TypeNotFound' diff --git a/Tests/Engine/ModuleDependencyHandler.tests.ps1 b/Tests/Engine/ModuleDependencyHandler.tests.ps1 index f56c9820b..b29e7d32c 100644 --- a/Tests/Engine/ModuleDependencyHandler.tests.ps1 +++ b/Tests/Engine/ModuleDependencyHandler.tests.ps1 @@ -1,23 +1,26 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. -Describe "Resolve DSC Resource Dependency" { - BeforeAll { - $skipTest = $false # Test that require DSC to be installed - if ($testingLibararyUsage -or ($PSversionTable.PSVersion -lt [Version]'5.0.0')) - { - $skipTest = $true - return - } - if ($IsLinux -or $IsMacOS) +function Get-Skip +{ + if ($testingLibararyUsage -or ($PSversionTable.PSVersion -lt [Version]'5.0.0')) + { + return $true + } + if ($IsLinux -or $IsMacOS) + { + $dscIsInstalled = Test-Path /etc/opt/omi/conf/dsc/configuration + if (-not $dscIsInstalled) { - $dscIsInstalled = Test-Path /etc/opt/omi/conf/dsc/configuration - if (-not $dscIsInstalled) - { - $skipTest = $true - } + return $true } + } + return $false +} +$skipTest = Get-Skip +Describe "Resolve DSC Resource Dependency" { + BeforeAll { $savedPSModulePath = $env:PSModulePath $violationFileName = 'MissingDSCResource.ps1' $violationFilePath = Join-Path $PSScriptRoot $violationFileName @@ -241,8 +244,7 @@ Describe "Resolve DSC Resource Dependency" { $env:PSModulePath | Should -Be $savedPSModulePath } - if (!$skipTest) - { + It "Keeps the environment variables unchanged" -skip:$skipTest { if ($IsLinux -or $IsMacOS) { $env:HOME = $oldLocalAppDataPath @@ -255,9 +257,7 @@ Describe "Resolve DSC Resource Dependency" { } Remove-Item -Recurse -Path $tempModulePath -Force Remove-Item -Recurse -Path $tempPath -Force - } - It "Keeps the environment variables unchanged" -skip:$skipTest { Test-EnvironmentVariables($oldEnvVars) } } diff --git a/Tests/Rules/AvoidOverwritingBuiltInCmdlets.tests.ps1 b/Tests/Rules/AvoidOverwritingBuiltInCmdlets.tests.ps1 index 306acebe4..2a111af0a 100644 --- a/Tests/Rules/AvoidOverwritingBuiltInCmdlets.tests.ps1 +++ b/Tests/Rules/AvoidOverwritingBuiltInCmdlets.tests.ps1 @@ -48,8 +48,10 @@ describe 'AvoidOverwritingBuiltInCmdlets' { } context 'PowerShellVersion explicitly set to Windows PowerShell' { - $settings['Rules'] = $ruleSettingsWindows - $violations = Invoke-ScriptAnalyzer -ScriptDefinition $scriptDefinition -Settings $settings + BeforeAll { + $settings['Rules'] = $ruleSettingsWindows + $violations = Invoke-ScriptAnalyzer -ScriptDefinition $scriptDefinition -Settings $settings + } it 'should find two violations' { $violations.Count | Should -Be 2 @@ -64,8 +66,10 @@ describe 'AvoidOverwritingBuiltInCmdlets' { } context 'PowerShellVersion explicitly set to PowerShell 6' { - $settings['Rules'] = $ruleSettingsCore - $violations = Invoke-ScriptAnalyzer -ScriptDefinition $scriptDefinition -Settings $settings + BeforeAll { + $settings['Rules'] = $ruleSettingsCore + $violations = Invoke-ScriptAnalyzer -ScriptDefinition $scriptDefinition -Settings $settings + } it 'should find one violation' { $violations.Count | Should -Be 1 @@ -77,8 +81,10 @@ describe 'AvoidOverwritingBuiltInCmdlets' { } context 'PowerShellVersion explicitly set to both Windows PowerShell and PowerShell 6' { - $settings['Rules'] = $ruleSettingsBoth - $violations = Invoke-ScriptAnalyzer -ScriptDefinition $scriptDefinition -Settings $settings + BeforeAll { + $settings['Rules'] = $ruleSettingsBoth + $violations = Invoke-ScriptAnalyzer -ScriptDefinition $scriptDefinition -Settings $settings + } it 'should find three violations' { $violations.Count | Should -Be 3 diff --git a/Tests/Rules/DscExamplesPresent.tests.ps1 b/Tests/Rules/DscExamplesPresent.tests.ps1 index 46e51fa26..a8ebd8600 100644 --- a/Tests/Rules/DscExamplesPresent.tests.ps1 +++ b/Tests/Rules/DscExamplesPresent.tests.ps1 @@ -12,9 +12,10 @@ BeforeAll { } Context "When examples absent" { - - $violations = Invoke-ScriptAnalyzer -ErrorAction SilentlyContinue $classResourcePath | Where-Object {$_.RuleName -eq $ruleName} - $violationMessage = "No examples found for resource 'FileResource'" + BeforeAll { + $violations = Invoke-ScriptAnalyzer -ErrorAction SilentlyContinue $classResourcePath | Where-Object {$_.RuleName -eq $ruleName} + $violationMessage = "No examples found for resource 'FileResource'" + } It "has 1 missing examples violation" { $violations.Count | Should -Be 1 @@ -26,16 +27,17 @@ BeforeAll { } Context "When examples present" { - New-Item -Path $examplesPath -ItemType Directory -force - New-Item -Path "$examplesPath\FileResource_Example.psm1" -ItemType File -force - - $noViolations = Invoke-ScriptAnalyzer -ErrorAction SilentlyContinue $classResourcePath | Where-Object {$_.RuleName -eq $ruleName} - It "returns no violations" { + New-Item -Path $examplesPath -ItemType Directory -force + New-Item -Path "$examplesPath\FileResource_Example.psm1" -ItemType File -force + + $noViolations = Invoke-ScriptAnalyzer -ErrorAction SilentlyContinue $classResourcePath | Where-Object {$_.RuleName -eq $ruleName} $noViolations.Count | Should -Be 0 } - Remove-Item -Path $examplesPath -Recurse -Force + AfterAll { + Remove-Item -Path $examplesPath -Recurse -Force + } } } @@ -46,9 +48,10 @@ Describe "DscExamplesPresent rule in regular (non-class) based resource" { } Context "When examples absent" { - - $violations = Invoke-ScriptAnalyzer -ErrorAction SilentlyContinue $resourcePath | Where-Object {$_.RuleName -eq $ruleName} - $violationMessage = "No examples found for resource 'MSFT_WaitForAll'" + BeforeAll { + $violations = Invoke-ScriptAnalyzer -ErrorAction SilentlyContinue $resourcePath | Where-Object {$_.RuleName -eq $ruleName} + $violationMessage = "No examples found for resource 'MSFT_WaitForAll'" + } It "has 1 missing examples violation" { $violations.Count | Should -Be 1 @@ -70,6 +73,8 @@ Describe "DscExamplesPresent rule in regular (non-class) based resource" { $noViolations.Count | Should -Be 0 } - Remove-Item -Path $examplesPath -Recurse -Force + AfterAll { + Remove-Item -Path $examplesPath -Recurse -Force + } } } diff --git a/Tests/Rules/DscTestsPresent.tests.ps1 b/Tests/Rules/DscTestsPresent.tests.ps1 index c6076646f..da41ea727 100644 --- a/Tests/Rules/DscTestsPresent.tests.ps1 +++ b/Tests/Rules/DscTestsPresent.tests.ps1 @@ -12,9 +12,10 @@ BeforeAll { } Context "When tests absent" { - - $violations = Invoke-ScriptAnalyzer -ErrorAction SilentlyContinue $classResourcePath | Where-Object {$_.RuleName -eq $ruleName} - $violationMessage = "No tests found for resource 'FileResource'" + BeforeAll { + $violations = Invoke-ScriptAnalyzer -ErrorAction SilentlyContinue $classResourcePath | Where-Object {$_.RuleName -eq $ruleName} + $violationMessage = "No tests found for resource 'FileResource'" + } It "has 1 missing test violation" { $violations.Count | Should -Be 1 @@ -36,7 +37,9 @@ BeforeAll { $noViolations.Count | Should -Be 0 } - Remove-Item -Path $testsPath -Recurse -Force + AfterAll { + Remove-Item -Path $testsPath -Recurse -Force + } } } @@ -65,14 +68,15 @@ Describe "DscTestsPresent rule in regular (non-class) based resource" { $testsPath = "$PSScriptRoot\DSCResourceModule\Tests" New-Item -Path $testsPath -ItemType Directory -force New-Item -Path "$testsPath\MSFT_WaitForAll_Test.psm1" -ItemType File -force + $noViolations = Invoke-ScriptAnalyzer -ErrorAction SilentlyContinue $resourcePath | Where-Object {$_.RuleName -eq $ruleName} } - $noViolations = Invoke-ScriptAnalyzer -ErrorAction SilentlyContinue $resourcePath | Where-Object {$_.RuleName -eq $ruleName} - It "returns no violations" { $noViolations.Count | Should -Be 0 } - Remove-Item -Path $testsPath -Recurse -Force + AfterAll { + Remove-Item -Path $testsPath -Recurse -Force + } } } From 35ed07c7d39b1bb37ca19a2b6f575c098ce173d8 Mon Sep 17 00:00:00 2001 From: Christoph Bergmeister Date: Mon, 13 Apr 2020 13:25:45 +0100 Subject: [PATCH 13/76] fix UseUsingScopeModifierInNewRunspaces.tests.ps1 --- ...UsingScopeModifierInNewRunspaces.tests.ps1 | 368 ++++++++++++------ 1 file changed, 243 insertions(+), 125 deletions(-) diff --git a/Tests/Rules/UseUsingScopeModifierInNewRunspaces.tests.ps1 b/Tests/Rules/UseUsingScopeModifierInNewRunspaces.tests.ps1 index 7ac1870aa..b29488df0 100644 --- a/Tests/Rules/UseUsingScopeModifierInNewRunspaces.tests.ps1 +++ b/Tests/Rules/UseUsingScopeModifierInNewRunspaces.tests.ps1 @@ -2,7 +2,7 @@ # Licensed under the MIT License. BeforeAll { - $settings = @{ + $settings = @{ IncludeRules = "PSUseUsingScopeModifierInNewRunspaces" Severity = "warning" # because we need to prevent ParseErrors from being reported, so 'workflow' keyword will not be flagged when running test on Pwsh. } @@ -10,133 +10,127 @@ BeforeAll { Describe "UseUsingScopeModifierInNewRunspaces" { Context "Should detect something" { - BeforeAll { - [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments','')] - $testCases = @( - # Test: Foreach-Object -Parallel {} - @{ - Description = "Foreach-Object -Parallel with undeclared var" - ScriptBlock = '{ + It "should emit for: " -TestCases @( + # Test: Foreach-Object -Parallel {} + @{ + Description = "Foreach-Object -Parallel with undeclared var" + ScriptBlock = '{ + 1..2 | ForEach-Object -Parallel { $var } + }' + } + @{ + Description = "foreach -parallel alias with undeclared var" + ScriptBlock = '{ + 1..2 | ForEach -Parallel { $var } + }' + } + @{ + Description = "% -parallel alias with undeclared var" + ScriptBlock = '{ + 1..2 | % -Parallel { $var } + }' + } + @{ + Description = "Foreach-Object -pa abbreviated param with undeclared var" + ScriptBlock = '{ + 1..2 | foreach-object -pa { $var } + }' + } + @{ + Description = "Foreach-Object -Parallel nested with undeclared var" + ScriptBlock = '{ + $myNestedScriptBlock = { 1..2 | ForEach-Object -Parallel { $var } - }' - } - @{ - Description = "foreach -parallel alias with undeclared var" - ScriptBlock = '{ - 1..2 | ForEach -Parallel { $var } - }' - } - @{ - Description = "% -parallel alias with undeclared var" - ScriptBlock = '{ - 1..2 | % -Parallel { $var } - }' - } - @{ - Description = "Foreach-Object -pa abbreviated param with undeclared var" - ScriptBlock = '{ - 1..2 | foreach-object -pa { $var } - }' - } - @{ - Description = "Foreach-Object -Parallel nested with undeclared var" - ScriptBlock = '{ - $myNestedScriptBlock = { - 1..2 | ForEach-Object -Parallel { $var } + } + }' + } + # Start-Job / Start-ThreadJob + @{ + Description = 'Start-Job without $using:' + ScriptBlock = '{ + $foo = "bar" + Start-Job {$foo} | Receive-Job -Wait -AutoRemoveJob + }' + } + @{ + Description = 'Start-ThreadJob without $using:' + ScriptBlock = '{ + $foo = "bar" + Start-ThreadJob -ScriptBlock {$foo} | Receive-Job -Wait -AutoRemoveJob + }' + } + @{ + Description = 'Start-Job with -InitializationScript with a variable' + ScriptBlock = '{ + $foo = "bar" + Start-Job -ScriptBlock {$foo} -InitializationScript {$foo} | Receive-Job -Wait -AutoRemoveJob + }' + } + @{ + Description = 'Start-ThreadJob with -InitializationScript with a variable' + ScriptBlock = '{ + $foo = "bar" + Start-ThreadJob -ScriptBlock {$foo} -InitializationScript {$foo} | Receive-Job -Wait -AutoRemoveJob + }' + } + # workflow/inlinescript + @{ + Description = "Workflow/InlineScript" + ScriptBlock = '{ + $foo = "bar" + workflow baz { InlineScript {$foo} } + }' + } + # Invoke-Command + @{ + Description = 'Invoke-Command with -ComputerName' + ScriptBlock = '{ + Invoke-Command -ScriptBlock {Write-Output $foo} -ComputerName "bar" + }' + } + @{ + Description = 'Invoke-Command with two different sessions, where var is declared in wrong session' + ScriptBlock = '{ + $session = new-PSSession -ComputerName "baz" + $otherSession = new-PSSession -ComputerName "bar" + Invoke-Command -session $session -ScriptBlock {[string]$foo = "foo" } + Invoke-Command -session $otherSession -ScriptBlock {Write-Output $foo} + }' + } + @{ + Description = 'Invoke-Command with session, where var is declared after use' + ScriptBlock = '{ + $session = new-PSSession -ComputerName "baz" + Invoke-Command -session $session -ScriptBlock {Write-Output $foo} + Invoke-Command -session $session -ScriptBlock {$foo = "foo" } + }' + } + # DSC Script resource + @{ + Description = 'DSC Script resource with GetScript {}' + ScriptBlock = 'Script ReturnFoo { + GetScript = { + return @{ "Result" = "$foo" } } }' - } - # Start-Job / Start-ThreadJob - @{ - Description = 'Start-Job without $using:' - ScriptBlock = '{ - $foo = "bar" - Start-Job {$foo} | Receive-Job -Wait -AutoRemoveJob - }' - } - @{ - Description = 'Start-ThreadJob without $using:' - ScriptBlock = '{ - $foo = "bar" - Start-ThreadJob -ScriptBlock {$foo} | Receive-Job -Wait -AutoRemoveJob - }' - } - @{ - Description = 'Start-Job with -InitializationScript with a variable' - ScriptBlock = '{ - $foo = "bar" - Start-Job -ScriptBlock {$foo} -InitializationScript {$foo} | Receive-Job -Wait -AutoRemoveJob - }' - } - @{ - Description = 'Start-ThreadJob with -InitializationScript with a variable' - ScriptBlock = '{ - $foo = "bar" - Start-ThreadJob -ScriptBlock {$foo} -InitializationScript {$foo} | Receive-Job -Wait -AutoRemoveJob - }' - } - # workflow/inlinescript - @{ - Description = "Workflow/InlineScript" - ScriptBlock = '{ - $foo = "bar" - workflow baz { InlineScript {$foo} } - }' - } - # Invoke-Command - @{ - Description = 'Invoke-Command with -ComputerName' - ScriptBlock = '{ - Invoke-Command -ScriptBlock {Write-Output $foo} -ComputerName "bar" - }' - } - @{ - Description = 'Invoke-Command with two different sessions, where var is declared in wrong session' - ScriptBlock = '{ - $session = new-PSSession -ComputerName "baz" - $otherSession = new-PSSession -ComputerName "bar" - Invoke-Command -session $session -ScriptBlock {[string]$foo = "foo" } - Invoke-Command -session $otherSession -ScriptBlock {Write-Output $foo} + } + @{ + Description = 'DSC Script resource with TestScript {}' + ScriptBlock = 'Script TestFoo { + TestScript = { + return [bool]$foo + } }' - } - @{ - Description = 'Invoke-Command with session, where var is declared after use' - ScriptBlock = '{ - $session = new-PSSession -ComputerName "baz" - Invoke-Command -session $session -ScriptBlock {Write-Output $foo} - Invoke-Command -session $session -ScriptBlock {$foo = "foo" } + } + @{ + Description = 'DSC Script resource with SetScript {}' + ScriptBlock = 'Script SetFoo { + SetScript = { + $foo | Set-Content -path "~\nonexistent\foo.txt" + } }' - } - # DSC Script resource - @{ - Description = 'DSC Script resource with GetScript {}' - ScriptBlock = 'Script ReturnFoo { - GetScript = { - return @{ "Result" = "$foo" } - } - }' - } - @{ - Description = 'DSC Script resource with TestScript {}' - ScriptBlock = 'Script TestFoo { - TestScript = { - return [bool]$foo - } - }' - } - @{ - Description = 'DSC Script resource with SetScript {}' - ScriptBlock = 'Script SetFoo { - SetScript = { - $foo | Set-Content -path "~\nonexistent\foo.txt" - } - }' - } - ) - } - - It "should emit for: " -TestCases $testCases { - param($Description, $ScriptBlock) + } + ) -Test { [System.Array] $warnings = Invoke-ScriptAnalyzer -ScriptDefinition $ScriptBlock -Settings $settings $warnings.Count | Should -Be 1 } @@ -282,8 +276,132 @@ Describe "UseUsingScopeModifierInNewRunspaces" { ) } - It "should not emit anything for: " -TestCases $testCases { - param($Description, $ScriptBlock) + It "should not emit anything for: " -TestCases @( + @{ + Description = "Foreach-Object with uninitialized var inside" + ScriptBlock = '{ + 1..2 | ForEach-Object { $var } + }' + } + @{ + Description = "Foreach-Object -Parallel with uninitialized `$using: var" + ScriptBlock = '{ + 1..2 | foreach-object -Parallel { $using:var } + }' + } + @{ + Description = "Foreach-Object -Parallel with var assigned locally" + ScriptBlock = '{ + 1..2 | ForEach-Object -Parallel { [string]$var="somevalue" } + }' + } + @{ + Description = "Foreach-Object -Parallel with built-in var '`$PSBoundParameters' inside" + ScriptBlock = '{ + 1..2 | ForEach-Object -Parallel{ $PSBoundParameters } + }' + } + @{ + Description = "Foreach-Object -Parallel with vars in other parameters" + ScriptBlock = '{ + $foo = "bar" + ForEach-Object -Parallel {$_} -InputObject $foo + }' + } + # Start-Job / Start-ThreadJob + @{ + Description = 'Start-Job with $using:' + ScriptBlock = '{ + $foo = "bar" + Start-Job -ScriptBlock {$using:foo} | Receive-Job -Wait -AutoRemoveJob + }' + } + @{ + Description = 'Start-ThreadJob with $using:' + ScriptBlock = '{ + $foo = "bar" + Start-ThreadJob -ScriptBlock {$using:foo} | Receive-Job -Wait -AutoRemoveJob + }' + } + @{ + Description = 'Start-Job with -InitializationScript with a variable' + ScriptBlock = '{ + $foo = "bar" + Start-Job -ScriptBlock {$using:foo} -InitializationScript {$foo} | Receive-Job -Wait -AutoRemoveJob + }' + } + @{ + Description = 'Start-ThreadJob with -InitializationScript with a variable' + ScriptBlock = '{ + $foo = "bar" + Start-ThreadJob -ScriptBlock {$using:foo} -InitializationScript {$foo} | Receive-Job -Wait -AutoRemoveJob + }' + } + # workflow/inlinescript + @{ + Description = "Workflow/InlineScript" + ScriptBlock = '{ + $foo = "bar" + workflow baz { InlineScript {$using:foo} } + }' + } + # Invoke-Command + @{ + Description = 'Invoke-Command -Session, var declared in same session, other scriptblock' + ScriptBlock = '{ + $session = new-PSSession -ComputerName "baz" + Invoke-Command -session $session -ScriptBlock {$foo = "foo" } + Invoke-Command -session $session -ScriptBlock {Write-Output $foo} + }' + } + @{ + Description = 'Invoke-Command without -ComputerName' + ScriptBlock = '{ + Invoke-Command -ScriptBlock {Write-Output $foo} + }' + } + # Unsupported scenarios + @{ + Description = 'Rule should skip analysis when Command Name cannot be resolved' + ScriptBlock = '{ + $commandName = "Invoke-Command" + & $commandName -ComputerName -ScriptBlock { $foo } + }' + } + # DSC Script resource + @{ + Description = 'DSC Script resource with GetScript {}' + ScriptBlock = 'Script ReturnFoo { + GetScript = { + return @{ "Result" = "$using:foo" } + } + }' + } + @{ + Description = 'DSC Script resource with TestScript {}' + ScriptBlock = 'Script TestFoo { + TestScript = { + return [bool]$using:foo + } + }' + } + @{ + Description = 'DSC Script resource with SetScript {}' + ScriptBlock = 'Script SetFoo { + SetScript = { + $using:foo | Set-Content -path "~\nonexistent\foo.txt" + } + }' + } + @{ + Description = 'Non-DSC function with the name SetScript {}' + ScriptBlock = '{ + SetScript -ScriptBlock { + $foo | Set-Content -path "~\nonexistent\foo.txt" + } + }' + } + ) -Test { [System.Array] $warnings = Invoke-ScriptAnalyzer -ScriptDefinition $ScriptBlock -Settings $settings $warnings.Count | Should -Be 0 } From a350f2b05820a99eca13c2134757ed45bda8bb9b Mon Sep 17 00:00:00 2001 From: Christoph Bergmeister Date: Mon, 13 Apr 2020 13:41:10 +0100 Subject: [PATCH 14/76] make test cases more readable --- ...UsingScopeModifierInNewRunspaces.tests.ps1 | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/Tests/Rules/UseUsingScopeModifierInNewRunspaces.tests.ps1 b/Tests/Rules/UseUsingScopeModifierInNewRunspaces.tests.ps1 index b29488df0..9217a26a1 100644 --- a/Tests/Rules/UseUsingScopeModifierInNewRunspaces.tests.ps1 +++ b/Tests/Rules/UseUsingScopeModifierInNewRunspaces.tests.ps1 @@ -10,7 +10,10 @@ BeforeAll { Describe "UseUsingScopeModifierInNewRunspaces" { Context "Should detect something" { - It "should emit for: " -TestCases @( + It "should emit for: " { + [System.Array] $warnings = Invoke-ScriptAnalyzer -ScriptDefinition $ScriptBlock -Settings $settings + $warnings.Count | Should -Be 1 + } -TestCases @( # Test: Foreach-Object -Parallel {} @{ Description = "Foreach-Object -Parallel with undeclared var" @@ -130,10 +133,7 @@ Describe "UseUsingScopeModifierInNewRunspaces" { } }' } - ) -Test { - [System.Array] $warnings = Invoke-ScriptAnalyzer -ScriptDefinition $ScriptBlock -Settings $settings - $warnings.Count | Should -Be 1 - } + ) It "should emit suggested correction" { $ScriptBlock = '{ @@ -276,7 +276,10 @@ Describe "UseUsingScopeModifierInNewRunspaces" { ) } - It "should not emit anything for: " -TestCases @( + It "should not emit anything for: " { + [System.Array] $warnings = Invoke-ScriptAnalyzer -ScriptDefinition $ScriptBlock -Settings $settings + $warnings.Count | Should -Be 0 + } -TestCases @( @{ Description = "Foreach-Object with uninitialized var inside" ScriptBlock = '{ @@ -401,9 +404,6 @@ Describe "UseUsingScopeModifierInNewRunspaces" { } }' } - ) -Test { - [System.Array] $warnings = Invoke-ScriptAnalyzer -ScriptDefinition $ScriptBlock -Settings $settings - $warnings.Count | Should -Be 0 - } + ) } } From 5350e873f04f78919ae99ea452f64e2da95af740 Mon Sep 17 00:00:00 2001 From: Christoph Bergmeister Date: Mon, 13 Apr 2020 13:43:30 +0100 Subject: [PATCH 15/76] cleanup UseUsingScopeModifierInNewRunspaces.tests.ps1 --- ...UsingScopeModifierInNewRunspaces.tests.ps1 | 129 ------------------ 1 file changed, 129 deletions(-) diff --git a/Tests/Rules/UseUsingScopeModifierInNewRunspaces.tests.ps1 b/Tests/Rules/UseUsingScopeModifierInNewRunspaces.tests.ps1 index 9217a26a1..d4756bbbe 100644 --- a/Tests/Rules/UseUsingScopeModifierInNewRunspaces.tests.ps1 +++ b/Tests/Rules/UseUsingScopeModifierInNewRunspaces.tests.ps1 @@ -146,135 +146,6 @@ Describe "UseUsingScopeModifierInNewRunspaces" { } Context "Should not detect anything" { - BeforeAll { - [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments','')] - $testCases = @( - @{ - Description = "Foreach-Object with uninitialized var inside" - ScriptBlock = '{ - 1..2 | ForEach-Object { $var } - }' - } - @{ - Description = "Foreach-Object -Parallel with uninitialized `$using: var" - ScriptBlock = '{ - 1..2 | foreach-object -Parallel { $using:var } - }' - } - @{ - Description = "Foreach-Object -Parallel with var assigned locally" - ScriptBlock = '{ - 1..2 | ForEach-Object -Parallel { [string]$var="somevalue" } - }' - } - @{ - Description = "Foreach-Object -Parallel with built-in var '`$PSBoundParameters' inside" - ScriptBlock = '{ - 1..2 | ForEach-Object -Parallel{ $PSBoundParameters } - }' - } - @{ - Description = "Foreach-Object -Parallel with vars in other parameters" - ScriptBlock = '{ - $foo = "bar" - ForEach-Object -Parallel {$_} -InputObject $foo - }' - } - # Start-Job / Start-ThreadJob - @{ - Description = 'Start-Job with $using:' - ScriptBlock = '{ - $foo = "bar" - Start-Job -ScriptBlock {$using:foo} | Receive-Job -Wait -AutoRemoveJob - }' - } - @{ - Description = 'Start-ThreadJob with $using:' - ScriptBlock = '{ - $foo = "bar" - Start-ThreadJob -ScriptBlock {$using:foo} | Receive-Job -Wait -AutoRemoveJob - }' - } - @{ - Description = 'Start-Job with -InitializationScript with a variable' - ScriptBlock = '{ - $foo = "bar" - Start-Job -ScriptBlock {$using:foo} -InitializationScript {$foo} | Receive-Job -Wait -AutoRemoveJob - }' - } - @{ - Description = 'Start-ThreadJob with -InitializationScript with a variable' - ScriptBlock = '{ - $foo = "bar" - Start-ThreadJob -ScriptBlock {$using:foo} -InitializationScript {$foo} | Receive-Job -Wait -AutoRemoveJob - }' - } - # workflow/inlinescript - @{ - Description = "Workflow/InlineScript" - ScriptBlock = '{ - $foo = "bar" - workflow baz { InlineScript {$using:foo} } - }' - } - # Invoke-Command - @{ - Description = 'Invoke-Command -Session, var declared in same session, other scriptblock' - ScriptBlock = '{ - $session = new-PSSession -ComputerName "baz" - Invoke-Command -session $session -ScriptBlock {$foo = "foo" } - Invoke-Command -session $session -ScriptBlock {Write-Output $foo} - }' - } - @{ - Description = 'Invoke-Command without -ComputerName' - ScriptBlock = '{ - Invoke-Command -ScriptBlock {Write-Output $foo} - }' - } - # Unsupported scenarios - @{ - Description = 'Rule should skip analysis when Command Name cannot be resolved' - ScriptBlock = '{ - $commandName = "Invoke-Command" - & $commandName -ComputerName -ScriptBlock { $foo } - }' - } - # DSC Script resource - @{ - Description = 'DSC Script resource with GetScript {}' - ScriptBlock = 'Script ReturnFoo { - GetScript = { - return @{ "Result" = "$using:foo" } - } - }' - } - @{ - Description = 'DSC Script resource with TestScript {}' - ScriptBlock = 'Script TestFoo { - TestScript = { - return [bool]$using:foo - } - }' - } - @{ - Description = 'DSC Script resource with SetScript {}' - ScriptBlock = 'Script SetFoo { - SetScript = { - $using:foo | Set-Content -path "~\nonexistent\foo.txt" - } - }' - } - @{ - Description = 'Non-DSC function with the name SetScript {}' - ScriptBlock = '{ - SetScript -ScriptBlock { - $foo | Set-Content -path "~\nonexistent\foo.txt" - } - }' - } - ) - } It "should not emit anything for: " { [System.Array] $warnings = Invoke-ScriptAnalyzer -ScriptDefinition $ScriptBlock -Settings $settings From f2e37f33601fac5797d2b6e15beeb5ee797ec1b8 Mon Sep 17 00:00:00 2001 From: Christoph Bergmeister Date: Mon, 13 Apr 2020 14:06:02 +0100 Subject: [PATCH 16/76] Fix UseShouldProcessForStateChangingFunctions.tests.ps1 --- ...ProcessForStateChangingFunctions.tests.ps1 | 50 ++++++++++++------- 1 file changed, 33 insertions(+), 17 deletions(-) diff --git a/Tests/Rules/UseShouldProcessForStateChangingFunctions.tests.ps1 b/Tests/Rules/UseShouldProcessForStateChangingFunctions.tests.ps1 index 841a76d3b..0b67a86d6 100644 --- a/Tests/Rules/UseShouldProcessForStateChangingFunctions.tests.ps1 +++ b/Tests/Rules/UseShouldProcessForStateChangingFunctions.tests.ps1 @@ -10,26 +10,42 @@ BeforeAll { Describe "It checks UseShouldProcess is enabled when there are state changing verbs in the function names" { Context "When function name has state changing verb" { - - Function Test-Verb([string] $verb) - { - $scriptDefinitionGeneric = @' -Function New-{0} () {{ }} -'@ - $scriptDef = $scriptDefinitionGeneric -f $verb - It ('finds "{0}" verb in function name' -f $verb) { - $violations = Invoke-ScriptAnalyzer -ScriptDefinition $scriptDef -IncludeRule $violationName - $violations.Count | Should -Be 1 + It 'Finds verb "" in function name' { + Param($Verb) + $scriptDefinition = "Function New-${Verb} () {{ }}" + $violations = Invoke-ScriptAnalyzer -ScriptDefinition $scriptDefinition -IncludeRule $violationName + $violations.Count | Should -Be 1 + } -TestCases @( + @{ + Verb = 'New' } - } - - $verbs = @('New', 'Set', 'Remove', 'Start', 'Stop', 'Restart', 'Reset', 'Update') - $verbs | ForEach-Object {Test-Verb $_} + @{ + Verb = 'Set' + } + @{ + Verb = 'Remove' + } + @{ + Verb = 'Start' + } + @{ + Verb = 'Stop' + } + @{ + Verb = 'Restart' + } + @{ + Verb = 'Reset' + } + @{ + Verb = 'Update' + } + ) } + Context "When there are violations" { - $numViolations = 5 - It ("has {0} violations where ShouldProcess is not supported" -f $numViolations) { - $violations.Count | Should -Be $numViolations + It "has correct number of violations where ShouldProcess is not supported" { + $violations.Count | Should -Be 5 } It "has the correct description message" { From 2a9fa9f1fcddb418e0dca0fdeb7616bd1c64b64e Mon Sep 17 00:00:00 2001 From: Christoph Bergmeister Date: Mon, 13 Apr 2020 14:06:39 +0100 Subject: [PATCH 17/76] cleanup UseShouldProcessForStateChangingFunctions.tests.ps1 --- .../UseShouldProcessForStateChangingFunctions.tests.ps1 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Tests/Rules/UseShouldProcessForStateChangingFunctions.tests.ps1 b/Tests/Rules/UseShouldProcessForStateChangingFunctions.tests.ps1 index 0b67a86d6..c4718f300 100644 --- a/Tests/Rules/UseShouldProcessForStateChangingFunctions.tests.ps1 +++ b/Tests/Rules/UseShouldProcessForStateChangingFunctions.tests.ps1 @@ -4,8 +4,8 @@ BeforeAll { $violationMessage = "Function 'Set-MyObject' has verb that could change system state. Therefore, the function has to support 'ShouldProcess'" $violationName = "PSUseShouldProcessForStateChangingFunctions" - $violations = Invoke-ScriptAnalyzer $PSScriptRoot\UseShouldProcessForStateChangingFunctions.ps1 | Where-Object {$_.RuleName -eq $violationName} - $noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\UseShouldProcessForStateChangingFunctionsNoViolations.ps1 | Where-Object {$_.RuleName -eq $violationName} + $violations = Invoke-ScriptAnalyzer $PSScriptRoot\UseShouldProcessForStateChangingFunctions.ps1 | Where-Object { $_.RuleName -eq $violationName } + $noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\UseShouldProcessForStateChangingFunctionsNoViolations.ps1 | Where-Object { $_.RuleName -eq $violationName } } Describe "It checks UseShouldProcess is enabled when there are state changing verbs in the function names" { @@ -53,7 +53,7 @@ Describe "It checks UseShouldProcess is enabled when there are state changing ve } It "has the correct extent" { - $violations[0].Extent.Text | Should -Be "Set-MyObject" + $violations[0].Extent.Text | Should -Be "Set-MyObject" } } From a5df593179de05490b50d9819b234f5647f7ce14 Mon Sep 17 00:00:00 2001 From: Christoph Bergmeister Date: Mon, 13 Apr 2020 14:43:26 +0100 Subject: [PATCH 18/76] Fix PSCompatibilityCollector/Tests/UtilityApi.Tests.ps1 --- .../Tests/UtilityApi.Tests.ps1 | 244 ++++++++---------- 1 file changed, 111 insertions(+), 133 deletions(-) diff --git a/PSCompatibilityCollector/Tests/UtilityApi.Tests.ps1 b/PSCompatibilityCollector/Tests/UtilityApi.Tests.ps1 index c6841eea6..ca2997a95 100644 --- a/PSCompatibilityCollector/Tests/UtilityApi.Tests.ps1 +++ b/PSCompatibilityCollector/Tests/UtilityApi.Tests.ps1 @@ -1,55 +1,46 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. -function Get-TypeNameAstFromScript -{ - param([string]$Script) +BeforeAll { + function Get-TypeNameAstFromScript + { + param([string]$Script) - $ast = [System.Management.Automation.Language.Parser]::ParseInput($Script, [ref]$null, [ref]$null) - $typeExpAst = $ast.Find({ - $args[0] -is [System.Management.Automation.Language.TypeExpressionAst] - }, $true) + $ast = [System.Management.Automation.Language.Parser]::ParseInput($Script, [ref]$null, [ref]$null) + $typeExpAst = $ast.Find({ + $args[0] -is [System.Management.Automation.Language.TypeExpressionAst] + }, $true) - return $typeExpAst.TypeName -} + return $typeExpAst.TypeName + } -function Get-TypeAccelerators -{ - [psobject].Assembly.GetType('System.Management.Automation.TypeAccelerators', 'nonpublic')::Get.GetEnumerator() + function Get-TypeAccelerators + { + [psobject].Assembly.GetType('System.Management.Automation.TypeAccelerators', 'nonpublic')::Get.GetEnumerator() + } } -Describe "Type name serialization" { - BeforeAll { - $typeNameTestCases = @( - @{ InputType = [System.Reflection.Assembly]; ExpectedName = "System.Reflection.Assembly" } - @{ InputType = [string]; ExpectedName = "System.String" } - @{ InputType = [datetime]; ExpectedName = "System.DateTime" } - @{ InputType = [string[]]; ExpectedName = "System.String[]" } - @{ InputType = [System.TimeZoneInfo+AdjustmentRule]; ExpectedName = "System.TimeZoneInfo+AdjustmentRule" } - @{ InputType = [System.Func`1]; ExpectedName = "System.Func``1" } - @{ InputType = [System.Collections.Generic.Dictionary`2]; ExpectedName = "System.Collections.Generic.Dictionary``2" } - @{ InputType = [System.Collections.Generic.Dictionary`2+Enumerator]; ExpectedName = "System.Collections.Generic.Dictionary``2+Enumerator" } - @{ InputType = [System.Collections.Generic.Dictionary[string,object]].GetNestedType('Enumerator'); ExpectedName = "System.Collections.Generic.Dictionary``2+Enumerator" } - @{ InputType = [System.Collections.Generic.List[object]]; ExpectedName = "System.Collections.Generic.List``1[System.Object]" } - @{ InputType = [System.Collections.Generic.Dictionary[string, object]]; ExpectedName = "System.Collections.Generic.Dictionary``2[System.String,System.Object]" } - @{ InputType = [System.Collections.Generic.Dictionary`2+Enumerator[string,object]]; ExpectedName = "System.Collections.Generic.Dictionary``2+Enumerator[System.String,System.Object]" } - @{ InputType = [System.Collections.Concurrent.ConcurrentDictionary`2].GetMethod('ToArray').ReturnType; ExpectedName = "System.Collections.Generic.KeyValuePair``2[]"} - ) - - $genericStrippingTests = @( - @{ RawTypeName = "String"; StrippedTypeName = "String" } - @{ RawTypeName = "Dictionary``2"; StrippedTypeName = "Dictionary" } - @{ RawTypeName = "Dictionary``2"; StrippedTypeName = "Dictionary" } - @{ RawTypeName = "Dictionary``2+Enumerator"; StrippedTypeName = "Dictionary+Enumerator" } - ) - } - It "Serializes the name of type to " -TestCases $typeNameTestCases { - param([type]$InputType, [string]$ExpectedName) +Describe "Type name serialization" { + It "Serializes the name of type to " { $name = [Microsoft.PowerShell.CrossCompatibility.TypeNaming]::GetFullTypeName($InputType) $name | Should -BeExactly $ExpectedName - } + } -TestCases @( + @{ InputType = [System.Reflection.Assembly]; ExpectedName = "System.Reflection.Assembly" } + @{ InputType = [string]; ExpectedName = "System.String" } + @{ InputType = [datetime]; ExpectedName = "System.DateTime" } + @{ InputType = [string[]]; ExpectedName = "System.String[]" } + @{ InputType = [System.TimeZoneInfo+AdjustmentRule]; ExpectedName = "System.TimeZoneInfo+AdjustmentRule" } + @{ InputType = [System.Func`1]; ExpectedName = "System.Func``1" } + @{ InputType = [System.Collections.Generic.Dictionary`2]; ExpectedName = "System.Collections.Generic.Dictionary``2" } + @{ InputType = [System.Collections.Generic.Dictionary`2+Enumerator]; ExpectedName = "System.Collections.Generic.Dictionary``2+Enumerator" } + @{ InputType = [System.Collections.Generic.Dictionary[string,object]].GetNestedType('Enumerator'); ExpectedName = "System.Collections.Generic.Dictionary``2+Enumerator" } + @{ InputType = [System.Collections.Generic.List[object]]; ExpectedName = "System.Collections.Generic.List``1[System.Object]" } + @{ InputType = [System.Collections.Generic.Dictionary[string, object]]; ExpectedName = "System.Collections.Generic.Dictionary``2[System.String,System.Object]" } + @{ InputType = [System.Collections.Generic.Dictionary`2+Enumerator[string,object]]; ExpectedName = "System.Collections.Generic.Dictionary``2+Enumerator[System.String,System.Object]" } + @{ InputType = [System.Collections.Concurrent.ConcurrentDictionary`2].GetMethod('ToArray').ReturnType; ExpectedName = "System.Collections.Generic.KeyValuePair``2[]"} + ) It "Null type throws exception" { { @@ -57,94 +48,86 @@ Describe "Type name serialization" { } | Should -Throw -ErrorId "ArgumentNullException" } - It "Strips generic quantifiers from '' to return ''" -TestCases $genericStrippingTests { + It "Strips generic quantifiers from '' to return ''" { param([string]$RawTypeName, [string]$StrippedTypeName) $stripped = [Microsoft.PowerShell.CrossCompatibility.TypeNaming]::StripGenericQuantifiers($RawTypeName) $stripped | Should -BeExactly $StrippedTypeName - } + } -TestCases @( + @{ RawTypeName = "String"; StrippedTypeName = "String" } + @{ RawTypeName = "Dictionary``2"; StrippedTypeName = "Dictionary" } + @{ RawTypeName = "Dictionary``2"; StrippedTypeName = "Dictionary" } + @{ RawTypeName = "Dictionary``2+Enumerator"; StrippedTypeName = "Dictionary+Enumerator" } + ) } Describe "Type accelerator expansion" { BeforeAll { $typeAccelerators = Get-TypeAccelerators | ForEach-Object { $d = New-Object 'System.Collections.Generic.Dictionary[string,string]' } { $d.Add($_.Key, $_.Value.FullName) } { $d } - - $typeAcceleratorTestCases = @( - @{ Raw = "[System.Exception]"; Expanded = "System.Exception" } - @{ Raw = "[string]"; Expanded = "System.String" } - @{ Raw = "[psmoduleinfo]"; Expanded = "System.Management.Automation.PSModuleInfo" } - @{ Raw = "[System.Collections.Generic.List[int]]"; Expanded = "System.Collections.Generic.List``1[System.Int32]" } - @{ Raw = "[System.Collections.Generic.Dictionary[string,psmoduleinfo]]"; Expanded = "System.Collections.Generic.Dictionary``2[System.String,System.Management.Automation.PSModuleInfo]" } - @{ Raw = "[System.Collections.Generic.Dictionary[string, psmoduleinfo]]"; Expanded = "System.Collections.Generic.Dictionary``2[System.String,System.Management.Automation.PSModuleInfo]" } - @{ Raw = "[System.Collections.Generic.Dictionary [string, psmoduleinfo]]"; Expanded = "System.Collections.Generic.Dictionary``2[System.String,System.Management.Automation.PSModuleInfo]" } - @{ Raw = "[System.Collections.Generic.List``1[uri]]"; Expanded = "System.Collections.Generic.List``1[System.Uri]" } - @{ Raw = "[System.Collections.Generic.Dictionary``2[string,psmoduleinfo]]"; Expanded = "System.Collections.Generic.Dictionary``2[System.String,System.Management.Automation.PSModuleInfo]" } - @{ Raw = "[System.Collections.Generic.Dictionary``2 [string, psmoduleinfo]]"; Expanded = "System.Collections.Generic.Dictionary``2[System.String,System.Management.Automation.PSModuleInfo]" } - @{ Raw = "[object]"; Expanded = "System.Object" } - ) } - It "Expands the typename in to " -TestCases $typeAcceleratorTestCases { - param([string]$Raw, [string]$Expanded) + It "Expands the typename in to " { $typeName = Get-TypeNameAstFromScript -Script $Raw $canonicalName = [Microsoft.PowerShell.CrossCompatibility.TypeNaming]::GetCanonicalTypeName($typeAccelerators, $typeName) $canonicalName | Should -BeExactly $Expanded + } -TestCases @( + @{ Raw = "[System.Exception]"; Expanded = "System.Exception" } + @{ Raw = "[string]"; Expanded = "System.String" } + @{ Raw = "[psmoduleinfo]"; Expanded = "System.Management.Automation.PSModuleInfo" } + @{ Raw = "[System.Collections.Generic.List[int]]"; Expanded = "System.Collections.Generic.List``1[System.Int32]" } + @{ Raw = "[System.Collections.Generic.Dictionary[string,psmoduleinfo]]"; Expanded = "System.Collections.Generic.Dictionary``2[System.String,System.Management.Automation.PSModuleInfo]" } + @{ Raw = "[System.Collections.Generic.Dictionary[string, psmoduleinfo]]"; Expanded = "System.Collections.Generic.Dictionary``2[System.String,System.Management.Automation.PSModuleInfo]" } + @{ Raw = "[System.Collections.Generic.Dictionary [string, psmoduleinfo]]"; Expanded = "System.Collections.Generic.Dictionary``2[System.String,System.Management.Automation.PSModuleInfo]" } + @{ Raw = "[System.Collections.Generic.List``1[uri]]"; Expanded = "System.Collections.Generic.List``1[System.Uri]" } + @{ Raw = "[System.Collections.Generic.Dictionary``2[string,psmoduleinfo]]"; Expanded = "System.Collections.Generic.Dictionary``2[System.String,System.Management.Automation.PSModuleInfo]" } + @{ Raw = "[System.Collections.Generic.Dictionary``2 [string, psmoduleinfo]]"; Expanded = "System.Collections.Generic.Dictionary``2[System.String,System.Management.Automation.PSModuleInfo]" } + @{ Raw = "[object]"; Expanded = "System.Object" } + ) +} - } +$versionCreationTests = @( + @{ Version = '6.1'; Major = 6; Minor = 1; Patch = -1 } + @{ Version = '6.1.4'; Major = 6; Minor = 1; Patch = 4; } + @{ Version = '5.1.8-preview.2'; Major = 5; Minor = 1; Patch = 8; Label = 'preview.2' } + @{ Version = [version]'4.2'; Major = 4; Minor = 2; Patch = -1; Revision = -1 } + @{ Version = [version]'4.2.1'; Major = 4; Minor = 2; Patch = 1; Revision = -1 } + @{ Version = [version]'4.2.1.7'; Major = 4; Minor = 2; Patch = 1; Revision = 7 } +) + +if ($PSVersionTable.PSVersion.Major -ge 6) +{ + $versionCreationTests += @( + @{ Version = [semver]'6.1.2'; Major = 6; Minor = 1; Patch = 2; Label = $null } + @{ Version = [semver]'6.1.2-rc.1'; Major = 6; Minor = 1; Patch = 2; Label = 'rc.1' } + @{ Version = [semver]'6.1-rc.1'; Major = 6; Minor = 1; Patch = 0; Label = 'rc.1' } + @{ Version = [semver]'6-rc.1'; Major = 6; Minor = 0; Patch = 0; Label = 'rc.1' } + @{ Version = [semver]'6.1.2-rc.1+duck'; Major = 6; Minor = 1; Patch = 2; Label = 'rc.1'; BuildLabel = 'duck' } + @{ Version = [semver]'6.1-rc.1+duck'; Major = 6; Minor = 1; Patch = 0; Label = 'rc.1'; BuildLabel = 'duck' } + @{ Version = [semver]'6-rc.1+duck'; Major = 6; Minor = 0; Patch = 0; Label = 'rc.1'; BuildLabel = 'duck' } + ) } Describe "PowerShell version object" { Context "Version parsing" { - BeforeAll { - $genericVerCases = @( - @{ VerStr = '6'; Major = 6; Minor = -1; Patch = -1 } - @{ VerStr = '6.1'; Major = 6; Minor = 1; Patch = -1 } - @{ VerStr = '5.2.7'; Major = 5; Minor = 2; Patch = 7 } - @{ VerStr = '512.2124.71'; Major = 512; Minor = 2124; Patch = 71 } - ) - - $semVerCases = @( - @{ VerStr = '6.1.0-rc.1'; Major = 6; Minor = 1; Patch = 0; Label = 'rc.1' } - @{ VerStr = '6.2-preview.2'; Major = 6; Minor = 2; Patch = -1; Label = 'preview.2' } - @{ VerStr = '6-preview.2'; Major = 6; Minor = -1; Patch = -1; Label = 'preview.2' } - @{ VerStr = '6.1.0-rc.1+moo'; Major = 6; Minor = 1; Patch = 0; Label = 'rc.1'; BuildLabel = 'moo' } - @{ VerStr = '6.2-preview.2+horse'; Major = 6; Minor = 2; Patch = -1; Label = 'preview.2'; BuildLabel = 'horse' } - @{ VerStr = '6-preview.2+veryimportant'; Major = 6; Minor = -1; Patch = -1; Label = 'preview.2'; BuildLabel = 'veryimportant' } - ) - - $systemVerCases = @( - @{ VerStr = '5.2.1.12312'; Major = 5; Minor = 2; Patch = 1; Revision = 12312 } - ) - - $versionFailCases = @( - @{ VerStr = 'banana' } - @{ VerStr = '' } - @{ VerStr = '1.' } - @{ VerStr = '.6' } - @{ VerStr = '5.1.' } - @{ VerStr = '5.1.2.' } - @{ VerStr = '4.1.5.7.' } - @{ VerStr = '4.1.5.7.4' } - @{ VerStr = '4.1.5.7-rc.2' } - @{ VerStr = '4.1.5.-rc.2' } - ) - } - It "Parses version string '' as .." -TestCases $semVerCases { - param([string]$VerStr, [int]$Major, [int]$Minor, [int]$Patch) + It "Parses version string '' as .." { $v = [Microsoft.PowerShell.CrossCompatibility.PowerShellVersion]$VerStr $v.Major | Should -Be $Major $v.Minor | Should -Be $Minor $v.Patch | Should -Be $Patch - } + } -TestCases @( + @{ VerStr = '6.1'; Major = 6; Minor = 1; Patch = -1 } + @{ VerStr = '5.2.7'; Major = 5; Minor = 2; Patch = 7 } + @{ VerStr = '512.2124.71'; Major = 512; Minor = 2124; Patch = 71 } + ) - It "Parses version string '' as ..-