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