Merge "Add a method to sanitize a string to be used as test name" am: c98f3763e3
am: cea29d2783

Change-Id: I6fd4f2bb3276052f19b532ad66b2c757b6b94fae
diff --git a/gtest_helper/hidl/GtestPrinter.h b/gtest_helper/hidl/GtestPrinter.h
index c9f5dd3..4b5ac2d 100644
--- a/gtest_helper/hidl/GtestPrinter.h
+++ b/gtest_helper/hidl/GtestPrinter.h
@@ -19,18 +19,40 @@
 namespace android {
 namespace hardware {
 
-static inline std::string PrintInstanceNameToString(
-        const testing::TestParamInfo<std::string>& info) {
-    // test names need to be unique -> index prefix
-    std::string name = std::to_string(info.index) + "/" + info.param;
-
+static inline std::string Sanitize(std::string name) {
     for (size_t i = 0; i < name.size(); i++) {
         // gtest test names must only contain alphanumeric characters
         if (!std::isalnum(name[i])) name[i] = '_';
     }
-
     return name;
 }
 
+static inline std::string PrintInstanceNameToString(
+        const testing::TestParamInfo<std::string>& info) {
+    // test names need to be unique -> index prefix
+    std::string name = std::to_string(info.index) + "/" + info.param;
+    return Sanitize(name);
+}
+
+template <typename... T>
+static inline std::string PrintInstanceTupleNameToString(
+        const testing::TestParamInfo<std::tuple<T...>>& info) {
+    std::vector<std::string> instances = std::apply(
+            [](auto&&... elems) {
+                std::vector<std::string> instances;
+                instances.reserve(sizeof...(elems));
+                (instances.push_back(std::forward<decltype(elems)>(elems)), ...);
+                return instances;
+            },
+            info.param);
+    std::string param_string;
+    for (const std::string& instance : instances) {
+        param_string += instance + "_";
+    }
+    param_string += std::to_string(info.index);
+
+    return Sanitize(param_string);
+}
+
 }  // namespace hardware
 }  // namespace android