1#include <algorithm> 2#include <cppunit/NotEqualException.h> 3#include <cppunit/SourceLine.h> 4#include <cppunit/TestFailure.h> 5#include <cppunit/TestResultCollector.h> 6#include <cppunit/CompilerOutputter.h> 7 8 9using std::endl; 10using std::ostream; 11using std::string; 12 13namespace CppUnit 14{ 15 16CompilerOutputter::CompilerOutputter( TestResultCollector *result, 17 ostream &stream ) : 18 m_result( result ), 19 m_stream( stream ) 20{ 21} 22 23 24CompilerOutputter::~CompilerOutputter() 25{ 26} 27 28 29CompilerOutputter * 30CompilerOutputter::defaultOutputter( TestResultCollector *result, 31 ostream &stream ) 32{ 33 return new CompilerOutputter( result, stream ); 34// For automatic adpatation... 35// return new CPPUNIT_DEFAULT_OUTPUTTER( result, stream ); 36} 37 38 39void 40CompilerOutputter::write() 41{ 42 if ( m_result->wasSuccessful() ) 43 printSucess(); 44 else 45 printFailureReport(); 46} 47 48 49void 50CompilerOutputter::printSucess() 51{ 52 m_stream << "OK (" << m_result->runTests() << ")" 53 << endl; 54} 55 56 57void 58CompilerOutputter::printFailureReport() 59{ 60 printFailuresList(); 61 printStatistics(); 62} 63 64 65void 66CompilerOutputter::printFailuresList() 67{ 68 for ( int index =0; index < m_result->testFailuresTotal(); ++index) 69 { 70 printFailureDetail( m_result->failures()[ index ] ); 71 } 72} 73 74 75void 76CompilerOutputter::printFailureDetail( TestFailure *failure ) 77{ 78 printFailureLocation( failure->sourceLine() ); 79 printFailureType( failure ); 80 printFailedTestName( failure ); 81 printFailureMessage( failure ); 82} 83 84 85void 86CompilerOutputter::printFailureLocation( SourceLine sourceLine ) 87{ 88 if ( sourceLine.isValid() ) 89 m_stream << sourceLine.fileName() 90 << "(" << sourceLine.lineNumber() << ") : "; 91 else 92 m_stream << "##Failure Location unknown## : "; 93} 94 95 96void 97CompilerOutputter::printFailureType( TestFailure *failure ) 98{ 99 m_stream << (failure->isError() ? "Error" : "Assertion"); 100} 101 102 103void 104CompilerOutputter::printFailedTestName( TestFailure *failure ) 105{ 106 m_stream << endl; 107 m_stream << "Test name: " << failure->failedTestName(); 108} 109 110 111void 112CompilerOutputter::printFailureMessage( TestFailure *failure ) 113{ 114 m_stream << endl; 115 Exception *thrownException = failure->thrownException(); 116 if ( thrownException->isInstanceOf( NotEqualException::type() ) ) 117 printNotEqualMessage( thrownException ); 118 else 119 printDefaultMessage( thrownException ); 120 m_stream << endl; 121} 122 123 124void 125CompilerOutputter::printNotEqualMessage( Exception *thrownException ) 126{ 127 NotEqualException *e = (NotEqualException *)thrownException; 128 m_stream << wrap( "- Expected : " + e->expectedValue() ); 129 m_stream << endl; 130 m_stream << wrap( "- Actual : " + e->actualValue() ); 131 m_stream << endl; 132 if ( !e->additionalMessage().empty() ) 133 { 134 m_stream << wrap( e->additionalMessage() ); 135 m_stream << endl; 136 } 137} 138 139 140void 141CompilerOutputter::printDefaultMessage( Exception *thrownException ) 142{ 143 string wrappedMessage = wrap( thrownException->what() ); 144 m_stream << wrappedMessage << endl; 145} 146 147 148void 149CompilerOutputter::printStatistics() 150{ 151 m_stream << "Failures !!!" << endl; 152 m_stream << "Run: " << m_result->runTests() << " " 153 << "Failure total: " << m_result->testFailuresTotal() << " " 154 << "Failures: " << m_result->testFailures() << " " 155 << "Errors: " << m_result->testErrors() 156 << endl; 157} 158 159 160string 161CompilerOutputter::wrap( string message ) 162{ 163 Lines lines = splitMessageIntoLines( message ); 164 string wrapped; 165 for ( Lines::iterator it = lines.begin(); it != lines.end(); ++it ) 166 { 167 string line( *it ); 168 const int maxLineLength = 80; 169 int index =0; 170 while ( index < (int)line.length() ) 171 { 172 string line( line.substr( index, maxLineLength ) ); 173 wrapped += line; 174 index += maxLineLength; 175 if ( index < (int)line.length() ) 176 wrapped += "\n"; 177 } 178 wrapped += '\n'; 179 } 180 return wrapped; 181} 182 183 184CompilerOutputter::Lines 185CompilerOutputter::splitMessageIntoLines( string message ) 186{ 187 Lines lines; 188 189 string::iterator itStart = message.begin(); 190 while ( true ) 191 { 192 string::iterator itEol = find( itStart, 193 message.end(), 194 '\n' ); 195 lines.push_back( message.substr( itStart - message.begin(), 196 itEol - itStart ) ); 197 if ( itEol == message.end() ) 198 break; 199 itStart = itEol +1; 200 } 201 return lines; 202} 203 204 205 206} // namespace CppUnit 207