GM: include filename extension (.png) of each output file in JSON summary

Doing this so that, once we *do* start writing PDF checksums into the JSON
summary, we'll be able to distinguish those from the PNG checksums.
Otherwise, we could have naming collisions.

R=scroggo@google.com

Review URL: https://codereview.chromium.org/14890017

git-svn-id: http://skia.googlecode.com/svn/trunk@9119 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/gm/gm_expectations.cpp b/gm/gm_expectations.cpp
index d9ed779..2c6dede 100644
--- a/gm/gm_expectations.cpp
+++ b/gm/gm_expectations.cpp
@@ -32,17 +32,24 @@
         va_end(args);
     }
 
+    SkString SkPathJoin(const char *rootPath, const char *relativePath) {
+        SkString result(rootPath);
+        if (!result.endsWith(SkPATH_SEPARATOR)) {
+            result.appendUnichar(SkPATH_SEPARATOR);
+        }
+        result.append(relativePath);
+        return result;
+    }
+
     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;
+        SkString filename(name);
+        filename.append(renderModeDescriptor);
+        filename.appendUnichar('.');
+        filename.append(suffix);
+        return SkPathJoin(path, filename.c_str());
     }
 
     // TODO(epoger): This currently assumes that the result SkHashDigest was
@@ -162,8 +169,7 @@
     // IndividualImageExpectationsSource class...
 
     Expectations IndividualImageExpectationsSource::get(const char *testName) {
-        SkString path = make_filename(fRootDir.c_str(), "", testName,
-                                      "png");
+        SkString path = SkPathJoin(fRootDir.c_str(), testName);
         SkBitmap referenceBitmap;
         bool decodedReferenceBitmap =
             SkImageDecoder::DecodeFile(path.c_str(), &referenceBitmap,
diff --git a/gm/gm_expectations.h b/gm/gm_expectations.h
index 0af18c1..9fca33b 100644
--- a/gm/gm_expectations.h
+++ b/gm/gm_expectations.h
@@ -41,6 +41,16 @@
 
     void gm_fprintf(FILE *stream, const char format[], ...);
 
+    /**
+     * Assembles rootPath and relativePath into a single path, like this:
+     * rootPath/relativePath
+     *
+     * Uses SkPATH_SEPARATOR, to work on all platforms.
+     *
+     * TODO(epoger): This should probably move into SkOSFile.h
+     */
+    SkString SkPathJoin(const char *rootPath, const char *relativePath);
+
     SkString make_filename(const char path[],
                            const char renderModeDescriptor[],
                            const char *name,
diff --git a/gm/gmmain.cpp b/gm/gmmain.cpp
index 179ec84..cd9b84f 100644
--- a/gm/gmmain.cpp
+++ b/gm/gmmain.cpp
@@ -121,6 +121,11 @@
     const GMRegistry* fReg;
 };
 
+// TODO(epoger): Right now, various places in this code assume that all the
+// image files read/written by GM use this file extension.
+// Search for references to this constant to find these assumptions.
+const static char kPNG_FileExtension[] = "png";
+
 enum Backend {
     kRaster_Backend,
     kGPU_Backend,
@@ -607,7 +612,7 @@
             (gRec.fBackend == kPDF_Backend && CAN_IMAGE_PDF)) {
 
             path = make_filename(writePath, renderModeDescriptor, name.c_str(),
-                                 "png");
+                                 kPNG_FileExtension);
             success = write_bitmap(path, bitmap);
         }
         if (kPDF_Backend == gRec.fBackend) {
@@ -727,6 +732,8 @@
         }
         SkString completeNameString = baseNameString;
         completeNameString.append(renderModeDescriptor);
+        completeNameString.append(".");
+        completeNameString.append(kPNG_FileExtension);
         const char* completeName = completeNameString.c_str();
 
         if (expectations.empty()) {
@@ -746,7 +753,7 @@
             if (fMismatchPath) {
                 SkString path =
                     make_filename(fMismatchPath, renderModeDescriptor,
-                                  baseNameString.c_str(), "png");
+                                  baseNameString.c_str(), kPNG_FileExtension);
                 write_bitmap(path, actualBitmap);
             }
 
@@ -853,7 +860,10 @@
              * force_all_opaque().
              * See comments above complete_bitmap() for more detail.
              */
-            Expectations expectations = expectationsSource->get(name.c_str());
+            SkString nameWithExtension(name);
+            nameWithExtension.append(".");
+            nameWithExtension.append(kPNG_FileExtension);
+            Expectations expectations = expectationsSource->get(nameWithExtension.c_str());
             errors.add(compare_to_expectations(expectations, actualBitmap,
                                                name, "", true));
         } else {
@@ -865,7 +875,10 @@
             if (!SkBitmapHasher::ComputeDigest(actualBitmap, &actualBitmapHash)) {
                 actualBitmapHash = 0;
             }
-            add_actual_results_to_json_summary(name.c_str(), actualBitmapHash,
+            SkString nameWithExtension(name);
+            nameWithExtension.append(".");
+            nameWithExtension.append(kPNG_FileExtension);
+            add_actual_results_to_json_summary(nameWithExtension.c_str(), actualBitmapHash,
                                                ErrorCombination(kMissingExpectations_ErrorType),
                                                false);
             RecordTestResults(ErrorCombination(kMissingExpectations_ErrorType), name, "");
diff --git a/gm/tests/outputs/compared-against-different-pixels-images/output-expected/json-summary.txt b/gm/tests/outputs/compared-against-different-pixels-images/output-expected/json-summary.txt
index 1bc40b7..e4fd005 100644
--- a/gm/tests/outputs/compared-against-different-pixels-images/output-expected/json-summary.txt
+++ b/gm/tests/outputs/compared-against-different-pixels-images/output-expected/json-summary.txt
@@ -1,10 +1,10 @@
 {
    "actual-results" : {
       "failed" : {
-         "565/selftest1" : {
+         "565/selftest1.png" : {
             "bitmap-64bitMD5" : 12927999507540085554
          },
-         "8888/selftest1" : {
+         "8888/selftest1.png" : {
             "bitmap-64bitMD5" : 1209453360120438698
          }
       },
@@ -13,11 +13,11 @@
       "succeeded" : null
    },
    "expected-results" : {
-      "565/selftest1" : {
+      "565/selftest1.png" : {
          "allowed-bitmap-64bitMD5s" : [ 8863920166200910451 ],
          "ignore-failure" : false
       },
-      "8888/selftest1" : {
+      "8888/selftest1.png" : {
          "allowed-bitmap-64bitMD5s" : [ 13451349865803053525 ],
          "ignore-failure" : false
       }
diff --git a/gm/tests/outputs/compared-against-different-pixels-images/output-expected/stderr b/gm/tests/outputs/compared-against-different-pixels-images/output-expected/stderr
index 3081d2e..293c4d0 100644
--- a/gm/tests/outputs/compared-against-different-pixels-images/output-expected/stderr
+++ b/gm/tests/outputs/compared-against-different-pixels-images/output-expected/stderr
@@ -1,2 +1,2 @@
-GM: ---- 8888/selftest1: 60000 (of 60000) differing pixels, max per-channel mismatch R=0 G=111 B=103 A=0
-GM: ---- 565/selftest1: not computing max per-channel pixel mismatch because non-8888
+GM: ---- 8888/selftest1.png: 60000 (of 60000) differing pixels, max per-channel mismatch R=0 G=111 B=103 A=0
+GM: ---- 565/selftest1.png: not computing max per-channel pixel mismatch because non-8888
diff --git a/gm/tests/outputs/compared-against-different-pixels-json/output-expected/json-summary.txt b/gm/tests/outputs/compared-against-different-pixels-json/output-expected/json-summary.txt
index 1bc40b7..e4fd005 100644
--- a/gm/tests/outputs/compared-against-different-pixels-json/output-expected/json-summary.txt
+++ b/gm/tests/outputs/compared-against-different-pixels-json/output-expected/json-summary.txt
@@ -1,10 +1,10 @@
 {
    "actual-results" : {
       "failed" : {
-         "565/selftest1" : {
+         "565/selftest1.png" : {
             "bitmap-64bitMD5" : 12927999507540085554
          },
-         "8888/selftest1" : {
+         "8888/selftest1.png" : {
             "bitmap-64bitMD5" : 1209453360120438698
          }
       },
@@ -13,11 +13,11 @@
       "succeeded" : null
    },
    "expected-results" : {
-      "565/selftest1" : {
+      "565/selftest1.png" : {
          "allowed-bitmap-64bitMD5s" : [ 8863920166200910451 ],
          "ignore-failure" : false
       },
-      "8888/selftest1" : {
+      "8888/selftest1.png" : {
          "allowed-bitmap-64bitMD5s" : [ 13451349865803053525 ],
          "ignore-failure" : false
       }
diff --git a/gm/tests/outputs/compared-against-empty-dir/output-expected/json-summary.txt b/gm/tests/outputs/compared-against-empty-dir/output-expected/json-summary.txt
index c5edc8a..f65de30 100644
--- a/gm/tests/outputs/compared-against-empty-dir/output-expected/json-summary.txt
+++ b/gm/tests/outputs/compared-against-empty-dir/output-expected/json-summary.txt
@@ -3,21 +3,21 @@
       "failed" : null,
       "failure-ignored" : null,
       "no-comparison" : {
-         "565/selftest1" : {
+         "565/selftest1.png" : {
             "bitmap-64bitMD5" : 12927999507540085554
          },
-         "8888/selftest1" : {
+         "8888/selftest1.png" : {
             "bitmap-64bitMD5" : 1209453360120438698
          }
       },
       "succeeded" : null
    },
    "expected-results" : {
-      "565/selftest1" : {
+      "565/selftest1.png" : {
          "allowed-bitmap-64bitMD5s" : null,
          "ignore-failure" : false
       },
-      "8888/selftest1" : {
+      "8888/selftest1.png" : {
          "allowed-bitmap-64bitMD5s" : null,
          "ignore-failure" : false
       }
diff --git a/gm/tests/outputs/compared-against-identical-bytes-images/output-expected/json-summary.txt b/gm/tests/outputs/compared-against-identical-bytes-images/output-expected/json-summary.txt
index 52256f4..64d1a3f 100644
--- a/gm/tests/outputs/compared-against-identical-bytes-images/output-expected/json-summary.txt
+++ b/gm/tests/outputs/compared-against-identical-bytes-images/output-expected/json-summary.txt
@@ -4,20 +4,20 @@
       "failure-ignored" : null,
       "no-comparison" : null,
       "succeeded" : {
-         "565/selftest1" : {
+         "565/selftest1.png" : {
             "bitmap-64bitMD5" : 12927999507540085554
          },
-         "8888/selftest1" : {
+         "8888/selftest1.png" : {
             "bitmap-64bitMD5" : 1209453360120438698
          }
       }
    },
    "expected-results" : {
-      "565/selftest1" : {
+      "565/selftest1.png" : {
          "allowed-bitmap-64bitMD5s" : [ 12927999507540085554 ],
          "ignore-failure" : false
       },
-      "8888/selftest1" : {
+      "8888/selftest1.png" : {
          "allowed-bitmap-64bitMD5s" : [ 1209453360120438698 ],
          "ignore-failure" : false
       }
diff --git a/gm/tests/outputs/compared-against-identical-bytes-json/output-expected/json-summary.txt b/gm/tests/outputs/compared-against-identical-bytes-json/output-expected/json-summary.txt
index 52256f4..64d1a3f 100644
--- a/gm/tests/outputs/compared-against-identical-bytes-json/output-expected/json-summary.txt
+++ b/gm/tests/outputs/compared-against-identical-bytes-json/output-expected/json-summary.txt
@@ -4,20 +4,20 @@
       "failure-ignored" : null,
       "no-comparison" : null,
       "succeeded" : {
-         "565/selftest1" : {
+         "565/selftest1.png" : {
             "bitmap-64bitMD5" : 12927999507540085554
          },
-         "8888/selftest1" : {
+         "8888/selftest1.png" : {
             "bitmap-64bitMD5" : 1209453360120438698
          }
       }
    },
    "expected-results" : {
-      "565/selftest1" : {
+      "565/selftest1.png" : {
          "allowed-bitmap-64bitMD5s" : [ 12927999507540085554 ],
          "ignore-failure" : false
       },
-      "8888/selftest1" : {
+      "8888/selftest1.png" : {
          "allowed-bitmap-64bitMD5s" : [ 1209453360120438698 ],
          "ignore-failure" : false
       }
diff --git a/gm/tests/outputs/compared-against-identical-pixels-images/output-expected/json-summary.txt b/gm/tests/outputs/compared-against-identical-pixels-images/output-expected/json-summary.txt
index 52256f4..64d1a3f 100644
--- a/gm/tests/outputs/compared-against-identical-pixels-images/output-expected/json-summary.txt
+++ b/gm/tests/outputs/compared-against-identical-pixels-images/output-expected/json-summary.txt
@@ -4,20 +4,20 @@
       "failure-ignored" : null,
       "no-comparison" : null,
       "succeeded" : {
-         "565/selftest1" : {
+         "565/selftest1.png" : {
             "bitmap-64bitMD5" : 12927999507540085554
          },
-         "8888/selftest1" : {
+         "8888/selftest1.png" : {
             "bitmap-64bitMD5" : 1209453360120438698
          }
       }
    },
    "expected-results" : {
-      "565/selftest1" : {
+      "565/selftest1.png" : {
          "allowed-bitmap-64bitMD5s" : [ 12927999507540085554 ],
          "ignore-failure" : false
       },
-      "8888/selftest1" : {
+      "8888/selftest1.png" : {
          "allowed-bitmap-64bitMD5s" : [ 1209453360120438698 ],
          "ignore-failure" : false
       }
diff --git a/gm/tests/outputs/compared-against-identical-pixels-json/output-expected/json-summary.txt b/gm/tests/outputs/compared-against-identical-pixels-json/output-expected/json-summary.txt
index 52256f4..64d1a3f 100644
--- a/gm/tests/outputs/compared-against-identical-pixels-json/output-expected/json-summary.txt
+++ b/gm/tests/outputs/compared-against-identical-pixels-json/output-expected/json-summary.txt
@@ -4,20 +4,20 @@
       "failure-ignored" : null,
       "no-comparison" : null,
       "succeeded" : {
-         "565/selftest1" : {
+         "565/selftest1.png" : {
             "bitmap-64bitMD5" : 12927999507540085554
          },
-         "8888/selftest1" : {
+         "8888/selftest1.png" : {
             "bitmap-64bitMD5" : 1209453360120438698
          }
       }
    },
    "expected-results" : {
-      "565/selftest1" : {
+      "565/selftest1.png" : {
          "allowed-bitmap-64bitMD5s" : [ 12927999507540085554 ],
          "ignore-failure" : false
       },
-      "8888/selftest1" : {
+      "8888/selftest1.png" : {
          "allowed-bitmap-64bitMD5s" : [ 1209453360120438698 ],
          "ignore-failure" : false
       }
diff --git a/gm/tests/outputs/ignore-expectations-mismatch/output-expected/json-summary.txt b/gm/tests/outputs/ignore-expectations-mismatch/output-expected/json-summary.txt
index 1bc40b7..e4fd005 100644
--- a/gm/tests/outputs/ignore-expectations-mismatch/output-expected/json-summary.txt
+++ b/gm/tests/outputs/ignore-expectations-mismatch/output-expected/json-summary.txt
@@ -1,10 +1,10 @@
 {
    "actual-results" : {
       "failed" : {
-         "565/selftest1" : {
+         "565/selftest1.png" : {
             "bitmap-64bitMD5" : 12927999507540085554
          },
-         "8888/selftest1" : {
+         "8888/selftest1.png" : {
             "bitmap-64bitMD5" : 1209453360120438698
          }
       },
@@ -13,11 +13,11 @@
       "succeeded" : null
    },
    "expected-results" : {
-      "565/selftest1" : {
+      "565/selftest1.png" : {
          "allowed-bitmap-64bitMD5s" : [ 8863920166200910451 ],
          "ignore-failure" : false
       },
-      "8888/selftest1" : {
+      "8888/selftest1.png" : {
          "allowed-bitmap-64bitMD5s" : [ 13451349865803053525 ],
          "ignore-failure" : false
       }
diff --git a/gm/tests/outputs/intentionally-skipped-tests/output-expected/json-summary.txt b/gm/tests/outputs/intentionally-skipped-tests/output-expected/json-summary.txt
index 8865b0c..45fe476 100644
--- a/gm/tests/outputs/intentionally-skipped-tests/output-expected/json-summary.txt
+++ b/gm/tests/outputs/intentionally-skipped-tests/output-expected/json-summary.txt
@@ -3,16 +3,16 @@
       "failed" : null,
       "failure-ignored" : null,
       "no-comparison" : {
-         "565/selftest1" : {
+         "565/selftest1.png" : {
             "bitmap-64bitMD5" : 12927999507540085554
          },
-         "565/selftest2" : {
+         "565/selftest2.png" : {
             "bitmap-64bitMD5" : 8863920166200910451
          },
-         "8888/selftest1" : {
+         "8888/selftest1.png" : {
             "bitmap-64bitMD5" : 1209453360120438698
          },
-         "8888/selftest2" : {
+         "8888/selftest2.png" : {
             "bitmap-64bitMD5" : 13451349865803053525
          }
       },
diff --git a/gm/tests/outputs/no-readpath/output-expected/json-summary.txt b/gm/tests/outputs/no-readpath/output-expected/json-summary.txt
index 1009e92..eeed6b4 100644
--- a/gm/tests/outputs/no-readpath/output-expected/json-summary.txt
+++ b/gm/tests/outputs/no-readpath/output-expected/json-summary.txt
@@ -3,10 +3,10 @@
       "failed" : null,
       "failure-ignored" : null,
       "no-comparison" : {
-         "565/selftest1" : {
+         "565/selftest1.png" : {
             "bitmap-64bitMD5" : 12927999507540085554
          },
-         "8888/selftest1" : {
+         "8888/selftest1.png" : {
             "bitmap-64bitMD5" : 1209453360120438698
          }
       },
diff --git a/gm/tests/outputs/nonverbose/output-expected/json-summary.txt b/gm/tests/outputs/nonverbose/output-expected/json-summary.txt
index c5edc8a..f65de30 100644
--- a/gm/tests/outputs/nonverbose/output-expected/json-summary.txt
+++ b/gm/tests/outputs/nonverbose/output-expected/json-summary.txt
@@ -3,21 +3,21 @@
       "failed" : null,
       "failure-ignored" : null,
       "no-comparison" : {
-         "565/selftest1" : {
+         "565/selftest1.png" : {
             "bitmap-64bitMD5" : 12927999507540085554
          },
-         "8888/selftest1" : {
+         "8888/selftest1.png" : {
             "bitmap-64bitMD5" : 1209453360120438698
          }
       },
       "succeeded" : null
    },
    "expected-results" : {
-      "565/selftest1" : {
+      "565/selftest1.png" : {
          "allowed-bitmap-64bitMD5s" : null,
          "ignore-failure" : false
       },
-      "8888/selftest1" : {
+      "8888/selftest1.png" : {
          "allowed-bitmap-64bitMD5s" : null,
          "ignore-failure" : false
       }
diff --git a/gm/tests/outputs/pipe-playback-failure/output-expected/json-summary.txt b/gm/tests/outputs/pipe-playback-failure/output-expected/json-summary.txt
index 5c12f9e..b4e6003 100644
--- a/gm/tests/outputs/pipe-playback-failure/output-expected/json-summary.txt
+++ b/gm/tests/outputs/pipe-playback-failure/output-expected/json-summary.txt
@@ -1,31 +1,31 @@
 {
    "actual-results" : {
       "failed" : {
-         "comparison/selftest1-pipe" : {
+         "comparison/selftest1-pipe.png" : {
             "bitmap-64bitMD5" : 6140979239232854774
          }
       },
       "failure-ignored" : null,
       "no-comparison" : null,
       "succeeded" : {
-         "565/selftest1" : {
+         "565/selftest1.png" : {
             "bitmap-64bitMD5" : 12927999507540085554
          },
-         "8888/selftest1" : {
+         "8888/selftest1.png" : {
             "bitmap-64bitMD5" : 1209453360120438698
          }
       }
    },
    "expected-results" : {
-      "565/selftest1" : {
+      "565/selftest1.png" : {
          "allowed-bitmap-64bitMD5s" : [ 12927999507540085554 ],
          "ignore-failure" : false
       },
-      "8888/selftest1" : {
+      "8888/selftest1.png" : {
          "allowed-bitmap-64bitMD5s" : [ 1209453360120438698 ],
          "ignore-failure" : false
       },
-      "comparison/selftest1-pipe" : {
+      "comparison/selftest1-pipe.png" : {
          "allowed-bitmap-64bitMD5s" : [ 1209453360120438698 ],
          "ignore-failure" : false
       }
diff --git a/gm/tests/outputs/pipe-playback-failure/output-expected/stderr b/gm/tests/outputs/pipe-playback-failure/output-expected/stderr
index e65d374..573600f 100644
--- a/gm/tests/outputs/pipe-playback-failure/output-expected/stderr
+++ b/gm/tests/outputs/pipe-playback-failure/output-expected/stderr
@@ -1 +1 @@
-GM: ---- comparison/selftest1-pipe: 60000 (of 60000) differing pixels, max per-channel mismatch R=135 G=246 B=135 A=0
+GM: ---- comparison/selftest1-pipe.png: 60000 (of 60000) differing pixels, max per-channel mismatch R=135 G=246 B=135 A=0