Skip to content

Commit

Permalink
Merge pull request mmanela#407 from stogle/master
Browse files Browse the repository at this point in the history
adds /coverageIgnore option to exclude files from code coverage results
  • Loading branch information
mmanela committed Nov 21, 2015
2 parents 59ea1c3 + 34fda9d commit c8949e8
Show file tree
Hide file tree
Showing 10 changed files with 116 additions and 6 deletions.
26 changes: 25 additions & 1 deletion Chutzpah/Coverage/BlanketJsCoverageEngine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ public class BlanketJsCoverageEngine : ICoverageEngine

private List<string> includePatterns { get; set; }
private List<string> excludePatterns { get; set; }
private List<string> ignorePatterns { get; set; }

public BlanketJsCoverageEngine(IJsonSerializer jsonSerializer, IFileSystemWrapper fileSystem, ILineCoverageMapper lineCoverageMapper)
{
Expand All @@ -34,6 +35,7 @@ public BlanketJsCoverageEngine(IJsonSerializer jsonSerializer, IFileSystemWrappe

includePatterns = new List<string>();
excludePatterns = new List<string>();
ignorePatterns = new List<string>();
}

public IEnumerable<string> GetFileDependencies(IFrameworkDefinition definition, ChutzpahTestSettingsFile testSettingsFile)
Expand Down Expand Up @@ -166,7 +168,9 @@ public CoverageData DeserializeCoverageObject(string json, TestContext testConte
}
}

if (IsFileEligibleForInstrumentation(newKey) && fileSystem.FileExists(filePath))
if (IsFileEligibleForInstrumentation(newKey) &&
!(testContext.CoverageEngine != null && testContext.CoverageEngine.IsIgnored(newKey)) &&
fileSystem.FileExists(filePath))
{
string[] sourceLines = fileSystem.GetLines(filePath);
int?[] lineExecutionCounts = entry.Value;
Expand All @@ -191,6 +195,7 @@ public void ClearPatterns()
{
includePatterns.Clear();
excludePatterns.Clear();
ignorePatterns.Clear();
}

public void AddIncludePatterns(IEnumerable<string> patterns)
Expand All @@ -209,6 +214,14 @@ public void AddExcludePatterns(IEnumerable<string> patterns)
}
}

public void AddIgnorePatterns(IEnumerable<string> patterns)
{
foreach (var pattern in patterns)
{
ignorePatterns.Add(pattern);
}
}

private bool IsFileEligibleForInstrumentation(string filePath)
{
// If no include patterns are given then include all files. Otherwise include only the ones that match an include pattern
Expand All @@ -226,6 +239,17 @@ private bool IsFileEligibleForInstrumentation(string filePath)
return true;
}

public bool IsIgnored(string filePath)
{
// If no ignore pattern is given then include all files. Otherwise ignore the ones that match an ignore pattern
if (ignorePatterns.Any() && ignorePatterns.Any(ignorePattern => NativeImports.PathMatchSpec(filePath, FileProbe.NormalizeFilePath(ignorePattern))))
{
return true;
}

return false;
}

