-
-
Notifications
You must be signed in to change notification settings - Fork 111
fix: add TestDataRow<T> unwrapping to analyzer and tests for named properties #4227
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
…d properties - Add TestDataRow<T> unwrapping in TestDataAnalyzer.UnwrapTypes() to correctly recognize wrapped data types in method data sources - Add analyzer tests for [Arguments] with DisplayName, Skip, and Categories properties - Add analyzer tests for [MethodDataSource] returning TestDataRow<T> with metadata Fixes #4212 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
SummaryThis PR fixes an analyzer false positive where Critical IssuesNone found ✅ Suggestions1. Consider placement of TestDataRow unwrapping logicThe TestDataRow unwrapping is added after the The current ordering handles this correctly because:
This is correct! However, it might be worth adding a code comment explaining the unwrapping order matters, or verifying that the test 2. TestDataRow type check could be more robustTUnit.Analyzers/TestDataAnalyzer.cs:800 checks if (type is INamedTypeSymbol { IsGenericType: true, TypeArguments.Length: 1 } testDataRowType
&& testDataRowType.OriginalDefinition.ToDisplayString() == "TUnit.Core.TestDataRow<T>")This ensures you're matching the exact type from TUnit.Core, not any type named "TestDataRow" from another namespace. However, the current approach is likely fine given the context (it's already inside test data analysis logic). 3. Minor: Whitespace cleanup already includedThe diff shows a trailing whitespace removal on line 725 of MethodDataSourceAnalyzerTests.cs (change from Verdict✅ APPROVE - No critical issues The bug fix is sound and correctly placed in the unwrapping sequence. The comprehensive test coverage for both the TestDataRow fix and the named properties ensures this won't regress. The only suggestions are minor code quality improvements that don't block merging. |
Verifies that Func<TestDataRow<T>> correctly sets isFunc=true, preventing TUnit0046 warning for reference types. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
SummaryFixes analyzer to correctly unwrap TestDataRow wrapper types and adds comprehensive tests for named properties (DisplayName, Skip, Categories) on Arguments and MethodDataSource attributes. Critical IssuesType Safety Concern - Minor but Worth Addressing In TUnit.Analyzers/TestDataAnalyzer.cs:800, the TestDataRow unwrapping only checks if (type is INamedTypeSymbol { IsGenericType: true, TypeArguments.Length: 1 } testDataRowType
&& testDataRowType.Name == "TestDataRow")
{
type = testDataRowType.TypeArguments[0];
}This could theoretically match any type named Recommendation: Follow the pattern used elsewhere in this file for robust type checking. See the pattern used for Suggested fix: var testDataRowType = context.Compilation.GetTypeByMetadataName("TUnit.Core.TestDataRow`1");
if (testDataRowType != null
&& type is INamedTypeSymbol { IsGenericType: true } namedType
&& SymbolEqualityComparer.Default.Equals(namedType.OriginalDefinition, testDataRowType))
{
type = namedType.TypeArguments[0];
}While unlikely to cause issues in practice, using proper type resolution ensures the analyzer won't misbehave if someone creates another TestDataRow type. SuggestionsNone beyond the type safety issue above. VerdictREQUEST CHANGES - Minor type safety improvement needed for consistency with existing code patterns The fix itself is solid and the tests are comprehensive. Just needs stronger type checking to match the codebase standards. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This pull request fixes an analyzer bug where TestDataRow<T> wrapper types were not being properly unwrapped during type checking, causing false positive type mismatch errors. It also adds comprehensive test coverage for named properties (DisplayName, Skip, Categories) on test data attributes.
Key changes:
- Added
TestDataRow<T>unwrapping logic in the analyzer'sUnwrapTypesmethod - Added 5 new tests for
[Arguments]attribute with named properties - Added 5 new tests for
[MethodDataSource]attribute withTestDataRow<T>metadata
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| TUnit.Analyzers/TestDataAnalyzer.cs | Added TestDataRow unwrapping logic to extract the inner data type when methods return IEnumerable<TestDataRow> |
| TUnit.Analyzers.Tests/ArgumentsAnalyzerTests.cs | Added 5 regression tests verifying that Arguments attribute with named properties (DisplayName, Skip, Categories) don't trigger false analyzer warnings |
| TUnit.Analyzers.Tests/MethodDataSourceAnalyzerTests.cs | Added 5 tests verifying TestDataRow wrapper is correctly handled with metadata properties, plus minor whitespace cleanup |
TUnit.Analyzers/TestDataAnalyzer.cs
Outdated
| if (type is INamedTypeSymbol { IsGenericType: true, TypeArguments.Length: 1 } testDataRowType | ||
| && testDataRowType.Name == "TestDataRow") | ||
| { | ||
| type = testDataRowType.TypeArguments[0]; |
Copilot
AI
Jan 4, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The TestDataRow unwrapping logic only checks the type name without validating the namespace. This could incorrectly match any generic type named "TestDataRow" from any namespace, not just TUnit.Core.TestDataRow. Consider using a more robust check similar to other type checks in this codebase, such as comparing the fully qualified type name or using GetTypeByMetadataName to get the expected type and comparing with SymbolEqualityComparer.
| if (type is INamedTypeSymbol { IsGenericType: true, TypeArguments.Length: 1 } testDataRowType | |
| && testDataRowType.Name == "TestDataRow") | |
| { | |
| type = testDataRowType.TypeArguments[0]; | |
| if (type is INamedTypeSymbol { IsGenericType: true, TypeArguments.Length: 1 } testDataRowType) | |
| { | |
| var tunitTestDataRowSymbol = context.Compilation.GetTypeByMetadataName("TUnit.Core.TestDataRow`1"); | |
| if (tunitTestDataRowSymbol is not null | |
| && SymbolEqualityComparer.Default.Equals(testDataRowType.ConstructedFrom, tunitTestDataRowSymbol)) | |
| { | |
| type = testDataRowType.TypeArguments[0]; | |
| } |
Address code review feedback by using GetTypeByMetadataName and SymbolEqualityComparer pattern for TestDataRow<T> detection, matching the existing pattern for Task<T>, Func<T>, etc. Also adds comment explaining unwrapping order importance. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
SummaryFixes analyzer to correctly unwrap TestDataRow wrapper types and adds comprehensive test coverage for named properties. Critical IssuesNone found ✅ Previous Review Status✅ Type safety concern addressed - Now uses GetTypeByMetadataName and SymbolEqualityComparer TUnit Rules Applied
Code ReviewThe implementation is solid:
Verdict✅ APPROVE - All previous concerns addressed. Fix is correct, well-tested, and follows TUnit code patterns. |
Summary
TestDataRow<T>return types as type mismatchesDisplayName,Skip,Categories) on[Arguments]and[MethodDataSource]attributesChanges
Bug Fix (TUnit.Analyzers/TestDataAnalyzer.cs)
Added
TestDataRow<T>unwrapping logic to theUnwrapTypesmethod. When a method data source returnsIEnumerable<TestDataRow<T>>orIEnumerable<Func<TestDataRow<T>>>, the analyzer now correctly extracts the inner typeTinstead of treatingTestDataRow<T>as the data type.Tests Added
ArgumentsAnalyzerTests.cs (5 new tests):
Arguments_With_DisplayName_Property_No_ErrorArguments_With_Skip_Property_No_ErrorArguments_With_Categories_Property_No_ErrorArguments_With_Multiple_Named_Properties_No_ErrorGeneric_Arguments_With_DisplayName_Property_No_ErrorMethodDataSourceAnalyzerTests.cs (5 new tests):
Method_Data_Source_With_TestDataRow_DisplayName_No_ErrorMethod_Data_Source_With_TestDataRow_Skip_No_ErrorMethod_Data_Source_With_TestDataRow_Categories_No_ErrorMethod_Data_Source_With_TestDataRow_All_Metadata_No_ErrorMethod_Data_Source_With_Func_TestDataRow_No_ErrorTest plan
[Arguments]with named properties don't trigger false positivesTestDataRow<T>wrapper is correctly unwrappedFixes #4212
🤖 Generated with Claude Code