Skip to content

Commit 4ad5980

Browse files
Update docs and diagnostic message for UseCorrectCasing (#2138)
* Inline the 2 overloads of GetDiagnosticRecord to their individual call sites It made it cumbersome to pass a different number of arguments to the string.Format call and didn't seem necessary * Add tests for diagnostic messages related to casing of functions, parameters, and operators * Remove errant space in rule name * Swap over and expand descriptions of CheckCommands and CheckOperator * Update the 'Wrong way' section to use an operator in the wrong way * inline local message var --------- Co-authored-by: Christoph Bergmeister <c.bergmeister@gmail.com>
1 parent 7d2b8ae commit 4ad5980

File tree

3 files changed

+51
-33
lines changed

3 files changed

+51
-33
lines changed

Rules/UseCorrectCasing.cs

Lines changed: 26 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,19 @@ public override IEnumerable<DiagnosticRecord> AnalyzeScript(Ast ast, string file
103103

104104
if (!commandName.Equals(correctlyCasedCommandName, StringComparison.Ordinal))
105105
{
106-
yield return GetDiagnosticRecord(commandAst, fileName, correctlyCasedCommandName, Strings.UseCorrectCasingError);
106+
var extent = GetCommandExtent(commandAst);
107+
yield return new DiagnosticRecord(
108+
string.Format(
109+
CultureInfo.CurrentCulture,
110+
Strings.UseCorrectCasingError,
111+
commandName,
112+
correctlyCasedCommandName),
113+
extent,
114+
GetName(),
115+
DiagnosticSeverity.Information,
116+
fileName,
117+
correctlyCasedCommandName,
118+
GetCorrectionExtent(commandAst, extent, correctlyCasedCommandName));
107119
}
108120

109121
var commandParameterAsts = commandAst.FindAll(
@@ -129,15 +141,26 @@ public override IEnumerable<DiagnosticRecord> AnalyzeScript(Ast ast, string file
129141
var correctlyCasedParameterName = parameterMetaData.Name;
130142
if (!parameterName.Equals(correctlyCasedParameterName, StringComparison.Ordinal))
131143
{
132-
yield return GetDiagnosticRecord(commandParameterAst, fileName, correctlyCasedParameterName, Strings.UseCorrectCasingError);
144+
yield return new DiagnosticRecord(
145+
string.Format(
146+
CultureInfo.CurrentCulture,
147+
Strings.UseCorrectCasingParameterError,
148+
commandParameterAst.Extent.Text,
149+
commandName,
150+
correctlyCasedParameterName),
151+
commandParameterAst.Extent,
152+
GetName(),
153+
DiagnosticSeverity.Information,
154+
fileName,
155+
correctlyCasedParameterName,
156+
GetCorrectionExtent(commandParameterAst, commandParameterAst.Extent, correctlyCasedParameterName));
133157
}
134158
}
135159
}
136160
}
137161
}
138162
}
139163

140-
141164
/// <summary>
142165
/// For a command like "gci -path c:", returns the extent of "gci" in the command
143166
/// </summary>
@@ -197,32 +220,6 @@ private DiagnosticRecord GetDiagnosticRecord(Token token, string fileName, strin
197220
suggestedCorrections: extents);
198221
}
199222

200-
private DiagnosticRecord GetDiagnosticRecord(Ast ast, string fileName, string correction, string message)
201-
{
202-
var extent = ast is CommandAst ? GetCommandExtent((CommandAst)ast) : ast.Extent;
203-
return new DiagnosticRecord(
204-
string.Format(CultureInfo.CurrentCulture, message, extent.Text, correction),
205-
extent,
206-
GetName(),
207-
DiagnosticSeverity.Information,
208-
fileName,
209-
correction,
210-
suggestedCorrections: GetCorrectionExtent(ast, extent, correction));
211-
}
212-
213-
private DiagnosticRecord GetDiagnosticRecord(CommandParameterAst ast, string fileName, string correction, string message)
214-
{
215-
var extent = ast.Extent;
216-
return new DiagnosticRecord(
217-
string.Format(CultureInfo.CurrentCulture, message, extent.Text, correction),
218-
extent,
219-
GetName(),
220-
DiagnosticSeverity.Information,
221-
fileName,
222-
correction,
223-
suggestedCorrections: GetCorrectionExtent(ast, extent, correction));
224-
}
225-
226223
/// <summary>
227224
/// GetName: Retrieves the name of this rule.
228225
/// </summary>

