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