# HG changeset patch # User Pavel Tisnovsky # Date 1326901963 -3600 # Node ID 5849d5bfbee0716ddc0364b44994fe061698f473 # Parent 5ef74c026b810c2fbe0765327a463abfab62ad63 2012-01-18 Pavel Tisnovsky * templates/class_template.html: * templates/summary.html: New templates used for a summary and a report generated for each tested class. * src/ReportGenerator.java: Support for templates updated, added the functionality to generate summary. diff -r 5ef74c026b81 -r 5849d5bfbee0 ChangeLog --- a/ChangeLog Tue Jan 17 14:02:07 2012 +0100 +++ b/ChangeLog Wed Jan 18 16:52:43 2012 +0100 @@ -1,3 +1,13 @@ +2012-01-18 Pavel Tisnovsky + + * templates/class_template.html: + * templates/summary.html: + New templates used for a summary and a report + generated for each tested class. + * src/ReportGenerator.java: + Support for templates updated, added the functionality + to generate summary. + 2012-01-17 Pavel Tisnovsky * src/FileUtils.java: diff -r 5ef74c026b81 -r 5849d5bfbee0 src/ReportGenerator.java --- a/src/ReportGenerator.java Tue Jan 17 14:02:07 2012 +0100 +++ b/src/ReportGenerator.java Wed Jan 18 16:52:43 2012 +0100 @@ -37,11 +37,9 @@ */ import java.io.BufferedReader; -import java.io.BufferedWriter; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; -import java.io.FileWriter; import java.io.IOException; import java.util.LinkedList; import java.util.List; @@ -70,6 +68,7 @@ List fileContent = FileUtils.readTextFile(allClassListFileName); // set of classes should be sorted Set allClasses = new TreeSet(); + // add all lines read from a file to a set (and sort them) allClasses.addAll(fileContent); return allClasses; } @@ -90,6 +89,7 @@ { List template = FileUtils.readTextFile("templates/all_packages_template.html"); List out = new LinkedList(); + // iterate through whole template for (String templateLine : template) { // replace text in template where needed @@ -97,11 +97,13 @@ { addPackageList(packageNames, out); } + // normal line else { out.add(templateLine); } } + // write list of string to a file with given name FileUtils.writeTextFile(reportDirectory, "all_packages.html", out); } @@ -121,6 +123,7 @@ { List template = FileUtils.readTextFile("templates/package_template.html"); List out = new LinkedList(); + // iterate through whole template for (String templateLine : template) { // replace text in template where needed @@ -128,11 +131,13 @@ { addClassList(packageName, testedClasses, out); } + // normal line else { out.add(templateLine); } } + // write list of string to a file with given name FileUtils.writeTextFile(reportDirectory, packageName + ".html", out); } @@ -153,6 +158,7 @@ { List template = FileUtils.readTextFile("templates/all_classes_template.html"); List out = new LinkedList(); + // iterate through whole template for (String templateLine : template) { // replace text in template where needed @@ -160,11 +166,13 @@ { addPackageAndClassList(usedPackageNames, testedClasses, out); } + // normal line else { out.add(templateLine); } } + // write list of string to a file with given name FileUtils.writeTextFile(reportDirectory, "all_classes.html", out); } @@ -198,6 +206,7 @@ */ private static void addClassList(String packageName, Set testedClasses, List out) { + // iterate through all class names for (String className : testedClasses) { // list only classes from given package @@ -221,6 +230,7 @@ */ private static void addPackageAndClassList(Set usedPackageNames, Set testedClasses, List out) { + // iterate through all class names for (String packageName : usedPackageNames) { out.add("

Package " + packageName + "

