From f02e71c9f38ebd458b4e22b5e30449104adef4f5 Mon Sep 17 00:00:00 2001 From: georgii-borovinskikh-sonarsource Date: Wed, 30 Aug 2023 11:16:42 +0200 Subject: [PATCH] Add CCT severity to Vs Severity mapping Implements #4804 --- .../ErrorList/IssuesSnapshot.cs | 2 +- ...nalysisIssueVisualizationConverterTests.cs | 4 +- ...lysisSeverityToVsSeverityConverterTests.cs | 44 +++++++++++++++++++ .../IAnalysisSeverityToVsSeverityConverter.cs | 30 +++++++++++++ 4 files changed, 77 insertions(+), 3 deletions(-) diff --git a/src/Integration.Vsix/ErrorList/IssuesSnapshot.cs b/src/Integration.Vsix/ErrorList/IssuesSnapshot.cs index af0cc6f8ac..445a5f04b6 100644 --- a/src/Integration.Vsix/ErrorList/IssuesSnapshot.cs +++ b/src/Integration.Vsix/ErrorList/IssuesSnapshot.cs @@ -210,7 +210,7 @@ public override bool TryGetValue(int index, string keyName, out object content) return true; case StandardTableKeyNames.ErrorSeverity: - content = toVsSeverityConverter.Convert(issue.Severity); + content = toVsSeverityConverter.GetVsSeverity(issue); return true; case StandardTableKeyNames.BuildTool: diff --git a/src/IssueViz.UnitTests/AnalysisIssueVisualizationConverterTests.cs b/src/IssueViz.UnitTests/AnalysisIssueVisualizationConverterTests.cs index 1909e6ea98..3de8255cc6 100644 --- a/src/IssueViz.UnitTests/AnalysisIssueVisualizationConverterTests.cs +++ b/src/IssueViz.UnitTests/AnalysisIssueVisualizationConverterTests.cs @@ -271,7 +271,7 @@ private IAnalysisIssue CreateIssue(params IQuickFix[] quickFixes) Guid.NewGuid().ToString(), AnalysisIssueSeverity.Blocker, AnalysisIssueType.Bug, - null, + SoftwareQualitySeverity.High, CreateLocation(Guid.NewGuid().ToString()), null, quickFixes @@ -286,7 +286,7 @@ private IAnalysisIssue CreateIssue(string filePath, params IAnalysisIssueFlow[] Guid.NewGuid().ToString(), AnalysisIssueSeverity.Blocker, AnalysisIssueType.Bug, - null, + SoftwareQualitySeverity.High, CreateLocation(filePath), flows ); diff --git a/src/IssueViz.UnitTests/Helpers/AnalysisSeverityToVsSeverityConverterTests.cs b/src/IssueViz.UnitTests/Helpers/AnalysisSeverityToVsSeverityConverterTests.cs index b7c9a424a7..fe9eafd02c 100644 --- a/src/IssueViz.UnitTests/Helpers/AnalysisSeverityToVsSeverityConverterTests.cs +++ b/src/IssueViz.UnitTests/Helpers/AnalysisSeverityToVsSeverityConverterTests.cs @@ -25,6 +25,7 @@ using SonarLint.VisualStudio.Core; using SonarLint.VisualStudio.Core.Analysis; using SonarLint.VisualStudio.IssueVisualization.Helpers; +using SonarLint.VisualStudio.TestInfrastructure; namespace SonarLint.VisualStudio.IssueVisualization.UnitTests.Helpers { @@ -60,11 +61,54 @@ public void Convert_Blocker_CorrectlyMapped(bool shouldTreatBlockerAsError, __VS testSubject.Convert(AnalysisIssueSeverity.Blocker).Should().Be(expectedVsErrorCategory); } + + [TestMethod] + [DataRow(SoftwareQualitySeverity.High, __VSERRORCATEGORY.EC_WARNING)] + [DataRow(SoftwareQualitySeverity.Medium, __VSERRORCATEGORY.EC_WARNING)] + [DataRow(SoftwareQualitySeverity.Low, __VSERRORCATEGORY.EC_MESSAGE)] + public void ConvertFromCct_CorrectlyMapped(SoftwareQualitySeverity severity, __VSERRORCATEGORY expectedVsErrorCategory) + { + testSubject.ConvertFromCct(severity).Should().Be(expectedVsErrorCategory); + } + [TestMethod] + public void ConvertFromCct_InvalidCctSeverity_DoesNotThrow() + { + testSubject.ConvertFromCct((SoftwareQualitySeverity)(-999)).Should().Be(__VSERRORCATEGORY.EC_MESSAGE); + } + [TestMethod] public void Convert_InvalidDaemonSeverity_DoesNotThrow() { testSubject.Convert((AnalysisIssueSeverity)(-999)).Should().Be(__VSERRORCATEGORY.EC_MESSAGE); } + + [TestMethod] + public void GetVsSeverity_IssueWithNewCct_UsesNewCctConverter() + { + var converter = new Mock(); + + converter.Object.GetVsSeverity(new DummyAnalysisIssue + { + Severity = AnalysisIssueSeverity.Major, HighestSoftwareQualitySeverity = SoftwareQualitySeverity.High + }); + + converter.Verify(x => x.ConvertFromCct(SoftwareQualitySeverity.High), Times.Once); + converter.Invocations.Should().HaveCount(1); + } + + [TestMethod] + public void GetVsSeverity_IssueWithoutNewCct_UsesOldSeverityConverter() + { + var converter = new Mock(); + + converter.Object.GetVsSeverity(new DummyAnalysisIssue + { + Severity = AnalysisIssueSeverity.Major + }); + + converter.Verify(x => x.Convert(AnalysisIssueSeverity.Major), Times.Once); + converter.Invocations.Should().HaveCount(1); + } } } diff --git a/src/IssueViz/Helpers/IAnalysisSeverityToVsSeverityConverter.cs b/src/IssueViz/Helpers/IAnalysisSeverityToVsSeverityConverter.cs index 930887c69e..6153b354ce 100644 --- a/src/IssueViz/Helpers/IAnalysisSeverityToVsSeverityConverter.cs +++ b/src/IssueViz/Helpers/IAnalysisSeverityToVsSeverityConverter.cs @@ -27,6 +27,7 @@ namespace SonarLint.VisualStudio.IssueVisualization.Helpers public interface IAnalysisSeverityToVsSeverityConverter { __VSERRORCATEGORY Convert(AnalysisIssueSeverity severity); + __VSERRORCATEGORY ConvertFromCct(SoftwareQualitySeverity severity); } public class AnalysisSeverityToVsSeverityConverter : IAnalysisSeverityToVsSeverityConverter @@ -43,6 +44,25 @@ internal AnalysisSeverityToVsSeverityConverter(IEnvironmentSettings environmentS this.environmentSettings = environmentSettings; } + public __VSERRORCATEGORY ConvertFromCct(SoftwareQualitySeverity severity) + { + switch (severity) + { + case SoftwareQualitySeverity.Medium: + case SoftwareQualitySeverity.High: + return __VSERRORCATEGORY.EC_WARNING; + + case SoftwareQualitySeverity.Low: + return __VSERRORCATEGORY.EC_MESSAGE; + + default: + // We don't want to throw here - we're being called by VS to populate + // the columns in the error list, and if we're on a UI thread then + // we'll crash VS + return __VSERRORCATEGORY.EC_MESSAGE; + } + } + public __VSERRORCATEGORY Convert(AnalysisIssueSeverity severity) { switch (severity) @@ -66,4 +86,14 @@ public __VSERRORCATEGORY Convert(AnalysisIssueSeverity severity) } } } + + public static class AnalysisSeverityToVsSeverityConverterExtensions + { + public static __VSERRORCATEGORY GetVsSeverity( + this IAnalysisSeverityToVsSeverityConverter converter, + IAnalysisIssue issue) => + issue.HighestSoftwareQualitySeverity.HasValue + ? converter.ConvertFromCct(issue.HighestSoftwareQualitySeverity.Value) + : converter.Convert(issue.Severity); + } }