Add support for skipped tests.

This was a bit tricky because it's necessary to parse the output of
a passing test to verify if a test has been skipped or not.

In addition, I implemented this slightly differently from gtest, I
output the message printed from the GTEST_SKIP macro since that seem
like the write thing to do.

Bug: 128034200

Test: New unit tests that pass, added skipped tests to some suites and
Test: verified they are listed as skipped.
Change-Id: I7a5538b9344b9883fbabeba5c4467fd5bd5446e0
diff --git a/Isolate.cpp b/Isolate.cpp
index 58283fd..227a875 100644
--- a/Isolate.cpp
+++ b/Isolate.cpp
@@ -267,7 +267,9 @@
           test->AppendOutput(output);
           test->set_result(TEST_FAIL);
         } else {
-          test->set_result(TEST_PASS);
+          // Set the result based on the output, since skipped tests and
+          // passing tests have the same exit status.
+          test->SetResultFromOutput();
         }
       }
     } else if (test->result() == TEST_TIMEOUT) {
@@ -308,6 +310,9 @@
       case TEST_XFAIL:
         total_xfail_tests_++;
         break;
+      case TEST_SKIPPED:
+        total_skipped_tests_++;
+        break;
       case TEST_NONE:
         LOG(FATAL) << "Test result is TEST_NONE, this should not be possible.";
     }
@@ -381,6 +386,7 @@
   total_xfail_tests_ = 0;
   total_timeout_tests_ = 0;
   total_slow_tests_ = 0;
+  total_skipped_tests_ = 0;
 
   running_by_test_index_.clear();
 
@@ -415,7 +421,11 @@
 
 void Isolate::PrintResults(size_t total, const ResultsType& results, std::string* footer) {
   ColoredPrintf(results.color, results.prefix);
-  printf(" %s %s, listed below:\n", PluralizeString(total, " test").c_str(), results.list_desc);
+  if (results.list_desc != nullptr) {
+    printf(" %s %s, listed below:\n", PluralizeString(total, " test").c_str(), results.list_desc);
+  } else {
+    printf(" %s, listed below:\n", PluralizeString(total, " test").c_str());
+  }
   for (const auto& entry : finished_) {
     const Test* test = entry.second.get();
     if (results.match_func(*test)) {
@@ -427,6 +437,11 @@
       printf("\n");
     }
   }
+
+  if (results.title == nullptr) {
+    return;
+  }
+
   if (total < 10) {
     *footer += ' ';
   }
@@ -477,6 +492,15 @@
         },
 };
 
+Isolate::ResultsType Isolate::SkippedResults = {
+    .color = COLOR_GREEN,
+    .prefix = "[  SKIPPED ]",
+    .list_desc = nullptr,
+    .title = nullptr,
+    .match_func = [](const Test& test) { return test.result() == TEST_SKIPPED; },
+    .print_func = nullptr,
+};
+
 void Isolate::PrintFooter(uint64_t elapsed_time_ns) {
   ColoredPrintf(COLOR_GREEN, "[==========]");
   printf(" %s from %s ran. (%" PRId64 " ms total)\n",
@@ -491,6 +515,12 @@
   printf("\n");
 
   std::string footer;
+
+  // Tests that were skipped.
+  if (total_skipped_tests_ != 0) {
+    PrintResults(total_skipped_tests_, SkippedResults, &footer);
+  }
+
   // Tests that ran slow.
   if (total_slow_tests_ != 0) {
     PrintResults(total_slow_tests_, SlowResults, &footer);
@@ -699,7 +729,7 @@
       WriteXmlResults(time_ns, start_time);
     }
 
-    if (total_pass_tests_ + total_xfail_tests_ != tests_.size()) {
+    if (total_pass_tests_ + total_skipped_tests_ + total_xfail_tests_ != tests_.size()) {
       exit_code = 1;
     }
   }