44using System . Collections . Generic ;
55using System . ComponentModel . Composition ;
66using System . Linq ;
7+ using System . Text . RegularExpressions ;
78
89namespace FineCodeCoverage . Engine . OpenCover
910{
@@ -22,16 +23,61 @@ public static string AddEscapeQuotes(string arg)
2223 [ Export ( typeof ( IOpenCoverExeArgumentsProvider ) ) ]
2324 internal class OpenCoverExeArgumentsProvider : IOpenCoverExeArgumentsProvider
2425 {
26+ private static readonly Regex AssemblyRegex = new Regex ( @"^\[(.*?)\]" , RegexOptions . Compiled ) ;
2527 private enum Delimiter { Semicolon , Space }
28+
29+ private static bool IncludeTestAssemblyOnlyWhenNecessary (
30+ List < IReferencedProject > includedReferencedProjects ,
31+ IEnumerable < string > inclusions ,
32+ List < string > exclusions ,
33+ string testAssemblyName )
34+ {
35+ return HasInclusions ( inclusions , includedReferencedProjects ) && ! IsTestAssemblySpecificallyExcluded ( exclusions , testAssemblyName ) ;
36+ }
37+
38+ private static string GetAssemblyFromFilter ( string input )
39+ {
40+ Match match = AssemblyRegex . Match ( input ) ;
41+ return match . Success ? match . Groups [ 1 ] . Value : null ;
42+ }
43+
44+ private static bool IsTestAssemblySpecificallyExcluded ( List < string > exclusions , string testAssemblyName )
45+ {
46+ // not interested in an exclude all
47+
48+ // note that it could also have been excluded with a wild card - for now for simplicity we are not checking that
49+ foreach ( var exclusion in exclusions)
50+ {
51+ var assembly = GetAssemblyFromFilter ( exclusion ) ;
52+ if ( assembly = = testAssemblyName )
53+ {
54+ return true;
55+ }
56+ }
57+ return false;
58+ }
59+
60+ private static bool HasInclusions ( IEnumerable < string > includes , List < IReferencedProject > includedReferencedProjects )
61+ {
62+ return includes . Any ( ) || includedReferencedProjects . Any ( ) ;
63+ }
64+
65+
66+
2667 private void AddFilter ( ICoverageProject project , List < string > opencoverSettings )
2768 {
69+ var includes = SanitizeExcludesOrIncludes ( project . Settings . Include ) ;
70+ var excludes = SanitizeExcludesOrIncludes ( project . Settings . Exclude ) . ToList ( ) ;
71+
2872 var includedModules = project . IncludedReferencedProjects . Select ( rp => rp . AssemblyName ) . ToList ( ) ;
29- if ( project . Settings . IncludeTestAssembly )
73+ if ( project . Settings . IncludeTestAssembly &&
74+ IncludeTestAssemblyOnlyWhenNecessary ( project . IncludedReferencedProjects , includes , excludes , project . ProjectName ) )
3075 {
3176 includedModules. Add ( project . ProjectName ) ;
3277 }
33- var includeFilters = GetExcludesOrIncludes ( project . Settings . Include , includedModules , true ) ;
34- var excludeFilters = GetExcludesOrIncludes( project . Settings . Exclude , project . ExcludedReferencedProjects . Select ( rp => rp . AssemblyName ) , false ) ;
78+
79+ var includeFilters = GetExcludesOrIncludes( includes , includedModules , true ) ;
80+ var excludeFilters = GetExcludesOrIncludes( excludes , project . ExcludedReferencedProjects . Select ( rp => rp . AssemblyName ) , false ) ;
3581 AddIncludeAllIfExcludingWithoutIncludes( ) ;
3682 var filters = includeFilters. Concat ( excludeFilters ) . ToList ( ) ;
3783 SafeAddToSettingsDelimitedIfAny( opencoverSettings , "filter" , filters , Delimiter . Space ) ;
@@ -49,9 +95,9 @@ List<string> GetExcludesOrIncludes(
4995 {
5096 var excludeOrIncludeFilters = new List < string > ( ) ;
5197 var prefix = IncludeSymbol( isInclude ) ;
52- var sanitizedExcludesOrIncludes = SanitizeExcludesOrIncludes ( excludesOrIncludes ) ;
98+ // var sanitizedExcludesOrIncludes = SanitizeExcludesOrIncludes(excludesOrIncludes);
5399
54- foreach ( var value in sanitizedExcludesOrIncludes )
100+ foreach ( var value in excludesOrIncludes )
55101 {
56102 excludeOrIncludeFilters . Add ( $@ "{ prefix } { value } ") ;
57103 }
0 commit comments