private string GetBlanketScriptName(IFrameworkDefinition def, ChutzpahTestSettingsFile settingsFile)
{
return def.GetBlanketScriptName(settingsFile);
Expand Down
13 changes: 13 additions & 0 deletions Chutzpah/Coverage/ICoverageEngine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,19 @@ public interface ICoverageEngine
/// is done with the <c>PathMatchSpec</c> Windows function.
void AddExcludePatterns(IEnumerable<string> excludePatterns);

/// <summary>
/// Add file name pattern that, if set, a file must NOT match to be included in results. Pattern matching
/// is done with the <c>PathMatchSpec</c> Windows function.
/// </summary>
void AddIgnorePatterns(IEnumerable<string> ignorePatterns);

/// <summary>
/// Returns true if the path should not be included in results, false otherwise.
/// </summary>
/// <param name="filePath">The path to test.</param>
/// <returns></returns>
bool IsIgnored(string filePath);

/// <summary>
/// Reset patterns between runs, this is to prevent caching old configurations
/// </summary>
Expand Down
6 changes: 6 additions & 0 deletions Chutzpah/CoverageOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ public CoverageOptions()
{
IncludePatterns = new List<string>();
ExcludePatterns = new List<string>();
IgnorePatterns = new List<string>();
}

/// <summary>
Expand All @@ -29,6 +30,11 @@ public CoverageOptions()
/// </summary>
public ICollection<string> ExcludePatterns { get; set; }

/// <summary>
/// If specified, pattern of files to exclude from the results phase.
/// </summary>
public ICollection<string> IgnorePatterns { get; set; }

public bool ShouldRunCoverage(CodeCoverageExecutionMode? coverageExecutionModeSetting)
{
// If not set or set to manual honor the passed in value from the user
Expand Down
7 changes: 7 additions & 0 deletions Chutzpah/Models/ChutzpahTestSettingsFile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ public ChutzpahTestSettingsFile()
{
CodeCoverageIncludes = new List<string>();
CodeCoverageExcludes = new List<string>();
CodeCoverageIgnores = new List<string>();
References = new List<SettingsFileReference>();
Tests = new List<SettingsFileTestPath>();
Transforms = new List<TransformConfig>();
Expand Down Expand Up @@ -209,6 +210,11 @@ private ChutzpahTestSettingsFile(bool isDefaultSetings) : this()
/// </summary>
public ICollection<string> CodeCoverageExcludes { get; set; }

/// <summary>
/// The collection code coverage file patterns to ignore in coverage. These are in glob format. If you specify none no files are excluded.
/// </summary>
public ICollection<string> CodeCoverageIgnores { get; set; }

/// <summary>
/// The collection of test files. These can list individual tests or folders scanned recursively. This setting can work in two ways:
/// 1. If you run tests normally by specifying folders/files then this settings will filter the sets of those files.
Expand Down Expand Up @@ -341,6 +347,7 @@ public ChutzpahTestSettingsFile InheritFrom(ChutzpahTestSettingsFile parent)
this.References = parent.References.Concat(this.References).ToList();
this.CodeCoverageIncludes = parent.CodeCoverageIncludes.Concat(this.CodeCoverageIncludes).ToList();
this.CodeCoverageExcludes = parent.CodeCoverageExcludes.Concat(this.CodeCoverageExcludes).ToList();
this.CodeCoverageIgnores = parent.CodeCoverageIgnores.Concat(this.CodeCoverageIgnores).ToList();
this.Transforms = parent.Transforms.Concat(this.Transforms).ToList();

if (this.Compile == null)
Expand Down
1 change: 1 addition & 0 deletions Chutzpah/TestContextBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -417,6 +417,7 @@ private ICoverageEngine GetConfiguredCoverageEngine(TestOptions options, Chutzpa
coverageEngine.ClearPatterns();
coverageEngine.AddIncludePatterns(chutzpahTestSettings.CodeCoverageIncludes.Concat(options.CoverageOptions.IncludePatterns));
coverageEngine.AddExcludePatterns(chutzpahTestSettings.CodeCoverageExcludes.Concat(options.CoverageOptions.ExcludePatterns));
coverageEngine.AddIgnorePatterns(chutzpahTestSettings.CodeCoverageIgnores.Concat(options.CoverageOptions.IgnorePatterns));
return coverageEngine;
}

Expand Down
18 changes: 17 additions & 1 deletion ConsoleRunner/CommandLine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,11 @@ protected CommandLine(string[] args)
public bool Coverage { get; protected set; }

public string CoverageIncludePatterns { get; protected set; }

public string CoverageExcludePatterns { get; protected set; }

public string CoverageIgnorePatterns { get; protected set; }

public string BrowserName { get; protected set; }

private static void GuardNoOptionValue(KeyValuePair<string, string> option)
Expand Down Expand Up @@ -165,6 +167,10 @@ protected void Parse()
{
AddCoverageExcludeOption(option.Value);
}
else if (optionName == "/coverageignores")
{
AddCoverageIgnoreOption(option.Value);
}
else if (optionName == "/showfailurereport")
{
GuardNoOptionValue(option);
Expand Down Expand Up @@ -207,6 +213,16 @@ private void AddCoverageExcludeOption(string value)
CoverageExcludePatterns = value;
}

private void AddCoverageIgnoreOption(string value)
{
if (string.IsNullOrEmpty(value))
{
throw new ArgumentException(
"invalid or missing argument for /coverageIgnores. Expecting a list of comma separated file name patterns");
}
CoverageIgnorePatterns = value;
}

private void AddParallelismOption(string value)
{
int parallelism;
Expand Down
3 changes: 2 additions & 1 deletion ConsoleRunner/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,8 @@ static int RunTests(CommandLine commandLine)
{
Enabled = commandLine.Coverage,
IncludePatterns = (commandLine.CoverageIncludePatterns ?? "").Split(new[]{','},StringSplitOptions.RemoveEmptyEntries),
ExcludePatterns = (commandLine.CoverageExcludePatterns ?? "").Split(new[]{','},StringSplitOptions.RemoveEmptyEntries)
ExcludePatterns = (commandLine.CoverageExcludePatterns ?? "").Split(new[]{','},StringSplitOptions.RemoveEmptyEntries),
IgnorePatterns = (commandLine.CoverageIgnorePatterns ?? "").Split(new[]{','},StringSplitOptions.RemoveEmptyEntries)
}
};

Expand Down
15 changes: 15 additions & 0 deletions Facts.Integration/Coverage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,21 @@ public void Will_exclude_given_file_patterns(string scriptPath)
});
}

