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