diff --git a/src/tl/tl/tlUnitTest.cc b/src/tl/tl/tlUnitTest.cc index 473bff366..694617cbd 100644 --- a/src/tl/tl/tlUnitTest.cc +++ b/src/tl/tl/tlUnitTest.cc @@ -133,6 +133,15 @@ bool equals (double a, double b) } } +bool less (double a, double b) +{ + if (equals (a, b)) { + return false; + } else { + return a < b; + } +} + // TODO: move this to tlString.h static std::string replicate (const char *s, size_t n) { diff --git a/src/tl/tl/tlUnitTest.h b/src/tl/tl/tlUnitTest.h index 730febf5a..6e760fde2 100644 --- a/src/tl/tl/tlUnitTest.h +++ b/src/tl/tl/tlUnitTest.h @@ -187,6 +187,47 @@ inline bool equals (const char *a, const std::string &b) return equals (std::string (a), b); } +/** + * @brief A generic compare operator + */ +template +inline bool less (const X &a, const Y &b) +{ + return a < b; +} + +/** + * @brief A specialization of the compare operator for doubles + */ +TL_PUBLIC bool less (double a, double b); + +/** + * @brief Specialization of comparison of pointers vs. integers (specifically "0") + */ +template +inline bool less (X *a, int b) +{ + return a == (X *) size_t (b); +} + +/** + * @brief A specialization of comparison of double vs "anything" + */ +template +inline bool less (double a, const Y &b) +{ + return less (a, double (b)); +} + +/** + * @brief A specialization of comparison of "anything" vs. double + */ +template +inline bool less (const X &a, double b) +{ + return less (double (a), b); +} + /** * @brief A utility class to capture the warning, error and info channels * @@ -447,6 +488,20 @@ public: } } + /** + * @brief Main entry point for the compare feature (EXPECT_LE, _LT, _GE, _GT) + */ + template + void cmp_helper (bool less, bool eq, const T1 &a, const T2 &b, const char *what_expr, const char *equals_expr, const char *file, int line) + { + bool res = (less ? tl::less (a, b) : tl::less (b, a)) && (! eq || tl::equals (a, b)); + if (! res) { + std::ostringstream sstr; + sstr << what_expr << " is not " << (less ? "less" : "greater") << (eq ? " or equal" : "") << " than " << equals_expr; + diff (file, line, sstr.str (), a, b); + } + } + protected: /** * @brief Returns a value indicating whether the test runs in editable mode @@ -511,6 +566,22 @@ struct TestImpl##NAME \ } \ void TestImpl##NAME::execute (tl::TestBase *_this) +#define EXPECT_LE(WHAT,EQUALS) \ + _this->checkpoint (__FILE__, __LINE__); \ + _this->cmp_helper (true, false, (WHAT), (EQUALS), #WHAT, #EQUALS, __FILE__, __LINE__); + +#define EXPECT_LT(WHAT,EQUALS) \ + _this->checkpoint (__FILE__, __LINE__); \ + _this->cmp_helper (true, true, (WHAT), (EQUALS), #WHAT, #EQUALS, __FILE__, __LINE__); + +#define EXPECT_GE(WHAT,EQUALS) \ + _this->checkpoint (__FILE__, __LINE__); \ + _this->cmp_helper (true, false, (WHAT), (EQUALS), #WHAT, #EQUALS, __FILE__, __LINE__); + +#define EXPECT_GT(WHAT,EQUALS) \ + _this->checkpoint (__FILE__, __LINE__); \ + _this->cmp_helper (true, true, (WHAT), (EQUALS), #WHAT, #EQUALS, __FILE__, __LINE__); + #define EXPECT_EQ(WHAT,EQUALS) \ _this->checkpoint (__FILE__, __LINE__); \ _this->eq_helper (true, (WHAT), (EQUALS), #WHAT, #EQUALS, __FILE__, __LINE__);