xref: /netbsd-src/external/bsd/atf/dist/atf-c++/macros.hpp (revision 4e0366868d8db90087f198d3f858472763f6afe3)
1e2207522Sjmmv //
2e2207522Sjmmv // Automated Testing Framework (atf)
3e2207522Sjmmv //
4a551a20fSjmmv // Copyright (c) 2007 The NetBSD Foundation, Inc.
5e2207522Sjmmv // All rights reserved.
6e2207522Sjmmv //
7e2207522Sjmmv // Redistribution and use in source and binary forms, with or without
8e2207522Sjmmv // modification, are permitted provided that the following conditions
9e2207522Sjmmv // are met:
10e2207522Sjmmv // 1. Redistributions of source code must retain the above copyright
11e2207522Sjmmv //    notice, this list of conditions and the following disclaimer.
12e2207522Sjmmv // 2. Redistributions in binary form must reproduce the above copyright
13e2207522Sjmmv //    notice, this list of conditions and the following disclaimer in the
14e2207522Sjmmv //    documentation and/or other materials provided with the distribution.
15e2207522Sjmmv //
16e2207522Sjmmv // THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
17e2207522Sjmmv // CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
18e2207522Sjmmv // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19e2207522Sjmmv // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20e2207522Sjmmv // IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
21e2207522Sjmmv // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22e2207522Sjmmv // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
23e2207522Sjmmv // GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24e2207522Sjmmv // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25e2207522Sjmmv // IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26e2207522Sjmmv // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27e2207522Sjmmv // IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28e2207522Sjmmv //
29e2207522Sjmmv 
30e2207522Sjmmv #if !defined(_ATF_CXX_MACROS_HPP_)
31e2207522Sjmmv #define _ATF_CXX_MACROS_HPP_
32e2207522Sjmmv 
33e2207522Sjmmv #include <sstream>
34e2207522Sjmmv #include <stdexcept>
35e2207522Sjmmv #include <vector>
36e2207522Sjmmv 
37e2207522Sjmmv #include <atf-c++/tests.hpp>
38e2207522Sjmmv 
39*4e036686Sjmmv // Do not define inline methods for the test case classes.  Doing so
40*4e036686Sjmmv // significantly increases the memory requirements of GNU G++ during
41*4e036686Sjmmv // compilation.
42*4e036686Sjmmv 
439b3149ccSjmmv #define ATF_TEST_CASE_WITHOUT_HEAD(name) \
44*4e036686Sjmmv     namespace { \
459b3149ccSjmmv     class atfu_tc_ ## name : public atf::tests::tc { \
469b3149ccSjmmv         void body(void) const; \
479b3149ccSjmmv     public: \
48*4e036686Sjmmv         atfu_tc_ ## name(void); \
49*4e036686Sjmmv     }; \
50*4e036686Sjmmv     static atfu_tc_ ## name* atfu_tcptr_ ## name; \
51*4e036686Sjmmv     atfu_tc_ ## name::atfu_tc_ ## name(void) : atf::tests::tc(#name, false) {} \
52*4e036686Sjmmv     }
539b3149ccSjmmv 
54e2207522Sjmmv #define ATF_TEST_CASE(name) \
55*4e036686Sjmmv     namespace { \
56e2207522Sjmmv     class atfu_tc_ ## name : public atf::tests::tc { \
57e2207522Sjmmv         void head(void); \
58e2207522Sjmmv         void body(void) const; \
59e2207522Sjmmv     public: \
60*4e036686Sjmmv         atfu_tc_ ## name(void); \
61*4e036686Sjmmv     }; \
62*4e036686Sjmmv     static atfu_tc_ ## name* atfu_tcptr_ ## name; \
63*4e036686Sjmmv     atfu_tc_ ## name::atfu_tc_ ## name(void) : atf::tests::tc(#name, false) {} \
64*4e036686Sjmmv     }
65e2207522Sjmmv 
66e2207522Sjmmv #define ATF_TEST_CASE_WITH_CLEANUP(name) \
67*4e036686Sjmmv     namespace { \
68e2207522Sjmmv     class atfu_tc_ ## name : public atf::tests::tc { \
69e2207522Sjmmv         void head(void); \
70e2207522Sjmmv         void body(void) const; \
71e2207522Sjmmv         void cleanup(void) const; \
72e2207522Sjmmv     public: \
73*4e036686Sjmmv         atfu_tc_ ## name(void); \
74*4e036686Sjmmv     }; \
75*4e036686Sjmmv     static atfu_tc_ ## name* atfu_tcptr_ ## name; \
76*4e036686Sjmmv     atfu_tc_ ## name::atfu_tc_ ## name(void) : atf::tests::tc(#name, true) {} \
77*4e036686Sjmmv     }
78e2207522Sjmmv 
79e2207522Sjmmv #define ATF_TEST_CASE_NAME(name) atfu_tc_ ## name
80*4e036686Sjmmv #define ATF_TEST_CASE_USE(name) (atfu_tcptr_ ## name) = NULL
81e2207522Sjmmv 
82e2207522Sjmmv #define ATF_TEST_CASE_HEAD(name) \
83e2207522Sjmmv     void \
84e2207522Sjmmv     atfu_tc_ ## name::head(void)
85e2207522Sjmmv 
86e2207522Sjmmv #define ATF_TEST_CASE_BODY(name) \
87e2207522Sjmmv     void \
88e2207522Sjmmv     atfu_tc_ ## name::body(void) \
89e2207522Sjmmv         const
90e2207522Sjmmv 
91e2207522Sjmmv #define ATF_TEST_CASE_CLEANUP(name) \
92e2207522Sjmmv     void \
93e2207522Sjmmv     atfu_tc_ ## name::cleanup(void) \
94e2207522Sjmmv         const
95e2207522Sjmmv 
96e2207522Sjmmv #define ATF_FAIL(reason) atf::tests::tc::fail(reason)
97e2207522Sjmmv 
98e2207522Sjmmv #define ATF_SKIP(reason) atf::tests::tc::skip(reason)
99e2207522Sjmmv 
100e2207522Sjmmv #define ATF_PASS() atf::tests::tc::pass()
101e2207522Sjmmv 
102895f502bSjmmv #define ATF_REQUIRE(x) \
103e2207522Sjmmv     do { \
104e2207522Sjmmv         if (!(x)) { \
105e2207522Sjmmv             std::ostringstream atfu_ss; \
106e2207522Sjmmv             atfu_ss << "Line " << __LINE__ << ": " << #x << " not met"; \
107e2207522Sjmmv             atf::tests::tc::fail(atfu_ss.str()); \
108e2207522Sjmmv         } \
109e2207522Sjmmv     } while (false)
110e2207522Sjmmv 
111895f502bSjmmv #define ATF_REQUIRE_EQ(x, y) \
112e2207522Sjmmv     do { \
113e2207522Sjmmv         if ((x) != (y)) { \
114e2207522Sjmmv             std::ostringstream atfu_ss; \
115e2207522Sjmmv             atfu_ss << "Line " << __LINE__ << ": " << #x << " != " << #y \
116e2207522Sjmmv                      << " (" << (x) << " != " << (y) << ")"; \
117e2207522Sjmmv             atf::tests::tc::fail(atfu_ss.str()); \
118e2207522Sjmmv         } \
119e2207522Sjmmv     } while (false)
120e2207522Sjmmv 
121eb215e31Sjmmv #define ATF_REQUIRE_IN(element, collection) \
122eb215e31Sjmmv     ATF_REQUIRE((collection).find(element) != (collection).end())
123eb215e31Sjmmv 
124eb215e31Sjmmv #define ATF_REQUIRE_NOT_IN(element, collection) \
125eb215e31Sjmmv     ATF_REQUIRE((collection).find(element) == (collection).end())
126eb215e31Sjmmv 
1270ebb519dSjmmv #define ATF_REQUIRE_MATCH(regexp, string) \
1280ebb519dSjmmv     do { \
1290ebb519dSjmmv         if (!atf::tests::detail::match(regexp, string)) { \
1300ebb519dSjmmv             std::ostringstream atfu_ss; \
1310ebb519dSjmmv             atfu_ss << "Line " << __LINE__ << ": '" << string << "' does not " \
1320ebb519dSjmmv                     << "match regexp '" << regexp << "'"; \
1330ebb519dSjmmv             atf::tests::tc::fail(atfu_ss.str()); \
1340ebb519dSjmmv         } \
1350ebb519dSjmmv     } while (false)
1360ebb519dSjmmv 
137895f502bSjmmv #define ATF_REQUIRE_THROW(e, x) \
138e2207522Sjmmv     do { \
139e2207522Sjmmv         try { \
140e2207522Sjmmv             x; \
141e2207522Sjmmv             std::ostringstream atfu_ss; \
142e2207522Sjmmv             atfu_ss << "Line " << __LINE__ << ": " #x " did not throw " \
143e2207522Sjmmv                         #e " as expected"; \
144e2207522Sjmmv             atf::tests::tc::fail(atfu_ss.str()); \
145895f502bSjmmv         } catch (const e&) { \
146e2207522Sjmmv         } catch (const std::exception& atfu_e) { \
147e2207522Sjmmv             std::ostringstream atfu_ss; \
148e2207522Sjmmv             atfu_ss << "Line " << __LINE__ << ": " #x " threw an " \
149e2207522Sjmmv                         "unexpected error (not " #e "): " << atfu_e.what(); \
150e2207522Sjmmv             atf::tests::tc::fail(atfu_ss.str()); \
151e2207522Sjmmv         } catch (...) { \
152e2207522Sjmmv             std::ostringstream atfu_ss; \
153e2207522Sjmmv             atfu_ss << "Line " << __LINE__ << ": " #x " threw an " \
154e2207522Sjmmv                         "unexpected error (not " #e ")"; \
155e2207522Sjmmv             atf::tests::tc::fail(atfu_ss.str()); \
156e2207522Sjmmv         } \
157e2207522Sjmmv     } while (false)
158e2207522Sjmmv 
1590ebb519dSjmmv #define ATF_REQUIRE_THROW_RE(type, regexp, x) \
1600ebb519dSjmmv     do { \
1610ebb519dSjmmv         try { \
1620ebb519dSjmmv             x; \
1630ebb519dSjmmv             std::ostringstream atfu_ss; \
1640ebb519dSjmmv             atfu_ss << "Line " << __LINE__ << ": " #x " did not throw " \
1650ebb519dSjmmv                         #type " as expected"; \
1660ebb519dSjmmv             atf::tests::tc::fail(atfu_ss.str()); \
1670ebb519dSjmmv         } catch (const type& e) { \
1680ebb519dSjmmv             if (!atf::tests::detail::match(regexp, e.what())) { \
1690ebb519dSjmmv                 std::ostringstream atfu_ss; \
1700ebb519dSjmmv                 atfu_ss << "Line " << __LINE__ << ": " #x " threw " #type "(" \
1710ebb519dSjmmv                         << e.what() << "), but does not match '" << regexp \
1720ebb519dSjmmv                         << "'"; \
1730ebb519dSjmmv                 atf::tests::tc::fail(atfu_ss.str()); \
1740ebb519dSjmmv             } \
1750ebb519dSjmmv         } catch (const std::exception& atfu_e) { \
1760ebb519dSjmmv             std::ostringstream atfu_ss; \
1770ebb519dSjmmv             atfu_ss << "Line " << __LINE__ << ": " #x " threw an " \
1780ebb519dSjmmv                         "unexpected error (not " #type "): " << atfu_e.what(); \
1790ebb519dSjmmv             atf::tests::tc::fail(atfu_ss.str()); \
1800ebb519dSjmmv         } catch (...) { \
1810ebb519dSjmmv             std::ostringstream atfu_ss; \
1820ebb519dSjmmv             atfu_ss << "Line " << __LINE__ << ": " #x " threw an " \
1830ebb519dSjmmv                         "unexpected error (not " #type ")"; \
1840ebb519dSjmmv             atf::tests::tc::fail(atfu_ss.str()); \
1850ebb519dSjmmv         } \
1860ebb519dSjmmv     } while (false)
1870ebb519dSjmmv 
188edebbb8eSjmmv #define ATF_CHECK_ERRNO(exp_errno, bool_expr) \
189edebbb8eSjmmv     atf::tests::tc::check_errno(__FILE__, __LINE__, exp_errno, #bool_expr, \
190edebbb8eSjmmv                                 bool_expr)
191edebbb8eSjmmv 
192edebbb8eSjmmv #define ATF_REQUIRE_ERRNO(exp_errno, bool_expr) \
193edebbb8eSjmmv     atf::tests::tc::require_errno(__FILE__, __LINE__, exp_errno, #bool_expr, \
194edebbb8eSjmmv                                   bool_expr)
195edebbb8eSjmmv 
196e2207522Sjmmv #define ATF_INIT_TEST_CASES(tcs) \
197e2207522Sjmmv     namespace atf { \
198e2207522Sjmmv         namespace tests { \
199e2207522Sjmmv             int run_tp(int, char* const*, \
200e2207522Sjmmv                        void (*)(std::vector< atf::tests::tc * >&)); \
201e2207522Sjmmv         } \
202e2207522Sjmmv     } \
203e2207522Sjmmv     \
204e2207522Sjmmv     static void atfu_init_tcs(std::vector< atf::tests::tc * >&); \
205e2207522Sjmmv     \
206e2207522Sjmmv     int \
207e2207522Sjmmv     main(int argc, char* const* argv) \
208e2207522Sjmmv     { \
209e2207522Sjmmv         return atf::tests::run_tp(argc, argv, atfu_init_tcs); \
210e2207522Sjmmv     } \
211e2207522Sjmmv     \
212e2207522Sjmmv     static \
213e2207522Sjmmv     void \
214e2207522Sjmmv     atfu_init_tcs(std::vector< atf::tests::tc * >& tcs)
215e2207522Sjmmv 
216e2207522Sjmmv #define ATF_ADD_TEST_CASE(tcs, tcname) \
217e2207522Sjmmv     do { \
218*4e036686Sjmmv         atfu_tcptr_ ## tcname = new atfu_tc_ ## tcname(); \
219*4e036686Sjmmv         (tcs).push_back(atfu_tcptr_ ## tcname); \
220e2207522Sjmmv     } while (0);
221e2207522Sjmmv 
222e2207522Sjmmv #endif // !defined(_ATF_CXX_MACROS_HPP_)
223