Skip to content

Commit

Permalink
Merge pull request OpenCover#397 from ddur/rc
Browse files Browse the repository at this point in the history
OpenCover.4.6.260-rc
  • Loading branch information
ddur committed Dec 30, 2015
2 parents e75bab9 + a38ef53 commit ab1148e
Show file tree
Hide file tree
Showing 9 changed files with 252 additions and 172 deletions.
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
OpenCover is a code coverage tool for .NET 2 and above (Windows OSs only - no MONO), with support for 32 and 64 processes and covers both branch and sequence points. OpenCover was started after attempts to make PartCover support 64-bit processes got just a [little too complicated](http://blog.many-monkeys.com/open_cover_first_beta_release/).

The latest releases can be downloaded from [releases](https://github.com/opencover/opencover/releases) or from the OpenCover mirror site on [bitbucket](https://bitbucket.org/shaunwilde/opencover/downloads). **Alternatively** why not try the [nuget](http://nuget.org/packages/opencover) package (this is the most popular).

[![Build status](https://img.shields.io/appveyor/ci/sawilde/opencover.svg)](https://ci.appveyor.com/project/sawilde/opencover)
Expand Down Expand Up @@ -28,6 +30,9 @@ If anyone is aware of any licence violations that this code may be making please
### Integration Test support
OpenCover was initially created to support unit testing techniques such as TDD and tools like NUnit and MSTest. Over time others have found ways to use OpenCover for integration testing especially in tricky scenarios such as IIS and Windows Services. I'll put links here as to how people have achieved this however as they say YMMV (You Mileage May Vary).

#### Mono support
It isn't sorry - this tool uses the profiler API that is currently only available to .NET Frameworks running on the windows platform.

#### IIS support
Please refer to the wiki - [IIS Support](https://github.com/OpenCover/opencover/wiki/IIS-Support)

Expand Down
2 changes: 1 addition & 1 deletion main/OpenCover.Framework/CommandLineParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,7 @@ private T ExtractValue<T>(string argumentName, Action onError)

private static List<string> ExtractFilters(string rawFilters)
{
const string strRegex = @"([+-](\{.*?\})?[\[].*?[\]].+?\s)|([+-](\{.*\})?[\[].*?[\]].*)";
const string strRegex = @"([+-](\{.*?\})?[\[].*?[\]].+?\s)|([+-](\{.*\})?[\[].*?[\]][^\x22]*)";
const RegexOptions myRegexOptions = RegexOptions.None;
var myRegex = new Regex(strRegex, myRegexOptions);

Expand Down
42 changes: 31 additions & 11 deletions main/OpenCover.Framework/Filter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ public void AddFilter(string assemblyClassName)

if (!RegExFilters)
{
processName = (string.IsNullOrEmpty(processName) ? "*" : processName).ValidateAndEscape();
processName = (string.IsNullOrEmpty(processName) ? "*" : processName).ValidateAndEscape("/?\"<>|}{");
assemblyName = assemblyName.ValidateAndEscape();
className = className.ValidateAndEscape();
}
Expand Down Expand Up @@ -319,24 +319,44 @@ public bool IsAutoImplementedProperty(MethodDefinition method)
/// <summary>
/// Should we instrument this asssembly
/// </summary>
/// <param name="processName"></param>
/// <param name="processPath"></param>
/// <returns></returns>
public bool InstrumentProcess(string processName)
public bool InstrumentProcess(string processPath)
{
if (string.IsNullOrEmpty(processName))
if (string.IsNullOrEmpty(processPath))
{
return false;
}
if (!ExclusionFilters.Any() && !InclusionFilters.Any()) return true;

processName = Path.GetFileNameWithoutExtension(processName);
var matchingExclusionFilters = ExclusionFilters.GetMatchingFiltersForProcessName(processName);
if (matchingExclusionFilters.Any(exclusionFilter => exclusionFilter.AssemblyName == ".*" && exclusionFilter.ClassName == ".*"))
{
return false;
var processName = Path.GetFileNameWithoutExtension(processPath); // can return null!
if (ExclusionFilters.Any()) {
var matchingExclusionFilters = new List<AssemblyAndClassFilter>(ExclusionFilters.GetMatchingFiltersForProcessName(processPath));
if (!string.IsNullOrWhiteSpace (processName) && processName != processPath) {
matchingExclusionFilters.AddRange(ExclusionFilters.GetMatchingFiltersForProcessName(processName));
}
if (matchingExclusionFilters.Any
( exclusionFilter =>
// class-filter is .* and assembly-filter is matching processName
// this does not match default exclude filters like {.*}[mscorlib].* or {.*}[system].*
// but does match {.*}[.*].* or {.*}[processNa*].* or {.*}[processName].* where assemblyName == processName
exclusionFilter.ClassName == ".*" && exclusionFilter.IsMatchingAssemblyName (processName)
)
)
{
return false;
}
}

if (InclusionFilters.Any()) {
var matchingInclusionFilters = new List<AssemblyAndClassFilter>(InclusionFilters.GetMatchingFiltersForProcessName(processPath));
if (!string.IsNullOrWhiteSpace (processName) && processName != processPath) {
matchingInclusionFilters.AddRange(InclusionFilters.GetMatchingFiltersForProcessName(processName));
}
return matchingInclusionFilters.Any();
}

var matchingInclusionFilters = InclusionFilters.GetMatchingFiltersForProcessName(processName);
return matchingInclusionFilters.Any(inclusionFilter => inclusionFilter.AssemblyName == ".*" || inclusionFilter.ClassName == ".*");
return true; // not excluded and no inclusion filters
}

/// <summary>
Expand Down
26 changes: 18 additions & 8 deletions main/OpenCover.Framework/Model/Method.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,13 @@ public class Method : SummarySkippedEntity
[XmlAttribute("cyclomaticComplexity")]
public int CyclomaticComplexity { get; set; }

/// <summary>
/// What is the NPath complexity of this method.
/// </summary>
/// <remarks>Product of path branches (ie:path0=2;path1=3;path2=2 =&gt;2*3*2==12</remarks>
[XmlAttribute("nPathComplexity")]
public int NPathComplexity { get; set; }

/// <summary>
/// What is the sequence coverage of this method
/// </summary>
Expand Down Expand Up @@ -108,6 +115,7 @@ public override void MarkAsSkipped(SkippedMethod reason)
SequencePoints = null;
BranchPoints = null;
}

/// <summary>
/// method name excluding return type, namespace and arguments
/// </summary>
Expand All @@ -122,13 +130,6 @@ public string shortName {
}
}

/* Compiler Generated Name Examples
<Name>System.Boolean DD.Collections.BitSetArray/&lt;Complement&gt;d__e::MoveNext()</Name>
<Name>System.Boolean DD.Collections.BitSetArray::&lt;_SetItems&gt;b__b(System.Int32)</Name>
<Name>System.Boolean DD.Collections.BitSetArray::BitSetArray_&lt;_SetItems&gt;b__b_0(System.Int32)</Name>
<Name>[^\s]+\s[^\s|/|:]+(/\w*)?(::(.+_)?)?(&lt;\w+&gt;[a-z]__\w(\w|_\w)?)(::.+)?(\(.*\)</Name>)$
*/
/// <summary>
/// True if method name matches isGeneratedMethodRegex pattern
/// </summary>
Expand All @@ -140,14 +141,23 @@ public bool isGenerated {
);
}
}

private const RegexOptions regexOptions = RegexOptions.Compiled | RegexOptions.Singleline | RegexOptions.ExplicitCapture;
private readonly Regex isGeneratedMethodRegex = new Regex(@"(<[^\s|>]+>[a-z]__\w(\w|_\w)?)(::([^\s|\(]+))?(\([^\s|\)]*\))$", regexOptions);
private readonly Regex generatedMethodItems = new Regex(@"(?<returnType>[^\s]+)\s(?<nameSpace>[^\s|/]+/)?(?<className>[^\s|:]+::)?(<(?<replacedName>[^\s|>]+)>[a-z]__\w(\w|_\w)?)(::(?<methodName>[^\s|\(]+))?(\([^\s|\)]*\))$", regexOptions);

/* Compiler Generated Name Examples
<Name>System.Boolean DD.Collections.BitSetArray/&lt;Complement&gt;d__e::MoveNext()</Name>
<Name>System.Boolean DD.Collections.BitSetArray::&lt;_SetItems&gt;b__b(System.Int32)</Name>
<Name>System.Boolean DD.Collections.BitSetArray::BitSetArray_&lt;_SetItems&gt;b__b_0(System.Int32)</Name>
<Name>[^\s]+\s[^\s|/|:]+(/\w*)?(::(.+_)?)?(&lt;\w+&gt;[a-z]__\w(\w|_\w)?)(::.+)?(\(.*\)</Name>)$
*/

/*
code sample
Match match = generatedMethodItems.Match(sample);
if (match.Success) Console.WriteLine(match.Groups["returnType"].Value);
*/
private readonly Regex generatedMethodItems = new Regex(@"(?<returnType>[^\s]+)\s(?<nameSpace>[^\s|/]+/)?(?<className>[^\s|:]+::)?(<(?<replacedName>[^\s|>]+)>[a-z]__\w(\w|_\w)?)(::(?<methodName>[^\s|\(]+))?(\([^\s|\)]*\))$", regexOptions);
}
}
8 changes: 3 additions & 5 deletions main/OpenCover.Framework/Model/SequencePoint.cs
Original file line number Diff line number Diff line change
Expand Up @@ -93,11 +93,8 @@ public override int GetHashCode () {
/// <param name="obj">Object</param>
/// <returns>bool</returns>
public override bool Equals (Object obj) {
if (ReferenceEquals(this, obj)) {
return true;
}
var that = obj as SequencePoint;
return !ReferenceEquals(that, null) && this.Equals(that);
return !ReferenceEquals(that, null) && (ReferenceEquals(this, that) || this.Equals(that));
}

/// <summary>
Expand All @@ -108,7 +105,8 @@ public override bool Equals (Object obj) {
bool IEquatable<SequencePoint>.Equals(SequencePoint other)
{
return !ReferenceEquals(other, null)
&& this.Document == other.Document
&& this.FileId != 0
&& this.FileId == other.FileId
&& this.StartLine == other.StartLine
&& this.StartColumn == other.StartColumn
&& this.EndLine == other.EndLine
Expand Down
Loading

0 comments on commit ab1148e

Please sign in to comment.