001package org.andromda.maven.plugin.bootstrap; 002 003import java.io.File; 004import java.io.FileWriter; 005import java.io.IOException; 006import java.io.PrintWriter; 007import java.io.StringWriter; 008import java.util.ArrayList; 009import java.util.Collection; 010import junit.framework.AssertionFailedError; 011import junit.framework.Test; 012import junit.framework.TestListener; 013 014/** 015 * Formats the translation-library test results into the correct format. 016 * 017 * @author Chad Brandon 018 */ 019public class TranslationLibraryTestFormatter 020 implements TestListener 021{ 022 /** 023 * Stores the report file location. 024 */ 025 private File reportFile; 026 027 /** 028 * Stores the contents of the report. 029 */ 030 private StringWriter report; 031 032 /** 033 * The print writer for the report. 034 */ 035 private PrintWriter reportWriter; 036 037 /** 038 * 039 */ 040 public TranslationLibraryTestFormatter() 041 { 042 this.report = new StringWriter(); 043 this.reportWriter = new PrintWriter(this.report); 044 } 045 046 /** 047 * Sets the file that will contain the report results (i.e. 048 * the results of the cartridge test run). 049 * 050 * @param reportFile the file to which the report output will be written. 051 */ 052 public void setReportFile(final File reportFile) 053 { 054 this.reportFile = reportFile; 055 } 056 057 /** 058 * Keeps track of the number of errors. 059 */ 060 private int numberOfErrors = 0; 061 062 /** 063 * @see junit.framework.TestListener#addError(junit.framework.Test, Throwable) 064 */ 065 public void addError( 066 Test test, 067 Throwable throwable) 068 { 069 this.numberOfErrors++; 070 this.collectFailure( 071 test, 072 throwable); 073 } 074 075 /** 076 * Keeps track of the number of failures. 077 */ 078 private int numberOfFailures = 0; 079 080 /** 081 * @see junit.framework.TestListener#addFailure(junit.framework.Test, junit.framework.AssertionFailedError) 082 */ 083 public void addFailure( 084 Test test, 085 AssertionFailedError failure) 086 { 087 this.numberOfFailures++; 088 this.collectFailure( 089 test, 090 failure); 091 } 092 093 /** 094 * @see junit.framework.TestListener#endTest(junit.framework.Test) 095 */ 096 public void endTest(Test test) 097 { 098 } 099 100 /** 101 * Keeps track of the number of tests run. 102 */ 103 private int numberOfTests = 0; 104 105 /** 106 * @see junit.framework.TestListener#startTest(junit.framework.Test) 107 */ 108 public void startTest(Test test) 109 { 110 this.numberOfTests++; 111 } 112 113 /** 114 * Stores the start time of the test suite 115 */ 116 private long startTime = 0; 117 118 /** 119 * Stores the new line separator. 120 */ 121 private static final String newLine = System.getProperty("line.separator"); 122 123 /** 124 * The testsuite started. 125 * @param name 126 */ 127 public void startTestSuite(final String name) 128 { 129 startTime = System.currentTimeMillis(); 130 this.reportWriter.println("-------------------------------------------------------------------------------"); 131 this.reportWriter.println(name + " Test Suite"); 132 this.reportWriter.println("-------------------------------------------------------------------------------"); 133 } 134 135 /** 136 * Adds a failure to the current <code>failures</code> 137 * collection (these are rendered at the end of test suite 138 * execution). 139 * 140 * @param type the failure type (error or failure). 141 * @param test the actual test. 142 * @param throwable the failure information. 143 */ 144 private void collectFailure( 145 Test test, 146 Throwable throwable) 147 { 148 this.failures.add(new Failure( 149 test, 150 throwable)); 151 } 152 153 private Collection<Failure> failures = new ArrayList<Failure>(); 154 155 /** 156 * Signifies the test suite ended and returns the summary of the 157 * test. 158 * 159 * @return the test summary. 160 */ 161 String endTestSuite() 162 { 163 final double elapsed = ((System.currentTimeMillis() - this.startTime) / 1000.0); 164 final StringBuilder summary = new StringBuilder("Tests: " + String.valueOf(this.numberOfTests) + ", "); 165 summary.append("Failures: ").append(this.numberOfFailures).append(", "); 166 summary.append("Errors: ").append(this.numberOfErrors).append(", "); 167 summary.append("Time elapsed: ").append(elapsed).append(" sec"); 168 summary.append(newLine); 169 summary.append(newLine); 170 this.reportWriter.print(summary); 171 172 for (final Failure failure : this.failures) 173 { 174 final Throwable information = failure.information; 175 if (information instanceof AssertionFailedError) 176 { 177 this.reportWriter.println(failure.information.getMessage()); 178 } 179 else 180 { 181 this.reportWriter.println("ERROR:"); 182 } 183 information.printStackTrace(this.reportWriter); 184 this.reportWriter.println(); 185 } 186 187 if (this.reportFile != null) 188 { 189 try 190 { 191 final File parent = this.reportFile.getParentFile(); 192 if (parent != null && !parent.exists()) 193 { 194 parent.mkdirs(); 195 } 196 final FileWriter writer = new FileWriter(this.reportFile); 197 writer.write(report.toString()); 198 writer.flush(); 199 writer.close(); 200 } 201 catch (IOException exception) 202 { 203 throw new RuntimeException(exception); 204 } 205 } 206 return summary.toString(); 207 } 208 209 /** 210 * Stores the information about a test failure. 211 */ 212 private static final class Failure 213 { 214 @SuppressWarnings({ "unused" }) 215 Test test; 216 Throwable information; 217 218 Failure( 219 final Test test, 220 final Throwable information) 221 { 222 this.test = test; 223 this.information = information; 224 } 225 } 226}