pw_unit_test: Support disabled tests

- As in Google Test, unit tests can be disabled by prefixing the test
  name or suite name with DISABLED_.
- Emit an event when a disabled test is encountered.
- Use a TestCase object inside of a TestInfo.

Change-Id: Ife5af89f959074f8034bc8cec14b88fbed720ffa
diff --git a/pw_unit_test/framework.cc b/pw_unit_test/framework.cc
index 52e1147..5c2ba05 100644
--- a/pw_unit_test/framework.cc
+++ b/pw_unit_test/framework.cc
@@ -14,6 +14,8 @@
 
 #include "pw_unit_test/framework.h"
 
+#include <cstring>
+
 namespace pw::unit_test {
 
 void RegisterEventHandler(EventHandler* event_handler) {
@@ -21,6 +23,16 @@
 }
 
 namespace internal {
+namespace {
+
+bool TestIsEnabled(const TestInfo& test) {
+  constexpr size_t kStringSize = sizeof("DISABLED_") - 1;
+  return std::strncmp("DISABLED_", test.test_case.test_name, kStringSize) !=
+             0 &&
+         std::strncmp("DISABLED_", test.test_case.suite_name, kStringSize) != 0;
+}
+
+}  // namespace
 
 // Singleton instance of the unit test framework class.
 Framework Framework::framework_;
@@ -45,7 +57,11 @@
     event_handler_->RunAllTestsStart();
   }
   for (TestInfo* test = tests_; test != nullptr; test = test->next) {
-    test->run();
+    if (TestIsEnabled(*test)) {
+      test->run();
+    } else {
+      event_handler_->TestCaseDisabled(test->test_case);
+    }
   }
   if (event_handler_ != nullptr) {
     event_handler_->RunAllTestsEnd(run_tests_summary_);
@@ -60,15 +76,7 @@
   if (event_handler_ == nullptr) {
     return;
   }
-
-  const TestInfo* info = test->pigweed_test_info_;
-  TestCase test_case = {
-      .suite_name = info->test_suite_name,
-      .test_name = info->test_name,
-      .file_name = info->file_name,
-  };
-
-  event_handler_->TestCaseStart(test_case);
+  event_handler_->TestCaseStart(test->pigweed_test_info_->test_case);
 }
 
 void Framework::EndTest(Test* test) {
@@ -86,14 +94,8 @@
     return;
   }
 
-  const TestInfo* info = test->pigweed_test_info_;
-  TestCase test_case = {
-      .suite_name = info->test_suite_name,
-      .test_name = info->test_name,
-      .file_name = info->file_name,
-  };
-
-  event_handler_->TestCaseEnd(test_case, current_result_);
+  event_handler_->TestCaseEnd(test->pigweed_test_info_->test_case,
+                              current_result_);
 }
 
 void Framework::ExpectationResult(const char* expression,
@@ -109,13 +111,6 @@
     return;
   }
 
-  const TestInfo* info = current_test_->pigweed_test_info_;
-  TestCase test_case = {
-      .suite_name = info->test_suite_name,
-      .test_name = info->test_name,
-      .file_name = info->file_name,
-  };
-
   TestExpectation expectation = {
       .expression = expression,
       .evaluated_expression = evaluated_expression,
@@ -123,7 +118,8 @@
       .success = success,
   };
 
-  event_handler_->TestCaseExpect(test_case, expectation);
+  event_handler_->TestCaseExpect(current_test_->pigweed_test_info_->test_case,
+                                 expectation);
 }
 
 }  // namespace internal
diff --git a/pw_unit_test/logging_event_handler.cc b/pw_unit_test/logging_event_handler.cc
index bf7ba22..bd063a2 100644
--- a/pw_unit_test/logging_event_handler.cc
+++ b/pw_unit_test/logging_event_handler.cc
@@ -76,4 +76,8 @@
          expectation.evaluated_expression);
 }
 
+void LoggingEventHandler::TestCaseDisabled(const TestCase& test) {
+  PW_LOG_DEBUG("Skipping disabled test %s.%s", test.suite_name, test.test_name);
+}
+
 }  // namespace pw::unit_test
