From 1b678a155adca8957866e016b0e344eee6290466 Mon Sep 17 00:00:00 2001
From: Thanos Doukoudakis <thanos.doukoudakis@isode.com>
Date: Fri, 16 Jun 2017 11:45:03 +0100
Subject: Make gtest output more compact

This patch will make the checker test application output to use a custom
printer for google test results. The output will be less verbose, and
similar to the output of CppUnit. If the --verbose flag is used, the
default printer will be used instead.

Test-information:
Tested on Windows 10 and Ubuntu 16.04.

Change-Id: I1488cf576ab07da03b0dfcc93a48a8518d5afc06

diff --git a/COPYING.thirdparty b/COPYING.thirdparty
index 0134aaa..35cad47 100644
--- a/COPYING.thirdparty
+++ b/COPYING.thirdparty
@@ -97,7 +97,7 @@ with others.
 
 The OFL allows the licensed fonts to be used, studied, modified and
 redistributed freely as long as they are not sold by themselves. The
-fonts, including any derivative works, can be bundled, embedded, 
+fonts, including any derivative works, can be bundled, embedded,
 redistributed and/or sold with any software provided that any reserved
 names are not used by derivative works. The fonts and derivatives,
 however, cannot be released under any other type of license. The
@@ -262,6 +262,46 @@ SUCH DAMAGE.
 
 --- END OF SOLARIS getifaddrs() LICENSE
 
+===========
+Google Test
+===========
+
+The checker application uses QA\Checker\CppUnitTestResultPrinter.cpp file
+which incorporates PrettyUnitTestResultPrinter class from gtest.cc under the following license:
+
+// Copyright 2005, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: wan@google.com (Zhanyong Wan)
+//
+// The Google C++ Testing Framework (Google Test)
+
 =========
 Trolltech
 =========
