-
-
Notifications
You must be signed in to change notification settings - Fork 108
Fix generic DependsOn<T> attribute not working #4246
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
…e argument Co-authored-by: thomhurst <[email protected]>
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 PR fixes a bug where the generic DependsOn<T> attribute was ignoring the type parameter T, treating cross-class dependencies as same-class dependencies. The root cause was that the source generator only examined constructor arguments, missing the generic type argument which is stored separately on the attribute class itself.
Key Changes
- The source generator now extracts the type argument from
AttributeClass.TypeArguments[0]when the attribute is generic - Adds handling for all three generic constructor overloads:
DependsOn<T>(),DependsOn<T>(methodName), andDependsOn<T>(methodName, parameterTypes) - Integration tests verify both generic dependency patterns work correctly
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 5 comments.
| File | Description |
|---|---|
| TUnit.Core.SourceGenerator/Generators/TestMetadataGenerator.cs | Modified GenerateTestDependency() to detect generic DependsOnAttribute<T> and extract the type argument, then generate appropriate TestDependency objects with the correct ClassType for all three constructor overloads |
| TUnit.TestProject/GenericDependsOnTests.cs | Added integration tests for both DependsOn<T>(methodName) and DependsOn<T>() patterns using timing assertions to verify dependency ordering is respected |
| [Test] | ||
| public async Task Test1() | ||
| { | ||
| Test1Start = TestContext.Current!.Execution.TestStart!.Value.DateTime; |
Copilot
AI
Jan 6, 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.
Write to static field from instance method, property, or constructor.
| [Test, DependsOn<GenericDependsOnTestsClassA>(nameof(GenericDependsOnTestsClassA.Test1))] | ||
| public async Task Test2() | ||
| { | ||
| _test2Start = TestContext.Current!.Execution.TestStart!.Value.DateTime; |
Copilot
AI
Jan 6, 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.
Write to static field from instance method, property, or constructor.
| [Test] | ||
| public async Task Test1() | ||
| { | ||
| Test1Start = TestContext.Current!.Execution.TestStart!.Value.DateTime; |
Copilot
AI
Jan 6, 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.
Write to static field from instance method, property, or constructor.
| [Test, DependsOn<GenericDependsOnTestsClassB>] | ||
| public async Task Test2() | ||
| { | ||
| _test2Start = TestContext.Current!.Execution.TestStart!.Value.DateTime; |
Copilot
AI
Jan 6, 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.
Write to static field from instance method, property, or constructor.
| [Test, DependsOn<GenericDependsOnTestsClassB>] | |
| public async Task Test2() | |
| { | |
| _test2Start = TestContext.Current!.Execution.TestStart!.Value.DateTime; | |
| private static void SetTest2Start(DateTime value) | |
| { | |
| _test2Start = value; | |
| } | |
| [Test, DependsOn<GenericDependsOnTestsClassB>] | |
| public async Task Test2() | |
| { | |
| SetTest2Start(TestContext.Current!.Execution.TestStart!.Value.DateTime); |
Generic
DependsOn<T>was ignoring the type parameterT, treating[DependsOn<ClassA>("MethodName")]as[DependsOn("MethodName")](same-class dependency).Root cause: The source generator only examined constructor arguments. For generic attributes,
Tis a type argument on the attribute class, not a constructor argument.Fix: Extract type from
attributeData.AttributeClass.TypeArguments[0]when attribute is generic.Changes
TestMetadataGenerator.GenerateTestDependency()- Check for genericDependsOnAttribute<T>and extract type argument for all three constructor overloads:DependsOn<T>()- all tests in class TDependsOn<T>(methodName)- specific test in class TDependsOn<T>(methodName, parameterTypes)- specific overload in class TGenericDependsOnTests.cs- Integration tests for bothDependsOn<T>()andDependsOn<T>(methodName)patternsExample
Original prompt
✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.