1240116Smarcel// Copyright (c) 2007 The NetBSD Foundation, Inc.
2240116Smarcel// All rights reserved.
3240116Smarcel//
4240116Smarcel// Redistribution and use in source and binary forms, with or without
5240116Smarcel// modification, are permitted provided that the following conditions
6240116Smarcel// are met:
7240116Smarcel// 1. Redistributions of source code must retain the above copyright
8240116Smarcel//    notice, this list of conditions and the following disclaimer.
9240116Smarcel// 2. Redistributions in binary form must reproduce the above copyright
10240116Smarcel//    notice, this list of conditions and the following disclaimer in the
11240116Smarcel//    documentation and/or other materials provided with the distribution.
12240116Smarcel//
13240116Smarcel// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
14240116Smarcel// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
15240116Smarcel// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
16240116Smarcel// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17240116Smarcel// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
18240116Smarcel// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19240116Smarcel// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
20240116Smarcel// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21240116Smarcel// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
22240116Smarcel// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23240116Smarcel// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
24240116Smarcel// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25240116Smarcel
26275988Sngie#if !defined(ATF_CXX_MACROS_HPP)
27275988Sngie#define ATF_CXX_MACROS_HPP
28240116Smarcel
29240116Smarcel#include <sstream>
30240116Smarcel#include <stdexcept>
31240116Smarcel#include <vector>
32240116Smarcel
33240116Smarcel#include <atf-c++/tests.hpp>
34240116Smarcel
35240116Smarcel// Do not define inline methods for the test case classes.  Doing so
36240116Smarcel// significantly increases the memory requirements of GNU G++ during
37240116Smarcel// compilation.
38240116Smarcel
39240116Smarcel#define ATF_TEST_CASE_WITHOUT_HEAD(name) \
40240116Smarcel    namespace { \
41240116Smarcel    class atfu_tc_ ## name : public atf::tests::tc { \
42240116Smarcel        void body(void) const; \
43240116Smarcel    public: \
44240116Smarcel        atfu_tc_ ## name(void); \
45240116Smarcel    }; \
46240116Smarcel    static atfu_tc_ ## name* atfu_tcptr_ ## name; \
47240116Smarcel    atfu_tc_ ## name::atfu_tc_ ## name(void) : atf::tests::tc(#name, false) {} \
48240116Smarcel    }
49240116Smarcel
50240116Smarcel#define ATF_TEST_CASE(name) \
51240116Smarcel    namespace { \
52240116Smarcel    class atfu_tc_ ## name : public atf::tests::tc { \
53240116Smarcel        void head(void); \
54240116Smarcel        void body(void) const; \
55240116Smarcel    public: \
56240116Smarcel        atfu_tc_ ## name(void); \
57240116Smarcel    }; \
58240116Smarcel    static atfu_tc_ ## name* atfu_tcptr_ ## name; \
59240116Smarcel    atfu_tc_ ## name::atfu_tc_ ## name(void) : atf::tests::tc(#name, false) {} \
60240116Smarcel    }
61240116Smarcel
62240116Smarcel#define ATF_TEST_CASE_WITH_CLEANUP(name) \
63240116Smarcel    namespace { \
64240116Smarcel    class atfu_tc_ ## name : public atf::tests::tc { \
65240116Smarcel        void head(void); \
66240116Smarcel        void body(void) const; \
67240116Smarcel        void cleanup(void) const; \
68240116Smarcel    public: \
69240116Smarcel        atfu_tc_ ## name(void); \
70240116Smarcel    }; \
71240116Smarcel    static atfu_tc_ ## name* atfu_tcptr_ ## name; \
72240116Smarcel    atfu_tc_ ## name::atfu_tc_ ## name(void) : atf::tests::tc(#name, true) {} \
73240116Smarcel    }
74240116Smarcel
75240116Smarcel#define ATF_TEST_CASE_NAME(name) atfu_tc_ ## name
76240116Smarcel#define ATF_TEST_CASE_USE(name) (atfu_tcptr_ ## name) = NULL
77240116Smarcel
78240116Smarcel#define ATF_TEST_CASE_HEAD(name) \
79240116Smarcel    void \
80240116Smarcel    atfu_tc_ ## name::head(void)
81240116Smarcel
82240116Smarcel#define ATF_TEST_CASE_BODY(name) \
83240116Smarcel    void \
84240116Smarcel    atfu_tc_ ## name::body(void) \
85240116Smarcel        const
86240116Smarcel
87240116Smarcel#define ATF_TEST_CASE_CLEANUP(name) \
88240116Smarcel    void \
89240116Smarcel    atfu_tc_ ## name::cleanup(void) \
90240116Smarcel        const
91240116Smarcel
92240116Smarcel#define ATF_FAIL(reason) atf::tests::tc::fail(reason)
93240116Smarcel
94240116Smarcel#define ATF_SKIP(reason) atf::tests::tc::skip(reason)
95240116Smarcel
96240116Smarcel#define ATF_PASS() atf::tests::tc::pass()
97240116Smarcel
98275988Sngie#define ATF_REQUIRE(expression) \
99240116Smarcel    do { \
100275988Sngie        if (!(expression)) { \
101240116Smarcel            std::ostringstream atfu_ss; \
102275988Sngie            atfu_ss << "Line " << __LINE__ << ": " << #expression \
103275988Sngie                    << " not met"; \
104240116Smarcel            atf::tests::tc::fail(atfu_ss.str()); \
105240116Smarcel        } \
106240116Smarcel    } while (false)
107240116Smarcel
108275988Sngie#define ATF_REQUIRE_EQ(expected, actual) \
109240116Smarcel    do { \
110275988Sngie        if ((expected) != (actual)) { \
111240116Smarcel            std::ostringstream atfu_ss; \
112275988Sngie            atfu_ss << "Line " << __LINE__ << ": " \
113275988Sngie                    << #expected << " != " << #actual \
114275988Sngie                    << " (" << (expected) << " != " << (actual) << ")"; \
115240116Smarcel            atf::tests::tc::fail(atfu_ss.str()); \
116240116Smarcel        } \
117240116Smarcel    } while (false)
118240116Smarcel
119240116Smarcel#define ATF_REQUIRE_IN(element, collection) \
120240116Smarcel    ATF_REQUIRE((collection).find(element) != (collection).end())
121240116Smarcel
122240116Smarcel#define ATF_REQUIRE_NOT_IN(element, collection) \
123240116Smarcel    ATF_REQUIRE((collection).find(element) == (collection).end())
124240116Smarcel
125240116Smarcel#define ATF_REQUIRE_MATCH(regexp, string) \
126240116Smarcel    do { \
127240116Smarcel        if (!atf::tests::detail::match(regexp, string)) { \
128240116Smarcel            std::ostringstream atfu_ss; \
129240116Smarcel            atfu_ss << "Line " << __LINE__ << ": '" << string << "' does not " \
130240116Smarcel                    << "match regexp '" << regexp << "'"; \
131240116Smarcel            atf::tests::tc::fail(atfu_ss.str()); \
132240116Smarcel        } \
133240116Smarcel    } while (false)
134240116Smarcel
135275988Sngie#define ATF_REQUIRE_THROW(expected_exception, statement) \
136240116Smarcel    do { \
137240116Smarcel        try { \
138275988Sngie            statement; \
139240116Smarcel            std::ostringstream atfu_ss; \
140275988Sngie            atfu_ss << "Line " << __LINE__ \
141275988Sngie                    << ": " #statement " did not throw " #expected_exception \
142275988Sngie                       " as expected"; \
143240116Smarcel            atf::tests::tc::fail(atfu_ss.str()); \
144275988Sngie        } catch (const expected_exception&) { \
145240116Smarcel        } catch (const std::exception& atfu_e) { \
146240116Smarcel            std::ostringstream atfu_ss; \
147275988Sngie            atfu_ss << "Line " << __LINE__ << ": " #statement " threw an " \
148275988Sngie                       "unexpected error (not " #expected_exception "): " \
149275988Sngie                    << atfu_e.what(); \
150240116Smarcel            atf::tests::tc::fail(atfu_ss.str()); \
151240116Smarcel        } catch (...) { \
152240116Smarcel            std::ostringstream atfu_ss; \
153275988Sngie            atfu_ss << "Line " << __LINE__ << ": " #statement " threw an " \
154275988Sngie                       "unexpected error (not " #expected_exception ")"; \
155240116Smarcel            atf::tests::tc::fail(atfu_ss.str()); \
156240116Smarcel        } \
157240116Smarcel    } while (false)
158240116Smarcel
159275988Sngie#define ATF_REQUIRE_THROW_RE(expected_exception, regexp, statement) \
160240116Smarcel    do { \
161240116Smarcel        try { \
162275988Sngie            statement; \
163240116Smarcel            std::ostringstream atfu_ss; \
164275988Sngie            atfu_ss << "Line " << __LINE__ \
165275988Sngie                    << ": " #statement " did not throw " #expected_exception \
166275988Sngie                       " as expected"; \
167240116Smarcel            atf::tests::tc::fail(atfu_ss.str()); \
168275988Sngie        } catch (const expected_exception& e) { \
169240116Smarcel            if (!atf::tests::detail::match(regexp, e.what())) { \
170240116Smarcel                std::ostringstream atfu_ss; \
171275988Sngie                atfu_ss << "Line " << __LINE__ \
172275988Sngie                        << ": " #statement " threw " #expected_exception "(" \
173240116Smarcel                        << e.what() << "), but does not match '" << regexp \
174240116Smarcel                        << "'"; \
175240116Smarcel                atf::tests::tc::fail(atfu_ss.str()); \
176240116Smarcel            } \
177240116Smarcel        } catch (const std::exception& atfu_e) { \
178240116Smarcel            std::ostringstream atfu_ss; \
179275988Sngie            atfu_ss << "Line " << __LINE__ << ": " #statement " threw an " \
180275988Sngie                        "unexpected error (not " #expected_exception "): " \
181275988Sngie                    << atfu_e.what(); \
182240116Smarcel            atf::tests::tc::fail(atfu_ss.str()); \
183240116Smarcel        } catch (...) { \
184240116Smarcel            std::ostringstream atfu_ss; \
185275988Sngie            atfu_ss << "Line " << __LINE__ << ": " #statement " threw an " \
186275988Sngie                        "unexpected error (not " #expected_exception ")"; \
187240116Smarcel            atf::tests::tc::fail(atfu_ss.str()); \
188240116Smarcel        } \
189240116Smarcel    } while (false)
190240116Smarcel
191275988Sngie#define ATF_CHECK_ERRNO(expected_errno, bool_expr) \
192275988Sngie    atf::tests::tc::check_errno(__FILE__, __LINE__, expected_errno, \
193275988Sngie                                #bool_expr, bool_expr)
194240116Smarcel
195275988Sngie#define ATF_REQUIRE_ERRNO(expected_errno, bool_expr) \
196275988Sngie    atf::tests::tc::require_errno(__FILE__, __LINE__, expected_errno, \
197275988Sngie                                  #bool_expr, bool_expr)
198240116Smarcel
199240116Smarcel#define ATF_INIT_TEST_CASES(tcs) \
200240116Smarcel    namespace atf { \
201240116Smarcel        namespace tests { \
202275988Sngie            int run_tp(int, char**, \
203240116Smarcel                       void (*)(std::vector< atf::tests::tc * >&)); \
204240116Smarcel        } \
205240116Smarcel    } \
206240116Smarcel    \
207240116Smarcel    static void atfu_init_tcs(std::vector< atf::tests::tc * >&); \
208240116Smarcel    \
209240116Smarcel    int \
210275988Sngie    main(int argc, char** argv) \
211240116Smarcel    { \
212240116Smarcel        return atf::tests::run_tp(argc, argv, atfu_init_tcs); \
213240116Smarcel    } \
214240116Smarcel    \
215240116Smarcel    static \
216240116Smarcel    void \
217240116Smarcel    atfu_init_tcs(std::vector< atf::tests::tc * >& tcs)
218240116Smarcel
219240116Smarcel#define ATF_ADD_TEST_CASE(tcs, tcname) \
220240116Smarcel    do { \
221240116Smarcel        atfu_tcptr_ ## tcname = new atfu_tc_ ## tcname(); \
222240116Smarcel        (tcs).push_back(atfu_tcptr_ ## tcname); \
223240116Smarcel    } while (0);
224240116Smarcel
225275988Sngie#endif // !defined(ATF_CXX_MACROS_HPP)
226