OKlibrary  0.2.1.6
TestBaseClass.hpp
Go to the documentation of this file.
00001 // Oliver Kullmann, 8.5.2005 (Swansea)
00002 /* Copyright 2005 - 2007 Oliver Kullmann
00003 This file is part of the OKlibrary. OKlibrary is free software; you can redistribute
00004 it and/or modify it under the terms of the GNU General Public License as published by
00005 the Free Software Foundation and included in this library; either version 3 of the
00006 License, or any later version. */
00007 
00015 #ifndef TESTBASECLASS_kkLLkbV5I
00016 #define TESTBASECLASS_kkLLkbV5I
00017 
00018 #include <vector>
00019 #include <exception>
00020 #include <string>
00021 #include <list>
00022 #include <ostream>
00023 #include <cstdlib>
00024 
00025 #include <boost/timer.hpp>
00026 
00027 #include <OKlib/TestSystem/TestExceptions.hpp>
00028 
00029 namespace OKlib {
00030 
00031   namespace TestSystem {
00032 
00033     typedef double TestSingleParameter;
00034     typedef std::vector<TestSingleParameter> TestParameter;
00035 
00046     class Test {
00047     public :
00048       virtual ~Test() {}
00049       typedef Test test_type;
00050       void perform_test(const TestParameter& P = TestParameter()) {
00051         // throws only TestException
00052         try {
00053           perform_test_trivial();
00054           if (not P.empty())
00055             perform_test_nontrivial(P);
00056         }
00057         catch(const TestException&) {
00058           throw;
00059         }
00060         catch(const std::exception& e) {
00061           TestException e_new(std::string("std::exception: what = ") + e.what() + "\ntype = " + typeid(e).name());
00062           e_new.add(OKLIB_TESTDESCRIPTION);
00063           throw e_new;
00064         }
00065         catch(...) {
00066           TestException e("exception ...\n ");
00067           e.add(OKLIB_TESTDESCRIPTION);
00068           throw e;
00069         }
00070       }
00071     private :
00072       virtual void perform_test_trivial() = 0;
00073       virtual void perform_test_nontrivial(const TestParameter&) {};
00074     };
00075 
00086     class TestBase : public Test {
00087 
00088       typedef std::list<TestBase*> List;
00089       // List does not take ownership of the elements pointed to by its members.
00090       static List test_list;
00091       mutable List::iterator it;
00092       mutable bool inserted;
00093 
00094       TestBase (const TestBase&); // not available
00095       TestBase& operator =(const TestBase&); // not available
00096 
00097     protected :
00098       void insert(TestBase* const p) const {
00099         test_list.push_back(p);
00100         it = --test_list.end();
00101         inserted = true;
00102       }
00103 
00104     public :
00105 
00106       static int run_tests_default(std::ostream& out) {
00107         out << "\nrun_tests_default:\n\n";
00108         int return_value = 0;
00109         boost::timer timer;
00110         for (List::iterator i = test_list.begin(); i != test_list.end(); ++i) {
00111           try {
00112             (*i) -> perform_test();
00113           }
00114           catch (const TestException& e) {
00115             out << e;
00116             return_value = EXIT_FAILURE;
00117           }
00118         }
00119         const double elapsed(timer.elapsed());
00120         out << "\nElapsed: " << elapsed << "s\n";
00121         const List::size_type& size(test_list.size());
00122         out << size << " testobject";
00123         if (size != 1) out << "s";
00124         out << ".\n";
00125         return return_value;
00126       }
00127 
00128       TestBase() : inserted(false) {}
00129 
00130       virtual ~TestBase() {
00131         if (inserted)
00132           test_list.erase(it);
00133         // does not throw
00134       }
00135 
00136     };
00137     TestBase::List TestBase::test_list;
00138  
00139   }
00140 
00141 }
00142 
00143 #endif