Skip to content
This repository was archived by the owner on Nov 19, 2024. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,21 @@ public String formatValueWithMetric(final Value value) {
+ format(value, Functions.getCurrentLocale());
}

/**
* Returns a formatted and localized String representation of the specified value prefixed with the metric name.
* The value will be printed with all details (number of covered and missed items).
*
* @param value
* the value to format
*
* @return the value formatted as a string
*/
@SuppressWarnings("unused") // Called by jelly view
public String formatDetailedValueWithMetric(final Value value) {
return getDisplayName(value.getMetric()) + ": "
+ formatDetails(value, Functions.getCurrentLocale());
}

/**
* Transforms percentages with a ',' decimal separator to a representation using a '.' in order to use the
* percentage for styling HTML tags.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,23 @@ public Baseline getDeltaBaseline(final Baseline baseline) {
throw new NoSuchElementException("No delta baseline for this baseline: " + baseline);
}

/**
* Returns the title text for the specified baseline.
*
* @param baseline
* the baseline to get the title for
*
* @return the title
*/
public String getTitle(final Baseline baseline) {
if (hasDelta(baseline)) {
return getDeltaBaseline(baseline).getTitle();
}
else {
return baseline.getTitle();
}
}

/**
* Returns all available values for the specified baseline.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@
import java.util.Collections;
import java.util.List;
import java.util.NavigableMap;
import java.util.NavigableSet;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.stream.Collectors;

import org.apache.commons.lang3.math.Fraction;
Expand All @@ -14,6 +17,7 @@
import edu.hm.hafner.coverage.FileNode;
import edu.hm.hafner.coverage.Metric;
import edu.hm.hafner.coverage.Node;
import edu.hm.hafner.coverage.Value;
import edu.hm.hafner.util.VisibleForTesting;

import hudson.Functions;
Expand Down Expand Up @@ -87,20 +91,48 @@ ChecksDetails extractChecksDetails() {
.withName(checksName)
.withStatus(ChecksStatus.COMPLETED)
.withConclusion(getCheckConclusion(action.getQualityGateResult().getOverallStatus()))
.withDetailsURL(getCoverageReportBaseUrl())
.withDetailsURL(getBaseUrl())
.withOutput(output)
.build();
}

private String getChecksTitle() {
return String.format("%s: %s",
FORMATTER.getDisplayName(Baseline.MODIFIED_LINES),
action.formatValue(Baseline.MODIFIED_LINES, Metric.LINE));
Baseline baseline = selectBaseline();
return getMetricsForTitle().stream()
.filter(metric -> action.hasValue(baseline, metric))
.map(metric -> format(baseline, metric))
.collect(Collectors.joining(", ", "", "."));
}

private Baseline selectBaseline() {
if (action.hasBaselineResult(Baseline.MODIFIED_LINES)) {
return Baseline.MODIFIED_LINES;
}
else {
return Baseline.PROJECT;
}
}

private String format(final Baseline baseline, final Metric metric) {
String suffix;
if (action.hasDelta(baseline, metric)) {
suffix = String.format(" (%s)", action.formatDelta(baseline, metric));
}
else {
suffix = "";
}
return String.format("%s: %s%s",
FORMATTER.getDisplayName(metric), action.formatValue(baseline, metric), suffix);
}

private NavigableSet<Metric> getMetricsForTitle() {
return new TreeSet<>(
Set.of(Metric.LINE, Metric.BRANCH, Metric.MUTATION));
}

private String getSummary() {
var root = rootNode;
return getOverallCoverageSummary(root) + "\n\n"
return getOverallCoverageSummary() + "\n\n"
+ getQualityGatesSummary() + "\n\n"
+ getProjectMetricsSummary(root);
}
Expand Down Expand Up @@ -132,7 +164,10 @@ private Collection<? extends ChecksAnnotation> getMissingLines(final FileNode fi
var builder = createAnnotationBuilder(fileNode).withTitle("Not covered line");

return fileNode.getMissedLines().stream()
.map(line -> builder.withMessage("Line " + line + " is not covered by tests").withStartLine(line).build())
.map(line -> builder.withMessage("Line " + line + " is not covered by tests")
.withStartLine(line)
.withEndLine(line)
.build())
.collect(Collectors.toList());
}

Expand All @@ -141,7 +176,9 @@ private Collection<? extends ChecksAnnotation> getSurvivedMutations(final FileNo

return fileNode.getSurvivedMutations().entrySet().stream()
.map(entry -> builder.withMessage(createMutationMessage(entry.getKey(), entry.getValue()))
.withStartLine(entry.getKey()).build())
.withStartLine(entry.getKey())
.withEndLine(entry.getKey())
.build())
.collect(Collectors.toList());
}

Expand All @@ -157,7 +194,9 @@ private Collection<? extends ChecksAnnotation> getPartiallyCoveredLines(final Fi

return fileNode.getPartiallyCoveredLines().entrySet().stream()
.map(entry -> builder.withMessage(createBranchMessage(entry.getKey(), entry.getValue()))
.withStartLine(entry.getKey()).build())
.withStartLine(entry.getKey())
.withEndLine(entry.getKey())
.build())
.collect(Collectors.toList());
}

Expand All @@ -175,79 +214,32 @@ private ChecksAnnotationBuilder createAnnotationBuilder(final FileNode fileNode)
.withAnnotationLevel(ChecksAnnotationLevel.WARNING);
}

private String getCoverageReportBaseUrl() {
private String getBaseUrl() {
return jenkinsFacade.getAbsoluteUrl(action.getOwner().getUrl(), action.getUrlName());
}

private String getOverallCoverageSummary(final Node root) {
String sectionHeader = getSectionHeader(2, Messages.Checks_Summary());

var modifiedFilesCoverageRoot = root.filterByModifiedFiles();
var modifiedLinesCoverageRoot = root.filterByModifiedLines();
var indirectlyChangedCoverage = root.filterByIndirectChanges();

var projectCoverageHeader = getBulletListItem(1,
formatText(TextFormat.BOLD, getUrlText(Baseline.PROJECT_DELTA.getTitle(),
getCoverageReportBaseUrl() + Baseline.PROJECT_DELTA.getUrl())));
var modifiedFilesCoverageHeader = getBulletListItem(1,
formatText(TextFormat.BOLD, getUrlText(Baseline.MODIFIED_FILES_DELTA.getTitle(),
getCoverageReportBaseUrl() + Baseline.MODIFIED_FILES_DELTA.getUrl())));
var modifiedLinesCoverageHeader = getBulletListItem(1,
formatText(TextFormat.BOLD, getUrlText(Baseline.MODIFIED_LINES_DELTA.getTitle(),
getCoverageReportBaseUrl() + Baseline.MODIFIED_LINES_DELTA.getUrl())));
var indirectCoverageChangesHeader = getBulletListItem(1,
formatText(TextFormat.BOLD, getUrlText(Baseline.INDIRECT.getTitle(),
getCoverageReportBaseUrl() + Baseline.INDIRECT.getUrl())));

var projectCoverageLine = getBulletListItem(2,
formatCoverageForMetric(Metric.LINE, Baseline.PROJECT));
var projectCoverageBranch = getBulletListItem(2,
formatCoverageForMetric(Metric.BRANCH, Baseline.PROJECT));
var projectCoverageComplexity = getBulletListItem(2, formatRootValueOfMetric(root, Metric.COMPLEXITY_DENSITY));
var projectCoverageLoc = getBulletListItem(2, formatRootValueOfMetric(root, Metric.LOC));

var modifiedFilesCoverageLine = getBulletListItem(2,
formatCoverageForMetric(Metric.LINE, Baseline.MODIFIED_FILES));
var modifiedFilesCoverageBranch = getBulletListItem(2,
formatCoverageForMetric(Metric.BRANCH, Baseline.MODIFIED_FILES));
var modifiedFilesCoverageComplexity = getBulletListItem(2,
formatRootValueOfMetric(modifiedFilesCoverageRoot, Metric.COMPLEXITY_DENSITY));
var modifiedFilesCoverageLoc = getBulletListItem(2,
formatRootValueOfMetric(modifiedFilesCoverageRoot, Metric.LOC));

var modifiedLinesCoverageLine = getBulletListItem(2,
formatCoverageForMetric(Metric.LINE, Baseline.MODIFIED_LINES));
var modifiedLinesCoverageBranch = getBulletListItem(2,
formatCoverageForMetric(Metric.BRANCH, Baseline.MODIFIED_LINES));
var modifiedLinesCoverageLoc = getBulletListItem(2,
formatRootValueOfMetric(modifiedLinesCoverageRoot, Metric.LOC));

var indirectCoverageChangesLine = getBulletListItem(2,
formatCoverageForMetric(Metric.LINE, Baseline.INDIRECT));
var indirectCoverageChangesBranch = getBulletListItem(2,
formatCoverageForMetric(Metric.BRANCH, Baseline.INDIRECT));
var indirectCoverageChangesLoc = getBulletListItem(2,
formatRootValueOfMetric(indirectlyChangedCoverage, Metric.LOC));
private List<Baseline> getBaselines() {
return List.of(Baseline.PROJECT, Baseline.MODIFIED_FILES, Baseline.MODIFIED_LINES, Baseline.INDIRECT);
}

return sectionHeader
+ projectCoverageHeader
+ projectCoverageLine
+ projectCoverageBranch
+ projectCoverageComplexity
+ projectCoverageLoc
+ modifiedFilesCoverageHeader
+ modifiedFilesCoverageLine
+ modifiedFilesCoverageBranch
+ modifiedFilesCoverageComplexity
+ modifiedFilesCoverageLoc
+ modifiedLinesCoverageHeader
+ modifiedLinesCoverageLine
+ modifiedLinesCoverageBranch
+ modifiedLinesCoverageLoc
+ indirectCoverageChangesHeader
+ indirectCoverageChangesLine
+ indirectCoverageChangesBranch
+ indirectCoverageChangesLoc;
private String getOverallCoverageSummary() {
StringBuilder description = new StringBuilder(getSectionHeader(2, Messages.Checks_Summary()));

for (Baseline baseline : getBaselines()) {
if (action.hasBaselineResult(baseline)) {
description.append(getBulletListItem(1,
formatText(TextFormat.BOLD,
getUrlText(action.getTitle(baseline), getBaseUrl() + baseline.getUrl()))));
for (Value value : action.getValues(baseline)) {
String display = FORMATTER.formatDetailedValueWithMetric(value);
if (action.hasDelta(baseline, value.getMetric())) {
display += String.format(" - Delta: %s", action.formatDelta(baseline, value.getMetric()));
}
description.append(getBulletListItem(2, display));
}
}
}
return description.toString();
}

/**
Expand Down Expand Up @@ -289,17 +281,6 @@ private String getProjectMetricsSummary(final Node result) {
+ projectCoverageDeltaRow;
}

private String formatCoverageForMetric(final Metric metric, final Baseline baseline) {
return String.format("%s: %s / %s", FORMATTER.getDisplayName(metric),
action.formatValue(baseline, metric), action.formatDelta(baseline, metric));
}

private String formatRootValueOfMetric(final Node root, final Metric metric) {
var value = root.getValue(metric);
return value.map(FORMATTER::formatValueWithMetric)
.orElseGet(() -> FORMATTER.getDisplayName(metric) + ": " + Messages.Coverage_Not_Available());
}

private String formatText(final TextFormat format, final String text) {
switch (format) {
case BOLD:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@ public class CoverageViewModel extends DefaultAsyncTableContentProvider implemen

static final String ABSOLUTE_COVERAGE_TABLE_ID = "absolute-coverage-table";
static final String MODIFIED_LINES_COVERAGE_TABLE_ID = "modified-lines-coverage-table";
static final String MODIFIED_FILES_COVERAGE_TABLE_ID = "modified-files-coverage-table";
static final String INDIRECT_COVERAGE_TABLE_ID = "indirect-coverage-table";
private static final String INLINE_SUFFIX = "-inline";
private static final String INFO_MESSAGES_VIEW_URL = "info";
Expand Down
9 changes: 1 addition & 8 deletions plugin/src/main/resources/coverage/coverage-summary.jelly
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,7 @@

<j:if test="${it.hasBaselineResult(baseline)}">
<li>
<j:choose>
<j:when test="${it.hasDelta(baseline)}">
<a href="${it.urlName}/#${baseline.url}">${it.getDeltaBaseline(baseline).title}</a>
</j:when>
<j:otherwise>
<a href="${it.urlName}/#${baseline.url}">${baseline.title}</a>
</j:otherwise>
</j:choose>
<a href="${it.urlName}/#${baseline.url}">${it.getTitle(baseline)}</a>
<div class="${baseline}-summary">
<j:set var="values" value="${it.getAllValues(baseline)}"/>
<j:set var="formatter" value="${it.formatter}"/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import org.junitpioneer.jupiter.DefaultLocale;

import edu.hm.hafner.coverage.Coverage.CoverageBuilder;
import edu.hm.hafner.coverage.CoverageParser;
import edu.hm.hafner.coverage.Metric;
import edu.hm.hafner.coverage.Node;
import edu.hm.hafner.coverage.Value;
Expand Down Expand Up @@ -50,8 +51,22 @@ public abstract class AbstractCoverageTest extends ResourceTest {
* @return the parsed coverage tree
*/
protected Node readJacocoResult(final String fileName) {
return readResult(fileName, new JacocoParser());
}

