Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix DateOnly / TimeOnly parameters is TestCaseUsage #821

Merged
merged 6 commits into from
Jan 8, 2025
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion appveyor.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
image: Visual Studio 2022

environment:
CLI_CHANNEL: 6.0.1xx
CLI_CHANNEL: 8.0

install:
- ps: $env:DOTNET_INSTALL_DIR = "$pwd\.dotnetsdk"
Expand Down
2 changes: 1 addition & 1 deletion global.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"sdk": {
"version": "6.0.100",
"version": "8.0.100",
"rollForward" : "latestFeature",
"allowPrerelease": false
}
Expand Down
8 changes: 4 additions & 4 deletions src/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@

<ItemGroup>
<PackageReference Include="StyleCop.Analyzers.Unstable" Version="1.2.0.556" PrivateAssets="all" />
<PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="7.0.4" PrivateAssets="all" />
<PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="8.0.0" PrivateAssets="all" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.CodeStyle" Version="3.11.0" PrivateAssets="all" />
<PackageReference Include="CSharpIsNullAnalyzer" Version="0.1.593" PrivateAssets="all" />
</ItemGroup>
Expand All @@ -31,9 +31,9 @@
<GenerateNullableAttributes>false</GenerateNullableAttributes>
</PropertyGroup>

<!-- Get nullability information from .NET7.0 when compiling for non net7.0 targets -->
<ItemGroup Condition="'$(TargetFramework)' != 'net7.0'">
<PackageDownload Include="Microsoft.NETCore.App.Ref" Version="[7.0.0]" />
<!-- Get nullability information from .NET8.0 when compiling for non net8.0 targets -->
<ItemGroup Condition="'$(TargetFramework)' != 'net8.0'">
<PackageDownload Include="Microsoft.NETCore.App.Ref" Version="[8.0.0]" />
<PackageReference Include="TunnelVisionLabs.ReferenceAssemblyAnnotator" Version="1.0.0-alpha.160" PrivateAssets="all" />
</ItemGroup>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ public void OneTimeSetUp()
{
// Find the NetAnalyzers assembly (note version should match the one referenced)
string netAnalyzersPath = Path.Combine(PathHelper.GetNuGetPackageDirectory(),
"microsoft.codeanalysis.netanalyzers/7.0.4/analyzers/dotnet/cs/Microsoft.CodeAnalysis.CSharp.NetAnalyzers.dll");
"microsoft.codeanalysis.netanalyzers/8.0.0/analyzers/dotnet/cs/Microsoft.CodeAnalysis.CSharp.NetAnalyzers.dll");
Assembly netAnalyzerAssembly = Assembly.LoadFrom(netAnalyzersPath);
Type analyzerType = netAnalyzerAssembly.GetType("Microsoft.CodeQuality.CSharp.Analyzers.Maintainability.CSharpAvoidUninstantiatedInternalClasses", true)!;
this.analyzer = (DiagnosticAnalyzer)Activator.CreateInstance(analyzerType)!;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ public void OneTimeSetUp()
{
// Find the NetAnalyzers assembly (note version should match the one referenced)
string netAnalyzersPath = Path.Combine(PathHelper.GetNuGetPackageDirectory(),
"microsoft.codeanalysis.netanalyzers/7.0.4/analyzers/dotnet/cs/Microsoft.CodeAnalysis.CSharp.NetAnalyzers.dll");
"microsoft.codeanalysis.netanalyzers/8.0.0/analyzers/dotnet/cs/Microsoft.CodeAnalysis.NetAnalyzers.dll");
Assembly netAnalyzerAssembly = Assembly.LoadFrom(netAnalyzersPath);
Type analyzerType = netAnalyzerAssembly.GetType("Microsoft.CodeQuality.CSharp.Analyzers.ApiDesignGuidelines.CSharpTypesThatOwnDisposableFieldsShouldBeDisposableAnalyzer", true)!;
Type analyzerType = netAnalyzerAssembly.GetType("Microsoft.CodeQuality.Analyzers.ApiDesignGuidelines.TypesThatOwnDisposableFieldsShouldBeDisposableAnalyzer", true)!;
this.analyzer = (DiagnosticAnalyzer)Activator.CreateInstance(analyzerType)!;

