-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix #6
- Loading branch information
Jérémie Bertrand
committed
Sep 5, 2016
1 parent
bba2afa
commit 2ff0c96
Showing
8 changed files
with
608 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
using NVika.Parsers; | ||
using System; | ||
using System.Collections.Generic; | ||
using System.IO.Abstractions.TestingHelpers; | ||
using System.Linq; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
using Xunit; | ||
|
||
namespace NVika.Tests.Parsers | ||
{ | ||
public class FxCopParserTest | ||
{ | ||
[Fact] | ||
public void Name() | ||
{ | ||
// arrange | ||
var parser = new FxCopParser(); | ||
parser.FileSystem = new MockFileSystem(); | ||
|
||
// act | ||
var name = parser.Name; | ||
|
||
// assert | ||
Assert.Equal("FxCop", name); | ||
} | ||
|
||
[Theory] | ||
[InlineData("CodeAnalysisLog.xml", true)] | ||
[InlineData("emptyreport.xml", true)] | ||
[InlineData("onlymessages.xml", true)] | ||
[InlineData("onlyrules.xml", true)] | ||
[InlineData("onlyissues.json", false)] | ||
public void CanParse(string reportPath, bool expectedResult) | ||
{ | ||
// arrange | ||
var parser = new FxCopParser(); | ||
parser.FileSystem = new MockFileSystem(new Dictionary<string, MockFileData> | ||
{ | ||
{ "CodeAnalysisLog.xml", new MockFileData(TestUtilities.GetEmbeddedResourceContent("CodeAnalysisLog.xml")) }, | ||
{ "emptyreport.xml", new MockFileData("<FxCopReport Version=\"10.0\"></FxCopReport>") }, | ||
{ "onlymessages.xml", new MockFileData("<FxCopReport Version=\"10.0\"><Messages><Message /></Messages></FxCopReport>") }, | ||
{ "onlyrules.xml", new MockFileData("<FxCopReport Version=\"10.0\"><Rules><Rule /></Rules></FxCopReport>") }, | ||
}); | ||
|
||
// act | ||
var result = parser.CanParse(reportPath); | ||
|
||
// assert | ||
Assert.Equal(expectedResult, result); | ||
} | ||
|
||
[Fact] | ||
public void Parse() | ||
{ | ||
// arrange | ||
var fileSystem = new MockFileSystem(new Dictionary<string, MockFileData> | ||
{ | ||
{ "CodeAnalysisLog.xml", new MockFileData(TestUtilities.GetEmbeddedResourceContent("CodeAnalysisLog.xml")) }, | ||
}); | ||
var parser = new FxCopParser(); | ||
parser.FileSystem = fileSystem; | ||
|
||
// act | ||
var result = parser.Parse("CodeAnalysisLog.xml").ToList(); | ||
|
||
// assert | ||
Assert.Equal(24, result.Count); | ||
|
||
AssertIssue(result[0], | ||
"Microsoft.Naming", | ||
"Identifiers should be spelled correctly", | ||
"http://msdn.microsoft.com/library/bb264492.aspx", | ||
"Correct the spelling of 'Vika' in namespace name 'NVika.Abstractions'.", | ||
"CA1704", | ||
IssueSeverity.Warning); | ||
|
||
AssertIssue(result[4], | ||
"Microsoft.Design", | ||
"Mark assemblies with CLSCompliantAttribute", | ||
"http://msdn.microsoft.com/library/ms182156.aspx", | ||
"Mark 'NVika.exe' with CLSCompliant(true) because it exposes externally visible types.", | ||
"CA1014", | ||
IssueSeverity.Error); | ||
|
||
AssertIssue(result[10], | ||
"Microsoft.Globalization", | ||
"Specify IFormatProvider", | ||
"http://msdn.microsoft.com/library/ms182190.aspx", | ||
"Because the behavior of 'string.Format(string, object)' could vary based on the current user's locale settings, replace this call in 'Program.Run(string[])' with a call to 'string.Format(IFormatProvider, string, params object[])'. If the result of 'string.Format(IFormatProvider, string, params object[])' will be displayed to the user, specify 'CultureInfo.CurrentCulture' as the 'IFormatProvider' parameter. Otherwise, if the result will be stored and accessed by software, such as when it is persisted to disk or to a database, specify 'CultureInfo.InvariantCulture'.", | ||
"CA1305", | ||
IssueSeverity.Error); | ||
|
||
AssertIssue(result[16], | ||
"Microsoft.Performance", | ||
"Avoid uncalled private code", | ||
"http://msdn.microsoft.com/library/ms182264.aspx", | ||
"'AppVeyor.CompilationMessage.Line.get()' appears to have no upstream public or protected callers.", | ||
"CA1811", | ||
IssueSeverity.Warning); | ||
|
||
AssertIssue(result[19], | ||
"Microsoft.Design", | ||
"Implement standard exception constructors", | ||
"http://msdn.microsoft.com/library/ms182151.aspx", | ||
"Add the following constructor to 'LoadingReportException': private LoadingReportException(SerializationInfo, StreamingContext).", | ||
"CA1032", | ||
IssueSeverity.Error); | ||
|
||
AssertIssue(result[23], | ||
"Microsoft.Globalization", | ||
"Specify IFormatProvider", | ||
"http://msdn.microsoft.com/library/ms182190.aspx", | ||
"Because the behavior of 'int.Parse(string)' could vary based on the current user's locale settings, replace this call in 'InspectCodeParser.GetOffset(XAttribute, string, uint?)' with a call to 'int.Parse(string, IFormatProvider)'. If the result of 'int.Parse(string, IFormatProvider)' will be based on input from the user, specify 'CultureInfo.CurrentCulture' as the 'IFormatProvider' parameter. Otherwise, if the result will based on input stored and accessed by software, such as when it is loaded from disk or from a database, specify 'CultureInfo.InvariantCulture'.", | ||
"CA1305", | ||
IssueSeverity.Error); | ||
} | ||
|
||
private void AssertIssue(Issue result, string expectedCategory, string expectedDescription, string expectedUri, string expectedMessage, string expectedName, IssueSeverity expectedSeverity) | ||
{ | ||
Assert.Equal(expectedCategory, result.Category); | ||
Assert.Equal(expectedDescription, result.Description); | ||
Assert.Null(result.FilePath); | ||
Assert.Equal(expectedUri, result.HelpUri.AbsoluteUri); | ||
Assert.Null(result.Line); | ||
Assert.Equal(expectedMessage, result.Message); | ||
Assert.Equal(expectedName, result.Name); | ||
Assert.Null(result.Offset); | ||
Assert.Null(result.Project); | ||
Assert.Equal(expectedSeverity, result.Severity); | ||
Assert.Equal("FxCop", result.Source); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.IO; | ||
using System.Linq; | ||
using System.Xml; | ||
using System.Xml.Linq; | ||
|
||
namespace NVika.Parsers | ||
{ | ||
internal sealed class FxCopParser : ReportParserBase | ||
{ | ||
private readonly Dictionary<string, XElement> _rules = new Dictionary<string, XElement>(); | ||
|
||
public override string Name | ||
{ | ||
get | ||
{ | ||
return "FxCop"; | ||
} | ||
} | ||
|
||
public FxCopParser() | ||
: base(new[] { ".xml" }, '<') | ||
{ | ||
|
||
} | ||
|
||
protected override bool CanParse(StreamReader streamReader) | ||
{ | ||
// Avoid Xml exception caused by the BOM | ||
using (var xmlReader = new XmlTextReader(streamReader.BaseStream)) | ||
{ | ||
var report = XDocument.Load(xmlReader); | ||
|
||
return report.Root.Name == "FxCopReport"; | ||
} | ||
} | ||
|
||
public override IEnumerable<Issue> Parse(string reportPath) | ||
{ | ||
var report = XDocument.Load(FileSystem.File.OpenRead(reportPath)); | ||
|
||
var rules = report.Descendants("Rule"); | ||
|
||
foreach (var message in report.Descendants("Message")) | ||
{ | ||
var rule = GetRule(rules, message.Attribute("CheckId").Value); | ||
var issue = message.Element("Issue"); | ||
|
||
yield return new Issue | ||
{ | ||
Category = rule.Attribute("Category").Value, | ||
Description = rule.Element("Name").Value, | ||
HelpUri = new Uri(rule.Element("Url").Value), | ||
Message = issue.Value, | ||
Name = message.Attribute("CheckId").Value, | ||
Severity = GetSeverity(issue.Attribute("Level")), | ||
Source = Name, | ||
}; | ||
} | ||
} | ||
|
||
private static IssueSeverity GetSeverity(XAttribute level) | ||
{ | ||
switch (level.Value) | ||
{ | ||
case "Error": | ||
case "CriticalError": return IssueSeverity.Error; | ||
|
||
case "Warning": | ||
case "CriticalWarning": | ||
default: return IssueSeverity.Warning; | ||
} | ||
} | ||
|
||
private XElement GetRule(IEnumerable<XElement> rules, string ruleId) | ||
{ | ||
if (!_rules.ContainsKey(ruleId)) | ||
{ | ||
_rules.Add(ruleId, rules.First(it => it.Attribute("CheckId").Value == ruleId)); | ||
} | ||
return _rules[ruleId]; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters