00001
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #ifndef MOCKPP_INVOCATIONMOCKER_H
00036 #define MOCKPP_INVOCATIONMOCKER_H
00037
00038
00039 #include <mockpp/mockpp.h>
00040
00041 #include MOCKPP_VECTOR_H
00042
00043 #include <mockpp/chaining/StubMatchersCollection.h>
00044 #include <mockpp/chaining/Invokable.h>
00045 #include <mockpp/chaining/InvocationMocker.h>
00046
00047 #include <mockpp/matcher/ArgumentsMatcher.h>
00048
00049 #include <mockpp/compat/AssertionFailedError.h>
00050
00051 #include <mockpp/stub/DefaultResultStub.h>
00052 #include <mockpp/stub/VoidStub.h>
00053 #include <mockpp/stub/StubHolder.h>
00054
00055
00056 MOCKPP_NS_START
00057
00061 template <typename R,
00062 typename I>
00063 class InvocationMockerBase : public Invokable<R, I>,
00064 public StubMatchersCollection<R, I>
00065 {
00066 public:
00067
00068 class DescriberBase;
00069
00070 protected:
00071
00076 InvocationMockerBase( AutoPointer<DescriberBase> in_describer,
00077 const StubHolder<R, I> &defaultStub)
00078 : stub(defaultStub)
00079 , describer(in_describer)
00080 {
00081 }
00082
00083 public:
00084
00085 #ifdef MOCKPP_NO_TYPENAME_FOR_STL_NS
00086 typedef MOCKPP_STL::vector<InvocationMatcher<I>*> List;
00087 #else
00088 typedef typename MOCKPP_STL::vector<InvocationMatcher<I>*> List;
00089 #endif
00090 typedef typename List::iterator Iterator;
00091 typedef typename List::const_iterator ConstIterator;
00092
00095 virtual ~InvocationMockerBase()
00096 {
00097 reset();
00098 }
00099
00102 virtual void reset()
00103 {
00104 for ( Iterator it = matchers.begin(); it != matchers.end(); ++it )
00105 delete (*it);
00106 matchers.clear();
00107 }
00108
00113 virtual bool matches( const I &invocation )
00114 {
00115 for ( Iterator it = matchers.begin(); it != matchers.end(); ++it )
00116 {
00117 if ( !( *it ) ->matches( invocation ) )
00118 return false;
00119 }
00120 return true;
00121 }
00122
00126 virtual void verify()
00127 {
00128 MOCKPP_TRY
00129 {
00130 for ( ConstIterator it = matchers.begin(); it != matchers.end(); ++it )
00131 ( *it ) ->verify();
00132 }
00133
00134 #ifndef MOCKPP_NO_EXCEPTIONS
00135 catch ( const AssertionFailedError & error )
00136 {
00137 assertionFailed( __LINE__, __FILE__,
00138 error.getMessage() + MOCKPP_PCHAR( "\n" ) + this->toString() );
00139 }
00140 #endif // MOCKPP_NO_EXCEPTIONS
00141 }
00142
00145 virtual void setName( const String &in_name )
00146 {
00147 name = in_name;
00148 }
00149
00154 virtual void addMatcher( const MatcherHolder<I> &holder )
00155 {
00156 typename InvocationMatcher<I>::AP matcher = holder;
00157 matchers.push_back( matcher.release() );
00158 }
00159
00163 virtual void setStub( const StubHolder<R, I> &in_stub )
00164 {
00165 stub = in_stub;
00166 }
00167
00171 virtual bool hasDescription()
00172 {
00173 return describer->hasDescription();
00174 }
00175
00180 virtual String describeTo( String &buffer ) const
00181 {
00182 return describer->describeTo( buffer, matchers, stub.get(), name );
00183 }
00184
00186
00187
00190 class DescriberBase
00191 {
00192 public:
00193
00194 typedef AutoPointer<DescriberBase> AP;
00195
00198 virtual ~DescriberBase()
00199 {
00200 }
00201
00205 virtual bool hasDescription() = 0;
00206
00214 virtual String describeTo( String &result,
00215 #ifdef MOCKPP_NO_TYPENAME_FOR_STL_NS
00216 const MOCKPP_STL::vector<InvocationMatcher<I>*> &matchers,
00217 #else
00218 const typename MOCKPP_STL::vector<InvocationMatcher<I>*> &matchers,
00219 #endif
00220 Stub<R, I> *stub,
00221 const String &name ) const = 0;
00222
00230 String describeTo( String &result,
00231 #ifdef MOCKPP_NO_TYPENAME_FOR_STL_NS
00232 const MOCKPP_STL::vector<InvocationMatcher<I>*> &matchers,
00233 #else
00234 const typename MOCKPP_STL::vector<InvocationMatcher<I>*> &matchers,
00235 #endif
00236 TypelessStub<R>* stub,
00237 const String &name ) const
00238 {
00239 typename Stub<R, I>::AP adap = new TypelessStubAdapter<R, I> (stub, false);
00240 return describeTo(result, matchers, adap.get(), name);
00241 }
00242 };
00243
00246
00251 class Describer : public DescriberBase
00252 {
00253 public:
00254
00258 virtual bool hasDescription()
00259 {
00260 return true;
00261 }
00262
00270 virtual String describeTo( String &result,
00271 #ifdef MOCKPP_NO_TYPENAME_FOR_STL_NS
00272 const MOCKPP_STL::vector<InvocationMatcher<I>*> &matchers,
00273 #else
00274 const typename MOCKPP_STL::vector<InvocationMatcher<I>*> &matchers,
00275 #endif
00276 Stub<R, I> *stub,
00277 const String &name ) const
00278 {
00279 const String SEP = MOCKPP_PCHAR( ", " );
00280 bool needSeparator = false;
00281
00282 for ( ConstIterator it = matchers.begin(); it != matchers.end(); ++it )
00283 {
00284 InvocationMatcher<I>* invmatcher = *it;
00285
00286 if ( !invmatcher->hasDescription() )
00287 continue;
00288
00289 if ( needSeparator )
00290 result += SEP;
00291
00292 invmatcher->describeTo( result );
00293 needSeparator = true;
00294 }
00295
00296 if ( needSeparator )
00297 result += SEP;
00298
00299 stub->describeTo( result );
00300
00301 if ( name.length() != 0 )
00302 result += MOCKPP_PCHAR( " [" ) + name + MOCKPP_PCHAR( "]" );
00303
00304 return result;
00305 }
00306 };
00307
00309
00310
00313 class DefaultDescriber : public DescriberBase
00314 {
00315 public:
00316
00317 virtual bool hasDescription()
00318 {
00319 return true;
00320 }
00321
00329 String describeTo( String &result,
00330 #ifdef MOCKPP_NO_TYPENAME_FOR_STL_NS
00331 const MOCKPP_STL::vector<InvocationMatcher<I>*> &matchers,
00332 #else
00333 const typename MOCKPP_STL::vector<InvocationMatcher<I>*> &matchers,
00334 #endif
00335 Stub<R, I> *stub,
00336 const String &name ) const
00337 {
00338 typename InvocationMockerBase<R, I>::ConstIterator it;
00339 for (it = matchers.begin(); it != matchers.end(); ++it )
00340 {
00341 InvocationMatcher<I>* matcher = *it;
00342
00343 if ( matcher->hasDescription() )
00344 {
00345 matcher->describeTo( result );
00346 result += MOCKPP_PCHAR( ", " );
00347 }
00348 }
00349
00350 stub->describeTo( result );
00351
00352 if ( name.length() != 0 )
00353 result += MOCKPP_PCHAR( " [" ) + name + MOCKPP_PCHAR( "]" );
00354 return result;
00355 }
00356 };
00357
00358 protected:
00359
00360 List matchers;
00361 typename Stub<R, I>::AP stub;
00362
00363 private:
00364
00365 String name;
00366 AutoPointer<DescriberBase> describer;
00367 };
00368
00369
00373 template <typename R,
00374 typename I>
00375 class InvocationMocker : public InvocationMockerBase<R, I>
00376 {
00377 typedef typename InvocationMockerBase<R, I>::Iterator Iterator;
00378 typedef typename InvocationMockerBase<R, I>::ConstIterator ConstIterator;
00379
00380 public:
00381
00382 typedef typename InvocationMockerBase<R, I>::Describer Describer;
00383 typedef typename InvocationMockerBase<R, I>::DescriberBase DescriberBase;
00384 typedef typename InvocationMockerBase<R, I>::DefaultDescriber DefaultDescriber;
00385
00388 InvocationMocker()
00389 : InvocationMockerBase<R, I>( new typename InvocationMockerBase<R, I>::DefaultDescriber(),
00390 new TypelessStubAdapter<R, I>(new DefaultResultStub<R> ))
00391 {
00392 }
00393
00397 InvocationMocker( AutoPointer<DescriberBase> in_describer )
00398 : InvocationMockerBase<R, I>( in_describer,
00399 new TypelessStubAdapter<R, I>(new DefaultResultStub<R> ))
00400 {
00401 }
00402
00407 virtual R invoke( const I &invocation )
00408 {
00409 for ( Iterator it = this->matchers.begin(); it != this->matchers.end(); ++it )
00410 ( *it ) ->incInvoked( invocation );
00411 return this->stub->invoke( invocation );
00412 }
00413 };
00414
00415
00416 #ifndef MOCKPP_PTI_WEAKNESS // Partial Template Instantiation Weakness
00417
00418
00422 template <typename I>
00423 class InvocationMocker<void, I> : public InvocationMockerBase<void, I>
00424 {
00425 typedef typename InvocationMockerBase<void, I>::Iterator Iterator;
00426 typedef typename InvocationMockerBase<void, I>::ConstIterator ConstIterator;
00427
00428 public:
00429
00430 typedef typename InvocationMockerBase<void, I>::Describer Describer;
00431 typedef typename InvocationMockerBase<void, I>::DescriberBase DescriberBase;
00432 typedef typename InvocationMockerBase<void, I>::DefaultDescriber DefaultDescriber;
00433
00436 InvocationMocker<void, I>()
00437 : InvocationMockerBase<void, I>( new DefaultDescriber(),
00438 new TypelessStubAdapter<void, I>(new VoidStub))
00439 {
00440 }
00441
00445 InvocationMocker<void, I>( AutoPointer<DescriberBase> in_describer )
00446 : InvocationMockerBase<void, I>( in_describer,
00447 new TypelessStubAdapter<void, I>(new VoidStub))
00448 {
00449 }
00450
00455 virtual void invoke( const I &invocation )
00456 {
00457 for ( Iterator it = this->matchers.begin(); it != this->matchers.end(); ++it )
00458 ( *it ) ->incInvoked( invocation );
00459 this->stub->invoke( invocation );
00460 }
00461 };
00462
00463
00464 #define MOCKPP_INVOCATIONMOCKER_PTI_IMPL(I)
00465 #define MOCKPP_INVOCATIONMOCKER_PTI_DECL(I)
00466
00467
00468 #else // MOCKPP_PTI_WEAKNESS Partial Template Instantiation Weakness
00469
00470
00471 #define MOCKPP_INVOCATIONMOCKER_PTI_DECL(I) \
00472 MOCKPP_NS_START \
00473 template<> \
00474 class InvocationMocker<void, I>; \
00475 }
00476
00477
00478 #define MOCKPP_INVOCATIONMOCKER_PTI_IMPL(I) \
00479 MOCKPP_NS_START \
00480 template<> \
00481 class InvocationMocker<void, I> : public InvocationMockerBase<void, I> \
00482 { \
00483 public: \
00484 InvocationMocker<void, I >() \
00485 : InvocationMockerBase<void, I >( new InvocationMockerBase<void, I >::DefaultDescriber(), \
00486 new TypelessStubAdapter<void, I >(new VoidStub)) \
00487 {} \
00488 \
00489 InvocationMocker<void, I >(\
00490 AutoPointer<MOCKPP_NS::InvocationMockerBase<void, I >::DescriberBase> in_describer ) \
00491 : InvocationMockerBase<void, I >( in_describer, \
00492 new TypelessStubAdapter<void, I >(new VoidStub)) \
00493 {} \
00494 \
00495 void invoke( const I &invocation ) \
00496 { \
00497 for ( Iterator it = this->matchers.begin(); it != this->matchers.end(); ++it ) \
00498 ( *it ) ->incInvoked( invocation ); \
00499 this->stub->invoke( invocation ); \
00500 } \
00501 }; \
00502 MOCKPP_NS_END
00503
00504
00505 #endif // MOCKPP_PTI_WEAKNESS
00506
00507
00508 MOCKPP_NS_END
00509
00520 #endif // MOCKPP_INVOCATIONMOCKER_H