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