diff options
Diffstat (limited to 'QA/Checker')
-rw-r--r-- | QA/Checker/CppUnitTestResultPrinter.cpp | 142 | ||||
-rw-r--r-- | QA/Checker/CppUnitTestResultPrinter.h | 58 | ||||
-rw-r--r-- | QA/Checker/SConscript | 2 | ||||
-rw-r--r-- | QA/Checker/checker.cpp | 7 |
4 files changed, 208 insertions, 1 deletions
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 @@ -1,24 +1,24 @@ import os Import("env") if env["TEST"] : if env["SCONS_STAGE"] == "flags" : env["CHECKER_FLAGS"] = { "LIBS": ["Checker"], "LIBPATH": [Dir(".")], "LINKFLAGS": env["PLATFORM"] == "win32" and ["/SUBSYSTEM:CONSOLE"] or [] } if os.path.basename(env["CC"]).startswith(("clang", "gcc")): env["CHECKER_FLAGS"]["CPPFLAGS"] = ["-isystem" + Dir("#/3rdParty/HippoMocks").abspath] else : env["CHECKER_FLAGS"]["CPPPATH"] = ["#/3rdParty/HippoMocks"] if env["SCONS_STAGE"] == "build" : checker_env = env.Clone() checker_env.UseFlags(env["SWIFTEN_FLAGS"]) 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 @@ -1,42 +1,43 @@ /* * Copyright (c) 2010-2017 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #include <cstdlib> #include <fstream> #include <string> #include <sstream> #include <gtest/gtest.h> +#include <QA/Checker/CppUnitTestResultPrinter.h> #include <cppunit/BriefTestProgressListener.h> #include <cppunit/TextOutputter.h> #include <cppunit/TextTestProgressListener.h> #include <cppunit/TextTestResult.h> #include <cppunit/XmlOutputter.h> #include <cppunit/extensions/TestFactoryRegistry.h> #include <cppunit/ui/text/TestRunner.h> #include <Swiften/Base/Log.h> using Swift::Log; int main(int argc, char* argv[]) { bool verbose = false; bool outputXML = false; Log::setLogLevel(Swift::Log::error); // Parse parameters std::vector<std::string> testsToRun; for (int i = 1; i < argc; ++i) { std::string param(argv[i]); if (param == "--verbose") { verbose = true; } else if (param == "--xml") { outputXML = true; } else if (param == "--debug") { @@ -99,40 +100,46 @@ int main(int argc, char* argv[]) { for (std::vector<std::string>::const_iterator i = testsToRun.begin(); i != testsToRun.end(); ++i) { try { runner.run(controller, *i); } catch (const std::exception& e) { std::cerr << "Error: " << e.what() << std::endl; return -1; } } // Output the results if (outputXML) { std::ofstream cppUnitXUnitOutputFile; cppUnitXUnitOutputFile.open(cppunitOutputFilename, std::ofstream::out | std::ofstream::trunc); if (cppUnitXUnitOutputFile.is_open()) { CppUnit::XmlOutputter outputter(&result, cppUnitXUnitOutputFile); outputter.write(); } else { std::cerr << "Failed to overwrite " << cppunitOutputFilename << " output file." << std::endl; return 1; } } else { CppUnit::TextOutputter outputter(&result, std::cerr); outputter.write(); } 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; SWIFT_LOG(error) << "GoogleTestFailureException was thrown: " << e.what() << std::endl; } auto cppUnitWasSuccessful = result.wasSuccessful() ? true : false; return (googleTestWasSuccessful && cppUnitWasSuccessful) ? 0 : 1; } |