public void GetPreciseIssueLocations_Xml() { var code = @"<Root> <Space><SelfClosing /></Space> <!-- ^^^^^^^^^^^^^^^ --> <NoSpace><SelfClosing /></NoSpace> <!--^^^^^^^^^^^^^^^--> <Multiline><SelfClosing /></Multiline> <!-- ^^^^^^^^^^^^^^^ --> </Root>"; var line = GetLine(2, code); var result = IssueLocationCollector.GetPreciseIssueLocations(line).ToList(); result.Should().ContainSingle(); var issueLocation = result.Single(); issueLocation.Start.Should().Be(7); issueLocation.Length.Should().Be(15); line = GetLine(4, code); result = IssueLocationCollector.GetPreciseIssueLocations(line).ToList(); result.Should().ContainSingle(); issueLocation = result.Single(); issueLocation.Start.Should().Be(9); issueLocation.Length.Should().Be(15); line = GetLine(6, code); result = IssueLocationCollector.GetPreciseIssueLocations(line).ToList(); result.Should().ContainSingle(); issueLocation = result.Single(); issueLocation.Start.Should().Be(11); issueLocation.Length.Should().Be(15); }
// Verifies the results for the given web.config file path. private static void VerifyResults(string webConfigPath, IList <Diagnostic> allDiagnostics, string languageVersion) { var actualIssues = allDiagnostics.Where(d => d.Location.GetLineSpan().Path.EndsWith(webConfigPath)); var expectedIssues = IssueLocationCollector.GetExpectedIssueLocations(SourceText.From(File.ReadAllText(webConfigPath)).Lines).ToList(); DiagnosticVerifier.CompareActualToExpected(languageVersion, actualIssues, expectedIssues, false); }
public void MergeLocations_No_Issues() { var result = new IssueLocationCollector().MergeLocations( Enumerable.Empty <IssueLocation>(), Enumerable.Empty <IssueLocation>()); result.Should().BeEmpty(); }
public static void VerifyAnalyzer(string path, SonarDiagnosticAnalyzer diagnosticAnalyzer, ParseOptions options = null, params MetadataReference[] additionalReferences) { var file = new FileInfo(path); var parseOptions = GetParseOptionsAlternatives(options, file.Extension); var issueLocationCollector = new IssueLocationCollector(); using (var workspace = new AdhocWorkspace()) { var document = GetDocument(file, GeneratedAssemblyName, workspace, additionalReferences: additionalReferences); var project = document.Project; foreach (var parseOption in parseOptions) { if (parseOption != null) { project = project.WithParseOptions(parseOption); } var compilation = project.GetCompilationAsync().Result; var diagnostics = GetDiagnostics(compilation, diagnosticAnalyzer); var expectedIssues = issueLocationCollector .GetExpectedIssueLocations(compilation.SyntaxTrees.First().GetText().Lines) .ToList(); foreach (var diagnostic in diagnostics) { var location = diagnostic.Location; var message = diagnostic.GetMessage(); string issueId; VerifyIssue(expectedIssues, issue => issue.IsPrimary, location, message, out issueId); var sortedAdditionalLocations = diagnostic.AdditionalLocations .OrderBy(x => x.GetLineNumberToReport()) .ThenBy(x => x.GetLineSpan().StartLinePosition.Character) .ToList(); for (int i = 0; i < sortedAdditionalLocations.Count; i++) { location = sortedAdditionalLocations[i]; diagnostic.Properties.TryGetValue(i.ToString(), out message); VerifyIssue(expectedIssues, issue => issue.IssueId == issueId && !issue.IsPrimary, location, message, out issueId); } } if (expectedIssues.Count != 0) { Execute.Assertion.FailWith($"Issue expected but not raised on line(s) {string.Join(",", expectedIssues.Select(i => i.LineNumber))}."); } } } }
public void MergeLocations_NonEmpty_Issues_Empty_PreciseLocations() { var result = new IssueLocationCollector().MergeLocations( new[] { new IssueLocation { LineNumber = 3 } }, Enumerable.Empty <IssueLocation>()); result.Should().ContainSingle(); }
public void GetPreciseIssueLocations_NoComment() { var line = GetLine(3, @"if (a > b) { Console.WriteLine(a); }"); var result = IssueLocationCollector.GetPreciseIssueLocations(line).ToList(); result.Should().BeEmpty(); }
public void MergeLocations_Empty_Issues_NonEmpty_PreciseLocations() { var result = new IssueLocationCollector().MergeLocations( Enumerable.Empty <IssueLocation>(), new[] { new IssueLocation { LineNumber = 3 } }); result.Should().HaveCount(1); }
public void GetPreciseIssueLocations_InvalidPattern() { var line = GetLine(3, @"if (a > b) { Console.WriteLine(a); // ^^^^^^^^^ SecondaryNoncompliantSecondary {{Some message}} }"); var result = IssueLocationCollector.GetPreciseIssueLocations(line).ToList(); result.Should().BeEmpty(); }
public void GetExpectedBuildErrors_No_Comments() { var code = @"public class Foo { public void Bar(object o) { Console.WriteLine(o); } }"; var expectedErrors = new IssueLocationCollector().GetExpectedBuildErrors(SourceText.From(code).Lines); expectedErrors.Should().BeEmpty(); }
public void GetExpectedIssueLocations_No_Comments() { var code = @"public class Foo { public void Bar(object o) { Console.WriteLine(o); } }"; var locations = IssueLocationCollector.GetExpectedIssueLocations(SourceText.From(code).Lines); locations.Should().BeEmpty(); }
private static void VerifyAnalyzer(IEnumerable <DocumentInfo> documents, string fileExtension, SonarDiagnosticAnalyzer diagnosticAnalyzer, ParseOptions options = null, params MetadataReference[] additionalReferences) { var parseOptions = GetParseOptionsAlternatives(options, fileExtension); using (var workspace = new AdhocWorkspace()) { var project = CreateProject(fileExtension, GeneratedAssemblyName, workspace, additionalReferences); documents.ToList().ForEach(document => project = project.AddDocument(document.Name, document.Content).Project); // side effect on purpose (project is immutable) var issueLocationCollector = new IssueLocationCollector(); foreach (var parseOption in parseOptions) { if (parseOption != null) { project = project.WithParseOptions(parseOption); } var compilation = project.GetCompilationAsync().Result; var diagnostics = GetDiagnostics(compilation, diagnosticAnalyzer); var expectedIssues = issueLocationCollector .GetExpectedIssueLocations(compilation.SyntaxTrees.Skip(1).First().GetText().Lines) .ToList(); foreach (var diagnostic in diagnostics) { string issueId; VerifyIssue(expectedIssues, issue => issue.IsPrimary, diagnostic.Location, diagnostic.GetMessage(), out issueId); diagnostic.AdditionalLocations .Select((location, i) => diagnostic.GetSecondaryLocation(i)) .OrderBy(x => x.Location.GetLineNumberToReport()) .ThenBy(x => x.Location.GetLineSpan().StartLinePosition.Character) .ToList() .ForEach(secondaryLocation => { VerifyIssue(expectedIssues, issue => issue.IssueId == issueId && !issue.IsPrimary, secondaryLocation.Location, secondaryLocation.Message, out issueId); }); } if (expectedIssues.Count != 0) { Execute.Assertion.FailWith($"Issue expected but not raised on line(s) {string.Join(",", expectedIssues.Select(i => i.LineNumber))}."); } } } }
public void GetExpectedIssueLocations_Multiple_PrimaryIds() { var code = @"public class Foo { public void Bar(object o) // Noncompliant [myId1] { Console.WriteLine(o); // Noncompliant [myId1] } }"; Action action = () => IssueLocationCollector.GetExpectedIssueLocations(SourceText.From(code).Lines); action.Should().Throw <InvalidOperationException>() .WithMessage("Primary location with id [myId1] found on multiple lines: 3, 5"); }
public void GetExpectedIssueLocations_OnlyCommentedNoncompliant() { var code = @"public class MyNoncompliantClass { public void NoncompliantMethod(object o) { Console.WriteLine(o); // Noncompliant } }"; var locations = new IssueLocationCollector().GetExpectedIssueLocations(SourceText.From(code).Lines); locations.Should().HaveCount(1); locations.Select(l => l.IsPrimary).Should().Equal(new[] { true }); locations.Select(l => l.LineNumber).Should().Equal(new[] { 5 }); }
public void GetExpectedBuildErrors_Multiple_ExpectedErrors() { var code = @"public class Foo { public void Bar(object o) // Error [CS1234,CS2345,CS3456] { } }"; var expectedErrors = new IssueLocationCollector().GetExpectedBuildErrors(SourceText.From(code).Lines); expectedErrors.Should().HaveCount(3); expectedErrors.Select(l => l.IsPrimary).Should().Equal(new[] { true, true, true }); expectedErrors.Select(l => l.LineNumber).Should().Equal(new[] { 3, 3, 3 }); expectedErrors.Select(l => l.IssueId).Should().Equal(new[] { "CS1234", "CS2345", "CS3456" }); }
public void GetIssueLocations_Noncompliant_With_Offset_Message_And_Flows() { var line = GetLine(2, @"if (a > b) { Console.WriteLine(a); //Noncompliant@-1 [flow1,flow2] {{Some message}} }"); var result = new IssueLocationCollector().GetIssueLocations(line).ToList(); result.Should().HaveCount(2); VerifyIssueLocations(result, expectedIsPrimary: new[] { true, true }, expectedLineNumbers: new[] { 2, 2 }, expectedMessages: new string[] { "Some message", "Some message" }, expectedIssueIds: new[] { "flow1", "flow2" }); }
public void GetIssueLocations_Noncompliant_With_Two_Flows() { var line = GetLine(2, @"if (a > b) { Console.WriteLine(a); //Noncompliant [flow1,flow2] }"); var result = new IssueLocationCollector().GetIssueLocations(line).ToList(); result.Should().HaveCount(2); VerifyIssueLocations(result, expectedIsPrimary: new[] { true, true }, expectedLineNumbers: new[] { 3, 3 }, expectedMessages: new string[] { null, null }, expectedIssueIds: new[] { "flow1", "flow2" }); }
public void GetIssueLocations_Noncompliant() { var line = GetLine(2, @"if (a > b) { Console.WriteLine(a); //Noncompliant }"); var result = new IssueLocationCollector().GetIssueLocations(line).ToList(); result.Should().ContainSingle(); VerifyIssueLocations(result, expectedIsPrimary: new[] { true }, expectedLineNumbers: new[] { 3 }, expectedMessages: new string[] { null }, expectedIssueIds: new string[] { null }); }
public void GetExpectedIssueLocations_Invalid_Type_Format() { var code = @"public class Foo { public void Bar(object o) // Is Noncompliant { Console.WriteLine(o); } }"; Action action = () => IssueLocationCollector.GetExpectedIssueLocations(SourceText.From(code).Lines); action.Should().Throw <InvalidOperationException>() .WithMessage(@"Line 2 looks like it contains comment for noncompliant code, but it is not recognized as one of the expected pattern. Either remove the Noncompliant/Secondary word or precise pattern '^^' from the comment, or fix the pattern."); }
public void GetIssueLocations_Secondary_ExactColumn_Ids() { var line = GetLine(2, @"if (a > b) { Console.WriteLine(a); //Secondary ^13#9 [myId] }"); var result = new IssueLocationCollector().GetIssueLocations(line).ToList(); result.Should().ContainSingle(); VerifyIssueLocations(result, expectedIsPrimary: new[] { false }, expectedLineNumbers: new[] { 3 }, expectedMessages: new string[] { null }, expectedIssueIds: new string[] { "myId" }); }
public void GetIssueLocations_Noncompliant_With_Reversed_Message_And_Flows() { var line = GetLine(2, @"if (a > b) { Console.WriteLine(a); //Noncompliant {{Some message}} [flow1,flow2] }"); var result = new IssueLocationCollector().GetIssueLocations(line).ToList(); result.Should().ContainSingle(); VerifyIssueLocations(result, expectedIsPrimary: new[] { true }, expectedLineNumbers: new[] { 3 }, expectedMessages: new string[] { "Some message" }, expectedIssueIds: new string[] { null }); }
public void GetIssueLocations_Flow_With_Offset_Message_And_Flows() { var line = GetLine(2, @"if (a > b) { Console.WriteLine(a); //Secondary@-1 [flow1,flow2] {{Some message}} }"); var result = IssueLocationCollector.GetIssueLocations(line).ToList(); result.Should().HaveCount(2); VerifyIssueLocations(result, expectedIsPrimary: new[] { false, false }, expectedLineNumbers: new[] { 2, 2 }, expectedMessages: new[] { "Some message", "Some message" }, expectedIssueIds: new[] { "flow1", "flow2" }); }
public void GetPreciseIssueLocations_MultiplePatternsOnSameLine() { var line = GetLine(3, @"if (a > b) { Console.WriteLine(a); // ^^^^^^^ ^^^^^^^^^ ^ }"); Action action = () => IssueLocationCollector.GetPreciseIssueLocations(line); action.Should() .Throw <InvalidOperationException>() .WithMessage(@"Expecting only one precise location per line, found 3 on line 3. If you want to specify more than one precise location per line you need to omit the Noncompliant comment: internal class MyClass : IInterface1 // there should be no Noncompliant comment ^^^^^^^ {{Do not create internal classes.}} ^^^^^^^^^^^ @-1 {{IInterface1 is bad for your health.}}"); }
public void GetPreciseIssueLocations_Message_And_IssueIds_Secondary_XML() { var line = GetLine(2, @"<Root> <Baaad /> <!-- ^^^^^^^^^ Secondary [flow1,flow2] {{Some message}} --> </Root>"); var result = IssueLocationCollector.GetPreciseIssueLocations(line).ToList(); result.Should().HaveCount(2); VerifyIssueLocations(result, expectedIsPrimary: new[] { false, false }, expectedLineNumbers: new[] { 2, 2 }, expectedMessages: new[] { "Some message", "Some message" }, expectedIssueIds: new[] { "flow1", "flow2" }); }
public void GetPreciseIssueLocations_Secondary_With_Offset() { var line = GetLine(3, @"if (a > b) { Console.WriteLine(a); // ^^^^^^^^^ Secondary@-1 }"); var result = IssueLocationCollector.GetPreciseIssueLocations(line).ToList(); result.Should().ContainSingle(); VerifyIssueLocations(result, expectedIsPrimary: new[] { false }, expectedLineNumbers: new[] { 2 }, expectedMessages: new string[] { null }, expectedIssueIds: new string[] { null }); }
public void GetPreciseIssueLocations_NoMessage_NoIds() { var line = GetLine(3, @"if (a > b) { Console.WriteLine(a); // ^^^^^^^^^ }"); var result = IssueLocationCollector.GetPreciseIssueLocations(line).ToList(); result.Should().ContainSingle(); VerifyIssueLocations(result, expectedIsPrimary: new[] { true }, expectedLineNumbers: new[] { 3 }, expectedMessages: new string[] { null }, expectedIssueIds: new string[] { null }); }
public void GetExpectedIssueLocations_Locations() { var code = @"public class Foo { public void Bar(object o) // Noncompliant { // Noncompliant @+1 Console.WriteLine(o); } }"; var locations = new IssueLocationCollector().GetExpectedIssueLocations(SourceText.From(code).Lines); locations.Should().HaveCount(2); locations.Select(l => l.IsPrimary).Should().Equal(new[] { true, true }); locations.Select(l => l.LineNumber).Should().Equal(new[] { 3, 5 }); }
public void GetExpectedBuildErrors_ExpectedErrors() { var code = @"public class Foo { public void Bar(object o) // Error [CS1234] { // Error@+1 [CS3456] Console.WriteLine(o); } }"; var expectedErrors = new IssueLocationCollector().GetExpectedBuildErrors(SourceText.From(code).Lines); expectedErrors.Should().HaveCount(2); expectedErrors.Select(l => l.IsPrimary).Should().Equal(new[] { true, true }); expectedErrors.Select(l => l.LineNumber).Should().Equal(new[] { 3, 6 }); }
public void GetPreciseIssueLocations_NotStartOfLineIsOk() { var line = GetLine(3, @"if (a > b) { Console.WriteLine(a); // ^^^^^^^^^ }"); var result = IssueLocationCollector.GetPreciseIssueLocations(line).ToList(); result.Should().ContainSingle(); var issueLocation = result.First(); issueLocation.IsPrimary.Should().BeTrue(); issueLocation.LineNumber.Should().Be(3); issueLocation.Start.Should().Be(12); issueLocation.Length.Should().Be(9); }
public void GetPreciseIssueLocations_IssueIds_Secondary() { var line = GetLine(3, @"if (a > b) { Console.WriteLine(a); // ^^^^^^^^^ Secondary [last1,flow1,flow2] }"); var result = IssueLocationCollector.GetPreciseIssueLocations(line).ToList(); result.Should().HaveCount(3); VerifyIssueLocations(result, expectedIsPrimary: new[] { false, false, false }, expectedLineNumbers: new[] { 3, 3, 3 }, expectedMessages: new string[] { null, null, null }, expectedIssueIds: new[] { "flow1", "flow2", "last1" }); }
public void GetPreciseIssueLocations_Message_And_IssueIds_Secondary_CS() { var line = GetLine(3, @"if (a > b) { Console.WriteLine(a); // ^^^^^^^^^ Secondary [flow1,flow2] {{Some message}} }"); var result = IssueLocationCollector.GetPreciseIssueLocations(line).ToList(); result.Should().HaveCount(2); VerifyIssueLocations(result, expectedIsPrimary: new[] { false, false }, expectedLineNumbers: new[] { 3, 3 }, expectedMessages: new[] { "Some message", "Some message" }, expectedIssueIds: new[] { "flow1", "flow2" }); }