00001 
00013 #ifndef MAT_CHECKS_H
00014 #define MAT_CHECKS_H
00015 
00016 #include "../bdm/itpp_ext.h"
00017 #include "UnitTest++.h"
00018 
00019 namespace UnitTest
00020 {
00021 
00022 bool AreClose(const itpp::vec &expected, const itpp::vec &actual,
00023               double tolerance);
00024 
00025 bool AreClose(const itpp::vec &expected, const itpp::vec &actual,
00026               const itpp::vec &tolerance);
00027 
00028 bool AreClose(const itpp::mat &expected, const itpp::mat &actual,
00029               double tolerance);
00030 
00031 inline void CheckClose(TestResults &results, const itpp::vec &expected,
00032                        const itpp::vec &actual, double tolerance,
00033                        TestDetails const &details) {
00034     if (!AreClose(expected, actual, tolerance)) { 
00035         MemoryOutStream stream;
00036         stream << "Expected " << expected << " +/- " << tolerance << " but was " << actual;
00037 
00038         results.OnTestFailure(details, stream.GetText());
00039     }
00040 }
00041 
00042 inline void CheckClose(TestResults &results, const itpp::mat &expected,
00043                        const itpp::mat &actual, double tolerance,
00044                        TestDetails const &details) {
00045     if (!AreClose(expected, actual, tolerance)) { 
00046         MemoryOutStream stream;
00047         stream << "Expected " << expected << " +/- " << tolerance << " but was " << actual;
00048 
00049         results.OnTestFailure(details, stream.GetText());
00050     }
00051 }
00052 
00053 }
00054 
00058 class CurrentContext
00059 {
00060 private:
00061     static const char *config_name;
00062     static int index;
00063 
00064 public:
00065     
00066     CurrentContext(const char *name, int idx);
00067     ~CurrentContext();
00068 
00069     template<typename Expected, typename Actual>
00070     static void CheckEqualEx(UnitTest::TestResults& results,
00071                              Expected const& expected,
00072                              Actual const& actual,
00073                              UnitTest::TestDetails const& details) {
00074         if (!(expected == actual)) {
00075             UnitTest::MemoryOutStream stream;
00076             stream << "error at " << config_name << '[' << index << "]: expected " << expected << " but was " << actual;
00077 
00078             results.OnTestFailure(details, stream.GetText());
00079         }
00080     }
00081 
00082     template<typename Expected, typename Actual, typename Tolerance>
00083     static void CheckCloseEx(UnitTest::TestResults& results,
00084                              Expected const& expected,
00085                              Actual const& actual,
00086                              Tolerance const& tolerance,
00087                              UnitTest::TestDetails const& details) {
00088         if (!UnitTest::AreClose(expected, actual, tolerance)) { 
00089             UnitTest::MemoryOutStream stream;
00090             stream << "error at " << config_name << '[' << index << "]: expected " << expected << " +/- " << tolerance << " but was " << actual;
00091 
00092             results.OnTestFailure(details, stream.GetText());
00093         }
00094     }
00095 };
00096 
00097 #define CHECK_EQUAL_EX(expected, actual) \
00098     do \
00099     { \
00100         try { \
00101             CurrentContext::CheckEqualEx(*UnitTest::CurrentTest::Results(), expected, actual, UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), 0, false)); \
00102         } \
00103         catch (...) { \
00104             UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), \
00105                     "Unhandled exception in CHECK_EQUAL_EX(" #expected ", " #actual ")"); \
00106         } \
00107     } while (0)
00108 
00109 
00110 #define CHECK_CLOSE_EX(expected, actual, tolerance) \
00111     do \
00112     { \
00113         try { \
00114             CurrentContext::CheckCloseEx(*UnitTest::CurrentTest::Results(), expected, actual, tolerance, UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), 0, false)); \
00115         } \
00116         catch (...) { \
00117             UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), \
00118                     "Unhandled exception in CHECK_CLOSE_EX(" #expected ", " #actual ")"); \
00119         } \
00120     } while (0)
00121 
00122 #endif