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