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