Skip to content

Commit abd7cb7

Browse files
author
Kapil Borle
authored
Merge pull request #595 from PowerShell/kapilmb/AddWhitelistToSingularNounRule
Add noun whitelist to singular noun rule
2 parents 2135a17 + 7a8ab5e commit abd7cb7

File tree

4 files changed

+44
-13
lines changed

4 files changed

+44
-13
lines changed

Rules/UseSingularNouns.cs

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,12 @@ namespace Microsoft.Windows.PowerShell.ScriptAnalyzer.BuiltinRules
2727
/// </summary>
2828
[Export(typeof(IScriptRule))]
2929
public class CmdletSingularNoun : IScriptRule {
30+
31+
private readonly string[] nounWhiteList =
32+
{
33+
"Data"
34+
};
35+
3036
/// <summary>
3137
/// Checks that all defined cmdlet use singular noun
3238
/// </summary>
@@ -46,23 +52,30 @@ public IEnumerable<DiagnosticRecord> AnalyzeScript(Ast ast, string fileName) {
4652
if (funcAst.Name != null && funcAst.Name.Contains('-'))
4753
{
4854
funcNamePieces = funcAst.Name.Split(funcSeperator);
49-
String noun = funcNamePieces[1];
55+
String nounPart = funcNamePieces[1];
5056

5157
// Convert the noun part of the function into a series of space delimited words
5258
// This helps the PluralizationService to provide an accurate determination about the plurality of the string
53-
noun = SplitCamelCaseString(noun);
54-
59+
nounPart = SplitCamelCaseString(nounPart);
60+
var words = nounPart.Split(new char [] { ' ' });
61+
var noun = words.LastOrDefault();
62+
if (noun == null)
63+
{
64+
continue;
65+
}
5566
var ps = System.Data.Entity.Design.PluralizationServices.PluralizationService.CreateService(CultureInfo.GetCultureInfo("en-us"));
5667

5768
if (!ps.IsSingular(noun) && ps.IsPlural(noun))
5869
{
5970
IScriptExtent extent = Helper.Instance.GetScriptExtentForFunctionName(funcAst);
60-
71+
if (nounWhiteList.Contains(noun, StringComparer.OrdinalIgnoreCase))
72+
{
73+
continue;
74+
}
6175
if (null == extent)
6276
{
6377
extent = funcAst.Extent;
6478
}
65-
6679
yield return new DiagnosticRecord(string.Format(CultureInfo.CurrentCulture, Strings.UseSingularNounsError, funcAst.Name),
6780
extent, GetName(), DiagnosticSeverity.Warning, fileName);
6881
}

Rules/UseToExportFieldsInManifest.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,9 +93,10 @@ public IEnumerable<DiagnosticRecord> AnalyzeScript(Ast ast, string fileName)
9393

9494
}
9595

96-
private string GetListLiteral<T>(Dictionary<string, T> exportedItems)
96+
private string GetListLiteral<T>(Dictionary<string, T> exportedItemsDict)
9797
{
9898
const int lineWidth = 64;
99+
var exportedItems = new SortedDictionary<string, T>(exportedItemsDict);
99100
if (exportedItems == null || exportedItems.Keys == null)
100101
{
101102
return null;

Tests/Rules/UseSingularNounsReservedVerbs.tests.ps1

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,25 @@ Describe "UseSingularNouns" {
2121
$nounViolations[0].Message | Should Match $nounViolationMessage
2222
}
2323

24-
It "has the correct extent" {
25-
$nounViolations[0].Extent.Text | Should be "Verb-Files"
26-
}
24+
It "has the correct extent" {
25+
$nounViolations[0].Extent.Text | Should be "Verb-Files"
26+
}
27+
}
28+
29+
Context "When function names have nouns from whitelist" {
30+
31+
It "ignores function name ending with Data" {
32+
$nounViolationScript = @'
33+
Function Add-SomeData
34+
{
35+
Write-Output "Adding some data"
36+
}
37+
'@
38+
Invoke-ScriptAnalyzer -ScriptDefinition $nounViolationScript `
39+
-IncludeRule "PSUseSingularNouns" `
40+
-OutVariable violations
41+
$violations.Count | Should Be 0
42+
}
2743
}
2844

2945
Context "When there are no violations" {

Tests/Rules/UseToExportFieldsInManifest.tests.ps1

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,8 @@ Describe "UseManifestExportFields" {
4343
It "suggests corrections for FunctionsToExport with wildcard" {
4444
$violations = Run-PSScriptAnalyzerRule $testManifestBadFunctionsWildcardPath
4545
$violationFilepath = Join-path $testManifestPath $testManifestBadFunctionsWildcardPath
46-
Test-CorrectionExtent $violationFilepath $violations[0] 1 "'*'" "@('Get-Foo', 'Get-Bar')"
47-
$violations[0].SuggestedCorrections[0].Description | Should Be "Replace '*' with @('Get-Foo', 'Get-Bar')"
46+
Test-CorrectionExtent $violationFilepath $violations[0] 1 "'*'" "@('Get-Bar', 'Get-Foo')"
47+
$violations[0].SuggestedCorrections[0].Description | Should Be "Replace '*' with @('Get-Bar', 'Get-Foo')"
4848
}
4949

5050
It "detects FunctionsToExport with null" {
@@ -56,7 +56,8 @@ Describe "UseManifestExportFields" {
5656
It "suggests corrections for FunctionsToExport with null and line wrapping" {
5757
$violations = Run-PSScriptAnalyzerRule $testManifestBadFunctionsNullPath
5858
$violationFilepath = Join-path $testManifestPath $testManifestBadFunctionsNullPath
59-
Test-CorrectionExtent $violationFilepath $violations[0] 1 '$null' "@('Get-Foo1', 'Get-Foo2', 'Get-Foo3', 'Get-Foo4', 'Get-Foo5', 'Get-Foo6', `r`n`t`t'Get-Foo7', 'Get-Foo8', 'Get-Foo9', 'Get-Foo10', 'Get-Foo11', `r`n`t`t'Get-Foo12')"
59+
$expectedCorrectionExtent = "@('Get-Foo1', 'Get-Foo10', 'Get-Foo11', 'Get-Foo12', 'Get-Foo2', 'Get-Foo3', {0}`t`t'Get-Foo4', 'Get-Foo5', 'Get-Foo6', 'Get-Foo7', 'Get-Foo8', {0}`t`t'Get-Foo9')" -f [System.Environment]::NewLine
60+
Test-CorrectionExtent $violationFilepath $violations[0] 1 '$null' $expectedCorrectionExtent
6061
}
6162

6263
It "detects array element containing wildcard" {
@@ -84,7 +85,7 @@ Describe "UseManifestExportFields" {
8485
It "suggests corrections for AliasesToExport with wildcard" {
8586
$violations = Run-PSScriptAnalyzerRule $testManifestBadAliasesWildcardPath
8687
$violationFilepath = Join-path $testManifestPath $testManifestBadAliasesWildcardPath
87-
Test-CorrectionExtent $violationFilepath $violations[0] 1 "'*'" "@('gfoo', 'gbar')"
88+
Test-CorrectionExtent $violationFilepath $violations[0] 1 "'*'" "@('gbar', 'gfoo')"
8889
}
8990

9091
It "detects all the *ToExport violations" {

0 commit comments

Comments
 (0)