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