this.analyzer = new DefaultEnabledAnalyzer(this.analyzer);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,12 @@ private static IEnumerable<TestCaseData> GetTestData()
SetName("CanAssignToWhenParameterIsVersionAndArgumentIsValidString");
yield return new TestCaseData("\"a.b.c.d\"", "Version", "object", Is.True).
SetName("CanAssignToWhenParameterIsVersionAndArgumentIsInValidString");
#if NET8_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)>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,17 @@ private static IEnumerable<TestCaseData> SpecialConversions
}
}

#if NET8_0_OR_GREATER
private static IEnumerable<TestCaseData> SpecialConversions_NET8
{
get
{
yield return new TestCaseData("2019-10-10", typeof(DateOnly));
yield return new TestCaseData("23:59:59", typeof(TimeOnly));
}
}
#endif

[Test]
public void VerifySupportedDiagnostics()
{
Expand Down Expand Up @@ -757,7 +768,7 @@ public void TestWithGenericParameter<T>(T arg1) { }
}

#if NUNIT4
#if NET6_0_OR_GREATER
#if NET8_0_OR_GREATER
[Test]
public void AnalyzeWhenArgumentIsCorrectGenericTypeParameter()
{
Expand Down Expand Up @@ -824,6 +835,18 @@ public void TestWithGenericParameter<T>(T arg1) { }
}");
RoslynAssert.Valid(this.analyzer, testCode);
}

