Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge pull request #4 from cizezsy/ui
[JENKINS-51368] Modernize report
  • Loading branch information
cizezsy committed May 30, 2018
2 parents c3a07da + aca9b82 commit 0a4f664
Show file tree
Hide file tree
Showing 5 changed files with 556 additions and 115 deletions.
Expand Up @@ -45,7 +45,7 @@ public HealthReport getBuildHealth() {
*
* @return coverage result
*/
private CoverageResult getResult() {
public CoverageResult getResult() {
if (report != null) {
CoverageResult r = report.get();
if (r != null) {
Expand Down
116 changes: 100 additions & 16 deletions src/main/java/io/jenkins/plugins/coverage/targets/CoverageResult.java
Expand Up @@ -25,18 +25,24 @@
import hudson.model.Api;
import hudson.model.Item;
import hudson.model.Run;
import hudson.util.ChartUtil;
import hudson.util.Graph;
import hudson.util.TextFile;
import io.jenkins.plugins.coverage.BuildUtils;
import io.jenkins.plugins.coverage.CoverageAction;
import org.jfree.chart.JFreeChart;
import org.kohsuke.stapler.StaplerRequest;
import org.kohsuke.stapler.StaplerResponse;
import org.kohsuke.stapler.bind.JavaScriptMethod;
import org.kohsuke.stapler.export.Exported;
import org.kohsuke.stapler.export.ExportedBean;

import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
* <p>Coverage result for a specific programming element.</p>
Expand All @@ -53,6 +59,8 @@ public class CoverageResult implements Serializable, Chartable {
*/
private static final long serialVersionUID = -3524882671364156445L;

private static final int DEFAULT_MAX_BUILDS_SHOW_IN_TREND = 6;

/**
* The type of the programming element.
*/
Expand Down Expand Up @@ -240,6 +248,11 @@ public Set<CoverageElement> getChildElements() {
return result;
}

public CoverageElement getChildElement() {
return getChildElements().stream().findAny().orElse(null);
}


public Set<String> getChildren(CoverageElement element) {
Set<String> result = new TreeSet<String>();
for (CoverageResult child : children.values()) {
Expand Down Expand Up @@ -435,22 +448,20 @@ public void setOwner(AbstractBuild<?, ?> owner) {
* @return Value for property 'previousResult'.
*/
public CoverageResult getPreviousResult() {
// if (parent == null) {
// if (owner == null) {
// return null;
// }
// Run<?, ?> prevBuild = BuildUtils.getPreviousNotFailedCompletedBuild(owner);
// CoberturaBuildAction action = null;
// while ((prevBuild != null) && (null == (action = prevBuild.getAction(CoberturaBuildAction.class)))) {
// prevBuild = BuildUtils.getPreviousNotFailedCompletedBuild(prevBuild);
// }
// return action == null ? null : action.getResult();
// } else {
// CoverageResult prevParent = parent.getPreviousResult();
// return prevParent == null ? null : prevParent.getChild(name);
// }
//TODO replace the CoberturaBuildAction to CoverageAction
return null;
if (parent == null) {
if (owner == null) {
return null;
}
Run<?, ?> prevBuild = BuildUtils.getPreviousNotFailedCompletedBuild(owner);
CoverageAction action = null;
while ((prevBuild != null) && (null == (action = prevBuild.getAction(CoverageAction.class)))) {
prevBuild = BuildUtils.getPreviousNotFailedCompletedBuild(prevBuild);
}
return action == null ? null : action.getResult();
} else {
CoverageResult prevParent = parent.getPreviousResult();
return prevParent == null ? null : prevParent.getChild(name);
}
}

public Object getDynamic(String token, StaplerRequest req, StaplerResponse rsp) throws IOException {
Expand Down Expand Up @@ -517,4 +528,77 @@ public void addParent(CoverageResult p) {
}
}
}

/**
* Interface for javascript code to get code coverage result.
*
* @return aggregated coverage results
*/
@JavaScriptMethod
public List<JSCoverageResult> jsGetResults() {
List<JSCoverageResult> results = new LinkedList<>();

for (Map.Entry<CoverageMetric, Ratio> c : aggregateResults.entrySet()) {
results.add(new JSCoverageResult(c.getKey().getName(), c.getValue()));
}
return results;
}


@JavaScriptMethod
public Map<String, List<JSCoverageResult>> jsGetChildResults() {
return getChildrenReal()
.entrySet()
.stream()
.collect(Collectors.toMap(Map.Entry::getKey, v -> v.getValue().jsGetResults()));
}


@JavaScriptMethod
public Map<String, List<JSCoverageResult>> jsGetTrendResults() {
Map<String, List<JSCoverageResult>> results = new LinkedHashMap<>();

if (getPreviousResult() == null) {
return results;
}

int i = 0;
for (Chartable c = this; c != null && i < DEFAULT_MAX_BUILDS_SHOW_IN_TREND; c = c.getPreviousResult(), i++) {
ChartUtil.NumberOnlyBuildLabel label = new ChartUtil.NumberOnlyBuildLabel(c.getOwner());

List<JSCoverageResult> r = c.getResults().entrySet().stream()
.map(e -> new JSCoverageResult(e.getKey().getName(), e.getValue()))
.collect(Collectors.toList());

results.put(label.toString(), r);
}
return results;

}

public static class JSCoverageResult {
private String name;
private Ratio ratio;

public JSCoverageResult(String name, Ratio ratio) {
this.name = name;
this.ratio = ratio;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public Ratio getRatio() {
return ratio;
}

public void setRatio(Ratio ratio) {
this.ratio = ratio;
}
}
}
@@ -1,109 +1,43 @@
<?jelly escape-by-default='true'?>
<?jelly escape-by-default='false'?>
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define" xmlns:l="/lib/layout"
xmlns:t="/lib/hudson" xmlns:f="/lib/form">
<l:layout css="/plugin/code-coverage-api/css/style.css" norefresh="true">
<script src="${rootURL}/plugin/code-coverage-api/scripts/echarts.min.js">
</script>
<script src="${rootURL}/plugin/code-coverage-api/scripts/custom-chart.js">
</script>
<st:include it="${it.owner}" page="sidepanel.jelly"/>
<l:main-panel>
<h1>${%Code Coverage}</h1>
<j:forEach var="parent" items="${it.parents}">
<a href="${it.relativeUrl(parent)}">${parent.xmlTransform(parent.name)}</a>
&gt;
</j:forEach>
<h2>${it.xmlTransform(it.name)}</h2>
<j:set var="metrics" value="${it.metrics}"/>
<h3>${%Trend}</h3>
<!--<j:if test="${it.previousResult != null}">-->
<!--<img src="graph" width="500px" height="200px"/>-->
<!--</j:if>-->
<!--<j:if test="${it.previousResult == null}">-->
<!--<div style="border: 1px solid #eee; width:500px; ">-->
<!--<j:forEach var="metric" items="${it.metrics}">-->
<!--<table style="padding: 0 10px; padding-top: 5px; width:480px;">-->
<!--<tr>-->
<!--<th align="left">${metric.name}</th>-->
<!--<td align="right">${it.getCoverage(metric).percentage}%</td>-->
<!--</tr>-->
<!--</table>-->
<!--<table style="height: 3px; padding: 0 10px; width:480px;">-->
<!--<tr>-->
<!--<j:if test="${it.getCoverage(metric).percentage &gt; 0}">-->
<!--<td width="${it.getCoverage(metric).percentage}%"-->
<!--style="background-color:#bfb;">-->
<!--&amp;nbsp;-->
<!--</td>-->
<!--</j:if>-->
<!--<j:if test="${it.getCoverage(metric).percentage &lt; 100}">-->
<!--<td width="${100-it.getCoverage(metric).percentage}%"-->
<!--style="background-color:#fdd;">-->
<!--&amp;nbsp;-->
<!--</td>-->
<!--</j:if>-->
<!--</tr>-->
<!--</table>-->
<!--</j:forEach>-->
<!--</div>-->
<!--</j:if>-->

<h3>${%coverage.summary.by(it.element.displayName)}</h3>
<table border="1px" class="pane">
<tr>
<th>${%Name}</th>
<j:forEach var="metric" items="${metrics}">
<th class="center">${metric.name}</th>
</j:forEach>
</tr>
<tr>
<td>${it.name}</td>
<j:forEach var="metric" items="${metrics}">
<td data="${it.getCoverage(metric).percentageString}">
<table class="percentgraph" cellpadding="0px" cellspacing="0px">
<tr class="percentgraph">
<td width="40" class="data">${it.getCoverage(metric).percentage}%</td>
<td class="percentgraph"><div class="percentgraph"><div class="greenbar" style="width: ${it.getCoverage(metric).percentageFloat}px;"><span class="text">${it.getCoverage(metric)}</span></div></div></td>
</tr>
</table>
</td>
</j:forEach>
</tr>
</table>
<br/>
<br/>
<br/>
<j:if test="${it.previousResult != null}">
<div id="trendChart" style="width:800px;height:100%;">
</div>
</j:if>
<br/>
<div id="summaryChart" style="width:800px;height:100%;">
</div>
<br/>
<div id="childSummaryChart" style="width:800px;height:100%;">
</div>
<script>
var instance =<st:bind value="${it}"/>;

<j:forEach var="element" items="${it.childElements}">
<j:set var="childMetrics" value="${it.getChildMetrics(element)}"/>
<h3>${%coverage.breakdown.by(element.displayName)}</h3>
<table border="1px" class="pane sortable">
<tr>
<th>${%Name}</th>
<j:forEach var="metric" items="${childMetrics}">
<th class="center">${metric.name}</th>
</j:forEach>
</tr>
<j:forEach var="c" items="${it.children}">
<j:set var="child" value="${it.getChild(c)}"/>
<tr>
var coverageChartGenerator = new CoverageChartGenerator(instance)
var name = "${it.xmlTransform(it.name)}";
coverageChartGenerator.generateSummaryChart('summaryChart', name);
var metric = '${it.childElement.displayName}';
coverageChartGenerator.generateChildSummaryChart('childSummaryChart', metric);

<td>
<a href="${child.urlTransform(child.name)}/">${child.xmlTransform(child.name)}</a>
</td>
<j:forEach var="metric" items="${childMetrics}">
<j:set var="childResult" value="${child.getCoverage(metric)}"/>
<j:choose>
<j:when test="${childResult!=null and childResult.denominator != 0}">
<td data="${childResult.percentageString}">
<table class="percentgraph" cellpadding="0px" cellspacing="0px"><tr class="percentgraph">
<td width="40" class="data">${childResult.percentage}%</td>
<td class="percentgraph"><div class="percentgraph"><div class="greenbar" style="width: ${childResult.percentageFloat}px;"><span class="text">${childResult}</span></div></div></td>
</tr></table>
</td>
</j:when>
<j:otherwise>
<td data="101" class="center">${%N/A}</td>
</j:otherwise>
</j:choose>
</j:forEach>
</tr>
</j:forEach>
</table>
</j:forEach>
coverageChartGenerator.generateTrendChart('trendChart');
</script>

<j:if test="${it.sourceCodeLevel}">
<h3>${%Source}</h3>
Expand All @@ -112,18 +46,21 @@
<div style="overflow-x:scroll;">
<table class="source">
<thead>
<tr>
<th colspan="3">${it.relativeSourcePath}</th>
</tr>
<tr>
<th colspan="3">${it.relativeSourcePath}</th>
</tr>
</thead>
<pre><j:out value="${it.sourceFileContent}"/></pre>
<pre>
<j:out value="${it.sourceFileContent}"/>
</pre>

</table>
</div>
</j:when>
<j:otherwise>
<p>
<i>${%Source code is unavailable.}</i> ${%Some possible reasons are:}
<i>${%Source code is unavailable.}</i>
${%Some possible reasons are:}
<ul>
<li>${%reason.1}</li>
<li>${%reason.2}</li>
Expand Down

0 comments on commit 0a4f664

Please sign in to comment.