Update lightup and tests for Diagnostic.IsSuppressed

This commit is contained in:
Sam Harwell 2021-12-13 12:40:59 -08:00
Родитель d19ef10265
Коммит a191420425
4 изменённых файлов: 179 добавлений и 28 удалений

Просмотреть файл

@ -412,15 +412,8 @@ namespace Microsoft.CodeAnalysis.Testing
if (expected.IsSuppressed.HasValue)
{
if (actual.diagnostic.TryGetIsSuppressed(out var actualValue))
{
message = FormatVerifierMessage(analyzers, actual.diagnostic, expected, $"Expected diagnostic suppression state to match");
verifier.Equal(expected.IsSuppressed.Value, actualValue, message);
}
else
{
throw new NotSupportedException("DiagnosticSuppressors are not supported on this platform.");
}
message = FormatVerifierMessage(analyzers, actual.diagnostic, expected, $"Expected diagnostic suppression state to match");
verifier.Equal(expected.IsSuppressed.Value, actual.diagnostic.IsSuppressed(), message);
}
DiagnosticVerifier?.Invoke(actual.diagnostic, expected, verifier);
@ -817,11 +810,9 @@ namespace Microsoft.CodeAnalysis.Testing
builder.Append(")");
}
if (diagnostics[i].TryGetIsSuppressed(out var isSuppressed) && isSuppressed)
if (diagnostics[i].IsSuppressed())
{
builder.Append($".{nameof(DiagnosticResult.WithIsSuppressed)}(");
builder.Append(isSuppressed);
builder.Append(")");
builder.Append($".{nameof(DiagnosticResult.WithIsSuppressed)}(true)");
}
builder.AppendLine(",");
@ -910,7 +901,7 @@ namespace Microsoft.CodeAnalysis.Testing
if (diagnostics[i].IsSuppressed.HasValue)
{
builder.Append($".{nameof(DiagnosticResult.WithIsSuppressed)}(");
builder.Append(diagnostics[i].IsSuppressed.GetValueOrDefault());
builder.Append(diagnostics[i].IsSuppressed.GetValueOrDefault() ? "true" : "false");
builder.Append(")");
}

Просмотреть файл

@ -3,30 +3,28 @@
// See the LICENSE file in the project root for more information.
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
namespace Microsoft.CodeAnalysis.Testing.Extensions
{
internal static class DiagnosticExtensions
{
private static readonly MethodInfo? IsSuppressedGetMethod = typeof(Diagnostic).GetProperty("IsSuppressed")?.GetMethod;
private static readonly Func<Diagnostic, bool> s_isSuppressed;
public static bool TryGetIsSuppressed(this Diagnostic diagnostic, out bool value)
static DiagnosticExtensions()
{
value = false;
var rawValue = IsSuppressedGetMethod?.Invoke(diagnostic, null);
if (rawValue?.GetType() != typeof(bool))
var isSuppressedProperty = typeof(Diagnostic).GetProperty(nameof(IsSuppressed), typeof(bool));
if (isSuppressedProperty is { GetMethod: { } getMethod })
{
return false;
s_isSuppressed = (Func<Diagnostic, bool>)getMethod.CreateDelegate(typeof(Func<Diagnostic, bool>), target: null);
}
else
{
s_isSuppressed = diagnostic => false;
}
value = (bool)rawValue;
return true;
}
public static bool IsSuppressed(this Diagnostic diagnostic)
=> s_isSuppressed(diagnostic);
}
}

Просмотреть файл

