00001 #ifndef TUT_REPORTER
00002 #define TUT_REPORTER
00003
00004 #include "tut.h"
00005
00012 namespace
00013 {
00014 std::ostream& operator << (std::ostream& os,const tut::test_result& tr)
00015 {
00016 switch(tr.result)
00017 {
00018 case tut::test_result::ok:
00019 os << '.';
00020 break;
00021
00022 case tut::test_result::fail:
00023 os << '[' << tr.test << "=F]";
00024 break;
00025
00026 case tut::test_result::ex:
00027 os << '[' << tr.test << "=X]";
00028 break;
00029
00030 case tut::test_result::warn:
00031 os << '[' << tr.test << "=W]";
00032 break;
00033
00034 case tut::test_result::term:
00035 os << '[' << tr.test << "=T]";
00036 break;
00037 }
00038
00039 return os;
00040 }
00041 }
00042
00043 namespace tut
00044 {
00048 class reporter : public tut::callback
00049 {
00050 std::string current_group;
00051 typedef std::vector<tut::test_result> not_passed_list;
00052 not_passed_list not_passed;
00053 std::ostream& os;
00054
00055 public:
00056 int ok_count;
00057 int exceptions_count;
00058 int failures_count;
00059 int terminations_count;
00060 int warnings_count;
00061
00062 reporter() : os(std::cout)
00063 {
00064 init();
00065 }
00066
00067 reporter(std::ostream& out) : os(out)
00068 {
00069 init();
00070 }
00071
00072 void run_started()
00073 {
00074 init();
00075 }
00076
00077 void test_completed(const tut::test_result& tr)
00078 {
00079 if( tr.group != current_group )
00080 {
00081 os << std::endl << tr.group << ": " << std::flush;
00082 current_group = tr.group;
00083 }
00084
00085 os << tr << std::flush;
00086 if( tr.result == tut::test_result::ok ) ok_count++;
00087 else if( tr.result == tut::test_result::ex ) exceptions_count++;
00088 else if( tr.result == tut::test_result::fail ) failures_count++;
00089 else if( tr.result == tut::test_result::warn ) warnings_count++;
00090 else terminations_count++;
00091
00092 if( tr.result != tut::test_result::ok )
00093 {
00094 not_passed.push_back(tr);
00095 }
00096 }
00097
00098 void run_completed()
00099 {
00100 os << std::endl;
00101
00102 if( not_passed.size() > 0 )
00103 {
00104 not_passed_list::const_iterator i = not_passed.begin();
00105 while( i != not_passed.end() )
00106 {
00107 tut::test_result tr = *i;
00108
00109 os << std::endl;
00110
00111 os << "---> " << "test: " << tr.group << ", test<" << tr.test << ">" << std::endl;
00112
00113 os << " problem: ";
00114 switch(tr.result)
00115 {
00116 case test_result::fail:
00117 os << "assertion failed" << std::endl;
00118 break;
00119 case test_result::ex:
00120 os << "unexpected exception" << std::endl;
00121 if( tr.exception_typeid != "" )
00122 {
00123 os << " exception typeid: "
00124 << tr.exception_typeid << std::endl;
00125 }
00126 break;
00127 case test_result::term:
00128 os << "would be terminated" << std::endl;
00129 break;
00130 case test_result::warn:
00131 os << "test passed, but cleanup code (destructor) raised an exception" << std::endl;
00132 break;
00133 default: break;
00134 }
00135
00136 if( tr.message != "" )
00137 {
00138 if( tr.result == test_result::fail )
00139 {
00140 os << " failed assertion: \"" << tr.message << "\"" << std::endl;
00141 }
00142 else
00143 {
00144 os << " message: \"" << tr.message << "\"" << std::endl;
00145 }
00146 }
00147
00148 ++i;
00149 }
00150 }
00151
00152 os << std::endl;
00153
00154 os << "tests summary:";
00155 if( terminations_count > 0 ) os << " terminations:" << terminations_count;
00156 if( exceptions_count > 0 ) os << " exceptions:" << exceptions_count;
00157 if( failures_count > 0 ) os << " failures:" << failures_count;
00158 if( warnings_count > 0 ) os << " warnings:" << warnings_count;
00159 os << " ok:" << ok_count;
00160 os << std::endl;
00161 }
00162
00163 bool all_ok() const
00164 {
00165 return not_passed.size() == 0;
00166 }
00167
00168 private:
00169 void init()
00170 {
00171 ok_count = 0;
00172 exceptions_count = 0;
00173 failures_count = 0;
00174 terminations_count = 0;
00175 warnings_count = 0;
00176
00177 not_passed.clear();
00178 }
00179 };
00180 };
00181
00182 #endif