[Theory]
[PropertyData("AmdTestScriptWithForcedRequire")]
public void Will_ignore_only_given_file_patterns(string scriptPath)
{
var testRunner = TestRunner.Create();

var result = testRunner.RunTests(scriptPath, WithCoverage(co => { co.IncludePatterns = new[] { "*\\ui\\*", "*core.js" }; co.IgnorePatterns = new[] { "tests\\*" }; }), new ExceptionThrowingRunnerCallback());

ExpectKeysMatching(result.TestFileSummaries.Single().CoverageObject,
new[]
{
"\\base\\core.js", "ui\\screen.js"
});
}

[Theory]
[PropertyData("AmdTestScriptWithForcedRequire")]
public void Will_resolve_requirejs_required_files_correctly(string scriptPath)
Expand Down
20 changes: 20 additions & 0 deletions Facts/ConsoleRunner/CommandLineFacts.cs
Original file line number Diff line number Diff line change
Expand Up @@ -590,6 +590,16 @@ public void CoverageExclude_Option_Not_Passed_CoverageExcludePattern_Null()
Assert.Null(commandLine.CoverageExcludePatterns);
}

[Fact]
public void CoverageExclude_Option_Not_Passed_CoverageIgnorePattern_Null()
{
var arguments = new[] { "test.html" };

var commandLine = TestableCommandLine.Create(arguments);

Assert.Null(commandLine.CoverageIgnorePatterns);
}

[Fact]
public void CoverageInclude_Option_With_Value_CoverageIncludePattern_Set()
{
Expand All @@ -610,6 +620,16 @@ public void CoverageExclude_Option_With_Value_CoverageExcludePattern_Set()
Assert.Equal("*.coffee", commandLine.CoverageExcludePatterns);
}

[Fact]
public void CoverageExclude_Option_With_Value_CoverageIgnorePattern_Set()
{
var arguments = new[] { "test.html", "/coverageIgnores", "*.ts" };

var commandLine = TestableCommandLine.Create(arguments);

Assert.Equal("*.ts", commandLine.CoverageIgnorePatterns);
}

