diff --git a/src/nunit.analyzers.tests/Extensions/AttributeArgumentTypedConstantExtensionsTests.cs b/src/nunit.analyzers.tests/Extensions/AttributeArgumentTypedConstantExtensionsTests.cs index 923a5f34..71d2d019 100644 --- a/src/nunit.analyzers.tests/Extensions/AttributeArgumentTypedConstantExtensionsTests.cs +++ b/src/nunit.analyzers.tests/Extensions/AttributeArgumentTypedConstantExtensionsTests.cs @@ -99,6 +99,12 @@ private static IEnumerable GetTestData() SetName("CanAssignToWhenParameterIsVersionAndArgumentIsValidString"); yield return new TestCaseData("\"a.b.c.d\"", "Version", "object", Is.True). SetName("CanAssignToWhenParameterIsVersionAndArgumentIsInValidString"); +#if NET6_0_OR_GREATER + yield return new TestCaseData("\"00:03:00\"", "TimeOnly", "string", Is.True). + SetName("CanAssignToWhenParameterIsTimeSpanAndArgumentIsValidString"); + yield return new TestCaseData("\"2020-05-08\"", "DateOnly", "string", Is.True). + SetName("CanAssignToWhenParameterIsDateTimeAndArgumentIsValidString"); +#endif } private static async Task<(TypedConstant argumentConstant, ITypeSymbol typeSymbol, Compilation compilation)> diff --git a/src/nunit.analyzers.tests/TestCaseUsage/TestCaseUsageAnalyzerTests.cs b/src/nunit.analyzers.tests/TestCaseUsage/TestCaseUsageAnalyzerTests.cs index 499a8917..f394673b 100644 --- a/src/nunit.analyzers.tests/TestCaseUsage/TestCaseUsageAnalyzerTests.cs +++ b/src/nunit.analyzers.tests/TestCaseUsage/TestCaseUsageAnalyzerTests.cs @@ -29,6 +29,17 @@ private static IEnumerable SpecialConversions } } +#if NET6_0_OR_GREATER + private static IEnumerable SpecialConversions_NET6 + { + get + { + yield return new TestCaseData("2019-10-10", typeof(DateOnly)); + yield return new TestCaseData("23:59:59", typeof(TimeOnly)); + } + } +#endif + [Test] public void VerifySupportedDiagnostics() { @@ -756,6 +767,20 @@ public void TestWithGenericParameter(T arg1) { } RoslynAssert.Valid(this.analyzer, testCode); } +#if NET6_0_OR_GREATER + [TestCaseSource(nameof(SpecialConversions_NET6))] + public void AnalyzeWhenArgumentIsSpecialConversionNET6(string value, Type targetType) + { + var testCode = TestUtility.WrapClassInNamespaceAndAddUsing($@" + public sealed class AnalyzeWhenArgumentIsSpecialConversion + {{ + [TestCase(""{value}"")] + public void Test({targetType.Name} a) {{ }} + }}"); + RoslynAssert.Valid(this.analyzer, testCode); + } +#endif + #if NUNIT4 #if NET6_0_OR_GREATER [Test] diff --git a/src/nunit.analyzers/Extensions/AttributeArgumentTypedConstantExtensions.cs b/src/nunit.analyzers/Extensions/AttributeArgumentTypedConstantExtensions.cs index 60d3e035..9fa71f71 100644 --- a/src/nunit.analyzers/Extensions/AttributeArgumentTypedConstantExtensions.cs +++ b/src/nunit.analyzers/Extensions/AttributeArgumentTypedConstantExtensions.cs @@ -26,32 +26,37 @@ internal static class AttributeArgumentTypedConstantExtensions // Intrinsic type converters for types // https://github.com/dotnet/runtime/blob/master/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/ReflectTypeDescriptionProvider.cs - // For converters that exist in .NET Standard 1.6 we use the converter. + // For converters that exist in .NET Standard 2.0 we use the converter. // Otherwise, we assume that the converter exists and it can convert the value. - private static readonly List<(Type type, Lazy? typeConverter)> IntrinsicTypeConverters = + private static readonly List<(string fullName, Lazy? typeConverter)> IntrinsicTypeConverters = new() { - (typeof(bool), new Lazy(() => new BooleanConverter())), - (typeof(byte), new Lazy(() => new ByteConverter())), - (typeof(sbyte), new Lazy(() => new SByteConverter())), - (typeof(char), new Lazy(() => new CharConverter())), - (typeof(double), new Lazy(() => new DoubleConverter())), - (typeof(string), new Lazy(() => new StringConverter())), - (typeof(int), new Lazy(() => new Int32Converter())), - (typeof(short), new Lazy(() => new Int16Converter())), - (typeof(long), new Lazy(() => new Int64Converter())), - (typeof(float), new Lazy(() => new SingleConverter())), - (typeof(ushort), new Lazy(() => new UInt16Converter())), - (typeof(uint), new Lazy(() => new UInt32Converter())), - (typeof(ulong), new Lazy(() => new UInt64Converter())), - (typeof(CultureInfo), null), - (typeof(DateTime), new Lazy(() => new DateTimeConverter())), - (typeof(DateTimeOffset), new Lazy(() => new DateTimeOffsetConverter())), - (typeof(decimal), new Lazy(() => new DecimalConverter())), - (typeof(TimeSpan), new Lazy(() => new TimeSpanConverter())), - (typeof(Guid), new Lazy(() => new GuidConverter())), - (typeof(Uri), new Lazy(() => new UriTypeConverter())), - (typeof(Version), null), + ("System.Boolean", new Lazy(() => new BooleanConverter())), + ("System.Byte", new Lazy(() => new ByteConverter())), + ("System.SByte", new Lazy(() => new SByteConverter())), + ("System.Char", new Lazy(() => new CharConverter())), + ("System.Double", new Lazy(() => new DoubleConverter())), + ("System.String", new Lazy(() => new StringConverter())), + ("System.Int32", new Lazy(() => new Int32Converter())), + ("System.Int16", new Lazy(() => new Int16Converter())), + ("System.Int64", new Lazy(() => new Int64Converter())), + ("System.Int128", null), + ("System.Half", null), + ("System.Single", new Lazy(() => new SingleConverter())), + ("System.UInt16", new Lazy(() => new UInt16Converter())), + ("System.UInt32", new Lazy(() => new UInt32Converter())), + ("System.UInt64", new Lazy(() => new UInt64Converter())), + ("System.UInt128", null), + ("System.Globalization.CultureInfo", null), + ("System.DateTime", new Lazy(() => new DateTimeConverter())), + ("System.DateTimeOffset", new Lazy(() => new DateTimeOffsetConverter())), + ("System.DateOnly", null), + ("System.Decimal", new Lazy(() => new DecimalConverter())), + ("System.TimeOnly", null), + ("System.TimeSpan", new Lazy(() => new TimeSpanConverter())), + ("System.Guid", new Lazy(() => new GuidConverter())), + ("System.Uri", new Lazy(() => new UriTypeConverter())), + ("System.Version", null) }; internal static bool CanAssignTo(this TypedConstant @this, ITypeSymbol target, Compilation compilation, @@ -214,7 +219,7 @@ private static bool CanBeTranslatedByTypeConverter( Compilation compilation) { var typeName = targetTypeSymbol.GetFullMetadataName(); - var targetType = IntrinsicTypeConverters.FirstOrDefault(t => t.type.FullName == typeName); + var targetType = IntrinsicTypeConverters.FirstOrDefault(t => t.fullName == typeName); if (targetType != default) { @@ -254,7 +259,7 @@ private static bool CanBeTranslatedByTypeConverter( return false; } -#endregion + #endregion #pragma warning disable SA1202 // Elements should be ordered by access. Prefer grouping internal static ImmutableArray AdjustArguments(this ImmutableArray attributePositionalArguments) diff --git a/src/nunit.analyzers/nunit.analyzers.csproj b/src/nunit.analyzers/nunit.analyzers.csproj index 993785a5..45f92b31 100644 --- a/src/nunit.analyzers/nunit.analyzers.csproj +++ b/src/nunit.analyzers/nunit.analyzers.csproj @@ -12,7 +12,6 @@ -