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