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