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