Skip to content
This repository was archived by the owner on Nov 19, 2024. It is now read-only.

Commit d45b444

Browse files
authored
Merge pull request #587 from jenkinsci/skip-not-existing-checks-details
Improve checks title and content
2 parents 261c3f2 + 5078829 commit d45b444

File tree

10 files changed

+194
-127
lines changed

10 files changed

+194
-127
lines changed

plugin/src/main/java/io/jenkins/plugins/coverage/metrics/model/ElementFormatter.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,21 @@ public String formatValueWithMetric(final Value value) {
226226
+ format(value, Functions.getCurrentLocale());
227227
}
228228

229+
/**
230+
* Returns a formatted and localized String representation of the specified value prefixed with the metric name.
231+
* The value will be printed with all details (number of covered and missed items).
232+
*
233+
* @param value
234+
* the value to format
235+
*
236+
* @return the value formatted as a string
237+
*/
238+
@SuppressWarnings("unused") // Called by jelly view
239+
public String formatDetailedValueWithMetric(final Value value) {
240+
return getDisplayName(value.getMetric()) + ": "
241+
+ formatDetails(value, Functions.getCurrentLocale());
242+
}
243+
229244
/**
230245
* Transforms percentages with a ',' decimal separator to a representation using a '.' in order to use the
231246
* percentage for styling HTML tags.

plugin/src/main/java/io/jenkins/plugins/coverage/metrics/steps/CoverageBuildAction.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,23 @@ public Baseline getDeltaBaseline(final Baseline baseline) {
277277
throw new NoSuchElementException("No delta baseline for this baseline: " + baseline);
278278
}
279279

280+
/**
281+
* Returns the title text for the specified baseline.
282+
*
283+
* @param baseline
284+
* the baseline to get the title for
285+
*
286+
* @return the title
287+
*/
288+
public String getTitle(final Baseline baseline) {
289+
if (hasDelta(baseline)) {
290+
return getDeltaBaseline(baseline).getTitle();
291+
}
292+
else {
293+
return baseline.getTitle();
294+
}
295+
}
296+
280297
/**
281298
* Returns all available values for the specified baseline.
282299
*

plugin/src/main/java/io/jenkins/plugins/coverage/metrics/steps/CoverageChecksPublisher.java

Lines changed: 69 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@
55
import java.util.Collections;
66
import java.util.List;
77
import java.util.NavigableMap;
8+
import java.util.NavigableSet;
9+
import java.util.Set;
810
import java.util.TreeMap;
11+
import java.util.TreeSet;
912
import java.util.stream.Collectors;
1013

1114
import org.apache.commons.lang3.math.Fraction;
@@ -14,6 +17,7 @@
1417
import edu.hm.hafner.coverage.FileNode;
1518
import edu.hm.hafner.coverage.Metric;
1619
import edu.hm.hafner.coverage.Node;
20+
import edu.hm.hafner.coverage.Value;
1721
import edu.hm.hafner.util.VisibleForTesting;
1822

1923
import hudson.Functions;
@@ -87,20 +91,48 @@ ChecksDetails extractChecksDetails() {
8791
.withName(checksName)
8892
.withStatus(ChecksStatus.COMPLETED)
8993
.withConclusion(getCheckConclusion(action.getQualityGateResult().getOverallStatus()))
90-
.withDetailsURL(getCoverageReportBaseUrl())
94+
.withDetailsURL(getBaseUrl())
9195
.withOutput(output)
9296
.build();
9397
}
9498

9599
private String getChecksTitle() {
96-
return String.format("%s: %s",
97-
FORMATTER.getDisplayName(Baseline.MODIFIED_LINES),
98-
action.formatValue(Baseline.MODIFIED_LINES, Metric.LINE));
100+
Baseline baseline = selectBaseline();
101+
return getMetricsForTitle().stream()
102+
.filter(metric -> action.hasValue(baseline, metric))
103+
.map(metric -> format(baseline, metric))
104+
.collect(Collectors.joining(", ", "", "."));
105+
}
106+
107+
private Baseline selectBaseline() {
108+
if (action.hasBaselineResult(Baseline.MODIFIED_LINES)) {
109+
return Baseline.MODIFIED_LINES;
110+
}
111+
else {
112+
return Baseline.PROJECT;
113+
}
114+
}
115+
116+
private String format(final Baseline baseline, final Metric metric) {
117+
String suffix;
118+
if (action.hasDelta(baseline, metric)) {
119+
suffix = String.format(" (%s)", action.formatDelta(baseline, metric));
120+
}
121+
else {
122+
suffix = "";
123+
}
124+
return String.format("%s: %s%s",
125+
FORMATTER.getDisplayName(metric), action.formatValue(baseline, metric), suffix);
126+
}
127+
128+
private NavigableSet<Metric> getMetricsForTitle() {
129+
return new TreeSet<>(
130+
Set.of(Metric.LINE, Metric.BRANCH, Metric.MUTATION));
99131
}
100132

101133
private String getSummary() {
102134
var root = rootNode;
103-
return getOverallCoverageSummary(root) + "\n\n"
135+
return getOverallCoverageSummary() + "\n\n"
104136
+ getQualityGatesSummary() + "\n\n"
105137
+ getProjectMetricsSummary(root);
106138
}
@@ -132,7 +164,10 @@ private Collection<? extends ChecksAnnotation> getMissingLines(final FileNode fi
132164
var builder = createAnnotationBuilder(fileNode).withTitle("Not covered line");
133165

134166
return fileNode.getMissedLines().stream()
135-
.map(line -> builder.withMessage("Line " + line + " is not covered by tests").withStartLine(line).build())
167+
.map(line -> builder.withMessage("Line " + line + " is not covered by tests")
168+
.withStartLine(line)
169+
.withEndLine(line)
170+
.build())
136171
.collect(Collectors.toList());
137172
}
138173

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

142177
return fileNode.getSurvivedMutations().entrySet().stream()
143178
.map(entry -> builder.withMessage(createMutationMessage(entry.getKey(), entry.getValue()))
144-
.withStartLine(entry.getKey()).build())
179+
.withStartLine(entry.getKey())
180+
.withEndLine(entry.getKey())
181+
.build())
145182
.collect(Collectors.toList());
146183
}
147184

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

158195
return fileNode.getPartiallyCoveredLines().entrySet().stream()
159196
.map(entry -> builder.withMessage(createBranchMessage(entry.getKey(), entry.getValue()))
160-
.withStartLine(entry.getKey()).build())
197+
.withStartLine(entry.getKey())
198+
.withEndLine(entry.getKey())
199+
.build())
161200
.collect(Collectors.toList());
162201
}
163202

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

178-
private String getCoverageReportBaseUrl() {
217+
private String getBaseUrl() {
179218
return jenkinsFacade.getAbsoluteUrl(action.getOwner().getUrl(), action.getUrlName());
180219
}
181220

182-
private String getOverallCoverageSummary(final Node root) {
183-
String sectionHeader = getSectionHeader(2, Messages.Checks_Summary());
184-
185-
var modifiedFilesCoverageRoot = root.filterByModifiedFiles();
186-
var modifiedLinesCoverageRoot = root.filterByModifiedLines();
187-
var indirectlyChangedCoverage = root.filterByIndirectChanges();
188-
189-
var projectCoverageHeader = getBulletListItem(1,
190-
formatText(TextFormat.BOLD, getUrlText(Baseline.PROJECT_DELTA.getTitle(),
191-
getCoverageReportBaseUrl() + Baseline.PROJECT_DELTA.getUrl())));
192-
var modifiedFilesCoverageHeader = getBulletListItem(1,
193-
formatText(TextFormat.BOLD, getUrlText(Baseline.MODIFIED_FILES_DELTA.getTitle(),
194-
getCoverageReportBaseUrl() + Baseline.MODIFIED_FILES_DELTA.getUrl())));
195-
var modifiedLinesCoverageHeader = getBulletListItem(1,
196-
formatText(TextFormat.BOLD, getUrlText(Baseline.MODIFIED_LINES_DELTA.getTitle(),
197-
getCoverageReportBaseUrl() + Baseline.MODIFIED_LINES_DELTA.getUrl())));
198-
var indirectCoverageChangesHeader = getBulletListItem(1,
199-
formatText(TextFormat.BOLD, getUrlText(Baseline.INDIRECT.getTitle(),
200-
getCoverageReportBaseUrl() + Baseline.INDIRECT.getUrl())));
201-
202-
var projectCoverageLine = getBulletListItem(2,
203-
formatCoverageForMetric(Metric.LINE, Baseline.PROJECT));
204-
var projectCoverageBranch = getBulletListItem(2,
205-
formatCoverageForMetric(Metric.BRANCH, Baseline.PROJECT));
206-
var projectCoverageComplexity = getBulletListItem(2, formatRootValueOfMetric(root, Metric.COMPLEXITY_DENSITY));
207-
var projectCoverageLoc = getBulletListItem(2, formatRootValueOfMetric(root, Metric.LOC));
208-
209-
var modifiedFilesCoverageLine = getBulletListItem(2,
210-
formatCoverageForMetric(Metric.LINE, Baseline.MODIFIED_FILES));
211-
var modifiedFilesCoverageBranch = getBulletListItem(2,
212-
formatCoverageForMetric(Metric.BRANCH, Baseline.MODIFIED_FILES));
213-
var modifiedFilesCoverageComplexity = getBulletListItem(2,
214-
formatRootValueOfMetric(modifiedFilesCoverageRoot, Metric.COMPLEXITY_DENSITY));
215-
var modifiedFilesCoverageLoc = getBulletListItem(2,
216-
formatRootValueOfMetric(modifiedFilesCoverageRoot, Metric.LOC));
217-
218-
var modifiedLinesCoverageLine = getBulletListItem(2,
219-
formatCoverageForMetric(Metric.LINE, Baseline.MODIFIED_LINES));
220-
var modifiedLinesCoverageBranch = getBulletListItem(2,
221-
formatCoverageForMetric(Metric.BRANCH, Baseline.MODIFIED_LINES));
222-
var modifiedLinesCoverageLoc = getBulletListItem(2,
223-
formatRootValueOfMetric(modifiedLinesCoverageRoot, Metric.LOC));
224-
225-
var indirectCoverageChangesLine = getBulletListItem(2,
226-
formatCoverageForMetric(Metric.LINE, Baseline.INDIRECT));
227-
var indirectCoverageChangesBranch = getBulletListItem(2,
228-
formatCoverageForMetric(Metric.BRANCH, Baseline.INDIRECT));
229-
var indirectCoverageChangesLoc = getBulletListItem(2,
230-
formatRootValueOfMetric(indirectlyChangedCoverage, Metric.LOC));
221+
private List<Baseline> getBaselines() {
222+
return List.of(Baseline.PROJECT, Baseline.MODIFIED_FILES, Baseline.MODIFIED_LINES, Baseline.INDIRECT);
223+
}
231224

232-
return sectionHeader
233-
+ projectCoverageHeader
234-
+ projectCoverageLine
235-
+ projectCoverageBranch
236-
+ projectCoverageComplexity
237-
+ projectCoverageLoc
238-
+ modifiedFilesCoverageHeader
239-
+ modifiedFilesCoverageLine
240-
+ modifiedFilesCoverageBranch
241-
+ modifiedFilesCoverageComplexity
242-
+ modifiedFilesCoverageLoc
243-
+ modifiedLinesCoverageHeader
244-
+ modifiedLinesCoverageLine
245-
+ modifiedLinesCoverageBranch
246-
+ modifiedLinesCoverageLoc
247-
+ indirectCoverageChangesHeader
248-
+ indirectCoverageChangesLine
249-
+ indirectCoverageChangesBranch
250-
+ indirectCoverageChangesLoc;
225+
private String getOverallCoverageSummary() {
226+
StringBuilder description = new StringBuilder(getSectionHeader(2, Messages.Checks_Summary()));
227+
228+
for (Baseline baseline : getBaselines()) {
229+
if (action.hasBaselineResult(baseline)) {
230+
description.append(getBulletListItem(1,
231+
formatText(TextFormat.BOLD,
232+
getUrlText(action.getTitle(baseline), getBaseUrl() + baseline.getUrl()))));
233+
for (Value value : action.getValues(baseline)) {
234+
String display = FORMATTER.formatDetailedValueWithMetric(value);
235+
if (action.hasDelta(baseline, value.getMetric())) {
236+
display += String.format(" - Delta: %s", action.formatDelta(baseline, value.getMetric()));
237+
}
238+
description.append(getBulletListItem(2, display));
239+
}
240+
}
241+
}
242+
return description.toString();
251243
}
252244

253245
/**
@@ -289,17 +281,6 @@ private String getProjectMetricsSummary(final Node result) {
289281
+ projectCoverageDeltaRow;
290282
}
291283

292-
private String formatCoverageForMetric(final Metric metric, final Baseline baseline) {
293-
return String.format("%s: %s / %s", FORMATTER.getDisplayName(metric),
294-
action.formatValue(baseline, metric), action.formatDelta(baseline, metric));
295-
}
296-
297-
private String formatRootValueOfMetric(final Node root, final Metric metric) {
298-
var value = root.getValue(metric);
299-
return value.map(FORMATTER::formatValueWithMetric)
300-
.orElseGet(() -> FORMATTER.getDisplayName(metric) + ": " + Messages.Coverage_Not_Available());
301-
}
302-
303284
private String formatText(final TextFormat format, final String text) {
304285
switch (format) {
305286
case BOLD:

plugin/src/main/java/io/jenkins/plugins/coverage/metrics/steps/CoverageViewModel.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,6 @@ public class CoverageViewModel extends DefaultAsyncTableContentProvider implemen
6868

6969
static final String ABSOLUTE_COVERAGE_TABLE_ID = "absolute-coverage-table";
7070
static final String MODIFIED_LINES_COVERAGE_TABLE_ID = "modified-lines-coverage-table";
71-
static final String MODIFIED_FILES_COVERAGE_TABLE_ID = "modified-files-coverage-table";
7271
static final String INDIRECT_COVERAGE_TABLE_ID = "indirect-coverage-table";
7372
private static final String INLINE_SUFFIX = "-inline";
7473
private static final String INFO_MESSAGES_VIEW_URL = "info";

plugin/src/main/resources/coverage/coverage-summary.jelly

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,7 @@
1010

1111
<j:if test="${it.hasBaselineResult(baseline)}">
1212
<li>
13-
<j:choose>
14-
<j:when test="${it.hasDelta(baseline)}">
15-
<a href="${it.urlName}/#${baseline.url}">${it.getDeltaBaseline(baseline).title}</a>
16-
</j:when>
17-
<j:otherwise>
18-
<a href="${it.urlName}/#${baseline.url}">${baseline.title}</a>
19-
</j:otherwise>
20-
</j:choose>
13+
<a href="${it.urlName}/#${baseline.url}">${it.getTitle(baseline)}</a>
2114
<div class="${baseline}-summary">
2215
<j:set var="values" value="${it.getAllValues(baseline)}"/>
2316
<j:set var="formatter" value="${it.formatter}"/>

plugin/src/test/java/io/jenkins/plugins/coverage/metrics/AbstractCoverageTest.java

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import org.junitpioneer.jupiter.DefaultLocale;
1111

1212
import edu.hm.hafner.coverage.Coverage.CoverageBuilder;
13+
import edu.hm.hafner.coverage.CoverageParser;
1314
import edu.hm.hafner.coverage.Metric;
1415
import edu.hm.hafner.coverage.Node;
1516
import edu.hm.hafner.coverage.Value;
@@ -50,8 +51,22 @@ public abstract class AbstractCoverageTest extends ResourceTest {
5051
* @return the parsed coverage tree
5152
*/
5253
protected Node readJacocoResult(final String fileName) {
54+
return readResult(fileName, new JacocoParser());
55+
}
56+
57+
/**
58+
* Reads and parses a JaCoCo coverage report.
59+
*
60+
* @param fileName
61+
* the name of the coverage report file
62+
* @param parser
63+
* the parser to use
64+
*
65+
* @return the parsed coverage tree
66+
*/
67+
protected Node readResult(final String fileName, final CoverageParser parser) {
5368
try {
54-
var node = new JacocoParser().parse(Files.newBufferedReader(getResourceAsFile(fileName)), log);
69+
var node = parser.parse(Files.newBufferedReader(getResourceAsFile(fileName)), log);
5570
node.splitPackages();
5671
return node;
5772
}

plugin/src/test/java/io/jenkins/plugins/coverage/metrics/charts/TreeMapNodeConverterTest.java

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,12 @@
2222
* @author Ullrich Hafner
2323
*/
2424
class TreeMapNodeConverterTest extends AbstractCoverageTest {
25-
2625
private static final ColorProvider COLOR_PROVIDER = ColorProviderFactory.createDefaultColorProvider();
26+
private static final String PREFIX = "../steps/";
2727

2828
@Test
2929
void shouldConvertCodingStyleToTree() {
30-
Node tree = readJacocoResult(JACOCO_CODING_STYLE_FILE);
30+
Node tree = readJacocoResult(PREFIX + JACOCO_CODING_STYLE_FILE);
3131

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

5050
@Test
5151
void shouldReadBranchCoverage() {
52-
Node tree = readJacocoResult(JACOCO_ANALYSIS_MODEL_FILE);
52+
Node tree = readJacocoResult(PREFIX + JACOCO_ANALYSIS_MODEL_FILE);
5353

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

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

72-
@Override
73-
protected Node readJacocoResult(final String fileName) {
74-
return super.readJacocoResult("../steps/" + fileName);
75-
}
76-
7772
/**
7873
* Gets the matching fill color for the coverage percentage.
7974
*

0 commit comments

Comments
 (0)