Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Round percentages #148

Merged
merged 13 commits into from
Feb 13, 2025
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 @@
@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 @@

@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 @@
}

@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 @@
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 @@
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 check run for this annotation

ci.jenkins.io / Code Coverage

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 check run for this annotation

ci.jenkins.io / Code Coverage

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 check run for this annotation

ci.jenkins.io / Code Coverage

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 check run for this annotation

ci.jenkins.io / Code Coverage

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 @@
}

@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
Loading