Skip to content

Commit

Permalink
Refactor and improve tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Tim-Pohlmann committed Feb 15, 2023
1 parent 089e06d commit cbf178b
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 76 deletions.
114 changes: 84 additions & 30 deletions analyzers/tests/SonarAnalyzer.UnitTest/Rules/RedundantCastTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,45 +21,99 @@
using Microsoft.CodeAnalysis.CSharp;
using SonarAnalyzer.Rules.CSharp;

namespace SonarAnalyzer.UnitTest.Rules
namespace SonarAnalyzer.UnitTest.Rules;

[TestClass]
public class RedundantCastTest
{
[TestClass]
public class RedundantCastTest
{
private readonly VerifierBuilder builder = new VerifierBuilder<RedundantCast>();
private readonly VerifierBuilder builder = new VerifierBuilder<RedundantCast>();

[TestMethod]
public void RedundantCast() =>
builder.AddPaths("RedundantCast.cs").Verify();
[TestMethod]
public void RedundantCast() =>
builder.AddPaths("RedundantCast.cs").Verify();

[TestMethod]
public void RedundantCast_CSharp8() =>
builder.AddPaths("RedundantCast.CSharp8.cs").WithOptions(ParseOptionsHelper.FromCSharp8).Verify();
[TestMethod]
public void RedundantCast_CSharp8() =>
builder.AddPaths("RedundantCast.CSharp8.cs").WithOptions(ParseOptionsHelper.FromCSharp8).Verify();

#if NET
[TestMethod]
public void RedundantCast_CSharp9() =>
builder.AddPaths("RedundantCast.CSharp9.cs").WithOptions(ParseOptionsHelper.FromCSharp9).Verify();
[TestMethod]
public void RedundantCast_CSharp9() =>
builder.AddPaths("RedundantCast.CSharp9.cs").WithOptions(ParseOptionsHelper.FromCSharp9).Verify();
#endif

[TestMethod]
public void RedundantCast_CodeFix() =>
builder.AddPaths("RedundantCast.cs").WithCodeFix<RedundantCastCodeFix>().WithCodeFixedPaths("RedundantCast.Fixed.cs").VerifyCodeFix();
[TestMethod]
public void RedundantCast_CodeFix() =>
builder.AddPaths("RedundantCast.cs").WithCodeFix<RedundantCastCodeFix>().WithCodeFixedPaths("RedundantCast.Fixed.cs").VerifyCodeFix();

[TestMethod]
public void RedundantCast_DefaultLiteral() =>
builder.AddSnippet(@"
using System;
public static class MyClass
{
public static void RunAction(Action action)
[TestMethod]
public void RedundantCast_DefaultLiteral() =>
builder.AddSnippet("""
using System;
public static class MyClass
{
public static void RunAction(Action action)
{
bool myBool = (bool)default; // FN - the cast is unneeded
RunFunc(() => { action(); return default; }, (bool)default); // should not raise because of the generic the cast is mandatory
RunFunc<bool>(() => { action(); return default; }, (bool)default); // FN - the cast is unneeded
}

public static T RunFunc<T>(Func<T> func, T returnValue = default) => returnValue;
}
""").WithLanguageVersion(LanguageVersion.CSharp7_1).Verify();

private static IEnumerable<object[]> NullableTestData => new[]
{
bool myBool = (bool)default; // FN - the cast is unneeded
RunFunc(() => { action(); return default; }, (bool)default); // should not raise because of the generic the cast is mandatory
RunFunc<bool>(() => { action(); return default; }, (bool)default); // FN - the cast is unneeded
}
new object[] { """_ = (string)"Test";""", false, false },
new object[] { """_ = (string?)"Test";""", true, false },
new object[] { """_ = (string)null;""", true, true },
new object[] { """_ = (string?)null;""", true, true },
new object[] { """_ = (string)nullable;""", true, false },
new object[] { """_ = (string?)nullable;""", false, false },
new object[] { """_ = (string)nonNullable;""", false, false },
new object[] { """_ = (string?)nonNullable;""", true, false },
new object[] { """if (nullable != null) _ = (string)nullable;""", false, false },
new object[] { """if (nullable != null) _ = (string?)nullable;""", true, false },
new object[] { """if (nonNullable == null) _ = (string)nonNullable;""", true, false },
new object[] { """if (nonNullable == null) _ = (string?)nonNullable;""", false, false },
};

private static IEnumerable<object[]> NullableTestDataWithFlowState =>
NullableTestData.Select(x => new[] { x[0], x[1] });

public static T RunFunc<T>(Func<T> func, T returnValue = default) => returnValue;
}").WithLanguageVersion(LanguageVersion.CSharp7_1).Verify();
private static IEnumerable<object[]> NullableTestDataWithoutFlowState =>
NullableTestData.Select(x => new[] { x[0], x[2] });

[TestMethod]
[DynamicData(nameof(NullableTestDataWithFlowState))]
public void RedundantCast_NullableEnabled(string snippet, bool compliant)
=> VerifyNullableTests(snippet, "enable", compliant);

[TestMethod]
[DynamicData(nameof(NullableTestDataWithFlowState))]
public void RedundantCast_NullableWarnings(string snippet, bool compliant)
=> VerifyNullableTests(snippet, "enable warnings", compliant);

[TestMethod]
[DynamicData(nameof(NullableTestDataWithoutFlowState))]
public void RedundantCast_NullableDisabled(string snippet, bool compliant)
=> VerifyNullableTests(snippet, "disable", compliant);

[TestMethod]
[DynamicData(nameof(NullableTestDataWithoutFlowState))]
public void RedundantCast_NullableAnnotations(string snippet, bool compliant)
=> VerifyNullableTests(snippet, "enable annotations", compliant);

private void VerifyNullableTests(string snippet, string nullableContext, bool compliant)
{
var code = $$"""
#nullable {{nullableContext}}
void Test(string nonNullable, string? nullable)
{
{{snippet}} // {{compliant switch { true => "Compliant", false => "Noncompliant" }}}
}
""";
builder.AddSnippet(code).WithTopLevelStatements().Verify();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,52 +8,6 @@ namespace Tests.Diagnostics
// https://github.com/SonarSource/sonar-dotnet/issues/3273
public class CastOnNullable
{
public void Simple(string nonNullable, string? nullable)
{
_ = (string)"Test"; // Noncompliant
_ = (string?)"Test"; // Compliant
_ = (string)null; // Compliant
_ = (string?)null; // Compliant
_ = (string)nullable; // Compliant
_ = (string?)nullable; // Noncompliant
_ = (string)nonNullable; // Noncompliant
_ = (string?)nonNullable; // Compliant
if (nullable != null)
{
_ = (string)nullable; // Noncompliant
_ = (string?)nullable; // Compliant
}
if (nonNullable == null)
{
_ = (string)nonNullable; // Compliant
_ = (string?)nonNullable; // Noncompliant
}
}

#nullable disable
public void NullableDisabled(string nonNullable, string? nullable)
{
_ = (string)"Test"; // Noncompliant
_ = (string?)"Test"; // Noncompliant
_ = (string)null; // Compliant
_ = (string?)null; // Compliant
_ = (string)nullable; // Noncompliant
_ = (string?)nullable; // Noncompliant
_ = (string)nonNullable; // Noncompliant
_ = (string?)nonNullable; // Noncompliant
if (nullable != null)
{
_ = (string)nullable; // Noncompliant
_ = (string?)nullable; // Noncompliant
}
if (nonNullable == null)
{
_ = (string)nonNullable; // Noncompliant
_ = (string?)nonNullable; // Noncompliant
}
}
#nullable enable

public static IEnumerable<string> Array()
{
var nullableStrings = new string?[] { "one", "two", null, "three" };
Expand Down

0 comments on commit cbf178b

Please sign in to comment.