changeset 14:eec2474fdaaa

* src/ClassInfo.java: Added new helper class. * src/FileUtils.java: Added new method for reading contents of text file. Refactored. * src/ReportGenerator.java: New functionality: methods coverage are printed in package list (previously only class coverage were printed). Refactored. * templates/all_packages_template.html: * templates/index.html: Changed width of left column. * templates/style.css: Tables have black borders (they are more visible). * Makefile: Updated according to previous changes.
author Pavel Tisnovsky <ptisnovs@redhat.com>
date Fri, 23 Mar 2012 11:55:40 +0100
parents 8c9c61f17fd1
children ed99188fff20
files ChangeLog Makefile src/ClassInfo.java src/FileUtils.java src/ReportGenerator.java templates/all_packages_template.html templates/index.html templates/style.css
diffstat 8 files changed, 302 insertions(+), 104 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Fri Mar 16 11:24:48 2012 +0100
+++ b/ChangeLog	Fri Mar 23 11:55:40 2012 +0100
@@ -1,3 +1,23 @@
+2012-03-23  Pavel Tisnovsky  <ptisnovs@redhat.com>
+
+	* src/ClassInfo.java:
+	Added new helper class.
+	* src/FileUtils.java:
+	Added new method for reading contents of text file.
+	Refactored.
+	* src/ReportGenerator.java:
+	New functionality: methods coverage are printed
+	in package list (previously only class coverage
+	were printed).
+	Refactored.
+	* templates/all_packages_template.html:
+	* templates/index.html:
+	Changed width of left column.
+	* templates/style.css:
+	Tables have black borders (they are more visible).
+	* Makefile:
+	Updated according to previous changes.
+
 2012-03-16  Pavel Tisnovsky  <ptisnovs@redhat.com>
 
 	* src/ReportGenerator.java:
--- a/Makefile	Fri Mar 16 11:24:48 2012 +0100
+++ b/Makefile	Fri Mar 23 11:55:40 2012 +0100
@@ -74,7 +74,8 @@
 	$(CLASSDIR)/PrintPublicMethods.class \
 	$(CLASSDIR)/PrintTestCoverage.class \
 	$(CLASSDIR)/ReportGenerator.class \
