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 all derived and base classes with entry invariants. 8 9 #undef BOOST_CONTRACT_TEST_NO_A_INV 10 #undef BOOST_CONTRACT_TEST_NO_B_INV 11 #undef BOOST_CONTRACT_TEST_NO_C_INV 12 #include "decl.hpp" 13 14 #include <boost/preprocessor/control/iif.hpp> 15 #include <boost/detail/lightweight_test.hpp> 16 #include <sstream> 17 #include <string> 18 ok_end()19 std::string ok_end() { 20 std::ostringstream ok; ok 21 #ifndef BOOST_CONTRACT_NO_PRECONDITIONS 22 << "c::f::pre" << std::endl 23 #endif 24 #ifndef BOOST_CONTRACT_NO_OLDS 25 << "c::f::old" << std::endl 26 << "b::f::old" << std::endl 27 << "a::f::old" << std::endl 28 #endif 29 << "a::f::body" << std::endl 30 #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS 31 << "c::static_inv" << std::endl 32 << "c::inv" << std::endl 33 << "b::static_inv" << std::endl 34 << "b::inv" << std::endl 35 << "a::static_inv" << std::endl 36 << "a::inv" << std::endl 37 #endif 38 #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS 39 << "c::f::old" << std::endl 40 << "c::f::post" << std::endl 41 << "b::f::old" << std::endl 42 << "b::f::post" << std::endl 43 << "a::f::post" << std::endl 44 #endif 45 ; 46 return ok.str(); 47 } 48 49 struct err {}; // Global decl so visible in MSVC10 lambdas. 50 main()51 int main() { 52 std::ostringstream ok; 53 54 #ifdef BOOST_CONTRACT_NO_ENTRY_INVARIANTS 55 #define BOOST_CONTRACT_TEST_entry_inv 0 56 #else 57 #define BOOST_CONTRACT_TEST_entry_inv 1 58 #endif 59 60 a aa; 61 62 a_entry_inv = true; 63 b_entry_inv = true; 64 c_entry_inv = true; 65 a_entering_inv = b_entering_inv = c_entering_inv = 66 BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); 67 out.str(""); 68 aa.f(); 69 ok.str(""); ok // Test nothing failed. 70 #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS 71 << "c::static_inv" << std::endl 72 << "c::inv" << std::endl 73 << "b::static_inv" << std::endl 74 << "b::inv" << std::endl 75 << "a::static_inv" << std::endl 76 << "a::inv" << std::endl 77 #endif 78 << ok_end() 79 ; 80 BOOST_TEST(out.eq(ok.str())); 81 82 boost::contract::set_entry_invariant_failure( 83 [] (boost::contract::from) { throw err(); }); 84 85 a_entry_inv = false; 86 b_entry_inv = true; 87 c_entry_inv = true; 88 a_entering_inv = b_entering_inv = c_entering_inv = 89 BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); 90 out.str(""); 91 try { 92 aa.f(); 93 #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS 94 BOOST_TEST(false); 95 } catch(err const&) { 96 #endif 97 ok.str(""); ok 98 #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS 99 << "c::static_inv" << std::endl 100 << "c::inv" << std::endl 101 << "b::static_inv" << std::endl 102 << "b::inv" << std::endl 103 << "a::static_inv" << std::endl 104 << "a::inv" << std::endl // Test this failed. 105 #else 106 << ok_end() 107 #endif 108 ; 109 BOOST_TEST(out.eq(ok.str())); 110 } catch(...) { BOOST_TEST(false); } 111 112 a_entry_inv = true; 113 b_entry_inv = false; 114 c_entry_inv = true; 115 a_entering_inv = b_entering_inv = c_entering_inv = 116 BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); 117 out.str(""); 118 try { 119 aa.f(); 120 #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS 121 BOOST_TEST(false); 122 } catch(err const&) { 123 #endif 124 ok.str(""); ok 125 #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS 126 << "c::static_inv" << std::endl 127 << "c::inv" << std::endl 128 << "b::static_inv" << std::endl 129 << "b::inv" << std::endl // Test this failed. 130 #else 131 << ok_end() 132 #endif 133 ; 134 BOOST_TEST(out.eq(ok.str())); 135 } catch(...) { BOOST_TEST(false); } 136 137 a_entry_inv = true; 138 b_entry_inv = true; 139 c_entry_inv = false; 140 a_entering_inv = b_entering_inv = c_entering_inv = 141 BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); 142 out.str(""); 143 try { 144 aa.f(); 145 #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS 146 BOOST_TEST(false); 147 } catch(err const&) { 148 #endif 149 ok.str(""); ok 150 #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS 151 << "c::static_inv" << std::endl 152 << "c::inv" << std::endl // Test this failed. 153 #else 154 << ok_end() 155 #endif 156 ; 157 BOOST_TEST(out.eq(ok.str())); 158 } catch(...) { BOOST_TEST(false); } 159 160 a_entry_inv = false; 161 b_entry_inv = false; 162 c_entry_inv = false; 163 a_entering_inv = b_entering_inv = c_entering_inv = 164 BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); 165 out.str(""); 166 try { 167 aa.f(); 168 #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS 169 BOOST_TEST(false); 170 } catch(err const&) { 171 #endif 172 ok.str(""); ok 173 #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS 174 << "c::static_inv" << std::endl 175 << "c::inv" << std::endl // Test this failed (as all did). 176 #else 177 << ok_end() 178 #endif 179 ; 180 BOOST_TEST(out.eq(ok.str())); 181 } catch(...) { BOOST_TEST(false); } 182 183 return boost::report_errors(); 184 } 185 186