Improve reporting
authorMathieu Baudier <mbaudier@argeo.org>
Sun, 18 Nov 2007 10:17:19 +0000 (10:17 +0000)
committerMathieu Baudier <mbaudier@argeo.org>
Sun, 18 Nov 2007 10:17:19 +0000 (10:17 +0000)
git-svn-id: https://svn.argeo.org/slc/trunk@716 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc

25 files changed:
org.argeo.slc/.classpath
org.argeo.slc/.settings/org.eclipse.jdt.core.prefs
org.argeo.slc/lib-src/commons-io-1.3.2-sources.jar [new file with mode: 0644]
org.argeo.slc/lib/commons-io-1.3.2.jar [new file with mode: 0644]
org.argeo.slc/src/main/java/org/argeo/slc/ant/taskdefs.properties
org.argeo.slc/src/main/java/org/argeo/slc/ant/test/SlcCloseTestResultTask.java
org.argeo.slc/src/main/java/org/argeo/slc/ant/test/SlcReportTask.java [new file with mode: 0644]
org.argeo.slc/src/main/java/org/argeo/slc/core/test/SimpleTestResult.java
org.argeo.slc/src/main/java/org/argeo/slc/core/test/TestResult.java
org.argeo.slc/src/main/java/org/argeo/slc/core/test/TestResultListener.java
org.argeo.slc/src/main/java/org/argeo/slc/core/test/tree/AsynchronousTreeTestResultListener.java
org.argeo.slc/src/main/java/org/argeo/slc/core/test/tree/FullHtmlTreeReport.java [deleted file]
org.argeo.slc/src/main/java/org/argeo/slc/core/test/tree/TreeTestResult.java
org.argeo.slc/src/main/java/org/argeo/slc/core/test/tree/TreeTestResultPersister.java
org.argeo.slc/src/main/java/org/argeo/slc/core/test/tree/htmlreport/FullHtmlTreeReport.java [new file with mode: 0644]
org.argeo.slc/src/main/java/org/argeo/slc/core/test/tree/htmlreport/ResultPage.java [new file with mode: 0644]
org.argeo.slc/src/main/java/org/argeo/slc/core/test/tree/htmlreport/ResultsList.java [new file with mode: 0644]
org.argeo.slc/src/main/java/org/argeo/slc/core/test/tree/htmlreport/index.html [new file with mode: 0644]
org.argeo.slc/src/main/java/org/argeo/slc/core/test/tree/htmlreport/style.css [new file with mode: 0644]
org.argeo.slc/src/main/java/org/argeo/slc/hibernate/test/tree/TreeTestResult.hbm.xml
org.argeo.slc/src/test/java/org/argeo/slc/example/junit/TestAntBuild.java
org.argeo.slc/src/test/java/org/argeo/slc/hibernate/test/tree/TreeTestResultDaoHibernateTest.java
org.argeo.slc/src/test/slc/conf/log4j.properties
org.argeo.slc/src/test/slc/conf/slc.xml
org.argeo.slc/src/test/slc/root/Category1/SubCategory2/build.xml

index 389d06896e2ed7bbb01c269ca473f3c5bfc37910..46fd2f448bb2e04d4b12e52e0e3532ef70788985 100644 (file)
@@ -21,6 +21,7 @@
        <classpathentry kind="lib" path="lib/jta.jar"/>\r
        <classpathentry kind="lib" path="lib/dbunit-2.2.jar" sourcepath="lib-src/dbunit-2.2-sources.jar"/>\r
        <classpathentry kind="lib" path="lib/junit-3.8.2.jar" sourcepath="lib-src/junit-3.8.2-sources.jar"/>\r
+       <classpathentry kind="lib" path="lib/commons-io-1.3.2.jar" sourcepath="lib-src/commons-io-1.3.2-sources.jar"/>\r
        <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>\r
        <classpathentry kind="output" path="target/classes"/>\r
 </classpath>\r
index e1ac4b347bdeafbb3c78f4fa0e0903127d210e8a..3a43ca756ef157ab51db3a977ae4b356d4b3ff82 100644 (file)
@@ -1,5 +1,13 @@
-#Sun Nov 11 11:22:17 CET 2007\r
+#Sun Nov 18 09:33:59 CET 2007\r
 eclipse.preferences.version=1\r
+org.eclipse.jdt.core.builder.cleanOutputFolder=clean\r
+org.eclipse.jdt.core.builder.duplicateResourceTask=warning\r
+org.eclipse.jdt.core.builder.invalidClasspath=abort\r
+org.eclipse.jdt.core.builder.recreateModifiedClassFileInOutputFolder=ignore\r
+org.eclipse.jdt.core.builder.resourceCopyExclusionFilter=*.launch,*.testsuite,*.deploy,*.location,*.execution,*.datapool,*.artifact,package.html,*.svg\r
+org.eclipse.jdt.core.circularClasspath=error\r
+org.eclipse.jdt.core.classpath.exclusionPatterns=enabled\r
+org.eclipse.jdt.core.classpath.multipleOutputLocations=enabled\r
 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled\r
 org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5\r
 org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve\r
@@ -7,6 +15,9 @@ org.eclipse.jdt.core.compiler.compliance=1.5
 org.eclipse.jdt.core.compiler.debug.lineNumber=generate\r
 org.eclipse.jdt.core.compiler.debug.localVariable=generate\r
 org.eclipse.jdt.core.compiler.debug.sourceFile=generate\r
+org.eclipse.jdt.core.compiler.maxProblemPerUnit=100\r
 org.eclipse.jdt.core.compiler.problem.assertIdentifier=error\r
 org.eclipse.jdt.core.compiler.problem.enumIdentifier=error\r
 org.eclipse.jdt.core.compiler.source=1.5\r
