• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 //  Copyright (c) 2012 Artyom Beilis (Tonkikh)
3 //  Copyright (c) 2019-2020 Alexander Grund
4 //
5 //  Distributed under the Boost Software License, Version 1.0. (See
6 //  accompanying file LICENSE or copy at
7 //  http://www.boost.org/LICENSE_1_0.txt)
8 //
9 #ifndef BOOST_NOWIDE_LIB_TEST_H_INCLUDED
10 #define BOOST_NOWIDE_LIB_TEST_H_INCLUDED
11 
12 #include <cstdlib>
13 #include <iostream>
14 #include <sstream>
15 #include <stdexcept>
16 
17 #if defined(_MSC_VER) && defined(_CPPLIB_VER) && defined(_DEBUG)
18 #include <crtdbg.h>
19 #endif
20 
21 namespace boost {
22 namespace nowide {
23     struct test_monitor
24     {
test_monitorboost::nowide::test_monitor25         test_monitor()
26         {
27 #if defined(_MSC_VER) && (_MSC_VER > 1310)
28             // disable message boxes on assert(), abort()
29             ::_set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT);
30 #endif
31 #if defined(_MSC_VER) && defined(_CPPLIB_VER) && defined(_DEBUG)
32             // disable message boxes on iterator debugging violations
33             _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE);
34             _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);
35 #endif
36         }
37     };
38 } // namespace nowide
39 } // namespace boost
40 
test_mon()41 inline boost::nowide::test_monitor& test_mon()
42 {
43     static boost::nowide::test_monitor instance;
44     return instance;
45 }
46 
47 /// Function called when a test failed to be able set a breakpoint for debugging
test_failed(const char * expr,const char * file,const int line,const char * function)48 inline void test_failed(const char* expr, const char* file, const int line, const char* function)
49 {
50     std::ostringstream ss;
51     ss << "Error " << expr << " at " << file << ':' << line << " in " << function;
52     throw std::runtime_error(ss.str());
53 }
54 
55 template<typename T, typename U>
test_equal_impl(const T & lhs,const U & rhs,const char * file,const int line,const char * function)56 inline void test_equal_impl(const T& lhs, const U& rhs, const char* file, const int line, const char* function)
57 {
58     if(lhs == rhs)
59         return;
60     std::ostringstream ss;
61     ss << "[" << lhs << "!=" << rhs << "]";
62     test_failed(ss.str().c_str(), file, line, function);
63 }
64 
65 #ifdef _MSC_VER
66 #define DISABLE_CONST_EXPR_DETECTED __pragma(warning(push)) __pragma(warning(disable : 4127))
67 #define DISABLE_CONST_EXPR_DETECTED_POP __pragma(warning(pop))
68 #else
69 #define DISABLE_CONST_EXPR_DETECTED
70 #define DISABLE_CONST_EXPR_DETECTED_POP
71 #endif
72 
73 #define TEST(x)                                            \
74     do                                                     \
75     {                                                      \
76         test_mon();                                        \
77         if(x)                                              \
78             break;                                         \
79         test_failed(#x, __FILE__, __LINE__, __FUNCTION__); \
80         DISABLE_CONST_EXPR_DETECTED                        \
81     } while(0) DISABLE_CONST_EXPR_DETECTED_POP
82 #define TEST_EQ(lhs, rhs)                                                \
83     do                                                                   \
84     {                                                                    \
85         test_mon();                                                      \
86         test_equal_impl((lhs), (rhs), __FILE__, __LINE__, __FUNCTION__); \
87         break;                                                           \
88         DISABLE_CONST_EXPR_DETECTED                                      \
89     } while(0) DISABLE_CONST_EXPR_DETECTED_POP
90 
91 #ifndef BOOST_NOWIDE_TEST_NO_MAIN
92 // Tests should implement this
93 void test_main(int argc, char** argv, char** env);
94 
main(int argc,char ** argv,char ** env)95 int main(int argc, char** argv, char** env)
96 {
97     try
98     {
99         test_main(argc, argv, env);
100     } catch(const std::exception& e)
101     {
102         std::cerr << "Failed " << e.what() << std::endl;
103         return 1;
104     }
105     return 0;
106 }
107 #endif
108 
109 #endif // #ifndef BOOST_NOWIDE_LIB_TEST_H_INCLUDED
110