From 9cac9702598a48666c633344b650066bdfc8a370 Mon Sep 17 00:00:00 2001 From: Hankun Yi Date: Thu, 19 Aug 2021 18:40:23 +0800 Subject: [PATCH 1/7] add AvoidMultipleTypesParameter Rule --- .../AvoidMultipleTypesParameter.md | 50 ++++++++++ RuleDocumentation/README.md | 1 + Rules/AvoidMultipleTypesParameter.cs | 98 +++++++++++++++++++ Rules/Strings.Designer.cs | 38 ++++++- Rules/Strings.resx | 14 ++- Tests/Engine/GetScriptAnalyzerRule.tests.ps1 | 2 +- Tests/Rules/AvoidMultipleTypesParameter.ps1 | 7 ++ .../AvoidMultipleTypesParameter.tests.ps1 | 25 +++++ ...voidMultipleTypesParameterNoViolations.ps1 | 3 + 9 files changed, 235 insertions(+), 3 deletions(-) create mode 100644 RuleDocumentation/AvoidMultipleTypesParameter.md create mode 100644 Rules/AvoidMultipleTypesParameter.cs create mode 100644 Tests/Rules/AvoidMultipleTypesParameter.ps1 create mode 100644 Tests/Rules/AvoidMultipleTypesParameter.tests.ps1 create mode 100644 Tests/Rules/AvoidMultipleTypesParameterNoViolations.ps1 diff --git a/RuleDocumentation/AvoidMultipleTypesParameter.md b/RuleDocumentation/AvoidMultipleTypesParameter.md new file mode 100644 index 000000000..4879a7ff3 --- /dev/null +++ b/RuleDocumentation/AvoidMultipleTypesParameter.md @@ -0,0 +1,50 @@ +# AvoidMultipleTypesParameter + +**Severity Level: Warning** + +## Description + +Parameter should not have more than one type specifier. + +## How + +Make each parameter has only 1 type spcifier. + +## Example + +### Wrong + +``` PowerShell +function Test-Script +{ + [CmdletBinding()] + Param + ( + [String] + $Param1, + + [switch] + [boolean] + $Switch=$True + ) + ... +} +``` + +### Correct + +``` PowerShell +function Test-Script +{ + [CmdletBinding()] + Param + ( + [String] + $Param1, + + [switch] + $Switch=$False + ) + ... +} +``` diff --git a/RuleDocumentation/README.md b/RuleDocumentation/README.md index 551ad55f5..db4671f4e 100644 --- a/RuleDocumentation/README.md +++ b/RuleDocumentation/README.md @@ -13,6 +13,7 @@ |[AvoidGlobalVars](./AvoidGlobalVars.md) | Warning | | |[AvoidInvokingEmptyMembers](./AvoidInvokingEmptyMembers.md) | Warning | | |[AvoidLongLines](./AvoidLongLines.md) | Warning | | +|[AvoidMultipleTypesParameter](./AvoidMultipleTypesParameter.md) | Warning | | |[AvoidOverwritingBuiltInCmdlets](./AvoidOverwritingBuiltInCmdlets.md) | Warning | | |[AvoidNullOrEmptyHelpMessageAttribute](./AvoidNullOrEmptyHelpMessageAttribute.md) | Warning | | |[AvoidShouldContinueWithoutForce](./AvoidShouldContinueWithoutForce.md) | Warning | | diff --git a/Rules/AvoidMultipleTypesParameter.cs b/Rules/AvoidMultipleTypesParameter.cs new file mode 100644 index 000000000..766436f78 --- /dev/null +++ b/Rules/AvoidMultipleTypesParameter.cs @@ -0,0 +1,98 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Management.Automation.Language; +using Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic; +#if !CORECLR +using System.ComponentModel.Composition; +#endif +using System.Globalization; + +namespace Microsoft.Windows.PowerShell.ScriptAnalyzer.BuiltinRules +{ + /// + /// AvoidMultipleTypesParameter: Check that parameter does not be assigned to multiple types. + /// +#if !CORECLR + [Export(typeof(IScriptRule))] +#endif + public sealed class AvoidMultipleTypesParameter : IScriptRule + { + /// + /// AvoidMultipleTypesParameter: Check that parameter does not be assigned to multiple types. + /// + public IEnumerable AnalyzeScript(Ast ast, string fileName) + { + if (ast == null) throw new ArgumentNullException(Strings.NullAstErrorMessage); + + // Finds all ParamAsts. + IEnumerable paramAsts = ast.FindAll(testAst => testAst is ParameterAst, true); + + // Iterates all ParamAsts and check the number of its types. + foreach (ParameterAst paramAst in paramAsts) + { + if (paramAst.Attributes.Where(typeAst => typeAst is TypeConstraintAst).Count() > 1) + { + yield return new DiagnosticRecord( + String.Format(CultureInfo.CurrentCulture, Strings.AvoidMultipleTypesParameterError, paramAst.Name), + paramAst.Name.Extent, GetName(), DiagnosticSeverity.Warning, fileName); + } + } + } + + /// + /// GetName: Retrieves the name of this rule. + /// + /// The name of this rule + public string GetName() + { + return string.Format(CultureInfo.CurrentCulture, Strings.NameSpaceFormat, GetSourceName(), Strings.AvoidMultipleTypesParameterName); + } + + /// + /// GetCommonName: Retrieves the common name of this rule. + /// + /// The common name of this rule + public string GetCommonName() + { + return string.Format(CultureInfo.CurrentCulture, Strings.AvoidMultipleTypesParameterCommonName); + } + + /// + /// GetDescription: Retrieves the description of this rule. + /// + /// The description of this rule + public string GetDescription() + { + return string.Format(CultureInfo.CurrentCulture, Strings.AvoidMultipleTypesParameterDescription); + } + + /// + /// GetSourceType: Retrieves the type of the rule, Builtin, Managed or Module. + /// + public SourceType GetSourceType() + { + return SourceType.Builtin; + } + + /// + /// GetSeverity: Retrieves the severity of the rule: error, warning or information. + /// + /// + public RuleSeverity GetSeverity() + { + return RuleSeverity.Warning; + } + + /// + /// GetSourceName: Retrieves the name of the module/assembly the rule is from. + /// + public string GetSourceName() + { + return string.Format(CultureInfo.CurrentCulture, Strings.SourceName); + } + } +} \ No newline at end of file diff --git a/Rules/Strings.Designer.cs b/Rules/Strings.Designer.cs index 70cda2d94..bd212211b 100644 --- a/Rules/Strings.Designer.cs +++ b/Rules/Strings.Designer.cs @@ -465,6 +465,42 @@ internal static string AvoidLongLinesName { } } + /// + /// Looks up a localized string similar to Avoid Multiple Types Parameter. + /// + internal static string AvoidMultipleTypesParameterCommonName { + get { + return ResourceManager.GetString("AvoidMultipleTypesParameterCommonName", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Prameter should not have more than one type specifier.. + /// + internal static string AvoidMultipleTypesParameterDescription { + get { + return ResourceManager.GetString("AvoidMultipleTypesParameterDescription", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Parameter '{0}' has more than one type specifier.. + /// + internal static string AvoidMultipleTypesParameterError { + get { + return ResourceManager.GetString("AvoidMultipleTypesParameterError", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to AvoidMultipleTypesParameter. + /// + internal static string AvoidMultipleTypesParameterName { + get { + return ResourceManager.GetString("AvoidMultipleTypesParameterName", resourceCulture); + } + } + /// /// Looks up a localized string similar to Avoid using null or empty HelpMessage parameter attribute.. /// @@ -1285,7 +1321,7 @@ internal static string DscTestsPresentNoTestsError { } /// - /// Looks up a localized string similar to When using a process block, only a begin or end block is allowed inside the function but no code.. + /// Looks up a localized string similar to When using an explicit process block, no preceding code is allowed, only begin, end and dynamicparams blocks.. /// internal static string InvalidSyntaxAroundProcessBlockError { get { diff --git a/Rules/Strings.resx b/Rules/Strings.resx index 120ead158..6ca4d84aa 100644 --- a/Rules/Strings.resx +++ b/Rules/Strings.resx @@ -1152,4 +1152,16 @@ When using an explicit process block, no preceding code is allowed, only begin, end and dynamicparams blocks. - + + Avoid Multiple Types Parameter + + + Prameter should not have more than one type specifier. + + + Parameter '{0}' has more than one type specifier. + + + AvoidMultipleTypesParameter + + \ No newline at end of file diff --git a/Tests/Engine/GetScriptAnalyzerRule.tests.ps1 b/Tests/Engine/GetScriptAnalyzerRule.tests.ps1 index e5e2159bd..50a6f0077 100644 --- a/Tests/Engine/GetScriptAnalyzerRule.tests.ps1 +++ b/Tests/Engine/GetScriptAnalyzerRule.tests.ps1 @@ -63,7 +63,7 @@ Describe "Test Name parameters" { It "get Rules with no parameters supplied" { $defaultRules = Get-ScriptAnalyzerRule - $expectedNumRules = 65 + $expectedNumRules = 66 if ($PSVersionTable.PSVersion.Major -le 4) { # for PSv3 PSAvoidGlobalAliases is not shipped because diff --git a/Tests/Rules/AvoidMultipleTypesParameter.ps1 b/Tests/Rules/AvoidMultipleTypesParameter.ps1 new file mode 100644 index 000000000..082f911c5 --- /dev/null +++ b/Tests/Rules/AvoidMultipleTypesParameter.ps1 @@ -0,0 +1,7 @@ +# Double typing is not allowed +function F10 ([int] [switch] $s1, [int] $p1){} + +# Double typing is not allowed even for switch and boolean, because: +# switch maps to System.Management.Automation.SwitchParameter +# boolean maps to System.Boolean +function F11 ([switch][boolean] $s1, [int] $p1){} \ No newline at end of file diff --git a/Tests/Rules/AvoidMultipleTypesParameter.tests.ps1 b/Tests/Rules/AvoidMultipleTypesParameter.tests.ps1 new file mode 100644 index 000000000..fc7a3c85b --- /dev/null +++ b/Tests/Rules/AvoidMultipleTypesParameter.tests.ps1 @@ -0,0 +1,25 @@ +BeforeAll { + $violationMessage = 'Parameter ''\$s1'' has more than one type specifier.' + $violationName = "PSAvoidMultipleTypesParameter" + $violations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidMultipleTypesParameter.ps1 | Where-Object {$_.RuleName -eq $violationName} + $noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidMultipleTypesParameterNoViolations.ps1 | Where-Object {$_.RuleName -eq $violationName} +} + +Describe "AvoidMultipleTypesParameter" { + Context "When there are violations" { + It "has two AvoidMultipleTypesParameter violations" { + $violations.Count | Should -Be 2 + } + + It "has the correct description message" { + $violations[0].Message | Should -Match $violationMessage + $violations[1].Message | Should -Match $violationMessage + } + } + + Context "When there are no violations" { + It "returns no violations" { + $noViolations.Count | Should -Be 0 + } + } +} \ No newline at end of file diff --git a/Tests/Rules/AvoidMultipleTypesParameterNoViolations.ps1 b/Tests/Rules/AvoidMultipleTypesParameterNoViolations.ps1 new file mode 100644 index 000000000..79636e48a --- /dev/null +++ b/Tests/Rules/AvoidMultipleTypesParameterNoViolations.ps1 @@ -0,0 +1,3 @@ +function F10 ([int] $s1, [int] $p1){} + +function F11 ([switch] $s1, [int] $p1){} \ No newline at end of file From 6f3e303cb1a04699666c0c141723847c33d7e80c Mon Sep 17 00:00:00 2001 From: hankyi95 <89194767+hankyi95@users.noreply.github.com> Date: Fri, 20 Aug 2021 16:48:08 +0800 Subject: [PATCH 2/7] resolve some comments --- Rules/AvoidMultipleTypesParameter.cs | 2 +- Rules/Strings.resx | 2 +- Tests/Rules/AvoidMultipleTypesParameter.ps1 | 7 ---- .../AvoidMultipleTypesParameter.tests.ps1 | 36 ++++++++++++++----- ...voidMultipleTypesParameterNoViolations.ps1 | 3 -- 5 files changed, 30 insertions(+), 20 deletions(-) delete mode 100644 Tests/Rules/AvoidMultipleTypesParameter.ps1 delete mode 100644 Tests/Rules/AvoidMultipleTypesParameterNoViolations.ps1 diff --git a/Rules/AvoidMultipleTypesParameter.cs b/Rules/AvoidMultipleTypesParameter.cs index 766436f78..4f0db6236 100644 --- a/Rules/AvoidMultipleTypesParameter.cs +++ b/Rules/AvoidMultipleTypesParameter.cs @@ -95,4 +95,4 @@ public string GetSourceName() return string.Format(CultureInfo.CurrentCulture, Strings.SourceName); } } -} \ No newline at end of file +} diff --git a/Rules/Strings.resx b/Rules/Strings.resx index 6ca4d84aa..73167ad48 100644 --- a/Rules/Strings.resx +++ b/Rules/Strings.resx @@ -1164,4 +1164,4 @@ AvoidMultipleTypesParameter - \ No newline at end of file + diff --git a/Tests/Rules/AvoidMultipleTypesParameter.ps1 b/Tests/Rules/AvoidMultipleTypesParameter.ps1 deleted file mode 100644 index 082f911c5..000000000 --- a/Tests/Rules/AvoidMultipleTypesParameter.ps1 +++ /dev/null @@ -1,7 +0,0 @@ -# Double typing is not allowed -function F10 ([int] [switch] $s1, [int] $p1){} - -# Double typing is not allowed even for switch and boolean, because: -# switch maps to System.Management.Automation.SwitchParameter -# boolean maps to System.Boolean -function F11 ([switch][boolean] $s1, [int] $p1){} \ No newline at end of file diff --git a/Tests/Rules/AvoidMultipleTypesParameter.tests.ps1 b/Tests/Rules/AvoidMultipleTypesParameter.tests.ps1 index fc7a3c85b..4a90d1084 100644 --- a/Tests/Rules/AvoidMultipleTypesParameter.tests.ps1 +++ b/Tests/Rules/AvoidMultipleTypesParameter.tests.ps1 @@ -1,12 +1,24 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + BeforeAll { - $violationMessage = 'Parameter ''\$s1'' has more than one type specifier.' - $violationName = "PSAvoidMultipleTypesParameter" - $violations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidMultipleTypesParameter.ps1 | Where-Object {$_.RuleName -eq $violationName} - $noViolations = Invoke-ScriptAnalyzer $PSScriptRoot\AvoidMultipleTypesParameterNoViolations.ps1 | Where-Object {$_.RuleName -eq $violationName} + $ruleName = "PSAvoidMultipleTypesParameter" + + $settings = @{ + IncludeRules = @($ruleName) + } } -Describe "AvoidMultipleTypesParameter" { - Context "When there are violations" { +Describe 'AvoidMultipleTypesParameter' { + Context 'When there are violations' { + BeforeAll { + $scriptDefinition = @' +function F10 ([int][switch] $s1, [int] $p1){} +function F11 ([switch][boolean] $s1, [int] $p1){} +'@ + $violations = Invoke-ScriptAnalyzer -ScriptDefinition $scriptDefinition -Settings $settings + $violationMessage = 'Parameter ''\$s1'' has more than one type specifier.' + } It "has two AvoidMultipleTypesParameter violations" { $violations.Count | Should -Be 2 } @@ -18,8 +30,16 @@ Describe "AvoidMultipleTypesParameter" { } Context "When there are no violations" { + BeforeAll { + $scriptDefinition = @' +function F10 ([switch] $s1, [int] $p1){} +function F11 ([boolean] $s1, [int] $p1){} +'@ + $violations = Invoke-ScriptAnalyzer -ScriptDefinition $scriptDefinition -Settings $settings + } + It "returns no violations" { - $noViolations.Count | Should -Be 0 + $violations.Count | Should -Be 0 } } -} \ No newline at end of file +} diff --git a/Tests/Rules/AvoidMultipleTypesParameterNoViolations.ps1 b/Tests/Rules/AvoidMultipleTypesParameterNoViolations.ps1 deleted file mode 100644 index 79636e48a..000000000 --- a/Tests/Rules/AvoidMultipleTypesParameterNoViolations.ps1 +++ /dev/null @@ -1,3 +0,0 @@ -function F10 ([int] $s1, [int] $p1){} - -function F11 ([switch] $s1, [int] $p1){} \ No newline at end of file From 5498863b31c4c587f36520a9e350d6761580a4b3 Mon Sep 17 00:00:00 2001 From: hankyi95 <89194767+hankyi95@users.noreply.github.com> Date: Mon, 23 Aug 2021 10:25:20 +0800 Subject: [PATCH 3/7] Update Rules/AvoidMultipleTypesParameter.cs Co-authored-by: Robert Holt --- Rules/AvoidMultipleTypesParameter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Rules/AvoidMultipleTypesParameter.cs b/Rules/AvoidMultipleTypesParameter.cs index 4f0db6236..4954850d7 100644 --- a/Rules/AvoidMultipleTypesParameter.cs +++ b/Rules/AvoidMultipleTypesParameter.cs @@ -29,7 +29,7 @@ public IEnumerable AnalyzeScript(Ast ast, string fileName) if (ast == null) throw new ArgumentNullException(Strings.NullAstErrorMessage); // Finds all ParamAsts. - IEnumerable paramAsts = ast.FindAll(testAst => testAst is ParameterAst, true); + IEnumerable paramAsts = ast.FindAll(testAst => testAst is ParameterAst, searchNestedScriptBlocks: true); // Iterates all ParamAsts and check the number of its types. foreach (ParameterAst paramAst in paramAsts) From 00b03cc4da3b430e1dfa3441e27b260b6e2318bc Mon Sep 17 00:00:00 2001 From: hankyi95 <89194767+hankyi95@users.noreply.github.com> Date: Wed, 25 Aug 2021 15:56:34 +0800 Subject: [PATCH 4/7] add more test case --- .../AvoidMultipleTypesParameter.md | 8 +- Rules/AvoidMultipleTypesParameter.cs | 10 ++- Rules/Strings.resx | 2 +- .../AvoidMultipleTypesParameter.tests.ps1 | 75 ++++++++++++------- 4 files changed, 63 insertions(+), 32 deletions(-) diff --git a/RuleDocumentation/AvoidMultipleTypesParameter.md b/RuleDocumentation/AvoidMultipleTypesParameter.md index 4879a7ff3..0cdc85802 100644 --- a/RuleDocumentation/AvoidMultipleTypesParameter.md +++ b/RuleDocumentation/AvoidMultipleTypesParameter.md @@ -4,11 +4,11 @@ ## Description -Parameter should not have more than one type specifier. +Parameters should not have more than one type specifier. Multiple type specifiers on parameters will cause a runtime error. ## How -Make each parameter has only 1 type spcifier. +Ensure each parameter has only 1 type spcifier. ## Example @@ -25,7 +25,7 @@ function Test-Script [switch] [boolean] - $Switch=$True + $Switch ) ... } @@ -43,7 +43,7 @@ function Test-Script $Param1, [switch] - $Switch=$False + $Switch ) ... } diff --git a/Rules/AvoidMultipleTypesParameter.cs b/Rules/AvoidMultipleTypesParameter.cs index 4f0db6236..e5a720554 100644 --- a/Rules/AvoidMultipleTypesParameter.cs +++ b/Rules/AvoidMultipleTypesParameter.cs @@ -26,7 +26,10 @@ public sealed class AvoidMultipleTypesParameter : IScriptRule /// public IEnumerable AnalyzeScript(Ast ast, string fileName) { - if (ast == null) throw new ArgumentNullException(Strings.NullAstErrorMessage); + if (ast == null) + { + throw new ArgumentNullException(Strings.NullAstErrorMessage); + } // Finds all ParamAsts. IEnumerable paramAsts = ast.FindAll(testAst => testAst is ParameterAst, true); @@ -38,7 +41,10 @@ public IEnumerable AnalyzeScript(Ast ast, string fileName) { yield return new DiagnosticRecord( String.Format(CultureInfo.CurrentCulture, Strings.AvoidMultipleTypesParameterError, paramAst.Name), - paramAst.Name.Extent, GetName(), DiagnosticSeverity.Warning, fileName); + paramAst.Name.Extent, + GetName(), + DiagnosticSeverity.Warning, + fileName); } } } diff --git a/Rules/Strings.resx b/Rules/Strings.resx index 73167ad48..5cb403af1 100644 --- a/Rules/Strings.resx +++ b/Rules/Strings.resx @@ -1153,7 +1153,7 @@ When using an explicit process block, no preceding code is allowed, only begin, end and dynamicparams blocks. - Avoid Multiple Types Parameter + Avoid multiple type specifiers on parameters Prameter should not have more than one type specifier. diff --git a/Tests/Rules/AvoidMultipleTypesParameter.tests.ps1 b/Tests/Rules/AvoidMultipleTypesParameter.tests.ps1 index 4a90d1084..f0409145d 100644 --- a/Tests/Rules/AvoidMultipleTypesParameter.tests.ps1 +++ b/Tests/Rules/AvoidMultipleTypesParameter.tests.ps1 @@ -10,36 +10,61 @@ BeforeAll { } Describe 'AvoidMultipleTypesParameter' { - Context 'When there are violations' { - BeforeAll { - $scriptDefinition = @' -function F10 ([int][switch] $s1, [int] $p1){} -function F11 ([switch][boolean] $s1, [int] $p1){} + it 'Should find 3 violations for paramters have more than one type spceifiers' { + $def = @' +function F1 ($s1, $p1){} +function F2 ([int] $s2, [int] $p2){} +function F3 ([int][switch] $s3, [int] $p3){} +function F4 ([int][ref] $s4, [int] $p4){} +function F5 ([int][switch][boolean] $s5, [int] $p5){} '@ - $violations = Invoke-ScriptAnalyzer -ScriptDefinition $scriptDefinition -Settings $settings - $violationMessage = 'Parameter ''\$s1'' has more than one type specifier.' - } - It "has two AvoidMultipleTypesParameter violations" { - $violations.Count | Should -Be 2 - } + Invoke-ScriptAnalyzer -ScriptDefinition $def -Settings $settings + $violations = Invoke-ScriptAnalyzer -ScriptDefinition $def -Settings $settings + $violations.Count | Should -Be 3 + } - It "has the correct description message" { - $violations[0].Message | Should -Match $violationMessage - $violations[1].Message | Should -Match $violationMessage - } + it 'Should get the correct extent of the violation ' { + $def = @' +function F1 ($s1, $p1){} +function F2 ([int] $s2, [int] $p2){} +function F3 ([int][switch] $s3, [int] $p3){} +function F4 ([int][ref] $s4, [int] $p4){} +function F5 ([int][switch][boolean] $s5, [int] $p5){} +'@ + Invoke-ScriptAnalyzer -ScriptDefinition $def -Settings $settings + $violations = Invoke-ScriptAnalyzer -ScriptDefinition $def -Settings $settings + $violations[0].Extent.StartLineNumber | Should -Be 3 + $violations[0].Extent.EndLineNumber | Should -Be 3 + $violations[1].Extent.StartLineNumber | Should -Be 4 + $violations[1].Extent.EndLineNumber | Should -Be 4 + $violations[2].Extent.StartLineNumber | Should -Be 5 + $violations[2].Extent.EndLineNumber | Should -Be 5 } - Context "When there are no violations" { - BeforeAll { - $scriptDefinition = @' -function F10 ([switch] $s1, [int] $p1){} -function F11 ([boolean] $s1, [int] $p1){} + it 'Should get the correct error messaage of the violation ' { + $def = @' +function F1 ($s1, $p1){} +function F2 ([int] $s2, [int] $p2){} +function F3 ([int][switch] $s3, [int] $p3){} +function F4 ([int][ref] $s4, [int] $p4){} +function F5 ([int][switch][boolean] $s5, [int] $p5){} '@ - $violations = Invoke-ScriptAnalyzer -ScriptDefinition $scriptDefinition -Settings $settings - } + Invoke-ScriptAnalyzer -ScriptDefinition $def -Settings $settings + $violations = Invoke-ScriptAnalyzer -ScriptDefinition $def -Settings $settings + $violations[0].Message | Should -Match 'Parameter ''\$s3'' has more than one type specifier.' + $violations[1].Message | Should -Match 'Parameter ''\$s4'' has more than one type specifier.' + $violations[2].Message | Should -Match 'Parameter ''\$s5'' has more than one type specifier.' + } - It "returns no violations" { - $violations.Count | Should -Be 0 - } + it 'Should not have violations for paramters have one or less type spceifier' { + $def = @' +function F1 ($s1, $p1){} +function F2 ([int] $s2, [int] $p2){} +function F3 ([ValidateSet()][int] $s3, [int] $p3){} +function F4 ([Parameter(Mandatory=$true)][ValidateSet()][int] $s4, [int] $p4){} +'@ + Invoke-ScriptAnalyzer -ScriptDefinition $def -Settings $settings + $violations = Invoke-ScriptAnalyzer -ScriptDefinition $def -Settings $settings + $violations.Count | Should -Be 0 } } From 2c5c3e8fa61a17c6fd0d61924bbfa8f06472d5fb Mon Sep 17 00:00:00 2001 From: hankyi95 <89194767+hankyi95@users.noreply.github.com> Date: Thu, 26 Aug 2021 14:37:49 +0800 Subject: [PATCH 5/7] refactor test case --- Rules/AvoidMultipleTypesParameter.cs | 2 +- .../AvoidMultipleTypesParameter.tests.ps1 | 78 ++++++------------- 2 files changed, 26 insertions(+), 54 deletions(-) diff --git a/Rules/AvoidMultipleTypesParameter.cs b/Rules/AvoidMultipleTypesParameter.cs index 91a5b3a79..64f536635 100644 --- a/Rules/AvoidMultipleTypesParameter.cs +++ b/Rules/AvoidMultipleTypesParameter.cs @@ -26,7 +26,7 @@ public sealed class AvoidMultipleTypesParameter : IScriptRule /// public IEnumerable AnalyzeScript(Ast ast, string fileName) { - if (ast == null) + if (ast is null) { throw new ArgumentNullException(Strings.NullAstErrorMessage); } diff --git a/Tests/Rules/AvoidMultipleTypesParameter.tests.ps1 b/Tests/Rules/AvoidMultipleTypesParameter.tests.ps1 index f0409145d..fd3016fb4 100644 --- a/Tests/Rules/AvoidMultipleTypesParameter.tests.ps1 +++ b/Tests/Rules/AvoidMultipleTypesParameter.tests.ps1 @@ -10,61 +10,33 @@ BeforeAll { } Describe 'AvoidMultipleTypesParameter' { - it 'Should find 3 violations for paramters have more than one type spceifiers' { - $def = @' -function F1 ($s1, $p1){} -function F2 ([int] $s2, [int] $p2){} -function F3 ([int][switch] $s3, [int] $p3){} -function F4 ([int][ref] $s4, [int] $p4){} -function F5 ([int][switch][boolean] $s5, [int] $p5){} -'@ - Invoke-ScriptAnalyzer -ScriptDefinition $def -Settings $settings - $violations = Invoke-ScriptAnalyzer -ScriptDefinition $def -Settings $settings - $violations.Count | Should -Be 3 - } + It 'Correctly diagnoses and corrects