From c9d8a15cd3615846e35a3eadf7d85cda75a2cfbe Mon Sep 17 00:00:00 2001 From: Timothy Makkison Date: Sun, 11 Jan 2026 23:41:00 +0000 Subject: [PATCH 1/3] perf: remove cache and use `IReadOnlyList` --- TUnit.Core/TestDetails.Metadata.cs | 1 + TUnit.Core/TestDetails.cs | 22 ++++-------- TUnit.Engine/Building/TestBuilder.cs | 7 ++-- TUnit.Engine/Building/TestBuilderPipeline.cs | 8 ++--- ...Has_No_API_Changes.DotNet10_0.verified.txt | 36 +++++++++---------- ..._Has_No_API_Changes.DotNet8_0.verified.txt | 36 +++++++++---------- ..._Has_No_API_Changes.DotNet9_0.verified.txt | 36 +++++++++---------- ...ary_Has_No_API_Changes.Net4_7.verified.txt | 36 +++++++++---------- 8 files changed, 88 insertions(+), 94 deletions(-) diff --git a/TUnit.Core/TestDetails.Metadata.cs b/TUnit.Core/TestDetails.Metadata.cs index fac756338c..d5f2e15437 100644 --- a/TUnit.Core/TestDetails.Metadata.cs +++ b/TUnit.Core/TestDetails.Metadata.cs @@ -14,4 +14,5 @@ public partial class TestDetails bool ITestDetailsMetadata.HasAttribute() => HasAttribute(); IEnumerable ITestDetailsMetadata.GetAttributes() => GetAttributes(); IReadOnlyList ITestDetailsMetadata.GetAllAttributes() => GetAllAttributes(); + } diff --git a/TUnit.Core/TestDetails.cs b/TUnit.Core/TestDetails.cs index b10daeb267..be72b6a8b6 100644 --- a/TUnit.Core/TestDetails.cs +++ b/TUnit.Core/TestDetails.cs @@ -9,6 +9,8 @@ namespace TUnit.Core; /// public partial class TestDetails : ITestIdentity, ITestClass, ITestMethod, ITestConfiguration, ITestLocation, ITestDetailsMetadata { + private readonly IReadOnlyList _allAttributes; + // Zero-allocation interface properties for organized API access public ITestIdentity Identity => this; public ITestClass Class => this; @@ -40,19 +42,9 @@ public partial class TestDetails : ITestIdentity, ITestClass, ITestMethod, ITest public required IReadOnlyDictionary> AttributesByType { get; init; } - private readonly Lazy> _cachedAllAttributes; - - public TestDetails() + public TestDetails(IReadOnlyList allAttributes) { - _cachedAllAttributes = new Lazy>(() => - { - var allAttrs = new List(); - foreach (var attrList in AttributesByType?.Values ?? []) - { - allAttrs.AddRange(attrList); - } - return allAttrs; - }); + _allAttributes = allAttributes; } /// @@ -73,12 +65,12 @@ public IEnumerable GetAttributes() where T : Attribute ? attrs.OfType() : []; - /// + // /// Gets all attributes as a flattened collection. /// Cached after first access for performance. /// /// All attributes associated with this test. - public IReadOnlyList GetAllAttributes() => _cachedAllAttributes.Value; + public IReadOnlyList GetAllAttributes() => _allAttributes; /// /// Resolved generic type arguments for the test method. @@ -96,4 +88,4 @@ public IEnumerable GetAttributes() where T : Attribute /// /// Generic version of TestDetails for compatibility with tests /// -public class TestDetails : TestDetails where T : class; +public class TestDetails(IReadOnlyList allAttributes) : TestDetails(allAttributes) where T : class; diff --git a/TUnit.Engine/Building/TestBuilder.cs b/TUnit.Engine/Building/TestBuilder.cs index ffb901e5dc..06cec57a2a 100644 --- a/TUnit.Engine/Building/TestBuilder.cs +++ b/TUnit.Engine/Building/TestBuilder.cs @@ -978,7 +978,7 @@ private async ValueTask CreateTestContextAsync(string testId, TestM attributes = [..attributes, (Attribute)testBuilderContext.DataSourceAttribute]; } - var testDetails = new TestDetails + var testDetails = new TestDetails(attributes) { TestId = testId, TestName = metadata.TestName, @@ -1074,7 +1074,8 @@ private async Task CreateFailedTestForDataGenerationErro private async Task CreateFailedTestDetails(TestMetadata metadata, string testId) { - return new TestDetails + var attributes = (await InitializeAttributesAsync(metadata.AttributeFactory.Invoke())); + return new TestDetails(attributes) { TestId = testId, TestName = metadata.TestName, @@ -1087,7 +1088,7 @@ private async Task CreateFailedTestDetails(TestMetadata metadata, s TestLineNumber = metadata.LineNumber, ReturnType = typeof(Task), MethodMetadata = metadata.MethodMetadata, - AttributesByType = (await InitializeAttributesAsync(metadata.AttributeFactory.Invoke())).ToAttributeDictionary(), + AttributesByType = attributes.ToAttributeDictionary(), Timeout = TimeSpan.FromMinutes(30) // Default 30-minute timeout (can be overridden by TimeoutAttribute) }; } diff --git a/TUnit.Engine/Building/TestBuilderPipeline.cs b/TUnit.Engine/Building/TestBuilderPipeline.cs index 23884ba399..54b3dae40f 100644 --- a/TUnit.Engine/Building/TestBuilderPipeline.cs +++ b/TUnit.Engine/Building/TestBuilderPipeline.cs @@ -249,7 +249,7 @@ private async Task GenerateDynamicTests(TestMetadata m var attributes = metadata.AttributeFactory(); // Create TestDetails for dynamic tests - var testDetails = new TestDetails + var testDetails = new TestDetails(attributes) { TestId = testId, TestName = metadata.TestName, @@ -377,7 +377,7 @@ private async IAsyncEnumerable BuildTestsFromSingleMetad : baseDisplayName; // Create TestDetails for dynamic tests - var testDetails = new TestDetails + var testDetails = new TestDetails(attributes) { TestId = testId, TestName = resolvedMetadata.TestName, @@ -457,7 +457,7 @@ private AbstractExecutableTest CreateFailedTestForDataGenerationError(TestMetada var testId = TestIdentifierService.GenerateFailedTestId(metadata); var displayName = $"{metadata.TestClassType.Name}.{metadata.TestName}"; - var testDetails = new TestDetails + var testDetails = new TestDetails([]) { TestId = testId, TestName = metadata.TestName, @@ -509,7 +509,7 @@ private AbstractExecutableTest CreateFailedTestForGenericResolutionError(TestMet var testId = TestIdentifierService.GenerateFailedTestId(metadata); var displayName = $"{metadata.TestName} [GENERIC RESOLUTION ERROR]"; - var testDetails = new TestDetails + var testDetails = new TestDetails([]) { TestId = testId, TestName = metadata.TestName, diff --git a/TUnit.PublicAPI/Tests.Core_Library_Has_No_API_Changes.DotNet10_0.verified.txt b/TUnit.PublicAPI/Tests.Core_Library_Has_No_API_Changes.DotNet10_0.verified.txt index e9f46064a1..cee3e2aeaa 100644 --- a/TUnit.PublicAPI/Tests.Core_Library_Has_No_API_Changes.DotNet10_0.verified.txt +++ b/TUnit.PublicAPI/Tests.Core_Library_Has_No_API_Changes.DotNet10_0.verified.txt @@ -2,7 +2,7 @@ [assembly: .(@", PublicKey=0024000004800000940000000602000000240000525341310004000001000100698a70398fa0b2230c5a72e3bd9d56b48f809f6173e49a19fbb942d621be93ad48c5566b47b28faabc359b9ad3ff4e00bbdea88f5bdfa250f391fedd28182b2e37b55d429c0151a42a98ea7a5821818cd15a79fef9903e8607a88304cf3e0317bf86ec96e32e1381535a6582251e5a6eed40b5a3ed82bc444598b1269cce57a7")] [assembly: .(@", PublicKey=0024000004800000940000000602000000240000525341310004000001000100698a70398fa0b2230c5a72e3bd9d56b48f809f6173e49a19fbb942d621be93ad48c5566b47b28faabc359b9ad3ff4e00bbdea88f5bdfa250f391fedd28182b2e37b55d429c0151a42a98ea7a5821818cd15a79fef9903e8607a88304cf3e0317bf86ec96e32e1381535a6582251e5a6eed40b5a3ed82bc444598b1269cce57a7")] [assembly: .(".NETCoreApp,Version=v10.0", FrameworkDisplayName=".NET 10.0")] -namespace +namespace { public abstract class AbstractDynamicTest { @@ -426,7 +426,7 @@ namespace public CultureExecutor(.CultureInfo cultureInfo) { } protected override void ConfigureThread(.Thread thread) { } } - public class DataGenerationException : + public class DataGenerationException : { public DataGenerationException(string message) { } public DataGenerationException(string message, innerException) { } @@ -676,7 +676,7 @@ namespace public object?[]? TestMethodArguments { get; set; } public override .<.DiscoveryResult> GetTests() { } } - public class EngineCancellationToken : + public class EngineCancellationToken : { public EngineCancellationToken() { } public .CancellationToken Token { get; } @@ -749,7 +749,7 @@ namespace public override .<.DiscoveryResult> GetTests() { } } [(.Class | .Method, AllowMultiple=true)] - public sealed class GenerateGenericTestAttribute : + public sealed class GenerateGenericTestAttribute : { public GenerateGenericTestAttribute(params [] typeArguments) { } public [] TypeArguments { get; } @@ -1152,7 +1152,7 @@ namespace public static void Register( type, ..IPropertySource source) { } } [(.Assembly, AllowMultiple=false, Inherited=false)] - public sealed class ReflectionModeAttribute : + public sealed class ReflectionModeAttribute : { public ReflectionModeAttribute() { } } @@ -1273,7 +1273,7 @@ namespace { public TestAttribute([.] string file = "", [.] int line = 0) { } } - public sealed class TestBuildContext : .Context, + public sealed class TestBuildContext : .Context, { public TestBuildContext() { } public new static .TestBuildContext? Current { get; } @@ -1299,7 +1299,7 @@ namespace public TestBuilderContextAccessor(.TestBuilderContext context) { } public .TestBuilderContext Current { get; set; } } - public class TestBuilderException : + public class TestBuilderException : { public TestBuilderException() { } public TestBuilderException(string message) { } @@ -1420,7 +1420,7 @@ namespace } public class TestDetails : ., ., ., ., ., . { - public TestDetails() { } + public TestDetails(IReadOnlyList allAttributes) { } public . Attributes { get; } public required .<, .<>> AttributesByType { get; init; } public . Categories { get; } @@ -1457,7 +1457,7 @@ namespace public class TestDetails : .TestDetails where T : class { - public TestDetails() { } + public TestDetails(IReadOnlyList allAttributes) { } } public class TestDiscoveryContext : .Context { @@ -1636,7 +1636,7 @@ namespace .AotCompatibility TupleInterfaceBased = 3, } [(.Method)] - public class AotCompatibleAttribute : + public class AotCompatibleAttribute : { public AotCompatibleAttribute() { } public string? Details { get; init; } @@ -1659,14 +1659,14 @@ namespace .AotCompatibility namespace .Attributes { [(.Class | .Constructor | .Method | .Property)] - public sealed class AotCompatibleAttribute : + public sealed class AotCompatibleAttribute : { public AotCompatibleAttribute() { } public string? AlternativeForReflection { get; set; } public string? Notes { get; set; } } [(.Class | .Constructor | .Method | .Property)] - public sealed class RequiresReflectionAttribute : + public sealed class RequiresReflectionAttribute : { public RequiresReflectionAttribute(string reason) { } public string? AotAlternative { get; set; } @@ -1854,7 +1854,7 @@ namespace .Exceptions { public BeforeTestSessionException(string message, innerException) { } } - public class CircularDependencyException : + public class CircularDependencyException : { public CircularDependencyException() { } public CircularDependencyException(string message) { } @@ -1866,7 +1866,7 @@ namespace .Exceptions public FailTestException(string reason) { } public string Reason { get; } } - public class GenericTypeResolutionException : + public class GenericTypeResolutionException : { public GenericTypeResolutionException(string message) { } public GenericTypeResolutionException(string message, innerException) { } @@ -1880,7 +1880,7 @@ namespace .Exceptions public SkipTestException(string reason) { } public string Reason { get; } } - public class TUnitException : + public class TUnitException : { public TUnitException() { } public TUnitException(string? message) { } @@ -1899,7 +1899,7 @@ namespace .Exceptions public .<> HookExceptions { get; } public ? TestException { get; } } - public class TestFailedInitializationException : + public class TestFailedInitializationException : { public TestFailedInitializationException(string? message, ? innerException) { } } @@ -2774,7 +2774,7 @@ namespace .Services public string FormatArgumentValue(object? value) { } public string FormatTestName(string template, object?[]? classArgs = null, object?[]? methodArgs = null, .? propertyValues = null) { } } - public class TestServiceProvider : + public class TestServiceProvider : { public TestServiceProvider() { } public . AddSingleton( serviceType, object service) { } @@ -2802,4 +2802,4 @@ namespace .StaticProperties public static void Register(. metadata) { } public static bool TryGetInitializedValue( declaringType, string propertyName, out object? value) { } } -} \ No newline at end of file +} diff --git a/TUnit.PublicAPI/Tests.Core_Library_Has_No_API_Changes.DotNet8_0.verified.txt b/TUnit.PublicAPI/Tests.Core_Library_Has_No_API_Changes.DotNet8_0.verified.txt index 8cc53af1a3..315a1f0dae 100644 --- a/TUnit.PublicAPI/Tests.Core_Library_Has_No_API_Changes.DotNet8_0.verified.txt +++ b/TUnit.PublicAPI/Tests.Core_Library_Has_No_API_Changes.DotNet8_0.verified.txt @@ -2,7 +2,7 @@ [assembly: .(@", PublicKey=0024000004800000940000000602000000240000525341310004000001000100698a70398fa0b2230c5a72e3bd9d56b48f809f6173e49a19fbb942d621be93ad48c5566b47b28faabc359b9ad3ff4e00bbdea88f5bdfa250f391fedd28182b2e37b55d429c0151a42a98ea7a5821818cd15a79fef9903e8607a88304cf3e0317bf86ec96e32e1381535a6582251e5a6eed40b5a3ed82bc444598b1269cce57a7")] [assembly: .(@", PublicKey=0024000004800000940000000602000000240000525341310004000001000100698a70398fa0b2230c5a72e3bd9d56b48f809f6173e49a19fbb942d621be93ad48c5566b47b28faabc359b9ad3ff4e00bbdea88f5bdfa250f391fedd28182b2e37b55d429c0151a42a98ea7a5821818cd15a79fef9903e8607a88304cf3e0317bf86ec96e32e1381535a6582251e5a6eed40b5a3ed82bc444598b1269cce57a7")] [assembly: .(".NETCoreApp,Version=v8.0", FrameworkDisplayName=".NET 8.0")] -namespace +namespace { public abstract class AbstractDynamicTest { @@ -426,7 +426,7 @@ namespace public CultureExecutor(.CultureInfo cultureInfo) { } protected override void ConfigureThread(.Thread thread) { } } - public class DataGenerationException : + public class DataGenerationException : { public DataGenerationException(string message) { } public DataGenerationException(string message, innerException) { } @@ -676,7 +676,7 @@ namespace public object?[]? TestMethodArguments { get; set; } public override .<.DiscoveryResult> GetTests() { } } - public class EngineCancellationToken : + public class EngineCancellationToken : { public EngineCancellationToken() { } public .CancellationToken Token { get; } @@ -749,7 +749,7 @@ namespace public override .<.DiscoveryResult> GetTests() { } } [(.Class | .Method, AllowMultiple=true)] - public sealed class GenerateGenericTestAttribute : + public sealed class GenerateGenericTestAttribute : { public GenerateGenericTestAttribute(params [] typeArguments) { } public [] TypeArguments { get; } @@ -1152,7 +1152,7 @@ namespace public static void Register( type, ..IPropertySource source) { } } [(.Assembly, AllowMultiple=false, Inherited=false)] - public sealed class ReflectionModeAttribute : + public sealed class ReflectionModeAttribute : { public ReflectionModeAttribute() { } } @@ -1273,7 +1273,7 @@ namespace { public TestAttribute([.] string file = "", [.] int line = 0) { } } - public sealed class TestBuildContext : .Context, + public sealed class TestBuildContext : .Context, { public TestBuildContext() { } public new static .TestBuildContext? Current { get; } @@ -1299,7 +1299,7 @@ namespace public TestBuilderContextAccessor(.TestBuilderContext context) { } public .TestBuilderContext Current { get; set; } } - public class TestBuilderException : + public class TestBuilderException : { public TestBuilderException() { } public TestBuilderException(string message) { } @@ -1420,7 +1420,7 @@ namespace } public class TestDetails : ., ., ., ., ., . { - public TestDetails() { } + public TestDetails(IReadOnlyList allAttributes) { } public . Attributes { get; } public required .<, .<>> AttributesByType { get; init; } public . Categories { get; } @@ -1457,7 +1457,7 @@ namespace public class TestDetails : .TestDetails where T : class { - public TestDetails() { } + public TestDetails(IReadOnlyList allAttributes) { } } public class TestDiscoveryContext : .Context { @@ -1636,7 +1636,7 @@ namespace .AotCompatibility TupleInterfaceBased = 3, } [(.Method)] - public class AotCompatibleAttribute : + public class AotCompatibleAttribute : { public AotCompatibleAttribute() { } public string? Details { get; init; } @@ -1659,14 +1659,14 @@ namespace .AotCompatibility namespace .Attributes { [(.Class | .Constructor | .Method | .Property)] - public sealed class AotCompatibleAttribute : + public sealed class AotCompatibleAttribute : { public AotCompatibleAttribute() { } public string? AlternativeForReflection { get; set; } public string? Notes { get; set; } } [(.Class | .Constructor | .Method | .Property)] - public sealed class RequiresReflectionAttribute : + public sealed class RequiresReflectionAttribute : { public RequiresReflectionAttribute(string reason) { } public string? AotAlternative { get; set; } @@ -1854,7 +1854,7 @@ namespace .Exceptions { public BeforeTestSessionException(string message, innerException) { } } - public class CircularDependencyException : + public class CircularDependencyException : { public CircularDependencyException() { } public CircularDependencyException(string message) { } @@ -1866,7 +1866,7 @@ namespace .Exceptions public FailTestException(string reason) { } public string Reason { get; } } - public class GenericTypeResolutionException : + public class GenericTypeResolutionException : { public GenericTypeResolutionException(string message) { } public GenericTypeResolutionException(string message, innerException) { } @@ -1880,7 +1880,7 @@ namespace .Exceptions public SkipTestException(string reason) { } public string Reason { get; } } - public class TUnitException : + public class TUnitException : { public TUnitException() { } public TUnitException(string? message) { } @@ -1899,7 +1899,7 @@ namespace .Exceptions public .<> HookExceptions { get; } public ? TestException { get; } } - public class TestFailedInitializationException : + public class TestFailedInitializationException : { public TestFailedInitializationException(string? message, ? innerException) { } } @@ -2774,7 +2774,7 @@ namespace .Services public string FormatArgumentValue(object? value) { } public string FormatTestName(string template, object?[]? classArgs = null, object?[]? methodArgs = null, .? propertyValues = null) { } } - public class TestServiceProvider : + public class TestServiceProvider : { public TestServiceProvider() { } public . AddSingleton( serviceType, object service) { } @@ -2802,4 +2802,4 @@ namespace .StaticProperties public static void Register(. metadata) { } public static bool TryGetInitializedValue( declaringType, string propertyName, out object? value) { } } -} \ No newline at end of file +} diff --git a/TUnit.PublicAPI/Tests.Core_Library_Has_No_API_Changes.DotNet9_0.verified.txt b/TUnit.PublicAPI/Tests.Core_Library_Has_No_API_Changes.DotNet9_0.verified.txt index ab0af14524..66bc06dac8 100644 --- a/TUnit.PublicAPI/Tests.Core_Library_Has_No_API_Changes.DotNet9_0.verified.txt +++ b/TUnit.PublicAPI/Tests.Core_Library_Has_No_API_Changes.DotNet9_0.verified.txt @@ -2,7 +2,7 @@ [assembly: .(@", PublicKey=0024000004800000940000000602000000240000525341310004000001000100698a70398fa0b2230c5a72e3bd9d56b48f809f6173e49a19fbb942d621be93ad48c5566b47b28faabc359b9ad3ff4e00bbdea88f5bdfa250f391fedd28182b2e37b55d429c0151a42a98ea7a5821818cd15a79fef9903e8607a88304cf3e0317bf86ec96e32e1381535a6582251e5a6eed40b5a3ed82bc444598b1269cce57a7")] [assembly: .(@", PublicKey=0024000004800000940000000602000000240000525341310004000001000100698a70398fa0b2230c5a72e3bd9d56b48f809f6173e49a19fbb942d621be93ad48c5566b47b28faabc359b9ad3ff4e00bbdea88f5bdfa250f391fedd28182b2e37b55d429c0151a42a98ea7a5821818cd15a79fef9903e8607a88304cf3e0317bf86ec96e32e1381535a6582251e5a6eed40b5a3ed82bc444598b1269cce57a7")] [assembly: .(".NETCoreApp,Version=v9.0", FrameworkDisplayName=".NET 9.0")] -namespace +namespace { public abstract class AbstractDynamicTest { @@ -426,7 +426,7 @@ namespace public CultureExecutor(.CultureInfo cultureInfo) { } protected override void ConfigureThread(.Thread thread) { } } - public class DataGenerationException : + public class DataGenerationException : { public DataGenerationException(string message) { } public DataGenerationException(string message, innerException) { } @@ -676,7 +676,7 @@ namespace public object?[]? TestMethodArguments { get; set; } public override .<.DiscoveryResult> GetTests() { } } - public class EngineCancellationToken : + public class EngineCancellationToken : { public EngineCancellationToken() { } public .CancellationToken Token { get; } @@ -749,7 +749,7 @@ namespace public override .<.DiscoveryResult> GetTests() { } } [(.Class | .Method, AllowMultiple=true)] - public sealed class GenerateGenericTestAttribute : + public sealed class GenerateGenericTestAttribute : { public GenerateGenericTestAttribute(params [] typeArguments) { } public [] TypeArguments { get; } @@ -1152,7 +1152,7 @@ namespace public static void Register( type, ..IPropertySource source) { } } [(.Assembly, AllowMultiple=false, Inherited=false)] - public sealed class ReflectionModeAttribute : + public sealed class ReflectionModeAttribute : { public ReflectionModeAttribute() { } } @@ -1273,7 +1273,7 @@ namespace { public TestAttribute([.] string file = "", [.] int line = 0) { } } - public sealed class TestBuildContext : .Context, + public sealed class TestBuildContext : .Context, { public TestBuildContext() { } public new static .TestBuildContext? Current { get; } @@ -1299,7 +1299,7 @@ namespace public TestBuilderContextAccessor(.TestBuilderContext context) { } public .TestBuilderContext Current { get; set; } } - public class TestBuilderException : + public class TestBuilderException : { public TestBuilderException() { } public TestBuilderException(string message) { } @@ -1420,7 +1420,7 @@ namespace } public class TestDetails : ., ., ., ., ., . { - public TestDetails() { } + public TestDetails(IReadOnlyList allAttributes) { } public . Attributes { get; } public required .<, .<>> AttributesByType { get; init; } public . Categories { get; } @@ -1457,7 +1457,7 @@ namespace public class TestDetails : .TestDetails where T : class { - public TestDetails() { } + public TestDetails(IReadOnlyList allAttributes) { } } public class TestDiscoveryContext : .Context { @@ -1636,7 +1636,7 @@ namespace .AotCompatibility TupleInterfaceBased = 3, } [(.Method)] - public class AotCompatibleAttribute : + public class AotCompatibleAttribute : { public AotCompatibleAttribute() { } public string? Details { get; init; } @@ -1659,14 +1659,14 @@ namespace .AotCompatibility namespace .Attributes { [(.Class | .Constructor | .Method | .Property)] - public sealed class AotCompatibleAttribute : + public sealed class AotCompatibleAttribute : { public AotCompatibleAttribute() { } public string? AlternativeForReflection { get; set; } public string? Notes { get; set; } } [(.Class | .Constructor | .Method | .Property)] - public sealed class RequiresReflectionAttribute : + public sealed class RequiresReflectionAttribute : { public RequiresReflectionAttribute(string reason) { } public string? AotAlternative { get; set; } @@ -1854,7 +1854,7 @@ namespace .Exceptions { public BeforeTestSessionException(string message, innerException) { } } - public class CircularDependencyException : + public class CircularDependencyException : { public CircularDependencyException() { } public CircularDependencyException(string message) { } @@ -1866,7 +1866,7 @@ namespace .Exceptions public FailTestException(string reason) { } public string Reason { get; } } - public class GenericTypeResolutionException : + public class GenericTypeResolutionException : { public GenericTypeResolutionException(string message) { } public GenericTypeResolutionException(string message, innerException) { } @@ -1880,7 +1880,7 @@ namespace .Exceptions public SkipTestException(string reason) { } public string Reason { get; } } - public class TUnitException : + public class TUnitException : { public TUnitException() { } public TUnitException(string? message) { } @@ -1899,7 +1899,7 @@ namespace .Exceptions public .<> HookExceptions { get; } public ? TestException { get; } } - public class TestFailedInitializationException : + public class TestFailedInitializationException : { public TestFailedInitializationException(string? message, ? innerException) { } } @@ -2774,7 +2774,7 @@ namespace .Services public string FormatArgumentValue(object? value) { } public string FormatTestName(string template, object?[]? classArgs = null, object?[]? methodArgs = null, .? propertyValues = null) { } } - public class TestServiceProvider : + public class TestServiceProvider : { public TestServiceProvider() { } public . AddSingleton( serviceType, object service) { } @@ -2802,4 +2802,4 @@ namespace .StaticProperties public static void Register(. metadata) { } public static bool TryGetInitializedValue( declaringType, string propertyName, out object? value) { } } -} \ No newline at end of file +} diff --git a/TUnit.PublicAPI/Tests.Core_Library_Has_No_API_Changes.Net4_7.verified.txt b/TUnit.PublicAPI/Tests.Core_Library_Has_No_API_Changes.Net4_7.verified.txt index 0b1701f10a..eedf5df730 100644 --- a/TUnit.PublicAPI/Tests.Core_Library_Has_No_API_Changes.Net4_7.verified.txt +++ b/TUnit.PublicAPI/Tests.Core_Library_Has_No_API_Changes.Net4_7.verified.txt @@ -2,7 +2,7 @@ [assembly: .(@", PublicKey=0024000004800000940000000602000000240000525341310004000001000100698a70398fa0b2230c5a72e3bd9d56b48f809f6173e49a19fbb942d621be93ad48c5566b47b28faabc359b9ad3ff4e00bbdea88f5bdfa250f391fedd28182b2e37b55d429c0151a42a98ea7a5821818cd15a79fef9903e8607a88304cf3e0317bf86ec96e32e1381535a6582251e5a6eed40b5a3ed82bc444598b1269cce57a7")] [assembly: .(@", PublicKey=0024000004800000940000000602000000240000525341310004000001000100698a70398fa0b2230c5a72e3bd9d56b48f809f6173e49a19fbb942d621be93ad48c5566b47b28faabc359b9ad3ff4e00bbdea88f5bdfa250f391fedd28182b2e37b55d429c0151a42a98ea7a5821818cd15a79fef9903e8607a88304cf3e0317bf86ec96e32e1381535a6582251e5a6eed40b5a3ed82bc444598b1269cce57a7")] [assembly: .(".NETStandard,Version=v2.0", FrameworkDisplayName=".NET Standard 2.0")] -namespace +namespace { public abstract class AbstractDynamicTest { @@ -406,7 +406,7 @@ namespace public CultureExecutor(.CultureInfo cultureInfo) { } protected override void ConfigureThread(.Thread thread) { } } - public class DataGenerationException : + public class DataGenerationException : { public DataGenerationException(string message) { } public DataGenerationException(string message, innerException) { } @@ -653,7 +653,7 @@ namespace public object?[]? TestMethodArguments { get; set; } public override .<.DiscoveryResult> GetTests() { } } - public class EngineCancellationToken : + public class EngineCancellationToken : { public EngineCancellationToken() { } public .CancellationToken Token { get; } @@ -726,7 +726,7 @@ namespace public override .<.DiscoveryResult> GetTests() { } } [(.Class | .Method, AllowMultiple=true)] - public sealed class GenerateGenericTestAttribute : + public sealed class GenerateGenericTestAttribute : { public GenerateGenericTestAttribute(params [] typeArguments) { } public [] TypeArguments { get; } @@ -1112,7 +1112,7 @@ namespace public static void Register( type, ..IPropertySource source) { } } [(.Assembly, AllowMultiple=false, Inherited=false)] - public sealed class ReflectionModeAttribute : + public sealed class ReflectionModeAttribute : { public ReflectionModeAttribute() { } } @@ -1228,7 +1228,7 @@ namespace { public TestAttribute([.] string file = "", [.] int line = 0) { } } - public sealed class TestBuildContext : .Context, + public sealed class TestBuildContext : .Context, { public TestBuildContext() { } public new static .TestBuildContext? Current { get; } @@ -1254,7 +1254,7 @@ namespace public TestBuilderContextAccessor(.TestBuilderContext context) { } public .TestBuilderContext Current { get; set; } } - public class TestBuilderException : + public class TestBuilderException : { public TestBuilderException() { } public TestBuilderException(string message) { } @@ -1375,7 +1375,7 @@ namespace } public class TestDetails : ., ., ., ., ., . { - public TestDetails() { } + public TestDetails(IReadOnlyList allAttributes) { } public . Attributes { get; } public required .<, .<>> AttributesByType { get; init; } public . Categories { get; } @@ -1411,7 +1411,7 @@ namespace public class TestDetails : .TestDetails where T : class { - public TestDetails() { } + public TestDetails(IReadOnlyList allAttributes) { } } public class TestDiscoveryContext : .Context { @@ -1589,7 +1589,7 @@ namespace .AotCompatibility TupleInterfaceBased = 3, } [(.Method)] - public class AotCompatibleAttribute : + public class AotCompatibleAttribute : { public AotCompatibleAttribute() { } public string? Details { get; init; } @@ -1612,14 +1612,14 @@ namespace .AotCompatibility namespace .Attributes { [(.Class | .Constructor | .Method | .Property)] - public sealed class AotCompatibleAttribute : + public sealed class AotCompatibleAttribute : { public AotCompatibleAttribute() { } public string? AlternativeForReflection { get; set; } public string? Notes { get; set; } } [(.Class | .Constructor | .Method | .Property)] - public sealed class RequiresReflectionAttribute : + public sealed class RequiresReflectionAttribute : { public RequiresReflectionAttribute(string reason) { } public string? AotAlternative { get; set; } @@ -1807,7 +1807,7 @@ namespace .Exceptions { public BeforeTestSessionException(string message, innerException) { } } - public class CircularDependencyException : + public class CircularDependencyException : { public CircularDependencyException() { } public CircularDependencyException(string message) { } @@ -1819,7 +1819,7 @@ namespace .Exceptions public FailTestException(string reason) { } public string Reason { get; } } - public class GenericTypeResolutionException : + public class GenericTypeResolutionException : { public GenericTypeResolutionException(string message) { } public GenericTypeResolutionException(string message, innerException) { } @@ -1833,7 +1833,7 @@ namespace .Exceptions public SkipTestException(string reason) { } public string Reason { get; } } - public class TUnitException : + public class TUnitException : { public TUnitException() { } public TUnitException(string? message) { } @@ -1852,7 +1852,7 @@ namespace .Exceptions public .<> HookExceptions { get; } public ? TestException { get; } } - public class TestFailedInitializationException : + public class TestFailedInitializationException : { public TestFailedInitializationException(string? message, ? innerException) { } } @@ -2695,7 +2695,7 @@ namespace .Services public string FormatArgumentValue(object? value) { } public string FormatTestName(string template, object?[]? classArgs = null, object?[]? methodArgs = null, .? propertyValues = null) { } } - public class TestServiceProvider : + public class TestServiceProvider : { public TestServiceProvider() { } public . AddSingleton( serviceType, object service) { } @@ -2723,4 +2723,4 @@ namespace .StaticProperties public static void Register(. metadata) { } public static bool TryGetInitializedValue( declaringType, string propertyName, out object? value) { } } -} \ No newline at end of file +} From 6c1962872792f85d1c6e1a2923e99c00ee451b44 Mon Sep 17 00:00:00 2001 From: Tom Longhurst <30480171+thomhurst@users.noreply.github.com> Date: Mon, 12 Jan 2026 01:19:11 +0000 Subject: [PATCH 2/3] chore: update public API snapshots for TestDetails constructor change Update verified snapshots to match current PublicApiGenerator output after constructor signature change from TestDetails() to TestDetails(IReadOnlyList allAttributes). Co-Authored-By: Claude Opus 4.5 --- ...Has_No_API_Changes.DotNet10_0.verified.txt | 36 +++++++++---------- ..._Has_No_API_Changes.DotNet8_0.verified.txt | 36 +++++++++---------- ..._Has_No_API_Changes.DotNet9_0.verified.txt | 36 +++++++++---------- ...ary_Has_No_API_Changes.Net4_7.verified.txt | 36 +++++++++---------- 4 files changed, 72 insertions(+), 72 deletions(-) diff --git a/TUnit.PublicAPI/Tests.Core_Library_Has_No_API_Changes.DotNet10_0.verified.txt b/TUnit.PublicAPI/Tests.Core_Library_Has_No_API_Changes.DotNet10_0.verified.txt index cee3e2aeaa..a37b740d48 100644 --- a/TUnit.PublicAPI/Tests.Core_Library_Has_No_API_Changes.DotNet10_0.verified.txt +++ b/TUnit.PublicAPI/Tests.Core_Library_Has_No_API_Changes.DotNet10_0.verified.txt @@ -2,7 +2,7 @@ [assembly: .(@", PublicKey=0024000004800000940000000602000000240000525341310004000001000100698a70398fa0b2230c5a72e3bd9d56b48f809f6173e49a19fbb942d621be93ad48c5566b47b28faabc359b9ad3ff4e00bbdea88f5bdfa250f391fedd28182b2e37b55d429c0151a42a98ea7a5821818cd15a79fef9903e8607a88304cf3e0317bf86ec96e32e1381535a6582251e5a6eed40b5a3ed82bc444598b1269cce57a7")] [assembly: .(@", PublicKey=0024000004800000940000000602000000240000525341310004000001000100698a70398fa0b2230c5a72e3bd9d56b48f809f6173e49a19fbb942d621be93ad48c5566b47b28faabc359b9ad3ff4e00bbdea88f5bdfa250f391fedd28182b2e37b55d429c0151a42a98ea7a5821818cd15a79fef9903e8607a88304cf3e0317bf86ec96e32e1381535a6582251e5a6eed40b5a3ed82bc444598b1269cce57a7")] [assembly: .(".NETCoreApp,Version=v10.0", FrameworkDisplayName=".NET 10.0")] -namespace +namespace { public abstract class AbstractDynamicTest { @@ -426,7 +426,7 @@ namespace public CultureExecutor(.CultureInfo cultureInfo) { } protected override void ConfigureThread(.Thread thread) { } } - public class DataGenerationException : + public class DataGenerationException : { public DataGenerationException(string message) { } public DataGenerationException(string message, innerException) { } @@ -676,7 +676,7 @@ namespace public object?[]? TestMethodArguments { get; set; } public override .<.DiscoveryResult> GetTests() { } } - public class EngineCancellationToken : + public class EngineCancellationToken : { public EngineCancellationToken() { } public .CancellationToken Token { get; } @@ -749,7 +749,7 @@ namespace public override .<.DiscoveryResult> GetTests() { } } [(.Class | .Method, AllowMultiple=true)] - public sealed class GenerateGenericTestAttribute : + public sealed class GenerateGenericTestAttribute : { public GenerateGenericTestAttribute(params [] typeArguments) { } public [] TypeArguments { get; } @@ -1152,7 +1152,7 @@ namespace public static void Register( type, ..IPropertySource source) { } } [(.Assembly, AllowMultiple=false, Inherited=false)] - public sealed class ReflectionModeAttribute : + public sealed class ReflectionModeAttribute : { public ReflectionModeAttribute() { } } @@ -1273,7 +1273,7 @@ namespace { public TestAttribute([.] string file = "", [.] int line = 0) { } } - public sealed class TestBuildContext : .Context, + public sealed class TestBuildContext : .Context, { public TestBuildContext() { } public new static .TestBuildContext? Current { get; } @@ -1299,7 +1299,7 @@ namespace public TestBuilderContextAccessor(.TestBuilderContext context) { } public .TestBuilderContext Current { get; set; } } - public class TestBuilderException : + public class TestBuilderException : { public TestBuilderException() { } public TestBuilderException(string message) { } @@ -1420,7 +1420,7 @@ namespace } public class TestDetails : ., ., ., ., ., . { - public TestDetails(IReadOnlyList allAttributes) { } + public TestDetails(.<> allAttributes) { } public . Attributes { get; } public required .<, .<>> AttributesByType { get; init; } public . Categories { get; } @@ -1457,7 +1457,7 @@ namespace public class TestDetails : .TestDetails where T : class { - public TestDetails(IReadOnlyList allAttributes) { } + public TestDetails(.<> allAttributes) { } } public class TestDiscoveryContext : .Context { @@ -1636,7 +1636,7 @@ namespace .AotCompatibility TupleInterfaceBased = 3, } [(.Method)] - public class AotCompatibleAttribute : + public class AotCompatibleAttribute : { public AotCompatibleAttribute() { } public string? Details { get; init; } @@ -1659,14 +1659,14 @@ namespace .AotCompatibility namespace .Attributes { [(.Class | .Constructor | .Method | .Property)] - public sealed class AotCompatibleAttribute : + public sealed class AotCompatibleAttribute : { public AotCompatibleAttribute() { } public string? AlternativeForReflection { get; set; } public string? Notes { get; set; } } [(.Class | .Constructor | .Method | .Property)] - public sealed class RequiresReflectionAttribute : + public sealed class RequiresReflectionAttribute : { public RequiresReflectionAttribute(string reason) { } public string? AotAlternative { get; set; } @@ -1854,7 +1854,7 @@ namespace .Exceptions { public BeforeTestSessionException(string message, innerException) { } } - public class CircularDependencyException : + public class CircularDependencyException : { public CircularDependencyException() { } public CircularDependencyException(string message) { } @@ -1866,7 +1866,7 @@ namespace .Exceptions public FailTestException(string reason) { } public string Reason { get; } } - public class GenericTypeResolutionException : + public class GenericTypeResolutionException : { public GenericTypeResolutionException(string message) { } public GenericTypeResolutionException(string message, innerException) { } @@ -1880,7 +1880,7 @@ namespace .Exceptions public SkipTestException(string reason) { } public string Reason { get; } } - public class TUnitException : + public class TUnitException : { public TUnitException() { } public TUnitException(string? message) { } @@ -1899,7 +1899,7 @@ namespace .Exceptions public .<> HookExceptions { get; } public ? TestException { get; } } - public class TestFailedInitializationException : + public class TestFailedInitializationException : { public TestFailedInitializationException(string? message, ? innerException) { } } @@ -2774,7 +2774,7 @@ namespace .Services public string FormatArgumentValue(object? value) { } public string FormatTestName(string template, object?[]? classArgs = null, object?[]? methodArgs = null, .? propertyValues = null) { } } - public class TestServiceProvider : + public class TestServiceProvider : { public TestServiceProvider() { } public . AddSingleton( serviceType, object service) { } @@ -2802,4 +2802,4 @@ namespace .StaticProperties public static void Register(. metadata) { } public static bool TryGetInitializedValue( declaringType, string propertyName, out object? value) { } } -} +} \ No newline at end of file diff --git a/TUnit.PublicAPI/Tests.Core_Library_Has_No_API_Changes.DotNet8_0.verified.txt b/TUnit.PublicAPI/Tests.Core_Library_Has_No_API_Changes.DotNet8_0.verified.txt index 315a1f0dae..f6dc6eb0b9 100644 --- a/TUnit.PublicAPI/Tests.Core_Library_Has_No_API_Changes.DotNet8_0.verified.txt +++ b/TUnit.PublicAPI/Tests.Core_Library_Has_No_API_Changes.DotNet8_0.verified.txt @@ -2,7 +2,7 @@ [assembly: .(@", PublicKey=0024000004800000940000000602000000240000525341310004000001000100698a70398fa0b2230c5a72e3bd9d56b48f809f6173e49a19fbb942d621be93ad48c5566b47b28faabc359b9ad3ff4e00bbdea88f5bdfa250f391fedd28182b2e37b55d429c0151a42a98ea7a5821818cd15a79fef9903e8607a88304cf3e0317bf86ec96e32e1381535a6582251e5a6eed40b5a3ed82bc444598b1269cce57a7")] [assembly: .(@", PublicKey=0024000004800000940000000602000000240000525341310004000001000100698a70398fa0b2230c5a72e3bd9d56b48f809f6173e49a19fbb942d621be93ad48c5566b47b28faabc359b9ad3ff4e00bbdea88f5bdfa250f391fedd28182b2e37b55d429c0151a42a98ea7a5821818cd15a79fef9903e8607a88304cf3e0317bf86ec96e32e1381535a6582251e5a6eed40b5a3ed82bc444598b1269cce57a7")] [assembly: .(".NETCoreApp,Version=v8.0", FrameworkDisplayName=".NET 8.0")] -namespace +namespace { public abstract class AbstractDynamicTest { @@ -426,7 +426,7 @@ namespace public CultureExecutor(.CultureInfo cultureInfo) { } protected override void ConfigureThread(.Thread thread) { } } - public class DataGenerationException : + public class DataGenerationException : { public DataGenerationException(string message) { } public DataGenerationException(string message, innerException) { } @@ -676,7 +676,7 @@ namespace public object?[]? TestMethodArguments { get; set; } public override .<.DiscoveryResult> GetTests() { } } - public class EngineCancellationToken : + public class EngineCancellationToken : { public EngineCancellationToken() { } public .CancellationToken Token { get; } @@ -749,7 +749,7 @@ namespace public override .<.DiscoveryResult> GetTests() { } } [(.Class | .Method, AllowMultiple=true)] - public sealed class GenerateGenericTestAttribute : + public sealed class GenerateGenericTestAttribute : { public GenerateGenericTestAttribute(params [] typeArguments) { } public [] TypeArguments { get; } @@ -1152,7 +1152,7 @@ namespace public static void Register( type, ..IPropertySource source) { } } [(.Assembly, AllowMultiple=false, Inherited=false)] - public sealed class ReflectionModeAttribute : + public sealed class ReflectionModeAttribute : { public ReflectionModeAttribute() { } } @@ -1273,7 +1273,7 @@ namespace { public TestAttribute([.] string file = "", [.] int line = 0) { } } - public sealed class TestBuildContext : .Context, + public sealed class TestBuildContext : .Context, { public TestBuildContext() { } public new static .TestBuildContext? Current { get; } @@ -1299,7 +1299,7 @@ namespace public TestBuilderContextAccessor(.TestBuilderContext context) { } public .TestBuilderContext Current { get; set; } } - public class TestBuilderException : + public class TestBuilderException : { public TestBuilderException() { } public TestBuilderException(string message) { } @@ -1420,7 +1420,7 @@ namespace } public class TestDetails : ., ., ., ., ., . { - public TestDetails(IReadOnlyList allAttributes) { } + public TestDetails(.<> allAttributes) { } public . Attributes { get; } public required .<, .<>> AttributesByType { get; init; } public . Categories { get; } @@ -1457,7 +1457,7 @@ namespace public class TestDetails : .TestDetails where T : class { - public TestDetails(IReadOnlyList allAttributes) { } + public TestDetails(.<> allAttributes) { } } public class TestDiscoveryContext : .Context { @@ -1636,7 +1636,7 @@ namespace .AotCompatibility TupleInterfaceBased = 3, } [(.Method)] - public class AotCompatibleAttribute : + public class AotCompatibleAttribute : { public AotCompatibleAttribute() { } public string? Details { get; init; } @@ -1659,14 +1659,14 @@ namespace .AotCompatibility namespace .Attributes { [(.Class | .Constructor | .Method | .Property)] - public sealed class AotCompatibleAttribute : + public sealed class AotCompatibleAttribute : { public AotCompatibleAttribute() { } public string? AlternativeForReflection { get; set; } public string? Notes { get; set; } } [(.Class | .Constructor | .Method | .Property)] - public sealed class RequiresReflectionAttribute : + public sealed class RequiresReflectionAttribute : { public RequiresReflectionAttribute(string reason) { } public string? AotAlternative { get; set; } @@ -1854,7 +1854,7 @@ namespace .Exceptions { public BeforeTestSessionException(string message, innerException) { } } - public class CircularDependencyException : + public class CircularDependencyException : { public CircularDependencyException() { } public CircularDependencyException(string message) { } @@ -1866,7 +1866,7 @@ namespace .Exceptions public FailTestException(string reason) { } public string Reason { get; } } - public class GenericTypeResolutionException : + public class GenericTypeResolutionException : { public GenericTypeResolutionException(string message) { } public GenericTypeResolutionException(string message, innerException) { } @@ -1880,7 +1880,7 @@ namespace .Exceptions public SkipTestException(string reason) { } public string Reason { get; } } - public class TUnitException : + public class TUnitException : { public TUnitException() { } public TUnitException(string? message) { } @@ -1899,7 +1899,7 @@ namespace .Exceptions public .<> HookExceptions { get; } public ? TestException { get; } } - public class TestFailedInitializationException : + public class TestFailedInitializationException : { public TestFailedInitializationException(string? message, ? innerException) { } } @@ -2774,7 +2774,7 @@ namespace .Services public string FormatArgumentValue(object? value) { } public string FormatTestName(string template, object?[]? classArgs = null, object?[]? methodArgs = null, .? propertyValues = null) { } } - public class TestServiceProvider : + public class TestServiceProvider : { public TestServiceProvider() { } public . AddSingleton( serviceType, object service) { } @@ -2802,4 +2802,4 @@ namespace .StaticProperties public static void Register(. metadata) { } public static bool TryGetInitializedValue( declaringType, string propertyName, out object? value) { } } -} +} \ No newline at end of file diff --git a/TUnit.PublicAPI/Tests.Core_Library_Has_No_API_Changes.DotNet9_0.verified.txt b/TUnit.PublicAPI/Tests.Core_Library_Has_No_API_Changes.DotNet9_0.verified.txt index 66bc06dac8..33bedbec01 100644 --- a/TUnit.PublicAPI/Tests.Core_Library_Has_No_API_Changes.DotNet9_0.verified.txt +++ b/TUnit.PublicAPI/Tests.Core_Library_Has_No_API_Changes.DotNet9_0.verified.txt @@ -2,7 +2,7 @@ [assembly: .(@", PublicKey=0024000004800000940000000602000000240000525341310004000001000100698a70398fa0b2230c5a72e3bd9d56b48f809f6173e49a19fbb942d621be93ad48c5566b47b28faabc359b9ad3ff4e00bbdea88f5bdfa250f391fedd28182b2e37b55d429c0151a42a98ea7a5821818cd15a79fef9903e8607a88304cf3e0317bf86ec96e32e1381535a6582251e5a6eed40b5a3ed82bc444598b1269cce57a7")] [assembly: .(@", PublicKey=0024000004800000940000000602000000240000525341310004000001000100698a70398fa0b2230c5a72e3bd9d56b48f809f6173e49a19fbb942d621be93ad48c5566b47b28faabc359b9ad3ff4e00bbdea88f5bdfa250f391fedd28182b2e37b55d429c0151a42a98ea7a5821818cd15a79fef9903e8607a88304cf3e0317bf86ec96e32e1381535a6582251e5a6eed40b5a3ed82bc444598b1269cce57a7")] [assembly: .(".NETCoreApp,Version=v9.0", FrameworkDisplayName=".NET 9.0")] -namespace +namespace { public abstract class AbstractDynamicTest { @@ -426,7 +426,7 @@ namespace public CultureExecutor(.CultureInfo cultureInfo) { } protected override void ConfigureThread(.Thread thread) { } } - public class DataGenerationException : + public class DataGenerationException : { public DataGenerationException(string message) { } public DataGenerationException(string message, innerException) { } @@ -676,7 +676,7 @@ namespace public object?[]? TestMethodArguments { get; set; } public override .<.DiscoveryResult> GetTests() { } } - public class EngineCancellationToken : + public class EngineCancellationToken : { public EngineCancellationToken() { } public .CancellationToken Token { get; } @@ -749,7 +749,7 @@ namespace public override .<.DiscoveryResult> GetTests() { } } [(.Class | .Method, AllowMultiple=true)] - public sealed class GenerateGenericTestAttribute : + public sealed class GenerateGenericTestAttribute : { public GenerateGenericTestAttribute(params [] typeArguments) { } public [] TypeArguments { get; } @@ -1152,7 +1152,7 @@ namespace public static void Register( type, ..IPropertySource source) { } } [(.Assembly, AllowMultiple=false, Inherited=false)] - public sealed class ReflectionModeAttribute : + public sealed class ReflectionModeAttribute : { public ReflectionModeAttribute() { } } @@ -1273,7 +1273,7 @@ namespace { public TestAttribute([.] string file = "", [.] int line = 0) { } } - public sealed class TestBuildContext : .Context, + public sealed class TestBuildContext : .Context, { public TestBuildContext() { } public new static .TestBuildContext? Current { get; } @@ -1299,7 +1299,7 @@ namespace public TestBuilderContextAccessor(.TestBuilderContext context) { } public .TestBuilderContext Current { get; set; } } - public class TestBuilderException : + public class TestBuilderException : { public TestBuilderException() { } public TestBuilderException(string message) { } @@ -1420,7 +1420,7 @@ namespace } public class TestDetails : ., ., ., ., ., . { - public TestDetails(IReadOnlyList allAttributes) { } + public TestDetails(.<> allAttributes) { } public . Attributes { get; } public required .<, .<>> AttributesByType { get; init; } public . Categories { get; } @@ -1457,7 +1457,7 @@ namespace public class TestDetails : .TestDetails where T : class { - public TestDetails(IReadOnlyList allAttributes) { } + public TestDetails(.<> allAttributes) { } } public class TestDiscoveryContext : .Context { @@ -1636,7 +1636,7 @@ namespace .AotCompatibility TupleInterfaceBased = 3, } [(.Method)] - public class AotCompatibleAttribute : + public class AotCompatibleAttribute : { public AotCompatibleAttribute() { } public string? Details { get; init; } @@ -1659,14 +1659,14 @@ namespace .AotCompatibility namespace .Attributes { [(.Class | .Constructor | .Method | .Property)] - public sealed class AotCompatibleAttribute : + public sealed class AotCompatibleAttribute : { public AotCompatibleAttribute() { } public string? AlternativeForReflection { get; set; } public string? Notes { get; set; } } [(.Class | .Constructor | .Method | .Property)] - public sealed class RequiresReflectionAttribute : + public sealed class RequiresReflectionAttribute : { public RequiresReflectionAttribute(string reason) { } public string? AotAlternative { get; set; } @@ -1854,7 +1854,7 @@ namespace .Exceptions { public BeforeTestSessionException(string message, innerException) { } } - public class CircularDependencyException : + public class CircularDependencyException : { public CircularDependencyException() { } public CircularDependencyException(string message) { } @@ -1866,7 +1866,7 @@ namespace .Exceptions public FailTestException(string reason) { } public string Reason { get; } } - public class GenericTypeResolutionException : + public class GenericTypeResolutionException : { public GenericTypeResolutionException(string message) { } public GenericTypeResolutionException(string message, innerException) { } @@ -1880,7 +1880,7 @@ namespace .Exceptions public SkipTestException(string reason) { } public string Reason { get; } } - public class TUnitException : + public class TUnitException : { public TUnitException() { } public TUnitException(string? message) { } @@ -1899,7 +1899,7 @@ namespace .Exceptions public .<> HookExceptions { get; } public ? TestException { get; } } - public class TestFailedInitializationException : + public class TestFailedInitializationException : { public TestFailedInitializationException(string? message, ? innerException) { } } @@ -2774,7 +2774,7 @@ namespace .Services public string FormatArgumentValue(object? value) { } public string FormatTestName(string template, object?[]? classArgs = null, object?[]? methodArgs = null, .? propertyValues = null) { } } - public class TestServiceProvider : + public class TestServiceProvider : { public TestServiceProvider() { } public . AddSingleton( serviceType, object service) { } @@ -2802,4 +2802,4 @@ namespace .StaticProperties public static void Register(. metadata) { } public static bool TryGetInitializedValue( declaringType, string propertyName, out object? value) { } } -} +} \ No newline at end of file diff --git a/TUnit.PublicAPI/Tests.Core_Library_Has_No_API_Changes.Net4_7.verified.txt b/TUnit.PublicAPI/Tests.Core_Library_Has_No_API_Changes.Net4_7.verified.txt index eedf5df730..220dd7716f 100644 --- a/TUnit.PublicAPI/Tests.Core_Library_Has_No_API_Changes.Net4_7.verified.txt +++ b/TUnit.PublicAPI/Tests.Core_Library_Has_No_API_Changes.Net4_7.verified.txt @@ -2,7 +2,7 @@ [assembly: .(@", PublicKey=0024000004800000940000000602000000240000525341310004000001000100698a70398fa0b2230c5a72e3bd9d56b48f809f6173e49a19fbb942d621be93ad48c5566b47b28faabc359b9ad3ff4e00bbdea88f5bdfa250f391fedd28182b2e37b55d429c0151a42a98ea7a5821818cd15a79fef9903e8607a88304cf3e0317bf86ec96e32e1381535a6582251e5a6eed40b5a3ed82bc444598b1269cce57a7")] [assembly: .(@", PublicKey=0024000004800000940000000602000000240000525341310004000001000100698a70398fa0b2230c5a72e3bd9d56b48f809f6173e49a19fbb942d621be93ad48c5566b47b28faabc359b9ad3ff4e00bbdea88f5bdfa250f391fedd28182b2e37b55d429c0151a42a98ea7a5821818cd15a79fef9903e8607a88304cf3e0317bf86ec96e32e1381535a6582251e5a6eed40b5a3ed82bc444598b1269cce57a7")] [assembly: .(".NETStandard,Version=v2.0", FrameworkDisplayName=".NET Standard 2.0")] -namespace +namespace { public abstract class AbstractDynamicTest { @@ -406,7 +406,7 @@ namespace public CultureExecutor(.CultureInfo cultureInfo) { } protected override void ConfigureThread(.Thread thread) { } } - public class DataGenerationException : + public class DataGenerationException : { public DataGenerationException(string message) { } public DataGenerationException(string message, innerException) { } @@ -653,7 +653,7 @@ namespace public object?[]? TestMethodArguments { get; set; } public override .<.DiscoveryResult> GetTests() { } } - public class EngineCancellationToken : + public class EngineCancellationToken : { public EngineCancellationToken() { } public .CancellationToken Token { get; } @@ -726,7 +726,7 @@ namespace public override .<.DiscoveryResult> GetTests() { } } [(.Class | .Method, AllowMultiple=true)] - public sealed class GenerateGenericTestAttribute : + public sealed class GenerateGenericTestAttribute : { public GenerateGenericTestAttribute(params [] typeArguments) { } public [] TypeArguments { get; } @@ -1112,7 +1112,7 @@ namespace public static void Register( type, ..IPropertySource source) { } } [(.Assembly, AllowMultiple=false, Inherited=false)] - public sealed class ReflectionModeAttribute : + public sealed class ReflectionModeAttribute : { public ReflectionModeAttribute() { } } @@ -1228,7 +1228,7 @@ namespace { public TestAttribute([.] string file = "", [.] int line = 0) { } } - public sealed class TestBuildContext : .Context, + public sealed class TestBuildContext : .Context, { public TestBuildContext() { } public new static .TestBuildContext? Current { get; } @@ -1254,7 +1254,7 @@ namespace public TestBuilderContextAccessor(.TestBuilderContext context) { } public .TestBuilderContext Current { get; set; } } - public class TestBuilderException : + public class TestBuilderException : { public TestBuilderException() { } public TestBuilderException(string message) { } @@ -1375,7 +1375,7 @@ namespace } public class TestDetails : ., ., ., ., ., . { - public TestDetails(IReadOnlyList allAttributes) { } + public TestDetails(.<> allAttributes) { } public . Attributes { get; } public required .<, .<>> AttributesByType { get; init; } public . Categories { get; } @@ -1411,7 +1411,7 @@ namespace public class TestDetails : .TestDetails where T : class { - public TestDetails(IReadOnlyList allAttributes) { } + public TestDetails(.<> allAttributes) { } } public class TestDiscoveryContext : .Context { @@ -1589,7 +1589,7 @@ namespace .AotCompatibility TupleInterfaceBased = 3, } [(.Method)] - public class AotCompatibleAttribute : + public class AotCompatibleAttribute : { public AotCompatibleAttribute() { } public string? Details { get; init; } @@ -1612,14 +1612,14 @@ namespace .AotCompatibility namespace .Attributes { [(.Class | .Constructor | .Method | .Property)] - public sealed class AotCompatibleAttribute : + public sealed class AotCompatibleAttribute : { public AotCompatibleAttribute() { } public string? AlternativeForReflection { get; set; } public string? Notes { get; set; } } [(.Class | .Constructor | .Method | .Property)] - public sealed class RequiresReflectionAttribute : + public sealed class RequiresReflectionAttribute : { public RequiresReflectionAttribute(string reason) { } public string? AotAlternative { get; set; } @@ -1807,7 +1807,7 @@ namespace .Exceptions { public BeforeTestSessionException(string message, innerException) { } } - public class CircularDependencyException : + public class CircularDependencyException : { public CircularDependencyException() { } public CircularDependencyException(string message) { } @@ -1819,7 +1819,7 @@ namespace .Exceptions public FailTestException(string reason) { } public string Reason { get; } } - public class GenericTypeResolutionException : + public class GenericTypeResolutionException : { public GenericTypeResolutionException(string message) { } public GenericTypeResolutionException(string message, innerException) { } @@ -1833,7 +1833,7 @@ namespace .Exceptions public SkipTestException(string reason) { } public string Reason { get; } } - public class TUnitException : + public class TUnitException : { public TUnitException() { } public TUnitException(string? message) { } @@ -1852,7 +1852,7 @@ namespace .Exceptions public .<> HookExceptions { get; } public ? TestException { get; } } - public class TestFailedInitializationException : + public class TestFailedInitializationException : { public TestFailedInitializationException(string? message, ? innerException) { } } @@ -2695,7 +2695,7 @@ namespace .Services public string FormatArgumentValue(object? value) { } public string FormatTestName(string template, object?[]? classArgs = null, object?[]? methodArgs = null, .? propertyValues = null) { } } - public class TestServiceProvider : + public class TestServiceProvider : { public TestServiceProvider() { } public . AddSingleton( serviceType, object service) { } @@ -2723,4 +2723,4 @@ namespace .StaticProperties public static void Register(. metadata) { } public static bool TryGetInitializedValue( declaringType, string propertyName, out object? value) { } } -} +} \ No newline at end of file From bab3e479a1548f0e586afea4f199304b14ecfa90 Mon Sep 17 00:00:00 2001 From: Tom Longhurst <30480171+thomhurst@users.noreply.github.com> Date: Mon, 12 Jan 2026 01:41:19 +0000 Subject: [PATCH 3/3] fix: restore XML documentation comment syntax Change `// ` back to `/// ` for proper XML documentation generation. Also removed outdated cache reference from the comment since attributes are now passed directly. Co-Authored-By: Claude Opus 4.5 --- TUnit.Core/TestDetails.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/TUnit.Core/TestDetails.cs b/TUnit.Core/TestDetails.cs index be72b6a8b6..4227e5b81c 100644 --- a/TUnit.Core/TestDetails.cs +++ b/TUnit.Core/TestDetails.cs @@ -65,9 +65,8 @@ public IEnumerable GetAttributes() where T : Attribute ? attrs.OfType() : []; - // + /// /// Gets all attributes as a flattened collection. - /// Cached after first access for performance. /// /// All attributes associated with this test. public IReadOnlyList GetAllAttributes() => _allAttributes;