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