diff --git a/TUnit.Engine/Services/MetadataFilterMatcher.cs b/TUnit.Engine/Services/MetadataFilterMatcher.cs index 28ee3729e7..9d22850128 100644 --- a/TUnit.Engine/Services/MetadataFilterMatcher.cs +++ b/TUnit.Engine/Services/MetadataFilterMatcher.cs @@ -1,6 +1,7 @@ using System.Collections.Concurrent; using System.Diagnostics.CodeAnalysis; using System.Reflection; +using System.Text.RegularExpressions; #if NET8_0_OR_GREATER using System.Buffers; #endif @@ -117,7 +118,7 @@ public bool CouldMatch(string testClassName, string testMethodName) /// Implementation of metadata filter matching logic extracted from TestBuilder. /// Evaluates if test metadata could match an execution filter without building tests. /// -internal sealed class MetadataFilterMatcher : IMetadataFilterMatcher +internal sealed partial class MetadataFilterMatcher : IMetadataFilterMatcher { #pragma warning disable TPEXP private static readonly ConstructorInfo _treeNodeFilterConstructor = @@ -129,6 +130,16 @@ internal sealed class MetadataFilterMatcher : IMetadataFilterMatcher private static readonly ConcurrentDictionary _strippedFilterCache = new(); + // Matches property-bag filters like [key=value]; used to strip them before path parsing. +#if NET8_0_OR_GREATER + [GeneratedRegex(@"\[[^\]]*\]")] + private static partial Regex PropertyFilterRegex(); +#else + private static readonly Regex _propertyFilterRegex = new(@"\[[^\]]*\]", RegexOptions.Compiled); + + private static Regex PropertyFilterRegex() => _propertyFilterRegex; +#endif + /// /// Extract hints from a filter that can be used to pre-filter test sources by type. /// @@ -149,7 +160,7 @@ public static FilterHints ExtractFilterHints(ITestExecutionFilter? filter) // Strip property filters like [key=value] if (filterString.Contains('[')) { - filterString = System.Text.RegularExpressions.Regex.Replace(filterString, @"\[([^\]]*)\]", ""); + filterString = PropertyFilterRegex().Replace(filterString, ""); } // Parse path: /{assembly}/{namespace}/{className}/{methodName} @@ -407,7 +418,7 @@ private static bool CouldMatchTreeNodeFilter(TreeNodeFilter filter, TestMetadata if (filterString.Contains('[')) { var strippedFilterString = _strippedFilterCache.GetOrAdd(filterString, - static fs => System.Text.RegularExpressions.Regex.Replace(fs, @"\[([^\]]*)\]", "")); + static fs => PropertyFilterRegex().Replace(fs, "")); pathOnlyFilter = CreateTreeNodeFilterViaReflection(strippedFilterString); } else