• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2013 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  *
7  * TODO(epoger): Combine this with tools/image_expectations.h, or eliminate one of the two.
8  */
9 #ifndef gm_expectations_DEFINED
10 #define gm_expectations_DEFINED
11 
12 #include "gm.h"
13 #include "SkBitmap.h"
14 #include "SkData.h"
15 #include "SkJSONCPP.h"
16 #include "SkOSFile.h"
17 #include "SkRefCnt.h"
18 #include "SkStream.h"
19 #include "SkTArray.h"
20 
21 
22 namespace skiagm {
23 
24     Json::Value CreateJsonTree(Json::Value expectedResults,
25                                Json::Value actualResultsFailed,
26                                Json::Value actualResultsFailureIgnored,
27                                Json::Value actualResultsNoComparison,
28                                Json::Value actualResultsSucceeded);
29     /**
30      * The digest of a GM test result.
31      *
32      * Currently, this is always a uint64_t hash digest of an SkBitmap...
33      * but we will add other flavors soon.
34      */
35     class GmResultDigest {
36     public:
37         /**
38          * Create a ResultDigest representing an actual image result.
39          */
40         explicit GmResultDigest(const SkBitmap &bitmap);
41 
42         /**
43          * Create a ResultDigest representing an allowed result
44          * checksum within JSON expectations file, in the form
45          * ["bitmap-64bitMD5", 12345].
46          */
47         explicit GmResultDigest(const Json::Value &jsonTypeValuePair);
48 
49         /**
50          * Returns true if this GmResultDigest was fully and successfully
51          * created.
52          */
53         bool isValid() const;
54 
55         /**
56          * Returns true if this and other GmResultDigest could
57          * represent identical results.
58          */
59         bool equals(const GmResultDigest &other) const;
60 
61         /**
62          * Returns a JSON type/value pair representing this result,
63          * such as ["bitmap-64bitMD5", 12345].
64          */
65         Json::Value asJsonTypeValuePair() const;
66 
67         /**
68          * Returns the hashtype, such as "bitmap-64bitMD5", as an SkString.
69          */
70         SkString getHashType() const;
71 
72         /**
73          * Returns the hash digest value, such as "12345", as an SkString.
74          */
75         SkString getDigestValue() const;
76 
77     private:
78         bool fIsValid; // always check this first--if it's false, other fields are meaningless
79         uint64_t fHashDigest;
80     };
81 
82     /**
83      * Encapsulates an SkBitmap and its GmResultDigest, guaranteed to keep them in sync.
84      */
85     class BitmapAndDigest {
86     public:
BitmapAndDigest(const SkBitmap & bitmap)87         explicit BitmapAndDigest(const SkBitmap &bitmap) : fBitmap(bitmap), fDigest(bitmap) {}
88 
89         const SkBitmap fBitmap;
90         const GmResultDigest fDigest;
91     };
92 
93     /**
94      * Test expectations (allowed image results, etc.)
95      */
96     class Expectations {
97     public:
98         /**
99          * No expectations at all.
100          */
101         explicit Expectations(bool ignoreFailure=kDefaultIgnoreFailure);
102 
103         /**
104          * Expect exactly one image (appropriate for the case when we
105          * are comparing against a single PNG file).
106          */
107         explicit Expectations(const SkBitmap& bitmap, bool ignoreFailure=kDefaultIgnoreFailure);
108 
109         /**
110          * Expect exactly one image, whose digest has already been computed.
111          */
112         explicit Expectations(const BitmapAndDigest& bitmapAndDigest);
113 
114         /**
115          * Create Expectations from a JSON element as found within the
116          * kJsonKey_ExpectedResults section.
117          *
118          * It's fine if the jsonElement is null or empty; in that case, we just
119          * don't have any expectations.
120          */
121         explicit Expectations(Json::Value jsonElement);
122 
123         /**
124          * Returns true iff we want to ignore failed expectations.
125          */
ignoreFailure()126         bool ignoreFailure() const { return this->fIgnoreFailure; }
127 
128         /**
129          * Override default setting of fIgnoreFailure.
130          */
setIgnoreFailure(bool val)131         void setIgnoreFailure(bool val) { this->fIgnoreFailure = val; }
132 
133         /**
134          * Returns true iff there are no allowed results.
135          */
empty()136         bool empty() const { return this->fAllowedResultDigests.empty(); }
137 
138         /**
139          * Returns true iff resultDigest matches any allowed result,
140          * regardless of fIgnoreFailure.  (The caller can check
141          * that separately.)
142          */
143         bool match(GmResultDigest resultDigest) const;
144 
145         /**
146          * If this Expectation is based on a single SkBitmap, return a
147          * pointer to that SkBitmap. Otherwise (if the Expectation is
148          * empty, or if it was based on a list of checksums rather
149          * than a single bitmap), returns nullptr.
150          */
asBitmap()151         const SkBitmap *asBitmap() const {
152             return (kUnknown_SkColorType == fBitmap.colorType()) ? nullptr : &fBitmap;
153         }
154 
155         /**
156          * Return a JSON representation of the expectations.
157          */
158         Json::Value asJsonValue() const;
159 
160     private:
161         const static bool kDefaultIgnoreFailure = false;
162 
163         SkTArray<GmResultDigest> fAllowedResultDigests;
164         bool fIgnoreFailure;
165         SkBitmap fBitmap;
166     };
167 
168     /**
169      * Abstract source of Expectations objects for individual tests.
170      */
171     class ExpectationsSource : public SkRefCnt {
172     public:
173         virtual Expectations get(const char *testName) const = 0;
174 
175     private:
176         typedef SkRefCnt INHERITED;
177     };
178 
179     /**
180      * Return Expectations based on individual image files on disk.
181      */
182     class IndividualImageExpectationsSource : public ExpectationsSource {
183     public:
184         /**
185          * Create an ExpectationsSource that will return Expectations based on
186          * image files found within rootDir.
187          *
188          * rootDir: directory under which to look for image files
189          *          (this string will be copied to storage within this object)
190          */
IndividualImageExpectationsSource(const char * rootDir)191         explicit IndividualImageExpectationsSource(const char *rootDir) : fRootDir(rootDir) {}
192 
193         Expectations get(const char *testName) const override ;
194 
195     private:
196         const SkString fRootDir;
197     };
198 
199     /**
200      * Return Expectations based on JSON summary file.
201      */
202     class JsonExpectationsSource : public ExpectationsSource {
203     public:
204         /**
205          * Create an ExpectationsSource that will return Expectations based on
206          * a JSON file.
207          *
208          * jsonPath: path to JSON file to read
209          */
210         explicit JsonExpectationsSource(const char *jsonPath);
211 
212         Expectations get(const char *testName) const override;
213 
214     private:
215 
216         /**
217          * Read the file contents from jsonPath and parse them into jsonRoot.
218          *
219          * Returns true if successful.
220          */
221         static bool Parse(const char *jsonPath, Json::Value *jsonRoot);
222 
223         Json::Value fJsonRoot;
224         Json::Value fJsonExpectedResults;
225     };
226 
227 }
228 #endif
229