00001
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #ifndef MOCKPP_ConstraintList_H
00031 #define MOCKPP_ConstraintList_H
00032
00033 #include <mockpp/mockpp.h>
00034
00035 #include MOCKPP_ALGORITHM_H
00036 #include MOCKPP_VECTOR_H
00037
00038 #include <mockpp/AbstractExpectationCollection.h>
00039
00040 #include <mockpp/util/AssertMo.h>
00041
00042 #include <mockpp/constraint/Constraint.h>
00043 #include <mockpp/constraint/ConstraintHolder.h>
00044 #include <mockpp/constraint/IsEqual.h>
00045 #include <mockpp/constraint/IsAnything.h>
00046
00047
00048 MOCKPP_NS_START
00049
00050
00056 template <class T>
00057 class ConstraintList : public AbstractExpectationCollection<T>
00058 {
00059 public:
00060
00065 ConstraintList(const String &name, VerifiableList *parent = 0)
00066 : AbstractExpectationCollection<T>(name, parent),
00067 expectNothing(false),
00068 haveActualValue(false)
00069 {
00070 }
00071
00074 virtual ~ConstraintList()
00075 {
00076 reset();
00077 }
00078
00079 typedef bool (Constraint<T>::*Checker)(const T &arg ) const;
00080
00086 virtual void verify()
00087 {
00088 if( expectNothing)
00089 {
00090 String fmt = mockpp_i18n(MOCKPP_PCHAR("%1 expected no value."));
00091 fmt << this->getVerifiableName();
00092 MOCKPP_ASSERT_FALSE_MESSAGE(fmt, haveActualValue );
00093 }
00094
00095 else
00096 {
00097 if (!this->hasExpectations() )
00098 return;
00099
00100 String fmt = mockpp_i18n(MOCKPP_PCHAR("%1 expected a value."));
00101 fmt << this->getVerifiableName();
00102
00103 MOCKPP_ASSERT_TRUE_MESSAGE(fmt, haveActualValue);
00104
00105 fmt = mockpp_i18n(MOCKPP_PCHAR("%1 did not receive the expected amount of values."));
00106 fmt << this->getVerifiableName();
00107 MOCKPP_ASSERT_TRUE_MESSAGE(fmt, actualItems.size() == constraints.size());
00108
00109 for (unsigned i = 0; i < actualItems.size(); ++i)
00110 checkImmediateValue(actualItems[i], i, &Constraint<T>::verify);
00111 }
00112 }
00113
00114
00118 void addActual(const T &actualItem)
00119 {
00120 actualItems.push_back(actualItem);
00121 haveActualValue = true;
00122
00123 if (this->shouldCheckImmediately())
00124 checkImmediateValue(actualItem);
00125 }
00126
00127
00132 template <class I>
00133 void addActual(I items, I end)
00134 {
00135 for ( ; items != end; ++items)
00136 addActual(*items);
00137 }
00138
00139
00144 ConstraintList& addExpected(const ConstraintHolder<T> &constraint)
00145 {
00146 typename Constraint<T>::AP cons (constraint);
00147 constraints.push_back(cons.release());
00148 expectNothing = false;
00149 this->setHasExpectations();
00150 return *this;
00151 }
00152
00153
00158 ConstraintList& addExpected(const T &expectedItem)
00159 {
00160 const ConstraintHolder<T> h = new IsEqual<T>(expectedItem);
00161 return addExpected(h);
00162 }
00163
00164
00168 void balanceActual()
00169 {
00170 if (actualItems.size() < constraints.size())
00171 {
00172 haveActualValue = true;
00173 delete constraints[actualItems.size()];
00174 constraints[actualItems.size()] = new TypelessConstraintAdapter<T>(new IsAnything);
00175 actualItems.push_back(T());
00176 }
00177 }
00178
00179
00185 template <class I>
00186 ConstraintList& addExpected(I items, I end)
00187 {
00188 for ( ; items != end; ++items)
00189 addExpected(T(*items));
00190 return *this;
00191 }
00192
00193
00196 virtual void clearActual()
00197 {
00198 haveActualValue = false;
00199 actualItems.clear();
00200 }
00201
00202
00206 virtual void reset()
00207 {
00208 this->clearFailOnVerify();
00209 clearActual();
00210 clearExpectation();
00211 expectNothing = false;
00212 }
00213
00214
00218 unsigned size() const
00219 {
00220 return constraints.size();
00221 }
00222
00223
00230 virtual void setExpectNothing()
00231 {
00232 expectNothing = true;
00233 clearExpectation();
00234 this->setHasExpectations();
00235 }
00236
00237
00238 protected:
00239
00242 virtual void clearExpectation()
00243 {
00244 this->clearHasExpectations();
00245 for (unsigned i =0; i < constraints.size(); ++i)
00246 delete constraints[i];
00247 constraints.clear();
00248 }
00249
00250
00257 void checkImmediateValue(const T &actualItem) const
00258 {
00259 checkImmediateValue(actualItem, actualItems.size()-1, &Constraint<T>::eval);
00260 }
00261
00262
00270 void checkImmediateValue(const T &actualItem, unsigned pos, Checker checker) const
00271 {
00272 String fmt = mockpp_i18n(MOCKPP_PCHAR("%1 had different item sizes.\n")
00273 MOCKPP_PCHAR("Expected %2 items but received %3 when adding %4."));
00274 fmt << this->getVerifiableName() << constraints.size() << (pos+1) << actualItem;
00275
00276 MOCKPP_ASSERT_TRUE_MESSAGE(fmt, constraints.size() > pos);
00277
00278 String s;
00279 fmt = mockpp_i18n(MOCKPP_PCHAR("%1 added constraint[%2] does not match: <%3> != %4"));
00280 fmt << this->getVerifiableName() << pos << constraints[pos]->describeTo(s) << actualItem;
00281 MOCKPP_ASSERT_TRUE_MESSAGE(fmt, (constraints[pos]->*checker)(actualItem));
00282 }
00283
00284 private:
00285
00286 ConstraintList<T> (const ConstraintList<T> &);
00287 ConstraintList<T>& operator=(ConstraintList<T>&);
00288
00289 MOCKPP_STL::vector<T> actualItems;
00290 MOCKPP_STL::vector<Constraint<T>*> constraints;
00291 bool expectNothing;
00292 bool haveActualValue;
00293 };
00294
00295
00296 MOCKPP_NS_END
00297
00298
00299 #endif // MOCKPP_ConstraintList_H