From 06b1ded9f48c594d59553e897c7be303406ea06a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20M=C3=BCller?= Date: Mon, 6 Jan 2025 23:57:42 +0100 Subject: [PATCH 1/5] first tests --- .../Helpers/InstrumentationHelper.cs | 22 ++++++++++++++++++- .../Helpers/InstrumentationHelperTests.cs | 13 +++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/src/coverlet.core/Helpers/InstrumentationHelper.cs b/src/coverlet.core/Helpers/InstrumentationHelper.cs index 82b66056b..4aecb60d4 100644 --- a/src/coverlet.core/Helpers/InstrumentationHelper.cs +++ b/src/coverlet.core/Helpers/InstrumentationHelper.cs @@ -367,7 +367,27 @@ private string GetModuleKeysForExcludeFilters(IEnumerable filters, char { string[] validFilters = GetValidFilters(filters); - return !validFilters.Any() ? string.Empty : GetModuleKeysForValidFilters(escapeSymbol, moduleKeys, validFilters); + + //return !validFilters.Any() ? string.Empty : GetModuleKeysForValidFilters(escapeSymbol, moduleKeys, validFilters); + return !validFilters.Any() ? string.Empty : GetExcludeModuleKeysForValidFilters(escapeSymbol, moduleKeys, validFilters); + } + + private static string GetExcludeModuleKeysForValidFilters(char escapeSymbol, string moduleKeys, string[] validFilters) + { + string pattern = CreateRegexExcludePattern(validFilters, escapeSymbol); + IEnumerable matches = Regex.Matches(moduleKeys, pattern, RegexOptions.IgnoreCase).Cast(); + + return string.Join( + Environment.NewLine, + matches.Where(x => x.Success).Select(x => x.Groups[0].Value)); + } + + private static string CreateRegexExcludePattern(IEnumerable filters, char escapeSymbol) + { + var filteredFilters = filters.Where(filter => filter.Substring(filter.IndexOf(']') + 1) == "*") ; + IEnumerable regexPatterns = filteredFilters.Select(x => + $"{escapeSymbol}{WildcardToRegex(x.Substring(1, x.IndexOf(']') - 1)).Trim('^', '$')}{escapeSymbol}"); + return string.Join("|", regexPatterns); } private static string GetModuleKeysForValidFilters(char escapeSymbol, string moduleKeys, string[] validFilters) diff --git a/test/coverlet.core.tests/Helpers/InstrumentationHelperTests.cs b/test/coverlet.core.tests/Helpers/InstrumentationHelperTests.cs index 557835806..eb87f61fb 100644 --- a/test/coverlet.core.tests/Helpers/InstrumentationHelperTests.cs +++ b/test/coverlet.core.tests/Helpers/InstrumentationHelperTests.cs @@ -198,6 +198,18 @@ public void TestIsModuleExcludedAndIncludedWithMatchingAndMismatchingFilter(stri Assert.Empty(result); } + [Fact] + public void TestIsModuleExcludedAndIncludedWithMatchingAndMismatchingFilter2() + { + string[] modules = new[] { "ClassLibrary1", "ClassLibrary1.Tests" }; + string[] includeFilters = new[] { "[*]ClassLibrary1*" }; + string[] excludeFilters = new[] { "[*]ClassLibrary1.Tests.*" }; + + IEnumerable result = _instrumentationHelper.SelectModules(modules, includeFilters, excludeFilters); + + Assert.Empty(result); + } + [Fact] public void TestIsTypeExcludedWithoutFilter() { @@ -326,6 +338,7 @@ public void InstrumentationHelper_IsLocalMethod_ReturnsExpectedResult(string met new object[] { "[Mod*le*]*" }, new object[] { "[Module?]*" }, new object[] { "[ModuleX?]*" }, + new object[] { "[*]*" } }; public static IEnumerable ValidModuleAndNamespaceFilterData => From 13af8e390b242189442bfba6fd4db2fe675caa12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20M=C3=BCller?= Date: Fri, 10 Jan 2025 00:37:58 +0100 Subject: [PATCH 2/5] some more test + refactoring --- .../Helpers/InstrumentationHelper.cs | 28 +++++++++---------- .../Helpers/InstrumentationHelperTests.cs | 14 +++++++++- 2 files changed, 26 insertions(+), 16 deletions(-) diff --git a/src/coverlet.core/Helpers/InstrumentationHelper.cs b/src/coverlet.core/Helpers/InstrumentationHelper.cs index 4aecb60d4..128f82f46 100644 --- a/src/coverlet.core/Helpers/InstrumentationHelper.cs +++ b/src/coverlet.core/Helpers/InstrumentationHelper.cs @@ -360,18 +360,24 @@ private string GetModuleKeysForIncludeFilters(IEnumerable filters, char { string[] validFilters = GetValidFilters(filters); - return !validFilters.Any() ? moduleKeys : GetModuleKeysForValidFilters(escapeSymbol, moduleKeys, validFilters); + return !validFilters.Any() ? moduleKeys : GetIncludeModuleKeysForValidFilters(escapeSymbol, moduleKeys, validFilters); } private string GetModuleKeysForExcludeFilters(IEnumerable filters, char escapeSymbol, string moduleKeys) { string[] validFilters = GetValidFilters(filters); - - //return !validFilters.Any() ? string.Empty : GetModuleKeysForValidFilters(escapeSymbol, moduleKeys, validFilters); return !validFilters.Any() ? string.Empty : GetExcludeModuleKeysForValidFilters(escapeSymbol, moduleKeys, validFilters); } + private string[] GetValidFilters(IEnumerable filters) + { + return (filters ?? Array.Empty()) + .Where(IsValidFilterExpression) + .Where(x => x.EndsWith("*")) + .ToArray(); + } + private static string GetExcludeModuleKeysForValidFilters(char escapeSymbol, string moduleKeys, string[] validFilters) { string pattern = CreateRegexExcludePattern(validFilters, escapeSymbol); @@ -384,15 +390,15 @@ private static string GetExcludeModuleKeysForValidFilters(char escapeSymbol, str private static string CreateRegexExcludePattern(IEnumerable filters, char escapeSymbol) { - var filteredFilters = filters.Where(filter => filter.Substring(filter.IndexOf(']') + 1) == "*") ; + IEnumerable filteredFilters = filters.Where(filter => filter.Substring(filter.IndexOf(']') + 1) == "*") ; IEnumerable regexPatterns = filteredFilters.Select(x => $"{escapeSymbol}{WildcardToRegex(x.Substring(1, x.IndexOf(']') - 1)).Trim('^', '$')}{escapeSymbol}"); return string.Join("|", regexPatterns); } - private static string GetModuleKeysForValidFilters(char escapeSymbol, string moduleKeys, string[] validFilters) + private static string GetIncludeModuleKeysForValidFilters(char escapeSymbol, string moduleKeys, string[] validFilters) { - string pattern = CreateRegexPattern(validFilters, escapeSymbol); + string pattern = CreateRegexIncludePattern(validFilters, escapeSymbol); IEnumerable matches = Regex.Matches(moduleKeys, pattern, RegexOptions.IgnoreCase).Cast(); return string.Join( @@ -400,15 +406,7 @@ private static string GetModuleKeysForValidFilters(char escapeSymbol, string mod matches.Where(x => x.Success).Select(x => x.Groups[0].Value)); } - private string[] GetValidFilters(IEnumerable filters) - { - return (filters ?? Array.Empty()) - .Where(IsValidFilterExpression) - .Where(x => x.EndsWith("*")) - .ToArray(); - } - - private static string CreateRegexPattern(IEnumerable filters, char escapeSymbol) + private static string CreateRegexIncludePattern(IEnumerable filters, char escapeSymbol) { IEnumerable regexPatterns = filters.Select(x => $"{escapeSymbol}{WildcardToRegex(x.Substring(1, x.IndexOf(']') - 1)).Trim('^', '$')}{escapeSymbol}"); diff --git a/test/coverlet.core.tests/Helpers/InstrumentationHelperTests.cs b/test/coverlet.core.tests/Helpers/InstrumentationHelperTests.cs index eb87f61fb..bd58e8705 100644 --- a/test/coverlet.core.tests/Helpers/InstrumentationHelperTests.cs +++ b/test/coverlet.core.tests/Helpers/InstrumentationHelperTests.cs @@ -207,7 +207,19 @@ public void TestIsModuleExcludedAndIncludedWithMatchingAndMismatchingFilter2() IEnumerable result = _instrumentationHelper.SelectModules(modules, includeFilters, excludeFilters); - Assert.Empty(result); + Assert.Equal(["ClassLibrary1", "ClassLibrary1.Tests"], result); + } + + [Fact] + public void TestIsModuleExcludedAndIncludedWithMatchingAndMismatchingFilter3() + { + string[] modules = new[] { "A", "A.Tests", "B", "B.Test.SuperTest.cs" }; + string[] includeFilters = new[] { "" }; + string[] excludeFilters = new[] { "[A*]*" }; + + IEnumerable result = _instrumentationHelper.SelectModules(modules, includeFilters, excludeFilters); + + Assert.Equal(["B", "B.Test.SuperTest.cs"], result); } [Fact] From 989d8cf3449b1f447f396aa12b77aa75287a4145 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20M=C3=BCller?= Date: Mon, 13 Jan 2025 00:23:10 +0100 Subject: [PATCH 3/5] update new unit tests --- .../Helpers/InstrumentationHelperTests.cs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/test/coverlet.core.tests/Helpers/InstrumentationHelperTests.cs b/test/coverlet.core.tests/Helpers/InstrumentationHelperTests.cs index bd58e8705..5a433ee91 100644 --- a/test/coverlet.core.tests/Helpers/InstrumentationHelperTests.cs +++ b/test/coverlet.core.tests/Helpers/InstrumentationHelperTests.cs @@ -199,27 +199,27 @@ public void TestIsModuleExcludedAndIncludedWithMatchingAndMismatchingFilter(stri } [Fact] - public void TestIsModuleExcludedAndIncludedWithMatchingAndMismatchingFilter2() + public void TestIsModuleExcludedAndIncludedWithAnyModuleFilters() { - string[] modules = new[] { "ClassLibrary1", "ClassLibrary1.Tests" }; - string[] includeFilters = new[] { "[*]ClassLibrary1*" }; - string[] excludeFilters = new[] { "[*]ClassLibrary1.Tests.*" }; + string[] modules = new[] { "Module.dll", "Module.Tests.dll" }; + string[] includeFilters = new[] { "[*]Module*" }; + string[] excludeFilters = new[] { "[*]Module.Tests.*" }; IEnumerable result = _instrumentationHelper.SelectModules(modules, includeFilters, excludeFilters); - Assert.Equal(["ClassLibrary1", "ClassLibrary1.Tests"], result); + Assert.Equal(modules, result); } [Fact] - public void TestIsModuleExcludedAndIncludedWithMatchingAndMismatchingFilter3() + public void TestAreModulesExcludedWithAnyModuleFilters() { - string[] modules = new[] { "A", "A.Tests", "B", "B.Test.SuperTest.cs" }; + string[] modules = new[] { "ModuleA.dll", "ModuleA.Tests.dll", "ModuleB.dll", "Module.B.Tests.dll" }; string[] includeFilters = new[] { "" }; - string[] excludeFilters = new[] { "[A*]*" }; + string[] excludeFilters = new[] { "[ModuleA*]*" }; IEnumerable result = _instrumentationHelper.SelectModules(modules, includeFilters, excludeFilters); - Assert.Equal(["B", "B.Test.SuperTest.cs"], result); + Assert.Equal(["ModuleB.dll", "Module.B.Tests.dll"], result); } [Fact] From b5c48af950f60ed31f7a24f83b659ae43f5e9df4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20M=C3=BCller?= Date: Mon, 13 Jan 2025 22:56:39 +0100 Subject: [PATCH 4/5] refactoring --- .../Helpers/InstrumentationHelper.cs | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/coverlet.core/Helpers/InstrumentationHelper.cs b/src/coverlet.core/Helpers/InstrumentationHelper.cs index 128f82f46..7ae12972e 100644 --- a/src/coverlet.core/Helpers/InstrumentationHelper.cs +++ b/src/coverlet.core/Helpers/InstrumentationHelper.cs @@ -388,14 +388,6 @@ private static string GetExcludeModuleKeysForValidFilters(char escapeSymbol, str matches.Where(x => x.Success).Select(x => x.Groups[0].Value)); } - private static string CreateRegexExcludePattern(IEnumerable filters, char escapeSymbol) - { - IEnumerable filteredFilters = filters.Where(filter => filter.Substring(filter.IndexOf(']') + 1) == "*") ; - IEnumerable regexPatterns = filteredFilters.Select(x => - $"{escapeSymbol}{WildcardToRegex(x.Substring(1, x.IndexOf(']') - 1)).Trim('^', '$')}{escapeSymbol}"); - return string.Join("|", regexPatterns); - } - private static string GetIncludeModuleKeysForValidFilters(char escapeSymbol, string moduleKeys, string[] validFilters) { string pattern = CreateRegexIncludePattern(validFilters, escapeSymbol); @@ -406,10 +398,18 @@ private static string GetIncludeModuleKeysForValidFilters(char escapeSymbol, str matches.Where(x => x.Success).Select(x => x.Groups[0].Value)); } - private static string CreateRegexIncludePattern(IEnumerable filters, char escapeSymbol) + private static string CreateRegexExcludePattern(IEnumerable filters, char escapeSymbol) + //only look for module filters here, types will be filtered out when instrumenting + => CreateRegexPattern(filters, escapeSymbol, filter => filter.Substring(filter.IndexOf(']') + 1) == "*"); + + private static string CreateRegexIncludePattern(IEnumerable filters, char escapeSymbol) => + CreateRegexPattern(filters, escapeSymbol); + + private static string CreateRegexPattern(IEnumerable filters, char escapeSymbol, Func filterPredicate = null) { - IEnumerable regexPatterns = filters.Select(x => - $"{escapeSymbol}{WildcardToRegex(x.Substring(1, x.IndexOf(']') - 1)).Trim('^', '$')}{escapeSymbol}"); + IEnumerable filteredFilters = filterPredicate != null ? filters.Where(filterPredicate) : filters; + IEnumerable regexPatterns = filteredFilters.Select(x => + $"{escapeSymbol}{WildcardToRegex(x.Substring(1, x.IndexOf(']') - 1)).Trim('^', '$')}{escapeSymbol}"); return string.Join("|", regexPatterns); } From 3c56c969efc08bea1e691e351a13029a7a10f9ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20M=C3=BCller?= Date: Tue, 14 Jan 2025 00:06:22 +0100 Subject: [PATCH 5/5] test --- .../coverlet.core.tests/Helpers/InstrumentationHelperTests.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/coverlet.core.tests/Helpers/InstrumentationHelperTests.cs b/test/coverlet.core.tests/Helpers/InstrumentationHelperTests.cs index 5a433ee91..fe2d9c7c7 100644 --- a/test/coverlet.core.tests/Helpers/InstrumentationHelperTests.cs +++ b/test/coverlet.core.tests/Helpers/InstrumentationHelperTests.cs @@ -199,7 +199,7 @@ public void TestIsModuleExcludedAndIncludedWithMatchingAndMismatchingFilter(stri } [Fact] - public void TestIsModuleExcludedAndIncludedWithAnyModuleFilters() + public void TestSelectModulesWithTypeFiltersDoesNotExcludeAssemblyWithType() { string[] modules = new[] { "Module.dll", "Module.Tests.dll" }; string[] includeFilters = new[] { "[*]Module*" }; @@ -211,7 +211,7 @@ public void TestIsModuleExcludedAndIncludedWithAnyModuleFilters() } [Fact] - public void TestAreModulesExcludedWithAnyModuleFilters() + public void TestSelectModulesWithModuleFilterExcludesExpectedModules() { string[] modules = new[] { "ModuleA.dll", "ModuleA.Tests.dll", "ModuleB.dll", "Module.B.Tests.dll" }; string[] includeFilters = new[] { "" };