Tests/Rules/UseCorrectCasing.tests.ps1

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,27 @@ Describe "UseCorrectCasing" {
103103
Should -BeExactly '$A++; $B--'
104104
}
105105

106+
It "Shows relevant diagnostic message for function/command name casing" {
107+
$settings = @{ 'Rules' = @{ 'PSUseCorrectCasing' = @{ 'Enable' = $true; CheckCommands = $true; CheckKeywords = $true; CheckOperators = $true } } }
108+
$violations = Invoke-ScriptAnalyzer -ScriptDefinition 'WHERE-OBJECT Name -EQ "Value"' -Settings $settings
109+
$violations.Count | Should -Be 1
110+
$violations[0].Message | Should -Be "Function/Cmdlet 'WHERE-OBJECT' does not match its exact casing 'Where-Object'."
111+
}
112+
113+
It "Shows relevant diagnostic message for parameter casing" {
114+
$settings = @{ 'Rules' = @{ 'PSUseCorrectCasing' = @{ 'Enable' = $true; CheckCommands = $true; CheckKeywords = $true; CheckOperators = $true } } }
115+
$violations = Invoke-ScriptAnalyzer -ScriptDefinition 'Where-Object Name -eq "Value"' -Settings $settings
116+
$violations.Count | Should -Be 1
117+
$violations[0].Message | Should -Be "Parameter '-eq' of function/cmdlet 'Where-Object' does not match its exact casing 'EQ'."
118+
}
119+
120+
It "Shows relevant diagnostic message for operator casing" {
121+
$settings = @{ 'Rules' = @{ 'PSUseCorrectCasing' = @{ 'Enable' = $true; CheckCommands = $true; CheckKeywords = $true; CheckOperators = $true } } }
122+
$violations = Invoke-ScriptAnalyzer -ScriptDefinition '$a -EQ 1' -Settings $settings
123+
$violations.Count | Should -Be 1
124+
$violations[0].Message | Should -Be "Operator '-EQ' does not match the expected case '-eq'."
125+
}
126+
106127
Context "Inconsistent Keywords" {
107128
It "Corrects keyword case" {
108129
Invoke-Formatter 'ForEach ($x IN $y) { $x }' |

docs/Rules/UseCorrectCasing.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ commands. Using lowercase operators helps distinguish them from parameters.
2525

2626
```powershell
2727
Rules = @{
28-
PS UseCorrectCasing = @{
28+
PSUseCorrectCasing = @{
2929
Enable = $true
3030
CheckCommands = $true
3131
CheckKeyword = $true
@@ -42,23 +42,23 @@ Enable or disable the rule during ScriptAnalyzer invocation.
4242

4343
#### CheckCommands: bool (Default value is `$true`)
4444

45-
If true, require the case of all operators to be lowercase.
45+
If true, require the case of all command and parameter names to match their canonical casing.
4646

4747
#### CheckKeyword: bool (Default value is `$true`)
4848

4949
If true, require the case of all keywords to be lowercase.
5050

5151
#### CheckOperator: bool (Default value is `$true`)
5252

53-
If true, require the case of all commands to match their actual casing.
53+
If true, require the case of all operators (e.g. -eq, -ne, -gt) to be lowercase.
5454

5555
## Examples
5656

5757
### Wrong way
5858

5959
```powershell
6060
ForEach ($file in Get-childitem -Recurse) {
61-
$file.Extension -eq '.txt'
61+
$file.Extension -EQ '.txt'
6262
}
6363
6464
invoke-command { 'foo' } -runasadministrator

0 commit comments

Comments
 (0)