-	$(CLASSDIR)/FileUtils.class
+	$(CLASSDIR)/FileUtils.class \
+	$(CLASSDIR)/ClassInfo.class
 
 api_class_list:	$(REPORTDIR) $(REPORTDIR)/$(ALL_CLASS_LIST)
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ClassInfo.java	Fri Mar 23 11:55:40 2012 +0100
@@ -0,0 +1,176 @@
+/*
+  Test coverage tool.
+
+   Copyright (C) 2012 Red Hat
+
+This tool is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This tool is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this tool; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version.
+*/
+
+import java.io.File;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+
+
+
+/**
+ * Instances of this class contain information about one tested class.
+ * There are three sets of strings stored for each class: set of methods
+ * contained in standard API, set of methods called from tests and the
+ * union of previous two sets. These information are used by test reporter.
+ * 
+ * @author Pavel Tisnovsky <ptisnovs@redhat.com>
+ */
+public class ClassInfo
+{
+    /**
+     * Set of methods contained in standard API.
+     */
+    private Set<String> apiMethods;
+
+    /**
+     * Set of methods called from tests.
+     */
+    private Set<String> testedMethods;
+
+    /**
+     * Union of apiMethods and testedMethods.
+     */
+    private Set<String> allMethods;
+
+    /**
+     * Constructor. It tries to read all required information
+     * for tested class.
+     * 
+     * @param reportDirectory
+     *            directory where all reports are stored
+     * @param className
+     *            name of tested class
+     */
+    public ClassInfo(String reportDirectory, String className)
+    {
+        // read methods described in standard API
+        this.apiMethods = readApiMethods(reportDirectory, className);
+        // read methods called from tests
+        this.testedMethods = readTestedMethods(reportDirectory, className);
+        // compute union of previous two sets
+        computeAllMethodsSet();
+    }
+
+    /**
+     * Compute union of allMethods and testedMethods sets.
+     */
+    private void computeAllMethodsSet()
+    {
+        this.allMethods = new TreeSet<String>();
+        this.allMethods.addAll(this.apiMethods);
+        this.allMethods.addAll(this.testedMethods);
+    }
+
+    /**
+     * Getter for a set apiMethods.
+     *
+     * @return the apiMethods attribute
+     */
+    public Set<String> getApiMethods()
+    {
+        return this.apiMethods;
+    }
+
+    /**
+     * Getter for a set testedMethods.
+     *
+     * @return the testedMethods attribute
+     */
+    public Set<String> getTestedMethods()
+    {
+        return this.testedMethods;
+    }
+
+    /**
+     * Getter for a set allMethods.
+     *
+     * @return the allMethods attribute
+     */
+    public Set<String> getAllMethods()
+    {
+        return this.allMethods;
+    }
+
+    /**
+     * Read all methods for a given class which are covered by a standard API.
+     * 
+     * @param reportDirectory
+     *            directory where all reports are stored
+     * @param testedClass
+     *            name of tested class
+     * @return set of all methods read from a file containing standard API
+     */
+    private static Set<String> readApiMethods(String reportDirectory, String testedClass)
+    {
+        File fileName = new File(reportDirectory, testedClass + "_api.txt");
+        return readMethods(fileName);
+    }
+
+    /**
+     * Read all methods for a given class which are called from tests.
+     * 
+     * @param reportDirectory
+     *            directory where all reports are stored
+     * @param testedClass
+     *            name of tested class
+     * @return set of all methods read from a file containing called methods
+     */
+    private static Set<String> readTestedMethods(String reportDirectory, String testedClass)
+    {
+        File fileName = new File(reportDirectory, testedClass + "_test.txt");
+        return readMethods(fileName);
+    }
+
+    /**
+     * Read set of method names from a text file. No exception is thrown during
+     * reading.
+     * 
+     * @param fileName
+     *            file containing methods list
+     * @return set of method names
+     */
+    private static Set<String> readMethods(File fileName)
+    {
+        Set<String> allMethods = new TreeSet<String>();
+        List<String> methodList = FileUtils.readTextFile(fileName.getAbsolutePath(), false);
+        allMethods.addAll(methodList);
+        return allMethods;
+    }
+
+}
--- a/src/FileUtils.java	Fri Mar 16 11:24:48 2012 +0100
+++ b/src/FileUtils.java	Fri Mar 23 11:55:40 2012 +0100
@@ -46,6 +46,7 @@
 import java.io.IOException;
 import java.io.InputStreamReader;
 import java.io.OutputStreamWriter;
+import java.util.Collection;
 import java.util.LinkedList;
 import java.util.List;
 