[Fact]
public void Will_throw_if_no_arg_given_to_CoverageInclude()
{
Expand Down
13 changes: 10 additions & 3 deletions Facts/Library/Models/ChutzpahTestSettingsServiceFacts.cs
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,8 @@ public void Will_inherit_all_parent_settings_when_none_set_on_child()
References = new List<SettingsFileReference> { new SettingsFileReference { Path = "parentReferencePath" } },
Transforms = new List<TransformConfig>{ new TransformConfig{ Path = "parentTransformPath"}},
CodeCoverageExcludes = new List<string>{"parentCodeCoverageExcludePath"},
CodeCoverageIncludes = new List<string>{"parentCodeCoverageIncludePath"},
CodeCoverageIncludes = new List<string> { "parentCodeCoverageIncludePath" },
CodeCoverageIgnores = new List<string> { "parentCodeCoverageIgnorePath" },
Compile = new BatchCompileConfiguration{ Mode = BatchCompileMode.External},

AMDBasePath = "parentAmdBasePath",
Expand Down Expand Up @@ -277,6 +278,7 @@ public void Will_inherit_all_parent_settings_when_none_set_on_child()
Assert.Equal(1, childSettings.Transforms.Count);
Assert.Equal(1, childSettings.CodeCoverageIncludes.Count);
Assert.Equal(1, childSettings.CodeCoverageExcludes.Count);
Assert.Equal(1, childSettings.CodeCoverageIgnores.Count);

Assert.Equal(parentSettings.Compile, childSettings.Compile);
Assert.Equal(@"C:\settingsDir", childSettings.SettingsFileDirectory);
Expand Down Expand Up @@ -305,7 +307,8 @@ public void Will_merge_list_settings_and_set_settings_dir_property_for_applicabl
References = new List<SettingsFileReference> { new SettingsFileReference { Path = "parentReferencePath" } },
Transforms = new List<TransformConfig> { new TransformConfig { Path = "parentTransformPath" } },
CodeCoverageExcludes = new List<string> { "parentCodeCoverageExcludePath" },
CodeCoverageIncludes = new List<string> { "parentCodeCoverageIncludePath" }
CodeCoverageIncludes = new List<string> { "parentCodeCoverageIncludePath" },
CodeCoverageIgnores = new List<string> { "parentCodeCoverageIgnorePath" }
};

var childSettings = new ChutzpahTestSettingsFile
Expand All @@ -315,7 +318,8 @@ public void Will_merge_list_settings_and_set_settings_dir_property_for_applicabl
References = new List<SettingsFileReference> { new SettingsFileReference { Path = "childReferencePath" } },
Transforms = new List<TransformConfig> { new TransformConfig { Path = "childTransformPath" } },
CodeCoverageExcludes = new List<string> { "childCodeCoverageExcludePath" },
CodeCoverageIncludes = new List<string> { "childCodeCoverageIncludePath" }
CodeCoverageIncludes = new List<string> { "childCodeCoverageIncludePath" },
CodeCoverageIgnores = new List<string> { "childCodeCoverageIgnorePath" }
};

service.Mock<IFileProbe>().Setup(x => x.FindTestSettingsFile(@"C:\settingsDir")).Returns(@"C:\settingsDir\settingsFile.json");
Expand Down Expand Up @@ -348,6 +352,9 @@ public void Will_merge_list_settings_and_set_settings_dir_property_for_applicabl
Assert.Equal(2, childSettings.CodeCoverageExcludes.Count);
Assert.Equal("parentCodeCoverageExcludePath", childSettings.CodeCoverageExcludes.ElementAt(0));
Assert.Equal("childCodeCoverageExcludePath", childSettings.CodeCoverageExcludes.ElementAt(1));
Assert.Equal(2, childSettings.CodeCoverageIgnores.Count);
Assert.Equal("parentCodeCoverageIgnorePath", childSettings.CodeCoverageIgnores.ElementAt(0));
Assert.Equal("childCodeCoverageIgnorePath", childSettings.CodeCoverageIgnores.ElementAt(1));
}

[Fact]
Expand Down

0 comments on commit c8949e8

Please sign in to comment.