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);
        }
Ejemplo n.º 3
0
        public void MergeLocations_No_Issues()
        {
            var result = new IssueLocationCollector().MergeLocations(
                Enumerable.Empty <IssueLocation>(),
                Enumerable.Empty <IssueLocation>());

            result.Should().BeEmpty();
        }
Ejemplo n.º 4
0
        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))}.");
                    }
                }
            }
        }
Ejemplo n.º 5
0
        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();
        }
Ejemplo n.º 11
0
        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");
        }
Ejemplo n.º 13
0
        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" });
        }
Ejemplo n.º 15
0
        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" });
        }
Ejemplo n.º 16
0
        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" });
        }
Ejemplo n.º 17
0
        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" });
        }
Ejemplo n.º 20
0
        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 });
        }
Ejemplo n.º 26
0
        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" });
        }