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