
/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */
#ifndef skiatest_Test_DEFINED
#define skiatest_Test_DEFINED

#include "SkRefCnt.h"
#include "SkString.h"
#include "SkTRegistry.h"
#include "SkThread.h"
#include "SkTypes.h"

class GrContextFactory;

namespace skiatest {

    class Test;

    class Reporter : public SkRefCnt {
    public:
        SK_DECLARE_INST_COUNT(Reporter)
        Reporter();

        int countTests() const { return fTestCount; }

        void startTest(Test*);
        void reportFailed(const SkString& desc);
        void endTest(Test*);

        virtual bool allowExtendedTest() const { return false; }
        virtual bool verbose() const { return false; }
        virtual void bumpTestCount() { sk_atomic_inc(&fTestCount); }

    protected:
        virtual void onStart(Test*) {}
        virtual void onReportFailed(const SkString& desc) {}
        virtual void onEnd(Test*) {}

    private:
        int32_t fTestCount;

        typedef SkRefCnt INHERITED;
    };

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

        Reporter* getReporter() const { return fReporter; }
        void setReporter(Reporter*);

        const char* getName();
        void run();
        bool passed() const { return fPassed; }
        SkMSec elapsedMs() const { return fElapsed; }

        static SkString GetTmpDir();

        virtual bool isGPUTest() const { return false; }
        virtual void setGrContextFactory(GrContextFactory* factory) {}

    protected:
        virtual void onGetName(SkString*) = 0;
        virtual void onRun(Reporter*) = 0;

    private:
        Reporter*   fReporter;
        SkString    fName;
        bool        fPassed;
        SkMSec      fElapsed;
    };

    class GpuTest : public Test{
    public:
        GpuTest() : Test(), fGrContextFactory(NULL) {}

        virtual bool isGPUTest() const { return true; }
        virtual void setGrContextFactory(GrContextFactory* factory) {
            fGrContextFactory = factory;
        }

    protected:
        GrContextFactory* fGrContextFactory;  // Unowned.
    };

    typedef SkTRegistry<Test*(*)(void*)> TestRegistry;
}  // namespace skiatest

/*
    Use the following macros to make use of the skiatest classes, e.g.

    #include "Test.h"

    DEF_TEST(TestName, reporter) {
        ...
        REPORTER_ASSERT(reporter, x == 15);
        ...
        REPORTER_ASSERT_MESSAGE(reporter, x == 15, "x should be 15");
        ...
        if (x != 15) {
            ERRORF(reporter, "x should be 15, but is %d", x);
            return;
        }
        ...
    }
*/

#define REPORTER_ASSERT(r, cond)                                 \
    do {                                                         \
        if (!(cond)) {                                           \
            SkString desc;                                       \
            desc.printf("%s:%d\t%s", __FILE__, __LINE__, #cond); \
            r->reportFailed(desc);                               \
        }                                                        \
    } while(0)

#define REPORTER_ASSERT_MESSAGE(r, cond, message)            \
    do {                                                     \
        if (!(cond)) {                                       \
            SkString desc;                                   \
            desc.printf("%s:%d\t%s: %s", __FILE__, __LINE__, \
                        message, #cond);                     \
            r->reportFailed(desc);                           \
        }                                                    \
    } while(0)

#define ERRORF(reporter, ...)                       \
    do {                                            \
        SkString desc;                              \
        desc.printf("%s:%d\t", __FILE__, __LINE__); \
        desc.appendf(__VA_ARGS__) ;                 \
        (reporter)->reportFailed(desc);             \
    } while(0)

#define DEF_TEST(name, reporter)                                        \
    static void test_##name(skiatest::Reporter*);                       \
    namespace skiatest {                                                \
    class name##Class : public Test {                                   \
    public:                                                             \
        static Test* Factory(void*) { return SkNEW(name##Class); }      \
    protected:                                                          \
        virtual void onGetName(SkString* name) SK_OVERRIDE {            \
            name->set(#name);                                           \
        }                                                               \
        virtual void onRun(Reporter* r) SK_OVERRIDE { test_##name(r); } \
    };                                                                  \
    static TestRegistry gReg_##name##Class(name##Class::Factory);       \
    }                                                                   \
    static void test_##name(skiatest::Reporter* reporter)

#define DEF_GPUTEST(name, reporter, factory)                          \
    static void test_##name(skiatest::Reporter*, GrContextFactory*);  \
    namespace skiatest {                                              \
    class name##Class : public GpuTest {                              \
    public:                                                           \
        static Test* Factory(void*) { return SkNEW(name##Class); }    \
    protected:                                                        \
        virtual void onGetName(SkString* name) SK_OVERRIDE {          \
            name->set(#name);                                         \
        }                                                             \
        virtual void onRun(Reporter* r) SK_OVERRIDE {                 \
            test_##name(r, fGrContextFactory);                        \
        }                                                             \
    };                                                                \
    static TestRegistry gReg_##name##Class(name##Class::Factory);     \
    }                                                                 \
    static void test_##name(skiatest::Reporter* reporter, GrContextFactory* factory)

#endif
