diff --git a/Rules/AvoidUninitializedVariable.cs b/DeprecatedRules/AvoidUninitializedVariable.cs similarity index 100% rename from Rules/AvoidUninitializedVariable.cs rename to DeprecatedRules/AvoidUninitializedVariable.cs diff --git a/Engine/Helper.cs b/Engine/Helper.cs index 89a33b354..3a09d2c56 100644 --- a/Engine/Helper.cs +++ b/Engine/Helper.cs @@ -224,6 +224,17 @@ public bool IsDscResourceModule(string filePath) return false; } + /// + /// Given a filePath. Returns true if it is a powershell help file + /// + /// + /// + public bool IsHelpFile(string filePath) + { + return filePath != null && File.Exists(filePath) && Path.GetFileName(filePath).StartsWith("about_", StringComparison.OrdinalIgnoreCase) + && Path.GetFileName(filePath).EndsWith(".help.txt", StringComparison.OrdinalIgnoreCase); + } + /// /// Given an AST, checks whether dsc resource is class based or not /// diff --git a/Engine/ScriptAnalyzer.cs b/Engine/ScriptAnalyzer.cs index 55b11ebb1..e3cdf8cc7 100644 --- a/Engine/ScriptAnalyzer.cs +++ b/Engine/ScriptAnalyzer.cs @@ -908,9 +908,9 @@ private void BuildScriptPathList( bool searchRecursively, IList scriptFilePaths) { - const string ps1Suffix = "ps1"; - const string psm1Suffix = "psm1"; - const string psd1Suffix = "psd1"; + const string ps1Suffix = ".ps1"; + const string psm1Suffix = ".psm1"; + const string psd1Suffix = ".psd1"; if (Directory.Exists(path)) { @@ -935,9 +935,14 @@ private void BuildScriptPathList( } else if (File.Exists(path)) { - if ((path.Length > ps1Suffix.Length && path.Substring(path.Length - ps1Suffix.Length).Equals(ps1Suffix, StringComparison.OrdinalIgnoreCase)) || - (path.Length > psm1Suffix.Length && path.Substring(path.Length - psm1Suffix.Length).Equals(psm1Suffix, StringComparison.OrdinalIgnoreCase)) || - (path.Length > psd1Suffix.Length && path.Substring(path.Length - psd1Suffix.Length).Equals(psd1Suffix, StringComparison.OrdinalIgnoreCase))) + String fileName = Path.GetFileName(path); + if ((fileName.Length > ps1Suffix.Length && String.Equals(Path.GetExtension(path), ps1Suffix, StringComparison.OrdinalIgnoreCase)) || + (fileName.Length > psm1Suffix.Length && String.Equals(Path.GetExtension(path), psm1Suffix, StringComparison.OrdinalIgnoreCase)) || + (fileName.Length > psd1Suffix.Length && String.Equals(Path.GetExtension(path), psd1Suffix, StringComparison.OrdinalIgnoreCase))) + { + scriptFilePaths.Add(path); + } + else if (Helper.Instance.IsHelpFile(path)) { scriptFilePaths.Add(path); } @@ -964,7 +969,28 @@ private IEnumerable AnalyzeFile(string filePath) //Parse the file if (File.Exists(filePath)) { - scriptAst = Parser.ParseFile(filePath, out scriptTokens, out errors); + // processing for non help script + if (!(Path.GetFileName(filePath).StartsWith("about_") && Path.GetFileName(filePath).EndsWith(".help.txt"))) + { + scriptAst = Parser.ParseFile(filePath, out scriptTokens, out errors); + + if (errors != null && errors.Length > 0) + { + foreach (ParseError error in errors) + { + string parseErrorMessage = String.Format(CultureInfo.CurrentCulture, Strings.ParserErrorFormat, error.Extent.File, error.Message.TrimEnd('.'), error.Extent.StartLineNumber, error.Extent.StartColumnNumber); + this.outputWriter.WriteError(new ErrorRecord(new ParseException(parseErrorMessage), parseErrorMessage, ErrorCategory.ParserError, error.ErrorId)); + } + } + + if (errors.Length > 10) + { + string manyParseErrorMessage = String.Format(CultureInfo.CurrentCulture, Strings.ParserErrorMessage, System.IO.Path.GetFileName(filePath)); + this.outputWriter.WriteError(new ErrorRecord(new ParseException(manyParseErrorMessage), manyParseErrorMessage, ErrorCategory.ParserError, filePath)); + + return new List(); + } + } } else { @@ -975,23 +1001,6 @@ private IEnumerable AnalyzeFile(string filePath) return null; } - if (errors != null && errors.Length > 0) - { - foreach (ParseError error in errors) - { - string parseErrorMessage = String.Format(CultureInfo.CurrentCulture, Strings.ParserErrorFormat, error.Extent.File, error.Message.TrimEnd('.'), error.Extent.StartLineNumber, error.Extent.StartColumnNumber); - this.outputWriter.WriteError(new ErrorRecord(new ParseException(parseErrorMessage), parseErrorMessage, ErrorCategory.ParserError, error.ErrorId)); - } - } - - if (errors.Length > 10) - { - string manyParseErrorMessage = String.Format(CultureInfo.CurrentCulture, Strings.ParserErrorMessage, System.IO.Path.GetFileName(filePath)); - this.outputWriter.WriteError(new ErrorRecord(new ParseException(manyParseErrorMessage), manyParseErrorMessage, ErrorCategory.ParserError, filePath)); - - return new List(); - } - return this.AnalyzeSyntaxTree(scriptAst, scriptTokens, filePath); } @@ -1007,7 +1016,7 @@ public IEnumerable AnalyzeSyntaxTree( Token[] scriptTokens, string filePath) { - Dictionary> ruleSuppressions; + Dictionary> ruleSuppressions = new Dictionary>(); ConcurrentBag diagnostics = new ConcurrentBag(); ConcurrentBag suppressed = new ConcurrentBag(); BlockingCollection> verboseOrErrors = new BlockingCollection>(); @@ -1015,28 +1024,33 @@ public IEnumerable AnalyzeSyntaxTree( // Use a List of KVP rather than dictionary, since for a script containing inline functions with same signature, keys clash List> cmdInfoTable = new List>(); - ruleSuppressions = Helper.Instance.GetRuleSuppression(scriptAst); + bool helpFile = (scriptAst == null) && Helper.Instance.IsHelpFile(filePath); - foreach (List ruleSuppressionsList in ruleSuppressions.Values) + if (!helpFile) { - foreach (RuleSuppression ruleSuppression in ruleSuppressionsList) + ruleSuppressions = Helper.Instance.GetRuleSuppression(scriptAst); + + foreach (List ruleSuppressionsList in ruleSuppressions.Values) { - if (!String.IsNullOrWhiteSpace(ruleSuppression.Error)) + foreach (RuleSuppression ruleSuppression in ruleSuppressionsList) { - this.outputWriter.WriteError(new ErrorRecord(new ArgumentException(ruleSuppression.Error), ruleSuppression.Error, ErrorCategory.InvalidArgument, ruleSuppression)); + if (!String.IsNullOrWhiteSpace(ruleSuppression.Error)) + { + this.outputWriter.WriteError(new ErrorRecord(new ArgumentException(ruleSuppression.Error), ruleSuppression.Error, ErrorCategory.InvalidArgument, ruleSuppression)); + } } } - } - #region Run VariableAnalysis - try - { - Helper.Instance.InitializeVariableAnalysis(scriptAst); - } - catch { } - #endregion + #region Run VariableAnalysis + try + { + Helper.Instance.InitializeVariableAnalysis(scriptAst); + } + catch { } + #endregion - Helper.Instance.Tokens = scriptTokens; + Helper.Instance.Tokens = scriptTokens; + } #region Run ScriptRules //Trim down to the leaf element of the filePath and pass it to Diagnostic Record @@ -1067,6 +1081,8 @@ public IEnumerable AnalyzeSyntaxTree( } } + bool helpRule = String.Equals(scriptRule.GetName(), "PSUseUTF8EncodingForHelpFile", StringComparison.OrdinalIgnoreCase); + if ((includeRule == null || includeRegexMatch) && (excludeRule == null || !excludeRegexMatch)) { List result = new List(); @@ -1077,14 +1093,25 @@ public IEnumerable AnalyzeSyntaxTree( // We want the Engine to continue functioning even if one or more Rules throws an exception try { - var records = Helper.Instance.SuppressRule(scriptRule.GetName(), ruleSuppressions, scriptRule.AnalyzeScript(scriptAst, scriptAst.Extent.File).ToList()); - foreach (var record in records.Item2) + if (helpRule && helpFile) { - diagnostics.Add(record); + var records = scriptRule.AnalyzeScript(scriptAst, filePath); + foreach (var record in records) + { + diagnostics.Add(record); + } } - foreach (var suppressedRec in records.Item1) + else if (!helpRule && !helpFile) { - suppressed.Add(suppressedRec); + var records = Helper.Instance.SuppressRule(scriptRule.GetName(), ruleSuppressions, scriptRule.AnalyzeScript(scriptAst, scriptAst.Extent.File).ToList()); + foreach (var record in records.Item2) + { + diagnostics.Add(record); + } + foreach (var suppressedRec in records.Item1) + { + suppressed.Add(suppressedRec); + } } } catch (Exception scriptRuleException) @@ -1122,7 +1149,7 @@ public IEnumerable AnalyzeSyntaxTree( #region Run Token Rules - if (this.TokenRules != null) + if (this.TokenRules != null && !helpFile) { foreach (ITokenRule tokenRule in this.TokenRules) { @@ -1173,7 +1200,7 @@ public IEnumerable AnalyzeSyntaxTree( #endregion #region DSC Resource Rules - if (this.DSCResourceRules != null) + if (this.DSCResourceRules != null && !helpFile) { // Invoke AnalyzeDSCClass only if the ast is a class based resource if (Helper.Instance.IsDscResourceClassBased(scriptAst)) @@ -1282,7 +1309,7 @@ public IEnumerable AnalyzeSyntaxTree( #region Run External Rules - if (this.ExternalRules != null) + if (this.ExternalRules != null && !helpFile) { List exRules = new List(); diff --git a/Rules/ScriptAnalyzerBuiltinRules.csproj b/Rules/ScriptAnalyzerBuiltinRules.csproj index 32697b07f..b6f246cee 100644 --- a/Rules/ScriptAnalyzerBuiltinRules.csproj +++ b/Rules/ScriptAnalyzerBuiltinRules.csproj @@ -60,7 +60,6 @@ - @@ -91,6 +90,7 @@ + diff --git a/Rules/Strings.Designer.cs b/Rules/Strings.Designer.cs index 40e597258..fcbacb9c2 100644 --- a/Rules/Strings.Designer.cs +++ b/Rules/Strings.Designer.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // // This code was generated by a tool. -// Runtime Version:4.0.30319.42000 +// Runtime Version:4.0.30319.34014 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. @@ -1869,6 +1869,42 @@ internal static string UseTypeAtVariableAssignmentName { } } + /// + /// Looks up a localized string similar to Use UTF8 Encoding For Help File. + /// + internal static string UseUTF8EncodingForHelpFileCommonName { + get { + return ResourceManager.GetString("UseUTF8EncodingForHelpFileCommonName", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to PowerShell help file needs to use UTF8 Encoding.. + /// + internal static string UseUTF8EncodingForHelpFileDescription { + get { + return ResourceManager.GetString("UseUTF8EncodingForHelpFileDescription", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to File {0} has to use UTF8 instead of {1} encoding because it is a powershell help file.. + /// + internal static string UseUTF8EncodingForHelpFileError { + get { + return ResourceManager.GetString("UseUTF8EncodingForHelpFileError", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to UseUTF8EncodingForHelpFile. + /// + internal static string UseUTF8EncodingForHelpFileName { + get { + return ResourceManager.GetString("UseUTF8EncodingForHelpFileName", resourceCulture); + } + } + /// /// Looks up a localized string similar to Use verbose message in DSC resource. /// diff --git a/Rules/Strings.resx b/Rules/Strings.resx index fe00a5328..c9ea57bdf 100644 --- a/Rules/Strings.resx +++ b/Rules/Strings.resx @@ -732,4 +732,16 @@ AvoidUsingDeprecatedManifestFields + + Use UTF8 Encoding For Help File + + + PowerShell help file needs to use UTF8 Encoding. + + + File {0} has to use UTF8 instead of {1} encoding because it is a powershell help file. + + + UseUTF8EncodingForHelpFile + \ No newline at end of file diff --git a/Rules/UseUTF8EncodingForHelpFile.cs b/Rules/UseUTF8EncodingForHelpFile.cs new file mode 100644 index 000000000..7f301abc8 --- /dev/null +++ b/Rules/UseUTF8EncodingForHelpFile.cs @@ -0,0 +1,99 @@ +// +// Copyright (c) Microsoft Corporation. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +using System; +using System.Collections.Generic; +using System.Management.Automation.Language; +using Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic; +using System.ComponentModel.Composition; +using System.Globalization; + +namespace Microsoft.Windows.PowerShell.ScriptAnalyzer.BuiltinRules +{ + /// + /// AvoidAlias: Check if help file uses utf8 encoding + /// + [Export(typeof(IScriptRule))] + public class UseUTF8EncodingForHelpFile : IScriptRule + { + /// + /// AnalyzeScript: check if the help file uses something other than utf8 + /// + public IEnumerable AnalyzeScript(Ast ast, string fileName) + { + if (!String.IsNullOrWhiteSpace(fileName) && Helper.Instance.IsHelpFile(fileName)) + { + using (var reader = new System.IO.StreamReader(fileName, true)) + { + reader.ReadToEnd(); + if (reader.CurrentEncoding != System.Text.Encoding.UTF8) + { + yield return new DiagnosticRecord(string.Format(CultureInfo.CurrentCulture, Strings.UseUTF8EncodingForHelpFileError, System.IO.Path.GetFileName(fileName), reader.CurrentEncoding), + null, 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.UseUTF8EncodingForHelpFileName); + } + + /// + /// GetCommonName: Retrieves the common name of this rule. + /// + /// The common name of this rule + public string GetCommonName() + { + return string.Format(CultureInfo.CurrentCulture, Strings.UseUTF8EncodingForHelpFileCommonName); + } + + /// + /// GetDescription: Retrieves the description of this rule. + /// + /// The description of this rule + public string GetDescription() + { + return string.Format(CultureInfo.CurrentCulture, Strings.UseUTF8EncodingForHelpFileDescription); + } + + /// + /// 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 of 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); + } + } +} diff --git a/Tests/Disabled Rules/AvoidOneChar.tests.ps1 b/Tests/DisabledRules/AvoidOneChar.tests.ps1 similarity index 100% rename from Tests/Disabled Rules/AvoidOneChar.tests.ps1 rename to Tests/DisabledRules/AvoidOneChar.tests.ps1 diff --git a/Tests/Disabled Rules/AvoidTrapStatements.ps1 b/Tests/DisabledRules/AvoidTrapStatements.ps1 similarity index 100% rename from Tests/Disabled Rules/AvoidTrapStatements.ps1 rename to Tests/DisabledRules/AvoidTrapStatements.ps1 diff --git a/Tests/Disabled Rules/AvoidTrapStatements.tests.ps1 b/Tests/DisabledRules/AvoidTrapStatements.tests.ps1 similarity index 100% rename from Tests/Disabled Rules/AvoidTrapStatements.tests.ps1 rename to Tests/DisabledRules/AvoidTrapStatements.tests.ps1 diff --git a/Tests/Disabled Rules/AvoidUnloadableModule.tests.ps1 b/Tests/DisabledRules/AvoidUnloadableModule.tests.ps1 similarity index 100% rename from Tests/Disabled Rules/AvoidUnloadableModule.tests.ps1 rename to Tests/DisabledRules/AvoidUnloadableModule.tests.ps1 diff --git a/Tests/Disabled Rules/AvoidUsingClearHost.ps1 b/Tests/DisabledRules/AvoidUsingClearHost.ps1 similarity index 100% rename from Tests/Disabled Rules/AvoidUsingClearHost.ps1 rename to Tests/DisabledRules/AvoidUsingClearHost.ps1 diff --git a/Tests/Disabled Rules/AvoidUsingClearHost.tests.ps1 b/Tests/DisabledRules/AvoidUsingClearHost.tests.ps1 similarity index 100% rename from Tests/Disabled Rules/AvoidUsingClearHost.tests.ps1 rename to Tests/DisabledRules/AvoidUsingClearHost.tests.ps1 diff --git a/Tests/Disabled Rules/AvoidUsingClearHostNoViolations.ps1 b/Tests/DisabledRules/AvoidUsingClearHostNoViolations.ps1 similarity index 100% rename from Tests/Disabled Rules/AvoidUsingClearHostNoViolations.ps1 rename to Tests/DisabledRules/AvoidUsingClearHostNoViolations.ps1 diff --git a/Tests/Disabled Rules/AvoidUsingFilePath.ps1 b/Tests/DisabledRules/AvoidUsingFilePath.ps1 similarity index 100% rename from Tests/Disabled Rules/AvoidUsingFilePath.ps1 rename to Tests/DisabledRules/AvoidUsingFilePath.ps1 diff --git a/Tests/Disabled Rules/AvoidUsingFilePath.tests.ps1 b/Tests/DisabledRules/AvoidUsingFilePath.tests.ps1 similarity index 100% rename from Tests/Disabled Rules/AvoidUsingFilePath.tests.ps1 rename to Tests/DisabledRules/AvoidUsingFilePath.tests.ps1 diff --git a/Tests/Disabled Rules/AvoidUsingFilePathNoViolations.ps1 b/Tests/DisabledRules/AvoidUsingFilePathNoViolations.ps1 similarity index 100% rename from Tests/Disabled Rules/AvoidUsingFilePathNoViolations.ps1 rename to Tests/DisabledRules/AvoidUsingFilePathNoViolations.ps1 diff --git a/Tests/Rules/AvoidUsingUninitializedVariable.Tests.ps1 b/Tests/DisabledRules/AvoidUsingUninitializedVariable.Tests.ps1 similarity index 100% rename from Tests/Rules/AvoidUsingUninitializedVariable.Tests.ps1 rename to Tests/DisabledRules/AvoidUsingUninitializedVariable.Tests.ps1 diff --git a/Tests/Rules/AvoidUsingUninitializedVariable.ps1 b/Tests/DisabledRules/AvoidUsingUninitializedVariable.ps1 similarity index 100% rename from Tests/Rules/AvoidUsingUninitializedVariable.ps1 rename to Tests/DisabledRules/AvoidUsingUninitializedVariable.ps1 diff --git a/Tests/Rules/AvoidUsingUninitializedVariableNoViolations.ps1 b/Tests/DisabledRules/AvoidUsingUninitializedVariableNoViolations.ps1 similarity index 100% rename from Tests/Rules/AvoidUsingUninitializedVariableNoViolations.ps1 rename to Tests/DisabledRules/AvoidUsingUninitializedVariableNoViolations.ps1 diff --git a/Tests/Disabled Rules/CommandNotFound.ps1 b/Tests/DisabledRules/CommandNotFound.ps1 similarity index 100% rename from Tests/Disabled Rules/CommandNotFound.ps1 rename to Tests/DisabledRules/CommandNotFound.ps1 diff --git a/Tests/Disabled Rules/CommandNotFound.tests.ps1 b/Tests/DisabledRules/CommandNotFound.tests.ps1 similarity index 100% rename from Tests/Disabled Rules/CommandNotFound.tests.ps1 rename to Tests/DisabledRules/CommandNotFound.tests.ps1 diff --git a/Tests/Disabled Rules/ProvideVerboseMessage.tests.ps1 b/Tests/DisabledRules/ProvideVerboseMessage.tests.ps1 similarity index 100% rename from Tests/Disabled Rules/ProvideVerboseMessage.tests.ps1 rename to Tests/DisabledRules/ProvideVerboseMessage.tests.ps1 diff --git a/Tests/Disabled Rules/TypeNotFound.ps1 b/Tests/DisabledRules/TypeNotFound.ps1 similarity index 100% rename from Tests/Disabled Rules/TypeNotFound.ps1 rename to Tests/DisabledRules/TypeNotFound.ps1 diff --git a/Tests/Disabled Rules/TypeNotFound.tests.ps1 b/Tests/DisabledRules/TypeNotFound.tests.ps1 similarity index 100% rename from Tests/Disabled Rules/TypeNotFound.tests.ps1 rename to Tests/DisabledRules/TypeNotFound.tests.ps1 diff --git a/Tests/Disabled Rules/UseTypeAtVariableAssignment.ps1 b/Tests/DisabledRules/UseTypeAtVariableAssignment.ps1 similarity index 100% rename from Tests/Disabled Rules/UseTypeAtVariableAssignment.ps1 rename to Tests/DisabledRules/UseTypeAtVariableAssignment.ps1 diff --git a/Tests/Disabled Rules/UseTypeAtVariableAssignment.tests.ps1 b/Tests/DisabledRules/UseTypeAtVariableAssignment.tests.ps1 similarity index 100% rename from Tests/Disabled Rules/UseTypeAtVariableAssignment.tests.ps1 rename to Tests/DisabledRules/UseTypeAtVariableAssignment.tests.ps1 diff --git a/Tests/Rules/AvoidGlobalOrUnitializedVars.tests.ps1 b/Tests/Rules/AvoidGlobalOrUnitializedVars.tests.ps1 index 47a709f27..e50a7d5d8 100644 --- a/Tests/Rules/AvoidGlobalOrUnitializedVars.tests.ps1 +++ b/Tests/Rules/AvoidGlobalOrUnitializedVars.tests.ps1 @@ -1,26 +1,41 @@ Import-Module PSScriptAnalyzer $globalMessage = "Found global variable 'Global:1'." $globalName = "PSAvoidGlobalVars" -$nonInitializedName = "PSAvoidUninitializedVariable" + +# PSAvoidUninitializedVariable rule has been deprecated +# $nonInitializedName = "PSAvoidUninitializedVariable" + $nonInitializedMessage = "Variable 'globalVars' is not initialized. Non-global variables must be initialized. To fix a violation of this rule, please initialize non-global variables." $directory = Split-Path -Parent $MyInvocation.MyCommand.Path $violations = Invoke-ScriptAnalyzer $directory\AvoidGlobalOrUnitializedVars.ps1 -$dscResourceViolations = Invoke-ScriptAnalyzer $directory\DSCResources\MSFT_WaitForAny\MSFT_WaitForAny.psm1 | Where-Object {$_.RuleName -eq $nonInitializedName} + +# PSAvoidUninitializedVariable rule has been deprecated +# $dscResourceViolations = Invoke-ScriptAnalyzer $directory\DSCResources\MSFT_WaitForAny\MSFT_WaitForAny.psm1 | Where-Object {$_.RuleName -eq $nonInitializedName} + $globalViolations = $violations | Where-Object {$_.RuleName -eq $globalName} -$nonInitializedViolations = $violations | Where-Object {$_.RuleName -eq $nonInitializedName} + +# PSAvoidUninitializedVariable rule has been deprecated +# $nonInitializedViolations = $violations | Where-Object {$_.RuleName -eq $nonInitializedName} + $noViolations = Invoke-ScriptAnalyzer $directory\AvoidGlobalOrUnitializedVarsNoViolations.ps1 $noGlobalViolations = $noViolations | Where-Object {$_.RuleName -eq $globalName} -$noUninitializedViolations = $noViolations | Where-Object {$_.RuleName -eq $nonInitializedName} + +# PSAvoidUninitializedVariable rule has been deprecated +# $noUninitializedViolations = $noViolations | Where-Object {$_.RuleName -eq $nonInitializedName} Describe "AvoidGlobalVars" { Context "When there are violations" { It "has 1 avoid using global variable violation" { $globalViolations.Count | Should Be 1 } - + + <# + # PSAvoidUninitializedVariable rule has been deprecated It "has 4 violations for dsc resources (not counting the variables in parameters)" { $dscResourceViolations.Count | Should Be 4 } + #> + It "has the correct description message" { $globalViolations[0].Message | Should Match $globalMessage @@ -34,6 +49,8 @@ Describe "AvoidGlobalVars" { } } +<# +# PSAvoidUninitializedVariable rule has been deprecated - Hence not a valid test case Describe "AvoidUnitializedVars" { Context "When there are violations" { It "has 5 avoid using unitialized variable violations" { @@ -49,5 +66,6 @@ Describe "AvoidUnitializedVars" { It "returns no violations" { $noUninitializedViolations.Count | Should Be 0 } - } -} \ No newline at end of file + } +} +#> \ No newline at end of file diff --git a/Tests/Rules/UseUTF8EncodingForHelpFile.tests.ps1 b/Tests/Rules/UseUTF8EncodingForHelpFile.tests.ps1 new file mode 100644 index 000000000..d42d57f3b --- /dev/null +++ b/Tests/Rules/UseUTF8EncodingForHelpFile.tests.ps1 @@ -0,0 +1,30 @@ +Import-Module PSScriptAnalyzer +$violationMessage = "File about_utf16.help.txt has to use UTF8 instead of System.Text.UTF32Encoding encoding because it is a powershell help file." +$violationName = "PSUseUTF8EncodingForHelpFile" +$directory = Split-Path -Parent $MyInvocation.MyCommand.Path +$violations = Invoke-ScriptAnalyzer $directory\about_utf16.help.txt | Where-Object {$_.RuleName -eq $violationName} +$noViolations = Invoke-ScriptAnalyzer $directory\about_utf8.help.txt | Where-Object {$_.RuleName -eq $violationName} +$notHelpFileViolations = Invoke-ScriptAnalyzer $directory\utf16.txt | Where-Object {$_.RuleName -eq $violationName} + +Describe "UseUTF8EncodingForHelpFile" { + Context "When there are violations" { + It "has 1 avoid use utf8 encoding violation" { + $violations.Count | Should Be 1 + } + + It "has the correct description message" { + $violations[0].Message | Should Match $violationMessage + } + + } + + Context "When there are no violations" { + It "returns no violations for correct utf8 help file" { + $noViolations.Count | Should Be 0 + } + + It "returns no violations for utf16 file that is not a help file" { + $notHelpFileViolations.Count | Should Be 0 + } + } +} \ No newline at end of file diff --git a/Tests/Rules/about_utf16.help.txt b/Tests/Rules/about_utf16.help.txt new file mode 100644 index 000000000..23be5e142 Binary files /dev/null and b/Tests/Rules/about_utf16.help.txt differ diff --git a/Tests/Rules/about_utf8.help.txt b/Tests/Rules/about_utf8.help.txt new file mode 100644 index 000000000..a06b616af --- /dev/null +++ b/Tests/Rules/about_utf8.help.txt @@ -0,0 +1,17 @@ +TOPIC + about_ + +SHORT DESCRIPTION + A short, one-line description of the topic contents. + +LONG DESCRIPTION + A detailed, full description of the subject or purpose of the module. + +EXAMPLES + Examples of how to use the module or how the subject feature works in practice. + +KEYWORDS + Terms or titles on which you might expect your users to search for the information in this topic. + +SEE ALSO + Text-only references for further reading. Hyperlinks cannot work in the Windows PowerShell console. \ No newline at end of file diff --git a/Tests/Rules/utf16.txt b/Tests/Rules/utf16.txt new file mode 100644 index 000000000..23be5e142 Binary files /dev/null and b/Tests/Rules/utf16.txt differ