diff --git a/src/Readme.txt b/src/Readme.txt
index 0da1dc5e..56ad9a4b 100644
--- a/src/Readme.txt
+++ b/src/Readme.txt
@@ -67,10 +67,11 @@ For further details take a look at LICENSE.txt.
CHANGELOG
-5.3.12.0
+5.4.0.0
* Fix: #699 Rounding crap score to full number
* Fix: #700 Fixed handling of .netconfig files (sourceDirectories, reportTypes, plugins, assemblyFilters, etc.)
+ * Fix: #704 Improved handling of file filters
5.3.11.0
diff --git a/src/ReportGenerator.Core.Test/Parser/Filtering/DefaultFilterTest.cs b/src/ReportGenerator.Core.Test/Parser/Filtering/DefaultFilterTest.cs
index 71002e5d..5e63d9cd 100644
--- a/src/ReportGenerator.Core.Test/Parser/Filtering/DefaultFilterTest.cs
+++ b/src/ReportGenerator.Core.Test/Parser/Filtering/DefaultFilterTest.cs
@@ -56,10 +56,10 @@ public void OnlyIncludesWithWildcards_NotMatchingElement_ElementIsNotAccepted()
{
IFilter filter = new DefaultFilter(new[] { "+Test*" });
- Assert.False(filter.IsElementIncludedInReport("PrefixTest"), "Element is expected to be included.");
- Assert.False(filter.IsElementIncludedInReport("prefixtest"), "Element is expected to be included.");
- Assert.False(filter.IsElementIncludedInReport("PrefixTest123"), "Element is expected to be included.");
- Assert.False(filter.IsElementIncludedInReport("prefixtest123"), "Element is expected to be included.");
+ Assert.False(filter.IsElementIncludedInReport("PrefixTest"), "Element is expected to be excluded.");
+ Assert.False(filter.IsElementIncludedInReport("prefixtest"), "Element is expected to be excluded.");
+ Assert.False(filter.IsElementIncludedInReport("PrefixTest123"), "Element is expected to be excluded.");
+ Assert.False(filter.IsElementIncludedInReport("prefixtest123"), "Element is expected to be excluded.");
Assert.True(filter.HasCustomFilters);
}
@@ -100,10 +100,50 @@ public void IncludesAndExcludesWithWildcards_NotMatchingElement_ElementIsNotAcce
{
IFilter filter = new DefaultFilter(new[] { "+Test*", "-Tes*" });
- Assert.False(filter.IsElementIncludedInReport("Test"), "Element is expected to be included.");
- Assert.False(filter.IsElementIncludedInReport("test"), "Element is expected to be included.");
- Assert.False(filter.IsElementIncludedInReport("PrefixTest123"), "Element is expected to be included.");
- Assert.False(filter.IsElementIncludedInReport("prefixtest123"), "Element is expected to be included.");
+ Assert.False(filter.IsElementIncludedInReport("Test"), "Element is expected to be excluded.");
+ Assert.False(filter.IsElementIncludedInReport("test"), "Element is expected to be excluded.");
+ Assert.False(filter.IsElementIncludedInReport("PrefixTest123"), "Element is expected to be excluded.");
+ Assert.False(filter.IsElementIncludedInReport("prefixtest123"), "Element is expected to be excluded.");
+ Assert.True(filter.HasCustomFilters);
+ }
+
+ [Fact]
+ public void LinuxPath_NoOsIndependantPathSeparator()
+ {
+ IFilter filter = new DefaultFilter(new[] { "+abc/def" });
+
+ Assert.True(filter.IsElementIncludedInReport("abc/def"), "Element is expected to be included.");
+ Assert.False(filter.IsElementIncludedInReport("abc\\def"), "Element is expected to be excluded.");
+ Assert.True(filter.HasCustomFilters);
+ }
+
+ [Fact]
+ public void LinuxPath_OsIndependantPathSeparator()
+ {
+ IFilter filter = new DefaultFilter(new[] { "+abc/def" }, true);
+
+ Assert.True(filter.IsElementIncludedInReport("abc/def"), "Element is expected to be included.");
+ Assert.True(filter.IsElementIncludedInReport("abc\\def"), "Element is expected to be included.");
+ Assert.True(filter.HasCustomFilters);
+ }
+
+ [Fact]
+ public void WindowsPath_NoOsIndependantPathSeparator()
+ {
+ IFilter filter = new DefaultFilter(new[] { "+abc\\def" });
+
+ Assert.False(filter.IsElementIncludedInReport("abc/def"), "Element is expected to be excluded.");
+ Assert.True(filter.IsElementIncludedInReport("abc\\def"), "Element is expected to be included.");
+ Assert.True(filter.HasCustomFilters);
+ }
+
+ [Fact]
+ public void WindowsPath_OsIndependantPathSeparator()
+ {
+ IFilter filter = new DefaultFilter(new[] { "+abc/def" }, true);
+
+ Assert.True(filter.IsElementIncludedInReport("abc/def"), "Element is expected to be included.");
+ Assert.True(filter.IsElementIncludedInReport("abc\\def"), "Element is expected to be included.");
Assert.True(filter.HasCustomFilters);
}
}
diff --git a/src/ReportGenerator.Core/Parser/CoverageReportParser.cs b/src/ReportGenerator.Core/Parser/CoverageReportParser.cs
index 4f848055..a69f76e6 100644
--- a/src/ReportGenerator.Core/Parser/CoverageReportParser.cs
+++ b/src/ReportGenerator.Core/Parser/CoverageReportParser.cs
@@ -181,7 +181,7 @@ public CoverageReportParser(IReportContext reportContext)
this.sourceDirectories = reportContext.ReportConfiguration.SourceDirectories ?? throw new ArgumentNullException(nameof(reportContext.ReportConfiguration.SourceDirectories));
this.assemblyFilter = new DefaultFilter(reportContext.ReportConfiguration.AssemblyFilters);
this.classFilter = new DefaultFilter(reportContext.ReportConfiguration.ClassFilters);
- this.fileFilter = new DefaultFilter(reportContext.ReportConfiguration.FileFilters);
+ this.fileFilter = new DefaultFilter(reportContext.ReportConfiguration.FileFilters, true);
}
///
diff --git a/src/ReportGenerator.Core/Parser/Filtering/DefaultFilter.cs b/src/ReportGenerator.Core/Parser/Filtering/DefaultFilter.cs
index 045f0339..c6823d69 100644
--- a/src/ReportGenerator.Core/Parser/Filtering/DefaultFilter.cs
+++ b/src/ReportGenerator.Core/Parser/Filtering/DefaultFilter.cs
@@ -28,6 +28,16 @@ public class DefaultFilter : IFilter
///
/// The filters.
public DefaultFilter(IEnumerable filters)
+ : this(filters, false)
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The filters.
+ /// Indicates whether filter thould be treated as paths and the operating system format should be ignored.
+ public DefaultFilter(IEnumerable filters, bool osIndependantPathSeparator)
{
if (filters == null)
{
@@ -36,12 +46,12 @@ public DefaultFilter(IEnumerable filters)
this.excludeFilters = filters
.Where(f => f.StartsWith("-", StringComparison.OrdinalIgnoreCase))
- .Select(f => CreateFilterRegex(f))
+ .Select(f => CreateFilterRegex(f, osIndependantPathSeparator))
.ToArray();
this.includeFilters = filters
.Where(f => f.StartsWith("+", StringComparison.OrdinalIgnoreCase))
- .Select(f => CreateFilterRegex(f))
+ .Select(f => CreateFilterRegex(f, osIndependantPathSeparator))
.ToArray();
this.HasCustomFilters = this.excludeFilters.Length > 0 || this.includeFilters.Length > 0;
@@ -50,7 +60,7 @@ public DefaultFilter(IEnumerable filters)
{
this.includeFilters = new[]
{
- CreateFilterRegex("+*")
+ CreateFilterRegex("+*", false)
};
}
}
@@ -87,14 +97,23 @@ public bool IsElementIncludedInReport(string name)
/// Special characters are escaped. Wildcards '*' are converted to '.*'.
///
/// The filter.
+ /// Indicates whether filter thould be treated as paths and the operating system format should be ignored.
/// The regular expression.
- private static Regex CreateFilterRegex(string filter)
+ private static Regex CreateFilterRegex(string filter, bool osIndependantPathSeparator)
{
filter = filter.Substring(1);
filter = filter.Replace("*", "$$$*");
filter = Regex.Escape(filter);
filter = filter.Replace(@"\$\$\$\*", ".*");
+ if (osIndependantPathSeparator)
+ {
+ filter = filter
+ .Replace("/", "$$$")
+ .Replace("\\", "$$$")
+ .Replace("$$$", @"[/\\]");
+ }
+
return new Regex($"^{filter}$", RegexOptions.Compiled | RegexOptions.IgnoreCase);
}
}