Skip to content
This repository was archived by the owner on Feb 24, 2021. It is now read-only.

Commit 1897361

Browse files
authored
Merge pull request #333 from PlagueHO/Issue-244
Adds PSSA Tests for Statement Capitalization
2 parents 5d468e3 + bc15d75 commit 1897361

File tree

6 files changed

+615
-18
lines changed

6 files changed

+615
-18
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,9 @@
7171
- The files are now outputted as UTF-8 (ASCII).
7272
- Added processing to `Test-PublishMetaData` for the InvalidGUID error
7373
from Test-ScriptFileInfo ([issue #330](https://github.com/PowerShell/DscResource.Tests/issues/330)).
74+
- Added PowerShell Script Analyzer rules to check the following
75+
statements are in lower case: `if`,`foreach`,`do`,`while`,`for`,
76+
`try`,`catch`,`enum`,`class` ([issue #224](https://github.com/PowerShell/DscResource.Tests/issues/224)).
7477

7578
## 0.3.0.0
7679

DscResource.AnalyzerRules/DscResource.AnalyzerRules.Helper.psm1

Lines changed: 43 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@
1212
.OUTPUTS
1313
[System.Boolean]
1414
15-
.NOTES
16-
I initially just walked up the AST tree till I hit
15+
.NOTES
16+
I initially just walked up the AST tree till I hit
1717
a TypeDefinitionAst that was a class
1818
1919
But...
@@ -60,7 +60,7 @@ function Test-IsInClass
6060
if ($Ast -is [System.Management.Automation.Language.NamedAttributeArgumentAst])
6161
{
6262
# Parent is an Attribute Ast AND
63-
$inAClass = $Ast.Parent -is [System.Management.Automation.Language.AttributeAst] -and
63+
$inAClass = $Ast.Parent -is [System.Management.Automation.Language.AttributeAst] -and
6464
# Grandparent is a Property Member Ast (This Ast Type ONLY shows up inside a TypeDefinitionAst) AND
6565
$Ast.Parent.Parent -is [System.Management.Automation.Language.PropertyMemberAst] -and
6666
# Great Grandparent is a Type Definition Ast AND
@@ -73,7 +73,7 @@ function Test-IsInClass
7373
{
7474
# Parent is a Function Definition Ast AND
7575
$inAClass = $Ast.Parent -is [System.Management.Automation.Language.FunctionDefinitionAst] -and
76-
# Grandparent is a Function Member Ast (This Ast Type ONLY shows up inside a TypeDefinitionAst) AND
76+
# Grandparent is a Function Member Ast (This Ast Type ONLY shows up inside a TypeDefinitionAst) AND
7777
$Ast.Parent.Parent -is [System.Management.Automation.Language.FunctionMemberAst] -and
7878
# Great Grandparent is a Type Definition Ast AND
7979
$Ast.Parent.Parent.Parent -is [System.Management.Automation.Language.TypeDefinitionAst] -and
@@ -98,7 +98,7 @@ function Test-IsInClass
9898
.OUTPUTS
9999
[System.String[]]
100100
101-
.NOTES
101+
.NOTES
102102
None
103103
#>
104104
function Get-StatementBlockAsRows
@@ -136,7 +136,7 @@ function Get-StatementBlockAsRows
136136
.OUTPUTS
137137
[System.Boolean]
138138
139-
.NOTES
139+
.NOTES
140140
None
141141
#>
142142
function Test-StatementOpeningBraceOnSameLine
@@ -178,7 +178,7 @@ function Test-StatementOpeningBraceOnSameLine
178178
.OUTPUTS
179179
[System.Boolean]
180180
181-
.NOTES
181+
.NOTES
182182
None
183183
#>
184184
function Test-StatementOpeningBraceIsNotFollowedByNewLine
@@ -220,7 +220,7 @@ function Test-StatementOpeningBraceIsNotFollowedByNewLine
220220
.OUTPUTS
221221
[System.Boolean]
222222
223-
.NOTES
223+
.NOTES
224224
None
225225
#>
226226
function Test-StatementOpeningBraceIsFollowedByMoreThanOneNewLine
@@ -247,3 +247,38 @@ function Test-StatementOpeningBraceIsFollowedByMoreThanOneNewLine
247247

248248
return $false
249249
}
250+
251+
<#
252+
.SYNOPSIS
253+
Helper function for the Measure-*Statement PSScriptAnalyzer rules.
254+
Tests if the statement at the beginning of the string contains any
255+
upper case letters.
256+
257+
.PARAMETER StatementBlock
258+
The StatementBlock that contains the statement to check contains any
259+
upper case letters.
260+
261+
.EXAMPLE
262+
Test-StatementContainsUpperCase -StatementBlock $ScriptBlockAst.Extent
263+
264+
.OUTPUTS
265+
[System.Boolean]
266+
267+
.NOTES
268+
None
269+
#>
270+
function Test-StatementContainsUpperCase
271+
{
272+
[CmdletBinding()]
273+
[OutputType([System.Boolean])]
274+
param
275+
(
276+
[Parameter(Mandatory = $true)]
277+
[ValidateNotNullOrEmpty()]
278+
[System.String]
279+
$StatementBlock
280+
)
281+
282+
$statement = [System.Text.RegularExpressions.Regex]::Match($statementBlock,'^[a-zA-Z]*').Value
283+
return ($statement -cne $statement.ToLower())
284+
}

DscResource.AnalyzerRules/DscResource.AnalyzerRules.psm1

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,8 @@ function Measure-FunctionBlockBraces
246246
.DESCRIPTION
247247
Each if-statement should have the opening brace on a separate line.
248248
Also, the opening brace should be followed by a new line.
249+
The if statement should also be in all lower case.
250+
The else and elseif statements are not currently checked.
249251
250252
.EXAMPLE
251253
Measure-IfStatement -IfStatementAst $ScriptBlockAst
@@ -305,6 +307,12 @@ function Measure-IfStatement
305307
$script:diagnosticRecord['Message'] = $localizedData.IfStatementOpeningBraceShouldBeFollowedByOnlyOneNewLine
306308
$script:diagnosticRecord -as $diagnosticRecordType
307309
} # if
310+
311+
if (Test-StatementContainsUpperCase @testParameters)
312+
{
313+
$script:diagnosticRecord['Message'] = $localizedData.StatementsContainsUpperCaseLetter -f 'if'
314+
$script:diagnosticRecord -as $diagnosticRecordType
315+
} # if
308316
}
309317
catch
310318
{
@@ -319,6 +327,7 @@ function Measure-IfStatement
319327
.DESCRIPTION
320328
Each foreach-statement should have the opening brace on a separate line.
321329
Also, the opening brace should be followed by a new line.
330+
The foreach statement should also be in all lower case.
322331
323332
.EXAMPLE
324333
Measure-ForEachStatement -ForEachStatementAst $ScriptBlockAst
@@ -370,6 +379,12 @@ function Measure-ForEachStatement
370379
$script:diagnosticRecord['Message'] = $localizedData.ForEachStatementOpeningBraceShouldBeFollowedByOnlyOneNewLine
371380
$script:diagnosticRecord -as $diagnosticRecordType
372381
} # if
382+
383+
if (Test-StatementContainsUpperCase @testParameters)
384+
{
385+
$script:diagnosticRecord['Message'] = $localizedData.StatementsContainsUpperCaseLetter -f 'foreach'
386+
$script:diagnosticRecord -as $diagnosticRecordType
387+
} # if
373388
}
374389
catch
375390
{
@@ -384,6 +399,7 @@ function Measure-ForEachStatement
384399
.DESCRIPTION
385400
Each DoUntil-statement should have the opening brace on a separate line.
386401
Also, the opening brace should be followed by a new line.
402+
The do statement should also be in all lower case.
387403
388404
.EXAMPLE
389405
Measure-DoUntilStatement -DoUntilStatementAst $ScriptBlockAst
@@ -435,6 +451,12 @@ function Measure-DoUntilStatement
435451
$script:diagnosticRecord['Message'] = $localizedData.DoUntilStatementOpeningBraceShouldBeFollowedByOnlyOneNewLine
436452
$script:diagnosticRecord -as $diagnosticRecordType
437453
} # if
454+
455+
if (Test-StatementContainsUpperCase @testParameters)
456+
{
457+
$script:diagnosticRecord['Message'] = $localizedData.StatementsContainsUpperCaseLetter -f 'do'
458+
$script:diagnosticRecord -as $diagnosticRecordType
459+
} # if
438460
}
439461
catch
440462
{
@@ -449,6 +471,7 @@ function Measure-DoUntilStatement
449471
.DESCRIPTION
450472
Each DoWhile-statement should have the opening brace on a separate line.
451473
Also, the opening brace should be followed by a new line.
474+
The do statement should also be in all lower case.
452475
453476
.EXAMPLE
454477
Measure-DoWhileStatement -DoWhileStatementAst $ScriptBlockAst
@@ -500,6 +523,12 @@ function Measure-DoWhileStatement
500523
$script:diagnosticRecord['Message'] = $localizedData.DoWhileStatementOpeningBraceShouldBeFollowedByOnlyOneNewLine
501524
$script:diagnosticRecord -as $diagnosticRecordType
502525
} # if
526+
527+
if (Test-StatementContainsUpperCase @testParameters)
528+
{
529+
$script:diagnosticRecord['Message'] = $localizedData.StatementsContainsUpperCaseLetter -f 'do'
530+
$script:diagnosticRecord -as $diagnosticRecordType
531+
} # if
503532
}
504533
catch
505534
{
@@ -514,6 +543,7 @@ function Measure-DoWhileStatement
514543
.DESCRIPTION
515544
Each while-statement should have the opening brace on a separate line.
516545
Also, the opening brace should be followed by a new line.
546+
The while statement should also be in all lower case.
517547
518548
.EXAMPLE
519549
Measure-WhileStatement -WhileStatementAst $ScriptBlockAst
@@ -565,6 +595,12 @@ function Measure-WhileStatement
565595
$script:diagnosticRecord['Message'] = $localizedData.WhileStatementOpeningBraceShouldBeFollowedByOnlyOneNewLine
566596
$script:diagnosticRecord -as $diagnosticRecordType
567597
} # if
598+
599+
if (Test-StatementContainsUpperCase @testParameters)
600+
{
601+
$script:diagnosticRecord['Message'] = $localizedData.StatementsContainsUpperCaseLetter -f 'while'
602+
$script:diagnosticRecord -as $diagnosticRecordType
603+
} # if
568604
}
569605
catch
570606
{
@@ -579,6 +615,7 @@ function Measure-WhileStatement
579615
.DESCRIPTION
580616
Each for-statement should have the opening brace on a separate line.
581617
Also, the opening brace should be followed by a new line.
618+
The for statement should also be in all lower case.
582619
583620
.EXAMPLE
584621
Measure-ForStatement -ForStatementAst $ScriptBlockAst
@@ -630,6 +667,12 @@ function Measure-ForStatement
630667
$script:diagnosticRecord['Message'] = $localizedData.ForStatementOpeningBraceShouldBeFollowedByOnlyOneNewLine
631668
$script:diagnosticRecord -as $diagnosticRecordType
632669
} # if
670+
671+
if (Test-StatementContainsUpperCase @testParameters)
672+
{
673+
$script:diagnosticRecord['Message'] = $localizedData.StatementsContainsUpperCaseLetter -f 'for'
674+
$script:diagnosticRecord -as $diagnosticRecordType
675+
} # if
633676
}
634677
catch
635678
{
@@ -644,6 +687,7 @@ function Measure-ForStatement
644687
.DESCRIPTION
645688
Each switch-statement should have the opening brace on a separate line.
646689
Also, the opening brace should be followed by a new line.
690+
The switch statement should also be in all lower case.
647691
648692
.EXAMPLE
649693
Measure-SwitchStatement -SwitchStatementAst $ScriptBlockAst
@@ -699,6 +743,12 @@ function Measure-SwitchStatement
699743
$script:diagnosticRecord['Message'] = $localizedData.SwitchStatementOpeningBraceShouldBeFollowedByOnlyOneNewLine
700744
$script:diagnosticRecord -as $diagnosticRecordType
701745
} # if
746+
747+
if (Test-StatementContainsUpperCase @testParameters)
748+
{
749+
$script:diagnosticRecord['Message'] = $localizedData.StatementsContainsUpperCaseLetter -f 'switch'
750+
$script:diagnosticRecord -as $diagnosticRecordType
751+
} # if
702752
}
703753
catch
704754
{
@@ -713,6 +763,7 @@ function Measure-SwitchStatement
713763
.DESCRIPTION
714764
Each try-statement should have the opening brace on a separate line.
715765
Also, the opening brace should be followed by a new line.
766+
The try statement should also be in all lower case.
716767
717768
.EXAMPLE
718769
Measure-TryStatement -TryStatementAst $ScriptBlockAst
@@ -764,6 +815,12 @@ function Measure-TryStatement
764815
$script:diagnosticRecord['Message'] = $localizedData.TryStatementOpeningBraceShouldBeFollowedByOnlyOneNewLine
765816
$script:diagnosticRecord -as $diagnosticRecordType
766817
} # if
818+
819+
if (Test-StatementContainsUpperCase @testParameters)
820+
{
821+
$script:diagnosticRecord['Message'] = $localizedData.StatementsContainsUpperCaseLetter -f 'try'
822+
$script:diagnosticRecord -as $diagnosticRecordType
823+
} # if
767824
}
768825
catch
769826
{
@@ -778,6 +835,7 @@ function Measure-TryStatement
778835
.DESCRIPTION
779836
Each catch-clause should have the opening brace on a separate line.
780837
Also, the opening brace should be followed by a new line.
838+
The catch statement should also be in all lower case.
781839
782840
.EXAMPLE
783841
Measure-CatchClause -CatchClauseAst $ScriptBlockAst
@@ -829,6 +887,12 @@ function Measure-CatchClause
829887
$script:diagnosticRecord['Message'] = $localizedData.CatchClauseOpeningBraceShouldBeFollowedByOnlyOneNewLine
830888
$script:diagnosticRecord -as $diagnosticRecordType
831889
} # if
890+
891+
if (Test-StatementContainsUpperCase @testParameters)
892+
{
893+
$script:diagnosticRecord['Message'] = $localizedData.StatementsContainsUpperCaseLetter -f 'catch'
894+
$script:diagnosticRecord -as $diagnosticRecordType
895+
} # if
832896
}
833897
catch
834898
{
@@ -842,6 +906,7 @@ function Measure-CatchClause
842906
843907
.DESCRIPTION
844908
Each Class or Enum must be formatted correctly.
909+
The class or enum statement should also be in all lower case.
845910
846911
.EXAMPLE
847912
Measure-TypeDefinition -TypeDefinitionAst $ScriptBlockAst
@@ -895,6 +960,12 @@ function Measure-TypeDefinition
895960
$script:diagnosticRecord['Message'] = $localizedData.EnumOpeningBraceShouldBeFollowedByOnlyOneNewLine
896961
$script:diagnosticRecord -as $diagnosticRecordType
897962
} # if
963+
964+
if (Test-StatementContainsUpperCase @testParameters)
965+
{
966+
$script:diagnosticRecord['Message'] = $localizedData.StatementsContainsUpperCaseLetter -f 'enum'
967+
$script:diagnosticRecord -as $diagnosticRecordType
968+
} # if
898969
} # if
899970
elseif ($TypeDefinitionAst.IsClass)
900971
{
@@ -915,6 +986,12 @@ function Measure-TypeDefinition
915986
$script:diagnosticRecord['Message'] = $localizedData.ClassOpeningBraceShouldBeFollowedByOnlyOneNewLine
916987
$script:diagnosticRecord -as $diagnosticRecordType
917988
} # if
989+
990+
if (Test-StatementContainsUpperCase @testParameters)
991+
{
992+
$script:diagnosticRecord['Message'] = $localizedData.StatementsContainsUpperCaseLetter -f 'class'
993+
$script:diagnosticRecord -as $diagnosticRecordType
994+
} # if
918995
} # if
919996
}
920997
catch

