Browse Source

Branch Coverage Color Highlighter

Highlighted visited code with incomplete branches has third color.
"Color Touched" is configurable from Options/Tools/Code Coverage
pull/67/head
Dragan 12 years ago
parent
commit
d58aec7529
  1. 385
      data/resources/StringResources.resx
  2. 11
      src/AddIns/Analysis/CodeCoverage/Project/Src/CodeCoverageControl.cs
  3. 9
      src/AddIns/Analysis/CodeCoverage/Project/Src/CodeCoverageHighlighter.cs
  4. 29
      src/AddIns/Analysis/CodeCoverage/Project/Src/CodeCoverageMethodElement.cs
  5. 14
      src/AddIns/Analysis/CodeCoverage/Project/Src/CodeCoverageOptions.cs
  6. 1
      src/AddIns/Analysis/CodeCoverage/Project/Src/CodeCoverageOptionsPanel.xaml.cs
  7. 51
      src/AddIns/Analysis/CodeCoverage/Project/Src/CodeCoverageResults.cs
  8. 4
      src/AddIns/Analysis/CodeCoverage/Project/Src/CodeCoverageSequencePoint.cs

385
data/resources/StringResources.resx

File diff suppressed because it is too large Load Diff

11
src/AddIns/Analysis/CodeCoverage/Project/Src/CodeCoverageControl.cs

@ -34,6 +34,7 @@ namespace ICSharpCode.CodeCoverage @@ -34,6 +34,7 @@ namespace ICSharpCode.CodeCoverage
ColumnHeader endLineColumnHeader;
ColumnHeader startColumnColumnHeader;
ColumnHeader endColumnColumnHeader;
ColumnHeader allBranchesColumnHeader;
ToolStrip toolStrip;
bool showSourceCodePanel;
bool showVisitCountPanel = true;
@ -300,7 +301,7 @@ namespace ICSharpCode.CodeCoverage @@ -300,7 +301,7 @@ namespace ICSharpCode.CodeCoverage
item.SubItems.Add(sequencePoint.Column.ToString());
item.SubItems.Add(sequencePoint.EndLine.ToString());
item.SubItems.Add(sequencePoint.EndColumn.ToString());
item.SubItems.Add(sequencePoint.BranchCovered.ToString());
item.SubItems.Add(sequencePoint.BranchCoverage.ToString());
item.Tag = sequencePoint;
listView.Items.Add(item);
@ -414,11 +415,17 @@ namespace ICSharpCode.CodeCoverage @@ -414,11 +415,17 @@ namespace ICSharpCode.CodeCoverage
endColumnColumnHeader.Text = StringParser.Parse("${res:ICSharpCode.CodeCoverage.EndColumn}");
endColumnColumnHeader.Width = 80;
allBranchesColumnHeader = new ColumnHeader();
allBranchesColumnHeader.Text = StringParser.Parse("${res:ICSharpCode.CodeCoverage.AllBranches}");
allBranchesColumnHeader.Width = 80;
listView.Columns.AddRange(new ColumnHeader[] {visitCountColumnHeader,
startLineColumnHeader,
startColumnColumnHeader,
endLineColumnHeader,
endColumnColumnHeader});
endColumnColumnHeader,
allBranchesColumnHeader
});
// Create custom list view sorter.
sequencePointListViewSorter = new SequencePointListViewSorter(listView);

9
src/AddIns/Analysis/CodeCoverage/Project/Src/CodeCoverageHighlighter.cs

