Skip to content

Commit

Permalink
Merge pull request #68 from alexsalesdev/master
Browse files Browse the repository at this point in the history
#66 Show summary of results implementation
  • Loading branch information
Grundlefleck committed Dec 14, 2015
2 parents ee53707 + 02bdc55 commit b6739d7
Show file tree
Hide file tree
Showing 5 changed files with 103 additions and 17 deletions.
Expand Up @@ -34,6 +34,8 @@ public interface BatchAnalysisOptions {

public abstract boolean verbose();

boolean showSummary();

public abstract ReportMode reportMode();

public abstract File classListFile();
Expand Down
19 changes: 17 additions & 2 deletions src/main/java/org/mutabilitydetector/cli/CommandLineOptions.java
Expand Up @@ -44,6 +44,7 @@ public class CommandLineOptions implements BatchAnalysisOptions {
private boolean isUsingClassList;
private boolean reportErrors;
private boolean failFast = false;
private boolean showSummary = false;

private final PrintStream errorStream;

Expand All @@ -58,9 +59,12 @@ public void doParsingAction(CommandLine line) {
extractClassListFile(line);
extractShowErrorsOption(line);
extractFailFastOption(line);
extractShowSummaryOption(line);
printHelpIfNoOptionsGiven(line);
}



}

public static enum ReportMode {
Expand Down Expand Up @@ -104,6 +108,7 @@ private Options createOptions() {
+ "the time taken to perform analysis.",
"classlist",
"cl");
opts.addOption("s", "summary", false, "Show summary of analysis result.");
opts.addOption("v", "verbose", false, "Print details of analysis and reasons for results.");
opts.addOption("r",
"report",
Expand All @@ -113,8 +118,9 @@ private Options createOptions() {
opts.addOption("h", "help", false, "print this message");
opts.addOption("e", "reportErrors", false, "Reports on errors in the analysis. Defaults to false.");
opts.addOption("f", "failFast", false, "When true, encountering an unhandled exception will cause analysis to abort immediately. " +
"When false, exceptions during analysis of a particular class will be reflected in the result assigned to " +
"that class. Defaults to false.");
"When false, exceptions during analysis of a particular class will be reflected in the result assigned to " +
"that class. Defaults to false.");

return opts;
}

Expand Down Expand Up @@ -154,6 +160,10 @@ private void extractReportMode(CommandLine line) {
}
}

private void extractShowSummaryOption(CommandLine line) {
this.showSummary = (line.hasOption("s") || line.hasOption("summary"));
}

private void extractVerboseOption(CommandLine line) {
if (line.hasOption("v") || line.hasOption("verbose")) {
verbose = true;
Expand Down Expand Up @@ -256,6 +266,11 @@ public boolean verbose() {
return verbose;
}

@Override
public boolean showSummary() {
return showSummary;
}

@Override
public ReportMode reportMode() {
return reportMode;
Expand Down
Expand Up @@ -21,37 +21,37 @@
*/


import com.google.common.collect.Ordering;
import org.mutabilitydetector.AnalysisError;
import org.mutabilitydetector.AnalysisResult;
import org.mutabilitydetector.IsImmutable;
import org.mutabilitydetector.MutableReasonDetail;
import org.mutabilitydetector.cli.CommandLineOptions.ReportMode;

import static org.mutabilitydetector.IsImmutable.IMMUTABLE;
import static org.mutabilitydetector.IsImmutable.NOT_IMMUTABLE;

import javax.annotation.concurrent.Immutable;
import java.io.Serializable;
import java.lang.management.ManagementFactory;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import javax.annotation.concurrent.Immutable;

import org.mutabilitydetector.AnalysisError;
import org.mutabilitydetector.AnalysisResult;
import org.mutabilitydetector.IsImmutable;
import org.mutabilitydetector.MutableReasonDetail;
import org.mutabilitydetector.cli.CommandLineOptions.ReportMode;

import com.google.common.collect.Ordering;
import static org.mutabilitydetector.IsImmutable.IMMUTABLE;
import static org.mutabilitydetector.IsImmutable.NOT_IMMUTABLE;

@Immutable
public final class SessionResultsFormatter {

private final boolean verbose;
private final boolean showSummary;
private final ReportMode reportMode;
private final Collection<String> classesToReport;
private final BatchAnalysisOptions options;

public SessionResultsFormatter(BatchAnalysisOptions options, ClassListReaderFactory readerFactory) {
this.options = options;
this.verbose = options.verbose();
this.showSummary = options.showSummary();
this.reportMode = options.reportMode();
this.classesToReport = getClassesToReport(options.isUsingClassList(), readerFactory);
}
Expand Down Expand Up @@ -88,10 +88,30 @@ private void appendErrors(Iterable<AnalysisError> errors, StringBuilder output)
private void appendAnalysisResults(Iterable<AnalysisResult> results, StringBuilder output) {
List<AnalysisResult> sortedList = sortByClassname(results);

int total = 0;
int totalNotImmutable = 0;
for (AnalysisResult result : sortedList) {
IsImmutable isImmutable = result.isImmutable;
if (isImmutable.equals(NOT_IMMUTABLE)) {
totalNotImmutable++;
}
total++;
addResultForClass(output, result, isImmutable);
}

if (showSummary) {
int totalImmutable = total - totalNotImmutable;
appendSummaryOfResults(output, total, totalImmutable, totalNotImmutable);
}

}

private void appendSummaryOfResults(StringBuilder output, int total, int totalImmutable, int totalMutable) {
output.append(String.format("\n\t%d %s%n", total, "Total number of classes scanned."));
output.append(String.format("\t%d %s%n", totalImmutable, "IMMUTABLE class(es)."));
output.append(String.format("\t%d %s%n", totalMutable, "NOT_IMMUTABLE class(es)."));
final long processRuntime = ManagementFactory.getRuntimeMXBean().getStartTime() - System.currentTimeMillis();
output.append(String.format("\t%d %s%n", processRuntime, "seconds runtime."));
}

private List<AnalysisResult> sortByClassname(Iterable<AnalysisResult> sessionResults) {
Expand Down
Expand Up @@ -74,6 +74,20 @@ public void verboseOptionCanBeSetWithLongOpt() throws Exception {
assertEquals(true, options.verbose());
}

@Test
public void showSummaryOptionCanBeSetWithShortOpt() throws Exception {
String[] args = makeArgs("-s");
options = createOptions(args);
assertEquals(true, options.showSummary());
}

@Test
public void showSummaryOptionCanBeSetWithLongOpt() throws Exception {
String[] args = makeArgs("-summary");
options = createOptions(args);
assertEquals(true, options.showSummary());
}

@Test
public void reportModeCanBeSetToAll() throws Exception {
String[] args = makeArgs("-report", "all");
Expand Down
Expand Up @@ -107,8 +107,43 @@ public void verboseOutputIncludesDetailedReasonAndPrettyPrintedCodeLocation() th
StringBuilder result = formatter.format(analysisSession.getResults(), analysisSession.getErrors());

assertThat(result.toString(),
containsString("a.b.c is NOT_IMMUTABLE" + newline +
"\t1st checker reason message [Class: path.to.MyClass]" + newline +
"\t2nd checker reason message [Field: myField, Class: path.to.OtherClass]" + newline));
containsString("a.b.c is NOT_IMMUTABLE" + newline +
"\t1st checker reason message [Class: path.to.MyClass]" + newline +
"\t2nd checker reason message [Field: myField, Class: path.to.OtherClass]" + newline));
}


@Test
public void printsSummaryOfInformationAlongWithReadableMessage() throws Exception {
BatchAnalysisOptions options = mock(BatchAnalysisOptions.class);
when(options.reportMode()).thenReturn(ReportMode.ALL);
when(options.isUsingClassList()).thenReturn(false);
when(options.showSummary()).thenReturn(true);

AnalysisSession analysisSession = mock(AnalysisSession.class);
Collection<AnalysisResult> analysisResults = Arrays.asList(analysisResult("a.b.c",
IsImmutable.IMMUTABLE,
unusedMutableReasonDetails()),
analysisResult("d.e.f",
IsImmutable.EFFECTIVELY_IMMUTABLE,
unusedMutableReasonDetails()),
analysisResult("g.h.i",
IsImmutable.NOT_IMMUTABLE,
unusedMutableReasonDetails()));
when(analysisSession.getResults()).thenReturn(analysisResults);

SessionResultsFormatter formatter = new SessionResultsFormatter(options, unusedReaderFactory);

StringBuilder result = formatter.format(analysisSession.getResults(), analysisSession.getErrors());

assertThat(result.toString(),
allOf(containsString("a.b.c is IMMUTABLE" + newline),
containsString("d.e.f is EFFECTIVELY_IMMUTABLE" + newline),
containsString("g.h.i is NOT_IMMUTABLE" + newline),
containsString("3 Total number of classes scanned." + newline),
containsString("2 IMMUTABLE class(es)." + newline),
containsString("1 NOT_IMMUTABLE class(es)." + newline),
containsString("seconds runtime." + newline)
));
}
}

0 comments on commit b6739d7

Please sign in to comment.