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 exit invariants. 8 9 #undef BOOST_CONTRACT_TEST_NO_A_INV 10 #define BOOST_CONTRACT_TEST_NO_B_INV 11 #undef 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()18std::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 << "c::inv" << std::endl // This can fail. 36 #endif 37 ; 38 return ok.str(); 39 } 40 ok_b()41std::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 // No failure here. 57 #endif 58 ; 59 return ok.str(); 60 } 61 ok_a()62std::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 << "a::inv" << std::endl // This can fail. 78 #endif 79 ; 80 return ok.str(); 81 } 82 ok_end()83std::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()94int 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 no failure. 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 #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS 122 BOOST_TEST(false); 123 } catch(err const&) { 124 #endif 125 ok.str(""); ok 126 << ok_c() 127 << ok_b() 128 << ok_a() // Test a::inv failed. 129 #ifdef BOOST_CONTRACT_NO_EXIT_INVARIANTS 130 << ok_end() 131 #endif 132 ; 133 BOOST_TEST(out.eq(ok.str())); 134 } catch(...) { BOOST_TEST(false); } 135 136 a_exit_inv = true; 137 b_exit_inv = false; 138 c_exit_inv = true; 139 try { 140 out.str(""); 141 a aa; 142 ok.str(""); ok 143 << ok_c() 144 << ok_b() // Test no b::inv so no failure. 145 << ok_a() 146 << ok_end() 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 #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS 158 BOOST_TEST(false); 159 } catch(err const&) { 160 #endif 161 ok.str(""); ok 162 << ok_c() // Test c::inv failed. 163 #ifdef BOOST_CONTRACT_NO_EXIT_INVARIANTS 164 << ok_b() 165 << ok_a() 166 << ok_end() 167 #endif 168 ; 169 BOOST_TEST(out.eq(ok.str())); 170 } catch(...) { BOOST_TEST(false); } 171 172 a_exit_inv = false; 173 b_exit_inv = false; 174 c_exit_inv = false; 175 try { 176 out.str(""); 177 a aa; 178 #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS 179 BOOST_TEST(false); 180 } catch(err const&) { 181 #endif 182 ok.str(""); ok 183 << ok_c() // Test c::inv failed. 184 #ifdef BOOST_CONTRACT_NO_EXIT_INVARIANTS 185 << ok_b() 186 << ok_a() 187 << ok_end() 188 #endif 189 ; 190 BOOST_TEST(out.eq(ok.str())); 191 } catch(...) { BOOST_TEST(false); } 192 193 return boost::report_errors(); 194 } 195 196