//___________________________________________________________ // Authors // Marc Briand, C/C++ Users Journal, July 2000 "Simple Unit Tests in C++" // ftp://ftp.cuj.com/pub/2000/cujjul2000.zip // Modifications by Michael S. Scherotter // // @doc // @module BaseTest | unit testing template classes // @lint //lint -esym(1509,std::unary_function<*>) #ifndef __BASETEST_H__ #define __BASETEST_H__ #ifndef _AFXCONV_H_ #include //lint !e537 #define _AFXCONV_H_ #endif #ifndef _ALGORITHM_ #include #define _ALGORITHM_ #endif #ifndef _FUNCTIONAL_ #include #define _FUNCTIONAL_ #endif #ifndef _IOSTREAM_ #include #define _IOSTREAM_ #endif #ifndef _VECTOR_ #include #define _VECTOR_ #endif #pragma warning (disable : 4290) #pragma warning (disable : 4800) #ifdef _UNICODE typedef std::wostream Stream_t; #else typedef std::ostream Stream_t; #endif template struct DoNothing : public std::unary_function //lint !e1932 { void operator()(const T& /*rObject*/) const { // This does nothing } }; //@class BaseTest11 | Base unit test for 1 input, 1 output function //@tcarg typename | I1 | Input 1 //@tcarg typename | O1 | Output 1 //@tcarg typename | DI1 | Destruction function for I1 //@tcarg typename | DO1 | Destruction function for O1 //@devnote Revision History //7.22.2001 MSS Added DI1 and DO1 parameters to destroy, if necessary, the parameter objects. // By default, DI1 and DO1 do nothing. // Added code in destructor to call DI1 and DO1 // Added code to run() to call DO1 on temporary object template, class DO1 = DoNothing > class BaseTest11 { //@access Public Members public: //@cmember Constructor BaseTest11() { } //@cmember Destructor virtual ~BaseTest11(); //@cmember Run the test cases int run(int first, int last, Stream_t &fout) throw (std::domain_error); //@cmember Apply a single test case virtual void apply(const I1 &, O1 &)=0; //@cmember Get the name of the test virtual const char *getName() const=0; //@access Protected Members protected: //@cmember Add a test case (Should be called in constructor of derived class.) void addCase(const I1 &i1, const O1 &o1); //@cmember Input parameters std::vector i1s;//lint !e407 //@cmember Output parameters std::vector o1s; //@access Private Members private: //@cmember equality operator function to be overridden, if necessary virtual bool Equals1(const O1& first, const O1& second) const; }; template BaseTest11::~BaseTest11() { // Destroy the input parameters (void) std::for_each(i1s.begin(), i1s.end(), DI1()); // Destroy the output parameters (void) std::for_each(o1s.begin(), o1s.end(), DO1()); } template bool BaseTest11::Equals1(const O1& first, const O1& second) const { return (bool)(first == second); } //@mfunc int | BaseTest12I1, O1 | run | Run the unit tests //@devnote Revision History //7. 6.2001 MSS Added macros for TCHAR compliance //7.22.2001 MSS Added template parameters for parameter destructors template int BaseTest11::run(int first, int last, Stream_t &fout) throw (std::domain_error) { O1 tempo1; // constrain range, if necessary if(first < 0) first = 0; if(last > static_cast(i1s.size() - 1)) //lint !e64 { last = i1s.size() - 1; //lint !e64 !e713 } for(int i = first; i <= last; ++i) { if(i >= 0 && i < static_cast(i1s.size())) //lint !e64 !e961 { USES_CONVERSION; fout << A2CT(getName()); apply(i1s[static_cast(i)], tempo1); //lint !e48 !e55 !e56 !e732 if(Equals1(tempo1, o1s[static_cast(i)])) //lint !e732 { fout << _T("(") << i << _T(") successful. Output: ") << tempo1 << std::endl; // Destroy the temporary object DO1()(tempo1); } else { fout << _T("(") << i << _T(") UNSUCCESSFUL") << std::endl; fout << _T(" expected: ") << o1s[static_cast(i)] << _T(", actual: ") << tempo1 << std::endl; //lint !e732 // Destroy the temporary object DO1()(tempo1); throw std::domain_error(getName()); } } else break; } return static_cast(i1s.size()); //lint !e64 } template void BaseTest11::addCase(const I1 &i1, const O1 &o1) { i1s.push_back(i1); //lint !e64 !e1514 o1s.push_back(o1); } // template class BaseTest12 { public: BaseTest12(){} virtual ~BaseTest12() {} int run(int first, int last, Stream_t &fout) throw (std::domain_error); virtual void apply(const I1 &, O1 &, O2&)=0; virtual const char *getName() const=0; protected: void addCase(const I1 &i1, const O1 &o1, const O2 &o2); std::vector i1s; std::vector o1s; std::vector o2s; private: virtual bool Equals1(const O1& first, const O1& second) const; virtual bool Equals2(const O2& first, const O2& second) const; }; template bool BaseTest12::Equals1(const O1& first, const O1& second) const { return (first == second); } template bool BaseTest12::Equals2(const O2& first, const O2& second) const { return (first == second); } //@mfunc int | BaseTest12I1, O1, O2 | run | Run the unit tests //@devnote Revision History //7.6.2001 MSS Added macros for TCHAR compliance template int BaseTest12::run(int first, int last, Stream_t &fout) throw (std::domain_error) { O1 tempo1; O2 tempo2; // constrain range, if necessary if(first < 0) first = 0; if(last > static_cast(i1s.size() - 1)) last = static_cast(i1s.size() - 1); for(int i = first; i <= last; ++i) { if(i >= 0 && i < static_cast(i1s.size())) { USES_CONVERSION; fout << A2CT(getName()); apply(i1s[i], tempo1, tempo2); //lint !e48 !e55 !e56 !e732 if(Equals1(tempo1, o1s[i]) && Equals2(tempo2, o2s[i])) fout << _T("(") << i << _T(") successful. Output: ") << tempo1 << _T(", ") << tempo2 << std::endl; else { fout << _T("(") << i << _T(") UNSUCCESSFUL") << std::endl; fout << _T(" expected: ") << o1s[i] << _T(", actual: ") << tempo1 << std::endl; fout << _T(" expected: ") << o2s[i] << _T(", actual: ") << tempo2 << std::endl; throw std::domain_error(getName()); } } else break; } return static_cast(i1s.size()); } template void BaseTest12::addCase(const I1 &i1, const O1 &o1, const O2 &o2) { i1s.push_back(i1); o1s.push_back(o1); o2s.push_back(o2); } // template class BaseTest13 { public: BaseTest13(){} virtual ~BaseTest13() {} int run(int first, int last, Stream_t &fout) throw (std::domain_error); virtual void apply(const I1 &, O1 &, O2 &, O3 &)=0; virtual const char *getName() const=0; protected: void addCase(const I1 &i1, const O1 &o1, const O2 &o2, const O3 &o3); std::vector i1s; std::vector o1s; std::vector o2s; std::vector o3s; private: virtual bool Equals1(const O1& first, const O1& second) const { return (first == second); } virtual bool Equals2(const O2& first, const O2& second) const { return (first == second); } virtual bool Equals3(const O3& first, const O3& second) const { return (first == second); } }; template int BaseTest13::run(int first, int last, Stream_t &fout) throw (std::domain_error) { O1 tempo1; O2 tempo2; O3 tempo3; // constrain range, if necessary if(first < 0) first = 0; if(last > static_cast(i1s.size() - 1)) last = static_cast(i1s.size() - 1); for(int i = first; i <= last; ++i) { if(i >= 0 && i < static_cast(i1s.size())) { USES_CONVERSION; fout << A2CT(getName()); apply(i1s[i], tempo1, tempo2, tempo3); if(Equals1(tempo1, o1s[i]) && Equals2(tempo2, o2s[i]) && Equals3(tempo3, o3s[i])) fout << "(" << i << ") successful. Output: " << tempo1 << ", " << tempo2 << ", " << tempo3 << std::endl; else { fout << "(" << i << ") UNSUCCESSFUL" << std::endl; fout << " expected: " << o1s[i] << ", actual: " << tempo1 << std::endl; fout << " expected: " << o2s[i] << ", actual: " << tempo2 << std::endl; fout << " expected: " << o3s[i] << ", actual: " << tempo3 << std::endl; throw std::domain_error(getName()); } } else break; } return i1s.size(); } template void BaseTest13::addCase(const I1 &i1, const O1 &o1, const O2 &o2, const O3 &o3) { i1s.push_back(i1); o1s.push_back(o1); o2s.push_back(o2); o3s.push_back(o3); } //@class BaseTest21 | Unit test that takes two input arguments and one output arguemnt //@tcarg typename | I1 | first input argument //@tcarg typename | I2 | second input argument //@tcarg typename | O1 | first output argument //@tcarg class | DI1 | optional first input argument destructor //@rhist //2.18.2002 MSS Added optional DI1 argument template > class BaseTest21 { public: BaseTest21(){} virtual~BaseTest21(); int run(int first, int last, Stream_t &fout) throw (std::domain_error); virtual void apply(const I1 &, const I2 &, O1 &)=0; virtual const char *getName() const=0; protected: void addCase(const I1 &i1, const I2 &i2, const O1 &o1); std::vector i1s; std::vector i2s; std::vector o1s; private: virtual bool Equals1(const O1& first, const O1& second) const { return (first == second); //lint !e734 } }; //@mfunc Destructor //@rhist //2.18.2002 MSS Added call to DI1 template BaseTest21::~BaseTest21() { try { // Destroy the input parameters (void) std::for_each(i1s.begin(), i1s.end(), DI1()); } catch(...) { } } template int BaseTest21::run(int first, int last, Stream_t &fout) throw (std::domain_error) { O1 tempo1; // constrain range, if necessary if(first < 0) first = 0; if(last > static_cast(i1s.size() - 1)) last = i1s.size() - 1; //lint !e713 for(int i = first; i <= last; ++i) { if(i >= 0 && i < static_cast(i1s.size())) { USES_CONVERSION; fout << A2CT(getName()); apply(i1s[i], i2s[i], tempo1); //lint !e732 if(Equals1(tempo1, o1s[i])) //lint !e732 { fout << _T("(") << i << _T(") successful. Output: ") << tempo1 << std::endl; } else { fout << _T("(") << i << _T(") UNSUCCESSFUL") << std::endl; fout << _T(" expected: ") << o1s[i] << _T(", actual: ") << tempo1 << std::endl; //lint !e732 throw std::domain_error(getName()); } } else break; } return static_cast(i1s.size()); } template void BaseTest21::addCase(const I1 &i1, const I2 &i2, const O1 &o1) { i1s.push_back(i1); i2s.push_back(i2); o1s.push_back(o1); } //@class BaseTest22 | Unit test which has two input parameters and two output parameters //@rhist //11.26.2001 MSS Added DI1 template parameter to destroy parameter I1 template > class BaseTest22 { //@access Public Memers public: //@cmember Default constructor BaseTest22(){} //@cmember Destructor virtual ~BaseTest22(); int run(int first, int last, Stream_t &fout) throw (std::domain_error); virtual void apply(const I1 &, const I2 &, O1 &, O2&)=0;//{} virtual const char *getName() const=0;// {return "BaseTest32";} protected: void addCase(const I1 &i1, const I2 &i2, const O1 &o1, const O2 &o2); std::vector i1s; std::vector i2s; std::vector o1s; std::vector o2s; private: virtual bool Equals1(const O1& first, const O1& second) const { return (first == second); //lint !e734 } virtual bool Equals2(const O2& first, const O2& second) const { return (first == second); } }; //@mfunc Destructor //@rhist //11.26.2001 MSS destroyed first input parameter with DI1 template BaseTest22::~BaseTest22() { // Destroy the input parameters (void) std::for_each(i1s.begin(), i1s.end(), DI1()); } template int BaseTest22::run(int first, int last, Stream_t &fout) throw (std::domain_error) { O1 tempo1; O2 tempo2; // constrain range, if necessary if(first < 0) first = 0; if(last > static_cast(i1s.size()) - 1) last = static_cast(i1s.size()) - 1; for(int i = first; i <= last; ++i) { if(i >= 0 && i < static_cast(i1s.size())) { USES_CONVERSION; fout << A2CT(getName()); apply(i1s[i], i2s[i], tempo1, tempo2); if(Equals1(tempo1, o1s[i]) && Equals2(tempo2, o2s[i])) { fout << "(" << i << ") successful. Output: " << tempo1 << ", " << tempo2 << std::endl; } else { fout << "(" << i << ") UNSUCCESSFUL" << std::endl; fout << " expected: " << o1s[i] << ", actual: " << tempo1 << std::endl; fout << " expected: " << o2s[i] << ", actual: " << tempo2 << std::endl; throw std::domain_error(getName()); } } else break; } return static_cast(i1s.size()); } template void BaseTest22::addCase(const I1 &i1, const I2 &i2, const O1 &o1, const O2 &o2) { i1s.push_back(i1); i2s.push_back(i2); o1s.push_back(o1); o2s.push_back(o2); } // template class BaseTest23 { public: BaseTest23(){} virtual ~BaseTest23(); int run(int first, int last, Stream_t &fout) throw (std::domain_error); virtual void apply(const I1 &, const I2 &, O1 &, O2 &, O3 &)=0;//{} virtual const char *getName() const=0;// {return "BaseTest32";} protected: void addCase(const I1 &i1, const I2 &i2, const O1 &o1, const O2 &o2, const O3 &o3); std::vector i1s; std::vector i2s; std::vector o1s; std::vector o2s; std::vector o3s; private: virtual bool Equals1(const O1& first, const O1& second) const { return (first == second); } virtual bool Equals2(const O2& first, const O2& second) const { return (first == second); } virtual bool Equals3(const O3& first, const O3& second) const { return (first == second); } }; template BaseTest23::~BaseTest23() { } template int BaseTest23::run(int first, int last, Stream_t &fout) throw (std::domain_error) { O1 tempo1; O2 tempo2; O3 tempo3; // constrain range, if necessary if(first < 0) first = 0; if(last > static_cast(i1s.size() - 1)) last = static_cast(i1s.size() - 1); for(int i = first; i <= last; ++i) { if(i >= 0 && i < static_cast(i1s.size())) { USES_CONVERSION; fout << A2CT(getName()); apply(i1s[i], i2s[i], tempo1, tempo2, tempo3); if(Equals1(tempo1, o1s[i]) && Equals2(tempo2, o2s[i]) && Equals3(tempo3, o3s[i])) { fout << "(" << i << ") successful. Output: " << tempo1 << ", " << tempo2 << ", " << tempo3 << std::endl; } else { fout << "(" << i << ") UNSUCCESSFUL" << std::endl; fout << " expected: " << o1s[i] << ", actual: " << tempo1 << std::endl; fout << " expected: " << o2s[i] << ", actual: " << tempo2 << std::endl; fout << " expected: " << o3s[i] << ", actual: " << tempo3 << std::endl; throw std::domain_error(getName()); } } else break; } return static_cast(i1s.size()); } template void BaseTest23::addCase(const I1 &i1, const I2 &i2, const O1 &o1, const O2 &o2, const O3 &o3) { i1s.push_back(i1); i2s.push_back(i2); o1s.push_back(o1); o2s.push_back(o2); o3s.push_back(o3); } // template class BaseTest31 { public: BaseTest31(){} //@cmember Destructor virtual ~BaseTest31(); int run(int first, int last, Stream_t &fout) throw (std::domain_error); virtual void apply(const I1 &, const I2 &, const I3 &, O1 &)=0; virtual const char *getName() const=0; protected: void addCase(const I1 &i1, const I2 &i2, const I3 &i3, const O1 &o1); std::vector i1s; std::vector i2s; std::vector i3s; std::vector o1s; private: virtual bool Equals1(const O1& first, const O1& second) const { return (first == second); //lint !e734 } }; template BaseTest31::~BaseTest31() { } template int BaseTest31::run(int first, int last, Stream_t &fout) throw (std::domain_error) { O1 tempo1; // constrain range, if necessary if(first < 0) first = 0; if(last > static_cast(i1s.size() - 1)) last = static_cast(i1s.size() - 1); for(int i = first; i <= last; ++i) { if(i >= 0 && i < static_cast(i1s.size())) { USES_CONVERSION; fout << A2CT(getName()); apply(i1s[i], i2s[i], i3s[i], tempo1); //lint !e732 if(Equals1(tempo1, o1s[i]))//lint !e732 fout << "(" << i << ") successful. Output: " << tempo1 << std::endl; else { fout << "(" << i << ") UNSUCCESSFUL" << std::endl; fout << " expected: " << o1s[i] << ", actual: " << tempo1 << std::endl;//lint !e732 throw std::domain_error(getName()); } } else break; } return static_cast(i1s.size()); } template void BaseTest31::addCase(const I1 &i1, const I2 &i2, const I3 &i3, const O1 &o1) { i1s.push_back(i1); i2s.push_back(i2); i3s.push_back(i3); o1s.push_back(o1); } //@class BaseTest32 | Base test with 3 input and 2 output values template class BaseTest32 { //@access Public Members public: //@cmember Constructor BaseTest32(){} //@cmember Destructor virtual ~BaseTest32(); int run(int first, int last, Stream_t &fout) throw (std::domain_error); virtual void apply(const I1 &, const I2 &, const I3 &, O1 &, O2&)=0;//{} virtual const char *getName() const=0;// {return "BaseTest32";} protected: void addCase(const I1 &i1, const I2 &i2, const I3 &i3, const O1 &o1, const O2 &o2); std::vector i1s; std::vector i2s; std::vector i3s; std::vector o1s; std::vector o2s; private: virtual bool Equals1(const O1& first, const O1& second) const { return (first == second); //lint !e734 } virtual bool Equals2(const O2& first, const O2& second) const { return (first == second); } }; //@mfunc Destructor template BaseTest32::~BaseTest32() { } template int BaseTest32::run(int first, int last, Stream_t &fout) throw (std::domain_error) { O1 tempo1; O2 tempo2; // constrain range, if necessary if(first < 0) first = 0; if(last > static_cast(i1s.size()) - 1) last = static_cast(i1s.size()) - 1; for(int i = first; i <= last; ++i) { if(i >= 0 && i < static_cast(i1s.size())) { USES_CONVERSION; fout << A2CT(getName()); apply(i1s[i], i2s[i], i3s[i], tempo1, tempo2); //lint !e732 if(Equals1(tempo1, o1s[i]) && Equals2(tempo2, o2s[i])) //lint !e732 fout << _T("(") << i << _T(") successful. Output: ") << tempo1 << _T(", ") << tempo2 << std::endl; else { fout << "(" << i << ") UNSUCCESSFUL" << std::endl; fout << " expected: " << o1s[i] << ", actual: " << tempo1 << std::endl; //lint !e732 fout << " expected: " << o2s[i] << ", actual: " << tempo2 << std::endl; //lint !e732 throw std::domain_error(getName()); } } else break; } return static_cast(i1s.size()); } template void BaseTest32::addCase(const I1 &i1, const I2 &i2, const I3 &i3, const O1 &o1, const O2 &o2) { i1s.push_back(i1); i2s.push_back(i2); i3s.push_back(i3); o1s.push_back(o1); o2s.push_back(o2); } // template class BaseTest33 { public: BaseTest33(){} virtual ~BaseTest33(); int run(int first, int last, Stream_t &fout) throw (std::domain_error); virtual void apply(const I1 &, const I2 &, const I3 &, O1 &, O2&, O3 &)=0; virtual const char *getName() const=0;// {return "BaseTest32";} protected: void addCase(const I1 &i1, const I2 &i2, const I3 &i3, const O1 &o1, const O2 &o2, const O3 &o3); std::vector i1s; std::vector i2s; std::vector i3s; std::vector o1s; std::vector o2s; std::vector o3s; private: virtual bool Equals1(const O1& first, const O1& second) const { return (first == second); } virtual bool Equals2(const O2& first, const O2& second) const { return (first == second); } virtual bool Equals3(const O3& first, const O3& second) const { return (first == second); } }; //@mfunc Destructor template BaseTest33::~BaseTest33() { } template int BaseTest33::run(int first, int last, Stream_t &fout) throw (std::domain_error) { O1 tempo1; O2 tempo2; O3 tempo3; // constrain range, if necessary if(first < 0) first = 0; if(last > static_cast(i1s.size() - 1)) last = static_cast(i1s.size() - 1); for(int i = first; i <= last; ++i) { if(i >= 0 && i < static_cast(i1s.size())) { USES_CONVERSION; fout << A2CT(getName()); apply(i1s[i], i2s[i], i3s[i], tempo1, tempo2, tempo3); if(Equals1(tempo1, o1s[i]) && Equals2(tempo2, o2s[i]) && Equals3(tempo3, o3s[i])) fout << "(" << i << ") successful. Output: " << tempo1 << ", " << tempo2 << ", " << std::endl; else { fout << "(" << i << ") UNSUCCESSFUL" << std::endl; fout << " expected: " << o1s[i] << ", actual: " << tempo1 << std::endl; fout << " expected: " << o2s[i] << ", actual: " << tempo2 << std::endl; fout << " expected: " << o3s[i] << ", actual: " << tempo3 << std::endl; throw std::domain_error(getName()); } } else break; } return static_cast(i1s.size()); } template void BaseTest33::addCase(const I1 &i1, const I2 &i2, const I3 &i3, const O1 &o1, const O2 &o2, const O3 &o3) { i1s.push_back(i1); i2s.push_back(i2); i3s.push_back(i3); o1s.push_back(o1); o2s.push_back(o2); o3s.push_back(o3); } // template class BaseTest41 { public: BaseTest41(){} //@cmember Destructor virtual ~BaseTest41(); int run(int first, int last, Stream_t &fout) throw (std::domain_error); virtual void apply(const I1 &, const I2 &, const I3 &, const I4 &, O1 &)=0; virtual const char *getName() const=0; protected: void addCase(const I1 &i1, const I2 &i2, const I3 &i3, const I4 &i4, const O1 &o1); std::vector i1s; std::vector i2s; std::vector i3s; std::vector i4s; std::vector o1s; private: virtual bool Equals1(const O1& first, const O1& second) const { return (first == second); } }; template BaseTest41::~BaseTest41() { } template int BaseTest41::run(int first, int last, Stream_t &fout) throw (std::domain_error) { O1 tempo1; // constrain range, if necessary if(first < 0) first = 0; if(last > static_cast(i1s.size() - 1)) last = static_cast(i1s.size() - 1); for(int i = first; i <= last; ++i) { if(i >= 0 && i < static_cast(i1s.size())) { USES_CONVERSION; fout << A2CT(getName()); apply(i1s[i], i2s[i], i3s[i], i4s[i], tempo1); //lint !e732 if(Equals1(tempo1, o1s[i])) //lint !e732 fout << "(" << i << ") successful. Output: " << tempo1 << std::endl; else { fout << "(" << i << ") UNSUCCESSFUL" << std::endl; fout << " expected: " << o1s[i] << ", actual: " << tempo1 << std::endl; //lint !e732 throw std::domain_error(getName()); } } else break; } return static_cast(i1s.size()); } template void BaseTest41::addCase(const I1 &i1, const I2 &i2, const I3 &i3, const I4 &i4, const O1 &o1) { i1s.push_back(i1); i2s.push_back(i2); i3s.push_back(i3); i4s.push_back(i4); o1s.push_back(o1); } // template class BaseTest42 { public: BaseTest42(){} //@cmember Destructor virtual ~BaseTest42(); int run(int first, int last, Stream_t &fout) throw (std::domain_error); virtual void apply(const I1 &, const I2 &, const I3 &, const I4 &, O1 &, O2 &)=0; virtual const char *getName() const=0; protected: void addCase(const I1 &i1, const I2 &i2, const I3 &i3, const I4 &i4, const O1 &o1, const O2 &o2); std::vector i1s; std::vector i2s; std::vector i3s; std::vector i4s; std::vector o1s; std::vector o2s; private: virtual bool Equals1(const O1& first, const O1& second) const { return (first == second); //lint !e734 } virtual bool Equals2(const O2& first, const O2& second) const { return (first == second); } }; template BaseTest42::~BaseTest42() { } template int BaseTest42::run(int first, int last, Stream_t &fout) throw (std::domain_error) { O1 tempo1; O2 tempo2; // constrain range, if necessary if(first < 0) first = 0; if(last > static_cast(i1s.size() - 1)) last = static_cast(i1s.size() - 1); for(int i = first; i <= last; ++i) { if(i >= 0 && i < static_cast(i1s.size())) { USES_CONVERSION; fout << A2CT(getName()); apply(i1s[i], i2s[i], i3s[i], i4s[i], tempo1, tempo2); //lint !e732 if(Equals1(tempo1, o1s[i]) && Equals2(tempo2, o2s[i])) fout << _T("(") << i << _T(") successful. Output: ") << tempo1 << _T(", ") << tempo2 << std::endl; else { fout << "(" << i << ") UNSUCCESSFUL" << std::endl; fout << " expected: " << o1s[i] << ", actual: " << tempo1 << std::endl; fout << " expected: " << o2s[i] << ", actual: " << tempo2 << std::endl; throw std::domain_error(getName()); } } else break; } return static_cast(i1s.size()); } template void BaseTest42::addCase(const I1 &i1, const I2 &i2, const I3 &i3, const I4 &i4, const O1 &o1, const O2 &o2) { i1s.push_back(i1); i2s.push_back(i2); i3s.push_back(i3); i4s.push_back(i4); o1s.push_back(o1); o2s.push_back(o2); } // template class BaseTest43 { public: BaseTest43(){} //@cmember Destructor virtual ~BaseTest43(); int run(int first, int last, Stream_t &fout) throw (std::domain_error); virtual void apply(const I1 &, const I2 &, const I3 &, const I4 &, O1 &, O2 &, O3 &)=0; virtual const char *getName() const=0; protected: void addCase(const I1 &i1, const I2 &i2, const I3 &i3, const I4 &i4, const O1 &o1, const O2 &o2, const O3 &o3); std::vector i1s; std::vector i2s; std::vector i3s; std::vector i4s; std::vector o1s; std::vector o2s; std::vector o3s; private: virtual bool Equals1(const O1& first, const O1& second) const { return (first == second); } virtual bool Equals2(const O2& first, const O2& second) const { return (first == second); } virtual bool Equals3(const O3& first, const O3& second) const { return (first == second); } }; template BaseTest43::~BaseTest43() { } template int BaseTest43::run(int first, int last, Stream_t &fout) throw (std::domain_error) { O1 tempo1; O2 tempo2; O3 tempo3; // constrain range, if necessary if(first < 0) first = 0; if(last > static_cast(i1s.size() - 1)) last = static_cast(i1s.size() - 1); for(int i = first; i <= last; ++i) { if(i >= 0 && i < static_cast(i1s.size())) { USES_CONVERSION; fout << A2CT(getName()); apply(i1s[i], i2s[i], i3s[i], i4s[i], tempo1, tempo2, tempo3); if(Equals1(tempo1, o1s[i]) && Equals2(tempo2, o2s[i]) && Equals3(tempo3, o3s[i]) ) fout << _T("(") << i << _T(") successful. Output: ") << tempo1 << _T(", ") << tempo2 << _T(", ") << tempo3 <(i1s.size()); } template void BaseTest43::addCase(const I1 &i1, const I2 &i2, const I3 &i3, const I4 &i4, const O1 &o1, const O2 &o2,const O3 &o3) { i1s.push_back(i1); i2s.push_back(i2); i3s.push_back(i3); i4s.push_back(i4); o1s.push_back(o1); o2s.push_back(o2); o3s.push_back(o3); } // template class BaseTest44 { public: BaseTest44(){} //@cmember Destructor virtual ~BaseTest44(); int run(int first, int last, Stream_t &fout) throw (std::domain_error); virtual void apply(const I1 &, const I2 &, const I3 &, const I4 &, O1 &, O2 &, O3 &, O4 &)=0; virtual const char *getName() const=0; protected: void addCase(const I1 &i1, const I2 &i2, const I3 &i3, const I4 &i4, const O1 &o1, const O2 &o2, const O3 &o3, const O4 &o4); std::vector i1s; std::vector i2s; std::vector i3s; std::vector i4s; std::vector o1s; std::vector o2s; std::vector o3s; std::vector o4s; private: virtual bool Equals1(const O1& first, const O1& second) const { return (first == second); } virtual bool Equals2(const O2& first, const O2& second) const { return (first == second); } virtual bool Equals3(const O3& first, const O3& second) const { return (first == second); } virtual bool Equals4(const O4& first, const O4& second) const { return (first == second); } }; template BaseTest44::~BaseTest44() { } template int BaseTest44::run(int first, int last, Stream_t &fout) throw (std::domain_error) { O1 tempo1; O2 tempo2; O3 tempo3; O4 tempo4; // constrain range, if necessary if(first < 0) first = 0; if(last > static_cast(i1s.size() - 1)) last = static_cast(i1s.size() - 1); for(int i = first; i <= last; ++i) { if(i >= 0 && i < static_cast(i1s.size())) { USES_CONVERSION; fout << A2CT(getName()); apply(i1s[i], i2s[i], i3s[i], i4s[i], tempo1, tempo2, tempo3, tempo4); if(Equals1(tempo1, o1s[i]) && Equals2(tempo2, o2s[i]) && Equals3(tempo3, o3s[i]) && Equals4(tempo4, o4s[i] ) ) fout << _T("(") << i << _T(") successful. Output: ") << tempo1 << _T(", ") << tempo2 << _T(", ") << tempo3 << _T(", ") << tempo4 <(i1s.size()); } template void BaseTest44::addCase(const I1 &i1, const I2 &i2, const I3 &i3, const I4 &i4, const O1 &o1, const O2 &o2,const O3 &o3, const O4 &o4) { i1s.push_back(i1); i2s.push_back(i2); i3s.push_back(i3); i4s.push_back(i4); o1s.push_back(o1); o2s.push_back(o2); o3s.push_back(o3); o4s.push_back(o4); } //--------------------------------------------------------------------------- #endif //__BASETEST_H__