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