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