+org.eclipse.jdt.core.incompatibleJDKLevel=ignore\r
+org.eclipse.jdt.core.incompleteClasspath=error\r
diff --git a/org.argeo.slc/lib-src/commons-io-1.3.2-sources.jar b/org.argeo.slc/lib-src/commons-io-1.3.2-sources.jar
new file mode 100644 (file)
index 0000000..b383cf3
Binary files /dev/null and b/org.argeo.slc/lib-src/commons-io-1.3.2-sources.jar differ
diff --git a/org.argeo.slc/lib/commons-io-1.3.2.jar b/org.argeo.slc/lib/commons-io-1.3.2.jar
new file mode 100644 (file)
index 0000000..865c9e4
Binary files /dev/null and b/org.argeo.slc/lib/commons-io-1.3.2.jar differ
index 7ae6f6839311014ca82f46ad945f3ec8a273229d..85e0743c82abb04a29558e83c42a0c5aceb4bb7c 100644 (file)
@@ -2,3 +2,4 @@
 slc.test=org.argeo.slc.ant.test.SlcTestTask\r
 slc.deploy=org.argeo.slc.ant.deploy.SlcDeployTask\r
 slc.closeResult=org.argeo.slc.ant.test.SlcCloseTestResultTask\r
+slc.report=org.argeo.slc.ant.test.SlcReportTask\r
index 694bd5b4c968e599f5f6019fa4f10cee3a0259f4..660928abe6676a572f0f80c53d2ec57f2b7da79a 100644 (file)
@@ -6,26 +6,15 @@ import org.argeo.slc.core.structure.StructureRegistry;
 import org.argeo.slc.core.test.TestReport;\r
 import org.argeo.slc.core.test.TestResult;\r
 \r
-/** Ant tasks closing a given result, and optionally generating a report. */\r
+/** Ant tasks closing a given result. */\r
 public class SlcCloseTestResultTask extends SAwareTask {\r
        private String result;\r
-       private String report;\r
 \r
        @Override\r
        public void executeActions(String mode) {\r
                if (!mode.equals(StructureRegistry.READ)) {\r
                        TestResult testResult = (TestResult) getContext().getBean(result);\r
                        testResult.close();\r
-\r
-                       if (report != null) {\r
-                               TestReport testReport = (TestReport) getContext().getBean(\r
-                                               report);\r
-                               if (testReport instanceof StructureAware) {\r
-                                       ((StructureAware) testReport).notifyCurrentPath(\r
-                                                       getRegistry(), null);\r
-                               }\r
-                               testReport.generateTestReport(testResult);\r
-                       }\r
                }\r
        }\r
 \r
@@ -34,9 +23,4 @@ public class SlcCloseTestResultTask extends SAwareTask {
                this.result = bean;\r
        }\r
 \r
-       /** Sets the bean name of the report to generate. */\r
-       public void setReport(String report) {\r
-               this.report = report;\r
-       }\r
-\r
 }\r
diff --git a/org.argeo.slc/src/main/java/org/argeo/slc/ant/test/SlcReportTask.java b/org.argeo.slc/src/main/java/org/argeo/slc/ant/test/SlcReportTask.java
new file mode 100644 (file)
index 0000000..7587762
--- /dev/null
@@ -0,0 +1,40 @@
+package org.argeo.slc.ant.test;\r
+\r
+import org.argeo.slc.ant.structure.SAwareTask;\r
+import org.argeo.slc.core.structure.StructureAware;\r
+import org.argeo.slc.core.structure.StructureRegistry;\r
+import org.argeo.slc.core.test.TestReport;\r
+import org.argeo.slc.core.test.TestResult;\r
+\r
+/** Ant tasks generating a report. */\r
+public class SlcReportTask extends SAwareTask {\r
+       private String result;\r
+       private String report;\r
+\r
+       @Override\r
+       public void executeActions(String mode) {\r
+               if (!mode.equals(StructureRegistry.READ)) {\r
+                       TestResult testResult = null;\r
+                       if (result != null) {\r
+                               testResult = (TestResult) getContext().getBean(result);\r
+                       }\r
+                       TestReport testReport = (TestReport) getContext().getBean(report);\r
+                       if (testReport instanceof StructureAware) {\r
+                               ((StructureAware) testReport).notifyCurrentPath(getRegistry(),\r
+                                               null);\r
+                       }\r
+                       testReport.generateTestReport(testResult);\r
+               }\r
+       }\r
+\r
+       /** Sets the bean name of the result to close. */\r
+       public void setResult(String bean) {\r
+               this.result = bean;\r
+       }\r
+\r
+       /** Sets the bean name of the report to generate. */\r
+       public void setReport(String report) {\r
+               this.report = report;\r
+       }\r
+\r
+}\r
index 88bf8b394eedeaad98bc31c5d53d888aba23e171..3f673305d6b72731435eeb7787db58488fcd432c 100644 (file)
@@ -1,15 +1,21 @@
 package org.argeo.slc.core.test;\r
 \r
+import java.util.Date;\r
 import java.util.List;\r
 import java.util.Vector;\r
 \r
 import org.apache.commons.logging.Log;\r
 import org.apache.commons.logging.LogFactory;\r
 \r
