Skip to content

Commit

Permalink
Merge pull request #148 from jenkinsci/round-percentage
Browse files Browse the repository at this point in the history
Round percentages
  • Loading branch information
uhafner authored Feb 13, 2025
2 parents 318926f + 42c92de commit e3f4194
Show file tree
Hide file tree
Showing 16 changed files with 806 additions and 151 deletions.
51 changes: 42 additions & 9 deletions src/main/java/edu/hm/hafner/coverage/Coverage.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ public final class Coverage extends Value {
@Serial
private static final long serialVersionUID = -3802318446471137305L;
private static final String FRACTION_SEPARATOR = "/";
private static final String N_A = "n/a";

/**
* Creates a new {@link Coverage} instance from the provided string representation. The string representation is
Expand Down Expand Up @@ -129,7 +130,7 @@ public int getMissed() {

@Override
public Coverage add(final Value other) {
var otherCoverage = ensureSameMetricAndType(other);
var otherCoverage = castValue(other);

return new CoverageBuilder().withMetric(getMetric())
.withCovered(getCovered() + otherCoverage.getCovered())
Expand All @@ -138,15 +139,15 @@ public Coverage add(final Value other) {
}

@Override
public Fraction delta(final Value other) {
var otherCoverage = ensureSameMetricAndType(other);
public Difference subtract(final Value other) {
ensureSameMetricAndType(other);

return getCoveredPercentage().subtract(otherCoverage.getCoveredPercentage());
return new Difference(getMetric(), asDouble() - other.asDouble());
}

@Override
public Coverage max(final Value other) {
var otherCoverage = ensureSameMetricAndType(other);
var otherCoverage = castValue(other);
Ensure.that(getTotal() == otherCoverage.getTotal())
.isTrue("Cannot compute maximum of coverages %s and %s since total differs",
this, other);
Expand All @@ -157,8 +158,9 @@ public Coverage max(final Value other) {
return otherCoverage;
}

private Coverage ensureSameMetricAndType(final Value other) {
ensureSameMetric(other);
private Coverage castValue(final Value other) {
ensureSameMetricAndType(other);

return (Coverage) other; // the type is checked in ensureSameMetric
}

Expand All @@ -184,6 +186,37 @@ public boolean isSet() {
return getTotal() > 0;
}

@Override
public String asText(final Locale locale) {
if (isSet()) {

Check warning on line 191 in src/main/java/edu/hm/hafner/coverage/Coverage.java

View workflow job for this annotation

GitHub Actions / Quality Monitor

Partially covered line

Line 191 is only partially covered, one branch is missing
return String.format(locale, "%.2f%%", asRounded());
}
return N_A;

Check warning on line 194 in src/main/java/edu/hm/hafner/coverage/Coverage.java

View workflow job for this annotation

GitHub Actions / Quality Monitor

Not covered line

Line 194 is not covered by tests

Check warning on line 194 in src/main/java/edu/hm/hafner/coverage/Coverage.java

View workflow job for this annotation

GitHub Actions / Quality Monitor

Not covered line

Line 194 is not covered by tests
}

@Override
public String asInformativeText(final Locale locale) {
if (isSet()) {

Check warning on line 199 in src/main/java/edu/hm/hafner/coverage/Coverage.java

View workflow job for this annotation

GitHub Actions / Quality Monitor

Partially covered line

Line 199 is only partially covered, one branch is missing
return String.format(locale, "%.2f%% (%d/%d)", asRounded(), getCovered(), getTotal());
}
return N_A;

Check warning on line 202 in src/main/java/edu/hm/hafner/coverage/Coverage.java

View workflow job for this annotation

GitHub Actions / Quality Monitor

Not covered line

Line 202 is not covered by tests

Check warning on line 202 in src/main/java/edu/hm/hafner/coverage/Coverage.java

View workflow job for this annotation

GitHub Actions / Quality Monitor

Not covered line

Line 202 is not covered by tests
}

@Override
public int asInteger() {
return getCoveredPercentage().toInt();
}

@Override
public double asDouble() {
return getCoveredPercentage().toDouble();
}

@Override
protected String serializeValue() {
return String.format(Locale.ENGLISH, "%d/%d", getCovered(), getTotal());
}

@Override
@Generated
public boolean equals(final Object o) {
Expand Down Expand Up @@ -216,8 +249,8 @@ public String toString() {
}

@Override
public String asText() {
return String.format(Locale.ENGLISH, "%d/%d", getCovered(), getTotal());
public double asRounded() {
return getCoveredPercentage().toRounded();
}

/**
Expand Down
97 changes: 97 additions & 0 deletions src/main/java/edu/hm/hafner/coverage/Difference.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package edu.hm.hafner.coverage;

import java.io.Serial;
import java.util.Locale;

import org.apache.commons.lang3.math.Fraction;

/**
* A leaf in the tree that represents a delta of two {@link Value} instances. Such values are used to show the
* delta (i.e., the difference) of two other values. The delta uses a slightly different textual representation than the
* plain value: positive values are prefixed with a plus sign, zero is also handled differently.
*
* @author Ullrich Hafner
*/
public class Difference extends Value {
@Serial
private static final long serialVersionUID = -1115727256219835389L;
/** Serialization prefix for delta values. */
public static final String DELTA = "Δ";

/**
* Returns a {@code null} object that indicates that no value has been recorded.
*
* @param metric
* the coverage metric
*
* @return the {@code null} object
*/
public static Difference nullObject(final Metric metric) {
return new Difference(metric, 0);
}

/**
* Creates a new leaf with the given value for the specified metric.
*
* @param metric
* the coverage metric
* @param value
* the value to store
*/
public Difference(final Metric metric, final Fraction value) {
super(metric, value);
}

/**
* Creates a new leaf with the given value for the specified metric.
*
* @param metric
* the coverage metric
* @param value
* the value to store
*/
public Difference(final Metric metric, final double value) {
super(metric, value);
}

/**
* Creates a new leaf with the given value (a fraction) for the specified metric.
*
* @param metric
* the coverage metric
* @param numerator
* the numerator, i.e., the three in 'three sevenths'
* @param denominator
* the denominator, i.ee, the seven in 'three sevenths'
*/
public Difference(final Metric metric, final int numerator, final int denominator) {
super(metric, numerator, denominator);
}

/**
* Creates a new leaf with the given value for the specified metric.
*
* @param metric
* the coverage metric
* @param value
* the value
*/
public Difference(final Metric metric, final int value) {
super(metric, value);
}

@Override
public String asText(final Locale locale) {
return getMetric().formatDelta(locale, asDouble());
}

@Override
public String asInformativeText(final Locale locale) {
return getMetric().formatDelta(locale, asDouble());
}

@Override
protected String serializeValue() {
return DELTA + super.serializeValue();
}
}
9 changes: 4 additions & 5 deletions src/main/java/edu/hm/hafner/coverage/FileNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@

import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.Fraction;

import com.google.errorprone.annotations.CanIgnoreReturnValue;

Expand Down Expand Up @@ -58,7 +57,7 @@ public final class FileNode extends Node {

private final SortedSet<Integer> modifiedLines = new TreeSet<>();
private final NavigableMap<Integer, Integer> indirectCoverageChanges = new TreeMap<>();
private final NavigableMap<Metric, Fraction> coverageDelta = new TreeMap<>();
private final NavigableMap<Metric, Value> coverageDelta = new TreeMap<>();

private TreeString relativePath; // @since 0.22.0

Expand Down Expand Up @@ -536,7 +535,7 @@ public void computeDelta(final FileNode referenceFile) {
NavigableMap<Metric, Value> referenceCoverage = referenceFile.getMetricsDistribution();
getMetricsDistribution().forEach((metric, value) -> {
if (referenceCoverage.containsKey(metric)) {
coverageDelta.put(metric, value.delta(referenceCoverage.get(metric)));
coverageDelta.put(metric, value.subtract(referenceCoverage.get(metric)));
}
});
}
Expand All @@ -550,8 +549,8 @@ public void computeDelta(final FileNode referenceFile) {
*
* @return the delta for the specified metric
*/
public Fraction getDelta(final Metric metric) {
return coverageDelta.getOrDefault(metric, Fraction.ZERO);
public Value getDelta(final Metric metric) {
return coverageDelta.getOrDefault(metric, Value.nullObject(metric));
}

/**
Expand Down
Loading

0 comments on commit e3f4194

Please sign in to comment.