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

📄 tut.hpp

📁 VC源码,开源测试工具.有助于VC++的学习与开发
💻 HPP
📖 第 1 页 / 共 2 页
字号:
#ifndef TUT_H_GUARD#define TUT_H_GUARD#include <iostream>#include <map>#include <vector>#include <string>#include <sstream>#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 Vladimir Dyuzhev, Vladimir.Dyuzhev@gmail.com */namespace tut{/** * The base for all TUT exceptions. */struct tut_error : public std::exception{    tut_error(const std::string& msg)        : err_msg(msg)    {    }        ~tut_error() throw()    {    }        const char* what() const throw()    {        return err_msg.c_str();    }    private:    std::string err_msg;};/** * Exception to be throwed when attempted to execute  * missed test by number. */struct no_such_test : public tut_error{    no_such_test()         : tut_error("no such test")    {    }        ~no_such_test() throw()    {    }};/** * 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()    {    }        ~beyond_last_test() throw()    {    }};/** * Group not found exception. */struct no_such_group : public tut_error{    no_such_group(const std::string& grp)         : tut_error(grp)    {    }        ~no_such_group() throw()    {    }};/** * Internal exception to be throwed when  * no more tests left in group or journal. */struct no_more_tests{    no_more_tests()    {    }        ~no_more_tests() throw()    {    }};/** * Internal exception to be throwed when  * test constructor has failed. */struct bad_ctor : public tut_error{    bad_ctor(const std::string& msg)         : tut_error(msg)    {    }        ~bad_ctor() throw()    {    }};/** * Exception to be throwed when ensure() fails or fail() called. */struct failure : public tut_error{    failure(const std::string& msg)         : tut_error(msg)    {    }        ~failure() throw()    {    }};/** * Exception to be throwed when test desctructor throwed an exception. */struct warning : public tut_error{    warning(const std::string& msg)         : tut_error(msg)    {    }        ~warning() throw()    {    }};/** * Exception to be throwed when test issued SEH (Win32) */struct seh : public tut_error{    seh(const std::string& msg)         : tut_error(msg)    {    }        ~seh() throw()    {    }};/** * 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;    /**     * Test name (optional)     */    std::string name;    /**     * 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     */    enum result_type    {         ok,         fail,         ex,         warn,         term,         ex_ctor     };        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,                const std::string& test_name, result_type res)        : group(grp),           test(pos),           name(test_name),           result(res)    {    }    /**     * Constructor with exception.     */    test_result(const std::string& grp,int pos,                const std::string& test_name, result_type res,                const std::exception& ex)        : group(grp),           test(pos),           name(test_name),           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 group started     * @param name Name of the group     */    virtual void group_started(const std::string& /*name*/)    {    }    /**     * Called when a test finished.     * @param tr Test results.     */    virtual void test_completed(const test_result& /*tr*/)    {    }    /**     * Called when a group is completed     * @param name Name of the group     */    virtual void group_completed(const std::string& /*name*/)    {    }    /**     * 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{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 tut_error("group shall be non-null");        }        // TODO: inline variable        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            // TODO: should this message appear in stream?            std::cerr << msg << std::endl;            throw tut_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.     */    const 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)        {            callback_->group_started(i->first);            try            {                run_all_tests_in_group_(i);            }            catch (const no_more_tests&)            {                callback_->group_completed(i->first);            }            ++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())        {            callback_->run_completed();            throw no_such_group(group_name);        }        callback_->group_started(group_name);        try        {            run_all_tests_in_group_(i);        }        catch (const no_more_tests&)        {            // ok        }        callback_->group_completed(group_name);        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())        {            callback_->run_completed();            throw no_such_group(group_name);        }        callback_->group_started(group_name);        try        {            test_result tr = i->second->run_test(n);            callback_->test_completed(tr);            callback_->group_completed(group_name);            callback_->run_completed();            return tr;        }        catch (const beyond_last_test&)        {            callback_->group_completed(group_name);            callback_->run_completed();            throw;        }        catch (const no_such_test&)        {            callback_->group_completed(group_name);            callback_->run_completed();            throw;        }    }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_;private:    void run_all_tests_in_group_(const_iterator i) const    {        i->second->rewind();        for ( ;; )        {            test_result tr = i->second->run_next();            callback_->test_completed(tr);            if (tr.result == test_result::ex_ctor)            {                throw no_more_tests();            }        }    }};/** * 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()    {    }    void set_test_name(const std::string& current_test_name)    {        current_test_name_ = current_test_name;    }    const std::string& get_test_name() const    {        return current_test_name_;    }    /**     * Default do-nothing test.     */    template <int n>    void test()    {        called_method_was_a_dummy_test_ = true;    }    /**     * 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_;

⌨️ 快捷键说明

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