diff --git a/QA/Checker/CppUnitTestResultPrinter.cpp b/QA/Checker/CppUnitTestResultPrinter.cpp
new file mode 100644
index 0000000..475411b
--- /dev/null
+++ b/QA/Checker/CppUnitTestResultPrinter.cpp
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 2017 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+ // Copyright 2005, Google Inc.
+ // All rights reserved.
+ //
+ // Redistribution and use in source and binary forms, with or without
+ // modification, are permitted provided that the following conditions are
+ // met:
+ //
+ //     * Redistributions of source code must retain the above copyright
+ // notice, this list of conditions and the following disclaimer.
+ //     * Redistributions in binary form must reproduce the above
+ // copyright notice, this list of conditions and the following disclaimer
+ // in the documentation and/or other materials provided with the
+ // distribution.
+ //     * Neither the name of Google Inc. nor the names of its
+ // contributors may be used to endorse or promote products derived from
+ // this software without specific prior written permission.
+ //
+ // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ //
+ // Author: wan@google.com (Zhanyong Wan)
+ //
+ // The Google C++ Testing Framework (Google Test)
+
+#include <QA/Checker/CppUnitTestResultPrinter.h>
+
+namespace testing {
+
+    namespace internal {
+        enum GTestColor {
+            COLOR_DEFAULT,
+            COLOR_RED,
+            COLOR_GREEN,
+            COLOR_YELLOW
+        };
+        void ColoredPrintf(GTestColor color, const char* fmt, ...);
+    }
+
+using namespace internal;
+
+static std::string PrintTestPartResultToString(const TestPartResult& testPartResult) {
+    return (Message() << internal::FormatFileLocation(testPartResult.file_name(), testPartResult.line_number())
+        << " " << (testPartResult.type() == TestPartResult::Type::kSuccess ? "Success" : "Failure") << std::endl << testPartResult.message()).GetString();
+}
+
+void CppUnitTestResultPrinter::OnTestIterationStart(const UnitTest& unitTest, int iteration) {
+    if (GTEST_FLAG(repeat) != 1) {
+        std::cout << std::endl << "Repeating all tests (iteration" << iteration + 1 << ") . . ." << std::endl << std::endl;
+    }
+    const char* const filter = GTEST_FLAG(filter).c_str();
+    if (!String::CStringEquals(filter, "*")) {
+        ColoredPrintf(COLOR_YELLOW, "Note: %s filter = %s\n", GTEST_NAME_, filter);
+    }
+    if (GTEST_FLAG(shuffle)) {
+        ColoredPrintf(COLOR_YELLOW, "Note: Randomizing tests' orders with a seed of %d .\n", unitTest.random_seed());
+    }
+    ColoredPrintf(COLOR_GREEN, "[==========] ");
+    std::cout << "Running " << unitTest.test_to_run_count() << " test(s) from " << unitTest.test_case_to_run_count() << " test case(s)" << std::endl;
+    fflush(stdout);
+}
+
+void CppUnitTestResultPrinter::OnTestPartResult(const TestPartResult& testPartResult) {
+    if (testPartResult.failed()) {
+        assertionsFailures_ << PrintTestPartResultToString(testPartResult) << std::endl;
+    }
+}
+
+void CppUnitTestResultPrinter::OnTestEnd(const TestInfo& testInfo) {
+    if (testInfo.result()->Passed()) {
+        ColoredPrintf(COLOR_GREEN, ".");
+    }
+    else {
+        ColoredPrintf(COLOR_RED, "F");
+        testFailures_ << std::endl << testInfo.name() << "." << testInfo.test_case_name() << std::endl << assertionsFailures_.rdbuf();
+        assertionsFailures_.clear();
+    }
+}
+
+void CppUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unitTest, int) {
+    ColoredPrintf(COLOR_GREEN, "\n[==========] ");
+    std::cout << unitTest.test_to_run_count() << " test(s) from " << unitTest.test_case_to_run_count() << " test case(s) ran. ";
+    if (GTEST_FLAG(print_time)) {
+        std::cout << "(" << StreamableToString(unitTest.elapsed_time()).c_str() << " ms total)";
+    }
+    ColoredPrintf(COLOR_GREEN, "\n[  PASSED  ] ");
+    std::cout << unitTest.successful_test_count() << std::endl;
+
+    int num_failures = unitTest.failed_test_count();
+    if (!unitTest.Passed()) {
+        ColoredPrintf(COLOR_RED, "[  FAILED  ] ");
+        std::cout << unitTest.failed_test_count() << " test(s), listed below:" << std::endl;
+        PrintFailedTests(unitTest);
+        std::cout << std::endl << num_failures << " FAILED " << ((num_failures == 1) ? "TEST" : "TESTS") << std::endl;
+    }
+    int num_disabled = unitTest.reportable_disabled_test_count();
+    if (num_disabled && !GTEST_FLAG(also_run_disabled_tests)) {
+        if (!num_failures) {
+            std::cout << std::endl;
+        }
+        std::cout << num_disabled << " test(s) were disabled." << std::endl << std::endl;
+    }
+    std::cout << testFailures_.rdbuf();
+    fflush(stdout);
+}
+
+// Internal helper for printing the list of failed tests.
+void CppUnitTestResultPrinter::PrintFailedTests(const UnitTest& unitTest) {
+    if (unitTest.failed_test_count() == 0) {
+        return;
+    }
+    for (int i = 0; i < unitTest.total_test_case_count(); ++i) {
+        const TestCase& testCase = *unitTest.GetTestCase(i);
+        if (!testCase.should_run() || (testCase.failed_test_count() == 0)) {
+            continue;
+        }
+        for (int j = 0; j < testCase.total_test_count(); ++j) {
+            const TestInfo& testInfo = *testCase.GetTestInfo(j);
+            if (!testInfo.should_run() || testInfo.result()->Passed()) {
+                continue;
+            }
+            ColoredPrintf(COLOR_RED, "[  FAILED  ] ");
+            std::cout << testCase.name() << "." << testInfo.name() << std::endl;
+        }
+    }
+}
+
+}
diff --git a/QA/Checker/CppUnitTestResultPrinter.h b/QA/Checker/CppUnitTestResultPrinter.h
new file mode 100644
index 0000000..8e09243
--- /dev/null
+++ b/QA/Checker/CppUnitTestResultPrinter.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2017 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+ // Copyright 2005, Google Inc.
+ // All rights reserved.
+ //
+ // Redistribution and use in source and binary forms, with or without
+ // modification, are permitted provided that the following conditions are
+ // met:
+ //
+ //     * Redistributions of source code must retain the above copyright
+ // notice, this list of conditions and the following disclaimer.
+ //     * Redistributions in binary form must reproduce the above
+ // copyright notice, this list of conditions and the following disclaimer
+ // in the documentation and/or other materials provided with the
+ // distribution.
+ //     * Neither the name of Google Inc. nor the names of its
+ // contributors may be used to endorse or promote products derived from
+ // this software without specific prior written permission.
+ //
+ // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ //
+ // Author: wan@google.com (Zhanyong Wan)
+ //
+ // The Google C++ Testing Framework (Google Test)
+
+#pragma once
+
+#include <gtest/gtest.h>
+
+namespace testing {
+
+    //CppUnitTestResultPrinter is based on PrettyUnitTestResultPrinter from the google test suite
+    class CppUnitTestResultPrinter : public ::testing::EmptyTestEventListener {
+    public:
+        virtual void OnTestIterationStart(const ::testing::UnitTest& unitTest, int iteration);
+        virtual void OnTestPartResult(const ::testing::TestPartResult& testPartResult);
+        virtual void OnTestEnd(const ::testing::TestInfo& test_info);
+        virtual void OnTestIterationEnd(const ::testing::UnitTest& unitTest, int);
+    private:
+        static void PrintFailedTests(const ::testing::UnitTest& unitTest);
+        std::stringstream assertionsFailures_;
+        std::stringstream testFailures_;
+    };
+}
diff --git a/QA/Checker/SConscript b/QA/Checker/SConscript
index a41a5f9..70458f0 100644
--- a/QA/Checker/SConscript
+++ b/QA/Checker/SConscript
@@ -21,4 +21,4 @@ if env["TEST"] :
             checker_env.UseFlags(env["BOOST_FLAGS"])
             checker_env.UseFlags(env["CPPUNIT_FLAGS"])
             checker_env.UseFlags(env["GOOGLETEST_FLAGS"])
