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