@ -0,0 +1,140 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#if !NETCOREAPP1_1 && !NET46
using System;
using System.Collections.Immutable;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Testing.TestAnalyzers;
using Xunit;
using CSharpAnalyzerTest = Microsoft.CodeAnalysis.Testing.TestAnalyzers.CSharpAnalyzerTest<
Microsoft.CodeAnalysis.Testing.TestAnalyzers.HighlightBracesAnalyzer>;
using CSharpTest = Microsoft.CodeAnalysis.Testing.TestAnalyzers.CSharpSuppressorTest<
Microsoft.CodeAnalysis.Testing.TestAnalyzers.HighlightBracesAnalyzer,
Microsoft.CodeAnalysis.Testing.DiagnosticSuppressorTests.HighlightBracesSuppressor>;
namespace Microsoft.CodeAnalysis.Testing
{
public class DiagnosticSuppressorTests
{
private static readonly DiagnosticDescriptor DiagnosticDescriptor = new HighlightBracesAnalyzer().Descriptor;
[Fact]
public async Task TestUnspecifiedSuppression()
{
await new CSharpTest
{
TestState =
{
Sources = { "namespace MyNamespace {|#0:{|} }" },
ExpectedDiagnostics =
{
new DiagnosticResult(DiagnosticDescriptor).WithLocation(0).WithIsSuppressed(null),
},
},
}.RunAsync();
}
[Fact]
public async Task TestNormalSuppression()
{
await new CSharpTest
{
TestState =
{
Sources = { "namespace MyNamespace {|#0:{|} }" },
ExpectedDiagnostics =
{
new DiagnosticResult(DiagnosticDescriptor).WithLocation(0).WithIsSuppressed(true),
},
},
}.RunAsync();
}
[Fact]
public async Task TestUnexpectedSuppressionPresent()
{
var exception = await Assert.ThrowsAsync<InvalidOperationException>(async () =>
{
await new CSharpTest
{
TestState =
{
Sources = { "namespace MyNamespace {|#0:{|} }" },
ExpectedDiagnostics =
{
new DiagnosticResult(DiagnosticDescriptor).WithLocation(0).WithIsSuppressed(false),
},
},
}.RunAsync();
});
var expected =
"Expected diagnostic suppression state to match" + Environment.NewLine +
Environment.NewLine +
"Expected diagnostic:" + Environment.NewLine +
" // /0/Test0.cs(1,23,1,24): warning Brace: message" + Environment.NewLine +
"VerifyCS.Diagnostic().WithSpan(1, 23, 1, 24).WithIsSuppressed(false)," + Environment.NewLine +
Environment.NewLine +
"Actual diagnostic:" + Environment.NewLine +
" // /0/Test0.cs(1,23): warning Brace: message" + Environment.NewLine +
"VerifyCS.Diagnostic().WithSpan(1, 23, 1, 24).WithIsSuppressed(true)," + Environment.NewLine +
Environment.NewLine;
new DefaultVerifier().EqualOrDiff(expected, exception.Message);
}
[Fact]
public async Task TestExpectedSuppressionMissing()
{
var exception = await Assert.ThrowsAsync<InvalidOperationException>(async () =>
{
await new CSharpAnalyzerTest
{
TestState =
{
Sources = { "namespace MyNamespace {|#0:{|} }" },
ExpectedDiagnostics =
{
new DiagnosticResult(DiagnosticDescriptor).WithLocation(0).WithIsSuppressed(true),
},
},
}.RunAsync();
});
var expected =
"Expected diagnostic suppression state to match" + Environment.NewLine +
Environment.NewLine +
"Expected diagnostic:" + Environment.NewLine +
" // /0/Test0.cs(1,23,1,24): warning Brace: message" + Environment.NewLine +
"VerifyCS.Diagnostic().WithSpan(1, 23, 1, 24).WithIsSuppressed(true)," + Environment.NewLine +
Environment.NewLine +
"Actual diagnostic:" + Environment.NewLine +
" // /0/Test0.cs(1,23): warning Brace: message" + Environment.NewLine +
"VerifyCS.Diagnostic().WithSpan(1, 23, 1, 24)," + Environment.NewLine +
Environment.NewLine;
new DefaultVerifier().EqualOrDiff(expected, exception.Message);
}
[DiagnosticAnalyzer(LanguageNames.CSharp)]
internal class HighlightBracesSuppressor : DiagnosticSuppressor
{
internal static readonly SuppressionDescriptor Descriptor =
new SuppressionDescriptor("XBrace", DiagnosticDescriptor.Id, "justification");
public override ImmutableArray<SuppressionDescriptor> SupportedSuppressions => ImmutableArray.Create(Descriptor);
public override void ReportSuppressions(SuppressionAnalysisContext context)
{
foreach (var diagnostic in context.ReportedDiagnostics)
{
context.ReportSuppression(Suppression.Create(Descriptor, diagnostic));
}
}
}
}
}
#endif

Просмотреть файл

@ -0,0 +1,22 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#if !NETCOREAPP1_1 && !NET46
using System.Collections.Generic;
using System.Linq;
using Microsoft.CodeAnalysis.Diagnostics;
namespace Microsoft.CodeAnalysis.Testing.TestAnalyzers
{
internal class CSharpSuppressorTest<TAnalyzer, TSuppressor> : CSharpAnalyzerTest<TAnalyzer>
where TAnalyzer : DiagnosticAnalyzer, new()
where TSuppressor : DiagnosticSuppressor, new()
{
protected override IEnumerable<DiagnosticAnalyzer> GetDiagnosticAnalyzers()
=> base.GetDiagnosticAnalyzers().Concat(new[] { new TSuppressor() });
}
}
#endif