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 preconditions. 8 9 #undef BOOST_CONTRACT_TEST_NO_A_PRE 10 #define BOOST_CONTRACT_TEST_NO_B_PRE 11 #undef BOOST_CONTRACT_TEST_NO_C_PRE 12 #include "decl.hpp" 13 14 #include <boost/detail/lightweight_test.hpp> 15 #include <sstream> 16 #include <string> 17 ok_begin()18std::string ok_begin() { 19 std::ostringstream ok; ok << "" // Suppress a warning. 20 #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS 21 << "c::static_inv" << std::endl 22 << "c::inv" << std::endl 23 << "b::static_inv" << std::endl 24 << "b::inv" << std::endl 25 << "a::static_inv" << std::endl 26 << "a::inv" << std::endl 27 #endif 28 ; 29 return ok.str(); 30 } 31 ok_end()32std::string ok_end() { 33 std::ostringstream ok; ok 34 #ifndef BOOST_CONTRACT_NO_OLDS 35 << "c::f::old" << std::endl 36 << "b::f::old" << std::endl 37 << "a::f::old" << std::endl 38 #endif 39 << "a::f::body" << std::endl 40 #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS 41 << "c::static_inv" << std::endl 42 << "c::inv" << std::endl 43 << "b::static_inv" << std::endl 44 << "b::inv" << std::endl 45 << "a::static_inv" << std::endl 46 << "a::inv" << std::endl 47 #endif 48 #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS 49 << "c::f::old" << std::endl // Old only if post (or except) run. 50 << "c::f::post" << std::endl 51 << "b::f::old" << std::endl 52 << "b::f::post" << std::endl 53 << "a::f::post" << std::endl 54 #endif 55 ; 56 return ok.str(); 57 } 58 59 struct err {}; // Global decl so visible in MSVC10 lambdas. 60 main()61int main() { 62 std::ostringstream ok; 63 64 a aa; 65 66 a_pre = true; 67 b_pre = true; 68 c_pre = true; 69 out.str(""); 70 aa.f(); 71 ok.str(""); ok // Test nothing failed. 72 << ok_begin() 73 #ifndef BOOST_CONTRACT_NO_PRECONDITIONS 74 << "c::f::pre" << std::endl // Test only c pre checked. 75 #endif 76 << ok_end() 77 ; 78 BOOST_TEST(out.eq(ok.str())); 79 80 a_pre = true; 81 b_pre = false; 82 c_pre = false; 83 out.str(""); 84 aa.f(); 85 ok.str(""); ok 86 << ok_begin() 87 #ifndef BOOST_CONTRACT_NO_PRECONDITIONS 88 << "c::f::pre" << std::endl 89 // Test b's pre not checked. 90 << "a::f::pre" << std::endl 91 #endif 92 << ok_end() 93 ; 94 BOOST_TEST(out.eq(ok.str())); 95 96 a_pre = false; 97 b_pre = false; 98 c_pre = true; 99 out.str(""); 100 aa.f(); 101 ok.str(""); ok 102 << ok_begin() 103 #ifndef BOOST_CONTRACT_NO_PRECONDITIONS 104 << "c::f::pre" << std::endl // Test only c pre checked. 105 #endif 106 << ok_end() 107 ; 108 BOOST_TEST(out.eq(ok.str())); 109 110 boost::contract::set_precondition_failure( 111 [] (boost::contract::from) { throw err(); }); 112 113 a_pre = false; 114 b_pre = true; 115 c_pre = false; 116 out.str(""); 117 try { 118 aa.f(); 119 #ifndef BOOST_CONTRACT_NO_PRECONDITIONS 120 BOOST_TEST(false); 121 } catch(err const&) { 122 #endif 123 ok.str(""); ok 124 << ok_begin() 125 #ifndef BOOST_CONTRACT_NO_PRECONDITIONS 126 << "c::f::pre" << std::endl 127 << "a::f::pre" << std::endl // Only ends pre checked and failed. 128 #else 129 << ok_end() 130 #endif 131 ; 132 BOOST_TEST(out.eq(ok.str())); 133 } catch(...) { BOOST_TEST(false); } 134 135 a_pre = false; 136 b_pre = false; 137 c_pre = false; 138 out.str(""); 139 try { 140 aa.f(); 141 #ifndef BOOST_CONTRACT_NO_PRECONDITIONS 142 BOOST_TEST(false); 143 } catch(err const&) { 144 #endif 145 ok.str(""); ok 146 << ok_begin() 147 #ifndef BOOST_CONTRACT_NO_PRECONDITIONS 148 << "c::f::pre" << std::endl 149 << "a::f::pre" << std::endl // Only ends pre checked and failed. 150 #else 151 << ok_end() 152 #endif 153 ; 154 BOOST_TEST(out.eq(ok.str())); 155 } catch(...) { BOOST_TEST(false); } 156 157 return boost::report_errors(); 158 } 159 160