-
-
Notifications
You must be signed in to change notification settings - Fork 108
fix: generic methods with [GenerateGenericTest] + [MethodDataSource] now discovered (#4440) #4443
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
Conversation
Design document for fixing generic methods with [GenerateGenericTest] and [MethodDataSource] not being discovered in reflection mode. Key changes planned: - Add ResolveClassInstantiationsAsync method - Add ResolveMethodInstantiations method - Refactor discovery loop to use new resolution methods - Ensure all errors are visible as failed tests Co-Authored-By: Claude Opus 4.5 <[email protected]>
Co-Authored-By: Claude Opus 4.5 <[email protected]>
SummaryFixes generic methods with [GenerateGenericTest] + [MethodDataSource] not being discovered in reflection mode by adding ResolveMethodInstantiations method and fixing data compatibility checks. Critical Issues1. .gitignore ErrorThe change to .gitignore appears incorrect. It changes from .worktrees/ to .worktrees/.worktrees/ which looks like a typo that will break the gitignore for worktrees. Should this be reverted to .worktrees/? Location: .gitignore:441 Suggestions1. Dual-Mode VerificationThe changes only touch reflection mode (TUnit.Engine). Per TUnit Rule 1, I would like to confirm tests verify BOTH modes produce identical behavior. The test file TUnit.Engine.Tests/GenericMethodWithDataSourceTests.cs uses InvokableTestBase(testMode) which suggests it tests both modes. Can you confirm the tests pass in both source-gen and reflection modes? 2. Code Quality
VerdictREQUEST CHANGES - The .gitignore issue must be fixed before merging. Once the .gitignore is corrected, this is a solid fix that properly brings reflection mode into parity with source generator mode. |
…now discovered (#4440) Generic test methods that combine [GenerateGenericTest] with [MethodDataSource] were not being discovered in reflection mode. The issue was in IsDataCompatibleWithExpectedTypes which incorrectly filtered out tests where the method parameter type (e.g., string) didn't match the generic type argument (e.g., int). The fix checks whether method parameters actually use the method's generic type parameters. For methods like GenericMethod<T>(string input), the parameter is a concrete type that doesn't depend on T, so data compatibility with T is irrelevant. Changes: - Add ParameterUsesMethodGenericType helper to detect if parameters use method generics - Skip data compatibility check when no parameters use method generic types - Add ResolveMethodInstantiations to create concrete method instances from [GenerateGenericTest] - Add comprehensive tests for various generic class/method/data source combinations Co-Authored-By: Claude Opus 4.5 <[email protected]>
d7fe9fc to
d76697c
Compare
SummaryFixes reflection mode to discover generic test methods combining Critical Issues1. .gitignore Error (Previously Reported - STILL PRESENT)Location: .gitignore:441 The change from Expected: This should be reverted to SuggestionsNone - the core implementation is solid. Previous Review StatusThe previous review (2026-01-16 12:24:11) identified the .gitignore issue and requested changes. This issue has NOT been fixed yet. All other aspects were approved. Code Quality Notes✅ Dual-Mode Compliance: Changes only touch reflection mode (TUnit.Engine). Tests inherit from ✅ AOT Compatible: Proper ✅ Error Handling: Failed discoveries become visible failed tests in the explorer rather than silently disappearing. ✅ Performance: No obvious hot-path allocations. The ✅ Modern C#: Good use of tuple deconstruction, collection expressions, and pattern matching. ✅ Well-documented: The VerdictOnce the .gitignore is corrected, this is an excellent fix that properly brings reflection mode into parity with source generator mode for generic methods with data sources. |
…tion The fix addresses three issues that were causing generic methods with [GenerateGenericTest] to be deduplicated incorrectly in reflection mode: 1. TestIdentifierService: Added method generic type arguments to test ID generation to ensure uniqueness (e.g., GenericMethod<int> vs GenericMethod<string> get different IDs). 2. TestGenericTypeResolver: Fixed the order of checks so that GenericMethodTypeArguments is checked first, before GenericMethodInfo. This ensures constructed generic methods (from MakeGenericMethod) have their type arguments populated correctly. 3. ReflectionTestDataCollector.GenerateTestName: Added type arguments to test display names for constructed generic methods to match source-gen behavior. Also renamed test fixture class to Bug4440_NonGenericClassWithGenericMethodAndDataSource to avoid name collision with existing test in 4431. Co-Authored-By: Claude Opus 4.5 <[email protected]>
SummaryFixes generic methods with [GenerateGenericTest] + [MethodDataSource] not being discovered in reflection mode, achieving parity with source-generated mode. Critical Issues1. Incorrect .gitignore change -.worktrees/
+.worktrees/.worktrees/This changes the pattern from Suggestions1. Consider performance optimization in ParameterUsesMethodGenericType // Current implementation traverses type hierarchy on every call
private static bool ParameterUsesMethodGenericType(TypeInfo? typeInfo)
{
return typeInfo switch
{
GenericParameter { IsMethodParameter: true } => true,
ConstructedGeneric cg => cg.TypeArguments.Any(ParameterUsesMethodGenericType),
_ => false
};
}Consider caching results or moving the check outside the parameter loop since the answer is the same for all parameters of a given method. 2. Minor: Whitespace-only changes TUnit Rules Compliance✅ Dual-Mode (Rule 1): PASS - Changes only affect reflection mode to achieve parity with source generator. Source gen already handles this correctly (lines 3676-3751 in TestMetadataGenerator.cs). ✅ Snapshot Testing (Rule 2): N/A - No source generator output or public API changes. Only runtime reflection discovery logic. ✅ Performance (Rule 4): GOOD - Implemented as ✅ AOT Compatible (Rule 5): PASS - Proper Test CoverageExcellent comprehensive test coverage:
All critical scenarios are tested in both source-gen and reflection modes. Previous Review StatusNo previous comments found. Verdict |
Summary
Fixes #4440 - Generic test methods combining
[GenerateGenericTest]with[MethodDataSource]were not being discovered in reflection mode.Root cause:
IsDataCompatibleWithExpectedTypesinTestBuilder.csincorrectly filtered out tests where method parameters (e.g.,string) didn't match the generic type argument (e.g.,int).Fix: Check whether method parameters actually use the method's generic type parameters. For methods like
GenericMethod<T>(string input), thestringparameter doesn't depend onT, so data compatibility withTis irrelevant.Changes
ParameterUsesMethodGenericTypehelper to detect if parameters use method genericsResolveMethodInstantiationsto create concrete method instances from[GenerateGenericTest]Test plan
NonGenericClassWithGenericMethodAndDataSource(2 types × 2 data items)🤖 Generated with Claude Code