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