Home | History | Annotate | Download | only in gm
      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:
     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          */
    126         bool ignoreFailure() const { return this->fIgnoreFailure; }
    127 
    128         /**
    129          * Override default setting of fIgnoreFailure.
    130          */
    131         void setIgnoreFailure(bool val) { this->fIgnoreFailure = val; }
    132 
    133         /**
    134          * Returns true iff there are no allowed results.
    135          */
    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          */
    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          */
    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