skia_test.cpp revision d6176b0dcacb124539e0cfd051e6d93a9782f020
1
2/*
3 * Copyright 2011 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8#include "SkGraphics.h"
9#include "Test.h"
10
11using namespace skiatest;
12
13// need to explicitly declare this, or we get some weird infinite loop llist
14template TestRegistry* TestRegistry::gHead;
15
16class Iter {
17public:
18    Iter(Reporter* r) : fReporter(r) {
19        r->ref();
20        fReg = TestRegistry::Head();
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#ifdef SK_ENABLE_INST_COUNT
107    gPrintInstCount = true;
108#endif
109    SkGraphics::Init();
110
111    bool androidMode = false;
112    const char* matchStr = NULL;
113
114    char* const* stop = argv + argc;
115    for (++argv; argv < stop; ++argv) {
116        if (strcmp(*argv, "-android") == 0) {
117            androidMode = true;
118
119        } else if (strcmp(*argv, "--match") == 0) {
120            ++argv;
121            if (argv < stop && **argv) {
122                matchStr = *argv;
123            }
124        }
125    }
126
127    {
128        SkString header("Skia UnitTests:");
129        if (matchStr) {
130            header.appendf(" --match %s", matchStr);
131        }
132#ifdef SK_DEBUG
133        header.append(" SK_DEBUG");
134#else
135        header.append(" SK_RELEASE");
136#endif
137#ifdef SK_SCALAR_IS_FIXED
138        header.append(" SK_SCALAR_IS_FIXED");
139#else
140        header.append(" SK_SCALAR_IS_FLOAT");
141#endif
142        if (!androidMode) {
143            SkDebugf("%s\n", header.c_str());
144        }
145    }
146
147    DebugfReporter reporter(androidMode);
148    Iter iter(&reporter);
149    Test* test;
150
151    const int count = Iter::Count();
152    int index = 0;
153    int failCount = 0;
154    int skipCount = 0;
155    while ((test = iter.next()) != NULL) {
156        reporter.setIndexOfTotal(index, count);
157        if (NULL != matchStr && !strstr(test->getName(), matchStr)) {
158            ++skipCount;
159        } else {
160            if (!test->run()) {
161                ++failCount;
162            }
163        }
164        SkDELETE(test);
165        index += 1;
166    }
167
168    if (!androidMode) {
169        SkDebugf("Finished %d tests, %d failures, %d skipped.\n",
170                 count, failCount, skipCount);
171    }
172
173    SkGraphics::Term();
174
175    return (failCount == 0) ? 0 : 1;
176}
177