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()18std::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)38std::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)56std::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()79int 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