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