DscResource.AnalyzerRules/en-US/DscResource.AnalyzerRules.psd1

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ ParameterBlockNonMandatoryParameterMandatoryAttributeWrongFormat = Non-mandatory
88
FunctionOpeningBraceNotOnSameLine = Functions should not have the open brace on the same line as the function name. See https://github.com/PowerShell/DscResources/blob/master/StyleGuidelines.md#one-newline-before-braces
99
FunctionOpeningBraceShouldBeFollowedByNewLine = Opening brace on function should be followed by a new line. See https://github.com/PowerShell/DscResources/blob/master/StyleGuidelines.md#one-newline-after-opening-brace
1010
FunctionOpeningBraceShouldBeFollowedByOnlyOneNewLine = Opening brace on functions should only be followed by one new line. See https://github.com/PowerShell/DscResources/blob/master/StyleGuidelines.md#one-newline-after-opening-brace
11+
StatementsContainsUpperCaseLetter = '{0}' statements should not contain upper case letters See https://github.com/PowerShell/DscResources/blob/master/StyleGuidelines.md#correct-format-for-keywords
1112
IfStatementOpeningBraceNotOnSameLine = If-statements should not have the open brace on the same line as the statement. See https://github.com/PowerShell/DscResources/blob/master/StyleGuidelines.md#one-newline-before-braces
1213
IfStatementOpeningBraceShouldBeFollowedByNewLine = Opening brace on if-statements should be followed by a new line. See https://github.com/PowerShell/DscResources/blob/master/StyleGuidelines.md#one-newline-after-opening-brace
1314
IfStatementOpeningBraceShouldBeFollowedByOnlyOneNewLine = Opening brace on if-statements should only be followed by one new line. See https://github.com/PowerShell/DscResources/blob/master/StyleGuidelines.md#one-newline-after-opening-brace

Tests/Unit/DscResource.AnalyzerRules.Helper.Tests.ps1

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,5 +266,31 @@ Describe 'DscResource.AnalyzerRules.Helper Unit Tests' {
266266
}
267267
}
268268
}
269+
270+
Describe 'Test-StatementContainsUpperCase' {
271+
Context 'When statement is all lower case' {
272+
It 'Should return false' {
273+
$statementBlock = 'foreach ($a in $b)'
274+
275+
Test-StatementContainsUpperCase -StatementBlock $statementBlock | Should -Be $false
276+
}
277+
}
278+
279+
Context 'When statement is all upper case' {
280+
It 'Should return true' {
281+
$statementBlock = 'FOREACH ($a in $b)'
282+
283+
Test-StatementContainsUpperCase -StatementBlock $statementBlock | Should -Be $true
284+
}
285+
}
286+
287+
Context 'When statement is starts with lower case but contains upper case letters' {
288+
It 'Should return true' {
289+
$statementBlock = 'forEach ($a in $b)'
290+
291+
Test-StatementContainsUpperCase -StatementBlock $statementBlock | Should -Be $true
292+
}
293+
}
294+
}
269295
}
270296
}

0 commit comments

Comments
 (0)