skia_test.cpp revision 601d1baa75518db36da6aef7df747ae3e15c771d
1#include "SkGraphics.h"
2#include "Test.h"
3
4using namespace skiatest;
5
6// need to explicitly declare this, or we get some weird infinite loop llist
7template TestRegistry* TestRegistry::gHead;
8
9class Iter {
10public:
11    Iter(Reporter* r) : fReporter(r) {
12        r->ref();
13        fReg = TestRegistry::Head();
14#ifdef SK_DEBUG
15#ifdef SK_SCALAR_IS_FIXED
16#ifndef SK_BUILD_FOR_MAC
17        intentional_error_added_by_epoger
18#endif
19#endif
20#endif
21    }
22
23    ~Iter() {
24        fReporter->unref();
25    }
26
27    Test* next() {
28        if (fReg) {
29            TestRegistry::Factory fact = fReg->factory();
30            fReg = fReg->next();
31            Test* test = fact(NULL);
32            test->setReporter(fReporter);
33            return test;
34        }
35        return NULL;
36    }
37
38    static int Count() {
39        const TestRegistry* reg = TestRegistry::Head();
40        int count = 0;
41        while (reg) {
42            count += 1;
43            reg = reg->next();
44        }
45        return count;
46    }
47
48private:
49    Reporter* fReporter;
50    const TestRegistry* fReg;
51};
52
53static const char* result2string(Reporter::Result result) {
54    return result == Reporter::kPassed ? "passed" : "FAILED";
55}
56
57class DebugfReporter : public Reporter {
58public:
59    DebugfReporter(bool androidMode) : fAndroidMode(androidMode) {}
60
61    void setIndexOfTotal(int index, int total) {
62        fIndex = index;
63        fTotal = total;
64    }
65protected:
66    virtual void onStart(Test* test) {
67        this->dumpState(test, kStarting_State);
68    }
69    virtual void onReport(const char desc[], Reporter::Result result) {
70        if (!fAndroidMode) {
71            SkDebugf("\t%s: %s\n", result2string(result), desc);
72        }
73    }
74    virtual void onEnd(Test* test) {
75        this->dumpState(test, this->getCurrSuccess() ?
76                        kSucceeded_State : kFailed_State);
77    }
78private:
79    enum State {
80        kStarting_State = 1,
81        kSucceeded_State = 0,
82        kFailed_State = -2
83    };
84
85    void dumpState(Test* test, State state) {
86        if (fAndroidMode) {
87            SkDebugf("INSTRUMENTATION_STATUS: test=%s\n", test->getName());
88            SkDebugf("INSTRUMENTATION_STATUS: class=com.skia\n");
89            SkDebugf("INSTRUMENTATION_STATUS: current=%d\n", fIndex+1);
90            SkDebugf("INSTRUMENTATION_STATUS: numtests=%d\n", fTotal);
91            SkDebugf("INSTRUMENTATION_STATUS_CODE: %d\n", state);
92        } else {
93            if (kStarting_State == state) {
94                SkDebugf("[%d/%d] %s...\n", fIndex+1, fTotal, test->getName());
95            } else if (kFailed_State == state) {
96                SkDebugf("---- FAILED\n");
97            }
98        }
99    }
100
101    int fIndex, fTotal;
102    bool fAndroidMode;
103};
104
105int main (int argc, char * const argv[]) {
106    SkAutoGraphics ag;
107
108    bool androidMode = false;
109    for (int i = 1; i < argc; i++) {
110        if (!strcmp(argv[i], "-android")) {
111            androidMode = true;
112        }
113    }
114
115    DebugfReporter reporter(androidMode);
116    Iter iter(&reporter);
117    Test* test;
118
119    const int count = Iter::Count();
120    int index = 0;
121    int successCount = 0;
122    while ((test = iter.next()) != NULL) {
123        reporter.setIndexOfTotal(index, count);
124        successCount += test->run();
125        SkDELETE(test);
126        index += 1;
127    }
128
129    if (!androidMode) {
130        SkDebugf("Finished %d tests, %d failures.\n", count,
131                 count - successCount);
132    }
133    return (count == successCount) ? 0 : 1;
134}
135