From c87166b9e4c263dece2cfb191436d302f4d2ea91 Mon Sep 17 00:00:00 2001 From: Christoph Bersch Date: Mon, 13 Jan 2025 13:45:29 +0100 Subject: [PATCH] Fix Nunit1029 for generic test method (#832) --- .../TestCaseSourceUsesStringAnalyzerTests.cs | 24 +++++++++++++++++++ .../TestCaseSourceUsesStringAnalyzer.cs | 6 ++--- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/src/nunit.analyzers.tests/TestCaseSourceUsage/TestCaseSourceUsesStringAnalyzerTests.cs b/src/nunit.analyzers.tests/TestCaseSourceUsage/TestCaseSourceUsesStringAnalyzerTests.cs index 66564bcc..7228544a 100644 --- a/src/nunit.analyzers.tests/TestCaseSourceUsage/TestCaseSourceUsesStringAnalyzerTests.cs +++ b/src/nunit.analyzers.tests/TestCaseSourceUsage/TestCaseSourceUsesStringAnalyzerTests.cs @@ -659,6 +659,30 @@ static IEnumerable TestData() RoslynAssert.Valid(analyzer, testCode); } +#if NUNIT4 + [Test] + public void AnalyzeWhenNumberOfParametersOfGenericTestIsNotEvidentFromTestSource() + { + var testCode = TestUtility.WrapClassInNamespaceAndAddUsing(@" + [TestFixture] + public class AnalyzeWhenTestSourceProvidesDataWithSingleTypeArgs + { + [TestCaseSource(nameof(TestData))] + public void Method() + { + Assert.That(typeof(T).IsValueType, Is.True); + } + + static IEnumerable TestData() + { + yield return new TestCaseData { TypeArgs = new Type[] { typeof(int) } }; + } + }", additionalUsings: "using System.Collections.Generic;"); + + RoslynAssert.Valid(analyzer, testCode); + } +#endif + [TestCase("IEnumerable", "object", "System.Collections")] [TestCase("IEnumerable", "object", "System.Collections.Generic")] [TestCase("IEnumerable", "TestCaseData", "System.Collections.Generic")] diff --git a/src/nunit.analyzers/TestCaseSourceUsage/TestCaseSourceUsesStringAnalyzer.cs b/src/nunit.analyzers/TestCaseSourceUsage/TestCaseSourceUsesStringAnalyzer.cs index f4593d42..aac639d6 100644 --- a/src/nunit.analyzers/TestCaseSourceUsage/TestCaseSourceUsesStringAnalyzer.cs +++ b/src/nunit.analyzers/TestCaseSourceUsage/TestCaseSourceUsesStringAnalyzer.cs @@ -248,16 +248,16 @@ private static void AnalyzeAttribute( var hasCancelAfterAttribute = testMethod.GetAttributes().Any(a => SymbolEqualityComparer.Default.Equals(a.AttributeClass, cancelAfterType)) || testMethod.ContainingType.GetAttributes().Any(a => SymbolEqualityComparer.Default.Equals(a.AttributeClass, cancelAfterType)); - var (methodRequiredParameters, methodOptionalParameters, methodParamsParameters) = testMethod.GetParameterCounts(hasCancelAfterAttribute, cancellationTokenType); + var (methodRequiredParameters, methodOptionalParameters, _) = testMethod.GetParameterCounts(hasCancelAfterAttribute, cancellationTokenType); if (elementType.SpecialType != SpecialType.System_String && (elementType.SpecialType == SpecialType.System_Object || elementType.IsIEnumerable(out _) || IsOrDerivesFrom(elementType, context.SemanticModel.Compilation.GetTypeByMetadataName(NUnitFrameworkConstants.FullNameOfTypeTestCaseParameters)))) { - // We only know that there is 1 or (likely) more parameters. + // For non-generic methods we only know that there is 1 or (likely) more parameters, for generic methods we even don't know this for sure. // The object could hide an array, possibly with a variable number of elements: TestCaseData.Argument. // Potentially we could examine the body of the TestCaseSource to see if we can determine the exact amount. // For complex method that is certainly beyond the scope of this. - if (methodRequiredParameters + methodOptionalParameters < 1) + if (methodRequiredParameters + methodOptionalParameters < 1 && !testMethod.IsGenericMethod) { context.ReportDiagnostic(Diagnostic.Create( mismatchInNumberOfTestMethodParameters,