| 1 | //  (C) Copyright Gennadiy Rozental 2005. | 
|---|
| 2 | //  Distributed under the Boost Software License, Version 1.0. | 
|---|
| 3 | //  (See accompanying file LICENSE_1_0.txt or copy at | 
|---|
| 4 | //  http://www.boost.org/LICENSE_1_0.txt) | 
|---|
| 5 |  | 
|---|
| 6 | //  See http://www.boost.org/libs/test for the library home page. | 
|---|
| 7 | // | 
|---|
| 8 | //  File        : $RCSfile: mock_object.hpp,v $ | 
|---|
| 9 | // | 
|---|
| 10 | //  Version     : $Revision: 1.3 $ | 
|---|
| 11 | // | 
|---|
| 12 | //  Description : Facilities to perform exception safety_tests | 
|---|
| 13 | // *************************************************************************** | 
|---|
| 14 |  | 
|---|
| 15 | #ifndef BOOST_TEST_MOCK_OBJECT_HPP_112205GER | 
|---|
| 16 | #define BOOST_TEST_MOCK_OBJECT_HPP_112205GER | 
|---|
| 17 |  | 
|---|
| 18 | // Boost.Test | 
|---|
| 19 | #include <boost/test/detail/config.hpp> | 
|---|
| 20 | #include <boost/test/interaction_based.hpp> | 
|---|
| 21 |  | 
|---|
| 22 | // Boost | 
|---|
| 23 | #include <boost/preprocessor/punctuation/comma.hpp> | 
|---|
| 24 |  | 
|---|
| 25 | #include <boost/test/detail/suppress_warnings.hpp> | 
|---|
| 26 |  | 
|---|
| 27 | //____________________________________________________________________________// | 
|---|
| 28 |  | 
|---|
| 29 | namespace boost { | 
|---|
| 30 |  | 
|---|
| 31 | namespace itest { | 
|---|
| 32 |  | 
|---|
| 33 | // ************************************************************************** // | 
|---|
| 34 | // **************                mock_object_base              ************** // | 
|---|
| 35 | // ************************************************************************** // | 
|---|
| 36 |  | 
|---|
| 37 | class mock_object_base { | 
|---|
| 38 | public: | 
|---|
| 39 |     mock_object_base() {} | 
|---|
| 40 |  | 
|---|
| 41 |     template<typename T1> | 
|---|
| 42 |     mock_object_base( T1 const& ) {} | 
|---|
| 43 |  | 
|---|
| 44 |     template<typename T1, typename T2> | 
|---|
| 45 |     mock_object_base( T1 const&, T2 const& ) {} | 
|---|
| 46 |  | 
|---|
| 47 |     template<typename T1, typename T2, typename T3> | 
|---|
| 48 |     mock_object_base( T1 const&, T2 const&, T3 const& ) {} | 
|---|
| 49 |  | 
|---|
| 50 |     template<typename T1, typename T2, typename T3, typename T4> | 
|---|
| 51 |     mock_object_base( T1 const&, T2 const&, T3 const&, T4 const& ) {} | 
|---|
| 52 |  | 
|---|
| 53 |     template<typename T1, typename T2, typename T3, typename T4, typename T5> | 
|---|
| 54 |     mock_object_base( T1 const&, T2 const&, T3 const&, T4 const&, T5 const& ) {} | 
|---|
| 55 | }; | 
|---|
| 56 |  | 
|---|
| 57 | // ************************************************************************** // | 
|---|
| 58 | // **************      mock_object implementation helpers      ************** // | 
|---|
| 59 | // ************************************************************************** // | 
|---|
| 60 |  | 
|---|
| 61 | #define MO_OP_IMPL( op, descr, ret )                        \ | 
|---|
| 62 |     BOOST_ITEST_SCOPE( mock_object::operator op );          \ | 
|---|
| 63 |     BOOST_ITEST_EPOINT( descr );                            \ | 
|---|
| 64 |     return ret                                              \ | 
|---|
| 65 | /**/ | 
|---|
| 66 |  | 
|---|
| 67 | #define MO_UNARY_OP( op, descr )                            \ | 
|---|
| 68 | self_type const& operator op() const                        \ | 
|---|
| 69 | {                                                           \ | 
|---|
| 70 |     MO_OP_IMPL( op, descr, prototype() );                   \ | 
|---|
| 71 | }                                                           \ | 
|---|
| 72 | /**/ | 
|---|
| 73 |  | 
|---|
| 74 | #define MO_UNARY_BOOL_OP( op, descr )                       \ | 
|---|
| 75 | bool operator op() const                                    \ | 
|---|
| 76 | {                                                           \ | 
|---|
| 77 |     MO_OP_IMPL( op, descr, (!!BOOST_ITEST_DPOINT()) );      \ | 
|---|
| 78 | }                                                           \ | 
|---|
| 79 | /**/ | 
|---|
| 80 |  | 
|---|
| 81 | #define MO_BINARY_OP( op, descr )                           \ | 
|---|
| 82 | template<int i1, typename Base1,int i2, typename Base2>     \ | 
|---|
| 83 | inline mock_object<i1,Base1> const&                         \ | 
|---|
| 84 | operator op( mock_object<i1,Base1> const& mo,               \ | 
|---|
| 85 |              mock_object<i2,Base2> const& )                 \ | 
|---|
| 86 | {                                                           \ | 
|---|
| 87 |     MO_OP_IMPL( op, descr, mo );                            \ | 
|---|
| 88 | }                                                           \ | 
|---|
| 89 |                                                             \ | 
|---|
| 90 | template<int i, typename Base, typename T>                  \ | 
|---|
| 91 | inline mock_object<i,Base> const&                           \ | 
|---|
| 92 | operator op( mock_object<i,Base> const& mo, T const& )      \ | 
|---|
| 93 | {                                                           \ | 
|---|
| 94 |     MO_OP_IMPL( op, descr, mo );                            \ | 
|---|
| 95 | }                                                           \ | 
|---|
| 96 |                                                             \ | 
|---|
| 97 | template<int i, typename Base, typename T>                  \ | 
|---|
| 98 | inline mock_object<i,Base> const&                           \ | 
|---|
| 99 | operator op( T const&, mock_object<i,Base> const& mo )      \ | 
|---|
| 100 | {                                                           \ | 
|---|
| 101 |     MO_OP_IMPL( op, descr, mo );                            \ | 
|---|
| 102 | }                                                           \ | 
|---|
| 103 | /**/ | 
|---|
| 104 |  | 
|---|
| 105 | #define MO_BINARY_BOOL_OP( op, descr )                      \ | 
|---|
| 106 | template<int i1, typename Base1,int i2, typename Base2>     \ | 
|---|
| 107 | inline bool                                                 \ | 
|---|
| 108 | operator op( mock_object<i1,Base1> const&,                  \ | 
|---|
| 109 |              mock_object<i2,Base2> const& )                 \ | 
|---|
| 110 | {                                                           \ | 
|---|
| 111 |     MO_OP_IMPL( op, descr, BOOST_ITEST_DPOINT() );          \ | 
|---|
| 112 | }                                                           \ | 
|---|
| 113 |                                                             \ | 
|---|
| 114 | template<int i, typename Base, typename T>                  \ | 
|---|
| 115 | inline bool                                                 \ | 
|---|
| 116 | operator op( mock_object<i,Base> const&, T const& )         \ | 
|---|
| 117 | {                                                           \ | 
|---|
| 118 |     MO_OP_IMPL( op, descr, BOOST_ITEST_DPOINT() );          \ | 
|---|
| 119 | }                                                           \ | 
|---|
| 120 |                                                             \ | 
|---|
| 121 | template<int i, typename Base, typename T>                  \ | 
|---|
| 122 | inline bool                                                 \ | 
|---|
| 123 | operator op( T const&, mock_object<i,Base> const& )         \ | 
|---|
| 124 | {                                                           \ | 
|---|
| 125 |     MO_OP_IMPL( op, descr, BOOST_ITEST_DPOINT() );          \ | 
|---|
| 126 | }                                                           \ | 
|---|
| 127 | /**/ | 
|---|
| 128 |  | 
|---|
| 129 | // ************************************************************************** // | 
|---|
| 130 | // **************                  mock_object                 ************** // | 
|---|
| 131 | // ************************************************************************** // | 
|---|
| 132 |  | 
|---|
| 133 | template<int i = 0, typename Base=mock_object_base> | 
|---|
| 134 | class mock_object; | 
|---|
| 135 |  | 
|---|
| 136 | template<int i, typename Base> | 
|---|
| 137 | class mock_object : public Base { | 
|---|
| 138 |     // Private typeefs | 
|---|
| 139 |     typedef mock_object<i,Base> self_type; | 
|---|
| 140 |     struct dummy { void nonnull() {}; }; | 
|---|
| 141 |     typedef void (dummy::*safe_bool)(); | 
|---|
| 142 |  | 
|---|
| 143 |     // prototype constructor | 
|---|
| 144 |     mock_object( dummy* ) {} | 
|---|
| 145 |  | 
|---|
| 146 | public: | 
|---|
| 147 |     static mock_object& prototype() | 
|---|
| 148 |     { | 
|---|
| 149 |         static mock_object p( (dummy*)0 );  | 
|---|
| 150 |         return p; | 
|---|
| 151 |     } | 
|---|
| 152 |  | 
|---|
| 153 |     // Constructors | 
|---|
| 154 |     mock_object() | 
|---|
| 155 |     { | 
|---|
| 156 |         BOOST_ITEST_SCOPE( mock_object::mock_object ); | 
|---|
| 157 |         BOOST_ITEST_EPOINT( "Mock object default constructor" ); | 
|---|
| 158 |     } | 
|---|
| 159 |  | 
|---|
| 160 |     template<typename T1> | 
|---|
| 161 |     mock_object( T1 const& arg1 ) | 
|---|
| 162 |     : mock_object_base( arg1 ) | 
|---|
| 163 |     { | 
|---|
| 164 |         BOOST_ITEST_SCOPE( mock_object::mock_object ); | 
|---|
| 165 |         BOOST_ITEST_EPOINT( "Mock object constructor" ); | 
|---|
| 166 |     } | 
|---|
| 167 |  | 
|---|
| 168 |     template<typename T1, typename T2> | 
|---|
| 169 |     mock_object( T1 const& arg1, T2 const& arg2 ) | 
|---|
| 170 |     : mock_object_base( arg1, arg2 ) | 
|---|
| 171 |     { | 
|---|
| 172 |         BOOST_ITEST_SCOPE( mock_object::mock_object ); | 
|---|
| 173 |         BOOST_ITEST_EPOINT( "Mock object constructor" ); | 
|---|
| 174 |     } | 
|---|
| 175 |  | 
|---|
| 176 |     template<typename T1, typename T2, typename T3> | 
|---|
| 177 |     mock_object( T1 const& arg1, T2 const& arg2, T3 const& arg3 ) | 
|---|
| 178 |     : mock_object_base( arg1, arg2, arg3 ) | 
|---|
| 179 |     { | 
|---|
| 180 |         BOOST_ITEST_SCOPE( mock_object::mock_object ); | 
|---|
| 181 |         BOOST_ITEST_EPOINT( "Mock object constructor" ); | 
|---|
| 182 |     } | 
|---|
| 183 |  | 
|---|
| 184 |     template<typename T1, typename T2, typename T3, typename T4> | 
|---|
| 185 |     mock_object( T1 const& arg1, T2 const& arg2, T3 const& arg3, T4 const& arg4 ) | 
|---|
| 186 |     : mock_object_base( arg1, arg2, arg3, arg4 ) | 
|---|
| 187 |     { | 
|---|
| 188 |         BOOST_ITEST_SCOPE( mock_object::mock_object ); | 
|---|
| 189 |         BOOST_ITEST_EPOINT( "Mock object constructor" ); | 
|---|
| 190 |     } | 
|---|
| 191 |  | 
|---|
| 192 |     template<typename T1, typename T2, typename T3, typename T4, typename T5> | 
|---|
| 193 |     mock_object( T1 const& arg1, T2 const& arg2, T3 const& arg3, T4 const& arg4, T5 const& arg5 ) | 
|---|
| 194 |     : mock_object_base( arg1, arg2, arg3, arg4, arg5 ) | 
|---|
| 195 |     { | 
|---|
| 196 |         BOOST_ITEST_SCOPE( mock_object::mock_object ); | 
|---|
| 197 |         BOOST_ITEST_EPOINT( "Mock object constructor" ); | 
|---|
| 198 |     } | 
|---|
| 199 |  | 
|---|
| 200 |     mock_object( mock_object const& ) | 
|---|
| 201 |     { | 
|---|
| 202 |         BOOST_ITEST_SCOPE( mock_object::mock_object ); | 
|---|
| 203 |         BOOST_ITEST_EPOINT( "Mock object copy constructor" ); | 
|---|
| 204 |     } | 
|---|
| 205 |  | 
|---|
| 206 |     // assignment | 
|---|
| 207 |     self_type const&    operator =( mock_object const& ) const | 
|---|
| 208 |     { | 
|---|
| 209 |         MO_OP_IMPL( =, "Copy assignment", prototype() ); | 
|---|
| 210 |     } | 
|---|
| 211 |  | 
|---|
| 212 |     template <typename T> | 
|---|
| 213 |     self_type const&    operator =( T const& ) const | 
|---|
| 214 |     { | 
|---|
| 215 |         MO_OP_IMPL( =, "Copy assignment", prototype() ); | 
|---|
| 216 |     } | 
|---|
| 217 |  | 
|---|
| 218 |     // Unary operators | 
|---|
| 219 |     MO_UNARY_BOOL_OP( !, "Logical NOT operator" ) | 
|---|
| 220 |     MO_UNARY_OP( &, "Address-of operator" ) | 
|---|
| 221 |     MO_UNARY_OP( ~, "One's complement operator" ) | 
|---|
| 222 |     MO_UNARY_OP( *, "Pointer dereference" ) | 
|---|
| 223 |     MO_UNARY_OP( +, "Unary plus" ) | 
|---|
| 224 |  | 
|---|
| 225 |     // Increment and Decrement | 
|---|
| 226 |     MO_UNARY_OP( ++, "Prefix increment" ) | 
|---|
| 227 |     MO_UNARY_OP( --, "Prefix decrement" ) | 
|---|
| 228 |     self_type const&    operator ++(int) const | 
|---|
| 229 |     { | 
|---|
| 230 |         MO_OP_IMPL( ++, "Postfix increment", prototype() ); | 
|---|
| 231 |     } | 
|---|
| 232 |     self_type const&    operator --(int) const | 
|---|
| 233 |     { | 
|---|
| 234 |         MO_OP_IMPL( --, "Postfix decrement", prototype() ); | 
|---|
| 235 |     } | 
|---|
| 236 |  | 
|---|
| 237 |     // Bool context convertion | 
|---|
| 238 |     operator safe_bool() const | 
|---|
| 239 |     { | 
|---|
| 240 |         MO_OP_IMPL( safe_bool, "Bool context conversion", | 
|---|
| 241 |                     (BOOST_ITEST_DPOINT() ? 0 : &dummy::nonnull) ); | 
|---|
| 242 |     } | 
|---|
| 243 |  | 
|---|
| 244 |     // Function-call operators | 
|---|
| 245 |     self_type const&    operator ()() const | 
|---|
| 246 |     { | 
|---|
| 247 |         MO_OP_IMPL( (), "0-arity function-call", prototype() ); | 
|---|
| 248 |     } | 
|---|
| 249 |     template<typename T1> | 
|---|
| 250 |     self_type const&    operator ()( T1 const& arg1 ) const | 
|---|
| 251 |     { | 
|---|
| 252 |         MO_OP_IMPL( (), "1-arity function-call", prototype() ); | 
|---|
| 253 |     } | 
|---|
| 254 |     template<typename T1, typename T2> | 
|---|
| 255 |     self_type const&    operator ()( T1 const&, T2 const& ) const | 
|---|
| 256 |     { | 
|---|
| 257 |         MO_OP_IMPL( (), "2-arity function-call", prototype() ); | 
|---|
| 258 |     } | 
|---|
| 259 |     template<typename T1, typename T2, typename T3> | 
|---|
| 260 |     self_type const&    operator ()( T1 const&, T2 const&, T3 const& ) const | 
|---|
| 261 |     { | 
|---|
| 262 |         MO_OP_IMPL( (), "3-arity function-call", prototype() ); | 
|---|
| 263 |     } | 
|---|
| 264 |     template<typename T1, typename T2, typename T3, typename T4> | 
|---|
| 265 |     self_type const&    operator ()( T1 const&, T2 const&, T3 const&, T4 const& ) const | 
|---|
| 266 |     { | 
|---|
| 267 |         MO_OP_IMPL( (), "4-arity function-call", prototype() ); | 
|---|
| 268 |     } | 
|---|
| 269 |     template<typename T1, typename T2, typename T3, typename T4, typename T5> | 
|---|
| 270 |     self_type const&    operator ()( T1 const&, T2 const&, T3 const&, T4 const&, T5 const& ) const | 
|---|
| 271 |     { | 
|---|
| 272 |         MO_OP_IMPL( (), "5-arity function-call", prototype() ); | 
|---|
| 273 |     } | 
|---|
| 274 |  | 
|---|
| 275 |     // Substripting | 
|---|
| 276 |     template<typename T> | 
|---|
| 277 |     self_type const&    operator []( T const& ) const | 
|---|
| 278 |     { | 
|---|
| 279 |         MO_OP_IMPL( [], "Substripting", prototype() ); | 
|---|
| 280 |     } | 
|---|
| 281 |  | 
|---|
| 282 |     // Class member access | 
|---|
| 283 |     self_type const*    operator->() const | 
|---|
| 284 |     { | 
|---|
| 285 |         MO_OP_IMPL( ->, "Class member access", this ); | 
|---|
| 286 |     } | 
|---|
| 287 | }; | 
|---|
| 288 |  | 
|---|
| 289 | // !! MO_BINARY_OP( BOOST_PP_COMMA(), "Comma operator" ) | 
|---|
| 290 |  | 
|---|
| 291 | MO_BINARY_BOOL_OP( !=, "Inequality" ) | 
|---|
| 292 | MO_BINARY_OP( %, "Modulus" ) | 
|---|
| 293 | MO_BINARY_OP( %=, "Modulus/assignment" ) | 
|---|
| 294 | MO_BINARY_OP( &, "Bitwise AND" ) | 
|---|
| 295 | MO_BINARY_BOOL_OP( &&, "Logical AND" ) | 
|---|
| 296 | MO_BINARY_OP( &=, "Bitwise AND/assignment" ) | 
|---|
| 297 | MO_BINARY_OP( *, "Multiplication" ) | 
|---|
| 298 | MO_BINARY_OP( *=, "Multiplication/assignment" ) | 
|---|
| 299 | MO_BINARY_OP( +, "Addition" ) | 
|---|
| 300 | MO_BINARY_OP( +=, "Addition/assignment" ) | 
|---|
| 301 | //MO_BINARY_OP( -, "Subtraction" ) | 
|---|
| 302 | MO_BINARY_OP( -=, "Subtraction/assignment" ) | 
|---|
| 303 | MO_BINARY_OP( ->*, "Pointer-to-member selection" ) | 
|---|
| 304 | MO_BINARY_OP( /, "Division" ) | 
|---|
| 305 | MO_BINARY_OP( /=, "Division/assignment" ) | 
|---|
| 306 | MO_BINARY_BOOL_OP( <, "Less than" ) | 
|---|
| 307 | MO_BINARY_OP( <<=, "Left shift/assignment" ) | 
|---|
| 308 | MO_BINARY_BOOL_OP( <=, "Less than or equal to" ) | 
|---|
| 309 | MO_BINARY_BOOL_OP( ==, "Equality" ) | 
|---|
| 310 | MO_BINARY_BOOL_OP( >, "Greater than" ) | 
|---|
| 311 | MO_BINARY_BOOL_OP( >=, "Greater than or equal to" ) | 
|---|
| 312 | MO_BINARY_OP( >>=, "Right shift/assignment" ) | 
|---|
| 313 | MO_BINARY_OP( ^, "Exclusive OR" ) | 
|---|
| 314 | MO_BINARY_OP( ^=, "Exclusive OR/assignment" ) | 
|---|
| 315 | MO_BINARY_OP( |, "Bitwise inclusive OR" ) | 
|---|
| 316 | MO_BINARY_OP( |=, "Bitwise inclusive OR/assignment" ) | 
|---|
| 317 | MO_BINARY_BOOL_OP( ||, "Logical OR" ) | 
|---|
| 318 |  | 
|---|
| 319 | MO_BINARY_OP( <<, "Left shift" ) | 
|---|
| 320 | MO_BINARY_OP( >>, "Right shift" ) | 
|---|
| 321 |  | 
|---|
| 322 | } // namespace itest | 
|---|
| 323 |  | 
|---|
| 324 | } // namespace boost | 
|---|
| 325 |  | 
|---|
| 326 | #include <boost/test/detail/enable_warnings.hpp> | 
|---|
| 327 |  | 
|---|
| 328 | // *************************************************************************** | 
|---|
| 329 | //  Revision History : | 
|---|
| 330 | // | 
|---|
| 331 | //  $Log: mock_object.hpp,v $ | 
|---|
| 332 | //  Revision 1.3  2006/03/19 07:27:52  rogeeff | 
|---|
| 333 | //  streamline test setup error message | 
|---|
| 334 | // | 
|---|
| 335 | //  Revision 1.2  2006/01/15 11:14:39  rogeeff | 
|---|
| 336 | //  simpl_mock -> mock_object<>::prototype() | 
|---|
| 337 | //  operator new need to be rethinked | 
|---|
| 338 | // | 
|---|
| 339 | //  Revision 1.1  2005/12/14 05:09:21  rogeeff | 
|---|
| 340 | //  interraction based testing is introdused | 
|---|
| 341 | // | 
|---|
| 342 | // *************************************************************************** | 
|---|
| 343 |  | 
|---|
| 344 | #endif // BOOST_TEST_MOCK_OBJECT_HPP_112205GER | 
|---|