⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tut.h

📁 美国加州大学操作系统课程实验平台Nachos
💻 H
📖 第 1 页 / 共 2 页
字号:
#ifndef TUT_H_GUARD#define TUT_H_GUARD#include <iostream>#include <map>#include <vector>#include <string>#include <sstream>#include <stdexcept>#include <typeinfo>#if defined(TUT_USE_SEH)#include <windows.h>#include <winbase.h>#endif/** * Template Unit Tests Framework for C++. * http://tut.dozen.ru * * @author dozen, tut@dozen.ru */namespace tut{  /**   * Exception to be throwed when attempted to execute    * missed test by number.   */  struct no_such_test : public std::logic_error  {    no_such_test() : std::logic_error("no such test"){};  };  /**   * No such test and passed test number is higher than   * any test number in current group. Used in one-by-one   * test running when upper bound is not known.   */  struct beyond_last_test : public no_such_test  {    beyond_last_test(){};  };  /**   * Group not found exception.   */  struct no_such_group : public std::logic_error  {    no_such_group(const std::string& grp) :       std::logic_error(grp){};  };  /**   * Internal exception to be throwed when    * no more tests left in group or journal.   */  struct no_more_tests  {    no_more_tests(){};  };  /**   * Exception to be throwed when ensure() fails or fail() called.   */  class failure : public std::logic_error  {    public:      failure(const std::string& msg) : std::logic_error(msg){};  };  /**   * Exception to be throwed when test desctructor throwed an exception.   */  class warning : public std::logic_error  {    public:      warning(const std::string& msg) : std::logic_error(msg){};  };  /**   * Exception to be throwed when test issued SEH (Win32)   */  class seh : public std::logic_error  {    public:      seh(const std::string& msg) : std::logic_error(msg){};  };  /**   * Return type of runned test/test group.   *   * For test: contains result of test and, possible, message   * for failure or exception.   */  struct test_result  {    /**     * Test group name.     */    std::string group;    /**     * Test number in group.     */    int test;        /**     * ok - test finished successfully     * fail - test failed with ensure() or fail() methods     * ex - test throwed an exceptions     * warn - test finished successfully, but test destructor throwed     * term - test forced test application to terminate abnormally     */    typedef enum { ok, fail, ex, warn, term } result_type;    result_type result;    /**     * Exception message for failed test.     */    std::string message;    std::string exception_typeid;    /**     * Default constructor.     */    test_result()      : test(0),result(ok)    {    }    /**     * Constructor.     */    test_result( const std::string& grp,int pos,result_type res)      : group(grp),test(pos),result(res)    {    }    /**     * Constructor with exception.     */    test_result( const std::string& grp,int pos,                 result_type res,                 const std::exception& ex)      : group(grp),test(pos),result(res),        message(ex.what()),exception_typeid(typeid(ex).name())    {    }  };  /**   * Interface.   * Test group operations.   */  struct group_base  {    virtual ~group_base(){};    // execute tests iteratively    virtual void rewind() = 0;    virtual test_result run_next() = 0;    // execute one test    virtual test_result run_test(int n) = 0;  };  /**   * Test runner callback interface.   * Can be implemented by caller to update   * tests results in real-time. User can implement    * any of callback methods, and leave unused    * in default implementation.   */  struct callback  {    /**     * Virtual destructor is a must for subclassed types.     */    virtual ~callback(){};    /**     * Called when new test run started.     */    virtual void run_started(){};    /**     * Called when a test finished.     * @param tr Test results.     */    virtual void test_completed(const test_result& /*tr*/){};    /**     * Called when all tests in run completed.     */    virtual void run_completed(){};  };  /**   * Typedef for runner::list_groups()   */  typedef std::vector<std::string> groupnames;  /**   * Test runner.   */  class test_runner  {    protected:      typedef std::map<std::string,group_base*> groups;      typedef groups::iterator iterator;      typedef groups::const_iterator const_iterator;      groups groups_;      callback  default_callback_;      callback* callback_;    public:    /**     * Constructor     */    test_runner() : callback_(&default_callback_)    {    }    /**     * Stores another group for getting by name.     */    void register_group(const std::string& name,group_base* gr)    {      if( gr == 0 )      {        throw std::invalid_argument("group shall be non-null");      }      groups::iterator found = groups_.find(name);      if( found != groups_.end() )      {        std::string msg("attempt to add already existent group "+name);        // this exception terminates application so we use cerr also        std::cerr << msg << std::endl;        throw std::logic_error(msg);      }      groups_[name] = gr;    }    /**     * Stores callback object.     */    void set_callback(callback* cb)    {      callback_ = cb==0? &default_callback_:cb;    }    /**     * Returns callback object.     */    callback& get_callback() const    {      return *callback_;    }    /**     * Returns list of known test groups.     */    groupnames list_groups() const    {      groupnames ret;      const_iterator i = groups_.begin();      const_iterator e = groups_.end();      while( i != e )      {        ret.push_back(i->first);        ++i;      }      return ret;    }    /**     * Runs all tests in all groups.     * @param callback Callback object if exists; null otherwise     */    void run_tests() const    {      callback_->run_started();      const_iterator i = groups_.begin();      const_iterator e = groups_.end();      while( i != e )      {        try        {          // iterate all tests          i->second->rewind();          for( ;; )          {            test_result tr = i->second->run_next();            callback_->test_completed(tr);          }        }        catch( const no_more_tests& )        {          // ok        }        ++i;      }      callback_->run_completed();    }    /**     * Runs all tests in specified group.     */    void run_tests(const std::string& group_name) const    {      callback_->run_started();      const_iterator i = groups_.find(group_name);      if( i == groups_.end() )      {        throw no_such_group(group_name);      }      try      {        // iterate all tests        i->second->rewind();        for(;;)        {          test_result tr = i->second->run_next();          callback_->test_completed(tr);        }      }      catch( const no_more_tests& )      {        // ok      }      callback_->run_completed();    }    /**     * Runs one test in specified group.     */    test_result run_test(const std::string& group_name,int n) const    {      callback_->run_started();      const_iterator i = groups_.find(group_name);      if( i == groups_.end() )      {        throw no_such_group(group_name);      }      try      {        test_result tr = i->second->run_test(n);        callback_->test_completed(tr);        callback_->run_completed();        return tr;      }      catch( const beyond_last_test& )      {        callback_->run_completed();        throw;      }            catch( const no_such_test& )      {        callback_->run_completed();        throw;      }    }  };  /**   * Singleton for test_runner implementation.   * Instance with name runner_singleton shall be implemented   * by user.   */  class test_runner_singleton  {    public:      static test_runner& get()      {        static test_runner tr;        return tr;      }  };  extern test_runner_singleton runner;  /**   * Test object. Contains data test run upon and default test method    * implementation. Inherited from Data to allow tests to     * access test data as members.   */  template <class Data>  class test_object : public Data  {    public:    /**     * Default constructor     */    test_object(){};    /**     * The flag is set to true by default (dummy) test.     * Used to detect usused test numbers and avoid unnecessary     * test object creation which may be time-consuming depending     * on operations described in Data::Data() and Data::~Data().     * TODO: replace with throwing special exception from default test.     */    bool called_method_was_a_dummy_test_;    /**     * Default do-nothing test.     */    template <int n>    void test()    {      called_method_was_a_dummy_test_ = true;    }  };  namespace   {    /**     * Tests provided condition.     * Throws if false.     */    void ensure(bool cond)    {       if( !cond ) throw failure("");    }    /**     * Tests provided condition.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -