/*! * \file * \brief UnitTest++ checks specialized for IT++ matrices. * \author Vaclav Barta. * * ----------------------------------- * BDM++ - C++ library for Bayesian Decision Making under Uncertainty * * Using IT++ for numerical operations * ----------------------------------- */ #ifndef MAT_CHECKS_H #define MAT_CHECKS_H #include "../bdm/itpp_ext.h" #include "UnitTest++.h" #include namespace UnitTest { bool AreClose ( const itpp::vec &expected, const itpp::vec &actual, double tolerance ); bool AreClose ( const itpp::vec &expected, const itpp::vec &actual, const itpp::vec &tolerance ); bool AreClose ( const itpp::mat &expected, const itpp::mat &actual, double tolerance ); inline void CheckClose ( TestResults &results, const itpp::vec &expected, const itpp::vec &actual, double tolerance, TestDetails const &details ) { if ( !AreClose ( expected, actual, tolerance ) ) { MemoryOutStream stream; stream << "Expected " << expected << " +/- " << tolerance << " but was " << actual; results.OnTestFailure ( details, stream.GetText() ); } } inline void CheckClose ( TestResults &results, const itpp::mat &expected, const itpp::mat &actual, double tolerance, TestDetails const &details ) { if ( !AreClose ( expected, actual, tolerance ) ) { MemoryOutStream stream; stream << "Expected " << expected << " +/- " << tolerance << " but was " << actual; results.OnTestFailure ( details, stream.GetText() ); } } } /*! Constructs the multiple of standard deviation used for sample tests (currently 2). */ inline itpp::vec make_close_tolerance ( const itpp::vec & variance, int nsamples ) { // simplify overloading for Visual Studio return 3 * ( sqrt ( variance ) / sqrt ( static_cast ( nsamples ) ) ); } /*! CHECK_*_EX macros should be used only in blocks having an instance of this class (which sets the globals for error reporting). */ class CurrentContext { public: // how many times to repeat a failing test before reporting // failure static const int max_trial_count = 3; private: static const char *config_name; static int index; public: // the pointer must stay valid for the lifetime of the object CurrentContext ( const char *name, int idx ); ~CurrentContext(); /* Should be called only in blocks having an instance of CurrentContext. The argument, when not default, should be __LINE__ (and it is included in the returned string). */ static std::string format_context ( int ln = -1 ); template static void CheckEqualEx ( UnitTest::TestResults& results, Expected const& expected, Actual const& actual, UnitTest::TestDetails const& details ) { if ( ! ( expected == actual ) ) { UnitTest::MemoryOutStream stream; stream << format_context() << "expected " << expected << " but was " << actual; results.OnTestFailure ( details, stream.GetText() ); } } template static void CheckCloseEx ( UnitTest::TestResults& results, Expected const& expected, Actual const& actual, Tolerance const& tolerance, UnitTest::TestDetails const& details ) { if ( !UnitTest::AreClose ( expected, actual, tolerance ) ) { UnitTest::MemoryOutStream stream; stream << format_context() << "expected " << expected << " +/- " << tolerance << " but was " << actual; results.OnTestFailure ( details, stream.GetText() ); } } }; #define CHECK_EQUAL_EX(expected, actual) \ do \ { \ try { \ CurrentContext::CheckEqualEx(*UnitTest::CurrentTest::Results(), expected, actual, UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), 0, false)); \ } \ catch (...) { \ UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), \ "Unhandled exception in CHECK_EQUAL_EX(" #expected ", " #actual ")"); \ } \ } while (0) #define CHECK_CLOSE_EX(expected, actual, tolerance) \ do \ { \ try { \ CurrentContext::CheckCloseEx(*UnitTest::CurrentTest::Results(), expected, actual, tolerance, UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), 0, false)); \ } \ catch (...) { \ UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), \ "Unhandled exception in CHECK_CLOSE_EX(" #expected ", " #actual ")"); \ } \ } while (0) #endif