Skip to content

Commit

Permalink
Fixing xUnit1044/1045/1046/1047 for Index/Range for v3 projects
Browse files Browse the repository at this point in the history
  • Loading branch information
bradwilson committed Jan 31, 2025
1 parent a08f8a7 commit 58192b4
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ public void TestMethod() {
[InlineData("new Dictionary<string, List<string>>()", "Dictionary<string, List<string>>")]
#if NET6_0_OR_GREATER
[InlineData("DateOnly.MinValue", "DateOnly")]
[InlineData("Index.Start", "Index")]
[InlineData("Range.All", "Range")]
[InlineData("TimeOnly.MinValue", "TimeOnly")]
#endif
[InlineData("Guid.Empty", "Guid")]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -207,33 +207,6 @@ public enum SerializableEnumeration {{ Zero }}
await Verify.VerifyAnalyzer(source);
}

[Theory]
[MemberData(nameof(TheoryDataMembers), "Guid")]
[MemberData(nameof(TheoryDataMembers), "Guid?")]
[MemberData(nameof(TheoryDataMembers), "Uri")]
public async Task GivenTheory_WithTypeOnlySupportedInV3_TriggersInV2_DoesNotTriggerInV3(
string member,
string attribute,
string type)
{
var source = string.Format(/* lang=c#-test */ """
using System;
using Xunit;
public class TestClass {{
{0}
[Theory]
[{{|#0:{1}|}}]
public void TestMethod({2} parameter) {{ }}
}}
""", member, attribute, type);
var expectedV2 = Verify.Diagnostic(type == "Uri" ? "xUnit1045" : "xUnit1044").WithLocation(0).WithArguments(type);

await Verify.VerifyAnalyzerV2(source, expectedV2);
await Verify.VerifyAnalyzerV3(source);
}

[Theory]
[MemberData(nameof(TheoryDataMembers), "IXunitSerializable")]
[MemberData(nameof(TheoryDataMembers), "IXunitSerializable[]")]
Expand Down Expand Up @@ -434,6 +407,36 @@ public async Task GivenTheory_WithNonSerializableTheoryDataClass_WithDiscoveryEn

