| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229 |
- #ifndef _TEST_SUITE_H_
- #define _TEST_SUITE_H_
- #include <string>
- #include <sstream>
- #include <cstring>
- #ifdef __GNUC__
- #define TEST_GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100)
- #if (TEST_GCC_VERSION >= 29600)
- #define test_likely(x) __builtin_expect((long)((bool)(x)),1)
- #define test_unlikely(x) __builtin_expect((long)((bool)(x)),0)
- #else
- #define test_likely(x) x
- #define test_unlikely(x) x
- #endif
- #else
- #define test_likely(x) x
- #define test_unlikely(x) x
- #endif
- #include <limits>
- template <typename T>
- union unittest_numUnion {
- unittest_numUnion(T _v) : val(_v){}
- T val;
- unsigned char c[sizeof(T)];
- };
- template<typename T>
- static bool unittest_isNAN(T num){
- unittest_numUnion<T> orig(num);
-
- static unittest_numUnion<T> sig_nan(std::numeric_limits<T>::signaling_NaN());
-
- bool isNAN = true;
- for(size_t i = 0; i < sizeof(T); ++i){
- if (orig.c[i] != sig_nan.c[i]){
- isNAN = false;
- break;
- }
- }
- if (isNAN) return true;
-
- static unittest_numUnion<T> quiet_nan(std::numeric_limits<T>::quiet_NaN());
-
- for(size_t i = 0; i < sizeof(T); ++i){
- if (orig.c[i] != quiet_nan.c[i]){
- return false;
- }
- }
- return true;
- }
- class UnitTest {
- public:
- static void SelfCheck(void);
- static void PushFailure(const std::string & fail);
- static void PushSuccess(const std::string & pass);
- static void echo_(const std::string & out);
- static std::string ToString(void);
- static std::string ToHTML(void);
- static void SaveTo(const std::string & location);
- static void SetReturnOnFail(bool option);
- static bool GetReturnOnFail(void);
- static void SetEcho(bool option);
- static void SetPrefix(const std::string & prefix);
- static std::string GetPrefix(void);
- static void StartTime(void);
- static inline bool _floatsAreEqual(const double & one, const double & two){
- return (one > two) ? (one - two) < .000001 : (one - two) > -.000001;
- }
- };
- #define MakePre()\
- std::string pre = UnitTest::GetPrefix();\
- if (test_unlikely(pre.empty())){\
- std::stringstream out;\
- out << __FILE__ << ":" << __LINE__;\
- pre = out.str();\
- }\
- pre += ": ";
- #define FAIL(stri)\
- MakePre()\
- UnitTest::PushFailure(pre + std::string(stri));\
- if (UnitTest::GetReturnOnFail()) return;
- #define PASS(stri)\
- MakePre();\
- UnitTest::PushSuccess(pre + std::string(stri));\
- #define assertUnitTest()\
- UnitTest::SelfCheck();
- #define assertTrue(cond)\
- if (test_unlikely(!(cond))){\
- FAIL(#cond);\
- } else {\
- PASS(#cond);\
- }
- #define assertFalse(cond)\
- if (test_unlikely(cond)){\
- FAIL(#cond);\
- } else {\
- PASS(#cond);\
- }
- #define assertTrue_Primitive(cond, leftside, rightside)\
- if (test_unlikely(!(cond))){\
- std::stringstream unit_out;\
- unit_out << #cond;\
- unit_out << ", Left side: " << leftside;\
- unit_out << ", Right side: " << rightside;\
- FAIL(unit_out.str());\
- } else {\
- PASS(#cond);\
- }
- //needs to copy it so that if its a function call it only does it once
- #define assertNAN(type, one)\
- {\
- type val = (type)one;\
- std::string lag(#one);\
- lag += " not a number";\
- if (test_likely(unittest_isNAN<type>(one))){\
- PASS(lag)\
- } else {\
- FAIL(lag)\
- }\
- }
- #define assertFloatEquals(one, two)\
- assertTrue(UnitTest::_floatsAreEqual(one, two))
- #define assertEquals(one, two)\
- assertTrue((one) == (two))
- #define assertNotEquals(one, two)\
- assertTrue((one) != (two))
- #define assertGreaterThan(one, two)\
- assertTrue((one) > (two))
- #define assertGreaterThanEqualTo(one, two)\
- assertTrue((one) >= (two))
- #define assertLessThan(one, two)\
- assertTrue((one) < (two))
- #define assertLessThanEqualTo(one, two)\
- assertTrue((one) <= (two))
- #define assertEquals_Primitive(one, two)\
- assertTrue_Primitive((one) == (two), one, two)
- #define assertNotEquals_Primitive(one, two)\
- assertTrue_Primitive((one) != (two), one, two)
- #define assertGreaterThan_Primitive(one, two)\
- assertTrue_Primitive((one) > (two), one, two)
- #define assertGreaterThanEqualTo_Primitive(one, two)\
- assertTrue_Primitive((one) >= (two), one, two)
- #define assertLessThan_Primitive(one, two)\
- assertTrue_Primitive((one) < (two), one, two)
- #define assertLessThanEqualTo_Primitive(one, two)\
- assertTrue_Primitive((one) <= (two), one, two)
- #define assertNull(one)\
- assertTrue(one == NULL);
- #define assertNotNull(one)\
- assertTrue(one != NULL);
- #define assertCStringEquals(one, two)\
- if (test_unlikely(strcmp(one, two))){\
- FAIL(std::string(#one) + "==" + #two);\
- } else {\
- PASS(std::string(#one) + "==" + #two);\
- }
- #define assertCStringNotEquals(one, two)\
- if (test_unlikely(!strcmp(one, two))){\
- FAIL(std::string(#one) + "!=" + #two);\
- } else {\
- PASS(std::string(#one) + "!=" + #two);\
- }
- #define assertCStringEqualsW(one, two)\
- if (test_unlikely(wcscmp(one, two))){\
- FAIL(std::string(#one) + "==" + #two);\
- } else {\
- PASS(std::string(#one) + "==" + #two);\
- }
- #define assertCStringNotEqualsW(one, two)\
- if (test_unlikely(!wcscmp(one, two))){\
- FAIL(std::string(#one) + "!=" + #two);\
- } else {\
- PASS(std::string(#one) + "!=" + #two);\
- }
- #define assertException(code, exc)\
- {\
- bool failed = false;\
- try {\
- code;\
- } catch (exc){\
- PASS(std::string(#exc) + " caught");\
- failed = true;\
- }\
- if (test_unlikely(!failed)){ FAIL(std::string(#exc) + " not caught");}\
- }
- #define echo(something)\
- {\
- std::stringstream somet;\
- somet << something;\
- UnitTest::echo_(somet.str());\
- }
- #endif
|