1 | |
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 |
6 | |
7 | // Test all derived and base classes with exit invariants. |
8 | |
9 | #undef BOOST_CONTRACT_TEST_NO_A_INV |
10 | #undef BOOST_CONTRACT_TEST_NO_B_INV |
11 | #undef BOOST_CONTRACT_TEST_NO_C_INV |
12 | #include "decl.hpp" |
13 | |
14 | #include <boost/detail/lightweight_test.hpp> |
15 | #include <sstream> |
16 | #include <string> |
17 | |
18 | std::string ok_c() { |
19 | std::ostringstream ok; ok << "" // Suppress a warning. |
20 | #ifndef BOOST_CONTRACT_NO_PRECONDITIONS |
21 | << "a::ctor::pre" << std::endl |
22 | << "b::ctor::pre" << std::endl |
23 | << "c::ctor::pre" << std::endl |
24 | #endif |
25 | |
26 | #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS |
27 | << "c::static_inv" << std::endl |
28 | #endif |
29 | #ifndef BOOST_CONTRACT_NO_OLDS |
30 | << "c::ctor::old" << std::endl |
31 | #endif |
32 | << "c::ctor::body" << std::endl |
33 | #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS |
34 | << "c::static_inv" << std::endl |
35 | << "c::inv" << std::endl // This can fail. |
36 | #endif |
37 | ; |
38 | return ok.str(); |
39 | } |
40 | |
41 | std::string ok_b() { |
42 | std::ostringstream ok; ok |
43 | #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS |
44 | << "c::ctor::post" << std::endl |
45 | #endif |
46 | |
47 | #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS |
48 | << "b::static_inv" << std::endl |
49 | #endif |
50 | #ifndef BOOST_CONTRACT_NO_OLDS |
51 | << "b::ctor::old" << std::endl |
52 | #endif |
53 | << "b::ctor::body" << std::endl |
54 | #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS |
55 | << "b::static_inv" << std::endl |
56 | << "b::inv" << std::endl // This can fail. |
57 | #endif |
58 | ; |
59 | return ok.str(); |
60 | } |
61 | |
62 | std::string ok_a() { |
63 | std::ostringstream ok; ok |
64 | #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS |
65 | << "b::ctor::post" << std::endl |
66 | #endif |
67 | |
68 | #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS |
69 | << "a::static_inv" << std::endl |
70 | #endif |
71 | #ifndef BOOST_CONTRACT_NO_OLDS |
72 | << "a::ctor::old" << std::endl |
73 | #endif |
74 | << "a::ctor::body" << std::endl |
75 | #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS |
76 | << "a::static_inv" << std::endl |
77 | << "a::inv" << std::endl // This can fail. |
78 | #endif |
79 | ; |
80 | return ok.str(); |
81 | } |
82 | |
83 | std::string ok_end() { |
84 | std::ostringstream ok; ok << "" // Suppress a warning. |
85 | #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS |
86 | << "a::ctor::post" << std::endl |
87 | #endif |
88 | ; |
89 | return ok.str(); |
90 | } |
91 | |
92 | struct err {}; // Global decl so visible in MSVC10 lambdas. |
93 | |
94 | int main() { |
95 | std::ostringstream ok; |
96 | |
97 | a_exit_inv = true; |
98 | b_exit_inv = true; |
99 | c_exit_inv = true; |
100 | { |
101 | out.str(s: "" ); |
102 | a aa; |
103 | ok.str(s: "" ); ok // Test nothing fails. |
104 | << ok_c() |
105 | << ok_b() |
106 | << ok_a() |
107 | << ok_end() |
108 | ; |
109 | BOOST_TEST(out.eq(ok.str())); |
110 | } |
111 | |
112 | boost::contract::set_exit_invariant_failure( |
113 | [] (boost::contract::from) { throw err(); }); |
114 | |
115 | a_exit_inv = false; |
116 | b_exit_inv = true; |
117 | c_exit_inv = true; |
118 | try { |
119 | out.str(s: "" ); |
120 | a aa; |
121 | #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS |
122 | BOOST_TEST(false); |
123 | } catch(err const&) { |
124 | #endif |
125 | ok.str(s: "" ); ok |
126 | << ok_c() |
127 | << ok_b() |
128 | << ok_a() // Test a::inv failed. |
129 | #ifdef BOOST_CONTRACT_NO_EXIT_INVARIANTS |
130 | << ok_end() |
131 | #endif |
132 | ; |
133 | BOOST_TEST(out.eq(ok.str())); |
134 | } catch(...) { BOOST_TEST(false); } |
135 | |
136 | a_exit_inv = true; |
137 | b_exit_inv = false; |
138 | c_exit_inv = true; |
139 | try { |
140 | out.str(s: "" ); |
141 | a aa; |
142 | #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS |
143 | BOOST_TEST(false); |
144 | } catch(err const&) { |
145 | #endif |
146 | ok.str(s: "" ); ok |
147 | << ok_c() |
148 | << ok_b() // Test bb::inv failed. |
149 | #ifdef BOOST_CONTRACT_NO_EXIT_INVARIANTS |
150 | << ok_a() |
151 | << ok_end() |
152 | #endif |
153 | ; |
154 | BOOST_TEST(out.eq(ok.str())); |
155 | } catch(...) { BOOST_TEST(false); } |
156 | |
157 | a_exit_inv = true; |
158 | b_exit_inv = true; |
159 | c_exit_inv = false; |
160 | try { |
161 | out.str(s: "" ); |
162 | a aa; |
163 | #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS |
164 | BOOST_TEST(false); |
165 | } catch(err const&) { |
166 | #endif |
167 | ok.str(s: "" ); ok |
168 | << ok_c() // Test c::inv failed. |
169 | #ifdef BOOST_CONTRACT_NO_EXIT_INVARIANTS |
170 | << ok_b() |
171 | << ok_a() |
172 | << ok_end() |
173 | #endif |
174 | ; |
175 | BOOST_TEST(out.eq(ok.str())); |
176 | } catch(...) { BOOST_TEST(false); } |
177 | |
178 | a_exit_inv = false; |
179 | b_exit_inv = false; |
180 | c_exit_inv = false; |
181 | try { |
182 | out.str(s: "" ); |
183 | a aa; |
184 | #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS |
185 | BOOST_TEST(false); |
186 | } catch(err const&) { |
187 | #endif |
188 | ok.str(s: "" ); ok |
189 | << ok_c() // Test c::inv failed. |
190 | #ifdef BOOST_CONTRACT_NO_EXIT_INVARIANTS |
191 | << ok_b() |
192 | << ok_a() |
193 | << ok_end() |
194 | #endif |
195 | ; |
196 | BOOST_TEST(out.eq(ok.str())); |
197 | } catch(...) { BOOST_TEST(false); } |
198 | |
199 | return boost::report_errors(); |
200 | } |
201 | |
202 | |