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 preconditions.
8 
9 #undef BOOST_CONTRACT_TEST_NO_A_PRE
10 #define BOOST_CONTRACT_TEST_NO_B_PRE
11 #undef BOOST_CONTRACT_TEST_NO_C_PRE
12 #include "decl.hpp"
13 
14 #include <boost/detail/lightweight_test.hpp>
15 #include <sstream>
16 #include <string>
17 
ok_after()18 std::string ok_after() {
19     std::ostringstream ok; ok
20         #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS
21             << "c::static_inv" << std::endl
22         #endif
23         #ifndef BOOST_CONTRACT_NO_OLDS
24             << "c::ctor::old" << std::endl
25         #endif
26         << "c::ctor::body" << std::endl
27         #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS
28             << "c::static_inv" << std::endl
29             << "c::inv" << std::endl
30         #endif
31         #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
32             << "c::ctor::post" << std::endl
33         #endif
34 
35         #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS
36             << "b::static_inv" << std::endl
37         #endif
38         #ifndef BOOST_CONTRACT_NO_OLDS
39             << "b::ctor::old" << std::endl
40         #endif
41         << "b::ctor::body" << std::endl
42         #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS
43             << "b::static_inv" << std::endl
44             << "b::inv" << std::endl
45         #endif
46         #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
47             << "b::ctor::post" << std::endl
48         #endif
49 
50         #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS
51             << "a::static_inv" << std::endl
52         #endif
53         #ifndef BOOST_CONTRACT_NO_OLDS
54             << "a::ctor::old" << std::endl
55         #endif
56         << "a::ctor::body" << std::endl
57         #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS
58             << "a::static_inv" << std::endl
59             << "a::inv" << std::endl
60         #endif
61         #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
62             << "a::ctor::post" << std::endl
63         #endif
64     ;
65     return ok.str();
66 }
67 
68 struct err {}; // Global decl so visible in MSVC10 lambdas.
69 
main()70 int main() {
71     std::ostringstream ok;
72 
73     a_pre = true;
74     b_pre = true;
75     c_pre = true;
76     {
77         out.str("");
78         a aa;
79         ok.str(""); ok // Test nothing failed.
80             #ifndef BOOST_CONTRACT_NO_PRECONDITIONS
81                 << "a::ctor::pre" << std::endl
82                 << "c::ctor::pre" << std::endl
83             #endif
84             << ok_after()
85         ;
86         BOOST_TEST(out.eq(ok.str()));
87     }
88 
89     boost::contract::set_precondition_failure(
90             [] (boost::contract::from) { throw err(); });
91 
92     a_pre = false;
93     b_pre = true;
94     c_pre = true;
95     try {
96         out.str("");
97         a aa;
98         #ifndef BOOST_CONTRACT_NO_PRECONDITIONS
99                 BOOST_TEST(false);
100             } catch(err const&) {
101         #endif
102         ok.str(""); ok
103             #ifndef BOOST_CONTRACT_NO_PRECONDITIONS
104                 << "a::ctor::pre" << std::endl // Test this failed.
105             #else
106                 << ok_after()
107             #endif
108         ;
109         BOOST_TEST(out.eq(ok.str()));
110     } catch(...) { BOOST_TEST(false); }
111 
112     a_pre = true;
113     b_pre = false;
114     c_pre = true;
115     {
116         out.str("");
117         a aa;
118         ok.str(""); ok
119             #ifndef BOOST_CONTRACT_NO_PRECONDITIONS
120                 << "a::ctor::pre" << std::endl
121                 // Test no failure here.
122                 << "c::ctor::pre" << std::endl
123             #endif
124             << ok_after()
125         ;
126         BOOST_TEST(out.eq(ok.str()));
127     }
128 
129     a_pre = true;
130     b_pre = true;
131     c_pre = false;
132     try {
133         out.str("");
134         a aa;
135         #ifndef BOOST_CONTRACT_NO_PRECONDITIONS
136                 BOOST_TEST(false);
137             } catch(err const&) {
138         #endif
139         ok.str(""); ok
140             #ifndef BOOST_CONTRACT_NO_PRECONDITIONS
141                 << "a::ctor::pre" << std::endl
142                 << "c::ctor::pre" << std::endl // Test this failed.
143             #else
144                 << ok_after()
145             #endif
146         ;
147         BOOST_TEST(out.eq(ok.str()));
148     } catch(...) { BOOST_TEST(false); }
149 
150     a_pre = false;
151     b_pre = false;
152     c_pre = false;
153     try {
154         out.str("");
155         a aa;
156         #ifndef BOOST_CONTRACT_NO_PRECONDITIONS
157                 BOOST_TEST(false);
158             } catch(err const&) {
159         #endif
160         ok.str(""); ok
161             #ifndef BOOST_CONTRACT_NO_PRECONDITIONS
162                 << "a::ctor::pre" << std::endl // Test this failed (as all did).
163             #else
164                 << ok_after()
165             #endif
166         ;
167         BOOST_TEST(out.eq(ok.str()));
168     } catch(...) { BOOST_TEST(false); }
169 
170     return boost::report_errors();
171 }
172 
173