diff options
Diffstat (limited to 'include/gtest')
-rw-r--r-- | include/gtest/gtest-printers.h | 56 | ||||
-rw-r--r-- | include/gtest/gtest.h | 90 |
2 files changed, 103 insertions, 43 deletions
diff --git a/include/gtest/gtest-printers.h b/include/gtest/gtest-printers.h index 0676269b..68e7eb1a 100644 --- a/include/gtest/gtest-printers.h +++ b/include/gtest/gtest-printers.h @@ -115,16 +115,23 @@ GTEST_API_ void PrintBytesInObjectTo(const unsigned char* obj_bytes, size_t count, ::std::ostream* os); -// TypeWithoutFormatter<T, kIsProto>::PrintValue(value, os) is called +// For selecting which printer to use when a given type has neither << +// nor PrintTo(). +enum TypeKind { + kProtobuf, // a protobuf type + kConvertibleToInteger, // a type implicitly convertible to BiggestInt + // (e.g. a named or unnamed enum type) + kOtherType, // anything else +}; + +// TypeWithoutFormatter<T, kTypeKind>::PrintValue(value, os) is called // by the universal printer to print a value of type T when neither -// operator<< nor PrintTo() is defined for type T. When T is -// ProtocolMessage, proto2::Message, or a subclass of those, kIsProto -// will be true and the short debug string of the protocol message -// value will be printed; otherwise kIsProto will be false and the -// bytes in the value will be printed. -template <typename T, bool kIsProto> +// operator<< nor PrintTo() is defined for T, where kTypeKind is the +// "kind" of T as defined by enum TypeKind. +template <typename T, TypeKind kTypeKind> class TypeWithoutFormatter { public: + // This default version is called when kTypeKind is kOtherType. static void PrintValue(const T& value, ::std::ostream* os) { PrintBytesInObjectTo(reinterpret_cast<const unsigned char*>(&value), sizeof(value), os); @@ -137,22 +144,39 @@ class TypeWithoutFormatter { const size_t kProtobufOneLinerMaxLength = 50; template <typename T> -class TypeWithoutFormatter<T, true> { +class TypeWithoutFormatter<T, kProtobuf> { public: static void PrintValue(const T& value, ::std::ostream* os) { const ::testing::internal::string short_str = value.ShortDebugString(); const ::testing::internal::string pretty_str = short_str.length() <= kProtobufOneLinerMaxLength ? short_str : ("\n" + value.DebugString()); - ::std::operator<<(*os, "<" + pretty_str + ">"); + *os << ("<" + pretty_str + ">"); + } +}; + +template <typename T> +class TypeWithoutFormatter<T, kConvertibleToInteger> { + public: + // Since T has no << operator or PrintTo() but can be implicitly + // converted to BiggestInt, we print it as a BiggestInt. + // + // Most likely T is an enum type (either named or unnamed), in which + // case printing it as an integer is the desired behavior. In case + // T is not an enum, printing it as an integer is the best we can do + // given that it has no user-defined printer. + static void PrintValue(const T& value, ::std::ostream* os) { + const internal::BiggestInt kBigInt = value; + *os << kBigInt; } }; // Prints the given value to the given ostream. If the value is a -// protocol message, its short debug string is printed; otherwise the -// bytes in the value are printed. This is what -// UniversalPrinter<T>::Print() does when it knows nothing about type -// T and T has no << operator. +// protocol message, its debug string is printed; if it's an enum or +// of a type implicitly convertible to BiggestInt, it's printed as an +// integer; otherwise the bytes in the value are printed. This is +// what UniversalPrinter<T>::Print() does when it knows nothing about +// type T and T has neither << operator nor PrintTo(). // // A user can override this behavior for a class type Foo by defining // a << operator in the namespace where Foo is defined. @@ -174,8 +198,10 @@ class TypeWithoutFormatter<T, true> { template <typename Char, typename CharTraits, typename T> ::std::basic_ostream<Char, CharTraits>& operator<<( ::std::basic_ostream<Char, CharTraits>& os, const T& x) { - TypeWithoutFormatter<T, ::testing::internal::IsAProtocolMessage<T>::value>:: - PrintValue(x, &os); + TypeWithoutFormatter<T, + (internal::IsAProtocolMessage<T>::value ? kProtobuf : + internal::ImplicitlyConvertible<const T&, internal::BiggestInt>::value ? + kConvertibleToInteger : kOtherType)>::PrintValue(x, &os); return os; } diff --git a/include/gtest/gtest.h b/include/gtest/gtest.h index af9d9e7c..20028a17 100644 --- a/include/gtest/gtest.h +++ b/include/gtest/gtest.h @@ -148,7 +148,6 @@ class ExecDeathTest; class NoExecDeathTest; class FinalSuccessChecker; class GTestFlagSaver; -class TestInfoImpl; class TestResultAccessor; class TestEventListenersAccessor; class TestEventRepeater; @@ -341,7 +340,7 @@ GTEST_API_ AssertionResult AssertionFailure(const Message& msg); // Test is not copyable. class GTEST_API_ Test { public: - friend class internal::TestInfoImpl; + friend class TestInfo; // Defines types for pointers to functions that set up and tear down // a test case. @@ -418,6 +417,10 @@ class GTEST_API_ Test { // Sets up, executes, and tears down the test. void Run(); + // Deletes self. We deliberately pick an unusual name for this + // internal method to avoid clashing with names used in user TESTs. + void DeleteSelf_() { delete this; } + // Uses a GTestFlagSaver to save and restore all Google Test flags. const internal::GTestFlagSaver* const gtest_flag_saver_; @@ -532,7 +535,6 @@ class GTEST_API_ TestResult { friend class UnitTest; friend class internal::DefaultGlobalTestPartResultReporter; friend class internal::ExecDeathTest; - friend class internal::TestInfoImpl; friend class internal::TestResultAccessor; friend class internal::UnitTestImpl; friend class internal::WindowsDeathTest; @@ -612,16 +614,16 @@ class GTEST_API_ TestInfo { ~TestInfo(); // Returns the test case name. - const char* test_case_name() const; + const char* test_case_name() const { return test_case_name_.c_str(); } // Returns the test name. - const char* name() const; + const char* name() const { return name_.c_str(); } // Returns the test case comment. - const char* test_case_comment() const; + const char* test_case_comment() const { return test_case_comment_.c_str(); } // Returns the test comment. - const char* comment() const; + const char* comment() const { return comment_.c_str(); } // Returns true if this test should run, that is if the test is not disabled // (or it is disabled but the also_run_disabled_tests flag has been specified) @@ -639,10 +641,10 @@ class GTEST_API_ TestInfo { // // For example, *A*:Foo.* is a filter that matches any string that // contains the character 'A' or starts with "Foo.". - bool should_run() const; + bool should_run() const { return should_run_; } // Returns the result of the test. - const TestResult* result() const; + const TestResult* result() const { return &result_; } private: #if GTEST_HAS_DEATH_TEST @@ -650,7 +652,6 @@ class GTEST_API_ TestInfo { #endif // GTEST_HAS_DEATH_TEST friend class Test; friend class TestCase; - friend class internal::TestInfoImpl; friend class internal::UnitTestImpl; friend TestInfo* internal::MakeAndRegisterTestInfo( const char* test_case_name, const char* name, @@ -660,17 +661,6 @@ class GTEST_API_ TestInfo { Test::TearDownTestCaseFunc tear_down_tc, internal::TestFactoryBase* factory); - // Returns true if this test matches the user-specified filter. - bool matches_filter() const; - - // Increments the number of death tests encountered in this test so - // far. - int increment_death_test_count(); - - // Accessors for the implementation object. - internal::TestInfoImpl* impl() { return impl_; } - const internal::TestInfoImpl* impl() const { return impl_; } - // Constructs a TestInfo object. The newly constructed instance assumes // ownership of the factory object. TestInfo(const char* test_case_name, const char* name, @@ -678,8 +668,36 @@ class GTEST_API_ TestInfo { internal::TypeId fixture_class_id, internal::TestFactoryBase* factory); - // An opaque implementation object. - internal::TestInfoImpl* impl_; + // Increments the number of death tests encountered in this test so + // far. + int increment_death_test_count() { + return result_.increment_death_test_count(); + } + + // Creates the test object, runs it, records its result, and then + // deletes it. + void Run(); + + static void ClearTestResult(TestInfo* test_info) { + test_info->result_.Clear(); + } + + // These fields are immutable properties of the test. + const std::string test_case_name_; // Test case name + const std::string name_; // Test name + const std::string test_case_comment_; // Test case comment + const std::string comment_; // Test comment + const internal::TypeId fixture_class_id_; // ID of the test fixture class + bool should_run_; // True iff this test should run + bool is_disabled_; // True iff this test is disabled + bool matches_filter_; // True if this test matches the + // user-specified filter. + internal::TestFactoryBase* const factory_; // The factory that creates + // the test object + + // This field is mutable and needs to be reset before running the + // test for the second time. + TestResult result_; GTEST_DISALLOW_COPY_AND_ASSIGN_(TestInfo); }; @@ -777,17 +795,33 @@ class GTEST_API_ TestCase { // Runs every test in this TestCase. void Run(); + // Runs SetUpTestCase() for this TestCase. This wrapper is needed + // for catching exceptions thrown from SetUpTestCase(). + void RunSetUpTestCase() { (*set_up_tc_)(); } + + // Runs TearDownTestCase() for this TestCase. This wrapper is + // needed for catching exceptions thrown from TearDownTestCase(). + void RunTearDownTestCase() { (*tear_down_tc_)(); } + // Returns true iff test passed. - static bool TestPassed(const TestInfo * test_info); + static bool TestPassed(const TestInfo* test_info) { + return test_info->should_run() && test_info->result()->Passed(); + } // Returns true iff test failed. - static bool TestFailed(const TestInfo * test_info); + static bool TestFailed(const TestInfo* test_info) { + return test_info->should_run() && test_info->result()->Failed(); + } // Returns true iff test is disabled. - static bool TestDisabled(const TestInfo * test_info); + static bool TestDisabled(const TestInfo* test_info) { + return test_info->is_disabled_; + } // Returns true if the given test should run. - static bool ShouldRunTest(const TestInfo *test_info); + static bool ShouldRunTest(const TestInfo* test_info) { + return test_info->should_run(); + } // Shuffles the tests in this test case. void ShuffleTests(internal::Random* random); @@ -962,10 +996,10 @@ class GTEST_API_ TestEventListeners { private: friend class TestCase; + friend class TestInfo; friend class internal::DefaultGlobalTestPartResultReporter; friend class internal::NoExecDeathTest; friend class internal::TestEventListenersAccessor; - friend class internal::TestInfoImpl; friend class internal::UnitTestImpl; // Returns repeater that broadcasts the TestEventListener events to all |