[TestCaseSource(nameof(SpecialConversions_NET8))]
public void AnalyzeWhenArgumentIsSpecialConversionNET8(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

[Test]
Expand Down
2 changes: 1 addition & 1 deletion src/nunit.analyzers.tests/nunit.analyzers.tests.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<RootNamespace>NUnit.Analyzers.Tests</RootNamespace>
<TargetFrameworks>net6.0;net462</TargetFrameworks>
<TargetFrameworks>net8.0;net462</TargetFrameworks>
<NUnitVersion Condition="'$(NUnitVersion)'==''">4</NUnitVersion>
</PropertyGroup>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ protected override (ExpressionSyntax? actual, ExpressionSyntax? constraintExpres
}
else if (expected is PatternSyntax pattern)
{
constraintExpression = this.ConvertPattern(
constraintExpression = ConvertPattern(
SyntaxFactory.IdentifierName(NUnitFrameworkConstants.NameOfIs),
pattern);
}
Expand Down Expand Up @@ -91,7 +91,7 @@ private static (ExpressionSyntax? actual, ExpressionOrPatternSyntax? expected) G
/// supported-pattern or supported-pattern,
/// supported-pattern and supported-pattern.
/// </remarks>
private InvocationExpressionSyntax? ConvertPattern(ExpressionSyntax member, PatternSyntax pattern)
manfred-brands marked this conversation as resolved.
Show resolved Hide resolved
private static InvocationExpressionSyntax? ConvertPattern(ExpressionSyntax member, PatternSyntax pattern)
{
if (pattern is ConstantPatternSyntax constantPattern)
{
Expand Down Expand Up @@ -125,7 +125,7 @@ private static (ExpressionSyntax? actual, ExpressionOrPatternSyntax? expected) G
}
else if (pattern is UnaryPatternSyntax unaryPattern && unaryPattern.IsKind(SyntaxKind.NotPattern))
{
return this.ConvertPattern(
return ConvertPattern(
SyntaxFactory.MemberAccessExpression(
SyntaxKind.SimpleMemberAccessExpression,
member,
Expand All @@ -143,11 +143,11 @@ private static (ExpressionSyntax? actual, ExpressionOrPatternSyntax? expected) G

if (constraint is not null)
{
InvocationExpressionSyntax? leftExpression = this.ConvertPattern(member, binaryPattern.Left);
InvocationExpressionSyntax? leftExpression = ConvertPattern(member, binaryPattern.Left);

if (leftExpression is not null)
{
return this.ConvertPattern(
return ConvertPattern(
SyntaxFactory.MemberAccessExpression(
SyntaxKind.SimpleMemberAccessExpression,
leftExpression,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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>? typeConverter)> IntrinsicTypeConverters =
private static readonly List<(string fullName, Lazy<TypeConverter>? typeConverter)> IntrinsicTypeConverters =
new()
{
(typeof(bool), new Lazy<TypeConverter>(() => new BooleanConverter())),
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated mapping per TypeConverter updates:
https://github.com/dotnet/runtime/blob/main/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/ReflectTypeDescriptionProvider.cs#L154

Had to update it to string from Type, as netstandard2.0 does not have DateTime/DateOnly/etc types.

(typeof(byte), new Lazy<TypeConverter>(() => new ByteConverter())),
(typeof(sbyte), new Lazy<TypeConverter>(() => new SByteConverter())),
(typeof(char), new Lazy<TypeConverter>(() => new CharConverter())),
(typeof(double), new Lazy<TypeConverter>(() => new DoubleConverter())),
(typeof(string), new Lazy<TypeConverter>(() => new StringConverter())),
(typeof(int), new Lazy<TypeConverter>(() => new Int32Converter())),
(typeof(short), new Lazy<TypeConverter>(() => new Int16Converter())),
(typeof(long), new Lazy<TypeConverter>(() => new Int64Converter())),
(typeof(float), new Lazy<TypeConverter>(() => new SingleConverter())),
(typeof(ushort), new Lazy<TypeConverter>(() => new UInt16Converter())),
(typeof(uint), new Lazy<TypeConverter>(() => new UInt32Converter())),
(typeof(ulong), new Lazy<TypeConverter>(() => new UInt64Converter())),
(typeof(CultureInfo), null),
(typeof(DateTime), new Lazy<TypeConverter>(() => new DateTimeConverter())),
(typeof(DateTimeOffset), new Lazy<TypeConverter>(() => new DateTimeOffsetConverter())),
(typeof(decimal), new Lazy<TypeConverter>(() => new DecimalConverter())),
(typeof(TimeSpan), new Lazy<TypeConverter>(() => new TimeSpanConverter())),
(typeof(Guid), new Lazy<TypeConverter>(() => new GuidConverter())),
(typeof(Uri), new Lazy<TypeConverter>(() => new UriTypeConverter())),
(typeof(Version), null),
("System.Boolean", new Lazy<TypeConverter>(() => new BooleanConverter())),
("System.Byte", new Lazy<TypeConverter>(() => new ByteConverter())),
("System.SByte", new Lazy<TypeConverter>(() => new SByteConverter())),
("System.Char", new Lazy<TypeConverter>(() => new CharConverter())),
("System.Double", new Lazy<TypeConverter>(() => new DoubleConverter())),
("System.String", new Lazy<TypeConverter>(() => new StringConverter())),
("System.Int32", new Lazy<TypeConverter>(() => new Int32Converter())),
("System.Int16", new Lazy<TypeConverter>(() => new Int16Converter())),
("System.Int64", new Lazy<TypeConverter>(() => new Int64Converter())),
("System.Int128", null),
("System.Half", null),
("System.Single", new Lazy<TypeConverter>(() => new SingleConverter())),
("System.UInt16", new Lazy<TypeConverter>(() => new UInt16Converter())),
("System.UInt32", new Lazy<TypeConverter>(() => new UInt32Converter())),
("System.UInt64", new Lazy<TypeConverter>(() => new UInt64Converter())),
("System.UInt128", null),
("System.Globalization.CultureInfo", null),
("System.DateTime", new Lazy<TypeConverter>(() => new DateTimeConverter())),
("System.DateTimeOffset", new Lazy<TypeConverter>(() => new DateTimeOffsetConverter())),
("System.DateOnly", null),
("System.Decimal", new Lazy<TypeConverter>(() => new DecimalConverter())),
("System.TimeOnly", null),
("System.TimeSpan", new Lazy<TypeConverter>(() => new TimeSpanConverter())),
("System.Guid", new Lazy<TypeConverter>(() => new GuidConverter())),
("System.Uri", new Lazy<TypeConverter>(() => new UriTypeConverter())),
("System.Version", null)
};

internal static bool CanAssignTo(this TypedConstant @this, ITypeSymbol target, Compilation compilation,
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -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<TypedConstant> AdjustArguments(this ImmutableArray<TypedConstant> attributePositionalArguments)
Expand Down
1 change: 0 additions & 1 deletion src/nunit.analyzers/nunit.analyzers.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
<PackageReference Include="Nullable" Version="1.3.1" PrivateAssets="all" />
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.4" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="3.11.0" />
<PackageReference Include="System.ComponentModel.TypeConverter" Version="4.3.0" />
manfred-brands marked this conversation as resolved.
Show resolved Hide resolved
</ItemGroup>

</Project>
Loading