aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc R. Hoffmann <hoffmann@mountainminds.com>2017-09-15 03:25:09 +0200
committerEvgeny Mandrikov <Godin@users.noreply.github.com>2017-09-15 03:25:09 +0200
commit4d08365f76149b7739beb5e17deaa0c7d024f47e (patch)
treeb2798d39e408f4d0c29f90a7a3817fe7d562c899
parent424251f1bc3a6a49488133e9ff7f039d23e32af9 (diff)
downloadjacoco-4d08365f76149b7739beb5e17deaa0c7d024f47e.tar.gz
Add "--verbose" option to "classinfo" CLI command (#578)
-rw-r--r--org.jacoco.cli.test/src/org/jacoco/cli/internal/CommandTestBase.java6
-rw-r--r--org.jacoco.cli.test/src/org/jacoco/cli/internal/commands/ClassInfoTest.java17
-rw-r--r--org.jacoco.cli/src/org/jacoco/cli/internal/commands/ClassInfo.java85
3 files changed, 85 insertions, 23 deletions
diff --git a/org.jacoco.cli.test/src/org/jacoco/cli/internal/CommandTestBase.java b/org.jacoco.cli.test/src/org/jacoco/cli/internal/CommandTestBase.java
index 4d12a373..2dee3adf 100644
--- a/org.jacoco.cli.test/src/org/jacoco/cli/internal/CommandTestBase.java
+++ b/org.jacoco.cli.test/src/org/jacoco/cli/internal/CommandTestBase.java
@@ -12,6 +12,7 @@
package org.jacoco.cli.internal;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import java.io.PrintWriter;
@@ -59,6 +60,11 @@ public abstract class CommandTestBase {
assertTrue(content, content.contains(expected));
}
+ protected void assertContainsNot(String expected, StringWriter buffer) {
+ final String content = buffer.toString();
+ assertFalse(content, content.contains(expected));
+ }
+
protected String getClassPath() {
final String name = getClass().getName();
final String res = "/" + name.replace('.', '/') + ".class";
diff --git a/org.jacoco.cli.test/src/org/jacoco/cli/internal/commands/ClassInfoTest.java b/org.jacoco.cli.test/src/org/jacoco/cli/internal/commands/ClassInfoTest.java
index 62934e28..cff5116c 100644
--- a/org.jacoco.cli.test/src/org/jacoco/cli/internal/commands/ClassInfoTest.java
+++ b/org.jacoco.cli.test/src/org/jacoco/cli/internal/commands/ClassInfoTest.java
@@ -45,10 +45,19 @@ public class ClassInfoTest extends CommandTestBase {
execute("classinfo", getClassPath());
assertOk();
- assertContains(
- "class name: org/jacoco/cli/internal/commands/ClassInfoTest",
- out);
- assertContains("methods: 4", out);
+ assertContains("class", out);
+ assertContains("org/jacoco/cli/internal/commands/ClassInfoTest", out);
+ assertContainsNot("method", out);
+ }
+
+ @Test
+ public void should_print_class_details_when_verbose() throws Exception {
+ execute("classinfo", "--verbose", getClassPath());
+
+ assertOk();
+ assertContains("line", out);
+ assertContains("method", out);
+ assertContains("line", out);
}
}
diff --git a/org.jacoco.cli/src/org/jacoco/cli/internal/commands/ClassInfo.java b/org.jacoco.cli/src/org/jacoco/cli/internal/commands/ClassInfo.java
index dd6a3718..5542d192 100644
--- a/org.jacoco.cli/src/org/jacoco/cli/internal/commands/ClassInfo.java
+++ b/org.jacoco.cli/src/org/jacoco/cli/internal/commands/ClassInfo.java
@@ -15,14 +15,20 @@ import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
+import java.util.Iterator;
import java.util.List;
import org.jacoco.cli.internal.Command;
import org.jacoco.core.analysis.Analyzer;
import org.jacoco.core.analysis.IClassCoverage;
+import org.jacoco.core.analysis.ICounter;
+import org.jacoco.core.analysis.ICoverageNode;
import org.jacoco.core.analysis.ICoverageVisitor;
+import org.jacoco.core.analysis.ILine;
+import org.jacoco.core.analysis.IMethodCoverage;
import org.jacoco.core.data.ExecutionDataStore;
import org.kohsuke.args4j.Argument;
+import org.kohsuke.args4j.Option;
/**
* The <code>classinfo</code> command.
@@ -32,6 +38,9 @@ public class ClassInfo extends Command {
@Argument(usage = "location of Java class files", metaVar = "<classlocations>")
List<File> classfiles = new ArrayList<File>();
+ @Option(name = "--verbose", usage = "show method and line number details")
+ boolean verbose = false;
+
@Override
public String description() {
return "Print information about Java class files at the provided location.";
@@ -44,12 +53,7 @@ public class ClassInfo extends Command {
out.println("[WARN] No class files provided.");
} else {
final Analyzer analyzer = new Analyzer(new ExecutionDataStore(),
- new ICoverageVisitor() {
- public void visitCoverage(
- final IClassCoverage coverage) {
- print(coverage, out);
- }
- });
+ new Printer(out));
for (final File file : classfiles) {
analyzer.analyzeAll(file);
}
@@ -57,19 +61,62 @@ public class ClassInfo extends Command {
return 0;
}
- private void print(final IClassCoverage coverage, final PrintWriter out) {
- out.printf("class name: %s%n", coverage.getName());
- out.printf("class id: %016x%n", Long.valueOf(coverage.getId()));
- out.printf("instructions: %s%n", Integer
- .valueOf(coverage.getInstructionCounter().getTotalCount()));
- out.printf("branches: %s%n",
- Integer.valueOf(coverage.getBranchCounter().getTotalCount()));
- out.printf("lines: %s%n",
- Integer.valueOf(coverage.getLineCounter().getTotalCount()));
- out.printf("methods: %s%n",
- Integer.valueOf(coverage.getMethodCounter().getTotalCount()));
- out.printf("complexity: %s%n%n", Integer
- .valueOf(coverage.getComplexityCounter().getTotalCount()));
+ private class Printer implements ICoverageVisitor {
+
+ private final PrintWriter out;
+
+ Printer(final PrintWriter out) {
+ this.out = out;
+ out.println(" INST BRAN LINE METH CXTY ELEMENT");
+ }
+
+ public void visitCoverage(final IClassCoverage coverage) {
+ final String desc = String.format("class 0x%016x %s",
+ Long.valueOf(coverage.getId()), coverage.getName());
+ printDetails(desc, coverage);
+ if (verbose) {
+ for (final Iterator<IMethodCoverage> i = coverage.getMethods()
+ .iterator(); i.hasNext();) {
+ printMethod(i.next(), i.hasNext());
+ }
+ }
+ }
+
+ private void printMethod(final IMethodCoverage method,
+ final boolean more) {
+ final String desc = String.format("+- method %s%s",
+ method.getName(), method.getDesc());
+ printDetails(desc, method);
+ for (int nr = method.getFirstLine(); nr <= method
+ .getLastLine(); nr++) {
+ printLine(method.getLine(nr), nr, more ? "| " : " ");
+ }
+ }
+
+ private void printLine(final ILine line, final int nr,
+ final String indent) {
+ if (line.getStatus() != ICounter.EMPTY) {
+ out.printf("%6s %6s %s +- line %s%n",
+ total(line.getInstructionCounter()),
+ total(line.getBranchCounter()), indent,
+ Integer.valueOf(nr));
+ }
+ }
+
+ private void printDetails(final String description,
+ final ICoverageNode coverage) {
+ out.printf("%6s %6s %6s %6s %6s %s%n",
+ total(coverage.getInstructionCounter()),
+ total(coverage.getBranchCounter()),
+ total(coverage.getLineCounter()),
+ total(coverage.getMethodCounter()),
+ total(coverage.getComplexityCounter()), description);
+ }
+
+ private String total(final ICounter counter) {
+ return String.valueOf(counter.getTotalCount());
+ }
+
}
}