diff options
author | Marc R. Hoffmann <hoffmann@mountainminds.com> | 2017-09-15 03:25:09 +0200 |
---|---|---|
committer | Evgeny Mandrikov <Godin@users.noreply.github.com> | 2017-09-15 03:25:09 +0200 |
commit | 4d08365f76149b7739beb5e17deaa0c7d024f47e (patch) | |
tree | b2798d39e408f4d0c29f90a7a3817fe7d562c899 | |
parent | 424251f1bc3a6a49488133e9ff7f039d23e32af9 (diff) | |
download | jacoco-4d08365f76149b7739beb5e17deaa0c7d024f47e.tar.gz |
Add "--verbose" option to "classinfo" CLI command (#578)
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()); + } + } } |