@@ -76,6 +77,21 @@
      */
     static List<String> readTextFile(String fileName)
     {
+        return readTextFile(fileName, true);
+    }
+
+    /**
+     * Read content of given text file and return it as list of strings. No
+     * exception is thrown during reading.
+     * 
+     * @param fileName
+     *            name of file to be read
+     * @param printFileNotFoundException
+     *            whether to print an exception when file is not found
+     * @return list of string containing content of text file
+     */
+    static List<String> readTextFile(String fileName, boolean printFileNotFoundException)
+    {
         BufferedReader reader = null;
         List<String> out = new LinkedList<String>();
         try
@@ -87,7 +103,12 @@
         catch (FileNotFoundException e)
         {
             // might happen - empty list is returned in this case
-            e.printStackTrace();
+            if (printFileNotFoundException)
+            {
+                // in some cases we don't want to see this exception
+                // (because some classes, for example, could not be tested at all)
+                e.printStackTrace();
+            }
         }
         catch (IOException e)
         {
@@ -215,7 +236,7 @@
      * @throws IOException
      *             thrown if an I/O error occurs
      */
-    private static void readAllLinesFromTextFile(BufferedReader bufferedReader, List<String> lines) throws IOException
+    private static void readAllLinesFromTextFile(BufferedReader bufferedReader, Collection<String> lines) throws IOException
     {
         String line;
         // read lines from a text file
--- a/src/ReportGenerator.java	Fri Mar 16 11:24:48 2012 +0100
+++ b/src/ReportGenerator.java	Fri Mar 23 11:55:40 2012 +0100
@@ -36,14 +36,10 @@
 exception statement from your version.
 */
 
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStreamReader;
+import java.util.HashMap;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 import java.util.TreeSet;
 
@@ -58,11 +54,6 @@
 public class ReportGenerator
 {
     /**
-     * Default charset used during all input/output operations.
-     */
-    private static final String DEFAULT_CHARSET = "UTF-8";
-
-    /**
      * Location of internal or external URI to standard API JavaDoc
      */
     private static final String DOC_BASE = "http://docs.oracle.com/javase/6/docs/api";
@@ -97,9 +88,10 @@
      *            set of tested classes
      * @param packageNames
      *            set of package names
+     * @param classInfoMap 
      */
     private static void printPackageListToFile(String reportDirectory, Set<String> allClasses,
-                    Set<String> testedClasses, Set<String> packageNames)
+                    Set<String> testedClasses, Set<String> packageNames, Map<String, ClassInfo> classInfoMap)
     {
         List<String> template = FileUtils.readTextFile("templates/all_packages_template.html");
         List<String> out = new LinkedList<String>();
@@ -109,7 +101,7 @@
             // replace text in template where needed
             if ("${PACKAGE_LIST}".equals(templateLine))
             {
-                addPackageList(allClasses, testedClasses, packageNames, out);
+                addPackageList(allClasses, testedClasses, packageNames, out, classInfoMap);
             }
             // normal line
             else
@@ -132,9 +124,10 @@
      *            package for which the report is generated
      * @param testedClasses
      *            set of tested classes
+     * @param classInfoMap 
      */
     private static void printReportForPackageToFile(String reportDirectory, String packageName,
-                    Set<String> testedClasses)
+                    Set<String> testedClasses, Map<String, ClassInfo> classInfoMap)
     {
         // read HTML template
         List<String> template = FileUtils.readTextFile("templates/package_template.html");
@@ -146,7 +139,7 @@
             // replace text in template where needed
             if ("${CLASS_LIST}".equals(templateLine))
             {
-                addClassList(reportDirectory, packageName, testedClasses, out);
+                addClassList(reportDirectory, packageName, testedClasses, out, classInfoMap);
             }
             else if ("${PACKAGE_NAME}".equals(templateLine))
             {
@@ -173,9 +166,10 @@
      *            all checked package names
      * @param testedClasses
      *            set of tested classes
+     * @param classInfoMap 
      */
     private static void printReportForAllClassesInOneFile(String reportDirectory, Set<String> usedPackageNames,
-                    Set<String> testedClasses)
+                    Set<String> testedClasses, Map<String, ClassInfo> classInfoMap)
     {
         List<String> template = FileUtils.readTextFile("templates/all_classes_template.html");
         List<String> out = new LinkedList<String>();
@@ -185,7 +179,7 @@
             // replace text in template where needed
             if ("${PACKAGE_AND_CLASS_LIST}".equals(templateLine))
             {
-                addPackageAndClassList(reportDirectory, usedPackageNames, testedClasses, out);
+                addPackageAndClassList(reportDirectory, usedPackageNames, testedClasses, out, classInfoMap);
             }
             // normal line
             else
@@ -214,25 +208,52 @@
      */
     @SuppressWarnings("boxing")
     private static void addPackageList(Set<String> allClasses, Set<String> testedClasses, Set<String> packageNames,
-                    List<String> out)
+                    List<String> out, Map<String, ClassInfo> classInfoMap)
     {
         // iterate through all package names
         for (String packageName : packageNames)
         {
             // compute number of all classes in a package
             final int allClassesCnt = numberOfClassesInPackage(packageName, allClasses);
-            // compute number of classes coveraged by tests
+            // compute number of classes covered by tests
             final int testedClassesCnt = numberOfClassesInPackage(packageName, testedClasses);
             // -> in percent
-            final float percentage = 100.0f*testedClassesCnt / allClassesCnt;
+            final float classPercentage = allClassesCnt == 0 ? 0.0f : 100.0f * testedClassesCnt / allClassesCnt;
+            // table row background color is based on percentual test coverage ration
+            String backgroundColor1 = generateTableRowBackground(classPercentage);
 
+            int allMethodsCnt=0;
+            int coveragedMethodsCnt=0;
+            for (String className : allClasses)
+            {
+                // count only classes in given package
+                if (className.startsWith(packageName))
+                {
+                    ClassInfo classInfo = classInfoMap.get(className);
+                    allMethodsCnt += classInfo.getAllMethods().size();
+                    coveragedMethodsCnt += classInfo.getTestedMethods().size();
+                }
+            }
+            float methodsPercentage = allMethodsCnt == 0 ? 0.0f : 100.0f * coveragedMethodsCnt / allMethodsCnt;
             // table row background color is based on percentual test coverage ration
-            String backgroundColor = generateTableRowBackground(percentage);
+            String backgroundColor2 = generateTableRowBackground(methodsPercentage);
+
+            // format output string
             String doc = DOC_BASE + "/" + packageName.replace('.', '/') + "/package-summary.html";
-            // format output string
-            String str = String.format("<tr style='background-color:%s'><td><a target='ClassesListFrame' href='%s.html'>%s</a></td><td style='text-align:right'>%d</td><td style='text-align:right'>%d</td><td style='text-align:right'>%5.1f %%</td><td style='text-align:right'><a href='%s' target='_blank'>ext</a></td></tr>",
-                            backgroundColor, packageName, packageName,
-                            allClassesCnt, testedClassesCnt, percentage, doc);
+
+            String str = String.format(
+                            "<tr><td><a target='ClassesListFrame' href='%s.html'>%s</a></td>" +
+                                 "<td style='background-color:%s;text-align:right'>%d</td>" +
+                                 "<td style='background-color:%s;text-align:right'>%d</td>" +
+                                 "<td style='background-color:%s;text-align:right'>%5.1f %%</td>" +
+                                 "<td style='background-color:%s;text-align:right'>%d</td>" +
+                                 "<td style='background-color:%s;text-align:right'>%d</td>" +
+                                 "<td style='background-color:%s;text-align:right'>%5.1f %%</td>" +
+                                 "<td style='text-align:right'><a href='%s' target='_blank'>ext</a></td></tr>",
+                            packageName, packageName,
+                            backgroundColor1, allClassesCnt, backgroundColor1, testedClassesCnt, backgroundColor1, classPercentage,
+                            backgroundColor2, allMethodsCnt, backgroundColor2, coveragedMethodsCnt, backgroundColor2, methodsPercentage,
+                            doc);
             out.add(str);
         }
     }
@@ -270,7 +291,7 @@
         for (String className : classes)
         {
             // count only classes in given package
-            if (className.startsWith(packageName))
+            if (className.substring(0, className.lastIndexOf('.')).equals(packageName))
             {
                 cnt++;
             }
@@ -288,8 +309,9 @@
      *            set of tested classes
      * @param out
      *            list of string which represents generated report
+     * @param classInfoMap 
      */
-    private static void addClassList(String reportDirectory, String packageName, Set<String> testedClasses, List<String> out)
+    private static void addClassList(String reportDirectory, String packageName, Set<String> testedClasses, List<String> out, Map<String, ClassInfo> classInfoMap)
     {
         // iterate through all class names
         for (String className : testedClasses)
@@ -298,7 +320,7 @@
             if (className.startsWith(packageName))
             {
                 //out.add("<a target='ResultsFrame' href='" + className + ".html'>" + className + "</a><br>");
-                out.add(addOneRowToResultsTable(reportDirectory, className));
+                out.add(addOneRowToResultsTable(reportDirectory, className, classInfoMap));
             }
         }
     }
@@ -315,8 +337,9 @@
      *            set of tested classes
      * @param out
      *            list of string which represents generated report
+     * @param classInfoMap 
      */
-    private static void addPackageAndClassList(String reportDirectory, Set<String> usedPackageNames, Set<String> testedClasses, List<String> out)
+    private static void addPackageAndClassList(String reportDirectory, Set<String> usedPackageNames, Set<String> testedClasses, List<String> out, Map<String, ClassInfo> classInfoMap)
     {
         // iterate through all class names
         for (String packageName : usedPackageNames)
@@ -329,7 +352,7 @@
             {
                 if (className.startsWith(packageName))
                 {
-                    out.add(addOneRowToResultsTable(reportDirectory, className));
+                    out.add(addOneRowToResultsTable(reportDirectory, className, classInfoMap));
                 }
             }
             out.add("</table>");
@@ -344,10 +367,10 @@
      * @param className
      *            name of tested class
      */
-    private static String addOneRowToResultsTable(String reportDirectory, String className)
+    private static String addOneRowToResultsTable(String reportDirectory, String className, Map<String, ClassInfo> classInfoMap)
     {
-        Set<String> apiMethods = readApiMethods(reportDirectory, className);
-        Set<String> testedMethods = readTestedMethods(reportDirectory, className);
+        Set<String> apiMethods = classInfoMap.get(className).getApiMethods();
+        Set<String> testedMethods = classInfoMap.get(className).getTestedMethods();
         // compute number of all methods in a class
         final int allMethodsCnt = apiMethods.size();
         // compute number of methods covered by tests
@@ -515,81 +538,31 @@
      *            packages for which the report is generated
      * @param testedClasses
      *            set of tested classes
+     * @param classInfoMap 
      */
     private static void printReportForAllPackages(String reportDirectory, Set<String> usedPackageNames,
-                    Set<String> testedClasses)
+                    Set<String> testedClasses, Map<String, ClassInfo> classInfoMap)
     {
         // iterate through all tested package names
         for (String packageName : usedPackageNames)
         {
-            printReportForPackageToFile(reportDirectory, packageName, testedClasses);
+            printReportForPackageToFile(reportDirectory, packageName, testedClasses, classInfoMap);
         }
     }
 
-    private static void printReportForAllClasses(String reportDirectory, Set<String> testedClasses)
+    private static void printReportForAllClasses(String reportDirectory, Set<String> testedClasses, Map<String, ClassInfo> classInfoMap)//String reportDirectory, Set<String> testedClasses)
     {
         // iterate through all tested classes
         for (String testedClass : testedClasses)
         {
-            Set<String> apiMethods = readApiMethods(reportDirectory, testedClass);
-            Set<String> testedMethods = readTestedMethods(reportDirectory, testedClass);
-            Set<String> allMethods = new TreeSet<String>();
-            allMethods.addAll(apiMethods);
-            allMethods.addAll(testedMethods);
+            ClassInfo classInfo = classInfoMap.get(testedClass);
+            Set<String> apiMethods = classInfo.getApiMethods();
+            Set<String> testedMethods = classInfo.getTestedMethods();
+            Set<String> allMethods = classInfo.getAllMethods();
             createFileForClass(reportDirectory, testedClass, allMethods, apiMethods, testedMethods);
         }
     }
 
-    private static Set<String> readApiMethods(String reportDirectory, String testedClass)
-    {
-        File fileName = new File(reportDirectory, testedClass + "_api.txt");
-        return readMethods(fileName);
-    }
-
-    private static Set<String> readTestedMethods(String reportDirectory, String testedClass)
-    {
-        File fileName = new File(reportDirectory, testedClass + "_test.txt");
-        return readMethods(fileName);
-    }
-
-    private static Set<String> readMethods(File fileName)
-    {
-        BufferedReader reader = null;
-        Set<String> allMethods = new TreeSet<String>();
-        try
-        {
-            reader = new BufferedReader(new InputStreamReader(new FileInputStream(fileName), DEFAULT_CHARSET));
-            String line;
-            while ((line = reader.readLine()) != null)
-            {
-                allMethods.add(line);
-            }
-        }
-        catch (FileNotFoundException e)
-        {
-            e.printStackTrace();
-        }
-        catch (IOException e)
-        {
-            e.printStackTrace();
-        }
-        finally
-        {
-            try
-            {
-                if (reader != null)
-                {
-                    reader.close();
-                }
-            }
-            catch (IOException e)
-            {
-                e.printStackTrace();
-            }
-        }
-        return allMethods;
-    }
-
     private static void printSummaryPage(String reportDirectory, Set<String> allPackageNames, Set<String> allClasses,
                     Set<String> testedClasses, Set<String> usedPackageNames)
     {
@@ -688,10 +661,16 @@
 
         System.out.println("Report directory:  " + reportDirectory);
 
-        printPackageListToFile(reportDirectory, allClasses, testedClasses, usedPackageNames);
-        printReportForAllClassesInOneFile(reportDirectory, usedPackageNames, testedClasses);
-        printReportForAllPackages(reportDirectory, usedPackageNames, testedClasses);
-        printReportForAllClasses(reportDirectory, testedClasses);
+        Map<String, ClassInfo> classInfoMap = new HashMap<String, ClassInfo>();
+        for (String className : allClasses)
+        {
+            classInfoMap.put(className, new ClassInfo(reportDirectory, className));
+        }
+
+        printPackageListToFile(reportDirectory, allClasses, testedClasses, usedPackageNames, classInfoMap);
+        printReportForAllClassesInOneFile(reportDirectory, usedPackageNames, testedClasses, classInfoMap);
+        printReportForAllPackages(reportDirectory, usedPackageNames, testedClasses, classInfoMap);
+        printReportForAllClasses(reportDirectory, testedClasses, classInfoMap);
         printSummaryPage(reportDirectory, allPackageNames, allClasses, testedClasses, usedPackageNames);
     }
 
--- a/templates/all_packages_template.html	Fri Mar 16 11:24:48 2012 +0100
+++ b/templates/all_packages_template.html	Fri Mar 23 11:55:40 2012 +0100
@@ -13,7 +13,8 @@
         <h1>Package list</h1>
 <a target='ClassesListFrame' href='all_classes.html'>all classes</a><br /><br />
 <table class='package_list'>
-<tr><th>package</th><th>classes</th><th>covered</th><th>ratio</th><th>doc</th></tr>
+<tr><th>package</th><th colspan='3'>classes</th><th colspan='3'>methods</th><th>doc</th></tr>
+<tr><th>&nbsp;</th><th>all</th><th>checked</th><th>ratio</th><th>all</th><th>covered</th><th>ratio</th><th>&nbsp;</th></tr>
 ${PACKAGE_LIST}
 </table>
     </body>
--- a/templates/index.html	Fri Mar 16 11:24:48 2012 +0100
+++ b/templates/index.html	Fri Mar 23 11:55:40 2012 +0100
@@ -3,7 +3,7 @@
     <head>
         <title>Test coverage report</title>
     </head>
-        <frameset cols="25%,75%" title="">
+        <frameset cols="30%,70%" title="">
         <frameset rows="40%,60%" title="">
             <frame src="all_packages.html" name="PackageListFrame" title="Package List" scrolling="yes">
             <frame src="all_classes.html" name="ClassesListFrame" title="All public classes" scrolling="yes">
--- a/templates/style.css	Fri Mar 16 11:24:48 2012 +0100
+++ b/templates/style.css	Fri Mar 23 11:55:40 2012 +0100
@@ -54,7 +54,7 @@
         border-width: 1px;
         padding: 1px;
         border-style: inset;
-        border-color: gray;
+        border-color: black;
         background-color: #c0c0ff;
         /* -moz-border-radius: ; */
 }
@@ -63,7 +63,7 @@
         border-width: 1px;
         padding: 1px;
         border-style: inset;
-        border-color: gray;
+        border-color: black;
         /* -moz-border-radius: ; */
 }
 
@@ -81,7 +81,7 @@
         border-width: 1px;
         padding: 1px;
         border-style: inset;
-        border-color: gray;
+        border-color: black;
         background-color: #c0c0ff;
         /* -moz-border-radius: ; */
 }
@@ -90,7 +90,7 @@
         border-width: 1px;
         padding: 1px;
         border-style: inset;
-        border-color: gray;
+        border-color: black;
         /* -moz-border-radius: ; */
 }