diff --git a/pw_unit_test/public/pw_unit_test/event_handler.h b/pw_unit_test/public/pw_unit_test/event_handler.h
index 60c7c27..b7b931d 100644
--- a/pw_unit_test/public/pw_unit_test/event_handler.h
+++ b/pw_unit_test/public/pw_unit_test/event_handler.h
@@ -106,6 +106,9 @@
   // provided.
   virtual void TestCaseEnd(const TestCase& test_case, TestResult result) = 0;
 
+  // Called when a disabled test case is encountered.
+  virtual void TestCaseDisabled(const TestCase&) {}
+
   // Called after each expect/assert statement within a test case with the
   // result of the expectation.
   virtual void TestCaseExpect(const TestCase& test_case,
diff --git a/pw_unit_test/public/pw_unit_test/framework.h b/pw_unit_test/public/pw_unit_test/framework.h
index 1283444..a74304b 100644
--- a/pw_unit_test/public/pw_unit_test/framework.h
+++ b/pw_unit_test/public/pw_unit_test/framework.h
@@ -288,21 +288,17 @@
            const char* const test_name,
            const char* const file_name,
            void (*run)())
-      : test_suite_name(test_suite_name),
-        test_name(test_name),
-        file_name(file_name),
-        run(run) {
+      : test_case{
+        .suite_name = test_suite_name,
+        .test_name = test_name,
+        .file_name = file_name,
+       }, run(run) {
     Framework::Get().RegisterTest(this);
   }
 
-  // Name of the suite to which the test case belongs.
-  const char* const test_suite_name;
-
-  // Name of the test case itself.
-  const char* const test_name;
-
-  // Path to the file in which the test case is located.
-  const char* const file_name;
+  // The name of the suite to which the test case belongs, the name of the test
+  // case itself, and the path to the file in which the test case is located.
+  TestCase test_case;
 
   // Function which runs the test case. Refers to Framework::CreateAndRunTest
   // instantiated for the test case's class.
diff --git a/pw_unit_test/public/pw_unit_test/logging_event_handler.h b/pw_unit_test/public/pw_unit_test/logging_event_handler.h
index 17b0829..b5a2bdc 100644
--- a/pw_unit_test/public/pw_unit_test/logging_event_handler.h
+++ b/pw_unit_test/public/pw_unit_test/logging_event_handler.h
@@ -30,6 +30,7 @@
   void TestCaseEnd(const TestCase& test_case, TestResult result) override;
   void TestCaseExpect(const TestCase& test_case,
                       const TestExpectation& expectation) override;
+  void TestCaseDisabled(const TestCase& test_case) override;
 
  private:
   bool verbose_;
diff --git a/pw_unit_test/public/pw_unit_test/simple_printing_event_handler.h b/pw_unit_test/public/pw_unit_test/simple_printing_event_handler.h
index c3eb15a..e329915 100644
--- a/pw_unit_test/public/pw_unit_test/simple_printing_event_handler.h
+++ b/pw_unit_test/public/pw_unit_test/simple_printing_event_handler.h
@@ -50,6 +50,7 @@
   void TestCaseEnd(const TestCase& test_case, TestResult result) override;
   void TestCaseExpect(const TestCase& test_case,
                       const TestExpectation& expectation) override;
+  void TestCaseDisabled(const TestCase& test_case) override;
 
  private:
   void WriteLine(const char* format, ...) PW_PRINTF_FORMAT(2, 3);
diff --git a/pw_unit_test/simple_printing_event_handler.cc b/pw_unit_test/simple_printing_event_handler.cc
index dfa01a6..ab5cd74 100644
--- a/pw_unit_test/simple_printing_event_handler.cc
+++ b/pw_unit_test/simple_printing_event_handler.cc
@@ -76,4 +76,10 @@
   write_(buffer_, true);
 }
 
+void SimplePrintingEventHandler::TestCaseDisabled(const TestCase& test) {
+  if (verbose_) {
+    WriteLine("Skipping disabled test %s.%s", test.suite_name, test.test_name);
+  }
+}
+
 }  // namespace pw::unit_test