aboutsummaryrefslogtreecommitdiffhomepage
path: root/gm/gm_expectations.h
diff options
context:
space:
mode:
authorGravatar epoger@google.com <epoger@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-01-19 04:21:27 +0000
committerGravatar epoger@google.com <epoger@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-01-19 04:21:27 +0000
commit37269607334b99bf814c7dc6b426745d9b7c7e3f (patch)
tree2f6317167cd825fc0a50c0243748f0165bda40e9 /gm/gm_expectations.h
parent514b922236aa9308827e50ec32b1ee6102deff60 (diff)
re-land r7258 with fixes and tests
Diffstat (limited to 'gm/gm_expectations.h')
-rw-r--r--gm/gm_expectations.h174
1 files changed, 174 insertions, 0 deletions
diff --git a/gm/gm_expectations.h b/gm/gm_expectations.h
new file mode 100644
index 0000000000..59a0c1c697
--- /dev/null
+++ b/gm/gm_expectations.h
@@ -0,0 +1,174 @@
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#ifndef gm_expectations_DEFINED
+#define gm_expectations_DEFINED
+
+#include "gm.h"
+#include "SkBitmapChecksummer.h"
+#include "SkImageDecoder.h"
+#include "SkOSFile.h"
+#include "SkRefCnt.h"
+#include "SkTArray.h"
+
+#ifdef SK_BUILD_FOR_WIN
+ // json includes xlocale which generates warning 4530 because we're compiling without
+ // exceptions; see https://code.google.com/p/skia/issues/detail?id=1067
+ #pragma warning(push)
+ #pragma warning(disable : 4530)
+#endif
+#include "json/value.h"
+#ifdef SK_BUILD_FOR_WIN
+ #pragma warning(pop)
+#endif
+
+namespace skiagm {
+
+ // The actual type we use to represent a checksum is hidden in here.
+ typedef Json::UInt64 Checksum;
+ static inline Json::Value asJsonValue(Checksum checksum) {
+ return checksum;
+ }
+
+ static SkString make_filename(const char path[],
+ const char renderModeDescriptor[],
+ const char *name,
+ const char suffix[]) {
+ SkString filename(path);
+ if (filename.endsWith(SkPATH_SEPARATOR)) {
+ filename.remove(filename.size() - 1, 1);
+ }
+ filename.appendf("%c%s%s.%s", SkPATH_SEPARATOR,
+ name, renderModeDescriptor, suffix);
+ return filename;
+ }
+
+ /**
+ * Test expectations (allowed image checksums, etc.)
+ */
+ class Expectations {
+ public:
+ /**
+ * No expectations at all.
+ *
+ * We set ignoreFailure to false by default, but it doesn't really
+ * matter... the result will always be "no-comparison" anyway.
+ */
+ Expectations(bool ignoreFailure=false) {
+ fIgnoreFailure = ignoreFailure;
+ }
+
+ /**
+ * Allow exactly one checksum (appropriate for the case when we
+ * are comparing against a single PNG file).
+ *
+ * By default, DO NOT ignore failures.
+ */
+ Expectations(Checksum singleChecksum, bool ignoreFailure=false) {
+ fIgnoreFailure = ignoreFailure;
+ fAllowedChecksums.push_back() = singleChecksum;
+ }
+
+ /**
+ * Returns true iff we want to ignore failed expectations.
+ */
+ bool ignoreFailure() const { return this->fIgnoreFailure; }
+
+ /**
+ * Returns true iff there are no allowed checksums.
+ */
+ bool empty() const { return this->fAllowedChecksums.empty(); }
+
+ /**
+ * Returns true iff actualChecksum matches any allowedChecksum,
+ * regardless of fIgnoreFailure. (The caller can check
+ * that separately.)
+ */
+ bool match(Checksum actualChecksum) const {
+ for (int i=0; i < this->fAllowedChecksums.count(); i++) {
+ Checksum allowedChecksum = this->fAllowedChecksums[i];
+ if (allowedChecksum == actualChecksum) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Return a JSON representation of the allowed checksums.
+ * This does NOT include any information about whether to
+ * ignore failures.
+ */
+ Json::Value allowedChecksumsAsJson() const {
+ Json::Value allowedChecksumArray;
+ if (!this->fAllowedChecksums.empty()) {
+ for (int i=0; i < this->fAllowedChecksums.count(); i++) {
+ Checksum allowedChecksum = this->fAllowedChecksums[i];
+ allowedChecksumArray.append(asJsonValue(allowedChecksum));
+ }
+ }
+ return allowedChecksumArray;
+ }
+
+ private:
+ SkTArray<Checksum> fAllowedChecksums;
+ bool fIgnoreFailure;
+ };
+
+ /**
+ * Abstract source of Expectations objects for individual tests.
+ */
+ class ExpectationsSource : public SkRefCnt {
+ public:
+ virtual Expectations get(const char *testName) = 0;
+ };
+
+ /**
+ * Return Expectations based on individual image files on disk.
+ */
+ class IndividualImageExpectationsSource : public ExpectationsSource {
+ public:
+ /**
+ * Create an ExpectationsSource that will return Expectations based on
+ * image files found within rootDir.
+ *
+ * rootDir: directory under which to look for image files
+ * (this string will be copied to storage within this object)
+ * notifyOfMissingFiles: whether to log a message to stderr if an image
+ * file cannot be found
+ */
+ IndividualImageExpectationsSource(const char *rootDir,
+ bool notifyOfMissingFiles) :
+ fRootDir(rootDir), fNotifyOfMissingFiles(notifyOfMissingFiles) {}
+
+ Expectations get(const char *testName) SK_OVERRIDE {
+ SkString path = make_filename(fRootDir.c_str(), "", testName,
+ "png");
+ SkBitmap referenceBitmap;
+ bool decodedReferenceBitmap =
+ SkImageDecoder::DecodeFile(path.c_str(), &referenceBitmap,
+ SkBitmap::kARGB_8888_Config,
+ SkImageDecoder::kDecodePixels_Mode,
+ NULL);
+ if (decodedReferenceBitmap) {
+ Checksum checksum = SkBitmapChecksummer::Compute64(
+ referenceBitmap);
+ return Expectations(checksum);
+ } else {
+ if (fNotifyOfMissingFiles) {
+ fprintf(stderr, "FAILED to read %s\n", path.c_str());
+ }
+ return Expectations();
+ }
+ }
+
+ private:
+ const SkString fRootDir;
+ const bool fNotifyOfMissingFiles;
+ };
+
+}
+#endif