"); @@ -235,56 +245,87 @@ } } + /** + * Create new HTML file containing report for one tested class. + * + * @param reportDirectory + * directory where report is generated + * @param testClass + * name of tested class + * @param allMethods + * superset of apiMethods and testedMethods + * @param apiMethods + * methods presented in API + * @param testedMethods + * methods called from tests + */ private static void createFileForClass(String reportDirectory, String testClass, Set allMethods, Set apiMethods, Set testedMethods) { - BufferedWriter fout = null; - try + List template = FileUtils.readTextFile("templates/class_template.html"); + List out = new LinkedList(); + // iterate through whole template + for (String templateLine : template) { - fout = new BufferedWriter(new FileWriter(new File(reportDirectory, testClass + ".html"))); - fout.write("\n"); - fout.write("\n"); - fout.write("" + testClass + "\n"); - fout.write("\n"); - fout.write("\n"); - fout.write("

Class " + testClass + "

\n"); - fout.write("\n"); - fout.write("\n"); - for (String methodName : allMethods) + // replace text in template where needed + if (templateLine.contains("${CLASS_NAME}")) { - fout.write(""); - fout.write(printMethodCoverage(methodName, apiMethods)); - fout.write(printMethodCoverage(methodName, testedMethods)); - fout.write("\n"); + out.add(templateLine.replace("${CLASS_NAME}", testClass)); + } + // replace text in template where needed + else if (templateLine.contains("${METHOD_LIST}")) + { + printReportForAllMethods(allMethods, apiMethods, testedMethods, out); + } + // normal line + else + { + out.add(templateLine); } - fout.write("
MethodAPITested
" + constructPrintedMethodName(methodName) + "
\n"); - fout.write("\n"); - fout.write("\n"); } - catch (IOException e) - { - e.printStackTrace(); - } - finally + // write list of string to a file with given name + FileUtils.writeTextFile(reportDirectory, testClass + ".html", out); + } + + /** + * Print report for all methods in given class. + * + * @param allMethods + * superset of apiMethods and testedMethods + * @param apiMethods + * methods presented in API + * @param testedMethods + * methods called from tests + * @param out + * list of string which represents generated report + */ + private static void printReportForAllMethods(Set allMethods, Set apiMethods, + Set testedMethods, List out) + { + // iterate through all methods + for (String methodName : allMethods) { - try - { - if (fout != null) - { - fout.close(); - } - } - catch (IOException e) - { - e.printStackTrace(); - } + out.add("" + constructPrintedMethodName(methodName) + ""); + out.add(printMethodCoverage(methodName, apiMethods)); + out.add(printMethodCoverage(methodName, testedMethods)); + out.add("\n"); } } + /** + * Construct set filled with public API classes. + * + * @param allClasses + * set of all API classes (including classes from proprietary + * packages) + * @return set filled with public API classes + */ private static Set preparePackageNames(Set allClasses) { Set packages = new TreeSet(); + // iterate through all class names for (String className : allClasses) { + // filter only public API classes String packageName = className.substring(0, className.lastIndexOf('.')); if (!packageName.startsWith("com.") && !packageName.startsWith("sun")) { @@ -407,6 +448,76 @@ return allMethods; } + private static void printSummaryPage(String reportDirectory, Set allPackageNames, Set allClasses, + Set testedClasses, Set usedPackageNames) + { + final int numberOfAllPackages = allPackageNames.size(); + final int numberOfAllClasses = allClasses.size(); + final int numberOfUsedPackages = usedPackageNames.size(); + final int numberOfTestedClasses = testedClasses.size(); + + List template = FileUtils.readTextFile("templates/summary.html"); + List out = new LinkedList(); + for (String templateLine : template) + { + // replace text in template where needed + if (templateLine.contains("${API_PACKAGES}")) + { + out.add(templateLine.replace("${API_PACKAGES}", "" + numberOfAllPackages)); + } + // replace text in template where needed + else if (templateLine.contains("${API_CLASSES}")) + { + out.add(templateLine.replace("${API_CLASSES}", "" + numberOfAllClasses)); + } + else + { + if (templateLine.contains("${TESTED_PACKAGES}")) + { + out.add(templateLine.replace("${TESTED_PACKAGES}", "" + numberOfUsedPackages)); + } + // replace text in template where needed + else if (templateLine.contains("${TESTED_CLASSES}")) + { + out.add(templateLine.replace("${TESTED_CLASSES}", "" + numberOfTestedClasses)); + } + // replace text in template where needed + else if (templateLine.contains("${TESTED_PACKAGES_RATIO}")) + { + out.add(templateLine.replace("${TESTED_PACKAGES_RATIO}", "" + calcRatio(numberOfUsedPackages, numberOfAllPackages))); + } + // replace text in template where needed + else if (templateLine.contains("${TESTED_CLASSES_RATIO}")) + { + out.add(templateLine.replace("${TESTED_CLASSES_RATIO}", "" + calcRatio(numberOfTestedClasses, numberOfAllClasses))); + } + // normal output + else + { + out.add(templateLine); + } + } + } + FileUtils.writeTextFile(reportDirectory, "all_results.html", out); + } + + /** + * Calculate ratio of two items (usually tested classes vs. all classes) and + * return textual representation of the calculated ratio (percentage) + * + * @param numberOfTestedItems + * number of tested items + * @param numberOfAllItems + * number of all items + * @return textual representation of the calculated ratio (percentage) + */ + @SuppressWarnings("boxing") + private static String calcRatio(int numberOfTestedItems, int numberOfAllItems) + { + float ratio = 100.0f * numberOfTestedItems / numberOfAllItems; + return String.format("%.2f%%", ratio); + } + private static void prepareReport(String allClassListFileName, String testedClassListFileName, String reportDirectory) { @@ -416,13 +527,13 @@ Set usedPackageNames = prepareUsedPackageNames(allPackageNames, testedClasses); System.out.println("All class list: " + allClassListFileName); - System.out.println("Read " + allClasses.size() + " class names"); + System.out.println("Read " + (allClasses.size()) + " class names"); System.out.println("Tested class list: " + testedClassListFileName); - System.out.println("Read " + testedClasses.size() + " class names"); + System.out.println("Read " + (testedClasses.size()) + " class names"); - System.out.println("Setting list of " + allPackageNames.size() + " all package names"); - System.out.println("Setting list of " + usedPackageNames.size() + " used package names"); + System.out.println("Setting list of " + (allPackageNames.size()) + " all package names"); + System.out.println("Setting list of " + (usedPackageNames.size()) + " used package names"); System.out.println("Report directory: " + reportDirectory); @@ -430,18 +541,29 @@ printReportForAllClassesInOneFile(reportDirectory, usedPackageNames, testedClasses); printReportForAllPackages(reportDirectory, usedPackageNames, testedClasses); printReportForAllClasses(reportDirectory, testedClasses); + printSummaryPage(reportDirectory, allPackageNames, allClasses, testedClasses, usedPackageNames); } + /** + * Entry point to the report generator. + * + * @param args + * should contain name of file containing all class list, name of + * file containing tested class list and the report directory + */ public static void main(String[] args) { + // check if all parameters are specified on command line if (args.length != 3) { System.err.println("Usage allClassListFileName classListFileName reportDirectory"); System.exit(1); } + // resolve all three parameters String allClassListFileName = args[0]; String testedClassListFileName = args[1]; String reportDirectory = args[2]; + // and do the report prepareReport(allClassListFileName, testedClassListFileName, reportDirectory); } } diff -r 5ef74c026b81 -r 5849d5bfbee0 templates/class_template.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/templates/class_template.html Wed Jan 18 16:52:43 2012 +0100 @@ -0,0 +1,24 @@ + + + + Report for class: ${CLASS_NAME} + + + + + +

Report for class: ${CLASS_NAME}   summary

+ + + + + + + +${METHOD_LIST} +
MethodAPITested
+ + + + diff -r 5ef74c026b81 -r 5849d5bfbee0 templates/summary.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/templates/summary.html Wed Jan 18 16:52:43 2012 +0100 @@ -0,0 +1,45 @@ + + + + Summary + + + + + +

Summary

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Public API packages:${API_PACKAGES} 
Public API classes:${API_CLASSES} 
 
Checked packages:${TESTED_PACKAGES}${TESTED_PACKAGES_RATIO}
Checked classes:${TESTED_CLASSES}${TESTED_CLASSES_RATIO}
 
All classes 
+ + +