Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,23 @@ private static ImmutableArray<ConcreteGenericTypeModel> ExtractConcreteGenericTy
// Check constructor arguments for type parameters
foreach (var ctorArg in attr.ConstructorArguments)
{
// Handle arrays - iterate over values to find concrete generic types
if (ctorArg.Kind == TypedConstantKind.Array)
{
foreach (var arrayElement in ctorArg.Values)
{
if (arrayElement.Value is INamedTypeSymbol elementType && IsConcreteGenericType(elementType))
{
var model = CreateConcreteGenericModel(elementType, dataSourceInterface, asyncInitializerInterface);
if (model != null)
{
results.Add(model);
}
}
}
continue;
}

if (ctorArg.Value is INamedTypeSymbol argType && IsConcreteGenericType(argType))
{
var model = CreateConcreteGenericModel(argType, dataSourceInterface, asyncInitializerInterface);
Expand Down
6 changes: 4 additions & 2 deletions TUnit.Engine/Building/TestBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,10 @@ private static async Task InitializeClassDataAsync(object?[] classData)

private async Task<object> CreateInstance(TestMetadata metadata, Type[] resolvedClassGenericArgs, object?[] classData, TestBuilderContext builderContext)
{
// Initialize any deferred IAsyncInitializer objects in class data
await InitializeClassDataAsync(classData);
foreach (var data in classData)
{
await _objectLifecycleService.InitializeObjectForExecutionAsync(data);
}

// First try to create instance with ClassConstructor attribute
// Use attributes from context if available
Expand Down
15 changes: 15 additions & 0 deletions TUnit.Engine/Services/ObjectLifecycleService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,21 @@ public Task InitializeTestObjectsAsync(TestContext testContext, CancellationToke
return InitializeTrackedObjectsAsync(testContext, cancellationToken);
}

/// <summary>
/// Initializes an object and its nested IAsyncInitializer objects for execution.
/// Used to initialize data source objects before they are passed to the test constructor.
/// </summary>
public async Task InitializeObjectForExecutionAsync(object? obj, CancellationToken cancellationToken = default)
{
if (obj is null)
{
return;
}

await InitializeNestedObjectsForExecutionAsync(obj, cancellationToken);
await ObjectInitializer.InitializeAsync(obj, cancellationToken);
}

/// <summary>
/// Sets already-cached property values on a test class instance.
/// This is used to apply cached property values to new instances created during retries.
Expand Down
Loading
Loading