001package org.andromda.maven.plugin.translationlibrary; 002 003import java.io.File; 004import java.io.IOException; 005import java.io.PrintWriter; 006import java.io.StringWriter; 007import java.util.ArrayList; 008import java.util.Collection; 009import junit.framework.AssertionFailedError; 010import junit.framework.Test; 011import junit.framework.TestListener; 012import org.apache.commons.io.FileUtils; 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: " + 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 FileUtils.writeStringToFile(this.reportFile, report.toString()); 197 } 198 catch (IOException exception) 199 { 200 throw new RuntimeException(exception); 201 } 202 } 203 return summary.toString(); 204 } 205 206 /** 207 * Stores the information about a test failure. 208 */ 209 private static final class Failure 210 { 211 @SuppressWarnings("unused") 212 Test test; 213 Throwable information; 214 215 Failure( 216 final Test test, 217 final Throwable information) 218 { 219 this.test = test; 220 this.information = information; 221 } 222 } 223}