/src/flatbuffers/tests/test_assert.h
Line | Count | Source (jump to first uncovered line) |
1 | | #ifndef TEST_ASSERT_H |
2 | | #define TEST_ASSERT_H |
3 | | |
4 | | #include "flatbuffers/base.h" |
5 | | #include "flatbuffers/util.h" |
6 | | |
7 | | // clang-format off |
8 | | |
9 | | #ifdef __ANDROID__ |
10 | | #include <android/log.h> |
11 | | #define TEST_OUTPUT_LINE(...) \ |
12 | | __android_log_print(ANDROID_LOG_INFO, "FlatBuffers", __VA_ARGS__) |
13 | | #define FLATBUFFERS_NO_FILE_TESTS |
14 | | #else |
15 | | #define TEST_OUTPUT_LINE(...) \ |
16 | 0 | do { printf(__VA_ARGS__); printf("\n"); } while(!IsConstTrue(true)) |
17 | | #endif |
18 | | |
19 | 2 | #define TEST_EQ(exp, val) TestEq(exp, val, "'" #exp "' != '" #val "'", __FILE__, __LINE__, "") |
20 | | #define TEST_NE(exp, val) TestNe(exp, val, "'" #exp "' == '" #val "'", __FILE__, __LINE__, "") |
21 | | #define TEST_ASSERT(val) TestEq(true, !!(val), "'" "true" "' != '" #val "'", __FILE__, __LINE__, "") |
22 | | #define TEST_NULL(val) TestEq(true, (val) == nullptr, "'" "nullptr" "' != '" #val "'", __FILE__, __LINE__, "") |
23 | 642 | #define TEST_NOTNULL(val) TestEq(true, (val) != nullptr, "'" "nullptr" "' == '" #val "'", __FILE__, __LINE__, "") |
24 | | #define TEST_EQ_STR(exp, val) TestEqStr(exp, val, "'" #exp "' != '" #val "'", __FILE__, __LINE__, "") |
25 | | |
26 | | #ifdef _WIN32 |
27 | | #define TEST_ASSERT_FUNC(val) TestEq(true, !!(val), "'" "true" "' != '" #val "'", __FILE__, __LINE__, __FUNCTION__) |
28 | | #define TEST_EQ_FUNC(exp, val) TestEq(exp, val, "'" #exp "' != '" #val "'", __FILE__, __LINE__, __FUNCTION__) |
29 | | #else |
30 | | #define TEST_ASSERT_FUNC(val) TestEq(true, !!(val), "'" "true" "' != '" #val "'", __FILE__, __LINE__, __PRETTY_FUNCTION__) |
31 | | #define TEST_EQ_FUNC(exp, val) TestEq(exp, val, "'" #exp "' != '" #val "'", __FILE__, __LINE__, __PRETTY_FUNCTION__) |
32 | | #endif |
33 | | |
34 | | // clang-format on |
35 | | |
36 | | extern int testing_fails; |
37 | | |
38 | | // Listener of TestFail, like 'gtest::OnTestPartResult' event handler. |
39 | | // Called in TestFail after a failed assertion. |
40 | | typedef bool (*TestFailEventListener)(const char *expval, const char *val, |
41 | | const char *exp, const char *file, |
42 | | int line, const char *func); |
43 | | |
44 | | // Prepare test engine (MSVC assertion setup, etc). |
45 | | // listener - this function will be notified on each TestFail call. |
46 | | void InitTestEngine(TestFailEventListener listener = nullptr); |
47 | | |
48 | | // Release all test-engine resources. |
49 | | // Prints or schedule a debug report if all test passed. |
50 | | // Returns 0 if all tests passed or 1 otherwise. |
51 | | // Memory leak report: FLATBUFFERS_MEMORY_LEAK_TRACKING && _MSC_VER && _DEBUG. |
52 | | int CloseTestEngine(bool force_report = false); |
53 | | |
54 | | // Write captured state to a log and terminate test run. |
55 | | void TestFail(const char *expval, const char *val, const char *exp, |
56 | | const char *file, int line, const char *func = nullptr); |
57 | | |
58 | | void TestEqStr(const char *expval, const char *val, const char *exp, |
59 | | const char *file, int line, const char *func = nullptr); |
60 | | |
61 | | // Workaround for `enum class` printing. |
62 | | // There is an issue with the printing of enums with a fixed underlying type. |
63 | | // These enums are generated by `flatc` if `--scoped-enums` is active. |
64 | | // All modern compilers have problems with `std::stringstream&<<(T v)` if T is |
65 | | // an enum with fixed type. For details see DR1601: |
66 | | // http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1601 |
67 | | // https://stackoverflow.com/questions/34336024/ambiguous-overload-when-writing-an-enum-with-an-enum-base-but-only-with-clang |
68 | | |
69 | | template<typename T, bool is_enum_type = flatbuffers::is_enum<T>::value> |
70 | | struct underlying_of_scalar { |
71 | | static_assert(flatbuffers::is_scalar<T>::value, "invalid type T"); |
72 | | typedef T type; |
73 | | }; |
74 | | |
75 | | template<typename T> struct underlying_of_scalar<T, true> { |
76 | | // clang-format off |
77 | | // There are old compilers without full C++11 support (see stl_emulation.h). |
78 | | #if defined(FLATBUFFERS_TEMPLATES_ALIASES) |
79 | | using type = typename std::underlying_type<T>::type; |
80 | | #else |
81 | | typedef int64_t type; |
82 | | #endif |
83 | | // clang-format on |
84 | | }; |
85 | | |
86 | | template<typename T> |
87 | 0 | typename underlying_of_scalar<T>::type scalar_as_underlying(T v) { |
88 | 0 | return static_cast<typename underlying_of_scalar<T>::type>(v); |
89 | 0 | } |
90 | | |
91 | | template<typename T, typename U> |
92 | | void TestEq(T expval, U val, const char *exp, const char *file, int line, |
93 | 644 | const char *func) { |
94 | 644 | if (static_cast<U>(expval) != val) { |
95 | 0 | TestFail(flatbuffers::NumToString(scalar_as_underlying(expval)).c_str(), |
96 | 0 | flatbuffers::NumToString(scalar_as_underlying(val)).c_str(), exp, |
97 | 0 | file, line, func); |
98 | 0 | } |
99 | 644 | } |
100 | | |
101 | | template<> |
102 | | inline void TestEq<std::string, std::string>(std::string expval, |
103 | | std::string val, const char *exp, |
104 | | const char *file, int line, |
105 | 0 | const char *func) { |
106 | 0 | if (expval != val) { |
107 | 0 | TestFail(expval.c_str(), val.c_str(), exp, file, line, func); |
108 | 0 | } |
109 | 0 | } |
110 | | |
111 | | template<typename T, typename U> |
112 | | void TestNe(T expval, U val, const char *exp, const char *file, int line, |
113 | | const char *func) { |
114 | | if (static_cast<U>(expval) == val) { |
115 | | TestFail(flatbuffers::NumToString(scalar_as_underlying(expval)).c_str(), |
116 | | flatbuffers::NumToString(scalar_as_underlying(val)).c_str(), exp, |
117 | | file, line, func); |
118 | | } |
119 | | } |
120 | | |
121 | | template<> |
122 | | inline void TestNe<std::string, std::string>(std::string expval, |
123 | | std::string val, const char *exp, |
124 | | const char *file, int line, |
125 | 0 | const char *func) { |
126 | 0 | if (expval == val) { |
127 | 0 | TestFail(expval.c_str(), val.c_str(), exp, file, line, func); |
128 | 0 | } |
129 | 0 | } |
130 | | |
131 | | #endif // !TEST_ASSERT_H |