1 // Copyright (c) 2007 The NetBSD Foundation, Inc. 2 // All rights reserved. 3 // 4 // Redistribution and use in source and binary forms, with or without 5 // modification, are permitted provided that the following conditions 6 // are met: 7 // 1. Redistributions of source code must retain the above copyright 8 // notice, this list of conditions and the following disclaimer. 9 // 2. Redistributions in binary form must reproduce the above copyright 10 // notice, this list of conditions and the following disclaimer in the 11 // documentation and/or other materials provided with the distribution. 12 // 13 // THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND 14 // CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 15 // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 16 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17 // IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY 18 // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 20 // GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 22 // IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 23 // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 24 // IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 26 #if !defined(ATF_CXX_MACROS_HPP) 27 #define ATF_CXX_MACROS_HPP 28 29 #include <sstream> 30 #include <stdexcept> 31 #include <vector> 32 33 #include <atf-c++/tests.hpp> 34 35 // Do not define inline methods for the test case classes. Doing so 36 // significantly increases the memory requirements of GNU G++ during 37 // compilation. 38 39 #define ATF_TEST_CASE_WITHOUT_HEAD(name) \ 40 namespace { \ 41 class atfu_tc_ ## name : public atf::tests::tc { \ 42 void body(void) const; \ 43 public: \ 44 atfu_tc_ ## name(void); \ 45 }; \ 46 static atfu_tc_ ## name* atfu_tcptr_ ## name; \ 47 atfu_tc_ ## name::atfu_tc_ ## name(void) : atf::tests::tc(#name, false) {} \ 48 } 49 50 #define ATF_TEST_CASE(name) \ 51 namespace { \ 52 class atfu_tc_ ## name : public atf::tests::tc { \ 53 void head(void); \ 54 void body(void) const; \ 55 public: \ 56 atfu_tc_ ## name(void); \ 57 }; \ 58 static atfu_tc_ ## name* atfu_tcptr_ ## name; \ 59 atfu_tc_ ## name::atfu_tc_ ## name(void) : atf::tests::tc(#name, false) {} \ 60 } 61 62 #define ATF_TEST_CASE_WITH_CLEANUP(name) \ 63 namespace { \ 64 class atfu_tc_ ## name : public atf::tests::tc { \ 65 void head(void); \ 66 void body(void) const; \ 67 void cleanup(void) const; \ 68 public: \ 69 atfu_tc_ ## name(void); \ 70 }; \ 71 static atfu_tc_ ## name* atfu_tcptr_ ## name; \ 72 atfu_tc_ ## name::atfu_tc_ ## name(void) : atf::tests::tc(#name, true) {} \ 73 } 74 75 #define ATF_TEST_CASE_NAME(name) atfu_tc_ ## name 76 #define ATF_TEST_CASE_USE(name) (atfu_tcptr_ ## name) = NULL 77 78 #define ATF_TEST_CASE_HEAD(name) \ 79 void \ 80 atfu_tc_ ## name::head(void) 81 82 #define ATF_TEST_CASE_BODY(name) \ 83 void \ 84 atfu_tc_ ## name::body(void) \ 85 const 86 87 #define ATF_TEST_CASE_CLEANUP(name) \ 88 void \ 89 atfu_tc_ ## name::cleanup(void) \ 90 const 91 92 #define ATF_FAIL(reason) atf::tests::tc::fail(reason) 93 94 #define ATF_SKIP(reason) atf::tests::tc::skip(reason) 95 96 #define ATF_PASS() atf::tests::tc::pass() 97 98 #define ATF_REQUIRE(expression) \ 99 do { \ 100 if (!(expression)) { \ 101 std::ostringstream atfu_ss; \ 102 atfu_ss << "Line " << __LINE__ << ": " << #expression \ 103 << " not met"; \ 104 atf::tests::tc::fail(atfu_ss.str()); \ 105 } \ 106 } while (false) 107 108 #define ATF_REQUIRE_EQ(expected, actual) \ 109 do { \ 110 if ((expected) != (actual)) { \ 111 std::ostringstream atfu_ss; \ 112 atfu_ss << "Line " << __LINE__ << ": " \ 113 << #expected << " != " << #actual \ 114 << " (" << (expected) << " != " << (actual) << ")"; \ 115 atf::tests::tc::fail(atfu_ss.str()); \ 116 } \ 117 } while (false) 118 119 #define ATF_REQUIRE_IN(element, collection) \ 120 ATF_REQUIRE((collection).find(element) != (collection).end()) 121 122 #define ATF_REQUIRE_NOT_IN(element, collection) \ 123 ATF_REQUIRE((collection).find(element) == (collection).end()) 124 125 #define ATF_REQUIRE_MATCH(regexp, string) \ 126 do { \ 127 if (!atf::tests::detail::match(regexp, string)) { \ 128 std::ostringstream atfu_ss; \ 129 atfu_ss << "Line " << __LINE__ << ": '" << string << "' does not " \ 130 << "match regexp '" << regexp << "'"; \ 131 atf::tests::tc::fail(atfu_ss.str()); \ 132 } \ 133 } while (false) 134 135 #define ATF_REQUIRE_THROW(expected_exception, statement) \ 136 do { \ 137 try { \ 138 statement; \ 139 std::ostringstream atfu_ss; \ 140 atfu_ss << "Line " << __LINE__ \ 141 << ": " #statement " did not throw " #expected_exception \ 142 " as expected"; \ 143 atf::tests::tc::fail(atfu_ss.str()); \ 144 } catch (const expected_exception&) { \ 145 } catch (const std::exception& atfu_e) { \ 146 std::ostringstream atfu_ss; \ 147 atfu_ss << "Line " << __LINE__ << ": " #statement " threw an " \ 148 "unexpected error (not " #expected_exception "): " \ 149 << atfu_e.what(); \ 150 atf::tests::tc::fail(atfu_ss.str()); \ 151 } catch (...) { \ 152 std::ostringstream atfu_ss; \ 153 atfu_ss << "Line " << __LINE__ << ": " #statement " threw an " \ 154 "unexpected error (not " #expected_exception ")"; \ 155 atf::tests::tc::fail(atfu_ss.str()); \ 156 } \ 157 } while (false) 158 159 #define ATF_REQUIRE_THROW_RE(expected_exception, regexp, statement) \ 160 do { \ 161 try { \ 162 statement; \ 163 std::ostringstream atfu_ss; \ 164 atfu_ss << "Line " << __LINE__ \ 165 << ": " #statement " did not throw " #expected_exception \ 166 " as expected"; \ 167 atf::tests::tc::fail(atfu_ss.str()); \ 168 } catch (const expected_exception& e) { \ 169 if (!atf::tests::detail::match(regexp, e.what())) { \ 170 std::ostringstream atfu_ss; \ 171 atfu_ss << "Line " << __LINE__ \ 172 << ": " #statement " threw " #expected_exception "(" \ 173 << e.what() << "), but does not match '" << regexp \ 174 << "'"; \ 175 atf::tests::tc::fail(atfu_ss.str()); \ 176 } \ 177 } catch (const std::exception& atfu_e) { \ 178 std::ostringstream atfu_ss; \ 179 atfu_ss << "Line " << __LINE__ << ": " #statement " threw an " \ 180 "unexpected error (not " #expected_exception "): " \ 181 << atfu_e.what(); \ 182 atf::tests::tc::fail(atfu_ss.str()); \ 183 } catch (...) { \ 184 std::ostringstream atfu_ss; \ 185 atfu_ss << "Line " << __LINE__ << ": " #statement " threw an " \ 186 "unexpected error (not " #expected_exception ")"; \ 187 atf::tests::tc::fail(atfu_ss.str()); \ 188 } \ 189 } while (false) 190 191 #define ATF_CHECK_ERRNO(expected_errno, bool_expr) \ 192 atf::tests::tc::check_errno(__FILE__, __LINE__, expected_errno, \ 193 #bool_expr, bool_expr) 194 195 #define ATF_REQUIRE_ERRNO(expected_errno, bool_expr) \ 196 atf::tests::tc::require_errno(__FILE__, __LINE__, expected_errno, \ 197 #bool_expr, bool_expr) 198 199 #define ATF_INIT_TEST_CASES(tcs) \ 200 namespace atf { \ 201 namespace tests { \ 202 int run_tp(int, char**, \ 203 void (*)(std::vector< atf::tests::tc * >&)); \ 204 } \ 205 } \ 206 \ 207 static void atfu_init_tcs(std::vector< atf::tests::tc * >&); \ 208 \ 209 int \ 210 main(int argc, char** argv) \ 211 { \ 212 return atf::tests::run_tp(argc, argv, atfu_init_tcs); \ 213 } \ 214 \ 215 static \ 216 void \ 217 atfu_init_tcs(std::vector< atf::tests::tc * >& tcs) 218 219 #define ATF_ADD_TEST_CASE(tcs, tcname) \ 220 do { \ 221 atfu_tcptr_ ## tcname = new atfu_tc_ ## tcname(); \ 222 (tcs).push_back(atfu_tcptr_ ## tcname); \ 223 } while (0); 224 225 #endif // !defined(ATF_CXX_MACROS_HPP) 226