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 #include "lib_a.hpp"
8 #include "lib_b.hpp"
9 #include "../detail/oteststream.hpp"
10 #include <boost/contract/core/exception.hpp>
11 #include <boost/contract/core/config.hpp>
12 #include <boost/detail/lightweight_test.hpp>
13 #include <sstream>
14 #include <string>
15
ok_f()16 std::string ok_f() {
17 std::ostringstream ok; ok
18 #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS
19 << "a::static_inv" << std::endl
20 << "a::inv" << std::endl
21 #endif
22 #ifndef BOOST_CONTRACT_NO_PRECONDITIONS
23 << "a::f::pre" << std::endl
24 #endif
25 #ifndef BOOST_CONTRACT_NO_OLDS
26 << "a::f::old" << std::endl
27 #endif
28 << "a::f::body" << std::endl
29 #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS
30 << "a::static_inv" << std::endl
31 << "a::inv" << std::endl
32 #endif
33 #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
34 << "a::f::post" << std::endl
35 #endif
36 ;
37 return ok.str();
38 }
39
main()40 int main() {
41 using boost::contract::test::detail::out;
42 std::ostringstream ok;
43 b bb;
44
45 out("");
46 bb.g();
47 ok.str(""); ok
48 #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS
49 << "b::static_inv" << std::endl
50 << "b::inv" << std::endl
51 #endif
52 #ifndef BOOST_CONTRACT_NO_PRECONDITIONS
53 << "b::g::pre" << std::endl
54 #ifdef BOOST_CONTRACT_PRECONDITIONS_DISABLE_NO_ASSERTION
55 // Test preconditions have disabled no contract.
56 << ok_f()
57 #else
58 // Test call while checking executes body (but no contracts).
59 << "a::f::body" << std::endl
60 #endif
61 #endif
62 #ifndef BOOST_CONTRACT_NO_OLDS
63 << "b::g::old" << std::endl
64 #endif
65 << "b::g::body" << std::endl
66 #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS
67 << "b::static_inv" << std::endl
68 << "b::inv" << std::endl
69 #endif
70 #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
71 << "b::g::post" << std::endl
72 // Test call while checking executes body (but no contracts).
73 << "a::f::body" << std::endl
74 #endif
75 ;
76 BOOST_TEST(boost::contract::test::detail::oteststream::eq(out(), ok.str()));
77
78 // Test old values not copied for disabled contracts.
79
80 #if defined(BOOST_CONTRACT_PRECONDITIONS_DISABLE_NO_ASSERTION) && \
81 !defined(BOOST_CONTRACT_NO_PRECONDITIONS) && \
82 !defined(BOOST_CONTRACT_NO_OLDS)
83 #define BOOST_CONTRACT_TEST_old 1u
84 #else
85 #define BOOST_CONTRACT_TEST_old 0u
86 #endif
87
88 BOOST_TEST_EQ(a::x_type::copies(), BOOST_CONTRACT_TEST_old);
89 BOOST_TEST_EQ(a::x_type::evals(), BOOST_CONTRACT_TEST_old);
90 BOOST_TEST_EQ(a::x_type::ctors(), a::x_type::dtors());
91
92 // Double check a call to f outside another contract checks f's contracts.
93
94 out("");
95 call_f();
96 BOOST_TEST(boost::contract::test::detail::oteststream::eq(out(), ok_f()));
97
98 // Test setting failure handlers (from this program using a lib).
99
100 a::disable_pre_failure();
101 out("");
102 boost::contract::precondition_failure(boost::contract::from());
103 BOOST_TEST(boost::contract::test::detail::oteststream::eq(out(),
104 "a::pre_failure\n"));
105
106 a::disable_post_failure();
107 out("");
108 boost::contract::postcondition_failure(boost::contract::from());
109 BOOST_TEST(boost::contract::test::detail::oteststream::eq(out(),
110 "a::post_failure\n"));
111
112 a::disable_entry_inv_failure();
113 out("");
114 boost::contract::entry_invariant_failure(boost::contract::from());
115 BOOST_TEST(boost::contract::test::detail::oteststream::eq(out(),
116 "a::entry_inv_failure\n"));
117
118 a::disable_exit_inv_failure();
119 out("");
120 boost::contract::exit_invariant_failure(boost::contract::from());
121 BOOST_TEST(boost::contract::test::detail::oteststream::eq(out(),
122 "a::exit_inv_failure\n"));
123
124 a::disable_inv_failure();
125 out("");
126 boost::contract::entry_invariant_failure(boost::contract::from());
127 BOOST_TEST(boost::contract::test::detail::oteststream::eq(out(),
128 "a::inv_failure\n"));
129 out("");
130 boost::contract::exit_invariant_failure(boost::contract::from());
131 BOOST_TEST(boost::contract::test::detail::oteststream::eq(out(),
132 "a::inv_failure\n"));
133
134 a::disable_failure();
135 out("");
136 boost::contract::precondition_failure(boost::contract::from());
137 BOOST_TEST(boost::contract::test::detail::oteststream::eq(out(),
138 "a::failure\n"));
139 out("");
140 boost::contract::postcondition_failure(boost::contract::from());
141 BOOST_TEST(boost::contract::test::detail::oteststream::eq(out(),
142 "a::failure\n"));
143 out("");
144 boost::contract::entry_invariant_failure(boost::contract::from());
145 BOOST_TEST(boost::contract::test::detail::oteststream::eq(out(),
146 "a::failure\n"));
147 out("");
148 boost::contract::exit_invariant_failure(boost::contract::from());
149 BOOST_TEST(boost::contract::test::detail::oteststream::eq(out(),
150 "a::failure\n"));
151
152 // Test setting failure handlers (from a lib using another lib).
153
154 BOOST_TEST(b::test_disable_pre_failure());
155 BOOST_TEST(b::test_disable_post_failure());
156 BOOST_TEST(b::test_disable_entry_inv_failure());
157 BOOST_TEST(b::test_disable_exit_inv_failure());
158 BOOST_TEST(b::test_disable_inv_failure());
159 BOOST_TEST(b::test_disable_failure());
160
161 #undef BOOST_CONTRACT_TEST_old
162 return boost::report_errors();
163 }
164
165