public sealed class X1044_AvoidUsingTheoryDataTypeArgumentsThatAreNotSerializable : TheoryDataTypeArgumentsShouldBeSerializableTests
{
[Theory]
[MemberData(nameof(TheoryDataMembers), "Guid")]
[MemberData(nameof(TheoryDataMembers), "Guid?")]
#if NET6_0_OR_GREATER
[MemberData(nameof(TheoryDataMembers), "Index")]
[MemberData(nameof(TheoryDataMembers), "Range")]
#endif
public async Task GivenTheory_WithTypeOnlySupportedInV3_TriggersInV2_DoesNotTriggerInV3(
string member,
string attribute,
string type)
{
var source = string.Format(/* lang=c#-test */ """
using System;
using Xunit;
public class TestClass {{
{0}
[Theory]
[{{|#0:{1}|}}]
public void TestMethod({2} parameter) {{ }}
}}
""", member, attribute, type);
var expectedV2 = Verify.Diagnostic("xUnit1044").WithLocation(0).WithArguments(type);

await Verify.VerifyAnalyzerV2(source, expectedV2);
await Verify.VerifyAnalyzerV3(source);
}

[Theory]
[MemberData(nameof(TheoryDataMembers), "Delegate")]
[MemberData(nameof(TheoryDataMembers), "Delegate[]")]
Expand Down Expand Up @@ -492,6 +495,32 @@ public async Task GivenTheory_WithNonSerializableTheoryDataClass_Triggers(

public sealed class X1045_AvoidUsingTheoryDataTypeArgumentsThatMightNotBeSerializable : TheoryDataTypeArgumentsShouldBeSerializableTests
{
[Theory]
[MemberData(nameof(TheoryDataMembers), "Uri")]
[MemberData(nameof(TheoryDataMembers), "Uri?")]
public async Task GivenTheory_WithTypeOnlySupportedInV3_TriggersInV2_DoesNotTriggerInV3(
string member,
string attribute,
string type)
{
var source = string.Format(/* lang=c#-test */ """
using System;
using Xunit;
public class TestClass {{
{0}
[Theory]
[{{|#0:{1}|}}]
public void TestMethod({2} parameter) {{ }}
}}
""", member, attribute, type);
var expectedV2 = Verify.Diagnostic("xUnit1045").WithLocation(0).WithArguments(type);

await Verify.VerifyAnalyzerV2(LanguageVersion.CSharp9, source, expectedV2);
await Verify.VerifyAnalyzerV3(LanguageVersion.CSharp9, source);
}

[Theory]
[MemberData(nameof(TheoryDataMembers), "object")]
[MemberData(nameof(TheoryDataMembers), "object[]")]
Expand Down
8 changes: 4 additions & 4 deletions src/xunit.analyzers/Utility/SerializabilityAnalyzer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,10 @@ public Serializability AnalayzeSerializability(

if (xunitContext.HasV3References)
{
if (type.Equals(typeSymbols.Guid, SymbolEqualityComparer.Default))
return Serializability.AlwaysSerializable;

if (type.Equals(typeSymbols.Uri, SymbolEqualityComparer.Default))
if (type.Equals(typeSymbols.Guid, SymbolEqualityComparer.Default)
|| type.Equals(typeSymbols.Index, SymbolEqualityComparer.Default)
|| type.Equals(typeSymbols.Range, SymbolEqualityComparer.Default)
|| type.Equals(typeSymbols.Uri, SymbolEqualityComparer.Default))
return Serializability.AlwaysSerializable;
}

Expand Down
6 changes: 6 additions & 0 deletions src/xunit.analyzers/Utility/SerializableTypeSymbols.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ public sealed class SerializableTypeSymbols
readonly Lazy<INamedTypeSymbol?> dateOnly;
readonly Lazy<INamedTypeSymbol?> dateTimeOffset;
readonly Lazy<INamedTypeSymbol?> guid;
readonly Lazy<INamedTypeSymbol?> index;
readonly Lazy<INamedTypeSymbol?> iXunitSerializable;
readonly Lazy<INamedTypeSymbol?> range;
readonly Lazy<INamedTypeSymbol?> theoryDataBaseType;
readonly Dictionary<int, INamedTypeSymbol> theoryDataTypes;
readonly Lazy<INamedTypeSymbol?> timeOnly;
Expand All @@ -37,7 +39,9 @@ public sealed class SerializableTypeSymbols
dateOnly = new(() => TypeSymbolFactory.DateOnly(compilation));
dateTimeOffset = new(() => TypeSymbolFactory.DateTimeOffset(compilation));
guid = new(() => TypeSymbolFactory.Guid(compilation));
index = new(() => TypeSymbolFactory.Index(compilation));
iXunitSerializable = new(() => xunitContext.Common.IXunitSerializableType);
range = new(() => TypeSymbolFactory.Range(compilation));
// For v2 and early versions of v3, the base type is "TheoryData" (non-generic). For later versions
// of v3, it's "TheoryDataBase<TTheoryDataRow, TRawDataRow>". In either case, getting "TheoryData<T>"
// and going up one layer gets us the type we want to be able to search for.
Expand Down Expand Up @@ -77,8 +81,10 @@ public sealed class SerializableTypeSymbols
public INamedTypeSymbol? DateOnly => dateOnly.Value;
public INamedTypeSymbol? DateTimeOffset => dateTimeOffset.Value;
public INamedTypeSymbol? Guid => guid.Value;
public INamedTypeSymbol? Index => index.Value;
public INamedTypeSymbol? IXunitSerializable => iXunitSerializable.Value;
public INamedTypeSymbol MemberDataAttribute { get; }
public INamedTypeSymbol? Range => range.Value;
public INamedTypeSymbol TheoryAttribute { get; }
public INamedTypeSymbol? TheoryDataBaseType => theoryDataBaseType.Value;
public INamedTypeSymbol? TimeOnly => timeOnly.Value;
Expand Down
6 changes: 6 additions & 0 deletions src/xunit.analyzers/Utility/TypeSymbolFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,9 @@ public static INamedTypeSymbol IEnumerableOfT(Compilation compilation) =>
public static INamedTypeSymbol? IMethodInfo_V2(Compilation compilation) =>
Guard.ArgumentNotNull(compilation).GetTypeByMetadataName(Constants.Types.Xunit.IMethodInfo_V2);

public static INamedTypeSymbol? Index(Compilation compilation) =>
Guard.ArgumentNotNull(compilation).GetTypeByMetadataName("System.Index");

public static INamedTypeSymbol? InlineDataAttribute(Compilation compilation) =>
Guard.ArgumentNotNull(compilation).GetTypeByMetadataName(Constants.Types.Xunit.InlineDataAttribute);

Expand Down Expand Up @@ -316,6 +319,9 @@ public static IArrayTypeSymbol ObjectArray(Compilation compilation) =>
public static INamedTypeSymbol? OptionalAttribute(Compilation compilation) =>
Guard.ArgumentNotNull(compilation).GetTypeByMetadataName("System.Runtime.InteropServices.OptionalAttribute");

public static INamedTypeSymbol? Range(Compilation compilation) =>
Guard.ArgumentNotNull(compilation).GetTypeByMetadataName("System.Range");

public static INamedTypeSymbol? Record(Compilation compilation) =>
Guard.ArgumentNotNull(compilation).GetTypeByMetadataName(Constants.Types.Xunit.Record);

Expand Down

0 comments on commit 58192b4

Please sign in to comment.