00001 #ifndef HSHGTEST_H
00002 #define HSHGTEST_H
00003
00004
00005
00006
00007
00008
00009 #include <string>
00010 #include <cstdlib>
00011 #include <ostream>
00012
00014 namespace HSHGTest
00015 {
00016
00018 class TestFailure
00019 {
00020 public:
00021
00023 TestFailure( const char* message, const char* file, unsigned int line )
00024 : m_message( message )
00025 , m_file( file )
00026 , m_line( line )
00027 {
00028 }
00029
00031 const std::string& GetMessage() const { return m_message; }
00032
00034 const std::string& GetFile() const { return m_file; }
00035
00037 unsigned int GetLine() const { return m_line; }
00038
00039 private:
00040
00041 std::string m_message;
00042 std::string m_file;
00043 unsigned int m_line;
00044 };
00045
00047 inline void TestAssert( bool condition, const char* message, const char* file
00048 , unsigned int line )
00049 {
00050 if( !condition )
00051 {
00052 throw TestFailure( message, file, line );
00053 }
00054 }
00055
00057 struct TestFn
00058 {
00060 const char* name;
00062 void (*fptr)();
00063 };
00064
00066
00072 inline int RunTests(TestFn fnarray[], std::ostream& log)
00073 {
00074 int fail = 0, count = 0;
00075 for (TestFn* p = fnarray; p->fptr != NULL; ++p)
00076 {
00077 try
00078 {
00079 ++count;
00080 (*p->fptr)();
00081 }
00082 catch (TestFailure& tf)
00083 {
00084 log << tf.GetFile() << ':' << tf.GetLine() << ": Test "
00085 << p->name << " failed. ( " << tf.GetMessage() << " )\n";
00086 ++fail;
00087 }
00088 catch (...)
00089 {
00090 log << "Test " << p->name
00091 << " failed. An unexpected exception was thrown.\n";
00092 ++fail;
00093 }
00094 }
00095 log << count - fail << " out of " << count << " tests passed.\n";
00096 return count == 0 || fail != 0 ? EXIT_FAILURE : EXIT_SUCCESS;
00097 }
00098
00099 }
00100
00102 #define HSHG_BEGIN_TESTS namespace { HSHGTest::TestFn tests[] = {
00103
00105
00108 #define HSHG_TEST_ENTRY(t) { #t, t },
00109
00111 #define HSHG_END_TESTS { NULL, NULL } }; }
00112
00114 #define HSHG_TEST_MAIN int main() { return HSHGTest::RunTests( tests, std::cout ); }
00115
00119 #define HSHG_ASSERT( x ) HSHGTest::TestAssert( x, #x, __FILE__, __LINE__ )
00120
00123 #define HSHG_ASSERT_DESC( x, d ) HSHGTest::TestAssert( x, d, __FILE__, __LINE__ )
00124
00129 #define HSHG_ASSERT_THROWS( x, except ) try { x;\
00130 HSHGTest::TestAssert( false, "Exception " #except " expected."\
00131 , __FILE__, __LINE__ ); } catch( except & ) {}
00132
00133 #endif//HSHGTEST_H