2 // Copyright (C) 2008-2018 Lorenzo Caminiti
3 // Distributed under the Boost Software License, Version 1.0 (see accompanying
4 // file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt).
5 // See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html
7 // Test all derived and base classes with entry static invariants.
9 #undef BOOST_CONTRACT_TEST_NO_A_INV
10 #undef BOOST_CONTRACT_TEST_NO_B_INV
11 #undef BOOST_CONTRACT_TEST_NO_C_INV
14 #include <boost/detail/lightweight_test.hpp>
18 std::string
ok_a(bool failed
= false) {
19 std::ostringstream ok
; ok
<< "" // Suppress a warning.
20 #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS
21 << "a::static_inv" << std::endl
22 << "a::inv" << std::endl
// This can fail.
26 #ifndef BOOST_CONTRACT_NO_OLDS
27 << "a::dtor::old" << std::endl
29 << "a::dtor::body" << std::endl
30 #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS
31 << "a::static_inv" << std::endl
33 #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
34 << "a::dtor::post" << std::endl
40 enum checked
{ passed
, failed
, threw
};
42 std::string
ok_b(checked check
= passed
) {
43 std::ostringstream ok
; ok
<< "" // Suppress a warning.
44 #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS
45 << "b::static_inv" << std::endl
46 << "b::inv" << std::endl
// This can fail.
49 if(check
!= failed
) ok
50 #ifndef BOOST_CONTRACT_NO_OLDS
51 << "b::dtor::old" << std::endl
53 << "b::dtor::body" << std::endl
54 #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS
55 << "b::static_inv" << std::endl
56 << (check
== threw
? "b::inv\n" : "")
58 #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
59 << (check
== passed
? "b::dtor::post\n" : "")
65 std::string
ok_c(checked check
= passed
) {
66 std::ostringstream ok
; ok
<< "" // Suppress a warning.
67 #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS
68 << "c::static_inv" << std::endl
69 << "c::inv" << std::endl
// This can fail.
72 if(check
!= failed
) ok
73 #ifndef BOOST_CONTRACT_NO_OLDS
74 << "c::dtor::old" << std::endl
76 << "c::dtor::body" << std::endl
77 #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS
78 << "c::static_inv" << std::endl
79 << (check
== threw
? "c::inv\n" : "")
81 #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
82 << (check
== passed
? "c::dtor::post\n" : "")
88 struct err
{}; // Global decl so visible in MSVC10 lambdas.
91 std::ostringstream ok
;
100 ok
.str(""); ok
// Test nothing failed.
105 BOOST_TEST(out
.eq(ok
.str()));
107 boost::contract::set_entry_invariant_failure([&ok
] (boost::contract::from
) {
108 BOOST_TEST(out
.eq(ok
.str())); // Must check before dtor throws.
109 throw err(); // For testing only (dtors should never throw otherwise).
112 #ifdef BOOST_CONTRACT_NO_ENTRY_INVARIANTS
113 #define BOOST_CONTRACT_TEST_entry_inv 0
115 #define BOOST_CONTRACT_TEST_entry_inv 1
125 // Test entry a::inv failed...
126 << ok_a(BOOST_CONTRACT_TEST_entry_inv
)
130 #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS
132 } catch(err
const&) {
134 ok
// ...then exec other dtors and check inv on throw (as dtor threw).
135 << ok_b(BOOST_CONTRACT_TEST_entry_inv
? threw
: passed
)
136 << ok_c(BOOST_CONTRACT_TEST_entry_inv
? threw
: passed
)
138 BOOST_TEST(out
.eq(ok
.str()));
139 } catch(...) { BOOST_TEST(false); }
149 // Test entry b::inv failed...
150 << ok_b(BOOST_CONTRACT_TEST_entry_inv
? failed
: passed
)
154 #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS
156 } catch(err
const&) {
158 ok
// ...then exec other dtors and check inv on throw (as dtor threw).
159 << ok_c(BOOST_CONTRACT_TEST_entry_inv
? threw
: passed
)
161 BOOST_TEST(out
.eq(ok
.str()));
162 } catch(...) { BOOST_TEST(false); }
173 // Test entry c::inv failed...
174 << ok_c(BOOST_CONTRACT_TEST_entry_inv
? failed
: passed
)
178 #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS
180 } catch(err
const&) {
182 // ...then exec other dtors and check inv on throw (as dtor threw).
183 BOOST_TEST(out
.eq(ok
.str()));
184 } catch(...) { BOOST_TEST(false); }
186 boost::contract::set_entry_invariant_failure([] (boost::contract::from
) {
187 // Testing multiple failures so dtors must not throw multiple except,
188 // just ignore failure and continue test program (for testing only).
199 // Test entry a::inv failed (as all did).
200 << ok_a(BOOST_CONTRACT_TEST_entry_inv
)
201 #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS
202 << "a::dtor::body" << std::endl
205 // Test entry b::inv failed (as all did).
206 << ok_b(BOOST_CONTRACT_TEST_entry_inv
? failed
: passed
)
207 #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS
208 << "b::dtor::body" << std::endl
211 // Test entry c::inv failed (as all did).
212 << ok_c(BOOST_CONTRACT_TEST_entry_inv
? failed
: passed
)
213 #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS
214 << "c::dtor::body" << std::endl
217 BOOST_TEST(out
.eq(ok
.str()));
219 #undef BOOST_CONTRACT_TEST_entry_inv
220 return boost::report_errors();