Skip to content

Commit

Permalink
[FIXED JENKINS-15538] added whole class coverage highlighting
Browse files Browse the repository at this point in the history
The code is refactored a bit so that the same line-by-line annotation code can be used by multiple callers.

For the time being, the class coverage highlight is rendered along with the per-method break down, but one might prefer some tweak to this, such as using tabs.
  • Loading branch information
kohsuke committed Feb 22, 2013
1 parent b1ef117 commit f778bc0
Show file tree
Hide file tree
Showing 5 changed files with 114 additions and 76 deletions.
29 changes: 23 additions & 6 deletions src/main/java/hudson/plugins/jacoco/report/ClassReport.java
@@ -1,18 +1,19 @@
package hudson.plugins.jacoco.report;

import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.jacoco.core.analysis.IClassCoverage;

import org.jacoco.core.analysis.IMethodCoverage;
import java.io.File;
import java.util.logging.Logger;

/**
* @author Kohsuke Kawaguchi
*/
public final class ClassReport extends AggregatedReport<PackageReport,ClassReport,MethodReport> {

public String buildURL;
@Override
private String sourceFilePath;
private IClassCoverage classCov;

@Override
public void setName(String name) {
super.setName(name.replaceAll("/", "."));
//logger.log(Level.INFO, "ClassReport");
Expand All @@ -24,6 +25,22 @@ public void add(MethodReport child) {
getChildren().put(child.getName(), child);
}

public void setSrcFileInfo(IClassCoverage classCov, String sourceFilePath) {
this.sourceFilePath = sourceFilePath;
this.classCov = classCov;
}

/**
* Read the source Java file for this class.
*/
public File getSourceFilePath() {
return new File(sourceFilePath);
}

public String printHighlightedSrcFile() {
return new SourceAnnotator(getSourceFilePath()).printHighlightedSrcFile(classCov);
}

@Override
public String toString() {
return getClass().getSimpleName() + ":"
Expand Down
Expand Up @@ -67,6 +67,8 @@ public CoverageReport(JacocoBuildAction action, ExecutionFileLoader executionFil
ClassReport classReport = new ClassReport();
classReport.setName(classCov.getName());
classReport.setParent(packageReport);
classReport.setSrcFileInfo(classCov, executionFileLoader.getSrcDir() + "/" + packageCov.getName() + "/" + classCov.getSourceFileName());

packageReport.setCoverage(classReport, classCov);

ArrayList<IMethodCoverage> methodList = new ArrayList<IMethodCoverage>(classCov.getMethods());
Expand All @@ -75,7 +77,7 @@ public CoverageReport(JacocoBuildAction action, ExecutionFileLoader executionFil
methodReport.setName(methodCov.getName());
methodReport.setParent(classReport);
classReport.setCoverage(methodReport, methodCov);
methodReport.setSrcFileInfo(methodCov, executionFileLoader.getSrcDir()+ "/" + packageCov.getName() + "/"+ classCov.getSourceFileName());
methodReport.setSrcFileInfo(methodCov);

classReport.add(methodReport);
}
Expand Down
74 changes: 5 additions & 69 deletions src/main/java/hudson/plugins/jacoco/report/MethodReport.java
Expand Up @@ -13,6 +13,7 @@
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

Expand All @@ -33,20 +34,8 @@ public final class MethodReport extends AggregatedReport<ClassReport,MethodRepor

public String lineNo;

public String sourceFilePath;

ArrayList<String> sourceLines;

private IMethodCoverage methodCov;

public String getSourceFilePath() {
return sourceFilePath;
}

public void setSourceFilePath(String sourceFilePath) {
this.sourceFilePath = sourceFilePath;
}

public void setDesc(String desc) {
this.desc = desc;
}
Expand All @@ -55,36 +44,6 @@ public String getDesc(String desc) {
return this.desc;
}

public void readFile(String filePath) throws java.io.FileNotFoundException,
java.io.IOException {
ArrayList<String> aList = new ArrayList<String>();

BufferedReader br = null;

try {
br = new BufferedReader(new FileReader(filePath));
String line = null;
while ((line = br.readLine()) != null) {
aList.add(line.replaceAll("\\t","&nbsp&nbsp&nbsp&nbsp").replaceAll("<", "&lt").replaceAll(">", "&gt"));
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

this.sourceLines = aList;
}


@Override
public String printFourCoverageColumns() {
StringBuilder buf = new StringBuilder();
Expand Down Expand Up @@ -115,34 +74,11 @@ public void add(SourceFileReport child) {

private static final Logger logger = Logger.getLogger(CoverageObject.class.getName());

public void setSrcFileInfo(IMethodCoverage methodCov, String sourceFilePath) {
this.sourceFilePath = sourceFilePath;
public void setSrcFileInfo(IMethodCoverage methodCov) {
this.methodCov = methodCov;
}

public String printHighlightedSrcFile() {
StringBuilder buf = new StringBuilder();
try {

readFile(sourceFilePath);
//buf.append(sourceFilePath+" number of lines: "+this.sourceLines.size()).append("<br>");
buf.append("<code style=\"white-space:pre;\">");
for (int i=1;i<=this.sourceLines.size(); ++i) {
if ((methodCov.getLine(i).getInstructionCounter().getStatus() == ICounter.FULLY_COVERED) || (methodCov.getLine(i).getInstructionCounter().getStatus() == ICounter.PARTLY_COVERED)) {
buf.append(i + ": ").append("<SPAN style=\"BACKGROUND-COLOR: #32cd32\">"+ sourceLines.get(i-1)).append("</SPAN>").append("<br>");
} else {
buf.append(i + ": ").append(sourceLines.get(i-1)).append("<br>");
}

}

//logger.log(Level.INFO, "lines: " + buf);
} catch (FileNotFoundException e) {
buf.append("ERROR: Sourcefile does not exist!");
} catch (IOException e) {
buf.append("ERROR: Error while reading the sourcefile!");
}
return buf.toString();
}

public String printHighlightedSrcFile() {
return new SourceAnnotator(getParent().getSourceFilePath()).printHighlightedSrcFile(methodCov);
}
}
80 changes: 80 additions & 0 deletions src/main/java/hudson/plugins/jacoco/report/SourceAnnotator.java
@@ -0,0 +1,80 @@
package hudson.plugins.jacoco.report;

import org.jacoco.core.analysis.ICounter;
import org.jacoco.core.analysis.ISourceNode;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
* Parses source file and annotates that with the coverage information.
*
* @author Kohsuke Kawaguchi
*/
public class SourceAnnotator {
private final File src;

public SourceAnnotator(File src) {
this.src = src;
}

/**
* Parses the source file into individual lines.
*/
private List<String> readLines() throws IOException {
ArrayList<String> aList = new ArrayList<String>();

BufferedReader br = null;

try {
br = new BufferedReader(new FileReader(src));
String line;
while ((line = br.readLine()) != null) {
aList.add(line.replaceAll("\\t", "&nbsp&nbsp&nbsp&nbsp").replaceAll("<", "&lt").replaceAll(">", "&gt"));
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

return aList;
}

public String printHighlightedSrcFile(ISourceNode cov) {
StringBuilder buf = new StringBuilder();
try {
List<String> sourceLines = readLines();
buf.append("<code style=\"white-space:pre;\">");
for (int i=1;i<=sourceLines.size(); ++i) {
int status = cov.getLine(i).getInstructionCounter().getStatus();
if ((status == ICounter.FULLY_COVERED) || (status == ICounter.PARTLY_COVERED)) {
buf.append(i + ": ").append("<SPAN style=\"BACKGROUND-COLOR: #32cd32\">"+ sourceLines.get(i-1)).append("</SPAN>").append("<br>");
} else {
buf.append(i + ": ").append(sourceLines.get(i-1)).append("<br>");
}

}

//logger.log(Level.INFO, "lines: " + buf);
} catch (FileNotFoundException e) {
buf.append("ERROR: Sourcefile does not exist!");
} catch (IOException e) {
buf.append("ERROR: Error while reading the sourcefile!");
}
return buf.toString();
}
}
Expand Up @@ -7,6 +7,9 @@

<h3>${it.name}</h3>
<e:breakdownMethodsTable />

<h2>${%Coverage}</h2>
${it.printHighlightedSrcFile()}
</l:main-panel>
</l:layout>
</j:jelly>

0 comments on commit f778bc0

Please sign in to comment.