+/**\r
+ * Basic implementation of a test result containing only a list of result\r
+ * parts.\r
+ */\r
 public class SimpleTestResult implements TestResult {\r
        private static Log log = LogFactory.getLog(SimpleTestResult.class);\r
 \r
        private TestResultId testResultId;\r
+       private Date closeDate;\r
        private List<TestResultPart> parts = new Vector<TestResultPart>();\r
 \r
        public void addResultPart(TestResultPart part) {\r
@@ -20,12 +26,14 @@ public class SimpleTestResult implements TestResult {
 \r
        public void close() {\r
                parts.clear();\r
+               closeDate = new Date();\r
        }\r
 \r
        public TestResultId getTestResultId() {\r
                return testResultId;\r
        }\r
 \r
+       /** Sets the test result id. */\r
        public void setTestResultId(TestResultId testResultId) {\r
                this.testResultId = testResultId;\r
        }\r
@@ -34,4 +42,8 @@ public class SimpleTestResult implements TestResult {
                return parts;\r
        }\r
 \r
+       public Date getCloseDate() {\r
+               return closeDate;\r
+       }\r
+\r
 }\r
index 5d6e3421f075f99c937325c1b4daaaf28387ce65..860fe1caf5bb46deb584c03024f1106854c8264d 100644 (file)
@@ -1,5 +1,7 @@
 package org.argeo.slc.core.test;\r
 \r
+import java.util.Date;\r
+\r
 /** The result of a test */\r
 public interface TestResult {\r
        /** Gets the id of the related test result. */\r
@@ -13,4 +15,10 @@ public interface TestResult {
         * related resources (also closing listeners).\r
         */\r
        public void close();\r
+\r
+       /**\r
+        * The date when this test result was closed. Can be null, which means the\r
+        * result is not closed.\r
+        */\r
+       public Date getCloseDate();\r
 }\r
index 10b296448555f3b583477903613f4b89a863f2d7..0d774a71eea7948f252591dd139f6ed1c965b9c0 100644 (file)
@@ -7,5 +7,5 @@ public interface TestResultListener {
                        TestResultPart testResultPart);\r
 \r
        /** Stops listening and release the related resources. */\r
-       public void close();\r
+       public void close(TestResult testResult);\r
 }\r
index 3ac38de5dd44953c602efb9a06bbcecd9a13b4a4..c3bc793ef5f357d03a16b821c1dd067f5163f83b 100644 (file)
@@ -26,7 +26,7 @@ public abstract class AsynchronousTreeTestResultListener implements
        }\r
 \r
        /** Finish the remaining and destroy */\r
-       public void close() {\r
+       public void close(TestResult testResult) {\r
                synchronized (partStructs) {\r
                        // TODO: put a timeout\r
                        while (partStructs.size() != 0) {\r
@@ -39,6 +39,7 @@ public abstract class AsynchronousTreeTestResultListener implements
                        thread = null;\r
                        partStructs.notifyAll();\r
                }\r
+               postClose((TreeTestResult)testResult);\r
        }\r
 \r
        public final void resultPartAdded(TestResult testResult,\r
@@ -55,6 +56,14 @@ public abstract class AsynchronousTreeTestResultListener implements
        /** Called when a result part has been added. */\r
        protected abstract void resultPartAdded(PartStruct partStruct);\r
 \r
+       /**\r
+        * Called at the end of close. Default implementation is empty. To be\r
+        * overridden.\r
+        */\r
+       protected void postClose(TreeTestResult testResult) {\r
+\r
+       }\r
+\r
        public void run() {\r
                while (thread != null) {\r
                        synchronized (partStructs) {\r
diff --git a/org.argeo.slc/src/main/java/org/argeo/slc/core/test/tree/FullHtmlTreeReport.java b/org.argeo.slc/src/main/java/org/argeo/slc/core/test/tree/FullHtmlTreeReport.java
deleted file mode 100644 (file)
index dd41847..0000000
+++ /dev/null
@@ -1,183 +0,0 @@
-package org.argeo.slc.core.test.tree;\r
-\r
-import java.io.File;\r
-import java.io.FileWriter;\r
-import java.io.IOException;\r
-import java.util.List;\r
-\r
-import org.argeo.slc.core.SlcException;\r
-import org.argeo.slc.core.structure.StructureAware;\r
-import org.argeo.slc.core.structure.StructureElement;\r
-import org.argeo.slc.core.structure.StructurePath;\r
-import org.argeo.slc.core.structure.StructureRegistry;\r
-import org.argeo.slc.core.structure.tree.TreeSPath;\r
-import org.argeo.slc.core.test.SimpleResultPart;\r
-import org.argeo.slc.core.test.TestReport;\r
-import org.argeo.slc.core.test.TestResult;\r
-import org.argeo.slc.core.test.TestResultPart;\r
-import org.argeo.slc.dao.structure.tree.TreeSRegistryDao;\r
-import org.argeo.slc.dao.test.TestResultDao;\r
-\r
-/**\r
- * Basic implementation of TestReport generating static HTML pages. If a\r
- * <code>TestResultDao</code> is passed, all the datas are dumped, otherwise\r
- * only the passed <code>TestResult</code>.\r
- */\r
-public class FullHtmlTreeReport implements TestReport, StructureAware {\r
-       private TestResultDao testResultDao;\r
-       private TreeSRegistryDao treeSRegistryDao;\r
-       private File reportDir;\r
-\r
-       private StructureRegistry registry;\r
-\r
-       public void generateTestReport(TestResult testResult) {\r
-               \r
-               if (testResultDao == null) {\r
-                       TreeTestResult result = (TreeTestResult) testResult;\r
-                       initRegistry(result.getResultParts().firstKey());\r
-                       generateResultPage(getResultFile(result), result);\r
-               } else {\r
-                       if (reportDir.exists()) {\r
-                               // clean\r
-                               for (File file : reportDir.listFiles()) {\r
-                                       file.delete();\r
-                               }\r
-                       }\r
-                       reportDir.mkdirs();\r
-\r
-                       StringBuffer index = new StringBuffer("");\r
-                       index\r
-                                       .append("<html><header><title>Results</title></header><body>\n<table border=1>\n");\r
-\r
-                       List<TestResult> list = testResultDao.listTestResults();\r
-                       for (TestResult testRes : list) {\r
-                               TreeTestResult result = (TreeTestResult) testRes;\r
-                               initRegistry(result.getResultParts().firstKey());\r
-\r
-                               File file = getResultFile(result);\r
-                               index.append("<tr><td><a href=\"").append(file.getName())\r
-                                               .append("\">");\r
-                               index.append(result.getTestResultId()).append("</a></td></tr>\n");\r
-                               generateResultPage(file, result);\r
-                       }\r
-\r
-                       index.append("</table>\n</body></html>");\r
-\r
-                       try {\r
-                               FileWriter writer = new FileWriter(reportDir.getPath()\r
-                                               + File.separator + "index.html");\r
-                               writer.write(index.toString());\r
-                               writer.close();\r
-                       } catch (IOException e) {\r
-                               e.printStackTrace();\r
-                       }\r
-\r
-               }\r
-       }\r
-\r
-       /**\r
-        * Generates a result page for one test result\r
-        * \r
-        * @param file\r
-        *            file to which generate the HTML\r
-        * @param result\r
-        *            the result to dump\r
-        */\r
-       protected void generateResultPage(File file, TreeTestResult result) {\r
-               StringBuffer buf = new StringBuffer("");\r
-               buf.append("<html>\n");\r
-               buf.append("<header><title>Result #").append(result.getTestResultId())\r
-                               .append("</title></header>\n");\r
-\r
-               buf.append("<body>\n");\r
-\r
-               buf.append("<h1>Result #").append(result.getTestResultId()).append(\r
-                               "</h1>\n");\r
-\r
-               buf.append("<table border=1>\n");\r
-               for (TreeSPath path : result.getResultParts().keySet()) {\r
-                       buf.append("<tr><td>");\r
-                       buf.append(path);\r
-                       StructureElement element = registry.getElement(path);\r
-                       if (registry != null) {\r
-                               if (element != null) {\r
-                                       buf.append("<br/><b>");\r
-                                       buf.append(element.getDescription());\r
-                                       buf.append("</b>");\r
-                               }\r
-                       }\r
-                       buf.append("</td>\n");\r
-                       buf.append("<td>");\r
-                       PartSubList subList = (PartSubList) result.getResultParts().get(\r
-                                       path);\r
-                       buf.append("<table border=0>\n");\r
-                       for (TestResultPart part : subList.getParts()) {\r
-                               SimpleResultPart sPart = (SimpleResultPart) part;\r
-                               String color = "yellow";\r
-                               if (sPart.getStatus().equals(SimpleResultPart.PASSED)) {\r
-                                       color = "green";\r
-                               } else {\r
-                                       color = "red";\r
-                               }\r
-                               buf.append("<tr><td style=\"color:").append(color)\r
-                                               .append("\">");\r
-\r
-                               buf.append(sPart.getMessage());\r
-                               buf.append("</td></tr>\n");\r
-                       }\r
-                       buf.append("</table>\n");\r
-\r
-                       buf.append("</td></tr>\n");\r
-               }\r
-               buf.append("</table>\n");\r
-\r
-               buf.append("</body>");\r
-               buf.append("</html>");\r
-\r
-               try {\r
-                       FileWriter writer = new FileWriter(file);\r
-                       writer.write(buf.toString());\r
-                       writer.close();\r
-               } catch (IOException e) {\r
-                       e.printStackTrace();\r
-               }\r
-       }\r
-\r
-       /**\r
-        * Generates a result file location based on the report dir and the id of\r
-        * the test result.\r
-        */\r
-       protected File getResultFile(TreeTestResult result) {\r
-               return new File(reportDir.getPath() + File.separator\r
-                               + result.getTestResultId() + ".html");\r
-       }\r
-\r
-       /** Sets the DAO to use to extract all data. */\r
-       public void setTestResultDao(TestResultDao testResultDao) {\r
-               this.testResultDao = testResultDao;\r
-       }\r
-\r
-       /** Sets the tree structure registry DAO.*/\r
-       public void setTreeSRegistryDao(TreeSRegistryDao treeSRegistryDao) {\r
-               this.treeSRegistryDao = treeSRegistryDao;\r
-       }\r
-\r
-       /** Sets the directory where to generate all the data. */\r
-       public void setReportDir(File reportDir) {\r
-               this.reportDir = reportDir;\r
-       }\r
-\r
-       private void initRegistry(TreeSPath path){\r
-               if(treeSRegistryDao != null){\r
-                       registry = treeSRegistryDao.getTreeSRegistry(path);\r
-               }\r
-               if(registry==null){\r
-                       throw new SlcException("No structure registry available");\r
-               }\r
-       }\r
-       \r
-       public void notifyCurrentPath(StructureRegistry registry, StructurePath path) {\r
-               this.registry = registry;\r
-       }\r
-\r
-}\r
index fb1b0130c951027a29f576381bd38357d47d5476..dc0f3aa59f5eb980f9071ed6548c53fe5c98cee0 100644 (file)
@@ -1,5 +1,6 @@
 package org.argeo.slc.core.test.tree;\r
 \r
+import java.util.Date;\r
 import java.util.List;\r
 import java.util.SortedMap;\r
 import java.util.TreeMap;\r
@@ -32,6 +33,8 @@ public class TreeTestResult implements TestResult, StructureAware {
        private List<TestResultListener> listeners = new Vector<TestResultListener>();\r
 \r
        private TreeSPath currentPath;\r
+       \r
+       private Date closeDate;\r
 \r
        private boolean isClosed = false;\r
 \r
@@ -105,14 +108,16 @@ public class TreeTestResult implements TestResult, StructureAware {
                        throw new SlcException("Test Result #" + getTestResultId()\r
                                        + " alredy closed.");\r
                }\r
+               closeDate = new Date();\r
 \r
                synchronized (listeners) {\r
                        for (TestResultListener listener : listeners) {\r
-                               listener.close();\r
+                               listener.close(this);\r
                        }\r
                        listeners.clear();\r
                }\r
                isClosed = true;\r
+               \r
                log.info("Test Result #" + getTestResultId() + " closed.");\r
        }\r
 \r
@@ -134,4 +139,13 @@ public class TreeTestResult implements TestResult, StructureAware {
                this.registry = registry;\r
        }\r
 \r
+       public Date getCloseDate() {\r
+               return closeDate;\r
+       }\r
+\r
+       /** Sets the close date (for ORM)*/\r
+       public void setCloseDate(Date closeDate) {\r
+               this.closeDate = closeDate;\r
+       }\r
+\r
 }\r
index 0621574292f2af41081d1fe1f61d23840c749f00..29c73d2fff2e73aadd45abcbef3452d026ae62cf 100644 (file)
@@ -76,6 +76,20 @@ public class TreeTestResultPersister extends AsynchronousTreeTestResultListener
                }\r
        }\r
 \r
+       @Override\r
+       protected void postClose(TreeTestResult testResult) {\r
+               TreeTestResult persistedResult = (TreeTestResult) testResultDao\r
+                               .getTestResult(testResult.getTestResultId());\r
+\r
+               if (persistedResult != null) {\r
+                       persistedResult.setCloseDate(testResult.getCloseDate());\r
+                       testResultDao.update(persistedResult);\r
+               }\r
+               if (log.isDebugEnabled())\r
+                       log.debug("Closed result persister for result "\r
+                                       + testResult.getNumericResultId());\r
+       }\r
+\r
        private TreeSRegistry getOrCreateTreeSRegistry(TreeSPath path) {\r
                TreeSRegistry registry = treeSRegistryDao.getTreeSRegistry(path);\r
                if (registry == null) {\r
diff --git a/org.argeo.slc/src/main/java/org/argeo/slc/core/test/tree/htmlreport/FullHtmlTreeReport.java b/org.argeo.slc/src/main/java/org/argeo/slc/core/test/tree/htmlreport/FullHtmlTreeReport.java
new file mode 100644 (file)
index 0000000..076da8f
--- /dev/null
@@ -0,0 +1,138 @@
+package org.argeo.slc.core.test.tree.htmlreport;\r
+\r
+import java.io.File;\r
+import java.io.FileOutputStream;\r
+import java.io.InputStream;\r
+import java.text.SimpleDateFormat;\r
+import java.util.List;\r
+\r
+import org.dbunit.dataset.IDataSet;\r
+import org.dbunit.dataset.xml.FlatXmlDataSet;\r
+import org.hsqldb.lib.FileUtil;\r
+\r
+import org.apache.commons.io.FileUtils;\r
+import org.apache.commons.io.IOUtils;\r
+\r
+import org.argeo.slc.core.SlcException;\r
+import org.argeo.slc.core.structure.StructureAware;\r
+import org.argeo.slc.core.structure.StructurePath;\r
+import org.argeo.slc.core.structure.StructureRegistry;\r
+import org.argeo.slc.core.structure.tree.TreeSPath;\r
+import org.argeo.slc.core.test.TestReport;\r
+import org.argeo.slc.core.test.TestResult;\r
+import org.argeo.slc.core.test.tree.TreeTestResult;\r
+import org.argeo.slc.dao.structure.tree.TreeSRegistryDao;\r
+import org.argeo.slc.dao.test.TestResultDao;\r
+\r
+/**\r
+ * Basic implementation of TestReport generating static HTML pages. If a\r
+ * <code>TestResultDao</code> is passed, all the data is dumped, otherwise\r
+ * only the passed <code>TestResult</code>.\r
+ */\r
+public class FullHtmlTreeReport implements TestReport, StructureAware {\r
+       SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd hh:mm:ss");\r
+\r
+       private TestResultDao testResultDao;\r
+       private TreeSRegistryDao treeSRegistryDao;\r
+       private File reportDir;\r
+\r
+       private StructureRegistry localRegistry;\r
+\r
+       public void generateTestReport(TestResult testResult) {\r
+\r
+               if (testResultDao == null) {\r
+                       if (testResult == null)\r
+                               throw new SlcException(\r
+                                               "Cannot generate report without DAO or result instance.");\r
+\r
+                       TreeTestResult result = (TreeTestResult) testResult;\r
+                       ResultPage page = new ResultPage(this, result);\r
+                       page.generate(getRegistry(result));\r
+               } else {\r
+                       if (reportDir.exists()) {\r
+                               // clean\r
+                               for (File file : reportDir.listFiles()) {\r
+                                       file.delete();\r
+                               }\r
+                       }\r
+                       reportDir.mkdirs();\r
+\r
+                       resourceToFile("index.html");\r
+                       resourceToFile("style.css");\r
+\r
+                       ResultsList index = new ResultsList(this);\r
+                       List<TestResult> list = testResultDao.listTestResults();\r
+                       for (TestResult testRes : list) {\r
+                               TreeTestResult result = (TreeTestResult) testRes;\r
+\r
+                               index.addTestResult(result);\r
+                               ResultPage page = new ResultPage(this, result);\r
+                               page.generate(getRegistry(result));\r
+                       }\r
+                       index.close();\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Generates a result file location based on the report dir and the id of\r
+        * the test result.\r
+        */\r
+       protected File getResultFile(TreeTestResult result) {\r
+               return new File(reportDir.getPath() + File.separator + "slc-result-"\r
+                               + result.getTestResultId() + ".html");\r
+       }\r
+\r
+       /** Sets the DAO to use to extract all data. */\r
+       public void setTestResultDao(TestResultDao testResultDao) {\r
+               this.testResultDao = testResultDao;\r
+       }\r
+\r
+       /** Sets the tree structure registry DAO. */\r
+       public void setTreeSRegistryDao(TreeSRegistryDao treeSRegistryDao) {\r
+               this.treeSRegistryDao = treeSRegistryDao;\r
+       }\r
+\r
+       /** Sets the directory where to generate all the data. */\r
+       public void setReportDir(File reportDir) {\r
+               this.reportDir = reportDir;\r
+       }\r
+\r
+       private StructureRegistry getRegistry(TreeTestResult result) {\r
+               StructureRegistry registry = null;\r
+               if (treeSRegistryDao != null) {\r
+                       TreeSPath path = result.getResultParts().firstKey();\r
+                       registry = treeSRegistryDao.getTreeSRegistry(path);\r
+               }\r
+               if (registry == null) {\r
+                       registry = localRegistry;\r
+               }\r
+               if (registry == null) {\r
+                       throw new SlcException("No structure registry available");\r
+               }\r
+               return registry;\r
+       }\r
+\r
+       public void notifyCurrentPath(StructureRegistry registry, StructurePath path) {\r
+               this.localRegistry = registry;\r
+       }\r
+\r
+       File getReportDir() {\r
+               return reportDir;\r
+       }\r
+\r
+       private void resourceToFile(String resourceName) {\r
+               try {\r
+                       File file = new File(getReportDir() + File.separator + resourceName);\r
+                       InputStream in = FullHtmlTreeReport.class\r
+                                       .getResourceAsStream(resourceName);\r
+                       FileOutputStream out = new FileOutputStream(file);\r
+                       IOUtils.copy(in, out);\r
+                       IOUtils.closeQuietly(in);\r
+                       IOUtils.closeQuietly(out);\r
+               } catch (Exception e) {\r
+                       throw new SlcException("Cannot load resource", e);\r
+               }\r
+\r
+       }\r
+\r
+}\r
diff --git a/org.argeo.slc/src/main/java/org/argeo/slc/core/test/tree/htmlreport/ResultPage.java b/org.argeo.slc/src/main/java/org/argeo/slc/core/test/tree/htmlreport/ResultPage.java
new file mode 100644 (file)
index 0000000..c03a458
--- /dev/null
@@ -0,0 +1,95 @@
+package org.argeo.slc.core.test.tree.htmlreport;\r
+\r
+import java.io.FileWriter;\r
+import java.io.IOException;\r
+\r
+import org.argeo.slc.core.structure.StructureElement;\r
+import org.argeo.slc.core.structure.StructureRegistry;\r
+import org.argeo.slc.core.structure.tree.TreeSPath;\r
+import org.argeo.slc.core.test.SimpleResultPart;\r
+import org.argeo.slc.core.test.TestResultPart;\r
+import org.argeo.slc.core.test.tree.PartSubList;\r
+import org.argeo.slc.core.test.tree.TreeTestResult;\r
+\r
+class ResultPage {\r
+       private final FullHtmlTreeReport report;\r
+       private final TreeTestResult result;\r
+\r
+       ResultPage(FullHtmlTreeReport report, TreeTestResult result) {\r
+               this.report = report;\r
+               this.result = result;\r
+       }\r
+\r
+       /**\r
+        * Generates a result page for one test result\r
+        * \r
+        * @param file\r
+        *            file to which generate the HTML\r
+        * @param result\r
+        *            the result to dump\r
+        */\r
+       protected void generate(StructureRegistry registry) {\r
+               StringBuffer buf = new StringBuffer("");\r
+               buf.append("<html>\n");\r
+               buf.append("<header>");\r
+               buf.append("<title>Result #").append(result.getTestResultId()).append(\r
+                               "</title>\n");\r
+               buf\r
+                               .append("<link href=\"style.css\" rel=\"stylesheet\" type=\"text/css\"/>");\r
+               buf.append("</header>\n");\r
+\r
+               buf.append("<body>\n");\r
+\r
+               buf.append("<h1>Result #").append(result.getTestResultId()).append(\r
+                               "</h1>\n");\r
+\r
+               buf.append("<table border=1>\n");\r
+               for (TreeSPath path : result.getResultParts().keySet()) {\r
+                       buf.append("<tr><td>");\r
+                       buf.append(path);\r
+                       if (registry != null) {\r
+                               StructureElement element = registry.getElement(path);\r
+                               if (element != null) {\r
+                                       buf.append("<br/><b>");\r
+                                       buf.append(element.getDescription());\r
+                                       buf.append("</b>");\r
+                               }\r
+                       }\r
+                       buf.append("</td>\n");\r
+                       buf.append("<td>");\r
+                       PartSubList subList = (PartSubList) result.getResultParts().get(\r
+                                       path);\r
+                       buf.append("<table border=0>\n");\r
+                       for (TestResultPart part : subList.getParts()) {\r
+                               SimpleResultPart sPart = (SimpleResultPart) part;\r
+                               String color = "yellow";\r
+                               if (sPart.getStatus().equals(SimpleResultPart.PASSED)) {\r
+                                       color = "green";\r
+                               } else {\r
+                                       color = "red";\r
+                               }\r
+                               buf.append("<tr><td style=\"color:").append(color)\r
+                                               .append("\">");\r
+\r
+                               buf.append(sPart.getMessage());\r
+                               buf.append("</td></tr>\n");\r
+                       }\r
+                       buf.append("</table>\n");\r
+\r
+                       buf.append("</td></tr>\n");\r
+               }\r
+               buf.append("</table>\n");\r
+\r
+               buf.append("</body>");\r
+               buf.append("</html>");\r
+\r
+               try {\r
+                       FileWriter writer = new FileWriter(report.getResultFile(result));\r
+                       writer.write(buf.toString());\r
+                       writer.close();\r
+               } catch (IOException e) {\r
+                       e.printStackTrace();\r
+               }\r
+       }\r
+\r
+}\r
diff --git a/org.argeo.slc/src/main/java/org/argeo/slc/core/test/tree/htmlreport/ResultsList.java b/org.argeo.slc/src/main/java/org/argeo/slc/core/test/tree/htmlreport/ResultsList.java
new file mode 100644 (file)
index 0000000..e191f5f
--- /dev/null
@@ -0,0 +1,63 @@
+package org.argeo.slc.core.test.tree.htmlreport;\r
+\r
+import java.io.File;\r
+import java.io.FileWriter;\r
+import java.io.IOException;\r
+import java.util.Date;\r
+\r
+import org.argeo.slc.core.SlcException;\r
+import org.argeo.slc.core.test.tree.TreeTestResult;\r
+\r
+class ResultsList {\r
+       private final FullHtmlTreeReport report;\r
+       private final StringBuffer buf = new StringBuffer("");\r
+\r
+       ResultsList(FullHtmlTreeReport report) {\r
+               this.report = report;\r
+\r
+               buf.append("<html><header><title>Results</title></header><body>");\r
+               buf.append("<header>");\r
+               buf.append("<title>Results</title>\n");\r
+               buf\r
+                               .append("<link href=\"style.css\" rel=\"stylesheet\" type=\"text/css\"/>");\r
+               buf.append("</header>\n");\r
+               buf.append("<body>\n");\r
+\r
+               buf.append("<h1>Results</h1>\n");\r
+               buf.append("<table border=\"1\" cellspacing=\"0\">\n");\r
+       }\r
+\r
+       void addTestResult(TreeTestResult result) {\r
+               buf.append("<tr>\n");\r
+               // Date\r
+               buf.append("<td>");\r
+               Date closeDate = result.getCloseDate();\r
+               if(closeDate == null){\r
+                       throw new SlcException("No close date");\r
+               }\r
+               buf.append(report.sdf.format(closeDate));\r
+               buf.append("</td>\n");\r
+               // Id and link\r
+               buf.append("<td><a href=\"");\r
+               buf.append(report.getResultFile(result).getName());\r
+               buf.append("\" target=\"main\">");\r
+               buf.append(result.getTestResultId()).append("</a></td>\n");\r
+               \r
+               buf.append("</tr>\n");\r
+       }\r
+\r
+       void close() {\r
+               buf.append("</table>\n</body></html>");\r
+\r
+               try {\r
+                       FileWriter writer = new FileWriter(report.getReportDir().getPath()\r
+                                       + File.separator + "slc-resultsList.html");\r
+                       writer.write(buf.toString());\r
+                       writer.close();\r
+               } catch (IOException e) {\r
+                       e.printStackTrace();\r
+               }\r
+\r
+       }\r
+\r
+}\r
diff --git a/org.argeo.slc/src/main/java/org/argeo/slc/core/test/tree/htmlreport/index.html b/org.argeo.slc/src/main/java/org/argeo/slc/core/test/tree/htmlreport/index.html
new file mode 100644 (file)
index 0000000..ca5836d
--- /dev/null
@@ -0,0 +1,17 @@
+<html>\r
+<head>\r
+<META http-equiv="Content-Type" content="text/html; charset=US-ASCII">\r
+<title>SLC test results</title>\r
+<link href="style.css" rel="stylesheet" type="text/css"/>\r
+</head>\r
+<frameset cols="20%,80%">\r
+       <frame src="slc-resultsList.html" name="navigation">\r
+       <frame src="about:blank" name="main">\r
+       <noframes>\r
+       <h2>Frame Alert</h2>\r
+       <p>This document is designed to be viewed using the frames feature.\r
+       If you see this message, you are using a non-frame-capable web client.\r
+       </p>\r
+       </noframes>\r
+</frameset>\r
+</html>\r
diff --git a/org.argeo.slc/src/main/java/org/argeo/slc/core/test/tree/htmlreport/style.css b/org.argeo.slc/src/main/java/org/argeo/slc/core/test/tree/htmlreport/style.css
new file mode 100644 (file)
index 0000000..d7e7730
--- /dev/null
@@ -0,0 +1,151 @@
+/* Generic Selectors */\r
+body {\r
+       font-family: sans-serif;\r
+       font-size: 12px;\r
+       color: black;\r
+       background-color: white;\r
+}\r
+\r
+li {\r
+       list-style-type: none;\r
+}\r
+\r
+h1 {\r
+       font-family: sans-serif;\r
+       font-size: 16px;\r
+       font-weight: bold;\r
+       color: #000000;\r
+       padding: 0px 0px 5px 0px;\r
+       margin: 0px;\r
+}\r
+\r
+h2 {\r
+       font-family: sans-serif;\r
+       font-size: 14px;\r
+       font-weight: bold;\r
+       color: #000000;\r
+       padding: 5px 0px 5px 0px;\r
+       margin: 0px;\r
+       margin-top: 5px;\r
+}\r
+\r
+table,form {\r
+       margin: 0px;\r
+}\r
+\r
+img {\r
+       border: none;\r
+}\r
+\r
+div {\r
+       font-size: 100%;\r
+}\r
+\r
+tr.list:hover {\r
+       background-color: lightgrey;\r
+}\r
+\r
+td.list {\r
+       border-top: 1px solid lighgrey;\r
+       padding: 2px 20px 2px 2px;\r
+       padding-right: 15px;\r
+}\r
+\r
+th {\r
+       font-size: 12px;\r
+       padding: 2px 20px 2px 2px;\r
+       vertical-align: top;\r
+       text-align: left;\r
+}\r
+\r
+td {\r
+       font-size: 12px;\r
+       padding: 1px;\r
+       vertical-align: middle;\r
+       text-align: left;\r
+}\r
+\r
+/**************** Navigation ****************/\r
+td.nav1 {\r
+       padding: 5px 0px 0px 0px;\r
+       font-size: 12px;\r
+       font-weight: bold;\r
+}\r
+\r
+td.nav2 {\r
+       padding: 0px 0px 0px 5px;\r
+       font-size: 12px;\r
+}\r
+\r
+/**************** Forms ****************/\r
+input.submit {\r
+       border: solid 1px grey;\r
+       background-color: lightgrey;\r
+       align: right;\r
+}\r
+\r
+input.submit:hover {\r
+       border: solid 1px #3399FF;\r
+       background-color: white;\r
+       color: #3399FF;\r
+}\r
+\r
+input.std {\r
+       border: solid 1px lightgrey;\r
+       padding: 1px;\r
+       margin: 2px;\r
+}\r
+\r
+.formError {\r
+       color: red;\r
+       padding: 1px;\r
+       margin: 2px;\r
+       font-weight: bold;\r
+}\r
+\r
+/**************** Pseudo classes ****************/\r
+a:link {\r
+       color: #0066CC;\r
+       text-decoration: none;\r
+}\r
+\r
+a:visited {\r
+       color: #0066CC;\r
+       text-decoration: none;\r
+}\r
+\r
+a:hover {\r
+       color: #3399FF;\r
+       text-decoration: none;\r
+}\r
+\r
+/************************* ID's *************************/\r
+#main {\r
+       position: absolute;\r
+       margin-left: 180px;\r
+       padding-top: 65px;\r
+}\r
+\r
+#navigation {\r
+       position: absolute;\r
+       width: 150px;\r
+       height: 800px;\r
+       border-right: 1px solid #0066CC;\r
+       font-weight: normal;\r
+       margin-top: 60px;\r
+       margin-left: 10px;\r
+}\r
+\r
+#banner {\r
+       position: absolute;\r
+       width: 400px;\r
+       height: 50px;\r
+}\r
+\r
+#upperRight {\r
+       position: absolute;\r
+       top: 0;\r
+       right: 0;\r
+       margin-top: 20px;\r
+       margin-right: 10px;\r
+}
\ No newline at end of file
index f01505bfa39b3e5ed15317a8b31f0bd2f32dd251..5b7bcb38dea88d230e5c3c58c77f788f99a35c56 100644 (file)
@@ -8,6 +8,9 @@
                        <generator class="native" />\r
                </id>\r
 \r
+               <property name="closeDate" column="CLOSE_DATE" type="timestamp"\r
+                       not-null="false" />\r
+\r
                <many-to-one name="numericResultId" unique="true"\r
                        not-null="true" column="TEST_RESULT_ID" cascade="all" lazy="false" />\r
 \r
index a3ca0e5303bb1891c27a701ecf35c875a005f9ac..10c215979e47b19d72e2a19e2c5e94960eff33ca 100644 (file)
@@ -68,10 +68,11 @@ public class TestAntBuild extends TestCase {
                                TestStatus.FAILED,\r
                                "Compare eu-reform-expected.txt with eu-reform-reached.txt");\r
 \r
-               assertTrue(new File("src/test/slc/work/results/report/index.html")\r
-                               .exists());\r
-               assertTrue(new File("src/test/slc/work/results/report/1.html").exists());\r
-               assertTrue(new File("src/test/slc/work/results/report/2.html").exists());\r
+               String reportDirPath = "src/test/slc/work/results/report/";\r
+               assertTrue(new File(reportDirPath + "index.html").exists());\r
+               assertTrue(new File(reportDirPath + "slc-resultsList.html").exists());\r
+               assertTrue(new File(reportDirPath + "slc-result-1.html").exists());\r
+               assertTrue(new File(reportDirPath + "slc-result-2.html").exists());\r
        }\r
 \r
        private void assertPart(TreeTestResult testResult, String pathStr,\r
index 1e7fcf716a9625da1b2eed63143a1cd5367bfe80..939d154fca0e74117afca631514ddc8ab04c14a0 100644 (file)
@@ -1,5 +1,7 @@
 package org.argeo.slc.hibernate.test.tree;\r
 \r
+import java.util.Date;\r
+\r
 import org.argeo.slc.core.structure.tree.TreeSPath;\r
 import org.argeo.slc.core.test.NumericTRId;\r
 import org.argeo.slc.core.test.SimpleResultPart;\r
@@ -41,6 +43,9 @@ public class TreeTestResultDaoHibernateTest extends SpringBasedTestCase {
                treeTestResult.notifyCurrentPath(null, path);\r
                treeTestResult.addResultPart(partPassed);\r
                treeTestResult.addResultPart(partFailed);\r
+               \r
+               Date closeDate = new Date();\r
+               treeTestResult.setCloseDate(closeDate);\r
 \r
                testResultDao.create(treeTestResult);\r
 \r
@@ -57,7 +62,7 @@ public class TreeTestResultDaoHibernateTest extends SpringBasedTestCase {
                assertEquals(TestStatus.FAILED, (int)part1.getStatus());\r
                assertEquals(msgFailed,part1.getMessage());\r
                \r
-               \r
+               assertEquals(closeDate, treeTestResult2.getCloseDate());\r
        }\r
 \r
        @Override\r
index 603ef8fdf689cc50ca8ac22084f706a422e5a1d4..551c14c6f123d5ccfb7223b755a1f3e3d89931ec 100644 (file)
@@ -3,7 +3,7 @@ log4j.rootLogger=INFO, console
 \r
 ## Levels\r
 # Slc\r
-log4j.logger.org.argeo.slc=INFO\r
+log4j.logger.org.argeo.slc=DEBUG\r
 # Spring\r
 log4j.logger.org.springframework=INFO\r
 # Hibernate\r
index ab92fe8b16c5f345c88179e8f0f555802c6e2919..14bdfd72a0332c4c9c51b03d2205501932e9159c 100644 (file)
                        </list>\r
                </property>\r
        </bean>\r
-<!--  \r
-       <bean id="testResultId" class="org.argeo.slc.core.test.NumericTRId"\r
-               init-method="init" scope="prototype">\r
-       </bean>\r
--->\r
+\r
        <bean\r
                class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" />\r
 \r
        <bean id="resultLogger"\r
                class="org.argeo.slc.core.test.tree.TreeTestResultLogger"\r
-               init-method="init">\r
+               init-method="init" scope="prototype">\r
        </bean>\r
 \r
        <bean id="resultPersister"\r
                class="org.argeo.slc.core.test.tree.TreeTestResultPersister"\r
-               init-method="init">\r
+               init-method="init" scope="prototype">\r
                <property name="testResultDao" ref="testResultDao" />\r
                <property name="treeSPathDao" ref="treeSPathDao" />\r
                <property name="treeSRegistryDao" ref="treeSRegistryDao" />\r
        </bean>\r
 \r
        <bean id="report"\r
-               class="org.argeo.slc.core.test.tree.FullHtmlTreeReport">\r
+               class="org.argeo.slc.core.test.tree.htmlreport.FullHtmlTreeReport">\r
                <property name="testResultDao" ref="testResultDao" />\r
                <property name="treeSRegistryDao" ref="treeSRegistryDao" />\r
                <property name="reportDir"\r
index ca26ed6299e35728e7ba9feee29a8219a98149c0..03c77f1d6cb04c519abacec2b5dd212382a08bfd 100644 (file)
@@ -2,8 +2,9 @@
        <description>A Test project</description>\r
 \r
        <target name="test" depends="testSimple,testComplex">\r
-               <slc.closeResult result="testResult" report="report" />\r
-               <slc.closeResult result="testResult2" report="report" />\r
+               <slc.closeResult result="testResult" />\r
+               <slc.closeResult result="testResult2" />\r
+               <slc.report report="report" />\r
        </target>\r
 \r
        <target name="testSimple" description="Simple tests">\r