changeset 6:5849d5bfbee0

2012-01-18 Pavel Tisnovsky <ptisnovs@redhat.com> * 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.
author Pavel Tisnovsky <ptisnovs@redhat.com>
date Wed, 18 Jan 2012 16:52:43 +0100
parents 5ef74c026b81
children 342d366654ce
files ChangeLog src/ReportGenerator.java templates/class_template.html templates/summary.html
diffstat 4 files changed, 242 insertions(+), 41 deletions(-) [+]
line wrap: on
line diff
--- 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  <ptisnovs@redhat.com>
+
+	* 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  <ptisnovs@redhat.com>
 
 	* src/FileUtils.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<String> fileContent = FileUtils.readTextFile(allClassListFileName);
         // set of classes should be sorted
         Set<String> allClasses = new TreeSet<String>();
+        // add all lines read from a file to a set (and sort them)
         allClasses.addAll(fileContent);
         return allClasses;
     }
@@ -90,6 +89,7 @@
     {
         List<String> template = FileUtils.readTextFile("templates/all_packages_template.html");
         List<String> out = new LinkedList<String>();
+        // 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<String> template = FileUtils.readTextFile("templates/package_template.html");
         List<String> out = new LinkedList<String>();
+        // 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<String> template = FileUtils.readTextFile("templates/all_classes_template.html");
         List<String> out = new LinkedList<String>();
+        // 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<String> testedClasses, List<String> 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<String> usedPackageNames, Set<String> testedClasses, List<String> out)
     {
+        // iterate through all class names
         for (String packageName : usedPackageNames)
         {
             out.add("<h2>Package " + packageName + "</h2>");
@@ -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<String> allMethods, Set<String> apiMethods, Set<String> testedMethods)
     {
-        BufferedWriter fout = null;
-        try
+        List<String> template = FileUtils.readTextFile("templates/class_template.html");
+        List<String> out = new LinkedList<String>();
+        // iterate through whole template
+        for (String templateLine : template)
         {
-            fout = new BufferedWriter(new FileWriter(new File(reportDirectory, testClass + ".html")));
-            fout.write("<html>\n");
-            fout.write("<head>\n");
-            fout.write("<title>" + testClass + "</title>\n");
-            fout.write("</head>\n");
-            fout.write("<body>\n");
-            fout.write("<h1>Class " + testClass + "</h1>\n");
-            fout.write("<table>\n");
-            fout.write("<tr><th>Method</th><th><a href='"+testClass+"_api.txt'>API</a></th><th><a href='"+testClass+"_test.txt'>Tested</a></th></tr>\n");
-            for (String methodName : allMethods)
+            // replace text in template where needed
+            if (templateLine.contains("${CLASS_NAME}"))
             {
-                fout.write("<tr><td>" + constructPrintedMethodName(methodName) + "</td>");
-                fout.write(printMethodCoverage(methodName, apiMethods));
-                fout.write(printMethodCoverage(methodName, testedMethods));
-                fout.write("</tr>\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("</table>\n");
-            fout.write("</body>\n");
-            fout.write("</html>\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<String> allMethods, Set<String> apiMethods,
+                    Set<String> testedMethods, List<String> out)
+    {
+        // iterate through all methods
+        for (String methodName : allMethods)
         {
-            try
-            {
-                if (fout != null)
-                {
-                    fout.close();
-                }
-            }
-            catch (IOException e)
-            {
-                e.printStackTrace();
-            }
+            out.add("<tr><td>" + constructPrintedMethodName(methodName) + "</td>");
+            out.add(printMethodCoverage(methodName, apiMethods));
+            out.add(printMethodCoverage(methodName, testedMethods));
+            out.add("</tr>\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<String> preparePackageNames(Set<String> allClasses)
     {
         Set<String> packages = new TreeSet<String>();
+        // 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<String> allPackageNames, Set<String> allClasses,
+                    Set<String> testedClasses, Set<String> usedPackageNames)
+    {
+        final int numberOfAllPackages = allPackageNames.size();
+        final int numberOfAllClasses = allClasses.size();
+        final int numberOfUsedPackages = usedPackageNames.size();
+        final int numberOfTestedClasses = testedClasses.size();
+
+        List<String> template = FileUtils.readTextFile("templates/summary.html");
+        List<String> out = new LinkedList<String>();
+        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<String> 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);
     }
 }
--- /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 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+    <head>
+        <title>Report for class: ${CLASS_NAME}</title>
+        <meta name="Generator" content="MauveTestCoverage" />
+        <meta http-equiv="content-type" content="text/html; charset=utf-8" />
+        <link type="text/css" rel="StyleSheet" href="style.css" />
+    </head>
+    <body>
+        <h1>Report for class: ${CLASS_NAME}&nbsp;&nbsp;&nbsp;<a href='all_results.html'>summary</a></h1>
+
+        <table>
+            <tr>
+                <th>Method</th>
+                <th><a href="${CLASS_NAME}_api.txt">API</a></th>
+                <th><a href="${CLASS_NAME}_test.txt">Tested</a></th>
+            </tr>
+${METHOD_LIST}
+        </table>
+
+    </body>
+</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 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+    <head>
+        <title>Summary</title>
+        <meta name="Generator" content="MauveTestCoverage" />
+        <meta http-equiv="content-type" content="text/html; charset=utf-8" />
+        <link type="text/css" rel="StyleSheet" href="style.css" />
+    </head>
+    <body>
+        <h1>Summary</h1>
+        <table>
+            <tr>
+                <td>Public API packages:</td>
+                <td>${API_PACKAGES}</td>
+                <td>&nbsp;</td>
+            </tr>
+            <tr>
+                <td>Public API classes:</td>
+                <td>${API_CLASSES}</td>
+                <td>&nbsp;</td>
+            </tr>
+            <tr>
+                <td colspan='3'>&nbsp;</td>
+            </tr>
+            <tr>
+                <td>Checked packages:</td>
+                <td>${TESTED_PACKAGES}</td>
+                <td>${TESTED_PACKAGES_RATIO}</td>
+            </tr>
+            <tr>
+                <td>Checked classes:</td>
+                <td>${TESTED_CLASSES}</td>
+                <td>${TESTED_CLASSES_RATIO}</td>
+            </tr>
+            <tr>
+                <td colspan='2'>&nbsp;</td>
+            </tr>
+            <tr>
+                <td><a target='ClassesListFrame' href='all_classes.html'>All classes</a></td><td>&nbsp;</td>
+            </tr>
+        </table>
+    </body>
+</html>
+