-            checker_env.Library("Checker", ["checker.cpp", "IO.cpp"])
+            checker_env.Library("Checker", ["checker.cpp", "IO.cpp", "CppUnitTestResultPrinter.cpp"])
diff --git a/QA/Checker/checker.cpp b/QA/Checker/checker.cpp
index bcf0f5c..3cc7713 100644
--- a/QA/Checker/checker.cpp
+++ b/QA/Checker/checker.cpp
@@ -10,6 +10,7 @@
 #include <sstream>
 
 #include <gtest/gtest.h>
+#include <QA/Checker/CppUnitTestResultPrinter.h>
 
 #include <cppunit/BriefTestProgressListener.h>
 #include <cppunit/TextOutputter.h>
@@ -126,6 +127,12 @@ int main(int argc, char* argv[]) {
 
     auto googleTestWasSuccessful = false;
     try {
+        if (!verbose) {
+            testing::UnitTest& unitTest = *testing::UnitTest::GetInstance();
+            testing::TestEventListeners& listeners = unitTest.listeners();
+            delete listeners.Release(listeners.default_result_printer());
+            listeners.Append(new testing::CppUnitTestResultPrinter);
+        }
         googleTestWasSuccessful = RUN_ALL_TESTS() == 0 ? true : false;
     } catch (const ::testing::internal::GoogleTestFailureException& e) {
         googleTestWasSuccessful = false;
-- 
cgit v0.10.2-6-g49f6