Index: base/test/nslog_test_event_listener.mm |
diff --git a/base/test/nslog_test_event_listener.mm b/base/test/nslog_test_event_listener.mm |
new file mode 100644 |
index 0000000000000000000000000000000000000000..b55554e9565f60d961ad12c53d710367cb9ba43d |
--- /dev/null |
+++ b/base/test/nslog_test_event_listener.mm |
@@ -0,0 +1,262 @@ |
+// Copyright 2012 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "base/test/nslog_test_event_listener.h" |
+ |
+#import <Foundation/Foundation.h> |
+ |
+#include "base/stringprintf.h" |
+#include "base/sys_info.h" |
+#include "testing/gtest/include/gtest/gtest.h" |
+ |
+using testing::internal::StreamableToString; |
+ |
+// The following static methods and TestEventListener implementation are largely |
+// copied from gtest.cc, but have been refactored such that output goes to NSLog |
+// instead of stdout (via printf). |
+ |
+NSString* PrintTestName(const char* test_case, const char* test) { |
+ return [NSString stringWithFormat:@"%s.%s", test_case, test]; |
+} |
+ |
+// Formats a countable noun. Depending on its quantity, either the |
+// singular form or the plural form is used. e.g. |
+// |
+// FormatCountableNoun(1, "formula", "formuli") returns "1 formula". |
+// FormatCountableNoun(5, "book", "books") returns "5 books". |
+static NSString* FormatCountableNoun(int count, |
+ NSString* singular_form, |
+ NSString* plural_form) { |
+ return [NSString stringWithFormat:@"%d %@", |
+ count, count == 1 ? singular_form : plural_form]; |
+} |
+ |
+static NSString* FormatTestCount(int test_count) { |
+ return FormatCountableNoun(test_count, @"test", @"tests"); |
+} |
+ |
+static NSString* FormatTestCaseCount(int test_case_count) { |
+ return FormatCountableNoun(test_case_count, @"test case", @"test cases"); |
+} |
+ |
+// Converts a TestPartResult::Type enum to human-friendly string |
+// representation. Both kNonFatalFailure and kFatalFailure are translated |
+// to "Failure", as the user usually doesn't care about the difference |
+// between the two when viewing the test result. |
+static const char* TestPartResultTypeToString( |
+ testing::TestPartResult::Type type) { |
+ switch (type) { |
+ case testing::TestPartResult::kSuccess: |
+ return "Success"; |
+ |
+ case testing::TestPartResult::kNonFatalFailure: |
+ case testing::TestPartResult::kFatalFailure: |
+ return "Failure\n"; |
+ default: |
+ return "Unknown result type"; |
+ } |
+} |
+ |
+// Prints a TestPartResult to an NSString*. |
+static NSString* PrintTestPartResultToString( |
+ const testing::TestPartResult& test_part_result) { |
+ std::string message = (testing::Message() |
+ << testing::internal::FormatFileLocation(test_part_result.file_name(), |
+ test_part_result.line_number()) |
+ << " " << TestPartResultTypeToString(test_part_result.type()) |
+ << test_part_result.message()).GetString(); |
+ return [NSString stringWithFormat:@"%s", message.c_str()]; |
+} |
+ |
+NSLogTestEventListener::NSLogTestEventListener() { |
+} |
+ |
+void NSLogTestEventListener::OnTestProgramStart( |
+ const testing::UnitTest& /*unit_test*/) { |
+} |
+ |
+// Fired before each iteration of tests starts. |
+void NSLogTestEventListener::OnTestIterationStart( |
+ const testing::UnitTest& unit_test, int iteration) { |
+ if (testing::GTEST_FLAG(repeat) != 1) { |
+ NSLog(@""); |
+ NSLog(@"Repeating all tests (iteration %d) . . .", iteration + 1); |
+ NSLog(@""); |
+ } |
+ |
+ if (testing::GTEST_FLAG(shuffle)) { |
+ NSLog(@"Note: Randomizing tests' orders with a seed of %d .", |
+ unit_test.random_seed()); |
+ } |
+ |
+ NSLog(@"[==========] Running %@ from %@.", |
+ FormatTestCount(unit_test.test_to_run_count()), |
+ FormatTestCaseCount(unit_test.test_case_to_run_count())); |
+} |
+ |
+void NSLogTestEventListener::OnEnvironmentsSetUpStart( |
+ const testing::UnitTest& /*unit_test*/) { |
+ NSLog(@"[----------] Global test environment set-up."); |
+} |
+ |
+void NSLogTestEventListener::OnEnvironmentsSetUpEnd( |
+ const testing::UnitTest& /*unit_test*/) { |
+} |
+ |
+void NSLogTestEventListener::OnTestCaseStart( |
+ const testing::TestCase& test_case) { |
+ NSString* counts = FormatTestCount(test_case.test_to_run_count()); |
+ NSString* output = [NSString stringWithFormat:@"[----------] %@ from %s", |
+ counts, test_case.name()]; |
+ if (test_case.type_param() != NULL) { |
+ output = [output stringByAppendingFormat:@", where TypeParam = %s", |
+ test_case.type_param()]; |
+ } |
+ NSLog(@"%@", output); |
+} |
+ |
+void NSLogTestEventListener::OnTestStart( |
+ const testing::TestInfo& test_info) { |
+ NSLog(@"[ RUN ] %@", |
+ PrintTestName(test_info.test_case_name(), test_info.name())); |
+} |
+ |
+// Called after an assertion failure. |
+void NSLogTestEventListener::OnTestPartResult( |
+ const testing::TestPartResult& result) { |
+ // If the test part succeeded, we don't need to do anything. |
+ if (result.type() == testing::TestPartResult::kSuccess) |
+ return; |
+ |
+ // Print failure message from the assertion (e.g. expected this and got that). |
+ NSLog(@"%@", PrintTestPartResultToString(result)); |
+} |
+ |
+void NSLogTestEventListener::OnTestEnd( |
+ const testing::TestInfo& test_info) { |
+ NSString* output = @""; |
+ if (test_info.result()->Passed()) { |
+ output = [output stringByAppendingString:@"[ OK ] "]; |
+ } else { |
+ output = [output stringByAppendingString:@"[ FAILED ] "]; |
+ } |
+ output = [output stringByAppendingString: |
+ PrintTestName(test_info.test_case_name(), test_info.name())]; |
+ if (test_info.result()->Failed()) |
+ output = [output stringByAppendingString: |
+ PrintFullTestCommentIfPresent(test_info)]; |
+ |
+ if (testing::GTEST_FLAG(print_time)) { |
+ output = [output stringByAppendingFormat:@" (%s ms)", |
+ StreamableToString(test_info.result()->elapsed_time()).c_str()]; |
+ } |
+ NSLog(@"%@", output); |
+} |
+ |
+void NSLogTestEventListener::OnTestCaseEnd( |
+ const testing::TestCase& test_case) { |
+ if (!testing::GTEST_FLAG(print_time)) return; |
+ |
+ NSString* counts = FormatTestCount(test_case.test_to_run_count()); |
+ NSLog(@"[----------] %@ from %s (%s ms total)", |
+ counts, test_case.name(), |
+ StreamableToString(test_case.elapsed_time()).c_str()); |
+ NSLog(@""); |
+} |
+ |
+void NSLogTestEventListener::OnEnvironmentsTearDownStart( |
+ const testing::UnitTest& /*unit_test*/) { |
+ NSLog(@"[----------] Global test environment tear-down"); |
+} |
+ |
+// Internal helper for printing the list of failed tests. |
+NSString* NSLogTestEventListener::PrintFailedTests( |
+ const testing::UnitTest& unit_test) { |
+ const int failed_test_count = unit_test.failed_test_count(); |
+ if (failed_test_count == 0) { |
+ return @""; |
+ } |
+ |
+ NSString* output = @""; |
+ for (int i = 0; i < unit_test.total_test_case_count(); ++i) { |
+ const testing::TestCase& test_case = *unit_test.GetTestCase(i); |
+ if (!test_case.should_run() || (test_case.failed_test_count() == 0)) { |
+ continue; |
+ } |
+ for (int j = 0; j < test_case.total_test_count(); ++j) { |
+ const testing::TestInfo& test_info = *test_case.GetTestInfo(j); |
+ if (!test_info.should_run() || test_info.result()->Passed()) { |
+ continue; |
+ } |
+ output = [output stringByAppendingFormat:@"[ FAILED ] %s.%s%@", |
+ test_case.name(), |
+ test_info.name(), |
+ PrintFullTestCommentIfPresent(test_info)]; |
+ } |
+ } |
+ return output; |
+} |
+ |
+void NSLogTestEventListener::OnEnvironmentsTearDownEnd( |
+ const testing::UnitTest& /*unit_test*/) { |
+} |
+ |
+NSString* NSLogTestEventListener::PrintFullTestCommentIfPresent( |
+ const testing::TestInfo& test_info) { |
+ const char* const type_param = test_info.type_param(); |
+ const char* const value_param = test_info.value_param(); |
+ |
+ NSString* comment = @""; |
+ if (type_param != NULL || value_param != NULL) { |
+ comment = [comment stringByAppendingString:@", where "]; |
+ if (type_param != NULL) { |
+ comment = [comment stringByAppendingFormat:@"TypeParam = %s", type_param]; |
+ if (value_param != NULL) |
+ comment = [comment stringByAppendingString:@" and "]; |
+ } |
+ if (value_param != NULL) { |
+ comment = [comment stringByAppendingFormat: |
+ @"GetParam() = %s", value_param]; |
+ } |
+ } |
+ return comment; |
+} |
+ |
+void NSLogTestEventListener::OnTestIterationEnd( |
+ const testing::UnitTest& unit_test, int /*iteration*/) { |
+ NSString* output = [NSString stringWithFormat:@"[==========] %@ from %@ ran.", |
+ FormatTestCount(unit_test.test_to_run_count()), |
+ FormatTestCaseCount(unit_test.test_case_to_run_count())]; |
+ if (testing::GTEST_FLAG(print_time)) { |
+ output = [output stringByAppendingFormat:@" (%s ms total)", |
+ StreamableToString(unit_test.elapsed_time()).c_str()]; |
+ } |
+ NSLog(@"%@", output); |
+ NSLog(@"[ PASSED ] %@.", |
+ FormatTestCount(unit_test.successful_test_count())); |
+ |
+ int num_failures = unit_test.failed_test_count(); |
+ if (!unit_test.Passed()) { |
+ const int failed_test_count = unit_test.failed_test_count(); |
+ NSLog(@"[ FAILED ] %@, listed below:", |
+ FormatTestCount(failed_test_count)); |
+ NSLog(@"%@", PrintFailedTests(unit_test)); |
+ NSLog(@""); |
+ NSLog(@"%2d FAILED %s", num_failures, num_failures == 1 ? "TEST" : "TESTS"); |
+ } |
+ |
+ int num_disabled = unit_test.disabled_test_count(); |
+ if (num_disabled && !testing::GTEST_FLAG(also_run_disabled_tests)) { |
+ if (!num_failures) { |
+ NSLog(@""); // Add a spacer if no FAILURE banner is displayed. |
+ } |
+ NSLog(@" YOU HAVE %d DISABLED %s", |
+ num_disabled, num_disabled == 1 ? "TEST" : "TESTS"); |
+ NSLog(@""); |
+ } |
+} |
+ |
+void NSLogTestEventListener::OnTestProgramEnd( |
+ const testing::UnitTest& /*unit_test*/) { |
+} |