diff --git a/TUnit.Core/Attributes/TestData/MatrixDataSourceAttribute.cs b/TUnit.Core/Attributes/TestData/MatrixDataSourceAttribute.cs index 18abcc9d44..ef6a40bdc8 100644 --- a/TUnit.Core/Attributes/TestData/MatrixDataSourceAttribute.cs +++ b/TUnit.Core/Attributes/TestData/MatrixDataSourceAttribute.cs @@ -66,12 +66,17 @@ private bool IsExcluded(object?[] exclusion, IEnumerable row) var exclusionValue = exclusion[i]; var rowValue = rowArray[i]; - // Handle enum to underlying type conversion - if (exclusionValue != null && exclusionValue.GetType().IsEnum && rowValue != null) + // Handle enum to underlying type conversion for both values + if (exclusionValue != null && exclusionValue.GetType().IsEnum) { exclusionValue = Convert.ChangeType(exclusionValue, Enum.GetUnderlyingType(exclusionValue.GetType())); } + if (rowValue != null && rowValue.GetType().IsEnum) + { + rowValue = Convert.ChangeType(rowValue, Enum.GetUnderlyingType(rowValue.GetType())); + } + if (!Equals(exclusionValue, rowValue)) { return false; diff --git a/TUnit.TestProject/MatrixExclusionBugTest.cs b/TUnit.TestProject/MatrixExclusionBugTest.cs index 9e08406fe0..3921cb0edf 100644 --- a/TUnit.TestProject/MatrixExclusionBugTest.cs +++ b/TUnit.TestProject/MatrixExclusionBugTest.cs @@ -32,18 +32,65 @@ public async Task Should_Filter_By_Status(Status status) } await Task.CompletedTask; } - + [Test] [MatrixDataSource] [MatrixExclusion(Status.Draft)] // This should work with the base attribute public async Task Should_Filter_By_Status_Base(Status status) { // Should generate 4 tests (all statuses except Draft) - // If this test runs with Status.Draft, the bug is NOT fixed + // If this test runs with Status.Draft, the bug is NOT fixed if (status == Status.Draft) { throw new InvalidOperationException("Draft status should have been excluded but was not!"); } await Task.CompletedTask; } + + // Issue #3320: Test Matrix attribute with explicit enum values + MatrixExclusion + [Test] + [MatrixDataSource] + [MatrixExclusion(Status.Draft)] + public async Task Matrix_With_Explicit_Enums_Should_Respect_Exclusion( + [Matrix(Status.Draft, Status.Pending, Status.Published)] Status status) + { + // Should generate 2 tests (Pending and Published only, Draft is excluded) + await Assert.That(status).IsNotEqualTo(Status.Draft); + } + + // Issue #3320: Test with multiple enum parameters and exclusion + [Test] + [MatrixDataSource] + [MatrixExclusion(Status.Draft, Status.Pending)] + public async Task Multiple_Enum_Matrix_With_Exclusion( + [Matrix(Status.Draft, Status.Published)] Status status1, + [Matrix(Status.Pending, Status.Archived)] Status status2) + { + // Should exclude (Draft, Pending) combination + // Should generate 3 tests: (Draft,Archived), (Published,Pending), (Published,Archived) + await Assert.That((status1, status2)).IsNotEqualTo((Status.Draft, Status.Pending)); + } + + // Issue #3320: Test with int cast exclusion (this was already working) + [Test] + [MatrixDataSource] + [MatrixExclusion((int)Status.Draft)] + public async Task Matrix_Enum_With_Int_Exclusion( + [Matrix(Status.Draft, Status.Pending, Status.Published)] Status status) + { + // Should generate 2 tests (Pending and Published only) + await Assert.That(status).IsNotEqualTo(Status.Draft); + } + + // Issue #3320: Test mixing auto-generated and explicit Matrix enums + [Test] + [MatrixDataSource] + [MatrixExclusion(Status.Draft, Status.Pending)] + public async Task Mixed_Auto_And_Explicit_Matrix_Enums( + Status autoGenerated, + [Matrix(Status.Pending, Status.Published)] Status explicitMatrix) + { + // Should exclude (Draft, Pending) combination + await Assert.That((autoGenerated, explicitMatrix)).IsNotEqualTo((Status.Draft, Status.Pending)); + } } \ No newline at end of file