// Copyright (C) 2010, Guy Barrand. All rights reserved. // See the file tools.license for terms. #ifndef tools_utest #define tools_utest #include "args" #include //for FILE* namespace tools { class test { public: typedef bool(*func)(std::ostream&,bool); typedef bool(*func2)(std::ostream&,const args&); typedef bool(*func3)(std::ostream&,int,char**); typedef bool(*cfunc)(FILE*,bool); public: test():m_do_it(false),m_func(0),m_func2(0),m_func3(0),m_cfunc(0){} test(bool a_do_it,func a_func):m_do_it(a_do_it),m_func(a_func),m_func2(0),m_func3(0),m_cfunc(0){} test(bool a_do_it,func2 a_func):m_do_it(a_do_it),m_func(0),m_func2(a_func),m_func3(0),m_cfunc(0){} test(bool a_do_it,func3 a_func):m_do_it(a_do_it),m_func(0),m_func2(0),m_func3(a_func),m_cfunc(0){} test(bool a_do_it,cfunc a_func):m_do_it(a_do_it),m_func(0),m_func2(0),m_func3(0),m_cfunc(a_func){} virtual ~test(){} public: test(const test& a_from) :m_do_it(a_from.m_do_it) ,m_func(a_from.m_func),m_func2(a_from.m_func2),m_func3(a_from.m_func3),m_cfunc(a_from.m_cfunc){} test& operator=(const test& a_from) { m_do_it = a_from.m_do_it; m_func = a_from.m_func; m_func2 = a_from.m_func2; m_func3 = a_from.m_func3; m_cfunc = a_from.m_cfunc; return *this; } public: bool m_do_it; func m_func; func2 m_func2; func3 m_func3; cfunc m_cfunc; }; class utest : public std::vector< std::pair > { typedef std::pair named_test; typedef std::vector parent; public: utest(std::ostream& a_out):m_out(a_out){} virtual~ utest(){} public: utest(const utest& a_from):parent(a_from),m_out(a_from.m_out){} utest& operator=(const utest& a_from){ parent::operator=(a_from);return *this;} public: void add(const std::string& a_name,test::func a_func) { (*this).push_back(named_test(a_name,test(false,a_func))); } void add(const std::string& a_name,test::func2 a_func) { (*this).push_back(named_test(a_name,test(false,a_func))); } void add(const std::string& a_name,test::func3 a_func) { (*this).push_back(named_test(a_name,test(false,a_func))); } void add(const std::string& a_name,test::cfunc a_func) { (*this).push_back(named_test(a_name,test(false,a_func))); } bool exec(const args& a_args,bool a_verbose,int a_argc=0,char** a_argv=0) { {tools_vforit(named_test,*this,it) (*it).second.m_do_it = false;} {tools_vforcit(args::arg,a_args.get_args(),it) { const std::string& key = (*it).first; bool found = false; tools_vforit(named_test,*this,itn) { const std::string& name = (*itn).first; if(key==std::string("-"+name)) {found=true;break;} if(key==std::string("-no_"+name)) {found=true;break;} //valid arg, but not a test. } if(!found) { m_out << "WARNING : arg " << sout(key) << " is not a test." << std::endl; } }} bool some = false; {tools_vforit(named_test,*this,it) { const std::string& name = (*it).first; if(a_args.is_arg("-"+name)) { (*it).second.m_do_it = true; some = true; } }} if(!some) { //do all. tools_vforit(named_test,*this,it) (*it).second.m_do_it = true; } {tools_vforit(named_test,*this,it) { const std::string& name = (*it).first; if(a_args.is_arg("-no_"+name)) { (*it).second.m_do_it = false; } }} bool status = true; {tools_vforcit(named_test,*this,it) { const std::string& name = (*it).first; if((*it).second.m_do_it && (*it).second.m_func) { if(a_verbose) m_out << "test_" << name << " ..." << std::endl; if(!(*it).second.m_func(m_out,a_verbose)) { m_out << "test_" << name << " failed." << std::endl; status = false; } if(a_verbose) m_out << "test_" << name << " end." << std::endl; } }} {tools_vforcit(named_test,*this,it) { const std::string& name = (*it).first; if((*it).second.m_do_it && (*it).second.m_func2) { if(a_verbose) m_out << "test_" << name << " ..." << std::endl; if(!(*it).second.m_func2(m_out,a_args)) { m_out << "test_" << name << " failed." << std::endl; status = false; } if(a_verbose) m_out << "test_" << name << " end." << std::endl; } }} {tools_vforcit(named_test,*this,it) { const std::string& name = (*it).first; if((*it).second.m_do_it && (*it).second.m_func3) { if(a_verbose) m_out << "test_" << name << " ..." << std::endl; if(!(*it).second.m_func3(m_out,a_argc,a_argv)) { m_out << "test_" << name << " failed." << std::endl; status = false; } if(a_verbose) m_out << "test_" << name << " end." << std::endl; } }} {tools_vforcit(named_test,*this,it) { const std::string& name = (*it).first; if((*it).second.m_do_it && (*it).second.m_cfunc) { if(a_verbose) m_out << "test_" << name << " ..." << std::endl; if(!(*it).second.m_cfunc(stdout,a_verbose)) { m_out << "test_" << name << " failed." << std::endl; status = false; } if(a_verbose) m_out << "test_" << name << " end." << std::endl; } }} tools_vforit(named_test,*this,it) (*it).second.m_do_it = false; return status; } void list() {tools_vforit(named_test,*this,it) m_out << (*it).first << std::endl;} protected: std::ostream& m_out; }; } #endif