• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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