From 58bfb8f521bb06aa1c0946a58c7ae3b9c27dda1c Mon Sep 17 00:00:00 2001 From: Manfred Brands Date: Wed, 22 Feb 2023 17:51:52 +0800 Subject: [PATCH] TestCaseSource now ignore all classes derived from TestCaseParameters --- .../Constants/NUnitFrameworkConstantsTests.cs | 2 ++ .../TestCaseSourceUsesStringAnalyzerTests.cs | 2 ++ .../Constants/NUnitFrameworkConstants.cs | 1 + .../TestCaseSourceUsesStringAnalyzer.cs | 24 ++++++++++++++++++- 4 files changed, 28 insertions(+), 1 deletion(-) diff --git a/src/nunit.analyzers.tests/Constants/NUnitFrameworkConstantsTests.cs b/src/nunit.analyzers.tests/Constants/NUnitFrameworkConstantsTests.cs index 6a6adc51..7d375796 100644 --- a/src/nunit.analyzers.tests/Constants/NUnitFrameworkConstantsTests.cs +++ b/src/nunit.analyzers.tests/Constants/NUnitFrameworkConstantsTests.cs @@ -6,6 +6,7 @@ using NUnit.Framework; using NUnit.Framework.Constraints; using NUnit.Framework.Interfaces; +using NUnit.Framework.Internal; namespace NUnit.Analyzers.Tests.Constants { @@ -140,6 +141,7 @@ public sealed class NUnitFrameworkConstantsTests (nameof(NUnitFrameworkConstants.FullNameOfTypeISimpleTestBuilder), typeof(ISimpleTestBuilder)), (nameof(NUnitFrameworkConstants.FullNameOfTypeIParameterDataSource), typeof(IParameterDataSource)), (nameof(NUnitFrameworkConstants.FullNameOfTypeTestCaseData), typeof(TestCaseData)), + (nameof(NUnitFrameworkConstants.FullNameOfTypeTestCaseParameters), typeof(TestCaseParameters)), (nameof(NUnitFrameworkConstants.FullNameOfTypeOneTimeSetUpAttribute), typeof(OneTimeSetUpAttribute)), (nameof(NUnitFrameworkConstants.FullNameOfTypeOneTimeTearDownAttribute), typeof(OneTimeTearDownAttribute)), diff --git a/src/nunit.analyzers.tests/TestCaseSourceUsage/TestCaseSourceUsesStringAnalyzerTests.cs b/src/nunit.analyzers.tests/TestCaseSourceUsage/TestCaseSourceUsesStringAnalyzerTests.cs index b3530431..a34e1d93 100644 --- a/src/nunit.analyzers.tests/TestCaseSourceUsage/TestCaseSourceUsesStringAnalyzerTests.cs +++ b/src/nunit.analyzers.tests/TestCaseSourceUsage/TestCaseSourceUsesStringAnalyzerTests.cs @@ -658,6 +658,7 @@ static IEnumerable TestData() [TestCase("IEnumerable", "object", "System.Collections")] [TestCase("IEnumerable", "object", "System.Collections.Generic")] [TestCase("IEnumerable", "TestCaseData", "System.Collections.Generic")] + [TestCase("IEnumerable", "TestCaseParameters", "System.Collections.Generic; using NUnit.Framework.Internal")] [TestCase("IEnumerable", "int", "System.Collections.Generic")] public void NoIssueIsRaisedWhenOneParameterIsExpectedAndTypeCannotBeDetermined(string enumerableType, string testCaseType, string collections) { @@ -681,6 +682,7 @@ public void ShortName(int n) [TestCase("IEnumerable", "object", "System.Collections")] [TestCase("IEnumerable", "object", "System.Collections.Generic")] [TestCase("IEnumerable", "TestCaseData", "System.Collections.Generic")] + [TestCase("IEnumerable", "TestCaseParameters", "System.Collections.Generic; using NUnit.Framework.Internal")] public void NoIssueIsRaisedWhenMultipleParameterAreExpectedAndTypeCannotBeDetermined(string enumerableType, string testCaseType, string collections) { var testCode = TestUtility.WrapClassInNamespaceAndAddUsing($@" diff --git a/src/nunit.analyzers/Constants/NUnitFrameworkConstants.cs b/src/nunit.analyzers/Constants/NUnitFrameworkConstants.cs index 1a78c8a7..f7ed38bb 100644 --- a/src/nunit.analyzers/Constants/NUnitFrameworkConstants.cs +++ b/src/nunit.analyzers/Constants/NUnitFrameworkConstants.cs @@ -108,6 +108,7 @@ public static class NUnitFrameworkConstants public const string FullNameOfTypeValueSourceAttribute = "NUnit.Framework.ValueSourceAttribute"; public const string FullNameOfTypeIParameterDataSource = "NUnit.Framework.Interfaces.IParameterDataSource"; public const string FullNameOfTypeTestCaseData = "NUnit.Framework.TestCaseData"; + public const string FullNameOfTypeTestCaseParameters = "NUnit.Framework.Internal.TestCaseParameters"; public const string FullNameOfTypeOneTimeSetUpAttribute = "NUnit.Framework.OneTimeSetUpAttribute"; public const string FullNameOfTypeOneTimeTearDownAttribute = "NUnit.Framework.OneTimeTearDownAttribute"; diff --git a/src/nunit.analyzers/TestCaseSourceUsage/TestCaseSourceUsesStringAnalyzer.cs b/src/nunit.analyzers/TestCaseSourceUsage/TestCaseSourceUsesStringAnalyzer.cs index 12350faf..f480384c 100644 --- a/src/nunit.analyzers/TestCaseSourceUsage/TestCaseSourceUsesStringAnalyzer.cs +++ b/src/nunit.analyzers/TestCaseSourceUsage/TestCaseSourceUsesStringAnalyzer.cs @@ -226,7 +226,7 @@ private static void AnalyzeAttribute(SyntaxNodeAnalysisContext context) var (methodRequiredParameters, methodOptionalParameters, methodParamsParameters) = testMethod.GetParameterCounts(); if (elementType.SpecialType != SpecialType.System_String && (elementType.SpecialType == SpecialType.System_Object || elementType.IsIEnumerable(out _) || - SymbolEqualityComparer.Default.Equals(elementType, context.SemanticModel.Compilation.GetTypeByMetadataName(NUnitFrameworkConstants.FullNameOfTypeTestCaseData)))) + IsOrDerivesFrom(elementType, context.SemanticModel.Compilation.GetTypeByMetadataName(NUnitFrameworkConstants.FullNameOfTypeTestCaseParameters)))) { // We only know that there is 1 or (likely) more parameters. // The object could hide an array, possibly with a variable number of elements: TestCaseData.Argument. @@ -306,5 +306,27 @@ private static void ReportIfParametersSupplied( kind)); } } + + private static bool IsOrDerivesFrom(ITypeSymbol type, ITypeSymbol? baseType) + { + if (baseType is null) + { + return false; + } + + ITypeSymbol? typeAtHand = type; + do + { + if (SymbolEqualityComparer.Default.Equals(typeAtHand, baseType)) + { + return true; + } + + typeAtHand = typeAtHand.BaseType; + } + while (typeAtHand is not null); + + return false; + } } }