1+ # Copyright (c) Microsoft Corporation. All rights reserved.
2+ # Licensed under the MIT License.
3+
4+ BeforeAll {
5+ $violationName = " PSUseFullyQualifiedCmdletNames"
6+ $testRootDirectory = Split-Path - Parent $PSScriptRoot
7+ Import-Module (Join-Path $testRootDirectory " PSScriptAnalyzerTestHelper.psm1" )
8+ }
9+
10+ Describe " UseFullyQualifiedCmdletNames" {
11+ Context " When there are violations" {
12+ It " detects unqualified cmdlet calls" {
13+ $scriptDefinition = ' Get-Command'
14+ $violations = Invoke-ScriptAnalyzer - ScriptDefinition $scriptDefinition - IncludeRule $violationName
15+ $violations.Count | Should - Be 1
16+ $violations [0 ].Message | Should -Match " The cmdlet 'Get-Command' should be replaced with the fully qualified cmdlet name 'Microsoft.PowerShell.Core\\Get-Command'"
17+ }
18+
19+ It " detects unqualified alias usage" {
20+ $scriptDefinition = ' gci C:\temp'
21+ $violations = Invoke-ScriptAnalyzer - ScriptDefinition $scriptDefinition - IncludeRule $violationName
22+ $violations.Count | Should - Be 1
23+ $violations [0 ].Message | Should -Match " The alias 'gci' should be replaced with the fully qualified cmdlet name 'Microsoft.PowerShell.Management\\Get-ChildItem'"
24+ }
25+
26+ It " provides correct suggested corrections for cmdlets" {
27+ $scriptDefinition = ' Get-Command'
28+ $violations = Invoke-ScriptAnalyzer - ScriptDefinition $scriptDefinition - IncludeRule $violationName
29+ $violations [0 ].SuggestedCorrections.Count | Should - Be 1
30+ $violations [0 ].SuggestedCorrections[0 ].Text | Should - Be ' Microsoft.PowerShell.Core\Get-Command'
31+ $violations [0 ].SuggestedCorrections[0 ].Description | Should - Be " Replace 'Get-Command' with 'Microsoft.PowerShell.Core\Get-Command'"
32+ }
33+
34+ It " provides correct suggested corrections for aliases" {
35+ $scriptDefinition = ' gci'
36+ $violations = Invoke-ScriptAnalyzer - ScriptDefinition $scriptDefinition - IncludeRule $violationName
37+ $violations [0 ].SuggestedCorrections.Count | Should - Be 1
38+ $violations [0 ].SuggestedCorrections[0 ].Text | Should - Be ' Microsoft.PowerShell.Management\Get-ChildItem'
39+ $violations [0 ].SuggestedCorrections[0 ].Description | Should - Be " Replace 'gci' with 'Microsoft.PowerShell.Management\Get-ChildItem'"
40+ }
41+
42+ It " detects multiple violations in same script" {
43+ $scriptDefinition = @'
44+ Get-Command
45+ Write-Host "test"
46+ gci -Recurse
47+ '@
48+ $violations = Invoke-ScriptAnalyzer - ScriptDefinition $scriptDefinition - IncludeRule $violationName
49+ $violations.Count | Should - Be 3
50+ $violations [0 ].Extent.Text | Should - Be " Get-Command"
51+ $violations [1 ].Extent.Text | Should - Be " Write-Host"
52+ $violations [2 ].Extent.Text | Should - Be " gci"
53+ }
54+
55+ It " detects violations in pipelines" {
56+ $scriptDefinition = ' Get-Process | Where-Object { $_.Name -eq "notepad" }'
57+ $violations = Invoke-ScriptAnalyzer - ScriptDefinition $scriptDefinition - IncludeRule $violationName
58+ $violations.Count | Should - Be 2
59+ $violations [0 ].Extent.Text | Should - Be " Get-Process"
60+ $violations [1 ].Extent.Text | Should - Be " Where-Object"
61+ }
62+
63+ It " detects violations in script blocks" {
64+ $scriptDefinition = ' Invoke-Command -ScriptBlock { Get-Process }'
65+ $violations = Invoke-ScriptAnalyzer - ScriptDefinition $scriptDefinition - IncludeRule $violationName
66+ $violations.Count | Should - Be 2
67+ ($violations.Extent.Text -contains " Invoke-Command" ) | Should - Be $true
68+ ($violations.Extent.Text -contains " Get-Process" ) | Should - Be $true
69+ }
70+
71+ It " detects violations with parameters" {
72+ $scriptDefinition = ' Get-ChildItem -Path C:\temp -Recurse'
73+ $violations = Invoke-ScriptAnalyzer - ScriptDefinition $scriptDefinition - IncludeRule $violationName
74+ $violations.Count | Should - Be 1
75+ $violations [0 ].Extent.Text | Should - Be " Get-ChildItem"
76+ }
77+
78+ It " detects violations with splatting" {
79+ $scriptDefinition = @'
80+ $params = @{ Name = "notepad" }
81+ Get-Process @params
82+ '@
83+ $violations = Invoke-ScriptAnalyzer - ScriptDefinition $scriptDefinition - IncludeRule $violationName
84+ $violations.Count | Should - Be 1
85+ $violations [0 ].Extent.Text | Should - Be " Get-Process"
86+ }
87+ }
88+
89+ Context " Violation Extent" {
90+ It " should return only the cmdlet extent, not parameters" {
91+ $scriptDefinition = ' Get-Command -Name Test'
92+ $violations = Invoke-ScriptAnalyzer - ScriptDefinition $scriptDefinition - IncludeRule $violationName
93+ $violations [0 ].Extent.Text | Should - Be " Get-Command"
94+ }
95+
96+ It " should return only the alias extent, not parameters" {
97+ $scriptDefinition = ' gci -Recurse'
98+ $violations = Invoke-ScriptAnalyzer - ScriptDefinition $scriptDefinition - IncludeRule $violationName
99+ $violations [0 ].Extent.Text | Should - Be " gci"
100+ }
101+ }
102+
103+ Context " When there are no violations" {
104+ It " ignores already qualified cmdlets" {
105+ $scriptDefinition = @'
106+ Microsoft.PowerShell.Core\Get-Command
107+ Microsoft.PowerShell.Utility\Write-Host "test"
108+ Microsoft.PowerShell.Management\Get-ChildItem -Path C:\temp
109+ '@
110+ $violations = Invoke-ScriptAnalyzer - ScriptDefinition $scriptDefinition - IncludeRule $violationName
111+ $violations.Count | Should - Be 0
112+ }
113+
114+ It " ignores native commands" {
115+ $scriptDefinition = @'
116+ where.exe notepad
117+ cmd /c dir
118+ '@
119+ $violations = Invoke-ScriptAnalyzer - ScriptDefinition $scriptDefinition - IncludeRule $violationName
120+ $violations.Count | Should - Be 0
121+ }
122+
123+ It " ignores variables" {
124+ $scriptDefinition = @'
125+ $GetCommand = "test"
126+ $variable = $true
127+ '@
128+ $violations = Invoke-ScriptAnalyzer - ScriptDefinition $scriptDefinition - IncludeRule $violationName
129+ $violations.Count | Should - Be 0
130+ }
131+
132+ It " ignores string literals containing cmdlet names" {
133+ $scriptDefinition = @'
134+ $command = "Get-Command"
135+ "The Get-Command cmdlet is useful"
136+ '@
137+ $violations = Invoke-ScriptAnalyzer - ScriptDefinition $scriptDefinition - IncludeRule $violationName
138+ $violations.Count | Should - Be 0
139+ }
140+
141+ It " handles mixed qualified and unqualified cmdlets" {
142+ $scriptDefinition = @'
143+ Microsoft.PowerShell.Core\Get-Command
144+ Get-Process
145+ '@
146+ $violations = Invoke-ScriptAnalyzer - ScriptDefinition $scriptDefinition - IncludeRule $violationName
147+ $violations.Count | Should - Be 1
148+ $violations [0 ].Extent.Text | Should - Be " Get-Process"
149+ }
150+ }
151+
152+ Context " Different Module Contexts" {
153+ It " handles cmdlets from different modules" {
154+ $scriptDefinition = @'
155+ Get-Content "file.txt"
156+ ConvertTo-Json @{}
157+ Test-Connection "server"
158+ '@
159+ $violations = Invoke-ScriptAnalyzer - ScriptDefinition $scriptDefinition - IncludeRule $violationName
160+ $violations.Count | Should - Be 3
161+
162+ $getContentViolation = $violations | Where-Object { $_.Extent.Text -eq " Get-Content" }
163+ $getContentViolation.SuggestedCorrections [0 ].Text | Should -Match " Get-Content$"
164+
165+ $convertToJsonViolation = $violations | Where-Object { $_.Extent.Text -eq " ConvertTo-Json" }
166+ $convertToJsonViolation.SuggestedCorrections [0 ].Text | Should -Match " ConvertTo-Json$"
167+ }
168+
169+ It " suggests different modules for different cmdlets" {
170+ $scriptDefinition = @'
171+ Get-Command
172+ Write-Host "test"
173+ Get-ChildItem
174+ '@
175+ $violations = Invoke-ScriptAnalyzer - ScriptDefinition $scriptDefinition - IncludeRule $violationName
176+ $violations.Count | Should - Be 3
177+
178+ $getCmdViolation = $violations | Where-Object { $_.Extent.Text -eq " Get-Command" }
179+ $getCmdViolation.SuggestedCorrections [0 ].Text | Should - Be ' Microsoft.PowerShell.Core\Get-Command'
180+
181+ $writeHostViolation = $violations | Where-Object { $_.Extent.Text -eq " Write-Host" }
182+ $writeHostViolation.SuggestedCorrections [0 ].Text | Should - Be ' Microsoft.PowerShell.Utility\Write-Host'
183+
184+ $getChildItemViolation = $violations | Where-Object { $_.Extent.Text -eq " Get-ChildItem" }
185+ $getChildItemViolation.SuggestedCorrections [0 ].Text | Should - Be ' Microsoft.PowerShell.Management\Get-ChildItem'
186+ }
187+ }
188+
189+ Context " Severity and Rule Properties" {
190+ It " has Warning severity" {
191+ $scriptDefinition = ' Get-Command'
192+ $violations = Invoke-ScriptAnalyzer - ScriptDefinition $scriptDefinition - IncludeRule $violationName
193+ $violations [0 ].Severity | Should - Be ([Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic.DiagnosticSeverity ]::Warning)
194+ }
195+
196+ It " has correct rule name" {
197+ $scriptDefinition = ' Get-Command'
198+ $violations = Invoke-ScriptAnalyzer - ScriptDefinition $scriptDefinition - IncludeRule $violationName
199+ $violations [0 ].RuleName | Should - Be $violationName
200+ }
201+ }
202+ }
0 commit comments