root/src/tests/system/kernel/unit/Test.h
/*
 * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
 * Distributed under the terms of the MIT License.
 */
#ifndef TEST_H
#define TEST_H


#include "TestContext.h"


class TestSuite;
class TestVisitor;


class Test {
public:
                                                                Test(const char* name);
        virtual                                         ~Test();

                        const char*                     Name() const    { return fName; }

                        TestSuite*                      Suite() const   { return fSuite; }
                        void                            SetSuite(TestSuite* suite);

        virtual bool                            IsLeafTest() const;
        virtual status_t                        Setup(TestContext& context);
        virtual bool                            Run(TestContext& context) = 0;
        virtual bool                            Run(TestContext& context, const char* name);
        virtual void                            Cleanup(TestContext& context, bool setupOK);

        virtual Test*                           Visit(TestVisitor& visitor);

private:
                        const char*                     fName;
                        TestSuite*                      fSuite;
};


class StandardTestDelegate {
public:
                                                                StandardTestDelegate();
        virtual                                         ~StandardTestDelegate();

        virtual status_t                        Setup(TestContext& context);
        virtual void                            Cleanup(TestContext& context, bool setupOK);
};


template<typename TestClass>
class StandardTest : public Test {
public:
                                                                StandardTest(const char* name,
                                                                        TestClass* object,
                                                                        bool (TestClass::*method)(TestContext&));
        virtual                                         ~StandardTest();

        virtual status_t                        Setup(TestContext& context);
        virtual bool                            Run(TestContext& context);
        virtual void                            Cleanup(TestContext& context, bool setupOK);

private:
                        TestClass*                      fObject;
                        bool                            (TestClass::*fMethod)(TestContext&);
};


template<typename TestClass>
StandardTest<TestClass>::StandardTest(const char* name, TestClass* object,
        bool (TestClass::*method)(TestContext&))
        :
        Test(name),
        fObject(object),
        fMethod(method)
{
}


template<typename TestClass>
StandardTest<TestClass>::~StandardTest()
{
        delete fObject;
}


template<typename TestClass>
status_t
StandardTest<TestClass>::Setup(TestContext& context)
{
        return fObject->Setup(context);
}


template<typename TestClass>
bool
StandardTest<TestClass>::Run(TestContext& context)
{
        return (fObject->*fMethod)(context);
}


template<typename TestClass>
void
StandardTest<TestClass>::Cleanup(TestContext& context, bool setupOK)
{
        fObject->Cleanup(context, setupOK);
}


#define TEST_ASSERT(condition)                                                                                  \
        do {                                                                                                                            \
                if (!(condition)) {                                                                                             \
                        TestContext::Current()->AssertFailed(__FILE__, __LINE__,        \
                                __PRETTY_FUNCTION__, #condition);                                               \
                        return false;                                                                                           \
                }                                                                                                                               \
        } while (false)

#define TEST_ASSERT_PRINT(condition, format...)                                                 \
        do {                                                                                                                            \
                if (!(condition)) {                                                                                             \
                        TestContext::Current()->AssertFailed(__FILE__, __LINE__,        \
                                __PRETTY_FUNCTION__, #condition, format);                               \
                        return false;                                                                                           \
                }                                                                                                                               \
        } while (false)

#define TEST_PROPAGATE(result)                                                                                  \
        do {                                                                                                                            \
                if (!(result))                                                                                                  \
                        return false;                                                                                           \
        } while (false)


#endif  // TEST_H