Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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 @@ -81,7 +81,7 @@ namespace TUnit.Core;
/// </code>
/// </example>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public sealed class CombinedDataSourcesAttribute : AsyncUntypedDataSourceGeneratorAttribute, IAccessesInstanceData
public sealed class CombinedDataSourcesAttribute : AsyncUntypedDataSourceGeneratorAttribute
{
protected override async IAsyncEnumerable<Func<Task<object?[]?>>> GenerateDataSourcesAsync(DataGeneratorMetadata dataGeneratorMetadata)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,7 @@ namespace
public static .ClassMetadata GetOrAdd(string name, <.ClassMetadata> factory) { }
}
[(.Class | .Method)]
public sealed class CombinedDataSourcesAttribute : .AsyncUntypedDataSourceGeneratorAttribute, .IAccessesInstanceData
public sealed class CombinedDataSourcesAttribute : .AsyncUntypedDataSourceGeneratorAttribute
{
public CombinedDataSourcesAttribute() { }
[.(typeof(.CombinedDataSourcesAttribute.<GenerateDataSourcesAsync>d__0))]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,7 @@ namespace
public static .ClassMetadata GetOrAdd(string name, <.ClassMetadata> factory) { }
}
[(.Class | .Method)]
public sealed class CombinedDataSourcesAttribute : .AsyncUntypedDataSourceGeneratorAttribute, .IAccessesInstanceData
public sealed class CombinedDataSourcesAttribute : .AsyncUntypedDataSourceGeneratorAttribute
{
public CombinedDataSourcesAttribute() { }
[.(typeof(.CombinedDataSourcesAttribute.<GenerateDataSourcesAsync>d__0))]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,7 @@ namespace
public static .ClassMetadata GetOrAdd(string name, <.ClassMetadata> factory) { }
}
[(.Class | .Method)]
public sealed class CombinedDataSourcesAttribute : .AsyncUntypedDataSourceGeneratorAttribute, .IAccessesInstanceData
public sealed class CombinedDataSourcesAttribute : .AsyncUntypedDataSourceGeneratorAttribute
{
public CombinedDataSourcesAttribute() { }
[.(typeof(.CombinedDataSourcesAttribute.<GenerateDataSourcesAsync>d__0))]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,7 @@ namespace
public static .ClassMetadata GetOrAdd(string name, <.ClassMetadata> factory) { }
}
[(.Class | .Method)]
public sealed class CombinedDataSourcesAttribute : .AsyncUntypedDataSourceGeneratorAttribute, .IAccessesInstanceData
public sealed class CombinedDataSourcesAttribute : .AsyncUntypedDataSourceGeneratorAttribute
{
public CombinedDataSourcesAttribute() { }
[.(typeof(.CombinedDataSourcesAttribute.<GenerateDataSourcesAsync>d__0))]
Expand Down
133 changes: 133 additions & 0 deletions TUnit.TestProject/Bugs/3990/ClassLevelCombinedDataSourcesTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
using TUnit.TestProject.Attributes;

namespace TUnit.TestProject.Bugs._3990;

/// <summary>
/// Tests for GitHub Issue #3990: Support CombinedDataSources on Class level
/// </summary>

#region Test 1: Class-level CombinedDataSources with static Arguments

[EngineTest(ExpectedResult.Pass)]
[CombinedDataSources]
public class ClassLevelCombinedDataSources_WithStaticArguments(
[Arguments(1, 2, 3)] int x,
[Arguments("a", "b")] string y)
{
[Test]
public async Task Test_ShouldReceiveConstructorParameters()
{
// Should create 3 x 2 = 6 test cases
await Assert.That(x).IsIn([1, 2, 3]);
await Assert.That(y).IsIn(["a", "b"]);
}
}

#endregion

#region Test 2: Class-level CombinedDataSources with static MethodDataSource

public class ClassLevelDataProviders
{
public static IEnumerable<int> GetNumbers()
{
yield return 10;
yield return 20;
}

public static IEnumerable<string> GetStrings()
{
yield return "Hello";
yield return "World";
}

public static IEnumerable<string> GetColors()
{
yield return "Red";
yield return "Blue";
yield return "Green";
}
}

[EngineTest(ExpectedResult.Pass)]
[CombinedDataSources]
public class ClassLevelCombinedDataSources_WithStaticMethodDataSource(
[MethodDataSource<ClassLevelDataProviders>(nameof(ClassLevelDataProviders.GetNumbers))] int number,
[MethodDataSource<ClassLevelDataProviders>(nameof(ClassLevelDataProviders.GetStrings))] string text)
{
[Test]
public async Task Test_ShouldReceiveDataFromStaticMethods()
{
// Should create 2 x 2 = 4 test cases
await Assert.That(number).IsIn([10, 20]);
await Assert.That(text).IsIn(["Hello", "World"]);
}
}

#endregion

#region Test 3: Class-level CombinedDataSources mixed with method-level data sources

[EngineTest(ExpectedResult.Pass)]
[CombinedDataSources]
public class ClassLevelCombinedDataSources_MixedWithMethodLevel(
[Arguments(1, 2)] int classArg,
[Arguments("A", "B")] string classText)
{
[Test]
[CombinedDataSources]
public async Task Test_ShouldCombineClassAndMethodData(
[Arguments(100, 200)] int methodArg,
[Arguments("X", "Y")] string methodText)
{
// Class: 2 x 2 = 4 combinations
// Method: 2 x 2 = 4 combinations
// Total: 4 x 4 = 16 test cases
await Assert.That(classArg).IsIn([1, 2]);
await Assert.That(classText).IsIn(["A", "B"]);
await Assert.That(methodArg).IsIn([100, 200]);
await Assert.That(methodText).IsIn(["X", "Y"]);
}
}

#endregion

#region Test 4: Class-level CombinedDataSources with mixed data source types

[EngineTest(ExpectedResult.Pass)]
[CombinedDataSources]
public class ClassLevelCombinedDataSources_MixedDataSourceTypes(
[Arguments(1, 2)] int number,
[MethodDataSource<ClassLevelDataProviders>(nameof(ClassLevelDataProviders.GetColors))] string color)
{
[Test]
public async Task Test_ShouldMixArgumentsAndMethodDataSource()
{
// Should create 2 x 3 = 6 test cases
await Assert.That(number).IsIn([1, 2]);
await Assert.That(color).IsIn(["Red", "Blue", "Green"]);
}
}

#endregion

#region Test 5: Class-level CombinedDataSources with three constructor parameters

[EngineTest(ExpectedResult.Pass)]
[CombinedDataSources]
public class ClassLevelCombinedDataSources_ThreeParameters(
[Arguments(1, 2)] int x,
[Arguments("a", "b")] string y,
[Arguments(true, false)] bool z)
{
[Test]
public async Task Test_ShouldHandleThreeParameters()
{
// Should create 2 x 2 x 2 = 8 test cases
await Assert.That(x).IsIn([1, 2]);
await Assert.That(y).IsIn(["a", "b"]);
await Assert.That(z).IsIn([true, false]);
}
}

#endregion
Loading