From 658edd8dd99da8bfdd3c6c8eec2c32a929c96ef1 Mon Sep 17 00:00:00 2001 From: Tom Longhurst <30480171+thomhurst@users.noreply.github.com> Date: Fri, 24 Apr 2026 02:08:58 +0100 Subject: [PATCH 1/4] perf(engine/core): reduce per-test allocations (#5688) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Addresses the six per-test allocation/reflection sources called out in #5688 — individually <1% CPU, collectively driving gen0 churn and steady-state latency. 1. TestCoordinator: guard Console.Out/Error.FlushAsync on the new Context.HasCapturedOutput check so the SynchronizedTextWriter lock is skipped for passing tests with no output. Include the console interceptor line buffers in the signal so partial writes still force a flush. 2. ObjectGraphDiscoverer.GetTypeHierarchy: cache results in a static ConcurrentDictionary> — hierarchy is invariant per type and was allocating a fresh HashSet per test. Cache is cleared alongside PropertyCacheManager in ClearCache. 3. TestMetadata.CreateExecutableTestFactory: replace the closure- allocating lambda with a static method reference. Per-test state now lives on a new internal ExecutableTest subclass instead of captured-variable closures, saving ~2 delegate allocations per test. 4. TestRegistry expression trees: bridge ValueTask/ValueTask through a new ValueTaskBridge helper that checks IsCompletedSuccessfully before calling AsTask() — synchronously-completed values avoid the Task allocation entirely. 5. TestMetadata.TestSessionId: drop the eager Guid.NewGuid().ToString() default (every engine factory immediately overwrites it) and default to string.Empty. 6. PropertyInjectionMetadata.GetProperty: add a compile-time-generated Func getter so the engine hot path in ObjectGraphDiscoverer.TraverseSourceGeneratedProperties and PropertyInjectionPlan.GetPropertyValues no longer does a Type.GetProperty reflection lookup per test invocation. The source generator emits a direct strongly-typed lambda; hand-authored or older metadata falls back to a cached PropertyInfo.GetValue via GetOrCreateGetter so both source-gen and reflection modes benefit. --- .../PropertyInjectionSourceGenerator.cs | 12 ++++ TUnit.Core/Context.cs | 10 ++- TUnit.Core/Discovery/ObjectGraphDiscoverer.cs | 45 +++++++------ TUnit.Core/ExecutableTest.cs | 22 +++++-- TUnit.Core/ExecutableTest`1.cs | 59 +++++++++++++++++ .../PropertyInjectionMetadata.cs | 41 ++++++++++++ .../PropertyInjectionPlanBuilder.cs | 9 ++- TUnit.Core/TestContext.Output.cs | 4 +- TUnit.Core/TestMetadata.cs | 6 +- TUnit.Core/TestMetadata`1.cs | 63 ++++++------------- TUnit.Engine/Helpers/ValueTaskBridge.cs | 45 +++++++++++++ .../Services/TestExecution/TestCoordinator.cs | 23 ++++--- TUnit.Engine/Services/TestRegistry.cs | 15 +++-- 13 files changed, 260 insertions(+), 94 deletions(-) create mode 100644 TUnit.Core/ExecutableTest`1.cs create mode 100644 TUnit.Engine/Helpers/ValueTaskBridge.cs diff --git a/TUnit.Core.SourceGenerator/Generators/PropertyInjectionSourceGenerator.cs b/TUnit.Core.SourceGenerator/Generators/PropertyInjectionSourceGenerator.cs index 0ba602ca70..eaa06041be 100644 --- a/TUnit.Core.SourceGenerator/Generators/PropertyInjectionSourceGenerator.cs +++ b/TUnit.Core.SourceGenerator/Generators/PropertyInjectionSourceGenerator.cs @@ -678,6 +678,18 @@ private static void GeneratePropertyMetadata(StringBuilder sb, PropertyDataSourc sb.AppendLine(" return dataSource;"); sb.AppendLine(" },"); + // GetProperty delegate — direct strongly-typed read so the engine hot path + // doesn't fall back to Type.GetProperty reflection. Static instance-typed cast + // mirrors SetProperty and stays AOT-friendly. + if (prop.IsStatic) + { + sb.AppendLine($" GetProperty = static _ => {prop.ContainingTypeFullyQualified}.{prop.PropertyName},"); + } + else + { + sb.AppendLine($" GetProperty = static instance => (({classTypeName})instance).{prop.PropertyName},"); + } + // SetProperty delegate sb.AppendLine(" SetProperty = (instance, value) =>"); sb.AppendLine(" {"); diff --git a/TUnit.Core/Context.cs b/TUnit.Core/Context.cs index a4d00352ce..b4ce1c3281 100644 --- a/TUnit.Core/Context.cs +++ b/TUnit.Core/Context.cs @@ -112,8 +112,14 @@ public void AddAsyncLocalValues() // Fast path for callers that need to know whether anything was ever captured — // lets the result-building code skip the reader/writer lock acquisition entirely - // for the (very common) case of a passing test with no output. - internal virtual bool HasCapturedOutput => _outputWriter != null || _errorOutputWriter != null; + // for the (very common) case of a passing test with no output. Includes the + // console interceptor line buffers so partial writes (Console.Write without a + // newline) still force a flush at end-of-test. + internal virtual bool HasCapturedOutput => + _outputWriter != null + || _errorOutputWriter != null + || _consoleStdOutLineBuffer != null + || _consoleStdErrLineBuffer != null; public DefaultLogger GetDefaultLogger() { diff --git a/TUnit.Core/Discovery/ObjectGraphDiscoverer.cs b/TUnit.Core/Discovery/ObjectGraphDiscoverer.cs index 5d77386df0..f1ded7c7dd 100644 --- a/TUnit.Core/Discovery/ObjectGraphDiscoverer.cs +++ b/TUnit.Core/Discovery/ObjectGraphDiscoverer.cs @@ -248,6 +248,7 @@ void Recurse(object value, int depth) public static void ClearCache() { PropertyCacheManager.ClearCache(); + TypeHierarchyCache.Clear(); ClearDiscoveryErrors(); } @@ -339,13 +340,11 @@ private static void TraverseSourceGeneratedProperties( foreach (var metadata in sourceGeneratedProperties) { cancellationToken.ThrowIfCancellationRequested(); - var property = metadata.ContainingType.GetProperty(metadata.PropertyName); - if (property == null || !property.CanRead) - { - continue; - } - - var value = property.GetValue(obj); + // Use the compile-time-generated getter when the source generator emitted one, + // otherwise fall back to a cached reflection-based getter. Eliminates the + // per-test Type.GetProperty reflection lookup on the hot path. + var getter = metadata.GetOrCreateGetter(); + var value = getter(obj); if (value != null && tryAdd(value, currentDepth)) { recurse(value, currentDepth + 1); @@ -604,26 +603,34 @@ private static void CollectRootObjects( } } + /// + /// Cache of type hierarchy sets keyed by . Per-type hierarchy is invariant, + /// and each invocation otherwise allocates a fresh of strings. + /// Populated on first access per type and read-only thereafter. + /// + private static readonly ConcurrentDictionary> TypeHierarchyCache = new(); + /// /// Gets all types in the inheritance hierarchy from the given type up to (but not including) object. /// private static HashSet GetTypeHierarchy(Type type) - { - var result = new HashSet(); - var currentType = type; - - while (currentType != null && currentType != typeof(object)) + => TypeHierarchyCache.GetOrAdd(type, static t => { - if (currentType.FullName != null) + var result = new HashSet(); + var currentType = t; + + while (currentType != null && currentType != typeof(object)) { - result.Add(currentType.FullName); - } + if (currentType.FullName != null) + { + result.Add(currentType.FullName); + } - currentType = currentType.BaseType; - } + currentType = currentType.BaseType; + } - return result; - } + return result; + }); /// /// Determines if a cache key represents a direct property (belonging to test class hierarchy) diff --git a/TUnit.Core/ExecutableTest.cs b/TUnit.Core/ExecutableTest.cs index 1199cf8414..b960080fd5 100644 --- a/TUnit.Core/ExecutableTest.cs +++ b/TUnit.Core/ExecutableTest.cs @@ -5,13 +5,23 @@ namespace TUnit.Core; /// Replaces ExecutableTest and DynamicExecutableTest with a single implementation. /// All mode-specific logic is handled during delegate creation, not execution. /// -public sealed class ExecutableTest : AbstractExecutableTest +public class ExecutableTest : AbstractExecutableTest { - private readonly Func> _createInstance; - private readonly Func _invokeTest; + // Null only inside typed subclasses that override CreateInstanceAsync/InvokeTestAsync and + // therefore never invoke the delegates. The parameterless constructor enforces that invariant. + private readonly Func>? _createInstance; + private readonly Func? _invokeTest; /// - /// Creates a UnifiedExecutableTest where all mode-specific behavior is encapsulated in the delegates. + /// Constructor for subclasses that supply their own invocation logic by overriding + /// and directly. + /// + private protected ExecutableTest() + { + } + + /// + /// Creates an ExecutableTest where mode-specific behavior is encapsulated in the delegates. /// Both AOT and reflection modes provide delegates with identical signatures. /// /// Delegate that creates the test instance with all necessary initialization @@ -26,11 +36,11 @@ public ExecutableTest( public override async Task CreateInstanceAsync() { - return await _createInstance(Context); + return await _createInstance!(Context); } public override async Task InvokeTestAsync(object instance, CancellationToken cancellationToken) { - await _invokeTest(instance, Arguments, Context, cancellationToken); + await _invokeTest!(instance, Arguments, Context, cancellationToken); } } diff --git a/TUnit.Core/ExecutableTest`1.cs b/TUnit.Core/ExecutableTest`1.cs new file mode 100644 index 0000000000..d6fc6ad7cf --- /dev/null +++ b/TUnit.Core/ExecutableTest`1.cs @@ -0,0 +1,59 @@ +using System.Diagnostics.CodeAnalysis; +using TUnit.Core.Helpers; + +namespace TUnit.Core; + +/// +/// Strongly typed that stores the per-test delegates from +/// as fields instead of capturing them in closures. This avoids the +/// two closure allocations (createInstance and invokeTest) that the generic factory +/// would otherwise allocate per test invocation — on a 1000-test run that is 2000 delegates saved. +/// +/// The test class type. +internal sealed class ExecutableTest< + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.PublicMethods)] + T> : ExecutableTest where T : class +{ + // Fields that the previous closures captured. ClassArguments and Arguments live on the + // base AbstractExecutableTest, so only the metadata reference plus the two ExecutableTestCreationContext + // values that aren't mirrored on the base need to be stored here. + private readonly TestMetadata _metadata; + private readonly Func>? _testClassInstanceFactory; + private readonly Type[] _resolvedClassGenericArguments; + + public ExecutableTest( + TestMetadata metadata, + ExecutableTestCreationContext context) + { + _metadata = metadata; + _testClassInstanceFactory = context.TestClassInstanceFactory; + _resolvedClassGenericArguments = context.ResolvedClassGenericArguments; + } + + public override async Task CreateInstanceAsync() + { + if (_testClassInstanceFactory != null) + { + return await _testClassInstanceFactory(); + } + + var attributes = _metadata.GetOrCreateAttributes(); + var instance = await ClassConstructorHelper.TryCreateInstanceWithClassConstructor( + attributes, + _metadata.TestClassType, + _metadata.TestSessionId, + Context); + + if (instance != null) + { + return instance; + } + + return _metadata.InstanceFactory!(_resolvedClassGenericArguments, ClassArguments); + } + + public override async Task InvokeTestAsync(object instance, CancellationToken cancellationToken) + { + await _metadata.InvokeTypedTest!((T)instance, Arguments, cancellationToken).ConfigureAwait(false); + } +} diff --git a/TUnit.Core/Interfaces/SourceGenerator/PropertyInjectionMetadata.cs b/TUnit.Core/Interfaces/SourceGenerator/PropertyInjectionMetadata.cs index bea4f11a9f..64b06b0e22 100644 --- a/TUnit.Core/Interfaces/SourceGenerator/PropertyInjectionMetadata.cs +++ b/TUnit.Core/Interfaces/SourceGenerator/PropertyInjectionMetadata.cs @@ -1,4 +1,5 @@ using System.Diagnostics.CodeAnalysis; +using System.Reflection; namespace TUnit.Core.Interfaces.SourceGenerator; @@ -7,6 +8,8 @@ namespace TUnit.Core.Interfaces.SourceGenerator; /// public sealed class PropertyInjectionMetadata { + private Func? _getProperty; + /// /// Gets the name of the property that needs injection. /// @@ -37,4 +40,42 @@ public sealed class PropertyInjectionMetadata /// Handles type casting and property setting (including init-only properties). /// public required Action SetProperty { get; init; } + + /// + /// Optional compile-time-generated getter that returns the property value from an instance. + /// When not supplied (e.g. older source-gen output or hand-authored metadata) the callers + /// fall back to a cached call. Supplying a + /// direct delegate removes a reflection lookup from + /// the per-test hot path in both source-gen and reflection modes. + /// + public Func? GetProperty + { + get => _getProperty; + init => _getProperty = value; + } + + /// + /// Returns a delegate that reads the property value from a given instance. Uses the + /// source-generated delegate when available, otherwise compiles + /// a reflection-based getter once and caches it on the metadata instance. + /// + [UnconditionalSuppressMessage("Trimming", "IL2075", + Justification = "ContainingType is annotated to preserve properties; reflection fallback is only used when source-gen did not emit a delegate.")] + internal Func GetOrCreateGetter() + { + if (_getProperty != null) + { + return _getProperty; + } + + var property = ContainingType.GetProperty(PropertyName); + if (property is null || !property.CanRead) + { + // Memoize a stub that mirrors the behavior the previous reflection-based + // call sites expected (null when the property can't be read). + return _getProperty = static _ => null; + } + + return _getProperty = property.GetValue; + } } diff --git a/TUnit.Core/PropertyInjection/PropertyInjectionPlanBuilder.cs b/TUnit.Core/PropertyInjection/PropertyInjectionPlanBuilder.cs index e49ca472c0..0a7b015641 100644 --- a/TUnit.Core/PropertyInjection/PropertyInjectionPlanBuilder.cs +++ b/TUnit.Core/PropertyInjection/PropertyInjectionPlanBuilder.cs @@ -224,6 +224,9 @@ public Task ForEachPropertyParallelAsync( /// /// Gets property values from an instance, abstracting source-gen vs reflection. + /// Uses the source-generated getter delegate on + /// when available and caches a reflection-based getter otherwise — no per-call + /// Type.GetProperty lookup on the hot path. /// public IEnumerable GetPropertyValues(object instance) { @@ -231,11 +234,7 @@ public Task ForEachPropertyParallelAsync( { foreach (var metadata in SourceGeneratedProperties) { - var property = metadata.ContainingType.GetProperty(metadata.PropertyName); - if (property?.CanRead == true) - { - yield return property.GetValue(instance); - } + yield return metadata.GetOrCreateGetter()(instance); } } else if (ReflectionProperties.Length > 0) diff --git a/TUnit.Core/TestContext.Output.cs b/TUnit.Core/TestContext.Output.cs index 92ff273b95..3931b237c4 100644 --- a/TUnit.Core/TestContext.Output.cs +++ b/TUnit.Core/TestContext.Output.cs @@ -101,7 +101,9 @@ public override string GetErrorOutput() internal string GetOutputError() => CombineOutputs(_buildTimeErrorOutput, base.GetErrorOutput()); internal override bool HasCapturedOutput => - base.HasCapturedOutput || _buildTimeOutput != null || _buildTimeErrorOutput != null; + base.HasCapturedOutput + || !string.IsNullOrEmpty(_buildTimeOutput) + || !string.IsNullOrEmpty(_buildTimeErrorOutput); private static string CombineOutputs(string? buildTimeOutput, string runtimeOutput) { diff --git a/TUnit.Core/TestMetadata.cs b/TUnit.Core/TestMetadata.cs index 1ef7e6c30e..80e6f0504f 100644 --- a/TUnit.Core/TestMetadata.cs +++ b/TUnit.Core/TestMetadata.cs @@ -70,9 +70,11 @@ internal Attribute[] GetOrCreateAttributes() public PropertyInjectionData[] PropertyInjections { get; init; } = []; /// - /// Test session ID used for data generation + /// Test session ID used for data generation. Callers must assign a real session id before + /// any data-generation code reads it; defaulting to an empty string avoids the per-instance + /// allocation that every engine caller immediately overwrites. /// - public string TestSessionId { get; set; } = Guid.NewGuid().ToString(); + public string TestSessionId { get; set; } = string.Empty; /// /// The depth of inheritance for this test method. diff --git a/TUnit.Core/TestMetadata`1.cs b/TUnit.Core/TestMetadata`1.cs index 923ec7df27..d8183fc15f 100644 --- a/TUnit.Core/TestMetadata`1.cs +++ b/TUnit.Core/TestMetadata`1.cs @@ -1,6 +1,4 @@ -using System.ComponentModel; using System.Diagnostics.CodeAnalysis; -using TUnit.Core.Helpers; using TUnit.Core.Interfaces; namespace TUnit.Core; @@ -61,12 +59,14 @@ public class TestMetadata< /// /// Factory delegate that creates an ExecutableTest for this metadata. + /// Uses a static factory method so the cached delegate is a pure method reference — + /// no closure, and per-test state is stored on the returned + /// instead of in captured lambdas. /// public override Func CreateExecutableTestFactory { get { - // Return cached factory if available if (_cachedExecutableTestFactory != null) { return _cachedExecutableTestFactory; @@ -74,47 +74,7 @@ public override Func - { - var typedMetadata = (TestMetadata)metadata; - - Func> createInstance = async testContext => - { - if (context.TestClassInstanceFactory != null) - { - return await context.TestClassInstanceFactory(); - } - - var attributes = metadata.GetOrCreateAttributes(); - var instance = await ClassConstructorHelper.TryCreateInstanceWithClassConstructor( - attributes, - TestClassType, - metadata.TestSessionId, - testContext); - - if (instance != null) - { - return instance; - } - - return typedMetadata.InstanceFactory!(context.ResolvedClassGenericArguments, context.ClassArguments); - }; - - Func invokeTest = async (instance, args, testContext, cancellationToken) => - { - await typedMetadata.InvokeTypedTest!((T)instance, args, cancellationToken).ConfigureAwait(false); - }; - - return new ExecutableTest(createInstance, invokeTest) - { - TestId = context.TestId, - Metadata = metadata, - Arguments = context.Arguments, - ClassArguments = context.ClassArguments, - Context = context.Context - }; - }; - + _cachedExecutableTestFactory = CreateTypedExecutableTest; return _cachedExecutableTestFactory; } @@ -122,6 +82,21 @@ public override Func)metadata; + return new ExecutableTest(typedMetadata, context) + { + TestId = context.TestId, + Metadata = metadata, + Arguments = context.Arguments, + ClassArguments = context.ClassArguments, + Context = context.Context + }; + } + /// /// Sets up runtime data combination generation for this test by updating the TestSessionId /// diff --git a/TUnit.Engine/Helpers/ValueTaskBridge.cs b/TUnit.Engine/Helpers/ValueTaskBridge.cs new file mode 100644 index 0000000000..fda2a2353e --- /dev/null +++ b/TUnit.Engine/Helpers/ValueTaskBridge.cs @@ -0,0 +1,45 @@ +using System.Reflection; + +namespace TUnit.Engine.Helpers; + +/// +/// Bridges and into without +/// allocating when the already completed synchronously. Invoked from dynamic +/// test Expression trees built in TestRegistry so the cost of calling +/// unconditionally on every invocation is avoided for the common +/// sync-completion path. +/// +internal static class ValueTaskBridge +{ + public static Task ToTask(ValueTask valueTask) + { + if (valueTask.IsCompletedSuccessfully) + { + return Task.CompletedTask; + } + + return valueTask.AsTask(); + } + + public static Task ToTask(ValueTask valueTask) + { + if (valueTask.IsCompletedSuccessfully) + { + return Task.FromResult(valueTask.Result); + } + + return valueTask.AsTask(); + } + + /// Pre-resolved for the non-generic . + internal static readonly MethodInfo ToTaskNonGenericMethod = + typeof(ValueTaskBridge).GetMethod(nameof(ToTask), [typeof(ValueTask)])!; + + /// + /// Pre-resolved generic method definition for . + /// Callers invoke on this instance per element type. + /// + internal static readonly MethodInfo ToTaskGenericMethodDefinition = + typeof(ValueTaskBridge).GetMethods() + .First(m => m.Name == nameof(ToTask) && m.IsGenericMethodDefinition); +} diff --git a/TUnit.Engine/Services/TestExecution/TestCoordinator.cs b/TUnit.Engine/Services/TestExecution/TestCoordinator.cs index a39f2fc516..5d6bc6b6b4 100644 --- a/TUnit.Engine/Services/TestExecution/TestCoordinator.cs +++ b/TUnit.Engine/Services/TestExecution/TestCoordinator.cs @@ -133,16 +133,21 @@ await RetryHelper.ExecuteWithRetry(test.Context, } finally { - // Flush console interceptors to ensure all buffered output is captured - // This is critical for output from Console.Write() without newline - try - { - await Console.Out.FlushAsync().ConfigureAwait(false); - await Console.Error.FlushAsync().ConfigureAwait(false); - } - catch (Exception flushEx) + // Flush console interceptors to ensure all buffered output is captured. + // This is critical for output from Console.Write() without newline, but Console.Out + // is a SynchronizedTextWriter and FlushAsync takes a lock — skip the flush entirely + // when the test wrote nothing, which is the hot path for passing tests with no output. + if (test.Context.HasCapturedOutput) { - await _logger.LogErrorAsync($"Error flushing console output for {test.TestId}: {flushEx}").ConfigureAwait(false); + try + { + await Console.Out.FlushAsync().ConfigureAwait(false); + await Console.Error.FlushAsync().ConfigureAwait(false); + } + catch (Exception flushEx) + { + await _logger.LogErrorAsync($"Error flushing console output for {test.TestId}: {flushEx}").ConfigureAwait(false); + } } // Stay null on the success path — materializing the list only when something actually fails diff --git a/TUnit.Engine/Services/TestRegistry.cs b/TUnit.Engine/Services/TestRegistry.cs index c5c63206e1..f6e3984684 100644 --- a/TUnit.Engine/Services/TestRegistry.cs +++ b/TUnit.Engine/Services/TestRegistry.cs @@ -165,6 +165,7 @@ public async Task CreateTestVariant( } [RequiresUnreferencedCode("Creating test variants requires reflection which is not supported in native AOT scenarios.")] + [RequiresDynamicCode("Creating test variants builds Expression trees and may instantiate generic helpers at runtime which is not supported in native AOT scenarios.")] private async Task CreateTestVariantInternal<[DynamicallyAccessedMembers( DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors @@ -208,16 +209,18 @@ public async Task CreateTestVariant( } else if (methodInfo.ReturnType == typeof(ValueTask)) { - // ValueTask.AsTask() converts to Task for proper awaiting - var asTaskMethod = typeof(ValueTask).GetMethod(nameof(ValueTask.AsTask))!; - body = Expression.Call(methodCall, asTaskMethod); + // Bridge through ValueTaskBridge so synchronously-completed ValueTasks avoid the + // Task allocation that .AsTask() would force. + body = Expression.Call(ValueTaskBridge.ToTaskNonGenericMethod, methodCall); } else if (methodInfo.ReturnType.IsGenericType && methodInfo.ReturnType.GetGenericTypeDefinition() == typeof(ValueTask<>)) { - // ValueTask.AsTask() returns Task, then convert to Task - var asTaskMethod = methodInfo.ReturnType.GetMethod(nameof(ValueTask.AsTask))!; - body = Expression.Convert(Expression.Call(methodCall, asTaskMethod), typeof(Task)); + // ValueTask → Task via the generic helper. Helper returns Task.FromResult for sync + // completion (runtime caches common results) instead of allocating a new Task. + var toTaskGeneric = ValueTaskBridge.ToTaskGenericMethodDefinition + .MakeGenericMethod(methodInfo.ReturnType.GenericTypeArguments[0]); + body = Expression.Convert(Expression.Call(toTaskGeneric, methodCall), typeof(Task)); } else { From 89955679d8b6a5cfef44d04991f7811435262ddd Mon Sep 17 00:00:00 2001 From: Tom Longhurst <30480171+thomhurst@users.noreply.github.com> Date: Fri, 24 Apr 2026 02:30:08 +0100 Subject: [PATCH 2/4] review: address #5694 feedback - Restore `ExecutableTest` as `public sealed class`; make `ExecutableTest` inherit from `AbstractExecutableTest` directly to preserve public API. - Update Public API snapshots: `PropertyInjectionMetadata` exposes new `GetProperty` init-only delegate (was missing from verified.txt files). - `PropertyInjectionMetadata`: split source-gen-supplied getter from the lazy reflection fallback; make the fallback cache `volatile` + write via `Interlocked.CompareExchange` so parallel readers cannot observe a torn delegate, and the public `GetProperty` contract stays clean (only surfaces what the source generator emitted). - Clarify `ValueTaskBridge` XML doc re: `Task.FromResult` only caching bool/null (earlier wording implied broader caching). - Document `ObjectGraphDiscoverer.TypeHierarchyCache` as returning a shared, read-only-by-convention `HashSet` (cannot use `IReadOnlySet` because netstandard2.0 lacks it and the caller needs the concrete type for `GetAlternateLookup`). --- TUnit.Core/Discovery/ObjectGraphDiscoverer.cs | 7 +++- TUnit.Core/ExecutableTest.cs | 20 +++------- TUnit.Core/ExecutableTest`1.cs | 6 ++- .../PropertyInjectionMetadata.cs | 38 ++++++++++++++----- TUnit.Engine/Helpers/ValueTaskBridge.cs | 13 ++++--- ...Has_No_API_Changes.DotNet10_0.verified.txt | 1 + ..._Has_No_API_Changes.DotNet8_0.verified.txt | 1 + ..._Has_No_API_Changes.DotNet9_0.verified.txt | 1 + ...ary_Has_No_API_Changes.Net4_7.verified.txt | 1 + 9 files changed, 55 insertions(+), 33 deletions(-) diff --git a/TUnit.Core/Discovery/ObjectGraphDiscoverer.cs b/TUnit.Core/Discovery/ObjectGraphDiscoverer.cs index f1ded7c7dd..eb4ae3cca1 100644 --- a/TUnit.Core/Discovery/ObjectGraphDiscoverer.cs +++ b/TUnit.Core/Discovery/ObjectGraphDiscoverer.cs @@ -606,12 +606,17 @@ private static void CollectRootObjects( /// /// Cache of type hierarchy sets keyed by . Per-type hierarchy is invariant, /// and each invocation otherwise allocates a fresh of strings. - /// Populated on first access per type and read-only thereafter. + /// Populated on first access per type and read-only thereafter. The stored + /// instance is shared — callers MUST treat it as read-only. + /// (Not typed as IReadOnlySet{T} because netstandard2.0 lacks the interface and + /// the only consumer, , needs the concrete type for + /// on newer TFMs.) /// private static readonly ConcurrentDictionary> TypeHierarchyCache = new(); /// /// Gets all types in the inheritance hierarchy from the given type up to (but not including) object. + /// The returned is shared across callers and MUST NOT be mutated. /// private static HashSet GetTypeHierarchy(Type type) => TypeHierarchyCache.GetOrAdd(type, static t => diff --git a/TUnit.Core/ExecutableTest.cs b/TUnit.Core/ExecutableTest.cs index b960080fd5..4a3e736743 100644 --- a/TUnit.Core/ExecutableTest.cs +++ b/TUnit.Core/ExecutableTest.cs @@ -5,20 +5,10 @@ namespace TUnit.Core; /// Replaces ExecutableTest and DynamicExecutableTest with a single implementation. /// All mode-specific logic is handled during delegate creation, not execution. /// -public class ExecutableTest : AbstractExecutableTest +public sealed class ExecutableTest : AbstractExecutableTest { - // Null only inside typed subclasses that override CreateInstanceAsync/InvokeTestAsync and - // therefore never invoke the delegates. The parameterless constructor enforces that invariant. - private readonly Func>? _createInstance; - private readonly Func? _invokeTest; - - /// - /// Constructor for subclasses that supply their own invocation logic by overriding - /// and directly. - /// - private protected ExecutableTest() - { - } + private readonly Func> _createInstance; + private readonly Func _invokeTest; /// /// Creates an ExecutableTest where mode-specific behavior is encapsulated in the delegates. @@ -36,11 +26,11 @@ public ExecutableTest( public override async Task CreateInstanceAsync() { - return await _createInstance!(Context); + return await _createInstance(Context); } public override async Task InvokeTestAsync(object instance, CancellationToken cancellationToken) { - await _invokeTest!(instance, Arguments, Context, cancellationToken); + await _invokeTest(instance, Arguments, Context, cancellationToken); } } diff --git a/TUnit.Core/ExecutableTest`1.cs b/TUnit.Core/ExecutableTest`1.cs index d6fc6ad7cf..351e862c2f 100644 --- a/TUnit.Core/ExecutableTest`1.cs +++ b/TUnit.Core/ExecutableTest`1.cs @@ -4,15 +4,17 @@ namespace TUnit.Core; /// -/// Strongly typed that stores the per-test delegates from +/// Strongly typed executable test that stores the per-test delegates from /// as fields instead of capturing them in closures. This avoids the /// two closure allocations (createInstance and invokeTest) that the generic factory /// would otherwise allocate per test invocation — on a 1000-test run that is 2000 delegates saved. +/// Inherits directly from so +/// can remain sealed (public API surface). /// /// The test class type. internal sealed class ExecutableTest< [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.PublicMethods)] - T> : ExecutableTest where T : class + T> : AbstractExecutableTest where T : class { // Fields that the previous closures captured. ClassArguments and Arguments live on the // base AbstractExecutableTest, so only the metadata reference plus the two ExecutableTestCreationContext diff --git a/TUnit.Core/Interfaces/SourceGenerator/PropertyInjectionMetadata.cs b/TUnit.Core/Interfaces/SourceGenerator/PropertyInjectionMetadata.cs index 64b06b0e22..f10b42ed63 100644 --- a/TUnit.Core/Interfaces/SourceGenerator/PropertyInjectionMetadata.cs +++ b/TUnit.Core/Interfaces/SourceGenerator/PropertyInjectionMetadata.cs @@ -8,7 +8,15 @@ namespace TUnit.Core.Interfaces.SourceGenerator; /// public sealed class PropertyInjectionMetadata { - private Func? _getProperty; + // Source-gen-supplied delegate (or null for hand-authored/reflection-only metadata). + // Kept separate from the lazy-init reflection fallback so the public GetProperty + // contract ("what the source generator emitted") is not polluted by internal caching. + private readonly Func? _sourceGenGetter; + + // Lazily populated reflection-based fallback. volatile so a racing reader observes + // the completed delegate write without tearing on weakly-ordered architectures; + // Interlocked.CompareExchange makes the winning writer visible to everyone. + private volatile Func? _cachedGetter; /// /// Gets the name of the property that needs injection. @@ -50,8 +58,8 @@ public sealed class PropertyInjectionMetadata /// public Func? GetProperty { - get => _getProperty; - init => _getProperty = value; + get => _sourceGenGetter; + init => _sourceGenGetter = value; } /// @@ -63,19 +71,29 @@ public sealed class PropertyInjectionMetadata Justification = "ContainingType is annotated to preserve properties; reflection fallback is only used when source-gen did not emit a delegate.")] internal Func GetOrCreateGetter() { - if (_getProperty != null) + // Fast path: source-gen supplied a delegate. + if (_sourceGenGetter != null) { - return _getProperty; + return _sourceGenGetter; } - var property = ContainingType.GetProperty(PropertyName); - if (property is null || !property.CanRead) + // Fast path: reflection fallback already cached (volatile read). + var cached = _cachedGetter; + if (cached != null) { + return cached; + } + + var property = ContainingType.GetProperty(PropertyName); + Func computed = property is null || !property.CanRead // Memoize a stub that mirrors the behavior the previous reflection-based // call sites expected (null when the property can't be read). - return _getProperty = static _ => null; - } + ? static _ => null + : property.GetValue; - return _getProperty = property.GetValue; + // Benign race: both racers compute equivalent delegates; CompareExchange makes the + // winner visible to any subsequent reader without a lock. + Interlocked.CompareExchange(ref _cachedGetter, computed, null); + return _cachedGetter!; } } diff --git a/TUnit.Engine/Helpers/ValueTaskBridge.cs b/TUnit.Engine/Helpers/ValueTaskBridge.cs index fda2a2353e..228931eeac 100644 --- a/TUnit.Engine/Helpers/ValueTaskBridge.cs +++ b/TUnit.Engine/Helpers/ValueTaskBridge.cs @@ -3,11 +3,14 @@ namespace TUnit.Engine.Helpers; /// -/// Bridges and into without -/// allocating when the already completed synchronously. Invoked from dynamic -/// test Expression trees built in TestRegistry so the cost of calling -/// unconditionally on every invocation is avoided for the common -/// sync-completion path. +/// Bridges and into , +/// avoiding the state-machine overhead of when the +/// already completed synchronously. Invoked from dynamic test Expression +/// trees built in TestRegistry so that the common sync-completion path returns +/// (non-generic) or Task.FromResult (generic) directly. +/// Note: only caches bool/null; other types +/// still allocate a fresh , but that cost is smaller than the +/// state-machine path. /// internal static class ValueTaskBridge { 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 e92385daa6..7cf82a3f02 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 @@ -2742,6 +2742,7 @@ namespace . [.(..None | ..PublicProperties | ..NonPublicProperties)] public required ContainingType { get; init; } public required <.IDataSourceAttribute> CreateDataSource { get; init; } + public ? GetProperty { get; init; } public required string PropertyName { get; init; } [.(..None | ..PublicParameterlessConstructor | ..PublicConstructors | ..NonPublicConstructors | ..PublicProperties)] public required PropertyType { get; init; } 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 d51c1804eb..6c1506df32 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 @@ -2742,6 +2742,7 @@ namespace . [.(..None | ..PublicProperties | ..NonPublicProperties)] public required ContainingType { get; init; } public required <.IDataSourceAttribute> CreateDataSource { get; init; } + public ? GetProperty { get; init; } public required string PropertyName { get; init; } [.(..None | ..PublicParameterlessConstructor | ..PublicConstructors | ..NonPublicConstructors | ..PublicProperties)] public required PropertyType { get; init; } 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 ee987aa6d1..0a3813cb57 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 @@ -2742,6 +2742,7 @@ namespace . [.(..None | ..PublicProperties | ..NonPublicProperties)] public required ContainingType { get; init; } public required <.IDataSourceAttribute> CreateDataSource { get; init; } + public ? GetProperty { get; init; } public required string PropertyName { get; init; } [.(..None | ..PublicParameterlessConstructor | ..PublicConstructors | ..NonPublicConstructors | ..PublicProperties)] public required PropertyType { get; init; } 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 5d87472120..68b6a760e0 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 @@ -2665,6 +2665,7 @@ namespace . public PropertyInjectionMetadata() { } public required ContainingType { get; init; } public required <.IDataSourceAttribute> CreateDataSource { get; init; } + public ? GetProperty { get; init; } public required string PropertyName { get; init; } public required PropertyType { get; init; } public required SetProperty { get; init; } From 71015108ff240723b5b7182c775f4d815f03fb4c Mon Sep 17 00:00:00 2001 From: Tom Longhurst <30480171+thomhurst@users.noreply.github.com> Date: Fri, 24 Apr 2026 02:52:31 +0100 Subject: [PATCH 3/4] =?UTF-8?q?review:=20address=20#5694=20round=202=20?= =?UTF-8?q?=E2=80=94=20flush=20guard=20revert,=20null-getter=20semantics?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Revert the `HasCapturedOutput` guard around the Console flush in `TestCoordinator`. The guard was a point-in-time check and could silently drop output from background writes landing after the check; the flush itself is a cheap no-op when nothing is buffered. Also drop the `ConsoleLineBuffer` ref-tracking that was only there to detect captured output for the (now-removed) guard. - Change `PropertyInjectionMetadata.GetOrCreateGetter()` to return `null` when the property is not readable instead of memoizing a `_ => null` stub. Updates `GetPropertyValues` and `TraverseSourceGeneratedProperties` to skip such properties, preserving the pre-PR "non-readable means no yield" enumeration semantic. - Add `Debug.Assert(!string.IsNullOrEmpty(TestSessionId))` in the two primary `TestSessionId` consumer paths (`ExecutableTest.CreateInstanceAsync` and `GenericTestMetadata` runtime-resolution path) so the `string.Empty` default surface misuse in debug builds without adding release-mode cost. --- TUnit.Core/Context.cs | 10 ++------ TUnit.Core/Discovery/ObjectGraphDiscoverer.cs | 6 +++++ TUnit.Core/ExecutableTest`1.cs | 6 +++++ TUnit.Core/GenericTestMetadata.cs | 5 ++++ .../PropertyInjectionMetadata.cs | 20 +++++++++------ .../PropertyInjectionPlanBuilder.cs | 8 +++++- .../Services/TestExecution/TestCoordinator.cs | 25 +++++++++---------- 7 files changed, 50 insertions(+), 30 deletions(-) diff --git a/TUnit.Core/Context.cs b/TUnit.Core/Context.cs index b4ce1c3281..a4d00352ce 100644 --- a/TUnit.Core/Context.cs +++ b/TUnit.Core/Context.cs @@ -112,14 +112,8 @@ public void AddAsyncLocalValues() // Fast path for callers that need to know whether anything was ever captured — // lets the result-building code skip the reader/writer lock acquisition entirely - // for the (very common) case of a passing test with no output. Includes the - // console interceptor line buffers so partial writes (Console.Write without a - // newline) still force a flush at end-of-test. - internal virtual bool HasCapturedOutput => - _outputWriter != null - || _errorOutputWriter != null - || _consoleStdOutLineBuffer != null - || _consoleStdErrLineBuffer != null; + // for the (very common) case of a passing test with no output. + internal virtual bool HasCapturedOutput => _outputWriter != null || _errorOutputWriter != null; public DefaultLogger GetDefaultLogger() { diff --git a/TUnit.Core/Discovery/ObjectGraphDiscoverer.cs b/TUnit.Core/Discovery/ObjectGraphDiscoverer.cs index eb4ae3cca1..129a0679b5 100644 --- a/TUnit.Core/Discovery/ObjectGraphDiscoverer.cs +++ b/TUnit.Core/Discovery/ObjectGraphDiscoverer.cs @@ -343,7 +343,13 @@ private static void TraverseSourceGeneratedProperties( // Use the compile-time-generated getter when the source generator emitted one, // otherwise fall back to a cached reflection-based getter. Eliminates the // per-test Type.GetProperty reflection lookup on the hot path. + // null getter => property is not readable; skip. var getter = metadata.GetOrCreateGetter(); + if (getter is null) + { + continue; + } + var value = getter(obj); if (value != null && tryAdd(value, currentDepth)) { diff --git a/TUnit.Core/ExecutableTest`1.cs b/TUnit.Core/ExecutableTest`1.cs index 351e862c2f..69bf3b1d40 100644 --- a/TUnit.Core/ExecutableTest`1.cs +++ b/TUnit.Core/ExecutableTest`1.cs @@ -1,3 +1,4 @@ +using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using TUnit.Core.Helpers; @@ -40,6 +41,11 @@ public override async Task CreateInstanceAsync() } var attributes = _metadata.GetOrCreateAttributes(); + // TestSessionId defaults to string.Empty for allocation reasons — callers in the + // engine must overwrite it before reaching test-variant generation. Assert here + // rather than guarding every write site. + Debug.Assert(!string.IsNullOrEmpty(_metadata.TestSessionId), + $"TestSessionId must be assigned before creating a test instance for {_metadata.TestName}"); var instance = await ClassConstructorHelper.TryCreateInstanceWithClassConstructor( attributes, _metadata.TestClassType, diff --git a/TUnit.Core/GenericTestMetadata.cs b/TUnit.Core/GenericTestMetadata.cs index 5f7d1ae91e..7856927abb 100644 --- a/TUnit.Core/GenericTestMetadata.cs +++ b/TUnit.Core/GenericTestMetadata.cs @@ -1,3 +1,4 @@ +using System.Diagnostics; using TUnit.Core.Helpers; namespace TUnit.Core; @@ -67,6 +68,10 @@ public override Func public sealed class PropertyInjectionMetadata { + // Sentinel indicating the property is not readable — distinct from "not yet computed" + // (null) so the memoized negative result does not keep re-running reflection. + private static readonly Func s_notReadableSentinel = static _ => null; + // Source-gen-supplied delegate (or null for hand-authored/reflection-only metadata). // Kept separate from the lazy-init reflection fallback so the public GetProperty // contract ("what the source generator emitted") is not polluted by internal caching. @@ -63,13 +67,14 @@ public sealed class PropertyInjectionMetadata } /// - /// Returns a delegate that reads the property value from a given instance. Uses the + /// Returns a delegate that reads the property value from a given instance, or null + /// when the property is not readable (callers should skip such properties). Uses the /// source-generated delegate when available, otherwise compiles /// a reflection-based getter once and caches it on the metadata instance. /// [UnconditionalSuppressMessage("Trimming", "IL2075", Justification = "ContainingType is annotated to preserve properties; reflection fallback is only used when source-gen did not emit a delegate.")] - internal Func GetOrCreateGetter() + internal Func? GetOrCreateGetter() { // Fast path: source-gen supplied a delegate. if (_sourceGenGetter != null) @@ -81,19 +86,18 @@ public sealed class PropertyInjectionMetadata var cached = _cachedGetter; if (cached != null) { - return cached; + return ReferenceEquals(cached, s_notReadableSentinel) ? null : cached; } var property = ContainingType.GetProperty(PropertyName); - Func computed = property is null || !property.CanRead - // Memoize a stub that mirrors the behavior the previous reflection-based - // call sites expected (null when the property can't be read). - ? static _ => null + var computed = property is null || !property.CanRead + ? s_notReadableSentinel : property.GetValue; // Benign race: both racers compute equivalent delegates; CompareExchange makes the // winner visible to any subsequent reader without a lock. Interlocked.CompareExchange(ref _cachedGetter, computed, null); - return _cachedGetter!; + var winner = _cachedGetter!; + return ReferenceEquals(winner, s_notReadableSentinel) ? null : winner; } } diff --git a/TUnit.Core/PropertyInjection/PropertyInjectionPlanBuilder.cs b/TUnit.Core/PropertyInjection/PropertyInjectionPlanBuilder.cs index 0a7b015641..2c7f70a138 100644 --- a/TUnit.Core/PropertyInjection/PropertyInjectionPlanBuilder.cs +++ b/TUnit.Core/PropertyInjection/PropertyInjectionPlanBuilder.cs @@ -234,7 +234,13 @@ public Task ForEachPropertyParallelAsync( { foreach (var metadata in SourceGeneratedProperties) { - yield return metadata.GetOrCreateGetter()(instance); + // Skip non-readable properties so the enumeration count matches the legacy + // reflection behavior (old code did not yield for properties without a getter). + var getter = metadata.GetOrCreateGetter(); + if (getter is not null) + { + yield return getter(instance); + } } } else if (ReflectionProperties.Length > 0) diff --git a/TUnit.Engine/Services/TestExecution/TestCoordinator.cs b/TUnit.Engine/Services/TestExecution/TestCoordinator.cs index 5d6bc6b6b4..8c74bad7a6 100644 --- a/TUnit.Engine/Services/TestExecution/TestCoordinator.cs +++ b/TUnit.Engine/Services/TestExecution/TestCoordinator.cs @@ -134,20 +134,19 @@ await RetryHelper.ExecuteWithRetry(test.Context, finally { // Flush console interceptors to ensure all buffered output is captured. - // This is critical for output from Console.Write() without newline, but Console.Out - // is a SynchronizedTextWriter and FlushAsync takes a lock — skip the flush entirely - // when the test wrote nothing, which is the hot path for passing tests with no output. - if (test.Context.HasCapturedOutput) + // This is critical for output from Console.Write() without newline. The flush + // is unconditional because `HasCapturedOutput` is a point-in-time check: a test + // that fires `Task.Run(() => Console.WriteLine(...))` without awaiting can land + // writes after the check, which would silently lose output. The interceptor's + // own FlushIfNonEmpty path is a cheap no-op when there is nothing buffered. + try { - try - { - await Console.Out.FlushAsync().ConfigureAwait(false); - await Console.Error.FlushAsync().ConfigureAwait(false); - } - catch (Exception flushEx) - { - await _logger.LogErrorAsync($"Error flushing console output for {test.TestId}: {flushEx}").ConfigureAwait(false); - } + await Console.Out.FlushAsync().ConfigureAwait(false); + await Console.Error.FlushAsync().ConfigureAwait(false); + } + catch (Exception flushEx) + { + await _logger.LogErrorAsync($"Error flushing console output for {test.TestId}: {flushEx}").ConfigureAwait(false); } // Stay null on the success path — materializing the list only when something actually fails From 099651ffa558352cc8a252fe2525d07aa95f2e71 Mon Sep 17 00:00:00 2001 From: Tom Longhurst <30480171+thomhurst@users.noreply.github.com> Date: Fri, 24 Apr 2026 03:12:12 +0100 Subject: [PATCH 4/4] =?UTF-8?q?review:=20address=20#5694=20round=203=20?= =?UTF-8?q?=E2=80=94=20thread=20safety,=20snapshots,=20release=20guard?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - TestMetadata`1._cachedExecutableTestFactory now uses Interlocked.CompareExchange for publication, mirroring the TestEntry cached-delegate idiom. - ExecutableTest`1.CreateInstanceAsync upgrades the Debug.Assert for TestSessionId to a release-mode InvalidOperationException so an empty session id cannot silently propagate into data-generation partition keys. - ValueTaskBridge.ToTaskGenericMethodDefinition uses the typed GetMethod overload on net8+ (with a Single() fallback on netstandard2.0) so a future ToTask overload cannot silently match. - PropertyInjectionMetadata.GetOrCreateGetter uses an explicit lambda instead of the PropertyInfo.GetValue method-group for clarity. - Delete orphaned GenericPropertyInjectionTests.*.verified.txt snapshots — only GenericPropertyInjectionRawTests (no Verify) remains. --- ...GeneratesMetadataForAllLevels.verified.txt | 321 ----- ...Diagnostic_ShowGeneratedFiles.verified.txt | 321 ----- ...rceProperty_GeneratesMetadata.verified.txt | 1149 ----------------- ...rProperties_GeneratesMetadata.verified.txt | 321 ----- ...tiations_EachGenerateMetadata.verified.txt | 321 ----- TUnit.Core/ExecutableTest`1.cs | 14 +- .../PropertyInjectionMetadata.cs | 2 +- TUnit.Core/TestMetadata`1.cs | 14 +- TUnit.Engine/Helpers/ValueTaskBridge.cs | 30 +- 9 files changed, 47 insertions(+), 2446 deletions(-) delete mode 100644 TUnit.Core.SourceGenerator.Tests/GenericPropertyInjectionTests.DeepInheritance_GeneratesMetadataForAllLevels.verified.txt delete mode 100644 TUnit.Core.SourceGenerator.Tests/GenericPropertyInjectionTests.Diagnostic_ShowGeneratedFiles.verified.txt delete mode 100644 TUnit.Core.SourceGenerator.Tests/GenericPropertyInjectionTests.GenericBaseClass_WithDataSourceProperty_GeneratesMetadata.verified.txt delete mode 100644 TUnit.Core.SourceGenerator.Tests/GenericPropertyInjectionTests.GenericClassDataSource_WithInitializerProperties_GeneratesMetadata.verified.txt delete mode 100644 TUnit.Core.SourceGenerator.Tests/GenericPropertyInjectionTests.MultipleInstantiations_EachGenerateMetadata.verified.txt diff --git a/TUnit.Core.SourceGenerator.Tests/GenericPropertyInjectionTests.DeepInheritance_GeneratesMetadataForAllLevels.verified.txt b/TUnit.Core.SourceGenerator.Tests/GenericPropertyInjectionTests.DeepInheritance_GeneratesMetadataForAllLevels.verified.txt deleted file mode 100644 index 7b28dd257e..0000000000 --- a/TUnit.Core.SourceGenerator.Tests/GenericPropertyInjectionTests.DeepInheritance_GeneratesMetadataForAllLevels.verified.txt +++ /dev/null @@ -1,321 +0,0 @@ -using System; -using System.Collections.Generic; -using TUnit.Core; -using TUnit.Core.Interfaces.SourceGenerator; -using TUnit.Core.Enums; -using System.Linq; - -namespace TUnit.Core; - -internal static class TUnit_TestProject_GenericInitializerPropertyTests_PropertyInjectionInitializer -{ - [global::System.Runtime.CompilerServices.ModuleInitializer] - public static void Initialize() - { - global::TUnit.Core.PropertySourceRegistry.Register(typeof(global::TUnit.TestProject.GenericInitializerPropertyTests), new PropertyInjectionSource_61ab58e()); - } -} - -internal sealed class PropertyInjectionSource_61ab58e : IPropertySource -{ - public Type Type => typeof(global::TUnit.TestProject.GenericInitializerPropertyTests); - public bool ShouldInitialize => true; - -#if NET8_0_OR_GREATER - [global::System.Runtime.CompilerServices.UnsafeAccessor(global::System.Runtime.CompilerServices.UnsafeAccessorKind.Field, Name = "k__BackingField")] - private static extern ref global::TUnit.TestProject.GenericInitializerFixture GetFixtureBackingField(TUnit.TestProject.GenericInitializerPropertyTests instance); -#endif - - public IEnumerable GetPropertyMetadata() - { - yield return new PropertyInjectionMetadata - { - PropertyName = "Fixture", - PropertyType = typeof(global::TUnit.TestProject.GenericInitializerFixture), - ContainingType = typeof(TUnit.TestProject.GenericInitializerPropertyTests), - CreateDataSource = () => - { - var dataSource = new TUnit.Core.ClassDataSourceAttribute>(); - dataSource.Shared = (TUnit.Core.SharedType)3; - return dataSource; - }, - SetProperty = (instance, value) => - { - var typedInstance = (global::TUnit.TestProject.GenericInitializerPropertyTests)instance; -#if NET8_0_OR_GREATER - GetFixtureBackingField((TUnit.TestProject.GenericInitializerPropertyTests)typedInstance) = (global::TUnit.TestProject.GenericInitializerFixture)value; -#else - var backingField = typeof(TUnit.TestProject.GenericInitializerPropertyTests).GetField("k__BackingField", - global::System.Reflection.BindingFlags.Instance | global::System.Reflection.BindingFlags.NonPublic); - backingField.SetValue(typedInstance, value); -#endif - } - }; - - } -} - - -// ===== FILE SEPARATOR ===== - -using System; -using System.Collections.Generic; -using TUnit.Core; -using TUnit.Core.Interfaces.SourceGenerator; -using TUnit.Core.Enums; -using System.Linq; - -namespace TUnit.Core; - -internal static class TUnit_TestProject_GenericFixtureBase_TUnit_TestProject_GenericPropertyInjectionTests_TestProgram__Generic_PropertyInjectionInitializer -{ - [global::System.Runtime.CompilerServices.ModuleInitializer] - public static void Initialize() - { - global::TUnit.Core.PropertySourceRegistry.Register(typeof(global::TUnit.TestProject.GenericFixtureBase), new PropertyInjectionSource_Generic_7a6c8287()); - } -} - -internal sealed class PropertyInjectionSource_Generic_7a6c8287 : IPropertySource -{ - public Type Type => typeof(global::TUnit.TestProject.GenericFixtureBase); - public bool ShouldInitialize => true; - -#if NET8_0_OR_GREATER - [global::System.Runtime.CompilerServices.UnsafeAccessor(global::System.Runtime.CompilerServices.UnsafeAccessorKind.Field, Name = "k__BackingField")] - private static extern ref global::TUnit.TestProject.InMemoryDatabase GetPostgresBackingField(TUnit.TestProject.GenericFixtureBase instance); -#endif - - public IEnumerable GetPropertyMetadata() - { - yield return new PropertyInjectionMetadata - { - PropertyName = "Postgres", - PropertyType = typeof(global::TUnit.TestProject.InMemoryDatabase), - ContainingType = typeof(TUnit.TestProject.GenericFixtureBase), - CreateDataSource = () => - { - var dataSource = new TUnit.Core.ClassDataSourceAttribute(); - dataSource.Shared = (TUnit.Core.SharedType)3; - return dataSource; - }, - SetProperty = (instance, value) => - { - var typedInstance = (global::TUnit.TestProject.GenericFixtureBase)instance; -#if NET8_0_OR_GREATER - GetPostgresBackingField((TUnit.TestProject.GenericFixtureBase)typedInstance) = (global::TUnit.TestProject.InMemoryDatabase)value; -#else - var backingField = typeof(TUnit.TestProject.GenericFixtureBase).GetField("k__BackingField", - global::System.Reflection.BindingFlags.Instance | global::System.Reflection.BindingFlags.NonPublic); - backingField.SetValue(typedInstance, value); -#endif - } - }; - - } -} - - -// ===== FILE SEPARATOR ===== - -using System; -using System.Collections.Generic; -using TUnit.Core; -using TUnit.Core.Interfaces.SourceGenerator; -using TUnit.Core.Enums; -using System.Linq; - -namespace TUnit.Core; - -internal static class TUnit_TestProject_GenericFixtureBase_TUnit_TestProject_MultipleGenericInstantiationTests_OtherProgram__Generic_PropertyInjectionInitializer -{ - [global::System.Runtime.CompilerServices.ModuleInitializer] - public static void Initialize() - { - global::TUnit.Core.PropertySourceRegistry.Register(typeof(global::TUnit.TestProject.GenericFixtureBase), new PropertyInjectionSource_Generic_64877686()); - } -} - -internal sealed class PropertyInjectionSource_Generic_64877686 : IPropertySource -{ - public Type Type => typeof(global::TUnit.TestProject.GenericFixtureBase); - public bool ShouldInitialize => true; - -#if NET8_0_OR_GREATER - [global::System.Runtime.CompilerServices.UnsafeAccessor(global::System.Runtime.CompilerServices.UnsafeAccessorKind.Field, Name = "k__BackingField")] - private static extern ref global::TUnit.TestProject.InMemoryDatabase GetPostgresBackingField(TUnit.TestProject.GenericFixtureBase instance); -#endif - - public IEnumerable GetPropertyMetadata() - { - yield return new PropertyInjectionMetadata - { - PropertyName = "Postgres", - PropertyType = typeof(global::TUnit.TestProject.InMemoryDatabase), - ContainingType = typeof(TUnit.TestProject.GenericFixtureBase), - CreateDataSource = () => - { - var dataSource = new TUnit.Core.ClassDataSourceAttribute(); - dataSource.Shared = (TUnit.Core.SharedType)3; - return dataSource; - }, - SetProperty = (instance, value) => - { - var typedInstance = (global::TUnit.TestProject.GenericFixtureBase)instance; -#if NET8_0_OR_GREATER - GetPostgresBackingField((TUnit.TestProject.GenericFixtureBase)typedInstance) = (global::TUnit.TestProject.InMemoryDatabase)value; -#else - var backingField = typeof(TUnit.TestProject.GenericFixtureBase).GetField("k__BackingField", - global::System.Reflection.BindingFlags.Instance | global::System.Reflection.BindingFlags.NonPublic); - backingField.SetValue(typedInstance, value); -#endif - } - }; - - } -} - - -// ===== FILE SEPARATOR ===== - -using System; -using System.Collections.Generic; -using TUnit.Core; -using TUnit.Core.Interfaces.SourceGenerator; -using TUnit.Core.Enums; -using System.Linq; - -namespace TUnit.Core; - -internal static class TUnit_TestProject_IntermediateBase_TUnit_TestProject_DeepInheritanceGenericTests_DeepProgram__Generic_PropertyInjectionInitializer -{ - [global::System.Runtime.CompilerServices.ModuleInitializer] - public static void Initialize() - { - global::TUnit.Core.PropertySourceRegistry.Register(typeof(global::TUnit.TestProject.IntermediateBase), new PropertyInjectionSource_Generic_344bd53a()); - } -} - -internal sealed class PropertyInjectionSource_Generic_344bd53a : IPropertySource -{ - public Type Type => typeof(global::TUnit.TestProject.IntermediateBase); - public bool ShouldInitialize => true; - -#if NET8_0_OR_GREATER - [global::System.Runtime.CompilerServices.UnsafeAccessor(global::System.Runtime.CompilerServices.UnsafeAccessorKind.Field, Name = "k__BackingField")] - private static extern ref global::TUnit.TestProject.InMemoryDatabase GetPostgresBackingField(TUnit.TestProject.GenericFixtureBase instance); -#endif - - public IEnumerable GetPropertyMetadata() - { - yield return new PropertyInjectionMetadata - { - PropertyName = "Postgres", - PropertyType = typeof(global::TUnit.TestProject.InMemoryDatabase), - ContainingType = typeof(TUnit.TestProject.GenericFixtureBase), - CreateDataSource = () => - { - var dataSource = new TUnit.Core.ClassDataSourceAttribute(); - dataSource.Shared = (TUnit.Core.SharedType)3; - return dataSource; - }, - SetProperty = (instance, value) => - { - var typedInstance = (global::TUnit.TestProject.IntermediateBase)instance; -#if NET8_0_OR_GREATER - GetPostgresBackingField((TUnit.TestProject.GenericFixtureBase)typedInstance) = (global::TUnit.TestProject.InMemoryDatabase)value; -#else - var backingField = typeof(TUnit.TestProject.GenericFixtureBase).GetField("k__BackingField", - global::System.Reflection.BindingFlags.Instance | global::System.Reflection.BindingFlags.NonPublic); - backingField.SetValue(typedInstance, value); -#endif - } - }; - - } -} - - -// ===== FILE SEPARATOR ===== - -using System; -using System.Collections.Generic; -using TUnit.Core; -using TUnit.Core.Interfaces.SourceGenerator; -using TUnit.Core.Enums; -using System.Linq; - -namespace TUnit.Core; - -internal static class TUnit_TestProject_GenericFixtureBase_TUnit_TestProject_DeepInheritanceGenericTests_DeepProgram__Generic_PropertyInjectionInitializer -{ - [global::System.Runtime.CompilerServices.ModuleInitializer] - public static void Initialize() - { - global::TUnit.Core.PropertySourceRegistry.Register(typeof(global::TUnit.TestProject.GenericFixtureBase), new PropertyInjectionSource_Generic_48a5b53f()); - } -} - -internal sealed class PropertyInjectionSource_Generic_48a5b53f : IPropertySource -{ - public Type Type => typeof(global::TUnit.TestProject.GenericFixtureBase); - public bool ShouldInitialize => true; - -#if NET8_0_OR_GREATER - [global::System.Runtime.CompilerServices.UnsafeAccessor(global::System.Runtime.CompilerServices.UnsafeAccessorKind.Field, Name = "k__BackingField")] - private static extern ref global::TUnit.TestProject.InMemoryDatabase GetPostgresBackingField(TUnit.TestProject.GenericFixtureBase instance); -#endif - - public IEnumerable GetPropertyMetadata() - { - yield return new PropertyInjectionMetadata - { - PropertyName = "Postgres", - PropertyType = typeof(global::TUnit.TestProject.InMemoryDatabase), - ContainingType = typeof(TUnit.TestProject.GenericFixtureBase), - CreateDataSource = () => - { - var dataSource = new TUnit.Core.ClassDataSourceAttribute(); - dataSource.Shared = (TUnit.Core.SharedType)3; - return dataSource; - }, - SetProperty = (instance, value) => - { - var typedInstance = (global::TUnit.TestProject.GenericFixtureBase)instance; -#if NET8_0_OR_GREATER - GetPostgresBackingField((TUnit.TestProject.GenericFixtureBase)typedInstance) = (global::TUnit.TestProject.InMemoryDatabase)value; -#else - var backingField = typeof(TUnit.TestProject.GenericFixtureBase).GetField("k__BackingField", - global::System.Reflection.BindingFlags.Instance | global::System.Reflection.BindingFlags.NonPublic); - backingField.SetValue(typedInstance, value); -#endif - } - }; - - } -} - - -// ===== FILE SEPARATOR ===== - -using System; -using TUnit.Core.Discovery; - -namespace TUnit.Generated; - -internal static class TUnit_TestProject_GenericInitializerFixture_TUnit_TestProject_GenericInitializerPropertyTests__Generic_InitializerPropertiesInitializer -{ - [global::System.Runtime.CompilerServices.ModuleInitializer] - public static void Initialize() - { - InitializerPropertyRegistry.Register(typeof(global::TUnit.TestProject.GenericInitializerFixture), new InitializerPropertyInfo[] - { - new InitializerPropertyInfo - { - PropertyName = "Database", - PropertyType = typeof(global::TUnit.TestProject.InMemoryDatabase), - GetValue = static obj => ((global::TUnit.TestProject.GenericInitializerFixture)obj).Database - }, - }); - } -} diff --git a/TUnit.Core.SourceGenerator.Tests/GenericPropertyInjectionTests.Diagnostic_ShowGeneratedFiles.verified.txt b/TUnit.Core.SourceGenerator.Tests/GenericPropertyInjectionTests.Diagnostic_ShowGeneratedFiles.verified.txt deleted file mode 100644 index dbf061f85e..0000000000 --- a/TUnit.Core.SourceGenerator.Tests/GenericPropertyInjectionTests.Diagnostic_ShowGeneratedFiles.verified.txt +++ /dev/null @@ -1,321 +0,0 @@ -using System; -using System.Collections.Generic; -using TUnit.Core; -using TUnit.Core.Interfaces.SourceGenerator; -using TUnit.Core.Enums; -using System.Linq; - -namespace TUnit.Core; - -internal static class TUnit_TestProject_GenericInitializerPropertyTests_PropertyInjectionInitializer -{ - [global::System.Runtime.CompilerServices.ModuleInitializer] - public static void Initialize() - { - global::TUnit.Core.PropertySourceRegistry.Register(typeof(global::TUnit.TestProject.GenericInitializerPropertyTests), new PropertyInjectionSource_1a6cab1c()); - } -} - -internal sealed class PropertyInjectionSource_1a6cab1c : IPropertySource -{ - public Type Type => typeof(global::TUnit.TestProject.GenericInitializerPropertyTests); - public bool ShouldInitialize => true; - -#if NET8_0_OR_GREATER - [global::System.Runtime.CompilerServices.UnsafeAccessor(global::System.Runtime.CompilerServices.UnsafeAccessorKind.Field, Name = "k__BackingField")] - private static extern ref global::TUnit.TestProject.GenericInitializerFixture GetFixtureBackingField(TUnit.TestProject.GenericInitializerPropertyTests instance); -#endif - - public IEnumerable GetPropertyMetadata() - { - yield return new PropertyInjectionMetadata - { - PropertyName = "Fixture", - PropertyType = typeof(global::TUnit.TestProject.GenericInitializerFixture), - ContainingType = typeof(TUnit.TestProject.GenericInitializerPropertyTests), - CreateDataSource = () => - { - var dataSource = new TUnit.Core.ClassDataSourceAttribute>(); - dataSource.Shared = (TUnit.Core.SharedType)3; - return dataSource; - }, - SetProperty = (instance, value) => - { - var typedInstance = (global::TUnit.TestProject.GenericInitializerPropertyTests)instance; -#if NET8_0_OR_GREATER - GetFixtureBackingField((TUnit.TestProject.GenericInitializerPropertyTests)typedInstance) = (global::TUnit.TestProject.GenericInitializerFixture)value; -#else - var backingField = typeof(TUnit.TestProject.GenericInitializerPropertyTests).GetField("k__BackingField", - global::System.Reflection.BindingFlags.Instance | global::System.Reflection.BindingFlags.NonPublic); - backingField.SetValue(typedInstance, value); -#endif - } - }; - - } -} - - -// ===== FILE SEPARATOR ===== - -using System; -using System.Collections.Generic; -using TUnit.Core; -using TUnit.Core.Interfaces.SourceGenerator; -using TUnit.Core.Enums; -using System.Linq; - -namespace TUnit.Core; - -internal static class TUnit_TestProject_GenericFixtureBase_TUnit_TestProject_GenericPropertyInjectionTests_TestProgram__Generic_PropertyInjectionInitializer -{ - [global::System.Runtime.CompilerServices.ModuleInitializer] - public static void Initialize() - { - global::TUnit.Core.PropertySourceRegistry.Register(typeof(global::TUnit.TestProject.GenericFixtureBase), new PropertyInjectionSource_Generic_1fe2b02e()); - } -} - -internal sealed class PropertyInjectionSource_Generic_1fe2b02e : IPropertySource -{ - public Type Type => typeof(global::TUnit.TestProject.GenericFixtureBase); - public bool ShouldInitialize => true; - -#if NET8_0_OR_GREATER - [global::System.Runtime.CompilerServices.UnsafeAccessor(global::System.Runtime.CompilerServices.UnsafeAccessorKind.Field, Name = "k__BackingField")] - private static extern ref global::TUnit.TestProject.InMemoryDatabase GetPostgresBackingField(TUnit.TestProject.GenericFixtureBase instance); -#endif - - public IEnumerable GetPropertyMetadata() - { - yield return new PropertyInjectionMetadata - { - PropertyName = "Postgres", - PropertyType = typeof(global::TUnit.TestProject.InMemoryDatabase), - ContainingType = typeof(TUnit.TestProject.GenericFixtureBase), - CreateDataSource = () => - { - var dataSource = new TUnit.Core.ClassDataSourceAttribute(); - dataSource.Shared = (TUnit.Core.SharedType)3; - return dataSource; - }, - SetProperty = (instance, value) => - { - var typedInstance = (global::TUnit.TestProject.GenericFixtureBase)instance; -#if NET8_0_OR_GREATER - GetPostgresBackingField((TUnit.TestProject.GenericFixtureBase)typedInstance) = (global::TUnit.TestProject.InMemoryDatabase)value; -#else - var backingField = typeof(TUnit.TestProject.GenericFixtureBase).GetField("k__BackingField", - global::System.Reflection.BindingFlags.Instance | global::System.Reflection.BindingFlags.NonPublic); - backingField.SetValue(typedInstance, value); -#endif - } - }; - - } -} - - -// ===== FILE SEPARATOR ===== - -using System; -using System.Collections.Generic; -using TUnit.Core; -using TUnit.Core.Interfaces.SourceGenerator; -using TUnit.Core.Enums; -using System.Linq; - -namespace TUnit.Core; - -internal static class TUnit_TestProject_GenericFixtureBase_TUnit_TestProject_MultipleGenericInstantiationTests_OtherProgram__Generic_PropertyInjectionInitializer -{ - [global::System.Runtime.CompilerServices.ModuleInitializer] - public static void Initialize() - { - global::TUnit.Core.PropertySourceRegistry.Register(typeof(global::TUnit.TestProject.GenericFixtureBase), new PropertyInjectionSource_Generic_3db19b9d()); - } -} - -internal sealed class PropertyInjectionSource_Generic_3db19b9d : IPropertySource -{ - public Type Type => typeof(global::TUnit.TestProject.GenericFixtureBase); - public bool ShouldInitialize => true; - -#if NET8_0_OR_GREATER - [global::System.Runtime.CompilerServices.UnsafeAccessor(global::System.Runtime.CompilerServices.UnsafeAccessorKind.Field, Name = "k__BackingField")] - private static extern ref global::TUnit.TestProject.InMemoryDatabase GetPostgresBackingField(TUnit.TestProject.GenericFixtureBase instance); -#endif - - public IEnumerable GetPropertyMetadata() - { - yield return new PropertyInjectionMetadata - { - PropertyName = "Postgres", - PropertyType = typeof(global::TUnit.TestProject.InMemoryDatabase), - ContainingType = typeof(TUnit.TestProject.GenericFixtureBase), - CreateDataSource = () => - { - var dataSource = new TUnit.Core.ClassDataSourceAttribute(); - dataSource.Shared = (TUnit.Core.SharedType)3; - return dataSource; - }, - SetProperty = (instance, value) => - { - var typedInstance = (global::TUnit.TestProject.GenericFixtureBase)instance; -#if NET8_0_OR_GREATER - GetPostgresBackingField((TUnit.TestProject.GenericFixtureBase)typedInstance) = (global::TUnit.TestProject.InMemoryDatabase)value; -#else - var backingField = typeof(TUnit.TestProject.GenericFixtureBase).GetField("k__BackingField", - global::System.Reflection.BindingFlags.Instance | global::System.Reflection.BindingFlags.NonPublic); - backingField.SetValue(typedInstance, value); -#endif - } - }; - - } -} - - -// ===== FILE SEPARATOR ===== - -using System; -using System.Collections.Generic; -using TUnit.Core; -using TUnit.Core.Interfaces.SourceGenerator; -using TUnit.Core.Enums; -using System.Linq; - -namespace TUnit.Core; - -internal static class TUnit_TestProject_IntermediateBase_TUnit_TestProject_DeepInheritanceGenericTests_DeepProgram__Generic_PropertyInjectionInitializer -{ - [global::System.Runtime.CompilerServices.ModuleInitializer] - public static void Initialize() - { - global::TUnit.Core.PropertySourceRegistry.Register(typeof(global::TUnit.TestProject.IntermediateBase), new PropertyInjectionSource_Generic_738479fe()); - } -} - -internal sealed class PropertyInjectionSource_Generic_738479fe : IPropertySource -{ - public Type Type => typeof(global::TUnit.TestProject.IntermediateBase); - public bool ShouldInitialize => true; - -#if NET8_0_OR_GREATER - [global::System.Runtime.CompilerServices.UnsafeAccessor(global::System.Runtime.CompilerServices.UnsafeAccessorKind.Field, Name = "k__BackingField")] - private static extern ref global::TUnit.TestProject.InMemoryDatabase GetPostgresBackingField(TUnit.TestProject.GenericFixtureBase instance); -#endif - - public IEnumerable GetPropertyMetadata() - { - yield return new PropertyInjectionMetadata - { - PropertyName = "Postgres", - PropertyType = typeof(global::TUnit.TestProject.InMemoryDatabase), - ContainingType = typeof(TUnit.TestProject.GenericFixtureBase), - CreateDataSource = () => - { - var dataSource = new TUnit.Core.ClassDataSourceAttribute(); - dataSource.Shared = (TUnit.Core.SharedType)3; - return dataSource; - }, - SetProperty = (instance, value) => - { - var typedInstance = (global::TUnit.TestProject.IntermediateBase)instance; -#if NET8_0_OR_GREATER - GetPostgresBackingField((TUnit.TestProject.GenericFixtureBase)typedInstance) = (global::TUnit.TestProject.InMemoryDatabase)value; -#else - var backingField = typeof(TUnit.TestProject.GenericFixtureBase).GetField("k__BackingField", - global::System.Reflection.BindingFlags.Instance | global::System.Reflection.BindingFlags.NonPublic); - backingField.SetValue(typedInstance, value); -#endif - } - }; - - } -} - - -// ===== FILE SEPARATOR ===== - -using System; -using System.Collections.Generic; -using TUnit.Core; -using TUnit.Core.Interfaces.SourceGenerator; -using TUnit.Core.Enums; -using System.Linq; - -namespace TUnit.Core; - -internal static class TUnit_TestProject_GenericFixtureBase_TUnit_TestProject_DeepInheritanceGenericTests_DeepProgram__Generic_PropertyInjectionInitializer -{ - [global::System.Runtime.CompilerServices.ModuleInitializer] - public static void Initialize() - { - global::TUnit.Core.PropertySourceRegistry.Register(typeof(global::TUnit.TestProject.GenericFixtureBase), new PropertyInjectionSource_Generic_112df024()); - } -} - -internal sealed class PropertyInjectionSource_Generic_112df024 : IPropertySource -{ - public Type Type => typeof(global::TUnit.TestProject.GenericFixtureBase); - public bool ShouldInitialize => true; - -#if NET8_0_OR_GREATER - [global::System.Runtime.CompilerServices.UnsafeAccessor(global::System.Runtime.CompilerServices.UnsafeAccessorKind.Field, Name = "k__BackingField")] - private static extern ref global::TUnit.TestProject.InMemoryDatabase GetPostgresBackingField(TUnit.TestProject.GenericFixtureBase instance); -#endif - - public IEnumerable GetPropertyMetadata() - { - yield return new PropertyInjectionMetadata - { - PropertyName = "Postgres", - PropertyType = typeof(global::TUnit.TestProject.InMemoryDatabase), - ContainingType = typeof(TUnit.TestProject.GenericFixtureBase), - CreateDataSource = () => - { - var dataSource = new TUnit.Core.ClassDataSourceAttribute(); - dataSource.Shared = (TUnit.Core.SharedType)3; - return dataSource; - }, - SetProperty = (instance, value) => - { - var typedInstance = (global::TUnit.TestProject.GenericFixtureBase)instance; -#if NET8_0_OR_GREATER - GetPostgresBackingField((TUnit.TestProject.GenericFixtureBase)typedInstance) = (global::TUnit.TestProject.InMemoryDatabase)value; -#else - var backingField = typeof(TUnit.TestProject.GenericFixtureBase).GetField("k__BackingField", - global::System.Reflection.BindingFlags.Instance | global::System.Reflection.BindingFlags.NonPublic); - backingField.SetValue(typedInstance, value); -#endif - } - }; - - } -} - - -// ===== FILE SEPARATOR ===== - -using System; -using TUnit.Core.Discovery; - -namespace TUnit.Generated; - -internal static class TUnit_TestProject_GenericInitializerFixture_TUnit_TestProject_GenericInitializerPropertyTests__Generic_InitializerPropertiesInitializer -{ - [global::System.Runtime.CompilerServices.ModuleInitializer] - public static void Initialize() - { - InitializerPropertyRegistry.Register(typeof(global::TUnit.TestProject.GenericInitializerFixture), new InitializerPropertyInfo[] - { - new InitializerPropertyInfo - { - PropertyName = "Database", - PropertyType = typeof(global::TUnit.TestProject.InMemoryDatabase), - GetValue = static obj => ((global::TUnit.TestProject.GenericInitializerFixture)obj).Database - }, - }); - } -} diff --git a/TUnit.Core.SourceGenerator.Tests/GenericPropertyInjectionTests.GenericBaseClass_WithDataSourceProperty_GeneratesMetadata.verified.txt b/TUnit.Core.SourceGenerator.Tests/GenericPropertyInjectionTests.GenericBaseClass_WithDataSourceProperty_GeneratesMetadata.verified.txt deleted file mode 100644 index 5095c30023..0000000000 --- a/TUnit.Core.SourceGenerator.Tests/GenericPropertyInjectionTests.GenericBaseClass_WithDataSourceProperty_GeneratesMetadata.verified.txt +++ /dev/null @@ -1,1149 +0,0 @@ -using System; -using System.Collections.Generic; -using TUnit.Core; -using TUnit.Core.Interfaces.SourceGenerator; -using TUnit.Core.Enums; -using System.Linq; - -namespace TUnit.Core; - -internal static class TUnit_TestProject_GenericInitializerPropertyTests_PropertyInjectionInitializer -{ - [global::System.Runtime.CompilerServices.ModuleInitializer] - public static void Initialize() - { - global::TUnit.Core.PropertySourceRegistry.Register(typeof(global::TUnit.TestProject.GenericInitializerPropertyTests), new PropertyInjectionSource_3cd38317()); - } -} - -internal sealed class PropertyInjectionSource_3cd38317 : IPropertySource -{ - public Type Type => typeof(global::TUnit.TestProject.GenericInitializerPropertyTests); - public bool ShouldInitialize => true; - -#if NET8_0_OR_GREATER - [global::System.Runtime.CompilerServices.UnsafeAccessor(global::System.Runtime.CompilerServices.UnsafeAccessorKind.Field, Name = "k__BackingField")] - private static extern ref global::TUnit.TestProject.GenericInitializerFixture GetFixtureBackingField(TUnit.TestProject.GenericInitializerPropertyTests instance); -#endif - - public IEnumerable GetPropertyMetadata() - { - yield return new PropertyInjectionMetadata - { - PropertyName = "Fixture", - PropertyType = typeof(global::TUnit.TestProject.GenericInitializerFixture), - ContainingType = typeof(TUnit.TestProject.GenericInitializerPropertyTests), - CreateDataSource = () => - { - var dataSource = new TUnit.Core.ClassDataSourceAttribute>(); - dataSource.Shared = (TUnit.Core.SharedType)3; - return dataSource; - }, - SetProperty = (instance, value) => - { - var typedInstance = (global::TUnit.TestProject.GenericInitializerPropertyTests)instance; -#if NET8_0_OR_GREATER - GetFixtureBackingField((TUnit.TestProject.GenericInitializerPropertyTests)typedInstance) = (global::TUnit.TestProject.GenericInitializerFixture)value; -#else - var backingField = typeof(TUnit.TestProject.GenericInitializerPropertyTests).GetField("k__BackingField", - global::System.Reflection.BindingFlags.Instance | global::System.Reflection.BindingFlags.NonPublic); - backingField.SetValue(typedInstance, value); -#endif - } - }; - - } -} - - -// ===== FILE SEPARATOR ===== - -using System; -using System.Collections.Generic; -using TUnit.Core; -using TUnit.Core.Interfaces.SourceGenerator; -using TUnit.Core.Enums; -using System.Linq; - -namespace TUnit.Core; - -internal static class TUnit_TestProject_MixedGenericAndDerivedPropertiesTests_PropertyInjectionInitializer -{ - [global::System.Runtime.CompilerServices.ModuleInitializer] - public static void Initialize() - { - global::TUnit.Core.PropertySourceRegistry.Register(typeof(global::TUnit.TestProject.MixedGenericAndDerivedPropertiesTests), new PropertyInjectionSource_4017f480()); - } -} - -internal sealed class PropertyInjectionSource_4017f480 : IPropertySource -{ - public Type Type => typeof(global::TUnit.TestProject.MixedGenericAndDerivedPropertiesTests); - public bool ShouldInitialize => true; - -#if NET8_0_OR_GREATER - [global::System.Runtime.CompilerServices.UnsafeAccessor(global::System.Runtime.CompilerServices.UnsafeAccessorKind.Field, Name = "k__BackingField")] - private static extern ref global::TUnit.TestProject.SecondaryDatabase GetDerivedDatabaseBackingField(TUnit.TestProject.MixedGenericAndDerivedPropertiesTests instance); -#endif - - public IEnumerable GetPropertyMetadata() - { - yield return new PropertyInjectionMetadata - { - PropertyName = "DerivedDatabase", - PropertyType = typeof(global::TUnit.TestProject.SecondaryDatabase), - ContainingType = typeof(TUnit.TestProject.MixedGenericAndDerivedPropertiesTests), - CreateDataSource = () => - { - var dataSource = new TUnit.Core.ClassDataSourceAttribute(); - dataSource.Shared = (TUnit.Core.SharedType)3; - return dataSource; - }, - SetProperty = (instance, value) => - { - var typedInstance = (global::TUnit.TestProject.MixedGenericAndDerivedPropertiesTests)instance; -#if NET8_0_OR_GREATER - GetDerivedDatabaseBackingField((TUnit.TestProject.MixedGenericAndDerivedPropertiesTests)typedInstance) = (global::TUnit.TestProject.SecondaryDatabase)value; -#else - var backingField = typeof(TUnit.TestProject.MixedGenericAndDerivedPropertiesTests).GetField("k__BackingField", - global::System.Reflection.BindingFlags.Instance | global::System.Reflection.BindingFlags.NonPublic); - backingField.SetValue(typedInstance, value); -#endif - } - }; - - } -} - - -// ===== FILE SEPARATOR ===== - -using System; -using System.Collections.Generic; -using TUnit.Core; -using TUnit.Core.Interfaces.SourceGenerator; -using TUnit.Core.Enums; -using System.Linq; - -namespace TUnit.Core; - -internal static class TUnit_TestProject_GenericInitializerWithNestedPropertyTests_PropertyInjectionInitializer -{ - [global::System.Runtime.CompilerServices.ModuleInitializer] - public static void Initialize() - { - global::TUnit.Core.PropertySourceRegistry.Register(typeof(global::TUnit.TestProject.GenericInitializerWithNestedPropertyTests), new PropertyInjectionSource_e5cd3ee()); - } -} - -internal sealed class PropertyInjectionSource_e5cd3ee : IPropertySource -{ - public Type Type => typeof(global::TUnit.TestProject.GenericInitializerWithNestedPropertyTests); - public bool ShouldInitialize => true; - -#if NET8_0_OR_GREATER - [global::System.Runtime.CompilerServices.UnsafeAccessor(global::System.Runtime.CompilerServices.UnsafeAccessorKind.Field, Name = "k__BackingField")] - private static extern ref global::TUnit.TestProject.GenericInitializerFixture GetFixtureBackingField(TUnit.TestProject.GenericInitializerWithNestedPropertyTests instance); -#endif - - public IEnumerable GetPropertyMetadata() - { - yield return new PropertyInjectionMetadata - { - PropertyName = "Fixture", - PropertyType = typeof(global::TUnit.TestProject.GenericInitializerFixture), - ContainingType = typeof(TUnit.TestProject.GenericInitializerWithNestedPropertyTests), - CreateDataSource = () => - { - var dataSource = new TUnit.Core.ClassDataSourceAttribute>(); - dataSource.Shared = (TUnit.Core.SharedType)3; - return dataSource; - }, - SetProperty = (instance, value) => - { - var typedInstance = (global::TUnit.TestProject.GenericInitializerWithNestedPropertyTests)instance; -#if NET8_0_OR_GREATER - GetFixtureBackingField((TUnit.TestProject.GenericInitializerWithNestedPropertyTests)typedInstance) = (global::TUnit.TestProject.GenericInitializerFixture)value; -#else - var backingField = typeof(TUnit.TestProject.GenericInitializerWithNestedPropertyTests).GetField("k__BackingField", - global::System.Reflection.BindingFlags.Instance | global::System.Reflection.BindingFlags.NonPublic); - backingField.SetValue(typedInstance, value); -#endif - } - }; - - } -} - - -// ===== FILE SEPARATOR ===== - -using System; -using System.Collections.Generic; -using TUnit.Core; -using TUnit.Core.Interfaces.SourceGenerator; -using TUnit.Core.Enums; -using System.Linq; - -namespace TUnit.Core; - -internal static class TUnit_TestProject_Issue4431_WebApplicationFactoryScenarioTests_PropertyInjectionInitializer -{ - [global::System.Runtime.CompilerServices.ModuleInitializer] - public static void Initialize() - { - global::TUnit.Core.PropertySourceRegistry.Register(typeof(global::TUnit.TestProject.Issue4431_WebApplicationFactoryScenarioTests), new PropertyInjectionSource_686a4b57()); - } -} - -internal sealed class PropertyInjectionSource_686a4b57 : IPropertySource -{ - public Type Type => typeof(global::TUnit.TestProject.Issue4431_WebApplicationFactoryScenarioTests); - public bool ShouldInitialize => true; - -#if NET8_0_OR_GREATER - [global::System.Runtime.CompilerServices.UnsafeAccessor(global::System.Runtime.CompilerServices.UnsafeAccessorKind.Field, Name = "k__BackingField")] - private static extern ref global::TUnit.TestProject.CustomWebApplicationFactory GetFactoryBackingField(TUnit.TestProject.Issue4431_WebApplicationFactoryScenarioTests instance); -#endif - - public IEnumerable GetPropertyMetadata() - { - yield return new PropertyInjectionMetadata - { - PropertyName = "Factory", - PropertyType = typeof(global::TUnit.TestProject.CustomWebApplicationFactory), - ContainingType = typeof(TUnit.TestProject.Issue4431_WebApplicationFactoryScenarioTests), - CreateDataSource = () => - { - var dataSource = new TUnit.Core.ClassDataSourceAttribute>(); - dataSource.Shared = (TUnit.Core.SharedType)3; - return dataSource; - }, - SetProperty = (instance, value) => - { - var typedInstance = (global::TUnit.TestProject.Issue4431_WebApplicationFactoryScenarioTests)instance; -#if NET8_0_OR_GREATER - GetFactoryBackingField((TUnit.TestProject.Issue4431_WebApplicationFactoryScenarioTests)typedInstance) = (global::TUnit.TestProject.CustomWebApplicationFactory)value; -#else - var backingField = typeof(TUnit.TestProject.Issue4431_WebApplicationFactoryScenarioTests).GetField("k__BackingField", - global::System.Reflection.BindingFlags.Instance | global::System.Reflection.BindingFlags.NonPublic); - backingField.SetValue(typedInstance, value); -#endif - } - }; - - } -} - - -// ===== FILE SEPARATOR ===== - -using System; -using System.Collections.Generic; -using TUnit.Core; -using TUnit.Core.Interfaces.SourceGenerator; -using TUnit.Core.Enums; -using System.Linq; - -namespace TUnit.Core; - -internal static class TUnit_TestProject_Issue4431_ParentTestScenario_PropertyInjectionInitializer -{ - [global::System.Runtime.CompilerServices.ModuleInitializer] - public static void Initialize() - { - global::TUnit.Core.PropertySourceRegistry.Register(typeof(global::TUnit.TestProject.Issue4431_ParentTestScenario), new PropertyInjectionSource_2e994dce()); - } -} - -internal sealed class PropertyInjectionSource_2e994dce : IPropertySource -{ - public Type Type => typeof(global::TUnit.TestProject.Issue4431_ParentTestScenario); - public bool ShouldInitialize => true; - -#if NET8_0_OR_GREATER - [global::System.Runtime.CompilerServices.UnsafeAccessor(global::System.Runtime.CompilerServices.UnsafeAccessorKind.Field, Name = "k__BackingField")] - private static extern ref global::TUnit.TestProject.InMemoryDatabase GetPostgresBackingField(TUnit.TestProject.Issue4431_ParentTestScenario instance); -#endif - - public IEnumerable GetPropertyMetadata() - { - yield return new PropertyInjectionMetadata - { - PropertyName = "Postgres", - PropertyType = typeof(global::TUnit.TestProject.InMemoryDatabase), - ContainingType = typeof(TUnit.TestProject.Issue4431_ParentTestScenario), - CreateDataSource = () => - { - var dataSource = new TUnit.Core.ClassDataSourceAttribute(); - dataSource.Shared = (TUnit.Core.SharedType)3; - return dataSource; - }, - SetProperty = (instance, value) => - { - var typedInstance = (global::TUnit.TestProject.Issue4431_ParentTestScenario)instance; -#if NET8_0_OR_GREATER - GetPostgresBackingField((TUnit.TestProject.Issue4431_ParentTestScenario)typedInstance) = (global::TUnit.TestProject.InMemoryDatabase)value; -#else - var backingField = typeof(TUnit.TestProject.Issue4431_ParentTestScenario).GetField("k__BackingField", - global::System.Reflection.BindingFlags.Instance | global::System.Reflection.BindingFlags.NonPublic); - backingField.SetValue(typedInstance, value); -#endif - } - }; - - } -} - - -// ===== FILE SEPARATOR ===== - -using System; -using System.Collections.Generic; -using TUnit.Core; -using TUnit.Core.Interfaces.SourceGenerator; -using TUnit.Core.Enums; -using System.Linq; - -namespace TUnit.Core; - -internal static class TUnit_TestProject_GenericFixtureBase_TUnit_TestProject_GenericPropertyInjectionTests_TestProgram__Generic_PropertyInjectionInitializer -{ - [global::System.Runtime.CompilerServices.ModuleInitializer] - public static void Initialize() - { - global::TUnit.Core.PropertySourceRegistry.Register(typeof(global::TUnit.TestProject.GenericFixtureBase), new PropertyInjectionSource_Generic_326cb647()); - } -} - -internal sealed class PropertyInjectionSource_Generic_326cb647 : IPropertySource -{ - public Type Type => typeof(global::TUnit.TestProject.GenericFixtureBase); - public bool ShouldInitialize => true; - -#if NET8_0_OR_GREATER - [global::System.Runtime.CompilerServices.UnsafeAccessor(global::System.Runtime.CompilerServices.UnsafeAccessorKind.Field, Name = "k__BackingField")] - private static extern ref global::TUnit.TestProject.InMemoryDatabase GetPostgresBackingField(TUnit.TestProject.GenericFixtureBase instance); -#endif - - public IEnumerable GetPropertyMetadata() - { - yield return new PropertyInjectionMetadata - { - PropertyName = "Postgres", - PropertyType = typeof(global::TUnit.TestProject.InMemoryDatabase), - ContainingType = typeof(TUnit.TestProject.GenericFixtureBase), - CreateDataSource = () => - { - var dataSource = new TUnit.Core.ClassDataSourceAttribute(); - dataSource.Shared = (TUnit.Core.SharedType)3; - return dataSource; - }, - SetProperty = (instance, value) => - { - var typedInstance = (global::TUnit.TestProject.GenericFixtureBase)instance; -#if NET8_0_OR_GREATER - GetPostgresBackingField((TUnit.TestProject.GenericFixtureBase)typedInstance) = (global::TUnit.TestProject.InMemoryDatabase)value; -#else - var backingField = typeof(TUnit.TestProject.GenericFixtureBase).GetField("k__BackingField", - global::System.Reflection.BindingFlags.Instance | global::System.Reflection.BindingFlags.NonPublic); - backingField.SetValue(typedInstance, value); -#endif - } - }; - - } -} - - -// ===== FILE SEPARATOR ===== - -using System; -using System.Collections.Generic; -using TUnit.Core; -using TUnit.Core.Interfaces.SourceGenerator; -using TUnit.Core.Enums; -using System.Linq; - -namespace TUnit.Core; - -internal static class TUnit_TestProject_GenericFixtureBase_TUnit_TestProject_MultipleGenericInstantiationTests_OtherProgram__Generic_PropertyInjectionInitializer -{ - [global::System.Runtime.CompilerServices.ModuleInitializer] - public static void Initialize() - { - global::TUnit.Core.PropertySourceRegistry.Register(typeof(global::TUnit.TestProject.GenericFixtureBase), new PropertyInjectionSource_Generic_548e1200()); - } -} - -internal sealed class PropertyInjectionSource_Generic_548e1200 : IPropertySource -{ - public Type Type => typeof(global::TUnit.TestProject.GenericFixtureBase); - public bool ShouldInitialize => true; - -#if NET8_0_OR_GREATER - [global::System.Runtime.CompilerServices.UnsafeAccessor(global::System.Runtime.CompilerServices.UnsafeAccessorKind.Field, Name = "k__BackingField")] - private static extern ref global::TUnit.TestProject.InMemoryDatabase GetPostgresBackingField(TUnit.TestProject.GenericFixtureBase instance); -#endif - - public IEnumerable GetPropertyMetadata() - { - yield return new PropertyInjectionMetadata - { - PropertyName = "Postgres", - PropertyType = typeof(global::TUnit.TestProject.InMemoryDatabase), - ContainingType = typeof(TUnit.TestProject.GenericFixtureBase), - CreateDataSource = () => - { - var dataSource = new TUnit.Core.ClassDataSourceAttribute(); - dataSource.Shared = (TUnit.Core.SharedType)3; - return dataSource; - }, - SetProperty = (instance, value) => - { - var typedInstance = (global::TUnit.TestProject.GenericFixtureBase)instance; -#if NET8_0_OR_GREATER - GetPostgresBackingField((TUnit.TestProject.GenericFixtureBase)typedInstance) = (global::TUnit.TestProject.InMemoryDatabase)value; -#else - var backingField = typeof(TUnit.TestProject.GenericFixtureBase).GetField("k__BackingField", - global::System.Reflection.BindingFlags.Instance | global::System.Reflection.BindingFlags.NonPublic); - backingField.SetValue(typedInstance, value); -#endif - } - }; - - } -} - - -// ===== FILE SEPARATOR ===== - -using System; -using System.Collections.Generic; -using TUnit.Core; -using TUnit.Core.Interfaces.SourceGenerator; -using TUnit.Core.Enums; -using System.Linq; - -namespace TUnit.Core; - -internal static class TUnit_TestProject_IntermediateBase_TUnit_TestProject_DeepInheritanceGenericTests_DeepProgram__Generic_PropertyInjectionInitializer -{ - [global::System.Runtime.CompilerServices.ModuleInitializer] - public static void Initialize() - { - global::TUnit.Core.PropertySourceRegistry.Register(typeof(global::TUnit.TestProject.IntermediateBase), new PropertyInjectionSource_Generic_55f0de4()); - } -} - -internal sealed class PropertyInjectionSource_Generic_55f0de4 : IPropertySource -{ - public Type Type => typeof(global::TUnit.TestProject.IntermediateBase); - public bool ShouldInitialize => true; - -#if NET8_0_OR_GREATER - [global::System.Runtime.CompilerServices.UnsafeAccessor(global::System.Runtime.CompilerServices.UnsafeAccessorKind.Field, Name = "k__BackingField")] - private static extern ref global::TUnit.TestProject.InMemoryDatabase GetPostgresBackingField(TUnit.TestProject.GenericFixtureBase instance); -#endif - - public IEnumerable GetPropertyMetadata() - { - yield return new PropertyInjectionMetadata - { - PropertyName = "Postgres", - PropertyType = typeof(global::TUnit.TestProject.InMemoryDatabase), - ContainingType = typeof(TUnit.TestProject.GenericFixtureBase), - CreateDataSource = () => - { - var dataSource = new TUnit.Core.ClassDataSourceAttribute(); - dataSource.Shared = (TUnit.Core.SharedType)3; - return dataSource; - }, - SetProperty = (instance, value) => - { - var typedInstance = (global::TUnit.TestProject.IntermediateBase)instance; -#if NET8_0_OR_GREATER - GetPostgresBackingField((TUnit.TestProject.GenericFixtureBase)typedInstance) = (global::TUnit.TestProject.InMemoryDatabase)value; -#else - var backingField = typeof(TUnit.TestProject.GenericFixtureBase).GetField("k__BackingField", - global::System.Reflection.BindingFlags.Instance | global::System.Reflection.BindingFlags.NonPublic); - backingField.SetValue(typedInstance, value); -#endif - } - }; - - } -} - - -// ===== FILE SEPARATOR ===== - -using System; -using System.Collections.Generic; -using TUnit.Core; -using TUnit.Core.Interfaces.SourceGenerator; -using TUnit.Core.Enums; -using System.Linq; - -namespace TUnit.Core; - -internal static class TUnit_TestProject_GenericFixtureBase_TUnit_TestProject_DeepInheritanceGenericTests_DeepProgram__Generic_PropertyInjectionInitializer -{ - [global::System.Runtime.CompilerServices.ModuleInitializer] - public static void Initialize() - { - global::TUnit.Core.PropertySourceRegistry.Register(typeof(global::TUnit.TestProject.GenericFixtureBase), new PropertyInjectionSource_Generic_551b4117()); - } -} - -internal sealed class PropertyInjectionSource_Generic_551b4117 : IPropertySource -{ - public Type Type => typeof(global::TUnit.TestProject.GenericFixtureBase); - public bool ShouldInitialize => true; - -#if NET8_0_OR_GREATER - [global::System.Runtime.CompilerServices.UnsafeAccessor(global::System.Runtime.CompilerServices.UnsafeAccessorKind.Field, Name = "k__BackingField")] - private static extern ref global::TUnit.TestProject.InMemoryDatabase GetPostgresBackingField(TUnit.TestProject.GenericFixtureBase instance); -#endif - - public IEnumerable GetPropertyMetadata() - { - yield return new PropertyInjectionMetadata - { - PropertyName = "Postgres", - PropertyType = typeof(global::TUnit.TestProject.InMemoryDatabase), - ContainingType = typeof(TUnit.TestProject.GenericFixtureBase), - CreateDataSource = () => - { - var dataSource = new TUnit.Core.ClassDataSourceAttribute(); - dataSource.Shared = (TUnit.Core.SharedType)3; - return dataSource; - }, - SetProperty = (instance, value) => - { - var typedInstance = (global::TUnit.TestProject.GenericFixtureBase)instance; -#if NET8_0_OR_GREATER - GetPostgresBackingField((TUnit.TestProject.GenericFixtureBase)typedInstance) = (global::TUnit.TestProject.InMemoryDatabase)value; -#else - var backingField = typeof(TUnit.TestProject.GenericFixtureBase).GetField("k__BackingField", - global::System.Reflection.BindingFlags.Instance | global::System.Reflection.BindingFlags.NonPublic); - backingField.SetValue(typedInstance, value); -#endif - } - }; - - } -} - - -// ===== FILE SEPARATOR ===== - -using System; -using TUnit.Core.Discovery; - -namespace TUnit.Generated; - -internal static class TUnit_TestProject_GenericInitializerFixture_TUnit_TestProject_GenericInitializerPropertyTests__Generic_InitializerPropertiesInitializer -{ - [global::System.Runtime.CompilerServices.ModuleInitializer] - public static void Initialize() - { - InitializerPropertyRegistry.Register(typeof(global::TUnit.TestProject.GenericInitializerFixture), new InitializerPropertyInfo[] - { - new InitializerPropertyInfo - { - PropertyName = "Database", - PropertyType = typeof(global::TUnit.TestProject.InMemoryDatabase), - GetValue = static obj => ((global::TUnit.TestProject.GenericInitializerFixture)obj).Database - }, - }); - } -} - - -// ===== FILE SEPARATOR ===== - -using System; -using System.Collections.Generic; -using TUnit.Core; -using TUnit.Core.Interfaces.SourceGenerator; -using TUnit.Core.Enums; -using System.Linq; - -namespace TUnit.Core; - -internal static class TUnit_TestProject_MultiPropertyGenericBase_TUnit_TestProject_MultiplePropertiesGenericTests_TestProgram__Generic_PropertyInjectionInitializer -{ - [global::System.Runtime.CompilerServices.ModuleInitializer] - public static void Initialize() - { - global::TUnit.Core.PropertySourceRegistry.Register(typeof(global::TUnit.TestProject.MultiPropertyGenericBase), new PropertyInjectionSource_Generic_467f7427()); - } -} - -internal sealed class PropertyInjectionSource_Generic_467f7427 : IPropertySource -{ - public Type Type => typeof(global::TUnit.TestProject.MultiPropertyGenericBase); - public bool ShouldInitialize => true; - -#if NET8_0_OR_GREATER - [global::System.Runtime.CompilerServices.UnsafeAccessor(global::System.Runtime.CompilerServices.UnsafeAccessorKind.Field, Name = "k__BackingField")] - private static extern ref global::TUnit.TestProject.InMemoryDatabase GetFirstDbBackingField(TUnit.TestProject.MultiPropertyGenericBase instance); -#endif - -#if NET8_0_OR_GREATER - [global::System.Runtime.CompilerServices.UnsafeAccessor(global::System.Runtime.CompilerServices.UnsafeAccessorKind.Field, Name = "k__BackingField")] - private static extern ref global::TUnit.TestProject.SecondaryDatabase GetSecondDbBackingField(TUnit.TestProject.MultiPropertyGenericBase instance); -#endif - - public IEnumerable GetPropertyMetadata() - { - yield return new PropertyInjectionMetadata - { - PropertyName = "FirstDb", - PropertyType = typeof(global::TUnit.TestProject.InMemoryDatabase), - ContainingType = typeof(TUnit.TestProject.MultiPropertyGenericBase), - CreateDataSource = () => - { - var dataSource = new TUnit.Core.ClassDataSourceAttribute(); - dataSource.Shared = (TUnit.Core.SharedType)3; - return dataSource; - }, - SetProperty = (instance, value) => - { - var typedInstance = (global::TUnit.TestProject.MultiPropertyGenericBase)instance; -#if NET8_0_OR_GREATER - GetFirstDbBackingField((TUnit.TestProject.MultiPropertyGenericBase)typedInstance) = (global::TUnit.TestProject.InMemoryDatabase)value; -#else - var backingField = typeof(TUnit.TestProject.MultiPropertyGenericBase).GetField("k__BackingField", - global::System.Reflection.BindingFlags.Instance | global::System.Reflection.BindingFlags.NonPublic); - backingField.SetValue(typedInstance, value); -#endif - } - }; - - yield return new PropertyInjectionMetadata - { - PropertyName = "SecondDb", - PropertyType = typeof(global::TUnit.TestProject.SecondaryDatabase), - ContainingType = typeof(TUnit.TestProject.MultiPropertyGenericBase), - CreateDataSource = () => - { - var dataSource = new TUnit.Core.ClassDataSourceAttribute(); - dataSource.Shared = (TUnit.Core.SharedType)3; - return dataSource; - }, - SetProperty = (instance, value) => - { - var typedInstance = (global::TUnit.TestProject.MultiPropertyGenericBase)instance; -#if NET8_0_OR_GREATER - GetSecondDbBackingField((TUnit.TestProject.MultiPropertyGenericBase)typedInstance) = (global::TUnit.TestProject.SecondaryDatabase)value; -#else - var backingField = typeof(TUnit.TestProject.MultiPropertyGenericBase).GetField("k__BackingField", - global::System.Reflection.BindingFlags.Instance | global::System.Reflection.BindingFlags.NonPublic); - backingField.SetValue(typedInstance, value); -#endif - } - }; - - } -} - - -// ===== FILE SEPARATOR ===== - -using System; -using System.Collections.Generic; -using TUnit.Core; -using TUnit.Core.Interfaces.SourceGenerator; -using TUnit.Core.Enums; -using System.Linq; - -namespace TUnit.Core; - -internal static class TUnit_TestProject_MultiTypeParamBase_TUnit_TestProject_MultiTypeParameterTests_Program1_TUnit_TestProject_MultiTypeParameterTests_Program2__Generic_PropertyInjectionInitializer -{ - [global::System.Runtime.CompilerServices.ModuleInitializer] - public static void Initialize() - { - global::TUnit.Core.PropertySourceRegistry.Register(typeof(global::TUnit.TestProject.MultiTypeParamBase), new PropertyInjectionSource_Generic_2513d22()); - } -} - -internal sealed class PropertyInjectionSource_Generic_2513d22 : IPropertySource -{ - public Type Type => typeof(global::TUnit.TestProject.MultiTypeParamBase); - public bool ShouldInitialize => true; - -#if NET8_0_OR_GREATER - [global::System.Runtime.CompilerServices.UnsafeAccessor(global::System.Runtime.CompilerServices.UnsafeAccessorKind.Field, Name = "k__BackingField")] - private static extern ref global::TUnit.TestProject.InMemoryDatabase GetDatabaseBackingField(TUnit.TestProject.MultiTypeParamBase instance); -#endif - - public IEnumerable GetPropertyMetadata() - { - yield return new PropertyInjectionMetadata - { - PropertyName = "Database", - PropertyType = typeof(global::TUnit.TestProject.InMemoryDatabase), - ContainingType = typeof(TUnit.TestProject.MultiTypeParamBase), - CreateDataSource = () => - { - var dataSource = new TUnit.Core.ClassDataSourceAttribute(); - dataSource.Shared = (TUnit.Core.SharedType)3; - return dataSource; - }, - SetProperty = (instance, value) => - { - var typedInstance = (global::TUnit.TestProject.MultiTypeParamBase)instance; -#if NET8_0_OR_GREATER - GetDatabaseBackingField((TUnit.TestProject.MultiTypeParamBase)typedInstance) = (global::TUnit.TestProject.InMemoryDatabase)value; -#else - var backingField = typeof(TUnit.TestProject.MultiTypeParamBase).GetField("k__BackingField", - global::System.Reflection.BindingFlags.Instance | global::System.Reflection.BindingFlags.NonPublic); - backingField.SetValue(typedInstance, value); -#endif - } - }; - - } -} - - -// ===== FILE SEPARATOR ===== - -using System; -using System.Collections.Generic; -using TUnit.Core; -using TUnit.Core.Interfaces.SourceGenerator; -using TUnit.Core.Enums; -using System.Linq; - -namespace TUnit.Core; - -internal static class TUnit_TestProject_ParentBase_TUnit_TestProject_DeepInheritanceMultiLevelPropertyTests_TestProgram__Generic_PropertyInjectionInitializer -{ - [global::System.Runtime.CompilerServices.ModuleInitializer] - public static void Initialize() - { - global::TUnit.Core.PropertySourceRegistry.Register(typeof(global::TUnit.TestProject.ParentBase), new PropertyInjectionSource_Generic_2bdc3e0a()); - } -} - -internal sealed class PropertyInjectionSource_Generic_2bdc3e0a : IPropertySource -{ - public Type Type => typeof(global::TUnit.TestProject.ParentBase); - public bool ShouldInitialize => true; - -#if NET8_0_OR_GREATER - [global::System.Runtime.CompilerServices.UnsafeAccessor(global::System.Runtime.CompilerServices.UnsafeAccessorKind.Field, Name = "k__BackingField")] - private static extern ref global::TUnit.TestProject.SecondaryDatabase GetParentDbBackingField(TUnit.TestProject.ParentBase instance); -#endif - -#if NET8_0_OR_GREATER - [global::System.Runtime.CompilerServices.UnsafeAccessor(global::System.Runtime.CompilerServices.UnsafeAccessorKind.Field, Name = "k__BackingField")] - private static extern ref global::TUnit.TestProject.InMemoryDatabase GetGrandparentDbBackingField(TUnit.TestProject.GrandparentBase instance); -#endif - - public IEnumerable GetPropertyMetadata() - { - yield return new PropertyInjectionMetadata - { - PropertyName = "ParentDb", - PropertyType = typeof(global::TUnit.TestProject.SecondaryDatabase), - ContainingType = typeof(TUnit.TestProject.ParentBase), - CreateDataSource = () => - { - var dataSource = new TUnit.Core.ClassDataSourceAttribute(); - dataSource.Shared = (TUnit.Core.SharedType)3; - return dataSource; - }, - SetProperty = (instance, value) => - { - var typedInstance = (global::TUnit.TestProject.ParentBase)instance; -#if NET8_0_OR_GREATER - GetParentDbBackingField((TUnit.TestProject.ParentBase)typedInstance) = (global::TUnit.TestProject.SecondaryDatabase)value; -#else - var backingField = typeof(TUnit.TestProject.ParentBase).GetField("k__BackingField", - global::System.Reflection.BindingFlags.Instance | global::System.Reflection.BindingFlags.NonPublic); - backingField.SetValue(typedInstance, value); -#endif - } - }; - - yield return new PropertyInjectionMetadata - { - PropertyName = "GrandparentDb", - PropertyType = typeof(global::TUnit.TestProject.InMemoryDatabase), - ContainingType = typeof(TUnit.TestProject.GrandparentBase), - CreateDataSource = () => - { - var dataSource = new TUnit.Core.ClassDataSourceAttribute(); - dataSource.Shared = (TUnit.Core.SharedType)3; - return dataSource; - }, - SetProperty = (instance, value) => - { - var typedInstance = (global::TUnit.TestProject.ParentBase)instance; -#if NET8_0_OR_GREATER - GetGrandparentDbBackingField((TUnit.TestProject.GrandparentBase)typedInstance) = (global::TUnit.TestProject.InMemoryDatabase)value; -#else - var backingField = typeof(TUnit.TestProject.GrandparentBase).GetField("k__BackingField", - global::System.Reflection.BindingFlags.Instance | global::System.Reflection.BindingFlags.NonPublic); - backingField.SetValue(typedInstance, value); -#endif - } - }; - - } -} - - -// ===== FILE SEPARATOR ===== - -using System; -using System.Collections.Generic; -using TUnit.Core; -using TUnit.Core.Interfaces.SourceGenerator; -using TUnit.Core.Enums; -using System.Linq; - -namespace TUnit.Core; - -internal static class TUnit_TestProject_GrandparentBase_TUnit_TestProject_DeepInheritanceMultiLevelPropertyTests_TestProgram__Generic_PropertyInjectionInitializer -{ - [global::System.Runtime.CompilerServices.ModuleInitializer] - public static void Initialize() - { - global::TUnit.Core.PropertySourceRegistry.Register(typeof(global::TUnit.TestProject.GrandparentBase), new PropertyInjectionSource_Generic_72e68a44()); - } -} - -internal sealed class PropertyInjectionSource_Generic_72e68a44 : IPropertySource -{ - public Type Type => typeof(global::TUnit.TestProject.GrandparentBase); - public bool ShouldInitialize => true; - -#if NET8_0_OR_GREATER - [global::System.Runtime.CompilerServices.UnsafeAccessor(global::System.Runtime.CompilerServices.UnsafeAccessorKind.Field, Name = "k__BackingField")] - private static extern ref global::TUnit.TestProject.InMemoryDatabase GetGrandparentDbBackingField(TUnit.TestProject.GrandparentBase instance); -#endif - - public IEnumerable GetPropertyMetadata() - { - yield return new PropertyInjectionMetadata - { - PropertyName = "GrandparentDb", - PropertyType = typeof(global::TUnit.TestProject.InMemoryDatabase), - ContainingType = typeof(TUnit.TestProject.GrandparentBase), - CreateDataSource = () => - { - var dataSource = new TUnit.Core.ClassDataSourceAttribute(); - dataSource.Shared = (TUnit.Core.SharedType)3; - return dataSource; - }, - SetProperty = (instance, value) => - { - var typedInstance = (global::TUnit.TestProject.GrandparentBase)instance; -#if NET8_0_OR_GREATER - GetGrandparentDbBackingField((TUnit.TestProject.GrandparentBase)typedInstance) = (global::TUnit.TestProject.InMemoryDatabase)value; -#else - var backingField = typeof(TUnit.TestProject.GrandparentBase).GetField("k__BackingField", - global::System.Reflection.BindingFlags.Instance | global::System.Reflection.BindingFlags.NonPublic); - backingField.SetValue(typedInstance, value); -#endif - } - }; - - } -} - - -// ===== FILE SEPARATOR ===== - -using System; -using System.Collections.Generic; -using TUnit.Core; -using TUnit.Core.Interfaces.SourceGenerator; -using TUnit.Core.Enums; -using System.Linq; - -namespace TUnit.Core; - -internal static class TUnit_TestProject_GenericFixtureBase_TUnit_TestProject_MixedGenericAndDerivedPropertiesTests_TestProgram__Generic_PropertyInjectionInitializer -{ - [global::System.Runtime.CompilerServices.ModuleInitializer] - public static void Initialize() - { - global::TUnit.Core.PropertySourceRegistry.Register(typeof(global::TUnit.TestProject.GenericFixtureBase), new PropertyInjectionSource_Generic_23bcede5()); - } -} - -internal sealed class PropertyInjectionSource_Generic_23bcede5 : IPropertySource -{ - public Type Type => typeof(global::TUnit.TestProject.GenericFixtureBase); - public bool ShouldInitialize => true; - -#if NET8_0_OR_GREATER - [global::System.Runtime.CompilerServices.UnsafeAccessor(global::System.Runtime.CompilerServices.UnsafeAccessorKind.Field, Name = "k__BackingField")] - private static extern ref global::TUnit.TestProject.InMemoryDatabase GetPostgresBackingField(TUnit.TestProject.GenericFixtureBase instance); -#endif - - public IEnumerable GetPropertyMetadata() - { - yield return new PropertyInjectionMetadata - { - PropertyName = "Postgres", - PropertyType = typeof(global::TUnit.TestProject.InMemoryDatabase), - ContainingType = typeof(TUnit.TestProject.GenericFixtureBase), - CreateDataSource = () => - { - var dataSource = new TUnit.Core.ClassDataSourceAttribute(); - dataSource.Shared = (TUnit.Core.SharedType)3; - return dataSource; - }, - SetProperty = (instance, value) => - { - var typedInstance = (global::TUnit.TestProject.GenericFixtureBase)instance; -#if NET8_0_OR_GREATER - GetPostgresBackingField((TUnit.TestProject.GenericFixtureBase)typedInstance) = (global::TUnit.TestProject.InMemoryDatabase)value; -#else - var backingField = typeof(TUnit.TestProject.GenericFixtureBase).GetField("k__BackingField", - global::System.Reflection.BindingFlags.Instance | global::System.Reflection.BindingFlags.NonPublic); - backingField.SetValue(typedInstance, value); -#endif - } - }; - - } -} - - -// ===== FILE SEPARATOR ===== - -using System; -using System.Collections.Generic; -using TUnit.Core; -using TUnit.Core.Interfaces.SourceGenerator; -using TUnit.Core.Enums; -using System.Linq; - -namespace TUnit.Core; - -internal static class TUnit_TestProject_GenericFixtureBase_System_Collections_Generic_List_string___Generic_PropertyInjectionInitializer -{ - [global::System.Runtime.CompilerServices.ModuleInitializer] - public static void Initialize() - { - global::TUnit.Core.PropertySourceRegistry.Register(typeof(global::TUnit.TestProject.GenericFixtureBase>), new PropertyInjectionSource_Generic_48d518d8()); - } -} - -internal sealed class PropertyInjectionSource_Generic_48d518d8 : IPropertySource -{ - public Type Type => typeof(global::TUnit.TestProject.GenericFixtureBase>); - public bool ShouldInitialize => true; - -#if NET8_0_OR_GREATER - [global::System.Runtime.CompilerServices.UnsafeAccessor(global::System.Runtime.CompilerServices.UnsafeAccessorKind.Field, Name = "k__BackingField")] - private static extern ref global::TUnit.TestProject.InMemoryDatabase GetPostgresBackingField(TUnit.TestProject.GenericFixtureBase> instance); -#endif - - public IEnumerable GetPropertyMetadata() - { - yield return new PropertyInjectionMetadata - { - PropertyName = "Postgres", - PropertyType = typeof(global::TUnit.TestProject.InMemoryDatabase), - ContainingType = typeof(TUnit.TestProject.GenericFixtureBase>), - CreateDataSource = () => - { - var dataSource = new TUnit.Core.ClassDataSourceAttribute(); - dataSource.Shared = (TUnit.Core.SharedType)3; - return dataSource; - }, - SetProperty = (instance, value) => - { - var typedInstance = (global::TUnit.TestProject.GenericFixtureBase>)instance; -#if NET8_0_OR_GREATER - GetPostgresBackingField((TUnit.TestProject.GenericFixtureBase>)typedInstance) = (global::TUnit.TestProject.InMemoryDatabase)value; -#else - var backingField = typeof(TUnit.TestProject.GenericFixtureBase>).GetField("k__BackingField", - global::System.Reflection.BindingFlags.Instance | global::System.Reflection.BindingFlags.NonPublic); - backingField.SetValue(typedInstance, value); -#endif - } - }; - - } -} - - -// ===== FILE SEPARATOR ===== - -using System; -using TUnit.Core.Discovery; - -namespace TUnit.Generated; - -internal static class TUnit_TestProject_GenericInitializerFixture_TUnit_TestProject_GenericInitializerWithNestedPropertyTests__Generic_InitializerPropertiesInitializer -{ - [global::System.Runtime.CompilerServices.ModuleInitializer] - public static void Initialize() - { - InitializerPropertyRegistry.Register(typeof(global::TUnit.TestProject.GenericInitializerFixture), new InitializerPropertyInfo[] - { - new InitializerPropertyInfo - { - PropertyName = "Database", - PropertyType = typeof(global::TUnit.TestProject.InMemoryDatabase), - GetValue = static obj => ((global::TUnit.TestProject.GenericInitializerFixture)obj).Database - }, - }); - } -} - - -// ===== FILE SEPARATOR ===== - -using System; -using System.Collections.Generic; -using TUnit.Core; -using TUnit.Core.Interfaces.SourceGenerator; -using TUnit.Core.Enums; -using System.Linq; - -namespace TUnit.Core; - -internal static class TUnit_TestProject_CustomWebApplicationFactory_TUnit_TestProject_Issue4431_WebApplicationFactoryScenarioTests_TestProgram__Generic_PropertyInjectionInitializer -{ - [global::System.Runtime.CompilerServices.ModuleInitializer] - public static void Initialize() - { - global::TUnit.Core.PropertySourceRegistry.Register(typeof(global::TUnit.TestProject.CustomWebApplicationFactory), new PropertyInjectionSource_Generic_39565e8e()); - } -} - -internal sealed class PropertyInjectionSource_Generic_39565e8e : IPropertySource -{ - public Type Type => typeof(global::TUnit.TestProject.CustomWebApplicationFactory); - public bool ShouldInitialize => true; - -#if NET8_0_OR_GREATER - [global::System.Runtime.CompilerServices.UnsafeAccessor(global::System.Runtime.CompilerServices.UnsafeAccessorKind.Field, Name = "k__BackingField")] - private static extern ref global::TUnit.TestProject.InMemoryDatabase GetTestDatabaseBackingField(TUnit.TestProject.CustomWebApplicationFactory instance); -#endif - - public IEnumerable GetPropertyMetadata() - { - yield return new PropertyInjectionMetadata - { - PropertyName = "TestDatabase", - PropertyType = typeof(global::TUnit.TestProject.InMemoryDatabase), - ContainingType = typeof(TUnit.TestProject.CustomWebApplicationFactory), - CreateDataSource = () => - { - var dataSource = new TUnit.Core.ClassDataSourceAttribute(); - dataSource.Shared = (TUnit.Core.SharedType)3; - return dataSource; - }, - SetProperty = (instance, value) => - { - var typedInstance = (global::TUnit.TestProject.CustomWebApplicationFactory)instance; -#if NET8_0_OR_GREATER - GetTestDatabaseBackingField((TUnit.TestProject.CustomWebApplicationFactory)typedInstance) = (global::TUnit.TestProject.InMemoryDatabase)value; -#else - var backingField = typeof(TUnit.TestProject.CustomWebApplicationFactory).GetField("k__BackingField", - global::System.Reflection.BindingFlags.Instance | global::System.Reflection.BindingFlags.NonPublic); - backingField.SetValue(typedInstance, value); -#endif - } - }; - - } -} - - -// ===== FILE SEPARATOR ===== - -using System; -using TUnit.Core.Discovery; - -namespace TUnit.Generated; - -internal static class TUnit_TestProject_CustomWebApplicationFactory_TUnit_TestProject_Issue4431_WebApplicationFactoryScenarioTests_TestProgram__Generic_InitializerPropertiesInitializer -{ - [global::System.Runtime.CompilerServices.ModuleInitializer] - public static void Initialize() - { - InitializerPropertyRegistry.Register(typeof(global::TUnit.TestProject.CustomWebApplicationFactory), new InitializerPropertyInfo[] - { - new InitializerPropertyInfo - { - PropertyName = "TestDatabase", - PropertyType = typeof(global::TUnit.TestProject.InMemoryDatabase), - GetValue = static obj => ((global::TUnit.TestProject.CustomWebApplicationFactory)obj).TestDatabase - }, - }); - } -} - - -// ===== FILE SEPARATOR ===== - -using System; -using System.Collections.Generic; -using TUnit.Core; -using TUnit.Core.Interfaces.SourceGenerator; -using TUnit.Core.Enums; -using System.Linq; - -namespace TUnit.Core; - -internal static class TUnit_TestProject_WebAppFactoryBase_TUnit_TestProject_CustomWebApplicationFactory_TUnit_TestProject_Issue4431_ComplexGenericInheritanceTests_MyProgram__TUnit_TestProject_Issue4431_ComplexGenericInheritanceTests_MyProgram__Generic_PropertyInjectionInitializer -{ - [global::System.Runtime.CompilerServices.ModuleInitializer] - public static void Initialize() - { - global::TUnit.Core.PropertySourceRegistry.Register(typeof(global::TUnit.TestProject.WebAppFactoryBase, global::TUnit.TestProject.Issue4431_ComplexGenericInheritanceTests.MyProgram>), new PropertyInjectionSource_Generic_3c089123()); - } -} - -internal sealed class PropertyInjectionSource_Generic_3c089123 : IPropertySource -{ - public Type Type => typeof(global::TUnit.TestProject.WebAppFactoryBase, global::TUnit.TestProject.Issue4431_ComplexGenericInheritanceTests.MyProgram>); - public bool ShouldInitialize => true; - -#if NET8_0_OR_GREATER - [global::System.Runtime.CompilerServices.UnsafeAccessor(global::System.Runtime.CompilerServices.UnsafeAccessorKind.Field, Name = "k__BackingField")] - private static extern ref global::TUnit.TestProject.InMemoryDatabase GetSharedDatabaseBackingField(TUnit.TestProject.WebAppFactoryBase, TUnit.TestProject.Issue4431_ComplexGenericInheritanceTests.MyProgram> instance); -#endif - - public IEnumerable GetPropertyMetadata() - { - yield return new PropertyInjectionMetadata - { - PropertyName = "SharedDatabase", - PropertyType = typeof(global::TUnit.TestProject.InMemoryDatabase), - ContainingType = typeof(TUnit.TestProject.WebAppFactoryBase, TUnit.TestProject.Issue4431_ComplexGenericInheritanceTests.MyProgram>), - CreateDataSource = () => - { - var dataSource = new TUnit.Core.ClassDataSourceAttribute(); - dataSource.Shared = (TUnit.Core.SharedType)3; - return dataSource; - }, - SetProperty = (instance, value) => - { - var typedInstance = (global::TUnit.TestProject.WebAppFactoryBase, global::TUnit.TestProject.Issue4431_ComplexGenericInheritanceTests.MyProgram>)instance; -#if NET8_0_OR_GREATER - GetSharedDatabaseBackingField((TUnit.TestProject.WebAppFactoryBase, TUnit.TestProject.Issue4431_ComplexGenericInheritanceTests.MyProgram>)typedInstance) = (global::TUnit.TestProject.InMemoryDatabase)value; -#else - var backingField = typeof(TUnit.TestProject.WebAppFactoryBase, TUnit.TestProject.Issue4431_ComplexGenericInheritanceTests.MyProgram>).GetField("k__BackingField", - global::System.Reflection.BindingFlags.Instance | global::System.Reflection.BindingFlags.NonPublic); - backingField.SetValue(typedInstance, value); -#endif - } - }; - - } -} diff --git a/TUnit.Core.SourceGenerator.Tests/GenericPropertyInjectionTests.GenericClassDataSource_WithInitializerProperties_GeneratesMetadata.verified.txt b/TUnit.Core.SourceGenerator.Tests/GenericPropertyInjectionTests.GenericClassDataSource_WithInitializerProperties_GeneratesMetadata.verified.txt deleted file mode 100644 index 7b28dd257e..0000000000 --- a/TUnit.Core.SourceGenerator.Tests/GenericPropertyInjectionTests.GenericClassDataSource_WithInitializerProperties_GeneratesMetadata.verified.txt +++ /dev/null @@ -1,321 +0,0 @@ -using System; -using System.Collections.Generic; -using TUnit.Core; -using TUnit.Core.Interfaces.SourceGenerator; -using TUnit.Core.Enums; -using System.Linq; - -namespace TUnit.Core; - -internal static class TUnit_TestProject_GenericInitializerPropertyTests_PropertyInjectionInitializer -{ - [global::System.Runtime.CompilerServices.ModuleInitializer] - public static void Initialize() - { - global::TUnit.Core.PropertySourceRegistry.Register(typeof(global::TUnit.TestProject.GenericInitializerPropertyTests), new PropertyInjectionSource_61ab58e()); - } -} - -internal sealed class PropertyInjectionSource_61ab58e : IPropertySource -{ - public Type Type => typeof(global::TUnit.TestProject.GenericInitializerPropertyTests); - public bool ShouldInitialize => true; - -#if NET8_0_OR_GREATER - [global::System.Runtime.CompilerServices.UnsafeAccessor(global::System.Runtime.CompilerServices.UnsafeAccessorKind.Field, Name = "k__BackingField")] - private static extern ref global::TUnit.TestProject.GenericInitializerFixture GetFixtureBackingField(TUnit.TestProject.GenericInitializerPropertyTests instance); -#endif - - public IEnumerable GetPropertyMetadata() - { - yield return new PropertyInjectionMetadata - { - PropertyName = "Fixture", - PropertyType = typeof(global::TUnit.TestProject.GenericInitializerFixture), - ContainingType = typeof(TUnit.TestProject.GenericInitializerPropertyTests), - CreateDataSource = () => - { - var dataSource = new TUnit.Core.ClassDataSourceAttribute>(); - dataSource.Shared = (TUnit.Core.SharedType)3; - return dataSource; - }, - SetProperty = (instance, value) => - { - var typedInstance = (global::TUnit.TestProject.GenericInitializerPropertyTests)instance; -#if NET8_0_OR_GREATER - GetFixtureBackingField((TUnit.TestProject.GenericInitializerPropertyTests)typedInstance) = (global::TUnit.TestProject.GenericInitializerFixture)value; -#else - var backingField = typeof(TUnit.TestProject.GenericInitializerPropertyTests).GetField("k__BackingField", - global::System.Reflection.BindingFlags.Instance | global::System.Reflection.BindingFlags.NonPublic); - backingField.SetValue(typedInstance, value); -#endif - } - }; - - } -} - - -// ===== FILE SEPARATOR ===== - -using System; -using System.Collections.Generic; -using TUnit.Core; -using TUnit.Core.Interfaces.SourceGenerator; -using TUnit.Core.Enums; -using System.Linq; - -namespace TUnit.Core; - -internal static class TUnit_TestProject_GenericFixtureBase_TUnit_TestProject_GenericPropertyInjectionTests_TestProgram__Generic_PropertyInjectionInitializer -{ - [global::System.Runtime.CompilerServices.ModuleInitializer] - public static void Initialize() - { - global::TUnit.Core.PropertySourceRegistry.Register(typeof(global::TUnit.TestProject.GenericFixtureBase), new PropertyInjectionSource_Generic_7a6c8287()); - } -} - -internal sealed class PropertyInjectionSource_Generic_7a6c8287 : IPropertySource -{ - public Type Type => typeof(global::TUnit.TestProject.GenericFixtureBase); - public bool ShouldInitialize => true; - -#if NET8_0_OR_GREATER - [global::System.Runtime.CompilerServices.UnsafeAccessor(global::System.Runtime.CompilerServices.UnsafeAccessorKind.Field, Name = "k__BackingField")] - private static extern ref global::TUnit.TestProject.InMemoryDatabase GetPostgresBackingField(TUnit.TestProject.GenericFixtureBase instance); -#endif - - public IEnumerable GetPropertyMetadata() - { - yield return new PropertyInjectionMetadata - { - PropertyName = "Postgres", - PropertyType = typeof(global::TUnit.TestProject.InMemoryDatabase), - ContainingType = typeof(TUnit.TestProject.GenericFixtureBase), - CreateDataSource = () => - { - var dataSource = new TUnit.Core.ClassDataSourceAttribute(); - dataSource.Shared = (TUnit.Core.SharedType)3; - return dataSource; - }, - SetProperty = (instance, value) => - { - var typedInstance = (global::TUnit.TestProject.GenericFixtureBase)instance; -#if NET8_0_OR_GREATER - GetPostgresBackingField((TUnit.TestProject.GenericFixtureBase)typedInstance) = (global::TUnit.TestProject.InMemoryDatabase)value; -#else - var backingField = typeof(TUnit.TestProject.GenericFixtureBase).GetField("k__BackingField", - global::System.Reflection.BindingFlags.Instance | global::System.Reflection.BindingFlags.NonPublic); - backingField.SetValue(typedInstance, value); -#endif - } - }; - - } -} - - -// ===== FILE SEPARATOR ===== - -using System; -using System.Collections.Generic; -using TUnit.Core; -using TUnit.Core.Interfaces.SourceGenerator; -using TUnit.Core.Enums; -using System.Linq; - -namespace TUnit.Core; - -internal static class TUnit_TestProject_GenericFixtureBase_TUnit_TestProject_MultipleGenericInstantiationTests_OtherProgram__Generic_PropertyInjectionInitializer -{ - [global::System.Runtime.CompilerServices.ModuleInitializer] - public static void Initialize() - { - global::TUnit.Core.PropertySourceRegistry.Register(typeof(global::TUnit.TestProject.GenericFixtureBase), new PropertyInjectionSource_Generic_64877686()); - } -} - -internal sealed class PropertyInjectionSource_Generic_64877686 : IPropertySource -{ - public Type Type => typeof(global::TUnit.TestProject.GenericFixtureBase); - public bool ShouldInitialize => true; - -#if NET8_0_OR_GREATER - [global::System.Runtime.CompilerServices.UnsafeAccessor(global::System.Runtime.CompilerServices.UnsafeAccessorKind.Field, Name = "k__BackingField")] - private static extern ref global::TUnit.TestProject.InMemoryDatabase GetPostgresBackingField(TUnit.TestProject.GenericFixtureBase instance); -#endif - - public IEnumerable GetPropertyMetadata() - { - yield return new PropertyInjectionMetadata - { - PropertyName = "Postgres", - PropertyType = typeof(global::TUnit.TestProject.InMemoryDatabase), - ContainingType = typeof(TUnit.TestProject.GenericFixtureBase), - CreateDataSource = () => - { - var dataSource = new TUnit.Core.ClassDataSourceAttribute(); - dataSource.Shared = (TUnit.Core.SharedType)3; - return dataSource; - }, - SetProperty = (instance, value) => - { - var typedInstance = (global::TUnit.TestProject.GenericFixtureBase)instance; -#if NET8_0_OR_GREATER - GetPostgresBackingField((TUnit.TestProject.GenericFixtureBase)typedInstance) = (global::TUnit.TestProject.InMemoryDatabase)value; -#else - var backingField = typeof(TUnit.TestProject.GenericFixtureBase).GetField("k__BackingField", - global::System.Reflection.BindingFlags.Instance | global::System.Reflection.BindingFlags.NonPublic); - backingField.SetValue(typedInstance, value); -#endif - } - }; - - } -} - - -// ===== FILE SEPARATOR ===== - -using System; -using System.Collections.Generic; -using TUnit.Core; -using TUnit.Core.Interfaces.SourceGenerator; -using TUnit.Core.Enums; -using System.Linq; - -namespace TUnit.Core; - -internal static class TUnit_TestProject_IntermediateBase_TUnit_TestProject_DeepInheritanceGenericTests_DeepProgram__Generic_PropertyInjectionInitializer -{ - [global::System.Runtime.CompilerServices.ModuleInitializer] - public static void Initialize() - { - global::TUnit.Core.PropertySourceRegistry.Register(typeof(global::TUnit.TestProject.IntermediateBase), new PropertyInjectionSource_Generic_344bd53a()); - } -} - -internal sealed class PropertyInjectionSource_Generic_344bd53a : IPropertySource -{ - public Type Type => typeof(global::TUnit.TestProject.IntermediateBase); - public bool ShouldInitialize => true; - -#if NET8_0_OR_GREATER - [global::System.Runtime.CompilerServices.UnsafeAccessor(global::System.Runtime.CompilerServices.UnsafeAccessorKind.Field, Name = "k__BackingField")] - private static extern ref global::TUnit.TestProject.InMemoryDatabase GetPostgresBackingField(TUnit.TestProject.GenericFixtureBase instance); -#endif - - public IEnumerable GetPropertyMetadata() - { - yield return new PropertyInjectionMetadata - { - PropertyName = "Postgres", - PropertyType = typeof(global::TUnit.TestProject.InMemoryDatabase), - ContainingType = typeof(TUnit.TestProject.GenericFixtureBase), - CreateDataSource = () => - { - var dataSource = new TUnit.Core.ClassDataSourceAttribute(); - dataSource.Shared = (TUnit.Core.SharedType)3; - return dataSource; - }, - SetProperty = (instance, value) => - { - var typedInstance = (global::TUnit.TestProject.IntermediateBase)instance; -#if NET8_0_OR_GREATER - GetPostgresBackingField((TUnit.TestProject.GenericFixtureBase)typedInstance) = (global::TUnit.TestProject.InMemoryDatabase)value; -#else - var backingField = typeof(TUnit.TestProject.GenericFixtureBase).GetField("k__BackingField", - global::System.Reflection.BindingFlags.Instance | global::System.Reflection.BindingFlags.NonPublic); - backingField.SetValue(typedInstance, value); -#endif - } - }; - - } -} - - -// ===== FILE SEPARATOR ===== - -using System; -using System.Collections.Generic; -using TUnit.Core; -using TUnit.Core.Interfaces.SourceGenerator; -using TUnit.Core.Enums; -using System.Linq; - -namespace TUnit.Core; - -internal static class TUnit_TestProject_GenericFixtureBase_TUnit_TestProject_DeepInheritanceGenericTests_DeepProgram__Generic_PropertyInjectionInitializer -{ - [global::System.Runtime.CompilerServices.ModuleInitializer] - public static void Initialize() - { - global::TUnit.Core.PropertySourceRegistry.Register(typeof(global::TUnit.TestProject.GenericFixtureBase), new PropertyInjectionSource_Generic_48a5b53f()); - } -} - -internal sealed class PropertyInjectionSource_Generic_48a5b53f : IPropertySource -{ - public Type Type => typeof(global::TUnit.TestProject.GenericFixtureBase); - public bool ShouldInitialize => true; - -#if NET8_0_OR_GREATER - [global::System.Runtime.CompilerServices.UnsafeAccessor(global::System.Runtime.CompilerServices.UnsafeAccessorKind.Field, Name = "k__BackingField")] - private static extern ref global::TUnit.TestProject.InMemoryDatabase GetPostgresBackingField(TUnit.TestProject.GenericFixtureBase instance); -#endif - - public IEnumerable GetPropertyMetadata() - { - yield return new PropertyInjectionMetadata - { - PropertyName = "Postgres", - PropertyType = typeof(global::TUnit.TestProject.InMemoryDatabase), - ContainingType = typeof(TUnit.TestProject.GenericFixtureBase), - CreateDataSource = () => - { - var dataSource = new TUnit.Core.ClassDataSourceAttribute(); - dataSource.Shared = (TUnit.Core.SharedType)3; - return dataSource; - }, - SetProperty = (instance, value) => - { - var typedInstance = (global::TUnit.TestProject.GenericFixtureBase)instance; -#if NET8_0_OR_GREATER - GetPostgresBackingField((TUnit.TestProject.GenericFixtureBase)typedInstance) = (global::TUnit.TestProject.InMemoryDatabase)value; -#else - var backingField = typeof(TUnit.TestProject.GenericFixtureBase).GetField("k__BackingField", - global::System.Reflection.BindingFlags.Instance | global::System.Reflection.BindingFlags.NonPublic); - backingField.SetValue(typedInstance, value); -#endif - } - }; - - } -} - - -// ===== FILE SEPARATOR ===== - -using System; -using TUnit.Core.Discovery; - -namespace TUnit.Generated; - -internal static class TUnit_TestProject_GenericInitializerFixture_TUnit_TestProject_GenericInitializerPropertyTests__Generic_InitializerPropertiesInitializer -{ - [global::System.Runtime.CompilerServices.ModuleInitializer] - public static void Initialize() - { - InitializerPropertyRegistry.Register(typeof(global::TUnit.TestProject.GenericInitializerFixture), new InitializerPropertyInfo[] - { - new InitializerPropertyInfo - { - PropertyName = "Database", - PropertyType = typeof(global::TUnit.TestProject.InMemoryDatabase), - GetValue = static obj => ((global::TUnit.TestProject.GenericInitializerFixture)obj).Database - }, - }); - } -} diff --git a/TUnit.Core.SourceGenerator.Tests/GenericPropertyInjectionTests.MultipleInstantiations_EachGenerateMetadata.verified.txt b/TUnit.Core.SourceGenerator.Tests/GenericPropertyInjectionTests.MultipleInstantiations_EachGenerateMetadata.verified.txt deleted file mode 100644 index 7b28dd257e..0000000000 --- a/TUnit.Core.SourceGenerator.Tests/GenericPropertyInjectionTests.MultipleInstantiations_EachGenerateMetadata.verified.txt +++ /dev/null @@ -1,321 +0,0 @@ -using System; -using System.Collections.Generic; -using TUnit.Core; -using TUnit.Core.Interfaces.SourceGenerator; -using TUnit.Core.Enums; -using System.Linq; - -namespace TUnit.Core; - -internal static class TUnit_TestProject_GenericInitializerPropertyTests_PropertyInjectionInitializer -{ - [global::System.Runtime.CompilerServices.ModuleInitializer] - public static void Initialize() - { - global::TUnit.Core.PropertySourceRegistry.Register(typeof(global::TUnit.TestProject.GenericInitializerPropertyTests), new PropertyInjectionSource_61ab58e()); - } -} - -internal sealed class PropertyInjectionSource_61ab58e : IPropertySource -{ - public Type Type => typeof(global::TUnit.TestProject.GenericInitializerPropertyTests); - public bool ShouldInitialize => true; - -#if NET8_0_OR_GREATER - [global::System.Runtime.CompilerServices.UnsafeAccessor(global::System.Runtime.CompilerServices.UnsafeAccessorKind.Field, Name = "k__BackingField")] - private static extern ref global::TUnit.TestProject.GenericInitializerFixture GetFixtureBackingField(TUnit.TestProject.GenericInitializerPropertyTests instance); -#endif - - public IEnumerable GetPropertyMetadata() - { - yield return new PropertyInjectionMetadata - { - PropertyName = "Fixture", - PropertyType = typeof(global::TUnit.TestProject.GenericInitializerFixture), - ContainingType = typeof(TUnit.TestProject.GenericInitializerPropertyTests), - CreateDataSource = () => - { - var dataSource = new TUnit.Core.ClassDataSourceAttribute>(); - dataSource.Shared = (TUnit.Core.SharedType)3; - return dataSource; - }, - SetProperty = (instance, value) => - { - var typedInstance = (global::TUnit.TestProject.GenericInitializerPropertyTests)instance; -#if NET8_0_OR_GREATER - GetFixtureBackingField((TUnit.TestProject.GenericInitializerPropertyTests)typedInstance) = (global::TUnit.TestProject.GenericInitializerFixture)value; -#else - var backingField = typeof(TUnit.TestProject.GenericInitializerPropertyTests).GetField("k__BackingField", - global::System.Reflection.BindingFlags.Instance | global::System.Reflection.BindingFlags.NonPublic); - backingField.SetValue(typedInstance, value); -#endif - } - }; - - } -} - - -// ===== FILE SEPARATOR ===== - -using System; -using System.Collections.Generic; -using TUnit.Core; -using TUnit.Core.Interfaces.SourceGenerator; -using TUnit.Core.Enums; -using System.Linq; - -namespace TUnit.Core; - -internal static class TUnit_TestProject_GenericFixtureBase_TUnit_TestProject_GenericPropertyInjectionTests_TestProgram__Generic_PropertyInjectionInitializer -{ - [global::System.Runtime.CompilerServices.ModuleInitializer] - public static void Initialize() - { - global::TUnit.Core.PropertySourceRegistry.Register(typeof(global::TUnit.TestProject.GenericFixtureBase), new PropertyInjectionSource_Generic_7a6c8287()); - } -} - -internal sealed class PropertyInjectionSource_Generic_7a6c8287 : IPropertySource -{ - public Type Type => typeof(global::TUnit.TestProject.GenericFixtureBase); - public bool ShouldInitialize => true; - -#if NET8_0_OR_GREATER - [global::System.Runtime.CompilerServices.UnsafeAccessor(global::System.Runtime.CompilerServices.UnsafeAccessorKind.Field, Name = "k__BackingField")] - private static extern ref global::TUnit.TestProject.InMemoryDatabase GetPostgresBackingField(TUnit.TestProject.GenericFixtureBase instance); -#endif - - public IEnumerable GetPropertyMetadata() - { - yield return new PropertyInjectionMetadata - { - PropertyName = "Postgres", - PropertyType = typeof(global::TUnit.TestProject.InMemoryDatabase), - ContainingType = typeof(TUnit.TestProject.GenericFixtureBase), - CreateDataSource = () => - { - var dataSource = new TUnit.Core.ClassDataSourceAttribute(); - dataSource.Shared = (TUnit.Core.SharedType)3; - return dataSource; - }, - SetProperty = (instance, value) => - { - var typedInstance = (global::TUnit.TestProject.GenericFixtureBase)instance; -#if NET8_0_OR_GREATER - GetPostgresBackingField((TUnit.TestProject.GenericFixtureBase)typedInstance) = (global::TUnit.TestProject.InMemoryDatabase)value; -#else - var backingField = typeof(TUnit.TestProject.GenericFixtureBase).GetField("k__BackingField", - global::System.Reflection.BindingFlags.Instance | global::System.Reflection.BindingFlags.NonPublic); - backingField.SetValue(typedInstance, value); -#endif - } - }; - - } -} - - -// ===== FILE SEPARATOR ===== - -using System; -using System.Collections.Generic; -using TUnit.Core; -using TUnit.Core.Interfaces.SourceGenerator; -using TUnit.Core.Enums; -using System.Linq; - -namespace TUnit.Core; - -internal static class TUnit_TestProject_GenericFixtureBase_TUnit_TestProject_MultipleGenericInstantiationTests_OtherProgram__Generic_PropertyInjectionInitializer -{ - [global::System.Runtime.CompilerServices.ModuleInitializer] - public static void Initialize() - { - global::TUnit.Core.PropertySourceRegistry.Register(typeof(global::TUnit.TestProject.GenericFixtureBase), new PropertyInjectionSource_Generic_64877686()); - } -} - -internal sealed class PropertyInjectionSource_Generic_64877686 : IPropertySource -{ - public Type Type => typeof(global::TUnit.TestProject.GenericFixtureBase); - public bool ShouldInitialize => true; - -#if NET8_0_OR_GREATER - [global::System.Runtime.CompilerServices.UnsafeAccessor(global::System.Runtime.CompilerServices.UnsafeAccessorKind.Field, Name = "k__BackingField")] - private static extern ref global::TUnit.TestProject.InMemoryDatabase GetPostgresBackingField(TUnit.TestProject.GenericFixtureBase instance); -#endif - - public IEnumerable GetPropertyMetadata() - { - yield return new PropertyInjectionMetadata - { - PropertyName = "Postgres", - PropertyType = typeof(global::TUnit.TestProject.InMemoryDatabase), - ContainingType = typeof(TUnit.TestProject.GenericFixtureBase), - CreateDataSource = () => - { - var dataSource = new TUnit.Core.ClassDataSourceAttribute(); - dataSource.Shared = (TUnit.Core.SharedType)3; - return dataSource; - }, - SetProperty = (instance, value) => - { - var typedInstance = (global::TUnit.TestProject.GenericFixtureBase)instance; -#if NET8_0_OR_GREATER - GetPostgresBackingField((TUnit.TestProject.GenericFixtureBase)typedInstance) = (global::TUnit.TestProject.InMemoryDatabase)value; -#else - var backingField = typeof(TUnit.TestProject.GenericFixtureBase).GetField("k__BackingField", - global::System.Reflection.BindingFlags.Instance | global::System.Reflection.BindingFlags.NonPublic); - backingField.SetValue(typedInstance, value); -#endif - } - }; - - } -} - - -// ===== FILE SEPARATOR ===== - -using System; -using System.Collections.Generic; -using TUnit.Core; -using TUnit.Core.Interfaces.SourceGenerator; -using TUnit.Core.Enums; -using System.Linq; - -namespace TUnit.Core; - -internal static class TUnit_TestProject_IntermediateBase_TUnit_TestProject_DeepInheritanceGenericTests_DeepProgram__Generic_PropertyInjectionInitializer -{ - [global::System.Runtime.CompilerServices.ModuleInitializer] - public static void Initialize() - { - global::TUnit.Core.PropertySourceRegistry.Register(typeof(global::TUnit.TestProject.IntermediateBase), new PropertyInjectionSource_Generic_344bd53a()); - } -} - -internal sealed class PropertyInjectionSource_Generic_344bd53a : IPropertySource -{ - public Type Type => typeof(global::TUnit.TestProject.IntermediateBase); - public bool ShouldInitialize => true; - -#if NET8_0_OR_GREATER - [global::System.Runtime.CompilerServices.UnsafeAccessor(global::System.Runtime.CompilerServices.UnsafeAccessorKind.Field, Name = "k__BackingField")] - private static extern ref global::TUnit.TestProject.InMemoryDatabase GetPostgresBackingField(TUnit.TestProject.GenericFixtureBase instance); -#endif - - public IEnumerable GetPropertyMetadata() - { - yield return new PropertyInjectionMetadata - { - PropertyName = "Postgres", - PropertyType = typeof(global::TUnit.TestProject.InMemoryDatabase), - ContainingType = typeof(TUnit.TestProject.GenericFixtureBase), - CreateDataSource = () => - { - var dataSource = new TUnit.Core.ClassDataSourceAttribute(); - dataSource.Shared = (TUnit.Core.SharedType)3; - return dataSource; - }, - SetProperty = (instance, value) => - { - var typedInstance = (global::TUnit.TestProject.IntermediateBase)instance; -#if NET8_0_OR_GREATER - GetPostgresBackingField((TUnit.TestProject.GenericFixtureBase)typedInstance) = (global::TUnit.TestProject.InMemoryDatabase)value; -#else - var backingField = typeof(TUnit.TestProject.GenericFixtureBase).GetField("k__BackingField", - global::System.Reflection.BindingFlags.Instance | global::System.Reflection.BindingFlags.NonPublic); - backingField.SetValue(typedInstance, value); -#endif - } - }; - - } -} - - -// ===== FILE SEPARATOR ===== - -using System; -using System.Collections.Generic; -using TUnit.Core; -using TUnit.Core.Interfaces.SourceGenerator; -using TUnit.Core.Enums; -using System.Linq; - -namespace TUnit.Core; - -internal static class TUnit_TestProject_GenericFixtureBase_TUnit_TestProject_DeepInheritanceGenericTests_DeepProgram__Generic_PropertyInjectionInitializer -{ - [global::System.Runtime.CompilerServices.ModuleInitializer] - public static void Initialize() - { - global::TUnit.Core.PropertySourceRegistry.Register(typeof(global::TUnit.TestProject.GenericFixtureBase), new PropertyInjectionSource_Generic_48a5b53f()); - } -} - -internal sealed class PropertyInjectionSource_Generic_48a5b53f : IPropertySource -{ - public Type Type => typeof(global::TUnit.TestProject.GenericFixtureBase); - public bool ShouldInitialize => true; - -#if NET8_0_OR_GREATER - [global::System.Runtime.CompilerServices.UnsafeAccessor(global::System.Runtime.CompilerServices.UnsafeAccessorKind.Field, Name = "k__BackingField")] - private static extern ref global::TUnit.TestProject.InMemoryDatabase GetPostgresBackingField(TUnit.TestProject.GenericFixtureBase instance); -#endif - - public IEnumerable GetPropertyMetadata() - { - yield return new PropertyInjectionMetadata - { - PropertyName = "Postgres", - PropertyType = typeof(global::TUnit.TestProject.InMemoryDatabase), - ContainingType = typeof(TUnit.TestProject.GenericFixtureBase), - CreateDataSource = () => - { - var dataSource = new TUnit.Core.ClassDataSourceAttribute(); - dataSource.Shared = (TUnit.Core.SharedType)3; - return dataSource; - }, - SetProperty = (instance, value) => - { - var typedInstance = (global::TUnit.TestProject.GenericFixtureBase)instance; -#if NET8_0_OR_GREATER - GetPostgresBackingField((TUnit.TestProject.GenericFixtureBase)typedInstance) = (global::TUnit.TestProject.InMemoryDatabase)value; -#else - var backingField = typeof(TUnit.TestProject.GenericFixtureBase).GetField("k__BackingField", - global::System.Reflection.BindingFlags.Instance | global::System.Reflection.BindingFlags.NonPublic); - backingField.SetValue(typedInstance, value); -#endif - } - }; - - } -} - - -// ===== FILE SEPARATOR ===== - -using System; -using TUnit.Core.Discovery; - -namespace TUnit.Generated; - -internal static class TUnit_TestProject_GenericInitializerFixture_TUnit_TestProject_GenericInitializerPropertyTests__Generic_InitializerPropertiesInitializer -{ - [global::System.Runtime.CompilerServices.ModuleInitializer] - public static void Initialize() - { - InitializerPropertyRegistry.Register(typeof(global::TUnit.TestProject.GenericInitializerFixture), new InitializerPropertyInfo[] - { - new InitializerPropertyInfo - { - PropertyName = "Database", - PropertyType = typeof(global::TUnit.TestProject.InMemoryDatabase), - GetValue = static obj => ((global::TUnit.TestProject.GenericInitializerFixture)obj).Database - }, - }); - } -} diff --git a/TUnit.Core/ExecutableTest`1.cs b/TUnit.Core/ExecutableTest`1.cs index 69bf3b1d40..8b1c022281 100644 --- a/TUnit.Core/ExecutableTest`1.cs +++ b/TUnit.Core/ExecutableTest`1.cs @@ -1,4 +1,3 @@ -using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using TUnit.Core.Helpers; @@ -42,10 +41,15 @@ public override async Task CreateInstanceAsync() var attributes = _metadata.GetOrCreateAttributes(); // TestSessionId defaults to string.Empty for allocation reasons — callers in the - // engine must overwrite it before reaching test-variant generation. Assert here - // rather than guarding every write site. - Debug.Assert(!string.IsNullOrEmpty(_metadata.TestSessionId), - $"TestSessionId must be assigned before creating a test instance for {_metadata.TestName}"); + // engine must overwrite it before reaching test-variant generation. This is the + // primary consumer, so upgrade from Debug.Assert to a release-mode guard: any caller + // reaching here without assigning a session id indicates an engine bug, and silently + // propagating an empty string into data-generation code would poison partition keys. + if (string.IsNullOrEmpty(_metadata.TestSessionId)) + { + throw new InvalidOperationException( + $"TestSessionId was not assigned before creating a test instance for {_metadata.TestName}. This is a TUnit engine bug."); + } var instance = await ClassConstructorHelper.TryCreateInstanceWithClassConstructor( attributes, _metadata.TestClassType, diff --git a/TUnit.Core/Interfaces/SourceGenerator/PropertyInjectionMetadata.cs b/TUnit.Core/Interfaces/SourceGenerator/PropertyInjectionMetadata.cs index 42b8d0b4b7..477c21b916 100644 --- a/TUnit.Core/Interfaces/SourceGenerator/PropertyInjectionMetadata.cs +++ b/TUnit.Core/Interfaces/SourceGenerator/PropertyInjectionMetadata.cs @@ -92,7 +92,7 @@ public sealed class PropertyInjectionMetadata var property = ContainingType.GetProperty(PropertyName); var computed = property is null || !property.CanRead ? s_notReadableSentinel - : property.GetValue; + : (Func)(obj => property.GetValue(obj)); // Benign race: both racers compute equivalent delegates; CompareExchange makes the // winner visible to any subsequent reader without a lock. diff --git a/TUnit.Core/TestMetadata`1.cs b/TUnit.Core/TestMetadata`1.cs index d8183fc15f..711a27d80e 100644 --- a/TUnit.Core/TestMetadata`1.cs +++ b/TUnit.Core/TestMetadata`1.cs @@ -67,15 +67,21 @@ public override Func?>( + ref _cachedExecutableTestFactory, CreateTypedExecutableTest, null); + return _cachedExecutableTestFactory!; } throw new InvalidOperationException($"InstanceFactory and InvokeTypedTest must be set for {typeof(T).Name}"); diff --git a/TUnit.Engine/Helpers/ValueTaskBridge.cs b/TUnit.Engine/Helpers/ValueTaskBridge.cs index 228931eeac..ce9f796577 100644 --- a/TUnit.Engine/Helpers/ValueTaskBridge.cs +++ b/TUnit.Engine/Helpers/ValueTaskBridge.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using System.Reflection; namespace TUnit.Engine.Helpers; @@ -41,8 +42,31 @@ public static Task ToTask(ValueTask valueTask) /// /// Pre-resolved generic method definition for . /// Callers invoke on this instance per element type. + /// On .NET 8+ uses the typed + /// overload so a future ToTask overload cannot silently match; on netstandard2.0 + /// (which lacks that overload and ) + /// falls back to a name-scan that uses + /// so an accidental duplicate match throws instead of silently picking one. /// - internal static readonly MethodInfo ToTaskGenericMethodDefinition = - typeof(ValueTaskBridge).GetMethods() - .First(m => m.Name == nameof(ToTask) && m.IsGenericMethodDefinition); + internal static readonly MethodInfo ToTaskGenericMethodDefinition = ResolveToTaskGenericMethodDefinition(); + +#if NET8_0_OR_GREATER + [UnconditionalSuppressMessage("AOT", "IL3050", + Justification = "MakeGenericType is called on ValueTask<> with a generic method parameter placeholder at startup to find the MethodInfo for ToTask; the shared generic-type vtable is always available, and the resolved MethodInfo is then instantiated per-element-type in the same expression tree paths that already require dynamic code (AOT paths use direct delegates).")] +#endif + private static MethodInfo ResolveToTaskGenericMethodDefinition() + { +#if NET8_0_OR_GREATER + return typeof(ValueTaskBridge).GetMethod( + name: nameof(ToTask), + genericParameterCount: 1, + bindingAttr: BindingFlags.Public | BindingFlags.Static, + binder: null, + types: [typeof(ValueTask<>).MakeGenericType(Type.MakeGenericMethodParameter(0))], + modifiers: null)!; +#else + return typeof(ValueTaskBridge).GetMethods(BindingFlags.Public | BindingFlags.Static) + .Single(m => m.Name == nameof(ToTask) && m.IsGenericMethodDefinition); +#endif + } }