]> git.stg.codes - stg.git/blobdiff - tests/tut/tut.hpp
Finalize transition to Boost.UnitTest.
[stg.git] / tests / tut / tut.hpp
diff --git a/tests/tut/tut.hpp b/tests/tut/tut.hpp
deleted file mode 100644 (file)
index 52f9643..0000000
+++ /dev/null
@@ -1,571 +0,0 @@
-#ifndef TUT_H_GUARD
-#define TUT_H_GUARD
-#include <tut/tut_config.hpp>
-
-#include <iostream>
-#include <map>
-#include <vector>
-#include <set>
-#include <string>
-#include <sstream>
-#include <iterator>
-#include <algorithm>
-
-#include "tut_exception.hpp"
-#include "tut_result.hpp"
-#include "tut_posix.hpp"
-#include "tut_assert.hpp"
-#include "tut_runner.hpp"
-
-#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
-{
-
-template <class, int>
-class test_group;
-
-/**
- * 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 test_object_posix
-{
-    template<class D, int M>
-    friend class test_group;
-
-    void set_test_group(const char *group)
-    {
-        current_test_group_ = group;
-    }
-
-    void set_test_id(int current_test_id)
-    {
-        current_test_id_ = current_test_id;
-    }
-
-public:
-
-    /**
-     * Default constructor
-     */
-    test_object()
-        : called_method_was_a_dummy_test_(false),
-          current_test_id_(0),
-          current_test_name_(),
-          current_test_group_()
-    {
-    }
-
-    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_;
-    }
-
-    const std::string& get_test_group() const
-    {
-        return current_test_group_;
-    }
-
-    int get_test_id() const
-    {
-        return current_test_id_;
-    }
-
-    /**
-     * 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().
-     */
-    bool called_method_was_a_dummy_test_;
-
-    virtual ~test_object()
-    {
-    }
-
-private:
-    int             current_test_id_;
-    std::string     current_test_name_;
-    std::string     current_test_group_;
-};
-
-
-/**
- * Walks through test tree and stores address of each
- * test method in group. Instantiation stops at 0.
- */
-template <class Test, class Group, int n>
-struct tests_registerer
-{
-    static void reg(Group& group)
-    {
-        group.reg(n, &Test::template test<n>);
-        tests_registerer<Test, Group, n - 1>::reg(group);
-    }
-};
-
-template <class Test, class Group>
-struct tests_registerer<Test, Group, 0>
-{
-    static void reg(Group&)
-    {
-    }
-};
-
-/**
- * Test group; used to recreate test object instance for
- * each new test since we have to have reinitialized
- * Data base class.
- */
-template <class Data, int MaxTestsInGroup = 50>
-class test_group : public group_base, public test_group_posix
-{
-    test_group(const test_group&);
-    void operator=(const test_group&);
-
-    const char* name_;
-
-    typedef void (test_object<Data>::*testmethod)();
-    typedef std::map<int, testmethod> tests;
-    typedef typename tests::iterator tests_iterator;
-    typedef typename tests::const_iterator tests_const_iterator;
-    typedef typename tests::const_reverse_iterator
-    tests_const_reverse_iterator;
-    typedef typename tests::size_type size_type;
-
-    tests tests_;
-    tests_iterator current_test_;
-
-    enum seh_result
-    {
-        SEH_OK,
-#if defined(TUT_USE_SEH)
-        SEH_CTOR,
-        SEH_TEST,
-#endif
-        SEH_DUMMY
-    };
-
-    /**
-     * Exception-in-destructor-safe smart-pointer class.
-     */
-    template <class T>
-    class safe_holder
-    {
-        T* p_;
-        bool permit_throw_in_dtor;
-
-        safe_holder(const safe_holder&);
-        safe_holder& operator=(const safe_holder&);
-
-    public:
-        safe_holder()
-            : p_(0),
-              permit_throw_in_dtor(false)
-        {
-        }
-
-        ~safe_holder()
-        {
-            release();
-        }
-
-        T* operator->() const
-        {
-            return p_;
-        }
-
-        T* get() const
-        {
-            return p_;
-        }
-
-        /**
-         * Tell ptr it can throw from destructor. Right way is to
-         * use std::uncaught_exception(), but some compilers lack
-         * correct implementation of the function.
-         */
-        void permit_throw()
-        {
-            permit_throw_in_dtor = true;
-        }
-
-        /**
-         * Specially treats exceptions in test object destructor;
-         * if test itself failed, exceptions in destructor
-         * are ignored; if test was successful and destructor failed,
-         * warning exception throwed.
-         */
-        void release()
-        {
-            try
-            {
-#if defined(TUT_USE_SEH)
-                if (delete_obj() == false)
-                {
-                    throw warning("destructor of test object raised"
-                        " an SEH exception");
-                }
-#else
-                bool d = delete_obj();
-                assert(d && "delete failed with SEH disabled: runtime bug?");
-#endif
-            }
-            catch (const std::exception& ex)
-            {
-                if (permit_throw_in_dtor)
-                {
-                    std::string msg = "destructor of test object raised"
-                        " exception: ";
-                    msg += ex.what();
-                    throw warning(msg);
-                }
-            }
-            catch( ... )
-            {
-                if (permit_throw_in_dtor)
-                {
-                    throw warning("destructor of test object raised an"
-                        " exception");
-                }
-            }
-        }
-
-        /**
-         * Re-init holder to get brand new object.
-         */
-        void reset()
-        {
-            release();
-            permit_throw_in_dtor = false;
-            p_ = new T();
-        }
-
-        bool delete_obj()
-        {
-#if defined(TUT_USE_SEH)
-            __try
-            {
-#endif
-                T* p = p_;
-                p_ = 0;
-                delete p;
-#if defined(TUT_USE_SEH)
-            }
-            __except(handle_seh_(::GetExceptionCode()))
-            {
-                if (permit_throw_in_dtor)
-                {
-                    return false;
-                }
-            }
-#endif
-            return true;
-        }
-    };
-
-public:
-
-    typedef test_object<Data> object;
-
-    /**
-     * Creates and registers test group with specified name.
-     */
-    test_group(const char* name)
-        : name_(name),
-          tests_(),
-          current_test_()
-    {
-        // register itself
-        runner.get().register_group(name_,this);
-
-        // register all tests
-        tests_registerer<object, test_group, MaxTestsInGroup>::reg(*this);
-    }
-
-    /**
-     * This constructor is used in self-test run only.
-     */
-    test_group(const char* name, test_runner& another_runner)
-        : name_(name),
-          tests_(),
-          current_test_()
-    {
-        // register itself
-        another_runner.register_group(name_, this);
-
-        // register all tests
-        tests_registerer<test_object<Data>, test_group,
-            MaxTestsInGroup>::reg(*this);
-    };
-
-    /**
-     * Registers test method under given number.
-     */
-    void reg(int n, testmethod tm)
-    {
-        tests_[n] = tm;
-    }
-
-    /**
-     * Reset test position before first test.
-     */
-    void rewind()
-    {
-        current_test_ = tests_.begin();
-    }
-
-    /**
-     * Runs next test.
-     */
-    bool run_next(test_result &tr)
-    {
-        if (current_test_ == tests_.end())
-        {
-            return false;
-        }
-
-        // find next user-specialized test
-        safe_holder<object> obj;
-        while (current_test_ != tests_.end())
-        {
-            tests_iterator current_test = current_test_++;
-
-            if(run_test_(current_test, obj, tr) && tr.result != test_result::dummy)
-            {
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    /**
-     * Runs one test by position.
-     */
-    bool run_test(int n, test_result &tr)
-    {
-        if (tests_.rbegin() == tests_.rend() ||
-            tests_.rbegin()->first < n)
-        {
-            return false;
-        }
-
-        // withing scope; check if given test exists
-        tests_iterator ti = tests_.find(n);
-        if (ti == tests_.end())
-        {
-            return false;
-        }
-
-        safe_holder<object> obj;
-        return run_test_(ti, obj, tr);
-    }
-
-    /**
-     * VC allows only one exception handling type per function,
-     * so I have to split the method.
-     */
-    bool run_test_(const tests_iterator& ti, safe_holder<object>& obj, test_result &tr)
-    {
-        std::string current_test_name;
-
-        tr = test_result(name_, ti->first, current_test_name, test_result::ok);
-
-        try
-        {
-            switch (run_test_seh_(ti->second, obj, current_test_name, ti->first))
-            {
-#if defined(TUT_USE_SEH)
-                case SEH_CTOR:
-                    throw bad_ctor("seh");
-                    break;
-
-                case SEH_TEST:
-                    throw seh("seh");
-                    break;
-#endif
-                case SEH_DUMMY:
-                    tr.result = test_result::dummy;
-                    break;
-
-                case SEH_OK:
-                    // ok
-                    break;
-            }
-        }
-        catch (const rethrown& ex)
-        {
-            tr = ex.tr;
-            tr.result = test_result::rethrown;
-        }
-        catch (const tut_error& ex)
-        {
-            tr.result = ex.result();
-            tr.exception_typeid = ex.type();
-            tr.message = ex.what();
-        }
-        catch (const std::exception& ex)
-        {
-            tr.result = test_result::ex;
-            tr.exception_typeid = type_name(ex);
-            tr.message = ex.what();
-        }
-        catch (...)
-        {
-            // test failed with unknown exception
-            tr.result = test_result::ex;
-        }
-
-        if (obj.get())
-        {
-            tr.name = obj->get_test_name();
-
-            // try to report to parent, if exists
-            send_result_(obj.get(), tr);
-        }
-        else
-        {
-            tr.name = current_test_name;
-        }
-
-        return true;
-    }
-
-    /**
-     * Runs one under SEH if platform supports it.
-     */
-    seh_result run_test_seh_(testmethod tm, safe_holder<object>& obj,
-                             std::string& current_test_name, int current_test_id)
-    {
-#if defined(TUT_USE_SEH)
-        __try
-        {
-#endif
-            if (obj.get() == 0)
-            {
-                reset_holder_(obj);
-            }
-
-            obj->called_method_was_a_dummy_test_ = false;
-
-#if defined(TUT_USE_SEH)
-
-            __try
-            {
-#endif
-                obj.get()->set_test_id(current_test_id);
-                obj.get()->set_test_group(name_);
-                (obj.get()->*tm)();
-#if defined(TUT_USE_SEH)
-            }
-            __except(handle_seh_(::GetExceptionCode()))
-            {
-                current_test_name = obj->get_test_name();
-                return SEH_TEST;
-            }
-#endif
-
-            if (obj->called_method_was_a_dummy_test_)
-            {
-                // do not call obj.release(); reuse object
-                return SEH_DUMMY;
-            }
-
-            current_test_name = obj->get_test_name();
-            obj.permit_throw();
-            obj.release();
-#if defined(TUT_USE_SEH)
-        }
-        __except(handle_seh_(::GetExceptionCode()))
-        {
-            return SEH_CTOR;
-        }
-#endif
-        return SEH_OK;
-    }
-
-    void reset_holder_(safe_holder<object>& obj)
-    {
-        try
-        {
-            obj.reset();
-        }
-        catch (const std::exception& ex)
-        {
-            throw bad_ctor(ex.what());
-        }
-        catch (...)
-        {
-            throw bad_ctor("test constructor has generated an exception;"
-                " group execution is terminated");
-        }
-    }
-};
-
-#if defined(TUT_USE_SEH)
-/**
- * Decides should we execute handler or ignore SE.
- */
-inline int handle_seh_(DWORD excode)
-{
-    switch(excode)
-    {
-    case EXCEPTION_ACCESS_VIOLATION:
-    case EXCEPTION_DATATYPE_MISALIGNMENT:
-    case EXCEPTION_BREAKPOINT:
-    case EXCEPTION_SINGLE_STEP:
-    case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
-    case EXCEPTION_FLT_DENORMAL_OPERAND:
-    case EXCEPTION_FLT_DIVIDE_BY_ZERO:
-    case EXCEPTION_FLT_INEXACT_RESULT:
-    case EXCEPTION_FLT_INVALID_OPERATION:
-    case EXCEPTION_FLT_OVERFLOW:
-    case EXCEPTION_FLT_STACK_CHECK:
-    case EXCEPTION_FLT_UNDERFLOW:
-    case EXCEPTION_INT_DIVIDE_BY_ZERO:
-    case EXCEPTION_INT_OVERFLOW:
-    case EXCEPTION_PRIV_INSTRUCTION:
-    case EXCEPTION_IN_PAGE_ERROR:
-    case EXCEPTION_ILLEGAL_INSTRUCTION:
-    case EXCEPTION_NONCONTINUABLE_EXCEPTION:
-    case EXCEPTION_STACK_OVERFLOW:
-    case EXCEPTION_INVALID_DISPOSITION:
-    case EXCEPTION_GUARD_PAGE:
-    case EXCEPTION_INVALID_HANDLE:
-        return EXCEPTION_EXECUTE_HANDLER;
-    };
-
-    return EXCEPTION_CONTINUE_SEARCH;
-}
-#endif
-}
-
-#endif // TUT_H_GUARD
-