/**
* Reads and parses a JaCoCo coverage report.
*
* @param fileName
* the name of the coverage report file
* @param parser
* the parser to use
*
* @return the parsed coverage tree
*/
protected Node readResult(final String fileName, final CoverageParser parser) {
try {
var node = new JacocoParser().parse(Files.newBufferedReader(getResourceAsFile(fileName)), log);
var node = parser.parse(Files.newBufferedReader(getResourceAsFile(fileName)), log);
node.splitPackages();
return node;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,12 @@
* @author Ullrich Hafner
*/
class TreeMapNodeConverterTest extends AbstractCoverageTest {

private static final ColorProvider COLOR_PROVIDER = ColorProviderFactory.createDefaultColorProvider();
private static final String PREFIX = "../steps/";

@Test
void shouldConvertCodingStyleToTree() {
Node tree = readJacocoResult(JACOCO_CODING_STYLE_FILE);
Node tree = readJacocoResult(PREFIX + JACOCO_CODING_STYLE_FILE);

LabeledTreeMapNode root = new TreeMapNodeConverter().toTreeChartModel(tree, Metric.LINE, COLOR_PROVIDER);
assertThat(root.getName()).isEqualTo("Java coding style");
Expand All @@ -49,7 +49,7 @@ void shouldConvertCodingStyleToTree() {

@Test
void shouldReadBranchCoverage() {
Node tree = readJacocoResult(JACOCO_ANALYSIS_MODEL_FILE);
Node tree = readJacocoResult(PREFIX + JACOCO_ANALYSIS_MODEL_FILE);

LabeledTreeMapNode root = new TreeMapNodeConverter().toTreeChartModel(tree, Metric.BRANCH, COLOR_PROVIDER);

Expand All @@ -69,11 +69,6 @@ private List<LabeledTreeMapNode> aggregateChildren(final LabeledTreeMapNode root
return subChildren;
}

@Override
protected Node readJacocoResult(final String fileName) {
return super.readJacocoResult("../steps/" + fileName);
}

/**
* Gets the matching fill color for the coverage percentage.
*
Expand Down
Loading