From 567ae61e784383921b57f1fe4884b5f3a333d04e Mon Sep 17 00:00:00 2001 From: Alexander Alekhin Date: Fri, 23 Feb 2018 09:24:44 +0000 Subject: [PATCH] core: add "check" macros --- modules/core/include/opencv2/core/base.hpp | 1 + modules/core/include/opencv2/core/check.hpp | 135 ++++++++ modules/core/src/check.cpp | 160 +++++++++ modules/core/src/system.cpp | 30 +- modules/core/test/test_misc.cpp | 499 ++++++++++++++++++++++++++++ 5 files changed, 822 insertions(+), 3 deletions(-) create mode 100644 modules/core/include/opencv2/core/check.hpp create mode 100644 modules/core/src/check.cpp diff --git a/modules/core/include/opencv2/core/base.hpp b/modules/core/include/opencv2/core/base.hpp index 61144e9..786e9de 100644 --- a/modules/core/include/opencv2/core/base.hpp +++ b/modules/core/include/opencv2/core/base.hpp @@ -758,5 +758,6 @@ CV_EXPORTS_W void setUseIPP_NE(bool flag); #include "opencv2/core/neon_utils.hpp" #include "opencv2/core/vsx_utils.hpp" +#include "opencv2/core/check.hpp" #endif //OPENCV_CORE_BASE_HPP diff --git a/modules/core/include/opencv2/core/check.hpp b/modules/core/include/opencv2/core/check.hpp new file mode 100644 index 0000000..92d114d --- /dev/null +++ b/modules/core/include/opencv2/core/check.hpp @@ -0,0 +1,135 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. + +#ifndef OPENCV_CORE_CHECK_HPP +#define OPENCV_CORE_CHECK_HPP + +#include + +namespace cv { + +/** Returns string of cv::Mat depth value: CV_8U -> "CV_8U" or "" */ +CV_EXPORTS const char* depthToString(int depth); + +/** Returns string of cv::Mat depth value: CV_8UC3 -> "CV_8UC3" or "" */ +CV_EXPORTS const String typeToString(int type); + + +//! @cond IGNORED +namespace detail { + +/** Returns string of cv::Mat depth value: CV_8U -> "CV_8U" or NULL */ +CV_EXPORTS const char* depthToString_(int depth); + +/** Returns string of cv::Mat depth value: CV_8UC3 -> "CV_8UC3" or cv::String() */ +CV_EXPORTS const cv::String typeToString_(int type); + +enum TestOp { + TEST_CUSTOM = 0, + TEST_EQ = 1, + TEST_NE = 2, + TEST_LE = 3, + TEST_LT = 4, + TEST_GE = 5, + TEST_GT = 6, + CV__LAST_TEST_OP +}; + +struct CheckContext { + const char* func; + const char* file; + int line; + enum TestOp testOp; + const char* message; + const char* p1_str; + const char* p2_str; +}; + +#ifndef CV__CHECK_FILENAME +# define CV__CHECK_FILENAME __FILE__ +#endif + +#ifndef CV__CHECK_FUNCTION +# if defined _MSC_VER +# define CV__CHECK_FUNCTION __FUNCSIG__ +# elif defined __GNUC__ +# define CV__CHECK_FUNCTION __PRETTY_FUNCTION__ +# else +# define CV__CHECK_FUNCTION "" +# endif +#endif + +#define CV__CHECK_LOCATION_VARNAME(id) CVAUX_CONCAT(CVAUX_CONCAT(__cv_check_, id), __LINE__) +#define CV__DEFINE_CHECK_CONTEXT(id, message, testOp, p1_str, p2_str) \ + static const cv::detail::CheckContext CV__CHECK_LOCATION_VARNAME(id) = \ + { CV__CHECK_FUNCTION, CV__CHECK_FILENAME, __LINE__, testOp, message, p1_str, p2_str } + +CV_EXPORTS void CV_NORETURN check_failed_auto(const int v1, const int v2, const CheckContext& ctx); +CV_EXPORTS void CV_NORETURN check_failed_auto(const float v1, const float v2, const CheckContext& ctx); +CV_EXPORTS void CV_NORETURN check_failed_auto(const double v1, const double v2, const CheckContext& ctx); +CV_EXPORTS void CV_NORETURN check_failed_MatDepth(const int v1, const int v2, const CheckContext& ctx); +CV_EXPORTS void CV_NORETURN check_failed_MatType(const int v1, const int v2, const CheckContext& ctx); +CV_EXPORTS void CV_NORETURN check_failed_MatChannels(const int v1, const int v2, const CheckContext& ctx); + +CV_EXPORTS void CV_NORETURN check_failed_auto(const int v, const CheckContext& ctx); +CV_EXPORTS void CV_NORETURN check_failed_auto(const float v, const CheckContext& ctx); +CV_EXPORTS void CV_NORETURN check_failed_auto(const double v, const CheckContext& ctx); +CV_EXPORTS void CV_NORETURN check_failed_MatDepth(const int v, const CheckContext& ctx); +CV_EXPORTS void CV_NORETURN check_failed_MatType(const int v, const CheckContext& ctx); +CV_EXPORTS void CV_NORETURN check_failed_MatChannels(const int v, const CheckContext& ctx); + + +#define CV__TEST_EQ(v1, v2) ((v1) == (v2)) +#define CV__TEST_NE(v1, v2) ((v1) != (v2)) +#define CV__TEST_LE(v1, v2) ((v1) <= (v2)) +#define CV__TEST_LT(v1, v2) ((v1) < (v2)) +#define CV__TEST_GE(v1, v2) ((v1) >= (v2)) +#define CV__TEST_GT(v1, v2) ((v1) > (v2)) + +#define CV__CHECK(id, op, type, v1, v2, v1_str, v2_str, msg_str) do { \ + if(CV__TEST_##op((v1), (v2))) ; else { \ + CV__DEFINE_CHECK_CONTEXT(id, msg_str, cv::detail::TEST_ ## op, v1_str, v2_str); \ + cv::detail::check_failed_ ## type((v1), (v2), CV__CHECK_LOCATION_VARNAME(id)); \ + } \ +} while (0) + +#define CV__CHECK_CUSTOM_TEST(id, type, v, test_expr, v_str, test_expr_str, msg_str) do { \ + if(!!(test_expr)) ; else { \ + CV__DEFINE_CHECK_CONTEXT(id, msg_str, cv::detail::TEST_CUSTOM, v_str, test_expr_str); \ + cv::detail::check_failed_ ## type((v), CV__CHECK_LOCATION_VARNAME(id)); \ + } \ +} while (0) + +} // namespace +//! @endcond + + +/// Supported values of these types: int, float, double +#define CV_CheckEQ(v1, v2, msg) CV__CHECK(_, EQ, auto, v1, v2, #v1, #v2, msg) +#define CV_CheckNE(v1, v2, msg) CV__CHECK(_, NE, auto, v1, v2, #v1, #v2, msg) +#define CV_CheckLE(v1, v2, msg) CV__CHECK(_, LE, auto, v1, v2, #v1, #v2, msg) +#define CV_CheckLT(v1, v2, msg) CV__CHECK(_, LT, auto, v1, v2, #v1, #v2, msg) +#define CV_CheckGE(v1, v2, msg) CV__CHECK(_, GE, auto, v1, v2, #v1, #v2, msg) +#define CV_CheckGT(v1, v2, msg) CV__CHECK(_, GT, auto, v1, v2, #v1, #v2, msg) + +/// Check with additional "decoding" of type values in error message +#define CV_CheckTypeEQ(t1, t2, msg) CV__CHECK(_, EQ, MatType, t1, t2, #t1, #t2, msg) +/// Check with additional "decoding" of depth values in error message +#define CV_CheckDepthEQ(d1, d2, msg) CV__CHECK(_, EQ, MatDepth, d1, d2, #d1, #d2, msg) + +#define CV_CheckChannelsEQ(c1, c2, msg) CV__CHECK(_, EQ, MatChannels, c1, c2, #c1, #c2, msg) + + +/// Example: type == CV_8UC1 || type == CV_8UC3 +#define CV_CheckType(t, test_expr, msg) CV__CHECK_CUSTOM_TEST(_, MatType, t, (test_expr), #t, #test_expr, msg) + +/// Example: depth == CV_32F || depth == CV_64F +#define CV_CheckDepth(t, test_expr, msg) CV__CHECK_CUSTOM_TEST(_, MatDepth, t, (test_expr), #t, #test_expr, msg) + +/// Some complex conditions: CV_Check(src2, src2.empty() || (src2.type() == src1.type() && src2.size() == src1.size()), "src2 should have same size/type as src1") +// TODO define pretty-printers: #define CV_Check(v, test_expr, msg) CV__CHECK_CUSTOM_TEST(_, auto, v, (test_expr), #v, #test_expr, msg) + +} // namespace + +#endif // OPENCV_CORE_CHECK_HPP diff --git a/modules/core/src/check.cpp b/modules/core/src/check.cpp new file mode 100644 index 0000000..966d2ca --- /dev/null +++ b/modules/core/src/check.cpp @@ -0,0 +1,160 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. + +#include "precomp.hpp" + +#include "opencv2/core/check.hpp" + +namespace cv { + +const char* depthToString(int depth) +{ + const char* s = detail::depthToString_(depth); + return s ? s : ""; +} + +const cv::String typeToString(int type) +{ + cv::String s = detail::typeToString_(type); + if (s.empty()) + { + static cv::String invalidType(""); + return invalidType; + } + return s; +} + + +namespace detail { + +static const char* getTestOpPhraseStr(unsigned testOp) +{ + static const char* _names[] = { "{custom check}", "equal to", "not equal to", "less than or equal to", "less than", "greater than or equal to", "greater than" }; + CV_DbgAssert(testOp < CV__LAST_TEST_OP); + return testOp < CV__LAST_TEST_OP ? _names[testOp] : "???"; +} +static const char* getTestOpMath(unsigned testOp) +{ + static const char* _names[] = { "???", "==", "!=", "<=", "<", ">=", ">" }; + CV_DbgAssert(testOp < CV__LAST_TEST_OP); + return testOp < CV__LAST_TEST_OP ? _names[testOp] : "???"; +} + +const char* depthToString_(int depth) +{ + static const char* depthNames[] = { "CV_8U", "CV_8S", "CV_16U", "CV_16S", "CV_32S", "CV_32F", "CV_64F", "CV_USRTYPE1" }; + return depth <= CV_USRTYPE1 ? depthNames[depth] : NULL; +} + +const cv::String typeToString_(int type) +{ + int depth = CV_MAT_DEPTH(type); + int cn = CV_MAT_CN(type); + if (depth >= 0 && depth <= CV_USRTYPE1) + return cv::format("%sC%d", depthToString_(depth), cn); + return cv::String(); +} + +template static CV_NORETURN +void check_failed_auto_(const T& v1, const T& v2, const CheckContext& ctx) +{ + std::stringstream ss; + ss << ctx.message << " (expected: '" << ctx.p1_str << " " << getTestOpMath(ctx.testOp) << " " << ctx.p2_str << "'), where" << std::endl + << " '" << ctx.p1_str << "' is " << v1 << std::endl; + if (ctx.testOp != TEST_CUSTOM && ctx.testOp < CV__LAST_TEST_OP) + { + ss << "must be " << getTestOpPhraseStr(ctx.testOp) << std::endl; + } + ss << " '" << ctx.p2_str << "' is " << v2; + cv::errorNoReturn(cv::Error::StsError, ss.str(), ctx.func, ctx.file, ctx.line); +} +void check_failed_MatDepth(const int v1, const int v2, const CheckContext& ctx) +{ + std::stringstream ss; + ss << ctx.message << " (expected: '" << ctx.p1_str << " " << getTestOpMath(ctx.testOp) << " " << ctx.p2_str << "'), where" << std::endl + << " '" << ctx.p1_str << "' is " << v1 << " (" << depthToString(v1) << ")" << std::endl; + if (ctx.testOp != TEST_CUSTOM && ctx.testOp < CV__LAST_TEST_OP) + { + ss << "must be " << getTestOpPhraseStr(ctx.testOp) << std::endl; + } + ss << " '" << ctx.p2_str << "' is " << v2 << " (" << depthToString(v2) << ")"; + cv::errorNoReturn(cv::Error::StsError, ss.str(), ctx.func, ctx.file, ctx.line); +} +void check_failed_MatType(const int v1, const int v2, const CheckContext& ctx) +{ + std::stringstream ss; + ss << ctx.message << " (expected: '" << ctx.p1_str << " " << getTestOpMath(ctx.testOp) << " " << ctx.p2_str << "'), where" << std::endl + << " '" << ctx.p1_str << "' is " << v1 << " (" << typeToString(v1) << ")" << std::endl; + if (ctx.testOp != TEST_CUSTOM && ctx.testOp < CV__LAST_TEST_OP) + { + ss << "must be " << getTestOpPhraseStr(ctx.testOp) << std::endl; + } + ss << " '" << ctx.p2_str << "' is " << v2 << " (" << typeToString(v2) << ")"; + cv::errorNoReturn(cv::Error::StsError, ss.str(), ctx.func, ctx.file, ctx.line); +} +void check_failed_MatChannels(const int v1, const int v2, const CheckContext& ctx) +{ + check_failed_auto_(v1, v2, ctx); +} +void check_failed_auto(const int v1, const int v2, const CheckContext& ctx) +{ + check_failed_auto_(v1, v2, ctx); +} +void check_failed_auto(const float v1, const float v2, const CheckContext& ctx) +{ + check_failed_auto_(v1, v2, ctx); +} +void check_failed_auto(const double v1, const double v2, const CheckContext& ctx) +{ + check_failed_auto_(v1, v2, ctx); +} + + +template static CV_NORETURN +void check_failed_auto_(const T& v, const CheckContext& ctx) +{ + std::stringstream ss; + ss << ctx.message << ":" << std::endl + << " '" << ctx.p2_str << "'" << std::endl + << "where" << std::endl + << " '" << ctx.p1_str << "' is " << v; + cv::errorNoReturn(cv::Error::StsError, ss.str(), ctx.func, ctx.file, ctx.line); +} +void check_failed_MatDepth(const int v, const CheckContext& ctx) +{ + std::stringstream ss; + ss << ctx.message << ":" << std::endl + << " '" << ctx.p2_str << "'" << std::endl + << "where" << std::endl + << " '" << ctx.p1_str << "' is " << v << " (" << depthToString(v) << ")"; + cv::errorNoReturn(cv::Error::StsError, ss.str(), ctx.func, ctx.file, ctx.line); +} +void check_failed_MatType(const int v, const CheckContext& ctx) +{ + std::stringstream ss; + ss << ctx.message << ":" << std::endl + << " '" << ctx.p2_str << "'" << std::endl + << "where" << std::endl + << " '" << ctx.p1_str << "' is " << v << " (" << typeToString(v) << ")"; + cv::errorNoReturn(cv::Error::StsError, ss.str(), ctx.func, ctx.file, ctx.line); +} +void check_failed_MatChannels(const int v, const CheckContext& ctx) +{ + check_failed_auto_(v, ctx); +} +void check_failed_auto(const int v, const CheckContext& ctx) +{ + check_failed_auto_(v, ctx); +} +void check_failed_auto(const float v, const CheckContext& ctx) +{ + check_failed_auto_(v, ctx); +} +void check_failed_auto(const double v, const CheckContext& ctx) +{ + check_failed_auto_(v, ctx); +} + + +}} // namespace diff --git a/modules/core/src/system.cpp b/modules/core/src/system.cpp index b53f7c9..6d0f4a8 100644 --- a/modules/core/src/system.cpp +++ b/modules/core/src/system.cpp @@ -249,10 +249,34 @@ const char* Exception::what() const throw() { return msg.c_str(); } void Exception::formatMessage() { - if( func.size() > 0 ) - msg = format("OpenCV(%s) %s:%d: error: (%d) %s: %s in function %s\n", CV_VERSION, file.c_str(), line, code, cvErrorStr(code), err.c_str(), func.c_str()); + size_t pos = err.find('\n'); + bool multiline = pos != cv::String::npos; + if (multiline) + { + std::stringstream ss; + size_t prev_pos = 0; + while (pos != cv::String::npos) + { + ss << "> " << err.substr(prev_pos, pos - prev_pos) << std::endl; + prev_pos = pos + 1; + pos = err.find('\n', prev_pos); + } + ss << "> " << err.substr(prev_pos); + if (err[err.size() - 1] != '\n') + ss << std::endl; + err = ss.str(); + } + if (func.size() > 0) + { + if (multiline) + msg = format("OpenCV(%s) %s:%d: error: (%d:%s) in function '%s'\n%s", CV_VERSION, file.c_str(), line, code, cvErrorStr(code), func.c_str(), err.c_str()); + else + msg = format("OpenCV(%s) %s:%d: error: (%d:%s) %s in function '%s'\n", CV_VERSION, file.c_str(), line, code, cvErrorStr(code), err.c_str(), func.c_str()); + } else - msg = format("OpenCV(%s) %s:%d: error: (%d) %s: %s\n", CV_VERSION, file.c_str(), line, code, cvErrorStr(code), err.c_str()); + { + msg = format("OpenCV(%s) %s:%d: error: (%d:%s) %s%s", CV_VERSION, file.c_str(), line, code, cvErrorStr(code), err.c_str(), multiline ? "" : "\n"); + } } static const char* g_hwFeatureNames[CV_HARDWARE_MAX_FEATURE] = { NULL }; diff --git a/modules/core/test/test_misc.cpp b/modules/core/test/test_misc.cpp index ae71d8d..b98ec4e 100644 --- a/modules/core/test/test_misc.cpp +++ b/modules/core/test/test_misc.cpp @@ -245,4 +245,503 @@ TEST(Core_Version, consistency) EXPECT_EQ(String(CV_VERSION), cv::getVersionString()); } + + +// +// Test core/check.hpp macros +// + +void test_check_eq_1(int value_1, int value_2) +{ + CV_CheckEQ(value_1, value_2, "Validation check failed"); +} +TEST(Core_Check, testEQ_int_fail) +{ + try + { + test_check_eq_1(123, 5678); + FAIL() << "Unreachable code called"; + } + catch (const cv::Exception& e) + { + EXPECT_STREQ(e.err.c_str(), +"> Validation check failed (expected: 'value_1 == value_2'), where\n" +"> 'value_1' is 123\n" +"> must be equal to\n" +"> 'value_2' is 5678\n" +); + } + catch (const std::exception& e) + { + FAIL() << "Unexpected C++ exception: " << e.what(); + } + catch (...) + { + FAIL() << "Unexpected unknown exception"; + } +} +TEST(Core_Check, testEQ_int_pass) +{ + EXPECT_NO_THROW( + { + test_check_eq_1(1234, 1234); + }); +} + + +void test_check_eq_2(float value_1, float value_2) +{ + CV_CheckEQ(value_1, value_2, "Validation check failed (float)"); +} +TEST(Core_Check, testEQ_float_fail) +{ + try + { + test_check_eq_2(1234.5f, 1234.55f); + FAIL() << "Unreachable code called"; + } + catch (const cv::Exception& e) + { + EXPECT_STREQ(e.err.c_str(), +"> Validation check failed (float) (expected: 'value_1 == value_2'), where\n" +"> 'value_1' is 1234.5\n" // TODO Locale handling (use LC_ALL=C on Linux) +"> must be equal to\n" +"> 'value_2' is 1234.55\n" +); + } + catch (const std::exception& e) + { + FAIL() << "Unexpected C++ exception: " << e.what(); + } + catch (...) + { + FAIL() << "Unexpected unknown exception"; + } +} +TEST(Core_Check, testEQ_float_pass) +{ + EXPECT_NO_THROW( + { + test_check_eq_2(1234.6f, 1234.6f); + }); +} + + +void test_check_eq_3(double value_1, double value_2) +{ + CV_CheckEQ(value_1, value_2, "Validation check failed (double)"); +} +TEST(Core_Check, testEQ_double_fail) +{ + try + { + test_check_eq_3(1234.5, 1234.56); + FAIL() << "Unreachable code called"; + } + catch (const cv::Exception& e) + { + EXPECT_STREQ(e.err.c_str(), +"> Validation check failed (double) (expected: 'value_1 == value_2'), where\n" +"> 'value_1' is 1234.5\n" // TODO Locale handling (use LC_ALL=C on Linux) +"> must be equal to\n" +"> 'value_2' is 1234.56\n" +); + } + catch (const std::exception& e) + { + FAIL() << "Unexpected C++ exception: " << e.what(); + } + catch (...) + { + FAIL() << "Unexpected unknown exception"; + } +} +TEST(Core_Check, testEQ_double_pass) +{ + EXPECT_NO_THROW( + { + test_check_eq_3(1234.0f, 1234.0f); + }); +} + + +void test_check_ne_1(int value_1, int value_2) +{ + CV_CheckNE(value_1, value_2, "Validation NE check failed"); +} +TEST(Core_Check, testNE_int_fail) +{ + try + { + test_check_ne_1(123, 123); + FAIL() << "Unreachable code called"; + } + catch (const cv::Exception& e) + { + EXPECT_STREQ(e.err.c_str(), +"> Validation NE check failed (expected: 'value_1 != value_2'), where\n" +"> 'value_1' is 123\n" +"> must be not equal to\n" +"> 'value_2' is 123\n" +); + } + catch (const std::exception& e) + { + FAIL() << "Unexpected C++ exception: " << e.what(); + } + catch (...) + { + FAIL() << "Unexpected unknown exception"; + } +} +TEST(Core_Check, testNE_int_pass) +{ + EXPECT_NO_THROW( + { + test_check_ne_1(123, 1234); + }); +} + + +void test_check_le_1(int value_1, int value_2) +{ + CV_CheckLE(value_1, value_2, "Validation LE check failed"); +} +TEST(Core_Check, testLE_int_fail) +{ + try + { + test_check_le_1(1234, 123); + FAIL() << "Unreachable code called"; + } + catch (const cv::Exception& e) + { + EXPECT_STREQ(e.err.c_str(), +"> Validation LE check failed (expected: 'value_1 <= value_2'), where\n" +"> 'value_1' is 1234\n" +"> must be less than or equal to\n" +"> 'value_2' is 123\n" +); + } + catch (const std::exception& e) + { + FAIL() << "Unexpected C++ exception: " << e.what(); + } + catch (...) + { + FAIL() << "Unexpected unknown exception"; + } +} +TEST(Core_Check, testLE_int_pass) +{ + EXPECT_NO_THROW( + { + test_check_le_1(1234, 1234); + }); + EXPECT_NO_THROW( + { + test_check_le_1(123, 1234); + }); +} + +void test_check_lt_1(int value_1, int value_2) +{ + CV_CheckLT(value_1, value_2, "Validation LT check failed"); +} +TEST(Core_Check, testLT_int_fail) +{ + try + { + test_check_lt_1(1234, 123); + FAIL() << "Unreachable code called"; + } + catch (const cv::Exception& e) + { + EXPECT_STREQ(e.err.c_str(), +"> Validation LT check failed (expected: 'value_1 < value_2'), where\n" +"> 'value_1' is 1234\n" +"> must be less than\n" +"> 'value_2' is 123\n" +); + } + catch (const std::exception& e) + { + FAIL() << "Unexpected C++ exception: " << e.what(); + } + catch (...) + { + FAIL() << "Unexpected unknown exception"; + } +} +TEST(Core_Check, testLT_int_fail_eq) +{ + try + { + test_check_lt_1(123, 123); + FAIL() << "Unreachable code called"; + } + catch (const cv::Exception& e) + { + EXPECT_STREQ(e.err.c_str(), +"> Validation LT check failed (expected: 'value_1 < value_2'), where\n" +"> 'value_1' is 123\n" +"> must be less than\n" +"> 'value_2' is 123\n" +); + } + catch (const std::exception& e) + { + FAIL() << "Unexpected C++ exception: " << e.what(); + } + catch (...) + { + FAIL() << "Unexpected unknown exception"; + } +} +TEST(Core_Check, testLT_int_pass) +{ + EXPECT_NO_THROW( + { + test_check_lt_1(123, 1234); + }); +} + + +void test_check_ge_1(int value_1, int value_2) +{ + CV_CheckGE(value_1, value_2, "Validation GE check failed"); +} +TEST(Core_Check, testGE_int_fail) +{ + try + { + test_check_ge_1(123, 1234); + FAIL() << "Unreachable code called"; + } + catch (const cv::Exception& e) + { + EXPECT_STREQ(e.err.c_str(), +"> Validation GE check failed (expected: 'value_1 >= value_2'), where\n" +"> 'value_1' is 123\n" +"> must be greater than or equal to\n" +"> 'value_2' is 1234\n" +); + } + catch (const std::exception& e) + { + FAIL() << "Unexpected C++ exception: " << e.what(); + } + catch (...) + { + FAIL() << "Unexpected unknown exception"; + } +} +TEST(Core_Check, testGE_int_pass) +{ + EXPECT_NO_THROW( + { + test_check_ge_1(1234, 1234); + }); + EXPECT_NO_THROW( + { + test_check_ge_1(1234, 123); + }); +} + +void test_check_gt_1(int value_1, int value_2) +{ + CV_CheckGT(value_1, value_2, "Validation GT check failed"); +} +TEST(Core_Check, testGT_int_fail) +{ + try + { + test_check_gt_1(123, 1234); + FAIL() << "Unreachable code called"; + } + catch (const cv::Exception& e) + { + EXPECT_STREQ(e.err.c_str(), +"> Validation GT check failed (expected: 'value_1 > value_2'), where\n" +"> 'value_1' is 123\n" +"> must be greater than\n" +"> 'value_2' is 1234\n" +); + } + catch (const std::exception& e) + { + FAIL() << "Unexpected C++ exception: " << e.what(); + } + catch (...) + { + FAIL() << "Unexpected unknown exception"; + } +} +TEST(Core_Check, testGT_int_fail_eq) +{ + try + { + test_check_gt_1(123, 123); + FAIL() << "Unreachable code called"; + } + catch (const cv::Exception& e) + { + EXPECT_STREQ(e.err.c_str(), +"> Validation GT check failed (expected: 'value_1 > value_2'), where\n" +"> 'value_1' is 123\n" +"> must be greater than\n" +"> 'value_2' is 123\n" +); + } + catch (const std::exception& e) + { + FAIL() << "Unexpected C++ exception: " << e.what(); + } + catch (...) + { + FAIL() << "Unexpected unknown exception"; + } +} +TEST(Core_Check, testGT_int_pass) +{ + EXPECT_NO_THROW( + { + test_check_gt_1(1234, 123); + }); +} + + +void test_check_MatType_1(int src_type) +{ + CV_CheckTypeEQ(src_type, CV_32FC1, "Unsupported source type"); +} +TEST(Core_Check, testMatType_pass) +{ + EXPECT_NO_THROW( + { + test_check_MatType_1(CV_MAKE_TYPE(CV_32F, 1)); + }); +} +TEST(Core_Check, testMatType_fail_1) +{ + try + { + test_check_MatType_1(CV_8UC1); + FAIL() << "Unreachable code called"; + } + catch (const cv::Exception& e) + { + EXPECT_STREQ(e.err.c_str(), +"> Unsupported source type (expected: 'src_type == CV_32FC1'), where\n" +"> 'src_type' is 0 (CV_8UC1)\n" +"> must be equal to\n" +"> 'CV_32FC1' is 5 (CV_32FC1)\n" +); + } + catch (const std::exception& e) + { + FAIL() << "Unexpected C++ exception: " << e.what(); + } + catch (...) + { + FAIL() << "Unexpected unknown exception"; + } +} + +void test_check_MatType_2(int src_type) +{ + CV_CheckType(src_type, src_type == CV_32FC1 || src_type == CV_32FC3, "Unsupported src"); +} +TEST(Core_Check, testMatType_fail_2) +{ + try + { + test_check_MatType_2(CV_8UC1); + FAIL() << "Unreachable code called"; + } + catch (const cv::Exception& e) + { + EXPECT_STREQ(e.err.c_str(), +"> Unsupported src:\n" +"> 'src_type == CV_32FC1 || src_type == CV_32FC3'\n" +"> where\n> 'src_type' is 0 (CV_8UC1)\n" +); + } + catch (const std::exception& e) + { + FAIL() << "Unexpected C++ exception: " << e.what(); + } + catch (...) + { + FAIL() << "Unexpected unknown exception"; + } +} + +void test_check_MatDepth_1(int src_depth) +{ + CV_CheckDepthEQ(src_depth, CV_32F, "Unsupported source depth"); +} +TEST(Core_Check, testMatDepth_pass) +{ + EXPECT_NO_THROW( + { + test_check_MatDepth_1(CV_MAKE_TYPE(CV_32F, 1)); + }); +} +TEST(Core_Check, testMatDepth_fail_1) +{ + try + { + test_check_MatDepth_1(CV_8U); + FAIL() << "Unreachable code called"; + } + catch (const cv::Exception& e) + { + EXPECT_STREQ(e.err.c_str(), +"> Unsupported source depth (expected: 'src_depth == CV_32F'), where\n" +"> 'src_depth' is 0 (CV_8U)\n" +"> must be equal to\n" +"> 'CV_32F' is 5 (CV_32F)\n" +); + } + catch (const std::exception& e) + { + FAIL() << "Unexpected C++ exception: " << e.what(); + } + catch (...) + { + FAIL() << "Unexpected unknown exception"; + } +} + +void test_check_MatDepth_2(int src_depth) +{ + CV_CheckDepth(src_depth, src_depth == CV_32F || src_depth == CV_64F, "Unsupported src"); +} +TEST(Core_Check, testMatDepth_fail_2) +{ + try + { + test_check_MatDepth_2(CV_8U); + FAIL() << "Unreachable code called"; + } + catch (const cv::Exception& e) + { + EXPECT_STREQ(e.err.c_str(), +"> Unsupported src:\n" +"> 'src_depth == CV_32F || src_depth == CV_64F'\n" +"> where\n> 'src_depth' is 0 (CV_8U)\n" +); + } + catch (const std::exception& e) + { + FAIL() << "Unexpected C++ exception: " << e.what(); + } + catch (...) + { + FAIL() << "Unexpected unknown exception"; + } +} + + }} // namespace -- 2.7.4