• 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 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/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             // No failure here.
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             << "b::inv" << std::endl // This can fail.
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             // No failure here.
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 nothing failed.
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         ok.str(""); ok
122             << ok_c()
123             << ok_b()
124             << ok_a() // Test no failure here.
125             << ok_end()
126         ;
127         BOOST_TEST(out.eq(ok.str()));
128     } catch(...) { BOOST_TEST(false); }
129 
130     a_exit_inv = true;
131     b_exit_inv = false;
132     c_exit_inv = true;
133     try {
134         out.str("");
135         a aa;
136         #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS
137                 BOOST_TEST(false);
138             } catch(err const&) {
139         #endif
140         ok.str(""); ok
141             << ok_c()
142             << ok_b() // Test b::inv failed.
143             #ifdef BOOST_CONTRACT_NO_EXIT_INVARIANTS
144                 << ok_a()
145                 << ok_end()
146             #endif
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         ok.str(""); ok
158             << ok_c() // Test no failure here.
159             << ok_b()
160             << ok_a()
161             << ok_end()
162         ;
163         BOOST_TEST(out.eq(ok.str()));
164     } catch(...) { BOOST_TEST(false); }
165 
166     a_exit_inv = false;
167     b_exit_inv = false;
168     c_exit_inv = false;
169     try {
170         out.str("");
171         a aa;
172         #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS
173                 BOOST_TEST(false);
174             } catch(err const&) {
175         #endif
176         ok.str(""); ok
177             << ok_c()
178             << ok_b() // Test b::inv failed.
179             #ifdef BOOST_CONTRACT_NO_EXIT_INVARIANTS
180                 << ok_a()
181                 << ok_end()
182             #endif
183         ;
184         BOOST_TEST(out.eq(ok.str()));
185     } catch(...) { BOOST_TEST(false); }
186 
187     return boost::report_errors();
188 }
189 
190