diff --git a/Engine/Settings/CodeFormatting.psd1 b/Engine/Settings/CodeFormatting.psd1 index 02a07a1da..297d93326 100644 --- a/Engine/Settings/CodeFormatting.psd1 +++ b/Engine/Settings/CodeFormatting.psd1 @@ -29,11 +29,13 @@ } PSUseConsistentWhitespace = @{ - Enable = $true - CheckOpenBrace = $true - CheckOpenParen = $true - CheckOperator = $true - CheckSeparator = $true + Enable = $true + CheckInnerBrace = $true + CheckOpenBrace = $true + CheckOpenParen = $true + CheckOperator = $true + CheckPipe = $true + CheckSeparator = $true } PSAlignAssignmentStatement = @{ diff --git a/Engine/Settings/CodeFormattingAllman.psd1 b/Engine/Settings/CodeFormattingAllman.psd1 index 15b0ecfbd..ba2664b86 100644 --- a/Engine/Settings/CodeFormattingAllman.psd1 +++ b/Engine/Settings/CodeFormattingAllman.psd1 @@ -29,11 +29,13 @@ } PSUseConsistentWhitespace = @{ - Enable = $true - CheckOpenBrace = $true - CheckOpenParen = $true - CheckOperator = $true - CheckSeparator = $true + Enable = $true + CheckInnerBrace = $true + CheckOpenBrace = $true + CheckOpenParen = $true + CheckOperator = $true + CheckPipe = $true + CheckSeparator = $true } PSAlignAssignmentStatement = @{ diff --git a/Engine/Settings/CodeFormattingOTBS.psd1 b/Engine/Settings/CodeFormattingOTBS.psd1 index 589487235..634747a63 100644 --- a/Engine/Settings/CodeFormattingOTBS.psd1 +++ b/Engine/Settings/CodeFormattingOTBS.psd1 @@ -30,9 +30,11 @@ PSUseConsistentWhitespace = @{ Enable = $true + CheckInnerBrace = $true CheckOpenBrace = $true CheckOpenParen = $true CheckOperator = $true + CheckPipe = $true CheckSeparator = $true } diff --git a/Engine/Settings/CodeFormattingStroustrup.psd1 b/Engine/Settings/CodeFormattingStroustrup.psd1 index f40c83988..03a195b16 100644 --- a/Engine/Settings/CodeFormattingStroustrup.psd1 +++ b/Engine/Settings/CodeFormattingStroustrup.psd1 @@ -30,11 +30,13 @@ } PSUseConsistentWhitespace = @{ - Enable = $true - CheckOpenBrace = $true - CheckOpenParen = $true - CheckOperator = $true - CheckSeparator = $true + Enable = $true + CheckInnerBrace = $true + CheckOpenBrace = $true + CheckOpenParen = $true + CheckOperator = $true + CheckPipe = $true + CheckSeparator = $true } PSAlignAssignmentStatement = @{ diff --git a/RuleDocumentation/UseConsistentWhitespace.md b/RuleDocumentation/UseConsistentWhitespace.md index 192f7441a..10d333971 100644 --- a/RuleDocumentation/UseConsistentWhitespace.md +++ b/RuleDocumentation/UseConsistentWhitespace.md @@ -28,18 +28,26 @@ Enable or disable the rule during ScriptAnalyzer invocation. +#### CheckInnerBrace: bool (Default value is `$true`) + +Checks if there is a space after the opening brace and a space before the closing brace. E.g. `if ($true) { foo }` instead of `if ($true) {bar}`. + #### CheckOpenBrace: bool (Default value is `$true`) -Checks if there is a space between a keyword and its corresponding open brace. E.g. `foo { }`. +Checks if there is a space between a keyword and its corresponding open brace. E.g. `foo { }` instead of `foo{ }`. #### CheckOpenParen: bool (Default value is `$true`) -Checks if there is space between a keyword and its corresponding open parenthesis. E.g. `if (true)`. +Checks if there is space between a keyword and its corresponding open parenthesis. E.g. `if (true)` instead of `if(true)`. #### CheckOperator: bool (Default value is `$true`) -Checks if a binary or unary operator is surrounded on both sides by a space. E.g. `$x = 1`. +Checks if a binary or unary operator is surrounded on both sides by a space. E.g. `$x = 1` instead of `$x=1`. #### CheckSeparator: bool (Default value is `$true`) -Checks if a comma or a semicolon is followed by a space. E.g. `@(1, 2, 3)` or `@{a = 1; b = 2}`. +Checks if a comma or a semicolon is followed by a space. E.g. `@(1, 2, 3)` or `@{a = 1; b = 2}` instead of `@(1,2,3)` or `@{a = 1;b = 2}`. + +#### CheckPipe: bool (Default value is `$true`) + +Checks if a pipe is surrounded on both sides by a space. E.g. `foo | bar` instead of `foo|bar`. \ No newline at end of file diff --git a/Rules/Strings.Designer.cs b/Rules/Strings.Designer.cs index 49fd55aea..77fb2bb22 100644 --- a/Rules/Strings.Designer.cs +++ b/Rules/Strings.Designer.cs @@ -2256,12 +2256,30 @@ internal static string UseConsistentWhitespaceDescription { } } + /// + /// Looks up a localized string similar to Use space after open brace.. + /// + internal static string UseConsistentWhitespaceErrorAfterOpeningBrace { + get { + return ResourceManager.GetString("UseConsistentWhitespaceErrorAfterOpeningBrace", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Use space before closing brace.. + /// + internal static string UseConsistentWhitespaceErrorBeforeClosingInnerBrace { + get { + return ResourceManager.GetString("UseConsistentWhitespaceErrorBeforeClosingInnerBrace", resourceCulture); + } + } + /// /// Looks up a localized string similar to Use space before open brace.. /// - internal static string UseConsistentWhitespaceErrorBeforeBrace { + internal static string UseConsistentWhitespaceErrorBeforeOpeningBrace { get { - return ResourceManager.GetString("UseConsistentWhitespaceErrorBeforeBrace", resourceCulture); + return ResourceManager.GetString("UseConsistentWhitespaceErrorBeforeOpeningBrace", resourceCulture); } } @@ -2301,6 +2319,24 @@ internal static string UseConsistentWhitespaceErrorSeparatorSemi { } } + /// + /// Looks up a localized string similar to Use space after pipe.. + /// + internal static string UseConsistentWhitespaceErrorSpaceAfterPipe { + get { + return ResourceManager.GetString("UseConsistentWhitespaceErrorSpaceAfterPipe", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Use space before pipe.. + /// + internal static string UseConsistentWhitespaceErrorSpaceBeforePipe { + get { + return ResourceManager.GetString("UseConsistentWhitespaceErrorSpaceBeforePipe", resourceCulture); + } + } + /// /// Looks up a localized string similar to UseConsistentWhitespace. /// diff --git a/Rules/Strings.resx b/Rules/Strings.resx index 48861402c..66e1b086b 100644 --- a/Rules/Strings.resx +++ b/Rules/Strings.resx @@ -957,7 +957,7 @@ Check for whitespace between keyword and open paren/curly, around assigment operator ('='), around arithmetic operators and after separators (',' and ';') - + Use space before open brace. @@ -1044,4 +1044,16 @@ Use $null on the left hand side for safe comparison with $null. + + Use space after open brace. + + + Use space before closing brace. + + + Use space after pipe. + + + Use space before pipe. + \ No newline at end of file diff --git a/Rules/UseConsistentWhitespace.cs b/Rules/UseConsistentWhitespace.cs index b2cceb153..f4f2be6ad 100644 --- a/Rules/UseConsistentWhitespace.cs +++ b/Rules/UseConsistentWhitespace.cs @@ -22,7 +22,7 @@ namespace Microsoft.Windows.PowerShell.ScriptAnalyzer.BuiltinRules #endif public class UseConsistentWhitespace : ConfigurableRule { - private enum ErrorKind { Brace, Paren, Operator, SeparatorComma, SeparatorSemi }; + private enum ErrorKind { BeforeOpeningBrace, Paren, Operator, SeparatorComma, SeparatorSemi, AfterOpeningBrace, BeforeClosingBrace, BeforePipe, AfterPipe }; private const int whiteSpaceSize = 1; private const string whiteSpace = " "; private readonly SortedSet openParenKeywordWhitelist = new SortedSet() @@ -41,6 +41,12 @@ private List>> violationFind [ConfigurableRuleProperty(defaultValue: true)] public bool CheckOpenBrace { get; protected set; } + [ConfigurableRuleProperty(defaultValue: true)] + public bool CheckInnerBrace { get; protected set; } + + [ConfigurableRuleProperty(defaultValue: true)] + public bool CheckPipe { get; protected set; } + [ConfigurableRuleProperty(defaultValue: true)] public bool CheckOpenParen { get; protected set; } @@ -58,6 +64,16 @@ public override void ConfigureRule(IDictionary paramValueMap) violationFinders.Add(FindOpenBraceViolations); } + if (CheckInnerBrace) + { + violationFinders.Add(FindInnerBraceViolations); + } + + if (CheckPipe) + { + violationFinders.Add(FindPipeViolations); + } + if (CheckOpenParen) { violationFinders.Add(FindOpenParenViolations); @@ -171,10 +187,18 @@ private string GetError(ErrorKind kind) { switch (kind) { - case ErrorKind.Brace: - return string.Format(CultureInfo.CurrentCulture, Strings.UseConsistentWhitespaceErrorBeforeBrace); + case ErrorKind.BeforeOpeningBrace: + return string.Format(CultureInfo.CurrentCulture, Strings.UseConsistentWhitespaceErrorBeforeOpeningBrace); + case ErrorKind.AfterOpeningBrace: + return string.Format(CultureInfo.CurrentCulture, Strings.UseConsistentWhitespaceErrorAfterOpeningBrace); + case ErrorKind.BeforeClosingBrace: + return string.Format(CultureInfo.CurrentCulture, Strings.UseConsistentWhitespaceErrorBeforeClosingInnerBrace); case ErrorKind.Operator: return string.Format(CultureInfo.CurrentCulture, Strings.UseConsistentWhitespaceErrorOperator); + case ErrorKind.BeforePipe: + return string.Format(CultureInfo.CurrentCulture, Strings.UseConsistentWhitespaceErrorSpaceBeforePipe); + case ErrorKind.AfterPipe: + return string.Format(CultureInfo.CurrentCulture, Strings.UseConsistentWhitespaceErrorSpaceAfterPipe); case ErrorKind.SeparatorComma: return string.Format(CultureInfo.CurrentCulture, Strings.UseConsistentWhitespaceErrorSeparatorComma); case ErrorKind.SeparatorSemi: @@ -200,7 +224,7 @@ private IEnumerable FindOpenBraceViolations(TokenOperations to if (!IsPreviousTokenApartByWhitespace(lcurly)) { yield return new DiagnosticRecord( - GetError(ErrorKind.Brace), + GetError(ErrorKind.BeforeOpeningBrace), lcurly.Value.Extent, GetName(), GetDiagnosticSeverity(), @@ -211,6 +235,111 @@ private IEnumerable FindOpenBraceViolations(TokenOperations to } } + private IEnumerable FindInnerBraceViolations(TokenOperations tokenOperations) + { + foreach (var lCurly in tokenOperations.GetTokenNodes(TokenKind.LCurly)) + { + if (lCurly.Next == null + || !IsPreviousTokenOnSameLine(lCurly) + || lCurly.Next.Value.Kind == TokenKind.NewLine + || lCurly.Next.Value.Kind == TokenKind.LineContinuation + ) + { + continue; + } + + if (!IsNextTokenApartByWhitespace(lCurly)) + { + yield return new DiagnosticRecord( + GetError(ErrorKind.AfterOpeningBrace), + lCurly.Value.Extent, + GetName(), + GetDiagnosticSeverity(), + tokenOperations.Ast.Extent.File, + null, + GetCorrections(lCurly.Previous.Value, lCurly.Value, lCurly.Next.Value, true, false).ToList()); + } + } + + foreach (var rCurly in tokenOperations.GetTokenNodes(TokenKind.RCurly)) + { + if (rCurly.Previous == null + || !IsPreviousTokenOnSameLine(rCurly) + || rCurly.Previous.Value.Kind == TokenKind.LCurly + || rCurly.Previous.Value.Kind == TokenKind.NewLine + || rCurly.Previous.Value.Kind == TokenKind.LineContinuation + ) + { + continue; + } + + if (!IsPreviousTokenApartByWhitespace(rCurly)) + { + yield return new DiagnosticRecord( + GetError(ErrorKind.BeforeClosingBrace), + rCurly.Value.Extent, + GetName(), + GetDiagnosticSeverity(), + tokenOperations.Ast.Extent.File, + null, + GetCorrections(rCurly.Previous.Value, rCurly.Value, rCurly.Next.Value, false, true).ToList()); + } + } + } + + private IEnumerable FindPipeViolations(TokenOperations tokenOperations) + { + foreach (var pipe in tokenOperations.GetTokenNodes(TokenKind.Pipe)) + { + if (pipe.Next == null + || !IsPreviousTokenOnSameLine(pipe) + || pipe.Next.Value.Kind == TokenKind.Pipe + || pipe.Next.Value.Kind == TokenKind.NewLine + || pipe.Next.Value.Kind == TokenKind.LineContinuation + ) + { + continue; + } + + if (!IsNextTokenApartByWhitespace(pipe)) + { + yield return new DiagnosticRecord( + GetError(ErrorKind.AfterPipe), + pipe.Value.Extent, + GetName(), + GetDiagnosticSeverity(), + tokenOperations.Ast.Extent.File, + null, + GetCorrections(pipe.Previous.Value, pipe.Value, pipe.Next.Value, true, false).ToList()); + } + } + + foreach (var pipe in tokenOperations.GetTokenNodes(TokenKind.Pipe)) + { + if (pipe.Previous == null + || !IsPreviousTokenOnSameLine(pipe) + || pipe.Previous.Value.Kind == TokenKind.Pipe + || pipe.Previous.Value.Kind == TokenKind.NewLine + || pipe.Previous.Value.Kind == TokenKind.LineContinuation + ) + { + continue; + } + + if (!IsPreviousTokenApartByWhitespace(pipe)) + { + yield return new DiagnosticRecord( + GetError(ErrorKind.BeforePipe), + pipe.Value.Extent, + GetName(), + GetDiagnosticSeverity(), + tokenOperations.Ast.Extent.File, + null, + GetCorrections(pipe.Previous.Value, pipe.Value, pipe.Next.Value, false, true).ToList()); + } + } + } + private IEnumerable FindOpenParenViolations(TokenOperations tokenOperations) { foreach (var lparen in tokenOperations.GetTokenNodes(TokenKind.LParen)) @@ -291,6 +420,12 @@ private bool IsPreviousTokenApartByWhitespace(LinkedListNode tokenNode) (tokenNode.Value.Extent.StartColumnNumber - tokenNode.Previous.Value.Extent.EndColumnNumber); } + private bool IsNextTokenApartByWhitespace(LinkedListNode tokenNode) + { + return whiteSpaceSize == + (tokenNode.Next.Value.Extent.StartColumnNumber - tokenNode.Value.Extent.EndColumnNumber); + } + private bool IsPreviousTokenOnSameLineAndApartByWhitespace(LinkedListNode tokenNode) { return IsPreviousTokenOnSameLine(tokenNode) && IsPreviousTokenApartByWhitespace(tokenNode); @@ -342,8 +477,9 @@ private List GetCorrections( Token prevToken, Token token, Token nextToken, - bool hasWhitespaceBefore, - bool hasWhitespaceAfter) + bool hasWhitespaceBefore, // if this is false, then the returned correction extent will add a whitespace before the token + bool hasWhitespaceAfter // if this is false, then the returned correction extent will add a whitespace after the token + ) { var sb = new StringBuilder(); IScriptExtent e1 = token.Extent; diff --git a/Tests/Engine/InvokeScriptAnalyzer.tests.ps1 b/Tests/Engine/InvokeScriptAnalyzer.tests.ps1 index 78643483d..ed71a57d2 100644 --- a/Tests/Engine/InvokeScriptAnalyzer.tests.ps1 +++ b/Tests/Engine/InvokeScriptAnalyzer.tests.ps1 @@ -446,7 +446,7 @@ Describe "Test CustomizedRulePath" { It "resolves rule preset when passed in via pipeline" { $warnings = 'CodeFormattingStroustrup' | ForEach-Object { - Invoke-ScriptAnalyzer -ScriptDefinition 'if ($true){}' -Settings $_} + Invoke-ScriptAnalyzer -ScriptDefinition 'if ($true){ }' -Settings $_} $warnings.Count | Should -Be 1 $warnings.RuleName | Should -Be 'PSUseConsistentWhitespace' } diff --git a/Tests/PSScriptAnalyzerTestHelper.psm1 b/Tests/PSScriptAnalyzerTestHelper.psm1 index 499c3e29d..1601b5e17 100644 --- a/Tests/PSScriptAnalyzerTestHelper.psm1 +++ b/Tests/PSScriptAnalyzerTestHelper.psm1 @@ -39,7 +39,8 @@ Function Test-CorrectionExtentFromContent { param( [string] $rawContent, [Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic.DiagnosticRecord] $diagnosticRecord, - [int] $correctionsCount, + [ValidateRange(0, 1)] + [int] $correctionsCount, [string] $violationText, [string] $correctionText ) diff --git a/Tests/Rules/UseConsistentWhitespace.tests.ps1 b/Tests/Rules/UseConsistentWhitespace.tests.ps1 index 75f620dee..24ecbe78a 100644 --- a/Tests/Rules/UseConsistentWhitespace.tests.ps1 +++ b/Tests/Rules/UseConsistentWhitespace.tests.ps1 @@ -5,16 +5,18 @@ Import-Module (Join-Path $testRootDirectory "PSScriptAnalyzerTestHelper.psm1") $ruleName = "PSUseConsistentWhitespace" $ruleConfiguration = @{ - Enable = $true - CheckOpenBrace = $false - CheckOpenParen = $false - CheckOperator = $false - CheckSeparator = $false + Enable = $true + CheckInnerBrace = $false + CheckOpenBrace = $false + CheckOpenParen = $false + CheckOperator = $false + CheckPipe = $false + CheckSeparator = $false } $settings = @{ IncludeRules = @($ruleName) - Rules = @{ + Rules = @{ PSUseConsistentWhitespace = $ruleConfiguration } } @@ -22,38 +24,32 @@ $settings = @{ Describe "UseWhitespace" { Context "When an open brace follows a keyword" { BeforeAll { + $ruleConfiguration.CheckInnerBrace = $false $ruleConfiguration.CheckOpenBrace = $true $ruleConfiguration.CheckOpenParen = $false $ruleConfiguration.CheckOperator = $false + $ruleConfiguration.CheckPipe = $false $ruleConfiguration.CheckSeparator = $false } It "Should find a violation if an open brace does not follow whitespace" { - $def = @' -if ($true){} -'@ + $def = 'if ($true){}' $violations = Invoke-ScriptAnalyzer -ScriptDefinition $def -Settings $settings Test-CorrectionExtentFromContent $def $violations 1 '' ' ' } It "Should not find violation if an open brace follows a whitespace" { - $def = @' -if($true) {} -'@ - $violations = Invoke-ScriptAnalyzer -ScriptDefinition $def -Settings $settings | Should -Be $null + $def = 'if($true) {}' + Invoke-ScriptAnalyzer -ScriptDefinition $def -Settings $settings | Should -Be $null } It "Should not find violation if an open brace follows a foreach member invocation" { - $def = @' -(1..5).foreach{$_} -'@ + $def = '(1..5).foreach{$_}' Invoke-ScriptAnalyzer -ScriptDefinition $def -Settings $settings | Should -Be $null } It "Should not find violation if an open brace follows a where member invocation" { - $def = @' -(1..5).where{$_} -'@ + $def = '(1..5).where{$_}' Invoke-ScriptAnalyzer -ScriptDefinition $def -Settings $settings | Should -Be $null } @@ -61,16 +57,16 @@ if($true) {} Context "When a parenthesis follows a keyword" { BeforeAll { + $ruleConfiguration.CheckInnerBrace = $false $ruleConfiguration.CheckOpenBrace = $false $ruleConfiguration.CheckOpenParen = $true $ruleConfiguration.CheckOperator = $false + $ruleConfiguration.CheckPipe = $false $ruleConfiguration.CheckSeparator = $false } It "Should find violation in an if statement" { - $def = @' -if($true) {} -'@ + $def = 'if($true) {}' $violations = Invoke-ScriptAnalyzer -ScriptDefinition $def -Settings $settings Test-CorrectionExtentFromContent $def $violations 1 '' ' ' } @@ -81,7 +77,7 @@ function foo($param1) { } '@ - $violations = Invoke-ScriptAnalyzer -ScriptDefinition $def -Settings $settings | Should -Be $null + Invoke-ScriptAnalyzer -ScriptDefinition $def -Settings $settings | Should -Be $null } It "Should not find a violation in a param block" { @@ -90,7 +86,7 @@ function foo() { param( ) } '@ - $violations = Invoke-ScriptAnalyzer -ScriptDefinition $def -Settings $settings | Should -Be $null + Invoke-ScriptAnalyzer -ScriptDefinition $def -Settings $settings | Should -Be $null } It "Should not find a violation in a nested open paren" { @@ -99,53 +95,45 @@ function foo($param) { ((Get-Process)) } '@ - $violations = Invoke-ScriptAnalyzer -ScriptDefinition $def -Settings $settings | Should -Be $null + Invoke-ScriptAnalyzer -ScriptDefinition $def -Settings $settings | Should -Be $null } It "Should not find a violation on a method call" { - $def = @' -$x.foo("bar") -'@ - $violations = Invoke-ScriptAnalyzer -ScriptDefinition $def -Settings $settings | Should -Be $null + $def = '$x.foo("bar")' + Invoke-ScriptAnalyzer -ScriptDefinition $def -Settings $settings | Should -Be $null } } Context "When there is whitespace around assignment and binary operators" { BeforeAll { + $ruleConfiguration.CheckInnerBrace = $false $ruleConfiguration.CheckOpenParen = $false $ruleConfiguration.CheckOpenBrace = $false $ruleConfiguration.CheckOperator = $true + $ruleConfiguration.CheckPipe = $false $ruleConfiguration.CheckSeparator = $false } It "Should find a violation if no whitespace around an assignment operator" { - $def = @' -$x=1 -'@ + $def = '$x=1' $violations = Invoke-ScriptAnalyzer -ScriptDefinition $def -Settings $settings Test-CorrectionExtentFromContent $def $violations 1 '=' ' = ' } It "Should find a violation if no whitespace before an assignment operator" { - $def = @' -$x= 1 -'@ + $def = '$x= 1' $violations = Invoke-ScriptAnalyzer -ScriptDefinition $def -Settings $settings Test-CorrectionExtentFromContent $def $violations 1 '' ' ' } It "Should find a violation if no whitespace after an assignment operator" { - $def = @' -$x =1 -'@ + $def = '$x =1' $violations = Invoke-ScriptAnalyzer -ScriptDefinition $def -Settings $settings Test-CorrectionExtentFromContent $def $violations 1 '' ' ' } It "Should find a violation if there is a whitespaces not of size 1 around an assignment operator" { - $def = @' -$x = 1 -'@ + $def = '$x = 1' $violations = Invoke-ScriptAnalyzer -ScriptDefinition $def -Settings $settings Test-CorrectionExtentFromContent $def $violations 1 ' = ' ' = ' } @@ -156,20 +144,16 @@ $x = @" "abc" "@ '@ - $violations = Invoke-ScriptAnalyzer -ScriptDefinition $def -Settings $settings | Should -Be $null + Invoke-ScriptAnalyzer -ScriptDefinition $def -Settings $settings | Should -Be $null } It "Should not find violation if there are whitespaces of size 1 around an assignment operator for here string" { - $def = @' -$x = 1 -'@ - $violations = Invoke-ScriptAnalyzer -ScriptDefinition $def -Settings $settings | Should -Be $null + $def = '$x = 1' + Invoke-ScriptAnalyzer -ScriptDefinition $def -Settings $settings | Should -Be $null } It "Should not find violation if there are no whitespaces around DotDot operator" { - $def = @' -1..5 -'@ + $def = '1..5' Invoke-ScriptAnalyzer -ScriptDefinition $def -Settings $settings | Should -Be $null } @@ -185,49 +169,45 @@ $x = $true -and Context "When a comma is not followed by a space" { BeforeAll { + $ruleConfiguration.CheckInnerBrace = $false $ruleConfiguration.CheckOpenBrace = $false $ruleConfiguration.CheckOpenParen = $false $ruleConfiguration.CheckOperator = $false + $ruleConfiguration.CheckPipe = $false $ruleConfiguration.CheckSeparator = $true } It "Should find a violation" { - $def = @' -$x = @(1,2) -'@ + $def = '$x = @(1,2)' $violations = Invoke-ScriptAnalyzer -ScriptDefinition $def -Settings $settings Test-CorrectionExtentFromContent $def $violations 1 '' ' ' } It "Should not find a violation if a space follows a comma" { - $def = @' -$x = @(1, 2) -'@ - $violations = Invoke-ScriptAnalyzer -ScriptDefinition $def -Settings $settings | Should -Be $null + $def = '$x = @(1, 2)' + Invoke-ScriptAnalyzer -ScriptDefinition $def -Settings $settings | Should -Be $null } } Context "When a semi-colon is not followed by a space" { BeforeAll { + $ruleConfiguration.CheckInnerBrace = $false $ruleConfiguration.CheckOpenBrace = $false $ruleConfiguration.CheckOpenParen = $false $ruleConfiguration.CheckOperator = $false + $ruleConfiguration.CheckPipe = $false $ruleConfiguration.CheckSeparator = $true } It "Should find a violation" { - $def = @' -$x = @{a=1;b=2} -'@ + $def = '$x = @{a=1;b=2}' $violations = Invoke-ScriptAnalyzer -ScriptDefinition $def -Settings $settings Test-CorrectionExtentFromContent $def $violations 1 '' ' ' } It "Should not find a violation if a space follows a semi-colon" { - $def = @' -$x = @{a=1; b=2} -'@ - $violations = Invoke-ScriptAnalyzer -ScriptDefinition $def -Settings $settings | Should -Be $null + $def = '$x = @{a=1; b=2}' + Invoke-ScriptAnalyzer -ScriptDefinition $def -Settings $settings | Should -Be $null } It "Should not find a violation if a new-line follows a semi-colon" { @@ -237,16 +217,164 @@ $x = @{ b=2 } '@ - $violations = Invoke-ScriptAnalyzer -ScriptDefinition $def -Settings $settings | Should -Be $null + Invoke-ScriptAnalyzer -ScriptDefinition $def -Settings $settings | Should -Be $null } It "Should not find a violation if a end of input follows a semi-colon" { $def = @' $x = "abc"; '@ - $violations = Invoke-ScriptAnalyzer -ScriptDefinition $def -Settings $settings | Should -Be $null + Invoke-ScriptAnalyzer -ScriptDefinition $def -Settings $settings | Should -Be $null + } + } + + + Context "CheckPipe" { + BeforeAll { + $ruleConfiguration.CheckInnerBrace = $false + $ruleConfiguration.CheckOpenBrace = $false + $ruleConfiguration.CheckOpenParen = $false + $ruleConfiguration.CheckOperator = $false + $ruleConfiguration.CheckPipe = $true + $ruleConfiguration.CheckSeparator = $false + } + + It "Should find a violation if there is no space after pipe" { + $def = 'Get-Item |foo' + $violations = Invoke-ScriptAnalyzer -ScriptDefinition $def -Settings $settings + Test-CorrectionExtentFromContent $def $violations 1 '' ' ' + } + + It "Should find a violation if there is no space before pipe" { + $def = 'Get-Item| foo' + $violations = Invoke-ScriptAnalyzer -ScriptDefinition $def -Settings $settings + Test-CorrectionExtentFromContent $def $violations 1 '' ' ' + } + + It "Should find a violation if there is one space too much before pipe" { + $def = 'Get-Item | foo' + $violations = Invoke-ScriptAnalyzer -ScriptDefinition $def -Settings $settings + Test-CorrectionExtentFromContent $def $violations 1 ' ' ' ' + } + + It "Should find a violation if there is one space too much after pipe" { + $def = 'Get-Item | foo' + $violations = Invoke-ScriptAnalyzer -ScriptDefinition $def -Settings $settings + Test-CorrectionExtentFromContent $def $violations 1 ' ' ' ' + } + + It "Should not find a violation if there is 1 space before and after a pipe" { + $def = 'Get-Item | foo' + Invoke-ScriptAnalyzer -ScriptDefinition $def -Settings $settings | Should -Be $null + } + + It "Should not find a violation if a backtick is before the pipe" { + $def = @' +Get-Item ` +| foo +'@ + Invoke-ScriptAnalyzer -ScriptDefinition $def -Settings $settings | Should -Be $null } + It "Should not find a violation if a new-line is after the pipe" { + $def = @' +Get-Item | + foo +'@ + Invoke-ScriptAnalyzer -ScriptDefinition $def -Settings $settings | Should -Be $null + } + It "Should not find a violation if a backtick is after the pipe" { + $def = @' +Get-Item |` +foo +'@ + Invoke-ScriptAnalyzer -ScriptDefinition $def -Settings $settings | Should -Be $null + } } + + + Context "CheckInnerBrace" { + BeforeAll { + $ruleConfiguration.CheckInnerBrace = $true + $ruleConfiguration.CheckOpenBrace = $false + $ruleConfiguration.CheckOpenParen = $false + $ruleConfiguration.CheckOperator = $false + $ruleConfiguration.CheckPipe = $false + $ruleConfiguration.CheckSeparator = $false + } + + It "Should find a violation if there is no space after opening brace" { + $def = 'if ($true) {Get-Item }' + $violations = Invoke-ScriptAnalyzer -ScriptDefinition $def -Settings $settings + Test-CorrectionExtentFromContent $def $violations 1 '' ' ' + } + + It "Should find a violation if there is no space after opening brace when there are 2 braces" { + $def = 'if ($true) {{ Get-Item } }' + $violations = Invoke-ScriptAnalyzer -ScriptDefinition $def -Settings $settings + Test-CorrectionExtentFromContent $def $violations 1 '' ' ' + } + + It "Should find a violation if there is no space before closing brace" { + $def = 'if ($true) { Get-Item}' + $violations = Invoke-ScriptAnalyzer -ScriptDefinition $def -Settings $settings + Test-CorrectionExtentFromContent $def $violations 1 '' ' ' + } + + It "Should find a violation if there is no space before closing brace when there are 2 braces" { + $def = 'if ($true) { { Get-Item }}' + $violations = Invoke-ScriptAnalyzer -ScriptDefinition $def -Settings $settings + Test-CorrectionExtentFromContent $def $violations 1 '' ' ' + } + + It "Should find a violation if there is more than 1 space inside empty curly braces" { + $def = 'if($true) { }' + $violations = Invoke-ScriptAnalyzer -ScriptDefinition $def -Settings $settings + Test-CorrectionExtentFromContent $def $violations 1 ' ' ' ' + } + + It "Should not find a violation if there is 1 space after the opening brace and 1 before the closing brace" { + $def = 'if($true) { Get-Item }' + Invoke-ScriptAnalyzer -ScriptDefinition $def -Settings $settings | Should -Be $null + } + + It "Should not find a violation if there is 1 space inside empty curly braces" { + $def = 'if($true) { }' + Invoke-ScriptAnalyzer -ScriptDefinition $def -Settings $settings | Should -Be $null + } + + It "Should not find a violation if a new-line is after the opening brace" { + $def = @' +if ($true) { + Get-Item } +'@ + Invoke-ScriptAnalyzer -ScriptDefinition $def -Settings $settings | Should -Be $null + } + + It "Should not find a violation if a backtick is after the opening brace" { + $def = @' +if ($true) {` + Get-Item } +'@ + Invoke-ScriptAnalyzer -ScriptDefinition $def -Settings $settings | Should -Be $null + } + + It "Should not find a violation if a new-line is before the closing brace" { + $def = @' +if ($true) { Get-Item +} +'@ + Invoke-ScriptAnalyzer -ScriptDefinition $def -Settings $settings | Should -Be $null + } + + It "Should not find a violation if a backtick is before the closing brace" { + $def = @' +if ($true) { Get-Item ` +} +'@ + Invoke-ScriptAnalyzer -ScriptDefinition $def -Settings $settings | Should -Be $null + } + } + }