@ -94,10 +94,10 @@ namespace ICSharpCode.CodeCoverage @@ -94,10 +94,10 @@ namespace ICSharpCode.CodeCoverage
public static Color GetSequencePointColor(CodeCoverageSequencePoint sequencePoint)
{
if (sequencePoint.VisitCount > 0) {
if ( sequencePoint.BranchCovered ) {
if ( sequencePoint.BranchCoverage == true ) {
return CodeCoverageOptions.VisitedColor.ToWpf();
}
return CodeCoverageOptions.PartialVisitedColor.ToWpf();
return CodeCoverageOptions.PartVisitedColor.ToWpf();
}
return CodeCoverageOptions.NotVisitedColor.ToWpf();
}
@ -105,7 +105,10 @@ namespace ICSharpCode.CodeCoverage @@ -105,7 +105,10 @@ namespace ICSharpCode.CodeCoverage
public static Color GetSequencePointForeColor(CodeCoverageSequencePoint sequencePoint)
{
if (sequencePoint.VisitCount > 0) {
return CodeCoverageOptions.VisitedForeColor.ToWpf();
if ( sequencePoint.BranchCoverage == true ) {
return CodeCoverageOptions.VisitedForeColor.ToWpf();
}
return CodeCoverageOptions.PartVisitedForeColor.ToWpf();
}
return CodeCoverageOptions.NotVisitedForeColor.ToWpf();
}

29
src/AddIns/Analysis/CodeCoverage/Project/Src/CodeCoverageMethodElement.cs

@ -30,7 +30,7 @@ namespace ICSharpCode.CodeCoverage @@ -30,7 +30,7 @@ namespace ICSharpCode.CodeCoverage
Init();
}
public string FileRef { get; private set; }
public string FileID { get; private set; }
public bool IsVisited { get; private set; }
public int CyclomaticComplexity { get; private set; }
public decimal SequenceCoverage { get; private set; }
@ -56,37 +56,40 @@ namespace ICSharpCode.CodeCoverage @@ -56,37 +56,40 @@ namespace ICSharpCode.CodeCoverage
IsGetter = GetBooleanAttributeValue("isGetter");
IsSetter = GetBooleanAttributeValue("isSetter");
this.FileRef = GetFileRef();
this.FileID = GetFileRef();
this.IsVisited = this.GetBooleanAttributeValue("visited");
this.CyclomaticComplexity = (int)this.GetDecimalAttributeValue("cyclomaticComplexity");
this.SequencePoints = this.GetSequencePoints();
this.SequencePointsCount = this.SequencePoints.Count;
//this.SequencePointsCount = this.GetSequencePointsCount();
this.SequencePointsCount = this.GetSequencePointsCount();
this.SequenceCoverage = (int)this.GetDecimalAttributeValue("sequenceCoverage");
this.BranchPoints = this.GetBranchPoints();
this.BranchCoverageRatio = this.GetBranchRatio();
this.BranchCoverage = this.GetBranchCoverage();
this.IsConstructor = this.GetBooleanAttributeValue("isConstructor");
this.IsStatic = this.GetBooleanAttributeValue("isStatic");
if ( !String.IsNullOrEmpty( this.FileID ) ) {
this.SequencePoints = this.GetSequencePoints();
this.BranchPoints = this.GetBranchPoints();
this.BranchCoverageRatio = this.GetBranchRatio();
this.BranchCoverage = this.GetBranchCoverage();
}
}
List<CodeCoverageSequencePoint> GetSequencePoints() {
// get all SequencePoints
List<CodeCoverageSequencePoint> sps = new List<CodeCoverageSequencePoint>();
var xSPoints = this.element
.Elements("SequencePoints")
.Elements("SequencePoint");
foreach (XElement xSPoint in xSPoints) {
CodeCoverageSequencePoint sp = new CodeCoverageSequencePoint();
sp.FileRef = this.FileRef;
sp.FileID = this.FileID;
sp.Line = (int)GetDecimalAttributeValue(xSPoint.Attribute("sl"));
sp.EndLine = (int)GetDecimalAttributeValue(xSPoint.Attribute("el"));
sp.Column = (int)GetDecimalAttributeValue(xSPoint.Attribute("sc"));
sp.EndColumn = (int)GetDecimalAttributeValue(xSPoint.Attribute("ec"));
sp.VisitCount = (int)GetDecimalAttributeValue(xSPoint.Attribute("vc"));
sp.Length = 1;
sp.BranchCovered = true;
sp.Offset = (int)GetDecimalAttributeValue(xSPoint.Attribute("offset"));
sp.BranchCoverage = true;
sps.Add(sp);
}
return sps;
@ -251,7 +254,7 @@ namespace ICSharpCode.CodeCoverage @@ -251,7 +254,7 @@ namespace ICSharpCode.CodeCoverage
foreach ( CodeCoverageSequencePoint sp in this.SequencePoints ) {
if ( sp.Offset > uniqueBranch.Offset ) {
if ( !Object.ReferenceEquals( sp_target, null ) ) {
sp_target.BranchCovered = false;
sp_target.BranchCoverage = false;
}
break;
}

14
src/AddIns/Analysis/CodeCoverage/Project/Src/CodeCoverageOptions.cs

@ -14,6 +14,8 @@ namespace ICSharpCode.CodeCoverage @@ -14,6 +14,8 @@ namespace ICSharpCode.CodeCoverage
#region Property names
public static readonly string VisitedColorProperty = "VisitedColor";
public static readonly string VisitedForeColorProperty = "VisitedForeColor";
public static readonly string PartVisitedColorProperty = "PartVisitedColor";
public static readonly string PartVisitedForeColorProperty = "PartVisitedForeColor";
public static readonly string NotVisitedColorProperty = "NotVisitedColor";
public static readonly string NotVisitedForeColorProperty = "NotVisitedForeColor";
@ -78,18 +80,18 @@ namespace ICSharpCode.CodeCoverage @@ -78,18 +80,18 @@ namespace ICSharpCode.CodeCoverage
/// <summary>
/// Gets the colour that will be used when highlighting visited code.
/// </summary>
public static Color PartialVisitedColor {
get { return Properties.Get<Color>(VisitedColorProperty, Color.Yellow); }
set { Properties.Set<Color>(VisitedColorProperty, value); }
public static Color PartVisitedColor {
get { return Properties.Get<Color>(PartVisitedColorProperty, Color.Yellow); }
set { Properties.Set<Color>(PartVisitedColorProperty, value); }
}
/// <summary>
/// Gets the foreground colour that will be used when highlighting
/// visited code.
/// </summary>
public static Color PartialVisitedForeColor {
get { return Properties.Get<Color>(VisitedForeColorProperty, Color.Black); }
set { Properties.Set<Color>(VisitedForeColorProperty, value); }
public static Color PartVisitedForeColor {
get { return Properties.Get<Color>(PartVisitedForeColorProperty, Color.Black); }
set { Properties.Set<Color>(PartVisitedForeColorProperty, value); }
}
/// <summary>

1
src/AddIns/Analysis/CodeCoverage/Project/Src/CodeCoverageOptionsPanel.xaml.cs

@ -32,6 +32,7 @@ namespace ICSharpCode.CodeCoverage @@ -32,6 +32,7 @@ namespace ICSharpCode.CodeCoverage
DataContext = this;
DisplayItems = new ObservableCollection<CodeCoverageDisplayItem>();
DisplayItems.Add(new CodeCoverageDisplayItem(StringParser.Parse("${res:ICSharpCode.CodeCoverage.CodeCovered}"), CodeCoverageOptions.VisitedColorProperty, CodeCoverageOptions.VisitedColor, CodeCoverageOptions.VisitedForeColorProperty, CodeCoverageOptions.VisitedForeColor));
DisplayItems.Add(new CodeCoverageDisplayItem(StringParser.Parse("${res:ICSharpCode.CodeCoverage.CodePartCovered}"), CodeCoverageOptions.PartVisitedColorProperty, CodeCoverageOptions.PartVisitedColor, CodeCoverageOptions.PartVisitedForeColorProperty, CodeCoverageOptions.PartVisitedForeColor));
DisplayItems.Add(new CodeCoverageDisplayItem(StringParser.Parse("${res:ICSharpCode.CodeCoverage.CodeNotCovered}"), CodeCoverageOptions.NotVisitedColorProperty, CodeCoverageOptions.NotVisitedColor, CodeCoverageOptions.NotVisitedForeColorProperty, CodeCoverageOptions.NotVisitedForeColor));
DisplayItem = DisplayItems[0];
}

51
src/AddIns/Analysis/CodeCoverage/Project/Src/CodeCoverageResults.cs

@ -106,49 +106,31 @@ namespace ICSharpCode.CodeCoverage @@ -106,49 +106,31 @@ namespace ICSharpCode.CodeCoverage
string id = reader.Attribute("hash").Value;
return GetAssembly(id);
}
/// <summary>
/// Sequence points that do not have a file id are not
/// added to the code coverage method. Typically these are
/// for types that are not part of the project but types from
/// the .NET framework.
/// </summary>
CodeCoverageMethod AddMethod(CodeCoverageModule module, string className, XElement reader)
{
CodeCoverageMethod method = new CodeCoverageMethod(className, reader);
module.Methods.Add(method);
/* move that code into CodeCoverageMethod/Element
var points = reader
.Elements("SequencePoints")
.Elements("SequencePoint");
foreach (XElement point in points) {
AddSequencePoint(method, point, reader);
}
*/
// UPDATE SEQUENCE POINTS DOCUMENT
// to resolve SequencePoint.BranchCoverage ...
// reading/adding method.sequencepoints is moved from this class into CodeCoverageMethod/Element
// but here yet must resolve sequencepoint.document
foreach ( var sp in method.SequencePoints ) {
sp.Document = GetFileName(sp.FileRef);
if ( !String.IsNullOrEmpty(sp.FileID) )
sp.Document = GetFileName(sp.FileID);
}
return method;
}
/// <summary>
/// Sequence points that do not have a file id are not
/// added to the code coverage method. Typically these are
/// for types that are not part of the project but types from
/// the .NET framework.
/// Cache result because same FileID is repeated for each SequencePoint
/// </summary>
void AddSequencePoint(CodeCoverageMethod method, XElement reader, XElement methodNode)
{
string fileName = GetFileName(methodNode);
CodeCoverageSequencePoint sequencePoint =
new CodeCoverageSequencePoint(fileName, reader);
method.SequencePoints.Add(sequencePoint);
}
string GetFileName(XElement reader)
{
XElement fileId = reader.Element("FileRef");
if (fileId != null) {
return GetFileName(fileId.Attribute("uid").Value);
}
return String.Empty;
}
private static Tuple<string,string> fileIdNameCache = new Tuple<string, string>(String.Empty,String.Empty);
/// <summary>
/// Returns a filename based on the file id. The filenames are stored in the
@ -156,7 +138,10 @@ namespace ICSharpCode.CodeCoverage @@ -156,7 +138,10 @@ namespace ICSharpCode.CodeCoverage
/// </summary>
string GetFileName(string id)
{
return GetDictionaryValue(fileNames, id);
if (fileIdNameCache.Item1 != id) {
fileIdNameCache = new Tuple<string, string>(id, GetDictionaryValue(fileNames, id));
}
return fileIdNameCache.Item2;
}
/// <summary>

4
src/AddIns/Analysis/CodeCoverage/Project/Src/CodeCoverageSequencePoint.cs

@ -64,7 +64,7 @@ namespace ICSharpCode.CodeCoverage @@ -64,7 +64,7 @@ namespace ICSharpCode.CodeCoverage
return !String.IsNullOrEmpty(Document);
}
public string FileRef { get; set; }
public string FileID { get; set; }
public string Document { get; set; }
public int VisitCount { get; set; }
public int Line { get; set; }
@ -73,7 +73,7 @@ namespace ICSharpCode.CodeCoverage @@ -73,7 +73,7 @@ namespace ICSharpCode.CodeCoverage
public int EndColumn { get; set; }
public int Length { get; set; }
public int Offset { get; set; }
public bool BranchCovered { get; set; }
public bool BranchCoverage { get; set; }
public override bool Equals(object obj)
{

Loading…
Cancel
Save