
/*
 * 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 allowThreaded() 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();

        static void SetResourcePath(const char*);
        static SkString GetResourcePath();

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

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

    private:
        static const char* gResourcePath;

        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 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 { name(r); }   \
    };                                                             \
    static TestRegistry gReg_##name##Class(name##Class::Factory);  \
    }                                                              \
    static void name(skiatest::Reporter* reporter)

#define DEF_GPUTEST(name, reporter, factory)                       \
    static void 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 {              \
            name(r, fGrContextFactory);                            \
        }                                                          \
    };                                                             \
    static TestRegistry gReg_##name##Class(name##Class::Factory);  \
    }                                                              \
    static void name(skiatest::Reporter* reporter, GrContextFactory* factory)

#endif
