Skip to content

Commit

Permalink
adjusted line coverage
Browse files Browse the repository at this point in the history
added branch coverage on for expressions
fixed LCOV reporter to show partial coverage for branches
fixed coverage collection on empty switch cases
  • Loading branch information
AlexHaxe committed Jan 22, 2025
1 parent 26308e2 commit e7c5c3d
Show file tree
Hide file tree
Showing 8 changed files with 78 additions and 57 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@

## dev branch / next version (1.x.x)

## version 1.4.0 (2025-01-22)

- adjusted line coverage calculation
- added branch coverage on for expressions
- fixed LCOV reporter to show partial coverage for branches
- fixed coverage collection on empty switch cases

## version 1.3.1 (2025-01-07)

- fixed null reference when resetting attributable coverage for a zero coverage file
Expand Down
4 changes: 2 additions & 2 deletions haxelib.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
"profiler"
],
"description": "a profiling and coverage library for Haxe",
"version": "1.3.1",
"releasenote": "fixed null reference when resetting attributable coverage - see CHANGELOG",
"version": "1.4.0",
"releasenote": "adjusted line coverage calculation - see CHANGELOG",
"contributors": [
"AlexHaxe"
],
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "haxe-instrument",
"version": "1.3.1",
"version": "1.4.0",
"description": "a profiling and coverage library for Haxe",
"author": {
"name": "Alexander Blum",
Expand Down
35 changes: 29 additions & 6 deletions src/instrument/Instrumentation.hx
Original file line number Diff line number Diff line change
Expand Up @@ -533,7 +533,8 @@ class Instrumentation {

case EFor(it, e):
it = instrumentExpr(it);
e = instrumentExpr(ensureBlockExpr(e));
var branchesInfo:BranchesInfo = makeBranchesInfo(expr);
e = coverBranch(instrumentExpr(ensureBlockExpr(e)), e.pos, branchesInfo);
{expr: EFor(it, e), pos: expr.pos};

case EWhile(econd, e, normal):
Expand Down Expand Up @@ -595,16 +596,33 @@ class Instrumentation {
var branchesInfo:BranchesInfo = makeBranchesInfo(expr);

e = instrumentExpr(e);
if ((edef != null) && (edef.expr != null)) {
edef = coverBranch(instrumentExpr(ensureBlockExpr(edef)), expr.pos, branchesInfo);
if (edef != null) {
if (edef.expr != null) {
edef = coverBranch(instrumentExpr(ensureBlockExpr(edef)), expr.pos, branchesInfo);
} else {
// unfortunately empty default branch does not have a position we can use
edef = coverBranch(null, e.pos, branchesInfo);
}
}

for (c in cases) {
if (c.expr == null) {
c.expr = coverBranch(null, expr.pos, branchesInfo);
var pos = expr.pos;
var refExpr = null;
if (c.values.length > 0) {
var pos1 = PositionTools.getInfos(c.values[0].pos);
var pos2 = PositionTools.getInfos(c.values[c.values.length - 1].pos);
pos = PositionTools.make({
file: pos1.file,
min: pos1.min,
max: pos2.max
});
refExpr = logExpression(c.values[0]);
}
c.expr = coverBranch(refExpr, pos, branchesInfo);
continue;
}
c.expr = coverBranch(instrumentExpr(ensureBlockExpr(c.expr)), expr.pos, branchesInfo);
c.expr = coverBranch(instrumentExpr(ensureBlockExpr(c.expr)), c.expr.pos, branchesInfo);
}
{expr: ESwitch(e, cases, edef), pos: expr.pos};

Expand Down Expand Up @@ -883,8 +901,13 @@ class Instrumentation {
case Coverage:
case Both:
}
var location:Location = PositionTools.toLocation(cond.pos);
var location:Location = PositionTools.toLocation(ifExpr.pos);
var branchTrue:BranchInfo = new BranchInfo(coverageContext.nextId(), location.locationToString(), location.range.start.line, location.range.end.line);
if (elseExpr == null) {
location = PositionTools.toLocation(cond.pos);
} else {
location = PositionTools.toLocation(elseExpr.pos);
}
var branchFalse:BranchInfo = new BranchInfo(coverageContext.nextId(), location.locationToString(), location.range.start.line, location.range.end.line);
branchesInfo.addBranch(branchTrue);
branchesInfo.addBranch(branchFalse);
Expand Down
8 changes: 6 additions & 2 deletions src/instrument/coverage/BranchesInfo.hx
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,12 @@ class BranchesInfo {

function calcLineCoverage() {
var lineCov:LineCoverage = new LineCoverage();
for (branch in branches) {
lineCov.addlines(branch.startLine, branch.endLine, branch.isCovered());
if (!isCovered()) {
lineCov.addlines(startLine, endLine, false);
} else {
for (branch in branches) {
lineCov.addlines(branch.startLine, branch.endLine, branch.isCovered());
}
}
lineCount = lineCov.lineCount();
linesCovered = lineCov.coveredLines.length;
Expand Down
17 changes: 10 additions & 7 deletions src/instrument/coverage/FieldInfo.hx
Original file line number Diff line number Diff line change
Expand Up @@ -69,13 +69,16 @@ class FieldInfo {

function calcLineCoverage() {
var lineCov:LineCoverage = new LineCoverage();

for (expression in expressions) {
lineCov.addlines(expression.startLine, expression.endLine, expression.isCovered());
}
for (branch in branches) {
for (b in branch.branches) {
lineCov.addlines(b.startLine, b.endLine, b.isCovered());
if (!isCovered()) {
lineCov.addlines(startLine, endLine, false);
} else {
for (branch in branches) {
for (b in branch.branches) {
lineCov.addlines(b.startLine, b.endLine, b.isCovered());
}
}
for (expression in expressions) {
lineCov.addlines(expression.startLine, expression.endLine, expression.isCovered());
}
}
lineCount = lineCov.lineCount();
Expand Down
58 changes: 21 additions & 37 deletions src/instrument/coverage/reporter/LcovCoverageReporter.hx
Original file line number Diff line number Diff line change
Expand Up @@ -82,58 +82,42 @@ class LcovCoverageReporter extends FileBaseReporter implements ICoverageReporter
for (type in types) {
final fileName = type.location.substring(0, type.location.indexOf(":"));
for (field in type.fields) {
if (!field.location.startsWith(fileName)) {
continue;
}
if (maxLineNumber < field.endLine) {
maxLineNumber = field.endLine;
}
if (!field.isCovered()) {
if (!field.location.startsWith(fileName)) {
continue;
}
for (line in field.startLine...field.endLine + 1) {
var count:Int = 0;
if (!lineCov.exists(line)) {
lineCov.set(line, 0);
continue;
}
count = lineCov.get(line).sure();
lineCov.set(line, 0);
}
if (maxLineNumber < field.endLine) {
maxLineNumber = field.endLine;
}
continue;
}
for (expr in field.expressions) {
if (expr.location.startsWith(fileName)) {
for (line in expr.startLine...expr.endLine + 1) {
var count:Int = 0;
if (!lineCov.exists(line)) {
lineCov.set(line, expr.count);
continue;
}
count = lineCov.get(line).sure();
if (count <= expr.count) {
continue;
}
if (maxLineNumber < expr.endLine) {
maxLineNumber = expr.endLine;
}
for (line in expr.startLine...expr.endLine + 1) {
var count:Int = 0;
if (!lineCov.exists(line)) {
lineCov.set(line, expr.count);
continue;
}
if (maxLineNumber < expr.endLine) {
maxLineNumber = expr.endLine;
count = lineCov.get(line).sure();
if (count <= expr.count) {
continue;
}
lineCov.set(line, expr.count);
}
}
}
}
for (type in types) {
final fileName = type.location.substring(0, type.location.indexOf(":"));
for (field in type.fields) {

for (branches in field.branches) {
if (!branches.location.startsWith(fileName)) {
continue;
}
for (branch in branches.branches) {
if (branch.count > 0) {
continue;
}
for (line in branch.startLine...branch.endLine + 1) {
lineCov.set(line, branch.count);
if (branch.count > 0) {
lineCov.set(line, branch.count);
}
}
if (maxLineNumber < branch.endLine) {
maxLineNumber = branch.endLine;
Expand Down

0 comments on commit e7c5c3d

Please sign in to comment.