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()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 // No failure here. 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 << "b::inv" << std::endl // This can fail. 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 // No failure here. 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 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