From d201456903f3ecae1f7794edfab0d5678e642265 Mon Sep 17 00:00:00 2001 From: shiqian Date: Thu, 3 Jul 2008 22:38:12 +0000 Subject: Initial import. --- test/gtest-death-test_test.cc | 862 ++++++ test/gtest-filepath_test.cc | 369 +++ test/gtest-message_test.cc | 157 ++ test/gtest-options_test.cc | 122 + test/gtest_break_on_failure_unittest.py | 178 ++ test/gtest_break_on_failure_unittest_.cc | 59 + test/gtest_color_test.py | 123 + test/gtest_color_test_.cc | 68 + test/gtest_env_var_test.py | 134 + test/gtest_env_var_test_.cc | 111 + test/gtest_environment_test.cc | 186 ++ test/gtest_filter_unittest.py | 315 +++ test/gtest_filter_unittest_.cc | 90 + test/gtest_list_tests_unittest.py | 165 ++ test/gtest_list_tests_unittest_.cc | 87 + test/gtest_main_unittest.cc | 45 + test/gtest_nc.cc | 115 + test/gtest_nc_test.py | 77 + test/gtest_no_test_unittest.cc | 54 + test/gtest_output_test.py | 183 ++ test/gtest_output_test_.cc | 755 ++++++ test/gtest_output_test_golden_lin.txt | 383 +++ test/gtest_output_test_golden_win.txt | 415 +++ test/gtest_pred_impl_unittest.cc | 2432 +++++++++++++++++ test/gtest_prod_test.cc | 57 + test/gtest_repeat_test.cc | 223 ++ test/gtest_stress_test.cc | 122 + test/gtest_test_utils.py | 106 + test/gtest_uninitialized_test.py | 110 + test/gtest_uninitialized_test_.cc | 43 + test/gtest_unittest.cc | 4299 ++++++++++++++++++++++++++++++ test/gtest_xml_outfile1_test_.cc | 49 + test/gtest_xml_outfile2_test_.cc | 49 + test/gtest_xml_outfiles_test.py | 134 + test/gtest_xml_output_unittest.py | 171 ++ test/gtest_xml_output_unittest_.cc | 120 + test/gtest_xml_test_utils.py | 138 + test/production.cc | 36 + test/production.h | 55 + 39 files changed, 13197 insertions(+) create mode 100644 test/gtest-death-test_test.cc create mode 100644 test/gtest-filepath_test.cc create mode 100644 test/gtest-message_test.cc create mode 100644 test/gtest-options_test.cc create mode 100755 test/gtest_break_on_failure_unittest.py create mode 100644 test/gtest_break_on_failure_unittest_.cc create mode 100755 test/gtest_color_test.py create mode 100644 test/gtest_color_test_.cc create mode 100755 test/gtest_env_var_test.py create mode 100644 test/gtest_env_var_test_.cc create mode 100644 test/gtest_environment_test.cc create mode 100755 test/gtest_filter_unittest.py create mode 100644 test/gtest_filter_unittest_.cc create mode 100755 test/gtest_list_tests_unittest.py create mode 100644 test/gtest_list_tests_unittest_.cc create mode 100644 test/gtest_main_unittest.cc create mode 100644 test/gtest_nc.cc create mode 100755 test/gtest_nc_test.py create mode 100644 test/gtest_no_test_unittest.cc create mode 100755 test/gtest_output_test.py create mode 100644 test/gtest_output_test_.cc create mode 100644 test/gtest_output_test_golden_lin.txt create mode 100644 test/gtest_output_test_golden_win.txt create mode 100644 test/gtest_pred_impl_unittest.cc create mode 100644 test/gtest_prod_test.cc create mode 100644 test/gtest_repeat_test.cc create mode 100644 test/gtest_stress_test.cc create mode 100755 test/gtest_test_utils.py create mode 100755 test/gtest_uninitialized_test.py create mode 100644 test/gtest_uninitialized_test_.cc create mode 100644 test/gtest_unittest.cc create mode 100644 test/gtest_xml_outfile1_test_.cc create mode 100644 test/gtest_xml_outfile2_test_.cc create mode 100755 test/gtest_xml_outfiles_test.py create mode 100755 test/gtest_xml_output_unittest.py create mode 100644 test/gtest_xml_output_unittest_.cc create mode 100755 test/gtest_xml_test_utils.py create mode 100644 test/production.cc create mode 100644 test/production.h (limited to 'test') diff --git a/test/gtest-death-test_test.cc b/test/gtest-death-test_test.cc new file mode 100644 index 00000000..4e4ca1a2 --- /dev/null +++ b/test/gtest-death-test_test.cc @@ -0,0 +1,862 @@ +// 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) +// +// Tests for death tests. + +#include +#include + +#ifdef GTEST_HAS_DEATH_TEST + +#include + +// Indicates that this translation unit is part of Google Test's +// implementation. It must come before gtest-internal-inl.h is +// included, or there will be a compiler error. This trick is to +// prevent a user from accidentally including gtest-internal-inl.h in +// his code. +#define GTEST_IMPLEMENTATION +#include "src/gtest-internal-inl.h" +#undef GTEST_IMPLEMENTATION + +using testing::internal::DeathTest; +using testing::internal::DeathTestFactory; + +namespace testing { +namespace internal { + +// A helper class whose objects replace the death test factory for a +// single UnitTest object during their lifetimes. +class ReplaceDeathTestFactory { + public: + ReplaceDeathTestFactory(UnitTest* parent, DeathTestFactory* new_factory) + : parent_impl_(parent->impl()) { + old_factory_ = parent_impl_->death_test_factory_.release(); + parent_impl_->death_test_factory_.reset(new_factory); + } + + ~ReplaceDeathTestFactory() { + parent_impl_->death_test_factory_.release(); + parent_impl_->death_test_factory_.reset(old_factory_); + } + private: + // Prevents copying ReplaceDeathTestFactory objects. + ReplaceDeathTestFactory(const ReplaceDeathTestFactory&); + void operator=(const ReplaceDeathTestFactory&); + + UnitTestImpl* parent_impl_; + DeathTestFactory* old_factory_; +}; + +} // namespace internal +} // namespace testing + +// Tests that death tests work. + +class TestForDeathTest : public testing::Test { + protected: + // A static member function that's expected to die. + static void StaticMemberFunction() { + GTEST_LOG(FATAL, "death inside StaticMemberFunction()."); + } + + // A method of the test fixture that may die. + void MemberFunction() { + if (should_die_) { + GTEST_LOG(FATAL, "death inside MemberFunction()."); + } + } + + // True iff MemberFunction() should die. + bool should_die_; +}; + +// A class with a member function that may die. +class MayDie { + public: + explicit MayDie(bool should_die) : should_die_(should_die) {} + + // A member function that may die. + void MemberFunction() const { + if (should_die_) { + GTEST_LOG(FATAL, "death inside MayDie::MemberFunction()."); + } + } + + private: + // True iff MemberFunction() should die. + bool should_die_; +}; + +// A global function that's expected to die. +void GlobalFunction() { + GTEST_LOG(FATAL, "death inside GlobalFunction()."); +} + +// A non-void function that's expected to die. +int NonVoidFunction() { + GTEST_LOG(FATAL, "death inside NonVoidFunction()."); + return 1; +} + +// A unary function that may die. +void DieIf(bool should_die) { + if (should_die) { + GTEST_LOG(FATAL, "death inside DieIf()."); + } +} + +// A binary function that may die. +bool DieIfLessThan(int x, int y) { + if (x < y) { + GTEST_LOG(FATAL, "death inside DieIfLessThan()."); + } + return true; +} + +// Tests that ASSERT_DEATH can be used outside a TEST, TEST_F, or test fixture. +void DeathTestSubroutine() { + EXPECT_DEATH(GlobalFunction(), "death.*GlobalFunction"); + ASSERT_DEATH(GlobalFunction(), "death.*GlobalFunction"); +} + +// Death in dbg, not opt. +int DieInDebugElse12(int* sideeffect) { + if (sideeffect) *sideeffect = 12; +#ifndef NDEBUG + GTEST_LOG(FATAL, "debug death inside DieInDebugElse12()"); +#endif // NDEBUG + return 12; +} + +// Returns the exit status of a process that calls exit(2) with a +// given exit code. This is a helper function for the +// ExitStatusPredicateTest test suite. +static int NormalExitStatus(int exit_code) { + pid_t child_pid = fork(); + if (child_pid == 0) { + exit(exit_code); + } + int status; + waitpid(child_pid, &status, 0); + return status; +} + +// Returns the exit status of a process that raises a given signal. +// If the signal does not cause the process to die, then it returns +// instead the exit status of a process that exits normally with exit +// code 1. This is a helper function for the ExitStatusPredicateTest +// test suite. +static int KilledExitStatus(int signum) { + pid_t child_pid = fork(); + if (child_pid == 0) { + raise(signum); + exit(1); + } + int status; + waitpid(child_pid, &status, 0); + return status; +} + +// Tests the ExitedWithCode predicate. +TEST(ExitStatusPredicateTest, ExitedWithCode) { + const int status0 = NormalExitStatus(0); + const int status1 = NormalExitStatus(1); + const int status42 = NormalExitStatus(42); + const testing::ExitedWithCode pred0(0); + const testing::ExitedWithCode pred1(1); + const testing::ExitedWithCode pred42(42); + EXPECT_PRED1(pred0, status0); + EXPECT_PRED1(pred1, status1); + EXPECT_PRED1(pred42, status42); + EXPECT_FALSE(pred0(status1)); + EXPECT_FALSE(pred42(status0)); + EXPECT_FALSE(pred1(status42)); +} + +// Tests the KilledBySignal predicate. +TEST(ExitStatusPredicateTest, KilledBySignal) { + const int status_segv = KilledExitStatus(SIGSEGV); + const int status_kill = KilledExitStatus(SIGKILL); + const testing::KilledBySignal pred_segv(SIGSEGV); + const testing::KilledBySignal pred_kill(SIGKILL); + EXPECT_PRED1(pred_segv, status_segv); + EXPECT_PRED1(pred_kill, status_kill); + EXPECT_FALSE(pred_segv(status_kill)); + EXPECT_FALSE(pred_kill(status_segv)); +} + +// Tests that the death test macros expand to code which may or may not +// be followed by operator<<, and that in either case the complete text +// comprises only a single C++ statement. +TEST_F(TestForDeathTest, SingleStatement) { + if (false) + // This would fail if executed; this is a compilation test only + ASSERT_DEATH(return, ""); + + if (true) + EXPECT_DEATH(exit(1), ""); + else + // This empty "else" branch is meant to ensure that EXPECT_DEATH + // doesn't expand into an "if" statement without an "else" + ; + + if (false) + ASSERT_DEATH(return, "") << "did not die"; + + if (false) + ; + else + EXPECT_DEATH(exit(1), "") << 1 << 2 << 3; +} + +void DieWithEmbeddedNul() { + fprintf(stderr, "Hello%cworld.\n", '\0'); + abort(); +} + +// Tests that EXPECT_DEATH and ASSERT_DEATH work when the error +// message has a NUL character in it. +TEST_F(TestForDeathTest, DISABLED_EmbeddedNulInMessage) { + // TODO(wan@google.com): doesn't support matching strings + // with embedded NUL characters - find a way to workaround it. + EXPECT_DEATH(DieWithEmbeddedNul(), "w.*ld"); + ASSERT_DEATH(DieWithEmbeddedNul(), "w.*ld"); +} + +// Tests that death test macros expand to code which interacts well with switch +// statements. +TEST_F(TestForDeathTest, SwitchStatement) { + switch (0) + default: + ASSERT_DEATH(exit(1), "") << "exit in default switch handler"; + + switch (0) + case 0: + EXPECT_DEATH(exit(1), "") << "exit in switch case"; +} + +// Tests that a static member function can be used in a death test. +TEST_F(TestForDeathTest, StaticMemberFunction) { + ASSERT_DEATH(StaticMemberFunction(), "death.*StaticMember"); +} + +// Tests that a method of the test fixture can be used in a death test. +TEST_F(TestForDeathTest, MemberFunction) { + should_die_ = true; + EXPECT_DEATH(MemberFunction(), "inside.*MemberFunction"); +} + +// Repeats a representative sample of death tests in the "threadsafe" style: + +TEST_F(TestForDeathTest, StaticMemberFunctionThreadsafeStyle) { + testing::GTEST_FLAG(death_test_style) = "threadsafe"; + ASSERT_DEATH(StaticMemberFunction(), "death.*StaticMember"); +} + +TEST_F(TestForDeathTest, MemberFunctionThreadsafeStyle) { + testing::GTEST_FLAG(death_test_style) = "threadsafe"; + should_die_ = true; + EXPECT_DEATH(MemberFunction(), "inside.*MemberFunction"); +} + +TEST_F(TestForDeathTest, ThreadsafeDeathTestInLoop) { + testing::GTEST_FLAG(death_test_style) = "threadsafe"; + + for (int i = 0; i < 3; ++i) + EXPECT_EXIT(exit(i), testing::ExitedWithCode(i), "") << ": i = " << i; +} + +TEST_F(TestForDeathTest, MixedStyles) { + testing::GTEST_FLAG(death_test_style) = "threadsafe"; + EXPECT_DEATH(exit(1), ""); + testing::GTEST_FLAG(death_test_style) = "fast"; + EXPECT_DEATH(exit(1), ""); +} + +namespace { + +bool pthread_flag; + +void SetPthreadFlag() { + pthread_flag = true; +} + +} // namespace + +TEST_F(TestForDeathTest, DoesNotExecuteAtforkHooks) { + testing::GTEST_FLAG(death_test_style) = "threadsafe"; + pthread_flag = false; + ASSERT_EQ(0, pthread_atfork(&SetPthreadFlag, NULL, NULL)); + ASSERT_DEATH(exit(1), ""); + ASSERT_FALSE(pthread_flag); +} + +// Tests that a method of another class can be used in a death test. +TEST_F(TestForDeathTest, MethodOfAnotherClass) { + const MayDie x(true); + ASSERT_DEATH(x.MemberFunction(), "MayDie\\:\\:MemberFunction"); +} + +// Tests that a global function can be used in a death test. +TEST_F(TestForDeathTest, GlobalFunction) { + EXPECT_DEATH(GlobalFunction(), "GlobalFunction"); +} + +// Tests that any value convertible to an RE works as a second +// argument to EXPECT_DEATH. +TEST_F(TestForDeathTest, AcceptsAnythingConvertibleToRE) { + static const char regex_c_str[] = "GlobalFunction"; + EXPECT_DEATH(GlobalFunction(), regex_c_str); + + const testing::internal::RE regex(regex_c_str); + EXPECT_DEATH(GlobalFunction(), regex); + +#if GTEST_HAS_GLOBAL_STRING + const string regex_str(regex_c_str); + EXPECT_DEATH(GlobalFunction(), regex_str); +#endif // GTEST_HAS_GLOBAL_STRING + +#if GTEST_HAS_STD_STRING + const ::std::string regex_std_str(regex_c_str); + EXPECT_DEATH(GlobalFunction(), regex_std_str); +#endif // GTEST_HAS_STD_STRING +} + +// Tests that a non-void function can be used in a death test. +TEST_F(TestForDeathTest, NonVoidFunction) { + ASSERT_DEATH(NonVoidFunction(), "NonVoidFunction"); +} + +// Tests that functions that take parameter(s) can be used in a death test. +TEST_F(TestForDeathTest, FunctionWithParameter) { + EXPECT_DEATH(DieIf(true), "DieIf\\(\\)"); + EXPECT_DEATH(DieIfLessThan(2, 3), "DieIfLessThan"); +} + +// Tests that ASSERT_DEATH can be used outside a TEST, TEST_F, or test fixture. +TEST_F(TestForDeathTest, OutsideFixture) { + DeathTestSubroutine(); +} + +// Tests that death tests can be done inside a loop. +TEST_F(TestForDeathTest, InsideLoop) { + for (int i = 0; i < 5; i++) { + EXPECT_DEATH(DieIfLessThan(-1, i), "DieIfLessThan") << "where i == " << i; + } +} + +// Tests that a compound statement can be used in a death test. +TEST_F(TestForDeathTest, CompoundStatement) { + EXPECT_DEATH({ // NOLINT + const int x = 2; + const int y = x + 1; + DieIfLessThan(x, y); + }, + "DieIfLessThan"); +} + +// Tests that code that doesn't die causes a death test to fail. +TEST_F(TestForDeathTest, DoesNotDie) { + EXPECT_NONFATAL_FAILURE(EXPECT_DEATH(DieIf(false), "DieIf"), + "failed to die"); +} + +// Tests that a death test fails when the error message isn't expected. +TEST_F(TestForDeathTest, ErrorMessageMismatch) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_DEATH(DieIf(true), "DieIfLessThan") << "End of death test message."; + }, "died but not with expected error"); +} + +// On exit, *aborted will be true iff the EXPECT_DEATH() statement +// aborted the function. +void ExpectDeathTestHelper(bool* aborted) { + *aborted = true; + EXPECT_DEATH(DieIf(false), "DieIf"); // This assertion should fail. + *aborted = false; +} + +// Tests that EXPECT_DEATH doesn't abort the test on failure. +TEST_F(TestForDeathTest, EXPECT_DEATH) { + bool aborted = true; + EXPECT_NONFATAL_FAILURE(ExpectDeathTestHelper(&aborted), + "failed to die"); + EXPECT_FALSE(aborted); +} + +// Tests that ASSERT_DEATH does abort the test on failure. +TEST_F(TestForDeathTest, ASSERT_DEATH) { + static bool aborted; + EXPECT_FATAL_FAILURE({ // NOLINT + aborted = true; + ASSERT_DEATH(DieIf(false), "DieIf"); // This assertion should fail. + aborted = false; + }, "failed to die"); + EXPECT_TRUE(aborted); +} + +// Tests that EXPECT_DEATH evaluates the arguments exactly once. +TEST_F(TestForDeathTest, SingleEvaluation) { + int x = 3; + EXPECT_DEATH(DieIf((++x) == 4), "DieIf"); + + const char* regex = "DieIf"; + const char* regex_save = regex; + EXPECT_DEATH(DieIfLessThan(3, 4), regex++); + EXPECT_EQ(regex_save + 1, regex); +} + +// Tests that run-away death tests are reported as failures. +TEST_F(TestForDeathTest, Runaway) { + EXPECT_NONFATAL_FAILURE(EXPECT_DEATH(static_cast(0), "Foo"), + "failed to die."); + + EXPECT_FATAL_FAILURE(ASSERT_DEATH(return, "Bar"), + "illegal return in test statement."); +} + + +// Tests that EXPECT_DEBUG_DEATH works as expected, +// that is, in debug mode, it: +// 1. Asserts on death. +// 2. Has no side effect. +// +// And in opt mode, it: +// 1. Has side effects but does not assert. +TEST_F(TestForDeathTest, TestExpectDebugDeath) { + int sideeffect = 0; + + EXPECT_DEBUG_DEATH(DieInDebugElse12(&sideeffect), + "death.*DieInDebugElse12"); + +#ifdef NDEBUG + // Checks that the assignment occurs in opt mode (sideeffect). + EXPECT_EQ(12, sideeffect); +#else + // Checks that the assignment does not occur in dbg mode (no sideeffect). + EXPECT_EQ(0, sideeffect); +#endif +} + +// Tests that EXPECT_DEBUG_DEATH works as expected, +// that is, in debug mode, it: +// 1. Asserts on death. +// 2. Has no side effect. +// +// And in opt mode, it: +// 1. Has side effects and returns the expected value (12). +TEST_F(TestForDeathTest, TestExpectDebugDeathM) { + int sideeffect = 0; + EXPECT_DEBUG_DEATH({ // NOLINT + // Tests that the return value is 12 in opt mode. + EXPECT_EQ(12, DieInDebugElse12(&sideeffect)); + // Tests that the side effect occurrs in opt mode. + EXPECT_EQ(12, sideeffect); + }, "death.*DieInDebugElse12") << "In ExpectDebugDeathM"; + +#ifdef NDEBUG + // Checks that the assignment occurs in opt mode (sideeffect). + EXPECT_EQ(12, sideeffect); +#else + // Checks that the assignment does not occur in dbg mode (no sideeffect). + EXPECT_EQ(0, sideeffect); +#endif +} + +// Tests that ASSERT_DEBUG_DEATH works as expected +// In debug mode: +// 1. Asserts on debug death. +// 2. Has no side effect. +// +// In opt mode: +// 1. Has side effects and returns the expected value (12). +TEST_F(TestForDeathTest, TestAssertDebugDeathM) { + int sideeffect = 0; + + ASSERT_DEBUG_DEATH({ // NOLINT + // Tests that the return value is 12 in opt mode. + EXPECT_EQ(12, DieInDebugElse12(&sideeffect)); + // Tests that the side effect occurred in opt mode. + EXPECT_EQ(12, sideeffect); + }, "death.*DieInDebugElse12") << "In AssertDebugDeathM"; + +#ifdef NDEBUG + // Checks that the assignment occurs in opt mode (sideeffect). + EXPECT_EQ(12, sideeffect); +#else + // Checks that the assignment does not occur in dbg mode (no sideeffect). + EXPECT_EQ(0, sideeffect); +#endif +} + +#ifndef NDEBUG + +void ExpectDebugDeathHelper(bool* aborted) { + *aborted = true; + EXPECT_DEBUG_DEATH(return, "") << "This is expected to fail."; + *aborted = false; +} + +// Tests that EXPECT_DEBUG_DEATH in debug mode does not abort +// the function. +TEST_F(TestForDeathTest, ExpectDebugDeathDoesNotAbort) { + bool aborted = true; + EXPECT_NONFATAL_FAILURE(ExpectDebugDeathHelper(&aborted), ""); + EXPECT_FALSE(aborted); +} + +void AssertDebugDeathHelper(bool* aborted) { + *aborted = true; + ASSERT_DEBUG_DEATH(return, "") << "This is expected to fail."; + *aborted = false; +} + +// Tests that ASSERT_DEBUG_DEATH in debug mode aborts the function on +// failure. +TEST_F(TestForDeathTest, AssertDebugDeathAborts) { + static bool aborted; + aborted = false; + EXPECT_FATAL_FAILURE(AssertDebugDeathHelper(&aborted), ""); + EXPECT_TRUE(aborted); +} + +#endif // _NDEBUG + +// Tests the *_EXIT family of macros, using a variety of predicates. +TEST_F(TestForDeathTest, ExitMacros) { + EXPECT_EXIT(exit(1), testing::ExitedWithCode(1), ""); + ASSERT_EXIT(exit(42), testing::ExitedWithCode(42), ""); + EXPECT_EXIT(raise(SIGKILL), testing::KilledBySignal(SIGKILL), "") << "foo"; + ASSERT_EXIT(raise(SIGUSR2), testing::KilledBySignal(SIGUSR2), "") << "bar"; + + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_EXIT(raise(SIGSEGV), testing::ExitedWithCode(0), "") + << "This failure is expected."; + }, "This failure is expected."); + + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_EXIT(exit(0), testing::KilledBySignal(SIGSEGV), "") + << "This failure is expected, too."; + }, "This failure is expected, too."); +} + +TEST_F(TestForDeathTest, InvalidStyle) { + testing::GTEST_FLAG(death_test_style) = "rococo"; + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_DEATH(exit(0), "") << "This failure is expected."; + }, "This failure is expected."); +} + +// A DeathTestFactory that returns MockDeathTests. +class MockDeathTestFactory : public DeathTestFactory { + public: + MockDeathTestFactory(); + virtual bool Create(const char* statement, + const ::testing::internal::RE* regex, + const char* file, int line, DeathTest** test); + + // Sets the parameters for subsequent calls to Create. + void SetParameters(bool create, DeathTest::TestRole role, + int status, bool passed); + + // Accessors. + int AssumeRoleCalls() const { return assume_role_calls_; } + int WaitCalls() const { return wait_calls_; } + int PassedCalls() const { return passed_args_.size(); } + bool PassedArgument(int n) const { return passed_args_[n]; } + int AbortCalls() const { return abort_args_.size(); } + DeathTest::AbortReason AbortArgument(int n) const { + return abort_args_[n]; + } + bool TestDeleted() const { return test_deleted_; } + + private: + friend class MockDeathTest; + // If true, Create will return a MockDeathTest; otherwise it returns + // NULL. + bool create_; + // The value a MockDeathTest will return from its AssumeRole method. + DeathTest::TestRole role_; + // The value a MockDeathTest will return from its Wait method. + int status_; + // The value a MockDeathTest will return from its Passed method. + bool passed_; + + // Number of times AssumeRole was called. + int assume_role_calls_; + // Number of times Wait was called. + int wait_calls_; + // The arguments to the calls to Passed since the last call to + // SetParameters. + std::vector passed_args_; + // The arguments to the calls to Abort since the last call to + // SetParameters. + std::vector abort_args_; + // True if the last MockDeathTest returned by Create has been + // deleted. + bool test_deleted_; +}; + + +// A DeathTest implementation useful in testing. It returns values set +// at its creation from its various inherited DeathTest methods, and +// reports calls to those methods to its parent MockDeathTestFactory +// object. +class MockDeathTest : public DeathTest { + public: + MockDeathTest(MockDeathTestFactory *parent, + TestRole role, int status, bool passed) : + parent_(parent), role_(role), status_(status), passed_(passed) { + } + virtual ~MockDeathTest() { + parent_->test_deleted_ = true; + } + virtual TestRole AssumeRole() { + ++parent_->assume_role_calls_; + return role_; + } + virtual int Wait() { + ++parent_->wait_calls_; + return status_; + } + virtual bool Passed(bool exit_status_ok) { + parent_->passed_args_.push_back(exit_status_ok); + return passed_; + } + virtual void Abort(AbortReason reason) { + parent_->abort_args_.push_back(reason); + } + private: + MockDeathTestFactory* const parent_; + const TestRole role_; + const int status_; + const bool passed_; +}; + + +// MockDeathTestFactory constructor. +MockDeathTestFactory::MockDeathTestFactory() + : create_(true), + role_(DeathTest::OVERSEE_TEST), + status_(0), + passed_(true), + assume_role_calls_(0), + wait_calls_(0), + passed_args_(), + abort_args_() { +} + + +// Sets the parameters for subsequent calls to Create. +void MockDeathTestFactory::SetParameters(bool create, + DeathTest::TestRole role, + int status, bool passed) { + create_ = create; + role_ = role; + status_ = status; + passed_ = passed; + + assume_role_calls_ = 0; + wait_calls_ = 0; + passed_args_.clear(); + abort_args_.clear(); +} + + +// Sets test to NULL (if create_ is false) or to the address of a new +// MockDeathTest object with parameters taken from the last call +// to SetParameters (if create_ is true). Always returns true. +bool MockDeathTestFactory::Create(const char* statement, + const ::testing::internal::RE* regex, + const char* file, int line, + DeathTest** test) { + test_deleted_ = false; + if (create_) { + *test = new MockDeathTest(this, role_, status_, passed_); + } else { + *test = NULL; + } + return true; +} + +// A test fixture for testing the logic of the GTEST_DEATH_TEST macro. +// It installs a MockDeathTestFactory that is used for the duration +// of the test case. +class MacroLogicDeathTest : public testing::Test { + protected: + static testing::internal::ReplaceDeathTestFactory* replacer_; + static MockDeathTestFactory* factory_; + + static void SetUpTestCase() { + factory_ = new MockDeathTestFactory; + replacer_ = new testing::internal::ReplaceDeathTestFactory( + testing::UnitTest::GetInstance(), factory_); + } + + static void TearDownTestCase() { + delete replacer_; + replacer_ = NULL; + delete factory_; + factory_ = NULL; + } + + // Runs a death test that breaks the rules by returning. Such a death + // test cannot be run directly from a test routine that uses a + // MockDeathTest, or the remainder of the routine will not be executed. + static void RunReturningDeathTest(bool* flag) { + ASSERT_DEATH({ // NOLINT + *flag = true; + return; + }, ""); + } +}; + +testing::internal::ReplaceDeathTestFactory* MacroLogicDeathTest::replacer_ + = NULL; +MockDeathTestFactory* MacroLogicDeathTest::factory_ = NULL; + + +// Test that nothing happens when the factory doesn't return a DeathTest: +TEST_F(MacroLogicDeathTest, NothingHappens) { + bool flag = false; + factory_->SetParameters(false, DeathTest::OVERSEE_TEST, 0, true); + EXPECT_DEATH(flag = true, ""); + EXPECT_FALSE(flag); + EXPECT_EQ(0, factory_->AssumeRoleCalls()); + EXPECT_EQ(0, factory_->WaitCalls()); + EXPECT_EQ(0, factory_->PassedCalls()); + EXPECT_EQ(0, factory_->AbortCalls()); + EXPECT_FALSE(factory_->TestDeleted()); +} + +// Test that the parent process doesn't run the death test code, +// and that the Passed method returns false when the (simulated) +// child process exits with status 0: +TEST_F(MacroLogicDeathTest, ChildExitsSuccessfully) { + bool flag = false; + factory_->SetParameters(true, DeathTest::OVERSEE_TEST, 0, true); + EXPECT_DEATH(flag = true, ""); + EXPECT_FALSE(flag); + EXPECT_EQ(1, factory_->AssumeRoleCalls()); + EXPECT_EQ(1, factory_->WaitCalls()); + ASSERT_EQ(1, factory_->PassedCalls()); + EXPECT_FALSE(factory_->PassedArgument(0)); + EXPECT_EQ(0, factory_->AbortCalls()); + EXPECT_TRUE(factory_->TestDeleted()); +} + +// Tests that the Passed method was given the argument "true" when +// the (simulated) child process exits with status 1: +TEST_F(MacroLogicDeathTest, ChildExitsUnsuccessfully) { + bool flag = false; + factory_->SetParameters(true, DeathTest::OVERSEE_TEST, 1, true); + EXPECT_DEATH(flag = true, ""); + EXPECT_FALSE(flag); + EXPECT_EQ(1, factory_->AssumeRoleCalls()); + EXPECT_EQ(1, factory_->WaitCalls()); + ASSERT_EQ(1, factory_->PassedCalls()); + EXPECT_TRUE(factory_->PassedArgument(0)); + EXPECT_EQ(0, factory_->AbortCalls()); + EXPECT_TRUE(factory_->TestDeleted()); +} + +// Tests that the (simulated) child process executes the death test +// code, and is aborted with the correct AbortReason if it +// executes a return statement. +TEST_F(MacroLogicDeathTest, ChildPerformsReturn) { + bool flag = false; + factory_->SetParameters(true, DeathTest::EXECUTE_TEST, 0, true); + RunReturningDeathTest(&flag); + EXPECT_TRUE(flag); + EXPECT_EQ(1, factory_->AssumeRoleCalls()); + EXPECT_EQ(0, factory_->WaitCalls()); + EXPECT_EQ(0, factory_->PassedCalls()); + EXPECT_EQ(1, factory_->AbortCalls()); + EXPECT_EQ(DeathTest::TEST_ENCOUNTERED_RETURN_STATEMENT, + factory_->AbortArgument(0)); + EXPECT_TRUE(factory_->TestDeleted()); +} + +// Tests that the (simulated) child process is aborted with the +// correct AbortReason if it does not die. +TEST_F(MacroLogicDeathTest, ChildDoesNotDie) { + bool flag = false; + factory_->SetParameters(true, DeathTest::EXECUTE_TEST, 0, true); + EXPECT_DEATH(flag = true, ""); + EXPECT_TRUE(flag); + EXPECT_EQ(1, factory_->AssumeRoleCalls()); + EXPECT_EQ(0, factory_->WaitCalls()); + EXPECT_EQ(0, factory_->PassedCalls()); + // This time there are two calls to Abort: one since the test didn't + // die, and another from the ReturnSentinel when it's destroyed. The + // sentinel normally isn't destroyed if a test doesn't die, since + // exit(2) is called in that case by ForkingDeathTest, but not by + // our MockDeathTest. + ASSERT_EQ(2, factory_->AbortCalls()); + EXPECT_EQ(DeathTest::TEST_DID_NOT_DIE, + factory_->AbortArgument(0)); + EXPECT_EQ(DeathTest::TEST_ENCOUNTERED_RETURN_STATEMENT, + factory_->AbortArgument(1)); + EXPECT_TRUE(factory_->TestDeleted()); +} + +// Returns the number of successful parts in the current test. +static size_t GetSuccessfulTestPartCount() { + return testing::UnitTest::GetInstance()->impl()->current_test_result()-> + successful_part_count(); +} + +// Tests that a successful death test does not register a successful +// test part. +TEST(SuccessRegistrationDeathTest, NoSuccessPart) { + EXPECT_DEATH(exit(1), ""); + EXPECT_EQ(0u, GetSuccessfulTestPartCount()); +} + +TEST(StreamingAssertionsDeathTest, DeathTest) { + EXPECT_DEATH(exit(1), "") << "unexpected failure"; + ASSERT_DEATH(exit(1), "") << "unexpected failure"; + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_DEATH(exit(0), "") << "expected failure"; + }, "expected failure"); + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_DEATH(exit(0), "") << "expected failure"; + }, "expected failure"); +} + +#endif // GTEST_HAS_DEATH_TEST + +// Tests that a test case whose name ends with "DeathTest" works fine +// on Windows. +TEST(NotADeathTest, Test) { + SUCCEED(); +} diff --git a/test/gtest-filepath_test.cc b/test/gtest-filepath_test.cc new file mode 100644 index 00000000..559b599b --- /dev/null +++ b/test/gtest-filepath_test.cc @@ -0,0 +1,369 @@ +// Copyright 2008, 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. +// +// Authors: keith.ray@gmail.com (Keith Ray) +// +// Google Test filepath utilities +// +// This file tests classes and functions used internally by +// Google Test. They are subject to change without notice. +// +// This file is #included from gtest_unittest.cc, to avoid changing +// build or make-files for some existing Google Test clients. Do not +// #include this file anywhere else! + +#include +#include + +// Indicates that this translation unit is part of Google Test's +// implementation. It must come before gtest-internal-inl.h is +// included, or there will be a compiler error. This trick is to +// prevent a user from accidentally including gtest-internal-inl.h in +// his code. +#define GTEST_IMPLEMENTATION +#include "src/gtest-internal-inl.h" +#undef GTEST_IMPLEMENTATION + +#ifdef GTEST_OS_WINDOWS +#include +#define PATH_SEP "\\" +#else +#define PATH_SEP "/" +#endif // GTEST_OS_WINDOWS + +namespace testing { +namespace internal { +namespace { + +// FilePath's functions used by UnitTestOptions::GetOutputFile. + +// RemoveDirectoryName "" -> "" +TEST(RemoveDirectoryNameTest, WhenEmptyName) { + EXPECT_STREQ("", FilePath("").RemoveDirectoryName().c_str()); +} + +// RemoveDirectoryName "afile" -> "afile" +TEST(RemoveDirectoryNameTest, ButNoDirectory) { + EXPECT_STREQ("afile", + FilePath("afile").RemoveDirectoryName().c_str()); +} + +// RemoveDirectoryName "/afile" -> "afile" +TEST(RemoveDirectoryNameTest, RootFileShouldGiveFileName) { + EXPECT_STREQ("afile", + FilePath(PATH_SEP "afile").RemoveDirectoryName().c_str()); +} + +// RemoveDirectoryName "adir/" -> "" +TEST(RemoveDirectoryNameTest, WhereThereIsNoFileName) { + EXPECT_STREQ("", + FilePath("adir" PATH_SEP).RemoveDirectoryName().c_str()); +} + +// RemoveDirectoryName "adir/afile" -> "afile" +TEST(RemoveDirectoryNameTest, ShouldGiveFileName) { + EXPECT_STREQ("afile", + FilePath("adir" PATH_SEP "afile").RemoveDirectoryName().c_str()); +} + +// RemoveDirectoryName "adir/subdir/afile" -> "afile" +TEST(RemoveDirectoryNameTest, ShouldAlsoGiveFileName) { + EXPECT_STREQ("afile", + FilePath("adir" PATH_SEP "subdir" PATH_SEP "afile") + .RemoveDirectoryName().c_str()); +} + + +// RemoveFileName "" -> "./" +TEST(RemoveFileNameTest, EmptyName) { + EXPECT_STREQ("." PATH_SEP, + FilePath("").RemoveFileName().c_str()); +} + +// RemoveFileName "adir/" -> "adir/" +TEST(RemoveFileNameTest, ButNoFile) { + EXPECT_STREQ("adir" PATH_SEP, + FilePath("adir" PATH_SEP).RemoveFileName().c_str()); +} + +// RemoveFileName "adir/afile" -> "adir/" +TEST(RemoveFileNameTest, GivesDirName) { + EXPECT_STREQ("adir" PATH_SEP, + FilePath("adir" PATH_SEP "afile") + .RemoveFileName().c_str()); +} + +// RemoveFileName "adir/subdir/afile" -> "adir/subdir/" +TEST(RemoveFileNameTest, GivesDirAndSubDirName) { + EXPECT_STREQ("adir" PATH_SEP "subdir" PATH_SEP, + FilePath("adir" PATH_SEP "subdir" PATH_SEP "afile") + .RemoveFileName().c_str()); +} + +// RemoveFileName "/afile" -> "/" +TEST(RemoveFileNameTest, GivesRootDir) { + EXPECT_STREQ(PATH_SEP, + FilePath(PATH_SEP "afile").RemoveFileName().c_str()); +} + + +TEST(MakeFileNameTest, GenerateWhenNumberIsZero) { + FilePath actual = FilePath::MakeFileName(FilePath("foo"), FilePath("bar"), + 0, "xml"); + EXPECT_STREQ("foo" PATH_SEP "bar.xml", actual.c_str()); +} + +TEST(MakeFileNameTest, GenerateFileNameNumberGtZero) { + FilePath actual = FilePath::MakeFileName(FilePath("foo"), FilePath("bar"), + 12, "xml"); + EXPECT_STREQ("foo" PATH_SEP "bar_12.xml", actual.c_str()); +} + +TEST(MakeFileNameTest, GenerateFileNameWithSlashNumberIsZero) { + FilePath actual = FilePath::MakeFileName(FilePath("foo" PATH_SEP), + FilePath("bar"), 0, "xml"); + EXPECT_STREQ("foo" PATH_SEP "bar.xml", actual.c_str()); +} + +TEST(MakeFileNameTest, GenerateFileNameWithSlashNumberGtZero) { + FilePath actual = FilePath::MakeFileName(FilePath("foo" PATH_SEP), + FilePath("bar"), 12, "xml"); + EXPECT_STREQ("foo" PATH_SEP "bar_12.xml", actual.c_str()); +} + + +// RemoveTrailingPathSeparator "" -> "" +TEST(RemoveTrailingPathSeparatorTest, EmptyString) { + EXPECT_STREQ("", + FilePath("").RemoveTrailingPathSeparator().c_str()); +} + +// RemoveTrailingPathSeparator "foo" -> "foo" +TEST(RemoveTrailingPathSeparatorTest, FileNoSlashString) { + EXPECT_STREQ("foo", + FilePath("foo").RemoveTrailingPathSeparator().c_str()); +} + +// RemoveTrailingPathSeparator "foo/" -> "foo" +TEST(RemoveTrailingPathSeparatorTest, ShouldRemoveTrailingSeparator) { + EXPECT_STREQ("foo", + FilePath("foo" PATH_SEP).RemoveTrailingPathSeparator().c_str()); +} + +// RemoveTrailingPathSeparator "foo/bar/" -> "foo/bar/" +TEST(RemoveTrailingPathSeparatorTest, ShouldRemoveLastSeparator) { + EXPECT_STREQ("foo" PATH_SEP "bar", + FilePath("foo" PATH_SEP "bar" PATH_SEP).RemoveTrailingPathSeparator() + .c_str()); +} + +// RemoveTrailingPathSeparator "foo/bar" -> "foo/bar" +TEST(RemoveTrailingPathSeparatorTest, ShouldReturnUnmodified) { + EXPECT_STREQ("foo" PATH_SEP "bar", + FilePath("foo" PATH_SEP "bar").RemoveTrailingPathSeparator().c_str()); +} + + +class DirectoryCreationTest : public Test { + protected: + virtual void SetUp() { + testdata_path_.Set(FilePath(String::Format("%s%s%s", + TempDir().c_str(), GetCurrentExecutableName().c_str(), + "_directory_creation" PATH_SEP "test" PATH_SEP))); + testdata_file_.Set(testdata_path_.RemoveTrailingPathSeparator()); + + unique_file0_.Set(FilePath::MakeFileName(testdata_path_, FilePath("unique"), + 0, "txt")); + unique_file1_.Set(FilePath::MakeFileName(testdata_path_, FilePath("unique"), + 1, "txt")); + + remove(testdata_file_.c_str()); + remove(unique_file0_.c_str()); + remove(unique_file1_.c_str()); +#ifdef GTEST_OS_WINDOWS + _rmdir(testdata_path_.c_str()); +#else + rmdir(testdata_path_.c_str()); +#endif // GTEST_OS_WINDOWS + } + + virtual void TearDown() { + remove(testdata_file_.c_str()); + remove(unique_file0_.c_str()); + remove(unique_file1_.c_str()); +#ifdef GTEST_OS_WINDOWS + _rmdir(testdata_path_.c_str()); +#else + rmdir(testdata_path_.c_str()); +#endif // GTEST_OS_WINDOWS + } + + String TempDir() const { +#ifdef _WIN32_WCE + return String("\\temp\\"); + +#elif defined(GTEST_OS_WINDOWS) + // MSVC 8 deprecates getenv(), so we want to suppress warning 4996 + // (deprecated function) there. +#pragma warning(push) // Saves the current warning state. +#pragma warning(disable:4996) // Temporarily disables warning 4996. + const char* temp_dir = getenv("TEMP"); +#pragma warning(pop) // Restores the warning state. + + if (temp_dir == NULL || temp_dir[0] == '\0') + return String("\\temp\\"); + else if (String(temp_dir).EndsWith("\\")) + return String(temp_dir); + else + return String::Format("%s\\", temp_dir); +#else + return String("/tmp/"); +#endif + } + + void CreateTextFile(const char* filename) { +#ifdef GTEST_OS_WINDOWS + // MSVC 8 deprecates fopen(), so we want to suppress warning 4996 + // (deprecated function) there.#pragma warning(push) +#pragma warning(push) // Saves the current warning state. +#pragma warning(disable:4996) // Temporarily disables warning 4996. + FILE* f = fopen(filename, "w"); +#pragma warning(pop) // Restores the warning state. +#else // We are on Linux or Mac OS. + FILE* f = fopen(filename, "w"); +#endif // GTEST_OS_WINDOWS + fprintf(f, "text\n"); + fclose(f); + } + + // Strings representing a directory and a file, with identical paths + // except for the trailing separator character that distinquishes + // a directory named 'test' from a file named 'test'. Example names: + FilePath testdata_path_; // "/tmp/directory_creation/test/" + FilePath testdata_file_; // "/tmp/directory_creation/test" + FilePath unique_file0_; // "/tmp/directory_creation/test/unique.txt" + FilePath unique_file1_; // "/tmp/directory_creation/test/unique_1.txt" +}; + +TEST_F(DirectoryCreationTest, CreateDirectoriesRecursively) { + EXPECT_FALSE(testdata_path_.DirectoryExists()) << testdata_path_.c_str(); + EXPECT_TRUE(testdata_path_.CreateDirectoriesRecursively()); + EXPECT_TRUE(testdata_path_.DirectoryExists()); +} + +TEST_F(DirectoryCreationTest, CreateDirectoriesForAlreadyExistingPath) { + EXPECT_FALSE(testdata_path_.DirectoryExists()) << testdata_path_.c_str(); + EXPECT_TRUE(testdata_path_.CreateDirectoriesRecursively()); + // Call 'create' again... should still succeed. + EXPECT_TRUE(testdata_path_.CreateDirectoriesRecursively()); +} + +TEST_F(DirectoryCreationTest, CreateDirectoriesAndUniqueFilename) { + FilePath file_path(FilePath::GenerateUniqueFileName(testdata_path_, + FilePath("unique"), "txt")); + EXPECT_STREQ(unique_file0_.c_str(), file_path.c_str()); + EXPECT_FALSE(file_path.FileOrDirectoryExists()); // file not there + + testdata_path_.CreateDirectoriesRecursively(); + EXPECT_FALSE(file_path.FileOrDirectoryExists()); // file still not there + CreateTextFile(file_path.c_str()); + EXPECT_TRUE(file_path.FileOrDirectoryExists()); + + FilePath file_path2(FilePath::GenerateUniqueFileName(testdata_path_, + FilePath("unique"), "txt")); + EXPECT_STREQ(unique_file1_.c_str(), file_path2.c_str()); + EXPECT_FALSE(file_path2.FileOrDirectoryExists()); // file not there + CreateTextFile(file_path2.c_str()); + EXPECT_TRUE(file_path2.FileOrDirectoryExists()); +} + +TEST_F(DirectoryCreationTest, CreateDirectoriesFail) { + // force a failure by putting a file where we will try to create a directory. + CreateTextFile(testdata_file_.c_str()); + EXPECT_TRUE(testdata_file_.FileOrDirectoryExists()); + EXPECT_FALSE(testdata_file_.DirectoryExists()); + EXPECT_FALSE(testdata_file_.CreateDirectoriesRecursively()); +} + +TEST(NoDirectoryCreationTest, CreateNoDirectoriesForDefaultXmlFile) { + const FilePath test_detail_xml("test_detail.xml"); + EXPECT_FALSE(test_detail_xml.CreateDirectoriesRecursively()); +} + +TEST(FilePathTest, DefaultConstructor) { + FilePath fp; + EXPECT_STREQ("", fp.c_str()); +} + +TEST(FilePathTest, CharAndCopyConstructors) { + const FilePath fp("spicy"); + EXPECT_STREQ("spicy", fp.c_str()); + + const FilePath fp_copy(fp); + EXPECT_STREQ("spicy", fp_copy.c_str()); +} + +TEST(FilePathTest, StringConstructor) { + const FilePath fp(String("cider")); + EXPECT_STREQ("cider", fp.c_str()); +} + +TEST(FilePathTest, Set) { + const FilePath apple("apple"); + FilePath mac("mac"); + mac.Set(apple); // Implement Set() since overloading operator= is forbidden. + EXPECT_STREQ("apple", mac.c_str()); + EXPECT_STREQ("apple", apple.c_str()); +} + +TEST(FilePathTest, ToString) { + const FilePath file("drink"); + String str(file.ToString()); + EXPECT_STREQ("drink", str.c_str()); +} + +TEST(FilePathTest, RemoveExtension) { + EXPECT_STREQ("app", FilePath("app.exe").RemoveExtension("exe").c_str()); + EXPECT_STREQ("APP", FilePath("APP.EXE").RemoveExtension("exe").c_str()); +} + +TEST(FilePathTest, RemoveExtensionWhenThereIsNoExtension) { + EXPECT_STREQ("app", FilePath("app").RemoveExtension("exe").c_str()); +} + +TEST(FilePathTest, IsDirectory) { + EXPECT_FALSE(FilePath("cola").IsDirectory()); + EXPECT_TRUE(FilePath("koala" PATH_SEP).IsDirectory()); +} + +} // namespace +} // namespace internal +} // namespace testing + +#undef PATH_SEP diff --git a/test/gtest-message_test.cc b/test/gtest-message_test.cc new file mode 100644 index 00000000..6c43c33d --- /dev/null +++ b/test/gtest-message_test.cc @@ -0,0 +1,157 @@ +// 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) +// +// Tests for the Message class. + +#include + +#include + +namespace { + +using ::testing::Message; +using ::testing::internal::StrStream; + +// A helper function that turns a Message into a C string. +const char* ToCString(const Message& msg) { + static testing::internal::String result; + result = msg.GetString(); + return result.c_str(); +} + +// Tests the testing::Message class + +// Tests the default constructor. +TEST(MessageTest, DefaultConstructor) { + const Message msg; + EXPECT_STREQ("", ToCString(msg)); +} + +// Tests the copy constructor. +TEST(MessageTest, CopyConstructor) { + const Message msg1("Hello"); + const Message msg2(msg1); + EXPECT_STREQ("Hello", ToCString(msg2)); +} + +// Tests constructing a Message from a C-string. +TEST(MessageTest, ConstructsFromCString) { + Message msg("Hello"); + EXPECT_STREQ("Hello", ToCString(msg)); +} + +// Tests streaming a non-char pointer. +TEST(MessageTest, StreamsPointer) { + int n = 0; + int* p = &n; + EXPECT_STRNE("(null)", ToCString(Message() << p)); +} + +// Tests streaming a NULL non-char pointer. +TEST(MessageTest, StreamsNullPointer) { + int* p = NULL; + EXPECT_STREQ("(null)", ToCString(Message() << p)); +} + +// Tests streaming a C string. +TEST(MessageTest, StreamsCString) { + EXPECT_STREQ("Foo", ToCString(Message() << "Foo")); +} + +// Tests streaming a NULL C string. +TEST(MessageTest, StreamsNullCString) { + char* p = NULL; + EXPECT_STREQ("(null)", ToCString(Message() << p)); +} + +#if GTEST_HAS_STD_STRING + +// Tests streaming std::string. +// +// As std::string has problem in MSVC when exception is disabled, we only +// test this where std::string can be used. +TEST(MessageTest, StreamsString) { + const ::std::string str("Hello"); + EXPECT_STREQ("Hello", ToCString(Message() << str)); +} + +// Tests that we can output strings containing embedded NULs. +TEST(MessageTest, StreamsStringWithEmbeddedNUL) { + const char char_array_with_nul[] = + "Here's a NUL\0 and some more string"; + const ::std::string string_with_nul(char_array_with_nul, + sizeof(char_array_with_nul) - 1); + EXPECT_STREQ("Here's a NUL\\0 and some more string", + ToCString(Message() << string_with_nul)); +} + +#endif // GTEST_HAS_STD_STRING + +// Tests streaming a NUL char. +TEST(MessageTest, StreamsNULChar) { + EXPECT_STREQ("\\0", ToCString(Message() << '\0')); +} + +// Tests streaming int. +TEST(MessageTest, StreamsInt) { + EXPECT_STREQ("123", ToCString(Message() << 123)); +} + +// Tests that basic IO manipulators (endl, ends, and flush) can be +// streamed to Message. +TEST(MessageTest, StreamsBasicIoManip) { + EXPECT_STREQ("Line 1.\nA NUL char \\0 in line 2.", + ToCString(Message() << "Line 1." << std::endl + << "A NUL char " << std::ends << std::flush + << " in line 2.")); +} + +// Tests Message::GetString() +TEST(MessageTest, GetString) { + Message msg; + msg << 1 << " lamb"; + EXPECT_STREQ("1 lamb", msg.GetString().c_str()); +} + +// Tests streaming a Message object to an ostream. +TEST(MessageTest, StreamsToOStream) { + Message msg("Hello"); + StrStream ss; + ss << msg; + EXPECT_STREQ("Hello", testing::internal::StrStreamToString(&ss).c_str()); +} + +// Tests that a Message object doesn't take up too much stack space. +TEST(MessageTest, DoesNotTakeUpMuchStackSpace) { + EXPECT_LE(sizeof(Message), 16U); +} + +} // namespace diff --git a/test/gtest-options_test.cc b/test/gtest-options_test.cc new file mode 100644 index 00000000..93f49e20 --- /dev/null +++ b/test/gtest-options_test.cc @@ -0,0 +1,122 @@ +// Copyright 2008, 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. +// +// Authors: keith.ray@gmail.com (Keith Ray) +// +// Google Test UnitTestOptions tests +// +// This file tests classes and functions used internally by +// Google Test. They are subject to change without notice. +// +// This file is #included from gtest.cc, to avoid changing build or +// make-files on Windows and other platforms. Do not #include this file +// anywhere else! + +#include + +// Indicates that this translation unit is part of Google Test's +// implementation. It must come before gtest-internal-inl.h is +// included, or there will be a compiler error. This trick is to +// prevent a user from accidentally including gtest-internal-inl.h in +// his code. +#define GTEST_IMPLEMENTATION +#include "src/gtest-internal-inl.h" +#undef GTEST_IMPLEMENTATION + +namespace testing { + +namespace internal { +namespace { + +// Testing UnitTestOptions::GetOutputFormat/GetOutputFile. + +TEST(XmlOutputTest, GetOutputFormatDefault) { + GTEST_FLAG(output) = ""; + EXPECT_STREQ("", UnitTestOptions::GetOutputFormat().c_str()); +} + +TEST(XmlOutputTest, GetOutputFormat) { + GTEST_FLAG(output) = "xml:filename"; + EXPECT_STREQ("xml", UnitTestOptions::GetOutputFormat().c_str()); +} + +TEST(XmlOutputTest, GetOutputFileDefault) { + GTEST_FLAG(output) = ""; + EXPECT_STREQ("test_detail.xml", + UnitTestOptions::GetOutputFile().c_str()); +} + +TEST(XmlOutputTest, GetOutputFileSingleFile) { + GTEST_FLAG(output) = "xml:filename.abc"; + EXPECT_STREQ("filename.abc", + UnitTestOptions::GetOutputFile().c_str()); +} + +TEST(XmlOutputTest, GetOutputFileFromDirectoryPath) { +#ifdef GTEST_OS_WINDOWS + GTEST_FLAG(output) = "xml:pathname\\"; + const String& output_file = UnitTestOptions::GetOutputFile(); + EXPECT_TRUE(_strcmpi(output_file.c_str(), + "pathname\\gtest-options_test.xml") == 0 || + _strcmpi(output_file.c_str(), + "pathname\\gtest-options-ex_test.xml") == 0) + << " output_file = " << output_file; +#else + GTEST_FLAG(output) = "xml:pathname/"; + const String& output_file = UnitTestOptions::GetOutputFile(); + // TODO(wan@google.com): libtool causes the test binary file to be + // named lt-gtest-options_test. Therefore the output file may be + // named .../lt-gtest-options_test.xml. We should remove this + // hard-coded logic when Chandler Carruth's libtool replacement is + // ready. + EXPECT_TRUE(output_file == "pathname/gtest-options_test.xml" || + output_file == "pathname/lt-gtest-options_test.xml") + << " output_file = " << output_file; +#endif +} + +TEST(OutputFileHelpersTest, GetCurrentExecutableName) { + const FilePath executable = GetCurrentExecutableName(); + const char* const exe_str = executable.c_str(); +#if defined(_WIN32_WCE) || defined(GTEST_OS_WINDOWS) + ASSERT_TRUE(_strcmpi("gtest-options_test", exe_str) == 0 || + _strcmpi("gtest-options-ex_test", exe_str) == 0) + << "GetCurrentExecutableName() returns " << exe_str; +#else + // TODO(wan@google.com): remove the hard-coded "lt-" prefix when + // Chandler Carruth's libtool replacement is ready. + EXPECT_TRUE(String(exe_str) == "gtest-options_test" || + String(exe_str) == "lt-gtest-options_test") + << "GetCurrentExecutableName() returns " << exe_str; +#endif +} + +} // namespace +} // namespace internal +} // namespace testing diff --git a/test/gtest_break_on_failure_unittest.py b/test/gtest_break_on_failure_unittest.py new file mode 100755 index 00000000..1b18339b --- /dev/null +++ b/test/gtest_break_on_failure_unittest.py @@ -0,0 +1,178 @@ +#!/usr/bin/env python +# +# Copyright 2006, 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. + +"""Unit test for Google Test's break-on-failure mode. + +A user can ask Google Test to seg-fault when an assertion fails, using +either the GTEST_BREAK_ON_FAILURE environment variable or the +--gtest_break_on_failure flag. This script tests such functionality +by invoking gtest_break_on_failure_unittest_ (a program written with +Google Test) with different environments and command line flags. +""" + +__author__ = 'wan@google.com (Zhanyong Wan)' + +import gtest_test_utils +import os +import signal +import sys +import unittest + + +# Constants. + +# The environment variable for enabling/disabling the break-on-failure mode. +BREAK_ON_FAILURE_ENV_VAR = 'GTEST_BREAK_ON_FAILURE' + +# The command line flag for enabling/disabling the break-on-failure mode. +BREAK_ON_FAILURE_FLAG = 'gtest_break_on_failure' + +# Path to the gtest_break_on_failure_unittest_ program. +EXE_PATH = os.path.join(gtest_test_utils.GetBuildDir(), + 'gtest_break_on_failure_unittest_'); + + +# Utilities. + +def SetEnvVar(env_var, value): + """Sets an environment variable to a given value; unsets it when the + given value is None. + """ + + if value is not None: + os.environ[env_var] = value + elif env_var in os.environ: + del os.environ[env_var] + + +def Run(command): + """Runs a command; returns 1 if it has a segmentation fault, or 0 otherwise. + """ + + return os.system(command) == signal.SIGSEGV + + +# The unit test. + +class GTestBreakOnFailureUnitTest(unittest.TestCase): + """Tests using the GTEST_BREAK_ON_FAILURE environment variable or + the --gtest_break_on_failure flag to turn assertion failures into + segmentation faults. + """ + + def RunAndVerify(self, env_var_value, flag_value, expect_seg_fault): + """Runs gtest_break_on_failure_unittest_ and verifies that it does + (or does not) have a seg-fault. + + Args: + env_var_value: value of the GTEST_BREAK_ON_FAILURE environment + variable; None if the variable should be unset. + flag_value: value of the --gtest_break_on_failure flag; + None if the flag should not be present. + expect_seg_fault: 1 if the program is expected to generate a seg-fault; + 0 otherwise. + """ + + SetEnvVar(BREAK_ON_FAILURE_ENV_VAR, env_var_value) + + if env_var_value is None: + env_var_value_msg = ' is not set' + else: + env_var_value_msg = '=' + env_var_value + + if flag_value is None: + flag = '' + elif flag_value == '0': + flag = ' --%s=0' % BREAK_ON_FAILURE_FLAG + else: + flag = ' --%s' % BREAK_ON_FAILURE_FLAG + + command = EXE_PATH + flag + + if expect_seg_fault: + should_or_not = 'should' + else: + should_or_not = 'should not' + + has_seg_fault = Run(command) + + SetEnvVar(BREAK_ON_FAILURE_ENV_VAR, None) + + msg = ('when %s%s, an assertion failure in "%s" %s cause a seg-fault.' % + (BREAK_ON_FAILURE_ENV_VAR, env_var_value_msg, command, should_or_not)) + self.assert_(has_seg_fault == expect_seg_fault, msg) + + def testDefaultBehavior(self): + """Tests the behavior of the default mode.""" + + self.RunAndVerify(env_var_value=None, + flag_value=None, + expect_seg_fault=0) + + def testEnvVar(self): + """Tests using the GTEST_BREAK_ON_FAILURE environment variable.""" + + self.RunAndVerify(env_var_value='0', + flag_value=None, + expect_seg_fault=0) + self.RunAndVerify(env_var_value='1', + flag_value=None, + expect_seg_fault=1) + + def testFlag(self): + """Tests using the --gtest_break_on_failure flag.""" + + self.RunAndVerify(env_var_value=None, + flag_value='0', + expect_seg_fault=0) + self.RunAndVerify(env_var_value=None, + flag_value='1', + expect_seg_fault=1) + + def testFlagOverridesEnvVar(self): + """Tests that the flag overrides the environment variable.""" + + self.RunAndVerify(env_var_value='0', + flag_value='0', + expect_seg_fault=0) + self.RunAndVerify(env_var_value='0', + flag_value='1', + expect_seg_fault=1) + self.RunAndVerify(env_var_value='1', + flag_value='0', + expect_seg_fault=0) + self.RunAndVerify(env_var_value='1', + flag_value='1', + expect_seg_fault=1) + + +if __name__ == '__main__': + gtest_test_utils.Main() diff --git a/test/gtest_break_on_failure_unittest_.cc b/test/gtest_break_on_failure_unittest_.cc new file mode 100644 index 00000000..f272fdd5 --- /dev/null +++ b/test/gtest_break_on_failure_unittest_.cc @@ -0,0 +1,59 @@ +// Copyright 2006, 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) + +// Unit test for Google Test's break-on-failure mode. +// +// A user can ask Google Test to seg-fault when an assertion fails, using +// either the GTEST_BREAK_ON_FAILURE environment variable or the +// --gtest_break_on_failure flag. This file is used for testing such +// functionality. +// +// This program will be invoked from a Python unit test. It is +// expected to fail. Don't run it directly. + +#include + + +namespace { + +// A test that's expected to fail. +TEST(Foo, Bar) { + EXPECT_EQ(2, 3); +} + +} // namespace + + +int main(int argc, char **argv) { + testing::InitGoogleTest(&argc, argv); + + return RUN_ALL_TESTS(); +} diff --git a/test/gtest_color_test.py b/test/gtest_color_test.py new file mode 100755 index 00000000..71891768 --- /dev/null +++ b/test/gtest_color_test.py @@ -0,0 +1,123 @@ +#!/usr/bin/env python +# +# Copyright 2008, 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. + +"""Verifies that Google Test correctly determines whether to use colors.""" + +__author__ = 'wan@google.com (Zhanyong Wan)' + +import gtest_test_utils +import os +import sys +import unittest + + +COLOR_ENV_VAR = 'GTEST_COLOR' +COLOR_FLAG = 'gtest_color' +COMMAND = os.path.join(gtest_test_utils.GetBuildDir(), + 'gtest_color_test_') + + +def SetEnvVar(env_var, value): + """Sets the env variable to 'value'; unsets it when 'value' is None.""" + + if value is not None: + os.environ[env_var] = value + elif env_var in os.environ: + del os.environ[env_var] + + +def UsesColor(term, color_env_var, color_flag): + """Runs gtest_color_test_ and returns its exit code.""" + + SetEnvVar('TERM', term) + SetEnvVar(COLOR_ENV_VAR, color_env_var) + cmd = COMMAND + if color_flag is not None: + cmd += ' --%s=%s' % (COLOR_FLAG, color_flag) + return os.system(cmd) + + +class GTestColorTest(unittest.TestCase): + def testNoEnvVarNoFlag(self): + """Tests the case when there's neither GTEST_COLOR nor --gtest_color.""" + + self.assert_(not UsesColor('dumb', None, None)) + self.assert_(not UsesColor('emacs', None, None)) + self.assert_(not UsesColor('xterm-mono', None, None)) + self.assert_(not UsesColor('unknown', None, None)) + self.assert_(not UsesColor(None, None, None)) + self.assert_(UsesColor('cygwin', None, None)) + self.assert_(UsesColor('xterm', None, None)) + self.assert_(UsesColor('xterm-color', None, None)) + + def testFlagOnly(self): + """Tests the case when there's --gtest_color but not GTEST_COLOR.""" + + self.assert_(not UsesColor('dumb', None, 'no')) + self.assert_(not UsesColor('xterm-color', None, 'no')) + self.assert_(not UsesColor('emacs', None, 'auto')) + self.assert_(UsesColor('xterm', None, 'auto')) + self.assert_(UsesColor('dumb', None, 'yes')) + self.assert_(UsesColor('xterm', None, 'yes')) + + def testEnvVarOnly(self): + """Tests the case when there's GTEST_COLOR but not --gtest_color.""" + + self.assert_(not UsesColor('dumb', 'no', None)) + self.assert_(not UsesColor('xterm-color', 'no', None)) + self.assert_(not UsesColor('dumb', 'auto', None)) + self.assert_(UsesColor('xterm-color', 'auto', None)) + self.assert_(UsesColor('dumb', 'yes', None)) + self.assert_(UsesColor('xterm-color', 'yes', None)) + + def testEnvVarAndFlag(self): + """Tests the case when there are both GTEST_COLOR and --gtest_color.""" + + self.assert_(not UsesColor('xterm-color', 'no', 'no')) + self.assert_(UsesColor('dumb', 'no', 'yes')) + self.assert_(UsesColor('xterm-color', 'no', 'auto')) + + def testAliasesOfYesAndNo(self): + """Tests using aliases in specifying --gtest_color.""" + + self.assert_(UsesColor('dumb', None, 'true')) + self.assert_(UsesColor('dumb', None, 'YES')) + self.assert_(UsesColor('dumb', None, 'T')) + self.assert_(UsesColor('dumb', None, '1')) + + self.assert_(not UsesColor('xterm', None, 'f')) + self.assert_(not UsesColor('xterm', None, 'false')) + self.assert_(not UsesColor('xterm', None, '0')) + self.assert_(not UsesColor('xterm', None, 'unknown')) + + +if __name__ == '__main__': + gtest_test_utils.Main() diff --git a/test/gtest_color_test_.cc b/test/gtest_color_test_.cc new file mode 100644 index 00000000..305aeb96 --- /dev/null +++ b/test/gtest_color_test_.cc @@ -0,0 +1,68 @@ +// Copyright 2008, 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) + +// A helper program for testing how Google Test determines whether to use +// colors in the output. It prints "YES" and returns 1 if Google Test +// decides to use colors, and prints "NO" and returns 0 otherwise. + +#include + +#include + +namespace testing { +namespace internal { +bool ShouldUseColor(bool stdout_is_tty); +} // namespace internal +} // namespace testing + +using testing::internal::ShouldUseColor; + +// The purpose of this is to ensure that the UnitTest singleton is +// created before main() is entered, and thus that ShouldUseColor() +// works the same way as in a real Google-Test-based test. We don't actual +// run the TEST itself. +TEST(GTestColorTest, Dummy) { +} + +int main(int argc, char** argv) { + testing::InitGoogleTest(&argc, argv); + + if (ShouldUseColor(true)) { + // Google Test decides to use colors in the output (assuming it + // goes to a TTY). + printf("YES\n"); + return 1; + } else { + // Google Test decides not to use colors in the output. + printf("NO\n"); + return 0; + } +} diff --git a/test/gtest_env_var_test.py b/test/gtest_env_var_test.py new file mode 100755 index 00000000..64d17e85 --- /dev/null +++ b/test/gtest_env_var_test.py @@ -0,0 +1,134 @@ +#!/usr/bin/env python +# +# Copyright 2008, 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. + +"""Verifies that Google Test correctly parses environment variables.""" + +__author__ = 'wan@google.com (Zhanyong Wan)' + +import gtest_test_utils +import os +import sys +import unittest + +IS_WINDOWS = os.name == 'nt' +IS_LINUX = os.name == 'posix' + +if IS_WINDOWS: + BUILD_DIRS = [ + 'build.dbg\\', + 'build.opt\\', + 'build.dbg8\\', + 'build.opt8\\', + ] + COMMAND = 'gtest_env_var_test_.exe' + +if IS_LINUX: + COMMAND = os.path.join(gtest_test_utils.GetBuildDir(), + 'gtest_env_var_test_') + + +def AssertEq(expected, actual): + if expected != actual: + print 'Expected: %s' % (expected,) + print ' Actual: %s' % (actual,) + raise AssertionError + + +def SetEnvVar(env_var, value): + """Sets the env variable to 'value'; unsets it when 'value' is None.""" + + if value is not None: + os.environ[env_var] = value + elif env_var in os.environ: + del os.environ[env_var] + + +def GetFlag(command, flag): + """Runs gtest_env_var_test_ and returns its output.""" + + cmd = command + if flag is not None: + cmd += ' %s' % (flag,) + stdin, stdout = os.popen2(cmd, 'b') + stdin.close() + line = stdout.readline() + stdout.close() + return line + + +def TestFlag(command, flag, test_val, default_val): + """Verifies that the given flag is affected by the corresponding env var.""" + + env_var = 'GTEST_' + flag.upper() + SetEnvVar(env_var, test_val) + AssertEq(test_val, GetFlag(command, flag)) + SetEnvVar(env_var, None) + AssertEq(default_val, GetFlag(command, flag)) + + +def TestEnvVarAffectsFlag(command): + """An environment variable should affect the corresponding flag.""" + + TestFlag(command, 'break_on_failure', '1', '0') + TestFlag(command, 'color', 'yes', 'auto') + TestFlag(command, 'filter', 'FooTest.Bar', '*') + TestFlag(command, 'output', 'tmp/foo.xml', '') + TestFlag(command, 'repeat', '999', '1') + + if IS_WINDOWS: + TestFlag(command, 'catch_exceptions', '1', '0') + if IS_LINUX: + TestFlag(command, 'stack_trace_depth', '0', '100') + TestFlag(command, 'death_test_style', 'thread-safe', 'fast') + + +if IS_WINDOWS: + + def main(): + for build_dir in BUILD_DIRS: + command = build_dir + COMMAND + print 'Testing with %s . . .' % (command,) + TestEnvVarAffectsFlag(command) + return 0 + + if __name__ == '__main__': + main() + + +if IS_LINUX: + + class GTestEnvVarTest(unittest.TestCase): + def testEnvVarAffectsFlag(self): + TestEnvVarAffectsFlag(COMMAND) + + + if __name__ == '__main__': + gtest_test_utils.Main() diff --git a/test/gtest_env_var_test_.cc b/test/gtest_env_var_test_.cc new file mode 100644 index 00000000..81056e84 --- /dev/null +++ b/test/gtest_env_var_test_.cc @@ -0,0 +1,111 @@ +// Copyright 2008, 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) + +// A helper program for testing that Google Test parses the environment +// variables correctly. + +#include + +#include + +#define GTEST_IMPLEMENTATION +#include "src/gtest-internal-inl.h" +#undef GTEST_IMPLEMENTATION + +using ::std::cout; + +namespace testing { + +// The purpose of this is to make the test more realistic by ensuring +// that the UnitTest singleton is created before main() is entered. +// We don't actual run the TEST itself. +TEST(GTestEnvVarTest, Dummy) { +} + +void PrintFlag(const char* flag) { + if (strcmp(flag, "break_on_failure") == 0) { + cout << GTEST_FLAG(break_on_failure); + return; + } + + if (strcmp(flag, "catch_exceptions") == 0) { + cout << GTEST_FLAG(catch_exceptions); + return; + } + + if (strcmp(flag, "color") == 0) { + cout << GTEST_FLAG(color); + return; + } + + if (strcmp(flag, "death_test_style") == 0) { + cout << GTEST_FLAG(death_test_style); + return; + } + + if (strcmp(flag, "filter") == 0) { + cout << GTEST_FLAG(filter); + return; + } + + if (strcmp(flag, "output") == 0) { + cout << GTEST_FLAG(output); + return; + } + + if (strcmp(flag, "repeat") == 0) { + cout << GTEST_FLAG(repeat); + return; + } + + if (strcmp(flag, "stack_trace_depth") == 0) { + cout << GTEST_FLAG(stack_trace_depth); + return; + } + + cout << "Invalid flag name " << flag + << ". Valid names are break_on_failure, color, filter, etc.\n"; + exit(1); +} + +} // namespace testing + +int main(int argc, char** argv) { + testing::InitGoogleTest(&argc, argv); + + if (argc != 2) { + cout << "Usage: gtest_env_var_test_ NAME_OF_FLAG\n"; + return 1; + } + + testing::PrintFlag(argv[1]); + return 0; +} diff --git a/test/gtest_environment_test.cc b/test/gtest_environment_test.cc new file mode 100644 index 00000000..999ed787 --- /dev/null +++ b/test/gtest_environment_test.cc @@ -0,0 +1,186 @@ +// Copyright 2007, 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) +// +// Tests using global test environments. + +#include +#include +#include + +namespace testing { +GTEST_DECLARE_string(filter); +} + +namespace { + +enum FailureType { + NO_FAILURE, NON_FATAL_FAILURE, FATAL_FAILURE +}; + +// For testing using global test environments. +class MyEnvironment : public testing::Environment { + public: + MyEnvironment() { Reset(); } + + // Depending on the value of failure_in_set_up_, SetUp() will + // generate a non-fatal failure, generate a fatal failure, or + // succeed. + virtual void SetUp() { + set_up_was_run_ = true; + + switch (failure_in_set_up_) { + case NON_FATAL_FAILURE: + ADD_FAILURE() << "Expected non-fatal failure in global set-up."; + break; + case FATAL_FAILURE: + FAIL() << "Expected fatal failure in global set-up."; + break; + default: + break; + } + } + + // Generates a non-fatal failure. + virtual void TearDown() { + tear_down_was_run_ = true; + ADD_FAILURE() << "Expected non-fatal failure in global tear-down."; + } + + // Resets the state of the environment s.t. it can be reused. + void Reset() { + failure_in_set_up_ = NO_FAILURE; + set_up_was_run_ = false; + tear_down_was_run_ = false; + } + + // We call this function to set the type of failure SetUp() should + // generate. + void set_failure_in_set_up(FailureType type) { + failure_in_set_up_ = type; + } + + // Was SetUp() run? + bool set_up_was_run() const { return set_up_was_run_; } + + // Was TearDown() run? + bool tear_down_was_run() const { return tear_down_was_run_; } + private: + FailureType failure_in_set_up_; + bool set_up_was_run_; + bool tear_down_was_run_; +}; + +// Was the TEST run? +bool test_was_run; + +// The sole purpose of this TEST is to enable us to check whether it +// was run. +TEST(FooTest, Bar) { + test_was_run = true; +} + +// Prints the message and aborts the program if condition is false. +void Check(bool condition, const char* msg) { + if (!condition) { + printf("FAILED: %s\n", msg); + abort(); + } +} + +// Runs the tests. Return true iff successful. +// +// The 'failure' parameter specifies the type of failure that should +// be generated by the global set-up. +int RunAllTests(MyEnvironment* env, FailureType failure) { + env->Reset(); + env->set_failure_in_set_up(failure); + test_was_run = false; + return RUN_ALL_TESTS(); +} + +} // namespace + +int main(int argc, char **argv) { + testing::InitGoogleTest(&argc, argv); + + // Registers a global test environment, and verifies that the + // registration function returns its argument. + MyEnvironment* const env = new MyEnvironment; + Check(testing::AddGlobalTestEnvironment(env) == env, + "AddGlobalTestEnvironment() should return its argument."); + + // Verifies that RUN_ALL_TESTS() runs the tests when the global + // set-up is successful. + Check(RunAllTests(env, NO_FAILURE) != 0, + "RUN_ALL_TESTS() should return non-zero, as the global tear-down " + "should generate a failure."); + Check(test_was_run, + "The tests should run, as the global set-up should generate no " + "failure"); + Check(env->tear_down_was_run(), + "The global tear-down should run, as the global set-up was run."); + + // Verifies that RUN_ALL_TESTS() runs the tests when the global + // set-up generates no fatal failure. + Check(RunAllTests(env, NON_FATAL_FAILURE) != 0, + "RUN_ALL_TESTS() should return non-zero, as both the global set-up " + "and the global tear-down should generate a non-fatal failure."); + Check(test_was_run, + "The tests should run, as the global set-up should generate no " + "fatal failure."); + Check(env->tear_down_was_run(), + "The global tear-down should run, as the global set-up was run."); + + // Verifies that RUN_ALL_TESTS() runs no test when the global set-up + // generates a fatal failure. + Check(RunAllTests(env, FATAL_FAILURE) != 0, + "RUN_ALL_TESTS() should return non-zero, as the global set-up " + "should generate a fatal failure."); + Check(!test_was_run, + "The tests should not run, as the global set-up should generate " + "a fatal failure."); + Check(env->tear_down_was_run(), + "The global tear-down should run, as the global set-up was run."); + + // Verifies that RUN_ALL_TESTS() doesn't do global set-up or + // tear-down when there is no test to run. + testing::GTEST_FLAG(filter) = "-*"; + Check(RunAllTests(env, NO_FAILURE) == 0, + "RUN_ALL_TESTS() should return zero, as there is no test to run."); + Check(!env->set_up_was_run(), + "The global set-up should not run, as there is no test to run."); + Check(!env->tear_down_was_run(), + "The global tear-down should not run, " + "as the global set-up was not run."); + + printf("PASS\n"); + return 0; +} diff --git a/test/gtest_filter_unittest.py b/test/gtest_filter_unittest.py new file mode 100755 index 00000000..04b69f76 --- /dev/null +++ b/test/gtest_filter_unittest.py @@ -0,0 +1,315 @@ +#!/usr/bin/env python +# +# 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. + +"""Unit test for Google Test test filters. + +A user can specify which test(s) in a Google Test program to run via either +the GTEST_FILTER environment variable or the --gtest_filter flag. +This script tests such functionality by invoking +gtest_filter_unittest_ (a program written with Google Test) with different +environments and command line flags. +""" + +__author__ = 'wan@google.com (Zhanyong Wan)' + +import gtest_test_utils +import os +import re +import sys +import unittest + +# Constants. + +# The environment variable for specifying the test filters. +FILTER_ENV_VAR = 'GTEST_FILTER' + +# The command line flag for specifying the test filters. +FILTER_FLAG = 'gtest_filter' + +# Command to run the gtest_filter_unittest_ program. +COMMAND = os.path.join(gtest_test_utils.GetBuildDir(), + 'gtest_filter_unittest_') + +# Regex for parsing test case names from Google Test's output. +TEST_CASE_REGEX = re.compile(r'^\[\-+\] \d+ test.* from (\w+)') + +# Regex for parsing test names from Google Test's output. +TEST_REGEX = re.compile(r'^\[\s*RUN\s*\].*\.(\w+)') + +# Full names of all tests in gtest_filter_unittests_. +ALL_TESTS = [ + 'FooTest.Abc', + 'FooTest.Xyz', + + 'BarTest.Test1', + 'BarTest.Test2', + 'BarTest.Test3', + + 'BazTest.Test1', + 'BazTest.TestA', + 'BazTest.TestB', + ] + + +# Utilities. + + +def SetEnvVar(env_var, value): + """Sets the env variable to 'value'; unsets it when 'value' is None.""" + + if value is not None: + os.environ[env_var] = value + elif env_var in os.environ: + del os.environ[env_var] + + +def Run(command): + """Runs a Google Test program and returns a list of full names of the + tests that were run. + """ + + stdout_file = os.popen(command, 'r') + tests_run = [] + test_case = '' + test = '' + for line in stdout_file: + match = TEST_CASE_REGEX.match(line) + if match is not None: + test_case = match.group(1) + else: + match = TEST_REGEX.match(line) + if match is not None: + test = match.group(1) + tests_run += [test_case + '.' + test] + stdout_file.close() + return tests_run + + +# The unit test. + + +class GTestFilterUnitTest(unittest.TestCase): + """Tests using the GTEST_FILTER environment variable or the + --gtest_filter flag to filter tests. + """ + + # Utilities. + + def AssertSetEqual(self, lhs, rhs): + """Asserts that two sets are equal.""" + + for elem in lhs: + self.assert_(elem in rhs, '%s in %s' % (elem, rhs)) + + for elem in rhs: + self.assert_(elem in lhs, '%s in %s' % (elem, lhs)) + + def RunAndVerify(self, gtest_filter, tests_to_run): + """Runs gtest_flag_unittest_ with the given filter, and verifies + that the right set of tests were run. + """ + + # First, tests using GTEST_FILTER. + + SetEnvVar(FILTER_ENV_VAR, gtest_filter) + tests_run = Run(COMMAND) + SetEnvVar(FILTER_ENV_VAR, None) + + self.AssertSetEqual(tests_run, tests_to_run) + + # Next, tests using --gtest_filter. + + if gtest_filter is None: + command = COMMAND + else: + command = '%s --%s=%s' % (COMMAND, FILTER_FLAG, gtest_filter) + + tests_run = Run(command) + self.AssertSetEqual(tests_run, tests_to_run) + + def testDefaultBehavior(self): + """Tests the behavior of not specifying the filter.""" + + self.RunAndVerify(None, ALL_TESTS) + + def testEmptyFilter(self): + """Tests an empty filter.""" + + self.RunAndVerify('', []) + + def testBadFilter(self): + """Tests a filter that matches nothing.""" + + self.RunAndVerify('BadFilter', []) + + def testFullName(self): + """Tests filtering by full name.""" + + self.RunAndVerify('FooTest.Xyz', ['FooTest.Xyz']) + + def testUniversalFilters(self): + """Tests filters that match everything.""" + + self.RunAndVerify('*', ALL_TESTS) + self.RunAndVerify('*.*', ALL_TESTS) + + def testFilterByTestCase(self): + """Tests filtering by test case name.""" + + self.RunAndVerify('FooTest.*', ['FooTest.Abc', 'FooTest.Xyz']) + + def testFilterByTest(self): + """Tests filtering by test name.""" + + self.RunAndVerify('*.Test1', ['BarTest.Test1', 'BazTest.Test1']) + + def testWildcardInTestCaseName(self): + """Tests using wildcard in the test case name.""" + + self.RunAndVerify('*a*.*', [ + 'BarTest.Test1', + 'BarTest.Test2', + 'BarTest.Test3', + + 'BazTest.Test1', + 'BazTest.TestA', + 'BazTest.TestB', + ]) + + def testWildcardInTestName(self): + """Tests using wildcard in the test name.""" + + self.RunAndVerify('*.*A*', ['FooTest.Abc', 'BazTest.TestA']) + + def testFilterWithoutDot(self): + """Tests a filter that has no '.' in it.""" + + self.RunAndVerify('*z*', [ + 'FooTest.Xyz', + + 'BazTest.Test1', + 'BazTest.TestA', + 'BazTest.TestB', + ]) + + def testTwoPatterns(self): + """Tests filters that consist of two patterns.""" + + self.RunAndVerify('Foo*.*:*A*', [ + 'FooTest.Abc', + 'FooTest.Xyz', + + 'BazTest.TestA', + ]) + + # An empty pattern + a non-empty one + self.RunAndVerify(':*A*', ['FooTest.Abc', 'BazTest.TestA']) + + def testThreePatterns(self): + """Tests filters that consist of three patterns.""" + + self.RunAndVerify('*oo*:*A*:*1', [ + 'FooTest.Abc', + 'FooTest.Xyz', + + 'BarTest.Test1', + + 'BazTest.Test1', + 'BazTest.TestA', + ]) + + # The 2nd pattern is empty. + self.RunAndVerify('*oo*::*1', [ + 'FooTest.Abc', + 'FooTest.Xyz', + + 'BarTest.Test1', + + 'BazTest.Test1', + ]) + + # The last 2 patterns are empty. + self.RunAndVerify('*oo*::', [ + 'FooTest.Abc', + 'FooTest.Xyz', + ]) + + def testNegativeFilters(self): + self.RunAndVerify('*-FooTest.Abc', [ + 'FooTest.Xyz', + + 'BarTest.Test1', + 'BarTest.Test2', + 'BarTest.Test3', + + 'BazTest.Test1', + 'BazTest.TestA', + 'BazTest.TestB', + ]) + + self.RunAndVerify('*-FooTest.Abc:BazTest.*', [ + 'FooTest.Xyz', + + 'BarTest.Test1', + 'BarTest.Test2', + 'BarTest.Test3', + ]) + + self.RunAndVerify('BarTest.*-BarTest.Test1', [ + 'BarTest.Test2', + 'BarTest.Test3', + ]) + + # Tests without leading '*'. + self.RunAndVerify('-FooTest.Abc:FooTest.Xyz', [ + 'BarTest.Test1', + 'BarTest.Test2', + 'BarTest.Test3', + + 'BazTest.Test1', + 'BazTest.TestA', + 'BazTest.TestB', + ]) + + def testFlagOverridesEnvVar(self): + """Tests that the --gtest_filter flag overrides the GTEST_FILTER + environment variable.""" + + SetEnvVar(FILTER_ENV_VAR, 'Foo*') + command = '%s --%s=%s' % (COMMAND, FILTER_FLAG, '*1') + tests_run = Run(command) + SetEnvVar(FILTER_ENV_VAR, None) + + self.AssertSetEqual(tests_run, ['BarTest.Test1', 'BazTest.Test1']) + + +if __name__ == '__main__': + gtest_test_utils.Main() diff --git a/test/gtest_filter_unittest_.cc b/test/gtest_filter_unittest_.cc new file mode 100644 index 00000000..6ff0d4f5 --- /dev/null +++ b/test/gtest_filter_unittest_.cc @@ -0,0 +1,90 @@ +// 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) + +// Unit test for Google Test test filters. +// +// A user can specify which test(s) in a Google Test program to run via +// either the GTEST_FILTER environment variable or the --gtest_filter +// flag. This is used for testing such functionality. +// +// The program will be invoked from a Python unit test. Don't run it +// directly. + +#include + + +namespace { + +// Test case FooTest. + +class FooTest : public testing::Test { +}; + +TEST_F(FooTest, Abc) { +} + +TEST_F(FooTest, Xyz) { + FAIL() << "Expected failure."; +} + + +// Test case BarTest. + +TEST(BarTest, Test1) { +} + +TEST(BarTest, Test2) { +} + +TEST(BarTest, Test3) { +} + + +// Test case BazTest. + +TEST(BazTest, Test1) { + FAIL() << "Expected failure."; +} + +TEST(BazTest, TestA) { +} + +TEST(BazTest, TestB) { +} + +} // namespace + + +int main(int argc, char **argv) { + testing::InitGoogleTest(&argc, argv); + + return RUN_ALL_TESTS(); +} diff --git a/test/gtest_list_tests_unittest.py b/test/gtest_list_tests_unittest.py new file mode 100755 index 00000000..9cefa15c --- /dev/null +++ b/test/gtest_list_tests_unittest.py @@ -0,0 +1,165 @@ +#!/usr/bin/env python +# +# Copyright 2006, 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. + +"""Unit test for Google Test's --gtest_list_tests flag. + +A user can ask Google Test to list all tests by specifying the +--gtest_list_tests flag. This script tests such functionality +by invoking gtest_list_tests_unittest_ (a program written with +Google Test) the command line flags. +""" + +__author__ = 'phanna@google.com (Patrick Hanna)' + +import gtest_test_utils +import os +import re +import sys +import unittest + + +# Constants. + +# The command line flag for enabling/disabling listing all tests. +LIST_TESTS_FLAG = 'gtest_list_tests' + +# Path to the gtest_list_tests_unittest_ program. +EXE_PATH = os.path.join(gtest_test_utils.GetBuildDir(), + 'gtest_list_tests_unittest_'); + +# The expected output when running gtest_list_tests_unittest_ with +# --gtest_list_tests +EXPECTED_OUTPUT = """FooDeathTest. + Test1 +Foo. + Bar1 + Bar2 + Bar3 +Abc. + Xyz + Def +FooBar. + Baz +FooTest. + Test1 + Test2 + Test3 +""" + +# Utilities. + +def Run(command): + """Runs a command and returns the list of tests printed. + """ + + stdout_file = os.popen(command, "r") + + output = stdout_file.read() + + stdout_file.close() + return output + + +# The unit test. + +class GTestListTestsUnitTest(unittest.TestCase): + """Tests using the --gtest_list_tests flag to list all tests. + """ + + def RunAndVerify(self, flag_value, expected_output, other_flag): + """Runs gtest_list_tests_unittest_ and verifies that it prints + the correct tests. + + Args: + flag_value: value of the --gtest_list_tests flag; + None if the flag should not be present. + + expected_output: the expected output after running command; + + other_flag: a different flag to be passed to command + along with gtest_list_tests; + None if the flag should not be present. + """ + + if flag_value is None: + flag = '' + flag_expression = "not set" + elif flag_value == '0': + flag = ' --%s=0' % LIST_TESTS_FLAG + flag_expression = "0" + else: + flag = ' --%s' % LIST_TESTS_FLAG + flag_expression = "1" + + command = EXE_PATH + flag + + if other_flag is not None: + command += " " + other_flag + + output = Run(command) + + msg = ('when %s is %s, the output of "%s" is "%s".' % + (LIST_TESTS_FLAG, flag_expression, command, output)) + + if expected_output is not None: + self.assert_(output == expected_output, msg) + else: + self.assert_(output != EXPECTED_OUTPUT, msg) + + def testDefaultBehavior(self): + """Tests the behavior of the default mode.""" + + self.RunAndVerify(flag_value=None, + expected_output=None, + other_flag=None) + + def testFlag(self): + """Tests using the --gtest_list_tests flag.""" + + self.RunAndVerify(flag_value='0', + expected_output=None, + other_flag=None) + self.RunAndVerify(flag_value='1', + expected_output=EXPECTED_OUTPUT, + other_flag=None) + + def testOverrideOtherFlags(self): + """Tests that --gtest_list_tests overrides all other flags.""" + + self.RunAndVerify(flag_value="1", + expected_output=EXPECTED_OUTPUT, + other_flag="--gtest_filter=*") + self.RunAndVerify(flag_value="1", + expected_output=EXPECTED_OUTPUT, + other_flag="--gtest_break_on_failure") + +if __name__ == '__main__': + gtest_test_utils.Main() diff --git a/test/gtest_list_tests_unittest_.cc b/test/gtest_list_tests_unittest_.cc new file mode 100644 index 00000000..566694b2 --- /dev/null +++ b/test/gtest_list_tests_unittest_.cc @@ -0,0 +1,87 @@ +// Copyright 2006, 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: phanna@google.com (Patrick Hanna) + +// Unit test for Google Test's --gtest_list_tests flag. +// +// A user can ask Google Test to list all tests that will run +// so that when using a filter, a user will know what +// tests to look for. The tests will not be run after listing. +// +// This program will be invoked from a Python unit test. +// Don't run it directly. + +#include + + +namespace { + +// Several different test cases and tests that will be listed. +TEST(Foo, Bar1) { +} + +TEST(Foo, Bar2) { +} + +TEST(Foo, Bar3) { +} + +TEST(Abc, Xyz) { +} + +TEST(Abc, Def) { +} + +TEST(FooBar, Baz) { +} + +class FooTest : public testing::Test { +}; + +TEST_F(FooTest, Test1) { +} + +TEST_F(FooTest, Test2) { +} + +TEST_F(FooTest, Test3) { +} + +TEST(FooDeathTest, Test1) { +} + +} // namespace + + +int main(int argc, char **argv) { + testing::InitGoogleTest(&argc, argv); + + return RUN_ALL_TESTS(); +} diff --git a/test/gtest_main_unittest.cc b/test/gtest_main_unittest.cc new file mode 100644 index 00000000..7a3f0adf --- /dev/null +++ b/test/gtest_main_unittest.cc @@ -0,0 +1,45 @@ +// Copyright 2006, 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) + +#include + +// Tests that we don't have to define main() when we link to +// gtest_main instead of gtest. + +namespace { + +TEST(GTestMainTest, ShouldSucceed) { +} + +} // namespace + +// We are using the main() function defined in src/gtest_main.cc, so +// we don't define it here. diff --git a/test/gtest_nc.cc b/test/gtest_nc.cc new file mode 100644 index 00000000..001deb1b --- /dev/null +++ b/test/gtest_nc.cc @@ -0,0 +1,115 @@ +// Copyright 2007, 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) + +// This file is the input to a negative-compilation test for Google +// Test. Code here is NOT supposed to compile. Its purpose is to +// verify that certain incorrect usages of the Google Test API are +// indeed rejected by the compiler. +// +// We still need to write the negative-compilation test itself, which +// will be tightly coupled with the build environment. +// +// TODO(wan@google.com): finish the negative-compilation test. + +#ifdef TEST_CANNOT_IGNORE_RUN_ALL_TESTS_RESULT +// Tests that the result of RUN_ALL_TESTS() cannot be ignored. + +#include + +int main(int argc, char** argv) { + testing::InitGoogleTest(&argc, argv); + RUN_ALL_TESTS(); // This line shouldn't compile. +} + +#elif defined(TEST_USER_CANNOT_INCLUDE_GTEST_INTERNAL_INL_H) +// Tests that a user cannot include gtest-internal-inl.h in his code. + +#include "src/gtest-internal-inl.h" + +#elif defined(TEST_CATCHES_DECLARING_SETUP_IN_TEST_FIXTURE_WITH_TYPO) +// Tests that the compiler catches the typo when a user declares a +// Setup() method in a test fixture. + +#include + +class MyTest : public testing::Test { + protected: + void Setup() {} +}; + +#elif defined(TEST_CATCHES_CALLING_SETUP_IN_TEST_WITH_TYPO) +// Tests that the compiler catches the typo when a user calls Setup() +// from a test fixture. + +#include + +class MyTest : public testing::Test { + protected: + virtual void SetUp() { + testing::Test::Setup(); // Tries to call SetUp() in the parent class. + } +}; + +#elif defined(TEST_CATCHES_DECLARING_SETUP_IN_ENVIRONMENT_WITH_TYPO) +// Tests that the compiler catches the typo when a user declares a +// Setup() method in a subclass of Environment. + +#include + +class MyEnvironment : public testing::Environment { + public: + void Setup() {} +}; + +#elif defined(TEST_CATCHES_CALLING_SETUP_IN_ENVIRONMENT_WITH_TYPO) +// Tests that the compiler catches the typo when a user calls Setup() +// in an Environment. + +#include + +class MyEnvironment : public testing::Environment { + protected: + virtual void SetUp() { + // Tries to call SetUp() in the parent class. + testing::Environment::Setup(); + } +}; + +#else +// A sanity test. This should compile. + +#include + +int main() { + return RUN_ALL_TESTS(); +} + +#endif diff --git a/test/gtest_nc_test.py b/test/gtest_nc_test.py new file mode 100755 index 00000000..f63feaa7 --- /dev/null +++ b/test/gtest_nc_test.py @@ -0,0 +1,77 @@ +#!/usr/bin/env python +# +# Copyright 2007, 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. + +"""Negative compilation test for Google Test.""" + +__author__ = 'wan@google.com (Zhanyong Wan)' + +import os +import sys +import unittest + + +class GTestNCTest(unittest.TestCase): + """Negative compilation test for Google Test.""" + + def testCompilerError(self): + """Verifies that erroneous code leads to expected compiler + messages.""" + + # Defines a list of test specs, where each element is a tuple + # (test name, list of regexes for matching the compiler errors). + test_specs = [ + ('CANNOT_IGNORE_RUN_ALL_TESTS_RESULT', + [r'ignoring return value']), + + ('USER_CANNOT_INCLUDE_GTEST_INTERNAL_INL_H', + [r'must not be included except by Google Test itself']), + + ('CATCHES_DECLARING_SETUP_IN_TEST_FIXTURE_WITH_TYPO', + [r'Setup_should_be_spelled_SetUp']), + + ('CATCHES_CALLING_SETUP_IN_TEST_WITH_TYPO', + [r'Setup_should_be_spelled_SetUp']), + + ('CATCHES_DECLARING_SETUP_IN_ENVIRONMENT_WITH_TYPO', + [r'Setup_should_be_spelled_SetUp']), + + ('CATCHES_CALLING_SETUP_IN_ENVIRONMENT_WITH_TYPO', + [r'Setup_should_be_spelled_SetUp']), + + ('SANITY', + None) + ] + + # TODO(wan@google.com): verify that the test specs are satisfied. + + +if __name__ == '__main__': + unittest.main() diff --git a/test/gtest_no_test_unittest.cc b/test/gtest_no_test_unittest.cc new file mode 100644 index 00000000..afe2dc0c --- /dev/null +++ b/test/gtest_no_test_unittest.cc @@ -0,0 +1,54 @@ +// Copyright 2006, 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. + +// Tests that a Google Test program that has no test defined can run +// successfully. +// +// Author: wan@google.com (Zhanyong Wan) + +#include + + +int main(int argc, char **argv) { + testing::InitGoogleTest(&argc, argv); + + // An ad-hoc assertion outside of all tests. + // + // This serves two purposes: + // + // 1. It verifies that an ad-hoc assertion can be executed even if + // no test is defined. + // 2. We had a bug where the XML output won't be generated if an + // assertion is executed before RUN_ALL_TESTS() is called, even + // though --gtest_output=xml is specified. This makes sure the + // bug is fixed and doesn't regress. + EXPECT_EQ(1, 1); + + return RUN_ALL_TESTS(); +} diff --git a/test/gtest_output_test.py b/test/gtest_output_test.py new file mode 100755 index 00000000..0fea034f --- /dev/null +++ b/test/gtest_output_test.py @@ -0,0 +1,183 @@ +#!/usr/bin/env python +# +# Copyright 2008, 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. + +"""Tests the text output of Google C++ Testing Framework. + +SYNOPSIS + gtest_output_test.py --gengolden + gtest_output_test.py +""" + +__author__ = 'wan@google.com (Zhanyong Wan)' + +import gtest_test_utils +import os +import re +import string +import sys +import unittest + + +# The flag for generating the golden file +GENGOLDEN_FLAG = '--gengolden' + +IS_WINDOWS = os.name == 'nt' + +if IS_WINDOWS: + PROGRAM = r'..\build.dbg8\gtest_output_test_.exe' + GOLDEN_NAME = 'gtest_output_test_golden_win.txt' +else: + PROGRAM = 'gtest_output_test_' + GOLDEN_NAME = 'gtest_output_test_golden_lin.txt' + +COMMAND = os.path.join(gtest_test_utils.GetBuildDir(), + PROGRAM) + ' --gtest_color=yes' + +GOLDEN_PATH = os.path.join(gtest_test_utils.GetSourceDir(), + GOLDEN_NAME) + +def ToUnixLineEnding(s): + """Changes all Windows/Mac line endings in s to UNIX line endings.""" + + return s.replace('\r\n', '\n').replace('\r', '\n') + + +def RemoveLocations(output): + """Removes all file location info from a Google Test program's output. + + Args: + output: the output of a Google Test program. + + Returns: + output with all file location info (in the form of + 'DIRECTORY/FILE_NAME:LINE_NUMBER: ') replaced by + 'FILE_NAME:#: '. + """ + + return re.sub(r'.*[/\\](.+)\:\d+\: ', r'\1:#: ', output) + + +def RemoveStackTraces(output): + """Removes all stack traces from a Google Test program's output.""" + + # *? means "find the shortest string that matches". + return re.sub(r'Stack trace:(.|\n)*?\n\n', + 'Stack trace: (omitted)\n\n', output) + + +def NormalizeOutput(output): + """Normalizes output (the output of gtest_output_test_.exe).""" + + output = ToUnixLineEnding(output) + output = RemoveLocations(output) + output = RemoveStackTraces(output) + return output + + +def IterShellCommandOutput(cmd, stdin_string=None): + """Runs a command in a sub-process, and iterates the lines in its STDOUT. + + Args: + + cmd: The shell command. + stdin_string: The string to be fed to the STDIN of the sub-process; + If None, the sub-process will inherit the STDIN + from the parent process. + """ + + # Spawns cmd in a sub-process, and gets its standard I/O file objects. + stdin_file, stdout_file = os.popen2(cmd, 'b') + + # If the caller didn't specify a string for STDIN, gets it from the + # parent process. + if stdin_string is None: + stdin_string = sys.stdin.read() + + # Feeds the STDIN string to the sub-process. + stdin_file.write(stdin_string) + stdin_file.close() + + while True: + line = stdout_file.readline() + if not line: # EOF + stdout_file.close() + break + + yield line + + +def GetShellCommandOutput(cmd, stdin_string=None): + """Runs a command in a sub-process, and returns its STDOUT in a string. + + Args: + + cmd: The shell command. + stdin_string: The string to be fed to the STDIN of the sub-process; + If None, the sub-process will inherit the STDIN + from the parent process. + """ + + lines = list(IterShellCommandOutput(cmd, stdin_string)) + return string.join(lines, '') + + +def GetCommandOutput(cmd): + """Runs a command and returns its output with all file location + info stripped off. + + Args: + cmd: the shell command. + """ + + # Disables exception pop-ups on Windows. + os.environ['GUNIT_CATCH_EXCEPTIONS'] = '1' + return NormalizeOutput(GetShellCommandOutput(cmd, '')) + + +class GTestOutputTest(unittest.TestCase): + def testOutput(self): + output = GetCommandOutput(COMMAND) + + golden_file = open(GOLDEN_PATH, 'rb') + golden = golden_file.read() + golden_file.close() + + self.assertEquals(golden, output) + + +if __name__ == '__main__': + if sys.argv[1:] == [GENGOLDEN_FLAG]: + output = GetCommandOutput(COMMAND) + golden_file = open(GOLDEN_PATH, 'wb') + golden_file.write(output) + golden_file.close() + else: + gtest_test_utils.Main() diff --git a/test/gtest_output_test_.cc b/test/gtest_output_test_.cc new file mode 100644 index 00000000..d9f3f9e2 --- /dev/null +++ b/test/gtest_output_test_.cc @@ -0,0 +1,755 @@ +// 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. +// +// A unit test for Google Test itself. This verifies that the basic +// constructs of Google Test work. +// +// Author: wan@google.com (Zhanyong Wan) + +#include +#include + +// Indicates that this translation unit is part of Google Test's +// implementation. It must come before gtest-internal-inl.h is +// included, or there will be a compiler error. This trick is to +// prevent a user from accidentally including gtest-internal-inl.h in +// his code. +#define GTEST_IMPLEMENTATION +#include "src/gtest-internal-inl.h" +#undef GTEST_IMPLEMENTATION + +#include + +#ifdef GTEST_OS_LINUX +#include +#include +#include +#include +#include +#endif // GTEST_OS_LINUX + +// Tests catching fatal failures. + +// A subroutine used by the following test. +void TestEq1(int x) { + ASSERT_EQ(1, x); +} + +// This function calls a test subroutine, catches the fatal failure it +// generates, and then returns early. +void TryTestSubroutine() { + // Calls a subrountine that yields a fatal failure. + TestEq1(2); + + // Catches the fatal failure and aborts the test. + // + // The testing::Test:: prefix is necessary when calling + // HasFatalFailure() outside of a TEST, TEST_F, or test fixture. + if (testing::Test::HasFatalFailure()) return; + + // If we get here, something is wrong. + FAIL() << "This should never be reached."; +} + +// Tests catching a fatal failure in a subroutine. +TEST(FatalFailureTest, FatalFailureInSubroutine) { + printf("(expecting a failure that x should be 1)\n"); + + TryTestSubroutine(); +} + +// Tests catching a fatal failure in a nested subroutine. +TEST(FatalFailureTest, FatalFailureInNestedSubroutine) { + printf("(expecting a failure that x should be 1)\n"); + + // Calls a subrountine that yields a fatal failure. + TryTestSubroutine(); + + // Catches the fatal failure and aborts the test. + // + // When calling HasFatalFailure() inside a TEST, TEST_F, or test + // fixture, the testing::Test:: prefix is not needed. + if (HasFatalFailure()) return; + + // If we get here, something is wrong. + FAIL() << "This should never be reached."; +} + +// Tests HasFatalFailure() after a failed EXPECT check. +TEST(FatalFailureTest, NonfatalFailureInSubroutine) { + printf("(expecting a failure on false)\n"); + EXPECT_TRUE(false); // Generates a nonfatal failure + ASSERT_FALSE(HasFatalFailure()); // This should succeed. +} + +// Tests interleaving user logging and Google Test assertions. +TEST(LoggingTest, InterleavingLoggingAndAssertions) { + static const int a[4] = { + 3, 9, 2, 6 + }; + + printf("(expecting 2 failures on (3) >= (a[i]))\n"); + for (int i = 0; i < static_cast(sizeof(a)/sizeof(*a)); i++) { + printf("i == %d\n", i); + EXPECT_GE(3, a[i]); + } +} + +// Tests the SCOPED_TRACE macro. + +// A helper function for testing SCOPED_TRACE. +void SubWithoutTrace(int n) { + EXPECT_EQ(1, n); + ASSERT_EQ(2, n); +} + +// Another helper function for testing SCOPED_TRACE. +void SubWithTrace(int n) { + SCOPED_TRACE(testing::Message() << "n = " << n); + + SubWithoutTrace(n); +} + +// Tests that SCOPED_TRACE() obeys lexical scopes. +TEST(SCOPED_TRACETest, ObeysScopes) { + printf("(expected to fail)\n"); + + // There should be no trace before SCOPED_TRACE() is invoked. + ADD_FAILURE() << "This failure is expected, and shouldn't have a trace."; + + { + SCOPED_TRACE("Expected trace"); + // After SCOPED_TRACE(), a failure in the current scope should contain + // the trace. + ADD_FAILURE() << "This failure is expected, and should have a trace."; + } + + // Once the control leaves the scope of the SCOPED_TRACE(), there + // should be no trace again. + ADD_FAILURE() << "This failure is expected, and shouldn't have a trace."; +} + +// Tests that SCOPED_TRACE works inside a loop. +TEST(SCOPED_TRACETest, WorksInLoop) { + printf("(expected to fail)\n"); + + for (int i = 1; i <= 2; i++) { + SCOPED_TRACE(testing::Message() << "i = " << i); + + SubWithoutTrace(i); + } +} + +// Tests that SCOPED_TRACE works in a subroutine. +TEST(SCOPED_TRACETest, WorksInSubroutine) { + printf("(expected to fail)\n"); + + SubWithTrace(1); + SubWithTrace(2); +} + +// Tests that SCOPED_TRACE can be nested. +TEST(SCOPED_TRACETest, CanBeNested) { + printf("(expected to fail)\n"); + + SCOPED_TRACE(""); // A trace without a message. + + SubWithTrace(2); +} + +// Tests that multiple SCOPED_TRACEs can be used in the same scope. +TEST(SCOPED_TRACETest, CanBeRepeated) { + printf("(expected to fail)\n"); + + SCOPED_TRACE("A"); + ADD_FAILURE() + << "This failure is expected, and should contain trace point A."; + + SCOPED_TRACE("B"); + ADD_FAILURE() + << "This failure is expected, and should contain trace point A and B."; + + { + SCOPED_TRACE("C"); + ADD_FAILURE() << "This failure is expected, and should contain " + << "trace point A, B, and C."; + } + + SCOPED_TRACE("D"); + ADD_FAILURE() << "This failure is expected, and should contain " + << "trace point A, B, and D."; +} + +// Tests using assertions outside of TEST and TEST_F. +// +// This function creates two failures intentionally. +void AdHocTest() { + printf("The non-test part of the code is expected to have 2 failures.\n\n"); + EXPECT_TRUE(false); + EXPECT_EQ(2, 3); +} + + +// Runs all TESTs, all TEST_Fs, and the ad hoc test. +int RunAllTests() { + AdHocTest(); + return RUN_ALL_TESTS(); +} + +// Tests non-fatal failures in the fixture constructor. +class NonFatalFailureInFixtureConstructorTest : public testing::Test { + protected: + NonFatalFailureInFixtureConstructorTest() { + printf("(expecting 5 failures)\n"); + ADD_FAILURE() << "Expected failure #1, in the test fixture c'tor."; + } + + ~NonFatalFailureInFixtureConstructorTest() { + ADD_FAILURE() << "Expected failure #5, in the test fixture d'tor."; + } + + virtual void SetUp() { + ADD_FAILURE() << "Expected failure #2, in SetUp()."; + } + + virtual void TearDown() { + ADD_FAILURE() << "Expected failure #4, in TearDown."; + } +}; + +TEST_F(NonFatalFailureInFixtureConstructorTest, FailureInConstructor) { + ADD_FAILURE() << "Expected failure #3, in the test body."; +} + +// Tests fatal failures in the fixture constructor. +class FatalFailureInFixtureConstructorTest : public testing::Test { + protected: + FatalFailureInFixtureConstructorTest() { + printf("(expecting 2 failures)\n"); + Init(); + } + + ~FatalFailureInFixtureConstructorTest() { + ADD_FAILURE() << "Expected failure #2, in the test fixture d'tor."; + } + + virtual void SetUp() { + ADD_FAILURE() << "UNEXPECTED failure in SetUp(). " + << "We should never get here, as the test fixture c'tor " + << "had a fatal failure."; + } + + virtual void TearDown() { + ADD_FAILURE() << "UNEXPECTED failure in TearDown(). " + << "We should never get here, as the test fixture c'tor " + << "had a fatal failure."; + } + private: + void Init() { + FAIL() << "Expected failure #1, in the test fixture c'tor."; + } +}; + +TEST_F(FatalFailureInFixtureConstructorTest, FailureInConstructor) { + ADD_FAILURE() << "UNEXPECTED failure in the test body. " + << "We should never get here, as the test fixture c'tor " + << "had a fatal failure."; +} + +// Tests non-fatal failures in SetUp(). +class NonFatalFailureInSetUpTest : public testing::Test { + protected: + virtual ~NonFatalFailureInSetUpTest() { + Deinit(); + } + + virtual void SetUp() { + printf("(expecting 4 failures)\n"); + ADD_FAILURE() << "Expected failure #1, in SetUp()."; + } + + virtual void TearDown() { + FAIL() << "Expected failure #3, in TearDown()."; + } + private: + void Deinit() { + FAIL() << "Expected failure #4, in the test fixture d'tor."; + } +}; + +TEST_F(NonFatalFailureInSetUpTest, FailureInSetUp) { + FAIL() << "Expected failure #2, in the test function."; +} + +// Tests fatal failures in SetUp(). +class FatalFailureInSetUpTest : public testing::Test { + protected: + virtual ~FatalFailureInSetUpTest() { + Deinit(); + } + + virtual void SetUp() { + printf("(expecting 3 failures)\n"); + FAIL() << "Expected failure #1, in SetUp()."; + } + + virtual void TearDown() { + FAIL() << "Expected failure #2, in TearDown()."; + } + private: + void Deinit() { + FAIL() << "Expected failure #3, in the test fixture d'tor."; + } +}; + +TEST_F(FatalFailureInSetUpTest, FailureInSetUp) { + FAIL() << "UNEXPECTED failure in the test function. " + << "We should never get here, as SetUp() failed."; +} + +#ifdef GTEST_OS_WINDOWS + +// This group of tests verifies that Google Test handles SEH and C++ +// exceptions correctly. + +// A function that throws an SEH exception. +static void ThrowSEH() { + int* p = NULL; + *p = 0; // Raises an access violation. +} + +// Tests exceptions thrown in the test fixture constructor. +class ExceptionInFixtureCtorTest : public testing::Test { + protected: + ExceptionInFixtureCtorTest() { + printf("(expecting a failure on thrown exception " + "in the test fixture's constructor)\n"); + + ThrowSEH(); + } + + virtual ~ExceptionInFixtureCtorTest() { + Deinit(); + } + + virtual void SetUp() { + FAIL() << "UNEXPECTED failure in SetUp(). " + << "We should never get here, as the test fixture c'tor threw."; + } + + virtual void TearDown() { + FAIL() << "UNEXPECTED failure in TearDown(). " + << "We should never get here, as the test fixture c'tor threw."; + } + private: + void Deinit() { + FAIL() << "UNEXPECTED failure in the d'tor. " + << "We should never get here, as the test fixture c'tor threw."; + } +}; + +TEST_F(ExceptionInFixtureCtorTest, ExceptionInFixtureCtor) { + FAIL() << "UNEXPECTED failure in the test function. " + << "We should never get here, as the test fixture c'tor threw."; +} + +// Tests exceptions thrown in SetUp(). +class ExceptionInSetUpTest : public testing::Test { + protected: + virtual ~ExceptionInSetUpTest() { + Deinit(); + } + + virtual void SetUp() { + printf("(expecting 3 failures)\n"); + + ThrowSEH(); + } + + virtual void TearDown() { + FAIL() << "Expected failure #2, in TearDown()."; + } + private: + void Deinit() { + FAIL() << "Expected failure #3, in the test fixture d'tor."; + } +}; + +TEST_F(ExceptionInSetUpTest, ExceptionInSetUp) { + FAIL() << "UNEXPECTED failure in the test function. " + << "We should never get here, as SetUp() threw."; +} + +// Tests that TearDown() and the test fixture d'tor are always called, +// even when the test function throws an exception. +class ExceptionInTestFunctionTest : public testing::Test { + protected: + virtual ~ExceptionInTestFunctionTest() { + Deinit(); + } + + virtual void TearDown() { + FAIL() << "Expected failure #2, in TearDown()."; + } + private: + void Deinit() { + FAIL() << "Expected failure #3, in the test fixture d'tor."; + } +}; + +// Tests that the test fixture d'tor is always called, even when the +// test function throws an SEH exception. +TEST_F(ExceptionInTestFunctionTest, SEH) { + printf("(expecting 3 failures)\n"); + + ThrowSEH(); +} + +#if GTEST_HAS_EXCEPTIONS + +// Tests that the test fixture d'tor is always called, even when the +// test function throws a C++ exception. We do this only when +// GTEST_HAS_EXCEPTIONS is non-zero, i.e. C++ exceptions are enabled. +TEST_F(ExceptionInTestFunctionTest, CppException) { + throw 1; +} + +// Tests exceptions thrown in TearDown(). +class ExceptionInTearDownTest : public testing::Test { + protected: + virtual ~ExceptionInTearDownTest() { + Deinit(); + } + + virtual void TearDown() { + throw 1; + } + private: + void Deinit() { + FAIL() << "Expected failure #2, in the test fixture d'tor."; + } +}; + +TEST_F(ExceptionInTearDownTest, ExceptionInTearDown) { + printf("(expecting 2 failures)\n"); +} + +#endif // GTEST_HAS_EXCEPTIONS + +#endif // GTEST_OS_WINDOWS + +// The MixedUpTestCaseTest test case verifies that Google Test will fail a +// test if it uses a different fixture class than what other tests in +// the same test case use. It deliberately contains two fixture +// classes with the same name but defined in different namespaces. + +// The MixedUpTestCaseWithSameTestNameTest test case verifies that +// when the user defines two tests with the same test case name AND +// same test name (but in different namespaces), the second test will +// fail. + +namespace foo { + +class MixedUpTestCaseTest : public testing::Test { +}; + +TEST_F(MixedUpTestCaseTest, FirstTestFromNamespaceFoo) {} +TEST_F(MixedUpTestCaseTest, SecondTestFromNamespaceFoo) {} + +class MixedUpTestCaseWithSameTestNameTest : public testing::Test { +}; + +TEST_F(MixedUpTestCaseWithSameTestNameTest, + TheSecondTestWithThisNameShouldFail) {} + +} // namespace foo + +namespace bar { + +class MixedUpTestCaseTest : public testing::Test { +}; + +// The following two tests are expected to fail. We rely on the +// golden file to check that Google Test generates the right error message. +TEST_F(MixedUpTestCaseTest, ThisShouldFail) {} +TEST_F(MixedUpTestCaseTest, ThisShouldFailToo) {} + +class MixedUpTestCaseWithSameTestNameTest : public testing::Test { +}; + +// Expected to fail. We rely on the golden file to check that Google Test +// generates the right error message. +TEST_F(MixedUpTestCaseWithSameTestNameTest, + TheSecondTestWithThisNameShouldFail) {} + +} // namespace bar + +// The following two test cases verify that Google Test catches the user +// error of mixing TEST and TEST_F in the same test case. The first +// test case checks the scenario where TEST_F appears before TEST, and +// the second one checks where TEST appears before TEST_F. + +class TEST_F_before_TEST_in_same_test_case : public testing::Test { +}; + +TEST_F(TEST_F_before_TEST_in_same_test_case, DefinedUsingTEST_F) {} + +// Expected to fail. We rely on the golden file to check that Google Test +// generates the right error message. +TEST(TEST_F_before_TEST_in_same_test_case, DefinedUsingTESTAndShouldFail) {} + +class TEST_before_TEST_F_in_same_test_case : public testing::Test { +}; + +TEST(TEST_before_TEST_F_in_same_test_case, DefinedUsingTEST) {} + +// Expected to fail. We rely on the golden file to check that Google Test +// generates the right error message. +TEST_F(TEST_before_TEST_F_in_same_test_case, DefinedUsingTEST_FAndShouldFail) { +} + +// Used for testing EXPECT_NONFATAL_FAILURE() and EXPECT_FATAL_FAILURE(). +int global_integer = 0; + +// Tests that EXPECT_NONFATAL_FAILURE() can reference global variables. +TEST(ExpectNonfatalFailureTest, CanReferenceGlobalVariables) { + global_integer = 0; + EXPECT_NONFATAL_FAILURE({ + EXPECT_EQ(1, global_integer) << "Expected non-fatal failure."; + }, "Expected non-fatal failure."); +} + +// Tests that EXPECT_NONFATAL_FAILURE() can reference local variables +// (static or not). +TEST(ExpectNonfatalFailureTest, CanReferenceLocalVariables) { + int m = 0; + static int n; + n = 1; + EXPECT_NONFATAL_FAILURE({ + EXPECT_EQ(m, n) << "Expected non-fatal failure."; + }, "Expected non-fatal failure."); +} + +// Tests that EXPECT_NONFATAL_FAILURE() succeeds when there is exactly +// one non-fatal failure and no fatal failure. +TEST(ExpectNonfatalFailureTest, SucceedsWhenThereIsOneNonfatalFailure) { + EXPECT_NONFATAL_FAILURE({ + ADD_FAILURE() << "Expected non-fatal failure."; + }, "Expected non-fatal failure."); +} + +// Tests that EXPECT_NONFATAL_FAILURE() fails when there is no +// non-fatal failure. +TEST(ExpectNonfatalFailureTest, FailsWhenThereIsNoNonfatalFailure) { + printf("(expecting a failure)\n"); + EXPECT_NONFATAL_FAILURE({ + }, ""); +} + +// Tests that EXPECT_NONFATAL_FAILURE() fails when there are two +// non-fatal failures. +TEST(ExpectNonfatalFailureTest, FailsWhenThereAreTwoNonfatalFailures) { + printf("(expecting a failure)\n"); + EXPECT_NONFATAL_FAILURE({ + ADD_FAILURE() << "Expected non-fatal failure 1."; + ADD_FAILURE() << "Expected non-fatal failure 2."; + }, ""); +} + +// Tests that EXPECT_NONFATAL_FAILURE() fails when there is one fatal +// failure. +TEST(ExpectNonfatalFailureTest, FailsWhenThereIsOneFatalFailure) { + printf("(expecting a failure)\n"); + EXPECT_NONFATAL_FAILURE({ + FAIL() << "Expected fatal failure."; + }, ""); +} + +// Tests that EXPECT_NONFATAL_FAILURE() fails when the statement being +// tested returns. +TEST(ExpectNonfatalFailureTest, FailsWhenStatementReturns) { + printf("(expecting a failure)\n"); + EXPECT_NONFATAL_FAILURE({ + return; + }, ""); +} + +#if GTEST_HAS_EXCEPTIONS + +// Tests that EXPECT_NONFATAL_FAILURE() fails when the statement being +// tested throws. +TEST(ExpectNonfatalFailureTest, FailsWhenStatementThrows) { + printf("(expecting a failure)\n"); + try { + EXPECT_NONFATAL_FAILURE({ + throw 0; + }, ""); + } catch(int) { // NOLINT + } +} + +#endif // GTEST_HAS_EXCEPTIONS + +// Tests that EXPECT_FATAL_FAILURE() can reference global variables. +TEST(ExpectFatalFailureTest, CanReferenceGlobalVariables) { + global_integer = 0; + EXPECT_FATAL_FAILURE({ + ASSERT_EQ(1, global_integer) << "Expected fatal failure."; + }, "Expected fatal failure."); +} + +// Tests that EXPECT_FATAL_FAILURE() can reference local static +// variables. +TEST(ExpectFatalFailureTest, CanReferenceLocalStaticVariables) { + static int n; + n = 1; + EXPECT_FATAL_FAILURE({ + ASSERT_EQ(0, n) << "Expected fatal failure."; + }, "Expected fatal failure."); +} + +// Tests that EXPECT_FATAL_FAILURE() succeeds when there is exactly +// one fatal failure and no non-fatal failure. +TEST(ExpectFatalFailureTest, SucceedsWhenThereIsOneFatalFailure) { + EXPECT_FATAL_FAILURE({ + FAIL() << "Expected fatal failure."; + }, "Expected fatal failure."); +} + +// Tests that EXPECT_FATAL_FAILURE() fails when there is no fatal +// failure. +TEST(ExpectFatalFailureTest, FailsWhenThereIsNoFatalFailure) { + printf("(expecting a failure)\n"); + EXPECT_FATAL_FAILURE({ + }, ""); +} + +// A helper for generating a fatal failure. +void FatalFailure() { + FAIL() << "Expected fatal failure."; +} + +// Tests that EXPECT_FATAL_FAILURE() fails when there are two +// fatal failures. +TEST(ExpectFatalFailureTest, FailsWhenThereAreTwoFatalFailures) { + printf("(expecting a failure)\n"); + EXPECT_FATAL_FAILURE({ + FatalFailure(); + FatalFailure(); + }, ""); +} + +// Tests that EXPECT_FATAL_FAILURE() fails when there is one non-fatal +// failure. +TEST(ExpectFatalFailureTest, FailsWhenThereIsOneNonfatalFailure) { + printf("(expecting a failure)\n"); + EXPECT_FATAL_FAILURE({ + ADD_FAILURE() << "Expected non-fatal failure."; + }, ""); +} + +// Tests that EXPECT_FATAL_FAILURE() fails when the statement being +// tested returns. +TEST(ExpectFatalFailureTest, FailsWhenStatementReturns) { + printf("(expecting a failure)\n"); + EXPECT_FATAL_FAILURE({ + return; + }, ""); +} + +#if GTEST_HAS_EXCEPTIONS + +// Tests that EXPECT_FATAL_FAILURE() fails when the statement being +// tested throws. +TEST(ExpectFatalFailureTest, FailsWhenStatementThrows) { + printf("(expecting a failure)\n"); + try { + EXPECT_FATAL_FAILURE({ + throw 0; + }, ""); + } catch(int) { // NOLINT + } +} + +#endif // GTEST_HAS_EXCEPTIONS + +// Two test environments for testing testing::AddGlobalTestEnvironment(). + +class FooEnvironment : public testing::Environment { + public: + virtual void SetUp() { + printf("%s", "FooEnvironment::SetUp() called.\n"); + } + + virtual void TearDown() { + printf("%s", "FooEnvironment::TearDown() called.\n"); + FAIL() << "Expected fatal failure."; + } +}; + +class BarEnvironment : public testing::Environment { + public: + virtual void SetUp() { + printf("%s", "BarEnvironment::SetUp() called.\n"); + } + + virtual void TearDown() { + printf("%s", "BarEnvironment::TearDown() called.\n"); + ADD_FAILURE() << "Expected non-fatal failure."; + } +}; + +// The main function. +// +// The idea is to use Google Test to run all the tests we have defined (some +// of them are intended to fail), and then compare the test results +// with the "golden" file. +int main(int argc, char **argv) { + // We just run the tests, knowing some of them are intended to fail. + // We will use a separate Python script to compare the output of + // this program with the golden file. + testing::InitGoogleTest(&argc, argv); + +#ifdef GTEST_HAS_DEATH_TEST + if (testing::internal::GTEST_FLAG(internal_run_death_test) != "") { + // Skip the usual output capturing if we're running as the child + // process of an threadsafe-style death test. + freopen("/dev/null", "w", stdout); + return RUN_ALL_TESTS(); + } +#endif // GTEST_HAS_DEATH_TEST + + // Registers two global test environments. + // The golden file verifies that they are set up in the order they + // are registered, and torn down in the reverse order. + testing::AddGlobalTestEnvironment(new FooEnvironment); + testing::AddGlobalTestEnvironment(new BarEnvironment); + + return RunAllTests(); +} diff --git a/test/gtest_output_test_golden_lin.txt b/test/gtest_output_test_golden_lin.txt new file mode 100644 index 00000000..bfcc9a9b --- /dev/null +++ b/test/gtest_output_test_golden_lin.txt @@ -0,0 +1,383 @@ +The non-test part of the code is expected to have 2 failures. + +gtest_output_test_.cc:#: Failure +Value of: false + Actual: false +Expected: true +gtest_output_test_.cc:#: Failure +Value of: 3 +Expected: 2 +[==========] Running 37 tests from 13 test cases. +[----------] Global test environment set-up. +FooEnvironment::SetUp() called. +BarEnvironment::SetUp() called. +[----------] 3 tests from FatalFailureTest +[ RUN ] FatalFailureTest.FatalFailureInSubroutine +(expecting a failure that x should be 1) +gtest_output_test_.cc:#: Failure +Value of: x + Actual: 2 +Expected: 1 +[ FAILED ] FatalFailureTest.FatalFailureInSubroutine +[ RUN ] FatalFailureTest.FatalFailureInNestedSubroutine +(expecting a failure that x should be 1) +gtest_output_test_.cc:#: Failure +Value of: x + Actual: 2 +Expected: 1 +[ FAILED ] FatalFailureTest.FatalFailureInNestedSubroutine +[ RUN ] FatalFailureTest.NonfatalFailureInSubroutine +(expecting a failure on false) +gtest_output_test_.cc:#: Failure +Value of: false + Actual: false +Expected: true +[ FAILED ] FatalFailureTest.NonfatalFailureInSubroutine +[----------] 1 test from LoggingTest +[ RUN ] LoggingTest.InterleavingLoggingAndAssertions +(expecting 2 failures on (3) >= (a[i])) +i == 0 +i == 1 +gtest_output_test_.cc:#: Failure +Expected: (3) >= (a[i]), actual: 3 vs 9 +i == 2 +i == 3 +gtest_output_test_.cc:#: Failure +Expected: (3) >= (a[i]), actual: 3 vs 6 +[ FAILED ] LoggingTest.InterleavingLoggingAndAssertions +[----------] 5 tests from SCOPED_TRACETest +[ RUN ] SCOPED_TRACETest.ObeysScopes +(expected to fail) +gtest_output_test_.cc:#: Failure +Failed +This failure is expected, and shouldn't have a trace. +gtest_output_test_.cc:#: Failure +Failed +This failure is expected, and should have a trace. +Google Test trace: +gtest_output_test_.cc:#: Expected trace +gtest_output_test_.cc:#: Failure +Failed +This failure is expected, and shouldn't have a trace. +[ FAILED ] SCOPED_TRACETest.ObeysScopes +[ RUN ] SCOPED_TRACETest.WorksInLoop +(expected to fail) +gtest_output_test_.cc:#: Failure +Value of: n + Actual: 1 +Expected: 2 +Google Test trace: +gtest_output_test_.cc:#: i = 1 +gtest_output_test_.cc:#: Failure +Value of: n + Actual: 2 +Expected: 1 +Google Test trace: +gtest_output_test_.cc:#: i = 2 +[ FAILED ] SCOPED_TRACETest.WorksInLoop +[ RUN ] SCOPED_TRACETest.WorksInSubroutine +(expected to fail) +gtest_output_test_.cc:#: Failure +Value of: n + Actual: 1 +Expected: 2 +Google Test trace: +gtest_output_test_.cc:#: n = 1 +gtest_output_test_.cc:#: Failure +Value of: n + Actual: 2 +Expected: 1 +Google Test trace: +gtest_output_test_.cc:#: n = 2 +[ FAILED ] SCOPED_TRACETest.WorksInSubroutine +[ RUN ] SCOPED_TRACETest.CanBeNested +(expected to fail) +gtest_output_test_.cc:#: Failure +Value of: n + Actual: 2 +Expected: 1 +Google Test trace: +gtest_output_test_.cc:#: n = 2 +gtest_output_test_.cc:#: +[ FAILED ] SCOPED_TRACETest.CanBeNested +[ RUN ] SCOPED_TRACETest.CanBeRepeated +(expected to fail) +gtest_output_test_.cc:#: Failure +Failed +This failure is expected, and should contain trace point A. +Google Test trace: +gtest_output_test_.cc:#: A +gtest_output_test_.cc:#: Failure +Failed +This failure is expected, and should contain trace point A and B. +Google Test trace: +gtest_output_test_.cc:#: B +gtest_output_test_.cc:#: A +gtest_output_test_.cc:#: Failure +Failed +This failure is expected, and should contain trace point A, B, and C. +Google Test trace: +gtest_output_test_.cc:#: C +gtest_output_test_.cc:#: B +gtest_output_test_.cc:#: A +gtest_output_test_.cc:#: Failure +Failed +This failure is expected, and should contain trace point A, B, and D. +Google Test trace: +gtest_output_test_.cc:#: D +gtest_output_test_.cc:#: B +gtest_output_test_.cc:#: A +[ FAILED ] SCOPED_TRACETest.CanBeRepeated +[----------] 1 test from NonFatalFailureInFixtureConstructorTest +[ RUN ] NonFatalFailureInFixtureConstructorTest.FailureInConstructor +(expecting 5 failures) +gtest_output_test_.cc:#: Failure +Failed +Expected failure #1, in the test fixture c'tor. +gtest_output_test_.cc:#: Failure +Failed +Expected failure #2, in SetUp(). +gtest_output_test_.cc:#: Failure +Failed +Expected failure #3, in the test body. +gtest_output_test_.cc:#: Failure +Failed +Expected failure #4, in TearDown. +gtest_output_test_.cc:#: Failure +Failed +Expected failure #5, in the test fixture d'tor. +[ FAILED ] NonFatalFailureInFixtureConstructorTest.FailureInConstructor +[----------] 1 test from FatalFailureInFixtureConstructorTest +[ RUN ] FatalFailureInFixtureConstructorTest.FailureInConstructor +(expecting 2 failures) +gtest_output_test_.cc:#: Failure +Failed +Expected failure #1, in the test fixture c'tor. +gtest_output_test_.cc:#: Failure +Failed +Expected failure #2, in the test fixture d'tor. +[ FAILED ] FatalFailureInFixtureConstructorTest.FailureInConstructor +[----------] 1 test from NonFatalFailureInSetUpTest +[ RUN ] NonFatalFailureInSetUpTest.FailureInSetUp +(expecting 4 failures) +gtest_output_test_.cc:#: Failure +Failed +Expected failure #1, in SetUp(). +gtest_output_test_.cc:#: Failure +Failed +Expected failure #2, in the test function. +gtest_output_test_.cc:#: Failure +Failed +Expected failure #3, in TearDown(). +gtest_output_test_.cc:#: Failure +Failed +Expected failure #4, in the test fixture d'tor. +[ FAILED ] NonFatalFailureInSetUpTest.FailureInSetUp +[----------] 1 test from FatalFailureInSetUpTest +[ RUN ] FatalFailureInSetUpTest.FailureInSetUp +(expecting 3 failures) +gtest_output_test_.cc:#: Failure +Failed +Expected failure #1, in SetUp(). +gtest_output_test_.cc:#: Failure +Failed +Expected failure #2, in TearDown(). +gtest_output_test_.cc:#: Failure +Failed +Expected failure #3, in the test fixture d'tor. +[ FAILED ] FatalFailureInSetUpTest.FailureInSetUp +[----------] 4 tests from MixedUpTestCaseTest +[ RUN ] MixedUpTestCaseTest.FirstTestFromNamespaceFoo +[ OK ] MixedUpTestCaseTest.FirstTestFromNamespaceFoo +[ RUN ] MixedUpTestCaseTest.SecondTestFromNamespaceFoo +[ OK ] MixedUpTestCaseTest.SecondTestFromNamespaceFoo +[ RUN ] MixedUpTestCaseTest.ThisShouldFail +gtest.cc:#: Failure +Failed +All tests in the same test case must use the same test fixture +class. However, in test case MixedUpTestCaseTest, +you defined test FirstTestFromNamespaceFoo and test ThisShouldFail +using two different test fixture classes. This can happen if +the two classes are from different namespaces or translation +units and have the same name. You should probably rename one +of the classes to put the tests into different test cases. +[ FAILED ] MixedUpTestCaseTest.ThisShouldFail +[ RUN ] MixedUpTestCaseTest.ThisShouldFailToo +gtest.cc:#: Failure +Failed +All tests in the same test case must use the same test fixture +class. However, in test case MixedUpTestCaseTest, +you defined test FirstTestFromNamespaceFoo and test ThisShouldFailToo +using two different test fixture classes. This can happen if +the two classes are from different namespaces or translation +units and have the same name. You should probably rename one +of the classes to put the tests into different test cases. +[ FAILED ] MixedUpTestCaseTest.ThisShouldFailToo +[----------] 2 tests from MixedUpTestCaseWithSameTestNameTest +[ RUN ] MixedUpTestCaseWithSameTestNameTest.TheSecondTestWithThisNameShouldFail +[ OK ] MixedUpTestCaseWithSameTestNameTest.TheSecondTestWithThisNameShouldFail +[ RUN ] MixedUpTestCaseWithSameTestNameTest.TheSecondTestWithThisNameShouldFail +gtest.cc:#: Failure +Failed +All tests in the same test case must use the same test fixture +class. However, in test case MixedUpTestCaseWithSameTestNameTest, +you defined test TheSecondTestWithThisNameShouldFail and test TheSecondTestWithThisNameShouldFail +using two different test fixture classes. This can happen if +the two classes are from different namespaces or translation +units and have the same name. You should probably rename one +of the classes to put the tests into different test cases. +[ FAILED ] MixedUpTestCaseWithSameTestNameTest.TheSecondTestWithThisNameShouldFail +[----------] 2 tests from TEST_F_before_TEST_in_same_test_case +[ RUN ] TEST_F_before_TEST_in_same_test_case.DefinedUsingTEST_F +[ OK ] TEST_F_before_TEST_in_same_test_case.DefinedUsingTEST_F +[ RUN ] TEST_F_before_TEST_in_same_test_case.DefinedUsingTESTAndShouldFail +gtest.cc:#: Failure +Failed +All tests in the same test case must use the same test fixture +class, so mixing TEST_F and TEST in the same test case is +illegal. In test case TEST_F_before_TEST_in_same_test_case, +test DefinedUsingTEST_F is defined using TEST_F but +test DefinedUsingTESTAndShouldFail is defined using TEST. You probably +want to change the TEST to TEST_F or move it to another test +case. +[ FAILED ] TEST_F_before_TEST_in_same_test_case.DefinedUsingTESTAndShouldFail +[----------] 2 tests from TEST_before_TEST_F_in_same_test_case +[ RUN ] TEST_before_TEST_F_in_same_test_case.DefinedUsingTEST +[ OK ] TEST_before_TEST_F_in_same_test_case.DefinedUsingTEST +[ RUN ] TEST_before_TEST_F_in_same_test_case.DefinedUsingTEST_FAndShouldFail +gtest.cc:#: Failure +Failed +All tests in the same test case must use the same test fixture +class, so mixing TEST_F and TEST in the same test case is +illegal. In test case TEST_before_TEST_F_in_same_test_case, +test DefinedUsingTEST_FAndShouldFail is defined using TEST_F but +test DefinedUsingTEST is defined using TEST. You probably +want to change the TEST to TEST_F or move it to another test +case. +[ FAILED ] TEST_before_TEST_F_in_same_test_case.DefinedUsingTEST_FAndShouldFail +[----------] 7 tests from ExpectNonfatalFailureTest +[ RUN ] ExpectNonfatalFailureTest.CanReferenceGlobalVariables +[ OK ] ExpectNonfatalFailureTest.CanReferenceGlobalVariables +[ RUN ] ExpectNonfatalFailureTest.CanReferenceLocalVariables +[ OK ] ExpectNonfatalFailureTest.CanReferenceLocalVariables +[ RUN ] ExpectNonfatalFailureTest.SucceedsWhenThereIsOneNonfatalFailure +[ OK ] ExpectNonfatalFailureTest.SucceedsWhenThereIsOneNonfatalFailure +[ RUN ] ExpectNonfatalFailureTest.FailsWhenThereIsNoNonfatalFailure +(expecting a failure) +gtest.cc:#: Failure +Expected: 1 non-fatal failure + Actual: 0 failures +[ FAILED ] ExpectNonfatalFailureTest.FailsWhenThereIsNoNonfatalFailure +[ RUN ] ExpectNonfatalFailureTest.FailsWhenThereAreTwoNonfatalFailures +(expecting a failure) +gtest.cc:#: Failure +Expected: 1 non-fatal failure + Actual: 2 failures +gtest_output_test_.cc:#: Non-fatal failure: +Failed +Expected non-fatal failure 1. + +gtest_output_test_.cc:#: Non-fatal failure: +Failed +Expected non-fatal failure 2. + +[ FAILED ] ExpectNonfatalFailureTest.FailsWhenThereAreTwoNonfatalFailures +[ RUN ] ExpectNonfatalFailureTest.FailsWhenThereIsOneFatalFailure +(expecting a failure) +gtest.cc:#: Failure +Expected: 1 non-fatal failure + Actual: +gtest_output_test_.cc:#: Fatal failure: +Failed +Expected fatal failure. + +[ FAILED ] ExpectNonfatalFailureTest.FailsWhenThereIsOneFatalFailure +[ RUN ] ExpectNonfatalFailureTest.FailsWhenStatementReturns +(expecting a failure) +gtest.cc:#: Failure +Expected: 1 non-fatal failure + Actual: 0 failures +[ FAILED ] ExpectNonfatalFailureTest.FailsWhenStatementReturns +[----------] 7 tests from ExpectFatalFailureTest +[ RUN ] ExpectFatalFailureTest.CanReferenceGlobalVariables +[ OK ] ExpectFatalFailureTest.CanReferenceGlobalVariables +[ RUN ] ExpectFatalFailureTest.CanReferenceLocalStaticVariables +[ OK ] ExpectFatalFailureTest.CanReferenceLocalStaticVariables +[ RUN ] ExpectFatalFailureTest.SucceedsWhenThereIsOneFatalFailure +[ OK ] ExpectFatalFailureTest.SucceedsWhenThereIsOneFatalFailure +[ RUN ] ExpectFatalFailureTest.FailsWhenThereIsNoFatalFailure +(expecting a failure) +gtest.cc:#: Failure +Expected: 1 fatal failure + Actual: 0 failures +[ FAILED ] ExpectFatalFailureTest.FailsWhenThereIsNoFatalFailure +[ RUN ] ExpectFatalFailureTest.FailsWhenThereAreTwoFatalFailures +(expecting a failure) +gtest.cc:#: Failure +Expected: 1 fatal failure + Actual: 2 failures +gtest_output_test_.cc:#: Fatal failure: +Failed +Expected fatal failure. + +gtest_output_test_.cc:#: Fatal failure: +Failed +Expected fatal failure. + +[ FAILED ] ExpectFatalFailureTest.FailsWhenThereAreTwoFatalFailures +[ RUN ] ExpectFatalFailureTest.FailsWhenThereIsOneNonfatalFailure +(expecting a failure) +gtest.cc:#: Failure +Expected: 1 fatal failure + Actual: +gtest_output_test_.cc:#: Non-fatal failure: +Failed +Expected non-fatal failure. + +[ FAILED ] ExpectFatalFailureTest.FailsWhenThereIsOneNonfatalFailure +[ RUN ] ExpectFatalFailureTest.FailsWhenStatementReturns +(expecting a failure) +gtest.cc:#: Failure +Expected: 1 fatal failure + Actual: 0 failures +[ FAILED ] ExpectFatalFailureTest.FailsWhenStatementReturns +[----------] Global test environment tear-down +BarEnvironment::TearDown() called. +gtest_output_test_.cc:#: Failure +Failed +Expected non-fatal failure. +FooEnvironment::TearDown() called. +gtest_output_test_.cc:#: Failure +Failed +Expected fatal failure. +[==========] 37 tests from 13 test cases ran. +[ PASSED ] 11 tests. +[ FAILED ] 26 tests, listed below: +[ FAILED ] FatalFailureTest.FatalFailureInSubroutine +[ FAILED ] FatalFailureTest.FatalFailureInNestedSubroutine +[ FAILED ] FatalFailureTest.NonfatalFailureInSubroutine +[ FAILED ] LoggingTest.InterleavingLoggingAndAssertions +[ FAILED ] SCOPED_TRACETest.ObeysScopes +[ FAILED ] SCOPED_TRACETest.WorksInLoop +[ FAILED ] SCOPED_TRACETest.WorksInSubroutine +[ FAILED ] SCOPED_TRACETest.CanBeNested +[ FAILED ] SCOPED_TRACETest.CanBeRepeated +[ FAILED ] NonFatalFailureInFixtureConstructorTest.FailureInConstructor +[ FAILED ] FatalFailureInFixtureConstructorTest.FailureInConstructor +[ FAILED ] NonFatalFailureInSetUpTest.FailureInSetUp +[ FAILED ] FatalFailureInSetUpTest.FailureInSetUp +[ FAILED ] MixedUpTestCaseTest.ThisShouldFail +[ FAILED ] MixedUpTestCaseTest.ThisShouldFailToo +[ FAILED ] MixedUpTestCaseWithSameTestNameTest.TheSecondTestWithThisNameShouldFail +[ FAILED ] TEST_F_before_TEST_in_same_test_case.DefinedUsingTESTAndShouldFail +[ FAILED ] TEST_before_TEST_F_in_same_test_case.DefinedUsingTEST_FAndShouldFail +[ FAILED ] ExpectNonfatalFailureTest.FailsWhenThereIsNoNonfatalFailure +[ FAILED ] ExpectNonfatalFailureTest.FailsWhenThereAreTwoNonfatalFailures +[ FAILED ] ExpectNonfatalFailureTest.FailsWhenThereIsOneFatalFailure +[ FAILED ] ExpectNonfatalFailureTest.FailsWhenStatementReturns +[ FAILED ] ExpectFatalFailureTest.FailsWhenThereIsNoFatalFailure +[ FAILED ] ExpectFatalFailureTest.FailsWhenThereAreTwoFatalFailures +[ FAILED ] ExpectFatalFailureTest.FailsWhenThereIsOneNonfatalFailure +[ FAILED ] ExpectFatalFailureTest.FailsWhenStatementReturns + +26 FAILED TESTS diff --git a/test/gtest_output_test_golden_win.txt b/test/gtest_output_test_golden_win.txt new file mode 100644 index 00000000..e72577d8 --- /dev/null +++ b/test/gtest_output_test_golden_win.txt @@ -0,0 +1,415 @@ +The non-test part of the code is expected to have 2 failures. + +gtest_output_test_.cc:#: Failure +Value of: false + Actual: false +Expected: true +gtest_output_test_.cc:#: Failure +Value of: 3 +Expected: 2 +[==========] Running 40 tests from 16 test cases. +[----------] Global test environment set-up. +FooEnvironment::SetUp() called. +BarEnvironment::SetUp() called. +[----------] 3 tests from FatalFailureTest +[ RUN ] FatalFailureTest.FatalFailureInSubroutine +(expecting a failure that x should be 1) +gtest_output_test_.cc:#: Failure +Value of: x + Actual: 2 +Expected: 1 +[ FAILED ] FatalFailureTest.FatalFailureInSubroutine +[ RUN ] FatalFailureTest.FatalFailureInNestedSubroutine +(expecting a failure that x should be 1) +gtest_output_test_.cc:#: Failure +Value of: x + Actual: 2 +Expected: 1 +[ FAILED ] FatalFailureTest.FatalFailureInNestedSubroutine +[ RUN ] FatalFailureTest.NonfatalFailureInSubroutine +(expecting a failure on false) +gtest_output_test_.cc:#: Failure +Value of: false + Actual: false +Expected: true +[ FAILED ] FatalFailureTest.NonfatalFailureInSubroutine +[----------] 1 test from LoggingTest +[ RUN ] LoggingTest.InterleavingLoggingAndAssertions +(expecting 2 failures on (3) >= (a[i])) +i == 0 +i == 1 +gtest_output_test_.cc:#: Failure +Expected: (3) >= (a[i]), actual: 3 vs 9 +i == 2 +i == 3 +gtest_output_test_.cc:#: Failure +Expected: (3) >= (a[i]), actual: 3 vs 6 +[ FAILED ] LoggingTest.InterleavingLoggingAndAssertions +[----------] 5 tests from SCOPED_TRACETest +[ RUN ] SCOPED_TRACETest.ObeysScopes +(expected to fail) +gtest_output_test_.cc:#: Failure +Failed +This failure is expected, and shouldn't have a trace. +gtest_output_test_.cc:#: Failure +Failed +This failure is expected, and should have a trace. +gUnit trace: +gtest_output_test_.cc:#: Expected trace +gtest_output_test_.cc:#: Failure +Failed +This failure is expected, and shouldn't have a trace. +[ FAILED ] SCOPED_TRACETest.ObeysScopes +[ RUN ] SCOPED_TRACETest.WorksInLoop +(expected to fail) +gtest_output_test_.cc:#: Failure +Value of: n + Actual: 1 +Expected: 2 +gUnit trace: +gtest_output_test_.cc:#: i = 1 +gtest_output_test_.cc:#: Failure +Value of: n + Actual: 2 +Expected: 1 +gUnit trace: +gtest_output_test_.cc:#: i = 2 +[ FAILED ] SCOPED_TRACETest.WorksInLoop +[ RUN ] SCOPED_TRACETest.WorksInSubroutine +(expected to fail) +gtest_output_test_.cc:#: Failure +Value of: n + Actual: 1 +Expected: 2 +gUnit trace: +gtest_output_test_.cc:#: n = 1 +gtest_output_test_.cc:#: Failure +Value of: n + Actual: 2 +Expected: 1 +gUnit trace: +gtest_output_test_.cc:#: n = 2 +[ FAILED ] SCOPED_TRACETest.WorksInSubroutine +[ RUN ] SCOPED_TRACETest.CanBeNested +(expected to fail) +gtest_output_test_.cc:#: Failure +Value of: n + Actual: 2 +Expected: 1 +gUnit trace: +gtest_output_test_.cc:#: n = 2 +gtest_output_test_.cc:#: +[ FAILED ] SCOPED_TRACETest.CanBeNested +[ RUN ] SCOPED_TRACETest.CanBeRepeated +(expected to fail) +gtest_output_test_.cc:#: Failure +Failed +This failure is expected, and should contain trace point A. +gUnit trace: +gtest_output_test_.cc:#: A +gtest_output_test_.cc:#: Failure +Failed +This failure is expected, and should contain trace point A and B. +gUnit trace: +gtest_output_test_.cc:#: B +gtest_output_test_.cc:#: A +gtest_output_test_.cc:#: Failure +Failed +This failure is expected, and should contain trace point A, B, and C. +gUnit trace: +gtest_output_test_.cc:#: C +gtest_output_test_.cc:#: B +gtest_output_test_.cc:#: A +gtest_output_test_.cc:#: Failure +Failed +This failure is expected, and should contain trace point A, B, and D. +gUnit trace: +gtest_output_test_.cc:#: D +gtest_output_test_.cc:#: B +gtest_output_test_.cc:#: A +[ FAILED ] SCOPED_TRACETest.CanBeRepeated +[----------] 1 test from NonFatalFailureInFixtureConstructorTest +[ RUN ] NonFatalFailureInFixtureConstructorTest.FailureInConstructor +(expecting 5 failures) +gtest_output_test_.cc:#: Failure +Failed +Expected failure #1, in the test fixture c'tor. +gtest_output_test_.cc:#: Failure +Failed +Expected failure #2, in SetUp(). +gtest_output_test_.cc:#: Failure +Failed +Expected failure #3, in the test body. +gtest_output_test_.cc:#: Failure +Failed +Expected failure #4, in TearDown. +gtest_output_test_.cc:#: Failure +Failed +Expected failure #5, in the test fixture d'tor. +[ FAILED ] NonFatalFailureInFixtureConstructorTest.FailureInConstructor +[----------] 1 test from FatalFailureInFixtureConstructorTest +[ RUN ] FatalFailureInFixtureConstructorTest.FailureInConstructor +(expecting 2 failures) +gtest_output_test_.cc:#: Failure +Failed +Expected failure #1, in the test fixture c'tor. +gtest_output_test_.cc:#: Failure +Failed +Expected failure #2, in the test fixture d'tor. +[ FAILED ] FatalFailureInFixtureConstructorTest.FailureInConstructor +[----------] 1 test from NonFatalFailureInSetUpTest +[ RUN ] NonFatalFailureInSetUpTest.FailureInSetUp +(expecting 4 failures) +gtest_output_test_.cc:#: Failure +Failed +Expected failure #1, in SetUp(). +gtest_output_test_.cc:#: Failure +Failed +Expected failure #2, in the test function. +gtest_output_test_.cc:#: Failure +Failed +Expected failure #3, in TearDown(). +gtest_output_test_.cc:#: Failure +Failed +Expected failure #4, in the test fixture d'tor. +[ FAILED ] NonFatalFailureInSetUpTest.FailureInSetUp +[----------] 1 test from FatalFailureInSetUpTest +[ RUN ] FatalFailureInSetUpTest.FailureInSetUp +(expecting 3 failures) +gtest_output_test_.cc:#: Failure +Failed +Expected failure #1, in SetUp(). +gtest_output_test_.cc:#: Failure +Failed +Expected failure #2, in TearDown(). +gtest_output_test_.cc:#: Failure +Failed +Expected failure #3, in the test fixture d'tor. +[ FAILED ] FatalFailureInSetUpTest.FailureInSetUp +[----------] 1 test from ExceptionInFixtureCtorTest +[ RUN ] ExceptionInFixtureCtorTest.ExceptionInFixtureCtor +(expecting a failure on thrown exception in the test fixture's constructor) +unknown file: Failure +Exception thrown with code 0xc0000005 in the test fixture's constructor. +[----------] 1 test from ExceptionInSetUpTest +[ RUN ] ExceptionInSetUpTest.ExceptionInSetUp +(expecting 3 failures) +unknown file: Failure +Exception thrown with code 0xc0000005 in SetUp(). +gtest_output_test_.cc:#: Failure +Failed +Expected failure #2, in TearDown(). +gtest_output_test_.cc:#: Failure +Failed +Expected failure #3, in the test fixture d'tor. +[ FAILED ] ExceptionInSetUpTest.ExceptionInSetUp +[----------] 1 test from ExceptionInTestFunctionTest +[ RUN ] ExceptionInTestFunctionTest.SEH +(expecting 3 failures) +unknown file: Failure +Exception thrown with code 0xc0000005 in the test body. +gtest_output_test_.cc:#: Failure +Failed +Expected failure #2, in TearDown(). +gtest_output_test_.cc:#: Failure +Failed +Expected failure #3, in the test fixture d'tor. +[ FAILED ] ExceptionInTestFunctionTest.SEH +[----------] 4 tests from MixedUpTestCaseTest +[ RUN ] MixedUpTestCaseTest.FirstTestFromNamespaceFoo +[ OK ] MixedUpTestCaseTest.FirstTestFromNamespaceFoo +[ RUN ] MixedUpTestCaseTest.SecondTestFromNamespaceFoo +[ OK ] MixedUpTestCaseTest.SecondTestFromNamespaceFoo +[ RUN ] MixedUpTestCaseTest.ThisShouldFail +gtest.cc:#: Failure +Failed +All tests in the same test case must use the same test fixture +class. However, in test case MixedUpTestCaseTest, +you defined test FirstTestFromNamespaceFoo and test ThisShouldFail +using two different test fixture classes. This can happen if +the two classes are from different namespaces or translation +units and have the same name. You should probably rename one +of the classes to put the tests into different test cases. +[ FAILED ] MixedUpTestCaseTest.ThisShouldFail +[ RUN ] MixedUpTestCaseTest.ThisShouldFailToo +gtest.cc:#: Failure +Failed +All tests in the same test case must use the same test fixture +class. However, in test case MixedUpTestCaseTest, +you defined test FirstTestFromNamespaceFoo and test ThisShouldFailToo +using two different test fixture classes. This can happen if +the two classes are from different namespaces or translation +units and have the same name. You should probably rename one +of the classes to put the tests into different test cases. +[ FAILED ] MixedUpTestCaseTest.ThisShouldFailToo +[----------] 2 tests from MixedUpTestCaseWithSameTestNameTest +[ RUN ] MixedUpTestCaseWithSameTestNameTest.TheSecondTestWithThisNameShouldFail +[ OK ] MixedUpTestCaseWithSameTestNameTest.TheSecondTestWithThisNameShouldFail +[ RUN ] MixedUpTestCaseWithSameTestNameTest.TheSecondTestWithThisNameShouldFail +gtest.cc:#: Failure +Failed +All tests in the same test case must use the same test fixture +class. However, in test case MixedUpTestCaseWithSameTestNameTest, +you defined test TheSecondTestWithThisNameShouldFail and test TheSecondTestWithThisNameShouldFail +using two different test fixture classes. This can happen if +the two classes are from different namespaces or translation +units and have the same name. You should probably rename one +of the classes to put the tests into different test cases. +[ FAILED ] MixedUpTestCaseWithSameTestNameTest.TheSecondTestWithThisNameShouldFail +[----------] 2 tests from TEST_F_before_TEST_in_same_test_case +[ RUN ] TEST_F_before_TEST_in_same_test_case.DefinedUsingTEST_F +[ OK ] TEST_F_before_TEST_in_same_test_case.DefinedUsingTEST_F +[ RUN ] TEST_F_before_TEST_in_same_test_case.DefinedUsingTESTAndShouldFail +gtest.cc:#: Failure +Failed +All tests in the same test case must use the same test fixture +class, so mixing TEST_F and TEST in the same test case is +illegal. In test case TEST_F_before_TEST_in_same_test_case, +test DefinedUsingTEST_F is defined using TEST_F but +test DefinedUsingTESTAndShouldFail is defined using TEST. You probably +want to change the TEST to TEST_F or move it to another test +case. +[ FAILED ] TEST_F_before_TEST_in_same_test_case.DefinedUsingTESTAndShouldFail +[----------] 2 tests from TEST_before_TEST_F_in_same_test_case +[ RUN ] TEST_before_TEST_F_in_same_test_case.DefinedUsingTEST +[ OK ] TEST_before_TEST_F_in_same_test_case.DefinedUsingTEST +[ RUN ] TEST_before_TEST_F_in_same_test_case.DefinedUsingTEST_FAndShouldFail +gtest.cc:#: Failure +Failed +All tests in the same test case must use the same test fixture +class, so mixing TEST_F and TEST in the same test case is +illegal. In test case TEST_before_TEST_F_in_same_test_case, +test DefinedUsingTEST_FAndShouldFail is defined using TEST_F but +test DefinedUsingTEST is defined using TEST. You probably +want to change the TEST to TEST_F or move it to another test +case. +[ FAILED ] TEST_before_TEST_F_in_same_test_case.DefinedUsingTEST_FAndShouldFail +[----------] 7 tests from ExpectNonfatalFailureTest +[ RUN ] ExpectNonfatalFailureTest.CanReferenceGlobalVariables +[ OK ] ExpectNonfatalFailureTest.CanReferenceGlobalVariables +[ RUN ] ExpectNonfatalFailureTest.CanReferenceLocalVariables +[ OK ] ExpectNonfatalFailureTest.CanReferenceLocalVariables +[ RUN ] ExpectNonfatalFailureTest.SucceedsWhenThereIsOneNonfatalFailure +[ OK ] ExpectNonfatalFailureTest.SucceedsWhenThereIsOneNonfatalFailure +[ RUN ] ExpectNonfatalFailureTest.FailsWhenThereIsNoNonfatalFailure +(expecting a failure) +gtest.cc:#: Failure +Expected: 1 non-fatal failure + Actual: 0 failures +[ FAILED ] ExpectNonfatalFailureTest.FailsWhenThereIsNoNonfatalFailure +[ RUN ] ExpectNonfatalFailureTest.FailsWhenThereAreTwoNonfatalFailures +(expecting a failure) +gtest.cc:#: Failure +Expected: 1 non-fatal failure + Actual: 2 failures +gtest_output_test_.cc:#: Non-fatal failure: +Failed +Expected non-fatal failure 1. + +gtest_output_test_.cc:#: Non-fatal failure: +Failed +Expected non-fatal failure 2. + +[ FAILED ] ExpectNonfatalFailureTest.FailsWhenThereAreTwoNonfatalFailures +[ RUN ] ExpectNonfatalFailureTest.FailsWhenThereIsOneFatalFailure +(expecting a failure) +gtest.cc:#: Failure +Expected: 1 non-fatal failure + Actual: +gtest_output_test_.cc:#: Fatal failure: +Failed +Expected fatal failure. + +[ FAILED ] ExpectNonfatalFailureTest.FailsWhenThereIsOneFatalFailure +[ RUN ] ExpectNonfatalFailureTest.FailsWhenStatementReturns +(expecting a failure) +gtest.cc:#: Failure +Expected: 1 non-fatal failure + Actual: 0 failures +[ FAILED ] ExpectNonfatalFailureTest.FailsWhenStatementReturns +[----------] 7 tests from ExpectFatalFailureTest +[ RUN ] ExpectFatalFailureTest.CanReferenceGlobalVariables +[ OK ] ExpectFatalFailureTest.CanReferenceGlobalVariables +[ RUN ] ExpectFatalFailureTest.CanReferenceLocalStaticVariables +[ OK ] ExpectFatalFailureTest.CanReferenceLocalStaticVariables +[ RUN ] ExpectFatalFailureTest.SucceedsWhenThereIsOneFatalFailure +[ OK ] ExpectFatalFailureTest.SucceedsWhenThereIsOneFatalFailure +[ RUN ] ExpectFatalFailureTest.FailsWhenThereIsNoFatalFailure +(expecting a failure) +gtest.cc:#: Failure +Expected: 1 fatal failure + Actual: 0 failures +[ FAILED ] ExpectFatalFailureTest.FailsWhenThereIsNoFatalFailure +[ RUN ] ExpectFatalFailureTest.FailsWhenThereAreTwoFatalFailures +(expecting a failure) +gtest.cc:#: Failure +Expected: 1 fatal failure + Actual: 2 failures +gtest_output_test_.cc:#: Fatal failure: +Failed +Expected fatal failure. + +gtest_output_test_.cc:#: Fatal failure: +Failed +Expected fatal failure. + +[ FAILED ] ExpectFatalFailureTest.FailsWhenThereAreTwoFatalFailures +[ RUN ] ExpectFatalFailureTest.FailsWhenThereIsOneNonfatalFailure +(expecting a failure) +gtest.cc:#: Failure +Expected: 1 fatal failure + Actual: +gtest_output_test_.cc:#: Non-fatal failure: +Failed +Expected non-fatal failure. + +[ FAILED ] ExpectFatalFailureTest.FailsWhenThereIsOneNonfatalFailure +[ RUN ] ExpectFatalFailureTest.FailsWhenStatementReturns +(expecting a failure) +gtest.cc:#: Failure +Expected: 1 fatal failure + Actual: 0 failures +[ FAILED ] ExpectFatalFailureTest.FailsWhenStatementReturns +[----------] Global test environment tear-down +BarEnvironment::TearDown() called. +gtest_output_test_.cc:#: Failure +Failed +Expected non-fatal failure. +FooEnvironment::TearDown() called. +gtest_output_test_.cc:#: Failure +Failed +Expected fatal failure. +[==========] 40 tests from 16 test cases ran. +[ PASSED ] 11 tests. +[ FAILED ] 29 tests, listed below: +[ FAILED ] FatalFailureTest.FatalFailureInSubroutine +[ FAILED ] FatalFailureTest.FatalFailureInNestedSubroutine +[ FAILED ] FatalFailureTest.NonfatalFailureInSubroutine +[ FAILED ] LoggingTest.InterleavingLoggingAndAssertions +[ FAILED ] SCOPED_TRACETest.ObeysScopes +[ FAILED ] SCOPED_TRACETest.WorksInLoop +[ FAILED ] SCOPED_TRACETest.WorksInSubroutine +[ FAILED ] SCOPED_TRACETest.CanBeNested +[ FAILED ] SCOPED_TRACETest.CanBeRepeated +[ FAILED ] NonFatalFailureInFixtureConstructorTest.FailureInConstructor +[ FAILED ] FatalFailureInFixtureConstructorTest.FailureInConstructor +[ FAILED ] NonFatalFailureInSetUpTest.FailureInSetUp +[ FAILED ] FatalFailureInSetUpTest.FailureInSetUp +[ FAILED ] ExceptionInFixtureCtorTest.ExceptionInFixtureCtor +[ FAILED ] ExceptionInSetUpTest.ExceptionInSetUp +[ FAILED ] ExceptionInTestFunctionTest.SEH +[ FAILED ] MixedUpTestCaseTest.ThisShouldFail +[ FAILED ] MixedUpTestCaseTest.ThisShouldFailToo +[ FAILED ] MixedUpTestCaseWithSameTestNameTest.TheSecondTestWithThisNameShouldFail +[ FAILED ] TEST_F_before_TEST_in_same_test_case.DefinedUsingTESTAndShouldFail +[ FAILED ] TEST_before_TEST_F_in_same_test_case.DefinedUsingTEST_FAndShouldFail +[ FAILED ] ExpectNonfatalFailureTest.FailsWhenThereIsNoNonfatalFailure +[ FAILED ] ExpectNonfatalFailureTest.FailsWhenThereAreTwoNonfatalFailures +[ FAILED ] ExpectNonfatalFailureTest.FailsWhenThereIsOneFatalFailure +[ FAILED ] ExpectNonfatalFailureTest.FailsWhenStatementReturns +[ FAILED ] ExpectFatalFailureTest.FailsWhenThereIsNoFatalFailure +[ FAILED ] ExpectFatalFailureTest.FailsWhenThereAreTwoFatalFailures +[ FAILED ] ExpectFatalFailureTest.FailsWhenThereIsOneNonfatalFailure +[ FAILED ] ExpectFatalFailureTest.FailsWhenStatementReturns + +29 FAILED TESTS diff --git a/test/gtest_pred_impl_unittest.cc b/test/gtest_pred_impl_unittest.cc new file mode 100644 index 00000000..3dea9904 --- /dev/null +++ b/test/gtest_pred_impl_unittest.cc @@ -0,0 +1,2432 @@ +// Copyright 2006, 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. + +// This file is AUTOMATICALLY GENERATED on 06/11/2008 by command +// 'gen_gtest_pred_impl.py 5'. DO NOT EDIT BY HAND! + +// Regression test for gtest_pred_impl.h +// +// This file is generated by a script and quite long. If you intend to +// learn how Google Test works by reading its unit tests, read +// gtest_unittest.cc instead. +// +// This is intended as a regression test for the Google Test predicate +// assertions. We compile it as part of the gtest_unittest target +// only to keep the implementation tidy and compact, as it is quite +// involved to set up the stage for testing Google Test using Google +// Test itself. +// +// Currently, gtest_unittest takes ~11 seconds to run in the testing +// daemon. In the future, if it grows too large and needs much more +// time to finish, we should consider separating this file into a +// stand-alone regression test. + +#include + +#include +#include + +// A user-defined data type. +struct Bool { + explicit Bool(int val) : value(val != 0) {} + + bool operator>(int n) const { return value > Bool(n).value; } + + Bool operator+(const Bool& rhs) const { return Bool(value + rhs.value); } + + bool operator==(const Bool& rhs) const { return value == rhs.value; } + + bool value; +}; + +// Enables Bool to be used in assertions. +std::ostream& operator<<(std::ostream& os, const Bool& x) { + return os << (x.value ? "true" : "false"); +} + +// Sample functions/functors for testing unary predicate assertions. + +// A unary predicate function. +template +bool PredFunction1(T1 v1) { + return v1 > 0; +} + +// The following two functions are needed to circumvent a bug in +// gcc 2.95.3, which sometimes has problem with the above template +// function. +bool PredFunction1Int(int v1) { + return v1 > 0; +} +bool PredFunction1Bool(Bool v1) { + return v1 > 0; +} + +// A unary predicate functor. +struct PredFunctor1 { + template + bool operator()(const T1& v1) { + return v1 > 0; + } +}; + +// A unary predicate-formatter function. +template +testing::AssertionResult PredFormatFunction1(const char* e1, + const T1& v1) { + if (PredFunction1(v1)) + return testing::AssertionSuccess(); + + testing::Message msg; + msg << e1 + << " is expected to be positive, but evaluates to " + << v1 << "."; + return testing::AssertionFailure(msg); +} + +// A unary predicate-formatter functor. +struct PredFormatFunctor1 { + template + testing::AssertionResult operator()(const char* e1, + const T1& v1) const { + return PredFormatFunction1(e1, v1); + } +}; + +// Tests for {EXPECT|ASSERT}_PRED_FORMAT1. + +class Predicate1Test : public testing::Test { + protected: + virtual void SetUp() { + expected_to_finish_ = true; + finished_ = false; + n1_ = 0; + } + + virtual void TearDown() { + // Verifies that each of the predicate's arguments was evaluated + // exactly once. + EXPECT_EQ(1, n1_) << + "The predicate assertion didn't evaluate argument 2 " + "exactly once."; + + // Verifies that the control flow in the test function is expected. + if (expected_to_finish_ && !finished_) { + FAIL() << "The predicate assertion unexpactedly aborted the test."; + } else if (!expected_to_finish_ && finished_) { + FAIL() << "The failed predicate assertion didn't abort the test " + "as expected."; + } + } + + // true iff the test function is expected to run to finish. + static bool expected_to_finish_; + + // true iff the test function did run to finish. + static bool finished_; + + static int n1_; +}; + +bool Predicate1Test::expected_to_finish_; +bool Predicate1Test::finished_; +int Predicate1Test::n1_; + +typedef Predicate1Test EXPECT_PRED_FORMAT1Test; +typedef Predicate1Test ASSERT_PRED_FORMAT1Test; +typedef Predicate1Test EXPECT_PRED1Test; +typedef Predicate1Test ASSERT_PRED1Test; + +// Tests a successful EXPECT_PRED1 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED1Test, FunctionOnBuiltInTypeSuccess) { + EXPECT_PRED1(PredFunction1Int, + ++n1_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED1 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED1Test, FunctionOnUserTypeSuccess) { + EXPECT_PRED1(PredFunction1Bool, + Bool(++n1_)); + finished_ = true; +} + +// Tests a successful EXPECT_PRED1 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED1Test, FunctorOnBuiltInTypeSuccess) { + EXPECT_PRED1(PredFunctor1(), + ++n1_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED1 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED1Test, FunctorOnUserTypeSuccess) { + EXPECT_PRED1(PredFunctor1(), + Bool(++n1_)); + finished_ = true; +} + +// Tests a failed EXPECT_PRED1 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED1Test, FunctionOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED1(PredFunction1Int, + n1_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED1 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED1Test, FunctionOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED1(PredFunction1Bool, + Bool(n1_++)); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED1 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED1Test, FunctorOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED1(PredFunctor1(), + n1_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED1 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED1Test, FunctorOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED1(PredFunctor1(), + Bool(n1_++)); + finished_ = true; + }, ""); +} + +// Tests a successful ASSERT_PRED1 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED1Test, FunctionOnBuiltInTypeSuccess) { + ASSERT_PRED1(PredFunction1Int, + ++n1_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED1 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED1Test, FunctionOnUserTypeSuccess) { + ASSERT_PRED1(PredFunction1Bool, + Bool(++n1_)); + finished_ = true; +} + +// Tests a successful ASSERT_PRED1 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED1Test, FunctorOnBuiltInTypeSuccess) { + ASSERT_PRED1(PredFunctor1(), + ++n1_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED1 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED1Test, FunctorOnUserTypeSuccess) { + ASSERT_PRED1(PredFunctor1(), + Bool(++n1_)); + finished_ = true; +} + +// Tests a failed ASSERT_PRED1 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED1Test, FunctionOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED1(PredFunction1Int, + n1_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED1 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED1Test, FunctionOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED1(PredFunction1Bool, + Bool(n1_++)); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED1 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED1Test, FunctorOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED1(PredFunctor1(), + n1_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED1 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED1Test, FunctorOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED1(PredFunctor1(), + Bool(n1_++)); + finished_ = true; + }, ""); +} + +// Tests a successful EXPECT_PRED_FORMAT1 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT1Test, FunctionOnBuiltInTypeSuccess) { + EXPECT_PRED_FORMAT1(PredFormatFunction1, + ++n1_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED_FORMAT1 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT1Test, FunctionOnUserTypeSuccess) { + EXPECT_PRED_FORMAT1(PredFormatFunction1, + Bool(++n1_)); + finished_ = true; +} + +// Tests a successful EXPECT_PRED_FORMAT1 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT1Test, FunctorOnBuiltInTypeSuccess) { + EXPECT_PRED_FORMAT1(PredFormatFunctor1(), + ++n1_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED_FORMAT1 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT1Test, FunctorOnUserTypeSuccess) { + EXPECT_PRED_FORMAT1(PredFormatFunctor1(), + Bool(++n1_)); + finished_ = true; +} + +// Tests a failed EXPECT_PRED_FORMAT1 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT1Test, FunctionOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT1(PredFormatFunction1, + n1_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED_FORMAT1 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT1Test, FunctionOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT1(PredFormatFunction1, + Bool(n1_++)); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED_FORMAT1 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT1Test, FunctorOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT1(PredFormatFunctor1(), + n1_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED_FORMAT1 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT1Test, FunctorOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT1(PredFormatFunctor1(), + Bool(n1_++)); + finished_ = true; + }, ""); +} + +// Tests a successful ASSERT_PRED_FORMAT1 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT1Test, FunctionOnBuiltInTypeSuccess) { + ASSERT_PRED_FORMAT1(PredFormatFunction1, + ++n1_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED_FORMAT1 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT1Test, FunctionOnUserTypeSuccess) { + ASSERT_PRED_FORMAT1(PredFormatFunction1, + Bool(++n1_)); + finished_ = true; +} + +// Tests a successful ASSERT_PRED_FORMAT1 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT1Test, FunctorOnBuiltInTypeSuccess) { + ASSERT_PRED_FORMAT1(PredFormatFunctor1(), + ++n1_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED_FORMAT1 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT1Test, FunctorOnUserTypeSuccess) { + ASSERT_PRED_FORMAT1(PredFormatFunctor1(), + Bool(++n1_)); + finished_ = true; +} + +// Tests a failed ASSERT_PRED_FORMAT1 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT1Test, FunctionOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT1(PredFormatFunction1, + n1_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED_FORMAT1 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT1Test, FunctionOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT1(PredFormatFunction1, + Bool(n1_++)); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED_FORMAT1 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT1Test, FunctorOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT1(PredFormatFunctor1(), + n1_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED_FORMAT1 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT1Test, FunctorOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT1(PredFormatFunctor1(), + Bool(n1_++)); + finished_ = true; + }, ""); +} +// Sample functions/functors for testing binary predicate assertions. + +// A binary predicate function. +template +bool PredFunction2(T1 v1, T2 v2) { + return v1 + v2 > 0; +} + +// The following two functions are needed to circumvent a bug in +// gcc 2.95.3, which sometimes has problem with the above template +// function. +bool PredFunction2Int(int v1, int v2) { + return v1 + v2 > 0; +} +bool PredFunction2Bool(Bool v1, Bool v2) { + return v1 + v2 > 0; +} + +// A binary predicate functor. +struct PredFunctor2 { + template + bool operator()(const T1& v1, + const T2& v2) { + return v1 + v2 > 0; + } +}; + +// A binary predicate-formatter function. +template +testing::AssertionResult PredFormatFunction2(const char* e1, + const char* e2, + const T1& v1, + const T2& v2) { + if (PredFunction2(v1, v2)) + return testing::AssertionSuccess(); + + testing::Message msg; + msg << e1 << " + " << e2 + << " is expected to be positive, but evaluates to " + << v1 + v2 << "."; + return testing::AssertionFailure(msg); +} + +// A binary predicate-formatter functor. +struct PredFormatFunctor2 { + template + testing::AssertionResult operator()(const char* e1, + const char* e2, + const T1& v1, + const T2& v2) const { + return PredFormatFunction2(e1, e2, v1, v2); + } +}; + +// Tests for {EXPECT|ASSERT}_PRED_FORMAT2. + +class Predicate2Test : public testing::Test { + protected: + virtual void SetUp() { + expected_to_finish_ = true; + finished_ = false; + n1_ = n2_ = 0; + } + + virtual void TearDown() { + // Verifies that each of the predicate's arguments was evaluated + // exactly once. + EXPECT_EQ(1, n1_) << + "The predicate assertion didn't evaluate argument 2 " + "exactly once."; + EXPECT_EQ(1, n2_) << + "The predicate assertion didn't evaluate argument 3 " + "exactly once."; + + // Verifies that the control flow in the test function is expected. + if (expected_to_finish_ && !finished_) { + FAIL() << "The predicate assertion unexpactedly aborted the test."; + } else if (!expected_to_finish_ && finished_) { + FAIL() << "The failed predicate assertion didn't abort the test " + "as expected."; + } + } + + // true iff the test function is expected to run to finish. + static bool expected_to_finish_; + + // true iff the test function did run to finish. + static bool finished_; + + static int n1_; + static int n2_; +}; + +bool Predicate2Test::expected_to_finish_; +bool Predicate2Test::finished_; +int Predicate2Test::n1_; +int Predicate2Test::n2_; + +typedef Predicate2Test EXPECT_PRED_FORMAT2Test; +typedef Predicate2Test ASSERT_PRED_FORMAT2Test; +typedef Predicate2Test EXPECT_PRED2Test; +typedef Predicate2Test ASSERT_PRED2Test; + +// Tests a successful EXPECT_PRED2 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED2Test, FunctionOnBuiltInTypeSuccess) { + EXPECT_PRED2(PredFunction2Int, + ++n1_, + ++n2_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED2 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED2Test, FunctionOnUserTypeSuccess) { + EXPECT_PRED2(PredFunction2Bool, + Bool(++n1_), + Bool(++n2_)); + finished_ = true; +} + +// Tests a successful EXPECT_PRED2 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED2Test, FunctorOnBuiltInTypeSuccess) { + EXPECT_PRED2(PredFunctor2(), + ++n1_, + ++n2_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED2 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED2Test, FunctorOnUserTypeSuccess) { + EXPECT_PRED2(PredFunctor2(), + Bool(++n1_), + Bool(++n2_)); + finished_ = true; +} + +// Tests a failed EXPECT_PRED2 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED2Test, FunctionOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED2(PredFunction2Int, + n1_++, + n2_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED2 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED2Test, FunctionOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED2(PredFunction2Bool, + Bool(n1_++), + Bool(n2_++)); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED2 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED2Test, FunctorOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED2(PredFunctor2(), + n1_++, + n2_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED2 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED2Test, FunctorOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED2(PredFunctor2(), + Bool(n1_++), + Bool(n2_++)); + finished_ = true; + }, ""); +} + +// Tests a successful ASSERT_PRED2 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED2Test, FunctionOnBuiltInTypeSuccess) { + ASSERT_PRED2(PredFunction2Int, + ++n1_, + ++n2_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED2 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED2Test, FunctionOnUserTypeSuccess) { + ASSERT_PRED2(PredFunction2Bool, + Bool(++n1_), + Bool(++n2_)); + finished_ = true; +} + +// Tests a successful ASSERT_PRED2 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED2Test, FunctorOnBuiltInTypeSuccess) { + ASSERT_PRED2(PredFunctor2(), + ++n1_, + ++n2_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED2 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED2Test, FunctorOnUserTypeSuccess) { + ASSERT_PRED2(PredFunctor2(), + Bool(++n1_), + Bool(++n2_)); + finished_ = true; +} + +// Tests a failed ASSERT_PRED2 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED2Test, FunctionOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED2(PredFunction2Int, + n1_++, + n2_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED2 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED2Test, FunctionOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED2(PredFunction2Bool, + Bool(n1_++), + Bool(n2_++)); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED2 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED2Test, FunctorOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED2(PredFunctor2(), + n1_++, + n2_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED2 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED2Test, FunctorOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED2(PredFunctor2(), + Bool(n1_++), + Bool(n2_++)); + finished_ = true; + }, ""); +} + +// Tests a successful EXPECT_PRED_FORMAT2 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT2Test, FunctionOnBuiltInTypeSuccess) { + EXPECT_PRED_FORMAT2(PredFormatFunction2, + ++n1_, + ++n2_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED_FORMAT2 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT2Test, FunctionOnUserTypeSuccess) { + EXPECT_PRED_FORMAT2(PredFormatFunction2, + Bool(++n1_), + Bool(++n2_)); + finished_ = true; +} + +// Tests a successful EXPECT_PRED_FORMAT2 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT2Test, FunctorOnBuiltInTypeSuccess) { + EXPECT_PRED_FORMAT2(PredFormatFunctor2(), + ++n1_, + ++n2_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED_FORMAT2 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT2Test, FunctorOnUserTypeSuccess) { + EXPECT_PRED_FORMAT2(PredFormatFunctor2(), + Bool(++n1_), + Bool(++n2_)); + finished_ = true; +} + +// Tests a failed EXPECT_PRED_FORMAT2 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT2Test, FunctionOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT2(PredFormatFunction2, + n1_++, + n2_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED_FORMAT2 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT2Test, FunctionOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT2(PredFormatFunction2, + Bool(n1_++), + Bool(n2_++)); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED_FORMAT2 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT2Test, FunctorOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT2(PredFormatFunctor2(), + n1_++, + n2_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED_FORMAT2 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT2Test, FunctorOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT2(PredFormatFunctor2(), + Bool(n1_++), + Bool(n2_++)); + finished_ = true; + }, ""); +} + +// Tests a successful ASSERT_PRED_FORMAT2 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT2Test, FunctionOnBuiltInTypeSuccess) { + ASSERT_PRED_FORMAT2(PredFormatFunction2, + ++n1_, + ++n2_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED_FORMAT2 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT2Test, FunctionOnUserTypeSuccess) { + ASSERT_PRED_FORMAT2(PredFormatFunction2, + Bool(++n1_), + Bool(++n2_)); + finished_ = true; +} + +// Tests a successful ASSERT_PRED_FORMAT2 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT2Test, FunctorOnBuiltInTypeSuccess) { + ASSERT_PRED_FORMAT2(PredFormatFunctor2(), + ++n1_, + ++n2_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED_FORMAT2 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT2Test, FunctorOnUserTypeSuccess) { + ASSERT_PRED_FORMAT2(PredFormatFunctor2(), + Bool(++n1_), + Bool(++n2_)); + finished_ = true; +} + +// Tests a failed ASSERT_PRED_FORMAT2 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT2Test, FunctionOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT2(PredFormatFunction2, + n1_++, + n2_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED_FORMAT2 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT2Test, FunctionOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT2(PredFormatFunction2, + Bool(n1_++), + Bool(n2_++)); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED_FORMAT2 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT2Test, FunctorOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT2(PredFormatFunctor2(), + n1_++, + n2_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED_FORMAT2 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT2Test, FunctorOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT2(PredFormatFunctor2(), + Bool(n1_++), + Bool(n2_++)); + finished_ = true; + }, ""); +} +// Sample functions/functors for testing ternary predicate assertions. + +// A ternary predicate function. +template +bool PredFunction3(T1 v1, T2 v2, T3 v3) { + return v1 + v2 + v3 > 0; +} + +// The following two functions are needed to circumvent a bug in +// gcc 2.95.3, which sometimes has problem with the above template +// function. +bool PredFunction3Int(int v1, int v2, int v3) { + return v1 + v2 + v3 > 0; +} +bool PredFunction3Bool(Bool v1, Bool v2, Bool v3) { + return v1 + v2 + v3 > 0; +} + +// A ternary predicate functor. +struct PredFunctor3 { + template + bool operator()(const T1& v1, + const T2& v2, + const T3& v3) { + return v1 + v2 + v3 > 0; + } +}; + +// A ternary predicate-formatter function. +template +testing::AssertionResult PredFormatFunction3(const char* e1, + const char* e2, + const char* e3, + const T1& v1, + const T2& v2, + const T3& v3) { + if (PredFunction3(v1, v2, v3)) + return testing::AssertionSuccess(); + + testing::Message msg; + msg << e1 << " + " << e2 << " + " << e3 + << " is expected to be positive, but evaluates to " + << v1 + v2 + v3 << "."; + return testing::AssertionFailure(msg); +} + +// A ternary predicate-formatter functor. +struct PredFormatFunctor3 { + template + testing::AssertionResult operator()(const char* e1, + const char* e2, + const char* e3, + const T1& v1, + const T2& v2, + const T3& v3) const { + return PredFormatFunction3(e1, e2, e3, v1, v2, v3); + } +}; + +// Tests for {EXPECT|ASSERT}_PRED_FORMAT3. + +class Predicate3Test : public testing::Test { + protected: + virtual void SetUp() { + expected_to_finish_ = true; + finished_ = false; + n1_ = n2_ = n3_ = 0; + } + + virtual void TearDown() { + // Verifies that each of the predicate's arguments was evaluated + // exactly once. + EXPECT_EQ(1, n1_) << + "The predicate assertion didn't evaluate argument 2 " + "exactly once."; + EXPECT_EQ(1, n2_) << + "The predicate assertion didn't evaluate argument 3 " + "exactly once."; + EXPECT_EQ(1, n3_) << + "The predicate assertion didn't evaluate argument 4 " + "exactly once."; + + // Verifies that the control flow in the test function is expected. + if (expected_to_finish_ && !finished_) { + FAIL() << "The predicate assertion unexpactedly aborted the test."; + } else if (!expected_to_finish_ && finished_) { + FAIL() << "The failed predicate assertion didn't abort the test " + "as expected."; + } + } + + // true iff the test function is expected to run to finish. + static bool expected_to_finish_; + + // true iff the test function did run to finish. + static bool finished_; + + static int n1_; + static int n2_; + static int n3_; +}; + +bool Predicate3Test::expected_to_finish_; +bool Predicate3Test::finished_; +int Predicate3Test::n1_; +int Predicate3Test::n2_; +int Predicate3Test::n3_; + +typedef Predicate3Test EXPECT_PRED_FORMAT3Test; +typedef Predicate3Test ASSERT_PRED_FORMAT3Test; +typedef Predicate3Test EXPECT_PRED3Test; +typedef Predicate3Test ASSERT_PRED3Test; + +// Tests a successful EXPECT_PRED3 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED3Test, FunctionOnBuiltInTypeSuccess) { + EXPECT_PRED3(PredFunction3Int, + ++n1_, + ++n2_, + ++n3_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED3 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED3Test, FunctionOnUserTypeSuccess) { + EXPECT_PRED3(PredFunction3Bool, + Bool(++n1_), + Bool(++n2_), + Bool(++n3_)); + finished_ = true; +} + +// Tests a successful EXPECT_PRED3 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED3Test, FunctorOnBuiltInTypeSuccess) { + EXPECT_PRED3(PredFunctor3(), + ++n1_, + ++n2_, + ++n3_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED3 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED3Test, FunctorOnUserTypeSuccess) { + EXPECT_PRED3(PredFunctor3(), + Bool(++n1_), + Bool(++n2_), + Bool(++n3_)); + finished_ = true; +} + +// Tests a failed EXPECT_PRED3 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED3Test, FunctionOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED3(PredFunction3Int, + n1_++, + n2_++, + n3_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED3 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED3Test, FunctionOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED3(PredFunction3Bool, + Bool(n1_++), + Bool(n2_++), + Bool(n3_++)); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED3 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED3Test, FunctorOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED3(PredFunctor3(), + n1_++, + n2_++, + n3_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED3 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED3Test, FunctorOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED3(PredFunctor3(), + Bool(n1_++), + Bool(n2_++), + Bool(n3_++)); + finished_ = true; + }, ""); +} + +// Tests a successful ASSERT_PRED3 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED3Test, FunctionOnBuiltInTypeSuccess) { + ASSERT_PRED3(PredFunction3Int, + ++n1_, + ++n2_, + ++n3_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED3 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED3Test, FunctionOnUserTypeSuccess) { + ASSERT_PRED3(PredFunction3Bool, + Bool(++n1_), + Bool(++n2_), + Bool(++n3_)); + finished_ = true; +} + +// Tests a successful ASSERT_PRED3 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED3Test, FunctorOnBuiltInTypeSuccess) { + ASSERT_PRED3(PredFunctor3(), + ++n1_, + ++n2_, + ++n3_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED3 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED3Test, FunctorOnUserTypeSuccess) { + ASSERT_PRED3(PredFunctor3(), + Bool(++n1_), + Bool(++n2_), + Bool(++n3_)); + finished_ = true; +} + +// Tests a failed ASSERT_PRED3 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED3Test, FunctionOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED3(PredFunction3Int, + n1_++, + n2_++, + n3_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED3 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED3Test, FunctionOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED3(PredFunction3Bool, + Bool(n1_++), + Bool(n2_++), + Bool(n3_++)); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED3 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED3Test, FunctorOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED3(PredFunctor3(), + n1_++, + n2_++, + n3_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED3 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED3Test, FunctorOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED3(PredFunctor3(), + Bool(n1_++), + Bool(n2_++), + Bool(n3_++)); + finished_ = true; + }, ""); +} + +// Tests a successful EXPECT_PRED_FORMAT3 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT3Test, FunctionOnBuiltInTypeSuccess) { + EXPECT_PRED_FORMAT3(PredFormatFunction3, + ++n1_, + ++n2_, + ++n3_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED_FORMAT3 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT3Test, FunctionOnUserTypeSuccess) { + EXPECT_PRED_FORMAT3(PredFormatFunction3, + Bool(++n1_), + Bool(++n2_), + Bool(++n3_)); + finished_ = true; +} + +// Tests a successful EXPECT_PRED_FORMAT3 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT3Test, FunctorOnBuiltInTypeSuccess) { + EXPECT_PRED_FORMAT3(PredFormatFunctor3(), + ++n1_, + ++n2_, + ++n3_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED_FORMAT3 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT3Test, FunctorOnUserTypeSuccess) { + EXPECT_PRED_FORMAT3(PredFormatFunctor3(), + Bool(++n1_), + Bool(++n2_), + Bool(++n3_)); + finished_ = true; +} + +// Tests a failed EXPECT_PRED_FORMAT3 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT3Test, FunctionOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT3(PredFormatFunction3, + n1_++, + n2_++, + n3_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED_FORMAT3 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT3Test, FunctionOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT3(PredFormatFunction3, + Bool(n1_++), + Bool(n2_++), + Bool(n3_++)); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED_FORMAT3 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT3Test, FunctorOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT3(PredFormatFunctor3(), + n1_++, + n2_++, + n3_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED_FORMAT3 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT3Test, FunctorOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT3(PredFormatFunctor3(), + Bool(n1_++), + Bool(n2_++), + Bool(n3_++)); + finished_ = true; + }, ""); +} + +// Tests a successful ASSERT_PRED_FORMAT3 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT3Test, FunctionOnBuiltInTypeSuccess) { + ASSERT_PRED_FORMAT3(PredFormatFunction3, + ++n1_, + ++n2_, + ++n3_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED_FORMAT3 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT3Test, FunctionOnUserTypeSuccess) { + ASSERT_PRED_FORMAT3(PredFormatFunction3, + Bool(++n1_), + Bool(++n2_), + Bool(++n3_)); + finished_ = true; +} + +// Tests a successful ASSERT_PRED_FORMAT3 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT3Test, FunctorOnBuiltInTypeSuccess) { + ASSERT_PRED_FORMAT3(PredFormatFunctor3(), + ++n1_, + ++n2_, + ++n3_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED_FORMAT3 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT3Test, FunctorOnUserTypeSuccess) { + ASSERT_PRED_FORMAT3(PredFormatFunctor3(), + Bool(++n1_), + Bool(++n2_), + Bool(++n3_)); + finished_ = true; +} + +// Tests a failed ASSERT_PRED_FORMAT3 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT3Test, FunctionOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT3(PredFormatFunction3, + n1_++, + n2_++, + n3_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED_FORMAT3 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT3Test, FunctionOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT3(PredFormatFunction3, + Bool(n1_++), + Bool(n2_++), + Bool(n3_++)); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED_FORMAT3 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT3Test, FunctorOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT3(PredFormatFunctor3(), + n1_++, + n2_++, + n3_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED_FORMAT3 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT3Test, FunctorOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT3(PredFormatFunctor3(), + Bool(n1_++), + Bool(n2_++), + Bool(n3_++)); + finished_ = true; + }, ""); +} +// Sample functions/functors for testing 4-ary predicate assertions. + +// A 4-ary predicate function. +template +bool PredFunction4(T1 v1, T2 v2, T3 v3, T4 v4) { + return v1 + v2 + v3 + v4 > 0; +} + +// The following two functions are needed to circumvent a bug in +// gcc 2.95.3, which sometimes has problem with the above template +// function. +bool PredFunction4Int(int v1, int v2, int v3, int v4) { + return v1 + v2 + v3 + v4 > 0; +} +bool PredFunction4Bool(Bool v1, Bool v2, Bool v3, Bool v4) { + return v1 + v2 + v3 + v4 > 0; +} + +// A 4-ary predicate functor. +struct PredFunctor4 { + template + bool operator()(const T1& v1, + const T2& v2, + const T3& v3, + const T4& v4) { + return v1 + v2 + v3 + v4 > 0; + } +}; + +// A 4-ary predicate-formatter function. +template +testing::AssertionResult PredFormatFunction4(const char* e1, + const char* e2, + const char* e3, + const char* e4, + const T1& v1, + const T2& v2, + const T3& v3, + const T4& v4) { + if (PredFunction4(v1, v2, v3, v4)) + return testing::AssertionSuccess(); + + testing::Message msg; + msg << e1 << " + " << e2 << " + " << e3 << " + " << e4 + << " is expected to be positive, but evaluates to " + << v1 + v2 + v3 + v4 << "."; + return testing::AssertionFailure(msg); +} + +// A 4-ary predicate-formatter functor. +struct PredFormatFunctor4 { + template + testing::AssertionResult operator()(const char* e1, + const char* e2, + const char* e3, + const char* e4, + const T1& v1, + const T2& v2, + const T3& v3, + const T4& v4) const { + return PredFormatFunction4(e1, e2, e3, e4, v1, v2, v3, v4); + } +}; + +// Tests for {EXPECT|ASSERT}_PRED_FORMAT4. + +class Predicate4Test : public testing::Test { + protected: + virtual void SetUp() { + expected_to_finish_ = true; + finished_ = false; + n1_ = n2_ = n3_ = n4_ = 0; + } + + virtual void TearDown() { + // Verifies that each of the predicate's arguments was evaluated + // exactly once. + EXPECT_EQ(1, n1_) << + "The predicate assertion didn't evaluate argument 2 " + "exactly once."; + EXPECT_EQ(1, n2_) << + "The predicate assertion didn't evaluate argument 3 " + "exactly once."; + EXPECT_EQ(1, n3_) << + "The predicate assertion didn't evaluate argument 4 " + "exactly once."; + EXPECT_EQ(1, n4_) << + "The predicate assertion didn't evaluate argument 5 " + "exactly once."; + + // Verifies that the control flow in the test function is expected. + if (expected_to_finish_ && !finished_) { + FAIL() << "The predicate assertion unexpactedly aborted the test."; + } else if (!expected_to_finish_ && finished_) { + FAIL() << "The failed predicate assertion didn't abort the test " + "as expected."; + } + } + + // true iff the test function is expected to run to finish. + static bool expected_to_finish_; + + // true iff the test function did run to finish. + static bool finished_; + + static int n1_; + static int n2_; + static int n3_; + static int n4_; +}; + +bool Predicate4Test::expected_to_finish_; +bool Predicate4Test::finished_; +int Predicate4Test::n1_; +int Predicate4Test::n2_; +int Predicate4Test::n3_; +int Predicate4Test::n4_; + +typedef Predicate4Test EXPECT_PRED_FORMAT4Test; +typedef Predicate4Test ASSERT_PRED_FORMAT4Test; +typedef Predicate4Test EXPECT_PRED4Test; +typedef Predicate4Test ASSERT_PRED4Test; + +// Tests a successful EXPECT_PRED4 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED4Test, FunctionOnBuiltInTypeSuccess) { + EXPECT_PRED4(PredFunction4Int, + ++n1_, + ++n2_, + ++n3_, + ++n4_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED4 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED4Test, FunctionOnUserTypeSuccess) { + EXPECT_PRED4(PredFunction4Bool, + Bool(++n1_), + Bool(++n2_), + Bool(++n3_), + Bool(++n4_)); + finished_ = true; +} + +// Tests a successful EXPECT_PRED4 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED4Test, FunctorOnBuiltInTypeSuccess) { + EXPECT_PRED4(PredFunctor4(), + ++n1_, + ++n2_, + ++n3_, + ++n4_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED4 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED4Test, FunctorOnUserTypeSuccess) { + EXPECT_PRED4(PredFunctor4(), + Bool(++n1_), + Bool(++n2_), + Bool(++n3_), + Bool(++n4_)); + finished_ = true; +} + +// Tests a failed EXPECT_PRED4 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED4Test, FunctionOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED4(PredFunction4Int, + n1_++, + n2_++, + n3_++, + n4_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED4 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED4Test, FunctionOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED4(PredFunction4Bool, + Bool(n1_++), + Bool(n2_++), + Bool(n3_++), + Bool(n4_++)); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED4 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED4Test, FunctorOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED4(PredFunctor4(), + n1_++, + n2_++, + n3_++, + n4_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED4 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED4Test, FunctorOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED4(PredFunctor4(), + Bool(n1_++), + Bool(n2_++), + Bool(n3_++), + Bool(n4_++)); + finished_ = true; + }, ""); +} + +// Tests a successful ASSERT_PRED4 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED4Test, FunctionOnBuiltInTypeSuccess) { + ASSERT_PRED4(PredFunction4Int, + ++n1_, + ++n2_, + ++n3_, + ++n4_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED4 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED4Test, FunctionOnUserTypeSuccess) { + ASSERT_PRED4(PredFunction4Bool, + Bool(++n1_), + Bool(++n2_), + Bool(++n3_), + Bool(++n4_)); + finished_ = true; +} + +// Tests a successful ASSERT_PRED4 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED4Test, FunctorOnBuiltInTypeSuccess) { + ASSERT_PRED4(PredFunctor4(), + ++n1_, + ++n2_, + ++n3_, + ++n4_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED4 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED4Test, FunctorOnUserTypeSuccess) { + ASSERT_PRED4(PredFunctor4(), + Bool(++n1_), + Bool(++n2_), + Bool(++n3_), + Bool(++n4_)); + finished_ = true; +} + +// Tests a failed ASSERT_PRED4 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED4Test, FunctionOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED4(PredFunction4Int, + n1_++, + n2_++, + n3_++, + n4_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED4 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED4Test, FunctionOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED4(PredFunction4Bool, + Bool(n1_++), + Bool(n2_++), + Bool(n3_++), + Bool(n4_++)); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED4 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED4Test, FunctorOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED4(PredFunctor4(), + n1_++, + n2_++, + n3_++, + n4_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED4 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED4Test, FunctorOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED4(PredFunctor4(), + Bool(n1_++), + Bool(n2_++), + Bool(n3_++), + Bool(n4_++)); + finished_ = true; + }, ""); +} + +// Tests a successful EXPECT_PRED_FORMAT4 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT4Test, FunctionOnBuiltInTypeSuccess) { + EXPECT_PRED_FORMAT4(PredFormatFunction4, + ++n1_, + ++n2_, + ++n3_, + ++n4_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED_FORMAT4 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT4Test, FunctionOnUserTypeSuccess) { + EXPECT_PRED_FORMAT4(PredFormatFunction4, + Bool(++n1_), + Bool(++n2_), + Bool(++n3_), + Bool(++n4_)); + finished_ = true; +} + +// Tests a successful EXPECT_PRED_FORMAT4 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT4Test, FunctorOnBuiltInTypeSuccess) { + EXPECT_PRED_FORMAT4(PredFormatFunctor4(), + ++n1_, + ++n2_, + ++n3_, + ++n4_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED_FORMAT4 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT4Test, FunctorOnUserTypeSuccess) { + EXPECT_PRED_FORMAT4(PredFormatFunctor4(), + Bool(++n1_), + Bool(++n2_), + Bool(++n3_), + Bool(++n4_)); + finished_ = true; +} + +// Tests a failed EXPECT_PRED_FORMAT4 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT4Test, FunctionOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT4(PredFormatFunction4, + n1_++, + n2_++, + n3_++, + n4_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED_FORMAT4 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT4Test, FunctionOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT4(PredFormatFunction4, + Bool(n1_++), + Bool(n2_++), + Bool(n3_++), + Bool(n4_++)); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED_FORMAT4 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT4Test, FunctorOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT4(PredFormatFunctor4(), + n1_++, + n2_++, + n3_++, + n4_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED_FORMAT4 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT4Test, FunctorOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT4(PredFormatFunctor4(), + Bool(n1_++), + Bool(n2_++), + Bool(n3_++), + Bool(n4_++)); + finished_ = true; + }, ""); +} + +// Tests a successful ASSERT_PRED_FORMAT4 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT4Test, FunctionOnBuiltInTypeSuccess) { + ASSERT_PRED_FORMAT4(PredFormatFunction4, + ++n1_, + ++n2_, + ++n3_, + ++n4_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED_FORMAT4 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT4Test, FunctionOnUserTypeSuccess) { + ASSERT_PRED_FORMAT4(PredFormatFunction4, + Bool(++n1_), + Bool(++n2_), + Bool(++n3_), + Bool(++n4_)); + finished_ = true; +} + +// Tests a successful ASSERT_PRED_FORMAT4 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT4Test, FunctorOnBuiltInTypeSuccess) { + ASSERT_PRED_FORMAT4(PredFormatFunctor4(), + ++n1_, + ++n2_, + ++n3_, + ++n4_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED_FORMAT4 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT4Test, FunctorOnUserTypeSuccess) { + ASSERT_PRED_FORMAT4(PredFormatFunctor4(), + Bool(++n1_), + Bool(++n2_), + Bool(++n3_), + Bool(++n4_)); + finished_ = true; +} + +// Tests a failed ASSERT_PRED_FORMAT4 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT4Test, FunctionOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT4(PredFormatFunction4, + n1_++, + n2_++, + n3_++, + n4_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED_FORMAT4 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT4Test, FunctionOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT4(PredFormatFunction4, + Bool(n1_++), + Bool(n2_++), + Bool(n3_++), + Bool(n4_++)); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED_FORMAT4 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT4Test, FunctorOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT4(PredFormatFunctor4(), + n1_++, + n2_++, + n3_++, + n4_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED_FORMAT4 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT4Test, FunctorOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT4(PredFormatFunctor4(), + Bool(n1_++), + Bool(n2_++), + Bool(n3_++), + Bool(n4_++)); + finished_ = true; + }, ""); +} +// Sample functions/functors for testing 5-ary predicate assertions. + +// A 5-ary predicate function. +template +bool PredFunction5(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5) { + return v1 + v2 + v3 + v4 + v5 > 0; +} + +// The following two functions are needed to circumvent a bug in +// gcc 2.95.3, which sometimes has problem with the above template +// function. +bool PredFunction5Int(int v1, int v2, int v3, int v4, int v5) { + return v1 + v2 + v3 + v4 + v5 > 0; +} +bool PredFunction5Bool(Bool v1, Bool v2, Bool v3, Bool v4, Bool v5) { + return v1 + v2 + v3 + v4 + v5 > 0; +} + +// A 5-ary predicate functor. +struct PredFunctor5 { + template + bool operator()(const T1& v1, + const T2& v2, + const T3& v3, + const T4& v4, + const T5& v5) { + return v1 + v2 + v3 + v4 + v5 > 0; + } +}; + +// A 5-ary predicate-formatter function. +template +testing::AssertionResult PredFormatFunction5(const char* e1, + const char* e2, + const char* e3, + const char* e4, + const char* e5, + const T1& v1, + const T2& v2, + const T3& v3, + const T4& v4, + const T5& v5) { + if (PredFunction5(v1, v2, v3, v4, v5)) + return testing::AssertionSuccess(); + + testing::Message msg; + msg << e1 << " + " << e2 << " + " << e3 << " + " << e4 << " + " << e5 + << " is expected to be positive, but evaluates to " + << v1 + v2 + v3 + v4 + v5 << "."; + return testing::AssertionFailure(msg); +} + +// A 5-ary predicate-formatter functor. +struct PredFormatFunctor5 { + template + testing::AssertionResult operator()(const char* e1, + const char* e2, + const char* e3, + const char* e4, + const char* e5, + const T1& v1, + const T2& v2, + const T3& v3, + const T4& v4, + const T5& v5) const { + return PredFormatFunction5(e1, e2, e3, e4, e5, v1, v2, v3, v4, v5); + } +}; + +// Tests for {EXPECT|ASSERT}_PRED_FORMAT5. + +class Predicate5Test : public testing::Test { + protected: + virtual void SetUp() { + expected_to_finish_ = true; + finished_ = false; + n1_ = n2_ = n3_ = n4_ = n5_ = 0; + } + + virtual void TearDown() { + // Verifies that each of the predicate's arguments was evaluated + // exactly once. + EXPECT_EQ(1, n1_) << + "The predicate assertion didn't evaluate argument 2 " + "exactly once."; + EXPECT_EQ(1, n2_) << + "The predicate assertion didn't evaluate argument 3 " + "exactly once."; + EXPECT_EQ(1, n3_) << + "The predicate assertion didn't evaluate argument 4 " + "exactly once."; + EXPECT_EQ(1, n4_) << + "The predicate assertion didn't evaluate argument 5 " + "exactly once."; + EXPECT_EQ(1, n5_) << + "The predicate assertion didn't evaluate argument 6 " + "exactly once."; + + // Verifies that the control flow in the test function is expected. + if (expected_to_finish_ && !finished_) { + FAIL() << "The predicate assertion unexpactedly aborted the test."; + } else if (!expected_to_finish_ && finished_) { + FAIL() << "The failed predicate assertion didn't abort the test " + "as expected."; + } + } + + // true iff the test function is expected to run to finish. + static bool expected_to_finish_; + + // true iff the test function did run to finish. + static bool finished_; + + static int n1_; + static int n2_; + static int n3_; + static int n4_; + static int n5_; +}; + +bool Predicate5Test::expected_to_finish_; +bool Predicate5Test::finished_; +int Predicate5Test::n1_; +int Predicate5Test::n2_; +int Predicate5Test::n3_; +int Predicate5Test::n4_; +int Predicate5Test::n5_; + +typedef Predicate5Test EXPECT_PRED_FORMAT5Test; +typedef Predicate5Test ASSERT_PRED_FORMAT5Test; +typedef Predicate5Test EXPECT_PRED5Test; +typedef Predicate5Test ASSERT_PRED5Test; + +// Tests a successful EXPECT_PRED5 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED5Test, FunctionOnBuiltInTypeSuccess) { + EXPECT_PRED5(PredFunction5Int, + ++n1_, + ++n2_, + ++n3_, + ++n4_, + ++n5_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED5 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED5Test, FunctionOnUserTypeSuccess) { + EXPECT_PRED5(PredFunction5Bool, + Bool(++n1_), + Bool(++n2_), + Bool(++n3_), + Bool(++n4_), + Bool(++n5_)); + finished_ = true; +} + +// Tests a successful EXPECT_PRED5 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED5Test, FunctorOnBuiltInTypeSuccess) { + EXPECT_PRED5(PredFunctor5(), + ++n1_, + ++n2_, + ++n3_, + ++n4_, + ++n5_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED5 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED5Test, FunctorOnUserTypeSuccess) { + EXPECT_PRED5(PredFunctor5(), + Bool(++n1_), + Bool(++n2_), + Bool(++n3_), + Bool(++n4_), + Bool(++n5_)); + finished_ = true; +} + +// Tests a failed EXPECT_PRED5 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED5Test, FunctionOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED5(PredFunction5Int, + n1_++, + n2_++, + n3_++, + n4_++, + n5_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED5 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED5Test, FunctionOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED5(PredFunction5Bool, + Bool(n1_++), + Bool(n2_++), + Bool(n3_++), + Bool(n4_++), + Bool(n5_++)); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED5 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED5Test, FunctorOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED5(PredFunctor5(), + n1_++, + n2_++, + n3_++, + n4_++, + n5_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED5 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED5Test, FunctorOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED5(PredFunctor5(), + Bool(n1_++), + Bool(n2_++), + Bool(n3_++), + Bool(n4_++), + Bool(n5_++)); + finished_ = true; + }, ""); +} + +// Tests a successful ASSERT_PRED5 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED5Test, FunctionOnBuiltInTypeSuccess) { + ASSERT_PRED5(PredFunction5Int, + ++n1_, + ++n2_, + ++n3_, + ++n4_, + ++n5_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED5 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED5Test, FunctionOnUserTypeSuccess) { + ASSERT_PRED5(PredFunction5Bool, + Bool(++n1_), + Bool(++n2_), + Bool(++n3_), + Bool(++n4_), + Bool(++n5_)); + finished_ = true; +} + +// Tests a successful ASSERT_PRED5 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED5Test, FunctorOnBuiltInTypeSuccess) { + ASSERT_PRED5(PredFunctor5(), + ++n1_, + ++n2_, + ++n3_, + ++n4_, + ++n5_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED5 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED5Test, FunctorOnUserTypeSuccess) { + ASSERT_PRED5(PredFunctor5(), + Bool(++n1_), + Bool(++n2_), + Bool(++n3_), + Bool(++n4_), + Bool(++n5_)); + finished_ = true; +} + +// Tests a failed ASSERT_PRED5 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED5Test, FunctionOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED5(PredFunction5Int, + n1_++, + n2_++, + n3_++, + n4_++, + n5_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED5 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED5Test, FunctionOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED5(PredFunction5Bool, + Bool(n1_++), + Bool(n2_++), + Bool(n3_++), + Bool(n4_++), + Bool(n5_++)); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED5 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED5Test, FunctorOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED5(PredFunctor5(), + n1_++, + n2_++, + n3_++, + n4_++, + n5_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED5 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED5Test, FunctorOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED5(PredFunctor5(), + Bool(n1_++), + Bool(n2_++), + Bool(n3_++), + Bool(n4_++), + Bool(n5_++)); + finished_ = true; + }, ""); +} + +// Tests a successful EXPECT_PRED_FORMAT5 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT5Test, FunctionOnBuiltInTypeSuccess) { + EXPECT_PRED_FORMAT5(PredFormatFunction5, + ++n1_, + ++n2_, + ++n3_, + ++n4_, + ++n5_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED_FORMAT5 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT5Test, FunctionOnUserTypeSuccess) { + EXPECT_PRED_FORMAT5(PredFormatFunction5, + Bool(++n1_), + Bool(++n2_), + Bool(++n3_), + Bool(++n4_), + Bool(++n5_)); + finished_ = true; +} + +// Tests a successful EXPECT_PRED_FORMAT5 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT5Test, FunctorOnBuiltInTypeSuccess) { + EXPECT_PRED_FORMAT5(PredFormatFunctor5(), + ++n1_, + ++n2_, + ++n3_, + ++n4_, + ++n5_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED_FORMAT5 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT5Test, FunctorOnUserTypeSuccess) { + EXPECT_PRED_FORMAT5(PredFormatFunctor5(), + Bool(++n1_), + Bool(++n2_), + Bool(++n3_), + Bool(++n4_), + Bool(++n5_)); + finished_ = true; +} + +// Tests a failed EXPECT_PRED_FORMAT5 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT5Test, FunctionOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT5(PredFormatFunction5, + n1_++, + n2_++, + n3_++, + n4_++, + n5_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED_FORMAT5 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT5Test, FunctionOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT5(PredFormatFunction5, + Bool(n1_++), + Bool(n2_++), + Bool(n3_++), + Bool(n4_++), + Bool(n5_++)); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED_FORMAT5 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT5Test, FunctorOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT5(PredFormatFunctor5(), + n1_++, + n2_++, + n3_++, + n4_++, + n5_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED_FORMAT5 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT5Test, FunctorOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT5(PredFormatFunctor5(), + Bool(n1_++), + Bool(n2_++), + Bool(n3_++), + Bool(n4_++), + Bool(n5_++)); + finished_ = true; + }, ""); +} + +// Tests a successful ASSERT_PRED_FORMAT5 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT5Test, FunctionOnBuiltInTypeSuccess) { + ASSERT_PRED_FORMAT5(PredFormatFunction5, + ++n1_, + ++n2_, + ++n3_, + ++n4_, + ++n5_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED_FORMAT5 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT5Test, FunctionOnUserTypeSuccess) { + ASSERT_PRED_FORMAT5(PredFormatFunction5, + Bool(++n1_), + Bool(++n2_), + Bool(++n3_), + Bool(++n4_), + Bool(++n5_)); + finished_ = true; +} + +// Tests a successful ASSERT_PRED_FORMAT5 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT5Test, FunctorOnBuiltInTypeSuccess) { + ASSERT_PRED_FORMAT5(PredFormatFunctor5(), + ++n1_, + ++n2_, + ++n3_, + ++n4_, + ++n5_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED_FORMAT5 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT5Test, FunctorOnUserTypeSuccess) { + ASSERT_PRED_FORMAT5(PredFormatFunctor5(), + Bool(++n1_), + Bool(++n2_), + Bool(++n3_), + Bool(++n4_), + Bool(++n5_)); + finished_ = true; +} + +// Tests a failed ASSERT_PRED_FORMAT5 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT5Test, FunctionOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT5(PredFormatFunction5, + n1_++, + n2_++, + n3_++, + n4_++, + n5_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED_FORMAT5 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT5Test, FunctionOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT5(PredFormatFunction5, + Bool(n1_++), + Bool(n2_++), + Bool(n3_++), + Bool(n4_++), + Bool(n5_++)); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED_FORMAT5 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT5Test, FunctorOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT5(PredFormatFunctor5(), + n1_++, + n2_++, + n3_++, + n4_++, + n5_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED_FORMAT5 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT5Test, FunctorOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT5(PredFormatFunctor5(), + Bool(n1_++), + Bool(n2_++), + Bool(n3_++), + Bool(n4_++), + Bool(n5_++)); + finished_ = true; + }, ""); +} diff --git a/test/gtest_prod_test.cc b/test/gtest_prod_test.cc new file mode 100644 index 00000000..bc3201d0 --- /dev/null +++ b/test/gtest_prod_test.cc @@ -0,0 +1,57 @@ +// Copyright 2006, 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) +// +// Unit test for include/gtest/gtest_prod.h. + +#include +#include "test/production.h" + +// Tests that private members can be accessed from a TEST declared as +// a friend of the class. +TEST(PrivateCodeTest, CanAccessPrivateMembers) { + PrivateCode a; + EXPECT_EQ(0, a.x_); + + a.set_x(1); + EXPECT_EQ(1, a.x_); +} + +typedef testing::Test PrivateCodeFixtureTest; + +// Tests that private members can be accessed from a TEST_F declared +// as a friend of the class. +TEST_F(PrivateCodeFixtureTest, CanAccessPrivateMembers) { + PrivateCode a; + EXPECT_EQ(0, a.x_); + + a.set_x(2); + EXPECT_EQ(2, a.x_); +} diff --git a/test/gtest_repeat_test.cc b/test/gtest_repeat_test.cc new file mode 100644 index 00000000..056e6cc8 --- /dev/null +++ b/test/gtest_repeat_test.cc @@ -0,0 +1,223 @@ +// Copyright 2008, 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) + +// Tests the --gtest_repeat=number flag. + +#include +#include +#include + +// Indicates that this translation unit is part of Google Test's +// implementation. It must come before gtest-internal-inl.h is +// included, or there will be a compiler error. This trick is to +// prevent a user from accidentally including gtest-internal-inl.h in +// his code. +#define GTEST_IMPLEMENTATION +#include "src/gtest-internal-inl.h" +#undef GTEST_IMPLEMENTATION + +namespace testing { + +GTEST_DECLARE_string(death_test_style); +GTEST_DECLARE_string(filter); +GTEST_DECLARE_int32(repeat); + +} // namespace testing + +using testing::GTEST_FLAG(death_test_style); +using testing::GTEST_FLAG(filter); +using testing::GTEST_FLAG(repeat); + +namespace { + +#define GTEST_CHECK_INT_EQ_(expected, actual) \ + do {\ + const int expected_val = (expected);\ + const int actual_val = (actual);\ + if (expected_val != actual_val) {\ + ::std::cout << "Value of: " #actual "\n"\ + << " Actual: " << actual_val << "\n"\ + << "Expected: " #expected "\n"\ + << "Which is: " << expected_val << "\n";\ + abort();\ + }\ + } while(false) + + +// Used for verifying that global environment set-up and tear-down are +// inside the gtest_repeat loop. + +int g_environment_set_up_count = 0; +int g_environment_tear_down_count = 0; + +class MyEnvironment : public testing::Environment { + public: + MyEnvironment() {} + virtual void SetUp() { g_environment_set_up_count++; } + virtual void TearDown() { g_environment_tear_down_count++; } +}; + +// A test that should fail. + +int g_should_fail_count = 0; + +TEST(FooTest, ShouldFail) { + g_should_fail_count++; + EXPECT_EQ(0, 1) << "Expected failure."; +} + +// A test that should pass. + +int g_should_pass_count = 0; + +TEST(FooTest, ShouldPass) { + g_should_pass_count++; +} + +// A test that contains a thread-safe death test and a fast death +// test. It should pass. + +int g_death_test_count = 0; + +TEST(BarDeathTest, ThreadSafeAndFast) { + g_death_test_count++; + + GTEST_FLAG(death_test_style) = "threadsafe"; + EXPECT_DEATH(abort(), ""); + + GTEST_FLAG(death_test_style) = "fast"; + EXPECT_DEATH(abort(), ""); +} + +// Resets the count for each test. +void ResetCounts() { + g_environment_set_up_count = 0; + g_environment_tear_down_count = 0; + g_should_fail_count = 0; + g_should_pass_count = 0; + g_death_test_count = 0; +} + +// Checks that the count for each test is expected. +void CheckCounts(int expected) { + // We cannot use Google Test assertions here since we are testing Google Test + // itself. + GTEST_CHECK_INT_EQ_(expected, g_environment_set_up_count); + GTEST_CHECK_INT_EQ_(expected, g_environment_tear_down_count); + GTEST_CHECK_INT_EQ_(expected, g_should_fail_count); + GTEST_CHECK_INT_EQ_(expected, g_should_pass_count); + GTEST_CHECK_INT_EQ_(expected, g_death_test_count); +} + +// Tests the behavior of Google Test when --gtest_repeat is not specified. +void TestRepeatUnspecified() { + ResetCounts(); + GTEST_CHECK_INT_EQ_(1, RUN_ALL_TESTS()); + CheckCounts(1); +} + +// Tests the behavior of Google Test when --gtest_repeat has the given value. +void TestRepeat(int repeat) { + GTEST_FLAG(repeat) = repeat; + + ResetCounts(); + GTEST_CHECK_INT_EQ_(repeat > 0 ? 1 : 0, RUN_ALL_TESTS()); + CheckCounts(repeat); +} + +// Tests using --gtest_repeat when --gtest_filter specifies an empty +// set of tests. +void TestRepeatWithEmptyFilter(int repeat) { + GTEST_FLAG(repeat) = repeat; + GTEST_FLAG(filter) = "None"; + + ResetCounts(); + GTEST_CHECK_INT_EQ_(0, RUN_ALL_TESTS()); + CheckCounts(0); +} + +// Tests using --gtest_repeat when --gtest_filter specifies a set of +// successful tests. +void TestRepeatWithFilterForSuccessfulTests(int repeat) { + GTEST_FLAG(repeat) = repeat; + GTEST_FLAG(filter) = "*-*ShouldFail"; + + ResetCounts(); + GTEST_CHECK_INT_EQ_(0, RUN_ALL_TESTS()); + GTEST_CHECK_INT_EQ_(repeat, g_environment_set_up_count); + GTEST_CHECK_INT_EQ_(repeat, g_environment_tear_down_count); + GTEST_CHECK_INT_EQ_(0, g_should_fail_count); + GTEST_CHECK_INT_EQ_(repeat, g_should_pass_count); + GTEST_CHECK_INT_EQ_(repeat, g_death_test_count); +} + +// Tests using --gtest_repeat when --gtest_filter specifies a set of +// failed tests. +void TestRepeatWithFilterForFailedTests(int repeat) { + GTEST_FLAG(repeat) = repeat; + GTEST_FLAG(filter) = "*ShouldFail"; + + ResetCounts(); + GTEST_CHECK_INT_EQ_(1, RUN_ALL_TESTS()); + GTEST_CHECK_INT_EQ_(repeat, g_environment_set_up_count); + GTEST_CHECK_INT_EQ_(repeat, g_environment_tear_down_count); + GTEST_CHECK_INT_EQ_(repeat, g_should_fail_count); + GTEST_CHECK_INT_EQ_(0, g_should_pass_count); + GTEST_CHECK_INT_EQ_(0, g_death_test_count); +} + +} // namespace + +int main(int argc, char **argv) { + testing::InitGoogleTest(&argc, argv); + testing::AddGlobalTestEnvironment(new MyEnvironment); + + TestRepeatUnspecified(); + TestRepeat(0); + TestRepeat(1); + TestRepeat(5); + + TestRepeatWithEmptyFilter(2); + TestRepeatWithEmptyFilter(3); + + TestRepeatWithFilterForSuccessfulTests(3); + + TestRepeatWithFilterForFailedTests(4); + + // It would be nice to verify that the tests indeed loop forever + // when GTEST_FLAG(repeat) is negative, but this test will be quite + // complicated to write. Since this flag is for interactive + // debugging only and doesn't affect the normal test result, such a + // test would be an overkill. + + printf("PASS\n"); + return 0; +} diff --git a/test/gtest_stress_test.cc b/test/gtest_stress_test.cc new file mode 100644 index 00000000..f833b7c6 --- /dev/null +++ b/test/gtest_stress_test.cc @@ -0,0 +1,122 @@ +// Copyright 2007, 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) + +// Tests that SCOPED_TRACE() and various Google Test assertions can be +// used in a large number of threads concurrently. + +#include +#include + +// We must define this macro in order to #include +// gtest-internal-inl.h. This is how Google Test prevents a user from +// accidentally depending on its internal implementation. +#define GTEST_IMPLEMENTATION +#include "src/gtest-internal-inl.h" +#undef GTEST_IMPLEMENTATION + +namespace testing { +namespace { + +using internal::List; +using internal::ListNode; +using internal::String; +using internal::TestProperty; +using internal::TestPropertyKeyIs; + +// How many threads to create? +const int kThreadCount = 50; + +String IdToKey(int id, const char* suffix) { + Message key; + key << "key_" << id << "_" << suffix; + return key.GetString(); +} + +String IdToString(int id) { + Message id_message; + id_message << id; + return id_message.GetString(); +} + +void ExpectKeyAndValueWereRecordedForId(const List& properties, + int id, + const char* suffix) { + TestPropertyKeyIs matches_key(IdToKey(id, suffix).c_str()); + const ListNode* node = properties.FindIf(matches_key); + EXPECT_TRUE(node != NULL) << "expecting " << suffix << " node for id " << id; + EXPECT_STREQ(IdToString(id).c_str(), node->element().value()); +} + +// Calls a large number of Google Test assertions, where exactly one of them +// will fail. +void ManyAsserts(int id) { + ::std::cout << "Thread #" << id << " running...\n"; + + SCOPED_TRACE(Message() << "Thread #" << id); + + for (int i = 0; i < kThreadCount; i++) { + SCOPED_TRACE(Message() << "Iteration #" << i); + + // A bunch of assertions that should succeed. + EXPECT_TRUE(true); + ASSERT_FALSE(false) << "This shouldn't fail."; + EXPECT_STREQ("a", "a"); + ASSERT_LE(5, 6); + EXPECT_EQ(i, i) << "This shouldn't fail."; + + // RecordProperty() should interact safely with other threads as well. + // The shared_key forces property updates. + Test::RecordProperty(IdToKey(id, "string").c_str(), IdToString(id).c_str()); + Test::RecordProperty(IdToKey(id, "int").c_str(), id); + Test::RecordProperty("shared_key", IdToString(id).c_str()); + + // This assertion should fail kThreadCount times per thread. It + // is for testing whether Google Test can handle failed assertions in a + // multi-threaded context. + EXPECT_LT(i, 0) << "This should always fail."; + } +} + +// Tests using SCOPED_TRACE() and Google Test assertions in many threads +// concurrently. +TEST(StressTest, CanUseScopedTraceAndAssertionsInManyThreads) { + // TODO(wan): when Google Test is made thread-safe, run + // ManyAsserts() in many threads here. +} + +} // namespace +} // namespace testing + +int main(int argc, char **argv) { + testing::InitGoogleTest(&argc, argv); + + return RUN_ALL_TESTS(); +} diff --git a/test/gtest_test_utils.py b/test/gtest_test_utils.py new file mode 100755 index 00000000..6c158871 --- /dev/null +++ b/test/gtest_test_utils.py @@ -0,0 +1,106 @@ +#!/usr/bin/env python +# +# Copyright 2006, 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. + +"""Unit test utilities for Google C++ Testing Framework.""" + +__author__ = 'wan@google.com (Zhanyong Wan)' + +import os +import sys +import unittest + + +# Initially maps a flag to its default value. After +# _ParseAndStripGTestFlags() is called, maps a flag to its actual +# value. +_flag_map = {'gtest_source_dir': os.path.dirname(sys.argv[0]), + 'gtest_build_dir': os.path.dirname(sys.argv[0])} +_gtest_flags_are_parsed = False + + +def _ParseAndStripGTestFlags(argv): + """Parses and strips Google Test flags from argv. This is idempotent.""" + + global _gtest_flags_are_parsed + if _gtest_flags_are_parsed: + return + + _gtest_flags_are_parsed = True + for flag in _flag_map: + # The environment variable overrides the default value. + if flag.upper() in os.environ: + _flag_map[flag] = os.environ[flag.upper()] + + # The command line flag overrides the environment variable. + i = 1 # Skips the program name. + while i < len(argv): + prefix = '--' + flag + '=' + if argv[i].startswith(prefix): + _flag_map[flag] = argv[i][len(prefix):] + del argv[i] + break + else: + # We don't increment i in case we just found a --gtest_* flag + # and removed it from argv. + i += 1 + + +def GetFlag(flag): + """Returns the value of the given flag.""" + + # In case GetFlag() is called before Main(), we always call + # _ParseAndStripGTestFlags() here to make sure the --gtest_* flags + # are parsed. + _ParseAndStripGTestFlags(sys.argv) + + return _flag_map[flag] + + +def GetSourceDir(): + """Returns the absolute path of the directory where the .py files are.""" + + return os.path.abspath(GetFlag('gtest_source_dir')) + + +def GetBuildDir(): + """Returns the absolute path of the directory where the test binaries are.""" + + return os.path.abspath(GetFlag('gtest_build_dir')) + + +def Main(): + """Runs the unit test.""" + + # We must call _ParseAndStripGTestFlags() before calling + # unittest.main(). Otherwise the latter will be confused by the + # --gtest_* flags. + _ParseAndStripGTestFlags(sys.argv) + unittest.main() diff --git a/test/gtest_uninitialized_test.py b/test/gtest_uninitialized_test.py new file mode 100755 index 00000000..1956a7b9 --- /dev/null +++ b/test/gtest_uninitialized_test.py @@ -0,0 +1,110 @@ +#!/usr/bin/env python +# +# Copyright 2008, 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. + +"""Verifies that Google Test warns the user when not initialized properly.""" + +__author__ = 'wan@google.com (Zhanyong Wan)' + +import gtest_test_utils +import os +import sys +import unittest + +IS_WINDOWS = os.name == 'nt' +IS_LINUX = os.name == 'posix' + +if IS_WINDOWS: + BUILD_DIRS = [ + 'build.dbg\\', + 'build.opt\\', + 'build.dbg8\\', + 'build.opt8\\', + ] + COMMAND = 'gtest_uninitialized_test_.exe' + +if IS_LINUX: + COMMAND = os.path.join(gtest_test_utils.GetBuildDir(), + 'gtest_uninitialized_test_') + + +def Assert(condition): + if not condition: + raise AssertionError + + +def AssertEq(expected, actual): + if expected != actual: + print 'Expected: %s' % (expected,) + print ' Actual: %s' % (actual,) + raise AssertionError + + +def GetOutput(command): + """Runs the given command and returns its output.""" + + stdin, stdout = os.popen2(command, 't') + stdin.close() + output = stdout.read() + stdout.close() + return output + + +def TestExitCodeAndOutput(command): + """Runs the given command and verifies its exit code and output.""" + + # 256 corresponds to return code 0. + AssertEq(256, os.system(command)) + output = GetOutput(command) + Assert('InitGoogleTest' in output) + + +if IS_WINDOWS: + + def main(): + for build_dir in BUILD_DIRS: + command = build_dir + COMMAND + print 'Testing with %s . . .' % (command,) + TestExitCodeAndOutput(command) + return 0 + + if __name__ == '__main__': + main() + + +if IS_LINUX: + + class GTestUninitializedTest(unittest.TestCase): + def testExitCodeAndOutput(self): + TestExitCodeAndOutput(COMMAND) + + + if __name__ == '__main__': + gtest_test_utils.Main() diff --git a/test/gtest_uninitialized_test_.cc b/test/gtest_uninitialized_test_.cc new file mode 100644 index 00000000..e8b2aa81 --- /dev/null +++ b/test/gtest_uninitialized_test_.cc @@ -0,0 +1,43 @@ +// Copyright 2008, 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) + +#include + +TEST(DummyTest, Dummy) { + // This test doesn't verify anything. We just need it to create a + // realistic stage for testing the behavior of Google Test when + // RUN_ALL_TESTS() is called without testing::InitGoogleTest() being + // called first. +} + +int main() { + return RUN_ALL_TESTS(); +} diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc new file mode 100644 index 00000000..9a64a13e --- /dev/null +++ b/test/gtest_unittest.cc @@ -0,0 +1,4299 @@ +// 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) +// +// Tests for Google Test itself. This verifies that the basic constructs of +// Google Test work. + +#include +#include + +// Indicates that this translation unit is part of Google Test's +// implementation. It must come before gtest-internal-inl.h is +// included, or there will be a compiler error. This trick is to +// prevent a user from accidentally including gtest-internal-inl.h in +// his code. +#define GTEST_IMPLEMENTATION +#include "src/gtest-internal-inl.h" +#undef GTEST_IMPLEMENTATION + +#include + +#ifdef GTEST_OS_LINUX +#include +#include +#include +#include +#include +#include +#include +#endif // GTEST_OS_LINUX + +namespace testing { +namespace internal { +bool ParseInt32Flag(const char* str, const char* flag, Int32* value); +} // namespace internal +} // namespace testing + +using testing::internal::ParseInt32Flag; + +namespace testing { + +GTEST_DECLARE_string(output); +GTEST_DECLARE_string(color); + +namespace internal { +bool ShouldUseColor(bool stdout_is_tty); +} // namespace internal +} // namespace testing + +using testing::GTEST_FLAG(color); +using testing::ScopedFakeTestPartResultReporter; +using testing::TestPartResult; +using testing::TestPartResultArray; +using testing::UnitTest; +using testing::internal::AppendUserMessage; +using testing::internal::EqFailure; +using testing::internal::Int32; +using testing::internal::List; +using testing::internal::OsStackTraceGetter; +using testing::internal::OsStackTraceGetterInterface; +using testing::internal::ShouldUseColor; +using testing::internal::StreamableToString; +using testing::internal::String; +using testing::internal::TestProperty; +using testing::internal::TestResult; +using testing::internal::ToUtf8String; +using testing::internal::UnitTestImpl; +using testing::internal::UnitTestOptions; + +// This line tests that we can define tests in an unnamed namespace. +namespace { + +#ifndef __SYMBIAN32__ +// NULL testing does not work with Symbian compilers. + +// Tests that GTEST_IS_NULL_LITERAL(x) is true when x is a null +// pointer literal. +TEST(NullLiteralTest, IsTrueForNullLiterals) { + EXPECT_TRUE(GTEST_IS_NULL_LITERAL(NULL)); + EXPECT_TRUE(GTEST_IS_NULL_LITERAL(0)); + EXPECT_TRUE(GTEST_IS_NULL_LITERAL(1 - 1)); + EXPECT_TRUE(GTEST_IS_NULL_LITERAL(0U)); + EXPECT_TRUE(GTEST_IS_NULL_LITERAL(0L)); + EXPECT_TRUE(GTEST_IS_NULL_LITERAL(false)); + EXPECT_TRUE(GTEST_IS_NULL_LITERAL(true && false)); +} + +// Tests that GTEST_IS_NULL_LITERAL(x) is false when x is not a null +// pointer literal. +TEST(NullLiteralTest, IsFalseForNonNullLiterals) { + EXPECT_FALSE(GTEST_IS_NULL_LITERAL(1)); + EXPECT_FALSE(GTEST_IS_NULL_LITERAL(0.0)); + EXPECT_FALSE(GTEST_IS_NULL_LITERAL('a')); + EXPECT_FALSE(GTEST_IS_NULL_LITERAL(static_cast(NULL))); +} + +#endif // __SYMBIAN32__ +// Tests ToUtf8String(). + +// Tests that the NUL character L'\0' is encoded correctly. +TEST(ToUtf8StringTest, CanEncodeNul) { + EXPECT_STREQ("", ToUtf8String(L'\0').c_str()); +} + +// Tests that ASCII characters are encoded correctly. +TEST(ToUtf8StringTest, CanEncodeAscii) { + EXPECT_STREQ("a", ToUtf8String(L'a').c_str()); + EXPECT_STREQ("Z", ToUtf8String(L'Z').c_str()); + EXPECT_STREQ("&", ToUtf8String(L'&').c_str()); + EXPECT_STREQ("\x7F", ToUtf8String(L'\x7F').c_str()); +} + +// Tests that Unicode code-points that have 8 to 11 bits are encoded +// as 110xxxxx 10xxxxxx. +TEST(ToUtf8StringTest, CanEncode8To11Bits) { + // 000 1101 0011 => 110-00011 10-010011 + EXPECT_STREQ("\xC3\x93", ToUtf8String(L'\xD3').c_str()); + + // 101 0111 0110 => 110-10101 10-110110 + EXPECT_STREQ("\xD5\xB6", ToUtf8String(L'\x576').c_str()); +} + +// Tests that Unicode code-points that have 12 to 16 bits are encoded +// as 1110xxxx 10xxxxxx 10xxxxxx. +TEST(ToUtf8StringTest, CanEncode12To16Bits) { + // 0000 1000 1101 0011 => 1110-0000 10-100011 10-010011 + EXPECT_STREQ("\xE0\xA3\x93", ToUtf8String(L'\x8D3').c_str()); + + // 1100 0111 0100 1101 => 1110-1100 10-011101 10-001101 + EXPECT_STREQ("\xEC\x9D\x8D", ToUtf8String(L'\xC74D').c_str()); +} + +#if !defined(GTEST_OS_WINDOWS) && !defined(__SYMBIAN32__) + +// Tests in this group require a wchar_t to hold > 16 bits, and thus +// are skipped on Windows and Symbian, where a wchar_t is 16-bit wide. + +// Tests that Unicode code-points that have 17 to 21 bits are encoded +// as 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx. +TEST(ToUtf8StringTest, CanEncode17To21Bits) { + // 0 0001 0000 1000 1101 0011 => 11110-000 10-010000 10-100011 10-010011 + EXPECT_STREQ("\xF0\x90\xA3\x93", ToUtf8String(L'\x108D3').c_str()); + + // 1 0111 1000 0110 0011 0100 => 11110-101 10-111000 10-011000 10-110100 + EXPECT_STREQ("\xF5\xB8\x98\xB4", ToUtf8String(L'\x178634').c_str()); +} + +// Tests that encoding an invalid code-point generates the expected result. +TEST(ToUtf8StringTest, CanEncodeInvalidCodePoint) { + EXPECT_STREQ("(Invalid Unicode 0x1234ABCD)", + ToUtf8String(L'\x1234ABCD').c_str()); +} + +#endif // Windows or Symbian + +// Tests the List template class. + +// Tests List::PushFront(). +TEST(ListTest, PushFront) { + List a; + ASSERT_EQ(0u, a.size()); + + // Calls PushFront() on an empty list. + a.PushFront(1); + ASSERT_EQ(1u, a.size()); + EXPECT_EQ(1, a.Head()->element()); + ASSERT_EQ(a.Head(), a.Last()); + + // Calls PushFront() on a singleton list. + a.PushFront(2); + ASSERT_EQ(2u, a.size()); + EXPECT_EQ(2, a.Head()->element()); + EXPECT_EQ(1, a.Last()->element()); + + // Calls PushFront() on a list with more than one elements. + a.PushFront(3); + ASSERT_EQ(3u, a.size()); + EXPECT_EQ(3, a.Head()->element()); + EXPECT_EQ(2, a.Head()->next()->element()); + EXPECT_EQ(1, a.Last()->element()); +} + +// Tests List::PopFront(). +TEST(ListTest, PopFront) { + List a; + + // Popping on an empty list should fail. + EXPECT_FALSE(a.PopFront(NULL)); + + // Popping again on an empty list should fail, and the result element + // shouldn't be overwritten. + int element = 1; + EXPECT_FALSE(a.PopFront(&element)); + EXPECT_EQ(1, element); + + a.PushFront(2); + a.PushFront(3); + + // PopFront() should pop the element in the front of the list. + EXPECT_TRUE(a.PopFront(&element)); + EXPECT_EQ(3, element); + + // After popping the last element, the list should be empty. + EXPECT_TRUE(a.PopFront(NULL)); + EXPECT_EQ(0u, a.size()); +} + +// Tests inserting at the beginning using List::InsertAfter(). +TEST(ListTest, InsertAfterAtBeginning) { + List a; + ASSERT_EQ(0u, a.size()); + + // Inserts into an empty list. + a.InsertAfter(NULL, 1); + ASSERT_EQ(1u, a.size()); + EXPECT_EQ(1, a.Head()->element()); + ASSERT_EQ(a.Head(), a.Last()); + + // Inserts at the beginning of a singleton list. + a.InsertAfter(NULL, 2); + ASSERT_EQ(2u, a.size()); + EXPECT_EQ(2, a.Head()->element()); + EXPECT_EQ(1, a.Last()->element()); + + // Inserts at the beginning of a list with more than one elements. + a.InsertAfter(NULL, 3); + ASSERT_EQ(3u, a.size()); + EXPECT_EQ(3, a.Head()->element()); + EXPECT_EQ(2, a.Head()->next()->element()); + EXPECT_EQ(1, a.Last()->element()); +} + +// Tests inserting at a location other than the beginning using +// List::InsertAfter(). +TEST(ListTest, InsertAfterNotAtBeginning) { + // Prepares a singleton list. + List a; + a.PushBack(1); + + // Inserts at the end of a singleton list. + a.InsertAfter(a.Last(), 2); + ASSERT_EQ(2u, a.size()); + EXPECT_EQ(1, a.Head()->element()); + EXPECT_EQ(2, a.Last()->element()); + + // Inserts at the end of a list with more than one elements. + a.InsertAfter(a.Last(), 3); + ASSERT_EQ(3u, a.size()); + EXPECT_EQ(1, a.Head()->element()); + EXPECT_EQ(2, a.Head()->next()->element()); + EXPECT_EQ(3, a.Last()->element()); + + // Inserts in the middle of a list. + a.InsertAfter(a.Head(), 4); + ASSERT_EQ(4u, a.size()); + EXPECT_EQ(1, a.Head()->element()); + EXPECT_EQ(4, a.Head()->next()->element()); + EXPECT_EQ(2, a.Head()->next()->next()->element()); + EXPECT_EQ(3, a.Last()->element()); +} + + +// Tests the String class. + +// Tests String's constructors. +TEST(StringTest, Constructors) { + // Default ctor. + String s1; + EXPECT_EQ(NULL, s1.c_str()); + + // Implicitly constructs from a C-string. + String s2 = "Hi"; + EXPECT_STREQ("Hi", s2.c_str()); + + // Constructs from a C-string and a length. + String s3("hello", 3); + EXPECT_STREQ("hel", s3.c_str()); + + // Copy ctor. + String s4 = s3; + EXPECT_STREQ("hel", s4.c_str()); +} + +// Tests String::ShowCString(). +TEST(StringTest, ShowCString) { + EXPECT_STREQ("(null)", String::ShowCString(NULL)); + EXPECT_STREQ("", String::ShowCString("")); + EXPECT_STREQ("foo", String::ShowCString("foo")); +} + +// Tests String::ShowCStringQuoted(). +TEST(StringTest, ShowCStringQuoted) { + EXPECT_STREQ("(null)", + String::ShowCStringQuoted(NULL).c_str()); + EXPECT_STREQ("\"\"", + String::ShowCStringQuoted("").c_str()); + EXPECT_STREQ("\"foo\"", + String::ShowCStringQuoted("foo").c_str()); +} + +// Tests String::operator==(). +TEST(StringTest, Equals) { + const String null(NULL); + EXPECT_TRUE(null == NULL); // NOLINT + EXPECT_FALSE(null == ""); // NOLINT + EXPECT_FALSE(null == "bar"); // NOLINT + + const String empty(""); + EXPECT_FALSE(empty == NULL); // NOLINT + EXPECT_TRUE(empty == ""); // NOLINT + EXPECT_FALSE(empty == "bar"); // NOLINT + + const String foo("foo"); + EXPECT_FALSE(foo == NULL); // NOLINT + EXPECT_FALSE(foo == ""); // NOLINT + EXPECT_FALSE(foo == "bar"); // NOLINT + EXPECT_TRUE(foo == "foo"); // NOLINT +} + +// Tests String::operator!=(). +TEST(StringTest, NotEquals) { + const String null(NULL); + EXPECT_FALSE(null != NULL); // NOLINT + EXPECT_TRUE(null != ""); // NOLINT + EXPECT_TRUE(null != "bar"); // NOLINT + + const String empty(""); + EXPECT_TRUE(empty != NULL); // NOLINT + EXPECT_FALSE(empty != ""); // NOLINT + EXPECT_TRUE(empty != "bar"); // NOLINT + + const String foo("foo"); + EXPECT_TRUE(foo != NULL); // NOLINT + EXPECT_TRUE(foo != ""); // NOLINT + EXPECT_TRUE(foo != "bar"); // NOLINT + EXPECT_FALSE(foo != "foo"); // NOLINT +} + +// Tests String::EndsWith(). +TEST(StringTest, EndsWith) { + EXPECT_TRUE(String("foobar").EndsWith("bar")); + EXPECT_TRUE(String("foobar").EndsWith("")); + EXPECT_TRUE(String("").EndsWith("")); + + EXPECT_FALSE(String("foobar").EndsWith("foo")); + EXPECT_FALSE(String("").EndsWith("foo")); +} + +// Tests String::EndsWithCaseInsensitive(). +TEST(StringTest, EndsWithCaseInsensitive) { + EXPECT_TRUE(String("foobar").EndsWithCaseInsensitive("BAR")); + EXPECT_TRUE(String("foobaR").EndsWithCaseInsensitive("bar")); + EXPECT_TRUE(String("foobar").EndsWithCaseInsensitive("")); + EXPECT_TRUE(String("").EndsWithCaseInsensitive("")); + + EXPECT_FALSE(String("Foobar").EndsWithCaseInsensitive("foo")); + EXPECT_FALSE(String("foobar").EndsWithCaseInsensitive("Foo")); + EXPECT_FALSE(String("").EndsWithCaseInsensitive("foo")); +} + +// Tests that NULL can be assigned to a String. +TEST(StringTest, CanBeAssignedNULL) { + const String src(NULL); + String dest; + + dest = src; + EXPECT_STREQ(NULL, dest.c_str()); +} + +// Tests that the empty string "" can be assigned to a String. +TEST(StringTest, CanBeAssignedEmpty) { + const String src(""); + String dest; + + dest = src; + EXPECT_STREQ("", dest.c_str()); +} + +// Tests that a non-empty string can be assigned to a String. +TEST(StringTest, CanBeAssignedNonEmpty) { + const String src("hello"); + String dest; + + dest = src; + EXPECT_STREQ("hello", dest.c_str()); +} + +// Tests that a String can be assigned to itself. +TEST(StringTest, CanBeAssignedSelf) { + String dest("hello"); + + dest = dest; + EXPECT_STREQ("hello", dest.c_str()); +} + +#ifdef GTEST_OS_WINDOWS + +// Tests String::ShowWideCString(). +TEST(StringTest, ShowWideCString) { + EXPECT_STREQ("(null)", + String::ShowWideCString(NULL).c_str()); + EXPECT_STREQ("", String::ShowWideCString(L"").c_str()); + EXPECT_STREQ("foo", String::ShowWideCString(L"foo").c_str()); +} + +// Tests String::ShowWideCStringQuoted(). +TEST(StringTest, ShowWideCStringQuoted) { + EXPECT_STREQ("(null)", + String::ShowWideCStringQuoted(NULL).c_str()); + EXPECT_STREQ("L\"\"", + String::ShowWideCStringQuoted(L"").c_str()); + EXPECT_STREQ("L\"foo\"", + String::ShowWideCStringQuoted(L"foo").c_str()); +} + +#endif // GTEST_OS_WINDOWS + +// Tests TestProperty construction. +TEST(TestPropertyTest, StringValue) { + TestProperty property("key", "1"); + EXPECT_STREQ("key", property.key()); + EXPECT_STREQ("1", property.value()); +} + +// Tests TestProperty replacing a value. +TEST(TestPropertyTest, ReplaceStringValue) { + TestProperty property("key", "1"); + EXPECT_STREQ("1", property.value()); + property.SetValue("2"); + EXPECT_STREQ("2", property.value()); +} + +// Tests the TestPartResult class. + +// The test fixture for testing TestPartResult. +class TestPartResultTest : public testing::Test { + protected: + TestPartResultTest() + : r1_(testing::TPRT_SUCCESS, + "foo/bar.cc", + 10, + "Success!"), + r2_(testing::TPRT_NONFATAL_FAILURE, + "foo/bar.cc", + -1, + "Failure!"), + r3_(testing::TPRT_FATAL_FAILURE, + NULL, + -1, + "Failure!") {} + + TestPartResult r1_, r2_, r3_; +}; + +// Tests TestPartResult::type() +TEST_F(TestPartResultTest, type) { + EXPECT_EQ(testing::TPRT_SUCCESS, r1_.type()); + EXPECT_EQ(testing::TPRT_NONFATAL_FAILURE, r2_.type()); + EXPECT_EQ(testing::TPRT_FATAL_FAILURE, r3_.type()); +} + +// Tests TestPartResult::file_name() +TEST_F(TestPartResultTest, file_name) { + EXPECT_STREQ("foo/bar.cc", r1_.file_name()); + EXPECT_STREQ(NULL, r3_.file_name()); +} + +// Tests TestPartResult::line_number() +TEST_F(TestPartResultTest, line_number) { + EXPECT_EQ(10, r1_.line_number()); + EXPECT_EQ(-1, r2_.line_number()); +} + +// Tests TestPartResult::message() +TEST_F(TestPartResultTest, message) { + EXPECT_STREQ("Success!", r1_.message()); +} + +// Tests TestPartResult::passed() +TEST_F(TestPartResultTest, Passed) { + EXPECT_TRUE(r1_.passed()); + EXPECT_FALSE(r2_.passed()); + EXPECT_FALSE(r3_.passed()); +} + +// Tests TestPartResult::failed() +TEST_F(TestPartResultTest, Failed) { + EXPECT_FALSE(r1_.failed()); + EXPECT_TRUE(r2_.failed()); + EXPECT_TRUE(r3_.failed()); +} + +// Tests TestPartResult::fatally_failed() +TEST_F(TestPartResultTest, FatallyFailed) { + EXPECT_FALSE(r1_.fatally_failed()); + EXPECT_FALSE(r2_.fatally_failed()); + EXPECT_TRUE(r3_.fatally_failed()); +} + +// Tests TestPartResult::nonfatally_failed() +TEST_F(TestPartResultTest, NonfatallyFailed) { + EXPECT_FALSE(r1_.nonfatally_failed()); + EXPECT_TRUE(r2_.nonfatally_failed()); + EXPECT_FALSE(r3_.nonfatally_failed()); +} + +// Tests the TestPartResultArray class. + +class TestPartResultArrayTest : public testing::Test { + protected: + TestPartResultArrayTest() + : r1_(testing::TPRT_NONFATAL_FAILURE, + "foo/bar.cc", + -1, + "Failure 1"), + r2_(testing::TPRT_FATAL_FAILURE, + "foo/bar.cc", + -1, + "Failure 2") {} + + const TestPartResult r1_, r2_; +}; + +// Tests that TestPartResultArray initially has size 0. +TEST_F(TestPartResultArrayTest, InitialSizeIsZero) { + TestPartResultArray results; + EXPECT_EQ(0, results.size()); +} + +// Tests that TestPartResultArray contains the given TestPartResult +// after one Append() operation. +TEST_F(TestPartResultArrayTest, ContainsGivenResultAfterAppend) { + TestPartResultArray results; + results.Append(r1_); + EXPECT_EQ(1, results.size()); + EXPECT_STREQ("Failure 1", results.GetTestPartResult(0).message()); +} + +// Tests that TestPartResultArray contains the given TestPartResults +// after two Append() operations. +TEST_F(TestPartResultArrayTest, ContainsGivenResultsAfterTwoAppends) { + TestPartResultArray results; + results.Append(r1_); + results.Append(r2_); + EXPECT_EQ(2, results.size()); + EXPECT_STREQ("Failure 1", results.GetTestPartResult(0).message()); + EXPECT_STREQ("Failure 2", results.GetTestPartResult(1).message()); +} + +void ScopedFakeTestPartResultReporterTestHelper() { + FAIL() << "Expected fatal failure."; +} + +// Tests that ScopedFakeTestPartResultReporter intercepts test +// failures. +TEST(ScopedFakeTestPartResultReporterTest, InterceptsTestFailures) { + TestPartResultArray results; + { + ScopedFakeTestPartResultReporter reporter(&results); + ADD_FAILURE() << "Expected non-fatal failure."; + ScopedFakeTestPartResultReporterTestHelper(); + } + + EXPECT_EQ(2, results.size()); + EXPECT_TRUE(results.GetTestPartResult(0).nonfatally_failed()); + EXPECT_TRUE(results.GetTestPartResult(1).fatally_failed()); +} + +// Tests the TestResult class + +// The test fixture for testing TestResult. +class TestResultTest : public testing::Test { + protected: + typedef List TPRList; + + // We make use of 2 TestPartResult objects, + TestPartResult * pr1, * pr2; + + // ... and 3 TestResult objects. + TestResult * r0, * r1, * r2; + + virtual void SetUp() { + // pr1 is for success. + pr1 = new TestPartResult(testing::TPRT_SUCCESS, + "foo/bar.cc", + 10, + "Success!"); + + // pr2 is for fatal failure. + pr2 = new TestPartResult(testing::TPRT_FATAL_FAILURE, + "foo/bar.cc", + -1, // This line number means "unknown" + "Failure!"); + + // Creates the TestResult objects. + r0 = new TestResult(); + r1 = new TestResult(); + r2 = new TestResult(); + + // In order to test TestResult, we need to modify its internal + // state, in particular the TestPartResult list it holds. + // test_part_results() returns a const reference to this list. + // We cast it to a non-const object s.t. it can be modified (yes, + // this is a hack). + TPRList * list1, * list2; + list1 = const_cast *>( + & r1->test_part_results()); + list2 = const_cast *>( + & r2->test_part_results()); + + // r0 is an empty TestResult. + + // r1 contains a single SUCCESS TestPartResult. + list1->PushBack(*pr1); + + // r2 contains a SUCCESS, and a FAILURE. + list2->PushBack(*pr1); + list2->PushBack(*pr2); + } + + virtual void TearDown() { + delete pr1; + delete pr2; + + delete r0; + delete r1; + delete r2; + } +}; + +// Tests TestResult::test_part_results() +TEST_F(TestResultTest, test_part_results) { + ASSERT_EQ(0u, r0->test_part_results().size()); + ASSERT_EQ(1u, r1->test_part_results().size()); + ASSERT_EQ(2u, r2->test_part_results().size()); +} + +// Tests TestResult::successful_part_count() +TEST_F(TestResultTest, successful_part_count) { + ASSERT_EQ(0u, r0->successful_part_count()); + ASSERT_EQ(1u, r1->successful_part_count()); + ASSERT_EQ(1u, r2->successful_part_count()); +} + +// Tests TestResult::failed_part_count() +TEST_F(TestResultTest, failed_part_count) { + ASSERT_EQ(0u, r0->failed_part_count()); + ASSERT_EQ(0u, r1->failed_part_count()); + ASSERT_EQ(1u, r2->failed_part_count()); +} + +// Tests TestResult::total_part_count() +TEST_F(TestResultTest, total_part_count) { + ASSERT_EQ(0u, r0->total_part_count()); + ASSERT_EQ(1u, r1->total_part_count()); + ASSERT_EQ(2u, r2->total_part_count()); +} + +// Tests TestResult::Passed() +TEST_F(TestResultTest, Passed) { + ASSERT_TRUE(r0->Passed()); + ASSERT_TRUE(r1->Passed()); + ASSERT_FALSE(r2->Passed()); +} + +// Tests TestResult::Failed() +TEST_F(TestResultTest, Failed) { + ASSERT_FALSE(r0->Failed()); + ASSERT_FALSE(r1->Failed()); + ASSERT_TRUE(r2->Failed()); +} + +// Tests TestResult::test_properties() has no properties when none are added. +TEST(TestResultPropertyTest, NoPropertiesFoundWhenNoneAreAdded) { + TestResult test_result; + ASSERT_EQ(0u, test_result.test_properties().size()); +} + +// Tests TestResult::test_properties() has the expected property when added. +TEST(TestResultPropertyTest, OnePropertyFoundWhenAdded) { + TestResult test_result; + TestProperty property("key_1", "1"); + test_result.RecordProperty(property); + const List& properties = test_result.test_properties(); + ASSERT_EQ(1u, properties.size()); + TestProperty actual_property = properties.Head()->element(); + EXPECT_STREQ("key_1", actual_property.key()); + EXPECT_STREQ("1", actual_property.value()); +} + +// Tests TestResult::test_properties() has multiple properties when added. +TEST(TestResultPropertyTest, MultiplePropertiesFoundWhenAdded) { + TestResult test_result; + TestProperty property_1("key_1", "1"); + TestProperty property_2("key_2", "2"); + test_result.RecordProperty(property_1); + test_result.RecordProperty(property_2); + const List& properties = test_result.test_properties(); + ASSERT_EQ(2u, properties.size()); + TestProperty actual_property_1 = properties.Head()->element(); + EXPECT_STREQ("key_1", actual_property_1.key()); + EXPECT_STREQ("1", actual_property_1.value()); + + TestProperty actual_property_2 = properties.Last()->element(); + EXPECT_STREQ("key_2", actual_property_2.key()); + EXPECT_STREQ("2", actual_property_2.value()); +} + +// Tests TestResult::test_properties() overrides values for duplicate keys. +TEST(TestResultPropertyTest, OverridesValuesForDuplicateKeys) { + TestResult test_result; + TestProperty property_1_1("key_1", "1"); + TestProperty property_2_1("key_2", "2"); + TestProperty property_1_2("key_1", "12"); + TestProperty property_2_2("key_2", "22"); + test_result.RecordProperty(property_1_1); + test_result.RecordProperty(property_2_1); + test_result.RecordProperty(property_1_2); + test_result.RecordProperty(property_2_2); + + const List& properties = test_result.test_properties(); + ASSERT_EQ(2u, properties.size()); + TestProperty actual_property_1 = properties.Head()->element(); + EXPECT_STREQ("key_1", actual_property_1.key()); + EXPECT_STREQ("12", actual_property_1.value()); + + TestProperty actual_property_2 = properties.Last()->element(); + EXPECT_STREQ("key_2", actual_property_2.key()); + EXPECT_STREQ("22", actual_property_2.value()); +} + +// When a property using a reserved key is supplied to this function, it tests +// that a non-fatal failure is added, a fatal failure is not added, and that the +// property is not recorded. +void ExpectNonFatalFailureRecordingPropertyWithReservedKey(const char* key) { + TestResult test_result; + TestProperty property("name", "1"); + EXPECT_NONFATAL_FAILURE(test_result.RecordProperty(property), "Reserved key"); + ASSERT_TRUE(test_result.test_properties().IsEmpty()) << "Not recorded"; +} + +// Attempting to recording a property with the Reserved literal "name" +// should add a non-fatal failure and the property should not be recorded. +TEST(TestResultPropertyTest, AddFailureWhenUsingReservedKeyCalledName) { + ExpectNonFatalFailureRecordingPropertyWithReservedKey("name"); +} + +// Attempting to recording a property with the Reserved literal "status" +// should add a non-fatal failure and the property should not be recorded. +TEST(TestResultPropertyTest, AddFailureWhenUsingReservedKeyCalledStatus) { + ExpectNonFatalFailureRecordingPropertyWithReservedKey("status"); +} + +// Attempting to recording a property with the Reserved literal "time" +// should add a non-fatal failure and the property should not be recorded. +TEST(TestResultPropertyTest, AddFailureWhenUsingReservedKeyCalledTime) { + ExpectNonFatalFailureRecordingPropertyWithReservedKey("time"); +} + +// Attempting to recording a property with the Reserved literal "classname" +// should add a non-fatal failure and the property should not be recorded. +TEST(TestResultPropertyTest, AddFailureWhenUsingReservedKeyCalledClassname) { + ExpectNonFatalFailureRecordingPropertyWithReservedKey("classname"); +} + +// Tests that GTestFlagSaver works on Windows and Mac. + +class GTestFlagSaverTest : public testing::Test { + protected: + // Saves the Google Test flags such that we can restore them later, and + // then sets them to their default values. This will be called + // before the first test in this test case is run. + static void SetUpTestCase() { + saver_ = new testing::internal::GTestFlagSaver; + + testing::GTEST_FLAG(break_on_failure) = false; + testing::GTEST_FLAG(catch_exceptions) = false; + testing::GTEST_FLAG(color) = "auto"; + testing::GTEST_FLAG(filter) = ""; + testing::GTEST_FLAG(list_tests) = false; + testing::GTEST_FLAG(output) = ""; + testing::GTEST_FLAG(repeat) = 1; + } + + // Restores the Google Test flags that the tests have modified. This will + // be called after the last test in this test case is run. + static void TearDownTestCase() { + delete saver_; + saver_ = NULL; + } + + // Verifies that the Google Test flags have their default values, and then + // modifies each of them. + void VerifyAndModifyFlags() { + EXPECT_FALSE(testing::GTEST_FLAG(break_on_failure)); + EXPECT_FALSE(testing::GTEST_FLAG(catch_exceptions)); + EXPECT_STREQ("auto", testing::GTEST_FLAG(color).c_str()); + EXPECT_STREQ("", testing::GTEST_FLAG(filter).c_str()); + EXPECT_FALSE(testing::GTEST_FLAG(list_tests)); + EXPECT_STREQ("", testing::GTEST_FLAG(output).c_str()); + EXPECT_EQ(1, testing::GTEST_FLAG(repeat)); + + testing::GTEST_FLAG(break_on_failure) = true; + testing::GTEST_FLAG(catch_exceptions) = true; + testing::GTEST_FLAG(color) = "no"; + testing::GTEST_FLAG(filter) = "abc"; + testing::GTEST_FLAG(list_tests) = true; + testing::GTEST_FLAG(output) = "xml:foo.xml"; + testing::GTEST_FLAG(repeat) = 100; + } + private: + // For saving Google Test flags during this test case. + static testing::internal::GTestFlagSaver* saver_; +}; + +testing::internal::GTestFlagSaver* GTestFlagSaverTest::saver_ = NULL; + +// Google Test doesn't guarantee the order of tests. The following two +// tests are designed to work regardless of their order. + +// Modifies the Google Test flags in the test body. +TEST_F(GTestFlagSaverTest, ModifyGTestFlags) { + VerifyAndModifyFlags(); +} + +// Verifies that the Google Test flags in the body of the previous test were +// restored to their original values. +TEST_F(GTestFlagSaverTest, VerifyGTestFlags) { + VerifyAndModifyFlags(); +} + +// Sets an environment variable with the given name to the given +// value. If the value argument is "", unsets the environment +// variable. The caller must ensure that both arguments are not NULL. +static void SetEnv(const char* name, const char* value) { +#ifdef _WIN32_WCE + // Environment variables are not supported on Windows CE. + return; +#elif defined(GTEST_OS_WINDOWS) // If we are on Windows proper. + _putenv((testing::Message() << name << "=" << value).GetString().c_str()); +#else + if (*value == '\0') { + unsetenv(name); + } else { + setenv(name, value, 1); + } +#endif +} + +#ifndef _WIN32_WCE +// Environment variables are not supported on Windows CE. + +using ::testing::internal::Int32FromGTestEnv; + +// Tests Int32FromGTestEnv(). + +// Tests that Int32FromGTestEnv() returns the default value when the +// environment variable is not set. +TEST(Int32FromGTestEnvTest, ReturnsDefaultWhenVariableIsNotSet) { + SetEnv(GTEST_FLAG_PREFIX_UPPER "TEMP", ""); + EXPECT_EQ(10, Int32FromGTestEnv("temp", 10)); +} + +// Tests that Int32FromGTestEnv() returns the default value when the +// environment variable overflows as an Int32. +TEST(Int32FromGTestEnvTest, ReturnsDefaultWhenValueOverflows) { + printf("(expecting 2 warnings)\n"); + + SetEnv(GTEST_FLAG_PREFIX_UPPER "TEMP", "12345678987654321"); + EXPECT_EQ(20, Int32FromGTestEnv("temp", 20)); + + SetEnv(GTEST_FLAG_PREFIX_UPPER "TEMP", "-12345678987654321"); + EXPECT_EQ(30, Int32FromGTestEnv("temp", 30)); +} + +// Tests that Int32FromGTestEnv() returns the default value when the +// environment variable does not represent a valid decimal integer. +TEST(Int32FromGTestEnvTest, ReturnsDefaultWhenValueIsInvalid) { + printf("(expecting 2 warnings)\n"); + + SetEnv(GTEST_FLAG_PREFIX_UPPER "TEMP", "A1"); + EXPECT_EQ(40, Int32FromGTestEnv("temp", 40)); + + SetEnv(GTEST_FLAG_PREFIX_UPPER "TEMP", "12X"); + EXPECT_EQ(50, Int32FromGTestEnv("temp", 50)); +} + +// Tests that Int32FromGTestEnv() parses and returns the value of the +// environment variable when it represents a valid decimal integer in +// the range of an Int32. +TEST(Int32FromGTestEnvTest, ParsesAndReturnsValidValue) { + SetEnv(GTEST_FLAG_PREFIX_UPPER "TEMP", "123"); + EXPECT_EQ(123, Int32FromGTestEnv("temp", 0)); + + SetEnv(GTEST_FLAG_PREFIX_UPPER "TEMP", "-321"); + EXPECT_EQ(-321, Int32FromGTestEnv("temp", 0)); +} +#endif // !defined(_WIN32_WCE) + +// Tests ParseInt32Flag(). + +// Tests that ParseInt32Flag() returns false and doesn't change the +// output value when the flag has wrong format +TEST(ParseInt32FlagTest, ReturnsFalseForInvalidFlag) { + Int32 value = 123; + EXPECT_FALSE(ParseInt32Flag("--a=100", "b", &value)); + EXPECT_EQ(123, value); + + EXPECT_FALSE(ParseInt32Flag("a=100", "a", &value)); + EXPECT_EQ(123, value); +} + +// Tests that ParseInt32Flag() returns false and doesn't change the +// output value when the flag overflows as an Int32. +TEST(ParseInt32FlagTest, ReturnsDefaultWhenValueOverflows) { + printf("(expecting 2 warnings)\n"); + + Int32 value = 123; + EXPECT_FALSE(ParseInt32Flag("--abc=12345678987654321", "abc", &value)); + EXPECT_EQ(123, value); + + EXPECT_FALSE(ParseInt32Flag("--abc=-12345678987654321", "abc", &value)); + EXPECT_EQ(123, value); +} + +// Tests that ParseInt32Flag() returns false and doesn't change the +// output value when the flag does not represent a valid decimal +// integer. +TEST(ParseInt32FlagTest, ReturnsDefaultWhenValueIsInvalid) { + printf("(expecting 2 warnings)\n"); + + Int32 value = 123; + EXPECT_FALSE(ParseInt32Flag("--abc=A1", "abc", &value)); + EXPECT_EQ(123, value); + + EXPECT_FALSE(ParseInt32Flag("--abc=12X", "abc", &value)); + EXPECT_EQ(123, value); +} + +// Tests that ParseInt32Flag() parses the value of the flag and +// returns true when the flag represents a valid decimal integer in +// the range of an Int32. +TEST(ParseInt32FlagTest, ParsesAndReturnsValidValue) { + Int32 value = 123; + EXPECT_TRUE(ParseInt32Flag("--" GTEST_FLAG_PREFIX "abc=456", "abc", &value)); + EXPECT_EQ(456, value); + + EXPECT_TRUE(ParseInt32Flag("--" GTEST_FLAG_PREFIX "abc=-789", "abc", &value)); + EXPECT_EQ(-789, value); +} + +// For the same reason we are not explicitly testing everything in the +// Test class, there are no separate tests for the following classes: +// +// TestCase, UnitTest, UnitTestResultPrinter. +// +// Similarly, there are no separate tests for the following macros: +// +// TEST, TEST_F, RUN_ALL_TESTS + +// This group of tests is for predicate assertions (ASSERT_PRED*, etc) +// of various arities. They do not attempt to be exhaustive. Rather, +// view them as smoke tests that can be easily reviewed and verified. +// A more complete set of tests for predicate assertions can be found +// in gtest_pred_impl_unittest.cc. + +// First, some predicates and predicate-formatters needed by the tests. + +// Returns true iff the argument is an even number. +bool IsEven(int n) { + return (n % 2) == 0; +} + +// A functor that returns true iff the argument is an even number. +struct IsEvenFunctor { + bool operator()(int n) { return IsEven(n); } +}; + +// A predicate-formatter function that asserts the argument is an even +// number. +testing::AssertionResult AssertIsEven(const char* expr, int n) { + if (IsEven(n)) { + return testing::AssertionSuccess(); + } + + testing::Message msg; + msg << expr << " evaluates to " << n << ", which is not even."; + return testing::AssertionFailure(msg); +} + +// A predicate-formatter functor that asserts the argument is an even +// number. +struct AssertIsEvenFunctor { + testing::AssertionResult operator()(const char* expr, int n) { + return AssertIsEven(expr, n); + } +}; + +// Returns true iff the sum of the arguments is an even number. +bool SumIsEven2(int n1, int n2) { + return IsEven(n1 + n2); +} + +// A functor that returns true iff the sum of the arguments is an even +// number. +struct SumIsEven3Functor { + bool operator()(int n1, int n2, int n3) { + return IsEven(n1 + n2 + n3); + } +}; + +// A predicate-formatter function that asserts the sum of the +// arguments is an even number. +testing::AssertionResult AssertSumIsEven4(const char* e1, + const char* e2, + const char* e3, + const char* e4, + int n1, + int n2, + int n3, + int n4) { + const int sum = n1 + n2 + n3 + n4; + if (IsEven(sum)) { + return testing::AssertionSuccess(); + } + + testing::Message msg; + msg << e1 << " + " << e2 << " + " << e3 << " + " << e4 + << " (" << n1 << " + " << n2 << " + " << n3 << " + " << n4 + << ") evaluates to " << sum << ", which is not even."; + return testing::AssertionFailure(msg); +} + +// A predicate-formatter functor that asserts the sum of the arguments +// is an even number. +struct AssertSumIsEven5Functor { + testing::AssertionResult operator()(const char* e1, + const char* e2, + const char* e3, + const char* e4, + const char* e5, + int n1, + int n2, + int n3, + int n4, + int n5) { + const int sum = n1 + n2 + n3 + n4 + n5; + if (IsEven(sum)) { + return testing::AssertionSuccess(); + } + + testing::Message msg; + msg << e1 << " + " << e2 << " + " << e3 << " + " << e4 << " + " << e5 + << " (" + << n1 << " + " << n2 << " + " << n3 << " + " << n4 << " + " << n5 + << ") evaluates to " << sum << ", which is not even."; + return testing::AssertionFailure(msg); + } +}; + + +// Tests unary predicate assertions. + +// Tests unary predicate assertions that don't use a custom formatter. +TEST(Pred1Test, WithoutFormat) { + // Success cases. + EXPECT_PRED1(IsEvenFunctor(), 2) << "This failure is UNEXPECTED!"; + ASSERT_PRED1(IsEven, 4); + + // Failure cases. + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED1(IsEven, 5) << "This failure is expected."; + }, "This failure is expected."); + EXPECT_FATAL_FAILURE(ASSERT_PRED1(IsEvenFunctor(), 5), + "evaluates to false"); +} + +// Tests unary predicate assertions that use a custom formatter. +TEST(Pred1Test, WithFormat) { + // Success cases. + EXPECT_PRED_FORMAT1(AssertIsEven, 2); + ASSERT_PRED_FORMAT1(AssertIsEvenFunctor(), 4) + << "This failure is UNEXPECTED!"; + + // Failure cases. + const int n = 5; + EXPECT_NONFATAL_FAILURE(EXPECT_PRED_FORMAT1(AssertIsEvenFunctor(), n), + "n evaluates to 5, which is not even."); + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT1(AssertIsEven, 5) << "This failure is expected."; + }, "This failure is expected."); +} + +// Tests that unary predicate assertions evaluates their arguments +// exactly once. +TEST(Pred1Test, SingleEvaluationOnFailure) { + // A success case. + static int n = 0; + EXPECT_PRED1(IsEven, n++); + EXPECT_EQ(1, n) << "The argument is not evaluated exactly once."; + + // A failure case. + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT1(AssertIsEvenFunctor(), n++) + << "This failure is expected."; + }, "This failure is expected."); + EXPECT_EQ(2, n) << "The argument is not evaluated exactly once."; +} + + +// Tests predicate assertions whose arity is >= 2. + +// Tests predicate assertions that don't use a custom formatter. +TEST(PredTest, WithoutFormat) { + // Success cases. + ASSERT_PRED2(SumIsEven2, 2, 4) << "This failure is UNEXPECTED!"; + EXPECT_PRED3(SumIsEven3Functor(), 4, 6, 8); + + // Failure cases. + const int n1 = 1; + const int n2 = 2; + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED2(SumIsEven2, n1, n2) << "This failure is expected."; + }, "This failure is expected."); + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED3(SumIsEven3Functor(), 1, 2, 4); + }, "evaluates to false"); +} + +// Tests predicate assertions that use a custom formatter. +TEST(PredTest, WithFormat) { + // Success cases. + ASSERT_PRED_FORMAT4(AssertSumIsEven4, 4, 6, 8, 10) << + "This failure is UNEXPECTED!"; + EXPECT_PRED_FORMAT5(AssertSumIsEven5Functor(), 2, 4, 6, 8, 10); + + // Failure cases. + const int n1 = 1; + const int n2 = 2; + const int n3 = 4; + const int n4 = 6; + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT4(AssertSumIsEven4, n1, n2, n3, n4); + }, "evaluates to 13, which is not even."); + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT5(AssertSumIsEven5Functor(), 1, 2, 4, 6, 8) + << "This failure is expected."; + }, "This failure is expected."); +} + +// Tests that predicate assertions evaluates their arguments +// exactly once. +TEST(PredTest, SingleEvaluationOnFailure) { + // A success case. + int n1 = 0; + int n2 = 0; + EXPECT_PRED2(SumIsEven2, n1++, n2++); + EXPECT_EQ(1, n1) << "Argument 1 is not evaluated exactly once."; + EXPECT_EQ(1, n2) << "Argument 2 is not evaluated exactly once."; + + // Another success case. + n1 = n2 = 0; + int n3 = 0; + int n4 = 0; + int n5 = 0; + ASSERT_PRED_FORMAT5(AssertSumIsEven5Functor(), + n1++, n2++, n3++, n4++, n5++) + << "This failure is UNEXPECTED!"; + EXPECT_EQ(1, n1) << "Argument 1 is not evaluated exactly once."; + EXPECT_EQ(1, n2) << "Argument 2 is not evaluated exactly once."; + EXPECT_EQ(1, n3) << "Argument 3 is not evaluated exactly once."; + EXPECT_EQ(1, n4) << "Argument 4 is not evaluated exactly once."; + EXPECT_EQ(1, n5) << "Argument 5 is not evaluated exactly once."; + + // A failure case. + n1 = n2 = n3 = 0; + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED3(SumIsEven3Functor(), ++n1, n2++, n3++) + << "This failure is expected."; + }, "This failure is expected."); + EXPECT_EQ(1, n1) << "Argument 1 is not evaluated exactly once."; + EXPECT_EQ(1, n2) << "Argument 2 is not evaluated exactly once."; + EXPECT_EQ(1, n3) << "Argument 3 is not evaluated exactly once."; + + // Another failure case. + n1 = n2 = n3 = n4 = 0; + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT4(AssertSumIsEven4, ++n1, n2++, n3++, n4++); + }, "evaluates to 1, which is not even."); + EXPECT_EQ(1, n1) << "Argument 1 is not evaluated exactly once."; + EXPECT_EQ(1, n2) << "Argument 2 is not evaluated exactly once."; + EXPECT_EQ(1, n3) << "Argument 3 is not evaluated exactly once."; + EXPECT_EQ(1, n4) << "Argument 4 is not evaluated exactly once."; +} + + +// Some helper functions for testing using overloaded/template +// functions with ASSERT_PREDn and EXPECT_PREDn. + +bool IsPositive(int n) { + return n > 0; +} + +bool IsPositive(double x) { + return x > 0; +} + +template +bool IsNegative(T x) { + return x < 0; +} + +template +bool GreaterThan(T1 x1, T2 x2) { + return x1 > x2; +} + +// Tests that overloaded functions can be used in *_PRED* as long as +// their types are explicitly specified. +TEST(PredicateAssertionTest, AcceptsOverloadedFunction) { + EXPECT_PRED1(static_cast(IsPositive), 5); // NOLINT + ASSERT_PRED1(static_cast(IsPositive), 6.0); // NOLINT +} + +// Tests that template functions can be used in *_PRED* as long as +// their types are explicitly specified. +TEST(PredicateAssertionTest, AcceptsTemplateFunction) { + EXPECT_PRED1(IsNegative, -5); + // Makes sure that we can handle templates with more than one + // parameter. + ASSERT_PRED2((GreaterThan), 5, 0); +} + + +// Some helper functions for testing using overloaded/template +// functions with ASSERT_PRED_FORMATn and EXPECT_PRED_FORMATn. + +testing::AssertionResult IsPositiveFormat(const char* expr, int n) { + return n > 0 ? testing::AssertionSuccess() : + testing::AssertionFailure(testing::Message() << "Failure"); +} + +testing::AssertionResult IsPositiveFormat(const char* expr, double x) { + return x > 0 ? testing::AssertionSuccess() : + testing::AssertionFailure(testing::Message() << "Failure"); +} + +template +testing::AssertionResult IsNegativeFormat(const char* expr, T x) { + return x < 0 ? testing::AssertionSuccess() : + testing::AssertionFailure(testing::Message() << "Failure"); +} + +template +testing::AssertionResult EqualsFormat(const char* expr1, const char* expr2, + const T1& x1, const T2& x2) { + return x1 == x2 ? testing::AssertionSuccess() : + testing::AssertionFailure(testing::Message() << "Failure"); +} + +// Tests that overloaded functions can be used in *_PRED_FORMAT* +// without explictly specifying their types. +TEST(PredicateFormatAssertionTest, AcceptsOverloadedFunction) { + EXPECT_PRED_FORMAT1(IsPositiveFormat, 5); + ASSERT_PRED_FORMAT1(IsPositiveFormat, 6.0); +} + +// Tests that template functions can be used in *_PRED_FORMAT* without +// explicitly specifying their types. +TEST(PredicateFormatAssertionTest, AcceptsTemplateFunction) { + EXPECT_PRED_FORMAT1(IsNegativeFormat, -5); + ASSERT_PRED_FORMAT2(EqualsFormat, 3, 3); +} + + +// Tests string assertions. + +// Tests ASSERT_STREQ with non-NULL arguments. +TEST(StringAssertionTest, ASSERT_STREQ) { + const char * const p1 = "good"; + ASSERT_STREQ(p1, p1); + + // Let p2 have the same content as p1, but be at a different address. + const char p2[] = "good"; + ASSERT_STREQ(p1, p2); + + EXPECT_FATAL_FAILURE(ASSERT_STREQ("bad", "good"), + "Expected: \"bad\""); +} + +// Tests ASSERT_STREQ with NULL arguments. +TEST(StringAssertionTest, ASSERT_STREQ_Null) { + ASSERT_STREQ(static_cast(NULL), NULL); + EXPECT_FATAL_FAILURE(ASSERT_STREQ(NULL, "non-null"), + "non-null"); +} + +// Tests ASSERT_STREQ with NULL arguments. +TEST(StringAssertionTest, ASSERT_STREQ_Null2) { + EXPECT_FATAL_FAILURE(ASSERT_STREQ("non-null", NULL), + "non-null"); +} + +// Tests ASSERT_STRNE. +TEST(StringAssertionTest, ASSERT_STRNE) { + ASSERT_STRNE("hi", "Hi"); + ASSERT_STRNE("Hi", NULL); + ASSERT_STRNE(NULL, "Hi"); + ASSERT_STRNE("", NULL); + ASSERT_STRNE(NULL, ""); + ASSERT_STRNE("", "Hi"); + ASSERT_STRNE("Hi", ""); + EXPECT_FATAL_FAILURE(ASSERT_STRNE("Hi", "Hi"), + "\"Hi\" vs \"Hi\""); +} + +// Tests ASSERT_STRCASEEQ. +TEST(StringAssertionTest, ASSERT_STRCASEEQ) { + ASSERT_STRCASEEQ("hi", "Hi"); + ASSERT_STRCASEEQ(static_cast(NULL), NULL); + + ASSERT_STRCASEEQ("", ""); + EXPECT_FATAL_FAILURE(ASSERT_STRCASEEQ("Hi", "hi2"), + "(ignoring case)"); +} + +// Tests ASSERT_STRCASENE. +TEST(StringAssertionTest, ASSERT_STRCASENE) { + ASSERT_STRCASENE("hi1", "Hi2"); + ASSERT_STRCASENE("Hi", NULL); + ASSERT_STRCASENE(NULL, "Hi"); + ASSERT_STRCASENE("", NULL); + ASSERT_STRCASENE(NULL, ""); + ASSERT_STRCASENE("", "Hi"); + ASSERT_STRCASENE("Hi", ""); + EXPECT_FATAL_FAILURE(ASSERT_STRCASENE("Hi", "hi"), + "(ignoring case)"); +} + +// Tests *_STREQ on wide strings. +TEST(StringAssertionTest, STREQ_Wide) { + // NULL strings. + ASSERT_STREQ(static_cast(NULL), NULL); + + // Empty strings. + ASSERT_STREQ(L"", L""); + + // Non-null vs NULL. + EXPECT_NONFATAL_FAILURE(EXPECT_STREQ(L"non-null", NULL), + "non-null"); + + // Equal strings. + EXPECT_STREQ(L"Hi", L"Hi"); + + // Unequal strings. + EXPECT_NONFATAL_FAILURE(EXPECT_STREQ(L"abc", L"Abc"), + "Abc"); + + // Strings containing wide characters. + EXPECT_NONFATAL_FAILURE(EXPECT_STREQ(L"abc\x8119", L"abc\x8120"), + "abc"); +} + +// Tests *_STRNE on wide strings. +TEST(StringAssertionTest, STRNE_Wide) { + // NULL strings. + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_STRNE(static_cast(NULL), NULL); + }, ""); + + // Empty strings. + EXPECT_NONFATAL_FAILURE(EXPECT_STRNE(L"", L""), + "L\"\""); + + // Non-null vs NULL. + ASSERT_STRNE(L"non-null", NULL); + + // Equal strings. + EXPECT_NONFATAL_FAILURE(EXPECT_STRNE(L"Hi", L"Hi"), + "L\"Hi\""); + + // Unequal strings. + EXPECT_STRNE(L"abc", L"Abc"); + + // Strings containing wide characters. + EXPECT_NONFATAL_FAILURE(EXPECT_STRNE(L"abc\x8119", L"abc\x8119"), + "abc"); +} + +// Tests for ::testing::IsSubstring(). + +// Tests that IsSubstring() returns the correct result when the input +// argument type is const char*. +TEST(IsSubstringTest, ReturnsCorrectResultForCString) { + using ::testing::IsSubstring; + + EXPECT_FALSE(IsSubstring("", "", NULL, "a")); + EXPECT_FALSE(IsSubstring("", "", "b", NULL)); + EXPECT_FALSE(IsSubstring("", "", "needle", "haystack")); + + EXPECT_TRUE(IsSubstring("", "", static_cast(NULL), NULL)); + EXPECT_TRUE(IsSubstring("", "", "needle", "two needles")); +} + +// Tests that IsSubstring() returns the correct result when the input +// argument type is const wchar_t*. +TEST(IsSubstringTest, ReturnsCorrectResultForWideCString) { + using ::testing::IsSubstring; + + EXPECT_FALSE(IsSubstring("", "", NULL, L"a")); + EXPECT_FALSE(IsSubstring("", "", L"b", NULL)); + EXPECT_FALSE(IsSubstring("", "", L"needle", L"haystack")); + + EXPECT_TRUE(IsSubstring("", "", static_cast(NULL), NULL)); + EXPECT_TRUE(IsSubstring("", "", L"needle", L"two needles")); +} + +// Tests that IsSubstring() generates the correct message when the input +// argument type is const char*. +TEST(IsSubstringTest, GeneratesCorrectMessageForCString) { + EXPECT_STREQ("Value of: needle_expr\n" + " Actual: \"needle\"\n" + "Expected: a substring of haystack_expr\n" + "Which is: \"haystack\"", + ::testing::IsSubstring("needle_expr", "haystack_expr", + "needle", "haystack").failure_message()); +} + +#if GTEST_HAS_STD_STRING + +// Tests that IsSubstring returns the correct result when the input +// argument type is ::std::string. +TEST(IsSubstringTest, ReturnsCorrectResultsForStdString) { + EXPECT_TRUE(::testing::IsSubstring("", "", std::string("hello"), "ahellob")); + EXPECT_FALSE(::testing::IsSubstring("", "", "hello", std::string("world"))); +} + +#endif // GTEST_HAS_STD_STRING + +#if GTEST_HAS_STD_WSTRING +// Tests that IsSubstring returns the correct result when the input +// argument type is ::std::wstring. +TEST(IsSubstringTest, ReturnsCorrectResultForStdWstring) { + using ::testing::IsSubstring; + + EXPECT_TRUE(IsSubstring("", "", ::std::wstring(L"needle"), L"two needles")); + EXPECT_FALSE(IsSubstring("", "", L"needle", ::std::wstring(L"haystack"))); +} + +// Tests that IsSubstring() generates the correct message when the input +// argument type is ::std::wstring. +TEST(IsSubstringTest, GeneratesCorrectMessageForWstring) { + EXPECT_STREQ("Value of: needle_expr\n" + " Actual: L\"needle\"\n" + "Expected: a substring of haystack_expr\n" + "Which is: L\"haystack\"", + ::testing::IsSubstring( + "needle_expr", "haystack_expr", + ::std::wstring(L"needle"), L"haystack").failure_message()); +} + +#endif // GTEST_HAS_STD_WSTRING + +// Tests for ::testing::IsNotSubstring(). + +// Tests that IsNotSubstring() returns the correct result when the input +// argument type is const char*. +TEST(IsNotSubstringTest, ReturnsCorrectResultForCString) { + using ::testing::IsNotSubstring; + + EXPECT_TRUE(IsNotSubstring("", "", "needle", "haystack")); + EXPECT_FALSE(IsNotSubstring("", "", "needle", "two needles")); +} + +// Tests that IsNotSubstring() returns the correct result when the input +// argument type is const wchar_t*. +TEST(IsNotSubstringTest, ReturnsCorrectResultForWideCString) { + using ::testing::IsNotSubstring; + + EXPECT_TRUE(IsNotSubstring("", "", L"needle", L"haystack")); + EXPECT_FALSE(IsNotSubstring("", "", L"needle", L"two needles")); +} + +// Tests that IsNotSubstring() generates the correct message when the input +// argument type is const wchar_t*. +TEST(IsNotSubstringTest, GeneratesCorrectMessageForWideCString) { + EXPECT_STREQ("Value of: needle_expr\n" + " Actual: L\"needle\"\n" + "Expected: not a substring of haystack_expr\n" + "Which is: L\"two needles\"", + ::testing::IsNotSubstring( + "needle_expr", "haystack_expr", + L"needle", L"two needles").failure_message()); +} + +#if GTEST_HAS_STD_STRING + +// Tests that IsNotSubstring returns the correct result when the input +// argument type is ::std::string. +TEST(IsNotSubstringTest, ReturnsCorrectResultsForStdString) { + using ::testing::IsNotSubstring; + + EXPECT_FALSE(IsNotSubstring("", "", std::string("hello"), "ahellob")); + EXPECT_TRUE(IsNotSubstring("", "", "hello", std::string("world"))); +} + +// Tests that IsNotSubstring() generates the correct message when the input +// argument type is ::std::string. +TEST(IsNotSubstringTest, GeneratesCorrectMessageForStdString) { + EXPECT_STREQ("Value of: needle_expr\n" + " Actual: \"needle\"\n" + "Expected: not a substring of haystack_expr\n" + "Which is: \"two needles\"", + ::testing::IsNotSubstring( + "needle_expr", "haystack_expr", + ::std::string("needle"), "two needles").failure_message()); +} + +#endif // GTEST_HAS_STD_STRING + +#if GTEST_HAS_STD_WSTRING + +// Tests that IsNotSubstring returns the correct result when the input +// argument type is ::std::wstring. +TEST(IsNotSubstringTest, ReturnsCorrectResultForStdWstring) { + using ::testing::IsNotSubstring; + + EXPECT_FALSE( + IsNotSubstring("", "", ::std::wstring(L"needle"), L"two needles")); + EXPECT_TRUE(IsNotSubstring("", "", L"needle", ::std::wstring(L"haystack"))); +} + +#endif // GTEST_HAS_STD_WSTRING + +// Tests floating-point assertions. + +template +class FloatingPointTest : public testing::Test { + protected: + typedef typename testing::internal::FloatingPoint Floating; + typedef typename Floating::Bits Bits; + + virtual void SetUp() { + const size_t max_ulps = Floating::kMaxUlps; + + // The bits that represent 0.0. + const Bits zero_bits = Floating(0).bits(); + + // Makes some numbers close to 0.0. + close_to_positive_zero_ = Floating::ReinterpretBits(zero_bits + max_ulps/2); + close_to_negative_zero_ = -Floating::ReinterpretBits( + zero_bits + max_ulps - max_ulps/2); + further_from_negative_zero_ = -Floating::ReinterpretBits( + zero_bits + max_ulps + 1 - max_ulps/2); + + // The bits that represent 1.0. + const Bits one_bits = Floating(1).bits(); + + // Makes some numbers close to 1.0. + close_to_one_ = Floating::ReinterpretBits(one_bits + max_ulps); + further_from_one_ = Floating::ReinterpretBits(one_bits + max_ulps + 1); + + // +infinity. + infinity_ = Floating::Infinity(); + + // The bits that represent +infinity. + const Bits infinity_bits = Floating(infinity_).bits(); + + // Makes some numbers close to infinity. + close_to_infinity_ = Floating::ReinterpretBits(infinity_bits - max_ulps); + further_from_infinity_ = Floating::ReinterpretBits( + infinity_bits - max_ulps - 1); + + // Makes some NAN's. + nan1_ = Floating::ReinterpretBits(Floating::kExponentBitMask | 1); + nan2_ = Floating::ReinterpretBits(Floating::kExponentBitMask | 200); + } + + void TestSize() { + EXPECT_EQ(sizeof(RawType), sizeof(Bits)); + } + + // Pre-calculated numbers to be used by the tests. + + static RawType close_to_positive_zero_; + static RawType close_to_negative_zero_; + static RawType further_from_negative_zero_; + + static RawType close_to_one_; + static RawType further_from_one_; + + static RawType infinity_; + static RawType close_to_infinity_; + static RawType further_from_infinity_; + + static RawType nan1_; + static RawType nan2_; +}; + +template +RawType FloatingPointTest::close_to_positive_zero_; + +template +RawType FloatingPointTest::close_to_negative_zero_; + +template +RawType FloatingPointTest::further_from_negative_zero_; + +template +RawType FloatingPointTest::close_to_one_; + +template +RawType FloatingPointTest::further_from_one_; + +template +RawType FloatingPointTest::infinity_; + +template +RawType FloatingPointTest::close_to_infinity_; + +template +RawType FloatingPointTest::further_from_infinity_; + +template +RawType FloatingPointTest::nan1_; + +template +RawType FloatingPointTest::nan2_; + +// Instantiates FloatingPointTest for testing *_FLOAT_EQ. +typedef FloatingPointTest FloatTest; + +// Tests that the size of Float::Bits matches the size of float. +TEST_F(FloatTest, Size) { + TestSize(); +} + +// Tests comparing with +0 and -0. +TEST_F(FloatTest, Zeros) { + EXPECT_FLOAT_EQ(0.0, -0.0); + EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(-0.0, 1.0), + "1.0"); + EXPECT_FATAL_FAILURE(ASSERT_FLOAT_EQ(0.0, 1.5), + "1.5"); +} + +// Tests comparing numbers close to 0. +// +// This ensures that *_FLOAT_EQ handles the sign correctly and no +// overflow occurs when comparing numbers whose absolute value is very +// small. +TEST_F(FloatTest, AlmostZeros) { + EXPECT_FLOAT_EQ(0.0, close_to_positive_zero_); + EXPECT_FLOAT_EQ(-0.0, close_to_negative_zero_); + EXPECT_FLOAT_EQ(close_to_positive_zero_, close_to_negative_zero_); + + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_FLOAT_EQ(close_to_positive_zero_, further_from_negative_zero_); + }, "further_from_negative_zero_"); +} + +// Tests comparing numbers close to each other. +TEST_F(FloatTest, SmallDiff) { + EXPECT_FLOAT_EQ(1.0, close_to_one_); + EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(1.0, further_from_one_), + "further_from_one_"); +} + +// Tests comparing numbers far apart. +TEST_F(FloatTest, LargeDiff) { + EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(2.5, 3.0), + "3.0"); +} + +// Tests comparing with infinity. +// +// This ensures that no overflow occurs when comparing numbers whose +// absolute value is very large. +TEST_F(FloatTest, Infinity) { + EXPECT_FLOAT_EQ(infinity_, close_to_infinity_); + EXPECT_FLOAT_EQ(-infinity_, -close_to_infinity_); + EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(infinity_, -infinity_), + "-infinity_"); + + // This is interesting as the representations of infinity_ and nan1_ + // are only 1 DLP apart. + EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(infinity_, nan1_), + "nan1_"); +} + +// Tests that comparing with NAN always returns false. +TEST_F(FloatTest, NaN) { + EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(nan1_, nan1_), + "nan1_"); + EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(nan1_, nan2_), + "nan2_"); + EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(1.0, nan1_), + "nan1_"); + + EXPECT_FATAL_FAILURE(ASSERT_FLOAT_EQ(nan1_, infinity_), + "infinity_"); +} + +// Tests that *_FLOAT_EQ are reflexive. +TEST_F(FloatTest, Reflexive) { + EXPECT_FLOAT_EQ(0.0, 0.0); + EXPECT_FLOAT_EQ(1.0, 1.0); + ASSERT_FLOAT_EQ(infinity_, infinity_); +} + +// Tests that *_FLOAT_EQ are commutative. +TEST_F(FloatTest, Commutative) { + // We already tested EXPECT_FLOAT_EQ(1.0, close_to_one_). + EXPECT_FLOAT_EQ(close_to_one_, 1.0); + + // We already tested EXPECT_FLOAT_EQ(1.0, further_from_one_). + EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(further_from_one_, 1.0), + "1.0"); +} + +// Tests EXPECT_NEAR. +TEST_F(FloatTest, EXPECT_NEAR) { + EXPECT_NEAR(-1.0f, -1.1f, 0.2f); + EXPECT_NEAR(2.0f, 3.0f, 1.0f); + EXPECT_NONFATAL_FAILURE(EXPECT_NEAR(1.0f,1.2f, 0.1f), // NOLINT + "The difference between 1.0f and 1.2f is 0.2, " + "which exceeds 0.1f"); + // To work around a bug in gcc 2.95.0, there is intentionally no + // space after the first comma in the previous line. +} + +// Tests ASSERT_NEAR. +TEST_F(FloatTest, ASSERT_NEAR) { + ASSERT_NEAR(-1.0f, -1.1f, 0.2f); + ASSERT_NEAR(2.0f, 3.0f, 1.0f); + EXPECT_FATAL_FAILURE(ASSERT_NEAR(1.0f,1.2f, 0.1f), // NOLINT + "The difference between 1.0f and 1.2f is 0.2, " + "which exceeds 0.1f"); + // To work around a bug in gcc 2.95.0, there is intentionally no + // space after the first comma in the previous line. +} + +// Tests the cases where FloatLE() should succeed. +TEST_F(FloatTest, FloatLESucceeds) { + EXPECT_PRED_FORMAT2(testing::FloatLE, 1.0f, 2.0f); // When val1 < val2, + ASSERT_PRED_FORMAT2(testing::FloatLE, 1.0f, 1.0f); // val1 == val2, + + // or when val1 is greater than, but almost equals to, val2. + EXPECT_PRED_FORMAT2(testing::FloatLE, close_to_positive_zero_, 0.0f); +} + +// Tests the cases where FloatLE() should fail. +TEST_F(FloatTest, FloatLEFails) { + // When val1 is greater than val2 by a large margin, + EXPECT_NONFATAL_FAILURE(EXPECT_PRED_FORMAT2(testing::FloatLE, 2.0f, 1.0f), + "(2.0f) <= (1.0f)"); + + // or by a small yet non-negligible margin, + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT2(testing::FloatLE, further_from_one_, 1.0f); + }, "(further_from_one_) <= (1.0f)"); + + // or when either val1 or val2 is NaN. + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT2(testing::FloatLE, nan1_, infinity_); + }, "(nan1_) <= (infinity_)"); + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT2(testing::FloatLE, -infinity_, nan1_); + }, "(-infinity_) <= (nan1_)"); + + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT2(testing::FloatLE, nan1_, nan1_); + }, "(nan1_) <= (nan1_)"); +} + +// Instantiates FloatingPointTest for testing *_DOUBLE_EQ. +typedef FloatingPointTest DoubleTest; + +// Tests that the size of Double::Bits matches the size of double. +TEST_F(DoubleTest, Size) { + TestSize(); +} + +// Tests comparing with +0 and -0. +TEST_F(DoubleTest, Zeros) { + EXPECT_DOUBLE_EQ(0.0, -0.0); + EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(-0.0, 1.0), + "1.0"); + EXPECT_FATAL_FAILURE(ASSERT_DOUBLE_EQ(0.0, 1.0), + "1.0"); +} + +// Tests comparing numbers close to 0. +// +// This ensures that *_DOUBLE_EQ handles the sign correctly and no +// overflow occurs when comparing numbers whose absolute value is very +// small. +TEST_F(DoubleTest, AlmostZeros) { + EXPECT_DOUBLE_EQ(0.0, close_to_positive_zero_); + EXPECT_DOUBLE_EQ(-0.0, close_to_negative_zero_); + EXPECT_DOUBLE_EQ(close_to_positive_zero_, close_to_negative_zero_); + + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_DOUBLE_EQ(close_to_positive_zero_, further_from_negative_zero_); + }, "further_from_negative_zero_"); +} + +// Tests comparing numbers close to each other. +TEST_F(DoubleTest, SmallDiff) { + EXPECT_DOUBLE_EQ(1.0, close_to_one_); + EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(1.0, further_from_one_), + "further_from_one_"); +} + +// Tests comparing numbers far apart. +TEST_F(DoubleTest, LargeDiff) { + EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(2.0, 3.0), + "3.0"); +} + +// Tests comparing with infinity. +// +// This ensures that no overflow occurs when comparing numbers whose +// absolute value is very large. +TEST_F(DoubleTest, Infinity) { + EXPECT_DOUBLE_EQ(infinity_, close_to_infinity_); + EXPECT_DOUBLE_EQ(-infinity_, -close_to_infinity_); + EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(infinity_, -infinity_), + "-infinity_"); + + // This is interesting as the representations of infinity_ and nan1_ + // are only 1 DLP apart. + EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(infinity_, nan1_), + "nan1_"); +} + +// Tests that comparing with NAN always returns false. +TEST_F(DoubleTest, NaN) { + EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(nan1_, nan1_), + "nan1_"); + EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(nan1_, nan2_), "nan2_"); + EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(1.0, nan1_), "nan1_"); + EXPECT_FATAL_FAILURE(ASSERT_DOUBLE_EQ(nan1_, infinity_), "infinity_"); +} + +// Tests that *_DOUBLE_EQ are reflexive. +TEST_F(DoubleTest, Reflexive) { + EXPECT_DOUBLE_EQ(0.0, 0.0); + EXPECT_DOUBLE_EQ(1.0, 1.0); + ASSERT_DOUBLE_EQ(infinity_, infinity_); +} + +// Tests that *_DOUBLE_EQ are commutative. +TEST_F(DoubleTest, Commutative) { + // We already tested EXPECT_DOUBLE_EQ(1.0, close_to_one_). + EXPECT_DOUBLE_EQ(close_to_one_, 1.0); + + // We already tested EXPECT_DOUBLE_EQ(1.0, further_from_one_). + EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(further_from_one_, 1.0), "1.0"); +} + +// Tests EXPECT_NEAR. +TEST_F(DoubleTest, EXPECT_NEAR) { + EXPECT_NEAR(-1.0, -1.1, 0.2); + EXPECT_NEAR(2.0, 3.0, 1.0); +#ifdef __SYMBIAN32__ + // Symbian STLport has currently a buggy floating point output. + // TODO(mikie): fix STLport. + EXPECT_NONFATAL_FAILURE(EXPECT_NEAR(1.0, 1.2, 0.1), // NOLINT + "The difference between 1.0 and 1.2 is 0.19999:, " + "which exceeds 0.1"); +#else // !__SYMBIAN32__ + EXPECT_NONFATAL_FAILURE(EXPECT_NEAR(1.0, 1.2, 0.1), // NOLINT + "The difference between 1.0 and 1.2 is 0.2, " + "which exceeds 0.1"); + // To work around a bug in gcc 2.95.0, there is intentionally no + // space after the first comma in the previous statement. +#endif // __SYMBIAN32__ +} + +// Tests ASSERT_NEAR. +TEST_F(DoubleTest, ASSERT_NEAR) { + ASSERT_NEAR(-1.0, -1.1, 0.2); + ASSERT_NEAR(2.0, 3.0, 1.0); +#ifdef __SYMBIAN32__ + // Symbian STLport has currently a buggy floating point output. + // TODO(mikie): fix STLport. + EXPECT_FATAL_FAILURE(ASSERT_NEAR(1.0, 1.2, 0.1), // NOLINT + "The difference between 1.0 and 1.2 is 0.19999:, " + "which exceeds 0.1"); +#else // ! __SYMBIAN32__ + EXPECT_FATAL_FAILURE(ASSERT_NEAR(1.0, 1.2, 0.1), // NOLINT + "The difference between 1.0 and 1.2 is 0.2, " + "which exceeds 0.1"); + // To work around a bug in gcc 2.95.0, there is intentionally no + // space after the first comma in the previous statement. +#endif // __SYMBIAN32__ +} + +// Tests the cases where DoubleLE() should succeed. +TEST_F(DoubleTest, DoubleLESucceeds) { + EXPECT_PRED_FORMAT2(testing::DoubleLE, 1.0, 2.0); // When val1 < val2, + ASSERT_PRED_FORMAT2(testing::DoubleLE, 1.0, 1.0); // val1 == val2, + + // or when val1 is greater than, but almost equals to, val2. + EXPECT_PRED_FORMAT2(testing::DoubleLE, close_to_positive_zero_, 0.0); +} + +// Tests the cases where DoubleLE() should fail. +TEST_F(DoubleTest, DoubleLEFails) { + // When val1 is greater than val2 by a large margin, + EXPECT_NONFATAL_FAILURE(EXPECT_PRED_FORMAT2(testing::DoubleLE, 2.0, 1.0), + "(2.0) <= (1.0)"); + + // or by a small yet non-negligible margin, + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT2(testing::DoubleLE, further_from_one_, 1.0); + }, "(further_from_one_) <= (1.0)"); + + // or when either val1 or val2 is NaN. + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT2(testing::DoubleLE, nan1_, infinity_); + }, "(nan1_) <= (infinity_)"); + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT2(testing::DoubleLE, -infinity_, nan1_); + }, " (-infinity_) <= (nan1_)"); + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT2(testing::DoubleLE, nan1_, nan1_); + }, "(nan1_) <= (nan1_)"); +} + + +// Verifies that a test or test case whose name starts with DISABLED_ is +// not run. + +// A test whose name starts with DISABLED_. +// Should not run. +TEST(DisabledTest, DISABLED_TestShouldNotRun) { + FAIL() << "Unexpected failure: Disabled test should not be run."; +} + +// A test whose name does not start with DISABLED_. +// Should run. +TEST(DisabledTest, NotDISABLED_TestShouldRun) { + EXPECT_EQ(1, 1); +} + +// A test case whose name starts with DISABLED_. +// Should not run. +TEST(DISABLED_TestCase, TestShouldNotRun) { + FAIL() << "Unexpected failure: Test in disabled test case should not be run."; +} + +// A test case and test whose names start with DISABLED_. +// Should not run. +TEST(DISABLED_TestCase, DISABLED_TestShouldNotRun) { + FAIL() << "Unexpected failure: Test in disabled test case should not be run."; +} + +// Check that when all tests in a test case are disabled, SetupTestCase() and +// TearDownTestCase() are not called. +class DisabledTestsTest : public testing::Test { + protected: + static void SetUpTestCase() { + FAIL() << "Unexpected failure: All tests disabled in test case. " + "SetupTestCase() should not be called."; + } + + static void TearDownTestCase() { + FAIL() << "Unexpected failure: All tests disabled in test case. " + "TearDownTestCase() should not be called."; + } +}; + +TEST_F(DisabledTestsTest, DISABLED_TestShouldNotRun_1) { + FAIL() << "Unexpected failure: Disabled test should not be run."; +} + +TEST_F(DisabledTestsTest, DISABLED_TestShouldNotRun_2) { + FAIL() << "Unexpected failure: Disabled test should not be run."; +} + + +// Tests that assertion macros evaluate their arguments exactly once. + +class SingleEvaluationTest : public testing::Test { + protected: + SingleEvaluationTest() { + p1_ = s1_; + p2_ = s2_; + a_ = 0; + b_ = 0; + } + + // This helper function is needed by the FailedASSERT_STREQ test + // below. + static void CompareAndIncrementCharPtrs() { + ASSERT_STREQ(p1_++, p2_++); + } + + // This helper function is needed by the FailedASSERT_NE test below. + static void CompareAndIncrementInts() { + ASSERT_NE(a_++, b_++); + } + + static const char* const s1_; + static const char* const s2_; + static const char* p1_; + static const char* p2_; + + static int a_; + static int b_; +}; + +const char* const SingleEvaluationTest::s1_ = "01234"; +const char* const SingleEvaluationTest::s2_ = "abcde"; +const char* SingleEvaluationTest::p1_; +const char* SingleEvaluationTest::p2_; +int SingleEvaluationTest::a_; +int SingleEvaluationTest::b_; + +// Tests that when ASSERT_STREQ fails, it evaluates its arguments +// exactly once. +TEST_F(SingleEvaluationTest, FailedASSERT_STREQ) { + EXPECT_FATAL_FAILURE(CompareAndIncrementCharPtrs(), + "p2_++"); + EXPECT_EQ(s1_ + 1, p1_); + EXPECT_EQ(s2_ + 1, p2_); +} + +// Tests that string assertion arguments are evaluated exactly once. +TEST_F(SingleEvaluationTest, ASSERT_STR) { + // successful EXPECT_STRNE + EXPECT_STRNE(p1_++, p2_++); + EXPECT_EQ(s1_ + 1, p1_); + EXPECT_EQ(s2_ + 1, p2_); + + // failed EXPECT_STRCASEEQ + EXPECT_NONFATAL_FAILURE(EXPECT_STRCASEEQ(p1_++, p2_++), + "ignoring case"); + EXPECT_EQ(s1_ + 2, p1_); + EXPECT_EQ(s2_ + 2, p2_); +} + +// Tests that when ASSERT_NE fails, it evaluates its arguments exactly +// once. +TEST_F(SingleEvaluationTest, FailedASSERT_NE) { + EXPECT_FATAL_FAILURE(CompareAndIncrementInts(), "(a_++) != (b_++)"); + EXPECT_EQ(1, a_); + EXPECT_EQ(1, b_); +} + +// Tests that assertion arguments are evaluated exactly once. +TEST_F(SingleEvaluationTest, OtherCases) { + // successful EXPECT_TRUE + EXPECT_TRUE(0 == a_++); // NOLINT + EXPECT_EQ(1, a_); + + // failed EXPECT_TRUE + EXPECT_NONFATAL_FAILURE(EXPECT_TRUE(-1 == a_++), "-1 == a_++"); + EXPECT_EQ(2, a_); + + // successful EXPECT_GT + EXPECT_GT(a_++, b_++); + EXPECT_EQ(3, a_); + EXPECT_EQ(1, b_); + + // failed EXPECT_LT + EXPECT_NONFATAL_FAILURE(EXPECT_LT(a_++, b_++), "(a_++) < (b_++)"); + EXPECT_EQ(4, a_); + EXPECT_EQ(2, b_); + + // successful ASSERT_TRUE + ASSERT_TRUE(0 < a_++); // NOLINT + EXPECT_EQ(5, a_); + + // successful ASSERT_GT + ASSERT_GT(a_++, b_++); + EXPECT_EQ(6, a_); + EXPECT_EQ(3, b_); +} + + +// Tests non-string assertions. + +// Tests EqFailure(), used for implementing *EQ* assertions. +TEST(AssertionTest, EqFailure) { + const String foo_val("5"), bar_val("6"); + const String msg1( + EqFailure("foo", "bar", foo_val, bar_val, false) + .failure_message()); + EXPECT_STREQ( + "Value of: bar\n" + " Actual: 6\n" + "Expected: foo\n" + "Which is: 5", + msg1.c_str()); + + const String msg2( + EqFailure("foo", "6", foo_val, bar_val, false) + .failure_message()); + EXPECT_STREQ( + "Value of: 6\n" + "Expected: foo\n" + "Which is: 5", + msg2.c_str()); + + const String msg3( + EqFailure("5", "bar", foo_val, bar_val, false) + .failure_message()); + EXPECT_STREQ( + "Value of: bar\n" + " Actual: 6\n" + "Expected: 5", + msg3.c_str()); + + const String msg4( + EqFailure("5", "6", foo_val, bar_val, false).failure_message()); + EXPECT_STREQ( + "Value of: 6\n" + "Expected: 5", + msg4.c_str()); + + const String msg5( + EqFailure("foo", "bar", + String("\"x\""), String("\"y\""), + true).failure_message()); + EXPECT_STREQ( + "Value of: bar\n" + " Actual: \"y\"\n" + "Expected: foo (ignoring case)\n" + "Which is: \"x\"", + msg5.c_str()); +} + +// Tests AppendUserMessage(), used for implementing the *EQ* macros. +TEST(AssertionTest, AppendUserMessage) { + const String foo("foo"); + + testing::Message msg; + EXPECT_STREQ("foo", + AppendUserMessage(foo, msg).c_str()); + + msg << "bar"; + EXPECT_STREQ("foo\nbar", + AppendUserMessage(foo, msg).c_str()); +} + +// Tests ASSERT_TRUE. +TEST(AssertionTest, ASSERT_TRUE) { + ASSERT_TRUE(2 > 1); // NOLINT + EXPECT_FATAL_FAILURE(ASSERT_TRUE(2 < 1), + "2 < 1"); +} + +// Tests ASSERT_FALSE. +TEST(AssertionTest, ASSERT_FALSE) { + ASSERT_FALSE(2 < 1); // NOLINT + EXPECT_FATAL_FAILURE(ASSERT_FALSE(2 > 1), + "Value of: 2 > 1\n" + " Actual: true\n" + "Expected: false"); +} + +// Tests using ASSERT_EQ on double values. The purpose is to make +// sure that the specialization we did for integer and anonymous enums +// isn't used for double arguments. +TEST(ExpectTest, ASSERT_EQ_Double) { + // A success. + ASSERT_EQ(5.6, 5.6); + + // A failure. + EXPECT_FATAL_FAILURE(ASSERT_EQ(5.1, 5.2), + "5.1"); +} + +// Tests ASSERT_EQ. +TEST(AssertionTest, ASSERT_EQ) { + ASSERT_EQ(5, 2 + 3); + EXPECT_FATAL_FAILURE(ASSERT_EQ(5, 2*3), + "Value of: 2*3\n" + " Actual: 6\n" + "Expected: 5"); +} + +// Tests ASSERT_EQ(NULL, pointer). +#ifndef __SYMBIAN32__ +// The NULL-detection template magic fails to compile with +// the Nokia compiler and crashes the ARM compiler, hence +// not testing on Symbian. +TEST(AssertionTest, ASSERT_EQ_NULL) { + // A success. + const char* p = NULL; + ASSERT_EQ(NULL, p); + + // A failure. + static int n = 0; + EXPECT_FATAL_FAILURE(ASSERT_EQ(NULL, &n), + "Value of: &n\n"); +} +#endif // __SYMBIAN32__ + +// Tests ASSERT_EQ(0, non_pointer). Since the literal 0 can be +// treated as a null pointer by the compiler, we need to make sure +// that ASSERT_EQ(0, non_pointer) isn't interpreted by Google Test as +// ASSERT_EQ(static_cast(NULL), non_pointer). +TEST(ExpectTest, ASSERT_EQ_0) { + int n = 0; + + // A success. + ASSERT_EQ(0, n); + + // A failure. + EXPECT_FATAL_FAILURE(ASSERT_EQ(0, 5.6), + "Expected: 0"); +} + +// Tests ASSERT_NE. +TEST(AssertionTest, ASSERT_NE) { + ASSERT_NE(6, 7); + EXPECT_FATAL_FAILURE(ASSERT_NE('a', 'a'), + "Expected: ('a') != ('a'), " + "actual: 'a' (97, 0x61) vs 'a' (97, 0x61)"); +} + +// Tests ASSERT_LE. +TEST(AssertionTest, ASSERT_LE) { + ASSERT_LE(2, 3); + ASSERT_LE(2, 2); + EXPECT_FATAL_FAILURE(ASSERT_LE(2, 0), + "Expected: (2) <= (0), actual: 2 vs 0"); +} + +// Tests ASSERT_LT. +TEST(AssertionTest, ASSERT_LT) { + ASSERT_LT(2, 3); + EXPECT_FATAL_FAILURE(ASSERT_LT(2, 2), + "Expected: (2) < (2), actual: 2 vs 2"); +} + +// Tests ASSERT_GE. +TEST(AssertionTest, ASSERT_GE) { + ASSERT_GE(2, 1); + ASSERT_GE(2, 2); + EXPECT_FATAL_FAILURE(ASSERT_GE(2, 3), + "Expected: (2) >= (3), actual: 2 vs 3"); +} + +// Tests ASSERT_GT. +TEST(AssertionTest, ASSERT_GT) { + ASSERT_GT(2, 1); + EXPECT_FATAL_FAILURE(ASSERT_GT(2, 2), + "Expected: (2) > (2), actual: 2 vs 2"); +} + +// Makes sure we deal with the precedence of <<. This test should +// compile. +TEST(AssertionTest, AssertPrecedence) { + ASSERT_EQ(1 < 2, true); + ASSERT_EQ(true && false, false); +} + +// A subroutine used by the following test. +void TestEq1(int x) { + ASSERT_EQ(1, x); +} + +// Tests calling a test subroutine that's not part of a fixture. +TEST(AssertionTest, NonFixtureSubroutine) { + EXPECT_FATAL_FAILURE(TestEq1(2), + "Value of: x"); +} + +// An uncopyable class. +class Uncopyable { + public: + explicit Uncopyable(int value) : value_(value) {} + + int value() const { return value_; } + bool operator==(const Uncopyable& rhs) const { + return value() == rhs.value(); + } + private: + // This constructor deliberately has no implementation, as we don't + // want this class to be copyable. + Uncopyable(const Uncopyable&); // NOLINT + + int value_; +}; + +::std::ostream& operator<<(::std::ostream& os, const Uncopyable& value) { + return os << value.value(); +} + + +bool IsPositiveUncopyable(const Uncopyable& x) { + return x.value() > 0; +} + +// A subroutine used by the following test. +void TestAssertNonPositive() { + Uncopyable y(-1); + ASSERT_PRED1(IsPositiveUncopyable, y); +} +// A subroutine used by the following test. +void TestAssertEqualsUncopyable() { + Uncopyable x(5); + Uncopyable y(-1); + ASSERT_EQ(x, y); +} + +// Tests that uncopyable objects can be used in assertions. +TEST(AssertionTest, AssertWorksWithUncopyableObject) { + Uncopyable x(5); + ASSERT_PRED1(IsPositiveUncopyable, x); + ASSERT_EQ(x, x); + EXPECT_FATAL_FAILURE(TestAssertNonPositive(), + "IsPositiveUncopyable(y) evaluates to false, where\ny evaluates to -1"); + EXPECT_FATAL_FAILURE(TestAssertEqualsUncopyable(), + "Value of: y\n Actual: -1\nExpected: x\nWhich is: 5"); +} + +// Tests that uncopyable objects can be used in expects. +TEST(AssertionTest, ExpectWorksWithUncopyableObject) { + Uncopyable x(5); + EXPECT_PRED1(IsPositiveUncopyable, x); + Uncopyable y(-1); + EXPECT_NONFATAL_FAILURE(EXPECT_PRED1(IsPositiveUncopyable, y), + "IsPositiveUncopyable(y) evaluates to false, where\ny evaluates to -1"); + EXPECT_EQ(x, x); + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(x, y), + "Value of: y\n Actual: -1\nExpected: x\nWhich is: 5"); +} + + +// The version of gcc used in XCode 2.2 has a bug and doesn't allow +// anonymous enums in assertions. Therefore the following test is +// done only on Linux and Windows. +#if defined(GTEST_OS_LINUX) || defined(GTEST_OS_WINDOWS) + +// Tests using assertions with anonymous enums. +enum { + CASE_A = -1, +#ifdef GTEST_OS_LINUX + // We want to test the case where the size of the anonymous enum is + // larger than sizeof(int), to make sure our implementation of the + // assertions doesn't truncate the enums. However, MSVC + // (incorrectly) doesn't allow an enum value to exceed the range of + // an int, so this has to be conditionally compiled. + // + // On Linux, CASE_B and CASE_A have the same value when truncated to + // int size. We want to test whether this will confuse the + // assertions. + CASE_B = ::testing::internal::kMaxBiggestInt, +#else + CASE_B = INT_MAX, +#endif // GTEST_OS_LINUX +}; + +TEST(AssertionTest, AnonymousEnum) { +#ifdef GTEST_OS_LINUX + EXPECT_EQ(static_cast(CASE_A), static_cast(CASE_B)); +#endif // GTEST_OS_LINUX + + EXPECT_EQ(CASE_A, CASE_A); + EXPECT_NE(CASE_A, CASE_B); + EXPECT_LT(CASE_A, CASE_B); + EXPECT_LE(CASE_A, CASE_B); + EXPECT_GT(CASE_B, CASE_A); + EXPECT_GE(CASE_A, CASE_A); + EXPECT_NONFATAL_FAILURE(EXPECT_GE(CASE_A, CASE_B), + "(CASE_A) >= (CASE_B)"); + + ASSERT_EQ(CASE_A, CASE_A); + ASSERT_NE(CASE_A, CASE_B); + ASSERT_LT(CASE_A, CASE_B); + ASSERT_LE(CASE_A, CASE_B); + ASSERT_GT(CASE_B, CASE_A); + ASSERT_GE(CASE_A, CASE_A); + EXPECT_FATAL_FAILURE(ASSERT_EQ(CASE_A, CASE_B), + "Value of: CASE_B"); +} + +#endif // defined(GTEST_OS_LINUX) || defined(GTEST_OS_WINDOWS) + +#if defined(GTEST_OS_WINDOWS) + +static HRESULT UnexpectedHRESULTFailure() { + return E_UNEXPECTED; +} + +static HRESULT OkHRESULTSuccess() { + return S_OK; +} + +static HRESULT FalseHRESULTSuccess() { + return S_FALSE; +} + +// HRESULT assertion tests test both zero and non-zero +// success codes as well as failure message for each. +// +// Windows CE doesn't support message texts. +TEST(HRESULTAssertionTest, EXPECT_HRESULT_SUCCEEDED) { + EXPECT_HRESULT_SUCCEEDED(S_OK); + EXPECT_HRESULT_SUCCEEDED(S_FALSE); + +#ifdef _WIN32_WCE + const char* expected = + "Expected: (UnexpectedHRESULTFailure()) succeeds.\n" + " Actual: 0x8000FFFF"; +#else // Windows proper + const char* expected = + "Expected: (UnexpectedHRESULTFailure()) succeeds.\n" + " Actual: 0x8000FFFF Catastrophic failure"; +#endif // _WIN32_WCE + EXPECT_NONFATAL_FAILURE(EXPECT_HRESULT_SUCCEEDED(UnexpectedHRESULTFailure()), + expected); +} + +TEST(HRESULTAssertionTest, ASSERT_HRESULT_SUCCEEDED) { + ASSERT_HRESULT_SUCCEEDED(S_OK); + ASSERT_HRESULT_SUCCEEDED(S_FALSE); + +#ifdef _WIN32_WCE + const char* expected = + "Expected: (UnexpectedHRESULTFailure()) succeeds.\n" + " Actual: 0x8000FFFF"; +#else // Windows proper + const char* expected = + "Expected: (UnexpectedHRESULTFailure()) succeeds.\n" + " Actual: 0x8000FFFF Catastrophic failure"; +#endif // _WIN32_WCE + + EXPECT_FATAL_FAILURE(ASSERT_HRESULT_SUCCEEDED(UnexpectedHRESULTFailure()), + expected); +} + +TEST(HRESULTAssertionTest, EXPECT_HRESULT_FAILED) { + EXPECT_HRESULT_FAILED(E_UNEXPECTED); + +#ifdef _WIN32_WCE + const char* expected_success = + "Expected: (OkHRESULTSuccess()) fails.\n" + " Actual: 0x00000000"; + const char* expected_incorrect_function = + "Expected: (FalseHRESULTSuccess()) fails.\n" + " Actual: 0x00000001"; +#else // Windows proper + const char* expected_success = + "Expected: (OkHRESULTSuccess()) fails.\n" + " Actual: 0x00000000 The operation completed successfully"; + const char* expected_incorrect_function = + "Expected: (FalseHRESULTSuccess()) fails.\n" + " Actual: 0x00000001 Incorrect function."; +#endif // _WIN32_WCE + + EXPECT_NONFATAL_FAILURE(EXPECT_HRESULT_FAILED(OkHRESULTSuccess()), + expected_success); + EXPECT_NONFATAL_FAILURE(EXPECT_HRESULT_FAILED(FalseHRESULTSuccess()), + expected_incorrect_function); +} + +TEST(HRESULTAssertionTest, ASSERT_HRESULT_FAILED) { + ASSERT_HRESULT_FAILED(E_UNEXPECTED); + +#ifdef _WIN32_WCE + const char* expected_success = + "Expected: (OkHRESULTSuccess()) fails.\n" + " Actual: 0x00000000"; + const char* expected_incorrect_function = + "Expected: (FalseHRESULTSuccess()) fails.\n" + " Actual: 0x00000001"; +#else // Windows proper + const char* expected_success = + "Expected: (OkHRESULTSuccess()) fails.\n" + " Actual: 0x00000000 The operation completed successfully"; + const char* expected_incorrect_function = + "Expected: (FalseHRESULTSuccess()) fails.\n" + " Actual: 0x00000001 Incorrect function."; +#endif // _WIN32_WCE + + EXPECT_FATAL_FAILURE(ASSERT_HRESULT_FAILED(OkHRESULTSuccess()), + expected_success); + EXPECT_FATAL_FAILURE(ASSERT_HRESULT_FAILED(FalseHRESULTSuccess()), + expected_incorrect_function); +} + +// Tests that streaming to the HRESULT macros works. +TEST(HRESULTAssertionTest, Streaming) { + EXPECT_HRESULT_SUCCEEDED(S_OK) << "unexpected failure"; + ASSERT_HRESULT_SUCCEEDED(S_OK) << "unexpected failure"; + EXPECT_HRESULT_FAILED(E_UNEXPECTED) << "unexpected failure"; + ASSERT_HRESULT_FAILED(E_UNEXPECTED) << "unexpected failure"; + + EXPECT_NONFATAL_FAILURE( + EXPECT_HRESULT_SUCCEEDED(E_UNEXPECTED) << "expected failure", + "expected failure"); + + EXPECT_FATAL_FAILURE( + ASSERT_HRESULT_SUCCEEDED(E_UNEXPECTED) << "expected failure", + "expected failure"); + + EXPECT_NONFATAL_FAILURE( + EXPECT_HRESULT_FAILED(S_OK) << "expected failure", + "expected failure"); + + EXPECT_FATAL_FAILURE( + ASSERT_HRESULT_FAILED(S_OK) << "expected failure", + "expected failure"); +} + +#endif // defined(GTEST_OS_WINDOWS) + +// Tests that the assertion macros behave like single statements. +TEST(AssertionSyntaxTest, BehavesLikeSingleStatement) { + if (false) + ASSERT_TRUE(false) << "This should never be executed; " + "It's a compilation test only."; + + if (true) + EXPECT_FALSE(false); + else + ; + + if (false) + ASSERT_LT(1, 3); + + if (false) + ; + else + EXPECT_GT(3, 2) << ""; +} + +// Tests that the assertion macros work well with switch statements. +TEST(AssertionSyntaxTest, WorksWithSwitch) { + switch (0) { + case 1: + break; + default: + ASSERT_TRUE(true); + } + + switch (0) + case 0: + EXPECT_FALSE(false) << "EXPECT_FALSE failed in switch case"; + + // Binary assertions are implemented using a different code path + // than the Boolean assertions. Hence we test them separately. + switch (0) { + case 1: + default: + ASSERT_EQ(1, 1) << "ASSERT_EQ failed in default switch handler"; + } + + switch (0) + case 0: + EXPECT_NE(1, 2); +} + +} // namespace + +// Returns the number of successful parts in the current test. +static size_t GetSuccessfulPartCount() { + return UnitTest::GetInstance()->impl()->current_test_result()-> + successful_part_count(); +} + +namespace testing { + +// Tests that Google Test tracks SUCCEED*. +TEST(SuccessfulAssertionTest, SUCCEED) { + SUCCEED(); + SUCCEED() << "OK"; + EXPECT_EQ(2u, GetSuccessfulPartCount()); +} + +// Tests that Google Test doesn't track successful EXPECT_*. +TEST(SuccessfulAssertionTest, EXPECT) { + EXPECT_TRUE(true); + EXPECT_EQ(0u, GetSuccessfulPartCount()); +} + +// Tests that Google Test doesn't track successful EXPECT_STR*. +TEST(SuccessfulAssertionTest, EXPECT_STR) { + EXPECT_STREQ("", ""); + EXPECT_EQ(0u, GetSuccessfulPartCount()); +} + +// Tests that Google Test doesn't track successful ASSERT_*. +TEST(SuccessfulAssertionTest, ASSERT) { + ASSERT_TRUE(true); + EXPECT_EQ(0u, GetSuccessfulPartCount()); +} + +// Tests that Google Test doesn't track successful ASSERT_STR*. +TEST(SuccessfulAssertionTest, ASSERT_STR) { + ASSERT_STREQ("", ""); + EXPECT_EQ(0u, GetSuccessfulPartCount()); +} + +} // namespace testing + +namespace { + +// Tests EXPECT_TRUE. +TEST(ExpectTest, EXPECT_TRUE) { + EXPECT_TRUE(2 > 1); // NOLINT + EXPECT_NONFATAL_FAILURE(EXPECT_TRUE(2 < 1), + "Value of: 2 < 1\n" + " Actual: false\n" + "Expected: true"); + EXPECT_NONFATAL_FAILURE(EXPECT_TRUE(2 > 3), + "2 > 3"); +} + +// Tests EXPECT_FALSE. +TEST(ExpectTest, EXPECT_FALSE) { + EXPECT_FALSE(2 < 1); // NOLINT + EXPECT_NONFATAL_FAILURE(EXPECT_FALSE(2 > 1), + "Value of: 2 > 1\n" + " Actual: true\n" + "Expected: false"); + EXPECT_NONFATAL_FAILURE(EXPECT_FALSE(2 < 3), + "2 < 3"); +} + +// Tests EXPECT_EQ. +TEST(ExpectTest, EXPECT_EQ) { + EXPECT_EQ(5, 2 + 3); + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(5, 2*3), + "Value of: 2*3\n" + " Actual: 6\n" + "Expected: 5"); + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(5, 2 - 3), + "2 - 3"); +} + +// Tests using EXPECT_EQ on double values. The purpose is to make +// sure that the specialization we did for integer and anonymous enums +// isn't used for double arguments. +TEST(ExpectTest, EXPECT_EQ_Double) { + // A success. + EXPECT_EQ(5.6, 5.6); + + // A failure. + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(5.1, 5.2), + "5.1"); +} + +#ifndef __SYMBIAN32__ +// Tests EXPECT_EQ(NULL, pointer). +TEST(ExpectTest, EXPECT_EQ_NULL) { + // A success. + const char* p = NULL; + EXPECT_EQ(NULL, p); + + // A failure. + int n = 0; + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(NULL, &n), + "Value of: &n\n"); +} +#endif // __SYMBIAN32__ + +// Tests EXPECT_EQ(0, non_pointer). Since the literal 0 can be +// treated as a null pointer by the compiler, we need to make sure +// that EXPECT_EQ(0, non_pointer) isn't interpreted by Google Test as +// EXPECT_EQ(static_cast(NULL), non_pointer). +TEST(ExpectTest, EXPECT_EQ_0) { + int n = 0; + + // A success. + EXPECT_EQ(0, n); + + // A failure. + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(0, 5.6), + "Expected: 0"); +} + +// Tests EXPECT_NE. +TEST(ExpectTest, EXPECT_NE) { + EXPECT_NE(6, 7); + + EXPECT_NONFATAL_FAILURE(EXPECT_NE('a', 'a'), + "Expected: ('a') != ('a'), " + "actual: 'a' (97, 0x61) vs 'a' (97, 0x61)"); + EXPECT_NONFATAL_FAILURE(EXPECT_NE(2, 2), + "2"); + char* const p0 = NULL; + EXPECT_NONFATAL_FAILURE(EXPECT_NE(p0, p0), + "p0"); + // Only way to get the Nokia compiler to compile the cast + // is to have a separate void* variable first. Putting + // the two casts on the same line doesn't work, neither does + // a direct C-style to char*. + void* pv1 = (void*)0x1234; // NOLINT + char* const p1 = reinterpret_cast(pv1); + EXPECT_NONFATAL_FAILURE(EXPECT_NE(p1, p1), + "p1"); +} + +// Tests EXPECT_LE. +TEST(ExpectTest, EXPECT_LE) { + EXPECT_LE(2, 3); + EXPECT_LE(2, 2); + EXPECT_NONFATAL_FAILURE(EXPECT_LE(2, 0), + "Expected: (2) <= (0), actual: 2 vs 0"); + EXPECT_NONFATAL_FAILURE(EXPECT_LE(1.1, 0.9), + "(1.1) <= (0.9)"); +} + +// Tests EXPECT_LT. +TEST(ExpectTest, EXPECT_LT) { + EXPECT_LT(2, 3); + EXPECT_NONFATAL_FAILURE(EXPECT_LT(2, 2), + "Expected: (2) < (2), actual: 2 vs 2"); + EXPECT_NONFATAL_FAILURE(EXPECT_LT(2, 1), + "(2) < (1)"); +} + +// Tests EXPECT_GE. +TEST(ExpectTest, EXPECT_GE) { + EXPECT_GE(2, 1); + EXPECT_GE(2, 2); + EXPECT_NONFATAL_FAILURE(EXPECT_GE(2, 3), + "Expected: (2) >= (3), actual: 2 vs 3"); + EXPECT_NONFATAL_FAILURE(EXPECT_GE(0.9, 1.1), + "(0.9) >= (1.1)"); +} + +// Tests EXPECT_GT. +TEST(ExpectTest, EXPECT_GT) { + EXPECT_GT(2, 1); + EXPECT_NONFATAL_FAILURE(EXPECT_GT(2, 2), + "Expected: (2) > (2), actual: 2 vs 2"); + EXPECT_NONFATAL_FAILURE(EXPECT_GT(2, 3), + "(2) > (3)"); +} + +// Make sure we deal with the precedence of <<. +TEST(ExpectTest, ExpectPrecedence) { + EXPECT_EQ(1 < 2, true); + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(true, true && false), + "Value of: true && false"); +} + + +// Tests the StreamableToString() function. + +// Tests using StreamableToString() on a scalar. +TEST(StreamableToStringTest, Scalar) { + EXPECT_STREQ("5", StreamableToString(5).c_str()); +} + +// Tests using StreamableToString() on a non-char pointer. +TEST(StreamableToStringTest, Pointer) { + int n = 0; + int* p = &n; + EXPECT_STRNE("(null)", StreamableToString(p).c_str()); +} + +// Tests using StreamableToString() on a NULL non-char pointer. +TEST(StreamableToStringTest, NullPointer) { + int* p = NULL; + EXPECT_STREQ("(null)", StreamableToString(p).c_str()); +} + +// Tests using StreamableToString() on a C string. +TEST(StreamableToStringTest, CString) { + EXPECT_STREQ("Foo", StreamableToString("Foo").c_str()); +} + +// Tests using StreamableToString() on a NULL C string. +TEST(StreamableToStringTest, NullCString) { + char* p = NULL; + EXPECT_STREQ("(null)", StreamableToString(p).c_str()); +} + +// Tests using streamable values as assertion messages. + +#if GTEST_HAS_STD_STRING +// Tests using std::string as an assertion message. +TEST(StreamableTest, string) { + static const std::string str( + "This failure message is a std::string, and is expected."); + EXPECT_FATAL_FAILURE(FAIL() << str, + str.c_str()); +} + +// Tests that we can output strings containing embedded NULs. +// Limited to Linux because we can only do this with std::string's. +TEST(StreamableTest, stringWithEmbeddedNUL) { + static const char char_array_with_nul[] = + "Here's a NUL\0 and some more string"; + static const std::string string_with_nul(char_array_with_nul, + sizeof(char_array_with_nul) + - 1); // drops the trailing NUL + EXPECT_FATAL_FAILURE(FAIL() << string_with_nul, + "Here's a NUL\\0 and some more string"); +} + +#endif // GTEST_HAS_STD_STRING + +// Tests that we can output a NUL char. +TEST(StreamableTest, NULChar) { + EXPECT_FATAL_FAILURE({ // NOLINT + FAIL() << "A NUL" << '\0' << " and some more string"; + }, "A NUL\\0 and some more string"); +} + +// Tests using int as an assertion message. +TEST(StreamableTest, int) { + EXPECT_FATAL_FAILURE(FAIL() << 900913, + "900913"); +} + +// Tests using NULL char pointer as an assertion message. +// +// In MSVC, streaming a NULL char * causes access violation. Google Test +// implemented a workaround (substituting "(null)" for NULL). This +// tests whether the workaround works. +TEST(StreamableTest, NullCharPtr) { + EXPECT_FATAL_FAILURE(FAIL() << static_cast(NULL), + "(null)"); +} + +// Tests that basic IO manipulators (endl, ends, and flush) can be +// streamed to testing::Message. +TEST(StreamableTest, BasicIoManip) { + EXPECT_FATAL_FAILURE({ // NOLINT + FAIL() << "Line 1." << std::endl + << "A NUL char " << std::ends << std::flush << " in line 2."; + }, "Line 1.\nA NUL char \\0 in line 2."); +} + + +// Tests the macros that haven't been covered so far. + +void AddFailureHelper(bool* aborted) { + *aborted = true; + ADD_FAILURE() << "Failure"; + *aborted = false; +} + +// Tests ADD_FAILURE. +TEST(MacroTest, ADD_FAILURE) { + bool aborted = true; + EXPECT_NONFATAL_FAILURE(AddFailureHelper(&aborted), + "Failure"); + EXPECT_FALSE(aborted); +} + +// Tests FAIL. +TEST(MacroTest, FAIL) { + EXPECT_FATAL_FAILURE(FAIL(), + "Failed"); + EXPECT_FATAL_FAILURE(FAIL() << "Intentional failure.", + "Intentional failure."); +} + +// Tests SUCCEED +TEST(MacroTest, SUCCEED) { + SUCCEED(); + SUCCEED() << "Explicit success."; +} + + +// Tests for EXPECT_EQ() and ASSERT_EQ(). +// +// These tests fail *intentionally*, s.t. the failure messages can be +// generated and tested. +// +// We have different tests for different argument types. + +// Tests using bool values in {EXPECT|ASSERT}_EQ. +TEST(EqAssertionTest, Bool) { + EXPECT_EQ(true, true); + EXPECT_FATAL_FAILURE(ASSERT_EQ(false, true), + "Value of: true"); +} + +// Tests using int values in {EXPECT|ASSERT}_EQ. +TEST(EqAssertionTest, Int) { + ASSERT_EQ(32, 32); + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(32, 33), + "33"); +} + +// Tests using time_t values in {EXPECT|ASSERT}_EQ. +TEST(EqAssertionTest, Time_T) { + EXPECT_EQ(static_cast(0), + static_cast(0)); + EXPECT_FATAL_FAILURE(ASSERT_EQ(static_cast(0), + static_cast(1234)), + "1234"); +} + +// Tests using char values in {EXPECT|ASSERT}_EQ. +TEST(EqAssertionTest, Char) { + ASSERT_EQ('z', 'z'); + const char ch = 'b'; + EXPECT_NONFATAL_FAILURE(EXPECT_EQ('\0', ch), + "ch"); + EXPECT_NONFATAL_FAILURE(EXPECT_EQ('a', ch), + "ch"); +} + +// Tests using wchar_t values in {EXPECT|ASSERT}_EQ. +TEST(EqAssertionTest, WideChar) { + EXPECT_EQ(L'b', L'b'); + + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(L'\0', L'x'), + "Value of: L'x'\n" + " Actual: L'x' (120, 0x78)\n" + "Expected: L'\0'\n" + "Which is: L'\0' (0, 0x0)"); + + static wchar_t wchar; + wchar = L'b'; + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(L'a', wchar), + "wchar"); + wchar = L'\x8119'; + EXPECT_FATAL_FAILURE(ASSERT_EQ(L'\x8120', wchar), + "Value of: wchar"); +} + +#if GTEST_HAS_STD_STRING +// Tests using ::std::string values in {EXPECT|ASSERT}_EQ. +TEST(EqAssertionTest, StdString) { + // Compares a const char* to an std::string that has identical + // content. + ASSERT_EQ("Test", ::std::string("Test")); + + // Compares two identical std::strings. + static const ::std::string str1("A * in the middle"); + static const ::std::string str2(str1); + EXPECT_EQ(str1, str2); + + // Compares a const char* to an std::string that has different + // content + EXPECT_NONFATAL_FAILURE(EXPECT_EQ("Test", ::std::string("test")), + "::std::string(\"test\")"); + + // Compares an std::string to a char* that has different content. + char* const p1 = const_cast("foo"); + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(::std::string("bar"), p1), + "p1"); + + // Compares two std::strings that have different contents, one of + // which having a NUL character in the middle. This should fail. + static ::std::string str3(str1); + str3.at(2) = '\0'; + EXPECT_FATAL_FAILURE(ASSERT_EQ(str1, str3), + "Value of: str3\n" + " Actual: \"A \\0 in the middle\""); +} + +#endif // GTEST_HAS_STD_STRING + +#if GTEST_HAS_STD_WSTRING + +// Tests using ::std::wstring values in {EXPECT|ASSERT}_EQ. +TEST(EqAssertionTest, StdWideString) { + // Compares an std::wstring to a const wchar_t* that has identical + // content. + EXPECT_EQ(::std::wstring(L"Test\x8119"), L"Test\x8119"); + + // Compares two identical std::wstrings. + const ::std::wstring wstr1(L"A * in the middle"); + const ::std::wstring wstr2(wstr1); + ASSERT_EQ(wstr1, wstr2); + + // Compares an std::wstring to a const wchar_t* that has different + // content. + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_EQ(::std::wstring(L"Test\x8119"), L"Test\x8120"); + }, "L\"Test\\x8120\""); + + // Compares two std::wstrings that have different contents, one of + // which having a NUL character in the middle. + ::std::wstring wstr3(wstr1); + wstr3.at(2) = L'\0'; + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(wstr1, wstr3), + "wstr3"); + + // Compares a wchar_t* to an std::wstring that has different + // content. + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_EQ(const_cast(L"foo"), ::std::wstring(L"bar")); + }, ""); +} + +#endif // GTEST_HAS_STD_WSTRING + +#if GTEST_HAS_GLOBAL_STRING +// Tests using ::string values in {EXPECT|ASSERT}_EQ. +TEST(EqAssertionTest, GlobalString) { + // Compares a const char* to a ::string that has identical content. + EXPECT_EQ("Test", ::string("Test")); + + // Compares two identical ::strings. + const ::string str1("A * in the middle"); + const ::string str2(str1); + ASSERT_EQ(str1, str2); + + // Compares a ::string to a const char* that has different content. + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(::string("Test"), "test"), + "test"); + + // Compares two ::strings that have different contents, one of which + // having a NUL character in the middle. + ::string str3(str1); + str3.at(2) = '\0'; + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(str1, str3), + "str3"); + + // Compares a ::string to a char* that has different content. + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_EQ(::string("bar"), const_cast("foo")); + }, ""); +} + +#endif // GTEST_HAS_GLOBAL_STRING + +#if GTEST_HAS_GLOBAL_WSTRING + +// Tests using ::wstring values in {EXPECT|ASSERT}_EQ. +TEST(EqAssertionTest, GlobalWideString) { + // Compares a const wchar_t* to a ::wstring that has identical content. + ASSERT_EQ(L"Test\x8119", ::wstring(L"Test\x8119")); + + // Compares two identical ::wstrings. + static const ::wstring wstr1(L"A * in the middle"); + static const ::wstring wstr2(wstr1); + EXPECT_EQ(wstr1, wstr2); + + // Compares a const wchar_t* to a ::wstring that has different + // content. + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_EQ(L"Test\x8120", ::wstring(L"Test\x8119")); + }, "Test\\x8119"); + + // Compares a wchar_t* to a ::wstring that has different content. + wchar_t* const p1 = const_cast(L"foo"); + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(p1, ::wstring(L"bar")), + "bar"); + + // Compares two ::wstrings that have different contents, one of which + // having a NUL character in the middle. + static ::wstring wstr3; + wstr3 = wstr1; + wstr3.at(2) = L'\0'; + EXPECT_FATAL_FAILURE(ASSERT_EQ(wstr1, wstr3), + "wstr3"); +} + +#endif // GTEST_HAS_GLOBAL_WSTRING + +// Tests using char pointers in {EXPECT|ASSERT}_EQ. +TEST(EqAssertionTest, CharPointer) { + char* const p0 = NULL; + // Only way to get the Nokia compiler to compile the cast + // is to have a separate void* variable first. Putting + // the two casts on the same line doesn't work, neither does + // a direct C-style to char*. + void* pv1 = (void*)0x1234; // NOLINT + void* pv2 = (void*)0xABC0; // NOLINT + char* const p1 = reinterpret_cast(pv1); + char* const p2 = reinterpret_cast(pv2); + ASSERT_EQ(p1, p1); + + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(p0, p2), + "Value of: p2"); + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(p1, p2), + "p2"); + EXPECT_FATAL_FAILURE(ASSERT_EQ(reinterpret_cast(0x1234), + reinterpret_cast(0xABC0)), + "ABC0"); +} + +// Tests using wchar_t pointers in {EXPECT|ASSERT}_EQ. +TEST(EqAssertionTest, WideCharPointer) { + wchar_t* const p0 = NULL; + // Only way to get the Nokia compiler to compile the cast + // is to have a separate void* variable first. Putting + // the two casts on the same line doesn't work, neither does + // a direct C-style to char*. + void* pv1 = (void*)0x1234; // NOLINT + void* pv2 = (void*)0xABC0; // NOLINT + wchar_t* const p1 = reinterpret_cast(pv1); + wchar_t* const p2 = reinterpret_cast(pv2); + EXPECT_EQ(p0, p0); + + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(p0, p2), + "Value of: p2"); + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(p1, p2), + "p2"); + void* pv3 = (void*)0x1234; // NOLINT + void* pv4 = (void*)0xABC0; // NOLINT + const wchar_t* p3 = reinterpret_cast(pv3); + const wchar_t* p4 = reinterpret_cast(pv4); + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(p3, p4), + "p4"); +} + +// Tests using other types of pointers in {EXPECT|ASSERT}_EQ. +TEST(EqAssertionTest, OtherPointer) { + ASSERT_EQ(static_cast(NULL), + static_cast(NULL)); + EXPECT_FATAL_FAILURE(ASSERT_EQ(static_cast(NULL), + reinterpret_cast(0x1234)), + "0x1234"); +} + +// Tests the FRIEND_TEST macro. + +// This class has a private member we want to test. We will test it +// both in a TEST and in a TEST_F. +class Foo { + public: + Foo() {} + + private: + int Bar() const { return 1; } + + // Declares the friend tests that can access the private member + // Bar(). + FRIEND_TEST(FRIEND_TEST_Test, TEST); + FRIEND_TEST(FRIEND_TEST_Test2, TEST_F); +}; + +// Tests that the FRIEND_TEST declaration allows a TEST to access a +// class's private members. This should compile. +TEST(FRIEND_TEST_Test, TEST) { + ASSERT_EQ(1, Foo().Bar()); +} + +// The fixture needed to test using FRIEND_TEST with TEST_F. +class FRIEND_TEST_Test2 : public testing::Test { + protected: + Foo foo; +}; + +// Tests that the FRIEND_TEST declaration allows a TEST_F to access a +// class's private members. This should compile. +TEST_F(FRIEND_TEST_Test2, TEST_F) { + ASSERT_EQ(1, foo.Bar()); +} + +// Tests the life cycle of Test objects. + +// The test fixture for testing the life cycle of Test objects. +// +// This class counts the number of live test objects that uses this +// fixture. +class TestLifeCycleTest : public testing::Test { + protected: + // Constructor. Increments the number of test objects that uses + // this fixture. + TestLifeCycleTest() { count_++; } + + // Destructor. Decrements the number of test objects that uses this + // fixture. + ~TestLifeCycleTest() { count_--; } + + // Returns the number of live test objects that uses this fixture. + int count() const { return count_; } + + private: + static int count_; +}; + +int TestLifeCycleTest::count_ = 0; + +// Tests the life cycle of test objects. +TEST_F(TestLifeCycleTest, Test1) { + // There should be only one test object in this test case that's + // currently alive. + ASSERT_EQ(1, count()); +} + +// Tests the life cycle of test objects. +TEST_F(TestLifeCycleTest, Test2) { + // After Test1 is done and Test2 is started, there should still be + // only one live test object, as the object for Test1 should've been + // deleted. + ASSERT_EQ(1, count()); +} + +} // namespace + +// Tests streaming a user type whose definition and operator << are +// both in the global namespace. +class Base { + public: + explicit Base(int x) : x_(x) {} + int x() const { return x_; } + private: + int x_; +}; +std::ostream& operator<<(std::ostream& os, + const Base& val) { + return os << val.x(); +} +std::ostream& operator<<(std::ostream& os, + const Base* pointer) { + return os << "(" << pointer->x() << ")"; +} + +TEST(MessageTest, CanStreamUserTypeInGlobalNameSpace) { + testing::Message msg; + Base a(1); + + msg << a << &a; // Uses ::operator<<. + EXPECT_STREQ("1(1)", msg.GetString().c_str()); +} + +// Tests streaming a user type whose definition and operator<< are +// both in an unnamed namespace. +namespace { +class MyTypeInUnnamedNameSpace : public Base { + public: + explicit MyTypeInUnnamedNameSpace(int x): Base(x) {} +}; +std::ostream& operator<<(std::ostream& os, + const MyTypeInUnnamedNameSpace& val) { + return os << val.x(); +} +std::ostream& operator<<(std::ostream& os, + const MyTypeInUnnamedNameSpace* pointer) { + return os << "(" << pointer->x() << ")"; +} +} // namespace + +TEST(MessageTest, CanStreamUserTypeInUnnamedNameSpace) { + testing::Message msg; + MyTypeInUnnamedNameSpace a(1); + + msg << a << &a; // Uses ::operator<<. + EXPECT_STREQ("1(1)", msg.GetString().c_str()); +} + +// Tests streaming a user type whose definition and operator<< are +// both in a user namespace. +namespace namespace1 { +class MyTypeInNameSpace1 : public Base { + public: + explicit MyTypeInNameSpace1(int x): Base(x) {} +}; +std::ostream& operator<<(std::ostream& os, + const MyTypeInNameSpace1& val) { + return os << val.x(); +} +std::ostream& operator<<(std::ostream& os, + const MyTypeInNameSpace1* pointer) { + return os << "(" << pointer->x() << ")"; +} +} // namespace namespace1 + +TEST(MessageTest, CanStreamUserTypeInUserNameSpace) { + testing::Message msg; + namespace1::MyTypeInNameSpace1 a(1); + + msg << a << &a; // Uses namespace1::operator<<. + EXPECT_STREQ("1(1)", msg.GetString().c_str()); +} + +// Tests streaming a user type whose definition is in a user namespace +// but whose operator<< is in the global namespace. +namespace namespace2 { +class MyTypeInNameSpace2 : public ::Base { + public: + explicit MyTypeInNameSpace2(int x): Base(x) {} +}; +} // namespace namespace2 +std::ostream& operator<<(std::ostream& os, + const namespace2::MyTypeInNameSpace2& val) { + return os << val.x(); +} +std::ostream& operator<<(std::ostream& os, + const namespace2::MyTypeInNameSpace2* pointer) { + return os << "(" << pointer->x() << ")"; +} + +TEST(MessageTest, CanStreamUserTypeInUserNameSpaceWithStreamOperatorInGlobal) { + testing::Message msg; + namespace2::MyTypeInNameSpace2 a(1); + + msg << a << &a; // Uses ::operator<<. + EXPECT_STREQ("1(1)", msg.GetString().c_str()); +} + +// Tests streaming NULL pointers to testing::Message. +TEST(MessageTest, NullPointers) { + testing::Message msg; + char* const p1 = NULL; + unsigned char* const p2 = NULL; + int* p3 = NULL; + double* p4 = NULL; + bool* p5 = NULL; + testing::Message* p6 = NULL; + + msg << p1 << p2 << p3 << p4 << p5 << p6; + ASSERT_STREQ("(null)(null)(null)(null)(null)(null)", + msg.GetString().c_str()); +} + +// Tests streaming wide strings to testing::Message. +TEST(MessageTest, WideStrings) { + using testing::Message; + + // Streams a NULL of type const wchar_t*. + const wchar_t* const_wstr = NULL; + EXPECT_STREQ("(null)", + (Message() << const_wstr).GetString().c_str()); + + // Streams a NULL of type wchar_t*. + wchar_t* wstr = NULL; + EXPECT_STREQ("(null)", + (Message() << wstr).GetString().c_str()); + + // Streams a non-NULL of type const wchar_t*. + const_wstr = L"abc\x8119"; + EXPECT_STREQ("abc\xe8\x84\x99", + (Message() << const_wstr).GetString().c_str()); + + // Streams a non-NULL of type wchar_t*. + wstr = const_cast(const_wstr); + EXPECT_STREQ("abc\xe8\x84\x99", + (Message() << wstr).GetString().c_str()); +} + + +// This line tests that we can define tests in the testing namespace. +namespace testing { + +// Tests the TestInfo class. + +class TestInfoTest : public testing::Test { + protected: + static TestInfo * GetTestInfo(const char* test_name) { + return UnitTest::GetInstance()->impl()-> + GetTestCase("TestInfoTest", NULL, NULL)-> + GetTestInfo(test_name); + } + + static const TestResult* GetTestResult( + const testing::TestInfo* test_info) { + return test_info->result(); + } +}; + +// Tests TestInfo::test_case_name() and TestInfo::name(). +TEST_F(TestInfoTest, Names) { + TestInfo * const test_info = GetTestInfo("Names"); + + ASSERT_STREQ("TestInfoTest", test_info->test_case_name()); + ASSERT_STREQ("Names", test_info->name()); +} + +// Tests TestInfo::result(). +TEST_F(TestInfoTest, result) { + TestInfo * const test_info = GetTestInfo("result"); + + // Initially, there is no TestPartResult for this test. + ASSERT_EQ(0u, GetTestResult(test_info)->total_part_count()); + + // After the previous assertion, there is still none. + ASSERT_EQ(0u, GetTestResult(test_info)->total_part_count()); +} + +// Tests setting up and tearing down a test case. + +class SetUpTestCaseTest : public testing::Test { + protected: + // This will be called once before the first test in this test case + // is run. + static void SetUpTestCase() { + printf("Setting up the test case . . .\n"); + + // Initializes some shared resource. In this simple example, we + // just create a C string. More complex stuff can be done if + // desired. + shared_resource_ = "123"; + + // Increments the number of test cases that have been set up. + counter_++; + + // SetUpTestCase() should be called only once. + EXPECT_EQ(1, counter_); + } + + // This will be called once after the last test in this test case is + // run. + static void TearDownTestCase() { + printf("Tearing down the test case . . .\n"); + + // Decrements the number of test cases that have been set up. + counter_--; + + // TearDownTestCase() should be called only once. + EXPECT_EQ(0, counter_); + + // Cleans up the shared resource. + shared_resource_ = NULL; + } + + // This will be called before each test in this test case. + virtual void SetUp() { + // SetUpTestCase() should be called only once, so counter_ should + // always be 1. + EXPECT_EQ(1, counter_); + } + + // Number of test cases that have been set up. + static int counter_; + + // Some resource to be shared by all tests in this test case. + static const char* shared_resource_; +}; + +int SetUpTestCaseTest::counter_ = 0; +const char* SetUpTestCaseTest::shared_resource_ = NULL; + +// A test that uses the shared resource. +TEST_F(SetUpTestCaseTest, Test1) { + EXPECT_STRNE(NULL, shared_resource_); +} + +// Another test that uses the shared resource. +TEST_F(SetUpTestCaseTest, Test2) { + EXPECT_STREQ("123", shared_resource_); +} + +// The InitGoogleTestTest test case tests testing::InitGoogleTest(). + +// The Flags struct stores a copy of all Google Test flags. +struct Flags { + // Constructs a Flags struct where each flag has its default value. + Flags() : break_on_failure(false), + catch_exceptions(false), + filter(""), + list_tests(false), + output(""), + repeat(1) {} + + // Factory methods. + + // Creates a Flags struct where the gtest_break_on_failure flag has + // the given value. + static Flags BreakOnFailure(bool break_on_failure) { + Flags flags; + flags.break_on_failure = break_on_failure; + return flags; + } + + // Creates a Flags struct where the gtest_catch_exceptions flag has + // the given value. + static Flags CatchExceptions(bool catch_exceptions) { + Flags flags; + flags.catch_exceptions = catch_exceptions; + return flags; + } + + // Creates a Flags struct where the gtest_filter flag has the given + // value. + static Flags Filter(const char* filter) { + Flags flags; + flags.filter = filter; + return flags; + } + + // Creates a Flags struct where the gtest_list_tests flag has the + // given value. + static Flags ListTests(bool list_tests) { + Flags flags; + flags.list_tests = list_tests; + return flags; + } + + // Creates a Flags struct where the gtest_output flag has the given + // value. + static Flags Output(const char* output) { + Flags flags; + flags.output = output; + return flags; + } + + // Creates a Flags struct where the gtest_repeat flag has the given + // value. + static Flags Repeat(Int32 repeat) { + Flags flags; + flags.repeat = repeat; + return flags; + } + + // These fields store the flag values. + bool break_on_failure; + bool catch_exceptions; + const char* filter; + bool list_tests; + const char* output; + Int32 repeat; +}; + +// Fixture for testing InitGoogleTest(). +class InitGoogleTestTest : public testing::Test { + protected: + // Clears the flags before each test. + virtual void SetUp() { + GTEST_FLAG(break_on_failure) = false; + GTEST_FLAG(catch_exceptions) = false; + GTEST_FLAG(filter) = ""; + GTEST_FLAG(list_tests) = false; + GTEST_FLAG(output) = ""; + GTEST_FLAG(repeat) = 1; + } + + // Asserts that two narrow or wide string arrays are equal. + template + static void AssertStringArrayEq(size_t size1, CharType** array1, + size_t size2, CharType** array2) { + ASSERT_EQ(size1, size2) << " Array sizes different."; + + for (size_t i = 0; i != size1; i++) { + ASSERT_STREQ(array1[i], array2[i]) << " where i == " << i; + } + } + + // Verifies that the flag values match the expected values. + static void CheckFlags(const Flags& expected) { + EXPECT_EQ(expected.break_on_failure, GTEST_FLAG(break_on_failure)); + EXPECT_EQ(expected.catch_exceptions, GTEST_FLAG(catch_exceptions)); + EXPECT_STREQ(expected.filter, GTEST_FLAG(filter).c_str()); + EXPECT_EQ(expected.list_tests, GTEST_FLAG(list_tests)); + EXPECT_STREQ(expected.output, GTEST_FLAG(output).c_str()); + EXPECT_EQ(expected.repeat, GTEST_FLAG(repeat)); + } + + // Parses a command line (specified by argc1 and argv1), then + // verifies that the flag values are expected and that the + // recognized flags are removed from the command line. + template + static void TestParsingFlags(int argc1, const CharType** argv1, + int argc2, const CharType** argv2, + const Flags& expected) { + // Parses the command line. + InitGoogleTest(&argc1, const_cast(argv1)); + + // Verifies the flag values. + CheckFlags(expected); + + // Verifies that the recognized flags are removed from the command + // line. + AssertStringArrayEq(argc1 + 1, argv1, argc2 + 1, argv2); + } + + // This macro wraps TestParsingFlags s.t. the user doesn't need + // to specify the array sizes. +#define TEST_PARSING_FLAGS(argv1, argv2, expected) \ + TestParsingFlags(sizeof(argv1)/sizeof(*argv1) - 1, argv1, \ + sizeof(argv2)/sizeof(*argv2) - 1, argv2, expected) +}; + +// Tests parsing an empty command line. +TEST_F(InitGoogleTestTest, Empty) { + const char* argv[] = { + NULL + }; + + const char* argv2[] = { + NULL + }; + + TEST_PARSING_FLAGS(argv, argv2, Flags()); +} + +// Tests parsing a command line that has no flag. +TEST_F(InitGoogleTestTest, NoFlag) { + const char* argv[] = { + "foo.exe", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + TEST_PARSING_FLAGS(argv, argv2, Flags()); +} + +// Tests parsing a bad --gtest_filter flag. +TEST_F(InitGoogleTestTest, FilterBad) { + const char* argv[] = { + "foo.exe", + "--gtest_filter", + NULL + }; + + const char* argv2[] = { + "foo.exe", + "--gtest_filter", + NULL + }; + + TEST_PARSING_FLAGS(argv, argv2, Flags::Filter("")); +} + +// Tests parsing an empty --gtest_filter flag. +TEST_F(InitGoogleTestTest, FilterEmpty) { + const char* argv[] = { + "foo.exe", + "--gtest_filter=", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + TEST_PARSING_FLAGS(argv, argv2, Flags::Filter("")); +} + +// Tests parsing a non-empty --gtest_filter flag. +TEST_F(InitGoogleTestTest, FilterNonEmpty) { + const char* argv[] = { + "foo.exe", + "--gtest_filter=abc", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + TEST_PARSING_FLAGS(argv, argv2, Flags::Filter("abc")); +} + +// Tests parsing --gtest_break_on_failure. +TEST_F(InitGoogleTestTest, BreakOnFailureNoDef) { + const char* argv[] = { + "foo.exe", + "--gtest_break_on_failure", + NULL +}; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + TEST_PARSING_FLAGS(argv, argv2, Flags::BreakOnFailure(true)); +} + +// Tests parsing --gtest_break_on_failure=0. +TEST_F(InitGoogleTestTest, BreakOnFailureFalse_0) { + const char* argv[] = { + "foo.exe", + "--gtest_break_on_failure=0", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + TEST_PARSING_FLAGS(argv, argv2, Flags::BreakOnFailure(false)); +} + +// Tests parsing --gtest_break_on_failure=f. +TEST_F(InitGoogleTestTest, BreakOnFailureFalse_f) { + const char* argv[] = { + "foo.exe", + "--gtest_break_on_failure=f", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + TEST_PARSING_FLAGS(argv, argv2, Flags::BreakOnFailure(false)); +} + +// Tests parsing --gtest_break_on_failure=F. +TEST_F(InitGoogleTestTest, BreakOnFailureFalse_F) { + const char* argv[] = { + "foo.exe", + "--gtest_break_on_failure=F", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + TEST_PARSING_FLAGS(argv, argv2, Flags::BreakOnFailure(false)); +} + +// Tests parsing a --gtest_break_on_failure flag that has a "true" +// definition. +TEST_F(InitGoogleTestTest, BreakOnFailureTrue) { + const char* argv[] = { + "foo.exe", + "--gtest_break_on_failure=1", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + TEST_PARSING_FLAGS(argv, argv2, Flags::BreakOnFailure(true)); +} + +// Tests parsing --gtest_catch_exceptions. +TEST_F(InitGoogleTestTest, CatchExceptions) { + const char* argv[] = { + "foo.exe", + "--gtest_catch_exceptions", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + TEST_PARSING_FLAGS(argv, argv2, Flags::CatchExceptions(true)); +} + +// Tests having the same flag twice with different values. The +// expected behavior is that the one coming last takes precedence. +TEST_F(InitGoogleTestTest, DuplicatedFlags) { + const char* argv[] = { + "foo.exe", + "--gtest_filter=a", + "--gtest_filter=b", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + TEST_PARSING_FLAGS(argv, argv2, Flags::Filter("b")); +} + +// Tests having an unrecognized flag on the command line. +TEST_F(InitGoogleTestTest, UnrecognizedFlag) { + const char* argv[] = { + "foo.exe", + "--gtest_break_on_failure", + "bar", // Unrecognized by Google Test. + "--gtest_filter=b", + NULL + }; + + const char* argv2[] = { + "foo.exe", + "bar", + NULL + }; + + Flags flags; + flags.break_on_failure = true; + flags.filter = "b"; + TEST_PARSING_FLAGS(argv, argv2, flags); +} + +// Tests having a --gtest_list_tests flag +TEST_F(InitGoogleTestTest, ListTestsFlag) { + const char* argv[] = { + "foo.exe", + "--gtest_list_tests", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + TEST_PARSING_FLAGS(argv, argv2, Flags::ListTests(true)); +} + +// Tests having a --gtest_list_tests flag with a "true" value +TEST_F(InitGoogleTestTest, ListTestsTrue) { + const char* argv[] = { + "foo.exe", + "--gtest_list_tests=1", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + TEST_PARSING_FLAGS(argv, argv2, Flags::ListTests(true)); +} + +// Tests having a --gtest_list_tests flag with a "false" value +TEST_F(InitGoogleTestTest, ListTestsFalse) { + const char* argv[] = { + "foo.exe", + "--gtest_list_tests=0", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + TEST_PARSING_FLAGS(argv, argv2, Flags::ListTests(false)); +} + +// Tests parsing --gtest_list_tests=f. +TEST_F(InitGoogleTestTest, ListTestsFalse_f) { + const char* argv[] = { + "foo.exe", + "--gtest_list_tests=f", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + TEST_PARSING_FLAGS(argv, argv2, Flags::ListTests(false)); +} + +// Tests parsing --gtest_break_on_failure=F. +TEST_F(InitGoogleTestTest, ListTestsFalse_F) { + const char* argv[] = { + "foo.exe", + "--gtest_list_tests=F", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + TEST_PARSING_FLAGS(argv, argv2, Flags::ListTests(false)); +} + +// Tests parsing --gtest_output (invalid). +TEST_F(InitGoogleTestTest, OutputEmpty) { + const char* argv[] = { + "foo.exe", + "--gtest_output", + NULL + }; + + const char* argv2[] = { + "foo.exe", + "--gtest_output", + NULL + }; + + TEST_PARSING_FLAGS(argv, argv2, Flags()); +} + +// Tests parsing --gtest_output=xml +TEST_F(InitGoogleTestTest, OutputXml) { + const char* argv[] = { + "foo.exe", + "--gtest_output=xml", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + TEST_PARSING_FLAGS(argv, argv2, Flags::Output("xml")); +} + +// Tests parsing --gtest_output=xml:file +TEST_F(InitGoogleTestTest, OutputXmlFile) { + const char* argv[] = { + "foo.exe", + "--gtest_output=xml:file", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + TEST_PARSING_FLAGS(argv, argv2, Flags::Output("xml:file")); +} + +// Tests parsing --gtest_output=xml:directory/path/ +TEST_F(InitGoogleTestTest, OutputXmlDirectory) { + const char* argv[] = { + "foo.exe", + "--gtest_output=xml:directory/path/", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + TEST_PARSING_FLAGS(argv, argv2, Flags::Output("xml:directory/path/")); +} + +// Tests parsing --gtest_repeat=number +TEST_F(InitGoogleTestTest, Repeat) { + const char* argv[] = { + "foo.exe", + "--gtest_repeat=1000", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + TEST_PARSING_FLAGS(argv, argv2, Flags::Repeat(1000)); +} + +#ifdef GTEST_OS_WINDOWS +// Tests parsing wide strings. +TEST_F(InitGoogleTestTest, WideStrings) { + const wchar_t* argv[] = { + L"foo.exe", + L"--gtest_filter=Foo*", + L"--gtest_list_tests=1", + L"--gtest_break_on_failure", + L"--non_gtest_flag", + NULL + }; + + const wchar_t* argv2[] = { + L"foo.exe", + L"--non_gtest_flag", + NULL + }; + + Flags expected_flags; + expected_flags.break_on_failure = true; + expected_flags.filter = "Foo*"; + expected_flags.list_tests = true; + + TEST_PARSING_FLAGS(argv, argv2, expected_flags); +} +#endif // GTEST_OS_WINDOWS + +// Tests current_test_info() in UnitTest. +class CurrentTestInfoTest : public Test { + protected: + // Tests that current_test_info() returns NULL before the first test in + // the test case is run. + static void SetUpTestCase() { + // There should be no tests running at this point. + const TestInfo* test_info = + UnitTest::GetInstance()->current_test_info(); + EXPECT_EQ(NULL, test_info) + << "There should be no tests running at this point."; + } + + // Tests that current_test_info() returns NULL after the last test in + // the test case has run. + static void TearDownTestCase() { + const TestInfo* test_info = + UnitTest::GetInstance()->current_test_info(); + EXPECT_EQ(NULL, test_info) + << "There should be no tests running at this point."; + } +}; + +// Tests that current_test_info() returns TestInfo for currently running +// test by checking the expected test name against the actual one. +TEST_F(CurrentTestInfoTest, WorksForFirstTestInATestCase) { + const TestInfo* test_info = + UnitTest::GetInstance()->current_test_info(); + ASSERT_TRUE(NULL != test_info) + << "There is a test running so we should have a valid TestInfo."; + EXPECT_STREQ("CurrentTestInfoTest", test_info->test_case_name()) + << "Expected the name of the currently running test case."; + EXPECT_STREQ("WorksForFirstTestInATestCase", test_info->name()) + << "Expected the name of the currently running test."; +} + +// Tests that current_test_info() returns TestInfo for currently running +// test by checking the expected test name against the actual one. We +// use this test to see that the TestInfo object actually changed from +// the previous invocation. +TEST_F(CurrentTestInfoTest, WorksForSecondTestInATestCase) { + const TestInfo* test_info = + UnitTest::GetInstance()->current_test_info(); + ASSERT_TRUE(NULL != test_info) + << "There is a test running so we should have a valid TestInfo."; + EXPECT_STREQ("CurrentTestInfoTest", test_info->test_case_name()) + << "Expected the name of the currently running test case."; + EXPECT_STREQ("WorksForSecondTestInATestCase", test_info->name()) + << "Expected the name of the currently running test."; +} + +} // namespace testing + +// These two lines test that we can define tests in a namespace that +// has the name "testing" and is nested in another namespace. +namespace my_namespace { +namespace testing { + +// Makes sure that TEST knows to use ::testing::Test instead of +// ::my_namespace::testing::Test. +class Test {}; + +// Makes sure that an assertion knows to use ::testing::Message instead of +// ::my_namespace::testing::Message. +class Message {}; + +// Makes sure that an assertion knows to use +// ::testing::AssertionResult instead of +// ::my_namespace::testing::AssertionResult. +class AssertionResult {}; + +// Tests that an assertion that should succeed works as expected. +TEST(NestedTestingNamespaceTest, Success) { + EXPECT_EQ(1, 1) << "This shouldn't fail."; +} + +// Tests that an assertion that should fail works as expected. +TEST(NestedTestingNamespaceTest, Failure) { + EXPECT_FATAL_FAILURE(FAIL() << "This failure is expected.", + "This failure is expected."); +} + +} // namespace testing +} // namespace my_namespace + +// Tests that one can call superclass SetUp and TearDown methods-- +// that is, that they are not private. +// No tests are based on this fixture; the test "passes" if it compiles +// successfully. +class ProtectedFixtureMethodsTest : public testing::Test { + protected: + virtual void SetUp() { + testing::Test::SetUp(); + } + virtual void TearDown() { + testing::Test::TearDown(); + } +}; + +// StreamingAssertionsTest tests the streaming versions of a representative +// sample of assertions. +TEST(StreamingAssertionsTest, Unconditional) { + SUCCEED() << "expected success"; + EXPECT_NONFATAL_FAILURE(ADD_FAILURE() << "expected failure", + "expected failure"); + EXPECT_FATAL_FAILURE(FAIL() << "expected failure", + "expected failure"); +} + +TEST(StreamingAssertionsTest, Truth) { + EXPECT_TRUE(true) << "unexpected failure"; + ASSERT_TRUE(true) << "unexpected failure"; + EXPECT_NONFATAL_FAILURE(EXPECT_TRUE(false) << "expected failure", + "expected failure"); + EXPECT_FATAL_FAILURE(ASSERT_TRUE(false) << "expected failure", + "expected failure"); +} + +TEST(StreamingAssertionsTest, Truth2) { + EXPECT_FALSE(false) << "unexpected failure"; + ASSERT_FALSE(false) << "unexpected failure"; + EXPECT_NONFATAL_FAILURE(EXPECT_FALSE(true) << "expected failure", + "expected failure"); + EXPECT_FATAL_FAILURE(ASSERT_FALSE(true) << "expected failure", + "expected failure"); +} + +TEST(StreamingAssertionsTest, IntegerEquals) { + EXPECT_EQ(1, 1) << "unexpected failure"; + ASSERT_EQ(1, 1) << "unexpected failure"; + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(1, 2) << "expected failure", + "expected failure"); + EXPECT_FATAL_FAILURE(ASSERT_EQ(1, 2) << "expected failure", + "expected failure"); +} + +TEST(StreamingAssertionsTest, IntegerLessThan) { + EXPECT_LT(1, 2) << "unexpected failure"; + ASSERT_LT(1, 2) << "unexpected failure"; + EXPECT_NONFATAL_FAILURE(EXPECT_LT(2, 1) << "expected failure", + "expected failure"); + EXPECT_FATAL_FAILURE(ASSERT_LT(2, 1) << "expected failure", + "expected failure"); +} + +TEST(StreamingAssertionsTest, StringsEqual) { + EXPECT_STREQ("foo", "foo") << "unexpected failure"; + ASSERT_STREQ("foo", "foo") << "unexpected failure"; + EXPECT_NONFATAL_FAILURE(EXPECT_STREQ("foo", "bar") << "expected failure", + "expected failure"); + EXPECT_FATAL_FAILURE(ASSERT_STREQ("foo", "bar") << "expected failure", + "expected failure"); +} + +TEST(StreamingAssertionsTest, StringsNotEqual) { + EXPECT_STRNE("foo", "bar") << "unexpected failure"; + ASSERT_STRNE("foo", "bar") << "unexpected failure"; + EXPECT_NONFATAL_FAILURE(EXPECT_STRNE("foo", "foo") << "expected failure", + "expected failure"); + EXPECT_FATAL_FAILURE(ASSERT_STRNE("foo", "foo") << "expected failure", + "expected failure"); +} + +TEST(StreamingAssertionsTest, StringsEqualIgnoringCase) { + EXPECT_STRCASEEQ("foo", "FOO") << "unexpected failure"; + ASSERT_STRCASEEQ("foo", "FOO") << "unexpected failure"; + EXPECT_NONFATAL_FAILURE(EXPECT_STRCASEEQ("foo", "bar") << "expected failure", + "expected failure"); + EXPECT_FATAL_FAILURE(ASSERT_STRCASEEQ("foo", "bar") << "expected failure", + "expected failure"); +} + +TEST(StreamingAssertionsTest, StringNotEqualIgnoringCase) { + EXPECT_STRCASENE("foo", "bar") << "unexpected failure"; + ASSERT_STRCASENE("foo", "bar") << "unexpected failure"; + EXPECT_NONFATAL_FAILURE(EXPECT_STRCASENE("foo", "FOO") << "expected failure", + "expected failure"); + EXPECT_FATAL_FAILURE(ASSERT_STRCASENE("bar", "BAR") << "expected failure", + "expected failure"); +} + +TEST(StreamingAssertionsTest, FloatingPointEquals) { + EXPECT_FLOAT_EQ(1.0, 1.0) << "unexpected failure"; + ASSERT_FLOAT_EQ(1.0, 1.0) << "unexpected failure"; + EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(0.0, 1.0) << "expected failure", + "expected failure"); + EXPECT_FATAL_FAILURE(ASSERT_FLOAT_EQ(0.0, 1.0) << "expected failure", + "expected failure"); +} + +// Tests that Google Test correctly decides whether to use colors in the output. + +TEST(ColoredOutputTest, UsesColorsWhenGTestColorFlagIsYes) { + GTEST_FLAG(color) = "yes"; + + SetEnv("TERM", "xterm"); // TERM supports colors. + EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY. + EXPECT_TRUE(ShouldUseColor(false)); // Stdout is not a TTY. + + SetEnv("TERM", "dumb"); // TERM doesn't support colors. + EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY. + EXPECT_TRUE(ShouldUseColor(false)); // Stdout is not a TTY. +} + +TEST(ColoredOutputTest, UsesColorsWhenGTestColorFlagIsAliasOfYes) { + SetEnv("TERM", "dumb"); // TERM doesn't support colors. + + GTEST_FLAG(color) = "True"; + EXPECT_TRUE(ShouldUseColor(false)); // Stdout is not a TTY. + + GTEST_FLAG(color) = "t"; + EXPECT_TRUE(ShouldUseColor(false)); // Stdout is not a TTY. + + GTEST_FLAG(color) = "1"; + EXPECT_TRUE(ShouldUseColor(false)); // Stdout is not a TTY. +} + +TEST(ColoredOutputTest, UsesNoColorWhenGTestColorFlagIsNo) { + GTEST_FLAG(color) = "no"; + + SetEnv("TERM", "xterm"); // TERM supports colors. + EXPECT_FALSE(ShouldUseColor(true)); // Stdout is a TTY. + EXPECT_FALSE(ShouldUseColor(false)); // Stdout is not a TTY. + + SetEnv("TERM", "dumb"); // TERM doesn't support colors. + EXPECT_FALSE(ShouldUseColor(true)); // Stdout is a TTY. + EXPECT_FALSE(ShouldUseColor(false)); // Stdout is not a TTY. +} + +TEST(ColoredOutputTest, UsesNoColorWhenGTestColorFlagIsInvalid) { + SetEnv("TERM", "xterm"); // TERM supports colors. + + GTEST_FLAG(color) = "F"; + EXPECT_FALSE(ShouldUseColor(true)); // Stdout is a TTY. + + GTEST_FLAG(color) = "0"; + EXPECT_FALSE(ShouldUseColor(true)); // Stdout is a TTY. + + GTEST_FLAG(color) = "unknown"; + EXPECT_FALSE(ShouldUseColor(true)); // Stdout is a TTY. +} + +TEST(ColoredOutputTest, UsesColorsWhenStdoutIsTty) { + GTEST_FLAG(color) = "auto"; + + SetEnv("TERM", "xterm"); // TERM supports colors. + EXPECT_FALSE(ShouldUseColor(false)); // Stdout is not a TTY. + EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY. +} + +TEST(ColoredOutputTest, UsesColorsWhenTermSupportsColors) { + GTEST_FLAG(color) = "auto"; + +#ifdef GTEST_OS_WINDOWS + // On Windows, we ignore the TERM variable as it's usually not set. + + SetEnv("TERM", "dumb"); + EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY. + + SetEnv("TERM", ""); + EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY. + + SetEnv("TERM", "xterm"); + EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY. +#else + // On non-Windows platforms, we rely on TERM to determine if the + // terminal supports colors. + + SetEnv("TERM", "dumb"); // TERM doesn't support colors. + EXPECT_FALSE(ShouldUseColor(true)); // Stdout is a TTY. + + SetEnv("TERM", "emacs"); // TERM doesn't support colors. + EXPECT_FALSE(ShouldUseColor(true)); // Stdout is a TTY. + + SetEnv("TERM", "vt100"); // TERM doesn't support colors. + EXPECT_FALSE(ShouldUseColor(true)); // Stdout is a TTY. + + SetEnv("TERM", "xterm-mono"); // TERM doesn't support colors. + EXPECT_FALSE(ShouldUseColor(true)); // Stdout is a TTY. + + SetEnv("TERM", "xterm"); // TERM supports colors. + EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY. + + SetEnv("TERM", "xterm-color"); // TERM supports colors. + EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY. +#endif // GTEST_OS_WINDOWS +} + +#ifndef __SYMBIAN32__ +// We will want to integrate running the unittests to a different +// main application on Symbian. +int main(int argc, char** argv) { + testing::InitGoogleTest(&argc, argv); + +#ifdef GTEST_HAS_DEATH_TEST + if (!testing::internal::GTEST_FLAG(internal_run_death_test).empty()) { + // Skip the usual output capturing if we're running as the child + // process of an threadsafe-style death test. + freopen("/dev/null", "w", stdout); + } +#endif // GTEST_HAS_DEATH_TEST + + // Runs all tests using Google Test. + return RUN_ALL_TESTS(); +} +#endif // __SYMBIAN32_ diff --git a/test/gtest_xml_outfile1_test_.cc b/test/gtest_xml_outfile1_test_.cc new file mode 100644 index 00000000..664baad2 --- /dev/null +++ b/test/gtest_xml_outfile1_test_.cc @@ -0,0 +1,49 @@ +// Copyright 2008, 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: keith.ray@gmail.com (Keith Ray) +// +// gtest_xml_outfile1_test_ writes some xml via TestProperty used by +// gtest_xml_outfiles_test.py + +#include + +class PropertyOne : public testing::Test { + protected: + virtual void SetUp() { + RecordProperty("SetUpProp", 1); + } + virtual void TearDown() { + RecordProperty("TearDownProp", 1); + } +}; + +TEST_F(PropertyOne, TestSomeProperties) { + RecordProperty("TestSomeProperty", 1); +} diff --git a/test/gtest_xml_outfile2_test_.cc b/test/gtest_xml_outfile2_test_.cc new file mode 100644 index 00000000..3411a3d3 --- /dev/null +++ b/test/gtest_xml_outfile2_test_.cc @@ -0,0 +1,49 @@ +// Copyright 2008, 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: keith.ray@gmail.com (Keith Ray) +// +// gtest_xml_outfile2_test_ writes some xml via TestProperty used by +// gtest_xml_outfiles_test.py + +#include + +class PropertyTwo : public testing::Test { + protected: + virtual void SetUp() { + RecordProperty("SetUpProp", 2); + } + virtual void TearDown() { + RecordProperty("TearDownProp", 2); + } +}; + +TEST_F(PropertyTwo, TestSomeProperties) { + RecordProperty("TestSomeProperty", 2); +} diff --git a/test/gtest_xml_outfiles_test.py b/test/gtest_xml_outfiles_test.py new file mode 100755 index 00000000..df0b95bc --- /dev/null +++ b/test/gtest_xml_outfiles_test.py @@ -0,0 +1,134 @@ +#!/usr/bin/env python +# +# Copyright 2008, 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. + +"""Unit test for the gtest_xml_output module.""" + +__author__ = "keith.ray@gmail.com (Keith Ray)" + +import gtest_test_utils +import os +import sys +import tempfile +import unittest + +from xml.dom import minidom, Node + +import gtest_xml_test_utils + + +GTEST_OUTPUT_1_TEST = "gtest_xml_outfile1_test_" +GTEST_OUTPUT_2_TEST = "gtest_xml_outfile2_test_" + +EXPECTED_XML_1 = """ + + + + + +""" + +EXPECTED_XML_2 = """ + + + + + +""" + + +class GTestXMLOutFilesTest(gtest_xml_test_utils.GTestXMLTestCase): + """Unit test for Google Test's XML output functionality.""" + + def setUp(self): + # We want the trailing '/' that the last "" provides in os.path.join, for + # telling Google Test to create an output directory instead of a single file + # for xml output. + self.output_dir_ = os.path.join(tempfile.mkdtemp(), "") + self.DeleteFilesAndDir() + + def tearDown(self): + self.DeleteFilesAndDir() + + def DeleteFilesAndDir(self): + try: + os.remove(os.path.join(self.output_dir_, GTEST_OUTPUT_1_TEST + ".xml")) + except os.error: + pass + try: + os.remove(os.path.join(self.output_dir_, GTEST_OUTPUT_2_TEST + ".xml")) + except os.error: + pass + try: + os.removedirs(self.output_dir_) + except os.error: + pass + + def testOutfile1(self): + self._TestOutFile(GTEST_OUTPUT_1_TEST, EXPECTED_XML_1) + + def testOutfile2(self): + self._TestOutFile(GTEST_OUTPUT_2_TEST, EXPECTED_XML_2) + + def _TestOutFile(self, test_name, expected_xml): + gtest_prog_path = os.path.join(gtest_test_utils.GetBuildDir(), + test_name) + command = "cd %s && %s --gtest_output=xml:%s &> /dev/null" % ( + tempfile.mkdtemp(), gtest_prog_path, self.output_dir_) + status = os.system(command) + self.assertEquals(0, status) + + # TODO(wan@google.com): libtool causes the built test binary to be + # named lt-gtest_xml_outfiles_test_ instead of + # gtest_xml_outfiles_test_. To account for this possibillity, we + # allow both names in the following code. We should remove this + # hack when Chandler Carruth's libtool replacement tool is ready. + output_file_name1 = test_name + ".xml" + output_file1 = os.path.join(self.output_dir_, output_file_name1) + output_file_name2 = 'lt-' + output_file_name1 + output_file2 = os.path.join(self.output_dir_, output_file_name2) + self.assert_(os.path.isfile(output_file1) or os.path.isfile(output_file2), + output_file1) + + expected = minidom.parseString(expected_xml) + if os.path.isfile(output_file1): + actual = minidom.parse(output_file1) + else: + actual = minidom.parse(output_file2) + self._NormalizeXml(actual.documentElement) + self._AssertEquivalentElements(expected.documentElement, + actual.documentElement) + expected.unlink() + actual.unlink() + + +if __name__ == "__main__": + os.environ["GTEST_STACK_TRACE_DEPTH"] = "0" + gtest_test_utils.Main() diff --git a/test/gtest_xml_output_unittest.py b/test/gtest_xml_output_unittest.py new file mode 100755 index 00000000..af021a9f --- /dev/null +++ b/test/gtest_xml_output_unittest.py @@ -0,0 +1,171 @@ +#!/usr/bin/env python +# +# Copyright 2006, 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. + +"""Unit test for the gtest_xml_output module""" + +__author__ = 'eefacm@gmail.com (Sean Mcafee)' + +import errno +import gtest_test_utils +import os +import sys +import tempfile +import unittest + +from xml.dom import minidom, Node + +import gtest_xml_test_utils + +GTEST_OUTPUT_FLAG = "--gtest_output" +GTEST_DEFAULT_OUTPUT_FILE = "test_detail.xml" + +EXPECTED_NON_EMPTY_XML = """ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +""" + + +EXPECTED_EMPTY_XML = """ + +""" + + +class GTestXMLOutputUnitTest(gtest_xml_test_utils.GTestXMLTestCase): + """ + Unit test for Google Test's XML output functionality. + """ + + def testNonEmptyXmlOutput(self): + """ + Runs a test program that generates a non-empty XML output, and + tests that the XML output is expected. + """ + self._TestXmlOutput("gtest_xml_output_unittest_", + EXPECTED_NON_EMPTY_XML, 1) + + def testEmptyXmlOutput(self): + """ + Runs a test program that generates an empty XML output, and + tests that the XML output is expected. + """ + + self._TestXmlOutput("gtest_no_test_unittest", + EXPECTED_EMPTY_XML, 0) + + def testDefaultOutputFile(self): + """ + Confirms that Google Test produces an XML output file with the expected + default name if no name is explicitly specified. + """ + temp_dir = tempfile.mkdtemp() + output_file = os.path.join(temp_dir, + GTEST_DEFAULT_OUTPUT_FILE) + gtest_prog_path = os.path.join(gtest_test_utils.GetBuildDir(), + "gtest_no_test_unittest") + try: + os.remove(output_file) + except OSError, e: + if e.errno != errno.ENOENT: + raise + + status = os.system("cd %s && %s %s=xml &> /dev/null" + % (temp_dir, gtest_prog_path, + GTEST_OUTPUT_FLAG)) + self.assertEquals(0, status) + self.assert_(os.path.isfile(output_file)) + + + def _TestXmlOutput(self, gtest_prog_name, expected_xml, expected_exit_code): + """ + Asserts that the XML document generated by running the program + gtest_prog_name matches expected_xml, a string containing another + XML document. Furthermore, the program's exit code must be + expected_exit_code. + """ + + xml_path = os.path.join(tempfile.mkdtemp(), gtest_prog_name + "out.xml") + gtest_prog_path = os.path.join(gtest_test_utils.GetBuildDir(), + gtest_prog_name) + + command = ("%s %s=xml:%s &> /dev/null" + % (gtest_prog_path, GTEST_OUTPUT_FLAG, xml_path)) + status = os.system(command) + signal = status & 0xff + self.assertEquals(0, signal, + "%s was killed by signal %d" % (gtest_prog_name, signal)) + exit_code = status >> 8 + self.assertEquals(expected_exit_code, exit_code, + "'%s' exited with code %s, which doesn't match " + "the expected exit code %s." + % (command, exit_code, expected_exit_code)) + + expected = minidom.parseString(expected_xml) + actual = minidom.parse(xml_path) + self._NormalizeXml(actual.documentElement) + self._AssertEquivalentElements(expected.documentElement, + actual.documentElement) + expected.unlink() + actual .unlink() + + + +if __name__ == '__main__': + os.environ['GTEST_STACK_TRACE_DEPTH'] = '0' + gtest_test_utils.Main() diff --git a/test/gtest_xml_output_unittest_.cc b/test/gtest_xml_output_unittest_.cc new file mode 100644 index 00000000..d7ce2c6f --- /dev/null +++ b/test/gtest_xml_output_unittest_.cc @@ -0,0 +1,120 @@ +// Copyright 2006, 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: eefacm@gmail.com (Sean Mcafee) + +// Unit test for Google Test XML output. +// +// A user can specify XML output in a Google Test program to run via +// either the GTEST_OUTPUT environment variable or the --gtest_output +// flag. This is used for testing such functionality. +// +// This program will be invoked from a Python unit test. Don't run it +// directly. + +#include + +class SuccessfulTest : public testing::Test { +}; + +TEST_F(SuccessfulTest, Succeeds) { + SUCCEED() << "This is a success."; + ASSERT_EQ(1, 1); +} + +class FailedTest : public testing::Test { +}; + +TEST_F(FailedTest, Fails) { + ASSERT_EQ(1, 2); +} + +class DisabledTest : public testing::Test { +}; + +TEST_F(DisabledTest, DISABLED_test_not_run) { + FAIL() << "Unexpected failure: Disabled test should not be run"; +} + +TEST(MixedResultTest, Succeeds) { + EXPECT_EQ(1, 1); + ASSERT_EQ(1, 1); +} + +TEST(MixedResultTest, Fails) { + EXPECT_EQ(1, 2); + ASSERT_EQ(2, 3); +} + +TEST(MixedResultTest, DISABLED_test) { + FAIL() << "Unexpected failure: Disabled test should not be run"; +} + +class PropertyRecordingTest : public testing::Test { +}; + +TEST_F(PropertyRecordingTest, OneProperty) { + RecordProperty("key_1", "1"); +} + +TEST_F(PropertyRecordingTest, IntValuedProperty) { + RecordProperty("key_int", 1); +} + +TEST_F(PropertyRecordingTest, ThreeProperties) { + RecordProperty("key_1", "1"); + RecordProperty("key_2", "2"); + RecordProperty("key_3", "3"); +} + +TEST_F(PropertyRecordingTest, TwoValuesForOneKeyUsesLastValue) { + RecordProperty("key_1", "1"); + RecordProperty("key_1", "2"); +} + +TEST(NoFixtureTest, RecordProperty) { + RecordProperty("key", "1"); +} + +void ExternalUtilityThatCallsRecordProperty(const char* key, int value) { + testing::Test::RecordProperty(key, value); +} + +void ExternalUtilityThatCallsRecordProperty(const char* key, + const char* value) { + testing::Test::RecordProperty(key, value); +} + +TEST(NoFixtureTest, ExternalUtilityThatCallsRecordIntValuedProperty) { + ExternalUtilityThatCallsRecordProperty("key_for_utility_int", 1); +} + +TEST(NoFixtureTest, ExternalUtilityThatCallsRecordStringValuedProperty) { + ExternalUtilityThatCallsRecordProperty("key_for_utility_string", "1"); +} diff --git a/test/gtest_xml_test_utils.py b/test/gtest_xml_test_utils.py new file mode 100755 index 00000000..c2ea9c1d --- /dev/null +++ b/test/gtest_xml_test_utils.py @@ -0,0 +1,138 @@ +#!/usr/bin/env python +# +# Copyright 2006, 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. + +"""Unit test utilities for gtest_xml_output""" + +__author__ = 'eefacm@gmail.com (Sean Mcafee)' + +import re +import unittest + +from xml.dom import minidom, Node + +GTEST_OUTPUT_FLAG = "--gtest_output" +GTEST_DEFAULT_OUTPUT_FILE = "test_detail.xml" + +class GTestXMLTestCase(unittest.TestCase): + """ + Base class for tests of Google Test's XML output functionality. + """ + + + def _AssertEquivalentElements(self, expected_element, actual_element): + """ + Asserts that actual_element (a DOM element object) is equivalent to + expected_element (another DOM element object), in that it meets all + of the following conditions: + * It has the same tag name as expected_element. + * It has the same set of attributes as expected_element, each with + the same value as the corresponding attribute of expected_element. + An exception is any attribute named "time", which need only be + convertible to a long integer. + * Each child element is equivalent to a child element of + expected_element. Child elements are matched according to an + attribute that varies depending on the element; "name" for + and elements, "message" for + elements. This matching is necessary because child elements are + not guaranteed to be ordered in any particular way. + """ + self.assertEquals(expected_element.tagName, actual_element.tagName) + + expected_attributes = expected_element.attributes + actual_attributes = actual_element .attributes + self.assertEquals(expected_attributes.length, actual_attributes.length) + for i in range(expected_attributes.length): + expected_attr = expected_attributes.item(i) + actual_attr = actual_attributes.get(expected_attr.name) + self.assert_(actual_attr is not None) + self.assertEquals(expected_attr.value, actual_attr.value) + + expected_child = self._GetChildElements(expected_element) + actual_child = self._GetChildElements(actual_element) + self.assertEquals(len(expected_child), len(actual_child)) + for child_id, element in expected_child.iteritems(): + self.assert_(child_id in actual_child, + '<%s> is not in <%s>' % (child_id, actual_child)) + self._AssertEquivalentElements(element, actual_child[child_id]) + + identifying_attribute = { + "testsuite": "name", + "testcase": "name", + "failure": "message", + } + + def _GetChildElements(self, element): + """ + Fetches all of the Element type child nodes of element, a DOM + Element object. Returns them as the values of a dictionary keyed by + the value of one of the node's attributes. For and + elements, the identifying attribute is "name"; for + elements, it is "message". An exception is raised if + any element other than the above three is encountered, if two + child elements with the same identifying attributes are encountered, + or if any other type of node is encountered, other than Text nodes + containing only whitespace. + """ + children = {} + for child in element.childNodes: + if child.nodeType == Node.ELEMENT_NODE: + self.assert_(child.tagName in self.identifying_attribute, + "Encountered unknown element <%s>" % child.tagName) + childID = child.getAttribute(self.identifying_attribute[child.tagName]) + self.assert_(childID not in children) + children[childID] = child + elif child.nodeType == Node.TEXT_NODE: + self.assert_(child.nodeValue.isspace()) + else: + self.fail("Encountered unexpected node type %d" % child.nodeType) + return children + + def _NormalizeXml(self, element): + """ + Normalizes Google Test's XML output to eliminate references to transient + information that may change from run to run. + + * The "time" attribute of and elements is + replaced with a single asterisk, if it contains only digit + characters. + * The line number reported in the first line of the "message" + attribute of elements is replaced with a single asterisk. + * The directory names in file paths are removed. + """ + if element.tagName in ("testsuite", "testcase"): + time = element.getAttributeNode("time") + time.value = re.sub(r"^\d+$", "*", time.value) + elif element.tagName == "failure": + message = element.getAttributeNode("message") + message.value = re.sub(r"^.*/(.*:)\d+\n", "\\1*\n", message.value) + for child in element.childNodes: + if child.nodeType == Node.ELEMENT_NODE: + self._NormalizeXml(child) diff --git a/test/production.cc b/test/production.cc new file mode 100644 index 00000000..8b8a40b4 --- /dev/null +++ b/test/production.cc @@ -0,0 +1,36 @@ +// Copyright 2006, 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) +// +// This is part of the unit test for include/gtest/gtest_prod.h. + +#include "production.h" + +PrivateCode::PrivateCode() : x_(0) {} diff --git a/test/production.h b/test/production.h new file mode 100644 index 00000000..59970da0 --- /dev/null +++ b/test/production.h @@ -0,0 +1,55 @@ +// Copyright 2006, 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) +// +// This is part of the unit test for include/gtest/gtest_prod.h. + +#ifndef GTEST_TEST_PRODUCTION_H_ +#define GTEST_TEST_PRODUCTION_H_ + +#include + +class PrivateCode { + public: + // Declares a friend test that does not use a fixture. + FRIEND_TEST(PrivateCodeTest, CanAccessPrivateMembers); + + // Declares a friend test that uses a fixture. + FRIEND_TEST(PrivateCodeFixtureTest, CanAccessPrivateMembers); + + PrivateCode(); + + int x() const { return x_; } + private: + void set_x(int x) { x_ = x; } + int x_; +}; + +#endif // GTEST_TEST_PRODUCTION_H_ -- cgit v1.2.3 From e4e9a8bd7d2dbbad62030c8f80513e3c81b32213 Mon Sep 17 00:00:00 2001 From: shiqian Date: Tue, 8 Jul 2008 21:32:17 +0000 Subject: Makes the autotools scripts work on Mac OS X. Also hopefully makes gtest compile on Windows CE. --- test/gtest_output_test.py | 2 +- test/gtest_output_test_golden_win.txt | 20 ++++++++++---------- test/gtest_repeat_test.cc | 2 ++ test/gtest_uninitialized_test.py | 11 +++++++++-- 4 files changed, 22 insertions(+), 13 deletions(-) (limited to 'test') diff --git a/test/gtest_output_test.py b/test/gtest_output_test.py index 0fea034f..7ecb4d1a 100755 --- a/test/gtest_output_test.py +++ b/test/gtest_output_test.py @@ -158,7 +158,7 @@ def GetCommandOutput(cmd): """ # Disables exception pop-ups on Windows. - os.environ['GUNIT_CATCH_EXCEPTIONS'] = '1' + os.environ['GTEST_CATCH_EXCEPTIONS'] = '1' return NormalizeOutput(GetShellCommandOutput(cmd, '')) diff --git a/test/gtest_output_test_golden_win.txt b/test/gtest_output_test_golden_win.txt index e72577d8..87d1a6aa 100644 --- a/test/gtest_output_test_golden_win.txt +++ b/test/gtest_output_test_golden_win.txt @@ -54,7 +54,7 @@ This failure is expected, and shouldn't have a trace. gtest_output_test_.cc:#: Failure Failed This failure is expected, and should have a trace. -gUnit trace: +Google Test trace: gtest_output_test_.cc:#: Expected trace gtest_output_test_.cc:#: Failure Failed @@ -66,13 +66,13 @@ gtest_output_test_.cc:#: Failure Value of: n Actual: 1 Expected: 2 -gUnit trace: +Google Test trace: gtest_output_test_.cc:#: i = 1 gtest_output_test_.cc:#: Failure Value of: n Actual: 2 Expected: 1 -gUnit trace: +Google Test trace: gtest_output_test_.cc:#: i = 2 [ FAILED ] SCOPED_TRACETest.WorksInLoop [ RUN ] SCOPED_TRACETest.WorksInSubroutine @@ -81,13 +81,13 @@ gtest_output_test_.cc:#: Failure Value of: n Actual: 1 Expected: 2 -gUnit trace: +Google Test trace: gtest_output_test_.cc:#: n = 1 gtest_output_test_.cc:#: Failure Value of: n Actual: 2 Expected: 1 -gUnit trace: +Google Test trace: gtest_output_test_.cc:#: n = 2 [ FAILED ] SCOPED_TRACETest.WorksInSubroutine [ RUN ] SCOPED_TRACETest.CanBeNested @@ -96,7 +96,7 @@ gtest_output_test_.cc:#: Failure Value of: n Actual: 2 Expected: 1 -gUnit trace: +Google Test trace: gtest_output_test_.cc:#: n = 2 gtest_output_test_.cc:#: [ FAILED ] SCOPED_TRACETest.CanBeNested @@ -105,25 +105,25 @@ gtest_output_test_.cc:#: gtest_output_test_.cc:#: Failure Failed This failure is expected, and should contain trace point A. -gUnit trace: +Google Test trace: gtest_output_test_.cc:#: A gtest_output_test_.cc:#: Failure Failed This failure is expected, and should contain trace point A and B. -gUnit trace: +Google Test trace: gtest_output_test_.cc:#: B gtest_output_test_.cc:#: A gtest_output_test_.cc:#: Failure Failed This failure is expected, and should contain trace point A, B, and C. -gUnit trace: +Google Test trace: gtest_output_test_.cc:#: C gtest_output_test_.cc:#: B gtest_output_test_.cc:#: A gtest_output_test_.cc:#: Failure Failed This failure is expected, and should contain trace point A, B, and D. -gUnit trace: +Google Test trace: gtest_output_test_.cc:#: D gtest_output_test_.cc:#: B gtest_output_test_.cc:#: A diff --git a/test/gtest_repeat_test.cc b/test/gtest_repeat_test.cc index 056e6cc8..fa52442f 100644 --- a/test/gtest_repeat_test.cc +++ b/test/gtest_repeat_test.cc @@ -110,11 +110,13 @@ int g_death_test_count = 0; TEST(BarDeathTest, ThreadSafeAndFast) { g_death_test_count++; +#ifdef GTEST_HAS_DEATH_TEST GTEST_FLAG(death_test_style) = "threadsafe"; EXPECT_DEATH(abort(), ""); GTEST_FLAG(death_test_style) = "fast"; EXPECT_DEATH(abort(), ""); +#endif // GTEST_HAS_DEATH_TEST } // Resets the count for each test. diff --git a/test/gtest_uninitialized_test.py b/test/gtest_uninitialized_test.py index 1956a7b9..d553bbf9 100755 --- a/test/gtest_uninitialized_test.py +++ b/test/gtest_uninitialized_test.py @@ -80,8 +80,15 @@ def GetOutput(command): def TestExitCodeAndOutput(command): """Runs the given command and verifies its exit code and output.""" - # 256 corresponds to return code 0. - AssertEq(256, os.system(command)) + # Verifies that 'command' exits with code 1. + if IS_WINDOWS: + # On Windows, os.system(command) returns the exit code of 'command'. + AssertEq(1, os.system(command)) + else: + # On Unix-like system, os.system(command) returns 256 times the + # exit code of 'command'. + AssertEq(256, os.system(command)) + output = GetOutput(command) Assert('InitGoogleTest' in output) -- cgit v1.2.3 From e0ecb7ac588e4061fe57207ff3734e465637b14d Mon Sep 17 00:00:00 2001 From: shiqian Date: Wed, 9 Jul 2008 20:58:26 +0000 Subject: Makes Google Test compile on Mac OS X and Cygwin, and adds project files for Microsoft Visual Studio. --- test/gtest_break_on_failure_unittest.py | 8 ++++++-- test/gtest_unittest.cc | 8 +++++--- 2 files changed, 11 insertions(+), 5 deletions(-) (limited to 'test') diff --git a/test/gtest_break_on_failure_unittest.py b/test/gtest_break_on_failure_unittest.py index 1b18339b..674ef11d 100755 --- a/test/gtest_break_on_failure_unittest.py +++ b/test/gtest_break_on_failure_unittest.py @@ -74,10 +74,14 @@ def SetEnvVar(env_var, value): def Run(command): - """Runs a command; returns 1 if it has a segmentation fault, or 0 otherwise. + """Runs a command; returns 1 if it was killed by a signal, or 0 otherwise. """ - return os.system(command) == signal.SIGSEGV + exit_code = os.system(command) + # On Unix-like systems, the lowest 8 bits of the exit code is the + # signal number that killed the process (or 0 if it wasn't killed by + # a signal). + return (exit_code & 255) != 0 # The unit test. diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index 9a64a13e..02799a4f 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -157,10 +157,12 @@ TEST(ToUtf8StringTest, CanEncode12To16Bits) { EXPECT_STREQ("\xEC\x9D\x8D", ToUtf8String(L'\xC74D').c_str()); } -#if !defined(GTEST_OS_WINDOWS) && !defined(__SYMBIAN32__) +#if !defined(GTEST_OS_WINDOWS) && !defined(GTEST_OS_CYGWIN) && \ + !defined(__SYMBIAN32__) // Tests in this group require a wchar_t to hold > 16 bits, and thus -// are skipped on Windows and Symbian, where a wchar_t is 16-bit wide. +// are skipped on Windows, Cygwin, and Symbian, where a wchar_t is +// 16-bit wide. // Tests that Unicode code-points that have 17 to 21 bits are encoded // as 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx. @@ -178,7 +180,7 @@ TEST(ToUtf8StringTest, CanEncodeInvalidCodePoint) { ToUtf8String(L'\x1234ABCD').c_str()); } -#endif // Windows or Symbian +#endif // Windows, Cygwin, or Symbian // Tests the List template class. -- cgit v1.2.3 From 253d2bc5760533c136f5b1b34b8c6f03d79fc538 Mon Sep 17 00:00:00 2001 From: shiqian Date: Wed, 23 Jul 2008 20:32:11 +0000 Subject: Makes the output understandable by VS when compiled by MSVC. --- test/gtest_output_test.py | 5 +- test/gtest_output_test_golden_win.txt | 165 ++++++++++++---------------------- 2 files changed, 58 insertions(+), 112 deletions(-) (limited to 'test') diff --git a/test/gtest_output_test.py b/test/gtest_output_test.py index 7ecb4d1a..ee766ffd 100755 --- a/test/gtest_output_test.py +++ b/test/gtest_output_test.py @@ -78,11 +78,12 @@ def RemoveLocations(output): Returns: output with all file location info (in the form of - 'DIRECTORY/FILE_NAME:LINE_NUMBER: ') replaced by + 'DIRECTORY/FILE_NAME:LINE_NUMBER: 'or + 'DIRECTORY\\FILE_NAME(LINE_NUMBER): ') replaced by 'FILE_NAME:#: '. """ - return re.sub(r'.*[/\\](.+)\:\d+\: ', r'\1:#: ', output) + return re.sub(r'.*[/\\](.+)(\:\d+|\(\d+\))\: ', r'\1:#: ', output) def RemoveStackTraces(output): diff --git a/test/gtest_output_test_golden_win.txt b/test/gtest_output_test_golden_win.txt index 87d1a6aa..eb476ecd 100644 --- a/test/gtest_output_test_golden_win.txt +++ b/test/gtest_output_test_golden_win.txt @@ -1,11 +1,9 @@ The non-test part of the code is expected to have 2 failures. -gtest_output_test_.cc:#: Failure -Value of: false +gtest_output_test_.cc:#: error: Value of: false Actual: false Expected: true -gtest_output_test_.cc:#: Failure -Value of: 3 +gtest_output_test_.cc:#: error: Value of: 3 Expected: 2 [==========] Running 40 tests from 16 test cases. [----------] Global test environment set-up. @@ -14,22 +12,19 @@ BarEnvironment::SetUp() called. [----------] 3 tests from FatalFailureTest [ RUN ] FatalFailureTest.FatalFailureInSubroutine (expecting a failure that x should be 1) -gtest_output_test_.cc:#: Failure -Value of: x +gtest_output_test_.cc:#: error: Value of: x Actual: 2 Expected: 1 [ FAILED ] FatalFailureTest.FatalFailureInSubroutine [ RUN ] FatalFailureTest.FatalFailureInNestedSubroutine (expecting a failure that x should be 1) -gtest_output_test_.cc:#: Failure -Value of: x +gtest_output_test_.cc:#: error: Value of: x Actual: 2 Expected: 1 [ FAILED ] FatalFailureTest.FatalFailureInNestedSubroutine [ RUN ] FatalFailureTest.NonfatalFailureInSubroutine (expecting a failure on false) -gtest_output_test_.cc:#: Failure -Value of: false +gtest_output_test_.cc:#: error: Value of: false Actual: false Expected: true [ FAILED ] FatalFailureTest.NonfatalFailureInSubroutine @@ -38,38 +33,31 @@ Expected: true (expecting 2 failures on (3) >= (a[i])) i == 0 i == 1 -gtest_output_test_.cc:#: Failure -Expected: (3) >= (a[i]), actual: 3 vs 9 +gtest_output_test_.cc:#: error: Expected: (3) >= (a[i]), actual: 3 vs 9 i == 2 i == 3 -gtest_output_test_.cc:#: Failure -Expected: (3) >= (a[i]), actual: 3 vs 6 +gtest_output_test_.cc:#: error: Expected: (3) >= (a[i]), actual: 3 vs 6 [ FAILED ] LoggingTest.InterleavingLoggingAndAssertions [----------] 5 tests from SCOPED_TRACETest [ RUN ] SCOPED_TRACETest.ObeysScopes (expected to fail) -gtest_output_test_.cc:#: Failure -Failed +gtest_output_test_.cc:#: error: Failed This failure is expected, and shouldn't have a trace. -gtest_output_test_.cc:#: Failure -Failed +gtest_output_test_.cc:#: error: Failed This failure is expected, and should have a trace. Google Test trace: gtest_output_test_.cc:#: Expected trace -gtest_output_test_.cc:#: Failure -Failed +gtest_output_test_.cc:#: error: Failed This failure is expected, and shouldn't have a trace. [ FAILED ] SCOPED_TRACETest.ObeysScopes [ RUN ] SCOPED_TRACETest.WorksInLoop (expected to fail) -gtest_output_test_.cc:#: Failure -Value of: n +gtest_output_test_.cc:#: error: Value of: n Actual: 1 Expected: 2 Google Test trace: gtest_output_test_.cc:#: i = 1 -gtest_output_test_.cc:#: Failure -Value of: n +gtest_output_test_.cc:#: error: Value of: n Actual: 2 Expected: 1 Google Test trace: @@ -77,14 +65,12 @@ gtest_output_test_.cc:#: i = 2 [ FAILED ] SCOPED_TRACETest.WorksInLoop [ RUN ] SCOPED_TRACETest.WorksInSubroutine (expected to fail) -gtest_output_test_.cc:#: Failure -Value of: n +gtest_output_test_.cc:#: error: Value of: n Actual: 1 Expected: 2 Google Test trace: gtest_output_test_.cc:#: n = 1 -gtest_output_test_.cc:#: Failure -Value of: n +gtest_output_test_.cc:#: error: Value of: n Actual: 2 Expected: 1 Google Test trace: @@ -92,8 +78,7 @@ gtest_output_test_.cc:#: n = 2 [ FAILED ] SCOPED_TRACETest.WorksInSubroutine [ RUN ] SCOPED_TRACETest.CanBeNested (expected to fail) -gtest_output_test_.cc:#: Failure -Value of: n +gtest_output_test_.cc:#: error: Value of: n Actual: 2 Expected: 1 Google Test trace: @@ -102,26 +87,22 @@ gtest_output_test_.cc:#: [ FAILED ] SCOPED_TRACETest.CanBeNested [ RUN ] SCOPED_TRACETest.CanBeRepeated (expected to fail) -gtest_output_test_.cc:#: Failure -Failed +gtest_output_test_.cc:#: error: Failed This failure is expected, and should contain trace point A. Google Test trace: gtest_output_test_.cc:#: A -gtest_output_test_.cc:#: Failure -Failed +gtest_output_test_.cc:#: error: Failed This failure is expected, and should contain trace point A and B. Google Test trace: gtest_output_test_.cc:#: B gtest_output_test_.cc:#: A -gtest_output_test_.cc:#: Failure -Failed +gtest_output_test_.cc:#: error: Failed This failure is expected, and should contain trace point A, B, and C. Google Test trace: gtest_output_test_.cc:#: C gtest_output_test_.cc:#: B gtest_output_test_.cc:#: A -gtest_output_test_.cc:#: Failure -Failed +gtest_output_test_.cc:#: error: Failed This failure is expected, and should contain trace point A, B, and D. Google Test trace: gtest_output_test_.cc:#: D @@ -131,88 +112,67 @@ gtest_output_test_.cc:#: A [----------] 1 test from NonFatalFailureInFixtureConstructorTest [ RUN ] NonFatalFailureInFixtureConstructorTest.FailureInConstructor (expecting 5 failures) -gtest_output_test_.cc:#: Failure -Failed +gtest_output_test_.cc:#: error: Failed Expected failure #1, in the test fixture c'tor. -gtest_output_test_.cc:#: Failure -Failed +gtest_output_test_.cc:#: error: Failed Expected failure #2, in SetUp(). -gtest_output_test_.cc:#: Failure -Failed +gtest_output_test_.cc:#: error: Failed Expected failure #3, in the test body. -gtest_output_test_.cc:#: Failure -Failed +gtest_output_test_.cc:#: error: Failed Expected failure #4, in TearDown. -gtest_output_test_.cc:#: Failure -Failed +gtest_output_test_.cc:#: error: Failed Expected failure #5, in the test fixture d'tor. [ FAILED ] NonFatalFailureInFixtureConstructorTest.FailureInConstructor [----------] 1 test from FatalFailureInFixtureConstructorTest [ RUN ] FatalFailureInFixtureConstructorTest.FailureInConstructor (expecting 2 failures) -gtest_output_test_.cc:#: Failure -Failed +gtest_output_test_.cc:#: error: Failed Expected failure #1, in the test fixture c'tor. -gtest_output_test_.cc:#: Failure -Failed +gtest_output_test_.cc:#: error: Failed Expected failure #2, in the test fixture d'tor. [ FAILED ] FatalFailureInFixtureConstructorTest.FailureInConstructor [----------] 1 test from NonFatalFailureInSetUpTest [ RUN ] NonFatalFailureInSetUpTest.FailureInSetUp (expecting 4 failures) -gtest_output_test_.cc:#: Failure -Failed +gtest_output_test_.cc:#: error: Failed Expected failure #1, in SetUp(). -gtest_output_test_.cc:#: Failure -Failed +gtest_output_test_.cc:#: error: Failed Expected failure #2, in the test function. -gtest_output_test_.cc:#: Failure -Failed +gtest_output_test_.cc:#: error: Failed Expected failure #3, in TearDown(). -gtest_output_test_.cc:#: Failure -Failed +gtest_output_test_.cc:#: error: Failed Expected failure #4, in the test fixture d'tor. [ FAILED ] NonFatalFailureInSetUpTest.FailureInSetUp [----------] 1 test from FatalFailureInSetUpTest [ RUN ] FatalFailureInSetUpTest.FailureInSetUp (expecting 3 failures) -gtest_output_test_.cc:#: Failure -Failed +gtest_output_test_.cc:#: error: Failed Expected failure #1, in SetUp(). -gtest_output_test_.cc:#: Failure -Failed +gtest_output_test_.cc:#: error: Failed Expected failure #2, in TearDown(). -gtest_output_test_.cc:#: Failure -Failed +gtest_output_test_.cc:#: error: Failed Expected failure #3, in the test fixture d'tor. [ FAILED ] FatalFailureInSetUpTest.FailureInSetUp [----------] 1 test from ExceptionInFixtureCtorTest [ RUN ] ExceptionInFixtureCtorTest.ExceptionInFixtureCtor (expecting a failure on thrown exception in the test fixture's constructor) -unknown file: Failure -Exception thrown with code 0xc0000005 in the test fixture's constructor. +unknown file: error: Exception thrown with code 0xc0000005 in the test fixture's constructor. [----------] 1 test from ExceptionInSetUpTest [ RUN ] ExceptionInSetUpTest.ExceptionInSetUp (expecting 3 failures) -unknown file: Failure -Exception thrown with code 0xc0000005 in SetUp(). -gtest_output_test_.cc:#: Failure -Failed +unknown file: error: Exception thrown with code 0xc0000005 in SetUp(). +gtest_output_test_.cc:#: error: Failed Expected failure #2, in TearDown(). -gtest_output_test_.cc:#: Failure -Failed +gtest_output_test_.cc:#: error: Failed Expected failure #3, in the test fixture d'tor. [ FAILED ] ExceptionInSetUpTest.ExceptionInSetUp [----------] 1 test from ExceptionInTestFunctionTest [ RUN ] ExceptionInTestFunctionTest.SEH (expecting 3 failures) -unknown file: Failure -Exception thrown with code 0xc0000005 in the test body. -gtest_output_test_.cc:#: Failure -Failed +unknown file: error: Exception thrown with code 0xc0000005 in the test body. +gtest_output_test_.cc:#: error: Failed Expected failure #2, in TearDown(). -gtest_output_test_.cc:#: Failure -Failed +gtest_output_test_.cc:#: error: Failed Expected failure #3, in the test fixture d'tor. [ FAILED ] ExceptionInTestFunctionTest.SEH [----------] 4 tests from MixedUpTestCaseTest @@ -221,8 +181,7 @@ Expected failure #3, in the test fixture d'tor. [ RUN ] MixedUpTestCaseTest.SecondTestFromNamespaceFoo [ OK ] MixedUpTestCaseTest.SecondTestFromNamespaceFoo [ RUN ] MixedUpTestCaseTest.ThisShouldFail -gtest.cc:#: Failure -Failed +gtest.cc:#: error: Failed All tests in the same test case must use the same test fixture class. However, in test case MixedUpTestCaseTest, you defined test FirstTestFromNamespaceFoo and test ThisShouldFail @@ -232,8 +191,7 @@ units and have the same name. You should probably rename one of the classes to put the tests into different test cases. [ FAILED ] MixedUpTestCaseTest.ThisShouldFail [ RUN ] MixedUpTestCaseTest.ThisShouldFailToo -gtest.cc:#: Failure -Failed +gtest.cc:#: error: Failed All tests in the same test case must use the same test fixture class. However, in test case MixedUpTestCaseTest, you defined test FirstTestFromNamespaceFoo and test ThisShouldFailToo @@ -246,8 +204,7 @@ of the classes to put the tests into different test cases. [ RUN ] MixedUpTestCaseWithSameTestNameTest.TheSecondTestWithThisNameShouldFail [ OK ] MixedUpTestCaseWithSameTestNameTest.TheSecondTestWithThisNameShouldFail [ RUN ] MixedUpTestCaseWithSameTestNameTest.TheSecondTestWithThisNameShouldFail -gtest.cc:#: Failure -Failed +gtest.cc:#: error: Failed All tests in the same test case must use the same test fixture class. However, in test case MixedUpTestCaseWithSameTestNameTest, you defined test TheSecondTestWithThisNameShouldFail and test TheSecondTestWithThisNameShouldFail @@ -260,8 +217,7 @@ of the classes to put the tests into different test cases. [ RUN ] TEST_F_before_TEST_in_same_test_case.DefinedUsingTEST_F [ OK ] TEST_F_before_TEST_in_same_test_case.DefinedUsingTEST_F [ RUN ] TEST_F_before_TEST_in_same_test_case.DefinedUsingTESTAndShouldFail -gtest.cc:#: Failure -Failed +gtest.cc:#: error: Failed All tests in the same test case must use the same test fixture class, so mixing TEST_F and TEST in the same test case is illegal. In test case TEST_F_before_TEST_in_same_test_case, @@ -274,8 +230,7 @@ case. [ RUN ] TEST_before_TEST_F_in_same_test_case.DefinedUsingTEST [ OK ] TEST_before_TEST_F_in_same_test_case.DefinedUsingTEST [ RUN ] TEST_before_TEST_F_in_same_test_case.DefinedUsingTEST_FAndShouldFail -gtest.cc:#: Failure -Failed +gtest.cc:#: error: Failed All tests in the same test case must use the same test fixture class, so mixing TEST_F and TEST in the same test case is illegal. In test case TEST_before_TEST_F_in_same_test_case, @@ -293,14 +248,12 @@ case. [ OK ] ExpectNonfatalFailureTest.SucceedsWhenThereIsOneNonfatalFailure [ RUN ] ExpectNonfatalFailureTest.FailsWhenThereIsNoNonfatalFailure (expecting a failure) -gtest.cc:#: Failure -Expected: 1 non-fatal failure +gtest.cc:#: error: Expected: 1 non-fatal failure Actual: 0 failures [ FAILED ] ExpectNonfatalFailureTest.FailsWhenThereIsNoNonfatalFailure [ RUN ] ExpectNonfatalFailureTest.FailsWhenThereAreTwoNonfatalFailures (expecting a failure) -gtest.cc:#: Failure -Expected: 1 non-fatal failure +gtest.cc:#: error: Expected: 1 non-fatal failure Actual: 2 failures gtest_output_test_.cc:#: Non-fatal failure: Failed @@ -313,8 +266,7 @@ Expected non-fatal failure 2. [ FAILED ] ExpectNonfatalFailureTest.FailsWhenThereAreTwoNonfatalFailures [ RUN ] ExpectNonfatalFailureTest.FailsWhenThereIsOneFatalFailure (expecting a failure) -gtest.cc:#: Failure -Expected: 1 non-fatal failure +gtest.cc:#: error: Expected: 1 non-fatal failure Actual: gtest_output_test_.cc:#: Fatal failure: Failed @@ -323,8 +275,7 @@ Expected fatal failure. [ FAILED ] ExpectNonfatalFailureTest.FailsWhenThereIsOneFatalFailure [ RUN ] ExpectNonfatalFailureTest.FailsWhenStatementReturns (expecting a failure) -gtest.cc:#: Failure -Expected: 1 non-fatal failure +gtest.cc:#: error: Expected: 1 non-fatal failure Actual: 0 failures [ FAILED ] ExpectNonfatalFailureTest.FailsWhenStatementReturns [----------] 7 tests from ExpectFatalFailureTest @@ -336,14 +287,12 @@ Expected: 1 non-fatal failure [ OK ] ExpectFatalFailureTest.SucceedsWhenThereIsOneFatalFailure [ RUN ] ExpectFatalFailureTest.FailsWhenThereIsNoFatalFailure (expecting a failure) -gtest.cc:#: Failure -Expected: 1 fatal failure +gtest.cc:#: error: Expected: 1 fatal failure Actual: 0 failures [ FAILED ] ExpectFatalFailureTest.FailsWhenThereIsNoFatalFailure [ RUN ] ExpectFatalFailureTest.FailsWhenThereAreTwoFatalFailures (expecting a failure) -gtest.cc:#: Failure -Expected: 1 fatal failure +gtest.cc:#: error: Expected: 1 fatal failure Actual: 2 failures gtest_output_test_.cc:#: Fatal failure: Failed @@ -356,8 +305,7 @@ Expected fatal failure. [ FAILED ] ExpectFatalFailureTest.FailsWhenThereAreTwoFatalFailures [ RUN ] ExpectFatalFailureTest.FailsWhenThereIsOneNonfatalFailure (expecting a failure) -gtest.cc:#: Failure -Expected: 1 fatal failure +gtest.cc:#: error: Expected: 1 fatal failure Actual: gtest_output_test_.cc:#: Non-fatal failure: Failed @@ -366,18 +314,15 @@ Expected non-fatal failure. [ FAILED ] ExpectFatalFailureTest.FailsWhenThereIsOneNonfatalFailure [ RUN ] ExpectFatalFailureTest.FailsWhenStatementReturns (expecting a failure) -gtest.cc:#: Failure -Expected: 1 fatal failure +gtest.cc:#: error: Expected: 1 fatal failure Actual: 0 failures [ FAILED ] ExpectFatalFailureTest.FailsWhenStatementReturns [----------] Global test environment tear-down BarEnvironment::TearDown() called. -gtest_output_test_.cc:#: Failure -Failed +gtest_output_test_.cc:#: error: Failed Expected non-fatal failure. FooEnvironment::TearDown() called. -gtest_output_test_.cc:#: Failure -Failed +gtest_output_test_.cc:#: error: Failed Expected fatal failure. [==========] 40 tests from 16 test cases ran. [ PASSED ] 11 tests. -- cgit v1.2.3 From 15cbe5f70adaade1a8a11afc37601fc6606e7e0d Mon Sep 17 00:00:00 2001 From: shiqian Date: Fri, 25 Jul 2008 04:06:16 +0000 Subject: Adds --gtest_print_test for printing the elapsed time of tests. --- test/gtest_output_test.py | 20 ++++++-- test/gtest_output_test_golden_lin.txt | 70 ++++++++++++++++++++++++++ test/gtest_output_test_golden_win.txt | 61 ++++++++++++++++++++++ test/gtest_unittest.cc | 95 +++++++++++++++++++++++++++++++++++ 4 files changed, 241 insertions(+), 5 deletions(-) (limited to 'test') diff --git a/test/gtest_output_test.py b/test/gtest_output_test.py index ee766ffd..05f49dc4 100755 --- a/test/gtest_output_test.py +++ b/test/gtest_output_test.py @@ -58,8 +58,10 @@ else: PROGRAM = 'gtest_output_test_' GOLDEN_NAME = 'gtest_output_test_golden_lin.txt' -COMMAND = os.path.join(gtest_test_utils.GetBuildDir(), - PROGRAM) + ' --gtest_color=yes' +PROGRAM_PATH = os.path.join(gtest_test_utils.GetBuildDir(), PROGRAM) +COMMAND_WITH_COLOR = PROGRAM_PATH + ' --gtest_color=yes' +COMMAND_WITH_TIME = (PROGRAM_PATH + ' --gtest_print_time ' + + '--gtest_filter="FatalFailureTest.*:LoggingTest.*"') GOLDEN_PATH = os.path.join(gtest_test_utils.GetSourceDir(), GOLDEN_NAME) @@ -94,12 +96,19 @@ def RemoveStackTraces(output): 'Stack trace: (omitted)\n\n', output) +def RemoveTime(output): + """Removes all time information from a Google Test program's output.""" + + return re.sub(r'\(\d+ ms', '(? ms', output) + + def NormalizeOutput(output): """Normalizes output (the output of gtest_output_test_.exe).""" output = ToUnixLineEnding(output) output = RemoveLocations(output) output = RemoveStackTraces(output) + output = RemoveTime(output) return output @@ -165,8 +174,8 @@ def GetCommandOutput(cmd): class GTestOutputTest(unittest.TestCase): def testOutput(self): - output = GetCommandOutput(COMMAND) - + output = (GetCommandOutput(COMMAND_WITH_COLOR) + + GetCommandOutput(COMMAND_WITH_TIME)) golden_file = open(GOLDEN_PATH, 'rb') golden = golden_file.read() golden_file.close() @@ -176,7 +185,8 @@ class GTestOutputTest(unittest.TestCase): if __name__ == '__main__': if sys.argv[1:] == [GENGOLDEN_FLAG]: - output = GetCommandOutput(COMMAND) + output = (GetCommandOutput(COMMAND_WITH_COLOR) + + GetCommandOutput(COMMAND_WITH_TIME)) golden_file = open(GOLDEN_PATH, 'wb') golden_file.write(output) golden_file.close() diff --git a/test/gtest_output_test_golden_lin.txt b/test/gtest_output_test_golden_lin.txt index bfcc9a9b..1da3bf30 100644 --- a/test/gtest_output_test_golden_lin.txt +++ b/test/gtest_output_test_golden_lin.txt @@ -381,3 +381,73 @@ Expected fatal failure. [ FAILED ] ExpectFatalFailureTest.FailsWhenStatementReturns 26 FAILED TESTS +The non-test part of the code is expected to have 2 failures. + +gtest_output_test_.cc:#: Failure +Value of: false + Actual: false +Expected: true +gtest_output_test_.cc:#: Failure +Value of: 3 +Expected: 2 +Note: Google Test filter = FatalFailureTest.*:LoggingTest.* +[==========] Running 4 tests from 2 test cases. +[----------] Global test environment set-up. +FooEnvironment::SetUp() called. +BarEnvironment::SetUp() called. +[----------] 3 tests from FatalFailureTest +[ RUN ] FatalFailureTest.FatalFailureInSubroutine +(expecting a failure that x should be 1) +gtest_output_test_.cc:#: Failure +Value of: x + Actual: 2 +Expected: 1 +[ FAILED ] FatalFailureTest.FatalFailureInSubroutine (? ms) +[ RUN ] FatalFailureTest.FatalFailureInNestedSubroutine +(expecting a failure that x should be 1) +gtest_output_test_.cc:#: Failure +Value of: x + Actual: 2 +Expected: 1 +[ FAILED ] FatalFailureTest.FatalFailureInNestedSubroutine (? ms) +[ RUN ] FatalFailureTest.NonfatalFailureInSubroutine +(expecting a failure on false) +gtest_output_test_.cc:#: Failure +Value of: false + Actual: false +Expected: true +[ FAILED ] FatalFailureTest.NonfatalFailureInSubroutine (? ms) +[----------] 3 tests from FatalFailureTest (? ms total) + +[----------] 1 test from LoggingTest +[ RUN ] LoggingTest.InterleavingLoggingAndAssertions +(expecting 2 failures on (3) >= (a[i])) +i == 0 +i == 1 +gtest_output_test_.cc:#: Failure +Expected: (3) >= (a[i]), actual: 3 vs 9 +i == 2 +i == 3 +gtest_output_test_.cc:#: Failure +Expected: (3) >= (a[i]), actual: 3 vs 6 +[ FAILED ] LoggingTest.InterleavingLoggingAndAssertions (? ms) +[----------] 1 test from LoggingTest (? ms total) + +[----------] Global test environment tear-down +BarEnvironment::TearDown() called. +gtest_output_test_.cc:#: Failure +Failed +Expected non-fatal failure. +FooEnvironment::TearDown() called. +gtest_output_test_.cc:#: Failure +Failed +Expected fatal failure. +[==========] 4 tests from 2 test cases ran. (? ms total) +[ PASSED ] 0 tests. +[ FAILED ] 4 tests, listed below: +[ FAILED ] FatalFailureTest.FatalFailureInSubroutine +[ FAILED ] FatalFailureTest.FatalFailureInNestedSubroutine +[ FAILED ] FatalFailureTest.NonfatalFailureInSubroutine +[ FAILED ] LoggingTest.InterleavingLoggingAndAssertions + + 4 FAILED TESTS diff --git a/test/gtest_output_test_golden_win.txt b/test/gtest_output_test_golden_win.txt index eb476ecd..9a13da95 100644 --- a/test/gtest_output_test_golden_win.txt +++ b/test/gtest_output_test_golden_win.txt @@ -358,3 +358,64 @@ Expected fatal failure. [ FAILED ] ExpectFatalFailureTest.FailsWhenStatementReturns 29 FAILED TESTS +The non-test part of the code is expected to have 2 failures. + +gtest_output_test_.cc:#: error: Value of: false + Actual: false +Expected: true +gtest_output_test_.cc:#: error: Value of: 3 +Expected: 2 +Note: Google Test filter = FatalFailureTest.*:LoggingTest.* +[==========] Running 4 tests from 2 test cases. +[----------] Global test environment set-up. +FooEnvironment::SetUp() called. +BarEnvironment::SetUp() called. +[----------] 3 tests from FatalFailureTest +[ RUN ] FatalFailureTest.FatalFailureInSubroutine +(expecting a failure that x should be 1) +gtest_output_test_.cc:#: error: Value of: x + Actual: 2 +Expected: 1 +[ FAILED ] FatalFailureTest.FatalFailureInSubroutine (? ms) +[ RUN ] FatalFailureTest.FatalFailureInNestedSubroutine +(expecting a failure that x should be 1) +gtest_output_test_.cc:#: error: Value of: x + Actual: 2 +Expected: 1 +[ FAILED ] FatalFailureTest.FatalFailureInNestedSubroutine (? ms) +[ RUN ] FatalFailureTest.NonfatalFailureInSubroutine +(expecting a failure on false) +gtest_output_test_.cc:#: error: Value of: false + Actual: false +Expected: true +[ FAILED ] FatalFailureTest.NonfatalFailureInSubroutine (? ms) +[----------] 3 tests from FatalFailureTest (? ms total) + +[----------] 1 test from LoggingTest +[ RUN ] LoggingTest.InterleavingLoggingAndAssertions +(expecting 2 failures on (3) >= (a[i])) +i == 0 +i == 1 +gtest_output_test_.cc:#: error: Expected: (3) >= (a[i]), actual: 3 vs 9 +i == 2 +i == 3 +gtest_output_test_.cc:#: error: Expected: (3) >= (a[i]), actual: 3 vs 6 +[ FAILED ] LoggingTest.InterleavingLoggingAndAssertions (? ms) +[----------] 1 test from LoggingTest (? ms total) + +[----------] Global test environment tear-down +BarEnvironment::TearDown() called. +gtest_output_test_.cc:#: error: Failed +Expected non-fatal failure. +FooEnvironment::TearDown() called. +gtest_output_test_.cc:#: error: Failed +Expected fatal failure. +[==========] 4 tests from 2 test cases ran. (? ms total) +[ PASSED ] 0 tests. +[ FAILED ] 4 tests, listed below: +[ FAILED ] FatalFailureTest.FatalFailureInSubroutine +[ FAILED ] FatalFailureTest.FatalFailureInNestedSubroutine +[ FAILED ] FatalFailureTest.NonfatalFailureInSubroutine +[ FAILED ] LoggingTest.InterleavingLoggingAndAssertions + + 4 FAILED TESTS diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index 02799a4f..e88a8d02 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -808,6 +808,7 @@ class GTestFlagSaverTest : public testing::Test { testing::GTEST_FLAG(filter) = ""; testing::GTEST_FLAG(list_tests) = false; testing::GTEST_FLAG(output) = ""; + testing::GTEST_FLAG(print_time) = false; testing::GTEST_FLAG(repeat) = 1; } @@ -827,6 +828,7 @@ class GTestFlagSaverTest : public testing::Test { EXPECT_STREQ("", testing::GTEST_FLAG(filter).c_str()); EXPECT_FALSE(testing::GTEST_FLAG(list_tests)); EXPECT_STREQ("", testing::GTEST_FLAG(output).c_str()); + EXPECT_FALSE(testing::GTEST_FLAG(print_time)); EXPECT_EQ(1, testing::GTEST_FLAG(repeat)); testing::GTEST_FLAG(break_on_failure) = true; @@ -835,6 +837,7 @@ class GTestFlagSaverTest : public testing::Test { testing::GTEST_FLAG(filter) = "abc"; testing::GTEST_FLAG(list_tests) = true; testing::GTEST_FLAG(output) = "xml:foo.xml"; + testing::GTEST_FLAG(print_time) = true; testing::GTEST_FLAG(repeat) = 100; } private: @@ -3471,6 +3474,7 @@ struct Flags { filter(""), list_tests(false), output(""), + print_time(false), repeat(1) {} // Factory methods. @@ -3515,6 +3519,14 @@ struct Flags { return flags; } + // Creates a Flags struct where the gtest_print_time flag has the given + // value. + static Flags PrintTime(bool print_time) { + Flags flags; + flags.print_time = print_time; + return flags; + } + // Creates a Flags struct where the gtest_repeat flag has the given // value. static Flags Repeat(Int32 repeat) { @@ -3529,6 +3541,7 @@ struct Flags { const char* filter; bool list_tests; const char* output; + bool print_time; Int32 repeat; }; @@ -3542,6 +3555,7 @@ class InitGoogleTestTest : public testing::Test { GTEST_FLAG(filter) = ""; GTEST_FLAG(list_tests) = false; GTEST_FLAG(output) = ""; + GTEST_FLAG(print_time) = false; GTEST_FLAG(repeat) = 1; } @@ -3563,6 +3577,7 @@ class InitGoogleTestTest : public testing::Test { EXPECT_STREQ(expected.filter, GTEST_FLAG(filter).c_str()); EXPECT_EQ(expected.list_tests, GTEST_FLAG(list_tests)); EXPECT_STREQ(expected.output, GTEST_FLAG(output).c_str()); + EXPECT_EQ(expected.print_time, GTEST_FLAG(print_time)); EXPECT_EQ(expected.repeat, GTEST_FLAG(repeat)); } @@ -3950,6 +3965,86 @@ TEST_F(InitGoogleTestTest, OutputXmlDirectory) { TEST_PARSING_FLAGS(argv, argv2, Flags::Output("xml:directory/path/")); } +// Tests having a --gtest_print_time flag +TEST_F(InitGoogleTestTest, PrintTimeFlag) { + const char* argv[] = { + "foo.exe", + "--gtest_print_time", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + TEST_PARSING_FLAGS(argv, argv2, Flags::PrintTime(true)); +} + +// Tests having a --gtest_print_time flag with a "true" value +TEST_F(InitGoogleTestTest, PrintTimeTrue) { + const char* argv[] = { + "foo.exe", + "--gtest_print_time=1", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + TEST_PARSING_FLAGS(argv, argv2, Flags::PrintTime(true)); +} + +// Tests having a --gtest_print_time flag with a "false" value +TEST_F(InitGoogleTestTest, PrintTimeFalse) { + const char* argv[] = { + "foo.exe", + "--gtest_print_time=0", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + TEST_PARSING_FLAGS(argv, argv2, Flags::PrintTime(false)); +} + +// Tests parsing --gtest_print_time=f. +TEST_F(InitGoogleTestTest, PrintTimeFalse_f) { + const char* argv[] = { + "foo.exe", + "--gtest_print_time=f", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + TEST_PARSING_FLAGS(argv, argv2, Flags::PrintTime(false)); +} + +// Tests parsing --gtest_print_time=F. +TEST_F(InitGoogleTestTest, PrintTimeFalse_F) { + const char* argv[] = { + "foo.exe", + "--gtest_print_time=F", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + TEST_PARSING_FLAGS(argv, argv2, Flags::PrintTime(false)); +} + // Tests parsing --gtest_repeat=number TEST_F(InitGoogleTestTest, Repeat) { const char* argv[] = { -- cgit v1.2.3 From d88da49d028d8d01c1e49761be577ed1cc1f5c1d Mon Sep 17 00:00:00 2001 From: shiqian Date: Fri, 25 Jul 2008 21:13:11 +0000 Subject: Adds a test for the GTEST_PRINT_TIME env var. By Balazs.Dan@gmail.com. --- test/gtest_env_var_test.py | 1 + test/gtest_env_var_test_.cc | 5 +++++ 2 files changed, 6 insertions(+) (limited to 'test') diff --git a/test/gtest_env_var_test.py b/test/gtest_env_var_test.py index 64d17e85..1b86b5a9 100755 --- a/test/gtest_env_var_test.py +++ b/test/gtest_env_var_test.py @@ -101,6 +101,7 @@ def TestEnvVarAffectsFlag(command): TestFlag(command, 'color', 'yes', 'auto') TestFlag(command, 'filter', 'FooTest.Bar', '*') TestFlag(command, 'output', 'tmp/foo.xml', '') + TestFlag(command, 'print_time', '1', '0') TestFlag(command, 'repeat', '999', '1') if IS_WINDOWS: diff --git a/test/gtest_env_var_test_.cc b/test/gtest_env_var_test_.cc index 81056e84..16b31103 100644 --- a/test/gtest_env_var_test_.cc +++ b/test/gtest_env_var_test_.cc @@ -81,6 +81,11 @@ void PrintFlag(const char* flag) { return; } + if (strcmp(flag, "print_time") == 0) { + cout << GTEST_FLAG(print_time); + return; + } + if (strcmp(flag, "repeat") == 0) { cout << GTEST_FLAG(repeat); return; -- cgit v1.2.3 From bf9b4b48dc65adc2edd44175f77b4a7363c59234 Mon Sep 17 00:00:00 2001 From: shiqian Date: Thu, 31 Jul 2008 18:34:08 +0000 Subject: Makes gtest work on Windows Mobile and Symbian. By Mika Raento. --- test/gtest-filepath_test.cc | 36 ++++++++++++++++++++++++++++++++++++ test/gtest_unittest.cc | 30 ++++++++++++++++++++++++++++-- 2 files changed, 64 insertions(+), 2 deletions(-) (limited to 'test') diff --git a/test/gtest-filepath_test.cc b/test/gtest-filepath_test.cc index 559b599b..f4b70c36 100644 --- a/test/gtest-filepath_test.cc +++ b/test/gtest-filepath_test.cc @@ -51,7 +51,11 @@ #undef GTEST_IMPLEMENTATION #ifdef GTEST_OS_WINDOWS +#ifdef _WIN32_WCE +#include +#else #include +#endif // _WIN32_WCE #define PATH_SEP "\\" #else #define PATH_SEP "/" @@ -61,6 +65,32 @@ namespace testing { namespace internal { namespace { +#ifdef _WIN32_WCE +// Windows CE doesn't have the remove C function. +int remove(const char* path) { + LPCWSTR wpath = String::AnsiToUtf16(path); + int ret = DeleteFile(wpath) ? 0 : -1; + delete [] wpath; + return ret; +} +// Windows CE doesn't have the _rmdir C function. +int _rmdir(const char* path) { + FilePath filepath(path); + LPCWSTR wpath = String::AnsiToUtf16( + filepath.RemoveTrailingPathSeparator().c_str()); + int ret = RemoveDirectory(wpath) ? 0 : -1; + delete [] wpath; + return ret; +} + +#elif defined(GTEST_LINUX_GOOGLE3_MODE) +// Creates a temporary directory and returns its path. +const char* MakeTempDir() { + static char dir_name[] = "gtest-filepath_test_tmpXXXXXX"; + return mkdtemp(dir_name); +} +#endif // _WIN32_WCE + // FilePath's functions used by UnitTestOptions::GetOutputFile. // RemoveDirectoryName "" -> "" @@ -102,8 +132,14 @@ TEST(RemoveDirectoryNameTest, ShouldAlsoGiveFileName) { // RemoveFileName "" -> "./" TEST(RemoveFileNameTest, EmptyName) { +#ifdef _WIN32_WCE + // On Windows CE, we use the root as the current directory. + EXPECT_STREQ(PATH_SEP, + FilePath("").RemoveFileName().c_str()); +#else EXPECT_STREQ("." PATH_SEP, FilePath("").RemoveFileName().c_str()); +#endif } // RemoveFileName "adir/" -> "adir/" diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index e88a8d02..374f7c14 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -295,7 +295,9 @@ TEST(ListTest, InsertAfterNotAtBeginning) { TEST(StringTest, Constructors) { // Default ctor. String s1; - EXPECT_EQ(NULL, s1.c_str()); + // We aren't using EXPECT_EQ(NULL, s1.c_str()) because comparing + // pointers with NULL isn't supported on all platforms. + EXPECT_TRUE(NULL == s1.c_str()); // Implicitly constructs from a C-string. String s2 = "Hi"; @@ -442,6 +444,31 @@ TEST(StringTest, ShowWideCStringQuoted) { String::ShowWideCStringQuoted(L"foo").c_str()); } +#ifdef _WIN32_WCE +TEST(StringTest, AnsiAndUtf16Null) { + EXPECT_EQ(NULL, String::AnsiToUtf16(NULL)); + EXPECT_EQ(NULL, String::Utf16ToAnsi(NULL)); +} + +TEST(StringTest, AnsiAndUtf16ConvertBasic) { + const char* ansi = String::Utf16ToAnsi(L"str"); + EXPECT_STREQ("str", ansi); + delete [] ansi; + const WCHAR* utf16 = String::AnsiToUtf16("str"); + EXPECT_TRUE(wcsncmp(L"str", utf16, 3) == 0); + delete [] utf16; +} + +TEST(StringTest, AnsiAndUtf16ConvertPathChars) { + const char* ansi = String::Utf16ToAnsi(L".:\\ \"*?"); + EXPECT_STREQ(".:\\ \"*?", ansi); + delete [] ansi; + const WCHAR* utf16 = String::AnsiToUtf16(".:\\ \"*?"); + EXPECT_TRUE(wcsncmp(L".:\\ \"*?", utf16, 3) == 0); + delete [] utf16; +} +#endif // _WIN32_WCE + #endif // GTEST_OS_WINDOWS // Tests TestProperty construction. @@ -2865,7 +2892,6 @@ TEST(StreamableTest, BasicIoManip) { }, "Line 1.\nA NUL char \\0 in line 2."); } - // Tests the macros that haven't been covered so far. void AddFailureHelper(bool* aborted) { -- cgit v1.2.3 From bcb12fa0f651f7de3a10f4535ed856e52b1c3f62 Mon Sep 17 00:00:00 2001 From: shiqian Date: Fri, 1 Aug 2008 19:04:48 +0000 Subject: Fixes the definition of GTEST_ATTRIBUTE_UNUSED and make the tests pass in opt mode. --- test/gtest-death-test_test.cc | 29 ++--------------------------- test/gtest_repeat_test.cc | 4 ++-- 2 files changed, 4 insertions(+), 29 deletions(-) (limited to 'test') diff --git a/test/gtest-death-test_test.cc b/test/gtest-death-test_test.cc index 4e4ca1a2..4bfd9d63 100644 --- a/test/gtest-death-test_test.cc +++ b/test/gtest-death-test_test.cc @@ -467,31 +467,6 @@ TEST_F(TestForDeathTest, TestExpectDebugDeath) { #endif } -// Tests that EXPECT_DEBUG_DEATH works as expected, -// that is, in debug mode, it: -// 1. Asserts on death. -// 2. Has no side effect. -// -// And in opt mode, it: -// 1. Has side effects and returns the expected value (12). -TEST_F(TestForDeathTest, TestExpectDebugDeathM) { - int sideeffect = 0; - EXPECT_DEBUG_DEATH({ // NOLINT - // Tests that the return value is 12 in opt mode. - EXPECT_EQ(12, DieInDebugElse12(&sideeffect)); - // Tests that the side effect occurrs in opt mode. - EXPECT_EQ(12, sideeffect); - }, "death.*DieInDebugElse12") << "In ExpectDebugDeathM"; - -#ifdef NDEBUG - // Checks that the assignment occurs in opt mode (sideeffect). - EXPECT_EQ(12, sideeffect); -#else - // Checks that the assignment does not occur in dbg mode (no sideeffect). - EXPECT_EQ(0, sideeffect); -#endif -} - // Tests that ASSERT_DEBUG_DEATH works as expected // In debug mode: // 1. Asserts on debug death. @@ -499,7 +474,7 @@ TEST_F(TestForDeathTest, TestExpectDebugDeathM) { // // In opt mode: // 1. Has side effects and returns the expected value (12). -TEST_F(TestForDeathTest, TestAssertDebugDeathM) { +TEST_F(TestForDeathTest, TestAssertDebugDeath) { int sideeffect = 0; ASSERT_DEBUG_DEATH({ // NOLINT @@ -507,7 +482,7 @@ TEST_F(TestForDeathTest, TestAssertDebugDeathM) { EXPECT_EQ(12, DieInDebugElse12(&sideeffect)); // Tests that the side effect occurred in opt mode. EXPECT_EQ(12, sideeffect); - }, "death.*DieInDebugElse12") << "In AssertDebugDeathM"; + }, "death.*DieInDebugElse12"); #ifdef NDEBUG // Checks that the assignment occurs in opt mode (sideeffect). diff --git a/test/gtest_repeat_test.cc b/test/gtest_repeat_test.cc index fa52442f..e2f03812 100644 --- a/test/gtest_repeat_test.cc +++ b/test/gtest_repeat_test.cc @@ -58,6 +58,8 @@ using testing::GTEST_FLAG(repeat); namespace { +// We need this when we are testing Google Test itself and therefore +// cannot use Google Test assertions. #define GTEST_CHECK_INT_EQ_(expected, actual) \ do {\ const int expected_val = (expected);\ @@ -130,8 +132,6 @@ void ResetCounts() { // Checks that the count for each test is expected. void CheckCounts(int expected) { - // We cannot use Google Test assertions here since we are testing Google Test - // itself. GTEST_CHECK_INT_EQ_(expected, g_environment_set_up_count); GTEST_CHECK_INT_EQ_(expected, g_environment_tear_down_count); GTEST_CHECK_INT_EQ_(expected, g_should_fail_count); -- cgit v1.2.3 From 9b093c1779eb48a55db026cfd525f4cf1bbd4749 Mon Sep 17 00:00:00 2001 From: shiqian Date: Wed, 6 Aug 2008 21:43:15 +0000 Subject: Cleans up the usage of testing:: in gtest_unittest. By Zhanyong Wan. --- test/gtest_unittest.cc | 313 ++++++++++++++++++++++--------------------------- 1 file changed, 143 insertions(+), 170 deletions(-) (limited to 'test') diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index 374f7c14..9f1cbe97 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -74,17 +74,38 @@ bool ShouldUseColor(bool stdout_is_tty); } // namespace internal } // namespace testing +using testing::AssertionFailure; +using testing::AssertionResult; +using testing::AssertionSuccess; +using testing::DoubleLE; +using testing::FloatLE; +using testing::GTEST_FLAG(break_on_failure); +using testing::GTEST_FLAG(catch_exceptions); using testing::GTEST_FLAG(color); +using testing::GTEST_FLAG(filter); +using testing::GTEST_FLAG(list_tests); +using testing::GTEST_FLAG(output); +using testing::GTEST_FLAG(print_time); +using testing::GTEST_FLAG(repeat); +using testing::GTEST_FLAG(show_internal_stack_frames); +using testing::GTEST_FLAG(stack_trace_depth); +using testing::IsNotSubstring; +using testing::IsSubstring; +using testing::Message; using testing::ScopedFakeTestPartResultReporter; +using testing::Test; using testing::TestPartResult; using testing::TestPartResultArray; +using testing::TPRT_FATAL_FAILURE; +using testing::TPRT_NONFATAL_FAILURE; +using testing::TPRT_SUCCESS; using testing::UnitTest; using testing::internal::AppendUserMessage; using testing::internal::EqFailure; +using testing::internal::FloatingPoint; +using testing::internal::GTestFlagSaver; using testing::internal::Int32; using testing::internal::List; -using testing::internal::OsStackTraceGetter; -using testing::internal::OsStackTraceGetterInterface; using testing::internal::ShouldUseColor; using testing::internal::StreamableToString; using testing::internal::String; @@ -92,7 +113,6 @@ using testing::internal::TestProperty; using testing::internal::TestResult; using testing::internal::ToUtf8String; using testing::internal::UnitTestImpl; -using testing::internal::UnitTestOptions; // This line tests that we can define tests in an unnamed namespace. namespace { @@ -489,30 +509,21 @@ TEST(TestPropertyTest, ReplaceStringValue) { // Tests the TestPartResult class. // The test fixture for testing TestPartResult. -class TestPartResultTest : public testing::Test { +class TestPartResultTest : public Test { protected: TestPartResultTest() - : r1_(testing::TPRT_SUCCESS, - "foo/bar.cc", - 10, - "Success!"), - r2_(testing::TPRT_NONFATAL_FAILURE, - "foo/bar.cc", - -1, - "Failure!"), - r3_(testing::TPRT_FATAL_FAILURE, - NULL, - -1, - "Failure!") {} + : r1_(TPRT_SUCCESS, "foo/bar.cc", 10, "Success!"), + r2_(TPRT_NONFATAL_FAILURE, "foo/bar.cc", -1, "Failure!"), + r3_(TPRT_FATAL_FAILURE, NULL, -1, "Failure!") {} TestPartResult r1_, r2_, r3_; }; // Tests TestPartResult::type() TEST_F(TestPartResultTest, type) { - EXPECT_EQ(testing::TPRT_SUCCESS, r1_.type()); - EXPECT_EQ(testing::TPRT_NONFATAL_FAILURE, r2_.type()); - EXPECT_EQ(testing::TPRT_FATAL_FAILURE, r3_.type()); + EXPECT_EQ(TPRT_SUCCESS, r1_.type()); + EXPECT_EQ(TPRT_NONFATAL_FAILURE, r2_.type()); + EXPECT_EQ(TPRT_FATAL_FAILURE, r3_.type()); } // Tests TestPartResult::file_name() @@ -562,17 +573,11 @@ TEST_F(TestPartResultTest, NonfatallyFailed) { // Tests the TestPartResultArray class. -class TestPartResultArrayTest : public testing::Test { +class TestPartResultArrayTest : public Test { protected: TestPartResultArrayTest() - : r1_(testing::TPRT_NONFATAL_FAILURE, - "foo/bar.cc", - -1, - "Failure 1"), - r2_(testing::TPRT_FATAL_FAILURE, - "foo/bar.cc", - -1, - "Failure 2") {} + : r1_(TPRT_NONFATAL_FAILURE, "foo/bar.cc", -1, "Failure 1"), + r2_(TPRT_FATAL_FAILURE, "foo/bar.cc", -1, "Failure 2") {} const TestPartResult r1_, r2_; }; @@ -625,7 +630,7 @@ TEST(ScopedFakeTestPartResultReporterTest, InterceptsTestFailures) { // Tests the TestResult class // The test fixture for testing TestResult. -class TestResultTest : public testing::Test { +class TestResultTest : public Test { protected: typedef List TPRList; @@ -637,16 +642,12 @@ class TestResultTest : public testing::Test { virtual void SetUp() { // pr1 is for success. - pr1 = new TestPartResult(testing::TPRT_SUCCESS, - "foo/bar.cc", - 10, - "Success!"); + pr1 = new TestPartResult(TPRT_SUCCESS, "foo/bar.cc", 10, "Success!"); // pr2 is for fatal failure. - pr2 = new TestPartResult(testing::TPRT_FATAL_FAILURE, - "foo/bar.cc", - -1, // This line number means "unknown" - "Failure!"); + pr2 = new TestPartResult(TPRT_FATAL_FAILURE, "foo/bar.cc", + -1, // This line number means "unknown" + "Failure!"); // Creates the TestResult objects. r0 = new TestResult(); @@ -821,22 +822,22 @@ TEST(TestResultPropertyTest, AddFailureWhenUsingReservedKeyCalledClassname) { // Tests that GTestFlagSaver works on Windows and Mac. -class GTestFlagSaverTest : public testing::Test { +class GTestFlagSaverTest : public Test { protected: // Saves the Google Test flags such that we can restore them later, and // then sets them to their default values. This will be called // before the first test in this test case is run. static void SetUpTestCase() { - saver_ = new testing::internal::GTestFlagSaver; - - testing::GTEST_FLAG(break_on_failure) = false; - testing::GTEST_FLAG(catch_exceptions) = false; - testing::GTEST_FLAG(color) = "auto"; - testing::GTEST_FLAG(filter) = ""; - testing::GTEST_FLAG(list_tests) = false; - testing::GTEST_FLAG(output) = ""; - testing::GTEST_FLAG(print_time) = false; - testing::GTEST_FLAG(repeat) = 1; + saver_ = new GTestFlagSaver; + + GTEST_FLAG(break_on_failure) = false; + GTEST_FLAG(catch_exceptions) = false; + GTEST_FLAG(color) = "auto"; + GTEST_FLAG(filter) = ""; + GTEST_FLAG(list_tests) = false; + GTEST_FLAG(output) = ""; + GTEST_FLAG(print_time) = false; + GTEST_FLAG(repeat) = 1; } // Restores the Google Test flags that the tests have modified. This will @@ -849,30 +850,30 @@ class GTestFlagSaverTest : public testing::Test { // Verifies that the Google Test flags have their default values, and then // modifies each of them. void VerifyAndModifyFlags() { - EXPECT_FALSE(testing::GTEST_FLAG(break_on_failure)); - EXPECT_FALSE(testing::GTEST_FLAG(catch_exceptions)); - EXPECT_STREQ("auto", testing::GTEST_FLAG(color).c_str()); - EXPECT_STREQ("", testing::GTEST_FLAG(filter).c_str()); - EXPECT_FALSE(testing::GTEST_FLAG(list_tests)); - EXPECT_STREQ("", testing::GTEST_FLAG(output).c_str()); - EXPECT_FALSE(testing::GTEST_FLAG(print_time)); - EXPECT_EQ(1, testing::GTEST_FLAG(repeat)); - - testing::GTEST_FLAG(break_on_failure) = true; - testing::GTEST_FLAG(catch_exceptions) = true; - testing::GTEST_FLAG(color) = "no"; - testing::GTEST_FLAG(filter) = "abc"; - testing::GTEST_FLAG(list_tests) = true; - testing::GTEST_FLAG(output) = "xml:foo.xml"; - testing::GTEST_FLAG(print_time) = true; - testing::GTEST_FLAG(repeat) = 100; + EXPECT_FALSE(GTEST_FLAG(break_on_failure)); + EXPECT_FALSE(GTEST_FLAG(catch_exceptions)); + EXPECT_STREQ("auto", GTEST_FLAG(color).c_str()); + EXPECT_STREQ("", GTEST_FLAG(filter).c_str()); + EXPECT_FALSE(GTEST_FLAG(list_tests)); + EXPECT_STREQ("", GTEST_FLAG(output).c_str()); + EXPECT_FALSE(GTEST_FLAG(print_time)); + EXPECT_EQ(1, GTEST_FLAG(repeat)); + + GTEST_FLAG(break_on_failure) = true; + GTEST_FLAG(catch_exceptions) = true; + GTEST_FLAG(color) = "no"; + GTEST_FLAG(filter) = "abc"; + GTEST_FLAG(list_tests) = true; + GTEST_FLAG(output) = "xml:foo.xml"; + GTEST_FLAG(print_time) = true; + GTEST_FLAG(repeat) = 100; } private: // For saving Google Test flags during this test case. - static testing::internal::GTestFlagSaver* saver_; + static GTestFlagSaver* saver_; }; -testing::internal::GTestFlagSaver* GTestFlagSaverTest::saver_ = NULL; +GTestFlagSaver* GTestFlagSaverTest::saver_ = NULL; // Google Test doesn't guarantee the order of tests. The following two // tests are designed to work regardless of their order. @@ -896,7 +897,7 @@ static void SetEnv(const char* name, const char* value) { // Environment variables are not supported on Windows CE. return; #elif defined(GTEST_OS_WINDOWS) // If we are on Windows proper. - _putenv((testing::Message() << name << "=" << value).GetString().c_str()); + _putenv((Message() << name << "=" << value).GetString().c_str()); #else if (*value == '\0') { unsetenv(name); @@ -909,7 +910,7 @@ static void SetEnv(const char* name, const char* value) { #ifndef _WIN32_WCE // Environment variables are not supported on Windows CE. -using ::testing::internal::Int32FromGTestEnv; +using testing::internal::Int32FromGTestEnv; // Tests Int32FromGTestEnv(). @@ -1037,20 +1038,20 @@ struct IsEvenFunctor { // A predicate-formatter function that asserts the argument is an even // number. -testing::AssertionResult AssertIsEven(const char* expr, int n) { +AssertionResult AssertIsEven(const char* expr, int n) { if (IsEven(n)) { - return testing::AssertionSuccess(); + return AssertionSuccess(); } - testing::Message msg; + Message msg; msg << expr << " evaluates to " << n << ", which is not even."; - return testing::AssertionFailure(msg); + return AssertionFailure(msg); } // A predicate-formatter functor that asserts the argument is an even // number. struct AssertIsEvenFunctor { - testing::AssertionResult operator()(const char* expr, int n) { + AssertionResult operator()(const char* expr, int n) { return AssertIsEven(expr, n); } }; @@ -1070,50 +1071,38 @@ struct SumIsEven3Functor { // A predicate-formatter function that asserts the sum of the // arguments is an even number. -testing::AssertionResult AssertSumIsEven4(const char* e1, - const char* e2, - const char* e3, - const char* e4, - int n1, - int n2, - int n3, - int n4) { +AssertionResult AssertSumIsEven4( + const char* e1, const char* e2, const char* e3, const char* e4, + int n1, int n2, int n3, int n4) { const int sum = n1 + n2 + n3 + n4; if (IsEven(sum)) { - return testing::AssertionSuccess(); + return AssertionSuccess(); } - testing::Message msg; + Message msg; msg << e1 << " + " << e2 << " + " << e3 << " + " << e4 << " (" << n1 << " + " << n2 << " + " << n3 << " + " << n4 << ") evaluates to " << sum << ", which is not even."; - return testing::AssertionFailure(msg); + return AssertionFailure(msg); } // A predicate-formatter functor that asserts the sum of the arguments // is an even number. struct AssertSumIsEven5Functor { - testing::AssertionResult operator()(const char* e1, - const char* e2, - const char* e3, - const char* e4, - const char* e5, - int n1, - int n2, - int n3, - int n4, - int n5) { + AssertionResult operator()( + const char* e1, const char* e2, const char* e3, const char* e4, + const char* e5, int n1, int n2, int n3, int n4, int n5) { const int sum = n1 + n2 + n3 + n4 + n5; if (IsEven(sum)) { - return testing::AssertionSuccess(); + return AssertionSuccess(); } - testing::Message msg; + Message msg; msg << e1 << " + " << e2 << " + " << e3 << " + " << e4 << " + " << e5 << " (" << n1 << " + " << n2 << " + " << n3 << " + " << n4 << " + " << n5 << ") evaluates to " << sum << ", which is not even."; - return testing::AssertionFailure(msg); + return AssertionFailure(msg); } }; @@ -1294,27 +1283,27 @@ TEST(PredicateAssertionTest, AcceptsTemplateFunction) { // Some helper functions for testing using overloaded/template // functions with ASSERT_PRED_FORMATn and EXPECT_PRED_FORMATn. -testing::AssertionResult IsPositiveFormat(const char* expr, int n) { - return n > 0 ? testing::AssertionSuccess() : - testing::AssertionFailure(testing::Message() << "Failure"); +AssertionResult IsPositiveFormat(const char* expr, int n) { + return n > 0 ? AssertionSuccess() : + AssertionFailure(Message() << "Failure"); } -testing::AssertionResult IsPositiveFormat(const char* expr, double x) { - return x > 0 ? testing::AssertionSuccess() : - testing::AssertionFailure(testing::Message() << "Failure"); +AssertionResult IsPositiveFormat(const char* expr, double x) { + return x > 0 ? AssertionSuccess() : + AssertionFailure(Message() << "Failure"); } template -testing::AssertionResult IsNegativeFormat(const char* expr, T x) { - return x < 0 ? testing::AssertionSuccess() : - testing::AssertionFailure(testing::Message() << "Failure"); +AssertionResult IsNegativeFormat(const char* expr, T x) { + return x < 0 ? AssertionSuccess() : + AssertionFailure(Message() << "Failure"); } template -testing::AssertionResult EqualsFormat(const char* expr1, const char* expr2, - const T1& x1, const T2& x2) { - return x1 == x2 ? testing::AssertionSuccess() : - testing::AssertionFailure(testing::Message() << "Failure"); +AssertionResult EqualsFormat(const char* expr1, const char* expr2, + const T1& x1, const T2& x2) { + return x1 == x2 ? AssertionSuccess() : + AssertionFailure(Message() << "Failure"); } // Tests that overloaded functions can be used in *_PRED_FORMAT* @@ -1451,8 +1440,6 @@ TEST(StringAssertionTest, STRNE_Wide) { // Tests that IsSubstring() returns the correct result when the input // argument type is const char*. TEST(IsSubstringTest, ReturnsCorrectResultForCString) { - using ::testing::IsSubstring; - EXPECT_FALSE(IsSubstring("", "", NULL, "a")); EXPECT_FALSE(IsSubstring("", "", "b", NULL)); EXPECT_FALSE(IsSubstring("", "", "needle", "haystack")); @@ -1464,8 +1451,6 @@ TEST(IsSubstringTest, ReturnsCorrectResultForCString) { // Tests that IsSubstring() returns the correct result when the input // argument type is const wchar_t*. TEST(IsSubstringTest, ReturnsCorrectResultForWideCString) { - using ::testing::IsSubstring; - EXPECT_FALSE(IsSubstring("", "", NULL, L"a")); EXPECT_FALSE(IsSubstring("", "", L"b", NULL)); EXPECT_FALSE(IsSubstring("", "", L"needle", L"haystack")); @@ -1481,8 +1466,8 @@ TEST(IsSubstringTest, GeneratesCorrectMessageForCString) { " Actual: \"needle\"\n" "Expected: a substring of haystack_expr\n" "Which is: \"haystack\"", - ::testing::IsSubstring("needle_expr", "haystack_expr", - "needle", "haystack").failure_message()); + IsSubstring("needle_expr", "haystack_expr", + "needle", "haystack").failure_message()); } #if GTEST_HAS_STD_STRING @@ -1490,8 +1475,8 @@ TEST(IsSubstringTest, GeneratesCorrectMessageForCString) { // Tests that IsSubstring returns the correct result when the input // argument type is ::std::string. TEST(IsSubstringTest, ReturnsCorrectResultsForStdString) { - EXPECT_TRUE(::testing::IsSubstring("", "", std::string("hello"), "ahellob")); - EXPECT_FALSE(::testing::IsSubstring("", "", "hello", std::string("world"))); + EXPECT_TRUE(IsSubstring("", "", std::string("hello"), "ahellob")); + EXPECT_FALSE(IsSubstring("", "", "hello", std::string("world"))); } #endif // GTEST_HAS_STD_STRING @@ -1500,8 +1485,6 @@ TEST(IsSubstringTest, ReturnsCorrectResultsForStdString) { // Tests that IsSubstring returns the correct result when the input // argument type is ::std::wstring. TEST(IsSubstringTest, ReturnsCorrectResultForStdWstring) { - using ::testing::IsSubstring; - EXPECT_TRUE(IsSubstring("", "", ::std::wstring(L"needle"), L"two needles")); EXPECT_FALSE(IsSubstring("", "", L"needle", ::std::wstring(L"haystack"))); } @@ -1513,7 +1496,7 @@ TEST(IsSubstringTest, GeneratesCorrectMessageForWstring) { " Actual: L\"needle\"\n" "Expected: a substring of haystack_expr\n" "Which is: L\"haystack\"", - ::testing::IsSubstring( + IsSubstring( "needle_expr", "haystack_expr", ::std::wstring(L"needle"), L"haystack").failure_message()); } @@ -1525,8 +1508,6 @@ TEST(IsSubstringTest, GeneratesCorrectMessageForWstring) { // Tests that IsNotSubstring() returns the correct result when the input // argument type is const char*. TEST(IsNotSubstringTest, ReturnsCorrectResultForCString) { - using ::testing::IsNotSubstring; - EXPECT_TRUE(IsNotSubstring("", "", "needle", "haystack")); EXPECT_FALSE(IsNotSubstring("", "", "needle", "two needles")); } @@ -1534,8 +1515,6 @@ TEST(IsNotSubstringTest, ReturnsCorrectResultForCString) { // Tests that IsNotSubstring() returns the correct result when the input // argument type is const wchar_t*. TEST(IsNotSubstringTest, ReturnsCorrectResultForWideCString) { - using ::testing::IsNotSubstring; - EXPECT_TRUE(IsNotSubstring("", "", L"needle", L"haystack")); EXPECT_FALSE(IsNotSubstring("", "", L"needle", L"two needles")); } @@ -1547,7 +1526,7 @@ TEST(IsNotSubstringTest, GeneratesCorrectMessageForWideCString) { " Actual: L\"needle\"\n" "Expected: not a substring of haystack_expr\n" "Which is: L\"two needles\"", - ::testing::IsNotSubstring( + IsNotSubstring( "needle_expr", "haystack_expr", L"needle", L"two needles").failure_message()); } @@ -1557,8 +1536,6 @@ TEST(IsNotSubstringTest, GeneratesCorrectMessageForWideCString) { // Tests that IsNotSubstring returns the correct result when the input // argument type is ::std::string. TEST(IsNotSubstringTest, ReturnsCorrectResultsForStdString) { - using ::testing::IsNotSubstring; - EXPECT_FALSE(IsNotSubstring("", "", std::string("hello"), "ahellob")); EXPECT_TRUE(IsNotSubstring("", "", "hello", std::string("world"))); } @@ -1570,7 +1547,7 @@ TEST(IsNotSubstringTest, GeneratesCorrectMessageForStdString) { " Actual: \"needle\"\n" "Expected: not a substring of haystack_expr\n" "Which is: \"two needles\"", - ::testing::IsNotSubstring( + IsNotSubstring( "needle_expr", "haystack_expr", ::std::string("needle"), "two needles").failure_message()); } @@ -1582,8 +1559,6 @@ TEST(IsNotSubstringTest, GeneratesCorrectMessageForStdString) { // Tests that IsNotSubstring returns the correct result when the input // argument type is ::std::wstring. TEST(IsNotSubstringTest, ReturnsCorrectResultForStdWstring) { - using ::testing::IsNotSubstring; - EXPECT_FALSE( IsNotSubstring("", "", ::std::wstring(L"needle"), L"two needles")); EXPECT_TRUE(IsNotSubstring("", "", L"needle", ::std::wstring(L"haystack"))); @@ -1594,7 +1569,7 @@ TEST(IsNotSubstringTest, ReturnsCorrectResultForStdWstring) { // Tests floating-point assertions. template -class FloatingPointTest : public testing::Test { +class FloatingPointTest : public Test { protected: typedef typename testing::internal::FloatingPoint Floating; typedef typename Floating::Bits Bits; @@ -1801,34 +1776,34 @@ TEST_F(FloatTest, ASSERT_NEAR) { // Tests the cases where FloatLE() should succeed. TEST_F(FloatTest, FloatLESucceeds) { - EXPECT_PRED_FORMAT2(testing::FloatLE, 1.0f, 2.0f); // When val1 < val2, - ASSERT_PRED_FORMAT2(testing::FloatLE, 1.0f, 1.0f); // val1 == val2, + EXPECT_PRED_FORMAT2(FloatLE, 1.0f, 2.0f); // When val1 < val2, + ASSERT_PRED_FORMAT2(FloatLE, 1.0f, 1.0f); // val1 == val2, // or when val1 is greater than, but almost equals to, val2. - EXPECT_PRED_FORMAT2(testing::FloatLE, close_to_positive_zero_, 0.0f); + EXPECT_PRED_FORMAT2(FloatLE, close_to_positive_zero_, 0.0f); } // Tests the cases where FloatLE() should fail. TEST_F(FloatTest, FloatLEFails) { // When val1 is greater than val2 by a large margin, - EXPECT_NONFATAL_FAILURE(EXPECT_PRED_FORMAT2(testing::FloatLE, 2.0f, 1.0f), + EXPECT_NONFATAL_FAILURE(EXPECT_PRED_FORMAT2(FloatLE, 2.0f, 1.0f), "(2.0f) <= (1.0f)"); // or by a small yet non-negligible margin, EXPECT_NONFATAL_FAILURE({ // NOLINT - EXPECT_PRED_FORMAT2(testing::FloatLE, further_from_one_, 1.0f); + EXPECT_PRED_FORMAT2(FloatLE, further_from_one_, 1.0f); }, "(further_from_one_) <= (1.0f)"); // or when either val1 or val2 is NaN. EXPECT_NONFATAL_FAILURE({ // NOLINT - EXPECT_PRED_FORMAT2(testing::FloatLE, nan1_, infinity_); + EXPECT_PRED_FORMAT2(FloatLE, nan1_, infinity_); }, "(nan1_) <= (infinity_)"); EXPECT_NONFATAL_FAILURE({ // NOLINT - EXPECT_PRED_FORMAT2(testing::FloatLE, -infinity_, nan1_); + EXPECT_PRED_FORMAT2(FloatLE, -infinity_, nan1_); }, "(-infinity_) <= (nan1_)"); EXPECT_FATAL_FAILURE({ // NOLINT - ASSERT_PRED_FORMAT2(testing::FloatLE, nan1_, nan1_); + ASSERT_PRED_FORMAT2(FloatLE, nan1_, nan1_); }, "(nan1_) <= (nan1_)"); } @@ -1958,33 +1933,33 @@ TEST_F(DoubleTest, ASSERT_NEAR) { // Tests the cases where DoubleLE() should succeed. TEST_F(DoubleTest, DoubleLESucceeds) { - EXPECT_PRED_FORMAT2(testing::DoubleLE, 1.0, 2.0); // When val1 < val2, - ASSERT_PRED_FORMAT2(testing::DoubleLE, 1.0, 1.0); // val1 == val2, + EXPECT_PRED_FORMAT2(DoubleLE, 1.0, 2.0); // When val1 < val2, + ASSERT_PRED_FORMAT2(DoubleLE, 1.0, 1.0); // val1 == val2, // or when val1 is greater than, but almost equals to, val2. - EXPECT_PRED_FORMAT2(testing::DoubleLE, close_to_positive_zero_, 0.0); + EXPECT_PRED_FORMAT2(DoubleLE, close_to_positive_zero_, 0.0); } // Tests the cases where DoubleLE() should fail. TEST_F(DoubleTest, DoubleLEFails) { // When val1 is greater than val2 by a large margin, - EXPECT_NONFATAL_FAILURE(EXPECT_PRED_FORMAT2(testing::DoubleLE, 2.0, 1.0), + EXPECT_NONFATAL_FAILURE(EXPECT_PRED_FORMAT2(DoubleLE, 2.0, 1.0), "(2.0) <= (1.0)"); // or by a small yet non-negligible margin, EXPECT_NONFATAL_FAILURE({ // NOLINT - EXPECT_PRED_FORMAT2(testing::DoubleLE, further_from_one_, 1.0); + EXPECT_PRED_FORMAT2(DoubleLE, further_from_one_, 1.0); }, "(further_from_one_) <= (1.0)"); // or when either val1 or val2 is NaN. EXPECT_NONFATAL_FAILURE({ // NOLINT - EXPECT_PRED_FORMAT2(testing::DoubleLE, nan1_, infinity_); + EXPECT_PRED_FORMAT2(DoubleLE, nan1_, infinity_); }, "(nan1_) <= (infinity_)"); EXPECT_NONFATAL_FAILURE({ // NOLINT - EXPECT_PRED_FORMAT2(testing::DoubleLE, -infinity_, nan1_); + EXPECT_PRED_FORMAT2(DoubleLE, -infinity_, nan1_); }, " (-infinity_) <= (nan1_)"); EXPECT_FATAL_FAILURE({ // NOLINT - ASSERT_PRED_FORMAT2(testing::DoubleLE, nan1_, nan1_); + ASSERT_PRED_FORMAT2(DoubleLE, nan1_, nan1_); }, "(nan1_) <= (nan1_)"); } @@ -2018,7 +1993,7 @@ TEST(DISABLED_TestCase, DISABLED_TestShouldNotRun) { // Check that when all tests in a test case are disabled, SetupTestCase() and // TearDownTestCase() are not called. -class DisabledTestsTest : public testing::Test { +class DisabledTestsTest : public Test { protected: static void SetUpTestCase() { FAIL() << "Unexpected failure: All tests disabled in test case. " @@ -2042,7 +2017,7 @@ TEST_F(DisabledTestsTest, DISABLED_TestShouldNotRun_2) { // Tests that assertion macros evaluate their arguments exactly once. -class SingleEvaluationTest : public testing::Test { +class SingleEvaluationTest : public Test { protected: SingleEvaluationTest() { p1_ = s1_; @@ -2196,7 +2171,7 @@ TEST(AssertionTest, EqFailure) { TEST(AssertionTest, AppendUserMessage) { const String foo("foo"); - testing::Message msg; + Message msg; EXPECT_STREQ("foo", AppendUserMessage(foo, msg).c_str()); @@ -2410,7 +2385,7 @@ enum { // On Linux, CASE_B and CASE_A have the same value when truncated to // int size. We want to test whether this will confuse the // assertions. - CASE_B = ::testing::internal::kMaxBiggestInt, + CASE_B = testing::internal::kMaxBiggestInt, #else CASE_B = INT_MAX, #endif // GTEST_OS_LINUX @@ -3194,7 +3169,7 @@ TEST(FRIEND_TEST_Test, TEST) { } // The fixture needed to test using FRIEND_TEST with TEST_F. -class FRIEND_TEST_Test2 : public testing::Test { +class FRIEND_TEST_Test2 : public Test { protected: Foo foo; }; @@ -3211,7 +3186,7 @@ TEST_F(FRIEND_TEST_Test2, TEST_F) { // // This class counts the number of live test objects that uses this // fixture. -class TestLifeCycleTest : public testing::Test { +class TestLifeCycleTest : public Test { protected: // Constructor. Increments the number of test objects that uses // this fixture. @@ -3266,7 +3241,7 @@ std::ostream& operator<<(std::ostream& os, } TEST(MessageTest, CanStreamUserTypeInGlobalNameSpace) { - testing::Message msg; + Message msg; Base a(1); msg << a << &a; // Uses ::operator<<. @@ -3291,7 +3266,7 @@ std::ostream& operator<<(std::ostream& os, } // namespace TEST(MessageTest, CanStreamUserTypeInUnnamedNameSpace) { - testing::Message msg; + Message msg; MyTypeInUnnamedNameSpace a(1); msg << a << &a; // Uses ::operator<<. @@ -3316,7 +3291,7 @@ std::ostream& operator<<(std::ostream& os, } // namespace namespace1 TEST(MessageTest, CanStreamUserTypeInUserNameSpace) { - testing::Message msg; + Message msg; namespace1::MyTypeInNameSpace1 a(1); msg << a << &a; // Uses namespace1::operator<<. @@ -3341,7 +3316,7 @@ std::ostream& operator<<(std::ostream& os, } TEST(MessageTest, CanStreamUserTypeInUserNameSpaceWithStreamOperatorInGlobal) { - testing::Message msg; + Message msg; namespace2::MyTypeInNameSpace2 a(1); msg << a << &a; // Uses ::operator<<. @@ -3350,13 +3325,13 @@ TEST(MessageTest, CanStreamUserTypeInUserNameSpaceWithStreamOperatorInGlobal) { // Tests streaming NULL pointers to testing::Message. TEST(MessageTest, NullPointers) { - testing::Message msg; + Message msg; char* const p1 = NULL; unsigned char* const p2 = NULL; int* p3 = NULL; double* p4 = NULL; bool* p5 = NULL; - testing::Message* p6 = NULL; + Message* p6 = NULL; msg << p1 << p2 << p3 << p4 << p5 << p6; ASSERT_STREQ("(null)(null)(null)(null)(null)(null)", @@ -3365,8 +3340,6 @@ TEST(MessageTest, NullPointers) { // Tests streaming wide strings to testing::Message. TEST(MessageTest, WideStrings) { - using testing::Message; - // Streams a NULL of type const wchar_t*. const wchar_t* const_wstr = NULL; EXPECT_STREQ("(null)", @@ -3394,7 +3367,7 @@ namespace testing { // Tests the TestInfo class. -class TestInfoTest : public testing::Test { +class TestInfoTest : public Test { protected: static TestInfo * GetTestInfo(const char* test_name) { return UnitTest::GetInstance()->impl()-> @@ -3403,7 +3376,7 @@ class TestInfoTest : public testing::Test { } static const TestResult* GetTestResult( - const testing::TestInfo* test_info) { + const TestInfo* test_info) { return test_info->result(); } }; @@ -3429,7 +3402,7 @@ TEST_F(TestInfoTest, result) { // Tests setting up and tearing down a test case. -class SetUpTestCaseTest : public testing::Test { +class SetUpTestCaseTest : public Test { protected: // This will be called once before the first test in this test case // is run. @@ -3572,7 +3545,7 @@ struct Flags { }; // Fixture for testing InitGoogleTest(). -class InitGoogleTestTest : public testing::Test { +class InitGoogleTestTest : public Test { protected: // Clears the flags before each test. virtual void SetUp() { @@ -4203,13 +4176,13 @@ TEST(NestedTestingNamespaceTest, Failure) { // that is, that they are not private. // No tests are based on this fixture; the test "passes" if it compiles // successfully. -class ProtectedFixtureMethodsTest : public testing::Test { +class ProtectedFixtureMethodsTest : public Test { protected: virtual void SetUp() { - testing::Test::SetUp(); + Test::SetUp(); } virtual void TearDown() { - testing::Test::TearDown(); + Test::TearDown(); } }; -- cgit v1.2.3 From 0c5a66245b8c5939b36b2aad6f4d5ab89b724b1a Mon Sep 17 00:00:00 2001 From: vladlosev Date: Mon, 25 Aug 2008 23:11:54 +0000 Subject: Implement wide->UTF-8 string conversion more correctly --- test/gtest_unittest.cc | 172 +++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 146 insertions(+), 26 deletions(-) (limited to 'test') diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index 9f1cbe97..eecaf4ee 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -101,6 +101,7 @@ using testing::TPRT_NONFATAL_FAILURE; using testing::TPRT_SUCCESS; using testing::UnitTest; using testing::internal::AppendUserMessage; +using testing::internal::CodePointToUtf8; using testing::internal::EqFailure; using testing::internal::FloatingPoint; using testing::internal::GTestFlagSaver; @@ -111,8 +112,8 @@ using testing::internal::StreamableToString; using testing::internal::String; using testing::internal::TestProperty; using testing::internal::TestResult; -using testing::internal::ToUtf8String; using testing::internal::UnitTestImpl; +using testing::internal::WideStringToUtf8; // This line tests that we can define tests in an unnamed namespace. namespace { @@ -142,65 +143,184 @@ TEST(NullLiteralTest, IsFalseForNonNullLiterals) { } #endif // __SYMBIAN32__ -// Tests ToUtf8String(). +// +// Tests CodePointToUtf8(). // Tests that the NUL character L'\0' is encoded correctly. -TEST(ToUtf8StringTest, CanEncodeNul) { - EXPECT_STREQ("", ToUtf8String(L'\0').c_str()); +TEST(CodePointToUtf8Test, CanEncodeNul) { + char buffer[32]; + EXPECT_STREQ("", CodePointToUtf8(L'\0', buffer)); } // Tests that ASCII characters are encoded correctly. -TEST(ToUtf8StringTest, CanEncodeAscii) { - EXPECT_STREQ("a", ToUtf8String(L'a').c_str()); - EXPECT_STREQ("Z", ToUtf8String(L'Z').c_str()); - EXPECT_STREQ("&", ToUtf8String(L'&').c_str()); - EXPECT_STREQ("\x7F", ToUtf8String(L'\x7F').c_str()); +TEST(CodePointToUtf8Test, CanEncodeAscii) { + char buffer[32]; + EXPECT_STREQ("a", CodePointToUtf8(L'a', buffer)); + EXPECT_STREQ("Z", CodePointToUtf8(L'Z', buffer)); + EXPECT_STREQ("&", CodePointToUtf8(L'&', buffer)); + EXPECT_STREQ("\x7F", CodePointToUtf8(L'\x7F', buffer)); } // Tests that Unicode code-points that have 8 to 11 bits are encoded // as 110xxxxx 10xxxxxx. -TEST(ToUtf8StringTest, CanEncode8To11Bits) { +TEST(CodePointToUtf8Test, CanEncode8To11Bits) { + char buffer[32]; // 000 1101 0011 => 110-00011 10-010011 - EXPECT_STREQ("\xC3\x93", ToUtf8String(L'\xD3').c_str()); + EXPECT_STREQ("\xC3\x93", CodePointToUtf8(L'\xD3', buffer)); // 101 0111 0110 => 110-10101 10-110110 - EXPECT_STREQ("\xD5\xB6", ToUtf8String(L'\x576').c_str()); + EXPECT_STREQ("\xD5\xB6", CodePointToUtf8(L'\x576', buffer)); } // Tests that Unicode code-points that have 12 to 16 bits are encoded // as 1110xxxx 10xxxxxx 10xxxxxx. -TEST(ToUtf8StringTest, CanEncode12To16Bits) { +TEST(CodePointToUtf8Test, CanEncode12To16Bits) { + char buffer[32]; // 0000 1000 1101 0011 => 1110-0000 10-100011 10-010011 - EXPECT_STREQ("\xE0\xA3\x93", ToUtf8String(L'\x8D3').c_str()); + EXPECT_STREQ("\xE0\xA3\x93", CodePointToUtf8(L'\x8D3', buffer)); // 1100 0111 0100 1101 => 1110-1100 10-011101 10-001101 - EXPECT_STREQ("\xEC\x9D\x8D", ToUtf8String(L'\xC74D').c_str()); + EXPECT_STREQ("\xEC\x9D\x8D", CodePointToUtf8(L'\xC74D', buffer)); } -#if !defined(GTEST_OS_WINDOWS) && !defined(GTEST_OS_CYGWIN) && \ - !defined(__SYMBIAN32__) - +#ifndef GTEST_WIDE_STRING_USES_UTF16_ // Tests in this group require a wchar_t to hold > 16 bits, and thus // are skipped on Windows, Cygwin, and Symbian, where a wchar_t is -// 16-bit wide. +// 16-bit wide. This code may not compile on those systems. // Tests that Unicode code-points that have 17 to 21 bits are encoded // as 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx. -TEST(ToUtf8StringTest, CanEncode17To21Bits) { +TEST(CodePointToUtf8Test, CanEncode17To21Bits) { + char buffer[32]; // 0 0001 0000 1000 1101 0011 => 11110-000 10-010000 10-100011 10-010011 - EXPECT_STREQ("\xF0\x90\xA3\x93", ToUtf8String(L'\x108D3').c_str()); + EXPECT_STREQ("\xF0\x90\xA3\x93", CodePointToUtf8(L'\x108D3', buffer)); + + // 0 0001 0000 0100 0000 0000 => 11110-000 10-010000 10-010000 10-000000 + EXPECT_STREQ("\xF0\x90\x90\x80", CodePointToUtf8(L'\x10400', buffer)); - // 1 0111 1000 0110 0011 0100 => 11110-101 10-111000 10-011000 10-110100 - EXPECT_STREQ("\xF5\xB8\x98\xB4", ToUtf8String(L'\x178634').c_str()); + // 1 0000 1000 0110 0011 0100 => 11110-100 10-001000 10-011000 10-110100 + EXPECT_STREQ("\xF4\x88\x98\xB4", CodePointToUtf8(L'\x108634', buffer)); } // Tests that encoding an invalid code-point generates the expected result. -TEST(ToUtf8StringTest, CanEncodeInvalidCodePoint) { +TEST(CodePointToUtf8Test, CanEncodeInvalidCodePoint) { + char buffer[32]; EXPECT_STREQ("(Invalid Unicode 0x1234ABCD)", - ToUtf8String(L'\x1234ABCD').c_str()); + CodePointToUtf8(L'\x1234ABCD', buffer)); +} + +#endif // GTEST_WIDE_STRING_USES_UTF16_ + +// Tests WideStringToUtf8(). + +// Tests that the NUL character L'\0' is encoded correctly. +TEST(WideStringToUtf8Test, CanEncodeNul) { + EXPECT_STREQ("", WideStringToUtf8(L"", 0).c_str()); + EXPECT_STREQ("", WideStringToUtf8(L"", -1).c_str()); +} + +// Tests that ASCII strings are encoded correctly. +TEST(WideStringToUtf8Test, CanEncodeAscii) { + EXPECT_STREQ("a", WideStringToUtf8(L"a", 1).c_str()); + EXPECT_STREQ("ab", WideStringToUtf8(L"ab", 2).c_str()); + EXPECT_STREQ("a", WideStringToUtf8(L"a", -1).c_str()); + EXPECT_STREQ("ab", WideStringToUtf8(L"ab", -1).c_str()); +} + +// Tests that Unicode code-points that have 8 to 11 bits are encoded +// as 110xxxxx 10xxxxxx. +TEST(WideStringToUtf8Test, CanEncode8To11Bits) { + // 000 1101 0011 => 110-00011 10-010011 + EXPECT_STREQ("\xC3\x93", WideStringToUtf8(L"\xD3", 1).c_str()); + EXPECT_STREQ("\xC3\x93", WideStringToUtf8(L"\xD3", -1).c_str()); + + // 101 0111 0110 => 110-10101 10-110110 + EXPECT_STREQ("\xD5\xB6", WideStringToUtf8(L"\x576", 1).c_str()); + EXPECT_STREQ("\xD5\xB6", WideStringToUtf8(L"\x576", -1).c_str()); +} + +// Tests that Unicode code-points that have 12 to 16 bits are encoded +// as 1110xxxx 10xxxxxx 10xxxxxx. +TEST(WideStringToUtf8Test, CanEncode12To16Bits) { + // 0000 1000 1101 0011 => 1110-0000 10-100011 10-010011 + EXPECT_STREQ("\xE0\xA3\x93", WideStringToUtf8(L"\x8D3", 1).c_str()); + EXPECT_STREQ("\xE0\xA3\x93", WideStringToUtf8(L"\x8D3", -1).c_str()); + + // 1100 0111 0100 1101 => 1110-1100 10-011101 10-001101 + EXPECT_STREQ("\xEC\x9D\x8D", WideStringToUtf8(L"\xC74D", 1).c_str()); + EXPECT_STREQ("\xEC\x9D\x8D", WideStringToUtf8(L"\xC74D", -1).c_str()); } -#endif // Windows, Cygwin, or Symbian +// Tests that the conversion stops when the function encounters \0 character. +TEST(WideStringToUtf8Test, StopsOnNulCharacter) { + EXPECT_STREQ("ABC", WideStringToUtf8(L"ABC\0XYZ", 100).c_str()); +} + +// Tests that the conversion stops when the function reaches the limit +// specified by the 'length' parameter. +TEST(WideStringToUtf8Test, StopsWhenLengthLimitReached) { + EXPECT_STREQ("ABC", WideStringToUtf8(L"ABCDEF", 3).c_str()); +} + + +#ifndef GTEST_WIDE_STRING_USES_UTF16_ +// Tests that Unicode code-points that have 17 to 21 bits are encoded +// as 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx. This code may not compile +// on the systems using UTF-16 encoding. +TEST(WideStringToUtf8Test, CanEncode17To21Bits) { + // 0 0001 0000 1000 1101 0011 => 11110-000 10-010000 10-100011 10-010011 + EXPECT_STREQ("\xF0\x90\xA3\x93", WideStringToUtf8(L"\x108D3", 1).c_str()); + EXPECT_STREQ("\xF0\x90\xA3\x93", WideStringToUtf8(L"\x108D3", -1).c_str()); + + // 1 0000 1000 0110 0011 0100 => 11110-100 10-001000 10-011000 10-110100 + EXPECT_STREQ("\xF4\x88\x98\xB4", WideStringToUtf8(L"\x108634", 1).c_str()); + EXPECT_STREQ("\xF4\x88\x98\xB4", WideStringToUtf8(L"\x108634", -1).c_str()); +} + +// Tests that encoding an invalid code-point generates the expected result. +TEST(WideStringToUtf8Test, CanEncodeInvalidCodePoint) { + EXPECT_STREQ("(Invalid Unicode 0xABCDFF)", + WideStringToUtf8(L"\xABCDFF", -1).c_str()); +} +#else +// Tests that surrogate pairs are encoded correctly on the systems using +// UTF-16 encoding in the wide strings. +TEST(WideStringToUtf8Test, CanEncodeValidUtf16SUrrogatePairs) { + EXPECT_STREQ("\xF0\x90\x90\x80", + WideStringToUtf8(L"\xD801\xDC00", -1).c_str()); +} + +// Tests that encoding an invalid UTF-16 surrogate pair +// generates the expected result. +TEST(WideStringToUtf8Test, CanEncodeInvalidUtf16SurrogatePair) { + // Leading surrogate is at the end of the string. + EXPECT_STREQ("\xED\xA0\x80", WideStringToUtf8(L"\xD800", -1).c_str()); + // Leading surrogate is not followed by the trailing surrogate. + EXPECT_STREQ("\xED\xA0\x80$", WideStringToUtf8(L"\xD800$", -1).c_str()); + // Trailing surrogate appearas without a leading surrogate. + EXPECT_STREQ("\xED\xB0\x80PQR", WideStringToUtf8(L"\xDC00PQR", -1).c_str()); +} +#endif // GTEST_WIDE_STRING_USES_UTF16_ + +// Tests that codepoint concatenation works correctly. +#ifndef GTEST_WIDE_STRING_USES_UTF16_ +TEST(WideStringToUtf8Test, ConcatenatesCodepointsCorrectly) { + EXPECT_STREQ( + "\xF4\x88\x98\xB4" + "\xEC\x9D\x8D" + "\n" + "\xD5\xB6" + "\xE0\xA3\x93" + "\xF4\x88\x98\xB4", + WideStringToUtf8(L"\x108634\xC74D\n\x576\x8D3\x108634", -1).c_str()); +} +#else +TEST(WideStringToUtf8Test, ConcatenatesCodepointsCorrectly) { + EXPECT_STREQ( + "\xEC\x9D\x8D" "\n" "\xD5\xB6" "\xE0\xA3\x93", + WideStringToUtf8(L"\xC74D\n\x576\x8D3", -1).c_str()); +} +#endif // GTEST_WIDE_STRING_USES_UTF16_ // Tests the List template class. -- cgit v1.2.3 From a2b1a8556ea64014606d78b09333d9c522430a25 Mon Sep 17 00:00:00 2001 From: shiqian Date: Mon, 8 Sep 2008 17:55:52 +0000 Subject: Adds support for type-parameterized tests (by Zhanyong Wan); also adds case-insensitive wide string comparison to the String class (by Vlad Losev). --- test/gtest_nc.cc | 78 ++++++++++++++++++++++++++++++ test/gtest_nc_test.py | 12 +++++ test/gtest_output_test.py | 2 + test/gtest_output_test_.cc | 91 +++++++++++++++++++++++++++++++++++ test/gtest_output_test_golden_lin.txt | 58 ++++++++++++++++++++-- test/gtest_output_test_golden_win.txt | 40 +++++++++++++-- test/gtest_unittest.cc | 76 ++++++++++++++++++++++++++++- 7 files changed, 346 insertions(+), 11 deletions(-) (limited to 'test') diff --git a/test/gtest_nc.cc b/test/gtest_nc.cc index 001deb1b..5cbaeefa 100644 --- a/test/gtest_nc.cc +++ b/test/gtest_nc.cc @@ -103,6 +103,84 @@ class MyEnvironment : public testing::Environment { } }; +#elif defined(TEST_CATCHES_WRONG_CASE_IN_TYPED_TEST_P) +// Tests that the compiler catches using the wrong test case name in +// TYPED_TEST_P. + +#include + +template +class FooTest : public testing::Test { +}; + +template +class BarTest : public testing::Test { +}; + +TYPED_TEST_CASE_P(FooTest); +TYPED_TEST_P(BarTest, A) {} // Wrong test case name. +REGISTER_TYPED_TEST_CASE_P(FooTest, A); +INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, testing::Types); + +#elif defined(TEST_CATCHES_WRONG_CASE_IN_REGISTER_TYPED_TEST_CASE_P) +// Tests that the compiler catches using the wrong test case name in +// REGISTER_TYPED_TEST_CASE_P. + +#include + +template +class FooTest : public testing::Test { +}; + +template +class BarTest : public testing::Test { +}; + +TYPED_TEST_CASE_P(FooTest); +TYPED_TEST_P(FooTest, A) {} +REGISTER_TYPED_TEST_CASE_P(BarTest, A); // Wrong test case name. +INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, testing::Types); + +#elif defined(TEST_CATCHES_WRONG_CASE_IN_INSTANTIATE_TYPED_TEST_CASE_P) +// Tests that the compiler catches using the wrong test case name in +// INSTANTIATE_TYPED_TEST_CASE_P. + +#include + +template +class FooTest : public testing::Test { +}; + +template +class BarTest : public testing::Test { +}; + +TYPED_TEST_CASE_P(FooTest); +TYPED_TEST_P(FooTest, A) {} +REGISTER_TYPED_TEST_CASE_P(FooTest, A); + +// Wrong test case name. +INSTANTIATE_TYPED_TEST_CASE_P(My, BarTest, testing::Types); + +#elif defined(TEST_CATCHES_INSTANTIATE_TYPED_TESET_CASE_P_WITH_SAME_NAME_PREFIX) +// Tests that the compiler catches instantiating TYPED_TEST_CASE_P +// twice with the same name prefix. + +#include + +template +class FooTest : public testing::Test { +}; + +TYPED_TEST_CASE_P(FooTest); +TYPED_TEST_P(FooTest, A) {} +REGISTER_TYPED_TEST_CASE_P(FooTest, A); + +INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, testing::Types); + +// Wrong name prefix: "My" has been used. +INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, testing::Types); + #else // A sanity test. This should compile. diff --git a/test/gtest_nc_test.py b/test/gtest_nc_test.py index f63feaa7..683bd370 100755 --- a/test/gtest_nc_test.py +++ b/test/gtest_nc_test.py @@ -66,6 +66,18 @@ class GTestNCTest(unittest.TestCase): ('CATCHES_CALLING_SETUP_IN_ENVIRONMENT_WITH_TYPO', [r'Setup_should_be_spelled_SetUp']), + ('CATCHES_WRONG_CASE_IN_TYPED_TEST_P', + [r'BarTest.*was not declared']), + + ('CATCHES_WRONG_CASE_IN_REGISTER_TYPED_TEST_CASE_P', + [r'BarTest.*was not declared']), + + ('CATCHES_WRONG_CASE_IN_INSTANTIATE_TYPED_TEST_CASE_P', + [r'BarTest.*not declared']), + + ('CATCHES_INSTANTIATE_TYPED_TESET_CASE_P_WITH_SAME_NAME_PREFIX', + [r'redefinition of.*My.*FooTest']), + ('SANITY', None) ] diff --git a/test/gtest_output_test.py b/test/gtest_output_test.py index 05f49dc4..f91050c0 100755 --- a/test/gtest_output_test.py +++ b/test/gtest_output_test.py @@ -32,6 +32,8 @@ """Tests the text output of Google C++ Testing Framework. SYNOPSIS + gtest_output_test.py --gtest_build_dir=BUILD/DIR --gengolden + # where BUILD/DIR contains the built gtest_output_test_ file. gtest_output_test.py --gengolden gtest_output_test.py """ diff --git a/test/gtest_output_test_.cc b/test/gtest_output_test_.cc index d9f3f9e2..758e18d6 100644 --- a/test/gtest_output_test_.cc +++ b/test/gtest_output_test_.cc @@ -699,6 +699,97 @@ TEST(ExpectFatalFailureTest, FailsWhenStatementThrows) { #endif // GTEST_HAS_EXCEPTIONS +// This #ifdef block tests the output of typed tests. +#ifdef GTEST_HAS_TYPED_TEST + +template +class TypedTest : public testing::Test { +}; + +TYPED_TEST_CASE(TypedTest, testing::Types); + +TYPED_TEST(TypedTest, Success) { + EXPECT_EQ(0, TypeParam()); +} + +TYPED_TEST(TypedTest, Failure) { + EXPECT_EQ(1, TypeParam()) << "Expected failure"; +} + +#endif // GTEST_HAS_TYPED_TEST + +// This #ifdef block tests the output of type-parameterized tests. +#ifdef GTEST_HAS_TYPED_TEST_P + +template +class TypedTestP : public testing::Test { +}; + +TYPED_TEST_CASE_P(TypedTestP); + +TYPED_TEST_P(TypedTestP, Success) { + EXPECT_EQ(0, TypeParam()); +} + +TYPED_TEST_P(TypedTestP, Failure) { + EXPECT_EQ(1, TypeParam()) << "Expected failure"; +} + +REGISTER_TYPED_TEST_CASE_P(TypedTestP, Success, Failure); + +typedef testing::Types UnsignedTypes; +INSTANTIATE_TYPED_TEST_CASE_P(Unsigned, TypedTestP, UnsignedTypes); + +#endif // GTEST_HAS_TYPED_TEST_P + +#ifdef GTEST_HAS_DEATH_TEST + +// We rely on the golden file to verify that tests whose test case +// name ends with DeathTest are run first. + +TEST(ADeathTest, ShouldRunFirst) { +} + +#ifdef GTEST_HAS_TYPED_TEST + +// We rely on the golden file to verify that typed tests whose test +// case name ends with DeathTest are run first. + +template +class ATypedDeathTest : public testing::Test { +}; + +typedef testing::Types NumericTypes; +TYPED_TEST_CASE(ATypedDeathTest, NumericTypes); + +TYPED_TEST(ATypedDeathTest, ShouldRunFirst) { +} + +#endif // GTEST_HAS_TYPED_TEST + +#ifdef GTEST_HAS_TYPED_TEST_P + + +// We rely on the golden file to verify that type-parameterized tests +// whose test case name ends with DeathTest are run first. + +template +class ATypeParamDeathTest : public testing::Test { +}; + +TYPED_TEST_CASE_P(ATypeParamDeathTest); + +TYPED_TEST_P(ATypeParamDeathTest, ShouldRunFirst) { +} + +REGISTER_TYPED_TEST_CASE_P(ATypeParamDeathTest, ShouldRunFirst); + +INSTANTIATE_TYPED_TEST_CASE_P(My, ATypeParamDeathTest, NumericTypes); + +#endif // GTEST_HAS_TYPED_TEST_P + +#endif // GTEST_HAS_DEATH_TEST + // Two test environments for testing testing::AddGlobalTestEnvironment(). class FooEnvironment : public testing::Environment { diff --git a/test/gtest_output_test_golden_lin.txt b/test/gtest_output_test_golden_lin.txt index 1da3bf30..e068bd2c 100644 --- a/test/gtest_output_test_golden_lin.txt +++ b/test/gtest_output_test_golden_lin.txt @@ -7,10 +7,25 @@ Expected: true gtest_output_test_.cc:#: Failure Value of: 3 Expected: 2 -[==========] Running 37 tests from 13 test cases. +[==========] Running 48 tests from 21 test cases. [----------] Global test environment set-up. FooEnvironment::SetUp() called. BarEnvironment::SetUp() called. +[----------] 1 test from ADeathTest +[ RUN ] ADeathTest.ShouldRunFirst +[ OK ] ADeathTest.ShouldRunFirst +[----------] 1 test from ATypedDeathTest/0, where TypeParam = int +[ RUN ] ATypedDeathTest/0.ShouldRunFirst +[ OK ] ATypedDeathTest/0.ShouldRunFirst +[----------] 1 test from ATypedDeathTest/1, where TypeParam = double +[ RUN ] ATypedDeathTest/1.ShouldRunFirst +[ OK ] ATypedDeathTest/1.ShouldRunFirst +[----------] 1 test from My/ATypeParamDeathTest/0, where TypeParam = int +[ RUN ] My/ATypeParamDeathTest/0.ShouldRunFirst +[ OK ] My/ATypeParamDeathTest/0.ShouldRunFirst +[----------] 1 test from My/ATypeParamDeathTest/1, where TypeParam = double +[ RUN ] My/ATypeParamDeathTest/1.ShouldRunFirst +[ OK ] My/ATypeParamDeathTest/1.ShouldRunFirst [----------] 3 tests from FatalFailureTest [ RUN ] FatalFailureTest.FatalFailureInSubroutine (expecting a failure that x should be 1) @@ -341,6 +356,36 @@ gtest.cc:#: Failure Expected: 1 fatal failure Actual: 0 failures [ FAILED ] ExpectFatalFailureTest.FailsWhenStatementReturns +[----------] 2 tests from TypedTest/0, where TypeParam = int +[ RUN ] TypedTest/0.Success +[ OK ] TypedTest/0.Success +[ RUN ] TypedTest/0.Failure +gtest_output_test_.cc:#: Failure +Value of: TypeParam() + Actual: 0 +Expected: 1 +Expected failure +[ FAILED ] TypedTest/0.Failure +[----------] 2 tests from Unsigned/TypedTestP/0, where TypeParam = unsigned char +[ RUN ] Unsigned/TypedTestP/0.Success +[ OK ] Unsigned/TypedTestP/0.Success +[ RUN ] Unsigned/TypedTestP/0.Failure +gtest_output_test_.cc:#: Failure +Value of: TypeParam() + Actual: \0 +Expected: 1 +Expected failure +[ FAILED ] Unsigned/TypedTestP/0.Failure +[----------] 2 tests from Unsigned/TypedTestP/1, where TypeParam = unsigned int +[ RUN ] Unsigned/TypedTestP/1.Success +[ OK ] Unsigned/TypedTestP/1.Success +[ RUN ] Unsigned/TypedTestP/1.Failure +gtest_output_test_.cc:#: Failure +Value of: TypeParam() + Actual: 0 +Expected: 1 +Expected failure +[ FAILED ] Unsigned/TypedTestP/1.Failure [----------] Global test environment tear-down BarEnvironment::TearDown() called. gtest_output_test_.cc:#: Failure @@ -350,9 +395,9 @@ FooEnvironment::TearDown() called. gtest_output_test_.cc:#: Failure Failed Expected fatal failure. -[==========] 37 tests from 13 test cases ran. -[ PASSED ] 11 tests. -[ FAILED ] 26 tests, listed below: +[==========] 48 tests from 21 test cases ran. +[ PASSED ] 19 tests. +[ FAILED ] 29 tests, listed below: [ FAILED ] FatalFailureTest.FatalFailureInSubroutine [ FAILED ] FatalFailureTest.FatalFailureInNestedSubroutine [ FAILED ] FatalFailureTest.NonfatalFailureInSubroutine @@ -379,8 +424,11 @@ Expected fatal failure. [ FAILED ] ExpectFatalFailureTest.FailsWhenThereAreTwoFatalFailures [ FAILED ] ExpectFatalFailureTest.FailsWhenThereIsOneNonfatalFailure [ FAILED ] ExpectFatalFailureTest.FailsWhenStatementReturns +[ FAILED ] TypedTest/0.Failure, where TypeParam = int +[ FAILED ] Unsigned/TypedTestP/0.Failure, where TypeParam = unsigned char +[ FAILED ] Unsigned/TypedTestP/1.Failure, where TypeParam = unsigned int -26 FAILED TESTS +29 FAILED TESTS The non-test part of the code is expected to have 2 failures. gtest_output_test_.cc:#: Failure diff --git a/test/gtest_output_test_golden_win.txt b/test/gtest_output_test_golden_win.txt index 9a13da95..b88b85e5 100644 --- a/test/gtest_output_test_golden_win.txt +++ b/test/gtest_output_test_golden_win.txt @@ -5,7 +5,7 @@ gtest_output_test_.cc:#: error: Value of: false Expected: true gtest_output_test_.cc:#: error: Value of: 3 Expected: 2 -[==========] Running 40 tests from 16 test cases. +[==========] Running 46 tests from 19 test cases. [----------] Global test environment set-up. FooEnvironment::SetUp() called. BarEnvironment::SetUp() called. @@ -317,6 +317,33 @@ Expected non-fatal failure. gtest.cc:#: error: Expected: 1 fatal failure Actual: 0 failures [ FAILED ] ExpectFatalFailureTest.FailsWhenStatementReturns +[----------] 2 tests from TypedTest/0, where TypeParam = int +[ RUN ] TypedTest/0.Success +[ OK ] TypedTest/0.Success +[ RUN ] TypedTest/0.Failure +gtest_output_test_.cc:#: error: Value of: TypeParam() + Actual: 0 +Expected: 1 +Expected failure +[ FAILED ] TypedTest/0.Failure +[----------] 2 tests from Unsigned/TypedTestP/0, where TypeParam = unsigned char +[ RUN ] Unsigned/TypedTestP/0.Success +[ OK ] Unsigned/TypedTestP/0.Success +[ RUN ] Unsigned/TypedTestP/0.Failure +gtest_output_test_.cc:#: error: Value of: TypeParam() + Actual: \0 +Expected: 1 +Expected failure +[ FAILED ] Unsigned/TypedTestP/0.Failure +[----------] 2 tests from Unsigned/TypedTestP/1, where TypeParam = unsigned int +[ RUN ] Unsigned/TypedTestP/1.Success +[ OK ] Unsigned/TypedTestP/1.Success +[ RUN ] Unsigned/TypedTestP/1.Failure +gtest_output_test_.cc:#: error: Value of: TypeParam() + Actual: 0 +Expected: 1 +Expected failure +[ FAILED ] Unsigned/TypedTestP/1.Failure [----------] Global test environment tear-down BarEnvironment::TearDown() called. gtest_output_test_.cc:#: error: Failed @@ -324,9 +351,9 @@ Expected non-fatal failure. FooEnvironment::TearDown() called. gtest_output_test_.cc:#: error: Failed Expected fatal failure. -[==========] 40 tests from 16 test cases ran. -[ PASSED ] 11 tests. -[ FAILED ] 29 tests, listed below: +[==========] 46 tests from 19 test cases ran. +[ PASSED ] 14 tests. +[ FAILED ] 32 tests, listed below: [ FAILED ] FatalFailureTest.FatalFailureInSubroutine [ FAILED ] FatalFailureTest.FatalFailureInNestedSubroutine [ FAILED ] FatalFailureTest.NonfatalFailureInSubroutine @@ -356,8 +383,11 @@ Expected fatal failure. [ FAILED ] ExpectFatalFailureTest.FailsWhenThereAreTwoFatalFailures [ FAILED ] ExpectFatalFailureTest.FailsWhenThereIsOneNonfatalFailure [ FAILED ] ExpectFatalFailureTest.FailsWhenStatementReturns +[ FAILED ] TypedTest/0.Failure, where TypeParam = int +[ FAILED ] Unsigned/TypedTestP/0.Failure, where TypeParam = unsigned char +[ FAILED ] Unsigned/TypedTestP/1.Failure, where TypeParam = unsigned int -29 FAILED TESTS +32 FAILED TESTS The non-test part of the code is expected to have 2 failures. gtest_output_test_.cc:#: error: Value of: false diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index eecaf4ee..7c5123c2 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -529,6 +529,18 @@ TEST(StringTest, EndsWithCaseInsensitive) { EXPECT_FALSE(String("").EndsWithCaseInsensitive("foo")); } +// Tests String::CaseInsensitiveWideCStringEquals +TEST(StringTest, CaseInsensitiveWideCStringEquals) { + EXPECT_TRUE(String::CaseInsensitiveWideCStringEquals(NULL, NULL)); + EXPECT_FALSE(String::CaseInsensitiveWideCStringEquals(NULL, L"")); + EXPECT_FALSE(String::CaseInsensitiveWideCStringEquals(L"", NULL)); + EXPECT_FALSE(String::CaseInsensitiveWideCStringEquals(NULL, L"foobar")); + EXPECT_FALSE(String::CaseInsensitiveWideCStringEquals(L"foobar", NULL)); + EXPECT_TRUE(String::CaseInsensitiveWideCStringEquals(L"foobar", L"foobar")); + EXPECT_TRUE(String::CaseInsensitiveWideCStringEquals(L"foobar", L"FOOBAR")); + EXPECT_TRUE(String::CaseInsensitiveWideCStringEquals(L"FOOBAR", L"foobar")); +} + // Tests that NULL can be assigned to a String. TEST(StringTest, CanBeAssignedNULL) { const String src(NULL); @@ -2134,6 +2146,68 @@ TEST_F(DisabledTestsTest, DISABLED_TestShouldNotRun_2) { FAIL() << "Unexpected failure: Disabled test should not be run."; } +// Tests that disabled typed tests aren't run. + +#ifdef GTEST_HAS_TYPED_TEST + +template +class TypedTest : public Test { +}; + +typedef testing::Types NumericTypes; +TYPED_TEST_CASE(TypedTest, NumericTypes); + +TYPED_TEST(TypedTest, DISABLED_ShouldNotRun) { + FAIL() << "Unexpected failure: Disabled typed test should not run."; +} + +template +class DISABLED_TypedTest : public Test { +}; + +TYPED_TEST_CASE(DISABLED_TypedTest, NumericTypes); + +TYPED_TEST(DISABLED_TypedTest, ShouldNotRun) { + FAIL() << "Unexpected failure: Disabled typed test should not run."; +} + +#endif // GTEST_HAS_TYPED_TEST + +// Tests that disabled type-parameterized tests aren't run. + +#ifdef GTEST_HAS_TYPED_TEST_P + +template +class TypedTestP : public Test { +}; + +TYPED_TEST_CASE_P(TypedTestP); + +TYPED_TEST_P(TypedTestP, DISABLED_ShouldNotRun) { + FAIL() << "Unexpected failure: " + << "Disabled type-parameterized test should not run."; +} + +REGISTER_TYPED_TEST_CASE_P(TypedTestP, DISABLED_ShouldNotRun); + +INSTANTIATE_TYPED_TEST_CASE_P(My, TypedTestP, NumericTypes); + +template +class DISABLED_TypedTestP : public Test { +}; + +TYPED_TEST_CASE_P(DISABLED_TypedTestP); + +TYPED_TEST_P(DISABLED_TypedTestP, ShouldNotRun) { + FAIL() << "Unexpected failure: " + << "Disabled type-parameterized test should not run."; +} + +REGISTER_TYPED_TEST_CASE_P(DISABLED_TypedTestP, ShouldNotRun); + +INSTANTIATE_TYPED_TEST_CASE_P(My, DISABLED_TypedTestP, NumericTypes); + +#endif // GTEST_HAS_TYPED_TEST_P // Tests that assertion macros evaluate their arguments exactly once. @@ -3491,7 +3565,7 @@ class TestInfoTest : public Test { protected: static TestInfo * GetTestInfo(const char* test_name) { return UnitTest::GetInstance()->impl()-> - GetTestCase("TestInfoTest", NULL, NULL)-> + GetTestCase("TestInfoTest", "", NULL, NULL)-> GetTestInfo(test_name); } -- cgit v1.2.3 From 29d8235540f1983c3dbd53a23783530017be80e7 Mon Sep 17 00:00:00 2001 From: shiqian Date: Tue, 9 Sep 2008 03:01:38 +0000 Subject: Adds new files for type-parameterized tests, which I forgot to commit in the previous revision. --- test/gtest-typed-test2_test.cc | 45 ++++++ test/gtest-typed-test_test.cc | 350 +++++++++++++++++++++++++++++++++++++++++ test/gtest-typed-test_test.h | 66 ++++++++ 3 files changed, 461 insertions(+) create mode 100644 test/gtest-typed-test2_test.cc create mode 100644 test/gtest-typed-test_test.cc create mode 100644 test/gtest-typed-test_test.h (limited to 'test') diff --git a/test/gtest-typed-test2_test.cc b/test/gtest-typed-test2_test.cc new file mode 100644 index 00000000..7dabe760 --- /dev/null +++ b/test/gtest-typed-test2_test.cc @@ -0,0 +1,45 @@ +// Copyright 2008 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) + +#include + +#include "test/gtest-typed-test_test.h" +#include + +#ifdef GTEST_HAS_TYPED_TEST_P + +// Tests that the same type-parameterized test case can be +// instantiated in different translation units linked together. +// (ContainerTest is also instantiated in gtest-typed-test_test.cc.) +INSTANTIATE_TYPED_TEST_CASE_P(Vector, ContainerTest, + testing::Types >); + +#endif // GTEST_HAS_TYPED_TEST_P diff --git a/test/gtest-typed-test_test.cc b/test/gtest-typed-test_test.cc new file mode 100644 index 00000000..0cec71a7 --- /dev/null +++ b/test/gtest-typed-test_test.cc @@ -0,0 +1,350 @@ +// Copyright 2008 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) + +#include +#include + +#include "test/gtest-typed-test_test.h" +#include + +using testing::Test; + +// Used for testing that SetUpTestCase()/TearDownTestCase(), fixture +// ctor/dtor, and SetUp()/TearDown() work correctly in typed tests and +// type-parameterized test. +template +class CommonTest : public Test { + // For some technical reason, SetUpTestCase() and TearDownTestCase() + // must be public. + public: + static void SetUpTestCase() { + shared_ = new T(5); + } + + static void TearDownTestCase() { + delete shared_; + shared_ = NULL; + } + + // This 'protected:' is optional. There's no harm in making all + // members of this fixture class template public. + protected: + typedef std::list List; + typedef std::set IntSet; + + CommonTest() : value_(1) {} + + virtual ~CommonTest() { EXPECT_EQ(3, value_); } + + virtual void SetUp() { + EXPECT_EQ(1, value_); + value_++; + } + + virtual void TearDown() { + EXPECT_EQ(2, value_); + value_++; + } + + T value_; + static T* shared_; +}; + +template +T* CommonTest::shared_ = NULL; + +// This #ifdef block tests typed tests. +#ifdef GTEST_HAS_TYPED_TEST + +using testing::Types; + +// Tests that SetUpTestCase()/TearDownTestCase(), fixture ctor/dtor, +// and SetUp()/TearDown() work correctly in typed tests + +typedef Types TwoTypes; +TYPED_TEST_CASE(CommonTest, TwoTypes); + +TYPED_TEST(CommonTest, ValuesAreCorrect) { + // Static members of the fixture class template can be visited via + // the TestFixture:: prefix. + EXPECT_EQ(5, *TestFixture::shared_); + + // Typedefs in the fixture class template can be visited via the + // "typename TestFixture::" prefix. + typename TestFixture::List empty; + EXPECT_EQ(0, empty.size()); + + typename TestFixture::IntSet empty2; + EXPECT_EQ(0, empty2.size()); + + // Non-static members of the fixture class must be visited via + // 'this', as required by C++ for class templates. + EXPECT_EQ(2, this->value_); +} + +// The second test makes sure shared_ is not deleted after the first +// test. +TYPED_TEST(CommonTest, ValuesAreStillCorrect) { + // Static members of the fixture class template can also be visited + // via 'this'. + ASSERT_TRUE(this->shared_ != NULL); + EXPECT_EQ(5, *this->shared_); + + // TypeParam can be used to refer to the type parameter. + EXPECT_EQ(static_cast(2), this->value_); +} + +// Tests that multiple TYPED_TEST_CASE's can be defined in the same +// translation unit. + +template +class TypedTest1 : public Test { +}; + +// Verifies that the second argument of TYPED_TEST_CASE can be a +// single type. +TYPED_TEST_CASE(TypedTest1, int); +TYPED_TEST(TypedTest1, A) {} + +template +class TypedTest2 : public Test { +}; + +// Verifies that the second argument of TYPED_TEST_CASE can be a +// Types<...> type list. +TYPED_TEST_CASE(TypedTest2, Types); + +// This also verifies that tests from different typed test cases can +// share the same name. +TYPED_TEST(TypedTest2, A) {} + +// Tests that a typed test case can be defined in a namespace. + +namespace library1 { + +template +class NumericTest : public Test { +}; + +typedef Types NumericTypes; +TYPED_TEST_CASE(NumericTest, NumericTypes); + +TYPED_TEST(NumericTest, DefaultIsZero) { + EXPECT_EQ(0, TypeParam()); +} + +} // namespace library1 + +#endif // GTEST_HAS_TYPED_TEST + +// This #ifdef block tests type-parameterized tests. +#ifdef GTEST_HAS_TYPED_TEST_P + +using testing::Types; +using testing::internal::TypedTestCasePState; + +// Tests TypedTestCasePState. + +class TypedTestCasePStateTest : public Test { + protected: + virtual void SetUp() { + state_.AddTestName("foo.cc", 0, "FooTest", "A"); + state_.AddTestName("foo.cc", 0, "FooTest", "B"); + state_.AddTestName("foo.cc", 0, "FooTest", "C"); + } + + TypedTestCasePState state_; +}; + +TEST_F(TypedTestCasePStateTest, SucceedsForMatchingList) { + const char* tests = "A, B, C"; + EXPECT_EQ(tests, + state_.VerifyRegisteredTestNames("foo.cc", 1, tests)); +} + +// Makes sure that the order of the tests and spaces around the names +// don't matter. +TEST_F(TypedTestCasePStateTest, IgnoresOrderAndSpaces) { + const char* tests = "A,C, B"; + EXPECT_EQ(tests, + state_.VerifyRegisteredTestNames("foo.cc", 1, tests)); +} + +#ifdef GTEST_HAS_DEATH_TEST + +typedef TypedTestCasePStateTest TypedTestCasePStateDeathTest; + +TEST_F(TypedTestCasePStateDeathTest, DetectsDuplicates) { + EXPECT_DEATH( + state_.VerifyRegisteredTestNames("foo.cc", 1, "A, B, A, C"), + "foo\\.cc:1: Test A is listed more than once\\."); +} + +TEST_F(TypedTestCasePStateDeathTest, DetectsExtraTest) { + EXPECT_DEATH( + state_.VerifyRegisteredTestNames("foo.cc", 1, "A, B, C, D"), + "foo\\.cc:1: No test named D can be found in this test case\\."); +} + +TEST_F(TypedTestCasePStateDeathTest, DetectsMissedTest) { + EXPECT_DEATH( + state_.VerifyRegisteredTestNames("foo.cc", 1, "A, C"), + "foo\\.cc:1: You forgot to list test B\\."); +} + +// Tests that defining a test for a parameterized test case generates +// a run-time error if the test case has been registered. +TEST_F(TypedTestCasePStateDeathTest, DetectsTestAfterRegistration) { + state_.VerifyRegisteredTestNames("foo.cc", 1, "A, B, C"); + EXPECT_DEATH( + state_.AddTestName("foo.cc", 2, "FooTest", "D"), + "foo\\.cc:2: Test D must be defined before REGISTER_TYPED_TEST_CASE_P" + "\\(FooTest, \\.\\.\\.\\)\\."); +} + +#endif // GTEST_HAS_DEATH_TEST + +// Tests that SetUpTestCase()/TearDownTestCase(), fixture ctor/dtor, +// and SetUp()/TearDown() work correctly in type-parameterized tests. + +template +class DerivedTest : public CommonTest { +}; + +TYPED_TEST_CASE_P(DerivedTest); + +TYPED_TEST_P(DerivedTest, ValuesAreCorrect) { + // Static members of the fixture class template can be visited via + // the TestFixture:: prefix. + EXPECT_EQ(5, *TestFixture::shared_); + + // Non-static members of the fixture class must be visited via + // 'this', as required by C++ for class templates. + EXPECT_EQ(2, this->value_); +} + +// The second test makes sure shared_ is not deleted after the first +// test. +TYPED_TEST_P(DerivedTest, ValuesAreStillCorrect) { + // Static members of the fixture class template can also be visited + // via 'this'. + ASSERT_TRUE(this->shared_ != NULL); + EXPECT_EQ(5, *this->shared_); + EXPECT_EQ(2, this->value_); +} + +REGISTER_TYPED_TEST_CASE_P(DerivedTest, + ValuesAreCorrect, ValuesAreStillCorrect); + +typedef Types MyTwoTypes; +INSTANTIATE_TYPED_TEST_CASE_P(My, DerivedTest, MyTwoTypes); + +// Tests that multiple TYPED_TEST_CASE_P's can be defined in the same +// translation unit. + +template +class TypedTestP1 : public Test { +}; + +TYPED_TEST_CASE_P(TypedTestP1); + +// For testing that the code between TYPED_TEST_CASE_P() and +// TYPED_TEST_P() is not enclosed in a namespace. +typedef int IntAfterTypedTestCaseP; + +TYPED_TEST_P(TypedTestP1, A) {} +TYPED_TEST_P(TypedTestP1, B) {} + +// For testing that the code between TYPED_TEST_P() and +// REGISTER_TYPED_TEST_CASE_P() is not enclosed in a namespace. +typedef int IntBeforeRegisterTypedTestCaseP; + +REGISTER_TYPED_TEST_CASE_P(TypedTestP1, A, B); + +template +class TypedTestP2 : public Test { +}; + +TYPED_TEST_CASE_P(TypedTestP2); + +// This also verifies that tests from different type-parameterized +// test cases can share the same name. +TYPED_TEST_P(TypedTestP2, A) {} + +REGISTER_TYPED_TEST_CASE_P(TypedTestP2, A); + +// Verifies that the code between TYPED_TEST_CASE_P() and +// REGISTER_TYPED_TEST_CASE_P() is not enclosed in a namespace. +IntAfterTypedTestCaseP after = 0; +IntBeforeRegisterTypedTestCaseP before = 0; + +// Verifies that the last argument of INSTANTIATE_TYPED_TEST_CASE_P() +// can be either a single type or a Types<...> type list. +INSTANTIATE_TYPED_TEST_CASE_P(Int, TypedTestP1, int); +INSTANTIATE_TYPED_TEST_CASE_P(Int, TypedTestP2, Types); + +// Tests that the same type-parameterized test case can be +// instantiated more than once in the same translation unit. +INSTANTIATE_TYPED_TEST_CASE_P(Double, TypedTestP2, Types); + +// Tests that the same type-parameterized test case can be +// instantiated in different translation units linked together. +// (ContainerTest is also instantiated in gtest-typed-test_test.cc.) +typedef Types, std::set > MyContainers; +INSTANTIATE_TYPED_TEST_CASE_P(My, ContainerTest, MyContainers); + +// Tests that a type-parameterized test case can be defined and +// instantiated in a namespace. + +namespace library2 { + +template +class NumericTest : public Test { +}; + +TYPED_TEST_CASE_P(NumericTest); + +TYPED_TEST_P(NumericTest, DefaultIsZero) { + EXPECT_EQ(0, TypeParam()); +} + +TYPED_TEST_P(NumericTest, ZeroIsLessThanOne) { + EXPECT_LT(TypeParam(0), TypeParam(1)); +} + +REGISTER_TYPED_TEST_CASE_P(NumericTest, + DefaultIsZero, ZeroIsLessThanOne); +typedef Types NumericTypes; +INSTANTIATE_TYPED_TEST_CASE_P(My, NumericTest, NumericTypes); + +} // namespace library2 + +#endif // GTEST_HAS_TYPED_TEST_P diff --git a/test/gtest-typed-test_test.h b/test/gtest-typed-test_test.h new file mode 100644 index 00000000..2e89dc4b --- /dev/null +++ b/test/gtest-typed-test_test.h @@ -0,0 +1,66 @@ +// Copyright 2008 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) + +#ifndef GTEST_TEST_GTEST_TYPED_TEST_TEST_H_ +#define GTEST_TEST_GTEST_TYPED_TEST_TEST_H_ + +#include + +#ifdef GTEST_HAS_TYPED_TEST_P + +using testing::Test; + +// For testing that the same type-parameterized test case can be +// instantiated in different translation units linked together. +// ContainerTest will be instantiated in both gtest-typed-test_test.cc +// and gtest-typed-test2_test.cc. + +template +class ContainerTest : public Test { +}; + +TYPED_TEST_CASE_P(ContainerTest); + +TYPED_TEST_P(ContainerTest, CanBeDefaultConstructed) { + TypeParam container; +} + +TYPED_TEST_P(ContainerTest, InitialSizeIsZero) { + TypeParam container; + EXPECT_EQ(0, container.size()); +} + +REGISTER_TYPED_TEST_CASE_P(ContainerTest, + CanBeDefaultConstructed, InitialSizeIsZero); + +#endif // GTEST_HAS_TYPED_TEST_P + +#endif // GTEST_TEST_GTEST_TYPED_TEST_TEST_H_ -- cgit v1.2.3 From 019d19af978f05b774407e0d46a3bda2c18c67c6 Mon Sep 17 00:00:00 2001 From: shiqian Date: Fri, 12 Sep 2008 04:01:37 +0000 Subject: Improves thread-safe death tests by changing to the original working directory before they are executed; also fixes out-dated comments about death tests. --- test/gtest-death-test_test.cc | 90 +++++++++++++++++++++++++++++-------------- test/gtest-filepath_test.cc | 32 +++++++++++++++ test/gtest_unittest.cc | 8 +++- 3 files changed, 101 insertions(+), 29 deletions(-) (limited to 'test') diff --git a/test/gtest-death-test_test.cc b/test/gtest-death-test_test.cc index 4bfd9d63..9d69b2cd 100644 --- a/test/gtest-death-test_test.cc +++ b/test/gtest-death-test_test.cc @@ -36,6 +36,8 @@ #ifdef GTEST_HAS_DEATH_TEST +#include +#include #include // Indicates that this translation unit is part of Google Test's @@ -85,13 +87,19 @@ class TestForDeathTest : public testing::Test { protected: // A static member function that's expected to die. static void StaticMemberFunction() { - GTEST_LOG(FATAL, "death inside StaticMemberFunction()."); + fprintf(stderr, "%s", "death inside StaticMemberFunction()."); + // We call _exit() instead of exit(), as the former is a direct + // system call and thus safer in the presence of threads. exit() + // will invoke user-defined exit-hooks, which may do dangerous + // things that conflict with death tests. + _exit(1); } // A method of the test fixture that may die. void MemberFunction() { if (should_die_) { - GTEST_LOG(FATAL, "death inside MemberFunction()."); + fprintf(stderr, "%s", "death inside MemberFunction()."); + _exit(1); } } @@ -157,13 +165,13 @@ int DieInDebugElse12(int* sideeffect) { return 12; } -// Returns the exit status of a process that calls exit(2) with a +// Returns the exit status of a process that calls _exit(2) with a // given exit code. This is a helper function for the // ExitStatusPredicateTest test suite. static int NormalExitStatus(int exit_code) { pid_t child_pid = fork(); if (child_pid == 0) { - exit(exit_code); + _exit(exit_code); } int status; waitpid(child_pid, &status, 0); @@ -179,7 +187,7 @@ static int KilledExitStatus(int signum) { pid_t child_pid = fork(); if (child_pid == 0) { raise(signum); - exit(1); + _exit(1); } int status; waitpid(child_pid, &status, 0); @@ -223,7 +231,7 @@ TEST_F(TestForDeathTest, SingleStatement) { ASSERT_DEATH(return, ""); if (true) - EXPECT_DEATH(exit(1), ""); + EXPECT_DEATH(_exit(1), ""); else // This empty "else" branch is meant to ensure that EXPECT_DEATH // doesn't expand into an "if" statement without an "else" @@ -235,12 +243,12 @@ TEST_F(TestForDeathTest, SingleStatement) { if (false) ; else - EXPECT_DEATH(exit(1), "") << 1 << 2 << 3; + EXPECT_DEATH(_exit(1), "") << 1 << 2 << 3; } void DieWithEmbeddedNul() { fprintf(stderr, "Hello%cworld.\n", '\0'); - abort(); + _exit(1); } // Tests that EXPECT_DEATH and ASSERT_DEATH work when the error @@ -257,24 +265,40 @@ TEST_F(TestForDeathTest, DISABLED_EmbeddedNulInMessage) { TEST_F(TestForDeathTest, SwitchStatement) { switch (0) default: - ASSERT_DEATH(exit(1), "") << "exit in default switch handler"; + ASSERT_DEATH(_exit(1), "") << "exit in default switch handler"; switch (0) case 0: - EXPECT_DEATH(exit(1), "") << "exit in switch case"; + EXPECT_DEATH(_exit(1), "") << "exit in switch case"; } -// Tests that a static member function can be used in a death test. -TEST_F(TestForDeathTest, StaticMemberFunction) { +// Tests that a static member function can be used in a "fast" style +// death test. +TEST_F(TestForDeathTest, StaticMemberFunctionFastStyle) { + testing::GTEST_FLAG(death_test_style) = "fast"; ASSERT_DEATH(StaticMemberFunction(), "death.*StaticMember"); } -// Tests that a method of the test fixture can be used in a death test. -TEST_F(TestForDeathTest, MemberFunction) { +// Tests that a method of the test fixture can be used in a "fast" +// style death test. +TEST_F(TestForDeathTest, MemberFunctionFastStyle) { + testing::GTEST_FLAG(death_test_style) = "fast"; should_die_ = true; EXPECT_DEATH(MemberFunction(), "inside.*MemberFunction"); } +// Tests that death tests work even if the current directory has been +// changed. +TEST_F(TestForDeathTest, FastDeathTestInChangedDir) { + testing::GTEST_FLAG(death_test_style) = "fast"; + + chdir("/"); + EXPECT_EXIT(_exit(1), testing::ExitedWithCode(1), ""); + + chdir("/"); + ASSERT_DEATH(_exit(1), ""); +} + // Repeats a representative sample of death tests in the "threadsafe" style: TEST_F(TestForDeathTest, StaticMemberFunctionThreadsafeStyle) { @@ -292,14 +316,24 @@ TEST_F(TestForDeathTest, ThreadsafeDeathTestInLoop) { testing::GTEST_FLAG(death_test_style) = "threadsafe"; for (int i = 0; i < 3; ++i) - EXPECT_EXIT(exit(i), testing::ExitedWithCode(i), "") << ": i = " << i; + EXPECT_EXIT(_exit(i), testing::ExitedWithCode(i), "") << ": i = " << i; +} + +TEST_F(TestForDeathTest, ThreadsafeDeathTestInChangedDir) { + testing::GTEST_FLAG(death_test_style) = "threadsafe"; + + chdir("/"); + EXPECT_EXIT(_exit(1), testing::ExitedWithCode(1), ""); + + chdir("/"); + ASSERT_DEATH(_exit(1), ""); } TEST_F(TestForDeathTest, MixedStyles) { testing::GTEST_FLAG(death_test_style) = "threadsafe"; - EXPECT_DEATH(exit(1), ""); + EXPECT_DEATH(_exit(1), ""); testing::GTEST_FLAG(death_test_style) = "fast"; - EXPECT_DEATH(exit(1), ""); + EXPECT_DEATH(_exit(1), ""); } namespace { @@ -316,7 +350,7 @@ TEST_F(TestForDeathTest, DoesNotExecuteAtforkHooks) { testing::GTEST_FLAG(death_test_style) = "threadsafe"; pthread_flag = false; ASSERT_EQ(0, pthread_atfork(&SetPthreadFlag, NULL, NULL)); - ASSERT_DEATH(exit(1), ""); + ASSERT_DEATH(_exit(1), ""); ASSERT_FALSE(pthread_flag); } @@ -528,8 +562,8 @@ TEST_F(TestForDeathTest, AssertDebugDeathAborts) { // Tests the *_EXIT family of macros, using a variety of predicates. TEST_F(TestForDeathTest, ExitMacros) { - EXPECT_EXIT(exit(1), testing::ExitedWithCode(1), ""); - ASSERT_EXIT(exit(42), testing::ExitedWithCode(42), ""); + EXPECT_EXIT(_exit(1), testing::ExitedWithCode(1), ""); + ASSERT_EXIT(_exit(42), testing::ExitedWithCode(42), ""); EXPECT_EXIT(raise(SIGKILL), testing::KilledBySignal(SIGKILL), "") << "foo"; ASSERT_EXIT(raise(SIGUSR2), testing::KilledBySignal(SIGUSR2), "") << "bar"; @@ -539,7 +573,7 @@ TEST_F(TestForDeathTest, ExitMacros) { }, "This failure is expected."); EXPECT_FATAL_FAILURE({ // NOLINT - ASSERT_EXIT(exit(0), testing::KilledBySignal(SIGSEGV), "") + ASSERT_EXIT(_exit(0), testing::KilledBySignal(SIGSEGV), "") << "This failure is expected, too."; }, "This failure is expected, too."); } @@ -547,7 +581,7 @@ TEST_F(TestForDeathTest, ExitMacros) { TEST_F(TestForDeathTest, InvalidStyle) { testing::GTEST_FLAG(death_test_style) = "rococo"; EXPECT_NONFATAL_FAILURE({ // NOLINT - EXPECT_DEATH(exit(0), "") << "This failure is expected."; + EXPECT_DEATH(_exit(0), "") << "This failure is expected."; }, "This failure is expected."); } @@ -794,7 +828,7 @@ TEST_F(MacroLogicDeathTest, ChildDoesNotDie) { // This time there are two calls to Abort: one since the test didn't // die, and another from the ReturnSentinel when it's destroyed. The // sentinel normally isn't destroyed if a test doesn't die, since - // exit(2) is called in that case by ForkingDeathTest, but not by + // _exit(2) is called in that case by ForkingDeathTest, but not by // our MockDeathTest. ASSERT_EQ(2, factory_->AbortCalls()); EXPECT_EQ(DeathTest::TEST_DID_NOT_DIE, @@ -813,18 +847,18 @@ static size_t GetSuccessfulTestPartCount() { // Tests that a successful death test does not register a successful // test part. TEST(SuccessRegistrationDeathTest, NoSuccessPart) { - EXPECT_DEATH(exit(1), ""); + EXPECT_DEATH(_exit(1), ""); EXPECT_EQ(0u, GetSuccessfulTestPartCount()); } TEST(StreamingAssertionsDeathTest, DeathTest) { - EXPECT_DEATH(exit(1), "") << "unexpected failure"; - ASSERT_DEATH(exit(1), "") << "unexpected failure"; + EXPECT_DEATH(_exit(1), "") << "unexpected failure"; + ASSERT_DEATH(_exit(1), "") << "unexpected failure"; EXPECT_NONFATAL_FAILURE({ // NOLINT - EXPECT_DEATH(exit(0), "") << "expected failure"; + EXPECT_DEATH(_exit(0), "") << "expected failure"; }, "expected failure"); EXPECT_FATAL_FAILURE({ // NOLINT - ASSERT_DEATH(exit(0), "") << "expected failure"; + ASSERT_DEATH(_exit(0), "") << "expected failure"; }, "expected failure"); } diff --git a/test/gtest-filepath_test.cc b/test/gtest-filepath_test.cc index f4b70c36..603427c1 100644 --- a/test/gtest-filepath_test.cc +++ b/test/gtest-filepath_test.cc @@ -91,6 +91,38 @@ const char* MakeTempDir() { } #endif // _WIN32_WCE +#ifndef _WIN32_WCE + +TEST(GetCurrentDirTest, ReturnsCurrentDir) { + EXPECT_FALSE(FilePath::GetCurrentDir().IsEmpty()); + +#ifdef GTEST_OS_WINDOWS + _chdir(PATH_SEP); + const FilePath cwd = FilePath::GetCurrentDir(); + // Skips the ":". + const char* const cwd_without_drive = strchr(cwd.c_str(), ':'); + ASSERT_TRUE(cwd_without_drive != NULL); + EXPECT_STREQ(PATH_SEP, cwd_without_drive + 1); +#else + chdir(PATH_SEP); + EXPECT_STREQ(PATH_SEP, FilePath::GetCurrentDir().c_str()); +#endif +} + +#endif // _WIN32_WCE + +TEST(IsEmptyTest, ReturnsTrueForEmptyPath) { + EXPECT_TRUE(FilePath("").IsEmpty()); + EXPECT_TRUE(FilePath(NULL).IsEmpty()); +} + +TEST(IsEmptyTest, ReturnsFalseForNonEmptyPath) { + EXPECT_FALSE(FilePath("a").IsEmpty()); + EXPECT_FALSE(FilePath(".").IsEmpty()); + EXPECT_FALSE(FilePath("a/b").IsEmpty()); + EXPECT_FALSE(FilePath("a\\b\\").IsEmpty()); +} + // FilePath's functions used by UnitTestOptions::GetOutputFile. // RemoveDirectoryName "" -> "" diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index 7c5123c2..8343795a 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -1142,7 +1142,8 @@ TEST(ParseInt32FlagTest, ParsesAndReturnsValidValue) { } // For the same reason we are not explicitly testing everything in the -// Test class, there are no separate tests for the following classes: +// Test class, there are no separate tests for the following classes +// (except for some trivial cases): // // TestCase, UnitTest, UnitTestResultPrinter. // @@ -1150,6 +1151,11 @@ TEST(ParseInt32FlagTest, ParsesAndReturnsValidValue) { // // TEST, TEST_F, RUN_ALL_TESTS +TEST(UnitTestTest, CanGetOriginalWorkingDir) { + ASSERT_TRUE(UnitTest::GetInstance()->original_working_dir() != NULL); + EXPECT_STRNE(UnitTest::GetInstance()->original_working_dir(), ""); +} + // This group of tests is for predicate assertions (ASSERT_PRED*, etc) // of various arities. They do not attempt to be exhaustive. Rather, // view them as smoke tests that can be easily reviewed and verified. -- cgit v1.2.3 From 36865d8d354465e3461eedf2949a4b7799985d5d Mon Sep 17 00:00:00 2001 From: shiqian Date: Fri, 12 Sep 2008 20:57:22 +0000 Subject: Adds exception assertions. By balaz.dan@gmail.com. --- test/gtest_unittest.cc | 185 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 185 insertions(+) (limited to 'test') diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index 8343795a..b20b98c1 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -2314,6 +2314,56 @@ TEST_F(SingleEvaluationTest, OtherCases) { EXPECT_EQ(3, b_); } +#if GTEST_HAS_EXCEPTIONS + +void ThrowAnInteger() { + throw 1; +} + +// Tests that assertion arguments are evaluated exactly once. +TEST_F(SingleEvaluationTest, ExceptionTests) { + // successful EXPECT_THROW + EXPECT_THROW({ // NOLINT + a_++; + ThrowAnInteger(); + }, int); + EXPECT_EQ(1, a_); + + // failed EXPECT_THROW, throws different + EXPECT_NONFATAL_FAILURE(EXPECT_THROW({ // NOLINT + a_++; + ThrowAnInteger(); + }, bool), "throws a different type"); + EXPECT_EQ(2, a_); + + // failed EXPECT_THROW, throws nothing + EXPECT_NONFATAL_FAILURE(EXPECT_THROW(a_++, bool), "throws nothing"); + EXPECT_EQ(3, a_); + + // successful EXPECT_NO_THROW + EXPECT_NO_THROW(a_++); + EXPECT_EQ(4, a_); + + // failed EXPECT_NO_THROW + EXPECT_NONFATAL_FAILURE(EXPECT_NO_THROW({ // NOLINT + a_++; + ThrowAnInteger(); + }), "it throws"); + EXPECT_EQ(5, a_); + + // successful EXPECT_ANY_THROW + EXPECT_ANY_THROW({ // NOLINT + a_++; + ThrowAnInteger(); + }); + EXPECT_EQ(6, a_); + + // failed EXPECT_ANY_THROW + EXPECT_NONFATAL_FAILURE(EXPECT_ANY_THROW(a_++), "it doesn't"); + EXPECT_EQ(7, a_); +} + +#endif // GTEST_HAS_EXCEPTIONS // Tests non-string assertions. @@ -2487,6 +2537,37 @@ TEST(AssertionTest, ASSERT_GT) { "Expected: (2) > (2), actual: 2 vs 2"); } +#if GTEST_HAS_EXCEPTIONS + +// Tests ASSERT_THROW. +TEST(AssertionTest, ASSERT_THROW) { + ASSERT_THROW(ThrowAnInteger(), int); + EXPECT_FATAL_FAILURE(ASSERT_THROW(ThrowAnInteger(), bool), + "Expected: ThrowAnInteger() throws an exception of type"\ + " bool.\n Actual: it throws a different type."); + EXPECT_FATAL_FAILURE(ASSERT_THROW(1, bool), + "Expected: 1 throws an exception of type bool.\n"\ + " Actual: it throws nothing."); +} + +// Tests ASSERT_NO_THROW. +TEST(AssertionTest, ASSERT_NO_THROW) { + ASSERT_NO_THROW(1); + EXPECT_FATAL_FAILURE(ASSERT_NO_THROW(ThrowAnInteger()), + "Expected: ThrowAnInteger() doesn't throw an exception."\ + "\n Actual: it throws."); +} + +// Tests ASSERT_ANY_THROW. +TEST(AssertionTest, ASSERT_ANY_THROW) { + ASSERT_ANY_THROW(ThrowAnInteger()); + EXPECT_FATAL_FAILURE(ASSERT_ANY_THROW(1), + "Expected: 1 throws an exception.\n Actual: it "\ + "doesn't."); +} + +#endif // GTEST_HAS_EXCEPTIONS + // Makes sure we deal with the precedence of <<. This test should // compile. TEST(AssertionTest, AssertPrecedence) { @@ -2764,6 +2845,32 @@ TEST(AssertionSyntaxTest, BehavesLikeSingleStatement) { ; else EXPECT_GT(3, 2) << ""; + +#if GTEST_HAS_EXCEPTIONS + if (false) + EXPECT_THROW(1, bool); + + if (true) + EXPECT_THROW(ThrowAnInteger(), int); + else + ; + + if (false) + EXPECT_NO_THROW(ThrowAnInteger()); + + if (true) + EXPECT_NO_THROW(1); + else + ; + + if (false) + EXPECT_ANY_THROW(1); + + if (true) + EXPECT_ANY_THROW(ThrowAnInteger()); + else + ; +#endif // GTEST_HAS_EXCEPTIONS } // Tests that the assertion macros work well with switch statements. @@ -2792,6 +2899,22 @@ TEST(AssertionSyntaxTest, WorksWithSwitch) { EXPECT_NE(1, 2); } +#if GTEST_HAS_EXCEPTIONS + +void ThrowAString() { + throw "String"; +} + +// Test that the exception assertion macros compile and work with const +// type qualifier. +TEST(AssertionSyntaxTest, WorksWithConst) { + ASSERT_THROW(ThrowAString(), const char*); + + EXPECT_THROW(ThrowAString(), const char*); +} + +#endif // GTEST_HAS_EXCEPTIONS + } // namespace // Returns the number of successful parts in the current test. @@ -2971,6 +3094,37 @@ TEST(ExpectTest, EXPECT_GT) { "(2) > (3)"); } +#if GTEST_HAS_EXCEPTIONS + +// Tests EXPECT_THROW. +TEST(ExpectTest, EXPECT_THROW) { + EXPECT_THROW(ThrowAnInteger(), int); + EXPECT_NONFATAL_FAILURE(EXPECT_THROW(ThrowAnInteger(), bool), + "Expected: ThrowAnInteger() throws an exception of "\ + "type bool.\n Actual: it throws a different type."); + EXPECT_NONFATAL_FAILURE(EXPECT_THROW(1, bool), + "Expected: 1 throws an exception of type bool.\n"\ + " Actual: it throws nothing."); +} + +// Tests EXPECT_NO_THROW. +TEST(ExpectTest, EXPECT_NO_THROW) { + EXPECT_NO_THROW(1); + EXPECT_NONFATAL_FAILURE(EXPECT_NO_THROW(ThrowAnInteger()), + "Expected: ThrowAnInteger() doesn't throw an "\ + "exception.\n Actual: it throws."); +} + +// Tests EXPECT_ANY_THROW. +TEST(ExpectTest, EXPECT_ANY_THROW) { + EXPECT_ANY_THROW(ThrowAnInteger()); + EXPECT_NONFATAL_FAILURE(EXPECT_ANY_THROW(1), + "Expected: 1 throws an exception.\n Actual: it "\ + "doesn't."); +} + +#endif // GTEST_HAS_EXCEPTIONS + // Make sure we deal with the precedence of <<. TEST(ExpectTest, ExpectPrecedence) { EXPECT_EQ(1 < 2, true); @@ -4477,6 +4631,37 @@ TEST(StreamingAssertionsTest, FloatingPointEquals) { "expected failure"); } +#if GTEST_HAS_EXCEPTIONS + +TEST(StreamingAssertionsTest, Throw) { + EXPECT_THROW(ThrowAnInteger(), int) << "unexpected failure"; + ASSERT_THROW(ThrowAnInteger(), int) << "unexpected failure"; + EXPECT_NONFATAL_FAILURE(EXPECT_THROW(ThrowAnInteger(), bool) << + "expected failure", "expected failure"); + EXPECT_FATAL_FAILURE(ASSERT_THROW(ThrowAnInteger(), bool) << + "expected failure", "expected failure"); +} + +TEST(StreamingAssertionsTest, NoThrow) { + EXPECT_NO_THROW(1) << "unexpected failure"; + ASSERT_NO_THROW(1) << "unexpected failure"; + EXPECT_NONFATAL_FAILURE(EXPECT_NO_THROW(ThrowAnInteger()) << + "expected failure", "expected failure"); + EXPECT_FATAL_FAILURE(ASSERT_NO_THROW(ThrowAnInteger()) << + "expected failure", "expected failure"); +} + +TEST(StreamingAssertionsTest, AnyThrow) { + EXPECT_ANY_THROW(ThrowAnInteger()) << "unexpected failure"; + ASSERT_ANY_THROW(ThrowAnInteger()) << "unexpected failure"; + EXPECT_NONFATAL_FAILURE(EXPECT_ANY_THROW(1) << + "expected failure", "expected failure"); + EXPECT_FATAL_FAILURE(ASSERT_ANY_THROW(1) << + "expected failure", "expected failure"); +} + +#endif // GTEST_HAS_EXCEPTIONS + // Tests that Google Test correctly decides whether to use colors in the output. TEST(ColoredOutputTest, UsesColorsWhenGTestColorFlagIsYes) { -- cgit v1.2.3 From ee39a89debba2b2e00dec3fa2df03e1d3dcb4027 Mon Sep 17 00:00:00 2001 From: shiqian Date: Sat, 13 Sep 2008 00:49:59 +0000 Subject: Adds suffix 'd' to gtest's libs on Windows. Also fixes gtest_unittest on non-English Windows. By balazs.dan@gmail.com. --- test/gtest_unittest.cc | 69 +++++++++----------------------------------------- 1 file changed, 12 insertions(+), 57 deletions(-) (limited to 'test') diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index b20b98c1..abc337f3 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -2720,85 +2720,40 @@ TEST(HRESULTAssertionTest, EXPECT_HRESULT_SUCCEEDED) { EXPECT_HRESULT_SUCCEEDED(S_OK); EXPECT_HRESULT_SUCCEEDED(S_FALSE); -#ifdef _WIN32_WCE - const char* expected = - "Expected: (UnexpectedHRESULTFailure()) succeeds.\n" - " Actual: 0x8000FFFF"; -#else // Windows proper - const char* expected = - "Expected: (UnexpectedHRESULTFailure()) succeeds.\n" - " Actual: 0x8000FFFF Catastrophic failure"; -#endif // _WIN32_WCE EXPECT_NONFATAL_FAILURE(EXPECT_HRESULT_SUCCEEDED(UnexpectedHRESULTFailure()), - expected); + "Expected: (UnexpectedHRESULTFailure()) succeeds.\n" + " Actual: 0x8000FFFF"); } TEST(HRESULTAssertionTest, ASSERT_HRESULT_SUCCEEDED) { ASSERT_HRESULT_SUCCEEDED(S_OK); ASSERT_HRESULT_SUCCEEDED(S_FALSE); -#ifdef _WIN32_WCE - const char* expected = - "Expected: (UnexpectedHRESULTFailure()) succeeds.\n" - " Actual: 0x8000FFFF"; -#else // Windows proper - const char* expected = - "Expected: (UnexpectedHRESULTFailure()) succeeds.\n" - " Actual: 0x8000FFFF Catastrophic failure"; -#endif // _WIN32_WCE - EXPECT_FATAL_FAILURE(ASSERT_HRESULT_SUCCEEDED(UnexpectedHRESULTFailure()), - expected); + "Expected: (UnexpectedHRESULTFailure()) succeeds.\n" + " Actual: 0x8000FFFF"); } TEST(HRESULTAssertionTest, EXPECT_HRESULT_FAILED) { EXPECT_HRESULT_FAILED(E_UNEXPECTED); -#ifdef _WIN32_WCE - const char* expected_success = - "Expected: (OkHRESULTSuccess()) fails.\n" - " Actual: 0x00000000"; - const char* expected_incorrect_function = - "Expected: (FalseHRESULTSuccess()) fails.\n" - " Actual: 0x00000001"; -#else // Windows proper - const char* expected_success = - "Expected: (OkHRESULTSuccess()) fails.\n" - " Actual: 0x00000000 The operation completed successfully"; - const char* expected_incorrect_function = - "Expected: (FalseHRESULTSuccess()) fails.\n" - " Actual: 0x00000001 Incorrect function."; -#endif // _WIN32_WCE - EXPECT_NONFATAL_FAILURE(EXPECT_HRESULT_FAILED(OkHRESULTSuccess()), - expected_success); + "Expected: (OkHRESULTSuccess()) fails.\n" + " Actual: 0x00000000"); EXPECT_NONFATAL_FAILURE(EXPECT_HRESULT_FAILED(FalseHRESULTSuccess()), - expected_incorrect_function); + "Expected: (FalseHRESULTSuccess()) fails.\n" + " Actual: 0x00000001"); } TEST(HRESULTAssertionTest, ASSERT_HRESULT_FAILED) { ASSERT_HRESULT_FAILED(E_UNEXPECTED); -#ifdef _WIN32_WCE - const char* expected_success = - "Expected: (OkHRESULTSuccess()) fails.\n" - " Actual: 0x00000000"; - const char* expected_incorrect_function = - "Expected: (FalseHRESULTSuccess()) fails.\n" - " Actual: 0x00000001"; -#else // Windows proper - const char* expected_success = - "Expected: (OkHRESULTSuccess()) fails.\n" - " Actual: 0x00000000 The operation completed successfully"; - const char* expected_incorrect_function = - "Expected: (FalseHRESULTSuccess()) fails.\n" - " Actual: 0x00000001 Incorrect function."; -#endif // _WIN32_WCE - EXPECT_FATAL_FAILURE(ASSERT_HRESULT_FAILED(OkHRESULTSuccess()), - expected_success); + "Expected: (OkHRESULTSuccess()) fails.\n" + " Actual: 0x00000000"); EXPECT_FATAL_FAILURE(ASSERT_HRESULT_FAILED(FalseHRESULTSuccess()), - expected_incorrect_function); + "Expected: (FalseHRESULTSuccess()) fails.\n" + " Actual: 0x00000001"); } // Tests that streaming to the HRESULT macros works. -- cgit v1.2.3 From f6b0dc0b408f38bb04079b14198d6bdf703e5e56 Mon Sep 17 00:00:00 2001 From: shiqian Date: Thu, 18 Sep 2008 18:06:35 +0000 Subject: Makes Google Test compile (and all tests pass) on cygwin (possibly on wingw too). --- test/gtest_output_test.py | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) (limited to 'test') diff --git a/test/gtest_output_test.py b/test/gtest_output_test.py index f91050c0..68cfe5ec 100755 --- a/test/gtest_output_test.py +++ b/test/gtest_output_test.py @@ -104,6 +104,20 @@ def RemoveTime(output): return re.sub(r'\(\d+ ms', '(? ms', output) +def RemoveTestCounts(output): + """Removes test counts from a Google Test program's output.""" + + output = re.sub(r'\d+ tests from \d+ test cases', + '? tests from ? test cases', output) + return re.sub(r'\d+ tests\.', '? tests.', output) + + +def RemoveDeathTests(output): + """Removes death test information from a Google Test program's output.""" + + return re.sub(r'\n.*DeathTest.*', '', output) + + def NormalizeOutput(output): """Normalizes output (the output of gtest_output_test_.exe).""" @@ -182,7 +196,11 @@ class GTestOutputTest(unittest.TestCase): golden = golden_file.read() golden_file.close() - self.assertEquals(golden, output) + # We want the test to pass regardless of death tests being + # supported or not. + self.assert_(output == golden or + RemoveTestCounts(output) == + RemoveTestCounts(RemoveDeathTests(golden))) if __name__ == '__main__': -- cgit v1.2.3 From e79c3ccb73d68543e8ad98d69179dee74abff7ab Mon Sep 17 00:00:00 2001 From: shiqian Date: Thu, 18 Sep 2008 21:18:11 +0000 Subject: Makes the Python tests more portable by calling standard functions to interpret the result of os.system(). This could fix the broken Python tests on some users' machines. --- test/gtest_break_on_failure_unittest.py | 5 +---- test/gtest_color_test.py | 2 +- test/gtest_test_utils.py | 20 ++++++++++++++++++++ test/gtest_uninitialized_test.py | 8 +------- test/gtest_xml_outfiles_test.py | 2 +- test/gtest_xml_output_unittest.py | 20 +++++++++++--------- 6 files changed, 35 insertions(+), 22 deletions(-) (limited to 'test') diff --git a/test/gtest_break_on_failure_unittest.py b/test/gtest_break_on_failure_unittest.py index 674ef11d..88716c9c 100755 --- a/test/gtest_break_on_failure_unittest.py +++ b/test/gtest_break_on_failure_unittest.py @@ -78,10 +78,7 @@ def Run(command): """ exit_code = os.system(command) - # On Unix-like systems, the lowest 8 bits of the exit code is the - # signal number that killed the process (or 0 if it wasn't killed by - # a signal). - return (exit_code & 255) != 0 + return os.WIFSIGNALED(exit_code) # The unit test. diff --git a/test/gtest_color_test.py b/test/gtest_color_test.py index 71891768..5260a899 100755 --- a/test/gtest_color_test.py +++ b/test/gtest_color_test.py @@ -62,7 +62,7 @@ def UsesColor(term, color_env_var, color_flag): cmd = COMMAND if color_flag is not None: cmd += ' --%s=%s' % (COLOR_FLAG, color_flag) - return os.system(cmd) + return gtest_test_utils.GetExitStatus(os.system(cmd)) class GTestColorTest(unittest.TestCase): diff --git a/test/gtest_test_utils.py b/test/gtest_test_utils.py index 6c158871..f454774d 100755 --- a/test/gtest_test_utils.py +++ b/test/gtest_test_utils.py @@ -96,6 +96,26 @@ def GetBuildDir(): return os.path.abspath(GetFlag('gtest_build_dir')) +def GetExitStatus(exit_code): + """Returns the argument to exit(), or -1 if exit() wasn't called. + + Args: + exit_code: the result value of os.system(command). + """ + + if os.name == 'nt': + # On Windows, os.WEXITSTATUS() doesn't work and os.system() returns + # the argument to exit() directly. + return exit_code + else: + # On Unix, os.WEXITSTATUS() must be used to extract the exit status + # from the result of os.system(). + if os.WIFEXITED(exit_code): + return os.WEXITSTATUS(exit_code) + else: + return -1 + + def Main(): """Runs the unit test.""" diff --git a/test/gtest_uninitialized_test.py b/test/gtest_uninitialized_test.py index d553bbf9..037daa8f 100755 --- a/test/gtest_uninitialized_test.py +++ b/test/gtest_uninitialized_test.py @@ -81,13 +81,7 @@ def TestExitCodeAndOutput(command): """Runs the given command and verifies its exit code and output.""" # Verifies that 'command' exits with code 1. - if IS_WINDOWS: - # On Windows, os.system(command) returns the exit code of 'command'. - AssertEq(1, os.system(command)) - else: - # On Unix-like system, os.system(command) returns 256 times the - # exit code of 'command'. - AssertEq(256, os.system(command)) + AssertEq(1, gtest_test_utils.GetExitStatus(os.system(command))) output = GetOutput(command) Assert('InitGoogleTest' in output) diff --git a/test/gtest_xml_outfiles_test.py b/test/gtest_xml_outfiles_test.py index df0b95bc..c76e1f78 100755 --- a/test/gtest_xml_outfiles_test.py +++ b/test/gtest_xml_outfiles_test.py @@ -103,7 +103,7 @@ class GTestXMLOutFilesTest(gtest_xml_test_utils.GTestXMLTestCase): command = "cd %s && %s --gtest_output=xml:%s &> /dev/null" % ( tempfile.mkdtemp(), gtest_prog_path, self.output_dir_) status = os.system(command) - self.assertEquals(0, status) + self.assertEquals(0, gtest_test_utils.GetExitStatus(status)) # TODO(wan@google.com): libtool causes the built test binary to be # named lt-gtest_xml_outfiles_test_ instead of diff --git a/test/gtest_xml_output_unittest.py b/test/gtest_xml_output_unittest.py index af021a9f..013e7397 100755 --- a/test/gtest_xml_output_unittest.py +++ b/test/gtest_xml_output_unittest.py @@ -128,7 +128,7 @@ class GTestXMLOutputUnitTest(gtest_xml_test_utils.GTestXMLTestCase): status = os.system("cd %s && %s %s=xml &> /dev/null" % (temp_dir, gtest_prog_path, GTEST_OUTPUT_FLAG)) - self.assertEquals(0, status) + self.assertEquals(0, gtest_test_utils.GetExitStatus(status)) self.assert_(os.path.isfile(output_file)) @@ -147,14 +147,16 @@ class GTestXMLOutputUnitTest(gtest_xml_test_utils.GTestXMLTestCase): command = ("%s %s=xml:%s &> /dev/null" % (gtest_prog_path, GTEST_OUTPUT_FLAG, xml_path)) status = os.system(command) - signal = status & 0xff - self.assertEquals(0, signal, - "%s was killed by signal %d" % (gtest_prog_name, signal)) - exit_code = status >> 8 - self.assertEquals(expected_exit_code, exit_code, - "'%s' exited with code %s, which doesn't match " - "the expected exit code %s." - % (command, exit_code, expected_exit_code)) + if os.WIFSIGNALED(status): + signal = os.WTERMSIG(status) + self.assert_(False, + "%s was killed by signal %d" % (gtest_prog_name, signal)) + else: + exit_code = gtest_test_utils.GetExitStatus(status) + self.assertEquals(expected_exit_code, exit_code, + "'%s' exited with code %s, which doesn't match " + "the expected exit code %s." + % (command, exit_code, expected_exit_code)) expected = minidom.parseString(expected_xml) actual = minidom.parse(xml_path) -- cgit v1.2.3 From 64cdcb69b28fc26e78d95c574187f7dd9830c84c Mon Sep 17 00:00:00 2001 From: shiqian Date: Fri, 26 Sep 2008 16:08:30 +0000 Subject: Lots of changes: * changes the XML report format to match JUnit/Ant's. * improves file path handling. * allows the user to disable RTTI using the GTEST_HAS_RTTI macro. * makes the code compile with -Wswitch-enum. --- test/gtest-filepath_test.cc | 106 +++++++++++++++++++++++++++++++++++++- test/gtest_unittest.cc | 24 +++++++++ test/gtest_xml_outfiles_test.py | 6 +-- test/gtest_xml_output_unittest.py | 20 ++++--- test/gtest_xml_test_utils.py | 100 +++++++++++++++++++++-------------- 5 files changed, 204 insertions(+), 52 deletions(-) (limited to 'test') diff --git a/test/gtest-filepath_test.cc b/test/gtest-filepath_test.cc index 603427c1..ae5e3fbc 100644 --- a/test/gtest-filepath_test.cc +++ b/test/gtest-filepath_test.cc @@ -123,8 +123,6 @@ TEST(IsEmptyTest, ReturnsFalseForNonEmptyPath) { EXPECT_FALSE(FilePath("a\\b\\").IsEmpty()); } -// FilePath's functions used by UnitTestOptions::GetOutputFile. - // RemoveDirectoryName "" -> "" TEST(RemoveDirectoryNameTest, WhenEmptyName) { EXPECT_STREQ("", FilePath("").RemoveDirectoryName().c_str()); @@ -257,6 +255,110 @@ TEST(RemoveTrailingPathSeparatorTest, ShouldReturnUnmodified) { FilePath("foo" PATH_SEP "bar").RemoveTrailingPathSeparator().c_str()); } +TEST(DirectoryTest, RootDirectoryExists) { +#ifdef GTEST_OS_WINDOWS // We are on Windows. + char current_drive[_MAX_PATH]; + current_drive[0] = _getdrive() + 'A' - 1; + current_drive[1] = ':'; + current_drive[2] = '\\'; + current_drive[3] = '\0'; + EXPECT_TRUE(FilePath(current_drive).DirectoryExists()); +#else + EXPECT_TRUE(FilePath("/").DirectoryExists()); +#endif // GTEST_OS_WINDOWS +} + +#ifdef GTEST_OS_WINDOWS +TEST(DirectoryTest, RootOfWrongDriveDoesNotExists) { + const int saved_drive_ = _getdrive(); + // Find a drive that doesn't exist. Start with 'Z' to avoid common ones. + for (char drive = 'Z'; drive >= 'A'; drive--) + if (_chdrive(drive - 'A' + 1) == -1) { + char non_drive[_MAX_PATH]; + non_drive[0] = drive; + non_drive[1] = ':'; + non_drive[2] = '\\'; + non_drive[3] = '\0'; + EXPECT_FALSE(FilePath(non_drive).DirectoryExists()); + break; + } + _chdrive(saved_drive_); +} +#endif // GTEST_OS_WINDOWS + +TEST(DirectoryTest, EmptyPathDirectoryDoesNotExist) { + EXPECT_FALSE(FilePath("").DirectoryExists()); +} + +TEST(DirectoryTest, CurrentDirectoryExists) { +#ifdef GTEST_OS_WINDOWS // We are on Windows. +#ifndef _WIN32_CE // Windows CE doesn't have a current directory. + EXPECT_TRUE(FilePath(".").DirectoryExists()); + EXPECT_TRUE(FilePath(".\\").DirectoryExists()); +#endif // _WIN32_CE +#else + EXPECT_TRUE(FilePath(".").DirectoryExists()); + EXPECT_TRUE(FilePath("./").DirectoryExists()); +#endif // GTEST_OS_WINDOWS +} + +TEST(NormalizeTest, NullStringsEqualEmptyDirectory) { + EXPECT_STREQ("", FilePath(NULL).c_str()); + EXPECT_STREQ("", FilePath(String(NULL)).c_str()); +} + +// "foo/bar" == foo//bar" == "foo///bar" +TEST(NormalizeTest, MultipleConsecutiveSepaparatorsInMidstring) { + EXPECT_STREQ("foo" PATH_SEP "bar", + FilePath("foo" PATH_SEP "bar").c_str()); + EXPECT_STREQ("foo" PATH_SEP "bar", + FilePath("foo" PATH_SEP PATH_SEP "bar").c_str()); + EXPECT_STREQ("foo" PATH_SEP "bar", + FilePath("foo" PATH_SEP PATH_SEP PATH_SEP "bar").c_str()); +} + +// "/bar" == //bar" == "///bar" +TEST(NormalizeTest, MultipleConsecutiveSepaparatorsAtStringStart) { + EXPECT_STREQ(PATH_SEP "bar", + FilePath(PATH_SEP "bar").c_str()); + EXPECT_STREQ(PATH_SEP "bar", + FilePath(PATH_SEP PATH_SEP "bar").c_str()); + EXPECT_STREQ(PATH_SEP "bar", + FilePath(PATH_SEP PATH_SEP PATH_SEP "bar").c_str()); +} + +// "foo/" == foo//" == "foo///" +TEST(NormalizeTest, MultipleConsecutiveSepaparatorsAtStringEnd) { + EXPECT_STREQ("foo" PATH_SEP, + FilePath("foo" PATH_SEP).c_str()); + EXPECT_STREQ("foo" PATH_SEP, + FilePath("foo" PATH_SEP PATH_SEP).c_str()); + EXPECT_STREQ("foo" PATH_SEP, + FilePath("foo" PATH_SEP PATH_SEP PATH_SEP).c_str()); +} + +TEST(AssignmentOperatorTest, DefaultAssignedToNonDefault) { + FilePath default_path; + FilePath non_default_path("path"); + non_default_path = default_path; + EXPECT_STREQ("", non_default_path.c_str()); + EXPECT_STREQ("", default_path.c_str()); // RHS var is unchanged. +} + +TEST(AssignmentOperatorTest, NonDefaultAssignedToDefault) { + FilePath non_default_path("path"); + FilePath default_path; + default_path = non_default_path; + EXPECT_STREQ("path", default_path.c_str()); + EXPECT_STREQ("path", non_default_path.c_str()); // RHS var is unchanged. +} + +TEST(AssignmentOperatorTest, ConstAssignedToNonConst) { + const FilePath const_default_path("const_path"); + FilePath non_default_path("path"); + non_default_path = const_default_path; + EXPECT_STREQ("const_path", non_default_path.c_str()); +} class DirectoryCreationTest : public Test { protected: diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index abc337f3..a9281cec 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -58,10 +58,12 @@ namespace testing { namespace internal { +const char* FormatTimeInMillisAsSeconds(TimeInMillis ms); bool ParseInt32Flag(const char* str, const char* flag, Int32* value); } // namespace internal } // namespace testing +using testing::internal::FormatTimeInMillisAsSeconds; using testing::internal::ParseInt32Flag; namespace testing { @@ -118,6 +120,28 @@ using testing::internal::WideStringToUtf8; // This line tests that we can define tests in an unnamed namespace. namespace { +// Tests FormatTimeInMillisAsSeconds(). + +TEST(FormatTimeInMillisAsSecondsTest, FormatsZero) { + EXPECT_STREQ("0", FormatTimeInMillisAsSeconds(0)); +} + +TEST(FormatTimeInMillisAsSecondsTest, FormatsPositiveNumber) { + EXPECT_STREQ("0.003", FormatTimeInMillisAsSeconds(3)); + EXPECT_STREQ("0.01", FormatTimeInMillisAsSeconds(10)); + EXPECT_STREQ("0.2", FormatTimeInMillisAsSeconds(200)); + EXPECT_STREQ("1.2", FormatTimeInMillisAsSeconds(1200)); + EXPECT_STREQ("3", FormatTimeInMillisAsSeconds(3000)); +} + +TEST(FormatTimeInMillisAsSecondsTest, FormatsNegativeNumber) { + EXPECT_STREQ("-0.003", FormatTimeInMillisAsSeconds(-3)); + EXPECT_STREQ("-0.01", FormatTimeInMillisAsSeconds(-10)); + EXPECT_STREQ("-0.2", FormatTimeInMillisAsSeconds(-200)); + EXPECT_STREQ("-1.2", FormatTimeInMillisAsSeconds(-1200)); + EXPECT_STREQ("-3", FormatTimeInMillisAsSeconds(-3000)); +} + #ifndef __SYMBIAN32__ // NULL testing does not work with Symbian compilers. diff --git a/test/gtest_xml_outfiles_test.py b/test/gtest_xml_outfiles_test.py index c76e1f78..b83df775 100755 --- a/test/gtest_xml_outfiles_test.py +++ b/test/gtest_xml_outfiles_test.py @@ -122,9 +122,9 @@ class GTestXMLOutFilesTest(gtest_xml_test_utils.GTestXMLTestCase): actual = minidom.parse(output_file1) else: actual = minidom.parse(output_file2) - self._NormalizeXml(actual.documentElement) - self._AssertEquivalentElements(expected.documentElement, - actual.documentElement) + self.NormalizeXml(actual.documentElement) + self.AssertEquivalentNodes(expected.documentElement, + actual.documentElement) expected.unlink() actual.unlink() diff --git a/test/gtest_xml_output_unittest.py b/test/gtest_xml_output_unittest.py index 013e7397..7206006c 100755 --- a/test/gtest_xml_output_unittest.py +++ b/test/gtest_xml_output_unittest.py @@ -54,14 +54,20 @@ EXPECTED_NON_EMPTY_XML = """ - + - - + + @@ -160,14 +166,14 @@ class GTestXMLOutputUnitTest(gtest_xml_test_utils.GTestXMLTestCase): expected = minidom.parseString(expected_xml) actual = minidom.parse(xml_path) - self._NormalizeXml(actual.documentElement) - self._AssertEquivalentElements(expected.documentElement, - actual.documentElement) + self.NormalizeXml(actual.documentElement) + self.AssertEquivalentNodes(expected.documentElement, + actual.documentElement) expected.unlink() actual .unlink() if __name__ == '__main__': - os.environ['GTEST_STACK_TRACE_DEPTH'] = '0' + os.environ['GTEST_STACK_TRACE_DEPTH'] = '1' gtest_test_utils.Main() diff --git a/test/gtest_xml_test_utils.py b/test/gtest_xml_test_utils.py index c2ea9c1d..5694dff9 100755 --- a/test/gtest_xml_test_utils.py +++ b/test/gtest_xml_test_utils.py @@ -47,27 +47,35 @@ class GTestXMLTestCase(unittest.TestCase): """ - def _AssertEquivalentElements(self, expected_element, actual_element): + def AssertEquivalentNodes(self, expected_node, actual_node): """ - Asserts that actual_element (a DOM element object) is equivalent to - expected_element (another DOM element object), in that it meets all - of the following conditions: - * It has the same tag name as expected_element. - * It has the same set of attributes as expected_element, each with - the same value as the corresponding attribute of expected_element. - An exception is any attribute named "time", which need only be - convertible to a long integer. - * Each child element is equivalent to a child element of - expected_element. Child elements are matched according to an - attribute that varies depending on the element; "name" for - and elements, "message" for - elements. This matching is necessary because child elements are - not guaranteed to be ordered in any particular way. + Asserts that actual_node (a DOM node object) is equivalent to + expected_node (another DOM node object), in that either both of + them are CDATA nodes and have the same value, or both are DOM + elements and actual_node meets all of the following conditions: + + * It has the same tag name as expected_node. + * It has the same set of attributes as expected_node, each with + the same value as the corresponding attribute of expected_node. + An exception is any attribute named "time", which needs only be + convertible to a floating-point number. + * It has an equivalent set of child nodes (including elements and + CDATA sections) as expected_node. Note that we ignore the + order of the children as they are not guaranteed to be in any + particular order. """ - self.assertEquals(expected_element.tagName, actual_element.tagName) - expected_attributes = expected_element.attributes - actual_attributes = actual_element .attributes + if expected_node.nodeType == Node.CDATA_SECTION_NODE: + self.assertEquals(Node.CDATA_SECTION_NODE, actual_node.nodeType) + self.assertEquals(expected_node.nodeValue, actual_node.nodeValue) + return + + self.assertEquals(Node.ELEMENT_NODE, actual_node.nodeType) + self.assertEquals(Node.ELEMENT_NODE, expected_node.nodeType) + self.assertEquals(expected_node.tagName, actual_node.tagName) + + expected_attributes = expected_node.attributes + actual_attributes = actual_node .attributes self.assertEquals(expected_attributes.length, actual_attributes.length) for i in range(expected_attributes.length): expected_attr = expected_attributes.item(i) @@ -75,13 +83,13 @@ class GTestXMLTestCase(unittest.TestCase): self.assert_(actual_attr is not None) self.assertEquals(expected_attr.value, actual_attr.value) - expected_child = self._GetChildElements(expected_element) - actual_child = self._GetChildElements(actual_element) - self.assertEquals(len(expected_child), len(actual_child)) - for child_id, element in expected_child.iteritems(): - self.assert_(child_id in actual_child, - '<%s> is not in <%s>' % (child_id, actual_child)) - self._AssertEquivalentElements(element, actual_child[child_id]) + expected_children = self._GetChildren(expected_node) + actual_children = self._GetChildren(actual_node) + self.assertEquals(len(expected_children), len(actual_children)) + for child_id, child in expected_children.iteritems(): + self.assert_(child_id in actual_children, + '<%s> is not in <%s>' % (child_id, actual_children)) + self.AssertEquivalentNodes(child, actual_children[child_id]) identifying_attribute = { "testsuite": "name", @@ -89,18 +97,20 @@ class GTestXMLTestCase(unittest.TestCase): "failure": "message", } - def _GetChildElements(self, element): + def _GetChildren(self, element): """ - Fetches all of the Element type child nodes of element, a DOM - Element object. Returns them as the values of a dictionary keyed by - the value of one of the node's attributes. For and - elements, the identifying attribute is "name"; for - elements, it is "message". An exception is raised if - any element other than the above three is encountered, if two - child elements with the same identifying attributes are encountered, - or if any other type of node is encountered, other than Text nodes - containing only whitespace. + Fetches all of the child nodes of element, a DOM Element object. + Returns them as the values of a dictionary keyed by the IDs of the + children. For and elements, the ID is the + value of their "name" attribute; for elements, it is the + value of the "message" attribute; for CDATA section node, it is + "detail". An exception is raised if any element other than the + above four is encountered, if two child elements with the same + identifying attributes are encountered, or if any other type of + node is encountered, other than Text nodes containing only + whitespace. """ + children = {} for child in element.childNodes: if child.nodeType == Node.ELEMENT_NODE: @@ -111,11 +121,14 @@ class GTestXMLTestCase(unittest.TestCase): children[childID] = child elif child.nodeType == Node.TEXT_NODE: self.assert_(child.nodeValue.isspace()) + elif child.nodeType == Node.CDATA_SECTION_NODE: + self.assert_("detail" not in children) + children["detail"] = child else: self.fail("Encountered unexpected node type %d" % child.nodeType) return children - def _NormalizeXml(self, element): + def NormalizeXml(self, element): """ Normalizes Google Test's XML output to eliminate references to transient information that may change from run to run. @@ -126,13 +139,20 @@ class GTestXMLTestCase(unittest.TestCase): * The line number reported in the first line of the "message" attribute of elements is replaced with a single asterisk. * The directory names in file paths are removed. + * The stack traces are removed. """ + if element.tagName in ("testsuite", "testcase"): time = element.getAttributeNode("time") - time.value = re.sub(r"^\d+$", "*", time.value) + time.value = re.sub(r"^\d+(\.\d+)?$", "*", time.value) elif element.tagName == "failure": - message = element.getAttributeNode("message") - message.value = re.sub(r"^.*/(.*:)\d+\n", "\\1*\n", message.value) + for child in element.childNodes: + if child.nodeType == Node.CDATA_SECTION_NODE: + # Removes the source line number. + cdata = re.sub(r"^.*/(.*:)\d+\n", "\\1*\n", child.nodeValue) + # Removes the actual stack trace. + child.nodeValue = re.sub(r"\nStack trace:\n(.|\n)*", + "", cdata) for child in element.childNodes: if child.nodeType == Node.ELEMENT_NODE: - self._NormalizeXml(child) + self.NormalizeXml(child) -- cgit v1.2.3 From e0865dd9199e8fffd5c2f95a68de6c1851f77c15 Mon Sep 17 00:00:00 2001 From: shiqian Date: Sat, 11 Oct 2008 07:20:02 +0000 Subject: Many changes: - appends "_" to internal macro names (by Markus Heule). - makes Google Test work with newer versions of tools on Symbian and Windows CE (by Mika Raento). - adds the (ASSERT|EXPECT)_NO_FATAL_FAILURE macros (by Markus Heule). - changes EXPECT_(NON|)FATAL_FAILURE to catch failures in the current thread only (by Markus Heule). - adds the EXPECT_(NON|)FATAL_FAILURE_ON_ALL_THREADS macros (by Markus Heule). - adds GTEST_HAS_PTHREAD and GTEST_IS_THREADSAFE to indicate the availability of and Google Test's thread-safety (by Zhanyong Wan). - adds scons/SConscript for building with scons (by Joi Sigurdsson). - adds src/gtest-all.cc for building Google Test from a single file (by Markus Heule). - updates the xcode project to include new tests (by Preston Jackson). --- test/gtest-death-test_test.cc | 14 +- test/gtest-filepath_test.cc | 3 + test/gtest-test-part_test.cc | 138 +++++++++++ test/gtest_environment_test.cc | 2 +- test/gtest_output_test_.cc | 136 ++++++++++- test/gtest_output_test_golden_lin.txt | 113 ++++++++- test/gtest_output_test_golden_win.txt | 101 +++++++- test/gtest_pred_impl_unittest.cc | 2 +- test/gtest_repeat_test.cc | 6 +- test/gtest_sole_header_test.cc | 57 +++++ test/gtest_stress_test.cc | 30 +++ test/gtest_unittest.cc | 441 ++++++++++++++++++++++++---------- 12 files changed, 889 insertions(+), 154 deletions(-) create mode 100644 test/gtest-test-part_test.cc create mode 100644 test/gtest_sole_header_test.cc (limited to 'test') diff --git a/test/gtest-death-test_test.cc b/test/gtest-death-test_test.cc index 9d69b2cd..07268d00 100644 --- a/test/gtest-death-test_test.cc +++ b/test/gtest-death-test_test.cc @@ -115,7 +115,7 @@ class MayDie { // A member function that may die. void MemberFunction() const { if (should_die_) { - GTEST_LOG(FATAL, "death inside MayDie::MemberFunction()."); + GTEST_LOG_(FATAL, "death inside MayDie::MemberFunction()."); } } @@ -126,26 +126,26 @@ class MayDie { // A global function that's expected to die. void GlobalFunction() { - GTEST_LOG(FATAL, "death inside GlobalFunction()."); + GTEST_LOG_(FATAL, "death inside GlobalFunction()."); } // A non-void function that's expected to die. int NonVoidFunction() { - GTEST_LOG(FATAL, "death inside NonVoidFunction()."); + GTEST_LOG_(FATAL, "death inside NonVoidFunction()."); return 1; } // A unary function that may die. void DieIf(bool should_die) { if (should_die) { - GTEST_LOG(FATAL, "death inside DieIf()."); + GTEST_LOG_(FATAL, "death inside DieIf()."); } } // A binary function that may die. bool DieIfLessThan(int x, int y) { if (x < y) { - GTEST_LOG(FATAL, "death inside DieIfLessThan()."); + GTEST_LOG_(FATAL, "death inside DieIfLessThan()."); } return true; } @@ -160,7 +160,7 @@ void DeathTestSubroutine() { int DieInDebugElse12(int* sideeffect) { if (sideeffect) *sideeffect = 12; #ifndef NDEBUG - GTEST_LOG(FATAL, "debug death inside DieInDebugElse12()"); + GTEST_LOG_(FATAL, "debug death inside DieInDebugElse12()"); #endif // NDEBUG return 12; } @@ -717,7 +717,7 @@ bool MockDeathTestFactory::Create(const char* statement, return true; } -// A test fixture for testing the logic of the GTEST_DEATH_TEST macro. +// A test fixture for testing the logic of the GTEST_DEATH_TEST_ macro. // It installs a MockDeathTestFactory that is used for the duration // of the test case. class MacroLogicDeathTest : public testing::Test { diff --git a/test/gtest-filepath_test.cc b/test/gtest-filepath_test.cc index ae5e3fbc..de8ad01e 100644 --- a/test/gtest-filepath_test.cc +++ b/test/gtest-filepath_test.cc @@ -286,9 +286,12 @@ TEST(DirectoryTest, RootOfWrongDriveDoesNotExists) { } #endif // GTEST_OS_WINDOWS +#ifndef _WIN32_WCE +// Windows CE _does_ consider an empty directory to exist. TEST(DirectoryTest, EmptyPathDirectoryDoesNotExist) { EXPECT_FALSE(FilePath("").DirectoryExists()); } +#endif // ! _WIN32_WCE TEST(DirectoryTest, CurrentDirectoryExists) { #ifdef GTEST_OS_WINDOWS // We are on Windows. diff --git a/test/gtest-test-part_test.cc b/test/gtest-test-part_test.cc new file mode 100644 index 00000000..f4f0d1d5 --- /dev/null +++ b/test/gtest-test-part_test.cc @@ -0,0 +1,138 @@ +// Copyright 2008 Google Inc. All Rights Reserved. +// Author: mheule@google.com (Markus Heule) + +#include + +#include + +using testing::Test; +using testing::TestPartResult; +using testing::TestPartResultArray; + +using testing::TPRT_FATAL_FAILURE; +using testing::TPRT_NONFATAL_FAILURE; +using testing::TPRT_SUCCESS; + +namespace { + +// Tests the TestPartResult class. + +// The test fixture for testing TestPartResult. +class TestPartResultTest : public Test { + protected: + TestPartResultTest() + : r1_(TPRT_SUCCESS, "foo/bar.cc", 10, "Success!"), + r2_(TPRT_NONFATAL_FAILURE, "foo/bar.cc", -1, "Failure!"), + r3_(TPRT_FATAL_FAILURE, NULL, -1, "Failure!") {} + + TestPartResult r1_, r2_, r3_; +}; + +// Tests TestPartResult::type(). +TEST_F(TestPartResultTest, type) { + EXPECT_EQ(TPRT_SUCCESS, r1_.type()); + EXPECT_EQ(TPRT_NONFATAL_FAILURE, r2_.type()); + EXPECT_EQ(TPRT_FATAL_FAILURE, r3_.type()); +} + +// Tests TestPartResult::file_name(). +TEST_F(TestPartResultTest, file_name) { + EXPECT_STREQ("foo/bar.cc", r1_.file_name()); + EXPECT_STREQ(NULL, r3_.file_name()); +} + +// Tests TestPartResult::line_number(). +TEST_F(TestPartResultTest, line_number) { + EXPECT_EQ(10, r1_.line_number()); + EXPECT_EQ(-1, r2_.line_number()); +} + +// Tests TestPartResult::message(). +TEST_F(TestPartResultTest, message) { + EXPECT_STREQ("Success!", r1_.message()); +} + +// Tests TestPartResult::passed(). +TEST_F(TestPartResultTest, Passed) { + EXPECT_TRUE(r1_.passed()); + EXPECT_FALSE(r2_.passed()); + EXPECT_FALSE(r3_.passed()); +} + +// Tests TestPartResult::failed(). +TEST_F(TestPartResultTest, Failed) { + EXPECT_FALSE(r1_.failed()); + EXPECT_TRUE(r2_.failed()); + EXPECT_TRUE(r3_.failed()); +} + +// Tests TestPartResult::fatally_failed(). +TEST_F(TestPartResultTest, FatallyFailed) { + EXPECT_FALSE(r1_.fatally_failed()); + EXPECT_FALSE(r2_.fatally_failed()); + EXPECT_TRUE(r3_.fatally_failed()); +} + +// Tests TestPartResult::nonfatally_failed(). +TEST_F(TestPartResultTest, NonfatallyFailed) { + EXPECT_FALSE(r1_.nonfatally_failed()); + EXPECT_TRUE(r2_.nonfatally_failed()); + EXPECT_FALSE(r3_.nonfatally_failed()); +} + +// Tests the TestPartResultArray class. + +class TestPartResultArrayTest : public Test { + protected: + TestPartResultArrayTest() + : r1_(TPRT_NONFATAL_FAILURE, "foo/bar.cc", -1, "Failure 1"), + r2_(TPRT_FATAL_FAILURE, "foo/bar.cc", -1, "Failure 2") {} + + const TestPartResult r1_, r2_; +}; + +// Tests that TestPartResultArray initially has size 0. +TEST_F(TestPartResultArrayTest, InitialSizeIsZero) { + TestPartResultArray results; + EXPECT_EQ(0, results.size()); +} + +// Tests that TestPartResultArray contains the given TestPartResult +// after one Append() operation. +TEST_F(TestPartResultArrayTest, ContainsGivenResultAfterAppend) { + TestPartResultArray results; + results.Append(r1_); + EXPECT_EQ(1, results.size()); + EXPECT_STREQ("Failure 1", results.GetTestPartResult(0).message()); +} + +// Tests that TestPartResultArray contains the given TestPartResults +// after two Append() operations. +TEST_F(TestPartResultArrayTest, ContainsGivenResultsAfterTwoAppends) { + TestPartResultArray results; + results.Append(r1_); + results.Append(r2_); + EXPECT_EQ(2, results.size()); + EXPECT_STREQ("Failure 1", results.GetTestPartResult(0).message()); + EXPECT_STREQ("Failure 2", results.GetTestPartResult(1).message()); +} + +#ifdef GTEST_HAS_DEATH_TEST + +typedef TestPartResultArrayTest TestPartResultArrayDeathTest; + +// Tests that the program dies when GetTestPartResult() is called with +// an invalid index. +TEST_F(TestPartResultArrayDeathTest, DiesWhenIndexIsOutOfBound) { + TestPartResultArray results; + results.Append(r1_); + + EXPECT_DEATH(results.GetTestPartResult(-1), ""); + EXPECT_DEATH(results.GetTestPartResult(1), ""); +} + +#endif // GTEST_HAS_DEATH_TEST + +// TODO(mheule@google.com): Add a test for the class HasNewFatalFailureHelper. + +} // namespace diff --git a/test/gtest_environment_test.cc b/test/gtest_environment_test.cc index 999ed787..c9392614 100644 --- a/test/gtest_environment_test.cc +++ b/test/gtest_environment_test.cc @@ -36,7 +36,7 @@ #include namespace testing { -GTEST_DECLARE_string(filter); +GTEST_DECLARE_string_(filter); } namespace { diff --git a/test/gtest_output_test_.cc b/test/gtest_output_test_.cc index 758e18d6..203374ec 100644 --- a/test/gtest_output_test_.cc +++ b/test/gtest_output_test_.cc @@ -46,14 +46,20 @@ #include +#if GTEST_HAS_PTHREAD +#include +#endif // GTEST_HAS_PTHREAD + #ifdef GTEST_OS_LINUX #include #include -#include #include #include #endif // GTEST_OS_LINUX +using testing::ScopedFakeTestPartResultReporter; +using testing::TestPartResultArray; + // Tests catching fatal failures. // A subroutine used by the following test. @@ -790,6 +796,134 @@ INSTANTIATE_TYPED_TEST_CASE_P(My, ATypeParamDeathTest, NumericTypes); #endif // GTEST_HAS_DEATH_TEST +// Tests various failure conditions of +// EXPECT_{,NON}FATAL_FAILURE{,_ON_ALL_THREADS}. +class ExpectFailureTest : public testing::Test { + protected: + enum FailureMode { + FATAL_FAILURE, + NONFATAL_FAILURE + }; + static void AddFailure(FailureMode failure) { + if (failure == FATAL_FAILURE) { + FAIL() << "Expected fatal failure."; + } else { + ADD_FAILURE() << "Expected non-fatal failure."; + } + } +}; + +TEST_F(ExpectFailureTest, ExpectFatalFailure) { + // Expected fatal failure, but succeeds. + printf("(expecting 1 failure)\n"); + EXPECT_FATAL_FAILURE(SUCCEED(), "Expected fatal failure."); + // Expected fatal failure, but got a non-fatal failure. + printf("(expecting 1 failure)\n"); + EXPECT_FATAL_FAILURE(AddFailure(NONFATAL_FAILURE), "Expected non-fatal " + "failure."); + // Wrong message. + printf("(expecting 1 failure)\n"); + EXPECT_FATAL_FAILURE(AddFailure(FATAL_FAILURE), "Some other fatal failure " + "expected."); +} + +TEST_F(ExpectFailureTest, ExpectNonFatalFailure) { + // Expected non-fatal failure, but succeeds. + printf("(expecting 1 failure)\n"); + EXPECT_NONFATAL_FAILURE(SUCCEED(), "Expected non-fatal failure."); + // Expected non-fatal failure, but got a fatal failure. + printf("(expecting 1 failure)\n"); + EXPECT_NONFATAL_FAILURE(AddFailure(FATAL_FAILURE), "Expected fatal failure."); + // Wrong message. + printf("(expecting 1 failure)\n"); + EXPECT_NONFATAL_FAILURE(AddFailure(NONFATAL_FAILURE), "Some other non-fatal " + "failure."); +} + +#if GTEST_IS_THREADSAFE && GTEST_HAS_PTHREAD + +class ExpectFailureWithThreadsTest : public ExpectFailureTest { + protected: + static void AddFailureInOtherThread(FailureMode failure) { + pthread_t tid; + pthread_create(&tid, + NULL, + ExpectFailureWithThreadsTest::FailureThread, + &failure); + pthread_join(tid, NULL); + } + private: + static void* FailureThread(void* attr) { + FailureMode* failure = static_cast(attr); + AddFailure(*failure); + return NULL; + } +}; + +TEST_F(ExpectFailureWithThreadsTest, ExpectFatalFailure) { + // We only intercept the current thread. + printf("(expecting 2 failures)\n"); + EXPECT_FATAL_FAILURE(AddFailureInOtherThread(FATAL_FAILURE), + "Expected fatal failure."); +} + +TEST_F(ExpectFailureWithThreadsTest, ExpectNonFatalFailure) { + // We only intercept the current thread. + printf("(expecting 2 failures)\n"); + EXPECT_NONFATAL_FAILURE(AddFailureInOtherThread(NONFATAL_FAILURE), + "Expected non-fatal failure."); +} + +typedef ExpectFailureWithThreadsTest ScopedFakeTestPartResultReporterTest; + +// Tests that the ScopedFakeTestPartResultReporter only catches failures from +// the current thread if it is instantiated with INTERCEPT_ONLY_CURRENT_THREAD. +TEST_F(ScopedFakeTestPartResultReporterTest, InterceptOnlyCurrentThread) { + printf("(expecting 2 failures)\n"); + TestPartResultArray results; + { + ScopedFakeTestPartResultReporter reporter( + ScopedFakeTestPartResultReporter::INTERCEPT_ONLY_CURRENT_THREAD, + &results); + AddFailureInOtherThread(FATAL_FAILURE); + AddFailureInOtherThread(NONFATAL_FAILURE); + } + // The two failures should not have been intercepted. + EXPECT_EQ(0, results.size()) << "This shouldn't fail."; +} + +#endif // GTEST_IS_THREADSAFE && GTEST_HAS_PTHREAD + +TEST_F(ExpectFailureTest, ExpectFatalFailureOnAllThreads) { + // Expected fatal failure, but succeeds. + printf("(expecting 1 failure)\n"); + EXPECT_FATAL_FAILURE_ON_ALL_THREADS(SUCCEED(), "Expected fatal failure."); + // Expected fatal failure, but got a non-fatal failure. + printf("(expecting 1 failure)\n"); + EXPECT_FATAL_FAILURE_ON_ALL_THREADS(AddFailure(NONFATAL_FAILURE), + "Expected non-fatal failure."); + // Wrong message. + printf("(expecting 1 failure)\n"); + EXPECT_FATAL_FAILURE_ON_ALL_THREADS(AddFailure(FATAL_FAILURE), + "Some other fatal failure expected."); +} + +TEST_F(ExpectFailureTest, ExpectNonFatalFailureOnAllThreads) { + // Expected non-fatal failure, but succeeds. + printf("(expecting 1 failure)\n"); + EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(SUCCEED(), "Expected non-fatal " + "failure."); + // Expected non-fatal failure, but got a fatal failure. + printf("(expecting 1 failure)\n"); + EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(AddFailure(FATAL_FAILURE), + "Expected fatal failure."); + // Wrong message. + printf("(expecting 1 failure)\n"); + EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(AddFailure(NONFATAL_FAILURE), + "Some other non-fatal failure."); +} + + // Two test environments for testing testing::AddGlobalTestEnvironment(). class FooEnvironment : public testing::Environment { diff --git a/test/gtest_output_test_golden_lin.txt b/test/gtest_output_test_golden_lin.txt index e068bd2c..fb932fa0 100644 --- a/test/gtest_output_test_golden_lin.txt +++ b/test/gtest_output_test_golden_lin.txt @@ -7,7 +7,7 @@ Expected: true gtest_output_test_.cc:#: Failure Value of: 3 Expected: 2 -[==========] Running 48 tests from 21 test cases. +[==========] Running 52 tests from 22 test cases. [----------] Global test environment set-up. FooEnvironment::SetUp() called. BarEnvironment::SetUp() called. @@ -386,6 +386,107 @@ Value of: TypeParam() Expected: 1 Expected failure [ FAILED ] Unsigned/TypedTestP/1.Failure +[----------] 4 tests from ExpectFailureTest +[ RUN ] ExpectFailureTest.ExpectFatalFailure +(expecting 1 failure) +gtest.cc:#: Failure +Expected: 1 fatal failure + Actual: +gtest_output_test_.cc:#: Success: +Succeeded + +(expecting 1 failure) +gtest.cc:#: Failure +Expected: 1 fatal failure + Actual: +gtest_output_test_.cc:#: Non-fatal failure: +Failed +Expected non-fatal failure. + +(expecting 1 failure) +gtest.cc:#: Failure +Expected: 1 fatal failure containing "Some other fatal failure expected." + Actual: +gtest_output_test_.cc:#: Fatal failure: +Failed +Expected fatal failure. + +[ FAILED ] ExpectFailureTest.ExpectFatalFailure +[ RUN ] ExpectFailureTest.ExpectNonFatalFailure +(expecting 1 failure) +gtest.cc:#: Failure +Expected: 1 non-fatal failure + Actual: +gtest_output_test_.cc:#: Success: +Succeeded + +(expecting 1 failure) +gtest.cc:#: Failure +Expected: 1 non-fatal failure + Actual: +gtest_output_test_.cc:#: Fatal failure: +Failed +Expected fatal failure. + +(expecting 1 failure) +gtest.cc:#: Failure +Expected: 1 non-fatal failure containing "Some other non-fatal failure." + Actual: +gtest_output_test_.cc:#: Non-fatal failure: +Failed +Expected non-fatal failure. + +[ FAILED ] ExpectFailureTest.ExpectNonFatalFailure +[ RUN ] ExpectFailureTest.ExpectFatalFailureOnAllThreads +(expecting 1 failure) +gtest.cc:#: Failure +Expected: 1 fatal failure + Actual: +gtest_output_test_.cc:#: Success: +Succeeded + +(expecting 1 failure) +gtest.cc:#: Failure +Expected: 1 fatal failure + Actual: +gtest_output_test_.cc:#: Non-fatal failure: +Failed +Expected non-fatal failure. + +(expecting 1 failure) +gtest.cc:#: Failure +Expected: 1 fatal failure containing "Some other fatal failure expected." + Actual: +gtest_output_test_.cc:#: Fatal failure: +Failed +Expected fatal failure. + +[ FAILED ] ExpectFailureTest.ExpectFatalFailureOnAllThreads +[ RUN ] ExpectFailureTest.ExpectNonFatalFailureOnAllThreads +(expecting 1 failure) +gtest.cc:#: Failure +Expected: 1 non-fatal failure + Actual: +gtest_output_test_.cc:#: Success: +Succeeded + +(expecting 1 failure) +gtest.cc:#: Failure +Expected: 1 non-fatal failure + Actual: +gtest_output_test_.cc:#: Fatal failure: +Failed +Expected fatal failure. + +(expecting 1 failure) +gtest.cc:#: Failure +Expected: 1 non-fatal failure containing "Some other non-fatal failure." + Actual: +gtest_output_test_.cc:#: Non-fatal failure: +Failed +Expected non-fatal failure. + +[ FAILED ] ExpectFailureTest.ExpectNonFatalFailureOnAllThreads [----------] Global test environment tear-down BarEnvironment::TearDown() called. gtest_output_test_.cc:#: Failure @@ -395,9 +496,9 @@ FooEnvironment::TearDown() called. gtest_output_test_.cc:#: Failure Failed Expected fatal failure. -[==========] 48 tests from 21 test cases ran. +[==========] 52 tests from 22 test cases ran. [ PASSED ] 19 tests. -[ FAILED ] 29 tests, listed below: +[ FAILED ] 33 tests, listed below: [ FAILED ] FatalFailureTest.FatalFailureInSubroutine [ FAILED ] FatalFailureTest.FatalFailureInNestedSubroutine [ FAILED ] FatalFailureTest.NonfatalFailureInSubroutine @@ -427,8 +528,12 @@ Expected fatal failure. [ FAILED ] TypedTest/0.Failure, where TypeParam = int [ FAILED ] Unsigned/TypedTestP/0.Failure, where TypeParam = unsigned char [ FAILED ] Unsigned/TypedTestP/1.Failure, where TypeParam = unsigned int +[ FAILED ] ExpectFailureTest.ExpectFatalFailure +[ FAILED ] ExpectFailureTest.ExpectNonFatalFailure +[ FAILED ] ExpectFailureTest.ExpectFatalFailureOnAllThreads +[ FAILED ] ExpectFailureTest.ExpectNonFatalFailureOnAllThreads -29 FAILED TESTS +33 FAILED TESTS The non-test part of the code is expected to have 2 failures. gtest_output_test_.cc:#: Failure diff --git a/test/gtest_output_test_golden_win.txt b/test/gtest_output_test_golden_win.txt index b88b85e5..579b10bb 100644 --- a/test/gtest_output_test_golden_win.txt +++ b/test/gtest_output_test_golden_win.txt @@ -5,7 +5,7 @@ gtest_output_test_.cc:#: error: Value of: false Expected: true gtest_output_test_.cc:#: error: Value of: 3 Expected: 2 -[==========] Running 46 tests from 19 test cases. +[==========] Running 50 tests from 20 test cases. [----------] Global test environment set-up. FooEnvironment::SetUp() called. BarEnvironment::SetUp() called. @@ -344,6 +344,95 @@ gtest_output_test_.cc:#: error: Value of: TypeParam() Expected: 1 Expected failure [ FAILED ] Unsigned/TypedTestP/1.Failure +[----------] 4 tests from ExpectFailureTest +[ RUN ] ExpectFailureTest.ExpectFatalFailure +(expecting 1 failure) +gtest.cc:#: error: Expected: 1 fatal failure + Actual: +gtest_output_test_.cc:#: Success: +Succeeded + +(expecting 1 failure) +gtest.cc:#: error: Expected: 1 fatal failure + Actual: +gtest_output_test_.cc:#: Non-fatal failure: +Failed +Expected non-fatal failure. + +(expecting 1 failure) +gtest.cc:#: error: Expected: 1 fatal failure containing "Some other fatal failure expected." + Actual: +gtest_output_test_.cc:#: Fatal failure: +Failed +Expected fatal failure. + +[ FAILED ] ExpectFailureTest.ExpectFatalFailure +[ RUN ] ExpectFailureTest.ExpectNonFatalFailure +(expecting 1 failure) +gtest.cc:#: error: Expected: 1 non-fatal failure + Actual: +gtest_output_test_.cc:#: Success: +Succeeded + +(expecting 1 failure) +gtest.cc:#: error: Expected: 1 non-fatal failure + Actual: +gtest_output_test_.cc:#: Fatal failure: +Failed +Expected fatal failure. + +(expecting 1 failure) +gtest.cc:#: error: Expected: 1 non-fatal failure containing "Some other non-fatal failure." + Actual: +gtest_output_test_.cc:#: Non-fatal failure: +Failed +Expected non-fatal failure. + +[ FAILED ] ExpectFailureTest.ExpectNonFatalFailure +[ RUN ] ExpectFailureTest.ExpectFatalFailureOnAllThreads +(expecting 1 failure) +gtest.cc:#: error: Expected: 1 fatal failure + Actual: +gtest_output_test_.cc:#: Success: +Succeeded + +(expecting 1 failure) +gtest.cc:#: error: Expected: 1 fatal failure + Actual: +gtest_output_test_.cc:#: Non-fatal failure: +Failed +Expected non-fatal failure. + +(expecting 1 failure) +gtest.cc:#: error: Expected: 1 fatal failure containing "Some other fatal failure expected." + Actual: +gtest_output_test_.cc:#: Fatal failure: +Failed +Expected fatal failure. + +[ FAILED ] ExpectFailureTest.ExpectFatalFailureOnAllThreads +[ RUN ] ExpectFailureTest.ExpectNonFatalFailureOnAllThreads +(expecting 1 failure) +gtest.cc:#: error: Expected: 1 non-fatal failure + Actual: +gtest_output_test_.cc:#: Success: +Succeeded + +(expecting 1 failure) +gtest.cc:#: error: Expected: 1 non-fatal failure + Actual: +gtest_output_test_.cc:#: Fatal failure: +Failed +Expected fatal failure. + +(expecting 1 failure) +gtest.cc:#: error: Expected: 1 non-fatal failure containing "Some other non-fatal failure." + Actual: +gtest_output_test_.cc:#: Non-fatal failure: +Failed +Expected non-fatal failure. + +[ FAILED ] ExpectFailureTest.ExpectNonFatalFailureOnAllThreads [----------] Global test environment tear-down BarEnvironment::TearDown() called. gtest_output_test_.cc:#: error: Failed @@ -351,9 +440,9 @@ Expected non-fatal failure. FooEnvironment::TearDown() called. gtest_output_test_.cc:#: error: Failed Expected fatal failure. -[==========] 46 tests from 19 test cases ran. +[==========] 50 tests from 20 test cases ran. [ PASSED ] 14 tests. -[ FAILED ] 32 tests, listed below: +[ FAILED ] 36 tests, listed below: [ FAILED ] FatalFailureTest.FatalFailureInSubroutine [ FAILED ] FatalFailureTest.FatalFailureInNestedSubroutine [ FAILED ] FatalFailureTest.NonfatalFailureInSubroutine @@ -386,8 +475,12 @@ Expected fatal failure. [ FAILED ] TypedTest/0.Failure, where TypeParam = int [ FAILED ] Unsigned/TypedTestP/0.Failure, where TypeParam = unsigned char [ FAILED ] Unsigned/TypedTestP/1.Failure, where TypeParam = unsigned int +[ FAILED ] ExpectFailureTest.ExpectFatalFailure +[ FAILED ] ExpectFailureTest.ExpectNonFatalFailure +[ FAILED ] ExpectFailureTest.ExpectFatalFailureOnAllThreads +[ FAILED ] ExpectFailureTest.ExpectNonFatalFailureOnAllThreads -32 FAILED TESTS +36 FAILED TESTS The non-test part of the code is expected to have 2 failures. gtest_output_test_.cc:#: error: Value of: false diff --git a/test/gtest_pred_impl_unittest.cc b/test/gtest_pred_impl_unittest.cc index 3dea9904..e7ee54b5 100644 --- a/test/gtest_pred_impl_unittest.cc +++ b/test/gtest_pred_impl_unittest.cc @@ -27,7 +27,7 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// This file is AUTOMATICALLY GENERATED on 06/11/2008 by command +// This file is AUTOMATICALLY GENERATED on 10/02/2008 by command // 'gen_gtest_pred_impl.py 5'. DO NOT EDIT BY HAND! // Regression test for gtest_pred_impl.h diff --git a/test/gtest_repeat_test.cc b/test/gtest_repeat_test.cc index e2f03812..80287373 100644 --- a/test/gtest_repeat_test.cc +++ b/test/gtest_repeat_test.cc @@ -46,9 +46,9 @@ namespace testing { -GTEST_DECLARE_string(death_test_style); -GTEST_DECLARE_string(filter); -GTEST_DECLARE_int32(repeat); +GTEST_DECLARE_string_(death_test_style); +GTEST_DECLARE_string_(filter); +GTEST_DECLARE_int32_(repeat); } // namespace testing diff --git a/test/gtest_sole_header_test.cc b/test/gtest_sole_header_test.cc new file mode 100644 index 00000000..de91e800 --- /dev/null +++ b/test/gtest_sole_header_test.cc @@ -0,0 +1,57 @@ +// Copyright 2008, 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: mheule@google.com (Markus Heule) +// +// This test verifies that it's possible to use Google Test by including +// the gtest.h header file alone. + +#include + +namespace { + +void Subroutine() { + EXPECT_EQ(42, 42); +} + +TEST(NoFatalFailureTest, ExpectNoFatalFailure) { + EXPECT_NO_FATAL_FAILURE(;); + EXPECT_NO_FATAL_FAILURE(SUCCEED()); + EXPECT_NO_FATAL_FAILURE(Subroutine()); + EXPECT_NO_FATAL_FAILURE({ SUCCEED(); }); +} + +TEST(NoFatalFailureTest, AssertNoFatalFailure) { + ASSERT_NO_FATAL_FAILURE(;); + ASSERT_NO_FATAL_FAILURE(SUCCEED()); + ASSERT_NO_FATAL_FAILURE(Subroutine()); + ASSERT_NO_FATAL_FAILURE({ SUCCEED(); }); +} + +} // namespace diff --git a/test/gtest_stress_test.cc b/test/gtest_stress_test.cc index f833b7c6..c58f56ca 100644 --- a/test/gtest_stress_test.cc +++ b/test/gtest_stress_test.cc @@ -112,6 +112,36 @@ TEST(StressTest, CanUseScopedTraceAndAssertionsInManyThreads) { // ManyAsserts() in many threads here. } +TEST(NoFatalFailureTest, ExpectNoFatalFailureIgnoresFailuresInOtherThreads) { + // TODO(mheule@google.com): Test this works correctly when Google + // Test is made thread-safe. +} + +TEST(NoFatalFailureTest, AssertNoFatalFailureIgnoresFailuresInOtherThreads) { + // TODO(mheule@google.com): Test this works correctly when Google + // Test is made thread-safe. +} + +TEST(FatalFailureTest, ExpectFatalFailureIgnoresFailuresInOtherThreads) { + // TODO(mheule@google.com): Test this works correctly when Google + // Test is made thread-safe. +} + +TEST(FatalFailureOnAllThreadsTest, ExpectFatalFailureOnAllThreads) { + // TODO(wan@google.com): Test this works correctly when Google Test + // is made thread-safe. +} + +TEST(NonFatalFailureTest, ExpectNonFatalFailureIgnoresFailuresInOtherThreads) { + // TODO(mheule@google.com): Test this works correctly when Google + // Test is made thread-safe. +} + +TEST(NonFatalFailureOnAllThreadsTest, ExpectNonFatalFailureOnAllThreads) { + // TODO(wan@google.com): Test this works correctly when Google Test + // is made thread-safe. +} + } // namespace } // namespace testing diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index a9281cec..62cfaa39 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -46,11 +46,14 @@ #include +#if GTEST_HAS_PTHREAD +#include +#endif // GTEST_HAS_PTHREAD + #ifdef GTEST_OS_LINUX #include #include #include -#include #include #include #include @@ -68,8 +71,8 @@ using testing::internal::ParseInt32Flag; namespace testing { -GTEST_DECLARE_string(output); -GTEST_DECLARE_string(color); +GTEST_DECLARE_string_(output); +GTEST_DECLARE_string_(color); namespace internal { bool ShouldUseColor(bool stdout_is_tty); @@ -114,6 +117,7 @@ using testing::internal::StreamableToString; using testing::internal::String; using testing::internal::TestProperty; using testing::internal::TestResult; +using testing::internal::ThreadLocal; using testing::internal::UnitTestImpl; using testing::internal::WideStringToUtf8; @@ -142,31 +146,31 @@ TEST(FormatTimeInMillisAsSecondsTest, FormatsNegativeNumber) { EXPECT_STREQ("-3", FormatTimeInMillisAsSeconds(-3000)); } -#ifndef __SYMBIAN32__ +#ifndef GTEST_OS_SYMBIAN // NULL testing does not work with Symbian compilers. -// Tests that GTEST_IS_NULL_LITERAL(x) is true when x is a null +// Tests that GTEST_IS_NULL_LITERAL_(x) is true when x is a null // pointer literal. TEST(NullLiteralTest, IsTrueForNullLiterals) { - EXPECT_TRUE(GTEST_IS_NULL_LITERAL(NULL)); - EXPECT_TRUE(GTEST_IS_NULL_LITERAL(0)); - EXPECT_TRUE(GTEST_IS_NULL_LITERAL(1 - 1)); - EXPECT_TRUE(GTEST_IS_NULL_LITERAL(0U)); - EXPECT_TRUE(GTEST_IS_NULL_LITERAL(0L)); - EXPECT_TRUE(GTEST_IS_NULL_LITERAL(false)); - EXPECT_TRUE(GTEST_IS_NULL_LITERAL(true && false)); + EXPECT_TRUE(GTEST_IS_NULL_LITERAL_(NULL)); + EXPECT_TRUE(GTEST_IS_NULL_LITERAL_(0)); + EXPECT_TRUE(GTEST_IS_NULL_LITERAL_(1 - 1)); + EXPECT_TRUE(GTEST_IS_NULL_LITERAL_(0U)); + EXPECT_TRUE(GTEST_IS_NULL_LITERAL_(0L)); + EXPECT_TRUE(GTEST_IS_NULL_LITERAL_(false)); + EXPECT_TRUE(GTEST_IS_NULL_LITERAL_(true && false)); } -// Tests that GTEST_IS_NULL_LITERAL(x) is false when x is not a null +// Tests that GTEST_IS_NULL_LITERAL_(x) is false when x is not a null // pointer literal. TEST(NullLiteralTest, IsFalseForNonNullLiterals) { - EXPECT_FALSE(GTEST_IS_NULL_LITERAL(1)); - EXPECT_FALSE(GTEST_IS_NULL_LITERAL(0.0)); - EXPECT_FALSE(GTEST_IS_NULL_LITERAL('a')); - EXPECT_FALSE(GTEST_IS_NULL_LITERAL(static_cast(NULL))); + EXPECT_FALSE(GTEST_IS_NULL_LITERAL_(1)); + EXPECT_FALSE(GTEST_IS_NULL_LITERAL_(0.0)); + EXPECT_FALSE(GTEST_IS_NULL_LITERAL_('a')); + EXPECT_FALSE(GTEST_IS_NULL_LITERAL_(static_cast(NULL))); } -#endif // __SYMBIAN32__ +#endif // GTEST_OS_SYMBIAN // // Tests CodePointToUtf8(). @@ -662,127 +666,160 @@ TEST(TestPropertyTest, ReplaceStringValue) { EXPECT_STREQ("2", property.value()); } -// Tests the TestPartResult class. - -// The test fixture for testing TestPartResult. -class TestPartResultTest : public Test { +class ScopedFakeTestPartResultReporterTest : public Test { protected: - TestPartResultTest() - : r1_(TPRT_SUCCESS, "foo/bar.cc", 10, "Success!"), - r2_(TPRT_NONFATAL_FAILURE, "foo/bar.cc", -1, "Failure!"), - r3_(TPRT_FATAL_FAILURE, NULL, -1, "Failure!") {} - - TestPartResult r1_, r2_, r3_; + enum FailureMode { + FATAL_FAILURE, + NONFATAL_FAILURE + }; + static void AddFailure(FailureMode failure) { + if (failure == FATAL_FAILURE) { + FAIL() << "Expected fatal failure."; + } else { + ADD_FAILURE() << "Expected non-fatal failure."; + } + } }; -// Tests TestPartResult::type() -TEST_F(TestPartResultTest, type) { - EXPECT_EQ(TPRT_SUCCESS, r1_.type()); - EXPECT_EQ(TPRT_NONFATAL_FAILURE, r2_.type()); - EXPECT_EQ(TPRT_FATAL_FAILURE, r3_.type()); -} +// Tests that ScopedFakeTestPartResultReporter intercepts test +// failures. +TEST_F(ScopedFakeTestPartResultReporterTest, InterceptsTestFailures) { + TestPartResultArray results; + { + ScopedFakeTestPartResultReporter reporter( + ScopedFakeTestPartResultReporter::INTERCEPT_ONLY_CURRENT_THREAD, + &results); + AddFailure(NONFATAL_FAILURE); + AddFailure(FATAL_FAILURE); + } -// Tests TestPartResult::file_name() -TEST_F(TestPartResultTest, file_name) { - EXPECT_STREQ("foo/bar.cc", r1_.file_name()); - EXPECT_STREQ(NULL, r3_.file_name()); + EXPECT_EQ(2, results.size()); + EXPECT_TRUE(results.GetTestPartResult(0).nonfatally_failed()); + EXPECT_TRUE(results.GetTestPartResult(1).fatally_failed()); } -// Tests TestPartResult::line_number() -TEST_F(TestPartResultTest, line_number) { - EXPECT_EQ(10, r1_.line_number()); - EXPECT_EQ(-1, r2_.line_number()); +TEST_F(ScopedFakeTestPartResultReporterTest, DeprecatedConstructor) { + TestPartResultArray results; + { + // Tests, that the deprecated constructor still works. + ScopedFakeTestPartResultReporter reporter(&results); + AddFailure(NONFATAL_FAILURE); + } + EXPECT_EQ(1, results.size()); } -// Tests TestPartResult::message() -TEST_F(TestPartResultTest, message) { - EXPECT_STREQ("Success!", r1_.message()); +#if GTEST_IS_THREADSAFE && GTEST_HAS_PTHREAD + +class ScopedFakeTestPartResultReporterWithThreadsTest + : public ScopedFakeTestPartResultReporterTest { + protected: + static void AddFailureInOtherThread(FailureMode failure) { + pthread_t tid; + pthread_create(&tid, + NULL, + ScopedFakeTestPartResultReporterWithThreadsTest:: + FailureThread, + &failure); + pthread_join(tid, NULL); + } + private: + static void* FailureThread(void* attr) { + FailureMode* failure = static_cast(attr); + AddFailure(*failure); + return NULL; + } +}; + +TEST_F(ScopedFakeTestPartResultReporterWithThreadsTest, + InterceptsTestFailuresInAllThreads) { + TestPartResultArray results; + { + ScopedFakeTestPartResultReporter reporter( + ScopedFakeTestPartResultReporter::INTERCEPT_ALL_THREADS, &results); + AddFailure(NONFATAL_FAILURE); + AddFailure(FATAL_FAILURE); + AddFailureInOtherThread(NONFATAL_FAILURE); + AddFailureInOtherThread(FATAL_FAILURE); + } + + EXPECT_EQ(4, results.size()); + EXPECT_TRUE(results.GetTestPartResult(0).nonfatally_failed()); + EXPECT_TRUE(results.GetTestPartResult(1).fatally_failed()); + EXPECT_TRUE(results.GetTestPartResult(2).nonfatally_failed()); + EXPECT_TRUE(results.GetTestPartResult(3).fatally_failed()); } -// Tests TestPartResult::passed() -TEST_F(TestPartResultTest, Passed) { - EXPECT_TRUE(r1_.passed()); - EXPECT_FALSE(r2_.passed()); - EXPECT_FALSE(r3_.passed()); +#endif // GTEST_IS_THREADSAFE && GTEST_HAS_PTHREAD + +// Tests EXPECT_{,NON}FATAL_FAILURE{,ON_ALL_THREADS}. + +typedef ScopedFakeTestPartResultReporterTest ExpectFailureTest; + +TEST_F(ExpectFailureTest, ExpectFatalFaliure) { + EXPECT_FATAL_FAILURE(AddFailure(FATAL_FAILURE), "Expected fatal failure."); } -// Tests TestPartResult::failed() -TEST_F(TestPartResultTest, Failed) { - EXPECT_FALSE(r1_.failed()); - EXPECT_TRUE(r2_.failed()); - EXPECT_TRUE(r3_.failed()); +TEST_F(ExpectFailureTest, ExpectNonFatalFailure) { + EXPECT_NONFATAL_FAILURE(AddFailure(NONFATAL_FAILURE), + "Expected non-fatal failure."); } -// Tests TestPartResult::fatally_failed() -TEST_F(TestPartResultTest, FatallyFailed) { - EXPECT_FALSE(r1_.fatally_failed()); - EXPECT_FALSE(r2_.fatally_failed()); - EXPECT_TRUE(r3_.fatally_failed()); +TEST_F(ExpectFailureTest, ExpectFatalFailureOnAllThreads) { + EXPECT_FATAL_FAILURE_ON_ALL_THREADS(AddFailure(FATAL_FAILURE), + "Expected fatal failure."); } -// Tests TestPartResult::nonfatally_failed() -TEST_F(TestPartResultTest, NonfatallyFailed) { - EXPECT_FALSE(r1_.nonfatally_failed()); - EXPECT_TRUE(r2_.nonfatally_failed()); - EXPECT_FALSE(r3_.nonfatally_failed()); +TEST_F(ExpectFailureTest, ExpectNonFatalFailureOnAllThreads) { + EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(AddFailure(NONFATAL_FAILURE), + "Expected non-fatal failure."); } -// Tests the TestPartResultArray class. +// Tests that the EXPECT_{,NON}FATAL_FAILURE{,_ON_ALL_THREADS} accepts +// a statement that contains a macro which expands to code containing +// an unprotected comma. -class TestPartResultArrayTest : public Test { - protected: - TestPartResultArrayTest() - : r1_(TPRT_NONFATAL_FAILURE, "foo/bar.cc", -1, "Failure 1"), - r2_(TPRT_FATAL_FAILURE, "foo/bar.cc", -1, "Failure 2") {} +static int global_var = 0; +#define GTEST_USE_UNPROTECTED_COMMA_ global_var++, global_var++ - const TestPartResult r1_, r2_; -}; +TEST_F(ExpectFailureTest, AcceptsMacroThatExpandsToUnprotectedComma) { + EXPECT_FATAL_FAILURE({ + GTEST_USE_UNPROTECTED_COMMA_; + AddFailure(FATAL_FAILURE); + }, ""); -// Tests that TestPartResultArray initially has size 0. -TEST_F(TestPartResultArrayTest, InitialSizeIsZero) { - TestPartResultArray results; - EXPECT_EQ(0, results.size()); -} + EXPECT_FATAL_FAILURE_ON_ALL_THREADS({ + GTEST_USE_UNPROTECTED_COMMA_; + AddFailure(FATAL_FAILURE); + }, ""); -// Tests that TestPartResultArray contains the given TestPartResult -// after one Append() operation. -TEST_F(TestPartResultArrayTest, ContainsGivenResultAfterAppend) { - TestPartResultArray results; - results.Append(r1_); - EXPECT_EQ(1, results.size()); - EXPECT_STREQ("Failure 1", results.GetTestPartResult(0).message()); -} + EXPECT_NONFATAL_FAILURE({ + GTEST_USE_UNPROTECTED_COMMA_; + AddFailure(NONFATAL_FAILURE); + }, ""); -// Tests that TestPartResultArray contains the given TestPartResults -// after two Append() operations. -TEST_F(TestPartResultArrayTest, ContainsGivenResultsAfterTwoAppends) { - TestPartResultArray results; - results.Append(r1_); - results.Append(r2_); - EXPECT_EQ(2, results.size()); - EXPECT_STREQ("Failure 1", results.GetTestPartResult(0).message()); - EXPECT_STREQ("Failure 2", results.GetTestPartResult(1).message()); + EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS({ + GTEST_USE_UNPROTECTED_COMMA_; + AddFailure(NONFATAL_FAILURE); + }, ""); } -void ScopedFakeTestPartResultReporterTestHelper() { - FAIL() << "Expected fatal failure."; -} +#if GTEST_IS_THREADSAFE && GTEST_HAS_PTHREAD -// Tests that ScopedFakeTestPartResultReporter intercepts test -// failures. -TEST(ScopedFakeTestPartResultReporterTest, InterceptsTestFailures) { - TestPartResultArray results; - { - ScopedFakeTestPartResultReporter reporter(&results); - ADD_FAILURE() << "Expected non-fatal failure."; - ScopedFakeTestPartResultReporterTestHelper(); - } +typedef ScopedFakeTestPartResultReporterWithThreadsTest + ExpectFailureWithThreadsTest; - EXPECT_EQ(2, results.size()); - EXPECT_TRUE(results.GetTestPartResult(0).nonfatally_failed()); - EXPECT_TRUE(results.GetTestPartResult(1).fatally_failed()); +TEST_F(ExpectFailureWithThreadsTest, ExpectFatalFailureOnAllThreads) { + EXPECT_FATAL_FAILURE_ON_ALL_THREADS(AddFailureInOtherThread(FATAL_FAILURE), + "Expected fatal failure."); +} + +TEST_F(ExpectFailureWithThreadsTest, ExpectNonFatalFailureOnAllThreads) { + EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS( + AddFailureInOtherThread(NONFATAL_FAILURE), "Expected non-fatal failure."); } +#endif // GTEST_IS_THREADSAFE && GTEST_HAS_PTHREAD + // Tests the TestResult class // The test fixture for testing TestResult. @@ -1875,6 +1912,8 @@ TEST_F(FloatTest, LargeDiff) { TEST_F(FloatTest, Infinity) { EXPECT_FLOAT_EQ(infinity_, close_to_infinity_); EXPECT_FLOAT_EQ(-infinity_, -close_to_infinity_); +#ifndef GTEST_OS_SYMBIAN + // Nokia's STLport crashes if we try to output infinity or NaN. EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(infinity_, -infinity_), "-infinity_"); @@ -1882,10 +1921,13 @@ TEST_F(FloatTest, Infinity) { // are only 1 DLP apart. EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(infinity_, nan1_), "nan1_"); +#endif // ! GTEST_OS_SYMBIAN } // Tests that comparing with NAN always returns false. TEST_F(FloatTest, NaN) { +#ifndef GTEST_OS_SYMBIAN +// Nokia's STLport crashes if we try to output infinity or NaN. EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(nan1_, nan1_), "nan1_"); EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(nan1_, nan2_), @@ -1895,6 +1937,7 @@ TEST_F(FloatTest, NaN) { EXPECT_FATAL_FAILURE(ASSERT_FLOAT_EQ(nan1_, infinity_), "infinity_"); +#endif // ! GTEST_OS_SYMBIAN } // Tests that *_FLOAT_EQ are reflexive. @@ -1956,6 +1999,8 @@ TEST_F(FloatTest, FloatLEFails) { EXPECT_PRED_FORMAT2(FloatLE, further_from_one_, 1.0f); }, "(further_from_one_) <= (1.0f)"); +#ifndef GTEST_OS_SYMBIAN + // Nokia's STLport crashes if we try to output infinity or NaN. // or when either val1 or val2 is NaN. EXPECT_NONFATAL_FAILURE({ // NOLINT EXPECT_PRED_FORMAT2(FloatLE, nan1_, infinity_); @@ -1967,6 +2012,7 @@ TEST_F(FloatTest, FloatLEFails) { EXPECT_FATAL_FAILURE({ // NOLINT ASSERT_PRED_FORMAT2(FloatLE, nan1_, nan1_); }, "(nan1_) <= (nan1_)"); +#endif // ! GTEST_OS_SYMBIAN } // Instantiates FloatingPointTest for testing *_DOUBLE_EQ. @@ -2021,6 +2067,8 @@ TEST_F(DoubleTest, LargeDiff) { TEST_F(DoubleTest, Infinity) { EXPECT_DOUBLE_EQ(infinity_, close_to_infinity_); EXPECT_DOUBLE_EQ(-infinity_, -close_to_infinity_); +#ifndef GTEST_OS_SYMBIAN + // Nokia's STLport crashes if we try to output infinity or NaN. EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(infinity_, -infinity_), "-infinity_"); @@ -2028,22 +2076,29 @@ TEST_F(DoubleTest, Infinity) { // are only 1 DLP apart. EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(infinity_, nan1_), "nan1_"); +#endif // ! GTEST_OS_SYMBIAN } // Tests that comparing with NAN always returns false. TEST_F(DoubleTest, NaN) { +#ifndef GTEST_OS_SYMBIAN + // Nokia's STLport crashes if we try to output infinity or NaN. EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(nan1_, nan1_), "nan1_"); EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(nan1_, nan2_), "nan2_"); EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(1.0, nan1_), "nan1_"); EXPECT_FATAL_FAILURE(ASSERT_DOUBLE_EQ(nan1_, infinity_), "infinity_"); +#endif // ! GTEST_OS_SYMBIAN } // Tests that *_DOUBLE_EQ are reflexive. TEST_F(DoubleTest, Reflexive) { EXPECT_DOUBLE_EQ(0.0, 0.0); EXPECT_DOUBLE_EQ(1.0, 1.0); +#ifndef GTEST_OS_SYMBIAN + // Nokia's STLport crashes if we try to output infinity or NaN. ASSERT_DOUBLE_EQ(infinity_, infinity_); +#endif // ! GTEST_OS_SYMBIAN } // Tests that *_DOUBLE_EQ are commutative. @@ -2059,38 +2114,22 @@ TEST_F(DoubleTest, Commutative) { TEST_F(DoubleTest, EXPECT_NEAR) { EXPECT_NEAR(-1.0, -1.1, 0.2); EXPECT_NEAR(2.0, 3.0, 1.0); -#ifdef __SYMBIAN32__ - // Symbian STLport has currently a buggy floating point output. - // TODO(mikie): fix STLport. - EXPECT_NONFATAL_FAILURE(EXPECT_NEAR(1.0, 1.2, 0.1), // NOLINT - "The difference between 1.0 and 1.2 is 0.19999:, " - "which exceeds 0.1"); -#else // !__SYMBIAN32__ EXPECT_NONFATAL_FAILURE(EXPECT_NEAR(1.0, 1.2, 0.1), // NOLINT "The difference between 1.0 and 1.2 is 0.2, " "which exceeds 0.1"); // To work around a bug in gcc 2.95.0, there is intentionally no // space after the first comma in the previous statement. -#endif // __SYMBIAN32__ } // Tests ASSERT_NEAR. TEST_F(DoubleTest, ASSERT_NEAR) { ASSERT_NEAR(-1.0, -1.1, 0.2); ASSERT_NEAR(2.0, 3.0, 1.0); -#ifdef __SYMBIAN32__ - // Symbian STLport has currently a buggy floating point output. - // TODO(mikie): fix STLport. - EXPECT_FATAL_FAILURE(ASSERT_NEAR(1.0, 1.2, 0.1), // NOLINT - "The difference between 1.0 and 1.2 is 0.19999:, " - "which exceeds 0.1"); -#else // ! __SYMBIAN32__ EXPECT_FATAL_FAILURE(ASSERT_NEAR(1.0, 1.2, 0.1), // NOLINT "The difference between 1.0 and 1.2 is 0.2, " "which exceeds 0.1"); // To work around a bug in gcc 2.95.0, there is intentionally no // space after the first comma in the previous statement. -#endif // __SYMBIAN32__ } // Tests the cases where DoubleLE() should succeed. @@ -2113,6 +2152,8 @@ TEST_F(DoubleTest, DoubleLEFails) { EXPECT_PRED_FORMAT2(DoubleLE, further_from_one_, 1.0); }, "(further_from_one_) <= (1.0)"); +#ifndef GTEST_OS_SYMBIAN + // Nokia's STLport crashes if we try to output infinity or NaN. // or when either val1 or val2 is NaN. EXPECT_NONFATAL_FAILURE({ // NOLINT EXPECT_PRED_FORMAT2(DoubleLE, nan1_, infinity_); @@ -2123,6 +2164,7 @@ TEST_F(DoubleTest, DoubleLEFails) { EXPECT_FATAL_FAILURE({ // NOLINT ASSERT_PRED_FORMAT2(DoubleLE, nan1_, nan1_); }, "(nan1_) <= (nan1_)"); +#endif // ! GTEST_OS_SYMBIAN } @@ -2389,6 +2431,97 @@ TEST_F(SingleEvaluationTest, ExceptionTests) { #endif // GTEST_HAS_EXCEPTIONS +// Tests {ASSERT|EXPECT}_NO_FATAL_FAILURE. +class NoFatalFailureTest : public Test { + protected: + void Succeeds() {} + void FailsNonFatal() { + ADD_FAILURE() << "some non-fatal failure"; + } + void Fails() { + FAIL() << "some fatal failure"; + } + + void DoAssertNoFatalFailureOnFails() { + ASSERT_NO_FATAL_FAILURE(Fails()); + ADD_FAILURE() << "shold not reach here."; + } + + void DoExpectNoFatalFailureOnFails() { + EXPECT_NO_FATAL_FAILURE(Fails()); + ADD_FAILURE() << "other failure"; + } +}; + +TEST_F(NoFatalFailureTest, NoFailure) { + EXPECT_NO_FATAL_FAILURE(Succeeds()); + ASSERT_NO_FATAL_FAILURE(Succeeds()); +} + +TEST_F(NoFatalFailureTest, NonFatalIsNoFailure) { + EXPECT_NONFATAL_FAILURE( + EXPECT_NO_FATAL_FAILURE(FailsNonFatal()), + "some non-fatal failure"); + EXPECT_NONFATAL_FAILURE( + ASSERT_NO_FATAL_FAILURE(FailsNonFatal()), + "some non-fatal failure"); +} + +TEST_F(NoFatalFailureTest, AssertNoFatalFailureOnFatalFailure) { + TestPartResultArray gtest_failures; + { + ScopedFakeTestPartResultReporter gtest_reporter(>est_failures); + DoAssertNoFatalFailureOnFails(); + } + ASSERT_EQ(2, gtest_failures.size()); + EXPECT_EQ(testing::TPRT_FATAL_FAILURE, + gtest_failures.GetTestPartResult(0).type()); + EXPECT_EQ(testing::TPRT_FATAL_FAILURE, + gtest_failures.GetTestPartResult(1).type()); + EXPECT_PRED_FORMAT2(testing::IsSubstring, "some fatal failure", + gtest_failures.GetTestPartResult(0).message()); + EXPECT_PRED_FORMAT2(testing::IsSubstring, "it does", + gtest_failures.GetTestPartResult(1).message()); +} + +TEST_F(NoFatalFailureTest, ExpectNoFatalFailureOnFatalFailure) { + TestPartResultArray gtest_failures; + { + ScopedFakeTestPartResultReporter gtest_reporter(>est_failures); + DoExpectNoFatalFailureOnFails(); + } + ASSERT_EQ(3, gtest_failures.size()); + EXPECT_EQ(testing::TPRT_FATAL_FAILURE, + gtest_failures.GetTestPartResult(0).type()); + EXPECT_EQ(testing::TPRT_NONFATAL_FAILURE, + gtest_failures.GetTestPartResult(1).type()); + EXPECT_EQ(testing::TPRT_NONFATAL_FAILURE, + gtest_failures.GetTestPartResult(2).type()); + EXPECT_PRED_FORMAT2(testing::IsSubstring, "some fatal failure", + gtest_failures.GetTestPartResult(0).message()); + EXPECT_PRED_FORMAT2(testing::IsSubstring, "it does", + gtest_failures.GetTestPartResult(1).message()); + EXPECT_PRED_FORMAT2(testing::IsSubstring, "other failure", + gtest_failures.GetTestPartResult(2).message()); +} + +TEST_F(NoFatalFailureTest, MessageIsStreamable) { + TestPartResultArray gtest_failures; + { + ScopedFakeTestPartResultReporter gtest_reporter(>est_failures); + EXPECT_NO_FATAL_FAILURE(FAIL() << "foo") << "my message"; + } + ASSERT_EQ(2, gtest_failures.size()); + EXPECT_EQ(testing::TPRT_NONFATAL_FAILURE, + gtest_failures.GetTestPartResult(0).type()); + EXPECT_EQ(testing::TPRT_NONFATAL_FAILURE, + gtest_failures.GetTestPartResult(1).type()); + EXPECT_PRED_FORMAT2(testing::IsSubstring, "foo", + gtest_failures.GetTestPartResult(0).message()); + EXPECT_PRED_FORMAT2(testing::IsSubstring, "my message", + gtest_failures.GetTestPartResult(1).message()); +} + // Tests non-string assertions. // Tests EqFailure(), used for implementing *EQ* assertions. @@ -2492,7 +2625,7 @@ TEST(AssertionTest, ASSERT_EQ) { } // Tests ASSERT_EQ(NULL, pointer). -#ifndef __SYMBIAN32__ +#ifndef GTEST_OS_SYMBIAN // The NULL-detection template magic fails to compile with // the Nokia compiler and crashes the ARM compiler, hence // not testing on Symbian. @@ -2506,7 +2639,7 @@ TEST(AssertionTest, ASSERT_EQ_NULL) { EXPECT_FATAL_FAILURE(ASSERT_EQ(NULL, &n), "Value of: &n\n"); } -#endif // __SYMBIAN32__ +#endif // GTEST_OS_SYMBIAN // Tests ASSERT_EQ(0, non_pointer). Since the literal 0 can be // treated as a null pointer by the compiler, we need to make sure @@ -2807,7 +2940,7 @@ TEST(HRESULTAssertionTest, Streaming) { #endif // defined(GTEST_OS_WINDOWS) // Tests that the assertion macros behave like single statements. -TEST(AssertionSyntaxTest, BehavesLikeSingleStatement) { +TEST(AssertionSyntaxTest, BasicAssertionsBehavesLikeSingleStatement) { if (false) ASSERT_TRUE(false) << "This should never be executed; " "It's a compilation test only."; @@ -2824,8 +2957,10 @@ TEST(AssertionSyntaxTest, BehavesLikeSingleStatement) { ; else EXPECT_GT(3, 2) << ""; +} #if GTEST_HAS_EXCEPTIONS +TEST(AssertionSyntaxTest, ExceptionAssertionsBehavesLikeSingleStatement) { if (false) EXPECT_THROW(1, bool); @@ -2849,7 +2984,30 @@ TEST(AssertionSyntaxTest, BehavesLikeSingleStatement) { EXPECT_ANY_THROW(ThrowAnInteger()); else ; +} #endif // GTEST_HAS_EXCEPTIONS + +TEST(AssertionSyntaxTest, NoFatalFailureAssertionsBehavesLikeSingleStatement) { + if (false) + EXPECT_NO_FATAL_FAILURE(FAIL()) << "This should never be executed. " + << "It's a compilation test only."; + else + ; + + if (false) + ASSERT_NO_FATAL_FAILURE(FAIL()) << ""; + else + ; + + if (true) + EXPECT_NO_FATAL_FAILURE(SUCCEED()); + else + ; + + if (false) + ; + else + ASSERT_NO_FATAL_FAILURE(SUCCEED()); } // Tests that the assertion macros work well with switch statements. @@ -2984,7 +3142,7 @@ TEST(ExpectTest, EXPECT_EQ_Double) { "5.1"); } -#ifndef __SYMBIAN32__ +#ifndef GTEST_OS_SYMBIAN // Tests EXPECT_EQ(NULL, pointer). TEST(ExpectTest, EXPECT_EQ_NULL) { // A success. @@ -2996,7 +3154,7 @@ TEST(ExpectTest, EXPECT_EQ_NULL) { EXPECT_NONFATAL_FAILURE(EXPECT_EQ(NULL, &n), "Value of: &n\n"); } -#endif // __SYMBIAN32__ +#endif // GTEST_OS_SYMBIAN // Tests EXPECT_EQ(0, non_pointer). Since the literal 0 can be // treated as a null pointer by the compiler, we need to make sure @@ -4739,7 +4897,24 @@ TEST(ColoredOutputTest, UsesColorsWhenTermSupportsColors) { #endif // GTEST_OS_WINDOWS } -#ifndef __SYMBIAN32__ +TEST(ThreadLocalTest, DefaultConstructor) { + ThreadLocal t1; + EXPECT_EQ(0, t1.get()); + + ThreadLocal t2; + EXPECT_TRUE(t2.get() == NULL); +} + +TEST(ThreadLocalTest, Init) { + ThreadLocal t1(123); + EXPECT_EQ(123, t1.get()); + + int i = 0; + ThreadLocal t2(&i); + EXPECT_EQ(&i, t2.get()); +} + +#ifndef GTEST_OS_SYMBIAN // We will want to integrate running the unittests to a different // main application on Symbian. int main(int argc, char** argv) { @@ -4756,4 +4931,4 @@ int main(int argc, char** argv) { // Runs all tests using Google Test. return RUN_ALL_TESTS(); } -#endif // __SYMBIAN32_ +#endif // GTEST_OS_SYMBIAN -- cgit v1.2.3 From 3d7042176307f0d7700a3640f3b3bcc8790b8fcd Mon Sep 17 00:00:00 2001 From: vladlosev Date: Thu, 20 Nov 2008 01:40:35 +0000 Subject: Value-parameterized tests and many bugfixes --- test/gtest-filepath_test.cc | 6 - test/gtest-linked_ptr_test.cc | 154 ++++++++ test/gtest-param-test2_test.cc | 65 ++++ test/gtest-param-test_test.cc | 796 +++++++++++++++++++++++++++++++++++++++++ test/gtest-param-test_test.h | 55 +++ test/gtest-port_test.cc | 156 ++++++++ test/gtest-typed-test_test.cc | 12 + test/gtest_filter_unittest.py | 129 ++++--- test/gtest_filter_unittest_.cc | 22 +- test/gtest_repeat_test.cc | 30 ++ test/gtest_unittest.cc | 17 + 11 files changed, 1392 insertions(+), 50 deletions(-) create mode 100644 test/gtest-linked_ptr_test.cc create mode 100644 test/gtest-param-test2_test.cc create mode 100644 test/gtest-param-test_test.cc create mode 100644 test/gtest-param-test_test.h create mode 100644 test/gtest-port_test.cc (limited to 'test') diff --git a/test/gtest-filepath_test.cc b/test/gtest-filepath_test.cc index de8ad01e..d87c7c8c 100644 --- a/test/gtest-filepath_test.cc +++ b/test/gtest-filepath_test.cc @@ -83,12 +83,6 @@ int _rmdir(const char* path) { return ret; } -#elif defined(GTEST_LINUX_GOOGLE3_MODE) -// Creates a temporary directory and returns its path. -const char* MakeTempDir() { - static char dir_name[] = "gtest-filepath_test_tmpXXXXXX"; - return mkdtemp(dir_name); -} #endif // _WIN32_WCE #ifndef _WIN32_WCE diff --git a/test/gtest-linked_ptr_test.cc b/test/gtest-linked_ptr_test.cc new file mode 100644 index 00000000..eae82296 --- /dev/null +++ b/test/gtest-linked_ptr_test.cc @@ -0,0 +1,154 @@ +// Copyright 2003, 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. +// +// Authors: Dan Egnor (egnor@google.com) +// Ported to Windows: Vadim Berman (vadimb@google.com) + +#include + +#include +#include + +namespace { + +using testing::Message; +using testing::internal::linked_ptr; + +int num; +Message* history = NULL; + +// Class which tracks allocation/deallocation +class A { + public: + A(): mynum(num++) { *history << "A" << mynum << " ctor\n"; } + virtual ~A() { *history << "A" << mynum << " dtor\n"; } + virtual void Use() { *history << "A" << mynum << " use\n"; } + protected: + int mynum; +}; + +// Subclass +class B : public A { + public: + B() { *history << "B" << mynum << " ctor\n"; } + ~B() { *history << "B" << mynum << " dtor\n"; } + virtual void Use() { *history << "B" << mynum << " use\n"; } +}; + +class LinkedPtrTest : public testing::Test { + public: + LinkedPtrTest() { + num = 0; + history = new Message; + } + + virtual ~LinkedPtrTest() { + delete history; + history = NULL; + } +}; + +TEST_F(LinkedPtrTest, GeneralTest) { + { + linked_ptr a0, a1, a2; + a0 = a0; + a1 = a2; + ASSERT_EQ(a0.get(), static_cast(NULL)); + ASSERT_EQ(a1.get(), static_cast(NULL)); + ASSERT_EQ(a2.get(), static_cast(NULL)); + ASSERT_TRUE(a0 == NULL); + ASSERT_TRUE(a1 == NULL); + ASSERT_TRUE(a2 == NULL); + + { + linked_ptr a3(new A); + a0 = a3; + ASSERT_TRUE(a0 == a3); + ASSERT_TRUE(a0 != NULL); + ASSERT_TRUE(a0.get() == a3); + ASSERT_TRUE(a0 == a3.get()); + linked_ptr a4(a0); + a1 = a4; + linked_ptr a5(new A); + ASSERT_TRUE(a5.get() != a3); + ASSERT_TRUE(a5 != a3.get()); + a2 = a5; + linked_ptr b0(new B); + linked_ptr a6(b0); + ASSERT_TRUE(b0 == a6); + ASSERT_TRUE(a6 == b0); + ASSERT_TRUE(b0 != NULL); + a5 = b0; + a5 = b0; + a3->Use(); + a4->Use(); + a5->Use(); + a6->Use(); + b0->Use(); + (*b0).Use(); + b0.get()->Use(); + } + + a0->Use(); + a1->Use(); + a2->Use(); + + a1 = a2; + a2.reset(new A); + a0.reset(); + + linked_ptr a7; + } + + ASSERT_STREQ( + "A0 ctor\n" + "A1 ctor\n" + "A2 ctor\n" + "B2 ctor\n" + "A0 use\n" + "A0 use\n" + "B2 use\n" + "B2 use\n" + "B2 use\n" + "B2 use\n" + "B2 use\n" + "B2 dtor\n" + "A2 dtor\n" + "A0 use\n" + "A0 use\n" + "A1 use\n" + "A3 ctor\n" + "A0 dtor\n" + "A3 dtor\n" + "A1 dtor\n", + history->GetString().c_str() + ); +} + +} // Unnamed namespace diff --git a/test/gtest-param-test2_test.cc b/test/gtest-param-test2_test.cc new file mode 100644 index 00000000..4e54206d --- /dev/null +++ b/test/gtest-param-test2_test.cc @@ -0,0 +1,65 @@ +// Copyright 2008, 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: vladl@google.com (Vlad Losev) +// +// Tests for Google Test itself. This verifies that the basic constructs of +// Google Test work. + +#include + +#include "test/gtest-param-test_test.h" + +#ifdef GTEST_HAS_PARAM_TEST + +using ::testing::Values; +using ::testing::internal::ParamGenerator; + +// Tests that generators defined in a different translation unit +// are functional. The test using extern_gen is defined +// in gtest-param-test_test.cc. +ParamGenerator extern_gen = Values(33); + +// Tests that a parameterized test case can be defined in one translation unit +// and instantiated in another. The test is defined in gtest-param-test_test.cc +// and ExternalInstantiationTest fixture class is defined in +// gtest-param-test_test.h. +INSTANTIATE_TEST_CASE_P(MultiplesOf33, + ExternalInstantiationTest, + Values(33, 66)); + +// Tests that a parameterized test case can be instantiated +// in multiple translation units. Another instantiation is defined +// in gtest-param-test_test.cc and InstantiationInMultipleTranslaionUnitsTest +// fixture is defined in gtest-param-test_test.h +INSTANTIATE_TEST_CASE_P(Sequence2, + InstantiationInMultipleTranslaionUnitsTest, + Values(42*3, 42*4, 42*5)); + +#endif // GTEST_HAS_PARAM_TEST diff --git a/test/gtest-param-test_test.cc b/test/gtest-param-test_test.cc new file mode 100644 index 00000000..6d84dcf9 --- /dev/null +++ b/test/gtest-param-test_test.cc @@ -0,0 +1,796 @@ +// Copyright 2008, 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: vladl@google.com (Vlad Losev) +// +// Tests for Google Test itself. This file verifies that the parameter +// generators objects produce correct parameter sequences and that +// Google Test runtime instantiates correct tests from those sequences. + +#include + +#ifdef GTEST_HAS_PARAM_TEST + +#include +#include +#include +#include + +#ifdef GTEST_HAS_COMBINE +#include +#endif // GTEST_HAS_COMBINE + +// To include gtest-internal-inl.h. +#define GTEST_IMPLEMENTATION +#include "src/gtest-internal-inl.h" // for UnitTestOptions +#undef GTEST_IMPLEMENTATION + +#include "test/gtest-param-test_test.h" + +using ::std::vector; +using ::std::sort; + +using ::testing::AddGlobalTestEnvironment; +using ::testing::Bool; +using ::testing::Message; +using ::testing::Range; +using ::testing::TestWithParam; +using ::testing::Values; +using ::testing::ValuesIn; + +#ifdef GTEST_HAS_COMBINE +using ::testing::Combine; +using ::std::tr1::get; +using ::std::tr1::make_tuple; +using ::std::tr1::tuple; +#endif // GTEST_HAS_COMBINE + +using ::testing::internal::ParamGenerator; +using ::testing::internal::UnitTestOptions; + +// Verifies that a sequence generated by the generator and accessed +// via the iterator object matches the expected one using Google Test +// assertions. +template +void VerifyGenerator(const ParamGenerator& generator, + const T (&expected_values)[N]) { + typename ParamGenerator::iterator it = generator.begin(); + for (size_t i = 0; i < N; ++i) { + ASSERT_FALSE(it == generator.end()) + << "At element " << i << " when accessing via an iterator " + << "created with the copy constructor." << std::endl; + EXPECT_EQ(expected_values[i], *it) + << "At element " << i << " when accessing via an iterator " + << "created with the copy constructor." << std::endl; + it++; + } + EXPECT_TRUE(it == generator.end()) + << "At the presumed end of sequence when accessing via an iterator " + << "created with the copy constructor." << std::endl; + + // Test the iterator assignment. The following lines verify that + // the sequence accessed via an iterator initialized via the + // assignment operator (as opposed to a copy constructor) matches + // just the same. + it = generator.begin(); + for (size_t i = 0; i < N; ++i) { + ASSERT_FALSE(it == generator.end()) + << "At element " << i << " when accessing via an iterator " + << "created with the assignment operator." << std::endl; + EXPECT_EQ(expected_values[i], *it) + << "At element " << i << " when accessing via an iterator " + << "created with the assignment operator." << std::endl; + it++; + } + EXPECT_TRUE(it == generator.end()) + << "At the presumed end of sequence when accessing via an iterator " + << "created with the assignment operator." << std::endl; +} + +template +void VerifyGeneratorIsEmpty(const ParamGenerator& generator) { + typename ParamGenerator::iterator it = generator.begin(); + EXPECT_TRUE(it == generator.end()); + + it = generator.begin(); + EXPECT_TRUE(it == generator.end()); +} + +// Generator tests. They test that each of the provided generator functions +// generates an expected sequence of values. The general test pattern +// instantiates a generator using one of the generator functions, +// checks the sequence produced by the generator using its iterator API, +// and then resets the iterator back to the beginning of the sequence +// and checks the sequence again. + +// Tests that iterators produced by generator functions conform to the +// ForwardIterator concept. +TEST(IteratorTest, ParamIteratorConformsToForwardIteratorConcept) { + const ParamGenerator gen = Range(0, 10); + ParamGenerator::iterator it = gen.begin(); + + // Verifies that iterator initialization works as expected. + ParamGenerator::iterator it2 = it; + EXPECT_TRUE(*it == *it2) << "Initialized iterators must point to the " + << "element same as its source points to"; + + // Verifies that iterator assignment works as expected. + it++; + EXPECT_FALSE(*it == *it2); + it2 = it; + EXPECT_TRUE(*it == *it2) << "Assigned iterators must point to the " + << "element same as its source points to"; + + // Verifies that prefix operator++() returns *this. + EXPECT_EQ(&it, &(++it)) << "Result of the prefix operator++ must be " + << "refer to the original object"; + + // Verifies that the result of the postfix operator++ points to the value + // pointed to by the original iterator. + int original_value = *it; // Have to compute it outside of macro call to be + // unaffected by the parameter evaluation order. + EXPECT_EQ(original_value, *(it++)); + + // Verifies that prefix and postfix operator++() advance an iterator + // all the same. + it2 = it; + it++; + ++it2; + EXPECT_TRUE(*it == *it2); +} + +// Tests that Range() generates the expected sequence. +TEST(RangeTest, IntRangeWithDefaultStep) { + const ParamGenerator gen = Range(0, 3); + const int expected_values[] = {0, 1, 2}; + VerifyGenerator(gen, expected_values); +} + +// Edge case. Tests that Range() generates the single element sequence +// as expected when provided with range limits that are equal. +TEST(RangeTest, IntRangeSingleValue) { + const ParamGenerator gen = Range(0, 1); + const int expected_values[] = {0}; + VerifyGenerator(gen, expected_values); +} + +// Edge case. Tests that Range() with generates empty sequence when +// supplied with an empty range. +TEST(RangeTest, IntRangeEmpty) { + const ParamGenerator gen = Range(0, 0); + VerifyGeneratorIsEmpty(gen); +} + +// Tests that Range() with custom step (greater then one) generates +// the expected sequence. +TEST(RangeTest, IntRangeWithCustomStep) { + const ParamGenerator gen = Range(0, 9, 3); + const int expected_values[] = {0, 3, 6}; + VerifyGenerator(gen, expected_values); +} + +// Tests that Range() with custom step (greater then one) generates +// the expected sequence when the last element does not fall on the +// upper range limit. Sequences generated by Range() must not have +// elements beyond the range limits. +TEST(RangeTest, IntRangeWithCustomStepOverUpperBound) { + const ParamGenerator gen = Range(0, 4, 3); + const int expected_values[] = {0, 3}; + VerifyGenerator(gen, expected_values); +} + +// Verifies that Range works with user-defined types that define +// copy constructor, operator=(), operator+(), and operator<(). +class DogAdder { + public: + explicit DogAdder(const char* value) : value_(value) {} + DogAdder(const DogAdder& other) : value_(other.value_.c_str()) {} + + DogAdder operator=(const DogAdder& other) { + if (this != &other) + value_ = other.value_; + return *this; + } + DogAdder operator+(const DogAdder& other) const { + Message msg; + msg << value_.c_str() << other.value_.c_str(); + return DogAdder(msg.GetString().c_str()); + } + bool operator<(const DogAdder& other) const { + return value_ < other.value_; + } + const ::testing::internal::String& value() const { return value_; } + + private: + ::testing::internal::String value_; +}; + +TEST(RangeTest, WorksWithACustomType) { + const ParamGenerator gen = + Range(DogAdder("cat"), DogAdder("catdogdog"), DogAdder("dog")); + ParamGenerator::iterator it = gen.begin(); + + ASSERT_FALSE(it == gen.end()); + EXPECT_STREQ("cat", it->value().c_str()); + + ASSERT_FALSE(++it == gen.end()); + EXPECT_STREQ("catdog", it->value().c_str()); + + EXPECT_TRUE(++it == gen.end()); +} + +class IntWrapper { + public: + explicit IntWrapper(int value) : value_(value) {} + IntWrapper(const IntWrapper& other) : value_(other.value_) {} + + IntWrapper operator=(const IntWrapper& other) { + value_ = other.value_; + return *this; + } + // operator+() adds a different type. + IntWrapper operator+(int other) const { return IntWrapper(value_ + other); } + bool operator<(const IntWrapper& other) const { + return value_ < other.value_; + } + int value() const { return value_; } + + private: + int value_; +}; + +TEST(RangeTest, WorksWithACustomTypeWithDifferentIncrementType) { + const ParamGenerator gen = Range(IntWrapper(0), IntWrapper(2)); + ParamGenerator::iterator it = gen.begin(); + + ASSERT_FALSE(it == gen.end()); + EXPECT_EQ(0, it->value()); + + ASSERT_FALSE(++it == gen.end()); + EXPECT_EQ(1, it->value()); + + EXPECT_TRUE(++it == gen.end()); +} + +// Tests that ValuesIn() with an array parameter generates +// the expected sequence. +TEST(ValuesInTest, ValuesInArray) { + int array[] = {3, 5, 8}; + const ParamGenerator gen = ValuesIn(array); + VerifyGenerator(gen, array); +} + +// Tests that ValuesIn() with a const array parameter generates +// the expected sequence. +TEST(ValuesInTest, ValuesInConstArray) { + const int array[] = {3, 5, 8}; + const ParamGenerator gen = ValuesIn(array); + VerifyGenerator(gen, array); +} + +// Edge case. Tests that ValuesIn() with an array parameter containing a +// single element generates the single element sequence. +TEST(ValuesInTest, ValuesInSingleElementArray) { + int array[] = {42}; + const ParamGenerator gen = ValuesIn(array); + VerifyGenerator(gen, array); +} + +// Tests that ValuesIn() generates the expected sequence for an STL +// container (vector). +TEST(ValuesInTest, ValuesInVector) { + typedef ::std::vector ContainerType; + ContainerType values; + values.push_back(3); + values.push_back(5); + values.push_back(8); + const ParamGenerator gen = ValuesIn(values); + + const int expected_values[] = {3, 5, 8}; + VerifyGenerator(gen, expected_values); +} + +// Tests that ValuesIn() generates the expected sequence. +TEST(ValuesInTest, ValuesInIteratorRange) { + typedef ::std::vector ContainerType; + ContainerType values; + values.push_back(3); + values.push_back(5); + values.push_back(8); + const ParamGenerator gen = ValuesIn(values.begin(), values.end()); + + const int expected_values[] = {3, 5, 8}; + VerifyGenerator(gen, expected_values); +} + +// Edge case. Tests that ValuesIn() provided with an iterator range specifying a +// single value generates a single-element sequence. +TEST(ValuesInTest, ValuesInSingleElementIteratorRange) { + typedef ::std::vector ContainerType; + ContainerType values; + values.push_back(42); + const ParamGenerator gen = ValuesIn(values.begin(), values.end()); + + const int expected_values[] = {42}; + VerifyGenerator(gen, expected_values); +} + +// Edge case. Tests that ValuesIn() provided with an empty iterator range +// generates an empty sequence. +TEST(ValuesInTest, ValuesInEmptyIteratorRange) { + typedef ::std::vector ContainerType; + ContainerType values; + const ParamGenerator gen = ValuesIn(values.begin(), values.end()); + + VerifyGeneratorIsEmpty(gen); +} + +// Tests that the Values() generates the expected sequence. +TEST(ValuesTest, ValuesWorks) { + const ParamGenerator gen = Values(3, 5, 8); + + const int expected_values[] = {3, 5, 8}; + VerifyGenerator(gen, expected_values); +} + +// Tests that Values() generates the expected sequences from elements of +// different types convertible to ParamGenerator's parameter type. +TEST(ValuesTest, ValuesWorksForValuesOfCompatibleTypes) { + const ParamGenerator gen = Values(3, 5.0f, 8.0); + + const double expected_values[] = {3.0, 5.0, 8.0}; + VerifyGenerator(gen, expected_values); +} + +TEST(ValuesTest, ValuesWorksForMaxLengthList) { + const ParamGenerator gen = Values( + 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, + 110, 120, 130, 140, 150, 160, 170, 180, 190, 200, + 210, 220, 230, 240, 250, 260, 270, 280, 290, 300, + 310, 320, 330, 340, 350, 360, 370, 380, 390, 400, + 410, 420, 430, 440, 450, 460, 470, 480, 490, 500); + + const int expected_values[] = { + 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, + 110, 120, 130, 140, 150, 160, 170, 180, 190, 200, + 210, 220, 230, 240, 250, 260, 270, 280, 290, 300, + 310, 320, 330, 340, 350, 360, 370, 380, 390, 400, + 410, 420, 430, 440, 450, 460, 470, 480, 490, 500}; + VerifyGenerator(gen, expected_values); +} + +// Edge case test. Tests that single-parameter Values() generates the sequence +// with the single value. +TEST(ValuesTest, ValuesWithSingleParameter) { + const ParamGenerator gen = Values(42); + + const int expected_values[] = {42}; + VerifyGenerator(gen, expected_values); +} + +// Tests that Bool() generates sequence (false, true). +TEST(BoolTest, BoolWorks) { + const ParamGenerator gen = Bool(); + + const bool expected_values[] = {false, true}; + VerifyGenerator(gen, expected_values); +} + +#ifdef GTEST_HAS_COMBINE + +template +::std::ostream& operator<<(::std::ostream& stream, const tuple& value) { + stream << "(" << get<0>(value) << ", " << get<1>(value) << ")"; + return stream; +} + +template +::std::ostream& operator<<(::std::ostream& stream, + const tuple& value) { + stream << "(" << get<0>(value) << ", " << get<1>(value) + << ", "<< get<2>(value) << ")"; + return stream; +} + +template +::std::ostream& operator<<( + ::std::ostream& stream, + const tuple& value) { + stream << "(" << get<0>(value) << ", " << get<1>(value) + << ", "<< get<2>(value) << ", " << get<3>(value) + << ", "<< get<4>(value) << ", " << get<5>(value) + << ", "<< get<6>(value) << ", " << get<7>(value) + << ", "<< get<8>(value) << ", " << get<9>(value) << ")"; + return stream; +} + +// Tests that Combine() with two parameters generates the expected sequence. +TEST(CombineTest, CombineWithTwoParameters) { + const char* foo = "foo"; + const char* bar = "bar"; + const ParamGenerator > gen = + Combine(Values(foo, bar), Values(3, 4)); + + tuple expected_values[] = { + make_tuple(foo, 3), make_tuple(foo, 4), + make_tuple(bar, 3), make_tuple(bar, 4)}; + VerifyGenerator(gen, expected_values); +} + +// Tests that Combine() with three parameters generates the expected sequence. +TEST(CombineTest, CombineWithThreeParameters) { + const ParamGenerator > gen = Combine(Values(0, 1), + Values(3, 4), + Values(5, 6)); + tuple expected_values[] = { + make_tuple(0, 3, 5), make_tuple(0, 3, 6), + make_tuple(0, 4, 5), make_tuple(0, 4, 6), + make_tuple(1, 3, 5), make_tuple(1, 3, 6), + make_tuple(1, 4, 5), make_tuple(1, 4, 6)}; + VerifyGenerator(gen, expected_values); +} + +// Tests that the Combine() with the first parameter generating a single value +// sequence generates a sequence with the number of elements equal to the +// number of elements in the sequence generated by the second parameter. +TEST(CombineTest, CombineWithFirstParameterSingleValue) { + const ParamGenerator > gen = Combine(Values(42), + Values(0, 1)); + + tuple expected_values[] = {make_tuple(42, 0), make_tuple(42, 1)}; + VerifyGenerator(gen, expected_values); +} + +// Tests that the Combine() with the second parameter generating a single value +// sequence generates a sequence with the number of elements equal to the +// number of elements in the sequence generated by the first parameter. +TEST(CombineTest, CombineWithSecondParameterSingleValue) { + const ParamGenerator > gen = Combine(Values(0, 1), + Values(42)); + + tuple expected_values[] = {make_tuple(0, 42), make_tuple(1, 42)}; + VerifyGenerator(gen, expected_values); +} + +// Tests that when the first parameter produces an empty sequence, +// Combine() produces an empty sequence, too. +TEST(CombineTest, CombineWithFirstParameterEmptyRange) { + const ParamGenerator > gen = Combine(Range(0, 0), + Values(0, 1)); + VerifyGeneratorIsEmpty(gen); +} + +// Tests that when the second parameter produces an empty sequence, +// Combine() produces an empty sequence, too. +TEST(CombineTest, CombineWithSecondParameterEmptyRange) { + const ParamGenerator > gen = Combine(Values(0, 1), + Range(1, 1)); + VerifyGeneratorIsEmpty(gen); +} + +// Edge case. Tests that combine works with the maximum number +// of parameters supported by Google Test (currently 10). +TEST(CombineTest, CombineWithMaxNumberOfParameters) { + const char* foo = "foo"; + const char* bar = "bar"; + const ParamGenerator > gen = Combine(Values(foo, bar), + Values(1), Values(2), + Values(3), Values(4), + Values(5), Values(6), + Values(7), Values(8), + Values(9)); + + tuple + expected_values[] = {make_tuple(foo, 1, 2, 3, 4, 5, 6, 7, 8, 9), + make_tuple(bar, 1, 2, 3, 4, 5, 6, 7, 8, 9)}; + VerifyGenerator(gen, expected_values); +} + +#endif // GTEST_HAS_COMBINE + +// Tests that an generator produces correct sequence after being +// assigned from another generator. +TEST(ParamGeneratorTest, AssignmentWorks) { + ParamGenerator gen = Values(1, 2); + const ParamGenerator gen2 = Values(3, 4); + gen = gen2; + + const int expected_values[] = {3, 4}; + VerifyGenerator(gen, expected_values); +} + +// This test verifies that the tests are expanded and run as specified: +// one test per element from the sequence produced by the generator +// specified in INSTANTIATE_TEST_CASE_P. It also verifies that the test's +// fixture constructor, SetUp(), and TearDown() have run and have been +// supplied with the correct parameters. + +// The use of environment object allows detection of the case where no test +// case functionality is run at all. In this case TestCaseTearDown will not +// be able to detect missing tests, naturally. +template +class TestGenerationEnvironment : public ::testing::Environment { + public: + static TestGenerationEnvironment* Instance() { + static TestGenerationEnvironment* instance = new TestGenerationEnvironment; + return instance; + } + + void FixtureConstructorExecuted() { fixture_constructor_count_++; } + void SetUpExecuted() { set_up_count_++; } + void TearDownExecuted() { tear_down_count_++; } + void TestBodyExecuted() { test_body_count_++; } + + virtual void TearDown() { + // If all MultipleTestGenerationTest tests have been de-selected + // by the filter flag, the following checks make no sense. + bool perform_check = false; + + for (int i = 0; i < kExpectedCalls; ++i) { + Message msg; + msg << "TestsExpandedAndRun/" << i; + if (UnitTestOptions::FilterMatchesTest( + "TestExpansionModule/MultipleTestGenerationTest", + msg.GetString().c_str())) { + perform_check = true; + } + } + if (perform_check) { + EXPECT_EQ(kExpectedCalls, fixture_constructor_count_) + << "Fixture constructor of ParamTestGenerationTest test case " + << "has not been run as expected."; + EXPECT_EQ(kExpectedCalls, set_up_count_) + << "Fixture SetUp method of ParamTestGenerationTest test case " + << "has not been run as expected."; + EXPECT_EQ(kExpectedCalls, tear_down_count_) + << "Fixture TearDown method of ParamTestGenerationTest test case " + << "has not been run as expected."; + EXPECT_EQ(kExpectedCalls, test_body_count_) + << "Test in ParamTestGenerationTest test case " + << "has not been run as expected."; + } + } + private: + TestGenerationEnvironment() : fixture_constructor_count_(0), set_up_count_(0), + tear_down_count_(0), test_body_count_(0) {} + + int fixture_constructor_count_; + int set_up_count_; + int tear_down_count_; + int test_body_count_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestGenerationEnvironment); +}; + +const int test_generation_params[] = {36, 42, 72}; + +class TestGenerationTest : public TestWithParam { + public: + enum { + PARAMETER_COUNT = + sizeof(test_generation_params)/sizeof(test_generation_params[0]) + }; + + typedef TestGenerationEnvironment Environment; + + TestGenerationTest() { + Environment::Instance()->FixtureConstructorExecuted(); + current_parameter_ = GetParam(); + } + virtual void SetUp() { + Environment::Instance()->SetUpExecuted(); + EXPECT_EQ(current_parameter_, GetParam()); + } + virtual void TearDown() { + Environment::Instance()->TearDownExecuted(); + EXPECT_EQ(current_parameter_, GetParam()); + } + + static void SetUpTestCase() { + bool all_tests_in_test_case_selected = true; + + for (int i = 0; i < PARAMETER_COUNT; ++i) { + Message test_name; + test_name << "TestsExpandedAndRun/" << i; + if ( !UnitTestOptions::FilterMatchesTest( + "TestExpansionModule/MultipleTestGenerationTest", + test_name.GetString())) { + all_tests_in_test_case_selected = false; + } + } + EXPECT_TRUE(all_tests_in_test_case_selected) + << "When running the TestGenerationTest test case all of its tests\n" + << "must be selected by the filter flag for the test case to pass.\n" + << "If not all of them are enabled, we can't reliably conclude\n" + << "that the correct number of tests have been generated."; + + collected_parameters_.clear(); + } + + static void TearDownTestCase() { + vector expected_values(test_generation_params, + test_generation_params + PARAMETER_COUNT); + // Test execution order is not guaranteed by Google Test, + // so the order of values in collected_parameters_ can be + // different and we have to sort to compare. + sort(expected_values.begin(), expected_values.end()); + sort(collected_parameters_.begin(), collected_parameters_.end()); + + EXPECT_TRUE(collected_parameters_ == expected_values); + } + protected: + int current_parameter_; + static vector collected_parameters_; + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestGenerationTest); +}; +vector TestGenerationTest::collected_parameters_; + +TEST_P(TestGenerationTest, TestsExpandedAndRun) { + Environment::Instance()->TestBodyExecuted(); + EXPECT_EQ(current_parameter_, GetParam()); + collected_parameters_.push_back(GetParam()); +} +INSTANTIATE_TEST_CASE_P(TestExpansionModule, TestGenerationTest, + ValuesIn(test_generation_params)); + +// This test verifies that the element sequence (third parameter of +// INSTANTIATE_TEST_CASE_P) is evaluated in RUN_ALL_TESTS and not at the call +// site of INSTANTIATE_TEST_CASE_P. +// For that, we declare param_value_ to be a static member of +// GeneratorEvaluationTest and initialize it to 0. We set it to 1 in main(), +// just before invocation of RUN_ALL_TESTS. If the sequence is evaluated +// before that moment, INSTANTIATE_TEST_CASE_P will create a test with +// parameter 0, and the test body will fail the assertion. +class GeneratorEvaluationTest : public TestWithParam { + public: + static int param_value() { return param_value_; } + static void set_param_value(int param_value) { param_value_ = param_value; } + + private: + static int param_value_; +}; +int GeneratorEvaluationTest::param_value_ = 0; + +TEST_P(GeneratorEvaluationTest, GeneratorsEvaluatedInMain) { + EXPECT_EQ(1, GetParam()); +} +INSTANTIATE_TEST_CASE_P(GenEvalModule, + GeneratorEvaluationTest, + Values(GeneratorEvaluationTest::param_value())); + +// Tests that generators defined in a different translation unit are +// functional. Generator extern_gen is defined in gtest-param-test_test2.cc. +extern ParamGenerator extern_gen; +class ExternalGeneratorTest : public TestWithParam {}; +TEST_P(ExternalGeneratorTest, ExternalGenerator) { + // Sequence produced by extern_gen contains only a single value + // which we verify here. + EXPECT_EQ(GetParam(), 33); +} +INSTANTIATE_TEST_CASE_P(ExternalGeneratorModule, + ExternalGeneratorTest, + extern_gen); + +// Tests that a parameterized test case can be defined in one translation +// unit and instantiated in another. This test will be instantiated in +// gtest-param-test_test2.cc. ExternalInstantiationTest fixture class is +// defined in gtest-param-test_test.h. +TEST_P(ExternalInstantiationTest, IsMultipleOf33) { + EXPECT_EQ(0, GetParam() % 33); +} + +// Tests that a parameterized test case can be instantiated with multiple +// generators. +class MultipleInstantiationTest : public TestWithParam {}; +TEST_P(MultipleInstantiationTest, AllowsMultipleInstances) { +} +INSTANTIATE_TEST_CASE_P(Sequence1, MultipleInstantiationTest, Values(1, 2)); +INSTANTIATE_TEST_CASE_P(Sequence2, MultipleInstantiationTest, Range(3, 5)); + +// Tests that a parameterized test case can be instantiated +// in multiple translation units. This test will be instantiated +// here and in gtest-param-test_test2.cc. +// InstantiationInMultipleTranslationUnitsTest fixture class +// is defined in gtest-param-test_test.h. +TEST_P(InstantiationInMultipleTranslaionUnitsTest, IsMultipleOf42) { + EXPECT_EQ(0, GetParam() % 42); +} +INSTANTIATE_TEST_CASE_P(Sequence1, + InstantiationInMultipleTranslaionUnitsTest, + Values(42, 42*2)); + +// Tests that each iteration of parameterized test runs in a separate test +// object. +class SeparateInstanceTest : public TestWithParam { + public: + SeparateInstanceTest() : count_(0) {} + + static void TearDownTestCase() { + EXPECT_GE(global_count_, 2) + << "If some (but not all) SeparateInstanceTest tests have been " + << "filtered out this test will fail. Make sure that all " + << "GeneratorEvaluationTest are selected or de-selected together " + << "by the test filter."; + } + + protected: + int count_; + static int global_count_; +}; +int SeparateInstanceTest::global_count_ = 0; + +TEST_P(SeparateInstanceTest, TestsRunInSeparateInstances) { + EXPECT_EQ(0, count_++); + global_count_++; +} +INSTANTIATE_TEST_CASE_P(FourElemSequence, SeparateInstanceTest, Range(1, 4)); + +// Tests that all instantiations of a test have named appropriately. Test +// defined with TEST_P(TestCaseName, TestName) and instantiated with +// INSTANTIATE_TEST_CASE_P(SequenceName, TestCaseName, generator) must be named +// SequenceName/TestCaseName.TestName/i, where i is the 0-based index of the +// sequence element used to instantiate the test. +class NamingTest : public TestWithParam {}; + +TEST_P(NamingTest, TestsAreNamedAppropriately) { + const ::testing::TestInfo* const test_info = + ::testing::UnitTest::GetInstance()->current_test_info(); + + EXPECT_STREQ("ZeroToFiveSequence/NamingTest", test_info->test_case_name()); + + Message msg; + msg << "TestsAreNamedAppropriately/" << GetParam(); + EXPECT_STREQ(msg.GetString().c_str(), test_info->name()); +} + +INSTANTIATE_TEST_CASE_P(ZeroToFiveSequence, NamingTest, Range(0, 5)); + +#endif // GTEST_HAS_PARAM_TEST + +TEST(CompileTest, CombineIsDefinedOnlyWhenGtestHasParamTestIsDefined) { +#if defined(GTEST_HAS_COMBINE) && !defined(GTEST_HAS_PARAM_TEST) + FAIL() << "GTEST_HAS_COMBINE is defined while GTEST_HAS_PARAM_TEST is not\n" +#endif +} + +int main(int argc, char **argv) { +#ifdef GTEST_HAS_PARAM_TEST + // Used in TestGenerationTest test case. + AddGlobalTestEnvironment(TestGenerationTest::Environment::Instance()); + // Used in GeneratorEvaluationTest test case. + GeneratorEvaluationTest::set_param_value(1); +#endif // GTEST_HAS_PARAM_TEST + + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/test/gtest-param-test_test.h b/test/gtest-param-test_test.h new file mode 100644 index 00000000..ee7bea00 --- /dev/null +++ b/test/gtest-param-test_test.h @@ -0,0 +1,55 @@ +// Copyright 2008, 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. +// +// Authors: vladl@google.com (Vlad Losev) +// +// The Google C++ Testing Framework (Google Test) +// +// This header file provides classes and functions used internally +// for testing Google Test itself. + +#ifndef GTEST_TEST_GTEST_PARAM_TEST_TEST_H_ +#define GTEST_TEST_GTEST_PARAM_TEST_TEST_H_ + +#include + +#ifdef GTEST_HAS_PARAM_TEST + +// Test fixture for testing definition and instantiation of a test +// in separate translation units. +class ExternalInstantiationTest : public ::testing::TestWithParam {}; + +// Test fixture for testing instantiation of a test in multiple +// translation units. +class InstantiationInMultipleTranslaionUnitsTest + : public ::testing::TestWithParam {}; + +#endif // GTEST_HAS_PARAM_TEST + +#endif // GTEST_TEST_GTEST_PARAM_TEST_TEST_H_ diff --git a/test/gtest-port_test.cc b/test/gtest-port_test.cc new file mode 100644 index 00000000..d945c589 --- /dev/null +++ b/test/gtest-port_test.cc @@ -0,0 +1,156 @@ +// Copyright 2008, 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: vladl@google.com (Vlad Losev) +// +// This file tests the internal cross-platform support utilities. + +#include +#include +#include + +TEST(GtestCheckSyntaxTest, BehavesLikeASingleStatement) { + if (false) + GTEST_CHECK_(false) << "This should never be executed; " + "It's a compilation test only."; + + if (true) + GTEST_CHECK_(true); + else + ; // NOLINT + + if (false) + ; // NOLINT + else + GTEST_CHECK_(true) << ""; +} + +TEST(GtestCheckSyntaxTest, WorksWithSwitch) { + switch (0) { + case 1: + break; + default: + GTEST_CHECK_(true); + } + + switch(0) + case 0: + GTEST_CHECK_(true) << "Check failed in switch case"; +} + +#ifdef GTEST_HAS_DEATH_TEST + +TEST(GtestCheckDeathTest, DiesWithCorrectOutputOnFailure) { + const bool a_false_condition = false; + EXPECT_DEATH(GTEST_CHECK_(a_false_condition) << "Extra info", +#ifdef _MSC_VER + "gtest-port_test\\.cc\\([0-9]+\\):" +#else + "gtest-port_test\\.cc:[0-9]+" +#endif // _MSC_VER + ".*a_false_condition.*Extra info.*"); +} + +TEST(GtestCheckDeathTest, LivesSilentlyOnSuccess) { + EXPECT_EXIT({ + GTEST_CHECK_(true) << "Extra info"; + ::std::cerr << "Success\n"; + exit(0); }, + ::testing::ExitedWithCode(0), "Success"); +} + +#endif // GTEST_HAS_DEATH_TEST + +#ifdef GTEST_USES_POSIX_RE + +using ::testing::internal::RE; + +template +class RETest : public ::testing::Test {}; + +// Defines StringTypes as the list of all string types that class RE +// supports. +typedef testing::Types< +#if GTEST_HAS_STD_STRING + ::std::string, +#endif // GTEST_HAS_STD_STRING +#if GTEST_HAS_GLOBAL_STRING + ::string, +#endif // GTEST_HAS_GLOBAL_STRING + const char*> StringTypes; + +TYPED_TEST_CASE(RETest, StringTypes); + +// Tests RE's implicit constructors. +TYPED_TEST(RETest, ImplicitConstructorWorks) { + const RE empty = TypeParam(""); + EXPECT_STREQ("", empty.pattern()); + + const RE simple = TypeParam("hello"); + EXPECT_STREQ("hello", simple.pattern()); + + const RE normal = TypeParam(".*(\\w+)"); + EXPECT_STREQ(".*(\\w+)", normal.pattern()); +} + +// Tests that RE's constructors reject invalid regular expressions. +TYPED_TEST(RETest, RejectsInvalidRegex) { + EXPECT_NONFATAL_FAILURE({ + const RE invalid = TypeParam("?"); + }, "\"?\" is not a valid POSIX Extended regular expression."); +} + +// Tests RE::FullMatch(). +TYPED_TEST(RETest, FullMatchWorks) { + const RE empty = TypeParam(""); + EXPECT_TRUE(RE::FullMatch(TypeParam(""), empty)); + EXPECT_FALSE(RE::FullMatch(TypeParam("a"), empty)); + + const RE re = TypeParam("a.*z"); + EXPECT_TRUE(RE::FullMatch(TypeParam("az"), re)); + EXPECT_TRUE(RE::FullMatch(TypeParam("axyz"), re)); + EXPECT_FALSE(RE::FullMatch(TypeParam("baz"), re)); + EXPECT_FALSE(RE::FullMatch(TypeParam("azy"), re)); +} + +// Tests RE::PartialMatch(). +TYPED_TEST(RETest, PartialMatchWorks) { + const RE empty = TypeParam(""); + EXPECT_TRUE(RE::PartialMatch(TypeParam(""), empty)); + EXPECT_TRUE(RE::PartialMatch(TypeParam("a"), empty)); + + const RE re = TypeParam("a.*z"); + EXPECT_TRUE(RE::PartialMatch(TypeParam("az"), re)); + EXPECT_TRUE(RE::PartialMatch(TypeParam("axyz"), re)); + EXPECT_TRUE(RE::PartialMatch(TypeParam("baz"), re)); + EXPECT_TRUE(RE::PartialMatch(TypeParam("azy"), re)); + EXPECT_FALSE(RE::PartialMatch(TypeParam("zza"), re)); +} + +#endif // GTEST_USES_POSIX_RE diff --git a/test/gtest-typed-test_test.cc b/test/gtest-typed-test_test.cc index 0cec71a7..ec03c95d 100644 --- a/test/gtest-typed-test_test.cc +++ b/test/gtest-typed-test_test.cc @@ -348,3 +348,15 @@ INSTANTIATE_TYPED_TEST_CASE_P(My, NumericTest, NumericTypes); } // namespace library2 #endif // GTEST_HAS_TYPED_TEST_P + +#if !defined(GTEST_HAS_TYPED_TEST) && !defined(GTEST_HAS_TYPED_TEST_P) + +// Google Test doesn't support type-parameterized tests on some platforms +// and compilers, such as MSVC 7.1. If we use conditional compilation to +// compile out all code referring to the gtest_main library, MSVC linker +// will not link that library at all and consequently complain about +// missing entry point defined in that library (fatal error LNK1561: +// entry point must be defined). This dummy test keeps gtest_main linked in. +TEST(DummyTest, TypedTestsAreNotSupportedOnThisPlatform) {} + +#endif // #if !defined(GTEST_HAS_TYPED_TEST) && !defined(GTEST_HAS_TYPED_TEST_P) diff --git a/test/gtest_filter_unittest.py b/test/gtest_filter_unittest.py index 04b69f76..b7dc2ed8 100755 --- a/test/gtest_filter_unittest.py +++ b/test/gtest_filter_unittest.py @@ -43,6 +43,7 @@ __author__ = 'wan@google.com (Zhanyong Wan)' import gtest_test_utils import os import re +import sets import sys import unittest @@ -58,26 +59,41 @@ FILTER_FLAG = 'gtest_filter' COMMAND = os.path.join(gtest_test_utils.GetBuildDir(), 'gtest_filter_unittest_') +# Regex for determining whether parameterized tests are enabled in the binary. +PARAM_TEST_REGEX = re.compile(r'/ParamTest') + # Regex for parsing test case names from Google Test's output. -TEST_CASE_REGEX = re.compile(r'^\[\-+\] \d+ test.* from (\w+)') +TEST_CASE_REGEX = re.compile(r'^\[\-+\] \d+ tests? from (\w+(/\w+)?)') # Regex for parsing test names from Google Test's output. -TEST_REGEX = re.compile(r'^\[\s*RUN\s*\].*\.(\w+)') +TEST_REGEX = re.compile(r'^\[\s*RUN\s*\].*\.(\w+(/\w+)?)') # Full names of all tests in gtest_filter_unittests_. +PARAM_TESTS = [ + 'SeqP/ParamTest.TestX/0', + 'SeqP/ParamTest.TestX/1', + 'SeqP/ParamTest.TestY/0', + 'SeqP/ParamTest.TestY/1', + 'SeqQ/ParamTest.TestX/0', + 'SeqQ/ParamTest.TestX/1', + 'SeqQ/ParamTest.TestY/0', + 'SeqQ/ParamTest.TestY/1', + ] + ALL_TESTS = [ 'FooTest.Abc', 'FooTest.Xyz', - 'BarTest.Test1', - 'BarTest.Test2', - 'BarTest.Test3', + 'BarTest.TestOne', + 'BarTest.TestTwo', + 'BarTest.TestThree', - 'BazTest.Test1', + 'BazTest.TestOne', 'BazTest.TestA', 'BazTest.TestB', - ] + ] + PARAM_TESTS +param_tests_present = None # Utilities. @@ -136,6 +152,11 @@ class GTestFilterUnitTest(unittest.TestCase): """Runs gtest_flag_unittest_ with the given filter, and verifies that the right set of tests were run. """ + # Adjust tests_to_run in case value parameterized tests are disabled + # in the binary. + global param_tests_present + if not param_tests_present: + tests_to_run = list(sets.Set(tests_to_run) - sets.Set(PARAM_TESTS)) # First, tests using GTEST_FILTER. @@ -155,6 +176,15 @@ class GTestFilterUnitTest(unittest.TestCase): tests_run = Run(command) self.AssertSetEqual(tests_run, tests_to_run) + def setUp(self): + """Sets up test case. Determines whether value-parameterized tests are + enabled in the binary and sets flags accordingly. + """ + global param_tests_present + if param_tests_present is None: + param_tests_present = PARAM_TEST_REGEX.search( + '\n'.join(os.popen(COMMAND, 'r').readlines())) is not None + def testDefaultBehavior(self): """Tests the behavior of not specifying the filter.""" @@ -189,20 +219,19 @@ class GTestFilterUnitTest(unittest.TestCase): def testFilterByTest(self): """Tests filtering by test name.""" - self.RunAndVerify('*.Test1', ['BarTest.Test1', 'BazTest.Test1']) + self.RunAndVerify('*.TestOne', ['BarTest.TestOne', 'BazTest.TestOne']) def testWildcardInTestCaseName(self): """Tests using wildcard in the test case name.""" self.RunAndVerify('*a*.*', [ - 'BarTest.Test1', - 'BarTest.Test2', - 'BarTest.Test3', + 'BarTest.TestOne', + 'BarTest.TestTwo', + 'BarTest.TestThree', - 'BazTest.Test1', + 'BazTest.TestOne', 'BazTest.TestA', - 'BazTest.TestB', - ]) + 'BazTest.TestB',] + PARAM_TESTS) def testWildcardInTestName(self): """Tests using wildcard in the test name.""" @@ -215,7 +244,7 @@ class GTestFilterUnitTest(unittest.TestCase): self.RunAndVerify('*z*', [ 'FooTest.Xyz', - 'BazTest.Test1', + 'BazTest.TestOne', 'BazTest.TestA', 'BazTest.TestB', ]) @@ -236,24 +265,24 @@ class GTestFilterUnitTest(unittest.TestCase): def testThreePatterns(self): """Tests filters that consist of three patterns.""" - self.RunAndVerify('*oo*:*A*:*1', [ + self.RunAndVerify('*oo*:*A*:*One', [ 'FooTest.Abc', 'FooTest.Xyz', - 'BarTest.Test1', + 'BarTest.TestOne', - 'BazTest.Test1', + 'BazTest.TestOne', 'BazTest.TestA', ]) # The 2nd pattern is empty. - self.RunAndVerify('*oo*::*1', [ + self.RunAndVerify('*oo*::*One', [ 'FooTest.Abc', 'FooTest.Xyz', - 'BarTest.Test1', + 'BarTest.TestOne', - 'BazTest.Test1', + 'BazTest.TestOne', ]) # The last 2 patterns are empty. @@ -266,49 +295,69 @@ class GTestFilterUnitTest(unittest.TestCase): self.RunAndVerify('*-FooTest.Abc', [ 'FooTest.Xyz', - 'BarTest.Test1', - 'BarTest.Test2', - 'BarTest.Test3', + 'BarTest.TestOne', + 'BarTest.TestTwo', + 'BarTest.TestThree', - 'BazTest.Test1', + 'BazTest.TestOne', 'BazTest.TestA', 'BazTest.TestB', - ]) + ] + PARAM_TESTS) self.RunAndVerify('*-FooTest.Abc:BazTest.*', [ 'FooTest.Xyz', - 'BarTest.Test1', - 'BarTest.Test2', - 'BarTest.Test3', - ]) + 'BarTest.TestOne', + 'BarTest.TestTwo', + 'BarTest.TestThree', + ] + PARAM_TESTS) - self.RunAndVerify('BarTest.*-BarTest.Test1', [ - 'BarTest.Test2', - 'BarTest.Test3', + self.RunAndVerify('BarTest.*-BarTest.TestOne', [ + 'BarTest.TestTwo', + 'BarTest.TestThree', ]) # Tests without leading '*'. self.RunAndVerify('-FooTest.Abc:FooTest.Xyz', [ - 'BarTest.Test1', - 'BarTest.Test2', - 'BarTest.Test3', + 'BarTest.TestOne', + 'BarTest.TestTwo', + 'BarTest.TestThree', - 'BazTest.Test1', + 'BazTest.TestOne', 'BazTest.TestA', 'BazTest.TestB', + ] + PARAM_TESTS) + + # Value parameterized tests. + self.RunAndVerify('*/*', PARAM_TESTS) + + # Value parameterized tests filtering by the sequence name. + self.RunAndVerify('SeqP/*', [ + 'SeqP/ParamTest.TestX/0', + 'SeqP/ParamTest.TestX/1', + 'SeqP/ParamTest.TestY/0', + 'SeqP/ParamTest.TestY/1', + ]) + + # Value parameterized tests filtering by the test name. + self.RunAndVerify('*/0', [ + 'SeqP/ParamTest.TestX/0', + 'SeqP/ParamTest.TestY/0', + 'SeqQ/ParamTest.TestX/0', + 'SeqQ/ParamTest.TestY/0', ]) def testFlagOverridesEnvVar(self): """Tests that the --gtest_filter flag overrides the GTEST_FILTER - environment variable.""" + environment variable. + """ SetEnvVar(FILTER_ENV_VAR, 'Foo*') - command = '%s --%s=%s' % (COMMAND, FILTER_FLAG, '*1') + command = '%s --%s=%s' % (COMMAND, FILTER_FLAG, '*One') tests_run = Run(command) SetEnvVar(FILTER_ENV_VAR, None) - self.AssertSetEqual(tests_run, ['BarTest.Test1', 'BazTest.Test1']) + self.AssertSetEqual(tests_run, ['BarTest.TestOne', 'BazTest.TestOne']) if __name__ == '__main__': diff --git a/test/gtest_filter_unittest_.cc b/test/gtest_filter_unittest_.cc index 6ff0d4f5..c554ad00 100644 --- a/test/gtest_filter_unittest_.cc +++ b/test/gtest_filter_unittest_.cc @@ -58,19 +58,19 @@ TEST_F(FooTest, Xyz) { // Test case BarTest. -TEST(BarTest, Test1) { +TEST(BarTest, TestOne) { } -TEST(BarTest, Test2) { +TEST(BarTest, TestTwo) { } -TEST(BarTest, Test3) { +TEST(BarTest, TestThree) { } // Test case BazTest. -TEST(BazTest, Test1) { +TEST(BazTest, TestOne) { FAIL() << "Expected failure."; } @@ -80,6 +80,20 @@ TEST(BazTest, TestA) { TEST(BazTest, TestB) { } +#ifdef GTEST_HAS_PARAM_TEST +class ParamTest : public testing::TestWithParam { +}; + +TEST_P(ParamTest, TestX) { +} + +TEST_P(ParamTest, TestY) { +} + +INSTANTIATE_TEST_CASE_P(SeqP, ParamTest, testing::Values(1, 2)); +INSTANTIATE_TEST_CASE_P(SeqQ, ParamTest, testing::Values(5, 6)); +#endif // GTEST_HAS_PARAM_TEST + } // namespace diff --git a/test/gtest_repeat_test.cc b/test/gtest_repeat_test.cc index 80287373..65298bfa 100644 --- a/test/gtest_repeat_test.cc +++ b/test/gtest_repeat_test.cc @@ -121,6 +121,24 @@ TEST(BarDeathTest, ThreadSafeAndFast) { #endif // GTEST_HAS_DEATH_TEST } +#ifdef GTEST_HAS_PARAM_TEST +int g_param_test_count = 0; + +const int kNumberOfParamTests = 10; + +class MyParamTest : public testing::TestWithParam {}; + +TEST_P(MyParamTest, ShouldPass) { + // TODO(vladl@google.com): Make parameter value checking robust + // WRT order of tests. + GTEST_CHECK_INT_EQ_(g_param_test_count % kNumberOfParamTests, GetParam()); + g_param_test_count++; +} +INSTANTIATE_TEST_CASE_P(MyParamSequence, + MyParamTest, + testing::Range(0, kNumberOfParamTests)); +#endif // GTEST_HAS_PARAM_TEST + // Resets the count for each test. void ResetCounts() { g_environment_set_up_count = 0; @@ -128,6 +146,9 @@ void ResetCounts() { g_should_fail_count = 0; g_should_pass_count = 0; g_death_test_count = 0; +#ifdef GTEST_HAS_PARAM_TEST + g_param_test_count = 0; +#endif // GTEST_HAS_PARAM_TEST } // Checks that the count for each test is expected. @@ -137,6 +158,9 @@ void CheckCounts(int expected) { GTEST_CHECK_INT_EQ_(expected, g_should_fail_count); GTEST_CHECK_INT_EQ_(expected, g_should_pass_count); GTEST_CHECK_INT_EQ_(expected, g_death_test_count); +#ifdef GTEST_HAS_PARAM_TEST + GTEST_CHECK_INT_EQ_(expected * kNumberOfParamTests, g_param_test_count); +#endif // GTEST_HAS_PARAM_TEST } // Tests the behavior of Google Test when --gtest_repeat is not specified. @@ -179,6 +203,9 @@ void TestRepeatWithFilterForSuccessfulTests(int repeat) { GTEST_CHECK_INT_EQ_(0, g_should_fail_count); GTEST_CHECK_INT_EQ_(repeat, g_should_pass_count); GTEST_CHECK_INT_EQ_(repeat, g_death_test_count); +#ifdef GTEST_HAS_PARAM_TEST + GTEST_CHECK_INT_EQ_(repeat * kNumberOfParamTests, g_param_test_count); +#endif // GTEST_HAS_PARAM_TEST } // Tests using --gtest_repeat when --gtest_filter specifies a set of @@ -194,6 +221,9 @@ void TestRepeatWithFilterForFailedTests(int repeat) { GTEST_CHECK_INT_EQ_(repeat, g_should_fail_count); GTEST_CHECK_INT_EQ_(0, g_should_pass_count); GTEST_CHECK_INT_EQ_(0, g_death_test_count); +#ifdef GTEST_HAS_PARAM_TEST + GTEST_CHECK_INT_EQ_(0, g_param_test_count); +#endif // GTEST_HAS_PARAM_TEST } } // namespace diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index 62cfaa39..0864d6eb 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -109,6 +109,8 @@ using testing::internal::AppendUserMessage; using testing::internal::CodePointToUtf8; using testing::internal::EqFailure; using testing::internal::FloatingPoint; +using testing::internal::GetCurrentOsStackTraceExceptTop; +using testing::internal::GetFailedPartCount; using testing::internal::GTestFlagSaver; using testing::internal::Int32; using testing::internal::List; @@ -899,6 +901,13 @@ TEST_F(TestResultTest, failed_part_count) { ASSERT_EQ(1u, r2->failed_part_count()); } +// Tests testing::internal::GetFailedPartCount(). +TEST_F(TestResultTest, GetFailedPartCount) { + ASSERT_EQ(0u, GetFailedPartCount(r0)); + ASSERT_EQ(0u, GetFailedPartCount(r1)); + ASSERT_EQ(1u, GetFailedPartCount(r2)); +} + // Tests TestResult::total_part_count() TEST_F(TestResultTest, total_part_count) { ASSERT_EQ(0u, r0->total_part_count()); @@ -4914,6 +4923,14 @@ TEST(ThreadLocalTest, Init) { EXPECT_EQ(&i, t2.get()); } +TEST(GetCurrentOsStackTraceExceptTopTest, ReturnsTheStackTrace) { + testing::UnitTest* const unit_test = testing::UnitTest::GetInstance(); + + // We don't have a stack walker in Google Test yet. + EXPECT_STREQ("", GetCurrentOsStackTraceExceptTop(unit_test, 0).c_str()); + EXPECT_STREQ("", GetCurrentOsStackTraceExceptTop(unit_test, 1).c_str()); +} + #ifndef GTEST_OS_SYMBIAN // We will want to integrate running the unittests to a different // main application on Symbian. -- cgit v1.2.3 From 514265c415e072caf92fb4eed57aacdfea9964f1 Mon Sep 17 00:00:00 2001 From: vladlosev Date: Sat, 22 Nov 2008 02:26:23 +0000 Subject: Fixed two of the failing tests mentioned in issue 9 --- test/gtest_test_utils.py | 25 +++++++++++++++++++++++++ test/gtest_xml_outfiles_test.py | 7 ++++--- test/gtest_xml_output_unittest.py | 11 +++++------ 3 files changed, 34 insertions(+), 9 deletions(-) (limited to 'test') diff --git a/test/gtest_test_utils.py b/test/gtest_test_utils.py index f454774d..a3f0138e 100755 --- a/test/gtest_test_utils.py +++ b/test/gtest_test_utils.py @@ -116,6 +116,31 @@ def GetExitStatus(exit_code): return -1 +def RunCommandSuppressOutput(command, working_dir=None): + """Changes into a specified directory, if provided, and executes a command. + Restores the old directory afterwards. + + Args: + command: A command to run. + working_dir: A directory to change into. + """ + + old_dir = None + try: + if working_dir is not None: + old_dir = os.getcwd() + os.chdir(working_dir) + f = os.popen(command, 'r') + f.read() + ret_code = f.close() + finally: + if old_dir is not None: + os.chdir(old_dir) + if ret_code is None: + ret_code = 0 + return ret_code + + def Main(): """Runs the unit test.""" diff --git a/test/gtest_xml_outfiles_test.py b/test/gtest_xml_outfiles_test.py index b83df775..d5d7266a 100755 --- a/test/gtest_xml_outfiles_test.py +++ b/test/gtest_xml_outfiles_test.py @@ -100,9 +100,10 @@ class GTestXMLOutFilesTest(gtest_xml_test_utils.GTestXMLTestCase): def _TestOutFile(self, test_name, expected_xml): gtest_prog_path = os.path.join(gtest_test_utils.GetBuildDir(), test_name) - command = "cd %s && %s --gtest_output=xml:%s &> /dev/null" % ( - tempfile.mkdtemp(), gtest_prog_path, self.output_dir_) - status = os.system(command) + command = "%s --gtest_output=xml:%s" % (gtest_prog_path, self.output_dir_) + status = gtest_test_utils.RunCommandSuppressOutput( + command, + working_dir=tempfile.mkdtemp()) self.assertEquals(0, gtest_test_utils.GetExitStatus(status)) # TODO(wan@google.com): libtool causes the built test binary to be diff --git a/test/gtest_xml_output_unittest.py b/test/gtest_xml_output_unittest.py index 7206006c..c5f9f57f 100755 --- a/test/gtest_xml_output_unittest.py +++ b/test/gtest_xml_output_unittest.py @@ -131,9 +131,9 @@ class GTestXMLOutputUnitTest(gtest_xml_test_utils.GTestXMLTestCase): if e.errno != errno.ENOENT: raise - status = os.system("cd %s && %s %s=xml &> /dev/null" - % (temp_dir, gtest_prog_path, - GTEST_OUTPUT_FLAG)) + status = gtest_test_utils.RunCommandSuppressOutput( + "%s %s=xml" % (gtest_prog_path, GTEST_OUTPUT_FLAG), + working_dir=temp_dir) self.assertEquals(0, gtest_test_utils.GetExitStatus(status)) self.assert_(os.path.isfile(output_file)) @@ -150,9 +150,8 @@ class GTestXMLOutputUnitTest(gtest_xml_test_utils.GTestXMLTestCase): gtest_prog_path = os.path.join(gtest_test_utils.GetBuildDir(), gtest_prog_name) - command = ("%s %s=xml:%s &> /dev/null" - % (gtest_prog_path, GTEST_OUTPUT_FLAG, xml_path)) - status = os.system(command) + command = ("%s %s=xml:%s" % (gtest_prog_path, GTEST_OUTPUT_FLAG, xml_path)) + status = gtest_test_utils.RunCommandSuppressOutput(command) if os.WIFSIGNALED(status): signal = os.WTERMSIG(status) self.assert_(False, -- cgit v1.2.3 From c440a6923aa65d5be64134a6f430a5867a63df3f Mon Sep 17 00:00:00 2001 From: shiqian Date: Mon, 24 Nov 2008 20:13:22 +0000 Subject: Enables the Python tests to run with 2.3 (necessary for testing on Mac OS X Tiger); also fixes gtest_output_test when built with xcode. --- test/gtest_unittest.cc | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'test') diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index 0864d6eb..d926a744 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -105,12 +105,15 @@ using testing::TPRT_FATAL_FAILURE; using testing::TPRT_NONFATAL_FAILURE; using testing::TPRT_SUCCESS; using testing::UnitTest; +using testing::internal::kTestTypeIdInGoogleTest; using testing::internal::AppendUserMessage; using testing::internal::CodePointToUtf8; using testing::internal::EqFailure; using testing::internal::FloatingPoint; using testing::internal::GetCurrentOsStackTraceExceptTop; using testing::internal::GetFailedPartCount; +using testing::internal::GetTestTypeId; +using testing::internal::GetTypeId; using testing::internal::GTestFlagSaver; using testing::internal::Int32; using testing::internal::List; @@ -126,6 +129,31 @@ using testing::internal::WideStringToUtf8; // This line tests that we can define tests in an unnamed namespace. namespace { +// Tests GetTypeId. + +TEST(GetTypeIdTest, ReturnsSameValueForSameType) { + EXPECT_EQ(GetTypeId(), GetTypeId()); + EXPECT_EQ(GetTypeId(), GetTypeId()); +} + +class SubClassOfTest : public Test {}; +class AnotherSubClassOfTest : public Test {}; + +TEST(GetTypeIdTest, ReturnsDifferentValuesForDifferentTypes) { + EXPECT_NE(GetTypeId(), GetTypeId()); + EXPECT_NE(GetTypeId(), GetTypeId()); + EXPECT_NE(GetTypeId(), GetTestTypeId()); + EXPECT_NE(GetTypeId(), GetTestTypeId()); + EXPECT_NE(GetTypeId(), GetTestTypeId()); + EXPECT_NE(GetTypeId(), GetTypeId()); +} + +// Verifies that GetTestTypeId() returns the same value, no matter it +// is called from inside Google Test or outside of it. +TEST(GetTestTypeIdTest, ReturnsTheSameValueInsideOrOutsideOfGoogleTest) { + EXPECT_EQ(kTestTypeIdInGoogleTest, GetTestTypeId()); +} + // Tests FormatTimeInMillisAsSeconds(). TEST(FormatTimeInMillisAsSecondsTest, FormatsZero) { -- cgit v1.2.3 From 95536ab53bba952d748f6c1535ba9a3b2ff7e294 Mon Sep 17 00:00:00 2001 From: vladlosev Date: Wed, 26 Nov 2008 20:02:45 +0000 Subject: Fixed gtest_break_on_failure_unittest on Ubuntu 8.04 and Windows --- test/gtest_break_on_failure_unittest.py | 18 ++++--- test/gtest_break_on_failure_unittest_.cc | 8 +++ test/gtest_test_utils.py | 87 ++++++++++++++++++++++++-------- test/gtest_xml_outfiles_test.py | 9 ++-- test/gtest_xml_output_unittest.py | 24 ++++----- 5 files changed, 101 insertions(+), 45 deletions(-) (limited to 'test') diff --git a/test/gtest_break_on_failure_unittest.py b/test/gtest_break_on_failure_unittest.py index 88716c9c..a295ac40 100755 --- a/test/gtest_break_on_failure_unittest.py +++ b/test/gtest_break_on_failure_unittest.py @@ -77,8 +77,11 @@ def Run(command): """Runs a command; returns 1 if it was killed by a signal, or 0 otherwise. """ - exit_code = os.system(command) - return os.WIFSIGNALED(exit_code) + p = gtest_test_utils.Subprocess(command) + if p.terminated_by_signal: + return 1 + else: + return 0 # The unit test. @@ -112,11 +115,13 @@ class GTestBreakOnFailureUnitTest(unittest.TestCase): if flag_value is None: flag = '' elif flag_value == '0': - flag = ' --%s=0' % BREAK_ON_FAILURE_FLAG + flag = '--%s=0' % BREAK_ON_FAILURE_FLAG else: - flag = ' --%s' % BREAK_ON_FAILURE_FLAG + flag = '--%s' % BREAK_ON_FAILURE_FLAG - command = EXE_PATH + flag + command = [EXE_PATH] + if flag: + command.append(flag) if expect_seg_fault: should_or_not = 'should' @@ -128,7 +133,8 @@ class GTestBreakOnFailureUnitTest(unittest.TestCase): SetEnvVar(BREAK_ON_FAILURE_ENV_VAR, None) msg = ('when %s%s, an assertion failure in "%s" %s cause a seg-fault.' % - (BREAK_ON_FAILURE_ENV_VAR, env_var_value_msg, command, should_or_not)) + (BREAK_ON_FAILURE_ENV_VAR, env_var_value_msg, ' '.join(command), + should_or_not)) self.assert_(has_seg_fault == expect_seg_fault, msg) def testDefaultBehavior(self): diff --git a/test/gtest_break_on_failure_unittest_.cc b/test/gtest_break_on_failure_unittest_.cc index f272fdd5..84c4a2ee 100644 --- a/test/gtest_break_on_failure_unittest_.cc +++ b/test/gtest_break_on_failure_unittest_.cc @@ -41,6 +41,9 @@ #include +#ifdef GTEST_OS_WINDOWS +#include +#endif namespace { @@ -53,6 +56,11 @@ TEST(Foo, Bar) { int main(int argc, char **argv) { +#ifdef GTEST_OS_WINDOWS + // Suppresses display of the Windows error dialog upon encountering + // a general protection fault (segment violation). + SetErrorMode(SEM_NOGPFAULTERRORBOX | SEM_FAILCRITICALERRORS); +#endif testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); diff --git a/test/gtest_test_utils.py b/test/gtest_test_utils.py index a3f0138e..8ee99c08 100755 --- a/test/gtest_test_utils.py +++ b/test/gtest_test_utils.py @@ -37,6 +37,13 @@ import os import sys import unittest +try: + import subprocess + _SUBPROCESS_MODULE_AVAILABLE = True +except: + import popen2 + _SUBPROCESS_MODULE_AVAILABLE = False + # Initially maps a flag to its default value. After # _ParseAndStripGTestFlags() is called, maps a flag to its actual @@ -116,29 +123,65 @@ def GetExitStatus(exit_code): return -1 -def RunCommandSuppressOutput(command, working_dir=None): - """Changes into a specified directory, if provided, and executes a command. - Restores the old directory afterwards. - - Args: - command: A command to run. - working_dir: A directory to change into. - """ - - old_dir = None - try: - if working_dir is not None: +class Subprocess: + def __init__(this, command, working_dir=None): + """Changes into a specified directory, if provided, and executes a command. + Restores the old directory afterwards. Execution results are returned + via the following attributes: + terminated_by_sygnal True iff the child process has been terminated + by a signal. + signal Sygnal that terminated the child process. + exited True iff the child process exited normally. + exit_code The code with which the child proces exited. + output Child process's stdout and stderr output + combined in a string. + + Args: + command: A command to run. + working_dir: A directory to change into. + """ + + # The subprocess module is the preferrable way of running programs + # since it is available and behaves consistently on all platforms, + # including Windows. But it is only available starting in python 2.4. + # In earlier python versions, we revert to the popen2 module, which is + # available in python 2.0 and later but doesn't provide required + # functionality (Popen4) under Windows. This allows us to support Mac + # OS X 10.4 Tiger, which has python 2.3 installed. + if _SUBPROCESS_MODULE_AVAILABLE: + p = subprocess.Popen(command, + stdout=subprocess.PIPE, stderr=subprocess.STDOUT, + cwd=working_dir, universal_newlines=True) + # communicate returns a tuple with the file obect for the child's + # output. + this.output = p.communicate()[0] + this._return_code = p.returncode + else: old_dir = os.getcwd() - os.chdir(working_dir) - f = os.popen(command, 'r') - f.read() - ret_code = f.close() - finally: - if old_dir is not None: - os.chdir(old_dir) - if ret_code is None: - ret_code = 0 - return ret_code + try: + if working_dir is not None: + os.chdir(working_dir) + p = popen2.Popen4(command) + p.tochild.close() + this.output = p.fromchild.read() + ret_code = p.wait() + finally: + os.chdir(old_dir) + # Converts ret_code to match the semantics of + # subprocess.Popen.returncode. + if os.WIFSIGNALED(ret_code): + this._return_code = -os.WTERMSIG(ret_code) + else: # os.WIFEXITED(ret_code) should return True here. + this._return_code = os.WEXITSTATUS(ret_code) + + if this._return_code < 0: + this.terminated_by_signal = True + this.exited = False + this.signal = -this._return_code + else: + this.terminated_by_signal = False + this.exited = True + this.exit_code = this._return_code def Main(): diff --git a/test/gtest_xml_outfiles_test.py b/test/gtest_xml_outfiles_test.py index d5d7266a..4ebc15ef 100755 --- a/test/gtest_xml_outfiles_test.py +++ b/test/gtest_xml_outfiles_test.py @@ -100,11 +100,10 @@ class GTestXMLOutFilesTest(gtest_xml_test_utils.GTestXMLTestCase): def _TestOutFile(self, test_name, expected_xml): gtest_prog_path = os.path.join(gtest_test_utils.GetBuildDir(), test_name) - command = "%s --gtest_output=xml:%s" % (gtest_prog_path, self.output_dir_) - status = gtest_test_utils.RunCommandSuppressOutput( - command, - working_dir=tempfile.mkdtemp()) - self.assertEquals(0, gtest_test_utils.GetExitStatus(status)) + command = [gtest_prog_path, "--gtest_output=xml:%s" % self.output_dir_] + p = gtest_test_utils.Subprocess(command, working_dir=tempfile.mkdtemp()) + self.assert_(p.exited) + self.assertEquals(0, p.exit_code) # TODO(wan@google.com): libtool causes the built test binary to be # named lt-gtest_xml_outfiles_test_ instead of diff --git a/test/gtest_xml_output_unittest.py b/test/gtest_xml_output_unittest.py index c5f9f57f..5e0b220b 100755 --- a/test/gtest_xml_output_unittest.py +++ b/test/gtest_xml_output_unittest.py @@ -131,10 +131,11 @@ class GTestXMLOutputUnitTest(gtest_xml_test_utils.GTestXMLTestCase): if e.errno != errno.ENOENT: raise - status = gtest_test_utils.RunCommandSuppressOutput( - "%s %s=xml" % (gtest_prog_path, GTEST_OUTPUT_FLAG), - working_dir=temp_dir) - self.assertEquals(0, gtest_test_utils.GetExitStatus(status)) + p = gtest_test_utils.Subprocess( + [gtest_prog_path, "%s=xml" % GTEST_OUTPUT_FLAG], + working_dir=temp_dir) + self.assert_(p.exited) + self.assertEquals(0, p.exit_code) self.assert_(os.path.isfile(output_file)) @@ -150,18 +151,17 @@ class GTestXMLOutputUnitTest(gtest_xml_test_utils.GTestXMLTestCase): gtest_prog_path = os.path.join(gtest_test_utils.GetBuildDir(), gtest_prog_name) - command = ("%s %s=xml:%s" % (gtest_prog_path, GTEST_OUTPUT_FLAG, xml_path)) - status = gtest_test_utils.RunCommandSuppressOutput(command) - if os.WIFSIGNALED(status): - signal = os.WTERMSIG(status) + command = [gtest_prog_path, "%s=xml:%s" % (GTEST_OUTPUT_FLAG, xml_path)] + p = gtest_test_utils.Subprocess(command) + if p.terminated_by_signal: self.assert_(False, - "%s was killed by signal %d" % (gtest_prog_name, signal)) + "%s was killed by signal %d" % (gtest_prog_name, p.signal)) else: - exit_code = gtest_test_utils.GetExitStatus(status) - self.assertEquals(expected_exit_code, exit_code, + self.assert_(p.exited) + self.assertEquals(expected_exit_code, p.exit_code, "'%s' exited with code %s, which doesn't match " "the expected exit code %s." - % (command, exit_code, expected_exit_code)) + % (command, p.exit_code, expected_exit_code)) expected = minidom.parseString(expected_xml) actual = minidom.parse(xml_path) -- cgit v1.2.3 From 957ed9fb5210a8e0e51f713387961d2538921aed Mon Sep 17 00:00:00 2001 From: vladlosev Date: Wed, 26 Nov 2008 20:06:52 +0000 Subject: Adding test/gtest_uninitialized_test.py missing from the previous check-in --- test/gtest_uninitialized_test.py | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) (limited to 'test') diff --git a/test/gtest_uninitialized_test.py b/test/gtest_uninitialized_test.py index 037daa8f..a3ba629c 100755 --- a/test/gtest_uninitialized_test.py +++ b/test/gtest_uninitialized_test.py @@ -67,24 +67,14 @@ def AssertEq(expected, actual): raise AssertionError -def GetOutput(command): - """Runs the given command and returns its output.""" - - stdin, stdout = os.popen2(command, 't') - stdin.close() - output = stdout.read() - stdout.close() - return output - - def TestExitCodeAndOutput(command): """Runs the given command and verifies its exit code and output.""" # Verifies that 'command' exits with code 1. - AssertEq(1, gtest_test_utils.GetExitStatus(os.system(command))) - - output = GetOutput(command) - Assert('InitGoogleTest' in output) + p = gtest_test_utils.Subprocess(command) + Assert(p.exited) + AssertEq(1, p.exit_code) + Assert('InitGoogleTest' in p.output) if IS_WINDOWS: -- cgit v1.2.3 From 1998cf5d32a19aaffe8652545802744d9133022d Mon Sep 17 00:00:00 2001 From: vladlosev Date: Wed, 26 Nov 2008 20:48:45 +0000 Subject: Allow Google Mock to initialize Google Test --- test/gtest_unittest.cc | 68 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 67 insertions(+), 1 deletion(-) (limited to 'test') diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index d926a744..1cbb27f6 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -510,6 +510,72 @@ TEST(StringTest, Constructors) { EXPECT_STREQ("hel", s4.c_str()); } +#if GTEST_HAS_STD_STRING + +TEST(StringTest, ConvertsFromStdString) { + // An empty std::string. + const std::string src1(""); + const String dest1 = src1; + EXPECT_STREQ("", dest1.c_str()); + + // A normal std::string. + const std::string src2("Hi"); + const String dest2 = src2; + EXPECT_STREQ("Hi", dest2.c_str()); + + // An std::string with an embedded NUL character. + const char src3[] = "Hello\0world."; + const String dest3 = std::string(src3, sizeof(src3)); + EXPECT_STREQ("Hello", dest3.c_str()); +} + +TEST(StringTest, ConvertsToStdString) { + // An empty String. + const String src1(""); + const std::string dest1 = src1; + EXPECT_EQ("", dest1); + + // A normal String. + const String src2("Hi"); + const std::string dest2 = src2; + EXPECT_EQ("Hi", dest2); +} + +#endif // GTEST_HAS_STD_STRING + +#if GTEST_HAS_GLOBAL_STRING + +TEST(StringTest, ConvertsFromGlobalString) { + // An empty ::string. + const ::string src1(""); + const String dest1 = src1; + EXPECT_STREQ("", dest1.c_str()); + + // A normal ::string. + const ::string src2("Hi"); + const String dest2 = src2; + EXPECT_STREQ("Hi", dest2.c_str()); + + // An ::string with an embedded NUL character. + const char src3[] = "Hello\0world."; + const String dest3 = ::string(src3, sizeof(src3)); + EXPECT_STREQ("Hello", dest3.c_str()); +} + +TEST(StringTest, ConvertsToGlobalString) { + // An empty String. + const String src1(""); + const ::string dest1 = src1; + EXPECT_EQ("", dest1); + + // A normal String. + const String src2("Hi"); + const ::string dest2 = src2; + EXPECT_EQ("Hi", dest2); +} + +#endif // GTEST_HAS_GLOBAL_STRING + // Tests String::ShowCString(). TEST(StringTest, ShowCString) { EXPECT_STREQ("(null)", String::ShowCString(NULL)); @@ -4116,7 +4182,7 @@ class InitGoogleTestTest : public Test { int argc2, const CharType** argv2, const Flags& expected) { // Parses the command line. - InitGoogleTest(&argc1, const_cast(argv1)); + internal::ParseGoogleTestFlagsOnly(&argc1, const_cast(argv1)); // Verifies the flag values. CheckFlags(expected); -- cgit v1.2.3 From 5145e0fb203071648f4be6b77c68fabf3d92ab8a Mon Sep 17 00:00:00 2001 From: shiqian Date: Tue, 9 Dec 2008 00:54:04 +0000 Subject: Use instead of when the compiler is not gcc, to conform with the TR1 spec. --- test/gtest-param-test_test.cc | 4 ---- 1 file changed, 4 deletions(-) (limited to 'test') diff --git a/test/gtest-param-test_test.cc b/test/gtest-param-test_test.cc index 6d84dcf9..22ba1a34 100644 --- a/test/gtest-param-test_test.cc +++ b/test/gtest-param-test_test.cc @@ -42,10 +42,6 @@ #include #include -#ifdef GTEST_HAS_COMBINE -#include -#endif // GTEST_HAS_COMBINE - // To include gtest-internal-inl.h. #define GTEST_IMPLEMENTATION #include "src/gtest-internal-inl.h" // for UnitTestOptions -- cgit v1.2.3 From 53e0dc4041f660b6517b15b08b496e164be614f1 Mon Sep 17 00:00:00 2001 From: shiqian Date: Thu, 8 Jan 2009 01:10:31 +0000 Subject: Implements the --gtest_death_test_use_fork flag and StaticAssertTypeEq. --- test/gtest-death-test_test.cc | 23 ++++++++++++----- test/gtest_env_var_test.py | 1 + test/gtest_env_var_test_.cc | 5 ++++ test/gtest_nc.cc | 41 ++++++++++++++++++++++++++++++ test/gtest_nc_test.py | 12 +++++++++ test/gtest_unittest.cc | 59 +++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 135 insertions(+), 6 deletions(-) (limited to 'test') diff --git a/test/gtest-death-test_test.cc b/test/gtest-death-test_test.cc index 07268d00..204ec413 100644 --- a/test/gtest-death-test_test.cc +++ b/test/gtest-death-test_test.cc @@ -347,11 +347,13 @@ void SetPthreadFlag() { } // namespace TEST_F(TestForDeathTest, DoesNotExecuteAtforkHooks) { - testing::GTEST_FLAG(death_test_style) = "threadsafe"; - pthread_flag = false; - ASSERT_EQ(0, pthread_atfork(&SetPthreadFlag, NULL, NULL)); - ASSERT_DEATH(_exit(1), ""); - ASSERT_FALSE(pthread_flag); + if (!testing::GTEST_FLAG(death_test_use_fork)) { + testing::GTEST_FLAG(death_test_style) = "threadsafe"; + pthread_flag = false; + ASSERT_EQ(0, pthread_atfork(&SetPthreadFlag, NULL, NULL)); + ASSERT_DEATH(_exit(1), ""); + ASSERT_FALSE(pthread_flag); + } } // Tests that a method of another class can be used in a death test. @@ -561,7 +563,7 @@ TEST_F(TestForDeathTest, AssertDebugDeathAborts) { #endif // _NDEBUG // Tests the *_EXIT family of macros, using a variety of predicates. -TEST_F(TestForDeathTest, ExitMacros) { +static void TestExitMacros() { EXPECT_EXIT(_exit(1), testing::ExitedWithCode(1), ""); ASSERT_EXIT(_exit(42), testing::ExitedWithCode(42), ""); EXPECT_EXIT(raise(SIGKILL), testing::KilledBySignal(SIGKILL), "") << "foo"; @@ -578,6 +580,15 @@ TEST_F(TestForDeathTest, ExitMacros) { }, "This failure is expected, too."); } +TEST_F(TestForDeathTest, ExitMacros) { + TestExitMacros(); +} + +TEST_F(TestForDeathTest, ExitMacrosUsingFork) { + testing::GTEST_FLAG(death_test_use_fork) = true; + TestExitMacros(); +} + TEST_F(TestForDeathTest, InvalidStyle) { testing::GTEST_FLAG(death_test_style) = "rococo"; EXPECT_NONFATAL_FAILURE({ // NOLINT diff --git a/test/gtest_env_var_test.py b/test/gtest_env_var_test.py index 1b86b5a9..67a22493 100755 --- a/test/gtest_env_var_test.py +++ b/test/gtest_env_var_test.py @@ -109,6 +109,7 @@ def TestEnvVarAffectsFlag(command): if IS_LINUX: TestFlag(command, 'stack_trace_depth', '0', '100') TestFlag(command, 'death_test_style', 'thread-safe', 'fast') + TestFlag(command, 'death_test_use_fork', '1', '0') if IS_WINDOWS: diff --git a/test/gtest_env_var_test_.cc b/test/gtest_env_var_test_.cc index 16b31103..bbccd462 100644 --- a/test/gtest_env_var_test_.cc +++ b/test/gtest_env_var_test_.cc @@ -71,6 +71,11 @@ void PrintFlag(const char* flag) { return; } + if (strcmp(flag, "death_test_use_fork") == 0) { + cout << GTEST_FLAG(death_test_use_fork); + return; + } + if (strcmp(flag, "filter") == 0) { cout << GTEST_FLAG(filter); return; diff --git a/test/gtest_nc.cc b/test/gtest_nc.cc index 5cbaeefa..73b5db6d 100644 --- a/test/gtest_nc.cc +++ b/test/gtest_nc.cc @@ -181,6 +181,47 @@ INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, testing::Types); // Wrong name prefix: "My" has been used. INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, testing::Types); +#elif defined(TEST_STATIC_ASSERT_TYPE_EQ_IS_NOT_A_TYPE) + +#include + +// Tests that StaticAssertTypeEq cannot be used as a type. +testing::StaticAssertTypeEq dummy; + +#elif defined(TEST_STATIC_ASSERT_TYPE_EQ_WORKS_IN_NAMESPACE) + +#include + +// Tests that StaticAssertTypeEq works in a namespace scope. +static bool dummy = testing::StaticAssertTypeEq(); + +#elif defined(TEST_STATIC_ASSERT_TYPE_EQ_WORKS_IN_CLASS) + +#include + +template +class Helper { + public: + // Tests that StaticAssertTypeEq works in a class. + Helper() { testing::StaticAssertTypeEq(); } + + void DoSomething() {} +}; + +void Test() { + Helper h; + h.DoSomething(); // To avoid the "unused variable" warning. +} + +#elif defined(TEST_STATIC_ASSERT_TYPE_EQ_WORKS_IN_FUNCTION) + +#include + +void Test() { + // Tests that StaticAssertTypeEq works inside a function. + testing::StaticAssertTypeEq(); +} + #else // A sanity test. This should compile. diff --git a/test/gtest_nc_test.py b/test/gtest_nc_test.py index 683bd370..6e77d708 100755 --- a/test/gtest_nc_test.py +++ b/test/gtest_nc_test.py @@ -78,6 +78,18 @@ class GTestNCTest(unittest.TestCase): ('CATCHES_INSTANTIATE_TYPED_TESET_CASE_P_WITH_SAME_NAME_PREFIX', [r'redefinition of.*My.*FooTest']), + ('STATIC_ASSERT_TYPE_EQ_IS_NOT_A_TYPE', + [r'StaticAssertTypeEq.* does not name a type']), + + ('STATIC_ASSERT_TYPE_EQ_WORKS_IN_NAMESPACE', + [r'StaticAssertTypeEq.*int.*const int']), + + ('STATIC_ASSERT_TYPE_EQ_WORKS_IN_CLASS', + [r'StaticAssertTypeEq.*int.*bool']), + + ('STATIC_ASSERT_TYPE_EQ_WORKS_IN_FUNCTION', + [r'StaticAssertTypeEq.*const int.*int']), + ('SANITY', None) ] diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index 1cbb27f6..2794f7ec 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -86,6 +86,7 @@ using testing::DoubleLE; using testing::FloatLE; using testing::GTEST_FLAG(break_on_failure); using testing::GTEST_FLAG(catch_exceptions); +using testing::GTEST_FLAG(death_test_use_fork); using testing::GTEST_FLAG(color); using testing::GTEST_FLAG(filter); using testing::GTEST_FLAG(list_tests); @@ -98,6 +99,7 @@ using testing::IsNotSubstring; using testing::IsSubstring; using testing::Message; using testing::ScopedFakeTestPartResultReporter; +using testing::StaticAssertTypeEq; using testing::Test; using testing::TestPartResult; using testing::TestPartResultArray; @@ -1128,6 +1130,7 @@ class GTestFlagSaverTest : public Test { GTEST_FLAG(break_on_failure) = false; GTEST_FLAG(catch_exceptions) = false; + GTEST_FLAG(death_test_use_fork) = false; GTEST_FLAG(color) = "auto"; GTEST_FLAG(filter) = ""; GTEST_FLAG(list_tests) = false; @@ -1149,6 +1152,7 @@ class GTestFlagSaverTest : public Test { EXPECT_FALSE(GTEST_FLAG(break_on_failure)); EXPECT_FALSE(GTEST_FLAG(catch_exceptions)); EXPECT_STREQ("auto", GTEST_FLAG(color).c_str()); + EXPECT_FALSE(GTEST_FLAG(death_test_use_fork)); EXPECT_STREQ("", GTEST_FLAG(filter).c_str()); EXPECT_FALSE(GTEST_FLAG(list_tests)); EXPECT_STREQ("", GTEST_FLAG(output).c_str()); @@ -1158,6 +1162,7 @@ class GTestFlagSaverTest : public Test { GTEST_FLAG(break_on_failure) = true; GTEST_FLAG(catch_exceptions) = true; GTEST_FLAG(color) = "no"; + GTEST_FLAG(death_test_use_fork) = true; GTEST_FLAG(filter) = "abc"; GTEST_FLAG(list_tests) = true; GTEST_FLAG(output) = "xml:foo.xml"; @@ -4064,6 +4069,7 @@ struct Flags { // Constructs a Flags struct where each flag has its default value. Flags() : break_on_failure(false), catch_exceptions(false), + death_test_use_fork(false), filter(""), list_tests(false), output(""), @@ -4088,6 +4094,14 @@ struct Flags { return flags; } + // Creates a Flags struct where the gtest_death_test_use_fork flag has + // the given value. + static Flags DeathTestUseFork(bool death_test_use_fork) { + Flags flags; + flags.death_test_use_fork = death_test_use_fork; + return flags; + } + // Creates a Flags struct where the gtest_filter flag has the given // value. static Flags Filter(const char* filter) { @@ -4131,6 +4145,7 @@ struct Flags { // These fields store the flag values. bool break_on_failure; bool catch_exceptions; + bool death_test_use_fork; const char* filter; bool list_tests; const char* output; @@ -4145,6 +4160,7 @@ class InitGoogleTestTest : public Test { virtual void SetUp() { GTEST_FLAG(break_on_failure) = false; GTEST_FLAG(catch_exceptions) = false; + GTEST_FLAG(death_test_use_fork) = false; GTEST_FLAG(filter) = ""; GTEST_FLAG(list_tests) = false; GTEST_FLAG(output) = ""; @@ -4167,6 +4183,7 @@ class InitGoogleTestTest : public Test { static void CheckFlags(const Flags& expected) { EXPECT_EQ(expected.break_on_failure, GTEST_FLAG(break_on_failure)); EXPECT_EQ(expected.catch_exceptions, GTEST_FLAG(catch_exceptions)); + EXPECT_EQ(expected.death_test_use_fork, GTEST_FLAG(death_test_use_fork)); EXPECT_STREQ(expected.filter, GTEST_FLAG(filter).c_str()); EXPECT_EQ(expected.list_tests, GTEST_FLAG(list_tests)); EXPECT_STREQ(expected.output, GTEST_FLAG(output).c_str()); @@ -4373,6 +4390,22 @@ TEST_F(InitGoogleTestTest, CatchExceptions) { TEST_PARSING_FLAGS(argv, argv2, Flags::CatchExceptions(true)); } +// Tests parsing --gtest_death_test_use_fork. +TEST_F(InitGoogleTestTest, DeathTestUseFork) { + const char* argv[] = { + "foo.exe", + "--gtest_death_test_use_fork", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + TEST_PARSING_FLAGS(argv, argv2, Flags::DeathTestUseFork(true)); +} + // Tests having the same flag twice with different values. The // expected behavior is that the one coming last takes precedence. TEST_F(InitGoogleTestTest, DuplicatedFlags) { @@ -5000,6 +5033,32 @@ TEST(ColoredOutputTest, UsesColorsWhenTermSupportsColors) { #endif // GTEST_OS_WINDOWS } +// Verifies that StaticAssertTypeEq works in a namespace scope. + +static bool dummy1 = StaticAssertTypeEq(); +static bool dummy2 = StaticAssertTypeEq(); + +// Verifies that StaticAssertTypeEq works in a class. + +template +class StaticAssertTypeEqTestHelper { + public: + StaticAssertTypeEqTestHelper() { StaticAssertTypeEq(); } +}; + +TEST(StaticAssertTypeEqTest, WorksInClass) { + StaticAssertTypeEqTestHelper(); +} + +// Verifies that StaticAssertTypeEq works inside a function. + +typedef int IntAlias; + +TEST(StaticAssertTypeEqTest, CompilesForEqualTypes) { + StaticAssertTypeEq(); + StaticAssertTypeEq(); +} + TEST(ThreadLocalTest, DefaultConstructor) { ThreadLocal t1; EXPECT_EQ(0, t1.get()); -- cgit v1.2.3 From fe186c382905dcf57014985ccea8e067275e9f5f Mon Sep 17 00:00:00 2001 From: shiqian Date: Sat, 10 Jan 2009 01:16:33 +0000 Subject: Implements --gtest_also_run_disabled_tests. By Eric Roman. --- test/gtest_filter_unittest.py | 72 +++++++++++++++++++++++++++++++---- test/gtest_filter_unittest_.cc | 27 +++++++++++++ test/gtest_output_test.py | 11 ++++-- test/gtest_output_test_.cc | 8 ++++ test/gtest_output_test_golden_lin.txt | 37 +++++++++++++++++- test/gtest_output_test_golden_win.txt | 31 +++++++++++++++ test/gtest_unittest.cc | 67 +++++++++++++++++++++++++++++++- 7 files changed, 241 insertions(+), 12 deletions(-) (limited to 'test') diff --git a/test/gtest_filter_unittest.py b/test/gtest_filter_unittest.py index b7dc2ed8..35307a26 100755 --- a/test/gtest_filter_unittest.py +++ b/test/gtest_filter_unittest.py @@ -40,12 +40,11 @@ environments and command line flags. __author__ = 'wan@google.com (Zhanyong Wan)' -import gtest_test_utils import os import re import sets -import sys import unittest +import gtest_test_utils # Constants. @@ -55,6 +54,9 @@ FILTER_ENV_VAR = 'GTEST_FILTER' # The command line flag for specifying the test filters. FILTER_FLAG = 'gtest_filter' +# The command line flag for including disabled tests. +ALSO_RUN_DISABED_TESTS_FLAG = 'gtest_also_run_disabled_tests' + # Command to run the gtest_filter_unittest_ program. COMMAND = os.path.join(gtest_test_utils.GetBuildDir(), 'gtest_filter_unittest_') @@ -80,7 +82,17 @@ PARAM_TESTS = [ 'SeqQ/ParamTest.TestY/1', ] -ALL_TESTS = [ +DISABLED_TESTS = [ + 'BarTest.DISABLED_TestFour', + 'BarTest.DISABLED_TestFive', + 'BazTest.DISABLED_TestC', + 'DISABLED_FoobarTest.Test1', + 'DISABLED_FoobarTest.DISABLED_Test2', + 'DISABLED_FoobarbazTest.TestA', + ] + +# All the non-disabled tests. +ACTIVE_TESTS = [ 'FooTest.Abc', 'FooTest.Xyz', @@ -176,6 +188,18 @@ class GTestFilterUnitTest(unittest.TestCase): tests_run = Run(command) self.AssertSetEqual(tests_run, tests_to_run) + def RunAndVerifyAllowingDisabled(self, gtest_filter, tests_to_run): + """Runs gtest_flag_unittest_ with the given filter, and enables + disabled tests. Verifies that the right set of tests were run. + """ + # Construct the command line. + command = '%s --%s' % (COMMAND, ALSO_RUN_DISABED_TESTS_FLAG) + if gtest_filter is not None: + command = '%s --%s=%s' % (command, FILTER_FLAG, gtest_filter) + + tests_run = Run(command) + self.AssertSetEqual(tests_run, tests_to_run) + def setUp(self): """Sets up test case. Determines whether value-parameterized tests are enabled in the binary and sets flags accordingly. @@ -188,7 +212,7 @@ class GTestFilterUnitTest(unittest.TestCase): def testDefaultBehavior(self): """Tests the behavior of not specifying the filter.""" - self.RunAndVerify(None, ALL_TESTS) + self.RunAndVerify(None, ACTIVE_TESTS) def testEmptyFilter(self): """Tests an empty filter.""" @@ -199,28 +223,62 @@ class GTestFilterUnitTest(unittest.TestCase): """Tests a filter that matches nothing.""" self.RunAndVerify('BadFilter', []) + self.RunAndVerifyAllowingDisabled('BadFilter', []) def testFullName(self): """Tests filtering by full name.""" self.RunAndVerify('FooTest.Xyz', ['FooTest.Xyz']) + self.RunAndVerifyAllowingDisabled('FooTest.Xyz', ['FooTest.Xyz']) def testUniversalFilters(self): """Tests filters that match everything.""" - self.RunAndVerify('*', ALL_TESTS) - self.RunAndVerify('*.*', ALL_TESTS) + self.RunAndVerify('*', ACTIVE_TESTS) + self.RunAndVerify('*.*', ACTIVE_TESTS) + self.RunAndVerifyAllowingDisabled('*', ACTIVE_TESTS + DISABLED_TESTS) + self.RunAndVerifyAllowingDisabled('*.*', ACTIVE_TESTS + DISABLED_TESTS) def testFilterByTestCase(self): """Tests filtering by test case name.""" self.RunAndVerify('FooTest.*', ['FooTest.Abc', 'FooTest.Xyz']) + BAZ_TESTS = ['BazTest.TestOne', 'BazTest.TestA', 'BazTest.TestB'] + self.RunAndVerify('BazTest.*', BAZ_TESTS) + self.RunAndVerifyAllowingDisabled('BazTest.*', + BAZ_TESTS + ['BazTest.DISABLED_TestC']) + def testFilterByTest(self): """Tests filtering by test name.""" self.RunAndVerify('*.TestOne', ['BarTest.TestOne', 'BazTest.TestOne']) + def testFilterDisabledTests(self): + """Select only the disabled tests to run.""" + + self.RunAndVerify('DISABLED_FoobarTest.Test1', []) + self.RunAndVerifyAllowingDisabled('DISABLED_FoobarTest.Test1', + ['DISABLED_FoobarTest.Test1']) + + self.RunAndVerify('*DISABLED_*', []) + self.RunAndVerifyAllowingDisabled('*DISABLED_*', DISABLED_TESTS) + + self.RunAndVerify('*.DISABLED_*', []) + self.RunAndVerifyAllowingDisabled('*.DISABLED_*', [ + 'BarTest.DISABLED_TestFour', + 'BarTest.DISABLED_TestFive', + 'BazTest.DISABLED_TestC', + 'DISABLED_FoobarTest.DISABLED_Test2', + ]) + + self.RunAndVerify('DISABLED_*', []) + self.RunAndVerifyAllowingDisabled('DISABLED_*', [ + 'DISABLED_FoobarTest.Test1', + 'DISABLED_FoobarTest.DISABLED_Test2', + 'DISABLED_FoobarbazTest.TestA', + ]) + def testWildcardInTestCaseName(self): """Tests using wildcard in the test case name.""" @@ -231,7 +289,7 @@ class GTestFilterUnitTest(unittest.TestCase): 'BazTest.TestOne', 'BazTest.TestA', - 'BazTest.TestB',] + PARAM_TESTS) + 'BazTest.TestB' ] + PARAM_TESTS) def testWildcardInTestName(self): """Tests using wildcard in the test name.""" diff --git a/test/gtest_filter_unittest_.cc b/test/gtest_filter_unittest_.cc index c554ad00..99610796 100644 --- a/test/gtest_filter_unittest_.cc +++ b/test/gtest_filter_unittest_.cc @@ -67,6 +67,13 @@ TEST(BarTest, TestTwo) { TEST(BarTest, TestThree) { } +TEST(BarTest, DISABLED_TestFour) { + FAIL() << "Expected failure."; +} + +TEST(BarTest, DISABLED_TestFive) { + FAIL() << "Expected failure."; +} // Test case BazTest. @@ -80,6 +87,26 @@ TEST(BazTest, TestA) { TEST(BazTest, TestB) { } +TEST(BazTest, DISABLED_TestC) { + FAIL() << "Expected failure."; +} + +// Test case FoobarTest + +TEST(DISABLED_FoobarTest, Test1) { + FAIL() << "Expected failure."; +} + +TEST(DISABLED_FoobarTest, DISABLED_Test2) { + FAIL() << "Expected failure."; +} + +// Test case FoobarbazTest + +TEST(DISABLED_FoobarbazTest, TestA) { + FAIL() << "Expected failure."; +} + #ifdef GTEST_HAS_PARAM_TEST class ParamTest : public testing::TestWithParam { }; diff --git a/test/gtest_output_test.py b/test/gtest_output_test.py index 68cfe5ec..42cf00c4 100755 --- a/test/gtest_output_test.py +++ b/test/gtest_output_test.py @@ -40,12 +40,12 @@ SYNOPSIS __author__ = 'wan@google.com (Zhanyong Wan)' -import gtest_test_utils import os import re import string import sys import unittest +import gtest_test_utils # The flag for generating the golden file @@ -64,10 +64,13 @@ PROGRAM_PATH = os.path.join(gtest_test_utils.GetBuildDir(), PROGRAM) COMMAND_WITH_COLOR = PROGRAM_PATH + ' --gtest_color=yes' COMMAND_WITH_TIME = (PROGRAM_PATH + ' --gtest_print_time ' + '--gtest_filter="FatalFailureTest.*:LoggingTest.*"') +COMMAND_WITH_DISABLED = (PROGRAM_PATH + ' --gtest_also_run_disabled_tests ' + + '--gtest_filter="*DISABLED_*"') GOLDEN_PATH = os.path.join(gtest_test_utils.GetSourceDir(), GOLDEN_NAME) + def ToUnixLineEnding(s): """Changes all Windows/Mac line endings in s to UNIX line endings.""" @@ -191,7 +194,8 @@ def GetCommandOutput(cmd): class GTestOutputTest(unittest.TestCase): def testOutput(self): output = (GetCommandOutput(COMMAND_WITH_COLOR) + - GetCommandOutput(COMMAND_WITH_TIME)) + GetCommandOutput(COMMAND_WITH_TIME) + + GetCommandOutput(COMMAND_WITH_DISABLED)) golden_file = open(GOLDEN_PATH, 'rb') golden = golden_file.read() golden_file.close() @@ -206,7 +210,8 @@ class GTestOutputTest(unittest.TestCase): if __name__ == '__main__': if sys.argv[1:] == [GENGOLDEN_FLAG]: output = (GetCommandOutput(COMMAND_WITH_COLOR) + - GetCommandOutput(COMMAND_WITH_TIME)) + GetCommandOutput(COMMAND_WITH_TIME) + + GetCommandOutput(COMMAND_WITH_DISABLED)) golden_file = open(GOLDEN_PATH, 'wb') golden_file.write(output) golden_file.close() diff --git a/test/gtest_output_test_.cc b/test/gtest_output_test_.cc index 203374ec..31a0672f 100644 --- a/test/gtest_output_test_.cc +++ b/test/gtest_output_test_.cc @@ -212,6 +212,14 @@ TEST(SCOPED_TRACETest, CanBeRepeated) { << "trace point A, B, and D."; } +TEST(DisabledTestsWarningTest, + DISABLED_AlsoRunDisabledTestsFlagSuppressesWarning) { + // This test body is intentionally empty. Its sole purpose is for + // verifying that the --gtest_also_run_disabled_tests flag + // suppresses the "YOU HAVE 12 DISABLED TESTS" warning at the end of + // the test output. +} + // Tests using assertions outside of TEST and TEST_F. // // This function creates two failures intentionally. diff --git a/test/gtest_output_test_golden_lin.txt b/test/gtest_output_test_golden_lin.txt index fb932fa0..0a7efca9 100644 --- a/test/gtest_output_test_golden_lin.txt +++ b/test/gtest_output_test_golden_lin.txt @@ -534,7 +534,9 @@ Expected fatal failure. [ FAILED ] ExpectFailureTest.ExpectNonFatalFailureOnAllThreads 33 FAILED TESTS -The non-test part of the code is expected to have 2 failures. + YOU HAVE 1 DISABLED TEST + +The non-test part of the code is expected to have 2 failures. gtest_output_test_.cc:#: Failure Value of: false @@ -604,3 +606,36 @@ Expected fatal failure. [ FAILED ] LoggingTest.InterleavingLoggingAndAssertions 4 FAILED TESTS + YOU HAVE 1 DISABLED TEST + +The non-test part of the code is expected to have 2 failures. + +gtest_output_test_.cc:#: Failure +Value of: false + Actual: false +Expected: true +gtest_output_test_.cc:#: Failure +Value of: 3 +Expected: 2 +Note: Google Test filter = *DISABLED_* +[==========] Running 1 test from 1 test case. +[----------] Global test environment set-up. +FooEnvironment::SetUp() called. +BarEnvironment::SetUp() called. +[----------] 1 test from DisabledTestsWarningTest +[ RUN ] DisabledTestsWarningTest.DISABLED_AlsoRunDisabledTestsFlagSuppressesWarning +[ OK ] DisabledTestsWarningTest.DISABLED_AlsoRunDisabledTestsFlagSuppressesWarning +[----------] Global test environment tear-down +BarEnvironment::TearDown() called. +gtest_output_test_.cc:#: Failure +Failed +Expected non-fatal failure. +FooEnvironment::TearDown() called. +gtest_output_test_.cc:#: Failure +Failed +Expected fatal failure. +[==========] 1 test from 1 test case ran. +[ PASSED ] 1 test. +[ FAILED ] 0 tests, listed below: + + 0 FAILED TESTS diff --git a/test/gtest_output_test_golden_win.txt b/test/gtest_output_test_golden_win.txt index 579b10bb..6fe87610 100644 --- a/test/gtest_output_test_golden_win.txt +++ b/test/gtest_output_test_golden_win.txt @@ -481,6 +481,8 @@ Expected fatal failure. [ FAILED ] ExpectFailureTest.ExpectNonFatalFailureOnAllThreads 36 FAILED TESTS + YOU HAVE 1 DISABLED TEST + The non-test part of the code is expected to have 2 failures. gtest_output_test_.cc:#: error: Value of: false @@ -542,3 +544,32 @@ Expected fatal failure. [ FAILED ] LoggingTest.InterleavingLoggingAndAssertions 4 FAILED TESTS + YOU HAVE 1 DISABLED TEST + +The non-test part of the code is expected to have 2 failures. + +gtest_output_test_.cc:#: error: Value of: false + Actual: false +Expected: true +gtest_output_test_.cc:#: error: Value of: 3 +Expected: 2 +Note: Google Test filter = *DISABLED_* +[==========] Running 1 test from 1 test case. +[----------] Global test environment set-up. +FooEnvironment::SetUp() called. +BarEnvironment::SetUp() called. +[----------] 1 test from DisabledTestsWarningTest +[ RUN ] DisabledTestsWarningTest.DISABLED_AlsoRunDisabledTestsFlagSuppressesWarning +[ OK ] DisabledTestsWarningTest.DISABLED_AlsoRunDisabledTestsFlagSuppressesWarning +[----------] Global test environment tear-down +BarEnvironment::TearDown() called. +gtest_output_test_.cc:#: error: Failed +Expected non-fatal failure. +FooEnvironment::TearDown() called. +gtest_output_test_.cc:#: error: Failed +Expected fatal failure. +[==========] 1 test from 1 test case ran. +[ PASSED ] 1 test. +[ FAILED ] 0 tests, listed below: + + 0 FAILED TESTS diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index 2794f7ec..135493f6 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -84,6 +84,7 @@ using testing::AssertionResult; using testing::AssertionSuccess; using testing::DoubleLE; using testing::FloatLE; +using testing::GTEST_FLAG(also_run_disabled_tests); using testing::GTEST_FLAG(break_on_failure); using testing::GTEST_FLAG(catch_exceptions); using testing::GTEST_FLAG(death_test_use_fork); @@ -1128,6 +1129,7 @@ class GTestFlagSaverTest : public Test { static void SetUpTestCase() { saver_ = new GTestFlagSaver; + GTEST_FLAG(also_run_disabled_tests) = false; GTEST_FLAG(break_on_failure) = false; GTEST_FLAG(catch_exceptions) = false; GTEST_FLAG(death_test_use_fork) = false; @@ -1149,6 +1151,7 @@ class GTestFlagSaverTest : public Test { // Verifies that the Google Test flags have their default values, and then // modifies each of them. void VerifyAndModifyFlags() { + EXPECT_FALSE(GTEST_FLAG(also_run_disabled_tests)); EXPECT_FALSE(GTEST_FLAG(break_on_failure)); EXPECT_FALSE(GTEST_FLAG(catch_exceptions)); EXPECT_STREQ("auto", GTEST_FLAG(color).c_str()); @@ -1159,6 +1162,7 @@ class GTestFlagSaverTest : public Test { EXPECT_FALSE(GTEST_FLAG(print_time)); EXPECT_EQ(1, GTEST_FLAG(repeat)); + GTEST_FLAG(also_run_disabled_tests) = true; GTEST_FLAG(break_on_failure) = true; GTEST_FLAG(catch_exceptions) = true; GTEST_FLAG(color) = "no"; @@ -4067,7 +4071,8 @@ TEST_F(SetUpTestCaseTest, Test2) { // The Flags struct stores a copy of all Google Test flags. struct Flags { // Constructs a Flags struct where each flag has its default value. - Flags() : break_on_failure(false), + Flags() : also_run_disabled_tests(false), + break_on_failure(false), catch_exceptions(false), death_test_use_fork(false), filter(""), @@ -4078,6 +4083,14 @@ struct Flags { // Factory methods. + // Creates a Flags struct where the gtest_also_run_disabled_tests flag has + // the given value. + static Flags AlsoRunDisabledTests(bool also_run_disabled_tests) { + Flags flags; + flags.also_run_disabled_tests = also_run_disabled_tests; + return flags; + } + // Creates a Flags struct where the gtest_break_on_failure flag has // the given value. static Flags BreakOnFailure(bool break_on_failure) { @@ -4143,6 +4156,7 @@ struct Flags { } // These fields store the flag values. + bool also_run_disabled_tests; bool break_on_failure; bool catch_exceptions; bool death_test_use_fork; @@ -4158,6 +4172,7 @@ class InitGoogleTestTest : public Test { protected: // Clears the flags before each test. virtual void SetUp() { + GTEST_FLAG(also_run_disabled_tests) = false; GTEST_FLAG(break_on_failure) = false; GTEST_FLAG(catch_exceptions) = false; GTEST_FLAG(death_test_use_fork) = false; @@ -4181,6 +4196,8 @@ class InitGoogleTestTest : public Test { // Verifies that the flag values match the expected values. static void CheckFlags(const Flags& expected) { + EXPECT_EQ(expected.also_run_disabled_tests, + GTEST_FLAG(also_run_disabled_tests)); EXPECT_EQ(expected.break_on_failure, GTEST_FLAG(break_on_failure)); EXPECT_EQ(expected.catch_exceptions, GTEST_FLAG(catch_exceptions)); EXPECT_EQ(expected.death_test_use_fork, GTEST_FLAG(death_test_use_fork)); @@ -4687,6 +4704,54 @@ TEST_F(InitGoogleTestTest, Repeat) { TEST_PARSING_FLAGS(argv, argv2, Flags::Repeat(1000)); } +// Tests having a --gtest_also_run_disabled_tests flag +TEST_F(InitGoogleTestTest, AlsoRunDisabledTestsFlag) { + const char* argv[] = { + "foo.exe", + "--gtest_also_run_disabled_tests", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + TEST_PARSING_FLAGS(argv, argv2, Flags::AlsoRunDisabledTests(true)); +} + +// Tests having a --gtest_also_run_disabled_tests flag with a "true" value +TEST_F(InitGoogleTestTest, AlsoRunDisabledTestsTrue) { + const char* argv[] = { + "foo.exe", + "--gtest_also_run_disabled_tests=1", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + TEST_PARSING_FLAGS(argv, argv2, Flags::AlsoRunDisabledTests(true)); +} + +// Tests having a --gtest_also_run_disabled_tests flag with a "false" value +TEST_F(InitGoogleTestTest, AlsoRunDisabledTestsFalse) { + const char* argv[] = { + "foo.exe", + "--gtest_also_run_disabled_tests=0", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + TEST_PARSING_FLAGS(argv, argv2, Flags::AlsoRunDisabledTests(false)); +} + #ifdef GTEST_OS_WINDOWS // Tests parsing wide strings. TEST_F(InitGoogleTestTest, WideStrings) { -- cgit v1.2.3 From 650d5bf3ba200ecbeccbfcec6e7b6cc6f40a1f60 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Mon, 26 Jan 2009 19:21:32 +0000 Subject: Fixes the bug where the XML output path is affected by test changing the current directory. By Stefan Weigand. --- test/gtest-filepath_test.cc | 84 +++++++++++++++++++++-- test/gtest-options_test.cc | 163 +++++++++++++++++++++++++++++++++++++++----- 2 files changed, 224 insertions(+), 23 deletions(-) (limited to 'test') diff --git a/test/gtest-filepath_test.cc b/test/gtest-filepath_test.cc index d87c7c8c..589442fe 100644 --- a/test/gtest-filepath_test.cc +++ b/test/gtest-filepath_test.cc @@ -52,9 +52,9 @@ #ifdef GTEST_OS_WINDOWS #ifdef _WIN32_WCE -#include +#include // NOLINT #else -#include +#include // NOLINT #endif // _WIN32_WCE #define PATH_SEP "\\" #else @@ -217,6 +217,65 @@ TEST(MakeFileNameTest, GenerateFileNameWithSlashNumberGtZero) { EXPECT_STREQ("foo" PATH_SEP "bar_12.xml", actual.c_str()); } +TEST(MakeFileNameTest, GenerateWhenNumberIsZeroAndDirIsEmpty) { + FilePath actual = FilePath::MakeFileName(FilePath(""), FilePath("bar"), + 0, "xml"); + EXPECT_STREQ("bar.xml", actual.c_str()); +} + +TEST(MakeFileNameTest, GenerateWhenNumberIsNotZeroAndDirIsEmpty) { + FilePath actual = FilePath::MakeFileName(FilePath(""), FilePath("bar"), + 14, "xml"); + EXPECT_STREQ("bar_14.xml", actual.c_str()); +} + +TEST(ConcatPathsTest, WorksWhenDirDoesNotEndWithPathSep) { + FilePath actual = FilePath::ConcatPaths(FilePath("foo"), + FilePath("bar.xml")); + EXPECT_STREQ("foo" PATH_SEP "bar.xml", actual.c_str()); +} + +TEST(ConcatPathsTest, WorksWhenPath1EndsWithPathSep) { + FilePath actual = FilePath::ConcatPaths(FilePath("foo" PATH_SEP), + FilePath("bar.xml")); + EXPECT_STREQ("foo" PATH_SEP "bar.xml", actual.c_str()); +} + +TEST(ConcatPathsTest, Path1BeingEmpty) { + FilePath actual = FilePath::ConcatPaths(FilePath(""), + FilePath("bar.xml")); + EXPECT_STREQ("bar.xml", actual.c_str()); +} + +TEST(ConcatPathsTest, Path2BeingEmpty) { + FilePath actual = FilePath::ConcatPaths(FilePath("foo"), + FilePath("")); + EXPECT_STREQ("foo" PATH_SEP, actual.c_str()); +} + +TEST(ConcatPathsTest, BothPathBeingEmpty) { + FilePath actual = FilePath::ConcatPaths(FilePath(""), + FilePath("")); + EXPECT_STREQ("", actual.c_str()); +} + +TEST(ConcatPathsTest, Path1ContainsPathSep) { + FilePath actual = FilePath::ConcatPaths(FilePath("foo" PATH_SEP "bar"), + FilePath("foobar.xml")); + EXPECT_STREQ("foo" PATH_SEP "bar" PATH_SEP "foobar.xml", actual.c_str()); +} + +TEST(ConcatPathsTest, Path2ContainsPathSep) { + FilePath actual = FilePath::ConcatPaths(FilePath("foo" PATH_SEP), + FilePath("bar" PATH_SEP "bar.xml")); + EXPECT_STREQ("foo" PATH_SEP "bar" PATH_SEP "bar.xml", actual.c_str()); +} + +TEST(ConcatPathsTest, Path2EndsWithPathSep) { + FilePath actual = FilePath::ConcatPaths(FilePath("foo"), + FilePath("bar" PATH_SEP)); + EXPECT_STREQ("foo" PATH_SEP "bar" PATH_SEP, actual.c_str()); +} // RemoveTrailingPathSeparator "" -> "" TEST(RemoveTrailingPathSeparatorTest, EmptyString) { @@ -251,7 +310,7 @@ TEST(RemoveTrailingPathSeparatorTest, ShouldReturnUnmodified) { TEST(DirectoryTest, RootDirectoryExists) { #ifdef GTEST_OS_WINDOWS // We are on Windows. - char current_drive[_MAX_PATH]; + char current_drive[_MAX_PATH]; // NOLINT current_drive[0] = _getdrive() + 'A' - 1; current_drive[1] = ':'; current_drive[2] = '\\'; @@ -268,7 +327,7 @@ TEST(DirectoryTest, RootOfWrongDriveDoesNotExists) { // Find a drive that doesn't exist. Start with 'Z' to avoid common ones. for (char drive = 'Z'; drive >= 'A'; drive--) if (_chdrive(drive - 'A' + 1) == -1) { - char non_drive[_MAX_PATH]; + char non_drive[_MAX_PATH]; // NOLINT non_drive[0] = drive; non_drive[1] = ':'; non_drive[2] = '\\'; @@ -278,14 +337,14 @@ TEST(DirectoryTest, RootOfWrongDriveDoesNotExists) { } _chdrive(saved_drive_); } -#endif // GTEST_OS_WINDOWS +#endif // GTEST_OS_WINDOWS #ifndef _WIN32_WCE // Windows CE _does_ consider an empty directory to exist. TEST(DirectoryTest, EmptyPathDirectoryDoesNotExist) { EXPECT_FALSE(FilePath("").DirectoryExists()); } -#endif // ! _WIN32_WCE +#endif // ! _WIN32_WCE TEST(DirectoryTest, CurrentDirectoryExists) { #ifdef GTEST_OS_WINDOWS // We are on Windows. @@ -529,6 +588,19 @@ TEST(FilePathTest, IsDirectory) { EXPECT_TRUE(FilePath("koala" PATH_SEP).IsDirectory()); } +TEST(FilePathTest, IsAbsolutePath) { + EXPECT_FALSE(FilePath("is" PATH_SEP "relative").IsAbsolutePath()); + EXPECT_FALSE(FilePath("").IsAbsolutePath()); +#ifdef GTEST_OS_WINDOWS + EXPECT_TRUE(FilePath("c:\\" PATH_SEP "is_not" PATH_SEP "relative") + .IsAbsolutePath()); + EXPECT_FALSE(FilePath("c:foo" PATH_SEP "bar").IsAbsolutePath()); +#else + EXPECT_TRUE(FilePath(PATH_SEP "is_not" PATH_SEP "relative") + .IsAbsolutePath()); +#endif // GTEST_OS_WINDOWS +} + } // namespace } // namespace internal } // namespace testing diff --git a/test/gtest-options_test.cc b/test/gtest-options_test.cc index 93f49e20..e3e7bd79 100644 --- a/test/gtest-options_test.cc +++ b/test/gtest-options_test.cc @@ -40,6 +40,12 @@ #include +#ifdef _WIN32_WCE +#include +#elif defined(GTEST_OS_WINDOWS) +#include +#endif // _WIN32_WCE + // Indicates that this translation unit is part of Google Test's // implementation. It must come before gtest-internal-inl.h is // included, or there will be a compiler error. This trick is to @@ -50,10 +56,14 @@ #undef GTEST_IMPLEMENTATION namespace testing { - namespace internal { namespace { +// Turns the given relative path into an absolute path. +FilePath GetAbsolutePathOf(const FilePath& relative_path) { + return FilePath::ConcatPaths(FilePath::GetCurrentDir(), relative_path); +} + // Testing UnitTestOptions::GetOutputFormat/GetOutputFile. TEST(XmlOutputTest, GetOutputFormatDefault) { @@ -68,36 +78,43 @@ TEST(XmlOutputTest, GetOutputFormat) { TEST(XmlOutputTest, GetOutputFileDefault) { GTEST_FLAG(output) = ""; - EXPECT_STREQ("test_detail.xml", - UnitTestOptions::GetOutputFile().c_str()); + EXPECT_STREQ(GetAbsolutePathOf(FilePath("test_detail.xml")).c_str(), + UnitTestOptions::GetAbsolutePathToOutputFile().c_str()); } TEST(XmlOutputTest, GetOutputFileSingleFile) { GTEST_FLAG(output) = "xml:filename.abc"; - EXPECT_STREQ("filename.abc", - UnitTestOptions::GetOutputFile().c_str()); + EXPECT_STREQ(GetAbsolutePathOf(FilePath("filename.abc")).c_str(), + UnitTestOptions::GetAbsolutePathToOutputFile().c_str()); } TEST(XmlOutputTest, GetOutputFileFromDirectoryPath) { #ifdef GTEST_OS_WINDOWS - GTEST_FLAG(output) = "xml:pathname\\"; - const String& output_file = UnitTestOptions::GetOutputFile(); - EXPECT_TRUE(_strcmpi(output_file.c_str(), - "pathname\\gtest-options_test.xml") == 0 || - _strcmpi(output_file.c_str(), - "pathname\\gtest-options-ex_test.xml") == 0) - << " output_file = " << output_file; + GTEST_FLAG(output) = "xml:path\\"; + const String& output_file = UnitTestOptions::GetAbsolutePathToOutputFile(); + EXPECT_TRUE( + _strcmpi(output_file.c_str(), + GetAbsolutePathOf( + FilePath("path\\gtest-options_test.xml")).c_str()) == 0 || + _strcmpi(output_file.c_str(), + GetAbsolutePathOf( + FilePath("path\\gtest-options-ex_test.xml")).c_str()) == 0) + << " output_file = " << output_file; #else - GTEST_FLAG(output) = "xml:pathname/"; - const String& output_file = UnitTestOptions::GetOutputFile(); + GTEST_FLAG(output) = "xml:path/"; + const String& output_file = UnitTestOptions::GetAbsolutePathToOutputFile(); // TODO(wan@google.com): libtool causes the test binary file to be // named lt-gtest-options_test. Therefore the output file may be // named .../lt-gtest-options_test.xml. We should remove this // hard-coded logic when Chandler Carruth's libtool replacement is // ready. - EXPECT_TRUE(output_file == "pathname/gtest-options_test.xml" || - output_file == "pathname/lt-gtest-options_test.xml") - << " output_file = " << output_file; + EXPECT_TRUE(output_file == + GetAbsolutePathOf( + FilePath("path/gtest-options_test.xml")).c_str() || + output_file == + GetAbsolutePathOf( + FilePath("path/lt-gtest-options_test.xml")).c_str()) + << " output_file = " << output_file; #endif } @@ -117,6 +134,118 @@ TEST(OutputFileHelpersTest, GetCurrentExecutableName) { #endif } +class XmlOutputChangeDirTest : public Test { + protected: + virtual void SetUp() { + original_working_dir_ = FilePath::GetCurrentDir(); + ChDir(".."); + // This will make the test fail if run from the root directory. + EXPECT_STRNE(original_working_dir_.c_str(), + FilePath::GetCurrentDir().c_str()); + } + + virtual void TearDown() { + ChDir(original_working_dir_.c_str()); + } + + void ChDir(const char* dir) { +#ifdef GTEST_OS_WINDOWS + _chdir(dir); +#else + chdir(dir); +#endif + } + + FilePath original_working_dir_; +}; + +TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithDefault) { + GTEST_FLAG(output) = ""; + EXPECT_STREQ(FilePath::ConcatPaths(original_working_dir_, + FilePath("test_detail.xml")).c_str(), + UnitTestOptions::GetAbsolutePathToOutputFile().c_str()); +} + +TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithDefaultXML) { + GTEST_FLAG(output) = "xml"; + EXPECT_STREQ(FilePath::ConcatPaths(original_working_dir_, + FilePath("test_detail.xml")).c_str(), + UnitTestOptions::GetAbsolutePathToOutputFile().c_str()); +} + +TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithRelativeFile) { + GTEST_FLAG(output) = "xml:filename.abc"; + EXPECT_STREQ(FilePath::ConcatPaths(original_working_dir_, + FilePath("filename.abc")).c_str(), + UnitTestOptions::GetAbsolutePathToOutputFile().c_str()); +} + +TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithRelativePath) { +#ifdef GTEST_OS_WINDOWS + GTEST_FLAG(output) = "xml:path\\"; + const String& output_file = UnitTestOptions::GetAbsolutePathToOutputFile(); + EXPECT_TRUE( + _strcmpi(output_file.c_str(), + FilePath::ConcatPaths( + original_working_dir_, + FilePath("path\\gtest-options_test.xml")).c_str()) == 0 || + _strcmpi(output_file.c_str(), + FilePath::ConcatPaths( + original_working_dir_, + FilePath("path\\gtest-options-ex_test.xml")).c_str()) == 0) + << " output_file = " << output_file; +#else + GTEST_FLAG(output) = "xml:path/"; + const String& output_file = UnitTestOptions::GetAbsolutePathToOutputFile(); + // TODO(wan@google.com): libtool causes the test binary file to be + // named lt-gtest-options_test. Therefore the output file may be + // named .../lt-gtest-options_test.xml. We should remove this + // hard-coded logic when Chandler Carruth's libtool replacement is + // ready. + EXPECT_TRUE(output_file == FilePath::ConcatPaths(original_working_dir_, + FilePath("path/gtest-options_test.xml")).c_str() || + output_file == FilePath::ConcatPaths(original_working_dir_, + FilePath("path/lt-gtest-options_test.xml")).c_str()) + << " output_file = " << output_file; +#endif +} + +TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithAbsoluteFile) { +#ifdef GTEST_OS_WINDOWS + GTEST_FLAG(output) = "xml:c:\\tmp\\filename.abc"; + EXPECT_STREQ(FilePath("c:\\tmp\\filename.abc").c_str(), + UnitTestOptions::GetAbsolutePathToOutputFile().c_str()); +#else + GTEST_FLAG(output) ="xml:/tmp/filename.abc"; + EXPECT_STREQ(FilePath("/tmp/filename.abc").c_str(), + UnitTestOptions::GetAbsolutePathToOutputFile().c_str()); +#endif +} + +TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithAbsolutePath) { +#ifdef GTEST_OS_WINDOWS + GTEST_FLAG(output) = "xml:c:\\tmp\\"; + const String& output_file = UnitTestOptions::GetAbsolutePathToOutputFile(); + EXPECT_TRUE( + _strcmpi(output_file.c_str(), + FilePath("c:\\tmp\\gtest-options_test.xml").c_str()) == 0 || + _strcmpi(output_file.c_str(), + FilePath("c:\\tmp\\gtest-options-ex_test.xml").c_str()) == 0) + << " output_file = " << output_file; +#else + GTEST_FLAG(output) = "xml:/tmp/"; + const String& output_file = UnitTestOptions::GetAbsolutePathToOutputFile(); + // TODO(wan@google.com): libtool causes the test binary file to be + // named lt-gtest-options_test. Therefore the output file may be + // named .../lt-gtest-options_test.xml. We should remove this + // hard-coded logic when Chandler Carruth's libtool replacement is + // ready. + EXPECT_TRUE(output_file == "/tmp/gtest-options_test.xml" || + output_file == "/tmp/lt-gtest-options_test.xml") + << " output_file = " << output_file; +#endif +} + } // namespace } // namespace internal } // namespace testing -- cgit v1.2.3 From c946ae60194727ede9d3ef44754839f48541a981 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Thu, 29 Jan 2009 01:28:52 +0000 Subject: Implements a simple regex matcher (to be used by death tests on Windows). --- test/gtest-port_test.cc | 501 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 489 insertions(+), 12 deletions(-) (limited to 'test') diff --git a/test/gtest-port_test.cc b/test/gtest-port_test.cc index d945c589..0041c911 100644 --- a/test/gtest-port_test.cc +++ b/test/gtest-port_test.cc @@ -27,7 +27,7 @@ // (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: vladl@google.com (Vlad Losev) +// Authors: vladl@google.com (Vlad Losev), wan@google.com (Zhanyong Wan) // // This file tests the internal cross-platform support utilities. @@ -35,6 +35,18 @@ #include #include +// Indicates that this translation unit is part of Google Test's +// implementation. It must come before gtest-internal-inl.h is +// included, or there will be a compiler error. This trick is to +// prevent a user from accidentally including gtest-internal-inl.h in +// his code. +#define GTEST_IMPLEMENTATION +#include "src/gtest-internal-inl.h" +#undef GTEST_IMPLEMENTATION + +namespace testing { +namespace internal { + TEST(GtestCheckSyntaxTest, BehavesLikeASingleStatement) { if (false) GTEST_CHECK_(false) << "This should never be executed; " @@ -87,9 +99,7 @@ TEST(GtestCheckDeathTest, LivesSilentlyOnSuccess) { #endif // GTEST_HAS_DEATH_TEST -#ifdef GTEST_USES_POSIX_RE - -using ::testing::internal::RE; +#if GTEST_USES_POSIX_RE template class RETest : public ::testing::Test {}; @@ -109,30 +119,30 @@ TYPED_TEST_CASE(RETest, StringTypes); // Tests RE's implicit constructors. TYPED_TEST(RETest, ImplicitConstructorWorks) { - const RE empty = TypeParam(""); + const RE empty(TypeParam("")); EXPECT_STREQ("", empty.pattern()); - const RE simple = TypeParam("hello"); + const RE simple(TypeParam("hello")); EXPECT_STREQ("hello", simple.pattern()); - const RE normal = TypeParam(".*(\\w+)"); + const RE normal(TypeParam(".*(\\w+)")); EXPECT_STREQ(".*(\\w+)", normal.pattern()); } // Tests that RE's constructors reject invalid regular expressions. TYPED_TEST(RETest, RejectsInvalidRegex) { EXPECT_NONFATAL_FAILURE({ - const RE invalid = TypeParam("?"); + const RE invalid(TypeParam("?")); }, "\"?\" is not a valid POSIX Extended regular expression."); } // Tests RE::FullMatch(). TYPED_TEST(RETest, FullMatchWorks) { - const RE empty = TypeParam(""); + const RE empty(TypeParam("")); EXPECT_TRUE(RE::FullMatch(TypeParam(""), empty)); EXPECT_FALSE(RE::FullMatch(TypeParam("a"), empty)); - const RE re = TypeParam("a.*z"); + const RE re(TypeParam("a.*z")); EXPECT_TRUE(RE::FullMatch(TypeParam("az"), re)); EXPECT_TRUE(RE::FullMatch(TypeParam("axyz"), re)); EXPECT_FALSE(RE::FullMatch(TypeParam("baz"), re)); @@ -141,11 +151,11 @@ TYPED_TEST(RETest, FullMatchWorks) { // Tests RE::PartialMatch(). TYPED_TEST(RETest, PartialMatchWorks) { - const RE empty = TypeParam(""); + const RE empty(TypeParam("")); EXPECT_TRUE(RE::PartialMatch(TypeParam(""), empty)); EXPECT_TRUE(RE::PartialMatch(TypeParam("a"), empty)); - const RE re = TypeParam("a.*z"); + const RE re(TypeParam("a.*z")); EXPECT_TRUE(RE::PartialMatch(TypeParam("az"), re)); EXPECT_TRUE(RE::PartialMatch(TypeParam("axyz"), re)); EXPECT_TRUE(RE::PartialMatch(TypeParam("baz"), re)); @@ -153,4 +163,471 @@ TYPED_TEST(RETest, PartialMatchWorks) { EXPECT_FALSE(RE::PartialMatch(TypeParam("zza"), re)); } +#elif GTEST_USES_SIMPLE_RE + +TEST(IsInSetTest, NulCharIsNotInAnySet) { + EXPECT_FALSE(IsInSet('\0', "")); + EXPECT_FALSE(IsInSet('\0', "\0")); + EXPECT_FALSE(IsInSet('\0', "a")); +} + +TEST(IsInSetTest, WorksForNonNulChars) { + EXPECT_FALSE(IsInSet('a', "Ab")); + EXPECT_FALSE(IsInSet('c', "")); + + EXPECT_TRUE(IsInSet('b', "bcd")); + EXPECT_TRUE(IsInSet('b', "ab")); +} + +TEST(IsDigitTest, IsFalseForNonDigit) { + EXPECT_FALSE(IsDigit('\0')); + EXPECT_FALSE(IsDigit(' ')); + EXPECT_FALSE(IsDigit('+')); + EXPECT_FALSE(IsDigit('-')); + EXPECT_FALSE(IsDigit('.')); + EXPECT_FALSE(IsDigit('a')); +} + +TEST(IsDigitTest, IsTrueForDigit) { + EXPECT_TRUE(IsDigit('0')); + EXPECT_TRUE(IsDigit('1')); + EXPECT_TRUE(IsDigit('5')); + EXPECT_TRUE(IsDigit('9')); +} + +TEST(IsPunctTest, IsFalseForNonPunct) { + EXPECT_FALSE(IsPunct('\0')); + EXPECT_FALSE(IsPunct(' ')); + EXPECT_FALSE(IsPunct('\n')); + EXPECT_FALSE(IsPunct('a')); + EXPECT_FALSE(IsPunct('0')); +} + +TEST(IsPunctTest, IsTrueForPunct) { + for (const char* p = "^-!\"#$%&'()*+,./:;<=>?@[\\]_`{|}~"; *p; p++) { + EXPECT_PRED1(IsPunct, *p); + } +} + +TEST(IsRepeatTest, IsFalseForNonRepeatChar) { + EXPECT_FALSE(IsRepeat('\0')); + EXPECT_FALSE(IsRepeat(' ')); + EXPECT_FALSE(IsRepeat('a')); + EXPECT_FALSE(IsRepeat('1')); + EXPECT_FALSE(IsRepeat('-')); +} + +TEST(IsRepeatTest, IsTrueForRepeatChar) { + EXPECT_TRUE(IsRepeat('?')); + EXPECT_TRUE(IsRepeat('*')); + EXPECT_TRUE(IsRepeat('+')); +} + +TEST(IsWhiteSpaceTest, IsFalseForNonWhiteSpace) { + EXPECT_FALSE(IsWhiteSpace('\0')); + EXPECT_FALSE(IsWhiteSpace('a')); + EXPECT_FALSE(IsWhiteSpace('1')); + EXPECT_FALSE(IsWhiteSpace('+')); + EXPECT_FALSE(IsWhiteSpace('_')); +} + +TEST(IsWhiteSpaceTest, IsTrueForWhiteSpace) { + EXPECT_TRUE(IsWhiteSpace(' ')); + EXPECT_TRUE(IsWhiteSpace('\n')); + EXPECT_TRUE(IsWhiteSpace('\r')); + EXPECT_TRUE(IsWhiteSpace('\t')); + EXPECT_TRUE(IsWhiteSpace('\v')); + EXPECT_TRUE(IsWhiteSpace('\f')); +} + +TEST(IsWordCharTest, IsFalseForNonWordChar) { + EXPECT_FALSE(IsWordChar('\0')); + EXPECT_FALSE(IsWordChar('+')); + EXPECT_FALSE(IsWordChar('.')); + EXPECT_FALSE(IsWordChar(' ')); + EXPECT_FALSE(IsWordChar('\n')); +} + +TEST(IsWordCharTest, IsTrueForLetter) { + EXPECT_TRUE(IsWordChar('a')); + EXPECT_TRUE(IsWordChar('b')); + EXPECT_TRUE(IsWordChar('A')); + EXPECT_TRUE(IsWordChar('Z')); +} + +TEST(IsWordCharTest, IsTrueForDigit) { + EXPECT_TRUE(IsWordChar('0')); + EXPECT_TRUE(IsWordChar('1')); + EXPECT_TRUE(IsWordChar('7')); + EXPECT_TRUE(IsWordChar('9')); +} + +TEST(IsWordCharTest, IsTrueForUnderscore) { + EXPECT_TRUE(IsWordChar('_')); +} + +TEST(IsValidEscapeTest, IsFalseForNonPrintable) { + EXPECT_FALSE(IsValidEscape('\0')); + EXPECT_FALSE(IsValidEscape('\007')); +} + +TEST(IsValidEscapeTest, IsFalseForDigit) { + EXPECT_FALSE(IsValidEscape('0')); + EXPECT_FALSE(IsValidEscape('9')); +} + +TEST(IsValidEscapeTest, IsFalseForWhiteSpace) { + EXPECT_FALSE(IsValidEscape(' ')); + EXPECT_FALSE(IsValidEscape('\n')); +} + +TEST(IsValidEscapeTest, IsFalseForSomeLetter) { + EXPECT_FALSE(IsValidEscape('a')); + EXPECT_FALSE(IsValidEscape('Z')); +} + +TEST(IsValidEscapeTest, IsTrueForPunct) { + EXPECT_TRUE(IsValidEscape('.')); + EXPECT_TRUE(IsValidEscape('-')); + EXPECT_TRUE(IsValidEscape('^')); + EXPECT_TRUE(IsValidEscape('$')); + EXPECT_TRUE(IsValidEscape('(')); + EXPECT_TRUE(IsValidEscape(']')); + EXPECT_TRUE(IsValidEscape('{')); + EXPECT_TRUE(IsValidEscape('|')); +} + +TEST(IsValidEscapeTest, IsTrueForSomeLetter) { + EXPECT_TRUE(IsValidEscape('d')); + EXPECT_TRUE(IsValidEscape('D')); + EXPECT_TRUE(IsValidEscape('s')); + EXPECT_TRUE(IsValidEscape('S')); + EXPECT_TRUE(IsValidEscape('w')); + EXPECT_TRUE(IsValidEscape('W')); +} + +TEST(AtomMatchesCharTest, EscapedPunct) { + EXPECT_FALSE(AtomMatchesChar(true, '\\', '\0')); + EXPECT_FALSE(AtomMatchesChar(true, '\\', ' ')); + EXPECT_FALSE(AtomMatchesChar(true, '_', '.')); + EXPECT_FALSE(AtomMatchesChar(true, '.', 'a')); + + EXPECT_TRUE(AtomMatchesChar(true, '\\', '\\')); + EXPECT_TRUE(AtomMatchesChar(true, '_', '_')); + EXPECT_TRUE(AtomMatchesChar(true, '+', '+')); + EXPECT_TRUE(AtomMatchesChar(true, '.', '.')); +} + +TEST(AtomMatchesCharTest, Escaped_d) { + EXPECT_FALSE(AtomMatchesChar(true, 'd', '\0')); + EXPECT_FALSE(AtomMatchesChar(true, 'd', 'a')); + EXPECT_FALSE(AtomMatchesChar(true, 'd', '.')); + + EXPECT_TRUE(AtomMatchesChar(true, 'd', '0')); + EXPECT_TRUE(AtomMatchesChar(true, 'd', '9')); +} + +TEST(AtomMatchesCharTest, Escaped_D) { + EXPECT_FALSE(AtomMatchesChar(true, 'D', '0')); + EXPECT_FALSE(AtomMatchesChar(true, 'D', '9')); + + EXPECT_TRUE(AtomMatchesChar(true, 'D', '\0')); + EXPECT_TRUE(AtomMatchesChar(true, 'D', 'a')); + EXPECT_TRUE(AtomMatchesChar(true, 'D', '-')); +} + +TEST(AtomMatchesCharTest, Escaped_s) { + EXPECT_FALSE(AtomMatchesChar(true, 's', '\0')); + EXPECT_FALSE(AtomMatchesChar(true, 's', 'a')); + EXPECT_FALSE(AtomMatchesChar(true, 's', '.')); + EXPECT_FALSE(AtomMatchesChar(true, 's', '9')); + + EXPECT_TRUE(AtomMatchesChar(true, 's', ' ')); + EXPECT_TRUE(AtomMatchesChar(true, 's', '\n')); + EXPECT_TRUE(AtomMatchesChar(true, 's', '\t')); +} + +TEST(AtomMatchesCharTest, Escaped_S) { + EXPECT_FALSE(AtomMatchesChar(true, 'S', ' ')); + EXPECT_FALSE(AtomMatchesChar(true, 'S', '\r')); + + EXPECT_TRUE(AtomMatchesChar(true, 'S', '\0')); + EXPECT_TRUE(AtomMatchesChar(true, 'S', 'a')); + EXPECT_TRUE(AtomMatchesChar(true, 'S', '9')); +} + +TEST(AtomMatchesCharTest, Escaped_w) { + EXPECT_FALSE(AtomMatchesChar(true, 'w', '\0')); + EXPECT_FALSE(AtomMatchesChar(true, 'w', '+')); + EXPECT_FALSE(AtomMatchesChar(true, 'w', ' ')); + EXPECT_FALSE(AtomMatchesChar(true, 'w', '\n')); + + EXPECT_TRUE(AtomMatchesChar(true, 'w', '0')); + EXPECT_TRUE(AtomMatchesChar(true, 'w', 'b')); + EXPECT_TRUE(AtomMatchesChar(true, 'w', 'C')); + EXPECT_TRUE(AtomMatchesChar(true, 'w', '_')); +} + +TEST(AtomMatchesCharTest, Escaped_W) { + EXPECT_FALSE(AtomMatchesChar(true, 'W', 'A')); + EXPECT_FALSE(AtomMatchesChar(true, 'W', 'b')); + EXPECT_FALSE(AtomMatchesChar(true, 'W', '9')); + EXPECT_FALSE(AtomMatchesChar(true, 'W', '_')); + + EXPECT_TRUE(AtomMatchesChar(true, 'W', '\0')); + EXPECT_TRUE(AtomMatchesChar(true, 'W', '*')); + EXPECT_TRUE(AtomMatchesChar(true, 'W', '\n')); +} + +TEST(AtomMatchesCharTest, EscapedWhiteSpace) { + EXPECT_FALSE(AtomMatchesChar(true, 'f', '\0')); + EXPECT_FALSE(AtomMatchesChar(true, 'f', '\n')); + EXPECT_FALSE(AtomMatchesChar(true, 'n', '\0')); + EXPECT_FALSE(AtomMatchesChar(true, 'n', '\r')); + EXPECT_FALSE(AtomMatchesChar(true, 'r', '\0')); + EXPECT_FALSE(AtomMatchesChar(true, 'r', 'a')); + EXPECT_FALSE(AtomMatchesChar(true, 't', '\0')); + EXPECT_FALSE(AtomMatchesChar(true, 't', 't')); + EXPECT_FALSE(AtomMatchesChar(true, 'v', '\0')); + EXPECT_FALSE(AtomMatchesChar(true, 'v', '\f')); + + EXPECT_TRUE(AtomMatchesChar(true, 'f', '\f')); + EXPECT_TRUE(AtomMatchesChar(true, 'n', '\n')); + EXPECT_TRUE(AtomMatchesChar(true, 'r', '\r')); + EXPECT_TRUE(AtomMatchesChar(true, 't', '\t')); + EXPECT_TRUE(AtomMatchesChar(true, 'v', '\v')); +} + +TEST(AtomMatchesCharTest, UnescapedDot) { + EXPECT_FALSE(AtomMatchesChar(false, '.', '\n')); + + EXPECT_TRUE(AtomMatchesChar(false, '.', '\0')); + EXPECT_TRUE(AtomMatchesChar(false, '.', '.')); + EXPECT_TRUE(AtomMatchesChar(false, '.', 'a')); + EXPECT_TRUE(AtomMatchesChar(false, '.', ' ')); +} + +TEST(AtomMatchesCharTest, UnescapedChar) { + EXPECT_FALSE(AtomMatchesChar(false, 'a', '\0')); + EXPECT_FALSE(AtomMatchesChar(false, 'a', 'b')); + EXPECT_FALSE(AtomMatchesChar(false, '$', 'a')); + + EXPECT_TRUE(AtomMatchesChar(false, '$', '$')); + EXPECT_TRUE(AtomMatchesChar(false, '5', '5')); + EXPECT_TRUE(AtomMatchesChar(false, 'Z', 'Z')); +} + +TEST(ValidateRegexTest, GeneratesFailureAndReturnsFalseForInvalid) { + EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex(NULL)), + "NULL is not a valid simple regular expression"); + EXPECT_NONFATAL_FAILURE( + ASSERT_FALSE(ValidateRegex("a\\")), + "Syntax error at index 1 in simple regular expression \"a\\\": "); + EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("a\\")), + "'\\' cannot appear at the end"); + EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("\\n\\")), + "'\\' cannot appear at the end"); + EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("\\s\\hb")), + "invalid escape sequence \"\\h\""); + EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("^^")), + "'^' can only appear at the beginning"); + EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex(".*^b")), + "'^' can only appear at the beginning"); + EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("$$")), + "'$' can only appear at the end"); + EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("^$a")), + "'$' can only appear at the end"); + EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("a(b")), + "'(' is unsupported"); + EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("ab)")), + "')' is unsupported"); + EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("[ab")), + "'[' is unsupported"); + EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("a{2")), + "'{' is unsupported"); + EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("?")), + "'?' can only follow a repeatable token"); + EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("^*")), + "'*' can only follow a repeatable token"); + EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("5*+")), + "'+' can only follow a repeatable token"); +} + +TEST(ValidateRegexTest, ReturnsTrueForValid) { + EXPECT_TRUE(ValidateRegex("")); + EXPECT_TRUE(ValidateRegex("a")); + EXPECT_TRUE(ValidateRegex(".*")); + EXPECT_TRUE(ValidateRegex("^a_+")); + EXPECT_TRUE(ValidateRegex("^a\\t\\&?")); + EXPECT_TRUE(ValidateRegex("09*$")); + EXPECT_TRUE(ValidateRegex("^Z$")); + EXPECT_TRUE(ValidateRegex("a\\^Z\\$\\(\\)\\|\\[\\]\\{\\}")); +} + +TEST(MatchRepetitionAndRegexAtHeadTest, WorksForZeroOrOne) { + EXPECT_FALSE(MatchRepetitionAndRegexAtHead(false, 'a', '?', "a", "ba")); + // Repeating more than once. + EXPECT_FALSE(MatchRepetitionAndRegexAtHead(false, 'a', '?', "b", "aab")); + + // Repeating zero times. + EXPECT_TRUE(MatchRepetitionAndRegexAtHead(false, 'a', '?', "b", "ba")); + // Repeating once. + EXPECT_TRUE(MatchRepetitionAndRegexAtHead(false, 'a', '?', "b", "ab")); + EXPECT_TRUE(MatchRepetitionAndRegexAtHead(false, '#', '?', ".", "##")); +} + +TEST(MatchRepetitionAndRegexAtHeadTest, WorksForZeroOrMany) { + EXPECT_FALSE(MatchRepetitionAndRegexAtHead(false, '.', '*', "a$", "baab")); + + // Repeating zero times. + EXPECT_TRUE(MatchRepetitionAndRegexAtHead(false, '.', '*', "b", "bc")); + // Repeating once. + EXPECT_TRUE(MatchRepetitionAndRegexAtHead(false, '.', '*', "b", "abc")); + // Repeating more than once. + EXPECT_TRUE(MatchRepetitionAndRegexAtHead(true, 'w', '*', "-", "ab_1-g")); +} + +TEST(MatchRepetitionAndRegexAtHeadTest, WorksForOneOrMany) { + EXPECT_FALSE(MatchRepetitionAndRegexAtHead(false, '.', '+', "a$", "baab")); + // Repeating zero times. + EXPECT_FALSE(MatchRepetitionAndRegexAtHead(false, '.', '+', "b", "bc")); + + // Repeating once. + EXPECT_TRUE(MatchRepetitionAndRegexAtHead(false, '.', '+', "b", "abc")); + // Repeating more than once. + EXPECT_TRUE(MatchRepetitionAndRegexAtHead(true, 'w', '+', "-", "ab_1-g")); +} + +TEST(MatchRegexAtHeadTest, ReturnsTrueForEmptyRegex) { + EXPECT_TRUE(MatchRegexAtHead("", "")); + EXPECT_TRUE(MatchRegexAtHead("", "ab")); +} + +TEST(MatchRegexAtHeadTest, WorksWhenDollarIsInRegex) { + EXPECT_FALSE(MatchRegexAtHead("$", "a")); + + EXPECT_TRUE(MatchRegexAtHead("$", "")); + EXPECT_TRUE(MatchRegexAtHead("a$", "a")); +} + +TEST(MatchRegexAtHeadTest, WorksWhenRegexStartsWithEscapeSequence) { + EXPECT_FALSE(MatchRegexAtHead("\\w", "+")); + EXPECT_FALSE(MatchRegexAtHead("\\W", "ab")); + + EXPECT_TRUE(MatchRegexAtHead("\\sa", "\nab")); + EXPECT_TRUE(MatchRegexAtHead("\\d", "1a")); +} + +TEST(MatchRegexAtHeadTest, WorksWhenRegexStartsWithRepetition) { + EXPECT_FALSE(MatchRegexAtHead(".+a", "abc")); + EXPECT_FALSE(MatchRegexAtHead("a?b", "aab")); + + EXPECT_TRUE(MatchRegexAtHead(".*a", "bc12-ab")); + EXPECT_TRUE(MatchRegexAtHead("a?b", "b")); + EXPECT_TRUE(MatchRegexAtHead("a?b", "ab")); +} + +TEST(MatchRegexAtHeadTest, + WorksWhenRegexStartsWithRepetionOfEscapeSequence) { + EXPECT_FALSE(MatchRegexAtHead("\\.+a", "abc")); + EXPECT_FALSE(MatchRegexAtHead("\\s?b", " b")); + + EXPECT_TRUE(MatchRegexAtHead("\\(*a", "((((ab")); + EXPECT_TRUE(MatchRegexAtHead("\\^?b", "^b")); + EXPECT_TRUE(MatchRegexAtHead("\\\\?b", "b")); + EXPECT_TRUE(MatchRegexAtHead("\\\\?b", "\\b")); +} + +TEST(MatchRegexAtHeadTest, MatchesSequentially) { + EXPECT_FALSE(MatchRegexAtHead("ab.*c", "acabc")); + + EXPECT_TRUE(MatchRegexAtHead("ab.*c", "ab-fsc")); +} + +TEST(MatchRegexAnywhereTest, ReturnsFalseWhenStringIsNull) { + EXPECT_FALSE(MatchRegexAnywhere("", NULL)); +} + +TEST(MatchRegexAnywhereTest, WorksWhenRegexStartsWithCaret) { + EXPECT_FALSE(MatchRegexAnywhere("^a", "ba")); + EXPECT_FALSE(MatchRegexAnywhere("^$", "a")); + + EXPECT_TRUE(MatchRegexAnywhere("^a", "ab")); + EXPECT_TRUE(MatchRegexAnywhere("^", "ab")); + EXPECT_TRUE(MatchRegexAnywhere("^$", "")); +} + +TEST(MatchRegexAnywhereTest, ReturnsFalseWhenNoMatch) { + EXPECT_FALSE(MatchRegexAnywhere("a", "bcde123")); + EXPECT_FALSE(MatchRegexAnywhere("a.+a", "--aa88888888")); +} + +TEST(MatchRegexAnywhereTest, ReturnsTrueWhenMatchingPrefix) { + EXPECT_TRUE(MatchRegexAnywhere("\\w+", "ab1_ - 5")); + EXPECT_TRUE(MatchRegexAnywhere(".*=", "=")); + EXPECT_TRUE(MatchRegexAnywhere("x.*ab?.*bc", "xaaabc")); +} + +TEST(MatchRegexAnywhereTest, ReturnsTrueWhenMatchingNonPrefix) { + EXPECT_TRUE(MatchRegexAnywhere("\\w+", "$$$ ab1_ - 5")); + EXPECT_TRUE(MatchRegexAnywhere("\\.+=", "= ...=")); +} + +// Tests RE's implicit constructors. +TEST(RETest, ImplicitConstructorWorks) { + const RE empty = ""; + EXPECT_STREQ("", empty.pattern()); + + const RE simple = "hello"; + EXPECT_STREQ("hello", simple.pattern()); +} + +// Tests that RE's constructors reject invalid regular expressions. +TEST(RETest, RejectsInvalidRegex) { + EXPECT_NONFATAL_FAILURE({ + const RE normal = NULL; + }, "NULL is not a valid simple regular expression"); + + EXPECT_NONFATAL_FAILURE({ + const RE normal = ".*(\\w+"; + }, "'(' is unsupported"); + + EXPECT_NONFATAL_FAILURE({ + const RE invalid = "^?"; + }, "'?' can only follow a repeatable token"); +} + +// Tests RE::FullMatch(). +TEST(RETest, FullMatchWorks) { + const RE empty(""); + EXPECT_TRUE(RE::FullMatch("", empty)); + EXPECT_FALSE(RE::FullMatch("a", empty)); + + const RE re1 = "a"; + EXPECT_TRUE(RE::FullMatch("a", re1)); + + const RE re = "a.*z"; + EXPECT_TRUE(RE::FullMatch("az", re)); + EXPECT_TRUE(RE::FullMatch("axyz", re)); + EXPECT_FALSE(RE::FullMatch("baz", re)); + EXPECT_FALSE(RE::FullMatch("azy", re)); +} + +// Tests RE::PartialMatch(). +TEST(RETest, PartialMatchWorks) { + const RE empty = ""; + EXPECT_TRUE(RE::PartialMatch("", empty)); + EXPECT_TRUE(RE::PartialMatch("a", empty)); + + const RE re = "a.*z"; + EXPECT_TRUE(RE::PartialMatch("az", re)); + EXPECT_TRUE(RE::PartialMatch("axyz", re)); + EXPECT_TRUE(RE::PartialMatch("baz", re)); + EXPECT_TRUE(RE::PartialMatch("azy", re)); + EXPECT_FALSE(RE::PartialMatch("zza", re)); +} + #endif // GTEST_USES_POSIX_RE + +} // namespace internal +} // namespace testing -- cgit v1.2.3 From 4b83461e9772cce62e84310060fe84172e9bf4ba Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Thu, 29 Jan 2009 06:49:00 +0000 Subject: Fixes some warnings when compiled with MSVC at warning level 4. --- test/gtest-filepath_test.cc | 2 +- test/gtest_unittest.cc | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) (limited to 'test') diff --git a/test/gtest-filepath_test.cc b/test/gtest-filepath_test.cc index 589442fe..ee80f0d9 100644 --- a/test/gtest-filepath_test.cc +++ b/test/gtest-filepath_test.cc @@ -311,7 +311,7 @@ TEST(RemoveTrailingPathSeparatorTest, ShouldReturnUnmodified) { TEST(DirectoryTest, RootDirectoryExists) { #ifdef GTEST_OS_WINDOWS // We are on Windows. char current_drive[_MAX_PATH]; // NOLINT - current_drive[0] = _getdrive() + 'A' - 1; + current_drive[0] = static_cast(_getdrive() + 'A' - 1); current_drive[1] = ':'; current_drive[2] = '\\'; current_drive[3] = '\0'; diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index 135493f6..cf9163be 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -1090,7 +1090,7 @@ TEST(TestResultPropertyTest, OverridesValuesForDuplicateKeys) { // property is not recorded. void ExpectNonFatalFailureRecordingPropertyWithReservedKey(const char* key) { TestResult test_result; - TestProperty property("name", "1"); + TestProperty property(key, "1"); EXPECT_NONFATAL_FAILURE(test_result.RecordProperty(property), "Reserved key"); ASSERT_TRUE(test_result.test_properties().IsEmpty()) << "Not recorded"; } @@ -1594,31 +1594,31 @@ TEST(PredicateAssertionTest, AcceptsTemplateFunction) { // Some helper functions for testing using overloaded/template // functions with ASSERT_PRED_FORMATn and EXPECT_PRED_FORMATn. -AssertionResult IsPositiveFormat(const char* expr, int n) { +AssertionResult IsPositiveFormat(const char* /* expr */, int n) { return n > 0 ? AssertionSuccess() : AssertionFailure(Message() << "Failure"); } -AssertionResult IsPositiveFormat(const char* expr, double x) { +AssertionResult IsPositiveFormat(const char* /* expr */, double x) { return x > 0 ? AssertionSuccess() : AssertionFailure(Message() << "Failure"); } template -AssertionResult IsNegativeFormat(const char* expr, T x) { +AssertionResult IsNegativeFormat(const char* /* expr */, T x) { return x < 0 ? AssertionSuccess() : AssertionFailure(Message() << "Failure"); } template -AssertionResult EqualsFormat(const char* expr1, const char* expr2, +AssertionResult EqualsFormat(const char* /* expr1 */, const char* /* expr2 */, const T1& x1, const T2& x2) { return x1 == x2 ? AssertionSuccess() : AssertionFailure(Message() << "Failure"); } // Tests that overloaded functions can be used in *_PRED_FORMAT* -// without explictly specifying their types. +// without explicitly specifying their types. TEST(PredicateFormatAssertionTest, AcceptsOverloadedFunction) { EXPECT_PRED_FORMAT1(IsPositiveFormat, 5); ASSERT_PRED_FORMAT1(IsPositiveFormat, 6.0); -- cgit v1.2.3 From ad99ca14461f0e929d835d29518e11c05e8d41f0 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Mon, 2 Feb 2009 06:37:03 +0000 Subject: Exposes gtest flags to user code access. By Alexander Demin. --- test/gtest_unittest.cc | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'test') diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index cf9163be..847502c7 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -33,6 +33,25 @@ // Google Test work. #include + +// Verifies that the command line flag variables can be accessed +// in code once has been #included. +// Do not move it after other #includes. +TEST(CommandLineFlagsTest, CanBeAccessedInCodeOnceGTestHIsIncluded) { + bool dummy = testing::GTEST_FLAG(also_run_disabled_tests) + || testing::GTEST_FLAG(break_on_failure) + || testing::GTEST_FLAG(catch_exceptions) + || testing::GTEST_FLAG(color) != "unknown" + || testing::GTEST_FLAG(filter) != "unknown" + || testing::GTEST_FLAG(list_tests) + || testing::GTEST_FLAG(output) != "unknown" + || testing::GTEST_FLAG(print_time) + || testing::GTEST_FLAG(repeat) > 0 + || testing::GTEST_FLAG(show_internal_stack_frames) + || testing::GTEST_FLAG(stack_trace_depth) > 0; + EXPECT_TRUE(dummy || !dummy); // Suppresses warning that dummy is unused. +} + #include // Indicates that this translation unit is part of Google Test's -- cgit v1.2.3 From 37504994338c114247519331237831f88a9a7c40 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Fri, 6 Feb 2009 00:47:20 +0000 Subject: Adds tests for EXPECT_FATAL_FAILURE and reduces the golden file bloat (by Zhanyong Wan). Fixes more warnings on Windows (by Vlad Losev). --- test/gtest_output_test.py | 9 +++- test/gtest_output_test_.cc | 12 +++++ test/gtest_output_test_golden_lin.txt | 43 +---------------- test/gtest_output_test_golden_win.txt | 33 ------------- test/gtest_unittest.cc | 88 ++++++++++++++++++++++++++++------- 5 files changed, 92 insertions(+), 93 deletions(-) (limited to 'test') diff --git a/test/gtest_output_test.py b/test/gtest_output_test.py index 42cf00c4..9aaade2e 100755 --- a/test/gtest_output_test.py +++ b/test/gtest_output_test.py @@ -61,11 +61,16 @@ else: GOLDEN_NAME = 'gtest_output_test_golden_lin.txt' PROGRAM_PATH = os.path.join(gtest_test_utils.GetBuildDir(), PROGRAM) + +# At least one command we exercise must not have the +# --gtest_internal_skip_environment_and_ad_hoc_tests flag. COMMAND_WITH_COLOR = PROGRAM_PATH + ' --gtest_color=yes' COMMAND_WITH_TIME = (PROGRAM_PATH + ' --gtest_print_time ' - + '--gtest_filter="FatalFailureTest.*:LoggingTest.*"') + '--gtest_internal_skip_environment_and_ad_hoc_tests ' + '--gtest_filter="FatalFailureTest.*:LoggingTest.*"') COMMAND_WITH_DISABLED = (PROGRAM_PATH + ' --gtest_also_run_disabled_tests ' - + '--gtest_filter="*DISABLED_*"') + '--gtest_internal_skip_environment_and_ad_hoc_tests ' + '--gtest_filter="*DISABLED_*"') GOLDEN_PATH = os.path.join(gtest_test_utils.GetSourceDir(), GOLDEN_NAME) diff --git a/test/gtest_output_test_.cc b/test/gtest_output_test_.cc index 31a0672f..5c76609f 100644 --- a/test/gtest_output_test_.cc +++ b/test/gtest_output_test_.cc @@ -60,6 +60,8 @@ using testing::ScopedFakeTestPartResultReporter; using testing::TestPartResultArray; +using testing::internal::String; + // Tests catching fatal failures. // A subroutine used by the following test. @@ -958,6 +960,10 @@ class BarEnvironment : public testing::Environment { } }; +GTEST_DEFINE_bool_(internal_skip_environment_and_ad_hoc_tests, false, + "This flag causes the program to skip test environment " + "tests and ad hoc tests."); + // The main function. // // The idea is to use Google Test to run all the tests we have defined (some @@ -968,6 +974,9 @@ int main(int argc, char **argv) { // We will use a separate Python script to compare the output of // this program with the golden file. testing::InitGoogleTest(&argc, argv); + if (argc >= 2 && + String(argv[1]) == "--gtest_internal_skip_environment_and_ad_hoc_tests") + GTEST_FLAG(internal_skip_environment_and_ad_hoc_tests) = true; #ifdef GTEST_HAS_DEATH_TEST if (testing::internal::GTEST_FLAG(internal_run_death_test) != "") { @@ -978,6 +987,9 @@ int main(int argc, char **argv) { } #endif // GTEST_HAS_DEATH_TEST + if (GTEST_FLAG(internal_skip_environment_and_ad_hoc_tests)) + return RUN_ALL_TESTS(); + // Registers two global test environments. // The golden file verifies that they are set up in the order they // are registered, and torn down in the reverse order. diff --git a/test/gtest_output_test_golden_lin.txt b/test/gtest_output_test_golden_lin.txt index 0a7efca9..ace88d07 100644 --- a/test/gtest_output_test_golden_lin.txt +++ b/test/gtest_output_test_golden_lin.txt @@ -536,20 +536,9 @@ Expected fatal failure. 33 FAILED TESTS  YOU HAVE 1 DISABLED TEST -The non-test part of the code is expected to have 2 failures. - -gtest_output_test_.cc:#: Failure -Value of: false - Actual: false -Expected: true -gtest_output_test_.cc:#: Failure -Value of: 3 -Expected: 2 -Note: Google Test filter = FatalFailureTest.*:LoggingTest.* +Note: Google Test filter = FatalFailureTest.*:LoggingTest.* [==========] Running 4 tests from 2 test cases. [----------] Global test environment set-up. -FooEnvironment::SetUp() called. -BarEnvironment::SetUp() called. [----------] 3 tests from FatalFailureTest [ RUN ] FatalFailureTest.FatalFailureInSubroutine (expecting a failure that x should be 1) @@ -589,14 +578,6 @@ Expected: (3) >= (a[i]), actual: 3 vs 6 [----------] 1 test from LoggingTest (? ms total) [----------] Global test environment tear-down -BarEnvironment::TearDown() called. -gtest_output_test_.cc:#: Failure -Failed -Expected non-fatal failure. -FooEnvironment::TearDown() called. -gtest_output_test_.cc:#: Failure -Failed -Expected fatal failure. [==========] 4 tests from 2 test cases ran. (? ms total) [ PASSED ] 0 tests. [ FAILED ] 4 tests, listed below: @@ -608,34 +589,12 @@ Expected fatal failure. 4 FAILED TESTS YOU HAVE 1 DISABLED TEST -The non-test part of the code is expected to have 2 failures. - -gtest_output_test_.cc:#: Failure -Value of: false - Actual: false -Expected: true -gtest_output_test_.cc:#: Failure -Value of: 3 -Expected: 2 Note: Google Test filter = *DISABLED_* [==========] Running 1 test from 1 test case. [----------] Global test environment set-up. -FooEnvironment::SetUp() called. -BarEnvironment::SetUp() called. [----------] 1 test from DisabledTestsWarningTest [ RUN ] DisabledTestsWarningTest.DISABLED_AlsoRunDisabledTestsFlagSuppressesWarning [ OK ] DisabledTestsWarningTest.DISABLED_AlsoRunDisabledTestsFlagSuppressesWarning [----------] Global test environment tear-down -BarEnvironment::TearDown() called. -gtest_output_test_.cc:#: Failure -Failed -Expected non-fatal failure. -FooEnvironment::TearDown() called. -gtest_output_test_.cc:#: Failure -Failed -Expected fatal failure. [==========] 1 test from 1 test case ran. [ PASSED ] 1 test. -[ FAILED ] 0 tests, listed below: - - 0 FAILED TESTS diff --git a/test/gtest_output_test_golden_win.txt b/test/gtest_output_test_golden_win.txt index 6fe87610..17be5c04 100644 --- a/test/gtest_output_test_golden_win.txt +++ b/test/gtest_output_test_golden_win.txt @@ -483,18 +483,9 @@ Expected fatal failure. 36 FAILED TESTS YOU HAVE 1 DISABLED TEST -The non-test part of the code is expected to have 2 failures. - -gtest_output_test_.cc:#: error: Value of: false - Actual: false -Expected: true -gtest_output_test_.cc:#: error: Value of: 3 -Expected: 2 Note: Google Test filter = FatalFailureTest.*:LoggingTest.* [==========] Running 4 tests from 2 test cases. [----------] Global test environment set-up. -FooEnvironment::SetUp() called. -BarEnvironment::SetUp() called. [----------] 3 tests from FatalFailureTest [ RUN ] FatalFailureTest.FatalFailureInSubroutine (expecting a failure that x should be 1) @@ -529,12 +520,6 @@ gtest_output_test_.cc:#: error: Expected: (3) >= (a[i]), actual: 3 vs 6 [----------] 1 test from LoggingTest (? ms total) [----------] Global test environment tear-down -BarEnvironment::TearDown() called. -gtest_output_test_.cc:#: error: Failed -Expected non-fatal failure. -FooEnvironment::TearDown() called. -gtest_output_test_.cc:#: error: Failed -Expected fatal failure. [==========] 4 tests from 2 test cases ran. (? ms total) [ PASSED ] 0 tests. [ FAILED ] 4 tests, listed below: @@ -546,30 +531,12 @@ Expected fatal failure. 4 FAILED TESTS YOU HAVE 1 DISABLED TEST -The non-test part of the code is expected to have 2 failures. - -gtest_output_test_.cc:#: error: Value of: false - Actual: false -Expected: true -gtest_output_test_.cc:#: error: Value of: 3 -Expected: 2 Note: Google Test filter = *DISABLED_* [==========] Running 1 test from 1 test case. [----------] Global test environment set-up. -FooEnvironment::SetUp() called. -BarEnvironment::SetUp() called. [----------] 1 test from DisabledTestsWarningTest [ RUN ] DisabledTestsWarningTest.DISABLED_AlsoRunDisabledTestsFlagSuppressesWarning [ OK ] DisabledTestsWarningTest.DISABLED_AlsoRunDisabledTestsFlagSuppressesWarning [----------] Global test environment tear-down -BarEnvironment::TearDown() called. -gtest_output_test_.cc:#: error: Failed -Expected non-fatal failure. -FooEnvironment::TearDown() called. -gtest_output_test_.cc:#: error: Failed -Expected fatal failure. [==========] 1 test from 1 test case ran. [ PASSED ] 1 test. -[ FAILED ] 0 tests, listed below: - - 0 FAILED TESTS diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index 847502c7..faf01a38 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -869,37 +869,58 @@ TEST_F(ScopedFakeTestPartResultReporterWithThreadsTest, #endif // GTEST_IS_THREADSAFE && GTEST_HAS_PTHREAD -// Tests EXPECT_{,NON}FATAL_FAILURE{,ON_ALL_THREADS}. +// Tests EXPECT_FATAL_FAILURE{,ON_ALL_THREADS}. -typedef ScopedFakeTestPartResultReporterTest ExpectFailureTest; +typedef ScopedFakeTestPartResultReporterTest ExpectFatalFailureTest; -TEST_F(ExpectFailureTest, ExpectFatalFaliure) { +TEST_F(ExpectFatalFailureTest, CatchesFatalFaliure) { EXPECT_FATAL_FAILURE(AddFailure(FATAL_FAILURE), "Expected fatal failure."); } -TEST_F(ExpectFailureTest, ExpectNonFatalFailure) { - EXPECT_NONFATAL_FAILURE(AddFailure(NONFATAL_FAILURE), - "Expected non-fatal failure."); -} - -TEST_F(ExpectFailureTest, ExpectFatalFailureOnAllThreads) { +TEST_F(ExpectFatalFailureTest, CatchesFatalFailureOnAllThreads) { + // We have another test below to verify that the macro catches fatal + // failures generated on another thread. EXPECT_FATAL_FAILURE_ON_ALL_THREADS(AddFailure(FATAL_FAILURE), "Expected fatal failure."); } -TEST_F(ExpectFailureTest, ExpectNonFatalFailureOnAllThreads) { - EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(AddFailure(NONFATAL_FAILURE), - "Expected non-fatal failure."); +// Tests that EXPECT_FATAL_FAILURE() can be used in a non-void +// function even when the statement in it contains ASSERT_*. + +int NonVoidFunction() { + EXPECT_FATAL_FAILURE(ASSERT_TRUE(false), ""); + EXPECT_FATAL_FAILURE_ON_ALL_THREADS(FAIL(), ""); + return 0; +} + +TEST_F(ExpectFatalFailureTest, CanBeUsedInNonVoidFunction) { + NonVoidFunction(); } -// Tests that the EXPECT_{,NON}FATAL_FAILURE{,_ON_ALL_THREADS} accepts -// a statement that contains a macro which expands to code containing -// an unprotected comma. +// Tests that EXPECT_FATAL_FAILURE(statement, ...) doesn't abort the +// current function even though 'statement' generates a fatal failure. + +void DoesNotAbortHelper(bool* aborted) { + EXPECT_FATAL_FAILURE(ASSERT_TRUE(false), ""); + EXPECT_FATAL_FAILURE_ON_ALL_THREADS(FAIL(), ""); + + *aborted = false; +} + +TEST_F(ExpectFatalFailureTest, DoesNotAbort) { + bool aborted = true; + DoesNotAbortHelper(&aborted); + EXPECT_FALSE(aborted); +} + +// Tests that the EXPECT_FATAL_FAILURE{,_ON_ALL_THREADS} accepts a +// statement that contains a macro which expands to code containing an +// unprotected comma. static int global_var = 0; #define GTEST_USE_UNPROTECTED_COMMA_ global_var++, global_var++ -TEST_F(ExpectFailureTest, AcceptsMacroThatExpandsToUnprotectedComma) { +TEST_F(ExpectFatalFailureTest, AcceptsMacroThatExpandsToUnprotectedComma) { EXPECT_FATAL_FAILURE({ GTEST_USE_UNPROTECTED_COMMA_; AddFailure(FATAL_FAILURE); @@ -909,7 +930,28 @@ TEST_F(ExpectFailureTest, AcceptsMacroThatExpandsToUnprotectedComma) { GTEST_USE_UNPROTECTED_COMMA_; AddFailure(FATAL_FAILURE); }, ""); +} + +// Tests EXPECT_NONFATAL_FAILURE{,ON_ALL_THREADS}. + +typedef ScopedFakeTestPartResultReporterTest ExpectNonfatalFailureTest; + +TEST_F(ExpectNonfatalFailureTest, CatchesNonfatalFailure) { + EXPECT_NONFATAL_FAILURE(AddFailure(NONFATAL_FAILURE), + "Expected non-fatal failure."); +} +TEST_F(ExpectNonfatalFailureTest, CatchesNonfatalFailureOnAllThreads) { + // We have another test below to verify that the macro catches + // non-fatal failures generated on another thread. + EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(AddFailure(NONFATAL_FAILURE), + "Expected non-fatal failure."); +} + +// Tests that the EXPECT_NONFATAL_FAILURE{,_ON_ALL_THREADS} accepts a +// statement that contains a macro which expands to code containing an +// unprotected comma. +TEST_F(ExpectNonfatalFailureTest, AcceptsMacroThatExpandsToUnprotectedComma) { EXPECT_NONFATAL_FAILURE({ GTEST_USE_UNPROTECTED_COMMA_; AddFailure(NONFATAL_FAILURE); @@ -3091,6 +3133,20 @@ TEST(AssertionSyntaxTest, BasicAssertionsBehavesLikeSingleStatement) { } #if GTEST_HAS_EXCEPTIONS +// Tests that the compiler will not complain about unreachable code in the +// EXPECT_THROW/EXPECT_ANY_THROW/EXPECT_NO_THROW macros. +TEST(ExpectThrowTest, DoesNotGenerateUnreachableCodeWarning) { + int n = 0; + + EXPECT_THROW(throw 1, int); + EXPECT_NONFATAL_FAILURE(EXPECT_THROW(n++, int), ""); + EXPECT_NONFATAL_FAILURE(EXPECT_THROW(throw 1, const char*), ""); + EXPECT_NO_THROW(n++); + EXPECT_NONFATAL_FAILURE(EXPECT_NO_THROW(throw 1), ""); + EXPECT_ANY_THROW(throw 1); + EXPECT_NONFATAL_FAILURE(EXPECT_ANY_THROW(n++), ""); +} + TEST(AssertionSyntaxTest, ExceptionAssertionsBehavesLikeSingleStatement) { if (false) EXPECT_THROW(1, bool); -- cgit v1.2.3 From 886cafd4a37fd5e7325da1ae5a5a948b6c2bc895 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Sun, 8 Feb 2009 04:53:35 +0000 Subject: Fixes the definition of GTEST_HAS_EXCEPTIONS, allowing exception assertions to be used with gcc. --- test/gtest_output_test_golden_lin.txt | 26 +++++++++++---- test/gtest_unittest.cc | 62 ++++++++++++++++++++--------------- 2 files changed, 55 insertions(+), 33 deletions(-) (limited to 'test') diff --git a/test/gtest_output_test_golden_lin.txt b/test/gtest_output_test_golden_lin.txt index ace88d07..74ed7371 100644 --- a/test/gtest_output_test_golden_lin.txt +++ b/test/gtest_output_test_golden_lin.txt @@ -7,7 +7,7 @@ Expected: true gtest_output_test_.cc:#: Failure Value of: 3 Expected: 2 -[==========] Running 52 tests from 22 test cases. +[==========] Running 54 tests from 22 test cases. [----------] Global test environment set-up. FooEnvironment::SetUp() called. BarEnvironment::SetUp() called. @@ -270,7 +270,7 @@ test DefinedUsingTEST is defined using TEST. You probably want to change the TEST to TEST_F or move it to another test case. [ FAILED ] TEST_before_TEST_F_in_same_test_case.DefinedUsingTEST_FAndShouldFail -[----------] 7 tests from ExpectNonfatalFailureTest +[----------] 8 tests from ExpectNonfatalFailureTest [ RUN ] ExpectNonfatalFailureTest.CanReferenceGlobalVariables [ OK ] ExpectNonfatalFailureTest.CanReferenceGlobalVariables [ RUN ] ExpectNonfatalFailureTest.CanReferenceLocalVariables @@ -313,7 +313,13 @@ gtest.cc:#: Failure Expected: 1 non-fatal failure Actual: 0 failures [ FAILED ] ExpectNonfatalFailureTest.FailsWhenStatementReturns -[----------] 7 tests from ExpectFatalFailureTest +[ RUN ] ExpectNonfatalFailureTest.FailsWhenStatementThrows +(expecting a failure) +gtest.cc:#: Failure +Expected: 1 non-fatal failure + Actual: 0 failures +[ FAILED ] ExpectNonfatalFailureTest.FailsWhenStatementThrows +[----------] 8 tests from ExpectFatalFailureTest [ RUN ] ExpectFatalFailureTest.CanReferenceGlobalVariables [ OK ] ExpectFatalFailureTest.CanReferenceGlobalVariables [ RUN ] ExpectFatalFailureTest.CanReferenceLocalStaticVariables @@ -356,6 +362,12 @@ gtest.cc:#: Failure Expected: 1 fatal failure Actual: 0 failures [ FAILED ] ExpectFatalFailureTest.FailsWhenStatementReturns +[ RUN ] ExpectFatalFailureTest.FailsWhenStatementThrows +(expecting a failure) +gtest.cc:#: Failure +Expected: 1 fatal failure + Actual: 0 failures +[ FAILED ] ExpectFatalFailureTest.FailsWhenStatementThrows [----------] 2 tests from TypedTest/0, where TypeParam = int [ RUN ] TypedTest/0.Success [ OK ] TypedTest/0.Success @@ -496,9 +508,9 @@ FooEnvironment::TearDown() called. gtest_output_test_.cc:#: Failure Failed Expected fatal failure. -[==========] 52 tests from 22 test cases ran. +[==========] 54 tests from 22 test cases ran. [ PASSED ] 19 tests. -[ FAILED ] 33 tests, listed below: +[ FAILED ] 35 tests, listed below: [ FAILED ] FatalFailureTest.FatalFailureInSubroutine [ FAILED ] FatalFailureTest.FatalFailureInNestedSubroutine [ FAILED ] FatalFailureTest.NonfatalFailureInSubroutine @@ -521,10 +533,12 @@ Expected fatal failure. [ FAILED ] ExpectNonfatalFailureTest.FailsWhenThereAreTwoNonfatalFailures [ FAILED ] ExpectNonfatalFailureTest.FailsWhenThereIsOneFatalFailure [ FAILED ] ExpectNonfatalFailureTest.FailsWhenStatementReturns +[ FAILED ] ExpectNonfatalFailureTest.FailsWhenStatementThrows [ FAILED ] ExpectFatalFailureTest.FailsWhenThereIsNoFatalFailure [ FAILED ] ExpectFatalFailureTest.FailsWhenThereAreTwoFatalFailures [ FAILED ] ExpectFatalFailureTest.FailsWhenThereIsOneNonfatalFailure [ FAILED ] ExpectFatalFailureTest.FailsWhenStatementReturns +[ FAILED ] ExpectFatalFailureTest.FailsWhenStatementThrows [ FAILED ] TypedTest/0.Failure, where TypeParam = int [ FAILED ] Unsigned/TypedTestP/0.Failure, where TypeParam = unsigned char [ FAILED ] Unsigned/TypedTestP/1.Failure, where TypeParam = unsigned int @@ -533,7 +547,7 @@ Expected fatal failure. [ FAILED ] ExpectFailureTest.ExpectFatalFailureOnAllThreads [ FAILED ] ExpectFailureTest.ExpectNonFatalFailureOnAllThreads -33 FAILED TESTS +35 FAILED TESTS  YOU HAVE 1 DISABLED TEST Note: Google Test filter = FatalFailureTest.*:LoggingTest.* diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index faf01a38..4bac8a69 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -2869,31 +2869,37 @@ TEST(AssertionTest, ASSERT_GT) { #if GTEST_HAS_EXCEPTIONS +void ThrowNothing() {} + + // Tests ASSERT_THROW. TEST(AssertionTest, ASSERT_THROW) { ASSERT_THROW(ThrowAnInteger(), int); - EXPECT_FATAL_FAILURE(ASSERT_THROW(ThrowAnInteger(), bool), - "Expected: ThrowAnInteger() throws an exception of type"\ - " bool.\n Actual: it throws a different type."); - EXPECT_FATAL_FAILURE(ASSERT_THROW(1, bool), - "Expected: 1 throws an exception of type bool.\n"\ - " Actual: it throws nothing."); + EXPECT_FATAL_FAILURE( + ASSERT_THROW(ThrowAnInteger(), bool), + "Expected: ThrowAnInteger() throws an exception of type bool.\n" + " Actual: it throws a different type."); + EXPECT_FATAL_FAILURE( + ASSERT_THROW(ThrowNothing(), bool), + "Expected: ThrowNothing() throws an exception of type bool.\n" + " Actual: it throws nothing."); } // Tests ASSERT_NO_THROW. TEST(AssertionTest, ASSERT_NO_THROW) { - ASSERT_NO_THROW(1); + ASSERT_NO_THROW(ThrowNothing()); EXPECT_FATAL_FAILURE(ASSERT_NO_THROW(ThrowAnInteger()), - "Expected: ThrowAnInteger() doesn't throw an exception."\ + "Expected: ThrowAnInteger() doesn't throw an exception." "\n Actual: it throws."); } // Tests ASSERT_ANY_THROW. TEST(AssertionTest, ASSERT_ANY_THROW) { ASSERT_ANY_THROW(ThrowAnInteger()); - EXPECT_FATAL_FAILURE(ASSERT_ANY_THROW(1), - "Expected: 1 throws an exception.\n Actual: it "\ - "doesn't."); + EXPECT_FATAL_FAILURE( + ASSERT_ANY_THROW(ThrowNothing()), + "Expected: ThrowNothing() throws an exception.\n" + " Actual: it doesn't."); } #endif // GTEST_HAS_EXCEPTIONS @@ -3149,7 +3155,7 @@ TEST(ExpectThrowTest, DoesNotGenerateUnreachableCodeWarning) { TEST(AssertionSyntaxTest, ExceptionAssertionsBehavesLikeSingleStatement) { if (false) - EXPECT_THROW(1, bool); + EXPECT_THROW(ThrowNothing(), bool); if (true) EXPECT_THROW(ThrowAnInteger(), int); @@ -3160,12 +3166,12 @@ TEST(AssertionSyntaxTest, ExceptionAssertionsBehavesLikeSingleStatement) { EXPECT_NO_THROW(ThrowAnInteger()); if (true) - EXPECT_NO_THROW(1); + EXPECT_NO_THROW(ThrowNothing()); else ; if (false) - EXPECT_ANY_THROW(1); + EXPECT_ANY_THROW(ThrowNothing()); if (true) EXPECT_ANY_THROW(ThrowAnInteger()); @@ -3424,27 +3430,29 @@ TEST(ExpectTest, EXPECT_GT) { TEST(ExpectTest, EXPECT_THROW) { EXPECT_THROW(ThrowAnInteger(), int); EXPECT_NONFATAL_FAILURE(EXPECT_THROW(ThrowAnInteger(), bool), - "Expected: ThrowAnInteger() throws an exception of "\ + "Expected: ThrowAnInteger() throws an exception of " "type bool.\n Actual: it throws a different type."); - EXPECT_NONFATAL_FAILURE(EXPECT_THROW(1, bool), - "Expected: 1 throws an exception of type bool.\n"\ - " Actual: it throws nothing."); + EXPECT_NONFATAL_FAILURE( + EXPECT_THROW(ThrowNothing(), bool), + "Expected: ThrowNothing() throws an exception of type bool.\n" + " Actual: it throws nothing."); } // Tests EXPECT_NO_THROW. TEST(ExpectTest, EXPECT_NO_THROW) { - EXPECT_NO_THROW(1); + EXPECT_NO_THROW(ThrowNothing()); EXPECT_NONFATAL_FAILURE(EXPECT_NO_THROW(ThrowAnInteger()), - "Expected: ThrowAnInteger() doesn't throw an "\ + "Expected: ThrowAnInteger() doesn't throw an " "exception.\n Actual: it throws."); } // Tests EXPECT_ANY_THROW. TEST(ExpectTest, EXPECT_ANY_THROW) { EXPECT_ANY_THROW(ThrowAnInteger()); - EXPECT_NONFATAL_FAILURE(EXPECT_ANY_THROW(1), - "Expected: 1 throws an exception.\n Actual: it "\ - "doesn't."); + EXPECT_NONFATAL_FAILURE( + EXPECT_ANY_THROW(ThrowNothing()), + "Expected: ThrowNothing() throws an exception.\n" + " Actual: it doesn't."); } #endif // GTEST_HAS_EXCEPTIONS @@ -5056,8 +5064,8 @@ TEST(StreamingAssertionsTest, Throw) { } TEST(StreamingAssertionsTest, NoThrow) { - EXPECT_NO_THROW(1) << "unexpected failure"; - ASSERT_NO_THROW(1) << "unexpected failure"; + EXPECT_NO_THROW(ThrowNothing()) << "unexpected failure"; + ASSERT_NO_THROW(ThrowNothing()) << "unexpected failure"; EXPECT_NONFATAL_FAILURE(EXPECT_NO_THROW(ThrowAnInteger()) << "expected failure", "expected failure"); EXPECT_FATAL_FAILURE(ASSERT_NO_THROW(ThrowAnInteger()) << @@ -5067,9 +5075,9 @@ TEST(StreamingAssertionsTest, NoThrow) { TEST(StreamingAssertionsTest, AnyThrow) { EXPECT_ANY_THROW(ThrowAnInteger()) << "unexpected failure"; ASSERT_ANY_THROW(ThrowAnInteger()) << "unexpected failure"; - EXPECT_NONFATAL_FAILURE(EXPECT_ANY_THROW(1) << + EXPECT_NONFATAL_FAILURE(EXPECT_ANY_THROW(ThrowNothing()) << "expected failure", "expected failure"); - EXPECT_FATAL_FAILURE(ASSERT_ANY_THROW(1) << + EXPECT_FATAL_FAILURE(ASSERT_ANY_THROW(ThrowNothing()) << "expected failure", "expected failure"); } -- cgit v1.2.3 From cd3e4016ea451c9ee5cb7925329f2611098cbcf9 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Mon, 9 Feb 2009 18:05:21 +0000 Subject: Implements the test sharding protocol. By Eric Fellheimer. --- test/gtest_filter_unittest.py | 162 +++++++++++++++++++++++++++++++--- test/gtest_filter_unittest_.cc | 19 ++++ test/gtest_output_test.py | 68 +++++++++----- test/gtest_output_test_.cc | 6 ++ test/gtest_output_test_golden_lin.txt | 24 ++++- test/gtest_output_test_golden_win.txt | 24 ++++- test/gtest_unittest.cc | 158 +++++++++++++++++++++++++++++++++ 7 files changed, 420 insertions(+), 41 deletions(-) (limited to 'test') diff --git a/test/gtest_filter_unittest.py b/test/gtest_filter_unittest.py index 35307a26..c3a016cf 100755 --- a/test/gtest_filter_unittest.py +++ b/test/gtest_filter_unittest.py @@ -36,6 +36,9 @@ the GTEST_FILTER environment variable or the --gtest_filter flag. This script tests such functionality by invoking gtest_filter_unittest_ (a program written with Google Test) with different environments and command line flags. + +Note that test sharding may also influence which tests are filtered. Therefore, +we test that here also. """ __author__ = 'wan@google.com (Zhanyong Wan)' @@ -43,6 +46,7 @@ __author__ = 'wan@google.com (Zhanyong Wan)' import os import re import sets +import tempfile import unittest import gtest_test_utils @@ -51,6 +55,11 @@ import gtest_test_utils # The environment variable for specifying the test filters. FILTER_ENV_VAR = 'GTEST_FILTER' +# The environment variables for test sharding. +TOTAL_SHARDS_ENV_VAR = 'GTEST_TOTAL_SHARDS' +SHARD_INDEX_ENV_VAR = 'GTEST_SHARD_INDEX' +SHARD_STATUS_FILE_ENV_VAR = 'GTEST_SHARD_STATUS_FILE' + # The command line flag for specifying the test filters. FILTER_FLAG = 'gtest_filter' @@ -103,6 +112,9 @@ ACTIVE_TESTS = [ 'BazTest.TestOne', 'BazTest.TestA', 'BazTest.TestB', + + 'HasDeathTest.Test1', + 'HasDeathTest.Test2', ] + PARAM_TESTS param_tests_present = None @@ -121,7 +133,7 @@ def SetEnvVar(env_var, value): def Run(command): """Runs a Google Test program and returns a list of full names of the - tests that were run. + tests that were run along with the test exit code. """ stdout_file = os.popen(command, 'r') @@ -137,9 +149,32 @@ def Run(command): if match is not None: test = match.group(1) tests_run += [test_case + '.' + test] - stdout_file.close() - return tests_run + exit_code = stdout_file.close() + return (tests_run, exit_code) + + +def InvokeWithModifiedEnv(extra_env, function, *args, **kwargs): + """Runs the given function and arguments in a modified environment.""" + try: + original_env = os.environ.copy() + os.environ.update(extra_env) + return function(*args, **kwargs) + finally: + for key in extra_env.iterkeys(): + if key in original_env: + os.environ[key] = original_env[key] + else: + del os.environ[key] + + +def RunWithSharding(total_shards, shard_index, command): + """Runs the Google Test program shard and returns a list of full names of the + tests that were run along with the exit code. + """ + extra_env = {SHARD_INDEX_ENV_VAR: str(shard_index), + TOTAL_SHARDS_ENV_VAR: str(total_shards)} + return InvokeWithModifiedEnv(extra_env, Run, command) # The unit test. @@ -160,6 +195,15 @@ class GTestFilterUnitTest(unittest.TestCase): for elem in rhs: self.assert_(elem in lhs, '%s in %s' % (elem, lhs)) + def AssertPartitionIsValid(self, set_var, list_of_sets): + """Asserts that list_of_sets is a valid partition of set_var.""" + + full_partition = [] + for slice_var in list_of_sets: + full_partition.extend(slice_var) + self.assertEqual(len(set_var), len(full_partition)) + self.assertEqual(sorted(set_var), sorted(full_partition)) + def RunAndVerify(self, gtest_filter, tests_to_run): """Runs gtest_flag_unittest_ with the given filter, and verifies that the right set of tests were run. @@ -173,7 +217,7 @@ class GTestFilterUnitTest(unittest.TestCase): # First, tests using GTEST_FILTER. SetEnvVar(FILTER_ENV_VAR, gtest_filter) - tests_run = Run(COMMAND) + tests_run = Run(COMMAND)[0] SetEnvVar(FILTER_ENV_VAR, None) self.AssertSetEqual(tests_run, tests_to_run) @@ -185,9 +229,27 @@ class GTestFilterUnitTest(unittest.TestCase): else: command = '%s --%s=%s' % (COMMAND, FILTER_FLAG, gtest_filter) - tests_run = Run(command) + tests_run = Run(command)[0] self.AssertSetEqual(tests_run, tests_to_run) + def RunAndVerifyWithSharding(self, gtest_filter, total_shards, tests_to_run, + command=COMMAND, check_exit_0=False): + """Runs all shards of gtest_flag_unittest_ with the given filter, and + verifies that the right set of tests were run. The union of tests run + on each shard should be identical to tests_to_run, without duplicates. + If check_exit_0, make sure that all shards returned 0. + """ + SetEnvVar(FILTER_ENV_VAR, gtest_filter) + partition = [] + for i in range(0, total_shards): + (tests_run, exit_code) = RunWithSharding(total_shards, i, command) + if check_exit_0: + self.assert_(exit_code is None) + partition.append(tests_run) + + self.AssertPartitionIsValid(tests_to_run, partition) + SetEnvVar(FILTER_ENV_VAR, None) + def RunAndVerifyAllowingDisabled(self, gtest_filter, tests_to_run): """Runs gtest_flag_unittest_ with the given filter, and enables disabled tests. Verifies that the right set of tests were run. @@ -197,7 +259,7 @@ class GTestFilterUnitTest(unittest.TestCase): if gtest_filter is not None: command = '%s --%s=%s' % (command, FILTER_FLAG, gtest_filter) - tests_run = Run(command) + tests_run = Run(command)[0] self.AssertSetEqual(tests_run, tests_to_run) def setUp(self): @@ -214,10 +276,22 @@ class GTestFilterUnitTest(unittest.TestCase): self.RunAndVerify(None, ACTIVE_TESTS) + def testDefaultBehaviorWithShards(self): + """Tests the behavior of not specifying the filter, with sharding + enabled. + """ + self.RunAndVerifyWithSharding(None, 1, ACTIVE_TESTS) + self.RunAndVerifyWithSharding(None, 2, ACTIVE_TESTS) + self.RunAndVerifyWithSharding(None, len(ACTIVE_TESTS) - 1, ACTIVE_TESTS) + self.RunAndVerifyWithSharding(None, len(ACTIVE_TESTS), ACTIVE_TESTS) + self.RunAndVerifyWithSharding(None, len(ACTIVE_TESTS) + 1, ACTIVE_TESTS) + def testEmptyFilter(self): """Tests an empty filter.""" self.RunAndVerify('', []) + self.RunAndVerifyWithSharding('', 1, []) + self.RunAndVerifyWithSharding('', 2, []) def testBadFilter(self): """Tests a filter that matches nothing.""" @@ -230,12 +304,14 @@ class GTestFilterUnitTest(unittest.TestCase): self.RunAndVerify('FooTest.Xyz', ['FooTest.Xyz']) self.RunAndVerifyAllowingDisabled('FooTest.Xyz', ['FooTest.Xyz']) + self.RunAndVerifyWithSharding('FooTest.Xyz', 5, ['FooTest.Xyz']) def testUniversalFilters(self): """Tests filters that match everything.""" self.RunAndVerify('*', ACTIVE_TESTS) self.RunAndVerify('*.*', ACTIVE_TESTS) + self.RunAndVerifyWithSharding('*.*', len(ACTIVE_TESTS) - 3, ACTIVE_TESTS) self.RunAndVerifyAllowingDisabled('*', ACTIVE_TESTS + DISABLED_TESTS) self.RunAndVerifyAllowingDisabled('*.*', ACTIVE_TESTS + DISABLED_TESTS) @@ -289,7 +365,10 @@ class GTestFilterUnitTest(unittest.TestCase): 'BazTest.TestOne', 'BazTest.TestA', - 'BazTest.TestB' ] + PARAM_TESTS) + 'BazTest.TestB', + + 'HasDeathTest.Test1', + 'HasDeathTest.Test2', ] + PARAM_TESTS) def testWildcardInTestName(self): """Tests using wildcard in the test name.""" @@ -350,7 +429,8 @@ class GTestFilterUnitTest(unittest.TestCase): ]) def testNegativeFilters(self): - self.RunAndVerify('*-FooTest.Abc', [ + self.RunAndVerify('*-HasDeathTest.Test1', [ + 'FooTest.Abc', 'FooTest.Xyz', 'BarTest.TestOne', @@ -360,14 +440,20 @@ class GTestFilterUnitTest(unittest.TestCase): 'BazTest.TestOne', 'BazTest.TestA', 'BazTest.TestB', + + 'HasDeathTest.Test2', ] + PARAM_TESTS) - self.RunAndVerify('*-FooTest.Abc:BazTest.*', [ + self.RunAndVerify('*-FooTest.Abc:HasDeathTest.*', [ 'FooTest.Xyz', 'BarTest.TestOne', 'BarTest.TestTwo', 'BarTest.TestThree', + + 'BazTest.TestOne', + 'BazTest.TestA', + 'BazTest.TestB', ] + PARAM_TESTS) self.RunAndVerify('BarTest.*-BarTest.TestOne', [ @@ -376,7 +462,7 @@ class GTestFilterUnitTest(unittest.TestCase): ]) # Tests without leading '*'. - self.RunAndVerify('-FooTest.Abc:FooTest.Xyz', [ + self.RunAndVerify('-FooTest.Abc:FooTest.Xyz:HasDeathTest.*', [ 'BarTest.TestOne', 'BarTest.TestTwo', 'BarTest.TestThree', @@ -412,11 +498,65 @@ class GTestFilterUnitTest(unittest.TestCase): SetEnvVar(FILTER_ENV_VAR, 'Foo*') command = '%s --%s=%s' % (COMMAND, FILTER_FLAG, '*One') - tests_run = Run(command) + tests_run = Run(command)[0] SetEnvVar(FILTER_ENV_VAR, None) self.AssertSetEqual(tests_run, ['BarTest.TestOne', 'BazTest.TestOne']) + def testShardStatusFileIsCreated(self): + """Tests that the shard file is created if specified in the environment.""" + + test_tmpdir = tempfile.mkdtemp() + shard_status_file = os.path.join(test_tmpdir, 'shard_status_file') + self.assert_(not os.path.exists(shard_status_file)) + + extra_env = {SHARD_STATUS_FILE_ENV_VAR: shard_status_file} + stdout_file = InvokeWithModifiedEnv(extra_env, os.popen, COMMAND, 'r') + try: + stdout_file.readlines() + finally: + stdout_file.close() + self.assert_(os.path.exists(shard_status_file)) + os.remove(shard_status_file) + os.removedirs(test_tmpdir) + + def testShardStatusFileIsCreatedWithListTests(self): + """Tests that the shard file is created with --gtest_list_tests.""" + + test_tmpdir = tempfile.mkdtemp() + shard_status_file = os.path.join(test_tmpdir, 'shard_status_file2') + self.assert_(not os.path.exists(shard_status_file)) + + extra_env = {SHARD_STATUS_FILE_ENV_VAR: shard_status_file} + stdout_file = InvokeWithModifiedEnv(extra_env, os.popen, + '%s --gtest_list_tests' % COMMAND, 'r') + try: + stdout_file.readlines() + finally: + stdout_file.close() + self.assert_(os.path.exists(shard_status_file)) + os.remove(shard_status_file) + os.removedirs(test_tmpdir) + + def testShardingWorksWithDeathTests(self): + """Tests integration with death tests and sharding.""" + gtest_filter = 'HasDeathTest.*:SeqP/*' + expected_tests = [ + 'HasDeathTest.Test1', + 'HasDeathTest.Test2', + + 'SeqP/ParamTest.TestX/0', + 'SeqP/ParamTest.TestX/1', + 'SeqP/ParamTest.TestY/0', + 'SeqP/ParamTest.TestY/1', + ] + + for command in (COMMAND + ' --gtest_death_test_style=threadsafe', + COMMAND + ' --gtest_death_test_style=fast'): + self.RunAndVerifyWithSharding(gtest_filter, 3, expected_tests, + check_exit_0=True, command=command) + self.RunAndVerifyWithSharding(gtest_filter, 5, expected_tests, + check_exit_0=True, command=command) if __name__ == '__main__': gtest_test_utils.Main() diff --git a/test/gtest_filter_unittest_.cc b/test/gtest_filter_unittest_.cc index 99610796..22638e0d 100644 --- a/test/gtest_filter_unittest_.cc +++ b/test/gtest_filter_unittest_.cc @@ -91,6 +91,25 @@ TEST(BazTest, DISABLED_TestC) { FAIL() << "Expected failure."; } +// Test case HasDeathTest + +TEST(HasDeathTest, Test1) { +#ifdef GTEST_HAS_DEATH_TEST + EXPECT_DEATH({exit(1);}, + ".*"); +#endif // GTEST_HAS_DEATH_TEST +} + +// We need at least two death tests to make sure that the all death tests +// aren't on the first shard. +TEST(HasDeathTest, Test2) { +#ifdef GTEST_HAS_DEATH_TEST + EXPECT_DEATH({exit(1);}, + ".*"); +#endif // GTEST_HAS_DEATH_TEST +} + + // Test case FoobarTest TEST(DISABLED_FoobarTest, Test1) { diff --git a/test/gtest_output_test.py b/test/gtest_output_test.py index 9aaade2e..f35e0024 100755 --- a/test/gtest_output_test.py +++ b/test/gtest_output_test.py @@ -64,13 +64,17 @@ PROGRAM_PATH = os.path.join(gtest_test_utils.GetBuildDir(), PROGRAM) # At least one command we exercise must not have the # --gtest_internal_skip_environment_and_ad_hoc_tests flag. -COMMAND_WITH_COLOR = PROGRAM_PATH + ' --gtest_color=yes' -COMMAND_WITH_TIME = (PROGRAM_PATH + ' --gtest_print_time ' +COMMAND_WITH_COLOR = ({}, PROGRAM_PATH + ' --gtest_color=yes') +COMMAND_WITH_TIME = ({}, PROGRAM_PATH + ' --gtest_print_time ' '--gtest_internal_skip_environment_and_ad_hoc_tests ' '--gtest_filter="FatalFailureTest.*:LoggingTest.*"') -COMMAND_WITH_DISABLED = (PROGRAM_PATH + ' --gtest_also_run_disabled_tests ' +COMMAND_WITH_DISABLED = ({}, PROGRAM_PATH + ' --gtest_also_run_disabled_tests ' '--gtest_internal_skip_environment_and_ad_hoc_tests ' '--gtest_filter="*DISABLED_*"') +COMMAND_WITH_SHARDING = ({'GTEST_SHARD_INDEX': '1', 'GTEST_TOTAL_SHARDS': '2'}, + PROGRAM_PATH + + ' --gtest_internal_skip_environment_and_ad_hoc_tests ' + ' --gtest_filter="PassingTest.*"') GOLDEN_PATH = os.path.join(gtest_test_utils.GetSourceDir(), GOLDEN_NAME) @@ -136,19 +140,26 @@ def NormalizeOutput(output): return output -def IterShellCommandOutput(cmd, stdin_string=None): +def IterShellCommandOutput(env_cmd, stdin_string=None): """Runs a command in a sub-process, and iterates the lines in its STDOUT. Args: - cmd: The shell command. - stdin_string: The string to be fed to the STDIN of the sub-process; - If None, the sub-process will inherit the STDIN - from the parent process. + env_cmd: The shell command. A 2-tuple where element 0 is a dict + of extra environment variables to set, and element 1 + is a string with the command and any flags. + stdin_string: The string to be fed to the STDIN of the sub-process; + If None, the sub-process will inherit the STDIN + from the parent process. """ # Spawns cmd in a sub-process, and gets its standard I/O file objects. - stdin_file, stdout_file = os.popen2(cmd, 'b') + # Set and save the environment properly. + old_env_vars = dict(os.environ) + os.environ.update(env_cmd[0]) + stdin_file, stdout_file = os.popen2(env_cmd[1], 'b') + os.environ.clear() + os.environ.update(old_env_vars) # If the caller didn't specify a string for STDIN, gets it from the # parent process. @@ -168,39 +179,50 @@ def IterShellCommandOutput(cmd, stdin_string=None): yield line -def GetShellCommandOutput(cmd, stdin_string=None): +def GetShellCommandOutput(env_cmd, stdin_string=None): """Runs a command in a sub-process, and returns its STDOUT in a string. Args: - cmd: The shell command. - stdin_string: The string to be fed to the STDIN of the sub-process; - If None, the sub-process will inherit the STDIN - from the parent process. + env_cmd: The shell command. A 2-tuple where element 0 is a dict + of extra environment variables to set, and element 1 + is a string with the command and any flags. + stdin_string: The string to be fed to the STDIN of the sub-process; + If None, the sub-process will inherit the STDIN + from the parent process. """ - lines = list(IterShellCommandOutput(cmd, stdin_string)) + lines = list(IterShellCommandOutput(env_cmd, stdin_string)) return string.join(lines, '') -def GetCommandOutput(cmd): +def GetCommandOutput(env_cmd): """Runs a command and returns its output with all file location info stripped off. Args: - cmd: the shell command. + env_cmd: The shell command. A 2-tuple where element 0 is a dict of extra + environment variables to set, and element 1 is a string with + the command and any flags. """ # Disables exception pop-ups on Windows. os.environ['GTEST_CATCH_EXCEPTIONS'] = '1' - return NormalizeOutput(GetShellCommandOutput(cmd, '')) + return NormalizeOutput(GetShellCommandOutput(env_cmd, '')) + + +def GetOutputOfAllCommands(): + """Returns concatenated output from several representative commands.""" + + return (GetCommandOutput(COMMAND_WITH_COLOR) + + GetCommandOutput(COMMAND_WITH_TIME) + + GetCommandOutput(COMMAND_WITH_DISABLED) + + GetCommandOutput(COMMAND_WITH_SHARDING)) class GTestOutputTest(unittest.TestCase): def testOutput(self): - output = (GetCommandOutput(COMMAND_WITH_COLOR) + - GetCommandOutput(COMMAND_WITH_TIME) + - GetCommandOutput(COMMAND_WITH_DISABLED)) + output = GetOutputOfAllCommands() golden_file = open(GOLDEN_PATH, 'rb') golden = golden_file.read() golden_file.close() @@ -214,9 +236,7 @@ class GTestOutputTest(unittest.TestCase): if __name__ == '__main__': if sys.argv[1:] == [GENGOLDEN_FLAG]: - output = (GetCommandOutput(COMMAND_WITH_COLOR) + - GetCommandOutput(COMMAND_WITH_TIME) + - GetCommandOutput(COMMAND_WITH_DISABLED)) + output = GetOutputOfAllCommands() golden_file = open(GOLDEN_PATH, 'wb') golden_file.write(output) golden_file.close() diff --git a/test/gtest_output_test_.cc b/test/gtest_output_test_.cc index 5c76609f..f5748d17 100644 --- a/test/gtest_output_test_.cc +++ b/test/gtest_output_test_.cc @@ -85,6 +85,12 @@ void TryTestSubroutine() { FAIL() << "This should never be reached."; } +TEST(PassingTest, PassingTest1) { +} + +TEST(PassingTest, PassingTest2) { +} + // Tests catching a fatal failure in a subroutine. TEST(FatalFailureTest, FatalFailureInSubroutine) { printf("(expecting a failure that x should be 1)\n"); diff --git a/test/gtest_output_test_golden_lin.txt b/test/gtest_output_test_golden_lin.txt index 74ed7371..46a90fb5 100644 --- a/test/gtest_output_test_golden_lin.txt +++ b/test/gtest_output_test_golden_lin.txt @@ -7,7 +7,7 @@ Expected: true gtest_output_test_.cc:#: Failure Value of: 3 Expected: 2 -[==========] Running 54 tests from 22 test cases. +[==========] Running 56 tests from 23 test cases. [----------] Global test environment set-up. FooEnvironment::SetUp() called. BarEnvironment::SetUp() called. @@ -26,6 +26,11 @@ BarEnvironment::SetUp() called. [----------] 1 test from My/ATypeParamDeathTest/1, where TypeParam = double [ RUN ] My/ATypeParamDeathTest/1.ShouldRunFirst [ OK ] My/ATypeParamDeathTest/1.ShouldRunFirst +[----------] 2 tests from PassingTest +[ RUN ] PassingTest.PassingTest1 +[ OK ] PassingTest.PassingTest1 +[ RUN ] PassingTest.PassingTest2 +[ OK ] PassingTest.PassingTest2 [----------] 3 tests from FatalFailureTest [ RUN ] FatalFailureTest.FatalFailureInSubroutine (expecting a failure that x should be 1) @@ -508,8 +513,8 @@ FooEnvironment::TearDown() called. gtest_output_test_.cc:#: Failure Failed Expected fatal failure. -[==========] 54 tests from 22 test cases ran. -[ PASSED ] 19 tests. +[==========] 56 tests from 23 test cases ran. +[ PASSED ] 21 tests. [ FAILED ] 35 tests, listed below: [ FAILED ] FatalFailureTest.FatalFailureInSubroutine [ FAILED ] FatalFailureTest.FatalFailureInNestedSubroutine @@ -612,3 +617,16 @@ Note: Google Test filter = *DISABLED_* [----------] Global test environment tear-down [==========] 1 test from 1 test case ran. [ PASSED ] 1 test. +Note: Google Test filter = PassingTest.* +Note: This is test shard 1 of 2. +[==========] Running 1 test from 1 test case. +[----------] Global test environment set-up. +[----------] 1 test from PassingTest +[ RUN ] PassingTest.PassingTest2 +[ OK ] PassingTest.PassingTest2 +[----------] Global test environment tear-down +[==========] 1 test from 1 test case ran. +[ PASSED ] 1 test. + + YOU HAVE 1 DISABLED TEST + diff --git a/test/gtest_output_test_golden_win.txt b/test/gtest_output_test_golden_win.txt index 17be5c04..77903ba1 100644 --- a/test/gtest_output_test_golden_win.txt +++ b/test/gtest_output_test_golden_win.txt @@ -5,10 +5,15 @@ gtest_output_test_.cc:#: error: Value of: false Expected: true gtest_output_test_.cc:#: error: Value of: 3 Expected: 2 -[==========] Running 50 tests from 20 test cases. +[==========] Running 52 tests from 21 test cases. [----------] Global test environment set-up. FooEnvironment::SetUp() called. BarEnvironment::SetUp() called. +[----------] 2 tests from PassingTest +[ RUN ] PassingTest.PassingTest1 +[ OK ] PassingTest.PassingTest1 +[ RUN ] PassingTest.PassingTest2 +[ OK ] PassingTest.PassingTest2 [----------] 3 tests from FatalFailureTest [ RUN ] FatalFailureTest.FatalFailureInSubroutine (expecting a failure that x should be 1) @@ -440,8 +445,8 @@ Expected non-fatal failure. FooEnvironment::TearDown() called. gtest_output_test_.cc:#: error: Failed Expected fatal failure. -[==========] 50 tests from 20 test cases ran. -[ PASSED ] 14 tests. +[==========] 52 tests from 21 test cases ran. +[ PASSED ] 16 tests. [ FAILED ] 36 tests, listed below: [ FAILED ] FatalFailureTest.FatalFailureInSubroutine [ FAILED ] FatalFailureTest.FatalFailureInNestedSubroutine @@ -540,3 +545,16 @@ Note: Google Test filter = *DISABLED_* [----------] Global test environment tear-down [==========] 1 test from 1 test case ran. [ PASSED ] 1 test. +Note: Google Test filter = PassingTest.* +Note: This is test shard 1 of 2. +[==========] Running 1 test from 1 test case. +[----------] Global test environment set-up. +[----------] 1 test from PassingTest +[ RUN ] PassingTest.PassingTest2 +[ OK ] PassingTest.PassingTest2 +[----------] Global test environment tear-down +[==========] 1 test from 1 test case ran. +[ PASSED ] 1 test. + + YOU HAVE 1 DISABLED TEST + diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index 4bac8a69..335b9e06 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -138,7 +138,10 @@ using testing::internal::GetTestTypeId; using testing::internal::GetTypeId; using testing::internal::GTestFlagSaver; using testing::internal::Int32; +using testing::internal::Int32FromEnvOrDie; using testing::internal::List; +using testing::internal::ShouldRunTestOnShard; +using testing::internal::ShouldShard; using testing::internal::ShouldUseColor; using testing::internal::StreamableToString; using testing::internal::String; @@ -1375,6 +1378,161 @@ TEST(ParseInt32FlagTest, ParsesAndReturnsValidValue) { EXPECT_EQ(-789, value); } +// Tests that Int32FromEnvOrDie() parses the value of the var or +// returns the correct default. +TEST(Int32FromEnvOrDieTest, ParsesAndReturnsValidValue) { + EXPECT_EQ(333, Int32FromEnvOrDie(GTEST_FLAG_PREFIX_UPPER "UnsetVar", 333)); + SetEnv(GTEST_FLAG_PREFIX_UPPER "UnsetVar", "123"); + EXPECT_EQ(123, Int32FromEnvOrDie(GTEST_FLAG_PREFIX_UPPER "UnsetVar", 333)); + SetEnv(GTEST_FLAG_PREFIX_UPPER "UnsetVar", "-123"); + EXPECT_EQ(-123, Int32FromEnvOrDie(GTEST_FLAG_PREFIX_UPPER "UnsetVar", 333)); +} + +#ifdef GTEST_HAS_DEATH_TEST + +// Tests that Int32FromEnvOrDie() aborts with an error message +// if the variable is not an Int32. +TEST(Int32FromEnvOrDieDeathTest, AbortsOnFailure) { + SetEnv(GTEST_FLAG_PREFIX_UPPER "VAR", "xxx"); + EXPECT_DEATH({Int32FromEnvOrDie(GTEST_FLAG_PREFIX_UPPER "VAR", 123);}, + ".*"); +} + +// Tests that Int32FromEnvOrDie() aborts with an error message +// if the variable cannot be represnted by an Int32. +TEST(Int32FromEnvOrDieDeathTest, AbortsOnInt32Overflow) { + SetEnv(GTEST_FLAG_PREFIX_UPPER "VAR", "1234567891234567891234"); + EXPECT_DEATH({Int32FromEnvOrDie(GTEST_FLAG_PREFIX_UPPER "VAR", 123);}, + ".*"); +} + +#endif // GTEST_HAS_DEATH_TEST + + +// Tests that ShouldRunTestOnShard() selects all tests +// where there is 1 shard. +TEST(ShouldRunTestOnShardTest, IsPartitionWhenThereIsOneShard) { + EXPECT_TRUE(ShouldRunTestOnShard(1, 0, 0)); + EXPECT_TRUE(ShouldRunTestOnShard(1, 0, 1)); + EXPECT_TRUE(ShouldRunTestOnShard(1, 0, 2)); + EXPECT_TRUE(ShouldRunTestOnShard(1, 0, 3)); + EXPECT_TRUE(ShouldRunTestOnShard(1, 0, 4)); +} + +class ShouldShardTest : public testing::Test { + protected: + virtual void SetUp() { + index_var_ = GTEST_FLAG_PREFIX_UPPER "INDEX"; + total_var_ = GTEST_FLAG_PREFIX_UPPER "TOTAL"; + } + + virtual void TearDown() { + SetEnv(index_var_, ""); + SetEnv(total_var_, ""); + } + + const char* index_var_; + const char* total_var_; +}; + +// Tests that sharding is disabled if neither of the environment variables +// are set. +TEST_F(ShouldShardTest, ReturnsFalseWhenNeitherEnvVarIsSet) { + SetEnv(index_var_, ""); + SetEnv(total_var_, ""); + + EXPECT_FALSE(ShouldShard(total_var_, index_var_, false)); + EXPECT_FALSE(ShouldShard(total_var_, index_var_, true)); +} + +// Tests that sharding is not enabled if total_shards == 1. +TEST_F(ShouldShardTest, ReturnsFalseWhenTotalShardIsOne) { + SetEnv(index_var_, "0"); + SetEnv(total_var_, "1"); + EXPECT_FALSE(ShouldShard(total_var_, index_var_, false)); + EXPECT_FALSE(ShouldShard(total_var_, index_var_, true)); +} + +// Tests that sharding is enabled if total_shards > 1 and +// we are not in a death test subprocess. +TEST_F(ShouldShardTest, WorksWhenShardEnvVarsAreValid) { + SetEnv(index_var_, "4"); + SetEnv(total_var_, "22"); + EXPECT_TRUE(ShouldShard(total_var_, index_var_, false)); + EXPECT_FALSE(ShouldShard(total_var_, index_var_, true)); + + SetEnv(index_var_, "8"); + SetEnv(total_var_, "9"); + EXPECT_TRUE(ShouldShard(total_var_, index_var_, false)); + EXPECT_FALSE(ShouldShard(total_var_, index_var_, true)); + + SetEnv(index_var_, "0"); + SetEnv(total_var_, "9"); + EXPECT_TRUE(ShouldShard(total_var_, index_var_, false)); + EXPECT_FALSE(ShouldShard(total_var_, index_var_, true)); +} + +#ifdef GTEST_HAS_DEATH_TEST + +// Tests that we exit in error if the sharding values are not valid. +TEST_F(ShouldShardTest, AbortsWhenShardingEnvVarsAreInvalid) { + SetEnv(index_var_, "4"); + SetEnv(total_var_, "4"); + EXPECT_DEATH({ShouldShard(total_var_, index_var_, false);}, + ".*"); + + SetEnv(index_var_, "4"); + SetEnv(total_var_, "-2"); + EXPECT_DEATH({ShouldShard(total_var_, index_var_, false);}, + ".*"); + + SetEnv(index_var_, "5"); + SetEnv(total_var_, ""); + EXPECT_DEATH({ShouldShard(total_var_, index_var_, false);}, + ".*"); + + SetEnv(index_var_, ""); + SetEnv(total_var_, "5"); + EXPECT_DEATH({ShouldShard(total_var_, index_var_, false);}, + ".*"); +} + +#endif // GTEST_HAS_DEATH_TEST + +// Tests that ShouldRunTestOnShard is a partition when 5 +// shards are used. +TEST(ShouldRunTestOnShardTest, IsPartitionWhenThereAreFiveShards) { + // Choose an arbitrary number of tests and shards. + const int num_tests = 17; + const int num_shards = 5; + + // Check partitioning: each test should be on exactly 1 shard. + for (int test_id = 0; test_id < num_tests; test_id++) { + int prev_selected_shard_index = -1; + for (int shard_index = 0; shard_index < num_shards; shard_index++) { + if (ShouldRunTestOnShard(num_shards, shard_index, test_id)) { + if (prev_selected_shard_index < 0) { + prev_selected_shard_index = shard_index; + } else { + ADD_FAILURE() << "Shard " << prev_selected_shard_index << " and " + << shard_index << " are both selected to run test " << test_id; + } + } + } + } + + // Check balance: This is not required by the sharding protocol, but is a + // desirable property for performance. + for (int shard_index = 0; shard_index < num_shards; shard_index++) { + int num_tests_on_shard = 0; + for (int test_id = 0; test_id < num_tests; test_id++) { + num_tests_on_shard += + ShouldRunTestOnShard(num_shards, shard_index, test_id); + } + EXPECT_GE(num_tests_on_shard, num_tests / num_shards); + } +} + // For the same reason we are not explicitly testing everything in the // Test class, there are no separate tests for the following classes // (except for some trivial cases): -- cgit v1.2.3 From a5391b50a28bc27deb48a5f6624305bbf58c6175 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Mon, 9 Feb 2009 19:56:02 +0000 Subject: Adds gtest_all_test.cc. Also cleans up gtest_unittest.cc. --- test/gtest_all_test.cc | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ test/gtest_unittest.cc | 19 ------------------- 2 files changed, 48 insertions(+), 19 deletions(-) create mode 100644 test/gtest_all_test.cc (limited to 'test') diff --git a/test/gtest_all_test.cc b/test/gtest_all_test.cc new file mode 100644 index 00000000..f73044d8 --- /dev/null +++ b/test/gtest_all_test.cc @@ -0,0 +1,48 @@ +// Copyright 2009, 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) +// +// Tests for Google C++ Testing Framework (Google Test) +// +// Sometimes it's desirable to build most of Google Test's own tests +// by compiling a single file. This file serves this purpose. +#include "test/gtest_environment_test.cc" +#include "test/gtest-filepath_test.cc" +#include "test/gtest-linked_ptr_test.cc" +#include "test/gtest-message_test.cc" +#include "test/gtest-options_test.cc" +#include "test/gtest-port_test.cc" +#include "test/gtest_pred_impl_unittest.cc" +#include "test/gtest_prod_test.cc" +#include "test/gtest-test-part_test.cc" +#include "test/gtest-typed-test_test.cc" +#include "test/gtest-typed-test2_test.cc" +#include "test/gtest_unittest.cc" +#include "test/production.cc" diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index 335b9e06..f8dbff0f 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -5389,22 +5389,3 @@ TEST(GetCurrentOsStackTraceExceptTopTest, ReturnsTheStackTrace) { EXPECT_STREQ("", GetCurrentOsStackTraceExceptTop(unit_test, 0).c_str()); EXPECT_STREQ("", GetCurrentOsStackTraceExceptTop(unit_test, 1).c_str()); } - -#ifndef GTEST_OS_SYMBIAN -// We will want to integrate running the unittests to a different -// main application on Symbian. -int main(int argc, char** argv) { - testing::InitGoogleTest(&argc, argv); - -#ifdef GTEST_HAS_DEATH_TEST - if (!testing::internal::GTEST_FLAG(internal_run_death_test).empty()) { - // Skip the usual output capturing if we're running as the child - // process of an threadsafe-style death test. - freopen("/dev/null", "w", stdout); - } -#endif // GTEST_HAS_DEATH_TEST - - // Runs all tests using Google Test. - return RUN_ALL_TESTS(); -} -#endif // GTEST_OS_SYMBIAN -- cgit v1.2.3 From 0af0709b02899f9177db55eba7929e65e5834b29 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Mon, 23 Feb 2009 23:21:55 +0000 Subject: Cleans up macro definitions. --- test/gtest-death-test_test.cc | 6 +- test/gtest-filepath_test.cc | 170 ++++++++++++++------------- test/gtest-options_test.cc | 18 +-- test/gtest-param-test2_test.cc | 2 +- test/gtest-param-test_test.cc | 14 +-- test/gtest-param-test_test.h | 2 +- test/gtest-port_test.cc | 6 +- test/gtest-test-part_test.cc | 2 +- test/gtest-typed-test2_test.cc | 2 +- test/gtest-typed-test_test.cc | 6 +- test/gtest-typed-test_test.h | 2 +- test/gtest_break_on_failure_unittest_.cc | 4 +- test/gtest_env_var_test_.cc | 4 +- test/gtest_filter_unittest_.cc | 6 +- test/gtest_output_test_.cc | 20 ++-- test/gtest_repeat_test.cc | 16 +-- test/gtest_stress_test.cc | 4 +- test/gtest_unittest.cc | 196 +++++++++++++++---------------- 18 files changed, 243 insertions(+), 237 deletions(-) (limited to 'test') diff --git a/test/gtest-death-test_test.cc b/test/gtest-death-test_test.cc index 204ec413..6d8a3f89 100644 --- a/test/gtest-death-test_test.cc +++ b/test/gtest-death-test_test.cc @@ -34,7 +34,7 @@ #include #include -#ifdef GTEST_HAS_DEATH_TEST +#if GTEST_HAS_DEATH_TEST #include #include @@ -45,9 +45,9 @@ // included, or there will be a compiler error. This trick is to // prevent a user from accidentally including gtest-internal-inl.h in // his code. -#define GTEST_IMPLEMENTATION +#define GTEST_IMPLEMENTATION_ 1 #include "src/gtest-internal-inl.h" -#undef GTEST_IMPLEMENTATION +#undef GTEST_IMPLEMENTATION_ using testing::internal::DeathTest; using testing::internal::DeathTestFactory; diff --git a/test/gtest-filepath_test.cc b/test/gtest-filepath_test.cc index ee80f0d9..dfbd5f02 100644 --- a/test/gtest-filepath_test.cc +++ b/test/gtest-filepath_test.cc @@ -46,19 +46,19 @@ // included, or there will be a compiler error. This trick is to // prevent a user from accidentally including gtest-internal-inl.h in // his code. -#define GTEST_IMPLEMENTATION +#define GTEST_IMPLEMENTATION_ 1 #include "src/gtest-internal-inl.h" -#undef GTEST_IMPLEMENTATION +#undef GTEST_IMPLEMENTATION_ -#ifdef GTEST_OS_WINDOWS +#if GTEST_OS_WINDOWS #ifdef _WIN32_WCE #include // NOLINT #else #include // NOLINT #endif // _WIN32_WCE -#define PATH_SEP "\\" +#define GTEST_PATH_SEP_ "\\" #else -#define PATH_SEP "/" +#define GTEST_PATH_SEP_ "/" #endif // GTEST_OS_WINDOWS namespace testing { @@ -90,16 +90,16 @@ int _rmdir(const char* path) { TEST(GetCurrentDirTest, ReturnsCurrentDir) { EXPECT_FALSE(FilePath::GetCurrentDir().IsEmpty()); -#ifdef GTEST_OS_WINDOWS - _chdir(PATH_SEP); +#if GTEST_OS_WINDOWS + _chdir(GTEST_PATH_SEP_); const FilePath cwd = FilePath::GetCurrentDir(); // Skips the ":". const char* const cwd_without_drive = strchr(cwd.c_str(), ':'); ASSERT_TRUE(cwd_without_drive != NULL); - EXPECT_STREQ(PATH_SEP, cwd_without_drive + 1); + EXPECT_STREQ(GTEST_PATH_SEP_, cwd_without_drive + 1); #else - chdir(PATH_SEP); - EXPECT_STREQ(PATH_SEP, FilePath::GetCurrentDir().c_str()); + chdir(GTEST_PATH_SEP_); + EXPECT_STREQ(GTEST_PATH_SEP_, FilePath::GetCurrentDir().c_str()); #endif } @@ -131,25 +131,25 @@ TEST(RemoveDirectoryNameTest, ButNoDirectory) { // RemoveDirectoryName "/afile" -> "afile" TEST(RemoveDirectoryNameTest, RootFileShouldGiveFileName) { EXPECT_STREQ("afile", - FilePath(PATH_SEP "afile").RemoveDirectoryName().c_str()); + FilePath(GTEST_PATH_SEP_ "afile").RemoveDirectoryName().c_str()); } // RemoveDirectoryName "adir/" -> "" TEST(RemoveDirectoryNameTest, WhereThereIsNoFileName) { EXPECT_STREQ("", - FilePath("adir" PATH_SEP).RemoveDirectoryName().c_str()); + FilePath("adir" GTEST_PATH_SEP_).RemoveDirectoryName().c_str()); } // RemoveDirectoryName "adir/afile" -> "afile" TEST(RemoveDirectoryNameTest, ShouldGiveFileName) { EXPECT_STREQ("afile", - FilePath("adir" PATH_SEP "afile").RemoveDirectoryName().c_str()); + FilePath("adir" GTEST_PATH_SEP_ "afile").RemoveDirectoryName().c_str()); } // RemoveDirectoryName "adir/subdir/afile" -> "afile" TEST(RemoveDirectoryNameTest, ShouldAlsoGiveFileName) { EXPECT_STREQ("afile", - FilePath("adir" PATH_SEP "subdir" PATH_SEP "afile") + FilePath("adir" GTEST_PATH_SEP_ "subdir" GTEST_PATH_SEP_ "afile") .RemoveDirectoryName().c_str()); } @@ -158,63 +158,63 @@ TEST(RemoveDirectoryNameTest, ShouldAlsoGiveFileName) { TEST(RemoveFileNameTest, EmptyName) { #ifdef _WIN32_WCE // On Windows CE, we use the root as the current directory. - EXPECT_STREQ(PATH_SEP, + EXPECT_STREQ(GTEST_PATH_SEP_, FilePath("").RemoveFileName().c_str()); #else - EXPECT_STREQ("." PATH_SEP, + EXPECT_STREQ("." GTEST_PATH_SEP_, FilePath("").RemoveFileName().c_str()); #endif } // RemoveFileName "adir/" -> "adir/" TEST(RemoveFileNameTest, ButNoFile) { - EXPECT_STREQ("adir" PATH_SEP, - FilePath("adir" PATH_SEP).RemoveFileName().c_str()); + EXPECT_STREQ("adir" GTEST_PATH_SEP_, + FilePath("adir" GTEST_PATH_SEP_).RemoveFileName().c_str()); } // RemoveFileName "adir/afile" -> "adir/" TEST(RemoveFileNameTest, GivesDirName) { - EXPECT_STREQ("adir" PATH_SEP, - FilePath("adir" PATH_SEP "afile") + EXPECT_STREQ("adir" GTEST_PATH_SEP_, + FilePath("adir" GTEST_PATH_SEP_ "afile") .RemoveFileName().c_str()); } // RemoveFileName "adir/subdir/afile" -> "adir/subdir/" TEST(RemoveFileNameTest, GivesDirAndSubDirName) { - EXPECT_STREQ("adir" PATH_SEP "subdir" PATH_SEP, - FilePath("adir" PATH_SEP "subdir" PATH_SEP "afile") + EXPECT_STREQ("adir" GTEST_PATH_SEP_ "subdir" GTEST_PATH_SEP_, + FilePath("adir" GTEST_PATH_SEP_ "subdir" GTEST_PATH_SEP_ "afile") .RemoveFileName().c_str()); } // RemoveFileName "/afile" -> "/" TEST(RemoveFileNameTest, GivesRootDir) { - EXPECT_STREQ(PATH_SEP, - FilePath(PATH_SEP "afile").RemoveFileName().c_str()); + EXPECT_STREQ(GTEST_PATH_SEP_, + FilePath(GTEST_PATH_SEP_ "afile").RemoveFileName().c_str()); } TEST(MakeFileNameTest, GenerateWhenNumberIsZero) { FilePath actual = FilePath::MakeFileName(FilePath("foo"), FilePath("bar"), 0, "xml"); - EXPECT_STREQ("foo" PATH_SEP "bar.xml", actual.c_str()); + EXPECT_STREQ("foo" GTEST_PATH_SEP_ "bar.xml", actual.c_str()); } TEST(MakeFileNameTest, GenerateFileNameNumberGtZero) { FilePath actual = FilePath::MakeFileName(FilePath("foo"), FilePath("bar"), 12, "xml"); - EXPECT_STREQ("foo" PATH_SEP "bar_12.xml", actual.c_str()); + EXPECT_STREQ("foo" GTEST_PATH_SEP_ "bar_12.xml", actual.c_str()); } TEST(MakeFileNameTest, GenerateFileNameWithSlashNumberIsZero) { - FilePath actual = FilePath::MakeFileName(FilePath("foo" PATH_SEP), + FilePath actual = FilePath::MakeFileName(FilePath("foo" GTEST_PATH_SEP_), FilePath("bar"), 0, "xml"); - EXPECT_STREQ("foo" PATH_SEP "bar.xml", actual.c_str()); + EXPECT_STREQ("foo" GTEST_PATH_SEP_ "bar.xml", actual.c_str()); } TEST(MakeFileNameTest, GenerateFileNameWithSlashNumberGtZero) { - FilePath actual = FilePath::MakeFileName(FilePath("foo" PATH_SEP), + FilePath actual = FilePath::MakeFileName(FilePath("foo" GTEST_PATH_SEP_), FilePath("bar"), 12, "xml"); - EXPECT_STREQ("foo" PATH_SEP "bar_12.xml", actual.c_str()); + EXPECT_STREQ("foo" GTEST_PATH_SEP_ "bar_12.xml", actual.c_str()); } TEST(MakeFileNameTest, GenerateWhenNumberIsZeroAndDirIsEmpty) { @@ -232,13 +232,13 @@ TEST(MakeFileNameTest, GenerateWhenNumberIsNotZeroAndDirIsEmpty) { TEST(ConcatPathsTest, WorksWhenDirDoesNotEndWithPathSep) { FilePath actual = FilePath::ConcatPaths(FilePath("foo"), FilePath("bar.xml")); - EXPECT_STREQ("foo" PATH_SEP "bar.xml", actual.c_str()); + EXPECT_STREQ("foo" GTEST_PATH_SEP_ "bar.xml", actual.c_str()); } TEST(ConcatPathsTest, WorksWhenPath1EndsWithPathSep) { - FilePath actual = FilePath::ConcatPaths(FilePath("foo" PATH_SEP), + FilePath actual = FilePath::ConcatPaths(FilePath("foo" GTEST_PATH_SEP_), FilePath("bar.xml")); - EXPECT_STREQ("foo" PATH_SEP "bar.xml", actual.c_str()); + EXPECT_STREQ("foo" GTEST_PATH_SEP_ "bar.xml", actual.c_str()); } TEST(ConcatPathsTest, Path1BeingEmpty) { @@ -250,7 +250,7 @@ TEST(ConcatPathsTest, Path1BeingEmpty) { TEST(ConcatPathsTest, Path2BeingEmpty) { FilePath actual = FilePath::ConcatPaths(FilePath("foo"), FilePath("")); - EXPECT_STREQ("foo" PATH_SEP, actual.c_str()); + EXPECT_STREQ("foo" GTEST_PATH_SEP_, actual.c_str()); } TEST(ConcatPathsTest, BothPathBeingEmpty) { @@ -260,21 +260,24 @@ TEST(ConcatPathsTest, BothPathBeingEmpty) { } TEST(ConcatPathsTest, Path1ContainsPathSep) { - FilePath actual = FilePath::ConcatPaths(FilePath("foo" PATH_SEP "bar"), + FilePath actual = FilePath::ConcatPaths(FilePath("foo" GTEST_PATH_SEP_ "bar"), FilePath("foobar.xml")); - EXPECT_STREQ("foo" PATH_SEP "bar" PATH_SEP "foobar.xml", actual.c_str()); + EXPECT_STREQ("foo" GTEST_PATH_SEP_ "bar" GTEST_PATH_SEP_ "foobar.xml", + actual.c_str()); } TEST(ConcatPathsTest, Path2ContainsPathSep) { - FilePath actual = FilePath::ConcatPaths(FilePath("foo" PATH_SEP), - FilePath("bar" PATH_SEP "bar.xml")); - EXPECT_STREQ("foo" PATH_SEP "bar" PATH_SEP "bar.xml", actual.c_str()); + FilePath actual = FilePath::ConcatPaths( + FilePath("foo" GTEST_PATH_SEP_), + FilePath("bar" GTEST_PATH_SEP_ "bar.xml")); + EXPECT_STREQ("foo" GTEST_PATH_SEP_ "bar" GTEST_PATH_SEP_ "bar.xml", + actual.c_str()); } TEST(ConcatPathsTest, Path2EndsWithPathSep) { FilePath actual = FilePath::ConcatPaths(FilePath("foo"), - FilePath("bar" PATH_SEP)); - EXPECT_STREQ("foo" PATH_SEP "bar" PATH_SEP, actual.c_str()); + FilePath("bar" GTEST_PATH_SEP_)); + EXPECT_STREQ("foo" GTEST_PATH_SEP_ "bar" GTEST_PATH_SEP_, actual.c_str()); } // RemoveTrailingPathSeparator "" -> "" @@ -291,25 +294,27 @@ TEST(RemoveTrailingPathSeparatorTest, FileNoSlashString) { // RemoveTrailingPathSeparator "foo/" -> "foo" TEST(RemoveTrailingPathSeparatorTest, ShouldRemoveTrailingSeparator) { - EXPECT_STREQ("foo", - FilePath("foo" PATH_SEP).RemoveTrailingPathSeparator().c_str()); + EXPECT_STREQ( + "foo", + FilePath("foo" GTEST_PATH_SEP_).RemoveTrailingPathSeparator().c_str()); } // RemoveTrailingPathSeparator "foo/bar/" -> "foo/bar/" TEST(RemoveTrailingPathSeparatorTest, ShouldRemoveLastSeparator) { - EXPECT_STREQ("foo" PATH_SEP "bar", - FilePath("foo" PATH_SEP "bar" PATH_SEP).RemoveTrailingPathSeparator() - .c_str()); + EXPECT_STREQ("foo" GTEST_PATH_SEP_ "bar", + FilePath("foo" GTEST_PATH_SEP_ "bar" GTEST_PATH_SEP_) + .RemoveTrailingPathSeparator().c_str()); } // RemoveTrailingPathSeparator "foo/bar" -> "foo/bar" TEST(RemoveTrailingPathSeparatorTest, ShouldReturnUnmodified) { - EXPECT_STREQ("foo" PATH_SEP "bar", - FilePath("foo" PATH_SEP "bar").RemoveTrailingPathSeparator().c_str()); + EXPECT_STREQ("foo" GTEST_PATH_SEP_ "bar", + FilePath("foo" GTEST_PATH_SEP_ "bar") + .RemoveTrailingPathSeparator().c_str()); } TEST(DirectoryTest, RootDirectoryExists) { -#ifdef GTEST_OS_WINDOWS // We are on Windows. +#if GTEST_OS_WINDOWS // We are on Windows. char current_drive[_MAX_PATH]; // NOLINT current_drive[0] = static_cast(_getdrive() + 'A' - 1); current_drive[1] = ':'; @@ -321,7 +326,7 @@ TEST(DirectoryTest, RootDirectoryExists) { #endif // GTEST_OS_WINDOWS } -#ifdef GTEST_OS_WINDOWS +#if GTEST_OS_WINDOWS TEST(DirectoryTest, RootOfWrongDriveDoesNotExists) { const int saved_drive_ = _getdrive(); // Find a drive that doesn't exist. Start with 'Z' to avoid common ones. @@ -347,7 +352,7 @@ TEST(DirectoryTest, EmptyPathDirectoryDoesNotExist) { #endif // ! _WIN32_WCE TEST(DirectoryTest, CurrentDirectoryExists) { -#ifdef GTEST_OS_WINDOWS // We are on Windows. +#if GTEST_OS_WINDOWS // We are on Windows. #ifndef _WIN32_CE // Windows CE doesn't have a current directory. EXPECT_TRUE(FilePath(".").DirectoryExists()); EXPECT_TRUE(FilePath(".\\").DirectoryExists()); @@ -365,32 +370,33 @@ TEST(NormalizeTest, NullStringsEqualEmptyDirectory) { // "foo/bar" == foo//bar" == "foo///bar" TEST(NormalizeTest, MultipleConsecutiveSepaparatorsInMidstring) { - EXPECT_STREQ("foo" PATH_SEP "bar", - FilePath("foo" PATH_SEP "bar").c_str()); - EXPECT_STREQ("foo" PATH_SEP "bar", - FilePath("foo" PATH_SEP PATH_SEP "bar").c_str()); - EXPECT_STREQ("foo" PATH_SEP "bar", - FilePath("foo" PATH_SEP PATH_SEP PATH_SEP "bar").c_str()); + EXPECT_STREQ("foo" GTEST_PATH_SEP_ "bar", + FilePath("foo" GTEST_PATH_SEP_ "bar").c_str()); + EXPECT_STREQ("foo" GTEST_PATH_SEP_ "bar", + FilePath("foo" GTEST_PATH_SEP_ GTEST_PATH_SEP_ "bar").c_str()); + EXPECT_STREQ("foo" GTEST_PATH_SEP_ "bar", + FilePath("foo" GTEST_PATH_SEP_ GTEST_PATH_SEP_ + GTEST_PATH_SEP_ "bar").c_str()); } // "/bar" == //bar" == "///bar" TEST(NormalizeTest, MultipleConsecutiveSepaparatorsAtStringStart) { - EXPECT_STREQ(PATH_SEP "bar", - FilePath(PATH_SEP "bar").c_str()); - EXPECT_STREQ(PATH_SEP "bar", - FilePath(PATH_SEP PATH_SEP "bar").c_str()); - EXPECT_STREQ(PATH_SEP "bar", - FilePath(PATH_SEP PATH_SEP PATH_SEP "bar").c_str()); + EXPECT_STREQ(GTEST_PATH_SEP_ "bar", + FilePath(GTEST_PATH_SEP_ "bar").c_str()); + EXPECT_STREQ(GTEST_PATH_SEP_ "bar", + FilePath(GTEST_PATH_SEP_ GTEST_PATH_SEP_ "bar").c_str()); + EXPECT_STREQ(GTEST_PATH_SEP_ "bar", + FilePath(GTEST_PATH_SEP_ GTEST_PATH_SEP_ GTEST_PATH_SEP_ "bar").c_str()); } // "foo/" == foo//" == "foo///" TEST(NormalizeTest, MultipleConsecutiveSepaparatorsAtStringEnd) { - EXPECT_STREQ("foo" PATH_SEP, - FilePath("foo" PATH_SEP).c_str()); - EXPECT_STREQ("foo" PATH_SEP, - FilePath("foo" PATH_SEP PATH_SEP).c_str()); - EXPECT_STREQ("foo" PATH_SEP, - FilePath("foo" PATH_SEP PATH_SEP PATH_SEP).c_str()); + EXPECT_STREQ("foo" GTEST_PATH_SEP_, + FilePath("foo" GTEST_PATH_SEP_).c_str()); + EXPECT_STREQ("foo" GTEST_PATH_SEP_, + FilePath("foo" GTEST_PATH_SEP_ GTEST_PATH_SEP_).c_str()); + EXPECT_STREQ("foo" GTEST_PATH_SEP_, + FilePath("foo" GTEST_PATH_SEP_ GTEST_PATH_SEP_ GTEST_PATH_SEP_).c_str()); } TEST(AssignmentOperatorTest, DefaultAssignedToNonDefault) { @@ -421,7 +427,7 @@ class DirectoryCreationTest : public Test { virtual void SetUp() { testdata_path_.Set(FilePath(String::Format("%s%s%s", TempDir().c_str(), GetCurrentExecutableName().c_str(), - "_directory_creation" PATH_SEP "test" PATH_SEP))); + "_directory_creation" GTEST_PATH_SEP_ "test" GTEST_PATH_SEP_))); testdata_file_.Set(testdata_path_.RemoveTrailingPathSeparator()); unique_file0_.Set(FilePath::MakeFileName(testdata_path_, FilePath("unique"), @@ -432,7 +438,7 @@ class DirectoryCreationTest : public Test { remove(testdata_file_.c_str()); remove(unique_file0_.c_str()); remove(unique_file1_.c_str()); -#ifdef GTEST_OS_WINDOWS +#if GTEST_OS_WINDOWS _rmdir(testdata_path_.c_str()); #else rmdir(testdata_path_.c_str()); @@ -443,7 +449,7 @@ class DirectoryCreationTest : public Test { remove(testdata_file_.c_str()); remove(unique_file0_.c_str()); remove(unique_file1_.c_str()); -#ifdef GTEST_OS_WINDOWS +#if GTEST_OS_WINDOWS _rmdir(testdata_path_.c_str()); #else rmdir(testdata_path_.c_str()); @@ -454,7 +460,7 @@ class DirectoryCreationTest : public Test { #ifdef _WIN32_WCE return String("\\temp\\"); -#elif defined(GTEST_OS_WINDOWS) +#elif GTEST_OS_WINDOWS // MSVC 8 deprecates getenv(), so we want to suppress warning 4996 // (deprecated function) there. #pragma warning(push) // Saves the current warning state. @@ -474,7 +480,7 @@ class DirectoryCreationTest : public Test { } void CreateTextFile(const char* filename) { -#ifdef GTEST_OS_WINDOWS +#if GTEST_OS_WINDOWS // MSVC 8 deprecates fopen(), so we want to suppress warning 4996 // (deprecated function) there.#pragma warning(push) #pragma warning(push) // Saves the current warning state. @@ -585,18 +591,18 @@ TEST(FilePathTest, RemoveExtensionWhenThereIsNoExtension) { TEST(FilePathTest, IsDirectory) { EXPECT_FALSE(FilePath("cola").IsDirectory()); - EXPECT_TRUE(FilePath("koala" PATH_SEP).IsDirectory()); + EXPECT_TRUE(FilePath("koala" GTEST_PATH_SEP_).IsDirectory()); } TEST(FilePathTest, IsAbsolutePath) { - EXPECT_FALSE(FilePath("is" PATH_SEP "relative").IsAbsolutePath()); + EXPECT_FALSE(FilePath("is" GTEST_PATH_SEP_ "relative").IsAbsolutePath()); EXPECT_FALSE(FilePath("").IsAbsolutePath()); -#ifdef GTEST_OS_WINDOWS - EXPECT_TRUE(FilePath("c:\\" PATH_SEP "is_not" PATH_SEP "relative") - .IsAbsolutePath()); - EXPECT_FALSE(FilePath("c:foo" PATH_SEP "bar").IsAbsolutePath()); +#if GTEST_OS_WINDOWS + EXPECT_TRUE(FilePath("c:\\" GTEST_PATH_SEP_ "is_not" + GTEST_PATH_SEP_ "relative").IsAbsolutePath()); + EXPECT_FALSE(FilePath("c:foo" GTEST_PATH_SEP_ "bar").IsAbsolutePath()); #else - EXPECT_TRUE(FilePath(PATH_SEP "is_not" PATH_SEP "relative") + EXPECT_TRUE(FilePath(GTEST_PATH_SEP_ "is_not" GTEST_PATH_SEP_ "relative") .IsAbsolutePath()); #endif // GTEST_OS_WINDOWS } @@ -605,4 +611,4 @@ TEST(FilePathTest, IsAbsolutePath) { } // namespace internal } // namespace testing -#undef PATH_SEP +#undef GTEST_PATH_SEP_ diff --git a/test/gtest-options_test.cc b/test/gtest-options_test.cc index e3e7bd79..5f24e7e3 100644 --- a/test/gtest-options_test.cc +++ b/test/gtest-options_test.cc @@ -42,7 +42,7 @@ #ifdef _WIN32_WCE #include -#elif defined(GTEST_OS_WINDOWS) +#elif GTEST_OS_WINDOWS #include #endif // _WIN32_WCE @@ -51,9 +51,9 @@ // included, or there will be a compiler error. This trick is to // prevent a user from accidentally including gtest-internal-inl.h in // his code. -#define GTEST_IMPLEMENTATION +#define GTEST_IMPLEMENTATION_ 1 #include "src/gtest-internal-inl.h" -#undef GTEST_IMPLEMENTATION +#undef GTEST_IMPLEMENTATION_ namespace testing { namespace internal { @@ -89,7 +89,7 @@ TEST(XmlOutputTest, GetOutputFileSingleFile) { } TEST(XmlOutputTest, GetOutputFileFromDirectoryPath) { -#ifdef GTEST_OS_WINDOWS +#if GTEST_OS_WINDOWS GTEST_FLAG(output) = "xml:path\\"; const String& output_file = UnitTestOptions::GetAbsolutePathToOutputFile(); EXPECT_TRUE( @@ -121,7 +121,7 @@ TEST(XmlOutputTest, GetOutputFileFromDirectoryPath) { TEST(OutputFileHelpersTest, GetCurrentExecutableName) { const FilePath executable = GetCurrentExecutableName(); const char* const exe_str = executable.c_str(); -#if defined(_WIN32_WCE) || defined(GTEST_OS_WINDOWS) +#if defined(_WIN32_WCE) || GTEST_OS_WINDOWS ASSERT_TRUE(_strcmpi("gtest-options_test", exe_str) == 0 || _strcmpi("gtest-options-ex_test", exe_str) == 0) << "GetCurrentExecutableName() returns " << exe_str; @@ -149,7 +149,7 @@ class XmlOutputChangeDirTest : public Test { } void ChDir(const char* dir) { -#ifdef GTEST_OS_WINDOWS +#if GTEST_OS_WINDOWS _chdir(dir); #else chdir(dir); @@ -181,7 +181,7 @@ TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithRelativeFile) { } TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithRelativePath) { -#ifdef GTEST_OS_WINDOWS +#if GTEST_OS_WINDOWS GTEST_FLAG(output) = "xml:path\\"; const String& output_file = UnitTestOptions::GetAbsolutePathToOutputFile(); EXPECT_TRUE( @@ -211,7 +211,7 @@ TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithRelativePath) { } TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithAbsoluteFile) { -#ifdef GTEST_OS_WINDOWS +#if GTEST_OS_WINDOWS GTEST_FLAG(output) = "xml:c:\\tmp\\filename.abc"; EXPECT_STREQ(FilePath("c:\\tmp\\filename.abc").c_str(), UnitTestOptions::GetAbsolutePathToOutputFile().c_str()); @@ -223,7 +223,7 @@ TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithAbsoluteFile) { } TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithAbsolutePath) { -#ifdef GTEST_OS_WINDOWS +#if GTEST_OS_WINDOWS GTEST_FLAG(output) = "xml:c:\\tmp\\"; const String& output_file = UnitTestOptions::GetAbsolutePathToOutputFile(); EXPECT_TRUE( diff --git a/test/gtest-param-test2_test.cc b/test/gtest-param-test2_test.cc index 4e54206d..ccb6cfac 100644 --- a/test/gtest-param-test2_test.cc +++ b/test/gtest-param-test2_test.cc @@ -36,7 +36,7 @@ #include "test/gtest-param-test_test.h" -#ifdef GTEST_HAS_PARAM_TEST +#if GTEST_HAS_PARAM_TEST using ::testing::Values; using ::testing::internal::ParamGenerator; diff --git a/test/gtest-param-test_test.cc b/test/gtest-param-test_test.cc index 22ba1a34..63080216 100644 --- a/test/gtest-param-test_test.cc +++ b/test/gtest-param-test_test.cc @@ -35,7 +35,7 @@ #include -#ifdef GTEST_HAS_PARAM_TEST +#if GTEST_HAS_PARAM_TEST #include #include @@ -43,9 +43,9 @@ #include // To include gtest-internal-inl.h. -#define GTEST_IMPLEMENTATION +#define GTEST_IMPLEMENTATION_ 1 #include "src/gtest-internal-inl.h" // for UnitTestOptions -#undef GTEST_IMPLEMENTATION +#undef GTEST_IMPLEMENTATION_ #include "test/gtest-param-test_test.h" @@ -60,7 +60,7 @@ using ::testing::TestWithParam; using ::testing::Values; using ::testing::ValuesIn; -#ifdef GTEST_HAS_COMBINE +#if GTEST_HAS_COMBINE using ::testing::Combine; using ::std::tr1::get; using ::std::tr1::make_tuple; @@ -398,7 +398,7 @@ TEST(BoolTest, BoolWorks) { VerifyGenerator(gen, expected_values); } -#ifdef GTEST_HAS_COMBINE +#if GTEST_HAS_COMBINE template ::std::ostream& operator<<(::std::ostream& stream, const tuple& value) { @@ -774,13 +774,13 @@ INSTANTIATE_TEST_CASE_P(ZeroToFiveSequence, NamingTest, Range(0, 5)); #endif // GTEST_HAS_PARAM_TEST TEST(CompileTest, CombineIsDefinedOnlyWhenGtestHasParamTestIsDefined) { -#if defined(GTEST_HAS_COMBINE) && !defined(GTEST_HAS_PARAM_TEST) +#if GTEST_HAS_COMBINE && !GTEST_HAS_PARAM_TEST FAIL() << "GTEST_HAS_COMBINE is defined while GTEST_HAS_PARAM_TEST is not\n" #endif } int main(int argc, char **argv) { -#ifdef GTEST_HAS_PARAM_TEST +#if GTEST_HAS_PARAM_TEST // Used in TestGenerationTest test case. AddGlobalTestEnvironment(TestGenerationTest::Environment::Instance()); // Used in GeneratorEvaluationTest test case. diff --git a/test/gtest-param-test_test.h b/test/gtest-param-test_test.h index ee7bea00..b7f94936 100644 --- a/test/gtest-param-test_test.h +++ b/test/gtest-param-test_test.h @@ -39,7 +39,7 @@ #include -#ifdef GTEST_HAS_PARAM_TEST +#if GTEST_HAS_PARAM_TEST // Test fixture for testing definition and instantiation of a test // in separate translation units. diff --git a/test/gtest-port_test.cc b/test/gtest-port_test.cc index 0041c911..40d36bd1 100644 --- a/test/gtest-port_test.cc +++ b/test/gtest-port_test.cc @@ -40,9 +40,9 @@ // included, or there will be a compiler error. This trick is to // prevent a user from accidentally including gtest-internal-inl.h in // his code. -#define GTEST_IMPLEMENTATION +#define GTEST_IMPLEMENTATION_ 1 #include "src/gtest-internal-inl.h" -#undef GTEST_IMPLEMENTATION +#undef GTEST_IMPLEMENTATION_ namespace testing { namespace internal { @@ -76,7 +76,7 @@ TEST(GtestCheckSyntaxTest, WorksWithSwitch) { GTEST_CHECK_(true) << "Check failed in switch case"; } -#ifdef GTEST_HAS_DEATH_TEST +#if GTEST_HAS_DEATH_TEST TEST(GtestCheckDeathTest, DiesWithCorrectOutputOnFailure) { const bool a_false_condition = false; diff --git a/test/gtest-test-part_test.cc b/test/gtest-test-part_test.cc index f4f0d1d5..f9e2e5d3 100644 --- a/test/gtest-test-part_test.cc +++ b/test/gtest-test-part_test.cc @@ -117,7 +117,7 @@ TEST_F(TestPartResultArrayTest, ContainsGivenResultsAfterTwoAppends) { EXPECT_STREQ("Failure 2", results.GetTestPartResult(1).message()); } -#ifdef GTEST_HAS_DEATH_TEST +#if GTEST_HAS_DEATH_TEST typedef TestPartResultArrayTest TestPartResultArrayDeathTest; diff --git a/test/gtest-typed-test2_test.cc b/test/gtest-typed-test2_test.cc index 7dabe760..79a8a87d 100644 --- a/test/gtest-typed-test2_test.cc +++ b/test/gtest-typed-test2_test.cc @@ -34,7 +34,7 @@ #include "test/gtest-typed-test_test.h" #include -#ifdef GTEST_HAS_TYPED_TEST_P +#if GTEST_HAS_TYPED_TEST_P // Tests that the same type-parameterized test case can be // instantiated in different translation units linked together. diff --git a/test/gtest-typed-test_test.cc b/test/gtest-typed-test_test.cc index ec03c95d..9ba9675f 100644 --- a/test/gtest-typed-test_test.cc +++ b/test/gtest-typed-test_test.cc @@ -82,7 +82,7 @@ template T* CommonTest::shared_ = NULL; // This #ifdef block tests typed tests. -#ifdef GTEST_HAS_TYPED_TEST +#if GTEST_HAS_TYPED_TEST using testing::Types; @@ -166,7 +166,7 @@ TYPED_TEST(NumericTest, DefaultIsZero) { #endif // GTEST_HAS_TYPED_TEST // This #ifdef block tests type-parameterized tests. -#ifdef GTEST_HAS_TYPED_TEST_P +#if GTEST_HAS_TYPED_TEST_P using testing::Types; using testing::internal::TypedTestCasePState; @@ -198,7 +198,7 @@ TEST_F(TypedTestCasePStateTest, IgnoresOrderAndSpaces) { state_.VerifyRegisteredTestNames("foo.cc", 1, tests)); } -#ifdef GTEST_HAS_DEATH_TEST +#if GTEST_HAS_DEATH_TEST typedef TypedTestCasePStateTest TypedTestCasePStateDeathTest; diff --git a/test/gtest-typed-test_test.h b/test/gtest-typed-test_test.h index 2e89dc4b..ecbe5b31 100644 --- a/test/gtest-typed-test_test.h +++ b/test/gtest-typed-test_test.h @@ -34,7 +34,7 @@ #include -#ifdef GTEST_HAS_TYPED_TEST_P +#if GTEST_HAS_TYPED_TEST_P using testing::Test; diff --git a/test/gtest_break_on_failure_unittest_.cc b/test/gtest_break_on_failure_unittest_.cc index 84c4a2ee..26b5bd3c 100644 --- a/test/gtest_break_on_failure_unittest_.cc +++ b/test/gtest_break_on_failure_unittest_.cc @@ -41,7 +41,7 @@ #include -#ifdef GTEST_OS_WINDOWS +#if GTEST_OS_WINDOWS #include #endif @@ -56,7 +56,7 @@ TEST(Foo, Bar) { int main(int argc, char **argv) { -#ifdef GTEST_OS_WINDOWS +#if GTEST_OS_WINDOWS // Suppresses display of the Windows error dialog upon encountering // a general protection fault (segment violation). SetErrorMode(SEM_NOGPFAULTERRORBOX | SEM_FAILCRITICALERRORS); diff --git a/test/gtest_env_var_test_.cc b/test/gtest_env_var_test_.cc index bbccd462..dd820e44 100644 --- a/test/gtest_env_var_test_.cc +++ b/test/gtest_env_var_test_.cc @@ -36,9 +36,9 @@ #include -#define GTEST_IMPLEMENTATION +#define GTEST_IMPLEMENTATION_ 1 #include "src/gtest-internal-inl.h" -#undef GTEST_IMPLEMENTATION +#undef GTEST_IMPLEMENTATION_ using ::std::cout; diff --git a/test/gtest_filter_unittest_.cc b/test/gtest_filter_unittest_.cc index 22638e0d..dd4f7167 100644 --- a/test/gtest_filter_unittest_.cc +++ b/test/gtest_filter_unittest_.cc @@ -94,7 +94,7 @@ TEST(BazTest, DISABLED_TestC) { // Test case HasDeathTest TEST(HasDeathTest, Test1) { -#ifdef GTEST_HAS_DEATH_TEST +#if GTEST_HAS_DEATH_TEST EXPECT_DEATH({exit(1);}, ".*"); #endif // GTEST_HAS_DEATH_TEST @@ -103,7 +103,7 @@ TEST(HasDeathTest, Test1) { // We need at least two death tests to make sure that the all death tests // aren't on the first shard. TEST(HasDeathTest, Test2) { -#ifdef GTEST_HAS_DEATH_TEST +#if GTEST_HAS_DEATH_TEST EXPECT_DEATH({exit(1);}, ".*"); #endif // GTEST_HAS_DEATH_TEST @@ -126,7 +126,7 @@ TEST(DISABLED_FoobarbazTest, TestA) { FAIL() << "Expected failure."; } -#ifdef GTEST_HAS_PARAM_TEST +#if GTEST_HAS_PARAM_TEST class ParamTest : public testing::TestWithParam { }; diff --git a/test/gtest_output_test_.cc b/test/gtest_output_test_.cc index f5748d17..a8ffa412 100644 --- a/test/gtest_output_test_.cc +++ b/test/gtest_output_test_.cc @@ -40,9 +40,9 @@ // included, or there will be a compiler error. This trick is to // prevent a user from accidentally including gtest-internal-inl.h in // his code. -#define GTEST_IMPLEMENTATION +#define GTEST_IMPLEMENTATION_ 1 #include "src/gtest-internal-inl.h" -#undef GTEST_IMPLEMENTATION +#undef GTEST_IMPLEMENTATION_ #include @@ -50,7 +50,7 @@ #include #endif // GTEST_HAS_PTHREAD -#ifdef GTEST_OS_LINUX +#if GTEST_OS_LINUX #include #include #include @@ -355,7 +355,7 @@ TEST_F(FatalFailureInSetUpTest, FailureInSetUp) { << "We should never get here, as SetUp() failed."; } -#ifdef GTEST_OS_WINDOWS +#if GTEST_OS_WINDOWS // This group of tests verifies that Google Test handles SEH and C++ // exceptions correctly. @@ -722,7 +722,7 @@ TEST(ExpectFatalFailureTest, FailsWhenStatementThrows) { #endif // GTEST_HAS_EXCEPTIONS // This #ifdef block tests the output of typed tests. -#ifdef GTEST_HAS_TYPED_TEST +#if GTEST_HAS_TYPED_TEST template class TypedTest : public testing::Test { @@ -741,7 +741,7 @@ TYPED_TEST(TypedTest, Failure) { #endif // GTEST_HAS_TYPED_TEST // This #ifdef block tests the output of type-parameterized tests. -#ifdef GTEST_HAS_TYPED_TEST_P +#if GTEST_HAS_TYPED_TEST_P template class TypedTestP : public testing::Test { @@ -764,7 +764,7 @@ INSTANTIATE_TYPED_TEST_CASE_P(Unsigned, TypedTestP, UnsignedTypes); #endif // GTEST_HAS_TYPED_TEST_P -#ifdef GTEST_HAS_DEATH_TEST +#if GTEST_HAS_DEATH_TEST // We rely on the golden file to verify that tests whose test case // name ends with DeathTest are run first. @@ -772,7 +772,7 @@ INSTANTIATE_TYPED_TEST_CASE_P(Unsigned, TypedTestP, UnsignedTypes); TEST(ADeathTest, ShouldRunFirst) { } -#ifdef GTEST_HAS_TYPED_TEST +#if GTEST_HAS_TYPED_TEST // We rely on the golden file to verify that typed tests whose test // case name ends with DeathTest are run first. @@ -789,7 +789,7 @@ TYPED_TEST(ATypedDeathTest, ShouldRunFirst) { #endif // GTEST_HAS_TYPED_TEST -#ifdef GTEST_HAS_TYPED_TEST_P +#if GTEST_HAS_TYPED_TEST_P // We rely on the golden file to verify that type-parameterized tests @@ -984,7 +984,7 @@ int main(int argc, char **argv) { String(argv[1]) == "--gtest_internal_skip_environment_and_ad_hoc_tests") GTEST_FLAG(internal_skip_environment_and_ad_hoc_tests) = true; -#ifdef GTEST_HAS_DEATH_TEST +#if GTEST_HAS_DEATH_TEST if (testing::internal::GTEST_FLAG(internal_run_death_test) != "") { // Skip the usual output capturing if we're running as the child // process of an threadsafe-style death test. diff --git a/test/gtest_repeat_test.cc b/test/gtest_repeat_test.cc index 65298bfa..39a0601d 100644 --- a/test/gtest_repeat_test.cc +++ b/test/gtest_repeat_test.cc @@ -40,9 +40,9 @@ // included, or there will be a compiler error. This trick is to // prevent a user from accidentally including gtest-internal-inl.h in // his code. -#define GTEST_IMPLEMENTATION +#define GTEST_IMPLEMENTATION_ 1 #include "src/gtest-internal-inl.h" -#undef GTEST_IMPLEMENTATION +#undef GTEST_IMPLEMENTATION_ namespace testing { @@ -112,7 +112,7 @@ int g_death_test_count = 0; TEST(BarDeathTest, ThreadSafeAndFast) { g_death_test_count++; -#ifdef GTEST_HAS_DEATH_TEST +#if GTEST_HAS_DEATH_TEST GTEST_FLAG(death_test_style) = "threadsafe"; EXPECT_DEATH(abort(), ""); @@ -121,7 +121,7 @@ TEST(BarDeathTest, ThreadSafeAndFast) { #endif // GTEST_HAS_DEATH_TEST } -#ifdef GTEST_HAS_PARAM_TEST +#if GTEST_HAS_PARAM_TEST int g_param_test_count = 0; const int kNumberOfParamTests = 10; @@ -146,7 +146,7 @@ void ResetCounts() { g_should_fail_count = 0; g_should_pass_count = 0; g_death_test_count = 0; -#ifdef GTEST_HAS_PARAM_TEST +#if GTEST_HAS_PARAM_TEST g_param_test_count = 0; #endif // GTEST_HAS_PARAM_TEST } @@ -158,7 +158,7 @@ void CheckCounts(int expected) { GTEST_CHECK_INT_EQ_(expected, g_should_fail_count); GTEST_CHECK_INT_EQ_(expected, g_should_pass_count); GTEST_CHECK_INT_EQ_(expected, g_death_test_count); -#ifdef GTEST_HAS_PARAM_TEST +#if GTEST_HAS_PARAM_TEST GTEST_CHECK_INT_EQ_(expected * kNumberOfParamTests, g_param_test_count); #endif // GTEST_HAS_PARAM_TEST } @@ -203,7 +203,7 @@ void TestRepeatWithFilterForSuccessfulTests(int repeat) { GTEST_CHECK_INT_EQ_(0, g_should_fail_count); GTEST_CHECK_INT_EQ_(repeat, g_should_pass_count); GTEST_CHECK_INT_EQ_(repeat, g_death_test_count); -#ifdef GTEST_HAS_PARAM_TEST +#if GTEST_HAS_PARAM_TEST GTEST_CHECK_INT_EQ_(repeat * kNumberOfParamTests, g_param_test_count); #endif // GTEST_HAS_PARAM_TEST } @@ -221,7 +221,7 @@ void TestRepeatWithFilterForFailedTests(int repeat) { GTEST_CHECK_INT_EQ_(repeat, g_should_fail_count); GTEST_CHECK_INT_EQ_(0, g_should_pass_count); GTEST_CHECK_INT_EQ_(0, g_death_test_count); -#ifdef GTEST_HAS_PARAM_TEST +#if GTEST_HAS_PARAM_TEST GTEST_CHECK_INT_EQ_(0, g_param_test_count); #endif // GTEST_HAS_PARAM_TEST } diff --git a/test/gtest_stress_test.cc b/test/gtest_stress_test.cc index c58f56ca..55e8bf42 100644 --- a/test/gtest_stress_test.cc +++ b/test/gtest_stress_test.cc @@ -38,9 +38,9 @@ // We must define this macro in order to #include // gtest-internal-inl.h. This is how Google Test prevents a user from // accidentally depending on its internal implementation. -#define GTEST_IMPLEMENTATION +#define GTEST_IMPLEMENTATION_ 1 #include "src/gtest-internal-inl.h" -#undef GTEST_IMPLEMENTATION +#undef GTEST_IMPLEMENTATION_ namespace testing { namespace { diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index f8dbff0f..8dabcc9a 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -59,9 +59,9 @@ TEST(CommandLineFlagsTest, CanBeAccessedInCodeOnceGTestHIsIncluded) { // included, or there will be a compiler error. This trick is to // prevent a user from accidentally including gtest-internal-inl.h in // his code. -#define GTEST_IMPLEMENTATION +#define GTEST_IMPLEMENTATION_ 1 #include "src/gtest-internal-inl.h" -#undef GTEST_IMPLEMENTATION +#undef GTEST_IMPLEMENTATION_ #include @@ -69,7 +69,7 @@ TEST(CommandLineFlagsTest, CanBeAccessedInCodeOnceGTestHIsIncluded) { #include #endif // GTEST_HAS_PTHREAD -#ifdef GTEST_OS_LINUX +#if GTEST_OS_LINUX #include #include #include @@ -201,7 +201,7 @@ TEST(FormatTimeInMillisAsSecondsTest, FormatsNegativeNumber) { EXPECT_STREQ("-3", FormatTimeInMillisAsSeconds(-3000)); } -#ifndef GTEST_OS_SYMBIAN +#if !GTEST_OS_SYMBIAN // NULL testing does not work with Symbian compilers. // Tests that GTEST_IS_NULL_LITERAL_(x) is true when x is a null @@ -225,7 +225,7 @@ TEST(NullLiteralTest, IsFalseForNonNullLiterals) { EXPECT_FALSE(GTEST_IS_NULL_LITERAL_(static_cast(NULL))); } -#endif // GTEST_OS_SYMBIAN +#endif // !GTEST_OS_SYMBIAN // // Tests CodePointToUtf8(). @@ -266,7 +266,7 @@ TEST(CodePointToUtf8Test, CanEncode12To16Bits) { EXPECT_STREQ("\xEC\x9D\x8D", CodePointToUtf8(L'\xC74D', buffer)); } -#ifndef GTEST_WIDE_STRING_USES_UTF16_ +#if !GTEST_WIDE_STRING_USES_UTF16_ // Tests in this group require a wchar_t to hold > 16 bits, and thus // are skipped on Windows, Cygwin, and Symbian, where a wchar_t is // 16-bit wide. This code may not compile on those systems. @@ -292,7 +292,7 @@ TEST(CodePointToUtf8Test, CanEncodeInvalidCodePoint) { CodePointToUtf8(L'\x1234ABCD', buffer)); } -#endif // GTEST_WIDE_STRING_USES_UTF16_ +#endif // !GTEST_WIDE_STRING_USES_UTF16_ // Tests WideStringToUtf8(). @@ -346,7 +346,7 @@ TEST(WideStringToUtf8Test, StopsWhenLengthLimitReached) { } -#ifndef GTEST_WIDE_STRING_USES_UTF16_ +#if !GTEST_WIDE_STRING_USES_UTF16_ // Tests that Unicode code-points that have 17 to 21 bits are encoded // as 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx. This code may not compile // on the systems using UTF-16 encoding. @@ -365,7 +365,7 @@ TEST(WideStringToUtf8Test, CanEncodeInvalidCodePoint) { EXPECT_STREQ("(Invalid Unicode 0xABCDFF)", WideStringToUtf8(L"\xABCDFF", -1).c_str()); } -#else +#else // !GTEST_WIDE_STRING_USES_UTF16_ // Tests that surrogate pairs are encoded correctly on the systems using // UTF-16 encoding in the wide strings. TEST(WideStringToUtf8Test, CanEncodeValidUtf16SUrrogatePairs) { @@ -383,10 +383,10 @@ TEST(WideStringToUtf8Test, CanEncodeInvalidUtf16SurrogatePair) { // Trailing surrogate appearas without a leading surrogate. EXPECT_STREQ("\xED\xB0\x80PQR", WideStringToUtf8(L"\xDC00PQR", -1).c_str()); } -#endif // GTEST_WIDE_STRING_USES_UTF16_ +#endif // !GTEST_WIDE_STRING_USES_UTF16_ // Tests that codepoint concatenation works correctly. -#ifndef GTEST_WIDE_STRING_USES_UTF16_ +#if !GTEST_WIDE_STRING_USES_UTF16_ TEST(WideStringToUtf8Test, ConcatenatesCodepointsCorrectly) { EXPECT_STREQ( "\xF4\x88\x98\xB4" @@ -403,7 +403,7 @@ TEST(WideStringToUtf8Test, ConcatenatesCodepointsCorrectly) { "\xEC\x9D\x8D" "\n" "\xD5\xB6" "\xE0\xA3\x93", WideStringToUtf8(L"\xC74D\n\x576\x8D3", -1).c_str()); } -#endif // GTEST_WIDE_STRING_USES_UTF16_ +#endif // !GTEST_WIDE_STRING_USES_UTF16_ // Tests the List template class. @@ -725,7 +725,7 @@ TEST(StringTest, CanBeAssignedSelf) { EXPECT_STREQ("hello", dest.c_str()); } -#ifdef GTEST_OS_WINDOWS +#if GTEST_OS_WINDOWS // Tests String::ShowWideCString(). TEST(StringTest, ShowWideCString) { @@ -1265,7 +1265,7 @@ static void SetEnv(const char* name, const char* value) { #ifdef _WIN32_WCE // Environment variables are not supported on Windows CE. return; -#elif defined(GTEST_OS_WINDOWS) // If we are on Windows proper. +#elif GTEST_OS_WINDOWS // If we are on Windows proper. _putenv((Message() << name << "=" << value).GetString().c_str()); #else if (*value == '\0') { @@ -1286,7 +1286,7 @@ using testing::internal::Int32FromGTestEnv; // Tests that Int32FromGTestEnv() returns the default value when the // environment variable is not set. TEST(Int32FromGTestEnvTest, ReturnsDefaultWhenVariableIsNotSet) { - SetEnv(GTEST_FLAG_PREFIX_UPPER "TEMP", ""); + SetEnv(GTEST_FLAG_PREFIX_UPPER_ "TEMP", ""); EXPECT_EQ(10, Int32FromGTestEnv("temp", 10)); } @@ -1295,10 +1295,10 @@ TEST(Int32FromGTestEnvTest, ReturnsDefaultWhenVariableIsNotSet) { TEST(Int32FromGTestEnvTest, ReturnsDefaultWhenValueOverflows) { printf("(expecting 2 warnings)\n"); - SetEnv(GTEST_FLAG_PREFIX_UPPER "TEMP", "12345678987654321"); + SetEnv(GTEST_FLAG_PREFIX_UPPER_ "TEMP", "12345678987654321"); EXPECT_EQ(20, Int32FromGTestEnv("temp", 20)); - SetEnv(GTEST_FLAG_PREFIX_UPPER "TEMP", "-12345678987654321"); + SetEnv(GTEST_FLAG_PREFIX_UPPER_ "TEMP", "-12345678987654321"); EXPECT_EQ(30, Int32FromGTestEnv("temp", 30)); } @@ -1307,10 +1307,10 @@ TEST(Int32FromGTestEnvTest, ReturnsDefaultWhenValueOverflows) { TEST(Int32FromGTestEnvTest, ReturnsDefaultWhenValueIsInvalid) { printf("(expecting 2 warnings)\n"); - SetEnv(GTEST_FLAG_PREFIX_UPPER "TEMP", "A1"); + SetEnv(GTEST_FLAG_PREFIX_UPPER_ "TEMP", "A1"); EXPECT_EQ(40, Int32FromGTestEnv("temp", 40)); - SetEnv(GTEST_FLAG_PREFIX_UPPER "TEMP", "12X"); + SetEnv(GTEST_FLAG_PREFIX_UPPER_ "TEMP", "12X"); EXPECT_EQ(50, Int32FromGTestEnv("temp", 50)); } @@ -1318,10 +1318,10 @@ TEST(Int32FromGTestEnvTest, ReturnsDefaultWhenValueIsInvalid) { // environment variable when it represents a valid decimal integer in // the range of an Int32. TEST(Int32FromGTestEnvTest, ParsesAndReturnsValidValue) { - SetEnv(GTEST_FLAG_PREFIX_UPPER "TEMP", "123"); + SetEnv(GTEST_FLAG_PREFIX_UPPER_ "TEMP", "123"); EXPECT_EQ(123, Int32FromGTestEnv("temp", 0)); - SetEnv(GTEST_FLAG_PREFIX_UPPER "TEMP", "-321"); + SetEnv(GTEST_FLAG_PREFIX_UPPER_ "TEMP", "-321"); EXPECT_EQ(-321, Int32FromGTestEnv("temp", 0)); } #endif // !defined(_WIN32_WCE) @@ -1371,38 +1371,38 @@ TEST(ParseInt32FlagTest, ReturnsDefaultWhenValueIsInvalid) { // the range of an Int32. TEST(ParseInt32FlagTest, ParsesAndReturnsValidValue) { Int32 value = 123; - EXPECT_TRUE(ParseInt32Flag("--" GTEST_FLAG_PREFIX "abc=456", "abc", &value)); + EXPECT_TRUE(ParseInt32Flag("--" GTEST_FLAG_PREFIX_ "abc=456", "abc", &value)); EXPECT_EQ(456, value); - EXPECT_TRUE(ParseInt32Flag("--" GTEST_FLAG_PREFIX "abc=-789", "abc", &value)); + EXPECT_TRUE(ParseInt32Flag("--" GTEST_FLAG_PREFIX_ "abc=-789", "abc", &value)); EXPECT_EQ(-789, value); } // Tests that Int32FromEnvOrDie() parses the value of the var or // returns the correct default. TEST(Int32FromEnvOrDieTest, ParsesAndReturnsValidValue) { - EXPECT_EQ(333, Int32FromEnvOrDie(GTEST_FLAG_PREFIX_UPPER "UnsetVar", 333)); - SetEnv(GTEST_FLAG_PREFIX_UPPER "UnsetVar", "123"); - EXPECT_EQ(123, Int32FromEnvOrDie(GTEST_FLAG_PREFIX_UPPER "UnsetVar", 333)); - SetEnv(GTEST_FLAG_PREFIX_UPPER "UnsetVar", "-123"); - EXPECT_EQ(-123, Int32FromEnvOrDie(GTEST_FLAG_PREFIX_UPPER "UnsetVar", 333)); + EXPECT_EQ(333, Int32FromEnvOrDie(GTEST_FLAG_PREFIX_UPPER_ "UnsetVar", 333)); + SetEnv(GTEST_FLAG_PREFIX_UPPER_ "UnsetVar", "123"); + EXPECT_EQ(123, Int32FromEnvOrDie(GTEST_FLAG_PREFIX_UPPER_ "UnsetVar", 333)); + SetEnv(GTEST_FLAG_PREFIX_UPPER_ "UnsetVar", "-123"); + EXPECT_EQ(-123, Int32FromEnvOrDie(GTEST_FLAG_PREFIX_UPPER_ "UnsetVar", 333)); } -#ifdef GTEST_HAS_DEATH_TEST +#if GTEST_HAS_DEATH_TEST // Tests that Int32FromEnvOrDie() aborts with an error message // if the variable is not an Int32. TEST(Int32FromEnvOrDieDeathTest, AbortsOnFailure) { - SetEnv(GTEST_FLAG_PREFIX_UPPER "VAR", "xxx"); - EXPECT_DEATH({Int32FromEnvOrDie(GTEST_FLAG_PREFIX_UPPER "VAR", 123);}, + SetEnv(GTEST_FLAG_PREFIX_UPPER_ "VAR", "xxx"); + EXPECT_DEATH({Int32FromEnvOrDie(GTEST_FLAG_PREFIX_UPPER_ "VAR", 123);}, ".*"); } // Tests that Int32FromEnvOrDie() aborts with an error message // if the variable cannot be represnted by an Int32. TEST(Int32FromEnvOrDieDeathTest, AbortsOnInt32Overflow) { - SetEnv(GTEST_FLAG_PREFIX_UPPER "VAR", "1234567891234567891234"); - EXPECT_DEATH({Int32FromEnvOrDie(GTEST_FLAG_PREFIX_UPPER "VAR", 123);}, + SetEnv(GTEST_FLAG_PREFIX_UPPER_ "VAR", "1234567891234567891234"); + EXPECT_DEATH({Int32FromEnvOrDie(GTEST_FLAG_PREFIX_UPPER_ "VAR", 123);}, ".*"); } @@ -1422,8 +1422,8 @@ TEST(ShouldRunTestOnShardTest, IsPartitionWhenThereIsOneShard) { class ShouldShardTest : public testing::Test { protected: virtual void SetUp() { - index_var_ = GTEST_FLAG_PREFIX_UPPER "INDEX"; - total_var_ = GTEST_FLAG_PREFIX_UPPER "TOTAL"; + index_var_ = GTEST_FLAG_PREFIX_UPPER_ "INDEX"; + total_var_ = GTEST_FLAG_PREFIX_UPPER_ "TOTAL"; } virtual void TearDown() { @@ -1472,7 +1472,7 @@ TEST_F(ShouldShardTest, WorksWhenShardEnvVarsAreValid) { EXPECT_FALSE(ShouldShard(total_var_, index_var_, true)); } -#ifdef GTEST_HAS_DEATH_TEST +#if GTEST_HAS_DEATH_TEST // Tests that we exit in error if the sharding values are not valid. TEST_F(ShouldShardTest, AbortsWhenShardingEnvVarsAreInvalid) { @@ -2243,7 +2243,7 @@ TEST_F(FloatTest, LargeDiff) { TEST_F(FloatTest, Infinity) { EXPECT_FLOAT_EQ(infinity_, close_to_infinity_); EXPECT_FLOAT_EQ(-infinity_, -close_to_infinity_); -#ifndef GTEST_OS_SYMBIAN +#if !GTEST_OS_SYMBIAN // Nokia's STLport crashes if we try to output infinity or NaN. EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(infinity_, -infinity_), "-infinity_"); @@ -2252,12 +2252,12 @@ TEST_F(FloatTest, Infinity) { // are only 1 DLP apart. EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(infinity_, nan1_), "nan1_"); -#endif // ! GTEST_OS_SYMBIAN +#endif // !GTEST_OS_SYMBIAN } // Tests that comparing with NAN always returns false. TEST_F(FloatTest, NaN) { -#ifndef GTEST_OS_SYMBIAN +#if !GTEST_OS_SYMBIAN // Nokia's STLport crashes if we try to output infinity or NaN. EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(nan1_, nan1_), "nan1_"); @@ -2268,7 +2268,7 @@ TEST_F(FloatTest, NaN) { EXPECT_FATAL_FAILURE(ASSERT_FLOAT_EQ(nan1_, infinity_), "infinity_"); -#endif // ! GTEST_OS_SYMBIAN +#endif // !GTEST_OS_SYMBIAN } // Tests that *_FLOAT_EQ are reflexive. @@ -2330,7 +2330,7 @@ TEST_F(FloatTest, FloatLEFails) { EXPECT_PRED_FORMAT2(FloatLE, further_from_one_, 1.0f); }, "(further_from_one_) <= (1.0f)"); -#ifndef GTEST_OS_SYMBIAN +#if !GTEST_OS_SYMBIAN // Nokia's STLport crashes if we try to output infinity or NaN. // or when either val1 or val2 is NaN. EXPECT_NONFATAL_FAILURE({ // NOLINT @@ -2343,7 +2343,7 @@ TEST_F(FloatTest, FloatLEFails) { EXPECT_FATAL_FAILURE({ // NOLINT ASSERT_PRED_FORMAT2(FloatLE, nan1_, nan1_); }, "(nan1_) <= (nan1_)"); -#endif // ! GTEST_OS_SYMBIAN +#endif // !GTEST_OS_SYMBIAN } // Instantiates FloatingPointTest for testing *_DOUBLE_EQ. @@ -2398,7 +2398,7 @@ TEST_F(DoubleTest, LargeDiff) { TEST_F(DoubleTest, Infinity) { EXPECT_DOUBLE_EQ(infinity_, close_to_infinity_); EXPECT_DOUBLE_EQ(-infinity_, -close_to_infinity_); -#ifndef GTEST_OS_SYMBIAN +#if !GTEST_OS_SYMBIAN // Nokia's STLport crashes if we try to output infinity or NaN. EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(infinity_, -infinity_), "-infinity_"); @@ -2407,29 +2407,29 @@ TEST_F(DoubleTest, Infinity) { // are only 1 DLP apart. EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(infinity_, nan1_), "nan1_"); -#endif // ! GTEST_OS_SYMBIAN +#endif // !GTEST_OS_SYMBIAN } // Tests that comparing with NAN always returns false. TEST_F(DoubleTest, NaN) { -#ifndef GTEST_OS_SYMBIAN +#if !GTEST_OS_SYMBIAN // Nokia's STLport crashes if we try to output infinity or NaN. EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(nan1_, nan1_), "nan1_"); EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(nan1_, nan2_), "nan2_"); EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(1.0, nan1_), "nan1_"); EXPECT_FATAL_FAILURE(ASSERT_DOUBLE_EQ(nan1_, infinity_), "infinity_"); -#endif // ! GTEST_OS_SYMBIAN +#endif // !GTEST_OS_SYMBIAN } // Tests that *_DOUBLE_EQ are reflexive. TEST_F(DoubleTest, Reflexive) { EXPECT_DOUBLE_EQ(0.0, 0.0); EXPECT_DOUBLE_EQ(1.0, 1.0); -#ifndef GTEST_OS_SYMBIAN +#if !GTEST_OS_SYMBIAN // Nokia's STLport crashes if we try to output infinity or NaN. ASSERT_DOUBLE_EQ(infinity_, infinity_); -#endif // ! GTEST_OS_SYMBIAN +#endif // !GTEST_OS_SYMBIAN } // Tests that *_DOUBLE_EQ are commutative. @@ -2483,7 +2483,7 @@ TEST_F(DoubleTest, DoubleLEFails) { EXPECT_PRED_FORMAT2(DoubleLE, further_from_one_, 1.0); }, "(further_from_one_) <= (1.0)"); -#ifndef GTEST_OS_SYMBIAN +#if !GTEST_OS_SYMBIAN // Nokia's STLport crashes if we try to output infinity or NaN. // or when either val1 or val2 is NaN. EXPECT_NONFATAL_FAILURE({ // NOLINT @@ -2495,7 +2495,7 @@ TEST_F(DoubleTest, DoubleLEFails) { EXPECT_FATAL_FAILURE({ // NOLINT ASSERT_PRED_FORMAT2(DoubleLE, nan1_, nan1_); }, "(nan1_) <= (nan1_)"); -#endif // ! GTEST_OS_SYMBIAN +#endif // !GTEST_OS_SYMBIAN } @@ -2551,7 +2551,7 @@ TEST_F(DisabledTestsTest, DISABLED_TestShouldNotRun_2) { // Tests that disabled typed tests aren't run. -#ifdef GTEST_HAS_TYPED_TEST +#if GTEST_HAS_TYPED_TEST template class TypedTest : public Test { @@ -2578,7 +2578,7 @@ TYPED_TEST(DISABLED_TypedTest, ShouldNotRun) { // Tests that disabled type-parameterized tests aren't run. -#ifdef GTEST_HAS_TYPED_TEST_P +#if GTEST_HAS_TYPED_TEST_P template class TypedTestP : public Test { @@ -2956,7 +2956,7 @@ TEST(AssertionTest, ASSERT_EQ) { } // Tests ASSERT_EQ(NULL, pointer). -#ifndef GTEST_OS_SYMBIAN +#if !GTEST_OS_SYMBIAN // The NULL-detection template magic fails to compile with // the Nokia compiler and crashes the ARM compiler, hence // not testing on Symbian. @@ -2970,7 +2970,7 @@ TEST(AssertionTest, ASSERT_EQ_NULL) { EXPECT_FATAL_FAILURE(ASSERT_EQ(NULL, &n), "Value of: &n\n"); } -#endif // GTEST_OS_SYMBIAN +#endif // !GTEST_OS_SYMBIAN // Tests ASSERT_EQ(0, non_pointer). Since the literal 0 can be // treated as a null pointer by the compiler, we need to make sure @@ -3145,12 +3145,12 @@ TEST(AssertionTest, ExpectWorksWithUncopyableObject) { // The version of gcc used in XCode 2.2 has a bug and doesn't allow // anonymous enums in assertions. Therefore the following test is // done only on Linux and Windows. -#if defined(GTEST_OS_LINUX) || defined(GTEST_OS_WINDOWS) +#if GTEST_OS_LINUX || GTEST_OS_WINDOWS // Tests using assertions with anonymous enums. enum { CASE_A = -1, -#ifdef GTEST_OS_LINUX +#if GTEST_OS_LINUX // We want to test the case where the size of the anonymous enum is // larger than sizeof(int), to make sure our implementation of the // assertions doesn't truncate the enums. However, MSVC @@ -3167,7 +3167,7 @@ enum { }; TEST(AssertionTest, AnonymousEnum) { -#ifdef GTEST_OS_LINUX +#if GTEST_OS_LINUX EXPECT_EQ(static_cast(CASE_A), static_cast(CASE_B)); #endif // GTEST_OS_LINUX @@ -3190,9 +3190,9 @@ TEST(AssertionTest, AnonymousEnum) { "Value of: CASE_B"); } -#endif // defined(GTEST_OS_LINUX) || defined(GTEST_OS_WINDOWS) +#endif // GTEST_OS_LINUX || GTEST_OS_WINDOWS -#if defined(GTEST_OS_WINDOWS) +#if GTEST_OS_WINDOWS static HRESULT UnexpectedHRESULTFailure() { return E_UNEXPECTED; @@ -3274,7 +3274,7 @@ TEST(HRESULTAssertionTest, Streaming) { "expected failure"); } -#endif // defined(GTEST_OS_WINDOWS) +#endif // GTEST_OS_WINDOWS // Tests that the assertion macros behave like single statements. TEST(AssertionSyntaxTest, BasicAssertionsBehavesLikeSingleStatement) { @@ -3493,7 +3493,7 @@ TEST(ExpectTest, EXPECT_EQ_Double) { "5.1"); } -#ifndef GTEST_OS_SYMBIAN +#if !GTEST_OS_SYMBIAN // Tests EXPECT_EQ(NULL, pointer). TEST(ExpectTest, EXPECT_EQ_NULL) { // A success. @@ -3505,7 +3505,7 @@ TEST(ExpectTest, EXPECT_EQ_NULL) { EXPECT_NONFATAL_FAILURE(EXPECT_EQ(NULL, &n), "Value of: &n\n"); } -#endif // GTEST_OS_SYMBIAN +#endif // !GTEST_OS_SYMBIAN // Tests EXPECT_EQ(0, non_pointer). Since the literal 0 can be // treated as a null pointer by the compiler, we need to make sure @@ -4469,7 +4469,7 @@ class InitGoogleTestTest : public Test { // This macro wraps TestParsingFlags s.t. the user doesn't need // to specify the array sizes. -#define TEST_PARSING_FLAGS(argv1, argv2, expected) \ +#define GTEST_TEST_PARSING_FLAGS_(argv1, argv2, expected) \ TestParsingFlags(sizeof(argv1)/sizeof(*argv1) - 1, argv1, \ sizeof(argv2)/sizeof(*argv2) - 1, argv2, expected) }; @@ -4484,7 +4484,7 @@ TEST_F(InitGoogleTestTest, Empty) { NULL }; - TEST_PARSING_FLAGS(argv, argv2, Flags()); + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags()); } // Tests parsing a command line that has no flag. @@ -4499,7 +4499,7 @@ TEST_F(InitGoogleTestTest, NoFlag) { NULL }; - TEST_PARSING_FLAGS(argv, argv2, Flags()); + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags()); } // Tests parsing a bad --gtest_filter flag. @@ -4516,7 +4516,7 @@ TEST_F(InitGoogleTestTest, FilterBad) { NULL }; - TEST_PARSING_FLAGS(argv, argv2, Flags::Filter("")); + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Filter("")); } // Tests parsing an empty --gtest_filter flag. @@ -4532,7 +4532,7 @@ TEST_F(InitGoogleTestTest, FilterEmpty) { NULL }; - TEST_PARSING_FLAGS(argv, argv2, Flags::Filter("")); + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Filter("")); } // Tests parsing a non-empty --gtest_filter flag. @@ -4548,7 +4548,7 @@ TEST_F(InitGoogleTestTest, FilterNonEmpty) { NULL }; - TEST_PARSING_FLAGS(argv, argv2, Flags::Filter("abc")); + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Filter("abc")); } // Tests parsing --gtest_break_on_failure. @@ -4564,7 +4564,7 @@ TEST_F(InitGoogleTestTest, BreakOnFailureNoDef) { NULL }; - TEST_PARSING_FLAGS(argv, argv2, Flags::BreakOnFailure(true)); + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::BreakOnFailure(true)); } // Tests parsing --gtest_break_on_failure=0. @@ -4580,7 +4580,7 @@ TEST_F(InitGoogleTestTest, BreakOnFailureFalse_0) { NULL }; - TEST_PARSING_FLAGS(argv, argv2, Flags::BreakOnFailure(false)); + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::BreakOnFailure(false)); } // Tests parsing --gtest_break_on_failure=f. @@ -4596,7 +4596,7 @@ TEST_F(InitGoogleTestTest, BreakOnFailureFalse_f) { NULL }; - TEST_PARSING_FLAGS(argv, argv2, Flags::BreakOnFailure(false)); + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::BreakOnFailure(false)); } // Tests parsing --gtest_break_on_failure=F. @@ -4612,7 +4612,7 @@ TEST_F(InitGoogleTestTest, BreakOnFailureFalse_F) { NULL }; - TEST_PARSING_FLAGS(argv, argv2, Flags::BreakOnFailure(false)); + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::BreakOnFailure(false)); } // Tests parsing a --gtest_break_on_failure flag that has a "true" @@ -4629,7 +4629,7 @@ TEST_F(InitGoogleTestTest, BreakOnFailureTrue) { NULL }; - TEST_PARSING_FLAGS(argv, argv2, Flags::BreakOnFailure(true)); + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::BreakOnFailure(true)); } // Tests parsing --gtest_catch_exceptions. @@ -4645,7 +4645,7 @@ TEST_F(InitGoogleTestTest, CatchExceptions) { NULL }; - TEST_PARSING_FLAGS(argv, argv2, Flags::CatchExceptions(true)); + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::CatchExceptions(true)); } // Tests parsing --gtest_death_test_use_fork. @@ -4661,7 +4661,7 @@ TEST_F(InitGoogleTestTest, DeathTestUseFork) { NULL }; - TEST_PARSING_FLAGS(argv, argv2, Flags::DeathTestUseFork(true)); + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::DeathTestUseFork(true)); } // Tests having the same flag twice with different values. The @@ -4679,7 +4679,7 @@ TEST_F(InitGoogleTestTest, DuplicatedFlags) { NULL }; - TEST_PARSING_FLAGS(argv, argv2, Flags::Filter("b")); + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Filter("b")); } // Tests having an unrecognized flag on the command line. @@ -4701,7 +4701,7 @@ TEST_F(InitGoogleTestTest, UnrecognizedFlag) { Flags flags; flags.break_on_failure = true; flags.filter = "b"; - TEST_PARSING_FLAGS(argv, argv2, flags); + GTEST_TEST_PARSING_FLAGS_(argv, argv2, flags); } // Tests having a --gtest_list_tests flag @@ -4717,7 +4717,7 @@ TEST_F(InitGoogleTestTest, ListTestsFlag) { NULL }; - TEST_PARSING_FLAGS(argv, argv2, Flags::ListTests(true)); + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ListTests(true)); } // Tests having a --gtest_list_tests flag with a "true" value @@ -4733,7 +4733,7 @@ TEST_F(InitGoogleTestTest, ListTestsTrue) { NULL }; - TEST_PARSING_FLAGS(argv, argv2, Flags::ListTests(true)); + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ListTests(true)); } // Tests having a --gtest_list_tests flag with a "false" value @@ -4749,7 +4749,7 @@ TEST_F(InitGoogleTestTest, ListTestsFalse) { NULL }; - TEST_PARSING_FLAGS(argv, argv2, Flags::ListTests(false)); + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ListTests(false)); } // Tests parsing --gtest_list_tests=f. @@ -4765,7 +4765,7 @@ TEST_F(InitGoogleTestTest, ListTestsFalse_f) { NULL }; - TEST_PARSING_FLAGS(argv, argv2, Flags::ListTests(false)); + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ListTests(false)); } // Tests parsing --gtest_break_on_failure=F. @@ -4781,7 +4781,7 @@ TEST_F(InitGoogleTestTest, ListTestsFalse_F) { NULL }; - TEST_PARSING_FLAGS(argv, argv2, Flags::ListTests(false)); + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ListTests(false)); } // Tests parsing --gtest_output (invalid). @@ -4798,7 +4798,7 @@ TEST_F(InitGoogleTestTest, OutputEmpty) { NULL }; - TEST_PARSING_FLAGS(argv, argv2, Flags()); + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags()); } // Tests parsing --gtest_output=xml @@ -4814,7 +4814,7 @@ TEST_F(InitGoogleTestTest, OutputXml) { NULL }; - TEST_PARSING_FLAGS(argv, argv2, Flags::Output("xml")); + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Output("xml")); } // Tests parsing --gtest_output=xml:file @@ -4830,7 +4830,7 @@ TEST_F(InitGoogleTestTest, OutputXmlFile) { NULL }; - TEST_PARSING_FLAGS(argv, argv2, Flags::Output("xml:file")); + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Output("xml:file")); } // Tests parsing --gtest_output=xml:directory/path/ @@ -4846,7 +4846,7 @@ TEST_F(InitGoogleTestTest, OutputXmlDirectory) { NULL }; - TEST_PARSING_FLAGS(argv, argv2, Flags::Output("xml:directory/path/")); + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Output("xml:directory/path/")); } // Tests having a --gtest_print_time flag @@ -4862,7 +4862,7 @@ TEST_F(InitGoogleTestTest, PrintTimeFlag) { NULL }; - TEST_PARSING_FLAGS(argv, argv2, Flags::PrintTime(true)); + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::PrintTime(true)); } // Tests having a --gtest_print_time flag with a "true" value @@ -4878,7 +4878,7 @@ TEST_F(InitGoogleTestTest, PrintTimeTrue) { NULL }; - TEST_PARSING_FLAGS(argv, argv2, Flags::PrintTime(true)); + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::PrintTime(true)); } // Tests having a --gtest_print_time flag with a "false" value @@ -4894,7 +4894,7 @@ TEST_F(InitGoogleTestTest, PrintTimeFalse) { NULL }; - TEST_PARSING_FLAGS(argv, argv2, Flags::PrintTime(false)); + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::PrintTime(false)); } // Tests parsing --gtest_print_time=f. @@ -4910,7 +4910,7 @@ TEST_F(InitGoogleTestTest, PrintTimeFalse_f) { NULL }; - TEST_PARSING_FLAGS(argv, argv2, Flags::PrintTime(false)); + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::PrintTime(false)); } // Tests parsing --gtest_print_time=F. @@ -4926,7 +4926,7 @@ TEST_F(InitGoogleTestTest, PrintTimeFalse_F) { NULL }; - TEST_PARSING_FLAGS(argv, argv2, Flags::PrintTime(false)); + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::PrintTime(false)); } // Tests parsing --gtest_repeat=number @@ -4942,7 +4942,7 @@ TEST_F(InitGoogleTestTest, Repeat) { NULL }; - TEST_PARSING_FLAGS(argv, argv2, Flags::Repeat(1000)); + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Repeat(1000)); } // Tests having a --gtest_also_run_disabled_tests flag @@ -4958,7 +4958,7 @@ TEST_F(InitGoogleTestTest, AlsoRunDisabledTestsFlag) { NULL }; - TEST_PARSING_FLAGS(argv, argv2, Flags::AlsoRunDisabledTests(true)); + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::AlsoRunDisabledTests(true)); } // Tests having a --gtest_also_run_disabled_tests flag with a "true" value @@ -4974,7 +4974,7 @@ TEST_F(InitGoogleTestTest, AlsoRunDisabledTestsTrue) { NULL }; - TEST_PARSING_FLAGS(argv, argv2, Flags::AlsoRunDisabledTests(true)); + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::AlsoRunDisabledTests(true)); } // Tests having a --gtest_also_run_disabled_tests flag with a "false" value @@ -4990,10 +4990,10 @@ TEST_F(InitGoogleTestTest, AlsoRunDisabledTestsFalse) { NULL }; - TEST_PARSING_FLAGS(argv, argv2, Flags::AlsoRunDisabledTests(false)); + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::AlsoRunDisabledTests(false)); } -#ifdef GTEST_OS_WINDOWS +#if GTEST_OS_WINDOWS // Tests parsing wide strings. TEST_F(InitGoogleTestTest, WideStrings) { const wchar_t* argv[] = { @@ -5016,7 +5016,7 @@ TEST_F(InitGoogleTestTest, WideStrings) { expected_flags.filter = "Foo*"; expected_flags.list_tests = true; - TEST_PARSING_FLAGS(argv, argv2, expected_flags); + GTEST_TEST_PARSING_FLAGS_(argv, argv2, expected_flags); } #endif // GTEST_OS_WINDOWS @@ -5304,7 +5304,7 @@ TEST(ColoredOutputTest, UsesColorsWhenStdoutIsTty) { TEST(ColoredOutputTest, UsesColorsWhenTermSupportsColors) { GTEST_FLAG(color) = "auto"; -#ifdef GTEST_OS_WINDOWS +#if GTEST_OS_WINDOWS // On Windows, we ignore the TERM variable as it's usually not set. SetEnv("TERM", "dumb"); -- cgit v1.2.3 From 4984c93490eeeb7d3d1979b30a39a21cad07cba5 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Fri, 6 Mar 2009 01:20:15 +0000 Subject: Implements death tests on Windows (by Vlad Losev); enables POSIX regex on Mac and Cygwin; fixes build issue on some Linux versions due to PATH_MAX. --- test/gtest-death-test_test.cc | 268 ++++++++++++++++++++++++++++++++-- test/gtest-port_test.cc | 38 +++-- test/gtest_output_test_.cc | 11 ++ test/gtest_output_test_golden_win.txt | 21 ++- 4 files changed, 313 insertions(+), 25 deletions(-) (limited to 'test') diff --git a/test/gtest-death-test_test.cc b/test/gtest-death-test_test.cc index 6d8a3f89..4151ef0e 100644 --- a/test/gtest-death-test_test.cc +++ b/test/gtest-death-test_test.cc @@ -36,8 +36,16 @@ #if GTEST_HAS_DEATH_TEST -#include +#if GTEST_OS_WINDOWS +#include // For chdir(). +#else #include +#include // For std::numeric_limits. +#endif // GTEST_OS_WINDOWS + +#include +#include +#include #include // Indicates that this translation unit is part of Google Test's @@ -49,8 +57,13 @@ #include "src/gtest-internal-inl.h" #undef GTEST_IMPLEMENTATION_ +using testing::Message; + using testing::internal::DeathTest; using testing::internal::DeathTestFactory; +using testing::internal::GetLastSystemErrorMessage; +using testing::internal::ParseNaturalNumber; +using testing::internal::String; namespace testing { namespace internal { @@ -88,6 +101,7 @@ class TestForDeathTest : public testing::Test { // A static member function that's expected to die. static void StaticMemberFunction() { fprintf(stderr, "%s", "death inside StaticMemberFunction()."); + fflush(stderr); // We call _exit() instead of exit(), as the former is a direct // system call and thus safer in the presence of threads. exit() // will invoke user-defined exit-hooks, which may do dangerous @@ -99,6 +113,7 @@ class TestForDeathTest : public testing::Test { void MemberFunction() { if (should_die_) { fprintf(stderr, "%s", "death inside MemberFunction()."); + fflush(stderr); _exit(1); } } @@ -165,6 +180,21 @@ int DieInDebugElse12(int* sideeffect) { return 12; } +#if GTEST_OS_WINDOWS + +// Tests the ExitedWithCode predicate. +TEST(ExitStatusPredicateTest, ExitedWithCode) { + // On Windows, the process's exit code is the same as its exit status, + // so the predicate just compares the its input with its parameter. + EXPECT_TRUE(testing::ExitedWithCode(0)(0)); + EXPECT_TRUE(testing::ExitedWithCode(1)(1)); + EXPECT_TRUE(testing::ExitedWithCode(42)(42)); + EXPECT_FALSE(testing::ExitedWithCode(0)(1)); + EXPECT_FALSE(testing::ExitedWithCode(1)(0)); +} + +#else + // Returns the exit status of a process that calls _exit(2) with a // given exit code. This is a helper function for the // ExitStatusPredicateTest test suite. @@ -222,6 +252,8 @@ TEST(ExitStatusPredicateTest, KilledBySignal) { EXPECT_FALSE(pred_kill(status_segv)); } +#endif // GTEST_OS_WINDOWS + // Tests that the death test macros expand to code which may or may not // be followed by operator<<, and that in either case the complete text // comprises only a single C++ statement. @@ -248,6 +280,7 @@ TEST_F(TestForDeathTest, SingleStatement) { void DieWithEmbeddedNul() { fprintf(stderr, "Hello%cworld.\n", '\0'); + fflush(stderr); _exit(1); } @@ -263,6 +296,13 @@ TEST_F(TestForDeathTest, DISABLED_EmbeddedNulInMessage) { // Tests that death test macros expand to code which interacts well with switch // statements. TEST_F(TestForDeathTest, SwitchStatement) { +// Microsoft compiler usually complains about switch statements without +// case labels. We suppress that warning for this test. +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable: 4065) +#endif // _MSC_VER + switch (0) default: ASSERT_DEATH(_exit(1), "") << "exit in default switch handler"; @@ -270,6 +310,10 @@ TEST_F(TestForDeathTest, SwitchStatement) { switch (0) case 0: EXPECT_DEATH(_exit(1), "") << "exit in switch case"; + +#ifdef _MSC_VER +#pragma warning(pop) +#endif // _MSC_VER } // Tests that a static member function can be used in a "fast" style @@ -287,15 +331,23 @@ TEST_F(TestForDeathTest, MemberFunctionFastStyle) { EXPECT_DEATH(MemberFunction(), "inside.*MemberFunction"); } +void ChangeToRootDir() { +#if GTEST_OS_WINDOWS + _chdir("\\"); +#else + chdir("/"); +#endif // GTEST_OS_WINDOWS +} + // Tests that death tests work even if the current directory has been // changed. TEST_F(TestForDeathTest, FastDeathTestInChangedDir) { testing::GTEST_FLAG(death_test_style) = "fast"; - chdir("/"); + ChangeToRootDir(); EXPECT_EXIT(_exit(1), testing::ExitedWithCode(1), ""); - chdir("/"); + ChangeToRootDir(); ASSERT_DEATH(_exit(1), ""); } @@ -322,10 +374,10 @@ TEST_F(TestForDeathTest, ThreadsafeDeathTestInLoop) { TEST_F(TestForDeathTest, ThreadsafeDeathTestInChangedDir) { testing::GTEST_FLAG(death_test_style) = "threadsafe"; - chdir("/"); + ChangeToRootDir(); EXPECT_EXIT(_exit(1), testing::ExitedWithCode(1), ""); - chdir("/"); + ChangeToRootDir(); ASSERT_DEATH(_exit(1), ""); } @@ -346,6 +398,8 @@ void SetPthreadFlag() { } // namespace +#if !GTEST_OS_WINDOWS + TEST_F(TestForDeathTest, DoesNotExecuteAtforkHooks) { if (!testing::GTEST_FLAG(death_test_use_fork)) { testing::GTEST_FLAG(death_test_style) = "threadsafe"; @@ -356,6 +410,8 @@ TEST_F(TestForDeathTest, DoesNotExecuteAtforkHooks) { } } +#endif // !GTEST_OS_WINDOWS + // Tests that a method of another class can be used in a death test. TEST_F(TestForDeathTest, MethodOfAnotherClass) { const MayDie x(true); @@ -537,6 +593,30 @@ void ExpectDebugDeathHelper(bool* aborted) { *aborted = false; } +#if GTEST_OS_WINDOWS +TEST(TestForPopUps, DoesNotShowPopUpOnAbort) { + printf("This test should be considered failing if it shows " + "any pop-up dialogs.\n"); + fflush(stdout); + + EXPECT_DEATH({ + testing::GTEST_FLAG(catch_exceptions) = false; + abort(); + }, ""); +} + +TEST(TestForPopUps, DoesNotShowPopUpOnThrow) { + printf("This test should be considered failing if it shows " + "any pop-up dialogs.\n"); + fflush(stdout); + + EXPECT_DEATH({ + testing::GTEST_FLAG(catch_exceptions) = false; + throw 1; + }, ""); +} +#endif // GTEST_OS_WINDOWS + // Tests that EXPECT_DEBUG_DEATH in debug mode does not abort // the function. TEST_F(TestForDeathTest, ExpectDebugDeathDoesNotAbort) { @@ -566,18 +646,38 @@ TEST_F(TestForDeathTest, AssertDebugDeathAborts) { static void TestExitMacros() { EXPECT_EXIT(_exit(1), testing::ExitedWithCode(1), ""); ASSERT_EXIT(_exit(42), testing::ExitedWithCode(42), ""); - EXPECT_EXIT(raise(SIGKILL), testing::KilledBySignal(SIGKILL), "") << "foo"; - ASSERT_EXIT(raise(SIGUSR2), testing::KilledBySignal(SIGUSR2), "") << "bar"; + +#if GTEST_OS_WINDOWS + EXPECT_EXIT({ + testing::GTEST_FLAG(catch_exceptions) = false; + *static_cast(NULL) = 1; + }, testing::ExitedWithCode(0xC0000005), "") << "foo"; EXPECT_NONFATAL_FAILURE({ // NOLINT - EXPECT_EXIT(raise(SIGSEGV), testing::ExitedWithCode(0), "") - << "This failure is expected."; + EXPECT_EXIT({ + testing::GTEST_FLAG(catch_exceptions) = false; + *static_cast(NULL) = 1; + }, testing::ExitedWithCode(0), "") << "This failure is expected."; }, "This failure is expected."); + // Of all signals effects on the process exit code, only those of SIGABRT + // are documented on Windows. + // See http://msdn.microsoft.com/en-us/library/dwwzkt4c(VS.71).aspx. + EXPECT_EXIT(raise(SIGABRT), testing::ExitedWithCode(3), ""); +#else + EXPECT_EXIT(raise(SIGKILL), testing::KilledBySignal(SIGKILL), "") << "foo"; + ASSERT_EXIT(raise(SIGUSR2), testing::KilledBySignal(SIGUSR2), "") << "bar"; + EXPECT_FATAL_FAILURE({ // NOLINT ASSERT_EXIT(_exit(0), testing::KilledBySignal(SIGSEGV), "") << "This failure is expected, too."; }, "This failure is expected, too."); +#endif // GTEST_OS_WINDOWS + + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_EXIT(raise(SIGSEGV), testing::ExitedWithCode(0), "") + << "This failure is expected."; + }, "This failure is expected."); } TEST_F(TestForDeathTest, ExitMacros) { @@ -873,6 +973,156 @@ TEST(StreamingAssertionsDeathTest, DeathTest) { }, "expected failure"); } +// Tests that GetLastSystemErrorMessage returns an empty string when the +// last error is 0 and non-empty string when it is non-zero. +TEST(GetLastSystemErrorMessageTest, GetLastSystemErrorMessageWorks) { +#if GTEST_OS_WINDOWS + ::SetLastError(ERROR_FILE_NOT_FOUND); + EXPECT_STRNE("", GetLastSystemErrorMessage().c_str()); + ::SetLastError(0); + EXPECT_STREQ("", GetLastSystemErrorMessage().c_str()); +#else + errno = ENOENT; + EXPECT_STRNE("", GetLastSystemErrorMessage().c_str()); + errno = 0; + EXPECT_STREQ("", GetLastSystemErrorMessage().c_str()); +#endif +} + +#if GTEST_OS_WINDOWS +TEST(AutoHandleTest, AutoHandleWorks) { + HANDLE handle = ::CreateEvent(NULL, FALSE, FALSE, NULL); + ASSERT_NE(INVALID_HANDLE_VALUE, handle); + + // Tests that the AutoHandle is correctly initialized with a handle. + testing::internal::AutoHandle auto_handle(handle); + EXPECT_EQ(handle, auto_handle.Get()); + + // Tests that Reset assigns INVALID_HANDLE_VALUE. + // Note that this cannot verify whether the original handle is closed. + auto_handle.Reset(); + EXPECT_EQ(INVALID_HANDLE_VALUE, auto_handle.Get()); + + // Tests that Reset assigns the new handle. + // Note that this cannot verify whether the original handle is closed. + handle = ::CreateEvent(NULL, FALSE, FALSE, NULL); + ASSERT_NE(INVALID_HANDLE_VALUE, handle); + auto_handle.Reset(handle); + EXPECT_EQ(handle, auto_handle.Get()); + + // Tests that AutoHandle contains INVALID_HANDLE_VALUE by default. + testing::internal::AutoHandle auto_handle2; + EXPECT_EQ(INVALID_HANDLE_VALUE, auto_handle2.Get()); +} +#endif // GTEST_OS_WINDOWS + +#if GTEST_OS_WINDOWS +typedef unsigned __int64 BiggestParsable; +typedef signed __int64 BiggestSignedParsable; +const BiggestParsable kBiggestParsableMax = ULLONG_MAX; +const BiggestParsable kBiggestSignedParsableMax = LLONG_MAX; +#else +typedef unsigned long long BiggestParsable; +typedef signed long long BiggestSignedParsable; +const BiggestParsable kBiggestParsableMax = + ::std::numeric_limits::max(); +const BiggestSignedParsable kBiggestSignedParsableMax = + ::std::numeric_limits::max(); +#endif // GTEST_OS_WINDOWS + +TEST(ParseNaturalNumberTest, RejectsInvalidFormat) { + BiggestParsable result = 0; + + // Rejects non-numbers. + EXPECT_FALSE(ParseNaturalNumber(String("non-number string"), &result)); + + // Rejects numbers with whitespace prefix. + EXPECT_FALSE(ParseNaturalNumber(String(" 123"), &result)); + + // Rejects negative numbers. + EXPECT_FALSE(ParseNaturalNumber(String("-123"), &result)); + + // Rejects numbers starting with a plus sign. + EXPECT_FALSE(ParseNaturalNumber(String("+123"), &result)); + errno = 0; +} + +TEST(ParseNaturalNumberTest, RejectsOverflownNumbers) { + BiggestParsable result = 0; + + EXPECT_FALSE(ParseNaturalNumber(String("99999999999999999999999"), &result)); + + signed char char_result = 0; + EXPECT_FALSE(ParseNaturalNumber(String("200"), &char_result)); + errno = 0; +} + +TEST(ParseNaturalNumberTest, AcceptsValidNumbers) { + BiggestParsable result = 0; + + result = 0; + ASSERT_TRUE(ParseNaturalNumber(String("123"), &result)); + EXPECT_EQ(123, result); + + // Check 0 as an edge case. + result = 1; + ASSERT_TRUE(ParseNaturalNumber(String("0"), &result)); + EXPECT_EQ(0, result); + + result = 1; + ASSERT_TRUE(ParseNaturalNumber(String("00000"), &result)); + EXPECT_EQ(0, result); +} + +TEST(ParseNaturalNumberTest, AcceptsTypeLimits) { + Message msg; + msg << kBiggestParsableMax; + + BiggestParsable result = 0; + EXPECT_TRUE(ParseNaturalNumber(msg.GetString(), &result)); + EXPECT_EQ(kBiggestParsableMax, result); + + Message msg2; + msg2 << kBiggestSignedParsableMax; + + BiggestSignedParsable signed_result = 0; + EXPECT_TRUE(ParseNaturalNumber(msg2.GetString(), &signed_result)); + EXPECT_EQ(kBiggestSignedParsableMax, signed_result); + + Message msg3; + msg3 << INT_MAX; + + int int_result = 0; + EXPECT_TRUE(ParseNaturalNumber(msg3.GetString(), &int_result)); + EXPECT_EQ(INT_MAX, int_result); + + Message msg4; + msg4 << UINT_MAX; + + unsigned int uint_result = 0; + EXPECT_TRUE(ParseNaturalNumber(msg4.GetString(), &uint_result)); + EXPECT_EQ(UINT_MAX, uint_result); +} + +TEST(ParseNaturalNumberTest, WorksForShorterIntegers) { + short short_result = 0; + ASSERT_TRUE(ParseNaturalNumber(String("123"), &short_result)); + EXPECT_EQ(123, short_result); + + signed char char_result = 0; + ASSERT_TRUE(ParseNaturalNumber(String("123"), &char_result)); + EXPECT_EQ(123, char_result); +} + +#if GTEST_OS_WINDOWS +TEST(EnvironmentTest, HandleFitsIntoSizeT) { + // TODO(vladl@google.com): Remove this test after this condition is verified + // in a static assertion in gtest-death-test.cc in the function + // GetStatusFileDescriptor. + ASSERT_TRUE(sizeof(HANDLE) <= sizeof(size_t)); +} +#endif // GTEST_OS_WINDOWS + #endif // GTEST_HAS_DEATH_TEST // Tests that a test case whose name ends with "DeathTest" works fine diff --git a/test/gtest-port_test.cc b/test/gtest-port_test.cc index 40d36bd1..0bda6f5e 100644 --- a/test/gtest-port_test.cc +++ b/test/gtest-port_test.cc @@ -80,13 +80,15 @@ TEST(GtestCheckSyntaxTest, WorksWithSwitch) { TEST(GtestCheckDeathTest, DiesWithCorrectOutputOnFailure) { const bool a_false_condition = false; - EXPECT_DEATH(GTEST_CHECK_(a_false_condition) << "Extra info", + const char regex[] = #ifdef _MSC_VER - "gtest-port_test\\.cc\\([0-9]+\\):" + "gtest-port_test\\.cc\\(\\d+\\):" #else - "gtest-port_test\\.cc:[0-9]+" + "gtest-port_test\\.cc:[0-9]+" #endif // _MSC_VER - ".*a_false_condition.*Extra info.*"); + ".*a_false_condition.*Extra info.*"; + + EXPECT_DEATH(GTEST_CHECK_(a_false_condition) << "Extra info", regex); } TEST(GtestCheckDeathTest, LivesSilentlyOnSuccess) { @@ -575,25 +577,25 @@ TEST(MatchRegexAnywhereTest, ReturnsTrueWhenMatchingNonPrefix) { // Tests RE's implicit constructors. TEST(RETest, ImplicitConstructorWorks) { - const RE empty = ""; + const RE empty(""); EXPECT_STREQ("", empty.pattern()); - const RE simple = "hello"; + const RE simple("hello"); EXPECT_STREQ("hello", simple.pattern()); } // Tests that RE's constructors reject invalid regular expressions. TEST(RETest, RejectsInvalidRegex) { EXPECT_NONFATAL_FAILURE({ - const RE normal = NULL; + const RE normal(NULL); }, "NULL is not a valid simple regular expression"); EXPECT_NONFATAL_FAILURE({ - const RE normal = ".*(\\w+"; + const RE normal(".*(\\w+"); }, "'(' is unsupported"); EXPECT_NONFATAL_FAILURE({ - const RE invalid = "^?"; + const RE invalid("^?"); }, "'?' can only follow a repeatable token"); } @@ -603,10 +605,10 @@ TEST(RETest, FullMatchWorks) { EXPECT_TRUE(RE::FullMatch("", empty)); EXPECT_FALSE(RE::FullMatch("a", empty)); - const RE re1 = "a"; + const RE re1("a"); EXPECT_TRUE(RE::FullMatch("a", re1)); - const RE re = "a.*z"; + const RE re("a.*z"); EXPECT_TRUE(RE::FullMatch("az", re)); EXPECT_TRUE(RE::FullMatch("axyz", re)); EXPECT_FALSE(RE::FullMatch("baz", re)); @@ -615,11 +617,11 @@ TEST(RETest, FullMatchWorks) { // Tests RE::PartialMatch(). TEST(RETest, PartialMatchWorks) { - const RE empty = ""; + const RE empty(""); EXPECT_TRUE(RE::PartialMatch("", empty)); EXPECT_TRUE(RE::PartialMatch("a", empty)); - const RE re = "a.*z"; + const RE re("a.*z"); EXPECT_TRUE(RE::PartialMatch("az", re)); EXPECT_TRUE(RE::PartialMatch("axyz", re)); EXPECT_TRUE(RE::PartialMatch("baz", re)); @@ -629,5 +631,15 @@ TEST(RETest, PartialMatchWorks) { #endif // GTEST_USES_POSIX_RE +#if GTEST_HAS_STD_STRING + +TEST(CaptureStderrTest, CapturesStdErr) { + CaptureStderr(); + fprintf(stderr, "abc"); + ASSERT_EQ("abc", GetCapturedStderr()); +} + +#endif // GTEST_HAS_STD_STRING + } // namespace internal } // namespace testing diff --git a/test/gtest_output_test_.cc b/test/gtest_output_test_.cc index a8ffa412..90d89b94 100644 --- a/test/gtest_output_test_.cc +++ b/test/gtest_output_test_.cc @@ -988,7 +988,18 @@ int main(int argc, char **argv) { if (testing::internal::GTEST_FLAG(internal_run_death_test) != "") { // Skip the usual output capturing if we're running as the child // process of an threadsafe-style death test. +#if GTEST_OS_WINDOWS +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable:4996) +#endif // _MSC_VER + freopen("nul:", "w", stdout); +#ifdef _MSC_VER +#pragma warning(pop) +#endif // _MSC_VER +#else freopen("/dev/null", "w", stdout); +#endif // GTEST_OS_WINDOWS return RUN_ALL_TESTS(); } #endif // GTEST_HAS_DEATH_TEST diff --git a/test/gtest_output_test_golden_win.txt b/test/gtest_output_test_golden_win.txt index 77903ba1..d8bb622b 100644 --- a/test/gtest_output_test_golden_win.txt +++ b/test/gtest_output_test_golden_win.txt @@ -5,10 +5,25 @@ gtest_output_test_.cc:#: error: Value of: false Expected: true gtest_output_test_.cc:#: error: Value of: 3 Expected: 2 -[==========] Running 52 tests from 21 test cases. +[==========] Running 57 tests from 26 test cases. [----------] Global test environment set-up. FooEnvironment::SetUp() called. BarEnvironment::SetUp() called. +[----------] 1 test from ADeathTest +[ RUN ] ADeathTest.ShouldRunFirst +[ OK ] ADeathTest.ShouldRunFirst +[----------] 1 test from ATypedDeathTest/0, where TypeParam = int +[ RUN ] ATypedDeathTest/0.ShouldRunFirst +[ OK ] ATypedDeathTest/0.ShouldRunFirst +[----------] 1 test from ATypedDeathTest/1, where TypeParam = double +[ RUN ] ATypedDeathTest/1.ShouldRunFirst +[ OK ] ATypedDeathTest/1.ShouldRunFirst +[----------] 1 test from My/ATypeParamDeathTest/0, where TypeParam = int +[ RUN ] My/ATypeParamDeathTest/0.ShouldRunFirst +[ OK ] My/ATypeParamDeathTest/0.ShouldRunFirst +[----------] 1 test from My/ATypeParamDeathTest/1, where TypeParam = double +[ RUN ] My/ATypeParamDeathTest/1.ShouldRunFirst +[ OK ] My/ATypeParamDeathTest/1.ShouldRunFirst [----------] 2 tests from PassingTest [ RUN ] PassingTest.PassingTest1 [ OK ] PassingTest.PassingTest1 @@ -445,8 +460,8 @@ Expected non-fatal failure. FooEnvironment::TearDown() called. gtest_output_test_.cc:#: error: Failed Expected fatal failure. -[==========] 52 tests from 21 test cases ran. -[ PASSED ] 16 tests. +[==========] 57 tests from 26 test cases ran. +[ PASSED ] 21 tests. [ FAILED ] 36 tests, listed below: [ FAILED ] FatalFailureTest.FatalFailureInSubroutine [ FAILED ] FatalFailureTest.FatalFailureInNestedSubroutine -- cgit v1.2.3 From 40e72a8a837b47cbfe2e695068c1845073ab2630 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Fri, 6 Mar 2009 20:05:23 +0000 Subject: Implements --gtest_throw_on_failure for using gtest with other testing frameworks. --- test/gtest_break_on_failure_unittest.py | 23 ++++- test/gtest_break_on_failure_unittest_.cc | 1 - test/gtest_env_var_test.py | 1 + test/gtest_env_var_test_.cc | 5 + test/gtest_throw_on_failure_ex_test.cc | 92 +++++++++++++++++ test/gtest_throw_on_failure_test.py | 171 +++++++++++++++++++++++++++++++ test/gtest_throw_on_failure_test_.cc | 56 ++++++++++ test/gtest_unittest.cc | 71 ++++++++++++- 8 files changed, 412 insertions(+), 8 deletions(-) create mode 100644 test/gtest_throw_on_failure_ex_test.cc create mode 100755 test/gtest_throw_on_failure_test.py create mode 100644 test/gtest_throw_on_failure_test_.cc (limited to 'test') diff --git a/test/gtest_break_on_failure_unittest.py b/test/gtest_break_on_failure_unittest.py index a295ac40..9c2855fd 100755 --- a/test/gtest_break_on_failure_unittest.py +++ b/test/gtest_break_on_failure_unittest.py @@ -42,7 +42,6 @@ __author__ = 'wan@google.com (Zhanyong Wan)' import gtest_test_utils import os -import signal import sys import unittest @@ -55,13 +54,17 @@ BREAK_ON_FAILURE_ENV_VAR = 'GTEST_BREAK_ON_FAILURE' # The command line flag for enabling/disabling the break-on-failure mode. BREAK_ON_FAILURE_FLAG = 'gtest_break_on_failure' +# The environment variable for enabling/disabling the throw-on-failure mode. +THROW_ON_FAILURE_ENV_VAR = 'GTEST_THROW_ON_FAILURE' + # Path to the gtest_break_on_failure_unittest_ program. EXE_PATH = os.path.join(gtest_test_utils.GetBuildDir(), - 'gtest_break_on_failure_unittest_'); + 'gtest_break_on_failure_unittest_') # Utilities. + def SetEnvVar(env_var, value): """Sets an environment variable to a given value; unsets it when the given value is None. @@ -74,8 +77,7 @@ def SetEnvVar(env_var, value): def Run(command): - """Runs a command; returns 1 if it was killed by a signal, or 0 otherwise. - """ + """Runs a command; returns 1 if it was killed by a signal, or 0 otherwise.""" p = gtest_test_utils.Subprocess(command) if p.terminated_by_signal: @@ -84,7 +86,8 @@ def Run(command): return 0 -# The unit test. +# The tests. + class GTestBreakOnFailureUnitTest(unittest.TestCase): """Tests using the GTEST_BREAK_ON_FAILURE environment variable or @@ -180,6 +183,16 @@ class GTestBreakOnFailureUnitTest(unittest.TestCase): flag_value='1', expect_seg_fault=1) + def testBreakOnFailureOverridesThrowOnFailure(self): + """Tests that gtest_break_on_failure overrides gtest_throw_on_failure.""" + + SetEnvVar(THROW_ON_FAILURE_ENV_VAR, '1') + try: + self.RunAndVerify(env_var_value=None, + flag_value='1', + expect_seg_fault=1) + finally: + SetEnvVar(THROW_ON_FAILURE_ENV_VAR, None) if __name__ == '__main__': gtest_test_utils.Main() diff --git a/test/gtest_break_on_failure_unittest_.cc b/test/gtest_break_on_failure_unittest_.cc index 26b5bd3c..10a1203b 100644 --- a/test/gtest_break_on_failure_unittest_.cc +++ b/test/gtest_break_on_failure_unittest_.cc @@ -54,7 +54,6 @@ TEST(Foo, Bar) { } // namespace - int main(int argc, char **argv) { #if GTEST_OS_WINDOWS // Suppresses display of the Windows error dialog upon encountering diff --git a/test/gtest_env_var_test.py b/test/gtest_env_var_test.py index 67a22493..c5acc5ca 100755 --- a/test/gtest_env_var_test.py +++ b/test/gtest_env_var_test.py @@ -103,6 +103,7 @@ def TestEnvVarAffectsFlag(command): TestFlag(command, 'output', 'tmp/foo.xml', '') TestFlag(command, 'print_time', '1', '0') TestFlag(command, 'repeat', '999', '1') + TestFlag(command, 'throw_on_failure', '1', '0') if IS_WINDOWS: TestFlag(command, 'catch_exceptions', '1', '0') diff --git a/test/gtest_env_var_test_.cc b/test/gtest_env_var_test_.cc index dd820e44..f7c78fcf 100644 --- a/test/gtest_env_var_test_.cc +++ b/test/gtest_env_var_test_.cc @@ -101,6 +101,11 @@ void PrintFlag(const char* flag) { return; } + if (strcmp(flag, "throw_on_failure") == 0) { + cout << GTEST_FLAG(throw_on_failure); + return; + } + cout << "Invalid flag name " << flag << ". Valid names are break_on_failure, color, filter, etc.\n"; exit(1); diff --git a/test/gtest_throw_on_failure_ex_test.cc b/test/gtest_throw_on_failure_ex_test.cc new file mode 100644 index 00000000..8bf9dc90 --- /dev/null +++ b/test/gtest_throw_on_failure_ex_test.cc @@ -0,0 +1,92 @@ +// Copyright 2009, 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) + +// Tests Google Test's throw-on-failure mode with exceptions enabled. + +#include + +#include +#include +#include +#include + +// Prints the given failure message and exits the program with +// non-zero. We use this instead of a Google Test assertion to +// indicate a failure, as the latter is been tested and cannot be +// relied on. +void Fail(const char* msg) { + printf("FAILURE: %s\n", msg); + fflush(stdout); + exit(1); +} + +// Tests that an assertion failure throws a subclass of +// std::runtime_error. +void TestFailureThrowsRuntimeError() { + testing::GTEST_FLAG(throw_on_failure) = true; + + // A successful assertion shouldn't throw. + try { + EXPECT_EQ(3, 3); + } catch(...) { + Fail("A successful assertion wrongfully threw."); + } + + // A failed assertion should throw a subclass of std::runtime_error. + try { + EXPECT_EQ(2, 3) << "Expected failure"; + } catch(const std::runtime_error& e) { + if (strstr(e.what(), "Expected failure") != NULL) + return; + + printf("%s", + "A failed assertion did throw an exception of the right type, " + "but the message is incorrect. Instead of containing \"Expected " + "failure\", it is:\n"); + Fail(e.what()); + } catch(...) { + Fail("A failed assertion threw the wrong type of exception."); + } + Fail("A failed assertion should've thrown but didn't."); +} + +int main(int argc, char** argv) { + testing::InitGoogleTest(&argc, argv); + + // We want to ensure that people can use Google Test assertions in + // other testing frameworks, as long as they initialize Google Test + // properly and set the thrown-on-failure mode. Therefore, we don't + // use Google Test's constructs for defining and running tests + // (e.g. TEST and RUN_ALL_TESTS) here. + + TestFailureThrowsRuntimeError(); + return 0; +} diff --git a/test/gtest_throw_on_failure_test.py b/test/gtest_throw_on_failure_test.py new file mode 100755 index 00000000..091e9334 --- /dev/null +++ b/test/gtest_throw_on_failure_test.py @@ -0,0 +1,171 @@ +#!/usr/bin/python2.4 +# +# Copyright 2009, 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. + +"""Tests Google Test's throw-on-failure mode with exceptions disabled. + +This script invokes gtest_throw_on_failure_test_ (a program written with +Google Test) with different environments and command line flags. +""" + +__author__ = 'wan@google.com (Zhanyong Wan)' + +import gtest_test_utils +import os +import unittest + + +# Constants. + +# The command line flag for enabling/disabling the throw-on-failure mode. +THROW_ON_FAILURE = 'gtest_throw_on_failure' + +# Path to the gtest_throw_on_failure_test_ program, compiled with +# exceptions disabled. +EXE_PATH = os.path.join(gtest_test_utils.GetBuildDir(), + 'gtest_throw_on_failure_test_') + + +# Utilities. + + +def SetEnvVar(env_var, value): + """Sets an environment variable to a given value; unsets it when the + given value is None. + """ + + env_var = env_var.upper() + if value is not None: + os.environ[env_var] = value + elif env_var in os.environ: + del os.environ[env_var] + + +def Run(command): + """Runs a command; returns True/False if its exit code is/isn't 0.""" + + print 'Running "%s". . .' % ' '.join(command) + return gtest_test_utils.Subprocess(command).exit_code == 0 + + +# The tests. TODO(wan@google.com): refactor the class to share common +# logic with code in gtest_break_on_failure_unittest.py. +class ThrowOnFailureTest(unittest.TestCase): + """Tests the throw-on-failure mode.""" + + def RunAndVerify(self, env_var_value, flag_value, should_fail): + """Runs gtest_throw_on_failure_test_ and verifies that it does + (or does not) exit with a non-zero code. + + Args: + env_var_value: value of the GTEST_BREAK_ON_FAILURE environment + variable; None if the variable should be unset. + flag_value: value of the --gtest_break_on_failure flag; + None if the flag should not be present. + should_fail: True iff the program is expected to fail. + """ + + SetEnvVar(THROW_ON_FAILURE, env_var_value) + + if env_var_value is None: + env_var_value_msg = ' is not set' + else: + env_var_value_msg = '=' + env_var_value + + if flag_value is None: + flag = '' + elif flag_value == '0': + flag = '--%s=0' % THROW_ON_FAILURE + else: + flag = '--%s' % THROW_ON_FAILURE + + command = [EXE_PATH] + if flag: + command.append(flag) + + if should_fail: + should_or_not = 'should' + else: + should_or_not = 'should not' + + failed = not Run(command) + + SetEnvVar(THROW_ON_FAILURE, None) + + msg = ('when %s%s, an assertion failure in "%s" %s cause a non-zero ' + 'exit code.' % + (THROW_ON_FAILURE, env_var_value_msg, ' '.join(command), + should_or_not)) + self.assert_(failed == should_fail, msg) + + def testDefaultBehavior(self): + """Tests the behavior of the default mode.""" + + self.RunAndVerify(env_var_value=None, flag_value=None, should_fail=False) + + def testThrowOnFailureEnvVar(self): + """Tests using the GTEST_THROW_ON_FAILURE environment variable.""" + + self.RunAndVerify(env_var_value='0', + flag_value=None, + should_fail=False) + self.RunAndVerify(env_var_value='1', + flag_value=None, + should_fail=True) + + def testThrowOnFailureFlag(self): + """Tests using the --gtest_throw_on_failure flag.""" + + self.RunAndVerify(env_var_value=None, + flag_value='0', + should_fail=False) + self.RunAndVerify(env_var_value=None, + flag_value='1', + should_fail=True) + + def testThrowOnFailureFlagOverridesEnvVar(self): + """Tests that --gtest_throw_on_failure overrides GTEST_THROW_ON_FAILURE.""" + + self.RunAndVerify(env_var_value='0', + flag_value='0', + should_fail=False) + self.RunAndVerify(env_var_value='0', + flag_value='1', + should_fail=True) + self.RunAndVerify(env_var_value='1', + flag_value='0', + should_fail=False) + self.RunAndVerify(env_var_value='1', + flag_value='1', + should_fail=True) + + +if __name__ == '__main__': + gtest_test_utils.Main() diff --git a/test/gtest_throw_on_failure_test_.cc b/test/gtest_throw_on_failure_test_.cc new file mode 100644 index 00000000..88fbd5a7 --- /dev/null +++ b/test/gtest_throw_on_failure_test_.cc @@ -0,0 +1,56 @@ +// Copyright 2009, 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) + +// Tests Google Test's throw-on-failure mode with exceptions disabled. +// +// This program must be compiled with exceptions disabled. It will be +// invoked by gtest_throw_on_failure_test.py, and is expected to exit +// with non-zero in the throw-on-failure mode or 0 otherwise. + +#include + +int main(int argc, char** argv) { + testing::InitGoogleTest(&argc, argv); + + // We want to ensure that people can use Google Test assertions in + // other testing frameworks, as long as they initialize Google Test + // properly and set the thrown-on-failure mode. Therefore, we don't + // use Google Test's constructs for defining and running tests + // (e.g. TEST and RUN_ALL_TESTS) here. + + // In the throw-on-failure mode with exceptions disabled, this + // assertion will cause the program to exit with a non-zero code. + EXPECT_EQ(2, 3); + + // When not in the throw-on-failure mode, the control will reach + // here. + return 0; +} diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index 8dabcc9a..9a731eeb 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -48,7 +48,8 @@ TEST(CommandLineFlagsTest, CanBeAccessedInCodeOnceGTestHIsIncluded) { || testing::GTEST_FLAG(print_time) || testing::GTEST_FLAG(repeat) > 0 || testing::GTEST_FLAG(show_internal_stack_frames) - || testing::GTEST_FLAG(stack_trace_depth) > 0; + || testing::GTEST_FLAG(stack_trace_depth) > 0 + || testing::GTEST_FLAG(throw_on_failure); EXPECT_TRUE(dummy || !dummy); // Suppresses warning that dummy is unused. } @@ -115,6 +116,7 @@ using testing::GTEST_FLAG(print_time); using testing::GTEST_FLAG(repeat); using testing::GTEST_FLAG(show_internal_stack_frames); using testing::GTEST_FLAG(stack_trace_depth); +using testing::GTEST_FLAG(throw_on_failure); using testing::IsNotSubstring; using testing::IsSubstring; using testing::Message; @@ -1203,6 +1205,7 @@ class GTestFlagSaverTest : public Test { GTEST_FLAG(output) = ""; GTEST_FLAG(print_time) = false; GTEST_FLAG(repeat) = 1; + GTEST_FLAG(throw_on_failure) = false; } // Restores the Google Test flags that the tests have modified. This will @@ -1225,6 +1228,7 @@ class GTestFlagSaverTest : public Test { EXPECT_STREQ("", GTEST_FLAG(output).c_str()); EXPECT_FALSE(GTEST_FLAG(print_time)); EXPECT_EQ(1, GTEST_FLAG(repeat)); + EXPECT_FALSE(GTEST_FLAG(throw_on_failure)); GTEST_FLAG(also_run_disabled_tests) = true; GTEST_FLAG(break_on_failure) = true; @@ -1236,6 +1240,7 @@ class GTestFlagSaverTest : public Test { GTEST_FLAG(output) = "xml:foo.xml"; GTEST_FLAG(print_time) = true; GTEST_FLAG(repeat) = 100; + GTEST_FLAG(throw_on_failure) = true; } private: // For saving Google Test flags during this test case. @@ -4320,7 +4325,8 @@ struct Flags { list_tests(false), output(""), print_time(false), - repeat(1) {} + repeat(1), + throw_on_failure(false) {} // Factory methods. @@ -4396,6 +4402,14 @@ struct Flags { return flags; } + // Creates a Flags struct where the gtest_throw_on_failure flag has + // the given value. + static Flags ThrowOnFailure(bool throw_on_failure) { + Flags flags; + flags.throw_on_failure = throw_on_failure; + return flags; + } + // These fields store the flag values. bool also_run_disabled_tests; bool break_on_failure; @@ -4406,6 +4420,7 @@ struct Flags { const char* output; bool print_time; Int32 repeat; + bool throw_on_failure; }; // Fixture for testing InitGoogleTest(). @@ -4422,6 +4437,7 @@ class InitGoogleTestTest : public Test { GTEST_FLAG(output) = ""; GTEST_FLAG(print_time) = false; GTEST_FLAG(repeat) = 1; + GTEST_FLAG(throw_on_failure) = false; } // Asserts that two narrow or wide string arrays are equal. @@ -4447,6 +4463,7 @@ class InitGoogleTestTest : public Test { EXPECT_STREQ(expected.output, GTEST_FLAG(output).c_str()); EXPECT_EQ(expected.print_time, GTEST_FLAG(print_time)); EXPECT_EQ(expected.repeat, GTEST_FLAG(repeat)); + EXPECT_EQ(expected.throw_on_failure, GTEST_FLAG(throw_on_failure)); } // Parses a command line (specified by argc1 and argv1), then @@ -4993,6 +5010,56 @@ TEST_F(InitGoogleTestTest, AlsoRunDisabledTestsFalse) { GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::AlsoRunDisabledTests(false)); } + +// Tests parsing --gtest_throw_on_failure. +TEST_F(InitGoogleTestTest, ThrowOnFailureNoDef) { + const char* argv[] = { + "foo.exe", + "--gtest_throw_on_failure", + NULL +}; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ThrowOnFailure(true)); +} + +// Tests parsing --gtest_throw_on_failure=0. +TEST_F(InitGoogleTestTest, ThrowOnFailureFalse_0) { + const char* argv[] = { + "foo.exe", + "--gtest_throw_on_failure=0", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ThrowOnFailure(false)); +} + +// Tests parsing a --gtest_throw_on_failure flag that has a "true" +// definition. +TEST_F(InitGoogleTestTest, ThrowOnFailureTrue) { + const char* argv[] = { + "foo.exe", + "--gtest_throw_on_failure=1", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ThrowOnFailure(true)); +} + #if GTEST_OS_WINDOWS // Tests parsing wide strings. TEST_F(InitGoogleTestTest, WideStrings) { -- cgit v1.2.3 From 44a041b711ff4a5b5f341f21127aed46dbfe38ad Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Wed, 11 Mar 2009 18:31:26 +0000 Subject: Fixes death-test-related tests on Windows, by Vlad Losev. --- test/gtest-death-test_test.cc | 9 ++++++--- test/gtest-typed-test_test.cc | 8 ++++---- 2 files changed, 10 insertions(+), 7 deletions(-) (limited to 'test') diff --git a/test/gtest-death-test_test.cc b/test/gtest-death-test_test.cc index 4151ef0e..e794a09e 100644 --- a/test/gtest-death-test_test.cc +++ b/test/gtest-death-test_test.cc @@ -46,6 +46,7 @@ #include #include #include + #include // Indicates that this translation unit is part of Google Test's @@ -284,14 +285,16 @@ void DieWithEmbeddedNul() { _exit(1); } +#if GTEST_USES_PCRE // Tests that EXPECT_DEATH and ASSERT_DEATH work when the error // message has a NUL character in it. -TEST_F(TestForDeathTest, DISABLED_EmbeddedNulInMessage) { +TEST_F(TestForDeathTest, EmbeddedNulInMessage) { // TODO(wan@google.com): doesn't support matching strings // with embedded NUL characters - find a way to workaround it. EXPECT_DEATH(DieWithEmbeddedNul(), "w.*ld"); ASSERT_DEATH(DieWithEmbeddedNul(), "w.*ld"); } +#endif // GTEST_USES_PCRE // Tests that death test macros expand to code which interacts well with switch // statements. @@ -594,7 +597,7 @@ void ExpectDebugDeathHelper(bool* aborted) { } #if GTEST_OS_WINDOWS -TEST(TestForPopUps, DoesNotShowPopUpOnAbort) { +TEST(PopUpDeathTest, DoesNotShowPopUpOnAbort) { printf("This test should be considered failing if it shows " "any pop-up dialogs.\n"); fflush(stdout); @@ -605,7 +608,7 @@ TEST(TestForPopUps, DoesNotShowPopUpOnAbort) { }, ""); } -TEST(TestForPopUps, DoesNotShowPopUpOnThrow) { +TEST(PopUpDeathTest, DoesNotShowPopUpOnThrow) { printf("This test should be considered failing if it shows " "any pop-up dialogs.\n"); fflush(stdout); diff --git a/test/gtest-typed-test_test.cc b/test/gtest-typed-test_test.cc index 9ba9675f..eb921a06 100644 --- a/test/gtest-typed-test_test.cc +++ b/test/gtest-typed-test_test.cc @@ -205,19 +205,19 @@ typedef TypedTestCasePStateTest TypedTestCasePStateDeathTest; TEST_F(TypedTestCasePStateDeathTest, DetectsDuplicates) { EXPECT_DEATH( state_.VerifyRegisteredTestNames("foo.cc", 1, "A, B, A, C"), - "foo\\.cc:1: Test A is listed more than once\\."); + "foo\\.cc.1.?: Test A is listed more than once\\."); } TEST_F(TypedTestCasePStateDeathTest, DetectsExtraTest) { EXPECT_DEATH( state_.VerifyRegisteredTestNames("foo.cc", 1, "A, B, C, D"), - "foo\\.cc:1: No test named D can be found in this test case\\."); + "foo\\.cc.1.?: No test named D can be found in this test case\\."); } TEST_F(TypedTestCasePStateDeathTest, DetectsMissedTest) { EXPECT_DEATH( state_.VerifyRegisteredTestNames("foo.cc", 1, "A, C"), - "foo\\.cc:1: You forgot to list test B\\."); + "foo\\.cc.1.?: You forgot to list test B\\."); } // Tests that defining a test for a parameterized test case generates @@ -226,7 +226,7 @@ TEST_F(TypedTestCasePStateDeathTest, DetectsTestAfterRegistration) { state_.VerifyRegisteredTestNames("foo.cc", 1, "A, B, C"); EXPECT_DEATH( state_.AddTestName("foo.cc", 2, "FooTest", "D"), - "foo\\.cc:2: Test D must be defined before REGISTER_TYPED_TEST_CASE_P" + "foo\\.cc.2.?: Test D must be defined before REGISTER_TYPED_TEST_CASE_P" "\\(FooTest, \\.\\.\\.\\)\\."); } -- cgit v1.2.3 From 87d23e45f096c91c9e722b20bf15b733dbab0f80 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Wed, 11 Mar 2009 22:18:52 +0000 Subject: Implements the --help flag; fixes tests on Windows. --- test/gtest-death-test_test.cc | 13 +++++ test/gtest-filepath_test.cc | 12 ++-- test/gtest-options_test.cc | 40 ++++++++++--- test/gtest_all_test.cc | 1 - test/gtest_help_test.py | 127 ++++++++++++++++++++++++++++++++++++++++++ test/gtest_help_test_.cc | 42 ++++++++++++++ test/gtest_test_utils.py | 28 +++++----- 7 files changed, 233 insertions(+), 30 deletions(-) create mode 100755 test/gtest_help_test.py create mode 100644 test/gtest_help_test_.cc (limited to 'test') diff --git a/test/gtest-death-test_test.cc b/test/gtest-death-test_test.cc index e794a09e..aa7e31cd 100644 --- a/test/gtest-death-test_test.cc +++ b/test/gtest-death-test_test.cc @@ -33,6 +33,7 @@ #include #include +#include #if GTEST_HAS_DEATH_TEST @@ -62,6 +63,7 @@ using testing::Message; using testing::internal::DeathTest; using testing::internal::DeathTestFactory; +using testing::internal::FilePath; using testing::internal::GetLastSystemErrorMessage; using testing::internal::ParseNaturalNumber; using testing::internal::String; @@ -99,6 +101,16 @@ class ReplaceDeathTestFactory { class TestForDeathTest : public testing::Test { protected: + TestForDeathTest() : original_dir_(FilePath::GetCurrentDir()) {} + + virtual ~TestForDeathTest() { +#if GTEST_OS_WINDOWS + _chdir(original_dir_.c_str()); +#else + chdir(original_dir_.c_str()); +#endif + } + // A static member function that's expected to die. static void StaticMemberFunction() { fprintf(stderr, "%s", "death inside StaticMemberFunction()."); @@ -121,6 +133,7 @@ class TestForDeathTest : public testing::Test { // True iff MemberFunction() should die. bool should_die_; + const FilePath original_dir_; }; // A class with a member function that may die. diff --git a/test/gtest-filepath_test.cc b/test/gtest-filepath_test.cc index dfbd5f02..f8b68a78 100644 --- a/test/gtest-filepath_test.cc +++ b/test/gtest-filepath_test.cc @@ -50,16 +50,11 @@ #include "src/gtest-internal-inl.h" #undef GTEST_IMPLEMENTATION_ -#if GTEST_OS_WINDOWS #ifdef _WIN32_WCE #include // NOLINT -#else +#elif GTEST_OS_WINDOWS #include // NOLINT #endif // _WIN32_WCE -#define GTEST_PATH_SEP_ "\\" -#else -#define GTEST_PATH_SEP_ "/" -#endif // GTEST_OS_WINDOWS namespace testing { namespace internal { @@ -88,11 +83,13 @@ int _rmdir(const char* path) { #ifndef _WIN32_WCE TEST(GetCurrentDirTest, ReturnsCurrentDir) { - EXPECT_FALSE(FilePath::GetCurrentDir().IsEmpty()); + const FilePath original_dir = FilePath::GetCurrentDir(); + EXPECT_FALSE(original_dir.IsEmpty()); #if GTEST_OS_WINDOWS _chdir(GTEST_PATH_SEP_); const FilePath cwd = FilePath::GetCurrentDir(); + _chdir(original_dir.c_str()); // Skips the ":". const char* const cwd_without_drive = strchr(cwd.c_str(), ':'); ASSERT_TRUE(cwd_without_drive != NULL); @@ -100,6 +97,7 @@ TEST(GetCurrentDirTest, ReturnsCurrentDir) { #else chdir(GTEST_PATH_SEP_); EXPECT_STREQ(GTEST_PATH_SEP_, FilePath::GetCurrentDir().c_str()); + chdir(original_dir.c_str()); #endif } diff --git a/test/gtest-options_test.cc b/test/gtest-options_test.cc index 5f24e7e3..27a6fe54 100644 --- a/test/gtest-options_test.cc +++ b/test/gtest-options_test.cc @@ -98,7 +98,10 @@ TEST(XmlOutputTest, GetOutputFileFromDirectoryPath) { FilePath("path\\gtest-options_test.xml")).c_str()) == 0 || _strcmpi(output_file.c_str(), GetAbsolutePathOf( - FilePath("path\\gtest-options-ex_test.xml")).c_str()) == 0) + FilePath("path\\gtest-options-ex_test.xml")).c_str()) == 0 || + _strcmpi(output_file.c_str(), + GetAbsolutePathOf( + FilePath("path\\gtest_all_test.xml")).c_str()) == 0) << " output_file = " << output_file; #else GTEST_FLAG(output) = "xml:path/"; @@ -113,7 +116,13 @@ TEST(XmlOutputTest, GetOutputFileFromDirectoryPath) { FilePath("path/gtest-options_test.xml")).c_str() || output_file == GetAbsolutePathOf( - FilePath("path/lt-gtest-options_test.xml")).c_str()) + FilePath("path/lt-gtest-options_test.xml")).c_str() || + output_file == + GetAbsolutePathOf( + FilePath("path/gtest_all_test.xml")).c_str() || + output_file == + GetAbsolutePathOf( + FilePath("path/lt-gtest_all_test.xml")).c_str()) << " output_file = " << output_file; #endif } @@ -123,13 +132,16 @@ TEST(OutputFileHelpersTest, GetCurrentExecutableName) { const char* const exe_str = executable.c_str(); #if defined(_WIN32_WCE) || GTEST_OS_WINDOWS ASSERT_TRUE(_strcmpi("gtest-options_test", exe_str) == 0 || - _strcmpi("gtest-options-ex_test", exe_str) == 0) + _strcmpi("gtest-options-ex_test", exe_str) == 0 || + _strcmpi("gtest_all_test", exe_str) == 0) << "GetCurrentExecutableName() returns " << exe_str; #else // TODO(wan@google.com): remove the hard-coded "lt-" prefix when // Chandler Carruth's libtool replacement is ready. EXPECT_TRUE(String(exe_str) == "gtest-options_test" || - String(exe_str) == "lt-gtest-options_test") + String(exe_str) == "lt-gtest-options_test" || + String(exe_str) == "gtest_all_test" || + String(exe_str) == "lt-gtest_all_test") << "GetCurrentExecutableName() returns " << exe_str; #endif } @@ -192,7 +204,11 @@ TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithRelativePath) { _strcmpi(output_file.c_str(), FilePath::ConcatPaths( original_working_dir_, - FilePath("path\\gtest-options-ex_test.xml")).c_str()) == 0) + FilePath("path\\gtest-options-ex_test.xml")).c_str()) == 0 || + _strcmpi(output_file.c_str(), + FilePath::ConcatPaths( + original_working_dir_, + FilePath("path\\gtest_all_test.xml")).c_str()) == 0) << " output_file = " << output_file; #else GTEST_FLAG(output) = "xml:path/"; @@ -205,7 +221,11 @@ TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithRelativePath) { EXPECT_TRUE(output_file == FilePath::ConcatPaths(original_working_dir_, FilePath("path/gtest-options_test.xml")).c_str() || output_file == FilePath::ConcatPaths(original_working_dir_, - FilePath("path/lt-gtest-options_test.xml")).c_str()) + FilePath("path/lt-gtest-options_test.xml")).c_str() || + output_file == FilePath::ConcatPaths(original_working_dir_, + FilePath("path/gtest_all_test.xml")).c_str() || + output_file == FilePath::ConcatPaths(original_working_dir_, + FilePath("path/lt-gtest_all_test.xml")).c_str()) << " output_file = " << output_file; #endif } @@ -230,7 +250,9 @@ TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithAbsolutePath) { _strcmpi(output_file.c_str(), FilePath("c:\\tmp\\gtest-options_test.xml").c_str()) == 0 || _strcmpi(output_file.c_str(), - FilePath("c:\\tmp\\gtest-options-ex_test.xml").c_str()) == 0) + FilePath("c:\\tmp\\gtest-options-ex_test.xml").c_str()) == 0 || + _strcmpi(output_file.c_str(), + FilePath("c:\\tmp\\gtest_all_test.xml").c_str()) == 0) << " output_file = " << output_file; #else GTEST_FLAG(output) = "xml:/tmp/"; @@ -241,7 +263,9 @@ TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithAbsolutePath) { // hard-coded logic when Chandler Carruth's libtool replacement is // ready. EXPECT_TRUE(output_file == "/tmp/gtest-options_test.xml" || - output_file == "/tmp/lt-gtest-options_test.xml") + output_file == "/tmp/lt-gtest-options_test.xml" || + output_file == "/tmp/gtest_all_test.xml" || + output_file == "/tmp/lt-gtest_all_test.xml") << " output_file = " << output_file; #endif } diff --git a/test/gtest_all_test.cc b/test/gtest_all_test.cc index f73044d8..955aa628 100644 --- a/test/gtest_all_test.cc +++ b/test/gtest_all_test.cc @@ -33,7 +33,6 @@ // // Sometimes it's desirable to build most of Google Test's own tests // by compiling a single file. This file serves this purpose. -#include "test/gtest_environment_test.cc" #include "test/gtest-filepath_test.cc" #include "test/gtest-linked_ptr_test.cc" #include "test/gtest-message_test.cc" diff --git a/test/gtest_help_test.py b/test/gtest_help_test.py new file mode 100755 index 00000000..cc5819ce --- /dev/null +++ b/test/gtest_help_test.py @@ -0,0 +1,127 @@ +#!/usr/bin/python2.4 +# +# Copyright 2009, 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. + +"""Tests the --help flag of Google C++ Testing Framework. + +SYNOPSIS + gtest_help_test.py --gtest_build_dir=BUILD/DIR + # where BUILD/DIR contains the built gtest_help_test_ file. + gtest_help_test.py +""" + +__author__ = 'wan@google.com (Zhanyong Wan)' + +import gtest_test_utils +import os +import re +import unittest + + +IS_WINDOWS = os.name == 'nt' + +if IS_WINDOWS: + PROGRAM = 'gtest_help_test_.exe' +else: + PROGRAM = 'gtest_help_test_' + +PROGRAM_PATH = os.path.join(gtest_test_utils.GetBuildDir(), PROGRAM) +FLAG_PREFIX = '--gtest_' +CATCH_EXCEPTIONS_FLAG = FLAG_PREFIX + 'catch_exceptions' + +# The help message must match this regex. +HELP_REGEX = re.compile( + FLAG_PREFIX + r'list_tests.*' + + FLAG_PREFIX + r'filter=.*' + + FLAG_PREFIX + r'also_run_disabled_tests.*' + + FLAG_PREFIX + r'repeat=.*' + + FLAG_PREFIX + r'color=.*' + + FLAG_PREFIX + r'print_time.*' + + FLAG_PREFIX + r'output=.*' + + FLAG_PREFIX + r'break_on_failure.*' + + FLAG_PREFIX + r'throw_on_failure.*', + re.DOTALL) + + +def RunWithFlag(flag): + """Runs gtest_help_test_ with the given flag. + + Returns: + the exit code and the text output as a tuple. + Args: + flag: the command-line flag to pass to gtest_help_test_, or None. + """ + + if flag is None: + command = [PROGRAM_PATH] + else: + command = [PROGRAM_PATH, flag] + child = gtest_test_utils.Subprocess(command) + return child.exit_code, child.output + + +class GTestHelpTest(unittest.TestCase): + """Tests the --help flag and its equivalent forms.""" + + def TestHelpFlag(self, flag): + """Verifies that the right message is printed and the tests are + skipped when the given flag is specified.""" + + exit_code, output = RunWithFlag(flag) + self.assertEquals(0, exit_code) + self.assert_(HELP_REGEX.search(output), output) + if IS_WINDOWS: + self.assert_(CATCH_EXCEPTIONS_FLAG in output, output) + else: + self.assert_(CATCH_EXCEPTIONS_FLAG not in output, output) + + def testPrintsHelpWithFullFlag(self): + self.TestHelpFlag('--help') + + def testPrintsHelpWithShortFlag(self): + self.TestHelpFlag('-h') + + def testPrintsHelpWithQuestionFlag(self): + self.TestHelpFlag('-?') + + def testPrintsHelpWithWindowsStyleQuestionFlag(self): + self.TestHelpFlag('/?') + + def testRunsTestsWithoutHelpFlag(self): + """Verifies that when no help flag is specified, the tests are run + and the help message is not printed.""" + + exit_code, output = RunWithFlag(None) + self.assert_(exit_code != 0) + self.assert_(not HELP_REGEX.search(output), output) + + +if __name__ == '__main__': + gtest_test_utils.Main() diff --git a/test/gtest_help_test_.cc b/test/gtest_help_test_.cc new file mode 100644 index 00000000..0282bc88 --- /dev/null +++ b/test/gtest_help_test_.cc @@ -0,0 +1,42 @@ +// Copyright 2009, 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) + +// This program is meant to be run by gtest_help_test.py. Do not run +// it directly. + +#include + +// When a help flag is specified, this program should skip the tests +// and exit with 0; otherwise the following test will be executed, +// causing this program to exit with a non-zero code. +TEST(HelpFlagTest, ShouldNotBeRun) { + ASSERT_TRUE(false) << "Tests shouldn't be run when --help is specified."; +} diff --git a/test/gtest_test_utils.py b/test/gtest_test_utils.py index 8ee99c08..8f55b075 100755 --- a/test/gtest_test_utils.py +++ b/test/gtest_test_utils.py @@ -124,7 +124,7 @@ def GetExitStatus(exit_code): class Subprocess: - def __init__(this, command, working_dir=None): + def __init__(self, command, working_dir=None): """Changes into a specified directory, if provided, and executes a command. Restores the old directory afterwards. Execution results are returned via the following attributes: @@ -137,7 +137,7 @@ class Subprocess: combined in a string. Args: - command: A command to run. + command: A command to run, in the form of sys.argv. working_dir: A directory to change into. """ @@ -154,8 +154,8 @@ class Subprocess: cwd=working_dir, universal_newlines=True) # communicate returns a tuple with the file obect for the child's # output. - this.output = p.communicate()[0] - this._return_code = p.returncode + self.output = p.communicate()[0] + self._return_code = p.returncode else: old_dir = os.getcwd() try: @@ -163,25 +163,25 @@ class Subprocess: os.chdir(working_dir) p = popen2.Popen4(command) p.tochild.close() - this.output = p.fromchild.read() + self.output = p.fromchild.read() ret_code = p.wait() finally: os.chdir(old_dir) # Converts ret_code to match the semantics of # subprocess.Popen.returncode. if os.WIFSIGNALED(ret_code): - this._return_code = -os.WTERMSIG(ret_code) + self._return_code = -os.WTERMSIG(ret_code) else: # os.WIFEXITED(ret_code) should return True here. - this._return_code = os.WEXITSTATUS(ret_code) + self._return_code = os.WEXITSTATUS(ret_code) - if this._return_code < 0: - this.terminated_by_signal = True - this.exited = False - this.signal = -this._return_code + if self._return_code < 0: + self.terminated_by_signal = True + self.exited = False + self.signal = -self._return_code else: - this.terminated_by_signal = False - this.exited = True - this.exit_code = this._return_code + self.terminated_by_signal = False + self.exited = True + self.exit_code = self._return_code def Main(): -- cgit v1.2.3 From 9623aed82cf3e0dcd2fb2fb7442a5a9507ac55a5 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Tue, 17 Mar 2009 21:03:35 +0000 Subject: Enables death tests on Cygwin and Mac (by Vlad Losev); fixes a python test on Mac. --- test/gtest-death-test_test.cc | 5 +++-- test/gtest_filter_unittest.py | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) (limited to 'test') diff --git a/test/gtest-death-test_test.cc b/test/gtest-death-test_test.cc index aa7e31cd..2c283b63 100644 --- a/test/gtest-death-test_test.cc +++ b/test/gtest-death-test_test.cc @@ -41,6 +41,7 @@ #include // For chdir(). #else #include +#include // For waitpid. #include // For std::numeric_limits. #endif // GTEST_OS_WINDOWS @@ -414,7 +415,7 @@ void SetPthreadFlag() { } // namespace -#if !GTEST_OS_WINDOWS +#if GTEST_HAS_CLONE TEST_F(TestForDeathTest, DoesNotExecuteAtforkHooks) { if (!testing::GTEST_FLAG(death_test_use_fork)) { @@ -426,7 +427,7 @@ TEST_F(TestForDeathTest, DoesNotExecuteAtforkHooks) { } } -#endif // !GTEST_OS_WINDOWS +#endif // GTEST_HAS_CLONE // Tests that a method of another class can be used in a death test. TEST_F(TestForDeathTest, MethodOfAnotherClass) { diff --git a/test/gtest_filter_unittest.py b/test/gtest_filter_unittest.py index c3a016cf..cd88cdf7 100755 --- a/test/gtest_filter_unittest.py +++ b/test/gtest_filter_unittest.py @@ -202,7 +202,7 @@ class GTestFilterUnitTest(unittest.TestCase): for slice_var in list_of_sets: full_partition.extend(slice_var) self.assertEqual(len(set_var), len(full_partition)) - self.assertEqual(sorted(set_var), sorted(full_partition)) + self.assertEqual(sets.Set(set_var), sets.Set(full_partition)) def RunAndVerify(self, gtest_filter, tests_to_run): """Runs gtest_flag_unittest_ with the given filter, and verifies -- cgit v1.2.3 From 61e953e8c39d9a82823cddc9581b5bcd583e49d4 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Tue, 17 Mar 2009 21:19:55 +0000 Subject: Fixes two tests on Cygwin, which has no python 2.4. --- test/gtest_help_test.py | 2 +- test/gtest_throw_on_failure_test.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'test') diff --git a/test/gtest_help_test.py b/test/gtest_help_test.py index cc5819ce..98c8fe75 100755 --- a/test/gtest_help_test.py +++ b/test/gtest_help_test.py @@ -1,4 +1,4 @@ -#!/usr/bin/python2.4 +#!/usr/bin/env python # # Copyright 2009, Google Inc. # All rights reserved. diff --git a/test/gtest_throw_on_failure_test.py b/test/gtest_throw_on_failure_test.py index 091e9334..a80d6172 100755 --- a/test/gtest_throw_on_failure_test.py +++ b/test/gtest_throw_on_failure_test.py @@ -1,4 +1,4 @@ -#!/usr/bin/python2.4 +#!/usr/bin/env python # # Copyright 2009, Google Inc. # All rights reserved. -- cgit v1.2.3 From 2c0fc6d415343b732a4ae39cce1458be1170b9f6 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Tue, 24 Mar 2009 20:39:44 +0000 Subject: Cleans up death test implementation (by Vlad Losev); changes the XML format to be closer to junitreport (by Zhanyong Wan). --- test/gtest-death-test_test.cc | 17 +++++------------ test/gtest_xml_outfiles_test.py | 8 ++++---- test/gtest_xml_output_unittest.py | 8 ++++---- test/gtest_xml_test_utils.py | 25 +++++++++++++------------ 4 files changed, 26 insertions(+), 32 deletions(-) (limited to 'test') diff --git a/test/gtest-death-test_test.cc b/test/gtest-death-test_test.cc index 2c283b63..a6d7b18d 100644 --- a/test/gtest-death-test_test.cc +++ b/test/gtest-death-test_test.cc @@ -65,7 +65,7 @@ using testing::Message; using testing::internal::DeathTest; using testing::internal::DeathTestFactory; using testing::internal::FilePath; -using testing::internal::GetLastSystemErrorMessage; +using testing::internal::GetLastErrnoDescription; using testing::internal::ParseNaturalNumber; using testing::internal::String; @@ -990,20 +990,13 @@ TEST(StreamingAssertionsDeathTest, DeathTest) { }, "expected failure"); } -// Tests that GetLastSystemErrorMessage returns an empty string when the +// Tests that GetLastErrnoDescription returns an empty string when the // last error is 0 and non-empty string when it is non-zero. -TEST(GetLastSystemErrorMessageTest, GetLastSystemErrorMessageWorks) { -#if GTEST_OS_WINDOWS - ::SetLastError(ERROR_FILE_NOT_FOUND); - EXPECT_STRNE("", GetLastSystemErrorMessage().c_str()); - ::SetLastError(0); - EXPECT_STREQ("", GetLastSystemErrorMessage().c_str()); -#else +TEST(GetLastErrnoDescription, GetLastErrnoDescriptionWorks) { errno = ENOENT; - EXPECT_STRNE("", GetLastSystemErrorMessage().c_str()); + EXPECT_STRNE("", GetLastErrnoDescription().c_str()); errno = 0; - EXPECT_STREQ("", GetLastSystemErrorMessage().c_str()); -#endif + EXPECT_STREQ("", GetLastErrnoDescription().c_str()); } #if GTEST_OS_WINDOWS diff --git a/test/gtest_xml_outfiles_test.py b/test/gtest_xml_outfiles_test.py index 4ebc15ef..3e91f6de 100755 --- a/test/gtest_xml_outfiles_test.py +++ b/test/gtest_xml_outfiles_test.py @@ -48,19 +48,19 @@ GTEST_OUTPUT_1_TEST = "gtest_xml_outfile1_test_" GTEST_OUTPUT_2_TEST = "gtest_xml_outfile2_test_" EXPECTED_XML_1 = """ - + - + """ EXPECTED_XML_2 = """ - + - + """ diff --git a/test/gtest_xml_output_unittest.py b/test/gtest_xml_output_unittest.py index 5e0b220b..4587c41b 100755 --- a/test/gtest_xml_output_unittest.py +++ b/test/gtest_xml_output_unittest.py @@ -48,7 +48,7 @@ GTEST_OUTPUT_FLAG = "--gtest_output" GTEST_DEFAULT_OUTPUT_FILE = "test_detail.xml" EXPECTED_NON_EMPTY_XML = """ - + @@ -85,12 +85,12 @@ Expected: 2]]> -""" +""" EXPECTED_EMPTY_XML = """ - -""" + +""" class GTestXMLOutputUnitTest(gtest_xml_test_utils.GTestXMLTestCase): diff --git a/test/gtest_xml_test_utils.py b/test/gtest_xml_test_utils.py index 5694dff9..00a56cbf 100755 --- a/test/gtest_xml_test_utils.py +++ b/test/gtest_xml_test_utils.py @@ -92,6 +92,7 @@ class GTestXMLTestCase(unittest.TestCase): self.AssertEquivalentNodes(child, actual_children[child_id]) identifying_attribute = { + "testsuites": "name", "testsuite": "name", "testcase": "name", "failure": "message", @@ -101,14 +102,14 @@ class GTestXMLTestCase(unittest.TestCase): """ Fetches all of the child nodes of element, a DOM Element object. Returns them as the values of a dictionary keyed by the IDs of the - children. For and elements, the ID is the - value of their "name" attribute; for elements, it is the - value of the "message" attribute; for CDATA section node, it is - "detail". An exception is raised if any element other than the - above four is encountered, if two child elements with the same - identifying attributes are encountered, or if any other type of - node is encountered, other than Text nodes containing only - whitespace. + children. For , and elements, + the ID is the value of their "name" attribute; for + elements, it is the value of the "message" attribute; for CDATA + section node, it is "detail". An exception is raised if any + element other than the above four is encountered, if two child + elements with the same identifying attributes are encountered, or + if any other type of node is encountered, other than Text nodes + containing only whitespace. """ children = {} @@ -133,16 +134,16 @@ class GTestXMLTestCase(unittest.TestCase): Normalizes Google Test's XML output to eliminate references to transient information that may change from run to run. - * The "time" attribute of and elements is - replaced with a single asterisk, if it contains only digit - characters. + * The "time" attribute of , and + elements is replaced with a single asterisk, if it contains + only digit characters. * The line number reported in the first line of the "message" attribute of elements is replaced with a single asterisk. * The directory names in file paths are removed. * The stack traces are removed. """ - if element.tagName in ("testsuite", "testcase"): + if element.tagName in ("testsuites", "testsuite", "testcase"): time = element.getAttributeNode("time") time.value = re.sub(r"^\d+(\.\d+)?$", "*", time.value) elif element.tagName == "failure": -- cgit v1.2.3 From 3c7bbf5b46679aea4e0ac7d3ad241cb036146751 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Thu, 26 Mar 2009 19:03:47 +0000 Subject: Simplifies implementation by defining a POSIX portability layer; adds the death test style flag to --help. --- test/gtest-death-test_test.cc | 17 ++++------------- test/gtest-filepath_test.cc | 42 +++++++++--------------------------------- test/gtest-options_test.cc | 12 ++---------- test/gtest_help_test.py | 3 +++ test/gtest_output_test_.cc | 12 +++--------- 5 files changed, 21 insertions(+), 65 deletions(-) (limited to 'test') diff --git a/test/gtest-death-test_test.cc b/test/gtest-death-test_test.cc index a6d7b18d..db5f72e0 100644 --- a/test/gtest-death-test_test.cc +++ b/test/gtest-death-test_test.cc @@ -60,8 +60,9 @@ #include "src/gtest-internal-inl.h" #undef GTEST_IMPLEMENTATION_ -using testing::Message; +namespace posix = ::testing::internal::posix; +using testing::Message; using testing::internal::DeathTest; using testing::internal::DeathTestFactory; using testing::internal::FilePath; @@ -105,11 +106,7 @@ class TestForDeathTest : public testing::Test { TestForDeathTest() : original_dir_(FilePath::GetCurrentDir()) {} virtual ~TestForDeathTest() { -#if GTEST_OS_WINDOWS - _chdir(original_dir_.c_str()); -#else - chdir(original_dir_.c_str()); -#endif + posix::chdir(original_dir_.c_str()); } // A static member function that's expected to die. @@ -348,13 +345,7 @@ TEST_F(TestForDeathTest, MemberFunctionFastStyle) { EXPECT_DEATH(MemberFunction(), "inside.*MemberFunction"); } -void ChangeToRootDir() { -#if GTEST_OS_WINDOWS - _chdir("\\"); -#else - chdir("/"); -#endif // GTEST_OS_WINDOWS -} +void ChangeToRootDir() { posix::chdir(GTEST_PATH_SEP_); } // Tests that death tests work even if the current directory has been // changed. diff --git a/test/gtest-filepath_test.cc b/test/gtest-filepath_test.cc index f8b68a78..77a2988e 100644 --- a/test/gtest-filepath_test.cc +++ b/test/gtest-filepath_test.cc @@ -86,18 +86,17 @@ TEST(GetCurrentDirTest, ReturnsCurrentDir) { const FilePath original_dir = FilePath::GetCurrentDir(); EXPECT_FALSE(original_dir.IsEmpty()); -#if GTEST_OS_WINDOWS - _chdir(GTEST_PATH_SEP_); + posix::chdir(GTEST_PATH_SEP_); const FilePath cwd = FilePath::GetCurrentDir(); - _chdir(original_dir.c_str()); + posix::chdir(original_dir.c_str()); + +#if GTEST_OS_WINDOWS // Skips the ":". const char* const cwd_without_drive = strchr(cwd.c_str(), ':'); ASSERT_TRUE(cwd_without_drive != NULL); EXPECT_STREQ(GTEST_PATH_SEP_, cwd_without_drive + 1); #else - chdir(GTEST_PATH_SEP_); - EXPECT_STREQ(GTEST_PATH_SEP_, FilePath::GetCurrentDir().c_str()); - chdir(original_dir.c_str()); + EXPECT_STREQ(GTEST_PATH_SEP_, cwd.c_str()); #endif } @@ -436,22 +435,14 @@ class DirectoryCreationTest : public Test { remove(testdata_file_.c_str()); remove(unique_file0_.c_str()); remove(unique_file1_.c_str()); -#if GTEST_OS_WINDOWS - _rmdir(testdata_path_.c_str()); -#else - rmdir(testdata_path_.c_str()); -#endif // GTEST_OS_WINDOWS + posix::rmdir(testdata_path_.c_str()); } virtual void TearDown() { remove(testdata_file_.c_str()); remove(unique_file0_.c_str()); remove(unique_file1_.c_str()); -#if GTEST_OS_WINDOWS - _rmdir(testdata_path_.c_str()); -#else - rmdir(testdata_path_.c_str()); -#endif // GTEST_OS_WINDOWS + posix::rmdir(testdata_path_.c_str()); } String TempDir() const { @@ -459,13 +450,7 @@ class DirectoryCreationTest : public Test { return String("\\temp\\"); #elif GTEST_OS_WINDOWS - // MSVC 8 deprecates getenv(), so we want to suppress warning 4996 - // (deprecated function) there. -#pragma warning(push) // Saves the current warning state. -#pragma warning(disable:4996) // Temporarily disables warning 4996. - const char* temp_dir = getenv("TEMP"); -#pragma warning(pop) // Restores the warning state. - + const char* temp_dir = posix::getenv("TEMP"); if (temp_dir == NULL || temp_dir[0] == '\0') return String("\\temp\\"); else if (String(temp_dir).EndsWith("\\")) @@ -478,16 +463,7 @@ class DirectoryCreationTest : public Test { } void CreateTextFile(const char* filename) { -#if GTEST_OS_WINDOWS - // MSVC 8 deprecates fopen(), so we want to suppress warning 4996 - // (deprecated function) there.#pragma warning(push) -#pragma warning(push) // Saves the current warning state. -#pragma warning(disable:4996) // Temporarily disables warning 4996. - FILE* f = fopen(filename, "w"); -#pragma warning(pop) // Restores the warning state. -#else // We are on Linux or Mac OS. - FILE* f = fopen(filename, "w"); -#endif // GTEST_OS_WINDOWS + FILE* f = posix::fopen(filename, "w"); fprintf(f, "text\n"); fclose(f); } diff --git a/test/gtest-options_test.cc b/test/gtest-options_test.cc index 27a6fe54..d49efe49 100644 --- a/test/gtest-options_test.cc +++ b/test/gtest-options_test.cc @@ -150,22 +150,14 @@ class XmlOutputChangeDirTest : public Test { protected: virtual void SetUp() { original_working_dir_ = FilePath::GetCurrentDir(); - ChDir(".."); + posix::chdir(".."); // This will make the test fail if run from the root directory. EXPECT_STRNE(original_working_dir_.c_str(), FilePath::GetCurrentDir().c_str()); } virtual void TearDown() { - ChDir(original_working_dir_.c_str()); - } - - void ChDir(const char* dir) { -#if GTEST_OS_WINDOWS - _chdir(dir); -#else - chdir(dir); -#endif + posix::chdir(original_working_dir_.c_str()); } FilePath original_working_dir_; diff --git a/test/gtest_help_test.py b/test/gtest_help_test.py index 98c8fe75..62710192 100755 --- a/test/gtest_help_test.py +++ b/test/gtest_help_test.py @@ -55,6 +55,7 @@ else: PROGRAM_PATH = os.path.join(gtest_test_utils.GetBuildDir(), PROGRAM) FLAG_PREFIX = '--gtest_' CATCH_EXCEPTIONS_FLAG = FLAG_PREFIX + 'catch_exceptions' +DEATH_TEST_STYLE_FLAG = FLAG_PREFIX + 'death_test_style' # The help message must match this regex. HELP_REGEX = re.compile( @@ -99,8 +100,10 @@ class GTestHelpTest(unittest.TestCase): self.assert_(HELP_REGEX.search(output), output) if IS_WINDOWS: self.assert_(CATCH_EXCEPTIONS_FLAG in output, output) + self.assert_(DEATH_TEST_STYLE_FLAG not in output, output) else: self.assert_(CATCH_EXCEPTIONS_FLAG not in output, output) + self.assert_(DEATH_TEST_STYLE_FLAG in output, output) def testPrintsHelpWithFullFlag(self): self.TestHelpFlag('--help') diff --git a/test/gtest_output_test_.cc b/test/gtest_output_test_.cc index 90d89b94..c867e159 100644 --- a/test/gtest_output_test_.cc +++ b/test/gtest_output_test_.cc @@ -60,6 +60,7 @@ using testing::ScopedFakeTestPartResultReporter; using testing::TestPartResultArray; +namespace posix = ::testing::internal::posix; using testing::internal::String; // Tests catching fatal failures. @@ -989,16 +990,9 @@ int main(int argc, char **argv) { // Skip the usual output capturing if we're running as the child // process of an threadsafe-style death test. #if GTEST_OS_WINDOWS -#ifdef _MSC_VER -#pragma warning(push) -#pragma warning(disable:4996) -#endif // _MSC_VER - freopen("nul:", "w", stdout); -#ifdef _MSC_VER -#pragma warning(pop) -#endif // _MSC_VER + posix::freopen("nul:", "w", stdout); #else - freopen("/dev/null", "w", stdout); + posix::freopen("/dev/null", "w", stdout); #endif // GTEST_OS_WINDOWS return RUN_ALL_TESTS(); } -- cgit v1.2.3 From 3e54f5a3715f2c0b4425e55cc5d42dd42f4eda54 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Tue, 31 Mar 2009 00:03:56 +0000 Subject: Fixes a MSVC warning (by Vlad Losev); fixes SConscript to work with VC 7.1 and exceptions enabled (by Zhanyong Wan). --- test/gtest_output_test_.cc | 1 - 1 file changed, 1 deletion(-) (limited to 'test') diff --git a/test/gtest_output_test_.cc b/test/gtest_output_test_.cc index c867e159..a47560be 100644 --- a/test/gtest_output_test_.cc +++ b/test/gtest_output_test_.cc @@ -238,7 +238,6 @@ void AdHocTest() { EXPECT_EQ(2, 3); } - // Runs all TESTs, all TEST_Fs, and the ad hoc test. int RunAllTests() { AdHocTest(); -- cgit v1.2.3 From 6a26383e31cf79dd0acf89bf3a53c7a805decf1d Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Tue, 31 Mar 2009 16:27:55 +0000 Subject: Cleans up the use of GTEST_OS_WINDOWS and _MSC_VER. --- test/gtest_unittest.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'test') diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index 9a731eeb..8e4b813c 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -3148,9 +3148,9 @@ TEST(AssertionTest, ExpectWorksWithUncopyableObject) { // The version of gcc used in XCode 2.2 has a bug and doesn't allow -// anonymous enums in assertions. Therefore the following test is -// done only on Linux and Windows. -#if GTEST_OS_LINUX || GTEST_OS_WINDOWS +// anonymous enums in assertions. Therefore the following test is not +// done on Mac. +#if !GTEST_OS_MAC // Tests using assertions with anonymous enums. enum { @@ -3195,7 +3195,7 @@ TEST(AssertionTest, AnonymousEnum) { "Value of: CASE_B"); } -#endif // GTEST_OS_LINUX || GTEST_OS_WINDOWS +#endif // !GTEST_OS_MAC #if GTEST_OS_WINDOWS -- cgit v1.2.3 From c12f63214e9b7761d27e68353e4aaf1761c9cf88 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Tue, 7 Apr 2009 21:03:22 +0000 Subject: Adds sample4_unittest to scons (by Vlad Losev); adds logic for getting the thread count on Mac (by Vlad Losev); adds HasFailure() and HasNonfatalFailure() (by Zhanyong Wan). --- test/gtest-port_test.cc | 43 +++++++++++++++++++++++++ test/gtest_unittest.cc | 85 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 128 insertions(+) (limited to 'test') diff --git a/test/gtest-port_test.cc b/test/gtest-port_test.cc index 0bda6f5e..f4560f19 100644 --- a/test/gtest-port_test.cc +++ b/test/gtest-port_test.cc @@ -32,6 +32,11 @@ // This file tests the internal cross-platform support utilities. #include + +#if GTEST_OS_MAC +#include +#endif // GTEST_OS_MAC + #include #include @@ -76,6 +81,44 @@ TEST(GtestCheckSyntaxTest, WorksWithSwitch) { GTEST_CHECK_(true) << "Check failed in switch case"; } +#if GTEST_OS_MAC +void* ThreadFunc(void* data) { + pthread_mutex_t* mutex = reinterpret_cast(data); + pthread_mutex_lock(mutex); + pthread_mutex_unlock(mutex); + return NULL; +} + +TEST(GetThreadCountTest, ReturnsCorrectValue) { + EXPECT_EQ(1, GetThreadCount()); + pthread_mutex_t mutex; + pthread_attr_t attr; + pthread_t thread_id; + + // TODO(vladl@google.com): turn mutex into internal::Mutex for automatic + // destruction. + pthread_mutex_init(&mutex, NULL); + pthread_mutex_lock(&mutex); + ASSERT_EQ(0, pthread_attr_init(&attr)); + ASSERT_EQ(0, pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE)); + + const int status = pthread_create(&thread_id, &attr, &ThreadFunc, &mutex); + ASSERT_EQ(0, pthread_attr_destroy(&attr)); + ASSERT_EQ(0, status); + EXPECT_EQ(2, GetThreadCount()); + pthread_mutex_unlock(&mutex); + + void* dummy; + ASSERT_EQ(0, pthread_join(thread_id, &dummy)); + EXPECT_EQ(1, GetThreadCount()); + pthread_mutex_destroy(&mutex); +} +#else +TEST(GetThreadCountTest, ReturnsZeroWhenUnableToCountThreads) { + EXPECT_EQ(0, GetThreadCount()); +} +#endif // GTEST_OS_MAC + #if GTEST_HAS_DEATH_TEST TEST(GtestCheckDeathTest, DiesWithCorrectOutputOnFailure) { diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index 8e4b813c..d1c517b5 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -131,6 +131,7 @@ using testing::TPRT_SUCCESS; using testing::UnitTest; using testing::internal::kTestTypeIdInGoogleTest; using testing::internal::AppendUserMessage; +using testing::internal::ClearCurrentTestPartResults; using testing::internal::CodePointToUtf8; using testing::internal::EqFailure; using testing::internal::FloatingPoint; @@ -5456,3 +5457,87 @@ TEST(GetCurrentOsStackTraceExceptTopTest, ReturnsTheStackTrace) { EXPECT_STREQ("", GetCurrentOsStackTraceExceptTop(unit_test, 0).c_str()); EXPECT_STREQ("", GetCurrentOsStackTraceExceptTop(unit_test, 1).c_str()); } + +TEST(HasNonfatalFailureTest, ReturnsFalseWhenThereIsNoFailure) { + EXPECT_FALSE(HasNonfatalFailure()); +} + +static void FailFatally() { FAIL(); } + +TEST(HasNonfatalFailureTest, ReturnsFalseWhenThereIsOnlyFatalFailure) { + FailFatally(); + const bool has_nonfatal_failure = HasNonfatalFailure(); + ClearCurrentTestPartResults(); + EXPECT_FALSE(has_nonfatal_failure); +} + +TEST(HasNonfatalFailureTest, ReturnsTrueWhenThereIsNonfatalFailure) { + ADD_FAILURE(); + const bool has_nonfatal_failure = HasNonfatalFailure(); + ClearCurrentTestPartResults(); + EXPECT_TRUE(has_nonfatal_failure); +} + +TEST(HasNonfatalFailureTest, ReturnsTrueWhenThereAreFatalAndNonfatalFailures) { + FailFatally(); + ADD_FAILURE(); + const bool has_nonfatal_failure = HasNonfatalFailure(); + ClearCurrentTestPartResults(); + EXPECT_TRUE(has_nonfatal_failure); +} + +// A wrapper for calling HasNonfatalFailure outside of a test body. +static bool HasNonfatalFailureHelper() { + return testing::Test::HasNonfatalFailure(); +} + +TEST(HasNonfatalFailureTest, WorksOutsideOfTestBody) { + EXPECT_FALSE(HasNonfatalFailureHelper()); +} + +TEST(HasNonfatalFailureTest, WorksOutsideOfTestBody2) { + ADD_FAILURE(); + const bool has_nonfatal_failure = HasNonfatalFailureHelper(); + ClearCurrentTestPartResults(); + EXPECT_TRUE(has_nonfatal_failure); +} + +TEST(HasFailureTest, ReturnsFalseWhenThereIsNoFailure) { + EXPECT_FALSE(HasFailure()); +} + +TEST(HasFailureTest, ReturnsTrueWhenThereIsFatalFailure) { + FailFatally(); + const bool has_failure = HasFailure(); + ClearCurrentTestPartResults(); + EXPECT_TRUE(has_failure); +} + +TEST(HasFailureTest, ReturnsTrueWhenThereIsNonfatalFailure) { + ADD_FAILURE(); + const bool has_failure = HasFailure(); + ClearCurrentTestPartResults(); + EXPECT_TRUE(has_failure); +} + +TEST(HasFailureTest, ReturnsTrueWhenThereAreFatalAndNonfatalFailures) { + FailFatally(); + ADD_FAILURE(); + const bool has_failure = HasFailure(); + ClearCurrentTestPartResults(); + EXPECT_TRUE(has_failure); +} + +// A wrapper for calling HasFailure outside of a test body. +static bool HasFailureHelper() { return testing::Test::HasFailure(); } + +TEST(HasFailureTest, WorksOutsideOfTestBody) { + EXPECT_FALSE(HasFailureHelper()); +} + +TEST(HasFailureTest, WorksOutsideOfTestBody2) { + ADD_FAILURE(); + const bool has_failure = HasFailureHelper(); + ClearCurrentTestPartResults(); + EXPECT_TRUE(has_failure); +} -- cgit v1.2.3 From 7fa242a44b47ce74d7246440b14571f7a5dd1b17 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Thu, 9 Apr 2009 02:57:38 +0000 Subject: Makes the Python tests more stable (by Vlad Losev); fixes a memory leak in GetThreadCount() on Mac (by Vlad Losev); improves fuse_gtest_files.py to support fusing Google Mock files (by Zhanyong Wan). --- test/gtest_break_on_failure_unittest.py | 4 +- test/gtest_color_test.py | 21 +++++---- test/gtest_env_var_test.py | 40 +++-------------- test/gtest_filter_unittest.py | 76 ++++++++++++++++++++++----------- test/gtest_help_test.py | 7 +-- test/gtest_list_tests_unittest.py | 3 +- test/gtest_output_test.py | 69 +++++++++++++++++++++++------- test/gtest_test_utils.py | 38 +++++++++++++++-- test/gtest_throw_on_failure_test.py | 4 +- test/gtest_uninitialized_test.py | 41 +++--------------- test/gtest_xml_outfiles_test.py | 3 +- test/gtest_xml_output_unittest.py | 10 ++--- test/gtest_xml_test_utils.py | 2 +- 13 files changed, 178 insertions(+), 140 deletions(-) (limited to 'test') diff --git a/test/gtest_break_on_failure_unittest.py b/test/gtest_break_on_failure_unittest.py index 9c2855fd..c9dd0081 100755 --- a/test/gtest_break_on_failure_unittest.py +++ b/test/gtest_break_on_failure_unittest.py @@ -58,8 +58,8 @@ BREAK_ON_FAILURE_FLAG = 'gtest_break_on_failure' THROW_ON_FAILURE_ENV_VAR = 'GTEST_THROW_ON_FAILURE' # Path to the gtest_break_on_failure_unittest_ program. -EXE_PATH = os.path.join(gtest_test_utils.GetBuildDir(), - 'gtest_break_on_failure_unittest_') +EXE_PATH = gtest_test_utils.GetTestExecutablePath( + 'gtest_break_on_failure_unittest_') # Utilities. diff --git a/test/gtest_color_test.py b/test/gtest_color_test.py index 5260a899..32db4b9a 100755 --- a/test/gtest_color_test.py +++ b/test/gtest_color_test.py @@ -38,11 +38,11 @@ import os import sys import unittest +IS_WINDOWS = os.name = 'nt' COLOR_ENV_VAR = 'GTEST_COLOR' COLOR_FLAG = 'gtest_color' -COMMAND = os.path.join(gtest_test_utils.GetBuildDir(), - 'gtest_color_test_') +COMMAND = gtest_test_utils.GetTestExecutablePath('gtest_color_test_') def SetEnvVar(env_var, value): @@ -69,11 +69,12 @@ class GTestColorTest(unittest.TestCase): def testNoEnvVarNoFlag(self): """Tests the case when there's neither GTEST_COLOR nor --gtest_color.""" - self.assert_(not UsesColor('dumb', None, None)) - self.assert_(not UsesColor('emacs', None, None)) - self.assert_(not UsesColor('xterm-mono', None, None)) - self.assert_(not UsesColor('unknown', None, None)) - self.assert_(not UsesColor(None, None, None)) + if not IS_WINDOWS: + self.assert_(not UsesColor('dumb', None, None)) + self.assert_(not UsesColor('emacs', None, None)) + self.assert_(not UsesColor('xterm-mono', None, None)) + self.assert_(not UsesColor('unknown', None, None)) + self.assert_(not UsesColor(None, None, None)) self.assert_(UsesColor('cygwin', None, None)) self.assert_(UsesColor('xterm', None, None)) self.assert_(UsesColor('xterm-color', None, None)) @@ -83,7 +84,8 @@ class GTestColorTest(unittest.TestCase): self.assert_(not UsesColor('dumb', None, 'no')) self.assert_(not UsesColor('xterm-color', None, 'no')) - self.assert_(not UsesColor('emacs', None, 'auto')) + if not IS_WINDOWS: + self.assert_(not UsesColor('emacs', None, 'auto')) self.assert_(UsesColor('xterm', None, 'auto')) self.assert_(UsesColor('dumb', None, 'yes')) self.assert_(UsesColor('xterm', None, 'yes')) @@ -93,7 +95,8 @@ class GTestColorTest(unittest.TestCase): self.assert_(not UsesColor('dumb', 'no', None)) self.assert_(not UsesColor('xterm-color', 'no', None)) - self.assert_(not UsesColor('dumb', 'auto', None)) + if not IS_WINDOWS: + self.assert_(not UsesColor('dumb', 'auto', None)) self.assert_(UsesColor('xterm-color', 'auto', None)) self.assert_(UsesColor('dumb', 'yes', None)) self.assert_(UsesColor('xterm-color', 'yes', None)) diff --git a/test/gtest_env_var_test.py b/test/gtest_env_var_test.py index c5acc5ca..92b9cd8a 100755 --- a/test/gtest_env_var_test.py +++ b/test/gtest_env_var_test.py @@ -41,18 +41,7 @@ import unittest IS_WINDOWS = os.name == 'nt' IS_LINUX = os.name == 'posix' -if IS_WINDOWS: - BUILD_DIRS = [ - 'build.dbg\\', - 'build.opt\\', - 'build.dbg8\\', - 'build.opt8\\', - ] - COMMAND = 'gtest_env_var_test_.exe' - -if IS_LINUX: - COMMAND = os.path.join(gtest_test_utils.GetBuildDir(), - 'gtest_env_var_test_') +COMMAND = gtest_test_utils.GetTestExecutablePath('gtest_env_var_test_') def AssertEq(expected, actual): @@ -104,34 +93,19 @@ def TestEnvVarAffectsFlag(command): TestFlag(command, 'print_time', '1', '0') TestFlag(command, 'repeat', '999', '1') TestFlag(command, 'throw_on_failure', '1', '0') + TestFlag(command, 'death_test_style', 'threadsafe', 'fast') if IS_WINDOWS: TestFlag(command, 'catch_exceptions', '1', '0') if IS_LINUX: TestFlag(command, 'stack_trace_depth', '0', '100') - TestFlag(command, 'death_test_style', 'thread-safe', 'fast') TestFlag(command, 'death_test_use_fork', '1', '0') -if IS_WINDOWS: - - def main(): - for build_dir in BUILD_DIRS: - command = build_dir + COMMAND - print 'Testing with %s . . .' % (command,) - TestEnvVarAffectsFlag(command) - return 0 - - if __name__ == '__main__': - main() - - -if IS_LINUX: - - class GTestEnvVarTest(unittest.TestCase): - def testEnvVarAffectsFlag(self): - TestEnvVarAffectsFlag(COMMAND) +class GTestEnvVarTest(unittest.TestCase): + def testEnvVarAffectsFlag(self): + TestEnvVarAffectsFlag(COMMAND) - if __name__ == '__main__': - gtest_test_utils.Main() +if __name__ == '__main__': + gtest_test_utils.Main() diff --git a/test/gtest_filter_unittest.py b/test/gtest_filter_unittest.py index cd88cdf7..6002fac9 100755 --- a/test/gtest_filter_unittest.py +++ b/test/gtest_filter_unittest.py @@ -52,6 +52,8 @@ import gtest_test_utils # Constants. +IS_WINDOWS = os.name == 'nt' + # The environment variable for specifying the test filters. FILTER_ENV_VAR = 'GTEST_FILTER' @@ -67,8 +69,7 @@ FILTER_FLAG = 'gtest_filter' ALSO_RUN_DISABED_TESTS_FLAG = 'gtest_also_run_disabled_tests' # Command to run the gtest_filter_unittest_ program. -COMMAND = os.path.join(gtest_test_utils.GetBuildDir(), - 'gtest_filter_unittest_') +COMMAND = gtest_test_utils.GetTestExecutablePath('gtest_filter_unittest_') # Regex for determining whether parameterized tests are enabled in the binary. PARAM_TEST_REGEX = re.compile(r'/ParamTest') @@ -204,23 +205,36 @@ class GTestFilterUnitTest(unittest.TestCase): self.assertEqual(len(set_var), len(full_partition)) self.assertEqual(sets.Set(set_var), sets.Set(full_partition)) + def AdjustForParameterizedTests(self, tests_to_run): + """Adjust tests_to_run in case value parameterized tests are disabled + in the binary. + """ + global param_tests_present + if not param_tests_present: + return list(sets.Set(tests_to_run) - sets.Set(PARAM_TESTS)) + else: + return tests_to_run + def RunAndVerify(self, gtest_filter, tests_to_run): """Runs gtest_flag_unittest_ with the given filter, and verifies that the right set of tests were run. """ - # Adjust tests_to_run in case value parameterized tests are disabled - # in the binary. - global param_tests_present - if not param_tests_present: - tests_to_run = list(sets.Set(tests_to_run) - sets.Set(PARAM_TESTS)) + tests_to_run = self.AdjustForParameterizedTests(tests_to_run) # First, tests using GTEST_FILTER. - SetEnvVar(FILTER_ENV_VAR, gtest_filter) - tests_run = Run(COMMAND)[0] - SetEnvVar(FILTER_ENV_VAR, None) - - self.AssertSetEqual(tests_run, tests_to_run) + # Windows removes empty variables from the environment when passing it + # to a new process. This means it is impossible to pass an empty filter + # into a process using the GTEST_FILTER environment variable. However, + # we can still test the case when the variable is not supplied (i.e., + # gtest_filter is None). + # pylint: disable-msg=C6403 + if not IS_WINDOWS or gtest_filter != '': + SetEnvVar(FILTER_ENV_VAR, gtest_filter) + tests_run = Run(COMMAND)[0] + SetEnvVar(FILTER_ENV_VAR, None) + self.AssertSetEqual(tests_run, tests_to_run) + # pylint: enable-msg=C6403 # Next, tests using --gtest_filter. @@ -239,21 +253,33 @@ class GTestFilterUnitTest(unittest.TestCase): on each shard should be identical to tests_to_run, without duplicates. If check_exit_0, make sure that all shards returned 0. """ - SetEnvVar(FILTER_ENV_VAR, gtest_filter) - partition = [] - for i in range(0, total_shards): - (tests_run, exit_code) = RunWithSharding(total_shards, i, command) - if check_exit_0: - self.assert_(exit_code is None) - partition.append(tests_run) - - self.AssertPartitionIsValid(tests_to_run, partition) - SetEnvVar(FILTER_ENV_VAR, None) + tests_to_run = self.AdjustForParameterizedTests(tests_to_run) + + # Windows removes empty variables from the environment when passing it + # to a new process. This means it is impossible to pass an empty filter + # into a process using the GTEST_FILTER environment variable. However, + # we can still test the case when the variable is not supplied (i.e., + # gtest_filter is None). + # pylint: disable-msg=C6403 + if not IS_WINDOWS or gtest_filter != '': + SetEnvVar(FILTER_ENV_VAR, gtest_filter) + partition = [] + for i in range(0, total_shards): + (tests_run, exit_code) = RunWithSharding(total_shards, i, command) + if check_exit_0: + self.assert_(exit_code is None) + partition.append(tests_run) + + self.AssertPartitionIsValid(tests_to_run, partition) + SetEnvVar(FILTER_ENV_VAR, None) + # pylint: enable-msg=C6403 def RunAndVerifyAllowingDisabled(self, gtest_filter, tests_to_run): """Runs gtest_flag_unittest_ with the given filter, and enables disabled tests. Verifies that the right set of tests were run. """ + tests_to_run = self.AdjustForParameterizedTests(tests_to_run) + # Construct the command line. command = '%s --%s' % (COMMAND, ALSO_RUN_DISABED_TESTS_FLAG) if gtest_filter is not None: @@ -263,8 +289,10 @@ class GTestFilterUnitTest(unittest.TestCase): self.AssertSetEqual(tests_run, tests_to_run) def setUp(self): - """Sets up test case. Determines whether value-parameterized tests are - enabled in the binary and sets flags accordingly. + """Sets up test case. + + Determines whether value-parameterized tests are enabled in the binary and + sets the flags accordingly. """ global param_tests_present if param_tests_present is None: diff --git a/test/gtest_help_test.py b/test/gtest_help_test.py index 62710192..d81f149f 100755 --- a/test/gtest_help_test.py +++ b/test/gtest_help_test.py @@ -47,12 +47,7 @@ import unittest IS_WINDOWS = os.name == 'nt' -if IS_WINDOWS: - PROGRAM = 'gtest_help_test_.exe' -else: - PROGRAM = 'gtest_help_test_' - -PROGRAM_PATH = os.path.join(gtest_test_utils.GetBuildDir(), PROGRAM) +PROGRAM_PATH = gtest_test_utils.GetTestExecutablePath('gtest_help_test_') FLAG_PREFIX = '--gtest_' CATCH_EXCEPTIONS_FLAG = FLAG_PREFIX + 'catch_exceptions' DEATH_TEST_STYLE_FLAG = FLAG_PREFIX + 'death_test_style' diff --git a/test/gtest_list_tests_unittest.py b/test/gtest_list_tests_unittest.py index 9cefa15c..147bd73a 100755 --- a/test/gtest_list_tests_unittest.py +++ b/test/gtest_list_tests_unittest.py @@ -52,8 +52,7 @@ import unittest LIST_TESTS_FLAG = 'gtest_list_tests' # Path to the gtest_list_tests_unittest_ program. -EXE_PATH = os.path.join(gtest_test_utils.GetBuildDir(), - 'gtest_list_tests_unittest_'); +EXE_PATH = gtest_test_utils.GetTestExecutablePath('gtest_list_tests_unittest_') # The expected output when running gtest_list_tests_unittest_ with # --gtest_list_tests diff --git a/test/gtest_output_test.py b/test/gtest_output_test.py index f35e0024..52894064 100755 --- a/test/gtest_output_test.py +++ b/test/gtest_output_test.py @@ -54,16 +54,15 @@ GENGOLDEN_FLAG = '--gengolden' IS_WINDOWS = os.name == 'nt' if IS_WINDOWS: - PROGRAM = r'..\build.dbg8\gtest_output_test_.exe' GOLDEN_NAME = 'gtest_output_test_golden_win.txt' else: - PROGRAM = 'gtest_output_test_' GOLDEN_NAME = 'gtest_output_test_golden_lin.txt' -PROGRAM_PATH = os.path.join(gtest_test_utils.GetBuildDir(), PROGRAM) +PROGRAM_PATH = gtest_test_utils.GetTestExecutablePath('gtest_output_test_') # At least one command we exercise must not have the # --gtest_internal_skip_environment_and_ad_hoc_tests flag. +COMMAND_LIST_TESTS = ({}, PROGRAM_PATH + ' --gtest_list_tests') COMMAND_WITH_COLOR = ({}, PROGRAM_PATH + ' --gtest_color=yes') COMMAND_WITH_TIME = ({}, PROGRAM_PATH + ' --gtest_print_time ' '--gtest_internal_skip_environment_and_ad_hoc_tests ' @@ -76,8 +75,7 @@ COMMAND_WITH_SHARDING = ({'GTEST_SHARD_INDEX': '1', 'GTEST_TOTAL_SHARDS': '2'}, ' --gtest_internal_skip_environment_and_ad_hoc_tests ' ' --gtest_filter="PassingTest.*"') -GOLDEN_PATH = os.path.join(gtest_test_utils.GetSourceDir(), - GOLDEN_NAME) +GOLDEN_PATH = os.path.join(gtest_test_utils.GetSourceDir(), GOLDEN_NAME) def ToUnixLineEnding(s): @@ -119,15 +117,35 @@ def RemoveTime(output): def RemoveTestCounts(output): """Removes test counts from a Google Test program's output.""" + output = re.sub(r'\d+ tests, listed below', + '? tests, listed below', output) + output = re.sub(r'\d+ FAILED TESTS', + '? FAILED TESTS', output) output = re.sub(r'\d+ tests from \d+ test cases', '? tests from ? test cases', output) return re.sub(r'\d+ tests\.', '? tests.', output) -def RemoveDeathTests(output): - """Removes death test information from a Google Test program's output.""" +def RemoveMatchingTests(test_output, pattern): + """Removes typed test information from a Google Test program's output. - return re.sub(r'\n.*DeathTest.*', '', output) + This function strips not only the beginning and the end of a test but also all + output in between. + + Args: + test_output: A string containing the test output. + pattern: A string that matches names of test cases to remove. + + Returns: + Contents of test_output with removed test case whose names match pattern. + """ + + test_output = re.sub( + r'\[ RUN \] .*%s(.|\n)*?\[( FAILED | OK )\] .*%s.*\n' % ( + pattern, pattern), + '', + test_output) + return re.sub(r'.*%s.*\n' % pattern, '', test_output) def NormalizeOutput(output): @@ -220,7 +238,19 @@ def GetOutputOfAllCommands(): GetCommandOutput(COMMAND_WITH_SHARDING)) +test_list = GetShellCommandOutput(COMMAND_LIST_TESTS, '') +SUPPORTS_DEATH_TESTS = 'DeathTest' in test_list +SUPPORTS_TYPED_TESTS = 'TypedTest' in test_list + + class GTestOutputTest(unittest.TestCase): + def RemoveUnsupportedTests(self, test_output): + if not SUPPORTS_DEATH_TESTS: + test_output = RemoveMatchingTests(test_output, 'DeathTest') + if not SUPPORTS_TYPED_TESTS: + test_output = RemoveMatchingTests(test_output, 'TypedTest') + return test_output + def testOutput(self): output = GetOutputOfAllCommands() golden_file = open(GOLDEN_PATH, 'rb') @@ -229,16 +259,25 @@ class GTestOutputTest(unittest.TestCase): # We want the test to pass regardless of death tests being # supported or not. - self.assert_(output == golden or - RemoveTestCounts(output) == - RemoveTestCounts(RemoveDeathTests(golden))) + if SUPPORTS_DEATH_TESTS and SUPPORTS_TYPED_TESTS: + self.assert_(golden == output) + else: + print RemoveTestCounts(self.RemoveUnsupportedTests(golden)) + self.assert_(RemoveTestCounts(self.RemoveUnsupportedTests(golden)) == + RemoveTestCounts(output)) if __name__ == '__main__': if sys.argv[1:] == [GENGOLDEN_FLAG]: - output = GetOutputOfAllCommands() - golden_file = open(GOLDEN_PATH, 'wb') - golden_file.write(output) - golden_file.close() + if SUPPORTS_DEATH_TESTS and SUPPORTS_TYPED_TESTS: + output = GetOutputOfAllCommands() + golden_file = open(GOLDEN_PATH, 'wb') + golden_file.write(output) + golden_file.close() + else: + print >> sys.stderr, ('Unable to write a golden file when compiled in an ' + 'environment that does not support death tests and ' + 'typed tests. Are you using VC 7.1?') + sys.exit(1) else: gtest_test_utils.Main() diff --git a/test/gtest_test_utils.py b/test/gtest_test_utils.py index 8f55b075..7dc8c421 100755 --- a/test/gtest_test_utils.py +++ b/test/gtest_test_utils.py @@ -44,10 +44,10 @@ except: import popen2 _SUBPROCESS_MODULE_AVAILABLE = False +IS_WINDOWS = os.name == 'nt' -# Initially maps a flag to its default value. After -# _ParseAndStripGTestFlags() is called, maps a flag to its actual -# value. +# Initially maps a flag to its default value. After +# _ParseAndStripGTestFlags() is called, maps a flag to its actual value. _flag_map = {'gtest_source_dir': os.path.dirname(sys.argv[0]), 'gtest_build_dir': os.path.dirname(sys.argv[0])} _gtest_flags_are_parsed = False @@ -103,6 +103,38 @@ def GetBuildDir(): return os.path.abspath(GetFlag('gtest_build_dir')) +def GetTestExecutablePath(executable_name): + """Returns the absolute path of the test binary given its name. + + The function will print a message and abort the program if the resulting file + doesn't exist. + + Args: + executable_name: name of the test binary that the test script runs. + + Returns: + The absolute path of the test binary. + """ + + path = os.path.abspath(os.path.join(GetBuildDir(), executable_name)) + if IS_WINDOWS and not path.endswith('.exe'): + path += '.exe' + + if not os.path.exists(path): + message = ( + 'Unable to find the test binary. Please make sure to provide path\n' + 'to the binary via the --gtest_build_dir flag or the GTEST_BUILD_DIR\n' + 'environment variable. For convenient use, invoke this script via\n' + 'mk_test.py.\n' + # TODO(vladl@google.com): change mk_test.py to test.py after renaming + # the file. + 'Please run mk_test.py -h for help.') + print >> sys.stderr, message + sys.exit(1) + + return path + + def GetExitStatus(exit_code): """Returns the argument to exit(), or -1 if exit() wasn't called. diff --git a/test/gtest_throw_on_failure_test.py b/test/gtest_throw_on_failure_test.py index a80d6172..50172d07 100755 --- a/test/gtest_throw_on_failure_test.py +++ b/test/gtest_throw_on_failure_test.py @@ -49,8 +49,8 @@ THROW_ON_FAILURE = 'gtest_throw_on_failure' # Path to the gtest_throw_on_failure_test_ program, compiled with # exceptions disabled. -EXE_PATH = os.path.join(gtest_test_utils.GetBuildDir(), - 'gtest_throw_on_failure_test_') +EXE_PATH = gtest_test_utils.GetTestExecutablePath( + 'gtest_throw_on_failure_test_') # Utilities. diff --git a/test/gtest_uninitialized_test.py b/test/gtest_uninitialized_test.py index a3ba629c..19b92e90 100755 --- a/test/gtest_uninitialized_test.py +++ b/test/gtest_uninitialized_test.py @@ -34,25 +34,11 @@ __author__ = 'wan@google.com (Zhanyong Wan)' import gtest_test_utils -import os import sys import unittest -IS_WINDOWS = os.name == 'nt' -IS_LINUX = os.name == 'posix' -if IS_WINDOWS: - BUILD_DIRS = [ - 'build.dbg\\', - 'build.opt\\', - 'build.dbg8\\', - 'build.opt8\\', - ] - COMMAND = 'gtest_uninitialized_test_.exe' - -if IS_LINUX: - COMMAND = os.path.join(gtest_test_utils.GetBuildDir(), - 'gtest_uninitialized_test_') +COMMAND = gtest_test_utils.GetTestExecutablePath('gtest_uninitialized_test_') def Assert(condition): @@ -77,25 +63,10 @@ def TestExitCodeAndOutput(command): Assert('InitGoogleTest' in p.output) -if IS_WINDOWS: - - def main(): - for build_dir in BUILD_DIRS: - command = build_dir + COMMAND - print 'Testing with %s . . .' % (command,) - TestExitCodeAndOutput(command) - return 0 - - if __name__ == '__main__': - main() - - -if IS_LINUX: - - class GTestUninitializedTest(unittest.TestCase): - def testExitCodeAndOutput(self): - TestExitCodeAndOutput(COMMAND) +class GTestUninitializedTest(unittest.TestCase): + def testExitCodeAndOutput(self): + TestExitCodeAndOutput(COMMAND) - if __name__ == '__main__': - gtest_test_utils.Main() +if __name__ == '__main__': + gtest_test_utils.Main() diff --git a/test/gtest_xml_outfiles_test.py b/test/gtest_xml_outfiles_test.py index 3e91f6de..9d627932 100755 --- a/test/gtest_xml_outfiles_test.py +++ b/test/gtest_xml_outfiles_test.py @@ -98,8 +98,7 @@ class GTestXMLOutFilesTest(gtest_xml_test_utils.GTestXMLTestCase): self._TestOutFile(GTEST_OUTPUT_2_TEST, EXPECTED_XML_2) def _TestOutFile(self, test_name, expected_xml): - gtest_prog_path = os.path.join(gtest_test_utils.GetBuildDir(), - test_name) + gtest_prog_path = gtest_test_utils.GetTestExecutablePath(test_name) command = [gtest_prog_path, "--gtest_output=xml:%s" % self.output_dir_] p = gtest_test_utils.Subprocess(command, working_dir=tempfile.mkdtemp()) self.assert_(p.exited) diff --git a/test/gtest_xml_output_unittest.py b/test/gtest_xml_output_unittest.py index 4587c41b..622251ea 100755 --- a/test/gtest_xml_output_unittest.py +++ b/test/gtest_xml_output_unittest.py @@ -121,10 +121,9 @@ class GTestXMLOutputUnitTest(gtest_xml_test_utils.GTestXMLTestCase): default name if no name is explicitly specified. """ temp_dir = tempfile.mkdtemp() - output_file = os.path.join(temp_dir, - GTEST_DEFAULT_OUTPUT_FILE) - gtest_prog_path = os.path.join(gtest_test_utils.GetBuildDir(), - "gtest_no_test_unittest") + output_file = os.path.join(temp_dir, GTEST_DEFAULT_OUTPUT_FILE) + gtest_prog_path = gtest_test_utils.GetTestExecutablePath( + "gtest_no_test_unittest") try: os.remove(output_file) except OSError, e: @@ -148,8 +147,7 @@ class GTestXMLOutputUnitTest(gtest_xml_test_utils.GTestXMLTestCase): """ xml_path = os.path.join(tempfile.mkdtemp(), gtest_prog_name + "out.xml") - gtest_prog_path = os.path.join(gtest_test_utils.GetBuildDir(), - gtest_prog_name) + gtest_prog_path = gtest_test_utils.GetTestExecutablePath(gtest_prog_name) command = [gtest_prog_path, "%s=xml:%s" % (GTEST_OUTPUT_FLAG, xml_path)] p = gtest_test_utils.Subprocess(command) diff --git a/test/gtest_xml_test_utils.py b/test/gtest_xml_test_utils.py index 00a56cbf..64eebb10 100755 --- a/test/gtest_xml_test_utils.py +++ b/test/gtest_xml_test_utils.py @@ -150,7 +150,7 @@ class GTestXMLTestCase(unittest.TestCase): for child in element.childNodes: if child.nodeType == Node.CDATA_SECTION_NODE: # Removes the source line number. - cdata = re.sub(r"^.*/(.*:)\d+\n", "\\1*\n", child.nodeValue) + cdata = re.sub(r"^.*[/\\](.*:)\d+\n", "\\1*\n", child.nodeValue) # Removes the actual stack trace. child.nodeValue = re.sub(r"\nStack trace:\n(.|\n)*", "", cdata) -- cgit v1.2.3 From f204cd89e591e8cda022f4b471962c8556e19b8c Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Tue, 14 Apr 2009 23:19:22 +0000 Subject: Makes gtest print elapsed time by default. --- test/gtest_env_var_test.py | 2 +- test/gtest_output_test_.cc | 2 ++ test/gtest_unittest.cc | 10 +++++----- 3 files changed, 8 insertions(+), 6 deletions(-) (limited to 'test') diff --git a/test/gtest_env_var_test.py b/test/gtest_env_var_test.py index 92b9cd8a..35e8041f 100755 --- a/test/gtest_env_var_test.py +++ b/test/gtest_env_var_test.py @@ -90,7 +90,7 @@ def TestEnvVarAffectsFlag(command): TestFlag(command, 'color', 'yes', 'auto') TestFlag(command, 'filter', 'FooTest.Bar', '*') TestFlag(command, 'output', 'tmp/foo.xml', '') - TestFlag(command, 'print_time', '1', '0') + TestFlag(command, 'print_time', '0', '1') TestFlag(command, 'repeat', '999', '1') TestFlag(command, 'throw_on_failure', '1', '0') TestFlag(command, 'death_test_style', 'threadsafe', 'fast') diff --git a/test/gtest_output_test_.cc b/test/gtest_output_test_.cc index a47560be..4d7f0758 100644 --- a/test/gtest_output_test_.cc +++ b/test/gtest_output_test_.cc @@ -976,6 +976,8 @@ GTEST_DEFINE_bool_(internal_skip_environment_and_ad_hoc_tests, false, // of them are intended to fail), and then compare the test results // with the "golden" file. int main(int argc, char **argv) { + testing::GTEST_FLAG(print_time) = false; + // We just run the tests, knowing some of them are intended to fail. // We will use a separate Python script to compare the output of // this program with the golden file. diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index d1c517b5..0786725b 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -1204,7 +1204,7 @@ class GTestFlagSaverTest : public Test { GTEST_FLAG(filter) = ""; GTEST_FLAG(list_tests) = false; GTEST_FLAG(output) = ""; - GTEST_FLAG(print_time) = false; + GTEST_FLAG(print_time) = true; GTEST_FLAG(repeat) = 1; GTEST_FLAG(throw_on_failure) = false; } @@ -1227,7 +1227,7 @@ class GTestFlagSaverTest : public Test { EXPECT_STREQ("", GTEST_FLAG(filter).c_str()); EXPECT_FALSE(GTEST_FLAG(list_tests)); EXPECT_STREQ("", GTEST_FLAG(output).c_str()); - EXPECT_FALSE(GTEST_FLAG(print_time)); + EXPECT_TRUE(GTEST_FLAG(print_time)); EXPECT_EQ(1, GTEST_FLAG(repeat)); EXPECT_FALSE(GTEST_FLAG(throw_on_failure)); @@ -1239,7 +1239,7 @@ class GTestFlagSaverTest : public Test { GTEST_FLAG(filter) = "abc"; GTEST_FLAG(list_tests) = true; GTEST_FLAG(output) = "xml:foo.xml"; - GTEST_FLAG(print_time) = true; + GTEST_FLAG(print_time) = false; GTEST_FLAG(repeat) = 100; GTEST_FLAG(throw_on_failure) = true; } @@ -4325,7 +4325,7 @@ struct Flags { filter(""), list_tests(false), output(""), - print_time(false), + print_time(true), repeat(1), throw_on_failure(false) {} @@ -4436,7 +4436,7 @@ class InitGoogleTestTest : public Test { GTEST_FLAG(filter) = ""; GTEST_FLAG(list_tests) = false; GTEST_FLAG(output) = ""; - GTEST_FLAG(print_time) = false; + GTEST_FLAG(print_time) = true; GTEST_FLAG(repeat) = 1; GTEST_FLAG(throw_on_failure) = false; } -- cgit v1.2.3 From f2d0d0e3d56794855d1e9a1f157457b7225e8c88 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Fri, 24 Apr 2009 00:26:25 +0000 Subject: Renames the POSIX wrappers (by Zhanyong Wan) and adds more targets to SConscript (by Vlad Losev). --- test/gtest-death-test_test.cc | 4 ++-- test/gtest-filepath_test.cc | 12 ++++++------ test/gtest-options_test.cc | 4 ++-- test/gtest_output_test_.cc | 4 ++-- test/gtest_throw_on_failure_test.py | 3 ++- 5 files changed, 14 insertions(+), 13 deletions(-) (limited to 'test') diff --git a/test/gtest-death-test_test.cc b/test/gtest-death-test_test.cc index db5f72e0..9dd477b2 100644 --- a/test/gtest-death-test_test.cc +++ b/test/gtest-death-test_test.cc @@ -106,7 +106,7 @@ class TestForDeathTest : public testing::Test { TestForDeathTest() : original_dir_(FilePath::GetCurrentDir()) {} virtual ~TestForDeathTest() { - posix::chdir(original_dir_.c_str()); + posix::ChDir(original_dir_.c_str()); } // A static member function that's expected to die. @@ -345,7 +345,7 @@ TEST_F(TestForDeathTest, MemberFunctionFastStyle) { EXPECT_DEATH(MemberFunction(), "inside.*MemberFunction"); } -void ChangeToRootDir() { posix::chdir(GTEST_PATH_SEP_); } +void ChangeToRootDir() { posix::ChDir(GTEST_PATH_SEP_); } // Tests that death tests work even if the current directory has been // changed. diff --git a/test/gtest-filepath_test.cc b/test/gtest-filepath_test.cc index 77a2988e..b6d950dd 100644 --- a/test/gtest-filepath_test.cc +++ b/test/gtest-filepath_test.cc @@ -86,9 +86,9 @@ TEST(GetCurrentDirTest, ReturnsCurrentDir) { const FilePath original_dir = FilePath::GetCurrentDir(); EXPECT_FALSE(original_dir.IsEmpty()); - posix::chdir(GTEST_PATH_SEP_); + posix::ChDir(GTEST_PATH_SEP_); const FilePath cwd = FilePath::GetCurrentDir(); - posix::chdir(original_dir.c_str()); + posix::ChDir(original_dir.c_str()); #if GTEST_OS_WINDOWS // Skips the ":". @@ -435,14 +435,14 @@ class DirectoryCreationTest : public Test { remove(testdata_file_.c_str()); remove(unique_file0_.c_str()); remove(unique_file1_.c_str()); - posix::rmdir(testdata_path_.c_str()); + posix::RmDir(testdata_path_.c_str()); } virtual void TearDown() { remove(testdata_file_.c_str()); remove(unique_file0_.c_str()); remove(unique_file1_.c_str()); - posix::rmdir(testdata_path_.c_str()); + posix::RmDir(testdata_path_.c_str()); } String TempDir() const { @@ -450,7 +450,7 @@ class DirectoryCreationTest : public Test { return String("\\temp\\"); #elif GTEST_OS_WINDOWS - const char* temp_dir = posix::getenv("TEMP"); + const char* temp_dir = posix::GetEnv("TEMP"); if (temp_dir == NULL || temp_dir[0] == '\0') return String("\\temp\\"); else if (String(temp_dir).EndsWith("\\")) @@ -463,7 +463,7 @@ class DirectoryCreationTest : public Test { } void CreateTextFile(const char* filename) { - FILE* f = posix::fopen(filename, "w"); + FILE* f = posix::FOpen(filename, "w"); fprintf(f, "text\n"); fclose(f); } diff --git a/test/gtest-options_test.cc b/test/gtest-options_test.cc index d49efe49..43c6d22d 100644 --- a/test/gtest-options_test.cc +++ b/test/gtest-options_test.cc @@ -150,14 +150,14 @@ class XmlOutputChangeDirTest : public Test { protected: virtual void SetUp() { original_working_dir_ = FilePath::GetCurrentDir(); - posix::chdir(".."); + posix::ChDir(".."); // This will make the test fail if run from the root directory. EXPECT_STRNE(original_working_dir_.c_str(), FilePath::GetCurrentDir().c_str()); } virtual void TearDown() { - posix::chdir(original_working_dir_.c_str()); + posix::ChDir(original_working_dir_.c_str()); } FilePath original_working_dir_; diff --git a/test/gtest_output_test_.cc b/test/gtest_output_test_.cc index 4d7f0758..9c92d8cc 100644 --- a/test/gtest_output_test_.cc +++ b/test/gtest_output_test_.cc @@ -991,9 +991,9 @@ int main(int argc, char **argv) { // Skip the usual output capturing if we're running as the child // process of an threadsafe-style death test. #if GTEST_OS_WINDOWS - posix::freopen("nul:", "w", stdout); + posix::FReopen("nul:", "w", stdout); #else - posix::freopen("/dev/null", "w", stdout); + posix::FReopen("/dev/null", "w", stdout); #endif // GTEST_OS_WINDOWS return RUN_ALL_TESTS(); } diff --git a/test/gtest_throw_on_failure_test.py b/test/gtest_throw_on_failure_test.py index 50172d07..e952da5a 100755 --- a/test/gtest_throw_on_failure_test.py +++ b/test/gtest_throw_on_failure_test.py @@ -72,7 +72,8 @@ def Run(command): """Runs a command; returns True/False if its exit code is/isn't 0.""" print 'Running "%s". . .' % ' '.join(command) - return gtest_test_utils.Subprocess(command).exit_code == 0 + p = gtest_test_utils.Subprocess(command) + return p.exited and p.exit_code == 0 # The tests. TODO(wan@google.com): refactor the class to share common -- cgit v1.2.3 From fa2b06c52fa3ffb1909ed8b928e106292609cfcb Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Fri, 24 Apr 2009 20:27:29 +0000 Subject: Makes --gtest_list_tests honor the test filter (by Jay Campan). --- test/gtest_list_tests_unittest.py | 55 ++++++++++++++++++++++++++------------ test/gtest_list_tests_unittest_.cc | 4 +-- 2 files changed, 40 insertions(+), 19 deletions(-) (limited to 'test') diff --git a/test/gtest_list_tests_unittest.py b/test/gtest_list_tests_unittest.py index 147bd73a..3d006dfe 100755 --- a/test/gtest_list_tests_unittest.py +++ b/test/gtest_list_tests_unittest.py @@ -56,12 +56,12 @@ EXE_PATH = gtest_test_utils.GetTestExecutablePath('gtest_list_tests_unittest_') # The expected output when running gtest_list_tests_unittest_ with # --gtest_list_tests -EXPECTED_OUTPUT = """FooDeathTest. +EXPECTED_OUTPUT_NO_FILTER = """FooDeathTest. Test1 Foo. Bar1 Bar2 - Bar3 + DISABLED_Bar3 Abc. Xyz Def @@ -69,17 +69,33 @@ FooBar. Baz FooTest. Test1 - Test2 + DISABLED_Test2 + Test3 +""" + +# The expected output when running gtest_list_tests_unittest_ with +# --gtest_list_tests and --gtest_filter=Foo*. +EXPECTED_OUTPUT_FILTER_FOO = """FooDeathTest. + Test1 +Foo. + Bar1 + Bar2 + DISABLED_Bar3 +FooBar. + Baz +FooTest. + Test1 + DISABLED_Test2 Test3 """ # Utilities. + def Run(command): - """Runs a command and returns the list of tests printed. - """ + """Runs a command and returns the list of tests printed.""" - stdout_file = os.popen(command, "r") + stdout_file = os.popen(command, 'r') output = stdout_file.read() @@ -90,8 +106,7 @@ def Run(command): # The unit test. class GTestListTestsUnitTest(unittest.TestCase): - """Tests using the --gtest_list_tests flag to list all tests. - """ + """Tests using the --gtest_list_tests flag to list all tests.""" def RunAndVerify(self, flag_value, expected_output, other_flag): """Runs gtest_list_tests_unittest_ and verifies that it prints @@ -126,12 +141,12 @@ class GTestListTestsUnitTest(unittest.TestCase): output = Run(command) msg = ('when %s is %s, the output of "%s" is "%s".' % - (LIST_TESTS_FLAG, flag_expression, command, output)) + (LIST_TESTS_FLAG, flag_expression, command, output)) if expected_output is not None: self.assert_(output == expected_output, msg) else: - self.assert_(output != EXPECTED_OUTPUT, msg) + self.assert_(output != EXPECTED_OUTPUT_NO_FILTER, msg) def testDefaultBehavior(self): """Tests the behavior of the default mode.""" @@ -147,18 +162,24 @@ class GTestListTestsUnitTest(unittest.TestCase): expected_output=None, other_flag=None) self.RunAndVerify(flag_value='1', - expected_output=EXPECTED_OUTPUT, + expected_output=EXPECTED_OUTPUT_NO_FILTER, other_flag=None) - def testOverrideOtherFlags(self): - """Tests that --gtest_list_tests overrides all other flags.""" + def testOverrideNonFilterFlags(self): + """Tests that --gtest_list_tests overrides the non-filter flags.""" self.RunAndVerify(flag_value="1", - expected_output=EXPECTED_OUTPUT, - other_flag="--gtest_filter=*") - self.RunAndVerify(flag_value="1", - expected_output=EXPECTED_OUTPUT, + expected_output=EXPECTED_OUTPUT_NO_FILTER, other_flag="--gtest_break_on_failure") + def testWithFilterFlags(self): + """Tests that --gtest_list_tests takes into account the + --gtest_filter flag.""" + + self.RunAndVerify(flag_value="1", + expected_output=EXPECTED_OUTPUT_FILTER_FOO, + other_flag="--gtest_filter=Foo*") + + if __name__ == '__main__': gtest_test_utils.Main() diff --git a/test/gtest_list_tests_unittest_.cc b/test/gtest_list_tests_unittest_.cc index 566694b2..b5e07ddd 100644 --- a/test/gtest_list_tests_unittest_.cc +++ b/test/gtest_list_tests_unittest_.cc @@ -50,7 +50,7 @@ TEST(Foo, Bar1) { TEST(Foo, Bar2) { } -TEST(Foo, Bar3) { +TEST(Foo, DISABLED_Bar3) { } TEST(Abc, Xyz) { @@ -68,7 +68,7 @@ class FooTest : public testing::Test { TEST_F(FooTest, Test1) { } -TEST_F(FooTest, Test2) { +TEST_F(FooTest, DISABLED_Test2) { } TEST_F(FooTest, Test3) { -- cgit v1.2.3 From c78ae6196dc9c24380b5cf86f8fd75a4d3edc704 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Tue, 28 Apr 2009 00:28:09 +0000 Subject: Ports gtest to C++Builder, by Josh Kelley. --- test/gtest_unittest.cc | 456 +++++++++++++++++++++++++++++++------------------ 1 file changed, 289 insertions(+), 167 deletions(-) (limited to 'test') diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index 0786725b..8becca15 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -65,6 +65,7 @@ TEST(CommandLineFlagsTest, CanBeAccessedInCodeOnceGTestHIsIncluded) { #undef GTEST_IMPLEMENTATION_ #include +#include #if GTEST_HAS_PTHREAD #include @@ -79,6 +80,10 @@ TEST(CommandLineFlagsTest, CanBeAccessedInCodeOnceGTestHIsIncluded) { #include #endif // GTEST_OS_LINUX +#ifdef __BORLANDC__ +#include +#endif + namespace testing { namespace internal { const char* FormatTimeInMillisAsSeconds(TimeInMillis ms); @@ -207,16 +212,26 @@ TEST(FormatTimeInMillisAsSecondsTest, FormatsNegativeNumber) { #if !GTEST_OS_SYMBIAN // NULL testing does not work with Symbian compilers. +#ifdef __BORLANDC__ +// Silences warnings: "Condition is always true", "Unreachable code" +#pragma option push -w-ccc -w-rch +#endif + // Tests that GTEST_IS_NULL_LITERAL_(x) is true when x is a null // pointer literal. TEST(NullLiteralTest, IsTrueForNullLiterals) { EXPECT_TRUE(GTEST_IS_NULL_LITERAL_(NULL)); EXPECT_TRUE(GTEST_IS_NULL_LITERAL_(0)); - EXPECT_TRUE(GTEST_IS_NULL_LITERAL_(1 - 1)); EXPECT_TRUE(GTEST_IS_NULL_LITERAL_(0U)); EXPECT_TRUE(GTEST_IS_NULL_LITERAL_(0L)); EXPECT_TRUE(GTEST_IS_NULL_LITERAL_(false)); +#ifndef __BORLANDC__ + // Some compilers may fail to detect some null pointer literals; + // as long as users of the framework don't use such literals, this + // is harmless. + EXPECT_TRUE(GTEST_IS_NULL_LITERAL_(1 - 1)); EXPECT_TRUE(GTEST_IS_NULL_LITERAL_(true && false)); +#endif } // Tests that GTEST_IS_NULL_LITERAL_(x) is false when x is not a null @@ -228,6 +243,11 @@ TEST(NullLiteralTest, IsFalseForNonNullLiterals) { EXPECT_FALSE(GTEST_IS_NULL_LITERAL_(static_cast(NULL))); } +#ifdef __BORLANDC__ +// Restores warnings after previous "#pragma option push" supressed them +#pragma option pop +#endif + #endif // !GTEST_OS_SYMBIAN // // Tests CodePointToUtf8(). @@ -681,13 +701,18 @@ TEST(StringTest, EndsWithCaseInsensitive) { EXPECT_FALSE(String("").EndsWithCaseInsensitive("foo")); } +// C++Builder's preprocessor is buggy; it fails to expand macros that +// appear in macro parameters after wide char literals. Provide an alias +// for NULL as a workaround. +static const wchar_t* const kNull = NULL; + // Tests String::CaseInsensitiveWideCStringEquals TEST(StringTest, CaseInsensitiveWideCStringEquals) { EXPECT_TRUE(String::CaseInsensitiveWideCStringEquals(NULL, NULL)); - EXPECT_FALSE(String::CaseInsensitiveWideCStringEquals(NULL, L"")); - EXPECT_FALSE(String::CaseInsensitiveWideCStringEquals(L"", NULL)); - EXPECT_FALSE(String::CaseInsensitiveWideCStringEquals(NULL, L"foobar")); - EXPECT_FALSE(String::CaseInsensitiveWideCStringEquals(L"foobar", NULL)); + EXPECT_FALSE(String::CaseInsensitiveWideCStringEquals(kNull, L"")); + EXPECT_FALSE(String::CaseInsensitiveWideCStringEquals(L"", kNull)); + EXPECT_FALSE(String::CaseInsensitiveWideCStringEquals(kNull, L"foobar")); + EXPECT_FALSE(String::CaseInsensitiveWideCStringEquals(L"foobar", kNull)); EXPECT_TRUE(String::CaseInsensitiveWideCStringEquals(L"foobar", L"foobar")); EXPECT_TRUE(String::CaseInsensitiveWideCStringEquals(L"foobar", L"FOOBAR")); EXPECT_TRUE(String::CaseInsensitiveWideCStringEquals(L"FOOBAR", L"foobar")); @@ -790,6 +815,17 @@ TEST(TestPropertyTest, ReplaceStringValue) { EXPECT_STREQ("2", property.value()); } +// AddFatalFailure() and AddNonfatalFailure() must be stand-alone +// functions (i.e. their definitions cannot be inlined at the call +// sites), or C++Builder won't compile the code. +static void AddFatalFailure() { + FAIL() << "Expected fatal failure."; +} + +static void AddNonfatalFailure() { + ADD_FAILURE() << "Expected non-fatal failure."; +} + class ScopedFakeTestPartResultReporterTest : public Test { protected: enum FailureMode { @@ -798,9 +834,9 @@ class ScopedFakeTestPartResultReporterTest : public Test { }; static void AddFailure(FailureMode failure) { if (failure == FATAL_FAILURE) { - FAIL() << "Expected fatal failure."; + AddFatalFailure(); } else { - ADD_FAILURE() << "Expected non-fatal failure."; + AddNonfatalFailure(); } } }; @@ -875,21 +911,28 @@ TEST_F(ScopedFakeTestPartResultReporterWithThreadsTest, #endif // GTEST_IS_THREADSAFE && GTEST_HAS_PTHREAD -// Tests EXPECT_FATAL_FAILURE{,ON_ALL_THREADS}. +// Tests EXPECT_FATAL_FAILURE{,ON_ALL_THREADS}. Makes sure that they +// work even if the failure is generated in a called function rather than +// the current context. typedef ScopedFakeTestPartResultReporterTest ExpectFatalFailureTest; TEST_F(ExpectFatalFailureTest, CatchesFatalFaliure) { - EXPECT_FATAL_FAILURE(AddFailure(FATAL_FAILURE), "Expected fatal failure."); + EXPECT_FATAL_FAILURE(AddFatalFailure(), "Expected fatal failure."); } TEST_F(ExpectFatalFailureTest, CatchesFatalFailureOnAllThreads) { // We have another test below to verify that the macro catches fatal // failures generated on another thread. - EXPECT_FATAL_FAILURE_ON_ALL_THREADS(AddFailure(FATAL_FAILURE), + EXPECT_FATAL_FAILURE_ON_ALL_THREADS(AddFatalFailure(), "Expected fatal failure."); } +#ifdef __BORLANDC__ +// Silences warnings: "Condition is always true" +#pragma option push -w-ccc +#endif + // Tests that EXPECT_FATAL_FAILURE() can be used in a non-void // function even when the statement in it contains ASSERT_*. @@ -913,6 +956,11 @@ void DoesNotAbortHelper(bool* aborted) { *aborted = false; } +#ifdef __BORLANDC__ +// Restores warnings after previous "#pragma option push" supressed them +#pragma option pop +#endif + TEST_F(ExpectFatalFailureTest, DoesNotAbort) { bool aborted = true; DoesNotAbortHelper(&aborted); @@ -927,14 +975,17 @@ static int global_var = 0; #define GTEST_USE_UNPROTECTED_COMMA_ global_var++, global_var++ TEST_F(ExpectFatalFailureTest, AcceptsMacroThatExpandsToUnprotectedComma) { +#ifndef __BORLANDC__ + // ICE's in C++Builder 2007. EXPECT_FATAL_FAILURE({ GTEST_USE_UNPROTECTED_COMMA_; - AddFailure(FATAL_FAILURE); + AddFatalFailure(); }, ""); +#endif EXPECT_FATAL_FAILURE_ON_ALL_THREADS({ GTEST_USE_UNPROTECTED_COMMA_; - AddFailure(FATAL_FAILURE); + AddFatalFailure(); }, ""); } @@ -943,14 +994,14 @@ TEST_F(ExpectFatalFailureTest, AcceptsMacroThatExpandsToUnprotectedComma) { typedef ScopedFakeTestPartResultReporterTest ExpectNonfatalFailureTest; TEST_F(ExpectNonfatalFailureTest, CatchesNonfatalFailure) { - EXPECT_NONFATAL_FAILURE(AddFailure(NONFATAL_FAILURE), + EXPECT_NONFATAL_FAILURE(AddNonfatalFailure(), "Expected non-fatal failure."); } TEST_F(ExpectNonfatalFailureTest, CatchesNonfatalFailureOnAllThreads) { // We have another test below to verify that the macro catches // non-fatal failures generated on another thread. - EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(AddFailure(NONFATAL_FAILURE), + EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(AddNonfatalFailure(), "Expected non-fatal failure."); } @@ -960,12 +1011,12 @@ TEST_F(ExpectNonfatalFailureTest, CatchesNonfatalFailureOnAllThreads) { TEST_F(ExpectNonfatalFailureTest, AcceptsMacroThatExpandsToUnprotectedComma) { EXPECT_NONFATAL_FAILURE({ GTEST_USE_UNPROTECTED_COMMA_; - AddFailure(NONFATAL_FAILURE); + AddNonfatalFailure(); }, ""); EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS({ GTEST_USE_UNPROTECTED_COMMA_; - AddFailure(NONFATAL_FAILURE); + AddNonfatalFailure(); }, ""); } @@ -1271,6 +1322,22 @@ static void SetEnv(const char* name, const char* value) { #ifdef _WIN32_WCE // Environment variables are not supported on Windows CE. return; +#elif defined(__BORLANDC__) + // C++Builder's putenv only stores a pointer to its parameter; we have to + // ensure that the string remains valid as long as it might be needed. + // We use an std::map to do so. + static std::map added_env; + + // Because putenv stores a pointer to the string buffer, we can't delete the + // previous string (if present) until after it's replaced. + String *prev_env = NULL; + if (added_env.find(name) != added_env.end()) { + prev_env = added_env[name]; + } + added_env[name] = new String((Message() << name << "=" << value).GetString()); + putenv(added_env[name]->c_str()); + delete prev_env; + #elif GTEST_OS_WINDOWS // If we are on Windows proper. _putenv((Message() << name << "=" << value).GetString().c_str()); #else @@ -1380,7 +1447,8 @@ TEST(ParseInt32FlagTest, ParsesAndReturnsValidValue) { EXPECT_TRUE(ParseInt32Flag("--" GTEST_FLAG_PREFIX_ "abc=456", "abc", &value)); EXPECT_EQ(456, value); - EXPECT_TRUE(ParseInt32Flag("--" GTEST_FLAG_PREFIX_ "abc=-789", "abc", &value)); + EXPECT_TRUE(ParseInt32Flag("--" GTEST_FLAG_PREFIX_ "abc=-789", + "abc", &value)); EXPECT_EQ(-789, value); } @@ -1802,8 +1870,9 @@ bool GreaterThan(T1 x1, T2 x2) { // Tests that overloaded functions can be used in *_PRED* as long as // their types are explicitly specified. TEST(PredicateAssertionTest, AcceptsOverloadedFunction) { - EXPECT_PRED1(static_cast(IsPositive), 5); // NOLINT - ASSERT_PRED1(static_cast(IsPositive), 6.0); // NOLINT + // C++Builder requires C-style casts rather than static_cast. + EXPECT_PRED1((bool (*)(int))(IsPositive), 5); // NOLINT + ASSERT_PRED1((bool (*)(double))(IsPositive), 6.0); // NOLINT } // Tests that template functions can be used in *_PRED* as long as @@ -1987,8 +2056,8 @@ TEST(IsSubstringTest, ReturnsCorrectResultForCString) { // Tests that IsSubstring() returns the correct result when the input // argument type is const wchar_t*. TEST(IsSubstringTest, ReturnsCorrectResultForWideCString) { - EXPECT_FALSE(IsSubstring("", "", NULL, L"a")); - EXPECT_FALSE(IsSubstring("", "", L"b", NULL)); + EXPECT_FALSE(IsSubstring("", "", kNull, L"a")); + EXPECT_FALSE(IsSubstring("", "", L"b", kNull)); EXPECT_FALSE(IsSubstring("", "", L"needle", L"haystack")); EXPECT_TRUE(IsSubstring("", "", static_cast(NULL), NULL)); @@ -2107,6 +2176,24 @@ TEST(IsNotSubstringTest, ReturnsCorrectResultForStdWstring) { template class FloatingPointTest : public Test { protected: + + // Pre-calculated numbers to be used by the tests. + struct TestValues { + RawType close_to_positive_zero; + RawType close_to_negative_zero; + RawType further_from_negative_zero; + + RawType close_to_one; + RawType further_from_one; + + RawType infinity; + RawType close_to_infinity; + RawType further_from_infinity; + + RawType nan1; + RawType nan2; + }; + typedef typename testing::internal::FloatingPoint Floating; typedef typename Floating::Bits Bits; @@ -2117,85 +2204,52 @@ class FloatingPointTest : public Test { const Bits zero_bits = Floating(0).bits(); // Makes some numbers close to 0.0. - close_to_positive_zero_ = Floating::ReinterpretBits(zero_bits + max_ulps/2); - close_to_negative_zero_ = -Floating::ReinterpretBits( + values_.close_to_positive_zero = Floating::ReinterpretBits( + zero_bits + max_ulps/2); + values_.close_to_negative_zero = -Floating::ReinterpretBits( zero_bits + max_ulps - max_ulps/2); - further_from_negative_zero_ = -Floating::ReinterpretBits( + values_.further_from_negative_zero = -Floating::ReinterpretBits( zero_bits + max_ulps + 1 - max_ulps/2); // The bits that represent 1.0. const Bits one_bits = Floating(1).bits(); // Makes some numbers close to 1.0. - close_to_one_ = Floating::ReinterpretBits(one_bits + max_ulps); - further_from_one_ = Floating::ReinterpretBits(one_bits + max_ulps + 1); + values_.close_to_one = Floating::ReinterpretBits(one_bits + max_ulps); + values_.further_from_one = Floating::ReinterpretBits( + one_bits + max_ulps + 1); // +infinity. - infinity_ = Floating::Infinity(); + values_.infinity = Floating::Infinity(); // The bits that represent +infinity. - const Bits infinity_bits = Floating(infinity_).bits(); + const Bits infinity_bits = Floating(values_.infinity).bits(); // Makes some numbers close to infinity. - close_to_infinity_ = Floating::ReinterpretBits(infinity_bits - max_ulps); - further_from_infinity_ = Floating::ReinterpretBits( + values_.close_to_infinity = Floating::ReinterpretBits( + infinity_bits - max_ulps); + values_.further_from_infinity = Floating::ReinterpretBits( infinity_bits - max_ulps - 1); - // Makes some NAN's. - nan1_ = Floating::ReinterpretBits(Floating::kExponentBitMask | 1); - nan2_ = Floating::ReinterpretBits(Floating::kExponentBitMask | 200); + // Makes some NAN's. Sets the most significant bit of the fraction so that + // our NaN's are quiet; trying to process a signaling NaN would raise an + // exception if our environment enables floating point exceptions. + values_.nan1 = Floating::ReinterpretBits(Floating::kExponentBitMask + | (static_cast(1) << (Floating::kFractionBitCount - 1)) | 1); + values_.nan2 = Floating::ReinterpretBits(Floating::kExponentBitMask + | (static_cast(1) << (Floating::kFractionBitCount - 1)) | 200); } void TestSize() { EXPECT_EQ(sizeof(RawType), sizeof(Bits)); } - // Pre-calculated numbers to be used by the tests. - - static RawType close_to_positive_zero_; - static RawType close_to_negative_zero_; - static RawType further_from_negative_zero_; - - static RawType close_to_one_; - static RawType further_from_one_; - - static RawType infinity_; - static RawType close_to_infinity_; - static RawType further_from_infinity_; - - static RawType nan1_; - static RawType nan2_; + static TestValues values_; }; template -RawType FloatingPointTest::close_to_positive_zero_; - -template -RawType FloatingPointTest::close_to_negative_zero_; - -template -RawType FloatingPointTest::further_from_negative_zero_; - -template -RawType FloatingPointTest::close_to_one_; - -template -RawType FloatingPointTest::further_from_one_; - -template -RawType FloatingPointTest::infinity_; - -template -RawType FloatingPointTest::close_to_infinity_; - -template -RawType FloatingPointTest::further_from_infinity_; - -template -RawType FloatingPointTest::nan1_; - -template -RawType FloatingPointTest::nan2_; +typename FloatingPointTest::TestValues + FloatingPointTest::values_; // Instantiates FloatingPointTest for testing *_FLOAT_EQ. typedef FloatingPointTest FloatTest; @@ -2220,20 +2274,26 @@ TEST_F(FloatTest, Zeros) { // overflow occurs when comparing numbers whose absolute value is very // small. TEST_F(FloatTest, AlmostZeros) { - EXPECT_FLOAT_EQ(0.0, close_to_positive_zero_); - EXPECT_FLOAT_EQ(-0.0, close_to_negative_zero_); - EXPECT_FLOAT_EQ(close_to_positive_zero_, close_to_negative_zero_); + // In C++Builder, names within local classes (such as used by + // EXPECT_FATAL_FAILURE) cannot be resolved against static members of the + // scoping class. Use a static local alias as a workaround. + static const FloatTest::TestValues& v(this->values_); + + EXPECT_FLOAT_EQ(0.0, v.close_to_positive_zero); + EXPECT_FLOAT_EQ(-0.0, v.close_to_negative_zero); + EXPECT_FLOAT_EQ(v.close_to_positive_zero, v.close_to_negative_zero); EXPECT_FATAL_FAILURE({ // NOLINT - ASSERT_FLOAT_EQ(close_to_positive_zero_, further_from_negative_zero_); - }, "further_from_negative_zero_"); + ASSERT_FLOAT_EQ(v.close_to_positive_zero, + v.further_from_negative_zero); + }, "v.further_from_negative_zero"); } // Tests comparing numbers close to each other. TEST_F(FloatTest, SmallDiff) { - EXPECT_FLOAT_EQ(1.0, close_to_one_); - EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(1.0, further_from_one_), - "further_from_one_"); + EXPECT_FLOAT_EQ(1.0, values_.close_to_one); + EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(1.0, values_.further_from_one), + "values_.further_from_one"); } // Tests comparing numbers far apart. @@ -2247,17 +2307,17 @@ TEST_F(FloatTest, LargeDiff) { // This ensures that no overflow occurs when comparing numbers whose // absolute value is very large. TEST_F(FloatTest, Infinity) { - EXPECT_FLOAT_EQ(infinity_, close_to_infinity_); - EXPECT_FLOAT_EQ(-infinity_, -close_to_infinity_); + EXPECT_FLOAT_EQ(values_.infinity, values_.close_to_infinity); + EXPECT_FLOAT_EQ(-values_.infinity, -values_.close_to_infinity); #if !GTEST_OS_SYMBIAN // Nokia's STLport crashes if we try to output infinity or NaN. - EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(infinity_, -infinity_), - "-infinity_"); + EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(values_.infinity, -values_.infinity), + "-values_.infinity"); - // This is interesting as the representations of infinity_ and nan1_ + // This is interesting as the representations of infinity and nan1 // are only 1 DLP apart. - EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(infinity_, nan1_), - "nan1_"); + EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(values_.infinity, values_.nan1), + "values_.nan1"); #endif // !GTEST_OS_SYMBIAN } @@ -2265,15 +2325,21 @@ TEST_F(FloatTest, Infinity) { TEST_F(FloatTest, NaN) { #if !GTEST_OS_SYMBIAN // Nokia's STLport crashes if we try to output infinity or NaN. - EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(nan1_, nan1_), - "nan1_"); - EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(nan1_, nan2_), - "nan2_"); - EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(1.0, nan1_), - "nan1_"); - - EXPECT_FATAL_FAILURE(ASSERT_FLOAT_EQ(nan1_, infinity_), - "infinity_"); + + // In C++Builder, names within local classes (such as used by + // EXPECT_FATAL_FAILURE) cannot be resolved against static members of the + // scoping class. Use a static local alias as a workaround. + static const FloatTest::TestValues& v(this->values_); + + EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(v.nan1, v.nan1), + "v.nan1"); + EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(v.nan1, v.nan2), + "v.nan2"); + EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(1.0, v.nan1), + "v.nan1"); + + EXPECT_FATAL_FAILURE(ASSERT_FLOAT_EQ(v.nan1, v.infinity), + "v.infinity"); #endif // !GTEST_OS_SYMBIAN } @@ -2281,16 +2347,16 @@ TEST_F(FloatTest, NaN) { TEST_F(FloatTest, Reflexive) { EXPECT_FLOAT_EQ(0.0, 0.0); EXPECT_FLOAT_EQ(1.0, 1.0); - ASSERT_FLOAT_EQ(infinity_, infinity_); + ASSERT_FLOAT_EQ(values_.infinity, values_.infinity); } // Tests that *_FLOAT_EQ are commutative. TEST_F(FloatTest, Commutative) { - // We already tested EXPECT_FLOAT_EQ(1.0, close_to_one_). - EXPECT_FLOAT_EQ(close_to_one_, 1.0); + // We already tested EXPECT_FLOAT_EQ(1.0, values_.close_to_one). + EXPECT_FLOAT_EQ(values_.close_to_one, 1.0); - // We already tested EXPECT_FLOAT_EQ(1.0, further_from_one_). - EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(further_from_one_, 1.0), + // We already tested EXPECT_FLOAT_EQ(1.0, values_.further_from_one). + EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(values_.further_from_one, 1.0), "1.0"); } @@ -2322,7 +2388,7 @@ TEST_F(FloatTest, FloatLESucceeds) { ASSERT_PRED_FORMAT2(FloatLE, 1.0f, 1.0f); // val1 == val2, // or when val1 is greater than, but almost equals to, val2. - EXPECT_PRED_FORMAT2(FloatLE, close_to_positive_zero_, 0.0f); + EXPECT_PRED_FORMAT2(FloatLE, values_.close_to_positive_zero, 0.0f); } // Tests the cases where FloatLE() should fail. @@ -2333,23 +2399,23 @@ TEST_F(FloatTest, FloatLEFails) { // or by a small yet non-negligible margin, EXPECT_NONFATAL_FAILURE({ // NOLINT - EXPECT_PRED_FORMAT2(FloatLE, further_from_one_, 1.0f); - }, "(further_from_one_) <= (1.0f)"); + EXPECT_PRED_FORMAT2(FloatLE, values_.further_from_one, 1.0f); + }, "(values_.further_from_one) <= (1.0f)"); -#if !GTEST_OS_SYMBIAN +#if !GTEST_OS_SYMBIAN && !defined(__BORLANDC__) // Nokia's STLport crashes if we try to output infinity or NaN. - // or when either val1 or val2 is NaN. + // C++Builder gives bad results for ordered comparisons involving NaNs + // due to compiler bugs. EXPECT_NONFATAL_FAILURE({ // NOLINT - EXPECT_PRED_FORMAT2(FloatLE, nan1_, infinity_); - }, "(nan1_) <= (infinity_)"); + EXPECT_PRED_FORMAT2(FloatLE, values_.nan1, values_.infinity); + }, "(values_.nan1) <= (values_.infinity)"); EXPECT_NONFATAL_FAILURE({ // NOLINT - EXPECT_PRED_FORMAT2(FloatLE, -infinity_, nan1_); - }, "(-infinity_) <= (nan1_)"); - + EXPECT_PRED_FORMAT2(FloatLE, -values_.infinity, values_.nan1); + }, "(-values_.infinity) <= (values_.nan1)"); EXPECT_FATAL_FAILURE({ // NOLINT - ASSERT_PRED_FORMAT2(FloatLE, nan1_, nan1_); - }, "(nan1_) <= (nan1_)"); -#endif // !GTEST_OS_SYMBIAN + ASSERT_PRED_FORMAT2(FloatLE, values_.nan1, values_.nan1); + }, "(values_.nan1) <= (values_.nan1)"); +#endif // !GTEST_OS_SYMBIAN && !defined(__BORLANDC__) } // Instantiates FloatingPointTest for testing *_DOUBLE_EQ. @@ -2375,20 +2441,26 @@ TEST_F(DoubleTest, Zeros) { // overflow occurs when comparing numbers whose absolute value is very // small. TEST_F(DoubleTest, AlmostZeros) { - EXPECT_DOUBLE_EQ(0.0, close_to_positive_zero_); - EXPECT_DOUBLE_EQ(-0.0, close_to_negative_zero_); - EXPECT_DOUBLE_EQ(close_to_positive_zero_, close_to_negative_zero_); + // In C++Builder, names within local classes (such as used by + // EXPECT_FATAL_FAILURE) cannot be resolved against static members of the + // scoping class. Use a static local alias as a workaround. + static const DoubleTest::TestValues& v(this->values_); + + EXPECT_DOUBLE_EQ(0.0, v.close_to_positive_zero); + EXPECT_DOUBLE_EQ(-0.0, v.close_to_negative_zero); + EXPECT_DOUBLE_EQ(v.close_to_positive_zero, v.close_to_negative_zero); EXPECT_FATAL_FAILURE({ // NOLINT - ASSERT_DOUBLE_EQ(close_to_positive_zero_, further_from_negative_zero_); - }, "further_from_negative_zero_"); + ASSERT_DOUBLE_EQ(v.close_to_positive_zero, + v.further_from_negative_zero); + }, "v.further_from_negative_zero"); } // Tests comparing numbers close to each other. TEST_F(DoubleTest, SmallDiff) { - EXPECT_DOUBLE_EQ(1.0, close_to_one_); - EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(1.0, further_from_one_), - "further_from_one_"); + EXPECT_DOUBLE_EQ(1.0, values_.close_to_one); + EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(1.0, values_.further_from_one), + "values_.further_from_one"); } // Tests comparing numbers far apart. @@ -2402,29 +2474,35 @@ TEST_F(DoubleTest, LargeDiff) { // This ensures that no overflow occurs when comparing numbers whose // absolute value is very large. TEST_F(DoubleTest, Infinity) { - EXPECT_DOUBLE_EQ(infinity_, close_to_infinity_); - EXPECT_DOUBLE_EQ(-infinity_, -close_to_infinity_); + EXPECT_DOUBLE_EQ(values_.infinity, values_.close_to_infinity); + EXPECT_DOUBLE_EQ(-values_.infinity, -values_.close_to_infinity); #if !GTEST_OS_SYMBIAN // Nokia's STLport crashes if we try to output infinity or NaN. - EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(infinity_, -infinity_), - "-infinity_"); + EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(values_.infinity, -values_.infinity), + "-values_.infinity"); // This is interesting as the representations of infinity_ and nan1_ // are only 1 DLP apart. - EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(infinity_, nan1_), - "nan1_"); + EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(values_.infinity, values_.nan1), + "values_.nan1"); #endif // !GTEST_OS_SYMBIAN } // Tests that comparing with NAN always returns false. TEST_F(DoubleTest, NaN) { #if !GTEST_OS_SYMBIAN + // In C++Builder, names within local classes (such as used by + // EXPECT_FATAL_FAILURE) cannot be resolved against static members of the + // scoping class. Use a static local alias as a workaround. + static const DoubleTest::TestValues& v(this->values_); + // Nokia's STLport crashes if we try to output infinity or NaN. - EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(nan1_, nan1_), - "nan1_"); - EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(nan1_, nan2_), "nan2_"); - EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(1.0, nan1_), "nan1_"); - EXPECT_FATAL_FAILURE(ASSERT_DOUBLE_EQ(nan1_, infinity_), "infinity_"); + EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(v.nan1, v.nan1), + "v.nan1"); + EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(v.nan1, v.nan2), "v.nan2"); + EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(1.0, v.nan1), "v.nan1"); + EXPECT_FATAL_FAILURE(ASSERT_DOUBLE_EQ(v.nan1, v.infinity), + "v.infinity"); #endif // !GTEST_OS_SYMBIAN } @@ -2434,17 +2512,18 @@ TEST_F(DoubleTest, Reflexive) { EXPECT_DOUBLE_EQ(1.0, 1.0); #if !GTEST_OS_SYMBIAN // Nokia's STLport crashes if we try to output infinity or NaN. - ASSERT_DOUBLE_EQ(infinity_, infinity_); + ASSERT_DOUBLE_EQ(values_.infinity, values_.infinity); #endif // !GTEST_OS_SYMBIAN } // Tests that *_DOUBLE_EQ are commutative. TEST_F(DoubleTest, Commutative) { - // We already tested EXPECT_DOUBLE_EQ(1.0, close_to_one_). - EXPECT_DOUBLE_EQ(close_to_one_, 1.0); + // We already tested EXPECT_DOUBLE_EQ(1.0, values_.close_to_one). + EXPECT_DOUBLE_EQ(values_.close_to_one, 1.0); - // We already tested EXPECT_DOUBLE_EQ(1.0, further_from_one_). - EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(further_from_one_, 1.0), "1.0"); + // We already tested EXPECT_DOUBLE_EQ(1.0, values_.further_from_one). + EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(values_.further_from_one, 1.0), + "1.0"); } // Tests EXPECT_NEAR. @@ -2475,7 +2554,7 @@ TEST_F(DoubleTest, DoubleLESucceeds) { ASSERT_PRED_FORMAT2(DoubleLE, 1.0, 1.0); // val1 == val2, // or when val1 is greater than, but almost equals to, val2. - EXPECT_PRED_FORMAT2(DoubleLE, close_to_positive_zero_, 0.0); + EXPECT_PRED_FORMAT2(DoubleLE, values_.close_to_positive_zero, 0.0); } // Tests the cases where DoubleLE() should fail. @@ -2486,22 +2565,23 @@ TEST_F(DoubleTest, DoubleLEFails) { // or by a small yet non-negligible margin, EXPECT_NONFATAL_FAILURE({ // NOLINT - EXPECT_PRED_FORMAT2(DoubleLE, further_from_one_, 1.0); - }, "(further_from_one_) <= (1.0)"); + EXPECT_PRED_FORMAT2(DoubleLE, values_.further_from_one, 1.0); + }, "(values_.further_from_one) <= (1.0)"); -#if !GTEST_OS_SYMBIAN +#if !GTEST_OS_SYMBIAN && !defined(__BORLANDC__) // Nokia's STLport crashes if we try to output infinity or NaN. - // or when either val1 or val2 is NaN. + // C++Builder gives bad results for ordered comparisons involving NaNs + // due to compiler bugs. EXPECT_NONFATAL_FAILURE({ // NOLINT - EXPECT_PRED_FORMAT2(DoubleLE, nan1_, infinity_); - }, "(nan1_) <= (infinity_)"); + EXPECT_PRED_FORMAT2(DoubleLE, values_.nan1, values_.infinity); + }, "(values_.nan1) <= (values_.infinity)"); EXPECT_NONFATAL_FAILURE({ // NOLINT - EXPECT_PRED_FORMAT2(DoubleLE, -infinity_, nan1_); - }, " (-infinity_) <= (nan1_)"); + EXPECT_PRED_FORMAT2(DoubleLE, -values_.infinity, values_.nan1); + }, " (-values_.infinity) <= (values_.nan1)"); EXPECT_FATAL_FAILURE({ // NOLINT - ASSERT_PRED_FORMAT2(DoubleLE, nan1_, nan1_); - }, "(nan1_) <= (nan1_)"); -#endif // !GTEST_OS_SYMBIAN + ASSERT_PRED_FORMAT2(DoubleLE, values_.nan1, values_.nan1); + }, "(values_.nan1) <= (values_.nan1)"); +#endif // !GTEST_OS_SYMBIAN && !defined(__BORLANDC__) } @@ -2621,25 +2701,28 @@ INSTANTIATE_TYPED_TEST_CASE_P(My, DISABLED_TypedTestP, NumericTypes); // Tests that assertion macros evaluate their arguments exactly once. class SingleEvaluationTest : public Test { - protected: - SingleEvaluationTest() { - p1_ = s1_; - p2_ = s2_; - a_ = 0; - b_ = 0; - } - + public: // This helper function is needed by the FailedASSERT_STREQ test - // below. + // below. It's public to work around C++Builder's bug with scoping local + // classes. static void CompareAndIncrementCharPtrs() { ASSERT_STREQ(p1_++, p2_++); } - // This helper function is needed by the FailedASSERT_NE test below. + // This helper function is needed by the FailedASSERT_NE test below. It's + // public to work around C++Builder's bug with scoping local classes. static void CompareAndIncrementInts() { ASSERT_NE(a_++, b_++); } + protected: + SingleEvaluationTest() { + p1_ = s1_; + p2_ = s2_; + a_ = 0; + b_ = 0; + } + static const char* const s1_; static const char* const s2_; static const char* p1_; @@ -2659,7 +2742,7 @@ int SingleEvaluationTest::b_; // Tests that when ASSERT_STREQ fails, it evaluates its arguments // exactly once. TEST_F(SingleEvaluationTest, FailedASSERT_STREQ) { - EXPECT_FATAL_FAILURE(CompareAndIncrementCharPtrs(), + EXPECT_FATAL_FAILURE(SingleEvaluationTest::CompareAndIncrementCharPtrs(), "p2_++"); EXPECT_EQ(s1_ + 1, p1_); EXPECT_EQ(s2_ + 1, p2_); @@ -2682,7 +2765,8 @@ TEST_F(SingleEvaluationTest, ASSERT_STR) { // Tests that when ASSERT_NE fails, it evaluates its arguments exactly // once. TEST_F(SingleEvaluationTest, FailedASSERT_NE) { - EXPECT_FATAL_FAILURE(CompareAndIncrementInts(), "(a_++) != (b_++)"); + EXPECT_FATAL_FAILURE(SingleEvaluationTest::CompareAndIncrementInts(), + "(a_++) != (b_++)"); EXPECT_EQ(1, a_); EXPECT_EQ(1, b_); } @@ -2924,6 +3008,11 @@ TEST(AssertionTest, AppendUserMessage) { AppendUserMessage(foo, msg).c_str()); } +#ifdef __BORLANDC__ +// Silences warnings: "Condition is always true", "Unreachable code" +#pragma option push -w-ccc -w-rch +#endif + // Tests ASSERT_TRUE. TEST(AssertionTest, ASSERT_TRUE) { ASSERT_TRUE(2 > 1); // NOLINT @@ -2940,6 +3029,11 @@ TEST(AssertionTest, ASSERT_FALSE) { "Expected: false"); } +#ifdef __BORLANDC__ +// Restores warnings after previous "#pragma option push" supressed them +#pragma option pop +#endif + // Tests using ASSERT_EQ on double values. The purpose is to make // sure that the specialization we did for integer and anonymous enums // isn't used for double arguments. @@ -3035,14 +3129,16 @@ TEST(AssertionTest, ASSERT_GT) { void ThrowNothing() {} - // Tests ASSERT_THROW. TEST(AssertionTest, ASSERT_THROW) { ASSERT_THROW(ThrowAnInteger(), int); +#if !defined(__BORLANDC__) || __BORLANDC__ >= 0x600 || defined(_DEBUG) + // ICE's in C++Builder 2007 (Release build). EXPECT_FATAL_FAILURE( ASSERT_THROW(ThrowAnInteger(), bool), "Expected: ThrowAnInteger() throws an exception of type bool.\n" " Actual: it throws a different type."); +#endif EXPECT_FATAL_FAILURE( ASSERT_THROW(ThrowNothing(), bool), "Expected: ThrowNothing() throws an exception of type bool.\n" @@ -3248,9 +3344,12 @@ TEST(HRESULTAssertionTest, EXPECT_HRESULT_FAILED) { TEST(HRESULTAssertionTest, ASSERT_HRESULT_FAILED) { ASSERT_HRESULT_FAILED(E_UNEXPECTED); +#ifndef __BORLANDC__ + // ICE's in C++Builder 2007 and 2009. EXPECT_FATAL_FAILURE(ASSERT_HRESULT_FAILED(OkHRESULTSuccess()), "Expected: (OkHRESULTSuccess()) fails.\n" " Actual: 0x00000000"); +#endif EXPECT_FATAL_FAILURE(ASSERT_HRESULT_FAILED(FalseHRESULTSuccess()), "Expected: (FalseHRESULTSuccess()) fails.\n" " Actual: 0x00000001"); @@ -3267,9 +3366,12 @@ TEST(HRESULTAssertionTest, Streaming) { EXPECT_HRESULT_SUCCEEDED(E_UNEXPECTED) << "expected failure", "expected failure"); +#ifndef __BORLANDC__ + // ICE's in C++Builder 2007 and 2009. EXPECT_FATAL_FAILURE( ASSERT_HRESULT_SUCCEEDED(E_UNEXPECTED) << "expected failure", "expected failure"); +#endif EXPECT_NONFATAL_FAILURE( EXPECT_HRESULT_FAILED(S_OK) << "expected failure", @@ -3282,6 +3384,11 @@ TEST(HRESULTAssertionTest, Streaming) { #endif // GTEST_OS_WINDOWS +#ifdef __BORLANDC__ +// Silences warnings: "Condition is always true", "Unreachable code" +#pragma option push -w-ccc -w-rch +#endif + // Tests that the assertion macros behave like single statements. TEST(AssertionSyntaxTest, BasicAssertionsBehavesLikeSingleStatement) { if (false) @@ -3476,6 +3583,11 @@ TEST(ExpectTest, EXPECT_FALSE) { "2 < 3"); } +#ifdef __BORLANDC__ +// Restores warnings after previous "#pragma option push" supressed them +#pragma option pop +#endif + // Tests EXPECT_EQ. TEST(ExpectTest, EXPECT_EQ) { EXPECT_EQ(5, 2 + 3); @@ -5197,6 +5309,11 @@ TEST(StreamingAssertionsTest, Unconditional) { "expected failure"); } +#ifdef __BORLANDC__ +// Silences warnings: "Condition is always true", "Unreachable code" +#pragma option push -w-ccc -w-rch +#endif + TEST(StreamingAssertionsTest, Truth) { EXPECT_TRUE(true) << "unexpected failure"; ASSERT_TRUE(true) << "unexpected failure"; @@ -5215,6 +5332,11 @@ TEST(StreamingAssertionsTest, Truth2) { "expected failure"); } +#ifdef __BORLANDC__ +// Restores warnings after previous "#pragma option push" supressed them +#pragma option pop +#endif + TEST(StreamingAssertionsTest, IntegerEquals) { EXPECT_EQ(1, 1) << "unexpected failure"; ASSERT_EQ(1, 1) << "unexpected failure"; -- cgit v1.2.3 From fbaedd2d017ca89d1362e54dc1890c4a5f55f240 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Wed, 29 Apr 2009 23:53:30 +0000 Subject: Trivial source code format tweak. --- test/gtest_filter_unittest_.cc | 4 ---- test/gtest_list_tests_unittest_.cc | 2 -- 2 files changed, 6 deletions(-) (limited to 'test') diff --git a/test/gtest_filter_unittest_.cc b/test/gtest_filter_unittest_.cc index dd4f7167..d496f531 100644 --- a/test/gtest_filter_unittest_.cc +++ b/test/gtest_filter_unittest_.cc @@ -40,7 +40,6 @@ #include - namespace { // Test case FooTest. @@ -55,7 +54,6 @@ TEST_F(FooTest, Xyz) { FAIL() << "Expected failure."; } - // Test case BarTest. TEST(BarTest, TestOne) { @@ -109,7 +107,6 @@ TEST(HasDeathTest, Test2) { #endif // GTEST_HAS_DEATH_TEST } - // Test case FoobarTest TEST(DISABLED_FoobarTest, Test1) { @@ -142,7 +139,6 @@ INSTANTIATE_TEST_CASE_P(SeqQ, ParamTest, testing::Values(5, 6)); } // namespace - int main(int argc, char **argv) { testing::InitGoogleTest(&argc, argv); diff --git a/test/gtest_list_tests_unittest_.cc b/test/gtest_list_tests_unittest_.cc index b5e07ddd..1ba3922c 100644 --- a/test/gtest_list_tests_unittest_.cc +++ b/test/gtest_list_tests_unittest_.cc @@ -40,7 +40,6 @@ #include - namespace { // Several different test cases and tests that will be listed. @@ -79,7 +78,6 @@ TEST(FooDeathTest, Test1) { } // namespace - int main(int argc, char **argv) { testing::InitGoogleTest(&argc, argv); -- cgit v1.2.3 From 9b23e3cc7677643f6adaf6c327275d0a7cdff02c Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Tue, 5 May 2009 19:31:00 +0000 Subject: Removes dead code (by Vlad Losev). Fixes tr1 tuple's path on gcc version before 4.0.0 (by Zhanyong Wan). --- test/gtest_output_test.py | 1 - test/gtest_output_test_.cc | 7 ------- 2 files changed, 8 deletions(-) (limited to 'test') diff --git a/test/gtest_output_test.py b/test/gtest_output_test.py index 52894064..6cff1623 100755 --- a/test/gtest_output_test.py +++ b/test/gtest_output_test.py @@ -262,7 +262,6 @@ class GTestOutputTest(unittest.TestCase): if SUPPORTS_DEATH_TESTS and SUPPORTS_TYPED_TESTS: self.assert_(golden == output) else: - print RemoveTestCounts(self.RemoveUnsupportedTests(golden)) self.assert_(RemoveTestCounts(self.RemoveUnsupportedTests(golden)) == RemoveTestCounts(output)) diff --git a/test/gtest_output_test_.cc b/test/gtest_output_test_.cc index 9c92d8cc..0e49f6c3 100644 --- a/test/gtest_output_test_.cc +++ b/test/gtest_output_test_.cc @@ -50,13 +50,6 @@ #include #endif // GTEST_HAS_PTHREAD -#if GTEST_OS_LINUX -#include -#include -#include -#include -#endif // GTEST_OS_LINUX - using testing::ScopedFakeTestPartResultReporter; using testing::TestPartResultArray; -- cgit v1.2.3 From 42abea350d4f26a006f760fae0d1f9882deb9221 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Tue, 5 May 2009 23:13:43 +0000 Subject: Uses DebugBreak() to properly break on Windows (by Vlad Losev). --- test/gtest_break_on_failure_unittest.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'test') diff --git a/test/gtest_break_on_failure_unittest.py b/test/gtest_break_on_failure_unittest.py index c9dd0081..c312ce22 100755 --- a/test/gtest_break_on_failure_unittest.py +++ b/test/gtest_break_on_failure_unittest.py @@ -57,6 +57,9 @@ BREAK_ON_FAILURE_FLAG = 'gtest_break_on_failure' # The environment variable for enabling/disabling the throw-on-failure mode. THROW_ON_FAILURE_ENV_VAR = 'GTEST_THROW_ON_FAILURE' +# The environment variable for enabling/disabling the catch-exceptions mode. +CATCH_EXCEPTIONS_ENV_VAR = 'GTEST_CATCH_EXCEPTIONS' + # Path to the gtest_break_on_failure_unittest_ program. EXE_PATH = gtest_test_utils.GetTestExecutablePath( 'gtest_break_on_failure_unittest_') @@ -194,5 +197,18 @@ class GTestBreakOnFailureUnitTest(unittest.TestCase): finally: SetEnvVar(THROW_ON_FAILURE_ENV_VAR, None) + if IS_WINDOWS: + def testCatchExceptionsDoesNotInterfere(self): + """Tests that gtest_catch_exceptions doesn't interfere.""" + + SetEnvVar(CATCH_EXCEPTIONS_ENV_VAR, '1') + try: + self.RunAndVerify(env_var_value='1', + flag_value='1', + expect_seg_fault=1) + finally: + SetEnvVar(CATCH_EXCEPTIONS_ENV_VAR, None) + + if __name__ == '__main__': gtest_test_utils.Main() -- cgit v1.2.3 From c8a0482c0bffe471a82d8513536aa87235cb523f Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Thu, 7 May 2009 20:39:08 +0000 Subject: Fixes the broken gtest_break_on_failure_unittest.py. --- test/gtest_break_on_failure_unittest.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'test') diff --git a/test/gtest_break_on_failure_unittest.py b/test/gtest_break_on_failure_unittest.py index c312ce22..cae288ad 100755 --- a/test/gtest_break_on_failure_unittest.py +++ b/test/gtest_break_on_failure_unittest.py @@ -48,6 +48,8 @@ import unittest # Constants. +IS_WINDOWS = os.name == 'nt' + # The environment variable for enabling/disabling the break-on-failure mode. BREAK_ON_FAILURE_ENV_VAR = 'GTEST_BREAK_ON_FAILURE' -- cgit v1.2.3 From 8de91f8f8374f49240b379e2328de9121837bae8 Mon Sep 17 00:00:00 2001 From: tsunanet Date: Mon, 18 May 2009 20:53:57 +0000 Subject: Change a few visibilities to work around a bug in g++ 3.4.2. It looks like this version of g++ is confused by the local class generated by the TEST_F macro and it can't tell that we're in a method that inherits the class we want to access. This bug causes the following kind of error: ../samples/../test/gtest_unittest.cc: In static member function `static void ::ExpectFatalFailureTest_CatchesFatalFaliure_Test::TestBody()::GTestExpectFatalFailureHelper::Execute()': ../samples/../test/gtest_unittest.cc:799: error: `static void ::ScopedFakeTestPartResultReporterTest::AddFailure(::ScopedFakeTestPartResultReporterTest::FailureMode)' is protected ../samples/../test/gtest_unittest.cc:883: error: within this context Signed-off-by: Benoit Sigoure --- test/gtest_output_test_.cc | 2 +- test/gtest_unittest.cc | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'test') diff --git a/test/gtest_output_test_.cc b/test/gtest_output_test_.cc index 0e49f6c3..6d42ad80 100644 --- a/test/gtest_output_test_.cc +++ b/test/gtest_output_test_.cc @@ -808,7 +808,7 @@ INSTANTIATE_TYPED_TEST_CASE_P(My, ATypeParamDeathTest, NumericTypes); // Tests various failure conditions of // EXPECT_{,NON}FATAL_FAILURE{,_ON_ALL_THREADS}. class ExpectFailureTest : public testing::Test { - protected: + public: // Must be public and not protected due to a bug in g++ 3.4.2. enum FailureMode { FATAL_FAILURE, NONFATAL_FAILURE diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index 8becca15..878aa23c 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -827,7 +827,7 @@ static void AddNonfatalFailure() { } class ScopedFakeTestPartResultReporterTest : public Test { - protected: + public: // Must be public and not protected due to a bug in g++ 3.4.2. enum FailureMode { FATAL_FAILURE, NONFATAL_FAILURE @@ -2701,7 +2701,7 @@ INSTANTIATE_TYPED_TEST_CASE_P(My, DISABLED_TypedTestP, NumericTypes); // Tests that assertion macros evaluate their arguments exactly once. class SingleEvaluationTest : public Test { - public: + public: // Must be public and not protected due to a bug in g++ 3.4.2. // This helper function is needed by the FailedASSERT_STREQ test // below. It's public to work around C++Builder's bug with scoping local // classes. -- cgit v1.2.3 From 1bd424d9608d85fc6b705a2370ed86db3118dcf6 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Fri, 29 May 2009 19:46:51 +0000 Subject: Adds missing copyright in test/gtest-test-part_test.cc (by Markus Heule). Minor format adjustments. --- test/gtest-param-test_test.cc | 2 +- test/gtest-test-part_test.cc | 31 ++++++++++++++++++++++++++++++- test/gtest_filter_unittest_.cc | 2 +- test/gtest_list_tests_unittest_.cc | 2 +- test/gtest_output_test.py | 7 ++++++- test/gtest_output_test_.cc | 4 ++++ 6 files changed, 43 insertions(+), 5 deletions(-) (limited to 'test') diff --git a/test/gtest-param-test_test.cc b/test/gtest-param-test_test.cc index 63080216..ecb5fdbb 100644 --- a/test/gtest-param-test_test.cc +++ b/test/gtest-param-test_test.cc @@ -787,6 +787,6 @@ int main(int argc, char **argv) { GeneratorEvaluationTest::set_param_value(1); #endif // GTEST_HAS_PARAM_TEST - testing::InitGoogleTest(&argc, argv); + ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/test/gtest-test-part_test.cc b/test/gtest-test-part_test.cc index f9e2e5d3..93fe156e 100644 --- a/test/gtest-test-part_test.cc +++ b/test/gtest-test-part_test.cc @@ -1,5 +1,34 @@ -// Copyright 2008 Google Inc. All Rights Reserved. +// Copyright 2008 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: mheule@google.com (Markus Heule) +// #include diff --git a/test/gtest_filter_unittest_.cc b/test/gtest_filter_unittest_.cc index d496f531..3cbddcf6 100644 --- a/test/gtest_filter_unittest_.cc +++ b/test/gtest_filter_unittest_.cc @@ -140,7 +140,7 @@ INSTANTIATE_TEST_CASE_P(SeqQ, ParamTest, testing::Values(5, 6)); } // namespace int main(int argc, char **argv) { - testing::InitGoogleTest(&argc, argv); + ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/test/gtest_list_tests_unittest_.cc b/test/gtest_list_tests_unittest_.cc index 1ba3922c..a0ed0825 100644 --- a/test/gtest_list_tests_unittest_.cc +++ b/test/gtest_list_tests_unittest_.cc @@ -79,7 +79,7 @@ TEST(FooDeathTest, Test1) { } // namespace int main(int argc, char **argv) { - testing::InitGoogleTest(&argc, argv); + ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/test/gtest_output_test.py b/test/gtest_output_test.py index 6cff1623..2751fa66 100755 --- a/test/gtest_output_test.py +++ b/test/gtest_output_test.py @@ -253,8 +253,13 @@ class GTestOutputTest(unittest.TestCase): def testOutput(self): output = GetOutputOfAllCommands() + golden_file = open(GOLDEN_PATH, 'rb') - golden = golden_file.read() + # A mis-configured source control system can cause \r appear in EOL + # sequences when we read the golden file irrespective of an operating + # system used. Therefore, we need to strip those \r's from newlines + # unconditionally. + golden = ToUnixLineEnding(golden_file.read()) golden_file.close() # We want the test to pass regardless of death tests being diff --git a/test/gtest_output_test_.cc b/test/gtest_output_test_.cc index 6d42ad80..693df3f5 100644 --- a/test/gtest_output_test_.cc +++ b/test/gtest_output_test_.cc @@ -974,6 +974,10 @@ int main(int argc, char **argv) { // We just run the tests, knowing some of them are intended to fail. // We will use a separate Python script to compare the output of // this program with the golden file. + + // It's hard to test InitGoogleTest() directly, as it has many + // global side effects. The following line serves as a sanity test + // for it. testing::InitGoogleTest(&argc, argv); if (argc >= 2 && String(argv[1]) == "--gtest_internal_skip_environment_and_ad_hoc_tests") -- cgit v1.2.3 From fd36c200f446aaada1a1f0b026f2d742d4b2fa5a Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Tue, 9 Jun 2009 05:38:14 +0000 Subject: Adds support for xterm-256color (by Michihiro Kuramochi). --- test/gtest_color_test.py | 1 + 1 file changed, 1 insertion(+) (limited to 'test') diff --git a/test/gtest_color_test.py b/test/gtest_color_test.py index 32db4b9a..1b686304 100755 --- a/test/gtest_color_test.py +++ b/test/gtest_color_test.py @@ -78,6 +78,7 @@ class GTestColorTest(unittest.TestCase): self.assert_(UsesColor('cygwin', None, None)) self.assert_(UsesColor('xterm', None, None)) self.assert_(UsesColor('xterm-color', None, None)) + self.assert_(UsesColor('xterm-256color', None, None)) def testFlagOnly(self): """Tests the case when there's --gtest_color but not GTEST_COLOR.""" -- cgit v1.2.3 From 819501581ccab949e7058ece111120e866197540 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Tue, 9 Jun 2009 05:47:03 +0000 Subject: Adds run_tests.py for running the tests (by Vlad Losev). --- test/run_tests_test.py | 527 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 527 insertions(+) create mode 100755 test/run_tests_test.py (limited to 'test') diff --git a/test/run_tests_test.py b/test/run_tests_test.py new file mode 100755 index 00000000..75b7d9d2 --- /dev/null +++ b/test/run_tests_test.py @@ -0,0 +1,527 @@ +#!/usr/bin/env python +# +# Copyright 2009 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. + +"""Tests for run_tests.py test runner script.""" + +__author__ = 'vladl@google.com (Vlad Losev)' + +import os +import sys +import unittest + +sys.path.append(os.path.join(os.path.dirname(sys.argv[0]), os.pardir)) +import run_tests + + +class FakePath(object): + """A fake os.path module for testing.""" + + def __init__(self, current_dir=os.getcwd(), known_paths=None): + self.current_dir = current_dir + self.tree = {} + self.path_separator = os.sep + + if known_paths: + self._AddPaths(known_paths) + + def _AddPath(self, path): + ends_with_slash = path.endswith('/') + path = self.abspath(path) + if ends_with_slash: + path += self.path_separator + name_list = path.split(self.path_separator) + tree = self.tree + for name in name_list[:-1]: + if not name: + continue + if name in tree: + tree = tree[name] + else: + tree[name] = {} + tree = tree[name] + + name = name_list[-1] + if name: + if name in tree: + assert tree[name] == 1 + else: + tree[name] = 1 + + def _AddPaths(self, paths): + for path in paths: + self._AddPath(path) + + def PathElement(self, path): + """Returns an internal representation of directory tree entry for path.""" + tree = self.tree + name_list = self.abspath(path).split(self.path_separator) + for name in name_list: + if not name: + continue + tree = tree.get(name, None) + if tree is None: + break + + return tree + + def abspath(self, path): + return os.path.normpath(os.path.join(self.current_dir, path)) + + def isfile(self, path): + return self.PathElement(self.abspath(path)) == 1 + + def isdir(self, path): + return type(self.PathElement(self.abspath(path))) == type(dict()) + + def basename(self, path): + return os.path.basename(path) + + def dirname(self, path): + return os.path.dirname(path) + + def join(self, *kargs): + return os.path.join(*kargs) + + +class FakeOs(object): + """A fake os module for testing.""" + P_WAIT = os.P_WAIT + + def __init__(self, fake_path_module): + self.path = fake_path_module + + # Some methods/attributes are delegated to the real os module. + self.environ = os.environ + + def listdir(self, path): + assert self.path.isdir(path) + return self.path.PathElement(path).iterkeys() + + def spawn(self, wait, executable, *kargs): + assert wait == FakeOs.P_WAIT + return self.spawn_impl(executable, kargs) + + +class GetTestsToRunTest(unittest.TestCase): + """Exercises TestRunner.GetTestsToRun.""" + + def AssertResultsEqual(self, results, expected): + """Asserts results returned by GetTestsToRun equal to expected results.""" + + def NormalizeResultPaths(paths): + """Normalizes values returned by GetTestsToRun for comparison.""" + + def NormalizeResultPair(pair): + return (os.path.normpath(pair[0]), os.path.normpath(pair[1])) + + return (sorted(map(NormalizeResultPair, paths[0])), + sorted(map(NormalizeResultPair, paths[1]))) + + self.assertEqual(NormalizeResultPaths(results), + NormalizeResultPaths(expected), + 'Incorrect set of tests %s returned vs %s expected' % + (results, expected)) + + def setUp(self): + self.fake_os = FakeOs(FakePath( + current_dir=os.path.abspath(os.path.dirname(run_tests.__file__)), + known_paths=['scons/build/dbg/scons/gtest_unittest', + 'scons/build/opt/scons/gtest_unittest', + 'test/gtest_color_test.py'])) + self.fake_configurations = ['dbg', 'opt'] + self.test_runner = run_tests.TestRunner(injected_os=self.fake_os, + injected_subprocess=None) + + def testBinaryTestsOnly(self): + """Exercises GetTestsToRun with parameters designating binary tests only.""" + + # A default build. + self.AssertResultsEqual( + self.test_runner.GetTestsToRun( + ['gtest_unittest'], + '', + False, + available_configurations=self.fake_configurations), + ([], + [('scons/build/dbg/scons', 'scons/build/dbg/scons/gtest_unittest')])) + + # An explicitly specified directory. + self.AssertResultsEqual( + self.test_runner.GetTestsToRun( + ['scons/build/dbg/scons', 'gtest_unittest'], + '', + False, + available_configurations=self.fake_configurations), + ([], + [('scons/build/dbg/scons', 'scons/build/dbg/scons/gtest_unittest')])) + + # A particular configuration. + self.AssertResultsEqual( + self.test_runner.GetTestsToRun( + ['gtest_unittest'], + 'other', + False, + available_configurations=self.fake_configurations), + ([], + [('scons/build/other/scons', + 'scons/build/other/scons/gtest_unittest')])) + + # All available configurations + self.AssertResultsEqual( + self.test_runner.GetTestsToRun( + ['gtest_unittest'], + 'all', + False, + available_configurations=self.fake_configurations), + ([], + [('scons/build/dbg/scons', 'scons/build/dbg/scons/gtest_unittest'), + ('scons/build/opt/scons', 'scons/build/opt/scons/gtest_unittest')])) + + # All built configurations (unbuilt don't cause failure). + self.AssertResultsEqual( + self.test_runner.GetTestsToRun( + ['gtest_unittest'], + '', + True, + available_configurations=self.fake_configurations + ['unbuilt']), + ([], + [('scons/build/dbg/scons', 'scons/build/dbg/scons/gtest_unittest'), + ('scons/build/opt/scons', 'scons/build/opt/scons/gtest_unittest')])) + + # A combination of an explicit directory and a configuration. + self.AssertResultsEqual( + self.test_runner.GetTestsToRun( + ['scons/build/dbg/scons', 'gtest_unittest'], + 'opt', + False, + available_configurations=self.fake_configurations), + ([], + [('scons/build/dbg/scons', 'scons/build/dbg/scons/gtest_unittest'), + ('scons/build/opt/scons', 'scons/build/opt/scons/gtest_unittest')])) + + # Same test specified in an explicit directory and via a configuration. + self.AssertResultsEqual( + self.test_runner.GetTestsToRun( + ['scons/build/dbg/scons', 'gtest_unittest'], + 'dbg', + False, + available_configurations=self.fake_configurations), + ([], + [('scons/build/dbg/scons', 'scons/build/dbg/scons/gtest_unittest')])) + + # All built configurations + explicit directory + explicit configuration. + self.AssertResultsEqual( + self.test_runner.GetTestsToRun( + ['scons/build/dbg/scons', 'gtest_unittest'], + 'opt', + True, + available_configurations=self.fake_configurations), + ([], + [('scons/build/dbg/scons', 'scons/build/dbg/scons/gtest_unittest'), + ('scons/build/opt/scons', 'scons/build/opt/scons/gtest_unittest')])) + + def testPythonTestsOnly(self): + """Exercises GetTestsToRun with parameters designating Python tests only.""" + + # A default build. + self.AssertResultsEqual( + self.test_runner.GetTestsToRun( + ['gtest_color_test.py'], + '', + False, + available_configurations=self.fake_configurations), + ([('scons/build/dbg/scons', 'test/gtest_color_test.py')], + [])) + + # An explicitly specified directory. + self.AssertResultsEqual( + self.test_runner.GetTestsToRun( + ['scons/build/dbg/scons', 'test/gtest_color_test.py'], + '', + False, + available_configurations=self.fake_configurations), + ([('scons/build/dbg/scons', 'test/gtest_color_test.py')], + [])) + + # A particular configuration. + self.AssertResultsEqual( + self.test_runner.GetTestsToRun( + ['gtest_color_test.py'], + 'other', + False, + available_configurations=self.fake_configurations), + ([('scons/build/other/scons', 'test/gtest_color_test.py')], + [])) + + # All available configurations + self.AssertResultsEqual( + self.test_runner.GetTestsToRun( + ['test/gtest_color_test.py'], + 'all', + False, + available_configurations=self.fake_configurations), + ([('scons/build/dbg/scons', 'test/gtest_color_test.py'), + ('scons/build/opt/scons', 'test/gtest_color_test.py')], + [])) + + # All built configurations (unbuilt don't cause failure). + self.AssertResultsEqual( + self.test_runner.GetTestsToRun( + ['gtest_color_test.py'], + '', + True, + available_configurations=self.fake_configurations + ['unbuilt']), + ([('scons/build/dbg/scons', 'test/gtest_color_test.py'), + ('scons/build/opt/scons', 'test/gtest_color_test.py')], + [])) + + # A combination of an explicit directory and a configuration. + self.AssertResultsEqual( + self.test_runner.GetTestsToRun( + ['scons/build/dbg/scons', 'gtest_color_test.py'], + 'opt', + False, + available_configurations=self.fake_configurations), + ([('scons/build/dbg/scons', 'test/gtest_color_test.py'), + ('scons/build/opt/scons', 'test/gtest_color_test.py')], + [])) + + # Same test specified in an explicit directory and via a configuration. + self.AssertResultsEqual( + self.test_runner.GetTestsToRun( + ['scons/build/dbg/scons', 'gtest_color_test.py'], + 'dbg', + False, + available_configurations=self.fake_configurations), + ([('scons/build/dbg/scons', 'test/gtest_color_test.py')], + [])) + + # All built configurations + explicit directory + explicit configuration. + self.AssertResultsEqual( + self.test_runner.GetTestsToRun( + ['scons/build/dbg/scons', 'gtest_color_test.py'], + 'opt', + True, + available_configurations=self.fake_configurations), + ([('scons/build/dbg/scons', 'test/gtest_color_test.py'), + ('scons/build/opt/scons', 'test/gtest_color_test.py')], + [])) + + def testCombinationOfBinaryAndPythonTests(self): + """Exercises GetTestsToRun with mixed binary/Python tests.""" + + # Use only default configuration for this test. + + # Neither binary nor Python tests are specified so find all. + self.AssertResultsEqual( + self.test_runner.GetTestsToRun( + [], + '', + False, + available_configurations=self.fake_configurations), + ([('scons/build/dbg/scons', 'test/gtest_color_test.py')], + [('scons/build/dbg/scons', 'scons/build/dbg/scons/gtest_unittest')])) + + # Specifying both binary and Python tests. + self.AssertResultsEqual( + self.test_runner.GetTestsToRun( + ['gtest_unittest', 'gtest_color_test.py'], + '', + False, + available_configurations=self.fake_configurations), + ([('scons/build/dbg/scons', 'test/gtest_color_test.py')], + [('scons/build/dbg/scons', 'scons/build/dbg/scons/gtest_unittest')])) + + # Specifying binary tests suppresses Python tests. + self.AssertResultsEqual( + self.test_runner.GetTestsToRun( + ['gtest_unittest'], + '', + False, + available_configurations=self.fake_configurations), + ([], + [('scons/build/dbg/scons', 'scons/build/dbg/scons/gtest_unittest')])) + + # Specifying Python tests suppresses binary tests. + self.AssertResultsEqual( + self.test_runner.GetTestsToRun( + ['gtest_color_test.py'], + '', + False, + available_configurations=self.fake_configurations), + ([('scons/build/dbg/scons', 'test/gtest_color_test.py')], + [])) + + def testIgnoresNonTestFiles(self): + """Verifies that GetTestsToRun ignores non-test files in the filesystem.""" + + self.fake_os = FakeOs(FakePath( + current_dir=os.path.abspath(os.path.dirname(run_tests.__file__)), + known_paths=['scons/build/dbg/scons/gtest_nontest', + 'scons/build/opt/scons/gtest_nontest.exe', + 'test/'])) + self.test_runner = run_tests.TestRunner(injected_os=self.fake_os, + injected_subprocess=None) + self.AssertResultsEqual( + self.test_runner.GetTestsToRun( + [], + '', + True, + available_configurations=self.fake_configurations), + ([], [])) + + def testNonTestBinary(self): + """Exercises GetTestsToRun with a non-test parameter.""" + + self.assert_( + not self.test_runner.GetTestsToRun( + ['gtest_unittest_not_really'], + '', + False, + available_configurations=self.fake_configurations)) + + def testNonExistingPythonTest(self): + """Exercises GetTestsToRun with a non-existent Python test parameter.""" + + self.assert_( + not self.test_runner.GetTestsToRun( + ['nonexistent_test.py'], + '', + False, + available_configurations=self.fake_configurations)) + + +class RunTestsTest(unittest.TestCase): + """Exercises TestRunner.RunTests.""" + + def SpawnSuccess(self, unused_executable, unused_argv): + """Fakes test success by returning 0 as an exit code.""" + + self.num_spawn_calls += 1 + return 0 + + def SpawnFailure(self, unused_executable, unused_argv): + """Fakes test success by returning 1 as an exit code.""" + + self.num_spawn_calls += 1 + return 1 + + def setUp(self): + self.fake_os = FakeOs(FakePath( + current_dir=os.path.abspath(os.path.dirname(run_tests.__file__)), + known_paths=['scons/build/dbg/scons/gtest_unittest', + 'scons/build/opt/scons/gtest_unittest', + 'test/gtest_color_test.py'])) + self.fake_configurations = ['dbg', 'opt'] + self.test_runner = run_tests.TestRunner(injected_os=self.fake_os, + injected_subprocess=None) + self.num_spawn_calls = 0 # A number of calls to spawn. + + def testRunPythonTestSuccess(self): + """Exercises RunTests to handle a Python test success.""" + + self.fake_os.spawn_impl = self.SpawnSuccess + self.assertEqual( + self.test_runner.RunTests( + [('scons/build/dbg/scons', 'test/gtest_color_test.py')], + []), + 0) + self.assertEqual(self.num_spawn_calls, 1) + + def testRunBinaryTestSuccess(self): + """Exercises RunTests to handle a binary test success.""" + + self.fake_os.spawn_impl = self.SpawnSuccess + self.assertEqual( + self.test_runner.RunTests( + [], + [('scons/build/dbg/scons', + 'scons/build/dbg/scons/gtest_unittest')]), + 0) + self.assertEqual(self.num_spawn_calls, 1) + + def testRunPythonTestFauilure(self): + """Exercises RunTests to handle a Python test failure.""" + + self.fake_os.spawn_impl = self.SpawnFailure + self.assertEqual( + self.test_runner.RunTests( + [('scons/build/dbg/scons', 'test/gtest_color_test.py')], + []), + 1) + self.assertEqual(self.num_spawn_calls, 1) + + def testRunBinaryTestFailure(self): + """Exercises RunTests to handle a binary test failure.""" + + self.fake_os.spawn_impl = self.SpawnFailure + self.assertEqual( + self.test_runner.RunTests( + [], + [('scons/build/dbg/scons', + 'scons/build/dbg/scons/gtest_unittest')]), + 1) + self.assertEqual(self.num_spawn_calls, 1) + + def testCombinedTestSuccess(self): + """Exercises RunTests to handle a success of both Python and binary test.""" + + self.fake_os.spawn_impl = self.SpawnSuccess + self.assertEqual( + self.test_runner.RunTests( + [('scons/build/dbg/scons', 'scons/build/dbg/scons/gtest_unittest')], + [('scons/build/dbg/scons', + 'scons/build/dbg/scons/gtest_unittest')]), + 0) + self.assertEqual(self.num_spawn_calls, 2) + + def testCombinedTestSuccessAndFailure(self): + """Exercises RunTests to handle a success of both Python and binary test.""" + + def SpawnImpl(executable, argv): + self.num_spawn_calls += 1 + # Simulates failure of a Python test and success of a binary test. + if '.py' in executable or '.py' in argv[0]: + return 1 + else: + return 0 + + self.fake_os.spawn_impl = SpawnImpl + self.assertEqual( + self.test_runner.RunTests( + [('scons/build/dbg/scons', 'scons/build/dbg/scons/gtest_unittest')], + [('scons/build/dbg/scons', + 'scons/build/dbg/scons/gtest_unittest')]), + 0) + self.assertEqual(self.num_spawn_calls, 2) + + +if __name__ == '__main__': + unittest.main() -- cgit v1.2.3 From b24b49d85a741f254cbe42da36e0cb93f0b0b57f Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Thu, 11 Jun 2009 00:51:14 +0000 Subject: Fixes a typo in run_tests.py and its test (by Vlad Losev). --- test/run_tests_test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'test') diff --git a/test/run_tests_test.py b/test/run_tests_test.py index 75b7d9d2..1d9f3b77 100755 --- a/test/run_tests_test.py +++ b/test/run_tests_test.py @@ -124,7 +124,7 @@ class FakeOs(object): assert self.path.isdir(path) return self.path.PathElement(path).iterkeys() - def spawn(self, wait, executable, *kargs): + def spawnv(self, wait, executable, *kargs): assert wait == FakeOs.P_WAIT return self.spawn_impl(executable, kargs) -- cgit v1.2.3 From 532dc2de35f2cef191bc91c3587a9f8f4974756f Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Wed, 17 Jun 2009 21:06:27 +0000 Subject: Implements a subset of TR1 tuple needed by gtest and gmock (by Zhanyong Wan); cleaned up the Python tests (by Vlad Losev); made run_tests.py invokable from any directory (by Vlad Losev). --- test/gtest-tuple_test.cc | 288 ++++++++++++++++++++++++++++++++ test/gtest_break_on_failure_unittest.py | 3 +- test/gtest_color_test.py | 7 +- test/gtest_env_var_test.py | 12 +- test/gtest_filter_unittest.py | 72 ++++---- test/gtest_help_test.py | 5 +- test/gtest_list_tests_unittest.py | 7 +- test/gtest_nc_test.py | 5 + test/gtest_output_test.py | 87 +++++++--- test/gtest_test_utils.py | 37 +++- test/gtest_throw_on_failure_test.py | 5 +- test/gtest_uninitialized_test.py | 4 +- test/gtest_xml_outfiles_test.py | 15 +- test/gtest_xml_output_unittest.py | 31 ++-- test/gtest_xml_test_utils.py | 7 +- test/run_tests_test.py | 50 +++++- 16 files changed, 524 insertions(+), 111 deletions(-) create mode 100644 test/gtest-tuple_test.cc (limited to 'test') diff --git a/test/gtest-tuple_test.cc b/test/gtest-tuple_test.cc new file mode 100644 index 00000000..3829118e --- /dev/null +++ b/test/gtest-tuple_test.cc @@ -0,0 +1,288 @@ +// Copyright 2007, 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) + +#include +#include +#include + +namespace { + +using ::std::tr1::get; +using ::std::tr1::make_tuple; +using ::std::tr1::tuple; +using ::std::tr1::tuple_element; +using ::std::tr1::tuple_size; +using ::testing::StaticAssertTypeEq; + +// Tests that tuple_element >::type returns TK. +TEST(tuple_element_Test, ReturnsElementType) { + StaticAssertTypeEq >::type>(); + StaticAssertTypeEq >::type>(); + StaticAssertTypeEq >::type>(); +} + +// Tests that tuple_size::value gives the number of fields in tuple +// type T. +TEST(tuple_size_Test, ReturnsNumberOfFields) { + EXPECT_EQ(0, +tuple_size >::value); + EXPECT_EQ(1, +tuple_size >::value); + EXPECT_EQ(1, +tuple_size >::value); + EXPECT_EQ(1, +(tuple_size > >::value)); + EXPECT_EQ(2, +(tuple_size >::value)); + EXPECT_EQ(3, +(tuple_size >::value)); +} + +// Tests comparing a tuple with itself. +TEST(ComparisonTest, ComparesWithSelf) { + const tuple a(5, 'a', false); + + EXPECT_TRUE(a == a); + EXPECT_FALSE(a != a); +} + +// Tests comparing two tuples with the same value. +TEST(ComparisonTest, ComparesEqualTuples) { + const tuple a(5, true), b(5, true); + + EXPECT_TRUE(a == b); + EXPECT_FALSE(a != b); +} + +// Tests comparing two different tuples that have no reference fields. +TEST(ComparisonTest, ComparesUnequalTuplesWithoutReferenceFields) { + typedef tuple FooTuple; + + const FooTuple a(0, 'x'); + const FooTuple b(1, 'a'); + + EXPECT_TRUE(a != b); + EXPECT_FALSE(a == b); + + const FooTuple c(1, 'b'); + + EXPECT_TRUE(b != c); + EXPECT_FALSE(b == c); +} + +// Tests comparing two different tuples that have reference fields. +TEST(ComparisonTest, ComparesUnequalTuplesWithReferenceFields) { + typedef tuple FooTuple; + + int i = 5; + const char ch = 'a'; + const FooTuple a(i, ch); + + int j = 6; + const FooTuple b(j, ch); + + EXPECT_TRUE(a != b); + EXPECT_FALSE(a == b); + + j = 5; + const char ch2 = 'b'; + const FooTuple c(j, ch2); + + EXPECT_TRUE(b != c); + EXPECT_FALSE(b == c); +} + +// Tests that a tuple field with a reference type is an alias of the +// variable it's supposed to reference. +TEST(ReferenceFieldTest, IsAliasOfReferencedVariable) { + int n = 0; + tuple t(true, n); + + n = 1; + EXPECT_EQ(n, get<1>(t)) + << "Changing a underlying variable should update the reference field."; + + // Makes sure that the implementation doesn't do anything funny with + // the & operator for the return type of get<>(). + EXPECT_EQ(&n, &(get<1>(t))) + << "The address of a reference field should equal the address of " + << "the underlying variable."; + + get<1>(t) = 2; + EXPECT_EQ(2, n) + << "Changing a reference field should update the underlying variable."; +} + +// Tests tuple's default constructor. +TEST(TupleConstructorTest, DefaultConstructor) { + // We are just testing that the following compiles. + tuple<> empty; + tuple one_field; + tuple three_fields; +} + +// Tests constructing a tuple from its fields. +TEST(TupleConstructorTest, ConstructsFromFields) { + int n = 1; + // Reference field. + tuple a(n); + EXPECT_EQ(&n, &(get<0>(a))); + + // Non-reference fields. + tuple b(5, 'a'); + EXPECT_EQ(5, get<0>(b)); + EXPECT_EQ('a', get<1>(b)); + + // Const reference field. + const int m = 2; + tuple c(true, m); + EXPECT_TRUE(get<0>(c)); + EXPECT_EQ(&m, &(get<1>(c))); +} + +// Tests tuple's copy constructor. +TEST(TupleConstructorTest, CopyConstructor) { + tuple a(0.0, true); + tuple b(a); + + EXPECT_DOUBLE_EQ(0.0, get<0>(b)); + EXPECT_TRUE(get<1>(b)); +} + +// Tests constructing a tuple from another tuple that has a compatible +// but different type. +TEST(TupleConstructorTest, ConstructsFromDifferentTupleType) { + tuple a(0, 1, 'a'); + tuple b(a); + + EXPECT_DOUBLE_EQ(0.0, get<0>(b)); + EXPECT_EQ(1, get<1>(b)); + EXPECT_EQ('a', get<2>(b)); +} + +// Tests constructing a 2-tuple from an std::pair. +TEST(TupleConstructorTest, ConstructsFromPair) { + ::std::pair a(1, 'a'); + tuple b(a); + tuple c(a); +} + +// Tests assigning a tuple to another tuple with the same type. +TEST(TupleAssignmentTest, AssignsToSameTupleType) { + const tuple a(5, 7L); + tuple b; + b = a; + EXPECT_EQ(5, get<0>(b)); + EXPECT_EQ(7L, get<1>(b)); +} + +// Tests assigning a tuple to another tuple with a different but +// compatible type. +TEST(TupleAssignmentTest, AssignsToDifferentTupleType) { + const tuple a(1, 7L, true); + tuple b; + b = a; + EXPECT_EQ(1L, get<0>(b)); + EXPECT_EQ(7, get<1>(b)); + EXPECT_TRUE(get<2>(b)); +} + +// Tests assigning an std::pair to a 2-tuple. +TEST(TupleAssignmentTest, AssignsFromPair) { + const ::std::pair a(5, true); + tuple b; + b = a; + EXPECT_EQ(5, get<0>(b)); + EXPECT_TRUE(get<1>(b)); + + tuple c; + c = a; + EXPECT_EQ(5L, get<0>(c)); + EXPECT_TRUE(get<1>(c)); +} + +// A fixture for testing big tuples. +class BigTupleTest : public testing::Test { + protected: + typedef tuple BigTuple; + + BigTupleTest() : + a_(1, 0, 0, 0, 0, 0, 0, 0, 0, 2), + b_(1, 0, 0, 0, 0, 0, 0, 0, 0, 3) {} + + BigTuple a_, b_; +}; + +// Tests constructing big tuples. +TEST_F(BigTupleTest, Construction) { + BigTuple a; + BigTuple b(b_); +} + +// Tests that get(t) returns the N-th (0-based) field of tuple t. +TEST_F(BigTupleTest, get) { + EXPECT_EQ(1, get<0>(a_)); + EXPECT_EQ(2, get<9>(a_)); + + // Tests that get() works on a const tuple too. + const BigTuple a(a_); + EXPECT_EQ(1, get<0>(a)); + EXPECT_EQ(2, get<9>(a)); +} + +// Tests comparing big tuples. +TEST_F(BigTupleTest, Comparisons) { + EXPECT_TRUE(a_ == a_); + EXPECT_FALSE(a_ != a_); + + EXPECT_TRUE(a_ != b_); + EXPECT_FALSE(a_ == b_); +} + +TEST(MakeTupleTest, WorksForScalarTypes) { + tuple a; + a = make_tuple(true, 5); + EXPECT_TRUE(get<0>(a)); + EXPECT_EQ(5, get<1>(a)); + + tuple b; + b = make_tuple('a', 'b', 5); + EXPECT_EQ('a', get<0>(b)); + EXPECT_EQ('b', get<1>(b)); + EXPECT_EQ(5, get<2>(b)); +} + +TEST(MakeTupleTest, WorksForPointers) { + int a[] = { 1, 2, 3, 4 }; + const char* const str = "hi"; + int* const p = a; + + tuple t; + t = make_tuple(str, p); + EXPECT_EQ(str, get<0>(t)); + EXPECT_EQ(p, get<1>(t)); +} + +} // namespace diff --git a/test/gtest_break_on_failure_unittest.py b/test/gtest_break_on_failure_unittest.py index cae288ad..218d3713 100755 --- a/test/gtest_break_on_failure_unittest.py +++ b/test/gtest_break_on_failure_unittest.py @@ -43,7 +43,6 @@ __author__ = 'wan@google.com (Zhanyong Wan)' import gtest_test_utils import os import sys -import unittest # Constants. @@ -94,7 +93,7 @@ def Run(command): # The tests. -class GTestBreakOnFailureUnitTest(unittest.TestCase): +class GTestBreakOnFailureUnitTest(gtest_test_utils.TestCase): """Tests using the GTEST_BREAK_ON_FAILURE environment variable or the --gtest_break_on_failure flag to turn assertion failures into segmentation faults. diff --git a/test/gtest_color_test.py b/test/gtest_color_test.py index 1b686304..f617dc5c 100755 --- a/test/gtest_color_test.py +++ b/test/gtest_color_test.py @@ -33,10 +33,9 @@ __author__ = 'wan@google.com (Zhanyong Wan)' -import gtest_test_utils import os -import sys -import unittest +import gtest_test_utils + IS_WINDOWS = os.name = 'nt' @@ -65,7 +64,7 @@ def UsesColor(term, color_env_var, color_flag): return gtest_test_utils.GetExitStatus(os.system(cmd)) -class GTestColorTest(unittest.TestCase): +class GTestColorTest(gtest_test_utils.TestCase): def testNoEnvVarNoFlag(self): """Tests the case when there's neither GTEST_COLOR nor --gtest_color.""" diff --git a/test/gtest_env_var_test.py b/test/gtest_env_var_test.py index 35e8041f..54719fac 100755 --- a/test/gtest_env_var_test.py +++ b/test/gtest_env_var_test.py @@ -33,13 +33,12 @@ __author__ = 'wan@google.com (Zhanyong Wan)' -import gtest_test_utils import os -import sys -import unittest +import gtest_test_utils + IS_WINDOWS = os.name == 'nt' -IS_LINUX = os.name == 'posix' +IS_LINUX = os.name == 'posix' and os.uname()[0] == 'Linux' COMMAND = gtest_test_utils.GetTestExecutablePath('gtest_env_var_test_') @@ -97,12 +96,13 @@ def TestEnvVarAffectsFlag(command): if IS_WINDOWS: TestFlag(command, 'catch_exceptions', '1', '0') + if IS_LINUX: - TestFlag(command, 'stack_trace_depth', '0', '100') TestFlag(command, 'death_test_use_fork', '1', '0') + TestFlag(command, 'stack_trace_depth', '0', '100') -class GTestEnvVarTest(unittest.TestCase): +class GTestEnvVarTest(gtest_test_utils.TestCase): def testEnvVarAffectsFlag(self): TestEnvVarAffectsFlag(COMMAND) diff --git a/test/gtest_filter_unittest.py b/test/gtest_filter_unittest.py index 6002fac9..4e9556b7 100755 --- a/test/gtest_filter_unittest.py +++ b/test/gtest_filter_unittest.py @@ -1,7 +1,6 @@ #!/usr/bin/env python # -# Copyright 2005, Google Inc. -# All rights reserved. +# 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 @@ -46,8 +45,6 @@ __author__ = 'wan@google.com (Zhanyong Wan)' import os import re import sets -import tempfile -import unittest import gtest_test_utils # Constants. @@ -133,9 +130,7 @@ def SetEnvVar(env_var, value): def Run(command): - """Runs a Google Test program and returns a list of full names of the - tests that were run along with the test exit code. - """ + """Runs a test program and returns its exit code and a list of tests run.""" stdout_file = os.popen(command, 'r') tests_run = [] @@ -169,9 +164,7 @@ def InvokeWithModifiedEnv(extra_env, function, *args, **kwargs): def RunWithSharding(total_shards, shard_index, command): - """Runs the Google Test program shard and returns a list of full names of the - tests that were run along with the exit code. - """ + """Runs a test program shard and returns exit code and a list of tests run.""" extra_env = {SHARD_INDEX_ENV_VAR: str(shard_index), TOTAL_SHARDS_ENV_VAR: str(total_shards)} @@ -180,10 +173,8 @@ def RunWithSharding(total_shards, shard_index, command): # The unit test. -class GTestFilterUnitTest(unittest.TestCase): - """Tests using the GTEST_FILTER environment variable or the - --gtest_filter flag to filter tests. - """ +class GTestFilterUnitTest(gtest_test_utils.TestCase): + """Tests GTEST_FILTER env variable or --gtest_filter flag to filter tests.""" # Utilities. @@ -206,9 +197,8 @@ class GTestFilterUnitTest(unittest.TestCase): self.assertEqual(sets.Set(set_var), sets.Set(full_partition)) def AdjustForParameterizedTests(self, tests_to_run): - """Adjust tests_to_run in case value parameterized tests are disabled - in the binary. - """ + """Adjust tests_to_run in case value parameterized tests are disabled.""" + global param_tests_present if not param_tests_present: return list(sets.Set(tests_to_run) - sets.Set(PARAM_TESTS)) @@ -216,9 +206,8 @@ class GTestFilterUnitTest(unittest.TestCase): return tests_to_run def RunAndVerify(self, gtest_filter, tests_to_run): - """Runs gtest_flag_unittest_ with the given filter, and verifies - that the right set of tests were run. - """ + """Checks that the binary runs correct set of tests for the given filter.""" + tests_to_run = self.AdjustForParameterizedTests(tests_to_run) # First, tests using GTEST_FILTER. @@ -248,11 +237,21 @@ class GTestFilterUnitTest(unittest.TestCase): def RunAndVerifyWithSharding(self, gtest_filter, total_shards, tests_to_run, command=COMMAND, check_exit_0=False): - """Runs all shards of gtest_flag_unittest_ with the given filter, and + """Checks that binary runs correct tests for the given filter and shard. + + Runs all shards of gtest_filter_unittest_ with the given filter, and verifies that the right set of tests were run. The union of tests run on each shard should be identical to tests_to_run, without duplicates. - If check_exit_0, make sure that all shards returned 0. + + Args: + gtest_filter: A filter to apply to the tests. + total_shards: A total number of shards to split test run into. + tests_to_run: A set of tests expected to run. + command: A command to invoke the test binary. + check_exit_0: When set to a true value, make sure that all shards + return 0. """ + tests_to_run = self.AdjustForParameterizedTests(tests_to_run) # Windows removes empty variables from the environment when passing it @@ -275,9 +274,16 @@ class GTestFilterUnitTest(unittest.TestCase): # pylint: enable-msg=C6403 def RunAndVerifyAllowingDisabled(self, gtest_filter, tests_to_run): - """Runs gtest_flag_unittest_ with the given filter, and enables + """Checks that the binary runs correct set of tests for the given filter. + + Runs gtest_filter_unittest_ with the given filter, and enables disabled tests. Verifies that the right set of tests were run. + + Args: + gtest_filter: A filter to apply to the tests. + tests_to_run: A set of tests expected to run. """ + tests_to_run = self.AdjustForParameterizedTests(tests_to_run) # Construct the command line. @@ -294,6 +300,7 @@ class GTestFilterUnitTest(unittest.TestCase): Determines whether value-parameterized tests are enabled in the binary and sets the flags accordingly. """ + global param_tests_present if param_tests_present is None: param_tests_present = PARAM_TEST_REGEX.search( @@ -305,9 +312,8 @@ class GTestFilterUnitTest(unittest.TestCase): self.RunAndVerify(None, ACTIVE_TESTS) def testDefaultBehaviorWithShards(self): - """Tests the behavior of not specifying the filter, with sharding - enabled. - """ + """Tests the behavior without the filter, with sharding enabled.""" + self.RunAndVerifyWithSharding(None, 1, ACTIVE_TESTS) self.RunAndVerifyWithSharding(None, 2, ACTIVE_TESTS) self.RunAndVerifyWithSharding(None, len(ACTIVE_TESTS) - 1, ACTIVE_TESTS) @@ -520,9 +526,7 @@ class GTestFilterUnitTest(unittest.TestCase): ]) def testFlagOverridesEnvVar(self): - """Tests that the --gtest_filter flag overrides the GTEST_FILTER - environment variable. - """ + """Tests that the filter flag overrides the filtering env. variable.""" SetEnvVar(FILTER_ENV_VAR, 'Foo*') command = '%s --%s=%s' % (COMMAND, FILTER_FLAG, '*One') @@ -534,8 +538,8 @@ class GTestFilterUnitTest(unittest.TestCase): def testShardStatusFileIsCreated(self): """Tests that the shard file is created if specified in the environment.""" - test_tmpdir = tempfile.mkdtemp() - shard_status_file = os.path.join(test_tmpdir, 'shard_status_file') + shard_status_file = os.path.join(gtest_test_utils.GetTempDir(), + 'shard_status_file') self.assert_(not os.path.exists(shard_status_file)) extra_env = {SHARD_STATUS_FILE_ENV_VAR: shard_status_file} @@ -546,13 +550,12 @@ class GTestFilterUnitTest(unittest.TestCase): stdout_file.close() self.assert_(os.path.exists(shard_status_file)) os.remove(shard_status_file) - os.removedirs(test_tmpdir) def testShardStatusFileIsCreatedWithListTests(self): """Tests that the shard file is created with --gtest_list_tests.""" - test_tmpdir = tempfile.mkdtemp() - shard_status_file = os.path.join(test_tmpdir, 'shard_status_file2') + shard_status_file = os.path.join(gtest_test_utils.GetTempDir(), + 'shard_status_file2') self.assert_(not os.path.exists(shard_status_file)) extra_env = {SHARD_STATUS_FILE_ENV_VAR: shard_status_file} @@ -564,7 +567,6 @@ class GTestFilterUnitTest(unittest.TestCase): stdout_file.close() self.assert_(os.path.exists(shard_status_file)) os.remove(shard_status_file) - os.removedirs(test_tmpdir) def testShardingWorksWithDeathTests(self): """Tests integration with death tests and sharding.""" diff --git a/test/gtest_help_test.py b/test/gtest_help_test.py index d81f149f..0a2a07b6 100755 --- a/test/gtest_help_test.py +++ b/test/gtest_help_test.py @@ -39,10 +39,9 @@ SYNOPSIS __author__ = 'wan@google.com (Zhanyong Wan)' -import gtest_test_utils import os import re -import unittest +import gtest_test_utils IS_WINDOWS = os.name == 'nt' @@ -83,7 +82,7 @@ def RunWithFlag(flag): return child.exit_code, child.output -class GTestHelpTest(unittest.TestCase): +class GTestHelpTest(gtest_test_utils.TestCase): """Tests the --help flag and its equivalent forms.""" def TestHelpFlag(self, flag): diff --git a/test/gtest_list_tests_unittest.py b/test/gtest_list_tests_unittest.py index 3d006dfe..7dca0b87 100755 --- a/test/gtest_list_tests_unittest.py +++ b/test/gtest_list_tests_unittest.py @@ -39,11 +39,8 @@ Google Test) the command line flags. __author__ = 'phanna@google.com (Patrick Hanna)' -import gtest_test_utils import os -import re -import sys -import unittest +import gtest_test_utils # Constants. @@ -105,7 +102,7 @@ def Run(command): # The unit test. -class GTestListTestsUnitTest(unittest.TestCase): +class GTestListTestsUnitTest(gtest_test_utils.TestCase): """Tests using the --gtest_list_tests flag to list all tests.""" def RunAndVerify(self, flag_value, expected_output, other_flag): diff --git a/test/gtest_nc_test.py b/test/gtest_nc_test.py index 6e77d708..06ffb3f8 100755 --- a/test/gtest_nc_test.py +++ b/test/gtest_nc_test.py @@ -38,6 +38,11 @@ import sys import unittest +IS_LINUX = os.name == 'posix' and os.uname()[0] == 'Linux' +if not IS_LINUX: + sys.exit(0) # Negative compilation tests are not supported on Windows & Mac. + + class GTestNCTest(unittest.TestCase): """Negative compilation test for Google Test.""" diff --git a/test/gtest_output_test.py b/test/gtest_output_test.py index 2751fa66..91cf9153 100755 --- a/test/gtest_output_test.py +++ b/test/gtest_output_test.py @@ -44,7 +44,6 @@ import os import re import string import sys -import unittest import gtest_test_utils @@ -84,11 +83,11 @@ def ToUnixLineEnding(s): return s.replace('\r\n', '\n').replace('\r', '\n') -def RemoveLocations(output): +def RemoveLocations(test_output): """Removes all file location info from a Google Test program's output. Args: - output: the output of a Google Test program. + test_output: the output of a Google Test program. Returns: output with all file location info (in the form of @@ -97,10 +96,10 @@ def RemoveLocations(output): 'FILE_NAME:#: '. """ - return re.sub(r'.*[/\\](.+)(\:\d+|\(\d+\))\: ', r'\1:#: ', output) + return re.sub(r'.*[/\\](.+)(\:\d+|\(\d+\))\: ', r'\1:#: ', test_output) -def RemoveStackTraces(output): +def RemoveStackTraceDetails(output): """Removes all stack traces from a Google Test program's output.""" # *? means "find the shortest string that matches". @@ -108,6 +107,13 @@ def RemoveStackTraces(output): 'Stack trace: (omitted)\n\n', output) +def RemoveStackTraces(output): + """Removes all traces of stack traces from a Google Test program's output.""" + + # *? means "find the shortest string that matches". + return re.sub(r'Stack trace:(.|\n)*?\n\n', '', output) + + def RemoveTime(output): """Removes all time information from a Google Test program's output.""" @@ -123,25 +129,28 @@ def RemoveTestCounts(output): '? FAILED TESTS', output) output = re.sub(r'\d+ tests from \d+ test cases', '? tests from ? test cases', output) + output = re.sub(r'\d+ tests from ([a-zA-Z_])', + r'? tests from \1', output) return re.sub(r'\d+ tests\.', '? tests.', output) def RemoveMatchingTests(test_output, pattern): - """Removes typed test information from a Google Test program's output. + """Removes output of specified tests from a Google Test program's output. - This function strips not only the beginning and the end of a test but also all - output in between. + This function strips not only the beginning and the end of a test but also + all output in between. Args: test_output: A string containing the test output. - pattern: A string that matches names of test cases to remove. + pattern: A regex string that matches names of test cases or + tests to remove. Returns: - Contents of test_output with removed test case whose names match pattern. + Contents of test_output with tests whose names match pattern removed. """ test_output = re.sub( - r'\[ RUN \] .*%s(.|\n)*?\[( FAILED | OK )\] .*%s.*\n' % ( + r'.*\[ RUN \] .*%s(.|\n)*?\[( FAILED | OK )\] .*%s.*\n' % ( pattern, pattern), '', test_output) @@ -153,7 +162,7 @@ def NormalizeOutput(output): output = ToUnixLineEnding(output) output = RemoveLocations(output) - output = RemoveStackTraces(output) + output = RemoveStackTraceDetails(output) output = RemoveTime(output) return output @@ -241,14 +250,28 @@ def GetOutputOfAllCommands(): test_list = GetShellCommandOutput(COMMAND_LIST_TESTS, '') SUPPORTS_DEATH_TESTS = 'DeathTest' in test_list SUPPORTS_TYPED_TESTS = 'TypedTest' in test_list +SUPPORTS_THREADS = 'ExpectFailureWithThreadsTest' in test_list +SUPPORTS_STACK_TRACES = False + +CAN_GENERATE_GOLDEN_FILE = SUPPORTS_DEATH_TESTS and SUPPORTS_TYPED_TESTS -class GTestOutputTest(unittest.TestCase): +class GTestOutputTest(gtest_test_utils.TestCase): def RemoveUnsupportedTests(self, test_output): if not SUPPORTS_DEATH_TESTS: test_output = RemoveMatchingTests(test_output, 'DeathTest') if not SUPPORTS_TYPED_TESTS: test_output = RemoveMatchingTests(test_output, 'TypedTest') + if not SUPPORTS_THREADS: + test_output = RemoveMatchingTests(test_output, + 'ExpectFailureWithThreadsTest') + test_output = RemoveMatchingTests(test_output, + 'ScopedFakeTestPartResultReporterTest') + test_output = RemoveMatchingTests(test_output, + 'WorksConcurrently') + if not SUPPORTS_STACK_TRACES: + test_output = RemoveStackTraces(test_output) + return test_output def testOutput(self): @@ -262,26 +285,48 @@ class GTestOutputTest(unittest.TestCase): golden = ToUnixLineEnding(golden_file.read()) golden_file.close() - # We want the test to pass regardless of death tests being + # We want the test to pass regardless of certain features being # supported or not. - if SUPPORTS_DEATH_TESTS and SUPPORTS_TYPED_TESTS: + if CAN_GENERATE_GOLDEN_FILE: self.assert_(golden == output) else: - self.assert_(RemoveTestCounts(self.RemoveUnsupportedTests(golden)) == - RemoveTestCounts(output)) + normalized_actual = RemoveTestCounts(output) + normalized_golden = RemoveTestCounts(self.RemoveUnsupportedTests(golden)) + + # This code is very handy when debugging test differences so I left it + # here, commented. + # open(os.path.join( + # gtest_test_utils.GetSourceDir(), + # '_gtest_output_test_normalized_actual.txt'), 'wb').write( + # normalized_actual) + # open(os.path.join( + # gtest_test_utils.GetSourceDir(), + # '_gtest_output_test_normalized_golden.txt'), 'wb').write( + # normalized_golden) + + self.assert_(normalized_golden == normalized_actual) if __name__ == '__main__': if sys.argv[1:] == [GENGOLDEN_FLAG]: - if SUPPORTS_DEATH_TESTS and SUPPORTS_TYPED_TESTS: + if CAN_GENERATE_GOLDEN_FILE: output = GetOutputOfAllCommands() golden_file = open(GOLDEN_PATH, 'wb') golden_file.write(output) golden_file.close() else: - print >> sys.stderr, ('Unable to write a golden file when compiled in an ' - 'environment that does not support death tests and ' - 'typed tests. Are you using VC 7.1?') + message = ( + """Unable to write a golden file when compiled in an environment +that does not support all the required features (death tests""") + if IS_WINDOWS: + message += ( + """\nand typed tests). Please check that you are using VC++ 8.0 SP1 +or higher as your compiler.""") + else: + message += """\nand typed tests). Please generate the golden file +using a binary built with those features enabled.""" + + sys.stderr.write(message) sys.exit(1) else: gtest_test_utils.Main() diff --git a/test/gtest_test_utils.py b/test/gtest_test_utils.py index 7dc8c421..45b25cd6 100755 --- a/test/gtest_test_utils.py +++ b/test/gtest_test_utils.py @@ -33,19 +33,32 @@ __author__ = 'wan@google.com (Zhanyong Wan)' +import atexit import os +import shutil import sys +import tempfile import unittest +_test_module = unittest +# Suppresses the 'Import not at the top of the file' lint complaint. +# pylint: disable-msg=C6204 try: import subprocess _SUBPROCESS_MODULE_AVAILABLE = True except: import popen2 _SUBPROCESS_MODULE_AVAILABLE = False +# pylint: enable-msg=C6204 + IS_WINDOWS = os.name == 'nt' +# Here we expose a class from a particular module, depending on the +# environment. The comment suppresses the 'Invalid variable name' lint +# complaint. +TestCase = _test_module.TestCase # pylint: disable-msg=C6409 + # Initially maps a flag to its default value. After # _ParseAndStripGTestFlags() is called, maps a flag to its actual value. _flag_map = {'gtest_source_dir': os.path.dirname(sys.argv[0]), @@ -56,7 +69,9 @@ _gtest_flags_are_parsed = False def _ParseAndStripGTestFlags(argv): """Parses and strips Google Test flags from argv. This is idempotent.""" - global _gtest_flags_are_parsed + # Suppresses the lint complaint about a global variable since we need it + # here to maintain module-wide state. + global _gtest_flags_are_parsed # pylint: disable-msg=W0603 if _gtest_flags_are_parsed: return @@ -103,6 +118,24 @@ def GetBuildDir(): return os.path.abspath(GetFlag('gtest_build_dir')) +_temp_dir = None + +def _RemoveTempDir(): + if _temp_dir: + shutil.rmtree(_temp_dir, ignore_errors=True) + +atexit.register(_RemoveTempDir) + + +def GetTempDir(): + """Returns a directory for temporary files.""" + + global _temp_dir + if not _temp_dir: + _temp_dir = tempfile.mkdtemp() + return _temp_dir + + def GetTestExecutablePath(executable_name): """Returns the absolute path of the test binary given its name. @@ -223,4 +256,4 @@ def Main(): # unittest.main(). Otherwise the latter will be confused by the # --gtest_* flags. _ParseAndStripGTestFlags(sys.argv) - unittest.main() + _test_module.main() diff --git a/test/gtest_throw_on_failure_test.py b/test/gtest_throw_on_failure_test.py index e952da5a..5678ffea 100755 --- a/test/gtest_throw_on_failure_test.py +++ b/test/gtest_throw_on_failure_test.py @@ -37,9 +37,8 @@ Google Test) with different environments and command line flags. __author__ = 'wan@google.com (Zhanyong Wan)' -import gtest_test_utils import os -import unittest +import gtest_test_utils # Constants. @@ -78,7 +77,7 @@ def Run(command): # The tests. TODO(wan@google.com): refactor the class to share common # logic with code in gtest_break_on_failure_unittest.py. -class ThrowOnFailureTest(unittest.TestCase): +class ThrowOnFailureTest(gtest_test_utils.TestCase): """Tests the throw-on-failure mode.""" def RunAndVerify(self, env_var_value, flag_value, should_fail): diff --git a/test/gtest_uninitialized_test.py b/test/gtest_uninitialized_test.py index 19b92e90..6ae57eee 100755 --- a/test/gtest_uninitialized_test.py +++ b/test/gtest_uninitialized_test.py @@ -34,8 +34,6 @@ __author__ = 'wan@google.com (Zhanyong Wan)' import gtest_test_utils -import sys -import unittest COMMAND = gtest_test_utils.GetTestExecutablePath('gtest_uninitialized_test_') @@ -63,7 +61,7 @@ def TestExitCodeAndOutput(command): Assert('InitGoogleTest' in p.output) -class GTestUninitializedTest(unittest.TestCase): +class GTestUninitializedTest(gtest_test_utils.TestCase): def testExitCodeAndOutput(self): TestExitCodeAndOutput(COMMAND) diff --git a/test/gtest_xml_outfiles_test.py b/test/gtest_xml_outfiles_test.py index 9d627932..0fe947f0 100755 --- a/test/gtest_xml_outfiles_test.py +++ b/test/gtest_xml_outfiles_test.py @@ -33,17 +33,14 @@ __author__ = "keith.ray@gmail.com (Keith Ray)" -import gtest_test_utils import os -import sys -import tempfile -import unittest - from xml.dom import minidom, Node +import gtest_test_utils import gtest_xml_test_utils +GTEST_OUTPUT_SUBDIR = "xml_outfiles" GTEST_OUTPUT_1_TEST = "gtest_xml_outfile1_test_" GTEST_OUTPUT_2_TEST = "gtest_xml_outfile2_test_" @@ -71,7 +68,8 @@ class GTestXMLOutFilesTest(gtest_xml_test_utils.GTestXMLTestCase): # We want the trailing '/' that the last "" provides in os.path.join, for # telling Google Test to create an output directory instead of a single file # for xml output. - self.output_dir_ = os.path.join(tempfile.mkdtemp(), "") + self.output_dir_ = os.path.join(gtest_test_utils.GetTempDir(), + GTEST_OUTPUT_SUBDIR, "") self.DeleteFilesAndDir() def tearDown(self): @@ -87,7 +85,7 @@ class GTestXMLOutFilesTest(gtest_xml_test_utils.GTestXMLTestCase): except os.error: pass try: - os.removedirs(self.output_dir_) + os.rmdir(self.output_dir_) except os.error: pass @@ -100,7 +98,8 @@ class GTestXMLOutFilesTest(gtest_xml_test_utils.GTestXMLTestCase): def _TestOutFile(self, test_name, expected_xml): gtest_prog_path = gtest_test_utils.GetTestExecutablePath(test_name) command = [gtest_prog_path, "--gtest_output=xml:%s" % self.output_dir_] - p = gtest_test_utils.Subprocess(command, working_dir=tempfile.mkdtemp()) + p = gtest_test_utils.Subprocess(command, + working_dir=gtest_test_utils.GetTempDir()) self.assert_(p.exited) self.assertEquals(0, p.exit_code) diff --git a/test/gtest_xml_output_unittest.py b/test/gtest_xml_output_unittest.py index 622251ea..a0cd4d09 100755 --- a/test/gtest_xml_output_unittest.py +++ b/test/gtest_xml_output_unittest.py @@ -34,19 +34,24 @@ __author__ = 'eefacm@gmail.com (Sean Mcafee)' import errno -import gtest_test_utils import os import sys -import tempfile -import unittest - from xml.dom import minidom, Node +import gtest_test_utils import gtest_xml_test_utils + GTEST_OUTPUT_FLAG = "--gtest_output" GTEST_DEFAULT_OUTPUT_FILE = "test_detail.xml" +SUPPORTS_STACK_TRACES = False + +if SUPPORTS_STACK_TRACES: + STACK_TRACE_TEMPLATE = "\nStack trace:\n*" +else: + STACK_TRACE_TEMPLATE = "" + EXPECTED_NON_EMPTY_XML = """ @@ -56,7 +61,7 @@ EXPECTED_NON_EMPTY_XML = """ +Expected: 1%(stack)s]]> @@ -64,10 +69,10 @@ Expected: 1]]> +Expected: 1%(stack)s]]> +Expected: 2%(stack)s]]> @@ -85,7 +90,7 @@ Expected: 2]]> -""" +""" % {'stack': STACK_TRACE_TEMPLATE} EXPECTED_EMPTY_XML = """ @@ -120,8 +125,8 @@ class GTestXMLOutputUnitTest(gtest_xml_test_utils.GTestXMLTestCase): Confirms that Google Test produces an XML output file with the expected default name if no name is explicitly specified. """ - temp_dir = tempfile.mkdtemp() - output_file = os.path.join(temp_dir, GTEST_DEFAULT_OUTPUT_FILE) + output_file = os.path.join(gtest_test_utils.GetTempDir(), + GTEST_DEFAULT_OUTPUT_FILE) gtest_prog_path = gtest_test_utils.GetTestExecutablePath( "gtest_no_test_unittest") try: @@ -132,7 +137,7 @@ class GTestXMLOutputUnitTest(gtest_xml_test_utils.GTestXMLTestCase): p = gtest_test_utils.Subprocess( [gtest_prog_path, "%s=xml" % GTEST_OUTPUT_FLAG], - working_dir=temp_dir) + working_dir=gtest_test_utils.GetTempDir()) self.assert_(p.exited) self.assertEquals(0, p.exit_code) self.assert_(os.path.isfile(output_file)) @@ -145,8 +150,8 @@ class GTestXMLOutputUnitTest(gtest_xml_test_utils.GTestXMLTestCase): XML document. Furthermore, the program's exit code must be expected_exit_code. """ - - xml_path = os.path.join(tempfile.mkdtemp(), gtest_prog_name + "out.xml") + xml_path = os.path.join(gtest_test_utils.GetTempDir(), + gtest_prog_name + "out.xml") gtest_prog_path = gtest_test_utils.GetTestExecutablePath(gtest_prog_name) command = [gtest_prog_path, "%s=xml:%s" % (GTEST_OUTPUT_FLAG, xml_path)] diff --git a/test/gtest_xml_test_utils.py b/test/gtest_xml_test_utils.py index 64eebb10..1811c408 100755 --- a/test/gtest_xml_test_utils.py +++ b/test/gtest_xml_test_utils.py @@ -34,14 +34,15 @@ __author__ = 'eefacm@gmail.com (Sean Mcafee)' import re -import unittest - from xml.dom import minidom, Node +import gtest_test_utils + + GTEST_OUTPUT_FLAG = "--gtest_output" GTEST_DEFAULT_OUTPUT_FILE = "test_detail.xml" -class GTestXMLTestCase(unittest.TestCase): +class GTestXMLTestCase(gtest_test_utils.TestCase): """ Base class for tests of Google Test's XML output functionality. """ diff --git a/test/run_tests_test.py b/test/run_tests_test.py index 1d9f3b77..b55739ea 100755 --- a/test/run_tests_test.py +++ b/test/run_tests_test.py @@ -48,6 +48,8 @@ class FakePath(object): self.tree = {} self.path_separator = os.sep + # known_paths contains either absolute or relative paths. Relative paths + # are absolutized with self.current_dir. if known_paths: self._AddPaths(known_paths) @@ -91,8 +93,11 @@ class FakePath(object): return tree + def normpath(self, path): + return os.path.normpath(path) + def abspath(self, path): - return os.path.normpath(os.path.join(self.current_dir, path)) + return self.normpath(os.path.join(self.current_dir, path)) def isfile(self, path): return self.PathElement(self.abspath(path)) == 1 @@ -157,7 +162,8 @@ class GetTestsToRunTest(unittest.TestCase): 'test/gtest_color_test.py'])) self.fake_configurations = ['dbg', 'opt'] self.test_runner = run_tests.TestRunner(injected_os=self.fake_os, - injected_subprocess=None) + injected_subprocess=None, + injected_script_dir='.') def testBinaryTestsOnly(self): """Exercises GetTestsToRun with parameters designating binary tests only.""" @@ -388,7 +394,8 @@ class GetTestsToRunTest(unittest.TestCase): 'scons/build/opt/scons/gtest_nontest.exe', 'test/'])) self.test_runner = run_tests.TestRunner(injected_os=self.fake_os, - injected_subprocess=None) + injected_subprocess=None, + injected_script_dir='.') self.AssertResultsEqual( self.test_runner.GetTestsToRun( [], @@ -397,6 +404,43 @@ class GetTestsToRunTest(unittest.TestCase): available_configurations=self.fake_configurations), ([], [])) + def testWorksFromDifferentDir(self): + """Exercises GetTestsToRun from a directory different from run_test.py's.""" + + # Here we simulate an test script in directory /d/ called from the + # directory /a/b/c/. + self.fake_os = FakeOs(FakePath( + current_dir=os.path.abspath('/a/b/c'), + known_paths=['/a/b/c/', + '/d/scons/build/dbg/scons/gtest_unittest', + '/d/scons/build/opt/scons/gtest_unittest', + '/d/test/gtest_color_test.py'])) + self.fake_configurations = ['dbg', 'opt'] + self.test_runner = run_tests.TestRunner(injected_os=self.fake_os, + injected_subprocess=None, + injected_script_dir='/d/') + # A binary test. + self.AssertResultsEqual( + self.test_runner.GetTestsToRun( + ['gtest_unittest'], + '', + False, + available_configurations=self.fake_configurations), + ([], + [('/d/scons/build/dbg/scons', + '/d/scons/build/dbg/scons/gtest_unittest')])) + + # A Python test. + self.AssertResultsEqual( + self.test_runner.GetTestsToRun( + ['gtest_color_test.py'], + '', + False, + available_configurations=self.fake_configurations), + ([('/d/scons/build/dbg/scons', '/d/test/gtest_color_test.py')], + [])) + + def testNonTestBinary(self): """Exercises GetTestsToRun with a non-test parameter.""" -- cgit v1.2.3 From ae3247986bbbafcc913b5fe6132090ad6f1c3f36 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Fri, 19 Jun 2009 00:24:28 +0000 Subject: Fixes broken gtest_unittest on Cygwin and cleans it up (by Vlad Losev); fixes the wrong usage of os.environ.clear() in gtest_output_test.py (by Vlad Losev); fixes the logic for detecting Symbian (by Zhanyong Wan); moves TestProperty for event listener (by Vlad Losev). --- test/gtest_output_test.py | 6 +++++- test/gtest_unittest.cc | 32 ++++++++++++-------------------- 2 files changed, 17 insertions(+), 21 deletions(-) (limited to 'test') diff --git a/test/gtest_output_test.py b/test/gtest_output_test.py index 91cf9153..c6ea0f8c 100755 --- a/test/gtest_output_test.py +++ b/test/gtest_output_test.py @@ -185,7 +185,11 @@ def IterShellCommandOutput(env_cmd, stdin_string=None): old_env_vars = dict(os.environ) os.environ.update(env_cmd[0]) stdin_file, stdout_file = os.popen2(env_cmd[1], 'b') - os.environ.clear() + # Changes made by os.environ.clear are not inheritable by child processes + # until Python 2.6. To produce inheritable changes we have to delete + # environment items with the del statement. + for key in os.environ.keys(): + del os.environ[key] os.environ.update(old_env_vars) # If the caller didn't specify a string for STDIN, gets it from the diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index 878aa23c..c6d5e0ee 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -64,6 +64,7 @@ TEST(CommandLineFlagsTest, CanBeAccessedInCodeOnceGTestHIsIncluded) { #include "src/gtest-internal-inl.h" #undef GTEST_IMPLEMENTATION_ +#include // For INT_MAX. #include #include @@ -71,15 +72,6 @@ TEST(CommandLineFlagsTest, CanBeAccessedInCodeOnceGTestHIsIncluded) { #include #endif // GTEST_HAS_PTHREAD -#if GTEST_OS_LINUX -#include -#include -#include -#include -#include -#include -#endif // GTEST_OS_LINUX - #ifdef __BORLANDC__ #include #endif @@ -784,7 +776,7 @@ TEST(StringTest, AnsiAndUtf16ConvertBasic) { EXPECT_STREQ("str", ansi); delete [] ansi; const WCHAR* utf16 = String::AnsiToUtf16("str"); - EXPECT_TRUE(wcsncmp(L"str", utf16, 3) == 0); + EXPECT_EQ(0, wcsncmp(L"str", utf16, 3)); delete [] utf16; } @@ -793,7 +785,7 @@ TEST(StringTest, AnsiAndUtf16ConvertPathChars) { EXPECT_STREQ(".:\\ \"*?", ansi); delete [] ansi; const WCHAR* utf16 = String::AnsiToUtf16(".:\\ \"*?"); - EXPECT_TRUE(wcsncmp(L".:\\ \"*?", utf16, 3) == 0); + EXPECT_EQ(0, wcsncmp(L".:\\ \"*?", utf16, 3)); delete [] utf16; } #endif // _WIN32_WCE @@ -3398,13 +3390,13 @@ TEST(AssertionSyntaxTest, BasicAssertionsBehavesLikeSingleStatement) { if (true) EXPECT_FALSE(false); else - ; + ; // NOLINT if (false) ASSERT_LT(1, 3); if (false) - ; + ; // NOLINT else EXPECT_GT(3, 2) << ""; } @@ -3431,7 +3423,7 @@ TEST(AssertionSyntaxTest, ExceptionAssertionsBehavesLikeSingleStatement) { if (true) EXPECT_THROW(ThrowAnInteger(), int); else - ; + ; // NOLINT if (false) EXPECT_NO_THROW(ThrowAnInteger()); @@ -3439,7 +3431,7 @@ TEST(AssertionSyntaxTest, ExceptionAssertionsBehavesLikeSingleStatement) { if (true) EXPECT_NO_THROW(ThrowNothing()); else - ; + ; // NOLINT if (false) EXPECT_ANY_THROW(ThrowNothing()); @@ -3447,7 +3439,7 @@ TEST(AssertionSyntaxTest, ExceptionAssertionsBehavesLikeSingleStatement) { if (true) EXPECT_ANY_THROW(ThrowAnInteger()); else - ; + ; // NOLINT } #endif // GTEST_HAS_EXCEPTIONS @@ -3456,20 +3448,20 @@ TEST(AssertionSyntaxTest, NoFatalFailureAssertionsBehavesLikeSingleStatement) { EXPECT_NO_FATAL_FAILURE(FAIL()) << "This should never be executed. " << "It's a compilation test only."; else - ; + ; // NOLINT if (false) ASSERT_NO_FATAL_FAILURE(FAIL()) << ""; else - ; + ; // NOLINT if (true) EXPECT_NO_FATAL_FAILURE(SUCCEED()); else - ; + ; // NOLINT if (false) - ; + ; // NOLINT else ASSERT_NO_FATAL_FAILURE(SUCCEED()); } -- cgit v1.2.3 From 4853a503371f39aa22e14adcdecea71c09841e34 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Fri, 19 Jun 2009 17:23:54 +0000 Subject: Fixes compatibility with Windows CE and Symbian (By Tim Baverstock and Mika). --- test/gtest-filepath_test.cc | 3 +++ test/gtest_unittest.cc | 6 ++++++ 2 files changed, 9 insertions(+) (limited to 'test') diff --git a/test/gtest-filepath_test.cc b/test/gtest-filepath_test.cc index b6d950dd..adf97467 100644 --- a/test/gtest-filepath_test.cc +++ b/test/gtest-filepath_test.cc @@ -61,6 +61,9 @@ namespace internal { namespace { #ifdef _WIN32_WCE +// TODO(wan@google.com): Move these to the POSIX adapter section in +// gtest-port.h. + // Windows CE doesn't have the remove C function. int remove(const char* path) { LPCWSTR wpath = String::AnsiToUtf16(path); diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index c6d5e0ee..fe452f42 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -1446,6 +1446,8 @@ TEST(ParseInt32FlagTest, ParsesAndReturnsValidValue) { // Tests that Int32FromEnvOrDie() parses the value of the var or // returns the correct default. +// Environment variables are not supported on Windows CE. +#ifndef _WIN32_WCE TEST(Int32FromEnvOrDieTest, ParsesAndReturnsValidValue) { EXPECT_EQ(333, Int32FromEnvOrDie(GTEST_FLAG_PREFIX_UPPER_ "UnsetVar", 333)); SetEnv(GTEST_FLAG_PREFIX_UPPER_ "UnsetVar", "123"); @@ -1453,6 +1455,7 @@ TEST(Int32FromEnvOrDieTest, ParsesAndReturnsValidValue) { SetEnv(GTEST_FLAG_PREFIX_UPPER_ "UnsetVar", "-123"); EXPECT_EQ(-123, Int32FromEnvOrDie(GTEST_FLAG_PREFIX_UPPER_ "UnsetVar", 333)); } +#endif // _WIN32_WCE #if GTEST_HAS_DEATH_TEST @@ -1521,6 +1524,8 @@ TEST_F(ShouldShardTest, ReturnsFalseWhenTotalShardIsOne) { // Tests that sharding is enabled if total_shards > 1 and // we are not in a death test subprocess. +// Environment variables are not supported on Windows CE. +#ifndef _WIN32_WCE TEST_F(ShouldShardTest, WorksWhenShardEnvVarsAreValid) { SetEnv(index_var_, "4"); SetEnv(total_var_, "22"); @@ -1537,6 +1542,7 @@ TEST_F(ShouldShardTest, WorksWhenShardEnvVarsAreValid) { EXPECT_TRUE(ShouldShard(total_var_, index_var_, false)); EXPECT_FALSE(ShouldShard(total_var_, index_var_, true)); } +#endif // _WIN32_WCE #if GTEST_HAS_DEATH_TEST -- cgit v1.2.3 From 046efb852bef27fe2a22dc632fdaeb909d5b0086 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Fri, 19 Jun 2009 21:23:56 +0000 Subject: Fixes the broken run_tests_test (by Vlad Losev). --- test/gtest_test_utils.py | 3 +- test/run_tests_test.py | 80 ++++++++++++++++++++++++++++++++++++------------ 2 files changed, 63 insertions(+), 20 deletions(-) (limited to 'test') diff --git a/test/gtest_test_utils.py b/test/gtest_test_utils.py index 45b25cd6..5b28fe49 100755 --- a/test/gtest_test_utils.py +++ b/test/gtest_test_utils.py @@ -53,6 +53,7 @@ except: IS_WINDOWS = os.name == 'nt' +IS_CYGWIN = os.name == 'posix' and 'CYGWIN' in os.uname()[0] # Here we expose a class from a particular module, depending on the # environment. The comment suppresses the 'Invalid variable name' lint @@ -150,7 +151,7 @@ def GetTestExecutablePath(executable_name): """ path = os.path.abspath(os.path.join(GetBuildDir(), executable_name)) - if IS_WINDOWS and not path.endswith('.exe'): + if (IS_WINDOWS or IS_CYGWIN) and not path.endswith('.exe'): path += '.exe' if not os.path.exists(path): diff --git a/test/run_tests_test.py b/test/run_tests_test.py index b55739ea..d8bbc362 100755 --- a/test/run_tests_test.py +++ b/test/run_tests_test.py @@ -33,12 +33,22 @@ __author__ = 'vladl@google.com (Vlad Losev)' import os +import re +import sets import sys import unittest sys.path.append(os.path.join(os.path.dirname(sys.argv[0]), os.pardir)) import run_tests +def AddExeExtension(path): + """Appends .exe to the path on Windows or Cygwin.""" + + if run_tests.IS_WINDOWS or run_tests.IS_CYGWIN: + return path + '.exe' + else: + return path + class FakePath(object): """A fake os.path module for testing.""" @@ -137,28 +147,43 @@ class FakeOs(object): class GetTestsToRunTest(unittest.TestCase): """Exercises TestRunner.GetTestsToRun.""" - def AssertResultsEqual(self, results, expected): - """Asserts results returned by GetTestsToRun equal to expected results.""" + def NormalizeGetTestsToRunResults(self, results): + """Normalizes path data returned from GetTestsToRun for comparison.""" + + def NormalizePythonTestPair(pair): + """Normalizes path data in the (directory, python_script) pair.""" + + return (os.path.normpath(pair[0]), os.path.normpath(pair[1])) - def NormalizeResultPaths(paths): - """Normalizes values returned by GetTestsToRun for comparison.""" + def NormalizeBinaryTestPair(pair): + """Normalizes path data in the (directory, binary_executable) pair.""" - def NormalizeResultPair(pair): - return (os.path.normpath(pair[0]), os.path.normpath(pair[1])) + directory, executable = map(os.path.normpath, pair) - return (sorted(map(NormalizeResultPair, paths[0])), - sorted(map(NormalizeResultPair, paths[1]))) + # On Windows and Cygwin, the test file names have the .exe extension, but + # they can be invoked either by name or by name+extension. Our test must + # accommodate both situations. + if run_tests.IS_WINDOWS or run_tests.IS_CYGWIN: + executable = re.sub(r'\.exe$', '', executable) + return (directory, executable) - self.assertEqual(NormalizeResultPaths(results), - NormalizeResultPaths(expected), - 'Incorrect set of tests %s returned vs %s expected' % + python_tests = sets.Set(map(NormalizePythonTestPair, results[0])) + binary_tests = sets.Set(map(NormalizeBinaryTestPair, results[1])) + return (python_tests, binary_tests) + + def AssertResultsEqual(self, results, expected): + """Asserts results returned by GetTestsToRun equal to expected results.""" + + self.assertEqual(self.NormalizeGetTestsToRunResults(results), + self.NormalizeGetTestsToRunResults(expected), + 'Incorrect set of tests returned:\n%s\nexpected:\n%s' % (results, expected)) def setUp(self): self.fake_os = FakeOs(FakePath( current_dir=os.path.abspath(os.path.dirname(run_tests.__file__)), - known_paths=['scons/build/dbg/scons/gtest_unittest', - 'scons/build/opt/scons/gtest_unittest', + known_paths=[AddExeExtension('scons/build/dbg/scons/gtest_unittest'), + AddExeExtension('scons/build/opt/scons/gtest_unittest'), 'test/gtest_color_test.py'])) self.fake_configurations = ['dbg', 'opt'] self.test_runner = run_tests.TestRunner(injected_os=self.fake_os, @@ -390,8 +415,7 @@ class GetTestsToRunTest(unittest.TestCase): self.fake_os = FakeOs(FakePath( current_dir=os.path.abspath(os.path.dirname(run_tests.__file__)), - known_paths=['scons/build/dbg/scons/gtest_nontest', - 'scons/build/opt/scons/gtest_nontest.exe', + known_paths=[AddExeExtension('scons/build/dbg/scons/gtest_nontest'), 'test/'])) self.test_runner = run_tests.TestRunner(injected_os=self.fake_os, injected_subprocess=None, @@ -412,8 +436,8 @@ class GetTestsToRunTest(unittest.TestCase): self.fake_os = FakeOs(FakePath( current_dir=os.path.abspath('/a/b/c'), known_paths=['/a/b/c/', - '/d/scons/build/dbg/scons/gtest_unittest', - '/d/scons/build/opt/scons/gtest_unittest', + AddExeExtension('/d/scons/build/dbg/scons/gtest_unittest'), + AddExeExtension('/d/scons/build/opt/scons/gtest_unittest'), '/d/test/gtest_color_test.py'])) self.fake_configurations = ['dbg', 'opt'] self.test_runner = run_tests.TestRunner(injected_os=self.fake_os, @@ -461,6 +485,24 @@ class GetTestsToRunTest(unittest.TestCase): False, available_configurations=self.fake_configurations)) + if run_tests.IS_WINDOWS or run_tests.IS_CYGWIN: + def testDoesNotPickNonExeFilesOnWindows(self): + """Verifies that GetTestsToRun does not find _test files on Windows.""" + + self.fake_os = FakeOs(FakePath( + current_dir=os.path.abspath(os.path.dirname(run_tests.__file__)), + known_paths=['scons/build/dbg/scons/gtest_test', 'test/'])) + self.test_runner = run_tests.TestRunner(injected_os=self.fake_os, + injected_subprocess=None, + injected_script_dir='.') + self.AssertResultsEqual( + self.test_runner.GetTestsToRun( + [], + '', + True, + available_configurations=self.fake_configurations), + ([], [])) + class RunTestsTest(unittest.TestCase): """Exercises TestRunner.RunTests.""" @@ -480,8 +522,8 @@ class RunTestsTest(unittest.TestCase): def setUp(self): self.fake_os = FakeOs(FakePath( current_dir=os.path.abspath(os.path.dirname(run_tests.__file__)), - known_paths=['scons/build/dbg/scons/gtest_unittest', - 'scons/build/opt/scons/gtest_unittest', + known_paths=[AddExeExtension('scons/build/dbg/scons/gtest_unittest'), + AddExeExtension('scons/build/opt/scons/gtest_unittest'), 'test/gtest_color_test.py'])) self.fake_configurations = ['dbg', 'opt'] self.test_runner = run_tests.TestRunner(injected_os=self.fake_os, -- cgit v1.2.3 From ef29ce3576240e51f289e49b2c4e156b414d6685 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Mon, 22 Jun 2009 23:29:24 +0000 Subject: Turns on exceptions when compiling gtest_output_test (by Vlad Losev); moves TestCase to gtest.h to prepare for the event listener API (by Vlad Losev). --- test/gtest_output_test_golden_win.txt | 42 +++++++++++++++++++++++++++++------ 1 file changed, 35 insertions(+), 7 deletions(-) (limited to 'test') diff --git a/test/gtest_output_test_golden_win.txt b/test/gtest_output_test_golden_win.txt index d8bb622b..92fe7f41 100644 --- a/test/gtest_output_test_golden_win.txt +++ b/test/gtest_output_test_golden_win.txt @@ -5,7 +5,7 @@ gtest_output_test_.cc:#: error: Value of: false Expected: true gtest_output_test_.cc:#: error: Value of: 3 Expected: 2 -[==========] Running 57 tests from 26 test cases. +[==========] Running 61 tests from 27 test cases. [----------] Global test environment set-up. FooEnvironment::SetUp() called. BarEnvironment::SetUp() called. @@ -186,7 +186,7 @@ Expected failure #2, in TearDown(). gtest_output_test_.cc:#: error: Failed Expected failure #3, in the test fixture d'tor. [ FAILED ] ExceptionInSetUpTest.ExceptionInSetUp -[----------] 1 test from ExceptionInTestFunctionTest +[----------] 2 tests from ExceptionInTestFunctionTest [ RUN ] ExceptionInTestFunctionTest.SEH (expecting 3 failures) unknown file: error: Exception thrown with code 0xc0000005 in the test body. @@ -195,6 +195,20 @@ Expected failure #2, in TearDown(). gtest_output_test_.cc:#: error: Failed Expected failure #3, in the test fixture d'tor. [ FAILED ] ExceptionInTestFunctionTest.SEH +[ RUN ] ExceptionInTestFunctionTest.CppException +unknown file: error: Exception thrown with code 0xe06d7363 in the test body. +gtest_output_test_.cc:#: error: Failed +Expected failure #2, in TearDown(). +gtest_output_test_.cc:#: error: Failed +Expected failure #3, in the test fixture d'tor. +[ FAILED ] ExceptionInTestFunctionTest.CppException +[----------] 1 test from ExceptionInTearDownTest +[ RUN ] ExceptionInTearDownTest.ExceptionInTearDown +(expecting 2 failures) +unknown file: error: Exception thrown with code 0xe06d7363 in TearDown(). +gtest_output_test_.cc:#: error: Failed +Expected failure #2, in the test fixture d'tor. +[ FAILED ] ExceptionInTearDownTest.ExceptionInTearDown [----------] 4 tests from MixedUpTestCaseTest [ RUN ] MixedUpTestCaseTest.FirstTestFromNamespaceFoo [ OK ] MixedUpTestCaseTest.FirstTestFromNamespaceFoo @@ -259,7 +273,7 @@ test DefinedUsingTEST is defined using TEST. You probably want to change the TEST to TEST_F or move it to another test case. [ FAILED ] TEST_before_TEST_F_in_same_test_case.DefinedUsingTEST_FAndShouldFail -[----------] 7 tests from ExpectNonfatalFailureTest +[----------] 8 tests from ExpectNonfatalFailureTest [ RUN ] ExpectNonfatalFailureTest.CanReferenceGlobalVariables [ OK ] ExpectNonfatalFailureTest.CanReferenceGlobalVariables [ RUN ] ExpectNonfatalFailureTest.CanReferenceLocalVariables @@ -298,7 +312,12 @@ Expected fatal failure. gtest.cc:#: error: Expected: 1 non-fatal failure Actual: 0 failures [ FAILED ] ExpectNonfatalFailureTest.FailsWhenStatementReturns -[----------] 7 tests from ExpectFatalFailureTest +[ RUN ] ExpectNonfatalFailureTest.FailsWhenStatementThrows +(expecting a failure) +gtest.cc:#: error: Expected: 1 non-fatal failure + Actual: 0 failures +[ FAILED ] ExpectNonfatalFailureTest.FailsWhenStatementThrows +[----------] 8 tests from ExpectFatalFailureTest [ RUN ] ExpectFatalFailureTest.CanReferenceGlobalVariables [ OK ] ExpectFatalFailureTest.CanReferenceGlobalVariables [ RUN ] ExpectFatalFailureTest.CanReferenceLocalStaticVariables @@ -337,6 +356,11 @@ Expected non-fatal failure. gtest.cc:#: error: Expected: 1 fatal failure Actual: 0 failures [ FAILED ] ExpectFatalFailureTest.FailsWhenStatementReturns +[ RUN ] ExpectFatalFailureTest.FailsWhenStatementThrows +(expecting a failure) +gtest.cc:#: error: Expected: 1 fatal failure + Actual: 0 failures +[ FAILED ] ExpectFatalFailureTest.FailsWhenStatementThrows [----------] 2 tests from TypedTest/0, where TypeParam = int [ RUN ] TypedTest/0.Success [ OK ] TypedTest/0.Success @@ -460,9 +484,9 @@ Expected non-fatal failure. FooEnvironment::TearDown() called. gtest_output_test_.cc:#: error: Failed Expected fatal failure. -[==========] 57 tests from 26 test cases ran. +[==========] 61 tests from 27 test cases ran. [ PASSED ] 21 tests. -[ FAILED ] 36 tests, listed below: +[ FAILED ] 40 tests, listed below: [ FAILED ] FatalFailureTest.FatalFailureInSubroutine [ FAILED ] FatalFailureTest.FatalFailureInNestedSubroutine [ FAILED ] FatalFailureTest.NonfatalFailureInSubroutine @@ -479,6 +503,8 @@ Expected fatal failure. [ FAILED ] ExceptionInFixtureCtorTest.ExceptionInFixtureCtor [ FAILED ] ExceptionInSetUpTest.ExceptionInSetUp [ FAILED ] ExceptionInTestFunctionTest.SEH +[ FAILED ] ExceptionInTestFunctionTest.CppException +[ FAILED ] ExceptionInTearDownTest.ExceptionInTearDown [ FAILED ] MixedUpTestCaseTest.ThisShouldFail [ FAILED ] MixedUpTestCaseTest.ThisShouldFailToo [ FAILED ] MixedUpTestCaseWithSameTestNameTest.TheSecondTestWithThisNameShouldFail @@ -488,10 +514,12 @@ Expected fatal failure. [ FAILED ] ExpectNonfatalFailureTest.FailsWhenThereAreTwoNonfatalFailures [ FAILED ] ExpectNonfatalFailureTest.FailsWhenThereIsOneFatalFailure [ FAILED ] ExpectNonfatalFailureTest.FailsWhenStatementReturns +[ FAILED ] ExpectNonfatalFailureTest.FailsWhenStatementThrows [ FAILED ] ExpectFatalFailureTest.FailsWhenThereIsNoFatalFailure [ FAILED ] ExpectFatalFailureTest.FailsWhenThereAreTwoFatalFailures [ FAILED ] ExpectFatalFailureTest.FailsWhenThereIsOneNonfatalFailure [ FAILED ] ExpectFatalFailureTest.FailsWhenStatementReturns +[ FAILED ] ExpectFatalFailureTest.FailsWhenStatementThrows [ FAILED ] TypedTest/0.Failure, where TypeParam = int [ FAILED ] Unsigned/TypedTestP/0.Failure, where TypeParam = unsigned char [ FAILED ] Unsigned/TypedTestP/1.Failure, where TypeParam = unsigned int @@ -500,7 +528,7 @@ Expected fatal failure. [ FAILED ] ExpectFailureTest.ExpectFatalFailureOnAllThreads [ FAILED ] ExpectFailureTest.ExpectNonFatalFailureOnAllThreads -36 FAILED TESTS +40 FAILED TESTS YOU HAVE 1 DISABLED TEST Note: Google Test filter = FatalFailureTest.*:LoggingTest.* -- cgit v1.2.3 From e6095deec89dcf5237948b3460d84a137622f16c Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Wed, 24 Jun 2009 23:02:50 +0000 Subject: Makes gtest's tuple implementation work with Symbian 5th edition by bypassing 2 compiler bugs (by Zhanyong Wan); refactors for the event listener API (by Vlad Losev). --- test/gtest_unittest.cc | 104 ++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 95 insertions(+), 9 deletions(-) (limited to 'test') diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index fe452f42..b1a161bb 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -148,7 +148,6 @@ using testing::internal::String; using testing::internal::TestProperty; using testing::internal::TestResult; using testing::internal::ThreadLocal; -using testing::internal::UnitTestImpl; using testing::internal::WideStringToUtf8; // This line tests that we can define tests in an unnamed namespace. @@ -526,6 +525,19 @@ TEST(ListTest, InsertAfterNotAtBeginning) { EXPECT_EQ(3, a.Last()->element()); } +// Tests the GetElement accessor. +TEST(ListTest, GetElement) { + List a; + a.PushBack(0); + a.PushBack(1); + a.PushBack(2); + + EXPECT_EQ(&(a.Head()->element()), a.GetElement(0)); + EXPECT_EQ(&(a.Head()->next()->element()), a.GetElement(1)); + EXPECT_EQ(&(a.Head()->next()->next()->element()), a.GetElement(2)); + EXPECT_TRUE(a.GetElement(3) == NULL); + EXPECT_TRUE(a.GetElement(-1) == NULL); +} // Tests the String class. @@ -1085,23 +1097,38 @@ class TestResultTest : public Test { delete r1; delete r2; } + + // Helper that compares two two TestPartResults. + static void CompareTestPartResult(const TestPartResult* expected, + const TestPartResult* actual) { + ASSERT_TRUE(actual != NULL); + EXPECT_EQ(expected->type(), actual->type()); + EXPECT_STREQ(expected->file_name(), actual->file_name()); + EXPECT_EQ(expected->line_number(), actual->line_number()); + EXPECT_STREQ(expected->summary(), actual->summary()); + EXPECT_STREQ(expected->message(), actual->message()); + EXPECT_EQ(expected->passed(), actual->passed()); + EXPECT_EQ(expected->failed(), actual->failed()); + EXPECT_EQ(expected->nonfatally_failed(), actual->nonfatally_failed()); + EXPECT_EQ(expected->fatally_failed(), actual->fatally_failed()); + } }; -// Tests TestResult::test_part_results() +// Tests TestResult::test_part_results(). TEST_F(TestResultTest, test_part_results) { ASSERT_EQ(0u, r0->test_part_results().size()); ASSERT_EQ(1u, r1->test_part_results().size()); ASSERT_EQ(2u, r2->test_part_results().size()); } -// Tests TestResult::successful_part_count() +// Tests TestResult::successful_part_count(). TEST_F(TestResultTest, successful_part_count) { ASSERT_EQ(0u, r0->successful_part_count()); ASSERT_EQ(1u, r1->successful_part_count()); ASSERT_EQ(1u, r2->successful_part_count()); } -// Tests TestResult::failed_part_count() +// Tests TestResult::failed_part_count(). TEST_F(TestResultTest, failed_part_count) { ASSERT_EQ(0u, r0->failed_part_count()); ASSERT_EQ(0u, r1->failed_part_count()); @@ -1115,27 +1142,35 @@ TEST_F(TestResultTest, GetFailedPartCount) { ASSERT_EQ(1u, GetFailedPartCount(r2)); } -// Tests TestResult::total_part_count() +// Tests TestResult::total_part_count(). TEST_F(TestResultTest, total_part_count) { ASSERT_EQ(0u, r0->total_part_count()); ASSERT_EQ(1u, r1->total_part_count()); ASSERT_EQ(2u, r2->total_part_count()); } -// Tests TestResult::Passed() +// Tests TestResult::Passed(). TEST_F(TestResultTest, Passed) { ASSERT_TRUE(r0->Passed()); ASSERT_TRUE(r1->Passed()); ASSERT_FALSE(r2->Passed()); } -// Tests TestResult::Failed() +// Tests TestResult::Failed(). TEST_F(TestResultTest, Failed) { ASSERT_FALSE(r0->Failed()); ASSERT_FALSE(r1->Failed()); ASSERT_TRUE(r2->Failed()); } +// Tests TestResult::GetTestPartResult(). +TEST_F(TestResultTest, GetTestPartResult) { + CompareTestPartResult(pr1, r2->GetTestPartResult(0)); + CompareTestPartResult(pr2, r2->GetTestPartResult(1)); + EXPECT_TRUE(r2->GetTestPartResult(2) == NULL); + EXPECT_TRUE(r2->GetTestPartResult(-1) == NULL); +} + // Tests TestResult::test_properties() has no properties when none are added. TEST(TestResultPropertyTest, NoPropertiesFoundWhenNoneAreAdded) { TestResult test_result; @@ -1195,6 +1230,49 @@ TEST(TestResultPropertyTest, OverridesValuesForDuplicateKeys) { EXPECT_STREQ("22", actual_property_2.value()); } +// Tests TestResult::test_property_count(). +TEST(TestResultPropertyTest, TestPropertyCount) { + TestResult test_result; + TestProperty property_1("key_1", "1"); + TestProperty property_2("key_2", "2"); + + ASSERT_EQ(0, test_result.test_property_count()); + test_result.RecordProperty(property_1); + ASSERT_EQ(1, test_result.test_property_count()); + test_result.RecordProperty(property_2); + ASSERT_EQ(2, test_result.test_property_count()); +} + +// Tests TestResult::GetTestProperty(). +TEST(TestResultPropertyTest, GetTestProperty) { + TestResult test_result; + TestProperty property_1("key_1", "1"); + TestProperty property_2("key_2", "2"); + TestProperty property_3("key_3", "3"); + test_result.RecordProperty(property_1); + test_result.RecordProperty(property_2); + test_result.RecordProperty(property_3); + + const TestProperty* fetched_property_1 = test_result.GetTestProperty(0); + const TestProperty* fetched_property_2 = test_result.GetTestProperty(1); + const TestProperty* fetched_property_3 = test_result.GetTestProperty(2); + + ASSERT_TRUE(fetched_property_1 != NULL); + EXPECT_STREQ("key_1", fetched_property_1->key()); + EXPECT_STREQ("1", fetched_property_1->value()); + + ASSERT_TRUE(fetched_property_2 != NULL); + EXPECT_STREQ("key_2", fetched_property_2->key()); + EXPECT_STREQ("2", fetched_property_2->value()); + + ASSERT_TRUE(fetched_property_3 != NULL); + EXPECT_STREQ("key_3", fetched_property_3->key()); + EXPECT_STREQ("3", fetched_property_3->value()); + + ASSERT_TRUE(test_result.GetTestProperty(3) == NULL); + ASSERT_TRUE(test_result.GetTestProperty(-1) == NULL); +} + // When a property using a reserved key is supplied to this function, it tests // that a non-fatal failure is added, a fatal failure is not added, and that the // property is not recorded. @@ -3061,6 +3139,10 @@ TEST(AssertionTest, ASSERT_EQ) { TEST(AssertionTest, ASSERT_EQ_NULL) { // A success. const char* p = NULL; + // Some older GCC versions may issue a spurious waring in this or the next + // assertion statement. This warning should not be suppressed with + // static_cast since the test verifies the ability to use bare NULL as the + // expected parameter to the macro. ASSERT_EQ(NULL, p); // A failure. @@ -3614,6 +3696,10 @@ TEST(ExpectTest, EXPECT_EQ_Double) { TEST(ExpectTest, EXPECT_EQ_NULL) { // A success. const char* p = NULL; + // Some older GCC versions may issue a spurious waring in this or the next + // assertion statement. This warning should not be suppressed with + // static_cast since the test verifies the ability to use bare NULL as the + // expected parameter to the macro. EXPECT_EQ(NULL, p); // A failure. @@ -5207,7 +5293,7 @@ class CurrentTestInfoTest : public Test { // There should be no tests running at this point. const TestInfo* test_info = UnitTest::GetInstance()->current_test_info(); - EXPECT_EQ(NULL, test_info) + EXPECT_TRUE(test_info == NULL) << "There should be no tests running at this point."; } @@ -5216,7 +5302,7 @@ class CurrentTestInfoTest : public Test { static void TearDownTestCase() { const TestInfo* test_info = UnitTest::GetInstance()->current_test_info(); - EXPECT_EQ(NULL, test_info) + EXPECT_TRUE(test_info == NULL) << "There should be no tests running at this point."; } }; -- cgit v1.2.3 From aaebfcdc4005afb22b68df61b58edd1ccc002913 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Thu, 25 Jun 2009 20:49:23 +0000 Subject: Refactors for the event listener API (by Vlad Losev): hides some methods in UnitTest; implements the result printers using the public API. --- test/gtest-death-test_test.cc | 21 ++++++++++----------- test/gtest_unittest.cc | 7 +++---- 2 files changed, 13 insertions(+), 15 deletions(-) (limited to 'test') diff --git a/test/gtest-death-test_test.cc b/test/gtest-death-test_test.cc index 9dd477b2..8b2173bf 100644 --- a/test/gtest-death-test_test.cc +++ b/test/gtest-death-test_test.cc @@ -67,6 +67,7 @@ using testing::internal::DeathTest; using testing::internal::DeathTestFactory; using testing::internal::FilePath; using testing::internal::GetLastErrnoDescription; +using testing::internal::GetUnitTestImpl; using testing::internal::ParseNaturalNumber; using testing::internal::String; @@ -77,22 +78,22 @@ namespace internal { // single UnitTest object during their lifetimes. class ReplaceDeathTestFactory { public: - ReplaceDeathTestFactory(UnitTest* parent, DeathTestFactory* new_factory) - : parent_impl_(parent->impl()) { - old_factory_ = parent_impl_->death_test_factory_.release(); - parent_impl_->death_test_factory_.reset(new_factory); + explicit ReplaceDeathTestFactory(DeathTestFactory* new_factory) + : unit_test_impl_(GetUnitTestImpl()) { + old_factory_ = unit_test_impl_->death_test_factory_.release(); + unit_test_impl_->death_test_factory_.reset(new_factory); } ~ReplaceDeathTestFactory() { - parent_impl_->death_test_factory_.release(); - parent_impl_->death_test_factory_.reset(old_factory_); + unit_test_impl_->death_test_factory_.release(); + unit_test_impl_->death_test_factory_.reset(old_factory_); } private: // Prevents copying ReplaceDeathTestFactory objects. ReplaceDeathTestFactory(const ReplaceDeathTestFactory&); void operator=(const ReplaceDeathTestFactory&); - UnitTestImpl* parent_impl_; + UnitTestImpl* unit_test_impl_; DeathTestFactory* old_factory_; }; @@ -846,8 +847,7 @@ class MacroLogicDeathTest : public testing::Test { static void SetUpTestCase() { factory_ = new MockDeathTestFactory; - replacer_ = new testing::internal::ReplaceDeathTestFactory( - testing::UnitTest::GetInstance(), factory_); + replacer_ = new testing::internal::ReplaceDeathTestFactory(factory_); } static void TearDownTestCase() { @@ -959,8 +959,7 @@ TEST_F(MacroLogicDeathTest, ChildDoesNotDie) { // Returns the number of successful parts in the current test. static size_t GetSuccessfulTestPartCount() { - return testing::UnitTest::GetInstance()->impl()->current_test_result()-> - successful_part_count(); + return GetUnitTestImpl()->current_test_result()->successful_part_count(); } // Tests that a successful death test does not register a successful diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index b1a161bb..4e430926 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -136,6 +136,7 @@ using testing::internal::GetCurrentOsStackTraceExceptTop; using testing::internal::GetFailedPartCount; using testing::internal::GetTestTypeId; using testing::internal::GetTypeId; +using testing::internal::GetUnitTestImpl; using testing::internal::GTestFlagSaver; using testing::internal::Int32; using testing::internal::Int32FromEnvOrDie; @@ -3600,8 +3601,7 @@ TEST(AssertionSyntaxTest, WorksWithConst) { // Returns the number of successful parts in the current test. static size_t GetSuccessfulPartCount() { - return UnitTest::GetInstance()->impl()->current_test_result()-> - successful_part_count(); + return GetUnitTestImpl()->current_test_result()->successful_part_count(); } namespace testing { @@ -4416,8 +4416,7 @@ namespace testing { class TestInfoTest : public Test { protected: static TestInfo * GetTestInfo(const char* test_name) { - return UnitTest::GetInstance()->impl()-> - GetTestCase("TestInfoTest", "", NULL, NULL)-> + return GetUnitTestImpl()->GetTestCase("TestInfoTest", "", NULL, NULL)-> GetTestInfo(test_name); } -- cgit v1.2.3 From b2db677c9905a34ca6454aa526f7a0cc5cfaeca1 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Wed, 1 Jul 2009 04:58:05 +0000 Subject: Reduces the flakiness of gtest-port_test on Mac; improves the Python tests; hides methods that we don't want to publish; makes win-dbg8 the default scons configuration (all by Vlad Losev). --- test/gtest-port_test.cc | 14 +++ test/gtest_color_test.py | 11 ++- test/gtest_env_var_test.py | 56 ++++++------ test/gtest_filter_unittest.py | 68 ++++++++------- test/gtest_list_tests_unittest.py | 39 ++++----- test/gtest_output_test.py | 85 ++++++------------ test/gtest_test_utils.py | 20 +++-- test/gtest_unittest.cc | 175 +++++++++++++++++++++----------------- 8 files changed, 238 insertions(+), 230 deletions(-) (limited to 'test') diff --git a/test/gtest-port_test.cc b/test/gtest-port_test.cc index f4560f19..37880a7f 100644 --- a/test/gtest-port_test.cc +++ b/test/gtest-port_test.cc @@ -35,6 +35,7 @@ #if GTEST_OS_MAC #include +#include #endif // GTEST_OS_MAC #include @@ -110,6 +111,19 @@ TEST(GetThreadCountTest, ReturnsCorrectValue) { void* dummy; ASSERT_EQ(0, pthread_join(thread_id, &dummy)); + + // MacOS X may not immediately report the updated thread count after + // joining a thread, causing flakiness in this test. To counter that, we + // wait for up to .5 seconds for the OS to report the correct value. + for (int i = 0; i < 5; ++i) { + if (GetThreadCount() == 1) + break; + + timespec time; + time.tv_sec = 0; + time.tv_nsec = 100L * 1000 * 1000; // .1 seconds. + nanosleep(&time, NULL); + } EXPECT_EQ(1, GetThreadCount()); pthread_mutex_destroy(&mutex); } diff --git a/test/gtest_color_test.py b/test/gtest_color_test.py index f617dc5c..cccf2d89 100755 --- a/test/gtest_color_test.py +++ b/test/gtest_color_test.py @@ -58,10 +58,13 @@ def UsesColor(term, color_env_var, color_flag): SetEnvVar('TERM', term) SetEnvVar(COLOR_ENV_VAR, color_env_var) - cmd = COMMAND - if color_flag is not None: - cmd += ' --%s=%s' % (COLOR_FLAG, color_flag) - return gtest_test_utils.GetExitStatus(os.system(cmd)) + + if color_flag is None: + args = [] + else: + args = ['--%s=%s' % (COLOR_FLAG, color_flag)] + p = gtest_test_utils.Subprocess([COMMAND] + args) + return not p.exited or p.exit_code class GTestColorTest(gtest_test_utils.TestCase): diff --git a/test/gtest_env_var_test.py b/test/gtest_env_var_test.py index 54719fac..19fd8103 100755 --- a/test/gtest_env_var_test.py +++ b/test/gtest_env_var_test.py @@ -59,52 +59,44 @@ def SetEnvVar(env_var, value): del os.environ[env_var] -def GetFlag(command, flag): +def GetFlag(flag): """Runs gtest_env_var_test_ and returns its output.""" - cmd = command + args = [COMMAND] if flag is not None: - cmd += ' %s' % (flag,) - stdin, stdout = os.popen2(cmd, 'b') - stdin.close() - line = stdout.readline() - stdout.close() - return line + args += [flag] + return gtest_test_utils.Subprocess(args).output -def TestFlag(command, flag, test_val, default_val): +def TestFlag(flag, test_val, default_val): """Verifies that the given flag is affected by the corresponding env var.""" env_var = 'GTEST_' + flag.upper() SetEnvVar(env_var, test_val) - AssertEq(test_val, GetFlag(command, flag)) + AssertEq(test_val, GetFlag(flag)) SetEnvVar(env_var, None) - AssertEq(default_val, GetFlag(command, flag)) - - -def TestEnvVarAffectsFlag(command): - """An environment variable should affect the corresponding flag.""" - - TestFlag(command, 'break_on_failure', '1', '0') - TestFlag(command, 'color', 'yes', 'auto') - TestFlag(command, 'filter', 'FooTest.Bar', '*') - TestFlag(command, 'output', 'tmp/foo.xml', '') - TestFlag(command, 'print_time', '0', '1') - TestFlag(command, 'repeat', '999', '1') - TestFlag(command, 'throw_on_failure', '1', '0') - TestFlag(command, 'death_test_style', 'threadsafe', 'fast') - - if IS_WINDOWS: - TestFlag(command, 'catch_exceptions', '1', '0') - - if IS_LINUX: - TestFlag(command, 'death_test_use_fork', '1', '0') - TestFlag(command, 'stack_trace_depth', '0', '100') + AssertEq(default_val, GetFlag(flag)) class GTestEnvVarTest(gtest_test_utils.TestCase): def testEnvVarAffectsFlag(self): - TestEnvVarAffectsFlag(COMMAND) + """Tests that environment variable should affect the corresponding flag.""" + + TestFlag('break_on_failure', '1', '0') + TestFlag('color', 'yes', 'auto') + TestFlag('filter', 'FooTest.Bar', '*') + TestFlag('output', 'tmp/foo.xml', '') + TestFlag('print_time', '0', '1') + TestFlag('repeat', '999', '1') + TestFlag('throw_on_failure', '1', '0') + TestFlag('death_test_style', 'threadsafe', 'fast') + + if IS_WINDOWS: + TestFlag('catch_exceptions', '1', '0') + + if IS_LINUX: + TestFlag('death_test_use_fork', '1', '0') + TestFlag('stack_trace_depth', '0', '100') if __name__ == '__main__': diff --git a/test/gtest_filter_unittest.py b/test/gtest_filter_unittest.py index 4e9556b7..a94a5210 100755 --- a/test/gtest_filter_unittest.py +++ b/test/gtest_filter_unittest.py @@ -129,14 +129,20 @@ def SetEnvVar(env_var, value): del os.environ[env_var] -def Run(command): - """Runs a test program and returns its exit code and a list of tests run.""" +def RunAndReturnOutput(args = None): + """Runs the test program and returns its output.""" - stdout_file = os.popen(command, 'r') + return gtest_test_utils.Subprocess([COMMAND] + (args or [])).output + + +def RunAndExtractTestList(args = None): + """Runs the test program and returns its exit code and a list of tests run.""" + + p = gtest_test_utils.Subprocess([COMMAND] + (args or [])) tests_run = [] test_case = '' test = '' - for line in stdout_file: + for line in p.output.split('\n'): match = TEST_CASE_REGEX.match(line) if match is not None: test_case = match.group(1) @@ -144,9 +150,8 @@ def Run(command): match = TEST_REGEX.match(line) if match is not None: test = match.group(1) - tests_run += [test_case + '.' + test] - exit_code = stdout_file.close() - return (tests_run, exit_code) + tests_run.append(test_case + '.' + test) + return (tests_run, p.exit_code) def InvokeWithModifiedEnv(extra_env, function, *args, **kwargs): @@ -168,7 +173,7 @@ def RunWithSharding(total_shards, shard_index, command): extra_env = {SHARD_INDEX_ENV_VAR: str(shard_index), TOTAL_SHARDS_ENV_VAR: str(total_shards)} - return InvokeWithModifiedEnv(extra_env, Run, command) + return InvokeWithModifiedEnv(extra_env, RunAndExtractTestList, command) # The unit test. @@ -220,7 +225,7 @@ class GTestFilterUnitTest(gtest_test_utils.TestCase): # pylint: disable-msg=C6403 if not IS_WINDOWS or gtest_filter != '': SetEnvVar(FILTER_ENV_VAR, gtest_filter) - tests_run = Run(COMMAND)[0] + tests_run = RunAndExtractTestList()[0] SetEnvVar(FILTER_ENV_VAR, None) self.AssertSetEqual(tests_run, tests_to_run) # pylint: enable-msg=C6403 @@ -228,15 +233,15 @@ class GTestFilterUnitTest(gtest_test_utils.TestCase): # Next, tests using --gtest_filter. if gtest_filter is None: - command = COMMAND + args = [] else: - command = '%s --%s=%s' % (COMMAND, FILTER_FLAG, gtest_filter) + args = ['--%s=%s' % (FILTER_FLAG, gtest_filter)] - tests_run = Run(command)[0] + tests_run = RunAndExtractTestList(args)[0] self.AssertSetEqual(tests_run, tests_to_run) def RunAndVerifyWithSharding(self, gtest_filter, total_shards, tests_to_run, - command=COMMAND, check_exit_0=False): + args=None, check_exit_0=False): """Checks that binary runs correct tests for the given filter and shard. Runs all shards of gtest_filter_unittest_ with the given filter, and @@ -247,7 +252,7 @@ class GTestFilterUnitTest(gtest_test_utils.TestCase): gtest_filter: A filter to apply to the tests. total_shards: A total number of shards to split test run into. tests_to_run: A set of tests expected to run. - command: A command to invoke the test binary. + args : Arguments to pass to the to the test binary. check_exit_0: When set to a true value, make sure that all shards return 0. """ @@ -264,9 +269,9 @@ class GTestFilterUnitTest(gtest_test_utils.TestCase): SetEnvVar(FILTER_ENV_VAR, gtest_filter) partition = [] for i in range(0, total_shards): - (tests_run, exit_code) = RunWithSharding(total_shards, i, command) + (tests_run, exit_code) = RunWithSharding(total_shards, i, args) if check_exit_0: - self.assert_(exit_code is None) + self.assertEqual(0, exit_code) partition.append(tests_run) self.AssertPartitionIsValid(tests_to_run, partition) @@ -287,11 +292,11 @@ class GTestFilterUnitTest(gtest_test_utils.TestCase): tests_to_run = self.AdjustForParameterizedTests(tests_to_run) # Construct the command line. - command = '%s --%s' % (COMMAND, ALSO_RUN_DISABED_TESTS_FLAG) + args = ['--%s' % ALSO_RUN_DISABED_TESTS_FLAG] if gtest_filter is not None: - command = '%s --%s=%s' % (command, FILTER_FLAG, gtest_filter) + args.append('--%s=%s' % (FILTER_FLAG, gtest_filter)) - tests_run = Run(command)[0] + tests_run = RunAndExtractTestList(args)[0] self.AssertSetEqual(tests_run, tests_to_run) def setUp(self): @@ -304,7 +309,7 @@ class GTestFilterUnitTest(gtest_test_utils.TestCase): global param_tests_present if param_tests_present is None: param_tests_present = PARAM_TEST_REGEX.search( - '\n'.join(os.popen(COMMAND, 'r').readlines())) is not None + RunAndReturnOutput()) is not None def testDefaultBehavior(self): """Tests the behavior of not specifying the filter.""" @@ -529,8 +534,8 @@ class GTestFilterUnitTest(gtest_test_utils.TestCase): """Tests that the filter flag overrides the filtering env. variable.""" SetEnvVar(FILTER_ENV_VAR, 'Foo*') - command = '%s --%s=%s' % (COMMAND, FILTER_FLAG, '*One') - tests_run = Run(command)[0] + args = ['--%s=%s' % (FILTER_FLAG, '*One')] + tests_run = RunAndExtractTestList(args)[0] SetEnvVar(FILTER_ENV_VAR, None) self.AssertSetEqual(tests_run, ['BarTest.TestOne', 'BazTest.TestOne']) @@ -543,11 +548,9 @@ class GTestFilterUnitTest(gtest_test_utils.TestCase): self.assert_(not os.path.exists(shard_status_file)) extra_env = {SHARD_STATUS_FILE_ENV_VAR: shard_status_file} - stdout_file = InvokeWithModifiedEnv(extra_env, os.popen, COMMAND, 'r') try: - stdout_file.readlines() + InvokeWithModifiedEnv(extra_env, RunAndReturnOutput) finally: - stdout_file.close() self.assert_(os.path.exists(shard_status_file)) os.remove(shard_status_file) @@ -559,12 +562,11 @@ class GTestFilterUnitTest(gtest_test_utils.TestCase): self.assert_(not os.path.exists(shard_status_file)) extra_env = {SHARD_STATUS_FILE_ENV_VAR: shard_status_file} - stdout_file = InvokeWithModifiedEnv(extra_env, os.popen, - '%s --gtest_list_tests' % COMMAND, 'r') try: - stdout_file.readlines() + InvokeWithModifiedEnv(extra_env, + RunAndReturnOutput, + ['--gtest_list_tests']) finally: - stdout_file.close() self.assert_(os.path.exists(shard_status_file)) os.remove(shard_status_file) @@ -581,12 +583,12 @@ class GTestFilterUnitTest(gtest_test_utils.TestCase): 'SeqP/ParamTest.TestY/1', ] - for command in (COMMAND + ' --gtest_death_test_style=threadsafe', - COMMAND + ' --gtest_death_test_style=fast'): + for flag in ['--gtest_death_test_style=threadsafe', + '--gtest_death_test_style=fast']: self.RunAndVerifyWithSharding(gtest_filter, 3, expected_tests, - check_exit_0=True, command=command) + check_exit_0=True, args=[flag]) self.RunAndVerifyWithSharding(gtest_filter, 5, expected_tests, - check_exit_0=True, command=command) + check_exit_0=True, args=[flag]) if __name__ == '__main__': gtest_test_utils.Main() diff --git a/test/gtest_list_tests_unittest.py b/test/gtest_list_tests_unittest.py index 7dca0b87..ce8c3ef0 100755 --- a/test/gtest_list_tests_unittest.py +++ b/test/gtest_list_tests_unittest.py @@ -39,7 +39,6 @@ Google Test) the command line flags. __author__ = 'phanna@google.com (Patrick Hanna)' -import os import gtest_test_utils @@ -89,15 +88,11 @@ FooTest. # Utilities. -def Run(command): - """Runs a command and returns the list of tests printed.""" +def Run(args): + """Runs gtest_list_tests_unittest_ and returns the list of tests printed.""" - stdout_file = os.popen(command, 'r') - - output = stdout_file.read() - - stdout_file.close() - return output + return gtest_test_utils.Subprocess([EXE_PATH] + args, + capture_stderr=False).output # The unit test. @@ -122,23 +117,23 @@ class GTestListTestsUnitTest(gtest_test_utils.TestCase): if flag_value is None: flag = '' - flag_expression = "not set" + flag_expression = 'not set' elif flag_value == '0': - flag = ' --%s=0' % LIST_TESTS_FLAG - flag_expression = "0" + flag = '--%s=0' % LIST_TESTS_FLAG + flag_expression = '0' else: - flag = ' --%s' % LIST_TESTS_FLAG - flag_expression = "1" + flag = '--%s' % LIST_TESTS_FLAG + flag_expression = '1' - command = EXE_PATH + flag + args = [flag] if other_flag is not None: - command += " " + other_flag + args += [other_flag] - output = Run(command) + output = Run(args) msg = ('when %s is %s, the output of "%s" is "%s".' % - (LIST_TESTS_FLAG, flag_expression, command, output)) + (LIST_TESTS_FLAG, flag_expression, ' '.join(args), output)) if expected_output is not None: self.assert_(output == expected_output, msg) @@ -165,17 +160,17 @@ class GTestListTestsUnitTest(gtest_test_utils.TestCase): def testOverrideNonFilterFlags(self): """Tests that --gtest_list_tests overrides the non-filter flags.""" - self.RunAndVerify(flag_value="1", + self.RunAndVerify(flag_value='1', expected_output=EXPECTED_OUTPUT_NO_FILTER, - other_flag="--gtest_break_on_failure") + other_flag='--gtest_break_on_failure') def testWithFilterFlags(self): """Tests that --gtest_list_tests takes into account the --gtest_filter flag.""" - self.RunAndVerify(flag_value="1", + self.RunAndVerify(flag_value='1', expected_output=EXPECTED_OUTPUT_FILTER_FOO, - other_flag="--gtest_filter=Foo*") + other_flag='--gtest_filter=Foo*') if __name__ == '__main__': diff --git a/test/gtest_output_test.py b/test/gtest_output_test.py index c6ea0f8c..c8a38f53 100755 --- a/test/gtest_output_test.py +++ b/test/gtest_output_test.py @@ -42,7 +42,6 @@ __author__ = 'wan@google.com (Zhanyong Wan)' import os import re -import string import sys import gtest_test_utils @@ -61,18 +60,22 @@ PROGRAM_PATH = gtest_test_utils.GetTestExecutablePath('gtest_output_test_') # At least one command we exercise must not have the # --gtest_internal_skip_environment_and_ad_hoc_tests flag. -COMMAND_LIST_TESTS = ({}, PROGRAM_PATH + ' --gtest_list_tests') -COMMAND_WITH_COLOR = ({}, PROGRAM_PATH + ' --gtest_color=yes') -COMMAND_WITH_TIME = ({}, PROGRAM_PATH + ' --gtest_print_time ' - '--gtest_internal_skip_environment_and_ad_hoc_tests ' - '--gtest_filter="FatalFailureTest.*:LoggingTest.*"') -COMMAND_WITH_DISABLED = ({}, PROGRAM_PATH + ' --gtest_also_run_disabled_tests ' - '--gtest_internal_skip_environment_and_ad_hoc_tests ' - '--gtest_filter="*DISABLED_*"') -COMMAND_WITH_SHARDING = ({'GTEST_SHARD_INDEX': '1', 'GTEST_TOTAL_SHARDS': '2'}, - PROGRAM_PATH + - ' --gtest_internal_skip_environment_and_ad_hoc_tests ' - ' --gtest_filter="PassingTest.*"') +COMMAND_LIST_TESTS = ({}, [PROGRAM_PATH, '--gtest_list_tests']) +COMMAND_WITH_COLOR = ({}, [PROGRAM_PATH, '--gtest_color=yes']) +COMMAND_WITH_TIME = ({}, [PROGRAM_PATH, + '--gtest_print_time', + '--gtest_internal_skip_environment_and_ad_hoc_tests', + '--gtest_filter=FatalFailureTest.*:LoggingTest.*']) +COMMAND_WITH_DISABLED = ( + {}, [PROGRAM_PATH, + '--gtest_also_run_disabled_tests', + '--gtest_internal_skip_environment_and_ad_hoc_tests', + '--gtest_filter=*DISABLED_*']) +COMMAND_WITH_SHARDING = ( + {'GTEST_SHARD_INDEX': '1', 'GTEST_TOTAL_SHARDS': '2'}, + [PROGRAM_PATH, + '--gtest_internal_skip_environment_and_ad_hoc_tests', + '--gtest_filter=PassingTest.*']) GOLDEN_PATH = os.path.join(gtest_test_utils.GetSourceDir(), GOLDEN_NAME) @@ -167,24 +170,24 @@ def NormalizeOutput(output): return output -def IterShellCommandOutput(env_cmd, stdin_string=None): - """Runs a command in a sub-process, and iterates the lines in its STDOUT. +def GetShellCommandOutput(env_cmd): + """Runs a command in a sub-process, and returns its output in a string. Args: + env_cmd: The shell command. A 2-tuple where element 0 is a dict of extra + environment variables to set, and element 1 is a string with + the command and any flags. - env_cmd: The shell command. A 2-tuple where element 0 is a dict - of extra environment variables to set, and element 1 - is a string with the command and any flags. - stdin_string: The string to be fed to the STDIN of the sub-process; - If None, the sub-process will inherit the STDIN - from the parent process. + Returns: + A string with the command's combined standard and diagnostic output. """ # Spawns cmd in a sub-process, and gets its standard I/O file objects. # Set and save the environment properly. old_env_vars = dict(os.environ) os.environ.update(env_cmd[0]) - stdin_file, stdout_file = os.popen2(env_cmd[1], 'b') + p = gtest_test_utils.Subprocess(env_cmd[1]) + # Changes made by os.environ.clear are not inheritable by child processes # until Python 2.6. To produce inheritable changes we have to delete # environment items with the del statement. @@ -192,39 +195,7 @@ def IterShellCommandOutput(env_cmd, stdin_string=None): del os.environ[key] os.environ.update(old_env_vars) - # If the caller didn't specify a string for STDIN, gets it from the - # parent process. - if stdin_string is None: - stdin_string = sys.stdin.read() - - # Feeds the STDIN string to the sub-process. - stdin_file.write(stdin_string) - stdin_file.close() - - while True: - line = stdout_file.readline() - if not line: # EOF - stdout_file.close() - break - - yield line - - -def GetShellCommandOutput(env_cmd, stdin_string=None): - """Runs a command in a sub-process, and returns its STDOUT in a string. - - Args: - - env_cmd: The shell command. A 2-tuple where element 0 is a dict - of extra environment variables to set, and element 1 - is a string with the command and any flags. - stdin_string: The string to be fed to the STDIN of the sub-process; - If None, the sub-process will inherit the STDIN - from the parent process. - """ - - lines = list(IterShellCommandOutput(env_cmd, stdin_string)) - return string.join(lines, '') + return p.output def GetCommandOutput(env_cmd): @@ -239,7 +210,7 @@ def GetCommandOutput(env_cmd): # Disables exception pop-ups on Windows. os.environ['GTEST_CATCH_EXCEPTIONS'] = '1' - return NormalizeOutput(GetShellCommandOutput(env_cmd, '')) + return NormalizeOutput(GetShellCommandOutput(env_cmd)) def GetOutputOfAllCommands(): @@ -251,7 +222,7 @@ def GetOutputOfAllCommands(): GetCommandOutput(COMMAND_WITH_SHARDING)) -test_list = GetShellCommandOutput(COMMAND_LIST_TESTS, '') +test_list = GetShellCommandOutput(COMMAND_LIST_TESTS) SUPPORTS_DEATH_TESTS = 'DeathTest' in test_list SUPPORTS_TYPED_TESTS = 'TypedTest' in test_list SUPPORTS_THREADS = 'ExpectFailureWithThreadsTest' in test_list diff --git a/test/gtest_test_utils.py b/test/gtest_test_utils.py index 5b28fe49..385662ad 100755 --- a/test/gtest_test_utils.py +++ b/test/gtest_test_utils.py @@ -190,7 +190,7 @@ def GetExitStatus(exit_code): class Subprocess: - def __init__(self, command, working_dir=None): + def __init__(self, command, working_dir=None, capture_stderr=True): """Changes into a specified directory, if provided, and executes a command. Restores the old directory afterwards. Execution results are returned via the following attributes: @@ -203,8 +203,10 @@ class Subprocess: combined in a string. Args: - command: A command to run, in the form of sys.argv. - working_dir: A directory to change into. + command: The command to run, in the form of sys.argv. + working_dir: The directory to change into. + capture_stderr: Determines whether to capture stderr in the output member + or to discard it. """ # The subprocess module is the preferrable way of running programs @@ -215,8 +217,13 @@ class Subprocess: # functionality (Popen4) under Windows. This allows us to support Mac # OS X 10.4 Tiger, which has python 2.3 installed. if _SUBPROCESS_MODULE_AVAILABLE: + if capture_stderr: + stderr = subprocess.STDOUT + else: + stderr = subprocess.PIPE + p = subprocess.Popen(command, - stdout=subprocess.PIPE, stderr=subprocess.STDOUT, + stdout=subprocess.PIPE, stderr=stderr, cwd=working_dir, universal_newlines=True) # communicate returns a tuple with the file obect for the child's # output. @@ -227,7 +234,10 @@ class Subprocess: try: if working_dir is not None: os.chdir(working_dir) - p = popen2.Popen4(command) + if capture_stderr: + p = popen2.Popen4(command) + else: + p = popen2.Popen3(command) p.tochild.close() self.output = p.fromchild.read() ret_code = p.wait() diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index 4e430926..bd9fa182 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -79,7 +79,29 @@ TEST(CommandLineFlagsTest, CanBeAccessedInCodeOnceGTestHIsIncluded) { namespace testing { namespace internal { const char* FormatTimeInMillisAsSeconds(TimeInMillis ms); + bool ParseInt32Flag(const char* str, const char* flag, Int32* value); + +// TestResult contains some private methods that should be hidden from +// Google Test user but are required for testing. This class allow our tests +// to access them. +class TestResultAccessor { + public: + static void RecordProperty(TestResult* test_result, + const TestProperty& property) { + test_result->RecordProperty(property); + } + + static void ClearTestPartResults(TestResult* test_result) { + test_result->ClearTestPartResults(); + } + + static const List& test_part_results( + const TestResult& test_result) { + return test_result.test_part_results(); + } +}; + } // namespace internal } // namespace testing @@ -128,7 +150,6 @@ using testing::TPRT_SUCCESS; using testing::UnitTest; using testing::internal::kTestTypeIdInGoogleTest; using testing::internal::AppendUserMessage; -using testing::internal::ClearCurrentTestPartResults; using testing::internal::CodePointToUtf8; using testing::internal::EqFailure; using testing::internal::FloatingPoint; @@ -146,14 +167,21 @@ using testing::internal::ShouldShard; using testing::internal::ShouldUseColor; using testing::internal::StreamableToString; using testing::internal::String; +using testing::internal::TestCase; using testing::internal::TestProperty; using testing::internal::TestResult; +using testing::internal::TestResultAccessor; using testing::internal::ThreadLocal; using testing::internal::WideStringToUtf8; // This line tests that we can define tests in an unnamed namespace. namespace { +static void ClearCurrentTestPartResults() { + TestResultAccessor::ClearTestPartResults( + GetUnitTestImpl()->current_test_result()); +} + // Tests GetTypeId. TEST(GetTypeIdTest, ReturnsSameValueForSameType) { @@ -1076,9 +1104,9 @@ class TestResultTest : public Test { // this is a hack). TPRList * list1, * list2; list1 = const_cast *>( - & r1->test_part_results()); + &TestResultAccessor::test_part_results(*r1)); list2 = const_cast *>( - & r2->test_part_results()); + &TestResultAccessor::test_part_results(*r2)); // r0 is an empty TestResult. @@ -1115,39 +1143,39 @@ class TestResultTest : public Test { } }; -// Tests TestResult::test_part_results(). +// Tests TestResult::total_part_count(). TEST_F(TestResultTest, test_part_results) { - ASSERT_EQ(0u, r0->test_part_results().size()); - ASSERT_EQ(1u, r1->test_part_results().size()); - ASSERT_EQ(2u, r2->test_part_results().size()); + ASSERT_EQ(0, r0->total_part_count()); + ASSERT_EQ(1, r1->total_part_count()); + ASSERT_EQ(2, r2->total_part_count()); } // Tests TestResult::successful_part_count(). TEST_F(TestResultTest, successful_part_count) { - ASSERT_EQ(0u, r0->successful_part_count()); - ASSERT_EQ(1u, r1->successful_part_count()); - ASSERT_EQ(1u, r2->successful_part_count()); + ASSERT_EQ(0, r0->successful_part_count()); + ASSERT_EQ(1, r1->successful_part_count()); + ASSERT_EQ(1, r2->successful_part_count()); } // Tests TestResult::failed_part_count(). TEST_F(TestResultTest, failed_part_count) { - ASSERT_EQ(0u, r0->failed_part_count()); - ASSERT_EQ(0u, r1->failed_part_count()); - ASSERT_EQ(1u, r2->failed_part_count()); + ASSERT_EQ(0, r0->failed_part_count()); + ASSERT_EQ(0, r1->failed_part_count()); + ASSERT_EQ(1, r2->failed_part_count()); } // Tests testing::internal::GetFailedPartCount(). TEST_F(TestResultTest, GetFailedPartCount) { - ASSERT_EQ(0u, GetFailedPartCount(r0)); - ASSERT_EQ(0u, GetFailedPartCount(r1)); - ASSERT_EQ(1u, GetFailedPartCount(r2)); + ASSERT_EQ(0, GetFailedPartCount(r0)); + ASSERT_EQ(0, GetFailedPartCount(r1)); + ASSERT_EQ(1, GetFailedPartCount(r2)); } // Tests TestResult::total_part_count(). TEST_F(TestResultTest, total_part_count) { - ASSERT_EQ(0u, r0->total_part_count()); - ASSERT_EQ(1u, r1->total_part_count()); - ASSERT_EQ(2u, r2->total_part_count()); + ASSERT_EQ(0, r0->total_part_count()); + ASSERT_EQ(1, r1->total_part_count()); + ASSERT_EQ(2, r2->total_part_count()); } // Tests TestResult::Passed(). @@ -1172,76 +1200,60 @@ TEST_F(TestResultTest, GetTestPartResult) { EXPECT_TRUE(r2->GetTestPartResult(-1) == NULL); } -// Tests TestResult::test_properties() has no properties when none are added. +// Tests TestResult has no properties when none are added. TEST(TestResultPropertyTest, NoPropertiesFoundWhenNoneAreAdded) { TestResult test_result; - ASSERT_EQ(0u, test_result.test_properties().size()); + ASSERT_EQ(0, test_result.test_property_count()); } -// Tests TestResult::test_properties() has the expected property when added. +// Tests TestResult has the expected property when added. TEST(TestResultPropertyTest, OnePropertyFoundWhenAdded) { TestResult test_result; TestProperty property("key_1", "1"); - test_result.RecordProperty(property); - const List& properties = test_result.test_properties(); - ASSERT_EQ(1u, properties.size()); - TestProperty actual_property = properties.Head()->element(); - EXPECT_STREQ("key_1", actual_property.key()); - EXPECT_STREQ("1", actual_property.value()); + TestResultAccessor::RecordProperty(&test_result, property); + ASSERT_EQ(1, test_result.test_property_count()); + const TestProperty* actual_property = test_result.GetTestProperty(0); + EXPECT_STREQ("key_1", actual_property->key()); + EXPECT_STREQ("1", actual_property->value()); } -// Tests TestResult::test_properties() has multiple properties when added. +// Tests TestResult has multiple properties when added. TEST(TestResultPropertyTest, MultiplePropertiesFoundWhenAdded) { TestResult test_result; TestProperty property_1("key_1", "1"); TestProperty property_2("key_2", "2"); - test_result.RecordProperty(property_1); - test_result.RecordProperty(property_2); - const List& properties = test_result.test_properties(); - ASSERT_EQ(2u, properties.size()); - TestProperty actual_property_1 = properties.Head()->element(); - EXPECT_STREQ("key_1", actual_property_1.key()); - EXPECT_STREQ("1", actual_property_1.value()); + TestResultAccessor::RecordProperty(&test_result, property_1); + TestResultAccessor::RecordProperty(&test_result, property_2); + ASSERT_EQ(2, test_result.test_property_count()); + const TestProperty* actual_property_1 = test_result.GetTestProperty(0); + EXPECT_STREQ("key_1", actual_property_1->key()); + EXPECT_STREQ("1", actual_property_1->value()); - TestProperty actual_property_2 = properties.Last()->element(); - EXPECT_STREQ("key_2", actual_property_2.key()); - EXPECT_STREQ("2", actual_property_2.value()); + const TestProperty* actual_property_2 = test_result.GetTestProperty(1); + EXPECT_STREQ("key_2", actual_property_2->key()); + EXPECT_STREQ("2", actual_property_2->value()); } -// Tests TestResult::test_properties() overrides values for duplicate keys. +// Tests TestResult::RecordProperty() overrides values for duplicate keys. TEST(TestResultPropertyTest, OverridesValuesForDuplicateKeys) { TestResult test_result; TestProperty property_1_1("key_1", "1"); TestProperty property_2_1("key_2", "2"); TestProperty property_1_2("key_1", "12"); TestProperty property_2_2("key_2", "22"); - test_result.RecordProperty(property_1_1); - test_result.RecordProperty(property_2_1); - test_result.RecordProperty(property_1_2); - test_result.RecordProperty(property_2_2); - - const List& properties = test_result.test_properties(); - ASSERT_EQ(2u, properties.size()); - TestProperty actual_property_1 = properties.Head()->element(); - EXPECT_STREQ("key_1", actual_property_1.key()); - EXPECT_STREQ("12", actual_property_1.value()); - - TestProperty actual_property_2 = properties.Last()->element(); - EXPECT_STREQ("key_2", actual_property_2.key()); - EXPECT_STREQ("22", actual_property_2.value()); -} - -// Tests TestResult::test_property_count(). -TEST(TestResultPropertyTest, TestPropertyCount) { - TestResult test_result; - TestProperty property_1("key_1", "1"); - TestProperty property_2("key_2", "2"); + TestResultAccessor::RecordProperty(&test_result, property_1_1); + TestResultAccessor::RecordProperty(&test_result, property_2_1); + TestResultAccessor::RecordProperty(&test_result, property_1_2); + TestResultAccessor::RecordProperty(&test_result, property_2_2); - ASSERT_EQ(0, test_result.test_property_count()); - test_result.RecordProperty(property_1); - ASSERT_EQ(1, test_result.test_property_count()); - test_result.RecordProperty(property_2); ASSERT_EQ(2, test_result.test_property_count()); + const TestProperty* actual_property_1 = test_result.GetTestProperty(0); + EXPECT_STREQ("key_1", actual_property_1->key()); + EXPECT_STREQ("12", actual_property_1->value()); + + const TestProperty* actual_property_2 = test_result.GetTestProperty(1); + EXPECT_STREQ("key_2", actual_property_2->key()); + EXPECT_STREQ("22", actual_property_2->value()); } // Tests TestResult::GetTestProperty(). @@ -1250,9 +1262,9 @@ TEST(TestResultPropertyTest, GetTestProperty) { TestProperty property_1("key_1", "1"); TestProperty property_2("key_2", "2"); TestProperty property_3("key_3", "3"); - test_result.RecordProperty(property_1); - test_result.RecordProperty(property_2); - test_result.RecordProperty(property_3); + TestResultAccessor::RecordProperty(&test_result, property_1); + TestResultAccessor::RecordProperty(&test_result, property_2); + TestResultAccessor::RecordProperty(&test_result, property_3); const TestProperty* fetched_property_1 = test_result.GetTestProperty(0); const TestProperty* fetched_property_2 = test_result.GetTestProperty(1); @@ -1280,8 +1292,10 @@ TEST(TestResultPropertyTest, GetTestProperty) { void ExpectNonFatalFailureRecordingPropertyWithReservedKey(const char* key) { TestResult test_result; TestProperty property(key, "1"); - EXPECT_NONFATAL_FAILURE(test_result.RecordProperty(property), "Reserved key"); - ASSERT_TRUE(test_result.test_properties().IsEmpty()) << "Not recorded"; + EXPECT_NONFATAL_FAILURE( + TestResultAccessor::RecordProperty(&test_result, property), + "Reserved key"); + ASSERT_EQ(0, test_result.test_property_count()) << "Not recorded"; } // Attempting to recording a property with the Reserved literal "name" @@ -4415,9 +4429,16 @@ namespace testing { class TestInfoTest : public Test { protected: - static TestInfo * GetTestInfo(const char* test_name) { - return GetUnitTestImpl()->GetTestCase("TestInfoTest", "", NULL, NULL)-> - GetTestInfo(test_name); + static const TestInfo* GetTestInfo(const char* test_name) { + const TestCase* const test_case = GetUnitTestImpl()-> + GetTestCase("TestInfoTest", "", NULL, NULL); + + for (int i = 0; i < test_case->total_test_count(); ++i) { + const TestInfo* const test_info = test_case->GetTestInfo(i); + if (strcmp(test_name, test_info->name()) == 0) + return test_info; + } + return NULL; } static const TestResult* GetTestResult( @@ -4428,7 +4449,7 @@ class TestInfoTest : public Test { // Tests TestInfo::test_case_name() and TestInfo::name(). TEST_F(TestInfoTest, Names) { - TestInfo * const test_info = GetTestInfo("Names"); + const TestInfo* const test_info = GetTestInfo("Names"); ASSERT_STREQ("TestInfoTest", test_info->test_case_name()); ASSERT_STREQ("Names", test_info->name()); @@ -4436,13 +4457,13 @@ TEST_F(TestInfoTest, Names) { // Tests TestInfo::result(). TEST_F(TestInfoTest, result) { - TestInfo * const test_info = GetTestInfo("result"); + const TestInfo* const test_info = GetTestInfo("result"); // Initially, there is no TestPartResult for this test. - ASSERT_EQ(0u, GetTestResult(test_info)->total_part_count()); + ASSERT_EQ(0, GetTestResult(test_info)->total_part_count()); // After the previous assertion, there is still none. - ASSERT_EQ(0u, GetTestResult(test_info)->total_part_count()); + ASSERT_EQ(0, GetTestResult(test_info)->total_part_count()); } // Tests setting up and tearing down a test case. -- cgit v1.2.3 From 600105ee3ac48a01143486e5536a5b8fff5b5b25 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Wed, 1 Jul 2009 22:55:05 +0000 Subject: Makes List a random-access data structure. This simplifies the implementation and makes it easier to implement test shuffling. --- test/gtest_stress_test.cc | 8 +- test/gtest_unittest.cc | 310 +++++++++++++++++++++++++++------------------- 2 files changed, 186 insertions(+), 132 deletions(-) (limited to 'test') diff --git a/test/gtest_stress_test.cc b/test/gtest_stress_test.cc index 55e8bf42..3e021318 100644 --- a/test/gtest_stress_test.cc +++ b/test/gtest_stress_test.cc @@ -46,7 +46,6 @@ namespace testing { namespace { using internal::List; -using internal::ListNode; using internal::String; using internal::TestProperty; using internal::TestPropertyKeyIs; @@ -70,9 +69,10 @@ void ExpectKeyAndValueWereRecordedForId(const List& properties, int id, const char* suffix) { TestPropertyKeyIs matches_key(IdToKey(id, suffix).c_str()); - const ListNode* node = properties.FindIf(matches_key); - EXPECT_TRUE(node != NULL) << "expecting " << suffix << " node for id " << id; - EXPECT_STREQ(IdToString(id).c_str(), node->element().value()); + const TestProperty* property = properties.FindIf(matches_key); + ASSERT_TRUE(property != NULL) + << "expecting " << suffix << " value for id " << id; + EXPECT_STREQ(IdToString(id).c_str(), property->value()); } // Calls a large number of Google Test assertions, where exactly one of them diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index bd9fa182..37e799fb 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -76,6 +76,16 @@ TEST(CommandLineFlagsTest, CanBeAccessedInCodeOnceGTestHIsIncluded) { #include #endif +// GTEST_EXPECT_DEATH_IF_SUPPORTED_(statement, regex) expands to a +// real death test if death tests are supported; otherwise it expands +// to empty. +#if GTEST_HAS_DEATH_TEST +#define GTEST_EXPECT_DEATH_IF_SUPPORTED_(statement, regex) \ + EXPECT_DEATH(statement, regex) +#else +#define GTEST_EXPECT_DEATH_IF_SUPPORTED_(statement, regex) +#endif + namespace testing { namespace internal { const char* FormatTimeInMillisAsSeconds(TimeInMillis ms); @@ -448,31 +458,56 @@ TEST(WideStringToUtf8Test, ConcatenatesCodepointsCorrectly) { } #endif // !GTEST_WIDE_STRING_USES_UTF16_ -// Tests the List template class. +// Tests the List class template. + +// Tests List::Clear(). +TEST(ListTest, Clear) { + List a; + a.PushBack(1); + a.Clear(); + EXPECT_EQ(0, a.size()); + + a.PushBack(2); + a.PushBack(3); + a.Clear(); + EXPECT_EQ(0, a.size()); +} + +// Tests List::PushBack(). +TEST(ListTest, PushBack) { + List a; + a.PushBack('a'); + ASSERT_EQ(1, a.size()); + EXPECT_EQ('a', a.GetElement(0)); + + a.PushBack('b'); + ASSERT_EQ(2, a.size()); + EXPECT_EQ('a', a.GetElement(0)); + EXPECT_EQ('b', a.GetElement(1)); +} // Tests List::PushFront(). TEST(ListTest, PushFront) { List a; - ASSERT_EQ(0u, a.size()); + ASSERT_EQ(0, a.size()); // Calls PushFront() on an empty list. a.PushFront(1); - ASSERT_EQ(1u, a.size()); - EXPECT_EQ(1, a.Head()->element()); - ASSERT_EQ(a.Head(), a.Last()); + ASSERT_EQ(1, a.size()); + EXPECT_EQ(1, a.GetElement(0)); // Calls PushFront() on a singleton list. a.PushFront(2); - ASSERT_EQ(2u, a.size()); - EXPECT_EQ(2, a.Head()->element()); - EXPECT_EQ(1, a.Last()->element()); + ASSERT_EQ(2, a.size()); + EXPECT_EQ(2, a.GetElement(0)); + EXPECT_EQ(1, a.GetElement(1)); // Calls PushFront() on a list with more than one elements. a.PushFront(3); - ASSERT_EQ(3u, a.size()); - EXPECT_EQ(3, a.Head()->element()); - EXPECT_EQ(2, a.Head()->next()->element()); - EXPECT_EQ(1, a.Last()->element()); + ASSERT_EQ(3, a.size()); + EXPECT_EQ(3, a.GetElement(0)); + EXPECT_EQ(2, a.GetElement(1)); + EXPECT_EQ(1, a.GetElement(2)); } // Tests List::PopFront(). @@ -497,75 +532,91 @@ TEST(ListTest, PopFront) { // After popping the last element, the list should be empty. EXPECT_TRUE(a.PopFront(NULL)); - EXPECT_EQ(0u, a.size()); + EXPECT_EQ(0, a.size()); } -// Tests inserting at the beginning using List::InsertAfter(). -TEST(ListTest, InsertAfterAtBeginning) { +// Tests inserting at the beginning using List::Insert(). +TEST(ListTest, InsertAtBeginning) { List a; - ASSERT_EQ(0u, a.size()); + ASSERT_EQ(0, a.size()); // Inserts into an empty list. - a.InsertAfter(NULL, 1); - ASSERT_EQ(1u, a.size()); - EXPECT_EQ(1, a.Head()->element()); - ASSERT_EQ(a.Head(), a.Last()); + a.Insert(1, 0); + ASSERT_EQ(1, a.size()); + EXPECT_EQ(1, a.GetElement(0)); // Inserts at the beginning of a singleton list. - a.InsertAfter(NULL, 2); - ASSERT_EQ(2u, a.size()); - EXPECT_EQ(2, a.Head()->element()); - EXPECT_EQ(1, a.Last()->element()); + a.Insert(2, 0); + ASSERT_EQ(2, a.size()); + EXPECT_EQ(2, a.GetElement(0)); + EXPECT_EQ(1, a.GetElement(1)); // Inserts at the beginning of a list with more than one elements. - a.InsertAfter(NULL, 3); - ASSERT_EQ(3u, a.size()); - EXPECT_EQ(3, a.Head()->element()); - EXPECT_EQ(2, a.Head()->next()->element()); - EXPECT_EQ(1, a.Last()->element()); + a.Insert(3, 0); + ASSERT_EQ(3, a.size()); + EXPECT_EQ(3, a.GetElement(0)); + EXPECT_EQ(2, a.GetElement(1)); + EXPECT_EQ(1, a.GetElement(2)); } // Tests inserting at a location other than the beginning using -// List::InsertAfter(). -TEST(ListTest, InsertAfterNotAtBeginning) { +// List::Insert(). +TEST(ListTest, InsertNotAtBeginning) { // Prepares a singleton list. List a; a.PushBack(1); // Inserts at the end of a singleton list. - a.InsertAfter(a.Last(), 2); - ASSERT_EQ(2u, a.size()); - EXPECT_EQ(1, a.Head()->element()); - EXPECT_EQ(2, a.Last()->element()); + a.Insert(2, a.size()); + ASSERT_EQ(2, a.size()); + EXPECT_EQ(1, a.GetElement(0)); + EXPECT_EQ(2, a.GetElement(1)); // Inserts at the end of a list with more than one elements. - a.InsertAfter(a.Last(), 3); - ASSERT_EQ(3u, a.size()); - EXPECT_EQ(1, a.Head()->element()); - EXPECT_EQ(2, a.Head()->next()->element()); - EXPECT_EQ(3, a.Last()->element()); + a.Insert(3, a.size()); + ASSERT_EQ(3, a.size()); + EXPECT_EQ(1, a.GetElement(0)); + EXPECT_EQ(2, a.GetElement(1)); + EXPECT_EQ(3, a.GetElement(2)); // Inserts in the middle of a list. - a.InsertAfter(a.Head(), 4); - ASSERT_EQ(4u, a.size()); - EXPECT_EQ(1, a.Head()->element()); - EXPECT_EQ(4, a.Head()->next()->element()); - EXPECT_EQ(2, a.Head()->next()->next()->element()); - EXPECT_EQ(3, a.Last()->element()); + a.Insert(4, 1); + ASSERT_EQ(4, a.size()); + EXPECT_EQ(1, a.GetElement(0)); + EXPECT_EQ(4, a.GetElement(1)); + EXPECT_EQ(2, a.GetElement(2)); + EXPECT_EQ(3, a.GetElement(3)); +} + +// Tests List::GetElementOr(). +TEST(ListTest, GetElementOr) { + List a; + EXPECT_EQ('x', a.GetElementOr(0, 'x')); + + a.PushBack('a'); + a.PushBack('b'); + EXPECT_EQ('a', a.GetElementOr(0, 'x')); + EXPECT_EQ('b', a.GetElementOr(1, 'x')); + EXPECT_EQ('x', a.GetElementOr(-2, 'x')); + EXPECT_EQ('x', a.GetElementOr(2, 'x')); } // Tests the GetElement accessor. -TEST(ListTest, GetElement) { +TEST(ListDeathTest, GetElement) { List a; a.PushBack(0); a.PushBack(1); a.PushBack(2); - EXPECT_EQ(&(a.Head()->element()), a.GetElement(0)); - EXPECT_EQ(&(a.Head()->next()->element()), a.GetElement(1)); - EXPECT_EQ(&(a.Head()->next()->next()->element()), a.GetElement(2)); - EXPECT_TRUE(a.GetElement(3) == NULL); - EXPECT_TRUE(a.GetElement(-1) == NULL); + EXPECT_EQ(0, a.GetElement(0)); + EXPECT_EQ(1, a.GetElement(1)); + EXPECT_EQ(2, a.GetElement(2)); + GTEST_EXPECT_DEATH_IF_SUPPORTED_( + a.GetElement(3), + "Invalid list index 3: must be in range \\[0, 2\\]\\."); + GTEST_EXPECT_DEATH_IF_SUPPORTED_( + a.GetElement(-1), + "Invalid list index -1: must be in range \\[0, 2\\]\\."); } // Tests the String class. @@ -1128,18 +1179,17 @@ class TestResultTest : public Test { } // Helper that compares two two TestPartResults. - static void CompareTestPartResult(const TestPartResult* expected, - const TestPartResult* actual) { - ASSERT_TRUE(actual != NULL); - EXPECT_EQ(expected->type(), actual->type()); - EXPECT_STREQ(expected->file_name(), actual->file_name()); - EXPECT_EQ(expected->line_number(), actual->line_number()); - EXPECT_STREQ(expected->summary(), actual->summary()); - EXPECT_STREQ(expected->message(), actual->message()); - EXPECT_EQ(expected->passed(), actual->passed()); - EXPECT_EQ(expected->failed(), actual->failed()); - EXPECT_EQ(expected->nonfatally_failed(), actual->nonfatally_failed()); - EXPECT_EQ(expected->fatally_failed(), actual->fatally_failed()); + static void CompareTestPartResult(const TestPartResult& expected, + const TestPartResult& actual) { + EXPECT_EQ(expected.type(), actual.type()); + EXPECT_STREQ(expected.file_name(), actual.file_name()); + EXPECT_EQ(expected.line_number(), actual.line_number()); + EXPECT_STREQ(expected.summary(), actual.summary()); + EXPECT_STREQ(expected.message(), actual.message()); + EXPECT_EQ(expected.passed(), actual.passed()); + EXPECT_EQ(expected.failed(), actual.failed()); + EXPECT_EQ(expected.nonfatally_failed(), actual.nonfatally_failed()); + EXPECT_EQ(expected.fatally_failed(), actual.fatally_failed()); } }; @@ -1193,11 +1243,18 @@ TEST_F(TestResultTest, Failed) { } // Tests TestResult::GetTestPartResult(). -TEST_F(TestResultTest, GetTestPartResult) { - CompareTestPartResult(pr1, r2->GetTestPartResult(0)); - CompareTestPartResult(pr2, r2->GetTestPartResult(1)); - EXPECT_TRUE(r2->GetTestPartResult(2) == NULL); - EXPECT_TRUE(r2->GetTestPartResult(-1) == NULL); + +typedef TestResultTest TestResultDeathTest; + +TEST_F(TestResultDeathTest, GetTestPartResult) { + CompareTestPartResult(*pr1, r2->GetTestPartResult(0)); + CompareTestPartResult(*pr2, r2->GetTestPartResult(1)); + GTEST_EXPECT_DEATH_IF_SUPPORTED_( + r2->GetTestPartResult(2), + "Invalid list index 2: must be in range \\[0, 1\\]\\."); + GTEST_EXPECT_DEATH_IF_SUPPORTED_( + r2->GetTestPartResult(-1), + "Invalid list index -1: must be in range \\[0, 1\\]\\."); } // Tests TestResult has no properties when none are added. @@ -1212,9 +1269,9 @@ TEST(TestResultPropertyTest, OnePropertyFoundWhenAdded) { TestProperty property("key_1", "1"); TestResultAccessor::RecordProperty(&test_result, property); ASSERT_EQ(1, test_result.test_property_count()); - const TestProperty* actual_property = test_result.GetTestProperty(0); - EXPECT_STREQ("key_1", actual_property->key()); - EXPECT_STREQ("1", actual_property->value()); + const TestProperty& actual_property = test_result.GetTestProperty(0); + EXPECT_STREQ("key_1", actual_property.key()); + EXPECT_STREQ("1", actual_property.value()); } // Tests TestResult has multiple properties when added. @@ -1225,13 +1282,13 @@ TEST(TestResultPropertyTest, MultiplePropertiesFoundWhenAdded) { TestResultAccessor::RecordProperty(&test_result, property_1); TestResultAccessor::RecordProperty(&test_result, property_2); ASSERT_EQ(2, test_result.test_property_count()); - const TestProperty* actual_property_1 = test_result.GetTestProperty(0); - EXPECT_STREQ("key_1", actual_property_1->key()); - EXPECT_STREQ("1", actual_property_1->value()); + const TestProperty& actual_property_1 = test_result.GetTestProperty(0); + EXPECT_STREQ("key_1", actual_property_1.key()); + EXPECT_STREQ("1", actual_property_1.value()); - const TestProperty* actual_property_2 = test_result.GetTestProperty(1); - EXPECT_STREQ("key_2", actual_property_2->key()); - EXPECT_STREQ("2", actual_property_2->value()); + const TestProperty& actual_property_2 = test_result.GetTestProperty(1); + EXPECT_STREQ("key_2", actual_property_2.key()); + EXPECT_STREQ("2", actual_property_2.value()); } // Tests TestResult::RecordProperty() overrides values for duplicate keys. @@ -1247,17 +1304,17 @@ TEST(TestResultPropertyTest, OverridesValuesForDuplicateKeys) { TestResultAccessor::RecordProperty(&test_result, property_2_2); ASSERT_EQ(2, test_result.test_property_count()); - const TestProperty* actual_property_1 = test_result.GetTestProperty(0); - EXPECT_STREQ("key_1", actual_property_1->key()); - EXPECT_STREQ("12", actual_property_1->value()); + const TestProperty& actual_property_1 = test_result.GetTestProperty(0); + EXPECT_STREQ("key_1", actual_property_1.key()); + EXPECT_STREQ("12", actual_property_1.value()); - const TestProperty* actual_property_2 = test_result.GetTestProperty(1); - EXPECT_STREQ("key_2", actual_property_2->key()); - EXPECT_STREQ("22", actual_property_2->value()); + const TestProperty& actual_property_2 = test_result.GetTestProperty(1); + EXPECT_STREQ("key_2", actual_property_2.key()); + EXPECT_STREQ("22", actual_property_2.value()); } // Tests TestResult::GetTestProperty(). -TEST(TestResultPropertyTest, GetTestProperty) { +TEST(TestResultPropertyDeathTest, GetTestProperty) { TestResult test_result; TestProperty property_1("key_1", "1"); TestProperty property_2("key_2", "2"); @@ -1266,24 +1323,25 @@ TEST(TestResultPropertyTest, GetTestProperty) { TestResultAccessor::RecordProperty(&test_result, property_2); TestResultAccessor::RecordProperty(&test_result, property_3); - const TestProperty* fetched_property_1 = test_result.GetTestProperty(0); - const TestProperty* fetched_property_2 = test_result.GetTestProperty(1); - const TestProperty* fetched_property_3 = test_result.GetTestProperty(2); + const TestProperty& fetched_property_1 = test_result.GetTestProperty(0); + const TestProperty& fetched_property_2 = test_result.GetTestProperty(1); + const TestProperty& fetched_property_3 = test_result.GetTestProperty(2); - ASSERT_TRUE(fetched_property_1 != NULL); - EXPECT_STREQ("key_1", fetched_property_1->key()); - EXPECT_STREQ("1", fetched_property_1->value()); + EXPECT_STREQ("key_1", fetched_property_1.key()); + EXPECT_STREQ("1", fetched_property_1.value()); - ASSERT_TRUE(fetched_property_2 != NULL); - EXPECT_STREQ("key_2", fetched_property_2->key()); - EXPECT_STREQ("2", fetched_property_2->value()); + EXPECT_STREQ("key_2", fetched_property_2.key()); + EXPECT_STREQ("2", fetched_property_2.value()); - ASSERT_TRUE(fetched_property_3 != NULL); - EXPECT_STREQ("key_3", fetched_property_3->key()); - EXPECT_STREQ("3", fetched_property_3->value()); + EXPECT_STREQ("key_3", fetched_property_3.key()); + EXPECT_STREQ("3", fetched_property_3.value()); - ASSERT_TRUE(test_result.GetTestProperty(3) == NULL); - ASSERT_TRUE(test_result.GetTestProperty(-1) == NULL); + GTEST_EXPECT_DEATH_IF_SUPPORTED_( + test_result.GetTestProperty(3), + "Invalid list index 3: must be in range \\[0, 2\\]\\."); + GTEST_EXPECT_DEATH_IF_SUPPORTED_( + test_result.GetTestProperty(-1), + "Invalid list index -1: must be in range \\[0, 2\\]\\."); } // When a property using a reserved key is supplied to this function, it tests @@ -1548,29 +1606,26 @@ TEST(Int32FromEnvOrDieTest, ParsesAndReturnsValidValue) { SetEnv(GTEST_FLAG_PREFIX_UPPER_ "UnsetVar", "-123"); EXPECT_EQ(-123, Int32FromEnvOrDie(GTEST_FLAG_PREFIX_UPPER_ "UnsetVar", 333)); } -#endif // _WIN32_WCE - -#if GTEST_HAS_DEATH_TEST +#endif // _WIN32_WCE // Tests that Int32FromEnvOrDie() aborts with an error message // if the variable is not an Int32. TEST(Int32FromEnvOrDieDeathTest, AbortsOnFailure) { SetEnv(GTEST_FLAG_PREFIX_UPPER_ "VAR", "xxx"); - EXPECT_DEATH({Int32FromEnvOrDie(GTEST_FLAG_PREFIX_UPPER_ "VAR", 123);}, - ".*"); + GTEST_EXPECT_DEATH_IF_SUPPORTED_( + Int32FromEnvOrDie(GTEST_FLAG_PREFIX_UPPER_ "VAR", 123), + ".*"); } // Tests that Int32FromEnvOrDie() aborts with an error message // if the variable cannot be represnted by an Int32. TEST(Int32FromEnvOrDieDeathTest, AbortsOnInt32Overflow) { SetEnv(GTEST_FLAG_PREFIX_UPPER_ "VAR", "1234567891234567891234"); - EXPECT_DEATH({Int32FromEnvOrDie(GTEST_FLAG_PREFIX_UPPER_ "VAR", 123);}, - ".*"); + GTEST_EXPECT_DEATH_IF_SUPPORTED_( + Int32FromEnvOrDie(GTEST_FLAG_PREFIX_UPPER_ "VAR", 123), + ".*"); } -#endif // GTEST_HAS_DEATH_TEST - - // Tests that ShouldRunTestOnShard() selects all tests // where there is 1 shard. TEST(ShouldRunTestOnShardTest, IsPartitionWhenThereIsOneShard) { @@ -1635,35 +1690,34 @@ TEST_F(ShouldShardTest, WorksWhenShardEnvVarsAreValid) { EXPECT_TRUE(ShouldShard(total_var_, index_var_, false)); EXPECT_FALSE(ShouldShard(total_var_, index_var_, true)); } -#endif // _WIN32_WCE - -#if GTEST_HAS_DEATH_TEST +#endif // _WIN32_WCE // Tests that we exit in error if the sharding values are not valid. -TEST_F(ShouldShardTest, AbortsWhenShardingEnvVarsAreInvalid) { + +typedef ShouldShardTest ShouldShardDeathTest; + +TEST_F(ShouldShardDeathTest, AbortsWhenShardingEnvVarsAreInvalid) { SetEnv(index_var_, "4"); SetEnv(total_var_, "4"); - EXPECT_DEATH({ShouldShard(total_var_, index_var_, false);}, - ".*"); + GTEST_EXPECT_DEATH_IF_SUPPORTED_(ShouldShard(total_var_, index_var_, false), + ".*"); SetEnv(index_var_, "4"); SetEnv(total_var_, "-2"); - EXPECT_DEATH({ShouldShard(total_var_, index_var_, false);}, - ".*"); + GTEST_EXPECT_DEATH_IF_SUPPORTED_(ShouldShard(total_var_, index_var_, false), + ".*"); SetEnv(index_var_, "5"); SetEnv(total_var_, ""); - EXPECT_DEATH({ShouldShard(total_var_, index_var_, false);}, - ".*"); + GTEST_EXPECT_DEATH_IF_SUPPORTED_(ShouldShard(total_var_, index_var_, false), + ".*"); SetEnv(index_var_, ""); SetEnv(total_var_, "5"); - EXPECT_DEATH({ShouldShard(total_var_, index_var_, false);}, - ".*"); + GTEST_EXPECT_DEATH_IF_SUPPORTED_(ShouldShard(total_var_, index_var_, false), + ".*"); } -#endif // GTEST_HAS_DEATH_TEST - // Tests that ShouldRunTestOnShard is a partition when 5 // shards are used. TEST(ShouldRunTestOnShardTest, IsPartitionWhenThereAreFiveShards) { @@ -3624,31 +3678,31 @@ namespace testing { TEST(SuccessfulAssertionTest, SUCCEED) { SUCCEED(); SUCCEED() << "OK"; - EXPECT_EQ(2u, GetSuccessfulPartCount()); + EXPECT_EQ(2, GetSuccessfulPartCount()); } // Tests that Google Test doesn't track successful EXPECT_*. TEST(SuccessfulAssertionTest, EXPECT) { EXPECT_TRUE(true); - EXPECT_EQ(0u, GetSuccessfulPartCount()); + EXPECT_EQ(0, GetSuccessfulPartCount()); } // Tests that Google Test doesn't track successful EXPECT_STR*. TEST(SuccessfulAssertionTest, EXPECT_STR) { EXPECT_STREQ("", ""); - EXPECT_EQ(0u, GetSuccessfulPartCount()); + EXPECT_EQ(0, GetSuccessfulPartCount()); } // Tests that Google Test doesn't track successful ASSERT_*. TEST(SuccessfulAssertionTest, ASSERT) { ASSERT_TRUE(true); - EXPECT_EQ(0u, GetSuccessfulPartCount()); + EXPECT_EQ(0, GetSuccessfulPartCount()); } // Tests that Google Test doesn't track successful ASSERT_STR*. TEST(SuccessfulAssertionTest, ASSERT_STR) { ASSERT_STREQ("", ""); - EXPECT_EQ(0u, GetSuccessfulPartCount()); + EXPECT_EQ(0, GetSuccessfulPartCount()); } } // namespace testing -- cgit v1.2.3 From 89080477aee9bd91536c9fb47bc31c62ea7d75bb Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Mon, 13 Jul 2009 19:25:02 +0000 Subject: Adds color support for TERM=linux (by Alexander Demin); renames List to Vector (by Zhanyong Wan); implements Vector::Erase (by Vlad Losev). --- test/gtest_color_test.py | 1 + test/gtest_stress_test.cc | 4 +- test/gtest_unittest.cc | 172 +++++++++++++++++++++++++++++++--------------- 3 files changed, 121 insertions(+), 56 deletions(-) (limited to 'test') diff --git a/test/gtest_color_test.py b/test/gtest_color_test.py index cccf2d89..d02a53ed 100755 --- a/test/gtest_color_test.py +++ b/test/gtest_color_test.py @@ -77,6 +77,7 @@ class GTestColorTest(gtest_test_utils.TestCase): self.assert_(not UsesColor('xterm-mono', None, None)) self.assert_(not UsesColor('unknown', None, None)) self.assert_(not UsesColor(None, None, None)) + self.assert_(UsesColor('linux', None, None)) self.assert_(UsesColor('cygwin', None, None)) self.assert_(UsesColor('xterm', None, None)) self.assert_(UsesColor('xterm-color', None, None)) diff --git a/test/gtest_stress_test.cc b/test/gtest_stress_test.cc index 3e021318..57ea75a9 100644 --- a/test/gtest_stress_test.cc +++ b/test/gtest_stress_test.cc @@ -45,10 +45,10 @@ namespace testing { namespace { -using internal::List; using internal::String; using internal::TestProperty; using internal::TestPropertyKeyIs; +using internal::Vector; // How many threads to create? const int kThreadCount = 50; @@ -65,7 +65,7 @@ String IdToString(int id) { return id_message.GetString(); } -void ExpectKeyAndValueWereRecordedForId(const List& properties, +void ExpectKeyAndValueWereRecordedForId(const Vector& properties, int id, const char* suffix) { TestPropertyKeyIs matches_key(IdToKey(id, suffix).c_str()); diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index 37e799fb..e4cc69ba 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -106,7 +106,7 @@ class TestResultAccessor { test_result->ClearTestPartResults(); } - static const List& test_part_results( + static const Vector& test_part_results( const TestResult& test_result) { return test_result.test_part_results(); } @@ -171,7 +171,6 @@ using testing::internal::GetUnitTestImpl; using testing::internal::GTestFlagSaver; using testing::internal::Int32; using testing::internal::Int32FromEnvOrDie; -using testing::internal::List; using testing::internal::ShouldRunTestOnShard; using testing::internal::ShouldShard; using testing::internal::ShouldUseColor; @@ -182,6 +181,7 @@ using testing::internal::TestProperty; using testing::internal::TestResult; using testing::internal::TestResultAccessor; using testing::internal::ThreadLocal; +using testing::internal::Vector; using testing::internal::WideStringToUtf8; // This line tests that we can define tests in an unnamed namespace. @@ -458,11 +458,11 @@ TEST(WideStringToUtf8Test, ConcatenatesCodepointsCorrectly) { } #endif // !GTEST_WIDE_STRING_USES_UTF16_ -// Tests the List class template. +// Tests the Vector class template. -// Tests List::Clear(). -TEST(ListTest, Clear) { - List a; +// Tests Vector::Clear(). +TEST(VectorTest, Clear) { + Vector a; a.PushBack(1); a.Clear(); EXPECT_EQ(0, a.size()); @@ -473,9 +473,9 @@ TEST(ListTest, Clear) { EXPECT_EQ(0, a.size()); } -// Tests List::PushBack(). -TEST(ListTest, PushBack) { - List a; +// Tests Vector::PushBack(). +TEST(VectorTest, PushBack) { + Vector a; a.PushBack('a'); ASSERT_EQ(1, a.size()); EXPECT_EQ('a', a.GetElement(0)); @@ -486,23 +486,23 @@ TEST(ListTest, PushBack) { EXPECT_EQ('b', a.GetElement(1)); } -// Tests List::PushFront(). -TEST(ListTest, PushFront) { - List a; +// Tests Vector::PushFront(). +TEST(VectorTest, PushFront) { + Vector a; ASSERT_EQ(0, a.size()); - // Calls PushFront() on an empty list. + // Calls PushFront() on an empty Vector. a.PushFront(1); ASSERT_EQ(1, a.size()); EXPECT_EQ(1, a.GetElement(0)); - // Calls PushFront() on a singleton list. + // Calls PushFront() on a singleton Vector. a.PushFront(2); ASSERT_EQ(2, a.size()); EXPECT_EQ(2, a.GetElement(0)); EXPECT_EQ(1, a.GetElement(1)); - // Calls PushFront() on a list with more than one elements. + // Calls PushFront() on a Vector with more than one elements. a.PushFront(3); ASSERT_EQ(3, a.size()); EXPECT_EQ(3, a.GetElement(0)); @@ -510,14 +510,14 @@ TEST(ListTest, PushFront) { EXPECT_EQ(1, a.GetElement(2)); } -// Tests List::PopFront(). -TEST(ListTest, PopFront) { - List a; +// Tests Vector::PopFront(). +TEST(VectorTest, PopFront) { + Vector a; - // Popping on an empty list should fail. + // Popping on an empty Vector should fail. EXPECT_FALSE(a.PopFront(NULL)); - // Popping again on an empty list should fail, and the result element + // Popping again on an empty Vector should fail, and the result element // shouldn't be overwritten. int element = 1; EXPECT_FALSE(a.PopFront(&element)); @@ -526,32 +526,32 @@ TEST(ListTest, PopFront) { a.PushFront(2); a.PushFront(3); - // PopFront() should pop the element in the front of the list. + // PopFront() should pop the element in the front of the Vector. EXPECT_TRUE(a.PopFront(&element)); EXPECT_EQ(3, element); - // After popping the last element, the list should be empty. + // After popping the last element, the Vector should be empty. EXPECT_TRUE(a.PopFront(NULL)); EXPECT_EQ(0, a.size()); } -// Tests inserting at the beginning using List::Insert(). -TEST(ListTest, InsertAtBeginning) { - List a; +// Tests inserting at the beginning using Vector::Insert(). +TEST(VectorTest, InsertAtBeginning) { + Vector a; ASSERT_EQ(0, a.size()); - // Inserts into an empty list. + // Inserts into an empty Vector. a.Insert(1, 0); ASSERT_EQ(1, a.size()); EXPECT_EQ(1, a.GetElement(0)); - // Inserts at the beginning of a singleton list. + // Inserts at the beginning of a singleton Vector. a.Insert(2, 0); ASSERT_EQ(2, a.size()); EXPECT_EQ(2, a.GetElement(0)); EXPECT_EQ(1, a.GetElement(1)); - // Inserts at the beginning of a list with more than one elements. + // Inserts at the beginning of a Vector with more than one elements. a.Insert(3, 0); ASSERT_EQ(3, a.size()); EXPECT_EQ(3, a.GetElement(0)); @@ -560,26 +560,26 @@ TEST(ListTest, InsertAtBeginning) { } // Tests inserting at a location other than the beginning using -// List::Insert(). -TEST(ListTest, InsertNotAtBeginning) { - // Prepares a singleton list. - List a; +// Vector::Insert(). +TEST(VectorTest, InsertNotAtBeginning) { + // Prepares a singleton Vector. + Vector a; a.PushBack(1); - // Inserts at the end of a singleton list. + // Inserts at the end of a singleton Vector. a.Insert(2, a.size()); ASSERT_EQ(2, a.size()); EXPECT_EQ(1, a.GetElement(0)); EXPECT_EQ(2, a.GetElement(1)); - // Inserts at the end of a list with more than one elements. + // Inserts at the end of a Vector with more than one elements. a.Insert(3, a.size()); ASSERT_EQ(3, a.size()); EXPECT_EQ(1, a.GetElement(0)); EXPECT_EQ(2, a.GetElement(1)); EXPECT_EQ(3, a.GetElement(2)); - // Inserts in the middle of a list. + // Inserts in the middle of a Vector. a.Insert(4, 1); ASSERT_EQ(4, a.size()); EXPECT_EQ(1, a.GetElement(0)); @@ -588,9 +588,9 @@ TEST(ListTest, InsertNotAtBeginning) { EXPECT_EQ(3, a.GetElement(3)); } -// Tests List::GetElementOr(). -TEST(ListTest, GetElementOr) { - List a; +// Tests Vector::GetElementOr(). +TEST(VectorTest, GetElementOr) { + Vector a; EXPECT_EQ('x', a.GetElementOr(0, 'x')); a.PushBack('a'); @@ -601,9 +601,71 @@ TEST(ListTest, GetElementOr) { EXPECT_EQ('x', a.GetElementOr(2, 'x')); } +// Tests Vector::Erase(). +TEST(VectorDeathTest, Erase) { + Vector a; + + // Tests erasing from an empty vector. + GTEST_EXPECT_DEATH_IF_SUPPORTED_( + a.Erase(0), + "Invalid Vector index 0: must be in range \\[0, -1\\]\\."); + + // Tests erasing from a singleton vector. + a.PushBack(0); + + a.Erase(0); + EXPECT_EQ(0, a.size()); + + // Tests Erase parameters beyond the bounds of the vector. + Vector a1; + a1.PushBack(0); + a1.PushBack(1); + a1.PushBack(2); + + GTEST_EXPECT_DEATH_IF_SUPPORTED_( + a1.Erase(3), + "Invalid Vector index 3: must be in range \\[0, 2\\]\\."); + GTEST_EXPECT_DEATH_IF_SUPPORTED_( + a1.Erase(-1), + "Invalid Vector index -1: must be in range \\[0, 2\\]\\."); + + // Tests erasing at the end of the vector. + Vector a2; + a2.PushBack(0); + a2.PushBack(1); + a2.PushBack(2); + + a2.Erase(2); + ASSERT_EQ(2, a2.size()); + EXPECT_EQ(0, a2.GetElement(0)); + EXPECT_EQ(1, a2.GetElement(1)); + + // Tests erasing in the middle of the vector. + Vector a3; + a3.PushBack(0); + a3.PushBack(1); + a3.PushBack(2); + + a3.Erase(1); + ASSERT_EQ(2, a3.size()); + EXPECT_EQ(0, a3.GetElement(0)); + EXPECT_EQ(2, a3.GetElement(1)); + + // Tests erasing at the beginning of the vector. + Vector a4; + a4.PushBack(0); + a4.PushBack(1); + a4.PushBack(2); + + a4.Erase(0); + ASSERT_EQ(2, a4.size()); + EXPECT_EQ(1, a4.GetElement(0)); + EXPECT_EQ(2, a4.GetElement(1)); +} + // Tests the GetElement accessor. TEST(ListDeathTest, GetElement) { - List a; + Vector a; a.PushBack(0); a.PushBack(1); a.PushBack(2); @@ -613,10 +675,10 @@ TEST(ListDeathTest, GetElement) { EXPECT_EQ(2, a.GetElement(2)); GTEST_EXPECT_DEATH_IF_SUPPORTED_( a.GetElement(3), - "Invalid list index 3: must be in range \\[0, 2\\]\\."); + "Invalid Vector index 3: must be in range \\[0, 2\\]\\."); GTEST_EXPECT_DEATH_IF_SUPPORTED_( a.GetElement(-1), - "Invalid list index -1: must be in range \\[0, 2\\]\\."); + "Invalid Vector index -1: must be in range \\[0, 2\\]\\."); } // Tests the String class. @@ -1126,7 +1188,7 @@ TEST_F(ExpectFailureWithThreadsTest, ExpectNonFatalFailureOnAllThreads) { // The test fixture for testing TestResult. class TestResultTest : public Test { protected: - typedef List TPRList; + typedef Vector TPRVector; // We make use of 2 TestPartResult objects, TestPartResult * pr1, * pr2; @@ -1149,24 +1211,23 @@ class TestResultTest : public Test { r2 = new TestResult(); // In order to test TestResult, we need to modify its internal - // state, in particular the TestPartResult list it holds. - // test_part_results() returns a const reference to this list. + // state, in particular the TestPartResult Vector it holds. + // test_part_results() returns a const reference to this Vector. // We cast it to a non-const object s.t. it can be modified (yes, // this is a hack). - TPRList * list1, * list2; - list1 = const_cast *>( + TPRVector* results1 = const_cast *>( &TestResultAccessor::test_part_results(*r1)); - list2 = const_cast *>( + TPRVector* results2 = const_cast *>( &TestResultAccessor::test_part_results(*r2)); // r0 is an empty TestResult. // r1 contains a single SUCCESS TestPartResult. - list1->PushBack(*pr1); + results1->PushBack(*pr1); // r2 contains a SUCCESS, and a FAILURE. - list2->PushBack(*pr1); - list2->PushBack(*pr2); + results2->PushBack(*pr1); + results2->PushBack(*pr2); } virtual void TearDown() { @@ -1251,10 +1312,10 @@ TEST_F(TestResultDeathTest, GetTestPartResult) { CompareTestPartResult(*pr2, r2->GetTestPartResult(1)); GTEST_EXPECT_DEATH_IF_SUPPORTED_( r2->GetTestPartResult(2), - "Invalid list index 2: must be in range \\[0, 1\\]\\."); + "Invalid Vector index 2: must be in range \\[0, 1\\]\\."); GTEST_EXPECT_DEATH_IF_SUPPORTED_( r2->GetTestPartResult(-1), - "Invalid list index -1: must be in range \\[0, 1\\]\\."); + "Invalid Vector index -1: must be in range \\[0, 1\\]\\."); } // Tests TestResult has no properties when none are added. @@ -1338,10 +1399,10 @@ TEST(TestResultPropertyDeathTest, GetTestProperty) { GTEST_EXPECT_DEATH_IF_SUPPORTED_( test_result.GetTestProperty(3), - "Invalid list index 3: must be in range \\[0, 2\\]\\."); + "Invalid Vector index 3: must be in range \\[0, 2\\]\\."); GTEST_EXPECT_DEATH_IF_SUPPORTED_( test_result.GetTestProperty(-1), - "Invalid list index -1: must be in range \\[0, 2\\]\\."); + "Invalid Vector index -1: must be in range \\[0, 2\\]\\."); } // When a property using a reserved key is supplied to this function, it tests @@ -5684,6 +5745,9 @@ TEST(ColoredOutputTest, UsesColorsWhenTermSupportsColors) { SetEnv("TERM", "xterm-color"); // TERM supports colors. EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY. + + SetEnv("TERM", "linux"); // TERM supports colors. + EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY. #endif // GTEST_OS_WINDOWS } -- cgit v1.2.3 From 8bdb31e0540c46de485b362178f60e8bb947ff43 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Tue, 14 Jul 2009 22:56:46 +0000 Subject: Adds the command line flags needed for test shuffling. Most code by Josh Kelley. --- test/gtest_help_test.py | 2 + test/gtest_unittest.cc | 144 +++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 143 insertions(+), 3 deletions(-) (limited to 'test') diff --git a/test/gtest_help_test.py b/test/gtest_help_test.py index 0a2a07b6..91081ad3 100755 --- a/test/gtest_help_test.py +++ b/test/gtest_help_test.py @@ -57,6 +57,8 @@ HELP_REGEX = re.compile( FLAG_PREFIX + r'filter=.*' + FLAG_PREFIX + r'also_run_disabled_tests.*' + FLAG_PREFIX + r'repeat=.*' + + FLAG_PREFIX + r'shuffle.*' + + FLAG_PREFIX + r'random_seed=.*' + FLAG_PREFIX + r'color=.*' + FLAG_PREFIX + r'print_time.*' + FLAG_PREFIX + r'output=.*' + diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index e4cc69ba..7cdfa172 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -46,8 +46,10 @@ TEST(CommandLineFlagsTest, CanBeAccessedInCodeOnceGTestHIsIncluded) { || testing::GTEST_FLAG(list_tests) || testing::GTEST_FLAG(output) != "unknown" || testing::GTEST_FLAG(print_time) + || testing::GTEST_FLAG(random_seed) || testing::GTEST_FLAG(repeat) > 0 || testing::GTEST_FLAG(show_internal_stack_frames) + || testing::GTEST_FLAG(shuffle) || testing::GTEST_FLAG(stack_trace_depth) > 0 || testing::GTEST_FLAG(throw_on_failure); EXPECT_TRUE(dummy || !dummy); // Suppresses warning that dummy is unused. @@ -142,8 +144,10 @@ using testing::GTEST_FLAG(filter); using testing::GTEST_FLAG(list_tests); using testing::GTEST_FLAG(output); using testing::GTEST_FLAG(print_time); +using testing::GTEST_FLAG(random_seed); using testing::GTEST_FLAG(repeat); using testing::GTEST_FLAG(show_internal_stack_frames); +using testing::GTEST_FLAG(shuffle); using testing::GTEST_FLAG(stack_trace_depth); using testing::GTEST_FLAG(throw_on_failure); using testing::IsNotSubstring; @@ -158,6 +162,7 @@ using testing::TPRT_FATAL_FAILURE; using testing::TPRT_NONFATAL_FAILURE; using testing::TPRT_SUCCESS; using testing::UnitTest; +using testing::internal::kMaxRandomSeed; using testing::internal::kTestTypeIdInGoogleTest; using testing::internal::AppendUserMessage; using testing::internal::CodePointToUtf8; @@ -165,6 +170,8 @@ using testing::internal::EqFailure; using testing::internal::FloatingPoint; using testing::internal::GetCurrentOsStackTraceExceptTop; using testing::internal::GetFailedPartCount; +using testing::internal::GetNextRandomSeed; +using testing::internal::GetRandomSeedFromFlag; using testing::internal::GetTestTypeId; using testing::internal::GetTypeId; using testing::internal::GetUnitTestImpl; @@ -187,6 +194,43 @@ using testing::internal::WideStringToUtf8; // This line tests that we can define tests in an unnamed namespace. namespace { +TEST(GetRandomSeedFromFlagTest, HandlesZero) { + const int seed = GetRandomSeedFromFlag(0); + EXPECT_LE(1, seed); + EXPECT_LE(seed, static_cast(kMaxRandomSeed)); +} + +TEST(GetRandomSeedFromFlagTest, PreservesValidSeed) { + EXPECT_EQ(1, GetRandomSeedFromFlag(1)); + EXPECT_EQ(2, GetRandomSeedFromFlag(2)); + EXPECT_EQ(kMaxRandomSeed - 1, GetRandomSeedFromFlag(kMaxRandomSeed - 1)); + EXPECT_EQ(static_cast(kMaxRandomSeed), + GetRandomSeedFromFlag(kMaxRandomSeed)); +} + +TEST(GetRandomSeedFromFlagTest, NormalizesInvalidSeed) { + const int seed1 = GetRandomSeedFromFlag(-1); + EXPECT_LE(1, seed1); + EXPECT_LE(seed1, static_cast(kMaxRandomSeed)); + + const int seed2 = GetRandomSeedFromFlag(kMaxRandomSeed + 1); + EXPECT_LE(1, seed2); + EXPECT_LE(seed2, static_cast(kMaxRandomSeed)); +} + +TEST(GetNextRandomSeedTest, WorksForValidInput) { + EXPECT_EQ(2, GetNextRandomSeed(1)); + EXPECT_EQ(3, GetNextRandomSeed(2)); + EXPECT_EQ(static_cast(kMaxRandomSeed), + GetNextRandomSeed(kMaxRandomSeed - 1)); + EXPECT_EQ(1, GetNextRandomSeed(kMaxRandomSeed)); + + // We deliberately don't test GetNextRandomSeed() with invalid + // inputs, as that requires death tests, which are expensive. This + // is fine as GetNextRandomSeed() is internal and has a + // straightforward definition. +} + static void ClearCurrentTestPartResults() { TestResultAccessor::ClearTestPartResults( GetUnitTestImpl()->current_test_result()); @@ -1460,7 +1504,9 @@ class GTestFlagSaverTest : public Test { GTEST_FLAG(list_tests) = false; GTEST_FLAG(output) = ""; GTEST_FLAG(print_time) = true; + GTEST_FLAG(random_seed) = 0; GTEST_FLAG(repeat) = 1; + GTEST_FLAG(shuffle) = false; GTEST_FLAG(throw_on_failure) = false; } @@ -1483,7 +1529,9 @@ class GTestFlagSaverTest : public Test { EXPECT_FALSE(GTEST_FLAG(list_tests)); EXPECT_STREQ("", GTEST_FLAG(output).c_str()); EXPECT_TRUE(GTEST_FLAG(print_time)); + EXPECT_EQ(0, GTEST_FLAG(random_seed)); EXPECT_EQ(1, GTEST_FLAG(repeat)); + EXPECT_FALSE(GTEST_FLAG(shuffle)); EXPECT_FALSE(GTEST_FLAG(throw_on_failure)); GTEST_FLAG(also_run_disabled_tests) = true; @@ -1495,7 +1543,9 @@ class GTestFlagSaverTest : public Test { GTEST_FLAG(list_tests) = true; GTEST_FLAG(output) = "xml:foo.xml"; GTEST_FLAG(print_time) = false; + GTEST_FLAG(random_seed) = 1; GTEST_FLAG(repeat) = 100; + GTEST_FLAG(shuffle) = true; GTEST_FLAG(throw_on_failure) = true; } private: @@ -4657,7 +4707,9 @@ struct Flags { list_tests(false), output(""), print_time(true), + random_seed(0), repeat(1), + shuffle(false), throw_on_failure(false) {} // Factory methods. @@ -4726,6 +4778,14 @@ struct Flags { return flags; } + // Creates a Flags struct where the gtest_random_seed flag has + // the given value. + static Flags RandomSeed(Int32 random_seed) { + Flags flags; + flags.random_seed = random_seed; + return flags; + } + // Creates a Flags struct where the gtest_repeat flag has the given // value. static Flags Repeat(Int32 repeat) { @@ -4734,6 +4794,14 @@ struct Flags { return flags; } + // Creates a Flags struct where the gtest_shuffle flag has + // the given value. + static Flags Shuffle(bool shuffle) { + Flags flags; + flags.shuffle = shuffle; + return flags; + } + // Creates a Flags struct where the gtest_throw_on_failure flag has // the given value. static Flags ThrowOnFailure(bool throw_on_failure) { @@ -4751,7 +4819,9 @@ struct Flags { bool list_tests; const char* output; bool print_time; + Int32 random_seed; Int32 repeat; + bool shuffle; bool throw_on_failure; }; @@ -4768,7 +4838,9 @@ class InitGoogleTestTest : public Test { GTEST_FLAG(list_tests) = false; GTEST_FLAG(output) = ""; GTEST_FLAG(print_time) = true; + GTEST_FLAG(random_seed) = 0; GTEST_FLAG(repeat) = 1; + GTEST_FLAG(shuffle) = false; GTEST_FLAG(throw_on_failure) = false; } @@ -4794,7 +4866,9 @@ class InitGoogleTestTest : public Test { EXPECT_EQ(expected.list_tests, GTEST_FLAG(list_tests)); EXPECT_STREQ(expected.output, GTEST_FLAG(output).c_str()); EXPECT_EQ(expected.print_time, GTEST_FLAG(print_time)); + EXPECT_EQ(expected.random_seed, GTEST_FLAG(random_seed)); EXPECT_EQ(expected.repeat, GTEST_FLAG(repeat)); + EXPECT_EQ(expected.shuffle, GTEST_FLAG(shuffle)); EXPECT_EQ(expected.throw_on_failure, GTEST_FLAG(throw_on_failure)); } @@ -4901,7 +4975,7 @@ TEST_F(InitGoogleTestTest, FilterNonEmpty) { } // Tests parsing --gtest_break_on_failure. -TEST_F(InitGoogleTestTest, BreakOnFailureNoDef) { +TEST_F(InitGoogleTestTest, BreakOnFailureWithoutValue) { const char* argv[] = { "foo.exe", "--gtest_break_on_failure", @@ -5117,7 +5191,7 @@ TEST_F(InitGoogleTestTest, ListTestsFalse_f) { GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ListTests(false)); } -// Tests parsing --gtest_break_on_failure=F. +// Tests parsing --gtest_list_tests=F. TEST_F(InitGoogleTestTest, ListTestsFalse_F) { const char* argv[] = { "foo.exe", @@ -5278,6 +5352,22 @@ TEST_F(InitGoogleTestTest, PrintTimeFalse_F) { GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::PrintTime(false)); } +// Tests parsing --gtest_random_seed=number +TEST_F(InitGoogleTestTest, RandomSeed) { + const char* argv[] = { + "foo.exe", + "--gtest_random_seed=1000", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::RandomSeed(1000)); +} + // Tests parsing --gtest_repeat=number TEST_F(InitGoogleTestTest, Repeat) { const char* argv[] = { @@ -5342,9 +5432,57 @@ TEST_F(InitGoogleTestTest, AlsoRunDisabledTestsFalse) { GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::AlsoRunDisabledTests(false)); } +// Tests parsing --gtest_shuffle. +TEST_F(InitGoogleTestTest, ShuffleWithoutValue) { + const char* argv[] = { + "foo.exe", + "--gtest_shuffle", + NULL +}; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Shuffle(true)); +} + +// Tests parsing --gtest_shuffle=0. +TEST_F(InitGoogleTestTest, ShuffleFalse_0) { + const char* argv[] = { + "foo.exe", + "--gtest_shuffle=0", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Shuffle(false)); +} + +// Tests parsing a --gtest_shuffle flag that has a "true" +// definition. +TEST_F(InitGoogleTestTest, ShuffleTrue) { + const char* argv[] = { + "foo.exe", + "--gtest_shuffle=1", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Shuffle(true)); +} // Tests parsing --gtest_throw_on_failure. -TEST_F(InitGoogleTestTest, ThrowOnFailureNoDef) { +TEST_F(InitGoogleTestTest, ThrowOnFailureWithoutValue) { const char* argv[] = { "foo.exe", "--gtest_throw_on_failure", -- cgit v1.2.3 From c214ebc830aa918d54e535c6caa2da6317877e12 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Thu, 16 Jul 2009 00:36:55 +0000 Subject: More refactoring for the event listener API, by Vlad Losev. --- test/gtest-death-test_test.cc | 7 +- test/gtest-unittest-api_test.cc | 363 ++++++++++++++++++++++++++++++++++++++++ test/gtest_unittest.cc | 137 ++++++++------- test/run_tests_test.py | 154 +++++++++-------- 4 files changed, 524 insertions(+), 137 deletions(-) create mode 100644 test/gtest-unittest-api_test.cc (limited to 'test') diff --git a/test/gtest-death-test_test.cc b/test/gtest-death-test_test.cc index 8b2173bf..e9317e17 100644 --- a/test/gtest-death-test_test.cc +++ b/test/gtest-death-test_test.cc @@ -957,16 +957,11 @@ TEST_F(MacroLogicDeathTest, ChildDoesNotDie) { EXPECT_TRUE(factory_->TestDeleted()); } -// Returns the number of successful parts in the current test. -static size_t GetSuccessfulTestPartCount() { - return GetUnitTestImpl()->current_test_result()->successful_part_count(); -} - // Tests that a successful death test does not register a successful // test part. TEST(SuccessRegistrationDeathTest, NoSuccessPart) { EXPECT_DEATH(_exit(1), ""); - EXPECT_EQ(0u, GetSuccessfulTestPartCount()); + EXPECT_EQ(0, GetUnitTestImpl()->current_test_result()->total_part_count()); } TEST(StreamingAssertionsDeathTest, DeathTest) { diff --git a/test/gtest-unittest-api_test.cc b/test/gtest-unittest-api_test.cc new file mode 100644 index 00000000..658e2985 --- /dev/null +++ b/test/gtest-unittest-api_test.cc @@ -0,0 +1,363 @@ +// Copyright 2009 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: vladl@google.com (Vlad Losev) +// +// The Google C++ Testing Framework (Google Test) +// +// This file contains tests verifying correctness of data provided via +// UnitTest's public methods. + +#include + +#include // For strcmp. +#include + +using ::testing::AddGlobalTestEnvironment; +using ::testing::Environment; +using ::testing::InitGoogleTest; +using ::testing::Test; +using ::testing::TestInfo; +using ::testing::TestPartResult; +using ::testing::UnitTest; +using ::testing::internal::TestCase; +using ::testing::internal::TestProperty; + +#if GTEST_HAS_TYPED_TEST +using ::testing::Types; +using ::testing::internal::GetTypeName; +using ::testing::internal::String; +#endif // GTEST_HAS_TYPED_TEST + +namespace testing { +namespace internal { + +template +struct LessByName { + bool operator()(const T* a, const T* b) { + return strcmp(a->name(), b->name()) < 0; + } +}; + +class UnitTestAccessor { + public: + // Returns the array of pointers to all test cases sorted by the test case + // name. The caller is responsible for deleting the array. + static TestCase const** const GetSortedTestCases() { + UnitTest* unit_test = UnitTest::GetInstance(); + TestCase const** const test_cases = + new const TestCase*[unit_test->total_test_case_count()]; + + for (int i = 0; i < unit_test->total_test_case_count(); ++i) + test_cases[i] = unit_test->GetTestCase(i); + + std::sort(test_cases, + test_cases + unit_test->total_test_case_count(), + LessByName()); + return test_cases; + } + + // Returns the test case by its name. The caller doesn't own the returned + // pointer. + static const TestCase* FindTestCase(const char* name) { + UnitTest* unit_test = UnitTest::GetInstance(); + for (int i = 0; i < unit_test->total_test_case_count(); ++i) { + const TestCase* test_case = unit_test->GetTestCase(i); + if (0 == strcmp(test_case->name(), name)) + return test_case; + } + return NULL; + } + + // Returns the array of pointers to all tests in a particular test case + // sorted by the test name. The caller is responsible for deleting the + // array. + static TestInfo const** const GetSortedTests(const TestCase* test_case) { + TestInfo const** const tests = + new const TestInfo*[test_case->total_test_count()]; + + for (int i = 0; i < test_case->total_test_count(); ++i) + tests[i] = test_case->GetTestInfo(i); + + std::sort(tests, + tests + test_case->total_test_count(), + LessByName()); + return tests; + } +}; + +// TODO(vladl@google.com): Put tests into the internal namespace after +// UnitTest methods are published. +} // namespace internal + +using internal::UnitTestAccessor; + +#if GTEST_HAS_TYPED_TEST +template class TestCaseWithCommentTest : public Test {}; +TYPED_TEST_CASE(TestCaseWithCommentTest, Types); +TYPED_TEST(TestCaseWithCommentTest, Dummy) {} + +const int kTypedTestCases = 1; +const int kTypedTests = 1; + +String GetExpectedTestCaseComment() { + Message comment; + comment << "TypeParam = " << GetTypeName().c_str(); + return comment.GetString(); +} +#else +const int kTypedTestCases = 0; +const int kTypedTests = 0; +#endif // GTEST_HAS_TYPED_TEST + +// We can only test the accessors that do not change value while tests run. +// Since tests can be run in any order, the values the accessors that track +// test execution (such as failed_test_count) can not be predicted. +TEST(ApiTest, UnitTestImmutableAccessorsWork) { + UnitTest* unit_test = UnitTest::GetInstance(); + + ASSERT_EQ(2 + kTypedTestCases, unit_test->total_test_case_count()); + EXPECT_EQ(1 + kTypedTestCases, unit_test->test_case_to_run_count()); + EXPECT_EQ(2, unit_test->disabled_test_count()); + EXPECT_EQ(5 + kTypedTests, unit_test->total_test_count()); + EXPECT_EQ(3 + kTypedTests, unit_test->test_to_run_count()); + + const TestCase** const test_cases = UnitTestAccessor::GetSortedTestCases(); + + EXPECT_STREQ("ApiTest", test_cases[0]->name()); + EXPECT_STREQ("DISABLED_Test", test_cases[1]->name()); +#if GTEST_HAS_TYPED_TEST + EXPECT_STREQ("TestCaseWithCommentTest/0", test_cases[2]->name()); +#endif // GTEST_HAS_TYPED_TEST + + delete[] test_cases; + + // The following lines initiate actions to verify certain methods in + // FinalSuccessChecker::TearDown. + + // Records a test property to verify TestResult::GetTestProperty(). + RecordProperty("key", "value"); +} + +TEST(ApiTest, TestCaseImmutableAccessorsWork) { + const TestCase* test_case = UnitTestAccessor::FindTestCase("ApiTest"); + ASSERT_TRUE(test_case != NULL); + + EXPECT_STREQ("ApiTest", test_case->name()); + EXPECT_STREQ("", test_case->comment()); + EXPECT_TRUE(test_case->should_run()); + EXPECT_EQ(1, test_case->disabled_test_count()); + EXPECT_EQ(3, test_case->test_to_run_count()); + ASSERT_EQ(4, test_case->total_test_count()); + + const TestInfo** tests = UnitTestAccessor::GetSortedTests(test_case); + + EXPECT_STREQ("DISABLED_Dummy1", tests[0]->name()); + EXPECT_STREQ("ApiTest", tests[0]->test_case_name()); + EXPECT_STREQ("", tests[0]->comment()); + EXPECT_STREQ("", tests[0]->test_case_comment()); + EXPECT_FALSE(tests[0]->should_run()); + + EXPECT_STREQ("TestCaseDisabledAccessorsWork", tests[1]->name()); + EXPECT_STREQ("ApiTest", tests[1]->test_case_name()); + EXPECT_STREQ("", tests[1]->comment()); + EXPECT_STREQ("", tests[1]->test_case_comment()); + EXPECT_TRUE(tests[1]->should_run()); + + EXPECT_STREQ("TestCaseImmutableAccessorsWork", tests[2]->name()); + EXPECT_STREQ("ApiTest", tests[2]->test_case_name()); + EXPECT_STREQ("", tests[2]->comment()); + EXPECT_STREQ("", tests[2]->test_case_comment()); + EXPECT_TRUE(tests[2]->should_run()); + + EXPECT_STREQ("UnitTestImmutableAccessorsWork", tests[3]->name()); + EXPECT_STREQ("ApiTest", tests[3]->test_case_name()); + EXPECT_STREQ("", tests[3]->comment()); + EXPECT_STREQ("", tests[3]->test_case_comment()); + EXPECT_TRUE(tests[3]->should_run()); + + delete[] tests; + tests = NULL; + +#if GTEST_HAS_TYPED_TEST + test_case = UnitTestAccessor::FindTestCase("TestCaseWithCommentTest/0"); + ASSERT_TRUE(test_case != NULL); + + EXPECT_STREQ("TestCaseWithCommentTest/0", test_case->name()); + EXPECT_STREQ(GetExpectedTestCaseComment().c_str(), test_case->comment()); + EXPECT_TRUE(test_case->should_run()); + EXPECT_EQ(0, test_case->disabled_test_count()); + EXPECT_EQ(1, test_case->test_to_run_count()); + ASSERT_EQ(1, test_case->total_test_count()); + + tests = UnitTestAccessor::GetSortedTests(test_case); + + EXPECT_STREQ("Dummy", tests[0]->name()); + EXPECT_STREQ("TestCaseWithCommentTest/0", tests[0]->test_case_name()); + EXPECT_STREQ("", tests[0]->comment()); + EXPECT_STREQ(GetExpectedTestCaseComment().c_str(), + tests[0]->test_case_comment()); + EXPECT_TRUE(tests[0]->should_run()); + + delete[] tests; +#endif // GTEST_HAS_TYPED_TEST +} + +TEST(ApiTest, TestCaseDisabledAccessorsWork) { + const TestCase* test_case = UnitTestAccessor::FindTestCase("DISABLED_Test"); + ASSERT_TRUE(test_case != NULL); + + EXPECT_STREQ("DISABLED_Test", test_case->name()); + EXPECT_STREQ("", test_case->comment()); + EXPECT_FALSE(test_case->should_run()); + EXPECT_EQ(1, test_case->disabled_test_count()); + EXPECT_EQ(0, test_case->test_to_run_count()); + ASSERT_EQ(1, test_case->total_test_count()); + + const TestInfo* const test_info = test_case->GetTestInfo(0); + EXPECT_STREQ("Dummy2", test_info->name()); + EXPECT_STREQ("DISABLED_Test", test_info->test_case_name()); + EXPECT_STREQ("", test_info->comment()); + EXPECT_STREQ("", test_info->test_case_comment()); + EXPECT_FALSE(test_info->should_run()); +} + +// These two tests are here to provide support for testing +// test_case_to_run_count, disabled_test_count, and test_to_run_count. +TEST(ApiTest, DISABLED_Dummy1) {} +TEST(DISABLED_Test, Dummy2) {} + +class FinalSuccessChecker : public Environment { + protected: + virtual void TearDown() { + UnitTest* unit_test = UnitTest::GetInstance(); + + EXPECT_EQ(1 + kTypedTestCases, unit_test->successful_test_case_count()); + EXPECT_EQ(3 + kTypedTests, unit_test->successful_test_count()); + EXPECT_EQ(0, unit_test->failed_test_case_count()); + EXPECT_EQ(0, unit_test->failed_test_count()); + EXPECT_TRUE(unit_test->Passed()); + EXPECT_FALSE(unit_test->Failed()); + ASSERT_EQ(2 + kTypedTestCases, unit_test->total_test_case_count()); + + const TestCase** const test_cases = UnitTestAccessor::GetSortedTestCases(); + + EXPECT_STREQ("ApiTest", test_cases[0]->name()); + EXPECT_STREQ("", test_cases[0]->comment()); + EXPECT_TRUE(test_cases[0]->should_run()); + EXPECT_EQ(1, test_cases[0]->disabled_test_count()); + ASSERT_EQ(4, test_cases[0]->total_test_count()); + EXPECT_EQ(3, test_cases[0]->successful_test_count()); + EXPECT_EQ(0, test_cases[0]->failed_test_count()); + EXPECT_TRUE(test_cases[0]->Passed()); + EXPECT_FALSE(test_cases[0]->Failed()); + + EXPECT_STREQ("DISABLED_Test", test_cases[1]->name()); + EXPECT_STREQ("", test_cases[1]->comment()); + EXPECT_FALSE(test_cases[1]->should_run()); + EXPECT_EQ(1, test_cases[1]->disabled_test_count()); + ASSERT_EQ(1, test_cases[1]->total_test_count()); + EXPECT_EQ(0, test_cases[1]->successful_test_count()); + EXPECT_EQ(0, test_cases[1]->failed_test_count()); + +#if GTEST_HAS_TYPED_TEST + EXPECT_STREQ("TestCaseWithCommentTest/0", test_cases[2]->name()); + EXPECT_STREQ(GetExpectedTestCaseComment().c_str(), + test_cases[2]->comment()); + EXPECT_TRUE(test_cases[2]->should_run()); + EXPECT_EQ(0, test_cases[2]->disabled_test_count()); + ASSERT_EQ(1, test_cases[2]->total_test_count()); + EXPECT_EQ(1, test_cases[2]->successful_test_count()); + EXPECT_EQ(0, test_cases[2]->failed_test_count()); + EXPECT_TRUE(test_cases[2]->Passed()); + EXPECT_FALSE(test_cases[2]->Failed()); +#endif // GTEST_HAS_TYPED_TEST + + const TestCase* test_case = UnitTestAccessor::FindTestCase("ApiTest"); + const TestInfo** tests = UnitTestAccessor::GetSortedTests(test_case); + EXPECT_STREQ("DISABLED_Dummy1", tests[0]->name()); + EXPECT_STREQ("ApiTest", tests[0]->test_case_name()); + EXPECT_FALSE(tests[0]->should_run()); + + EXPECT_STREQ("TestCaseDisabledAccessorsWork", tests[1]->name()); + EXPECT_STREQ("ApiTest", tests[1]->test_case_name()); + EXPECT_STREQ("", tests[1]->comment()); + EXPECT_STREQ("", tests[1]->test_case_comment()); + EXPECT_TRUE(tests[1]->should_run()); + EXPECT_TRUE(tests[1]->result()->Passed()); + EXPECT_EQ(0, tests[1]->result()->test_property_count()); + + EXPECT_STREQ("TestCaseImmutableAccessorsWork", tests[2]->name()); + EXPECT_STREQ("ApiTest", tests[2]->test_case_name()); + EXPECT_STREQ("", tests[2]->comment()); + EXPECT_STREQ("", tests[2]->test_case_comment()); + EXPECT_TRUE(tests[2]->should_run()); + EXPECT_TRUE(tests[2]->result()->Passed()); + EXPECT_EQ(0, tests[2]->result()->test_property_count()); + + EXPECT_STREQ("UnitTestImmutableAccessorsWork", tests[3]->name()); + EXPECT_STREQ("ApiTest", tests[3]->test_case_name()); + EXPECT_STREQ("", tests[3]->comment()); + EXPECT_STREQ("", tests[3]->test_case_comment()); + EXPECT_TRUE(tests[3]->should_run()); + EXPECT_TRUE(tests[3]->result()->Passed()); + EXPECT_EQ(1, tests[3]->result()->test_property_count()); + const TestProperty& property = tests[3]->result()->GetTestProperty(0); + EXPECT_STREQ("key", property.key()); + EXPECT_STREQ("value", property.value()); + + delete[] tests; + +#if GTEST_HAS_TYPED_TEST + test_case = UnitTestAccessor::FindTestCase("TestCaseWithCommentTest/0"); + tests = UnitTestAccessor::GetSortedTests(test_case); + + EXPECT_STREQ("Dummy", tests[0]->name()); + EXPECT_STREQ("TestCaseWithCommentTest/0", tests[0]->test_case_name()); + EXPECT_STREQ("", tests[0]->comment()); + EXPECT_STREQ(GetExpectedTestCaseComment().c_str(), + tests[0]->test_case_comment()); + EXPECT_TRUE(tests[0]->should_run()); + EXPECT_TRUE(tests[0]->result()->Passed()); + EXPECT_EQ(0, tests[0]->result()->test_property_count()); + + delete[] tests; +#endif // GTEST_HAS_TYPED_TEST + delete[] test_cases; + } +}; + +} // namespace testing + +int main(int argc, char **argv) { + InitGoogleTest(&argc, argv); + + AddGlobalTestEnvironment(new testing::FinalSuccessChecker()); + + return RUN_ALL_TESTS(); +} diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index 7cdfa172..4eb098e7 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -94,26 +94,6 @@ const char* FormatTimeInMillisAsSeconds(TimeInMillis ms); bool ParseInt32Flag(const char* str, const char* flag, Int32* value); -// TestResult contains some private methods that should be hidden from -// Google Test user but are required for testing. This class allow our tests -// to access them. -class TestResultAccessor { - public: - static void RecordProperty(TestResult* test_result, - const TestProperty& property) { - test_result->RecordProperty(property); - } - - static void ClearTestPartResults(TestResult* test_result) { - test_result->ClearTestPartResults(); - } - - static const Vector& test_part_results( - const TestResult& test_result) { - return test_result.test_part_results(); - } -}; - } // namespace internal } // namespace testing @@ -138,8 +118,8 @@ using testing::FloatLE; using testing::GTEST_FLAG(also_run_disabled_tests); using testing::GTEST_FLAG(break_on_failure); using testing::GTEST_FLAG(catch_exceptions); -using testing::GTEST_FLAG(death_test_use_fork); using testing::GTEST_FLAG(color); +using testing::GTEST_FLAG(death_test_use_fork); using testing::GTEST_FLAG(filter); using testing::GTEST_FLAG(list_tests); using testing::GTEST_FLAG(output); @@ -155,12 +135,12 @@ using testing::IsSubstring; using testing::Message; using testing::ScopedFakeTestPartResultReporter; using testing::StaticAssertTypeEq; -using testing::Test; -using testing::TestPartResult; -using testing::TestPartResultArray; using testing::TPRT_FATAL_FAILURE; using testing::TPRT_NONFATAL_FAILURE; using testing::TPRT_SUCCESS; +using testing::Test; +using testing::TestPartResult; +using testing::TestPartResultArray; using testing::UnitTest; using testing::internal::kMaxRandomSeed; using testing::internal::kTestTypeIdInGoogleTest; @@ -168,14 +148,13 @@ using testing::internal::AppendUserMessage; using testing::internal::CodePointToUtf8; using testing::internal::EqFailure; using testing::internal::FloatingPoint; +using testing::internal::GTestFlagSaver; using testing::internal::GetCurrentOsStackTraceExceptTop; -using testing::internal::GetFailedPartCount; using testing::internal::GetNextRandomSeed; using testing::internal::GetRandomSeedFromFlag; using testing::internal::GetTestTypeId; using testing::internal::GetTypeId; using testing::internal::GetUnitTestImpl; -using testing::internal::GTestFlagSaver; using testing::internal::Int32; using testing::internal::Int32FromEnvOrDie; using testing::internal::ShouldRunTestOnShard; @@ -190,6 +169,7 @@ using testing::internal::TestResultAccessor; using testing::internal::ThreadLocal; using testing::internal::Vector; using testing::internal::WideStringToUtf8; +using testing::internal::kTestTypeIdInGoogleTest; // This line tests that we can define tests in an unnamed namespace. namespace { @@ -1227,6 +1207,68 @@ TEST_F(ExpectFailureWithThreadsTest, ExpectNonFatalFailureOnAllThreads) { #endif // GTEST_IS_THREADSAFE && GTEST_HAS_PTHREAD +// Tests the TestProperty class. + +TEST(TestPropertyTest, ConstructorWorks) { + const TestProperty property("key", "value"); + EXPECT_STREQ("key", property.key()); + EXPECT_STREQ("value", property.value()); +} + +TEST(TestPropertyTest, SetValue) { + TestProperty property("key", "value_1"); + EXPECT_STREQ("key", property.key()); + property.SetValue("value_2"); + EXPECT_STREQ("key", property.key()); + EXPECT_STREQ("value_2", property.value()); +} + +// Tests the TestPartResult class. + +TEST(TestPartResultTest, ConstructorWorks) { + Message message; + message << "something is terribly wrong"; + message << static_cast(testing::internal::kStackTraceMarker); + message << "some unimportant stack trace"; + + const TestPartResult result(TPRT_NONFATAL_FAILURE, + "some_file.cc", + 42, + message.GetString().c_str()); + + EXPECT_EQ(TPRT_NONFATAL_FAILURE, result.type()); + EXPECT_STREQ("some_file.cc", result.file_name()); + EXPECT_EQ(42, result.line_number()); + EXPECT_STREQ(message.GetString().c_str(), result.message()); + EXPECT_STREQ("something is terribly wrong", result.summary()); +} + +TEST(TestPartResultTest, ResultAccessorsWork) { + const TestPartResult success(TPRT_SUCCESS, "file.cc", 42, "message"); + EXPECT_TRUE(success.passed()); + EXPECT_FALSE(success.failed()); + EXPECT_FALSE(success.nonfatally_failed()); + EXPECT_FALSE(success.fatally_failed()); + + const TestPartResult nonfatal_failure(TPRT_NONFATAL_FAILURE, + "file.cc", + 42, + "message"); + EXPECT_FALSE(nonfatal_failure.passed()); + EXPECT_TRUE(nonfatal_failure.failed()); + EXPECT_TRUE(nonfatal_failure.nonfatally_failed()); + EXPECT_FALSE(nonfatal_failure.fatally_failed()); + + const TestPartResult fatal_failure(TPRT_FATAL_FAILURE, + "file.cc", + 42, + "message"); + EXPECT_FALSE(fatal_failure.passed()); + EXPECT_TRUE(fatal_failure.failed()); + EXPECT_FALSE(fatal_failure.nonfatally_failed()); + EXPECT_TRUE(fatal_failure.fatally_failed()); +} + // Tests the TestResult class // The test fixture for testing TestResult. @@ -1298,34 +1340,6 @@ class TestResultTest : public Test { } }; -// Tests TestResult::total_part_count(). -TEST_F(TestResultTest, test_part_results) { - ASSERT_EQ(0, r0->total_part_count()); - ASSERT_EQ(1, r1->total_part_count()); - ASSERT_EQ(2, r2->total_part_count()); -} - -// Tests TestResult::successful_part_count(). -TEST_F(TestResultTest, successful_part_count) { - ASSERT_EQ(0, r0->successful_part_count()); - ASSERT_EQ(1, r1->successful_part_count()); - ASSERT_EQ(1, r2->successful_part_count()); -} - -// Tests TestResult::failed_part_count(). -TEST_F(TestResultTest, failed_part_count) { - ASSERT_EQ(0, r0->failed_part_count()); - ASSERT_EQ(0, r1->failed_part_count()); - ASSERT_EQ(1, r2->failed_part_count()); -} - -// Tests testing::internal::GetFailedPartCount(). -TEST_F(TestResultTest, GetFailedPartCount) { - ASSERT_EQ(0, GetFailedPartCount(r0)); - ASSERT_EQ(0, GetFailedPartCount(r1)); - ASSERT_EQ(1, GetFailedPartCount(r2)); -} - // Tests TestResult::total_part_count(). TEST_F(TestResultTest, total_part_count) { ASSERT_EQ(0, r0->total_part_count()); @@ -3778,42 +3792,37 @@ TEST(AssertionSyntaxTest, WorksWithConst) { } // namespace -// Returns the number of successful parts in the current test. -static size_t GetSuccessfulPartCount() { - return GetUnitTestImpl()->current_test_result()->successful_part_count(); -} - namespace testing { // Tests that Google Test tracks SUCCEED*. TEST(SuccessfulAssertionTest, SUCCEED) { SUCCEED(); SUCCEED() << "OK"; - EXPECT_EQ(2, GetSuccessfulPartCount()); + EXPECT_EQ(2, GetUnitTestImpl()->current_test_result()->total_part_count()); } // Tests that Google Test doesn't track successful EXPECT_*. TEST(SuccessfulAssertionTest, EXPECT) { EXPECT_TRUE(true); - EXPECT_EQ(0, GetSuccessfulPartCount()); + EXPECT_EQ(0, GetUnitTestImpl()->current_test_result()->total_part_count()); } // Tests that Google Test doesn't track successful EXPECT_STR*. TEST(SuccessfulAssertionTest, EXPECT_STR) { EXPECT_STREQ("", ""); - EXPECT_EQ(0, GetSuccessfulPartCount()); + EXPECT_EQ(0, GetUnitTestImpl()->current_test_result()->total_part_count()); } // Tests that Google Test doesn't track successful ASSERT_*. TEST(SuccessfulAssertionTest, ASSERT) { ASSERT_TRUE(true); - EXPECT_EQ(0, GetSuccessfulPartCount()); + EXPECT_EQ(0, GetUnitTestImpl()->current_test_result()->total_part_count()); } // Tests that Google Test doesn't track successful ASSERT_STR*. TEST(SuccessfulAssertionTest, ASSERT_STR) { ASSERT_STREQ("", ""); - EXPECT_EQ(0, GetSuccessfulPartCount()); + EXPECT_EQ(0, GetUnitTestImpl()->current_test_result()->total_part_count()); } } // namespace testing diff --git a/test/run_tests_test.py b/test/run_tests_test.py index d8bbc362..2582262e 100755 --- a/test/run_tests_test.py +++ b/test/run_tests_test.py @@ -182,9 +182,10 @@ class GetTestsToRunTest(unittest.TestCase): def setUp(self): self.fake_os = FakeOs(FakePath( current_dir=os.path.abspath(os.path.dirname(run_tests.__file__)), - known_paths=[AddExeExtension('scons/build/dbg/scons/gtest_unittest'), - AddExeExtension('scons/build/opt/scons/gtest_unittest'), - 'test/gtest_color_test.py'])) + known_paths=[ + AddExeExtension('scons/build/dbg/gtest/scons/gtest_unittest'), + AddExeExtension('scons/build/opt/gtest/scons/gtest_unittest'), + 'test/gtest_color_test.py'])) self.fake_configurations = ['dbg', 'opt'] self.test_runner = run_tests.TestRunner(injected_os=self.fake_os, injected_subprocess=None, @@ -201,17 +202,19 @@ class GetTestsToRunTest(unittest.TestCase): False, available_configurations=self.fake_configurations), ([], - [('scons/build/dbg/scons', 'scons/build/dbg/scons/gtest_unittest')])) + [('scons/build/dbg/gtest/scons', + 'scons/build/dbg/gtest/scons/gtest_unittest')])) # An explicitly specified directory. self.AssertResultsEqual( self.test_runner.GetTestsToRun( - ['scons/build/dbg/scons', 'gtest_unittest'], + ['scons/build/dbg/gtest/scons', 'gtest_unittest'], '', False, available_configurations=self.fake_configurations), ([], - [('scons/build/dbg/scons', 'scons/build/dbg/scons/gtest_unittest')])) + [('scons/build/dbg/gtest/scons', + 'scons/build/dbg/gtest/scons/gtest_unittest')])) # A particular configuration. self.AssertResultsEqual( @@ -221,8 +224,8 @@ class GetTestsToRunTest(unittest.TestCase): False, available_configurations=self.fake_configurations), ([], - [('scons/build/other/scons', - 'scons/build/other/scons/gtest_unittest')])) + [('scons/build/other/gtest/scons', + 'scons/build/other/gtest/scons/gtest_unittest')])) # All available configurations self.AssertResultsEqual( @@ -232,8 +235,10 @@ class GetTestsToRunTest(unittest.TestCase): False, available_configurations=self.fake_configurations), ([], - [('scons/build/dbg/scons', 'scons/build/dbg/scons/gtest_unittest'), - ('scons/build/opt/scons', 'scons/build/opt/scons/gtest_unittest')])) + [('scons/build/dbg/gtest/scons', + 'scons/build/dbg/gtest/scons/gtest_unittest'), + ('scons/build/opt/gtest/scons', + 'scons/build/opt/gtest/scons/gtest_unittest')])) # All built configurations (unbuilt don't cause failure). self.AssertResultsEqual( @@ -243,40 +248,47 @@ class GetTestsToRunTest(unittest.TestCase): True, available_configurations=self.fake_configurations + ['unbuilt']), ([], - [('scons/build/dbg/scons', 'scons/build/dbg/scons/gtest_unittest'), - ('scons/build/opt/scons', 'scons/build/opt/scons/gtest_unittest')])) + [('scons/build/dbg/gtest/scons', + 'scons/build/dbg/gtest/scons/gtest_unittest'), + ('scons/build/opt/gtest/scons', + 'scons/build/opt/gtest/scons/gtest_unittest')])) # A combination of an explicit directory and a configuration. self.AssertResultsEqual( self.test_runner.GetTestsToRun( - ['scons/build/dbg/scons', 'gtest_unittest'], + ['scons/build/dbg/gtest/scons', 'gtest_unittest'], 'opt', False, available_configurations=self.fake_configurations), ([], - [('scons/build/dbg/scons', 'scons/build/dbg/scons/gtest_unittest'), - ('scons/build/opt/scons', 'scons/build/opt/scons/gtest_unittest')])) + [('scons/build/dbg/gtest/scons', + 'scons/build/dbg/gtest/scons/gtest_unittest'), + ('scons/build/opt/gtest/scons', + 'scons/build/opt/gtest/scons/gtest_unittest')])) # Same test specified in an explicit directory and via a configuration. self.AssertResultsEqual( self.test_runner.GetTestsToRun( - ['scons/build/dbg/scons', 'gtest_unittest'], + ['scons/build/dbg/gtest/scons', 'gtest_unittest'], 'dbg', False, available_configurations=self.fake_configurations), ([], - [('scons/build/dbg/scons', 'scons/build/dbg/scons/gtest_unittest')])) + [('scons/build/dbg/gtest/scons', + 'scons/build/dbg/gtest/scons/gtest_unittest')])) # All built configurations + explicit directory + explicit configuration. self.AssertResultsEqual( self.test_runner.GetTestsToRun( - ['scons/build/dbg/scons', 'gtest_unittest'], + ['scons/build/dbg/gtest/scons', 'gtest_unittest'], 'opt', True, available_configurations=self.fake_configurations), ([], - [('scons/build/dbg/scons', 'scons/build/dbg/scons/gtest_unittest'), - ('scons/build/opt/scons', 'scons/build/opt/scons/gtest_unittest')])) + [('scons/build/dbg/gtest/scons', + 'scons/build/dbg/gtest/scons/gtest_unittest'), + ('scons/build/opt/gtest/scons', + 'scons/build/opt/gtest/scons/gtest_unittest')])) def testPythonTestsOnly(self): """Exercises GetTestsToRun with parameters designating Python tests only.""" @@ -288,17 +300,17 @@ class GetTestsToRunTest(unittest.TestCase): '', False, available_configurations=self.fake_configurations), - ([('scons/build/dbg/scons', 'test/gtest_color_test.py')], + ([('scons/build/dbg/gtest/scons', 'test/gtest_color_test.py')], [])) # An explicitly specified directory. self.AssertResultsEqual( self.test_runner.GetTestsToRun( - ['scons/build/dbg/scons', 'test/gtest_color_test.py'], + ['scons/build/dbg/gtest/scons', 'test/gtest_color_test.py'], '', False, available_configurations=self.fake_configurations), - ([('scons/build/dbg/scons', 'test/gtest_color_test.py')], + ([('scons/build/dbg/gtest/scons', 'test/gtest_color_test.py')], [])) # A particular configuration. @@ -308,7 +320,7 @@ class GetTestsToRunTest(unittest.TestCase): 'other', False, available_configurations=self.fake_configurations), - ([('scons/build/other/scons', 'test/gtest_color_test.py')], + ([('scons/build/other/gtest/scons', 'test/gtest_color_test.py')], [])) # All available configurations @@ -318,8 +330,8 @@ class GetTestsToRunTest(unittest.TestCase): 'all', False, available_configurations=self.fake_configurations), - ([('scons/build/dbg/scons', 'test/gtest_color_test.py'), - ('scons/build/opt/scons', 'test/gtest_color_test.py')], + ([('scons/build/dbg/gtest/scons', 'test/gtest_color_test.py'), + ('scons/build/opt/gtest/scons', 'test/gtest_color_test.py')], [])) # All built configurations (unbuilt don't cause failure). @@ -329,40 +341,40 @@ class GetTestsToRunTest(unittest.TestCase): '', True, available_configurations=self.fake_configurations + ['unbuilt']), - ([('scons/build/dbg/scons', 'test/gtest_color_test.py'), - ('scons/build/opt/scons', 'test/gtest_color_test.py')], + ([('scons/build/dbg/gtest/scons', 'test/gtest_color_test.py'), + ('scons/build/opt/gtest/scons', 'test/gtest_color_test.py')], [])) # A combination of an explicit directory and a configuration. self.AssertResultsEqual( self.test_runner.GetTestsToRun( - ['scons/build/dbg/scons', 'gtest_color_test.py'], + ['scons/build/dbg/gtest/scons', 'gtest_color_test.py'], 'opt', False, available_configurations=self.fake_configurations), - ([('scons/build/dbg/scons', 'test/gtest_color_test.py'), - ('scons/build/opt/scons', 'test/gtest_color_test.py')], + ([('scons/build/dbg/gtest/scons', 'test/gtest_color_test.py'), + ('scons/build/opt/gtest/scons', 'test/gtest_color_test.py')], [])) # Same test specified in an explicit directory and via a configuration. self.AssertResultsEqual( self.test_runner.GetTestsToRun( - ['scons/build/dbg/scons', 'gtest_color_test.py'], + ['scons/build/dbg/gtest/scons', 'gtest_color_test.py'], 'dbg', False, available_configurations=self.fake_configurations), - ([('scons/build/dbg/scons', 'test/gtest_color_test.py')], + ([('scons/build/dbg/gtest/scons', 'test/gtest_color_test.py')], [])) # All built configurations + explicit directory + explicit configuration. self.AssertResultsEqual( self.test_runner.GetTestsToRun( - ['scons/build/dbg/scons', 'gtest_color_test.py'], + ['scons/build/dbg/gtest/scons', 'gtest_color_test.py'], 'opt', True, available_configurations=self.fake_configurations), - ([('scons/build/dbg/scons', 'test/gtest_color_test.py'), - ('scons/build/opt/scons', 'test/gtest_color_test.py')], + ([('scons/build/dbg/gtest/scons', 'test/gtest_color_test.py'), + ('scons/build/opt/gtest/scons', 'test/gtest_color_test.py')], [])) def testCombinationOfBinaryAndPythonTests(self): @@ -377,8 +389,9 @@ class GetTestsToRunTest(unittest.TestCase): '', False, available_configurations=self.fake_configurations), - ([('scons/build/dbg/scons', 'test/gtest_color_test.py')], - [('scons/build/dbg/scons', 'scons/build/dbg/scons/gtest_unittest')])) + ([('scons/build/dbg/gtest/scons', 'test/gtest_color_test.py')], + [('scons/build/dbg/gtest/scons', + 'scons/build/dbg/gtest/scons/gtest_unittest')])) # Specifying both binary and Python tests. self.AssertResultsEqual( @@ -387,8 +400,9 @@ class GetTestsToRunTest(unittest.TestCase): '', False, available_configurations=self.fake_configurations), - ([('scons/build/dbg/scons', 'test/gtest_color_test.py')], - [('scons/build/dbg/scons', 'scons/build/dbg/scons/gtest_unittest')])) + ([('scons/build/dbg/gtest/scons', 'test/gtest_color_test.py')], + [('scons/build/dbg/gtest/scons', + 'scons/build/dbg/gtest/scons/gtest_unittest')])) # Specifying binary tests suppresses Python tests. self.AssertResultsEqual( @@ -398,7 +412,8 @@ class GetTestsToRunTest(unittest.TestCase): False, available_configurations=self.fake_configurations), ([], - [('scons/build/dbg/scons', 'scons/build/dbg/scons/gtest_unittest')])) + [('scons/build/dbg/gtest/scons', + 'scons/build/dbg/gtest/scons/gtest_unittest')])) # Specifying Python tests suppresses binary tests. self.AssertResultsEqual( @@ -407,7 +422,7 @@ class GetTestsToRunTest(unittest.TestCase): '', False, available_configurations=self.fake_configurations), - ([('scons/build/dbg/scons', 'test/gtest_color_test.py')], + ([('scons/build/dbg/gtest/scons', 'test/gtest_color_test.py')], [])) def testIgnoresNonTestFiles(self): @@ -415,8 +430,9 @@ class GetTestsToRunTest(unittest.TestCase): self.fake_os = FakeOs(FakePath( current_dir=os.path.abspath(os.path.dirname(run_tests.__file__)), - known_paths=[AddExeExtension('scons/build/dbg/scons/gtest_nontest'), - 'test/'])) + known_paths=[ + AddExeExtension('scons/build/dbg/gtest/scons/gtest_nontest'), + 'test/'])) self.test_runner = run_tests.TestRunner(injected_os=self.fake_os, injected_subprocess=None, injected_script_dir='.') @@ -435,10 +451,11 @@ class GetTestsToRunTest(unittest.TestCase): # directory /a/b/c/. self.fake_os = FakeOs(FakePath( current_dir=os.path.abspath('/a/b/c'), - known_paths=['/a/b/c/', - AddExeExtension('/d/scons/build/dbg/scons/gtest_unittest'), - AddExeExtension('/d/scons/build/opt/scons/gtest_unittest'), - '/d/test/gtest_color_test.py'])) + known_paths=[ + '/a/b/c/', + AddExeExtension('/d/scons/build/dbg/gtest/scons/gtest_unittest'), + AddExeExtension('/d/scons/build/opt/gtest/scons/gtest_unittest'), + '/d/test/gtest_color_test.py'])) self.fake_configurations = ['dbg', 'opt'] self.test_runner = run_tests.TestRunner(injected_os=self.fake_os, injected_subprocess=None, @@ -451,8 +468,8 @@ class GetTestsToRunTest(unittest.TestCase): False, available_configurations=self.fake_configurations), ([], - [('/d/scons/build/dbg/scons', - '/d/scons/build/dbg/scons/gtest_unittest')])) + [('/d/scons/build/dbg/gtest/scons', + '/d/scons/build/dbg/gtest/scons/gtest_unittest')])) # A Python test. self.AssertResultsEqual( @@ -461,7 +478,7 @@ class GetTestsToRunTest(unittest.TestCase): '', False, available_configurations=self.fake_configurations), - ([('/d/scons/build/dbg/scons', '/d/test/gtest_color_test.py')], + ([('/d/scons/build/dbg/gtest/scons', '/d/test/gtest_color_test.py')], [])) @@ -491,7 +508,7 @@ class GetTestsToRunTest(unittest.TestCase): self.fake_os = FakeOs(FakePath( current_dir=os.path.abspath(os.path.dirname(run_tests.__file__)), - known_paths=['scons/build/dbg/scons/gtest_test', 'test/'])) + known_paths=['scons/build/dbg/gtest/scons/gtest_test', 'test/'])) self.test_runner = run_tests.TestRunner(injected_os=self.fake_os, injected_subprocess=None, injected_script_dir='.') @@ -522,9 +539,10 @@ class RunTestsTest(unittest.TestCase): def setUp(self): self.fake_os = FakeOs(FakePath( current_dir=os.path.abspath(os.path.dirname(run_tests.__file__)), - known_paths=[AddExeExtension('scons/build/dbg/scons/gtest_unittest'), - AddExeExtension('scons/build/opt/scons/gtest_unittest'), - 'test/gtest_color_test.py'])) + known_paths=[ + AddExeExtension('scons/build/dbg/gtest/scons/gtest_unittest'), + AddExeExtension('scons/build/opt/gtest/scons/gtest_unittest'), + 'test/gtest_color_test.py'])) self.fake_configurations = ['dbg', 'opt'] self.test_runner = run_tests.TestRunner(injected_os=self.fake_os, injected_subprocess=None) @@ -536,7 +554,7 @@ class RunTestsTest(unittest.TestCase): self.fake_os.spawn_impl = self.SpawnSuccess self.assertEqual( self.test_runner.RunTests( - [('scons/build/dbg/scons', 'test/gtest_color_test.py')], + [('scons/build/dbg/gtest/scons', 'test/gtest_color_test.py')], []), 0) self.assertEqual(self.num_spawn_calls, 1) @@ -548,8 +566,8 @@ class RunTestsTest(unittest.TestCase): self.assertEqual( self.test_runner.RunTests( [], - [('scons/build/dbg/scons', - 'scons/build/dbg/scons/gtest_unittest')]), + [('scons/build/dbg/gtest/scons', + 'scons/build/dbg/gtest/scons/gtest_unittest')]), 0) self.assertEqual(self.num_spawn_calls, 1) @@ -559,7 +577,7 @@ class RunTestsTest(unittest.TestCase): self.fake_os.spawn_impl = self.SpawnFailure self.assertEqual( self.test_runner.RunTests( - [('scons/build/dbg/scons', 'test/gtest_color_test.py')], + [('scons/build/dbg/gtest/scons', 'test/gtest_color_test.py')], []), 1) self.assertEqual(self.num_spawn_calls, 1) @@ -571,8 +589,8 @@ class RunTestsTest(unittest.TestCase): self.assertEqual( self.test_runner.RunTests( [], - [('scons/build/dbg/scons', - 'scons/build/dbg/scons/gtest_unittest')]), + [('scons/build/dbg/gtest/scons', + 'scons/build/dbg/gtest/scons/gtest_unittest')]), 1) self.assertEqual(self.num_spawn_calls, 1) @@ -582,9 +600,10 @@ class RunTestsTest(unittest.TestCase): self.fake_os.spawn_impl = self.SpawnSuccess self.assertEqual( self.test_runner.RunTests( - [('scons/build/dbg/scons', 'scons/build/dbg/scons/gtest_unittest')], - [('scons/build/dbg/scons', - 'scons/build/dbg/scons/gtest_unittest')]), + [('scons/build/dbg/gtest/scons', + 'scons/build/dbg/gtest/scons/gtest_unittest')], + [('scons/build/dbg/gtest/scons', + 'scons/build/dbg/gtest/scons/gtest_unittest')]), 0) self.assertEqual(self.num_spawn_calls, 2) @@ -602,9 +621,10 @@ class RunTestsTest(unittest.TestCase): self.fake_os.spawn_impl = SpawnImpl self.assertEqual( self.test_runner.RunTests( - [('scons/build/dbg/scons', 'scons/build/dbg/scons/gtest_unittest')], - [('scons/build/dbg/scons', - 'scons/build/dbg/scons/gtest_unittest')]), + [('scons/build/dbg/gtest/scons', + 'scons/build/dbg/gtest/scons/gtest_unittest')], + [('scons/build/dbg/gtest/scons', + 'scons/build/dbg/gtest/scons/gtest_unittest')]), 0) self.assertEqual(self.num_spawn_calls, 2) -- cgit v1.2.3 From 16b9431ae01d83de80db7ef3e411d9771ee845e4 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Wed, 22 Jul 2009 02:16:37 +0000 Subject: Makes gtest compile clean with gcc -Wall -Werror (by Zhanyong Wan); refactors scons script (by Vlad Losev). --- test/gtest-death-test_test.cc | 6 +- test/gtest-port_test.cc | 8 +- test/gtest-typed-test_test.cc | 4 +- test/gtest-typed-test_test.h | 2 +- test/gtest_output_test_.cc | 4 +- test/gtest_output_test_golden_lin.txt | 6 +- test/gtest_output_test_golden_win.txt | 6 +- test/run_tests_test.py | 147 +++++++++++++++------------------- 8 files changed, 84 insertions(+), 99 deletions(-) (limited to 'test') diff --git a/test/gtest-death-test_test.cc b/test/gtest-death-test_test.cc index e9317e17..d5f1598a 100644 --- a/test/gtest-death-test_test.cc +++ b/test/gtest-death-test_test.cc @@ -1057,16 +1057,16 @@ TEST(ParseNaturalNumberTest, AcceptsValidNumbers) { result = 0; ASSERT_TRUE(ParseNaturalNumber(String("123"), &result)); - EXPECT_EQ(123, result); + EXPECT_EQ(123U, result); // Check 0 as an edge case. result = 1; ASSERT_TRUE(ParseNaturalNumber(String("0"), &result)); - EXPECT_EQ(0, result); + EXPECT_EQ(0U, result); result = 1; ASSERT_TRUE(ParseNaturalNumber(String("00000"), &result)); - EXPECT_EQ(0, result); + EXPECT_EQ(0U, result); } TEST(ParseNaturalNumberTest, AcceptsTypeLimits) { diff --git a/test/gtest-port_test.cc b/test/gtest-port_test.cc index 37880a7f..49af8b9b 100644 --- a/test/gtest-port_test.cc +++ b/test/gtest-port_test.cc @@ -91,7 +91,7 @@ void* ThreadFunc(void* data) { } TEST(GetThreadCountTest, ReturnsCorrectValue) { - EXPECT_EQ(1, GetThreadCount()); + EXPECT_EQ(1U, GetThreadCount()); pthread_mutex_t mutex; pthread_attr_t attr; pthread_t thread_id; @@ -106,7 +106,7 @@ TEST(GetThreadCountTest, ReturnsCorrectValue) { const int status = pthread_create(&thread_id, &attr, &ThreadFunc, &mutex); ASSERT_EQ(0, pthread_attr_destroy(&attr)); ASSERT_EQ(0, status); - EXPECT_EQ(2, GetThreadCount()); + EXPECT_EQ(2U, GetThreadCount()); pthread_mutex_unlock(&mutex); void* dummy; @@ -124,12 +124,12 @@ TEST(GetThreadCountTest, ReturnsCorrectValue) { time.tv_nsec = 100L * 1000 * 1000; // .1 seconds. nanosleep(&time, NULL); } - EXPECT_EQ(1, GetThreadCount()); + EXPECT_EQ(1U, GetThreadCount()); pthread_mutex_destroy(&mutex); } #else TEST(GetThreadCountTest, ReturnsZeroWhenUnableToCountThreads) { - EXPECT_EQ(0, GetThreadCount()); + EXPECT_EQ(0U, GetThreadCount()); } #endif // GTEST_OS_MAC diff --git a/test/gtest-typed-test_test.cc b/test/gtest-typed-test_test.cc index eb921a06..8e86ac8c 100644 --- a/test/gtest-typed-test_test.cc +++ b/test/gtest-typed-test_test.cc @@ -100,10 +100,10 @@ TYPED_TEST(CommonTest, ValuesAreCorrect) { // Typedefs in the fixture class template can be visited via the // "typename TestFixture::" prefix. typename TestFixture::List empty; - EXPECT_EQ(0, empty.size()); + EXPECT_EQ(0U, empty.size()); typename TestFixture::IntSet empty2; - EXPECT_EQ(0, empty2.size()); + EXPECT_EQ(0U, empty2.size()); // Non-static members of the fixture class must be visited via // 'this', as required by C++ for class templates. diff --git a/test/gtest-typed-test_test.h b/test/gtest-typed-test_test.h index ecbe5b31..40dfeac6 100644 --- a/test/gtest-typed-test_test.h +++ b/test/gtest-typed-test_test.h @@ -55,7 +55,7 @@ TYPED_TEST_P(ContainerTest, CanBeDefaultConstructed) { TYPED_TEST_P(ContainerTest, InitialSizeIsZero) { TypeParam container; - EXPECT_EQ(0, container.size()); + EXPECT_EQ(0U, container.size()); } REGISTER_TYPED_TEST_CASE_P(ContainerTest, diff --git a/test/gtest_output_test_.cc b/test/gtest_output_test_.cc index 693df3f5..6d756027 100644 --- a/test/gtest_output_test_.cc +++ b/test/gtest_output_test_.cc @@ -743,11 +743,11 @@ class TypedTestP : public testing::Test { TYPED_TEST_CASE_P(TypedTestP); TYPED_TEST_P(TypedTestP, Success) { - EXPECT_EQ(0, TypeParam()); + EXPECT_EQ(0U, TypeParam()); } TYPED_TEST_P(TypedTestP, Failure) { - EXPECT_EQ(1, TypeParam()) << "Expected failure"; + EXPECT_EQ(1U, TypeParam()) << "Expected failure"; } REGISTER_TYPED_TEST_CASE_P(TypedTestP, Success, Failure); diff --git a/test/gtest_output_test_golden_lin.txt b/test/gtest_output_test_golden_lin.txt index 46a90fb5..51bae52d 100644 --- a/test/gtest_output_test_golden_lin.txt +++ b/test/gtest_output_test_golden_lin.txt @@ -390,7 +390,8 @@ Expected failure gtest_output_test_.cc:#: Failure Value of: TypeParam() Actual: \0 -Expected: 1 +Expected: 1U +Which is: 1 Expected failure [ FAILED ] Unsigned/TypedTestP/0.Failure [----------] 2 tests from Unsigned/TypedTestP/1, where TypeParam = unsigned int @@ -400,7 +401,8 @@ Expected failure gtest_output_test_.cc:#: Failure Value of: TypeParam() Actual: 0 -Expected: 1 +Expected: 1U +Which is: 1 Expected failure [ FAILED ] Unsigned/TypedTestP/1.Failure [----------] 4 tests from ExpectFailureTest diff --git a/test/gtest_output_test_golden_win.txt b/test/gtest_output_test_golden_win.txt index 92fe7f41..313c3aaf 100644 --- a/test/gtest_output_test_golden_win.txt +++ b/test/gtest_output_test_golden_win.txt @@ -376,7 +376,8 @@ Expected failure [ RUN ] Unsigned/TypedTestP/0.Failure gtest_output_test_.cc:#: error: Value of: TypeParam() Actual: \0 -Expected: 1 +Expected: 1U +Which is: 1 Expected failure [ FAILED ] Unsigned/TypedTestP/0.Failure [----------] 2 tests from Unsigned/TypedTestP/1, where TypeParam = unsigned int @@ -385,7 +386,8 @@ Expected failure [ RUN ] Unsigned/TypedTestP/1.Failure gtest_output_test_.cc:#: error: Value of: TypeParam() Actual: 0 -Expected: 1 +Expected: 1U +Which is: 1 Expected failure [ FAILED ] Unsigned/TypedTestP/1.Failure [----------] 4 tests from ExpectFailureTest diff --git a/test/run_tests_test.py b/test/run_tests_test.py index 2582262e..79524a68 100755 --- a/test/run_tests_test.py +++ b/test/run_tests_test.py @@ -41,6 +41,12 @@ import unittest sys.path.append(os.path.join(os.path.dirname(sys.argv[0]), os.pardir)) import run_tests + +GTEST_DBG_DIR = 'scons/build/dbg/scons' +GTEST_OPT_DIR = 'scons/build/opt/scons' +GTEST_OTHER_DIR = 'scons/build/other/scons' + + def AddExeExtension(path): """Appends .exe to the path on Windows or Cygwin.""" @@ -182,10 +188,9 @@ class GetTestsToRunTest(unittest.TestCase): def setUp(self): self.fake_os = FakeOs(FakePath( current_dir=os.path.abspath(os.path.dirname(run_tests.__file__)), - known_paths=[ - AddExeExtension('scons/build/dbg/gtest/scons/gtest_unittest'), - AddExeExtension('scons/build/opt/gtest/scons/gtest_unittest'), - 'test/gtest_color_test.py'])) + known_paths=[AddExeExtension(GTEST_DBG_DIR + '/gtest_unittest'), + AddExeExtension(GTEST_OPT_DIR + '/gtest_unittest'), + 'test/gtest_color_test.py'])) self.fake_configurations = ['dbg', 'opt'] self.test_runner = run_tests.TestRunner(injected_os=self.fake_os, injected_subprocess=None, @@ -202,19 +207,17 @@ class GetTestsToRunTest(unittest.TestCase): False, available_configurations=self.fake_configurations), ([], - [('scons/build/dbg/gtest/scons', - 'scons/build/dbg/gtest/scons/gtest_unittest')])) + [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest')])) # An explicitly specified directory. self.AssertResultsEqual( self.test_runner.GetTestsToRun( - ['scons/build/dbg/gtest/scons', 'gtest_unittest'], + [GTEST_DBG_DIR, 'gtest_unittest'], '', False, available_configurations=self.fake_configurations), ([], - [('scons/build/dbg/gtest/scons', - 'scons/build/dbg/gtest/scons/gtest_unittest')])) + [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest')])) # A particular configuration. self.AssertResultsEqual( @@ -224,8 +227,7 @@ class GetTestsToRunTest(unittest.TestCase): False, available_configurations=self.fake_configurations), ([], - [('scons/build/other/gtest/scons', - 'scons/build/other/gtest/scons/gtest_unittest')])) + [(GTEST_OTHER_DIR, GTEST_OTHER_DIR + '/gtest_unittest')])) # All available configurations self.AssertResultsEqual( @@ -235,10 +237,8 @@ class GetTestsToRunTest(unittest.TestCase): False, available_configurations=self.fake_configurations), ([], - [('scons/build/dbg/gtest/scons', - 'scons/build/dbg/gtest/scons/gtest_unittest'), - ('scons/build/opt/gtest/scons', - 'scons/build/opt/gtest/scons/gtest_unittest')])) + [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest'), + (GTEST_OPT_DIR, GTEST_OPT_DIR + '/gtest_unittest')])) # All built configurations (unbuilt don't cause failure). self.AssertResultsEqual( @@ -248,47 +248,40 @@ class GetTestsToRunTest(unittest.TestCase): True, available_configurations=self.fake_configurations + ['unbuilt']), ([], - [('scons/build/dbg/gtest/scons', - 'scons/build/dbg/gtest/scons/gtest_unittest'), - ('scons/build/opt/gtest/scons', - 'scons/build/opt/gtest/scons/gtest_unittest')])) + [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest'), + (GTEST_OPT_DIR, GTEST_OPT_DIR + '/gtest_unittest')])) # A combination of an explicit directory and a configuration. self.AssertResultsEqual( self.test_runner.GetTestsToRun( - ['scons/build/dbg/gtest/scons', 'gtest_unittest'], + [GTEST_DBG_DIR, 'gtest_unittest'], 'opt', False, available_configurations=self.fake_configurations), ([], - [('scons/build/dbg/gtest/scons', - 'scons/build/dbg/gtest/scons/gtest_unittest'), - ('scons/build/opt/gtest/scons', - 'scons/build/opt/gtest/scons/gtest_unittest')])) + [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest'), + (GTEST_OPT_DIR, GTEST_OPT_DIR + '/gtest_unittest')])) # Same test specified in an explicit directory and via a configuration. self.AssertResultsEqual( self.test_runner.GetTestsToRun( - ['scons/build/dbg/gtest/scons', 'gtest_unittest'], + [GTEST_DBG_DIR, 'gtest_unittest'], 'dbg', False, available_configurations=self.fake_configurations), ([], - [('scons/build/dbg/gtest/scons', - 'scons/build/dbg/gtest/scons/gtest_unittest')])) + [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest')])) # All built configurations + explicit directory + explicit configuration. self.AssertResultsEqual( self.test_runner.GetTestsToRun( - ['scons/build/dbg/gtest/scons', 'gtest_unittest'], + [GTEST_DBG_DIR, 'gtest_unittest'], 'opt', True, available_configurations=self.fake_configurations), ([], - [('scons/build/dbg/gtest/scons', - 'scons/build/dbg/gtest/scons/gtest_unittest'), - ('scons/build/opt/gtest/scons', - 'scons/build/opt/gtest/scons/gtest_unittest')])) + [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest'), + (GTEST_OPT_DIR, GTEST_OPT_DIR + '/gtest_unittest')])) def testPythonTestsOnly(self): """Exercises GetTestsToRun with parameters designating Python tests only.""" @@ -300,17 +293,17 @@ class GetTestsToRunTest(unittest.TestCase): '', False, available_configurations=self.fake_configurations), - ([('scons/build/dbg/gtest/scons', 'test/gtest_color_test.py')], + ([(GTEST_DBG_DIR, 'test/gtest_color_test.py')], [])) # An explicitly specified directory. self.AssertResultsEqual( self.test_runner.GetTestsToRun( - ['scons/build/dbg/gtest/scons', 'test/gtest_color_test.py'], + [GTEST_DBG_DIR, 'test/gtest_color_test.py'], '', False, available_configurations=self.fake_configurations), - ([('scons/build/dbg/gtest/scons', 'test/gtest_color_test.py')], + ([(GTEST_DBG_DIR, 'test/gtest_color_test.py')], [])) # A particular configuration. @@ -320,7 +313,7 @@ class GetTestsToRunTest(unittest.TestCase): 'other', False, available_configurations=self.fake_configurations), - ([('scons/build/other/gtest/scons', 'test/gtest_color_test.py')], + ([(GTEST_OTHER_DIR, 'test/gtest_color_test.py')], [])) # All available configurations @@ -330,8 +323,8 @@ class GetTestsToRunTest(unittest.TestCase): 'all', False, available_configurations=self.fake_configurations), - ([('scons/build/dbg/gtest/scons', 'test/gtest_color_test.py'), - ('scons/build/opt/gtest/scons', 'test/gtest_color_test.py')], + ([(GTEST_DBG_DIR, 'test/gtest_color_test.py'), + (GTEST_OPT_DIR, 'test/gtest_color_test.py')], [])) # All built configurations (unbuilt don't cause failure). @@ -341,40 +334,40 @@ class GetTestsToRunTest(unittest.TestCase): '', True, available_configurations=self.fake_configurations + ['unbuilt']), - ([('scons/build/dbg/gtest/scons', 'test/gtest_color_test.py'), - ('scons/build/opt/gtest/scons', 'test/gtest_color_test.py')], + ([(GTEST_DBG_DIR, 'test/gtest_color_test.py'), + (GTEST_OPT_DIR, 'test/gtest_color_test.py')], [])) # A combination of an explicit directory and a configuration. self.AssertResultsEqual( self.test_runner.GetTestsToRun( - ['scons/build/dbg/gtest/scons', 'gtest_color_test.py'], + [GTEST_DBG_DIR, 'gtest_color_test.py'], 'opt', False, available_configurations=self.fake_configurations), - ([('scons/build/dbg/gtest/scons', 'test/gtest_color_test.py'), - ('scons/build/opt/gtest/scons', 'test/gtest_color_test.py')], + ([(GTEST_DBG_DIR, 'test/gtest_color_test.py'), + (GTEST_OPT_DIR, 'test/gtest_color_test.py')], [])) # Same test specified in an explicit directory and via a configuration. self.AssertResultsEqual( self.test_runner.GetTestsToRun( - ['scons/build/dbg/gtest/scons', 'gtest_color_test.py'], + [GTEST_DBG_DIR, 'gtest_color_test.py'], 'dbg', False, available_configurations=self.fake_configurations), - ([('scons/build/dbg/gtest/scons', 'test/gtest_color_test.py')], + ([(GTEST_DBG_DIR, 'test/gtest_color_test.py')], [])) # All built configurations + explicit directory + explicit configuration. self.AssertResultsEqual( self.test_runner.GetTestsToRun( - ['scons/build/dbg/gtest/scons', 'gtest_color_test.py'], + [GTEST_DBG_DIR, 'gtest_color_test.py'], 'opt', True, available_configurations=self.fake_configurations), - ([('scons/build/dbg/gtest/scons', 'test/gtest_color_test.py'), - ('scons/build/opt/gtest/scons', 'test/gtest_color_test.py')], + ([(GTEST_DBG_DIR, 'test/gtest_color_test.py'), + (GTEST_OPT_DIR, 'test/gtest_color_test.py')], [])) def testCombinationOfBinaryAndPythonTests(self): @@ -389,9 +382,8 @@ class GetTestsToRunTest(unittest.TestCase): '', False, available_configurations=self.fake_configurations), - ([('scons/build/dbg/gtest/scons', 'test/gtest_color_test.py')], - [('scons/build/dbg/gtest/scons', - 'scons/build/dbg/gtest/scons/gtest_unittest')])) + ([(GTEST_DBG_DIR, 'test/gtest_color_test.py')], + [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest')])) # Specifying both binary and Python tests. self.AssertResultsEqual( @@ -400,9 +392,8 @@ class GetTestsToRunTest(unittest.TestCase): '', False, available_configurations=self.fake_configurations), - ([('scons/build/dbg/gtest/scons', 'test/gtest_color_test.py')], - [('scons/build/dbg/gtest/scons', - 'scons/build/dbg/gtest/scons/gtest_unittest')])) + ([(GTEST_DBG_DIR, 'test/gtest_color_test.py')], + [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest')])) # Specifying binary tests suppresses Python tests. self.AssertResultsEqual( @@ -412,8 +403,7 @@ class GetTestsToRunTest(unittest.TestCase): False, available_configurations=self.fake_configurations), ([], - [('scons/build/dbg/gtest/scons', - 'scons/build/dbg/gtest/scons/gtest_unittest')])) + [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest')])) # Specifying Python tests suppresses binary tests. self.AssertResultsEqual( @@ -422,7 +412,7 @@ class GetTestsToRunTest(unittest.TestCase): '', False, available_configurations=self.fake_configurations), - ([('scons/build/dbg/gtest/scons', 'test/gtest_color_test.py')], + ([(GTEST_DBG_DIR, 'test/gtest_color_test.py')], [])) def testIgnoresNonTestFiles(self): @@ -430,9 +420,8 @@ class GetTestsToRunTest(unittest.TestCase): self.fake_os = FakeOs(FakePath( current_dir=os.path.abspath(os.path.dirname(run_tests.__file__)), - known_paths=[ - AddExeExtension('scons/build/dbg/gtest/scons/gtest_nontest'), - 'test/'])) + known_paths=[AddExeExtension(GTEST_DBG_DIR + '/gtest_nontest'), + 'test/'])) self.test_runner = run_tests.TestRunner(injected_os=self.fake_os, injected_subprocess=None, injected_script_dir='.') @@ -453,8 +442,8 @@ class GetTestsToRunTest(unittest.TestCase): current_dir=os.path.abspath('/a/b/c'), known_paths=[ '/a/b/c/', - AddExeExtension('/d/scons/build/dbg/gtest/scons/gtest_unittest'), - AddExeExtension('/d/scons/build/opt/gtest/scons/gtest_unittest'), + AddExeExtension('/d/' + GTEST_DBG_DIR + '/gtest_unittest'), + AddExeExtension('/d/' + GTEST_OPT_DIR + '/gtest_unittest'), '/d/test/gtest_color_test.py'])) self.fake_configurations = ['dbg', 'opt'] self.test_runner = run_tests.TestRunner(injected_os=self.fake_os, @@ -468,8 +457,7 @@ class GetTestsToRunTest(unittest.TestCase): False, available_configurations=self.fake_configurations), ([], - [('/d/scons/build/dbg/gtest/scons', - '/d/scons/build/dbg/gtest/scons/gtest_unittest')])) + [('/d/' + GTEST_DBG_DIR, '/d/' + GTEST_DBG_DIR + '/gtest_unittest')])) # A Python test. self.AssertResultsEqual( @@ -478,8 +466,7 @@ class GetTestsToRunTest(unittest.TestCase): '', False, available_configurations=self.fake_configurations), - ([('/d/scons/build/dbg/gtest/scons', '/d/test/gtest_color_test.py')], - [])) + ([('/d/' + GTEST_DBG_DIR, '/d/test/gtest_color_test.py')], [])) def testNonTestBinary(self): @@ -508,7 +495,7 @@ class GetTestsToRunTest(unittest.TestCase): self.fake_os = FakeOs(FakePath( current_dir=os.path.abspath(os.path.dirname(run_tests.__file__)), - known_paths=['scons/build/dbg/gtest/scons/gtest_test', 'test/'])) + known_paths=['/d/' + GTEST_DBG_DIR + '/gtest_test', 'test/'])) self.test_runner = run_tests.TestRunner(injected_os=self.fake_os, injected_subprocess=None, injected_script_dir='.') @@ -540,8 +527,8 @@ class RunTestsTest(unittest.TestCase): self.fake_os = FakeOs(FakePath( current_dir=os.path.abspath(os.path.dirname(run_tests.__file__)), known_paths=[ - AddExeExtension('scons/build/dbg/gtest/scons/gtest_unittest'), - AddExeExtension('scons/build/opt/gtest/scons/gtest_unittest'), + AddExeExtension(GTEST_DBG_DIR + '/gtest_unittest'), + AddExeExtension(GTEST_OPT_DIR + '/gtest_unittest'), 'test/gtest_color_test.py'])) self.fake_configurations = ['dbg', 'opt'] self.test_runner = run_tests.TestRunner(injected_os=self.fake_os, @@ -554,7 +541,7 @@ class RunTestsTest(unittest.TestCase): self.fake_os.spawn_impl = self.SpawnSuccess self.assertEqual( self.test_runner.RunTests( - [('scons/build/dbg/gtest/scons', 'test/gtest_color_test.py')], + [(GTEST_DBG_DIR, 'test/gtest_color_test.py')], []), 0) self.assertEqual(self.num_spawn_calls, 1) @@ -566,8 +553,7 @@ class RunTestsTest(unittest.TestCase): self.assertEqual( self.test_runner.RunTests( [], - [('scons/build/dbg/gtest/scons', - 'scons/build/dbg/gtest/scons/gtest_unittest')]), + [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest')]), 0) self.assertEqual(self.num_spawn_calls, 1) @@ -577,7 +563,7 @@ class RunTestsTest(unittest.TestCase): self.fake_os.spawn_impl = self.SpawnFailure self.assertEqual( self.test_runner.RunTests( - [('scons/build/dbg/gtest/scons', 'test/gtest_color_test.py')], + [(GTEST_DBG_DIR, 'test/gtest_color_test.py')], []), 1) self.assertEqual(self.num_spawn_calls, 1) @@ -589,8 +575,7 @@ class RunTestsTest(unittest.TestCase): self.assertEqual( self.test_runner.RunTests( [], - [('scons/build/dbg/gtest/scons', - 'scons/build/dbg/gtest/scons/gtest_unittest')]), + [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest')]), 1) self.assertEqual(self.num_spawn_calls, 1) @@ -600,10 +585,8 @@ class RunTestsTest(unittest.TestCase): self.fake_os.spawn_impl = self.SpawnSuccess self.assertEqual( self.test_runner.RunTests( - [('scons/build/dbg/gtest/scons', - 'scons/build/dbg/gtest/scons/gtest_unittest')], - [('scons/build/dbg/gtest/scons', - 'scons/build/dbg/gtest/scons/gtest_unittest')]), + [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest')], + [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest')]), 0) self.assertEqual(self.num_spawn_calls, 2) @@ -621,10 +604,8 @@ class RunTestsTest(unittest.TestCase): self.fake_os.spawn_impl = SpawnImpl self.assertEqual( self.test_runner.RunTests( - [('scons/build/dbg/gtest/scons', - 'scons/build/dbg/gtest/scons/gtest_unittest')], - [('scons/build/dbg/gtest/scons', - 'scons/build/dbg/gtest/scons/gtest_unittest')]), + [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest')], + [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest')]), 0) self.assertEqual(self.num_spawn_calls, 2) -- cgit v1.2.3 From ed8500b341c473ecf46acd13951ae5b4e3acc780 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Fri, 7 Aug 2009 06:47:47 +0000 Subject: Implements EXPECT_DEATH_IF_SUPPORTED (by Vlad Losev); Fixes compatibility with Symbian (by Araceli Checa); Removes GetCapturedStderr()'s dependency on std::string (by Vlad Losev). --- test/gtest-death-test_test.cc | 38 +++++++++++++++++++++++++++++++++++++ test/gtest-port_test.cc | 6 +----- test/gtest_unittest.cc | 44 +++++++++++++++---------------------------- 3 files changed, 54 insertions(+), 34 deletions(-) (limited to 'test') diff --git a/test/gtest-death-test_test.cc b/test/gtest-death-test_test.cc index d5f1598a..18811391 100644 --- a/test/gtest-death-test_test.cc +++ b/test/gtest-death-test_test.cc @@ -1118,6 +1118,44 @@ TEST(EnvironmentTest, HandleFitsIntoSizeT) { } #endif // GTEST_OS_WINDOWS +// Tests that EXPECT_DEATH_IF_SUPPORTED/ASSERT_DEATH_IF_SUPPORTED trigger +// failures when death tests are available on the system. +TEST(ConditionalDeathMacrosDeathTest, ExpectsDeathWhenDeathTestsAvailable) { + EXPECT_DEATH_IF_SUPPORTED(GTEST_CHECK_(false) << "failure", "false.*failure"); + ASSERT_DEATH_IF_SUPPORTED(GTEST_CHECK_(false) << "failure", "false.*failure"); + + // Empty statement will not crash, which must trigger a failure. + EXPECT_NONFATAL_FAILURE(EXPECT_DEATH_IF_SUPPORTED(;, ""), ""); + EXPECT_FATAL_FAILURE(ASSERT_DEATH_IF_SUPPORTED(;, ""), ""); +} + +#else + +using testing::internal::CaptureStderr; +using testing::internal::GetCapturedStderr; +using testing::internal::String; + +// Tests that EXPECT_DEATH_IF_SUPPORTED/ASSERT_DEATH_IF_SUPPORTED are still +// defined but do not rigger failures when death tests are not available on +// the system. +TEST(ConditionalDeathMacrosTest, WarnsWhenDeathTestsNotAvailable) { + // Empty statement will not crash, but that should not trigger a failure + // when death tests are not supported. + CaptureStderr(); + EXPECT_DEATH_IF_SUPPORTED(;, ""); + String output = GetCapturedStderr(); + ASSERT_TRUE(NULL != strstr(output.c_str(), + "Death tests are not supported on this platform")); + ASSERT_TRUE(NULL != strstr(output.c_str(), ";")); + + CaptureStderr(); + ASSERT_DEATH_IF_SUPPORTED(;, ""); + output = GetCapturedStderr(); + ASSERT_TRUE(NULL != strstr(output.c_str(), + "Death tests are not supported on this platform")); + ASSERT_TRUE(NULL != strstr(output.c_str(), ";")); +} + #endif // GTEST_HAS_DEATH_TEST // Tests that a test case whose name ends with "DeathTest" works fine diff --git a/test/gtest-port_test.cc b/test/gtest-port_test.cc index 49af8b9b..d980b7ce 100644 --- a/test/gtest-port_test.cc +++ b/test/gtest-port_test.cc @@ -688,15 +688,11 @@ TEST(RETest, PartialMatchWorks) { #endif // GTEST_USES_POSIX_RE -#if GTEST_HAS_STD_STRING - TEST(CaptureStderrTest, CapturesStdErr) { CaptureStderr(); fprintf(stderr, "abc"); - ASSERT_EQ("abc", GetCapturedStderr()); + ASSERT_STREQ("abc", GetCapturedStderr().c_str()); } -#endif // GTEST_HAS_STD_STRING - } // namespace internal } // namespace testing diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index 4eb098e7..2c087209 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -78,16 +78,6 @@ TEST(CommandLineFlagsTest, CanBeAccessedInCodeOnceGTestHIsIncluded) { #include #endif -// GTEST_EXPECT_DEATH_IF_SUPPORTED_(statement, regex) expands to a -// real death test if death tests are supported; otherwise it expands -// to empty. -#if GTEST_HAS_DEATH_TEST -#define GTEST_EXPECT_DEATH_IF_SUPPORTED_(statement, regex) \ - EXPECT_DEATH(statement, regex) -#else -#define GTEST_EXPECT_DEATH_IF_SUPPORTED_(statement, regex) -#endif - namespace testing { namespace internal { const char* FormatTimeInMillisAsSeconds(TimeInMillis ms); @@ -630,7 +620,7 @@ TEST(VectorDeathTest, Erase) { Vector a; // Tests erasing from an empty vector. - GTEST_EXPECT_DEATH_IF_SUPPORTED_( + EXPECT_DEATH_IF_SUPPORTED( a.Erase(0), "Invalid Vector index 0: must be in range \\[0, -1\\]\\."); @@ -646,10 +636,10 @@ TEST(VectorDeathTest, Erase) { a1.PushBack(1); a1.PushBack(2); - GTEST_EXPECT_DEATH_IF_SUPPORTED_( + EXPECT_DEATH_IF_SUPPORTED( a1.Erase(3), "Invalid Vector index 3: must be in range \\[0, 2\\]\\."); - GTEST_EXPECT_DEATH_IF_SUPPORTED_( + EXPECT_DEATH_IF_SUPPORTED( a1.Erase(-1), "Invalid Vector index -1: must be in range \\[0, 2\\]\\."); @@ -697,10 +687,10 @@ TEST(ListDeathTest, GetElement) { EXPECT_EQ(0, a.GetElement(0)); EXPECT_EQ(1, a.GetElement(1)); EXPECT_EQ(2, a.GetElement(2)); - GTEST_EXPECT_DEATH_IF_SUPPORTED_( + EXPECT_DEATH_IF_SUPPORTED( a.GetElement(3), "Invalid Vector index 3: must be in range \\[0, 2\\]\\."); - GTEST_EXPECT_DEATH_IF_SUPPORTED_( + EXPECT_DEATH_IF_SUPPORTED( a.GetElement(-1), "Invalid Vector index -1: must be in range \\[0, 2\\]\\."); } @@ -1368,10 +1358,10 @@ typedef TestResultTest TestResultDeathTest; TEST_F(TestResultDeathTest, GetTestPartResult) { CompareTestPartResult(*pr1, r2->GetTestPartResult(0)); CompareTestPartResult(*pr2, r2->GetTestPartResult(1)); - GTEST_EXPECT_DEATH_IF_SUPPORTED_( + EXPECT_DEATH_IF_SUPPORTED( r2->GetTestPartResult(2), "Invalid Vector index 2: must be in range \\[0, 1\\]\\."); - GTEST_EXPECT_DEATH_IF_SUPPORTED_( + EXPECT_DEATH_IF_SUPPORTED( r2->GetTestPartResult(-1), "Invalid Vector index -1: must be in range \\[0, 1\\]\\."); } @@ -1455,10 +1445,10 @@ TEST(TestResultPropertyDeathTest, GetTestProperty) { EXPECT_STREQ("key_3", fetched_property_3.key()); EXPECT_STREQ("3", fetched_property_3.value()); - GTEST_EXPECT_DEATH_IF_SUPPORTED_( + EXPECT_DEATH_IF_SUPPORTED( test_result.GetTestProperty(3), "Invalid Vector index 3: must be in range \\[0, 2\\]\\."); - GTEST_EXPECT_DEATH_IF_SUPPORTED_( + EXPECT_DEATH_IF_SUPPORTED( test_result.GetTestProperty(-1), "Invalid Vector index -1: must be in range \\[0, 2\\]\\."); } @@ -1737,7 +1727,7 @@ TEST(Int32FromEnvOrDieTest, ParsesAndReturnsValidValue) { // if the variable is not an Int32. TEST(Int32FromEnvOrDieDeathTest, AbortsOnFailure) { SetEnv(GTEST_FLAG_PREFIX_UPPER_ "VAR", "xxx"); - GTEST_EXPECT_DEATH_IF_SUPPORTED_( + EXPECT_DEATH_IF_SUPPORTED( Int32FromEnvOrDie(GTEST_FLAG_PREFIX_UPPER_ "VAR", 123), ".*"); } @@ -1746,7 +1736,7 @@ TEST(Int32FromEnvOrDieDeathTest, AbortsOnFailure) { // if the variable cannot be represnted by an Int32. TEST(Int32FromEnvOrDieDeathTest, AbortsOnInt32Overflow) { SetEnv(GTEST_FLAG_PREFIX_UPPER_ "VAR", "1234567891234567891234"); - GTEST_EXPECT_DEATH_IF_SUPPORTED_( + EXPECT_DEATH_IF_SUPPORTED( Int32FromEnvOrDie(GTEST_FLAG_PREFIX_UPPER_ "VAR", 123), ".*"); } @@ -1824,23 +1814,19 @@ typedef ShouldShardTest ShouldShardDeathTest; TEST_F(ShouldShardDeathTest, AbortsWhenShardingEnvVarsAreInvalid) { SetEnv(index_var_, "4"); SetEnv(total_var_, "4"); - GTEST_EXPECT_DEATH_IF_SUPPORTED_(ShouldShard(total_var_, index_var_, false), - ".*"); + EXPECT_DEATH_IF_SUPPORTED(ShouldShard(total_var_, index_var_, false), ".*"); SetEnv(index_var_, "4"); SetEnv(total_var_, "-2"); - GTEST_EXPECT_DEATH_IF_SUPPORTED_(ShouldShard(total_var_, index_var_, false), - ".*"); + EXPECT_DEATH_IF_SUPPORTED(ShouldShard(total_var_, index_var_, false), ".*"); SetEnv(index_var_, "5"); SetEnv(total_var_, ""); - GTEST_EXPECT_DEATH_IF_SUPPORTED_(ShouldShard(total_var_, index_var_, false), - ".*"); + EXPECT_DEATH_IF_SUPPORTED(ShouldShard(total_var_, index_var_, false), ".*"); SetEnv(index_var_, ""); SetEnv(total_var_, "5"); - GTEST_EXPECT_DEATH_IF_SUPPORTED_(ShouldShard(total_var_, index_var_, false), - ".*"); + EXPECT_DEATH_IF_SUPPORTED(ShouldShard(total_var_, index_var_, false), ".*"); } // Tests that ShouldRunTestOnShard is a partition when 5 -- cgit v1.2.3 From 56a2e686e915d483cb22db091140130b23814127 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Tue, 1 Sep 2009 18:53:56 +0000 Subject: Enables String to contain NUL (by Zhanyong Wan); Adds scons scripts (by Vlad Losev). --- test/gtest-death-test_test.cc | 6 +- test/gtest_unittest.cc | 154 ++++++++++++++++++++++++++++++++++++++---- 2 files changed, 142 insertions(+), 18 deletions(-) (limited to 'test') diff --git a/test/gtest-death-test_test.cc b/test/gtest-death-test_test.cc index 18811391..16fc7e09 100644 --- a/test/gtest-death-test_test.cc +++ b/test/gtest-death-test_test.cc @@ -292,7 +292,7 @@ TEST_F(TestForDeathTest, SingleStatement) { } void DieWithEmbeddedNul() { - fprintf(stderr, "Hello%cworld.\n", '\0'); + fprintf(stderr, "Hello%cmy null world.\n", '\0'); fflush(stderr); _exit(1); } @@ -303,8 +303,8 @@ void DieWithEmbeddedNul() { TEST_F(TestForDeathTest, EmbeddedNulInMessage) { // TODO(wan@google.com): doesn't support matching strings // with embedded NUL characters - find a way to workaround it. - EXPECT_DEATH(DieWithEmbeddedNul(), "w.*ld"); - ASSERT_DEATH(DieWithEmbeddedNul(), "w.*ld"); + EXPECT_DEATH(DieWithEmbeddedNul(), "my null world"); + ASSERT_DEATH(DieWithEmbeddedNul(), "my null world"); } #endif // GTEST_USES_PCRE diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index 2c087209..90d29e56 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -697,25 +697,61 @@ TEST(ListDeathTest, GetElement) { // Tests the String class. +TEST(StringTest, SizeIsSmall) { + // To avoid breaking clients that use lots of assertions in one + // function, we cannot grow the size of String. + EXPECT_LE(sizeof(String), sizeof(void*)); +} + // Tests String's constructors. TEST(StringTest, Constructors) { // Default ctor. String s1; // We aren't using EXPECT_EQ(NULL, s1.c_str()) because comparing // pointers with NULL isn't supported on all platforms. + EXPECT_EQ(0U, s1.length()); EXPECT_TRUE(NULL == s1.c_str()); // Implicitly constructs from a C-string. String s2 = "Hi"; + EXPECT_EQ(2U, s2.length()); EXPECT_STREQ("Hi", s2.c_str()); // Constructs from a C-string and a length. String s3("hello", 3); + EXPECT_EQ(3U, s3.length()); EXPECT_STREQ("hel", s3.c_str()); - // Copy ctor. - String s4 = s3; - EXPECT_STREQ("hel", s4.c_str()); + // The empty String should be created when String is constructed with + // a NULL pointer and length 0. + EXPECT_EQ(0U, String(NULL, 0).length()); + EXPECT_FALSE(String(NULL, 0).c_str() == NULL); + + // Constructs a String that contains '\0'. + String s4("a\0bcd", 4); + EXPECT_EQ(4U, s4.length()); + EXPECT_EQ('a', s4.c_str()[0]); + EXPECT_EQ('\0', s4.c_str()[1]); + EXPECT_EQ('b', s4.c_str()[2]); + EXPECT_EQ('c', s4.c_str()[3]); + + // Copy ctor where the source is NULL. + const String null_str; + String s5 = null_str; + EXPECT_TRUE(s5.c_str() == NULL); + + // Copy ctor where the source isn't NULL. + String s6 = s3; + EXPECT_EQ(3U, s6.length()); + EXPECT_STREQ("hel", s6.c_str()); + + // Copy ctor where the source contains '\0'. + String s7 = s4; + EXPECT_EQ(4U, s7.length()); + EXPECT_EQ('a', s7.c_str()[0]); + EXPECT_EQ('\0', s7.c_str()[1]); + EXPECT_EQ('b', s7.c_str()[2]); + EXPECT_EQ('c', s7.c_str()[3]); } #if GTEST_HAS_STD_STRING @@ -724,17 +760,22 @@ TEST(StringTest, ConvertsFromStdString) { // An empty std::string. const std::string src1(""); const String dest1 = src1; + EXPECT_EQ(0U, dest1.length()); EXPECT_STREQ("", dest1.c_str()); // A normal std::string. const std::string src2("Hi"); const String dest2 = src2; + EXPECT_EQ(2U, dest2.length()); EXPECT_STREQ("Hi", dest2.c_str()); // An std::string with an embedded NUL character. - const char src3[] = "Hello\0world."; + const char src3[] = "a\0b"; const String dest3 = std::string(src3, sizeof(src3)); - EXPECT_STREQ("Hello", dest3.c_str()); + EXPECT_EQ(sizeof(src3), dest3.length()); + EXPECT_EQ('a', dest3.c_str()[0]); + EXPECT_EQ('\0', dest3.c_str()[1]); + EXPECT_EQ('b', dest3.c_str()[2]); } TEST(StringTest, ConvertsToStdString) { @@ -747,6 +788,11 @@ TEST(StringTest, ConvertsToStdString) { const String src2("Hi"); const std::string dest2 = src2; EXPECT_EQ("Hi", dest2); + + // A String containing a '\0'. + const String src3("x\0y", 3); + const std::string dest3 = src3; + EXPECT_EQ(std::string("x\0y", 3), dest3); } #endif // GTEST_HAS_STD_STRING @@ -757,17 +803,22 @@ TEST(StringTest, ConvertsFromGlobalString) { // An empty ::string. const ::string src1(""); const String dest1 = src1; + EXPECT_EQ(0U, dest1.length()); EXPECT_STREQ("", dest1.c_str()); // A normal ::string. const ::string src2("Hi"); const String dest2 = src2; + EXPECT_EQ(2U, dest2.length()); EXPECT_STREQ("Hi", dest2.c_str()); // An ::string with an embedded NUL character. - const char src3[] = "Hello\0world."; + const char src3[] = "x\0y"; const String dest3 = ::string(src3, sizeof(src3)); - EXPECT_STREQ("Hello", dest3.c_str()); + EXPECT_EQ(sizeof(src3), dest3.length()); + EXPECT_EQ('x', dest3.c_str()[0]); + EXPECT_EQ('\0', dest3.c_str()[1]); + EXPECT_EQ('y', dest3.c_str()[2]); } TEST(StringTest, ConvertsToGlobalString) { @@ -780,17 +831,14 @@ TEST(StringTest, ConvertsToGlobalString) { const String src2("Hi"); const ::string dest2 = src2; EXPECT_EQ("Hi", dest2); + + const String src3("x\0y", 3); + const ::string dest3 = src3; + EXPECT_EQ(::string("x\0y", 3), dest3); } #endif // GTEST_HAS_GLOBAL_STRING -// Tests String::ShowCString(). -TEST(StringTest, ShowCString) { - EXPECT_STREQ("(null)", String::ShowCString(NULL)); - EXPECT_STREQ("", String::ShowCString("")); - EXPECT_STREQ("foo", String::ShowCString("foo")); -} - // Tests String::ShowCStringQuoted(). TEST(StringTest, ShowCStringQuoted) { EXPECT_STREQ("(null)", @@ -801,6 +849,53 @@ TEST(StringTest, ShowCStringQuoted) { String::ShowCStringQuoted("foo").c_str()); } +// Tests String::empty(). +TEST(StringTest, Empty) { + EXPECT_TRUE(String("").empty()); + EXPECT_FALSE(String().empty()); + EXPECT_FALSE(String(NULL).empty()); + EXPECT_FALSE(String("a").empty()); + EXPECT_FALSE(String("\0", 1).empty()); +} + +// Tests String::Compare(). +TEST(StringTest, Compare) { + // NULL vs NULL. + EXPECT_EQ(0, String().Compare(String())); + + // NULL vs non-NULL. + EXPECT_EQ(-1, String().Compare(String(""))); + + // Non-NULL vs NULL. + EXPECT_EQ(1, String("").Compare(String())); + + // The following covers non-NULL vs non-NULL. + + // "" vs "". + EXPECT_EQ(0, String("").Compare(String(""))); + + // "" vs non-"". + EXPECT_EQ(-1, String("").Compare(String("\0", 1))); + EXPECT_EQ(-1, String("").Compare(" ")); + + // Non-"" vs "". + EXPECT_EQ(1, String("a").Compare(String(""))); + + // The following covers non-"" vs non-"". + + // Same length and equal. + EXPECT_EQ(0, String("a").Compare(String("a"))); + + // Same length and different. + EXPECT_EQ(-1, String("a\0b", 3).Compare(String("a\0c", 3))); + EXPECT_EQ(1, String("b").Compare(String("a"))); + + // Different lengths. + EXPECT_EQ(-1, String("a").Compare(String("ab"))); + EXPECT_EQ(-1, String("a").Compare(String("a\0", 2))); + EXPECT_EQ(1, String("abc").Compare(String("aacd"))); +} + // Tests String::operator==(). TEST(StringTest, Equals) { const String null(NULL); @@ -818,6 +913,9 @@ TEST(StringTest, Equals) { EXPECT_FALSE(foo == ""); // NOLINT EXPECT_FALSE(foo == "bar"); // NOLINT EXPECT_TRUE(foo == "foo"); // NOLINT + + const String bar("x\0y", 3); + EXPECT_FALSE(bar == "x"); } // Tests String::operator!=(). @@ -837,6 +935,17 @@ TEST(StringTest, NotEquals) { EXPECT_TRUE(foo != ""); // NOLINT EXPECT_TRUE(foo != "bar"); // NOLINT EXPECT_FALSE(foo != "foo"); // NOLINT + + const String bar("x\0y", 3); + EXPECT_TRUE(bar != "x"); +} + +// Tests String::length(). +TEST(StringTest, Length) { + EXPECT_EQ(0U, String().length()); + EXPECT_EQ(0U, String("").length()); + EXPECT_EQ(2U, String("ab").length()); + EXPECT_EQ(3U, String("a\0b", 3).length()); } // Tests String::EndsWith(). @@ -900,9 +1009,17 @@ TEST(StringTest, CanBeAssignedEmpty) { TEST(StringTest, CanBeAssignedNonEmpty) { const String src("hello"); String dest; - dest = src; + EXPECT_EQ(5U, dest.length()); EXPECT_STREQ("hello", dest.c_str()); + + const String src2("x\0y", 3); + String dest2; + dest2 = src2; + EXPECT_EQ(3U, dest2.length()); + EXPECT_EQ('x', dest2.c_str()[0]); + EXPECT_EQ('\0', dest2.c_str()[1]); + EXPECT_EQ('y', dest2.c_str()[2]); } // Tests that a String can be assigned to itself. @@ -913,6 +1030,13 @@ TEST(StringTest, CanBeAssignedSelf) { EXPECT_STREQ("hello", dest.c_str()); } +// Tests streaming a String. +TEST(StringTest, Streams) { + EXPECT_EQ(StreamableToString(String()), "(null)"); + EXPECT_EQ(StreamableToString(String("")), ""); + EXPECT_EQ(StreamableToString(String("a\0b", 3)), "a\\0b"); +} + #if GTEST_OS_WINDOWS // Tests String::ShowWideCString(). -- cgit v1.2.3 From 16e9dd6e28a8a7fb2d611011e7353e042fcb282f Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Fri, 4 Sep 2009 18:30:25 +0000 Subject: More implementation of the event listener interface (by Vlad Losev); Reduces the stack space usage of assertions by moving AssertHelper's fields to the heap (by Jorg Brown); Makes String faster, smaller, and simpler (by Zhanyong Wan); Fixes a bug in String::Format() (by Chandler); Adds the /MD version of VC projects to the distribution (by Vlad Losev). --- test/gtest-listener_test.cc | 230 +++++++++++++++++++++++++ test/gtest_env_var_test.py | 2 +- test/gtest_unittest.cc | 339 ++++++++++++++++++++++++++++++++++++- test/gtest_xml_output_unittest.py | 33 +++- test/gtest_xml_output_unittest_.cc | 28 +++ 5 files changed, 625 insertions(+), 7 deletions(-) create mode 100644 test/gtest-listener_test.cc (limited to 'test') diff --git a/test/gtest-listener_test.cc b/test/gtest-listener_test.cc new file mode 100644 index 00000000..fb6fcf48 --- /dev/null +++ b/test/gtest-listener_test.cc @@ -0,0 +1,230 @@ +// Copyright 2009 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: vladl@google.com (Vlad Losev) +// +// The Google C++ Testing Framework (Google Test) +// +// This file verifies Google Test event listeners receive events at the +// right times. + +#include + +// Indicates that this translation unit is part of Google Test's +// implementation. It must come before gtest-internal-inl.h is +// included, or there will be a compiler error. This trick is to +// prevent a user from accidentally including gtest-internal-inl.h in +// his code. +#define GTEST_IMPLEMENTATION_ 1 +#include "src/gtest-internal-inl.h" // For Vector. +#undef GTEST_IMPLEMENTATION_ + +using ::testing::AddGlobalTestEnvironment; +using ::testing::Environment; +using ::testing::InitGoogleTest; +using ::testing::Test; +using ::testing::TestInfo; +using ::testing::TestPartResult; +using ::testing::UnitTest; +using ::testing::internal::String; +using ::testing::internal::TestCase; +using ::testing::internal::UnitTestEventListenerInterface; +using ::testing::internal::Vector; + +// Used by tests to register their events. +Vector* g_events = NULL; + +namespace testing { +namespace internal { + +// TODO(vladl@google.com): Remove this and use UnitTest::listeners() +// directly after it is published. +class UnitTestAccessor { + public: + static EventListeners& GetEventListeners() { + return UnitTest::GetInstance()->listeners(); + } + static bool UnitTestFailed() { return UnitTest::GetInstance()->Failed(); } +}; + +class EventRecordingListener : public UnitTestEventListenerInterface { + protected: + virtual void OnUnitTestStart(const UnitTest& unit_test) { + g_events->PushBack(String("TestEventListener::OnUnitTestStart")); + } + + virtual void OnGlobalSetUpStart(const UnitTest& unit_test) { + g_events->PushBack(String("TestEventListener::OnGlobalSetUpStart")); + } + + virtual void OnGlobalSetUpEnd(const UnitTest& unit_test) { + g_events->PushBack(String("TestEventListener::OnGlobalSetUpEnd")); + } + + virtual void OnTestCaseStart(const TestCase& test_case) { + g_events->PushBack(String("TestEventListener::OnTestCaseStart")); + } + + virtual void OnTestStart(const TestInfo& test_info) { + g_events->PushBack(String("TestEventListener::OnTestStart")); + } + + virtual void OnNewTestPartResult(const TestPartResult& test_part_result) { + g_events->PushBack(String("TestEventListener::OnNewTestPartResult")); + } + + virtual void OnTestEnd(const TestInfo& test_info) { + g_events->PushBack(String("TestEventListener::OnTestEnd")); + } + + virtual void OnTestCaseEnd(const TestCase& test_case) { + g_events->PushBack(String("TestEventListener::OnTestCaseEnd")); + } + + virtual void OnGlobalTearDownStart(const UnitTest& unit_test) { + g_events->PushBack(String("TestEventListener::OnGlobalTearDownStart")); + } + + virtual void OnGlobalTearDownEnd(const UnitTest& unit_test) { + g_events->PushBack(String("TestEventListener::OnGlobalTearDownEnd")); + } + + virtual void OnUnitTestEnd(const UnitTest& unit_test) { + g_events->PushBack(String("TestEventListener::OnUnitTestEnd")); + } +}; + +class EnvironmentInvocationCatcher : public Environment { + protected: + virtual void SetUp() { + g_events->PushBack(String("Environment::SetUp")); + } + + virtual void TearDown() { + g_events->PushBack(String("Environment::TearDown")); + } +}; + +class ListenerTest : public Test { + protected: + static void SetUpTestCase() { + g_events->PushBack(String("ListenerTest::SetUpTestCase")); + } + + static void TearDownTestCase() { + g_events->PushBack(String("ListenerTest::TearDownTestCase")); + } + + virtual void SetUp() { + g_events->PushBack(String("ListenerTest::SetUp")); + } + + virtual void TearDown() { + g_events->PushBack(String("ListenerTest::TearDown")); + } +}; + +TEST_F(ListenerTest, DoesFoo) { + // Test execution order within a test case is not guaranteed so we are not + // recording the test name. + g_events->PushBack(String("ListenerTest::* Test Body")); + SUCCEED(); // Triggers OnTestPartResult. +} + +TEST_F(ListenerTest, DoesBar) { + g_events->PushBack(String("ListenerTest::* Test Body")); + SUCCEED(); // Triggers OnTestPartResult. +} + +} // namespace internal + +} // namespace testing + +using ::testing::internal::EnvironmentInvocationCatcher; +using ::testing::internal::EventRecordingListener; +using ::testing::internal::UnitTestAccessor; + +int main(int argc, char **argv) { + Vector events; + g_events = &events; + InitGoogleTest(&argc, argv); + + UnitTestEventListenerInterface* listener = new EventRecordingListener; + UnitTestAccessor::GetEventListeners().Append(listener); + + AddGlobalTestEnvironment(new EnvironmentInvocationCatcher); + + GTEST_CHECK_(events.size() == 0) + << "AddGlobalTestEnvironment should not generate any events itself."; + + int ret_val = RUN_ALL_TESTS(); + + const char* const expected_events[] = { + "TestEventListener::OnUnitTestStart", + "TestEventListener::OnGlobalSetUpStart", + "Environment::SetUp", + "TestEventListener::OnGlobalSetUpEnd", + "TestEventListener::OnTestCaseStart", + "ListenerTest::SetUpTestCase", + "TestEventListener::OnTestStart", + "ListenerTest::SetUp", + "ListenerTest::* Test Body", + "TestEventListener::OnNewTestPartResult", + "ListenerTest::TearDown", + "TestEventListener::OnTestEnd", + "TestEventListener::OnTestStart", + "ListenerTest::SetUp", + "ListenerTest::* Test Body", + "TestEventListener::OnNewTestPartResult", + "ListenerTest::TearDown", + "TestEventListener::OnTestEnd", + "ListenerTest::TearDownTestCase", + "TestEventListener::OnTestCaseEnd", + "TestEventListener::OnGlobalTearDownStart", + "Environment::TearDown", + "TestEventListener::OnGlobalTearDownEnd", + "TestEventListener::OnUnitTestEnd" + }; + const int kExpectedEventsSize = + sizeof(expected_events)/sizeof(expected_events[0]); + + // Cannot use ASSERT_EQ() here because it requires the scoping function to + // return void. + GTEST_CHECK_(events.size() == kExpectedEventsSize); + + for (int i = 0; i < events.size(); ++i) + GTEST_CHECK_(String(events.GetElement(i)) == expected_events[i]) + << "At position " << i; + + // We need to check manually for ad hoc test failures that happen after + // RUN_ALL_TESTS finishes. + if (UnitTestAccessor::UnitTestFailed()) + ret_val = 1; + + return ret_val; +} diff --git a/test/gtest_env_var_test.py b/test/gtest_env_var_test.py index 19fd8103..f8250d4c 100755 --- a/test/gtest_env_var_test.py +++ b/test/gtest_env_var_test.py @@ -85,7 +85,7 @@ class GTestEnvVarTest(gtest_test_utils.TestCase): TestFlag('break_on_failure', '1', '0') TestFlag('color', 'yes', 'auto') TestFlag('filter', 'FooTest.Bar', '*') - TestFlag('output', 'tmp/foo.xml', '') + TestFlag('output', 'xml:tmp/foo.xml', '') TestFlag('print_time', '0', '1') TestFlag('repeat', '999', '1') TestFlag('throw_on_failure', '1', '0') diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index 90d29e56..dcec9dad 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -84,11 +84,38 @@ const char* FormatTimeInMillisAsSeconds(TimeInMillis ms); bool ParseInt32Flag(const char* str, const char* flag, Int32* value); +// Provides access to otherwise private parts of the EventListeners class +// that are needed to test it. +class EventListenersAccessor { + public: + static UnitTestEventListenerInterface* GetRepeater( + EventListeners* listeners) { return listeners->repeater(); } + + static void SetDefaultResultPrinter( + EventListeners* listeners, + UnitTestEventListenerInterface* listener) { + listeners->SetDefaultResultPrinter(listener); + } + static void SetDefaultXmlGenerator(EventListeners* listeners, + UnitTestEventListenerInterface* listener) { + listeners->SetDefaultXmlGenerator(listener); + } + + static bool EventForwardingEnabled(const EventListeners& listeners) { + return listeners.EventForwardingEnabled(); + } + + static void SuppressEventForwarding(EventListeners* listeners) { + listeners->SuppressEventForwarding(); + } +}; + } // namespace internal } // namespace testing using testing::internal::FormatTimeInMillisAsSeconds; using testing::internal::ParseInt32Flag; +using testing::internal::EventListenersAccessor; namespace testing { @@ -136,7 +163,9 @@ using testing::internal::kMaxRandomSeed; using testing::internal::kTestTypeIdInGoogleTest; using testing::internal::AppendUserMessage; using testing::internal::CodePointToUtf8; +using testing::internal::EmptyTestEventListener; using testing::internal::EqFailure; +using testing::internal::EventListeners; using testing::internal::FloatingPoint; using testing::internal::GTestFlagSaver; using testing::internal::GetCurrentOsStackTraceExceptTop; @@ -160,6 +189,7 @@ using testing::internal::ThreadLocal; using testing::internal::Vector; using testing::internal::WideStringToUtf8; using testing::internal::kTestTypeIdInGoogleTest; +using testing::internal::scoped_ptr; // This line tests that we can define tests in an unnamed namespace. namespace { @@ -695,14 +725,16 @@ TEST(ListDeathTest, GetElement) { "Invalid Vector index -1: must be in range \\[0, 2\\]\\."); } -// Tests the String class. +// Tests the size of the AssertHelper class. -TEST(StringTest, SizeIsSmall) { +TEST(AssertHelperTest, AssertHelperIsSmall) { // To avoid breaking clients that use lots of assertions in one - // function, we cannot grow the size of String. - EXPECT_LE(sizeof(String), sizeof(void*)); + // function, we cannot grow the size of AssertHelper. + EXPECT_LE(sizeof(testing::internal::AssertHelper), sizeof(void*)); } +// Tests the String class. + // Tests String's constructors. TEST(StringTest, Constructors) { // Default ctor. @@ -1037,6 +1069,33 @@ TEST(StringTest, Streams) { EXPECT_EQ(StreamableToString(String("a\0b", 3)), "a\\0b"); } +// Tests that String::Format() works. +TEST(StringTest, FormatWorks) { + // Normal case: the format spec is valid, the arguments match the + // spec, and the result is < 4095 characters. + EXPECT_STREQ("Hello, 42", String::Format("%s, %d", "Hello", 42).c_str()); + + // Edge case: the result is 4095 characters. + char buffer[4096]; + const size_t kSize = sizeof(buffer); + memset(buffer, 'a', kSize - 1); + buffer[kSize - 1] = '\0'; + EXPECT_STREQ(buffer, String::Format("%s", buffer).c_str()); + + // The result needs to be 4096 characters, exceeding Format()'s limit. + EXPECT_STREQ("", + String::Format("x%s", buffer).c_str()); + +#if GTEST_OS_LINUX + // On Linux, invalid format spec should lead to an error message. + // In other environment (e.g. MSVC on Windows), String::Format() may + // simply ignore a bad format spec, so this assertion is run on + // Linux only. + EXPECT_STREQ("", + String::Format("%").c_str()); +#endif +} + #if GTEST_OS_WINDOWS // Tests String::ShowWideCString(). @@ -6142,3 +6201,275 @@ TEST(HasFailureTest, WorksOutsideOfTestBody2) { ClearCurrentTestPartResults(); EXPECT_TRUE(has_failure); } + +class TestListener : public EmptyTestEventListener { + public: + TestListener() : on_start_counter_(NULL), is_destroyed_(NULL) {} + TestListener(int* on_start_counter, bool* is_destroyed) + : on_start_counter_(on_start_counter), + is_destroyed_(is_destroyed) {} + + virtual ~TestListener() { + if (is_destroyed_) + *is_destroyed_ = true; + } + + protected: + virtual void OnUnitTestStart(const UnitTest& /*unit_test*/) { + if (on_start_counter_ != NULL) + (*on_start_counter_)++; + } + + private: + int* on_start_counter_; + bool* is_destroyed_; +}; + +// Tests the constructor. +TEST(EventListenersTest, ConstructionWorks) { + EventListeners listeners; + + EXPECT_TRUE(EventListenersAccessor::GetRepeater(&listeners) != NULL); + EXPECT_TRUE(listeners.default_result_printer() == NULL); + EXPECT_TRUE(listeners.default_xml_generator() == NULL); +} + +// Tests that the EventListeners destructor deletes all the listeners it +// owns. +TEST(EventListenersTest, DestructionWorks) { + bool default_result_printer_is_destroyed = false; + bool default_xml_printer_is_destroyed = false; + bool extra_listener_is_destroyed = false; + TestListener* default_result_printer = new TestListener( + NULL, &default_result_printer_is_destroyed); + TestListener* default_xml_printer = new TestListener( + NULL, &default_xml_printer_is_destroyed); + TestListener* extra_listener = new TestListener( + NULL, &extra_listener_is_destroyed); + + { + EventListeners listeners; + EventListenersAccessor::SetDefaultResultPrinter(&listeners, + default_result_printer); + EventListenersAccessor::SetDefaultXmlGenerator(&listeners, + default_xml_printer); + listeners.Append(extra_listener); + } + EXPECT_TRUE(default_result_printer_is_destroyed); + EXPECT_TRUE(default_xml_printer_is_destroyed); + EXPECT_TRUE(extra_listener_is_destroyed); +} + +// Tests that a listener Append'ed to an EventListeners list starts +// receiving events. +TEST(EventListenersTest, Append) { + int on_start_counter = 0; + bool is_destroyed = false; + TestListener* listener = new TestListener(&on_start_counter, &is_destroyed); + { + EventListeners listeners; + listeners.Append(listener); + EventListenersAccessor::GetRepeater(&listeners)->OnUnitTestStart( + *UnitTest::GetInstance()); + EXPECT_EQ(1, on_start_counter); + } + EXPECT_TRUE(is_destroyed); +} + +// Tests that listeners receive requests in the order they were appended to +// the list. +class SequenceTestingListener : public EmptyTestEventListener { + public: + SequenceTestingListener(Vector* vector, const char* signature) + : vector_(vector), signature_(signature) {} + + protected: + virtual void OnUnitTestStart(const UnitTest& /*unit_test*/) { + if (vector_ != NULL) + vector_->PushBack(signature_); + } + + private: + Vector* vector_; + const char* const signature_; +}; + +TEST(EventListenerTest, AppendKeepsOrder) { + Vector vec; + EventListeners listeners; + listeners.Append(new SequenceTestingListener(&vec, "0")); + listeners.Append(new SequenceTestingListener(&vec, "1")); + listeners.Append(new SequenceTestingListener(&vec, "2")); + EventListenersAccessor::GetRepeater(&listeners)->OnUnitTestStart( + *UnitTest::GetInstance()); + ASSERT_EQ(3, vec.size()); + ASSERT_STREQ("0", vec.GetElement(0)); + ASSERT_STREQ("1", vec.GetElement(1)); + ASSERT_STREQ("2", vec.GetElement(2)); +} + +// Tests that a listener removed from an EventListeners list stops receiving +// events and is not deleted when the list is destroyed. +TEST(EventListenersTest, Release) { + int on_start_counter = 0; + bool is_destroyed = false; + // Although Append passes the ownership of this object to the list, + // the following calls release it, and we need to delete it before the + // test ends. + TestListener* listener = new TestListener(&on_start_counter, &is_destroyed); + { + EventListeners listeners; + listeners.Append(listener); + EXPECT_EQ(listener, listeners.Release(listener)); + EventListenersAccessor::GetRepeater(&listeners)->OnUnitTestStart( + *UnitTest::GetInstance()); + EXPECT_TRUE(listeners.Release(listener) == NULL); + } + EXPECT_EQ(0, on_start_counter); + EXPECT_FALSE(is_destroyed); + delete listener; +} + +// Tests that no events are forwarded when event forwarding is disabled. +TEST(EventListenerTest, SuppressEventForwarding) { + int on_start_counter = 0; + TestListener* listener = new TestListener(&on_start_counter, NULL); + + EventListeners listeners; + listeners.Append(listener); + ASSERT_TRUE(EventListenersAccessor::EventForwardingEnabled(listeners)); + EventListenersAccessor::SuppressEventForwarding(&listeners); + ASSERT_FALSE(EventListenersAccessor::EventForwardingEnabled(listeners)); + EventListenersAccessor::GetRepeater(&listeners)->OnUnitTestStart( + *UnitTest::GetInstance()); + EXPECT_EQ(0, on_start_counter); +} + +#if GTEST_HAS_DEATH_TEST +// Tests that events generated by Google Test are not forwarded in +// death test subprocesses. +TEST(EventListenerDeathTest, EventsNotForwardedInDeathTestSubprecesses) { + EXPECT_DEATH({ // NOLINT + GTEST_CHECK_(EventListenersAccessor::EventForwardingEnabled( + *GetUnitTestImpl()->listeners())) << "expected failure";}, + "expected failure"); +} +#endif // GTEST_HAS_DEATH_TEST + +// Tests that a listener installed via SetDefaultResultPrinter() starts +// receiving events and is returned via default_result_printer() and that +// the previous default_result_printer is removed from the list and deleted. +TEST(EventListenerTest, default_result_printer) { + int on_start_counter = 0; + bool is_destroyed = false; + TestListener* listener = new TestListener(&on_start_counter, &is_destroyed); + + EventListeners listeners; + EventListenersAccessor::SetDefaultResultPrinter(&listeners, listener); + + EXPECT_EQ(listener, listeners.default_result_printer()); + + EventListenersAccessor::GetRepeater(&listeners)->OnUnitTestStart( + *UnitTest::GetInstance()); + + EXPECT_EQ(1, on_start_counter); + + // Replacing default_result_printer with something else should remove it + // from the list and destroy it. + EventListenersAccessor::SetDefaultResultPrinter(&listeners, NULL); + + EXPECT_TRUE(listeners.default_result_printer() == NULL); + EXPECT_TRUE(is_destroyed); + + // After broadcasting an event the counter is still the same, indicating + // the listener is not in the list anymore. + EventListenersAccessor::GetRepeater(&listeners)->OnUnitTestStart( + *UnitTest::GetInstance()); + EXPECT_EQ(1, on_start_counter); +} + +// Tests that the default_result_printer listener stops receiving events +// when removed via Release and that is not owned by the list anymore. +TEST(EventListenerTest, RemovingDefaultResultPrinterWorks) { + int on_start_counter = 0; + bool is_destroyed = false; + // Although Append passes the ownership of this object to the list, + // the following calls release it, and we need to delete it before the + // test ends. + TestListener* listener = new TestListener(&on_start_counter, &is_destroyed); + { + EventListeners listeners; + EventListenersAccessor::SetDefaultResultPrinter(&listeners, listener); + + EXPECT_EQ(listener, listeners.Release(listener)); + EXPECT_TRUE(listeners.default_result_printer() == NULL); + EXPECT_FALSE(is_destroyed); + + // Broadcasting events now should not affect default_result_printer. + EventListenersAccessor::GetRepeater(&listeners)->OnUnitTestStart( + *UnitTest::GetInstance()); + EXPECT_EQ(0, on_start_counter); + } + // Destroying the list should not affect the listener now, too. + EXPECT_FALSE(is_destroyed); + delete listener; +} + +// Tests that a listener installed via SetDefaultXmlGenerator() starts +// receiving events and is returned via default_xml_generator() and that +// the previous default_xml_generator is removed from the list and deleted. +TEST(EventListenerTest, default_xml_generator) { + int on_start_counter = 0; + bool is_destroyed = false; + TestListener* listener = new TestListener(&on_start_counter, &is_destroyed); + + EventListeners listeners; + EventListenersAccessor::SetDefaultXmlGenerator(&listeners, listener); + + EXPECT_EQ(listener, listeners.default_xml_generator()); + + EventListenersAccessor::GetRepeater(&listeners)->OnUnitTestStart( + *UnitTest::GetInstance()); + + EXPECT_EQ(1, on_start_counter); + + // Replacing default_xml_generator with something else should remove it + // from the list and destroy it. + EventListenersAccessor::SetDefaultXmlGenerator(&listeners, NULL); + + EXPECT_TRUE(listeners.default_xml_generator() == NULL); + EXPECT_TRUE(is_destroyed); + + // After broadcasting an event the counter is still the same, indicating + // the listener is not in the list anymore. + EventListenersAccessor::GetRepeater(&listeners)->OnUnitTestStart( + *UnitTest::GetInstance()); + EXPECT_EQ(1, on_start_counter); +} + +// Tests that the default_xml_generator listener stops receiving events +// when removed via Release and that is not owned by the list anymore. +TEST(EventListenerTest, RemovingDefaultXmlGeneratorWorks) { + int on_start_counter = 0; + bool is_destroyed = false; + // Although Append passes the ownership of this object to the list, + // the following calls release it, and we need to delete it before the + // test ends. + TestListener* listener = new TestListener(&on_start_counter, &is_destroyed); + { + EventListeners listeners; + EventListenersAccessor::SetDefaultXmlGenerator(&listeners, listener); + + EXPECT_EQ(listener, listeners.Release(listener)); + EXPECT_TRUE(listeners.default_xml_generator() == NULL); + EXPECT_FALSE(is_destroyed); + + // Broadcasting events now should not affect default_xml_generator. + EventListenersAccessor::GetRepeater(&listeners)->OnUnitTestStart( + *UnitTest::GetInstance()); + EXPECT_EQ(0, on_start_counter); + } + // Destroying the list should not affect the listener now, too. + EXPECT_FALSE(is_destroyed); + delete listener; +} diff --git a/test/gtest_xml_output_unittest.py b/test/gtest_xml_output_unittest.py index a0cd4d09..3ee6846e 100755 --- a/test/gtest_xml_output_unittest.py +++ b/test/gtest_xml_output_unittest.py @@ -44,6 +44,7 @@ import gtest_xml_test_utils GTEST_OUTPUT_FLAG = "--gtest_output" GTEST_DEFAULT_OUTPUT_FILE = "test_detail.xml" +GTEST_PROGRAM_NAME = "gtest_xml_output_unittest_" SUPPORTS_STACK_TRACES = False @@ -108,8 +109,7 @@ class GTestXMLOutputUnitTest(gtest_xml_test_utils.GTestXMLTestCase): Runs a test program that generates a non-empty XML output, and tests that the XML output is expected. """ - self._TestXmlOutput("gtest_xml_output_unittest_", - EXPECTED_NON_EMPTY_XML, 1) + self._TestXmlOutput(GTEST_PROGRAM_NAME, EXPECTED_NON_EMPTY_XML, 1) def testEmptyXmlOutput(self): """ @@ -142,6 +142,35 @@ class GTestXMLOutputUnitTest(gtest_xml_test_utils.GTestXMLTestCase): self.assertEquals(0, p.exit_code) self.assert_(os.path.isfile(output_file)) + def testSuppressedXmlOutput(self): + """ + Tests that no XML file is generated if the default XML listener is + shut down before RUN_ALL_TESTS is invoked. + """ + + xml_path = os.path.join(gtest_test_utils.GetTempDir(), + GTEST_PROGRAM_NAME + "out.xml") + if os.path.isfile(xml_path): + os.remove(xml_path) + + gtest_prog_path = gtest_test_utils.GetTestExecutablePath(GTEST_PROGRAM_NAME) + + command = [gtest_prog_path, + "%s=xml:%s" % (GTEST_OUTPUT_FLAG, xml_path), + "--shut_down_xml"] + p = gtest_test_utils.Subprocess(command) + if p.terminated_by_signal: + self.assert_(False, + "%s was killed by signal %d" % (gtest_prog_name, p.signal)) + else: + self.assert_(p.exited) + self.assertEquals(1, p.exit_code, + "'%s' exited with code %s, which doesn't match " + "the expected exit code %s." + % (command, p.exit_code, 1)) + + self.assert_(not os.path.isfile(xml_path)) + def _TestXmlOutput(self, gtest_prog_name, expected_xml, expected_exit_code): """ diff --git a/test/gtest_xml_output_unittest_.cc b/test/gtest_xml_output_unittest_.cc index d7ce2c6f..bfeda3d8 100644 --- a/test/gtest_xml_output_unittest_.cc +++ b/test/gtest_xml_output_unittest_.cc @@ -40,6 +40,20 @@ #include +// TODO(vladl@google.com): Remove this include when the event listener API is +// published and GetUnitTestImpl is no longer needed. +// +// Indicates that this translation unit is part of Google Test's +// implementation. It must come before gtest-internal-inl.h is +// included, or there will be a compiler error. This trick is to +// prevent a user from accidentally including gtest-internal-inl.h in +// his code. +#define GTEST_IMPLEMENTATION_ 1 +#include "src/gtest-internal-inl.h" +#undef GTEST_IMPLEMENTATION_ + +using ::testing::InitGoogleTest; + class SuccessfulTest : public testing::Test { }; @@ -118,3 +132,17 @@ TEST(NoFixtureTest, ExternalUtilityThatCallsRecordIntValuedProperty) { TEST(NoFixtureTest, ExternalUtilityThatCallsRecordStringValuedProperty) { ExternalUtilityThatCallsRecordProperty("key_for_utility_string", "1"); } + +int main(int argc, char** argv) { + InitGoogleTest(&argc, argv); + + if (argc > 1 && strcmp(argv[1], "--shut_down_xml") == 0) { + // TODO(vladl@google.com): Replace GetUnitTestImpl()->listeners() with + // UnitTest::GetInstance()->listeners() when the event listener API is + // published. + ::testing::internal::EventListeners& listeners = + *::testing::internal::GetUnitTestImpl()->listeners(); + delete listeners.Release(listeners.default_xml_generator()); + } + return RUN_ALL_TESTS(); +} -- cgit v1.2.3 From b2ee82ebf9b8f1be859d08611b768ae6c0700090 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Fri, 11 Sep 2009 06:59:42 +0000 Subject: Improves EXPECT_DEATH_IF_SUPPORTED to allow streaming of messages and enforcing the validity of arguments (by Vlad Losev); adds samples for the event listener API (by Vlad Losev); simplifies the tests using EXPECT_DEATH_IF_SUPPORTED (by Zhanyong Wan). --- test/gtest-death-test_test.cc | 77 ++++++++++++++++++++++++++++++++++++++++-- test/gtest-port_test.cc | 7 ++-- test/gtest-test-part_test.cc | 8 ++--- test/gtest-typed-test_test.cc | 12 +++---- test/gtest_filter_unittest_.cc | 10 ++---- test/gtest_repeat_test.cc | 6 ++-- test/gtest_unittest.cc | 4 +-- 7 files changed, 90 insertions(+), 34 deletions(-) (limited to 'test') diff --git a/test/gtest-death-test_test.cc b/test/gtest-death-test_test.cc index 16fc7e09..f56f35dc 100644 --- a/test/gtest-death-test_test.cc +++ b/test/gtest-death-test_test.cc @@ -1136,7 +1136,7 @@ using testing::internal::GetCapturedStderr; using testing::internal::String; // Tests that EXPECT_DEATH_IF_SUPPORTED/ASSERT_DEATH_IF_SUPPORTED are still -// defined but do not rigger failures when death tests are not available on +// defined but do not trigger failures when death tests are not available on // the system. TEST(ConditionalDeathMacrosTest, WarnsWhenDeathTestsNotAvailable) { // Empty statement will not crash, but that should not trigger a failure @@ -1148,16 +1148,89 @@ TEST(ConditionalDeathMacrosTest, WarnsWhenDeathTestsNotAvailable) { "Death tests are not supported on this platform")); ASSERT_TRUE(NULL != strstr(output.c_str(), ";")); + // The streamed message should not be printed as there is no test failure. CaptureStderr(); - ASSERT_DEATH_IF_SUPPORTED(;, ""); + EXPECT_DEATH_IF_SUPPORTED(;, "") << "streamed message"; + output = GetCapturedStderr(); + ASSERT_TRUE(NULL == strstr(output.c_str(), "streamed message")); + + CaptureStderr(); + ASSERT_DEATH_IF_SUPPORTED(;, ""); // NOLINT output = GetCapturedStderr(); ASSERT_TRUE(NULL != strstr(output.c_str(), "Death tests are not supported on this platform")); ASSERT_TRUE(NULL != strstr(output.c_str(), ";")); + + CaptureStderr(); + ASSERT_DEATH_IF_SUPPORTED(;, "") << "streamed message"; // NOLINT + output = GetCapturedStderr(); + ASSERT_TRUE(NULL == strstr(output.c_str(), "streamed message")); } +void FuncWithAssert(int* n) { + ASSERT_DEATH_IF_SUPPORTED(return;, ""); + (*n)++; +} + +// Tests that ASSERT_DEATH_IF_SUPPORTED does not return from the current +// function (as ASSERT_DEATH does) if death tests are not supported. +TEST(ConditionalDeathMacrosTest, AssertDeatDoesNotReturnhIfUnsupported) { + int n = 0; + FuncWithAssert(&n); + EXPECT_EQ(1, n); +} #endif // GTEST_HAS_DEATH_TEST +// Tests that the death test macros expand to code which may or may not +// be followed by operator<<, and that in either case the complete text +// comprises only a single C++ statement. +// +// The syntax should work whether death tests are available or not. +TEST(ConditionalDeathMacrosSyntaxDeathTest, SingleStatement) { + if (false) + // This would fail if executed; this is a compilation test only + ASSERT_DEATH_IF_SUPPORTED(return, ""); + + if (true) + EXPECT_DEATH_IF_SUPPORTED(_exit(1), ""); + else + // This empty "else" branch is meant to ensure that EXPECT_DEATH + // doesn't expand into an "if" statement without an "else" + ; // NOLINT + + if (false) + ASSERT_DEATH_IF_SUPPORTED(return, "") << "did not die"; + + if (false) + ; // NOLINT + else + EXPECT_DEATH_IF_SUPPORTED(_exit(1), "") << 1 << 2 << 3; +} + +// Tests that conditional death test macros expand to code which interacts +// well with switch statements. +TEST(ConditionalDeathMacrosSyntaxDeathTest, SwitchStatement) { +// Microsoft compiler usually complains about switch statements without +// case labels. We suppress that warning for this test. +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable: 4065) +#endif // _MSC_VER + + switch (0) + default: + ASSERT_DEATH_IF_SUPPORTED(_exit(1), "") + << "exit in default switch handler"; + + switch (0) + case 0: + EXPECT_DEATH_IF_SUPPORTED(_exit(1), "") << "exit in switch case"; + +#ifdef _MSC_VER +#pragma warning(pop) +#endif // _MSC_VER +} + // Tests that a test case whose name ends with "DeathTest" works fine // on Windows. TEST(NotADeathTest, Test) { diff --git a/test/gtest-port_test.cc b/test/gtest-port_test.cc index d980b7ce..97859515 100644 --- a/test/gtest-port_test.cc +++ b/test/gtest-port_test.cc @@ -133,8 +133,6 @@ TEST(GetThreadCountTest, ReturnsZeroWhenUnableToCountThreads) { } #endif // GTEST_OS_MAC -#if GTEST_HAS_DEATH_TEST - TEST(GtestCheckDeathTest, DiesWithCorrectOutputOnFailure) { const bool a_false_condition = false; const char regex[] = @@ -145,9 +143,12 @@ TEST(GtestCheckDeathTest, DiesWithCorrectOutputOnFailure) { #endif // _MSC_VER ".*a_false_condition.*Extra info.*"; - EXPECT_DEATH(GTEST_CHECK_(a_false_condition) << "Extra info", regex); + EXPECT_DEATH_IF_SUPPORTED(GTEST_CHECK_(a_false_condition) << "Extra info", + regex); } +#if GTEST_HAS_DEATH_TEST + TEST(GtestCheckDeathTest, LivesSilentlyOnSuccess) { EXPECT_EXIT({ GTEST_CHECK_(true) << "Extra info"; diff --git a/test/gtest-test-part_test.cc b/test/gtest-test-part_test.cc index 93fe156e..fc94f92b 100644 --- a/test/gtest-test-part_test.cc +++ b/test/gtest-test-part_test.cc @@ -146,8 +146,6 @@ TEST_F(TestPartResultArrayTest, ContainsGivenResultsAfterTwoAppends) { EXPECT_STREQ("Failure 2", results.GetTestPartResult(1).message()); } -#if GTEST_HAS_DEATH_TEST - typedef TestPartResultArrayTest TestPartResultArrayDeathTest; // Tests that the program dies when GetTestPartResult() is called with @@ -156,12 +154,10 @@ TEST_F(TestPartResultArrayDeathTest, DiesWhenIndexIsOutOfBound) { TestPartResultArray results; results.Append(r1_); - EXPECT_DEATH(results.GetTestPartResult(-1), ""); - EXPECT_DEATH(results.GetTestPartResult(1), ""); + EXPECT_DEATH_IF_SUPPORTED(results.GetTestPartResult(-1), ""); + EXPECT_DEATH_IF_SUPPORTED(results.GetTestPartResult(1), ""); } -#endif // GTEST_HAS_DEATH_TEST - // TODO(mheule@google.com): Add a test for the class HasNewFatalFailureHelper. } // namespace diff --git a/test/gtest-typed-test_test.cc b/test/gtest-typed-test_test.cc index 8e86ac8c..e97598fb 100644 --- a/test/gtest-typed-test_test.cc +++ b/test/gtest-typed-test_test.cc @@ -198,24 +198,22 @@ TEST_F(TypedTestCasePStateTest, IgnoresOrderAndSpaces) { state_.VerifyRegisteredTestNames("foo.cc", 1, tests)); } -#if GTEST_HAS_DEATH_TEST - typedef TypedTestCasePStateTest TypedTestCasePStateDeathTest; TEST_F(TypedTestCasePStateDeathTest, DetectsDuplicates) { - EXPECT_DEATH( + EXPECT_DEATH_IF_SUPPORTED( state_.VerifyRegisteredTestNames("foo.cc", 1, "A, B, A, C"), "foo\\.cc.1.?: Test A is listed more than once\\."); } TEST_F(TypedTestCasePStateDeathTest, DetectsExtraTest) { - EXPECT_DEATH( + EXPECT_DEATH_IF_SUPPORTED( state_.VerifyRegisteredTestNames("foo.cc", 1, "A, B, C, D"), "foo\\.cc.1.?: No test named D can be found in this test case\\."); } TEST_F(TypedTestCasePStateDeathTest, DetectsMissedTest) { - EXPECT_DEATH( + EXPECT_DEATH_IF_SUPPORTED( state_.VerifyRegisteredTestNames("foo.cc", 1, "A, C"), "foo\\.cc.1.?: You forgot to list test B\\."); } @@ -224,14 +222,12 @@ TEST_F(TypedTestCasePStateDeathTest, DetectsMissedTest) { // a run-time error if the test case has been registered. TEST_F(TypedTestCasePStateDeathTest, DetectsTestAfterRegistration) { state_.VerifyRegisteredTestNames("foo.cc", 1, "A, B, C"); - EXPECT_DEATH( + EXPECT_DEATH_IF_SUPPORTED( state_.AddTestName("foo.cc", 2, "FooTest", "D"), "foo\\.cc.2.?: Test D must be defined before REGISTER_TYPED_TEST_CASE_P" "\\(FooTest, \\.\\.\\.\\)\\."); } -#endif // GTEST_HAS_DEATH_TEST - // Tests that SetUpTestCase()/TearDownTestCase(), fixture ctor/dtor, // and SetUp()/TearDown() work correctly in type-parameterized tests. diff --git a/test/gtest_filter_unittest_.cc b/test/gtest_filter_unittest_.cc index 3cbddcf6..325504fe 100644 --- a/test/gtest_filter_unittest_.cc +++ b/test/gtest_filter_unittest_.cc @@ -92,19 +92,13 @@ TEST(BazTest, DISABLED_TestC) { // Test case HasDeathTest TEST(HasDeathTest, Test1) { -#if GTEST_HAS_DEATH_TEST - EXPECT_DEATH({exit(1);}, - ".*"); -#endif // GTEST_HAS_DEATH_TEST + EXPECT_DEATH_IF_SUPPORTED(exit(1), ".*"); } // We need at least two death tests to make sure that the all death tests // aren't on the first shard. TEST(HasDeathTest, Test2) { -#if GTEST_HAS_DEATH_TEST - EXPECT_DEATH({exit(1);}, - ".*"); -#endif // GTEST_HAS_DEATH_TEST + EXPECT_DEATH_IF_SUPPORTED(exit(1), ".*"); } // Test case FoobarTest diff --git a/test/gtest_repeat_test.cc b/test/gtest_repeat_test.cc index 39a0601d..8ec3700c 100644 --- a/test/gtest_repeat_test.cc +++ b/test/gtest_repeat_test.cc @@ -112,13 +112,11 @@ int g_death_test_count = 0; TEST(BarDeathTest, ThreadSafeAndFast) { g_death_test_count++; -#if GTEST_HAS_DEATH_TEST GTEST_FLAG(death_test_style) = "threadsafe"; - EXPECT_DEATH(abort(), ""); + EXPECT_DEATH_IF_SUPPORTED(abort(), ""); GTEST_FLAG(death_test_style) = "fast"; - EXPECT_DEATH(abort(), ""); -#endif // GTEST_HAS_DEATH_TEST + EXPECT_DEATH_IF_SUPPORTED(abort(), ""); } #if GTEST_HAS_PARAM_TEST diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index dcec9dad..07e60f51 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -6345,16 +6345,14 @@ TEST(EventListenerTest, SuppressEventForwarding) { EXPECT_EQ(0, on_start_counter); } -#if GTEST_HAS_DEATH_TEST // Tests that events generated by Google Test are not forwarded in // death test subprocesses. TEST(EventListenerDeathTest, EventsNotForwardedInDeathTestSubprecesses) { - EXPECT_DEATH({ // NOLINT + EXPECT_DEATH_IF_SUPPORTED({ GTEST_CHECK_(EventListenersAccessor::EventForwardingEnabled( *GetUnitTestImpl()->listeners())) << "expected failure";}, "expected failure"); } -#endif // GTEST_HAS_DEATH_TEST // Tests that a listener installed via SetDefaultResultPrinter() starts // receiving events and is returned via default_result_printer() and that -- cgit v1.2.3 From 866f4a94461d765f7f9514b6cb6e82d7b9ea12d2 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Wed, 16 Sep 2009 06:59:17 +0000 Subject: Simplifies the implementation of GTEST_LOG_ & GTEST_LOG_; renames GTEST_HIDE_UNREACHABLE_CODE_ to GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_ (by Vlad Losev). --- test/gtest-death-test_test.cc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'test') diff --git a/test/gtest-death-test_test.cc b/test/gtest-death-test_test.cc index f56f35dc..1b0061a6 100644 --- a/test/gtest-death-test_test.cc +++ b/test/gtest-death-test_test.cc @@ -143,7 +143,7 @@ class MayDie { // A member function that may die. void MemberFunction() const { if (should_die_) { - GTEST_LOG_(FATAL, "death inside MayDie::MemberFunction()."); + GTEST_LOG_(FATAL) << "death inside MayDie::MemberFunction()."; } } @@ -154,26 +154,26 @@ class MayDie { // A global function that's expected to die. void GlobalFunction() { - GTEST_LOG_(FATAL, "death inside GlobalFunction()."); + GTEST_LOG_(FATAL) << "death inside GlobalFunction()."; } // A non-void function that's expected to die. int NonVoidFunction() { - GTEST_LOG_(FATAL, "death inside NonVoidFunction()."); + GTEST_LOG_(FATAL) << "death inside NonVoidFunction()."; return 1; } // A unary function that may die. void DieIf(bool should_die) { if (should_die) { - GTEST_LOG_(FATAL, "death inside DieIf()."); + GTEST_LOG_(FATAL) << "death inside DieIf()."; } } // A binary function that may die. bool DieIfLessThan(int x, int y) { if (x < y) { - GTEST_LOG_(FATAL, "death inside DieIfLessThan()."); + GTEST_LOG_(FATAL) << "death inside DieIfLessThan()."; } return true; } @@ -188,7 +188,7 @@ void DeathTestSubroutine() { int DieInDebugElse12(int* sideeffect) { if (sideeffect) *sideeffect = 12; #ifndef NDEBUG - GTEST_LOG_(FATAL, "debug death inside DieInDebugElse12()"); + GTEST_LOG_(FATAL) << "debug death inside DieInDebugElse12()"; #endif // NDEBUG return 12; } -- cgit v1.2.3 From 12d740faef11779b27b17c558ca92622bc0d2b54 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Thu, 17 Sep 2009 05:04:08 +0000 Subject: Makes gtest compile clean with MSVC's warning 4100 (unused formal parameter) enabled. --- test/gtest-death-test_test.cc | 7 ++++--- test/gtest-listener_test.cc | 22 +++++++++++----------- 2 files changed, 15 insertions(+), 14 deletions(-) (limited to 'test') diff --git a/test/gtest-death-test_test.cc b/test/gtest-death-test_test.cc index 1b0061a6..7cc4cafc 100644 --- a/test/gtest-death-test_test.cc +++ b/test/gtest-death-test_test.cc @@ -824,9 +824,10 @@ void MockDeathTestFactory::SetParameters(bool create, // Sets test to NULL (if create_ is false) or to the address of a new // MockDeathTest object with parameters taken from the last call // to SetParameters (if create_ is true). Always returns true. -bool MockDeathTestFactory::Create(const char* statement, - const ::testing::internal::RE* regex, - const char* file, int line, +bool MockDeathTestFactory::Create(const char* /*statement*/, + const ::testing::internal::RE* /*regex*/, + const char* /*file*/, + int /*line*/, DeathTest** test) { test_deleted_ = false; if (create_) { diff --git a/test/gtest-listener_test.cc b/test/gtest-listener_test.cc index fb6fcf48..75c2c184 100644 --- a/test/gtest-listener_test.cc +++ b/test/gtest-listener_test.cc @@ -74,47 +74,47 @@ class UnitTestAccessor { class EventRecordingListener : public UnitTestEventListenerInterface { protected: - virtual void OnUnitTestStart(const UnitTest& unit_test) { + virtual void OnUnitTestStart(const UnitTest& /*unit_test*/) { g_events->PushBack(String("TestEventListener::OnUnitTestStart")); } - virtual void OnGlobalSetUpStart(const UnitTest& unit_test) { + virtual void OnGlobalSetUpStart(const UnitTest& /*unit_test*/) { g_events->PushBack(String("TestEventListener::OnGlobalSetUpStart")); } - virtual void OnGlobalSetUpEnd(const UnitTest& unit_test) { + virtual void OnGlobalSetUpEnd(const UnitTest& /*unit_test*/) { g_events->PushBack(String("TestEventListener::OnGlobalSetUpEnd")); } - virtual void OnTestCaseStart(const TestCase& test_case) { + virtual void OnTestCaseStart(const TestCase& /*test_case*/) { g_events->PushBack(String("TestEventListener::OnTestCaseStart")); } - virtual void OnTestStart(const TestInfo& test_info) { + virtual void OnTestStart(const TestInfo& /*test_info*/) { g_events->PushBack(String("TestEventListener::OnTestStart")); } - virtual void OnNewTestPartResult(const TestPartResult& test_part_result) { + virtual void OnNewTestPartResult(const TestPartResult& /*test_part_result*/) { g_events->PushBack(String("TestEventListener::OnNewTestPartResult")); } - virtual void OnTestEnd(const TestInfo& test_info) { + virtual void OnTestEnd(const TestInfo& /*test_info*/) { g_events->PushBack(String("TestEventListener::OnTestEnd")); } - virtual void OnTestCaseEnd(const TestCase& test_case) { + virtual void OnTestCaseEnd(const TestCase& /*test_case*/) { g_events->PushBack(String("TestEventListener::OnTestCaseEnd")); } - virtual void OnGlobalTearDownStart(const UnitTest& unit_test) { + virtual void OnGlobalTearDownStart(const UnitTest& /*unit_test*/) { g_events->PushBack(String("TestEventListener::OnGlobalTearDownStart")); } - virtual void OnGlobalTearDownEnd(const UnitTest& unit_test) { + virtual void OnGlobalTearDownEnd(const UnitTest& /*unit_test*/) { g_events->PushBack(String("TestEventListener::OnGlobalTearDownEnd")); } - virtual void OnUnitTestEnd(const UnitTest& unit_test) { + virtual void OnUnitTestEnd(const UnitTest& /*unit_test*/) { g_events->PushBack(String("TestEventListener::OnUnitTestEnd")); } }; -- cgit v1.2.3 From f43e4ff3ad12ace9d423cc3ce02feadb8f24fe67 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Thu, 17 Sep 2009 19:12:30 +0000 Subject: Renames the methods in the event listener API, and changes the order of *End events (by Vlad Losev). --- test/gtest-listener_test.cc | 191 ++++++++++++++++++++++++++++++++++---------- test/gtest_unittest.cc | 99 ++++++++++++++++------- 2 files changed, 219 insertions(+), 71 deletions(-) (limited to 'test') diff --git a/test/gtest-listener_test.cc b/test/gtest-listener_test.cc index 75c2c184..95ff0b11 100644 --- a/test/gtest-listener_test.cc +++ b/test/gtest-listener_test.cc @@ -73,50 +73,78 @@ class UnitTestAccessor { }; class EventRecordingListener : public UnitTestEventListenerInterface { + public: + EventRecordingListener(const char* name) : name_(name) {} + protected: - virtual void OnUnitTestStart(const UnitTest& /*unit_test*/) { - g_events->PushBack(String("TestEventListener::OnUnitTestStart")); + virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) { + g_events->PushBack(GetFullMethodName("OnTestProgramStart")); + } + + virtual void OnTestIterationStart(const UnitTest& /*unit_test*/, + int iteration) { + Message message; + message << GetFullMethodName("OnTestIterationStart") + << "(" << iteration << ")"; + g_events->PushBack(message.GetString()); } - virtual void OnGlobalSetUpStart(const UnitTest& /*unit_test*/) { - g_events->PushBack(String("TestEventListener::OnGlobalSetUpStart")); + virtual void OnEnvironmentsSetUpStart(const UnitTest& /*unit_test*/) { + g_events->PushBack(GetFullMethodName("OnEnvironmentsSetUpStart")); } - virtual void OnGlobalSetUpEnd(const UnitTest& /*unit_test*/) { - g_events->PushBack(String("TestEventListener::OnGlobalSetUpEnd")); + virtual void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) { + g_events->PushBack(GetFullMethodName("OnEnvironmentsSetUpEnd")); } virtual void OnTestCaseStart(const TestCase& /*test_case*/) { - g_events->PushBack(String("TestEventListener::OnTestCaseStart")); + g_events->PushBack(GetFullMethodName("OnTestCaseStart")); } virtual void OnTestStart(const TestInfo& /*test_info*/) { - g_events->PushBack(String("TestEventListener::OnTestStart")); + g_events->PushBack(GetFullMethodName("OnTestStart")); } - virtual void OnNewTestPartResult(const TestPartResult& /*test_part_result*/) { - g_events->PushBack(String("TestEventListener::OnNewTestPartResult")); + virtual void OnTestPartResult(const TestPartResult& /*test_part_result*/) { + g_events->PushBack(GetFullMethodName("OnTestPartResult")); } virtual void OnTestEnd(const TestInfo& /*test_info*/) { - g_events->PushBack(String("TestEventListener::OnTestEnd")); + g_events->PushBack(GetFullMethodName("OnTestEnd")); } virtual void OnTestCaseEnd(const TestCase& /*test_case*/) { - g_events->PushBack(String("TestEventListener::OnTestCaseEnd")); + g_events->PushBack(GetFullMethodName("OnTestCaseEnd")); } - virtual void OnGlobalTearDownStart(const UnitTest& /*unit_test*/) { - g_events->PushBack(String("TestEventListener::OnGlobalTearDownStart")); + virtual void OnEnvironmentsTearDownStart(const UnitTest& /*unit_test*/) { + g_events->PushBack(GetFullMethodName("OnEnvironmentsTearDownStart")); } - virtual void OnGlobalTearDownEnd(const UnitTest& /*unit_test*/) { - g_events->PushBack(String("TestEventListener::OnGlobalTearDownEnd")); + virtual void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) { + g_events->PushBack(GetFullMethodName("OnEnvironmentsTearDownEnd")); } - virtual void OnUnitTestEnd(const UnitTest& /*unit_test*/) { - g_events->PushBack(String("TestEventListener::OnUnitTestEnd")); + virtual void OnTestIterationEnd(const UnitTest& /*unit_test*/, + int iteration) { + Message message; + message << GetFullMethodName("OnTestIterationEnd") + << "(" << iteration << ")"; + g_events->PushBack(message.GetString()); } + + virtual void OnTestProgramEnd(const UnitTest& /*unit_test*/) { + g_events->PushBack(GetFullMethodName("OnTestProgramEnd")); + } + + private: + String GetFullMethodName(const char* name) { + Message message; + message << name_ << "." << name; + return message.GetString(); + } + + String name_; }; class EnvironmentInvocationCatcher : public Environment { @@ -169,57 +197,132 @@ using ::testing::internal::EnvironmentInvocationCatcher; using ::testing::internal::EventRecordingListener; using ::testing::internal::UnitTestAccessor; +void VerifyResults(const Vector& data, + const char* const* expected_data, + int expected_data_size) { + const int actual_size = data.size(); + // If the following assertion fails, a new entry will be appended to + // data. Hence we save data.size() first. + EXPECT_EQ(expected_data_size, actual_size); + + // Compares the common prefix. + const int shorter_size = expected_data_size <= actual_size ? + expected_data_size : actual_size; + int i = 0; + for (; i < shorter_size; ++i) { + ASSERT_STREQ(expected_data[i], data.GetElement(i).c_str()) + << "at position " << i; + } + + // Prints extra elements in the actual data. + for (; i < actual_size; ++i) { + printf(" Actual event #%d: %s\n", i, data.GetElement(i).c_str()); + } +} + int main(int argc, char **argv) { Vector events; g_events = &events; InitGoogleTest(&argc, argv); - UnitTestEventListenerInterface* listener = new EventRecordingListener; - UnitTestAccessor::GetEventListeners().Append(listener); + UnitTestAccessor::GetEventListeners().Append( + new EventRecordingListener("1st")); + UnitTestAccessor::GetEventListeners().Append( + new EventRecordingListener("2nd")); AddGlobalTestEnvironment(new EnvironmentInvocationCatcher); GTEST_CHECK_(events.size() == 0) << "AddGlobalTestEnvironment should not generate any events itself."; + ::testing::GTEST_FLAG(repeat) = 2; int ret_val = RUN_ALL_TESTS(); const char* const expected_events[] = { - "TestEventListener::OnUnitTestStart", - "TestEventListener::OnGlobalSetUpStart", + "1st.OnTestProgramStart", + "2nd.OnTestProgramStart", + "1st.OnTestIterationStart(0)", + "2nd.OnTestIterationStart(0)", + "1st.OnEnvironmentsSetUpStart", + "2nd.OnEnvironmentsSetUpStart", "Environment::SetUp", - "TestEventListener::OnGlobalSetUpEnd", - "TestEventListener::OnTestCaseStart", + "2nd.OnEnvironmentsSetUpEnd", + "1st.OnEnvironmentsSetUpEnd", + "1st.OnTestCaseStart", + "2nd.OnTestCaseStart", "ListenerTest::SetUpTestCase", - "TestEventListener::OnTestStart", + "1st.OnTestStart", + "2nd.OnTestStart", "ListenerTest::SetUp", "ListenerTest::* Test Body", - "TestEventListener::OnNewTestPartResult", + "1st.OnTestPartResult", + "2nd.OnTestPartResult", "ListenerTest::TearDown", - "TestEventListener::OnTestEnd", - "TestEventListener::OnTestStart", + "2nd.OnTestEnd", + "1st.OnTestEnd", + "1st.OnTestStart", + "2nd.OnTestStart", "ListenerTest::SetUp", "ListenerTest::* Test Body", - "TestEventListener::OnNewTestPartResult", + "1st.OnTestPartResult", + "2nd.OnTestPartResult", "ListenerTest::TearDown", - "TestEventListener::OnTestEnd", + "2nd.OnTestEnd", + "1st.OnTestEnd", "ListenerTest::TearDownTestCase", - "TestEventListener::OnTestCaseEnd", - "TestEventListener::OnGlobalTearDownStart", + "2nd.OnTestCaseEnd", + "1st.OnTestCaseEnd", + "1st.OnEnvironmentsTearDownStart", + "2nd.OnEnvironmentsTearDownStart", "Environment::TearDown", - "TestEventListener::OnGlobalTearDownEnd", - "TestEventListener::OnUnitTestEnd" + "2nd.OnEnvironmentsTearDownEnd", + "1st.OnEnvironmentsTearDownEnd", + "2nd.OnTestIterationEnd(0)", + "1st.OnTestIterationEnd(0)", + "1st.OnTestIterationStart(1)", + "2nd.OnTestIterationStart(1)", + "1st.OnEnvironmentsSetUpStart", + "2nd.OnEnvironmentsSetUpStart", + "Environment::SetUp", + "2nd.OnEnvironmentsSetUpEnd", + "1st.OnEnvironmentsSetUpEnd", + "1st.OnTestCaseStart", + "2nd.OnTestCaseStart", + "ListenerTest::SetUpTestCase", + "1st.OnTestStart", + "2nd.OnTestStart", + "ListenerTest::SetUp", + "ListenerTest::* Test Body", + "1st.OnTestPartResult", + "2nd.OnTestPartResult", + "ListenerTest::TearDown", + "2nd.OnTestEnd", + "1st.OnTestEnd", + "1st.OnTestStart", + "2nd.OnTestStart", + "ListenerTest::SetUp", + "ListenerTest::* Test Body", + "1st.OnTestPartResult", + "2nd.OnTestPartResult", + "ListenerTest::TearDown", + "2nd.OnTestEnd", + "1st.OnTestEnd", + "ListenerTest::TearDownTestCase", + "2nd.OnTestCaseEnd", + "1st.OnTestCaseEnd", + "1st.OnEnvironmentsTearDownStart", + "2nd.OnEnvironmentsTearDownStart", + "Environment::TearDown", + "2nd.OnEnvironmentsTearDownEnd", + "1st.OnEnvironmentsTearDownEnd", + "2nd.OnTestIterationEnd(1)", + "1st.OnTestIterationEnd(1)", + "2nd.OnTestProgramEnd", + "1st.OnTestProgramEnd" }; - const int kExpectedEventsSize = - sizeof(expected_events)/sizeof(expected_events[0]); - - // Cannot use ASSERT_EQ() here because it requires the scoping function to - // return void. - GTEST_CHECK_(events.size() == kExpectedEventsSize); - - for (int i = 0; i < events.size(); ++i) - GTEST_CHECK_(String(events.GetElement(i)) == expected_events[i]) - << "At position " << i; + VerifyResults(events, + expected_events, + sizeof(expected_events)/sizeof(expected_events[0])); // We need to check manually for ad hoc test failures that happen after // RUN_ALL_TESTS finishes. diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index 07e60f51..0cb202c1 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -6215,7 +6215,7 @@ class TestListener : public EmptyTestEventListener { } protected: - virtual void OnUnitTestStart(const UnitTest& /*unit_test*/) { + virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) { if (on_start_counter_ != NULL) (*on_start_counter_)++; } @@ -6269,43 +6269,88 @@ TEST(EventListenersTest, Append) { { EventListeners listeners; listeners.Append(listener); - EventListenersAccessor::GetRepeater(&listeners)->OnUnitTestStart( + EventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart( *UnitTest::GetInstance()); EXPECT_EQ(1, on_start_counter); } EXPECT_TRUE(is_destroyed); } -// Tests that listeners receive requests in the order they were appended to -// the list. +// Tests that listeners receive events in the order they were appended to +// the list, except for *End requests, which must be received in the reverse +// order. class SequenceTestingListener : public EmptyTestEventListener { public: - SequenceTestingListener(Vector* vector, const char* signature) - : vector_(vector), signature_(signature) {} + SequenceTestingListener(Vector* vector, const char* id) + : vector_(vector), id_(id) {} protected: - virtual void OnUnitTestStart(const UnitTest& /*unit_test*/) { - if (vector_ != NULL) - vector_->PushBack(signature_); + virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) { + vector_->PushBack(GetEventDescription("OnTestProgramStart")); + } + + virtual void OnTestProgramEnd(const UnitTest& /*unit_test*/) { + vector_->PushBack(GetEventDescription("OnTestProgramEnd")); + } + + virtual void OnTestIterationStart(const UnitTest& /*unit_test*/, + int /*iteration*/) { + vector_->PushBack(GetEventDescription("OnTestIterationStart")); + } + + virtual void OnTestIterationEnd(const UnitTest& /*unit_test*/, + int /*iteration*/) { + vector_->PushBack(GetEventDescription("OnTestIterationEnd")); } private: - Vector* vector_; - const char* const signature_; + String GetEventDescription(const char* method) { + Message message; + message << id_ << "." << method; + return message.GetString(); + } + + Vector* vector_; + const char* const id_; }; TEST(EventListenerTest, AppendKeepsOrder) { - Vector vec; + Vector vec; EventListeners listeners; - listeners.Append(new SequenceTestingListener(&vec, "0")); - listeners.Append(new SequenceTestingListener(&vec, "1")); - listeners.Append(new SequenceTestingListener(&vec, "2")); - EventListenersAccessor::GetRepeater(&listeners)->OnUnitTestStart( + listeners.Append(new SequenceTestingListener(&vec, "1st")); + listeners.Append(new SequenceTestingListener(&vec, "2nd")); + listeners.Append(new SequenceTestingListener(&vec, "3rd")); + + EventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart( + *UnitTest::GetInstance()); + ASSERT_EQ(3, vec.size()); + EXPECT_STREQ("1st.OnTestProgramStart", vec.GetElement(0).c_str()); + EXPECT_STREQ("2nd.OnTestProgramStart", vec.GetElement(1).c_str()); + EXPECT_STREQ("3rd.OnTestProgramStart", vec.GetElement(2).c_str()); + + vec.Clear(); + EventListenersAccessor::GetRepeater(&listeners)->OnTestProgramEnd( *UnitTest::GetInstance()); ASSERT_EQ(3, vec.size()); - ASSERT_STREQ("0", vec.GetElement(0)); - ASSERT_STREQ("1", vec.GetElement(1)); - ASSERT_STREQ("2", vec.GetElement(2)); + EXPECT_STREQ("3rd.OnTestProgramEnd", vec.GetElement(0).c_str()); + EXPECT_STREQ("2nd.OnTestProgramEnd", vec.GetElement(1).c_str()); + EXPECT_STREQ("1st.OnTestProgramEnd", vec.GetElement(2).c_str()); + + vec.Clear(); + EventListenersAccessor::GetRepeater(&listeners)->OnTestIterationStart( + *UnitTest::GetInstance(), 0); + ASSERT_EQ(3, vec.size()); + EXPECT_STREQ("1st.OnTestIterationStart", vec.GetElement(0).c_str()); + EXPECT_STREQ("2nd.OnTestIterationStart", vec.GetElement(1).c_str()); + EXPECT_STREQ("3rd.OnTestIterationStart", vec.GetElement(2).c_str()); + + vec.Clear(); + EventListenersAccessor::GetRepeater(&listeners)->OnTestIterationEnd( + *UnitTest::GetInstance(), 0); + ASSERT_EQ(3, vec.size()); + EXPECT_STREQ("3rd.OnTestIterationEnd", vec.GetElement(0).c_str()); + EXPECT_STREQ("2nd.OnTestIterationEnd", vec.GetElement(1).c_str()); + EXPECT_STREQ("1st.OnTestIterationEnd", vec.GetElement(2).c_str()); } // Tests that a listener removed from an EventListeners list stops receiving @@ -6321,7 +6366,7 @@ TEST(EventListenersTest, Release) { EventListeners listeners; listeners.Append(listener); EXPECT_EQ(listener, listeners.Release(listener)); - EventListenersAccessor::GetRepeater(&listeners)->OnUnitTestStart( + EventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart( *UnitTest::GetInstance()); EXPECT_TRUE(listeners.Release(listener) == NULL); } @@ -6340,7 +6385,7 @@ TEST(EventListenerTest, SuppressEventForwarding) { ASSERT_TRUE(EventListenersAccessor::EventForwardingEnabled(listeners)); EventListenersAccessor::SuppressEventForwarding(&listeners); ASSERT_FALSE(EventListenersAccessor::EventForwardingEnabled(listeners)); - EventListenersAccessor::GetRepeater(&listeners)->OnUnitTestStart( + EventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart( *UnitTest::GetInstance()); EXPECT_EQ(0, on_start_counter); } @@ -6367,7 +6412,7 @@ TEST(EventListenerTest, default_result_printer) { EXPECT_EQ(listener, listeners.default_result_printer()); - EventListenersAccessor::GetRepeater(&listeners)->OnUnitTestStart( + EventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart( *UnitTest::GetInstance()); EXPECT_EQ(1, on_start_counter); @@ -6381,7 +6426,7 @@ TEST(EventListenerTest, default_result_printer) { // After broadcasting an event the counter is still the same, indicating // the listener is not in the list anymore. - EventListenersAccessor::GetRepeater(&listeners)->OnUnitTestStart( + EventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart( *UnitTest::GetInstance()); EXPECT_EQ(1, on_start_counter); } @@ -6404,7 +6449,7 @@ TEST(EventListenerTest, RemovingDefaultResultPrinterWorks) { EXPECT_FALSE(is_destroyed); // Broadcasting events now should not affect default_result_printer. - EventListenersAccessor::GetRepeater(&listeners)->OnUnitTestStart( + EventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart( *UnitTest::GetInstance()); EXPECT_EQ(0, on_start_counter); } @@ -6426,7 +6471,7 @@ TEST(EventListenerTest, default_xml_generator) { EXPECT_EQ(listener, listeners.default_xml_generator()); - EventListenersAccessor::GetRepeater(&listeners)->OnUnitTestStart( + EventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart( *UnitTest::GetInstance()); EXPECT_EQ(1, on_start_counter); @@ -6440,7 +6485,7 @@ TEST(EventListenerTest, default_xml_generator) { // After broadcasting an event the counter is still the same, indicating // the listener is not in the list anymore. - EventListenersAccessor::GetRepeater(&listeners)->OnUnitTestStart( + EventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart( *UnitTest::GetInstance()); EXPECT_EQ(1, on_start_counter); } @@ -6463,7 +6508,7 @@ TEST(EventListenerTest, RemovingDefaultXmlGeneratorWorks) { EXPECT_FALSE(is_destroyed); // Broadcasting events now should not affect default_xml_generator. - EventListenersAccessor::GetRepeater(&listeners)->OnUnitTestStart( + EventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart( *UnitTest::GetInstance()); EXPECT_EQ(0, on_start_counter); } -- cgit v1.2.3 From 9f894c2b36e83e9414b3369f9a4974644d843d8d Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Fri, 18 Sep 2009 16:35:15 +0000 Subject: Makes gtest compile cleanly with MSVC's warning 4511 & 4512 (copy ctor / assignment operator cannot be generated) enabled. --- test/gtest_unittest.cc | 2 ++ 1 file changed, 2 insertions(+) (limited to 'test') diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index 0cb202c1..8a2ba54c 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -6312,6 +6312,8 @@ class SequenceTestingListener : public EmptyTestEventListener { Vector* vector_; const char* const id_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(SequenceTestingListener); }; TEST(EventListenerTest, AppendKeepsOrder) { -- cgit v1.2.3 From e5373af0cb9cae249e7bc618cae3483397332895 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Fri, 18 Sep 2009 18:16:20 +0000 Subject: Renames the TestPartResult type enums and adjusts the order of methods in the event listener interface (by Vlad Losev). --- test/gtest-test-part_test.cc | 20 ++++++++------------ test/gtest_unittest.cc | 38 +++++++++++++++++++++----------------- 2 files changed, 29 insertions(+), 29 deletions(-) (limited to 'test') diff --git a/test/gtest-test-part_test.cc b/test/gtest-test-part_test.cc index fc94f92b..403c1845 100644 --- a/test/gtest-test-part_test.cc +++ b/test/gtest-test-part_test.cc @@ -38,10 +38,6 @@ using testing::Test; using testing::TestPartResult; using testing::TestPartResultArray; -using testing::TPRT_FATAL_FAILURE; -using testing::TPRT_NONFATAL_FAILURE; -using testing::TPRT_SUCCESS; - namespace { // Tests the TestPartResult class. @@ -50,18 +46,18 @@ namespace { class TestPartResultTest : public Test { protected: TestPartResultTest() - : r1_(TPRT_SUCCESS, "foo/bar.cc", 10, "Success!"), - r2_(TPRT_NONFATAL_FAILURE, "foo/bar.cc", -1, "Failure!"), - r3_(TPRT_FATAL_FAILURE, NULL, -1, "Failure!") {} + : r1_(TestPartResult::kSuccess, "foo/bar.cc", 10, "Success!"), + r2_(TestPartResult::kNonFatalFailure, "foo/bar.cc", -1, "Failure!"), + r3_(TestPartResult::kFatalFailure, NULL, -1, "Failure!") {} TestPartResult r1_, r2_, r3_; }; // Tests TestPartResult::type(). TEST_F(TestPartResultTest, type) { - EXPECT_EQ(TPRT_SUCCESS, r1_.type()); - EXPECT_EQ(TPRT_NONFATAL_FAILURE, r2_.type()); - EXPECT_EQ(TPRT_FATAL_FAILURE, r3_.type()); + EXPECT_EQ(TestPartResult::kSuccess, r1_.type()); + EXPECT_EQ(TestPartResult::kNonFatalFailure, r2_.type()); + EXPECT_EQ(TestPartResult::kFatalFailure, r3_.type()); } // Tests TestPartResult::file_name(). @@ -114,8 +110,8 @@ TEST_F(TestPartResultTest, NonfatallyFailed) { class TestPartResultArrayTest : public Test { protected: TestPartResultArrayTest() - : r1_(TPRT_NONFATAL_FAILURE, "foo/bar.cc", -1, "Failure 1"), - r2_(TPRT_FATAL_FAILURE, "foo/bar.cc", -1, "Failure 2") {} + : r1_(TestPartResult::kNonFatalFailure, "foo/bar.cc", -1, "Failure 1"), + r2_(TestPartResult::kFatalFailure, "foo/bar.cc", -1, "Failure 2") {} const TestPartResult r1_, r2_; }; diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index 8a2ba54c..3b1457d4 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -152,9 +152,6 @@ using testing::IsSubstring; using testing::Message; using testing::ScopedFakeTestPartResultReporter; using testing::StaticAssertTypeEq; -using testing::TPRT_FATAL_FAILURE; -using testing::TPRT_NONFATAL_FAILURE; -using testing::TPRT_SUCCESS; using testing::Test; using testing::TestPartResult; using testing::TestPartResultArray; @@ -1404,12 +1401,12 @@ TEST(TestPartResultTest, ConstructorWorks) { message << static_cast(testing::internal::kStackTraceMarker); message << "some unimportant stack trace"; - const TestPartResult result(TPRT_NONFATAL_FAILURE, + const TestPartResult result(TestPartResult::kNonFatalFailure, "some_file.cc", 42, message.GetString().c_str()); - EXPECT_EQ(TPRT_NONFATAL_FAILURE, result.type()); + EXPECT_EQ(TestPartResult::kNonFatalFailure, result.type()); EXPECT_STREQ("some_file.cc", result.file_name()); EXPECT_EQ(42, result.line_number()); EXPECT_STREQ(message.GetString().c_str(), result.message()); @@ -1417,13 +1414,16 @@ TEST(TestPartResultTest, ConstructorWorks) { } TEST(TestPartResultTest, ResultAccessorsWork) { - const TestPartResult success(TPRT_SUCCESS, "file.cc", 42, "message"); + const TestPartResult success(TestPartResult::kSuccess, + "file.cc", + 42, + "message"); EXPECT_TRUE(success.passed()); EXPECT_FALSE(success.failed()); EXPECT_FALSE(success.nonfatally_failed()); EXPECT_FALSE(success.fatally_failed()); - const TestPartResult nonfatal_failure(TPRT_NONFATAL_FAILURE, + const TestPartResult nonfatal_failure(TestPartResult::kNonFatalFailure, "file.cc", 42, "message"); @@ -1432,7 +1432,7 @@ TEST(TestPartResultTest, ResultAccessorsWork) { EXPECT_TRUE(nonfatal_failure.nonfatally_failed()); EXPECT_FALSE(nonfatal_failure.fatally_failed()); - const TestPartResult fatal_failure(TPRT_FATAL_FAILURE, + const TestPartResult fatal_failure(TestPartResult::kFatalFailure, "file.cc", 42, "message"); @@ -1457,10 +1457,14 @@ class TestResultTest : public Test { virtual void SetUp() { // pr1 is for success. - pr1 = new TestPartResult(TPRT_SUCCESS, "foo/bar.cc", 10, "Success!"); + pr1 = new TestPartResult(TestPartResult::kSuccess, + "foo/bar.cc", + 10, + "Success!"); // pr2 is for fatal failure. - pr2 = new TestPartResult(TPRT_FATAL_FAILURE, "foo/bar.cc", + pr2 = new TestPartResult(TestPartResult::kFatalFailure, + "foo/bar.cc", -1, // This line number means "unknown" "Failure!"); @@ -3334,9 +3338,9 @@ TEST_F(NoFatalFailureTest, AssertNoFatalFailureOnFatalFailure) { DoAssertNoFatalFailureOnFails(); } ASSERT_EQ(2, gtest_failures.size()); - EXPECT_EQ(testing::TPRT_FATAL_FAILURE, + EXPECT_EQ(TestPartResult::kFatalFailure, gtest_failures.GetTestPartResult(0).type()); - EXPECT_EQ(testing::TPRT_FATAL_FAILURE, + EXPECT_EQ(TestPartResult::kFatalFailure, gtest_failures.GetTestPartResult(1).type()); EXPECT_PRED_FORMAT2(testing::IsSubstring, "some fatal failure", gtest_failures.GetTestPartResult(0).message()); @@ -3351,11 +3355,11 @@ TEST_F(NoFatalFailureTest, ExpectNoFatalFailureOnFatalFailure) { DoExpectNoFatalFailureOnFails(); } ASSERT_EQ(3, gtest_failures.size()); - EXPECT_EQ(testing::TPRT_FATAL_FAILURE, + EXPECT_EQ(TestPartResult::kFatalFailure, gtest_failures.GetTestPartResult(0).type()); - EXPECT_EQ(testing::TPRT_NONFATAL_FAILURE, + EXPECT_EQ(TestPartResult::kNonFatalFailure, gtest_failures.GetTestPartResult(1).type()); - EXPECT_EQ(testing::TPRT_NONFATAL_FAILURE, + EXPECT_EQ(TestPartResult::kNonFatalFailure, gtest_failures.GetTestPartResult(2).type()); EXPECT_PRED_FORMAT2(testing::IsSubstring, "some fatal failure", gtest_failures.GetTestPartResult(0).message()); @@ -3372,9 +3376,9 @@ TEST_F(NoFatalFailureTest, MessageIsStreamable) { EXPECT_NO_FATAL_FAILURE(FAIL() << "foo") << "my message"; } ASSERT_EQ(2, gtest_failures.size()); - EXPECT_EQ(testing::TPRT_NONFATAL_FAILURE, + EXPECT_EQ(TestPartResult::kNonFatalFailure, gtest_failures.GetTestPartResult(0).type()); - EXPECT_EQ(testing::TPRT_NONFATAL_FAILURE, + EXPECT_EQ(TestPartResult::kNonFatalFailure, gtest_failures.GetTestPartResult(1).type()); EXPECT_PRED_FORMAT2(testing::IsSubstring, "foo", gtest_failures.GetTestPartResult(0).message()); -- cgit v1.2.3 From 2534ae201e47986d36d5fab0e523a7f046b8ec1e Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Mon, 21 Sep 2009 19:42:03 +0000 Subject: Adds a Random class to support --gtest_shuffle (by Josh Kelley); Makes the scons script build in a deterministic order (by Zhanyong Wan). --- test/gtest_unittest.cc | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) (limited to 'test') diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index 3b1457d4..d5315c46 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -183,6 +183,7 @@ using testing::internal::TestProperty; using testing::internal::TestResult; using testing::internal::TestResultAccessor; using testing::internal::ThreadLocal; +using testing::internal::UInt32; using testing::internal::Vector; using testing::internal::WideStringToUtf8; using testing::internal::kTestTypeIdInGoogleTest; @@ -499,6 +500,49 @@ TEST(WideStringToUtf8Test, ConcatenatesCodepointsCorrectly) { } #endif // !GTEST_WIDE_STRING_USES_UTF16_ +// Tests the Random class. + +TEST(RandomDeathTest, GeneratesCrashesOnInvalidRange) { + testing::internal::Random random(42); + EXPECT_DEATH_IF_SUPPORTED( + random.Generate(0), + "Cannot generate a number in the range \\[0, 0\\)"); + EXPECT_DEATH_IF_SUPPORTED( + random.Generate(testing::internal::Random::kMaxRange + 1), + "Generation of a number in \\[0, 2147483649\\) was requested, " + "but this can only generate numbers in \\[0, 2147483648\\)"); +} + +TEST(RandomTest, GeneratesNumbersWithinRange) { + const UInt32 kRange = 10000; + testing::internal::Random random(12345); + for (int i = 0; i < 10; i++) { + EXPECT_LT(random.Generate(kRange), kRange) << " for iteration " << i; + } + + testing::internal::Random random2(testing::internal::Random::kMaxRange); + for (int i = 0; i < 10; i++) { + EXPECT_LT(random2.Generate(kRange), kRange) << " for iteration " << i; + } +} + +TEST(RandomTest, RepeatsWhenReseeded) { + const int kSeed = 123; + const int kArraySize = 10; + const UInt32 kRange = 10000; + UInt32 values[kArraySize]; + + testing::internal::Random random(kSeed); + for (int i = 0; i < kArraySize; i++) { + values[i] = random.Generate(kRange); + } + + random.Reseed(kSeed); + for (int i = 0; i < kArraySize; i++) { + EXPECT_EQ(values[i], random.Generate(kRange)) << " for iteration " << i; + } +} + // Tests the Vector class template. // Tests Vector::Clear(). -- cgit v1.2.3 From b50ef44a3527d958270ff1f08cb99e3ac633bd17 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Thu, 24 Sep 2009 21:15:59 +0000 Subject: Publishes the even listener API (by Vlad Losev); adds OS-indicating macros to simplify gtest code (by Zhanyong Wan). --- test/gtest-filepath_test.cc | 23 ++++++------- test/gtest-listener_test.cc | 23 ++++--------- test/gtest-options_test.cc | 8 ++--- test/gtest-unittest-api_test.cc | 66 +++++++++++++------------------------- test/gtest_stress_test.cc | 1 - test/gtest_unittest.cc | 46 +++++++++++++------------- test/gtest_xml_output_unittest_.cc | 20 ++---------- 7 files changed, 68 insertions(+), 119 deletions(-) (limited to 'test') diff --git a/test/gtest-filepath_test.cc b/test/gtest-filepath_test.cc index adf97467..5bc4daf2 100644 --- a/test/gtest-filepath_test.cc +++ b/test/gtest-filepath_test.cc @@ -50,17 +50,17 @@ #include "src/gtest-internal-inl.h" #undef GTEST_IMPLEMENTATION_ -#ifdef _WIN32_WCE +#if GTEST_OS_WINDOWS_MOBILE #include // NOLINT #elif GTEST_OS_WINDOWS #include // NOLINT -#endif // _WIN32_WCE +#endif // GTEST_OS_WINDOWS_MOBILE namespace testing { namespace internal { namespace { -#ifdef _WIN32_WCE +#if GTEST_OS_WINDOWS_MOBILE // TODO(wan@google.com): Move these to the POSIX adapter section in // gtest-port.h. @@ -81,9 +81,7 @@ int _rmdir(const char* path) { return ret; } -#endif // _WIN32_WCE - -#ifndef _WIN32_WCE +#else TEST(GetCurrentDirTest, ReturnsCurrentDir) { const FilePath original_dir = FilePath::GetCurrentDir(); @@ -103,7 +101,7 @@ TEST(GetCurrentDirTest, ReturnsCurrentDir) { #endif } -#endif // _WIN32_WCE +#endif // GTEST_OS_WINDOWS_MOBILE TEST(IsEmptyTest, ReturnsTrueForEmptyPath) { EXPECT_TRUE(FilePath("").IsEmpty()); @@ -156,7 +154,7 @@ TEST(RemoveDirectoryNameTest, ShouldAlsoGiveFileName) { // RemoveFileName "" -> "./" TEST(RemoveFileNameTest, EmptyName) { -#ifdef _WIN32_WCE +#if GTEST_OS_WINDOWS_MOBILE // On Windows CE, we use the root as the current directory. EXPECT_STREQ(GTEST_PATH_SEP_, FilePath("").RemoveFileName().c_str()); @@ -344,12 +342,12 @@ TEST(DirectoryTest, RootOfWrongDriveDoesNotExists) { } #endif // GTEST_OS_WINDOWS -#ifndef _WIN32_WCE +#if !GTEST_OS_WINDOWS_MOBILE // Windows CE _does_ consider an empty directory to exist. TEST(DirectoryTest, EmptyPathDirectoryDoesNotExist) { EXPECT_FALSE(FilePath("").DirectoryExists()); } -#endif // ! _WIN32_WCE +#endif // !GTEST_OS_WINDOWS_MOBILE TEST(DirectoryTest, CurrentDirectoryExists) { #if GTEST_OS_WINDOWS // We are on Windows. @@ -449,9 +447,8 @@ class DirectoryCreationTest : public Test { } String TempDir() const { -#ifdef _WIN32_WCE +#if GTEST_OS_WINDOWS_MOBILE return String("\\temp\\"); - #elif GTEST_OS_WINDOWS const char* temp_dir = posix::GetEnv("TEMP"); if (temp_dir == NULL || temp_dir[0] == '\0') @@ -462,7 +459,7 @@ class DirectoryCreationTest : public Test { return String::Format("%s\\", temp_dir); #else return String("/tmp/"); -#endif +#endif // GTEST_OS_WINDOWS_MOBILE } void CreateTextFile(const char* filename) { diff --git a/test/gtest-listener_test.cc b/test/gtest-listener_test.cc index 95ff0b11..f12f5188 100644 --- a/test/gtest-listener_test.cc +++ b/test/gtest-listener_test.cc @@ -48,12 +48,12 @@ using ::testing::AddGlobalTestEnvironment; using ::testing::Environment; using ::testing::InitGoogleTest; using ::testing::Test; +using ::testing::TestCase; +using ::testing::TestEventListener; using ::testing::TestInfo; using ::testing::TestPartResult; using ::testing::UnitTest; using ::testing::internal::String; -using ::testing::internal::TestCase; -using ::testing::internal::UnitTestEventListenerInterface; using ::testing::internal::Vector; // Used by tests to register their events. @@ -62,17 +62,7 @@ Vector* g_events = NULL; namespace testing { namespace internal { -// TODO(vladl@google.com): Remove this and use UnitTest::listeners() -// directly after it is published. -class UnitTestAccessor { - public: - static EventListeners& GetEventListeners() { - return UnitTest::GetInstance()->listeners(); - } - static bool UnitTestFailed() { return UnitTest::GetInstance()->Failed(); } -}; - -class EventRecordingListener : public UnitTestEventListenerInterface { +class EventRecordingListener : public TestEventListener { public: EventRecordingListener(const char* name) : name_(name) {} @@ -195,7 +185,6 @@ TEST_F(ListenerTest, DoesBar) { using ::testing::internal::EnvironmentInvocationCatcher; using ::testing::internal::EventRecordingListener; -using ::testing::internal::UnitTestAccessor; void VerifyResults(const Vector& data, const char* const* expected_data, @@ -225,9 +214,9 @@ int main(int argc, char **argv) { g_events = &events; InitGoogleTest(&argc, argv); - UnitTestAccessor::GetEventListeners().Append( + UnitTest::GetInstance()->listeners().Append( new EventRecordingListener("1st")); - UnitTestAccessor::GetEventListeners().Append( + UnitTest::GetInstance()->listeners().Append( new EventRecordingListener("2nd")); AddGlobalTestEnvironment(new EnvironmentInvocationCatcher); @@ -326,7 +315,7 @@ int main(int argc, char **argv) { // We need to check manually for ad hoc test failures that happen after // RUN_ALL_TESTS finishes. - if (UnitTestAccessor::UnitTestFailed()) + if (UnitTest::GetInstance()->Failed()) ret_val = 1; return ret_val; diff --git a/test/gtest-options_test.cc b/test/gtest-options_test.cc index 43c6d22d..31ae3277 100644 --- a/test/gtest-options_test.cc +++ b/test/gtest-options_test.cc @@ -40,11 +40,11 @@ #include -#ifdef _WIN32_WCE +#if GTEST_OS_WINDOWS_MOBILE #include #elif GTEST_OS_WINDOWS #include -#endif // _WIN32_WCE +#endif // GTEST_OS_WINDOWS_MOBILE // Indicates that this translation unit is part of Google Test's // implementation. It must come before gtest-internal-inl.h is @@ -130,7 +130,7 @@ TEST(XmlOutputTest, GetOutputFileFromDirectoryPath) { TEST(OutputFileHelpersTest, GetCurrentExecutableName) { const FilePath executable = GetCurrentExecutableName(); const char* const exe_str = executable.c_str(); -#if defined(_WIN32_WCE) || GTEST_OS_WINDOWS +#if GTEST_OS_WINDOWS ASSERT_TRUE(_strcmpi("gtest-options_test", exe_str) == 0 || _strcmpi("gtest-options-ex_test", exe_str) == 0 || _strcmpi("gtest_all_test", exe_str) == 0) @@ -143,7 +143,7 @@ TEST(OutputFileHelpersTest, GetCurrentExecutableName) { String(exe_str) == "gtest_all_test" || String(exe_str) == "lt-gtest_all_test") << "GetCurrentExecutableName() returns " << exe_str; -#endif +#endif // GTEST_OS_WINDOWS } class XmlOutputChangeDirTest : public Test { diff --git a/test/gtest-unittest-api_test.cc b/test/gtest-unittest-api_test.cc index 658e2985..7e0f8f80 100644 --- a/test/gtest-unittest-api_test.cc +++ b/test/gtest-unittest-api_test.cc @@ -38,21 +38,7 @@ #include // For strcmp. #include -using ::testing::AddGlobalTestEnvironment; -using ::testing::Environment; using ::testing::InitGoogleTest; -using ::testing::Test; -using ::testing::TestInfo; -using ::testing::TestPartResult; -using ::testing::UnitTest; -using ::testing::internal::TestCase; -using ::testing::internal::TestProperty; - -#if GTEST_HAS_TYPED_TEST -using ::testing::Types; -using ::testing::internal::GetTypeName; -using ::testing::internal::String; -#endif // GTEST_HAS_TYPED_TEST namespace testing { namespace internal { @@ -64,20 +50,20 @@ struct LessByName { } }; -class UnitTestAccessor { +class UnitTestHelper { public: // Returns the array of pointers to all test cases sorted by the test case // name. The caller is responsible for deleting the array. static TestCase const** const GetSortedTestCases() { - UnitTest* unit_test = UnitTest::GetInstance(); + UnitTest& unit_test = *UnitTest::GetInstance(); TestCase const** const test_cases = - new const TestCase*[unit_test->total_test_case_count()]; + new const TestCase*[unit_test.total_test_case_count()]; - for (int i = 0; i < unit_test->total_test_case_count(); ++i) - test_cases[i] = unit_test->GetTestCase(i); + for (int i = 0; i < unit_test.total_test_case_count(); ++i) + test_cases[i] = unit_test.GetTestCase(i); std::sort(test_cases, - test_cases + unit_test->total_test_case_count(), + test_cases + unit_test.total_test_case_count(), LessByName()); return test_cases; } @@ -85,9 +71,9 @@ class UnitTestAccessor { // Returns the test case by its name. The caller doesn't own the returned // pointer. static const TestCase* FindTestCase(const char* name) { - UnitTest* unit_test = UnitTest::GetInstance(); - for (int i = 0; i < unit_test->total_test_case_count(); ++i) { - const TestCase* test_case = unit_test->GetTestCase(i); + UnitTest& unit_test = *UnitTest::GetInstance(); + for (int i = 0; i < unit_test.total_test_case_count(); ++i) { + const TestCase* test_case = unit_test.GetTestCase(i); if (0 == strcmp(test_case->name(), name)) return test_case; } @@ -104,19 +90,12 @@ class UnitTestAccessor { for (int i = 0; i < test_case->total_test_count(); ++i) tests[i] = test_case->GetTestInfo(i); - std::sort(tests, - tests + test_case->total_test_count(), + std::sort(tests, tests + test_case->total_test_count(), LessByName()); return tests; } }; -// TODO(vladl@google.com): Put tests into the internal namespace after -// UnitTest methods are published. -} // namespace internal - -using internal::UnitTestAccessor; - #if GTEST_HAS_TYPED_TEST template class TestCaseWithCommentTest : public Test {}; TYPED_TEST_CASE(TestCaseWithCommentTest, Types); @@ -147,7 +126,7 @@ TEST(ApiTest, UnitTestImmutableAccessorsWork) { EXPECT_EQ(5 + kTypedTests, unit_test->total_test_count()); EXPECT_EQ(3 + kTypedTests, unit_test->test_to_run_count()); - const TestCase** const test_cases = UnitTestAccessor::GetSortedTestCases(); + const TestCase** const test_cases = UnitTestHelper::GetSortedTestCases(); EXPECT_STREQ("ApiTest", test_cases[0]->name()); EXPECT_STREQ("DISABLED_Test", test_cases[1]->name()); @@ -165,7 +144,7 @@ TEST(ApiTest, UnitTestImmutableAccessorsWork) { } TEST(ApiTest, TestCaseImmutableAccessorsWork) { - const TestCase* test_case = UnitTestAccessor::FindTestCase("ApiTest"); + const TestCase* test_case = UnitTestHelper::FindTestCase("ApiTest"); ASSERT_TRUE(test_case != NULL); EXPECT_STREQ("ApiTest", test_case->name()); @@ -175,7 +154,7 @@ TEST(ApiTest, TestCaseImmutableAccessorsWork) { EXPECT_EQ(3, test_case->test_to_run_count()); ASSERT_EQ(4, test_case->total_test_count()); - const TestInfo** tests = UnitTestAccessor::GetSortedTests(test_case); + const TestInfo** tests = UnitTestHelper::GetSortedTests(test_case); EXPECT_STREQ("DISABLED_Dummy1", tests[0]->name()); EXPECT_STREQ("ApiTest", tests[0]->test_case_name()); @@ -205,7 +184,7 @@ TEST(ApiTest, TestCaseImmutableAccessorsWork) { tests = NULL; #if GTEST_HAS_TYPED_TEST - test_case = UnitTestAccessor::FindTestCase("TestCaseWithCommentTest/0"); + test_case = UnitTestHelper::FindTestCase("TestCaseWithCommentTest/0"); ASSERT_TRUE(test_case != NULL); EXPECT_STREQ("TestCaseWithCommentTest/0", test_case->name()); @@ -215,7 +194,7 @@ TEST(ApiTest, TestCaseImmutableAccessorsWork) { EXPECT_EQ(1, test_case->test_to_run_count()); ASSERT_EQ(1, test_case->total_test_count()); - tests = UnitTestAccessor::GetSortedTests(test_case); + tests = UnitTestHelper::GetSortedTests(test_case); EXPECT_STREQ("Dummy", tests[0]->name()); EXPECT_STREQ("TestCaseWithCommentTest/0", tests[0]->test_case_name()); @@ -229,7 +208,7 @@ TEST(ApiTest, TestCaseImmutableAccessorsWork) { } TEST(ApiTest, TestCaseDisabledAccessorsWork) { - const TestCase* test_case = UnitTestAccessor::FindTestCase("DISABLED_Test"); + const TestCase* test_case = UnitTestHelper::FindTestCase("DISABLED_Test"); ASSERT_TRUE(test_case != NULL); EXPECT_STREQ("DISABLED_Test", test_case->name()); @@ -265,7 +244,7 @@ class FinalSuccessChecker : public Environment { EXPECT_FALSE(unit_test->Failed()); ASSERT_EQ(2 + kTypedTestCases, unit_test->total_test_case_count()); - const TestCase** const test_cases = UnitTestAccessor::GetSortedTestCases(); + const TestCase** const test_cases = UnitTestHelper::GetSortedTestCases(); EXPECT_STREQ("ApiTest", test_cases[0]->name()); EXPECT_STREQ("", test_cases[0]->comment()); @@ -298,8 +277,8 @@ class FinalSuccessChecker : public Environment { EXPECT_FALSE(test_cases[2]->Failed()); #endif // GTEST_HAS_TYPED_TEST - const TestCase* test_case = UnitTestAccessor::FindTestCase("ApiTest"); - const TestInfo** tests = UnitTestAccessor::GetSortedTests(test_case); + const TestCase* test_case = UnitTestHelper::FindTestCase("ApiTest"); + const TestInfo** tests = UnitTestHelper::GetSortedTests(test_case); EXPECT_STREQ("DISABLED_Dummy1", tests[0]->name()); EXPECT_STREQ("ApiTest", tests[0]->test_case_name()); EXPECT_FALSE(tests[0]->should_run()); @@ -334,8 +313,8 @@ class FinalSuccessChecker : public Environment { delete[] tests; #if GTEST_HAS_TYPED_TEST - test_case = UnitTestAccessor::FindTestCase("TestCaseWithCommentTest/0"); - tests = UnitTestAccessor::GetSortedTests(test_case); + test_case = UnitTestHelper::FindTestCase("TestCaseWithCommentTest/0"); + tests = UnitTestHelper::GetSortedTests(test_case); EXPECT_STREQ("Dummy", tests[0]->name()); EXPECT_STREQ("TestCaseWithCommentTest/0", tests[0]->test_case_name()); @@ -352,12 +331,13 @@ class FinalSuccessChecker : public Environment { } }; +} // namespace internal } // namespace testing int main(int argc, char **argv) { InitGoogleTest(&argc, argv); - AddGlobalTestEnvironment(new testing::FinalSuccessChecker()); + AddGlobalTestEnvironment(new testing::internal::FinalSuccessChecker()); return RUN_ALL_TESTS(); } diff --git a/test/gtest_stress_test.cc b/test/gtest_stress_test.cc index 57ea75a9..0034bb84 100644 --- a/test/gtest_stress_test.cc +++ b/test/gtest_stress_test.cc @@ -46,7 +46,6 @@ namespace testing { namespace { using internal::String; -using internal::TestProperty; using internal::TestPropertyKeyIs; using internal::Vector; diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index d5315c46..03acfb0f 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -88,16 +88,16 @@ bool ParseInt32Flag(const char* str, const char* flag, Int32* value); // that are needed to test it. class EventListenersAccessor { public: - static UnitTestEventListenerInterface* GetRepeater( - EventListeners* listeners) { return listeners->repeater(); } + static TestEventListener* GetRepeater(EventListeners* listeners) { + return listeners->repeater(); + } - static void SetDefaultResultPrinter( - EventListeners* listeners, - UnitTestEventListenerInterface* listener) { + static void SetDefaultResultPrinter(EventListeners* listeners, + TestEventListener* listener) { listeners->SetDefaultResultPrinter(listener); } static void SetDefaultXmlGenerator(EventListeners* listeners, - UnitTestEventListenerInterface* listener) { + TestEventListener* listener) { listeners->SetDefaultXmlGenerator(listener); } @@ -131,6 +131,8 @@ using testing::AssertionFailure; using testing::AssertionResult; using testing::AssertionSuccess; using testing::DoubleLE; +using testing::EmptyTestEventListener; +using testing::EventListeners; using testing::FloatLE; using testing::GTEST_FLAG(also_run_disabled_tests); using testing::GTEST_FLAG(break_on_failure); @@ -153,16 +155,15 @@ using testing::Message; using testing::ScopedFakeTestPartResultReporter; using testing::StaticAssertTypeEq; using testing::Test; +using testing::TestCase; using testing::TestPartResult; using testing::TestPartResultArray; +using testing::TestProperty; +using testing::TestResult; using testing::UnitTest; -using testing::internal::kMaxRandomSeed; -using testing::internal::kTestTypeIdInGoogleTest; using testing::internal::AppendUserMessage; using testing::internal::CodePointToUtf8; -using testing::internal::EmptyTestEventListener; using testing::internal::EqFailure; -using testing::internal::EventListeners; using testing::internal::FloatingPoint; using testing::internal::GTestFlagSaver; using testing::internal::GetCurrentOsStackTraceExceptTop; @@ -178,14 +179,12 @@ using testing::internal::ShouldShard; using testing::internal::ShouldUseColor; using testing::internal::StreamableToString; using testing::internal::String; -using testing::internal::TestCase; -using testing::internal::TestProperty; -using testing::internal::TestResult; using testing::internal::TestResultAccessor; using testing::internal::ThreadLocal; using testing::internal::UInt32; using testing::internal::Vector; using testing::internal::WideStringToUtf8; +using testing::internal::kMaxRandomSeed; using testing::internal::kTestTypeIdInGoogleTest; using testing::internal::scoped_ptr; @@ -1157,7 +1156,7 @@ TEST(StringTest, ShowWideCStringQuoted) { String::ShowWideCStringQuoted(L"foo").c_str()); } -#ifdef _WIN32_WCE +#if GTEST_OS_WINDOWS_MOBILE TEST(StringTest, AnsiAndUtf16Null) { EXPECT_EQ(NULL, String::AnsiToUtf16(NULL)); EXPECT_EQ(NULL, String::Utf16ToAnsi(NULL)); @@ -1180,7 +1179,7 @@ TEST(StringTest, AnsiAndUtf16ConvertPathChars) { EXPECT_EQ(0, wcsncmp(L".:\\ \"*?", utf16, 3)); delete [] utf16; } -#endif // _WIN32_WCE +#endif // GTEST_OS_WINDOWS_MOBILE #endif // GTEST_OS_WINDOWS @@ -1808,7 +1807,7 @@ TEST_F(GTestFlagSaverTest, VerifyGTestFlags) { // value. If the value argument is "", unsets the environment // variable. The caller must ensure that both arguments are not NULL. static void SetEnv(const char* name, const char* value) { -#ifdef _WIN32_WCE +#if GTEST_OS_WINDOWS_MOBILE // Environment variables are not supported on Windows CE. return; #elif defined(__BORLANDC__) @@ -1826,7 +1825,6 @@ static void SetEnv(const char* name, const char* value) { added_env[name] = new String((Message() << name << "=" << value).GetString()); putenv(added_env[name]->c_str()); delete prev_env; - #elif GTEST_OS_WINDOWS // If we are on Windows proper. _putenv((Message() << name << "=" << value).GetString().c_str()); #else @@ -1835,10 +1833,10 @@ static void SetEnv(const char* name, const char* value) { } else { setenv(name, value, 1); } -#endif +#endif // GTEST_OS_WINDOWS_MOBILE } -#ifndef _WIN32_WCE +#if !GTEST_OS_WINDOWS_MOBILE // Environment variables are not supported on Windows CE. using testing::internal::Int32FromGTestEnv; @@ -1886,7 +1884,7 @@ TEST(Int32FromGTestEnvTest, ParsesAndReturnsValidValue) { SetEnv(GTEST_FLAG_PREFIX_UPPER_ "TEMP", "-321"); EXPECT_EQ(-321, Int32FromGTestEnv("temp", 0)); } -#endif // !defined(_WIN32_WCE) +#endif // !GTEST_OS_WINDOWS_MOBILE // Tests ParseInt32Flag(). @@ -1944,7 +1942,7 @@ TEST(ParseInt32FlagTest, ParsesAndReturnsValidValue) { // Tests that Int32FromEnvOrDie() parses the value of the var or // returns the correct default. // Environment variables are not supported on Windows CE. -#ifndef _WIN32_WCE +#if !GTEST_OS_WINDOWS_MOBILE TEST(Int32FromEnvOrDieTest, ParsesAndReturnsValidValue) { EXPECT_EQ(333, Int32FromEnvOrDie(GTEST_FLAG_PREFIX_UPPER_ "UnsetVar", 333)); SetEnv(GTEST_FLAG_PREFIX_UPPER_ "UnsetVar", "123"); @@ -1952,7 +1950,7 @@ TEST(Int32FromEnvOrDieTest, ParsesAndReturnsValidValue) { SetEnv(GTEST_FLAG_PREFIX_UPPER_ "UnsetVar", "-123"); EXPECT_EQ(-123, Int32FromEnvOrDie(GTEST_FLAG_PREFIX_UPPER_ "UnsetVar", 333)); } -#endif // _WIN32_WCE +#endif // !GTEST_OS_WINDOWS_MOBILE // Tests that Int32FromEnvOrDie() aborts with an error message // if the variable is not an Int32. @@ -2019,7 +2017,7 @@ TEST_F(ShouldShardTest, ReturnsFalseWhenTotalShardIsOne) { // Tests that sharding is enabled if total_shards > 1 and // we are not in a death test subprocess. // Environment variables are not supported on Windows CE. -#ifndef _WIN32_WCE +#if !GTEST_OS_WINDOWS_MOBILE TEST_F(ShouldShardTest, WorksWhenShardEnvVarsAreValid) { SetEnv(index_var_, "4"); SetEnv(total_var_, "22"); @@ -2036,7 +2034,7 @@ TEST_F(ShouldShardTest, WorksWhenShardEnvVarsAreValid) { EXPECT_TRUE(ShouldShard(total_var_, index_var_, false)); EXPECT_FALSE(ShouldShard(total_var_, index_var_, true)); } -#endif // _WIN32_WCE +#endif // !GTEST_OS_WINDOWS_MOBILE // Tests that we exit in error if the sharding values are not valid. diff --git a/test/gtest_xml_output_unittest_.cc b/test/gtest_xml_output_unittest_.cc index bfeda3d8..c0da2151 100644 --- a/test/gtest_xml_output_unittest_.cc +++ b/test/gtest_xml_output_unittest_.cc @@ -40,19 +40,9 @@ #include -// TODO(vladl@google.com): Remove this include when the event listener API is -// published and GetUnitTestImpl is no longer needed. -// -// Indicates that this translation unit is part of Google Test's -// implementation. It must come before gtest-internal-inl.h is -// included, or there will be a compiler error. This trick is to -// prevent a user from accidentally including gtest-internal-inl.h in -// his code. -#define GTEST_IMPLEMENTATION_ 1 -#include "src/gtest-internal-inl.h" -#undef GTEST_IMPLEMENTATION_ - +using ::testing::EventListeners; using ::testing::InitGoogleTest; +using ::testing::UnitTest; class SuccessfulTest : public testing::Test { }; @@ -137,11 +127,7 @@ int main(int argc, char** argv) { InitGoogleTest(&argc, argv); if (argc > 1 && strcmp(argv[1], "--shut_down_xml") == 0) { - // TODO(vladl@google.com): Replace GetUnitTestImpl()->listeners() with - // UnitTest::GetInstance()->listeners() when the event listener API is - // published. - ::testing::internal::EventListeners& listeners = - *::testing::internal::GetUnitTestImpl()->listeners(); + EventListeners& listeners = UnitTest::GetInstance()->listeners(); delete listeners.Release(listeners.default_xml_generator()); } return RUN_ALL_TESTS(); -- cgit v1.2.3 From f8b268ee86ca74bba3276352f1e7de53d1336c3e Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Wed, 30 Sep 2009 20:23:50 +0000 Subject: Makes gtest compile cleanly with MSVC's /W4 (by Zhanyong Wan). Renames EventListenrs to TestEventListeners (by Zhanyong Wan). Fixes invalid characters in XML report (by Vlad Losev). Refacotrs SConscript (by Vlad Losev). --- test/gtest-death-test_test.cc | 19 +++-- test/gtest-port_test.cc | 6 +- test/gtest-typed-test_test.cc | 10 ++- test/gtest_repeat_test.cc | 4 +- test/gtest_unittest.cc | 156 ++++++++++++++++++------------------- test/gtest_xml_output_unittest.py | 16 +++- test/gtest_xml_output_unittest_.cc | 15 +++- test/gtest_xml_test_utils.py | 48 +++++++----- 8 files changed, 154 insertions(+), 120 deletions(-) (limited to 'test') diff --git a/test/gtest-death-test_test.cc b/test/gtest-death-test_test.cc index 7cc4cafc..7bf6a716 100644 --- a/test/gtest-death-test_test.cc +++ b/test/gtest-death-test_test.cc @@ -35,6 +35,9 @@ #include #include +using testing::internal::AlwaysFalse; +using testing::internal::AlwaysTrue; + #if GTEST_HAS_DEATH_TEST #if GTEST_OS_WINDOWS @@ -271,21 +274,21 @@ TEST(ExitStatusPredicateTest, KilledBySignal) { // be followed by operator<<, and that in either case the complete text // comprises only a single C++ statement. TEST_F(TestForDeathTest, SingleStatement) { - if (false) + if (AlwaysFalse()) // This would fail if executed; this is a compilation test only ASSERT_DEATH(return, ""); - if (true) + if (AlwaysTrue()) EXPECT_DEATH(_exit(1), ""); else // This empty "else" branch is meant to ensure that EXPECT_DEATH // doesn't expand into an "if" statement without an "else" ; - if (false) + if (AlwaysFalse()) ASSERT_DEATH(return, "") << "did not die"; - if (false) + if (AlwaysFalse()) ; else EXPECT_DEATH(_exit(1), "") << 1 << 2 << 3; @@ -1188,21 +1191,21 @@ TEST(ConditionalDeathMacrosTest, AssertDeatDoesNotReturnhIfUnsupported) { // // The syntax should work whether death tests are available or not. TEST(ConditionalDeathMacrosSyntaxDeathTest, SingleStatement) { - if (false) + if (AlwaysFalse()) // This would fail if executed; this is a compilation test only ASSERT_DEATH_IF_SUPPORTED(return, ""); - if (true) + if (AlwaysTrue()) EXPECT_DEATH_IF_SUPPORTED(_exit(1), ""); else // This empty "else" branch is meant to ensure that EXPECT_DEATH // doesn't expand into an "if" statement without an "else" ; // NOLINT - if (false) + if (AlwaysFalse()) ASSERT_DEATH_IF_SUPPORTED(return, "") << "did not die"; - if (false) + if (AlwaysFalse()) ; // NOLINT else EXPECT_DEATH_IF_SUPPORTED(_exit(1), "") << 1 << 2 << 3; diff --git a/test/gtest-port_test.cc b/test/gtest-port_test.cc index 97859515..df59f9e8 100644 --- a/test/gtest-port_test.cc +++ b/test/gtest-port_test.cc @@ -54,16 +54,16 @@ namespace testing { namespace internal { TEST(GtestCheckSyntaxTest, BehavesLikeASingleStatement) { - if (false) + if (AlwaysFalse()) GTEST_CHECK_(false) << "This should never be executed; " "It's a compilation test only."; - if (true) + if (AlwaysTrue()) GTEST_CHECK_(true); else ; // NOLINT - if (false) + if (AlwaysFalse()) ; // NOLINT else GTEST_CHECK_(true) << ""; diff --git a/test/gtest-typed-test_test.cc b/test/gtest-typed-test_test.cc index e97598fb..4b6e971c 100644 --- a/test/gtest-typed-test_test.cc +++ b/test/gtest-typed-test_test.cc @@ -29,8 +29,8 @@ // // Author: wan@google.com (Zhanyong Wan) -#include #include +#include #include "test/gtest-typed-test_test.h" #include @@ -57,7 +57,9 @@ class CommonTest : public Test { // This 'protected:' is optional. There's no harm in making all // members of this fixture class template public. protected: - typedef std::list List; + // We used to use std::list here, but switched to std::vector since + // MSVC's doesn't compile cleanly with /W4. + typedef std::vector Vector; typedef std::set IntSet; CommonTest() : value_(1) {} @@ -99,7 +101,7 @@ TYPED_TEST(CommonTest, ValuesAreCorrect) { // Typedefs in the fixture class template can be visited via the // "typename TestFixture::" prefix. - typename TestFixture::List empty; + typename TestFixture::Vector empty; EXPECT_EQ(0U, empty.size()); typename TestFixture::IntSet empty2; @@ -314,7 +316,7 @@ INSTANTIATE_TYPED_TEST_CASE_P(Double, TypedTestP2, Types); // Tests that the same type-parameterized test case can be // instantiated in different translation units linked together. // (ContainerTest is also instantiated in gtest-typed-test_test.cc.) -typedef Types, std::set > MyContainers; +typedef Types, std::set > MyContainers; INSTANTIATE_TYPED_TEST_CASE_P(My, ContainerTest, MyContainers); // Tests that a type-parameterized test case can be defined and diff --git a/test/gtest_repeat_test.cc b/test/gtest_repeat_test.cc index 8ec3700c..df6868b8 100644 --- a/test/gtest_repeat_test.cc +++ b/test/gtest_repeat_test.cc @@ -64,14 +64,14 @@ namespace { do {\ const int expected_val = (expected);\ const int actual_val = (actual);\ - if (expected_val != actual_val) {\ + if (::testing::internal::IsTrue(expected_val != actual_val)) {\ ::std::cout << "Value of: " #actual "\n"\ << " Actual: " << actual_val << "\n"\ << "Expected: " #expected "\n"\ << "Which is: " << expected_val << "\n";\ abort();\ }\ - } while(false) + } while(::testing::internal::AlwaysFalse()) // Used for verifying that global environment set-up and tear-down are diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index 03acfb0f..ba39ae6a 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -80,32 +80,33 @@ TEST(CommandLineFlagsTest, CanBeAccessedInCodeOnceGTestHIsIncluded) { namespace testing { namespace internal { -const char* FormatTimeInMillisAsSeconds(TimeInMillis ms); +bool ShouldUseColor(bool stdout_is_tty); +const char* FormatTimeInMillisAsSeconds(TimeInMillis ms); bool ParseInt32Flag(const char* str, const char* flag, Int32* value); -// Provides access to otherwise private parts of the EventListeners class +// Provides access to otherwise private parts of the TestEventListeners class // that are needed to test it. -class EventListenersAccessor { +class TestEventListenersAccessor { public: - static TestEventListener* GetRepeater(EventListeners* listeners) { + static TestEventListener* GetRepeater(TestEventListeners* listeners) { return listeners->repeater(); } - static void SetDefaultResultPrinter(EventListeners* listeners, + static void SetDefaultResultPrinter(TestEventListeners* listeners, TestEventListener* listener) { listeners->SetDefaultResultPrinter(listener); } - static void SetDefaultXmlGenerator(EventListeners* listeners, + static void SetDefaultXmlGenerator(TestEventListeners* listeners, TestEventListener* listener) { listeners->SetDefaultXmlGenerator(listener); } - static bool EventForwardingEnabled(const EventListeners& listeners) { + static bool EventForwardingEnabled(const TestEventListeners& listeners) { return listeners.EventForwardingEnabled(); } - static void SuppressEventForwarding(EventListeners* listeners) { + static void SuppressEventForwarding(TestEventListeners* listeners) { listeners->SuppressEventForwarding(); } }; @@ -113,26 +114,11 @@ class EventListenersAccessor { } // namespace internal } // namespace testing -using testing::internal::FormatTimeInMillisAsSeconds; -using testing::internal::ParseInt32Flag; -using testing::internal::EventListenersAccessor; - -namespace testing { - -GTEST_DECLARE_string_(output); -GTEST_DECLARE_string_(color); - -namespace internal { -bool ShouldUseColor(bool stdout_is_tty); -} // namespace internal -} // namespace testing - using testing::AssertionFailure; using testing::AssertionResult; using testing::AssertionSuccess; using testing::DoubleLE; using testing::EmptyTestEventListener; -using testing::EventListeners; using testing::FloatLE; using testing::GTEST_FLAG(also_run_disabled_tests); using testing::GTEST_FLAG(break_on_failure); @@ -155,16 +141,20 @@ using testing::Message; using testing::ScopedFakeTestPartResultReporter; using testing::StaticAssertTypeEq; using testing::Test; +using testing::TestEventListeners; using testing::TestCase; using testing::TestPartResult; using testing::TestPartResultArray; using testing::TestProperty; using testing::TestResult; using testing::UnitTest; +using testing::internal::AlwaysFalse; +using testing::internal::AlwaysTrue; using testing::internal::AppendUserMessage; using testing::internal::CodePointToUtf8; using testing::internal::EqFailure; using testing::internal::FloatingPoint; +using testing::internal::FormatTimeInMillisAsSeconds; using testing::internal::GTestFlagSaver; using testing::internal::GetCurrentOsStackTraceExceptTop; using testing::internal::GetNextRandomSeed; @@ -174,11 +164,13 @@ using testing::internal::GetTypeId; using testing::internal::GetUnitTestImpl; using testing::internal::Int32; using testing::internal::Int32FromEnvOrDie; +using testing::internal::ParseInt32Flag; using testing::internal::ShouldRunTestOnShard; using testing::internal::ShouldShard; using testing::internal::ShouldUseColor; using testing::internal::StreamableToString; using testing::internal::String; +using testing::internal::TestEventListenersAccessor; using testing::internal::TestResultAccessor; using testing::internal::ThreadLocal; using testing::internal::UInt32; @@ -3880,19 +3872,19 @@ TEST(HRESULTAssertionTest, Streaming) { // Tests that the assertion macros behave like single statements. TEST(AssertionSyntaxTest, BasicAssertionsBehavesLikeSingleStatement) { - if (false) + if (AlwaysFalse()) ASSERT_TRUE(false) << "This should never be executed; " "It's a compilation test only."; - if (true) + if (AlwaysTrue()) EXPECT_FALSE(false); else ; // NOLINT - if (false) + if (AlwaysFalse()) ASSERT_LT(1, 3); - if (false) + if (AlwaysFalse()) ; // NOLINT else EXPECT_GT(3, 2) << ""; @@ -3914,26 +3906,26 @@ TEST(ExpectThrowTest, DoesNotGenerateUnreachableCodeWarning) { } TEST(AssertionSyntaxTest, ExceptionAssertionsBehavesLikeSingleStatement) { - if (false) + if (AlwaysFalse()) EXPECT_THROW(ThrowNothing(), bool); - if (true) + if (AlwaysTrue()) EXPECT_THROW(ThrowAnInteger(), int); else ; // NOLINT - if (false) + if (AlwaysFalse()) EXPECT_NO_THROW(ThrowAnInteger()); - if (true) + if (AlwaysTrue()) EXPECT_NO_THROW(ThrowNothing()); else ; // NOLINT - if (false) + if (AlwaysFalse()) EXPECT_ANY_THROW(ThrowNothing()); - if (true) + if (AlwaysTrue()) EXPECT_ANY_THROW(ThrowAnInteger()); else ; // NOLINT @@ -3941,23 +3933,23 @@ TEST(AssertionSyntaxTest, ExceptionAssertionsBehavesLikeSingleStatement) { #endif // GTEST_HAS_EXCEPTIONS TEST(AssertionSyntaxTest, NoFatalFailureAssertionsBehavesLikeSingleStatement) { - if (false) + if (AlwaysFalse()) EXPECT_NO_FATAL_FAILURE(FAIL()) << "This should never be executed. " << "It's a compilation test only."; else ; // NOLINT - if (false) + if (AlwaysFalse()) ASSERT_NO_FATAL_FAILURE(FAIL()) << ""; else ; // NOLINT - if (true) + if (AlwaysTrue()) EXPECT_NO_FATAL_FAILURE(SUCCEED()); else ; // NOLINT - if (false) + if (AlwaysFalse()) ; // NOLINT else ASSERT_NO_FATAL_FAILURE(SUCCEED()); @@ -6272,17 +6264,17 @@ class TestListener : public EmptyTestEventListener { }; // Tests the constructor. -TEST(EventListenersTest, ConstructionWorks) { - EventListeners listeners; +TEST(TestEventListenersTest, ConstructionWorks) { + TestEventListeners listeners; - EXPECT_TRUE(EventListenersAccessor::GetRepeater(&listeners) != NULL); + EXPECT_TRUE(TestEventListenersAccessor::GetRepeater(&listeners) != NULL); EXPECT_TRUE(listeners.default_result_printer() == NULL); EXPECT_TRUE(listeners.default_xml_generator() == NULL); } -// Tests that the EventListeners destructor deletes all the listeners it +// Tests that the TestEventListeners destructor deletes all the listeners it // owns. -TEST(EventListenersTest, DestructionWorks) { +TEST(TestEventListenersTest, DestructionWorks) { bool default_result_printer_is_destroyed = false; bool default_xml_printer_is_destroyed = false; bool extra_listener_is_destroyed = false; @@ -6294,11 +6286,11 @@ TEST(EventListenersTest, DestructionWorks) { NULL, &extra_listener_is_destroyed); { - EventListeners listeners; - EventListenersAccessor::SetDefaultResultPrinter(&listeners, - default_result_printer); - EventListenersAccessor::SetDefaultXmlGenerator(&listeners, - default_xml_printer); + TestEventListeners listeners; + TestEventListenersAccessor::SetDefaultResultPrinter(&listeners, + default_result_printer); + TestEventListenersAccessor::SetDefaultXmlGenerator(&listeners, + default_xml_printer); listeners.Append(extra_listener); } EXPECT_TRUE(default_result_printer_is_destroyed); @@ -6306,16 +6298,16 @@ TEST(EventListenersTest, DestructionWorks) { EXPECT_TRUE(extra_listener_is_destroyed); } -// Tests that a listener Append'ed to an EventListeners list starts +// Tests that a listener Append'ed to a TestEventListeners list starts // receiving events. -TEST(EventListenersTest, Append) { +TEST(TestEventListenersTest, Append) { int on_start_counter = 0; bool is_destroyed = false; TestListener* listener = new TestListener(&on_start_counter, &is_destroyed); { - EventListeners listeners; + TestEventListeners listeners; listeners.Append(listener); - EventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart( + TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart( *UnitTest::GetInstance()); EXPECT_EQ(1, on_start_counter); } @@ -6364,12 +6356,12 @@ class SequenceTestingListener : public EmptyTestEventListener { TEST(EventListenerTest, AppendKeepsOrder) { Vector vec; - EventListeners listeners; + TestEventListeners listeners; listeners.Append(new SequenceTestingListener(&vec, "1st")); listeners.Append(new SequenceTestingListener(&vec, "2nd")); listeners.Append(new SequenceTestingListener(&vec, "3rd")); - EventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart( + TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart( *UnitTest::GetInstance()); ASSERT_EQ(3, vec.size()); EXPECT_STREQ("1st.OnTestProgramStart", vec.GetElement(0).c_str()); @@ -6377,7 +6369,7 @@ TEST(EventListenerTest, AppendKeepsOrder) { EXPECT_STREQ("3rd.OnTestProgramStart", vec.GetElement(2).c_str()); vec.Clear(); - EventListenersAccessor::GetRepeater(&listeners)->OnTestProgramEnd( + TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramEnd( *UnitTest::GetInstance()); ASSERT_EQ(3, vec.size()); EXPECT_STREQ("3rd.OnTestProgramEnd", vec.GetElement(0).c_str()); @@ -6385,7 +6377,7 @@ TEST(EventListenerTest, AppendKeepsOrder) { EXPECT_STREQ("1st.OnTestProgramEnd", vec.GetElement(2).c_str()); vec.Clear(); - EventListenersAccessor::GetRepeater(&listeners)->OnTestIterationStart( + TestEventListenersAccessor::GetRepeater(&listeners)->OnTestIterationStart( *UnitTest::GetInstance(), 0); ASSERT_EQ(3, vec.size()); EXPECT_STREQ("1st.OnTestIterationStart", vec.GetElement(0).c_str()); @@ -6393,7 +6385,7 @@ TEST(EventListenerTest, AppendKeepsOrder) { EXPECT_STREQ("3rd.OnTestIterationStart", vec.GetElement(2).c_str()); vec.Clear(); - EventListenersAccessor::GetRepeater(&listeners)->OnTestIterationEnd( + TestEventListenersAccessor::GetRepeater(&listeners)->OnTestIterationEnd( *UnitTest::GetInstance(), 0); ASSERT_EQ(3, vec.size()); EXPECT_STREQ("3rd.OnTestIterationEnd", vec.GetElement(0).c_str()); @@ -6401,9 +6393,9 @@ TEST(EventListenerTest, AppendKeepsOrder) { EXPECT_STREQ("1st.OnTestIterationEnd", vec.GetElement(2).c_str()); } -// Tests that a listener removed from an EventListeners list stops receiving +// Tests that a listener removed from a TestEventListeners list stops receiving // events and is not deleted when the list is destroyed. -TEST(EventListenersTest, Release) { +TEST(TestEventListenersTest, Release) { int on_start_counter = 0; bool is_destroyed = false; // Although Append passes the ownership of this object to the list, @@ -6411,10 +6403,10 @@ TEST(EventListenersTest, Release) { // test ends. TestListener* listener = new TestListener(&on_start_counter, &is_destroyed); { - EventListeners listeners; + TestEventListeners listeners; listeners.Append(listener); EXPECT_EQ(listener, listeners.Release(listener)); - EventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart( + TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart( *UnitTest::GetInstance()); EXPECT_TRUE(listeners.Release(listener) == NULL); } @@ -6428,12 +6420,12 @@ TEST(EventListenerTest, SuppressEventForwarding) { int on_start_counter = 0; TestListener* listener = new TestListener(&on_start_counter, NULL); - EventListeners listeners; + TestEventListeners listeners; listeners.Append(listener); - ASSERT_TRUE(EventListenersAccessor::EventForwardingEnabled(listeners)); - EventListenersAccessor::SuppressEventForwarding(&listeners); - ASSERT_FALSE(EventListenersAccessor::EventForwardingEnabled(listeners)); - EventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart( + ASSERT_TRUE(TestEventListenersAccessor::EventForwardingEnabled(listeners)); + TestEventListenersAccessor::SuppressEventForwarding(&listeners); + ASSERT_FALSE(TestEventListenersAccessor::EventForwardingEnabled(listeners)); + TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart( *UnitTest::GetInstance()); EXPECT_EQ(0, on_start_counter); } @@ -6442,7 +6434,7 @@ TEST(EventListenerTest, SuppressEventForwarding) { // death test subprocesses. TEST(EventListenerDeathTest, EventsNotForwardedInDeathTestSubprecesses) { EXPECT_DEATH_IF_SUPPORTED({ - GTEST_CHECK_(EventListenersAccessor::EventForwardingEnabled( + GTEST_CHECK_(TestEventListenersAccessor::EventForwardingEnabled( *GetUnitTestImpl()->listeners())) << "expected failure";}, "expected failure"); } @@ -6455,26 +6447,26 @@ TEST(EventListenerTest, default_result_printer) { bool is_destroyed = false; TestListener* listener = new TestListener(&on_start_counter, &is_destroyed); - EventListeners listeners; - EventListenersAccessor::SetDefaultResultPrinter(&listeners, listener); + TestEventListeners listeners; + TestEventListenersAccessor::SetDefaultResultPrinter(&listeners, listener); EXPECT_EQ(listener, listeners.default_result_printer()); - EventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart( + TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart( *UnitTest::GetInstance()); EXPECT_EQ(1, on_start_counter); // Replacing default_result_printer with something else should remove it // from the list and destroy it. - EventListenersAccessor::SetDefaultResultPrinter(&listeners, NULL); + TestEventListenersAccessor::SetDefaultResultPrinter(&listeners, NULL); EXPECT_TRUE(listeners.default_result_printer() == NULL); EXPECT_TRUE(is_destroyed); // After broadcasting an event the counter is still the same, indicating // the listener is not in the list anymore. - EventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart( + TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart( *UnitTest::GetInstance()); EXPECT_EQ(1, on_start_counter); } @@ -6489,15 +6481,15 @@ TEST(EventListenerTest, RemovingDefaultResultPrinterWorks) { // test ends. TestListener* listener = new TestListener(&on_start_counter, &is_destroyed); { - EventListeners listeners; - EventListenersAccessor::SetDefaultResultPrinter(&listeners, listener); + TestEventListeners listeners; + TestEventListenersAccessor::SetDefaultResultPrinter(&listeners, listener); EXPECT_EQ(listener, listeners.Release(listener)); EXPECT_TRUE(listeners.default_result_printer() == NULL); EXPECT_FALSE(is_destroyed); // Broadcasting events now should not affect default_result_printer. - EventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart( + TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart( *UnitTest::GetInstance()); EXPECT_EQ(0, on_start_counter); } @@ -6514,26 +6506,26 @@ TEST(EventListenerTest, default_xml_generator) { bool is_destroyed = false; TestListener* listener = new TestListener(&on_start_counter, &is_destroyed); - EventListeners listeners; - EventListenersAccessor::SetDefaultXmlGenerator(&listeners, listener); + TestEventListeners listeners; + TestEventListenersAccessor::SetDefaultXmlGenerator(&listeners, listener); EXPECT_EQ(listener, listeners.default_xml_generator()); - EventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart( + TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart( *UnitTest::GetInstance()); EXPECT_EQ(1, on_start_counter); // Replacing default_xml_generator with something else should remove it // from the list and destroy it. - EventListenersAccessor::SetDefaultXmlGenerator(&listeners, NULL); + TestEventListenersAccessor::SetDefaultXmlGenerator(&listeners, NULL); EXPECT_TRUE(listeners.default_xml_generator() == NULL); EXPECT_TRUE(is_destroyed); // After broadcasting an event the counter is still the same, indicating // the listener is not in the list anymore. - EventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart( + TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart( *UnitTest::GetInstance()); EXPECT_EQ(1, on_start_counter); } @@ -6548,15 +6540,15 @@ TEST(EventListenerTest, RemovingDefaultXmlGeneratorWorks) { // test ends. TestListener* listener = new TestListener(&on_start_counter, &is_destroyed); { - EventListeners listeners; - EventListenersAccessor::SetDefaultXmlGenerator(&listeners, listener); + TestEventListeners listeners; + TestEventListenersAccessor::SetDefaultXmlGenerator(&listeners, listener); EXPECT_EQ(listener, listeners.Release(listener)); EXPECT_TRUE(listeners.default_xml_generator() == NULL); EXPECT_FALSE(is_destroyed); // Broadcasting events now should not affect default_xml_generator. - EventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart( + TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart( *UnitTest::GetInstance()); EXPECT_EQ(0, on_start_counter); } diff --git a/test/gtest_xml_output_unittest.py b/test/gtest_xml_output_unittest.py index 3ee6846e..6d44929c 100755 --- a/test/gtest_xml_output_unittest.py +++ b/test/gtest_xml_output_unittest.py @@ -54,7 +54,7 @@ else: STACK_TRACE_TEMPLATE = "" EXPECTED_NON_EMPTY_XML = """ - + @@ -77,6 +77,20 @@ Expected: 2%(stack)s]]> + + + ]]>%(stack)s]]> + + + + + + + diff --git a/test/gtest_xml_output_unittest_.cc b/test/gtest_xml_output_unittest_.cc index c0da2151..fc07ef46 100644 --- a/test/gtest_xml_output_unittest_.cc +++ b/test/gtest_xml_output_unittest_.cc @@ -40,8 +40,8 @@ #include -using ::testing::EventListeners; using ::testing::InitGoogleTest; +using ::testing::TestEventListeners; using ::testing::UnitTest; class SuccessfulTest : public testing::Test { @@ -80,6 +80,17 @@ TEST(MixedResultTest, DISABLED_test) { FAIL() << "Unexpected failure: Disabled test should not be run"; } +TEST(XmlQuotingTest, OutputsCData) { + FAIL() << "XML output: " + ""; +} + +// Helps to test that invalid characters produced by test code do not make +// it into the XML file. +TEST(InvalidCharactersTest, InvalidCharactersInMessage) { + FAIL() << "Invalid characters in brackets [\x1\x2]"; +} + class PropertyRecordingTest : public testing::Test { }; @@ -127,7 +138,7 @@ int main(int argc, char** argv) { InitGoogleTest(&argc, argv); if (argc > 1 && strcmp(argv[1], "--shut_down_xml") == 0) { - EventListeners& listeners = UnitTest::GetInstance()->listeners(); + TestEventListeners& listeners = UnitTest::GetInstance()->listeners(); delete listeners.Release(listeners.default_xml_generator()); } return RUN_ALL_TESTS(); diff --git a/test/gtest_xml_test_utils.py b/test/gtest_xml_test_utils.py index 1811c408..c83c3b7e 100755 --- a/test/gtest_xml_test_utils.py +++ b/test/gtest_xml_test_utils.py @@ -77,19 +77,29 @@ class GTestXMLTestCase(gtest_test_utils.TestCase): expected_attributes = expected_node.attributes actual_attributes = actual_node .attributes - self.assertEquals(expected_attributes.length, actual_attributes.length) + self.assertEquals( + expected_attributes.length, actual_attributes.length, + "attribute numbers differ in element " + actual_node.tagName) for i in range(expected_attributes.length): expected_attr = expected_attributes.item(i) actual_attr = actual_attributes.get(expected_attr.name) - self.assert_(actual_attr is not None) - self.assertEquals(expected_attr.value, actual_attr.value) + self.assert_( + actual_attr is not None, + "expected attribute %s not found in element %s" % + (expected_attr.name, actual_node.tagName)) + self.assertEquals(expected_attr.value, actual_attr.value, + " values of attribute %s in element %s differ" % + (expected_attr.name, actual_node.tagName)) expected_children = self._GetChildren(expected_node) actual_children = self._GetChildren(actual_node) - self.assertEquals(len(expected_children), len(actual_children)) + self.assertEquals( + len(expected_children), len(actual_children), + "number of child elements differ in element " + actual_node.tagName) for child_id, child in expected_children.iteritems(): self.assert_(child_id in actual_children, - '<%s> is not in <%s>' % (child_id, actual_children)) + '<%s> is not in <%s> (in element %s)' % + (child_id, actual_children, actual_node.tagName)) self.AssertEquivalentNodes(child, actual_children[child_id]) identifying_attribute = { @@ -103,14 +113,13 @@ class GTestXMLTestCase(gtest_test_utils.TestCase): """ Fetches all of the child nodes of element, a DOM Element object. Returns them as the values of a dictionary keyed by the IDs of the - children. For , and elements, - the ID is the value of their "name" attribute; for - elements, it is the value of the "message" attribute; for CDATA - section node, it is "detail". An exception is raised if any - element other than the above four is encountered, if two child - elements with the same identifying attributes are encountered, or - if any other type of node is encountered, other than Text nodes - containing only whitespace. + children. For , and elements, the ID + is the value of their "name" attribute; for elements, it is + the value of the "message" attribute; CDATA sections and non-whitespace + text nodes are concatenated into a single CDATA section with ID + "detail". An exception is raised if any element other than the above + four is encountered, if two child elements with the same identifying + attributes are encountered, or if any other type of node is encountered. """ children = {} @@ -121,11 +130,14 @@ class GTestXMLTestCase(gtest_test_utils.TestCase): childID = child.getAttribute(self.identifying_attribute[child.tagName]) self.assert_(childID not in children) children[childID] = child - elif child.nodeType == Node.TEXT_NODE: - self.assert_(child.nodeValue.isspace()) - elif child.nodeType == Node.CDATA_SECTION_NODE: - self.assert_("detail" not in children) - children["detail"] = child + elif child.nodeType in [Node.TEXT_NODE, Node.CDATA_SECTION_NODE]: + if "detail" not in children: + if (child.nodeType == Node.CDATA_SECTION_NODE or + not child.nodeValue.isspace()): + children["detail"] = child.ownerDocument.createCDATASection( + child.nodeValue) + else: + children["detail"].nodeValue += child.nodeValue else: self.fail("Encountered unexpected node type %d" % child.nodeType) return children -- cgit v1.2.3 From bd851333e89517762c91a3fef67cf25a6f1bd37a Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Wed, 30 Sep 2009 23:46:28 +0000 Subject: Implements test shuffling (by Zhanyong Wan, based on Josh Kelley's original patch). Enables death tests on minGW (by Vlad Losev). --- test/gtest-death-test_test.cc | 8 +- test/gtest_shuffle_test.py | 331 ++++++++++++++++++++++++++++++++++++++++++ test/gtest_shuffle_test_.cc | 104 +++++++++++++ test/gtest_unittest.cc | 301 +++++++++++++++++++++++++++++++++++++- 4 files changed, 737 insertions(+), 7 deletions(-) create mode 100755 test/gtest_shuffle_test.py create mode 100644 test/gtest_shuffle_test_.cc (limited to 'test') diff --git a/test/gtest-death-test_test.cc b/test/gtest-death-test_test.cc index 7bf6a716..288c70a0 100644 --- a/test/gtest-death-test_test.cc +++ b/test/gtest-death-test_test.cc @@ -659,7 +659,11 @@ static void TestExitMacros() { EXPECT_EXIT(_exit(1), testing::ExitedWithCode(1), ""); ASSERT_EXIT(_exit(42), testing::ExitedWithCode(42), ""); -#if GTEST_OS_WINDOWS +#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MINGW + // MinGW (as of MinGW 5.1.6 and MSYS 1.0.11) does not tag crashed + // processes with non-zero exit code and does not honor calls to + // SetErrorMode(SEM_NOGPFAULTERRORBOX) that are supposed to suppress + // error pop-ups. EXPECT_EXIT({ testing::GTEST_FLAG(catch_exceptions) = false; *static_cast(NULL) = 1; @@ -671,7 +675,9 @@ static void TestExitMacros() { *static_cast(NULL) = 1; }, testing::ExitedWithCode(0), "") << "This failure is expected."; }, "This failure is expected."); +#endif // GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MINGW +#if GTEST_OS_WINDOWS // Of all signals effects on the process exit code, only those of SIGABRT // are documented on Windows. // See http://msdn.microsoft.com/en-us/library/dwwzkt4c(VS.71).aspx. diff --git a/test/gtest_shuffle_test.py b/test/gtest_shuffle_test.py new file mode 100755 index 00000000..a870a01b --- /dev/null +++ b/test/gtest_shuffle_test.py @@ -0,0 +1,331 @@ +#!/usr/bin/env python +# +# Copyright 2009 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. + +"""Verifies that test shuffling works.""" + +__author__ = 'wan@google.com (Zhanyong Wan)' + +import os +import gtest_test_utils + +# Command to run the gtest_shuffle_test_ program. +COMMAND = gtest_test_utils.GetTestExecutablePath('gtest_shuffle_test_') + +# The environment variables for test sharding. +TOTAL_SHARDS_ENV_VAR = 'GTEST_TOTAL_SHARDS' +SHARD_INDEX_ENV_VAR = 'GTEST_SHARD_INDEX' + +TEST_FILTER = 'A*.A:A*.B:C*' + +ALL_TESTS = [] +ACTIVE_TESTS = [] +FILTERED_TESTS = [] +SHARDED_TESTS = [] + +SHUFFLED_ALL_TESTS = [] +SHUFFLED_ACTIVE_TESTS = [] +SHUFFLED_FILTERED_TESTS = [] +SHUFFLED_SHARDED_TESTS = [] + + +def AlsoRunDisabledTestsFlag(): + return '--gtest_also_run_disabled_tests' + + +def FilterFlag(test_filter): + return '--gtest_filter=%s' % (test_filter,) + + +def RepeatFlag(n): + return '--gtest_repeat=%s' % (n,) + + +def ShuffleFlag(): + return '--gtest_shuffle' + + +def RandomSeedFlag(n): + return '--gtest_random_seed=%s' % (n,) + + +def RunAndReturnOutput(extra_env, args): + """Runs the test program and returns its output.""" + + try: + original_env = os.environ.copy() + os.environ.update(extra_env) + return gtest_test_utils.Subprocess([COMMAND] + args).output + finally: + for key in extra_env.iterkeys(): + if key in original_env: + os.environ[key] = original_env[key] + else: + del os.environ[key] + + +def GetTestsForAllIterations(extra_env, args): + """Runs the test program and returns a list of test lists. + + Args: + extra_env: a map from environment variables to their values + args: command line flags to pass to gtest_shuffle_test_ + + Returns: + A list where the i-th element is the list of tests run in the i-th + test iteration. + """ + + test_iterations = [] + for line in RunAndReturnOutput(extra_env, args).split('\n'): + if line.startswith('----'): + tests = [] + test_iterations.append(tests) + elif line.strip(): + tests.append(line.strip()) # 'TestCaseName.TestName' + + return test_iterations + + +def GetTestCases(tests): + """Returns a list of test cases in the given full test names. + + Args: + tests: a list of full test names + + Returns: + A list of test cases from 'tests', in their original order. + Consecutive duplicates are removed. + """ + + test_cases = [] + for test in tests: + test_case = test.split('.')[0] + if not test_case in test_cases: + test_cases.append(test_case) + + return test_cases + + +def CalculateTestLists(): + """Calculates the list of tests run under different flags.""" + + if not ALL_TESTS: + ALL_TESTS.extend( + GetTestsForAllIterations({}, [AlsoRunDisabledTestsFlag()])[0]) + + if not ACTIVE_TESTS: + ACTIVE_TESTS.extend(GetTestsForAllIterations({}, [])[0]) + + if not FILTERED_TESTS: + FILTERED_TESTS.extend( + GetTestsForAllIterations({}, [FilterFlag(TEST_FILTER)])[0]) + + if not SHARDED_TESTS: + SHARDED_TESTS.extend( + GetTestsForAllIterations({TOTAL_SHARDS_ENV_VAR: '3', + SHARD_INDEX_ENV_VAR: '1'}, + [])[0]) + + if not SHUFFLED_ALL_TESTS: + SHUFFLED_ALL_TESTS.extend(GetTestsForAllIterations( + {}, [AlsoRunDisabledTestsFlag(), ShuffleFlag(), RandomSeedFlag(1)])[0]) + + if not SHUFFLED_ACTIVE_TESTS: + SHUFFLED_ACTIVE_TESTS.extend(GetTestsForAllIterations( + {}, [ShuffleFlag(), RandomSeedFlag(1)])[0]) + + if not SHUFFLED_FILTERED_TESTS: + SHUFFLED_FILTERED_TESTS.extend(GetTestsForAllIterations( + {}, [ShuffleFlag(), RandomSeedFlag(1), FilterFlag(TEST_FILTER)])[0]) + + if not SHUFFLED_SHARDED_TESTS: + SHUFFLED_SHARDED_TESTS.extend( + GetTestsForAllIterations({TOTAL_SHARDS_ENV_VAR: '3', + SHARD_INDEX_ENV_VAR: '1'}, + [ShuffleFlag(), RandomSeedFlag(1)])[0]) + + +class GTestShuffleUnitTest(gtest_test_utils.TestCase): + """Tests test shuffling.""" + + def setUp(self): + CalculateTestLists() + + def testShufflePreservesNumberOfTests(self): + self.assertEqual(len(ALL_TESTS), len(SHUFFLED_ALL_TESTS)) + self.assertEqual(len(ACTIVE_TESTS), len(SHUFFLED_ACTIVE_TESTS)) + self.assertEqual(len(FILTERED_TESTS), len(SHUFFLED_FILTERED_TESTS)) + self.assertEqual(len(SHARDED_TESTS), len(SHUFFLED_SHARDED_TESTS)) + + def testShuffleChangesTestOrder(self): + self.assert_(SHUFFLED_ALL_TESTS != ALL_TESTS, SHUFFLED_ALL_TESTS) + self.assert_(SHUFFLED_ACTIVE_TESTS != ACTIVE_TESTS, SHUFFLED_ACTIVE_TESTS) + self.assert_(SHUFFLED_FILTERED_TESTS != FILTERED_TESTS, + SHUFFLED_FILTERED_TESTS) + self.assert_(SHUFFLED_SHARDED_TESTS != SHARDED_TESTS, + SHUFFLED_SHARDED_TESTS) + + def testShuffleChangesTestCaseOrder(self): + self.assert_(GetTestCases(SHUFFLED_ALL_TESTS) != GetTestCases(ALL_TESTS), + GetTestCases(SHUFFLED_ALL_TESTS)) + self.assert_( + GetTestCases(SHUFFLED_ACTIVE_TESTS) != GetTestCases(ACTIVE_TESTS), + GetTestCases(SHUFFLED_ACTIVE_TESTS)) + self.assert_( + GetTestCases(SHUFFLED_FILTERED_TESTS) != GetTestCases(FILTERED_TESTS), + GetTestCases(SHUFFLED_FILTERED_TESTS)) + self.assert_( + GetTestCases(SHUFFLED_SHARDED_TESTS) != GetTestCases(SHARDED_TESTS), + GetTestCases(SHUFFLED_SHARDED_TESTS)) + + def testShuffleDoesNotRepeatTest(self): + for test in SHUFFLED_ALL_TESTS: + self.assertEqual(1, SHUFFLED_ALL_TESTS.count(test), + '%s appears more than once' % (test,)) + for test in SHUFFLED_ACTIVE_TESTS: + self.assertEqual(1, SHUFFLED_ACTIVE_TESTS.count(test), + '%s appears more than once' % (test,)) + for test in SHUFFLED_FILTERED_TESTS: + self.assertEqual(1, SHUFFLED_FILTERED_TESTS.count(test), + '%s appears more than once' % (test,)) + for test in SHUFFLED_SHARDED_TESTS: + self.assertEqual(1, SHUFFLED_SHARDED_TESTS.count(test), + '%s appears more than once' % (test,)) + + def testShuffleDoesNotCreateNewTest(self): + for test in SHUFFLED_ALL_TESTS: + self.assert_(test in ALL_TESTS, '%s is an invalid test' % (test,)) + for test in SHUFFLED_ACTIVE_TESTS: + self.assert_(test in ACTIVE_TESTS, '%s is an invalid test' % (test,)) + for test in SHUFFLED_FILTERED_TESTS: + self.assert_(test in FILTERED_TESTS, '%s is an invalid test' % (test,)) + for test in SHUFFLED_SHARDED_TESTS: + self.assert_(test in SHARDED_TESTS, '%s is an invalid test' % (test,)) + + def testShuffleIncludesAllTests(self): + for test in ALL_TESTS: + self.assert_(test in SHUFFLED_ALL_TESTS, '%s is missing' % (test,)) + for test in ACTIVE_TESTS: + self.assert_(test in SHUFFLED_ACTIVE_TESTS, '%s is missing' % (test,)) + for test in FILTERED_TESTS: + self.assert_(test in SHUFFLED_FILTERED_TESTS, '%s is missing' % (test,)) + for test in SHARDED_TESTS: + self.assert_(test in SHUFFLED_SHARDED_TESTS, '%s is missing' % (test,)) + + def testShuffleLeavesDeathTestsAtFront(self): + non_death_test_found = False + for test in SHUFFLED_ACTIVE_TESTS: + if 'DeathTest.' in test: + self.assert_(not non_death_test_found, + '%s appears after a non-death test' % (test,)) + else: + non_death_test_found = True + + def _VerifyTestCasesDoNotInterleave(self, tests): + test_cases = [] + for test in tests: + [test_case, _] = test.split('.') + if test_cases and test_cases[-1] != test_case: + test_cases.append(test_case) + self.assertEqual(1, test_cases.count(test_case), + 'Test case %s is not grouped together in %s' % + (test_case, tests)) + + def testShuffleDoesNotInterleaveTestCases(self): + self._VerifyTestCasesDoNotInterleave(SHUFFLED_ALL_TESTS) + self._VerifyTestCasesDoNotInterleave(SHUFFLED_ACTIVE_TESTS) + self._VerifyTestCasesDoNotInterleave(SHUFFLED_FILTERED_TESTS) + self._VerifyTestCasesDoNotInterleave(SHUFFLED_SHARDED_TESTS) + + def testShuffleRestoresOrderAfterEachIteration(self): + # Get the test lists in all 3 iterations, using random seed 1, 2, + # and 3 respectively. Google Test picks a different seed in each + # iteration, and this test depends on the current implementation + # picking successive numbers. This dependency is not ideal, but + # makes the test much easier to write. + [tests_in_iteration1, tests_in_iteration2, tests_in_iteration3] = ( + GetTestsForAllIterations( + {}, [ShuffleFlag(), RandomSeedFlag(1), RepeatFlag(3)])) + + # Make sure running the tests with random seed 1 gets the same + # order as in iteration 1 above. + [tests_with_seed1] = GetTestsForAllIterations( + {}, [ShuffleFlag(), RandomSeedFlag(1)]) + self.assertEqual(tests_in_iteration1, tests_with_seed1) + + # Make sure running the tests with random seed 2 gets the same + # order as in iteration 2 above. Success means that Google Test + # correctly restores the test order before re-shuffling at the + # beginning of iteration 2. + [tests_with_seed2] = GetTestsForAllIterations( + {}, [ShuffleFlag(), RandomSeedFlag(2)]) + self.assertEqual(tests_in_iteration2, tests_with_seed2) + + # Make sure running the tests with random seed 3 gets the same + # order as in iteration 3 above. Success means that Google Test + # correctly restores the test order before re-shuffling at the + # beginning of iteration 3. + [tests_with_seed3] = GetTestsForAllIterations( + {}, [ShuffleFlag(), RandomSeedFlag(3)]) + self.assertEqual(tests_in_iteration3, tests_with_seed3) + + def testShuffleGeneratesNewOrderInEachIteration(self): + [tests_in_iteration1, tests_in_iteration2, tests_in_iteration3] = ( + GetTestsForAllIterations( + {}, [ShuffleFlag(), RandomSeedFlag(1), RepeatFlag(3)])) + + self.assert_(tests_in_iteration1 != tests_in_iteration2, + tests_in_iteration1) + self.assert_(tests_in_iteration1 != tests_in_iteration3, + tests_in_iteration1) + self.assert_(tests_in_iteration2 != tests_in_iteration3, + tests_in_iteration2) + + def testShuffleShardedTestsPreservesPartition(self): + # If we run M tests on N shards, the same M tests should be run in + # total, regardless of the random seeds used by the shards. + [tests1] = GetTestsForAllIterations({TOTAL_SHARDS_ENV_VAR: '3', + SHARD_INDEX_ENV_VAR: '0'}, + [ShuffleFlag(), RandomSeedFlag(1)]) + [tests2] = GetTestsForAllIterations({TOTAL_SHARDS_ENV_VAR: '3', + SHARD_INDEX_ENV_VAR: '1'}, + [ShuffleFlag(), RandomSeedFlag(20)]) + [tests3] = GetTestsForAllIterations({TOTAL_SHARDS_ENV_VAR: '3', + SHARD_INDEX_ENV_VAR: '2'}, + [ShuffleFlag(), RandomSeedFlag(25)]) + sorted_sharded_tests = tests1 + tests2 + tests3 + sorted_sharded_tests.sort() + sorted_active_tests = [] + sorted_active_tests.extend(ACTIVE_TESTS) + sorted_active_tests.sort() + self.assertEqual(sorted_active_tests, sorted_sharded_tests) + +if __name__ == '__main__': + gtest_test_utils.Main() diff --git a/test/gtest_shuffle_test_.cc b/test/gtest_shuffle_test_.cc new file mode 100644 index 00000000..53ecf777 --- /dev/null +++ b/test/gtest_shuffle_test_.cc @@ -0,0 +1,104 @@ +// Copyright 2009, 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) + +// Verifies that test shuffling works. + +#include + +namespace { + +using ::testing::EmptyTestEventListener; +using ::testing::InitGoogleTest; +using ::testing::Message; +using ::testing::Test; +using ::testing::TestEventListeners; +using ::testing::TestInfo; +using ::testing::UnitTest; +using ::testing::internal::String; +using ::testing::internal::scoped_ptr; + +// The test methods are empty, as the sole purpose of this program is +// to print the test names before/after shuffling. + +class A : public Test {}; +TEST_F(A, A) {} +TEST_F(A, B) {} + +TEST(ADeathTest, A) {} +TEST(ADeathTest, B) {} +TEST(ADeathTest, C) {} + +TEST(B, A) {} +TEST(B, B) {} +TEST(B, C) {} +TEST(B, DISABLED_D) {} +TEST(B, DISABLED_E) {} + +TEST(BDeathTest, A) {} +TEST(BDeathTest, B) {} + +TEST(C, A) {} +TEST(C, B) {} +TEST(C, C) {} +TEST(C, DISABLED_D) {} + +TEST(CDeathTest, A) {} + +TEST(DISABLED_D, A) {} +TEST(DISABLED_D, DISABLED_B) {} + +// This printer prints the full test names only, starting each test +// iteration with a "----" marker. +class TestNamePrinter : public EmptyTestEventListener { + public: + virtual void OnTestIterationStart(const UnitTest& /* unit_test */, + int /* iteration */) { + printf("----\n"); + } + + virtual void OnTestStart(const TestInfo& test_info) { + printf("%s.%s\n", test_info.test_case_name(), test_info.name()); + } +}; + +} // namespace + +int main(int argc, char **argv) { + InitGoogleTest(&argc, argv); + + // Replaces the default printer with TestNamePrinter, which prints + // the test name only. + TestEventListeners& listeners = UnitTest::GetInstance()->listeners(); + delete listeners.Release(listeners.default_result_printer()); + listeners.Append(new TestNamePrinter); + + return RUN_ALL_TESTS(); +} diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index ba39ae6a..5c69b463 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -180,6 +180,19 @@ using testing::internal::kMaxRandomSeed; using testing::internal::kTestTypeIdInGoogleTest; using testing::internal::scoped_ptr; +class TestingVector : public Vector { +}; + +::std::ostream& operator<<(::std::ostream& os, + const TestingVector& vector) { + os << "{ "; + for (int i = 0; i < vector.size(); i++) { + os << vector.GetElement(i) << " "; + } + os << "}"; + return os; +} + // This line tests that we can define tests in an unnamed namespace. namespace { @@ -677,6 +690,53 @@ TEST(VectorTest, GetElementOr) { EXPECT_EQ('x', a.GetElementOr(2, 'x')); } +TEST(VectorTest, Swap) { + Vector a; + a.PushBack(0); + a.PushBack(1); + a.PushBack(2); + + // Swaps an element with itself. + a.Swap(0, 0); + ASSERT_EQ(0, a.GetElement(0)); + ASSERT_EQ(1, a.GetElement(1)); + ASSERT_EQ(2, a.GetElement(2)); + + // Swaps two different elements where the indices go up. + a.Swap(0, 1); + ASSERT_EQ(1, a.GetElement(0)); + ASSERT_EQ(0, a.GetElement(1)); + ASSERT_EQ(2, a.GetElement(2)); + + // Swaps two different elements where the indices go down. + a.Swap(2, 0); + ASSERT_EQ(2, a.GetElement(0)); + ASSERT_EQ(0, a.GetElement(1)); + ASSERT_EQ(1, a.GetElement(2)); +} + +TEST(VectorTest, Clone) { + // Clones an empty Vector. + Vector a; + scoped_ptr > empty(a.Clone()); + EXPECT_EQ(0, empty->size()); + + // Clones a singleton. + a.PushBack(42); + scoped_ptr > singleton(a.Clone()); + ASSERT_EQ(1, singleton->size()); + EXPECT_EQ(42, singleton->GetElement(0)); + + // Clones a Vector with more elements. + a.PushBack(43); + a.PushBack(44); + scoped_ptr > big(a.Clone()); + ASSERT_EQ(3, big->size()); + EXPECT_EQ(42, big->GetElement(0)); + EXPECT_EQ(43, big->GetElement(1)); + EXPECT_EQ(44, big->GetElement(2)); +} + // Tests Vector::Erase(). TEST(VectorDeathTest, Erase) { Vector a; @@ -740,23 +800,252 @@ TEST(VectorDeathTest, Erase) { } // Tests the GetElement accessor. -TEST(ListDeathTest, GetElement) { +TEST(VectorDeathTest, GetElement) { Vector a; a.PushBack(0); a.PushBack(1); a.PushBack(2); + const Vector& b = a; + + EXPECT_EQ(0, b.GetElement(0)); + EXPECT_EQ(1, b.GetElement(1)); + EXPECT_EQ(2, b.GetElement(2)); + EXPECT_DEATH_IF_SUPPORTED( + b.GetElement(3), + "Invalid Vector index 3: must be in range \\[0, 2\\]\\."); + EXPECT_DEATH_IF_SUPPORTED( + b.GetElement(-1), + "Invalid Vector index -1: must be in range \\[0, 2\\]\\."); +} + +// Tests the GetMutableElement accessor. +TEST(VectorDeathTest, GetMutableElement) { + Vector a; + a.PushBack(0); + a.PushBack(1); + a.PushBack(2); + + EXPECT_EQ(0, a.GetMutableElement(0)); + EXPECT_EQ(1, a.GetMutableElement(1)); + EXPECT_EQ(2, a.GetMutableElement(2)); + + a.GetMutableElement(0) = 42; + EXPECT_EQ(42, a.GetMutableElement(0)); + EXPECT_EQ(1, a.GetMutableElement(1)); + EXPECT_EQ(2, a.GetMutableElement(2)); - EXPECT_EQ(0, a.GetElement(0)); - EXPECT_EQ(1, a.GetElement(1)); - EXPECT_EQ(2, a.GetElement(2)); EXPECT_DEATH_IF_SUPPORTED( - a.GetElement(3), + a.GetMutableElement(3), "Invalid Vector index 3: must be in range \\[0, 2\\]\\."); EXPECT_DEATH_IF_SUPPORTED( - a.GetElement(-1), + a.GetMutableElement(-1), "Invalid Vector index -1: must be in range \\[0, 2\\]\\."); } +TEST(VectorDeathTest, Swap) { + Vector a; + a.PushBack(0); + a.PushBack(1); + a.PushBack(2); + + EXPECT_DEATH_IF_SUPPORTED( + a.Swap(-1, 1), + "Invalid first swap element -1: must be in range \\[0, 2\\]"); + EXPECT_DEATH_IF_SUPPORTED( + a.Swap(3, 1), + "Invalid first swap element 3: must be in range \\[0, 2\\]"); + EXPECT_DEATH_IF_SUPPORTED( + a.Swap(1, -1), + "Invalid second swap element -1: must be in range \\[0, 2\\]"); + EXPECT_DEATH_IF_SUPPORTED( + a.Swap(1, 3), + "Invalid second swap element 3: must be in range \\[0, 2\\]"); +} + +TEST(VectorDeathTest, ShuffleRange) { + Vector a; + a.PushBack(0); + a.PushBack(1); + a.PushBack(2); + testing::internal::Random random(1); + + EXPECT_DEATH_IF_SUPPORTED( + a.ShuffleRange(&random, -1, 1), + "Invalid shuffle range start -1: must be in range \\[0, 3\\]"); + EXPECT_DEATH_IF_SUPPORTED( + a.ShuffleRange(&random, 4, 4), + "Invalid shuffle range start 4: must be in range \\[0, 3\\]"); + EXPECT_DEATH_IF_SUPPORTED( + a.ShuffleRange(&random, 3, 2), + "Invalid shuffle range finish 2: must be in range \\[3, 3\\]"); + EXPECT_DEATH_IF_SUPPORTED( + a.ShuffleRange(&random, 3, 4), + "Invalid shuffle range finish 4: must be in range \\[3, 3\\]"); +} + +class VectorShuffleTest : public Test { + protected: + static const int kVectorSize = 20; + + VectorShuffleTest() : random_(1) { + for (int i = 0; i < kVectorSize; i++) { + vector_.PushBack(i); + } + } + + static bool VectorIsCorrupt(const TestingVector& vector) { + if (kVectorSize != vector.size()) { + return true; + } + + bool found_in_vector[kVectorSize] = { false }; + for (int i = 0; i < vector.size(); i++) { + const int e = vector.GetElement(i); + if (e < 0 || e >= kVectorSize || found_in_vector[e]) { + return true; + } + found_in_vector[e] = true; + } + + // Vector size is correct, elements' range is correct, no + // duplicate elements. Therefore no corruption has occurred. + return false; + } + + static bool VectorIsNotCorrupt(const TestingVector& vector) { + return !VectorIsCorrupt(vector); + } + + static bool RangeIsShuffled(const TestingVector& vector, int begin, int end) { + for (int i = begin; i < end; i++) { + if (i != vector.GetElement(i)) { + return true; + } + } + return false; + } + + static bool RangeIsUnshuffled( + const TestingVector& vector, int begin, int end) { + return !RangeIsShuffled(vector, begin, end); + } + + static bool VectorIsShuffled(const TestingVector& vector) { + return RangeIsShuffled(vector, 0, vector.size()); + } + + static bool VectorIsUnshuffled(const TestingVector& vector) { + return !VectorIsShuffled(vector); + } + + testing::internal::Random random_; + TestingVector vector_; +}; // class VectorShuffleTest + +const int VectorShuffleTest::kVectorSize; + +TEST_F(VectorShuffleTest, HandlesEmptyRange) { + // Tests an empty range at the beginning... + vector_.ShuffleRange(&random_, 0, 0); + ASSERT_PRED1(VectorIsNotCorrupt, vector_); + ASSERT_PRED1(VectorIsUnshuffled, vector_); + + // ...in the middle... + vector_.ShuffleRange(&random_, kVectorSize/2, kVectorSize/2); + ASSERT_PRED1(VectorIsNotCorrupt, vector_); + ASSERT_PRED1(VectorIsUnshuffled, vector_); + + // ...at the end... + vector_.ShuffleRange(&random_, kVectorSize - 1, kVectorSize - 1); + ASSERT_PRED1(VectorIsNotCorrupt, vector_); + ASSERT_PRED1(VectorIsUnshuffled, vector_); + + // ...and past the end. + vector_.ShuffleRange(&random_, kVectorSize, kVectorSize); + ASSERT_PRED1(VectorIsNotCorrupt, vector_); + ASSERT_PRED1(VectorIsUnshuffled, vector_); +} + +TEST_F(VectorShuffleTest, HandlesRangeOfSizeOne) { + // Tests a size one range at the beginning... + vector_.ShuffleRange(&random_, 0, 1); + ASSERT_PRED1(VectorIsNotCorrupt, vector_); + ASSERT_PRED1(VectorIsUnshuffled, vector_); + + // ...in the middle... + vector_.ShuffleRange(&random_, kVectorSize/2, kVectorSize/2 + 1); + ASSERT_PRED1(VectorIsNotCorrupt, vector_); + ASSERT_PRED1(VectorIsUnshuffled, vector_); + + // ...and at the end. + vector_.ShuffleRange(&random_, kVectorSize - 1, kVectorSize); + ASSERT_PRED1(VectorIsNotCorrupt, vector_); + ASSERT_PRED1(VectorIsUnshuffled, vector_); +} + +// Because we use our own random number generator and a fixed seed, +// we can guarantee that the following "random" tests will succeed. + +TEST_F(VectorShuffleTest, ShufflesEntireVector) { + vector_.Shuffle(&random_); + ASSERT_PRED1(VectorIsNotCorrupt, vector_); + EXPECT_FALSE(VectorIsUnshuffled(vector_)) << vector_; + + // Tests the first and last elements in particular to ensure that + // there are no off-by-one problems in our shuffle algorithm. + EXPECT_NE(0, vector_.GetElement(0)); + EXPECT_NE(kVectorSize - 1, vector_.GetElement(kVectorSize - 1)); +} + +TEST_F(VectorShuffleTest, ShufflesStartOfVector) { + const int kRangeSize = kVectorSize/2; + + vector_.ShuffleRange(&random_, 0, kRangeSize); + + ASSERT_PRED1(VectorIsNotCorrupt, vector_); + EXPECT_PRED3(RangeIsShuffled, vector_, 0, kRangeSize); + EXPECT_PRED3(RangeIsUnshuffled, vector_, kRangeSize, kVectorSize); +} + +TEST_F(VectorShuffleTest, ShufflesEndOfVector) { + const int kRangeSize = kVectorSize / 2; + vector_.ShuffleRange(&random_, kRangeSize, kVectorSize); + + ASSERT_PRED1(VectorIsNotCorrupt, vector_); + EXPECT_PRED3(RangeIsUnshuffled, vector_, 0, kRangeSize); + EXPECT_PRED3(RangeIsShuffled, vector_, kRangeSize, kVectorSize); +} + +TEST_F(VectorShuffleTest, ShufflesMiddleOfVector) { + int kRangeSize = kVectorSize/3; + vector_.ShuffleRange(&random_, kRangeSize, 2*kRangeSize); + + ASSERT_PRED1(VectorIsNotCorrupt, vector_); + EXPECT_PRED3(RangeIsUnshuffled, vector_, 0, kRangeSize); + EXPECT_PRED3(RangeIsShuffled, vector_, kRangeSize, 2*kRangeSize); + EXPECT_PRED3(RangeIsUnshuffled, vector_, 2*kRangeSize, kVectorSize); +} + +TEST_F(VectorShuffleTest, ShufflesRepeatably) { + TestingVector vector2; + for (int i = 0; i < kVectorSize; i++) { + vector2.PushBack(i); + } + + random_.Reseed(1234); + vector_.Shuffle(&random_); + random_.Reseed(1234); + vector2.Shuffle(&random_); + + ASSERT_PRED1(VectorIsNotCorrupt, vector_); + ASSERT_PRED1(VectorIsNotCorrupt, vector2); + + for (int i = 0; i < kVectorSize; i++) { + EXPECT_EQ(vector_.GetElement(i), vector2.GetElement(i)) + << " where i is " << i; + } +} + // Tests the size of the AssertHelper class. TEST(AssertHelperTest, AssertHelperIsSmall) { -- cgit v1.2.3 From bad778caa39a88b7c11b159e20730aeec4fd711e Mon Sep 17 00:00:00 2001 From: vladlosev Date: Tue, 20 Oct 2009 21:03:10 +0000 Subject: Implements support for AssertionResult in Boolean assertions such as EXPECT_TRUE; Fixes Google Tests's tuple implementation to default-initialize its fields in the default constructor (by Zhanyong Wan); Populates gtest_stress_test.cc with actual tests. --- test/gtest-tuple_test.cc | 42 +++++++++++-- test/gtest_stress_test.cc | 148 +++++++++++++++++++++++++++++++++++++++++----- test/gtest_unittest.cc | 132 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 301 insertions(+), 21 deletions(-) (limited to 'test') diff --git a/test/gtest-tuple_test.cc b/test/gtest-tuple_test.cc index 3829118e..ca5232ee 100644 --- a/test/gtest-tuple_test.cc +++ b/test/gtest-tuple_test.cc @@ -135,12 +135,44 @@ TEST(ReferenceFieldTest, IsAliasOfReferencedVariable) { << "Changing a reference field should update the underlying variable."; } -// Tests tuple's default constructor. -TEST(TupleConstructorTest, DefaultConstructor) { - // We are just testing that the following compiles. +// Tests that tuple's default constructor default initializes each field. +// This test needs to compile without generating warnings. +TEST(TupleConstructorTest, DefaultConstructorDefaultInitializesEachField) { + // The TR1 report requires that tuple's default constructor default + // initializes each field, even if it's a primitive type. If the + // implementation forgets to do this, this test will catch it by + // generating warnings about using uninitialized variables (assuming + // a decent compiler). + tuple<> empty; - tuple one_field; - tuple three_fields; + + tuple a1, b1; + b1 = a1; + EXPECT_EQ(0, get<0>(b1)); + + tuple a2, b2; + b2 = a2; + EXPECT_EQ(0, get<0>(b2)); + EXPECT_EQ(0.0, get<1>(b2)); + + tuple a3, b3; + b3 = a3; + EXPECT_EQ(0.0, get<0>(b3)); + EXPECT_EQ('\0', get<1>(b3)); + EXPECT_EQ(NULL, get<2>(b3)); + + tuple a10, b10; + b10 = a10; + EXPECT_EQ(0, get<0>(b10)); + EXPECT_EQ(0, get<1>(b10)); + EXPECT_EQ(0, get<2>(b10)); + EXPECT_EQ(0, get<3>(b10)); + EXPECT_EQ(0, get<4>(b10)); + EXPECT_EQ(0, get<5>(b10)); + EXPECT_EQ(0, get<6>(b10)); + EXPECT_EQ(0, get<7>(b10)); + EXPECT_EQ(0, get<8>(b10)); + EXPECT_EQ(0, get<9>(b10)); } // Tests constructing a tuple from its fields. diff --git a/test/gtest_stress_test.cc b/test/gtest_stress_test.cc index 0034bb84..75d6268e 100644 --- a/test/gtest_stress_test.cc +++ b/test/gtest_stress_test.cc @@ -32,9 +32,10 @@ // Tests that SCOPED_TRACE() and various Google Test assertions can be // used in a large number of threads concurrently. -#include #include +#include + // We must define this macro in order to #include // gtest-internal-inl.h. This is how Google Test prevents a user from // accidentally depending on its internal implementation. @@ -42,6 +43,8 @@ #include "src/gtest-internal-inl.h" #undef GTEST_IMPLEMENTATION_ +#if GTEST_IS_THREADSAFE + namespace testing { namespace { @@ -49,6 +52,20 @@ using internal::String; using internal::TestPropertyKeyIs; using internal::Vector; +// In order to run tests in this file, for platforms where Google Test is +// thread safe, implement ThreadWithParam with the following interface: +// +// template class ThreadWithParam { +// public: +// // Creates the thread. The thread should execute thread_func(param) when +// // started by a call to Start(). +// ThreadWithParam(void (*thread_func)(T), T param); +// // Starts the thread. +// void Start(); +// // Waits for the thread to finish. +// void Join(); +// }; + // How many threads to create? const int kThreadCount = 50; @@ -77,7 +94,7 @@ void ExpectKeyAndValueWereRecordedForId(const Vector& properties, // Calls a large number of Google Test assertions, where exactly one of them // will fail. void ManyAsserts(int id) { - ::std::cout << "Thread #" << id << " running...\n"; + GTEST_LOG_(INFO) << "Thread #" << id << " running..."; SCOPED_TRACE(Message() << "Thread #" << id); @@ -104,41 +121,125 @@ void ManyAsserts(int id) { } } +void CheckTestFailureCount(int expected_failures) { + const TestInfo* const info = UnitTest::GetInstance()->current_test_info(); + const TestResult* const result = info->result(); + GTEST_CHECK_(expected_failures == result->total_part_count()) + << "Logged " << result->total_part_count() << " failures " + << " vs. " << expected_failures << " expected"; +} + // Tests using SCOPED_TRACE() and Google Test assertions in many threads // concurrently. TEST(StressTest, CanUseScopedTraceAndAssertionsInManyThreads) { - // TODO(wan): when Google Test is made thread-safe, run - // ManyAsserts() in many threads here. + ThreadWithParam* threads[kThreadCount] = {}; + for (int i = 0; i != kThreadCount; i++) { + // Creates a thread to run the ManyAsserts() function. + threads[i] = new ThreadWithParam(&ManyAsserts, i); + + // Starts the thread. + threads[i]->Start(); + } + + // At this point, we have many threads running. + + for (int i = 0; i != kThreadCount; i++) { + // We block until the thread is done. + threads[i]->Join(); + delete threads[i]; + threads[i] = NULL; + } + + // Ensures that kThreadCount*kThreadCount failures have been reported. + const TestInfo* const info = UnitTest::GetInstance()->current_test_info(); + const TestResult* const result = info->result(); + + Vector properties; + // We have no access to the TestResult's list of properties but we can + // copy them one by one. + for (int i = 0; i < result->test_property_count(); ++i) + properties.PushBack(result->GetTestProperty(i)); + + EXPECT_EQ(kThreadCount * 2 + 1, result->test_property_count()) + << "String and int values recorded on each thread, " + << "as well as one shared_key"; + for (int i = 0; i < kThreadCount; ++i) { + ExpectKeyAndValueWereRecordedForId(properties, i, "string"); + ExpectKeyAndValueWereRecordedForId(properties, i, "int"); + } + CheckTestFailureCount(kThreadCount*kThreadCount); +} + +void FailingThread(bool is_fatal) { + if (is_fatal) + FAIL() << "Fatal failure in some other thread. " + << "(This failure is expected.)"; + else + ADD_FAILURE() << "Non-fatal failure in some other thread. " + << "(This failure is expected.)"; +} + +void GenerateFatalFailureInAnotherThread(bool is_fatal) { + ThreadWithParam thread(&FailingThread, is_fatal); + thread.Start(); + thread.Join(); } TEST(NoFatalFailureTest, ExpectNoFatalFailureIgnoresFailuresInOtherThreads) { - // TODO(mheule@google.com): Test this works correctly when Google - // Test is made thread-safe. + EXPECT_NO_FATAL_FAILURE(GenerateFatalFailureInAnotherThread(true)); + // We should only have one failure (the one from + // GenerateFatalFailureInAnotherThread()), since the EXPECT_NO_FATAL_FAILURE + // should succeed. + CheckTestFailureCount(1); } +void AssertNoFatalFailureIgnoresFailuresInOtherThreads() { + ASSERT_NO_FATAL_FAILURE(GenerateFatalFailureInAnotherThread(true)); +} TEST(NoFatalFailureTest, AssertNoFatalFailureIgnoresFailuresInOtherThreads) { - // TODO(mheule@google.com): Test this works correctly when Google - // Test is made thread-safe. + // Using a subroutine, to make sure, that the test continues. + AssertNoFatalFailureIgnoresFailuresInOtherThreads(); + // We should only have one failure (the one from + // GenerateFatalFailureInAnotherThread()), since the EXPECT_NO_FATAL_FAILURE + // should succeed. + CheckTestFailureCount(1); } TEST(FatalFailureTest, ExpectFatalFailureIgnoresFailuresInOtherThreads) { - // TODO(mheule@google.com): Test this works correctly when Google - // Test is made thread-safe. + // This statement should fail, since the current thread doesn't generate a + // fatal failure, only another one does. + EXPECT_FATAL_FAILURE(GenerateFatalFailureInAnotherThread(true), "expected"); + CheckTestFailureCount(2); } TEST(FatalFailureOnAllThreadsTest, ExpectFatalFailureOnAllThreads) { - // TODO(wan@google.com): Test this works correctly when Google Test - // is made thread-safe. + // This statement should succeed, because failures in all threads are + // considered. + EXPECT_FATAL_FAILURE_ON_ALL_THREADS( + GenerateFatalFailureInAnotherThread(true), "expected"); + CheckTestFailureCount(0); + // We need to add a failure, because main() checks that there are failures. + // But when only this test is run, we shouldn't have any failures. + ADD_FAILURE() << "This is an expected non-fatal failure."; } TEST(NonFatalFailureTest, ExpectNonFatalFailureIgnoresFailuresInOtherThreads) { - // TODO(mheule@google.com): Test this works correctly when Google - // Test is made thread-safe. + // This statement should fail, since the current thread doesn't generate a + // fatal failure, only another one does. + EXPECT_NONFATAL_FAILURE(GenerateFatalFailureInAnotherThread(false), + "expected"); + CheckTestFailureCount(2); } TEST(NonFatalFailureOnAllThreadsTest, ExpectNonFatalFailureOnAllThreads) { - // TODO(wan@google.com): Test this works correctly when Google Test - // is made thread-safe. + // This statement should succeed, because failures in all threads are + // considered. + EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS( + GenerateFatalFailureInAnotherThread(false), "expected"); + CheckTestFailureCount(0); + // We need to add a failure, because main() checks that there are failures, + // But when only this test is run, we shouldn't have any failures. + ADD_FAILURE() << "This is an expected non-fatal failure."; } } // namespace @@ -147,5 +248,20 @@ TEST(NonFatalFailureOnAllThreadsTest, ExpectNonFatalFailureOnAllThreads) { int main(int argc, char **argv) { testing::InitGoogleTest(&argc, argv); + const int result = RUN_ALL_TESTS(); // Expected to fail. + GTEST_CHECK_(result == 1) << "RUN_ALL_TESTS() did not fail as expected"; + + printf("\nPASS\n"); + return 0; +} + +#else +TEST(StressTest, + DISABLED_ThreadSafetyTestsAreSkippedWhenGoogleTestIsNotThreadSafe) { +} + +int main(int argc, char **argv) { + testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } +#endif // GTEST_IS_THREADSAFE diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index 5c69b463..98f3a8b4 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -2418,6 +2418,25 @@ AssertionResult AssertIsEven(const char* expr, int n) { return AssertionFailure(msg); } +// A predicate function that returns AssertionResult for use in +// EXPECT/ASSERT_TRUE/FALSE. +AssertionResult ResultIsEven(int n) { + if (IsEven(n)) + return AssertionSuccess() << n << " is even"; + else + return AssertionFailure() << n << " is odd"; +} + +// A predicate function that returns AssertionResult but gives no +// explanation why it succeeds. Needed for testing that +// EXPECT/ASSERT_FALSE handles such functions correctly. +AssertionResult ResultIsEvenNoExplanation(int n) { + if (IsEven(n)) + return AssertionSuccess(); + else + return AssertionFailure() << n << " is odd"; +} + // A predicate-formatter functor that asserts the argument is an even // number. struct AssertIsEvenFunctor { @@ -3786,6 +3805,20 @@ TEST(AssertionTest, ASSERT_TRUE) { "2 < 1"); } +// Tests ASSERT_TRUE(predicate) for predicates returning AssertionResult. +TEST(AssertionTest, AssertTrueWithAssertionResult) { + ASSERT_TRUE(ResultIsEven(2)); + EXPECT_FATAL_FAILURE(ASSERT_TRUE(ResultIsEven(3)), + "Value of: ResultIsEven(3)\n" + " Actual: false (3 is odd)\n" + "Expected: true"); + ASSERT_TRUE(ResultIsEvenNoExplanation(2)); + EXPECT_FATAL_FAILURE(ASSERT_TRUE(ResultIsEvenNoExplanation(3)), + "Value of: ResultIsEvenNoExplanation(3)\n" + " Actual: false (3 is odd)\n" + "Expected: true"); +} + // Tests ASSERT_FALSE. TEST(AssertionTest, ASSERT_FALSE) { ASSERT_FALSE(2 < 1); // NOLINT @@ -3795,6 +3828,20 @@ TEST(AssertionTest, ASSERT_FALSE) { "Expected: false"); } +// Tests ASSERT_FALSE(predicate) for predicates returning AssertionResult. +TEST(AssertionTest, AssertFalseWithAssertionResult) { + ASSERT_FALSE(ResultIsEven(3)); + EXPECT_FATAL_FAILURE(ASSERT_FALSE(ResultIsEven(2)), + "Value of: ResultIsEven(2)\n" + " Actual: true (2 is even)\n" + "Expected: false"); + ASSERT_FALSE(ResultIsEvenNoExplanation(3)); + EXPECT_FATAL_FAILURE(ASSERT_FALSE(ResultIsEvenNoExplanation(2)), + "Value of: ResultIsEvenNoExplanation(2)\n" + " Actual: true\n" + "Expected: false"); +} + #ifdef __BORLANDC__ // Restores warnings after previous "#pragma option push" supressed them #pragma option pop @@ -4336,6 +4383,20 @@ TEST(ExpectTest, EXPECT_TRUE) { "2 > 3"); } +// Tests EXPECT_TRUE(predicate) for predicates returning AssertionResult. +TEST(ExpectTest, ExpectTrueWithAssertionResult) { + EXPECT_TRUE(ResultIsEven(2)); + EXPECT_NONFATAL_FAILURE(EXPECT_TRUE(ResultIsEven(3)), + "Value of: ResultIsEven(3)\n" + " Actual: false (3 is odd)\n" + "Expected: true"); + EXPECT_TRUE(ResultIsEvenNoExplanation(2)); + EXPECT_NONFATAL_FAILURE(EXPECT_TRUE(ResultIsEvenNoExplanation(3)), + "Value of: ResultIsEvenNoExplanation(3)\n" + " Actual: false (3 is odd)\n" + "Expected: true"); +} + // Tests EXPECT_FALSE. TEST(ExpectTest, EXPECT_FALSE) { EXPECT_FALSE(2 < 1); // NOLINT @@ -4347,6 +4408,20 @@ TEST(ExpectTest, EXPECT_FALSE) { "2 < 3"); } +// Tests EXPECT_FALSE(predicate) for predicates returning AssertionResult. +TEST(ExpectTest, ExpectFalseWithAssertionResult) { + EXPECT_FALSE(ResultIsEven(3)); + EXPECT_NONFATAL_FAILURE(EXPECT_FALSE(ResultIsEven(2)), + "Value of: ResultIsEven(2)\n" + " Actual: true (2 is even)\n" + "Expected: false"); + EXPECT_FALSE(ResultIsEvenNoExplanation(3)); + EXPECT_NONFATAL_FAILURE(EXPECT_FALSE(ResultIsEvenNoExplanation(2)), + "Value of: ResultIsEvenNoExplanation(2)\n" + " Actual: true\n" + "Expected: false"); +} + #ifdef __BORLANDC__ // Restores warnings after previous "#pragma option push" supressed them #pragma option pop @@ -4952,6 +5027,63 @@ TEST_F(TestLifeCycleTest, Test2) { } // namespace +// Tests that the copy constructor works when it is NOT optimized away by +// the compiler. +TEST(AssertionResultTest, CopyConstructorWorksWhenNotOptimied) { + // Checks that the copy constructor doesn't try to dereference NULL pointers + // in the source object. + AssertionResult r1 = AssertionSuccess(); + AssertionResult r2 = r1; + // The following line is added to prevent the compiler from optimizing + // away the constructor call. + r1 << "abc"; + + AssertionResult r3 = r1; + EXPECT_EQ(static_cast(r3), static_cast(r1)); + EXPECT_STREQ("abc", r1.message()); +} + +// Tests that AssertionSuccess and AssertionFailure construct +// AssertionResult objects as expected. +TEST(AssertionResultTest, ConstructionWorks) { + AssertionResult r1 = AssertionSuccess(); + EXPECT_TRUE(r1); + EXPECT_STREQ("", r1.message()); + + AssertionResult r2 = AssertionSuccess() << "abc"; + EXPECT_TRUE(r2); + EXPECT_STREQ("abc", r2.message()); + + AssertionResult r3 = AssertionFailure(); + EXPECT_FALSE(r3); + EXPECT_STREQ("", r3.message()); + + AssertionResult r4 = AssertionFailure() << "def"; + EXPECT_FALSE(r4); + EXPECT_STREQ("def", r4.message()); + + AssertionResult r5 = AssertionFailure(Message() << "ghi"); + EXPECT_FALSE(r5); + EXPECT_STREQ("ghi", r5.message()); +} + +// Tests that the negation fips the predicate result but keeps the message. +TEST(AssertionResultTest, NegationWorks) { + AssertionResult r1 = AssertionSuccess() << "abc"; + EXPECT_FALSE(!r1); + EXPECT_STREQ("abc", (!r1).message()); + + AssertionResult r2 = AssertionFailure() << "def"; + EXPECT_TRUE(!r2); + EXPECT_STREQ("def", (!r2).message()); +} + +TEST(AssertionResultTest, StreamingWorks) { + AssertionResult r = AssertionSuccess(); + r << "abc" << 'd' << 0 << true; + EXPECT_STREQ("abcd0true", r.message()); +} + // Tests streaming a user type whose definition and operator << are // both in the global namespace. class Base { -- cgit v1.2.3 From 6bfc4b2bd378940fa006bd32b9667ad4137d8f15 Mon Sep 17 00:00:00 2001 From: vladlosev Date: Thu, 22 Oct 2009 01:22:29 +0000 Subject: Prints help when encountering unrecognized Google Test flags. --- test/gtest_help_test.py | 46 +++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 41 insertions(+), 5 deletions(-) (limited to 'test') diff --git a/test/gtest_help_test.py b/test/gtest_help_test.py index 91081ad3..7883c1c5 100755 --- a/test/gtest_help_test.py +++ b/test/gtest_help_test.py @@ -50,6 +50,11 @@ PROGRAM_PATH = gtest_test_utils.GetTestExecutablePath('gtest_help_test_') FLAG_PREFIX = '--gtest_' CATCH_EXCEPTIONS_FLAG = FLAG_PREFIX + 'catch_exceptions' DEATH_TEST_STYLE_FLAG = FLAG_PREFIX + 'death_test_style' +UNKNOWN_FLAG = FLAG_PREFIX + 'unknown_flag_for_testing' +INCORRECT_FLAG_VARIANTS = [re.sub('^--', '-', DEATH_TEST_STYLE_FLAG), + re.sub('^--', '/', DEATH_TEST_STYLE_FLAG), + re.sub('_', '-', DEATH_TEST_STYLE_FLAG)] +INTERNAL_FLAG_FOR_TESTING = FLAG_PREFIX + 'internal_flag_for_testing' # The help message must match this regex. HELP_REGEX = re.compile( @@ -88,8 +93,14 @@ class GTestHelpTest(gtest_test_utils.TestCase): """Tests the --help flag and its equivalent forms.""" def TestHelpFlag(self, flag): - """Verifies that the right message is printed and the tests are - skipped when the given flag is specified.""" + """Verifies correct behavior when help flag is specified. + + The right message must be printed and the tests must + skipped when the given flag is specified. + + Args: + flag: A flag to pass to the binary or None. + """ exit_code, output = RunWithFlag(flag) self.assertEquals(0, exit_code) @@ -101,6 +112,20 @@ class GTestHelpTest(gtest_test_utils.TestCase): self.assert_(CATCH_EXCEPTIONS_FLAG not in output, output) self.assert_(DEATH_TEST_STYLE_FLAG in output, output) + def TestNonHelpFlag(self, flag): + """Verifies correct behavior when no help flag is specified. + + Verifies that when no help flag is specified, the tests are run + and the help message is not printed. + + Args: + flag: A flag to pass to the binary or None. + """ + + exit_code, output = RunWithFlag(flag) + self.assert_(exit_code != 0) + self.assert_(not HELP_REGEX.search(output), output) + def testPrintsHelpWithFullFlag(self): self.TestHelpFlag('--help') @@ -113,13 +138,24 @@ class GTestHelpTest(gtest_test_utils.TestCase): def testPrintsHelpWithWindowsStyleQuestionFlag(self): self.TestHelpFlag('/?') + def testPrintsHelpWithUnrecognizedGoogleTestFlag(self): + self.TestHelpFlag(UNKNOWN_FLAG) + + def testPrintsHelpWithIncorrectFlagStyle(self): + for incorrect_flag in INCORRECT_FLAG_VARIANTS: + self.TestHelpFlag(incorrect_flag) + def testRunsTestsWithoutHelpFlag(self): """Verifies that when no help flag is specified, the tests are run and the help message is not printed.""" - exit_code, output = RunWithFlag(None) - self.assert_(exit_code != 0) - self.assert_(not HELP_REGEX.search(output), output) + self.TestNonHelpFlag(None) + + def testRunsTestsWithGtestInternalFlag(self): + """Verifies that the tests are run and no help message is printed when + a flag starting with Google Test prefix and 'internal_' is supplied.""" + + self.TestNonHelpFlag(INTERNAL_FLAG_FOR_TESTING) if __name__ == '__main__': -- cgit v1.2.3 From bcf926ec656688d7eb03159faaddbf56bd4ec8e2 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Fri, 13 Nov 2009 02:54:23 +0000 Subject: Improves the scons scripts and run_tests.py (by Vlad Losev); uses typed tests in gtest-port_test.cc only when typed tests are available (by Zhanyong Wan); makes gtest-param-util-generated.h conform to the C++ standard (by Zhanyong Wan). --- test/gtest-port_test.cc | 4 ++++ test/run_tests_test.py | 6 +++--- 2 files changed, 7 insertions(+), 3 deletions(-) (limited to 'test') diff --git a/test/gtest-port_test.cc b/test/gtest-port_test.cc index df59f9e8..0fbe5c51 100644 --- a/test/gtest-port_test.cc +++ b/test/gtest-port_test.cc @@ -161,6 +161,8 @@ TEST(GtestCheckDeathTest, LivesSilentlyOnSuccess) { #if GTEST_USES_POSIX_RE +#if GTEST_HAS_TYPED_TEST + template class RETest : public ::testing::Test {}; @@ -223,6 +225,8 @@ TYPED_TEST(RETest, PartialMatchWorks) { EXPECT_FALSE(RE::PartialMatch(TypeParam("zza"), re)); } +#endif // GTEST_HAS_TYPED_TEST + #elif GTEST_USES_SIMPLE_RE TEST(IsInSetTest, NulCharIsNotInAnySet) { diff --git a/test/run_tests_test.py b/test/run_tests_test.py index 79524a68..a9f0b5db 100755 --- a/test/run_tests_test.py +++ b/test/run_tests_test.py @@ -42,9 +42,9 @@ sys.path.append(os.path.join(os.path.dirname(sys.argv[0]), os.pardir)) import run_tests -GTEST_DBG_DIR = 'scons/build/dbg/scons' -GTEST_OPT_DIR = 'scons/build/opt/scons' -GTEST_OTHER_DIR = 'scons/build/other/scons' +GTEST_DBG_DIR = 'scons/build/dbg/gtest/scons' +GTEST_OPT_DIR = 'scons/build/opt/gtest/scons' +GTEST_OTHER_DIR = 'scons/build/other/gtest/scons' def AddExeExtension(path): -- cgit v1.2.3 From 24ccb2c3e079dc0387e9a48cf6414ba982af8a45 Mon Sep 17 00:00:00 2001 From: vladlosev Date: Tue, 17 Nov 2009 22:41:27 +0000 Subject: Blocks test binaries from inheriting GTEST_OUTPUT variable when invoked from Python test scripts (fixes issue 223). --- test/gtest_test_utils.py | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'test') diff --git a/test/gtest_test_utils.py b/test/gtest_test_utils.py index 385662ad..591cdb82 100755 --- a/test/gtest_test_utils.py +++ b/test/gtest_test_utils.py @@ -51,6 +51,7 @@ except: _SUBPROCESS_MODULE_AVAILABLE = False # pylint: enable-msg=C6204 +GTEST_OUTPUT_VAR_NAME = 'GTEST_OUTPUT' IS_WINDOWS = os.name == 'nt' IS_CYGWIN = os.name == 'posix' and 'CYGWIN' in os.uname()[0] @@ -267,4 +268,11 @@ def Main(): # unittest.main(). Otherwise the latter will be confused by the # --gtest_* flags. _ParseAndStripGTestFlags(sys.argv) + # The tested binaries should not be writing XML output files unless the + # script explicitly instructs them to. + # TODO(vladl@google.com): Move this into Subprocess when we implement + # passing environment into it as a parameter. + if GTEST_OUTPUT_VAR_NAME in os.environ: + del os.environ[GTEST_OUTPUT_VAR_NAME] + _test_module.main() -- cgit v1.2.3 From bf26ca01f23e432f8b2355fd700707ba217a7605 Mon Sep 17 00:00:00 2001 From: vladlosev Date: Tue, 17 Nov 2009 22:43:15 +0000 Subject: Prevents Google Test from printing help message upon seeing the --gtest_stack_trace_depth flag. This was breaking gmock_output_test. --- test/gtest_unittest.cc | 138 ++++++++++++++++++++++++++++++++++--------------- 1 file changed, 95 insertions(+), 43 deletions(-) (limited to 'test') diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index 98f3a8b4..bf41de73 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -85,6 +85,9 @@ bool ShouldUseColor(bool stdout_is_tty); const char* FormatTimeInMillisAsSeconds(TimeInMillis ms); bool ParseInt32Flag(const char* str, const char* flag, Int32* value); +// Used for testing the flag parsing. +extern bool g_help_flag; + // Provides access to otherwise private parts of the TestEventListeners class // that are needed to test it. class TestEventListenersAccessor { @@ -148,6 +151,7 @@ using testing::TestPartResultArray; using testing::TestProperty; using testing::TestResult; using testing::UnitTest; +using testing::kMaxStackTraceDepth; using testing::internal::AlwaysFalse; using testing::internal::AlwaysTrue; using testing::internal::AppendUserMessage; @@ -2022,6 +2026,7 @@ class GTestFlagSaverTest : public Test { GTEST_FLAG(random_seed) = 0; GTEST_FLAG(repeat) = 1; GTEST_FLAG(shuffle) = false; + GTEST_FLAG(stack_trace_depth) = kMaxStackTraceDepth; GTEST_FLAG(throw_on_failure) = false; } @@ -2047,6 +2052,7 @@ class GTestFlagSaverTest : public Test { EXPECT_EQ(0, GTEST_FLAG(random_seed)); EXPECT_EQ(1, GTEST_FLAG(repeat)); EXPECT_FALSE(GTEST_FLAG(shuffle)); + EXPECT_EQ(kMaxStackTraceDepth, GTEST_FLAG(stack_trace_depth)); EXPECT_FALSE(GTEST_FLAG(throw_on_failure)); GTEST_FLAG(also_run_disabled_tests) = true; @@ -2061,6 +2067,7 @@ class GTestFlagSaverTest : public Test { GTEST_FLAG(random_seed) = 1; GTEST_FLAG(repeat) = 100; GTEST_FLAG(shuffle) = true; + GTEST_FLAG(stack_trace_depth) = 1; GTEST_FLAG(throw_on_failure) = true; } private: @@ -5347,6 +5354,7 @@ struct Flags { random_seed(0), repeat(1), shuffle(false), + stack_trace_depth(kMaxStackTraceDepth), throw_on_failure(false) {} // Factory methods. @@ -5439,6 +5447,14 @@ struct Flags { return flags; } + // Creates a Flags struct where the GTEST_FLAG(stack_trace_depth) flag has + // the given value. + static Flags StackTraceDepth(Int32 stack_trace_depth) { + Flags flags; + flags.stack_trace_depth = stack_trace_depth; + return flags; + } + // Creates a Flags struct where the gtest_throw_on_failure flag has // the given value. static Flags ThrowOnFailure(bool throw_on_failure) { @@ -5459,6 +5475,7 @@ struct Flags { Int32 random_seed; Int32 repeat; bool shuffle; + Int32 stack_trace_depth; bool throw_on_failure; }; @@ -5478,6 +5495,7 @@ class InitGoogleTestTest : public Test { GTEST_FLAG(random_seed) = 0; GTEST_FLAG(repeat) = 1; GTEST_FLAG(shuffle) = false; + GTEST_FLAG(stack_trace_depth) = kMaxStackTraceDepth; GTEST_FLAG(throw_on_failure) = false; } @@ -5507,6 +5525,7 @@ class InitGoogleTestTest : public Test { EXPECT_EQ(expected.repeat, GTEST_FLAG(repeat)); EXPECT_EQ(expected.shuffle, GTEST_FLAG(shuffle)); EXPECT_EQ(expected.throw_on_failure, GTEST_FLAG(throw_on_failure)); + EXPECT_EQ(expected.stack_trace_depth, GTEST_FLAG(stack_trace_depth)); } // Parses a command line (specified by argc1 and argv1), then @@ -5515,7 +5534,10 @@ class InitGoogleTestTest : public Test { template static void TestParsingFlags(int argc1, const CharType** argv1, int argc2, const CharType** argv2, - const Flags& expected) { + const Flags& expected, bool should_print_help) { + const bool saved_help_flag = ::testing::internal::g_help_flag; + ::testing::internal::g_help_flag = false; + // Parses the command line. internal::ParseGoogleTestFlagsOnly(&argc1, const_cast(argv1)); @@ -5525,13 +5547,23 @@ class InitGoogleTestTest : public Test { // Verifies that the recognized flags are removed from the command // line. AssertStringArrayEq(argc1 + 1, argv1, argc2 + 1, argv2); + + // ParseGoogleTestFlagsOnly should neither set g_help_flag nor print the + // help message for the flags it recognizes. + EXPECT_EQ(should_print_help, ::testing::internal::g_help_flag); + + // TODO(vladl@google.com): Verify that the help output is not printed + // for recognized flags when stdout capturing is implemeted. + + ::testing::internal::g_help_flag = saved_help_flag; } // This macro wraps TestParsingFlags s.t. the user doesn't need // to specify the array sizes. -#define GTEST_TEST_PARSING_FLAGS_(argv1, argv2, expected) \ +#define GTEST_TEST_PARSING_FLAGS_(argv1, argv2, expected, should_print_help) \ TestParsingFlags(sizeof(argv1)/sizeof(*argv1) - 1, argv1, \ - sizeof(argv2)/sizeof(*argv2) - 1, argv2, expected) + sizeof(argv2)/sizeof(*argv2) - 1, argv2, \ + expected, should_print_help) }; // Tests parsing an empty command line. @@ -5544,7 +5576,7 @@ TEST_F(InitGoogleTestTest, Empty) { NULL }; - GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags()); + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags(), false); } // Tests parsing a command line that has no flag. @@ -5559,7 +5591,7 @@ TEST_F(InitGoogleTestTest, NoFlag) { NULL }; - GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags()); + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags(), false); } // Tests parsing a bad --gtest_filter flag. @@ -5576,7 +5608,7 @@ TEST_F(InitGoogleTestTest, FilterBad) { NULL }; - GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Filter("")); + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Filter(""), true); } // Tests parsing an empty --gtest_filter flag. @@ -5592,7 +5624,7 @@ TEST_F(InitGoogleTestTest, FilterEmpty) { NULL }; - GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Filter("")); + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Filter(""), false); } // Tests parsing a non-empty --gtest_filter flag. @@ -5608,7 +5640,7 @@ TEST_F(InitGoogleTestTest, FilterNonEmpty) { NULL }; - GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Filter("abc")); + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Filter("abc"), false); } // Tests parsing --gtest_break_on_failure. @@ -5624,7 +5656,7 @@ TEST_F(InitGoogleTestTest, BreakOnFailureWithoutValue) { NULL }; - GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::BreakOnFailure(true)); + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::BreakOnFailure(true), false); } // Tests parsing --gtest_break_on_failure=0. @@ -5640,7 +5672,7 @@ TEST_F(InitGoogleTestTest, BreakOnFailureFalse_0) { NULL }; - GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::BreakOnFailure(false)); + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::BreakOnFailure(false), false); } // Tests parsing --gtest_break_on_failure=f. @@ -5656,7 +5688,7 @@ TEST_F(InitGoogleTestTest, BreakOnFailureFalse_f) { NULL }; - GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::BreakOnFailure(false)); + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::BreakOnFailure(false), false); } // Tests parsing --gtest_break_on_failure=F. @@ -5672,7 +5704,7 @@ TEST_F(InitGoogleTestTest, BreakOnFailureFalse_F) { NULL }; - GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::BreakOnFailure(false)); + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::BreakOnFailure(false), false); } // Tests parsing a --gtest_break_on_failure flag that has a "true" @@ -5689,7 +5721,7 @@ TEST_F(InitGoogleTestTest, BreakOnFailureTrue) { NULL }; - GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::BreakOnFailure(true)); + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::BreakOnFailure(true), false); } // Tests parsing --gtest_catch_exceptions. @@ -5705,7 +5737,7 @@ TEST_F(InitGoogleTestTest, CatchExceptions) { NULL }; - GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::CatchExceptions(true)); + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::CatchExceptions(true), false); } // Tests parsing --gtest_death_test_use_fork. @@ -5721,7 +5753,7 @@ TEST_F(InitGoogleTestTest, DeathTestUseFork) { NULL }; - GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::DeathTestUseFork(true)); + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::DeathTestUseFork(true), false); } // Tests having the same flag twice with different values. The @@ -5739,7 +5771,7 @@ TEST_F(InitGoogleTestTest, DuplicatedFlags) { NULL }; - GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Filter("b")); + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Filter("b"), false); } // Tests having an unrecognized flag on the command line. @@ -5761,7 +5793,7 @@ TEST_F(InitGoogleTestTest, UnrecognizedFlag) { Flags flags; flags.break_on_failure = true; flags.filter = "b"; - GTEST_TEST_PARSING_FLAGS_(argv, argv2, flags); + GTEST_TEST_PARSING_FLAGS_(argv, argv2, flags, false); } // Tests having a --gtest_list_tests flag @@ -5777,7 +5809,7 @@ TEST_F(InitGoogleTestTest, ListTestsFlag) { NULL }; - GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ListTests(true)); + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ListTests(true), false); } // Tests having a --gtest_list_tests flag with a "true" value @@ -5793,7 +5825,7 @@ TEST_F(InitGoogleTestTest, ListTestsTrue) { NULL }; - GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ListTests(true)); + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ListTests(true), false); } // Tests having a --gtest_list_tests flag with a "false" value @@ -5809,7 +5841,7 @@ TEST_F(InitGoogleTestTest, ListTestsFalse) { NULL }; - GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ListTests(false)); + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ListTests(false), false); } // Tests parsing --gtest_list_tests=f. @@ -5825,7 +5857,7 @@ TEST_F(InitGoogleTestTest, ListTestsFalse_f) { NULL }; - GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ListTests(false)); + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ListTests(false), false); } // Tests parsing --gtest_list_tests=F. @@ -5841,7 +5873,7 @@ TEST_F(InitGoogleTestTest, ListTestsFalse_F) { NULL }; - GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ListTests(false)); + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ListTests(false), false); } // Tests parsing --gtest_output (invalid). @@ -5858,7 +5890,7 @@ TEST_F(InitGoogleTestTest, OutputEmpty) { NULL }; - GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags()); + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags(), true); } // Tests parsing --gtest_output=xml @@ -5874,7 +5906,7 @@ TEST_F(InitGoogleTestTest, OutputXml) { NULL }; - GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Output("xml")); + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Output("xml"), false); } // Tests parsing --gtest_output=xml:file @@ -5890,7 +5922,7 @@ TEST_F(InitGoogleTestTest, OutputXmlFile) { NULL }; - GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Output("xml:file")); + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Output("xml:file"), false); } // Tests parsing --gtest_output=xml:directory/path/ @@ -5906,7 +5938,8 @@ TEST_F(InitGoogleTestTest, OutputXmlDirectory) { NULL }; - GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Output("xml:directory/path/")); + GTEST_TEST_PARSING_FLAGS_(argv, argv2, + Flags::Output("xml:directory/path/"), false); } // Tests having a --gtest_print_time flag @@ -5922,7 +5955,7 @@ TEST_F(InitGoogleTestTest, PrintTimeFlag) { NULL }; - GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::PrintTime(true)); + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::PrintTime(true), false); } // Tests having a --gtest_print_time flag with a "true" value @@ -5938,7 +5971,7 @@ TEST_F(InitGoogleTestTest, PrintTimeTrue) { NULL }; - GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::PrintTime(true)); + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::PrintTime(true), false); } // Tests having a --gtest_print_time flag with a "false" value @@ -5954,7 +5987,7 @@ TEST_F(InitGoogleTestTest, PrintTimeFalse) { NULL }; - GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::PrintTime(false)); + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::PrintTime(false), false); } // Tests parsing --gtest_print_time=f. @@ -5970,7 +6003,7 @@ TEST_F(InitGoogleTestTest, PrintTimeFalse_f) { NULL }; - GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::PrintTime(false)); + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::PrintTime(false), false); } // Tests parsing --gtest_print_time=F. @@ -5986,7 +6019,7 @@ TEST_F(InitGoogleTestTest, PrintTimeFalse_F) { NULL }; - GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::PrintTime(false)); + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::PrintTime(false), false); } // Tests parsing --gtest_random_seed=number @@ -6002,7 +6035,7 @@ TEST_F(InitGoogleTestTest, RandomSeed) { NULL }; - GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::RandomSeed(1000)); + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::RandomSeed(1000), false); } // Tests parsing --gtest_repeat=number @@ -6018,7 +6051,7 @@ TEST_F(InitGoogleTestTest, Repeat) { NULL }; - GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Repeat(1000)); + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Repeat(1000), false); } // Tests having a --gtest_also_run_disabled_tests flag @@ -6034,7 +6067,8 @@ TEST_F(InitGoogleTestTest, AlsoRunDisabledTestsFlag) { NULL }; - GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::AlsoRunDisabledTests(true)); + GTEST_TEST_PARSING_FLAGS_(argv, argv2, + Flags::AlsoRunDisabledTests(true), false); } // Tests having a --gtest_also_run_disabled_tests flag with a "true" value @@ -6050,7 +6084,8 @@ TEST_F(InitGoogleTestTest, AlsoRunDisabledTestsTrue) { NULL }; - GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::AlsoRunDisabledTests(true)); + GTEST_TEST_PARSING_FLAGS_(argv, argv2, + Flags::AlsoRunDisabledTests(true), false); } // Tests having a --gtest_also_run_disabled_tests flag with a "false" value @@ -6066,7 +6101,8 @@ TEST_F(InitGoogleTestTest, AlsoRunDisabledTestsFalse) { NULL }; - GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::AlsoRunDisabledTests(false)); + GTEST_TEST_PARSING_FLAGS_(argv, argv2, + Flags::AlsoRunDisabledTests(false), false); } // Tests parsing --gtest_shuffle. @@ -6082,7 +6118,7 @@ TEST_F(InitGoogleTestTest, ShuffleWithoutValue) { NULL }; - GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Shuffle(true)); + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Shuffle(true), false); } // Tests parsing --gtest_shuffle=0. @@ -6098,7 +6134,7 @@ TEST_F(InitGoogleTestTest, ShuffleFalse_0) { NULL }; - GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Shuffle(false)); + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Shuffle(false), false); } // Tests parsing a --gtest_shuffle flag that has a "true" @@ -6115,7 +6151,23 @@ TEST_F(InitGoogleTestTest, ShuffleTrue) { NULL }; - GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Shuffle(true)); + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Shuffle(true), false); +} + +// Tests parsing --gtest_stack_trace_depth=number. +TEST_F(InitGoogleTestTest, StackTraceDepth) { + const char* argv[] = { + "foo.exe", + "--gtest_stack_trace_depth=5", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::StackTraceDepth(5), false); } // Tests parsing --gtest_throw_on_failure. @@ -6131,7 +6183,7 @@ TEST_F(InitGoogleTestTest, ThrowOnFailureWithoutValue) { NULL }; - GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ThrowOnFailure(true)); + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ThrowOnFailure(true), false); } // Tests parsing --gtest_throw_on_failure=0. @@ -6147,7 +6199,7 @@ TEST_F(InitGoogleTestTest, ThrowOnFailureFalse_0) { NULL }; - GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ThrowOnFailure(false)); + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ThrowOnFailure(false), false); } // Tests parsing a --gtest_throw_on_failure flag that has a "true" @@ -6164,7 +6216,7 @@ TEST_F(InitGoogleTestTest, ThrowOnFailureTrue) { NULL }; - GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ThrowOnFailure(true)); + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ThrowOnFailure(true), false); } #if GTEST_OS_WINDOWS @@ -6190,7 +6242,7 @@ TEST_F(InitGoogleTestTest, WideStrings) { expected_flags.filter = "Foo*"; expected_flags.list_tests = true; - GTEST_TEST_PARSING_FLAGS_(argv, argv2, expected_flags); + GTEST_TEST_PARSING_FLAGS_(argv, argv2, expected_flags, false); } #endif // GTEST_OS_WINDOWS -- cgit v1.2.3 From b6fe6899bef6dd90572fc0e7f12912d9ad87a19e Mon Sep 17 00:00:00 2001 From: vladlosev Date: Tue, 17 Nov 2009 23:34:56 +0000 Subject: Implements the element_type typedef in testing::internal::scoped_ptr. This is needed to test gmock's IsNull/NotNull with it. --- test/gtest-port_test.cc | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'test') diff --git a/test/gtest-port_test.cc b/test/gtest-port_test.cc index 0fbe5c51..a2b0059e 100644 --- a/test/gtest-port_test.cc +++ b/test/gtest-port_test.cc @@ -53,6 +53,14 @@ namespace testing { namespace internal { +// Tests that the element_type typedef is available in scoped_ptr and refers +// to the parameter type. +TEST(ScopedPtrTest, DefinesElementType) { + StaticAssertTypeEq::element_type>(); +} + +// TODO(vladl@google.com): Implement THE REST of scoped_ptr tests. + TEST(GtestCheckSyntaxTest, BehavesLikeASingleStatement) { if (AlwaysFalse()) GTEST_CHECK_(false) << "This should never be executed; " -- cgit v1.2.3 From 2e075a7f60da95cd02a3935fda49d222a435d56a Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Tue, 24 Nov 2009 20:19:45 +0000 Subject: Refactors run_tests.py s.t. it can be shared by gmock (by Vlad Losev); Fixes a warning in gtest-tuple_test.cc on Cygwin (by Vlad Losev). --- test/gtest-tuple_test.cc | 2 +- test/gtest_test_utils.py | 7 +- test/run_tests_test.py | 614 ---------------------------------------- test/run_tests_util.py | 445 +++++++++++++++++++++++++++++ test/run_tests_util_test.py | 676 ++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 1127 insertions(+), 617 deletions(-) delete mode 100755 test/run_tests_test.py create mode 100755 test/run_tests_util.py create mode 100755 test/run_tests_util_test.py (limited to 'test') diff --git a/test/gtest-tuple_test.cc b/test/gtest-tuple_test.cc index ca5232ee..532f70b3 100644 --- a/test/gtest-tuple_test.cc +++ b/test/gtest-tuple_test.cc @@ -159,7 +159,7 @@ TEST(TupleConstructorTest, DefaultConstructorDefaultInitializesEachField) { b3 = a3; EXPECT_EQ(0.0, get<0>(b3)); EXPECT_EQ('\0', get<1>(b3)); - EXPECT_EQ(NULL, get<2>(b3)); + EXPECT_TRUE(get<2>(b3) == NULL); tuple a10, b10; b10 = a10; diff --git a/test/gtest_test_utils.py b/test/gtest_test_utils.py index 591cdb82..19b5b228 100755 --- a/test/gtest_test_utils.py +++ b/test/gtest_test_utils.py @@ -138,7 +138,7 @@ def GetTempDir(): return _temp_dir -def GetTestExecutablePath(executable_name): +def GetTestExecutablePath(executable_name, build_dir=None): """Returns the absolute path of the test binary given its name. The function will print a message and abort the program if the resulting file @@ -146,12 +146,15 @@ def GetTestExecutablePath(executable_name): Args: executable_name: name of the test binary that the test script runs. + build_dir: directory where to look for executables, by default + the result of GetBuildDir(). Returns: The absolute path of the test binary. """ - path = os.path.abspath(os.path.join(GetBuildDir(), executable_name)) + path = os.path.abspath(os.path.join(build_dir or GetBuildDir(), + executable_name)) if (IS_WINDOWS or IS_CYGWIN) and not path.endswith('.exe'): path += '.exe' diff --git a/test/run_tests_test.py b/test/run_tests_test.py deleted file mode 100755 index a9f0b5db..00000000 --- a/test/run_tests_test.py +++ /dev/null @@ -1,614 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2009 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. - -"""Tests for run_tests.py test runner script.""" - -__author__ = 'vladl@google.com (Vlad Losev)' - -import os -import re -import sets -import sys -import unittest - -sys.path.append(os.path.join(os.path.dirname(sys.argv[0]), os.pardir)) -import run_tests - - -GTEST_DBG_DIR = 'scons/build/dbg/gtest/scons' -GTEST_OPT_DIR = 'scons/build/opt/gtest/scons' -GTEST_OTHER_DIR = 'scons/build/other/gtest/scons' - - -def AddExeExtension(path): - """Appends .exe to the path on Windows or Cygwin.""" - - if run_tests.IS_WINDOWS or run_tests.IS_CYGWIN: - return path + '.exe' - else: - return path - - -class FakePath(object): - """A fake os.path module for testing.""" - - def __init__(self, current_dir=os.getcwd(), known_paths=None): - self.current_dir = current_dir - self.tree = {} - self.path_separator = os.sep - - # known_paths contains either absolute or relative paths. Relative paths - # are absolutized with self.current_dir. - if known_paths: - self._AddPaths(known_paths) - - def _AddPath(self, path): - ends_with_slash = path.endswith('/') - path = self.abspath(path) - if ends_with_slash: - path += self.path_separator - name_list = path.split(self.path_separator) - tree = self.tree - for name in name_list[:-1]: - if not name: - continue - if name in tree: - tree = tree[name] - else: - tree[name] = {} - tree = tree[name] - - name = name_list[-1] - if name: - if name in tree: - assert tree[name] == 1 - else: - tree[name] = 1 - - def _AddPaths(self, paths): - for path in paths: - self._AddPath(path) - - def PathElement(self, path): - """Returns an internal representation of directory tree entry for path.""" - tree = self.tree - name_list = self.abspath(path).split(self.path_separator) - for name in name_list: - if not name: - continue - tree = tree.get(name, None) - if tree is None: - break - - return tree - - def normpath(self, path): - return os.path.normpath(path) - - def abspath(self, path): - return self.normpath(os.path.join(self.current_dir, path)) - - def isfile(self, path): - return self.PathElement(self.abspath(path)) == 1 - - def isdir(self, path): - return type(self.PathElement(self.abspath(path))) == type(dict()) - - def basename(self, path): - return os.path.basename(path) - - def dirname(self, path): - return os.path.dirname(path) - - def join(self, *kargs): - return os.path.join(*kargs) - - -class FakeOs(object): - """A fake os module for testing.""" - P_WAIT = os.P_WAIT - - def __init__(self, fake_path_module): - self.path = fake_path_module - - # Some methods/attributes are delegated to the real os module. - self.environ = os.environ - - def listdir(self, path): - assert self.path.isdir(path) - return self.path.PathElement(path).iterkeys() - - def spawnv(self, wait, executable, *kargs): - assert wait == FakeOs.P_WAIT - return self.spawn_impl(executable, kargs) - - -class GetTestsToRunTest(unittest.TestCase): - """Exercises TestRunner.GetTestsToRun.""" - - def NormalizeGetTestsToRunResults(self, results): - """Normalizes path data returned from GetTestsToRun for comparison.""" - - def NormalizePythonTestPair(pair): - """Normalizes path data in the (directory, python_script) pair.""" - - return (os.path.normpath(pair[0]), os.path.normpath(pair[1])) - - def NormalizeBinaryTestPair(pair): - """Normalizes path data in the (directory, binary_executable) pair.""" - - directory, executable = map(os.path.normpath, pair) - - # On Windows and Cygwin, the test file names have the .exe extension, but - # they can be invoked either by name or by name+extension. Our test must - # accommodate both situations. - if run_tests.IS_WINDOWS or run_tests.IS_CYGWIN: - executable = re.sub(r'\.exe$', '', executable) - return (directory, executable) - - python_tests = sets.Set(map(NormalizePythonTestPair, results[0])) - binary_tests = sets.Set(map(NormalizeBinaryTestPair, results[1])) - return (python_tests, binary_tests) - - def AssertResultsEqual(self, results, expected): - """Asserts results returned by GetTestsToRun equal to expected results.""" - - self.assertEqual(self.NormalizeGetTestsToRunResults(results), - self.NormalizeGetTestsToRunResults(expected), - 'Incorrect set of tests returned:\n%s\nexpected:\n%s' % - (results, expected)) - - def setUp(self): - self.fake_os = FakeOs(FakePath( - current_dir=os.path.abspath(os.path.dirname(run_tests.__file__)), - known_paths=[AddExeExtension(GTEST_DBG_DIR + '/gtest_unittest'), - AddExeExtension(GTEST_OPT_DIR + '/gtest_unittest'), - 'test/gtest_color_test.py'])) - self.fake_configurations = ['dbg', 'opt'] - self.test_runner = run_tests.TestRunner(injected_os=self.fake_os, - injected_subprocess=None, - injected_script_dir='.') - - def testBinaryTestsOnly(self): - """Exercises GetTestsToRun with parameters designating binary tests only.""" - - # A default build. - self.AssertResultsEqual( - self.test_runner.GetTestsToRun( - ['gtest_unittest'], - '', - False, - available_configurations=self.fake_configurations), - ([], - [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest')])) - - # An explicitly specified directory. - self.AssertResultsEqual( - self.test_runner.GetTestsToRun( - [GTEST_DBG_DIR, 'gtest_unittest'], - '', - False, - available_configurations=self.fake_configurations), - ([], - [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest')])) - - # A particular configuration. - self.AssertResultsEqual( - self.test_runner.GetTestsToRun( - ['gtest_unittest'], - 'other', - False, - available_configurations=self.fake_configurations), - ([], - [(GTEST_OTHER_DIR, GTEST_OTHER_DIR + '/gtest_unittest')])) - - # All available configurations - self.AssertResultsEqual( - self.test_runner.GetTestsToRun( - ['gtest_unittest'], - 'all', - False, - available_configurations=self.fake_configurations), - ([], - [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest'), - (GTEST_OPT_DIR, GTEST_OPT_DIR + '/gtest_unittest')])) - - # All built configurations (unbuilt don't cause failure). - self.AssertResultsEqual( - self.test_runner.GetTestsToRun( - ['gtest_unittest'], - '', - True, - available_configurations=self.fake_configurations + ['unbuilt']), - ([], - [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest'), - (GTEST_OPT_DIR, GTEST_OPT_DIR + '/gtest_unittest')])) - - # A combination of an explicit directory and a configuration. - self.AssertResultsEqual( - self.test_runner.GetTestsToRun( - [GTEST_DBG_DIR, 'gtest_unittest'], - 'opt', - False, - available_configurations=self.fake_configurations), - ([], - [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest'), - (GTEST_OPT_DIR, GTEST_OPT_DIR + '/gtest_unittest')])) - - # Same test specified in an explicit directory and via a configuration. - self.AssertResultsEqual( - self.test_runner.GetTestsToRun( - [GTEST_DBG_DIR, 'gtest_unittest'], - 'dbg', - False, - available_configurations=self.fake_configurations), - ([], - [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest')])) - - # All built configurations + explicit directory + explicit configuration. - self.AssertResultsEqual( - self.test_runner.GetTestsToRun( - [GTEST_DBG_DIR, 'gtest_unittest'], - 'opt', - True, - available_configurations=self.fake_configurations), - ([], - [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest'), - (GTEST_OPT_DIR, GTEST_OPT_DIR + '/gtest_unittest')])) - - def testPythonTestsOnly(self): - """Exercises GetTestsToRun with parameters designating Python tests only.""" - - # A default build. - self.AssertResultsEqual( - self.test_runner.GetTestsToRun( - ['gtest_color_test.py'], - '', - False, - available_configurations=self.fake_configurations), - ([(GTEST_DBG_DIR, 'test/gtest_color_test.py')], - [])) - - # An explicitly specified directory. - self.AssertResultsEqual( - self.test_runner.GetTestsToRun( - [GTEST_DBG_DIR, 'test/gtest_color_test.py'], - '', - False, - available_configurations=self.fake_configurations), - ([(GTEST_DBG_DIR, 'test/gtest_color_test.py')], - [])) - - # A particular configuration. - self.AssertResultsEqual( - self.test_runner.GetTestsToRun( - ['gtest_color_test.py'], - 'other', - False, - available_configurations=self.fake_configurations), - ([(GTEST_OTHER_DIR, 'test/gtest_color_test.py')], - [])) - - # All available configurations - self.AssertResultsEqual( - self.test_runner.GetTestsToRun( - ['test/gtest_color_test.py'], - 'all', - False, - available_configurations=self.fake_configurations), - ([(GTEST_DBG_DIR, 'test/gtest_color_test.py'), - (GTEST_OPT_DIR, 'test/gtest_color_test.py')], - [])) - - # All built configurations (unbuilt don't cause failure). - self.AssertResultsEqual( - self.test_runner.GetTestsToRun( - ['gtest_color_test.py'], - '', - True, - available_configurations=self.fake_configurations + ['unbuilt']), - ([(GTEST_DBG_DIR, 'test/gtest_color_test.py'), - (GTEST_OPT_DIR, 'test/gtest_color_test.py')], - [])) - - # A combination of an explicit directory and a configuration. - self.AssertResultsEqual( - self.test_runner.GetTestsToRun( - [GTEST_DBG_DIR, 'gtest_color_test.py'], - 'opt', - False, - available_configurations=self.fake_configurations), - ([(GTEST_DBG_DIR, 'test/gtest_color_test.py'), - (GTEST_OPT_DIR, 'test/gtest_color_test.py')], - [])) - - # Same test specified in an explicit directory and via a configuration. - self.AssertResultsEqual( - self.test_runner.GetTestsToRun( - [GTEST_DBG_DIR, 'gtest_color_test.py'], - 'dbg', - False, - available_configurations=self.fake_configurations), - ([(GTEST_DBG_DIR, 'test/gtest_color_test.py')], - [])) - - # All built configurations + explicit directory + explicit configuration. - self.AssertResultsEqual( - self.test_runner.GetTestsToRun( - [GTEST_DBG_DIR, 'gtest_color_test.py'], - 'opt', - True, - available_configurations=self.fake_configurations), - ([(GTEST_DBG_DIR, 'test/gtest_color_test.py'), - (GTEST_OPT_DIR, 'test/gtest_color_test.py')], - [])) - - def testCombinationOfBinaryAndPythonTests(self): - """Exercises GetTestsToRun with mixed binary/Python tests.""" - - # Use only default configuration for this test. - - # Neither binary nor Python tests are specified so find all. - self.AssertResultsEqual( - self.test_runner.GetTestsToRun( - [], - '', - False, - available_configurations=self.fake_configurations), - ([(GTEST_DBG_DIR, 'test/gtest_color_test.py')], - [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest')])) - - # Specifying both binary and Python tests. - self.AssertResultsEqual( - self.test_runner.GetTestsToRun( - ['gtest_unittest', 'gtest_color_test.py'], - '', - False, - available_configurations=self.fake_configurations), - ([(GTEST_DBG_DIR, 'test/gtest_color_test.py')], - [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest')])) - - # Specifying binary tests suppresses Python tests. - self.AssertResultsEqual( - self.test_runner.GetTestsToRun( - ['gtest_unittest'], - '', - False, - available_configurations=self.fake_configurations), - ([], - [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest')])) - - # Specifying Python tests suppresses binary tests. - self.AssertResultsEqual( - self.test_runner.GetTestsToRun( - ['gtest_color_test.py'], - '', - False, - available_configurations=self.fake_configurations), - ([(GTEST_DBG_DIR, 'test/gtest_color_test.py')], - [])) - - def testIgnoresNonTestFiles(self): - """Verifies that GetTestsToRun ignores non-test files in the filesystem.""" - - self.fake_os = FakeOs(FakePath( - current_dir=os.path.abspath(os.path.dirname(run_tests.__file__)), - known_paths=[AddExeExtension(GTEST_DBG_DIR + '/gtest_nontest'), - 'test/'])) - self.test_runner = run_tests.TestRunner(injected_os=self.fake_os, - injected_subprocess=None, - injected_script_dir='.') - self.AssertResultsEqual( - self.test_runner.GetTestsToRun( - [], - '', - True, - available_configurations=self.fake_configurations), - ([], [])) - - def testWorksFromDifferentDir(self): - """Exercises GetTestsToRun from a directory different from run_test.py's.""" - - # Here we simulate an test script in directory /d/ called from the - # directory /a/b/c/. - self.fake_os = FakeOs(FakePath( - current_dir=os.path.abspath('/a/b/c'), - known_paths=[ - '/a/b/c/', - AddExeExtension('/d/' + GTEST_DBG_DIR + '/gtest_unittest'), - AddExeExtension('/d/' + GTEST_OPT_DIR + '/gtest_unittest'), - '/d/test/gtest_color_test.py'])) - self.fake_configurations = ['dbg', 'opt'] - self.test_runner = run_tests.TestRunner(injected_os=self.fake_os, - injected_subprocess=None, - injected_script_dir='/d/') - # A binary test. - self.AssertResultsEqual( - self.test_runner.GetTestsToRun( - ['gtest_unittest'], - '', - False, - available_configurations=self.fake_configurations), - ([], - [('/d/' + GTEST_DBG_DIR, '/d/' + GTEST_DBG_DIR + '/gtest_unittest')])) - - # A Python test. - self.AssertResultsEqual( - self.test_runner.GetTestsToRun( - ['gtest_color_test.py'], - '', - False, - available_configurations=self.fake_configurations), - ([('/d/' + GTEST_DBG_DIR, '/d/test/gtest_color_test.py')], [])) - - - def testNonTestBinary(self): - """Exercises GetTestsToRun with a non-test parameter.""" - - self.assert_( - not self.test_runner.GetTestsToRun( - ['gtest_unittest_not_really'], - '', - False, - available_configurations=self.fake_configurations)) - - def testNonExistingPythonTest(self): - """Exercises GetTestsToRun with a non-existent Python test parameter.""" - - self.assert_( - not self.test_runner.GetTestsToRun( - ['nonexistent_test.py'], - '', - False, - available_configurations=self.fake_configurations)) - - if run_tests.IS_WINDOWS or run_tests.IS_CYGWIN: - def testDoesNotPickNonExeFilesOnWindows(self): - """Verifies that GetTestsToRun does not find _test files on Windows.""" - - self.fake_os = FakeOs(FakePath( - current_dir=os.path.abspath(os.path.dirname(run_tests.__file__)), - known_paths=['/d/' + GTEST_DBG_DIR + '/gtest_test', 'test/'])) - self.test_runner = run_tests.TestRunner(injected_os=self.fake_os, - injected_subprocess=None, - injected_script_dir='.') - self.AssertResultsEqual( - self.test_runner.GetTestsToRun( - [], - '', - True, - available_configurations=self.fake_configurations), - ([], [])) - - -class RunTestsTest(unittest.TestCase): - """Exercises TestRunner.RunTests.""" - - def SpawnSuccess(self, unused_executable, unused_argv): - """Fakes test success by returning 0 as an exit code.""" - - self.num_spawn_calls += 1 - return 0 - - def SpawnFailure(self, unused_executable, unused_argv): - """Fakes test success by returning 1 as an exit code.""" - - self.num_spawn_calls += 1 - return 1 - - def setUp(self): - self.fake_os = FakeOs(FakePath( - current_dir=os.path.abspath(os.path.dirname(run_tests.__file__)), - known_paths=[ - AddExeExtension(GTEST_DBG_DIR + '/gtest_unittest'), - AddExeExtension(GTEST_OPT_DIR + '/gtest_unittest'), - 'test/gtest_color_test.py'])) - self.fake_configurations = ['dbg', 'opt'] - self.test_runner = run_tests.TestRunner(injected_os=self.fake_os, - injected_subprocess=None) - self.num_spawn_calls = 0 # A number of calls to spawn. - - def testRunPythonTestSuccess(self): - """Exercises RunTests to handle a Python test success.""" - - self.fake_os.spawn_impl = self.SpawnSuccess - self.assertEqual( - self.test_runner.RunTests( - [(GTEST_DBG_DIR, 'test/gtest_color_test.py')], - []), - 0) - self.assertEqual(self.num_spawn_calls, 1) - - def testRunBinaryTestSuccess(self): - """Exercises RunTests to handle a binary test success.""" - - self.fake_os.spawn_impl = self.SpawnSuccess - self.assertEqual( - self.test_runner.RunTests( - [], - [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest')]), - 0) - self.assertEqual(self.num_spawn_calls, 1) - - def testRunPythonTestFauilure(self): - """Exercises RunTests to handle a Python test failure.""" - - self.fake_os.spawn_impl = self.SpawnFailure - self.assertEqual( - self.test_runner.RunTests( - [(GTEST_DBG_DIR, 'test/gtest_color_test.py')], - []), - 1) - self.assertEqual(self.num_spawn_calls, 1) - - def testRunBinaryTestFailure(self): - """Exercises RunTests to handle a binary test failure.""" - - self.fake_os.spawn_impl = self.SpawnFailure - self.assertEqual( - self.test_runner.RunTests( - [], - [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest')]), - 1) - self.assertEqual(self.num_spawn_calls, 1) - - def testCombinedTestSuccess(self): - """Exercises RunTests to handle a success of both Python and binary test.""" - - self.fake_os.spawn_impl = self.SpawnSuccess - self.assertEqual( - self.test_runner.RunTests( - [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest')], - [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest')]), - 0) - self.assertEqual(self.num_spawn_calls, 2) - - def testCombinedTestSuccessAndFailure(self): - """Exercises RunTests to handle a success of both Python and binary test.""" - - def SpawnImpl(executable, argv): - self.num_spawn_calls += 1 - # Simulates failure of a Python test and success of a binary test. - if '.py' in executable or '.py' in argv[0]: - return 1 - else: - return 0 - - self.fake_os.spawn_impl = SpawnImpl - self.assertEqual( - self.test_runner.RunTests( - [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest')], - [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest')]), - 0) - self.assertEqual(self.num_spawn_calls, 2) - - -if __name__ == '__main__': - unittest.main() diff --git a/test/run_tests_util.py b/test/run_tests_util.py new file mode 100755 index 00000000..f1bb3e04 --- /dev/null +++ b/test/run_tests_util.py @@ -0,0 +1,445 @@ +# Copyright 2008 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. + +"""Provides facilities for running SCons-built Google Test/Mock tests.""" + + +import optparse +import os +import re +import sets +import sys + +try: + # subrocess module is a preferable way to invoke subprocesses but it may + # not be available on MacOS X 10.4. + # Suppresses the 'Import not at the top of the file' lint complaint. + # pylint: disable-msg=C6204 + import subprocess +except ImportError: + subprocess = None + +HELP_MSG = """Runs the specified tests for %(proj)s. + +SYNOPSIS + run_tests.py [OPTION]... [BUILD_DIR]... [TEST]... + +DESCRIPTION + Runs the specified tests (either binary or Python), and prints a + summary of the results. BUILD_DIRS will be used to search for the + binaries. If no TESTs are specified, all binary tests found in + BUILD_DIRs and all Python tests found in the directory test/ (in the + %(proj)s root) are run. + + TEST is a name of either a binary or a Python test. A binary test is + an executable file named *_test or *_unittest (with the .exe + extension on Windows) A Python test is a script named *_test.py or + *_unittest.py. + +OPTIONS + -h, --help + Print this help message. + -c CONFIGURATIONS + Specify build directories via build configurations. + CONFIGURATIONS is either a comma-separated list of build + configurations or 'all'. Each configuration is equivalent to + adding 'scons/build//%(proj)s/scons' to BUILD_DIRs. + Specifying -c=all is equivalent to providing all directories + listed in KNOWN BUILD DIRECTORIES section below. + -a + Equivalent to -c=all + -b + Equivalent to -c=all with the exception that the script will not + fail if some of the KNOWN BUILD DIRECTORIES do not exists; the + script will simply not run the tests there. 'b' stands for + 'built directories'. + +RETURN VALUE + Returns 0 if all tests are successful; otherwise returns 1. + +EXAMPLES + run_tests.py + Runs all tests for the default build configuration. + run_tests.py -a + Runs all tests with binaries in KNOWN BUILD DIRECTORIES. + run_tests.py -b + Runs all tests in KNOWN BUILD DIRECTORIES that have been + built. + run_tests.py foo/ + Runs all tests in the foo/ directory and all Python tests in + the directory test. The Python tests are instructed to look + for binaries in foo/. + run_tests.py bar_test.exe test/baz_test.exe foo/ bar/ + Runs foo/bar_test.exe, bar/bar_test.exe, foo/baz_test.exe, and + bar/baz_test.exe. + run_tests.py foo bar test/foo_test.py + Runs test/foo_test.py twice instructing it to look for its + test binaries in the directories foo and bar, + correspondingly. + +KNOWN BUILD DIRECTORIES + run_tests.py knows about directories where the SCons build script + deposits its products. These are the directories where run_tests.py + will be looking for its binaries. Currently, %(proj)s's SConstruct file + defines them as follows (the default build directory is the first one + listed in each group): + On Windows: + <%(proj)s root>/scons/build/win-dbg8/%(proj)s/scons/ + <%(proj)s root>/scons/build/win-opt8/%(proj)s/scons/ + <%(proj)s root>/scons/build/win-dbg/%(proj)s/scons/ + <%(proj)s root>/scons/build/win-opt/%(proj)s/scons/ + On Mac: + <%(proj)s root>/scons/build/mac-dbg/%(proj)s/scons/ + <%(proj)s root>/scons/build/mac-opt/%(proj)s/scons/ + On other platforms: + <%(proj)s root>/scons/build/dbg/%(proj)s/scons/ + <%(proj)s root>/scons/build/opt/%(proj)s/scons/""" + +IS_WINDOWS = os.name == 'nt' +IS_MAC = os.name == 'posix' and os.uname()[0] == 'Darwin' +IS_CYGWIN = os.name == 'posix' and 'CYGWIN' in os.uname()[0] + +# Definition of CONFIGS must match that of the build directory names in the +# SConstruct script. The first list item is the default build configuration. +if IS_WINDOWS: + CONFIGS = ('win-dbg8', 'win-opt8', 'win-dbg', 'win-opt') +elif IS_MAC: + CONFIGS = ('mac-dbg', 'mac-opt') +else: + CONFIGS = ('dbg', 'opt') + +if IS_WINDOWS or IS_CYGWIN: + PYTHON_TEST_REGEX = re.compile(r'_(unit)?test\.py$', re.IGNORECASE) + BINARY_TEST_REGEX = re.compile(r'_(unit)?test(\.exe)?$', re.IGNORECASE) + BINARY_TEST_SEARCH_REGEX = re.compile(r'_(unit)?test\.exe$', re.IGNORECASE) +else: + PYTHON_TEST_REGEX = re.compile(r'_(unit)?test\.py$') + BINARY_TEST_REGEX = re.compile(r'_(unit)?test$') + BINARY_TEST_SEARCH_REGEX = BINARY_TEST_REGEX + + +def _GetGtestBuildDir(injected_os, script_dir, config): + """Calculates path to the Google Test SCons build directory.""" + + return injected_os.path.normpath(injected_os.path.join(script_dir, + 'scons/build', + config, + 'gtest/scons')) + + +# All paths in this script are either absolute or relative to the current +# working directory, unless otherwise specified. +class TestRunner(object): + """Provides facilities for running Python and binary tests for Google Test.""" + + def __init__(self, + script_dir, + build_dir_var_name='GTEST_BUILD_DIR', + injected_os=os, + injected_subprocess=subprocess, + injected_build_dir_finder=_GetGtestBuildDir): + """Initializes a TestRunner instance. + + Args: + script_dir: File path to the calling script. + build_dir_var_name: Name of the env variable used to pass the + the build directory path to the invoked + tests. + injected_os: standard os module or a mock/stub for + testing. + injected_subprocess: standard subprocess module or a mock/stub + for testing + injected_build_dir_finder: function that determines the path to + the build directory. + """ + + self.os = injected_os + self.subprocess = injected_subprocess + self.build_dir_finder = injected_build_dir_finder + self.build_dir_var_name = build_dir_var_name + self.script_dir = script_dir + + def _GetBuildDirForConfig(self, config): + """Returns the build directory for a given configuration.""" + + return self.build_dir_finder(self.os, self.script_dir, config) + + def _Run(self, args): + """Runs the executable with given args (args[0] is the executable name). + + Args: + args: Command line arguments for the process. + + Returns: + Process's exit code if it exits normally, or -signal if the process is + killed by a signal. + """ + + if self.subprocess: + return self.subprocess.Popen(args).wait() + else: + return self.os.spawnv(self.os.P_WAIT, args[0], args) + + def _RunBinaryTest(self, test): + """Runs the binary test given its path. + + Args: + test: Path to the test binary. + + Returns: + Process's exit code if it exits normally, or -signal if the process is + killed by a signal. + """ + + return self._Run([test]) + + def _RunPythonTest(self, test, build_dir): + """Runs the Python test script with the specified build directory. + + Args: + test: Path to the test's Python script. + build_dir: Path to the directory where the test binary is to be found. + + Returns: + Process's exit code if it exits normally, or -signal if the process is + killed by a signal. + """ + + old_build_dir = self.os.environ.get(self.build_dir_var_name) + + try: + self.os.environ[self.build_dir_var_name] = build_dir + + # If this script is run on a Windows machine that has no association + # between the .py extension and a python interpreter, simply passing + # the script name into subprocess.Popen/os.spawn will not work. + print 'Running %s . . .' % (test,) + return self._Run([sys.executable, test]) + + finally: + if old_build_dir is None: + del self.os.environ[self.build_dir_var_name] + else: + self.os.environ[self.build_dir_var_name] = old_build_dir + + def _FindFilesByRegex(self, directory, regex): + """Returns files in a directory whose names match a regular expression. + + Args: + directory: Path to the directory to search for files. + regex: Regular expression to filter file names. + + Returns: + The list of the paths to the files in the directory. + """ + + return [self.os.path.join(directory, file_name) + for file_name in self.os.listdir(directory) + if re.search(regex, file_name)] + + # TODO(vladl@google.com): Implement parsing of scons/SConscript to run all + # tests defined there when no tests are specified. + # TODO(vladl@google.com): Update the docstring after the code is changed to + # try to test all builds defined in scons/SConscript. + def GetTestsToRun(self, + args, + named_configurations, + built_configurations, + available_configurations=CONFIGS): + """Determines what tests should be run. + + Args: + args: The list of non-option arguments from the command line. + named_configurations: The list of configurations specified via -c or -a. + built_configurations: True if -b has been specified. + available_configurations: a list of configurations available on the + current platform, injectable for testing. + + Returns: + A tuple with 2 elements: the list of Python tests to run and the list of + binary tests to run. + """ + + if named_configurations == 'all': + named_configurations = ','.join(available_configurations) + + normalized_args = [self.os.path.normpath(arg) for arg in args] + + # A final list of build directories which will be searched for the test + # binaries. First, add directories specified directly on the command + # line. + build_dirs = filter(self.os.path.isdir, normalized_args) + + # Adds build directories specified via their build configurations using + # the -c or -a options. + if named_configurations: + build_dirs += [self._GetBuildDirForConfig(config) + for config in named_configurations.split(',')] + + # Adds KNOWN BUILD DIRECTORIES if -b is specified. + if built_configurations: + build_dirs += [self._GetBuildDirForConfig(config) + for config in available_configurations + if self.os.path.isdir(self._GetBuildDirForConfig(config))] + + # If no directories were specified either via -a, -b, -c, or directly, use + # the default configuration. + elif not build_dirs: + build_dirs = [self._GetBuildDirForConfig(available_configurations[0])] + + # Makes sure there are no duplications. + build_dirs = sets.Set(build_dirs) + + errors_found = False + listed_python_tests = [] # All Python tests listed on the command line. + listed_binary_tests = [] # All binary tests listed on the command line. + + test_dir = self.os.path.normpath(self.os.path.join(self.script_dir, 'test')) + + # Sifts through non-directory arguments fishing for any Python or binary + # tests and detecting errors. + for argument in sets.Set(normalized_args) - build_dirs: + if re.search(PYTHON_TEST_REGEX, argument): + python_path = self.os.path.join(test_dir, + self.os.path.basename(argument)) + if self.os.path.isfile(python_path): + listed_python_tests.append(python_path) + else: + sys.stderr.write('Unable to find Python test %s' % argument) + errors_found = True + elif re.search(BINARY_TEST_REGEX, argument): + # This script also accepts binary test names prefixed with test/ for + # the convenience of typing them (can use path completions in the + # shell). Strips test/ prefix from the binary test names. + listed_binary_tests.append(self.os.path.basename(argument)) + else: + sys.stderr.write('%s is neither test nor build directory' % argument) + errors_found = True + + if errors_found: + return None + + user_has_listed_tests = listed_python_tests or listed_binary_tests + + if user_has_listed_tests: + selected_python_tests = listed_python_tests + else: + selected_python_tests = self._FindFilesByRegex(test_dir, + PYTHON_TEST_REGEX) + + # TODO(vladl@google.com): skip unbuilt Python tests when -b is specified. + python_test_pairs = [] + for directory in build_dirs: + for test in selected_python_tests: + python_test_pairs.append((directory, test)) + + binary_test_pairs = [] + for directory in build_dirs: + if user_has_listed_tests: + binary_test_pairs.extend( + [(directory, self.os.path.join(directory, test)) + for test in listed_binary_tests]) + else: + tests = self._FindFilesByRegex(directory, BINARY_TEST_SEARCH_REGEX) + binary_test_pairs.extend([(directory, test) for test in tests]) + + return (python_test_pairs, binary_test_pairs) + + def RunTests(self, python_tests, binary_tests): + """Runs Python and binary tests and reports results to the standard output. + + Args: + python_tests: List of Python tests to run in the form of tuples + (build directory, Python test script). + binary_tests: List of binary tests to run in the form of tuples + (build directory, binary file). + + Returns: + The exit code the program should pass into sys.exit(). + """ + + if python_tests or binary_tests: + results = [] + for directory, test in python_tests: + results.append((directory, + test, + self._RunPythonTest(test, directory) == 0)) + for directory, test in binary_tests: + results.append((directory, + self.os.path.basename(test), + self._RunBinaryTest(test) == 0)) + + failed = [(directory, test) + for (directory, test, success) in results + if not success] + print + print '%d tests run.' % len(results) + if failed: + print 'The following %d tests failed:' % len(failed) + for (directory, test) in failed: + print '%s in %s' % (test, directory) + return 1 + else: + print 'All tests passed!' + else: # No tests defined + print 'Nothing to test - no tests specified!' + + return 0 + + +def ParseArgs(project_name, argv=None, help_callback=None): + """Parses the options run_tests.py uses.""" + + # Suppresses lint warning on unused arguments. These arguments are + # required by optparse, even though they are unused. + # pylint: disable-msg=W0613 + def PrintHelp(option, opt, value, parser): + print HELP_MSG % {'proj': project_name} + sys.exit(1) + + parser = optparse.OptionParser() + parser.add_option('-c', + action='store', + dest='configurations', + default=None) + parser.add_option('-a', + action='store_const', + dest='configurations', + default=None, + const='all') + parser.add_option('-b', + action='store_const', + dest='built_configurations', + default=False, + const=True) + # Replaces the built-in help with ours. + parser.remove_option('-h') + parser.add_option('-h', '--help', + action='callback', + callback=help_callback or PrintHelp) + return parser.parse_args(argv) diff --git a/test/run_tests_util_test.py b/test/run_tests_util_test.py new file mode 100755 index 00000000..9c55726f --- /dev/null +++ b/test/run_tests_util_test.py @@ -0,0 +1,676 @@ +#!/usr/bin/env python +# +# Copyright 2009 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. + +"""Tests for run_tests_util.py test runner script.""" + +__author__ = 'vladl@google.com (Vlad Losev)' + +import os +import re +import sets +import unittest + +import run_tests_util + + +GTEST_DBG_DIR = 'scons/build/dbg/gtest/scons' +GTEST_OPT_DIR = 'scons/build/opt/gtest/scons' +GTEST_OTHER_DIR = 'scons/build/other/gtest/scons' + + +def AddExeExtension(path): + """Appends .exe to the path on Windows or Cygwin.""" + + if run_tests_util.IS_WINDOWS or run_tests_util.IS_CYGWIN: + return path + '.exe' + else: + return path + + +class FakePath(object): + """A fake os.path module for testing.""" + + def __init__(self, current_dir=os.getcwd(), known_paths=None): + self.current_dir = current_dir + self.tree = {} + self.path_separator = os.sep + + # known_paths contains either absolute or relative paths. Relative paths + # are absolutized with self.current_dir. + if known_paths: + self._AddPaths(known_paths) + + def _AddPath(self, path): + ends_with_slash = path.endswith('/') + path = self.abspath(path) + if ends_with_slash: + path += self.path_separator + name_list = path.split(self.path_separator) + tree = self.tree + for name in name_list[:-1]: + if not name: + continue + if name in tree: + tree = tree[name] + else: + tree[name] = {} + tree = tree[name] + + name = name_list[-1] + if name: + if name in tree: + assert tree[name] == 1 + else: + tree[name] = 1 + + def _AddPaths(self, paths): + for path in paths: + self._AddPath(path) + + def PathElement(self, path): + """Returns an internal representation of directory tree entry for path.""" + tree = self.tree + name_list = self.abspath(path).split(self.path_separator) + for name in name_list: + if not name: + continue + tree = tree.get(name, None) + if tree is None: + break + + return tree + + # Silences pylint warning about using standard names. + # pylint: disable-msg=C6409 + def normpath(self, path): + return os.path.normpath(path) + + def abspath(self, path): + return self.normpath(os.path.join(self.current_dir, path)) + + def isfile(self, path): + return self.PathElement(self.abspath(path)) == 1 + + def isdir(self, path): + return type(self.PathElement(self.abspath(path))) == type(dict()) + + def basename(self, path): + return os.path.basename(path) + + def dirname(self, path): + return os.path.dirname(path) + + def join(self, *kargs): + return os.path.join(*kargs) + + +class FakeOs(object): + """A fake os module for testing.""" + P_WAIT = os.P_WAIT + + def __init__(self, fake_path_module): + self.path = fake_path_module + + # Some methods/attributes are delegated to the real os module. + self.environ = os.environ + + # pylint: disable-msg=C6409 + def listdir(self, path): + assert self.path.isdir(path) + return self.path.PathElement(path).iterkeys() + + def spawnv(self, wait, executable, *kargs): + assert wait == FakeOs.P_WAIT + return self.spawn_impl(executable, kargs) + + +class GetTestsToRunTest(unittest.TestCase): + """Exercises TestRunner.GetTestsToRun.""" + + def NormalizeGetTestsToRunResults(self, results): + """Normalizes path data returned from GetTestsToRun for comparison.""" + + def NormalizePythonTestPair(pair): + """Normalizes path data in the (directory, python_script) pair.""" + + return (os.path.normpath(pair[0]), os.path.normpath(pair[1])) + + def NormalizeBinaryTestPair(pair): + """Normalizes path data in the (directory, binary_executable) pair.""" + + directory, executable = map(os.path.normpath, pair) + + # On Windows and Cygwin, the test file names have the .exe extension, but + # they can be invoked either by name or by name+extension. Our test must + # accommodate both situations. + if run_tests_util.IS_WINDOWS or run_tests_util.IS_CYGWIN: + executable = re.sub(r'\.exe$', '', executable) + return (directory, executable) + + python_tests = sets.Set(map(NormalizePythonTestPair, results[0])) + binary_tests = sets.Set(map(NormalizeBinaryTestPair, results[1])) + return (python_tests, binary_tests) + + def AssertResultsEqual(self, results, expected): + """Asserts results returned by GetTestsToRun equal to expected results.""" + + self.assertEqual(self.NormalizeGetTestsToRunResults(results), + self.NormalizeGetTestsToRunResults(expected), + 'Incorrect set of tests returned:\n%s\nexpected:\n%s' % + (results, expected)) + + def setUp(self): + self.fake_os = FakeOs(FakePath( + current_dir=os.path.abspath(os.path.dirname(run_tests_util.__file__)), + known_paths=[AddExeExtension(GTEST_DBG_DIR + '/gtest_unittest'), + AddExeExtension(GTEST_OPT_DIR + '/gtest_unittest'), + 'test/gtest_color_test.py'])) + self.fake_configurations = ['dbg', 'opt'] + self.test_runner = run_tests_util.TestRunner(script_dir='.', + injected_os=self.fake_os, + injected_subprocess=None) + + def testBinaryTestsOnly(self): + """Exercises GetTestsToRun with parameters designating binary tests only.""" + + # A default build. + self.AssertResultsEqual( + self.test_runner.GetTestsToRun( + ['gtest_unittest'], + '', + False, + available_configurations=self.fake_configurations), + ([], + [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest')])) + + # An explicitly specified directory. + self.AssertResultsEqual( + self.test_runner.GetTestsToRun( + [GTEST_DBG_DIR, 'gtest_unittest'], + '', + False, + available_configurations=self.fake_configurations), + ([], + [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest')])) + + # A particular configuration. + self.AssertResultsEqual( + self.test_runner.GetTestsToRun( + ['gtest_unittest'], + 'other', + False, + available_configurations=self.fake_configurations), + ([], + [(GTEST_OTHER_DIR, GTEST_OTHER_DIR + '/gtest_unittest')])) + + # All available configurations + self.AssertResultsEqual( + self.test_runner.GetTestsToRun( + ['gtest_unittest'], + 'all', + False, + available_configurations=self.fake_configurations), + ([], + [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest'), + (GTEST_OPT_DIR, GTEST_OPT_DIR + '/gtest_unittest')])) + + # All built configurations (unbuilt don't cause failure). + self.AssertResultsEqual( + self.test_runner.GetTestsToRun( + ['gtest_unittest'], + '', + True, + available_configurations=self.fake_configurations + ['unbuilt']), + ([], + [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest'), + (GTEST_OPT_DIR, GTEST_OPT_DIR + '/gtest_unittest')])) + + # A combination of an explicit directory and a configuration. + self.AssertResultsEqual( + self.test_runner.GetTestsToRun( + [GTEST_DBG_DIR, 'gtest_unittest'], + 'opt', + False, + available_configurations=self.fake_configurations), + ([], + [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest'), + (GTEST_OPT_DIR, GTEST_OPT_DIR + '/gtest_unittest')])) + + # Same test specified in an explicit directory and via a configuration. + self.AssertResultsEqual( + self.test_runner.GetTestsToRun( + [GTEST_DBG_DIR, 'gtest_unittest'], + 'dbg', + False, + available_configurations=self.fake_configurations), + ([], + [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest')])) + + # All built configurations + explicit directory + explicit configuration. + self.AssertResultsEqual( + self.test_runner.GetTestsToRun( + [GTEST_DBG_DIR, 'gtest_unittest'], + 'opt', + True, + available_configurations=self.fake_configurations), + ([], + [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest'), + (GTEST_OPT_DIR, GTEST_OPT_DIR + '/gtest_unittest')])) + + def testPythonTestsOnly(self): + """Exercises GetTestsToRun with parameters designating Python tests only.""" + + # A default build. + self.AssertResultsEqual( + self.test_runner.GetTestsToRun( + ['gtest_color_test.py'], + '', + False, + available_configurations=self.fake_configurations), + ([(GTEST_DBG_DIR, 'test/gtest_color_test.py')], + [])) + + # An explicitly specified directory. + self.AssertResultsEqual( + self.test_runner.GetTestsToRun( + [GTEST_DBG_DIR, 'test/gtest_color_test.py'], + '', + False, + available_configurations=self.fake_configurations), + ([(GTEST_DBG_DIR, 'test/gtest_color_test.py')], + [])) + + # A particular configuration. + self.AssertResultsEqual( + self.test_runner.GetTestsToRun( + ['gtest_color_test.py'], + 'other', + False, + available_configurations=self.fake_configurations), + ([(GTEST_OTHER_DIR, 'test/gtest_color_test.py')], + [])) + + # All available configurations + self.AssertResultsEqual( + self.test_runner.GetTestsToRun( + ['test/gtest_color_test.py'], + 'all', + False, + available_configurations=self.fake_configurations), + ([(GTEST_DBG_DIR, 'test/gtest_color_test.py'), + (GTEST_OPT_DIR, 'test/gtest_color_test.py')], + [])) + + # All built configurations (unbuilt don't cause failure). + self.AssertResultsEqual( + self.test_runner.GetTestsToRun( + ['gtest_color_test.py'], + '', + True, + available_configurations=self.fake_configurations + ['unbuilt']), + ([(GTEST_DBG_DIR, 'test/gtest_color_test.py'), + (GTEST_OPT_DIR, 'test/gtest_color_test.py')], + [])) + + # A combination of an explicit directory and a configuration. + self.AssertResultsEqual( + self.test_runner.GetTestsToRun( + [GTEST_DBG_DIR, 'gtest_color_test.py'], + 'opt', + False, + available_configurations=self.fake_configurations), + ([(GTEST_DBG_DIR, 'test/gtest_color_test.py'), + (GTEST_OPT_DIR, 'test/gtest_color_test.py')], + [])) + + # Same test specified in an explicit directory and via a configuration. + self.AssertResultsEqual( + self.test_runner.GetTestsToRun( + [GTEST_DBG_DIR, 'gtest_color_test.py'], + 'dbg', + False, + available_configurations=self.fake_configurations), + ([(GTEST_DBG_DIR, 'test/gtest_color_test.py')], + [])) + + # All built configurations + explicit directory + explicit configuration. + self.AssertResultsEqual( + self.test_runner.GetTestsToRun( + [GTEST_DBG_DIR, 'gtest_color_test.py'], + 'opt', + True, + available_configurations=self.fake_configurations), + ([(GTEST_DBG_DIR, 'test/gtest_color_test.py'), + (GTEST_OPT_DIR, 'test/gtest_color_test.py')], + [])) + + def testCombinationOfBinaryAndPythonTests(self): + """Exercises GetTestsToRun with mixed binary/Python tests.""" + + # Use only default configuration for this test. + + # Neither binary nor Python tests are specified so find all. + self.AssertResultsEqual( + self.test_runner.GetTestsToRun( + [], + '', + False, + available_configurations=self.fake_configurations), + ([(GTEST_DBG_DIR, 'test/gtest_color_test.py')], + [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest')])) + + # Specifying both binary and Python tests. + self.AssertResultsEqual( + self.test_runner.GetTestsToRun( + ['gtest_unittest', 'gtest_color_test.py'], + '', + False, + available_configurations=self.fake_configurations), + ([(GTEST_DBG_DIR, 'test/gtest_color_test.py')], + [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest')])) + + # Specifying binary tests suppresses Python tests. + self.AssertResultsEqual( + self.test_runner.GetTestsToRun( + ['gtest_unittest'], + '', + False, + available_configurations=self.fake_configurations), + ([], + [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest')])) + + # Specifying Python tests suppresses binary tests. + self.AssertResultsEqual( + self.test_runner.GetTestsToRun( + ['gtest_color_test.py'], + '', + False, + available_configurations=self.fake_configurations), + ([(GTEST_DBG_DIR, 'test/gtest_color_test.py')], + [])) + + def testIgnoresNonTestFiles(self): + """Verifies that GetTestsToRun ignores non-test files in the filesystem.""" + + self.fake_os = FakeOs(FakePath( + current_dir=os.path.abspath(os.path.dirname(run_tests_util.__file__)), + known_paths=[AddExeExtension(GTEST_DBG_DIR + '/gtest_nontest'), + 'test/'])) + self.test_runner = run_tests_util.TestRunner(script_dir='.', + injected_os=self.fake_os, + injected_subprocess=None) + self.AssertResultsEqual( + self.test_runner.GetTestsToRun( + [], + '', + True, + available_configurations=self.fake_configurations), + ([], [])) + + def testWorksFromDifferentDir(self): + """Exercises GetTestsToRun from a directory different from run_test.py's.""" + + # Here we simulate an test script in directory /d/ called from the + # directory /a/b/c/. + self.fake_os = FakeOs(FakePath( + current_dir=os.path.abspath('/a/b/c'), + known_paths=[ + '/a/b/c/', + AddExeExtension('/d/' + GTEST_DBG_DIR + '/gtest_unittest'), + AddExeExtension('/d/' + GTEST_OPT_DIR + '/gtest_unittest'), + '/d/test/gtest_color_test.py'])) + self.fake_configurations = ['dbg', 'opt'] + self.test_runner = run_tests_util.TestRunner(script_dir='/d/', + injected_os=self.fake_os, + injected_subprocess=None) + # A binary test. + self.AssertResultsEqual( + self.test_runner.GetTestsToRun( + ['gtest_unittest'], + '', + False, + available_configurations=self.fake_configurations), + ([], + [('/d/' + GTEST_DBG_DIR, '/d/' + GTEST_DBG_DIR + '/gtest_unittest')])) + + # A Python test. + self.AssertResultsEqual( + self.test_runner.GetTestsToRun( + ['gtest_color_test.py'], + '', + False, + available_configurations=self.fake_configurations), + ([('/d/' + GTEST_DBG_DIR, '/d/test/gtest_color_test.py')], [])) + + def testNonTestBinary(self): + """Exercises GetTestsToRun with a non-test parameter.""" + + self.assert_( + not self.test_runner.GetTestsToRun( + ['gtest_unittest_not_really'], + '', + False, + available_configurations=self.fake_configurations)) + + def testNonExistingPythonTest(self): + """Exercises GetTestsToRun with a non-existent Python test parameter.""" + + self.assert_( + not self.test_runner.GetTestsToRun( + ['nonexistent_test.py'], + '', + False, + available_configurations=self.fake_configurations)) + + if run_tests_util.IS_WINDOWS or run_tests_util.IS_CYGWIN: + + def testDoesNotPickNonExeFilesOnWindows(self): + """Verifies that GetTestsToRun does not find _test files on Windows.""" + + self.fake_os = FakeOs(FakePath( + current_dir=os.path.abspath(os.path.dirname(run_tests_util.__file__)), + known_paths=['/d/' + GTEST_DBG_DIR + '/gtest_test', 'test/'])) + self.test_runner = run_tests_util.TestRunner(script_dir='.', + injected_os=self.fake_os, + injected_subprocess=None) + self.AssertResultsEqual( + self.test_runner.GetTestsToRun( + [], + '', + True, + available_configurations=self.fake_configurations), + ([], [])) + + +class RunTestsTest(unittest.TestCase): + """Exercises TestRunner.RunTests.""" + + def SpawnSuccess(self, unused_executable, unused_argv): + """Fakes test success by returning 0 as an exit code.""" + + self.num_spawn_calls += 1 + return 0 + + def SpawnFailure(self, unused_executable, unused_argv): + """Fakes test success by returning 1 as an exit code.""" + + self.num_spawn_calls += 1 + return 1 + + def setUp(self): + self.fake_os = FakeOs(FakePath( + current_dir=os.path.abspath(os.path.dirname(run_tests_util.__file__)), + known_paths=[ + AddExeExtension(GTEST_DBG_DIR + '/gtest_unittest'), + AddExeExtension(GTEST_OPT_DIR + '/gtest_unittest'), + 'test/gtest_color_test.py'])) + self.fake_configurations = ['dbg', 'opt'] + self.test_runner = run_tests_util.TestRunner( + script_dir=os.path.dirname(__file__) or '.', + injected_os=self.fake_os, + injected_subprocess=None) + self.num_spawn_calls = 0 # A number of calls to spawn. + + def testRunPythonTestSuccess(self): + """Exercises RunTests to handle a Python test success.""" + + self.fake_os.spawn_impl = self.SpawnSuccess + self.assertEqual( + self.test_runner.RunTests( + [(GTEST_DBG_DIR, 'test/gtest_color_test.py')], + []), + 0) + self.assertEqual(self.num_spawn_calls, 1) + + def testRunBinaryTestSuccess(self): + """Exercises RunTests to handle a binary test success.""" + + self.fake_os.spawn_impl = self.SpawnSuccess + self.assertEqual( + self.test_runner.RunTests( + [], + [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest')]), + 0) + self.assertEqual(self.num_spawn_calls, 1) + + def testRunPythonTestFauilure(self): + """Exercises RunTests to handle a Python test failure.""" + + self.fake_os.spawn_impl = self.SpawnFailure + self.assertEqual( + self.test_runner.RunTests( + [(GTEST_DBG_DIR, 'test/gtest_color_test.py')], + []), + 1) + self.assertEqual(self.num_spawn_calls, 1) + + def testRunBinaryTestFailure(self): + """Exercises RunTests to handle a binary test failure.""" + + self.fake_os.spawn_impl = self.SpawnFailure + self.assertEqual( + self.test_runner.RunTests( + [], + [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest')]), + 1) + self.assertEqual(self.num_spawn_calls, 1) + + def testCombinedTestSuccess(self): + """Exercises RunTests to handle a success of both Python and binary test.""" + + self.fake_os.spawn_impl = self.SpawnSuccess + self.assertEqual( + self.test_runner.RunTests( + [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest')], + [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest')]), + 0) + self.assertEqual(self.num_spawn_calls, 2) + + def testCombinedTestSuccessAndFailure(self): + """Exercises RunTests to handle a success of both Python and binary test.""" + + def SpawnImpl(executable, argv): + self.num_spawn_calls += 1 + # Simulates failure of a Python test and success of a binary test. + if '.py' in executable or '.py' in argv[0]: + return 1 + else: + return 0 + + self.fake_os.spawn_impl = SpawnImpl + self.assertEqual( + self.test_runner.RunTests( + [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest')], + [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest')]), + 0) + self.assertEqual(self.num_spawn_calls, 2) + + +class ParseArgsTest(unittest.TestCase): + """Exercises ParseArgs.""" + + def testNoOptions(self): + options, args = run_tests_util.ParseArgs('gtest', argv=['script.py']) + self.assertEqual(args, ['script.py']) + self.assert_(options.configurations is None) + self.assertFalse(options.built_configurations) + + def testOptionC(self): + options, args = run_tests_util.ParseArgs( + 'gtest', argv=['script.py', '-c', 'dbg']) + self.assertEqual(args, ['script.py']) + self.assertEqual(options.configurations, 'dbg') + self.assertFalse(options.built_configurations) + + def testOptionA(self): + options, args = run_tests_util.ParseArgs('gtest', argv=['script.py', '-a']) + self.assertEqual(args, ['script.py']) + self.assertEqual(options.configurations, 'all') + self.assertFalse(options.built_configurations) + + def testOptionB(self): + options, args = run_tests_util.ParseArgs('gtest', argv=['script.py', '-b']) + self.assertEqual(args, ['script.py']) + self.assert_(options.configurations is None) + self.assertTrue(options.built_configurations) + + def testOptionCAndOptionB(self): + options, args = run_tests_util.ParseArgs( + 'gtest', argv=['script.py', '-c', 'dbg', '-b']) + self.assertEqual(args, ['script.py']) + self.assertEqual(options.configurations, 'dbg') + self.assertTrue(options.built_configurations) + + def testOptionH(self): + help_called = [False] + + # Suppresses lint warning on unused arguments. These arguments are + # required by optparse, even though they are unused. + # pylint: disable-msg=W0613 + def VerifyHelp(option, opt, value, parser): + help_called[0] = True + + # Verifies that -h causes the help callback to be called. + help_called[0] = False + _, args = run_tests_util.ParseArgs( + 'gtest', argv=['script.py', '-h'], help_callback=VerifyHelp) + self.assertEqual(args, ['script.py']) + self.assertTrue(help_called[0]) + + # Verifies that --help causes the help callback to be called. + help_called[0] = False + _, args = run_tests_util.ParseArgs( + 'gtest', argv=['script.py', '--help'], help_callback=VerifyHelp) + self.assertEqual(args, ['script.py']) + self.assertTrue(help_called[0]) + + +if __name__ == '__main__': + unittest.main() -- cgit v1.2.3 From d56773b492b7b675d5c547baab815289a7815bdd Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Wed, 16 Dec 2009 19:54:05 +0000 Subject: Turns on -Wshadow (by Preston Jackson). --- test/gtest-param-test_test.cc | 4 ++-- test/gtest_unittest.cc | 10 +++++----- test/production.h | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) (limited to 'test') diff --git a/test/gtest-param-test_test.cc b/test/gtest-param-test_test.cc index ecb5fdbb..e718ffb4 100644 --- a/test/gtest-param-test_test.cc +++ b/test/gtest-param-test_test.cc @@ -205,7 +205,7 @@ TEST(RangeTest, IntRangeWithCustomStepOverUpperBound) { // copy constructor, operator=(), operator+(), and operator<(). class DogAdder { public: - explicit DogAdder(const char* value) : value_(value) {} + explicit DogAdder(const char* a_value) : value_(a_value) {} DogAdder(const DogAdder& other) : value_(other.value_.c_str()) {} DogAdder operator=(const DogAdder& other) { @@ -243,7 +243,7 @@ TEST(RangeTest, WorksWithACustomType) { class IntWrapper { public: - explicit IntWrapper(int value) : value_(value) {} + explicit IntWrapper(int a_value) : value_(a_value) {} IntWrapper(const IntWrapper& other) : value_(other.value_) {} IntWrapper operator=(const IntWrapper& other) { diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index bf41de73..5e79c5ac 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -4009,7 +4009,7 @@ TEST(AssertionTest, NonFixtureSubroutine) { // An uncopyable class. class Uncopyable { public: - explicit Uncopyable(int value) : value_(value) {} + explicit Uncopyable(int a_value) : value_(a_value) {} int value() const { return value_; } bool operator==(const Uncopyable& rhs) const { @@ -5095,7 +5095,7 @@ TEST(AssertionResultTest, StreamingWorks) { // both in the global namespace. class Base { public: - explicit Base(int x) : x_(x) {} + explicit Base(int an_x) : x_(an_x) {} int x() const { return x_; } private: int x_; @@ -5122,7 +5122,7 @@ TEST(MessageTest, CanStreamUserTypeInGlobalNameSpace) { namespace { class MyTypeInUnnamedNameSpace : public Base { public: - explicit MyTypeInUnnamedNameSpace(int x): Base(x) {} + explicit MyTypeInUnnamedNameSpace(int an_x): Base(an_x) {} }; std::ostream& operator<<(std::ostream& os, const MyTypeInUnnamedNameSpace& val) { @@ -5147,7 +5147,7 @@ TEST(MessageTest, CanStreamUserTypeInUnnamedNameSpace) { namespace namespace1 { class MyTypeInNameSpace1 : public Base { public: - explicit MyTypeInNameSpace1(int x): Base(x) {} + explicit MyTypeInNameSpace1(int an_x): Base(an_x) {} }; std::ostream& operator<<(std::ostream& os, const MyTypeInNameSpace1& val) { @@ -5172,7 +5172,7 @@ TEST(MessageTest, CanStreamUserTypeInUserNameSpace) { namespace namespace2 { class MyTypeInNameSpace2 : public ::Base { public: - explicit MyTypeInNameSpace2(int x): Base(x) {} + explicit MyTypeInNameSpace2(int an_x): Base(an_x) {} }; } // namespace namespace2 std::ostream& operator<<(std::ostream& os, diff --git a/test/production.h b/test/production.h index 59970da0..8f16fffa 100644 --- a/test/production.h +++ b/test/production.h @@ -48,7 +48,7 @@ class PrivateCode { int x() const { return x_; } private: - void set_x(int x) { x_ = x; } + void set_x(int an_x) { x_ = an_x; } int x_; }; -- cgit v1.2.3 From cca227fe7548171869021bafc31ffd33515f1fcc Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Wed, 16 Dec 2009 20:21:27 +0000 Subject: Moves mis-placed tests. --- test/gtest-test-part_test.cc | 49 ++++++++++++++++++++++++++++++++++++++++++++ test/gtest_unittest.cc | 49 -------------------------------------------- 2 files changed, 49 insertions(+), 49 deletions(-) (limited to 'test') diff --git a/test/gtest-test-part_test.cc b/test/gtest-test-part_test.cc index 403c1845..5a3e9196 100644 --- a/test/gtest-test-part_test.cc +++ b/test/gtest-test-part_test.cc @@ -34,6 +34,7 @@ #include +using testing::Message; using testing::Test; using testing::TestPartResult; using testing::TestPartResultArray; @@ -53,6 +54,54 @@ class TestPartResultTest : public Test { TestPartResult r1_, r2_, r3_; }; + +TEST_F(TestPartResultTest, ConstructorWorks) { + Message message; + message << "something is terribly wrong"; + message << static_cast(testing::internal::kStackTraceMarker); + message << "some unimportant stack trace"; + + const TestPartResult result(TestPartResult::kNonFatalFailure, + "some_file.cc", + 42, + message.GetString().c_str()); + + EXPECT_EQ(TestPartResult::kNonFatalFailure, result.type()); + EXPECT_STREQ("some_file.cc", result.file_name()); + EXPECT_EQ(42, result.line_number()); + EXPECT_STREQ(message.GetString().c_str(), result.message()); + EXPECT_STREQ("something is terribly wrong", result.summary()); +} + +TEST_F(TestPartResultTest, ResultAccessorsWork) { + const TestPartResult success(TestPartResult::kSuccess, + "file.cc", + 42, + "message"); + EXPECT_TRUE(success.passed()); + EXPECT_FALSE(success.failed()); + EXPECT_FALSE(success.nonfatally_failed()); + EXPECT_FALSE(success.fatally_failed()); + + const TestPartResult nonfatal_failure(TestPartResult::kNonFatalFailure, + "file.cc", + 42, + "message"); + EXPECT_FALSE(nonfatal_failure.passed()); + EXPECT_TRUE(nonfatal_failure.failed()); + EXPECT_TRUE(nonfatal_failure.nonfatally_failed()); + EXPECT_FALSE(nonfatal_failure.fatally_failed()); + + const TestPartResult fatal_failure(TestPartResult::kFatalFailure, + "file.cc", + 42, + "message"); + EXPECT_FALSE(fatal_failure.passed()); + EXPECT_TRUE(fatal_failure.failed()); + EXPECT_FALSE(fatal_failure.nonfatally_failed()); + EXPECT_TRUE(fatal_failure.fatally_failed()); +} + // Tests TestPartResult::type(). TEST_F(TestPartResultTest, type) { EXPECT_EQ(TestPartResult::kSuccess, r1_.type()); diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index 5e79c5ac..9745f936 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -1721,55 +1721,6 @@ TEST(TestPropertyTest, SetValue) { EXPECT_STREQ("value_2", property.value()); } -// Tests the TestPartResult class. - -TEST(TestPartResultTest, ConstructorWorks) { - Message message; - message << "something is terribly wrong"; - message << static_cast(testing::internal::kStackTraceMarker); - message << "some unimportant stack trace"; - - const TestPartResult result(TestPartResult::kNonFatalFailure, - "some_file.cc", - 42, - message.GetString().c_str()); - - EXPECT_EQ(TestPartResult::kNonFatalFailure, result.type()); - EXPECT_STREQ("some_file.cc", result.file_name()); - EXPECT_EQ(42, result.line_number()); - EXPECT_STREQ(message.GetString().c_str(), result.message()); - EXPECT_STREQ("something is terribly wrong", result.summary()); -} - -TEST(TestPartResultTest, ResultAccessorsWork) { - const TestPartResult success(TestPartResult::kSuccess, - "file.cc", - 42, - "message"); - EXPECT_TRUE(success.passed()); - EXPECT_FALSE(success.failed()); - EXPECT_FALSE(success.nonfatally_failed()); - EXPECT_FALSE(success.fatally_failed()); - - const TestPartResult nonfatal_failure(TestPartResult::kNonFatalFailure, - "file.cc", - 42, - "message"); - EXPECT_FALSE(nonfatal_failure.passed()); - EXPECT_TRUE(nonfatal_failure.failed()); - EXPECT_TRUE(nonfatal_failure.nonfatally_failed()); - EXPECT_FALSE(nonfatal_failure.fatally_failed()); - - const TestPartResult fatal_failure(TestPartResult::kFatalFailure, - "file.cc", - 42, - "message"); - EXPECT_FALSE(fatal_failure.passed()); - EXPECT_TRUE(fatal_failure.failed()); - EXPECT_FALSE(fatal_failure.nonfatally_failed()); - EXPECT_TRUE(fatal_failure.fatally_failed()); -} - // Tests the TestResult class // The test fixture for testing TestResult. -- cgit v1.2.3 From 88e97c822c988eaa9f8bcbaa1ea5d702ffd7d384 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Wed, 16 Dec 2009 23:34:59 +0000 Subject: Removes uses of GTEST_HAS_STD_STRING. --- test/gtest-death-test_test.cc | 2 -- test/gtest-message_test.cc | 4 ---- test/gtest-port_test.cc | 2 -- test/gtest_output_test.py | 28 ++++++++++++++-------------- test/gtest_unittest.cc | 18 ------------------ test/run_tests_util.py | 29 ++++++++++++++++++++++++++--- 6 files changed, 40 insertions(+), 43 deletions(-) (limited to 'test') diff --git a/test/gtest-death-test_test.cc b/test/gtest-death-test_test.cc index 288c70a0..4dc85b41 100644 --- a/test/gtest-death-test_test.cc +++ b/test/gtest-death-test_test.cc @@ -449,10 +449,8 @@ TEST_F(TestForDeathTest, AcceptsAnythingConvertibleToRE) { EXPECT_DEATH(GlobalFunction(), regex_str); #endif // GTEST_HAS_GLOBAL_STRING -#if GTEST_HAS_STD_STRING const ::std::string regex_std_str(regex_c_str); EXPECT_DEATH(GlobalFunction(), regex_std_str); -#endif // GTEST_HAS_STD_STRING } // Tests that a non-void function can be used in a death test. diff --git a/test/gtest-message_test.cc b/test/gtest-message_test.cc index 6c43c33d..f3dda11e 100644 --- a/test/gtest-message_test.cc +++ b/test/gtest-message_test.cc @@ -92,8 +92,6 @@ TEST(MessageTest, StreamsNullCString) { EXPECT_STREQ("(null)", ToCString(Message() << p)); } -#if GTEST_HAS_STD_STRING - // Tests streaming std::string. // // As std::string has problem in MSVC when exception is disabled, we only @@ -113,8 +111,6 @@ TEST(MessageTest, StreamsStringWithEmbeddedNUL) { ToCString(Message() << string_with_nul)); } -#endif // GTEST_HAS_STD_STRING - // Tests streaming a NUL char. TEST(MessageTest, StreamsNULChar) { EXPECT_STREQ("\\0", ToCString(Message() << '\0')); diff --git a/test/gtest-port_test.cc b/test/gtest-port_test.cc index a2b0059e..551c98b2 100644 --- a/test/gtest-port_test.cc +++ b/test/gtest-port_test.cc @@ -177,9 +177,7 @@ class RETest : public ::testing::Test {}; // Defines StringTypes as the list of all string types that class RE // supports. typedef testing::Types< -#if GTEST_HAS_STD_STRING ::std::string, -#endif // GTEST_HAS_STD_STRING #if GTEST_HAS_GLOBAL_STRING ::string, #endif // GTEST_HAS_GLOBAL_STRING diff --git a/test/gtest_output_test.py b/test/gtest_output_test.py index c8a38f53..8d9a40b0 100755 --- a/test/gtest_output_test.py +++ b/test/gtest_output_test.py @@ -126,15 +126,15 @@ def RemoveTime(output): def RemoveTestCounts(output): """Removes test counts from a Google Test program's output.""" - output = re.sub(r'\d+ tests, listed below', + output = re.sub(r'\d+ tests?, listed below', '? tests, listed below', output) output = re.sub(r'\d+ FAILED TESTS', '? FAILED TESTS', output) - output = re.sub(r'\d+ tests from \d+ test cases', + output = re.sub(r'\d+ tests? from \d+ test cases?', '? tests from ? test cases', output) - output = re.sub(r'\d+ tests from ([a-zA-Z_])', + output = re.sub(r'\d+ tests? from ([a-zA-Z_])', r'? tests from \1', output) - return re.sub(r'\d+ tests\.', '? tests.', output) + return re.sub(r'\d+ tests?\.', '? tests.', output) def RemoveMatchingTests(test_output, pattern): @@ -268,16 +268,16 @@ class GTestOutputTest(gtest_test_utils.TestCase): normalized_actual = RemoveTestCounts(output) normalized_golden = RemoveTestCounts(self.RemoveUnsupportedTests(golden)) - # This code is very handy when debugging test differences so I left it - # here, commented. - # open(os.path.join( - # gtest_test_utils.GetSourceDir(), - # '_gtest_output_test_normalized_actual.txt'), 'wb').write( - # normalized_actual) - # open(os.path.join( - # gtest_test_utils.GetSourceDir(), - # '_gtest_output_test_normalized_golden.txt'), 'wb').write( - # normalized_golden) + # This code is very handy when debugging golden file differences: + if os.getenv('DEBUG_GTEST_OUTPUT_TEST'): + open(os.path.join( + gtest_test_utils.GetSourceDir(), + '_gtest_output_test_normalized_actual.txt'), 'wb').write( + normalized_actual) + open(os.path.join( + gtest_test_utils.GetSourceDir(), + '_gtest_output_test_normalized_golden.txt'), 'wb').write( + normalized_golden) self.assert_(normalized_golden == normalized_actual) diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index 9745f936..ba5eb604 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -1111,8 +1111,6 @@ TEST(StringTest, Constructors) { EXPECT_EQ('c', s7.c_str()[3]); } -#if GTEST_HAS_STD_STRING - TEST(StringTest, ConvertsFromStdString) { // An empty std::string. const std::string src1(""); @@ -1152,8 +1150,6 @@ TEST(StringTest, ConvertsToStdString) { EXPECT_EQ(std::string("x\0y", 3), dest3); } -#endif // GTEST_HAS_STD_STRING - #if GTEST_HAS_GLOBAL_STRING TEST(StringTest, ConvertsFromGlobalString) { @@ -2818,8 +2814,6 @@ TEST(IsSubstringTest, GeneratesCorrectMessageForCString) { "needle", "haystack").failure_message()); } -#if GTEST_HAS_STD_STRING - // Tests that IsSubstring returns the correct result when the input // argument type is ::std::string. TEST(IsSubstringTest, ReturnsCorrectResultsForStdString) { @@ -2827,8 +2821,6 @@ TEST(IsSubstringTest, ReturnsCorrectResultsForStdString) { EXPECT_FALSE(IsSubstring("", "", "hello", std::string("world"))); } -#endif // GTEST_HAS_STD_STRING - #if GTEST_HAS_STD_WSTRING // Tests that IsSubstring returns the correct result when the input // argument type is ::std::wstring. @@ -2879,8 +2871,6 @@ TEST(IsNotSubstringTest, GeneratesCorrectMessageForWideCString) { L"needle", L"two needles").failure_message()); } -#if GTEST_HAS_STD_STRING - // Tests that IsNotSubstring returns the correct result when the input // argument type is ::std::string. TEST(IsNotSubstringTest, ReturnsCorrectResultsForStdString) { @@ -2900,8 +2890,6 @@ TEST(IsNotSubstringTest, GeneratesCorrectMessageForStdString) { ::std::string("needle"), "two needles").failure_message()); } -#endif // GTEST_HAS_STD_STRING - #if GTEST_HAS_STD_WSTRING // Tests that IsNotSubstring returns the correct result when the input @@ -4575,7 +4563,6 @@ TEST(StreamableToStringTest, NullCString) { // Tests using streamable values as assertion messages. -#if GTEST_HAS_STD_STRING // Tests using std::string as an assertion message. TEST(StreamableTest, string) { static const std::string str( @@ -4596,8 +4583,6 @@ TEST(StreamableTest, stringWithEmbeddedNUL) { "Here's a NUL\\0 and some more string"); } -#endif // GTEST_HAS_STD_STRING - // Tests that we can output a NUL char. TEST(StreamableTest, NULChar) { EXPECT_FATAL_FAILURE({ // NOLINT @@ -4720,7 +4705,6 @@ TEST(EqAssertionTest, WideChar) { "Value of: wchar"); } -#if GTEST_HAS_STD_STRING // Tests using ::std::string values in {EXPECT|ASSERT}_EQ. TEST(EqAssertionTest, StdString) { // Compares a const char* to an std::string that has identical @@ -4751,8 +4735,6 @@ TEST(EqAssertionTest, StdString) { " Actual: \"A \\0 in the middle\""); } -#endif // GTEST_HAS_STD_STRING - #if GTEST_HAS_STD_WSTRING // Tests using ::std::wstring values in {EXPECT|ASSERT}_EQ. diff --git a/test/run_tests_util.py b/test/run_tests_util.py index f1bb3e04..fb7fd387 100755 --- a/test/run_tests_util.py +++ b/test/run_tests_util.py @@ -152,6 +152,20 @@ def _GetGtestBuildDir(injected_os, script_dir, config): 'gtest/scons')) +def _GetConfigFromBuildDir(build_dir): + """Extracts the configuration name from the build directory.""" + + # We don't want to depend on build_dir containing the correct path + # separators. + m = re.match(r'.*[\\/]([^\\/]+)[\\/][^\\/]+[\\/]scons[\\/]?$', build_dir) + if m: + return m.group(1) + else: + print >>sys.stderr, ('%s is an invalid build directory that does not ' + 'correspond to any configuration.' % (build_dir,)) + return '' + + # All paths in this script are either absolute or relative to the current # working directory, unless otherwise specified. class TestRunner(object): @@ -270,7 +284,8 @@ class TestRunner(object): args, named_configurations, built_configurations, - available_configurations=CONFIGS): + available_configurations=CONFIGS, + python_tests_to_skip=None): """Determines what tests should be run. Args: @@ -278,7 +293,9 @@ class TestRunner(object): named_configurations: The list of configurations specified via -c or -a. built_configurations: True if -b has been specified. available_configurations: a list of configurations available on the - current platform, injectable for testing. + current platform, injectable for testing. + python_tests_to_skip: a collection of (configuration, python test name)s + that need to be skipped. Returns: A tuple with 2 elements: the list of Python tests to run and the list of @@ -356,7 +373,13 @@ class TestRunner(object): python_test_pairs = [] for directory in build_dirs: for test in selected_python_tests: - python_test_pairs.append((directory, test)) + config = _GetConfigFromBuildDir(directory) + file_name = os.path.basename(test) + if python_tests_to_skip and (config, file_name) in python_tests_to_skip: + print ('NOTE: %s is skipped for configuration %s, as it does not ' + 'work there.' % (file_name, config)) + else: + python_test_pairs.append((directory, test)) binary_test_pairs = [] for directory in build_dirs: -- cgit v1.2.3 From a3dd9d97c57eb1be851a27ffcd6edaed69ee816e Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Fri, 18 Dec 2009 05:23:04 +0000 Subject: Supports building gtest as a DLL (by Vlad Losev). --- test/gtest_dll_test_.cc | 498 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 498 insertions(+) create mode 100644 test/gtest_dll_test_.cc (limited to 'test') diff --git a/test/gtest_dll_test_.cc b/test/gtest_dll_test_.cc new file mode 100644 index 00000000..c99358aa --- /dev/null +++ b/test/gtest_dll_test_.cc @@ -0,0 +1,498 @@ +// Copyright 2009 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: vladl@google.com (Vlad Losev) +// +// Tests for Google Test itself. This verifies that Google Test can be +// linked into an executable successfully when built as a DLL on Windows. +// The test is not meant to check the success of test assertions employed in +// it. It only checks that constructs in them can be successfully linked. +// +// If you add new features to Google Test's documented interface, you need to +// add tests exercising them to this file. +// +// If you start having 'unresolved external symbol' linker errors in this file +// after the changes you have made, re-generate src/gtest.def by running +// scripts/generate_gtest_def.py. + +#include +#include + +#include +#include + +using ::std::vector; +using ::std::tr1::tuple; + + +using ::testing::AddGlobalTestEnvironment; +using ::testing::AssertionFailure; +using ::testing::AssertionResult; +using ::testing::AssertionSuccess; +using ::testing::DoubleLE; +using ::testing::EmptyTestEventListener; +using ::testing::Environment; +using ::testing::ExitedWithCode; +using ::testing::FloatLE; +using ::testing::GTEST_FLAG(also_run_disabled_tests); +using ::testing::GTEST_FLAG(break_on_failure); +using ::testing::GTEST_FLAG(catch_exceptions); +using ::testing::GTEST_FLAG(color); +using ::testing::GTEST_FLAG(filter); +using ::testing::GTEST_FLAG(output); +using ::testing::GTEST_FLAG(print_time); +using ::testing::GTEST_FLAG(random_seed); +using ::testing::GTEST_FLAG(repeat); +using ::testing::GTEST_FLAG(shuffle); +using ::testing::GTEST_FLAG(stack_trace_depth); +using ::testing::GTEST_FLAG(throw_on_failure); +using ::testing::InitGoogleTest; +using ::testing::Message; +using ::testing::Test; +using ::testing::TestCase; +using ::testing::TestEventListener; +using ::testing::TestEventListeners; +using ::testing::TestInfo; +using ::testing::TestPartResult; +using ::testing::TestProperty; +using ::testing::TestResult; +using ::testing::UnitTest; +using ::testing::internal::AlwaysTrue; +using ::testing::internal::AlwaysFalse; + +#if GTEST_HAS_PARAM_TEST +using ::testing::Bool; +using ::testing::Combine; +using ::testing::TestWithParam; +using ::testing::Values; +using ::testing::ValuesIn; +#endif // GTEST_HAS_PARAM_TEST + +#if GTEST_HAS_TYPED_TEST +using ::testing::Types; +#endif // GTEST_HAS_TYPED_TEST + +// Tests linking of TEST constructs. +TEST(TestMacroTest, LinksSuccessfully) { +} + +// Tests linking of TEST_F constructs. +class FixtureTest : public Test { +}; + +TEST_F(FixtureTest, LinksSuccessfully) { +} + +// Tests linking of value parameterized tests. +#if GTEST_HAS_PARAM_TEST +class IntParamTest : public TestWithParam {}; + +TEST_P(IntParamTest, LinksSuccessfully) {} + +const int c_array[] = {1, 2}; +INSTANTIATE_TEST_CASE_P(ValuesInCArrayTest, IntParamTest, ValuesIn(c_array)); + +INSTANTIATE_TEST_CASE_P(ValuesInIteratorPairTest, IntParamTest, + ValuesIn(c_array, c_array + 2)); + +vector stl_vector(c_array, c_array + 2); +INSTANTIATE_TEST_CASE_P(ValuesInStlVectorTest, IntParamTest, + ValuesIn(stl_vector)); + +class BoolParamTest : public TestWithParam {}; + +INSTANTIATE_TEST_CASE_P(BoolTest, BoolParamTest, Bool()); + +INSTANTIATE_TEST_CASE_P(ValuesTest, IntParamTest, Values(1, 2)); + +#if GTEST_HAS_COMBINE +class CombineTest : public TestWithParam > {}; + +INSTANTIATE_TEST_CASE_P(CombineTest, CombineTest, Combine(Values(1), Bool())); +#endif // GTEST_HAS_COMBINE +#endif // GTEST_HAS_PARAM_TEST + +// Tests linking of typed tests. +#if GTEST_HAS_TYPED_TEST +template class TypedTest : public Test {}; + +TYPED_TEST_CASE(TypedTest, Types); + +TYPED_TEST(TypedTest, LinksSuccessfully) {} +#endif // GTEST_HAS_TYPED_TEST + +// Tests linking of type-parameterized tests. +#if GTEST_HAS_TYPED_TEST_P +template class TypeParameterizedTest : public Test {}; + +TYPED_TEST_CASE_P(TypeParameterizedTest); + +TYPED_TEST_P(TypeParameterizedTest, LinksSuccessfully) {} + +REGISTER_TYPED_TEST_CASE_P(TypeParameterizedTest, LinksSuccessfully); + +INSTANTIATE_TYPED_TEST_CASE_P(Char, TypeParameterizedTest, Types); +#endif // GTEST_HAS_TYPED_TEST_P + +// Tests linking of explicit success or failure. +TEST(ExplicitSuccessFailureTest, ExplicitSuccessAndFailure) { + if (AlwaysTrue()) + SUCCEED() << "This is a success statement"; + if (AlwaysFalse()) { + ADD_FAILURE() << "This is a non-fatal failure assertion"; + FAIL() << "This is a fatal failure assertion"; + } +} + +// Tests linking of Boolean assertions. +AssertionResult IsEven(int n) { + if (n % 2 == 0) + return AssertionSuccess() << n << " is even"; + else + return AssertionFailure() << n << " is odd"; +} + +TEST(BooleanAssertionTest, LinksSuccessfully) { + EXPECT_TRUE(true) << "true is true"; + EXPECT_FALSE(false) << "false is not true"; + ASSERT_TRUE(true); + ASSERT_FALSE(false); + EXPECT_TRUE(IsEven(2)); + EXPECT_FALSE(IsEven(3)); +} + +// Tests linking of predicate assertions. +bool IsOdd(int n) { return n % 2 != 0; } + +bool Ge(int val1, int val2) { return val1 >= val2; } + +TEST(PredicateAssertionTest, LinksSuccessfully) { + EXPECT_PRED1(IsOdd, 1); + EXPECT_PRED2(Ge, 2, 1); +} + +AssertionResult AddToFive(const char* val1_expr, + const char* val2_expr, + int val1, + int val2) { + if (val1 + val2 == 5) + return AssertionSuccess(); + + return AssertionFailure() << val1_expr << " and " << val2_expr + << " (" << val1 << " and " << val2 << ") " + << "do not add up to five, as their sum is " + << val1 + val2; +} + +TEST(PredicateFormatterAssertionTest, LinksSuccessfully) { + EXPECT_PRED_FORMAT2(AddToFive, 1 + 2, 2); +} + + +// Tests linking of comparison assertions. +TEST(ComparisonAssertionTest, LinksSuccessfully) { + EXPECT_EQ(1, 1); + EXPECT_NE(1, 2); + EXPECT_LT(1, 2); + EXPECT_LE(1, 1); + EXPECT_GT(2, 1); + EXPECT_GE(2, 1); + + EXPECT_EQ('\n', '\n'); + EXPECT_NE('\n', '\r'); + EXPECT_LT('\n', 'a'); + EXPECT_LE('\n', 'b'); + EXPECT_GT('a', '\t'); + EXPECT_GE('b', '\t'); +} + +TEST(StringComparisonAssertionTest, LinksSuccessfully) { + EXPECT_STREQ("test", "test"); + EXPECT_STRNE("test", "prod"); + + char test_str[5] = "test"; + char prod_str[5] = "prod"; + + EXPECT_STREQ(test_str, test_str); + EXPECT_STRNE(test_str, prod_str); + + EXPECT_STRCASEEQ("test", "TEST"); + EXPECT_STRCASENE("test", "prod"); + + wchar_t test_wstr[5] = L"test"; + wchar_t prod_wstr[5] = L"prod"; + + EXPECT_STREQ(L"test", L"test"); + EXPECT_STRNE(L"test", L"prod"); + + EXPECT_STREQ(test_wstr, test_wstr); + EXPECT_STRNE(test_wstr, prod_wstr); + +#if GTEST_HAS_STD_STRING + EXPECT_EQ("test", ::std::string("test")); + EXPECT_NE("test", ::std::string("prod")); + + EXPECT_EQ(::std::string("test"), "test"); + EXPECT_NE(::std::string("prod"), "test"); + + EXPECT_EQ(test_str, ::std::string("test")); + EXPECT_NE(test_str, ::std::string("prod")); + + EXPECT_EQ(::std::string("test"), test_str); + EXPECT_NE(::std::string("prod"), test_str); + + EXPECT_EQ(::std::string("test"), ::std::string("test")); + EXPECT_NE(::std::string("test"), ::std::string("prod")); +#endif // GTEST_HAS_STD_STRING + +#if GTEST_HAS_STD_WSTRING + EXPECT_EQ(L"test", ::std::wstring(L"test")); + EXPECT_NE(L"test", ::std::wstring(L"prod")); + + EXPECT_EQ(::std::wstring(L"test"), L"test"); + EXPECT_NE(::std::wstring(L"prod"), L"test"); + + EXPECT_EQ(test_wstr, ::std::wstring(L"test")); + EXPECT_NE(test_wstr, ::std::wstring(L"prod")); + + EXPECT_EQ(::std::wstring(L"test"), test_wstr); + EXPECT_NE(::std::wstring(L"prod"), test_wstr); + + EXPECT_EQ(::std::wstring(L"test"), ::std::wstring(L"test")); + EXPECT_NE(::std::wstring(L"test"), ::std::wstring(L"prod")); +#endif // GTEST_HAS_STD_WSTRING +} + +// Tests linking of floating point assertions. +TEST(FloatingPointComparisonAssertionTest, LinksSuccessfully) { + EXPECT_FLOAT_EQ(0.0f, 0.0f); + EXPECT_DOUBLE_EQ(0.0, 0.0); + EXPECT_NEAR(0.0, 0.1, 0.2); + EXPECT_PRED_FORMAT2(::testing::FloatLE, 0.0f, 0.01f); + EXPECT_PRED_FORMAT2(::testing::DoubleLE, 0.0, 0.001); +} + +// Tests linking of HRESULT assertions. +TEST(HresultAssertionTest, LinksSuccessfully) { + EXPECT_HRESULT_SUCCEEDED(S_OK); + EXPECT_HRESULT_FAILED(E_FAIL); +} + +#if GTEST_HAS_EXCEPTIONS +// Tests linking of exception assertions. +TEST(ExceptionAssertionTest, LinksSuccessfully) { + EXPECT_THROW(throw 1, int); + EXPECT_ANY_THROW(throw 1); + EXPECT_NO_THROW(int x = 1); +} +#endif // GTEST_HAS_EXCEPTIONS + +// Tests linking of death test assertions. +TEST(DeathTestAssertionDeathTest, LinksSuccessfully) { + EXPECT_DEATH_IF_SUPPORTED(exit(1), ""); + +#if GTEST_HAS_DEATH_TEST + EXPECT_EXIT(exit(1), ExitedWithCode(1), ""); +#endif // GTEST_HAS_DEATH_TEST +} + +// Tests linking of SCOPED_TRACE. +void Sub() { EXPECT_EQ(1, 1); } + +TEST(ScopedTraceTest, LinksSuccessfully) { + SCOPED_TRACE("X"); + Sub(); +} + +// Tests linking of failure absence assertions. +TEST(NoFailureAssertionTest, LinksSuccessfully) { + EXPECT_NO_FATAL_FAILURE(IsEven(2)); +} + +// Tests linking of HasFatalFailure. +TEST(HasFatalFailureTest, LinksSuccessfully) { + EXPECT_FALSE(HasFatalFailure()); + EXPECT_FALSE(HasNonfatalFailure()); + EXPECT_FALSE(HasFailure()); +} + +// Tests linking of RecordProperty. +TEST(RecordPropertyTest, LinksSuccessfully) { + RecordProperty("DummyPropery", "DummyValue"); +} + +// Tests linking of environments. +class MyEnvironment : public Environment {}; + +Environment* const environment = AddGlobalTestEnvironment(new MyEnvironment); + +// Tests linking of flags. +TEST(FlagTest, LinksSuccessfully) { + Message message; + + message << GTEST_FLAG(filter); + message << GTEST_FLAG(also_run_disabled_tests); + message << GTEST_FLAG(repeat); + message << GTEST_FLAG(shuffle); + message << GTEST_FLAG(random_seed); + message << GTEST_FLAG(color); + message << GTEST_FLAG(print_time); + message << GTEST_FLAG(output); + message << GTEST_FLAG(break_on_failure); + message << GTEST_FLAG(throw_on_failure); + message << GTEST_FLAG(catch_exceptions); + message << GTEST_FLAG(stack_trace_depth); +} + +// Tests linking of failure catching assertions. +void FunctionWithFailure() { FAIL(); } + +TEST(FailureCatchingAssertionTest, LinksCorrectly) { + EXPECT_FATAL_FAILURE(FunctionWithFailure(), ""); + EXPECT_NONFATAL_FAILURE(ADD_FAILURE(), ""); + EXPECT_FATAL_FAILURE_ON_ALL_THREADS(FunctionWithFailure(), ""); + EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(ADD_FAILURE(), ""); +} + +// Tests linking of the reflection API. +TEST(ReflectionApiTest, LinksCorrectly) { + // UnitTest API. + UnitTest* unit_test = UnitTest::GetInstance(); + + unit_test->original_working_dir(); + EXPECT_TRUE(unit_test->current_test_case() != NULL); + EXPECT_TRUE(unit_test->current_test_info() != NULL); + EXPECT_NE(0, unit_test->random_seed()); + EXPECT_GE(unit_test->successful_test_case_count(), 0); + EXPECT_EQ(0, unit_test->failed_test_case_count()); + EXPECT_GE(unit_test->total_test_case_count(), 0); + EXPECT_GT(unit_test->test_case_to_run_count(), 0); + EXPECT_GE(unit_test->successful_test_count(), 0); + EXPECT_EQ(0, unit_test->failed_test_count()); + EXPECT_EQ(0, unit_test->disabled_test_count()); + EXPECT_GT(unit_test->total_test_count(), 0); + EXPECT_GT(unit_test->test_to_run_count(), 0); + EXPECT_GE(unit_test->elapsed_time(), 0); + EXPECT_TRUE(unit_test->Passed()); + EXPECT_FALSE(unit_test->Failed()); + EXPECT_TRUE(unit_test->GetTestCase(0) != NULL); + + // TestCase API. + const TestCase*const test_case = unit_test->current_test_case(); + + EXPECT_STRNE("", test_case->name()); + const char* const test_case_comment = test_case->comment(); + EXPECT_TRUE(test_case->should_run()); + EXPECT_GE(test_case->successful_test_count(), 0); + EXPECT_EQ(0, test_case->failed_test_count()); + EXPECT_EQ(0, test_case->disabled_test_count()); + EXPECT_GT(test_case->test_to_run_count(), 0); + EXPECT_GT(test_case->total_test_count(), 0); + EXPECT_TRUE(test_case->Passed()); + EXPECT_FALSE(test_case->Failed()); + EXPECT_GE(test_case->elapsed_time(), 0); + EXPECT_TRUE(test_case->GetTestInfo(0) != NULL); + + // TestInfo API. + const TestInfo* const test_info = unit_test->current_test_info(); + + EXPECT_STRNE("", test_info->test_case_name()); + EXPECT_STRNE("", test_info->name()); + EXPECT_STREQ(test_case_comment, test_info->test_case_comment()); + const char* const comment = test_info->comment(); + EXPECT_TRUE(comment == NULL || strlen(comment) >= 0); + EXPECT_TRUE(test_info->should_run()); + EXPECT_TRUE(test_info->result() != NULL); + + // TestResult API. + const TestResult* const test_result = test_info->result(); + + SUCCEED() << "This generates a successful test part instance for API testing"; + RecordProperty("Test Name", "Test Value"); + EXPECT_EQ(1, test_result->total_part_count()); + EXPECT_EQ(1, test_result->test_property_count()); + EXPECT_TRUE(test_result->Passed()); + EXPECT_FALSE(test_result->Failed()); + EXPECT_FALSE(test_result->HasFatalFailure()); + EXPECT_FALSE(test_result->HasNonfatalFailure()); + EXPECT_GE(test_result->elapsed_time(), 0); + const TestPartResult& test_part_result = test_result->GetTestPartResult(0); + const TestProperty& test_property = test_result->GetTestProperty(0); + + // TestPartResult API. + EXPECT_EQ(TestPartResult::kSuccess, test_part_result.type()); + EXPECT_STRNE("", test_part_result.file_name()); + EXPECT_GT(test_part_result.line_number(), 0); + EXPECT_STRNE("", test_part_result.summary()); + EXPECT_STRNE("", test_part_result.message()); + EXPECT_TRUE(test_part_result.passed()); + EXPECT_FALSE(test_part_result.failed()); + EXPECT_FALSE(test_part_result.nonfatally_failed()); + EXPECT_FALSE(test_part_result.fatally_failed()); + + // TestProperty API. + EXPECT_STREQ("Test Name", test_property.key()); + EXPECT_STREQ("Test Value", test_property.value()); +} + +// Tests linking of the event listener API. +class MyListener : public TestEventListener { + virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) {} + virtual void OnTestIterationStart(const UnitTest& /*unit_test*/, + int /*iteration*/) {} + virtual void OnEnvironmentsSetUpStart(const UnitTest& /*unit_test*/) {} + virtual void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) {} + virtual void OnTestCaseStart(const TestCase& /*test_case*/) {} + virtual void OnTestStart(const TestInfo& /*test_info*/) {} + virtual void OnTestPartResult(const TestPartResult& /*test_part_result*/) {} + virtual void OnTestEnd(const TestInfo& /*test_info*/) {} + virtual void OnTestCaseEnd(const TestCase& /*test_case*/) {} + virtual void OnEnvironmentsTearDownStart(const UnitTest& /*unit_test*/) {} + virtual void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) {} + virtual void OnTestIterationEnd(const UnitTest& /*unit_test*/, + int /*iteration*/) {} + virtual void OnTestProgramEnd(const UnitTest& /*unit_test*/) {} +}; + +class MyOtherListener : public EmptyTestEventListener {}; + +int main(int argc, char **argv) { + testing::InitGoogleTest(&argc, argv); + + TestEventListeners& listeners = UnitTest::GetInstance()->listeners(); + TestEventListener* listener = new MyListener; + + listeners.Append(listener); + listeners.Release(listener); + listeners.Append(new MyOtherListener); + listener = listeners.default_result_printer(); + listener = listeners.default_xml_generator(); + + RUN_ALL_TESTS(); + return 0; +} -- cgit v1.2.3 From 24265424027ffff14861ef9b6de9e57307b9feeb Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Wed, 23 Dec 2009 20:47:20 +0000 Subject: Removes support for MSVC 7.1 from the scons scripts. --- test/run_tests_util.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'test') diff --git a/test/run_tests_util.py b/test/run_tests_util.py index fb7fd387..9e57931e 100755 --- a/test/run_tests_util.py +++ b/test/run_tests_util.py @@ -111,8 +111,6 @@ KNOWN BUILD DIRECTORIES On Windows: <%(proj)s root>/scons/build/win-dbg8/%(proj)s/scons/ <%(proj)s root>/scons/build/win-opt8/%(proj)s/scons/ - <%(proj)s root>/scons/build/win-dbg/%(proj)s/scons/ - <%(proj)s root>/scons/build/win-opt/%(proj)s/scons/ On Mac: <%(proj)s root>/scons/build/mac-dbg/%(proj)s/scons/ <%(proj)s root>/scons/build/mac-opt/%(proj)s/scons/ @@ -127,7 +125,7 @@ IS_CYGWIN = os.name == 'posix' and 'CYGWIN' in os.uname()[0] # Definition of CONFIGS must match that of the build directory names in the # SConstruct script. The first list item is the default build configuration. if IS_WINDOWS: - CONFIGS = ('win-dbg8', 'win-opt8', 'win-dbg', 'win-opt') + CONFIGS = ('win-dbg8', 'win-opt8') elif IS_MAC: CONFIGS = ('mac-dbg', 'mac-opt') else: -- cgit v1.2.3 From e92ccedad996eeb4f0d9244a1acd8882b5f54fd0 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Fri, 8 Jan 2010 00:23:45 +0000 Subject: Changes Message() to print double with enough precision by default. --- test/gtest-message_test.cc | 20 ++++++++++++++++--- test/gtest_unittest.cc | 48 +++++++++++++++++++++++----------------------- 2 files changed, 41 insertions(+), 27 deletions(-) (limited to 'test') diff --git a/test/gtest-message_test.cc b/test/gtest-message_test.cc index f3dda11e..e42b0344 100644 --- a/test/gtest-message_test.cc +++ b/test/gtest-message_test.cc @@ -68,6 +68,23 @@ TEST(MessageTest, ConstructsFromCString) { EXPECT_STREQ("Hello", ToCString(msg)); } +// Tests streaming a float. +TEST(MessageTest, StreamsFloat) { + const char* const s = ToCString(Message() << 1.23456F << " " << 2.34567F); + // Both numbers should be printed with enough precision. + EXPECT_PRED_FORMAT2(testing::IsSubstring, "1.234560", s); + EXPECT_PRED_FORMAT2(testing::IsSubstring, " 2.345669", s); +} + +// Tests streaming a double. +TEST(MessageTest, StreamsDouble) { + const char* const s = ToCString(Message() << 1260570880.4555497 << " " + << 1260572265.1954534); + // Both numbers should be printed with enough precision. + EXPECT_PRED_FORMAT2(testing::IsSubstring, "1260570880.45", s); + EXPECT_PRED_FORMAT2(testing::IsSubstring, " 1260572265.19", s); +} + // Tests streaming a non-char pointer. TEST(MessageTest, StreamsPointer) { int n = 0; @@ -93,9 +110,6 @@ TEST(MessageTest, StreamsNullCString) { } // Tests streaming std::string. -// -// As std::string has problem in MSVC when exception is disabled, we only -// test this where std::string can be used. TEST(MessageTest, StreamsString) { const ::std::string str("Hello"); EXPECT_STREQ("Hello", ToCString(Message() << str)); diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index ba5eb604..16de794d 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -82,7 +82,7 @@ namespace testing { namespace internal { bool ShouldUseColor(bool stdout_is_tty); -const char* FormatTimeInMillisAsSeconds(TimeInMillis ms); +::std::string FormatTimeInMillisAsSeconds(TimeInMillis ms); bool ParseInt32Flag(const char* str, const char* flag, Int32* value); // Used for testing the flag parsing. @@ -270,23 +270,23 @@ TEST(GetTestTypeIdTest, ReturnsTheSameValueInsideOrOutsideOfGoogleTest) { // Tests FormatTimeInMillisAsSeconds(). TEST(FormatTimeInMillisAsSecondsTest, FormatsZero) { - EXPECT_STREQ("0", FormatTimeInMillisAsSeconds(0)); + EXPECT_EQ("0", FormatTimeInMillisAsSeconds(0)); } TEST(FormatTimeInMillisAsSecondsTest, FormatsPositiveNumber) { - EXPECT_STREQ("0.003", FormatTimeInMillisAsSeconds(3)); - EXPECT_STREQ("0.01", FormatTimeInMillisAsSeconds(10)); - EXPECT_STREQ("0.2", FormatTimeInMillisAsSeconds(200)); - EXPECT_STREQ("1.2", FormatTimeInMillisAsSeconds(1200)); - EXPECT_STREQ("3", FormatTimeInMillisAsSeconds(3000)); + EXPECT_EQ("0.003", FormatTimeInMillisAsSeconds(3)); + EXPECT_EQ("0.01", FormatTimeInMillisAsSeconds(10)); + EXPECT_EQ("0.2", FormatTimeInMillisAsSeconds(200)); + EXPECT_EQ("1.2", FormatTimeInMillisAsSeconds(1200)); + EXPECT_EQ("3", FormatTimeInMillisAsSeconds(3000)); } TEST(FormatTimeInMillisAsSecondsTest, FormatsNegativeNumber) { - EXPECT_STREQ("-0.003", FormatTimeInMillisAsSeconds(-3)); - EXPECT_STREQ("-0.01", FormatTimeInMillisAsSeconds(-10)); - EXPECT_STREQ("-0.2", FormatTimeInMillisAsSeconds(-200)); - EXPECT_STREQ("-1.2", FormatTimeInMillisAsSeconds(-1200)); - EXPECT_STREQ("-3", FormatTimeInMillisAsSeconds(-3000)); + EXPECT_EQ("-0.003", FormatTimeInMillisAsSeconds(-3)); + EXPECT_EQ("-0.01", FormatTimeInMillisAsSeconds(-10)); + EXPECT_EQ("-0.2", FormatTimeInMillisAsSeconds(-200)); + EXPECT_EQ("-1.2", FormatTimeInMillisAsSeconds(-1200)); + EXPECT_EQ("-3", FormatTimeInMillisAsSeconds(-3000)); } #if !GTEST_OS_SYMBIAN @@ -3095,9 +3095,9 @@ TEST_F(FloatTest, Commutative) { TEST_F(FloatTest, EXPECT_NEAR) { EXPECT_NEAR(-1.0f, -1.1f, 0.2f); EXPECT_NEAR(2.0f, 3.0f, 1.0f); - EXPECT_NONFATAL_FAILURE(EXPECT_NEAR(1.0f,1.2f, 0.1f), // NOLINT - "The difference between 1.0f and 1.2f is 0.2, " - "which exceeds 0.1f"); + EXPECT_NONFATAL_FAILURE(EXPECT_NEAR(1.0f,1.5f, 0.25f), // NOLINT + "The difference between 1.0f and 1.5f is 0.5, " + "which exceeds 0.25f"); // To work around a bug in gcc 2.95.0, there is intentionally no // space after the first comma in the previous line. } @@ -3106,9 +3106,9 @@ TEST_F(FloatTest, EXPECT_NEAR) { TEST_F(FloatTest, ASSERT_NEAR) { ASSERT_NEAR(-1.0f, -1.1f, 0.2f); ASSERT_NEAR(2.0f, 3.0f, 1.0f); - EXPECT_FATAL_FAILURE(ASSERT_NEAR(1.0f,1.2f, 0.1f), // NOLINT - "The difference between 1.0f and 1.2f is 0.2, " - "which exceeds 0.1f"); + EXPECT_FATAL_FAILURE(ASSERT_NEAR(1.0f,1.5f, 0.25f), // NOLINT + "The difference between 1.0f and 1.5f is 0.5, " + "which exceeds 0.25f"); // To work around a bug in gcc 2.95.0, there is intentionally no // space after the first comma in the previous line. } @@ -3261,9 +3261,9 @@ TEST_F(DoubleTest, Commutative) { TEST_F(DoubleTest, EXPECT_NEAR) { EXPECT_NEAR(-1.0, -1.1, 0.2); EXPECT_NEAR(2.0, 3.0, 1.0); - EXPECT_NONFATAL_FAILURE(EXPECT_NEAR(1.0, 1.2, 0.1), // NOLINT - "The difference between 1.0 and 1.2 is 0.2, " - "which exceeds 0.1"); + EXPECT_NONFATAL_FAILURE(EXPECT_NEAR(1.0, 1.5, 0.25), // NOLINT + "The difference between 1.0 and 1.5 is 0.5, " + "which exceeds 0.25"); // To work around a bug in gcc 2.95.0, there is intentionally no // space after the first comma in the previous statement. } @@ -3272,9 +3272,9 @@ TEST_F(DoubleTest, EXPECT_NEAR) { TEST_F(DoubleTest, ASSERT_NEAR) { ASSERT_NEAR(-1.0, -1.1, 0.2); ASSERT_NEAR(2.0, 3.0, 1.0); - EXPECT_FATAL_FAILURE(ASSERT_NEAR(1.0, 1.2, 0.1), // NOLINT - "The difference between 1.0 and 1.2 is 0.2, " - "which exceeds 0.1"); + EXPECT_FATAL_FAILURE(ASSERT_NEAR(1.0, 1.5, 0.25), // NOLINT + "The difference between 1.0 and 1.5 is 0.5, " + "which exceeds 0.25"); // To work around a bug in gcc 2.95.0, there is intentionally no // space after the first comma in the previous statement. } -- cgit v1.2.3 From fd6f2a8a4b3fe8beb31f26b774b460727c410b66 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Wed, 27 Jan 2010 22:27:30 +0000 Subject: Implements stdout capturing (by Vlad Losev); fixes compiler error on NVCC (by Zhanyong Wan). --- test/gtest-port_test.cc | 46 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 43 insertions(+), 3 deletions(-) (limited to 'test') diff --git a/test/gtest-port_test.cc b/test/gtest-port_test.cc index 551c98b2..3576c2b8 100644 --- a/test/gtest-port_test.cc +++ b/test/gtest-port_test.cc @@ -33,6 +33,8 @@ #include +#include + #if GTEST_OS_MAC #include #include @@ -699,11 +701,49 @@ TEST(RETest, PartialMatchWorks) { #endif // GTEST_USES_POSIX_RE -TEST(CaptureStderrTest, CapturesStdErr) { +#if !GTEST_OS_WINDOWS_MOBILE + +TEST(CaptureTest, CapturesStdout) { + CaptureStdout(); + fprintf(stdout, "abc"); + EXPECT_STREQ("abc", GetCapturedStdout().c_str()); + + CaptureStdout(); + fprintf(stdout, "def%cghi", '\0'); + EXPECT_EQ(::std::string("def\0ghi", 7), ::std::string(GetCapturedStdout())); +} + +TEST(CaptureTest, CapturesStderr) { + CaptureStderr(); + fprintf(stderr, "jkl"); + EXPECT_STREQ("jkl", GetCapturedStderr().c_str()); + CaptureStderr(); - fprintf(stderr, "abc"); - ASSERT_STREQ("abc", GetCapturedStderr().c_str()); + fprintf(stderr, "jkl%cmno", '\0'); + EXPECT_EQ(::std::string("jkl\0mno", 7), ::std::string(GetCapturedStderr())); } +// Tests that stdout and stderr capture don't interfere with each other. +TEST(CaptureTest, CapturesStdoutAndStderr) { + CaptureStdout(); + CaptureStderr(); + fprintf(stdout, "pqr"); + fprintf(stderr, "stu"); + EXPECT_STREQ("pqr", GetCapturedStdout().c_str()); + EXPECT_STREQ("stu", GetCapturedStderr().c_str()); +} + +TEST(CaptureDeathTest, CannotReenterStdoutCapture) { + CaptureStdout(); + EXPECT_DEATH_IF_SUPPORTED(CaptureStdout();, + "Only one stdout capturer can exist at a time"); + GetCapturedStdout(); + + // We cannot test stderr capturing using death tests as they use it + // themselves. +} + +#endif // !GTEST_OS_WINDOWS_MOBILE + } // namespace internal } // namespace testing -- cgit v1.2.3 From 81e1cc73c83265e54b2ec7edc17e77f4d1b89e86 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Thu, 28 Jan 2010 21:50:29 +0000 Subject: Introduces macro GTEST_HAS_STREAM_REDIRECTION_ (by Vlad Losev); fixes unsynchronized color text output on Windows (by Vlad Losev); fixes the cmake script to work with MSVC 10 (by Manuel Klimek). --- test/gtest_unittest.cc | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) (limited to 'test') diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index 16de794d..a5934946 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -184,6 +184,11 @@ using testing::internal::kMaxRandomSeed; using testing::internal::kTestTypeIdInGoogleTest; using testing::internal::scoped_ptr; +#if GTEST_HAS_STREAM_REDIRECTION_ +using testing::internal::CaptureStdout; +using testing::internal::GetCapturedStdout; +#endif // GTEST_HAS_STREAM_REDIRECTION_ + class TestingVector : public Vector { }; @@ -5471,9 +5476,17 @@ class InitGoogleTestTest : public Test { const bool saved_help_flag = ::testing::internal::g_help_flag; ::testing::internal::g_help_flag = false; +#if GTEST_HAS_STREAM_REDIRECTION_ + CaptureStdout(); +#endif // GTEST_HAS_STREAM_REDIRECTION_ + // Parses the command line. internal::ParseGoogleTestFlagsOnly(&argc1, const_cast(argv1)); +#if GTEST_HAS_STREAM_REDIRECTION_ + const String captured_stdout = GetCapturedStdout(); +#endif // GTEST_HAS_STREAM_REDIRECTION_ + // Verifies the flag values. CheckFlags(expected); @@ -5485,8 +5498,16 @@ class InitGoogleTestTest : public Test { // help message for the flags it recognizes. EXPECT_EQ(should_print_help, ::testing::internal::g_help_flag); - // TODO(vladl@google.com): Verify that the help output is not printed - // for recognized flags when stdout capturing is implemeted. +#if GTEST_HAS_STREAM_REDIRECTION_ + const char* const expected_help_fragment = + "This program contains tests written using"; + if (should_print_help) { + EXPECT_PRED_FORMAT2(IsSubstring, expected_help_fragment, captured_stdout); + } else { + EXPECT_PRED_FORMAT2(IsNotSubstring, + expected_help_fragment, captured_stdout); + } +#endif // GTEST_HAS_STREAM_REDIRECTION_ ::testing::internal::g_help_flag = saved_help_flag; } -- cgit v1.2.3 From 8d373310561a8d68d2a22ca7c6613deff5fa6e05 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Tue, 2 Feb 2010 22:33:34 +0000 Subject: Adds support for alternate path separator on Windows, and make all tests pass with CMake and VC++ 9 (by Manuel Klimek). --- test/gtest-death-test_test.cc | 18 ------ test/gtest-filepath_test.cc | 103 +++++++++++++++++++++++++++++++ test/gtest_break_on_failure_unittest_.cc | 20 ++++++ 3 files changed, 123 insertions(+), 18 deletions(-) (limited to 'test') diff --git a/test/gtest-death-test_test.cc b/test/gtest-death-test_test.cc index 4dc85b41..1c7fa474 100644 --- a/test/gtest-death-test_test.cc +++ b/test/gtest-death-test_test.cc @@ -657,24 +657,6 @@ static void TestExitMacros() { EXPECT_EXIT(_exit(1), testing::ExitedWithCode(1), ""); ASSERT_EXIT(_exit(42), testing::ExitedWithCode(42), ""); -#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MINGW - // MinGW (as of MinGW 5.1.6 and MSYS 1.0.11) does not tag crashed - // processes with non-zero exit code and does not honor calls to - // SetErrorMode(SEM_NOGPFAULTERRORBOX) that are supposed to suppress - // error pop-ups. - EXPECT_EXIT({ - testing::GTEST_FLAG(catch_exceptions) = false; - *static_cast(NULL) = 1; - }, testing::ExitedWithCode(0xC0000005), "") << "foo"; - - EXPECT_NONFATAL_FAILURE({ // NOLINT - EXPECT_EXIT({ - testing::GTEST_FLAG(catch_exceptions) = false; - *static_cast(NULL) = 1; - }, testing::ExitedWithCode(0), "") << "This failure is expected."; - }, "This failure is expected."); -#endif // GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MINGW - #if GTEST_OS_WINDOWS // Of all signals effects on the process exit code, only those of SIGABRT // are documented on Windows. diff --git a/test/gtest-filepath_test.cc b/test/gtest-filepath_test.cc index 5bc4daf2..5706c8e1 100644 --- a/test/gtest-filepath_test.cc +++ b/test/gtest-filepath_test.cc @@ -151,6 +151,36 @@ TEST(RemoveDirectoryNameTest, ShouldAlsoGiveFileName) { .RemoveDirectoryName().c_str()); } +#if GTEST_HAS_ALT_PATH_SEP_ + +// Test RemoveDirectory* functions with "/". + +// RemoveDirectoryName "/afile" -> "afile" +TEST(RemoveDirectoryNameTest, RootFileShouldGiveFileNameForAlternateSeparator) { + EXPECT_STREQ("afile", + FilePath("/afile").RemoveDirectoryName().c_str()); +} + +// RemoveDirectoryName "adir/" -> "" +TEST(RemoveDirectoryNameTest, WhereThereIsNoFileNameForAlternateSeparator) { + EXPECT_STREQ("", + FilePath("adir/").RemoveDirectoryName().c_str()); +} + +// RemoveDirectoryName "adir/afile" -> "afile" +TEST(RemoveDirectoryNameTest, ShouldGiveFileNameForAlternateSeparator) { + EXPECT_STREQ("afile", + FilePath("adir/afile").RemoveDirectoryName().c_str()); +} + +// RemoveDirectoryName "adir/subdir/afile" -> "afile" +TEST(RemoveDirectoryNameTest, ShouldAlsoGiveFileNameForAlternateSeparator) { + EXPECT_STREQ("afile", + FilePath("adir/subdir/afile") + .RemoveDirectoryName().c_str()); +} + +#endif // RemoveFileName "" -> "./" TEST(RemoveFileNameTest, EmptyName) { @@ -190,6 +220,37 @@ TEST(RemoveFileNameTest, GivesRootDir) { FilePath(GTEST_PATH_SEP_ "afile").RemoveFileName().c_str()); } +#if GTEST_HAS_ALT_PATH_SEP_ + +// Test RemoveFile* functions with "/". + +// RemoveFileName "adir/" -> "adir/" +TEST(RemoveFileNameTest, ButNoFileForAlternateSeparator) { + EXPECT_STREQ("adir" GTEST_PATH_SEP_, + FilePath("adir/").RemoveFileName().c_str()); +} + +// RemoveFileName "adir/afile" -> "adir/" +TEST(RemoveFileNameTest, GivesDirNameForAlternateSeparator) { + EXPECT_STREQ("adir" GTEST_PATH_SEP_, + FilePath("adir/afile") + .RemoveFileName().c_str()); +} + +// RemoveFileName "adir/subdir/afile" -> "adir/subdir/" +TEST(RemoveFileNameTest, GivesDirAndSubDirNameForAlternateSeparator) { + EXPECT_STREQ("adir" GTEST_PATH_SEP_ "subdir" GTEST_PATH_SEP_, + FilePath("adir/subdir/afile") + .RemoveFileName().c_str()); +} + +// RemoveFileName "/afile" -> "\" +TEST(RemoveFileNameTest, GivesRootDirForAlternateSeparator) { + EXPECT_STREQ(GTEST_PATH_SEP_, + FilePath("/afile").RemoveFileName().c_str()); +} + +#endif TEST(MakeFileNameTest, GenerateWhenNumberIsZero) { FilePath actual = FilePath::MakeFileName(FilePath("foo"), FilePath("bar"), @@ -295,6 +356,11 @@ TEST(RemoveTrailingPathSeparatorTest, ShouldRemoveTrailingSeparator) { EXPECT_STREQ( "foo", FilePath("foo" GTEST_PATH_SEP_).RemoveTrailingPathSeparator().c_str()); +#if GTEST_HAS_ALT_PATH_SEP_ + EXPECT_STREQ( + "foo", + FilePath("foo/").RemoveTrailingPathSeparator().c_str()); +#endif } // RemoveTrailingPathSeparator "foo/bar/" -> "foo/bar/" @@ -397,6 +463,20 @@ TEST(NormalizeTest, MultipleConsecutiveSepaparatorsAtStringEnd) { FilePath("foo" GTEST_PATH_SEP_ GTEST_PATH_SEP_ GTEST_PATH_SEP_).c_str()); } +#if GTEST_HAS_ALT_PATH_SEP_ + +// "foo\" =="foo/\" == "foo\\/" +TEST(NormalizeTest, MixAlternateSeparatorAtStringEnd) { + EXPECT_STREQ("foo" GTEST_PATH_SEP_, + FilePath("foo/").c_str()); + EXPECT_STREQ("foo" GTEST_PATH_SEP_, + FilePath("foo" GTEST_PATH_SEP_ "/").c_str()); + EXPECT_STREQ("foo" GTEST_PATH_SEP_, + FilePath("foo//" GTEST_PATH_SEP_).c_str()); +} + +#endif + TEST(AssignmentOperatorTest, DefaultAssignedToNonDefault) { FilePath default_path; FilePath non_default_path("path"); @@ -566,6 +646,9 @@ TEST(FilePathTest, RemoveExtensionWhenThereIsNoExtension) { TEST(FilePathTest, IsDirectory) { EXPECT_FALSE(FilePath("cola").IsDirectory()); EXPECT_TRUE(FilePath("koala" GTEST_PATH_SEP_).IsDirectory()); +#if GTEST_HAS_ALT_PATH_SEP_ + EXPECT_TRUE(FilePath("koala/").IsDirectory()); +#endif } TEST(FilePathTest, IsAbsolutePath) { @@ -575,12 +658,32 @@ TEST(FilePathTest, IsAbsolutePath) { EXPECT_TRUE(FilePath("c:\\" GTEST_PATH_SEP_ "is_not" GTEST_PATH_SEP_ "relative").IsAbsolutePath()); EXPECT_FALSE(FilePath("c:foo" GTEST_PATH_SEP_ "bar").IsAbsolutePath()); + EXPECT_TRUE(FilePath("c:/" GTEST_PATH_SEP_ "is_not" + GTEST_PATH_SEP_ "relative").IsAbsolutePath()); #else EXPECT_TRUE(FilePath(GTEST_PATH_SEP_ "is_not" GTEST_PATH_SEP_ "relative") .IsAbsolutePath()); #endif // GTEST_OS_WINDOWS } +TEST(FilePathTest, IsRootDirectory) { +#if GTEST_OS_WINDOWS + EXPECT_TRUE(FilePath("a:\\").IsRootDirectory()); + EXPECT_TRUE(FilePath("Z:/").IsRootDirectory()); + EXPECT_TRUE(FilePath("e://").IsRootDirectory()); + EXPECT_FALSE(FilePath("").IsRootDirectory()); + EXPECT_FALSE(FilePath("b:").IsRootDirectory()); + EXPECT_FALSE(FilePath("b:a").IsRootDirectory()); + EXPECT_FALSE(FilePath("8:/").IsRootDirectory()); + EXPECT_FALSE(FilePath("c|/").IsRootDirectory()); +#else + EXPECT_TRUE(FilePath("/").IsRootDirectory()); + EXPECT_FALSE(FilePath("").IsRootDirectory()); + EXPECT_FALSE(FilePath("\\").IsRootDirectory()); + EXPECT_FALSE(FilePath("/x").IsRootDirectory()); +#endif +} + } // namespace } // namespace internal } // namespace testing diff --git a/test/gtest_break_on_failure_unittest_.cc b/test/gtest_break_on_failure_unittest_.cc index 10a1203b..d28d1d3d 100644 --- a/test/gtest_break_on_failure_unittest_.cc +++ b/test/gtest_break_on_failure_unittest_.cc @@ -43,6 +43,7 @@ #if GTEST_OS_WINDOWS #include +#include #endif namespace { @@ -52,6 +53,14 @@ TEST(Foo, Bar) { EXPECT_EQ(2, 3); } +#if GTEST_HAS_SEH && !GTEST_OS_WINDOWS_MOBILE +// On Windows Mobile global exception handlers are not supported. +LONG WINAPI ExitWithExceptionCode( + struct _EXCEPTION_POINTERS* exception_pointers) { + exit(exception_pointers->ExceptionRecord->ExceptionCode); +} +#endif + } // namespace int main(int argc, char **argv) { @@ -59,7 +68,18 @@ int main(int argc, char **argv) { // Suppresses display of the Windows error dialog upon encountering // a general protection fault (segment violation). SetErrorMode(SEM_NOGPFAULTERRORBOX | SEM_FAILCRITICALERRORS); + +#if !GTEST_OS_WINDOWS_MOBILE + // The default unhandled exception filter does not always exit + // with the exception code as exit code - for example it exits with + // 0 for EXCEPTION_ACCESS_VIOLATION and 1 for EXCEPTION_BREAKPOINT + // if the application is compiled in debug mode. Thus we use our own + // filter which always exits with the exception code for unhandled + // exceptions. + SetUnhandledExceptionFilter(ExitWithExceptionCode); +#endif #endif + testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); -- cgit v1.2.3 From cfcbc298cd91806e0e3417e03fce42bc4f1fa150 Mon Sep 17 00:00:00 2001 From: vladlosev Date: Wed, 3 Feb 2010 02:27:02 +0000 Subject: Adds Solaris support (by Hady Zalek) --- test/gtest-filepath_test.cc | 51 +++++++++++++++++++++++---------------------- test/gtest_unittest.cc | 39 +++++++++++++++++++++++++--------- 2 files changed, 55 insertions(+), 35 deletions(-) (limited to 'test') diff --git a/test/gtest-filepath_test.cc b/test/gtest-filepath_test.cc index 5706c8e1..c5f58f42 100644 --- a/test/gtest-filepath_test.cc +++ b/test/gtest-filepath_test.cc @@ -153,31 +153,31 @@ TEST(RemoveDirectoryNameTest, ShouldAlsoGiveFileName) { #if GTEST_HAS_ALT_PATH_SEP_ -// Test RemoveDirectory* functions with "/". +// Tests that RemoveDirectoryName() works with the alternate separator +// on Windows. -// RemoveDirectoryName "/afile" -> "afile" +// RemoveDirectoryName("/afile") -> "afile" TEST(RemoveDirectoryNameTest, RootFileShouldGiveFileNameForAlternateSeparator) { EXPECT_STREQ("afile", - FilePath("/afile").RemoveDirectoryName().c_str()); + FilePath("/afile").RemoveDirectoryName().c_str()); } -// RemoveDirectoryName "adir/" -> "" +// RemoveDirectoryName("adir/") -> "" TEST(RemoveDirectoryNameTest, WhereThereIsNoFileNameForAlternateSeparator) { EXPECT_STREQ("", - FilePath("adir/").RemoveDirectoryName().c_str()); + FilePath("adir/").RemoveDirectoryName().c_str()); } -// RemoveDirectoryName "adir/afile" -> "afile" +// RemoveDirectoryName("adir/afile") -> "afile" TEST(RemoveDirectoryNameTest, ShouldGiveFileNameForAlternateSeparator) { EXPECT_STREQ("afile", - FilePath("adir/afile").RemoveDirectoryName().c_str()); + FilePath("adir/afile").RemoveDirectoryName().c_str()); } -// RemoveDirectoryName "adir/subdir/afile" -> "afile" +// RemoveDirectoryName("adir/subdir/afile") -> "afile" TEST(RemoveDirectoryNameTest, ShouldAlsoGiveFileNameForAlternateSeparator) { EXPECT_STREQ("afile", - FilePath("adir/subdir/afile") - .RemoveDirectoryName().c_str()); + FilePath("adir/subdir/afile").RemoveDirectoryName().c_str()); } #endif @@ -222,32 +222,31 @@ TEST(RemoveFileNameTest, GivesRootDir) { #if GTEST_HAS_ALT_PATH_SEP_ -// Test RemoveFile* functions with "/". +// Tests that RemoveFileName() works with the alternate separator on +// Windows. -// RemoveFileName "adir/" -> "adir/" +// RemoveFileName("adir/") -> "adir/" TEST(RemoveFileNameTest, ButNoFileForAlternateSeparator) { EXPECT_STREQ("adir" GTEST_PATH_SEP_, - FilePath("adir/").RemoveFileName().c_str()); + FilePath("adir/").RemoveFileName().c_str()); } -// RemoveFileName "adir/afile" -> "adir/" +// RemoveFileName("adir/afile") -> "adir/" TEST(RemoveFileNameTest, GivesDirNameForAlternateSeparator) { EXPECT_STREQ("adir" GTEST_PATH_SEP_, - FilePath("adir/afile") - .RemoveFileName().c_str()); + FilePath("adir/afile").RemoveFileName().c_str()); } -// RemoveFileName "adir/subdir/afile" -> "adir/subdir/" +// RemoveFileName("adir/subdir/afile") -> "adir/subdir/" TEST(RemoveFileNameTest, GivesDirAndSubDirNameForAlternateSeparator) { EXPECT_STREQ("adir" GTEST_PATH_SEP_ "subdir" GTEST_PATH_SEP_, - FilePath("adir/subdir/afile") - .RemoveFileName().c_str()); + FilePath("adir/subdir/afile").RemoveFileName().c_str()); } -// RemoveFileName "/afile" -> "\" +// RemoveFileName("/afile") -> "\" TEST(RemoveFileNameTest, GivesRootDirForAlternateSeparator) { EXPECT_STREQ(GTEST_PATH_SEP_, - FilePath("/afile").RemoveFileName().c_str()); + FilePath("/afile").RemoveFileName().c_str()); } #endif @@ -357,9 +356,8 @@ TEST(RemoveTrailingPathSeparatorTest, ShouldRemoveTrailingSeparator) { "foo", FilePath("foo" GTEST_PATH_SEP_).RemoveTrailingPathSeparator().c_str()); #if GTEST_HAS_ALT_PATH_SEP_ - EXPECT_STREQ( - "foo", - FilePath("foo/").RemoveTrailingPathSeparator().c_str()); + EXPECT_STREQ("foo", + FilePath("foo/").RemoveTrailingPathSeparator().c_str()); #endif } @@ -465,7 +463,9 @@ TEST(NormalizeTest, MultipleConsecutiveSepaparatorsAtStringEnd) { #if GTEST_HAS_ALT_PATH_SEP_ -// "foo\" =="foo/\" == "foo\\/" +// Tests that separators at the end of the string are normalized +// regardless of their combination (e.g. "foo\" =="foo/\" == +// "foo\\/"). TEST(NormalizeTest, MixAlternateSeparatorAtStringEnd) { EXPECT_STREQ("foo" GTEST_PATH_SEP_, FilePath("foo/").c_str()); @@ -678,6 +678,7 @@ TEST(FilePathTest, IsRootDirectory) { EXPECT_FALSE(FilePath("c|/").IsRootDirectory()); #else EXPECT_TRUE(FilePath("/").IsRootDirectory()); + EXPECT_TRUE(FilePath("//").IsRootDirectory()); EXPECT_FALSE(FilePath("").IsRootDirectory()); EXPECT_FALSE(FilePath("\\").IsRootDirectory()); EXPECT_FALSE(FilePath("/x").IsRootDirectory()); diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index a5934946..55313e36 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -74,9 +74,7 @@ TEST(CommandLineFlagsTest, CanBeAccessedInCodeOnceGTestHIsIncluded) { #include #endif // GTEST_HAS_PTHREAD -#ifdef __BORLANDC__ #include -#endif namespace testing { namespace internal { @@ -1388,12 +1386,16 @@ TEST(StringTest, CanBeAssignedSelf) { EXPECT_STREQ("hello", dest.c_str()); } +// Sun Studio < 12 incorrectly rejects this code due to an overloading +// ambiguity. +#if !(defined(__SUNPRO_CC) && __SUNPRO_CC < 0x590) // Tests streaming a String. TEST(StringTest, Streams) { EXPECT_EQ(StreamableToString(String()), "(null)"); EXPECT_EQ(StreamableToString(String("")), ""); EXPECT_EQ(StreamableToString(String("a\0b", 3)), "a\\0b"); } +#endif // Tests that String::Format() works. TEST(StringTest, FormatWorks) { @@ -2050,7 +2052,7 @@ static void SetEnv(const char* name, const char* value) { #if GTEST_OS_WINDOWS_MOBILE // Environment variables are not supported on Windows CE. return; -#elif defined(__BORLANDC__) +#elif defined(__BORLANDC__) || defined(__SunOS_5_8) || defined(__SunOS_5_9) // C++Builder's putenv only stores a pointer to its parameter; we have to // ensure that the string remains valid as long as it might be needed. // We use an std::map to do so. @@ -2063,7 +2065,11 @@ static void SetEnv(const char* name, const char* value) { prev_env = added_env[name]; } added_env[name] = new String((Message() << name << "=" << value).GetString()); - putenv(added_env[name]->c_str()); + + // The standard signature of putenv accepts a 'char*' argument. Other + // implementations, like C++Builder's, accept a 'const char*'. + // We cast away the 'const' since that would work for both variants. + putenv(const_cast(added_env[name]->c_str())); delete prev_env; #elif GTEST_OS_WINDOWS // If we are on Windows proper. _putenv((Message() << name << "=" << value).GetString().c_str()); @@ -3013,7 +3019,10 @@ TEST_F(FloatTest, AlmostZeros) { // In C++Builder, names within local classes (such as used by // EXPECT_FATAL_FAILURE) cannot be resolved against static members of the // scoping class. Use a static local alias as a workaround. - static const FloatTest::TestValues& v(this->values_); + // We use the assignment syntax since some compilers, like Sun Studio, + // don't allow initializing references using construction syntax + // (parentheses). + static const FloatTest::TestValues& v = this->values_; EXPECT_FLOAT_EQ(0.0, v.close_to_positive_zero); EXPECT_FLOAT_EQ(-0.0, v.close_to_negative_zero); @@ -3065,7 +3074,10 @@ TEST_F(FloatTest, NaN) { // In C++Builder, names within local classes (such as used by // EXPECT_FATAL_FAILURE) cannot be resolved against static members of the // scoping class. Use a static local alias as a workaround. - static const FloatTest::TestValues& v(this->values_); + // We use the assignment syntax since some compilers, like Sun Studio, + // don't allow initializing references using construction syntax + // (parentheses). + static const FloatTest::TestValues& v = this->values_; EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(v.nan1, v.nan1), "v.nan1"); @@ -3180,7 +3192,10 @@ TEST_F(DoubleTest, AlmostZeros) { // In C++Builder, names within local classes (such as used by // EXPECT_FATAL_FAILURE) cannot be resolved against static members of the // scoping class. Use a static local alias as a workaround. - static const DoubleTest::TestValues& v(this->values_); + // We use the assignment syntax since some compilers, like Sun Studio, + // don't allow initializing references using construction syntax + // (parentheses). + static const DoubleTest::TestValues& v = this->values_; EXPECT_DOUBLE_EQ(0.0, v.close_to_positive_zero); EXPECT_DOUBLE_EQ(-0.0, v.close_to_negative_zero); @@ -3230,7 +3245,10 @@ TEST_F(DoubleTest, NaN) { // In C++Builder, names within local classes (such as used by // EXPECT_FATAL_FAILURE) cannot be resolved against static members of the // scoping class. Use a static local alias as a workaround. - static const DoubleTest::TestValues& v(this->values_); + // We use the assignment syntax since some compilers, like Sun Studio, + // don't allow initializing references using construction syntax + // (parentheses). + static const DoubleTest::TestValues& v = this->values_; // Nokia's STLport crashes if we try to output infinity or NaN. EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(v.nan1, v.nan1), @@ -4015,7 +4033,8 @@ TEST(AssertionTest, ExpectWorksWithUncopyableObject) { // The version of gcc used in XCode 2.2 has a bug and doesn't allow // anonymous enums in assertions. Therefore the following test is not // done on Mac. -#if !GTEST_OS_MAC +// Sun Studio also rejects this code. +#if !GTEST_OS_MAC && !defined(__SUNPRO_CC) // Tests using assertions with anonymous enums. enum { @@ -4060,7 +4079,7 @@ TEST(AssertionTest, AnonymousEnum) { "Value of: CASE_B"); } -#endif // !GTEST_OS_MAC +#endif // !GTEST_OS_MAC && !defined(__SUNPRO_CC) #if GTEST_OS_WINDOWS -- cgit v1.2.3 From 6f50ccf32c31cb6e287cdfee149429ac3029bbdb Mon Sep 17 00:00:00 2001 From: vladlosev Date: Mon, 15 Feb 2010 21:31:41 +0000 Subject: Google Test's Python tests now pass on Solaris. --- test/gtest_break_on_failure_unittest.py | 11 +++--- test/gtest_env_var_test.py | 10 +++--- test/gtest_filter_unittest.py | 61 +++++++++++++++++++++++++-------- test/gtest_output_test.py | 46 +++++++++++++++++-------- test/gtest_shuffle_test.py | 14 +++----- test/gtest_test_utils.py | 50 +++++++++++++++++++++------ 6 files changed, 133 insertions(+), 59 deletions(-) (limited to 'test') diff --git a/test/gtest_break_on_failure_unittest.py b/test/gtest_break_on_failure_unittest.py index 218d3713..c8191833 100755 --- a/test/gtest_break_on_failure_unittest.py +++ b/test/gtest_break_on_failure_unittest.py @@ -69,21 +69,24 @@ EXE_PATH = gtest_test_utils.GetTestExecutablePath( # Utilities. +environ = os.environ.copy() + + def SetEnvVar(env_var, value): """Sets an environment variable to a given value; unsets it when the given value is None. """ if value is not None: - os.environ[env_var] = value - elif env_var in os.environ: - del os.environ[env_var] + environ[env_var] = value + elif env_var in environ: + del environ[env_var] def Run(command): """Runs a command; returns 1 if it was killed by a signal, or 0 otherwise.""" - p = gtest_test_utils.Subprocess(command) + p = gtest_test_utils.Subprocess(command, env=environ) if p.terminated_by_signal: return 1 else: diff --git a/test/gtest_env_var_test.py b/test/gtest_env_var_test.py index f8250d4c..bcc0bfd5 100755 --- a/test/gtest_env_var_test.py +++ b/test/gtest_env_var_test.py @@ -42,6 +42,8 @@ IS_LINUX = os.name == 'posix' and os.uname()[0] == 'Linux' COMMAND = gtest_test_utils.GetTestExecutablePath('gtest_env_var_test_') +environ = os.environ.copy() + def AssertEq(expected, actual): if expected != actual: @@ -54,9 +56,9 @@ def SetEnvVar(env_var, value): """Sets the env variable to 'value'; unsets it when 'value' is None.""" if value is not None: - os.environ[env_var] = value - elif env_var in os.environ: - del os.environ[env_var] + environ[env_var] = value + elif env_var in environ: + del environ[env_var] def GetFlag(flag): @@ -65,7 +67,7 @@ def GetFlag(flag): args = [COMMAND] if flag is not None: args += [flag] - return gtest_test_utils.Subprocess(args).output + return gtest_test_utils.Subprocess(args, env=environ).output def TestFlag(flag, test_val, default_val): diff --git a/test/gtest_filter_unittest.py b/test/gtest_filter_unittest.py index a94a5210..89171e06 100755 --- a/test/gtest_filter_unittest.py +++ b/test/gtest_filter_unittest.py @@ -45,11 +45,42 @@ __author__ = 'wan@google.com (Zhanyong Wan)' import os import re import sets +import sys + import gtest_test_utils # Constants. -IS_WINDOWS = os.name == 'nt' +# Checks if this platform can pass empty environment variables to child +# processes. We set an env variable to an empty string and invoke a python +# script in a subprocess to print whether the variable is STILL in +# os.environ. We then use 'eval' to parse the child's output so that an +# exception is thrown if the input is anything other than 'True' nor 'False'. +os.environ['EMPTY_VAR'] = '' +child = gtest_test_utils.Subprocess( + [sys.executable, '-c', 'import os; print \'EMPTY_VAR\' in os.environ']) +CAN_PASS_EMPTY_ENV = eval(child.output) + + +# Check if this platform can unset environment variables in child processes. +# We set an env variable to a non-empty string, unset it, and invoke +# a python script in a subprocess to print whether the variable +# is NO LONGER in os.environ. +# We use 'eval' to parse the child's output so that an exception +# is thrown if the input is neither 'True' nor 'False'. +os.environ['UNSET_VAR'] = 'X' +del os.environ['UNSET_VAR'] +child = gtest_test_utils.Subprocess( + [sys.executable, '-c', 'import os; print \'UNSET_VAR\' not in os.environ']) +CAN_UNSET_ENV = eval(child.output) + + +# Checks if we should test with an empty filter. This doesn't +# make sense on platforms that cannot pass empty env variables (Win32) +# and on platforms that cannot unset variables (since we cannot tell +# the difference between "" and NULL -- Borland and Solaris < 5.10) +CAN_TEST_EMPTY_FILTER = (CAN_PASS_EMPTY_ENV and CAN_UNSET_ENV) + # The environment variable for specifying the test filters. FILTER_ENV_VAR = 'GTEST_FILTER' @@ -119,26 +150,29 @@ param_tests_present = None # Utilities. +environ = os.environ.copy() + def SetEnvVar(env_var, value): """Sets the env variable to 'value'; unsets it when 'value' is None.""" if value is not None: - os.environ[env_var] = value - elif env_var in os.environ: - del os.environ[env_var] + environ[env_var] = value + elif env_var in environ: + del environ[env_var] def RunAndReturnOutput(args = None): """Runs the test program and returns its output.""" - return gtest_test_utils.Subprocess([COMMAND] + (args or [])).output + return gtest_test_utils.Subprocess([COMMAND] + (args or []), + env=environ).output def RunAndExtractTestList(args = None): """Runs the test program and returns its exit code and a list of tests run.""" - p = gtest_test_utils.Subprocess([COMMAND] + (args or [])) + p = gtest_test_utils.Subprocess([COMMAND] + (args or []), env=environ) tests_run = [] test_case = '' test = '' @@ -157,15 +191,12 @@ def RunAndExtractTestList(args = None): def InvokeWithModifiedEnv(extra_env, function, *args, **kwargs): """Runs the given function and arguments in a modified environment.""" try: - original_env = os.environ.copy() - os.environ.update(extra_env) + original_env = environ.copy() + environ.update(extra_env) return function(*args, **kwargs) finally: - for key in extra_env.iterkeys(): - if key in original_env: - os.environ[key] = original_env[key] - else: - del os.environ[key] + environ.clear() + environ.update(original_env) def RunWithSharding(total_shards, shard_index, command): @@ -223,7 +254,7 @@ class GTestFilterUnitTest(gtest_test_utils.TestCase): # we can still test the case when the variable is not supplied (i.e., # gtest_filter is None). # pylint: disable-msg=C6403 - if not IS_WINDOWS or gtest_filter != '': + if CAN_TEST_EMPTY_FILTER or gtest_filter != '': SetEnvVar(FILTER_ENV_VAR, gtest_filter) tests_run = RunAndExtractTestList()[0] SetEnvVar(FILTER_ENV_VAR, None) @@ -265,7 +296,7 @@ class GTestFilterUnitTest(gtest_test_utils.TestCase): # we can still test the case when the variable is not supplied (i.e., # gtest_filter is None). # pylint: disable-msg=C6403 - if not IS_WINDOWS or gtest_filter != '': + if CAN_TEST_EMPTY_FILTER or gtest_filter != '': SetEnvVar(FILTER_ENV_VAR, gtest_filter) partition = [] for i in range(0, total_shards): diff --git a/test/gtest_output_test.py b/test/gtest_output_test.py index 8d9a40b0..a0aa64fd 100755 --- a/test/gtest_output_test.py +++ b/test/gtest_output_test.py @@ -48,6 +48,7 @@ import gtest_test_utils # The flag for generating the golden file GENGOLDEN_FLAG = '--gengolden' +CATCH_EXCEPTIONS_ENV_VAR_NAME = 'GTEST_CATCH_EXCEPTIONS' IS_WINDOWS = os.name == 'nt' @@ -123,6 +124,20 @@ def RemoveTime(output): return re.sub(r'\(\d+ ms', '(? ms', output) +def RemoveTypeInfoDetails(test_output): + """Removes compiler-specific type info from Google Test program's output. + + Args: + test_output: the output of a Google Test program. + + Returns: + output with type information normalized to canonical form. + """ + + # some compilers output the name of type 'unsigned int' as 'unsigned' + return re.sub(r'unsigned int', 'unsigned', test_output) + + def RemoveTestCounts(output): """Removes test counts from a Google Test program's output.""" @@ -184,16 +199,9 @@ def GetShellCommandOutput(env_cmd): # Spawns cmd in a sub-process, and gets its standard I/O file objects. # Set and save the environment properly. - old_env_vars = dict(os.environ) - os.environ.update(env_cmd[0]) - p = gtest_test_utils.Subprocess(env_cmd[1]) - - # Changes made by os.environ.clear are not inheritable by child processes - # until Python 2.6. To produce inheritable changes we have to delete - # environment items with the del statement. - for key in os.environ.keys(): - del os.environ[key] - os.environ.update(old_env_vars) + environ = os.environ.copy() + environ.update(env_cmd[0]) + p = gtest_test_utils.Subprocess(env_cmd[1], env=environ) return p.output @@ -209,8 +217,10 @@ def GetCommandOutput(env_cmd): """ # Disables exception pop-ups on Windows. - os.environ['GTEST_CATCH_EXCEPTIONS'] = '1' - return NormalizeOutput(GetShellCommandOutput(env_cmd)) + environ, cmdline = env_cmd + environ = dict(environ) # Ensures we are modifying a copy. + environ[CATCH_EXCEPTIONS_ENV_VAR_NAME] = '1' + return NormalizeOutput(GetShellCommandOutput((environ, cmdline))) def GetOutputOfAllCommands(): @@ -262,11 +272,17 @@ class GTestOutputTest(gtest_test_utils.TestCase): # We want the test to pass regardless of certain features being # supported or not. + + # We still have to remove type name specifics in all cases. + normalized_actual = RemoveTypeInfoDetails(output) + normalized_golden = RemoveTypeInfoDetails(golden) + if CAN_GENERATE_GOLDEN_FILE: - self.assert_(golden == output) + self.assert_(normalized_golden == normalized_actual) else: - normalized_actual = RemoveTestCounts(output) - normalized_golden = RemoveTestCounts(self.RemoveUnsupportedTests(golden)) + normalized_actual = RemoveTestCounts(normalized_actual) + normalized_golden = RemoveTestCounts(self.RemoveUnsupportedTests( + normalized_golden)) # This code is very handy when debugging golden file differences: if os.getenv('DEBUG_GTEST_OUTPUT_TEST'): diff --git a/test/gtest_shuffle_test.py b/test/gtest_shuffle_test.py index a870a01b..30d0303d 100755 --- a/test/gtest_shuffle_test.py +++ b/test/gtest_shuffle_test.py @@ -78,16 +78,10 @@ def RandomSeedFlag(n): def RunAndReturnOutput(extra_env, args): """Runs the test program and returns its output.""" - try: - original_env = os.environ.copy() - os.environ.update(extra_env) - return gtest_test_utils.Subprocess([COMMAND] + args).output - finally: - for key in extra_env.iterkeys(): - if key in original_env: - os.environ[key] = original_env[key] - else: - del os.environ[key] + environ_copy = os.environ.copy() + environ_copy.update(extra_env) + + return gtest_test_utils.Subprocess([COMMAND] + args, env=environ_copy).output def GetTestsForAllIterations(extra_env, args): diff --git a/test/gtest_test_utils.py b/test/gtest_test_utils.py index 19b5b228..e0f5973e 100755 --- a/test/gtest_test_utils.py +++ b/test/gtest_test_utils.py @@ -194,23 +194,28 @@ def GetExitStatus(exit_code): class Subprocess: - def __init__(self, command, working_dir=None, capture_stderr=True): + def __init__(self, command, working_dir=None, capture_stderr=True, env=None): """Changes into a specified directory, if provided, and executes a command. - Restores the old directory afterwards. Execution results are returned - via the following attributes: - terminated_by_sygnal True iff the child process has been terminated - by a signal. - signal Sygnal that terminated the child process. - exited True iff the child process exited normally. - exit_code The code with which the child proces exited. - output Child process's stdout and stderr output - combined in a string. + + Restores the old directory afterwards. Args: command: The command to run, in the form of sys.argv. working_dir: The directory to change into. capture_stderr: Determines whether to capture stderr in the output member or to discard it. + env: Dictionary with environment to pass to the subprocess. + + Returns: + An object that represents outcome of the executed process. It has the + following attributes: + terminated_by_signal True iff the child process has been terminated + by a signal. + signal Sygnal that terminated the child process. + exited True iff the child process exited normally. + exit_code The code with which the child process exited. + output Child process's stdout and stderr output + combined in a string. """ # The subprocess module is the preferrable way of running programs @@ -228,13 +233,30 @@ class Subprocess: p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=stderr, - cwd=working_dir, universal_newlines=True) + cwd=working_dir, universal_newlines=True, env=env) # communicate returns a tuple with the file obect for the child's # output. self.output = p.communicate()[0] self._return_code = p.returncode else: old_dir = os.getcwd() + + def _ReplaceEnvDict(dest, src): + # Changes made by os.environ.clear are not inheritable by child + # processes until Python 2.6. To produce inheritable changes we have + # to delete environment items with the del statement. + for key in dest: + del dest[key] + dest.update(src) + + # When 'env' is not None, backup the environment variables and replace + # them with the passed 'env'. When 'env' is None, we simply use the + # current 'os.environ' for compatibility with the subprocess.Popen + # semantics used above. + if env is not None: + old_environ = os.environ.copy() + _ReplaceEnvDict(os.environ, env) + try: if working_dir is not None: os.chdir(working_dir) @@ -247,6 +269,12 @@ class Subprocess: ret_code = p.wait() finally: os.chdir(old_dir) + + # Restore the old environment variables + # if they were replaced. + if env is not None: + _ReplaceEnvDict(os.environ, old_environ) + # Converts ret_code to match the semantics of # subprocess.Popen.returncode. if os.WIFSIGNALED(ret_code): -- cgit v1.2.3 From dd280cfa8dff2247f71a1177d7c8f0c2fde9789a Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Wed, 17 Feb 2010 21:28:45 +0000 Subject: Fixes a C++ standard conformance bug in gtest-param-test_test.cc. --- test/gtest-param-test_test.cc | 106 +++++++++++++++++++++++++++--------------- 1 file changed, 69 insertions(+), 37 deletions(-) (limited to 'test') diff --git a/test/gtest-param-test_test.cc b/test/gtest-param-test_test.cc index e718ffb4..0288b6a7 100644 --- a/test/gtest-param-test_test.cc +++ b/test/gtest-param-test_test.cc @@ -40,6 +40,8 @@ #include #include #include +#include +#include #include // To include gtest-internal-inl.h. @@ -70,6 +72,57 @@ using ::std::tr1::tuple; using ::testing::internal::ParamGenerator; using ::testing::internal::UnitTestOptions; +// Prints a value to a string. +// +// TODO(wan@google.com): remove PrintValue() when we move matchers and +// EXPECT_THAT() from Google Mock to Google Test. At that time, we +// can write EXPECT_THAT(x, Eq(y)) to compare two tuples x and y, as +// EXPECT_THAT() and the matchers know how to print tuples. +template +::std::string PrintValue(const T& value) { + ::std::stringstream stream; + stream << value; + return stream.str(); +} + +#if GTEST_HAS_COMBINE + +// These overloads allow printing tuples in our tests. We cannot +// define an operator<< for tuples, as that definition needs to be in +// the std namespace in order to be picked up by Google Test via +// Argument-Dependent Lookup, yet defining anything in the std +// namespace in non-STL code is undefined behavior. + +template +::std::string PrintValue(const tuple& value) { + ::std::stringstream stream; + stream << "(" << get<0>(value) << ", " << get<1>(value) << ")"; + return stream.str(); +} + +template +::std::string PrintValue(const tuple& value) { + ::std::stringstream stream; + stream << "(" << get<0>(value) << ", " << get<1>(value) + << ", "<< get<2>(value) << ")"; + return stream.str(); +} + +template +::std::string PrintValue( + const tuple& value) { + ::std::stringstream stream; + stream << "(" << get<0>(value) << ", " << get<1>(value) + << ", "<< get<2>(value) << ", " << get<3>(value) + << ", "<< get<4>(value) << ", " << get<5>(value) + << ", "<< get<6>(value) << ", " << get<7>(value) + << ", "<< get<8>(value) << ", " << get<9>(value) << ")"; + return stream.str(); +} + +#endif // GTEST_HAS_COMBINE + // Verifies that a sequence generated by the generator and accessed // via the iterator object matches the expected one using Google Test // assertions. @@ -80,15 +133,19 @@ void VerifyGenerator(const ParamGenerator& generator, for (size_t i = 0; i < N; ++i) { ASSERT_FALSE(it == generator.end()) << "At element " << i << " when accessing via an iterator " - << "created with the copy constructor." << std::endl; - EXPECT_EQ(expected_values[i], *it) - << "At element " << i << " when accessing via an iterator " - << "created with the copy constructor." << std::endl; + << "created with the copy constructor.\n"; + // We cannot use EXPECT_EQ() here as the values may be tuples, + // which don't support <<. + EXPECT_TRUE(expected_values[i] == *it) + << "where i is " << i + << ", expected_values[i] is " << PrintValue(expected_values[i]) + << ", *it is " << PrintValue(*it) + << ", and 'it' is an iterator created with the copy constructor.\n"; it++; } EXPECT_TRUE(it == generator.end()) << "At the presumed end of sequence when accessing via an iterator " - << "created with the copy constructor." << std::endl; + << "created with the copy constructor.\n"; // Test the iterator assignment. The following lines verify that // the sequence accessed via an iterator initialized via the @@ -98,15 +155,17 @@ void VerifyGenerator(const ParamGenerator& generator, for (size_t i = 0; i < N; ++i) { ASSERT_FALSE(it == generator.end()) << "At element " << i << " when accessing via an iterator " - << "created with the assignment operator." << std::endl; - EXPECT_EQ(expected_values[i], *it) - << "At element " << i << " when accessing via an iterator " - << "created with the assignment operator." << std::endl; + << "created with the assignment operator.\n"; + EXPECT_TRUE(expected_values[i] == *it) + << "where i is " << i + << ", expected_values[i] is " << PrintValue(expected_values[i]) + << ", *it is " << PrintValue(*it) + << ", and 'it' is an iterator created with the copy constructor.\n"; it++; } EXPECT_TRUE(it == generator.end()) << "At the presumed end of sequence when accessing via an iterator " - << "created with the assignment operator." << std::endl; + << "created with the assignment operator.\n"; } template @@ -400,33 +459,6 @@ TEST(BoolTest, BoolWorks) { #if GTEST_HAS_COMBINE -template -::std::ostream& operator<<(::std::ostream& stream, const tuple& value) { - stream << "(" << get<0>(value) << ", " << get<1>(value) << ")"; - return stream; -} - -template -::std::ostream& operator<<(::std::ostream& stream, - const tuple& value) { - stream << "(" << get<0>(value) << ", " << get<1>(value) - << ", "<< get<2>(value) << ")"; - return stream; -} - -template -::std::ostream& operator<<( - ::std::ostream& stream, - const tuple& value) { - stream << "(" << get<0>(value) << ", " << get<1>(value) - << ", "<< get<2>(value) << ", " << get<3>(value) - << ", "<< get<4>(value) << ", " << get<5>(value) - << ", "<< get<6>(value) << ", " << get<7>(value) - << ", "<< get<8>(value) << ", " << get<9>(value) << ")"; - return stream; -} - // Tests that Combine() with two parameters generates the expected sequence. TEST(CombineTest, CombineWithTwoParameters) { const char* foo = "foo"; -- cgit v1.2.3 From 3bef459eac9aa84c579f34249aebc9ff56832054 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Wed, 24 Feb 2010 17:19:25 +0000 Subject: Adds threading support (by Miklos Fazekas, Vlad Losev, and Chandler Carruth); adds wide InitGoogleTest to gtest.def (by Vlad Losev); updates the version number (by Zhanyong Wan); updates the release notes for 1.5.0 (by Vlad Losev); removes scons scripts from the distribution (by Zhanyong Wan); adds the cmake build script to the distribution (by Zhanyong Wan); adds fused source files to the distribution (by Vlad Losev and Chandler Carruth). --- test/gtest-death-test_test.cc | 4 +- test/gtest-port_test.cc | 223 +++++++++++++++++++++++++++++++++- test/gtest_dll_test_.cc | 5 + test/gtest_output_test.py | 8 +- test/gtest_output_test_golden_lin.txt | 40 +++++- test/gtest_stress_test.cc | 44 +++---- test/gtest_unittest.cc | 18 --- 7 files changed, 285 insertions(+), 57 deletions(-) (limited to 'test') diff --git a/test/gtest-death-test_test.cc b/test/gtest-death-test_test.cc index 1c7fa474..127b7ffc 100644 --- a/test/gtest-death-test_test.cc +++ b/test/gtest-death-test_test.cc @@ -410,7 +410,7 @@ void SetPthreadFlag() { } // namespace -#if GTEST_HAS_CLONE +#if GTEST_HAS_CLONE && GTEST_HAS_PTHREAD TEST_F(TestForDeathTest, DoesNotExecuteAtforkHooks) { if (!testing::GTEST_FLAG(death_test_use_fork)) { @@ -422,7 +422,7 @@ TEST_F(TestForDeathTest, DoesNotExecuteAtforkHooks) { } } -#endif // GTEST_HAS_CLONE +#endif // GTEST_HAS_CLONE && GTEST_HAS_PTHREAD // Tests that a method of another class can be used in a death test. TEST_F(TestForDeathTest, MethodOfAnotherClass) { diff --git a/test/gtest-port_test.cc b/test/gtest-port_test.cc index 3576c2b8..8594aa97 100644 --- a/test/gtest-port_test.cc +++ b/test/gtest-port_test.cc @@ -35,11 +35,16 @@ #include +#if GTEST_HAS_PTHREAD +#include // For nanosleep(). +#endif // GTEST_HAS_PTHREAD + #if GTEST_OS_MAC -#include #include #endif // GTEST_OS_MAC +#include // For std::pair and std::make_pair. + #include #include @@ -52,6 +57,9 @@ #include "src/gtest-internal-inl.h" #undef GTEST_IMPLEMENTATION_ +using std::make_pair; +using std::pair; + namespace testing { namespace internal { @@ -94,7 +102,7 @@ TEST(GtestCheckSyntaxTest, WorksWithSwitch) { #if GTEST_OS_MAC void* ThreadFunc(void* data) { - pthread_mutex_t* mutex = reinterpret_cast(data); + pthread_mutex_t* mutex = static_cast(data); pthread_mutex_lock(mutex); pthread_mutex_unlock(mutex); return NULL; @@ -745,5 +753,216 @@ TEST(CaptureDeathTest, CannotReenterStdoutCapture) { #endif // !GTEST_OS_WINDOWS_MOBILE +TEST(ThreadLocalTest, DefaultConstructorInitializesToDefaultValues) { + ThreadLocal t1; + EXPECT_EQ(0, t1.get()); + + ThreadLocal t2; + EXPECT_TRUE(t2.get() == NULL); +} + +TEST(ThreadLocalTest, SingleParamConstructorInitializesToParam) { + ThreadLocal t1(123); + EXPECT_EQ(123, t1.get()); + + int i = 0; + ThreadLocal t2(&i); + EXPECT_EQ(&i, t2.get()); +} + +class NoCopyConstructor { + public: + NoCopyConstructor() {} + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(NoCopyConstructor); +}; + +TEST(ThreadLocalTest, ValueCopyConstructorIsNotRequiredForDefaultVersion) { + ThreadLocal bar; + bar.get(); +} + +class NoDefaultContructor { + public: + explicit NoDefaultContructor(const char*) {} + NoDefaultContructor(const NoDefaultContructor&) {} +}; + +TEST(ThreadLocalTest, ValueDefaultContructorIsNotRequiredForParamVersion) { + ThreadLocal bar(NoDefaultContructor("foo")); + bar.pointer(); +} + +TEST(ThreadLocalTest, GetAndPointerReturnSameValue) { + ThreadLocal thread_local; + + // This is why EXPECT_TRUE is used here rather than EXPECT_EQ because + // we don't care about a particular value of thread_local.pointer() here; + // we only care about pointer and reference referring to the same lvalue. + EXPECT_EQ(thread_local.pointer(), &(thread_local.get())); + + // Verifies the condition still holds after calling set. + thread_local.set("foo"); + EXPECT_EQ(thread_local.pointer(), &(thread_local.get())); +} + +TEST(ThreadLocalTest, PointerAndConstPointerReturnSameValue) { + ThreadLocal thread_local; + const ThreadLocal& const_thread_local = thread_local; + + EXPECT_EQ(thread_local.pointer(), const_thread_local.pointer()); + + thread_local.set("foo"); + EXPECT_EQ(thread_local.pointer(), const_thread_local.pointer()); +} + +#if GTEST_IS_THREADSAFE +TEST(MutexTestDeathTest, AssertHeldShouldAssertWhenNotLocked) { + // AssertHeld() is flaky only in the presence of multiple threads accessing + // the lock. In this case, the test is robust. + EXPECT_DEATH_IF_SUPPORTED({ + Mutex m; + { MutexLock lock(&m); } + m.AssertHeld(); + }, + "Current thread is not holding mutex..+"); +} + +void SleepMilliseconds(int time) { + usleep(static_cast(time * 1000.0)); +} + +class AtomicCounterWithMutex { + public: + explicit AtomicCounterWithMutex(Mutex* mutex) : + value_(0), mutex_(mutex), random_(42) {} + + void Increment() { + MutexLock lock(mutex_); + int temp = value_; + { + // Locking a mutex puts up a memory barrier, preventing reads and + // writes to value_ rearranged when observed from other threads. + // + // We cannot use Mutex and MutexLock here or rely on their memory + // barrier functionality as we are testing them here. + pthread_mutex_t memory_barrier_mutex; + int err = pthread_mutex_init(&memory_barrier_mutex, NULL); + GTEST_CHECK_(err == 0) << "pthread_mutex_init failed with error " << err; + err = pthread_mutex_lock(&memory_barrier_mutex); + GTEST_CHECK_(err == 0) << "pthread_mutex_lock failed with error " << err; + + SleepMilliseconds(random_.Generate(30)); + + err = pthread_mutex_unlock(&memory_barrier_mutex); + GTEST_CHECK_(err == 0) + << "pthread_mutex_unlock failed with error " << err; + } + value_ = temp + 1; + } + int value() const { return value_; } + + private: + volatile int value_; + Mutex* const mutex_; // Protects value_. + Random random_; +}; + +void CountingThreadFunc(pair param) { + for (int i = 0; i < param.second; ++i) + param.first->Increment(); +} + +// Tests that the mutex only lets one thread at a time to lock it. +TEST(MutexTest, OnlyOneThreadCanLockAtATime) { + Mutex mutex; + AtomicCounterWithMutex locked_counter(&mutex); + + typedef ThreadWithParam > ThreadType; + const int kCycleCount = 20; + const int kThreadCount = 7; + scoped_ptr counting_threads[kThreadCount]; + ThreadStartSemaphore semaphore; + // Creates and runs kThreadCount threads that increment locked_counter + // kCycleCount times each. + for (int i = 0; i < kThreadCount; ++i) { + counting_threads[i].reset(new ThreadType(&CountingThreadFunc, + make_pair(&locked_counter, + kCycleCount), + &semaphore)); + } + semaphore.Signal(); // Start the threads. + for (int i = 0; i < kThreadCount; ++i) + counting_threads[i]->Join(); + + // If the mutex lets more than one thread to increment the counter at a + // time, they are likely to encounter a race condition and have some + // increments overwritten, resulting in the lower then expected counter + // value. + EXPECT_EQ(kCycleCount * kThreadCount, locked_counter.value()); +} + +template +void RunFromThread(void (func)(T), T param) { + ThreadWithParam thread(func, param, NULL); + thread.Join(); +} + +void RetrieveThreadLocalValue(pair*, String*> param) { + *param.second = param.first->get(); +} + +TEST(ThreadLocalTest, ParameterizedConstructorSetsDefault) { + ThreadLocal thread_local("foo"); + EXPECT_STREQ("foo", thread_local.get().c_str()); + + thread_local.set("bar"); + EXPECT_STREQ("bar", thread_local.get().c_str()); + + String result; + RunFromThread(&RetrieveThreadLocalValue, make_pair(&thread_local, &result)); + EXPECT_STREQ("foo", result.c_str()); +} + +class CountedDestructor { + public: + ~CountedDestructor() { counter_++; } + static int counter() { return counter_; } + static void set_counter(int value) { counter_ = value; } + + private: + static int counter_; +}; +int CountedDestructor::counter_ = 0; + +template +void CallThreadLocalGet(ThreadLocal* threadLocal) { + threadLocal->get(); +} + +TEST(ThreadLocalTest, DestroysManagedObjectsNoLaterThanSelf) { + CountedDestructor::set_counter(0); + { + ThreadLocal thread_local; + ThreadWithParam*> thread( + &CallThreadLocalGet, &thread_local, NULL); + thread.Join(); + } + // There should be 2 desctuctor calls as ThreadLocal also contains a member + // T - used as a prototype for copy ctr version. + EXPECT_EQ(2, CountedDestructor::counter()); +} + +TEST(ThreadLocalTest, ThreadLocalMutationsAffectOnlyCurrentThread) { + ThreadLocal thread_local; + thread_local.set("Foo"); + EXPECT_STREQ("Foo", thread_local.get().c_str()); + + String result; + RunFromThread(&RetrieveThreadLocalValue, make_pair(&thread_local, &result)); + EXPECT_TRUE(result.c_str() == NULL); +} +#endif // GTEST_IS_THREADSAFE + } // namespace internal } // namespace testing diff --git a/test/gtest_dll_test_.cc b/test/gtest_dll_test_.cc index c99358aa..3fb61812 100644 --- a/test/gtest_dll_test_.cc +++ b/test/gtest_dll_test_.cc @@ -484,6 +484,11 @@ class MyOtherListener : public EmptyTestEventListener {}; int main(int argc, char **argv) { testing::InitGoogleTest(&argc, argv); + void (*wide_init_google_test)(int*, wchar_t**) = &testing::InitGoogleTest; + + // Ensures the linker doesn't throw away reference to wide InitGoogleTest. + GTEST_CHECK_(wide_init_google_test != NULL); + TestEventListeners& listeners = UnitTest::GetInstance()->listeners(); TestEventListener* listener = new MyListener; diff --git a/test/gtest_output_test.py b/test/gtest_output_test.py index a0aa64fd..4374a96e 100755 --- a/test/gtest_output_test.py +++ b/test/gtest_output_test.py @@ -238,7 +238,9 @@ SUPPORTS_TYPED_TESTS = 'TypedTest' in test_list SUPPORTS_THREADS = 'ExpectFailureWithThreadsTest' in test_list SUPPORTS_STACK_TRACES = False -CAN_GENERATE_GOLDEN_FILE = SUPPORTS_DEATH_TESTS and SUPPORTS_TYPED_TESTS +CAN_GENERATE_GOLDEN_FILE = (SUPPORTS_DEATH_TESTS and + SUPPORTS_TYPED_TESTS and + SUPPORTS_THREADS) class GTestOutputTest(gtest_test_utils.TestCase): @@ -314,8 +316,8 @@ that does not support all the required features (death tests""") """\nand typed tests). Please check that you are using VC++ 8.0 SP1 or higher as your compiler.""") else: - message += """\nand typed tests). Please generate the golden file -using a binary built with those features enabled.""" + message += """\ntyped tests, and threads). Please generate the +golden file using a binary built with those features enabled.""" sys.stderr.write(message) sys.exit(1) diff --git a/test/gtest_output_test_golden_lin.txt b/test/gtest_output_test_golden_lin.txt index 51bae52d..4d67bd62 100644 --- a/test/gtest_output_test_golden_lin.txt +++ b/test/gtest_output_test_golden_lin.txt @@ -7,7 +7,7 @@ Expected: true gtest_output_test_.cc:#: Failure Value of: 3 Expected: 2 -[==========] Running 56 tests from 23 test cases. +[==========] Running 59 tests from 25 test cases. [----------] Global test environment set-up. FooEnvironment::SetUp() called. BarEnvironment::SetUp() called. @@ -506,6 +506,35 @@ Failed Expected non-fatal failure. [ FAILED ] ExpectFailureTest.ExpectNonFatalFailureOnAllThreads +[----------] 2 tests from ExpectFailureWithThreadsTest +[ RUN ] ExpectFailureWithThreadsTest.ExpectFatalFailure +(expecting 2 failures) +gtest_output_test_.cc:#: Failure +Failed +Expected fatal failure. +gtest.cc:#: Failure +Expected: 1 fatal failure + Actual: 0 failures +[ FAILED ] ExpectFailureWithThreadsTest.ExpectFatalFailure +[ RUN ] ExpectFailureWithThreadsTest.ExpectNonFatalFailure +(expecting 2 failures) +gtest_output_test_.cc:#: Failure +Failed +Expected non-fatal failure. +gtest.cc:#: Failure +Expected: 1 non-fatal failure + Actual: 0 failures +[ FAILED ] ExpectFailureWithThreadsTest.ExpectNonFatalFailure +[----------] 1 test from ScopedFakeTestPartResultReporterTest +[ RUN ] ScopedFakeTestPartResultReporterTest.InterceptOnlyCurrentThread +(expecting 2 failures) +gtest_output_test_.cc:#: Failure +Failed +Expected fatal failure. +gtest_output_test_.cc:#: Failure +Failed +Expected non-fatal failure. +[ FAILED ] ScopedFakeTestPartResultReporterTest.InterceptOnlyCurrentThread [----------] Global test environment tear-down BarEnvironment::TearDown() called. gtest_output_test_.cc:#: Failure @@ -515,9 +544,9 @@ FooEnvironment::TearDown() called. gtest_output_test_.cc:#: Failure Failed Expected fatal failure. -[==========] 56 tests from 23 test cases ran. +[==========] 59 tests from 25 test cases ran. [ PASSED ] 21 tests. -[ FAILED ] 35 tests, listed below: +[ FAILED ] 38 tests, listed below: [ FAILED ] FatalFailureTest.FatalFailureInSubroutine [ FAILED ] FatalFailureTest.FatalFailureInNestedSubroutine [ FAILED ] FatalFailureTest.NonfatalFailureInSubroutine @@ -553,8 +582,11 @@ Expected fatal failure. [ FAILED ] ExpectFailureTest.ExpectNonFatalFailure [ FAILED ] ExpectFailureTest.ExpectFatalFailureOnAllThreads [ FAILED ] ExpectFailureTest.ExpectNonFatalFailureOnAllThreads +[ FAILED ] ExpectFailureWithThreadsTest.ExpectFatalFailure +[ FAILED ] ExpectFailureWithThreadsTest.ExpectNonFatalFailure +[ FAILED ] ScopedFakeTestPartResultReporterTest.InterceptOnlyCurrentThread -35 FAILED TESTS +38 FAILED TESTS  YOU HAVE 1 DISABLED TEST Note: Google Test filter = FatalFailureTest.*:LoggingTest.* diff --git a/test/gtest_stress_test.cc b/test/gtest_stress_test.cc index 75d6268e..3cb68de8 100644 --- a/test/gtest_stress_test.cc +++ b/test/gtest_stress_test.cc @@ -48,23 +48,17 @@ namespace testing { namespace { +using internal::scoped_ptr; using internal::String; using internal::TestPropertyKeyIs; using internal::Vector; +using internal::ThreadStartSemaphore; +using internal::ThreadWithParam; // In order to run tests in this file, for platforms where Google Test is -// thread safe, implement ThreadWithParam with the following interface: -// -// template class ThreadWithParam { -// public: -// // Creates the thread. The thread should execute thread_func(param) when -// // started by a call to Start(). -// ThreadWithParam(void (*thread_func)(T), T param); -// // Starts the thread. -// void Start(); -// // Waits for the thread to finish. -// void Join(); -// }; +// thread safe, implement ThreadWithParam and ThreadStartSemaphore. See the +// description of their API in gtest-port.h, where they are defined for +// already supported platforms. // How many threads to create? const int kThreadCount = 50; @@ -132,22 +126,17 @@ void CheckTestFailureCount(int expected_failures) { // Tests using SCOPED_TRACE() and Google Test assertions in many threads // concurrently. TEST(StressTest, CanUseScopedTraceAndAssertionsInManyThreads) { - ThreadWithParam* threads[kThreadCount] = {}; - for (int i = 0; i != kThreadCount; i++) { - // Creates a thread to run the ManyAsserts() function. - threads[i] = new ThreadWithParam(&ManyAsserts, i); - - // Starts the thread. - threads[i]->Start(); - } + { + scoped_ptr > threads[kThreadCount]; + ThreadStartSemaphore semaphore; + for (int i = 0; i != kThreadCount; i++) + threads[i].reset(new ThreadWithParam(&ManyAsserts, i, &semaphore)); - // At this point, we have many threads running. + semaphore.Signal(); // Starts all the threads. - for (int i = 0; i != kThreadCount; i++) { - // We block until the thread is done. - threads[i]->Join(); - delete threads[i]; - threads[i] = NULL; + // Blocks until all the threads are done. + for (int i = 0; i != kThreadCount; i++) + threads[i]->Join(); } // Ensures that kThreadCount*kThreadCount failures have been reported. @@ -180,8 +169,7 @@ void FailingThread(bool is_fatal) { } void GenerateFatalFailureInAnotherThread(bool is_fatal) { - ThreadWithParam thread(&FailingThread, is_fatal); - thread.Start(); + ThreadWithParam thread(&FailingThread, is_fatal, NULL); thread.Join(); } diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index 55313e36..071301ea 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -174,7 +174,6 @@ using testing::internal::StreamableToString; using testing::internal::String; using testing::internal::TestEventListenersAccessor; using testing::internal::TestResultAccessor; -using testing::internal::ThreadLocal; using testing::internal::UInt32; using testing::internal::Vector; using testing::internal::WideStringToUtf8; @@ -6577,23 +6576,6 @@ TEST(StaticAssertTypeEqTest, CompilesForEqualTypes) { StaticAssertTypeEq(); } -TEST(ThreadLocalTest, DefaultConstructor) { - ThreadLocal t1; - EXPECT_EQ(0, t1.get()); - - ThreadLocal t2; - EXPECT_TRUE(t2.get() == NULL); -} - -TEST(ThreadLocalTest, Init) { - ThreadLocal t1(123); - EXPECT_EQ(123, t1.get()); - - int i = 0; - ThreadLocal t2(&i); - EXPECT_EQ(&i, t2.get()); -} - TEST(GetCurrentOsStackTraceExceptTopTest, ReturnsTheStackTrace) { testing::UnitTest* const unit_test = testing::UnitTest::GetInstance(); -- cgit v1.2.3 From 0d27868d0faef474594682f25336229daa89d6d7 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Thu, 25 Feb 2010 01:09:07 +0000 Subject: Simplifies the implementation by using std::vector instead of Vector. --- test/gtest-listener_test.cc | 63 +++--- test/gtest_stress_test.cc | 17 +- test/gtest_unittest.cc | 505 +++++++++++--------------------------------- 3 files changed, 155 insertions(+), 430 deletions(-) (limited to 'test') diff --git a/test/gtest-listener_test.cc b/test/gtest-listener_test.cc index f12f5188..c9be39a8 100644 --- a/test/gtest-listener_test.cc +++ b/test/gtest-listener_test.cc @@ -34,15 +34,7 @@ // right times. #include - -// Indicates that this translation unit is part of Google Test's -// implementation. It must come before gtest-internal-inl.h is -// included, or there will be a compiler error. This trick is to -// prevent a user from accidentally including gtest-internal-inl.h in -// his code. -#define GTEST_IMPLEMENTATION_ 1 -#include "src/gtest-internal-inl.h" // For Vector. -#undef GTEST_IMPLEMENTATION_ +#include using ::testing::AddGlobalTestEnvironment; using ::testing::Environment; @@ -54,10 +46,9 @@ using ::testing::TestInfo; using ::testing::TestPartResult; using ::testing::UnitTest; using ::testing::internal::String; -using ::testing::internal::Vector; // Used by tests to register their events. -Vector* g_events = NULL; +std::vector* g_events = NULL; namespace testing { namespace internal { @@ -68,7 +59,7 @@ class EventRecordingListener : public TestEventListener { protected: virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) { - g_events->PushBack(GetFullMethodName("OnTestProgramStart")); + g_events->push_back(GetFullMethodName("OnTestProgramStart")); } virtual void OnTestIterationStart(const UnitTest& /*unit_test*/, @@ -76,43 +67,43 @@ class EventRecordingListener : public TestEventListener { Message message; message << GetFullMethodName("OnTestIterationStart") << "(" << iteration << ")"; - g_events->PushBack(message.GetString()); + g_events->push_back(message.GetString()); } virtual void OnEnvironmentsSetUpStart(const UnitTest& /*unit_test*/) { - g_events->PushBack(GetFullMethodName("OnEnvironmentsSetUpStart")); + g_events->push_back(GetFullMethodName("OnEnvironmentsSetUpStart")); } virtual void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) { - g_events->PushBack(GetFullMethodName("OnEnvironmentsSetUpEnd")); + g_events->push_back(GetFullMethodName("OnEnvironmentsSetUpEnd")); } virtual void OnTestCaseStart(const TestCase& /*test_case*/) { - g_events->PushBack(GetFullMethodName("OnTestCaseStart")); + g_events->push_back(GetFullMethodName("OnTestCaseStart")); } virtual void OnTestStart(const TestInfo& /*test_info*/) { - g_events->PushBack(GetFullMethodName("OnTestStart")); + g_events->push_back(GetFullMethodName("OnTestStart")); } virtual void OnTestPartResult(const TestPartResult& /*test_part_result*/) { - g_events->PushBack(GetFullMethodName("OnTestPartResult")); + g_events->push_back(GetFullMethodName("OnTestPartResult")); } virtual void OnTestEnd(const TestInfo& /*test_info*/) { - g_events->PushBack(GetFullMethodName("OnTestEnd")); + g_events->push_back(GetFullMethodName("OnTestEnd")); } virtual void OnTestCaseEnd(const TestCase& /*test_case*/) { - g_events->PushBack(GetFullMethodName("OnTestCaseEnd")); + g_events->push_back(GetFullMethodName("OnTestCaseEnd")); } virtual void OnEnvironmentsTearDownStart(const UnitTest& /*unit_test*/) { - g_events->PushBack(GetFullMethodName("OnEnvironmentsTearDownStart")); + g_events->push_back(GetFullMethodName("OnEnvironmentsTearDownStart")); } virtual void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) { - g_events->PushBack(GetFullMethodName("OnEnvironmentsTearDownEnd")); + g_events->push_back(GetFullMethodName("OnEnvironmentsTearDownEnd")); } virtual void OnTestIterationEnd(const UnitTest& /*unit_test*/, @@ -120,11 +111,11 @@ class EventRecordingListener : public TestEventListener { Message message; message << GetFullMethodName("OnTestIterationEnd") << "(" << iteration << ")"; - g_events->PushBack(message.GetString()); + g_events->push_back(message.GetString()); } virtual void OnTestProgramEnd(const UnitTest& /*unit_test*/) { - g_events->PushBack(GetFullMethodName("OnTestProgramEnd")); + g_events->push_back(GetFullMethodName("OnTestProgramEnd")); } private: @@ -140,42 +131,42 @@ class EventRecordingListener : public TestEventListener { class EnvironmentInvocationCatcher : public Environment { protected: virtual void SetUp() { - g_events->PushBack(String("Environment::SetUp")); + g_events->push_back(String("Environment::SetUp")); } virtual void TearDown() { - g_events->PushBack(String("Environment::TearDown")); + g_events->push_back(String("Environment::TearDown")); } }; class ListenerTest : public Test { protected: static void SetUpTestCase() { - g_events->PushBack(String("ListenerTest::SetUpTestCase")); + g_events->push_back(String("ListenerTest::SetUpTestCase")); } static void TearDownTestCase() { - g_events->PushBack(String("ListenerTest::TearDownTestCase")); + g_events->push_back(String("ListenerTest::TearDownTestCase")); } virtual void SetUp() { - g_events->PushBack(String("ListenerTest::SetUp")); + g_events->push_back(String("ListenerTest::SetUp")); } virtual void TearDown() { - g_events->PushBack(String("ListenerTest::TearDown")); + g_events->push_back(String("ListenerTest::TearDown")); } }; TEST_F(ListenerTest, DoesFoo) { // Test execution order within a test case is not guaranteed so we are not // recording the test name. - g_events->PushBack(String("ListenerTest::* Test Body")); + g_events->push_back(String("ListenerTest::* Test Body")); SUCCEED(); // Triggers OnTestPartResult. } TEST_F(ListenerTest, DoesBar) { - g_events->PushBack(String("ListenerTest::* Test Body")); + g_events->push_back(String("ListenerTest::* Test Body")); SUCCEED(); // Triggers OnTestPartResult. } @@ -186,7 +177,7 @@ TEST_F(ListenerTest, DoesBar) { using ::testing::internal::EnvironmentInvocationCatcher; using ::testing::internal::EventRecordingListener; -void VerifyResults(const Vector& data, +void VerifyResults(const std::vector& data, const char* const* expected_data, int expected_data_size) { const int actual_size = data.size(); @@ -199,18 +190,18 @@ void VerifyResults(const Vector& data, expected_data_size : actual_size; int i = 0; for (; i < shorter_size; ++i) { - ASSERT_STREQ(expected_data[i], data.GetElement(i).c_str()) + ASSERT_STREQ(expected_data[i], data[i].c_str()) << "at position " << i; } // Prints extra elements in the actual data. for (; i < actual_size; ++i) { - printf(" Actual event #%d: %s\n", i, data.GetElement(i).c_str()); + printf(" Actual event #%d: %s\n", i, data[i].c_str()); } } int main(int argc, char **argv) { - Vector events; + std::vector events; g_events = &events; InitGoogleTest(&argc, argv); diff --git a/test/gtest_stress_test.cc b/test/gtest_stress_test.cc index 3cb68de8..01f4fc6f 100644 --- a/test/gtest_stress_test.cc +++ b/test/gtest_stress_test.cc @@ -35,6 +35,7 @@ #include #include +#include // We must define this macro in order to #include // gtest-internal-inl.h. This is how Google Test prevents a user from @@ -51,7 +52,6 @@ namespace { using internal::scoped_ptr; using internal::String; using internal::TestPropertyKeyIs; -using internal::Vector; using internal::ThreadStartSemaphore; using internal::ThreadWithParam; @@ -75,12 +75,13 @@ String IdToString(int id) { return id_message.GetString(); } -void ExpectKeyAndValueWereRecordedForId(const Vector& properties, - int id, - const char* suffix) { +void ExpectKeyAndValueWereRecordedForId( + const std::vector& properties, + int id, const char* suffix) { TestPropertyKeyIs matches_key(IdToKey(id, suffix).c_str()); - const TestProperty* property = properties.FindIf(matches_key); - ASSERT_TRUE(property != NULL) + const std::vector::const_iterator property = + std::find_if(properties.begin(), properties.end(), matches_key); + ASSERT_TRUE(property != properties.end()) << "expecting " << suffix << " value for id " << id; EXPECT_STREQ(IdToString(id).c_str(), property->value()); } @@ -143,11 +144,11 @@ TEST(StressTest, CanUseScopedTraceAndAssertionsInManyThreads) { const TestInfo* const info = UnitTest::GetInstance()->current_test_info(); const TestResult* const result = info->result(); - Vector properties; + std::vector properties; // We have no access to the TestResult's list of properties but we can // copy them one by one. for (int i = 0; i < result->test_property_count(); ++i) - properties.PushBack(result->GetTestProperty(i)); + properties.push_back(result->GetTestProperty(i)); EXPECT_EQ(kThreadCount * 2 + 1, result->test_property_count()) << "String and int values recorded on each thread, " diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index 071301ea..05515035 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -33,6 +33,7 @@ // Google Test work. #include +#include // Verifies that the command line flag variables can be accessed // in code once has been #included. @@ -154,11 +155,14 @@ using testing::internal::AlwaysFalse; using testing::internal::AlwaysTrue; using testing::internal::AppendUserMessage; using testing::internal::CodePointToUtf8; +using testing::internal::CountIf; using testing::internal::EqFailure; using testing::internal::FloatingPoint; using testing::internal::FormatTimeInMillisAsSeconds; +using testing::internal::ForEach; using testing::internal::GTestFlagSaver; using testing::internal::GetCurrentOsStackTraceExceptTop; +using testing::internal::GetElementOr; using testing::internal::GetNextRandomSeed; using testing::internal::GetRandomSeedFromFlag; using testing::internal::GetTestTypeId; @@ -170,12 +174,13 @@ using testing::internal::ParseInt32Flag; using testing::internal::ShouldRunTestOnShard; using testing::internal::ShouldShard; using testing::internal::ShouldUseColor; +using testing::internal::Shuffle; +using testing::internal::ShuffleRange; using testing::internal::StreamableToString; using testing::internal::String; using testing::internal::TestEventListenersAccessor; using testing::internal::TestResultAccessor; using testing::internal::UInt32; -using testing::internal::Vector; using testing::internal::WideStringToUtf8; using testing::internal::kMaxRandomSeed; using testing::internal::kTestTypeIdInGoogleTest; @@ -186,14 +191,14 @@ using testing::internal::CaptureStdout; using testing::internal::GetCapturedStdout; #endif // GTEST_HAS_STREAM_REDIRECTION_ -class TestingVector : public Vector { +class TestingVector : public std::vector { }; ::std::ostream& operator<<(::std::ostream& os, const TestingVector& vector) { os << "{ "; - for (int i = 0; i < vector.size(); i++) { - os << vector.GetElement(i) << " "; + for (size_t i = 0; i < vector.size(); i++) { + os << vector[i] << " "; } os << "}"; return os; @@ -553,339 +558,80 @@ TEST(RandomTest, RepeatsWhenReseeded) { } } -// Tests the Vector class template. +// Tests STL container utilities. -// Tests Vector::Clear(). -TEST(VectorTest, Clear) { - Vector a; - a.PushBack(1); - a.Clear(); - EXPECT_EQ(0, a.size()); +// Tests CountIf(). - a.PushBack(2); - a.PushBack(3); - a.Clear(); - EXPECT_EQ(0, a.size()); -} - -// Tests Vector::PushBack(). -TEST(VectorTest, PushBack) { - Vector a; - a.PushBack('a'); - ASSERT_EQ(1, a.size()); - EXPECT_EQ('a', a.GetElement(0)); - - a.PushBack('b'); - ASSERT_EQ(2, a.size()); - EXPECT_EQ('a', a.GetElement(0)); - EXPECT_EQ('b', a.GetElement(1)); -} - -// Tests Vector::PushFront(). -TEST(VectorTest, PushFront) { - Vector a; - ASSERT_EQ(0, a.size()); - - // Calls PushFront() on an empty Vector. - a.PushFront(1); - ASSERT_EQ(1, a.size()); - EXPECT_EQ(1, a.GetElement(0)); - - // Calls PushFront() on a singleton Vector. - a.PushFront(2); - ASSERT_EQ(2, a.size()); - EXPECT_EQ(2, a.GetElement(0)); - EXPECT_EQ(1, a.GetElement(1)); - - // Calls PushFront() on a Vector with more than one elements. - a.PushFront(3); - ASSERT_EQ(3, a.size()); - EXPECT_EQ(3, a.GetElement(0)); - EXPECT_EQ(2, a.GetElement(1)); - EXPECT_EQ(1, a.GetElement(2)); -} - -// Tests Vector::PopFront(). -TEST(VectorTest, PopFront) { - Vector a; - - // Popping on an empty Vector should fail. - EXPECT_FALSE(a.PopFront(NULL)); - - // Popping again on an empty Vector should fail, and the result element - // shouldn't be overwritten. - int element = 1; - EXPECT_FALSE(a.PopFront(&element)); - EXPECT_EQ(1, element); - - a.PushFront(2); - a.PushFront(3); - - // PopFront() should pop the element in the front of the Vector. - EXPECT_TRUE(a.PopFront(&element)); - EXPECT_EQ(3, element); - - // After popping the last element, the Vector should be empty. - EXPECT_TRUE(a.PopFront(NULL)); - EXPECT_EQ(0, a.size()); -} - -// Tests inserting at the beginning using Vector::Insert(). -TEST(VectorTest, InsertAtBeginning) { - Vector a; - ASSERT_EQ(0, a.size()); - - // Inserts into an empty Vector. - a.Insert(1, 0); - ASSERT_EQ(1, a.size()); - EXPECT_EQ(1, a.GetElement(0)); - - // Inserts at the beginning of a singleton Vector. - a.Insert(2, 0); - ASSERT_EQ(2, a.size()); - EXPECT_EQ(2, a.GetElement(0)); - EXPECT_EQ(1, a.GetElement(1)); - - // Inserts at the beginning of a Vector with more than one elements. - a.Insert(3, 0); - ASSERT_EQ(3, a.size()); - EXPECT_EQ(3, a.GetElement(0)); - EXPECT_EQ(2, a.GetElement(1)); - EXPECT_EQ(1, a.GetElement(2)); -} - -// Tests inserting at a location other than the beginning using -// Vector::Insert(). -TEST(VectorTest, InsertNotAtBeginning) { - // Prepares a singleton Vector. - Vector a; - a.PushBack(1); - - // Inserts at the end of a singleton Vector. - a.Insert(2, a.size()); - ASSERT_EQ(2, a.size()); - EXPECT_EQ(1, a.GetElement(0)); - EXPECT_EQ(2, a.GetElement(1)); - - // Inserts at the end of a Vector with more than one elements. - a.Insert(3, a.size()); - ASSERT_EQ(3, a.size()); - EXPECT_EQ(1, a.GetElement(0)); - EXPECT_EQ(2, a.GetElement(1)); - EXPECT_EQ(3, a.GetElement(2)); - - // Inserts in the middle of a Vector. - a.Insert(4, 1); - ASSERT_EQ(4, a.size()); - EXPECT_EQ(1, a.GetElement(0)); - EXPECT_EQ(4, a.GetElement(1)); - EXPECT_EQ(2, a.GetElement(2)); - EXPECT_EQ(3, a.GetElement(3)); -} - -// Tests Vector::GetElementOr(). -TEST(VectorTest, GetElementOr) { - Vector a; - EXPECT_EQ('x', a.GetElementOr(0, 'x')); - - a.PushBack('a'); - a.PushBack('b'); - EXPECT_EQ('a', a.GetElementOr(0, 'x')); - EXPECT_EQ('b', a.GetElementOr(1, 'x')); - EXPECT_EQ('x', a.GetElementOr(-2, 'x')); - EXPECT_EQ('x', a.GetElementOr(2, 'x')); -} - -TEST(VectorTest, Swap) { - Vector a; - a.PushBack(0); - a.PushBack(1); - a.PushBack(2); - - // Swaps an element with itself. - a.Swap(0, 0); - ASSERT_EQ(0, a.GetElement(0)); - ASSERT_EQ(1, a.GetElement(1)); - ASSERT_EQ(2, a.GetElement(2)); - - // Swaps two different elements where the indices go up. - a.Swap(0, 1); - ASSERT_EQ(1, a.GetElement(0)); - ASSERT_EQ(0, a.GetElement(1)); - ASSERT_EQ(2, a.GetElement(2)); - - // Swaps two different elements where the indices go down. - a.Swap(2, 0); - ASSERT_EQ(2, a.GetElement(0)); - ASSERT_EQ(0, a.GetElement(1)); - ASSERT_EQ(1, a.GetElement(2)); -} - -TEST(VectorTest, Clone) { - // Clones an empty Vector. - Vector a; - scoped_ptr > empty(a.Clone()); - EXPECT_EQ(0, empty->size()); - - // Clones a singleton. - a.PushBack(42); - scoped_ptr > singleton(a.Clone()); - ASSERT_EQ(1, singleton->size()); - EXPECT_EQ(42, singleton->GetElement(0)); - - // Clones a Vector with more elements. - a.PushBack(43); - a.PushBack(44); - scoped_ptr > big(a.Clone()); - ASSERT_EQ(3, big->size()); - EXPECT_EQ(42, big->GetElement(0)); - EXPECT_EQ(43, big->GetElement(1)); - EXPECT_EQ(44, big->GetElement(2)); -} - -// Tests Vector::Erase(). -TEST(VectorDeathTest, Erase) { - Vector a; - - // Tests erasing from an empty vector. - EXPECT_DEATH_IF_SUPPORTED( - a.Erase(0), - "Invalid Vector index 0: must be in range \\[0, -1\\]\\."); - - // Tests erasing from a singleton vector. - a.PushBack(0); +static bool IsPositive(int n) { return n > 0; } - a.Erase(0); - EXPECT_EQ(0, a.size()); +TEST(ContainerUtilityTest, CountIf) { + std::vector v; + EXPECT_EQ(0, CountIf(v, IsPositive)); // Works for an empty container. - // Tests Erase parameters beyond the bounds of the vector. - Vector a1; - a1.PushBack(0); - a1.PushBack(1); - a1.PushBack(2); + v.push_back(-1); + v.push_back(0); + EXPECT_EQ(0, CountIf(v, IsPositive)); // Works when no value satisfies. - EXPECT_DEATH_IF_SUPPORTED( - a1.Erase(3), - "Invalid Vector index 3: must be in range \\[0, 2\\]\\."); - EXPECT_DEATH_IF_SUPPORTED( - a1.Erase(-1), - "Invalid Vector index -1: must be in range \\[0, 2\\]\\."); - - // Tests erasing at the end of the vector. - Vector a2; - a2.PushBack(0); - a2.PushBack(1); - a2.PushBack(2); - - a2.Erase(2); - ASSERT_EQ(2, a2.size()); - EXPECT_EQ(0, a2.GetElement(0)); - EXPECT_EQ(1, a2.GetElement(1)); - - // Tests erasing in the middle of the vector. - Vector a3; - a3.PushBack(0); - a3.PushBack(1); - a3.PushBack(2); - - a3.Erase(1); - ASSERT_EQ(2, a3.size()); - EXPECT_EQ(0, a3.GetElement(0)); - EXPECT_EQ(2, a3.GetElement(1)); - - // Tests erasing at the beginning of the vector. - Vector a4; - a4.PushBack(0); - a4.PushBack(1); - a4.PushBack(2); - - a4.Erase(0); - ASSERT_EQ(2, a4.size()); - EXPECT_EQ(1, a4.GetElement(0)); - EXPECT_EQ(2, a4.GetElement(1)); -} - -// Tests the GetElement accessor. -TEST(VectorDeathTest, GetElement) { - Vector a; - a.PushBack(0); - a.PushBack(1); - a.PushBack(2); - const Vector& b = a; - - EXPECT_EQ(0, b.GetElement(0)); - EXPECT_EQ(1, b.GetElement(1)); - EXPECT_EQ(2, b.GetElement(2)); - EXPECT_DEATH_IF_SUPPORTED( - b.GetElement(3), - "Invalid Vector index 3: must be in range \\[0, 2\\]\\."); - EXPECT_DEATH_IF_SUPPORTED( - b.GetElement(-1), - "Invalid Vector index -1: must be in range \\[0, 2\\]\\."); + v.push_back(2); + v.push_back(-10); + v.push_back(10); + EXPECT_EQ(2, CountIf(v, IsPositive)); } -// Tests the GetMutableElement accessor. -TEST(VectorDeathTest, GetMutableElement) { - Vector a; - a.PushBack(0); - a.PushBack(1); - a.PushBack(2); +// Tests ForEach(). - EXPECT_EQ(0, a.GetMutableElement(0)); - EXPECT_EQ(1, a.GetMutableElement(1)); - EXPECT_EQ(2, a.GetMutableElement(2)); +static int g_sum = 0; +static void Accumulate(int n) { g_sum += n; } - a.GetMutableElement(0) = 42; - EXPECT_EQ(42, a.GetMutableElement(0)); - EXPECT_EQ(1, a.GetMutableElement(1)); - EXPECT_EQ(2, a.GetMutableElement(2)); +TEST(ContainerUtilityTest, ForEach) { + std::vector v; + g_sum = 0; + ForEach(v, Accumulate); + EXPECT_EQ(0, g_sum); // Works for an empty container; - EXPECT_DEATH_IF_SUPPORTED( - a.GetMutableElement(3), - "Invalid Vector index 3: must be in range \\[0, 2\\]\\."); - EXPECT_DEATH_IF_SUPPORTED( - a.GetMutableElement(-1), - "Invalid Vector index -1: must be in range \\[0, 2\\]\\."); + g_sum = 0; + v.push_back(1); + ForEach(v, Accumulate); + EXPECT_EQ(1, g_sum); // Works for a container with one element. + + g_sum = 0; + v.push_back(20); + v.push_back(300); + ForEach(v, Accumulate); + EXPECT_EQ(321, g_sum); } -TEST(VectorDeathTest, Swap) { - Vector a; - a.PushBack(0); - a.PushBack(1); - a.PushBack(2); +// Tests GetElementOr(). +TEST(ContainerUtilityTest, GetElementOr) { + std::vector a; + EXPECT_EQ('x', GetElementOr(a, 0, 'x')); - EXPECT_DEATH_IF_SUPPORTED( - a.Swap(-1, 1), - "Invalid first swap element -1: must be in range \\[0, 2\\]"); - EXPECT_DEATH_IF_SUPPORTED( - a.Swap(3, 1), - "Invalid first swap element 3: must be in range \\[0, 2\\]"); - EXPECT_DEATH_IF_SUPPORTED( - a.Swap(1, -1), - "Invalid second swap element -1: must be in range \\[0, 2\\]"); - EXPECT_DEATH_IF_SUPPORTED( - a.Swap(1, 3), - "Invalid second swap element 3: must be in range \\[0, 2\\]"); + a.push_back('a'); + a.push_back('b'); + EXPECT_EQ('a', GetElementOr(a, 0, 'x')); + EXPECT_EQ('b', GetElementOr(a, 1, 'x')); + EXPECT_EQ('x', GetElementOr(a, -2, 'x')); + EXPECT_EQ('x', GetElementOr(a, 2, 'x')); } -TEST(VectorDeathTest, ShuffleRange) { - Vector a; - a.PushBack(0); - a.PushBack(1); - a.PushBack(2); +TEST(ContainerUtilityDeathTest, ShuffleRange) { + std::vector a; + a.push_back(0); + a.push_back(1); + a.push_back(2); testing::internal::Random random(1); EXPECT_DEATH_IF_SUPPORTED( - a.ShuffleRange(&random, -1, 1), + ShuffleRange(&random, -1, 1, &a), "Invalid shuffle range start -1: must be in range \\[0, 3\\]"); EXPECT_DEATH_IF_SUPPORTED( - a.ShuffleRange(&random, 4, 4), + ShuffleRange(&random, 4, 4, &a), "Invalid shuffle range start 4: must be in range \\[0, 3\\]"); EXPECT_DEATH_IF_SUPPORTED( - a.ShuffleRange(&random, 3, 2), + ShuffleRange(&random, 3, 2, &a), "Invalid shuffle range finish 2: must be in range \\[3, 3\\]"); EXPECT_DEATH_IF_SUPPORTED( - a.ShuffleRange(&random, 3, 4), + ShuffleRange(&random, 3, 4, &a), "Invalid shuffle range finish 4: must be in range \\[3, 3\\]"); } @@ -895,18 +641,18 @@ class VectorShuffleTest : public Test { VectorShuffleTest() : random_(1) { for (int i = 0; i < kVectorSize; i++) { - vector_.PushBack(i); + vector_.push_back(i); } } static bool VectorIsCorrupt(const TestingVector& vector) { - if (kVectorSize != vector.size()) { + if (kVectorSize != static_cast(vector.size())) { return true; } bool found_in_vector[kVectorSize] = { false }; - for (int i = 0; i < vector.size(); i++) { - const int e = vector.GetElement(i); + for (size_t i = 0; i < vector.size(); i++) { + const int e = vector[i]; if (e < 0 || e >= kVectorSize || found_in_vector[e]) { return true; } @@ -924,7 +670,7 @@ class VectorShuffleTest : public Test { static bool RangeIsShuffled(const TestingVector& vector, int begin, int end) { for (int i = begin; i < end; i++) { - if (i != vector.GetElement(i)) { + if (i != vector[i]) { return true; } } @@ -952,39 +698,39 @@ const int VectorShuffleTest::kVectorSize; TEST_F(VectorShuffleTest, HandlesEmptyRange) { // Tests an empty range at the beginning... - vector_.ShuffleRange(&random_, 0, 0); + ShuffleRange(&random_, 0, 0, &vector_); ASSERT_PRED1(VectorIsNotCorrupt, vector_); ASSERT_PRED1(VectorIsUnshuffled, vector_); // ...in the middle... - vector_.ShuffleRange(&random_, kVectorSize/2, kVectorSize/2); + ShuffleRange(&random_, kVectorSize/2, kVectorSize/2, &vector_); ASSERT_PRED1(VectorIsNotCorrupt, vector_); ASSERT_PRED1(VectorIsUnshuffled, vector_); // ...at the end... - vector_.ShuffleRange(&random_, kVectorSize - 1, kVectorSize - 1); + ShuffleRange(&random_, kVectorSize - 1, kVectorSize - 1, &vector_); ASSERT_PRED1(VectorIsNotCorrupt, vector_); ASSERT_PRED1(VectorIsUnshuffled, vector_); // ...and past the end. - vector_.ShuffleRange(&random_, kVectorSize, kVectorSize); + ShuffleRange(&random_, kVectorSize, kVectorSize, &vector_); ASSERT_PRED1(VectorIsNotCorrupt, vector_); ASSERT_PRED1(VectorIsUnshuffled, vector_); } TEST_F(VectorShuffleTest, HandlesRangeOfSizeOne) { // Tests a size one range at the beginning... - vector_.ShuffleRange(&random_, 0, 1); + ShuffleRange(&random_, 0, 1, &vector_); ASSERT_PRED1(VectorIsNotCorrupt, vector_); ASSERT_PRED1(VectorIsUnshuffled, vector_); // ...in the middle... - vector_.ShuffleRange(&random_, kVectorSize/2, kVectorSize/2 + 1); + ShuffleRange(&random_, kVectorSize/2, kVectorSize/2 + 1, &vector_); ASSERT_PRED1(VectorIsNotCorrupt, vector_); ASSERT_PRED1(VectorIsUnshuffled, vector_); // ...and at the end. - vector_.ShuffleRange(&random_, kVectorSize - 1, kVectorSize); + ShuffleRange(&random_, kVectorSize - 1, kVectorSize, &vector_); ASSERT_PRED1(VectorIsNotCorrupt, vector_); ASSERT_PRED1(VectorIsUnshuffled, vector_); } @@ -993,20 +739,20 @@ TEST_F(VectorShuffleTest, HandlesRangeOfSizeOne) { // we can guarantee that the following "random" tests will succeed. TEST_F(VectorShuffleTest, ShufflesEntireVector) { - vector_.Shuffle(&random_); + Shuffle(&random_, &vector_); ASSERT_PRED1(VectorIsNotCorrupt, vector_); EXPECT_FALSE(VectorIsUnshuffled(vector_)) << vector_; // Tests the first and last elements in particular to ensure that // there are no off-by-one problems in our shuffle algorithm. - EXPECT_NE(0, vector_.GetElement(0)); - EXPECT_NE(kVectorSize - 1, vector_.GetElement(kVectorSize - 1)); + EXPECT_NE(0, vector_[0]); + EXPECT_NE(kVectorSize - 1, vector_[kVectorSize - 1]); } TEST_F(VectorShuffleTest, ShufflesStartOfVector) { const int kRangeSize = kVectorSize/2; - vector_.ShuffleRange(&random_, 0, kRangeSize); + ShuffleRange(&random_, 0, kRangeSize, &vector_); ASSERT_PRED1(VectorIsNotCorrupt, vector_); EXPECT_PRED3(RangeIsShuffled, vector_, 0, kRangeSize); @@ -1015,7 +761,7 @@ TEST_F(VectorShuffleTest, ShufflesStartOfVector) { TEST_F(VectorShuffleTest, ShufflesEndOfVector) { const int kRangeSize = kVectorSize / 2; - vector_.ShuffleRange(&random_, kRangeSize, kVectorSize); + ShuffleRange(&random_, kRangeSize, kVectorSize, &vector_); ASSERT_PRED1(VectorIsNotCorrupt, vector_); EXPECT_PRED3(RangeIsUnshuffled, vector_, 0, kRangeSize); @@ -1024,7 +770,7 @@ TEST_F(VectorShuffleTest, ShufflesEndOfVector) { TEST_F(VectorShuffleTest, ShufflesMiddleOfVector) { int kRangeSize = kVectorSize/3; - vector_.ShuffleRange(&random_, kRangeSize, 2*kRangeSize); + ShuffleRange(&random_, kRangeSize, 2*kRangeSize, &vector_); ASSERT_PRED1(VectorIsNotCorrupt, vector_); EXPECT_PRED3(RangeIsUnshuffled, vector_, 0, kRangeSize); @@ -1035,20 +781,19 @@ TEST_F(VectorShuffleTest, ShufflesMiddleOfVector) { TEST_F(VectorShuffleTest, ShufflesRepeatably) { TestingVector vector2; for (int i = 0; i < kVectorSize; i++) { - vector2.PushBack(i); + vector2.push_back(i); } random_.Reseed(1234); - vector_.Shuffle(&random_); + Shuffle(&random_, &vector_); random_.Reseed(1234); - vector2.Shuffle(&random_); + Shuffle(&random_, &vector2); ASSERT_PRED1(VectorIsNotCorrupt, vector_); ASSERT_PRED1(VectorIsNotCorrupt, vector2); for (int i = 0; i < kVectorSize; i++) { - EXPECT_EQ(vector_.GetElement(i), vector2.GetElement(i)) - << " where i is " << i; + EXPECT_EQ(vector_[i], vector2[i]) << " where i is " << i; } } @@ -1728,7 +1473,7 @@ TEST(TestPropertyTest, SetValue) { // The test fixture for testing TestResult. class TestResultTest : public Test { protected: - typedef Vector TPRVector; + typedef std::vector TPRVector; // We make use of 2 TestPartResult objects, TestPartResult * pr1, * pr2; @@ -1755,23 +1500,23 @@ class TestResultTest : public Test { r2 = new TestResult(); // In order to test TestResult, we need to modify its internal - // state, in particular the TestPartResult Vector it holds. - // test_part_results() returns a const reference to this Vector. + // state, in particular the TestPartResult vector it holds. + // test_part_results() returns a const reference to this vector. // We cast it to a non-const object s.t. it can be modified (yes, // this is a hack). - TPRVector* results1 = const_cast *>( + TPRVector* results1 = const_cast( &TestResultAccessor::test_part_results(*r1)); - TPRVector* results2 = const_cast *>( + TPRVector* results2 = const_cast( &TestResultAccessor::test_part_results(*r2)); // r0 is an empty TestResult. // r1 contains a single SUCCESS TestPartResult. - results1->PushBack(*pr1); + results1->push_back(*pr1); // r2 contains a SUCCESS, and a FAILURE. - results2->PushBack(*pr1); - results2->PushBack(*pr2); + results2->push_back(*pr1); + results2->push_back(*pr2); } virtual void TearDown() { @@ -1826,12 +1571,8 @@ typedef TestResultTest TestResultDeathTest; TEST_F(TestResultDeathTest, GetTestPartResult) { CompareTestPartResult(*pr1, r2->GetTestPartResult(0)); CompareTestPartResult(*pr2, r2->GetTestPartResult(1)); - EXPECT_DEATH_IF_SUPPORTED( - r2->GetTestPartResult(2), - "Invalid Vector index 2: must be in range \\[0, 1\\]\\."); - EXPECT_DEATH_IF_SUPPORTED( - r2->GetTestPartResult(-1), - "Invalid Vector index -1: must be in range \\[0, 1\\]\\."); + EXPECT_DEATH_IF_SUPPORTED(r2->GetTestPartResult(2), ""); + EXPECT_DEATH_IF_SUPPORTED(r2->GetTestPartResult(-1), ""); } // Tests TestResult has no properties when none are added. @@ -1913,12 +1654,8 @@ TEST(TestResultPropertyDeathTest, GetTestProperty) { EXPECT_STREQ("key_3", fetched_property_3.key()); EXPECT_STREQ("3", fetched_property_3.value()); - EXPECT_DEATH_IF_SUPPORTED( - test_result.GetTestProperty(3), - "Invalid Vector index 3: must be in range \\[0, 2\\]\\."); - EXPECT_DEATH_IF_SUPPORTED( - test_result.GetTestProperty(-1), - "Invalid Vector index -1: must be in range \\[0, 2\\]\\."); + EXPECT_DEATH_IF_SUPPORTED(test_result.GetTestProperty(3), ""); + EXPECT_DEATH_IF_SUPPORTED(test_result.GetTestProperty(-1), ""); } // When a property using a reserved key is supplied to this function, it tests @@ -2598,10 +2335,6 @@ TEST(PredTest, SingleEvaluationOnFailure) { // Some helper functions for testing using overloaded/template // functions with ASSERT_PREDn and EXPECT_PREDn. -bool IsPositive(int n) { - return n > 0; -} - bool IsPositive(double x) { return x > 0; } @@ -6747,26 +6480,26 @@ TEST(TestEventListenersTest, Append) { // order. class SequenceTestingListener : public EmptyTestEventListener { public: - SequenceTestingListener(Vector* vector, const char* id) + SequenceTestingListener(std::vector* vector, const char* id) : vector_(vector), id_(id) {} protected: virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) { - vector_->PushBack(GetEventDescription("OnTestProgramStart")); + vector_->push_back(GetEventDescription("OnTestProgramStart")); } virtual void OnTestProgramEnd(const UnitTest& /*unit_test*/) { - vector_->PushBack(GetEventDescription("OnTestProgramEnd")); + vector_->push_back(GetEventDescription("OnTestProgramEnd")); } virtual void OnTestIterationStart(const UnitTest& /*unit_test*/, int /*iteration*/) { - vector_->PushBack(GetEventDescription("OnTestIterationStart")); + vector_->push_back(GetEventDescription("OnTestIterationStart")); } virtual void OnTestIterationEnd(const UnitTest& /*unit_test*/, int /*iteration*/) { - vector_->PushBack(GetEventDescription("OnTestIterationEnd")); + vector_->push_back(GetEventDescription("OnTestIterationEnd")); } private: @@ -6776,14 +6509,14 @@ class SequenceTestingListener : public EmptyTestEventListener { return message.GetString(); } - Vector* vector_; + std::vector* vector_; const char* const id_; GTEST_DISALLOW_COPY_AND_ASSIGN_(SequenceTestingListener); }; TEST(EventListenerTest, AppendKeepsOrder) { - Vector vec; + std::vector vec; TestEventListeners listeners; listeners.Append(new SequenceTestingListener(&vec, "1st")); listeners.Append(new SequenceTestingListener(&vec, "2nd")); @@ -6791,34 +6524,34 @@ TEST(EventListenerTest, AppendKeepsOrder) { TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart( *UnitTest::GetInstance()); - ASSERT_EQ(3, vec.size()); - EXPECT_STREQ("1st.OnTestProgramStart", vec.GetElement(0).c_str()); - EXPECT_STREQ("2nd.OnTestProgramStart", vec.GetElement(1).c_str()); - EXPECT_STREQ("3rd.OnTestProgramStart", vec.GetElement(2).c_str()); + ASSERT_EQ(3U, vec.size()); + EXPECT_STREQ("1st.OnTestProgramStart", vec[0].c_str()); + EXPECT_STREQ("2nd.OnTestProgramStart", vec[1].c_str()); + EXPECT_STREQ("3rd.OnTestProgramStart", vec[2].c_str()); - vec.Clear(); + vec.clear(); TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramEnd( *UnitTest::GetInstance()); - ASSERT_EQ(3, vec.size()); - EXPECT_STREQ("3rd.OnTestProgramEnd", vec.GetElement(0).c_str()); - EXPECT_STREQ("2nd.OnTestProgramEnd", vec.GetElement(1).c_str()); - EXPECT_STREQ("1st.OnTestProgramEnd", vec.GetElement(2).c_str()); + ASSERT_EQ(3U, vec.size()); + EXPECT_STREQ("3rd.OnTestProgramEnd", vec[0].c_str()); + EXPECT_STREQ("2nd.OnTestProgramEnd", vec[1].c_str()); + EXPECT_STREQ("1st.OnTestProgramEnd", vec[2].c_str()); - vec.Clear(); + vec.clear(); TestEventListenersAccessor::GetRepeater(&listeners)->OnTestIterationStart( *UnitTest::GetInstance(), 0); - ASSERT_EQ(3, vec.size()); - EXPECT_STREQ("1st.OnTestIterationStart", vec.GetElement(0).c_str()); - EXPECT_STREQ("2nd.OnTestIterationStart", vec.GetElement(1).c_str()); - EXPECT_STREQ("3rd.OnTestIterationStart", vec.GetElement(2).c_str()); + ASSERT_EQ(3U, vec.size()); + EXPECT_STREQ("1st.OnTestIterationStart", vec[0].c_str()); + EXPECT_STREQ("2nd.OnTestIterationStart", vec[1].c_str()); + EXPECT_STREQ("3rd.OnTestIterationStart", vec[2].c_str()); - vec.Clear(); + vec.clear(); TestEventListenersAccessor::GetRepeater(&listeners)->OnTestIterationEnd( *UnitTest::GetInstance(), 0); - ASSERT_EQ(3, vec.size()); - EXPECT_STREQ("3rd.OnTestIterationEnd", vec.GetElement(0).c_str()); - EXPECT_STREQ("2nd.OnTestIterationEnd", vec.GetElement(1).c_str()); - EXPECT_STREQ("1st.OnTestIterationEnd", vec.GetElement(2).c_str()); + ASSERT_EQ(3U, vec.size()); + EXPECT_STREQ("3rd.OnTestIterationEnd", vec[0].c_str()); + EXPECT_STREQ("2nd.OnTestIterationEnd", vec[1].c_str()); + EXPECT_STREQ("1st.OnTestIterationEnd", vec[2].c_str()); } // Tests that a listener removed from a TestEventListeners list stops receiving -- cgit v1.2.3 From 4879aac74991ad4552c5ed2ec178af511f3feb5e Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Thu, 25 Feb 2010 21:40:08 +0000 Subject: Simplifies the threading implementation and improves some comments. --- test/gtest-port_test.cc | 30 ++++++------------------------ 1 file changed, 6 insertions(+), 24 deletions(-) (limited to 'test') diff --git a/test/gtest-port_test.cc b/test/gtest-port_test.cc index 8594aa97..f7f26215 100644 --- a/test/gtest-port_test.cc +++ b/test/gtest-port_test.cc @@ -770,18 +770,6 @@ TEST(ThreadLocalTest, SingleParamConstructorInitializesToParam) { EXPECT_EQ(&i, t2.get()); } -class NoCopyConstructor { - public: - NoCopyConstructor() {} - private: - GTEST_DISALLOW_COPY_AND_ASSIGN_(NoCopyConstructor); -}; - -TEST(ThreadLocalTest, ValueCopyConstructorIsNotRequiredForDefaultVersion) { - ThreadLocal bar; - bar.get(); -} - class NoDefaultContructor { public: explicit NoDefaultContructor(const char*) {} @@ -796,9 +784,6 @@ TEST(ThreadLocalTest, ValueDefaultContructorIsNotRequiredForParamVersion) { TEST(ThreadLocalTest, GetAndPointerReturnSameValue) { ThreadLocal thread_local; - // This is why EXPECT_TRUE is used here rather than EXPECT_EQ because - // we don't care about a particular value of thread_local.pointer() here; - // we only care about pointer and reference referring to the same lvalue. EXPECT_EQ(thread_local.pointer(), &(thread_local.get())); // Verifies the condition still holds after calling set. @@ -825,7 +810,7 @@ TEST(MutexTestDeathTest, AssertHeldShouldAssertWhenNotLocked) { { MutexLock lock(&m); } m.AssertHeld(); }, - "Current thread is not holding mutex..+"); + "The current thread is not holding the mutex @.+"); } void SleepMilliseconds(int time) { @@ -847,16 +832,13 @@ class AtomicCounterWithMutex { // We cannot use Mutex and MutexLock here or rely on their memory // barrier functionality as we are testing them here. pthread_mutex_t memory_barrier_mutex; - int err = pthread_mutex_init(&memory_barrier_mutex, NULL); - GTEST_CHECK_(err == 0) << "pthread_mutex_init failed with error " << err; - err = pthread_mutex_lock(&memory_barrier_mutex); - GTEST_CHECK_(err == 0) << "pthread_mutex_lock failed with error " << err; + GTEST_CHECK_POSIX_SUCCESS_( + pthread_mutex_init(&memory_barrier_mutex, NULL)); + GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_lock(&memory_barrier_mutex)); SleepMilliseconds(random_.Generate(30)); - err = pthread_mutex_unlock(&memory_barrier_mutex); - GTEST_CHECK_(err == 0) - << "pthread_mutex_unlock failed with error " << err; + GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_unlock(&memory_barrier_mutex)); } value_ = temp + 1; } @@ -937,7 +919,7 @@ int CountedDestructor::counter_ = 0; template void CallThreadLocalGet(ThreadLocal* threadLocal) { - threadLocal->get(); + threadLocal->get(); } TEST(ThreadLocalTest, DestroysManagedObjectsNoLaterThanSelf) { -- cgit v1.2.3 From 6baed3c1173c19f5d43af75798d3685853fbe8bd Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Thu, 25 Feb 2010 22:15:27 +0000 Subject: Fixes MSVC warnings in 64-bit mode. --- test/gtest_unittest.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'test') diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index 05515035..bc190e1e 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -683,7 +683,7 @@ class VectorShuffleTest : public Test { } static bool VectorIsShuffled(const TestingVector& vector) { - return RangeIsShuffled(vector, 0, vector.size()); + return RangeIsShuffled(vector, 0, static_cast(vector.size())); } static bool VectorIsUnshuffled(const TestingVector& vector) { -- cgit v1.2.3 From c85a77a6ab0ef05c4a9a8554bf8c5e1c8687cc75 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Fri, 26 Feb 2010 05:42:53 +0000 Subject: Simplifies ThreadStartSemaphore's implementation. --- test/gtest-port_test.cc | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) (limited to 'test') diff --git a/test/gtest-port_test.cc b/test/gtest-port_test.cc index f7f26215..357a99ed 100644 --- a/test/gtest-port_test.cc +++ b/test/gtest-port_test.cc @@ -35,10 +35,6 @@ #include -#if GTEST_HAS_PTHREAD -#include // For nanosleep(). -#endif // GTEST_HAS_PTHREAD - #if GTEST_OS_MAC #include #endif // GTEST_OS_MAC @@ -137,10 +133,7 @@ TEST(GetThreadCountTest, ReturnsCorrectValue) { if (GetThreadCount() == 1) break; - timespec time; - time.tv_sec = 0; - time.tv_nsec = 100L * 1000 * 1000; // .1 seconds. - nanosleep(&time, NULL); + SleepMilliseconds(100); } EXPECT_EQ(1U, GetThreadCount()); pthread_mutex_destroy(&mutex); @@ -802,7 +795,7 @@ TEST(ThreadLocalTest, PointerAndConstPointerReturnSameValue) { } #if GTEST_IS_THREADSAFE -TEST(MutexTestDeathTest, AssertHeldShouldAssertWhenNotLocked) { +TEST(MutexDeathTest, AssertHeldShouldAssertWhenNotLocked) { // AssertHeld() is flaky only in the presence of multiple threads accessing // the lock. In this case, the test is robust. EXPECT_DEATH_IF_SUPPORTED({ @@ -813,8 +806,10 @@ TEST(MutexTestDeathTest, AssertHeldShouldAssertWhenNotLocked) { "The current thread is not holding the mutex @.+"); } -void SleepMilliseconds(int time) { - usleep(static_cast(time * 1000.0)); +TEST(MutexTest, AssertHeldShouldNotAssertWhenLocked) { + Mutex m; + MutexLock lock(&m); + m.AssertHeld(); } class AtomicCounterWithMutex { @@ -873,7 +868,7 @@ TEST(MutexTest, OnlyOneThreadCanLockAtATime) { kCycleCount), &semaphore)); } - semaphore.Signal(); // Start the threads. + semaphore.Signal(); // Starts the threads. for (int i = 0; i < kThreadCount; ++i) counting_threads[i]->Join(); -- cgit v1.2.3 From 70eceaf8e7c6eb5c58838418db1768d8f08e53f5 Mon Sep 17 00:00:00 2001 From: vladlosev Date: Sat, 27 Feb 2010 00:48:00 +0000 Subject: Fixes issue 216 (gtest_output_test broken on Solaris --- test/gtest_output_test.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'test') diff --git a/test/gtest_output_test.py b/test/gtest_output_test.py index 4374a96e..125970aa 100755 --- a/test/gtest_output_test.py +++ b/test/gtest_output_test.py @@ -249,6 +249,8 @@ class GTestOutputTest(gtest_test_utils.TestCase): test_output = RemoveMatchingTests(test_output, 'DeathTest') if not SUPPORTS_TYPED_TESTS: test_output = RemoveMatchingTests(test_output, 'TypedTest') + test_output = RemoveMatchingTests(test_output, 'TypedDeathTest') + test_output = RemoveMatchingTests(test_output, 'TypeParamDeathTest') if not SUPPORTS_THREADS: test_output = RemoveMatchingTests(test_output, 'ExpectFailureWithThreadsTest') -- cgit v1.2.3 From 172b233a0477f82a5bc2b6d15f0647db1cfe5a1e Mon Sep 17 00:00:00 2001 From: vladlosev Date: Tue, 2 Mar 2010 00:56:24 +0000 Subject: Modifies gtest-death-test_test not to use core-dumping API calls. --- test/gtest-death-test_test.cc | 53 ++++++++++++++++++++----------------------- 1 file changed, 25 insertions(+), 28 deletions(-) (limited to 'test') diff --git a/test/gtest-death-test_test.cc b/test/gtest-death-test_test.cc index 127b7ffc..c57d700f 100644 --- a/test/gtest-death-test_test.cc +++ b/test/gtest-death-test_test.cc @@ -103,6 +103,16 @@ class ReplaceDeathTestFactory { } // namespace internal } // namespace testing +void DieInside(const char* function) { + fprintf(stderr, "death inside %s().", function); + fflush(stderr); + // We call _exit() instead of exit(), as the former is a direct + // system call and thus safer in the presence of threads. exit() + // will invoke user-defined exit-hooks, which may do dangerous + // things that conflict with death tests. + _exit(1); +} + // Tests that death tests work. class TestForDeathTest : public testing::Test { @@ -114,23 +124,12 @@ class TestForDeathTest : public testing::Test { } // A static member function that's expected to die. - static void StaticMemberFunction() { - fprintf(stderr, "%s", "death inside StaticMemberFunction()."); - fflush(stderr); - // We call _exit() instead of exit(), as the former is a direct - // system call and thus safer in the presence of threads. exit() - // will invoke user-defined exit-hooks, which may do dangerous - // things that conflict with death tests. - _exit(1); - } + static void StaticMemberFunction() { DieInside("StaticMemberFunction"); } // A method of the test fixture that may die. void MemberFunction() { - if (should_die_) { - fprintf(stderr, "%s", "death inside MemberFunction()."); - fflush(stderr); - _exit(1); - } + if (should_die_) + DieInside("MemberFunction"); } // True iff MemberFunction() should die. @@ -145,9 +144,8 @@ class MayDie { // A member function that may die. void MemberFunction() const { - if (should_die_) { - GTEST_LOG_(FATAL) << "death inside MayDie::MemberFunction()."; - } + if (should_die_) + DieInside("MayDie::MemberFunction"); } private: @@ -156,27 +154,24 @@ class MayDie { }; // A global function that's expected to die. -void GlobalFunction() { - GTEST_LOG_(FATAL) << "death inside GlobalFunction()."; -} +void GlobalFunction() { DieInside("GlobalFunction"); } // A non-void function that's expected to die. int NonVoidFunction() { - GTEST_LOG_(FATAL) << "death inside NonVoidFunction()."; + DieInside("NonVoidFunction"); return 1; } // A unary function that may die. void DieIf(bool should_die) { - if (should_die) { - GTEST_LOG_(FATAL) << "death inside DieIf()."; - } + if (should_die) + DieInside("DieIf"); } // A binary function that may die. bool DieIfLessThan(int x, int y) { if (x < y) { - GTEST_LOG_(FATAL) << "death inside DieIfLessThan()."; + DieInside("DieIfLessThan"); } return true; } @@ -191,7 +186,7 @@ void DeathTestSubroutine() { int DieInDebugElse12(int* sideeffect) { if (sideeffect) *sideeffect = 12; #ifndef NDEBUG - GTEST_LOG_(FATAL) << "debug death inside DieInDebugElse12()"; + DieInside("DieInDebugElse12"); #endif // NDEBUG return 12; } @@ -1111,8 +1106,10 @@ TEST(EnvironmentTest, HandleFitsIntoSizeT) { // Tests that EXPECT_DEATH_IF_SUPPORTED/ASSERT_DEATH_IF_SUPPORTED trigger // failures when death tests are available on the system. TEST(ConditionalDeathMacrosDeathTest, ExpectsDeathWhenDeathTestsAvailable) { - EXPECT_DEATH_IF_SUPPORTED(GTEST_CHECK_(false) << "failure", "false.*failure"); - ASSERT_DEATH_IF_SUPPORTED(GTEST_CHECK_(false) << "failure", "false.*failure"); + EXPECT_DEATH_IF_SUPPORTED(DieInside("CondDeathTestExpectMacro"), + "death inside CondDeathTestExpectMacro"); + ASSERT_DEATH_IF_SUPPORTED(DieInside("CondDeathTestAssertMacro"), + "death inside CondDeathTestAssertMacro"); // Empty statement will not crash, which must trigger a failure. EXPECT_NONFATAL_FAILURE(EXPECT_DEATH_IF_SUPPORTED(;, ""), ""); -- cgit v1.2.3 From 12a92c26fc0e0de81f687dbe739a6aa24f37f9dd Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Thu, 4 Mar 2010 22:15:53 +0000 Subject: Renames ThreadStartSempahore to Notificaton (by Vlad Losev); adds threading tests for SCOPED_TRACE() (by Vlad Losev); replaces native pthread calls with gtest's threading constructs (by Vlad Losev); fixes flakiness in CountedDestructor (by Vlad Losev); minor MSVC 7.1 clean-up (by Zhanyong Wan). --- test/gtest-port_test.cc | 50 +++++++---- test/gtest-typed-test_test.cc | 12 +-- test/gtest_output_test.py | 4 +- test/gtest_output_test_.cc | 162 ++++++++++++++++++++++++++++++---- test/gtest_output_test_golden_lin.txt | 40 +++++++-- test/gtest_stress_test.cc | 17 ++-- test/gtest_unittest.cc | 31 +++---- 7 files changed, 239 insertions(+), 77 deletions(-) (limited to 'test') diff --git a/test/gtest-port_test.cc b/test/gtest-port_test.cc index 357a99ed..1588bd46 100644 --- a/test/gtest-port_test.cc +++ b/test/gtest-port_test.cc @@ -803,7 +803,7 @@ TEST(MutexDeathTest, AssertHeldShouldAssertWhenNotLocked) { { MutexLock lock(&m); } m.AssertHeld(); }, - "The current thread is not holding the mutex @.+"); + "thread .*hold"); } TEST(MutexTest, AssertHeldShouldNotAssertWhenLocked) { @@ -859,16 +859,16 @@ TEST(MutexTest, OnlyOneThreadCanLockAtATime) { const int kCycleCount = 20; const int kThreadCount = 7; scoped_ptr counting_threads[kThreadCount]; - ThreadStartSemaphore semaphore; + Notification threads_can_start; // Creates and runs kThreadCount threads that increment locked_counter // kCycleCount times each. for (int i = 0; i < kThreadCount; ++i) { counting_threads[i].reset(new ThreadType(&CountingThreadFunc, make_pair(&locked_counter, kCycleCount), - &semaphore)); + &threads_can_start)); } - semaphore.Signal(); // Starts the threads. + threads_can_start.Notify(); for (int i = 0; i < kThreadCount; ++i) counting_threads[i]->Join(); @@ -901,16 +901,29 @@ TEST(ThreadLocalTest, ParameterizedConstructorSetsDefault) { EXPECT_STREQ("foo", result.c_str()); } -class CountedDestructor { +// DestructorTracker keeps track of whether the class instances have been +// destroyed. The static synchronization mutex has to be defined outside +// of the class, due to syntax of its definition. +static GTEST_DEFINE_STATIC_MUTEX_(destructor_tracker_mutex); + +static std::vector g_destroyed; + +class DestructorTracker { public: - ~CountedDestructor() { counter_++; } - static int counter() { return counter_; } - static void set_counter(int value) { counter_ = value; } + DestructorTracker() : index_(GetNewIndex()) {} + ~DestructorTracker() { + MutexLock lock(&destructor_tracker_mutex); + g_destroyed[index_] = true; + } private: - static int counter_; + static int GetNewIndex() { + MutexLock lock(&destructor_tracker_mutex); + g_destroyed.push_back(false); + return g_destroyed.size() - 1; + } + const int index_; }; -int CountedDestructor::counter_ = 0; template void CallThreadLocalGet(ThreadLocal* threadLocal) { @@ -918,16 +931,19 @@ void CallThreadLocalGet(ThreadLocal* threadLocal) { } TEST(ThreadLocalTest, DestroysManagedObjectsNoLaterThanSelf) { - CountedDestructor::set_counter(0); + g_destroyed.clear(); { - ThreadLocal thread_local; - ThreadWithParam*> thread( - &CallThreadLocalGet, &thread_local, NULL); + ThreadLocal thread_local; + ThreadWithParam*> thread( + &CallThreadLocalGet, &thread_local, NULL); thread.Join(); } - // There should be 2 desctuctor calls as ThreadLocal also contains a member - // T - used as a prototype for copy ctr version. - EXPECT_EQ(2, CountedDestructor::counter()); + // Verifies that all DestructorTracker objects there were have been + // destroyed. + for (size_t i = 0; i < g_destroyed.size(); ++i) + EXPECT_TRUE(g_destroyed[i]) << "at index " << i; + + g_destroyed.clear(); } TEST(ThreadLocalTest, ThreadLocalMutationsAffectOnlyCurrentThread) { diff --git a/test/gtest-typed-test_test.cc b/test/gtest-typed-test_test.cc index 4b6e971c..f2c39723 100644 --- a/test/gtest-typed-test_test.cc +++ b/test/gtest-typed-test_test.cc @@ -349,12 +349,12 @@ INSTANTIATE_TYPED_TEST_CASE_P(My, NumericTest, NumericTypes); #if !defined(GTEST_HAS_TYPED_TEST) && !defined(GTEST_HAS_TYPED_TEST_P) -// Google Test doesn't support type-parameterized tests on some platforms -// and compilers, such as MSVC 7.1. If we use conditional compilation to -// compile out all code referring to the gtest_main library, MSVC linker -// will not link that library at all and consequently complain about -// missing entry point defined in that library (fatal error LNK1561: -// entry point must be defined). This dummy test keeps gtest_main linked in. +// Google Test may not support type-parameterized tests with some +// compilers. If we use conditional compilation to compile out all +// code referring to the gtest_main library, MSVC linker will not link +// that library at all and consequently complain about missing entry +// point defined in that library (fatal error LNK1561: entry point +// must be defined). This dummy test keeps gtest_main linked in. TEST(DummyTest, TypedTestsAreNotSupportedOnThisPlatform) {} #endif // #if !defined(GTEST_HAS_TYPED_TEST) && !defined(GTEST_HAS_TYPED_TEST_P) diff --git a/test/gtest_output_test.py b/test/gtest_output_test.py index 125970aa..192030a2 100755 --- a/test/gtest_output_test.py +++ b/test/gtest_output_test.py @@ -282,7 +282,7 @@ class GTestOutputTest(gtest_test_utils.TestCase): normalized_golden = RemoveTypeInfoDetails(golden) if CAN_GENERATE_GOLDEN_FILE: - self.assert_(normalized_golden == normalized_actual) + self.assertEqual(normalized_golden, normalized_actual) else: normalized_actual = RemoveTestCounts(normalized_actual) normalized_golden = RemoveTestCounts(self.RemoveUnsupportedTests( @@ -299,7 +299,7 @@ class GTestOutputTest(gtest_test_utils.TestCase): '_gtest_output_test_normalized_golden.txt'), 'wb').write( normalized_golden) - self.assert_(normalized_golden == normalized_actual) + self.assertEqual(normalized_golden, normalized_actual) if __name__ == '__main__': diff --git a/test/gtest_output_test_.cc b/test/gtest_output_test_.cc index 6d756027..273e8e93 100644 --- a/test/gtest_output_test_.cc +++ b/test/gtest_output_test_.cc @@ -46,15 +46,17 @@ #include -#if GTEST_HAS_PTHREAD -#include -#endif // GTEST_HAS_PTHREAD - +#if GTEST_IS_THREADSAFE using testing::ScopedFakeTestPartResultReporter; using testing::TestPartResultArray; +using testing::internal::Notification; +using testing::internal::ThreadWithParam; +#endif + namespace posix = ::testing::internal::posix; using testing::internal::String; +using testing::internal::scoped_ptr; // Tests catching fatal failures. @@ -214,6 +216,83 @@ TEST(SCOPED_TRACETest, CanBeRepeated) { << "trace point A, B, and D."; } +#if GTEST_IS_THREADSAFE +// Tests that SCOPED_TRACE()s can be used concurrently from multiple +// threads. Namely, an assertion should be affected by +// SCOPED_TRACE()s in its own thread only. + +// Here's the sequence of actions that happen in the test: +// +// Thread A (main) | Thread B (spawned) +// ===============================|================================ +// spawns thread B | +// -------------------------------+-------------------------------- +// waits for n1 | SCOPED_TRACE("Trace B"); +// | generates failure #1 +// | notifies n1 +// -------------------------------+-------------------------------- +// SCOPED_TRACE("Trace A"); | waits for n2 +// generates failure #2 | +// notifies n2 | +// -------------------------------|-------------------------------- +// waits for n3 | generates failure #3 +// | trace B dies +// | generates failure #4 +// | notifies n3 +// -------------------------------|-------------------------------- +// generates failure #5 | finishes +// trace A dies | +// generates failure #6 | +// -------------------------------|-------------------------------- +// waits for thread B to finish | + +struct CheckPoints { + Notification n1; + Notification n2; + Notification n3; +}; + +static void ThreadWithScopedTrace(CheckPoints* check_points) { + { + SCOPED_TRACE("Trace B"); + ADD_FAILURE() + << "Expected failure #1 (in thread B, only trace B alive)."; + check_points->n1.Notify(); + check_points->n2.WaitForNotification(); + + ADD_FAILURE() + << "Expected failure #3 (in thread B, trace A & B both alive)."; + } // Trace B dies here. + ADD_FAILURE() + << "Expected failure #4 (in thread B, only trace A alive)."; + check_points->n3.Notify(); +} + +TEST(SCOPED_TRACETest, WorksConcurrently) { + printf("(expecting 6 failures)\n"); + + CheckPoints check_points; + ThreadWithParam thread(&ThreadWithScopedTrace, + &check_points, + NULL); + check_points.n1.WaitForNotification(); + + { + SCOPED_TRACE("Trace A"); + ADD_FAILURE() + << "Expected failure #2 (in thread A, trace A & B both alive)."; + check_points.n2.Notify(); + check_points.n3.WaitForNotification(); + + ADD_FAILURE() + << "Expected failure #5 (in thread A, only trace A alive)."; + } // Trace A dies here. + ADD_FAILURE() + << "Expected failure #6 (in thread A, no trace alive)."; + thread.Join(); +} +#endif // GTEST_IS_THREADSAFE + TEST(DisabledTestsWarningTest, DISABLED_AlsoRunDisabledTestsFlagSuppressesWarning) { // This test body is intentionally empty. Its sole purpose is for @@ -479,6 +558,63 @@ TEST_F(ExceptionInTearDownTest, ExceptionInTearDown) { #endif // GTEST_OS_WINDOWS +#if GTEST_IS_THREADSAFE + +// A unary function that may die. +void DieIf(bool should_die) { + GTEST_CHECK_(!should_die) << " - death inside DieIf()."; +} + +// Tests running death tests in a multi-threaded context. + +// Used for coordination between the main and the spawn thread. +struct SpawnThreadNotifications { + SpawnThreadNotifications() {} + + Notification spawn_thread_started; + Notification spawn_thread_ok_to_terminate; + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(SpawnThreadNotifications); +}; + +// The function to be executed in the thread spawn by the +// MultipleThreads test (below). +static void ThreadRoutine(SpawnThreadNotifications* notifications) { + // Signals the main thread that this thread has started. + notifications->spawn_thread_started.Notify(); + + // Waits for permission to finish from the main thread. + notifications->spawn_thread_ok_to_terminate.WaitForNotification(); +} + +// This is a death-test test, but it's not named with a DeathTest +// suffix. It starts threads which might interfere with later +// death tests, so it must run after all other death tests. +class DeathTestAndMultiThreadsTest : public testing::Test { + protected: + // Starts a thread and waits for it to begin. + virtual void SetUp() { + thread_.reset(new ThreadWithParam( + &ThreadRoutine, ¬ifications_, NULL)); + notifications_.spawn_thread_started.WaitForNotification(); + } + // Tells the thread to finish, and reaps it. + // Depending on the version of the thread library in use, + // a manager thread might still be left running that will interfere + // with later death tests. This is unfortunate, but this class + // cleans up after itself as best it can. + virtual void TearDown() { + notifications_.spawn_thread_ok_to_terminate.Notify(); + } + + private: + SpawnThreadNotifications notifications_; + scoped_ptr > thread_; +}; + +#endif // GTEST_IS_THREADSAFE + // The MixedUpTestCaseTest test case verifies that Google Test will fail a // test if it uses a different fixture class than what other tests in // the same test case use. It deliberately contains two fixture @@ -849,23 +985,13 @@ TEST_F(ExpectFailureTest, ExpectNonFatalFailure) { "failure."); } -#if GTEST_IS_THREADSAFE && GTEST_HAS_PTHREAD +#if GTEST_IS_THREADSAFE class ExpectFailureWithThreadsTest : public ExpectFailureTest { protected: static void AddFailureInOtherThread(FailureMode failure) { - pthread_t tid; - pthread_create(&tid, - NULL, - ExpectFailureWithThreadsTest::FailureThread, - &failure); - pthread_join(tid, NULL); - } - private: - static void* FailureThread(void* attr) { - FailureMode* failure = static_cast(attr); - AddFailure(*failure); - return NULL; + ThreadWithParam thread(&AddFailure, failure, NULL); + thread.Join(); } }; @@ -901,7 +1027,7 @@ TEST_F(ScopedFakeTestPartResultReporterTest, InterceptOnlyCurrentThread) { EXPECT_EQ(0, results.size()) << "This shouldn't fail."; } -#endif // GTEST_IS_THREADSAFE && GTEST_HAS_PTHREAD +#endif // GTEST_IS_THREADSAFE TEST_F(ExpectFailureTest, ExpectFatalFailureOnAllThreads) { // Expected fatal failure, but succeeds. diff --git a/test/gtest_output_test_golden_lin.txt b/test/gtest_output_test_golden_lin.txt index 4d67bd62..ec60437a 100644 --- a/test/gtest_output_test_golden_lin.txt +++ b/test/gtest_output_test_golden_lin.txt @@ -7,7 +7,7 @@ Expected: true gtest_output_test_.cc:#: Failure Value of: 3 Expected: 2 -[==========] Running 59 tests from 25 test cases. +[==========] Running 60 tests from 25 test cases. [----------] Global test environment set-up. FooEnvironment::SetUp() called. BarEnvironment::SetUp() called. @@ -65,7 +65,7 @@ i == 3 gtest_output_test_.cc:#: Failure Expected: (3) >= (a[i]), actual: 3 vs 6 [ FAILED ] LoggingTest.InterleavingLoggingAndAssertions -[----------] 5 tests from SCOPED_TRACETest +[----------] 6 tests from SCOPED_TRACETest [ RUN ] SCOPED_TRACETest.ObeysScopes (expected to fail) gtest_output_test_.cc:#: Failure @@ -148,6 +148,35 @@ gtest_output_test_.cc:#: D gtest_output_test_.cc:#: B gtest_output_test_.cc:#: A [ FAILED ] SCOPED_TRACETest.CanBeRepeated +[ RUN ] SCOPED_TRACETest.WorksConcurrently +(expecting 6 failures) +gtest_output_test_.cc:#: Failure +Failed +Expected failure #1 (in thread B, only trace B alive). +Google Test trace: +gtest_output_test_.cc:#: Trace B +gtest_output_test_.cc:#: Failure +Failed +Expected failure #2 (in thread A, trace A & B both alive). +Google Test trace: +gtest_output_test_.cc:#: Trace A +gtest_output_test_.cc:#: Failure +Failed +Expected failure #3 (in thread B, trace A & B both alive). +Google Test trace: +gtest_output_test_.cc:#: Trace B +gtest_output_test_.cc:#: Failure +Failed +Expected failure #4 (in thread B, only trace A alive). +gtest_output_test_.cc:#: Failure +Failed +Expected failure #5 (in thread A, only trace A alive). +Google Test trace: +gtest_output_test_.cc:#: Trace A +gtest_output_test_.cc:#: Failure +Failed +Expected failure #6 (in thread A, no trace alive). +[ FAILED ] SCOPED_TRACETest.WorksConcurrently [----------] 1 test from NonFatalFailureInFixtureConstructorTest [ RUN ] NonFatalFailureInFixtureConstructorTest.FailureInConstructor (expecting 5 failures) @@ -544,9 +573,9 @@ FooEnvironment::TearDown() called. gtest_output_test_.cc:#: Failure Failed Expected fatal failure. -[==========] 59 tests from 25 test cases ran. +[==========] 60 tests from 25 test cases ran. [ PASSED ] 21 tests. -[ FAILED ] 38 tests, listed below: +[ FAILED ] 39 tests, listed below: [ FAILED ] FatalFailureTest.FatalFailureInSubroutine [ FAILED ] FatalFailureTest.FatalFailureInNestedSubroutine [ FAILED ] FatalFailureTest.NonfatalFailureInSubroutine @@ -556,6 +585,7 @@ Expected fatal failure. [ FAILED ] SCOPED_TRACETest.WorksInSubroutine [ FAILED ] SCOPED_TRACETest.CanBeNested [ FAILED ] SCOPED_TRACETest.CanBeRepeated +[ FAILED ] SCOPED_TRACETest.WorksConcurrently [ FAILED ] NonFatalFailureInFixtureConstructorTest.FailureInConstructor [ FAILED ] FatalFailureInFixtureConstructorTest.FailureInConstructor [ FAILED ] NonFatalFailureInSetUpTest.FailureInSetUp @@ -586,7 +616,7 @@ Expected fatal failure. [ FAILED ] ExpectFailureWithThreadsTest.ExpectNonFatalFailure [ FAILED ] ScopedFakeTestPartResultReporterTest.InterceptOnlyCurrentThread -38 FAILED TESTS +39 FAILED TESTS  YOU HAVE 1 DISABLED TEST Note: Google Test filter = FatalFailureTest.*:LoggingTest.* diff --git a/test/gtest_stress_test.cc b/test/gtest_stress_test.cc index 01f4fc6f..f5af78cc 100644 --- a/test/gtest_stress_test.cc +++ b/test/gtest_stress_test.cc @@ -49,16 +49,15 @@ namespace testing { namespace { -using internal::scoped_ptr; +using internal::Notification; using internal::String; using internal::TestPropertyKeyIs; -using internal::ThreadStartSemaphore; using internal::ThreadWithParam; +using internal::scoped_ptr; // In order to run tests in this file, for platforms where Google Test is -// thread safe, implement ThreadWithParam and ThreadStartSemaphore. See the -// description of their API in gtest-port.h, where they are defined for -// already supported platforms. +// thread safe, implement ThreadWithParam. See the description of its API +// in gtest-port.h, where it is defined for already supported platforms. // How many threads to create? const int kThreadCount = 50; @@ -129,11 +128,13 @@ void CheckTestFailureCount(int expected_failures) { TEST(StressTest, CanUseScopedTraceAndAssertionsInManyThreads) { { scoped_ptr > threads[kThreadCount]; - ThreadStartSemaphore semaphore; + Notification threads_can_start; for (int i = 0; i != kThreadCount; i++) - threads[i].reset(new ThreadWithParam(&ManyAsserts, i, &semaphore)); + threads[i].reset(new ThreadWithParam(&ManyAsserts, + i, + &threads_can_start)); - semaphore.Signal(); // Starts all the threads. + threads_can_start.Notify(); // Blocks until all the threads are done. for (int i = 0; i != kThreadCount; i++) diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index bc190e1e..d5a6f302 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -71,10 +71,6 @@ TEST(CommandLineFlagsTest, CanBeAccessedInCodeOnceGTestHIsIncluded) { #include #include -#if GTEST_HAS_PTHREAD -#include -#endif // GTEST_HAS_PTHREAD - #include namespace testing { @@ -191,6 +187,10 @@ using testing::internal::CaptureStdout; using testing::internal::GetCapturedStdout; #endif // GTEST_HAS_STREAM_REDIRECTION_ +#if GTEST_IS_THREADSAFE +using testing::internal::ThreadWithParam; +#endif + class TestingVector : public std::vector { }; @@ -1283,25 +1283,14 @@ TEST_F(ScopedFakeTestPartResultReporterTest, DeprecatedConstructor) { EXPECT_EQ(1, results.size()); } -#if GTEST_IS_THREADSAFE && GTEST_HAS_PTHREAD +#if GTEST_IS_THREADSAFE class ScopedFakeTestPartResultReporterWithThreadsTest : public ScopedFakeTestPartResultReporterTest { protected: static void AddFailureInOtherThread(FailureMode failure) { - pthread_t tid; - pthread_create(&tid, - NULL, - ScopedFakeTestPartResultReporterWithThreadsTest:: - FailureThread, - &failure); - pthread_join(tid, NULL); - } - private: - static void* FailureThread(void* attr) { - FailureMode* failure = static_cast(attr); - AddFailure(*failure); - return NULL; + ThreadWithParam thread(&AddFailure, failure, NULL); + thread.Join(); } }; @@ -1324,7 +1313,7 @@ TEST_F(ScopedFakeTestPartResultReporterWithThreadsTest, EXPECT_TRUE(results.GetTestPartResult(3).fatally_failed()); } -#endif // GTEST_IS_THREADSAFE && GTEST_HAS_PTHREAD +#endif // GTEST_IS_THREADSAFE // Tests EXPECT_FATAL_FAILURE{,ON_ALL_THREADS}. Makes sure that they // work even if the failure is generated in a called function rather than @@ -1435,7 +1424,7 @@ TEST_F(ExpectNonfatalFailureTest, AcceptsMacroThatExpandsToUnprotectedComma) { }, ""); } -#if GTEST_IS_THREADSAFE && GTEST_HAS_PTHREAD +#if GTEST_IS_THREADSAFE typedef ScopedFakeTestPartResultReporterWithThreadsTest ExpectFailureWithThreadsTest; @@ -1450,7 +1439,7 @@ TEST_F(ExpectFailureWithThreadsTest, ExpectNonFatalFailureOnAllThreads) { AddFailureInOtherThread(NONFATAL_FAILURE), "Expected non-fatal failure."); } -#endif // GTEST_IS_THREADSAFE && GTEST_HAS_PTHREAD +#endif // GTEST_IS_THREADSAFE // Tests the TestProperty class. -- cgit v1.2.3 From 83589cca345d2f03d93b0555437aa480e0ed6699 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Fri, 5 Mar 2010 21:21:06 +0000 Subject: Supports building gtest as a DLL (by Vlad Losev). --- test/gtest_dll_test_.cc | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) (limited to 'test') diff --git a/test/gtest_dll_test_.cc b/test/gtest_dll_test_.cc index 3fb61812..3bb3c76f 100644 --- a/test/gtest_dll_test_.cc +++ b/test/gtest_dll_test_.cc @@ -29,21 +29,24 @@ // Author: vladl@google.com (Vlad Losev) // // Tests for Google Test itself. This verifies that Google Test can be -// linked into an executable successfully when built as a DLL on Windows. -// The test is not meant to check the success of test assertions employed in -// it. It only checks that constructs in them can be successfully linked. +// linked into an executable successfully when built as a shared library (a +// DLL on Windows). The test is not meant to check the success of test +// assertions employed in it. It only checks that constructs in them can be +// successfully linked. // // If you add new features to Google Test's documented interface, you need to // add tests exercising them to this file. // // If you start having 'unresolved external symbol' linker errors in this file -// after the changes you have made, re-generate src/gtest.def by running -// scripts/generate_gtest_def.py. +// after the changes you have made, you have to modify your source code to +// export the new symbols. #include #include +#if GTEST_OS_WINDOWS #include +#endif #include using ::std::vector; @@ -297,18 +300,20 @@ TEST(FloatingPointComparisonAssertionTest, LinksSuccessfully) { EXPECT_PRED_FORMAT2(::testing::DoubleLE, 0.0, 0.001); } +#if GTEST_OS_WINDOWS // Tests linking of HRESULT assertions. TEST(HresultAssertionTest, LinksSuccessfully) { EXPECT_HRESULT_SUCCEEDED(S_OK); EXPECT_HRESULT_FAILED(E_FAIL); } +#endif // GTEST_OS_WINDOWS #if GTEST_HAS_EXCEPTIONS // Tests linking of exception assertions. TEST(ExceptionAssertionTest, LinksSuccessfully) { EXPECT_THROW(throw 1, int); EXPECT_ANY_THROW(throw 1); - EXPECT_NO_THROW(int x = 1); + EXPECT_NO_THROW(std::vector v); } #endif // GTEST_HAS_EXCEPTIONS @@ -498,6 +503,7 @@ int main(int argc, char **argv) { listener = listeners.default_result_printer(); listener = listeners.default_xml_generator(); - RUN_ALL_TESTS(); + int ret_val = RUN_ALL_TESTS(); + static_cast(ret_val); return 0; } -- cgit v1.2.3 From 79e11d7c7d17e6f893467656815a79d8e84dd7c3 Mon Sep 17 00:00:00 2001 From: vladlosev Date: Fri, 5 Mar 2010 22:17:25 +0000 Subject: Adds a smoketest for ThreadWithParam. --- test/gtest-port_test.cc | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'test') diff --git a/test/gtest-port_test.cc b/test/gtest-port_test.cc index 1588bd46..577f6099 100644 --- a/test/gtest-port_test.cc +++ b/test/gtest-port_test.cc @@ -795,6 +795,16 @@ TEST(ThreadLocalTest, PointerAndConstPointerReturnSameValue) { } #if GTEST_IS_THREADSAFE + +void AddTwo(int* param) { *param += 2; } + +TEST(ThreadWithParamTest, ConstructorExecutesThreadFunc) { + int i = 40; + ThreadWithParam thread(&AddTwo, &i, NULL); + thread.Join(); + EXPECT_EQ(42, i); +} + TEST(MutexDeathTest, AssertHeldShouldAssertWhenNotLocked) { // AssertHeld() is flaky only in the presence of multiple threads accessing // the lock. In this case, the test is robust. -- cgit v1.2.3 From 40604f891efd16779af66c2b3e42f433ead74b15 Mon Sep 17 00:00:00 2001 From: vladlosev Date: Mon, 8 Mar 2010 20:42:47 +0000 Subject: Fixes an 'unreachable code' warning by MSVC on certain opt settings in gtest-death-test_test.cc. --- test/gtest-death-test_test.cc | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'test') diff --git a/test/gtest-death-test_test.cc b/test/gtest-death-test_test.cc index c57d700f..ed5b53b7 100644 --- a/test/gtest-death-test_test.cc +++ b/test/gtest-death-test_test.cc @@ -110,7 +110,12 @@ void DieInside(const char* function) { // system call and thus safer in the presence of threads. exit() // will invoke user-defined exit-hooks, which may do dangerous // things that conflict with death tests. - _exit(1); + // + // Some compilers can recognize that _exit() never returns and issue the + // 'unreachable code' warning for code following this function, unless + // fooled by a fake condition. + if (AlwaysTrue()) + _exit(1); } // Tests that death tests work. -- cgit v1.2.3 From 06d04c0945bf47bae90532552e6e8294802fc9aa Mon Sep 17 00:00:00 2001 From: vladlosev Date: Wed, 17 Mar 2010 18:22:59 +0000 Subject: Solaris and AIX patch by Hady Zalek --- test/gtest_unittest.cc | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) (limited to 'test') diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index d5a6f302..bd10ae0d 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -296,8 +296,7 @@ TEST(FormatTimeInMillisAsSecondsTest, FormatsNegativeNumber) { EXPECT_EQ("-3", FormatTimeInMillisAsSeconds(-3000)); } -#if !GTEST_OS_SYMBIAN -// NULL testing does not work with Symbian compilers. +#if GTEST_CAN_COMPARE_NULL #ifdef __BORLANDC__ // Silences warnings: "Condition is always true", "Unreachable code" @@ -335,7 +334,7 @@ TEST(NullLiteralTest, IsFalseForNonNullLiterals) { #pragma option pop #endif -#endif // !GTEST_OS_SYMBIAN +#endif // GTEST_CAN_COMPARE_NULL // // Tests CodePointToUtf8(). @@ -3559,10 +3558,7 @@ TEST(AssertionTest, ASSERT_EQ) { } // Tests ASSERT_EQ(NULL, pointer). -#if !GTEST_OS_SYMBIAN -// The NULL-detection template magic fails to compile with -// the Nokia compiler and crashes the ARM compiler, hence -// not testing on Symbian. +#if GTEST_CAN_COMPARE_NULL TEST(AssertionTest, ASSERT_EQ_NULL) { // A success. const char* p = NULL; @@ -3577,7 +3573,7 @@ TEST(AssertionTest, ASSERT_EQ_NULL) { EXPECT_FATAL_FAILURE(ASSERT_EQ(NULL, &n), "Value of: &n\n"); } -#endif // !GTEST_OS_SYMBIAN +#endif // GTEST_CAN_COMPARE_NULL // Tests ASSERT_EQ(0, non_pointer). Since the literal 0 can be // treated as a null pointer by the compiler, we need to make sure @@ -4141,7 +4137,7 @@ TEST(ExpectTest, EXPECT_EQ_Double) { "5.1"); } -#if !GTEST_OS_SYMBIAN +#if GTEST_CAN_COMPARE_NULL // Tests EXPECT_EQ(NULL, pointer). TEST(ExpectTest, EXPECT_EQ_NULL) { // A success. @@ -4157,7 +4153,7 @@ TEST(ExpectTest, EXPECT_EQ_NULL) { EXPECT_NONFATAL_FAILURE(EXPECT_EQ(NULL, &n), "Value of: &n\n"); } -#endif // !GTEST_OS_SYMBIAN +#endif // GTEST_CAN_COMPARE_NULL // Tests EXPECT_EQ(0, non_pointer). Since the literal 0 can be // treated as a null pointer by the compiler, we need to make sure -- cgit v1.2.3 From 90030d74c8cacbdab62136daa465a7ef359e2adc Mon Sep 17 00:00:00 2001 From: vladlosev Date: Sat, 20 Mar 2010 12:33:48 +0000 Subject: Fixes comments and tests for the moment of generator parameter evaluation in INSTANTIATE_TEST_CASE_P. --- test/gtest-param-test_test.cc | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) (limited to 'test') diff --git a/test/gtest-param-test_test.cc b/test/gtest-param-test_test.cc index 0288b6a7..d0a0e735 100644 --- a/test/gtest-param-test_test.cc +++ b/test/gtest-param-test_test.cc @@ -692,13 +692,15 @@ INSTANTIATE_TEST_CASE_P(TestExpansionModule, TestGenerationTest, ValuesIn(test_generation_params)); // This test verifies that the element sequence (third parameter of -// INSTANTIATE_TEST_CASE_P) is evaluated in RUN_ALL_TESTS and not at the call -// site of INSTANTIATE_TEST_CASE_P. -// For that, we declare param_value_ to be a static member of -// GeneratorEvaluationTest and initialize it to 0. We set it to 1 in main(), -// just before invocation of RUN_ALL_TESTS. If the sequence is evaluated -// before that moment, INSTANTIATE_TEST_CASE_P will create a test with -// parameter 0, and the test body will fail the assertion. +// INSTANTIATE_TEST_CASE_P) is evaluated in InitGoogleTest() and neither at +// the call site of INSTANTIATE_TEST_CASE_P nor in RUN_ALL_TESTS(). For +// that, we declare param_value_ to be a static member of +// GeneratorEvaluationTest and initialize it to 0. We set it to 1 in +// main(), just before invocation of InitGoogleTest(). After calling +// InitGoogleTest(), we set the value to 2. If the sequence is evaluated +// before or after InitGoogleTest, INSTANTIATE_TEST_CASE_P will create a +// test with parameter other than 1, and the test body will fail the +// assertion. class GeneratorEvaluationTest : public TestWithParam { public: static int param_value() { return param_value_; } @@ -815,10 +817,19 @@ int main(int argc, char **argv) { #if GTEST_HAS_PARAM_TEST // Used in TestGenerationTest test case. AddGlobalTestEnvironment(TestGenerationTest::Environment::Instance()); - // Used in GeneratorEvaluationTest test case. + // Used in GeneratorEvaluationTest test case. Tests that the updated value + // will be picked up for instantiating tests in GeneratorEvaluationTest. GeneratorEvaluationTest::set_param_value(1); #endif // GTEST_HAS_PARAM_TEST ::testing::InitGoogleTest(&argc, argv); + +#if GTEST_HAS_PARAM_TEST + // Used in GeneratorEvaluationTest test case. Tests that value updated + // here will NOT be used for instantiating tests in + // GeneratorEvaluationTest. + GeneratorEvaluationTest::set_param_value(2); +#endif // GTEST_HAS_PARAM_TEST + return RUN_ALL_TESTS(); } -- cgit v1.2.3 From 9f0824b0a61b50fd40e47da2387cd9b3f872ce47 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Mon, 22 Mar 2010 21:23:51 +0000 Subject: Adds missing gtest DLL exports. --- test/gtest-filepath_test.cc | 2 - test/gtest-options_test.cc | 139 ++++-------- test/gtest_all_test.cc | 1 + test/gtest_color_test_.cc | 13 +- test/gtest_dll_test_.cc | 509 -------------------------------------------- test/gtest_unittest.cc | 7 - 6 files changed, 51 insertions(+), 620 deletions(-) delete mode 100644 test/gtest_dll_test_.cc (limited to 'test') diff --git a/test/gtest-filepath_test.cc b/test/gtest-filepath_test.cc index c5f58f42..62502827 100644 --- a/test/gtest-filepath_test.cc +++ b/test/gtest-filepath_test.cc @@ -688,5 +688,3 @@ TEST(FilePathTest, IsRootDirectory) { } // namespace } // namespace internal } // namespace testing - -#undef GTEST_PATH_SEP_ diff --git a/test/gtest-options_test.cc b/test/gtest-options_test.cc index 31ae3277..2e2cbc92 100644 --- a/test/gtest-options_test.cc +++ b/test/gtest-options_test.cc @@ -89,61 +89,38 @@ TEST(XmlOutputTest, GetOutputFileSingleFile) { } TEST(XmlOutputTest, GetOutputFileFromDirectoryPath) { -#if GTEST_OS_WINDOWS - GTEST_FLAG(output) = "xml:path\\"; + GTEST_FLAG(output) = "xml:path" GTEST_PATH_SEP_; + const std::string expected_output_file = + GetAbsolutePathOf( + FilePath(std::string("path") + GTEST_PATH_SEP_ + + GetCurrentExecutableName().c_str() + ".xml")).c_str(); const String& output_file = UnitTestOptions::GetAbsolutePathToOutputFile(); - EXPECT_TRUE( - _strcmpi(output_file.c_str(), - GetAbsolutePathOf( - FilePath("path\\gtest-options_test.xml")).c_str()) == 0 || - _strcmpi(output_file.c_str(), - GetAbsolutePathOf( - FilePath("path\\gtest-options-ex_test.xml")).c_str()) == 0 || - _strcmpi(output_file.c_str(), - GetAbsolutePathOf( - FilePath("path\\gtest_all_test.xml")).c_str()) == 0) - << " output_file = " << output_file; +#if GTEST_OS_WINDOWS + EXPECT_STRCASEEQ(expected_output_file.c_str(), output_file.c_str()); #else - GTEST_FLAG(output) = "xml:path/"; - const String& output_file = UnitTestOptions::GetAbsolutePathToOutputFile(); - // TODO(wan@google.com): libtool causes the test binary file to be - // named lt-gtest-options_test. Therefore the output file may be - // named .../lt-gtest-options_test.xml. We should remove this - // hard-coded logic when Chandler Carruth's libtool replacement is - // ready. - EXPECT_TRUE(output_file == - GetAbsolutePathOf( - FilePath("path/gtest-options_test.xml")).c_str() || - output_file == - GetAbsolutePathOf( - FilePath("path/lt-gtest-options_test.xml")).c_str() || - output_file == - GetAbsolutePathOf( - FilePath("path/gtest_all_test.xml")).c_str() || - output_file == - GetAbsolutePathOf( - FilePath("path/lt-gtest_all_test.xml")).c_str()) - << " output_file = " << output_file; + EXPECT_EQ(expected_output_file, output_file.c_str()); #endif } TEST(OutputFileHelpersTest, GetCurrentExecutableName) { - const FilePath executable = GetCurrentExecutableName(); - const char* const exe_str = executable.c_str(); + const std::string exe_str = GetCurrentExecutableName().c_str(); #if GTEST_OS_WINDOWS - ASSERT_TRUE(_strcmpi("gtest-options_test", exe_str) == 0 || - _strcmpi("gtest-options-ex_test", exe_str) == 0 || - _strcmpi("gtest_all_test", exe_str) == 0) - << "GetCurrentExecutableName() returns " << exe_str; + const bool success = + _strcmpi("gtest-options_test", exe_str.c_str()) == 0 || + _strcmpi("gtest-options-ex_test", exe_str.c_str()) == 0 || + _strcmpi("gtest_all_test", exe_str.c_str()) == 0 || + _strcmpi("gtest_dll_test", exe_str.c_str()) == 0; #else // TODO(wan@google.com): remove the hard-coded "lt-" prefix when // Chandler Carruth's libtool replacement is ready. - EXPECT_TRUE(String(exe_str) == "gtest-options_test" || - String(exe_str) == "lt-gtest-options_test" || - String(exe_str) == "gtest_all_test" || - String(exe_str) == "lt-gtest_all_test") - << "GetCurrentExecutableName() returns " << exe_str; + const bool success = + exe_str == "gtest-options_test" || + exe_str == "gtest_all_test" || + exe_str == "lt-gtest_all_test" || + exe_str == "gtest_dll_test"; #endif // GTEST_OS_WINDOWS + if (!success) + FAIL() << "GetCurrentExecutableName() returns " << exe_str; } class XmlOutputChangeDirTest : public Test { @@ -185,40 +162,17 @@ TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithRelativeFile) { } TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithRelativePath) { -#if GTEST_OS_WINDOWS - GTEST_FLAG(output) = "xml:path\\"; + GTEST_FLAG(output) = "xml:path" GTEST_PATH_SEP_; + const std::string expected_output_file = + FilePath::ConcatPaths( + original_working_dir_, + FilePath(std::string("path") + GTEST_PATH_SEP_ + + GetCurrentExecutableName().c_str() + ".xml")).c_str(); const String& output_file = UnitTestOptions::GetAbsolutePathToOutputFile(); - EXPECT_TRUE( - _strcmpi(output_file.c_str(), - FilePath::ConcatPaths( - original_working_dir_, - FilePath("path\\gtest-options_test.xml")).c_str()) == 0 || - _strcmpi(output_file.c_str(), - FilePath::ConcatPaths( - original_working_dir_, - FilePath("path\\gtest-options-ex_test.xml")).c_str()) == 0 || - _strcmpi(output_file.c_str(), - FilePath::ConcatPaths( - original_working_dir_, - FilePath("path\\gtest_all_test.xml")).c_str()) == 0) - << " output_file = " << output_file; +#if GTEST_OS_WINDOWS + EXPECT_STRCASEEQ(expected_output_file.c_str(), output_file.c_str()); #else - GTEST_FLAG(output) = "xml:path/"; - const String& output_file = UnitTestOptions::GetAbsolutePathToOutputFile(); - // TODO(wan@google.com): libtool causes the test binary file to be - // named lt-gtest-options_test. Therefore the output file may be - // named .../lt-gtest-options_test.xml. We should remove this - // hard-coded logic when Chandler Carruth's libtool replacement is - // ready. - EXPECT_TRUE(output_file == FilePath::ConcatPaths(original_working_dir_, - FilePath("path/gtest-options_test.xml")).c_str() || - output_file == FilePath::ConcatPaths(original_working_dir_, - FilePath("path/lt-gtest-options_test.xml")).c_str() || - output_file == FilePath::ConcatPaths(original_working_dir_, - FilePath("path/gtest_all_test.xml")).c_str() || - output_file == FilePath::ConcatPaths(original_working_dir_, - FilePath("path/lt-gtest_all_test.xml")).c_str()) - << " output_file = " << output_file; + EXPECT_EQ(expected_output_file, output_file.c_str()); #endif } @@ -236,29 +190,20 @@ TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithAbsoluteFile) { TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithAbsolutePath) { #if GTEST_OS_WINDOWS - GTEST_FLAG(output) = "xml:c:\\tmp\\"; - const String& output_file = UnitTestOptions::GetAbsolutePathToOutputFile(); - EXPECT_TRUE( - _strcmpi(output_file.c_str(), - FilePath("c:\\tmp\\gtest-options_test.xml").c_str()) == 0 || - _strcmpi(output_file.c_str(), - FilePath("c:\\tmp\\gtest-options-ex_test.xml").c_str()) == 0 || - _strcmpi(output_file.c_str(), - FilePath("c:\\tmp\\gtest_all_test.xml").c_str()) == 0) - << " output_file = " << output_file; + const std::string path = "c:\\tmp\\"; #else - GTEST_FLAG(output) = "xml:/tmp/"; + const std::string path = "/tmp/"; +#endif + + GTEST_FLAG(output) = "xml:" + path; + const std::string expected_output_file = + path + GetCurrentExecutableName().c_str() + ".xml"; const String& output_file = UnitTestOptions::GetAbsolutePathToOutputFile(); - // TODO(wan@google.com): libtool causes the test binary file to be - // named lt-gtest-options_test. Therefore the output file may be - // named .../lt-gtest-options_test.xml. We should remove this - // hard-coded logic when Chandler Carruth's libtool replacement is - // ready. - EXPECT_TRUE(output_file == "/tmp/gtest-options_test.xml" || - output_file == "/tmp/lt-gtest-options_test.xml" || - output_file == "/tmp/gtest_all_test.xml" || - output_file == "/tmp/lt-gtest_all_test.xml") - << " output_file = " << output_file; + +#if GTEST_OS_WINDOWS + EXPECT_STRCASEEQ(expected_output_file.c_str(), output_file.c_str()); +#else + EXPECT_EQ(expected_output_file, output_file.c_str()); #endif } diff --git a/test/gtest_all_test.cc b/test/gtest_all_test.cc index 955aa628..e1edb08e 100644 --- a/test/gtest_all_test.cc +++ b/test/gtest_all_test.cc @@ -45,3 +45,4 @@ #include "test/gtest-typed-test2_test.cc" #include "test/gtest_unittest.cc" #include "test/production.cc" +#include "src/gtest_main.cc" diff --git a/test/gtest_color_test_.cc b/test/gtest_color_test_.cc index 305aeb96..58d377c9 100644 --- a/test/gtest_color_test_.cc +++ b/test/gtest_color_test_.cc @@ -37,11 +37,14 @@ #include -namespace testing { -namespace internal { -bool ShouldUseColor(bool stdout_is_tty); -} // namespace internal -} // namespace testing +// Indicates that this translation unit is part of Google Test's +// implementation. It must come before gtest-internal-inl.h is +// included, or there will be a compiler error. This trick is to +// prevent a user from accidentally including gtest-internal-inl.h in +// his code. +#define GTEST_IMPLEMENTATION_ 1 +#include "src/gtest-internal-inl.h" +#undef GTEST_IMPLEMENTATION_ using testing::internal::ShouldUseColor; diff --git a/test/gtest_dll_test_.cc b/test/gtest_dll_test_.cc deleted file mode 100644 index 3bb3c76f..00000000 --- a/test/gtest_dll_test_.cc +++ /dev/null @@ -1,509 +0,0 @@ -// Copyright 2009 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: vladl@google.com (Vlad Losev) -// -// Tests for Google Test itself. This verifies that Google Test can be -// linked into an executable successfully when built as a shared library (a -// DLL on Windows). The test is not meant to check the success of test -// assertions employed in it. It only checks that constructs in them can be -// successfully linked. -// -// If you add new features to Google Test's documented interface, you need to -// add tests exercising them to this file. -// -// If you start having 'unresolved external symbol' linker errors in this file -// after the changes you have made, you have to modify your source code to -// export the new symbols. - -#include -#include - -#if GTEST_OS_WINDOWS -#include -#endif -#include - -using ::std::vector; -using ::std::tr1::tuple; - - -using ::testing::AddGlobalTestEnvironment; -using ::testing::AssertionFailure; -using ::testing::AssertionResult; -using ::testing::AssertionSuccess; -using ::testing::DoubleLE; -using ::testing::EmptyTestEventListener; -using ::testing::Environment; -using ::testing::ExitedWithCode; -using ::testing::FloatLE; -using ::testing::GTEST_FLAG(also_run_disabled_tests); -using ::testing::GTEST_FLAG(break_on_failure); -using ::testing::GTEST_FLAG(catch_exceptions); -using ::testing::GTEST_FLAG(color); -using ::testing::GTEST_FLAG(filter); -using ::testing::GTEST_FLAG(output); -using ::testing::GTEST_FLAG(print_time); -using ::testing::GTEST_FLAG(random_seed); -using ::testing::GTEST_FLAG(repeat); -using ::testing::GTEST_FLAG(shuffle); -using ::testing::GTEST_FLAG(stack_trace_depth); -using ::testing::GTEST_FLAG(throw_on_failure); -using ::testing::InitGoogleTest; -using ::testing::Message; -using ::testing::Test; -using ::testing::TestCase; -using ::testing::TestEventListener; -using ::testing::TestEventListeners; -using ::testing::TestInfo; -using ::testing::TestPartResult; -using ::testing::TestProperty; -using ::testing::TestResult; -using ::testing::UnitTest; -using ::testing::internal::AlwaysTrue; -using ::testing::internal::AlwaysFalse; - -#if GTEST_HAS_PARAM_TEST -using ::testing::Bool; -using ::testing::Combine; -using ::testing::TestWithParam; -using ::testing::Values; -using ::testing::ValuesIn; -#endif // GTEST_HAS_PARAM_TEST - -#if GTEST_HAS_TYPED_TEST -using ::testing::Types; -#endif // GTEST_HAS_TYPED_TEST - -// Tests linking of TEST constructs. -TEST(TestMacroTest, LinksSuccessfully) { -} - -// Tests linking of TEST_F constructs. -class FixtureTest : public Test { -}; - -TEST_F(FixtureTest, LinksSuccessfully) { -} - -// Tests linking of value parameterized tests. -#if GTEST_HAS_PARAM_TEST -class IntParamTest : public TestWithParam {}; - -TEST_P(IntParamTest, LinksSuccessfully) {} - -const int c_array[] = {1, 2}; -INSTANTIATE_TEST_CASE_P(ValuesInCArrayTest, IntParamTest, ValuesIn(c_array)); - -INSTANTIATE_TEST_CASE_P(ValuesInIteratorPairTest, IntParamTest, - ValuesIn(c_array, c_array + 2)); - -vector stl_vector(c_array, c_array + 2); -INSTANTIATE_TEST_CASE_P(ValuesInStlVectorTest, IntParamTest, - ValuesIn(stl_vector)); - -class BoolParamTest : public TestWithParam {}; - -INSTANTIATE_TEST_CASE_P(BoolTest, BoolParamTest, Bool()); - -INSTANTIATE_TEST_CASE_P(ValuesTest, IntParamTest, Values(1, 2)); - -#if GTEST_HAS_COMBINE -class CombineTest : public TestWithParam > {}; - -INSTANTIATE_TEST_CASE_P(CombineTest, CombineTest, Combine(Values(1), Bool())); -#endif // GTEST_HAS_COMBINE -#endif // GTEST_HAS_PARAM_TEST - -// Tests linking of typed tests. -#if GTEST_HAS_TYPED_TEST -template class TypedTest : public Test {}; - -TYPED_TEST_CASE(TypedTest, Types); - -TYPED_TEST(TypedTest, LinksSuccessfully) {} -#endif // GTEST_HAS_TYPED_TEST - -// Tests linking of type-parameterized tests. -#if GTEST_HAS_TYPED_TEST_P -template class TypeParameterizedTest : public Test {}; - -TYPED_TEST_CASE_P(TypeParameterizedTest); - -TYPED_TEST_P(TypeParameterizedTest, LinksSuccessfully) {} - -REGISTER_TYPED_TEST_CASE_P(TypeParameterizedTest, LinksSuccessfully); - -INSTANTIATE_TYPED_TEST_CASE_P(Char, TypeParameterizedTest, Types); -#endif // GTEST_HAS_TYPED_TEST_P - -// Tests linking of explicit success or failure. -TEST(ExplicitSuccessFailureTest, ExplicitSuccessAndFailure) { - if (AlwaysTrue()) - SUCCEED() << "This is a success statement"; - if (AlwaysFalse()) { - ADD_FAILURE() << "This is a non-fatal failure assertion"; - FAIL() << "This is a fatal failure assertion"; - } -} - -// Tests linking of Boolean assertions. -AssertionResult IsEven(int n) { - if (n % 2 == 0) - return AssertionSuccess() << n << " is even"; - else - return AssertionFailure() << n << " is odd"; -} - -TEST(BooleanAssertionTest, LinksSuccessfully) { - EXPECT_TRUE(true) << "true is true"; - EXPECT_FALSE(false) << "false is not true"; - ASSERT_TRUE(true); - ASSERT_FALSE(false); - EXPECT_TRUE(IsEven(2)); - EXPECT_FALSE(IsEven(3)); -} - -// Tests linking of predicate assertions. -bool IsOdd(int n) { return n % 2 != 0; } - -bool Ge(int val1, int val2) { return val1 >= val2; } - -TEST(PredicateAssertionTest, LinksSuccessfully) { - EXPECT_PRED1(IsOdd, 1); - EXPECT_PRED2(Ge, 2, 1); -} - -AssertionResult AddToFive(const char* val1_expr, - const char* val2_expr, - int val1, - int val2) { - if (val1 + val2 == 5) - return AssertionSuccess(); - - return AssertionFailure() << val1_expr << " and " << val2_expr - << " (" << val1 << " and " << val2 << ") " - << "do not add up to five, as their sum is " - << val1 + val2; -} - -TEST(PredicateFormatterAssertionTest, LinksSuccessfully) { - EXPECT_PRED_FORMAT2(AddToFive, 1 + 2, 2); -} - - -// Tests linking of comparison assertions. -TEST(ComparisonAssertionTest, LinksSuccessfully) { - EXPECT_EQ(1, 1); - EXPECT_NE(1, 2); - EXPECT_LT(1, 2); - EXPECT_LE(1, 1); - EXPECT_GT(2, 1); - EXPECT_GE(2, 1); - - EXPECT_EQ('\n', '\n'); - EXPECT_NE('\n', '\r'); - EXPECT_LT('\n', 'a'); - EXPECT_LE('\n', 'b'); - EXPECT_GT('a', '\t'); - EXPECT_GE('b', '\t'); -} - -TEST(StringComparisonAssertionTest, LinksSuccessfully) { - EXPECT_STREQ("test", "test"); - EXPECT_STRNE("test", "prod"); - - char test_str[5] = "test"; - char prod_str[5] = "prod"; - - EXPECT_STREQ(test_str, test_str); - EXPECT_STRNE(test_str, prod_str); - - EXPECT_STRCASEEQ("test", "TEST"); - EXPECT_STRCASENE("test", "prod"); - - wchar_t test_wstr[5] = L"test"; - wchar_t prod_wstr[5] = L"prod"; - - EXPECT_STREQ(L"test", L"test"); - EXPECT_STRNE(L"test", L"prod"); - - EXPECT_STREQ(test_wstr, test_wstr); - EXPECT_STRNE(test_wstr, prod_wstr); - -#if GTEST_HAS_STD_STRING - EXPECT_EQ("test", ::std::string("test")); - EXPECT_NE("test", ::std::string("prod")); - - EXPECT_EQ(::std::string("test"), "test"); - EXPECT_NE(::std::string("prod"), "test"); - - EXPECT_EQ(test_str, ::std::string("test")); - EXPECT_NE(test_str, ::std::string("prod")); - - EXPECT_EQ(::std::string("test"), test_str); - EXPECT_NE(::std::string("prod"), test_str); - - EXPECT_EQ(::std::string("test"), ::std::string("test")); - EXPECT_NE(::std::string("test"), ::std::string("prod")); -#endif // GTEST_HAS_STD_STRING - -#if GTEST_HAS_STD_WSTRING - EXPECT_EQ(L"test", ::std::wstring(L"test")); - EXPECT_NE(L"test", ::std::wstring(L"prod")); - - EXPECT_EQ(::std::wstring(L"test"), L"test"); - EXPECT_NE(::std::wstring(L"prod"), L"test"); - - EXPECT_EQ(test_wstr, ::std::wstring(L"test")); - EXPECT_NE(test_wstr, ::std::wstring(L"prod")); - - EXPECT_EQ(::std::wstring(L"test"), test_wstr); - EXPECT_NE(::std::wstring(L"prod"), test_wstr); - - EXPECT_EQ(::std::wstring(L"test"), ::std::wstring(L"test")); - EXPECT_NE(::std::wstring(L"test"), ::std::wstring(L"prod")); -#endif // GTEST_HAS_STD_WSTRING -} - -// Tests linking of floating point assertions. -TEST(FloatingPointComparisonAssertionTest, LinksSuccessfully) { - EXPECT_FLOAT_EQ(0.0f, 0.0f); - EXPECT_DOUBLE_EQ(0.0, 0.0); - EXPECT_NEAR(0.0, 0.1, 0.2); - EXPECT_PRED_FORMAT2(::testing::FloatLE, 0.0f, 0.01f); - EXPECT_PRED_FORMAT2(::testing::DoubleLE, 0.0, 0.001); -} - -#if GTEST_OS_WINDOWS -// Tests linking of HRESULT assertions. -TEST(HresultAssertionTest, LinksSuccessfully) { - EXPECT_HRESULT_SUCCEEDED(S_OK); - EXPECT_HRESULT_FAILED(E_FAIL); -} -#endif // GTEST_OS_WINDOWS - -#if GTEST_HAS_EXCEPTIONS -// Tests linking of exception assertions. -TEST(ExceptionAssertionTest, LinksSuccessfully) { - EXPECT_THROW(throw 1, int); - EXPECT_ANY_THROW(throw 1); - EXPECT_NO_THROW(std::vector v); -} -#endif // GTEST_HAS_EXCEPTIONS - -// Tests linking of death test assertions. -TEST(DeathTestAssertionDeathTest, LinksSuccessfully) { - EXPECT_DEATH_IF_SUPPORTED(exit(1), ""); - -#if GTEST_HAS_DEATH_TEST - EXPECT_EXIT(exit(1), ExitedWithCode(1), ""); -#endif // GTEST_HAS_DEATH_TEST -} - -// Tests linking of SCOPED_TRACE. -void Sub() { EXPECT_EQ(1, 1); } - -TEST(ScopedTraceTest, LinksSuccessfully) { - SCOPED_TRACE("X"); - Sub(); -} - -// Tests linking of failure absence assertions. -TEST(NoFailureAssertionTest, LinksSuccessfully) { - EXPECT_NO_FATAL_FAILURE(IsEven(2)); -} - -// Tests linking of HasFatalFailure. -TEST(HasFatalFailureTest, LinksSuccessfully) { - EXPECT_FALSE(HasFatalFailure()); - EXPECT_FALSE(HasNonfatalFailure()); - EXPECT_FALSE(HasFailure()); -} - -// Tests linking of RecordProperty. -TEST(RecordPropertyTest, LinksSuccessfully) { - RecordProperty("DummyPropery", "DummyValue"); -} - -// Tests linking of environments. -class MyEnvironment : public Environment {}; - -Environment* const environment = AddGlobalTestEnvironment(new MyEnvironment); - -// Tests linking of flags. -TEST(FlagTest, LinksSuccessfully) { - Message message; - - message << GTEST_FLAG(filter); - message << GTEST_FLAG(also_run_disabled_tests); - message << GTEST_FLAG(repeat); - message << GTEST_FLAG(shuffle); - message << GTEST_FLAG(random_seed); - message << GTEST_FLAG(color); - message << GTEST_FLAG(print_time); - message << GTEST_FLAG(output); - message << GTEST_FLAG(break_on_failure); - message << GTEST_FLAG(throw_on_failure); - message << GTEST_FLAG(catch_exceptions); - message << GTEST_FLAG(stack_trace_depth); -} - -// Tests linking of failure catching assertions. -void FunctionWithFailure() { FAIL(); } - -TEST(FailureCatchingAssertionTest, LinksCorrectly) { - EXPECT_FATAL_FAILURE(FunctionWithFailure(), ""); - EXPECT_NONFATAL_FAILURE(ADD_FAILURE(), ""); - EXPECT_FATAL_FAILURE_ON_ALL_THREADS(FunctionWithFailure(), ""); - EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(ADD_FAILURE(), ""); -} - -// Tests linking of the reflection API. -TEST(ReflectionApiTest, LinksCorrectly) { - // UnitTest API. - UnitTest* unit_test = UnitTest::GetInstance(); - - unit_test->original_working_dir(); - EXPECT_TRUE(unit_test->current_test_case() != NULL); - EXPECT_TRUE(unit_test->current_test_info() != NULL); - EXPECT_NE(0, unit_test->random_seed()); - EXPECT_GE(unit_test->successful_test_case_count(), 0); - EXPECT_EQ(0, unit_test->failed_test_case_count()); - EXPECT_GE(unit_test->total_test_case_count(), 0); - EXPECT_GT(unit_test->test_case_to_run_count(), 0); - EXPECT_GE(unit_test->successful_test_count(), 0); - EXPECT_EQ(0, unit_test->failed_test_count()); - EXPECT_EQ(0, unit_test->disabled_test_count()); - EXPECT_GT(unit_test->total_test_count(), 0); - EXPECT_GT(unit_test->test_to_run_count(), 0); - EXPECT_GE(unit_test->elapsed_time(), 0); - EXPECT_TRUE(unit_test->Passed()); - EXPECT_FALSE(unit_test->Failed()); - EXPECT_TRUE(unit_test->GetTestCase(0) != NULL); - - // TestCase API. - const TestCase*const test_case = unit_test->current_test_case(); - - EXPECT_STRNE("", test_case->name()); - const char* const test_case_comment = test_case->comment(); - EXPECT_TRUE(test_case->should_run()); - EXPECT_GE(test_case->successful_test_count(), 0); - EXPECT_EQ(0, test_case->failed_test_count()); - EXPECT_EQ(0, test_case->disabled_test_count()); - EXPECT_GT(test_case->test_to_run_count(), 0); - EXPECT_GT(test_case->total_test_count(), 0); - EXPECT_TRUE(test_case->Passed()); - EXPECT_FALSE(test_case->Failed()); - EXPECT_GE(test_case->elapsed_time(), 0); - EXPECT_TRUE(test_case->GetTestInfo(0) != NULL); - - // TestInfo API. - const TestInfo* const test_info = unit_test->current_test_info(); - - EXPECT_STRNE("", test_info->test_case_name()); - EXPECT_STRNE("", test_info->name()); - EXPECT_STREQ(test_case_comment, test_info->test_case_comment()); - const char* const comment = test_info->comment(); - EXPECT_TRUE(comment == NULL || strlen(comment) >= 0); - EXPECT_TRUE(test_info->should_run()); - EXPECT_TRUE(test_info->result() != NULL); - - // TestResult API. - const TestResult* const test_result = test_info->result(); - - SUCCEED() << "This generates a successful test part instance for API testing"; - RecordProperty("Test Name", "Test Value"); - EXPECT_EQ(1, test_result->total_part_count()); - EXPECT_EQ(1, test_result->test_property_count()); - EXPECT_TRUE(test_result->Passed()); - EXPECT_FALSE(test_result->Failed()); - EXPECT_FALSE(test_result->HasFatalFailure()); - EXPECT_FALSE(test_result->HasNonfatalFailure()); - EXPECT_GE(test_result->elapsed_time(), 0); - const TestPartResult& test_part_result = test_result->GetTestPartResult(0); - const TestProperty& test_property = test_result->GetTestProperty(0); - - // TestPartResult API. - EXPECT_EQ(TestPartResult::kSuccess, test_part_result.type()); - EXPECT_STRNE("", test_part_result.file_name()); - EXPECT_GT(test_part_result.line_number(), 0); - EXPECT_STRNE("", test_part_result.summary()); - EXPECT_STRNE("", test_part_result.message()); - EXPECT_TRUE(test_part_result.passed()); - EXPECT_FALSE(test_part_result.failed()); - EXPECT_FALSE(test_part_result.nonfatally_failed()); - EXPECT_FALSE(test_part_result.fatally_failed()); - - // TestProperty API. - EXPECT_STREQ("Test Name", test_property.key()); - EXPECT_STREQ("Test Value", test_property.value()); -} - -// Tests linking of the event listener API. -class MyListener : public TestEventListener { - virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) {} - virtual void OnTestIterationStart(const UnitTest& /*unit_test*/, - int /*iteration*/) {} - virtual void OnEnvironmentsSetUpStart(const UnitTest& /*unit_test*/) {} - virtual void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) {} - virtual void OnTestCaseStart(const TestCase& /*test_case*/) {} - virtual void OnTestStart(const TestInfo& /*test_info*/) {} - virtual void OnTestPartResult(const TestPartResult& /*test_part_result*/) {} - virtual void OnTestEnd(const TestInfo& /*test_info*/) {} - virtual void OnTestCaseEnd(const TestCase& /*test_case*/) {} - virtual void OnEnvironmentsTearDownStart(const UnitTest& /*unit_test*/) {} - virtual void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) {} - virtual void OnTestIterationEnd(const UnitTest& /*unit_test*/, - int /*iteration*/) {} - virtual void OnTestProgramEnd(const UnitTest& /*unit_test*/) {} -}; - -class MyOtherListener : public EmptyTestEventListener {}; - -int main(int argc, char **argv) { - testing::InitGoogleTest(&argc, argv); - - void (*wide_init_google_test)(int*, wchar_t**) = &testing::InitGoogleTest; - - // Ensures the linker doesn't throw away reference to wide InitGoogleTest. - GTEST_CHECK_(wide_init_google_test != NULL); - - TestEventListeners& listeners = UnitTest::GetInstance()->listeners(); - TestEventListener* listener = new MyListener; - - listeners.Append(listener); - listeners.Release(listener); - listeners.Append(new MyOtherListener); - listener = listeners.default_result_printer(); - listener = listeners.default_xml_generator(); - - int ret_val = RUN_ALL_TESTS(); - static_cast(ret_val); - return 0; -} diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index bd10ae0d..199b2547 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -76,13 +76,6 @@ TEST(CommandLineFlagsTest, CanBeAccessedInCodeOnceGTestHIsIncluded) { namespace testing { namespace internal { -bool ShouldUseColor(bool stdout_is_tty); -::std::string FormatTimeInMillisAsSeconds(TimeInMillis ms); -bool ParseInt32Flag(const char* str, const char* flag, Int32* value); - -// Used for testing the flag parsing. -extern bool g_help_flag; - // Provides access to otherwise private parts of the TestEventListeners class // that are needed to test it. class TestEventListenersAccessor { -- cgit v1.2.3 From b9a7cead1cdf588b9b00ec46f38a727b14681c5b Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Fri, 26 Mar 2010 20:23:06 +0000 Subject: Fixes a leak in ThreadLocal. --- test/gtest-port_test.cc | 81 ++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 64 insertions(+), 17 deletions(-) (limited to 'test') diff --git a/test/gtest-port_test.cc b/test/gtest-port_test.cc index 577f6099..37258602 100644 --- a/test/gtest-port_test.cc +++ b/test/gtest-port_test.cc @@ -911,47 +911,93 @@ TEST(ThreadLocalTest, ParameterizedConstructorSetsDefault) { EXPECT_STREQ("foo", result.c_str()); } -// DestructorTracker keeps track of whether the class instances have been -// destroyed. The static synchronization mutex has to be defined outside -// of the class, due to syntax of its definition. -static GTEST_DEFINE_STATIC_MUTEX_(destructor_tracker_mutex); - +// DestructorTracker keeps track of whether its instances have been +// destroyed. static std::vector g_destroyed; class DestructorTracker { public: DestructorTracker() : index_(GetNewIndex()) {} + DestructorTracker(const DestructorTracker& /* rhs */) + : index_(GetNewIndex()) {} ~DestructorTracker() { - MutexLock lock(&destructor_tracker_mutex); + // We never access g_destroyed concurrently, so we don't need to + // protect the write operation under a mutex. g_destroyed[index_] = true; } private: static int GetNewIndex() { - MutexLock lock(&destructor_tracker_mutex); g_destroyed.push_back(false); return g_destroyed.size() - 1; } const int index_; }; -template -void CallThreadLocalGet(ThreadLocal* threadLocal) { - threadLocal->get(); +typedef ThreadLocal* ThreadParam; + +void CallThreadLocalGet(ThreadParam thread_local) { + thread_local->get(); +} + +// Tests that when a ThreadLocal object dies in a thread, it destroys +// the managed object for that thread. +TEST(ThreadLocalTest, DestroysManagedObjectForOwnThreadWhenDying) { + g_destroyed.clear(); + + { + // The next line default constructs a DestructorTracker object as + // the default value of objects managed by thread_local. + ThreadLocal thread_local; + ASSERT_EQ(1U, g_destroyed.size()); + ASSERT_FALSE(g_destroyed[0]); + + // This creates another DestructorTracker object for the main thread. + thread_local.get(); + ASSERT_EQ(2U, g_destroyed.size()); + ASSERT_FALSE(g_destroyed[0]); + ASSERT_FALSE(g_destroyed[1]); + } + + // Now thread_local has died. It should have destroyed both the + // default value shared by all threads and the value for the main + // thread. + ASSERT_EQ(2U, g_destroyed.size()); + EXPECT_TRUE(g_destroyed[0]); + EXPECT_TRUE(g_destroyed[1]); + + g_destroyed.clear(); } -TEST(ThreadLocalTest, DestroysManagedObjectsNoLaterThanSelf) { +// Tests that when a thread exits, the thread-local object for that +// thread is destroyed. +TEST(ThreadLocalTest, DestroysManagedObjectAtThreadExit) { g_destroyed.clear(); + { + // The next line default constructs a DestructorTracker object as + // the default value of objects managed by thread_local. ThreadLocal thread_local; - ThreadWithParam*> thread( - &CallThreadLocalGet, &thread_local, NULL); + ASSERT_EQ(1U, g_destroyed.size()); + ASSERT_FALSE(g_destroyed[0]); + + // This creates another DestructorTracker object in the new thread. + ThreadWithParam thread( + &CallThreadLocalGet, &thread_local, NULL); thread.Join(); + + // Now the new thread has exited. The per-thread object for it + // should have been destroyed. + ASSERT_EQ(2U, g_destroyed.size()); + ASSERT_FALSE(g_destroyed[0]); + ASSERT_TRUE(g_destroyed[1]); } - // Verifies that all DestructorTracker objects there were have been - // destroyed. - for (size_t i = 0; i < g_destroyed.size(); ++i) - EXPECT_TRUE(g_destroyed[i]) << "at index " << i; + + // Now thread_local has died. The default value should have been + // destroyed too. + ASSERT_EQ(2U, g_destroyed.size()); + EXPECT_TRUE(g_destroyed[0]); + EXPECT_TRUE(g_destroyed[1]); g_destroyed.clear(); } @@ -965,6 +1011,7 @@ TEST(ThreadLocalTest, ThreadLocalMutationsAffectOnlyCurrentThread) { RunFromThread(&RetrieveThreadLocalValue, make_pair(&thread_local, &result)); EXPECT_TRUE(result.c_str() == NULL); } + #endif // GTEST_IS_THREADSAFE } // namespace internal -- cgit v1.2.3 From d21c142eb89ce42817165368641329072e2ad8fb Mon Sep 17 00:00:00 2001 From: vladlosev Date: Wed, 7 Apr 2010 05:32:34 +0000 Subject: C++ Builder compatibility patch by Josh Kelley. --- test/gtest_unittest.cc | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) (limited to 'test') diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index 199b2547..717bd4e1 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -323,7 +323,7 @@ TEST(NullLiteralTest, IsFalseForNonNullLiterals) { } #ifdef __BORLANDC__ -// Restores warnings after previous "#pragma option push" supressed them +// Restores warnings after previous "#pragma option push" suppressed them. #pragma option pop #endif @@ -1353,7 +1353,7 @@ void DoesNotAbortHelper(bool* aborted) { } #ifdef __BORLANDC__ -// Restores warnings after previous "#pragma option push" supressed them +// Restores warnings after previous "#pragma option push" suppressed them. #pragma option pop #endif @@ -1371,7 +1371,7 @@ static int global_var = 0; #define GTEST_USE_UNPROTECTED_COMMA_ global_var++, global_var++ TEST_F(ExpectFatalFailureTest, AcceptsMacroThatExpandsToUnprotectedComma) { -#ifndef __BORLANDC__ +#if !defined(__BORLANDC__) || __BORLANDC__ >= 0x600 // ICE's in C++Builder 2007. EXPECT_FATAL_FAILURE({ GTEST_USE_UNPROTECTED_COMMA_; @@ -3490,10 +3490,13 @@ TEST(AssertionTest, ASSERT_TRUE) { // Tests ASSERT_TRUE(predicate) for predicates returning AssertionResult. TEST(AssertionTest, AssertTrueWithAssertionResult) { ASSERT_TRUE(ResultIsEven(2)); +#if !defined(__BORLANDC__) || __BORLANDC__ >= 0x600 + // ICE's in C++Builder 2007. EXPECT_FATAL_FAILURE(ASSERT_TRUE(ResultIsEven(3)), "Value of: ResultIsEven(3)\n" " Actual: false (3 is odd)\n" "Expected: true"); +#endif ASSERT_TRUE(ResultIsEvenNoExplanation(2)); EXPECT_FATAL_FAILURE(ASSERT_TRUE(ResultIsEvenNoExplanation(3)), "Value of: ResultIsEvenNoExplanation(3)\n" @@ -3513,10 +3516,13 @@ TEST(AssertionTest, ASSERT_FALSE) { // Tests ASSERT_FALSE(predicate) for predicates returning AssertionResult. TEST(AssertionTest, AssertFalseWithAssertionResult) { ASSERT_FALSE(ResultIsEven(3)); +#if !defined(__BORLANDC__) || __BORLANDC__ >= 0x600 + // ICE's in C++Builder 2007. EXPECT_FATAL_FAILURE(ASSERT_FALSE(ResultIsEven(2)), "Value of: ResultIsEven(2)\n" " Actual: true (2 is even)\n" "Expected: false"); +#endif ASSERT_FALSE(ResultIsEvenNoExplanation(3)); EXPECT_FATAL_FAILURE(ASSERT_FALSE(ResultIsEvenNoExplanation(2)), "Value of: ResultIsEvenNoExplanation(2)\n" @@ -3628,13 +3634,15 @@ void ThrowNothing() {} // Tests ASSERT_THROW. TEST(AssertionTest, ASSERT_THROW) { ASSERT_THROW(ThrowAnInteger(), int); -#if !defined(__BORLANDC__) || __BORLANDC__ >= 0x600 || defined(_DEBUG) - // ICE's in C++Builder 2007 (Release build). + +#ifndef __BORLANDC__ + // ICE's in C++Builder 2007 and 2009. EXPECT_FATAL_FAILURE( ASSERT_THROW(ThrowAnInteger(), bool), "Expected: ThrowAnInteger() throws an exception of type bool.\n" " Actual: it throws a different type."); #endif + EXPECT_FATAL_FAILURE( ASSERT_THROW(ThrowNothing(), bool), "Expected: ThrowNothing() throws an exception of type bool.\n" -- cgit v1.2.3 From eddd9e85a829b91eb8d0a5ff10abed85abb33bdf Mon Sep 17 00:00:00 2001 From: vladlosev Date: Thu, 8 Apr 2010 01:01:12 +0000 Subject: Fixes gtest_filter_unittest and gtest_help_test on systems without death tests. --- test/gtest_filter_unittest.py | 128 ++++++++++++++++++++++-------------------- test/gtest_help_test.py | 15 +++-- test/gtest_help_test_.cc | 4 ++ 3 files changed, 83 insertions(+), 64 deletions(-) (limited to 'test') diff --git a/test/gtest_filter_unittest.py b/test/gtest_filter_unittest.py index 89171e06..0d1a7700 100755 --- a/test/gtest_filter_unittest.py +++ b/test/gtest_filter_unittest.py @@ -108,6 +108,14 @@ TEST_CASE_REGEX = re.compile(r'^\[\-+\] \d+ tests? from (\w+(/\w+)?)') # Regex for parsing test names from Google Test's output. TEST_REGEX = re.compile(r'^\[\s*RUN\s*\].*\.(\w+(/\w+)?)') +# The command line flag to tell Google Test to output the list of tests it +# will run. +LIST_TESTS_FLAG = '--gtest_list_tests' + +# Indicates whether Google Test supports death tests. +SUPPORTS_DEATH_TESTS = 'HasDeathTest' in gtest_test_utils.Subprocess( + [COMMAND, LIST_TESTS_FLAG]).output + # Full names of all tests in gtest_filter_unittests_. PARAM_TESTS = [ 'SeqP/ParamTest.TestX/0', @@ -129,6 +137,14 @@ DISABLED_TESTS = [ 'DISABLED_FoobarbazTest.TestA', ] +if SUPPORTS_DEATH_TESTS: + DEATH_TESTS = [ + 'HasDeathTest.Test1', + 'HasDeathTest.Test2', + ] +else: + DEATH_TESTS = [] + # All the non-disabled tests. ACTIVE_TESTS = [ 'FooTest.Abc', @@ -141,10 +157,7 @@ ACTIVE_TESTS = [ 'BazTest.TestOne', 'BazTest.TestA', 'BazTest.TestB', - - 'HasDeathTest.Test1', - 'HasDeathTest.Test2', - ] + PARAM_TESTS + ] + DEATH_TESTS + PARAM_TESTS param_tests_present = None @@ -210,7 +223,7 @@ def RunWithSharding(total_shards, shard_index, command): class GTestFilterUnitTest(gtest_test_utils.TestCase): - """Tests GTEST_FILTER env variable or --gtest_filter flag to filter tests.""" + """Tests the env variable or the command line flag to filter tests.""" # Utilities. @@ -242,17 +255,17 @@ class GTestFilterUnitTest(gtest_test_utils.TestCase): return tests_to_run def RunAndVerify(self, gtest_filter, tests_to_run): - """Checks that the binary runs correct set of tests for the given filter.""" + """Checks that the binary runs correct set of tests for a given filter.""" tests_to_run = self.AdjustForParameterizedTests(tests_to_run) - # First, tests using GTEST_FILTER. + # First, tests using the environment variable. # Windows removes empty variables from the environment when passing it - # to a new process. This means it is impossible to pass an empty filter - # into a process using the GTEST_FILTER environment variable. However, - # we can still test the case when the variable is not supplied (i.e., - # gtest_filter is None). + # to a new process. This means it is impossible to pass an empty filter + # into a process using the environment variable. However, we can still + # test the case when the variable is not supplied (i.e., gtest_filter is + # None). # pylint: disable-msg=C6403 if CAN_TEST_EMPTY_FILTER or gtest_filter != '': SetEnvVar(FILTER_ENV_VAR, gtest_filter) @@ -261,7 +274,7 @@ class GTestFilterUnitTest(gtest_test_utils.TestCase): self.AssertSetEqual(tests_run, tests_to_run) # pylint: enable-msg=C6403 - # Next, tests using --gtest_filter. + # Next, tests using the command line flag. if gtest_filter is None: args = [] @@ -291,10 +304,10 @@ class GTestFilterUnitTest(gtest_test_utils.TestCase): tests_to_run = self.AdjustForParameterizedTests(tests_to_run) # Windows removes empty variables from the environment when passing it - # to a new process. This means it is impossible to pass an empty filter - # into a process using the GTEST_FILTER environment variable. However, - # we can still test the case when the variable is not supplied (i.e., - # gtest_filter is None). + # to a new process. This means it is impossible to pass an empty filter + # into a process using the environment variable. However, we can still + # test the case when the variable is not supplied (i.e., gtest_filter is + # None). # pylint: disable-msg=C6403 if CAN_TEST_EMPTY_FILTER or gtest_filter != '': SetEnvVar(FILTER_ENV_VAR, gtest_filter) @@ -435,10 +448,7 @@ class GTestFilterUnitTest(gtest_test_utils.TestCase): 'BazTest.TestOne', 'BazTest.TestA', - 'BazTest.TestB', - - 'HasDeathTest.Test1', - 'HasDeathTest.Test2', ] + PARAM_TESTS) + 'BazTest.TestB', ] + DEATH_TESTS + PARAM_TESTS) def testWildcardInTestName(self): """Tests using wildcard in the test name.""" @@ -499,7 +509,7 @@ class GTestFilterUnitTest(gtest_test_utils.TestCase): ]) def testNegativeFilters(self): - self.RunAndVerify('*-HasDeathTest.Test1', [ + self.RunAndVerify('*-BazTest.TestOne', [ 'FooTest.Abc', 'FooTest.Xyz', @@ -507,24 +517,17 @@ class GTestFilterUnitTest(gtest_test_utils.TestCase): 'BarTest.TestTwo', 'BarTest.TestThree', - 'BazTest.TestOne', 'BazTest.TestA', 'BazTest.TestB', + ] + DEATH_TESTS + PARAM_TESTS) - 'HasDeathTest.Test2', - ] + PARAM_TESTS) - - self.RunAndVerify('*-FooTest.Abc:HasDeathTest.*', [ + self.RunAndVerify('*-FooTest.Abc:BazTest.*', [ 'FooTest.Xyz', 'BarTest.TestOne', 'BarTest.TestTwo', 'BarTest.TestThree', - - 'BazTest.TestOne', - 'BazTest.TestA', - 'BazTest.TestB', - ] + PARAM_TESTS) + ] + DEATH_TESTS + PARAM_TESTS) self.RunAndVerify('BarTest.*-BarTest.TestOne', [ 'BarTest.TestTwo', @@ -532,15 +535,11 @@ class GTestFilterUnitTest(gtest_test_utils.TestCase): ]) # Tests without leading '*'. - self.RunAndVerify('-FooTest.Abc:FooTest.Xyz:HasDeathTest.*', [ + self.RunAndVerify('-FooTest.Abc:FooTest.Xyz:BazTest.*', [ 'BarTest.TestOne', 'BarTest.TestTwo', 'BarTest.TestThree', - - 'BazTest.TestOne', - 'BazTest.TestA', - 'BazTest.TestB', - ] + PARAM_TESTS) + ] + DEATH_TESTS + PARAM_TESTS) # Value parameterized tests. self.RunAndVerify('*/*', PARAM_TESTS) @@ -586,7 +585,7 @@ class GTestFilterUnitTest(gtest_test_utils.TestCase): os.remove(shard_status_file) def testShardStatusFileIsCreatedWithListTests(self): - """Tests that the shard file is created with --gtest_list_tests.""" + """Tests that the shard file is created with the "list_tests" flag.""" shard_status_file = os.path.join(gtest_test_utils.GetTempDir(), 'shard_status_file2') @@ -594,32 +593,41 @@ class GTestFilterUnitTest(gtest_test_utils.TestCase): extra_env = {SHARD_STATUS_FILE_ENV_VAR: shard_status_file} try: - InvokeWithModifiedEnv(extra_env, - RunAndReturnOutput, - ['--gtest_list_tests']) + output = InvokeWithModifiedEnv(extra_env, + RunAndReturnOutput, + [LIST_TESTS_FLAG]) finally: + # This assertion ensures that Google Test enumerated the tests as + # opposed to running them. + self.assert_('[==========]' not in output, + 'Unexpected output during test enumeration.\n' + 'Please ensure that LIST_TESTS_FLAG is assigned the\n' + 'correct flag value for listing Google Test tests.') + self.assert_(os.path.exists(shard_status_file)) os.remove(shard_status_file) - def testShardingWorksWithDeathTests(self): - """Tests integration with death tests and sharding.""" - gtest_filter = 'HasDeathTest.*:SeqP/*' - expected_tests = [ - 'HasDeathTest.Test1', - 'HasDeathTest.Test2', - - 'SeqP/ParamTest.TestX/0', - 'SeqP/ParamTest.TestX/1', - 'SeqP/ParamTest.TestY/0', - 'SeqP/ParamTest.TestY/1', - ] - - for flag in ['--gtest_death_test_style=threadsafe', - '--gtest_death_test_style=fast']: - self.RunAndVerifyWithSharding(gtest_filter, 3, expected_tests, - check_exit_0=True, args=[flag]) - self.RunAndVerifyWithSharding(gtest_filter, 5, expected_tests, - check_exit_0=True, args=[flag]) + if SUPPORTS_DEATH_TESTS: + def testShardingWorksWithDeathTests(self): + """Tests integration with death tests and sharding.""" + + gtest_filter = 'HasDeathTest.*:SeqP/*' + expected_tests = [ + 'HasDeathTest.Test1', + 'HasDeathTest.Test2', + + 'SeqP/ParamTest.TestX/0', + 'SeqP/ParamTest.TestX/1', + 'SeqP/ParamTest.TestY/0', + 'SeqP/ParamTest.TestY/1', + ] + + for flag in ['--gtest_death_test_style=threadsafe', + '--gtest_death_test_style=fast']: + self.RunAndVerifyWithSharding(gtest_filter, 3, expected_tests, + check_exit_0=True, args=[flag]) + self.RunAndVerifyWithSharding(gtest_filter, 5, expected_tests, + check_exit_0=True, args=[flag]) if __name__ == '__main__': gtest_test_utils.Main() diff --git a/test/gtest_help_test.py b/test/gtest_help_test.py index 7883c1c5..3cb4c48e 100755 --- a/test/gtest_help_test.py +++ b/test/gtest_help_test.py @@ -51,11 +51,15 @@ FLAG_PREFIX = '--gtest_' CATCH_EXCEPTIONS_FLAG = FLAG_PREFIX + 'catch_exceptions' DEATH_TEST_STYLE_FLAG = FLAG_PREFIX + 'death_test_style' UNKNOWN_FLAG = FLAG_PREFIX + 'unknown_flag_for_testing' -INCORRECT_FLAG_VARIANTS = [re.sub('^--', '-', DEATH_TEST_STYLE_FLAG), - re.sub('^--', '/', DEATH_TEST_STYLE_FLAG), - re.sub('_', '-', DEATH_TEST_STYLE_FLAG)] +LIST_TESTS_FLAG = FLAG_PREFIX + 'list_tests' +INCORRECT_FLAG_VARIANTS = [re.sub('^--', '-', LIST_TESTS_FLAG), + re.sub('^--', '/', LIST_TESTS_FLAG), + re.sub('_', '-', LIST_TESTS_FLAG)] INTERNAL_FLAG_FOR_TESTING = FLAG_PREFIX + 'internal_flag_for_testing' +SUPPORTS_DEATH_TESTS = "DeathTest" in gtest_test_utils.Subprocess( + [PROGRAM_PATH, LIST_TESTS_FLAG]).output + # The help message must match this regex. HELP_REGEX = re.compile( FLAG_PREFIX + r'list_tests.*' + @@ -107,10 +111,13 @@ class GTestHelpTest(gtest_test_utils.TestCase): self.assert_(HELP_REGEX.search(output), output) if IS_WINDOWS: self.assert_(CATCH_EXCEPTIONS_FLAG in output, output) - self.assert_(DEATH_TEST_STYLE_FLAG not in output, output) else: self.assert_(CATCH_EXCEPTIONS_FLAG not in output, output) + + if SUPPORTS_DEATH_TESTS and not IS_WINDOWS: self.assert_(DEATH_TEST_STYLE_FLAG in output, output) + else: + self.assert_(DEATH_TEST_STYLE_FLAG not in output, output) def TestNonHelpFlag(self, flag): """Verifies correct behavior when no help flag is specified. diff --git a/test/gtest_help_test_.cc b/test/gtest_help_test_.cc index 0282bc88..aad0d72d 100644 --- a/test/gtest_help_test_.cc +++ b/test/gtest_help_test_.cc @@ -40,3 +40,7 @@ TEST(HelpFlagTest, ShouldNotBeRun) { ASSERT_TRUE(false) << "Tests shouldn't be run when --help is specified."; } + +#if GTEST_HAS_DEATH_TEST +TEST(DeathTest, UsedByPythonScriptToDetectSupportForDeathTestsInThisBinary) {} +#endif -- cgit v1.2.3 From 1b71f0b272f4d3dfb45db44ab39a77727ddafb9b Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Tue, 13 Apr 2010 04:40:32 +0000 Subject: Adds alternative spellings for FAIL, SUCCEED, and TEST. --- test/gtest_unittest.cc | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'test') diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index 717bd4e1..a14f065a 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -6703,3 +6703,16 @@ TEST(EventListenerTest, RemovingDefaultXmlGeneratorWorks) { EXPECT_FALSE(is_destroyed); delete listener; } + +// Sanity tests to ensure that the alternative, verbose spellings of +// some of the macros work. We don't test them thoroughly as that +// would be quite involved. Since their implementations are +// straightforward, and they are rarely used, we'll just rely on the +// users to tell us when they are broken. +GTEST_TEST(AlternativeNameTest, Works) { // GTEST_TEST is the same as TEST. + GTEST_SUCCEED() << "OK"; // GTEST_SUCCEED is the same as SUCCEED. + + // GTEST_FAIL is the same as FAIL. + EXPECT_FATAL_FAILURE(GTEST_FAIL() << "An expected failure", + "An expected failure"); +} -- cgit v1.2.3 From e85375608b87ffd48fbc9c9f1f2d9a58176d7055 Mon Sep 17 00:00:00 2001 From: vladlosev Date: Thu, 22 Apr 2010 11:43:55 +0000 Subject: Fixes gtest-port_test on MinGW. --- test/gtest-port_test.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'test') diff --git a/test/gtest-port_test.cc b/test/gtest-port_test.cc index 37258602..b6e53ba8 100644 --- a/test/gtest-port_test.cc +++ b/test/gtest-port_test.cc @@ -149,8 +149,10 @@ TEST(GtestCheckDeathTest, DiesWithCorrectOutputOnFailure) { const char regex[] = #ifdef _MSC_VER "gtest-port_test\\.cc\\(\\d+\\):" -#else +#elif GTEST_USES_POSIX_RE "gtest-port_test\\.cc:[0-9]+" +#else + "gtest-port_test\\.cc:\\d+" #endif // _MSC_VER ".*a_false_condition.*Extra info.*"; -- cgit v1.2.3 From e05489605fc58736f837563db1fc33f9131ee810 Mon Sep 17 00:00:00 2001 From: vladlosev Date: Thu, 22 Apr 2010 11:44:59 +0000 Subject: Implements color output in GNU Screen sessions (issue 277). --- test/gtest_unittest.cc | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'test') diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index a14f065a..adc0fffa 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -6264,8 +6264,17 @@ TEST(ColoredOutputTest, UsesColorsWhenTermSupportsColors) { SetEnv("TERM", "xterm-color"); // TERM supports colors. EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY. + SetEnv("TERM", "xterm-256color"); // TERM supports colors. + EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY. + + SetEnv("TERM", "screen"); // TERM supports colors. + EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY. + SetEnv("TERM", "linux"); // TERM supports colors. EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY. + + SetEnv("TERM", "cygwin"); // TERM supports colors. + EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY. #endif // GTEST_OS_WINDOWS } -- cgit v1.2.3 From c476707e82f8db4974912594fbf419326973cb2a Mon Sep 17 00:00:00 2001 From: vladlosev Date: Wed, 5 May 2010 13:09:35 +0000 Subject: Improves support for building Google Test as Windows DLL. --- test/gtest_all_test.cc | 1 - test/gtest_output_test_.cc | 4 +--- 2 files changed, 1 insertion(+), 4 deletions(-) (limited to 'test') diff --git a/test/gtest_all_test.cc b/test/gtest_all_test.cc index e1edb08e..955aa628 100644 --- a/test/gtest_all_test.cc +++ b/test/gtest_all_test.cc @@ -45,4 +45,3 @@ #include "test/gtest-typed-test2_test.cc" #include "test/gtest_unittest.cc" #include "test/production.cc" -#include "src/gtest_main.cc" diff --git a/test/gtest_output_test_.cc b/test/gtest_output_test_.cc index 273e8e93..32fb49a9 100644 --- a/test/gtest_output_test_.cc +++ b/test/gtest_output_test_.cc @@ -1085,9 +1085,7 @@ class BarEnvironment : public testing::Environment { } }; -GTEST_DEFINE_bool_(internal_skip_environment_and_ad_hoc_tests, false, - "This flag causes the program to skip test environment " - "tests and ad hoc tests."); +bool GTEST_FLAG(internal_skip_environment_and_ad_hoc_tests) = false; // The main function. // -- cgit v1.2.3 From 2ccea88c99d1ae23383d1b8eb3680a4a4d2edd66 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Mon, 10 May 2010 17:11:58 +0000 Subject: Moves the universal printer from gmock to gtest and refactors the cmake script for reusing in gmock (by Vlad Losev). --- test/gtest-port_test.cc | 112 +++++ test/gtest-printers_test.cc | 1163 +++++++++++++++++++++++++++++++++++++++++++ test/gtest_unittest.cc | 339 ++++++++++++- 3 files changed, 1612 insertions(+), 2 deletions(-) create mode 100644 test/gtest-printers_test.cc (limited to 'test') diff --git a/test/gtest-port_test.cc b/test/gtest-port_test.cc index b6e53ba8..6f1512ce 100644 --- a/test/gtest-port_test.cc +++ b/test/gtest-port_test.cc @@ -59,6 +59,118 @@ using std::pair; namespace testing { namespace internal { +class Base { + public: + // Copy constructor and assignment operator do exactly what we need, so we + // use them. + Base() : member_(0) {} + explicit Base(int n) : member_(n) {} + virtual ~Base() {} + int member() { return member_; } + + private: + int member_; +}; + +class Derived : public Base { + public: + explicit Derived(int n) : Base(n) {} +}; + +TEST(ImplicitCastTest, ConvertsPointers) { + Derived derived(0); + EXPECT_TRUE(&derived == ::testing::internal::implicit_cast(&derived)); +} + +TEST(ImplicitCastTest, CanUseInheritance) { + Derived derived(1); + Base base = ::testing::internal::implicit_cast(derived); + EXPECT_EQ(derived.member(), base.member()); +} + +class Castable { + public: + Castable(bool* converted) : converted_(converted) {} + operator Base() { + *converted_ = true; + return Base(); + } + + private: + bool* converted_; +}; + +TEST(ImplicitCastTest, CanUseNonConstCastOperator) { + bool converted = false; + Castable castable(&converted); + Base base = ::testing::internal::implicit_cast(castable); + EXPECT_TRUE(converted); +} + +class ConstCastable { + public: + ConstCastable(bool* converted) : converted_(converted) {} + operator Base() const { + *converted_ = true; + return Base(); + } + + private: + bool* converted_; +}; + +TEST(ImplicitCastTest, CanUseConstCastOperatorOnConstValues) { + bool converted = false; + const ConstCastable const_castable(&converted); + Base base = ::testing::internal::implicit_cast(const_castable); + EXPECT_TRUE(converted); +} + +class ConstAndNonConstCastable { + public: + ConstAndNonConstCastable(bool* converted, bool* const_converted) + : converted_(converted), const_converted_(const_converted) {} + operator Base() { + *converted_ = true; + return Base(); + } + operator Base() const { + *const_converted_ = true; + return Base(); + } + + private: + bool* converted_; + bool* const_converted_; +}; + +TEST(ImplicitCastTest, CanSelectBetweenConstAndNonConstCasrAppropriately) { + bool converted = false; + bool const_converted = false; + ConstAndNonConstCastable castable(&converted, &const_converted); + Base base = ::testing::internal::implicit_cast(castable); + EXPECT_TRUE(converted); + EXPECT_FALSE(const_converted); + + converted = false; + const_converted = false; + const ConstAndNonConstCastable const_castable(&converted, &const_converted); + base = ::testing::internal::implicit_cast(const_castable); + EXPECT_FALSE(converted); + EXPECT_TRUE(const_converted); +} + +class To { + public: + To(bool* converted) { *converted = true; } // NOLINT +}; + +TEST(ImplicitCastTest, CanUseImplicitConstructor) { + bool converted = false; + To to = ::testing::internal::implicit_cast(&converted); + EXPECT_TRUE(converted); +} + // Tests that the element_type typedef is available in scoped_ptr and refers // to the parameter type. TEST(ScopedPtrTest, DefinesElementType) { diff --git a/test/gtest-printers_test.cc b/test/gtest-printers_test.cc new file mode 100644 index 00000000..0ecd8715 --- /dev/null +++ b/test/gtest-printers_test.cc @@ -0,0 +1,1163 @@ +// Copyright 2007, 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) + +// Google Test - The Google C++ Testing Framework +// +// This file tests the universal value printer. + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +// hash_map and hash_set are available on Windows. +#if GTEST_OS_WINDOWS +#define GTEST_HAS_HASH_MAP_ 1 // Indicates that hash_map is available. +#include // NOLINT +#define GTEST_HAS_HASH_SET_ 1 // Indicates that hash_set is available. +#include // NOLINT +#endif // GTEST_OS_WINDOWS + +// Some user-defined types for testing the universal value printer. + +// A user-defined unprintable class template in the global namespace. +template +class UnprintableTemplateInGlobal { + public: + UnprintableTemplateInGlobal() : value_() {} + private: + T value_; +}; + +// A user-defined streamable type in the global namespace. +class StreamableInGlobal { + public: + virtual ~StreamableInGlobal() {} +}; + +inline void operator<<(::std::ostream& os, const StreamableInGlobal& /* x */) { + os << "StreamableInGlobal"; +} + +namespace foo { + +// A user-defined unprintable type in a user namespace. +class UnprintableInFoo { + public: + UnprintableInFoo() : x_(0x12EF), y_(0xAB34), z_(0) {} + private: + testing::internal::Int32 x_; + testing::internal::Int32 y_; + double z_; +}; + +// A user-defined printable type in a user-chosen namespace. +struct PrintableViaPrintTo { + PrintableViaPrintTo() : value() {} + int value; +}; + +void PrintTo(const PrintableViaPrintTo& x, ::std::ostream* os) { + *os << "PrintableViaPrintTo: " << x.value; +} + +// A user-defined printable class template in a user-chosen namespace. +template +class PrintableViaPrintToTemplate { + public: + explicit PrintableViaPrintToTemplate(const T& a_value) : value_(a_value) {} + + const T& value() const { return value_; } + private: + T value_; +}; + +template +void PrintTo(const PrintableViaPrintToTemplate& x, ::std::ostream* os) { + *os << "PrintableViaPrintToTemplate: " << x.value(); +} + +// A user-defined streamable class template in a user namespace. +template +class StreamableTemplateInFoo { + public: + StreamableTemplateInFoo() : value_() {} + + const T& value() const { return value_; } + private: + T value_; +}; + +template +inline ::std::ostream& operator<<(::std::ostream& os, + const StreamableTemplateInFoo& x) { + return os << "StreamableTemplateInFoo: " << x.value(); +} + +} // namespace foo + +namespace testing { +namespace gtest_printers_test { + +using ::std::deque; +using ::std::list; +using ::std::make_pair; +using ::std::map; +using ::std::multimap; +using ::std::multiset; +using ::std::pair; +using ::std::set; +using ::std::vector; +using ::testing::PrintToString; +using ::testing::internal::NativeArray; +using ::testing::internal::RE; +using ::testing::internal::Strings; +using ::testing::internal::UniversalTersePrint; +using ::testing::internal::UniversalPrint; +using ::testing::internal::UniversalTersePrintTupleFieldsToStrings; +using ::testing::internal::UniversalPrinter; +using ::testing::internal::kReference; +using ::testing::internal::string; + +#if GTEST_HAS_TR1_TUPLE +using ::std::tr1::make_tuple; +using ::std::tr1::tuple; +#endif + +#if GTEST_OS_WINDOWS +// MSVC defines the following classes in the ::stdext namespace while +// gcc defines them in the :: namespace. Note that they are not part +// of the C++ standard. + +using ::stdext::hash_map; +using ::stdext::hash_set; +using ::stdext::hash_multimap; +using ::stdext::hash_multiset; + +#endif // GTEST_OS_WINDOWS + +// Prints a value to a string using the universal value printer. This +// is a helper for testing UniversalPrinter::Print() for various types. +template +string Print(const T& value) { + ::std::stringstream ss; + UniversalPrinter::Print(value, &ss); + return ss.str(); +} + +// Prints a value passed by reference to a string, using the universal +// value printer. This is a helper for testing +// UniversalPrinter::Print() for various types. +template +string PrintByRef(const T& value) { + ::std::stringstream ss; + UniversalPrinter::Print(value, &ss); + return ss.str(); +} + +// Tests printing various char types. + +// char. +TEST(PrintCharTest, PlainChar) { + EXPECT_EQ("'\\0'", Print('\0')); + EXPECT_EQ("'\\'' (39)", Print('\'')); + EXPECT_EQ("'\"' (34)", Print('"')); + EXPECT_EQ("'\\?' (63)", Print('\?')); + EXPECT_EQ("'\\\\' (92)", Print('\\')); + EXPECT_EQ("'\\a' (7)", Print('\a')); + EXPECT_EQ("'\\b' (8)", Print('\b')); + EXPECT_EQ("'\\f' (12)", Print('\f')); + EXPECT_EQ("'\\n' (10)", Print('\n')); + EXPECT_EQ("'\\r' (13)", Print('\r')); + EXPECT_EQ("'\\t' (9)", Print('\t')); + EXPECT_EQ("'\\v' (11)", Print('\v')); + EXPECT_EQ("'\\x7F' (127)", Print('\x7F')); + EXPECT_EQ("'\\xFF' (255)", Print('\xFF')); + EXPECT_EQ("' ' (32)", Print(' ')); + EXPECT_EQ("'a' (97)", Print('a')); +} + +// signed char. +TEST(PrintCharTest, SignedChar) { + EXPECT_EQ("'\\0'", Print(static_cast('\0'))); + EXPECT_EQ("'\\xCE' (-50)", + Print(static_cast(-50))); +} + +// unsigned char. +TEST(PrintCharTest, UnsignedChar) { + EXPECT_EQ("'\\0'", Print(static_cast('\0'))); + EXPECT_EQ("'b' (98)", + Print(static_cast('b'))); +} + +// Tests printing other simple, built-in types. + +// bool. +TEST(PrintBuiltInTypeTest, Bool) { + EXPECT_EQ("false", Print(false)); + EXPECT_EQ("true", Print(true)); +} + +// wchar_t. +TEST(PrintBuiltInTypeTest, Wchar_t) { + EXPECT_EQ("L'\\0'", Print(L'\0')); + EXPECT_EQ("L'\\'' (39)", Print(L'\'')); + EXPECT_EQ("L'\"' (34)", Print(L'"')); + EXPECT_EQ("L'\\?' (63)", Print(L'\?')); + EXPECT_EQ("L'\\\\' (92)", Print(L'\\')); + EXPECT_EQ("L'\\a' (7)", Print(L'\a')); + EXPECT_EQ("L'\\b' (8)", Print(L'\b')); + EXPECT_EQ("L'\\f' (12)", Print(L'\f')); + EXPECT_EQ("L'\\n' (10)", Print(L'\n')); + EXPECT_EQ("L'\\r' (13)", Print(L'\r')); + EXPECT_EQ("L'\\t' (9)", Print(L'\t')); + EXPECT_EQ("L'\\v' (11)", Print(L'\v')); + EXPECT_EQ("L'\\x7F' (127)", Print(L'\x7F')); + EXPECT_EQ("L'\\xFF' (255)", Print(L'\xFF')); + EXPECT_EQ("L' ' (32)", Print(L' ')); + EXPECT_EQ("L'a' (97)", Print(L'a')); + EXPECT_EQ("L'\\x576' (1398)", Print(L'\x576')); + EXPECT_EQ("L'\\xC74D' (51021)", Print(L'\xC74D')); +} + +// Test that Int64 provides more storage than wchar_t. +TEST(PrintTypeSizeTest, Wchar_t) { + EXPECT_LT(sizeof(wchar_t), sizeof(testing::internal::Int64)); +} + +// Various integer types. +TEST(PrintBuiltInTypeTest, Integer) { + EXPECT_EQ("'\\xFF' (255)", Print(static_cast(255))); // uint8 + EXPECT_EQ("'\\x80' (-128)", Print(static_cast(-128))); // int8 + EXPECT_EQ("65535", Print(USHRT_MAX)); // uint16 + EXPECT_EQ("-32768", Print(SHRT_MIN)); // int16 + EXPECT_EQ("4294967295", Print(UINT_MAX)); // uint32 + EXPECT_EQ("-2147483648", Print(INT_MIN)); // int32 + EXPECT_EQ("18446744073709551615", + Print(static_cast(-1))); // uint64 + EXPECT_EQ("-9223372036854775808", + Print(static_cast(1) << 63)); // int64 +} + +// Size types. +TEST(PrintBuiltInTypeTest, Size_t) { + EXPECT_EQ("1", Print(sizeof('a'))); // size_t. +#if !GTEST_OS_WINDOWS + // Windows has no ssize_t type. + EXPECT_EQ("-2", Print(static_cast(-2))); // ssize_t. +#endif // !GTEST_OS_WINDOWS +} + +// Floating-points. +TEST(PrintBuiltInTypeTest, FloatingPoints) { + EXPECT_EQ("1.5", Print(1.5f)); // float + EXPECT_EQ("-2.5", Print(-2.5)); // double +} + +// Since ::std::stringstream::operator<<(const void *) formats the pointer +// output differently with different compilers, we have to create the expected +// output first and use it as our expectation. +static string PrintPointer(const void *p) { + ::std::stringstream expected_result_stream; + expected_result_stream << p; + return expected_result_stream.str(); +} + +// Tests printing C strings. + +// const char*. +TEST(PrintCStringTest, Const) { + const char* p = "World"; + EXPECT_EQ(PrintPointer(p) + " pointing to \"World\"", Print(p)); +} + +// char*. +TEST(PrintCStringTest, NonConst) { + char p[] = "Hi"; + EXPECT_EQ(PrintPointer(p) + " pointing to \"Hi\"", + Print(static_cast(p))); +} + +// NULL C string. +TEST(PrintCStringTest, Null) { + const char* p = NULL; + EXPECT_EQ("NULL", Print(p)); +} + +// Tests that C strings are escaped properly. +TEST(PrintCStringTest, EscapesProperly) { + const char* p = "'\"\?\\\a\b\f\n\r\t\v\x7F\xFF a"; + EXPECT_EQ(PrintPointer(p) + " pointing to \"'\\\"\\?\\\\\\a\\b\\f" + "\\n\\r\\t\\v\\x7F\\xFF a\"", + Print(p)); +} + + + +// MSVC compiler can be configured to define whar_t as a typedef +// of unsigned short. Defining an overload for const wchar_t* in that case +// would cause pointers to unsigned shorts be printed as wide strings, +// possibly accessing more memory than intended and causing invalid +// memory accesses. MSVC defines _NATIVE_WCHAR_T_DEFINED symbol when +// wchar_t is implemented as a native type. +#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED) + +// const wchar_t*. +TEST(PrintWideCStringTest, Const) { + const wchar_t* p = L"World"; + EXPECT_EQ(PrintPointer(p) + " pointing to L\"World\"", Print(p)); +} + +// wchar_t*. +TEST(PrintWideCStringTest, NonConst) { + wchar_t p[] = L"Hi"; + EXPECT_EQ(PrintPointer(p) + " pointing to L\"Hi\"", + Print(static_cast(p))); +} + +// NULL wide C string. +TEST(PrintWideCStringTest, Null) { + const wchar_t* p = NULL; + EXPECT_EQ("NULL", Print(p)); +} + +// Tests that wide C strings are escaped properly. +TEST(PrintWideCStringTest, EscapesProperly) { + const wchar_t* p = L"'\"\?\\\a\b\f\n\r\t\v\xD3\x576\x8D3\xC74D a"; + EXPECT_EQ(PrintPointer(p) + " pointing to L\"'\\\"\\?\\\\\\a\\b\\f" + "\\n\\r\\t\\v\\xD3\\x576\\x8D3\\xC74D a\"", + Print(p)); +} +#endif // native wchar_t + +// Tests printing pointers to other char types. + +// signed char*. +TEST(PrintCharPointerTest, SignedChar) { + signed char* p = reinterpret_cast(0x1234); + EXPECT_EQ(PrintPointer(p), Print(p)); + p = NULL; + EXPECT_EQ("NULL", Print(p)); +} + +// const signed char*. +TEST(PrintCharPointerTest, ConstSignedChar) { + signed char* p = reinterpret_cast(0x1234); + EXPECT_EQ(PrintPointer(p), Print(p)); + p = NULL; + EXPECT_EQ("NULL", Print(p)); +} + +// unsigned char*. +TEST(PrintCharPointerTest, UnsignedChar) { + unsigned char* p = reinterpret_cast(0x1234); + EXPECT_EQ(PrintPointer(p), Print(p)); + p = NULL; + EXPECT_EQ("NULL", Print(p)); +} + +// const unsigned char*. +TEST(PrintCharPointerTest, ConstUnsignedChar) { + const unsigned char* p = reinterpret_cast(0x1234); + EXPECT_EQ(PrintPointer(p), Print(p)); + p = NULL; + EXPECT_EQ("NULL", Print(p)); +} + +// Tests printing pointers to simple, built-in types. + +// bool*. +TEST(PrintPointerToBuiltInTypeTest, Bool) { + bool* p = reinterpret_cast(0xABCD); + EXPECT_EQ(PrintPointer(p), Print(p)); + p = NULL; + EXPECT_EQ("NULL", Print(p)); +} + +// void*. +TEST(PrintPointerToBuiltInTypeTest, Void) { + void* p = reinterpret_cast(0xABCD); + EXPECT_EQ(PrintPointer(p), Print(p)); + p = NULL; + EXPECT_EQ("NULL", Print(p)); +} + +// const void*. +TEST(PrintPointerToBuiltInTypeTest, ConstVoid) { + const void* p = reinterpret_cast(0xABCD); + EXPECT_EQ(PrintPointer(p), Print(p)); + p = NULL; + EXPECT_EQ("NULL", Print(p)); +} + +// Tests printing pointers to pointers. +TEST(PrintPointerToPointerTest, IntPointerPointer) { + int** p = reinterpret_cast(0xABCD); + EXPECT_EQ(PrintPointer(p), Print(p)); + p = NULL; + EXPECT_EQ("NULL", Print(p)); +} + +// Tests printing (non-member) function pointers. + +void MyFunction(int /* n */) {} + +TEST(PrintPointerTest, NonMemberFunctionPointer) { + // We cannot directly cast &MyFunction to const void* because the + // standard disallows casting between pointers to functions and + // pointers to objects, and some compilers (e.g. GCC 3.4) enforce + // this limitation. + EXPECT_EQ( + PrintPointer(reinterpret_cast( + reinterpret_cast(&MyFunction))), + Print(&MyFunction)); + int (*p)(bool) = NULL; // NOLINT + EXPECT_EQ("NULL", Print(p)); +} + +// An assertion predicate determining whether a one string is a prefix for +// another. +template +AssertionResult HasPrefix(const StringType& str, const StringType& prefix) { + if (str.find(prefix, 0) == 0) + return AssertionSuccess(); + + const bool is_wide_string = sizeof(prefix[0]) > 1; + const char* const begin_string_quote = is_wide_string ? "L\"" : "\""; + return AssertionFailure() + << begin_string_quote << prefix << "\" is not a prefix of " + << begin_string_quote << str << "\"\n"; +} + +// Tests printing member variable pointers. Although they are called +// pointers, they don't point to a location in the address space. +// Their representation is implementation-defined. Thus they will be +// printed as raw bytes. + +struct Foo { + public: + virtual ~Foo() {} + int MyMethod(char x) { return x + 1; } + virtual char MyVirtualMethod(int /* n */) { return 'a'; } + + int value; +}; + +TEST(PrintPointerTest, MemberVariablePointer) { + EXPECT_TRUE(HasPrefix(Print(&Foo::value), + Print(sizeof(&Foo::value)) + "-byte object ")); + int (Foo::*p) = NULL; // NOLINT + EXPECT_TRUE(HasPrefix(Print(p), + Print(sizeof(p)) + "-byte object ")); +} + +// Tests printing member function pointers. Although they are called +// pointers, they don't point to a location in the address space. +// Their representation is implementation-defined. Thus they will be +// printed as raw bytes. +TEST(PrintPointerTest, MemberFunctionPointer) { + EXPECT_TRUE(HasPrefix(Print(&Foo::MyMethod), + Print(sizeof(&Foo::MyMethod)) + "-byte object ")); + EXPECT_TRUE( + HasPrefix(Print(&Foo::MyVirtualMethod), + Print(sizeof((&Foo::MyVirtualMethod))) + "-byte object ")); + int (Foo::*p)(char) = NULL; // NOLINT + EXPECT_TRUE(HasPrefix(Print(p), + Print(sizeof(p)) + "-byte object ")); +} + +// Tests printing C arrays. + +// The difference between this and Print() is that it ensures that the +// argument is a reference to an array. +template +string PrintArrayHelper(T (&a)[N]) { + return Print(a); +} + +// One-dimensional array. +TEST(PrintArrayTest, OneDimensionalArray) { + int a[5] = { 1, 2, 3, 4, 5 }; + EXPECT_EQ("{ 1, 2, 3, 4, 5 }", PrintArrayHelper(a)); +} + +// Two-dimensional array. +TEST(PrintArrayTest, TwoDimensionalArray) { + int a[2][5] = { + { 1, 2, 3, 4, 5 }, + { 6, 7, 8, 9, 0 } + }; + EXPECT_EQ("{ { 1, 2, 3, 4, 5 }, { 6, 7, 8, 9, 0 } }", PrintArrayHelper(a)); +} + +// Array of const elements. +TEST(PrintArrayTest, ConstArray) { + const bool a[1] = { false }; + EXPECT_EQ("{ false }", PrintArrayHelper(a)); +} + +// Char array. +TEST(PrintArrayTest, CharArray) { + // Array a contains '\0' in the middle and doesn't end with '\0'. + char a[3] = { 'H', '\0', 'i' }; + EXPECT_EQ("\"H\\0i\"", PrintArrayHelper(a)); +} + +// Const char array. +TEST(PrintArrayTest, ConstCharArray) { + const char a[4] = "\0Hi"; + EXPECT_EQ("\"\\0Hi\\0\"", PrintArrayHelper(a)); +} + +// Array of objects. +TEST(PrintArrayTest, ObjectArray) { + string a[3] = { "Hi", "Hello", "Ni hao" }; + EXPECT_EQ("{ \"Hi\", \"Hello\", \"Ni hao\" }", PrintArrayHelper(a)); +} + +// Array with many elements. +TEST(PrintArrayTest, BigArray) { + int a[100] = { 1, 2, 3 }; + EXPECT_EQ("{ 1, 2, 3, 0, 0, 0, 0, 0, ..., 0, 0, 0, 0, 0, 0, 0, 0 }", + PrintArrayHelper(a)); +} + +// Tests printing ::string and ::std::string. + +#if GTEST_HAS_GLOBAL_STRING +// ::string. +TEST(PrintStringTest, StringInGlobalNamespace) { + const char s[] = "'\"\?\\\a\b\f\n\0\r\t\v\x7F\xFF a"; + const ::string str(s, sizeof(s)); + EXPECT_EQ("\"'\\\"\\?\\\\\\a\\b\\f\\n\\0\\r\\t\\v\\x7F\\xFF a\\0\"", + Print(str)); +} +#endif // GTEST_HAS_GLOBAL_STRING + +// ::std::string. +TEST(PrintStringTest, StringInStdNamespace) { + const char s[] = "'\"\?\\\a\b\f\n\0\r\t\v\x7F\xFF a"; + const ::std::string str(s, sizeof(s)); + EXPECT_EQ("\"'\\\"\\?\\\\\\a\\b\\f\\n\\0\\r\\t\\v\\x7F\\xFF a\\0\"", + Print(str)); +} + +// Tests printing ::wstring and ::std::wstring. + +#if GTEST_HAS_GLOBAL_WSTRING +// ::wstring. +TEST(PrintWideStringTest, StringInGlobalNamespace) { + const wchar_t s[] = L"'\"\?\\\a\b\f\n\0\r\t\v\xD3\x576\x8D3\xC74D a"; + const ::wstring str(s, sizeof(s)/sizeof(wchar_t)); + EXPECT_EQ("L\"'\\\"\\?\\\\\\a\\b\\f\\n\\0\\r\\t\\v" + "\\xD3\\x576\\x8D3\\xC74D a\\0\"", + Print(str)); +} +#endif // GTEST_HAS_GLOBAL_WSTRING + +#if GTEST_HAS_STD_WSTRING +// ::std::wstring. +TEST(PrintWideStringTest, StringInStdNamespace) { + const wchar_t s[] = L"'\"\?\\\a\b\f\n\0\r\t\v\xD3\x576\x8D3\xC74D a"; + const ::std::wstring str(s, sizeof(s)/sizeof(wchar_t)); + EXPECT_EQ("L\"'\\\"\\?\\\\\\a\\b\\f\\n\\0\\r\\t\\v" + "\\xD3\\x576\\x8D3\\xC74D a\\0\"", + Print(str)); +} +#endif // GTEST_HAS_STD_WSTRING + +// Tests printing types that support generic streaming (i.e. streaming +// to std::basic_ostream for any valid Char and +// CharTraits types). + +// Tests printing a non-template type that supports generic streaming. + +class AllowsGenericStreaming {}; + +template +std::basic_ostream& operator<<( + std::basic_ostream& os, + const AllowsGenericStreaming& /* a */) { + return os << "AllowsGenericStreaming"; +} + +TEST(PrintTypeWithGenericStreamingTest, NonTemplateType) { + AllowsGenericStreaming a; + EXPECT_EQ("AllowsGenericStreaming", Print(a)); +} + +// Tests printing a template type that supports generic streaming. + +template +class AllowsGenericStreamingTemplate {}; + +template +std::basic_ostream& operator<<( + std::basic_ostream& os, + const AllowsGenericStreamingTemplate& /* a */) { + return os << "AllowsGenericStreamingTemplate"; +} + +TEST(PrintTypeWithGenericStreamingTest, TemplateType) { + AllowsGenericStreamingTemplate a; + EXPECT_EQ("AllowsGenericStreamingTemplate", Print(a)); +} + +// Tests printing a type that supports generic streaming and can be +// implicitly converted to another printable type. + +template +class AllowsGenericStreamingAndImplicitConversionTemplate { + public: + operator bool() const { return false; } +}; + +template +std::basic_ostream& operator<<( + std::basic_ostream& os, + const AllowsGenericStreamingAndImplicitConversionTemplate& /* a */) { + return os << "AllowsGenericStreamingAndImplicitConversionTemplate"; +} + +TEST(PrintTypeWithGenericStreamingTest, TypeImplicitlyConvertible) { + AllowsGenericStreamingAndImplicitConversionTemplate a; + EXPECT_EQ("AllowsGenericStreamingAndImplicitConversionTemplate", Print(a)); +} + +#if GTEST_HAS_STRING_PIECE_ + +// Tests printing StringPiece. + +TEST(PrintStringPieceTest, SimpleStringPiece) { + const StringPiece sp = "Hello"; + EXPECT_EQ("\"Hello\"", Print(sp)); +} + +TEST(PrintStringPieceTest, UnprintableCharacters) { + const char str[] = "NUL (\0) and \r\t"; + const StringPiece sp(str, sizeof(str) - 1); + EXPECT_EQ("\"NUL (\\0) and \\r\\t\"", Print(sp)); +} + +#endif // GTEST_HAS_STRING_PIECE_ + +// Tests printing STL containers. + +TEST(PrintStlContainerTest, EmptyDeque) { + deque empty; + EXPECT_EQ("{}", Print(empty)); +} + +TEST(PrintStlContainerTest, NonEmptyDeque) { + deque non_empty; + non_empty.push_back(1); + non_empty.push_back(3); + EXPECT_EQ("{ 1, 3 }", Print(non_empty)); +} + +#if GTEST_HAS_HASH_MAP_ + +TEST(PrintStlContainerTest, OneElementHashMap) { + hash_map map1; + map1[1] = 'a'; + EXPECT_EQ("{ (1, 'a' (97)) }", Print(map1)); +} + +TEST(PrintStlContainerTest, HashMultiMap) { + hash_multimap map1; + map1.insert(make_pair(5, true)); + map1.insert(make_pair(5, false)); + + // Elements of hash_multimap can be printed in any order. + const string result = Print(map1); + EXPECT_TRUE(result == "{ (5, true), (5, false) }" || + result == "{ (5, false), (5, true) }") + << " where Print(map1) returns \"" << result << "\"."; +} + +#endif // GTEST_HAS_HASH_MAP_ + +#if GTEST_HAS_HASH_SET_ + +TEST(PrintStlContainerTest, HashSet) { + hash_set set1; + set1.insert("hello"); + EXPECT_EQ("{ \"hello\" }", Print(set1)); +} + +TEST(PrintStlContainerTest, HashMultiSet) { + const int kSize = 5; + int a[kSize] = { 1, 1, 2, 5, 1 }; + hash_multiset set1(a, a + kSize); + + // Elements of hash_multiset can be printed in any order. + const string result = Print(set1); + const string expected_pattern = "{ d, d, d, d, d }"; // d means a digit. + + // Verifies the result matches the expected pattern; also extracts + // the numbers in the result. + ASSERT_EQ(expected_pattern.length(), result.length()); + std::vector numbers; + for (size_t i = 0; i != result.length(); i++) { + if (expected_pattern[i] == 'd') { + ASSERT_TRUE(isdigit(result[i]) != 0); + numbers.push_back(result[i] - '0'); + } else { + EXPECT_EQ(expected_pattern[i], result[i]) << " where result is " + << result; + } + } + + // Makes sure the result contains the right numbers. + std::sort(numbers.begin(), numbers.end()); + std::sort(a, a + kSize); + EXPECT_TRUE(std::equal(a, a + kSize, numbers.begin())); +} + +#endif // GTEST_HAS_HASH_SET_ + +TEST(PrintStlContainerTest, List) { + const char* a[] = { + "hello", + "world" + }; + const list strings(a, a + 2); + EXPECT_EQ("{ \"hello\", \"world\" }", Print(strings)); +} + +TEST(PrintStlContainerTest, Map) { + map map1; + map1[1] = true; + map1[5] = false; + map1[3] = true; + EXPECT_EQ("{ (1, true), (3, true), (5, false) }", Print(map1)); +} + +TEST(PrintStlContainerTest, MultiMap) { + multimap map1; + map1.insert(make_pair(true, 0)); + map1.insert(make_pair(true, 1)); + map1.insert(make_pair(false, 2)); + EXPECT_EQ("{ (false, 2), (true, 0), (true, 1) }", Print(map1)); +} + +TEST(PrintStlContainerTest, Set) { + const unsigned int a[] = { 3, 0, 5 }; + set set1(a, a + 3); + EXPECT_EQ("{ 0, 3, 5 }", Print(set1)); +} + +TEST(PrintStlContainerTest, MultiSet) { + const int a[] = { 1, 1, 2, 5, 1 }; + multiset set1(a, a + 5); + EXPECT_EQ("{ 1, 1, 1, 2, 5 }", Print(set1)); +} + +TEST(PrintStlContainerTest, Pair) { + pair p(true, 5); + EXPECT_EQ("(true, 5)", Print(p)); +} + +TEST(PrintStlContainerTest, Vector) { + vector v; + v.push_back(1); + v.push_back(2); + EXPECT_EQ("{ 1, 2 }", Print(v)); +} + +TEST(PrintStlContainerTest, LongSequence) { + const int a[100] = { 1, 2, 3 }; + const vector v(a, a + 100); + EXPECT_EQ("{ 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, " + "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ... }", Print(v)); +} + +TEST(PrintStlContainerTest, NestedContainer) { + const int a1[] = { 1, 2 }; + const int a2[] = { 3, 4, 5 }; + const list l1(a1, a1 + 2); + const list l2(a2, a2 + 3); + + vector > v; + v.push_back(l1); + v.push_back(l2); + EXPECT_EQ("{ { 1, 2 }, { 3, 4, 5 } }", Print(v)); +} + +TEST(PrintStlContainerTest, OneDimensionalNativeArray) { + const int a[3] = { 1, 2, 3 }; + NativeArray b(a, 3, kReference); + EXPECT_EQ("{ 1, 2, 3 }", Print(b)); +} + +TEST(PrintStlContainerTest, TwoDimensionalNativeArray) { + const int a[2][3] = { { 1, 2, 3 }, { 4, 5, 6 } }; + NativeArray b(a, 2, kReference); + EXPECT_EQ("{ { 1, 2, 3 }, { 4, 5, 6 } }", Print(b)); +} + +#if GTEST_HAS_TR1_TUPLE +// Tests printing tuples. + +// Tuples of various arities. +TEST(PrintTupleTest, VariousSizes) { + tuple<> t0; + EXPECT_EQ("()", Print(t0)); + + tuple t1(5); + EXPECT_EQ("(5)", Print(t1)); + + tuple t2('a', true); + EXPECT_EQ("('a' (97), true)", Print(t2)); + + tuple t3(false, 2, 3); + EXPECT_EQ("(false, 2, 3)", Print(t3)); + + tuple t4(false, 2, 3, 4); + EXPECT_EQ("(false, 2, 3, 4)", Print(t4)); + + tuple t5(false, 2, 3, 4, true); + EXPECT_EQ("(false, 2, 3, 4, true)", Print(t5)); + + tuple t6(false, 2, 3, 4, true, 6); + EXPECT_EQ("(false, 2, 3, 4, true, 6)", Print(t6)); + + tuple t7(false, 2, 3, 4, true, 6, 7); + EXPECT_EQ("(false, 2, 3, 4, true, 6, 7)", Print(t7)); + + tuple t8( + false, 2, 3, 4, true, 6, 7, true); + EXPECT_EQ("(false, 2, 3, 4, true, 6, 7, true)", Print(t8)); + + tuple t9( + false, 2, 3, 4, true, 6, 7, true, 9); + EXPECT_EQ("(false, 2, 3, 4, true, 6, 7, true, 9)", Print(t9)); + + const char* const str = "8"; + tuple + t10(false, 'a', 3, 4, 5, 1.5F, -2.5, str, NULL, "10"); + EXPECT_EQ("(false, 'a' (97), 3, 4, 5, 1.5, -2.5, " + PrintPointer(str) + + " pointing to \"8\", NULL, \"10\")", + Print(t10)); +} + +// Nested tuples. +TEST(PrintTupleTest, NestedTuple) { + tuple, char> nested(make_tuple(5, true), 'a'); + EXPECT_EQ("((5, true), 'a' (97))", Print(nested)); +} + +#endif // GTEST_HAS_TR1_TUPLE + +// Tests printing user-defined unprintable types. + +// Unprintable types in the global namespace. +TEST(PrintUnprintableTypeTest, InGlobalNamespace) { + EXPECT_EQ("1-byte object <00>", + Print(UnprintableTemplateInGlobal())); +} + +// Unprintable types in a user namespace. +TEST(PrintUnprintableTypeTest, InUserNamespace) { + EXPECT_EQ("16-byte object ", + Print(::foo::UnprintableInFoo())); +} + +// Unprintable types are that too big to be printed completely. + +struct Big { + Big() { memset(array, 0, sizeof(array)); } + char array[257]; +}; + +TEST(PrintUnpritableTypeTest, BigObject) { + EXPECT_EQ("257-byte object <0000 0000 0000 0000 0000 0000 " + "0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 " + "0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 " + "0000 0000 0000 0000 0000 0000 ... 0000 0000 0000 " + "0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 " + "0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 " + "0000 0000 0000 0000 0000 0000 0000 0000 00>", + Print(Big())); +} + +// Tests printing user-defined streamable types. + +// Streamable types in the global namespace. +TEST(PrintStreamableTypeTest, InGlobalNamespace) { + EXPECT_EQ("StreamableInGlobal", + Print(StreamableInGlobal())); +} + +// Printable template types in a user namespace. +TEST(PrintStreamableTypeTest, TemplateTypeInUserNamespace) { + EXPECT_EQ("StreamableTemplateInFoo: 0", + Print(::foo::StreamableTemplateInFoo())); +} + +// Tests printing user-defined types that have a PrintTo() function. +TEST(PrintPrintableTypeTest, InUserNamespace) { + EXPECT_EQ("PrintableViaPrintTo: 0", + Print(::foo::PrintableViaPrintTo())); +} + +// Tests printing user-defined class template that have a PrintTo() function. +TEST(PrintPrintableTypeTest, TemplateInUserNamespace) { + EXPECT_EQ("PrintableViaPrintToTemplate: 5", + Print(::foo::PrintableViaPrintToTemplate(5))); +} + +#if GTEST_HAS_PROTOBUF_ + +// Tests printing a protocol message. +TEST(PrintProtocolMessageTest, PrintsShortDebugString) { + testing::internal::TestMessage msg; + msg.set_member("yes"); + EXPECT_EQ("", Print(msg)); +} + +// Tests printing a short proto2 message. +TEST(PrintProto2MessageTest, PrintsShortDebugStringWhenItIsShort) { + testing::internal::FooMessage msg; + msg.set_int_field(2); + msg.set_string_field("hello"); + EXPECT_PRED2(RE::FullMatch, Print(msg), + ""); +} + +// Tests printing a long proto2 message. +TEST(PrintProto2MessageTest, PrintsDebugStringWhenItIsLong) { + testing::internal::FooMessage msg; + msg.set_int_field(2); + msg.set_string_field("hello"); + msg.add_names("peter"); + msg.add_names("paul"); + msg.add_names("mary"); + EXPECT_PRED2(RE::FullMatch, Print(msg), + "<\n" + "int_field:\\s*2\n" + "string_field:\\s*\"hello\"\n" + "names:\\s*\"peter\"\n" + "names:\\s*\"paul\"\n" + "names:\\s*\"mary\"\n" + ">"); +} + +#endif // GTEST_HAS_PROTOBUF_ + +// Tests that the universal printer prints both the address and the +// value of a reference. +TEST(PrintReferenceTest, PrintsAddressAndValue) { + int n = 5; + EXPECT_EQ("@" + PrintPointer(&n) + " 5", PrintByRef(n)); + + int a[2][3] = { + { 0, 1, 2 }, + { 3, 4, 5 } + }; + EXPECT_EQ("@" + PrintPointer(a) + " { { 0, 1, 2 }, { 3, 4, 5 } }", + PrintByRef(a)); + + const ::foo::UnprintableInFoo x; + EXPECT_EQ("@" + PrintPointer(&x) + " 16-byte object " + "", + PrintByRef(x)); +} + +// Tests that the universal printer prints a function pointer passed by +// reference. +TEST(PrintReferenceTest, HandlesFunctionPointer) { + void (*fp)(int n) = &MyFunction; + const string fp_pointer_string = + PrintPointer(reinterpret_cast(&fp)); + // We cannot directly cast &MyFunction to const void* because the + // standard disallows casting between pointers to functions and + // pointers to objects, and some compilers (e.g. GCC 3.4) enforce + // this limitation. + const string fp_string = PrintPointer(reinterpret_cast( + reinterpret_cast(fp))); + EXPECT_EQ("@" + fp_pointer_string + " " + fp_string, + PrintByRef(fp)); +} + +// Tests that the universal printer prints a member function pointer +// passed by reference. +TEST(PrintReferenceTest, HandlesMemberFunctionPointer) { + int (Foo::*p)(char ch) = &Foo::MyMethod; + EXPECT_TRUE(HasPrefix( + PrintByRef(p), + "@" + PrintPointer(reinterpret_cast(&p)) + " " + + Print(sizeof(p)) + "-byte object ")); + + char (Foo::*p2)(int n) = &Foo::MyVirtualMethod; + EXPECT_TRUE(HasPrefix( + PrintByRef(p2), + "@" + PrintPointer(reinterpret_cast(&p2)) + " " + + Print(sizeof(p2)) + "-byte object ")); +} + +// Tests that the universal printer prints a member variable pointer +// passed by reference. +TEST(PrintReferenceTest, HandlesMemberVariablePointer) { + int (Foo::*p) = &Foo::value; // NOLINT + EXPECT_TRUE(HasPrefix( + PrintByRef(p), + "@" + PrintPointer(&p) + " " + Print(sizeof(p)) + "-byte object ")); +} + +TEST(PrintToStringTest, WorksForScalar) { + EXPECT_EQ("123", PrintToString(123)); +} + +TEST(PrintToStringTest, WorksForPointerToConstChar) { + const char* p = "hello"; + EXPECT_EQ("\"hello\"", PrintToString(p)); +} + +TEST(PrintToStringTest, WorksForPointerToNonConstChar) { + char s[] = "hello"; + char* p = s; + EXPECT_EQ("\"hello\"", PrintToString(p)); +} + +TEST(PrintToStringTest, WorksForArray) { + int n[3] = { 1, 2, 3 }; + EXPECT_EQ("{ 1, 2, 3 }", PrintToString(n)); +} + +TEST(UniversalTersePrintTest, WorksForNonReference) { + ::std::stringstream ss; + UniversalTersePrint(123, &ss); + EXPECT_EQ("123", ss.str()); +} + +TEST(UniversalTersePrintTest, WorksForReference) { + const int& n = 123; + ::std::stringstream ss; + UniversalTersePrint(n, &ss); + EXPECT_EQ("123", ss.str()); +} + +TEST(UniversalTersePrintTest, WorksForCString) { + const char* s1 = "abc"; + ::std::stringstream ss1; + UniversalTersePrint(s1, &ss1); + EXPECT_EQ("\"abc\"", ss1.str()); + + char* s2 = const_cast(s1); + ::std::stringstream ss2; + UniversalTersePrint(s2, &ss2); + EXPECT_EQ("\"abc\"", ss2.str()); + + const char* s3 = NULL; + ::std::stringstream ss3; + UniversalTersePrint(s3, &ss3); + EXPECT_EQ("NULL", ss3.str()); +} + +TEST(UniversalPrintTest, WorksForNonReference) { + ::std::stringstream ss; + UniversalPrint(123, &ss); + EXPECT_EQ("123", ss.str()); +} + +TEST(UniversalPrintTest, WorksForReference) { + const int& n = 123; + ::std::stringstream ss; + UniversalPrint(n, &ss); + EXPECT_EQ("123", ss.str()); +} + +TEST(UniversalPrintTest, WorksForCString) { + const char* s1 = "abc"; + ::std::stringstream ss1; + UniversalPrint(s1, &ss1); + EXPECT_EQ(PrintPointer(s1) + " pointing to \"abc\"", string(ss1.str())); + + char* s2 = const_cast(s1); + ::std::stringstream ss2; + UniversalPrint(s2, &ss2); + EXPECT_EQ(PrintPointer(s2) + " pointing to \"abc\"", string(ss2.str())); + + const char* s3 = NULL; + ::std::stringstream ss3; + UniversalPrint(s3, &ss3); + EXPECT_EQ("NULL", ss3.str()); +} + + +#if GTEST_HAS_TR1_TUPLE + +TEST(UniversalTersePrintTupleFieldsToStringsTest, PrintsEmptyTuple) { + Strings result = UniversalTersePrintTupleFieldsToStrings(make_tuple()); + EXPECT_EQ(0u, result.size()); +} + +TEST(UniversalTersePrintTupleFieldsToStringsTest, PrintsOneTuple) { + Strings result = UniversalTersePrintTupleFieldsToStrings(make_tuple(1)); + ASSERT_EQ(1u, result.size()); + EXPECT_EQ("1", result[0]); +} + +TEST(UniversalTersePrintTupleFieldsToStringsTest, PrintsTwoTuple) { + Strings result = UniversalTersePrintTupleFieldsToStrings(make_tuple(1, 'a')); + ASSERT_EQ(2u, result.size()); + EXPECT_EQ("1", result[0]); + EXPECT_EQ("'a' (97)", result[1]); +} + +TEST(UniversalTersePrintTupleFieldsToStringsTest, PrintsTersely) { + const int n = 1; + Strings result = UniversalTersePrintTupleFieldsToStrings( + tuple(n, "a")); + ASSERT_EQ(2u, result.size()); + EXPECT_EQ("1", result[0]); + EXPECT_EQ("\"a\"", result[1]); +} + +#endif // GTEST_HAS_TR1_TUPLE + +} // namespace gtest_printers_test +} // namespace testing diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index adc0fffa..a92809f7 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -132,23 +132,28 @@ using testing::Message; using testing::ScopedFakeTestPartResultReporter; using testing::StaticAssertTypeEq; using testing::Test; -using testing::TestEventListeners; using testing::TestCase; +using testing::TestEventListeners; using testing::TestPartResult; using testing::TestPartResultArray; using testing::TestProperty; using testing::TestResult; using testing::UnitTest; using testing::kMaxStackTraceDepth; +using testing::internal::AddReference; using testing::internal::AlwaysFalse; using testing::internal::AlwaysTrue; using testing::internal::AppendUserMessage; +using testing::internal::ArrayAwareFind; +using testing::internal::ArrayEq; using testing::internal::CodePointToUtf8; +using testing::internal::CompileAssertTypesEqual; +using testing::internal::CopyArray; using testing::internal::CountIf; using testing::internal::EqFailure; using testing::internal::FloatingPoint; -using testing::internal::FormatTimeInMillisAsSeconds; using testing::internal::ForEach; +using testing::internal::FormatTimeInMillisAsSeconds; using testing::internal::GTestFlagSaver; using testing::internal::GetCurrentOsStackTraceExceptTop; using testing::internal::GetElementOr; @@ -157,9 +162,17 @@ using testing::internal::GetRandomSeedFromFlag; using testing::internal::GetTestTypeId; using testing::internal::GetTypeId; using testing::internal::GetUnitTestImpl; +using testing::internal::ImplicitlyConvertible; using testing::internal::Int32; using testing::internal::Int32FromEnvOrDie; +using testing::internal::IsAProtocolMessage; +using testing::internal::IsContainer; +using testing::internal::IsContainerTest; +using testing::internal::IsNotContainer; +using testing::internal::NativeArray; using testing::internal::ParseInt32Flag; +using testing::internal::RemoveConst; +using testing::internal::RemoveReference; using testing::internal::ShouldRunTestOnShard; using testing::internal::ShouldShard; using testing::internal::ShouldUseColor; @@ -171,7 +184,9 @@ using testing::internal::TestEventListenersAccessor; using testing::internal::TestResultAccessor; using testing::internal::UInt32; using testing::internal::WideStringToUtf8; +using testing::internal::kCopy; using testing::internal::kMaxRandomSeed; +using testing::internal::kReference; using testing::internal::kTestTypeIdInGoogleTest; using testing::internal::scoped_ptr; @@ -184,6 +199,10 @@ using testing::internal::GetCapturedStdout; using testing::internal::ThreadWithParam; #endif +#if GTEST_HAS_PROTOBUF_ +using ::testing::internal::TestMessage; +#endif // GTEST_HAS_PROTOBUF_ + class TestingVector : public std::vector { }; @@ -6725,3 +6744,319 @@ GTEST_TEST(AlternativeNameTest, Works) { // GTEST_TEST is the same as TEST. EXPECT_FATAL_FAILURE(GTEST_FAIL() << "An expected failure", "An expected failure"); } + +// Tests for internal utilities necessary for implementation of the universal +// printing. +// TODO(vladl@google.com): Find a better home for them. + +class ConversionHelperBase {}; +class ConversionHelperDerived : public ConversionHelperBase {}; + +// Tests that IsAProtocolMessage::value is a compile-time constant. +TEST(IsAProtocolMessageTest, ValueIsCompileTimeConstant) { + GTEST_COMPILE_ASSERT_(IsAProtocolMessage::value, + const_true); + GTEST_COMPILE_ASSERT_(!IsAProtocolMessage::value, const_false); +} + +// Tests that IsAProtocolMessage::value is true when T is +// ProtocolMessage or a sub-class of it. +TEST(IsAProtocolMessageTest, ValueIsTrueWhenTypeIsAProtocolMessage) { + EXPECT_TRUE(IsAProtocolMessage< ::proto2::Message>::value); + EXPECT_TRUE(IsAProtocolMessage::value); +#if GTEST_HAS_PROTOBUF_ + EXPECT_TRUE(IsAProtocolMessage::value); +#endif // GTEST_HAS_PROTOBUF_ +} + +// Tests that IsAProtocolMessage::value is false when T is neither +// ProtocolMessage nor a sub-class of it. +TEST(IsAProtocolMessageTest, ValueIsFalseWhenTypeIsNotAProtocolMessage) { + EXPECT_FALSE(IsAProtocolMessage::value); + EXPECT_FALSE(IsAProtocolMessage::value); +} + +// Tests that CompileAssertTypesEqual compiles when the type arguments are +// equal. +TEST(CompileAssertTypesEqual, CompilesWhenTypesAreEqual) { + CompileAssertTypesEqual(); + CompileAssertTypesEqual(); +} + +// Tests that RemoveReference does not affect non-reference types. +TEST(RemoveReferenceTest, DoesNotAffectNonReferenceType) { + CompileAssertTypesEqual::type>(); + CompileAssertTypesEqual::type>(); +} + +// Tests that RemoveReference removes reference from reference types. +TEST(RemoveReferenceTest, RemovesReference) { + CompileAssertTypesEqual::type>(); + CompileAssertTypesEqual::type>(); +} + +// Tests GTEST_REMOVE_REFERENCE_. + +template +void TestGTestRemoveReference() { + CompileAssertTypesEqual(); +} + +TEST(RemoveReferenceTest, MacroVersion) { + TestGTestRemoveReference(); + TestGTestRemoveReference(); +} + + +// Tests that RemoveConst does not affect non-const types. +TEST(RemoveConstTest, DoesNotAffectNonConstType) { + CompileAssertTypesEqual::type>(); + CompileAssertTypesEqual::type>(); +} + +// Tests that RemoveConst removes const from const types. +TEST(RemoveConstTest, RemovesConst) { + CompileAssertTypesEqual::type>(); + CompileAssertTypesEqual::type>(); + CompileAssertTypesEqual::type>(); +} + +// Tests GTEST_REMOVE_CONST_. + +template +void TestGTestRemoveConst() { + CompileAssertTypesEqual(); +} + +TEST(RemoveConstTest, MacroVersion) { + TestGTestRemoveConst(); + TestGTestRemoveConst(); + TestGTestRemoveConst(); +} + +// Tests that AddReference does not affect reference types. +TEST(AddReferenceTest, DoesNotAffectReferenceType) { + CompileAssertTypesEqual::type>(); + CompileAssertTypesEqual::type>(); +} + +// Tests that AddReference adds reference to non-reference types. +TEST(AddReferenceTest, AddsReference) { + CompileAssertTypesEqual::type>(); + CompileAssertTypesEqual::type>(); +} + +// Tests GTEST_ADD_REFERENCE_. + +template +void TestGTestAddReference() { + CompileAssertTypesEqual(); +} + +TEST(AddReferenceTest, MacroVersion) { + TestGTestAddReference(); + TestGTestAddReference(); +} + +// Tests GTEST_REFERENCE_TO_CONST_. + +template +void TestGTestReferenceToConst() { + CompileAssertTypesEqual(); +} + +TEST(GTestReferenceToConstTest, Works) { + TestGTestReferenceToConst(); + TestGTestReferenceToConst(); + TestGTestReferenceToConst(); + TestGTestReferenceToConst(); +} + +// Tests that ImplicitlyConvertible::value is a compile-time constant. +TEST(ImplicitlyConvertibleTest, ValueIsCompileTimeConstant) { + GTEST_COMPILE_ASSERT_((ImplicitlyConvertible::value), const_true); + GTEST_COMPILE_ASSERT_((!ImplicitlyConvertible::value), + const_false); +} + +// Tests that ImplicitlyConvertible::value is true when T1 can +// be implicitly converted to T2. +TEST(ImplicitlyConvertibleTest, ValueIsTrueWhenConvertible) { + EXPECT_TRUE((ImplicitlyConvertible::value)); + EXPECT_TRUE((ImplicitlyConvertible::value)); + EXPECT_TRUE((ImplicitlyConvertible::value)); + EXPECT_TRUE((ImplicitlyConvertible::value)); + EXPECT_TRUE((ImplicitlyConvertible::value)); + EXPECT_TRUE((ImplicitlyConvertible::value)); +} + +// Tests that ImplicitlyConvertible::value is false when T1 +// cannot be implicitly converted to T2. +TEST(ImplicitlyConvertibleTest, ValueIsFalseWhenNotConvertible) { + EXPECT_FALSE((ImplicitlyConvertible::value)); + EXPECT_FALSE((ImplicitlyConvertible::value)); + EXPECT_FALSE((ImplicitlyConvertible::value)); + EXPECT_FALSE((ImplicitlyConvertible::value)); +} + +// Tests IsContainerTest. + +class NonContainer {}; + +TEST(IsContainerTestTest, WorksForNonContainer) { + EXPECT_EQ(sizeof(IsNotContainer), sizeof(IsContainerTest(0))); + EXPECT_EQ(sizeof(IsNotContainer), sizeof(IsContainerTest(0))); + EXPECT_EQ(sizeof(IsNotContainer), sizeof(IsContainerTest(0))); +} + +TEST(IsContainerTestTest, WorksForContainer) { + EXPECT_EQ(sizeof(IsContainer), + sizeof(IsContainerTest >(0))); + EXPECT_EQ(sizeof(IsContainer), + sizeof(IsContainerTest >(0))); +} + +// Tests ArrayEq(). + +TEST(ArrayEqTest, WorksForDegeneratedArrays) { + EXPECT_TRUE(ArrayEq(5, 5L)); + EXPECT_FALSE(ArrayEq('a', 0)); +} + +TEST(ArrayEqTest, WorksForOneDimensionalArrays) { + const int a[] = { 0, 1 }; + long b[] = { 0, 1 }; + EXPECT_TRUE(ArrayEq(a, b)); + EXPECT_TRUE(ArrayEq(a, 2, b)); + + b[0] = 2; + EXPECT_FALSE(ArrayEq(a, b)); + EXPECT_FALSE(ArrayEq(a, 1, b)); +} + +TEST(ArrayEqTest, WorksForTwoDimensionalArrays) { + const char a[][3] = { "hi", "lo" }; + const char b[][3] = { "hi", "lo" }; + const char c[][3] = { "hi", "li" }; + + EXPECT_TRUE(ArrayEq(a, b)); + EXPECT_TRUE(ArrayEq(a, 2, b)); + + EXPECT_FALSE(ArrayEq(a, c)); + EXPECT_FALSE(ArrayEq(a, 2, c)); +} + +// Tests ArrayAwareFind(). + +TEST(ArrayAwareFindTest, WorksForOneDimensionalArray) { + const char a[] = "hello"; + EXPECT_EQ(a + 4, ArrayAwareFind(a, a + 5, 'o')); + EXPECT_EQ(a + 5, ArrayAwareFind(a, a + 5, 'x')); +} + +TEST(ArrayAwareFindTest, WorksForTwoDimensionalArray) { + int a[][2] = { { 0, 1 }, { 2, 3 }, { 4, 5 } }; + const int b[2] = { 2, 3 }; + EXPECT_EQ(a + 1, ArrayAwareFind(a, a + 3, b)); + + const int c[2] = { 6, 7 }; + EXPECT_EQ(a + 3, ArrayAwareFind(a, a + 3, c)); +} + +// Tests CopyArray(). + +TEST(CopyArrayTest, WorksForDegeneratedArrays) { + int n = 0; + CopyArray('a', &n); + EXPECT_EQ('a', n); +} + +TEST(CopyArrayTest, WorksForOneDimensionalArrays) { + const char a[3] = "hi"; + int b[3]; + CopyArray(a, &b); + EXPECT_TRUE(ArrayEq(a, b)); + + int c[3]; + CopyArray(a, 3, c); + EXPECT_TRUE(ArrayEq(a, c)); +} + +TEST(CopyArrayTest, WorksForTwoDimensionalArrays) { + const int a[2][3] = { { 0, 1, 2 }, { 3, 4, 5 } }; + int b[2][3]; + CopyArray(a, &b); + EXPECT_TRUE(ArrayEq(a, b)); + + int c[2][3]; + CopyArray(a, 2, c); + EXPECT_TRUE(ArrayEq(a, c)); +} + +// Tests NativeArray. + +TEST(NativeArrayTest, ConstructorFromArrayWorks) { + const int a[3] = { 0, 1, 2 }; + NativeArray na(a, 3, kReference); + EXPECT_EQ(3U, na.size()); + EXPECT_EQ(a, na.begin()); +} + +TEST(NativeArrayTest, CreatesAndDeletesCopyOfArrayWhenAskedTo) { + typedef int Array[2]; + Array* a = new Array[1]; + (*a)[0] = 0; + (*a)[1] = 1; + NativeArray na(*a, 2, kCopy); + EXPECT_NE(*a, na.begin()); + delete[] a; + EXPECT_EQ(0, na.begin()[0]); + EXPECT_EQ(1, na.begin()[1]); + + // We rely on the heap checker to verify that na deletes the copy of + // array. +} + +TEST(NativeArrayTest, TypeMembersAreCorrect) { + StaticAssertTypeEq::value_type>(); + StaticAssertTypeEq::value_type>(); + + StaticAssertTypeEq::const_iterator>(); + StaticAssertTypeEq::const_iterator>(); +} + +TEST(NativeArrayTest, MethodsWork) { + const int a[3] = { 0, 1, 2 }; + NativeArray na(a, 3, kCopy); + ASSERT_EQ(3U, na.size()); + EXPECT_EQ(3, na.end() - na.begin()); + + NativeArray::const_iterator it = na.begin(); + EXPECT_EQ(0, *it); + ++it; + EXPECT_EQ(1, *it); + it++; + EXPECT_EQ(2, *it); + ++it; + EXPECT_EQ(na.end(), it); + + EXPECT_TRUE(na == na); + + NativeArray na2(a, 3, kReference); + EXPECT_TRUE(na == na2); + + const int b1[3] = { 0, 1, 1 }; + const int b2[4] = { 0, 1, 2, 3 }; + EXPECT_FALSE(na == NativeArray(b1, 3, kReference)); + EXPECT_FALSE(na == NativeArray(b2, 4, kCopy)); +} + +TEST(NativeArrayTest, WorksForTwoDimensionalArray) { + const char a[2][3] = { "hi", "lo" }; + NativeArray na(a, 2, kReference); + ASSERT_EQ(2U, na.size()); + EXPECT_EQ(a, na.begin()); +} -- cgit v1.2.3 From 3678a248d35723d5e18c7c2a78d7da5b4f5a3e57 Mon Sep 17 00:00:00 2001 From: vladlosev Date: Thu, 13 May 2010 18:05:20 +0000 Subject: Renames test script flags. --- test/gtest_help_test.py | 2 +- test/gtest_output_test.py | 2 +- test/gtest_test_utils.py | 10 +++++----- test/run_tests_util.py | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) (limited to 'test') diff --git a/test/gtest_help_test.py b/test/gtest_help_test.py index 3cb4c48e..dc67ed3d 100755 --- a/test/gtest_help_test.py +++ b/test/gtest_help_test.py @@ -32,7 +32,7 @@ """Tests the --help flag of Google C++ Testing Framework. SYNOPSIS - gtest_help_test.py --gtest_build_dir=BUILD/DIR + gtest_help_test.py --build_dir=BUILD/DIR # where BUILD/DIR contains the built gtest_help_test_ file. gtest_help_test.py """ diff --git a/test/gtest_output_test.py b/test/gtest_output_test.py index 192030a2..dca4af04 100755 --- a/test/gtest_output_test.py +++ b/test/gtest_output_test.py @@ -32,7 +32,7 @@ """Tests the text output of Google C++ Testing Framework. SYNOPSIS - gtest_output_test.py --gtest_build_dir=BUILD/DIR --gengolden + gtest_output_test.py --build_dir=BUILD/DIR --gengolden # where BUILD/DIR contains the built gtest_output_test_ file. gtest_output_test.py --gengolden gtest_output_test.py diff --git a/test/gtest_test_utils.py b/test/gtest_test_utils.py index e0f5973e..e7ee9d9c 100755 --- a/test/gtest_test_utils.py +++ b/test/gtest_test_utils.py @@ -63,8 +63,8 @@ TestCase = _test_module.TestCase # pylint: disable-msg=C6409 # Initially maps a flag to its default value. After # _ParseAndStripGTestFlags() is called, maps a flag to its actual value. -_flag_map = {'gtest_source_dir': os.path.dirname(sys.argv[0]), - 'gtest_build_dir': os.path.dirname(sys.argv[0])} +_flag_map = {'source_dir': os.path.dirname(sys.argv[0]), + 'build_dir': os.path.dirname(sys.argv[0])} _gtest_flags_are_parsed = False @@ -111,13 +111,13 @@ def GetFlag(flag): def GetSourceDir(): """Returns the absolute path of the directory where the .py files are.""" - return os.path.abspath(GetFlag('gtest_source_dir')) + return os.path.abspath(GetFlag('source_dir')) def GetBuildDir(): """Returns the absolute path of the directory where the test binaries are.""" - return os.path.abspath(GetFlag('gtest_build_dir')) + return os.path.abspath(GetFlag('build_dir')) _temp_dir = None @@ -161,7 +161,7 @@ def GetTestExecutablePath(executable_name, build_dir=None): if not os.path.exists(path): message = ( 'Unable to find the test binary. Please make sure to provide path\n' - 'to the binary via the --gtest_build_dir flag or the GTEST_BUILD_DIR\n' + 'to the binary via the --build_dir flag or the BUILD_DIR\n' 'environment variable. For convenient use, invoke this script via\n' 'mk_test.py.\n' # TODO(vladl@google.com): change mk_test.py to test.py after renaming diff --git a/test/run_tests_util.py b/test/run_tests_util.py index 9e57931e..a123569e 100755 --- a/test/run_tests_util.py +++ b/test/run_tests_util.py @@ -171,7 +171,7 @@ class TestRunner(object): def __init__(self, script_dir, - build_dir_var_name='GTEST_BUILD_DIR', + build_dir_var_name='BUILD_DIR', injected_os=os, injected_subprocess=subprocess, injected_build_dir_finder=_GetGtestBuildDir): -- cgit v1.2.3 From 55d166a2228d7e3b3500b8651ab9b8e56fb43b7e Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Mon, 17 May 2010 19:31:00 +0000 Subject: Adds GTEST_REMOVE_REFERENCE_AND_CONST_. --- test/gtest_unittest.cc | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'test') diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index a92809f7..40049aef 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -6834,6 +6834,21 @@ TEST(RemoveConstTest, MacroVersion) { TestGTestRemoveConst(); } +// Tests GTEST_REMOVE_REFERENCE_AND_CONST_. + +template +void TestGTestRemoveReferenceAndConst() { + CompileAssertTypesEqual(); +} + +TEST(RemoveReferenceToConstTest, Works) { + TestGTestRemoveReferenceAndConst(); + TestGTestRemoveReferenceAndConst(); + TestGTestRemoveReferenceAndConst(); + TestGTestRemoveReferenceAndConst(); + TestGTestRemoveReferenceAndConst(); +} + // Tests that AddReference does not affect reference types. TEST(AddReferenceTest, DoesNotAffectReferenceType) { CompileAssertTypesEqual::type>(); -- cgit v1.2.3 From 1097b54dcf1cd393e64ec0adf54301a575bbbc1c Mon Sep 17 00:00:00 2001 From: vladlosev Date: Tue, 18 May 2010 21:13:48 +0000 Subject: Implements printing parameters of failed parameterized tests (issue 71). --- test/gtest-param-test_test.cc | 39 +++++++++++++++++++++++++++++++---- test/gtest_output_test.py | 2 +- test/gtest_output_test_.cc | 14 +++++++++++++ test/gtest_output_test_golden_lin.txt | 22 +++++++++++++------- test/gtest_output_test_golden_win.txt | 21 ++++++++++++------- 5 files changed, 79 insertions(+), 19 deletions(-) (limited to 'test') diff --git a/test/gtest-param-test_test.cc b/test/gtest-param-test_test.cc index d0a0e735..26acce4c 100644 --- a/test/gtest-param-test_test.cc +++ b/test/gtest-param-test_test.cc @@ -792,19 +792,50 @@ INSTANTIATE_TEST_CASE_P(FourElemSequence, SeparateInstanceTest, Range(1, 4)); // sequence element used to instantiate the test. class NamingTest : public TestWithParam {}; -TEST_P(NamingTest, TestsAreNamedAppropriately) { +TEST_P(NamingTest, TestsAreNamedAndCommentedCorrectly) { const ::testing::TestInfo* const test_info = ::testing::UnitTest::GetInstance()->current_test_info(); EXPECT_STREQ("ZeroToFiveSequence/NamingTest", test_info->test_case_name()); - Message msg; - msg << "TestsAreNamedAppropriately/" << GetParam(); - EXPECT_STREQ(msg.GetString().c_str(), test_info->name()); + Message index_stream; + index_stream << "TestsAreNamedAndCommentedCorrectly/" << GetParam(); + EXPECT_STREQ(index_stream.GetString().c_str(), test_info->name()); + + const ::std::string comment = + "GetParam() = " + ::testing::PrintToString(GetParam()); + EXPECT_EQ(comment, test_info->comment()); } INSTANTIATE_TEST_CASE_P(ZeroToFiveSequence, NamingTest, Range(0, 5)); +// Class that cannot be streamed into an ostream. It needs to be copyable +// (and, in case of MSVC, also assignable) in order to be a test parameter +// type. Its default copy constructor and assignment operator do exactly +// what we need. +class Unstreamable { + public: + explicit Unstreamable(int value) : value_(value) {} + + private: + int value_; +}; + +class CommentTest : public TestWithParam {}; + +TEST_P(CommentTest, TestsWithUnstreamableParamsCommentedCorrectly) { + const ::testing::TestInfo* const test_info = + ::testing::UnitTest::GetInstance()->current_test_info(); + + const ::std::string comment = + "GetParam() = " + ::testing::PrintToString(GetParam()); + EXPECT_EQ(comment, test_info->comment()); +} + +INSTANTIATE_TEST_CASE_P(InstantiationWithComments, + CommentTest, + Values(Unstreamable(1))); + #endif // GTEST_HAS_PARAM_TEST TEST(CompileTest, CombineIsDefinedOnlyWhenGtestHasParamTestIsDefined) { diff --git a/test/gtest_output_test.py b/test/gtest_output_test.py index dca4af04..425d9da4 100755 --- a/test/gtest_output_test.py +++ b/test/gtest_output_test.py @@ -240,7 +240,7 @@ SUPPORTS_STACK_TRACES = False CAN_GENERATE_GOLDEN_FILE = (SUPPORTS_DEATH_TESTS and SUPPORTS_TYPED_TESTS and - SUPPORTS_THREADS) + (SUPPORTS_THREADS or IS_WINDOWS)) class GTestOutputTest(gtest_test_utils.TestCase): diff --git a/test/gtest_output_test_.cc b/test/gtest_output_test_.cc index 32fb49a9..1ac439c6 100644 --- a/test/gtest_output_test_.cc +++ b/test/gtest_output_test_.cc @@ -87,6 +87,20 @@ TEST(PassingTest, PassingTest1) { TEST(PassingTest, PassingTest2) { } +// Tests that parameters of failing parameterized tests are printed in the +// failing test summary. +class FailingParamTest : public testing::TestWithParam {}; + +TEST_P(FailingParamTest, Fails) { + EXPECT_EQ(1, GetParam()); +} + +// This generates a test which will fail. Google Test is expected to print +// its parameter when it outputs the list of all failed tests. +INSTANTIATE_TEST_CASE_P(PrintingFailingParams, + FailingParamTest, + testing::Values(2)); + // Tests catching a fatal failure in a subroutine. TEST(FatalFailureTest, FatalFailureInSubroutine) { printf("(expecting a failure that x should be 1)\n"); diff --git a/test/gtest_output_test_golden_lin.txt b/test/gtest_output_test_golden_lin.txt index ec60437a..2f3994a0 100644 --- a/test/gtest_output_test_golden_lin.txt +++ b/test/gtest_output_test_golden_lin.txt @@ -7,7 +7,7 @@ Expected: true gtest_output_test_.cc:#: Failure Value of: 3 Expected: 2 -[==========] Running 60 tests from 25 test cases. +[==========] Running 61 tests from 26 test cases. [----------] Global test environment set-up. FooEnvironment::SetUp() called. BarEnvironment::SetUp() called. @@ -411,7 +411,7 @@ Value of: TypeParam() Actual: 0 Expected: 1 Expected failure -[ FAILED ] TypedTest/0.Failure +[ FAILED ] TypedTest/0.Failure, where TypeParam = int [----------] 2 tests from Unsigned/TypedTestP/0, where TypeParam = unsigned char [ RUN ] Unsigned/TypedTestP/0.Success [ OK ] Unsigned/TypedTestP/0.Success @@ -422,7 +422,7 @@ Value of: TypeParam() Expected: 1U Which is: 1 Expected failure -[ FAILED ] Unsigned/TypedTestP/0.Failure +[ FAILED ] Unsigned/TypedTestP/0.Failure, where TypeParam = unsigned char [----------] 2 tests from Unsigned/TypedTestP/1, where TypeParam = unsigned int [ RUN ] Unsigned/TypedTestP/1.Success [ OK ] Unsigned/TypedTestP/1.Success @@ -433,7 +433,7 @@ Value of: TypeParam() Expected: 1U Which is: 1 Expected failure -[ FAILED ] Unsigned/TypedTestP/1.Failure +[ FAILED ] Unsigned/TypedTestP/1.Failure, where TypeParam = unsigned int [----------] 4 tests from ExpectFailureTest [ RUN ] ExpectFailureTest.ExpectFatalFailure (expecting 1 failure) @@ -564,6 +564,13 @@ gtest_output_test_.cc:#: Failure Failed Expected non-fatal failure. [ FAILED ] ScopedFakeTestPartResultReporterTest.InterceptOnlyCurrentThread +[----------] 1 test from PrintingFailingParams/FailingParamTest +[ RUN ] PrintingFailingParams/FailingParamTest.Fails/0 +gtest_output_test_.cc:#: Failure +Value of: GetParam() + Actual: 2 +Expected: 1 +[ FAILED ] PrintingFailingParams/FailingParamTest.Fails/0, where GetParam() = 2 [----------] Global test environment tear-down BarEnvironment::TearDown() called. gtest_output_test_.cc:#: Failure @@ -573,9 +580,9 @@ FooEnvironment::TearDown() called. gtest_output_test_.cc:#: Failure Failed Expected fatal failure. -[==========] 60 tests from 25 test cases ran. +[==========] 61 tests from 26 test cases ran. [ PASSED ] 21 tests. -[ FAILED ] 39 tests, listed below: +[ FAILED ] 40 tests, listed below: [ FAILED ] FatalFailureTest.FatalFailureInSubroutine [ FAILED ] FatalFailureTest.FatalFailureInNestedSubroutine [ FAILED ] FatalFailureTest.NonfatalFailureInSubroutine @@ -615,8 +622,9 @@ Expected fatal failure. [ FAILED ] ExpectFailureWithThreadsTest.ExpectFatalFailure [ FAILED ] ExpectFailureWithThreadsTest.ExpectNonFatalFailure [ FAILED ] ScopedFakeTestPartResultReporterTest.InterceptOnlyCurrentThread +[ FAILED ] PrintingFailingParams/FailingParamTest.Fails/0, where GetParam() = 2 -39 FAILED TESTS +40 FAILED TESTS  YOU HAVE 1 DISABLED TEST Note: Google Test filter = FatalFailureTest.*:LoggingTest.* diff --git a/test/gtest_output_test_golden_win.txt b/test/gtest_output_test_golden_win.txt index 313c3aaf..fb697103 100644 --- a/test/gtest_output_test_golden_win.txt +++ b/test/gtest_output_test_golden_win.txt @@ -5,7 +5,7 @@ gtest_output_test_.cc:#: error: Value of: false Expected: true gtest_output_test_.cc:#: error: Value of: 3 Expected: 2 -[==========] Running 61 tests from 27 test cases. +[==========] Running 62 tests from 28 test cases. [----------] Global test environment set-up. FooEnvironment::SetUp() called. BarEnvironment::SetUp() called. @@ -369,7 +369,7 @@ gtest_output_test_.cc:#: error: Value of: TypeParam() Actual: 0 Expected: 1 Expected failure -[ FAILED ] TypedTest/0.Failure +[ FAILED ] TypedTest/0.Failure, where TypeParam = int [----------] 2 tests from Unsigned/TypedTestP/0, where TypeParam = unsigned char [ RUN ] Unsigned/TypedTestP/0.Success [ OK ] Unsigned/TypedTestP/0.Success @@ -379,7 +379,7 @@ gtest_output_test_.cc:#: error: Value of: TypeParam() Expected: 1U Which is: 1 Expected failure -[ FAILED ] Unsigned/TypedTestP/0.Failure +[ FAILED ] Unsigned/TypedTestP/0.Failure, where TypeParam = unsigned char [----------] 2 tests from Unsigned/TypedTestP/1, where TypeParam = unsigned int [ RUN ] Unsigned/TypedTestP/1.Success [ OK ] Unsigned/TypedTestP/1.Success @@ -389,7 +389,7 @@ gtest_output_test_.cc:#: error: Value of: TypeParam() Expected: 1U Which is: 1 Expected failure -[ FAILED ] Unsigned/TypedTestP/1.Failure +[ FAILED ] Unsigned/TypedTestP/1.Failure, where TypeParam = unsigned int [----------] 4 tests from ExpectFailureTest [ RUN ] ExpectFailureTest.ExpectFatalFailure (expecting 1 failure) @@ -479,6 +479,12 @@ Failed Expected non-fatal failure. [ FAILED ] ExpectFailureTest.ExpectNonFatalFailureOnAllThreads +[----------] 1 test from PrintingFailingParams/FailingParamTest +[ RUN ] PrintingFailingParams/FailingParamTest.Fails/0 +gtest_output_test_.cc:#: error: Value of: GetParam() + Actual: 2 +Expected: 1 +[ FAILED ] PrintingFailingParams/FailingParamTest.Fails/0, where GetParam() = 2 [----------] Global test environment tear-down BarEnvironment::TearDown() called. gtest_output_test_.cc:#: error: Failed @@ -486,9 +492,9 @@ Expected non-fatal failure. FooEnvironment::TearDown() called. gtest_output_test_.cc:#: error: Failed Expected fatal failure. -[==========] 61 tests from 27 test cases ran. +[==========] 62 tests from 28 test cases ran. [ PASSED ] 21 tests. -[ FAILED ] 40 tests, listed below: +[ FAILED ] 41 tests, listed below: [ FAILED ] FatalFailureTest.FatalFailureInSubroutine [ FAILED ] FatalFailureTest.FatalFailureInNestedSubroutine [ FAILED ] FatalFailureTest.NonfatalFailureInSubroutine @@ -529,8 +535,9 @@ Expected fatal failure. [ FAILED ] ExpectFailureTest.ExpectNonFatalFailure [ FAILED ] ExpectFailureTest.ExpectFatalFailureOnAllThreads [ FAILED ] ExpectFailureTest.ExpectNonFatalFailureOnAllThreads +[ FAILED ] PrintingFailingParams/FailingParamTest.Fails/0, where GetParam() = 2 -40 FAILED TESTS +41 FAILED TESTS YOU HAVE 1 DISABLED TEST Note: Google Test filter = FatalFailureTest.*:LoggingTest.* -- cgit v1.2.3 From 0e41324393d526c25118eee05f6d81e15bfab0d6 Mon Sep 17 00:00:00 2001 From: vladlosev Date: Sat, 22 May 2010 00:27:10 +0000 Subject: Fixes issue 286. --- test/gtest-printers_test.cc | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'test') diff --git a/test/gtest-printers_test.cc b/test/gtest-printers_test.cc index 0ecd8715..fae3fa41 100644 --- a/test/gtest-printers_test.cc +++ b/test/gtest-printers_test.cc @@ -84,10 +84,9 @@ namespace foo { // A user-defined unprintable type in a user namespace. class UnprintableInFoo { public: - UnprintableInFoo() : x_(0x12EF), y_(0xAB34), z_(0) {} + UnprintableInFoo() : z_(0) { memcpy(xy_, "\xEF\x12\x0\x0\x34\xAB\x0\x0", 8); } private: - testing::internal::Int32 x_; - testing::internal::Int32 y_; + char xy_[8]; double z_; }; -- cgit v1.2.3 From 985a30360ce4824b65cb35ad55faa0d7c1ad1104 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Tue, 8 Jun 2010 22:51:46 +0000 Subject: Adds tests for SkipPrefix(). --- test/gtest_unittest.cc | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'test') diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index 40049aef..a65ce922 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -178,6 +178,7 @@ using testing::internal::ShouldShard; using testing::internal::ShouldUseColor; using testing::internal::Shuffle; using testing::internal::ShuffleRange; +using testing::internal::SkipPrefix; using testing::internal::StreamableToString; using testing::internal::String; using testing::internal::TestEventListenersAccessor; @@ -7075,3 +7076,29 @@ TEST(NativeArrayTest, WorksForTwoDimensionalArray) { ASSERT_EQ(2U, na.size()); EXPECT_EQ(a, na.begin()); } + +// Tests SkipPrefix(). + +TEST(SkipPrefixTest, SkipsWhenPrefixMatches) { + const char* const str = "hello"; + + const char* p = str; + EXPECT_TRUE(SkipPrefix("", &p)); + EXPECT_EQ(str, p); + + p = str; + EXPECT_TRUE(SkipPrefix("hell", &p)); + EXPECT_EQ(str + 4, p); +} + +TEST(SkipPrefixTest, DoesNotSkipWhenPrefixDoesNotMatch) { + const char* const str = "world"; + + const char* p = str; + EXPECT_FALSE(SkipPrefix("W", &p)); + EXPECT_EQ(str, p); + + p = str; + EXPECT_FALSE(SkipPrefix("world!", &p)); + EXPECT_EQ(str, p); +} -- cgit v1.2.3 From 682c89f7557eb53c7359b6cbf3670c05165f2419 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Wed, 16 Jun 2010 22:47:13 +0000 Subject: Makes gtest report failures in ad hoc test assertions executed before RUN_ALL_TESTS(). --- test/gtest_environment_test.cc | 5 +++++ test/gtest_no_test_unittest.cc | 11 +++++++---- 2 files changed, 12 insertions(+), 4 deletions(-) (limited to 'test') diff --git a/test/gtest_environment_test.cc b/test/gtest_environment_test.cc index c9392614..94ea318b 100644 --- a/test/gtest_environment_test.cc +++ b/test/gtest_environment_test.cc @@ -35,6 +35,10 @@ #include #include +#define GTEST_IMPLEMENTATION_ 1 // Required for the next #include. +#include "src/gtest-internal-inl.h" +#undef GTEST_IMPLEMENTATION_ + namespace testing { GTEST_DECLARE_string_(filter); } @@ -123,6 +127,7 @@ int RunAllTests(MyEnvironment* env, FailureType failure) { env->Reset(); env->set_failure_in_set_up(failure); test_was_run = false; + testing::internal::GetUnitTestImpl()->ClearAdHocTestResult(); return RUN_ALL_TESTS(); } diff --git a/test/gtest_no_test_unittest.cc b/test/gtest_no_test_unittest.cc index afe2dc0c..e09ca73a 100644 --- a/test/gtest_no_test_unittest.cc +++ b/test/gtest_no_test_unittest.cc @@ -40,15 +40,18 @@ int main(int argc, char **argv) { // An ad-hoc assertion outside of all tests. // - // This serves two purposes: + // This serves three purposes: // // 1. It verifies that an ad-hoc assertion can be executed even if // no test is defined. - // 2. We had a bug where the XML output won't be generated if an + // 2. It verifies that a failed ad-hoc assertion causes the test + // program to fail. + // 3. We had a bug where the XML output won't be generated if an // assertion is executed before RUN_ALL_TESTS() is called, even // though --gtest_output=xml is specified. This makes sure the // bug is fixed and doesn't regress. - EXPECT_EQ(1, 1); + EXPECT_EQ(1, 2); - return RUN_ALL_TESTS(); + // The above EXPECT_EQ() should cause RUN_ALL_TESTS() to return non-zero. + return RUN_ALL_TESTS() ? 0 : 1; } -- cgit v1.2.3 From 5e4214cee4f74d25f1d89dc1c95dc247ed20b6c8 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Thu, 8 Jul 2010 21:44:59 +0000 Subject: Makes gtest_break_on_failure_unittest work on minGW (by vladl); improves the NULL-dereferencing hack to work with LLVM (by chandlerc). --- test/gtest_break_on_failure_unittest_.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'test') diff --git a/test/gtest_break_on_failure_unittest_.cc b/test/gtest_break_on_failure_unittest_.cc index d28d1d3d..6779c903 100644 --- a/test/gtest_break_on_failure_unittest_.cc +++ b/test/gtest_break_on_failure_unittest_.cc @@ -69,7 +69,7 @@ int main(int argc, char **argv) { // a general protection fault (segment violation). SetErrorMode(SEM_NOGPFAULTERRORBOX | SEM_FAILCRITICALERRORS); -#if !GTEST_OS_WINDOWS_MOBILE +#if GTEST_HAS_SEH && !GTEST_OS_WINDOWS_MOBILE // The default unhandled exception filter does not always exit // with the exception code as exit code - for example it exits with // 0 for EXCEPTION_ACCESS_VIOLATION and 1 for EXCEPTION_BREAKPOINT -- cgit v1.2.3 From e2a7f03b80fc0e9e6a6f36acb43776509486a6d4 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Wed, 21 Jul 2010 22:15:17 +0000 Subject: Allows EXPECT_EQ to accept arguments that don't have operator << (by Zhanyong Wan). Allows a user to customize how the universal printer prints a pointer of a specific type by overloading << (by Zhanyong Wan). Works around a bug in Cymbian's C++ compiler (by Vlad Losev). --- test/gtest-printers_test.cc | 94 +++++++++++++++++++++++------------ test/gtest_output_test_golden_lin.txt | 2 +- test/gtest_output_test_golden_win.txt | 2 +- test/gtest_unittest.cc | 59 ++++++++++++++++++++++ 4 files changed, 123 insertions(+), 34 deletions(-) (limited to 'test') diff --git a/test/gtest-printers_test.cc b/test/gtest-printers_test.cc index fae3fa41..11f6625b 100644 --- a/test/gtest-printers_test.cc +++ b/test/gtest-printers_test.cc @@ -79,6 +79,10 @@ inline void operator<<(::std::ostream& os, const StreamableInGlobal& /* x */) { os << "StreamableInGlobal"; } +void operator<<(::std::ostream& os, const StreamableInGlobal* /* x */) { + os << "StreamableInGlobal*"; +} + namespace foo { // A user-defined unprintable type in a user namespace. @@ -100,6 +104,15 @@ void PrintTo(const PrintableViaPrintTo& x, ::std::ostream* os) { *os << "PrintableViaPrintTo: " << x.value; } +// A type with a user-defined << for printing its pointer. +struct PointerPrintable { +}; + +::std::ostream& operator<<(::std::ostream& os, + const PointerPrintable* /* x */) { + return os << "PointerPrintable*"; +} + // A user-defined printable class template in a user-chosen namespace. template class PrintableViaPrintToTemplate { @@ -199,21 +212,21 @@ string PrintByRef(const T& value) { // char. TEST(PrintCharTest, PlainChar) { EXPECT_EQ("'\\0'", Print('\0')); - EXPECT_EQ("'\\'' (39)", Print('\'')); - EXPECT_EQ("'\"' (34)", Print('"')); - EXPECT_EQ("'\\?' (63)", Print('\?')); - EXPECT_EQ("'\\\\' (92)", Print('\\')); + EXPECT_EQ("'\\'' (39, 0x27)", Print('\'')); + EXPECT_EQ("'\"' (34, 0x22)", Print('"')); + EXPECT_EQ("'\\?' (63, 0x3F)", Print('\?')); + EXPECT_EQ("'\\\\' (92, 0x5C)", Print('\\')); EXPECT_EQ("'\\a' (7)", Print('\a')); EXPECT_EQ("'\\b' (8)", Print('\b')); - EXPECT_EQ("'\\f' (12)", Print('\f')); - EXPECT_EQ("'\\n' (10)", Print('\n')); - EXPECT_EQ("'\\r' (13)", Print('\r')); + EXPECT_EQ("'\\f' (12, 0xC)", Print('\f')); + EXPECT_EQ("'\\n' (10, 0xA)", Print('\n')); + EXPECT_EQ("'\\r' (13, 0xD)", Print('\r')); EXPECT_EQ("'\\t' (9)", Print('\t')); - EXPECT_EQ("'\\v' (11)", Print('\v')); + EXPECT_EQ("'\\v' (11, 0xB)", Print('\v')); EXPECT_EQ("'\\x7F' (127)", Print('\x7F')); EXPECT_EQ("'\\xFF' (255)", Print('\xFF')); - EXPECT_EQ("' ' (32)", Print(' ')); - EXPECT_EQ("'a' (97)", Print('a')); + EXPECT_EQ("' ' (32, 0x20)", Print(' ')); + EXPECT_EQ("'a' (97, 0x61)", Print('a')); } // signed char. @@ -226,7 +239,7 @@ TEST(PrintCharTest, SignedChar) { // unsigned char. TEST(PrintCharTest, UnsignedChar) { EXPECT_EQ("'\\0'", Print(static_cast('\0'))); - EXPECT_EQ("'b' (98)", + EXPECT_EQ("'b' (98, 0x62)", Print(static_cast('b'))); } @@ -241,21 +254,21 @@ TEST(PrintBuiltInTypeTest, Bool) { // wchar_t. TEST(PrintBuiltInTypeTest, Wchar_t) { EXPECT_EQ("L'\\0'", Print(L'\0')); - EXPECT_EQ("L'\\'' (39)", Print(L'\'')); - EXPECT_EQ("L'\"' (34)", Print(L'"')); - EXPECT_EQ("L'\\?' (63)", Print(L'\?')); - EXPECT_EQ("L'\\\\' (92)", Print(L'\\')); + EXPECT_EQ("L'\\'' (39, 0x27)", Print(L'\'')); + EXPECT_EQ("L'\"' (34, 0x22)", Print(L'"')); + EXPECT_EQ("L'\\?' (63, 0x3F)", Print(L'\?')); + EXPECT_EQ("L'\\\\' (92, 0x5C)", Print(L'\\')); EXPECT_EQ("L'\\a' (7)", Print(L'\a')); EXPECT_EQ("L'\\b' (8)", Print(L'\b')); - EXPECT_EQ("L'\\f' (12)", Print(L'\f')); - EXPECT_EQ("L'\\n' (10)", Print(L'\n')); - EXPECT_EQ("L'\\r' (13)", Print(L'\r')); + EXPECT_EQ("L'\\f' (12, 0xC)", Print(L'\f')); + EXPECT_EQ("L'\\n' (10, 0xA)", Print(L'\n')); + EXPECT_EQ("L'\\r' (13, 0xD)", Print(L'\r')); EXPECT_EQ("L'\\t' (9)", Print(L'\t')); - EXPECT_EQ("L'\\v' (11)", Print(L'\v')); + EXPECT_EQ("L'\\v' (11, 0xB)", Print(L'\v')); EXPECT_EQ("L'\\x7F' (127)", Print(L'\x7F')); EXPECT_EQ("L'\\xFF' (255)", Print(L'\xFF')); - EXPECT_EQ("L' ' (32)", Print(L' ')); - EXPECT_EQ("L'a' (97)", Print(L'a')); + EXPECT_EQ("L' ' (32, 0x20)", Print(L' ')); + EXPECT_EQ("L'a' (97, 0x61)", Print(L'a')); EXPECT_EQ("L'\\x576' (1398)", Print(L'\x576')); EXPECT_EQ("L'\\xC74D' (51021)", Print(L'\xC74D')); } @@ -700,7 +713,7 @@ TEST(PrintStlContainerTest, NonEmptyDeque) { TEST(PrintStlContainerTest, OneElementHashMap) { hash_map map1; map1[1] = 'a'; - EXPECT_EQ("{ (1, 'a' (97)) }", Print(map1)); + EXPECT_EQ("{ (1, 'a' (97, 0x61)) }", Print(map1)); } TEST(PrintStlContainerTest, HashMultiMap) { @@ -848,7 +861,7 @@ TEST(PrintTupleTest, VariousSizes) { EXPECT_EQ("(5)", Print(t1)); tuple t2('a', true); - EXPECT_EQ("('a' (97), true)", Print(t2)); + EXPECT_EQ("('a' (97, 0x61), true)", Print(t2)); tuple t3(false, 2, 3); EXPECT_EQ("(false, 2, 3)", Print(t3)); @@ -877,7 +890,7 @@ TEST(PrintTupleTest, VariousSizes) { tuple t10(false, 'a', 3, 4, 5, 1.5F, -2.5, str, NULL, "10"); - EXPECT_EQ("(false, 'a' (97), 3, 4, 5, 1.5, -2.5, " + PrintPointer(str) + + EXPECT_EQ("(false, 'a' (97, 0x61), 3, 4, 5, 1.5, -2.5, " + PrintPointer(str) + " pointing to \"8\", NULL, \"10\")", Print(t10)); } @@ -885,7 +898,7 @@ TEST(PrintTupleTest, VariousSizes) { // Nested tuples. TEST(PrintTupleTest, NestedTuple) { tuple, char> nested(make_tuple(5, true), 'a'); - EXPECT_EQ("((5, true), 'a' (97))", Print(nested)); + EXPECT_EQ("((5, true), 'a' (97, 0x61))", Print(nested)); } #endif // GTEST_HAS_TR1_TUPLE @@ -926,8 +939,9 @@ TEST(PrintUnpritableTypeTest, BigObject) { // Streamable types in the global namespace. TEST(PrintStreamableTypeTest, InGlobalNamespace) { - EXPECT_EQ("StreamableInGlobal", - Print(StreamableInGlobal())); + StreamableInGlobal x; + EXPECT_EQ("StreamableInGlobal", Print(x)); + EXPECT_EQ("StreamableInGlobal*", Print(&x)); } // Printable template types in a user namespace. @@ -942,6 +956,13 @@ TEST(PrintPrintableTypeTest, InUserNamespace) { Print(::foo::PrintableViaPrintTo())); } +// Tests printing a pointer to a user-defined type that has a << +// operator for its pointer. +TEST(PrintPrintableTypeTest, PointerInUserNamespace) { + ::foo::PointerPrintable x; + EXPECT_EQ("PointerPrintable*", Print(&x)); +} + // Tests printing user-defined class template that have a PrintTo() function. TEST(PrintPrintableTypeTest, TemplateInUserNamespace) { EXPECT_EQ("PrintableViaPrintToTemplate: 5", @@ -1046,26 +1067,35 @@ TEST(PrintReferenceTest, HandlesMemberVariablePointer) { "@" + PrintPointer(&p) + " " + Print(sizeof(p)) + "-byte object ")); } +// Useful for testing PrintToString(). We cannot use EXPECT_EQ() +// there as its implementation uses PrintToString(). The caller must +// ensure that 'value' has no side effect. +#define EXPECT_PRINT_TO_STRING_(value, expected_string) \ + EXPECT_TRUE(PrintToString(value) == (expected_string)) \ + << " where " #value " prints as " << (PrintToString(value)) + TEST(PrintToStringTest, WorksForScalar) { - EXPECT_EQ("123", PrintToString(123)); + EXPECT_PRINT_TO_STRING_(123, "123"); } TEST(PrintToStringTest, WorksForPointerToConstChar) { const char* p = "hello"; - EXPECT_EQ("\"hello\"", PrintToString(p)); + EXPECT_PRINT_TO_STRING_(p, "\"hello\""); } TEST(PrintToStringTest, WorksForPointerToNonConstChar) { char s[] = "hello"; char* p = s; - EXPECT_EQ("\"hello\"", PrintToString(p)); + EXPECT_PRINT_TO_STRING_(p, "\"hello\""); } TEST(PrintToStringTest, WorksForArray) { int n[3] = { 1, 2, 3 }; - EXPECT_EQ("{ 1, 2, 3 }", PrintToString(n)); + EXPECT_PRINT_TO_STRING_(n, "{ 1, 2, 3 }"); } +#undef EXPECT_PRINT_TO_STRING_ + TEST(UniversalTersePrintTest, WorksForNonReference) { ::std::stringstream ss; UniversalTersePrint(123, &ss); @@ -1144,7 +1174,7 @@ TEST(UniversalTersePrintTupleFieldsToStringsTest, PrintsTwoTuple) { Strings result = UniversalTersePrintTupleFieldsToStrings(make_tuple(1, 'a')); ASSERT_EQ(2u, result.size()); EXPECT_EQ("1", result[0]); - EXPECT_EQ("'a' (97)", result[1]); + EXPECT_EQ("'a' (97, 0x61)", result[1]); } TEST(UniversalTersePrintTupleFieldsToStringsTest, PrintsTersely) { diff --git a/test/gtest_output_test_golden_lin.txt b/test/gtest_output_test_golden_lin.txt index 2f3994a0..9b30445e 100644 --- a/test/gtest_output_test_golden_lin.txt +++ b/test/gtest_output_test_golden_lin.txt @@ -418,7 +418,7 @@ Expected failure [ RUN ] Unsigned/TypedTestP/0.Failure gtest_output_test_.cc:#: Failure Value of: TypeParam() - Actual: \0 + Actual: '\0' Expected: 1U Which is: 1 Expected failure diff --git a/test/gtest_output_test_golden_win.txt b/test/gtest_output_test_golden_win.txt index fb697103..bf76b8cc 100644 --- a/test/gtest_output_test_golden_win.txt +++ b/test/gtest_output_test_golden_win.txt @@ -375,7 +375,7 @@ Expected failure [ OK ] Unsigned/TypedTestP/0.Success [ RUN ] Unsigned/TypedTestP/0.Failure gtest_output_test_.cc:#: error: Value of: TypeParam() - Actual: \0 + Actual: '\0' Expected: 1U Which is: 1 Expected failure diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index a65ce922..e11b6a66 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -4652,6 +4652,65 @@ TEST(EqAssertionTest, OtherPointer) { "0x1234"); } +// A class that supports binary comparison operators but not streaming. +class UnprintableChar { + public: + explicit UnprintableChar(char ch) : char_(ch) {} + + bool operator==(const UnprintableChar& rhs) const { + return char_ == rhs.char_; + } + bool operator!=(const UnprintableChar& rhs) const { + return char_ != rhs.char_; + } + bool operator<(const UnprintableChar& rhs) const { + return char_ < rhs.char_; + } + bool operator<=(const UnprintableChar& rhs) const { + return char_ <= rhs.char_; + } + bool operator>(const UnprintableChar& rhs) const { + return char_ > rhs.char_; + } + bool operator>=(const UnprintableChar& rhs) const { + return char_ >= rhs.char_; + } + + private: + char char_; +}; + +// Tests that ASSERT_EQ() and friends don't require the arguments to +// be printable. +TEST(ComparisonAssertionTest, AcceptsUnprintableArgs) { + const UnprintableChar x('x'), y('y'); + ASSERT_EQ(x, x); + EXPECT_NE(x, y); + ASSERT_LT(x, y); + EXPECT_LE(x, y); + ASSERT_GT(y, x); + EXPECT_GE(x, x); + + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(x, y), "1-byte object <78>"); + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(x, y), "1-byte object <79>"); + EXPECT_NONFATAL_FAILURE(EXPECT_LT(y, y), "1-byte object <79>"); + EXPECT_NONFATAL_FAILURE(EXPECT_GT(x, y), "1-byte object <78>"); + EXPECT_NONFATAL_FAILURE(EXPECT_GT(x, y), "1-byte object <79>"); + + // Code tested by EXPECT_FATAL_FAILURE cannot reference local + // variables, so we have to write UnprintableChar('x') instead of x. + EXPECT_FATAL_FAILURE(ASSERT_NE(UnprintableChar('x'), UnprintableChar('x')), + "1-byte object <78>"); + EXPECT_FATAL_FAILURE(ASSERT_LE(UnprintableChar('y'), UnprintableChar('x')), + "1-byte object <78>"); + EXPECT_FATAL_FAILURE(ASSERT_LE(UnprintableChar('y'), UnprintableChar('x')), + "1-byte object <79>"); + EXPECT_FATAL_FAILURE(ASSERT_GE(UnprintableChar('x'), UnprintableChar('y')), + "1-byte object <78>"); + EXPECT_FATAL_FAILURE(ASSERT_GE(UnprintableChar('x'), UnprintableChar('y')), + "1-byte object <79>"); +} + // Tests the FRIEND_TEST macro. // This class has a private member we want to test. We will test it -- cgit v1.2.3 From e96d247b20116646f343b6e2ec37af154f655977 Mon Sep 17 00:00:00 2001 From: vladlosev Date: Thu, 22 Jul 2010 21:07:19 +0000 Subject: Allows Google Test to build on OSes other then a pre-determined set and implements GTEST_HAS_POSIX_REGEX condition for compatibility with them. --- test/gtest-port_test.cc | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'test') diff --git a/test/gtest-port_test.cc b/test/gtest-port_test.cc index 6f1512ce..6cdbfab4 100644 --- a/test/gtest-port_test.cc +++ b/test/gtest-port_test.cc @@ -284,6 +284,17 @@ TEST(GtestCheckDeathTest, LivesSilentlyOnSuccess) { #endif // GTEST_HAS_DEATH_TEST +// Verifies that Google Test choose regular expression engine appropriate to +// the platform. The test will produce compiler errors in case of failure. +// For simplicity, we only cover the most important platforms here. +TEST(RegexEngineSelectionTest, SelectsCorrectRegexEngine) { +#if GTEST_HAS_POSIX_RE + EXPECT_TRUE(GTEST_USES_POSIX_RE); +#else + EXPECT_TRUE(GTEST_USES_SIMPLE_RE); +#endif +} + #if GTEST_USES_POSIX_RE #if GTEST_HAS_TYPED_TEST -- cgit v1.2.3 From 744de6fa59f81232f0d82fc9b35c4aa0f9ccb5c0 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Thu, 22 Jul 2010 22:03:48 +0000 Subject: Removes unused scons-related scripts; makes gtest_nc_test compatible with Clang. --- test/gtest_nc_test.py | 16 +- test/run_tests_util.py | 466 ------------------------------ test/run_tests_util_test.py | 676 -------------------------------------------- 3 files changed, 12 insertions(+), 1146 deletions(-) delete mode 100755 test/run_tests_util.py delete mode 100755 test/run_tests_util_test.py (limited to 'test') diff --git a/test/gtest_nc_test.py b/test/gtest_nc_test.py index 06ffb3f8..bf09234a 100755 --- a/test/gtest_nc_test.py +++ b/test/gtest_nc_test.py @@ -72,19 +72,27 @@ class GTestNCTest(unittest.TestCase): [r'Setup_should_be_spelled_SetUp']), ('CATCHES_WRONG_CASE_IN_TYPED_TEST_P', - [r'BarTest.*was not declared']), + [r'BarTest.*was not declared', # GCC + r'undeclared identifier .*BarTest', # Clang + ]), ('CATCHES_WRONG_CASE_IN_REGISTER_TYPED_TEST_CASE_P', - [r'BarTest.*was not declared']), + [r'BarTest.*was not declared', # GCC + r'undeclared identifier .*BarTest', # Clang + ]), ('CATCHES_WRONG_CASE_IN_INSTANTIATE_TYPED_TEST_CASE_P', - [r'BarTest.*not declared']), + [r'BarTest.*not declared', # GCC + r'undeclared identifier .*BarTest', # Clang + ]), ('CATCHES_INSTANTIATE_TYPED_TESET_CASE_P_WITH_SAME_NAME_PREFIX', [r'redefinition of.*My.*FooTest']), ('STATIC_ASSERT_TYPE_EQ_IS_NOT_A_TYPE', - [r'StaticAssertTypeEq.* does not name a type']), + [r'StaticAssertTypeEq.* does not name a type', # GCC + r'requires a type.*\n.*StaticAssertTypeEq', # Clang + ]), ('STATIC_ASSERT_TYPE_EQ_WORKS_IN_NAMESPACE', [r'StaticAssertTypeEq.*int.*const int']), diff --git a/test/run_tests_util.py b/test/run_tests_util.py deleted file mode 100755 index a123569e..00000000 --- a/test/run_tests_util.py +++ /dev/null @@ -1,466 +0,0 @@ -# Copyright 2008 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. - -"""Provides facilities for running SCons-built Google Test/Mock tests.""" - - -import optparse -import os -import re -import sets -import sys - -try: - # subrocess module is a preferable way to invoke subprocesses but it may - # not be available on MacOS X 10.4. - # Suppresses the 'Import not at the top of the file' lint complaint. - # pylint: disable-msg=C6204 - import subprocess -except ImportError: - subprocess = None - -HELP_MSG = """Runs the specified tests for %(proj)s. - -SYNOPSIS - run_tests.py [OPTION]... [BUILD_DIR]... [TEST]... - -DESCRIPTION - Runs the specified tests (either binary or Python), and prints a - summary of the results. BUILD_DIRS will be used to search for the - binaries. If no TESTs are specified, all binary tests found in - BUILD_DIRs and all Python tests found in the directory test/ (in the - %(proj)s root) are run. - - TEST is a name of either a binary or a Python test. A binary test is - an executable file named *_test or *_unittest (with the .exe - extension on Windows) A Python test is a script named *_test.py or - *_unittest.py. - -OPTIONS - -h, --help - Print this help message. - -c CONFIGURATIONS - Specify build directories via build configurations. - CONFIGURATIONS is either a comma-separated list of build - configurations or 'all'. Each configuration is equivalent to - adding 'scons/build//%(proj)s/scons' to BUILD_DIRs. - Specifying -c=all is equivalent to providing all directories - listed in KNOWN BUILD DIRECTORIES section below. - -a - Equivalent to -c=all - -b - Equivalent to -c=all with the exception that the script will not - fail if some of the KNOWN BUILD DIRECTORIES do not exists; the - script will simply not run the tests there. 'b' stands for - 'built directories'. - -RETURN VALUE - Returns 0 if all tests are successful; otherwise returns 1. - -EXAMPLES - run_tests.py - Runs all tests for the default build configuration. - run_tests.py -a - Runs all tests with binaries in KNOWN BUILD DIRECTORIES. - run_tests.py -b - Runs all tests in KNOWN BUILD DIRECTORIES that have been - built. - run_tests.py foo/ - Runs all tests in the foo/ directory and all Python tests in - the directory test. The Python tests are instructed to look - for binaries in foo/. - run_tests.py bar_test.exe test/baz_test.exe foo/ bar/ - Runs foo/bar_test.exe, bar/bar_test.exe, foo/baz_test.exe, and - bar/baz_test.exe. - run_tests.py foo bar test/foo_test.py - Runs test/foo_test.py twice instructing it to look for its - test binaries in the directories foo and bar, - correspondingly. - -KNOWN BUILD DIRECTORIES - run_tests.py knows about directories where the SCons build script - deposits its products. These are the directories where run_tests.py - will be looking for its binaries. Currently, %(proj)s's SConstruct file - defines them as follows (the default build directory is the first one - listed in each group): - On Windows: - <%(proj)s root>/scons/build/win-dbg8/%(proj)s/scons/ - <%(proj)s root>/scons/build/win-opt8/%(proj)s/scons/ - On Mac: - <%(proj)s root>/scons/build/mac-dbg/%(proj)s/scons/ - <%(proj)s root>/scons/build/mac-opt/%(proj)s/scons/ - On other platforms: - <%(proj)s root>/scons/build/dbg/%(proj)s/scons/ - <%(proj)s root>/scons/build/opt/%(proj)s/scons/""" - -IS_WINDOWS = os.name == 'nt' -IS_MAC = os.name == 'posix' and os.uname()[0] == 'Darwin' -IS_CYGWIN = os.name == 'posix' and 'CYGWIN' in os.uname()[0] - -# Definition of CONFIGS must match that of the build directory names in the -# SConstruct script. The first list item is the default build configuration. -if IS_WINDOWS: - CONFIGS = ('win-dbg8', 'win-opt8') -elif IS_MAC: - CONFIGS = ('mac-dbg', 'mac-opt') -else: - CONFIGS = ('dbg', 'opt') - -if IS_WINDOWS or IS_CYGWIN: - PYTHON_TEST_REGEX = re.compile(r'_(unit)?test\.py$', re.IGNORECASE) - BINARY_TEST_REGEX = re.compile(r'_(unit)?test(\.exe)?$', re.IGNORECASE) - BINARY_TEST_SEARCH_REGEX = re.compile(r'_(unit)?test\.exe$', re.IGNORECASE) -else: - PYTHON_TEST_REGEX = re.compile(r'_(unit)?test\.py$') - BINARY_TEST_REGEX = re.compile(r'_(unit)?test$') - BINARY_TEST_SEARCH_REGEX = BINARY_TEST_REGEX - - -def _GetGtestBuildDir(injected_os, script_dir, config): - """Calculates path to the Google Test SCons build directory.""" - - return injected_os.path.normpath(injected_os.path.join(script_dir, - 'scons/build', - config, - 'gtest/scons')) - - -def _GetConfigFromBuildDir(build_dir): - """Extracts the configuration name from the build directory.""" - - # We don't want to depend on build_dir containing the correct path - # separators. - m = re.match(r'.*[\\/]([^\\/]+)[\\/][^\\/]+[\\/]scons[\\/]?$', build_dir) - if m: - return m.group(1) - else: - print >>sys.stderr, ('%s is an invalid build directory that does not ' - 'correspond to any configuration.' % (build_dir,)) - return '' - - -# All paths in this script are either absolute or relative to the current -# working directory, unless otherwise specified. -class TestRunner(object): - """Provides facilities for running Python and binary tests for Google Test.""" - - def __init__(self, - script_dir, - build_dir_var_name='BUILD_DIR', - injected_os=os, - injected_subprocess=subprocess, - injected_build_dir_finder=_GetGtestBuildDir): - """Initializes a TestRunner instance. - - Args: - script_dir: File path to the calling script. - build_dir_var_name: Name of the env variable used to pass the - the build directory path to the invoked - tests. - injected_os: standard os module or a mock/stub for - testing. - injected_subprocess: standard subprocess module or a mock/stub - for testing - injected_build_dir_finder: function that determines the path to - the build directory. - """ - - self.os = injected_os - self.subprocess = injected_subprocess - self.build_dir_finder = injected_build_dir_finder - self.build_dir_var_name = build_dir_var_name - self.script_dir = script_dir - - def _GetBuildDirForConfig(self, config): - """Returns the build directory for a given configuration.""" - - return self.build_dir_finder(self.os, self.script_dir, config) - - def _Run(self, args): - """Runs the executable with given args (args[0] is the executable name). - - Args: - args: Command line arguments for the process. - - Returns: - Process's exit code if it exits normally, or -signal if the process is - killed by a signal. - """ - - if self.subprocess: - return self.subprocess.Popen(args).wait() - else: - return self.os.spawnv(self.os.P_WAIT, args[0], args) - - def _RunBinaryTest(self, test): - """Runs the binary test given its path. - - Args: - test: Path to the test binary. - - Returns: - Process's exit code if it exits normally, or -signal if the process is - killed by a signal. - """ - - return self._Run([test]) - - def _RunPythonTest(self, test, build_dir): - """Runs the Python test script with the specified build directory. - - Args: - test: Path to the test's Python script. - build_dir: Path to the directory where the test binary is to be found. - - Returns: - Process's exit code if it exits normally, or -signal if the process is - killed by a signal. - """ - - old_build_dir = self.os.environ.get(self.build_dir_var_name) - - try: - self.os.environ[self.build_dir_var_name] = build_dir - - # If this script is run on a Windows machine that has no association - # between the .py extension and a python interpreter, simply passing - # the script name into subprocess.Popen/os.spawn will not work. - print 'Running %s . . .' % (test,) - return self._Run([sys.executable, test]) - - finally: - if old_build_dir is None: - del self.os.environ[self.build_dir_var_name] - else: - self.os.environ[self.build_dir_var_name] = old_build_dir - - def _FindFilesByRegex(self, directory, regex): - """Returns files in a directory whose names match a regular expression. - - Args: - directory: Path to the directory to search for files. - regex: Regular expression to filter file names. - - Returns: - The list of the paths to the files in the directory. - """ - - return [self.os.path.join(directory, file_name) - for file_name in self.os.listdir(directory) - if re.search(regex, file_name)] - - # TODO(vladl@google.com): Implement parsing of scons/SConscript to run all - # tests defined there when no tests are specified. - # TODO(vladl@google.com): Update the docstring after the code is changed to - # try to test all builds defined in scons/SConscript. - def GetTestsToRun(self, - args, - named_configurations, - built_configurations, - available_configurations=CONFIGS, - python_tests_to_skip=None): - """Determines what tests should be run. - - Args: - args: The list of non-option arguments from the command line. - named_configurations: The list of configurations specified via -c or -a. - built_configurations: True if -b has been specified. - available_configurations: a list of configurations available on the - current platform, injectable for testing. - python_tests_to_skip: a collection of (configuration, python test name)s - that need to be skipped. - - Returns: - A tuple with 2 elements: the list of Python tests to run and the list of - binary tests to run. - """ - - if named_configurations == 'all': - named_configurations = ','.join(available_configurations) - - normalized_args = [self.os.path.normpath(arg) for arg in args] - - # A final list of build directories which will be searched for the test - # binaries. First, add directories specified directly on the command - # line. - build_dirs = filter(self.os.path.isdir, normalized_args) - - # Adds build directories specified via their build configurations using - # the -c or -a options. - if named_configurations: - build_dirs += [self._GetBuildDirForConfig(config) - for config in named_configurations.split(',')] - - # Adds KNOWN BUILD DIRECTORIES if -b is specified. - if built_configurations: - build_dirs += [self._GetBuildDirForConfig(config) - for config in available_configurations - if self.os.path.isdir(self._GetBuildDirForConfig(config))] - - # If no directories were specified either via -a, -b, -c, or directly, use - # the default configuration. - elif not build_dirs: - build_dirs = [self._GetBuildDirForConfig(available_configurations[0])] - - # Makes sure there are no duplications. - build_dirs = sets.Set(build_dirs) - - errors_found = False - listed_python_tests = [] # All Python tests listed on the command line. - listed_binary_tests = [] # All binary tests listed on the command line. - - test_dir = self.os.path.normpath(self.os.path.join(self.script_dir, 'test')) - - # Sifts through non-directory arguments fishing for any Python or binary - # tests and detecting errors. - for argument in sets.Set(normalized_args) - build_dirs: - if re.search(PYTHON_TEST_REGEX, argument): - python_path = self.os.path.join(test_dir, - self.os.path.basename(argument)) - if self.os.path.isfile(python_path): - listed_python_tests.append(python_path) - else: - sys.stderr.write('Unable to find Python test %s' % argument) - errors_found = True - elif re.search(BINARY_TEST_REGEX, argument): - # This script also accepts binary test names prefixed with test/ for - # the convenience of typing them (can use path completions in the - # shell). Strips test/ prefix from the binary test names. - listed_binary_tests.append(self.os.path.basename(argument)) - else: - sys.stderr.write('%s is neither test nor build directory' % argument) - errors_found = True - - if errors_found: - return None - - user_has_listed_tests = listed_python_tests or listed_binary_tests - - if user_has_listed_tests: - selected_python_tests = listed_python_tests - else: - selected_python_tests = self._FindFilesByRegex(test_dir, - PYTHON_TEST_REGEX) - - # TODO(vladl@google.com): skip unbuilt Python tests when -b is specified. - python_test_pairs = [] - for directory in build_dirs: - for test in selected_python_tests: - config = _GetConfigFromBuildDir(directory) - file_name = os.path.basename(test) - if python_tests_to_skip and (config, file_name) in python_tests_to_skip: - print ('NOTE: %s is skipped for configuration %s, as it does not ' - 'work there.' % (file_name, config)) - else: - python_test_pairs.append((directory, test)) - - binary_test_pairs = [] - for directory in build_dirs: - if user_has_listed_tests: - binary_test_pairs.extend( - [(directory, self.os.path.join(directory, test)) - for test in listed_binary_tests]) - else: - tests = self._FindFilesByRegex(directory, BINARY_TEST_SEARCH_REGEX) - binary_test_pairs.extend([(directory, test) for test in tests]) - - return (python_test_pairs, binary_test_pairs) - - def RunTests(self, python_tests, binary_tests): - """Runs Python and binary tests and reports results to the standard output. - - Args: - python_tests: List of Python tests to run in the form of tuples - (build directory, Python test script). - binary_tests: List of binary tests to run in the form of tuples - (build directory, binary file). - - Returns: - The exit code the program should pass into sys.exit(). - """ - - if python_tests or binary_tests: - results = [] - for directory, test in python_tests: - results.append((directory, - test, - self._RunPythonTest(test, directory) == 0)) - for directory, test in binary_tests: - results.append((directory, - self.os.path.basename(test), - self._RunBinaryTest(test) == 0)) - - failed = [(directory, test) - for (directory, test, success) in results - if not success] - print - print '%d tests run.' % len(results) - if failed: - print 'The following %d tests failed:' % len(failed) - for (directory, test) in failed: - print '%s in %s' % (test, directory) - return 1 - else: - print 'All tests passed!' - else: # No tests defined - print 'Nothing to test - no tests specified!' - - return 0 - - -def ParseArgs(project_name, argv=None, help_callback=None): - """Parses the options run_tests.py uses.""" - - # Suppresses lint warning on unused arguments. These arguments are - # required by optparse, even though they are unused. - # pylint: disable-msg=W0613 - def PrintHelp(option, opt, value, parser): - print HELP_MSG % {'proj': project_name} - sys.exit(1) - - parser = optparse.OptionParser() - parser.add_option('-c', - action='store', - dest='configurations', - default=None) - parser.add_option('-a', - action='store_const', - dest='configurations', - default=None, - const='all') - parser.add_option('-b', - action='store_const', - dest='built_configurations', - default=False, - const=True) - # Replaces the built-in help with ours. - parser.remove_option('-h') - parser.add_option('-h', '--help', - action='callback', - callback=help_callback or PrintHelp) - return parser.parse_args(argv) diff --git a/test/run_tests_util_test.py b/test/run_tests_util_test.py deleted file mode 100755 index 9c55726f..00000000 --- a/test/run_tests_util_test.py +++ /dev/null @@ -1,676 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2009 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. - -"""Tests for run_tests_util.py test runner script.""" - -__author__ = 'vladl@google.com (Vlad Losev)' - -import os -import re -import sets -import unittest - -import run_tests_util - - -GTEST_DBG_DIR = 'scons/build/dbg/gtest/scons' -GTEST_OPT_DIR = 'scons/build/opt/gtest/scons' -GTEST_OTHER_DIR = 'scons/build/other/gtest/scons' - - -def AddExeExtension(path): - """Appends .exe to the path on Windows or Cygwin.""" - - if run_tests_util.IS_WINDOWS or run_tests_util.IS_CYGWIN: - return path + '.exe' - else: - return path - - -class FakePath(object): - """A fake os.path module for testing.""" - - def __init__(self, current_dir=os.getcwd(), known_paths=None): - self.current_dir = current_dir - self.tree = {} - self.path_separator = os.sep - - # known_paths contains either absolute or relative paths. Relative paths - # are absolutized with self.current_dir. - if known_paths: - self._AddPaths(known_paths) - - def _AddPath(self, path): - ends_with_slash = path.endswith('/') - path = self.abspath(path) - if ends_with_slash: - path += self.path_separator - name_list = path.split(self.path_separator) - tree = self.tree - for name in name_list[:-1]: - if not name: - continue - if name in tree: - tree = tree[name] - else: - tree[name] = {} - tree = tree[name] - - name = name_list[-1] - if name: - if name in tree: - assert tree[name] == 1 - else: - tree[name] = 1 - - def _AddPaths(self, paths): - for path in paths: - self._AddPath(path) - - def PathElement(self, path): - """Returns an internal representation of directory tree entry for path.""" - tree = self.tree - name_list = self.abspath(path).split(self.path_separator) - for name in name_list: - if not name: - continue - tree = tree.get(name, None) - if tree is None: - break - - return tree - - # Silences pylint warning about using standard names. - # pylint: disable-msg=C6409 - def normpath(self, path): - return os.path.normpath(path) - - def abspath(self, path): - return self.normpath(os.path.join(self.current_dir, path)) - - def isfile(self, path): - return self.PathElement(self.abspath(path)) == 1 - - def isdir(self, path): - return type(self.PathElement(self.abspath(path))) == type(dict()) - - def basename(self, path): - return os.path.basename(path) - - def dirname(self, path): - return os.path.dirname(path) - - def join(self, *kargs): - return os.path.join(*kargs) - - -class FakeOs(object): - """A fake os module for testing.""" - P_WAIT = os.P_WAIT - - def __init__(self, fake_path_module): - self.path = fake_path_module - - # Some methods/attributes are delegated to the real os module. - self.environ = os.environ - - # pylint: disable-msg=C6409 - def listdir(self, path): - assert self.path.isdir(path) - return self.path.PathElement(path).iterkeys() - - def spawnv(self, wait, executable, *kargs): - assert wait == FakeOs.P_WAIT - return self.spawn_impl(executable, kargs) - - -class GetTestsToRunTest(unittest.TestCase): - """Exercises TestRunner.GetTestsToRun.""" - - def NormalizeGetTestsToRunResults(self, results): - """Normalizes path data returned from GetTestsToRun for comparison.""" - - def NormalizePythonTestPair(pair): - """Normalizes path data in the (directory, python_script) pair.""" - - return (os.path.normpath(pair[0]), os.path.normpath(pair[1])) - - def NormalizeBinaryTestPair(pair): - """Normalizes path data in the (directory, binary_executable) pair.""" - - directory, executable = map(os.path.normpath, pair) - - # On Windows and Cygwin, the test file names have the .exe extension, but - # they can be invoked either by name or by name+extension. Our test must - # accommodate both situations. - if run_tests_util.IS_WINDOWS or run_tests_util.IS_CYGWIN: - executable = re.sub(r'\.exe$', '', executable) - return (directory, executable) - - python_tests = sets.Set(map(NormalizePythonTestPair, results[0])) - binary_tests = sets.Set(map(NormalizeBinaryTestPair, results[1])) - return (python_tests, binary_tests) - - def AssertResultsEqual(self, results, expected): - """Asserts results returned by GetTestsToRun equal to expected results.""" - - self.assertEqual(self.NormalizeGetTestsToRunResults(results), - self.NormalizeGetTestsToRunResults(expected), - 'Incorrect set of tests returned:\n%s\nexpected:\n%s' % - (results, expected)) - - def setUp(self): - self.fake_os = FakeOs(FakePath( - current_dir=os.path.abspath(os.path.dirname(run_tests_util.__file__)), - known_paths=[AddExeExtension(GTEST_DBG_DIR + '/gtest_unittest'), - AddExeExtension(GTEST_OPT_DIR + '/gtest_unittest'), - 'test/gtest_color_test.py'])) - self.fake_configurations = ['dbg', 'opt'] - self.test_runner = run_tests_util.TestRunner(script_dir='.', - injected_os=self.fake_os, - injected_subprocess=None) - - def testBinaryTestsOnly(self): - """Exercises GetTestsToRun with parameters designating binary tests only.""" - - # A default build. - self.AssertResultsEqual( - self.test_runner.GetTestsToRun( - ['gtest_unittest'], - '', - False, - available_configurations=self.fake_configurations), - ([], - [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest')])) - - # An explicitly specified directory. - self.AssertResultsEqual( - self.test_runner.GetTestsToRun( - [GTEST_DBG_DIR, 'gtest_unittest'], - '', - False, - available_configurations=self.fake_configurations), - ([], - [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest')])) - - # A particular configuration. - self.AssertResultsEqual( - self.test_runner.GetTestsToRun( - ['gtest_unittest'], - 'other', - False, - available_configurations=self.fake_configurations), - ([], - [(GTEST_OTHER_DIR, GTEST_OTHER_DIR + '/gtest_unittest')])) - - # All available configurations - self.AssertResultsEqual( - self.test_runner.GetTestsToRun( - ['gtest_unittest'], - 'all', - False, - available_configurations=self.fake_configurations), - ([], - [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest'), - (GTEST_OPT_DIR, GTEST_OPT_DIR + '/gtest_unittest')])) - - # All built configurations (unbuilt don't cause failure). - self.AssertResultsEqual( - self.test_runner.GetTestsToRun( - ['gtest_unittest'], - '', - True, - available_configurations=self.fake_configurations + ['unbuilt']), - ([], - [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest'), - (GTEST_OPT_DIR, GTEST_OPT_DIR + '/gtest_unittest')])) - - # A combination of an explicit directory and a configuration. - self.AssertResultsEqual( - self.test_runner.GetTestsToRun( - [GTEST_DBG_DIR, 'gtest_unittest'], - 'opt', - False, - available_configurations=self.fake_configurations), - ([], - [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest'), - (GTEST_OPT_DIR, GTEST_OPT_DIR + '/gtest_unittest')])) - - # Same test specified in an explicit directory and via a configuration. - self.AssertResultsEqual( - self.test_runner.GetTestsToRun( - [GTEST_DBG_DIR, 'gtest_unittest'], - 'dbg', - False, - available_configurations=self.fake_configurations), - ([], - [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest')])) - - # All built configurations + explicit directory + explicit configuration. - self.AssertResultsEqual( - self.test_runner.GetTestsToRun( - [GTEST_DBG_DIR, 'gtest_unittest'], - 'opt', - True, - available_configurations=self.fake_configurations), - ([], - [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest'), - (GTEST_OPT_DIR, GTEST_OPT_DIR + '/gtest_unittest')])) - - def testPythonTestsOnly(self): - """Exercises GetTestsToRun with parameters designating Python tests only.""" - - # A default build. - self.AssertResultsEqual( - self.test_runner.GetTestsToRun( - ['gtest_color_test.py'], - '', - False, - available_configurations=self.fake_configurations), - ([(GTEST_DBG_DIR, 'test/gtest_color_test.py')], - [])) - - # An explicitly specified directory. - self.AssertResultsEqual( - self.test_runner.GetTestsToRun( - [GTEST_DBG_DIR, 'test/gtest_color_test.py'], - '', - False, - available_configurations=self.fake_configurations), - ([(GTEST_DBG_DIR, 'test/gtest_color_test.py')], - [])) - - # A particular configuration. - self.AssertResultsEqual( - self.test_runner.GetTestsToRun( - ['gtest_color_test.py'], - 'other', - False, - available_configurations=self.fake_configurations), - ([(GTEST_OTHER_DIR, 'test/gtest_color_test.py')], - [])) - - # All available configurations - self.AssertResultsEqual( - self.test_runner.GetTestsToRun( - ['test/gtest_color_test.py'], - 'all', - False, - available_configurations=self.fake_configurations), - ([(GTEST_DBG_DIR, 'test/gtest_color_test.py'), - (GTEST_OPT_DIR, 'test/gtest_color_test.py')], - [])) - - # All built configurations (unbuilt don't cause failure). - self.AssertResultsEqual( - self.test_runner.GetTestsToRun( - ['gtest_color_test.py'], - '', - True, - available_configurations=self.fake_configurations + ['unbuilt']), - ([(GTEST_DBG_DIR, 'test/gtest_color_test.py'), - (GTEST_OPT_DIR, 'test/gtest_color_test.py')], - [])) - - # A combination of an explicit directory and a configuration. - self.AssertResultsEqual( - self.test_runner.GetTestsToRun( - [GTEST_DBG_DIR, 'gtest_color_test.py'], - 'opt', - False, - available_configurations=self.fake_configurations), - ([(GTEST_DBG_DIR, 'test/gtest_color_test.py'), - (GTEST_OPT_DIR, 'test/gtest_color_test.py')], - [])) - - # Same test specified in an explicit directory and via a configuration. - self.AssertResultsEqual( - self.test_runner.GetTestsToRun( - [GTEST_DBG_DIR, 'gtest_color_test.py'], - 'dbg', - False, - available_configurations=self.fake_configurations), - ([(GTEST_DBG_DIR, 'test/gtest_color_test.py')], - [])) - - # All built configurations + explicit directory + explicit configuration. - self.AssertResultsEqual( - self.test_runner.GetTestsToRun( - [GTEST_DBG_DIR, 'gtest_color_test.py'], - 'opt', - True, - available_configurations=self.fake_configurations), - ([(GTEST_DBG_DIR, 'test/gtest_color_test.py'), - (GTEST_OPT_DIR, 'test/gtest_color_test.py')], - [])) - - def testCombinationOfBinaryAndPythonTests(self): - """Exercises GetTestsToRun with mixed binary/Python tests.""" - - # Use only default configuration for this test. - - # Neither binary nor Python tests are specified so find all. - self.AssertResultsEqual( - self.test_runner.GetTestsToRun( - [], - '', - False, - available_configurations=self.fake_configurations), - ([(GTEST_DBG_DIR, 'test/gtest_color_test.py')], - [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest')])) - - # Specifying both binary and Python tests. - self.AssertResultsEqual( - self.test_runner.GetTestsToRun( - ['gtest_unittest', 'gtest_color_test.py'], - '', - False, - available_configurations=self.fake_configurations), - ([(GTEST_DBG_DIR, 'test/gtest_color_test.py')], - [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest')])) - - # Specifying binary tests suppresses Python tests. - self.AssertResultsEqual( - self.test_runner.GetTestsToRun( - ['gtest_unittest'], - '', - False, - available_configurations=self.fake_configurations), - ([], - [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest')])) - - # Specifying Python tests suppresses binary tests. - self.AssertResultsEqual( - self.test_runner.GetTestsToRun( - ['gtest_color_test.py'], - '', - False, - available_configurations=self.fake_configurations), - ([(GTEST_DBG_DIR, 'test/gtest_color_test.py')], - [])) - - def testIgnoresNonTestFiles(self): - """Verifies that GetTestsToRun ignores non-test files in the filesystem.""" - - self.fake_os = FakeOs(FakePath( - current_dir=os.path.abspath(os.path.dirname(run_tests_util.__file__)), - known_paths=[AddExeExtension(GTEST_DBG_DIR + '/gtest_nontest'), - 'test/'])) - self.test_runner = run_tests_util.TestRunner(script_dir='.', - injected_os=self.fake_os, - injected_subprocess=None) - self.AssertResultsEqual( - self.test_runner.GetTestsToRun( - [], - '', - True, - available_configurations=self.fake_configurations), - ([], [])) - - def testWorksFromDifferentDir(self): - """Exercises GetTestsToRun from a directory different from run_test.py's.""" - - # Here we simulate an test script in directory /d/ called from the - # directory /a/b/c/. - self.fake_os = FakeOs(FakePath( - current_dir=os.path.abspath('/a/b/c'), - known_paths=[ - '/a/b/c/', - AddExeExtension('/d/' + GTEST_DBG_DIR + '/gtest_unittest'), - AddExeExtension('/d/' + GTEST_OPT_DIR + '/gtest_unittest'), - '/d/test/gtest_color_test.py'])) - self.fake_configurations = ['dbg', 'opt'] - self.test_runner = run_tests_util.TestRunner(script_dir='/d/', - injected_os=self.fake_os, - injected_subprocess=None) - # A binary test. - self.AssertResultsEqual( - self.test_runner.GetTestsToRun( - ['gtest_unittest'], - '', - False, - available_configurations=self.fake_configurations), - ([], - [('/d/' + GTEST_DBG_DIR, '/d/' + GTEST_DBG_DIR + '/gtest_unittest')])) - - # A Python test. - self.AssertResultsEqual( - self.test_runner.GetTestsToRun( - ['gtest_color_test.py'], - '', - False, - available_configurations=self.fake_configurations), - ([('/d/' + GTEST_DBG_DIR, '/d/test/gtest_color_test.py')], [])) - - def testNonTestBinary(self): - """Exercises GetTestsToRun with a non-test parameter.""" - - self.assert_( - not self.test_runner.GetTestsToRun( - ['gtest_unittest_not_really'], - '', - False, - available_configurations=self.fake_configurations)) - - def testNonExistingPythonTest(self): - """Exercises GetTestsToRun with a non-existent Python test parameter.""" - - self.assert_( - not self.test_runner.GetTestsToRun( - ['nonexistent_test.py'], - '', - False, - available_configurations=self.fake_configurations)) - - if run_tests_util.IS_WINDOWS or run_tests_util.IS_CYGWIN: - - def testDoesNotPickNonExeFilesOnWindows(self): - """Verifies that GetTestsToRun does not find _test files on Windows.""" - - self.fake_os = FakeOs(FakePath( - current_dir=os.path.abspath(os.path.dirname(run_tests_util.__file__)), - known_paths=['/d/' + GTEST_DBG_DIR + '/gtest_test', 'test/'])) - self.test_runner = run_tests_util.TestRunner(script_dir='.', - injected_os=self.fake_os, - injected_subprocess=None) - self.AssertResultsEqual( - self.test_runner.GetTestsToRun( - [], - '', - True, - available_configurations=self.fake_configurations), - ([], [])) - - -class RunTestsTest(unittest.TestCase): - """Exercises TestRunner.RunTests.""" - - def SpawnSuccess(self, unused_executable, unused_argv): - """Fakes test success by returning 0 as an exit code.""" - - self.num_spawn_calls += 1 - return 0 - - def SpawnFailure(self, unused_executable, unused_argv): - """Fakes test success by returning 1 as an exit code.""" - - self.num_spawn_calls += 1 - return 1 - - def setUp(self): - self.fake_os = FakeOs(FakePath( - current_dir=os.path.abspath(os.path.dirname(run_tests_util.__file__)), - known_paths=[ - AddExeExtension(GTEST_DBG_DIR + '/gtest_unittest'), - AddExeExtension(GTEST_OPT_DIR + '/gtest_unittest'), - 'test/gtest_color_test.py'])) - self.fake_configurations = ['dbg', 'opt'] - self.test_runner = run_tests_util.TestRunner( - script_dir=os.path.dirname(__file__) or '.', - injected_os=self.fake_os, - injected_subprocess=None) - self.num_spawn_calls = 0 # A number of calls to spawn. - - def testRunPythonTestSuccess(self): - """Exercises RunTests to handle a Python test success.""" - - self.fake_os.spawn_impl = self.SpawnSuccess - self.assertEqual( - self.test_runner.RunTests( - [(GTEST_DBG_DIR, 'test/gtest_color_test.py')], - []), - 0) - self.assertEqual(self.num_spawn_calls, 1) - - def testRunBinaryTestSuccess(self): - """Exercises RunTests to handle a binary test success.""" - - self.fake_os.spawn_impl = self.SpawnSuccess - self.assertEqual( - self.test_runner.RunTests( - [], - [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest')]), - 0) - self.assertEqual(self.num_spawn_calls, 1) - - def testRunPythonTestFauilure(self): - """Exercises RunTests to handle a Python test failure.""" - - self.fake_os.spawn_impl = self.SpawnFailure - self.assertEqual( - self.test_runner.RunTests( - [(GTEST_DBG_DIR, 'test/gtest_color_test.py')], - []), - 1) - self.assertEqual(self.num_spawn_calls, 1) - - def testRunBinaryTestFailure(self): - """Exercises RunTests to handle a binary test failure.""" - - self.fake_os.spawn_impl = self.SpawnFailure - self.assertEqual( - self.test_runner.RunTests( - [], - [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest')]), - 1) - self.assertEqual(self.num_spawn_calls, 1) - - def testCombinedTestSuccess(self): - """Exercises RunTests to handle a success of both Python and binary test.""" - - self.fake_os.spawn_impl = self.SpawnSuccess - self.assertEqual( - self.test_runner.RunTests( - [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest')], - [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest')]), - 0) - self.assertEqual(self.num_spawn_calls, 2) - - def testCombinedTestSuccessAndFailure(self): - """Exercises RunTests to handle a success of both Python and binary test.""" - - def SpawnImpl(executable, argv): - self.num_spawn_calls += 1 - # Simulates failure of a Python test and success of a binary test. - if '.py' in executable or '.py' in argv[0]: - return 1 - else: - return 0 - - self.fake_os.spawn_impl = SpawnImpl - self.assertEqual( - self.test_runner.RunTests( - [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest')], - [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest')]), - 0) - self.assertEqual(self.num_spawn_calls, 2) - - -class ParseArgsTest(unittest.TestCase): - """Exercises ParseArgs.""" - - def testNoOptions(self): - options, args = run_tests_util.ParseArgs('gtest', argv=['script.py']) - self.assertEqual(args, ['script.py']) - self.assert_(options.configurations is None) - self.assertFalse(options.built_configurations) - - def testOptionC(self): - options, args = run_tests_util.ParseArgs( - 'gtest', argv=['script.py', '-c', 'dbg']) - self.assertEqual(args, ['script.py']) - self.assertEqual(options.configurations, 'dbg') - self.assertFalse(options.built_configurations) - - def testOptionA(self): - options, args = run_tests_util.ParseArgs('gtest', argv=['script.py', '-a']) - self.assertEqual(args, ['script.py']) - self.assertEqual(options.configurations, 'all') - self.assertFalse(options.built_configurations) - - def testOptionB(self): - options, args = run_tests_util.ParseArgs('gtest', argv=['script.py', '-b']) - self.assertEqual(args, ['script.py']) - self.assert_(options.configurations is None) - self.assertTrue(options.built_configurations) - - def testOptionCAndOptionB(self): - options, args = run_tests_util.ParseArgs( - 'gtest', argv=['script.py', '-c', 'dbg', '-b']) - self.assertEqual(args, ['script.py']) - self.assertEqual(options.configurations, 'dbg') - self.assertTrue(options.built_configurations) - - def testOptionH(self): - help_called = [False] - - # Suppresses lint warning on unused arguments. These arguments are - # required by optparse, even though they are unused. - # pylint: disable-msg=W0613 - def VerifyHelp(option, opt, value, parser): - help_called[0] = True - - # Verifies that -h causes the help callback to be called. - help_called[0] = False - _, args = run_tests_util.ParseArgs( - 'gtest', argv=['script.py', '-h'], help_callback=VerifyHelp) - self.assertEqual(args, ['script.py']) - self.assertTrue(help_called[0]) - - # Verifies that --help causes the help callback to be called. - help_called[0] = False - _, args = run_tests_util.ParseArgs( - 'gtest', argv=['script.py', '--help'], help_callback=VerifyHelp) - self.assertEqual(args, ['script.py']) - self.assertTrue(help_called[0]) - - -if __name__ == '__main__': - unittest.main() -- cgit v1.2.3 From 7c598c4f1a44fdda5f97587484c85bef9e93fa98 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Mon, 26 Jul 2010 21:59:50 +0000 Subject: Adds ADD_FAILURE_AT (by Zhanyong Wan); disables -Wswitch-default (by Vlad Losev). --- test/gtest_output_test_.cc | 4 ++++ test/gtest_output_test_golden_lin.txt | 15 +++++++++++---- test/gtest_output_test_golden_win.txt | 14 ++++++++++---- test/gtest_unittest.cc | 15 +++++++++++++++ 4 files changed, 40 insertions(+), 8 deletions(-) (limited to 'test') diff --git a/test/gtest_output_test_.cc b/test/gtest_output_test_.cc index 1ac439c6..454e1bad 100644 --- a/test/gtest_output_test_.cc +++ b/test/gtest_output_test_.cc @@ -441,6 +441,10 @@ TEST_F(FatalFailureInSetUpTest, FailureInSetUp) { << "We should never get here, as SetUp() failed."; } +TEST(AddFailureAtTest, MessageContainsSpecifiedFileAndLineNumber) { + ADD_FAILURE_AT("foo.cc", 42) << "Expected failure in foo.cc"; +} + #if GTEST_OS_WINDOWS // This group of tests verifies that Google Test handles SEH and C++ diff --git a/test/gtest_output_test_golden_lin.txt b/test/gtest_output_test_golden_lin.txt index 9b30445e..0ba9968c 100644 --- a/test/gtest_output_test_golden_lin.txt +++ b/test/gtest_output_test_golden_lin.txt @@ -7,7 +7,7 @@ Expected: true gtest_output_test_.cc:#: Failure Value of: 3 Expected: 2 -[==========] Running 61 tests from 26 test cases. +[==========] Running 62 tests from 27 test cases. [----------] Global test environment set-up. FooEnvironment::SetUp() called. BarEnvironment::SetUp() called. @@ -235,6 +235,12 @@ gtest_output_test_.cc:#: Failure Failed Expected failure #3, in the test fixture d'tor. [ FAILED ] FatalFailureInSetUpTest.FailureInSetUp +[----------] 1 test from AddFailureAtTest +[ RUN ] AddFailureAtTest.MessageContainsSpecifiedFileAndLineNumber +foo.cc:42: Failure +Failed +Expected failure in foo.cc +[ FAILED ] AddFailureAtTest.MessageContainsSpecifiedFileAndLineNumber [----------] 4 tests from MixedUpTestCaseTest [ RUN ] MixedUpTestCaseTest.FirstTestFromNamespaceFoo [ OK ] MixedUpTestCaseTest.FirstTestFromNamespaceFoo @@ -580,9 +586,9 @@ FooEnvironment::TearDown() called. gtest_output_test_.cc:#: Failure Failed Expected fatal failure. -[==========] 61 tests from 26 test cases ran. +[==========] 62 tests from 27 test cases ran. [ PASSED ] 21 tests. -[ FAILED ] 40 tests, listed below: +[ FAILED ] 41 tests, listed below: [ FAILED ] FatalFailureTest.FatalFailureInSubroutine [ FAILED ] FatalFailureTest.FatalFailureInNestedSubroutine [ FAILED ] FatalFailureTest.NonfatalFailureInSubroutine @@ -597,6 +603,7 @@ Expected fatal failure. [ FAILED ] FatalFailureInFixtureConstructorTest.FailureInConstructor [ FAILED ] NonFatalFailureInSetUpTest.FailureInSetUp [ FAILED ] FatalFailureInSetUpTest.FailureInSetUp +[ FAILED ] AddFailureAtTest.MessageContainsSpecifiedFileAndLineNumber [ FAILED ] MixedUpTestCaseTest.ThisShouldFail [ FAILED ] MixedUpTestCaseTest.ThisShouldFailToo [ FAILED ] MixedUpTestCaseWithSameTestNameTest.TheSecondTestWithThisNameShouldFail @@ -624,7 +631,7 @@ Expected fatal failure. [ FAILED ] ScopedFakeTestPartResultReporterTest.InterceptOnlyCurrentThread [ FAILED ] PrintingFailingParams/FailingParamTest.Fails/0, where GetParam() = 2 -40 FAILED TESTS +41 FAILED TESTS  YOU HAVE 1 DISABLED TEST Note: Google Test filter = FatalFailureTest.*:LoggingTest.* diff --git a/test/gtest_output_test_golden_win.txt b/test/gtest_output_test_golden_win.txt index bf76b8cc..135f39e3 100644 --- a/test/gtest_output_test_golden_win.txt +++ b/test/gtest_output_test_golden_win.txt @@ -5,7 +5,7 @@ gtest_output_test_.cc:#: error: Value of: false Expected: true gtest_output_test_.cc:#: error: Value of: 3 Expected: 2 -[==========] Running 62 tests from 28 test cases. +[==========] Running 63 tests from 29 test cases. [----------] Global test environment set-up. FooEnvironment::SetUp() called. BarEnvironment::SetUp() called. @@ -173,6 +173,11 @@ Expected failure #2, in TearDown(). gtest_output_test_.cc:#: error: Failed Expected failure #3, in the test fixture d'tor. [ FAILED ] FatalFailureInSetUpTest.FailureInSetUp +[----------] 1 test from AddFailureAtTest +[ RUN ] AddFailureAtTest.MessageContainsSpecifiedFileAndLineNumber +foo.cc(42): error: Failed +Expected failure in foo.cc +[ FAILED ] AddFailureAtTest.MessageContainsSpecifiedFileAndLineNumber [----------] 1 test from ExceptionInFixtureCtorTest [ RUN ] ExceptionInFixtureCtorTest.ExceptionInFixtureCtor (expecting a failure on thrown exception in the test fixture's constructor) @@ -492,9 +497,9 @@ Expected non-fatal failure. FooEnvironment::TearDown() called. gtest_output_test_.cc:#: error: Failed Expected fatal failure. -[==========] 62 tests from 28 test cases ran. +[==========] 63 tests from 29 test cases ran. [ PASSED ] 21 tests. -[ FAILED ] 41 tests, listed below: +[ FAILED ] 42 tests, listed below: [ FAILED ] FatalFailureTest.FatalFailureInSubroutine [ FAILED ] FatalFailureTest.FatalFailureInNestedSubroutine [ FAILED ] FatalFailureTest.NonfatalFailureInSubroutine @@ -508,6 +513,7 @@ Expected fatal failure. [ FAILED ] FatalFailureInFixtureConstructorTest.FailureInConstructor [ FAILED ] NonFatalFailureInSetUpTest.FailureInSetUp [ FAILED ] FatalFailureInSetUpTest.FailureInSetUp +[ FAILED ] AddFailureAtTest.MessageContainsSpecifiedFileAndLineNumber [ FAILED ] ExceptionInFixtureCtorTest.ExceptionInFixtureCtor [ FAILED ] ExceptionInSetUpTest.ExceptionInSetUp [ FAILED ] ExceptionInTestFunctionTest.SEH @@ -537,7 +543,7 @@ Expected fatal failure. [ FAILED ] ExpectFailureTest.ExpectNonFatalFailureOnAllThreads [ FAILED ] PrintingFailingParams/FailingParamTest.Fails/0, where GetParam() = 2 -41 FAILED TESTS +42 FAILED TESTS YOU HAVE 1 DISABLED TEST Note: Google Test filter = FatalFailureTest.*:LoggingTest.* diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index e11b6a66..910d4e20 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -4393,6 +4393,21 @@ TEST(MacroTest, ADD_FAILURE) { EXPECT_FALSE(aborted); } +// Tests ADD_FAILURE_AT. +TEST(MacroTest, ADD_FAILURE_AT) { + // Verifies that ADD_FAILURE_AT does generate a nonfatal failure and + // the failure message contains the user-streamed part. + EXPECT_NONFATAL_FAILURE(ADD_FAILURE_AT("foo.cc", 42) << "Wrong!", "Wrong!"); + + // Verifies that the user-streamed part is optional. + EXPECT_NONFATAL_FAILURE(ADD_FAILURE_AT("foo.cc", 42), "Failed"); + + // Unfortunately, we cannot verify that the failure message contains + // the right file path and line number the same way, as + // EXPECT_NONFATAL_FAILURE() doesn't get to see the file path and + // line number. Instead, we do that in gtest_output_test_.cc. +} + // Tests FAIL. TEST(MacroTest, FAIL) { EXPECT_FATAL_FAILURE(FAIL(), -- cgit v1.2.3 From 5c4b472bbf8c81fc3d52fc69a92f174821a96280 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Mon, 9 Aug 2010 18:19:15 +0000 Subject: Makes gtest print enums as integers instead of hex dumps (by Zhanyong Wan); improves the hex dump format (by Zhanyong Wan); gets rid of class TestInfoImpl (by Zhanyong Wan); adds exception handling (by Vlad Losev). --- test/gtest-death-test_test.cc | 11 -- test/gtest-printers_test.cc | 82 +++++++++- test/gtest_catch_exceptions_test.py | 203 +++++++++++++++++++++++ test/gtest_catch_exceptions_test_.cc | 299 ++++++++++++++++++++++++++++++++++ test/gtest_output_test_.cc | 131 --------------- test/gtest_output_test_golden_win.txt | 49 +----- test/gtest_unittest.cc | 62 ++++--- 7 files changed, 619 insertions(+), 218 deletions(-) create mode 100755 test/gtest_catch_exceptions_test.py create mode 100644 test/gtest_catch_exceptions_test_.cc (limited to 'test') diff --git a/test/gtest-death-test_test.cc b/test/gtest-death-test_test.cc index ed5b53b7..d33cfeb7 100644 --- a/test/gtest-death-test_test.cc +++ b/test/gtest-death-test_test.cc @@ -614,17 +614,6 @@ TEST(PopUpDeathTest, DoesNotShowPopUpOnAbort) { abort(); }, ""); } - -TEST(PopUpDeathTest, DoesNotShowPopUpOnThrow) { - printf("This test should be considered failing if it shows " - "any pop-up dialogs.\n"); - fflush(stdout); - - EXPECT_DEATH({ - testing::GTEST_FLAG(catch_exceptions) = false; - throw 1; - }, ""); -} #endif // GTEST_OS_WINDOWS // Tests that EXPECT_DEBUG_DEATH in debug mode does not abort diff --git a/test/gtest-printers_test.cc b/test/gtest-printers_test.cc index 11f6625b..5dec871c 100644 --- a/test/gtest-printers_test.cc +++ b/test/gtest-printers_test.cc @@ -60,6 +60,42 @@ // Some user-defined types for testing the universal value printer. +// An anonymous enum type. +enum AnonymousEnum { + kAE1 = -1, + kAE2 = 1 +}; + +// An enum without a user-defined printer. +enum EnumWithoutPrinter { + kEWP1 = -2, + kEWP2 = 42 +}; + +// An enum with a << operator. +enum EnumWithStreaming { + kEWS1 = 10, +}; + +std::ostream& operator<<(std::ostream& os, EnumWithStreaming e) { + return os << (e == kEWS1 ? "kEWS1" : "invalid"); +} + +// An enum with a PrintTo() function. +enum EnumWithPrintTo { + kEWPT1 = 1, +}; + +void PrintTo(EnumWithPrintTo e, std::ostream* os) { + *os << (e == kEWPT1 ? "kEWPT1" : "invalid"); +} + +// A class implicitly convertible to BiggestInt. +class BiggestIntConvertible { + public: + operator ::testing::internal::BiggestInt() const { return 42; } +}; + // A user-defined unprintable class template in the global namespace. template class UnprintableTemplateInGlobal { @@ -207,6 +243,34 @@ string PrintByRef(const T& value) { return ss.str(); } +// Tests printing various enum types. + +TEST(PrintEnumTest, AnonymousEnum) { + EXPECT_EQ("-1", Print(kAE1)); + EXPECT_EQ("1", Print(kAE2)); +} + +TEST(PrintEnumTest, EnumWithoutPrinter) { + EXPECT_EQ("-2", Print(kEWP1)); + EXPECT_EQ("42", Print(kEWP2)); +} + +TEST(PrintEnumTest, EnumWithStreaming) { + EXPECT_EQ("kEWS1", Print(kEWS1)); + EXPECT_EQ("invalid", Print(static_cast(0))); +} + +TEST(PrintEnumTest, EnumWithPrintTo) { + EXPECT_EQ("kEWPT1", Print(kEWPT1)); + EXPECT_EQ("invalid", Print(static_cast(0))); +} + +// Tests printing a class implicitly convertible to BiggestInt. + +TEST(PrintClassTest, BiggestIntConvertible) { + EXPECT_EQ("42", Print(BiggestIntConvertible())); +} + // Tests printing various char types. // char. @@ -913,7 +977,7 @@ TEST(PrintUnprintableTypeTest, InGlobalNamespace) { // Unprintable types in a user namespace. TEST(PrintUnprintableTypeTest, InUserNamespace) { - EXPECT_EQ("16-byte object ", + EXPECT_EQ("16-byte object ", Print(::foo::UnprintableInFoo())); } @@ -925,13 +989,13 @@ struct Big { }; TEST(PrintUnpritableTypeTest, BigObject) { - EXPECT_EQ("257-byte object <0000 0000 0000 0000 0000 0000 " - "0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 " - "0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 " - "0000 0000 0000 0000 0000 0000 ... 0000 0000 0000 " - "0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 " - "0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 " - "0000 0000 0000 0000 0000 0000 0000 0000 00>", + EXPECT_EQ("257-byte object <00-00 00-00 00-00 00-00 00-00 00-00 " + "00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 " + "00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 " + "00-00 00-00 00-00 00-00 00-00 00-00 ... 00-00 00-00 00-00 " + "00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 " + "00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 " + "00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00>", Print(Big())); } @@ -1022,7 +1086,7 @@ TEST(PrintReferenceTest, PrintsAddressAndValue) { const ::foo::UnprintableInFoo x; EXPECT_EQ("@" + PrintPointer(&x) + " 16-byte object " - "", + "", PrintByRef(x)); } diff --git a/test/gtest_catch_exceptions_test.py b/test/gtest_catch_exceptions_test.py new file mode 100755 index 00000000..c4d1756d --- /dev/null +++ b/test/gtest_catch_exceptions_test.py @@ -0,0 +1,203 @@ +#!/usr/bin/env python +# +# Copyright 2010 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. + +"""Tests Google Test's exception catching behavior. + +This script invokes gtest_catch_exceptions_test_ and +gtest_catch_exceptions_ex_test_ (programs written with +Google Test) and verifies their output. +""" + +__author__ = 'vladl@google.com (Vlad Losev)' + +import os + +import gtest_test_utils + +# Constants. +LIST_TESTS_FLAG = '--gtest_list_tests' + +# Path to the gtest_catch_exceptions_ex_test_ binary, compiled with +# exceptions enabled. +EX_EXE_PATH = gtest_test_utils.GetTestExecutablePath( + 'gtest_catch_exceptions_ex_test_') + +# Path to the gtest_catch_exceptions_test_ binary, compiled with +# exceptions disabled. +EXE_PATH = gtest_test_utils.GetTestExecutablePath( + 'gtest_catch_exceptions_no_ex_test_') + +TEST_LIST = gtest_test_utils.Subprocess([EXE_PATH, LIST_TESTS_FLAG]).output + +SUPPORTS_SEH_EXCEPTIONS = 'ThrowsSehException' in TEST_LIST + +if SUPPORTS_SEH_EXCEPTIONS: + BINARY_OUTPUT = gtest_test_utils.Subprocess([EXE_PATH]).output + +EX_BINARY_OUTPUT = gtest_test_utils.Subprocess([EX_EXE_PATH]).output + + +# The tests. +if SUPPORTS_SEH_EXCEPTIONS: + # pylint:disable-msg=C6302 + class CatchSehExceptionsTest(gtest_test_utils.TestCase): + """Tests exception-catching behavior.""" + + + def TestSehExceptions(self, test_output): + self.assert_('SEH exception with code 0x2a thrown ' + 'in the test fixture\'s constructor' + in test_output) + self.assert_('SEH exception with code 0x2a thrown ' + 'in the test fixture\'s destructor' + in test_output) + self.assert_('SEH exception with code 0x2a thrown in SetUpTestCase()' + in test_output) + self.assert_('SEH exception with code 0x2a thrown in TearDownTestCase()' + in test_output) + self.assert_('SEH exception with code 0x2a thrown in SetUp()' + in test_output) + self.assert_('SEH exception with code 0x2a thrown in TearDown()' + in test_output) + self.assert_('SEH exception with code 0x2a thrown in the test body' + in test_output) + + def testCatchesSehExceptionsWithCxxExceptionsEnabled(self): + self.TestSehExceptions(EX_BINARY_OUTPUT) + + def testCatchesSehExceptionsWithCxxExceptionsDisabled(self): + self.TestSehExceptions(BINARY_OUTPUT) + + +class CatchCxxExceptionsTest(gtest_test_utils.TestCase): + """Tests C++ exception-catching behavior. + + Tests in this test case verify that: + * C++ exceptions are caught and logged as C++ (not SEH) exceptions + * Exception thrown affect the remainder of the test work flow in the + expected manner. + """ + + def testCatchesCxxExceptionsInFixtureConstructor(self): + self.assert_('C++ exception with description ' + '"Standard C++ exception" thrown ' + 'in the test fixture\'s constructor' + in EX_BINARY_OUTPUT) + self.assert_('unexpected' not in EX_BINARY_OUTPUT, + 'This failure belongs in this test only if ' + '"CxxExceptionInConstructorTest" (no quotes) ' + 'appears on the same line as words "called unexpectedly"') + + def testCatchesCxxExceptionsInFixtureDestructor(self): + self.assert_('C++ exception with description ' + '"Standard C++ exception" thrown ' + 'in the test fixture\'s destructor' + in EX_BINARY_OUTPUT) + self.assert_('CxxExceptionInDestructorTest::TearDownTestCase() ' + 'called as expected.' + in EX_BINARY_OUTPUT) + + def testCatchesCxxExceptionsInSetUpTestCase(self): + self.assert_('C++ exception with description "Standard C++ exception"' + ' thrown in SetUpTestCase()' + in EX_BINARY_OUTPUT) + self.assert_('CxxExceptionInConstructorTest::TearDownTestCase() ' + 'called as expected.' + in EX_BINARY_OUTPUT) + self.assert_('CxxExceptionInSetUpTestCaseTest constructor ' + 'called as expected.' + in EX_BINARY_OUTPUT) + self.assert_('CxxExceptionInSetUpTestCaseTest destructor ' + 'called as expected.' + in EX_BINARY_OUTPUT) + self.assert_('CxxExceptionInSetUpTestCaseTest::SetUp() ' + 'called as expected.' + in EX_BINARY_OUTPUT) + self.assert_('CxxExceptionInSetUpTestCaseTest::TearDown() ' + 'called as expected.' + in EX_BINARY_OUTPUT) + self.assert_('CxxExceptionInSetUpTestCaseTest test body ' + 'called as expected.' + in EX_BINARY_OUTPUT) + + def testCatchesCxxExceptionsInTearDownTestCase(self): + self.assert_('C++ exception with description "Standard C++ exception"' + ' thrown in TearDownTestCase()' + in EX_BINARY_OUTPUT) + + def testCatchesCxxExceptionsInSetUp(self): + self.assert_('C++ exception with description "Standard C++ exception"' + ' thrown in SetUp()' + in EX_BINARY_OUTPUT) + self.assert_('CxxExceptionInSetUpTest::TearDownTestCase() ' + 'called as expected.' + in EX_BINARY_OUTPUT) + self.assert_('CxxExceptionInSetUpTest destructor ' + 'called as expected.' + in EX_BINARY_OUTPUT) + self.assert_('CxxExceptionInSetUpTest::TearDown() ' + 'called as expected.' + in EX_BINARY_OUTPUT) + self.assert_('unexpected' not in EX_BINARY_OUTPUT, + 'This failure belongs in this test only if ' + '"CxxExceptionInSetUpTest" (no quotes) ' + 'appears on the same line as words "called unexpectedly"') + + def testCatchesCxxExceptionsInTearDown(self): + self.assert_('C++ exception with description "Standard C++ exception"' + ' thrown in TearDown()' + in EX_BINARY_OUTPUT) + self.assert_('CxxExceptionInTearDownTest::TearDownTestCase() ' + 'called as expected.' + in EX_BINARY_OUTPUT) + self.assert_('CxxExceptionInTearDownTest destructor ' + 'called as expected.' + in EX_BINARY_OUTPUT) + + def testCatchesCxxExceptionsInTestBody(self): + self.assert_('C++ exception with description "Standard C++ exception"' + ' thrown in the test body' + in EX_BINARY_OUTPUT) + self.assert_('CxxExceptionInTestBodyTest::TearDownTestCase() ' + 'called as expected.' + in EX_BINARY_OUTPUT) + self.assert_('CxxExceptionInTestBodyTest destructor ' + 'called as expected.' + in EX_BINARY_OUTPUT) + self.assert_('CxxExceptionInTestBodyTest::TearDown() ' + 'called as expected.' + in EX_BINARY_OUTPUT) + + def testCatchesNonStdCxxExceptions(self): + self.assert_('Unknown C++ exception thrown in the test body' + in EX_BINARY_OUTPUT) + +if __name__ == '__main__': + gtest_test_utils.Main() diff --git a/test/gtest_catch_exceptions_test_.cc b/test/gtest_catch_exceptions_test_.cc new file mode 100644 index 00000000..86736811 --- /dev/null +++ b/test/gtest_catch_exceptions_test_.cc @@ -0,0 +1,299 @@ +// Copyright 2010, 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: vladl@google.com (Vlad Losev) +// +// Tests for Google Test itself. Tests in this file throw C++ or SEH +// exceptions, and the output is verified by gtest_catch_exceptions_test.py. + +#include + +#include // NOLINT + +#if GTEST_HAS_SEH +#include +#endif + +#if GTEST_HAS_EXCEPTIONS +#include +#endif + +using testing::Test; +using testing::GTEST_FLAG(catch_exceptions); + +#if GTEST_HAS_SEH + +class SehExceptionInConstructorTest : public Test { + public: + SehExceptionInConstructorTest() { RaiseException(42, 0, 0, NULL); } +}; + +TEST_F(SehExceptionInConstructorTest, ThrowsExceptionInConstructor) {} + +class SehExceptionInDestructorTest : public Test { + public: + ~SehExceptionInDestructorTest() { RaiseException(42, 0, 0, NULL); } +}; + +TEST_F(SehExceptionInDestructorTest, ThrowsExceptionInDestructor) {} + +class SehExceptionInSetUpTestCaseTest : public Test { + public: + static void SetUpTestCase() { RaiseException(42, 0, 0, NULL); } +}; + +TEST_F(SehExceptionInSetUpTestCaseTest, ThrowsExceptionInSetUpTestCase) {} + +class SehExceptionInTearDownTestCaseTest : public Test { + public: + static void TearDownTestCase() { RaiseException(42, 0, 0, NULL); } +}; + +TEST_F(SehExceptionInTearDownTestCaseTest, ThrowsExceptionInTearDownTestCase) {} + +class SehExceptionInSetUpTest : public Test { + protected: + virtual void SetUp() { RaiseException(42, 0, 0, NULL); } +}; + +TEST_F(SehExceptionInSetUpTest, ThrowsExceptionInSetUp) {} + +class SehExceptionInTearDownTest : public Test { + protected: + virtual void TearDown() { RaiseException(42, 0, 0, NULL); } +}; + +TEST_F(SehExceptionInTearDownTest, ThrowsExceptionInTearDown) {} + +TEST(SehExceptionTest, ThrowsSehException) { + RaiseException(42, 0, 0, NULL); +} + +#endif // GTEST_HAS_SEH + +#if GTEST_HAS_EXCEPTIONS + +class CxxExceptionInConstructorTest : public Test { + public: + CxxExceptionInConstructorTest() { + // Without this macro VC++ complains about unreachable code at the end of + // the constructor. + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_( + throw std::runtime_error("Standard C++ exception")); + } + + static void TearDownTestCase() { + printf("%s", + "CxxExceptionInConstructorTest::TearDownTestCase() " + "called as expected.\n"); + } + + protected: + ~CxxExceptionInConstructorTest() { + ADD_FAILURE() << "CxxExceptionInConstructorTest destructor " + << "called unexpectedly."; + } + + virtual void SetUp() { + ADD_FAILURE() << "CxxExceptionInConstructorTest::SetUp() " + << "called unexpectedly."; + } + + virtual void TearDown() { + ADD_FAILURE() << "CxxExceptionInConstructorTest::TearDown() " + << "called unexpectedly."; + } +}; + +TEST_F(CxxExceptionInConstructorTest, ThrowsExceptionInConstructor) { + ADD_FAILURE() << "CxxExceptionInConstructorTest test body " + << "called unexpectedly."; +} + +class CxxExceptionInDestructorTest : public Test { + public: + static void TearDownTestCase() { + printf("%s", + "CxxExceptionInDestructorTest::TearDownTestCase() " + "called as expected.\n"); + } + + protected: + ~CxxExceptionInDestructorTest() { + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_( + throw std::runtime_error("Standard C++ exception")); + } +}; + +TEST_F(CxxExceptionInDestructorTest, ThrowsExceptionInDestructor) {} + +class CxxExceptionInSetUpTestCaseTest : public Test { + public: + CxxExceptionInSetUpTestCaseTest() { + printf("%s", + "CxxExceptionInSetUpTestCaseTest constructor " + "called as expected.\n"); + } + + static void SetUpTestCase() { + throw std::runtime_error("Standard C++ exception"); + } + + static void TearDownTestCase() { + printf("%s", + "CxxExceptionInSetUpTestCaseTest::TearDownTestCase() " + "called as expected.\n"); + } + + protected: + ~CxxExceptionInSetUpTestCaseTest() { + printf("%s", + "CxxExceptionInSetUpTestCaseTest destructor " + "called as expected.\n"); + } + + virtual void SetUp() { + printf("%s", + "CxxExceptionInSetUpTestCaseTest::SetUp() " + "called as expected.\n"); + } + + virtual void TearDown() { + printf("%s", + "CxxExceptionInSetUpTestCaseTest::TearDown() " + "called as expected.\n"); + } +}; + +TEST_F(CxxExceptionInSetUpTestCaseTest, ThrowsExceptionInSetUpTestCase) { + printf("%s", + "CxxExceptionInSetUpTestCaseTest test body " + "called as expected.\n"); +} + +class CxxExceptionInTearDownTestCaseTest : public Test { + public: + static void TearDownTestCase() { + throw std::runtime_error("Standard C++ exception"); + } +}; + +TEST_F(CxxExceptionInTearDownTestCaseTest, ThrowsExceptionInTearDownTestCase) {} + +class CxxExceptionInSetUpTest : public Test { + public: + static void TearDownTestCase() { + printf("%s", + "CxxExceptionInSetUpTest::TearDownTestCase() " + "called as expected.\n"); + } + + protected: + ~CxxExceptionInSetUpTest() { + printf("%s", + "CxxExceptionInSetUpTest destructor " + "called as expected.\n"); + } + + virtual void SetUp() { throw std::runtime_error("Standard C++ exception"); } + + virtual void TearDown() { + printf("%s", + "CxxExceptionInSetUpTest::TearDown() " + "called as expected.\n"); + } +}; + +TEST_F(CxxExceptionInSetUpTest, ThrowsExceptionInSetUp) { + ADD_FAILURE() << "CxxExceptionInSetUpTest test body " + << "called unexpectedly."; +} + +class CxxExceptionInTearDownTest : public Test { + public: + static void TearDownTestCase() { + printf("%s", + "CxxExceptionInTearDownTest::TearDownTestCase() " + "called as expected.\n"); + } + + protected: + ~CxxExceptionInTearDownTest() { + printf("%s", + "CxxExceptionInTearDownTest destructor " + "called as expected.\n"); + } + + virtual void TearDown() { + throw std::runtime_error("Standard C++ exception"); + } +}; + +TEST_F(CxxExceptionInTearDownTest, ThrowsExceptionInTearDown) {} + +class CxxExceptionInTestBodyTest : public Test { + public: + static void TearDownTestCase() { + printf("%s", + "CxxExceptionInTestBodyTest::TearDownTestCase() " + "called as expected.\n"); + } + + protected: + ~CxxExceptionInTestBodyTest() { + printf("%s", + "CxxExceptionInTestBodyTest destructor " + "called as expected.\n"); + } + + virtual void TearDown() { + printf("%s", + "CxxExceptionInTestBodyTest::TearDown() " + "called as expected.\n"); + } +}; + +TEST_F(CxxExceptionInTestBodyTest, ThrowsStdCxxException) { + throw std::runtime_error("Standard C++ exception"); +} + +TEST(CxxExceptionTest, ThrowsNonStdCxxException) { + throw "C-string"; +} + +#endif // GTEST_HAS_EXCEPTIONS + +int main(int argc, char** argv) { +#if GTEST_HAS_SEH + // Tells Google Test to catch SEH-style exceptions on Windows. + GTEST_FLAG(catch_exceptions) = true; +#endif + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/test/gtest_output_test_.cc b/test/gtest_output_test_.cc index 454e1bad..fc80fac3 100644 --- a/test/gtest_output_test_.cc +++ b/test/gtest_output_test_.cc @@ -445,137 +445,6 @@ TEST(AddFailureAtTest, MessageContainsSpecifiedFileAndLineNumber) { ADD_FAILURE_AT("foo.cc", 42) << "Expected failure in foo.cc"; } -#if GTEST_OS_WINDOWS - -// This group of tests verifies that Google Test handles SEH and C++ -// exceptions correctly. - -// A function that throws an SEH exception. -static void ThrowSEH() { - int* p = NULL; - *p = 0; // Raises an access violation. -} - -// Tests exceptions thrown in the test fixture constructor. -class ExceptionInFixtureCtorTest : public testing::Test { - protected: - ExceptionInFixtureCtorTest() { - printf("(expecting a failure on thrown exception " - "in the test fixture's constructor)\n"); - - ThrowSEH(); - } - - virtual ~ExceptionInFixtureCtorTest() { - Deinit(); - } - - virtual void SetUp() { - FAIL() << "UNEXPECTED failure in SetUp(). " - << "We should never get here, as the test fixture c'tor threw."; - } - - virtual void TearDown() { - FAIL() << "UNEXPECTED failure in TearDown(). " - << "We should never get here, as the test fixture c'tor threw."; - } - private: - void Deinit() { - FAIL() << "UNEXPECTED failure in the d'tor. " - << "We should never get here, as the test fixture c'tor threw."; - } -}; - -TEST_F(ExceptionInFixtureCtorTest, ExceptionInFixtureCtor) { - FAIL() << "UNEXPECTED failure in the test function. " - << "We should never get here, as the test fixture c'tor threw."; -} - -// Tests exceptions thrown in SetUp(). -class ExceptionInSetUpTest : public testing::Test { - protected: - virtual ~ExceptionInSetUpTest() { - Deinit(); - } - - virtual void SetUp() { - printf("(expecting 3 failures)\n"); - - ThrowSEH(); - } - - virtual void TearDown() { - FAIL() << "Expected failure #2, in TearDown()."; - } - private: - void Deinit() { - FAIL() << "Expected failure #3, in the test fixture d'tor."; - } -}; - -TEST_F(ExceptionInSetUpTest, ExceptionInSetUp) { - FAIL() << "UNEXPECTED failure in the test function. " - << "We should never get here, as SetUp() threw."; -} - -// Tests that TearDown() and the test fixture d'tor are always called, -// even when the test function throws an exception. -class ExceptionInTestFunctionTest : public testing::Test { - protected: - virtual ~ExceptionInTestFunctionTest() { - Deinit(); - } - - virtual void TearDown() { - FAIL() << "Expected failure #2, in TearDown()."; - } - private: - void Deinit() { - FAIL() << "Expected failure #3, in the test fixture d'tor."; - } -}; - -// Tests that the test fixture d'tor is always called, even when the -// test function throws an SEH exception. -TEST_F(ExceptionInTestFunctionTest, SEH) { - printf("(expecting 3 failures)\n"); - - ThrowSEH(); -} - -#if GTEST_HAS_EXCEPTIONS - -// Tests that the test fixture d'tor is always called, even when the -// test function throws a C++ exception. We do this only when -// GTEST_HAS_EXCEPTIONS is non-zero, i.e. C++ exceptions are enabled. -TEST_F(ExceptionInTestFunctionTest, CppException) { - throw 1; -} - -// Tests exceptions thrown in TearDown(). -class ExceptionInTearDownTest : public testing::Test { - protected: - virtual ~ExceptionInTearDownTest() { - Deinit(); - } - - virtual void TearDown() { - throw 1; - } - private: - void Deinit() { - FAIL() << "Expected failure #2, in the test fixture d'tor."; - } -}; - -TEST_F(ExceptionInTearDownTest, ExceptionInTearDown) { - printf("(expecting 2 failures)\n"); -} - -#endif // GTEST_HAS_EXCEPTIONS - -#endif // GTEST_OS_WINDOWS - #if GTEST_IS_THREADSAFE // A unary function that may die. diff --git a/test/gtest_output_test_golden_win.txt b/test/gtest_output_test_golden_win.txt index 135f39e3..8251c23d 100644 --- a/test/gtest_output_test_golden_win.txt +++ b/test/gtest_output_test_golden_win.txt @@ -5,7 +5,7 @@ gtest_output_test_.cc:#: error: Value of: false Expected: true gtest_output_test_.cc:#: error: Value of: 3 Expected: 2 -[==========] Running 63 tests from 29 test cases. +[==========] Running 58 tests from 25 test cases. [----------] Global test environment set-up. FooEnvironment::SetUp() called. BarEnvironment::SetUp() called. @@ -178,42 +178,6 @@ Expected failure #3, in the test fixture d'tor. foo.cc(42): error: Failed Expected failure in foo.cc [ FAILED ] AddFailureAtTest.MessageContainsSpecifiedFileAndLineNumber -[----------] 1 test from ExceptionInFixtureCtorTest -[ RUN ] ExceptionInFixtureCtorTest.ExceptionInFixtureCtor -(expecting a failure on thrown exception in the test fixture's constructor) -unknown file: error: Exception thrown with code 0xc0000005 in the test fixture's constructor. -[----------] 1 test from ExceptionInSetUpTest -[ RUN ] ExceptionInSetUpTest.ExceptionInSetUp -(expecting 3 failures) -unknown file: error: Exception thrown with code 0xc0000005 in SetUp(). -gtest_output_test_.cc:#: error: Failed -Expected failure #2, in TearDown(). -gtest_output_test_.cc:#: error: Failed -Expected failure #3, in the test fixture d'tor. -[ FAILED ] ExceptionInSetUpTest.ExceptionInSetUp -[----------] 2 tests from ExceptionInTestFunctionTest -[ RUN ] ExceptionInTestFunctionTest.SEH -(expecting 3 failures) -unknown file: error: Exception thrown with code 0xc0000005 in the test body. -gtest_output_test_.cc:#: error: Failed -Expected failure #2, in TearDown(). -gtest_output_test_.cc:#: error: Failed -Expected failure #3, in the test fixture d'tor. -[ FAILED ] ExceptionInTestFunctionTest.SEH -[ RUN ] ExceptionInTestFunctionTest.CppException -unknown file: error: Exception thrown with code 0xe06d7363 in the test body. -gtest_output_test_.cc:#: error: Failed -Expected failure #2, in TearDown(). -gtest_output_test_.cc:#: error: Failed -Expected failure #3, in the test fixture d'tor. -[ FAILED ] ExceptionInTestFunctionTest.CppException -[----------] 1 test from ExceptionInTearDownTest -[ RUN ] ExceptionInTearDownTest.ExceptionInTearDown -(expecting 2 failures) -unknown file: error: Exception thrown with code 0xe06d7363 in TearDown(). -gtest_output_test_.cc:#: error: Failed -Expected failure #2, in the test fixture d'tor. -[ FAILED ] ExceptionInTearDownTest.ExceptionInTearDown [----------] 4 tests from MixedUpTestCaseTest [ RUN ] MixedUpTestCaseTest.FirstTestFromNamespaceFoo [ OK ] MixedUpTestCaseTest.FirstTestFromNamespaceFoo @@ -497,9 +461,9 @@ Expected non-fatal failure. FooEnvironment::TearDown() called. gtest_output_test_.cc:#: error: Failed Expected fatal failure. -[==========] 63 tests from 29 test cases ran. +[==========] 58 tests from 25 test cases ran. [ PASSED ] 21 tests. -[ FAILED ] 42 tests, listed below: +[ FAILED ] 37 tests, listed below: [ FAILED ] FatalFailureTest.FatalFailureInSubroutine [ FAILED ] FatalFailureTest.FatalFailureInNestedSubroutine [ FAILED ] FatalFailureTest.NonfatalFailureInSubroutine @@ -514,11 +478,6 @@ Expected fatal failure. [ FAILED ] NonFatalFailureInSetUpTest.FailureInSetUp [ FAILED ] FatalFailureInSetUpTest.FailureInSetUp [ FAILED ] AddFailureAtTest.MessageContainsSpecifiedFileAndLineNumber -[ FAILED ] ExceptionInFixtureCtorTest.ExceptionInFixtureCtor -[ FAILED ] ExceptionInSetUpTest.ExceptionInSetUp -[ FAILED ] ExceptionInTestFunctionTest.SEH -[ FAILED ] ExceptionInTestFunctionTest.CppException -[ FAILED ] ExceptionInTearDownTest.ExceptionInTearDown [ FAILED ] MixedUpTestCaseTest.ThisShouldFail [ FAILED ] MixedUpTestCaseTest.ThisShouldFailToo [ FAILED ] MixedUpTestCaseWithSameTestNameTest.TheSecondTestWithThisNameShouldFail @@ -543,7 +502,7 @@ Expected fatal failure. [ FAILED ] ExpectFailureTest.ExpectNonFatalFailureOnAllThreads [ FAILED ] PrintingFailingParams/FailingParamTest.Fails/0, where GetParam() = 2 -42 FAILED TESTS +37 FAILED TESTS YOU HAVE 1 DISABLED TEST Note: Google Test filter = FatalFailureTest.*:LoggingTest.* diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index 910d4e20..9b95b138 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -3767,6 +3767,17 @@ TEST(AssertionTest, ExpectWorksWithUncopyableObject) { "Value of: y\n Actual: -1\nExpected: x\nWhich is: 5"); } +enum NamedEnum { + kE1 = 0, + kE2 = 1, +}; + +TEST(AssertionTest, NamedEnum) { + EXPECT_EQ(kE1, kE1); + EXPECT_LT(kE1, kE2); + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(kE1, kE2), "Which is: 0"); + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(kE1, kE2), "Actual: 1"); +} // The version of gcc used in XCode 2.2 has a bug and doesn't allow // anonymous enums in assertions. Therefore the following test is not @@ -3776,7 +3787,7 @@ TEST(AssertionTest, ExpectWorksWithUncopyableObject) { // Tests using assertions with anonymous enums. enum { - CASE_A = -1, + kCaseA = -1, #if GTEST_OS_LINUX // We want to test the case where the size of the anonymous enum is // larger than sizeof(int), to make sure our implementation of the @@ -3784,37 +3795,44 @@ enum { // (incorrectly) doesn't allow an enum value to exceed the range of // an int, so this has to be conditionally compiled. // - // On Linux, CASE_B and CASE_A have the same value when truncated to + // On Linux, kCaseB and kCaseA have the same value when truncated to // int size. We want to test whether this will confuse the // assertions. - CASE_B = testing::internal::kMaxBiggestInt, + kCaseB = testing::internal::kMaxBiggestInt, #else - CASE_B = INT_MAX, + kCaseB = INT_MAX, #endif // GTEST_OS_LINUX + kCaseC = 42, }; TEST(AssertionTest, AnonymousEnum) { #if GTEST_OS_LINUX - EXPECT_EQ(static_cast(CASE_A), static_cast(CASE_B)); + EXPECT_EQ(static_cast(kCaseA), static_cast(kCaseB)); #endif // GTEST_OS_LINUX - EXPECT_EQ(CASE_A, CASE_A); - EXPECT_NE(CASE_A, CASE_B); - EXPECT_LT(CASE_A, CASE_B); - EXPECT_LE(CASE_A, CASE_B); - EXPECT_GT(CASE_B, CASE_A); - EXPECT_GE(CASE_A, CASE_A); - EXPECT_NONFATAL_FAILURE(EXPECT_GE(CASE_A, CASE_B), - "(CASE_A) >= (CASE_B)"); - - ASSERT_EQ(CASE_A, CASE_A); - ASSERT_NE(CASE_A, CASE_B); - ASSERT_LT(CASE_A, CASE_B); - ASSERT_LE(CASE_A, CASE_B); - ASSERT_GT(CASE_B, CASE_A); - ASSERT_GE(CASE_A, CASE_A); - EXPECT_FATAL_FAILURE(ASSERT_EQ(CASE_A, CASE_B), - "Value of: CASE_B"); + EXPECT_EQ(kCaseA, kCaseA); + EXPECT_NE(kCaseA, kCaseB); + EXPECT_LT(kCaseA, kCaseB); + EXPECT_LE(kCaseA, kCaseB); + EXPECT_GT(kCaseB, kCaseA); + EXPECT_GE(kCaseA, kCaseA); + EXPECT_NONFATAL_FAILURE(EXPECT_GE(kCaseA, kCaseB), + "(kCaseA) >= (kCaseB)"); + EXPECT_NONFATAL_FAILURE(EXPECT_GE(kCaseA, kCaseC), + "-1 vs 42"); + + ASSERT_EQ(kCaseA, kCaseA); + ASSERT_NE(kCaseA, kCaseB); + ASSERT_LT(kCaseA, kCaseB); + ASSERT_LE(kCaseA, kCaseB); + ASSERT_GT(kCaseB, kCaseA); + ASSERT_GE(kCaseA, kCaseA); + EXPECT_FATAL_FAILURE(ASSERT_EQ(kCaseA, kCaseB), + "Value of: kCaseB"); + EXPECT_FATAL_FAILURE(ASSERT_EQ(kCaseA, kCaseC), + "Actual: 42"); + EXPECT_FATAL_FAILURE(ASSERT_EQ(kCaseA, kCaseC), + "Which is: -1"); } #endif // !GTEST_OS_MAC && !defined(__SUNPRO_CC) -- cgit v1.2.3 From a9f380f5c7ff75cd715c58e11885dddc54baef02 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Thu, 19 Aug 2010 22:16:00 +0000 Subject: Removes the Windows golden file (by Vlad Losev); implements test result streaming (by Nikhil Jindal and cleaned up by Zhanyong Wan). --- test/gtest_help_test.py | 13 +- test/gtest_output_test.py | 40 ++- test/gtest_output_test_golden_win.txt | 577 ---------------------------------- test/gtest_unittest.cc | 36 ++- 4 files changed, 67 insertions(+), 599 deletions(-) delete mode 100644 test/gtest_output_test_golden_win.txt (limited to 'test') diff --git a/test/gtest_help_test.py b/test/gtest_help_test.py index dc67ed3d..0777106a 100755 --- a/test/gtest_help_test.py +++ b/test/gtest_help_test.py @@ -44,12 +44,13 @@ import re import gtest_test_utils +IS_LINUX = os.name == 'posix' and os.uname()[0] == 'Linux' IS_WINDOWS = os.name == 'nt' PROGRAM_PATH = gtest_test_utils.GetTestExecutablePath('gtest_help_test_') FLAG_PREFIX = '--gtest_' -CATCH_EXCEPTIONS_FLAG = FLAG_PREFIX + 'catch_exceptions' DEATH_TEST_STYLE_FLAG = FLAG_PREFIX + 'death_test_style' +STREAM_RESULT_TO_FLAG = FLAG_PREFIX + 'stream_result_to' UNKNOWN_FLAG = FLAG_PREFIX + 'unknown_flag_for_testing' LIST_TESTS_FLAG = FLAG_PREFIX + 'list_tests' INCORRECT_FLAG_VARIANTS = [re.sub('^--', '-', LIST_TESTS_FLAG), @@ -72,7 +73,8 @@ HELP_REGEX = re.compile( FLAG_PREFIX + r'print_time.*' + FLAG_PREFIX + r'output=.*' + FLAG_PREFIX + r'break_on_failure.*' + - FLAG_PREFIX + r'throw_on_failure.*', + FLAG_PREFIX + r'throw_on_failure.*' + + FLAG_PREFIX + r'catch_exceptions.*', re.DOTALL) @@ -109,10 +111,11 @@ class GTestHelpTest(gtest_test_utils.TestCase): exit_code, output = RunWithFlag(flag) self.assertEquals(0, exit_code) self.assert_(HELP_REGEX.search(output), output) - if IS_WINDOWS: - self.assert_(CATCH_EXCEPTIONS_FLAG in output, output) + + if IS_LINUX: + self.assert_(STREAM_RESULT_TO_FLAG in output, output) else: - self.assert_(CATCH_EXCEPTIONS_FLAG not in output, output) + self.assert_(STREAM_RESULT_TO_FLAG not in output, output) if SUPPORTS_DEATH_TESTS and not IS_WINDOWS: self.assert_(DEATH_TEST_STYLE_FLAG in output, output) diff --git a/test/gtest_output_test.py b/test/gtest_output_test.py index 425d9da4..f409e2a7 100755 --- a/test/gtest_output_test.py +++ b/test/gtest_output_test.py @@ -52,10 +52,8 @@ CATCH_EXCEPTIONS_ENV_VAR_NAME = 'GTEST_CATCH_EXCEPTIONS' IS_WINDOWS = os.name == 'nt' -if IS_WINDOWS: - GOLDEN_NAME = 'gtest_output_test_golden_win.txt' -else: - GOLDEN_NAME = 'gtest_output_test_golden_lin.txt' +# TODO(vladl@google.com): remove the _lin suffix. +GOLDEN_NAME = 'gtest_output_test_golden_lin.txt' PROGRAM_PATH = gtest_test_utils.GetTestExecutablePath('gtest_output_test_') @@ -138,6 +136,20 @@ def RemoveTypeInfoDetails(test_output): return re.sub(r'unsigned int', 'unsigned', test_output) +def NormalizeToCurrentPlatform(test_output): + """Normalizes platform specific output details for easier comparison.""" + + if IS_WINDOWS: + # Removes the color information that is not present on Windows. + test_output = re.sub('\x1b\\[(0;3\d)?m', '', test_output) + # Changes failure message headers into the Windows format. + test_output = re.sub(r': Failure\n', r': error: ', test_output) + # Changes file(line_number) to file:line_number. + test_output = re.sub(r'((\w|\.)+)\((\d+)\):', r'\1:\3:', test_output) + + return test_output + + def RemoveTestCounts(output): """Removes test counts from a Google Test program's output.""" @@ -240,7 +252,7 @@ SUPPORTS_STACK_TRACES = False CAN_GENERATE_GOLDEN_FILE = (SUPPORTS_DEATH_TESTS and SUPPORTS_TYPED_TESTS and - (SUPPORTS_THREADS or IS_WINDOWS)) + SUPPORTS_THREADS) class GTestOutputTest(gtest_test_utils.TestCase): @@ -284,9 +296,10 @@ class GTestOutputTest(gtest_test_utils.TestCase): if CAN_GENERATE_GOLDEN_FILE: self.assertEqual(normalized_golden, normalized_actual) else: - normalized_actual = RemoveTestCounts(normalized_actual) - normalized_golden = RemoveTestCounts(self.RemoveUnsupportedTests( - normalized_golden)) + normalized_actual = NormalizeToCurrentPlatform( + RemoveTestCounts(normalized_actual)) + normalized_golden = NormalizeToCurrentPlatform( + RemoveTestCounts(self.RemoveUnsupportedTests(normalized_golden))) # This code is very handy when debugging golden file differences: if os.getenv('DEBUG_GTEST_OUTPUT_TEST'): @@ -312,14 +325,9 @@ if __name__ == '__main__': else: message = ( """Unable to write a golden file when compiled in an environment -that does not support all the required features (death tests""") - if IS_WINDOWS: - message += ( - """\nand typed tests). Please check that you are using VC++ 8.0 SP1 -or higher as your compiler.""") - else: - message += """\ntyped tests, and threads). Please generate the -golden file using a binary built with those features enabled.""" +that does not support all the required features (death tests, typed tests, +and multiple threads). Please generate the golden file using a binary built +with those features enabled.""") sys.stderr.write(message) sys.exit(1) diff --git a/test/gtest_output_test_golden_win.txt b/test/gtest_output_test_golden_win.txt deleted file mode 100644 index 8251c23d..00000000 --- a/test/gtest_output_test_golden_win.txt +++ /dev/null @@ -1,577 +0,0 @@ -The non-test part of the code is expected to have 2 failures. - -gtest_output_test_.cc:#: error: Value of: false - Actual: false -Expected: true -gtest_output_test_.cc:#: error: Value of: 3 -Expected: 2 -[==========] Running 58 tests from 25 test cases. -[----------] Global test environment set-up. -FooEnvironment::SetUp() called. -BarEnvironment::SetUp() called. -[----------] 1 test from ADeathTest -[ RUN ] ADeathTest.ShouldRunFirst -[ OK ] ADeathTest.ShouldRunFirst -[----------] 1 test from ATypedDeathTest/0, where TypeParam = int -[ RUN ] ATypedDeathTest/0.ShouldRunFirst -[ OK ] ATypedDeathTest/0.ShouldRunFirst -[----------] 1 test from ATypedDeathTest/1, where TypeParam = double -[ RUN ] ATypedDeathTest/1.ShouldRunFirst -[ OK ] ATypedDeathTest/1.ShouldRunFirst -[----------] 1 test from My/ATypeParamDeathTest/0, where TypeParam = int -[ RUN ] My/ATypeParamDeathTest/0.ShouldRunFirst -[ OK ] My/ATypeParamDeathTest/0.ShouldRunFirst -[----------] 1 test from My/ATypeParamDeathTest/1, where TypeParam = double -[ RUN ] My/ATypeParamDeathTest/1.ShouldRunFirst -[ OK ] My/ATypeParamDeathTest/1.ShouldRunFirst -[----------] 2 tests from PassingTest -[ RUN ] PassingTest.PassingTest1 -[ OK ] PassingTest.PassingTest1 -[ RUN ] PassingTest.PassingTest2 -[ OK ] PassingTest.PassingTest2 -[----------] 3 tests from FatalFailureTest -[ RUN ] FatalFailureTest.FatalFailureInSubroutine -(expecting a failure that x should be 1) -gtest_output_test_.cc:#: error: Value of: x - Actual: 2 -Expected: 1 -[ FAILED ] FatalFailureTest.FatalFailureInSubroutine -[ RUN ] FatalFailureTest.FatalFailureInNestedSubroutine -(expecting a failure that x should be 1) -gtest_output_test_.cc:#: error: Value of: x - Actual: 2 -Expected: 1 -[ FAILED ] FatalFailureTest.FatalFailureInNestedSubroutine -[ RUN ] FatalFailureTest.NonfatalFailureInSubroutine -(expecting a failure on false) -gtest_output_test_.cc:#: error: Value of: false - Actual: false -Expected: true -[ FAILED ] FatalFailureTest.NonfatalFailureInSubroutine -[----------] 1 test from LoggingTest -[ RUN ] LoggingTest.InterleavingLoggingAndAssertions -(expecting 2 failures on (3) >= (a[i])) -i == 0 -i == 1 -gtest_output_test_.cc:#: error: Expected: (3) >= (a[i]), actual: 3 vs 9 -i == 2 -i == 3 -gtest_output_test_.cc:#: error: Expected: (3) >= (a[i]), actual: 3 vs 6 -[ FAILED ] LoggingTest.InterleavingLoggingAndAssertions -[----------] 5 tests from SCOPED_TRACETest -[ RUN ] SCOPED_TRACETest.ObeysScopes -(expected to fail) -gtest_output_test_.cc:#: error: Failed -This failure is expected, and shouldn't have a trace. -gtest_output_test_.cc:#: error: Failed -This failure is expected, and should have a trace. -Google Test trace: -gtest_output_test_.cc:#: Expected trace -gtest_output_test_.cc:#: error: Failed -This failure is expected, and shouldn't have a trace. -[ FAILED ] SCOPED_TRACETest.ObeysScopes -[ RUN ] SCOPED_TRACETest.WorksInLoop -(expected to fail) -gtest_output_test_.cc:#: error: Value of: n - Actual: 1 -Expected: 2 -Google Test trace: -gtest_output_test_.cc:#: i = 1 -gtest_output_test_.cc:#: error: Value of: n - Actual: 2 -Expected: 1 -Google Test trace: -gtest_output_test_.cc:#: i = 2 -[ FAILED ] SCOPED_TRACETest.WorksInLoop -[ RUN ] SCOPED_TRACETest.WorksInSubroutine -(expected to fail) -gtest_output_test_.cc:#: error: Value of: n - Actual: 1 -Expected: 2 -Google Test trace: -gtest_output_test_.cc:#: n = 1 -gtest_output_test_.cc:#: error: Value of: n - Actual: 2 -Expected: 1 -Google Test trace: -gtest_output_test_.cc:#: n = 2 -[ FAILED ] SCOPED_TRACETest.WorksInSubroutine -[ RUN ] SCOPED_TRACETest.CanBeNested -(expected to fail) -gtest_output_test_.cc:#: error: Value of: n - Actual: 2 -Expected: 1 -Google Test trace: -gtest_output_test_.cc:#: n = 2 -gtest_output_test_.cc:#: -[ FAILED ] SCOPED_TRACETest.CanBeNested -[ RUN ] SCOPED_TRACETest.CanBeRepeated -(expected to fail) -gtest_output_test_.cc:#: error: Failed -This failure is expected, and should contain trace point A. -Google Test trace: -gtest_output_test_.cc:#: A -gtest_output_test_.cc:#: error: Failed -This failure is expected, and should contain trace point A and B. -Google Test trace: -gtest_output_test_.cc:#: B -gtest_output_test_.cc:#: A -gtest_output_test_.cc:#: error: Failed -This failure is expected, and should contain trace point A, B, and C. -Google Test trace: -gtest_output_test_.cc:#: C -gtest_output_test_.cc:#: B -gtest_output_test_.cc:#: A -gtest_output_test_.cc:#: error: Failed -This failure is expected, and should contain trace point A, B, and D. -Google Test trace: -gtest_output_test_.cc:#: D -gtest_output_test_.cc:#: B -gtest_output_test_.cc:#: A -[ FAILED ] SCOPED_TRACETest.CanBeRepeated -[----------] 1 test from NonFatalFailureInFixtureConstructorTest -[ RUN ] NonFatalFailureInFixtureConstructorTest.FailureInConstructor -(expecting 5 failures) -gtest_output_test_.cc:#: error: Failed -Expected failure #1, in the test fixture c'tor. -gtest_output_test_.cc:#: error: Failed -Expected failure #2, in SetUp(). -gtest_output_test_.cc:#: error: Failed -Expected failure #3, in the test body. -gtest_output_test_.cc:#: error: Failed -Expected failure #4, in TearDown. -gtest_output_test_.cc:#: error: Failed -Expected failure #5, in the test fixture d'tor. -[ FAILED ] NonFatalFailureInFixtureConstructorTest.FailureInConstructor -[----------] 1 test from FatalFailureInFixtureConstructorTest -[ RUN ] FatalFailureInFixtureConstructorTest.FailureInConstructor -(expecting 2 failures) -gtest_output_test_.cc:#: error: Failed -Expected failure #1, in the test fixture c'tor. -gtest_output_test_.cc:#: error: Failed -Expected failure #2, in the test fixture d'tor. -[ FAILED ] FatalFailureInFixtureConstructorTest.FailureInConstructor -[----------] 1 test from NonFatalFailureInSetUpTest -[ RUN ] NonFatalFailureInSetUpTest.FailureInSetUp -(expecting 4 failures) -gtest_output_test_.cc:#: error: Failed -Expected failure #1, in SetUp(). -gtest_output_test_.cc:#: error: Failed -Expected failure #2, in the test function. -gtest_output_test_.cc:#: error: Failed -Expected failure #3, in TearDown(). -gtest_output_test_.cc:#: error: Failed -Expected failure #4, in the test fixture d'tor. -[ FAILED ] NonFatalFailureInSetUpTest.FailureInSetUp -[----------] 1 test from FatalFailureInSetUpTest -[ RUN ] FatalFailureInSetUpTest.FailureInSetUp -(expecting 3 failures) -gtest_output_test_.cc:#: error: Failed -Expected failure #1, in SetUp(). -gtest_output_test_.cc:#: error: Failed -Expected failure #2, in TearDown(). -gtest_output_test_.cc:#: error: Failed -Expected failure #3, in the test fixture d'tor. -[ FAILED ] FatalFailureInSetUpTest.FailureInSetUp -[----------] 1 test from AddFailureAtTest -[ RUN ] AddFailureAtTest.MessageContainsSpecifiedFileAndLineNumber -foo.cc(42): error: Failed -Expected failure in foo.cc -[ FAILED ] AddFailureAtTest.MessageContainsSpecifiedFileAndLineNumber -[----------] 4 tests from MixedUpTestCaseTest -[ RUN ] MixedUpTestCaseTest.FirstTestFromNamespaceFoo -[ OK ] MixedUpTestCaseTest.FirstTestFromNamespaceFoo -[ RUN ] MixedUpTestCaseTest.SecondTestFromNamespaceFoo -[ OK ] MixedUpTestCaseTest.SecondTestFromNamespaceFoo -[ RUN ] MixedUpTestCaseTest.ThisShouldFail -gtest.cc:#: error: Failed -All tests in the same test case must use the same test fixture -class. However, in test case MixedUpTestCaseTest, -you defined test FirstTestFromNamespaceFoo and test ThisShouldFail -using two different test fixture classes. This can happen if -the two classes are from different namespaces or translation -units and have the same name. You should probably rename one -of the classes to put the tests into different test cases. -[ FAILED ] MixedUpTestCaseTest.ThisShouldFail -[ RUN ] MixedUpTestCaseTest.ThisShouldFailToo -gtest.cc:#: error: Failed -All tests in the same test case must use the same test fixture -class. However, in test case MixedUpTestCaseTest, -you defined test FirstTestFromNamespaceFoo and test ThisShouldFailToo -using two different test fixture classes. This can happen if -the two classes are from different namespaces or translation -units and have the same name. You should probably rename one -of the classes to put the tests into different test cases. -[ FAILED ] MixedUpTestCaseTest.ThisShouldFailToo -[----------] 2 tests from MixedUpTestCaseWithSameTestNameTest -[ RUN ] MixedUpTestCaseWithSameTestNameTest.TheSecondTestWithThisNameShouldFail -[ OK ] MixedUpTestCaseWithSameTestNameTest.TheSecondTestWithThisNameShouldFail -[ RUN ] MixedUpTestCaseWithSameTestNameTest.TheSecondTestWithThisNameShouldFail -gtest.cc:#: error: Failed -All tests in the same test case must use the same test fixture -class. However, in test case MixedUpTestCaseWithSameTestNameTest, -you defined test TheSecondTestWithThisNameShouldFail and test TheSecondTestWithThisNameShouldFail -using two different test fixture classes. This can happen if -the two classes are from different namespaces or translation -units and have the same name. You should probably rename one -of the classes to put the tests into different test cases. -[ FAILED ] MixedUpTestCaseWithSameTestNameTest.TheSecondTestWithThisNameShouldFail -[----------] 2 tests from TEST_F_before_TEST_in_same_test_case -[ RUN ] TEST_F_before_TEST_in_same_test_case.DefinedUsingTEST_F -[ OK ] TEST_F_before_TEST_in_same_test_case.DefinedUsingTEST_F -[ RUN ] TEST_F_before_TEST_in_same_test_case.DefinedUsingTESTAndShouldFail -gtest.cc:#: error: Failed -All tests in the same test case must use the same test fixture -class, so mixing TEST_F and TEST in the same test case is -illegal. In test case TEST_F_before_TEST_in_same_test_case, -test DefinedUsingTEST_F is defined using TEST_F but -test DefinedUsingTESTAndShouldFail is defined using TEST. You probably -want to change the TEST to TEST_F or move it to another test -case. -[ FAILED ] TEST_F_before_TEST_in_same_test_case.DefinedUsingTESTAndShouldFail -[----------] 2 tests from TEST_before_TEST_F_in_same_test_case -[ RUN ] TEST_before_TEST_F_in_same_test_case.DefinedUsingTEST -[ OK ] TEST_before_TEST_F_in_same_test_case.DefinedUsingTEST -[ RUN ] TEST_before_TEST_F_in_same_test_case.DefinedUsingTEST_FAndShouldFail -gtest.cc:#: error: Failed -All tests in the same test case must use the same test fixture -class, so mixing TEST_F and TEST in the same test case is -illegal. In test case TEST_before_TEST_F_in_same_test_case, -test DefinedUsingTEST_FAndShouldFail is defined using TEST_F but -test DefinedUsingTEST is defined using TEST. You probably -want to change the TEST to TEST_F or move it to another test -case. -[ FAILED ] TEST_before_TEST_F_in_same_test_case.DefinedUsingTEST_FAndShouldFail -[----------] 8 tests from ExpectNonfatalFailureTest -[ RUN ] ExpectNonfatalFailureTest.CanReferenceGlobalVariables -[ OK ] ExpectNonfatalFailureTest.CanReferenceGlobalVariables -[ RUN ] ExpectNonfatalFailureTest.CanReferenceLocalVariables -[ OK ] ExpectNonfatalFailureTest.CanReferenceLocalVariables -[ RUN ] ExpectNonfatalFailureTest.SucceedsWhenThereIsOneNonfatalFailure -[ OK ] ExpectNonfatalFailureTest.SucceedsWhenThereIsOneNonfatalFailure -[ RUN ] ExpectNonfatalFailureTest.FailsWhenThereIsNoNonfatalFailure -(expecting a failure) -gtest.cc:#: error: Expected: 1 non-fatal failure - Actual: 0 failures -[ FAILED ] ExpectNonfatalFailureTest.FailsWhenThereIsNoNonfatalFailure -[ RUN ] ExpectNonfatalFailureTest.FailsWhenThereAreTwoNonfatalFailures -(expecting a failure) -gtest.cc:#: error: Expected: 1 non-fatal failure - Actual: 2 failures -gtest_output_test_.cc:#: Non-fatal failure: -Failed -Expected non-fatal failure 1. - -gtest_output_test_.cc:#: Non-fatal failure: -Failed -Expected non-fatal failure 2. - -[ FAILED ] ExpectNonfatalFailureTest.FailsWhenThereAreTwoNonfatalFailures -[ RUN ] ExpectNonfatalFailureTest.FailsWhenThereIsOneFatalFailure -(expecting a failure) -gtest.cc:#: error: Expected: 1 non-fatal failure - Actual: -gtest_output_test_.cc:#: Fatal failure: -Failed -Expected fatal failure. - -[ FAILED ] ExpectNonfatalFailureTest.FailsWhenThereIsOneFatalFailure -[ RUN ] ExpectNonfatalFailureTest.FailsWhenStatementReturns -(expecting a failure) -gtest.cc:#: error: Expected: 1 non-fatal failure - Actual: 0 failures -[ FAILED ] ExpectNonfatalFailureTest.FailsWhenStatementReturns -[ RUN ] ExpectNonfatalFailureTest.FailsWhenStatementThrows -(expecting a failure) -gtest.cc:#: error: Expected: 1 non-fatal failure - Actual: 0 failures -[ FAILED ] ExpectNonfatalFailureTest.FailsWhenStatementThrows -[----------] 8 tests from ExpectFatalFailureTest -[ RUN ] ExpectFatalFailureTest.CanReferenceGlobalVariables -[ OK ] ExpectFatalFailureTest.CanReferenceGlobalVariables -[ RUN ] ExpectFatalFailureTest.CanReferenceLocalStaticVariables -[ OK ] ExpectFatalFailureTest.CanReferenceLocalStaticVariables -[ RUN ] ExpectFatalFailureTest.SucceedsWhenThereIsOneFatalFailure -[ OK ] ExpectFatalFailureTest.SucceedsWhenThereIsOneFatalFailure -[ RUN ] ExpectFatalFailureTest.FailsWhenThereIsNoFatalFailure -(expecting a failure) -gtest.cc:#: error: Expected: 1 fatal failure - Actual: 0 failures -[ FAILED ] ExpectFatalFailureTest.FailsWhenThereIsNoFatalFailure -[ RUN ] ExpectFatalFailureTest.FailsWhenThereAreTwoFatalFailures -(expecting a failure) -gtest.cc:#: error: Expected: 1 fatal failure - Actual: 2 failures -gtest_output_test_.cc:#: Fatal failure: -Failed -Expected fatal failure. - -gtest_output_test_.cc:#: Fatal failure: -Failed -Expected fatal failure. - -[ FAILED ] ExpectFatalFailureTest.FailsWhenThereAreTwoFatalFailures -[ RUN ] ExpectFatalFailureTest.FailsWhenThereIsOneNonfatalFailure -(expecting a failure) -gtest.cc:#: error: Expected: 1 fatal failure - Actual: -gtest_output_test_.cc:#: Non-fatal failure: -Failed -Expected non-fatal failure. - -[ FAILED ] ExpectFatalFailureTest.FailsWhenThereIsOneNonfatalFailure -[ RUN ] ExpectFatalFailureTest.FailsWhenStatementReturns -(expecting a failure) -gtest.cc:#: error: Expected: 1 fatal failure - Actual: 0 failures -[ FAILED ] ExpectFatalFailureTest.FailsWhenStatementReturns -[ RUN ] ExpectFatalFailureTest.FailsWhenStatementThrows -(expecting a failure) -gtest.cc:#: error: Expected: 1 fatal failure - Actual: 0 failures -[ FAILED ] ExpectFatalFailureTest.FailsWhenStatementThrows -[----------] 2 tests from TypedTest/0, where TypeParam = int -[ RUN ] TypedTest/0.Success -[ OK ] TypedTest/0.Success -[ RUN ] TypedTest/0.Failure -gtest_output_test_.cc:#: error: Value of: TypeParam() - Actual: 0 -Expected: 1 -Expected failure -[ FAILED ] TypedTest/0.Failure, where TypeParam = int -[----------] 2 tests from Unsigned/TypedTestP/0, where TypeParam = unsigned char -[ RUN ] Unsigned/TypedTestP/0.Success -[ OK ] Unsigned/TypedTestP/0.Success -[ RUN ] Unsigned/TypedTestP/0.Failure -gtest_output_test_.cc:#: error: Value of: TypeParam() - Actual: '\0' -Expected: 1U -Which is: 1 -Expected failure -[ FAILED ] Unsigned/TypedTestP/0.Failure, where TypeParam = unsigned char -[----------] 2 tests from Unsigned/TypedTestP/1, where TypeParam = unsigned int -[ RUN ] Unsigned/TypedTestP/1.Success -[ OK ] Unsigned/TypedTestP/1.Success -[ RUN ] Unsigned/TypedTestP/1.Failure -gtest_output_test_.cc:#: error: Value of: TypeParam() - Actual: 0 -Expected: 1U -Which is: 1 -Expected failure -[ FAILED ] Unsigned/TypedTestP/1.Failure, where TypeParam = unsigned int -[----------] 4 tests from ExpectFailureTest -[ RUN ] ExpectFailureTest.ExpectFatalFailure -(expecting 1 failure) -gtest.cc:#: error: Expected: 1 fatal failure - Actual: -gtest_output_test_.cc:#: Success: -Succeeded - -(expecting 1 failure) -gtest.cc:#: error: Expected: 1 fatal failure - Actual: -gtest_output_test_.cc:#: Non-fatal failure: -Failed -Expected non-fatal failure. - -(expecting 1 failure) -gtest.cc:#: error: Expected: 1 fatal failure containing "Some other fatal failure expected." - Actual: -gtest_output_test_.cc:#: Fatal failure: -Failed -Expected fatal failure. - -[ FAILED ] ExpectFailureTest.ExpectFatalFailure -[ RUN ] ExpectFailureTest.ExpectNonFatalFailure -(expecting 1 failure) -gtest.cc:#: error: Expected: 1 non-fatal failure - Actual: -gtest_output_test_.cc:#: Success: -Succeeded - -(expecting 1 failure) -gtest.cc:#: error: Expected: 1 non-fatal failure - Actual: -gtest_output_test_.cc:#: Fatal failure: -Failed -Expected fatal failure. - -(expecting 1 failure) -gtest.cc:#: error: Expected: 1 non-fatal failure containing "Some other non-fatal failure." - Actual: -gtest_output_test_.cc:#: Non-fatal failure: -Failed -Expected non-fatal failure. - -[ FAILED ] ExpectFailureTest.ExpectNonFatalFailure -[ RUN ] ExpectFailureTest.ExpectFatalFailureOnAllThreads -(expecting 1 failure) -gtest.cc:#: error: Expected: 1 fatal failure - Actual: -gtest_output_test_.cc:#: Success: -Succeeded - -(expecting 1 failure) -gtest.cc:#: error: Expected: 1 fatal failure - Actual: -gtest_output_test_.cc:#: Non-fatal failure: -Failed -Expected non-fatal failure. - -(expecting 1 failure) -gtest.cc:#: error: Expected: 1 fatal failure containing "Some other fatal failure expected." - Actual: -gtest_output_test_.cc:#: Fatal failure: -Failed -Expected fatal failure. - -[ FAILED ] ExpectFailureTest.ExpectFatalFailureOnAllThreads -[ RUN ] ExpectFailureTest.ExpectNonFatalFailureOnAllThreads -(expecting 1 failure) -gtest.cc:#: error: Expected: 1 non-fatal failure - Actual: -gtest_output_test_.cc:#: Success: -Succeeded - -(expecting 1 failure) -gtest.cc:#: error: Expected: 1 non-fatal failure - Actual: -gtest_output_test_.cc:#: Fatal failure: -Failed -Expected fatal failure. - -(expecting 1 failure) -gtest.cc:#: error: Expected: 1 non-fatal failure containing "Some other non-fatal failure." - Actual: -gtest_output_test_.cc:#: Non-fatal failure: -Failed -Expected non-fatal failure. - -[ FAILED ] ExpectFailureTest.ExpectNonFatalFailureOnAllThreads -[----------] 1 test from PrintingFailingParams/FailingParamTest -[ RUN ] PrintingFailingParams/FailingParamTest.Fails/0 -gtest_output_test_.cc:#: error: Value of: GetParam() - Actual: 2 -Expected: 1 -[ FAILED ] PrintingFailingParams/FailingParamTest.Fails/0, where GetParam() = 2 -[----------] Global test environment tear-down -BarEnvironment::TearDown() called. -gtest_output_test_.cc:#: error: Failed -Expected non-fatal failure. -FooEnvironment::TearDown() called. -gtest_output_test_.cc:#: error: Failed -Expected fatal failure. -[==========] 58 tests from 25 test cases ran. -[ PASSED ] 21 tests. -[ FAILED ] 37 tests, listed below: -[ FAILED ] FatalFailureTest.FatalFailureInSubroutine -[ FAILED ] FatalFailureTest.FatalFailureInNestedSubroutine -[ FAILED ] FatalFailureTest.NonfatalFailureInSubroutine -[ FAILED ] LoggingTest.InterleavingLoggingAndAssertions -[ FAILED ] SCOPED_TRACETest.ObeysScopes -[ FAILED ] SCOPED_TRACETest.WorksInLoop -[ FAILED ] SCOPED_TRACETest.WorksInSubroutine -[ FAILED ] SCOPED_TRACETest.CanBeNested -[ FAILED ] SCOPED_TRACETest.CanBeRepeated -[ FAILED ] NonFatalFailureInFixtureConstructorTest.FailureInConstructor -[ FAILED ] FatalFailureInFixtureConstructorTest.FailureInConstructor -[ FAILED ] NonFatalFailureInSetUpTest.FailureInSetUp -[ FAILED ] FatalFailureInSetUpTest.FailureInSetUp -[ FAILED ] AddFailureAtTest.MessageContainsSpecifiedFileAndLineNumber -[ FAILED ] MixedUpTestCaseTest.ThisShouldFail -[ FAILED ] MixedUpTestCaseTest.ThisShouldFailToo -[ FAILED ] MixedUpTestCaseWithSameTestNameTest.TheSecondTestWithThisNameShouldFail -[ FAILED ] TEST_F_before_TEST_in_same_test_case.DefinedUsingTESTAndShouldFail -[ FAILED ] TEST_before_TEST_F_in_same_test_case.DefinedUsingTEST_FAndShouldFail -[ FAILED ] ExpectNonfatalFailureTest.FailsWhenThereIsNoNonfatalFailure -[ FAILED ] ExpectNonfatalFailureTest.FailsWhenThereAreTwoNonfatalFailures -[ FAILED ] ExpectNonfatalFailureTest.FailsWhenThereIsOneFatalFailure -[ FAILED ] ExpectNonfatalFailureTest.FailsWhenStatementReturns -[ FAILED ] ExpectNonfatalFailureTest.FailsWhenStatementThrows -[ FAILED ] ExpectFatalFailureTest.FailsWhenThereIsNoFatalFailure -[ FAILED ] ExpectFatalFailureTest.FailsWhenThereAreTwoFatalFailures -[ FAILED ] ExpectFatalFailureTest.FailsWhenThereIsOneNonfatalFailure -[ FAILED ] ExpectFatalFailureTest.FailsWhenStatementReturns -[ FAILED ] ExpectFatalFailureTest.FailsWhenStatementThrows -[ FAILED ] TypedTest/0.Failure, where TypeParam = int -[ FAILED ] Unsigned/TypedTestP/0.Failure, where TypeParam = unsigned char -[ FAILED ] Unsigned/TypedTestP/1.Failure, where TypeParam = unsigned int -[ FAILED ] ExpectFailureTest.ExpectFatalFailure -[ FAILED ] ExpectFailureTest.ExpectNonFatalFailure -[ FAILED ] ExpectFailureTest.ExpectFatalFailureOnAllThreads -[ FAILED ] ExpectFailureTest.ExpectNonFatalFailureOnAllThreads -[ FAILED ] PrintingFailingParams/FailingParamTest.Fails/0, where GetParam() = 2 - -37 FAILED TESTS - YOU HAVE 1 DISABLED TEST - -Note: Google Test filter = FatalFailureTest.*:LoggingTest.* -[==========] Running 4 tests from 2 test cases. -[----------] Global test environment set-up. -[----------] 3 tests from FatalFailureTest -[ RUN ] FatalFailureTest.FatalFailureInSubroutine -(expecting a failure that x should be 1) -gtest_output_test_.cc:#: error: Value of: x - Actual: 2 -Expected: 1 -[ FAILED ] FatalFailureTest.FatalFailureInSubroutine (? ms) -[ RUN ] FatalFailureTest.FatalFailureInNestedSubroutine -(expecting a failure that x should be 1) -gtest_output_test_.cc:#: error: Value of: x - Actual: 2 -Expected: 1 -[ FAILED ] FatalFailureTest.FatalFailureInNestedSubroutine (? ms) -[ RUN ] FatalFailureTest.NonfatalFailureInSubroutine -(expecting a failure on false) -gtest_output_test_.cc:#: error: Value of: false - Actual: false -Expected: true -[ FAILED ] FatalFailureTest.NonfatalFailureInSubroutine (? ms) -[----------] 3 tests from FatalFailureTest (? ms total) - -[----------] 1 test from LoggingTest -[ RUN ] LoggingTest.InterleavingLoggingAndAssertions -(expecting 2 failures on (3) >= (a[i])) -i == 0 -i == 1 -gtest_output_test_.cc:#: error: Expected: (3) >= (a[i]), actual: 3 vs 9 -i == 2 -i == 3 -gtest_output_test_.cc:#: error: Expected: (3) >= (a[i]), actual: 3 vs 6 -[ FAILED ] LoggingTest.InterleavingLoggingAndAssertions (? ms) -[----------] 1 test from LoggingTest (? ms total) - -[----------] Global test environment tear-down -[==========] 4 tests from 2 test cases ran. (? ms total) -[ PASSED ] 0 tests. -[ FAILED ] 4 tests, listed below: -[ FAILED ] FatalFailureTest.FatalFailureInSubroutine -[ FAILED ] FatalFailureTest.FatalFailureInNestedSubroutine -[ FAILED ] FatalFailureTest.NonfatalFailureInSubroutine -[ FAILED ] LoggingTest.InterleavingLoggingAndAssertions - - 4 FAILED TESTS - YOU HAVE 1 DISABLED TEST - -Note: Google Test filter = *DISABLED_* -[==========] Running 1 test from 1 test case. -[----------] Global test environment set-up. -[----------] 1 test from DisabledTestsWarningTest -[ RUN ] DisabledTestsWarningTest.DISABLED_AlsoRunDisabledTestsFlagSuppressesWarning -[ OK ] DisabledTestsWarningTest.DISABLED_AlsoRunDisabledTestsFlagSuppressesWarning -[----------] Global test environment tear-down -[==========] 1 test from 1 test case ran. -[ PASSED ] 1 test. -Note: Google Test filter = PassingTest.* -Note: This is test shard 1 of 2. -[==========] Running 1 test from 1 test case. -[----------] Global test environment set-up. -[----------] 1 test from PassingTest -[ RUN ] PassingTest.PassingTest2 -[ OK ] PassingTest.PassingTest2 -[----------] Global test environment tear-down -[==========] 1 test from 1 test case ran. -[ PASSED ] 1 test. - - YOU HAVE 1 DISABLED TEST - diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index 9b95b138..d993c048 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -52,6 +52,7 @@ TEST(CommandLineFlagsTest, CanBeAccessedInCodeOnceGTestHIsIncluded) { || testing::GTEST_FLAG(show_internal_stack_frames) || testing::GTEST_FLAG(shuffle) || testing::GTEST_FLAG(stack_trace_depth) > 0 + || testing::GTEST_FLAG(stream_result_to) != "unknown" || testing::GTEST_FLAG(throw_on_failure); EXPECT_TRUE(dummy || !dummy); // Suppresses warning that dummy is unused. } @@ -125,6 +126,7 @@ using testing::GTEST_FLAG(repeat); using testing::GTEST_FLAG(show_internal_stack_frames); using testing::GTEST_FLAG(shuffle); using testing::GTEST_FLAG(stack_trace_depth); +using testing::GTEST_FLAG(stream_result_to); using testing::GTEST_FLAG(throw_on_failure); using testing::IsNotSubstring; using testing::IsSubstring; @@ -1718,6 +1720,7 @@ class GTestFlagSaverTest : public Test { GTEST_FLAG(repeat) = 1; GTEST_FLAG(shuffle) = false; GTEST_FLAG(stack_trace_depth) = kMaxStackTraceDepth; + GTEST_FLAG(stream_result_to) = ""; GTEST_FLAG(throw_on_failure) = false; } @@ -1744,6 +1747,7 @@ class GTestFlagSaverTest : public Test { EXPECT_EQ(1, GTEST_FLAG(repeat)); EXPECT_FALSE(GTEST_FLAG(shuffle)); EXPECT_EQ(kMaxStackTraceDepth, GTEST_FLAG(stack_trace_depth)); + EXPECT_STREQ("", GTEST_FLAG(stream_result_to).c_str()); EXPECT_FALSE(GTEST_FLAG(throw_on_failure)); GTEST_FLAG(also_run_disabled_tests) = true; @@ -1759,6 +1763,7 @@ class GTestFlagSaverTest : public Test { GTEST_FLAG(repeat) = 100; GTEST_FLAG(shuffle) = true; GTEST_FLAG(stack_trace_depth) = 1; + GTEST_FLAG(stream_result_to) = "localhost:1234"; GTEST_FLAG(throw_on_failure) = true; } private: @@ -5142,6 +5147,7 @@ struct Flags { repeat(1), shuffle(false), stack_trace_depth(kMaxStackTraceDepth), + stream_result_to(""), throw_on_failure(false) {} // Factory methods. @@ -5242,6 +5248,14 @@ struct Flags { return flags; } + // Creates a Flags struct where the GTEST_FLAG(stream_result_to) flag has + // the given value. + static Flags StreamResultTo(const char* stream_result_to) { + Flags flags; + flags.stream_result_to = stream_result_to; + return flags; + } + // Creates a Flags struct where the gtest_throw_on_failure flag has // the given value. static Flags ThrowOnFailure(bool throw_on_failure) { @@ -5263,6 +5277,7 @@ struct Flags { Int32 repeat; bool shuffle; Int32 stack_trace_depth; + const char* stream_result_to; bool throw_on_failure; }; @@ -5283,6 +5298,7 @@ class InitGoogleTestTest : public Test { GTEST_FLAG(repeat) = 1; GTEST_FLAG(shuffle) = false; GTEST_FLAG(stack_trace_depth) = kMaxStackTraceDepth; + GTEST_FLAG(stream_result_to) = ""; GTEST_FLAG(throw_on_failure) = false; } @@ -5311,8 +5327,10 @@ class InitGoogleTestTest : public Test { EXPECT_EQ(expected.random_seed, GTEST_FLAG(random_seed)); EXPECT_EQ(expected.repeat, GTEST_FLAG(repeat)); EXPECT_EQ(expected.shuffle, GTEST_FLAG(shuffle)); - EXPECT_EQ(expected.throw_on_failure, GTEST_FLAG(throw_on_failure)); EXPECT_EQ(expected.stack_trace_depth, GTEST_FLAG(stack_trace_depth)); + EXPECT_STREQ(expected.stream_result_to, + GTEST_FLAG(stream_result_to).c_str()); + EXPECT_EQ(expected.throw_on_failure, GTEST_FLAG(throw_on_failure)); } // Parses a command line (specified by argc1 and argv1), then @@ -5973,6 +5991,22 @@ TEST_F(InitGoogleTestTest, StackTraceDepth) { GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::StackTraceDepth(5), false); } +TEST_F(InitGoogleTestTest, StreamResultTo) { + const char* argv[] = { + "foo.exe", + "--gtest_stream_result_to=localhost:1234", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_( + argv, argv2, Flags::StreamResultTo("localhost:1234"), false); +} + // Tests parsing --gtest_throw_on_failure. TEST_F(InitGoogleTestTest, ThrowOnFailureWithoutValue) { const char* argv[] = { -- cgit v1.2.3 From 35c39756495bea5959de5778aaaf33a94f8c1e2e Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Tue, 31 Aug 2010 18:21:13 +0000 Subject: Casts char to unsigned char before calling isspace() etc to avoid undefined behavior (by Zhanyong Wan); removes conditional #includes keyed on GTEST_HAS_PROTOBUF_ (by Zhanyong Wan); publishes GTEST_HAS_STREAM_REDIRECTION (by Vlad Losev); forward declares some classes properly (by Samuel Benzaquen); honors the --gtest_catch_exceptions flag (by Vlad Losev). --- test/gtest-port_test.cc | 102 +++++++++++++++++------------------ test/gtest-printers_test.cc | 2 +- test/gtest_catch_exceptions_test.py | 22 ++++++-- test/gtest_catch_exceptions_test_.cc | 17 ++++-- test/gtest_unittest.cc | 25 ++++----- 5 files changed, 93 insertions(+), 75 deletions(-) (limited to 'test') diff --git a/test/gtest-port_test.cc b/test/gtest-port_test.cc index 6cdbfab4..e08afe8e 100644 --- a/test/gtest-port_test.cc +++ b/test/gtest-port_test.cc @@ -377,33 +377,33 @@ TEST(IsInSetTest, WorksForNonNulChars) { EXPECT_TRUE(IsInSet('b', "ab")); } -TEST(IsDigitTest, IsFalseForNonDigit) { - EXPECT_FALSE(IsDigit('\0')); - EXPECT_FALSE(IsDigit(' ')); - EXPECT_FALSE(IsDigit('+')); - EXPECT_FALSE(IsDigit('-')); - EXPECT_FALSE(IsDigit('.')); - EXPECT_FALSE(IsDigit('a')); +TEST(IsAsciiDigitTest, IsFalseForNonDigit) { + EXPECT_FALSE(IsAsciiDigit('\0')); + EXPECT_FALSE(IsAsciiDigit(' ')); + EXPECT_FALSE(IsAsciiDigit('+')); + EXPECT_FALSE(IsAsciiDigit('-')); + EXPECT_FALSE(IsAsciiDigit('.')); + EXPECT_FALSE(IsAsciiDigit('a')); } -TEST(IsDigitTest, IsTrueForDigit) { - EXPECT_TRUE(IsDigit('0')); - EXPECT_TRUE(IsDigit('1')); - EXPECT_TRUE(IsDigit('5')); - EXPECT_TRUE(IsDigit('9')); +TEST(IsAsciiDigitTest, IsTrueForDigit) { + EXPECT_TRUE(IsAsciiDigit('0')); + EXPECT_TRUE(IsAsciiDigit('1')); + EXPECT_TRUE(IsAsciiDigit('5')); + EXPECT_TRUE(IsAsciiDigit('9')); } -TEST(IsPunctTest, IsFalseForNonPunct) { - EXPECT_FALSE(IsPunct('\0')); - EXPECT_FALSE(IsPunct(' ')); - EXPECT_FALSE(IsPunct('\n')); - EXPECT_FALSE(IsPunct('a')); - EXPECT_FALSE(IsPunct('0')); +TEST(IsAsciiPunctTest, IsFalseForNonPunct) { + EXPECT_FALSE(IsAsciiPunct('\0')); + EXPECT_FALSE(IsAsciiPunct(' ')); + EXPECT_FALSE(IsAsciiPunct('\n')); + EXPECT_FALSE(IsAsciiPunct('a')); + EXPECT_FALSE(IsAsciiPunct('0')); } -TEST(IsPunctTest, IsTrueForPunct) { +TEST(IsAsciiPunctTest, IsTrueForPunct) { for (const char* p = "^-!\"#$%&'()*+,./:;<=>?@[\\]_`{|}~"; *p; p++) { - EXPECT_PRED1(IsPunct, *p); + EXPECT_PRED1(IsAsciiPunct, *p); } } @@ -421,47 +421,47 @@ TEST(IsRepeatTest, IsTrueForRepeatChar) { EXPECT_TRUE(IsRepeat('+')); } -TEST(IsWhiteSpaceTest, IsFalseForNonWhiteSpace) { - EXPECT_FALSE(IsWhiteSpace('\0')); - EXPECT_FALSE(IsWhiteSpace('a')); - EXPECT_FALSE(IsWhiteSpace('1')); - EXPECT_FALSE(IsWhiteSpace('+')); - EXPECT_FALSE(IsWhiteSpace('_')); +TEST(IsAsciiWhiteSpaceTest, IsFalseForNonWhiteSpace) { + EXPECT_FALSE(IsAsciiWhiteSpace('\0')); + EXPECT_FALSE(IsAsciiWhiteSpace('a')); + EXPECT_FALSE(IsAsciiWhiteSpace('1')); + EXPECT_FALSE(IsAsciiWhiteSpace('+')); + EXPECT_FALSE(IsAsciiWhiteSpace('_')); } -TEST(IsWhiteSpaceTest, IsTrueForWhiteSpace) { - EXPECT_TRUE(IsWhiteSpace(' ')); - EXPECT_TRUE(IsWhiteSpace('\n')); - EXPECT_TRUE(IsWhiteSpace('\r')); - EXPECT_TRUE(IsWhiteSpace('\t')); - EXPECT_TRUE(IsWhiteSpace('\v')); - EXPECT_TRUE(IsWhiteSpace('\f')); +TEST(IsAsciiWhiteSpaceTest, IsTrueForWhiteSpace) { + EXPECT_TRUE(IsAsciiWhiteSpace(' ')); + EXPECT_TRUE(IsAsciiWhiteSpace('\n')); + EXPECT_TRUE(IsAsciiWhiteSpace('\r')); + EXPECT_TRUE(IsAsciiWhiteSpace('\t')); + EXPECT_TRUE(IsAsciiWhiteSpace('\v')); + EXPECT_TRUE(IsAsciiWhiteSpace('\f')); } -TEST(IsWordCharTest, IsFalseForNonWordChar) { - EXPECT_FALSE(IsWordChar('\0')); - EXPECT_FALSE(IsWordChar('+')); - EXPECT_FALSE(IsWordChar('.')); - EXPECT_FALSE(IsWordChar(' ')); - EXPECT_FALSE(IsWordChar('\n')); +TEST(IsAsciiWordCharTest, IsFalseForNonWordChar) { + EXPECT_FALSE(IsAsciiWordChar('\0')); + EXPECT_FALSE(IsAsciiWordChar('+')); + EXPECT_FALSE(IsAsciiWordChar('.')); + EXPECT_FALSE(IsAsciiWordChar(' ')); + EXPECT_FALSE(IsAsciiWordChar('\n')); } -TEST(IsWordCharTest, IsTrueForLetter) { - EXPECT_TRUE(IsWordChar('a')); - EXPECT_TRUE(IsWordChar('b')); - EXPECT_TRUE(IsWordChar('A')); - EXPECT_TRUE(IsWordChar('Z')); +TEST(IsAsciiWordCharTest, IsTrueForLetter) { + EXPECT_TRUE(IsAsciiWordChar('a')); + EXPECT_TRUE(IsAsciiWordChar('b')); + EXPECT_TRUE(IsAsciiWordChar('A')); + EXPECT_TRUE(IsAsciiWordChar('Z')); } -TEST(IsWordCharTest, IsTrueForDigit) { - EXPECT_TRUE(IsWordChar('0')); - EXPECT_TRUE(IsWordChar('1')); - EXPECT_TRUE(IsWordChar('7')); - EXPECT_TRUE(IsWordChar('9')); +TEST(IsAsciiWordCharTest, IsTrueForDigit) { + EXPECT_TRUE(IsAsciiWordChar('0')); + EXPECT_TRUE(IsAsciiWordChar('1')); + EXPECT_TRUE(IsAsciiWordChar('7')); + EXPECT_TRUE(IsAsciiWordChar('9')); } -TEST(IsWordCharTest, IsTrueForUnderscore) { - EXPECT_TRUE(IsWordChar('_')); +TEST(IsAsciiWordCharTest, IsTrueForUnderscore) { + EXPECT_TRUE(IsAsciiWordChar('_')); } TEST(IsValidEscapeTest, IsFalseForNonPrintable) { diff --git a/test/gtest-printers_test.cc b/test/gtest-printers_test.cc index 5dec871c..ce72421f 100644 --- a/test/gtest-printers_test.cc +++ b/test/gtest-printers_test.cc @@ -817,7 +817,7 @@ TEST(PrintStlContainerTest, HashMultiSet) { std::vector numbers; for (size_t i = 0; i != result.length(); i++) { if (expected_pattern[i] == 'd') { - ASSERT_TRUE(isdigit(result[i]) != 0); + ASSERT_TRUE(isdigit(static_cast(result[i])) != 0); numbers.push_back(result[i] - '0'); } else { EXPECT_EQ(expected_pattern[i], result[i]) << " where result is " diff --git a/test/gtest_catch_exceptions_test.py b/test/gtest_catch_exceptions_test.py index c4d1756d..061c5c3d 100755 --- a/test/gtest_catch_exceptions_test.py +++ b/test/gtest_catch_exceptions_test.py @@ -43,6 +43,8 @@ import gtest_test_utils # Constants. LIST_TESTS_FLAG = '--gtest_list_tests' +CATCH_EXCEPTIONS_FLAG = '--gtest_catch_exceptions=1' +FILTER_FLAG='--gtest_filter' # Path to the gtest_catch_exceptions_ex_test_ binary, compiled with # exceptions enabled. @@ -59,10 +61,11 @@ TEST_LIST = gtest_test_utils.Subprocess([EXE_PATH, LIST_TESTS_FLAG]).output SUPPORTS_SEH_EXCEPTIONS = 'ThrowsSehException' in TEST_LIST if SUPPORTS_SEH_EXCEPTIONS: - BINARY_OUTPUT = gtest_test_utils.Subprocess([EXE_PATH]).output - -EX_BINARY_OUTPUT = gtest_test_utils.Subprocess([EX_EXE_PATH]).output + BINARY_OUTPUT = gtest_test_utils.Subprocess([EXE_PATH, + CATCH_EXCEPTIONS_FLAG]).output +EX_BINARY_OUTPUT = gtest_test_utils.Subprocess([EX_EXE_PATH, + CATCH_EXCEPTIONS_FLAG]).output # The tests. if SUPPORTS_SEH_EXCEPTIONS: @@ -199,5 +202,18 @@ class CatchCxxExceptionsTest(gtest_test_utils.TestCase): self.assert_('Unknown C++ exception thrown in the test body' in EX_BINARY_OUTPUT) + def testUnhandledCxxExceptionsAbortTheProgram(self): + # Filters out SEH exception tests on Windows. Unhandled SEH exceptions + # cause tests to show pop-up windows there. + FITLER_OUT_SEH_TESTS_FLAG = FILTER_FLAG + '=-*Seh*' + # By default, Google Test doesn't catch the exceptions. + uncaught_exceptions_ex_binary_output = gtest_test_utils.Subprocess( + [EX_EXE_PATH, FITLER_OUT_SEH_TESTS_FLAG]).output + + self.assert_('Unhandled C++ exception terminating the program' + in uncaught_exceptions_ex_binary_output) + self.assert_('unexpected' not in uncaught_exceptions_ex_binary_output) + + if __name__ == '__main__': gtest_test_utils.Main() diff --git a/test/gtest_catch_exceptions_test_.cc b/test/gtest_catch_exceptions_test_.cc index 86736811..2ba6eb44 100644 --- a/test/gtest_catch_exceptions_test_.cc +++ b/test/gtest_catch_exceptions_test_.cc @@ -35,17 +35,18 @@ #include #include // NOLINT +#include // For exit(). #if GTEST_HAS_SEH #include #endif #if GTEST_HAS_EXCEPTIONS +#include // For set_terminate(). #include #endif using testing::Test; -using testing::GTEST_FLAG(catch_exceptions); #if GTEST_HAS_SEH @@ -287,12 +288,20 @@ TEST(CxxExceptionTest, ThrowsNonStdCxxException) { throw "C-string"; } +// This terminate handler aborts the program using exit() rather than abort(). +// This avoids showing pop-ups on Windows systems and core dumps on Unix-like +// ones. +void TerminateHandler() { + fprintf(stderr, "%s\n", "Unhandled C++ exception terminating the program."); + fflush(NULL); + exit(3); +} + #endif // GTEST_HAS_EXCEPTIONS int main(int argc, char** argv) { -#if GTEST_HAS_SEH - // Tells Google Test to catch SEH-style exceptions on Windows. - GTEST_FLAG(catch_exceptions) = true; +#if GTEST_HAS_EXCEPTIONS + std::set_terminate(&TerminateHandler); #endif testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index d993c048..d7092495 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -193,19 +193,15 @@ using testing::internal::kReference; using testing::internal::kTestTypeIdInGoogleTest; using testing::internal::scoped_ptr; -#if GTEST_HAS_STREAM_REDIRECTION_ +#if GTEST_HAS_STREAM_REDIRECTION using testing::internal::CaptureStdout; using testing::internal::GetCapturedStdout; -#endif // GTEST_HAS_STREAM_REDIRECTION_ +#endif #if GTEST_IS_THREADSAFE using testing::internal::ThreadWithParam; #endif -#if GTEST_HAS_PROTOBUF_ -using ::testing::internal::TestMessage; -#endif // GTEST_HAS_PROTOBUF_ - class TestingVector : public std::vector { }; @@ -5343,16 +5339,16 @@ class InitGoogleTestTest : public Test { const bool saved_help_flag = ::testing::internal::g_help_flag; ::testing::internal::g_help_flag = false; -#if GTEST_HAS_STREAM_REDIRECTION_ +#if GTEST_HAS_STREAM_REDIRECTION CaptureStdout(); -#endif // GTEST_HAS_STREAM_REDIRECTION_ +#endif // Parses the command line. internal::ParseGoogleTestFlagsOnly(&argc1, const_cast(argv1)); -#if GTEST_HAS_STREAM_REDIRECTION_ +#if GTEST_HAS_STREAM_REDIRECTION const String captured_stdout = GetCapturedStdout(); -#endif // GTEST_HAS_STREAM_REDIRECTION_ +#endif // Verifies the flag values. CheckFlags(expected); @@ -5365,7 +5361,7 @@ class InitGoogleTestTest : public Test { // help message for the flags it recognizes. EXPECT_EQ(should_print_help, ::testing::internal::g_help_flag); -#if GTEST_HAS_STREAM_REDIRECTION_ +#if GTEST_HAS_STREAM_REDIRECTION const char* const expected_help_fragment = "This program contains tests written using"; if (should_print_help) { @@ -5374,7 +5370,7 @@ class InitGoogleTestTest : public Test { EXPECT_PRED_FORMAT2(IsNotSubstring, expected_help_fragment, captured_stdout); } -#endif // GTEST_HAS_STREAM_REDIRECTION_ +#endif // GTEST_HAS_STREAM_REDIRECTION ::testing::internal::g_help_flag = saved_help_flag; } @@ -6887,13 +6883,10 @@ TEST(IsAProtocolMessageTest, ValueIsCompileTimeConstant) { } // Tests that IsAProtocolMessage::value is true when T is -// ProtocolMessage or a sub-class of it. +// proto2::Message or a sub-class of it. TEST(IsAProtocolMessageTest, ValueIsTrueWhenTypeIsAProtocolMessage) { EXPECT_TRUE(IsAProtocolMessage< ::proto2::Message>::value); EXPECT_TRUE(IsAProtocolMessage::value); -#if GTEST_HAS_PROTOBUF_ - EXPECT_TRUE(IsAProtocolMessage::value); -#endif // GTEST_HAS_PROTOBUF_ } // Tests that IsAProtocolMessage::value is false when T is neither -- cgit v1.2.3 From 88e0df62470fa82e8d3010ef88241cd7565ebe9e Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Wed, 8 Sep 2010 05:57:37 +0000 Subject: Removes all uses of StrStream; fixes the VC projects and simplifies them by using gtest-all.cc. --- test/gtest-message_test.cc | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'test') diff --git a/test/gtest-message_test.cc b/test/gtest-message_test.cc index e42b0344..efb6ff08 100644 --- a/test/gtest-message_test.cc +++ b/test/gtest-message_test.cc @@ -38,7 +38,6 @@ namespace { using ::testing::Message; -using ::testing::internal::StrStream; // A helper function that turns a Message into a C string. const char* ToCString(const Message& msg) { @@ -154,9 +153,9 @@ TEST(MessageTest, GetString) { // Tests streaming a Message object to an ostream. TEST(MessageTest, StreamsToOStream) { Message msg("Hello"); - StrStream ss; + ::std::stringstream ss; ss << msg; - EXPECT_STREQ("Hello", testing::internal::StrStreamToString(&ss).c_str()); + EXPECT_STREQ("Hello", testing::internal::StringStreamToString(&ss).c_str()); } // Tests that a Message object doesn't take up too much stack space. -- cgit v1.2.3 From dac3e879c56a50696a36f53e1e5e353e48fa665f Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Tue, 14 Sep 2010 05:35:59 +0000 Subject: Include gtest headers as user headers instead of system headers. --- test/gtest-death-test_test.cc | 8 ++++---- test/gtest-filepath_test.cc | 4 ++-- test/gtest-linked_ptr_test.cc | 4 ++-- test/gtest-listener_test.cc | 2 +- test/gtest-message_test.cc | 4 ++-- test/gtest-options_test.cc | 2 +- test/gtest-param-test2_test.cc | 2 +- test/gtest-param-test_test.cc | 2 +- test/gtest-param-test_test.h | 2 +- test/gtest-port_test.cc | 6 +++--- test/gtest-printers_test.cc | 4 ++-- test/gtest-test-part_test.cc | 4 ++-- test/gtest-tuple_test.cc | 4 ++-- test/gtest-typed-test2_test.cc | 2 +- test/gtest-typed-test_test.cc | 2 +- test/gtest-typed-test_test.h | 2 +- test/gtest-unittest-api_test.cc | 2 +- test/gtest_break_on_failure_unittest_.cc | 2 +- test/gtest_catch_exceptions_test_.cc | 2 +- test/gtest_color_test_.cc | 2 +- test/gtest_env_var_test_.cc | 2 +- test/gtest_environment_test.cc | 2 +- test/gtest_filter_unittest_.cc | 2 +- test/gtest_help_test_.cc | 2 +- test/gtest_list_tests_unittest_.cc | 2 +- test/gtest_main_unittest.cc | 2 +- test/gtest_nc.cc | 28 ++++++++++++++-------------- test/gtest_no_test_unittest.cc | 2 +- test/gtest_output_test_.cc | 4 ++-- test/gtest_pred_impl_unittest.cc | 4 ++-- test/gtest_prod_test.cc | 2 +- test/gtest_repeat_test.cc | 2 +- test/gtest_shuffle_test_.cc | 2 +- test/gtest_sole_header_test.cc | 2 +- test/gtest_stress_test.cc | 2 +- test/gtest_throw_on_failure_ex_test.cc | 2 +- test/gtest_throw_on_failure_test_.cc | 2 +- test/gtest_uninitialized_test_.cc | 2 +- test/gtest_unittest.cc | 4 ++-- test/gtest_xml_outfile1_test_.cc | 2 +- test/gtest_xml_outfile2_test_.cc | 2 +- test/gtest_xml_output_unittest_.cc | 2 +- test/production.h | 2 +- 43 files changed, 70 insertions(+), 70 deletions(-) (limited to 'test') diff --git a/test/gtest-death-test_test.cc b/test/gtest-death-test_test.cc index d33cfeb7..6144f2db 100644 --- a/test/gtest-death-test_test.cc +++ b/test/gtest-death-test_test.cc @@ -31,9 +31,9 @@ // // Tests for death tests. -#include -#include -#include +#include "gtest/gtest-death-test.h" +#include "gtest/gtest.h" +#include "gtest/internal/gtest-filepath.h" using testing::internal::AlwaysFalse; using testing::internal::AlwaysTrue; @@ -52,7 +52,7 @@ using testing::internal::AlwaysTrue; #include #include -#include +#include "gtest/gtest-spi.h" // Indicates that this translation unit is part of Google Test's // implementation. It must come before gtest-internal-inl.h is diff --git a/test/gtest-filepath_test.cc b/test/gtest-filepath_test.cc index 62502827..549dcef2 100644 --- a/test/gtest-filepath_test.cc +++ b/test/gtest-filepath_test.cc @@ -38,8 +38,8 @@ // build or make-files for some existing Google Test clients. Do not // #include this file anywhere else! -#include -#include +#include "gtest/internal/gtest-filepath.h" +#include "gtest/gtest.h" // Indicates that this translation unit is part of Google Test's // implementation. It must come before gtest-internal-inl.h is diff --git a/test/gtest-linked_ptr_test.cc b/test/gtest-linked_ptr_test.cc index eae82296..efd6b1ed 100644 --- a/test/gtest-linked_ptr_test.cc +++ b/test/gtest-linked_ptr_test.cc @@ -30,10 +30,10 @@ // Authors: Dan Egnor (egnor@google.com) // Ported to Windows: Vadim Berman (vadimb@google.com) -#include +#include "gtest/internal/gtest-linked_ptr.h" #include -#include +#include "gtest/gtest.h" namespace { diff --git a/test/gtest-listener_test.cc b/test/gtest-listener_test.cc index c9be39a8..2aa08ef3 100644 --- a/test/gtest-listener_test.cc +++ b/test/gtest-listener_test.cc @@ -33,7 +33,7 @@ // This file verifies Google Test event listeners receive events at the // right times. -#include +#include "gtest/gtest.h" #include using ::testing::AddGlobalTestEnvironment; diff --git a/test/gtest-message_test.cc b/test/gtest-message_test.cc index efb6ff08..c09c6a83 100644 --- a/test/gtest-message_test.cc +++ b/test/gtest-message_test.cc @@ -31,9 +31,9 @@ // // Tests for the Message class. -#include +#include "gtest/gtest-message.h" -#include +#include "gtest/gtest.h" namespace { diff --git a/test/gtest-options_test.cc b/test/gtest-options_test.cc index 2e2cbc92..30b82f3f 100644 --- a/test/gtest-options_test.cc +++ b/test/gtest-options_test.cc @@ -38,7 +38,7 @@ // make-files on Windows and other platforms. Do not #include this file // anywhere else! -#include +#include "gtest/gtest.h" #if GTEST_OS_WINDOWS_MOBILE #include diff --git a/test/gtest-param-test2_test.cc b/test/gtest-param-test2_test.cc index ccb6cfac..4a782fe7 100644 --- a/test/gtest-param-test2_test.cc +++ b/test/gtest-param-test2_test.cc @@ -32,7 +32,7 @@ // Tests for Google Test itself. This verifies that the basic constructs of // Google Test work. -#include +#include "gtest/gtest.h" #include "test/gtest-param-test_test.h" diff --git a/test/gtest-param-test_test.cc b/test/gtest-param-test_test.cc index 26acce4c..c920f4fd 100644 --- a/test/gtest-param-test_test.cc +++ b/test/gtest-param-test_test.cc @@ -33,7 +33,7 @@ // generators objects produce correct parameter sequences and that // Google Test runtime instantiates correct tests from those sequences. -#include +#include "gtest/gtest.h" #if GTEST_HAS_PARAM_TEST diff --git a/test/gtest-param-test_test.h b/test/gtest-param-test_test.h index b7f94936..d0f6556b 100644 --- a/test/gtest-param-test_test.h +++ b/test/gtest-param-test_test.h @@ -37,7 +37,7 @@ #ifndef GTEST_TEST_GTEST_PARAM_TEST_TEST_H_ #define GTEST_TEST_GTEST_PARAM_TEST_TEST_H_ -#include +#include "gtest/gtest.h" #if GTEST_HAS_PARAM_TEST diff --git a/test/gtest-port_test.cc b/test/gtest-port_test.cc index e08afe8e..bf42d8b8 100644 --- a/test/gtest-port_test.cc +++ b/test/gtest-port_test.cc @@ -31,7 +31,7 @@ // // This file tests the internal cross-platform support utilities. -#include +#include "gtest/internal/gtest-port.h" #include @@ -41,8 +41,8 @@ #include // For std::pair and std::make_pair. -#include -#include +#include "gtest/gtest.h" +#include "gtest/gtest-spi.h" // Indicates that this translation unit is part of Google Test's // implementation. It must come before gtest-internal-inl.h is diff --git a/test/gtest-printers_test.cc b/test/gtest-printers_test.cc index ce72421f..16fe9249 100644 --- a/test/gtest-printers_test.cc +++ b/test/gtest-printers_test.cc @@ -33,7 +33,7 @@ // // This file tests the universal value printer. -#include +#include "gtest/gtest-printers.h" #include #include @@ -48,7 +48,7 @@ #include #include -#include +#include "gtest/gtest.h" // hash_map and hash_set are available on Windows. #if GTEST_OS_WINDOWS diff --git a/test/gtest-test-part_test.cc b/test/gtest-test-part_test.cc index 5a3e9196..ca8ba933 100644 --- a/test/gtest-test-part_test.cc +++ b/test/gtest-test-part_test.cc @@ -30,9 +30,9 @@ // Author: mheule@google.com (Markus Heule) // -#include +#include "gtest/gtest-test-part.h" -#include +#include "gtest/gtest.h" using testing::Message; using testing::Test; diff --git a/test/gtest-tuple_test.cc b/test/gtest-tuple_test.cc index 532f70b3..bfaa3e0a 100644 --- a/test/gtest-tuple_test.cc +++ b/test/gtest-tuple_test.cc @@ -29,9 +29,9 @@ // // Author: wan@google.com (Zhanyong Wan) -#include +#include "gtest/internal/gtest-tuple.h" #include -#include +#include "gtest/gtest.h" namespace { diff --git a/test/gtest-typed-test2_test.cc b/test/gtest-typed-test2_test.cc index 79a8a87d..c284700b 100644 --- a/test/gtest-typed-test2_test.cc +++ b/test/gtest-typed-test2_test.cc @@ -32,7 +32,7 @@ #include #include "test/gtest-typed-test_test.h" -#include +#include "gtest/gtest.h" #if GTEST_HAS_TYPED_TEST_P diff --git a/test/gtest-typed-test_test.cc b/test/gtest-typed-test_test.cc index f2c39723..dd4ba43b 100644 --- a/test/gtest-typed-test_test.cc +++ b/test/gtest-typed-test_test.cc @@ -33,7 +33,7 @@ #include #include "test/gtest-typed-test_test.h" -#include +#include "gtest/gtest.h" using testing::Test; diff --git a/test/gtest-typed-test_test.h b/test/gtest-typed-test_test.h index 40dfeac6..41d75704 100644 --- a/test/gtest-typed-test_test.h +++ b/test/gtest-typed-test_test.h @@ -32,7 +32,7 @@ #ifndef GTEST_TEST_GTEST_TYPED_TEST_TEST_H_ #define GTEST_TEST_GTEST_TYPED_TEST_TEST_H_ -#include +#include "gtest/gtest.h" #if GTEST_HAS_TYPED_TEST_P diff --git a/test/gtest-unittest-api_test.cc b/test/gtest-unittest-api_test.cc index 7e0f8f80..ed5dea83 100644 --- a/test/gtest-unittest-api_test.cc +++ b/test/gtest-unittest-api_test.cc @@ -33,7 +33,7 @@ // This file contains tests verifying correctness of data provided via // UnitTest's public methods. -#include +#include "gtest/gtest.h" #include // For strcmp. #include diff --git a/test/gtest_break_on_failure_unittest_.cc b/test/gtest_break_on_failure_unittest_.cc index 6779c903..30755090 100644 --- a/test/gtest_break_on_failure_unittest_.cc +++ b/test/gtest_break_on_failure_unittest_.cc @@ -39,7 +39,7 @@ // This program will be invoked from a Python unit test. It is // expected to fail. Don't run it directly. -#include +#include "gtest/gtest.h" #if GTEST_OS_WINDOWS #include diff --git a/test/gtest_catch_exceptions_test_.cc b/test/gtest_catch_exceptions_test_.cc index 2ba6eb44..3cf75321 100644 --- a/test/gtest_catch_exceptions_test_.cc +++ b/test/gtest_catch_exceptions_test_.cc @@ -32,7 +32,7 @@ // Tests for Google Test itself. Tests in this file throw C++ or SEH // exceptions, and the output is verified by gtest_catch_exceptions_test.py. -#include +#include "gtest/gtest.h" #include // NOLINT #include // For exit(). diff --git a/test/gtest_color_test_.cc b/test/gtest_color_test_.cc index 58d377c9..f61ebb89 100644 --- a/test/gtest_color_test_.cc +++ b/test/gtest_color_test_.cc @@ -35,7 +35,7 @@ #include -#include +#include "gtest/gtest.h" // Indicates that this translation unit is part of Google Test's // implementation. It must come before gtest-internal-inl.h is diff --git a/test/gtest_env_var_test_.cc b/test/gtest_env_var_test_.cc index f7c78fcf..539afc96 100644 --- a/test/gtest_env_var_test_.cc +++ b/test/gtest_env_var_test_.cc @@ -32,7 +32,7 @@ // A helper program for testing that Google Test parses the environment // variables correctly. -#include +#include "gtest/gtest.h" #include diff --git a/test/gtest_environment_test.cc b/test/gtest_environment_test.cc index 94ea318b..744b405e 100644 --- a/test/gtest_environment_test.cc +++ b/test/gtest_environment_test.cc @@ -33,7 +33,7 @@ #include #include -#include +#include "gtest/gtest.h" #define GTEST_IMPLEMENTATION_ 1 // Required for the next #include. #include "src/gtest-internal-inl.h" diff --git a/test/gtest_filter_unittest_.cc b/test/gtest_filter_unittest_.cc index 325504fe..77deffc3 100644 --- a/test/gtest_filter_unittest_.cc +++ b/test/gtest_filter_unittest_.cc @@ -38,7 +38,7 @@ // The program will be invoked from a Python unit test. Don't run it // directly. -#include +#include "gtest/gtest.h" namespace { diff --git a/test/gtest_help_test_.cc b/test/gtest_help_test_.cc index aad0d72d..31f78c24 100644 --- a/test/gtest_help_test_.cc +++ b/test/gtest_help_test_.cc @@ -32,7 +32,7 @@ // This program is meant to be run by gtest_help_test.py. Do not run // it directly. -#include +#include "gtest/gtest.h" // When a help flag is specified, this program should skip the tests // and exit with 0; otherwise the following test will be executed, diff --git a/test/gtest_list_tests_unittest_.cc b/test/gtest_list_tests_unittest_.cc index a0ed0825..2b1d0780 100644 --- a/test/gtest_list_tests_unittest_.cc +++ b/test/gtest_list_tests_unittest_.cc @@ -38,7 +38,7 @@ // This program will be invoked from a Python unit test. // Don't run it directly. -#include +#include "gtest/gtest.h" namespace { diff --git a/test/gtest_main_unittest.cc b/test/gtest_main_unittest.cc index 7a3f0adf..ecd9bb87 100644 --- a/test/gtest_main_unittest.cc +++ b/test/gtest_main_unittest.cc @@ -29,7 +29,7 @@ // // Author: wan@google.com (Zhanyong Wan) -#include +#include "gtest/gtest.h" // Tests that we don't have to define main() when we link to // gtest_main instead of gtest. diff --git a/test/gtest_nc.cc b/test/gtest_nc.cc index 73b5db6d..71acf2bd 100644 --- a/test/gtest_nc.cc +++ b/test/gtest_nc.cc @@ -42,7 +42,7 @@ #ifdef TEST_CANNOT_IGNORE_RUN_ALL_TESTS_RESULT // Tests that the result of RUN_ALL_TESTS() cannot be ignored. -#include +#include "gtest/gtest.h" int main(int argc, char** argv) { testing::InitGoogleTest(&argc, argv); @@ -58,7 +58,7 @@ int main(int argc, char** argv) { // Tests that the compiler catches the typo when a user declares a // Setup() method in a test fixture. -#include +#include "gtest/gtest.h" class MyTest : public testing::Test { protected: @@ -69,7 +69,7 @@ class MyTest : public testing::Test { // Tests that the compiler catches the typo when a user calls Setup() // from a test fixture. -#include +#include "gtest/gtest.h" class MyTest : public testing::Test { protected: @@ -82,7 +82,7 @@ class MyTest : public testing::Test { // Tests that the compiler catches the typo when a user declares a // Setup() method in a subclass of Environment. -#include +#include "gtest/gtest.h" class MyEnvironment : public testing::Environment { public: @@ -93,7 +93,7 @@ class MyEnvironment : public testing::Environment { // Tests that the compiler catches the typo when a user calls Setup() // in an Environment. -#include +#include "gtest/gtest.h" class MyEnvironment : public testing::Environment { protected: @@ -107,7 +107,7 @@ class MyEnvironment : public testing::Environment { // Tests that the compiler catches using the wrong test case name in // TYPED_TEST_P. -#include +#include "gtest/gtest.h" template class FooTest : public testing::Test { @@ -126,7 +126,7 @@ INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, testing::Types); // Tests that the compiler catches using the wrong test case name in // REGISTER_TYPED_TEST_CASE_P. -#include +#include "gtest/gtest.h" template class FooTest : public testing::Test { @@ -145,7 +145,7 @@ INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, testing::Types); // Tests that the compiler catches using the wrong test case name in // INSTANTIATE_TYPED_TEST_CASE_P. -#include +#include "gtest/gtest.h" template class FooTest : public testing::Test { @@ -166,7 +166,7 @@ INSTANTIATE_TYPED_TEST_CASE_P(My, BarTest, testing::Types); // Tests that the compiler catches instantiating TYPED_TEST_CASE_P // twice with the same name prefix. -#include +#include "gtest/gtest.h" template class FooTest : public testing::Test { @@ -183,21 +183,21 @@ INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, testing::Types); #elif defined(TEST_STATIC_ASSERT_TYPE_EQ_IS_NOT_A_TYPE) -#include +#include "gtest/gtest.h" // Tests that StaticAssertTypeEq cannot be used as a type. testing::StaticAssertTypeEq dummy; #elif defined(TEST_STATIC_ASSERT_TYPE_EQ_WORKS_IN_NAMESPACE) -#include +#include "gtest/gtest.h" // Tests that StaticAssertTypeEq works in a namespace scope. static bool dummy = testing::StaticAssertTypeEq(); #elif defined(TEST_STATIC_ASSERT_TYPE_EQ_WORKS_IN_CLASS) -#include +#include "gtest/gtest.h" template class Helper { @@ -215,7 +215,7 @@ void Test() { #elif defined(TEST_STATIC_ASSERT_TYPE_EQ_WORKS_IN_FUNCTION) -#include +#include "gtest/gtest.h" void Test() { // Tests that StaticAssertTypeEq works inside a function. @@ -225,7 +225,7 @@ void Test() { #else // A sanity test. This should compile. -#include +#include "gtest/gtest.h" int main() { return RUN_ALL_TESTS(); diff --git a/test/gtest_no_test_unittest.cc b/test/gtest_no_test_unittest.cc index e09ca73a..e3a85f12 100644 --- a/test/gtest_no_test_unittest.cc +++ b/test/gtest_no_test_unittest.cc @@ -32,7 +32,7 @@ // // Author: wan@google.com (Zhanyong Wan) -#include +#include "gtest/gtest.h" int main(int argc, char **argv) { diff --git a/test/gtest_output_test_.cc b/test/gtest_output_test_.cc index fc80fac3..47343e50 100644 --- a/test/gtest_output_test_.cc +++ b/test/gtest_output_test_.cc @@ -32,8 +32,8 @@ // // Author: wan@google.com (Zhanyong Wan) -#include -#include +#include "gtest/gtest-spi.h" +#include "gtest/gtest.h" // Indicates that this translation unit is part of Google Test's // implementation. It must come before gtest-internal-inl.h is diff --git a/test/gtest_pred_impl_unittest.cc b/test/gtest_pred_impl_unittest.cc index e7ee54b5..66c75d17 100644 --- a/test/gtest_pred_impl_unittest.cc +++ b/test/gtest_pred_impl_unittest.cc @@ -49,8 +49,8 @@ #include -#include -#include +#include "gtest/gtest.h" +#include "gtest/gtest-spi.h" // A user-defined data type. struct Bool { diff --git a/test/gtest_prod_test.cc b/test/gtest_prod_test.cc index bc3201d0..060abce1 100644 --- a/test/gtest_prod_test.cc +++ b/test/gtest_prod_test.cc @@ -31,7 +31,7 @@ // // Unit test for include/gtest/gtest_prod.h. -#include +#include "gtest/gtest.h" #include "test/production.h" // Tests that private members can be accessed from a TEST declared as diff --git a/test/gtest_repeat_test.cc b/test/gtest_repeat_test.cc index df6868b8..ff9063a4 100644 --- a/test/gtest_repeat_test.cc +++ b/test/gtest_repeat_test.cc @@ -33,7 +33,7 @@ #include #include -#include +#include "gtest/gtest.h" // Indicates that this translation unit is part of Google Test's // implementation. It must come before gtest-internal-inl.h is diff --git a/test/gtest_shuffle_test_.cc b/test/gtest_shuffle_test_.cc index 53ecf777..0752789e 100644 --- a/test/gtest_shuffle_test_.cc +++ b/test/gtest_shuffle_test_.cc @@ -31,7 +31,7 @@ // Verifies that test shuffling works. -#include +#include "gtest/gtest.h" namespace { diff --git a/test/gtest_sole_header_test.cc b/test/gtest_sole_header_test.cc index de91e800..ccd091a2 100644 --- a/test/gtest_sole_header_test.cc +++ b/test/gtest_sole_header_test.cc @@ -32,7 +32,7 @@ // This test verifies that it's possible to use Google Test by including // the gtest.h header file alone. -#include +#include "gtest/gtest.h" namespace { diff --git a/test/gtest_stress_test.cc b/test/gtest_stress_test.cc index f5af78cc..4e7d9bff 100644 --- a/test/gtest_stress_test.cc +++ b/test/gtest_stress_test.cc @@ -32,7 +32,7 @@ // Tests that SCOPED_TRACE() and various Google Test assertions can be // used in a large number of threads concurrently. -#include +#include "gtest/gtest.h" #include #include diff --git a/test/gtest_throw_on_failure_ex_test.cc b/test/gtest_throw_on_failure_ex_test.cc index 8bf9dc90..8d46c76f 100644 --- a/test/gtest_throw_on_failure_ex_test.cc +++ b/test/gtest_throw_on_failure_ex_test.cc @@ -31,7 +31,7 @@ // Tests Google Test's throw-on-failure mode with exceptions enabled. -#include +#include "gtest/gtest.h" #include #include diff --git a/test/gtest_throw_on_failure_test_.cc b/test/gtest_throw_on_failure_test_.cc index 88fbd5a7..03776ecb 100644 --- a/test/gtest_throw_on_failure_test_.cc +++ b/test/gtest_throw_on_failure_test_.cc @@ -35,7 +35,7 @@ // invoked by gtest_throw_on_failure_test.py, and is expected to exit // with non-zero in the throw-on-failure mode or 0 otherwise. -#include +#include "gtest/gtest.h" int main(int argc, char** argv) { testing::InitGoogleTest(&argc, argv); diff --git a/test/gtest_uninitialized_test_.cc b/test/gtest_uninitialized_test_.cc index e8b2aa81..44316987 100644 --- a/test/gtest_uninitialized_test_.cc +++ b/test/gtest_uninitialized_test_.cc @@ -29,7 +29,7 @@ // // Author: wan@google.com (Zhanyong Wan) -#include +#include "gtest/gtest.h" TEST(DummyTest, Dummy) { // This test doesn't verify anything. We just need it to create a diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index d7092495..5eaa2af6 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -32,7 +32,7 @@ // Tests for Google Test itself. This verifies that the basic constructs of // Google Test work. -#include +#include "gtest/gtest.h" #include // Verifies that the command line flag variables can be accessed @@ -57,7 +57,7 @@ TEST(CommandLineFlagsTest, CanBeAccessedInCodeOnceGTestHIsIncluded) { EXPECT_TRUE(dummy || !dummy); // Suppresses warning that dummy is unused. } -#include +#include "gtest/gtest-spi.h" // Indicates that this translation unit is part of Google Test's // implementation. It must come before gtest-internal-inl.h is diff --git a/test/gtest_xml_outfile1_test_.cc b/test/gtest_xml_outfile1_test_.cc index 664baad2..531ced49 100644 --- a/test/gtest_xml_outfile1_test_.cc +++ b/test/gtest_xml_outfile1_test_.cc @@ -32,7 +32,7 @@ // gtest_xml_outfile1_test_ writes some xml via TestProperty used by // gtest_xml_outfiles_test.py -#include +#include "gtest/gtest.h" class PropertyOne : public testing::Test { protected: diff --git a/test/gtest_xml_outfile2_test_.cc b/test/gtest_xml_outfile2_test_.cc index 3411a3d3..7b400b27 100644 --- a/test/gtest_xml_outfile2_test_.cc +++ b/test/gtest_xml_outfile2_test_.cc @@ -32,7 +32,7 @@ // gtest_xml_outfile2_test_ writes some xml via TestProperty used by // gtest_xml_outfiles_test.py -#include +#include "gtest/gtest.h" class PropertyTwo : public testing::Test { protected: diff --git a/test/gtest_xml_output_unittest_.cc b/test/gtest_xml_output_unittest_.cc index fc07ef46..693ffb99 100644 --- a/test/gtest_xml_output_unittest_.cc +++ b/test/gtest_xml_output_unittest_.cc @@ -38,7 +38,7 @@ // This program will be invoked from a Python unit test. Don't run it // directly. -#include +#include "gtest/gtest.h" using ::testing::InitGoogleTest; using ::testing::TestEventListeners; diff --git a/test/production.h b/test/production.h index 8f16fffa..98fd5e47 100644 --- a/test/production.h +++ b/test/production.h @@ -34,7 +34,7 @@ #ifndef GTEST_TEST_PRODUCTION_H_ #define GTEST_TEST_PRODUCTION_H_ -#include +#include "gtest/gtest_prod.h" class PrivateCode { public: -- cgit v1.2.3 From 345d9ebf30ccc2747c4e4c224b95fd8406093e29 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Wed, 15 Sep 2010 04:56:58 +0000 Subject: Implements GTEST_ASSERT_XY as alias of ASSERT_XY. --- test/gtest_unittest.cc | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) (limited to 'test') diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index 5eaa2af6..8e3e7e60 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -6866,6 +6866,41 @@ GTEST_TEST(AlternativeNameTest, Works) { // GTEST_TEST is the same as TEST. // GTEST_FAIL is the same as FAIL. EXPECT_FATAL_FAILURE(GTEST_FAIL() << "An expected failure", "An expected failure"); + + // GTEST_ASSERT_XY is the same as ASSERT_XY. + + GTEST_ASSERT_EQ(0, 0); + EXPECT_FATAL_FAILURE(GTEST_ASSERT_EQ(0, 1) << "An expected failure", + "An expected failure"); + EXPECT_FATAL_FAILURE(GTEST_ASSERT_EQ(1, 0) << "An expected failure", + "An expected failure"); + + GTEST_ASSERT_NE(0, 1); + GTEST_ASSERT_NE(1, 0); + EXPECT_FATAL_FAILURE(GTEST_ASSERT_NE(0, 0) << "An expected failure", + "An expected failure"); + + GTEST_ASSERT_LE(0, 0); + GTEST_ASSERT_LE(0, 1); + EXPECT_FATAL_FAILURE(GTEST_ASSERT_LE(1, 0) << "An expected failure", + "An expected failure"); + + GTEST_ASSERT_LT(0, 1); + EXPECT_FATAL_FAILURE(GTEST_ASSERT_LT(0, 0) << "An expected failure", + "An expected failure"); + EXPECT_FATAL_FAILURE(GTEST_ASSERT_LT(1, 0) << "An expected failure", + "An expected failure"); + + GTEST_ASSERT_GE(0, 0); + GTEST_ASSERT_GE(1, 0); + EXPECT_FATAL_FAILURE(GTEST_ASSERT_GE(0, 1) << "An expected failure", + "An expected failure"); + + GTEST_ASSERT_GT(1, 0); + EXPECT_FATAL_FAILURE(GTEST_ASSERT_GT(0, 1) << "An expected failure", + "An expected failure"); + EXPECT_FATAL_FAILURE(GTEST_ASSERT_GT(1, 1) << "An expected failure", + "An expected failure"); } // Tests for internal utilities necessary for implementation of the universal -- cgit v1.2.3 From b5d3a17805fe0ed2ccde463412ae1fd206c4df21 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Mon, 27 Sep 2010 17:42:52 +0000 Subject: Allows EXPECT_FATAL_FAILURE() and friends to accept a string object as the second argument. --- test/gtest_unittest.cc | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'test') diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index 8e3e7e60..056064fa 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -1335,6 +1335,17 @@ TEST_F(ExpectFatalFailureTest, CatchesFatalFaliure) { EXPECT_FATAL_FAILURE(AddFatalFailure(), "Expected fatal failure."); } +#if GTEST_HAS_GLOBAL_STRING +TEST_F(ExpectFatalFailureTest, AcceptsStringObject) { + EXPECT_FATAL_FAILURE(AddFatalFailure(), ::string("Expected fatal failure.")); +} +#endif + +TEST_F(ExpectFatalFailureTest, AcceptsStdStringObject) { + EXPECT_FATAL_FAILURE(AddFatalFailure(), + ::std::string("Expected fatal failure.")); +} + TEST_F(ExpectFatalFailureTest, CatchesFatalFailureOnAllThreads) { // We have another test below to verify that the macro catches fatal // failures generated on another thread. @@ -1412,6 +1423,18 @@ TEST_F(ExpectNonfatalFailureTest, CatchesNonfatalFailure) { "Expected non-fatal failure."); } +#if GTEST_HAS_GLOBAL_STRING +TEST_F(ExpectNonfatalFailureTest, AcceptsStringObject) { + EXPECT_NONFATAL_FAILURE(AddNonfatalFailure(), + ::string("Expected non-fatal failure.")); +} +#endif + +TEST_F(ExpectNonfatalFailureTest, AcceptsStdStringObject) { + EXPECT_NONFATAL_FAILURE(AddNonfatalFailure(), + ::std::string("Expected non-fatal failure.")); +} + TEST_F(ExpectNonfatalFailureTest, CatchesNonfatalFailureOnAllThreads) { // We have another test below to verify that the macro catches // non-fatal failures generated on another thread. -- cgit v1.2.3 From 2d1835b086e69570e4c3e0ad6197da509bd0a957 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Mon, 27 Sep 2010 22:09:42 +0000 Subject: Removes uses of deprecated AssertionFailure() API (by Vlad Losev). --- test/gtest_pred_impl_unittest.cc | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-) (limited to 'test') diff --git a/test/gtest_pred_impl_unittest.cc b/test/gtest_pred_impl_unittest.cc index 66c75d17..35dc9bcf 100644 --- a/test/gtest_pred_impl_unittest.cc +++ b/test/gtest_pred_impl_unittest.cc @@ -27,7 +27,7 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// This file is AUTOMATICALLY GENERATED on 10/02/2008 by command +// This file is AUTOMATICALLY GENERATED on 09/24/2010 by command // 'gen_gtest_pred_impl.py 5'. DO NOT EDIT BY HAND! // Regression test for gtest_pred_impl.h @@ -103,11 +103,10 @@ testing::AssertionResult PredFormatFunction1(const char* e1, if (PredFunction1(v1)) return testing::AssertionSuccess(); - testing::Message msg; - msg << e1 + return testing::AssertionFailure() + << e1 << " is expected to be positive, but evaluates to " << v1 << "."; - return testing::AssertionFailure(msg); } // A unary predicate-formatter functor. @@ -494,11 +493,10 @@ testing::AssertionResult PredFormatFunction2(const char* e1, if (PredFunction2(v1, v2)) return testing::AssertionSuccess(); - testing::Message msg; - msg << e1 << " + " << e2 + return testing::AssertionFailure() + << e1 << " + " << e2 << " is expected to be positive, but evaluates to " << v1 + v2 << "."; - return testing::AssertionFailure(msg); } // A binary predicate-formatter functor. @@ -927,11 +925,10 @@ testing::AssertionResult PredFormatFunction3(const char* e1, if (PredFunction3(v1, v2, v3)) return testing::AssertionSuccess(); - testing::Message msg; - msg << e1 << " + " << e2 << " + " << e3 + return testing::AssertionFailure() + << e1 << " + " << e2 << " + " << e3 << " is expected to be positive, but evaluates to " << v1 + v2 + v3 << "."; - return testing::AssertionFailure(msg); } // A ternary predicate-formatter functor. @@ -1402,11 +1399,10 @@ testing::AssertionResult PredFormatFunction4(const char* e1, if (PredFunction4(v1, v2, v3, v4)) return testing::AssertionSuccess(); - testing::Message msg; - msg << e1 << " + " << e2 << " + " << e3 << " + " << e4 + return testing::AssertionFailure() + << e1 << " + " << e2 << " + " << e3 << " + " << e4 << " is expected to be positive, but evaluates to " << v1 + v2 + v3 + v4 << "."; - return testing::AssertionFailure(msg); } // A 4-ary predicate-formatter functor. @@ -1919,11 +1915,10 @@ testing::AssertionResult PredFormatFunction5(const char* e1, if (PredFunction5(v1, v2, v3, v4, v5)) return testing::AssertionSuccess(); - testing::Message msg; - msg << e1 << " + " << e2 << " + " << e3 << " + " << e4 << " + " << e5 + return testing::AssertionFailure() + << e1 << " + " << e2 << " + " << e3 << " + " << e4 << " + " << e5 << " is expected to be positive, but evaluates to " << v1 + v2 + v3 + v4 + v5 << "."; - return testing::AssertionFailure(msg); } // A 5-ary predicate-formatter functor. -- cgit v1.2.3 From c18438ca2983d4f334cfdbd4453e15c41111fa17 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Mon, 11 Oct 2010 06:28:54 +0000 Subject: Makes gtest wokr on MinGW (by Vlad Losev); removes unused linked_ptr::release() method (by Zhanyong Wan). --- test/gtest-death-test_test.cc | 2 +- test/gtest-printers_test.cc | 21 ++++++------ test/gtest_unittest.cc | 75 ++++++++++++++++++++++++++----------------- 3 files changed, 57 insertions(+), 41 deletions(-) (limited to 'test') diff --git a/test/gtest-death-test_test.cc b/test/gtest-death-test_test.cc index 6144f2db..2f1d3859 100644 --- a/test/gtest-death-test_test.cc +++ b/test/gtest-death-test_test.cc @@ -994,7 +994,7 @@ TEST(AutoHandleTest, AutoHandleWorks) { typedef unsigned __int64 BiggestParsable; typedef signed __int64 BiggestSignedParsable; const BiggestParsable kBiggestParsableMax = ULLONG_MAX; -const BiggestParsable kBiggestSignedParsableMax = LLONG_MAX; +const BiggestSignedParsable kBiggestSignedParsableMax = LLONG_MAX; #else typedef unsigned long long BiggestParsable; typedef signed long long BiggestSignedParsable; diff --git a/test/gtest-printers_test.cc b/test/gtest-printers_test.cc index 16fe9249..5eabd235 100644 --- a/test/gtest-printers_test.cc +++ b/test/gtest-printers_test.cc @@ -50,8 +50,8 @@ #include "gtest/gtest.h" -// hash_map and hash_set are available on Windows. -#if GTEST_OS_WINDOWS +// hash_map and hash_set are available under Visual C++. +#if _MSC_VER #define GTEST_HAS_HASH_MAP_ 1 // Indicates that hash_map is available. #include // NOLINT #define GTEST_HAS_HASH_SET_ 1 // Indicates that hash_set is available. @@ -212,17 +212,15 @@ using ::std::tr1::make_tuple; using ::std::tr1::tuple; #endif -#if GTEST_OS_WINDOWS +#if _MSC_VER // MSVC defines the following classes in the ::stdext namespace while // gcc defines them in the :: namespace. Note that they are not part // of the C++ standard. - using ::stdext::hash_map; using ::stdext::hash_set; using ::stdext::hash_multimap; using ::stdext::hash_multiset; - -#endif // GTEST_OS_WINDOWS +#endif // Prints a value to a string using the universal value printer. This // is a helper for testing UniversalPrinter::Print() for various types. @@ -333,8 +331,8 @@ TEST(PrintBuiltInTypeTest, Wchar_t) { EXPECT_EQ("L'\\xFF' (255)", Print(L'\xFF')); EXPECT_EQ("L' ' (32, 0x20)", Print(L' ')); EXPECT_EQ("L'a' (97, 0x61)", Print(L'a')); - EXPECT_EQ("L'\\x576' (1398)", Print(L'\x576')); - EXPECT_EQ("L'\\xC74D' (51021)", Print(L'\xC74D')); + EXPECT_EQ("L'\\x576' (1398)", Print(static_cast(0x576))); + EXPECT_EQ("L'\\xC74D' (51021)", Print(static_cast(0xC74D))); } // Test that Int64 provides more storage than wchar_t. @@ -440,10 +438,11 @@ TEST(PrintWideCStringTest, Null) { // Tests that wide C strings are escaped properly. TEST(PrintWideCStringTest, EscapesProperly) { - const wchar_t* p = L"'\"\?\\\a\b\f\n\r\t\v\xD3\x576\x8D3\xC74D a"; - EXPECT_EQ(PrintPointer(p) + " pointing to L\"'\\\"\\?\\\\\\a\\b\\f" + const wchar_t s[] = {'\'', '"', '\?', '\\', '\a', '\b', '\f', '\n', '\r', + '\t', '\v', 0xD3, 0x576, 0x8D3, 0xC74D, ' ', 'a', '\0'}; + EXPECT_EQ(PrintPointer(s) + " pointing to L\"'\\\"\\?\\\\\\a\\b\\f" "\\n\\r\\t\\v\\xD3\\x576\\x8D3\\xC74D a\"", - Print(p)); + Print(static_cast(s))); } #endif // native wchar_t diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index 056064fa..cb189a30 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -372,7 +372,11 @@ TEST(CodePointToUtf8Test, CanEncode8To11Bits) { EXPECT_STREQ("\xC3\x93", CodePointToUtf8(L'\xD3', buffer)); // 101 0111 0110 => 110-10101 10-110110 - EXPECT_STREQ("\xD5\xB6", CodePointToUtf8(L'\x576', buffer)); + // Some compilers (e.g., GCC on MinGW) cannot handle non-ASCII codepoints + // in wide strings and wide chars. In order to accomodate them, we have to + // introduce such character constants as integers. + EXPECT_STREQ("\xD5\xB6", + CodePointToUtf8(static_cast(0x576), buffer)); } // Tests that Unicode code-points that have 12 to 16 bits are encoded @@ -380,10 +384,12 @@ TEST(CodePointToUtf8Test, CanEncode8To11Bits) { TEST(CodePointToUtf8Test, CanEncode12To16Bits) { char buffer[32]; // 0000 1000 1101 0011 => 1110-0000 10-100011 10-010011 - EXPECT_STREQ("\xE0\xA3\x93", CodePointToUtf8(L'\x8D3', buffer)); + EXPECT_STREQ("\xE0\xA3\x93", + CodePointToUtf8(static_cast(0x8D3), buffer)); // 1100 0111 0100 1101 => 1110-1100 10-011101 10-001101 - EXPECT_STREQ("\xEC\x9D\x8D", CodePointToUtf8(L'\xC74D', buffer)); + EXPECT_STREQ("\xEC\x9D\x8D", + CodePointToUtf8(static_cast(0xC74D), buffer)); } #if !GTEST_WIDE_STRING_USES_UTF16_ @@ -438,20 +444,23 @@ TEST(WideStringToUtf8Test, CanEncode8To11Bits) { EXPECT_STREQ("\xC3\x93", WideStringToUtf8(L"\xD3", -1).c_str()); // 101 0111 0110 => 110-10101 10-110110 - EXPECT_STREQ("\xD5\xB6", WideStringToUtf8(L"\x576", 1).c_str()); - EXPECT_STREQ("\xD5\xB6", WideStringToUtf8(L"\x576", -1).c_str()); + const wchar_t s[] = { 0x576, '\0' }; + EXPECT_STREQ("\xD5\xB6", WideStringToUtf8(s, 1).c_str()); + EXPECT_STREQ("\xD5\xB6", WideStringToUtf8(s, -1).c_str()); } // Tests that Unicode code-points that have 12 to 16 bits are encoded // as 1110xxxx 10xxxxxx 10xxxxxx. TEST(WideStringToUtf8Test, CanEncode12To16Bits) { // 0000 1000 1101 0011 => 1110-0000 10-100011 10-010011 - EXPECT_STREQ("\xE0\xA3\x93", WideStringToUtf8(L"\x8D3", 1).c_str()); - EXPECT_STREQ("\xE0\xA3\x93", WideStringToUtf8(L"\x8D3", -1).c_str()); + const wchar_t s1[] = { 0x8D3, '\0' }; + EXPECT_STREQ("\xE0\xA3\x93", WideStringToUtf8(s1, 1).c_str()); + EXPECT_STREQ("\xE0\xA3\x93", WideStringToUtf8(s1, -1).c_str()); // 1100 0111 0100 1101 => 1110-1100 10-011101 10-001101 - EXPECT_STREQ("\xEC\x9D\x8D", WideStringToUtf8(L"\xC74D", 1).c_str()); - EXPECT_STREQ("\xEC\x9D\x8D", WideStringToUtf8(L"\xC74D", -1).c_str()); + const wchar_t s2[] = { 0xC74D, '\0' }; + EXPECT_STREQ("\xEC\x9D\x8D", WideStringToUtf8(s2, 1).c_str()); + EXPECT_STREQ("\xEC\x9D\x8D", WideStringToUtf8(s2, -1).c_str()); } // Tests that the conversion stops when the function encounters \0 character. @@ -465,7 +474,6 @@ TEST(WideStringToUtf8Test, StopsWhenLengthLimitReached) { EXPECT_STREQ("ABC", WideStringToUtf8(L"ABCDEF", 3).c_str()); } - #if !GTEST_WIDE_STRING_USES_UTF16_ // Tests that Unicode code-points that have 17 to 21 bits are encoded // as 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx. This code may not compile @@ -489,25 +497,29 @@ TEST(WideStringToUtf8Test, CanEncodeInvalidCodePoint) { // Tests that surrogate pairs are encoded correctly on the systems using // UTF-16 encoding in the wide strings. TEST(WideStringToUtf8Test, CanEncodeValidUtf16SUrrogatePairs) { - EXPECT_STREQ("\xF0\x90\x90\x80", - WideStringToUtf8(L"\xD801\xDC00", -1).c_str()); + const wchar_t s[] = { 0xD801, 0xDC00, '\0' }; + EXPECT_STREQ("\xF0\x90\x90\x80", WideStringToUtf8(s, -1).c_str()); } // Tests that encoding an invalid UTF-16 surrogate pair // generates the expected result. TEST(WideStringToUtf8Test, CanEncodeInvalidUtf16SurrogatePair) { // Leading surrogate is at the end of the string. - EXPECT_STREQ("\xED\xA0\x80", WideStringToUtf8(L"\xD800", -1).c_str()); + const wchar_t s1[] = { 0xD800, '\0' }; + EXPECT_STREQ("\xED\xA0\x80", WideStringToUtf8(s1, -1).c_str()); // Leading surrogate is not followed by the trailing surrogate. - EXPECT_STREQ("\xED\xA0\x80$", WideStringToUtf8(L"\xD800$", -1).c_str()); + const wchar_t s2[] = { 0xD800, 'M', '\0' }; + EXPECT_STREQ("\xED\xA0\x80M", WideStringToUtf8(s2, -1).c_str()); // Trailing surrogate appearas without a leading surrogate. - EXPECT_STREQ("\xED\xB0\x80PQR", WideStringToUtf8(L"\xDC00PQR", -1).c_str()); + const wchar_t s3[] = { 0xDC00, 'P', 'Q', 'R', '\0' }; + EXPECT_STREQ("\xED\xB0\x80PQR", WideStringToUtf8(s3, -1).c_str()); } #endif // !GTEST_WIDE_STRING_USES_UTF16_ // Tests that codepoint concatenation works correctly. #if !GTEST_WIDE_STRING_USES_UTF16_ TEST(WideStringToUtf8Test, ConcatenatesCodepointsCorrectly) { + const wchar_t s[] = { 0x108634, 0xC74D, '\n', 0x576, 0x8D3, 0x108634, '\0'}; EXPECT_STREQ( "\xF4\x88\x98\xB4" "\xEC\x9D\x8D" @@ -515,13 +527,14 @@ TEST(WideStringToUtf8Test, ConcatenatesCodepointsCorrectly) { "\xD5\xB6" "\xE0\xA3\x93" "\xF4\x88\x98\xB4", - WideStringToUtf8(L"\x108634\xC74D\n\x576\x8D3\x108634", -1).c_str()); + WideStringToUtf8(s, -1).c_str()); } #else TEST(WideStringToUtf8Test, ConcatenatesCodepointsCorrectly) { + const wchar_t s[] = { 0xC74D, '\n', 0x576, 0x8D3, '\0'}; EXPECT_STREQ( "\xEC\x9D\x8D" "\n" "\xD5\xB6" "\xE0\xA3\x93", - WideStringToUtf8(L"\xC74D\n\x576\x8D3", -1).c_str()); + WideStringToUtf8(s, -1).c_str()); } #endif // !GTEST_WIDE_STRING_USES_UTF16_ @@ -4519,8 +4532,8 @@ TEST(EqAssertionTest, WideChar) { wchar = L'b'; EXPECT_NONFATAL_FAILURE(EXPECT_EQ(L'a', wchar), "wchar"); - wchar = L'\x8119'; - EXPECT_FATAL_FAILURE(ASSERT_EQ(L'\x8120', wchar), + wchar = 0x8119; + EXPECT_FATAL_FAILURE(ASSERT_EQ(static_cast(0x8120), wchar), "Value of: wchar"); } @@ -4558,20 +4571,22 @@ TEST(EqAssertionTest, StdString) { // Tests using ::std::wstring values in {EXPECT|ASSERT}_EQ. TEST(EqAssertionTest, StdWideString) { - // Compares an std::wstring to a const wchar_t* that has identical - // content. - EXPECT_EQ(::std::wstring(L"Test\x8119"), L"Test\x8119"); - // Compares two identical std::wstrings. const ::std::wstring wstr1(L"A * in the middle"); const ::std::wstring wstr2(wstr1); ASSERT_EQ(wstr1, wstr2); + // Compares an std::wstring to a const wchar_t* that has identical + // content. + const wchar_t kTestX8119[] = { 'T', 'e', 's', 't', 0x8119, '\0' }; + EXPECT_EQ(::std::wstring(kTestX8119), kTestX8119); + // Compares an std::wstring to a const wchar_t* that has different // content. + const wchar_t kTestX8120[] = { 'T', 'e', 's', 't', 0x8120, '\0' }; EXPECT_NONFATAL_FAILURE({ // NOLINT - EXPECT_EQ(::std::wstring(L"Test\x8119"), L"Test\x8120"); - }, "L\"Test\\x8120\""); + EXPECT_EQ(::std::wstring(kTestX8119), kTestX8120); + }, "kTestX8120"); // Compares two std::wstrings that have different contents, one of // which having a NUL character in the middle. @@ -4623,18 +4638,20 @@ TEST(EqAssertionTest, GlobalString) { // Tests using ::wstring values in {EXPECT|ASSERT}_EQ. TEST(EqAssertionTest, GlobalWideString) { - // Compares a const wchar_t* to a ::wstring that has identical content. - ASSERT_EQ(L"Test\x8119", ::wstring(L"Test\x8119")); - // Compares two identical ::wstrings. static const ::wstring wstr1(L"A * in the middle"); static const ::wstring wstr2(wstr1); EXPECT_EQ(wstr1, wstr2); + // Compares a const wchar_t* to a ::wstring that has identical content. + const wchar_t kTestX8119[] = { 'T', 'e', 's', 't', 0x8119, '\0' }; + ASSERT_EQ(kTestX8119, ::wstring(kTestX8119)); + // Compares a const wchar_t* to a ::wstring that has different // content. + const wchar_t kTestX8120[] = { 'T', 'e', 's', 't', 0x8120, '\0' }; EXPECT_NONFATAL_FAILURE({ // NOLINT - EXPECT_EQ(L"Test\x8120", ::wstring(L"Test\x8119")); + EXPECT_EQ(kTestX8120, ::wstring(kTestX8119)); }, "Test\\x8119"); // Compares a wchar_t* to a ::wstring that has different content. -- cgit v1.2.3 From 50f4deb1cf3ef32282c13b7cb84a81b1bf61e0d8 Mon Sep 17 00:00:00 2001 From: vladlosev Date: Mon, 18 Oct 2010 22:09:55 +0000 Subject: Modifies handling of C++ exceptions in death tests to treat exceptions escaping them as failures. --- test/gtest-death-test_ex_test.cc | 93 ++++++++++++++++++++++++++++++++++++++++ test/gtest-death-test_test.cc | 7 ++- 2 files changed, 98 insertions(+), 2 deletions(-) create mode 100644 test/gtest-death-test_ex_test.cc (limited to 'test') diff --git a/test/gtest-death-test_ex_test.cc b/test/gtest-death-test_ex_test.cc new file mode 100644 index 00000000..71cc7a36 --- /dev/null +++ b/test/gtest-death-test_ex_test.cc @@ -0,0 +1,93 @@ +// Copyright 2010, 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: vladl@google.com (Vlad Losev) +// +// Tests that verify interaction of exceptions and death tests. + +#include "gtest/gtest-death-test.h" +#include "gtest/gtest.h" + +#if GTEST_HAS_DEATH_TEST + +#if GTEST_HAS_SEH +#include // For RaiseException(). +#endif + +#include "gtest/gtest-spi.h" + +#if GTEST_HAS_EXCEPTIONS + +#include // For std::exception. + +// Tests that death tests report thrown exceptions as failures and that the +// exceptions do not escape death test macros. +TEST(CxxExceptionDeathTest, ExceptionIsFailure) { + try { + EXPECT_NONFATAL_FAILURE(EXPECT_DEATH(throw 1, ""), "threw an exception"); + } catch (...) { // NOLINT + FAIL() << "An exception escaped a death test macro invocation " + << "with catch_exceptions " + << (testing::GTEST_FLAG(catch_exceptions) ? "enabled" : "disabled"); + } +} + +class TestException : public std::exception { + public: + virtual const char* what() const throw() { return "exceptional message"; } +}; + +TEST(CxxExceptionDeathTest, PrintsMessageForStdExceptions) { + // Verifies that the exception message is quoted in the failure text. + EXPECT_NONFATAL_FAILURE(EXPECT_DEATH(throw TestException(), ""), + "exceptional message"); + // Verifies that the location is mentioned in the failure text. + EXPECT_NONFATAL_FAILURE(EXPECT_DEATH(throw TestException(), ""), + "gtest-death-test_ex_test.cc"); +} +#endif // GTEST_HAS_EXCEPTIONS + +#if GTEST_HAS_SEH +// Tests that enabling interception of SEH exceptions with the +// catch_exceptions flag does not interfere with SEH exceptions being +// treated as death by death tests. +TEST(SehExceptionDeasTest, CatchExceptionsDoesNotInterfere) { + EXPECT_DEATH(RaiseException(42, 0x0, 0, NULL), "") + << "with catch_exceptions " + << (testing::GTEST_FLAG(catch_exceptions) ? "enabled" : "disabled"); +} +#endif + +#endif // GTEST_HAS_DEATH_TEST + +int main(int argc, char** argv) { + testing::InitGoogleTest(&argc, argv); + testing::GTEST_FLAG(catch_exceptions) = GTEST_ENABLE_CATCH_EXCEPTIONS_ != 0; + return RUN_ALL_TESTS(); +} diff --git a/test/gtest-death-test_test.cc b/test/gtest-death-test_test.cc index 2f1d3859..b83b0db2 100644 --- a/test/gtest-death-test_test.cc +++ b/test/gtest-death-test_test.cc @@ -538,15 +538,18 @@ TEST_F(TestForDeathTest, SingleEvaluation) { } // Tests that run-away death tests are reported as failures. -TEST_F(TestForDeathTest, Runaway) { +TEST_F(TestForDeathTest, RunawayIsFailure) { EXPECT_NONFATAL_FAILURE(EXPECT_DEATH(static_cast(0), "Foo"), "failed to die."); +} +// Tests that death tests report executing 'return' in the statement as +// failure. +TEST_F(TestForDeathTest, ReturnIsFailure) { EXPECT_FATAL_FAILURE(ASSERT_DEATH(return, "Bar"), "illegal return in test statement."); } - // Tests that EXPECT_DEBUG_DEATH works as expected, // that is, in debug mode, it: // 1. Asserts on death. -- cgit v1.2.3 From 25958f3e4c4097caca8347b7937f5f6fb26d6c56 Mon Sep 17 00:00:00 2001 From: vladlosev Date: Fri, 22 Oct 2010 01:33:11 +0000 Subject: Fixes compiler warning when built with -std=c++0x. --- test/gtest_unittest.cc | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'test') diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index cb189a30..5a93ff26 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -34,6 +34,7 @@ #include "gtest/gtest.h" #include +#include // Verifies that the command line flag variables can be accessed // in code once has been #included. @@ -4902,7 +4903,7 @@ TEST(AssertionResultTest, ConstructionWorks) { EXPECT_STREQ("ghi", r5.message()); } -// Tests that the negation fips the predicate result but keeps the message. +// Tests that the negation flips the predicate result but keeps the message. TEST(AssertionResultTest, NegationWorks) { AssertionResult r1 = AssertionSuccess() << "abc"; EXPECT_FALSE(!r1); @@ -4919,6 +4920,12 @@ TEST(AssertionResultTest, StreamingWorks) { EXPECT_STREQ("abcd0true", r.message()); } +TEST(AssertionResultTest, CanStreamOstreamManipulators) { + AssertionResult r = AssertionSuccess(); + r << "Data" << std::endl << std::flush << std::ends << "Will be visible"; + EXPECT_STREQ("Data\n\\0Will be visible", r.message()); +} + // Tests streaming a user type whose definition and operator << are // both in the global namespace. class Base { -- cgit v1.2.3 From 82cc1d1135879be3b901a10e224dbd827365f8bf Mon Sep 17 00:00:00 2001 From: vladlosev Date: Tue, 26 Oct 2010 23:12:47 +0000 Subject: Changes default of --gtest_catch_exceptions to true. --- test/gtest_catch_exceptions_test.py | 17 +++++++++-------- test/gtest_env_var_test.py | 4 +--- test/gtest_help_test.py | 2 +- 3 files changed, 11 insertions(+), 12 deletions(-) (limited to 'test') diff --git a/test/gtest_catch_exceptions_test.py b/test/gtest_catch_exceptions_test.py index 061c5c3d..7fd7dbad 100755 --- a/test/gtest_catch_exceptions_test.py +++ b/test/gtest_catch_exceptions_test.py @@ -42,9 +42,10 @@ import os import gtest_test_utils # Constants. -LIST_TESTS_FLAG = '--gtest_list_tests' -CATCH_EXCEPTIONS_FLAG = '--gtest_catch_exceptions=1' -FILTER_FLAG='--gtest_filter' +FLAG_PREFIX = '--gtest_' +LIST_TESTS_FLAG = FLAG_PREFIX + 'list_tests' +NO_CATCH_EXCEPTIONS_FLAG = FLAG_PREFIX + 'catch_exceptions=0' +FILTER_FLAG = FLAG_PREFIX + 'filter' # Path to the gtest_catch_exceptions_ex_test_ binary, compiled with # exceptions enabled. @@ -61,11 +62,9 @@ TEST_LIST = gtest_test_utils.Subprocess([EXE_PATH, LIST_TESTS_FLAG]).output SUPPORTS_SEH_EXCEPTIONS = 'ThrowsSehException' in TEST_LIST if SUPPORTS_SEH_EXCEPTIONS: - BINARY_OUTPUT = gtest_test_utils.Subprocess([EXE_PATH, - CATCH_EXCEPTIONS_FLAG]).output + BINARY_OUTPUT = gtest_test_utils.Subprocess([EXE_PATH]).output -EX_BINARY_OUTPUT = gtest_test_utils.Subprocess([EX_EXE_PATH, - CATCH_EXCEPTIONS_FLAG]).output +EX_BINARY_OUTPUT = gtest_test_utils.Subprocess([EX_EXE_PATH]).output # The tests. if SUPPORTS_SEH_EXCEPTIONS: @@ -208,7 +207,9 @@ class CatchCxxExceptionsTest(gtest_test_utils.TestCase): FITLER_OUT_SEH_TESTS_FLAG = FILTER_FLAG + '=-*Seh*' # By default, Google Test doesn't catch the exceptions. uncaught_exceptions_ex_binary_output = gtest_test_utils.Subprocess( - [EX_EXE_PATH, FITLER_OUT_SEH_TESTS_FLAG]).output + [EX_EXE_PATH, + NO_CATCH_EXCEPTIONS_FLAG, + FITLER_OUT_SEH_TESTS_FLAG]).output self.assert_('Unhandled C++ exception terminating the program' in uncaught_exceptions_ex_binary_output) diff --git a/test/gtest_env_var_test.py b/test/gtest_env_var_test.py index bcc0bfd5..ac24337f 100755 --- a/test/gtest_env_var_test.py +++ b/test/gtest_env_var_test.py @@ -92,9 +92,7 @@ class GTestEnvVarTest(gtest_test_utils.TestCase): TestFlag('repeat', '999', '1') TestFlag('throw_on_failure', '1', '0') TestFlag('death_test_style', 'threadsafe', 'fast') - - if IS_WINDOWS: - TestFlag('catch_exceptions', '1', '0') + TestFlag('catch_exceptions', '0', '1') if IS_LINUX: TestFlag('death_test_use_fork', '1', '0') diff --git a/test/gtest_help_test.py b/test/gtest_help_test.py index 0777106a..093c838d 100755 --- a/test/gtest_help_test.py +++ b/test/gtest_help_test.py @@ -74,7 +74,7 @@ HELP_REGEX = re.compile( FLAG_PREFIX + r'output=.*' + FLAG_PREFIX + r'break_on_failure.*' + FLAG_PREFIX + r'throw_on_failure.*' + - FLAG_PREFIX + r'catch_exceptions.*', + FLAG_PREFIX + r'catch_exceptions=0.*', re.DOTALL) -- cgit v1.2.3 From b5eb6ed9e27b7bf80a406e4a38ffe42db43889cc Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Thu, 2 Dec 2010 23:28:38 +0000 Subject: Makes gtest print string literals correctly when it contains \x escape sequences. Contributed by Yair Chuchem. --- test/gtest-printers_test.cc | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'test') diff --git a/test/gtest-printers_test.cc b/test/gtest-printers_test.cc index 5eabd235..da1fbc25 100644 --- a/test/gtest-printers_test.cc +++ b/test/gtest-printers_test.cc @@ -658,6 +658,20 @@ TEST(PrintStringTest, StringInStdNamespace) { Print(str)); } +TEST(PrintStringTest, StringAmbiguousHex) { + // "\x6BANANA" is ambiguous, it can be interpreted as starting with either of: + // '\x6', '\x6B', or '\x6BA'. + + // a hex escaping sequence following by a decimal digit + EXPECT_EQ("\"0\\x12\" \"3\"", Print(::std::string("0\x12" "3"))); + // a hex escaping sequence following by a hex digit (lower-case) + EXPECT_EQ("\"mm\\x6\" \"bananas\"", Print(::std::string("mm\x6" "bananas"))); + // a hex escaping sequence following by a hex digit (upper-case) + EXPECT_EQ("\"NOM\\x6\" \"BANANA\"", Print(::std::string("NOM\x6" "BANANA"))); + // a hex escaping sequence following by a non-xdigit + EXPECT_EQ("\"!\\x5-!\"", Print(::std::string("!\x5-!"))); +} + // Tests printing ::wstring and ::std::wstring. #if GTEST_HAS_GLOBAL_WSTRING @@ -680,6 +694,16 @@ TEST(PrintWideStringTest, StringInStdNamespace) { "\\xD3\\x576\\x8D3\\xC74D a\\0\"", Print(str)); } + +TEST(PrintWideStringTest, StringAmbiguousHex) { + // same for wide strings. + EXPECT_EQ("L\"0\\x12\" L\"3\"", Print(::std::wstring(L"0\x12" L"3"))); + EXPECT_EQ("L\"mm\\x6\" L\"bananas\"", + Print(::std::wstring(L"mm\x6" L"bananas"))); + EXPECT_EQ("L\"NOM\\x6\" L\"BANANA\"", + Print(::std::wstring(L"NOM\x6" L"BANANA"))); + EXPECT_EQ("L\"!\\x5-!\"", Print(::std::wstring(L"!\x5-!"))); +} #endif // GTEST_HAS_STD_WSTRING // Tests printing types that support generic streaming (i.e. streaming -- cgit v1.2.3 From 915129ee6fd4d9c5564aafedb238a237592a3d42 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Mon, 6 Dec 2010 22:18:59 +0000 Subject: Allows a value-parameterized test fixture to derive from Test and WithParamInterface separately; contributed by Matt Austern. --- test/gtest-param-test_test.cc | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) (limited to 'test') diff --git a/test/gtest-param-test_test.cc b/test/gtest-param-test_test.cc index c920f4fd..acd269bc 100644 --- a/test/gtest-param-test_test.cc +++ b/test/gtest-param-test_test.cc @@ -836,6 +836,39 @@ INSTANTIATE_TEST_CASE_P(InstantiationWithComments, CommentTest, Values(Unstreamable(1))); +// Verify that we can create a hierarchy of test fixtures, where the base +// class fixture is not parameterized and the derived class is. In this case +// ParameterizedDerivedTest inherits from NonParameterizedBaseTest. We +// perform simple tests on both. +class NonParameterizedBaseTest : public ::testing::Test { + public: + NonParameterizedBaseTest() : n_(17) { } + protected: + int n_; +}; + +class ParameterizedDerivedTest : public NonParameterizedBaseTest, + public ::testing::WithParamInterface { + protected: + ParameterizedDerivedTest() : count_(0) { } + int count_; + static int global_count_; +}; + +int ParameterizedDerivedTest::global_count_ = 0; + +TEST_F(NonParameterizedBaseTest, FixtureIsInitialized) { + EXPECT_EQ(17, n_); +} + +TEST_P(ParameterizedDerivedTest, SeesSequence) { + EXPECT_EQ(17, n_); + EXPECT_EQ(0, count_++); + EXPECT_EQ(GetParam(), global_count_++); +} + +INSTANTIATE_TEST_CASE_P(RangeZeroToFive, ParameterizedDerivedTest, Range(0, 5)); + #endif // GTEST_HAS_PARAM_TEST TEST(CompileTest, CombineIsDefinedOnlyWhenGtestHasParamTestIsDefined) { -- cgit v1.2.3 From 7225dd179a49165036ebad0a92a8f6f408d332c6 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Fri, 7 Jan 2011 01:14:05 +0000 Subject: Suppresses self-assignment warnings. --- test/gtest-linked_ptr_test.cc | 3 +- test/gtest_nc_test.py | 93 ++++++++++++++++++++++--------------------- test/gtest_unittest.cc | 3 +- 3 files changed, 51 insertions(+), 48 deletions(-) (limited to 'test') diff --git a/test/gtest-linked_ptr_test.cc b/test/gtest-linked_ptr_test.cc index efd6b1ed..0d5508ae 100644 --- a/test/gtest-linked_ptr_test.cc +++ b/test/gtest-linked_ptr_test.cc @@ -77,7 +77,8 @@ class LinkedPtrTest : public testing::Test { TEST_F(LinkedPtrTest, GeneralTest) { { linked_ptr a0, a1, a2; - a0 = a0; + // Use explicit function call notation here to suppress self-assign warning. + a0.operator=(a0); a1 = a2; ASSERT_EQ(a0.get(), static_cast(NULL)); ASSERT_EQ(a1.get(), static_cast(NULL)); diff --git a/test/gtest_nc_test.py b/test/gtest_nc_test.py index bf09234a..c60b96e5 100755 --- a/test/gtest_nc_test.py +++ b/test/gtest_nc_test.py @@ -46,68 +46,69 @@ if not IS_LINUX: class GTestNCTest(unittest.TestCase): """Negative compilation test for Google Test.""" - def testCompilerError(self): - """Verifies that erroneous code leads to expected compiler - messages.""" + # The class body is intentionally empty. The actual test*() methods + # will be defined at run time by a call to + # DefineNegativeCompilationTests() later. + pass - # Defines a list of test specs, where each element is a tuple - # (test name, list of regexes for matching the compiler errors). - test_specs = [ - ('CANNOT_IGNORE_RUN_ALL_TESTS_RESULT', - [r'ignoring return value']), +# Defines a list of test specs, where each element is a tuple +# (test name, list of regexes for matching the compiler errors). +TEST_SPECS = [ + ('CANNOT_IGNORE_RUN_ALL_TESTS_RESULT', + [r'ignoring return value']), - ('USER_CANNOT_INCLUDE_GTEST_INTERNAL_INL_H', - [r'must not be included except by Google Test itself']), + ('USER_CANNOT_INCLUDE_GTEST_INTERNAL_INL_H', + [r'must not be included except by Google Test itself']), - ('CATCHES_DECLARING_SETUP_IN_TEST_FIXTURE_WITH_TYPO', - [r'Setup_should_be_spelled_SetUp']), + ('CATCHES_DECLARING_SETUP_IN_TEST_FIXTURE_WITH_TYPO', + [r'Setup_should_be_spelled_SetUp']), - ('CATCHES_CALLING_SETUP_IN_TEST_WITH_TYPO', - [r'Setup_should_be_spelled_SetUp']), + ('CATCHES_CALLING_SETUP_IN_TEST_WITH_TYPO', + [r'Setup_should_be_spelled_SetUp']), - ('CATCHES_DECLARING_SETUP_IN_ENVIRONMENT_WITH_TYPO', - [r'Setup_should_be_spelled_SetUp']), + ('CATCHES_DECLARING_SETUP_IN_ENVIRONMENT_WITH_TYPO', + [r'Setup_should_be_spelled_SetUp']), - ('CATCHES_CALLING_SETUP_IN_ENVIRONMENT_WITH_TYPO', - [r'Setup_should_be_spelled_SetUp']), + ('CATCHES_CALLING_SETUP_IN_ENVIRONMENT_WITH_TYPO', + [r'Setup_should_be_spelled_SetUp']), - ('CATCHES_WRONG_CASE_IN_TYPED_TEST_P', - [r'BarTest.*was not declared', # GCC - r'undeclared identifier .*BarTest', # Clang - ]), + ('CATCHES_WRONG_CASE_IN_TYPED_TEST_P', + [r'BarTest.*was not declared', # GCC + r'undeclared identifier .*BarTest', # Clang + ]), - ('CATCHES_WRONG_CASE_IN_REGISTER_TYPED_TEST_CASE_P', - [r'BarTest.*was not declared', # GCC - r'undeclared identifier .*BarTest', # Clang - ]), + ('CATCHES_WRONG_CASE_IN_REGISTER_TYPED_TEST_CASE_P', + [r'BarTest.*was not declared', # GCC + r'undeclared identifier .*BarTest', # Clang + ]), - ('CATCHES_WRONG_CASE_IN_INSTANTIATE_TYPED_TEST_CASE_P', - [r'BarTest.*not declared', # GCC - r'undeclared identifier .*BarTest', # Clang - ]), + ('CATCHES_WRONG_CASE_IN_INSTANTIATE_TYPED_TEST_CASE_P', + [r'BarTest.*not declared', # GCC + r'undeclared identifier .*BarTest', # Clang + ]), - ('CATCHES_INSTANTIATE_TYPED_TESET_CASE_P_WITH_SAME_NAME_PREFIX', - [r'redefinition of.*My.*FooTest']), + ('CATCHES_INSTANTIATE_TYPED_TESET_CASE_P_WITH_SAME_NAME_PREFIX', + [r'redefinition of.*My.*FooTest']), - ('STATIC_ASSERT_TYPE_EQ_IS_NOT_A_TYPE', - [r'StaticAssertTypeEq.* does not name a type', # GCC - r'requires a type.*\n.*StaticAssertTypeEq', # Clang - ]), + ('STATIC_ASSERT_TYPE_EQ_IS_NOT_A_TYPE', + [r'StaticAssertTypeEq.* does not name a type', # GCC + r'requires a type.*\n.*StaticAssertTypeEq', # Clang + ]), - ('STATIC_ASSERT_TYPE_EQ_WORKS_IN_NAMESPACE', - [r'StaticAssertTypeEq.*int.*const int']), + ('STATIC_ASSERT_TYPE_EQ_WORKS_IN_NAMESPACE', + [r'StaticAssertTypeEq.*int.*const int']), - ('STATIC_ASSERT_TYPE_EQ_WORKS_IN_CLASS', - [r'StaticAssertTypeEq.*int.*bool']), + ('STATIC_ASSERT_TYPE_EQ_WORKS_IN_CLASS', + [r'StaticAssertTypeEq.*int.*bool']), - ('STATIC_ASSERT_TYPE_EQ_WORKS_IN_FUNCTION', - [r'StaticAssertTypeEq.*const int.*int']), + ('STATIC_ASSERT_TYPE_EQ_WORKS_IN_FUNCTION', + [r'StaticAssertTypeEq.*const int.*int']), - ('SANITY', - None) - ] + ('SANITY', + None) + ] - # TODO(wan@google.com): verify that the test specs are satisfied. +# TODO(wan@google.com): verify that the test specs are satisfied. if __name__ == '__main__': diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index 5a93ff26..89a4a0e7 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -1150,7 +1150,8 @@ TEST(StringTest, CanBeAssignedNonEmpty) { TEST(StringTest, CanBeAssignedSelf) { String dest("hello"); - dest = dest; + // Use explicit function call notation here to suppress self-assign warning. + dest.operator=(dest); EXPECT_STREQ("hello", dest.c_str()); } -- cgit v1.2.3 From afaefb0e30366cf8bedb41daf14dc9e17a5d1ff9 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Fri, 7 Jan 2011 01:21:35 +0000 Subject: Removes unused NC tests. --- test/gtest_nc.cc | 234 -------------------------------------------------- test/gtest_nc_test.py | 115 ------------------------- 2 files changed, 349 deletions(-) delete mode 100644 test/gtest_nc.cc delete mode 100755 test/gtest_nc_test.py (limited to 'test') diff --git a/test/gtest_nc.cc b/test/gtest_nc.cc deleted file mode 100644 index 71acf2bd..00000000 --- a/test/gtest_nc.cc +++ /dev/null @@ -1,234 +0,0 @@ -// Copyright 2007, 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) - -// This file is the input to a negative-compilation test for Google -// Test. Code here is NOT supposed to compile. Its purpose is to -// verify that certain incorrect usages of the Google Test API are -// indeed rejected by the compiler. -// -// We still need to write the negative-compilation test itself, which -// will be tightly coupled with the build environment. -// -// TODO(wan@google.com): finish the negative-compilation test. - -#ifdef TEST_CANNOT_IGNORE_RUN_ALL_TESTS_RESULT -// Tests that the result of RUN_ALL_TESTS() cannot be ignored. - -#include "gtest/gtest.h" - -int main(int argc, char** argv) { - testing::InitGoogleTest(&argc, argv); - RUN_ALL_TESTS(); // This line shouldn't compile. -} - -#elif defined(TEST_USER_CANNOT_INCLUDE_GTEST_INTERNAL_INL_H) -// Tests that a user cannot include gtest-internal-inl.h in his code. - -#include "src/gtest-internal-inl.h" - -#elif defined(TEST_CATCHES_DECLARING_SETUP_IN_TEST_FIXTURE_WITH_TYPO) -// Tests that the compiler catches the typo when a user declares a -// Setup() method in a test fixture. - -#include "gtest/gtest.h" - -class MyTest : public testing::Test { - protected: - void Setup() {} -}; - -#elif defined(TEST_CATCHES_CALLING_SETUP_IN_TEST_WITH_TYPO) -// Tests that the compiler catches the typo when a user calls Setup() -// from a test fixture. - -#include "gtest/gtest.h" - -class MyTest : public testing::Test { - protected: - virtual void SetUp() { - testing::Test::Setup(); // Tries to call SetUp() in the parent class. - } -}; - -#elif defined(TEST_CATCHES_DECLARING_SETUP_IN_ENVIRONMENT_WITH_TYPO) -// Tests that the compiler catches the typo when a user declares a -// Setup() method in a subclass of Environment. - -#include "gtest/gtest.h" - -class MyEnvironment : public testing::Environment { - public: - void Setup() {} -}; - -#elif defined(TEST_CATCHES_CALLING_SETUP_IN_ENVIRONMENT_WITH_TYPO) -// Tests that the compiler catches the typo when a user calls Setup() -// in an Environment. - -#include "gtest/gtest.h" - -class MyEnvironment : public testing::Environment { - protected: - virtual void SetUp() { - // Tries to call SetUp() in the parent class. - testing::Environment::Setup(); - } -}; - -#elif defined(TEST_CATCHES_WRONG_CASE_IN_TYPED_TEST_P) -// Tests that the compiler catches using the wrong test case name in -// TYPED_TEST_P. - -#include "gtest/gtest.h" - -template -class FooTest : public testing::Test { -}; - -template -class BarTest : public testing::Test { -}; - -TYPED_TEST_CASE_P(FooTest); -TYPED_TEST_P(BarTest, A) {} // Wrong test case name. -REGISTER_TYPED_TEST_CASE_P(FooTest, A); -INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, testing::Types); - -#elif defined(TEST_CATCHES_WRONG_CASE_IN_REGISTER_TYPED_TEST_CASE_P) -// Tests that the compiler catches using the wrong test case name in -// REGISTER_TYPED_TEST_CASE_P. - -#include "gtest/gtest.h" - -template -class FooTest : public testing::Test { -}; - -template -class BarTest : public testing::Test { -}; - -TYPED_TEST_CASE_P(FooTest); -TYPED_TEST_P(FooTest, A) {} -REGISTER_TYPED_TEST_CASE_P(BarTest, A); // Wrong test case name. -INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, testing::Types); - -#elif defined(TEST_CATCHES_WRONG_CASE_IN_INSTANTIATE_TYPED_TEST_CASE_P) -// Tests that the compiler catches using the wrong test case name in -// INSTANTIATE_TYPED_TEST_CASE_P. - -#include "gtest/gtest.h" - -template -class FooTest : public testing::Test { -}; - -template -class BarTest : public testing::Test { -}; - -TYPED_TEST_CASE_P(FooTest); -TYPED_TEST_P(FooTest, A) {} -REGISTER_TYPED_TEST_CASE_P(FooTest, A); - -// Wrong test case name. -INSTANTIATE_TYPED_TEST_CASE_P(My, BarTest, testing::Types); - -#elif defined(TEST_CATCHES_INSTANTIATE_TYPED_TESET_CASE_P_WITH_SAME_NAME_PREFIX) -// Tests that the compiler catches instantiating TYPED_TEST_CASE_P -// twice with the same name prefix. - -#include "gtest/gtest.h" - -template -class FooTest : public testing::Test { -}; - -TYPED_TEST_CASE_P(FooTest); -TYPED_TEST_P(FooTest, A) {} -REGISTER_TYPED_TEST_CASE_P(FooTest, A); - -INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, testing::Types); - -// Wrong name prefix: "My" has been used. -INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, testing::Types); - -#elif defined(TEST_STATIC_ASSERT_TYPE_EQ_IS_NOT_A_TYPE) - -#include "gtest/gtest.h" - -// Tests that StaticAssertTypeEq cannot be used as a type. -testing::StaticAssertTypeEq dummy; - -#elif defined(TEST_STATIC_ASSERT_TYPE_EQ_WORKS_IN_NAMESPACE) - -#include "gtest/gtest.h" - -// Tests that StaticAssertTypeEq works in a namespace scope. -static bool dummy = testing::StaticAssertTypeEq(); - -#elif defined(TEST_STATIC_ASSERT_TYPE_EQ_WORKS_IN_CLASS) - -#include "gtest/gtest.h" - -template -class Helper { - public: - // Tests that StaticAssertTypeEq works in a class. - Helper() { testing::StaticAssertTypeEq(); } - - void DoSomething() {} -}; - -void Test() { - Helper h; - h.DoSomething(); // To avoid the "unused variable" warning. -} - -#elif defined(TEST_STATIC_ASSERT_TYPE_EQ_WORKS_IN_FUNCTION) - -#include "gtest/gtest.h" - -void Test() { - // Tests that StaticAssertTypeEq works inside a function. - testing::StaticAssertTypeEq(); -} - -#else -// A sanity test. This should compile. - -#include "gtest/gtest.h" - -int main() { - return RUN_ALL_TESTS(); -} - -#endif diff --git a/test/gtest_nc_test.py b/test/gtest_nc_test.py deleted file mode 100755 index c60b96e5..00000000 --- a/test/gtest_nc_test.py +++ /dev/null @@ -1,115 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2007, 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. - -"""Negative compilation test for Google Test.""" - -__author__ = 'wan@google.com (Zhanyong Wan)' - -import os -import sys -import unittest - - -IS_LINUX = os.name == 'posix' and os.uname()[0] == 'Linux' -if not IS_LINUX: - sys.exit(0) # Negative compilation tests are not supported on Windows & Mac. - - -class GTestNCTest(unittest.TestCase): - """Negative compilation test for Google Test.""" - - # The class body is intentionally empty. The actual test*() methods - # will be defined at run time by a call to - # DefineNegativeCompilationTests() later. - pass - -# Defines a list of test specs, where each element is a tuple -# (test name, list of regexes for matching the compiler errors). -TEST_SPECS = [ - ('CANNOT_IGNORE_RUN_ALL_TESTS_RESULT', - [r'ignoring return value']), - - ('USER_CANNOT_INCLUDE_GTEST_INTERNAL_INL_H', - [r'must not be included except by Google Test itself']), - - ('CATCHES_DECLARING_SETUP_IN_TEST_FIXTURE_WITH_TYPO', - [r'Setup_should_be_spelled_SetUp']), - - ('CATCHES_CALLING_SETUP_IN_TEST_WITH_TYPO', - [r'Setup_should_be_spelled_SetUp']), - - ('CATCHES_DECLARING_SETUP_IN_ENVIRONMENT_WITH_TYPO', - [r'Setup_should_be_spelled_SetUp']), - - ('CATCHES_CALLING_SETUP_IN_ENVIRONMENT_WITH_TYPO', - [r'Setup_should_be_spelled_SetUp']), - - ('CATCHES_WRONG_CASE_IN_TYPED_TEST_P', - [r'BarTest.*was not declared', # GCC - r'undeclared identifier .*BarTest', # Clang - ]), - - ('CATCHES_WRONG_CASE_IN_REGISTER_TYPED_TEST_CASE_P', - [r'BarTest.*was not declared', # GCC - r'undeclared identifier .*BarTest', # Clang - ]), - - ('CATCHES_WRONG_CASE_IN_INSTANTIATE_TYPED_TEST_CASE_P', - [r'BarTest.*not declared', # GCC - r'undeclared identifier .*BarTest', # Clang - ]), - - ('CATCHES_INSTANTIATE_TYPED_TESET_CASE_P_WITH_SAME_NAME_PREFIX', - [r'redefinition of.*My.*FooTest']), - - ('STATIC_ASSERT_TYPE_EQ_IS_NOT_A_TYPE', - [r'StaticAssertTypeEq.* does not name a type', # GCC - r'requires a type.*\n.*StaticAssertTypeEq', # Clang - ]), - - ('STATIC_ASSERT_TYPE_EQ_WORKS_IN_NAMESPACE', - [r'StaticAssertTypeEq.*int.*const int']), - - ('STATIC_ASSERT_TYPE_EQ_WORKS_IN_CLASS', - [r'StaticAssertTypeEq.*int.*bool']), - - ('STATIC_ASSERT_TYPE_EQ_WORKS_IN_FUNCTION', - [r'StaticAssertTypeEq.*const int.*int']), - - ('SANITY', - None) - ] - -# TODO(wan@google.com): verify that the test specs are satisfied. - - -if __name__ == '__main__': - unittest.main() -- cgit v1.2.3 From 48b1315108cdba8f37394aedb8098102ca00e8b9 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Mon, 10 Jan 2011 18:17:59 +0000 Subject: Fixes GCC 4.6 warnings (patch by Jeffrey Yasskin). --- test/gtest-port_test.cc | 1 + test/gtest_unittest.cc | 18 ++++++++++-------- 2 files changed, 11 insertions(+), 8 deletions(-) (limited to 'test') diff --git a/test/gtest-port_test.cc b/test/gtest-port_test.cc index bf42d8b8..db63ea98 100644 --- a/test/gtest-port_test.cc +++ b/test/gtest-port_test.cc @@ -168,6 +168,7 @@ class To { TEST(ImplicitCastTest, CanUseImplicitConstructor) { bool converted = false; To to = ::testing::internal::implicit_cast(&converted); + (void)to; EXPECT_TRUE(converted); } diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index 89a4a0e7..1069ecf8 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -322,13 +322,11 @@ TEST(NullLiteralTest, IsTrueForNullLiterals) { EXPECT_TRUE(GTEST_IS_NULL_LITERAL_(0)); EXPECT_TRUE(GTEST_IS_NULL_LITERAL_(0U)); EXPECT_TRUE(GTEST_IS_NULL_LITERAL_(0L)); - EXPECT_TRUE(GTEST_IS_NULL_LITERAL_(false)); #ifndef __BORLANDC__ // Some compilers may fail to detect some null pointer literals; // as long as users of the framework don't use such literals, this // is harmless. EXPECT_TRUE(GTEST_IS_NULL_LITERAL_(1 - 1)); - EXPECT_TRUE(GTEST_IS_NULL_LITERAL_(true && false)); #endif } @@ -3731,7 +3729,8 @@ TEST(AssertionTest, ASSERT_ANY_THROW) { // compile. TEST(AssertionTest, AssertPrecedence) { ASSERT_EQ(1 < 2, true); - ASSERT_EQ(true && false, false); + bool false_value = false; + ASSERT_EQ(true && false_value, false); } // A subroutine used by the following test. @@ -4220,7 +4219,7 @@ TEST(ExpectTest, EXPECT_EQ_Double) { TEST(ExpectTest, EXPECT_EQ_NULL) { // A success. const char* p = NULL; - // Some older GCC versions may issue a spurious waring in this or the next + // Some older GCC versions may issue a spurious warning in this or the next // assertion statement. This warning should not be suppressed with // static_cast since the test verifies the ability to use bare NULL as the // expected parameter to the macro. @@ -4490,8 +4489,10 @@ TEST(MacroTest, SUCCEED) { // Tests using bool values in {EXPECT|ASSERT}_EQ. TEST(EqAssertionTest, Bool) { EXPECT_EQ(true, true); - EXPECT_FATAL_FAILURE(ASSERT_EQ(false, true), - "Value of: true"); + EXPECT_FATAL_FAILURE({ + bool false_value = false; + ASSERT_EQ(false_value, true); + }, "Value of: true"); } // Tests using int values in {EXPECT|ASSERT}_EQ. @@ -6470,8 +6471,9 @@ TEST(ColoredOutputTest, UsesColorsWhenTermSupportsColors) { // Verifies that StaticAssertTypeEq works in a namespace scope. -static bool dummy1 = StaticAssertTypeEq(); -static bool dummy2 = StaticAssertTypeEq(); +static bool dummy1 GTEST_ATTRIBUTE_UNUSED_ = StaticAssertTypeEq(); +static bool dummy2 GTEST_ATTRIBUTE_UNUSED_ = + StaticAssertTypeEq(); // Verifies that StaticAssertTypeEq works in a class. -- cgit v1.2.3 From a198966dd349f446f0ab065e5576db7ac1e48e63 Mon Sep 17 00:00:00 2001 From: vladlosev Date: Sat, 29 Jan 2011 16:15:40 +0000 Subject: Renames some internal functions to avoid name clashes. --- test/gtest-port_test.cc | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'test') diff --git a/test/gtest-port_test.cc b/test/gtest-port_test.cc index db63ea98..5afba2d8 100644 --- a/test/gtest-port_test.cc +++ b/test/gtest-port_test.cc @@ -79,12 +79,12 @@ class Derived : public Base { TEST(ImplicitCastTest, ConvertsPointers) { Derived derived(0); - EXPECT_TRUE(&derived == ::testing::internal::implicit_cast(&derived)); + EXPECT_TRUE(&derived == ::testing::internal::ImplicitCast_(&derived)); } TEST(ImplicitCastTest, CanUseInheritance) { Derived derived(1); - Base base = ::testing::internal::implicit_cast(derived); + Base base = ::testing::internal::ImplicitCast_(derived); EXPECT_EQ(derived.member(), base.member()); } @@ -103,7 +103,7 @@ class Castable { TEST(ImplicitCastTest, CanUseNonConstCastOperator) { bool converted = false; Castable castable(&converted); - Base base = ::testing::internal::implicit_cast(castable); + Base base = ::testing::internal::ImplicitCast_(castable); EXPECT_TRUE(converted); } @@ -122,7 +122,7 @@ class ConstCastable { TEST(ImplicitCastTest, CanUseConstCastOperatorOnConstValues) { bool converted = false; const ConstCastable const_castable(&converted); - Base base = ::testing::internal::implicit_cast(const_castable); + Base base = ::testing::internal::ImplicitCast_(const_castable); EXPECT_TRUE(converted); } @@ -148,14 +148,14 @@ TEST(ImplicitCastTest, CanSelectBetweenConstAndNonConstCasrAppropriately) { bool converted = false; bool const_converted = false; ConstAndNonConstCastable castable(&converted, &const_converted); - Base base = ::testing::internal::implicit_cast(castable); + Base base = ::testing::internal::ImplicitCast_(castable); EXPECT_TRUE(converted); EXPECT_FALSE(const_converted); converted = false; const_converted = false; const ConstAndNonConstCastable const_castable(&converted, &const_converted); - base = ::testing::internal::implicit_cast(const_castable); + base = ::testing::internal::ImplicitCast_(const_castable); EXPECT_FALSE(converted); EXPECT_TRUE(const_converted); } @@ -167,7 +167,7 @@ class To { TEST(ImplicitCastTest, CanUseImplicitConstructor) { bool converted = false; - To to = ::testing::internal::implicit_cast(&converted); + To to = ::testing::internal::ImplicitCast_(&converted); (void)to; EXPECT_TRUE(converted); } -- cgit v1.2.3 From 9bcf4d0a654b27732e2fa901fe98c09aba71773a Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Wed, 2 Feb 2011 00:49:33 +0000 Subject: Adds type_param and value_param as attributes to the XML report; also removes the comment() and test_case_comment() fields of TestInfo. Proposed and initally implemented by Joey Oravec. Re-implemented by Vlad Losev. --- test/gtest-param-test_test.cc | 14 +++----- test/gtest-unittest-api_test.cc | 69 +++++++++++++++++++------------------- test/gtest_xml_output_unittest.py | 20 ++++++++++- test/gtest_xml_output_unittest_.cc | 37 +++++++++++++++++--- test/gtest_xml_test_utils.py | 11 ++++-- 5 files changed, 100 insertions(+), 51 deletions(-) (limited to 'test') diff --git a/test/gtest-param-test_test.cc b/test/gtest-param-test_test.cc index acd269bc..5a681d83 100644 --- a/test/gtest-param-test_test.cc +++ b/test/gtest-param-test_test.cc @@ -792,19 +792,17 @@ INSTANTIATE_TEST_CASE_P(FourElemSequence, SeparateInstanceTest, Range(1, 4)); // sequence element used to instantiate the test. class NamingTest : public TestWithParam {}; -TEST_P(NamingTest, TestsAreNamedAndCommentedCorrectly) { +TEST_P(NamingTest, TestsReportCorrectNamesAndParameters) { const ::testing::TestInfo* const test_info = ::testing::UnitTest::GetInstance()->current_test_info(); EXPECT_STREQ("ZeroToFiveSequence/NamingTest", test_info->test_case_name()); Message index_stream; - index_stream << "TestsAreNamedAndCommentedCorrectly/" << GetParam(); + index_stream << "TestsReportCorrectNamesAndParameters/" << GetParam(); EXPECT_STREQ(index_stream.GetString().c_str(), test_info->name()); - const ::std::string comment = - "GetParam() = " + ::testing::PrintToString(GetParam()); - EXPECT_EQ(comment, test_info->comment()); + EXPECT_EQ(::testing::PrintToString(GetParam()), test_info->value_param()); } INSTANTIATE_TEST_CASE_P(ZeroToFiveSequence, NamingTest, Range(0, 5)); @@ -823,13 +821,11 @@ class Unstreamable { class CommentTest : public TestWithParam {}; -TEST_P(CommentTest, TestsWithUnstreamableParamsCommentedCorrectly) { +TEST_P(CommentTest, TestsCorrectlyReportUnstreamableParams) { const ::testing::TestInfo* const test_info = ::testing::UnitTest::GetInstance()->current_test_info(); - const ::std::string comment = - "GetParam() = " + ::testing::PrintToString(GetParam()); - EXPECT_EQ(comment, test_info->comment()); + EXPECT_EQ(::testing::PrintToString(GetParam()), test_info->value_param()); } INSTANTIATE_TEST_CASE_P(InstantiationWithComments, diff --git a/test/gtest-unittest-api_test.cc b/test/gtest-unittest-api_test.cc index ed5dea83..f53e2744 100644 --- a/test/gtest-unittest-api_test.cc +++ b/test/gtest-unittest-api_test.cc @@ -37,6 +37,7 @@ #include // For strcmp. #include +#include using ::testing::InitGoogleTest; @@ -103,12 +104,6 @@ TYPED_TEST(TestCaseWithCommentTest, Dummy) {} const int kTypedTestCases = 1; const int kTypedTests = 1; - -String GetExpectedTestCaseComment() { - Message comment; - comment << "TypeParam = " << GetTypeName().c_str(); - return comment.GetString(); -} #else const int kTypedTestCases = 0; const int kTypedTests = 0; @@ -143,12 +138,19 @@ TEST(ApiTest, UnitTestImmutableAccessorsWork) { RecordProperty("key", "value"); } +AssertionResult IsNull(const char* str) { + if (str != NULL) { + return testing::AssertionFailure() << "argument is " << str; + } + return AssertionSuccess(); +} + TEST(ApiTest, TestCaseImmutableAccessorsWork) { const TestCase* test_case = UnitTestHelper::FindTestCase("ApiTest"); ASSERT_TRUE(test_case != NULL); EXPECT_STREQ("ApiTest", test_case->name()); - EXPECT_STREQ("", test_case->comment()); + EXPECT_TRUE(IsNull(test_case->type_param())); EXPECT_TRUE(test_case->should_run()); EXPECT_EQ(1, test_case->disabled_test_count()); EXPECT_EQ(3, test_case->test_to_run_count()); @@ -158,26 +160,26 @@ TEST(ApiTest, TestCaseImmutableAccessorsWork) { EXPECT_STREQ("DISABLED_Dummy1", tests[0]->name()); EXPECT_STREQ("ApiTest", tests[0]->test_case_name()); - EXPECT_STREQ("", tests[0]->comment()); - EXPECT_STREQ("", tests[0]->test_case_comment()); + EXPECT_TRUE(IsNull(tests[0]->value_param())); + EXPECT_TRUE(IsNull(tests[0]->type_param())); EXPECT_FALSE(tests[0]->should_run()); EXPECT_STREQ("TestCaseDisabledAccessorsWork", tests[1]->name()); EXPECT_STREQ("ApiTest", tests[1]->test_case_name()); - EXPECT_STREQ("", tests[1]->comment()); - EXPECT_STREQ("", tests[1]->test_case_comment()); + EXPECT_TRUE(IsNull(tests[1]->value_param())); + EXPECT_TRUE(IsNull(tests[1]->type_param())); EXPECT_TRUE(tests[1]->should_run()); EXPECT_STREQ("TestCaseImmutableAccessorsWork", tests[2]->name()); EXPECT_STREQ("ApiTest", tests[2]->test_case_name()); - EXPECT_STREQ("", tests[2]->comment()); - EXPECT_STREQ("", tests[2]->test_case_comment()); + EXPECT_TRUE(IsNull(tests[2]->value_param())); + EXPECT_TRUE(IsNull(tests[2]->type_param())); EXPECT_TRUE(tests[2]->should_run()); EXPECT_STREQ("UnitTestImmutableAccessorsWork", tests[3]->name()); EXPECT_STREQ("ApiTest", tests[3]->test_case_name()); - EXPECT_STREQ("", tests[3]->comment()); - EXPECT_STREQ("", tests[3]->test_case_comment()); + EXPECT_TRUE(IsNull(tests[3]->value_param())); + EXPECT_TRUE(IsNull(tests[3]->type_param())); EXPECT_TRUE(tests[3]->should_run()); delete[] tests; @@ -188,7 +190,7 @@ TEST(ApiTest, TestCaseImmutableAccessorsWork) { ASSERT_TRUE(test_case != NULL); EXPECT_STREQ("TestCaseWithCommentTest/0", test_case->name()); - EXPECT_STREQ(GetExpectedTestCaseComment().c_str(), test_case->comment()); + EXPECT_STREQ(GetTypeName().c_str(), test_case->type_param()); EXPECT_TRUE(test_case->should_run()); EXPECT_EQ(0, test_case->disabled_test_count()); EXPECT_EQ(1, test_case->test_to_run_count()); @@ -198,9 +200,8 @@ TEST(ApiTest, TestCaseImmutableAccessorsWork) { EXPECT_STREQ("Dummy", tests[0]->name()); EXPECT_STREQ("TestCaseWithCommentTest/0", tests[0]->test_case_name()); - EXPECT_STREQ("", tests[0]->comment()); - EXPECT_STREQ(GetExpectedTestCaseComment().c_str(), - tests[0]->test_case_comment()); + EXPECT_TRUE(IsNull(tests[0]->value_param())); + EXPECT_STREQ(GetTypeName().c_str(), tests[0]->type_param()); EXPECT_TRUE(tests[0]->should_run()); delete[] tests; @@ -212,7 +213,7 @@ TEST(ApiTest, TestCaseDisabledAccessorsWork) { ASSERT_TRUE(test_case != NULL); EXPECT_STREQ("DISABLED_Test", test_case->name()); - EXPECT_STREQ("", test_case->comment()); + EXPECT_TRUE(IsNull(test_case->type_param())); EXPECT_FALSE(test_case->should_run()); EXPECT_EQ(1, test_case->disabled_test_count()); EXPECT_EQ(0, test_case->test_to_run_count()); @@ -221,8 +222,8 @@ TEST(ApiTest, TestCaseDisabledAccessorsWork) { const TestInfo* const test_info = test_case->GetTestInfo(0); EXPECT_STREQ("Dummy2", test_info->name()); EXPECT_STREQ("DISABLED_Test", test_info->test_case_name()); - EXPECT_STREQ("", test_info->comment()); - EXPECT_STREQ("", test_info->test_case_comment()); + EXPECT_TRUE(IsNull(test_info->value_param())); + EXPECT_TRUE(IsNull(test_info->type_param())); EXPECT_FALSE(test_info->should_run()); } @@ -247,7 +248,7 @@ class FinalSuccessChecker : public Environment { const TestCase** const test_cases = UnitTestHelper::GetSortedTestCases(); EXPECT_STREQ("ApiTest", test_cases[0]->name()); - EXPECT_STREQ("", test_cases[0]->comment()); + EXPECT_TRUE(IsNull(test_cases[0]->type_param())); EXPECT_TRUE(test_cases[0]->should_run()); EXPECT_EQ(1, test_cases[0]->disabled_test_count()); ASSERT_EQ(4, test_cases[0]->total_test_count()); @@ -257,7 +258,7 @@ class FinalSuccessChecker : public Environment { EXPECT_FALSE(test_cases[0]->Failed()); EXPECT_STREQ("DISABLED_Test", test_cases[1]->name()); - EXPECT_STREQ("", test_cases[1]->comment()); + EXPECT_TRUE(IsNull(test_cases[1]->type_param())); EXPECT_FALSE(test_cases[1]->should_run()); EXPECT_EQ(1, test_cases[1]->disabled_test_count()); ASSERT_EQ(1, test_cases[1]->total_test_count()); @@ -266,8 +267,7 @@ class FinalSuccessChecker : public Environment { #if GTEST_HAS_TYPED_TEST EXPECT_STREQ("TestCaseWithCommentTest/0", test_cases[2]->name()); - EXPECT_STREQ(GetExpectedTestCaseComment().c_str(), - test_cases[2]->comment()); + EXPECT_STREQ(GetTypeName().c_str(), test_cases[2]->type_param()); EXPECT_TRUE(test_cases[2]->should_run()); EXPECT_EQ(0, test_cases[2]->disabled_test_count()); ASSERT_EQ(1, test_cases[2]->total_test_count()); @@ -285,24 +285,24 @@ class FinalSuccessChecker : public Environment { EXPECT_STREQ("TestCaseDisabledAccessorsWork", tests[1]->name()); EXPECT_STREQ("ApiTest", tests[1]->test_case_name()); - EXPECT_STREQ("", tests[1]->comment()); - EXPECT_STREQ("", tests[1]->test_case_comment()); + EXPECT_TRUE(IsNull(tests[1]->value_param())); + EXPECT_TRUE(IsNull(tests[1]->type_param())); EXPECT_TRUE(tests[1]->should_run()); EXPECT_TRUE(tests[1]->result()->Passed()); EXPECT_EQ(0, tests[1]->result()->test_property_count()); EXPECT_STREQ("TestCaseImmutableAccessorsWork", tests[2]->name()); EXPECT_STREQ("ApiTest", tests[2]->test_case_name()); - EXPECT_STREQ("", tests[2]->comment()); - EXPECT_STREQ("", tests[2]->test_case_comment()); + EXPECT_TRUE(IsNull(tests[2]->value_param())); + EXPECT_TRUE(IsNull(tests[2]->type_param())); EXPECT_TRUE(tests[2]->should_run()); EXPECT_TRUE(tests[2]->result()->Passed()); EXPECT_EQ(0, tests[2]->result()->test_property_count()); EXPECT_STREQ("UnitTestImmutableAccessorsWork", tests[3]->name()); EXPECT_STREQ("ApiTest", tests[3]->test_case_name()); - EXPECT_STREQ("", tests[3]->comment()); - EXPECT_STREQ("", tests[3]->test_case_comment()); + EXPECT_TRUE(IsNull(tests[3]->value_param())); + EXPECT_TRUE(IsNull(tests[3]->type_param())); EXPECT_TRUE(tests[3]->should_run()); EXPECT_TRUE(tests[3]->result()->Passed()); EXPECT_EQ(1, tests[3]->result()->test_property_count()); @@ -318,9 +318,8 @@ class FinalSuccessChecker : public Environment { EXPECT_STREQ("Dummy", tests[0]->name()); EXPECT_STREQ("TestCaseWithCommentTest/0", tests[0]->test_case_name()); - EXPECT_STREQ("", tests[0]->comment()); - EXPECT_STREQ(GetExpectedTestCaseComment().c_str(), - tests[0]->test_case_comment()); + EXPECT_TRUE(IsNull(tests[0]->value_param())); + EXPECT_STREQ(GetTypeName().c_str(), tests[0]->type_param()); EXPECT_TRUE(tests[0]->should_run()); EXPECT_TRUE(tests[0]->result()->Passed()); EXPECT_EQ(0, tests[0]->result()->test_property_count()); diff --git a/test/gtest_xml_output_unittest.py b/test/gtest_xml_output_unittest.py index 6d44929c..bdd50353 100755 --- a/test/gtest_xml_output_unittest.py +++ b/test/gtest_xml_output_unittest.py @@ -54,7 +54,7 @@ else: STACK_TRACE_TEMPLATE = "" EXPECTED_NON_EMPTY_XML = """ - + @@ -105,6 +105,24 @@ Invalid characters in brackets []%(stack)s]]> + + + + + + + + + + + + + + + + + + """ % {'stack': STACK_TRACE_TEMPLATE} diff --git a/test/gtest_xml_output_unittest_.cc b/test/gtest_xml_output_unittest_.cc index 693ffb99..741a8874 100644 --- a/test/gtest_xml_output_unittest_.cc +++ b/test/gtest_xml_output_unittest_.cc @@ -42,9 +42,13 @@ using ::testing::InitGoogleTest; using ::testing::TestEventListeners; +using ::testing::TestWithParam; using ::testing::UnitTest; +using ::testing::Test; +using ::testing::Types; +using ::testing::Values; -class SuccessfulTest : public testing::Test { +class SuccessfulTest : public Test { }; TEST_F(SuccessfulTest, Succeeds) { @@ -52,14 +56,14 @@ TEST_F(SuccessfulTest, Succeeds) { ASSERT_EQ(1, 1); } -class FailedTest : public testing::Test { +class FailedTest : public Test { }; TEST_F(FailedTest, Fails) { ASSERT_EQ(1, 2); } -class DisabledTest : public testing::Test { +class DisabledTest : public Test { }; TEST_F(DisabledTest, DISABLED_test_not_run) { @@ -91,7 +95,7 @@ TEST(InvalidCharactersTest, InvalidCharactersInMessage) { FAIL() << "Invalid characters in brackets [\x1\x2]"; } -class PropertyRecordingTest : public testing::Test { +class PropertyRecordingTest : public Test { }; TEST_F(PropertyRecordingTest, OneProperty) { @@ -134,6 +138,31 @@ TEST(NoFixtureTest, ExternalUtilityThatCallsRecordStringValuedProperty) { ExternalUtilityThatCallsRecordProperty("key_for_utility_string", "1"); } +// Verifies that the test parameter value is output in the 'value_param' +// XML attribute for value-parameterized tests. +class ValueParamTest : public TestWithParam {}; +TEST_P(ValueParamTest, HasValueParamAttribute) {} +TEST_P(ValueParamTest, AnotherTestThatHasValueParamAttribute) {} +INSTANTIATE_TEST_CASE_P(Single, ValueParamTest, Values(33, 42)); + +// Verifies that the type parameter name is output in the 'type_param' +// XML attribute for typed tests. +template class TypedTest : public Test {}; +typedef Types TypedTestTypes; +TYPED_TEST_CASE(TypedTest, TypedTestTypes); +TYPED_TEST(TypedTest, HasTypeParamAttribute) {} + +// Verifies that the type parameter name is output in the 'type_param' +// XML attribute for type-parameterized tests. +template class TypeParameterizedTestCase : public Test {}; +TYPED_TEST_CASE_P(TypeParameterizedTestCase); +TYPED_TEST_P(TypeParameterizedTestCase, HasTypeParamAttribute) {} +REGISTER_TYPED_TEST_CASE_P(TypeParameterizedTestCase, HasTypeParamAttribute); +typedef Types TypeParameterizedTestCaseTypes; +INSTANTIATE_TYPED_TEST_CASE_P(Single, + TypeParameterizedTestCase, + TypeParameterizedTestCaseTypes); + int main(int argc, char** argv) { InitGoogleTest(&argc, argv); diff --git a/test/gtest_xml_test_utils.py b/test/gtest_xml_test_utils.py index c83c3b7e..0f55c164 100755 --- a/test/gtest_xml_test_utils.py +++ b/test/gtest_xml_test_utils.py @@ -58,8 +58,9 @@ class GTestXMLTestCase(gtest_test_utils.TestCase): * It has the same tag name as expected_node. * It has the same set of attributes as expected_node, each with the same value as the corresponding attribute of expected_node. - An exception is any attribute named "time", which needs only be - convertible to a floating-point number. + Exceptions are any attribute named "time", which needs only be + convertible to a floating-point number and any attribute named + "type_param" which only has to be non-empty. * It has an equivalent set of child nodes (including elements and CDATA sections) as expected_node. Note that we ignore the order of the children as they are not guaranteed to be in any @@ -150,6 +151,9 @@ class GTestXMLTestCase(gtest_test_utils.TestCase): * The "time" attribute of , and elements is replaced with a single asterisk, if it contains only digit characters. + * The "type_param" attribute of elements is replaced with a + single asterisk (if it sn non-empty) as it is the type name returned + by the compiler and is platform dependent. * The line number reported in the first line of the "message" attribute of elements is replaced with a single asterisk. * The directory names in file paths are removed. @@ -159,6 +163,9 @@ class GTestXMLTestCase(gtest_test_utils.TestCase): if element.tagName in ("testsuites", "testsuite", "testcase"): time = element.getAttributeNode("time") time.value = re.sub(r"^\d+(\.\d+)?$", "*", time.value) + type_param = element.getAttributeNode("type_param") + if type_param and type_param.value: + type_param.value = "*" elif element.tagName == "failure": for child in element.childNodes: if child.nodeType == Node.CDATA_SECTION_NODE: -- cgit v1.2.3 From b147ec394bc024dc63860f0a982ecd82106b8e40 Mon Sep 17 00:00:00 2001 From: vladlosev Date: Wed, 2 Feb 2011 01:18:50 +0000 Subject: Removes unused include directive. --- test/gtest-unittest-api_test.cc | 1 - 1 file changed, 1 deletion(-) (limited to 'test') diff --git a/test/gtest-unittest-api_test.cc b/test/gtest-unittest-api_test.cc index f53e2744..07083e51 100644 --- a/test/gtest-unittest-api_test.cc +++ b/test/gtest-unittest-api_test.cc @@ -37,7 +37,6 @@ #include // For strcmp. #include -#include using ::testing::InitGoogleTest; -- cgit v1.2.3 From 40d0ba7a62a8bc749fbaf0747621b0aa10ddf1b9 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Wed, 2 Feb 2011 01:25:37 +0000 Subject: Add markers to death test messages to make them more recogizable (by Jeff Shute). --- test/gtest-death-test_test.cc | 62 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 59 insertions(+), 3 deletions(-) (limited to 'test') diff --git a/test/gtest-death-test_test.cc b/test/gtest-death-test_test.cc index b83b0db2..6cc017ba 100644 --- a/test/gtest-death-test_test.cc +++ b/test/gtest-death-test_test.cc @@ -103,9 +103,10 @@ class ReplaceDeathTestFactory { } // namespace internal } // namespace testing -void DieInside(const char* function) { - fprintf(stderr, "death inside %s().", function); - fflush(stderr); +void DieWithMessage(const ::std::string& message) { + fprintf(stderr, "%s", message.c_str()); + fflush(stderr); // Make sure the text is printed before the process exits. + // We call _exit() instead of exit(), as the former is a direct // system call and thus safer in the presence of threads. exit() // will invoke user-defined exit-hooks, which may do dangerous @@ -118,6 +119,10 @@ void DieInside(const char* function) { _exit(1); } +void DieInside(const ::std::string& function) { + DieWithMessage("death inside " + function + "()."); +} + // Tests that death tests work. class TestForDeathTest : public testing::Test { @@ -686,6 +691,57 @@ TEST_F(TestForDeathTest, InvalidStyle) { }, "This failure is expected."); } +TEST_F(TestForDeathTest, DeathTestFailedOutput) { + testing::GTEST_FLAG(death_test_style) = "fast"; + EXPECT_NONFATAL_FAILURE( + EXPECT_DEATH(DieWithMessage("death\n"), + "expected message"), + "Actual msg:\n" + "[ DEATH ] death\n"); +} + +TEST_F(TestForDeathTest, DeathTestUnexpectedReturnOutput) { + testing::GTEST_FLAG(death_test_style) = "fast"; + EXPECT_NONFATAL_FAILURE( + EXPECT_DEATH({ + fprintf(stderr, "returning\n"); + fflush(stderr); + return; + }, ""), + " Result: illegal return in test statement.\n" + " Error msg:\n" + "[ DEATH ] returning\n"); +} + +TEST_F(TestForDeathTest, DeathTestBadExitCodeOutput) { + testing::GTEST_FLAG(death_test_style) = "fast"; + EXPECT_NONFATAL_FAILURE( + EXPECT_EXIT(DieWithMessage("exiting with rc 1\n"), + testing::ExitedWithCode(3), + "expected message"), + " Result: died but not with expected exit code:\n" + " Exited with exit status 1\n" + "Actual msg:\n" + "[ DEATH ] exiting with rc 1\n"); +} + +TEST_F(TestForDeathTest, DeathTestMultiLineMatchFail) { + testing::GTEST_FLAG(death_test_style) = "fast"; + EXPECT_NONFATAL_FAILURE( + EXPECT_DEATH(DieWithMessage("line 1\nline 2\nline 3\n"), + "line 1\nxyz\nline 3\n"), + "Actual msg:\n" + "[ DEATH ] line 1\n" + "[ DEATH ] line 2\n" + "[ DEATH ] line 3\n"); +} + +TEST_F(TestForDeathTest, DeathTestMultiLineMatchPass) { + testing::GTEST_FLAG(death_test_style) = "fast"; + EXPECT_DEATH(DieWithMessage("line 1\nline 2\nline 3\n"), + "line 1\nline 2\nline 3\n"); +} + // A DeathTestFactory that returns MockDeathTests. class MockDeathTestFactory : public DeathTestFactory { public: -- cgit v1.2.3 From 9d7455f9844e293dff8b7902f0c2553094f2f976 Mon Sep 17 00:00:00 2001 From: vladlosev Date: Wed, 2 Feb 2011 10:07:04 +0000 Subject: Adds null check for file locations in XML output printer. --- test/gtest-port_test.cc | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) (limited to 'test') diff --git a/test/gtest-port_test.cc b/test/gtest-port_test.cc index 5afba2d8..be0f8b0a 100644 --- a/test/gtest-port_test.cc +++ b/test/gtest-port_test.cc @@ -209,6 +209,44 @@ TEST(GtestCheckSyntaxTest, WorksWithSwitch) { GTEST_CHECK_(true) << "Check failed in switch case"; } +// Verifies behavior of FormatFileLocation. +TEST(FormatFileLocationTest, FormatsFileLocation) { + EXPECT_PRED_FORMAT2(IsSubstring, "foo.cc", FormatFileLocation("foo.cc", 42)); + EXPECT_PRED_FORMAT2(IsSubstring, "42", FormatFileLocation("foo.cc", 42)); +} + +TEST(FormatFileLocationTest, FormatsUnknownFile) { + EXPECT_PRED_FORMAT2( + IsSubstring, "unknown file", FormatFileLocation(NULL, 42)); + EXPECT_PRED_FORMAT2(IsSubstring, "42", FormatFileLocation(NULL, 42)); +} + +TEST(FormatFileLocationTest, FormatsUknownLine) { + EXPECT_EQ("foo.cc:", FormatFileLocation("foo.cc", -1)); +} + +TEST(FormatFileLocationTest, FormatsUknownFileAndLine) { + EXPECT_EQ("unknown file:", FormatFileLocation(NULL, -1)); +} + +// Verifies behavior of FormatCompilerIndependentFileLocation. +TEST(FormatCompilerIndependentFileLocationTest, FormatsFileLocation) { + EXPECT_EQ("foo.cc:42", FormatCompilerIndependentFileLocation("foo.cc", 42)); +} + +TEST(FormatCompilerIndependentFileLocationTest, FormatsUknownFile) { + EXPECT_EQ("unknown file:42", + FormatCompilerIndependentFileLocation(NULL, 42)); +} + +TEST(FormatCompilerIndependentFileLocationTest, FormatsUknownLine) { + EXPECT_EQ("foo.cc", FormatCompilerIndependentFileLocation("foo.cc", -1)); +} + +TEST(FormatCompilerIndependentFileLocationTest, FormatsUknownFileAndLine) { + EXPECT_EQ("unknown file", FormatCompilerIndependentFileLocation(NULL, -1)); +} + #if GTEST_OS_MAC void* ThreadFunc(void* data) { pthread_mutex_t* mutex = static_cast(data); -- cgit v1.2.3 From 6642ca8cd46cf905b45e8f71532922df4d03800d Mon Sep 17 00:00:00 2001 From: vladlosev Date: Thu, 10 Feb 2011 23:14:49 +0000 Subject: Updates an outdated error message. --- test/gtest_test_utils.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'test') diff --git a/test/gtest_test_utils.py b/test/gtest_test_utils.py index e7ee9d9c..4e897bd3 100755 --- a/test/gtest_test_utils.py +++ b/test/gtest_test_utils.py @@ -162,11 +162,7 @@ def GetTestExecutablePath(executable_name, build_dir=None): message = ( 'Unable to find the test binary. Please make sure to provide path\n' 'to the binary via the --build_dir flag or the BUILD_DIR\n' - 'environment variable. For convenient use, invoke this script via\n' - 'mk_test.py.\n' - # TODO(vladl@google.com): change mk_test.py to test.py after renaming - # the file. - 'Please run mk_test.py -h for help.') + 'environment variable.') print >> sys.stderr, message sys.exit(1) -- cgit v1.2.3 From 0980b4bd66b496074d9e34d9f05244e700e9406d Mon Sep 17 00:00:00 2001 From: vladlosev Date: Sat, 12 Feb 2011 07:12:20 +0000 Subject: Fixes off-by-one error in a message about test sharding (by David Glasser). --- test/gtest_output_test_golden_lin.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'test') diff --git a/test/gtest_output_test_golden_lin.txt b/test/gtest_output_test_golden_lin.txt index 0ba9968c..a1d342d9 100644 --- a/test/gtest_output_test_golden_lin.txt +++ b/test/gtest_output_test_golden_lin.txt @@ -697,7 +697,7 @@ Note: Google Test filter = *DISABLED_* [==========] 1 test from 1 test case ran. [ PASSED ] 1 test. Note: Google Test filter = PassingTest.* -Note: This is test shard 1 of 2. +Note: This is test shard 2 of 2. [==========] Running 1 test from 1 test case. [----------] Global test environment set-up. [----------] 1 test from PassingTest -- cgit v1.2.3 From ffeb11d14a890b902dbb26ff2296cda7bf2d31df Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Tue, 22 Feb 2011 22:08:59 +0000 Subject: Indents preprocessor directives. --- test/gtest-death-test_ex_test.cc | 18 ++--- test/gtest-death-test_test.cc | 128 ++++++++++++++++++------------- test/gtest-filepath_test.cc | 20 +++-- test/gtest-options_test.cc | 4 +- test/gtest-param-test_test.cc | 32 ++++---- test/gtest-port_test.cc | 14 ++-- test/gtest-printers_test.cc | 8 +- test/gtest_break_on_failure_unittest_.cc | 10 ++- test/gtest_catch_exceptions_test_.cc | 6 +- test/gtest_output_test_.cc | 14 ++-- test/gtest_unittest.cc | 74 +++++++++++------- 11 files changed, 187 insertions(+), 141 deletions(-) (limited to 'test') diff --git a/test/gtest-death-test_ex_test.cc b/test/gtest-death-test_ex_test.cc index 71cc7a36..b50a13d5 100644 --- a/test/gtest-death-test_ex_test.cc +++ b/test/gtest-death-test_ex_test.cc @@ -36,15 +36,15 @@ #if GTEST_HAS_DEATH_TEST -#if GTEST_HAS_SEH -#include // For RaiseException(). -#endif +# if GTEST_HAS_SEH +# include // For RaiseException(). +# endif -#include "gtest/gtest-spi.h" +# include "gtest/gtest-spi.h" -#if GTEST_HAS_EXCEPTIONS +# if GTEST_HAS_EXCEPTIONS -#include // For std::exception. +# include // For std::exception. // Tests that death tests report thrown exceptions as failures and that the // exceptions do not escape death test macros. @@ -71,9 +71,9 @@ TEST(CxxExceptionDeathTest, PrintsMessageForStdExceptions) { EXPECT_NONFATAL_FAILURE(EXPECT_DEATH(throw TestException(), ""), "gtest-death-test_ex_test.cc"); } -#endif // GTEST_HAS_EXCEPTIONS +# endif // GTEST_HAS_EXCEPTIONS -#if GTEST_HAS_SEH +# if GTEST_HAS_SEH // Tests that enabling interception of SEH exceptions with the // catch_exceptions flag does not interfere with SEH exceptions being // treated as death by death tests. @@ -82,7 +82,7 @@ TEST(SehExceptionDeasTest, CatchExceptionsDoesNotInterfere) { << "with catch_exceptions " << (testing::GTEST_FLAG(catch_exceptions) ? "enabled" : "disabled"); } -#endif +# endif #endif // GTEST_HAS_DEATH_TEST diff --git a/test/gtest-death-test_test.cc b/test/gtest-death-test_test.cc index 6cc017ba..bcf8e2a3 100644 --- a/test/gtest-death-test_test.cc +++ b/test/gtest-death-test_test.cc @@ -40,28 +40,28 @@ using testing::internal::AlwaysTrue; #if GTEST_HAS_DEATH_TEST -#if GTEST_OS_WINDOWS -#include // For chdir(). -#else -#include -#include // For waitpid. -#include // For std::numeric_limits. -#endif // GTEST_OS_WINDOWS +# if GTEST_OS_WINDOWS +# include // For chdir(). +# else +# include +# include // For waitpid. +# include // For std::numeric_limits. +# endif // GTEST_OS_WINDOWS -#include -#include -#include +# include +# include +# include -#include "gtest/gtest-spi.h" +# include "gtest/gtest-spi.h" // Indicates that this translation unit is part of Google Test's // implementation. It must come before gtest-internal-inl.h is // included, or there will be a compiler error. This trick is to // prevent a user from accidentally including gtest-internal-inl.h in // his code. -#define GTEST_IMPLEMENTATION_ 1 -#include "src/gtest-internal-inl.h" -#undef GTEST_IMPLEMENTATION_ +# define GTEST_IMPLEMENTATION_ 1 +# include "src/gtest-internal-inl.h" +# undef GTEST_IMPLEMENTATION_ namespace posix = ::testing::internal::posix; @@ -195,13 +195,17 @@ void DeathTestSubroutine() { // Death in dbg, not opt. int DieInDebugElse12(int* sideeffect) { if (sideeffect) *sideeffect = 12; -#ifndef NDEBUG + +# ifndef NDEBUG + DieInside("DieInDebugElse12"); -#endif // NDEBUG + +# endif // NDEBUG + return 12; } -#if GTEST_OS_WINDOWS +# if GTEST_OS_WINDOWS // Tests the ExitedWithCode predicate. TEST(ExitStatusPredicateTest, ExitedWithCode) { @@ -214,7 +218,7 @@ TEST(ExitStatusPredicateTest, ExitedWithCode) { EXPECT_FALSE(testing::ExitedWithCode(1)(0)); } -#else +# else // Returns the exit status of a process that calls _exit(2) with a // given exit code. This is a helper function for the @@ -273,7 +277,7 @@ TEST(ExitStatusPredicateTest, KilledBySignal) { EXPECT_FALSE(pred_kill(status_segv)); } -#endif // GTEST_OS_WINDOWS +# endif // GTEST_OS_WINDOWS // Tests that the death test macros expand to code which may or may not // be followed by operator<<, and that in either case the complete text @@ -305,7 +309,7 @@ void DieWithEmbeddedNul() { _exit(1); } -#if GTEST_USES_PCRE +# if GTEST_USES_PCRE // Tests that EXPECT_DEATH and ASSERT_DEATH work when the error // message has a NUL character in it. TEST_F(TestForDeathTest, EmbeddedNulInMessage) { @@ -314,17 +318,17 @@ TEST_F(TestForDeathTest, EmbeddedNulInMessage) { EXPECT_DEATH(DieWithEmbeddedNul(), "my null world"); ASSERT_DEATH(DieWithEmbeddedNul(), "my null world"); } -#endif // GTEST_USES_PCRE +# endif // GTEST_USES_PCRE // Tests that death test macros expand to code which interacts well with switch // statements. TEST_F(TestForDeathTest, SwitchStatement) { // Microsoft compiler usually complains about switch statements without // case labels. We suppress that warning for this test. -#ifdef _MSC_VER -#pragma warning(push) -#pragma warning(disable: 4065) -#endif // _MSC_VER +# ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable: 4065) +# endif // _MSC_VER switch (0) default: @@ -334,9 +338,9 @@ TEST_F(TestForDeathTest, SwitchStatement) { case 0: EXPECT_DEATH(_exit(1), "") << "exit in switch case"; -#ifdef _MSC_VER -#pragma warning(pop) -#endif // _MSC_VER +# ifdef _MSC_VER +# pragma warning(pop) +# endif // _MSC_VER } // Tests that a static member function can be used in a "fast" style @@ -415,7 +419,7 @@ void SetPthreadFlag() { } // namespace -#if GTEST_HAS_CLONE && GTEST_HAS_PTHREAD +# if GTEST_HAS_CLONE && GTEST_HAS_PTHREAD TEST_F(TestForDeathTest, DoesNotExecuteAtforkHooks) { if (!testing::GTEST_FLAG(death_test_use_fork)) { @@ -427,7 +431,7 @@ TEST_F(TestForDeathTest, DoesNotExecuteAtforkHooks) { } } -#endif // GTEST_HAS_CLONE && GTEST_HAS_PTHREAD +# endif // GTEST_HAS_CLONE && GTEST_HAS_PTHREAD // Tests that a method of another class can be used in a death test. TEST_F(TestForDeathTest, MethodOfAnotherClass) { @@ -449,10 +453,12 @@ TEST_F(TestForDeathTest, AcceptsAnythingConvertibleToRE) { const testing::internal::RE regex(regex_c_str); EXPECT_DEATH(GlobalFunction(), regex); -#if GTEST_HAS_GLOBAL_STRING +# if GTEST_HAS_GLOBAL_STRING + const string regex_str(regex_c_str); EXPECT_DEATH(GlobalFunction(), regex_str); -#endif // GTEST_HAS_GLOBAL_STRING + +# endif // GTEST_HAS_GLOBAL_STRING const ::std::string regex_std_str(regex_c_str); EXPECT_DEATH(GlobalFunction(), regex_std_str); @@ -568,13 +574,17 @@ TEST_F(TestForDeathTest, TestExpectDebugDeath) { EXPECT_DEBUG_DEATH(DieInDebugElse12(&sideeffect), "death.*DieInDebugElse12"); -#ifdef NDEBUG +# ifdef NDEBUG + // Checks that the assignment occurs in opt mode (sideeffect). EXPECT_EQ(12, sideeffect); -#else + +# else + // Checks that the assignment does not occur in dbg mode (no sideeffect). EXPECT_EQ(0, sideeffect); -#endif + +# endif } // Tests that ASSERT_DEBUG_DEATH works as expected @@ -594,16 +604,20 @@ TEST_F(TestForDeathTest, TestAssertDebugDeath) { EXPECT_EQ(12, sideeffect); }, "death.*DieInDebugElse12"); -#ifdef NDEBUG +# ifdef NDEBUG + // Checks that the assignment occurs in opt mode (sideeffect). EXPECT_EQ(12, sideeffect); -#else + +# else + // Checks that the assignment does not occur in dbg mode (no sideeffect). EXPECT_EQ(0, sideeffect); -#endif + +# endif } -#ifndef NDEBUG +# ifndef NDEBUG void ExpectDebugDeathHelper(bool* aborted) { *aborted = true; @@ -611,7 +625,7 @@ void ExpectDebugDeathHelper(bool* aborted) { *aborted = false; } -#if GTEST_OS_WINDOWS +# if GTEST_OS_WINDOWS TEST(PopUpDeathTest, DoesNotShowPopUpOnAbort) { printf("This test should be considered failing if it shows " "any pop-up dialogs.\n"); @@ -622,7 +636,7 @@ TEST(PopUpDeathTest, DoesNotShowPopUpOnAbort) { abort(); }, ""); } -#endif // GTEST_OS_WINDOWS +# endif // GTEST_OS_WINDOWS // Tests that EXPECT_DEBUG_DEATH in debug mode does not abort // the function. @@ -647,19 +661,22 @@ TEST_F(TestForDeathTest, AssertDebugDeathAborts) { EXPECT_TRUE(aborted); } -#endif // _NDEBUG +# endif // _NDEBUG // Tests the *_EXIT family of macros, using a variety of predicates. static void TestExitMacros() { EXPECT_EXIT(_exit(1), testing::ExitedWithCode(1), ""); ASSERT_EXIT(_exit(42), testing::ExitedWithCode(42), ""); -#if GTEST_OS_WINDOWS +# if GTEST_OS_WINDOWS + // Of all signals effects on the process exit code, only those of SIGABRT // are documented on Windows. // See http://msdn.microsoft.com/en-us/library/dwwzkt4c(VS.71).aspx. EXPECT_EXIT(raise(SIGABRT), testing::ExitedWithCode(3), ""); -#else + +# else + EXPECT_EXIT(raise(SIGKILL), testing::KilledBySignal(SIGKILL), "") << "foo"; ASSERT_EXIT(raise(SIGUSR2), testing::KilledBySignal(SIGUSR2), "") << "bar"; @@ -667,7 +684,8 @@ static void TestExitMacros() { ASSERT_EXIT(_exit(0), testing::KilledBySignal(SIGSEGV), "") << "This failure is expected, too."; }, "This failure is expected, too."); -#endif // GTEST_OS_WINDOWS + +# endif // GTEST_OS_WINDOWS EXPECT_NONFATAL_FAILURE({ // NOLINT EXPECT_EXIT(raise(SIGSEGV), testing::ExitedWithCode(0), "") @@ -1022,7 +1040,7 @@ TEST(GetLastErrnoDescription, GetLastErrnoDescriptionWorks) { EXPECT_STREQ("", GetLastErrnoDescription().c_str()); } -#if GTEST_OS_WINDOWS +# if GTEST_OS_WINDOWS TEST(AutoHandleTest, AutoHandleWorks) { HANDLE handle = ::CreateEvent(NULL, FALSE, FALSE, NULL); ASSERT_NE(INVALID_HANDLE_VALUE, handle); @@ -1047,21 +1065,21 @@ TEST(AutoHandleTest, AutoHandleWorks) { testing::internal::AutoHandle auto_handle2; EXPECT_EQ(INVALID_HANDLE_VALUE, auto_handle2.Get()); } -#endif // GTEST_OS_WINDOWS +# endif // GTEST_OS_WINDOWS -#if GTEST_OS_WINDOWS +# if GTEST_OS_WINDOWS typedef unsigned __int64 BiggestParsable; typedef signed __int64 BiggestSignedParsable; const BiggestParsable kBiggestParsableMax = ULLONG_MAX; const BiggestSignedParsable kBiggestSignedParsableMax = LLONG_MAX; -#else +# else typedef unsigned long long BiggestParsable; typedef signed long long BiggestSignedParsable; const BiggestParsable kBiggestParsableMax = ::std::numeric_limits::max(); const BiggestSignedParsable kBiggestSignedParsableMax = ::std::numeric_limits::max(); -#endif // GTEST_OS_WINDOWS +# endif // GTEST_OS_WINDOWS TEST(ParseNaturalNumberTest, RejectsInvalidFormat) { BiggestParsable result = 0; @@ -1147,14 +1165,14 @@ TEST(ParseNaturalNumberTest, WorksForShorterIntegers) { EXPECT_EQ(123, char_result); } -#if GTEST_OS_WINDOWS +# if GTEST_OS_WINDOWS TEST(EnvironmentTest, HandleFitsIntoSizeT) { // TODO(vladl@google.com): Remove this test after this condition is verified // in a static assertion in gtest-death-test.cc in the function // GetStatusFileDescriptor. ASSERT_TRUE(sizeof(HANDLE) <= sizeof(size_t)); } -#endif // GTEST_OS_WINDOWS +# endif // GTEST_OS_WINDOWS // Tests that EXPECT_DEATH_IF_SUPPORTED/ASSERT_DEATH_IF_SUPPORTED trigger // failures when death tests are available on the system. @@ -1253,8 +1271,8 @@ TEST(ConditionalDeathMacrosSyntaxDeathTest, SwitchStatement) { // Microsoft compiler usually complains about switch statements without // case labels. We suppress that warning for this test. #ifdef _MSC_VER -#pragma warning(push) -#pragma warning(disable: 4065) +# pragma warning(push) +# pragma warning(disable: 4065) #endif // _MSC_VER switch (0) @@ -1267,7 +1285,7 @@ TEST(ConditionalDeathMacrosSyntaxDeathTest, SwitchStatement) { EXPECT_DEATH_IF_SUPPORTED(_exit(1), "") << "exit in switch case"; #ifdef _MSC_VER -#pragma warning(pop) +# pragma warning(pop) #endif // _MSC_VER } diff --git a/test/gtest-filepath_test.cc b/test/gtest-filepath_test.cc index 549dcef2..66d41184 100644 --- a/test/gtest-filepath_test.cc +++ b/test/gtest-filepath_test.cc @@ -51,9 +51,9 @@ #undef GTEST_IMPLEMENTATION_ #if GTEST_OS_WINDOWS_MOBILE -#include // NOLINT +# include // NOLINT #elif GTEST_OS_WINDOWS -#include // NOLINT +# include // NOLINT #endif // GTEST_OS_WINDOWS_MOBILE namespace testing { @@ -91,14 +91,18 @@ TEST(GetCurrentDirTest, ReturnsCurrentDir) { const FilePath cwd = FilePath::GetCurrentDir(); posix::ChDir(original_dir.c_str()); -#if GTEST_OS_WINDOWS +# if GTEST_OS_WINDOWS + // Skips the ":". const char* const cwd_without_drive = strchr(cwd.c_str(), ':'); ASSERT_TRUE(cwd_without_drive != NULL); EXPECT_STREQ(GTEST_PATH_SEP_, cwd_without_drive + 1); -#else + +# else + EXPECT_STREQ(GTEST_PATH_SEP_, cwd.c_str()); -#endif + +# endif } #endif // GTEST_OS_WINDOWS_MOBILE @@ -415,10 +419,12 @@ TEST(DirectoryTest, EmptyPathDirectoryDoesNotExist) { TEST(DirectoryTest, CurrentDirectoryExists) { #if GTEST_OS_WINDOWS // We are on Windows. -#ifndef _WIN32_CE // Windows CE doesn't have a current directory. +# ifndef _WIN32_CE // Windows CE doesn't have a current directory. + EXPECT_TRUE(FilePath(".").DirectoryExists()); EXPECT_TRUE(FilePath(".\\").DirectoryExists()); -#endif // _WIN32_CE + +# endif // _WIN32_CE #else EXPECT_TRUE(FilePath(".").DirectoryExists()); EXPECT_TRUE(FilePath("./").DirectoryExists()); diff --git a/test/gtest-options_test.cc b/test/gtest-options_test.cc index 30b82f3f..9e98f3f0 100644 --- a/test/gtest-options_test.cc +++ b/test/gtest-options_test.cc @@ -41,9 +41,9 @@ #include "gtest/gtest.h" #if GTEST_OS_WINDOWS_MOBILE -#include +# include #elif GTEST_OS_WINDOWS -#include +# include #endif // GTEST_OS_WINDOWS_MOBILE // Indicates that this translation unit is part of Google Test's diff --git a/test/gtest-param-test_test.cc b/test/gtest-param-test_test.cc index 5a681d83..94a53d9f 100644 --- a/test/gtest-param-test_test.cc +++ b/test/gtest-param-test_test.cc @@ -37,19 +37,19 @@ #if GTEST_HAS_PARAM_TEST -#include -#include -#include -#include -#include -#include +# include +# include +# include +# include +# include +# include // To include gtest-internal-inl.h. -#define GTEST_IMPLEMENTATION_ 1 -#include "src/gtest-internal-inl.h" // for UnitTestOptions -#undef GTEST_IMPLEMENTATION_ +# define GTEST_IMPLEMENTATION_ 1 +# include "src/gtest-internal-inl.h" // for UnitTestOptions +# undef GTEST_IMPLEMENTATION_ -#include "test/gtest-param-test_test.h" +# include "test/gtest-param-test_test.h" using ::std::vector; using ::std::sort; @@ -62,12 +62,12 @@ using ::testing::TestWithParam; using ::testing::Values; using ::testing::ValuesIn; -#if GTEST_HAS_COMBINE +# if GTEST_HAS_COMBINE using ::testing::Combine; using ::std::tr1::get; using ::std::tr1::make_tuple; using ::std::tr1::tuple; -#endif // GTEST_HAS_COMBINE +# endif // GTEST_HAS_COMBINE using ::testing::internal::ParamGenerator; using ::testing::internal::UnitTestOptions; @@ -85,7 +85,7 @@ template return stream.str(); } -#if GTEST_HAS_COMBINE +# if GTEST_HAS_COMBINE // These overloads allow printing tuples in our tests. We cannot // define an operator<< for tuples, as that definition needs to be in @@ -121,7 +121,7 @@ template #if GTEST_OS_MAC -#include +# include #endif // GTEST_OS_MAC #include // For std::pair and std::make_pair. @@ -328,15 +328,19 @@ TEST(GtestCheckDeathTest, LivesSilentlyOnSuccess) { // For simplicity, we only cover the most important platforms here. TEST(RegexEngineSelectionTest, SelectsCorrectRegexEngine) { #if GTEST_HAS_POSIX_RE + EXPECT_TRUE(GTEST_USES_POSIX_RE); + #else + EXPECT_TRUE(GTEST_USES_SIMPLE_RE); + #endif } #if GTEST_USES_POSIX_RE -#if GTEST_HAS_TYPED_TEST +# if GTEST_HAS_TYPED_TEST template class RETest : public ::testing::Test {}; @@ -345,9 +349,9 @@ class RETest : public ::testing::Test {}; // supports. typedef testing::Types< ::std::string, -#if GTEST_HAS_GLOBAL_STRING +# if GTEST_HAS_GLOBAL_STRING ::string, -#endif // GTEST_HAS_GLOBAL_STRING +# endif // GTEST_HAS_GLOBAL_STRING const char*> StringTypes; TYPED_TEST_CASE(RETest, StringTypes); @@ -398,7 +402,7 @@ TYPED_TEST(RETest, PartialMatchWorks) { EXPECT_FALSE(RE::PartialMatch(TypeParam("zza"), re)); } -#endif // GTEST_HAS_TYPED_TEST +# endif // GTEST_HAS_TYPED_TEST #elif GTEST_USES_SIMPLE_RE diff --git a/test/gtest-printers_test.cc b/test/gtest-printers_test.cc index da1fbc25..e11662ff 100644 --- a/test/gtest-printers_test.cc +++ b/test/gtest-printers_test.cc @@ -52,10 +52,10 @@ // hash_map and hash_set are available under Visual C++. #if _MSC_VER -#define GTEST_HAS_HASH_MAP_ 1 // Indicates that hash_map is available. -#include // NOLINT -#define GTEST_HAS_HASH_SET_ 1 // Indicates that hash_set is available. -#include // NOLINT +# define GTEST_HAS_HASH_MAP_ 1 // Indicates that hash_map is available. +# include // NOLINT +# define GTEST_HAS_HASH_SET_ 1 // Indicates that hash_set is available. +# include // NOLINT #endif // GTEST_OS_WINDOWS // Some user-defined types for testing the universal value printer. diff --git a/test/gtest_break_on_failure_unittest_.cc b/test/gtest_break_on_failure_unittest_.cc index 30755090..dd07478c 100644 --- a/test/gtest_break_on_failure_unittest_.cc +++ b/test/gtest_break_on_failure_unittest_.cc @@ -42,8 +42,8 @@ #include "gtest/gtest.h" #if GTEST_OS_WINDOWS -#include -#include +# include +# include #endif namespace { @@ -69,7 +69,8 @@ int main(int argc, char **argv) { // a general protection fault (segment violation). SetErrorMode(SEM_NOGPFAULTERRORBOX | SEM_FAILCRITICALERRORS); -#if GTEST_HAS_SEH && !GTEST_OS_WINDOWS_MOBILE +# if GTEST_HAS_SEH && !GTEST_OS_WINDOWS_MOBILE + // The default unhandled exception filter does not always exit // with the exception code as exit code - for example it exits with // 0 for EXCEPTION_ACCESS_VIOLATION and 1 for EXCEPTION_BREAKPOINT @@ -77,7 +78,8 @@ int main(int argc, char **argv) { // filter which always exits with the exception code for unhandled // exceptions. SetUnhandledExceptionFilter(ExitWithExceptionCode); -#endif + +# endif #endif testing::InitGoogleTest(&argc, argv); diff --git a/test/gtest_catch_exceptions_test_.cc b/test/gtest_catch_exceptions_test_.cc index 3cf75321..a35103f0 100644 --- a/test/gtest_catch_exceptions_test_.cc +++ b/test/gtest_catch_exceptions_test_.cc @@ -38,12 +38,12 @@ #include // For exit(). #if GTEST_HAS_SEH -#include +# include #endif #if GTEST_HAS_EXCEPTIONS -#include // For set_terminate(). -#include +# include // For set_terminate(). +# include #endif using testing::Test; diff --git a/test/gtest_output_test_.cc b/test/gtest_output_test_.cc index 47343e50..13dbec47 100644 --- a/test/gtest_output_test_.cc +++ b/test/gtest_output_test_.cc @@ -788,7 +788,7 @@ INSTANTIATE_TYPED_TEST_CASE_P(Unsigned, TypedTestP, UnsignedTypes); TEST(ADeathTest, ShouldRunFirst) { } -#if GTEST_HAS_TYPED_TEST +# if GTEST_HAS_TYPED_TEST // We rely on the golden file to verify that typed tests whose test // case name ends with DeathTest are run first. @@ -803,9 +803,9 @@ TYPED_TEST_CASE(ATypedDeathTest, NumericTypes); TYPED_TEST(ATypedDeathTest, ShouldRunFirst) { } -#endif // GTEST_HAS_TYPED_TEST +# endif // GTEST_HAS_TYPED_TEST -#if GTEST_HAS_TYPED_TEST_P +# if GTEST_HAS_TYPED_TEST_P // We rely on the golden file to verify that type-parameterized tests @@ -824,7 +824,7 @@ REGISTER_TYPED_TEST_CASE_P(ATypeParamDeathTest, ShouldRunFirst); INSTANTIATE_TYPED_TEST_CASE_P(My, ATypeParamDeathTest, NumericTypes); -#endif // GTEST_HAS_TYPED_TEST_P +# endif // GTEST_HAS_TYPED_TEST_P #endif // GTEST_HAS_DEATH_TEST @@ -998,11 +998,11 @@ int main(int argc, char **argv) { if (testing::internal::GTEST_FLAG(internal_run_death_test) != "") { // Skip the usual output capturing if we're running as the child // process of an threadsafe-style death test. -#if GTEST_OS_WINDOWS +# if GTEST_OS_WINDOWS posix::FReopen("nul:", "w", stdout); -#else +# else posix::FReopen("/dev/null", "w", stdout); -#endif // GTEST_OS_WINDOWS +# endif // GTEST_OS_WINDOWS return RUN_ALL_TESTS(); } #endif // GTEST_HAS_DEATH_TEST diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index 1069ecf8..3f0456e9 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -310,10 +310,10 @@ TEST(FormatTimeInMillisAsSecondsTest, FormatsNegativeNumber) { #if GTEST_CAN_COMPARE_NULL -#ifdef __BORLANDC__ +# ifdef __BORLANDC__ // Silences warnings: "Condition is always true", "Unreachable code" -#pragma option push -w-ccc -w-rch -#endif +# pragma option push -w-ccc -w-rch +# endif // Tests that GTEST_IS_NULL_LITERAL_(x) is true when x is a null // pointer literal. @@ -322,12 +322,15 @@ TEST(NullLiteralTest, IsTrueForNullLiterals) { EXPECT_TRUE(GTEST_IS_NULL_LITERAL_(0)); EXPECT_TRUE(GTEST_IS_NULL_LITERAL_(0U)); EXPECT_TRUE(GTEST_IS_NULL_LITERAL_(0L)); -#ifndef __BORLANDC__ + +# ifndef __BORLANDC__ + // Some compilers may fail to detect some null pointer literals; // as long as users of the framework don't use such literals, this // is harmless. EXPECT_TRUE(GTEST_IS_NULL_LITERAL_(1 - 1)); -#endif + +# endif } // Tests that GTEST_IS_NULL_LITERAL_(x) is false when x is not a null @@ -339,10 +342,10 @@ TEST(NullLiteralTest, IsFalseForNonNullLiterals) { EXPECT_FALSE(GTEST_IS_NULL_LITERAL_(static_cast(NULL))); } -#ifdef __BORLANDC__ +# ifdef __BORLANDC__ // Restores warnings after previous "#pragma option push" suppressed them. -#pragma option pop -#endif +# pragma option pop +# endif #endif // GTEST_CAN_COMPARE_NULL // @@ -1211,7 +1214,7 @@ TEST(StringTest, ShowWideCStringQuoted) { String::ShowWideCStringQuoted(L"foo").c_str()); } -#if GTEST_OS_WINDOWS_MOBILE +# if GTEST_OS_WINDOWS_MOBILE TEST(StringTest, AnsiAndUtf16Null) { EXPECT_EQ(NULL, String::AnsiToUtf16(NULL)); EXPECT_EQ(NULL, String::Utf16ToAnsi(NULL)); @@ -1234,7 +1237,7 @@ TEST(StringTest, AnsiAndUtf16ConvertPathChars) { EXPECT_EQ(0, wcsncmp(L".:\\ \"*?", utf16, 3)); delete [] utf16; } -#endif // GTEST_OS_WINDOWS_MOBILE +# endif // GTEST_OS_WINDOWS_MOBILE #endif // GTEST_OS_WINDOWS @@ -1368,7 +1371,7 @@ TEST_F(ExpectFatalFailureTest, CatchesFatalFailureOnAllThreads) { #ifdef __BORLANDC__ // Silences warnings: "Condition is always true" -#pragma option push -w-ccc +# pragma option push -w-ccc #endif // Tests that EXPECT_FATAL_FAILURE() can be used in a non-void @@ -1396,7 +1399,7 @@ void DoesNotAbortHelper(bool* aborted) { #ifdef __BORLANDC__ // Restores warnings after previous "#pragma option push" suppressed them. -#pragma option pop +# pragma option pop #endif TEST_F(ExpectFatalFailureTest, DoesNotAbort) { @@ -3534,7 +3537,7 @@ TEST(AssertionTest, AppendUserMessage) { #ifdef __BORLANDC__ // Silences warnings: "Condition is always true", "Unreachable code" -#pragma option push -w-ccc -w-rch +# pragma option push -w-ccc -w-rch #endif // Tests ASSERT_TRUE. @@ -3589,7 +3592,7 @@ TEST(AssertionTest, AssertFalseWithAssertionResult) { #ifdef __BORLANDC__ // Restores warnings after previous "#pragma option push" supressed them -#pragma option pop +# pragma option pop #endif // Tests using ASSERT_EQ on double values. The purpose is to make @@ -3692,13 +3695,14 @@ void ThrowNothing() {} TEST(AssertionTest, ASSERT_THROW) { ASSERT_THROW(ThrowAnInteger(), int); -#ifndef __BORLANDC__ +# ifndef __BORLANDC__ + // ICE's in C++Builder 2007 and 2009. EXPECT_FATAL_FAILURE( ASSERT_THROW(ThrowAnInteger(), bool), "Expected: ThrowAnInteger() throws an exception of type bool.\n" " Actual: it throws a different type."); -#endif +# endif EXPECT_FATAL_FAILURE( ASSERT_THROW(ThrowNothing(), bool), @@ -3826,7 +3830,9 @@ TEST(AssertionTest, NamedEnum) { // Tests using assertions with anonymous enums. enum { kCaseA = -1, -#if GTEST_OS_LINUX + +# if GTEST_OS_LINUX + // We want to test the case where the size of the anonymous enum is // larger than sizeof(int), to make sure our implementation of the // assertions doesn't truncate the enums. However, MSVC @@ -3837,16 +3843,22 @@ enum { // int size. We want to test whether this will confuse the // assertions. kCaseB = testing::internal::kMaxBiggestInt, -#else + +# else + kCaseB = INT_MAX, -#endif // GTEST_OS_LINUX + +# endif // GTEST_OS_LINUX + kCaseC = 42, }; TEST(AssertionTest, AnonymousEnum) { -#if GTEST_OS_LINUX +# if GTEST_OS_LINUX + EXPECT_EQ(static_cast(kCaseA), static_cast(kCaseB)); -#endif // GTEST_OS_LINUX + +# endif // GTEST_OS_LINUX EXPECT_EQ(kCaseA, kCaseA); EXPECT_NE(kCaseA, kCaseB); @@ -3925,12 +3937,14 @@ TEST(HRESULTAssertionTest, EXPECT_HRESULT_FAILED) { TEST(HRESULTAssertionTest, ASSERT_HRESULT_FAILED) { ASSERT_HRESULT_FAILED(E_UNEXPECTED); -#ifndef __BORLANDC__ +# ifndef __BORLANDC__ + // ICE's in C++Builder 2007 and 2009. EXPECT_FATAL_FAILURE(ASSERT_HRESULT_FAILED(OkHRESULTSuccess()), "Expected: (OkHRESULTSuccess()) fails.\n" " Actual: 0x00000000"); -#endif +# endif + EXPECT_FATAL_FAILURE(ASSERT_HRESULT_FAILED(FalseHRESULTSuccess()), "Expected: (FalseHRESULTSuccess()) fails.\n" " Actual: 0x00000001"); @@ -3947,12 +3961,13 @@ TEST(HRESULTAssertionTest, Streaming) { EXPECT_HRESULT_SUCCEEDED(E_UNEXPECTED) << "expected failure", "expected failure"); -#ifndef __BORLANDC__ +# ifndef __BORLANDC__ + // ICE's in C++Builder 2007 and 2009. EXPECT_FATAL_FAILURE( ASSERT_HRESULT_SUCCEEDED(E_UNEXPECTED) << "expected failure", "expected failure"); -#endif +# endif EXPECT_NONFATAL_FAILURE( EXPECT_HRESULT_FAILED(S_OK) << "expected failure", @@ -3967,7 +3982,7 @@ TEST(HRESULTAssertionTest, Streaming) { #ifdef __BORLANDC__ // Silences warnings: "Condition is always true", "Unreachable code" -#pragma option push -w-ccc -w-rch +# pragma option push -w-ccc -w-rch #endif // Tests that the assertion macros behave like single statements. @@ -4188,7 +4203,7 @@ TEST(ExpectTest, ExpectFalseWithAssertionResult) { #ifdef __BORLANDC__ // Restores warnings after previous "#pragma option push" supressed them -#pragma option pop +# pragma option pop #endif // Tests EXPECT_EQ. @@ -5426,6 +5441,7 @@ class InitGoogleTestTest : public Test { // This macro wraps TestParsingFlags s.t. the user doesn't need // to specify the array sizes. + #define GTEST_TEST_PARSING_FLAGS_(argv1, argv2, expected, should_print_help) \ TestParsingFlags(sizeof(argv1)/sizeof(*argv1) - 1, argv1, \ sizeof(argv2)/sizeof(*argv2) - 1, argv2, \ @@ -6239,7 +6255,7 @@ TEST(StreamingAssertionsTest, Unconditional) { #ifdef __BORLANDC__ // Silences warnings: "Condition is always true", "Unreachable code" -#pragma option push -w-ccc -w-rch +# pragma option push -w-ccc -w-rch #endif TEST(StreamingAssertionsTest, Truth) { @@ -6262,7 +6278,7 @@ TEST(StreamingAssertionsTest, Truth2) { #ifdef __BORLANDC__ // Restores warnings after previous "#pragma option push" supressed them -#pragma option pop +# pragma option pop #endif TEST(StreamingAssertionsTest, IntegerEquals) { -- cgit v1.2.3 From f4419791abd9d0962eb5a61003b7f4b80d7e4068 Mon Sep 17 00:00:00 2001 From: vladlosev Date: Mon, 28 Feb 2011 18:02:01 +0000 Subject: Fixes PrintUnprintableTypeTest.InGlobalNamespace in gtest-printers_test on 64bit PowerPCs. --- test/gtest-printers_test.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'test') diff --git a/test/gtest-printers_test.cc b/test/gtest-printers_test.cc index e11662ff..9aba39a4 100644 --- a/test/gtest-printers_test.cc +++ b/test/gtest-printers_test.cc @@ -995,7 +995,7 @@ TEST(PrintTupleTest, NestedTuple) { // Unprintable types in the global namespace. TEST(PrintUnprintableTypeTest, InGlobalNamespace) { EXPECT_EQ("1-byte object <00>", - Print(UnprintableTemplateInGlobal())); + Print(UnprintableTemplateInGlobal())); } // Unprintable types in a user namespace. -- cgit v1.2.3 From 66ac4909aea5c4dc9c43e6f11518c34049c6bd5e Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Sat, 5 Mar 2011 01:16:12 +0000 Subject: Fixes non-conforming uses of commas in enums s.t. the code compiles on Sun OS. Patch by Hady Zalek. --- test/gtest-printers_test.cc | 4 ++-- test/gtest_unittest.cc | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'test') diff --git a/test/gtest-printers_test.cc b/test/gtest-printers_test.cc index 9aba39a4..8992a9a7 100644 --- a/test/gtest-printers_test.cc +++ b/test/gtest-printers_test.cc @@ -74,7 +74,7 @@ enum EnumWithoutPrinter { // An enum with a << operator. enum EnumWithStreaming { - kEWS1 = 10, + kEWS1 = 10 }; std::ostream& operator<<(std::ostream& os, EnumWithStreaming e) { @@ -83,7 +83,7 @@ std::ostream& operator<<(std::ostream& os, EnumWithStreaming e) { // An enum with a PrintTo() function. enum EnumWithPrintTo { - kEWPT1 = 1, + kEWPT1 = 1 }; void PrintTo(EnumWithPrintTo e, std::ostream* os) { diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index 3f0456e9..e6619d57 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -3811,7 +3811,7 @@ TEST(AssertionTest, ExpectWorksWithUncopyableObject) { enum NamedEnum { kE1 = 0, - kE2 = 1, + kE2 = 1 }; TEST(AssertionTest, NamedEnum) { -- cgit v1.2.3 From 603533a0a4dcfc2ef33051b9ae8237568a19adc4 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Sat, 5 Mar 2011 08:04:01 +0000 Subject: Fixes compatibility with Borland C++Builder. Original patch by Josh Kelley. Simplified by Zhanyong Wan. --- test/gtest_unittest.cc | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) (limited to 'test') diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index e6619d57..46db38d4 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -1416,8 +1416,8 @@ static int global_var = 0; #define GTEST_USE_UNPROTECTED_COMMA_ global_var++, global_var++ TEST_F(ExpectFatalFailureTest, AcceptsMacroThatExpandsToUnprotectedComma) { -#if !defined(__BORLANDC__) || __BORLANDC__ >= 0x600 - // ICE's in C++Builder 2007. +#ifndef __BORLANDC__ + // ICE's in C++Builder. EXPECT_FATAL_FAILURE({ GTEST_USE_UNPROTECTED_COMMA_; AddFatalFailure(); @@ -3550,8 +3550,8 @@ TEST(AssertionTest, ASSERT_TRUE) { // Tests ASSERT_TRUE(predicate) for predicates returning AssertionResult. TEST(AssertionTest, AssertTrueWithAssertionResult) { ASSERT_TRUE(ResultIsEven(2)); -#if !defined(__BORLANDC__) || __BORLANDC__ >= 0x600 - // ICE's in C++Builder 2007. +#ifndef __BORLANDC__ + // ICE's in C++Builder. EXPECT_FATAL_FAILURE(ASSERT_TRUE(ResultIsEven(3)), "Value of: ResultIsEven(3)\n" " Actual: false (3 is odd)\n" @@ -3576,8 +3576,8 @@ TEST(AssertionTest, ASSERT_FALSE) { // Tests ASSERT_FALSE(predicate) for predicates returning AssertionResult. TEST(AssertionTest, AssertFalseWithAssertionResult) { ASSERT_FALSE(ResultIsEven(3)); -#if !defined(__BORLANDC__) || __BORLANDC__ >= 0x600 - // ICE's in C++Builder 2007. +#ifndef __BORLANDC__ + // ICE's in C++Builder. EXPECT_FATAL_FAILURE(ASSERT_FALSE(ResultIsEven(2)), "Value of: ResultIsEven(2)\n" " Actual: true (2 is even)\n" @@ -3877,10 +3877,16 @@ TEST(AssertionTest, AnonymousEnum) { ASSERT_LE(kCaseA, kCaseB); ASSERT_GT(kCaseB, kCaseA); ASSERT_GE(kCaseA, kCaseA); + +# ifndef __BORLANDC__ + + // ICE's in C++Builder. EXPECT_FATAL_FAILURE(ASSERT_EQ(kCaseA, kCaseB), "Value of: kCaseB"); EXPECT_FATAL_FAILURE(ASSERT_EQ(kCaseA, kCaseC), "Actual: 42"); +# endif + EXPECT_FATAL_FAILURE(ASSERT_EQ(kCaseA, kCaseC), "Which is: -1"); } @@ -4791,10 +4797,13 @@ TEST(ComparisonAssertionTest, AcceptsUnprintableArgs) { // Code tested by EXPECT_FATAL_FAILURE cannot reference local // variables, so we have to write UnprintableChar('x') instead of x. +#ifndef __BORLANDC__ + // ICE's in C++Builder. EXPECT_FATAL_FAILURE(ASSERT_NE(UnprintableChar('x'), UnprintableChar('x')), "1-byte object <78>"); EXPECT_FATAL_FAILURE(ASSERT_LE(UnprintableChar('y'), UnprintableChar('x')), "1-byte object <78>"); +#endif EXPECT_FATAL_FAILURE(ASSERT_LE(UnprintableChar('y'), UnprintableChar('x')), "1-byte object <79>"); EXPECT_FATAL_FAILURE(ASSERT_GE(UnprintableChar('x'), UnprintableChar('y')), @@ -7213,8 +7222,10 @@ TEST(CopyArrayTest, WorksForDegeneratedArrays) { TEST(CopyArrayTest, WorksForOneDimensionalArrays) { const char a[3] = "hi"; int b[3]; +#ifndef __BORLANDC__ // C++Builder cannot compile some array size deductions. CopyArray(a, &b); EXPECT_TRUE(ArrayEq(a, b)); +#endif int c[3]; CopyArray(a, 3, c); @@ -7224,8 +7235,10 @@ TEST(CopyArrayTest, WorksForOneDimensionalArrays) { TEST(CopyArrayTest, WorksForTwoDimensionalArrays) { const int a[2][3] = { { 0, 1, 2 }, { 3, 4, 5 } }; int b[2][3]; +#ifndef __BORLANDC__ // C++Builder cannot compile some array size deductions. CopyArray(a, &b); EXPECT_TRUE(ArrayEq(a, b)); +#endif int c[2][3]; CopyArray(a, 2, c); -- cgit v1.2.3 From 5451ffe816cafe4f0f51813eb8ddedb3543f0fea Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Wed, 9 Mar 2011 01:13:19 +0000 Subject: Makes IsContainerTest compatible with Sun C++ and Visual Age C++, based on Hady Zalek's report and experiment; also fixes a bug that causes it to think that a class named const_iterator is a container; also clarifies the Borland C++ compatibility fix in the comments based on Josh Kelley's suggestion. --- test/gtest-printers_test.cc | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'test') diff --git a/test/gtest-printers_test.cc b/test/gtest-printers_test.cc index 8992a9a7..e0065e2f 100644 --- a/test/gtest-printers_test.cc +++ b/test/gtest-printers_test.cc @@ -936,6 +936,28 @@ TEST(PrintStlContainerTest, TwoDimensionalNativeArray) { EXPECT_EQ("{ { 1, 2, 3 }, { 4, 5, 6 } }", Print(b)); } +// Tests that a class named iterator isn't treated as a container. + +struct iterator { + char x; +}; + +TEST(PrintStlContainerTest, Iterator) { + iterator it = {}; + EXPECT_EQ("1-byte object <00>", Print(it)); +} + +// Tests that a class named const_iterator isn't treated as a container. + +struct const_iterator { + char x; +}; + +TEST(PrintStlContainerTest, ConstIterator) { + const_iterator it = {}; + EXPECT_EQ("1-byte object <00>", Print(it)); +} + #if GTEST_HAS_TR1_TUPLE // Tests printing tuples. -- cgit v1.2.3 From 1ea6b31d5debaf2535096b1f511a605a541780ef Mon Sep 17 00:00:00 2001 From: vladlosev Date: Wed, 30 Mar 2011 22:02:47 +0000 Subject: Fixes Windows CE compatibility problem (issue http://code.google.com/p/googletest/issues/detail?id=362). --- test/gtest_environment_test.cc | 2 +- test/gtest_repeat_test.cc | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'test') diff --git a/test/gtest_environment_test.cc b/test/gtest_environment_test.cc index 744b405e..ec9aa2cd 100644 --- a/test/gtest_environment_test.cc +++ b/test/gtest_environment_test.cc @@ -115,7 +115,7 @@ TEST(FooTest, Bar) { void Check(bool condition, const char* msg) { if (!condition) { printf("FAILED: %s\n", msg); - abort(); + testing::internal::posix::Abort(); } } diff --git a/test/gtest_repeat_test.cc b/test/gtest_repeat_test.cc index ff9063a4..5223dc0e 100644 --- a/test/gtest_repeat_test.cc +++ b/test/gtest_repeat_test.cc @@ -69,7 +69,7 @@ namespace { << " Actual: " << actual_val << "\n"\ << "Expected: " #expected "\n"\ << "Which is: " << expected_val << "\n";\ - abort();\ + ::testing::internal::posix::Abort();\ }\ } while(::testing::internal::AlwaysFalse()) @@ -113,10 +113,10 @@ TEST(BarDeathTest, ThreadSafeAndFast) { g_death_test_count++; GTEST_FLAG(death_test_style) = "threadsafe"; - EXPECT_DEATH_IF_SUPPORTED(abort(), ""); + EXPECT_DEATH_IF_SUPPORTED(::testing::internal::posix::Abort(), ""); GTEST_FLAG(death_test_style) = "fast"; - EXPECT_DEATH_IF_SUPPORTED(abort(), ""); + EXPECT_DEATH_IF_SUPPORTED(::testing::internal::posix::Abort(), ""); } #if GTEST_HAS_PARAM_TEST -- cgit v1.2.3 From c7a9cc35121536e44373a2eb5670f7d3a3d5ee28 Mon Sep 17 00:00:00 2001 From: vladlosev Date: Fri, 1 Apr 2011 21:57:36 +0000 Subject: Changes diagnostic output of the question mark from '\?' to '?'. --- test/gtest-printers_test.cc | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'test') diff --git a/test/gtest-printers_test.cc b/test/gtest-printers_test.cc index e0065e2f..1395c69b 100644 --- a/test/gtest-printers_test.cc +++ b/test/gtest-printers_test.cc @@ -276,7 +276,7 @@ TEST(PrintCharTest, PlainChar) { EXPECT_EQ("'\\0'", Print('\0')); EXPECT_EQ("'\\'' (39, 0x27)", Print('\'')); EXPECT_EQ("'\"' (34, 0x22)", Print('"')); - EXPECT_EQ("'\\?' (63, 0x3F)", Print('\?')); + EXPECT_EQ("'?' (63, 0x3F)", Print('?')); EXPECT_EQ("'\\\\' (92, 0x5C)", Print('\\')); EXPECT_EQ("'\\a' (7)", Print('\a')); EXPECT_EQ("'\\b' (8)", Print('\b')); @@ -318,7 +318,7 @@ TEST(PrintBuiltInTypeTest, Wchar_t) { EXPECT_EQ("L'\\0'", Print(L'\0')); EXPECT_EQ("L'\\'' (39, 0x27)", Print(L'\'')); EXPECT_EQ("L'\"' (34, 0x22)", Print(L'"')); - EXPECT_EQ("L'\\?' (63, 0x3F)", Print(L'\?')); + EXPECT_EQ("L'?' (63, 0x3F)", Print(L'?')); EXPECT_EQ("L'\\\\' (92, 0x5C)", Print(L'\\')); EXPECT_EQ("L'\\a' (7)", Print(L'\a')); EXPECT_EQ("L'\\b' (8)", Print(L'\b')); @@ -401,8 +401,8 @@ TEST(PrintCStringTest, Null) { // Tests that C strings are escaped properly. TEST(PrintCStringTest, EscapesProperly) { - const char* p = "'\"\?\\\a\b\f\n\r\t\v\x7F\xFF a"; - EXPECT_EQ(PrintPointer(p) + " pointing to \"'\\\"\\?\\\\\\a\\b\\f" + const char* p = "'\"?\\\a\b\f\n\r\t\v\x7F\xFF a"; + EXPECT_EQ(PrintPointer(p) + " pointing to \"'\\\"?\\\\\\a\\b\\f" "\\n\\r\\t\\v\\x7F\\xFF a\"", Print(p)); } @@ -438,9 +438,9 @@ TEST(PrintWideCStringTest, Null) { // Tests that wide C strings are escaped properly. TEST(PrintWideCStringTest, EscapesProperly) { - const wchar_t s[] = {'\'', '"', '\?', '\\', '\a', '\b', '\f', '\n', '\r', + const wchar_t s[] = {'\'', '"', '?', '\\', '\a', '\b', '\f', '\n', '\r', '\t', '\v', 0xD3, 0x576, 0x8D3, 0xC74D, ' ', 'a', '\0'}; - EXPECT_EQ(PrintPointer(s) + " pointing to L\"'\\\"\\?\\\\\\a\\b\\f" + EXPECT_EQ(PrintPointer(s) + " pointing to L\"'\\\"?\\\\\\a\\b\\f" "\\n\\r\\t\\v\\xD3\\x576\\x8D3\\xC74D a\"", Print(static_cast(s))); } @@ -643,18 +643,18 @@ TEST(PrintArrayTest, BigArray) { #if GTEST_HAS_GLOBAL_STRING // ::string. TEST(PrintStringTest, StringInGlobalNamespace) { - const char s[] = "'\"\?\\\a\b\f\n\0\r\t\v\x7F\xFF a"; + const char s[] = "'\"?\\\a\b\f\n\0\r\t\v\x7F\xFF a"; const ::string str(s, sizeof(s)); - EXPECT_EQ("\"'\\\"\\?\\\\\\a\\b\\f\\n\\0\\r\\t\\v\\x7F\\xFF a\\0\"", + EXPECT_EQ("\"'\\\"?\\\\\\a\\b\\f\\n\\0\\r\\t\\v\\x7F\\xFF a\\0\"", Print(str)); } #endif // GTEST_HAS_GLOBAL_STRING // ::std::string. TEST(PrintStringTest, StringInStdNamespace) { - const char s[] = "'\"\?\\\a\b\f\n\0\r\t\v\x7F\xFF a"; + const char s[] = "'\"?\\\a\b\f\n\0\r\t\v\x7F\xFF a"; const ::std::string str(s, sizeof(s)); - EXPECT_EQ("\"'\\\"\\?\\\\\\a\\b\\f\\n\\0\\r\\t\\v\\x7F\\xFF a\\0\"", + EXPECT_EQ("\"'\\\"?\\\\\\a\\b\\f\\n\\0\\r\\t\\v\\x7F\\xFF a\\0\"", Print(str)); } @@ -677,9 +677,9 @@ TEST(PrintStringTest, StringAmbiguousHex) { #if GTEST_HAS_GLOBAL_WSTRING // ::wstring. TEST(PrintWideStringTest, StringInGlobalNamespace) { - const wchar_t s[] = L"'\"\?\\\a\b\f\n\0\r\t\v\xD3\x576\x8D3\xC74D a"; + const wchar_t s[] = L"'\"?\\\a\b\f\n\0\r\t\v\xD3\x576\x8D3\xC74D a"; const ::wstring str(s, sizeof(s)/sizeof(wchar_t)); - EXPECT_EQ("L\"'\\\"\\?\\\\\\a\\b\\f\\n\\0\\r\\t\\v" + EXPECT_EQ("L\"'\\\"?\\\\\\a\\b\\f\\n\\0\\r\\t\\v" "\\xD3\\x576\\x8D3\\xC74D a\\0\"", Print(str)); } @@ -688,9 +688,9 @@ TEST(PrintWideStringTest, StringInGlobalNamespace) { #if GTEST_HAS_STD_WSTRING // ::std::wstring. TEST(PrintWideStringTest, StringInStdNamespace) { - const wchar_t s[] = L"'\"\?\\\a\b\f\n\0\r\t\v\xD3\x576\x8D3\xC74D a"; + const wchar_t s[] = L"'\"?\\\a\b\f\n\0\r\t\v\xD3\x576\x8D3\xC74D a"; const ::std::wstring str(s, sizeof(s)/sizeof(wchar_t)); - EXPECT_EQ("L\"'\\\"\\?\\\\\\a\\b\\f\\n\\0\\r\\t\\v" + EXPECT_EQ("L\"'\\\"?\\\\\\a\\b\\f\\n\\0\\r\\t\\v" "\\xD3\\x576\\x8D3\\xC74D a\\0\"", Print(str)); } -- cgit v1.2.3 From 741d6c0d475664fc48790917cefed455a4307227 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Thu, 7 Apr 2011 18:36:50 +0000 Subject: makes gtest compatible with HP UX (by Pasi Valminen); fixes a typo in the name of xlC (by Hady Zalek). --- test/gtest_unittest.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'test') diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index 46db38d4..6834e8c4 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -3824,8 +3824,8 @@ TEST(AssertionTest, NamedEnum) { // The version of gcc used in XCode 2.2 has a bug and doesn't allow // anonymous enums in assertions. Therefore the following test is not // done on Mac. -// Sun Studio also rejects this code. -#if !GTEST_OS_MAC && !defined(__SUNPRO_CC) +// Sun Studio and HP aCC also reject this code. +#if !GTEST_OS_MAC && !defined(__SUNPRO_CC) && !defined(__HP_aCC) // Tests using assertions with anonymous enums. enum { -- cgit v1.2.3 From 962b6554f44c3d3e4a8b4c949c89cf77b744d210 Mon Sep 17 00:00:00 2001 From: vladlosev Date: Fri, 8 Apr 2011 00:29:12 +0000 Subject: Removes commas from last items in enums (a C++ standard compliance fix). --- test/gtest_unittest.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'test') diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index 6834e8c4..23d6860e 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -3850,7 +3850,7 @@ enum { # endif // GTEST_OS_LINUX - kCaseC = 42, + kCaseC = 42 }; TEST(AssertionTest, AnonymousEnum) { -- cgit v1.2.3 From fc99b1ad515ccfc92ee92001c409f69385033af5 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Tue, 12 Apr 2011 18:24:59 +0000 Subject: Avoids iterator_traits, as it's not available in libCStd when compiled with Sun C++. --- test/gtest-port_test.cc | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'test') diff --git a/test/gtest-port_test.cc b/test/gtest-port_test.cc index ff0165fe..1c6e2b09 100644 --- a/test/gtest-port_test.cc +++ b/test/gtest-port_test.cc @@ -39,7 +39,9 @@ # include #endif // GTEST_OS_MAC +#include #include // For std::pair and std::make_pair. +#include #include "gtest/gtest.h" #include "gtest/gtest-spi.h" @@ -172,6 +174,24 @@ TEST(ImplicitCastTest, CanUseImplicitConstructor) { EXPECT_TRUE(converted); } +TEST(IteratorTraitsTest, WorksForSTLContainerIterators) { + StaticAssertTypeEq::const_iterator>::value_type>(); + StaticAssertTypeEq::iterator>::value_type>(); +} + +TEST(IteratorTraitsTest, WorksForPointerToNonConst) { + StaticAssertTypeEq::value_type>(); + StaticAssertTypeEq::value_type>(); +} + +TEST(IteratorTraitsTest, WorksForPointerToConst) { + StaticAssertTypeEq::value_type>(); + StaticAssertTypeEq::value_type>(); +} + // Tests that the element_type typedef is available in scoped_ptr and refers // to the parameter type. TEST(ScopedPtrTest, DefinesElementType) { -- cgit v1.2.3 From b8c0e16eeb7496f71480c6a060144b0e050edcf5 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Tue, 12 Apr 2011 20:36:11 +0000 Subject: Fixes Sun C++ compiler errors (by Pasi Valminen) --- test/gtest-printers_test.cc | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'test') diff --git a/test/gtest-printers_test.cc b/test/gtest-printers_test.cc index 1395c69b..6292c7f2 100644 --- a/test/gtest-printers_test.cc +++ b/test/gtest-printers_test.cc @@ -857,7 +857,7 @@ TEST(PrintStlContainerTest, HashMultiSet) { #endif // GTEST_HAS_HASH_SET_ TEST(PrintStlContainerTest, List) { - const char* a[] = { + const string a[] = { "hello", "world" }; @@ -875,9 +875,15 @@ TEST(PrintStlContainerTest, Map) { TEST(PrintStlContainerTest, MultiMap) { multimap map1; - map1.insert(make_pair(true, 0)); - map1.insert(make_pair(true, 1)); - map1.insert(make_pair(false, 2)); + // The make_pair template function would deduce the type as + // pair here, and since the key part in a multimap has to + // be constant, without a templated ctor in the pair class (as in + // libCstd on Solaris), make_pair call would fail to compile as no + // implicit conversion is found. Thus explicit typename is used + // here instead. + map1.insert(pair(true, 0)); + map1.insert(pair(true, 1)); + map1.insert(pair(false, 2)); EXPECT_EQ("{ (false, 2), (true, 0), (true, 1) }", Print(map1)); } -- cgit v1.2.3 From cc265df8b44e613ca118ce5da145f91d66f6c440 Mon Sep 17 00:00:00 2001 From: vladlosev Date: Mon, 13 Jun 2011 19:00:37 +0000 Subject: Fixes broken build on VC++ 7.1. --- test/gtest_throw_on_failure_test_.cc | 18 +++++++++++- test/gtest_xml_output_unittest.py | 54 ++++++++++++++++++++---------------- test/gtest_xml_output_unittest_.cc | 9 ++++-- 3 files changed, 53 insertions(+), 28 deletions(-) (limited to 'test') diff --git a/test/gtest_throw_on_failure_test_.cc b/test/gtest_throw_on_failure_test_.cc index 03776ecb..2b88fe3d 100644 --- a/test/gtest_throw_on_failure_test_.cc +++ b/test/gtest_throw_on_failure_test_.cc @@ -37,12 +37,28 @@ #include "gtest/gtest.h" +#include // for fflush, fprintf, NULL, etc. +#include // for exit +#include // for set_terminate + +// This terminate handler aborts the program using exit() rather than abort(). +// This avoids showing pop-ups on Windows systems and core dumps on Unix-like +// ones. +void TerminateHandler() { + fprintf(stderr, "%s\n", "Unhandled C++ exception terminating the program."); + fflush(NULL); + exit(1); +} + int main(int argc, char** argv) { +#if GTEST_HAS_EXCEPTIONS + std::set_terminate(&TerminateHandler); +#endif testing::InitGoogleTest(&argc, argv); // We want to ensure that people can use Google Test assertions in // other testing frameworks, as long as they initialize Google Test - // properly and set the thrown-on-failure mode. Therefore, we don't + // properly and set the throw-on-failure mode. Therefore, we don't // use Google Test's constructs for defining and running tests // (e.g. TEST and RUN_ALL_TESTS) here. diff --git a/test/gtest_xml_output_unittest.py b/test/gtest_xml_output_unittest.py index bdd50353..06637e5b 100755 --- a/test/gtest_xml_output_unittest.py +++ b/test/gtest_xml_output_unittest.py @@ -42,6 +42,7 @@ import gtest_test_utils import gtest_xml_test_utils +GTEST_LIST_TESTS_FLAG = '--gtest_list_tests' GTEST_OUTPUT_FLAG = "--gtest_output" GTEST_DEFAULT_OUTPUT_FILE = "test_detail.xml" GTEST_PROGRAM_NAME = "gtest_xml_output_unittest_" @@ -49,9 +50,9 @@ GTEST_PROGRAM_NAME = "gtest_xml_output_unittest_" SUPPORTS_STACK_TRACES = False if SUPPORTS_STACK_TRACES: - STACK_TRACE_TEMPLATE = "\nStack trace:\n*" + STACK_TRACE_TEMPLATE = '\nStack trace:\n*' else: - STACK_TRACE_TEMPLATE = "" + STACK_TRACE_TEMPLATE = '' EXPECTED_NON_EMPTY_XML = """ @@ -130,18 +131,26 @@ EXPECTED_EMPTY_XML = """ """ +GTEST_PROGRAM_PATH = gtest_test_utils.GetTestExecutablePath(GTEST_PROGRAM_NAME) + +SUPPORTS_TYPED_TESTS = 'TypedTest' in gtest_test_utils.Subprocess( + [GTEST_PROGRAM_PATH, GTEST_LIST_TESTS_FLAG], capture_stderr=False).output + class GTestXMLOutputUnitTest(gtest_xml_test_utils.GTestXMLTestCase): """ Unit test for Google Test's XML output functionality. """ - def testNonEmptyXmlOutput(self): - """ - Runs a test program that generates a non-empty XML output, and - tests that the XML output is expected. - """ - self._TestXmlOutput(GTEST_PROGRAM_NAME, EXPECTED_NON_EMPTY_XML, 1) + # This test currently breaks on platforms that do not support typed and + # type-parameterized tests, so we don't run it under them. + if SUPPORTS_TYPED_TESTS: + def testNonEmptyXmlOutput(self): + """ + Runs a test program that generates a non-empty XML output, and + tests that the XML output is expected. + """ + self._TestXmlOutput(GTEST_PROGRAM_NAME, EXPECTED_NON_EMPTY_XML, 1) def testEmptyXmlOutput(self): """ @@ -149,8 +158,7 @@ class GTestXMLOutputUnitTest(gtest_xml_test_utils.GTestXMLTestCase): tests that the XML output is expected. """ - self._TestXmlOutput("gtest_no_test_unittest", - EXPECTED_EMPTY_XML, 0) + self._TestXmlOutput('gtest_no_test_unittest', EXPECTED_EMPTY_XML, 0) def testDefaultOutputFile(self): """ @@ -160,7 +168,7 @@ class GTestXMLOutputUnitTest(gtest_xml_test_utils.GTestXMLTestCase): output_file = os.path.join(gtest_test_utils.GetTempDir(), GTEST_DEFAULT_OUTPUT_FILE) gtest_prog_path = gtest_test_utils.GetTestExecutablePath( - "gtest_no_test_unittest") + 'gtest_no_test_unittest') try: os.remove(output_file) except OSError, e: @@ -168,7 +176,7 @@ class GTestXMLOutputUnitTest(gtest_xml_test_utils.GTestXMLTestCase): raise p = gtest_test_utils.Subprocess( - [gtest_prog_path, "%s=xml" % GTEST_OUTPUT_FLAG], + [gtest_prog_path, '%s=xml' % GTEST_OUTPUT_FLAG], working_dir=gtest_test_utils.GetTempDir()) self.assert_(p.exited) self.assertEquals(0, p.exit_code) @@ -181,24 +189,22 @@ class GTestXMLOutputUnitTest(gtest_xml_test_utils.GTestXMLTestCase): """ xml_path = os.path.join(gtest_test_utils.GetTempDir(), - GTEST_PROGRAM_NAME + "out.xml") + GTEST_PROGRAM_NAME + 'out.xml') if os.path.isfile(xml_path): os.remove(xml_path) - gtest_prog_path = gtest_test_utils.GetTestExecutablePath(GTEST_PROGRAM_NAME) - - command = [gtest_prog_path, - "%s=xml:%s" % (GTEST_OUTPUT_FLAG, xml_path), - "--shut_down_xml"] + command = [GTEST_PROGRAM_PATH, + '%s=xml:%s' % (GTEST_OUTPUT_FLAG, xml_path), + '--shut_down_xml'] p = gtest_test_utils.Subprocess(command) if p.terminated_by_signal: self.assert_(False, - "%s was killed by signal %d" % (gtest_prog_name, p.signal)) + '%s was killed by signal %d' % (gtest_prog_name, p.signal)) else: self.assert_(p.exited) self.assertEquals(1, p.exit_code, "'%s' exited with code %s, which doesn't match " - "the expected exit code %s." + 'the expected exit code %s.' % (command, p.exit_code, 1)) self.assert_(not os.path.isfile(xml_path)) @@ -212,19 +218,19 @@ class GTestXMLOutputUnitTest(gtest_xml_test_utils.GTestXMLTestCase): expected_exit_code. """ xml_path = os.path.join(gtest_test_utils.GetTempDir(), - gtest_prog_name + "out.xml") + gtest_prog_name + 'out.xml') gtest_prog_path = gtest_test_utils.GetTestExecutablePath(gtest_prog_name) - command = [gtest_prog_path, "%s=xml:%s" % (GTEST_OUTPUT_FLAG, xml_path)] + command = [gtest_prog_path, '%s=xml:%s' % (GTEST_OUTPUT_FLAG, xml_path)] p = gtest_test_utils.Subprocess(command) if p.terminated_by_signal: self.assert_(False, - "%s was killed by signal %d" % (gtest_prog_name, p.signal)) + '%s was killed by signal %d' % (gtest_prog_name, p.signal)) else: self.assert_(p.exited) self.assertEquals(expected_exit_code, p.exit_code, "'%s' exited with code %s, which doesn't match " - "the expected exit code %s." + 'the expected exit code %s.' % (command, p.exit_code, expected_exit_code)) expected = minidom.parseString(expected_xml) diff --git a/test/gtest_xml_output_unittest_.cc b/test/gtest_xml_output_unittest_.cc index 741a8874..bf0c871b 100644 --- a/test/gtest_xml_output_unittest_.cc +++ b/test/gtest_xml_output_unittest_.cc @@ -45,7 +45,6 @@ using ::testing::TestEventListeners; using ::testing::TestWithParam; using ::testing::UnitTest; using ::testing::Test; -using ::testing::Types; using ::testing::Values; class SuccessfulTest : public Test { @@ -145,23 +144,27 @@ TEST_P(ValueParamTest, HasValueParamAttribute) {} TEST_P(ValueParamTest, AnotherTestThatHasValueParamAttribute) {} INSTANTIATE_TEST_CASE_P(Single, ValueParamTest, Values(33, 42)); +#if GTEST_HAS_TYPED_TEST // Verifies that the type parameter name is output in the 'type_param' // XML attribute for typed tests. template class TypedTest : public Test {}; -typedef Types TypedTestTypes; +typedef testing::Types TypedTestTypes; TYPED_TEST_CASE(TypedTest, TypedTestTypes); TYPED_TEST(TypedTest, HasTypeParamAttribute) {} +#endif +#if GTEST_HAS_TYPED_TEST_P // Verifies that the type parameter name is output in the 'type_param' // XML attribute for type-parameterized tests. template class TypeParameterizedTestCase : public Test {}; TYPED_TEST_CASE_P(TypeParameterizedTestCase); TYPED_TEST_P(TypeParameterizedTestCase, HasTypeParamAttribute) {} REGISTER_TYPED_TEST_CASE_P(TypeParameterizedTestCase, HasTypeParamAttribute); -typedef Types TypeParameterizedTestCaseTypes; +typedef testing::Types TypeParameterizedTestCaseTypes; INSTANTIATE_TYPED_TEST_CASE_P(Single, TypeParameterizedTestCase, TypeParameterizedTestCaseTypes); +#endif int main(int argc, char** argv) { InitGoogleTest(&argc, argv); -- cgit v1.2.3 From 386da2037dc7b1d063ac43bf146889b1edcafe7e Mon Sep 17 00:00:00 2001 From: vladlosev Date: Mon, 20 Jun 2011 21:43:18 +0000 Subject: QNX compatibility patch (by Haruka Iwao). --- test/gtest-port_test.cc | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'test') diff --git a/test/gtest-port_test.cc b/test/gtest-port_test.cc index 1c6e2b09..c83e005f 100644 --- a/test/gtest-port_test.cc +++ b/test/gtest-port_test.cc @@ -267,7 +267,7 @@ TEST(FormatCompilerIndependentFileLocationTest, FormatsUknownFileAndLine) { EXPECT_EQ("unknown file", FormatCompilerIndependentFileLocation(NULL, -1)); } -#if GTEST_OS_MAC +#if GTEST_OS_MAC || GTEST_OS_QNX void* ThreadFunc(void* data) { pthread_mutex_t* mutex = static_cast(data); pthread_mutex_lock(mutex); @@ -297,6 +297,8 @@ TEST(GetThreadCountTest, ReturnsCorrectValue) { void* dummy; ASSERT_EQ(0, pthread_join(thread_id, &dummy)); +# if GTEST_OS_MAC + // MacOS X may not immediately report the updated thread count after // joining a thread, causing flakiness in this test. To counter that, we // wait for up to .5 seconds for the OS to report the correct value. @@ -306,6 +308,9 @@ TEST(GetThreadCountTest, ReturnsCorrectValue) { SleepMilliseconds(100); } + +# endif // GTEST_OS_MAC + EXPECT_EQ(1U, GetThreadCount()); pthread_mutex_destroy(&mutex); } @@ -313,7 +318,7 @@ TEST(GetThreadCountTest, ReturnsCorrectValue) { TEST(GetThreadCountTest, ReturnsZeroWhenUnableToCountThreads) { EXPECT_EQ(0U, GetThreadCount()); } -#endif // GTEST_OS_MAC +#endif // GTEST_OS_MAC || GTEST_OS_QNX TEST(GtestCheckDeathTest, DiesWithCorrectOutputOnFailure) { const bool a_false_condition = false; -- cgit v1.2.3 From c2922d4ed2ecff5ba889b2008dba45dbc39c9168 Mon Sep 17 00:00:00 2001 From: vladlosev Date: Mon, 11 Jul 2011 19:27:07 +0000 Subject: Fixes a resource leak in gtest-port_test (by Haruka Iwao). --- test/gtest-port_test.cc | 1 + 1 file changed, 1 insertion(+) (limited to 'test') diff --git a/test/gtest-port_test.cc b/test/gtest-port_test.cc index c83e005f..9ae78769 100644 --- a/test/gtest-port_test.cc +++ b/test/gtest-port_test.cc @@ -1037,6 +1037,7 @@ class AtomicCounterWithMutex { SleepMilliseconds(random_.Generate(30)); GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_unlock(&memory_barrier_mutex)); + GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_destroy(&memory_barrier_mutex)); } value_ = temp + 1; } -- cgit v1.2.3 From cf3f92ef93ffc35ec1efe8b3b1d65b2624d84de5 Mon Sep 17 00:00:00 2001 From: vladlosev Date: Tue, 16 Aug 2011 00:47:22 +0000 Subject: Fixes a user reported test break (modifying a dict while iterating). --- test/gtest_test_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'test') diff --git a/test/gtest_test_utils.py b/test/gtest_test_utils.py index 4e897bd3..6dd8db4b 100755 --- a/test/gtest_test_utils.py +++ b/test/gtest_test_utils.py @@ -241,7 +241,7 @@ class Subprocess: # Changes made by os.environ.clear are not inheritable by child # processes until Python 2.6. To produce inheritable changes we have # to delete environment items with the del statement. - for key in dest: + for key in dest.keys(): del dest[key] dest.update(src) -- cgit v1.2.3 From 4b07d73f4e683d85546d78793a9914a4b5d3d98e Mon Sep 17 00:00:00 2001 From: vladlosev Date: Fri, 9 Sep 2011 05:42:09 +0000 Subject: Ignore SIGPROF signal during clone()/fork() call. clone()/fork() call hangs permanently if it consumes more cpu than the SIGPROF signal timer interval (by Nabeel Mian). --- test/gtest-death-test_test.cc | 55 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) (limited to 'test') diff --git a/test/gtest-death-test_test.cc b/test/gtest-death-test_test.cc index bcf8e2a3..afbdf8a2 100644 --- a/test/gtest-death-test_test.cc +++ b/test/gtest-death-test_test.cc @@ -52,6 +52,10 @@ using testing::internal::AlwaysTrue; # include # include +# if GTEST_OS_LINUX +# include +# endif // GTEST_OS_LINUX + # include "gtest/gtest-spi.h" // Indicates that this translation unit is part of Google Test's @@ -372,6 +376,57 @@ TEST_F(TestForDeathTest, FastDeathTestInChangedDir) { ASSERT_DEATH(_exit(1), ""); } +# if GTEST_OS_LINUX +void SigprofAction(int, siginfo_t*, void*) { /* no op */ } + +// Sets SIGPROF action and ITIMER_PROF timer (interval: 1ms). +void SetSigprofActionAndTimer() { + struct itimerval timer; + timer.it_interval.tv_sec = 0; + timer.it_interval.tv_usec = 1; + timer.it_value = timer.it_interval; + ASSERT_EQ(0, setitimer(ITIMER_PROF, &timer, NULL)); + struct sigaction signal_action; + memset(&signal_action, 0, sizeof(signal_action)); + sigemptyset(&signal_action.sa_mask); + signal_action.sa_sigaction = SigprofAction; + signal_action.sa_flags = SA_RESTART | SA_SIGINFO; + ASSERT_EQ(0, sigaction(SIGPROF, &signal_action, NULL)); +} + +// Disables ITIMER_PROF timer and ignores SIGPROF signal. +void DisableSigprofActionAndTimer(struct sigaction* old_signal_action) { + struct itimerval timer; + timer.it_interval.tv_usec = 0; + timer.it_value.tv_usec = 0; + ASSERT_EQ(0, setitimer(ITIMER_PROF, &timer, NULL)); + struct sigaction signal_action; + memset(&signal_action, 0, sizeof(signal_action)); + sigemptyset(&signal_action.sa_mask); + signal_action.sa_handler = SIG_IGN; + ASSERT_EQ(0, sigaction(SIGPROF, &signal_action, old_signal_action)); +} + +// Tests that death tests work when SIGPROF handler and timer are set. +TEST_F(TestForDeathTest, FastSigprofActionSet) { + testing::GTEST_FLAG(death_test_style) = "fast"; + SetSigprofActionAndTimer(); + EXPECT_DEATH(_exit(1), ""); + struct sigaction old_signal_action; + DisableSigprofActionAndTimer(&old_signal_action); + EXPECT_TRUE(old_signal_action.sa_sigaction == SigprofAction); +} + +TEST_F(TestForDeathTest, ThreadSafeSigprofActionSet) { + testing::GTEST_FLAG(death_test_style) = "threadsafe"; + SetSigprofActionAndTimer(); + EXPECT_DEATH(_exit(1), ""); + struct sigaction old_signal_action; + DisableSigprofActionAndTimer(&old_signal_action); + EXPECT_TRUE(old_signal_action.sa_sigaction == SigprofAction); +} +# endif // GTEST_OS_LINUX + // Repeats a representative sample of death tests in the "threadsafe" style: TEST_F(TestForDeathTest, StaticMemberFunctionThreadsafeStyle) { -- cgit v1.2.3 From 1b2e50995887d7128f486eeb0544345296215d30 Mon Sep 17 00:00:00 2001 From: vladlosev Date: Mon, 26 Sep 2011 17:52:19 +0000 Subject: Fixes C++0x compatibility problems. --- test/gtest-port_test.cc | 58 +++++++++++++++++++++++++------------------------ 1 file changed, 30 insertions(+), 28 deletions(-) (limited to 'test') diff --git a/test/gtest-port_test.cc b/test/gtest-port_test.cc index 9ae78769..b0177cf1 100644 --- a/test/gtest-port_test.cc +++ b/test/gtest-port_test.cc @@ -968,23 +968,23 @@ TEST(ThreadLocalTest, ValueDefaultContructorIsNotRequiredForParamVersion) { } TEST(ThreadLocalTest, GetAndPointerReturnSameValue) { - ThreadLocal thread_local; + ThreadLocal thread_local_string; - EXPECT_EQ(thread_local.pointer(), &(thread_local.get())); + EXPECT_EQ(thread_local_string.pointer(), &(thread_local_string.get())); // Verifies the condition still holds after calling set. - thread_local.set("foo"); - EXPECT_EQ(thread_local.pointer(), &(thread_local.get())); + thread_local_string.set("foo"); + EXPECT_EQ(thread_local_string.pointer(), &(thread_local_string.get())); } TEST(ThreadLocalTest, PointerAndConstPointerReturnSameValue) { - ThreadLocal thread_local; - const ThreadLocal& const_thread_local = thread_local; + ThreadLocal thread_local_string; + const ThreadLocal& const_thread_local_string = thread_local_string; - EXPECT_EQ(thread_local.pointer(), const_thread_local.pointer()); + EXPECT_EQ(thread_local_string.pointer(), const_thread_local_string.pointer()); - thread_local.set("foo"); - EXPECT_EQ(thread_local.pointer(), const_thread_local.pointer()); + thread_local_string.set("foo"); + EXPECT_EQ(thread_local_string.pointer(), const_thread_local_string.pointer()); } #if GTEST_IS_THREADSAFE @@ -1094,14 +1094,15 @@ void RetrieveThreadLocalValue(pair*, String*> param) { } TEST(ThreadLocalTest, ParameterizedConstructorSetsDefault) { - ThreadLocal thread_local("foo"); - EXPECT_STREQ("foo", thread_local.get().c_str()); + ThreadLocal thread_local_string("foo"); + EXPECT_STREQ("foo", thread_local_string.get().c_str()); - thread_local.set("bar"); - EXPECT_STREQ("bar", thread_local.get().c_str()); + thread_local_string.set("bar"); + EXPECT_STREQ("bar", thread_local_string.get().c_str()); String result; - RunFromThread(&RetrieveThreadLocalValue, make_pair(&thread_local, &result)); + RunFromThread(&RetrieveThreadLocalValue, + make_pair(&thread_local_string, &result)); EXPECT_STREQ("foo", result.c_str()); } @@ -1130,8 +1131,8 @@ class DestructorTracker { typedef ThreadLocal* ThreadParam; -void CallThreadLocalGet(ThreadParam thread_local) { - thread_local->get(); +void CallThreadLocalGet(ThreadParam thread_local_param) { + thread_local_param->get(); } // Tests that when a ThreadLocal object dies in a thread, it destroys @@ -1141,19 +1142,19 @@ TEST(ThreadLocalTest, DestroysManagedObjectForOwnThreadWhenDying) { { // The next line default constructs a DestructorTracker object as - // the default value of objects managed by thread_local. - ThreadLocal thread_local; + // the default value of objects managed by thread_local_tracker. + ThreadLocal thread_local_tracker; ASSERT_EQ(1U, g_destroyed.size()); ASSERT_FALSE(g_destroyed[0]); // This creates another DestructorTracker object for the main thread. - thread_local.get(); + thread_local_tracker.get(); ASSERT_EQ(2U, g_destroyed.size()); ASSERT_FALSE(g_destroyed[0]); ASSERT_FALSE(g_destroyed[1]); } - // Now thread_local has died. It should have destroyed both the + // Now thread_local_tracker has died. It should have destroyed both the // default value shared by all threads and the value for the main // thread. ASSERT_EQ(2U, g_destroyed.size()); @@ -1170,14 +1171,14 @@ TEST(ThreadLocalTest, DestroysManagedObjectAtThreadExit) { { // The next line default constructs a DestructorTracker object as - // the default value of objects managed by thread_local. - ThreadLocal thread_local; + // the default value of objects managed by thread_local_tracker. + ThreadLocal thread_local_tracker; ASSERT_EQ(1U, g_destroyed.size()); ASSERT_FALSE(g_destroyed[0]); // This creates another DestructorTracker object in the new thread. ThreadWithParam thread( - &CallThreadLocalGet, &thread_local, NULL); + &CallThreadLocalGet, &thread_local_tracker, NULL); thread.Join(); // Now the new thread has exited. The per-thread object for it @@ -1187,7 +1188,7 @@ TEST(ThreadLocalTest, DestroysManagedObjectAtThreadExit) { ASSERT_TRUE(g_destroyed[1]); } - // Now thread_local has died. The default value should have been + // Now thread_local_tracker has died. The default value should have been // destroyed too. ASSERT_EQ(2U, g_destroyed.size()); EXPECT_TRUE(g_destroyed[0]); @@ -1197,12 +1198,13 @@ TEST(ThreadLocalTest, DestroysManagedObjectAtThreadExit) { } TEST(ThreadLocalTest, ThreadLocalMutationsAffectOnlyCurrentThread) { - ThreadLocal thread_local; - thread_local.set("Foo"); - EXPECT_STREQ("Foo", thread_local.get().c_str()); + ThreadLocal thread_local_string; + thread_local_string.set("Foo"); + EXPECT_STREQ("Foo", thread_local_string.get().c_str()); String result; - RunFromThread(&RetrieveThreadLocalValue, make_pair(&thread_local, &result)); + RunFromThread(&RetrieveThreadLocalValue, + make_pair(&thread_local_string, &result)); EXPECT_TRUE(result.c_str() == NULL); } -- cgit v1.2.3 From 879916a9393ef4af84ebe8b331220586dd8cafbb Mon Sep 17 00:00:00 2001 From: vladlosev Date: Wed, 5 Oct 2011 05:49:40 +0000 Subject: Fixes test failure on 32-bit Ubuntu. --- test/gtest-death-test_test.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'test') diff --git a/test/gtest-death-test_test.cc b/test/gtest-death-test_test.cc index afbdf8a2..15f6719b 100644 --- a/test/gtest-death-test_test.cc +++ b/test/gtest-death-test_test.cc @@ -397,8 +397,9 @@ void SetSigprofActionAndTimer() { // Disables ITIMER_PROF timer and ignores SIGPROF signal. void DisableSigprofActionAndTimer(struct sigaction* old_signal_action) { struct itimerval timer; + timer.it_interval.tv_sec = 0; timer.it_interval.tv_usec = 0; - timer.it_value.tv_usec = 0; + timer.it_value = timer.it_interval; ASSERT_EQ(0, setitimer(ITIMER_PROF, &timer, NULL)); struct sigaction signal_action; memset(&signal_action, 0, sizeof(signal_action)); -- cgit v1.2.3 From 431a8be1662a3bc9601240914f412b0436d94703 Mon Sep 17 00:00:00 2001 From: vladlosev Date: Wed, 5 Oct 2011 05:52:34 +0000 Subject: Implements the timestamp attribute for the testsuites element in the output XML (external contribution by Dirk Meister). --- test/gtest_unittest.cc | 106 ++++++++++++++++++++++++++++++++++++++ test/gtest_xml_outfiles_test.py | 4 +- test/gtest_xml_output_unittest.py | 64 ++++++++++++++++++----- test/gtest_xml_test_utils.py | 54 ++++++++++--------- 4 files changed, 188 insertions(+), 40 deletions(-) (limited to 'test') diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index 23d6860e..0d624fd7 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -71,6 +71,7 @@ TEST(CommandLineFlagsTest, CanBeAccessedInCodeOnceGTestHIsIncluded) { #include // For INT_MAX. #include +#include #include #include @@ -141,6 +142,7 @@ using testing::TestPartResult; using testing::TestPartResultArray; using testing::TestProperty; using testing::TestResult; +using testing::TimeInMillis; using testing::UnitTest; using testing::kMaxStackTraceDepth; using testing::internal::AddReference; @@ -156,6 +158,7 @@ using testing::internal::CountIf; using testing::internal::EqFailure; using testing::internal::FloatingPoint; using testing::internal::ForEach; +using testing::internal::FormatEpochTimeInMillisAsIso8601; using testing::internal::FormatTimeInMillisAsSeconds; using testing::internal::GTestFlagSaver; using testing::internal::GetCurrentOsStackTraceExceptTop; @@ -163,6 +166,7 @@ using testing::internal::GetElementOr; using testing::internal::GetNextRandomSeed; using testing::internal::GetRandomSeedFromFlag; using testing::internal::GetTestTypeId; +using testing::internal::GetTimeInMillis; using testing::internal::GetTypeId; using testing::internal::GetUnitTestImpl; using testing::internal::ImplicitlyConvertible; @@ -308,6 +312,103 @@ TEST(FormatTimeInMillisAsSecondsTest, FormatsNegativeNumber) { EXPECT_EQ("-3", FormatTimeInMillisAsSeconds(-3000)); } +// Tests FormatEpochTimeInMillisAsIso8601(). The correctness of conversion +// for particular dates below was verified in Python using +// datetime.datetime.fromutctimestamp(/1000). + +// FormatEpochTimeInMillisAsIso8601 depends on the current timezone, so we +// have to set up a particular timezone to obtain predictable results. +class FormatEpochTimeInMillisAsIso8601Test : public Test { + public: + // On Cygwin, GCC doesn't allow unqualified integer literals to exceed + // 32 bits, even when 64-bit integer types are available. We have to + // force the constants to have a 64-bit type here. + static const TimeInMillis kMillisPerSec = 1000; + + private: + virtual void SetUp() { + saved_tz_ = NULL; +#if _MSC_VER +# pragma warning(push) // Saves the current warning state. +# pragma warning(disable:4996) // Temporarily disables warning 4996 + // (function or variable may be unsafe + // for getenv, function is deprecated for + // strdup). + if (getenv("TZ")) + saved_tz_ = strdup(getenv("TZ")); +# pragma warning(pop) // Restores the warning state again. +#else + if (getenv("TZ")) + saved_tz_ = strdup(getenv("TZ")); +#endif + + // Set up the time zone for FormatEpochTimeInMillisAsIso8601 to use. We + // cannot use the local time zone because the function's output depends + // on the time zone. + SetTimeZone("UTC+00"); + } + + virtual void TearDown() { + SetTimeZone(saved_tz_); + free(const_cast(saved_tz_)); + saved_tz_ = NULL; + } + + static void SetTimeZone(const char* time_zone) { + // tzset() distinguishes between the TZ variable being present and empty + // and not being present, so we have to consider the case of time_zone + // being NULL. +#if _MSC_VER + // ...Unless it's MSVC, whose standard library's _putenv doesn't + // distinguish between an empty and a missing variable. + const std::string env_var = + std::string("TZ=") + (time_zone ? time_zone : ""); + _putenv(env_var.c_str()); +# pragma warning(push) // Saves the current warning state. +# pragma warning(disable:4996) // Temporarily disables warning 4996 + // (function is deprecated). + tzset(); +# pragma warning(pop) // Restores the warning state again. +#else + if (time_zone) { + setenv(("TZ"), time_zone, 1); + } else { + unsetenv("TZ"); + } + tzset(); +#endif + } + + const char* saved_tz_; +}; + +const TimeInMillis FormatEpochTimeInMillisAsIso8601Test::kMillisPerSec; + +TEST_F(FormatEpochTimeInMillisAsIso8601Test, PrintsTwoDigitSegments) { + EXPECT_EQ("2011-10-31T18:52:42", + FormatEpochTimeInMillisAsIso8601(1320087162 * kMillisPerSec)); +} + +TEST_F(FormatEpochTimeInMillisAsIso8601Test, MillisecondsDoNotAffectResult) { + EXPECT_EQ( + "2011-10-31T18:52:42", + FormatEpochTimeInMillisAsIso8601(1320087162 * kMillisPerSec + 234)); +} + +TEST_F(FormatEpochTimeInMillisAsIso8601Test, PrintsLeadingZeroes) { + EXPECT_EQ("2011-09-03T05:07:02", + FormatEpochTimeInMillisAsIso8601(1315026422 * kMillisPerSec)); +} + +TEST_F(FormatEpochTimeInMillisAsIso8601Test, Prints24HourTime) { + EXPECT_EQ("2011-09-28T17:08:22", + FormatEpochTimeInMillisAsIso8601(1317229702 * kMillisPerSec)); +} + +TEST_F(FormatEpochTimeInMillisAsIso8601Test, PrintsEpochStart) { + EXPECT_EQ("1970-01-01T00:00:00", FormatEpochTimeInMillisAsIso8601(0)); +} + #if GTEST_CAN_COMPARE_NULL # ifdef __BORLANDC__ @@ -2130,6 +2231,11 @@ TEST(UnitTestTest, CanGetOriginalWorkingDir) { EXPECT_STRNE(UnitTest::GetInstance()->original_working_dir(), ""); } +TEST(UnitTestTest, ReturnsPlausibleTimestamp) { + EXPECT_LT(0, UnitTest::GetInstance()->start_timestamp()); + EXPECT_LE(UnitTest::GetInstance()->start_timestamp(), GetTimeInMillis()); +} + // This group of tests is for predicate assertions (ASSERT_PRED*, etc) // of various arities. They do not attempt to be exhaustive. Rather, // view them as smoke tests that can be easily reviewed and verified. diff --git a/test/gtest_xml_outfiles_test.py b/test/gtest_xml_outfiles_test.py index 0fe947f0..524e437e 100755 --- a/test/gtest_xml_outfiles_test.py +++ b/test/gtest_xml_outfiles_test.py @@ -45,7 +45,7 @@ GTEST_OUTPUT_1_TEST = "gtest_xml_outfile1_test_" GTEST_OUTPUT_2_TEST = "gtest_xml_outfile2_test_" EXPECTED_XML_1 = """ - + @@ -53,7 +53,7 @@ EXPECTED_XML_1 = """ """ EXPECTED_XML_2 = """ - + diff --git a/test/gtest_xml_output_unittest.py b/test/gtest_xml_output_unittest.py index 06637e5b..83903002 100755 --- a/test/gtest_xml_output_unittest.py +++ b/test/gtest_xml_output_unittest.py @@ -33,8 +33,10 @@ __author__ = 'eefacm@gmail.com (Sean Mcafee)' +import datetime import errno import os +import re import sys from xml.dom import minidom, Node @@ -55,7 +57,7 @@ else: STACK_TRACE_TEMPLATE = '' EXPECTED_NON_EMPTY_XML = """ - + @@ -128,7 +130,7 @@ Invalid characters in brackets []%(stack)s]]> EXPECTED_EMPTY_XML = """ - + """ GTEST_PROGRAM_PATH = gtest_test_utils.GetTestExecutablePath(GTEST_PROGRAM_NAME) @@ -153,13 +155,39 @@ class GTestXMLOutputUnitTest(gtest_xml_test_utils.GTestXMLTestCase): self._TestXmlOutput(GTEST_PROGRAM_NAME, EXPECTED_NON_EMPTY_XML, 1) def testEmptyXmlOutput(self): - """ + """Verifies XML output for a Google Test binary without actual tests. + Runs a test program that generates an empty XML output, and tests that the XML output is expected. """ self._TestXmlOutput('gtest_no_test_unittest', EXPECTED_EMPTY_XML, 0) + def testTimestampValue(self): + """Checks whether the timestamp attribute in the XML output is valid. + + Runs a test program that generates an empty XML output, and checks if + the timestamp attribute in the testsuites tag is valid. + """ + actual = self._GetXmlOutput('gtest_no_test_unittest', 0) + date_time_str = actual.documentElement.getAttributeNode('timestamp').value + # datetime.strptime() is only available in Python 2.5+ so we have to + # parse the expected datetime manually. + match = re.match(r'(\d+)-(\d\d)-(\d\d)T(\d\d):(\d\d):(\d\d)', date_time_str) + self.assertTrue( + re.match, + 'XML datettime string %s has incorrect format' % date_time_str) + date_time_from_xml = datetime.datetime( + year=int(match.group(1)), month=int(match.group(2)), + day=int(match.group(3)), hour=int(match.group(4)), + minute=int(match.group(5)), second=int(match.group(6))) + + time_delta = abs(datetime.datetime.now() - date_time_from_xml) + # timestamp value should be near the current local time + self.assertTrue(time_delta < datetime.timedelta(seconds=600), + 'time_delta is %s' % time_delta) + actual.unlink() + def testDefaultOutputFile(self): """ Confirms that Google Test produces an XML output file with the expected @@ -198,8 +226,10 @@ class GTestXMLOutputUnitTest(gtest_xml_test_utils.GTestXMLTestCase): '--shut_down_xml'] p = gtest_test_utils.Subprocess(command) if p.terminated_by_signal: - self.assert_(False, - '%s was killed by signal %d' % (gtest_prog_name, p.signal)) + # p.signal is avalable only if p.terminated_by_signal is True. + self.assertFalse( + p.terminated_by_signal, + '%s was killed by signal %d' % (GTEST_PROGRAM_NAME, p.signal)) else: self.assert_(p.exited) self.assertEquals(1, p.exit_code, @@ -209,13 +239,10 @@ class GTestXMLOutputUnitTest(gtest_xml_test_utils.GTestXMLTestCase): self.assert_(not os.path.isfile(xml_path)) - - def _TestXmlOutput(self, gtest_prog_name, expected_xml, expected_exit_code): + def _GetXmlOutput(self, gtest_prog_name, expected_exit_code): """ - Asserts that the XML document generated by running the program - gtest_prog_name matches expected_xml, a string containing another - XML document. Furthermore, the program's exit code must be - expected_exit_code. + Returns the xml output generated by running the program gtest_prog_name. + Furthermore, the program's exit code must be expected_exit_code. """ xml_path = os.path.join(gtest_test_utils.GetTempDir(), gtest_prog_name + 'out.xml') @@ -232,15 +259,24 @@ class GTestXMLOutputUnitTest(gtest_xml_test_utils.GTestXMLTestCase): "'%s' exited with code %s, which doesn't match " 'the expected exit code %s.' % (command, p.exit_code, expected_exit_code)) + actual = minidom.parse(xml_path) + return actual + def _TestXmlOutput(self, gtest_prog_name, expected_xml, expected_exit_code): + """ + Asserts that the XML document generated by running the program + gtest_prog_name matches expected_xml, a string containing another + XML document. Furthermore, the program's exit code must be + expected_exit_code. + """ + + actual = self._GetXmlOutput(gtest_prog_name, expected_exit_code) expected = minidom.parseString(expected_xml) - actual = minidom.parse(xml_path) self.NormalizeXml(actual.documentElement) self.AssertEquivalentNodes(expected.documentElement, actual.documentElement) expected.unlink() - actual .unlink() - + actual.unlink() if __name__ == '__main__': diff --git a/test/gtest_xml_test_utils.py b/test/gtest_xml_test_utils.py index 0f55c164..f94d634b 100755 --- a/test/gtest_xml_test_utils.py +++ b/test/gtest_xml_test_utils.py @@ -39,8 +39,8 @@ from xml.dom import minidom, Node import gtest_test_utils -GTEST_OUTPUT_FLAG = "--gtest_output" -GTEST_DEFAULT_OUTPUT_FILE = "test_detail.xml" +GTEST_OUTPUT_FLAG = '--gtest_output' +GTEST_DEFAULT_OUTPUT_FILE = 'test_detail.xml' class GTestXMLTestCase(gtest_test_utils.TestCase): """ @@ -80,23 +80,23 @@ class GTestXMLTestCase(gtest_test_utils.TestCase): actual_attributes = actual_node .attributes self.assertEquals( expected_attributes.length, actual_attributes.length, - "attribute numbers differ in element " + actual_node.tagName) + 'attribute numbers differ in element ' + actual_node.tagName) for i in range(expected_attributes.length): expected_attr = expected_attributes.item(i) actual_attr = actual_attributes.get(expected_attr.name) self.assert_( actual_attr is not None, - "expected attribute %s not found in element %s" % + 'expected attribute %s not found in element %s' % (expected_attr.name, actual_node.tagName)) self.assertEquals(expected_attr.value, actual_attr.value, - " values of attribute %s in element %s differ" % + ' values of attribute %s in element %s differ' % (expected_attr.name, actual_node.tagName)) expected_children = self._GetChildren(expected_node) actual_children = self._GetChildren(actual_node) self.assertEquals( len(expected_children), len(actual_children), - "number of child elements differ in element " + actual_node.tagName) + 'number of child elements differ in element ' + actual_node.tagName) for child_id, child in expected_children.iteritems(): self.assert_(child_id in actual_children, '<%s> is not in <%s> (in element %s)' % @@ -104,10 +104,10 @@ class GTestXMLTestCase(gtest_test_utils.TestCase): self.AssertEquivalentNodes(child, actual_children[child_id]) identifying_attribute = { - "testsuites": "name", - "testsuite": "name", - "testcase": "name", - "failure": "message", + 'testsuites': 'name', + 'testsuite': 'name', + 'testcase': 'name', + 'failure': 'message', } def _GetChildren(self, element): @@ -127,20 +127,20 @@ class GTestXMLTestCase(gtest_test_utils.TestCase): for child in element.childNodes: if child.nodeType == Node.ELEMENT_NODE: self.assert_(child.tagName in self.identifying_attribute, - "Encountered unknown element <%s>" % child.tagName) + 'Encountered unknown element <%s>' % child.tagName) childID = child.getAttribute(self.identifying_attribute[child.tagName]) self.assert_(childID not in children) children[childID] = child elif child.nodeType in [Node.TEXT_NODE, Node.CDATA_SECTION_NODE]: - if "detail" not in children: + if 'detail' not in children: if (child.nodeType == Node.CDATA_SECTION_NODE or not child.nodeValue.isspace()): - children["detail"] = child.ownerDocument.createCDATASection( + children['detail'] = child.ownerDocument.createCDATASection( child.nodeValue) else: - children["detail"].nodeValue += child.nodeValue + children['detail'].nodeValue += child.nodeValue else: - self.fail("Encountered unexpected node type %d" % child.nodeType) + self.fail('Encountered unexpected node type %d' % child.nodeType) return children def NormalizeXml(self, element): @@ -151,6 +151,8 @@ class GTestXMLTestCase(gtest_test_utils.TestCase): * The "time" attribute of , and elements is replaced with a single asterisk, if it contains only digit characters. + * The "timestamp" attribute of elements is replaced with a + single asterisk, if it contains a valid ISO8601 datetime value. * The "type_param" attribute of elements is replaced with a single asterisk (if it sn non-empty) as it is the type name returned by the compiler and is platform dependent. @@ -160,20 +162,24 @@ class GTestXMLTestCase(gtest_test_utils.TestCase): * The stack traces are removed. """ - if element.tagName in ("testsuites", "testsuite", "testcase"): - time = element.getAttributeNode("time") - time.value = re.sub(r"^\d+(\.\d+)?$", "*", time.value) - type_param = element.getAttributeNode("type_param") + if element.tagName == 'testsuites': + timestamp = element.getAttributeNode('timestamp') + timestamp.value = re.sub(r'^\d{4}-\d\d-\d\dT\d\d:\d\d:\d\d$', + '*', timestamp.value) + if element.tagName in ('testsuites', 'testsuite', 'testcase'): + time = element.getAttributeNode('time') + time.value = re.sub(r'^\d+(\.\d+)?$', '*', time.value) + type_param = element.getAttributeNode('type_param') if type_param and type_param.value: - type_param.value = "*" - elif element.tagName == "failure": + type_param.value = '*' + elif element.tagName == 'failure': for child in element.childNodes: if child.nodeType == Node.CDATA_SECTION_NODE: # Removes the source line number. - cdata = re.sub(r"^.*[/\\](.*:)\d+\n", "\\1*\n", child.nodeValue) + cdata = re.sub(r'^.*[/\\](.*:)\d+\n', '\\1*\n', child.nodeValue) # Removes the actual stack trace. - child.nodeValue = re.sub(r"\nStack trace:\n(.|\n)*", - "", cdata) + child.nodeValue = re.sub(r'\nStack trace:\n(.|\n)*', + '', cdata) for child in element.childNodes: if child.nodeType == Node.ELEMENT_NODE: self.NormalizeXml(child) -- cgit v1.2.3 From 97ef1c705eb24945cf4a2bca9eafe5357281703b Mon Sep 17 00:00:00 2001 From: vladlosev Date: Mon, 24 Oct 2011 18:33:26 +0000 Subject: Changes to fix gtest-printers_test on VC++ 2010. --- test/gtest-printers_test.cc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'test') diff --git a/test/gtest-printers_test.cc b/test/gtest-printers_test.cc index 6292c7f2..58044ab5 100644 --- a/test/gtest-printers_test.cc +++ b/test/gtest-printers_test.cc @@ -197,6 +197,7 @@ using ::std::pair; using ::std::set; using ::std::vector; using ::testing::PrintToString; +using ::testing::internal::ImplicitCast_; using ::testing::internal::NativeArray; using ::testing::internal::RE; using ::testing::internal::Strings; @@ -1002,9 +1003,12 @@ TEST(PrintTupleTest, VariousSizes) { EXPECT_EQ("(false, 2, 3, 4, true, 6, 7, true, 9)", Print(t9)); const char* const str = "8"; + // VC++ 2010's implementation of tuple of C++0x is deficient, requiring + // an explicit type cast of NULL to be used. tuple - t10(false, 'a', 3, 4, 5, 1.5F, -2.5, str, NULL, "10"); + t10(false, 'a', 3, 4, 5, 1.5F, -2.5, str, + ImplicitCast_(NULL), "10"); EXPECT_EQ("(false, 'a' (97, 0x61), 3, 4, 5, 1.5, -2.5, " + PrintPointer(str) + " pointing to \"8\", NULL, \"10\")", Print(t10)); -- cgit v1.2.3 From 829402edcffe712ed4c79412ca020525cd8295ad Mon Sep 17 00:00:00 2001 From: vladlosev Date: Fri, 28 Oct 2011 16:19:04 +0000 Subject: Adds support for detection of running in death test child processes. --- test/gtest-death-test_test.cc | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'test') diff --git a/test/gtest-death-test_test.cc b/test/gtest-death-test_test.cc index 15f6719b..54f5a1a1 100644 --- a/test/gtest-death-test_test.cc +++ b/test/gtest-death-test_test.cc @@ -75,6 +75,7 @@ using testing::internal::DeathTestFactory; using testing::internal::FilePath; using testing::internal::GetLastErrnoDescription; using testing::internal::GetUnitTestImpl; +using testing::internal::InDeathTestChild; using testing::internal::ParseNaturalNumber; using testing::internal::String; @@ -1345,6 +1346,26 @@ TEST(ConditionalDeathMacrosSyntaxDeathTest, SwitchStatement) { #endif // _MSC_VER } +TEST(InDeathTestChildDeathTest, ReportsDeathTestCorrectlyInFastStyle) { + testing::GTEST_FLAG(death_test_style) = "fast"; + EXPECT_FALSE(InDeathTestChild()); + EXPECT_DEATH({ + fprintf(stderr, InDeathTestChild() ? "Inside" : "Outside"); + fflush(stderr); + _exit(1); + }, "Inside"); +} + +TEST(InDeathTestChildDeathTest, ReportsDeathTestCorrectlyInThreadSafeStyle) { + testing::GTEST_FLAG(death_test_style) = "threadsafe"; + EXPECT_FALSE(InDeathTestChild()); + EXPECT_DEATH({ + fprintf(stderr, InDeathTestChild() ? "Inside" : "Outside"); + fflush(stderr); + _exit(1); + }, "Inside"); +} + // Tests that a test case whose name ends with "DeathTest" works fine // on Windows. TEST(NotADeathTest, Test) { -- cgit v1.2.3 From 8965a6a0d2165f32e6413594bba6367f271f51e7 Mon Sep 17 00:00:00 2001 From: vladlosev Date: Fri, 4 Nov 2011 17:56:23 +0000 Subject: Improves conformance to the Google C++ Style Guide (by Greg Miller). --- test/gtest-death-test_test.cc | 1 + test/gtest-linked_ptr_test.cc | 3 +-- test/gtest-listener_test.cc | 2 +- test/gtest-param-test_test.cc | 2 ++ test/gtest-param-test_test.h | 6 ++++-- test/gtest-port_test.cc | 8 ++++---- test/gtest-printers_test.cc | 2 +- test/gtest_environment_test.cc | 1 + test/gtest_no_test_unittest.cc | 1 - test/gtest_output_test_.cc | 1 + test/gtest_pred_impl_unittest.cc | 2 +- test/gtest_repeat_test.cc | 2 +- test/gtest_unittest.cc | 25 +++++++++++++------------ 13 files changed, 31 insertions(+), 25 deletions(-) (limited to 'test') diff --git a/test/gtest-death-test_test.cc b/test/gtest-death-test_test.cc index 54f5a1a1..5a4a989d 100644 --- a/test/gtest-death-test_test.cc +++ b/test/gtest-death-test_test.cc @@ -896,6 +896,7 @@ class MockDeathTest : public DeathTest { virtual void Abort(AbortReason reason) { parent_->abort_args_.push_back(reason); } + private: MockDeathTestFactory* const parent_; const TestRole role_; diff --git a/test/gtest-linked_ptr_test.cc b/test/gtest-linked_ptr_test.cc index 0d5508ae..6fcf5124 100644 --- a/test/gtest-linked_ptr_test.cc +++ b/test/gtest-linked_ptr_test.cc @@ -148,8 +148,7 @@ TEST_F(LinkedPtrTest, GeneralTest) { "A0 dtor\n" "A3 dtor\n" "A1 dtor\n", - history->GetString().c_str() - ); + history->GetString().c_str()); } } // Unnamed namespace diff --git a/test/gtest-listener_test.cc b/test/gtest-listener_test.cc index 2aa08ef3..10086086 100644 --- a/test/gtest-listener_test.cc +++ b/test/gtest-listener_test.cc @@ -55,7 +55,7 @@ namespace internal { class EventRecordingListener : public TestEventListener { public: - EventRecordingListener(const char* name) : name_(name) {} + explicit EventRecordingListener(const char* name) : name_(name) {} protected: virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) { diff --git a/test/gtest-param-test_test.cc b/test/gtest-param-test_test.cc index 94a53d9f..cf618665 100644 --- a/test/gtest-param-test_test.cc +++ b/test/gtest-param-test_test.cc @@ -606,6 +606,7 @@ class TestGenerationEnvironment : public ::testing::Environment { << "has not been run as expected."; } } + private: TestGenerationEnvironment() : fixture_constructor_count_(0), set_up_count_(0), tear_down_count_(0), test_body_count_(0) {} @@ -674,6 +675,7 @@ class TestGenerationTest : public TestWithParam { EXPECT_TRUE(collected_parameters_ == expected_values); } + protected: int current_parameter_; static vector collected_parameters_; diff --git a/test/gtest-param-test_test.h b/test/gtest-param-test_test.h index d0f6556b..26ea122b 100644 --- a/test/gtest-param-test_test.h +++ b/test/gtest-param-test_test.h @@ -43,12 +43,14 @@ // Test fixture for testing definition and instantiation of a test // in separate translation units. -class ExternalInstantiationTest : public ::testing::TestWithParam {}; +class ExternalInstantiationTest : public ::testing::TestWithParam { +}; // Test fixture for testing instantiation of a test in multiple // translation units. class InstantiationInMultipleTranslaionUnitsTest - : public ::testing::TestWithParam {}; + : public ::testing::TestWithParam { +}; #endif // GTEST_HAS_PARAM_TEST diff --git a/test/gtest-port_test.cc b/test/gtest-port_test.cc index b0177cf1..75471c39 100644 --- a/test/gtest-port_test.cc +++ b/test/gtest-port_test.cc @@ -92,7 +92,7 @@ TEST(ImplicitCastTest, CanUseInheritance) { class Castable { public: - Castable(bool* converted) : converted_(converted) {} + explicit Castable(bool* converted) : converted_(converted) {} operator Base() { *converted_ = true; return Base(); @@ -111,7 +111,7 @@ TEST(ImplicitCastTest, CanUseNonConstCastOperator) { class ConstCastable { public: - ConstCastable(bool* converted) : converted_(converted) {} + explicit ConstCastable(bool* converted) : converted_(converted) {} operator Base() const { *converted_ = true; return Base(); @@ -224,7 +224,7 @@ TEST(GtestCheckSyntaxTest, WorksWithSwitch) { GTEST_CHECK_(true); } - switch(0) + switch (0) case 0: GTEST_CHECK_(true) << "Check failed in switch case"; } @@ -929,7 +929,7 @@ TEST(CaptureTest, CapturesStdoutAndStderr) { TEST(CaptureDeathTest, CannotReenterStdoutCapture) { CaptureStdout(); - EXPECT_DEATH_IF_SUPPORTED(CaptureStdout();, + EXPECT_DEATH_IF_SUPPORTED(CaptureStdout(), "Only one stdout capturer can exist at a time"); GetCapturedStdout(); diff --git a/test/gtest-printers_test.cc b/test/gtest-printers_test.cc index 58044ab5..58d96225 100644 --- a/test/gtest-printers_test.cc +++ b/test/gtest-printers_test.cc @@ -841,7 +841,7 @@ TEST(PrintStlContainerTest, HashMultiSet) { std::vector numbers; for (size_t i = 0; i != result.length(); i++) { if (expected_pattern[i] == 'd') { - ASSERT_TRUE(isdigit(static_cast(result[i])) != 0); + ASSERT_NE(isdigit(static_cast(result[i])), 0); numbers.push_back(result[i] - '0'); } else { EXPECT_EQ(expected_pattern[i], result[i]) << " where result is " diff --git a/test/gtest_environment_test.cc b/test/gtest_environment_test.cc index ec9aa2cd..3cff19e7 100644 --- a/test/gtest_environment_test.cc +++ b/test/gtest_environment_test.cc @@ -96,6 +96,7 @@ class MyEnvironment : public testing::Environment { // Was TearDown() run? bool tear_down_was_run() const { return tear_down_was_run_; } + private: FailureType failure_in_set_up_; bool set_up_was_run_; diff --git a/test/gtest_no_test_unittest.cc b/test/gtest_no_test_unittest.cc index e3a85f12..292599af 100644 --- a/test/gtest_no_test_unittest.cc +++ b/test/gtest_no_test_unittest.cc @@ -34,7 +34,6 @@ #include "gtest/gtest.h" - int main(int argc, char **argv) { testing::InitGoogleTest(&argc, argv); diff --git a/test/gtest_output_test_.cc b/test/gtest_output_test_.cc index 13dbec47..031ae83b 100644 --- a/test/gtest_output_test_.cc +++ b/test/gtest_output_test_.cc @@ -378,6 +378,7 @@ class FatalFailureInFixtureConstructorTest : public testing::Test { << "We should never get here, as the test fixture c'tor " << "had a fatal failure."; } + private: void Init() { FAIL() << "Expected failure #1, in the test fixture c'tor."; diff --git a/test/gtest_pred_impl_unittest.cc b/test/gtest_pred_impl_unittest.cc index 35dc9bcf..a84eff86 100644 --- a/test/gtest_pred_impl_unittest.cc +++ b/test/gtest_pred_impl_unittest.cc @@ -27,7 +27,7 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// This file is AUTOMATICALLY GENERATED on 09/24/2010 by command +// This file is AUTOMATICALLY GENERATED on 10/31/2011 by command // 'gen_gtest_pred_impl.py 5'. DO NOT EDIT BY HAND! // Regression test for gtest_pred_impl.h diff --git a/test/gtest_repeat_test.cc b/test/gtest_repeat_test.cc index 5223dc0e..481012ad 100644 --- a/test/gtest_repeat_test.cc +++ b/test/gtest_repeat_test.cc @@ -71,7 +71,7 @@ namespace { << "Which is: " << expected_val << "\n";\ ::testing::internal::posix::Abort();\ }\ - } while(::testing::internal::AlwaysFalse()) + } while (::testing::internal::AlwaysFalse()) // Used for verifying that global environment set-up and tear-down are diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index 0d624fd7..8cd58be0 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -33,8 +33,6 @@ // Google Test work. #include "gtest/gtest.h" -#include -#include // Verifies that the command line flag variables can be accessed // in code once has been #included. @@ -58,6 +56,15 @@ TEST(CommandLineFlagsTest, CanBeAccessedInCodeOnceGTestHIsIncluded) { EXPECT_TRUE(dummy || !dummy); // Suppresses warning that dummy is unused. } +#include // For INT_MAX. +#include +#include +#include + +#include +#include +#include + #include "gtest/gtest-spi.h" // Indicates that this translation unit is part of Google Test's @@ -69,13 +76,6 @@ TEST(CommandLineFlagsTest, CanBeAccessedInCodeOnceGTestHIsIncluded) { #include "src/gtest-internal-inl.h" #undef GTEST_IMPLEMENTATION_ -#include // For INT_MAX. -#include -#include -#include - -#include - namespace testing { namespace internal { @@ -1141,7 +1141,7 @@ TEST(StringTest, Equals) { EXPECT_TRUE(foo == "foo"); // NOLINT const String bar("x\0y", 3); - EXPECT_FALSE(bar == "x"); + EXPECT_NE(bar, "x"); } // Tests String::operator!=(). @@ -1163,7 +1163,7 @@ TEST(StringTest, NotEquals) { EXPECT_FALSE(foo != "foo"); // NOLINT const String bar("x\0y", 3); - EXPECT_TRUE(bar != "x"); + EXPECT_NE(bar, "x"); } // Tests String::length(). @@ -1902,6 +1902,7 @@ class GTestFlagSaverTest : public Test { GTEST_FLAG(stream_result_to) = "localhost:1234"; GTEST_FLAG(throw_on_failure) = true; } + private: // For saving Google Test flags during this test case. static GTestFlagSaver* saver_; @@ -2797,7 +2798,6 @@ TEST(IsNotSubstringTest, ReturnsCorrectResultForStdWstring) { template class FloatingPointTest : public Test { protected: - // Pre-calculated numbers to be used by the tests. struct TestValues { RawType close_to_positive_zero; @@ -7278,6 +7278,7 @@ TEST(ArrayEqTest, WorksForDegeneratedArrays) { } TEST(ArrayEqTest, WorksForOneDimensionalArrays) { + // Note that a and b are distinct but compatible types. const int a[] = { 0, 1 }; long b[] = { 0, 1 }; EXPECT_TRUE(ArrayEq(a, b)); -- cgit v1.2.3 From 4d6f296e8e5d3f839ef4868390bbec27cb12e068 Mon Sep 17 00:00:00 2001 From: jgm Date: Tue, 17 Jan 2012 15:11:32 +0000 Subject: Adds file and line information to the "message", which is used as the summary of a failure. --- test/gtest_xml_output_unittest.py | 10 +++++----- test/gtest_xml_test_utils.py | 13 +++++++++---- 2 files changed, 14 insertions(+), 9 deletions(-) (limited to 'test') diff --git a/test/gtest_xml_output_unittest.py b/test/gtest_xml_output_unittest.py index 83903002..1bcd4187 100755 --- a/test/gtest_xml_output_unittest.py +++ b/test/gtest_xml_output_unittest.py @@ -63,7 +63,7 @@ EXPECTED_NON_EMPTY_XML = """ - @@ -71,10 +71,10 @@ Expected: 1%(stack)s]]> - - @@ -82,14 +82,14 @@ Expected: 2%(stack)s]]> - ]]>%(stack)s]]> - diff --git a/test/gtest_xml_test_utils.py b/test/gtest_xml_test_utils.py index f94d634b..0e5a1089 100755 --- a/test/gtest_xml_test_utils.py +++ b/test/gtest_xml_test_utils.py @@ -156,8 +156,9 @@ class GTestXMLTestCase(gtest_test_utils.TestCase): * The "type_param" attribute of elements is replaced with a single asterisk (if it sn non-empty) as it is the type name returned by the compiler and is platform dependent. - * The line number reported in the first line of the "message" - attribute of elements is replaced with a single asterisk. + * The line info reported in the first line of the "message" + attribute and CDATA section of elements is replaced with the + file's basename and a single asterisk for the line number. * The directory names in file paths are removed. * The stack traces are removed. """ @@ -173,10 +174,14 @@ class GTestXMLTestCase(gtest_test_utils.TestCase): if type_param and type_param.value: type_param.value = '*' elif element.tagName == 'failure': + source_line_pat = r'^.*[/\\](.*:)\d+\n' + # Replaces the source line information with a normalized form. + message = element.getAttributeNode('message') + message.value = re.sub(source_line_pat, '\\1*\n', message.value) for child in element.childNodes: if child.nodeType == Node.CDATA_SECTION_NODE: - # Removes the source line number. - cdata = re.sub(r'^.*[/\\](.*:)\d+\n', '\\1*\n', child.nodeValue) + # Replaces the source line information with a normalized form. + cdata = re.sub(source_line_pat, '\\1*\n', child.nodeValue) # Removes the actual stack trace. child.nodeValue = re.sub(r'\nStack trace:\n(.|\n)*', '', cdata) -- cgit v1.2.3 From f0b86fc3b0f625e1db84f3632cb37bd9eae6ae19 Mon Sep 17 00:00:00 2001 From: jgm Date: Fri, 9 Mar 2012 17:12:39 +0000 Subject: Misc small updates to some debug death code, and to messages streaming to macros --- test/gtest-death-test_test.cc | 32 +++++------ test/gtest_env_var_test.py | 3 +- test/gtest_output_test.py | 2 +- test/gtest_output_test_.cc | 8 +-- test/gtest_shuffle_test.py | 3 +- test/gtest_unittest.cc | 121 ++++++++++++++++++++++++++++++++++++++++-- 6 files changed, 140 insertions(+), 29 deletions(-) (limited to 'test') diff --git a/test/gtest-death-test_test.cc b/test/gtest-death-test_test.cc index 5a4a989d..b389e73b 100644 --- a/test/gtest-death-test_test.cc +++ b/test/gtest-death-test_test.cc @@ -618,8 +618,8 @@ TEST_F(TestForDeathTest, ReturnIsFailure) { "illegal return in test statement."); } -// Tests that EXPECT_DEBUG_DEATH works as expected, -// that is, in debug mode, it: +// Tests that EXPECT_DEBUG_DEATH works as expected, that is, you can stream a +// message to it, and in debug mode it: // 1. Asserts on death. // 2. Has no side effect. // @@ -628,8 +628,8 @@ TEST_F(TestForDeathTest, ReturnIsFailure) { TEST_F(TestForDeathTest, TestExpectDebugDeath) { int sideeffect = 0; - EXPECT_DEBUG_DEATH(DieInDebugElse12(&sideeffect), - "death.*DieInDebugElse12"); + EXPECT_DEBUG_DEATH(DieInDebugElse12(&sideeffect), "death.*DieInDebugElse12") + << "Must accept a streamed message"; # ifdef NDEBUG @@ -644,22 +644,18 @@ TEST_F(TestForDeathTest, TestExpectDebugDeath) { # endif } -// Tests that ASSERT_DEBUG_DEATH works as expected -// In debug mode: -// 1. Asserts on debug death. +// Tests that ASSERT_DEBUG_DEATH works as expected, that is, you can stream a +// message to it, and in debug mode it: +// 1. Asserts on death. // 2. Has no side effect. // -// In opt mode: -// 1. Has side effects and returns the expected value (12). +// And in opt mode, it: +// 1. Has side effects but does not assert. TEST_F(TestForDeathTest, TestAssertDebugDeath) { int sideeffect = 0; - ASSERT_DEBUG_DEATH({ // NOLINT - // Tests that the return value is 12 in opt mode. - EXPECT_EQ(12, DieInDebugElse12(&sideeffect)); - // Tests that the side effect occurred in opt mode. - EXPECT_EQ(12, sideeffect); - }, "death.*DieInDebugElse12"); + ASSERT_DEBUG_DEATH(DieInDebugElse12(&sideeffect), "death.*DieInDebugElse12") + << "Must accept a streamed message"; # ifdef NDEBUG @@ -730,7 +726,7 @@ static void TestExitMacros() { // Of all signals effects on the process exit code, only those of SIGABRT // are documented on Windows. // See http://msdn.microsoft.com/en-us/library/dwwzkt4c(VS.71).aspx. - EXPECT_EXIT(raise(SIGABRT), testing::ExitedWithCode(3), ""); + EXPECT_EXIT(raise(SIGABRT), testing::ExitedWithCode(3), "") << "b_ar"; # else @@ -739,14 +735,14 @@ static void TestExitMacros() { EXPECT_FATAL_FAILURE({ // NOLINT ASSERT_EXIT(_exit(0), testing::KilledBySignal(SIGSEGV), "") - << "This failure is expected, too."; + << "This failure is expected, too."; }, "This failure is expected, too."); # endif // GTEST_OS_WINDOWS EXPECT_NONFATAL_FAILURE({ // NOLINT EXPECT_EXIT(raise(SIGSEGV), testing::ExitedWithCode(0), "") - << "This failure is expected."; + << "This failure is expected."; }, "This failure is expected."); } diff --git a/test/gtest_env_var_test.py b/test/gtest_env_var_test.py index ac24337f..4728bbc3 100755 --- a/test/gtest_env_var_test.py +++ b/test/gtest_env_var_test.py @@ -67,7 +67,8 @@ def GetFlag(flag): args = [COMMAND] if flag is not None: args += [flag] - return gtest_test_utils.Subprocess(args, env=environ).output + return gtest_test_utils.Subprocess(args, env=environ, + capture_stderr=False).output def TestFlag(flag, test_val, default_val): diff --git a/test/gtest_output_test.py b/test/gtest_output_test.py index f409e2a7..72b3ae00 100755 --- a/test/gtest_output_test.py +++ b/test/gtest_output_test.py @@ -213,7 +213,7 @@ def GetShellCommandOutput(env_cmd): # Set and save the environment properly. environ = os.environ.copy() environ.update(env_cmd[0]) - p = gtest_test_utils.Subprocess(env_cmd[1], env=environ) + p = gtest_test_utils.Subprocess(env_cmd[1], env=environ, capture_stderr=False) return p.output diff --git a/test/gtest_output_test_.cc b/test/gtest_output_test_.cc index 031ae83b..1b08b65b 100644 --- a/test/gtest_output_test_.cc +++ b/test/gtest_output_test_.cc @@ -221,13 +221,13 @@ TEST(SCOPED_TRACETest, CanBeRepeated) { { SCOPED_TRACE("C"); - ADD_FAILURE() << "This failure is expected, and should contain " - << "trace point A, B, and C."; + ADD_FAILURE() << "This failure is expected, and should " + << "contain trace point A, B, and C."; } SCOPED_TRACE("D"); - ADD_FAILURE() << "This failure is expected, and should contain " - << "trace point A, B, and D."; + ADD_FAILURE() << "This failure is expected, and should " + << "contain trace point A, B, and D."; } #if GTEST_IS_THREADSAFE diff --git a/test/gtest_shuffle_test.py b/test/gtest_shuffle_test.py index 30d0303d..d3e57809 100755 --- a/test/gtest_shuffle_test.py +++ b/test/gtest_shuffle_test.py @@ -81,7 +81,8 @@ def RunAndReturnOutput(extra_env, args): environ_copy = os.environ.copy() environ_copy.update(extra_env) - return gtest_test_utils.Subprocess([COMMAND] + args, env=environ_copy).output + return gtest_test_utils.Subprocess([COMMAND] + args, env=environ_copy, + capture_stderr=False).output def GetTestsForAllIterations(extra_env, args): diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index 8cd58be0..e61f7919 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -2642,6 +2642,11 @@ TEST(StringAssertionTest, STREQ_Wide) { // Strings containing wide characters. EXPECT_NONFATAL_FAILURE(EXPECT_STREQ(L"abc\x8119", L"abc\x8120"), "abc"); + + // The streaming variation. + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_STREQ(L"abc\x8119", L"abc\x8121") << "Expected failure"; + }, "Expected failure"); } // Tests *_STRNE on wide strings. @@ -2668,6 +2673,9 @@ TEST(StringAssertionTest, STRNE_Wide) { // Strings containing wide characters. EXPECT_NONFATAL_FAILURE(EXPECT_STRNE(L"abc\x8119", L"abc\x8119"), "abc"); + + // The streaming variation. + ASSERT_STRNE(L"abc\x8119", L"abc\x8120") << "This shouldn't happen"; } // Tests for ::testing::IsSubstring(). @@ -4263,8 +4271,109 @@ TEST(SuccessfulAssertionTest, ASSERT_STR) { namespace { +// Tests the message streaming variation of assertions. + +TEST(AssertionWithMessageTest, EXPECT) { + EXPECT_EQ(1, 1) << "This should succeed."; + EXPECT_NONFATAL_FAILURE(EXPECT_NE(1, 1) << "Expected failure #1.", + "Expected failure #1"); + EXPECT_LE(1, 2) << "This should succeed."; + EXPECT_NONFATAL_FAILURE(EXPECT_LT(1, 0) << "Expected failure #2.", + "Expected failure #2."); + EXPECT_GE(1, 0) << "This should succeed."; + EXPECT_NONFATAL_FAILURE(EXPECT_GT(1, 2) << "Expected failure #3.", + "Expected failure #3."); + + EXPECT_STREQ("1", "1") << "This should succeed."; + EXPECT_NONFATAL_FAILURE(EXPECT_STRNE("1", "1") << "Expected failure #4.", + "Expected failure #4."); + EXPECT_STRCASEEQ("a", "A") << "This should succeed."; + EXPECT_NONFATAL_FAILURE(EXPECT_STRCASENE("a", "A") << "Expected failure #5.", + "Expected failure #5."); + + EXPECT_FLOAT_EQ(1, 1) << "This should succeed."; + EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(1, 1.2) << "Expected failure #6.", + "Expected failure #6."); + EXPECT_NEAR(1, 1.1, 0.2) << "This should succeed."; +} + +TEST(AssertionWithMessageTest, ASSERT) { + ASSERT_EQ(1, 1) << "This should succeed."; + ASSERT_NE(1, 2) << "This should succeed."; + ASSERT_LE(1, 2) << "This should succeed."; + ASSERT_LT(1, 2) << "This should succeed."; + ASSERT_GE(1, 0) << "This should succeed."; + EXPECT_FATAL_FAILURE(ASSERT_GT(1, 2) << "Expected failure.", + "Expected failure."); +} + +TEST(AssertionWithMessageTest, ASSERT_STR) { + ASSERT_STREQ("1", "1") << "This should succeed."; + ASSERT_STRNE("1", "2") << "This should succeed."; + ASSERT_STRCASEEQ("a", "A") << "This should succeed."; + EXPECT_FATAL_FAILURE(ASSERT_STRCASENE("a", "A") << "Expected failure.", + "Expected failure."); +} + +TEST(AssertionWithMessageTest, ASSERT_FLOATING) { + ASSERT_FLOAT_EQ(1, 1) << "This should succeed."; + ASSERT_DOUBLE_EQ(1, 1) << "This should succeed."; + EXPECT_FATAL_FAILURE(ASSERT_NEAR(1,1.2, 0.1) << "Expect failure.", // NOLINT + "Expect failure."); + // To work around a bug in gcc 2.95.0, there is intentionally no + // space after the first comma in the previous statement. +} + +// Tests using ASSERT_FALSE with a streamed message. +TEST(AssertionWithMessageTest, ASSERT_FALSE) { + ASSERT_FALSE(false) << "This shouldn't fail."; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_FALSE(true) << "Expected failure: " << 2 << " > " << 1 + << " evaluates to " << true; + }, "Expected failure"); +} + +// Tests using FAIL with a streamed message. +TEST(AssertionWithMessageTest, FAIL) { + EXPECT_FATAL_FAILURE(FAIL() << 0, + "0"); +} + +// Tests using SUCCEED with a streamed message. +TEST(AssertionWithMessageTest, SUCCEED) { + SUCCEED() << "Success == " << 1; +} + +// Tests using ASSERT_TRUE with a streamed message. +TEST(AssertionWithMessageTest, ASSERT_TRUE) { + ASSERT_TRUE(true) << "This should succeed."; + ASSERT_TRUE(true) << true; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_TRUE(false) << static_cast(NULL) + << static_cast(NULL); + }, "(null)(null)"); +} + +#if GTEST_OS_WINDOWS +// Tests using wide strings in assertion messages. +TEST(AssertionWithMessageTest, WideStringMessage) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_TRUE(false) << L"This failure is expected.\x8119"; + }, "This failure is expected."); + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_EQ(1, 2) << "This failure is " + << L"expected too.\x8120"; + }, "This failure is expected too."); +} +#endif // GTEST_OS_WINDOWS + // Tests EXPECT_TRUE. TEST(ExpectTest, EXPECT_TRUE) { + EXPECT_TRUE(true) << "Intentional success"; + EXPECT_NONFATAL_FAILURE(EXPECT_TRUE(false) << "Intentional failure #1.", + "Intentional failure #1."); + EXPECT_NONFATAL_FAILURE(EXPECT_TRUE(false) << "Intentional failure #2.", + "Intentional failure #2."); EXPECT_TRUE(2 > 1); // NOLINT EXPECT_NONFATAL_FAILURE(EXPECT_TRUE(2 < 1), "Value of: 2 < 1\n" @@ -4288,9 +4397,14 @@ TEST(ExpectTest, ExpectTrueWithAssertionResult) { "Expected: true"); } -// Tests EXPECT_FALSE. +// Tests EXPECT_FALSE with a streamed message. TEST(ExpectTest, EXPECT_FALSE) { EXPECT_FALSE(2 < 1); // NOLINT + EXPECT_FALSE(false) << "Intentional success"; + EXPECT_NONFATAL_FAILURE(EXPECT_FALSE(true) << "Intentional failure #1.", + "Intentional failure #1."); + EXPECT_NONFATAL_FAILURE(EXPECT_FALSE(true) << "Intentional failure #2.", + "Intentional failure #2."); EXPECT_NONFATAL_FAILURE(EXPECT_FALSE(2 > 1), "Value of: 2 > 1\n" " Actual: true\n" @@ -4564,7 +4678,7 @@ TEST(StreamableTest, BasicIoManip) { void AddFailureHelper(bool* aborted) { *aborted = true; - ADD_FAILURE() << "Failure"; + ADD_FAILURE() << "Intentional failure."; *aborted = false; } @@ -4572,7 +4686,7 @@ void AddFailureHelper(bool* aborted) { TEST(MacroTest, ADD_FAILURE) { bool aborted = true; EXPECT_NONFATAL_FAILURE(AddFailureHelper(&aborted), - "Failure"); + "Intentional failure."); EXPECT_FALSE(aborted); } @@ -4605,7 +4719,6 @@ TEST(MacroTest, SUCCEED) { SUCCEED() << "Explicit success."; } - // Tests for EXPECT_EQ() and ASSERT_EQ(). // // These tests fail *intentionally*, s.t. the failure messages can be -- cgit v1.2.3 From a3b859162dd7a4a1798cf8753a03098f2cbdb62e Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Thu, 31 May 2012 20:37:13 +0000 Subject: Fixes threading annotations and compatibility with C++11, which doesn't allow exepctions to be thrown in a destructor. --- test/gtest_catch_exceptions_test.py | 19 +++++++++++-------- test/gtest_catch_exceptions_test_.cc | 3 +++ 2 files changed, 14 insertions(+), 8 deletions(-) (limited to 'test') diff --git a/test/gtest_catch_exceptions_test.py b/test/gtest_catch_exceptions_test.py index 7fd7dbad..d7ef10eb 100755 --- a/test/gtest_catch_exceptions_test.py +++ b/test/gtest_catch_exceptions_test.py @@ -117,14 +117,17 @@ class CatchCxxExceptionsTest(gtest_test_utils.TestCase): '"CxxExceptionInConstructorTest" (no quotes) ' 'appears on the same line as words "called unexpectedly"') - def testCatchesCxxExceptionsInFixtureDestructor(self): - self.assert_('C++ exception with description ' - '"Standard C++ exception" thrown ' - 'in the test fixture\'s destructor' - in EX_BINARY_OUTPUT) - self.assert_('CxxExceptionInDestructorTest::TearDownTestCase() ' - 'called as expected.' - in EX_BINARY_OUTPUT) + if ('CxxExceptionInDestructorTest.ThrowsExceptionInDestructor' in + EX_BINARY_OUTPUT): + + def testCatchesCxxExceptionsInFixtureDestructor(self): + self.assert_('C++ exception with description ' + '"Standard C++ exception" thrown ' + 'in the test fixture\'s destructor' + in EX_BINARY_OUTPUT) + self.assert_('CxxExceptionInDestructorTest::TearDownTestCase() ' + 'called as expected.' + in EX_BINARY_OUTPUT) def testCatchesCxxExceptionsInSetUpTestCase(self): self.assert_('C++ exception with description "Standard C++ exception"' diff --git a/test/gtest_catch_exceptions_test_.cc b/test/gtest_catch_exceptions_test_.cc index a35103f0..d0fc82c9 100644 --- a/test/gtest_catch_exceptions_test_.cc +++ b/test/gtest_catch_exceptions_test_.cc @@ -137,6 +137,8 @@ TEST_F(CxxExceptionInConstructorTest, ThrowsExceptionInConstructor) { << "called unexpectedly."; } +// Exceptions in destructors are not supported in C++11. +#if !defined(__GXX_EXPERIMENTAL_CXX0X__) && __cplusplus < 201103L class CxxExceptionInDestructorTest : public Test { public: static void TearDownTestCase() { @@ -153,6 +155,7 @@ class CxxExceptionInDestructorTest : public Test { }; TEST_F(CxxExceptionInDestructorTest, ThrowsExceptionInDestructor) {} +#endif // C++11 mode class CxxExceptionInSetUpTestCaseTest : public Test { public: -- cgit v1.2.3 From a88c9a88e49e90ec414175543b2b7ff2f70866a7 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Thu, 7 Jun 2012 20:34:34 +0000 Subject: Improves gtest's failure messages. In particulars, char pointers and char arrays are not escapped properly. --- test/gtest-port_test.cc | 37 +++++ test/gtest-printers_test.cc | 270 ++++++++++++++++++++++++++++++++-- test/gtest_output_test_.cc | 17 ++- test/gtest_output_test_golden_lin.txt | 22 ++- test/gtest_unittest.cc | 20 --- 5 files changed, 330 insertions(+), 36 deletions(-) (limited to 'test') diff --git a/test/gtest-port_test.cc b/test/gtest-port_test.cc index 75471c39..dfbf029f 100644 --- a/test/gtest-port_test.cc +++ b/test/gtest-port_test.cc @@ -61,6 +61,43 @@ using std::pair; namespace testing { namespace internal { +TEST(IsXDigitTest, WorksForNarrowAscii) { + EXPECT_TRUE(IsXDigit('0')); + EXPECT_TRUE(IsXDigit('9')); + EXPECT_TRUE(IsXDigit('A')); + EXPECT_TRUE(IsXDigit('F')); + EXPECT_TRUE(IsXDigit('a')); + EXPECT_TRUE(IsXDigit('f')); + + EXPECT_FALSE(IsXDigit('-')); + EXPECT_FALSE(IsXDigit('g')); + EXPECT_FALSE(IsXDigit('G')); +} + +TEST(IsXDigitTest, ReturnsFalseForNarrowNonAscii) { + EXPECT_FALSE(IsXDigit(static_cast(0x80))); + EXPECT_FALSE(IsXDigit(static_cast('0' | 0x80))); +} + +TEST(IsXDigitTest, WorksForWideAscii) { + EXPECT_TRUE(IsXDigit(L'0')); + EXPECT_TRUE(IsXDigit(L'9')); + EXPECT_TRUE(IsXDigit(L'A')); + EXPECT_TRUE(IsXDigit(L'F')); + EXPECT_TRUE(IsXDigit(L'a')); + EXPECT_TRUE(IsXDigit(L'f')); + + EXPECT_FALSE(IsXDigit(L'-')); + EXPECT_FALSE(IsXDigit(L'g')); + EXPECT_FALSE(IsXDigit(L'G')); +} + +TEST(IsXDigitTest, ReturnsFalseForWideNonAscii) { + EXPECT_FALSE(IsXDigit(static_cast(0x80))); + EXPECT_FALSE(IsXDigit(static_cast(L'0' | 0x80))); + EXPECT_FALSE(IsXDigit(static_cast(L'0' | 0x100))); +} + class Base { public: // Copy constructor and assignment operator do exactly what we need, so we diff --git a/test/gtest-printers_test.cc b/test/gtest-printers_test.cc index 58d96225..45610f8f 100644 --- a/test/gtest-printers_test.cc +++ b/test/gtest-printers_test.cc @@ -197,14 +197,15 @@ using ::std::pair; using ::std::set; using ::std::vector; using ::testing::PrintToString; +using ::testing::internal::FormatForComparisonFailureMessage; using ::testing::internal::ImplicitCast_; using ::testing::internal::NativeArray; using ::testing::internal::RE; using ::testing::internal::Strings; -using ::testing::internal::UniversalTersePrint; using ::testing::internal::UniversalPrint; -using ::testing::internal::UniversalTersePrintTupleFieldsToStrings; using ::testing::internal::UniversalPrinter; +using ::testing::internal::UniversalTersePrint; +using ::testing::internal::UniversalTersePrintTupleFieldsToStrings; using ::testing::internal::kReference; using ::testing::internal::string; @@ -613,17 +614,30 @@ TEST(PrintArrayTest, ConstArray) { EXPECT_EQ("{ false }", PrintArrayHelper(a)); } -// Char array. -TEST(PrintArrayTest, CharArray) { +// char array without terminating NUL. +TEST(PrintArrayTest, CharArrayWithNoTerminatingNul) { + // Array a contains '\0' in the middle and doesn't end with '\0'. + char a[] = { 'H', '\0', 'i' }; + EXPECT_EQ("\"H\\0i\" (no terminating NUL)", PrintArrayHelper(a)); +} + +// const char array with terminating NUL. +TEST(PrintArrayTest, ConstCharArrayWithTerminatingNul) { + const char a[] = "\0Hi"; + EXPECT_EQ("\"\\0Hi\"", PrintArrayHelper(a)); +} + +// const wchar_t array without terminating NUL. +TEST(PrintArrayTest, WCharArrayWithNoTerminatingNul) { // Array a contains '\0' in the middle and doesn't end with '\0'. - char a[3] = { 'H', '\0', 'i' }; - EXPECT_EQ("\"H\\0i\"", PrintArrayHelper(a)); + const wchar_t a[] = { L'H', L'\0', L'i' }; + EXPECT_EQ("L\"H\\0i\" (no terminating NUL)", PrintArrayHelper(a)); } -// Const char array. -TEST(PrintArrayTest, ConstCharArray) { - const char a[4] = "\0Hi"; - EXPECT_EQ("\"\\0Hi\\0\"", PrintArrayHelper(a)); +// wchar_t array with terminating NUL. +TEST(PrintArrayTest, WConstCharArrayWithTerminatingNul) { + const wchar_t a[] = L"\0Hi"; + EXPECT_EQ("L\"\\0Hi\"", PrintArrayHelper(a)); } // Array of objects. @@ -1186,6 +1200,207 @@ TEST(PrintReferenceTest, HandlesMemberVariablePointer) { "@" + PrintPointer(&p) + " " + Print(sizeof(p)) + "-byte object ")); } +// Tests that FormatForComparisonFailureMessage(), which is used to print +// an operand in a comparison assertion (e.g. ASSERT_EQ) when the assertion +// fails, formats the operand in the desired way. + +// scalar +TEST(FormatForComparisonFailureMessageTest, WorksForScalar) { + EXPECT_STREQ("123", + FormatForComparisonFailureMessage(123, 124).c_str()); +} + +// non-char pointer +TEST(FormatForComparisonFailureMessageTest, WorksForNonCharPointer) { + int n = 0; + EXPECT_EQ(PrintPointer(&n), + FormatForComparisonFailureMessage(&n, &n).c_str()); +} + +// non-char array +TEST(FormatForComparisonFailureMessageTest, FormatsNonCharArrayAsPointer) { + // In expression 'array == x', 'array' is compared by pointer. + // Therefore we want to print an array operand as a pointer. + int n[] = { 1, 2, 3 }; + EXPECT_EQ(PrintPointer(n), + FormatForComparisonFailureMessage(n, n).c_str()); +} + +// Tests formatting a char pointer when it's compared with another pointer. +// In this case we want to print it as a raw pointer, as the comparision is by +// pointer. + +// char pointer vs pointer +TEST(FormatForComparisonFailureMessageTest, WorksForCharPointerVsPointer) { + // In expression 'p == x', where 'p' and 'x' are (const or not) char + // pointers, the operands are compared by pointer. Therefore we + // want to print 'p' as a pointer instead of a C string (we don't + // even know if it's supposed to point to a valid C string). + + // const char* + const char* s = "hello"; + EXPECT_EQ(PrintPointer(s), + FormatForComparisonFailureMessage(s, s).c_str()); + + // char* + char ch = 'a'; + EXPECT_EQ(PrintPointer(&ch), + FormatForComparisonFailureMessage(&ch, &ch).c_str()); +} + +// wchar_t pointer vs pointer +TEST(FormatForComparisonFailureMessageTest, WorksForWCharPointerVsPointer) { + // In expression 'p == x', where 'p' and 'x' are (const or not) char + // pointers, the operands are compared by pointer. Therefore we + // want to print 'p' as a pointer instead of a wide C string (we don't + // even know if it's supposed to point to a valid wide C string). + + // const wchar_t* + const wchar_t* s = L"hello"; + EXPECT_EQ(PrintPointer(s), + FormatForComparisonFailureMessage(s, s).c_str()); + + // wchar_t* + wchar_t ch = L'a'; + EXPECT_EQ(PrintPointer(&ch), + FormatForComparisonFailureMessage(&ch, &ch).c_str()); +} + +// Tests formatting a char pointer when it's compared to a string object. +// In this case we want to print the char pointer as a C string. + +#if GTEST_HAS_GLOBAL_STRING +// char pointer vs ::string +TEST(FormatForComparisonFailureMessageTest, WorksForCharPointerVsString) { + const char* s = "hello \"world"; + EXPECT_STREQ("\"hello \\\"world\"", // The string content should be escaped. + FormatForComparisonFailureMessage(s, ::string()).c_str()); + + // char* + char str[] = "hi\1"; + char* p = str; + EXPECT_STREQ("\"hi\\x1\"", // The string content should be escaped. + FormatForComparisonFailureMessage(p, ::string()).c_str()); +} +#endif + +// char pointer vs std::string +TEST(FormatForComparisonFailureMessageTest, WorksForCharPointerVsStdString) { + const char* s = "hello \"world"; + EXPECT_STREQ("\"hello \\\"world\"", // The string content should be escaped. + FormatForComparisonFailureMessage(s, ::std::string()).c_str()); + + // char* + char str[] = "hi\1"; + char* p = str; + EXPECT_STREQ("\"hi\\x1\"", // The string content should be escaped. + FormatForComparisonFailureMessage(p, ::std::string()).c_str()); +} + +#if GTEST_HAS_GLOBAL_WSTRING +// wchar_t pointer vs ::wstring +TEST(FormatForComparisonFailureMessageTest, WorksForWCharPointerVsWString) { + const wchar_t* s = L"hi \"world"; + EXPECT_STREQ("L\"hi \\\"world\"", // The string content should be escaped. + FormatForComparisonFailureMessage(s, ::wstring()).c_str()); + + // wchar_t* + wchar_t str[] = L"hi\1"; + wchar_t* p = str; + EXPECT_STREQ("L\"hi\\x1\"", // The string content should be escaped. + FormatForComparisonFailureMessage(p, ::wstring()).c_str()); +} +#endif + +#if GTEST_HAS_STD_WSTRING +// wchar_t pointer vs std::wstring +TEST(FormatForComparisonFailureMessageTest, WorksForWCharPointerVsStdWString) { + const wchar_t* s = L"hi \"world"; + EXPECT_STREQ("L\"hi \\\"world\"", // The string content should be escaped. + FormatForComparisonFailureMessage(s, ::std::wstring()).c_str()); + + // wchar_t* + wchar_t str[] = L"hi\1"; + wchar_t* p = str; + EXPECT_STREQ("L\"hi\\x1\"", // The string content should be escaped. + FormatForComparisonFailureMessage(p, ::std::wstring()).c_str()); +} +#endif + +// Tests formatting a char array when it's compared with a pointer or array. +// In this case we want to print the array as a row pointer, as the comparison +// is by pointer. + +// char array vs pointer +TEST(FormatForComparisonFailureMessageTest, WorksForCharArrayVsPointer) { + char str[] = "hi \"world\""; + char* p = NULL; + EXPECT_EQ(PrintPointer(str), + FormatForComparisonFailureMessage(str, p).c_str()); +} + +// char array vs char array +TEST(FormatForComparisonFailureMessageTest, WorksForCharArrayVsCharArray) { + const char str[] = "hi \"world\""; + EXPECT_EQ(PrintPointer(str), + FormatForComparisonFailureMessage(str, str).c_str()); +} + +// wchar_t array vs pointer +TEST(FormatForComparisonFailureMessageTest, WorksForWCharArrayVsPointer) { + wchar_t str[] = L"hi \"world\""; + wchar_t* p = NULL; + EXPECT_EQ(PrintPointer(str), + FormatForComparisonFailureMessage(str, p).c_str()); +} + +// wchar_t array vs wchar_t array +TEST(FormatForComparisonFailureMessageTest, WorksForWCharArrayVsWCharArray) { + const wchar_t str[] = L"hi \"world\""; + EXPECT_EQ(PrintPointer(str), + FormatForComparisonFailureMessage(str, str).c_str()); +} + +// Tests formatting a char array when it's compared with a string object. +// In this case we want to print the array as a C string. + +#if GTEST_HAS_GLOBAL_STRING +// char array vs string +TEST(FormatForComparisonFailureMessageTest, WorksForCharArrayVsString) { + const char str[] = "hi \"w\0rld\""; + EXPECT_STREQ("\"hi \\\"w\"", // The content should be escaped. + // Embedded NUL terminates the string. + FormatForComparisonFailureMessage(str, ::string()).c_str()); +} +#endif + +// char array vs std::string +TEST(FormatForComparisonFailureMessageTest, WorksForCharArrayVsStdString) { + const char str[] = "hi \"world\""; + EXPECT_STREQ("\"hi \\\"world\\\"\"", // The content should be escaped. + FormatForComparisonFailureMessage(str, ::std::string()).c_str()); +} + +#if GTEST_HAS_GLOBAL_WSTRING +// wchar_t array vs wstring +TEST(FormatForComparisonFailureMessageTest, WorksForWCharArrayVsWString) { + const wchar_t str[] = L"hi \"world\""; + EXPECT_STREQ("L\"hi \\\"world\\\"\"", // The content should be escaped. + FormatForComparisonFailureMessage(str, ::wstring()).c_str()); +} +#endif + +#if GTEST_HAS_STD_WSTRING +// wchar_t array vs std::wstring +TEST(FormatForComparisonFailureMessageTest, WorksForWCharArrayVsStdWString) { + const wchar_t str[] = L"hi \"w\0rld\""; + EXPECT_STREQ( + "L\"hi \\\"w\"", // The content should be escaped. + // Embedded NUL terminates the string. + FormatForComparisonFailureMessage(str, ::std::wstring()).c_str()); +} +#endif + // Useful for testing PrintToString(). We cannot use EXPECT_EQ() // there as its implementation uses PrintToString(). The caller must // ensure that 'value' has no side effect. @@ -1208,11 +1423,35 @@ TEST(PrintToStringTest, WorksForPointerToNonConstChar) { EXPECT_PRINT_TO_STRING_(p, "\"hello\""); } +TEST(PrintToStringTest, EscapesForPointerToConstChar) { + const char* p = "hello\n"; + EXPECT_PRINT_TO_STRING_(p, "\"hello\\n\""); +} + +TEST(PrintToStringTest, EscapesForPointerToNonConstChar) { + char s[] = "hello\1"; + char* p = s; + EXPECT_PRINT_TO_STRING_(p, "\"hello\\x1\""); +} + TEST(PrintToStringTest, WorksForArray) { int n[3] = { 1, 2, 3 }; EXPECT_PRINT_TO_STRING_(n, "{ 1, 2, 3 }"); } +TEST(PrintToStringTest, WorksForCharArray) { + char s[] = "hello"; + EXPECT_PRINT_TO_STRING_(s, "\"hello\""); +} + +TEST(PrintToStringTest, WorksForCharArrayWithEmbeddedNul) { + const char str_with_nul[] = "hello\0 world"; + EXPECT_PRINT_TO_STRING_(str_with_nul, "\"hello\\0 world\""); + + char mutable_str_with_nul[] = "hello\0 world"; + EXPECT_PRINT_TO_STRING_(mutable_str_with_nul, "\"hello\\0 world\""); +} + #undef EXPECT_PRINT_TO_STRING_ TEST(UniversalTersePrintTest, WorksForNonReference) { @@ -1275,6 +1514,17 @@ TEST(UniversalPrintTest, WorksForCString) { EXPECT_EQ("NULL", ss3.str()); } +TEST(UniversalPrintTest, WorksForCharArray) { + const char str[] = "\"Line\0 1\"\nLine 2"; + ::std::stringstream ss1; + UniversalPrint(str, &ss1); + EXPECT_EQ("\"\\\"Line\\0 1\\\"\\nLine 2\"", ss1.str()); + + const char mutable_str[] = "\"Line\0 1\"\nLine 2"; + ::std::stringstream ss2; + UniversalPrint(mutable_str, &ss2); + EXPECT_EQ("\"\\\"Line\\0 1\\\"\\nLine 2\"", ss2.str()); +} #if GTEST_HAS_TR1_TUPLE diff --git a/test/gtest_output_test_.cc b/test/gtest_output_test_.cc index 1b08b65b..da8b7449 100644 --- a/test/gtest_output_test_.cc +++ b/test/gtest_output_test_.cc @@ -27,8 +27,11 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// A unit test for Google Test itself. This verifies that the basic -// constructs of Google Test work. +// The purpose of this file is to generate Google Test output under +// various conditions. The output will then be verified by +// gtest_output_test.py to ensure that Google Test generates the +// desired messages. Therefore, most tests in this file are MEANT TO +// FAIL. // // Author: wan@google.com (Zhanyong Wan) @@ -101,6 +104,16 @@ INSTANTIATE_TEST_CASE_P(PrintingFailingParams, FailingParamTest, testing::Values(2)); +static const char kGoldenString[] = "\"Line\0 1\"\nLine 2"; + +TEST(NonfatalFailureTest, EscapesStringOperands) { + std::string actual = "actual \"string\""; + EXPECT_EQ(kGoldenString, actual); + + const char* golden = kGoldenString; + EXPECT_EQ(golden, actual); +} + // Tests catching a fatal failure in a subroutine. TEST(FatalFailureTest, FatalFailureInSubroutine) { printf("(expecting a failure that x should be 1)\n"); diff --git a/test/gtest_output_test_golden_lin.txt b/test/gtest_output_test_golden_lin.txt index a1d342d9..0e26d63d 100644 --- a/test/gtest_output_test_golden_lin.txt +++ b/test/gtest_output_test_golden_lin.txt @@ -7,7 +7,7 @@ Expected: true gtest_output_test_.cc:#: Failure Value of: 3 Expected: 2 -[==========] Running 62 tests from 27 test cases. +[==========] Running 63 tests from 28 test cases. [----------] Global test environment set-up. FooEnvironment::SetUp() called. BarEnvironment::SetUp() called. @@ -31,6 +31,19 @@ BarEnvironment::SetUp() called. [ OK ] PassingTest.PassingTest1 [ RUN ] PassingTest.PassingTest2 [ OK ] PassingTest.PassingTest2 +[----------] 1 test from NonfatalFailureTest +[ RUN ] NonfatalFailureTest.EscapesStringOperands +gtest_output_test_.cc:#: Failure +Value of: actual + Actual: "actual \"string\"" +Expected: kGoldenString +Which is: "\"Line" +gtest_output_test_.cc:#: Failure +Value of: actual + Actual: "actual \"string\"" +Expected: golden +Which is: "\"Line" +[ FAILED ] NonfatalFailureTest.EscapesStringOperands [----------] 3 tests from FatalFailureTest [ RUN ] FatalFailureTest.FatalFailureInSubroutine (expecting a failure that x should be 1) @@ -586,9 +599,10 @@ FooEnvironment::TearDown() called. gtest_output_test_.cc:#: Failure Failed Expected fatal failure. -[==========] 62 tests from 27 test cases ran. +[==========] 63 tests from 28 test cases ran. [ PASSED ] 21 tests. -[ FAILED ] 41 tests, listed below: +[ FAILED ] 42 tests, listed below: +[ FAILED ] NonfatalFailureTest.EscapesStringOperands [ FAILED ] FatalFailureTest.FatalFailureInSubroutine [ FAILED ] FatalFailureTest.FatalFailureInNestedSubroutine [ FAILED ] FatalFailureTest.NonfatalFailureInSubroutine @@ -631,7 +645,7 @@ Expected fatal failure. [ FAILED ] ScopedFakeTestPartResultReporterTest.InterceptOnlyCurrentThread [ FAILED ] PrintingFailingParams/FailingParamTest.Fails/0, where GetParam() = 2 -41 FAILED TESTS +42 FAILED TESTS  YOU HAVE 1 DISABLED TEST Note: Google Test filter = FatalFailureTest.*:LoggingTest.* diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index e61f7919..31a45656 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -1065,16 +1065,6 @@ TEST(StringTest, ConvertsToGlobalString) { #endif // GTEST_HAS_GLOBAL_STRING -// Tests String::ShowCStringQuoted(). -TEST(StringTest, ShowCStringQuoted) { - EXPECT_STREQ("(null)", - String::ShowCStringQuoted(NULL).c_str()); - EXPECT_STREQ("\"\"", - String::ShowCStringQuoted("").c_str()); - EXPECT_STREQ("\"foo\"", - String::ShowCStringQuoted("foo").c_str()); -} - // Tests String::empty(). TEST(StringTest, Empty) { EXPECT_TRUE(String("").empty()); @@ -1305,16 +1295,6 @@ TEST(StringTest, ShowWideCString) { EXPECT_STREQ("foo", String::ShowWideCString(L"foo").c_str()); } -// Tests String::ShowWideCStringQuoted(). -TEST(StringTest, ShowWideCStringQuoted) { - EXPECT_STREQ("(null)", - String::ShowWideCStringQuoted(NULL).c_str()); - EXPECT_STREQ("L\"\"", - String::ShowWideCStringQuoted(L"").c_str()); - EXPECT_STREQ("L\"foo\"", - String::ShowWideCStringQuoted(L"foo").c_str()); -} - # if GTEST_OS_WINDOWS_MOBILE TEST(StringTest, AnsiAndUtf16Null) { EXPECT_EQ(NULL, String::AnsiToUtf16(NULL)); -- cgit v1.2.3 From b535c1767e7ec4e9675bb7257d9bc34a84949741 Mon Sep 17 00:00:00 2001 From: vladlosev Date: Thu, 6 Sep 2012 17:09:27 +0000 Subject: Removes obsolete debug code. --- test/gtest_env_var_test.py | 3 +-- test/gtest_output_test.py | 2 +- test/gtest_shuffle_test.py | 3 +-- 3 files changed, 3 insertions(+), 5 deletions(-) (limited to 'test') diff --git a/test/gtest_env_var_test.py b/test/gtest_env_var_test.py index 4728bbc3..ac24337f 100755 --- a/test/gtest_env_var_test.py +++ b/test/gtest_env_var_test.py @@ -67,8 +67,7 @@ def GetFlag(flag): args = [COMMAND] if flag is not None: args += [flag] - return gtest_test_utils.Subprocess(args, env=environ, - capture_stderr=False).output + return gtest_test_utils.Subprocess(args, env=environ).output def TestFlag(flag, test_val, default_val): diff --git a/test/gtest_output_test.py b/test/gtest_output_test.py index 72b3ae00..f409e2a7 100755 --- a/test/gtest_output_test.py +++ b/test/gtest_output_test.py @@ -213,7 +213,7 @@ def GetShellCommandOutput(env_cmd): # Set and save the environment properly. environ = os.environ.copy() environ.update(env_cmd[0]) - p = gtest_test_utils.Subprocess(env_cmd[1], env=environ, capture_stderr=False) + p = gtest_test_utils.Subprocess(env_cmd[1], env=environ) return p.output diff --git a/test/gtest_shuffle_test.py b/test/gtest_shuffle_test.py index d3e57809..30d0303d 100755 --- a/test/gtest_shuffle_test.py +++ b/test/gtest_shuffle_test.py @@ -81,8 +81,7 @@ def RunAndReturnOutput(extra_env, args): environ_copy = os.environ.copy() environ_copy.update(extra_env) - return gtest_test_utils.Subprocess([COMMAND] + args, env=environ_copy, - capture_stderr=False).output + return gtest_test_utils.Subprocess([COMMAND] + args, env=environ_copy).output def GetTestsForAllIterations(extra_env, args): -- cgit v1.2.3 From 78bf6d5724e733cce313228856e18d5c372b4fb3 Mon Sep 17 00:00:00 2001 From: vladlosev Date: Wed, 19 Sep 2012 17:58:01 +0000 Subject: Improves Android support (by David Turner). --- test/gtest-filepath_test.cc | 2 ++ test/gtest_unittest.cc | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'test') diff --git a/test/gtest-filepath_test.cc b/test/gtest-filepath_test.cc index 66d41184..3196ea05 100644 --- a/test/gtest-filepath_test.cc +++ b/test/gtest-filepath_test.cc @@ -543,6 +543,8 @@ class DirectoryCreationTest : public Test { return String(temp_dir); else return String::Format("%s\\", temp_dir); +#elif GTEST_OS_LINUX_ANDROID + return String("/sdcard/"); #else return String("/tmp/"); #endif // GTEST_OS_WINDOWS_MOBILE diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index 31a45656..79e11b62 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -1275,7 +1275,7 @@ TEST(StringTest, FormatWorks) { EXPECT_STREQ("", String::Format("x%s", buffer).c_str()); -#if GTEST_OS_LINUX +#if GTEST_OS_LINUX && !GTEST_OS_LINUX_ANDROID // On Linux, invalid format spec should lead to an error message. // In other environment (e.g. MSVC on Windows), String::Format() may // simply ignore a bad format spec, so this assertion is run on -- cgit v1.2.3 From 87fdda2cf24d953f3cbec1e0c266b2db9928f406 Mon Sep 17 00:00:00 2001 From: jgm Date: Thu, 15 Nov 2012 15:47:38 +0000 Subject: Unfortunately, the svn repo is a bit out of date. This commit contains 8 changes that haven't made it to svn. The descriptions of each change are listed below. - Fixes some python shebang lines. - Add ElementsAreArray overloads to gmock. ElementsAreArray now makes a copy of its input elements before the conversion to a Matcher. ElementsAreArray can now take a vector as input. ElementsAreArray can now take an iterator pair as input. - Templatize MatchAndExplain to allow independent string types for the matcher and matchee. I also templatized the ConstCharPointer version of MatchAndExplain to avoid calls with "char*" from using the new templated MatchAndExplain. - Fixes the bug where the constructor of the return type of ElementsAre() saves a reference instead of a copy of the arguments. - Extends ElementsAre() to accept arrays whose sizes aren't known. - Switches gTest's internal FilePath class from testing::internal::String to std::string. testing::internal::String was introduced when gTest couldn't depend on std::string. It's now deprecated. - Switches gTest & gMock from using testing::internal::String objects to std::string. Some static methods of String are still in use. We may be able to remove some but not all of them. In particular, String::Format() should eventually be removed as it truncates the result at 4096 characters, often causing problems. --- test/gtest-death-test_test.cc | 26 ++- test/gtest-filepath_test.cc | 256 ++++++++++++++---------------- test/gtest-listener_test.cc | 31 ++-- test/gtest-message_test.cc | 55 +++---- test/gtest-options_test.cc | 57 +++---- test/gtest-param-test_test.cc | 4 +- test/gtest-port_test.cc | 20 +-- test/gtest_output_test_.cc | 4 +- test/gtest_shuffle_test_.cc | 1 - test/gtest_stress_test.cc | 5 +- test/gtest_unittest.cc | 359 ++++-------------------------------------- 11 files changed, 247 insertions(+), 571 deletions(-) (limited to 'test') diff --git a/test/gtest-death-test_test.cc b/test/gtest-death-test_test.cc index b389e73b..e42c0136 100644 --- a/test/gtest-death-test_test.cc +++ b/test/gtest-death-test_test.cc @@ -77,7 +77,6 @@ using testing::internal::GetLastErrnoDescription; using testing::internal::GetUnitTestImpl; using testing::internal::InDeathTestChild; using testing::internal::ParseNaturalNumber; -using testing::internal::String; namespace testing { namespace internal { @@ -1139,26 +1138,26 @@ TEST(ParseNaturalNumberTest, RejectsInvalidFormat) { BiggestParsable result = 0; // Rejects non-numbers. - EXPECT_FALSE(ParseNaturalNumber(String("non-number string"), &result)); + EXPECT_FALSE(ParseNaturalNumber("non-number string", &result)); // Rejects numbers with whitespace prefix. - EXPECT_FALSE(ParseNaturalNumber(String(" 123"), &result)); + EXPECT_FALSE(ParseNaturalNumber(" 123", &result)); // Rejects negative numbers. - EXPECT_FALSE(ParseNaturalNumber(String("-123"), &result)); + EXPECT_FALSE(ParseNaturalNumber("-123", &result)); // Rejects numbers starting with a plus sign. - EXPECT_FALSE(ParseNaturalNumber(String("+123"), &result)); + EXPECT_FALSE(ParseNaturalNumber("+123", &result)); errno = 0; } TEST(ParseNaturalNumberTest, RejectsOverflownNumbers) { BiggestParsable result = 0; - EXPECT_FALSE(ParseNaturalNumber(String("99999999999999999999999"), &result)); + EXPECT_FALSE(ParseNaturalNumber("99999999999999999999999", &result)); signed char char_result = 0; - EXPECT_FALSE(ParseNaturalNumber(String("200"), &char_result)); + EXPECT_FALSE(ParseNaturalNumber("200", &char_result)); errno = 0; } @@ -1166,16 +1165,16 @@ TEST(ParseNaturalNumberTest, AcceptsValidNumbers) { BiggestParsable result = 0; result = 0; - ASSERT_TRUE(ParseNaturalNumber(String("123"), &result)); + ASSERT_TRUE(ParseNaturalNumber("123", &result)); EXPECT_EQ(123U, result); // Check 0 as an edge case. result = 1; - ASSERT_TRUE(ParseNaturalNumber(String("0"), &result)); + ASSERT_TRUE(ParseNaturalNumber("0", &result)); EXPECT_EQ(0U, result); result = 1; - ASSERT_TRUE(ParseNaturalNumber(String("00000"), &result)); + ASSERT_TRUE(ParseNaturalNumber("00000", &result)); EXPECT_EQ(0U, result); } @@ -1211,11 +1210,11 @@ TEST(ParseNaturalNumberTest, AcceptsTypeLimits) { TEST(ParseNaturalNumberTest, WorksForShorterIntegers) { short short_result = 0; - ASSERT_TRUE(ParseNaturalNumber(String("123"), &short_result)); + ASSERT_TRUE(ParseNaturalNumber("123", &short_result)); EXPECT_EQ(123, short_result); signed char char_result = 0; - ASSERT_TRUE(ParseNaturalNumber(String("123"), &char_result)); + ASSERT_TRUE(ParseNaturalNumber("123", &char_result)); EXPECT_EQ(123, char_result); } @@ -1245,7 +1244,6 @@ TEST(ConditionalDeathMacrosDeathTest, ExpectsDeathWhenDeathTestsAvailable) { using testing::internal::CaptureStderr; using testing::internal::GetCapturedStderr; -using testing::internal::String; // Tests that EXPECT_DEATH_IF_SUPPORTED/ASSERT_DEATH_IF_SUPPORTED are still // defined but do not trigger failures when death tests are not available on @@ -1255,7 +1253,7 @@ TEST(ConditionalDeathMacrosTest, WarnsWhenDeathTestsNotAvailable) { // when death tests are not supported. CaptureStderr(); EXPECT_DEATH_IF_SUPPORTED(;, ""); - String output = GetCapturedStderr(); + std::string output = GetCapturedStderr(); ASSERT_TRUE(NULL != strstr(output.c_str(), "Death tests are not supported on this platform")); ASSERT_TRUE(NULL != strstr(output.c_str(), ";")); diff --git a/test/gtest-filepath_test.cc b/test/gtest-filepath_test.cc index 3196ea05..ae9f55a0 100644 --- a/test/gtest-filepath_test.cc +++ b/test/gtest-filepath_test.cc @@ -100,7 +100,7 @@ TEST(GetCurrentDirTest, ReturnsCurrentDir) { # else - EXPECT_STREQ(GTEST_PATH_SEP_, cwd.c_str()); + EXPECT_EQ(GTEST_PATH_SEP_, cwd.string()); # endif } @@ -109,7 +109,6 @@ TEST(GetCurrentDirTest, ReturnsCurrentDir) { TEST(IsEmptyTest, ReturnsTrueForEmptyPath) { EXPECT_TRUE(FilePath("").IsEmpty()); - EXPECT_TRUE(FilePath(NULL).IsEmpty()); } TEST(IsEmptyTest, ReturnsFalseForNonEmptyPath) { @@ -121,38 +120,38 @@ TEST(IsEmptyTest, ReturnsFalseForNonEmptyPath) { // RemoveDirectoryName "" -> "" TEST(RemoveDirectoryNameTest, WhenEmptyName) { - EXPECT_STREQ("", FilePath("").RemoveDirectoryName().c_str()); + EXPECT_EQ("", FilePath("").RemoveDirectoryName().string()); } // RemoveDirectoryName "afile" -> "afile" TEST(RemoveDirectoryNameTest, ButNoDirectory) { - EXPECT_STREQ("afile", - FilePath("afile").RemoveDirectoryName().c_str()); + EXPECT_EQ("afile", + FilePath("afile").RemoveDirectoryName().string()); } // RemoveDirectoryName "/afile" -> "afile" TEST(RemoveDirectoryNameTest, RootFileShouldGiveFileName) { - EXPECT_STREQ("afile", - FilePath(GTEST_PATH_SEP_ "afile").RemoveDirectoryName().c_str()); + EXPECT_EQ("afile", + FilePath(GTEST_PATH_SEP_ "afile").RemoveDirectoryName().string()); } // RemoveDirectoryName "adir/" -> "" TEST(RemoveDirectoryNameTest, WhereThereIsNoFileName) { - EXPECT_STREQ("", - FilePath("adir" GTEST_PATH_SEP_).RemoveDirectoryName().c_str()); + EXPECT_EQ("", + FilePath("adir" GTEST_PATH_SEP_).RemoveDirectoryName().string()); } // RemoveDirectoryName "adir/afile" -> "afile" TEST(RemoveDirectoryNameTest, ShouldGiveFileName) { - EXPECT_STREQ("afile", - FilePath("adir" GTEST_PATH_SEP_ "afile").RemoveDirectoryName().c_str()); + EXPECT_EQ("afile", + FilePath("adir" GTEST_PATH_SEP_ "afile").RemoveDirectoryName().string()); } // RemoveDirectoryName "adir/subdir/afile" -> "afile" TEST(RemoveDirectoryNameTest, ShouldAlsoGiveFileName) { - EXPECT_STREQ("afile", + EXPECT_EQ("afile", FilePath("adir" GTEST_PATH_SEP_ "subdir" GTEST_PATH_SEP_ "afile") - .RemoveDirectoryName().c_str()); + .RemoveDirectoryName().string()); } #if GTEST_HAS_ALT_PATH_SEP_ @@ -162,26 +161,23 @@ TEST(RemoveDirectoryNameTest, ShouldAlsoGiveFileName) { // RemoveDirectoryName("/afile") -> "afile" TEST(RemoveDirectoryNameTest, RootFileShouldGiveFileNameForAlternateSeparator) { - EXPECT_STREQ("afile", - FilePath("/afile").RemoveDirectoryName().c_str()); + EXPECT_EQ("afile", FilePath("/afile").RemoveDirectoryName().string()); } // RemoveDirectoryName("adir/") -> "" TEST(RemoveDirectoryNameTest, WhereThereIsNoFileNameForAlternateSeparator) { - EXPECT_STREQ("", - FilePath("adir/").RemoveDirectoryName().c_str()); + EXPECT_EQ("", FilePath("adir/").RemoveDirectoryName().string()); } // RemoveDirectoryName("adir/afile") -> "afile" TEST(RemoveDirectoryNameTest, ShouldGiveFileNameForAlternateSeparator) { - EXPECT_STREQ("afile", - FilePath("adir/afile").RemoveDirectoryName().c_str()); + EXPECT_EQ("afile", FilePath("adir/afile").RemoveDirectoryName().string()); } // RemoveDirectoryName("adir/subdir/afile") -> "afile" TEST(RemoveDirectoryNameTest, ShouldAlsoGiveFileNameForAlternateSeparator) { - EXPECT_STREQ("afile", - FilePath("adir/subdir/afile").RemoveDirectoryName().c_str()); + EXPECT_EQ("afile", + FilePath("adir/subdir/afile").RemoveDirectoryName().string()); } #endif @@ -190,38 +186,35 @@ TEST(RemoveDirectoryNameTest, ShouldAlsoGiveFileNameForAlternateSeparator) { TEST(RemoveFileNameTest, EmptyName) { #if GTEST_OS_WINDOWS_MOBILE // On Windows CE, we use the root as the current directory. - EXPECT_STREQ(GTEST_PATH_SEP_, - FilePath("").RemoveFileName().c_str()); + EXPECT_EQ(GTEST_PATH_SEP_, FilePath("").RemoveFileName().string()); #else - EXPECT_STREQ("." GTEST_PATH_SEP_, - FilePath("").RemoveFileName().c_str()); + EXPECT_EQ("." GTEST_PATH_SEP_, FilePath("").RemoveFileName().string()); #endif } // RemoveFileName "adir/" -> "adir/" TEST(RemoveFileNameTest, ButNoFile) { - EXPECT_STREQ("adir" GTEST_PATH_SEP_, - FilePath("adir" GTEST_PATH_SEP_).RemoveFileName().c_str()); + EXPECT_EQ("adir" GTEST_PATH_SEP_, + FilePath("adir" GTEST_PATH_SEP_).RemoveFileName().string()); } // RemoveFileName "adir/afile" -> "adir/" TEST(RemoveFileNameTest, GivesDirName) { - EXPECT_STREQ("adir" GTEST_PATH_SEP_, - FilePath("adir" GTEST_PATH_SEP_ "afile") - .RemoveFileName().c_str()); + EXPECT_EQ("adir" GTEST_PATH_SEP_, + FilePath("adir" GTEST_PATH_SEP_ "afile").RemoveFileName().string()); } // RemoveFileName "adir/subdir/afile" -> "adir/subdir/" TEST(RemoveFileNameTest, GivesDirAndSubDirName) { - EXPECT_STREQ("adir" GTEST_PATH_SEP_ "subdir" GTEST_PATH_SEP_, + EXPECT_EQ("adir" GTEST_PATH_SEP_ "subdir" GTEST_PATH_SEP_, FilePath("adir" GTEST_PATH_SEP_ "subdir" GTEST_PATH_SEP_ "afile") - .RemoveFileName().c_str()); + .RemoveFileName().string()); } // RemoveFileName "/afile" -> "/" TEST(RemoveFileNameTest, GivesRootDir) { - EXPECT_STREQ(GTEST_PATH_SEP_, - FilePath(GTEST_PATH_SEP_ "afile").RemoveFileName().c_str()); + EXPECT_EQ(GTEST_PATH_SEP_, + FilePath(GTEST_PATH_SEP_ "afile").RemoveFileName().string()); } #if GTEST_HAS_ALT_PATH_SEP_ @@ -231,26 +224,25 @@ TEST(RemoveFileNameTest, GivesRootDir) { // RemoveFileName("adir/") -> "adir/" TEST(RemoveFileNameTest, ButNoFileForAlternateSeparator) { - EXPECT_STREQ("adir" GTEST_PATH_SEP_, - FilePath("adir/").RemoveFileName().c_str()); + EXPECT_EQ("adir" GTEST_PATH_SEP_, + FilePath("adir/").RemoveFileName().string()); } // RemoveFileName("adir/afile") -> "adir/" TEST(RemoveFileNameTest, GivesDirNameForAlternateSeparator) { - EXPECT_STREQ("adir" GTEST_PATH_SEP_, - FilePath("adir/afile").RemoveFileName().c_str()); + EXPECT_EQ("adir" GTEST_PATH_SEP_, + FilePath("adir/afile").RemoveFileName().string()); } // RemoveFileName("adir/subdir/afile") -> "adir/subdir/" TEST(RemoveFileNameTest, GivesDirAndSubDirNameForAlternateSeparator) { - EXPECT_STREQ("adir" GTEST_PATH_SEP_ "subdir" GTEST_PATH_SEP_, - FilePath("adir/subdir/afile").RemoveFileName().c_str()); + EXPECT_EQ("adir" GTEST_PATH_SEP_ "subdir" GTEST_PATH_SEP_, + FilePath("adir/subdir/afile").RemoveFileName().string()); } // RemoveFileName("/afile") -> "\" TEST(RemoveFileNameTest, GivesRootDirForAlternateSeparator) { - EXPECT_STREQ(GTEST_PATH_SEP_, - FilePath("/afile").RemoveFileName().c_str()); + EXPECT_EQ(GTEST_PATH_SEP_, FilePath("/afile").RemoveFileName().string()); } #endif @@ -258,125 +250,120 @@ TEST(RemoveFileNameTest, GivesRootDirForAlternateSeparator) { TEST(MakeFileNameTest, GenerateWhenNumberIsZero) { FilePath actual = FilePath::MakeFileName(FilePath("foo"), FilePath("bar"), 0, "xml"); - EXPECT_STREQ("foo" GTEST_PATH_SEP_ "bar.xml", actual.c_str()); + EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar.xml", actual.string()); } TEST(MakeFileNameTest, GenerateFileNameNumberGtZero) { FilePath actual = FilePath::MakeFileName(FilePath("foo"), FilePath("bar"), 12, "xml"); - EXPECT_STREQ("foo" GTEST_PATH_SEP_ "bar_12.xml", actual.c_str()); + EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar_12.xml", actual.string()); } TEST(MakeFileNameTest, GenerateFileNameWithSlashNumberIsZero) { FilePath actual = FilePath::MakeFileName(FilePath("foo" GTEST_PATH_SEP_), FilePath("bar"), 0, "xml"); - EXPECT_STREQ("foo" GTEST_PATH_SEP_ "bar.xml", actual.c_str()); + EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar.xml", actual.string()); } TEST(MakeFileNameTest, GenerateFileNameWithSlashNumberGtZero) { FilePath actual = FilePath::MakeFileName(FilePath("foo" GTEST_PATH_SEP_), FilePath("bar"), 12, "xml"); - EXPECT_STREQ("foo" GTEST_PATH_SEP_ "bar_12.xml", actual.c_str()); + EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar_12.xml", actual.string()); } TEST(MakeFileNameTest, GenerateWhenNumberIsZeroAndDirIsEmpty) { FilePath actual = FilePath::MakeFileName(FilePath(""), FilePath("bar"), 0, "xml"); - EXPECT_STREQ("bar.xml", actual.c_str()); + EXPECT_EQ("bar.xml", actual.string()); } TEST(MakeFileNameTest, GenerateWhenNumberIsNotZeroAndDirIsEmpty) { FilePath actual = FilePath::MakeFileName(FilePath(""), FilePath("bar"), 14, "xml"); - EXPECT_STREQ("bar_14.xml", actual.c_str()); + EXPECT_EQ("bar_14.xml", actual.string()); } TEST(ConcatPathsTest, WorksWhenDirDoesNotEndWithPathSep) { FilePath actual = FilePath::ConcatPaths(FilePath("foo"), FilePath("bar.xml")); - EXPECT_STREQ("foo" GTEST_PATH_SEP_ "bar.xml", actual.c_str()); + EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar.xml", actual.string()); } TEST(ConcatPathsTest, WorksWhenPath1EndsWithPathSep) { FilePath actual = FilePath::ConcatPaths(FilePath("foo" GTEST_PATH_SEP_), FilePath("bar.xml")); - EXPECT_STREQ("foo" GTEST_PATH_SEP_ "bar.xml", actual.c_str()); + EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar.xml", actual.string()); } TEST(ConcatPathsTest, Path1BeingEmpty) { FilePath actual = FilePath::ConcatPaths(FilePath(""), FilePath("bar.xml")); - EXPECT_STREQ("bar.xml", actual.c_str()); + EXPECT_EQ("bar.xml", actual.string()); } TEST(ConcatPathsTest, Path2BeingEmpty) { - FilePath actual = FilePath::ConcatPaths(FilePath("foo"), - FilePath("")); - EXPECT_STREQ("foo" GTEST_PATH_SEP_, actual.c_str()); + FilePath actual = FilePath::ConcatPaths(FilePath("foo"), FilePath("")); + EXPECT_EQ("foo" GTEST_PATH_SEP_, actual.string()); } TEST(ConcatPathsTest, BothPathBeingEmpty) { FilePath actual = FilePath::ConcatPaths(FilePath(""), FilePath("")); - EXPECT_STREQ("", actual.c_str()); + EXPECT_EQ("", actual.string()); } TEST(ConcatPathsTest, Path1ContainsPathSep) { FilePath actual = FilePath::ConcatPaths(FilePath("foo" GTEST_PATH_SEP_ "bar"), FilePath("foobar.xml")); - EXPECT_STREQ("foo" GTEST_PATH_SEP_ "bar" GTEST_PATH_SEP_ "foobar.xml", - actual.c_str()); + EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar" GTEST_PATH_SEP_ "foobar.xml", + actual.string()); } TEST(ConcatPathsTest, Path2ContainsPathSep) { FilePath actual = FilePath::ConcatPaths( FilePath("foo" GTEST_PATH_SEP_), FilePath("bar" GTEST_PATH_SEP_ "bar.xml")); - EXPECT_STREQ("foo" GTEST_PATH_SEP_ "bar" GTEST_PATH_SEP_ "bar.xml", - actual.c_str()); + EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar" GTEST_PATH_SEP_ "bar.xml", + actual.string()); } TEST(ConcatPathsTest, Path2EndsWithPathSep) { FilePath actual = FilePath::ConcatPaths(FilePath("foo"), FilePath("bar" GTEST_PATH_SEP_)); - EXPECT_STREQ("foo" GTEST_PATH_SEP_ "bar" GTEST_PATH_SEP_, actual.c_str()); + EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar" GTEST_PATH_SEP_, actual.string()); } // RemoveTrailingPathSeparator "" -> "" TEST(RemoveTrailingPathSeparatorTest, EmptyString) { - EXPECT_STREQ("", - FilePath("").RemoveTrailingPathSeparator().c_str()); + EXPECT_EQ("", FilePath("").RemoveTrailingPathSeparator().string()); } // RemoveTrailingPathSeparator "foo" -> "foo" TEST(RemoveTrailingPathSeparatorTest, FileNoSlashString) { - EXPECT_STREQ("foo", - FilePath("foo").RemoveTrailingPathSeparator().c_str()); + EXPECT_EQ("foo", FilePath("foo").RemoveTrailingPathSeparator().string()); } // RemoveTrailingPathSeparator "foo/" -> "foo" TEST(RemoveTrailingPathSeparatorTest, ShouldRemoveTrailingSeparator) { - EXPECT_STREQ( - "foo", - FilePath("foo" GTEST_PATH_SEP_).RemoveTrailingPathSeparator().c_str()); + EXPECT_EQ("foo", + FilePath("foo" GTEST_PATH_SEP_).RemoveTrailingPathSeparator().string()); #if GTEST_HAS_ALT_PATH_SEP_ - EXPECT_STREQ("foo", - FilePath("foo/").RemoveTrailingPathSeparator().c_str()); + EXPECT_EQ("foo", FilePath("foo/").RemoveTrailingPathSeparator().string()); #endif } // RemoveTrailingPathSeparator "foo/bar/" -> "foo/bar/" TEST(RemoveTrailingPathSeparatorTest, ShouldRemoveLastSeparator) { - EXPECT_STREQ("foo" GTEST_PATH_SEP_ "bar", - FilePath("foo" GTEST_PATH_SEP_ "bar" GTEST_PATH_SEP_) - .RemoveTrailingPathSeparator().c_str()); + EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar", + FilePath("foo" GTEST_PATH_SEP_ "bar" GTEST_PATH_SEP_) + .RemoveTrailingPathSeparator().string()); } // RemoveTrailingPathSeparator "foo/bar" -> "foo/bar" TEST(RemoveTrailingPathSeparatorTest, ShouldReturnUnmodified) { - EXPECT_STREQ("foo" GTEST_PATH_SEP_ "bar", - FilePath("foo" GTEST_PATH_SEP_ "bar") - .RemoveTrailingPathSeparator().c_str()); + EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar", + FilePath("foo" GTEST_PATH_SEP_ "bar") + .RemoveTrailingPathSeparator().string()); } TEST(DirectoryTest, RootDirectoryExists) { @@ -431,40 +418,35 @@ TEST(DirectoryTest, CurrentDirectoryExists) { #endif // GTEST_OS_WINDOWS } -TEST(NormalizeTest, NullStringsEqualEmptyDirectory) { - EXPECT_STREQ("", FilePath(NULL).c_str()); - EXPECT_STREQ("", FilePath(String(NULL)).c_str()); -} - // "foo/bar" == foo//bar" == "foo///bar" TEST(NormalizeTest, MultipleConsecutiveSepaparatorsInMidstring) { - EXPECT_STREQ("foo" GTEST_PATH_SEP_ "bar", - FilePath("foo" GTEST_PATH_SEP_ "bar").c_str()); - EXPECT_STREQ("foo" GTEST_PATH_SEP_ "bar", - FilePath("foo" GTEST_PATH_SEP_ GTEST_PATH_SEP_ "bar").c_str()); - EXPECT_STREQ("foo" GTEST_PATH_SEP_ "bar", - FilePath("foo" GTEST_PATH_SEP_ GTEST_PATH_SEP_ - GTEST_PATH_SEP_ "bar").c_str()); + EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar", + FilePath("foo" GTEST_PATH_SEP_ "bar").string()); + EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar", + FilePath("foo" GTEST_PATH_SEP_ GTEST_PATH_SEP_ "bar").string()); + EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar", + FilePath("foo" GTEST_PATH_SEP_ GTEST_PATH_SEP_ + GTEST_PATH_SEP_ "bar").string()); } // "/bar" == //bar" == "///bar" TEST(NormalizeTest, MultipleConsecutiveSepaparatorsAtStringStart) { - EXPECT_STREQ(GTEST_PATH_SEP_ "bar", - FilePath(GTEST_PATH_SEP_ "bar").c_str()); - EXPECT_STREQ(GTEST_PATH_SEP_ "bar", - FilePath(GTEST_PATH_SEP_ GTEST_PATH_SEP_ "bar").c_str()); - EXPECT_STREQ(GTEST_PATH_SEP_ "bar", - FilePath(GTEST_PATH_SEP_ GTEST_PATH_SEP_ GTEST_PATH_SEP_ "bar").c_str()); + EXPECT_EQ(GTEST_PATH_SEP_ "bar", + FilePath(GTEST_PATH_SEP_ "bar").string()); + EXPECT_EQ(GTEST_PATH_SEP_ "bar", + FilePath(GTEST_PATH_SEP_ GTEST_PATH_SEP_ "bar").string()); + EXPECT_EQ(GTEST_PATH_SEP_ "bar", + FilePath(GTEST_PATH_SEP_ GTEST_PATH_SEP_ GTEST_PATH_SEP_ "bar").string()); } // "foo/" == foo//" == "foo///" TEST(NormalizeTest, MultipleConsecutiveSepaparatorsAtStringEnd) { - EXPECT_STREQ("foo" GTEST_PATH_SEP_, - FilePath("foo" GTEST_PATH_SEP_).c_str()); - EXPECT_STREQ("foo" GTEST_PATH_SEP_, - FilePath("foo" GTEST_PATH_SEP_ GTEST_PATH_SEP_).c_str()); - EXPECT_STREQ("foo" GTEST_PATH_SEP_, - FilePath("foo" GTEST_PATH_SEP_ GTEST_PATH_SEP_ GTEST_PATH_SEP_).c_str()); + EXPECT_EQ("foo" GTEST_PATH_SEP_, + FilePath("foo" GTEST_PATH_SEP_).string()); + EXPECT_EQ("foo" GTEST_PATH_SEP_, + FilePath("foo" GTEST_PATH_SEP_ GTEST_PATH_SEP_).string()); + EXPECT_EQ("foo" GTEST_PATH_SEP_, + FilePath("foo" GTEST_PATH_SEP_ GTEST_PATH_SEP_ GTEST_PATH_SEP_).string()); } #if GTEST_HAS_ALT_PATH_SEP_ @@ -473,12 +455,12 @@ TEST(NormalizeTest, MultipleConsecutiveSepaparatorsAtStringEnd) { // regardless of their combination (e.g. "foo\" =="foo/\" == // "foo\\/"). TEST(NormalizeTest, MixAlternateSeparatorAtStringEnd) { - EXPECT_STREQ("foo" GTEST_PATH_SEP_, - FilePath("foo/").c_str()); - EXPECT_STREQ("foo" GTEST_PATH_SEP_, - FilePath("foo" GTEST_PATH_SEP_ "/").c_str()); - EXPECT_STREQ("foo" GTEST_PATH_SEP_, - FilePath("foo//" GTEST_PATH_SEP_).c_str()); + EXPECT_EQ("foo" GTEST_PATH_SEP_, + FilePath("foo/").string()); + EXPECT_EQ("foo" GTEST_PATH_SEP_, + FilePath("foo" GTEST_PATH_SEP_ "/").string()); + EXPECT_EQ("foo" GTEST_PATH_SEP_, + FilePath("foo//" GTEST_PATH_SEP_).string()); } #endif @@ -487,31 +469,31 @@ TEST(AssignmentOperatorTest, DefaultAssignedToNonDefault) { FilePath default_path; FilePath non_default_path("path"); non_default_path = default_path; - EXPECT_STREQ("", non_default_path.c_str()); - EXPECT_STREQ("", default_path.c_str()); // RHS var is unchanged. + EXPECT_EQ("", non_default_path.string()); + EXPECT_EQ("", default_path.string()); // RHS var is unchanged. } TEST(AssignmentOperatorTest, NonDefaultAssignedToDefault) { FilePath non_default_path("path"); FilePath default_path; default_path = non_default_path; - EXPECT_STREQ("path", default_path.c_str()); - EXPECT_STREQ("path", non_default_path.c_str()); // RHS var is unchanged. + EXPECT_EQ("path", default_path.string()); + EXPECT_EQ("path", non_default_path.string()); // RHS var is unchanged. } TEST(AssignmentOperatorTest, ConstAssignedToNonConst) { const FilePath const_default_path("const_path"); FilePath non_default_path("path"); non_default_path = const_default_path; - EXPECT_STREQ("const_path", non_default_path.c_str()); + EXPECT_EQ("const_path", non_default_path.string()); } class DirectoryCreationTest : public Test { protected: virtual void SetUp() { - testdata_path_.Set(FilePath(String::Format("%s%s%s", - TempDir().c_str(), GetCurrentExecutableName().c_str(), - "_directory_creation" GTEST_PATH_SEP_ "test" GTEST_PATH_SEP_))); + testdata_path_.Set(FilePath( + TempDir() + GetCurrentExecutableName().string() + + "_directory_creation" GTEST_PATH_SEP_ "test" GTEST_PATH_SEP_)); testdata_file_.Set(testdata_path_.RemoveTrailingPathSeparator()); unique_file0_.Set(FilePath::MakeFileName(testdata_path_, FilePath("unique"), @@ -532,21 +514,21 @@ class DirectoryCreationTest : public Test { posix::RmDir(testdata_path_.c_str()); } - String TempDir() const { + std::string TempDir() const { #if GTEST_OS_WINDOWS_MOBILE - return String("\\temp\\"); + return "\\temp\\"; #elif GTEST_OS_WINDOWS const char* temp_dir = posix::GetEnv("TEMP"); if (temp_dir == NULL || temp_dir[0] == '\0') - return String("\\temp\\"); - else if (String(temp_dir).EndsWith("\\")) - return String(temp_dir); + return "\\temp\\"; + else if (temp_dir[strlen(temp_dir) - 1] == '\\') + return temp_dir; else - return String::Format("%s\\", temp_dir); + return std::string(temp_dir) + "\\"; #elif GTEST_OS_LINUX_ANDROID - return String("/sdcard/"); + return "/sdcard/"; #else - return String("/tmp/"); + return "/tmp/"; #endif // GTEST_OS_WINDOWS_MOBILE } @@ -566,13 +548,13 @@ class DirectoryCreationTest : public Test { }; TEST_F(DirectoryCreationTest, CreateDirectoriesRecursively) { - EXPECT_FALSE(testdata_path_.DirectoryExists()) << testdata_path_.c_str(); + EXPECT_FALSE(testdata_path_.DirectoryExists()) << testdata_path_.string(); EXPECT_TRUE(testdata_path_.CreateDirectoriesRecursively()); EXPECT_TRUE(testdata_path_.DirectoryExists()); } TEST_F(DirectoryCreationTest, CreateDirectoriesForAlreadyExistingPath) { - EXPECT_FALSE(testdata_path_.DirectoryExists()) << testdata_path_.c_str(); + EXPECT_FALSE(testdata_path_.DirectoryExists()) << testdata_path_.string(); EXPECT_TRUE(testdata_path_.CreateDirectoriesRecursively()); // Call 'create' again... should still succeed. EXPECT_TRUE(testdata_path_.CreateDirectoriesRecursively()); @@ -581,7 +563,7 @@ TEST_F(DirectoryCreationTest, CreateDirectoriesForAlreadyExistingPath) { TEST_F(DirectoryCreationTest, CreateDirectoriesAndUniqueFilename) { FilePath file_path(FilePath::GenerateUniqueFileName(testdata_path_, FilePath("unique"), "txt")); - EXPECT_STREQ(unique_file0_.c_str(), file_path.c_str()); + EXPECT_EQ(unique_file0_.string(), file_path.string()); EXPECT_FALSE(file_path.FileOrDirectoryExists()); // file not there testdata_path_.CreateDirectoriesRecursively(); @@ -591,7 +573,7 @@ TEST_F(DirectoryCreationTest, CreateDirectoriesAndUniqueFilename) { FilePath file_path2(FilePath::GenerateUniqueFileName(testdata_path_, FilePath("unique"), "txt")); - EXPECT_STREQ(unique_file1_.c_str(), file_path2.c_str()); + EXPECT_EQ(unique_file1_.string(), file_path2.string()); EXPECT_FALSE(file_path2.FileOrDirectoryExists()); // file not there CreateTextFile(file_path2.c_str()); EXPECT_TRUE(file_path2.FileOrDirectoryExists()); @@ -612,43 +594,43 @@ TEST(NoDirectoryCreationTest, CreateNoDirectoriesForDefaultXmlFile) { TEST(FilePathTest, DefaultConstructor) { FilePath fp; - EXPECT_STREQ("", fp.c_str()); + EXPECT_EQ("", fp.string()); } TEST(FilePathTest, CharAndCopyConstructors) { const FilePath fp("spicy"); - EXPECT_STREQ("spicy", fp.c_str()); + EXPECT_EQ("spicy", fp.string()); const FilePath fp_copy(fp); - EXPECT_STREQ("spicy", fp_copy.c_str()); + EXPECT_EQ("spicy", fp_copy.string()); } TEST(FilePathTest, StringConstructor) { - const FilePath fp(String("cider")); - EXPECT_STREQ("cider", fp.c_str()); + const FilePath fp(std::string("cider")); + EXPECT_EQ("cider", fp.string()); } TEST(FilePathTest, Set) { const FilePath apple("apple"); FilePath mac("mac"); mac.Set(apple); // Implement Set() since overloading operator= is forbidden. - EXPECT_STREQ("apple", mac.c_str()); - EXPECT_STREQ("apple", apple.c_str()); + EXPECT_EQ("apple", mac.string()); + EXPECT_EQ("apple", apple.string()); } TEST(FilePathTest, ToString) { const FilePath file("drink"); - String str(file.ToString()); - EXPECT_STREQ("drink", str.c_str()); + EXPECT_EQ("drink", file.string()); } TEST(FilePathTest, RemoveExtension) { - EXPECT_STREQ("app", FilePath("app.exe").RemoveExtension("exe").c_str()); - EXPECT_STREQ("APP", FilePath("APP.EXE").RemoveExtension("exe").c_str()); + EXPECT_EQ("app", FilePath("app.cc").RemoveExtension("cc").string()); + EXPECT_EQ("app", FilePath("app.exe").RemoveExtension("exe").string()); + EXPECT_EQ("APP", FilePath("APP.EXE").RemoveExtension("exe").string()); } TEST(FilePathTest, RemoveExtensionWhenThereIsNoExtension) { - EXPECT_STREQ("app", FilePath("app").RemoveExtension("exe").c_str()); + EXPECT_EQ("app", FilePath("app").RemoveExtension("exe").string()); } TEST(FilePathTest, IsDirectory) { diff --git a/test/gtest-listener_test.cc b/test/gtest-listener_test.cc index 10086086..99662cff 100644 --- a/test/gtest-listener_test.cc +++ b/test/gtest-listener_test.cc @@ -45,10 +45,9 @@ using ::testing::TestEventListener; using ::testing::TestInfo; using ::testing::TestPartResult; using ::testing::UnitTest; -using ::testing::internal::String; // Used by tests to register their events. -std::vector* g_events = NULL; +std::vector* g_events = NULL; namespace testing { namespace internal { @@ -119,54 +118,52 @@ class EventRecordingListener : public TestEventListener { } private: - String GetFullMethodName(const char* name) { - Message message; - message << name_ << "." << name; - return message.GetString(); + std::string GetFullMethodName(const char* name) { + return name_ + "." + name; } - String name_; + std::string name_; }; class EnvironmentInvocationCatcher : public Environment { protected: virtual void SetUp() { - g_events->push_back(String("Environment::SetUp")); + g_events->push_back("Environment::SetUp"); } virtual void TearDown() { - g_events->push_back(String("Environment::TearDown")); + g_events->push_back("Environment::TearDown"); } }; class ListenerTest : public Test { protected: static void SetUpTestCase() { - g_events->push_back(String("ListenerTest::SetUpTestCase")); + g_events->push_back("ListenerTest::SetUpTestCase"); } static void TearDownTestCase() { - g_events->push_back(String("ListenerTest::TearDownTestCase")); + g_events->push_back("ListenerTest::TearDownTestCase"); } virtual void SetUp() { - g_events->push_back(String("ListenerTest::SetUp")); + g_events->push_back("ListenerTest::SetUp"); } virtual void TearDown() { - g_events->push_back(String("ListenerTest::TearDown")); + g_events->push_back("ListenerTest::TearDown"); } }; TEST_F(ListenerTest, DoesFoo) { // Test execution order within a test case is not guaranteed so we are not // recording the test name. - g_events->push_back(String("ListenerTest::* Test Body")); + g_events->push_back("ListenerTest::* Test Body"); SUCCEED(); // Triggers OnTestPartResult. } TEST_F(ListenerTest, DoesBar) { - g_events->push_back(String("ListenerTest::* Test Body")); + g_events->push_back("ListenerTest::* Test Body"); SUCCEED(); // Triggers OnTestPartResult. } @@ -177,7 +174,7 @@ TEST_F(ListenerTest, DoesBar) { using ::testing::internal::EnvironmentInvocationCatcher; using ::testing::internal::EventRecordingListener; -void VerifyResults(const std::vector& data, +void VerifyResults(const std::vector& data, const char* const* expected_data, int expected_data_size) { const int actual_size = data.size(); @@ -201,7 +198,7 @@ void VerifyResults(const std::vector& data, } int main(int argc, char **argv) { - std::vector events; + std::vector events; g_events = &events; InitGoogleTest(&argc, argv); diff --git a/test/gtest-message_test.cc b/test/gtest-message_test.cc index c09c6a83..175238ef 100644 --- a/test/gtest-message_test.cc +++ b/test/gtest-message_test.cc @@ -39,79 +39,72 @@ namespace { using ::testing::Message; -// A helper function that turns a Message into a C string. -const char* ToCString(const Message& msg) { - static testing::internal::String result; - result = msg.GetString(); - return result.c_str(); -} - // Tests the testing::Message class // Tests the default constructor. TEST(MessageTest, DefaultConstructor) { const Message msg; - EXPECT_STREQ("", ToCString(msg)); + EXPECT_EQ("", msg.GetString()); } // Tests the copy constructor. TEST(MessageTest, CopyConstructor) { const Message msg1("Hello"); const Message msg2(msg1); - EXPECT_STREQ("Hello", ToCString(msg2)); + EXPECT_EQ("Hello", msg2.GetString()); } // Tests constructing a Message from a C-string. TEST(MessageTest, ConstructsFromCString) { Message msg("Hello"); - EXPECT_STREQ("Hello", ToCString(msg)); + EXPECT_EQ("Hello", msg.GetString()); } // Tests streaming a float. TEST(MessageTest, StreamsFloat) { - const char* const s = ToCString(Message() << 1.23456F << " " << 2.34567F); + const std::string s = (Message() << 1.23456F << " " << 2.34567F).GetString(); // Both numbers should be printed with enough precision. - EXPECT_PRED_FORMAT2(testing::IsSubstring, "1.234560", s); - EXPECT_PRED_FORMAT2(testing::IsSubstring, " 2.345669", s); + EXPECT_PRED_FORMAT2(testing::IsSubstring, "1.234560", s.c_str()); + EXPECT_PRED_FORMAT2(testing::IsSubstring, " 2.345669", s.c_str()); } // Tests streaming a double. TEST(MessageTest, StreamsDouble) { - const char* const s = ToCString(Message() << 1260570880.4555497 << " " - << 1260572265.1954534); + const std::string s = (Message() << 1260570880.4555497 << " " + << 1260572265.1954534).GetString(); // Both numbers should be printed with enough precision. - EXPECT_PRED_FORMAT2(testing::IsSubstring, "1260570880.45", s); - EXPECT_PRED_FORMAT2(testing::IsSubstring, " 1260572265.19", s); + EXPECT_PRED_FORMAT2(testing::IsSubstring, "1260570880.45", s.c_str()); + EXPECT_PRED_FORMAT2(testing::IsSubstring, " 1260572265.19", s.c_str()); } // Tests streaming a non-char pointer. TEST(MessageTest, StreamsPointer) { int n = 0; int* p = &n; - EXPECT_STRNE("(null)", ToCString(Message() << p)); + EXPECT_NE("(null)", (Message() << p).GetString()); } // Tests streaming a NULL non-char pointer. TEST(MessageTest, StreamsNullPointer) { int* p = NULL; - EXPECT_STREQ("(null)", ToCString(Message() << p)); + EXPECT_EQ("(null)", (Message() << p).GetString()); } // Tests streaming a C string. TEST(MessageTest, StreamsCString) { - EXPECT_STREQ("Foo", ToCString(Message() << "Foo")); + EXPECT_EQ("Foo", (Message() << "Foo").GetString()); } // Tests streaming a NULL C string. TEST(MessageTest, StreamsNullCString) { char* p = NULL; - EXPECT_STREQ("(null)", ToCString(Message() << p)); + EXPECT_EQ("(null)", (Message() << p).GetString()); } // Tests streaming std::string. TEST(MessageTest, StreamsString) { const ::std::string str("Hello"); - EXPECT_STREQ("Hello", ToCString(Message() << str)); + EXPECT_EQ("Hello", (Message() << str).GetString()); } // Tests that we can output strings containing embedded NULs. @@ -120,34 +113,34 @@ TEST(MessageTest, StreamsStringWithEmbeddedNUL) { "Here's a NUL\0 and some more string"; const ::std::string string_with_nul(char_array_with_nul, sizeof(char_array_with_nul) - 1); - EXPECT_STREQ("Here's a NUL\\0 and some more string", - ToCString(Message() << string_with_nul)); + EXPECT_EQ("Here's a NUL\\0 and some more string", + (Message() << string_with_nul).GetString()); } // Tests streaming a NUL char. TEST(MessageTest, StreamsNULChar) { - EXPECT_STREQ("\\0", ToCString(Message() << '\0')); + EXPECT_EQ("\\0", (Message() << '\0').GetString()); } // Tests streaming int. TEST(MessageTest, StreamsInt) { - EXPECT_STREQ("123", ToCString(Message() << 123)); + EXPECT_EQ("123", (Message() << 123).GetString()); } // Tests that basic IO manipulators (endl, ends, and flush) can be // streamed to Message. TEST(MessageTest, StreamsBasicIoManip) { - EXPECT_STREQ("Line 1.\nA NUL char \\0 in line 2.", - ToCString(Message() << "Line 1." << std::endl + EXPECT_EQ("Line 1.\nA NUL char \\0 in line 2.", + (Message() << "Line 1." << std::endl << "A NUL char " << std::ends << std::flush - << " in line 2.")); + << " in line 2.").GetString()); } // Tests Message::GetString() TEST(MessageTest, GetString) { Message msg; msg << 1 << " lamb"; - EXPECT_STREQ("1 lamb", msg.GetString().c_str()); + EXPECT_EQ("1 lamb", msg.GetString()); } // Tests streaming a Message object to an ostream. @@ -155,7 +148,7 @@ TEST(MessageTest, StreamsToOStream) { Message msg("Hello"); ::std::stringstream ss; ss << msg; - EXPECT_STREQ("Hello", testing::internal::StringStreamToString(&ss).c_str()); + EXPECT_EQ("Hello", testing::internal::StringStreamToString(&ss)); } // Tests that a Message object doesn't take up too much stack space. diff --git a/test/gtest-options_test.cc b/test/gtest-options_test.cc index 9e98f3f0..5586dc3b 100644 --- a/test/gtest-options_test.cc +++ b/test/gtest-options_test.cc @@ -78,14 +78,14 @@ TEST(XmlOutputTest, GetOutputFormat) { TEST(XmlOutputTest, GetOutputFileDefault) { GTEST_FLAG(output) = ""; - EXPECT_STREQ(GetAbsolutePathOf(FilePath("test_detail.xml")).c_str(), - UnitTestOptions::GetAbsolutePathToOutputFile().c_str()); + EXPECT_EQ(GetAbsolutePathOf(FilePath("test_detail.xml")).string(), + UnitTestOptions::GetAbsolutePathToOutputFile()); } TEST(XmlOutputTest, GetOutputFileSingleFile) { GTEST_FLAG(output) = "xml:filename.abc"; - EXPECT_STREQ(GetAbsolutePathOf(FilePath("filename.abc")).c_str(), - UnitTestOptions::GetAbsolutePathToOutputFile().c_str()); + EXPECT_EQ(GetAbsolutePathOf(FilePath("filename.abc")).string(), + UnitTestOptions::GetAbsolutePathToOutputFile()); } TEST(XmlOutputTest, GetOutputFileFromDirectoryPath) { @@ -93,8 +93,9 @@ TEST(XmlOutputTest, GetOutputFileFromDirectoryPath) { const std::string expected_output_file = GetAbsolutePathOf( FilePath(std::string("path") + GTEST_PATH_SEP_ + - GetCurrentExecutableName().c_str() + ".xml")).c_str(); - const String& output_file = UnitTestOptions::GetAbsolutePathToOutputFile(); + GetCurrentExecutableName().string() + ".xml")).string(); + const std::string& output_file = + UnitTestOptions::GetAbsolutePathToOutputFile(); #if GTEST_OS_WINDOWS EXPECT_STRCASEEQ(expected_output_file.c_str(), output_file.c_str()); #else @@ -103,7 +104,7 @@ TEST(XmlOutputTest, GetOutputFileFromDirectoryPath) { } TEST(OutputFileHelpersTest, GetCurrentExecutableName) { - const std::string exe_str = GetCurrentExecutableName().c_str(); + const std::string exe_str = GetCurrentExecutableName().string(); #if GTEST_OS_WINDOWS const bool success = _strcmpi("gtest-options_test", exe_str.c_str()) == 0 || @@ -129,12 +130,12 @@ class XmlOutputChangeDirTest : public Test { original_working_dir_ = FilePath::GetCurrentDir(); posix::ChDir(".."); // This will make the test fail if run from the root directory. - EXPECT_STRNE(original_working_dir_.c_str(), - FilePath::GetCurrentDir().c_str()); + EXPECT_NE(original_working_dir_.string(), + FilePath::GetCurrentDir().string()); } virtual void TearDown() { - posix::ChDir(original_working_dir_.c_str()); + posix::ChDir(original_working_dir_.string().c_str()); } FilePath original_working_dir_; @@ -142,23 +143,23 @@ class XmlOutputChangeDirTest : public Test { TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithDefault) { GTEST_FLAG(output) = ""; - EXPECT_STREQ(FilePath::ConcatPaths(original_working_dir_, - FilePath("test_detail.xml")).c_str(), - UnitTestOptions::GetAbsolutePathToOutputFile().c_str()); + EXPECT_EQ(FilePath::ConcatPaths(original_working_dir_, + FilePath("test_detail.xml")).string(), + UnitTestOptions::GetAbsolutePathToOutputFile()); } TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithDefaultXML) { GTEST_FLAG(output) = "xml"; - EXPECT_STREQ(FilePath::ConcatPaths(original_working_dir_, - FilePath("test_detail.xml")).c_str(), - UnitTestOptions::GetAbsolutePathToOutputFile().c_str()); + EXPECT_EQ(FilePath::ConcatPaths(original_working_dir_, + FilePath("test_detail.xml")).string(), + UnitTestOptions::GetAbsolutePathToOutputFile()); } TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithRelativeFile) { GTEST_FLAG(output) = "xml:filename.abc"; - EXPECT_STREQ(FilePath::ConcatPaths(original_working_dir_, - FilePath("filename.abc")).c_str(), - UnitTestOptions::GetAbsolutePathToOutputFile().c_str()); + EXPECT_EQ(FilePath::ConcatPaths(original_working_dir_, + FilePath("filename.abc")).string(), + UnitTestOptions::GetAbsolutePathToOutputFile()); } TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithRelativePath) { @@ -167,8 +168,9 @@ TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithRelativePath) { FilePath::ConcatPaths( original_working_dir_, FilePath(std::string("path") + GTEST_PATH_SEP_ + - GetCurrentExecutableName().c_str() + ".xml")).c_str(); - const String& output_file = UnitTestOptions::GetAbsolutePathToOutputFile(); + GetCurrentExecutableName().string() + ".xml")).string(); + const std::string& output_file = + UnitTestOptions::GetAbsolutePathToOutputFile(); #if GTEST_OS_WINDOWS EXPECT_STRCASEEQ(expected_output_file.c_str(), output_file.c_str()); #else @@ -179,12 +181,12 @@ TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithRelativePath) { TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithAbsoluteFile) { #if GTEST_OS_WINDOWS GTEST_FLAG(output) = "xml:c:\\tmp\\filename.abc"; - EXPECT_STREQ(FilePath("c:\\tmp\\filename.abc").c_str(), - UnitTestOptions::GetAbsolutePathToOutputFile().c_str()); + EXPECT_EQ(FilePath("c:\\tmp\\filename.abc").string(), + UnitTestOptions::GetAbsolutePathToOutputFile()); #else GTEST_FLAG(output) ="xml:/tmp/filename.abc"; - EXPECT_STREQ(FilePath("/tmp/filename.abc").c_str(), - UnitTestOptions::GetAbsolutePathToOutputFile().c_str()); + EXPECT_EQ(FilePath("/tmp/filename.abc").string(), + UnitTestOptions::GetAbsolutePathToOutputFile()); #endif } @@ -197,8 +199,9 @@ TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithAbsolutePath) { GTEST_FLAG(output) = "xml:" + path; const std::string expected_output_file = - path + GetCurrentExecutableName().c_str() + ".xml"; - const String& output_file = UnitTestOptions::GetAbsolutePathToOutputFile(); + path + GetCurrentExecutableName().string() + ".xml"; + const std::string& output_file = + UnitTestOptions::GetAbsolutePathToOutputFile(); #if GTEST_OS_WINDOWS EXPECT_STRCASEEQ(expected_output_file.c_str(), output_file.c_str()); diff --git a/test/gtest-param-test_test.cc b/test/gtest-param-test_test.cc index cf618665..7b6f7e24 100644 --- a/test/gtest-param-test_test.cc +++ b/test/gtest-param-test_test.cc @@ -280,10 +280,10 @@ class DogAdder { bool operator<(const DogAdder& other) const { return value_ < other.value_; } - const ::testing::internal::String& value() const { return value_; } + const std::string& value() const { return value_; } private: - ::testing::internal::String value_; + std::string value_; }; TEST(RangeTest, WorksWithACustomType) { diff --git a/test/gtest-port_test.cc b/test/gtest-port_test.cc index dfbf029f..43f1f201 100644 --- a/test/gtest-port_test.cc +++ b/test/gtest-port_test.cc @@ -1005,7 +1005,7 @@ TEST(ThreadLocalTest, ValueDefaultContructorIsNotRequiredForParamVersion) { } TEST(ThreadLocalTest, GetAndPointerReturnSameValue) { - ThreadLocal thread_local_string; + ThreadLocal thread_local_string; EXPECT_EQ(thread_local_string.pointer(), &(thread_local_string.get())); @@ -1015,8 +1015,9 @@ TEST(ThreadLocalTest, GetAndPointerReturnSameValue) { } TEST(ThreadLocalTest, PointerAndConstPointerReturnSameValue) { - ThreadLocal thread_local_string; - const ThreadLocal& const_thread_local_string = thread_local_string; + ThreadLocal thread_local_string; + const ThreadLocal& const_thread_local_string = + thread_local_string; EXPECT_EQ(thread_local_string.pointer(), const_thread_local_string.pointer()); @@ -1126,18 +1127,19 @@ void RunFromThread(void (func)(T), T param) { thread.Join(); } -void RetrieveThreadLocalValue(pair*, String*> param) { +void RetrieveThreadLocalValue( + pair*, std::string*> param) { *param.second = param.first->get(); } TEST(ThreadLocalTest, ParameterizedConstructorSetsDefault) { - ThreadLocal thread_local_string("foo"); + ThreadLocal thread_local_string("foo"); EXPECT_STREQ("foo", thread_local_string.get().c_str()); thread_local_string.set("bar"); EXPECT_STREQ("bar", thread_local_string.get().c_str()); - String result; + std::string result; RunFromThread(&RetrieveThreadLocalValue, make_pair(&thread_local_string, &result)); EXPECT_STREQ("foo", result.c_str()); @@ -1235,14 +1237,14 @@ TEST(ThreadLocalTest, DestroysManagedObjectAtThreadExit) { } TEST(ThreadLocalTest, ThreadLocalMutationsAffectOnlyCurrentThread) { - ThreadLocal thread_local_string; + ThreadLocal thread_local_string; thread_local_string.set("Foo"); EXPECT_STREQ("Foo", thread_local_string.get().c_str()); - String result; + std::string result; RunFromThread(&RetrieveThreadLocalValue, make_pair(&thread_local_string, &result)); - EXPECT_TRUE(result.c_str() == NULL); + EXPECT_TRUE(result.empty()); } #endif // GTEST_IS_THREADSAFE diff --git a/test/gtest_output_test_.cc b/test/gtest_output_test_.cc index da8b7449..07ab633d 100644 --- a/test/gtest_output_test_.cc +++ b/test/gtest_output_test_.cc @@ -58,7 +58,6 @@ using testing::internal::ThreadWithParam; #endif namespace posix = ::testing::internal::posix; -using testing::internal::String; using testing::internal::scoped_ptr; // Tests catching fatal failures. @@ -1005,7 +1004,8 @@ int main(int argc, char **argv) { // for it. testing::InitGoogleTest(&argc, argv); if (argc >= 2 && - String(argv[1]) == "--gtest_internal_skip_environment_and_ad_hoc_tests") + (std::string(argv[1]) == + "--gtest_internal_skip_environment_and_ad_hoc_tests")) GTEST_FLAG(internal_skip_environment_and_ad_hoc_tests) = true; #if GTEST_HAS_DEATH_TEST diff --git a/test/gtest_shuffle_test_.cc b/test/gtest_shuffle_test_.cc index 0752789e..6fb441bd 100644 --- a/test/gtest_shuffle_test_.cc +++ b/test/gtest_shuffle_test_.cc @@ -42,7 +42,6 @@ using ::testing::Test; using ::testing::TestEventListeners; using ::testing::TestInfo; using ::testing::UnitTest; -using ::testing::internal::String; using ::testing::internal::scoped_ptr; // The test methods are empty, as the sole purpose of this program is diff --git a/test/gtest_stress_test.cc b/test/gtest_stress_test.cc index 4e7d9bff..e7daa430 100644 --- a/test/gtest_stress_test.cc +++ b/test/gtest_stress_test.cc @@ -50,7 +50,6 @@ namespace testing { namespace { using internal::Notification; -using internal::String; using internal::TestPropertyKeyIs; using internal::ThreadWithParam; using internal::scoped_ptr; @@ -62,13 +61,13 @@ using internal::scoped_ptr; // How many threads to create? const int kThreadCount = 50; -String IdToKey(int id, const char* suffix) { +std::string IdToKey(int id, const char* suffix) { Message key; key << "key_" << id << "_" << suffix; return key.GetString(); } -String IdToString(int id) { +std::string IdToString(int id) { Message id_message; id_message << id; return id_message.GetString(); diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index 79e11b62..f4f30431 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -931,259 +931,16 @@ TEST(AssertHelperTest, AssertHelperIsSmall) { EXPECT_LE(sizeof(testing::internal::AssertHelper), sizeof(void*)); } -// Tests the String class. - -// Tests String's constructors. -TEST(StringTest, Constructors) { - // Default ctor. - String s1; - // We aren't using EXPECT_EQ(NULL, s1.c_str()) because comparing - // pointers with NULL isn't supported on all platforms. - EXPECT_EQ(0U, s1.length()); - EXPECT_TRUE(NULL == s1.c_str()); - - // Implicitly constructs from a C-string. - String s2 = "Hi"; - EXPECT_EQ(2U, s2.length()); - EXPECT_STREQ("Hi", s2.c_str()); - - // Constructs from a C-string and a length. - String s3("hello", 3); - EXPECT_EQ(3U, s3.length()); - EXPECT_STREQ("hel", s3.c_str()); - - // The empty String should be created when String is constructed with - // a NULL pointer and length 0. - EXPECT_EQ(0U, String(NULL, 0).length()); - EXPECT_FALSE(String(NULL, 0).c_str() == NULL); - - // Constructs a String that contains '\0'. - String s4("a\0bcd", 4); - EXPECT_EQ(4U, s4.length()); - EXPECT_EQ('a', s4.c_str()[0]); - EXPECT_EQ('\0', s4.c_str()[1]); - EXPECT_EQ('b', s4.c_str()[2]); - EXPECT_EQ('c', s4.c_str()[3]); - - // Copy ctor where the source is NULL. - const String null_str; - String s5 = null_str; - EXPECT_TRUE(s5.c_str() == NULL); - - // Copy ctor where the source isn't NULL. - String s6 = s3; - EXPECT_EQ(3U, s6.length()); - EXPECT_STREQ("hel", s6.c_str()); - - // Copy ctor where the source contains '\0'. - String s7 = s4; - EXPECT_EQ(4U, s7.length()); - EXPECT_EQ('a', s7.c_str()[0]); - EXPECT_EQ('\0', s7.c_str()[1]); - EXPECT_EQ('b', s7.c_str()[2]); - EXPECT_EQ('c', s7.c_str()[3]); -} - -TEST(StringTest, ConvertsFromStdString) { - // An empty std::string. - const std::string src1(""); - const String dest1 = src1; - EXPECT_EQ(0U, dest1.length()); - EXPECT_STREQ("", dest1.c_str()); - - // A normal std::string. - const std::string src2("Hi"); - const String dest2 = src2; - EXPECT_EQ(2U, dest2.length()); - EXPECT_STREQ("Hi", dest2.c_str()); - - // An std::string with an embedded NUL character. - const char src3[] = "a\0b"; - const String dest3 = std::string(src3, sizeof(src3)); - EXPECT_EQ(sizeof(src3), dest3.length()); - EXPECT_EQ('a', dest3.c_str()[0]); - EXPECT_EQ('\0', dest3.c_str()[1]); - EXPECT_EQ('b', dest3.c_str()[2]); -} - -TEST(StringTest, ConvertsToStdString) { - // An empty String. - const String src1(""); - const std::string dest1 = src1; - EXPECT_EQ("", dest1); - - // A normal String. - const String src2("Hi"); - const std::string dest2 = src2; - EXPECT_EQ("Hi", dest2); - - // A String containing a '\0'. - const String src3("x\0y", 3); - const std::string dest3 = src3; - EXPECT_EQ(std::string("x\0y", 3), dest3); -} - -#if GTEST_HAS_GLOBAL_STRING - -TEST(StringTest, ConvertsFromGlobalString) { - // An empty ::string. - const ::string src1(""); - const String dest1 = src1; - EXPECT_EQ(0U, dest1.length()); - EXPECT_STREQ("", dest1.c_str()); - - // A normal ::string. - const ::string src2("Hi"); - const String dest2 = src2; - EXPECT_EQ(2U, dest2.length()); - EXPECT_STREQ("Hi", dest2.c_str()); - - // An ::string with an embedded NUL character. - const char src3[] = "x\0y"; - const String dest3 = ::string(src3, sizeof(src3)); - EXPECT_EQ(sizeof(src3), dest3.length()); - EXPECT_EQ('x', dest3.c_str()[0]); - EXPECT_EQ('\0', dest3.c_str()[1]); - EXPECT_EQ('y', dest3.c_str()[2]); -} - -TEST(StringTest, ConvertsToGlobalString) { - // An empty String. - const String src1(""); - const ::string dest1 = src1; - EXPECT_EQ("", dest1); - - // A normal String. - const String src2("Hi"); - const ::string dest2 = src2; - EXPECT_EQ("Hi", dest2); - - const String src3("x\0y", 3); - const ::string dest3 = src3; - EXPECT_EQ(::string("x\0y", 3), dest3); -} - -#endif // GTEST_HAS_GLOBAL_STRING - -// Tests String::empty(). -TEST(StringTest, Empty) { - EXPECT_TRUE(String("").empty()); - EXPECT_FALSE(String().empty()); - EXPECT_FALSE(String(NULL).empty()); - EXPECT_FALSE(String("a").empty()); - EXPECT_FALSE(String("\0", 1).empty()); -} - -// Tests String::Compare(). -TEST(StringTest, Compare) { - // NULL vs NULL. - EXPECT_EQ(0, String().Compare(String())); - - // NULL vs non-NULL. - EXPECT_EQ(-1, String().Compare(String(""))); - - // Non-NULL vs NULL. - EXPECT_EQ(1, String("").Compare(String())); - - // The following covers non-NULL vs non-NULL. - - // "" vs "". - EXPECT_EQ(0, String("").Compare(String(""))); - - // "" vs non-"". - EXPECT_EQ(-1, String("").Compare(String("\0", 1))); - EXPECT_EQ(-1, String("").Compare(" ")); - - // Non-"" vs "". - EXPECT_EQ(1, String("a").Compare(String(""))); - - // The following covers non-"" vs non-"". - - // Same length and equal. - EXPECT_EQ(0, String("a").Compare(String("a"))); - - // Same length and different. - EXPECT_EQ(-1, String("a\0b", 3).Compare(String("a\0c", 3))); - EXPECT_EQ(1, String("b").Compare(String("a"))); - - // Different lengths. - EXPECT_EQ(-1, String("a").Compare(String("ab"))); - EXPECT_EQ(-1, String("a").Compare(String("a\0", 2))); - EXPECT_EQ(1, String("abc").Compare(String("aacd"))); -} - -// Tests String::operator==(). -TEST(StringTest, Equals) { - const String null(NULL); - EXPECT_TRUE(null == NULL); // NOLINT - EXPECT_FALSE(null == ""); // NOLINT - EXPECT_FALSE(null == "bar"); // NOLINT - - const String empty(""); - EXPECT_FALSE(empty == NULL); // NOLINT - EXPECT_TRUE(empty == ""); // NOLINT - EXPECT_FALSE(empty == "bar"); // NOLINT - - const String foo("foo"); - EXPECT_FALSE(foo == NULL); // NOLINT - EXPECT_FALSE(foo == ""); // NOLINT - EXPECT_FALSE(foo == "bar"); // NOLINT - EXPECT_TRUE(foo == "foo"); // NOLINT - - const String bar("x\0y", 3); - EXPECT_NE(bar, "x"); -} - -// Tests String::operator!=(). -TEST(StringTest, NotEquals) { - const String null(NULL); - EXPECT_FALSE(null != NULL); // NOLINT - EXPECT_TRUE(null != ""); // NOLINT - EXPECT_TRUE(null != "bar"); // NOLINT - - const String empty(""); - EXPECT_TRUE(empty != NULL); // NOLINT - EXPECT_FALSE(empty != ""); // NOLINT - EXPECT_TRUE(empty != "bar"); // NOLINT - - const String foo("foo"); - EXPECT_TRUE(foo != NULL); // NOLINT - EXPECT_TRUE(foo != ""); // NOLINT - EXPECT_TRUE(foo != "bar"); // NOLINT - EXPECT_FALSE(foo != "foo"); // NOLINT - - const String bar("x\0y", 3); - EXPECT_NE(bar, "x"); -} - -// Tests String::length(). -TEST(StringTest, Length) { - EXPECT_EQ(0U, String().length()); - EXPECT_EQ(0U, String("").length()); - EXPECT_EQ(2U, String("ab").length()); - EXPECT_EQ(3U, String("a\0b", 3).length()); -} - -// Tests String::EndsWith(). -TEST(StringTest, EndsWith) { - EXPECT_TRUE(String("foobar").EndsWith("bar")); - EXPECT_TRUE(String("foobar").EndsWith("")); - EXPECT_TRUE(String("").EndsWith("")); - - EXPECT_FALSE(String("foobar").EndsWith("foo")); - EXPECT_FALSE(String("").EndsWith("foo")); -} - // Tests String::EndsWithCaseInsensitive(). TEST(StringTest, EndsWithCaseInsensitive) { - EXPECT_TRUE(String("foobar").EndsWithCaseInsensitive("BAR")); - EXPECT_TRUE(String("foobaR").EndsWithCaseInsensitive("bar")); - EXPECT_TRUE(String("foobar").EndsWithCaseInsensitive("")); - EXPECT_TRUE(String("").EndsWithCaseInsensitive("")); + EXPECT_TRUE(String::EndsWithCaseInsensitive("foobar", "BAR")); + EXPECT_TRUE(String::EndsWithCaseInsensitive("foobaR", "bar")); + EXPECT_TRUE(String::EndsWithCaseInsensitive("foobar", "")); + EXPECT_TRUE(String::EndsWithCaseInsensitive("", "")); - EXPECT_FALSE(String("Foobar").EndsWithCaseInsensitive("foo")); - EXPECT_FALSE(String("foobar").EndsWithCaseInsensitive("Foo")); - EXPECT_FALSE(String("").EndsWithCaseInsensitive("foo")); + EXPECT_FALSE(String::EndsWithCaseInsensitive("Foobar", "foo")); + EXPECT_FALSE(String::EndsWithCaseInsensitive("foobar", "Foo")); + EXPECT_FALSE(String::EndsWithCaseInsensitive("", "foo")); } // C++Builder's preprocessor is buggy; it fails to expand macros that @@ -1203,61 +960,6 @@ TEST(StringTest, CaseInsensitiveWideCStringEquals) { EXPECT_TRUE(String::CaseInsensitiveWideCStringEquals(L"FOOBAR", L"foobar")); } -// Tests that NULL can be assigned to a String. -TEST(StringTest, CanBeAssignedNULL) { - const String src(NULL); - String dest; - - dest = src; - EXPECT_STREQ(NULL, dest.c_str()); -} - -// Tests that the empty string "" can be assigned to a String. -TEST(StringTest, CanBeAssignedEmpty) { - const String src(""); - String dest; - - dest = src; - EXPECT_STREQ("", dest.c_str()); -} - -// Tests that a non-empty string can be assigned to a String. -TEST(StringTest, CanBeAssignedNonEmpty) { - const String src("hello"); - String dest; - dest = src; - EXPECT_EQ(5U, dest.length()); - EXPECT_STREQ("hello", dest.c_str()); - - const String src2("x\0y", 3); - String dest2; - dest2 = src2; - EXPECT_EQ(3U, dest2.length()); - EXPECT_EQ('x', dest2.c_str()[0]); - EXPECT_EQ('\0', dest2.c_str()[1]); - EXPECT_EQ('y', dest2.c_str()[2]); -} - -// Tests that a String can be assigned to itself. -TEST(StringTest, CanBeAssignedSelf) { - String dest("hello"); - - // Use explicit function call notation here to suppress self-assign warning. - dest.operator=(dest); - EXPECT_STREQ("hello", dest.c_str()); -} - -// Sun Studio < 12 incorrectly rejects this code due to an overloading -// ambiguity. -#if !(defined(__SUNPRO_CC) && __SUNPRO_CC < 0x590) -// Tests streaming a String. -TEST(StringTest, Streams) { - EXPECT_EQ(StreamableToString(String()), "(null)"); - EXPECT_EQ(StreamableToString(String("")), ""); - EXPECT_EQ(StreamableToString(String("a\0b", 3)), "a\\0b"); -} -#endif - // Tests that String::Format() works. TEST(StringTest, FormatWorks) { // Normal case: the format spec is valid, the arguments match the @@ -1269,19 +971,19 @@ TEST(StringTest, FormatWorks) { const size_t kSize = sizeof(buffer); memset(buffer, 'a', kSize - 1); buffer[kSize - 1] = '\0'; - EXPECT_STREQ(buffer, String::Format("%s", buffer).c_str()); + EXPECT_EQ(buffer, String::Format("%s", buffer)); // The result needs to be 4096 characters, exceeding Format()'s limit. - EXPECT_STREQ("", - String::Format("x%s", buffer).c_str()); + EXPECT_EQ("", + String::Format("x%s", buffer)); #if GTEST_OS_LINUX && !GTEST_OS_LINUX_ANDROID // On Linux, invalid format spec should lead to an error message. // In other environment (e.g. MSVC on Windows), String::Format() may // simply ignore a bad format spec, so this assertion is run on // Linux only. - EXPECT_STREQ("", - String::Format("%").c_str()); + EXPECT_EQ("", + String::Format("%")); #endif } @@ -1915,15 +1617,16 @@ static void SetEnv(const char* name, const char* value) { // C++Builder's putenv only stores a pointer to its parameter; we have to // ensure that the string remains valid as long as it might be needed. // We use an std::map to do so. - static std::map added_env; + static std::map added_env; // Because putenv stores a pointer to the string buffer, we can't delete the // previous string (if present) until after it's replaced. - String *prev_env = NULL; + std::string *prev_env = NULL; if (added_env.find(name) != added_env.end()) { prev_env = added_env[name]; } - added_env[name] = new String((Message() << name << "=" << value).GetString()); + added_env[name] = new std::string( + (Message() << name << "=" << value).GetString()); // The standard signature of putenv accepts a 'char*' argument. Other // implementations, like C++Builder's, accept a 'const char*'. @@ -3568,8 +3271,8 @@ TEST_F(NoFatalFailureTest, MessageIsStreamable) { // Tests EqFailure(), used for implementing *EQ* assertions. TEST(AssertionTest, EqFailure) { - const String foo_val("5"), bar_val("6"); - const String msg1( + const std::string foo_val("5"), bar_val("6"); + const std::string msg1( EqFailure("foo", "bar", foo_val, bar_val, false) .failure_message()); EXPECT_STREQ( @@ -3579,7 +3282,7 @@ TEST(AssertionTest, EqFailure) { "Which is: 5", msg1.c_str()); - const String msg2( + const std::string msg2( EqFailure("foo", "6", foo_val, bar_val, false) .failure_message()); EXPECT_STREQ( @@ -3588,7 +3291,7 @@ TEST(AssertionTest, EqFailure) { "Which is: 5", msg2.c_str()); - const String msg3( + const std::string msg3( EqFailure("5", "bar", foo_val, bar_val, false) .failure_message()); EXPECT_STREQ( @@ -3597,16 +3300,16 @@ TEST(AssertionTest, EqFailure) { "Expected: 5", msg3.c_str()); - const String msg4( + const std::string msg4( EqFailure("5", "6", foo_val, bar_val, false).failure_message()); EXPECT_STREQ( "Value of: 6\n" "Expected: 5", msg4.c_str()); - const String msg5( + const std::string msg5( EqFailure("foo", "bar", - String("\"x\""), String("\"y\""), + std::string("\"x\""), std::string("\"y\""), true).failure_message()); EXPECT_STREQ( "Value of: bar\n" @@ -3618,7 +3321,7 @@ TEST(AssertionTest, EqFailure) { // Tests AppendUserMessage(), used for implementing the *EQ* macros. TEST(AssertionTest, AppendUserMessage) { - const String foo("foo"); + const std::string foo("foo"); Message msg; EXPECT_STREQ("foo", @@ -4199,7 +3902,7 @@ TEST(AssertionSyntaxTest, WorksWithSwitch) { #if GTEST_HAS_EXCEPTIONS void ThrowAString() { - throw "String"; + throw "std::string"; } // Test that the exception assertion macros compile and work with const @@ -5619,7 +5322,7 @@ class InitGoogleTestTest : public Test { internal::ParseGoogleTestFlagsOnly(&argc1, const_cast(argv1)); #if GTEST_HAS_STREAM_REDIRECTION - const String captured_stdout = GetCapturedStdout(); + const std::string captured_stdout = GetCapturedStdout(); #endif // Verifies the flag values. @@ -6891,7 +6594,7 @@ TEST(TestEventListenersTest, Append) { // order. class SequenceTestingListener : public EmptyTestEventListener { public: - SequenceTestingListener(std::vector* vector, const char* id) + SequenceTestingListener(std::vector* vector, const char* id) : vector_(vector), id_(id) {} protected: @@ -6914,20 +6617,20 @@ class SequenceTestingListener : public EmptyTestEventListener { } private: - String GetEventDescription(const char* method) { + std::string GetEventDescription(const char* method) { Message message; message << id_ << "." << method; return message.GetString(); } - std::vector* vector_; + std::vector* vector_; const char* const id_; GTEST_DISALLOW_COPY_AND_ASSIGN_(SequenceTestingListener); }; TEST(EventListenerTest, AppendKeepsOrder) { - std::vector vec; + std::vector vec; TestEventListeners listeners; listeners.Append(new SequenceTestingListener(&vec, "1st")); listeners.Append(new SequenceTestingListener(&vec, "2nd")); @@ -7313,7 +7016,7 @@ TEST(GTestReferenceToConstTest, Works) { TestGTestReferenceToConst(); TestGTestReferenceToConst(); TestGTestReferenceToConst(); - TestGTestReferenceToConst(); + TestGTestReferenceToConst(); } // Tests that ImplicitlyConvertible::value is a compile-time constant. -- cgit v1.2.3 From cc1fdb58caf8d5ac9b858f615d3c42267fc5e258 Mon Sep 17 00:00:00 2001 From: kosak Date: Fri, 22 Feb 2013 20:10:40 +0000 Subject: Removes testing::internal::String::Format(), which causes problems as it truncates the result at 4096 chars. Also update an obsolete link in comment. --- test/gtest_unittest.cc | 74 ++++++++++++++------------------------------------ 1 file changed, 20 insertions(+), 54 deletions(-) (limited to 'test') diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index f4f30431..4e9564f5 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -454,45 +454,41 @@ TEST(NullLiteralTest, IsFalseForNonNullLiterals) { // Tests that the NUL character L'\0' is encoded correctly. TEST(CodePointToUtf8Test, CanEncodeNul) { - char buffer[32]; - EXPECT_STREQ("", CodePointToUtf8(L'\0', buffer)); + EXPECT_EQ("", CodePointToUtf8(L'\0')); } // Tests that ASCII characters are encoded correctly. TEST(CodePointToUtf8Test, CanEncodeAscii) { - char buffer[32]; - EXPECT_STREQ("a", CodePointToUtf8(L'a', buffer)); - EXPECT_STREQ("Z", CodePointToUtf8(L'Z', buffer)); - EXPECT_STREQ("&", CodePointToUtf8(L'&', buffer)); - EXPECT_STREQ("\x7F", CodePointToUtf8(L'\x7F', buffer)); + EXPECT_EQ("a", CodePointToUtf8(L'a')); + EXPECT_EQ("Z", CodePointToUtf8(L'Z')); + EXPECT_EQ("&", CodePointToUtf8(L'&')); + EXPECT_EQ("\x7F", CodePointToUtf8(L'\x7F')); } // Tests that Unicode code-points that have 8 to 11 bits are encoded // as 110xxxxx 10xxxxxx. TEST(CodePointToUtf8Test, CanEncode8To11Bits) { - char buffer[32]; // 000 1101 0011 => 110-00011 10-010011 - EXPECT_STREQ("\xC3\x93", CodePointToUtf8(L'\xD3', buffer)); + EXPECT_EQ("\xC3\x93", CodePointToUtf8(L'\xD3')); // 101 0111 0110 => 110-10101 10-110110 // Some compilers (e.g., GCC on MinGW) cannot handle non-ASCII codepoints // in wide strings and wide chars. In order to accomodate them, we have to // introduce such character constants as integers. - EXPECT_STREQ("\xD5\xB6", - CodePointToUtf8(static_cast(0x576), buffer)); + EXPECT_EQ("\xD5\xB6", + CodePointToUtf8(static_cast(0x576))); } // Tests that Unicode code-points that have 12 to 16 bits are encoded // as 1110xxxx 10xxxxxx 10xxxxxx. TEST(CodePointToUtf8Test, CanEncode12To16Bits) { - char buffer[32]; // 0000 1000 1101 0011 => 1110-0000 10-100011 10-010011 - EXPECT_STREQ("\xE0\xA3\x93", - CodePointToUtf8(static_cast(0x8D3), buffer)); + EXPECT_EQ("\xE0\xA3\x93", + CodePointToUtf8(static_cast(0x8D3))); // 1100 0111 0100 1101 => 1110-1100 10-011101 10-001101 - EXPECT_STREQ("\xEC\x9D\x8D", - CodePointToUtf8(static_cast(0xC74D), buffer)); + EXPECT_EQ("\xEC\x9D\x8D", + CodePointToUtf8(static_cast(0xC74D))); } #if !GTEST_WIDE_STRING_USES_UTF16_ @@ -503,22 +499,19 @@ TEST(CodePointToUtf8Test, CanEncode12To16Bits) { // Tests that Unicode code-points that have 17 to 21 bits are encoded // as 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx. TEST(CodePointToUtf8Test, CanEncode17To21Bits) { - char buffer[32]; // 0 0001 0000 1000 1101 0011 => 11110-000 10-010000 10-100011 10-010011 - EXPECT_STREQ("\xF0\x90\xA3\x93", CodePointToUtf8(L'\x108D3', buffer)); + EXPECT_EQ("\xF0\x90\xA3\x93", CodePointToUtf8(L'\x108D3')); // 0 0001 0000 0100 0000 0000 => 11110-000 10-010000 10-010000 10-000000 - EXPECT_STREQ("\xF0\x90\x90\x80", CodePointToUtf8(L'\x10400', buffer)); + EXPECT_EQ("\xF0\x90\x90\x80", CodePointToUtf8(L'\x10400')); // 1 0000 1000 0110 0011 0100 => 11110-100 10-001000 10-011000 10-110100 - EXPECT_STREQ("\xF4\x88\x98\xB4", CodePointToUtf8(L'\x108634', buffer)); + EXPECT_EQ("\xF4\x88\x98\xB4", CodePointToUtf8(L'\x108634')); } // Tests that encoding an invalid code-point generates the expected result. TEST(CodePointToUtf8Test, CanEncodeInvalidCodePoint) { - char buffer[32]; - EXPECT_STREQ("(Invalid Unicode 0x1234ABCD)", - CodePointToUtf8(L'\x1234ABCD', buffer)); + EXPECT_EQ("(Invalid Unicode 0x1234ABCD)", CodePointToUtf8(L'\x1234ABCD')); } #endif // !GTEST_WIDE_STRING_USES_UTF16_ @@ -960,33 +953,6 @@ TEST(StringTest, CaseInsensitiveWideCStringEquals) { EXPECT_TRUE(String::CaseInsensitiveWideCStringEquals(L"FOOBAR", L"foobar")); } -// Tests that String::Format() works. -TEST(StringTest, FormatWorks) { - // Normal case: the format spec is valid, the arguments match the - // spec, and the result is < 4095 characters. - EXPECT_STREQ("Hello, 42", String::Format("%s, %d", "Hello", 42).c_str()); - - // Edge case: the result is 4095 characters. - char buffer[4096]; - const size_t kSize = sizeof(buffer); - memset(buffer, 'a', kSize - 1); - buffer[kSize - 1] = '\0'; - EXPECT_EQ(buffer, String::Format("%s", buffer)); - - // The result needs to be 4096 characters, exceeding Format()'s limit. - EXPECT_EQ("", - String::Format("x%s", buffer)); - -#if GTEST_OS_LINUX && !GTEST_OS_LINUX_ANDROID - // On Linux, invalid format spec should lead to an error message. - // In other environment (e.g. MSVC on Windows), String::Format() may - // simply ignore a bad format spec, so this assertion is run on - // Linux only. - EXPECT_EQ("", - String::Format("%")); -#endif -} - #if GTEST_OS_WINDOWS // Tests String::ShowWideCString(). @@ -3731,10 +3697,10 @@ TEST(HRESULTAssertionTest, EXPECT_HRESULT_FAILED) { EXPECT_NONFATAL_FAILURE(EXPECT_HRESULT_FAILED(OkHRESULTSuccess()), "Expected: (OkHRESULTSuccess()) fails.\n" - " Actual: 0x00000000"); + " Actual: 0x0"); EXPECT_NONFATAL_FAILURE(EXPECT_HRESULT_FAILED(FalseHRESULTSuccess()), "Expected: (FalseHRESULTSuccess()) fails.\n" - " Actual: 0x00000001"); + " Actual: 0x1"); } TEST(HRESULTAssertionTest, ASSERT_HRESULT_FAILED) { @@ -3745,12 +3711,12 @@ TEST(HRESULTAssertionTest, ASSERT_HRESULT_FAILED) { // ICE's in C++Builder 2007 and 2009. EXPECT_FATAL_FAILURE(ASSERT_HRESULT_FAILED(OkHRESULTSuccess()), "Expected: (OkHRESULTSuccess()) fails.\n" - " Actual: 0x00000000"); + " Actual: 0x0"); # endif EXPECT_FATAL_FAILURE(ASSERT_HRESULT_FAILED(FalseHRESULTSuccess()), "Expected: (FalseHRESULTSuccess()) fails.\n" - " Actual: 0x00000001"); + " Actual: 0x1"); } // Tests that streaming to the HRESULT macros works. -- cgit v1.2.3 From ba072ccca41212e3ac3ac1eca3381d226187c0d1 Mon Sep 17 00:00:00 2001 From: kosak Date: Fri, 22 Feb 2013 20:25:42 +0000 Subject: Fixes gUnit streaming output format. --- test/gtest_unittest.cc | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) (limited to 'test') diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index 4e9564f5..f594a447 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -79,6 +79,81 @@ TEST(CommandLineFlagsTest, CanBeAccessedInCodeOnceGTestHIsIncluded) { namespace testing { namespace internal { +#if GTEST_CAN_STREAM_RESULTS_ + +class StreamingListenerTest : public Test { + public: + class FakeSocketWriter : public StreamingListener::AbstractSocketWriter { + public: + // Sends a string to the socket. + virtual void Send(const string& message) { output_ += message; } + + string output_; + }; + + StreamingListenerTest() + : fake_sock_writer_(new FakeSocketWriter), + streamer_(fake_sock_writer_), + test_info_obj_("FooTest", "Bar", NULL, NULL, 0, NULL) {} + + protected: + string* output() { return &(fake_sock_writer_->output_); } + + FakeSocketWriter* const fake_sock_writer_; + StreamingListener streamer_; + UnitTest unit_test_; + TestInfo test_info_obj_; // The name test_info_ was taken by testing::Test. +}; + +TEST_F(StreamingListenerTest, OnTestProgramEnd) { + *output() = ""; + streamer_.OnTestProgramEnd(unit_test_); + EXPECT_EQ("event=TestProgramEnd&passed=1\n", *output()); +} + +TEST_F(StreamingListenerTest, OnTestIterationEnd) { + *output() = ""; + streamer_.OnTestIterationEnd(unit_test_, 42); + EXPECT_EQ("event=TestIterationEnd&passed=1&elapsed_time=0ms\n", *output()); +} + +TEST_F(StreamingListenerTest, OnTestCaseStart) { + *output() = ""; + streamer_.OnTestCaseStart(TestCase("FooTest", "Bar", NULL, NULL)); + EXPECT_EQ("event=TestCaseStart&name=FooTest\n", *output()); +} + +TEST_F(StreamingListenerTest, OnTestCaseEnd) { + *output() = ""; + streamer_.OnTestCaseEnd(TestCase("FooTest", "Bar", NULL, NULL)); + EXPECT_EQ("event=TestCaseEnd&passed=1&elapsed_time=0ms\n", *output()); +} + +TEST_F(StreamingListenerTest, OnTestStart) { + *output() = ""; + streamer_.OnTestStart(test_info_obj_); + EXPECT_EQ("event=TestStart&name=Bar\n", *output()); +} + +TEST_F(StreamingListenerTest, OnTestEnd) { + *output() = ""; + streamer_.OnTestEnd(test_info_obj_); + EXPECT_EQ("event=TestEnd&passed=1&elapsed_time=0ms\n", *output()); +} + +TEST_F(StreamingListenerTest, OnTestPartResult) { + *output() = ""; + streamer_.OnTestPartResult(TestPartResult( + TestPartResult::kFatalFailure, "foo.cc", 42, "failed=\n&%")); + + // Meta characters in the failure message should be properly escaped. + EXPECT_EQ( + "event=TestPartResult&file=foo.cc&line=42&message=failed%3D%0A%26%25\n", + *output()); +} + +#endif // GTEST_CAN_STREAM_RESULTS_ + // Provides access to otherwise private parts of the TestEventListeners class // that are needed to test it. class TestEventListenersAccessor { -- cgit v1.2.3 From fc01f532a622a7d460a4eff816c56c0e501f20f7 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Thu, 28 Feb 2013 23:52:42 +0000 Subject: Fixes unused function warning on Mac, and fixes compatibility with newer GCC. --- test/gtest-death-test_test.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'test') diff --git a/test/gtest-death-test_test.cc b/test/gtest-death-test_test.cc index e42c0136..e857bc8f 100644 --- a/test/gtest-death-test_test.cc +++ b/test/gtest-death-test_test.cc @@ -465,6 +465,8 @@ TEST_F(TestForDeathTest, MixedStyles) { EXPECT_DEATH(_exit(1), ""); } +# if GTEST_HAS_CLONE && GTEST_HAS_PTHREAD + namespace { bool pthread_flag; @@ -475,8 +477,6 @@ void SetPthreadFlag() { } // namespace -# if GTEST_HAS_CLONE && GTEST_HAS_PTHREAD - TEST_F(TestForDeathTest, DoesNotExecuteAtforkHooks) { if (!testing::GTEST_FLAG(death_test_use_fork)) { testing::GTEST_FLAG(death_test_style) = "threadsafe"; -- cgit v1.2.3 From 6b7a167dca7a9007d14fc95a07f4f6e07fec3162 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Mon, 11 Mar 2013 17:52:13 +0000 Subject: Supports colored output on term type screen-256color. Proposed as a one-line patch by Tom Jakubowski (tom@crystae.net); finished by Zhanyong Wan. --- test/gtest_unittest.cc | 3 +++ 1 file changed, 3 insertions(+) (limited to 'test') diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index f594a447..769b75c3 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -6429,6 +6429,9 @@ TEST(ColoredOutputTest, UsesColorsWhenTermSupportsColors) { SetEnv("TERM", "screen"); // TERM supports colors. EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY. + SetEnv("TERM", "screen-256color"); // TERM supports colors. + EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY. + SetEnv("TERM", "linux"); // TERM supports colors. EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY. -- cgit v1.2.3 From 1edbcbad73e0c711d5aa0f165bad5e9518894375 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Tue, 12 Mar 2013 21:17:22 +0000 Subject: Prints a useful message when GetParam() is called in a non-parameterized test. --- test/gtest-param-test_test.cc | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'test') diff --git a/test/gtest-param-test_test.cc b/test/gtest-param-test_test.cc index 7b6f7e24..f60cb8a5 100644 --- a/test/gtest-param-test_test.cc +++ b/test/gtest-param-test_test.cc @@ -865,6 +865,13 @@ TEST_P(ParameterizedDerivedTest, SeesSequence) { EXPECT_EQ(GetParam(), global_count_++); } +class ParameterizedDeathTest : public ::testing::TestWithParam { }; + +TEST_F(ParameterizedDeathTest, GetParamDiesFromTestF) { + EXPECT_DEATH_IF_SUPPORTED(GetParam(), + ".* value-parameterized test .*"); +} + INSTANTIATE_TEST_CASE_P(RangeZeroToFive, ParameterizedDerivedTest, Range(0, 5)); #endif // GTEST_HAS_PARAM_TEST -- cgit v1.2.3 From 5f18b68bfc96e69f8b1e5b7b5449f4890c1a2016 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Thu, 4 Apr 2013 22:44:57 +0000 Subject: Fixes some compatibility issues with STLport. --- test/gtest-printers_test.cc | 13 +++++++++---- test/gtest_unittest.cc | 2 +- 2 files changed, 10 insertions(+), 5 deletions(-) (limited to 'test') diff --git a/test/gtest-printers_test.cc b/test/gtest-printers_test.cc index 45610f8f..c2beca7d 100644 --- a/test/gtest-printers_test.cc +++ b/test/gtest-printers_test.cc @@ -214,10 +214,15 @@ using ::std::tr1::make_tuple; using ::std::tr1::tuple; #endif -#if _MSC_VER -// MSVC defines the following classes in the ::stdext namespace while -// gcc defines them in the :: namespace. Note that they are not part -// of the C++ standard. +// The hash_* classes are not part of the C++ standard. STLport +// defines them in namespace std. MSVC defines them in ::stdext. GCC +// defines them in ::. +#ifdef _STLP_HASH_MAP // We got from STLport. +using ::std::hash_map; +using ::std::hash_set; +using ::std::hash_multimap; +using ::std::hash_multiset; +#elif _MSC_VER using ::stdext::hash_map; using ::stdext::hash_set; using ::stdext::hash_multimap; diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index 769b75c3..09ee8989 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -4518,7 +4518,7 @@ TEST(EqAssertionTest, StdString) { // Compares a const char* to an std::string that has different // content EXPECT_NONFATAL_FAILURE(EXPECT_EQ("Test", ::std::string("test")), - "::std::string(\"test\")"); + "\"test\""); // Compares an std::string to a char* that has different content. char* const p1 = const_cast("foo"); -- cgit v1.2.3 From f5fa71f728ce77c5d5c1a940a9bd8bb1d64c9f78 Mon Sep 17 00:00:00 2001 From: vladlosev Date: Fri, 5 Apr 2013 20:50:46 +0000 Subject: Implements support for calling Test::RecordProperty() outside of a test. --- test/gtest_unittest.cc | 234 +++++++++++++++++++++++++++++-------- test/gtest_xml_output_unittest.py | 4 +- test/gtest_xml_output_unittest_.cc | 10 +- test/gtest_xml_test_utils.py | 4 +- 4 files changed, 199 insertions(+), 53 deletions(-) (limited to 'test') diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index 09ee8989..5aec883b 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -180,6 +180,18 @@ class TestEventListenersAccessor { } }; +class UnitTestRecordPropertyTestHelper : public Test { + protected: + UnitTestRecordPropertyTestHelper() {} + + // Forwards to UnitTest::RecordProperty() to bypass access controls. + void UnitTestRecordProperty(const char* key, const std::string& value) { + unit_test_.RecordProperty(key, value); + } + + UnitTest unit_test_; +}; + } // namespace internal } // namespace testing @@ -188,6 +200,7 @@ using testing::AssertionResult; using testing::AssertionSuccess; using testing::DoubleLE; using testing::EmptyTestEventListener; +using testing::Environment; using testing::FloatLE; using testing::GTEST_FLAG(also_run_disabled_tests); using testing::GTEST_FLAG(break_on_failure); @@ -213,6 +226,7 @@ using testing::StaticAssertTypeEq; using testing::Test; using testing::TestCase; using testing::TestEventListeners; +using testing::TestInfo; using testing::TestPartResult; using testing::TestPartResultArray; using testing::TestProperty; @@ -1447,7 +1461,7 @@ TEST(TestResultPropertyTest, NoPropertiesFoundWhenNoneAreAdded) { TEST(TestResultPropertyTest, OnePropertyFoundWhenAdded) { TestResult test_result; TestProperty property("key_1", "1"); - TestResultAccessor::RecordProperty(&test_result, property); + TestResultAccessor::RecordProperty(&test_result, "testcase", property); ASSERT_EQ(1, test_result.test_property_count()); const TestProperty& actual_property = test_result.GetTestProperty(0); EXPECT_STREQ("key_1", actual_property.key()); @@ -1459,8 +1473,8 @@ TEST(TestResultPropertyTest, MultiplePropertiesFoundWhenAdded) { TestResult test_result; TestProperty property_1("key_1", "1"); TestProperty property_2("key_2", "2"); - TestResultAccessor::RecordProperty(&test_result, property_1); - TestResultAccessor::RecordProperty(&test_result, property_2); + TestResultAccessor::RecordProperty(&test_result, "testcase", property_1); + TestResultAccessor::RecordProperty(&test_result, "testcase", property_2); ASSERT_EQ(2, test_result.test_property_count()); const TestProperty& actual_property_1 = test_result.GetTestProperty(0); EXPECT_STREQ("key_1", actual_property_1.key()); @@ -1478,10 +1492,10 @@ TEST(TestResultPropertyTest, OverridesValuesForDuplicateKeys) { TestProperty property_2_1("key_2", "2"); TestProperty property_1_2("key_1", "12"); TestProperty property_2_2("key_2", "22"); - TestResultAccessor::RecordProperty(&test_result, property_1_1); - TestResultAccessor::RecordProperty(&test_result, property_2_1); - TestResultAccessor::RecordProperty(&test_result, property_1_2); - TestResultAccessor::RecordProperty(&test_result, property_2_2); + TestResultAccessor::RecordProperty(&test_result, "testcase", property_1_1); + TestResultAccessor::RecordProperty(&test_result, "testcase", property_2_1); + TestResultAccessor::RecordProperty(&test_result, "testcase", property_1_2); + TestResultAccessor::RecordProperty(&test_result, "testcase", property_2_2); ASSERT_EQ(2, test_result.test_property_count()); const TestProperty& actual_property_1 = test_result.GetTestProperty(0); @@ -1494,14 +1508,14 @@ TEST(TestResultPropertyTest, OverridesValuesForDuplicateKeys) { } // Tests TestResult::GetTestProperty(). -TEST(TestResultPropertyDeathTest, GetTestProperty) { +TEST(TestResultPropertyTest, GetTestProperty) { TestResult test_result; TestProperty property_1("key_1", "1"); TestProperty property_2("key_2", "2"); TestProperty property_3("key_3", "3"); - TestResultAccessor::RecordProperty(&test_result, property_1); - TestResultAccessor::RecordProperty(&test_result, property_2); - TestResultAccessor::RecordProperty(&test_result, property_3); + TestResultAccessor::RecordProperty(&test_result, "testcase", property_1); + TestResultAccessor::RecordProperty(&test_result, "testcase", property_2); + TestResultAccessor::RecordProperty(&test_result, "testcase", property_3); const TestProperty& fetched_property_1 = test_result.GetTestProperty(0); const TestProperty& fetched_property_2 = test_result.GetTestProperty(1); @@ -1520,42 +1534,6 @@ TEST(TestResultPropertyDeathTest, GetTestProperty) { EXPECT_DEATH_IF_SUPPORTED(test_result.GetTestProperty(-1), ""); } -// When a property using a reserved key is supplied to this function, it tests -// that a non-fatal failure is added, a fatal failure is not added, and that the -// property is not recorded. -void ExpectNonFatalFailureRecordingPropertyWithReservedKey(const char* key) { - TestResult test_result; - TestProperty property(key, "1"); - EXPECT_NONFATAL_FAILURE( - TestResultAccessor::RecordProperty(&test_result, property), - "Reserved key"); - ASSERT_EQ(0, test_result.test_property_count()) << "Not recorded"; -} - -// Attempting to recording a property with the Reserved literal "name" -// should add a non-fatal failure and the property should not be recorded. -TEST(TestResultPropertyTest, AddFailureWhenUsingReservedKeyCalledName) { - ExpectNonFatalFailureRecordingPropertyWithReservedKey("name"); -} - -// Attempting to recording a property with the Reserved literal "status" -// should add a non-fatal failure and the property should not be recorded. -TEST(TestResultPropertyTest, AddFailureWhenUsingReservedKeyCalledStatus) { - ExpectNonFatalFailureRecordingPropertyWithReservedKey("status"); -} - -// Attempting to recording a property with the Reserved literal "time" -// should add a non-fatal failure and the property should not be recorded. -TEST(TestResultPropertyTest, AddFailureWhenUsingReservedKeyCalledTime) { - ExpectNonFatalFailureRecordingPropertyWithReservedKey("time"); -} - -// Attempting to recording a property with the Reserved literal "classname" -// should add a non-fatal failure and the property should not be recorded. -TEST(TestResultPropertyTest, AddFailureWhenUsingReservedKeyCalledClassname) { - ExpectNonFatalFailureRecordingPropertyWithReservedKey("classname"); -} - // Tests that GTestFlagSaver works on Windows and Mac. class GTestFlagSaverTest : public Test { @@ -1961,6 +1939,168 @@ TEST(UnitTestTest, ReturnsPlausibleTimestamp) { EXPECT_LE(UnitTest::GetInstance()->start_timestamp(), GetTimeInMillis()); } +// When a property using a reserved key is supplied to this function, it +// tests that a non-fatal failure is added, a fatal failure is not added, +// and that the property is not recorded. +void ExpectNonFatalFailureRecordingPropertyWithReservedKey( + const TestResult& test_result, const char* key) { + EXPECT_NONFATAL_FAILURE(Test::RecordProperty(key, "1"), "Reserved key"); + ASSERT_EQ(0, test_result.test_property_count()) << "Property for key '" << key + << "' recorded unexpectedly."; +} + +void ExpectNonFatalFailureRecordingPropertyWithReservedKeyForCurrentTest( + const char* key) { + const TestInfo* test_info = UnitTest::GetInstance()->current_test_info(); + ASSERT_TRUE(test_info != NULL); + ExpectNonFatalFailureRecordingPropertyWithReservedKey(*test_info->result(), + key); +} + +void ExpectNonFatalFailureRecordingPropertyWithReservedKeyForCurrentTestCase( + const char* key) { + const TestCase* test_case = UnitTest::GetInstance()->current_test_case(); + ASSERT_TRUE(test_case != NULL); + ExpectNonFatalFailureRecordingPropertyWithReservedKey( + test_case->ad_hoc_test_result(), key); +} + +void ExpectNonFatalFailureRecordingPropertyWithReservedKeyOutsideOfTestCase( + const char* key) { + ExpectNonFatalFailureRecordingPropertyWithReservedKey( + UnitTest::GetInstance()->ad_hoc_test_result(), key); +} + +// Tests that property recording functions in UnitTest outside of tests +// functions correcly. Creating a separate instance of UnitTest ensures it +// is in a state similar to the UnitTest's singleton's between tests. +class UnitTestRecordPropertyTest : + public testing::internal::UnitTestRecordPropertyTestHelper { + public: + static void SetUpTestCase() { + ExpectNonFatalFailureRecordingPropertyWithReservedKeyForCurrentTestCase( + "disabled"); + ExpectNonFatalFailureRecordingPropertyWithReservedKeyForCurrentTestCase( + "errors"); + ExpectNonFatalFailureRecordingPropertyWithReservedKeyForCurrentTestCase( + "failures"); + ExpectNonFatalFailureRecordingPropertyWithReservedKeyForCurrentTestCase( + "name"); + ExpectNonFatalFailureRecordingPropertyWithReservedKeyForCurrentTestCase( + "tests"); + ExpectNonFatalFailureRecordingPropertyWithReservedKeyForCurrentTestCase( + "time"); + + Test::RecordProperty("test_case_key_1", "1"); + const TestCase* test_case = UnitTest::GetInstance()->current_test_case(); + ASSERT_TRUE(test_case != NULL); + + ASSERT_EQ(1, test_case->ad_hoc_test_result().test_property_count()); + EXPECT_STREQ("test_case_key_1", + test_case->ad_hoc_test_result().GetTestProperty(0).key()); + EXPECT_STREQ("1", + test_case->ad_hoc_test_result().GetTestProperty(0).value()); + } +}; + +// Tests TestResult has the expected property when added. +TEST_F(UnitTestRecordPropertyTest, OnePropertyFoundWhenAdded) { + UnitTestRecordProperty("key_1", "1"); + + ASSERT_EQ(1, unit_test_.ad_hoc_test_result().test_property_count()); + + EXPECT_STREQ("key_1", + unit_test_.ad_hoc_test_result().GetTestProperty(0).key()); + EXPECT_STREQ("1", + unit_test_.ad_hoc_test_result().GetTestProperty(0).value()); +} + +// Tests TestResult has multiple properties when added. +TEST_F(UnitTestRecordPropertyTest, MultiplePropertiesFoundWhenAdded) { + UnitTestRecordProperty("key_1", "1"); + UnitTestRecordProperty("key_2", "2"); + + ASSERT_EQ(2, unit_test_.ad_hoc_test_result().test_property_count()); + + EXPECT_STREQ("key_1", + unit_test_.ad_hoc_test_result().GetTestProperty(0).key()); + EXPECT_STREQ("1", unit_test_.ad_hoc_test_result().GetTestProperty(0).value()); + + EXPECT_STREQ("key_2", + unit_test_.ad_hoc_test_result().GetTestProperty(1).key()); + EXPECT_STREQ("2", unit_test_.ad_hoc_test_result().GetTestProperty(1).value()); +} + +// Tests TestResult::RecordProperty() overrides values for duplicate keys. +TEST_F(UnitTestRecordPropertyTest, OverridesValuesForDuplicateKeys) { + UnitTestRecordProperty("key_1", "1"); + UnitTestRecordProperty("key_2", "2"); + UnitTestRecordProperty("key_1", "12"); + UnitTestRecordProperty("key_2", "22"); + + ASSERT_EQ(2, unit_test_.ad_hoc_test_result().test_property_count()); + + EXPECT_STREQ("key_1", + unit_test_.ad_hoc_test_result().GetTestProperty(0).key()); + EXPECT_STREQ("12", + unit_test_.ad_hoc_test_result().GetTestProperty(0).value()); + + EXPECT_STREQ("key_2", + unit_test_.ad_hoc_test_result().GetTestProperty(1).key()); + EXPECT_STREQ("22", + unit_test_.ad_hoc_test_result().GetTestProperty(1).value()); +} + +TEST_F(UnitTestRecordPropertyTest, + AddFailureInsideTestsWhenUsingTestCaseReservedKeys) { + ExpectNonFatalFailureRecordingPropertyWithReservedKeyForCurrentTest( + "name"); + ExpectNonFatalFailureRecordingPropertyWithReservedKeyForCurrentTest( + "value_param"); + ExpectNonFatalFailureRecordingPropertyWithReservedKeyForCurrentTest( + "type_param"); + ExpectNonFatalFailureRecordingPropertyWithReservedKeyForCurrentTest( + "status"); + ExpectNonFatalFailureRecordingPropertyWithReservedKeyForCurrentTest( + "time"); + ExpectNonFatalFailureRecordingPropertyWithReservedKeyForCurrentTest( + "classname"); +} + +TEST_F(UnitTestRecordPropertyTest, + AddRecordWithReservedKeysGeneratesCorrectPropertyList) { + EXPECT_NONFATAL_FAILURE( + Test::RecordProperty("name", "1"), + "'classname', 'name', 'status', 'time', 'type_param', and 'value_param'" + " are reserved"); +} + +class UnitTestRecordPropertyTestEnvironment : public Environment { + public: + virtual void TearDown() { + ExpectNonFatalFailureRecordingPropertyWithReservedKeyOutsideOfTestCase( + "tests"); + ExpectNonFatalFailureRecordingPropertyWithReservedKeyOutsideOfTestCase( + "failures"); + ExpectNonFatalFailureRecordingPropertyWithReservedKeyOutsideOfTestCase( + "disabled"); + ExpectNonFatalFailureRecordingPropertyWithReservedKeyOutsideOfTestCase( + "errors"); + ExpectNonFatalFailureRecordingPropertyWithReservedKeyOutsideOfTestCase( + "name"); + ExpectNonFatalFailureRecordingPropertyWithReservedKeyOutsideOfTestCase( + "timestamp"); + ExpectNonFatalFailureRecordingPropertyWithReservedKeyOutsideOfTestCase( + "time"); + ExpectNonFatalFailureRecordingPropertyWithReservedKeyOutsideOfTestCase( + "random_seed"); + } +}; + +// This will test property recording outside of any test or test case. +static Environment* record_property_env = + AddGlobalTestEnvironment(new UnitTestRecordPropertyTestEnvironment); + // This group of tests is for predicate assertions (ASSERT_PRED*, etc) // of various arities. They do not attempt to be exhaustive. Rather, // view them as smoke tests that can be easily reviewed and verified. diff --git a/test/gtest_xml_output_unittest.py b/test/gtest_xml_output_unittest.py index 1bcd4187..3d794e6b 100755 --- a/test/gtest_xml_output_unittest.py +++ b/test/gtest_xml_output_unittest.py @@ -57,7 +57,7 @@ else: STACK_TRACE_TEMPLATE = '' EXPECTED_NON_EMPTY_XML = """ - + @@ -97,7 +97,7 @@ Invalid characters in brackets []%(stack)s]]> - + diff --git a/test/gtest_xml_output_unittest_.cc b/test/gtest_xml_output_unittest_.cc index bf0c871b..48b8771b 100644 --- a/test/gtest_xml_output_unittest_.cc +++ b/test/gtest_xml_output_unittest_.cc @@ -95,6 +95,9 @@ TEST(InvalidCharactersTest, InvalidCharactersInMessage) { } class PropertyRecordingTest : public Test { + public: + static void SetUpTestCase() { RecordProperty("SetUpTestCase", "yes"); } + static void TearDownTestCase() { RecordProperty("TearDownTestCase", "aye"); } }; TEST_F(PropertyRecordingTest, OneProperty) { @@ -120,12 +123,12 @@ TEST(NoFixtureTest, RecordProperty) { RecordProperty("key", "1"); } -void ExternalUtilityThatCallsRecordProperty(const char* key, int value) { +void ExternalUtilityThatCallsRecordProperty(const std::string& key, int value) { testing::Test::RecordProperty(key, value); } -void ExternalUtilityThatCallsRecordProperty(const char* key, - const char* value) { +void ExternalUtilityThatCallsRecordProperty(const std::string& key, + const std::string& value) { testing::Test::RecordProperty(key, value); } @@ -173,5 +176,6 @@ int main(int argc, char** argv) { TestEventListeners& listeners = UnitTest::GetInstance()->listeners(); delete listeners.Release(listeners.default_xml_generator()); } + testing::Test::RecordProperty("ad_hoc_property", "42"); return RUN_ALL_TESTS(); } diff --git a/test/gtest_xml_test_utils.py b/test/gtest_xml_test_utils.py index 0e5a1089..35458f88 100755 --- a/test/gtest_xml_test_utils.py +++ b/test/gtest_xml_test_utils.py @@ -80,7 +80,9 @@ class GTestXMLTestCase(gtest_test_utils.TestCase): actual_attributes = actual_node .attributes self.assertEquals( expected_attributes.length, actual_attributes.length, - 'attribute numbers differ in element ' + actual_node.tagName) + 'attribute numbers differ in element %s:\nExpected: %r\nActual: %r' % ( + actual_node.tagName, expected_attributes.keys(), + actual_attributes.keys())) for i in range(expected_attributes.length): expected_attr = expected_attributes.item(i) actual_attr = actual_attributes.get(expected_attr.name) -- cgit v1.2.3 From 0fac83390adaf4e80ddee5bc3747079be4234c27 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Wed, 10 Apr 2013 04:29:33 +0000 Subject: prints type/value parameters when listing tests --- test/gtest_list_tests_unittest.py | 92 +++++++++++++++++++++++++------------- test/gtest_list_tests_unittest_.cc | 78 ++++++++++++++++++++++++++++++-- 2 files changed, 136 insertions(+), 34 deletions(-) (limited to 'test') diff --git a/test/gtest_list_tests_unittest.py b/test/gtest_list_tests_unittest.py index ce8c3ef0..925b09d9 100755 --- a/test/gtest_list_tests_unittest.py +++ b/test/gtest_list_tests_unittest.py @@ -40,6 +40,7 @@ Google Test) the command line flags. __author__ = 'phanna@google.com (Patrick Hanna)' import gtest_test_utils +import re # Constants. @@ -52,38 +53,63 @@ EXE_PATH = gtest_test_utils.GetTestExecutablePath('gtest_list_tests_unittest_') # The expected output when running gtest_list_tests_unittest_ with # --gtest_list_tests -EXPECTED_OUTPUT_NO_FILTER = """FooDeathTest. +EXPECTED_OUTPUT_NO_FILTER_RE = re.compile(r"""FooDeathTest\. Test1 -Foo. +Foo\. Bar1 Bar2 DISABLED_Bar3 -Abc. +Abc\. Xyz Def -FooBar. +FooBar\. Baz -FooTest. +FooTest\. Test1 DISABLED_Test2 Test3 -""" +TypedTest/0\. # TypeParam = (VeryLo{245}|class VeryLo{239})\.\.\. + TestA + TestB +TypedTest/1\. # TypeParam = int\s*\* + TestA + TestB +TypedTest/2\. # TypeParam = .*MyArray + TestA + TestB +My/TypeParamTest/0\. # TypeParam = (VeryLo{245}|class VeryLo{239})\.\.\. + TestA + TestB +My/TypeParamTest/1\. # TypeParam = int\s*\* + TestA + TestB +My/TypeParamTest/2\. # TypeParam = .*MyArray + TestA + TestB +MyInstantiation/ValueParamTest\. + TestA/0 # GetParam\(\) = one line + TestA/1 # GetParam\(\) = two\\nlines + TestA/2 # GetParam\(\) = a very\\nlo{241}\.\.\. + TestB/0 # GetParam\(\) = one line + TestB/1 # GetParam\(\) = two\\nlines + TestB/2 # GetParam\(\) = a very\\nlo{241}\.\.\. +""") # The expected output when running gtest_list_tests_unittest_ with # --gtest_list_tests and --gtest_filter=Foo*. -EXPECTED_OUTPUT_FILTER_FOO = """FooDeathTest. +EXPECTED_OUTPUT_FILTER_FOO_RE = re.compile(r"""FooDeathTest\. Test1 -Foo. +Foo\. Bar1 Bar2 DISABLED_Bar3 -FooBar. +FooBar\. Baz -FooTest. +FooTest\. Test1 DISABLED_Test2 Test3 -""" +""") # Utilities. @@ -100,19 +126,18 @@ def Run(args): class GTestListTestsUnitTest(gtest_test_utils.TestCase): """Tests using the --gtest_list_tests flag to list all tests.""" - def RunAndVerify(self, flag_value, expected_output, other_flag): + def RunAndVerify(self, flag_value, expected_output_re, other_flag): """Runs gtest_list_tests_unittest_ and verifies that it prints the correct tests. Args: - flag_value: value of the --gtest_list_tests flag; - None if the flag should not be present. - - expected_output: the expected output after running command; - - other_flag: a different flag to be passed to command - along with gtest_list_tests; - None if the flag should not be present. + flag_value: value of the --gtest_list_tests flag; + None if the flag should not be present. + expected_output_re: regular expression that matches the expected + output after running command; + other_flag: a different flag to be passed to command + along with gtest_list_tests; + None if the flag should not be present. """ if flag_value is None: @@ -132,36 +157,41 @@ class GTestListTestsUnitTest(gtest_test_utils.TestCase): output = Run(args) - msg = ('when %s is %s, the output of "%s" is "%s".' % - (LIST_TESTS_FLAG, flag_expression, ' '.join(args), output)) - - if expected_output is not None: - self.assert_(output == expected_output, msg) + if expected_output_re: + self.assert_( + expected_output_re.match(output), + ('when %s is %s, the output of "%s" is "%s",\n' + 'which does not match regex "%s"' % + (LIST_TESTS_FLAG, flag_expression, ' '.join(args), output, + expected_output_re.pattern))) else: - self.assert_(output != EXPECTED_OUTPUT_NO_FILTER, msg) + self.assert_( + not EXPECTED_OUTPUT_NO_FILTER_RE.match(output), + ('when %s is %s, the output of "%s" is "%s"'% + (LIST_TESTS_FLAG, flag_expression, ' '.join(args), output))) def testDefaultBehavior(self): """Tests the behavior of the default mode.""" self.RunAndVerify(flag_value=None, - expected_output=None, + expected_output_re=None, other_flag=None) def testFlag(self): """Tests using the --gtest_list_tests flag.""" self.RunAndVerify(flag_value='0', - expected_output=None, + expected_output_re=None, other_flag=None) self.RunAndVerify(flag_value='1', - expected_output=EXPECTED_OUTPUT_NO_FILTER, + expected_output_re=EXPECTED_OUTPUT_NO_FILTER_RE, other_flag=None) def testOverrideNonFilterFlags(self): """Tests that --gtest_list_tests overrides the non-filter flags.""" self.RunAndVerify(flag_value='1', - expected_output=EXPECTED_OUTPUT_NO_FILTER, + expected_output_re=EXPECTED_OUTPUT_NO_FILTER_RE, other_flag='--gtest_break_on_failure') def testWithFilterFlags(self): @@ -169,7 +199,7 @@ class GTestListTestsUnitTest(gtest_test_utils.TestCase): --gtest_filter flag.""" self.RunAndVerify(flag_value='1', - expected_output=EXPECTED_OUTPUT_FILTER_FOO, + expected_output_re=EXPECTED_OUTPUT_FILTER_FOO_RE, other_flag='--gtest_filter=Foo*') diff --git a/test/gtest_list_tests_unittest_.cc b/test/gtest_list_tests_unittest_.cc index 2b1d0780..907c176b 100644 --- a/test/gtest_list_tests_unittest_.cc +++ b/test/gtest_list_tests_unittest_.cc @@ -40,8 +40,6 @@ #include "gtest/gtest.h" -namespace { - // Several different test cases and tests that will be listed. TEST(Foo, Bar1) { } @@ -76,7 +74,81 @@ TEST_F(FooTest, Test3) { TEST(FooDeathTest, Test1) { } -} // namespace +// A group of value-parameterized tests. + +class MyType { + public: + explicit MyType(const std::string& a_value) : value_(a_value) {} + + const std::string& value() const { return value_; } + + private: + std::string value_; +}; + +// Teaches Google Test how to print a MyType. +void PrintTo(const MyType& x, std::ostream* os) { + *os << x.value(); +} + +class ValueParamTest : public testing::TestWithParam { +}; + +TEST_P(ValueParamTest, TestA) { +} + +TEST_P(ValueParamTest, TestB) { +} + +INSTANTIATE_TEST_CASE_P( + MyInstantiation, ValueParamTest, + testing::Values(MyType("one line"), + MyType("two\nlines"), + MyType("a very\nloooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong line"))); // NOLINT + +// A group of typed tests. + +// A deliberately long type name for testing the line-truncating +// behavior when printing a type parameter. +class VeryLoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooogName { // NOLINT +}; + +template +class TypedTest : public testing::Test { +}; + +template +class MyArray { +}; + +typedef testing::Types > MyTypes; + +TYPED_TEST_CASE(TypedTest, MyTypes); + +TYPED_TEST(TypedTest, TestA) { +} + +TYPED_TEST(TypedTest, TestB) { +} + +// A group of type-parameterized tests. + +template +class TypeParamTest : public testing::Test { +}; + +TYPED_TEST_CASE_P(TypeParamTest); + +TYPED_TEST_P(TypeParamTest, TestA) { +} + +TYPED_TEST_P(TypeParamTest, TestB) { +} + +REGISTER_TYPED_TEST_CASE_P(TypeParamTest, TestA, TestB); + +INSTANTIATE_TYPED_TEST_CASE_P(My, TypeParamTest, MyTypes); int main(int argc, char **argv) { ::testing::InitGoogleTest(&argc, argv); -- cgit v1.2.3 From c506784b08473f3ba8f37d588fd08d8d3f948245 Mon Sep 17 00:00:00 2001 From: vladlosev Date: Thu, 25 Apr 2013 17:58:52 +0000 Subject: When --gtest_filter is specified, XML report now doesn't contain information about tests that are filtered out (issue 141). --- test/gtest_output_test_golden_lin.txt | 5 ----- test/gtest_xml_output_unittest.py | 35 +++++++++++++++++++++++++++++------ test/gtest_xml_test_utils.py | 8 +++++--- 3 files changed, 34 insertions(+), 14 deletions(-) (limited to 'test') diff --git a/test/gtest_output_test_golden_lin.txt b/test/gtest_output_test_golden_lin.txt index 0e26d63d..960eedce 100644 --- a/test/gtest_output_test_golden_lin.txt +++ b/test/gtest_output_test_golden_lin.txt @@ -699,8 +699,6 @@ Expected: (3) >= (a[i]), actual: 3 vs 6 [ FAILED ] LoggingTest.InterleavingLoggingAndAssertions 4 FAILED TESTS - YOU HAVE 1 DISABLED TEST - Note: Google Test filter = *DISABLED_* [==========] Running 1 test from 1 test case. [----------] Global test environment set-up. @@ -720,6 +718,3 @@ Note: This is test shard 2 of 2. [----------] Global test environment tear-down [==========] 1 test from 1 test case ran. [ PASSED ] 1 test. - - YOU HAVE 1 DISABLED TEST - diff --git a/test/gtest_xml_output_unittest.py b/test/gtest_xml_output_unittest.py index 3d794e6b..f605d4ee 100755 --- a/test/gtest_xml_output_unittest.py +++ b/test/gtest_xml_output_unittest.py @@ -44,6 +44,7 @@ import gtest_test_utils import gtest_xml_test_utils +GTEST_FILTER_FLAG = '--gtest_filter' GTEST_LIST_TESTS_FLAG = '--gtest_list_tests' GTEST_OUTPUT_FLAG = "--gtest_output" GTEST_DEFAULT_OUTPUT_FILE = "test_detail.xml" @@ -128,9 +129,18 @@ Invalid characters in brackets []%(stack)s]]> """ % {'stack': STACK_TRACE_TEMPLATE} +EXPECTED_FILTERED_TEST_XML = """ + + + + +""" EXPECTED_EMPTY_XML = """ - + """ GTEST_PROGRAM_PATH = gtest_test_utils.GetTestExecutablePath(GTEST_PROGRAM_NAME) @@ -169,7 +179,7 @@ class GTestXMLOutputUnitTest(gtest_xml_test_utils.GTestXMLTestCase): Runs a test program that generates an empty XML output, and checks if the timestamp attribute in the testsuites tag is valid. """ - actual = self._GetXmlOutput('gtest_no_test_unittest', 0) + actual = self._GetXmlOutput('gtest_no_test_unittest', [], 0) date_time_str = actual.documentElement.getAttributeNode('timestamp').value # datetime.strptime() is only available in Python 2.5+ so we have to # parse the expected datetime manually. @@ -239,7 +249,17 @@ class GTestXMLOutputUnitTest(gtest_xml_test_utils.GTestXMLTestCase): self.assert_(not os.path.isfile(xml_path)) - def _GetXmlOutput(self, gtest_prog_name, expected_exit_code): + def testFilteredTestXmlOutput(self): + """Verifies XML output when a filter is applied. + + Runs a test program that executes only some tests and verifies that + non-selected tests do not show up in the XML output. + """ + + self._TestXmlOutput(GTEST_PROGRAM_NAME, EXPECTED_FILTERED_TEST_XML, 0, + extra_args=['%s=SuccessfulTest.*' % GTEST_FILTER_FLAG]) + + def _GetXmlOutput(self, gtest_prog_name, extra_args, expected_exit_code): """ Returns the xml output generated by running the program gtest_prog_name. Furthermore, the program's exit code must be expected_exit_code. @@ -248,7 +268,8 @@ class GTestXMLOutputUnitTest(gtest_xml_test_utils.GTestXMLTestCase): gtest_prog_name + 'out.xml') gtest_prog_path = gtest_test_utils.GetTestExecutablePath(gtest_prog_name) - command = [gtest_prog_path, '%s=xml:%s' % (GTEST_OUTPUT_FLAG, xml_path)] + command = ([gtest_prog_path, '%s=xml:%s' % (GTEST_OUTPUT_FLAG, xml_path)] + + extra_args) p = gtest_test_utils.Subprocess(command) if p.terminated_by_signal: self.assert_(False, @@ -262,7 +283,8 @@ class GTestXMLOutputUnitTest(gtest_xml_test_utils.GTestXMLTestCase): actual = minidom.parse(xml_path) return actual - def _TestXmlOutput(self, gtest_prog_name, expected_xml, expected_exit_code): + def _TestXmlOutput(self, gtest_prog_name, expected_xml, + expected_exit_code, extra_args=None): """ Asserts that the XML document generated by running the program gtest_prog_name matches expected_xml, a string containing another @@ -270,7 +292,8 @@ class GTestXMLOutputUnitTest(gtest_xml_test_utils.GTestXMLTestCase): expected_exit_code. """ - actual = self._GetXmlOutput(gtest_prog_name, expected_exit_code) + actual = self._GetXmlOutput(gtest_prog_name, extra_args or [], + expected_exit_code) expected = minidom.parseString(expected_xml) self.NormalizeXml(actual.documentElement) self.AssertEquivalentNodes(expected.documentElement, diff --git a/test/gtest_xml_test_utils.py b/test/gtest_xml_test_utils.py index 35458f88..3d0c3b2c 100755 --- a/test/gtest_xml_test_utils.py +++ b/test/gtest_xml_test_utils.py @@ -90,9 +90,11 @@ class GTestXMLTestCase(gtest_test_utils.TestCase): actual_attr is not None, 'expected attribute %s not found in element %s' % (expected_attr.name, actual_node.tagName)) - self.assertEquals(expected_attr.value, actual_attr.value, - ' values of attribute %s in element %s differ' % - (expected_attr.name, actual_node.tagName)) + self.assertEquals( + expected_attr.value, actual_attr.value, + ' values of attribute %s in element %s differ: %s vs %s' % + (expected_attr.name, actual_node.tagName, + expected_attr.value, actual_attr.value)) expected_children = self._GetChildren(expected_node) actual_children = self._GetChildren(actual_node) -- cgit v1.2.3 From 48568d0688d6e330ecf2efadd9d1539c349f6167 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Tue, 18 Jun 2013 18:44:25 +0000 Subject: Fixes compatibility with C++11: (1 - 1) is no longer a NULL pointer constant. --- test/gtest_unittest.cc | 9 --------- 1 file changed, 9 deletions(-) (limited to 'test') diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index 5aec883b..0cab07d1 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -512,15 +512,6 @@ TEST(NullLiteralTest, IsTrueForNullLiterals) { EXPECT_TRUE(GTEST_IS_NULL_LITERAL_(0)); EXPECT_TRUE(GTEST_IS_NULL_LITERAL_(0U)); EXPECT_TRUE(GTEST_IS_NULL_LITERAL_(0L)); - -# ifndef __BORLANDC__ - - // Some compilers may fail to detect some null pointer literals; - // as long as users of the framework don't use such literals, this - // is harmless. - EXPECT_TRUE(GTEST_IS_NULL_LITERAL_(1 - 1)); - -# endif } // Tests that GTEST_IS_NULL_LITERAL_(x) is false when x is not a null -- cgit v1.2.3 From 81ddb8434f2b034f49d24b07c03c80a70d116404 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Mon, 8 Jul 2013 04:40:28 +0000 Subject: makes gtest-death-test_test.cc compile on platforms that don't support death tests; h/t to Steve Robbins for reporting the issue and suggesting the fix. --- test/gtest-death-test_test.cc | 41 +++++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 20 deletions(-) (limited to 'test') diff --git a/test/gtest-death-test_test.cc b/test/gtest-death-test_test.cc index e857bc8f..4f379963 100644 --- a/test/gtest-death-test_test.cc +++ b/test/gtest-death-test_test.cc @@ -1289,6 +1289,27 @@ TEST(ConditionalDeathMacrosTest, AssertDeatDoesNotReturnhIfUnsupported) { FuncWithAssert(&n); EXPECT_EQ(1, n); } + +TEST(InDeathTestChildDeathTest, ReportsDeathTestCorrectlyInFastStyle) { + testing::GTEST_FLAG(death_test_style) = "fast"; + EXPECT_FALSE(InDeathTestChild()); + EXPECT_DEATH({ + fprintf(stderr, InDeathTestChild() ? "Inside" : "Outside"); + fflush(stderr); + _exit(1); + }, "Inside"); +} + +TEST(InDeathTestChildDeathTest, ReportsDeathTestCorrectlyInThreadSafeStyle) { + testing::GTEST_FLAG(death_test_style) = "threadsafe"; + EXPECT_FALSE(InDeathTestChild()); + EXPECT_DEATH({ + fprintf(stderr, InDeathTestChild() ? "Inside" : "Outside"); + fflush(stderr); + _exit(1); + }, "Inside"); +} + #endif // GTEST_HAS_DEATH_TEST // Tests that the death test macros expand to code which may or may not @@ -1341,26 +1362,6 @@ TEST(ConditionalDeathMacrosSyntaxDeathTest, SwitchStatement) { #endif // _MSC_VER } -TEST(InDeathTestChildDeathTest, ReportsDeathTestCorrectlyInFastStyle) { - testing::GTEST_FLAG(death_test_style) = "fast"; - EXPECT_FALSE(InDeathTestChild()); - EXPECT_DEATH({ - fprintf(stderr, InDeathTestChild() ? "Inside" : "Outside"); - fflush(stderr); - _exit(1); - }, "Inside"); -} - -TEST(InDeathTestChildDeathTest, ReportsDeathTestCorrectlyInThreadSafeStyle) { - testing::GTEST_FLAG(death_test_style) = "threadsafe"; - EXPECT_FALSE(InDeathTestChild()); - EXPECT_DEATH({ - fprintf(stderr, InDeathTestChild() ? "Inside" : "Outside"); - fflush(stderr); - _exit(1); - }, "Inside"); -} - // Tests that a test case whose name ends with "DeathTest" works fine // on Windows. TEST(NotADeathTest, Test) { -- cgit v1.2.3 From c306ef2e14483dbf4f047a3e1ca3f86111b800ca Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Fri, 6 Sep 2013 22:50:25 +0000 Subject: supports a protocol for catching tests that prematurely exit --- test/gtest_break_on_failure_unittest.py | 24 ++---- test/gtest_catch_exceptions_test.py | 22 ++++- test/gtest_premature_exit_test.cc | 141 ++++++++++++++++++++++++++++++++ test/gtest_test_utils.py | 15 ++++ 4 files changed, 183 insertions(+), 19 deletions(-) create mode 100644 test/gtest_premature_exit_test.cc (limited to 'test') diff --git a/test/gtest_break_on_failure_unittest.py b/test/gtest_break_on_failure_unittest.py index c8191833..78f3e0f5 100755 --- a/test/gtest_break_on_failure_unittest.py +++ b/test/gtest_break_on_failure_unittest.py @@ -66,21 +66,15 @@ EXE_PATH = gtest_test_utils.GetTestExecutablePath( 'gtest_break_on_failure_unittest_') -# Utilities. - - -environ = os.environ.copy() - - -def SetEnvVar(env_var, value): - """Sets an environment variable to a given value; unsets it when the - given value is None. - """ - - if value is not None: - environ[env_var] = value - elif env_var in environ: - del environ[env_var] +environ = gtest_test_utils.environ +SetEnvVar = gtest_test_utils.SetEnvVar + +# Tests in this file run a Google-Test-based test program and expect it +# to terminate prematurely. Therefore they are incompatible with +# the premature-exit-file protocol by design. Unset the +# premature-exit filepath to prevent Google Test from creating +# the file. +SetEnvVar(gtest_test_utils.PREMATURE_EXIT_FILE_ENV_VAR, None) def Run(command): diff --git a/test/gtest_catch_exceptions_test.py b/test/gtest_catch_exceptions_test.py index d7ef10eb..e6fc22fd 100755 --- a/test/gtest_catch_exceptions_test.py +++ b/test/gtest_catch_exceptions_test.py @@ -57,14 +57,27 @@ EX_EXE_PATH = gtest_test_utils.GetTestExecutablePath( EXE_PATH = gtest_test_utils.GetTestExecutablePath( 'gtest_catch_exceptions_no_ex_test_') -TEST_LIST = gtest_test_utils.Subprocess([EXE_PATH, LIST_TESTS_FLAG]).output +environ = gtest_test_utils.environ +SetEnvVar = gtest_test_utils.SetEnvVar + +# Tests in this file run a Google-Test-based test program and expect it +# to terminate prematurely. Therefore they are incompatible with +# the premature-exit-file protocol by design. Unset the +# premature-exit filepath to prevent Google Test from creating +# the file. +SetEnvVar(gtest_test_utils.PREMATURE_EXIT_FILE_ENV_VAR, None) + +TEST_LIST = gtest_test_utils.Subprocess( + [EXE_PATH, LIST_TESTS_FLAG], env=environ).output SUPPORTS_SEH_EXCEPTIONS = 'ThrowsSehException' in TEST_LIST if SUPPORTS_SEH_EXCEPTIONS: - BINARY_OUTPUT = gtest_test_utils.Subprocess([EXE_PATH]).output + BINARY_OUTPUT = gtest_test_utils.Subprocess([EXE_PATH], env=environ).output + +EX_BINARY_OUTPUT = gtest_test_utils.Subprocess( + [EX_EXE_PATH], env=environ).output -EX_BINARY_OUTPUT = gtest_test_utils.Subprocess([EX_EXE_PATH]).output # The tests. if SUPPORTS_SEH_EXCEPTIONS: @@ -212,7 +225,8 @@ class CatchCxxExceptionsTest(gtest_test_utils.TestCase): uncaught_exceptions_ex_binary_output = gtest_test_utils.Subprocess( [EX_EXE_PATH, NO_CATCH_EXCEPTIONS_FLAG, - FITLER_OUT_SEH_TESTS_FLAG]).output + FITLER_OUT_SEH_TESTS_FLAG], + env=environ).output self.assert_('Unhandled C++ exception terminating the program' in uncaught_exceptions_ex_binary_output) diff --git a/test/gtest_premature_exit_test.cc b/test/gtest_premature_exit_test.cc new file mode 100644 index 00000000..f6b6be9a --- /dev/null +++ b/test/gtest_premature_exit_test.cc @@ -0,0 +1,141 @@ +// Copyright 2013, 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) +// +// Tests that Google Test manipulates the premature-exit-detection +// file correctly. + +#include + +#include "gtest/gtest.h" + +using ::testing::InitGoogleTest; +using ::testing::Test; +using ::testing::internal::posix::GetEnv; +using ::testing::internal::posix::Stat; +using ::testing::internal::posix::StatStruct; + +namespace { + +// Is the TEST_PREMATURE_EXIT_FILE environment variable expected to be +// set? +const bool kTestPrematureExitFileEnvVarShouldBeSet = false; + +class PrematureExitTest : public Test { + public: + // Returns true iff the given file exists. + static bool FileExists(const char* filepath) { + StatStruct stat; + return Stat(filepath, &stat) == 0; + } + + protected: + PrematureExitTest() { + premature_exit_file_path_ = GetEnv("TEST_PREMATURE_EXIT_FILE"); + + // Normalize NULL to "" for ease of handling. + if (premature_exit_file_path_ == NULL) { + premature_exit_file_path_ = ""; + } + } + + // Returns true iff the premature-exit file exists. + bool PrematureExitFileExists() const { + return FileExists(premature_exit_file_path_); + } + + const char* premature_exit_file_path_; +}; + +typedef PrematureExitTest PrematureExitDeathTest; + +// Tests that: +// - the premature-exit file exists during the execution of a +// death test (EXPECT_DEATH*), and +// - a death test doesn't interfere with the main test process's +// handling of the premature-exit file. +TEST_F(PrematureExitDeathTest, FileExistsDuringExecutionOfDeathTest) { + if (*premature_exit_file_path_ == '\0') { + return; + } + + EXPECT_DEATH_IF_SUPPORTED({ + // If the file exists, crash the process such that the main test + // process will catch the (expected) crash and report a success; + // otherwise don't crash, which will cause the main test process + // to report that the death test has failed. + if (PrematureExitFileExists()) { + exit(1); + } + }, ""); +} + +// Tests that TEST_PREMATURE_EXIT_FILE is set where it's expected to +// be set. +TEST_F(PrematureExitTest, TestPrematureExitFileEnvVarIsSet) { + if (kTestPrematureExitFileEnvVarShouldBeSet) { + const char* const filepath = GetEnv("TEST_PREMATURE_EXIT_FILE"); + ASSERT_TRUE(filepath != NULL); + ASSERT_NE(*filepath, '\0'); + } +} + +// Tests that the premature-exit file exists during the execution of a +// normal (non-death) test. +TEST_F(PrematureExitTest, PrematureExitFileExistsDuringTestExecution) { + if (*premature_exit_file_path_ == '\0') { + return; + } + + EXPECT_TRUE(PrematureExitFileExists()) + << " file " << premature_exit_file_path_ + << " should exist during test execution, but doesn't."; +} + +} // namespace + +int main(int argc, char **argv) { + InitGoogleTest(&argc, argv); + const int exit_code = RUN_ALL_TESTS(); + + // Test that the premature-exit file is deleted upon return from + // RUN_ALL_TESTS(). + const char* const filepath = GetEnv("TEST_PREMATURE_EXIT_FILE"); + if (filepath != NULL && *filepath != '\0') { + if (PrematureExitTest::FileExists(filepath)) { + printf( + "File %s shouldn't exist after the test program finishes, but does.", + filepath); + return 1; + } + } + + return exit_code; +} diff --git a/test/gtest_test_utils.py b/test/gtest_test_utils.py index 6dd8db4b..28884bdc 100755 --- a/test/gtest_test_utils.py +++ b/test/gtest_test_utils.py @@ -56,6 +56,21 @@ GTEST_OUTPUT_VAR_NAME = 'GTEST_OUTPUT' IS_WINDOWS = os.name == 'nt' IS_CYGWIN = os.name == 'posix' and 'CYGWIN' in os.uname()[0] +# The environment variable for specifying the path to the premature-exit file. +PREMATURE_EXIT_FILE_ENV_VAR = 'TEST_PREMATURE_EXIT_FILE' + +environ = os.environ.copy() + + +def SetEnvVar(env_var, value): + """Sets/unsets an environment variable to a given value.""" + + if value is not None: + environ[env_var] = value + elif env_var in environ: + del environ[env_var] + + # Here we expose a class from a particular module, depending on the # environment. The comment suppresses the 'Invalid variable name' lint # complaint. -- cgit v1.2.3 From 2d3543f81d6d4583332f8b60768ade18e0f96220 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Wed, 18 Sep 2013 17:49:56 +0000 Subject: avoids clash with the max() macro on Windows --- test/gtest-death-test_test.cc | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'test') diff --git a/test/gtest-death-test_test.cc b/test/gtest-death-test_test.cc index 4f379963..c2d26df9 100644 --- a/test/gtest-death-test_test.cc +++ b/test/gtest-death-test_test.cc @@ -45,7 +45,6 @@ using testing::internal::AlwaysTrue; # else # include # include // For waitpid. -# include // For std::numeric_limits. # endif // GTEST_OS_WINDOWS # include @@ -1123,17 +1122,16 @@ TEST(AutoHandleTest, AutoHandleWorks) { # if GTEST_OS_WINDOWS typedef unsigned __int64 BiggestParsable; typedef signed __int64 BiggestSignedParsable; -const BiggestParsable kBiggestParsableMax = ULLONG_MAX; -const BiggestSignedParsable kBiggestSignedParsableMax = LLONG_MAX; # else typedef unsigned long long BiggestParsable; typedef signed long long BiggestSignedParsable; -const BiggestParsable kBiggestParsableMax = - ::std::numeric_limits::max(); -const BiggestSignedParsable kBiggestSignedParsableMax = - ::std::numeric_limits::max(); # endif // GTEST_OS_WINDOWS +// We cannot use std::numeric_limits::max() as it clashes with the +// max() macro defined by . +const BiggestParsable kBiggestParsableMax = ULLONG_MAX; +const BiggestSignedParsable kBiggestSignedParsableMax = LLONG_MAX; + TEST(ParseNaturalNumberTest, RejectsInvalidFormat) { BiggestParsable result = 0; -- cgit v1.2.3 From aa34ae250800af7e98499abba44636503cf99b16 Mon Sep 17 00:00:00 2001 From: kosak Date: Tue, 3 Dec 2013 01:36:29 +0000 Subject: Delete whitespace, and change the return type of ImplicitlyConvertible::MakeFrom() to From&. --- test/gtest-printers_test.cc | 2 -- 1 file changed, 2 deletions(-) (limited to 'test') diff --git a/test/gtest-printers_test.cc b/test/gtest-printers_test.cc index c2beca7d..184f9d9f 100644 --- a/test/gtest-printers_test.cc +++ b/test/gtest-printers_test.cc @@ -414,8 +414,6 @@ TEST(PrintCStringTest, EscapesProperly) { Print(p)); } - - // MSVC compiler can be configured to define whar_t as a typedef // of unsigned short. Defining an overload for const wchar_t* in that case // would cause pointers to unsigned shorts be printed as wide strings, -- cgit v1.2.3 From 5d83ee08dff5775b3bc59d144bc3ea3d4fe9dfb9 Mon Sep 17 00:00:00 2001 From: kosak Date: Tue, 3 Dec 2013 23:15:40 +0000 Subject: Fix warnings encountered with clang -Wall. --- test/gtest-printers_test.cc | 1 + test/gtest-unittest-api_test.cc | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'test') diff --git a/test/gtest-printers_test.cc b/test/gtest-printers_test.cc index 184f9d9f..c2ba7113 100644 --- a/test/gtest-printers_test.cc +++ b/test/gtest-printers_test.cc @@ -125,6 +125,7 @@ namespace foo { class UnprintableInFoo { public: UnprintableInFoo() : z_(0) { memcpy(xy_, "\xEF\x12\x0\x0\x34\xAB\x0\x0", 8); } + double z() const { return z_; } private: char xy_[8]; double z_; diff --git a/test/gtest-unittest-api_test.cc b/test/gtest-unittest-api_test.cc index 07083e51..b1f51688 100644 --- a/test/gtest-unittest-api_test.cc +++ b/test/gtest-unittest-api_test.cc @@ -54,7 +54,7 @@ class UnitTestHelper { public: // Returns the array of pointers to all test cases sorted by the test case // name. The caller is responsible for deleting the array. - static TestCase const** const GetSortedTestCases() { + static TestCase const** GetSortedTestCases() { UnitTest& unit_test = *UnitTest::GetInstance(); TestCase const** const test_cases = new const TestCase*[unit_test.total_test_case_count()]; @@ -83,7 +83,7 @@ class UnitTestHelper { // Returns the array of pointers to all tests in a particular test case // sorted by the test name. The caller is responsible for deleting the // array. - static TestInfo const** const GetSortedTests(const TestCase* test_case) { + static TestInfo const** GetSortedTests(const TestCase* test_case) { TestInfo const** const tests = new const TestInfo*[test_case->total_test_count()]; -- cgit v1.2.3 From ccf8e33bc59a26745753d494b2535a5f0a97acc5 Mon Sep 17 00:00:00 2001 From: kosak Date: Sun, 12 Jan 2014 19:59:41 +0000 Subject: Define specialization of PrintTo(...) for ::std::tuple. --- test/gtest-printers_test.cc | 148 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 120 insertions(+), 28 deletions(-) (limited to 'test') diff --git a/test/gtest-printers_test.cc b/test/gtest-printers_test.cc index c2ba7113..d34a85e1 100644 --- a/test/gtest-printers_test.cc +++ b/test/gtest-printers_test.cc @@ -210,11 +210,6 @@ using ::testing::internal::UniversalTersePrintTupleFieldsToStrings; using ::testing::internal::kReference; using ::testing::internal::string; -#if GTEST_HAS_TR1_TUPLE -using ::std::tr1::make_tuple; -using ::std::tr1::tuple; -#endif - // The hash_* classes are not part of the C++ standard. STLport // defines them in namespace std. MSVC defines them in ::stdext. GCC // defines them in ::. @@ -984,46 +979,47 @@ TEST(PrintStlContainerTest, ConstIterator) { } #if GTEST_HAS_TR1_TUPLE -// Tests printing tuples. +// Tests printing ::std::tr1::tuples. // Tuples of various arities. -TEST(PrintTupleTest, VariousSizes) { - tuple<> t0; +TEST(PrintTr1TupleTest, VariousSizes) { + ::std::tr1::tuple<> t0; EXPECT_EQ("()", Print(t0)); - tuple t1(5); + ::std::tr1::tuple t1(5); EXPECT_EQ("(5)", Print(t1)); - tuple t2('a', true); + ::std::tr1::tuple t2('a', true); EXPECT_EQ("('a' (97, 0x61), true)", Print(t2)); - tuple t3(false, 2, 3); + ::std::tr1::tuple t3(false, 2, 3); EXPECT_EQ("(false, 2, 3)", Print(t3)); - tuple t4(false, 2, 3, 4); + ::std::tr1::tuple t4(false, 2, 3, 4); EXPECT_EQ("(false, 2, 3, 4)", Print(t4)); - tuple t5(false, 2, 3, 4, true); + ::std::tr1::tuple t5(false, 2, 3, 4, true); EXPECT_EQ("(false, 2, 3, 4, true)", Print(t5)); - tuple t6(false, 2, 3, 4, true, 6); + ::std::tr1::tuple t6(false, 2, 3, 4, true, 6); EXPECT_EQ("(false, 2, 3, 4, true, 6)", Print(t6)); - tuple t7(false, 2, 3, 4, true, 6, 7); + ::std::tr1::tuple t7( + false, 2, 3, 4, true, 6, 7); EXPECT_EQ("(false, 2, 3, 4, true, 6, 7)", Print(t7)); - tuple t8( + ::std::tr1::tuple t8( false, 2, 3, 4, true, 6, 7, true); EXPECT_EQ("(false, 2, 3, 4, true, 6, 7, true)", Print(t8)); - tuple t9( + ::std::tr1::tuple t9( false, 2, 3, 4, true, 6, 7, true, 9); EXPECT_EQ("(false, 2, 3, 4, true, 6, 7, true, 9)", Print(t9)); const char* const str = "8"; // VC++ 2010's implementation of tuple of C++0x is deficient, requiring // an explicit type cast of NULL to be used. - tuple t10(false, 'a', 3, 4, 5, 1.5F, -2.5, str, ImplicitCast_(NULL), "10"); @@ -1033,13 +1029,73 @@ TEST(PrintTupleTest, VariousSizes) { } // Nested tuples. -TEST(PrintTupleTest, NestedTuple) { - tuple, char> nested(make_tuple(5, true), 'a'); +TEST(PrintTr1TupleTest, NestedTuple) { + ::std::tr1::tuple< ::std::tr1::tuple, char> nested( + ::std::tr1::make_tuple(5, true), 'a'); EXPECT_EQ("((5, true), 'a' (97, 0x61))", Print(nested)); } #endif // GTEST_HAS_TR1_TUPLE +#if GTEST_LANG_CXX11 +// Tests printing ::std::tuples. + +// Tuples of various arities. +TEST(PrintStdTupleTest, VariousSizes) { + ::std::tuple<> t0; + EXPECT_EQ("()", Print(t0)); + + ::std::tuple t1(5); + EXPECT_EQ("(5)", Print(t1)); + + ::std::tuple t2('a', true); + EXPECT_EQ("('a' (97, 0x61), true)", Print(t2)); + + ::std::tuple t3(false, 2, 3); + EXPECT_EQ("(false, 2, 3)", Print(t3)); + + ::std::tuple t4(false, 2, 3, 4); + EXPECT_EQ("(false, 2, 3, 4)", Print(t4)); + + ::std::tuple t5(false, 2, 3, 4, true); + EXPECT_EQ("(false, 2, 3, 4, true)", Print(t5)); + + ::std::tuple t6(false, 2, 3, 4, true, 6); + EXPECT_EQ("(false, 2, 3, 4, true, 6)", Print(t6)); + + ::std::tuple t7( + false, 2, 3, 4, true, 6, 7); + EXPECT_EQ("(false, 2, 3, 4, true, 6, 7)", Print(t7)); + + ::std::tuple t8( + false, 2, 3, 4, true, 6, 7, true); + EXPECT_EQ("(false, 2, 3, 4, true, 6, 7, true)", Print(t8)); + + ::std::tuple t9( + false, 2, 3, 4, true, 6, 7, true, 9); + EXPECT_EQ("(false, 2, 3, 4, true, 6, 7, true, 9)", Print(t9)); + + const char* const str = "8"; + // VC++ 2010's implementation of tuple of C++0x is deficient, requiring + // an explicit type cast of NULL to be used. + ::std::tuple + t10(false, 'a', 3, 4, 5, 1.5F, -2.5, str, + ImplicitCast_(NULL), "10"); + EXPECT_EQ("(false, 'a' (97, 0x61), 3, 4, 5, 1.5, -2.5, " + PrintPointer(str) + + " pointing to \"8\", NULL, \"10\")", + Print(t10)); +} + +// Nested tuples. +TEST(PrintStdTupleTest, NestedTuple) { + ::std::tuple< ::std::tuple, char> nested( + ::std::make_tuple(5, true), 'a'); + EXPECT_EQ("((5, true), 'a' (97, 0x61))", Print(nested)); +} + +#endif // GTEST_LANG_CXX11 + // Tests printing user-defined unprintable types. // Unprintable types in the global namespace. @@ -1532,28 +1588,31 @@ TEST(UniversalPrintTest, WorksForCharArray) { #if GTEST_HAS_TR1_TUPLE -TEST(UniversalTersePrintTupleFieldsToStringsTest, PrintsEmptyTuple) { - Strings result = UniversalTersePrintTupleFieldsToStrings(make_tuple()); +TEST(UniversalTersePrintTupleFieldsToStringsTestWithTr1, PrintsEmptyTuple) { + Strings result = UniversalTersePrintTupleFieldsToStrings( + ::std::tr1::make_tuple()); EXPECT_EQ(0u, result.size()); } -TEST(UniversalTersePrintTupleFieldsToStringsTest, PrintsOneTuple) { - Strings result = UniversalTersePrintTupleFieldsToStrings(make_tuple(1)); +TEST(UniversalTersePrintTupleFieldsToStringsTestWithTr1, PrintsOneTuple) { + Strings result = UniversalTersePrintTupleFieldsToStrings( + ::std::tr1::make_tuple(1)); ASSERT_EQ(1u, result.size()); EXPECT_EQ("1", result[0]); } -TEST(UniversalTersePrintTupleFieldsToStringsTest, PrintsTwoTuple) { - Strings result = UniversalTersePrintTupleFieldsToStrings(make_tuple(1, 'a')); +TEST(UniversalTersePrintTupleFieldsToStringsTestWithTr1, PrintsTwoTuple) { + Strings result = UniversalTersePrintTupleFieldsToStrings( + ::std::tr1::make_tuple(1, 'a')); ASSERT_EQ(2u, result.size()); EXPECT_EQ("1", result[0]); EXPECT_EQ("'a' (97, 0x61)", result[1]); } -TEST(UniversalTersePrintTupleFieldsToStringsTest, PrintsTersely) { +TEST(UniversalTersePrintTupleFieldsToStringsTestWithTr1, PrintsTersely) { const int n = 1; Strings result = UniversalTersePrintTupleFieldsToStrings( - tuple(n, "a")); + ::std::tr1::tuple(n, "a")); ASSERT_EQ(2u, result.size()); EXPECT_EQ("1", result[0]); EXPECT_EQ("\"a\"", result[1]); @@ -1561,5 +1620,38 @@ TEST(UniversalTersePrintTupleFieldsToStringsTest, PrintsTersely) { #endif // GTEST_HAS_TR1_TUPLE +#if GTEST_HAS_STD_TUPLE_ + +TEST(UniversalTersePrintTupleFieldsToStringsTestWithStd, PrintsEmptyTuple) { + Strings result = UniversalTersePrintTupleFieldsToStrings(::std::make_tuple()); + EXPECT_EQ(0u, result.size()); +} + +TEST(UniversalTersePrintTupleFieldsToStringsTestWithStd, PrintsOneTuple) { + Strings result = UniversalTersePrintTupleFieldsToStrings( + ::std::make_tuple(1)); + ASSERT_EQ(1u, result.size()); + EXPECT_EQ("1", result[0]); +} + +TEST(UniversalTersePrintTupleFieldsToStringsTestWithStd, PrintsTwoTuple) { + Strings result = UniversalTersePrintTupleFieldsToStrings( + ::std::make_tuple(1, 'a')); + ASSERT_EQ(2u, result.size()); + EXPECT_EQ("1", result[0]); + EXPECT_EQ("'a' (97, 0x61)", result[1]); +} + +TEST(UniversalTersePrintTupleFieldsToStringsTestWithStd, PrintsTersely) { + const int n = 1; + Strings result = UniversalTersePrintTupleFieldsToStrings( + ::std::tuple(n, "a")); + ASSERT_EQ(2u, result.size()); + EXPECT_EQ("1", result[0]); + EXPECT_EQ("\"a\"", result[1]); +} + +#endif // GTEST_HAS_STD_TUPLE_ + } // namespace gtest_printers_test } // namespace testing -- cgit v1.2.3 From 7d1051ce2b3be67d27b200d0050a7ec88c18621b Mon Sep 17 00:00:00 2001 From: kosak Date: Mon, 13 Jan 2014 22:24:15 +0000 Subject: Make Google Test build cleanly on Visual Studio 2010, 2012, 2013. Also improve an error message in gtest_test_utils.py. --- test/gtest-typed-test_test.cc | 3 ++- test/gtest_test_utils.py | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-) (limited to 'test') diff --git a/test/gtest-typed-test_test.cc b/test/gtest-typed-test_test.cc index dd4ba43b..c3e66c2d 100644 --- a/test/gtest-typed-test_test.cc +++ b/test/gtest-typed-test_test.cc @@ -29,10 +29,11 @@ // // Author: wan@google.com (Zhanyong Wan) +#include "test/gtest-typed-test_test.h" + #include #include -#include "test/gtest-typed-test_test.h" #include "gtest/gtest.h" using testing::Test; diff --git a/test/gtest_test_utils.py b/test/gtest_test_utils.py index 28884bdc..7e3cbcaf 100755 --- a/test/gtest_test_utils.py +++ b/test/gtest_test_utils.py @@ -175,9 +175,9 @@ def GetTestExecutablePath(executable_name, build_dir=None): if not os.path.exists(path): message = ( - 'Unable to find the test binary. Please make sure to provide path\n' - 'to the binary via the --build_dir flag or the BUILD_DIR\n' - 'environment variable.') + 'Unable to find the test binary "%s". Please make sure to provide\n' + 'a path to the binary via the --build_dir flag or the BUILD_DIR\n' + 'environment variable.' % path) print >> sys.stderr, message sys.exit(1) -- cgit v1.2.3 From 41a8bc67ab7e7a81735e9d560f54d8d130dcc3ab Mon Sep 17 00:00:00 2001 From: kosak Date: Wed, 29 Jan 2014 07:29:19 +0000 Subject: Suppress "Conditional expression is constant" warning on Visual Studio. --- test/gtest_premature_exit_test.cc | 2 ++ 1 file changed, 2 insertions(+) (limited to 'test') diff --git a/test/gtest_premature_exit_test.cc b/test/gtest_premature_exit_test.cc index f6b6be9a..fcfc623e 100644 --- a/test/gtest_premature_exit_test.cc +++ b/test/gtest_premature_exit_test.cc @@ -100,7 +100,9 @@ TEST_F(PrematureExitDeathTest, FileExistsDuringExecutionOfDeathTest) { // Tests that TEST_PREMATURE_EXIT_FILE is set where it's expected to // be set. TEST_F(PrematureExitTest, TestPrematureExitFileEnvVarIsSet) { + GTEST_INTENTIONAL_CONST_COND_PUSH_ if (kTestPrematureExitFileEnvVarShouldBeSet) { + GTEST_INTENTIONAL_CONST_COND_POP_ const char* const filepath = GetEnv("TEST_PREMATURE_EXIT_FILE"); ASSERT_TRUE(filepath != NULL); ASSERT_NE(*filepath, '\0'); -- cgit v1.2.3 From c82282819c0f6fbd2bd025f2326f0a6b104c59b9 Mon Sep 17 00:00:00 2001 From: kosak Date: Wed, 12 Mar 2014 22:51:07 +0000 Subject: Remove code referencing Google protocol buffers version 1. --- test/gtest-printers_test.cc | 7 ------- 1 file changed, 7 deletions(-) (limited to 'test') diff --git a/test/gtest-printers_test.cc b/test/gtest-printers_test.cc index d34a85e1..9481290c 100644 --- a/test/gtest-printers_test.cc +++ b/test/gtest-printers_test.cc @@ -1164,13 +1164,6 @@ TEST(PrintPrintableTypeTest, TemplateInUserNamespace) { #if GTEST_HAS_PROTOBUF_ -// Tests printing a protocol message. -TEST(PrintProtocolMessageTest, PrintsShortDebugString) { - testing::internal::TestMessage msg; - msg.set_member("yes"); - EXPECT_EQ("", Print(msg)); -} - // Tests printing a short proto2 message. TEST(PrintProto2MessageTest, PrintsShortDebugStringWhenItIsShort) { testing::internal::FooMessage msg; -- cgit v1.2.3 From a6340420b9cee27f77c5b91bea807121914a5831 Mon Sep 17 00:00:00 2001 From: kosak Date: Mon, 24 Mar 2014 21:58:25 +0000 Subject: Implement threading support for gtest on Windows. Also, stop using localtime(). Instead, use localtime_r() on most systems, localtime_s() on Windows. --- test/gtest-death-test_test.cc | 68 +++++++++++++++++++- test/gtest-port_test.cc | 142 +++++++++++++++++++++++++++++++----------- test/gtest_output_test.py | 4 +- 3 files changed, 175 insertions(+), 39 deletions(-) (limited to 'test') diff --git a/test/gtest-death-test_test.cc b/test/gtest-death-test_test.cc index c2d26df9..da0b84d3 100644 --- a/test/gtest-death-test_test.cc +++ b/test/gtest-death-test_test.cc @@ -699,7 +699,10 @@ TEST_F(TestForDeathTest, ExpectDebugDeathDoesNotAbort) { void AssertDebugDeathHelper(bool* aborted) { *aborted = true; - ASSERT_DEBUG_DEATH(return, "") << "This is expected to fail."; + GTEST_LOG_(INFO) << "Before ASSERT_DEBUG_DEATH"; + ASSERT_DEBUG_DEATH(GTEST_LOG_(INFO) << "In ASSERT_DEBUG_DEATH"; return, "") + << "This is expected to fail."; + GTEST_LOG_(INFO) << "After ASSERT_DEBUG_DEATH"; *aborted = false; } @@ -712,6 +715,69 @@ TEST_F(TestForDeathTest, AssertDebugDeathAborts) { EXPECT_TRUE(aborted); } +TEST_F(TestForDeathTest, AssertDebugDeathAborts2) { + static bool aborted; + aborted = false; + EXPECT_FATAL_FAILURE(AssertDebugDeathHelper(&aborted), ""); + EXPECT_TRUE(aborted); +} + +TEST_F(TestForDeathTest, AssertDebugDeathAborts3) { + static bool aborted; + aborted = false; + EXPECT_FATAL_FAILURE(AssertDebugDeathHelper(&aborted), ""); + EXPECT_TRUE(aborted); +} + +TEST_F(TestForDeathTest, AssertDebugDeathAborts4) { + static bool aborted; + aborted = false; + EXPECT_FATAL_FAILURE(AssertDebugDeathHelper(&aborted), ""); + EXPECT_TRUE(aborted); +} + +TEST_F(TestForDeathTest, AssertDebugDeathAborts5) { + static bool aborted; + aborted = false; + EXPECT_FATAL_FAILURE(AssertDebugDeathHelper(&aborted), ""); + EXPECT_TRUE(aborted); +} + +TEST_F(TestForDeathTest, AssertDebugDeathAborts6) { + static bool aborted; + aborted = false; + EXPECT_FATAL_FAILURE(AssertDebugDeathHelper(&aborted), ""); + EXPECT_TRUE(aborted); +} + +TEST_F(TestForDeathTest, AssertDebugDeathAborts7) { + static bool aborted; + aborted = false; + EXPECT_FATAL_FAILURE(AssertDebugDeathHelper(&aborted), ""); + EXPECT_TRUE(aborted); +} + +TEST_F(TestForDeathTest, AssertDebugDeathAborts8) { + static bool aborted; + aborted = false; + EXPECT_FATAL_FAILURE(AssertDebugDeathHelper(&aborted), ""); + EXPECT_TRUE(aborted); +} + +TEST_F(TestForDeathTest, AssertDebugDeathAborts9) { + static bool aborted; + aborted = false; + EXPECT_FATAL_FAILURE(AssertDebugDeathHelper(&aborted), ""); + EXPECT_TRUE(aborted); +} + +TEST_F(TestForDeathTest, AssertDebugDeathAborts10) { + static bool aborted; + aborted = false; + EXPECT_FATAL_FAILURE(AssertDebugDeathHelper(&aborted), ""); + EXPECT_TRUE(aborted); +} + # endif // _NDEBUG // Tests the *_EXIT family of macros, using a variety of predicates. diff --git a/test/gtest-port_test.cc b/test/gtest-port_test.cc index 43f1f201..370c952b 100644 --- a/test/gtest-port_test.cc +++ b/test/gtest-port_test.cc @@ -1062,11 +1062,13 @@ class AtomicCounterWithMutex { MutexLock lock(mutex_); int temp = value_; { - // Locking a mutex puts up a memory barrier, preventing reads and - // writes to value_ rearranged when observed from other threads. - // - // We cannot use Mutex and MutexLock here or rely on their memory - // barrier functionality as we are testing them here. + // We need to put up a memory barrier to prevent reads and writes to + // value_ rearranged with the call to SleepMilliseconds when observed + // from other threads. +#if GTEST_HAS_PTHREAD + // On POSIX, locking a mutex puts up a memory barrier. We cannot use + // Mutex and MutexLock here or rely on their memory barrier + // functionality as we are testing them here. pthread_mutex_t memory_barrier_mutex; GTEST_CHECK_POSIX_SUCCESS_( pthread_mutex_init(&memory_barrier_mutex, NULL)); @@ -1076,6 +1078,15 @@ class AtomicCounterWithMutex { GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_unlock(&memory_barrier_mutex)); GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_destroy(&memory_barrier_mutex)); +#elif GTEST_OS_WINDOWS + // On Windows, performing an interlocked access puts up a memory barrier. + volatile LONG dummy = 0; + ::InterlockedIncrement(&dummy); + SleepMilliseconds(random_.Generate(30)); + ::InterlockedIncrement(&dummy); +#else +# error "Memory barrier not implemented on this platform." +#endif // GTEST_HAS_PTHREAD } value_ = temp + 1; } @@ -1145,27 +1156,76 @@ TEST(ThreadLocalTest, ParameterizedConstructorSetsDefault) { EXPECT_STREQ("foo", result.c_str()); } +// Keeps track of whether of destructors being called on instances of +// DestructorTracker. On Windows, waits for the destructor call reports. +class DestructorCall { + public: + DestructorCall() { + invoked_ = false; +#if GTEST_OS_WINDOWS + wait_event_.Reset(::CreateEvent(NULL, TRUE, FALSE, NULL)); + GTEST_CHECK_(wait_event_.Get() != NULL); +#endif + } + + bool CheckDestroyed() const { +#if GTEST_OS_WINDOWS + if (::WaitForSingleObject(wait_event_.Get(), 1000) != WAIT_OBJECT_0) + return false; +#endif + return invoked_; + } + + void ReportDestroyed() { + invoked_ = true; +#if GTEST_OS_WINDOWS + ::SetEvent(wait_event_.Get()); +#endif + } + + static std::vector& List() { return *list_; } + + static void ResetList() { + for (size_t i = 0; i < list_->size(); ++i) { + delete list_->at(i); + } + list_->clear(); + } + + private: + bool invoked_; +#if GTEST_OS_WINDOWS + AutoHandle wait_event_; +#endif + static std::vector* const list_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(DestructorCall); +}; + +std::vector* const DestructorCall::list_ = + new std::vector; + // DestructorTracker keeps track of whether its instances have been // destroyed. -static std::vector g_destroyed; - class DestructorTracker { public: DestructorTracker() : index_(GetNewIndex()) {} DestructorTracker(const DestructorTracker& /* rhs */) : index_(GetNewIndex()) {} ~DestructorTracker() { - // We never access g_destroyed concurrently, so we don't need to - // protect the write operation under a mutex. - g_destroyed[index_] = true; + // We never access DestructorCall::List() concurrently, so we don't need + // to protect this acccess with a mutex. + DestructorCall::List()[index_]->ReportDestroyed(); } private: static int GetNewIndex() { - g_destroyed.push_back(false); - return g_destroyed.size() - 1; + DestructorCall::List().push_back(new DestructorCall); + return DestructorCall::List().size() - 1; } const int index_; + + GTEST_DISALLOW_ASSIGN_(DestructorTracker); }; typedef ThreadLocal* ThreadParam; @@ -1177,63 +1237,63 @@ void CallThreadLocalGet(ThreadParam thread_local_param) { // Tests that when a ThreadLocal object dies in a thread, it destroys // the managed object for that thread. TEST(ThreadLocalTest, DestroysManagedObjectForOwnThreadWhenDying) { - g_destroyed.clear(); + DestructorCall::ResetList(); { // The next line default constructs a DestructorTracker object as // the default value of objects managed by thread_local_tracker. ThreadLocal thread_local_tracker; - ASSERT_EQ(1U, g_destroyed.size()); - ASSERT_FALSE(g_destroyed[0]); + ASSERT_EQ(1U, DestructorCall::List().size()); + ASSERT_FALSE(DestructorCall::List()[0]->CheckDestroyed()); // This creates another DestructorTracker object for the main thread. thread_local_tracker.get(); - ASSERT_EQ(2U, g_destroyed.size()); - ASSERT_FALSE(g_destroyed[0]); - ASSERT_FALSE(g_destroyed[1]); + ASSERT_EQ(2U, DestructorCall::List().size()); + ASSERT_FALSE(DestructorCall::List()[0]->CheckDestroyed()); + ASSERT_FALSE(DestructorCall::List()[1]->CheckDestroyed()); } // Now thread_local_tracker has died. It should have destroyed both the // default value shared by all threads and the value for the main // thread. - ASSERT_EQ(2U, g_destroyed.size()); - EXPECT_TRUE(g_destroyed[0]); - EXPECT_TRUE(g_destroyed[1]); + ASSERT_EQ(2U, DestructorCall::List().size()); + EXPECT_TRUE(DestructorCall::List()[0]->CheckDestroyed()); + EXPECT_TRUE(DestructorCall::List()[1]->CheckDestroyed()); - g_destroyed.clear(); + DestructorCall::ResetList(); } // Tests that when a thread exits, the thread-local object for that // thread is destroyed. TEST(ThreadLocalTest, DestroysManagedObjectAtThreadExit) { - g_destroyed.clear(); + DestructorCall::ResetList(); { // The next line default constructs a DestructorTracker object as // the default value of objects managed by thread_local_tracker. ThreadLocal thread_local_tracker; - ASSERT_EQ(1U, g_destroyed.size()); - ASSERT_FALSE(g_destroyed[0]); + ASSERT_EQ(1U, DestructorCall::List().size()); + ASSERT_FALSE(DestructorCall::List()[0]->CheckDestroyed()); // This creates another DestructorTracker object in the new thread. ThreadWithParam thread( &CallThreadLocalGet, &thread_local_tracker, NULL); thread.Join(); - // Now the new thread has exited. The per-thread object for it - // should have been destroyed. - ASSERT_EQ(2U, g_destroyed.size()); - ASSERT_FALSE(g_destroyed[0]); - ASSERT_TRUE(g_destroyed[1]); + // The thread has exited, and we should have another DestroyedTracker + // instance created for it. But it may not have been destroyed yet. + // The instance for the main thread should still persist. + ASSERT_EQ(2U, DestructorCall::List().size()); + ASSERT_FALSE(DestructorCall::List()[0]->CheckDestroyed()); } - // Now thread_local_tracker has died. The default value should have been - // destroyed too. - ASSERT_EQ(2U, g_destroyed.size()); - EXPECT_TRUE(g_destroyed[0]); - EXPECT_TRUE(g_destroyed[1]); + // The thread has exited and thread_local_tracker has died. The default + // value should have been destroyed too. + ASSERT_EQ(2U, DestructorCall::List().size()); + EXPECT_TRUE(DestructorCall::List()[0]->CheckDestroyed()); + EXPECT_TRUE(DestructorCall::List()[1]->CheckDestroyed()); - g_destroyed.clear(); + DestructorCall::ResetList(); } TEST(ThreadLocalTest, ThreadLocalMutationsAffectOnlyCurrentThread) { @@ -1249,5 +1309,15 @@ TEST(ThreadLocalTest, ThreadLocalMutationsAffectOnlyCurrentThread) { #endif // GTEST_IS_THREADSAFE +#if GTEST_OS_WINDOWS +TEST(WindowsTypesTest, HANDLEIsVoidStar) { + StaticAssertTypeEq(); +} + +TEST(WindowsTypesTest, CRITICAL_SECTIONIs_RTL_CRITICAL_SECTION) { + StaticAssertTypeEq(); +} +#endif // GTEST_OS_WINDOWS + } // namespace internal } // namespace testing diff --git a/test/gtest_output_test.py b/test/gtest_output_test.py index f409e2a7..fa1a3117 100755 --- a/test/gtest_output_test.py +++ b/test/gtest_output_test.py @@ -252,8 +252,8 @@ SUPPORTS_STACK_TRACES = False CAN_GENERATE_GOLDEN_FILE = (SUPPORTS_DEATH_TESTS and SUPPORTS_TYPED_TESTS and - SUPPORTS_THREADS) - + SUPPORTS_THREADS and + not IS_WINDOWS) class GTestOutputTest(gtest_test_utils.TestCase): def RemoveUnsupportedTests(self, test_output): -- cgit v1.2.3 From 5df87d70b64dd8080ab9e3f1b0250e74715e2a60 Mon Sep 17 00:00:00 2001 From: kosak Date: Wed, 2 Apr 2014 20:26:07 +0000 Subject: Export tuple and friends in the ::testing namespace. --- test/gtest-param-test_test.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'test') diff --git a/test/gtest-param-test_test.cc b/test/gtest-param-test_test.cc index f60cb8a5..cc1dc65f 100644 --- a/test/gtest-param-test_test.cc +++ b/test/gtest-param-test_test.cc @@ -64,9 +64,9 @@ using ::testing::ValuesIn; # if GTEST_HAS_COMBINE using ::testing::Combine; -using ::std::tr1::get; -using ::std::tr1::make_tuple; -using ::std::tr1::tuple; +using ::testing::get; +using ::testing::make_tuple; +using ::testing::tuple; # endif // GTEST_HAS_COMBINE using ::testing::internal::ParamGenerator; -- cgit v1.2.3 From 8120f66c3249e253f03fdb48bee7e528bc038d31 Mon Sep 17 00:00:00 2001 From: billydonahue Date: Thu, 15 May 2014 19:42:15 +0000 Subject: Push upstream to SVN. --- test/gtest-death-test_test.cc | 70 +++++++++++++++++---------------------- test/gtest-printers_test.cc | 7 ++-- test/gtest_premature_exit_test.cc | 4 +-- test/gtest_unittest.cc | 66 ++++++++++++++++++++++-------------- 4 files changed, 77 insertions(+), 70 deletions(-) (limited to 'test') diff --git a/test/gtest-death-test_test.cc b/test/gtest-death-test_test.cc index da0b84d3..b25bc229 100644 --- a/test/gtest-death-test_test.cc +++ b/test/gtest-death-test_test.cc @@ -326,12 +326,9 @@ TEST_F(TestForDeathTest, EmbeddedNulInMessage) { // Tests that death test macros expand to code which interacts well with switch // statements. TEST_F(TestForDeathTest, SwitchStatement) { -// Microsoft compiler usually complains about switch statements without -// case labels. We suppress that warning for this test. -# ifdef _MSC_VER -# pragma warning(push) -# pragma warning(disable: 4065) -# endif // _MSC_VER + // Microsoft compiler usually complains about switch statements without + // case labels. We suppress that warning for this test. + GTEST_DISABLE_MSC_WARNINGS_PUSH_(4065) switch (0) default: @@ -341,9 +338,7 @@ TEST_F(TestForDeathTest, SwitchStatement) { case 0: EXPECT_DEATH(_exit(1), "") << "exit in switch case"; -# ifdef _MSC_VER -# pragma warning(pop) -# endif // _MSC_VER + GTEST_DISABLE_MSC_WARNINGS_POP_() } // Tests that a static member function can be used in a "fast" style @@ -1304,7 +1299,27 @@ TEST(ConditionalDeathMacrosDeathTest, ExpectsDeathWhenDeathTestsAvailable) { EXPECT_FATAL_FAILURE(ASSERT_DEATH_IF_SUPPORTED(;, ""), ""); } -#else +TEST(InDeathTestChildDeathTest, ReportsDeathTestCorrectlyInFastStyle) { + testing::GTEST_FLAG(death_test_style) = "fast"; + EXPECT_FALSE(InDeathTestChild()); + EXPECT_DEATH({ + fprintf(stderr, InDeathTestChild() ? "Inside" : "Outside"); + fflush(stderr); + _exit(1); + }, "Inside"); +} + +TEST(InDeathTestChildDeathTest, ReportsDeathTestCorrectlyInThreadSafeStyle) { + testing::GTEST_FLAG(death_test_style) = "threadsafe"; + EXPECT_FALSE(InDeathTestChild()); + EXPECT_DEATH({ + fprintf(stderr, InDeathTestChild() ? "Inside" : "Outside"); + fflush(stderr); + _exit(1); + }, "Inside"); +} + +#else // !GTEST_HAS_DEATH_TEST follows using testing::internal::CaptureStderr; using testing::internal::GetCapturedStderr; @@ -1354,27 +1369,7 @@ TEST(ConditionalDeathMacrosTest, AssertDeatDoesNotReturnhIfUnsupported) { EXPECT_EQ(1, n); } -TEST(InDeathTestChildDeathTest, ReportsDeathTestCorrectlyInFastStyle) { - testing::GTEST_FLAG(death_test_style) = "fast"; - EXPECT_FALSE(InDeathTestChild()); - EXPECT_DEATH({ - fprintf(stderr, InDeathTestChild() ? "Inside" : "Outside"); - fflush(stderr); - _exit(1); - }, "Inside"); -} - -TEST(InDeathTestChildDeathTest, ReportsDeathTestCorrectlyInThreadSafeStyle) { - testing::GTEST_FLAG(death_test_style) = "threadsafe"; - EXPECT_FALSE(InDeathTestChild()); - EXPECT_DEATH({ - fprintf(stderr, InDeathTestChild() ? "Inside" : "Outside"); - fflush(stderr); - _exit(1); - }, "Inside"); -} - -#endif // GTEST_HAS_DEATH_TEST +#endif // !GTEST_HAS_DEATH_TEST // Tests that the death test macros expand to code which may or may not // be followed by operator<<, and that in either case the complete text @@ -1405,12 +1400,9 @@ TEST(ConditionalDeathMacrosSyntaxDeathTest, SingleStatement) { // Tests that conditional death test macros expand to code which interacts // well with switch statements. TEST(ConditionalDeathMacrosSyntaxDeathTest, SwitchStatement) { -// Microsoft compiler usually complains about switch statements without -// case labels. We suppress that warning for this test. -#ifdef _MSC_VER -# pragma warning(push) -# pragma warning(disable: 4065) -#endif // _MSC_VER + // Microsoft compiler usually complains about switch statements without + // case labels. We suppress that warning for this test. + GTEST_DISABLE_MSC_WARNINGS_PUSH_(4065) switch (0) default: @@ -1421,9 +1413,7 @@ TEST(ConditionalDeathMacrosSyntaxDeathTest, SwitchStatement) { case 0: EXPECT_DEATH_IF_SUPPORTED(_exit(1), "") << "exit in switch case"; -#ifdef _MSC_VER -# pragma warning(pop) -#endif // _MSC_VER + GTEST_DISABLE_MSC_WARNINGS_POP_() } // Tests that a test case whose name ends with "DeathTest" works fine diff --git a/test/gtest-printers_test.cc b/test/gtest-printers_test.cc index 9481290c..7b07fd10 100644 --- a/test/gtest-printers_test.cc +++ b/test/gtest-printers_test.cc @@ -202,12 +202,12 @@ using ::testing::internal::FormatForComparisonFailureMessage; using ::testing::internal::ImplicitCast_; using ::testing::internal::NativeArray; using ::testing::internal::RE; +using ::testing::internal::RelationToSourceReference; using ::testing::internal::Strings; using ::testing::internal::UniversalPrint; using ::testing::internal::UniversalPrinter; using ::testing::internal::UniversalTersePrint; using ::testing::internal::UniversalTersePrintTupleFieldsToStrings; -using ::testing::internal::kReference; using ::testing::internal::string; // The hash_* classes are not part of the C++ standard. STLport @@ -946,13 +946,13 @@ TEST(PrintStlContainerTest, NestedContainer) { TEST(PrintStlContainerTest, OneDimensionalNativeArray) { const int a[3] = { 1, 2, 3 }; - NativeArray b(a, 3, kReference); + NativeArray b(a, 3, RelationToSourceReference()); EXPECT_EQ("{ 1, 2, 3 }", Print(b)); } TEST(PrintStlContainerTest, TwoDimensionalNativeArray) { const int a[2][3] = { { 1, 2, 3 }, { 4, 5, 6 } }; - NativeArray b(a, 2, kReference); + NativeArray b(a, 2, RelationToSourceReference()); EXPECT_EQ("{ { 1, 2, 3 }, { 4, 5, 6 } }", Print(b)); } @@ -1648,3 +1648,4 @@ TEST(UniversalTersePrintTupleFieldsToStringsTestWithStd, PrintsTersely) { } // namespace gtest_printers_test } // namespace testing + diff --git a/test/gtest_premature_exit_test.cc b/test/gtest_premature_exit_test.cc index fcfc623e..c1ed9686 100644 --- a/test/gtest_premature_exit_test.cc +++ b/test/gtest_premature_exit_test.cc @@ -100,9 +100,9 @@ TEST_F(PrematureExitDeathTest, FileExistsDuringExecutionOfDeathTest) { // Tests that TEST_PREMATURE_EXIT_FILE is set where it's expected to // be set. TEST_F(PrematureExitTest, TestPrematureExitFileEnvVarIsSet) { - GTEST_INTENTIONAL_CONST_COND_PUSH_ + GTEST_INTENTIONAL_CONST_COND_PUSH_() if (kTestPrematureExitFileEnvVarShouldBeSet) { - GTEST_INTENTIONAL_CONST_COND_POP_ + GTEST_INTENTIONAL_CONST_COND_POP_() const char* const filepath = GetEnv("TEST_PREMATURE_EXIT_FILE"); ASSERT_TRUE(filepath != NULL); ASSERT_NE(*filepath, '\0'); diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index 0cab07d1..6cccd018 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -233,7 +233,6 @@ using testing::TestProperty; using testing::TestResult; using testing::TimeInMillis; using testing::UnitTest; -using testing::kMaxStackTraceDepth; using testing::internal::AddReference; using testing::internal::AlwaysFalse; using testing::internal::AlwaysTrue; @@ -267,6 +266,8 @@ using testing::internal::IsContainerTest; using testing::internal::IsNotContainer; using testing::internal::NativeArray; using testing::internal::ParseInt32Flag; +using testing::internal::RelationToSourceCopy; +using testing::internal::RelationToSourceReference; using testing::internal::RemoveConst; using testing::internal::RemoveReference; using testing::internal::ShouldRunTestOnShard; @@ -281,11 +282,10 @@ using testing::internal::TestEventListenersAccessor; using testing::internal::TestResultAccessor; using testing::internal::UInt32; using testing::internal::WideStringToUtf8; -using testing::internal::kCopy; using testing::internal::kMaxRandomSeed; -using testing::internal::kReference; using testing::internal::kTestTypeIdInGoogleTest; using testing::internal::scoped_ptr; +using testing::kMaxStackTraceDepth; #if GTEST_HAS_STREAM_REDIRECTION using testing::internal::CaptureStdout; @@ -417,19 +417,11 @@ class FormatEpochTimeInMillisAsIso8601Test : public Test { private: virtual void SetUp() { saved_tz_ = NULL; -#if _MSC_VER -# pragma warning(push) // Saves the current warning state. -# pragma warning(disable:4996) // Temporarily disables warning 4996 - // (function or variable may be unsafe - // for getenv, function is deprecated for - // strdup). - if (getenv("TZ")) - saved_tz_ = strdup(getenv("TZ")); -# pragma warning(pop) // Restores the warning state again. -#else + + GTEST_DISABLE_MSC_WARNINGS_PUSH_(4996 /* getenv, strdup: deprecated */) if (getenv("TZ")) saved_tz_ = strdup(getenv("TZ")); -#endif + GTEST_DISABLE_MSC_WARNINGS_POP_() // Set up the time zone for FormatEpochTimeInMillisAsIso8601 to use. We // cannot use the local time zone because the function's output depends @@ -453,11 +445,9 @@ class FormatEpochTimeInMillisAsIso8601Test : public Test { const std::string env_var = std::string("TZ=") + (time_zone ? time_zone : ""); _putenv(env_var.c_str()); -# pragma warning(push) // Saves the current warning state. -# pragma warning(disable:4996) // Temporarily disables warning 4996 - // (function is deprecated). + GTEST_DISABLE_MSC_WARNINGS_PUSH_(4996 /* deprecated function */) tzset(); -# pragma warning(pop) // Restores the warning state again. + GTEST_DISABLE_MSC_WARNINGS_POP_() #else if (time_zone) { setenv(("TZ"), time_zone, 1); @@ -5026,6 +5016,31 @@ TEST(AssertionResultTest, CanStreamOstreamManipulators) { EXPECT_STREQ("Data\n\\0Will be visible", r.message()); } +// The next test uses explicit conversion operators -- a C++11 feature. +#if GTEST_LANG_CXX11 + +TEST(AssertionResultTest, ConstructibleFromContextuallyConvertibleToBool) { + struct ExplicitlyConvertibleToBool { + explicit operator bool() const { return value; } + bool value; + }; + ExplicitlyConvertibleToBool v1 = {false}; + ExplicitlyConvertibleToBool v2 = {true}; + EXPECT_FALSE(v1); + EXPECT_TRUE(v2); +} + +#endif // GTEST_LANG_CXX11 + +struct ConvertibleToAssertionResult { + operator AssertionResult() const { return AssertionResult(true); } +}; + +TEST(AssertionResultTest, ConstructibleFromImplicitlyConvertible) { + ConvertibleToAssertionResult obj; + EXPECT_TRUE(obj); +} + // Tests streaming a user type whose definition and operator << are // both in the global namespace. class Base { @@ -7327,7 +7342,7 @@ TEST(CopyArrayTest, WorksForTwoDimensionalArrays) { TEST(NativeArrayTest, ConstructorFromArrayWorks) { const int a[3] = { 0, 1, 2 }; - NativeArray na(a, 3, kReference); + NativeArray na(a, 3, RelationToSourceReference()); EXPECT_EQ(3U, na.size()); EXPECT_EQ(a, na.begin()); } @@ -7337,7 +7352,7 @@ TEST(NativeArrayTest, CreatesAndDeletesCopyOfArrayWhenAskedTo) { Array* a = new Array[1]; (*a)[0] = 0; (*a)[1] = 1; - NativeArray na(*a, 2, kCopy); + NativeArray na(*a, 2, RelationToSourceCopy()); EXPECT_NE(*a, na.begin()); delete[] a; EXPECT_EQ(0, na.begin()[0]); @@ -7357,7 +7372,7 @@ TEST(NativeArrayTest, TypeMembersAreCorrect) { TEST(NativeArrayTest, MethodsWork) { const int a[3] = { 0, 1, 2 }; - NativeArray na(a, 3, kCopy); + NativeArray na(a, 3, RelationToSourceCopy()); ASSERT_EQ(3U, na.size()); EXPECT_EQ(3, na.end() - na.begin()); @@ -7372,18 +7387,18 @@ TEST(NativeArrayTest, MethodsWork) { EXPECT_TRUE(na == na); - NativeArray na2(a, 3, kReference); + NativeArray na2(a, 3, RelationToSourceReference()); EXPECT_TRUE(na == na2); const int b1[3] = { 0, 1, 1 }; const int b2[4] = { 0, 1, 2, 3 }; - EXPECT_FALSE(na == NativeArray(b1, 3, kReference)); - EXPECT_FALSE(na == NativeArray(b2, 4, kCopy)); + EXPECT_FALSE(na == NativeArray(b1, 3, RelationToSourceReference())); + EXPECT_FALSE(na == NativeArray(b2, 4, RelationToSourceCopy())); } TEST(NativeArrayTest, WorksForTwoDimensionalArray) { const char a[2][3] = { "hi", "lo" }; - NativeArray na(a, 2, kReference); + NativeArray na(a, 2, RelationToSourceReference()); ASSERT_EQ(2U, na.size()); EXPECT_EQ(a, na.begin()); } @@ -7413,3 +7428,4 @@ TEST(SkipPrefixTest, DoesNotSkipWhenPrefixDoesNotMatch) { EXPECT_FALSE(SkipPrefix("world!", &p)); EXPECT_EQ(str, p); } + -- cgit v1.2.3 From b54098a9abade957ab3c4e94ae5e5225ef0015a4 Mon Sep 17 00:00:00 2001 From: kosak Date: Mon, 28 Jul 2014 21:54:50 +0000 Subject: Expand equality failure messages with a by-line diff. --- test/gtest_output_test_.cc | 5 ++ test/gtest_output_test_golden_lin.txt | 22 ++++++-- test/gtest_unittest.cc | 94 +++++++++++++++++++++++++++++++++++ 3 files changed, 116 insertions(+), 5 deletions(-) (limited to 'test') diff --git a/test/gtest_output_test_.cc b/test/gtest_output_test_.cc index 07ab633d..5361d8d8 100644 --- a/test/gtest_output_test_.cc +++ b/test/gtest_output_test_.cc @@ -113,6 +113,11 @@ TEST(NonfatalFailureTest, EscapesStringOperands) { EXPECT_EQ(golden, actual); } +TEST(NonfatalFailureTest, DiffForLongStrings) { + std::string golden_str(kGoldenString, sizeof(kGoldenString) - 1); + EXPECT_EQ(golden_str, "Line 2"); +} + // Tests catching a fatal failure in a subroutine. TEST(FatalFailureTest, FatalFailureInSubroutine) { printf("(expecting a failure that x should be 1)\n"); diff --git a/test/gtest_output_test_golden_lin.txt b/test/gtest_output_test_golden_lin.txt index 960eedce..da541700 100644 --- a/test/gtest_output_test_golden_lin.txt +++ b/test/gtest_output_test_golden_lin.txt @@ -7,7 +7,7 @@ Expected: true gtest_output_test_.cc:#: Failure Value of: 3 Expected: 2 -[==========] Running 63 tests from 28 test cases. +[==========] Running 64 tests from 28 test cases. [----------] Global test environment set-up. FooEnvironment::SetUp() called. BarEnvironment::SetUp() called. @@ -31,7 +31,7 @@ BarEnvironment::SetUp() called. [ OK ] PassingTest.PassingTest1 [ RUN ] PassingTest.PassingTest2 [ OK ] PassingTest.PassingTest2 -[----------] 1 test from NonfatalFailureTest +[----------] 2 tests from NonfatalFailureTest [ RUN ] NonfatalFailureTest.EscapesStringOperands gtest_output_test_.cc:#: Failure Value of: actual @@ -44,6 +44,17 @@ Value of: actual Expected: golden Which is: "\"Line" [ FAILED ] NonfatalFailureTest.EscapesStringOperands +[ RUN ] NonfatalFailureTest.DiffForLongStrings +gtest_output_test_.cc:#: Failure +Value of: "Line 2" +Expected: golden_str +Which is: "\"Line\0 1\"\nLine 2" +With diff: +@@ -1,2 @@ +-\"Line\0 1\" + Line 2 + +[ FAILED ] NonfatalFailureTest.DiffForLongStrings [----------] 3 tests from FatalFailureTest [ RUN ] FatalFailureTest.FatalFailureInSubroutine (expecting a failure that x should be 1) @@ -599,10 +610,11 @@ FooEnvironment::TearDown() called. gtest_output_test_.cc:#: Failure Failed Expected fatal failure. -[==========] 63 tests from 28 test cases ran. +[==========] 64 tests from 28 test cases ran. [ PASSED ] 21 tests. -[ FAILED ] 42 tests, listed below: +[ FAILED ] 43 tests, listed below: [ FAILED ] NonfatalFailureTest.EscapesStringOperands +[ FAILED ] NonfatalFailureTest.DiffForLongStrings [ FAILED ] FatalFailureTest.FatalFailureInSubroutine [ FAILED ] FatalFailureTest.FatalFailureInNestedSubroutine [ FAILED ] FatalFailureTest.NonfatalFailureInSubroutine @@ -645,7 +657,7 @@ Expected fatal failure. [ FAILED ] ScopedFakeTestPartResultReporterTest.InterceptOnlyCurrentThread [ FAILED ] PrintingFailingParams/FailingParamTest.Fails/0, where GetParam() = 2 -42 FAILED TESTS +43 FAILED TESTS  YOU HAVE 1 DISABLED TEST Note: Google Test filter = FatalFailureTest.*:LoggingTest.* diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index 6cccd018..42638ce2 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -282,6 +282,9 @@ using testing::internal::TestEventListenersAccessor; using testing::internal::TestResultAccessor; using testing::internal::UInt32; using testing::internal::WideStringToUtf8; +using testing::internal::edit_distance::CalculateOptimalEdits; +using testing::internal::edit_distance::CreateUnifiedDiff; +using testing::internal::edit_distance::EditType; using testing::internal::kMaxRandomSeed; using testing::internal::kTestTypeIdInGoogleTest; using testing::internal::scoped_ptr; @@ -3431,6 +3434,79 @@ TEST_F(NoFatalFailureTest, MessageIsStreamable) { // Tests non-string assertions. +std::string EditsToString(const std::vector& edits) { + std::string out; + for (size_t i = 0; i < edits.size(); ++i) { + static const char kEdits[] = " +-/"; + out.append(1, kEdits[edits[i]]); + } + return out; +} + +std::vector CharsToIndices(const std::string& str) { + std::vector out; + for (size_t i = 0; i < str.size(); ++i) { + out.push_back(str[i]); + } + return out; +} + +std::vector CharsToLines(const std::string& str) { + std::vector out; + for (size_t i = 0; i < str.size(); ++i) { + out.push_back(str.substr(i, 1)); + } + return out; +} + +TEST(EditDistance, TestCases) { + struct Case { + int line; + const char* left; + const char* right; + const char* expected_edits; + const char* expected_diff; + }; + static const Case kCases[] = { + // No change. + {__LINE__, "A", "A", " ", ""}, + {__LINE__, "ABCDE", "ABCDE", " ", ""}, + // Simple adds. + {__LINE__, "X", "XA", " +", "@@ +1,2 @@\n X\n+A\n"}, + {__LINE__, "X", "XABCD", " ++++", "@@ +1,5 @@\n X\n+A\n+B\n+C\n+D\n"}, + // Simple removes. + {__LINE__, "XA", "X", " -", "@@ -1,2 @@\n X\n-A\n"}, + {__LINE__, "XABCD", "X", " ----", "@@ -1,5 @@\n X\n-A\n-B\n-C\n-D\n"}, + // Simple replaces. + {__LINE__, "A", "a", "/", "@@ -1,1 +1,1 @@\n-A\n+a\n"}, + {__LINE__, "ABCD", "abcd", "////", + "@@ -1,4 +1,4 @@\n-A\n-B\n-C\n-D\n+a\n+b\n+c\n+d\n"}, + // Path finding. + {__LINE__, "ABCDEFGH", "ABXEGH1", " -/ - +", + "@@ -1,8 +1,7 @@\n A\n B\n-C\n-D\n+X\n E\n-F\n G\n H\n+1\n"}, + {__LINE__, "AAAABCCCC", "ABABCDCDC", "- / + / ", + "@@ -1,9 +1,9 @@\n-A\n A\n-A\n+B\n A\n B\n C\n+D\n C\n-C\n+D\n C\n"}, + {__LINE__, "ABCDE", "BCDCD", "- +/", + "@@ -1,5 +1,5 @@\n-A\n B\n C\n D\n-E\n+C\n+D\n"}, + {__LINE__, "ABCDEFGHIJKL", "BCDCDEFGJKLJK", "- ++ -- ++", + "@@ -1,4 +1,5 @@\n-A\n B\n+C\n+D\n C\n D\n" + "@@ -6,7 +7,7 @@\n F\n G\n-H\n-I\n J\n K\n L\n+J\n+K\n"}, + {}}; + for (const Case* c = kCases; c->left; ++c) { + EXPECT_TRUE(c->expected_edits == + EditsToString(CalculateOptimalEdits(CharsToIndices(c->left), + CharsToIndices(c->right)))) + << "Left <" << c->left << "> Right <" << c->right << "> Edits <" + << EditsToString(CalculateOptimalEdits( + CharsToIndices(c->left), CharsToIndices(c->right))) << ">"; + EXPECT_TRUE(c->expected_diff == CreateUnifiedDiff(CharsToLines(c->left), + CharsToLines(c->right))) + << "Left <" << c->left << "> Right <" << c->right << "> Diff <" + << CreateUnifiedDiff(CharsToLines(c->left), CharsToLines(c->right)) + << ">"; + } +} + // Tests EqFailure(), used for implementing *EQ* assertions. TEST(AssertionTest, EqFailure) { const std::string foo_val("5"), bar_val("6"); @@ -3481,6 +3557,24 @@ TEST(AssertionTest, EqFailure) { msg5.c_str()); } +TEST(AssertionTest, EqFailureWithDiff) { + const std::string left( + "1\\n2XXX\\n3\\n5\\n6\\n7\\n8\\n9\\n10\\n11\\n12XXX\\n13\\n14\\n15"); + const std::string right( + "1\\n2\\n3\\n4\\n5\\n6\\n7\\n8\\n9\\n11\\n12\\n13\\n14"); + const std::string msg1( + EqFailure("left", "right", left, right, false).failure_message()); + EXPECT_STREQ( + "Value of: right\n" + " Actual: 1\\n2\\n3\\n4\\n5\\n6\\n7\\n8\\n9\\n11\\n12\\n13\\n14\n" + "Expected: left\n" + "Which is: " + "1\\n2XXX\\n3\\n5\\n6\\n7\\n8\\n9\\n10\\n11\\n12XXX\\n13\\n14\\n15\n" + "With diff:\n@@ -1,5 +1,6 @@\n 1\n-2XXX\n+2\n 3\n+4\n 5\n 6\n" + "@@ -7,8 +8,6 @@\n 8\n 9\n-10\n 11\n-12XXX\n+12\n 13\n 14\n-15\n", + msg1.c_str()); +} + // Tests AppendUserMessage(), used for implementing the *EQ* macros. TEST(AssertionTest, AppendUserMessage) { const std::string foo("foo"); -- cgit v1.2.3 From 6aa0422e8529d76385b64f0a826f5ffd353fd37b Mon Sep 17 00:00:00 2001 From: kosak Date: Mon, 17 Nov 2014 00:27:28 +0000 Subject: Distinguish between C++11 language and library support for std::function, std::begin, std::end, and std::move in gtest and gmock. --- test/gtest-printers_test.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'test') diff --git a/test/gtest-printers_test.cc b/test/gtest-printers_test.cc index 7b07fd10..562a0a9a 100644 --- a/test/gtest-printers_test.cc +++ b/test/gtest-printers_test.cc @@ -1037,7 +1037,7 @@ TEST(PrintTr1TupleTest, NestedTuple) { #endif // GTEST_HAS_TR1_TUPLE -#if GTEST_LANG_CXX11 +#if GTEST_HAS_STD_TUPLE_ // Tests printing ::std::tuples. // Tuples of various arities. -- cgit v1.2.3 From e330b754cbd4b23a160521e05ff1014ed576378b Mon Sep 17 00:00:00 2001 From: kosak Date: Mon, 17 Nov 2014 02:28:09 +0000 Subject: Strip trailing whitespace when stringifying type lists. --- test/gtest-typed-test_test.cc | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'test') diff --git a/test/gtest-typed-test_test.cc b/test/gtest-typed-test_test.cc index c3e66c2d..93628ba0 100644 --- a/test/gtest-typed-test_test.cc +++ b/test/gtest-typed-test_test.cc @@ -344,6 +344,25 @@ REGISTER_TYPED_TEST_CASE_P(NumericTest, typedef Types NumericTypes; INSTANTIATE_TYPED_TEST_CASE_P(My, NumericTest, NumericTypes); +static const char* GetTestName() { + return testing::UnitTest::GetInstance()->current_test_info()->name(); +} +// Test the stripping of space from test names +template class TrimmedTest : public Test { }; +TYPED_TEST_CASE_P(TrimmedTest); +TYPED_TEST_P(TrimmedTest, Test1) { EXPECT_STREQ("Test1", GetTestName()); } +TYPED_TEST_P(TrimmedTest, Test2) { EXPECT_STREQ("Test2", GetTestName()); } +TYPED_TEST_P(TrimmedTest, Test3) { EXPECT_STREQ("Test3", GetTestName()); } +TYPED_TEST_P(TrimmedTest, Test4) { EXPECT_STREQ("Test4", GetTestName()); } +TYPED_TEST_P(TrimmedTest, Test5) { EXPECT_STREQ("Test5", GetTestName()); } +REGISTER_TYPED_TEST_CASE_P( + TrimmedTest, + Test1, Test2,Test3 , Test4 ,Test5 ); // NOLINT +template struct MyPair {}; +// Be sure to try a type with a comma in its name just in case it matters. +typedef Types > TrimTypes; +INSTANTIATE_TYPED_TEST_CASE_P(My, TrimmedTest, TrimTypes); + } // namespace library2 #endif // GTEST_HAS_TYPED_TEST_P -- cgit v1.2.3 From f8c44a0ae449dd78d703e94c295287d051560217 Mon Sep 17 00:00:00 2001 From: kosak Date: Tue, 28 Apr 2015 21:59:44 +0000 Subject: Work around some unsigned->signed warnings in our tests/. Thanks to Diego Barrios Romero . --- test/gtest-death-test_test.cc | 24 ++++++++++++------------ test/gtest-listener_test.cc | 11 ++++++----- test/gtest-port_test.cc | 4 ++-- 3 files changed, 20 insertions(+), 19 deletions(-) (limited to 'test') diff --git a/test/gtest-death-test_test.cc b/test/gtest-death-test_test.cc index b25bc229..d62cf6ef 100644 --- a/test/gtest-death-test_test.cc +++ b/test/gtest-death-test_test.cc @@ -887,9 +887,9 @@ class MockDeathTestFactory : public DeathTestFactory { // Accessors. int AssumeRoleCalls() const { return assume_role_calls_; } int WaitCalls() const { return wait_calls_; } - int PassedCalls() const { return passed_args_.size(); } + size_t PassedCalls() const { return passed_args_.size(); } bool PassedArgument(int n) const { return passed_args_[n]; } - int AbortCalls() const { return abort_args_.size(); } + size_t AbortCalls() const { return abort_args_.size(); } DeathTest::AbortReason AbortArgument(int n) const { return abort_args_[n]; } @@ -1050,8 +1050,8 @@ TEST_F(MacroLogicDeathTest, NothingHappens) { EXPECT_FALSE(flag); EXPECT_EQ(0, factory_->AssumeRoleCalls()); EXPECT_EQ(0, factory_->WaitCalls()); - EXPECT_EQ(0, factory_->PassedCalls()); - EXPECT_EQ(0, factory_->AbortCalls()); + EXPECT_EQ(0U, factory_->PassedCalls()); + EXPECT_EQ(0U, factory_->AbortCalls()); EXPECT_FALSE(factory_->TestDeleted()); } @@ -1065,9 +1065,9 @@ TEST_F(MacroLogicDeathTest, ChildExitsSuccessfully) { EXPECT_FALSE(flag); EXPECT_EQ(1, factory_->AssumeRoleCalls()); EXPECT_EQ(1, factory_->WaitCalls()); - ASSERT_EQ(1, factory_->PassedCalls()); + ASSERT_EQ(1U, factory_->PassedCalls()); EXPECT_FALSE(factory_->PassedArgument(0)); - EXPECT_EQ(0, factory_->AbortCalls()); + EXPECT_EQ(0U, factory_->AbortCalls()); EXPECT_TRUE(factory_->TestDeleted()); } @@ -1080,9 +1080,9 @@ TEST_F(MacroLogicDeathTest, ChildExitsUnsuccessfully) { EXPECT_FALSE(flag); EXPECT_EQ(1, factory_->AssumeRoleCalls()); EXPECT_EQ(1, factory_->WaitCalls()); - ASSERT_EQ(1, factory_->PassedCalls()); + ASSERT_EQ(1U, factory_->PassedCalls()); EXPECT_TRUE(factory_->PassedArgument(0)); - EXPECT_EQ(0, factory_->AbortCalls()); + EXPECT_EQ(0U, factory_->AbortCalls()); EXPECT_TRUE(factory_->TestDeleted()); } @@ -1096,8 +1096,8 @@ TEST_F(MacroLogicDeathTest, ChildPerformsReturn) { EXPECT_TRUE(flag); EXPECT_EQ(1, factory_->AssumeRoleCalls()); EXPECT_EQ(0, factory_->WaitCalls()); - EXPECT_EQ(0, factory_->PassedCalls()); - EXPECT_EQ(1, factory_->AbortCalls()); + EXPECT_EQ(0U, factory_->PassedCalls()); + EXPECT_EQ(1U, factory_->AbortCalls()); EXPECT_EQ(DeathTest::TEST_ENCOUNTERED_RETURN_STATEMENT, factory_->AbortArgument(0)); EXPECT_TRUE(factory_->TestDeleted()); @@ -1112,13 +1112,13 @@ TEST_F(MacroLogicDeathTest, ChildDoesNotDie) { EXPECT_TRUE(flag); EXPECT_EQ(1, factory_->AssumeRoleCalls()); EXPECT_EQ(0, factory_->WaitCalls()); - EXPECT_EQ(0, factory_->PassedCalls()); + EXPECT_EQ(0U, factory_->PassedCalls()); // This time there are two calls to Abort: one since the test didn't // die, and another from the ReturnSentinel when it's destroyed. The // sentinel normally isn't destroyed if a test doesn't die, since // _exit(2) is called in that case by ForkingDeathTest, but not by // our MockDeathTest. - ASSERT_EQ(2, factory_->AbortCalls()); + ASSERT_EQ(2U, factory_->AbortCalls()); EXPECT_EQ(DeathTest::TEST_DID_NOT_DIE, factory_->AbortArgument(0)); EXPECT_EQ(DeathTest::TEST_ENCOUNTERED_RETURN_STATEMENT, diff --git a/test/gtest-listener_test.cc b/test/gtest-listener_test.cc index 99662cff..90747685 100644 --- a/test/gtest-listener_test.cc +++ b/test/gtest-listener_test.cc @@ -176,16 +176,16 @@ using ::testing::internal::EventRecordingListener; void VerifyResults(const std::vector& data, const char* const* expected_data, - int expected_data_size) { - const int actual_size = data.size(); + size_t expected_data_size) { + const size_t actual_size = data.size(); // If the following assertion fails, a new entry will be appended to // data. Hence we save data.size() first. EXPECT_EQ(expected_data_size, actual_size); // Compares the common prefix. - const int shorter_size = expected_data_size <= actual_size ? + const size_t shorter_size = expected_data_size <= actual_size ? expected_data_size : actual_size; - int i = 0; + size_t i = 0; for (; i < shorter_size; ++i) { ASSERT_STREQ(expected_data[i], data[i].c_str()) << "at position " << i; @@ -193,7 +193,8 @@ void VerifyResults(const std::vector& data, // Prints extra elements in the actual data. for (; i < actual_size; ++i) { - printf(" Actual event #%d: %s\n", i, data[i].c_str()); + printf(" Actual event #%lu: %s\n", + static_cast(i), data[i].c_str()); } } diff --git a/test/gtest-port_test.cc b/test/gtest-port_test.cc index 370c952b..c904f1e7 100644 --- a/test/gtest-port_test.cc +++ b/test/gtest-port_test.cc @@ -1219,11 +1219,11 @@ class DestructorTracker { } private: - static int GetNewIndex() { + static size_t GetNewIndex() { DestructorCall::List().push_back(new DestructorCall); return DestructorCall::List().size() - 1; } - const int index_; + const size_t index_; GTEST_DISALLOW_ASSIGN_(DestructorTracker); }; -- cgit v1.2.3 From 1197daf3571161590dce2bc4879512ef7bc1ba67 Mon Sep 17 00:00:00 2001 From: kosak Date: Tue, 28 Apr 2015 22:04:35 +0000 Subject: urxvt supports colors --- test/gtest_unittest.cc | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'test') diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index 42638ce2..5509a6b2 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -6672,6 +6672,12 @@ TEST(ColoredOutputTest, UsesColorsWhenTermSupportsColors) { SetEnv("TERM", "screen-256color"); // TERM supports colors. EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY. + SetEnv("TERM", "rxvt-unicode"); // TERM supports colors. + EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY. + + SetEnv("TERM", "rxvt-unicode-256color"); // TERM supports colors. + EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY. + SetEnv("TERM", "linux"); // TERM supports colors. EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY. -- cgit v1.2.3 From 0f3d673be15d7e6e01dccc9a7e66097fe7592c8f Mon Sep 17 00:00:00 2001 From: kosak Date: Mon, 13 Jul 2015 21:33:41 +0000 Subject: fully-qualify use of scoped_ptr name --- test/gtest_output_test_.cc | 4 ++-- test/gtest_unittest.cc | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) (limited to 'test') diff --git a/test/gtest_output_test_.cc b/test/gtest_output_test_.cc index 5361d8d8..adeb42c8 100644 --- a/test/gtest_output_test_.cc +++ b/test/gtest_output_test_.cc @@ -58,7 +58,6 @@ using testing::internal::ThreadWithParam; #endif namespace posix = ::testing::internal::posix; -using testing::internal::scoped_ptr; // Tests catching fatal failures. @@ -515,7 +514,8 @@ class DeathTestAndMultiThreadsTest : public testing::Test { private: SpawnThreadNotifications notifications_; - scoped_ptr > thread_; + testing::internal::scoped_ptr > + thread_; }; #endif // GTEST_IS_THREADSAFE diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index 5509a6b2..774fa833 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -287,7 +287,6 @@ using testing::internal::edit_distance::CreateUnifiedDiff; using testing::internal::edit_distance::EditType; using testing::internal::kMaxRandomSeed; using testing::internal::kTestTypeIdInGoogleTest; -using testing::internal::scoped_ptr; using testing::kMaxStackTraceDepth; #if GTEST_HAS_STREAM_REDIRECTION -- cgit v1.2.3 From 1e4d31008ff9e095de3ff35a3db7b66773eab54f Mon Sep 17 00:00:00 2001 From: kosak Date: Tue, 14 Jul 2015 20:26:09 +0000 Subject: Control death test with an #ifdef guard. --- test/gtest-death-test_test.cc | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'test') diff --git a/test/gtest-death-test_test.cc b/test/gtest-death-test_test.cc index d62cf6ef..bb4a3d1b 100644 --- a/test/gtest-death-test_test.cc +++ b/test/gtest-death-test_test.cc @@ -510,8 +510,12 @@ TEST_F(TestForDeathTest, AcceptsAnythingConvertibleToRE) { # endif // GTEST_HAS_GLOBAL_STRING +# if !GTEST_USES_PCRE + const ::std::string regex_std_str(regex_c_str); EXPECT_DEATH(GlobalFunction(), regex_std_str); + +# endif // !GTEST_USES_PCRE } // Tests that a non-void function can be used in a death test. -- cgit v1.2.3 From fb9caa4a18853ed3fc404c3ba5c47c9be695eae7 Mon Sep 17 00:00:00 2001 From: kosak Date: Tue, 14 Jul 2015 20:44:00 +0000 Subject: Minor changes. --- test/gtest_unittest.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'test') diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index 774fa833..8f8abb35 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -6333,7 +6333,7 @@ TEST_F(InitGoogleTestTest, WideStrings) { GTEST_TEST_PARSING_FLAGS_(argv, argv2, expected_flags, false); } -#endif // GTEST_OS_WINDOWS +# endif // GTEST_OS_WINDOWS // Tests current_test_info() in UnitTest. class CurrentTestInfoTest : public Test { -- cgit v1.2.3 From 54566c2573cbd1e2b416717e85f26ebf38efc5ec Mon Sep 17 00:00:00 2001 From: kosak Date: Tue, 14 Jul 2015 20:52:01 +0000 Subject: Remove TestPrematureExitFileEnvVarIsSet --- test/gtest_premature_exit_test.cc | 16 ---------------- 1 file changed, 16 deletions(-) (limited to 'test') diff --git a/test/gtest_premature_exit_test.cc b/test/gtest_premature_exit_test.cc index c1ed9686..3b4dc7d4 100644 --- a/test/gtest_premature_exit_test.cc +++ b/test/gtest_premature_exit_test.cc @@ -44,10 +44,6 @@ using ::testing::internal::posix::StatStruct; namespace { -// Is the TEST_PREMATURE_EXIT_FILE environment variable expected to be -// set? -const bool kTestPrematureExitFileEnvVarShouldBeSet = false; - class PrematureExitTest : public Test { public: // Returns true iff the given file exists. @@ -97,18 +93,6 @@ TEST_F(PrematureExitDeathTest, FileExistsDuringExecutionOfDeathTest) { }, ""); } -// Tests that TEST_PREMATURE_EXIT_FILE is set where it's expected to -// be set. -TEST_F(PrematureExitTest, TestPrematureExitFileEnvVarIsSet) { - GTEST_INTENTIONAL_CONST_COND_PUSH_() - if (kTestPrematureExitFileEnvVarShouldBeSet) { - GTEST_INTENTIONAL_CONST_COND_POP_() - const char* const filepath = GetEnv("TEST_PREMATURE_EXIT_FILE"); - ASSERT_TRUE(filepath != NULL); - ASSERT_NE(*filepath, '\0'); - } -} - // Tests that the premature-exit file exists during the execution of a // normal (non-death) test. TEST_F(PrematureExitTest, PrematureExitFileExistsDuringTestExecution) { -- cgit v1.2.3 From 1cc9514de5a9b361e7a000eb34da9175b6de0593 Mon Sep 17 00:00:00 2001 From: kosak Date: Tue, 14 Jul 2015 20:58:40 +0000 Subject: Add comment. --- test/gtest_unittest.cc | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'test') diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index 8f8abb35..b3ee60a5 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -1517,6 +1517,16 @@ TEST(TestResultPropertyTest, GetTestProperty) { EXPECT_DEATH_IF_SUPPORTED(test_result.GetTestProperty(-1), ""); } +// Tests the Test class. +// +// It's difficult to test every public method of this class (we are +// already stretching the limit of Google Test by using it to test itself!). +// Fortunately, we don't have to do that, as we are already testing +// the functionalities of the Test class extensively by using Google Test +// alone. +// +// Therefore, this section only contains one test. + // Tests that GTestFlagSaver works on Windows and Mac. class GTestFlagSaverTest : public Test { -- cgit v1.2.3 From f025eba07ba75b7fc059838d58880e661dea577a Mon Sep 17 00:00:00 2001 From: kosak Date: Tue, 14 Jul 2015 21:26:09 +0000 Subject: Add support for gtest custom printers. --- test/gtest-printers_test.cc | 46 +++++++++++++++------------------------------ 1 file changed, 15 insertions(+), 31 deletions(-) (limited to 'test') diff --git a/test/gtest-printers_test.cc b/test/gtest-printers_test.cc index 562a0a9a..a6636c57 100644 --- a/test/gtest-printers_test.cc +++ b/test/gtest-printers_test.cc @@ -58,6 +58,10 @@ # include // NOLINT #endif // GTEST_OS_WINDOWS +#if GTEST_HAS_STD_FORWARD_LIST_ +# include // NOLINT +#endif // GTEST_HAS_STD_FORWARD_LIST_ + // Some user-defined types for testing the universal value printer. // An anonymous enum type. @@ -913,6 +917,17 @@ TEST(PrintStlContainerTest, MultiSet) { EXPECT_EQ("{ 1, 1, 1, 2, 5 }", Print(set1)); } +#if GTEST_HAS_STD_FORWARD_LIST_ +// is available on Linux in the google3 mode, but not on +// Windows or Mac OS X. + +TEST(PrintStlContainerTest, SinglyLinkedList) { + int a[] = { 9, 2, 8 }; + const std::forward_list ints(a, a + 3); + EXPECT_EQ("{ 9, 2, 8 }", Print(ints)); +} +#endif // GTEST_HAS_STD_FORWARD_LIST_ + TEST(PrintStlContainerTest, Pair) { pair p(true, 5); EXPECT_EQ("(true, 5)", Print(p)); @@ -1162,37 +1177,6 @@ TEST(PrintPrintableTypeTest, TemplateInUserNamespace) { Print(::foo::PrintableViaPrintToTemplate(5))); } -#if GTEST_HAS_PROTOBUF_ - -// Tests printing a short proto2 message. -TEST(PrintProto2MessageTest, PrintsShortDebugStringWhenItIsShort) { - testing::internal::FooMessage msg; - msg.set_int_field(2); - msg.set_string_field("hello"); - EXPECT_PRED2(RE::FullMatch, Print(msg), - ""); -} - -// Tests printing a long proto2 message. -TEST(PrintProto2MessageTest, PrintsDebugStringWhenItIsLong) { - testing::internal::FooMessage msg; - msg.set_int_field(2); - msg.set_string_field("hello"); - msg.add_names("peter"); - msg.add_names("paul"); - msg.add_names("mary"); - EXPECT_PRED2(RE::FullMatch, Print(msg), - "<\n" - "int_field:\\s*2\n" - "string_field:\\s*\"hello\"\n" - "names:\\s*\"peter\"\n" - "names:\\s*\"paul\"\n" - "names:\\s*\"mary\"\n" - ">"); -} - -#endif // GTEST_HAS_PROTOBUF_ - // Tests that the universal printer prints both the address and the // value of a reference. TEST(PrintReferenceTest, PrintsAddressAndValue) { -- cgit v1.2.3 From 80167de7055d61ed54808995fb7d632781a5f70e Mon Sep 17 00:00:00 2001 From: kosak Date: Tue, 14 Jul 2015 22:29:59 +0000 Subject: Minor refactoring. --- test/gtest_output_test.py | 15 ++++++++++----- test/gtest_output_test_.cc | 11 ++++------- 2 files changed, 14 insertions(+), 12 deletions(-) (limited to 'test') diff --git a/test/gtest_output_test.py b/test/gtest_output_test.py index fa1a3117..d5c637b4 100755 --- a/test/gtest_output_test.py +++ b/test/gtest_output_test.py @@ -40,6 +40,7 @@ SYNOPSIS __author__ = 'wan@google.com (Zhanyong Wan)' +import difflib import os import re import sys @@ -58,22 +59,22 @@ GOLDEN_NAME = 'gtest_output_test_golden_lin.txt' PROGRAM_PATH = gtest_test_utils.GetTestExecutablePath('gtest_output_test_') # At least one command we exercise must not have the -# --gtest_internal_skip_environment_and_ad_hoc_tests flag. +# 'internal_skip_environment_and_ad_hoc_tests' argument. COMMAND_LIST_TESTS = ({}, [PROGRAM_PATH, '--gtest_list_tests']) COMMAND_WITH_COLOR = ({}, [PROGRAM_PATH, '--gtest_color=yes']) COMMAND_WITH_TIME = ({}, [PROGRAM_PATH, '--gtest_print_time', - '--gtest_internal_skip_environment_and_ad_hoc_tests', + 'internal_skip_environment_and_ad_hoc_tests', '--gtest_filter=FatalFailureTest.*:LoggingTest.*']) COMMAND_WITH_DISABLED = ( {}, [PROGRAM_PATH, '--gtest_also_run_disabled_tests', - '--gtest_internal_skip_environment_and_ad_hoc_tests', + 'internal_skip_environment_and_ad_hoc_tests', '--gtest_filter=*DISABLED_*']) COMMAND_WITH_SHARDING = ( {'GTEST_SHARD_INDEX': '1', 'GTEST_TOTAL_SHARDS': '2'}, [PROGRAM_PATH, - '--gtest_internal_skip_environment_and_ad_hoc_tests', + 'internal_skip_environment_and_ad_hoc_tests', '--gtest_filter=PassingTest.*']) GOLDEN_PATH = os.path.join(gtest_test_utils.GetSourceDir(), GOLDEN_NAME) @@ -294,7 +295,11 @@ class GTestOutputTest(gtest_test_utils.TestCase): normalized_golden = RemoveTypeInfoDetails(golden) if CAN_GENERATE_GOLDEN_FILE: - self.assertEqual(normalized_golden, normalized_actual) + self.assertEqual(normalized_golden, normalized_actual, + '\n'.join(difflib.unified_diff( + normalized_golden.split('\n'), + normalized_actual.split('\n'), + 'golden', 'actual'))) else: normalized_actual = NormalizeToCurrentPlatform( RemoveTestCounts(normalized_actual)) diff --git a/test/gtest_output_test_.cc b/test/gtest_output_test_.cc index adeb42c8..a619459c 100644 --- a/test/gtest_output_test_.cc +++ b/test/gtest_output_test_.cc @@ -990,8 +990,6 @@ class BarEnvironment : public testing::Environment { } }; -bool GTEST_FLAG(internal_skip_environment_and_ad_hoc_tests) = false; - // The main function. // // The idea is to use Google Test to run all the tests we have defined (some @@ -1008,10 +1006,9 @@ int main(int argc, char **argv) { // global side effects. The following line serves as a sanity test // for it. testing::InitGoogleTest(&argc, argv); - if (argc >= 2 && - (std::string(argv[1]) == - "--gtest_internal_skip_environment_and_ad_hoc_tests")) - GTEST_FLAG(internal_skip_environment_and_ad_hoc_tests) = true; + bool internal_skip_environment_and_ad_hoc_tests = + std::count(argv, argv + argc, + std::string("internal_skip_environment_and_ad_hoc_tests")) > 0; #if GTEST_HAS_DEATH_TEST if (testing::internal::GTEST_FLAG(internal_run_death_test) != "") { @@ -1026,7 +1023,7 @@ int main(int argc, char **argv) { } #endif // GTEST_HAS_DEATH_TEST - if (GTEST_FLAG(internal_skip_environment_and_ad_hoc_tests)) + if (internal_skip_environment_and_ad_hoc_tests) return RUN_ALL_TESTS(); // Registers two global test environments. -- cgit v1.2.3 From 195610d30c2234b76bef70a85426ac8d7dbdf9f3 Mon Sep 17 00:00:00 2001 From: kosak Date: Fri, 17 Jul 2015 21:56:19 +0000 Subject: Add support for --gtest_flagfile --- test/gtest-filepath_test.cc | 18 --------- test/gtest_unittest.cc | 99 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 99 insertions(+), 18 deletions(-) (limited to 'test') diff --git a/test/gtest-filepath_test.cc b/test/gtest-filepath_test.cc index ae9f55a0..da729869 100644 --- a/test/gtest-filepath_test.cc +++ b/test/gtest-filepath_test.cc @@ -514,24 +514,6 @@ class DirectoryCreationTest : public Test { posix::RmDir(testdata_path_.c_str()); } - std::string TempDir() const { -#if GTEST_OS_WINDOWS_MOBILE - return "\\temp\\"; -#elif GTEST_OS_WINDOWS - const char* temp_dir = posix::GetEnv("TEMP"); - if (temp_dir == NULL || temp_dir[0] == '\0') - return "\\temp\\"; - else if (temp_dir[strlen(temp_dir) - 1] == '\\') - return temp_dir; - else - return std::string(temp_dir) + "\\"; -#elif GTEST_OS_LINUX_ANDROID - return "/sdcard/"; -#else - return "/tmp/"; -#endif // GTEST_OS_WINDOWS_MOBILE - } - void CreateTextFile(const char* filename) { FILE* f = posix::FOpen(filename, "w"); fprintf(f, "text\n"); diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index b3ee60a5..71a6a965 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -6345,6 +6345,105 @@ TEST_F(InitGoogleTestTest, WideStrings) { } # endif // GTEST_OS_WINDOWS +class FlagfileTest : public InitGoogleTestTest { + public: + virtual void SetUp() { + InitGoogleTestTest::SetUp(); + + testdata_path_.Set(internal::FilePath( + internal::TempDir() + internal::GetCurrentExecutableName().string() + + "_flagfile_test")); + testing::internal::posix::RmDir(testdata_path_.c_str()); + EXPECT_TRUE(testdata_path_.CreateFolder()); + } + + virtual void TearDown() { + testing::internal::posix::RmDir(testdata_path_.c_str()); + InitGoogleTestTest::TearDown(); + } + + internal::FilePath CreateFlagfile(const char* contents) { + internal::FilePath file_path(internal::FilePath::GenerateUniqueFileName( + testdata_path_, internal::FilePath("unique"), "txt")); + FILE* f = testing::internal::posix::FOpen(file_path.c_str(), "w"); + fprintf(f, "%s", contents); + fclose(f); + return file_path; + } + + private: + internal::FilePath testdata_path_; +}; + +// Tests an empty flagfile. +TEST_F(FlagfileTest, Empty) { + internal::FilePath flagfile_path(CreateFlagfile("")); + std::string flagfile_flag = + std::string("--" GTEST_FLAG_PREFIX_ "flagfile=") + flagfile_path.c_str(); + + const char* argv[] = { + "foo.exe", + flagfile_flag.c_str(), + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags(), false); +} + +// Tests passing a non-empty --gtest_filter flag via --gtest_flagfile. +TEST_F(FlagfileTest, FilterNonEmpty) { + internal::FilePath flagfile_path(CreateFlagfile( + "--" GTEST_FLAG_PREFIX_ "filter=abc")); + std::string flagfile_flag = + std::string("--" GTEST_FLAG_PREFIX_ "flagfile=") + flagfile_path.c_str(); + + const char* argv[] = { + "foo.exe", + flagfile_flag.c_str(), + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Filter("abc"), false); +} + +// Tests passing several flags via --gtest_flagfile. +TEST_F(FlagfileTest, SeveralFlags) { + internal::FilePath flagfile_path(CreateFlagfile( + "--" GTEST_FLAG_PREFIX_ "filter=abc\n" + "--" GTEST_FLAG_PREFIX_ "break_on_failure\n" + "--" GTEST_FLAG_PREFIX_ "list_tests")); + std::string flagfile_flag = + std::string("--" GTEST_FLAG_PREFIX_ "flagfile=") + flagfile_path.c_str(); + + const char* argv[] = { + "foo.exe", + flagfile_flag.c_str(), + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + Flags expected_flags; + expected_flags.break_on_failure = true; + expected_flags.filter = "abc"; + expected_flags.list_tests = true; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, expected_flags, false); +} + // Tests current_test_info() in UnitTest. class CurrentTestInfoTest : public Test { protected: -- cgit v1.2.3 From 4f8dc917ebce062f75defee3d4890bbcd07e277b Mon Sep 17 00:00:00 2001 From: kosak Date: Fri, 17 Jul 2015 22:11:58 +0000 Subject: Add support for --gtest_flagfile. --- test/gtest_unittest.cc | 56 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 55 insertions(+), 1 deletion(-) (limited to 'test') diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index 71a6a965..88130dfa 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -94,7 +94,8 @@ class StreamingListenerTest : public Test { StreamingListenerTest() : fake_sock_writer_(new FakeSocketWriter), streamer_(fake_sock_writer_), - test_info_obj_("FooTest", "Bar", NULL, NULL, 0, NULL) {} + test_info_obj_("FooTest", "Bar", NULL, NULL, + CodeLocation(__FILE__, __LINE__), 0, NULL) {} protected: string* output() { return &(fake_sock_writer_->output_); } @@ -5328,6 +5329,59 @@ TEST_F(TestInfoTest, result) { ASSERT_EQ(0, GetTestResult(test_info)->total_part_count()); } +#define VERIFY_CODE_LOCATION \ + const int expected_line = __LINE__ - 1; \ + const TestInfo* const test_info = GetUnitTestImpl()->current_test_info(); \ + ASSERT_TRUE(test_info); \ + EXPECT_STREQ(__FILE__, test_info->file()); \ + EXPECT_EQ(expected_line, test_info->line()) + +TEST(CodeLocationForTEST, Verify) { + VERIFY_CODE_LOCATION; +} + +class CodeLocationForTESTF : public Test { +}; + +TEST_F(CodeLocationForTESTF, Verify) { + VERIFY_CODE_LOCATION; +} + +class CodeLocationForTESTP : public TestWithParam { +}; + +TEST_P(CodeLocationForTESTP, Verify) { + VERIFY_CODE_LOCATION; +} + +INSTANTIATE_TEST_CASE_P(, CodeLocationForTESTP, Values(0)); + +template +class CodeLocationForTYPEDTEST : public Test { +}; + +TYPED_TEST_CASE(CodeLocationForTYPEDTEST, int); + +TYPED_TEST(CodeLocationForTYPEDTEST, Verify) { + VERIFY_CODE_LOCATION; +} + +template +class CodeLocationForTYPEDTESTP : public Test { +}; + +TYPED_TEST_CASE_P(CodeLocationForTYPEDTESTP); + +TYPED_TEST_P(CodeLocationForTYPEDTESTP, Verify) { + VERIFY_CODE_LOCATION; +} + +REGISTER_TYPED_TEST_CASE_P(CodeLocationForTYPEDTESTP, Verify); + +INSTANTIATE_TYPED_TEST_CASE_P(My, CodeLocationForTYPEDTESTP, int); + +#undef VERIFY_CODE_LOCATION + // Tests setting up and tearing down a test case. class SetUpTestCaseTest : public Test { -- cgit v1.2.3 From 060b7452ec0f3f0a7fa09914e4044349dc9990c6 Mon Sep 17 00:00:00 2001 From: kosak Date: Fri, 17 Jul 2015 22:53:00 +0000 Subject: Implement GetThreadCount for Linux. --- test/gtest-port_test.cc | 49 +++++++++++++++++++++---------------------------- 1 file changed, 21 insertions(+), 28 deletions(-) (limited to 'test') diff --git a/test/gtest-port_test.cc b/test/gtest-port_test.cc index c904f1e7..7647859e 100644 --- a/test/gtest-port_test.cc +++ b/test/gtest-port_test.cc @@ -304,58 +304,51 @@ TEST(FormatCompilerIndependentFileLocationTest, FormatsUknownFileAndLine) { EXPECT_EQ("unknown file", FormatCompilerIndependentFileLocation(NULL, -1)); } -#if GTEST_OS_MAC || GTEST_OS_QNX +#if GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_QNX void* ThreadFunc(void* data) { - pthread_mutex_t* mutex = static_cast(data); - pthread_mutex_lock(mutex); - pthread_mutex_unlock(mutex); + internal::Mutex* mutex = static_cast(data); + mutex->Lock(); + mutex->Unlock(); return NULL; } TEST(GetThreadCountTest, ReturnsCorrectValue) { - EXPECT_EQ(1U, GetThreadCount()); - pthread_mutex_t mutex; - pthread_attr_t attr; + const size_t starting_count = GetThreadCount(); pthread_t thread_id; - // TODO(vladl@google.com): turn mutex into internal::Mutex for automatic - // destruction. - pthread_mutex_init(&mutex, NULL); - pthread_mutex_lock(&mutex); - ASSERT_EQ(0, pthread_attr_init(&attr)); - ASSERT_EQ(0, pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE)); - - const int status = pthread_create(&thread_id, &attr, &ThreadFunc, &mutex); - ASSERT_EQ(0, pthread_attr_destroy(&attr)); - ASSERT_EQ(0, status); - EXPECT_EQ(2U, GetThreadCount()); - pthread_mutex_unlock(&mutex); + internal::Mutex mutex; + { + internal::MutexLock lock(&mutex); + pthread_attr_t attr; + ASSERT_EQ(0, pthread_attr_init(&attr)); + ASSERT_EQ(0, pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE)); + + const int status = pthread_create(&thread_id, &attr, &ThreadFunc, &mutex); + ASSERT_EQ(0, pthread_attr_destroy(&attr)); + ASSERT_EQ(0, status); + EXPECT_EQ(starting_count + 1, GetThreadCount()); + } void* dummy; ASSERT_EQ(0, pthread_join(thread_id, &dummy)); -# if GTEST_OS_MAC - - // MacOS X may not immediately report the updated thread count after + // The OS may not immediately report the updated thread count after // joining a thread, causing flakiness in this test. To counter that, we // wait for up to .5 seconds for the OS to report the correct value. for (int i = 0; i < 5; ++i) { - if (GetThreadCount() == 1) + if (GetThreadCount() == starting_count) break; SleepMilliseconds(100); } -# endif // GTEST_OS_MAC - - EXPECT_EQ(1U, GetThreadCount()); - pthread_mutex_destroy(&mutex); + EXPECT_EQ(starting_count, GetThreadCount()); } #else TEST(GetThreadCountTest, ReturnsZeroWhenUnableToCountThreads) { EXPECT_EQ(0U, GetThreadCount()); } -#endif // GTEST_OS_MAC || GTEST_OS_QNX +#endif // GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_QNX TEST(GtestCheckDeathTest, DiesWithCorrectOutputOnFailure) { const bool a_false_condition = false; -- cgit v1.2.3 From fe95bc332d92c6e3f5c2e07fd681bd3549b77374 Mon Sep 17 00:00:00 2001 From: kosak Date: Fri, 17 Jul 2015 23:08:48 +0000 Subject: Determine the existence of hash_map/hash_set in gtest-port.h. --- test/gtest-printers_test.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'test') diff --git a/test/gtest-printers_test.cc b/test/gtest-printers_test.cc index a6636c57..3e97cc24 100644 --- a/test/gtest-printers_test.cc +++ b/test/gtest-printers_test.cc @@ -50,13 +50,13 @@ #include "gtest/gtest.h" -// hash_map and hash_set are available under Visual C++. -#if _MSC_VER -# define GTEST_HAS_HASH_MAP_ 1 // Indicates that hash_map is available. +// hash_map and hash_set are available under Visual C++, or on Linux. +#if GTEST_HAS_HASH_MAP_ # include // NOLINT -# define GTEST_HAS_HASH_SET_ 1 // Indicates that hash_set is available. +#endif // GTEST_HAS_HASH_MAP_ +#if GTEST_HAS_HASH_SET_ # include // NOLINT -#endif // GTEST_OS_WINDOWS +#endif // GTEST_HAS_HASH_SET_ #if GTEST_HAS_STD_FORWARD_LIST_ # include // NOLINT -- cgit v1.2.3 From 4d69b1607a876a77b8719f035b23254677617a47 Mon Sep 17 00:00:00 2001 From: kosak Date: Sun, 19 Jul 2015 21:50:45 +0000 Subject: GTEST_USE_OWN_FLAGFILE support --- test/gtest_unittest.cc | 2 ++ 1 file changed, 2 insertions(+) (limited to 'test') diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index 88130dfa..dd7f19f4 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -6399,6 +6399,7 @@ TEST_F(InitGoogleTestTest, WideStrings) { } # endif // GTEST_OS_WINDOWS +#if GTEST_USE_OWN_FLAGFILE_FLAG_ class FlagfileTest : public InitGoogleTestTest { public: virtual void SetUp() { @@ -6497,6 +6498,7 @@ TEST_F(FlagfileTest, SeveralFlags) { GTEST_TEST_PARSING_FLAGS_(argv, argv2, expected_flags, false); } +#endif // GTEST_USE_OWN_FLAGFILE_FLAG_ // Tests current_test_info() in UnitTest. class CurrentTestInfoTest : public Test { -- cgit v1.2.3 From 7d7beaa155717adafb783a52b6dfa37fae15df3f Mon Sep 17 00:00:00 2001 From: kosak Date: Sun, 19 Jul 2015 22:05:06 +0000 Subject: Condition some code on !GTEST_HAS_MUTEX_AND_THREAD_LOCAL_ --- test/gtest-port_test.cc | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'test') diff --git a/test/gtest-port_test.cc b/test/gtest-port_test.cc index 7647859e..937832bb 100644 --- a/test/gtest-port_test.cc +++ b/test/gtest-port_test.cc @@ -1149,6 +1149,13 @@ TEST(ThreadLocalTest, ParameterizedConstructorSetsDefault) { EXPECT_STREQ("foo", result.c_str()); } +# if !GTEST_HAS_MUTEX_AND_THREAD_LOCAL_ + +// Tests in this section depend on that Google Test's own ThreadLocal +// implementation stores a copy of the default value shared by all +// threads. We don't want to test this for an external implementation received +// through GTEST_HAS_MUTEX_AND_THREAD_LOCAL_. + // Keeps track of whether of destructors being called on instances of // DestructorTracker. On Windows, waits for the destructor call reports. class DestructorCall { @@ -1289,6 +1296,8 @@ TEST(ThreadLocalTest, DestroysManagedObjectAtThreadExit) { DestructorCall::ResetList(); } +# endif // !GTEST_HAS_MUTEX_AND_THREAD_LOCAL_ + TEST(ThreadLocalTest, ThreadLocalMutationsAffectOnlyCurrentThread) { ThreadLocal thread_local_string; thread_local_string.set("Foo"); -- cgit v1.2.3 From 831b87f2342df0ee2d13c466b400245bdf1c04f3 Mon Sep 17 00:00:00 2001 From: kosak Date: Sun, 19 Jul 2015 22:33:19 +0000 Subject: Do not create an extra default instance of T when constructing a ThreadLocal. --- test/gtest-port_test.cc | 41 +++++++++-------------------------------- 1 file changed, 9 insertions(+), 32 deletions(-) (limited to 'test') diff --git a/test/gtest-port_test.cc b/test/gtest-port_test.cc index 937832bb..14418804 100644 --- a/test/gtest-port_test.cc +++ b/test/gtest-port_test.cc @@ -1149,13 +1149,6 @@ TEST(ThreadLocalTest, ParameterizedConstructorSetsDefault) { EXPECT_STREQ("foo", result.c_str()); } -# if !GTEST_HAS_MUTEX_AND_THREAD_LOCAL_ - -// Tests in this section depend on that Google Test's own ThreadLocal -// implementation stores a copy of the default value shared by all -// threads. We don't want to test this for an external implementation received -// through GTEST_HAS_MUTEX_AND_THREAD_LOCAL_. - // Keeps track of whether of destructors being called on instances of // DestructorTracker. On Windows, waits for the destructor call reports. class DestructorCall { @@ -1240,25 +1233,18 @@ TEST(ThreadLocalTest, DestroysManagedObjectForOwnThreadWhenDying) { DestructorCall::ResetList(); { - // The next line default constructs a DestructorTracker object as - // the default value of objects managed by thread_local_tracker. ThreadLocal thread_local_tracker; - ASSERT_EQ(1U, DestructorCall::List().size()); - ASSERT_FALSE(DestructorCall::List()[0]->CheckDestroyed()); + ASSERT_EQ(0U, DestructorCall::List().size()); // This creates another DestructorTracker object for the main thread. thread_local_tracker.get(); - ASSERT_EQ(2U, DestructorCall::List().size()); + ASSERT_EQ(1U, DestructorCall::List().size()); ASSERT_FALSE(DestructorCall::List()[0]->CheckDestroyed()); - ASSERT_FALSE(DestructorCall::List()[1]->CheckDestroyed()); } - // Now thread_local_tracker has died. It should have destroyed both the - // default value shared by all threads and the value for the main - // thread. - ASSERT_EQ(2U, DestructorCall::List().size()); + // Now thread_local_tracker has died. + ASSERT_EQ(1U, DestructorCall::List().size()); EXPECT_TRUE(DestructorCall::List()[0]->CheckDestroyed()); - EXPECT_TRUE(DestructorCall::List()[1]->CheckDestroyed()); DestructorCall::ResetList(); } @@ -1269,35 +1255,26 @@ TEST(ThreadLocalTest, DestroysManagedObjectAtThreadExit) { DestructorCall::ResetList(); { - // The next line default constructs a DestructorTracker object as - // the default value of objects managed by thread_local_tracker. ThreadLocal thread_local_tracker; - ASSERT_EQ(1U, DestructorCall::List().size()); - ASSERT_FALSE(DestructorCall::List()[0]->CheckDestroyed()); + ASSERT_EQ(0U, DestructorCall::List().size()); // This creates another DestructorTracker object in the new thread. ThreadWithParam thread( &CallThreadLocalGet, &thread_local_tracker, NULL); thread.Join(); - // The thread has exited, and we should have another DestroyedTracker + // The thread has exited, and we should have a DestroyedTracker // instance created for it. But it may not have been destroyed yet. - // The instance for the main thread should still persist. - ASSERT_EQ(2U, DestructorCall::List().size()); - ASSERT_FALSE(DestructorCall::List()[0]->CheckDestroyed()); + ASSERT_EQ(1U, DestructorCall::List().size()); } - // The thread has exited and thread_local_tracker has died. The default - // value should have been destroyed too. - ASSERT_EQ(2U, DestructorCall::List().size()); + // The thread has exited and thread_local_tracker has died. + ASSERT_EQ(1U, DestructorCall::List().size()); EXPECT_TRUE(DestructorCall::List()[0]->CheckDestroyed()); - EXPECT_TRUE(DestructorCall::List()[1]->CheckDestroyed()); DestructorCall::ResetList(); } -# endif // !GTEST_HAS_MUTEX_AND_THREAD_LOCAL_ - TEST(ThreadLocalTest, ThreadLocalMutationsAffectOnlyCurrentThread) { ThreadLocal thread_local_string; thread_local_string.set("Foo"); -- cgit v1.2.3 From 41b5b28d4858530a94078a5204c9d393f520159d Mon Sep 17 00:00:00 2001 From: kosak Date: Fri, 24 Jul 2015 19:07:10 +0000 Subject: Inject implementation of *FromGTestEnv using macros. --- test/gtest_unittest.cc | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'test') diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index dd7f19f4..60aed357 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -1671,6 +1671,8 @@ TEST(Int32FromGTestEnvTest, ReturnsDefaultWhenVariableIsNotSet) { EXPECT_EQ(10, Int32FromGTestEnv("temp", 10)); } +# if !defined(GTEST_GET_INT32_FROM_ENV_) + // Tests that Int32FromGTestEnv() returns the default value when the // environment variable overflows as an Int32. TEST(Int32FromGTestEnvTest, ReturnsDefaultWhenValueOverflows) { @@ -1695,6 +1697,8 @@ TEST(Int32FromGTestEnvTest, ReturnsDefaultWhenValueIsInvalid) { EXPECT_EQ(50, Int32FromGTestEnv("temp", 50)); } +# endif // !defined(GTEST_GET_INT32_FROM_ENV_) + // Tests that Int32FromGTestEnv() parses and returns the value of the // environment variable when it represents a valid decimal integer in // the range of an Int32. -- cgit v1.2.3 From 794ef030ebad671b699abdfd8e0474f93045be91 Mon Sep 17 00:00:00 2001 From: kosak Date: Fri, 24 Jul 2015 19:46:18 +0000 Subject: Add support for named value-parameterized tests. --- test/gtest-param-test_test.cc | 151 ++++++++++++++++++++++++++++++++++ test/gtest_output_test_.cc | 26 ++++++ test/gtest_output_test_golden_lin.txt | 21 +++-- 3 files changed, 193 insertions(+), 5 deletions(-) (limited to 'test') diff --git a/test/gtest-param-test_test.cc b/test/gtest-param-test_test.cc index cc1dc65f..8b278bb9 100644 --- a/test/gtest-param-test_test.cc +++ b/test/gtest-param-test_test.cc @@ -809,6 +809,157 @@ TEST_P(NamingTest, TestsReportCorrectNamesAndParameters) { INSTANTIATE_TEST_CASE_P(ZeroToFiveSequence, NamingTest, Range(0, 5)); +// Tests that user supplied custom parameter names are working correctly. +// Runs the test with a builtin helper method which uses PrintToString, +// as well as a custom function and custom functor to ensure all possible +// uses work correctly. +class CustomFunctorNamingTest : public TestWithParam {}; +TEST_P(CustomFunctorNamingTest, CustomTestNames) {} + +struct CustomParamNameFunctor { + std::string operator()(const ::testing::TestParamInfo& info) { + return info.param; + } +}; + +INSTANTIATE_TEST_CASE_P(CustomParamNameFunctor, + CustomFunctorNamingTest, + Values(std::string("FunctorName")), + CustomParamNameFunctor()); + +INSTANTIATE_TEST_CASE_P(AllAllowedCharacters, + CustomFunctorNamingTest, + Values("abcdefghijklmnopqrstuvwxyz", + "ABCDEFGHIJKLMNOPQRSTUVWXYZ", + "01234567890_"), + CustomParamNameFunctor()); + +inline std::string CustomParamNameFunction( + const ::testing::TestParamInfo& info) { + return info.param; +} + +class CustomFunctionNamingTest : public TestWithParam {}; +TEST_P(CustomFunctionNamingTest, CustomTestNames) {} + +INSTANTIATE_TEST_CASE_P(CustomParamNameFunction, + CustomFunctionNamingTest, + Values(std::string("FunctionName")), + CustomParamNameFunction); + +#if GTEST_LANG_CXX11 + +// Test custom naming with a lambda + +class CustomLambdaNamingTest : public TestWithParam {}; +TEST_P(CustomLambdaNamingTest, CustomTestNames) {} + +INSTANTIATE_TEST_CASE_P(CustomParamNameLambda, + CustomLambdaNamingTest, + Values(std::string("LambdaName")), + [](const ::testing::TestParamInfo& info) { + return info.param; + }); + +#endif // GTEST_LANG_CXX11 + +TEST(CustomNamingTest, CheckNameRegistry) { + ::testing::UnitTest* unit_test = ::testing::UnitTest::GetInstance(); + std::set test_names; + for (int case_num = 0; + case_num < unit_test->total_test_case_count(); + ++case_num) { + const ::testing::TestCase* test_case = unit_test->GetTestCase(case_num); + for (int test_num = 0; + test_num < test_case->total_test_count(); + ++test_num) { + const ::testing::TestInfo* test_info = test_case->GetTestInfo(test_num); + test_names.insert(std::string(test_info->name())); + } + } + EXPECT_EQ(1u, test_names.count("CustomTestNames/FunctorName")); + EXPECT_EQ(1u, test_names.count("CustomTestNames/FunctionName")); +#if GTEST_LANG_CXX11 + EXPECT_EQ(1u, test_names.count("CustomTestNames/LambdaName")); +#endif // GTEST_LANG_CXX11 +} + +// Test a numeric name to ensure PrintToStringParamName works correctly. + +class CustomIntegerNamingTest : public TestWithParam {}; + +TEST_P(CustomIntegerNamingTest, TestsReportCorrectNames) { + const ::testing::TestInfo* const test_info = + ::testing::UnitTest::GetInstance()->current_test_info(); + Message test_name_stream; + test_name_stream << "TestsReportCorrectNames/" << GetParam(); + EXPECT_STREQ(test_name_stream.GetString().c_str(), test_info->name()); +} + +INSTANTIATE_TEST_CASE_P(PrintToString, + CustomIntegerNamingTest, + Range(0, 5), + ::testing::PrintToStringParamName()); + +// Test a custom struct with PrintToString. + +struct CustomStruct { + explicit CustomStruct(int value) : x(value) {} + int x; +}; + +std::ostream& operator<<(std::ostream& stream, const CustomStruct& val) { + stream << val.x; + return stream; +} + +class CustomStructNamingTest : public TestWithParam {}; + +TEST_P(CustomStructNamingTest, TestsReportCorrectNames) { + const ::testing::TestInfo* const test_info = + ::testing::UnitTest::GetInstance()->current_test_info(); + Message test_name_stream; + test_name_stream << "TestsReportCorrectNames/" << GetParam(); + EXPECT_STREQ(test_name_stream.GetString().c_str(), test_info->name()); +} + +INSTANTIATE_TEST_CASE_P(PrintToString, + CustomStructNamingTest, + Values(CustomStruct(0), CustomStruct(1)), + ::testing::PrintToStringParamName()); + +// Test that using a stateful parameter naming function works as expected. + +struct StatefulNamingFunctor { + StatefulNamingFunctor() : sum(0) {} + std::string operator()(const ::testing::TestParamInfo& info) { + int value = info.param + sum; + sum += info.param; + return ::testing::PrintToString(value); + } + int sum; +}; + +class StatefulNamingTest : public ::testing::TestWithParam { + protected: + StatefulNamingTest() : sum_(0) {} + int sum_; +}; + +TEST_P(StatefulNamingTest, TestsReportCorrectNames) { + const ::testing::TestInfo* const test_info = + ::testing::UnitTest::GetInstance()->current_test_info(); + sum_ += GetParam(); + Message test_name_stream; + test_name_stream << "TestsReportCorrectNames/" << sum_; + EXPECT_STREQ(test_name_stream.GetString().c_str(), test_info->name()); +} + +INSTANTIATE_TEST_CASE_P(StatefulNamingFunctor, + StatefulNamingTest, + Range(0, 5), + StatefulNamingFunctor()); + // Class that cannot be streamed into an ostream. It needs to be copyable // (and, in case of MSVC, also assignable) in order to be a test parameter // type. Its default copy constructor and assignment operator do exactly diff --git a/test/gtest_output_test_.cc b/test/gtest_output_test_.cc index a619459c..1070a9f2 100644 --- a/test/gtest_output_test_.cc +++ b/test/gtest_output_test_.cc @@ -755,6 +755,32 @@ TEST(ExpectFatalFailureTest, FailsWhenStatementThrows) { #endif // GTEST_HAS_EXCEPTIONS +// This #ifdef block tests the output of value-parameterized tests. + +#if GTEST_HAS_PARAM_TEST + +std::string ParamNameFunc(const testing::TestParamInfo& info) { + return info.param; +} + +class ParamTest : public testing::TestWithParam { +}; + +TEST_P(ParamTest, Success) { + EXPECT_EQ("a", GetParam()); +} + +TEST_P(ParamTest, Failure) { + EXPECT_EQ("b", GetParam()) << "Expected failure"; +} + +INSTANTIATE_TEST_CASE_P(PrintingStrings, + ParamTest, + testing::Values(std::string("a")), + ParamNameFunc); + +#endif // GTEST_HAS_PARAM_TEST + // This #ifdef block tests the output of typed tests. #if GTEST_HAS_TYPED_TEST diff --git a/test/gtest_output_test_golden_lin.txt b/test/gtest_output_test_golden_lin.txt index da541700..7fff8530 100644 --- a/test/gtest_output_test_golden_lin.txt +++ b/test/gtest_output_test_golden_lin.txt @@ -7,7 +7,7 @@ Expected: true gtest_output_test_.cc:#: Failure Value of: 3 Expected: 2 -[==========] Running 64 tests from 28 test cases. +[==========] Running 66 tests from 29 test cases. [----------] Global test environment set-up. FooEnvironment::SetUp() called. BarEnvironment::SetUp() called. @@ -601,6 +601,16 @@ Value of: GetParam() Actual: 2 Expected: 1 [ FAILED ] PrintingFailingParams/FailingParamTest.Fails/0, where GetParam() = 2 +[----------] 2 tests from PrintingStrings/ParamTest +[ RUN ] PrintingStrings/ParamTest.Success/a +[ OK ] PrintingStrings/ParamTest.Success/a +[ RUN ] PrintingStrings/ParamTest.Failure/a +gtest_output_test_.cc:#: Failure +Value of: GetParam() + Actual: "a" +Expected: "b" +Expected failure +[ FAILED ] PrintingStrings/ParamTest.Failure/a, where GetParam() = "a" [----------] Global test environment tear-down BarEnvironment::TearDown() called. gtest_output_test_.cc:#: Failure @@ -610,9 +620,9 @@ FooEnvironment::TearDown() called. gtest_output_test_.cc:#: Failure Failed Expected fatal failure. -[==========] 64 tests from 28 test cases ran. -[ PASSED ] 21 tests. -[ FAILED ] 43 tests, listed below: +[==========] 66 tests from 29 test cases ran. +[ PASSED ] 22 tests. +[ FAILED ] 44 tests, listed below: [ FAILED ] NonfatalFailureTest.EscapesStringOperands [ FAILED ] NonfatalFailureTest.DiffForLongStrings [ FAILED ] FatalFailureTest.FatalFailureInSubroutine @@ -656,8 +666,9 @@ Expected fatal failure. [ FAILED ] ExpectFailureWithThreadsTest.ExpectNonFatalFailure [ FAILED ] ScopedFakeTestPartResultReporterTest.InterceptOnlyCurrentThread [ FAILED ] PrintingFailingParams/FailingParamTest.Fails/0, where GetParam() = 2 +[ FAILED ] PrintingStrings/ParamTest.Failure/a, where GetParam() = "a" -43 FAILED TESTS +44 FAILED TESTS  YOU HAVE 1 DISABLED TEST Note: Google Test filter = FatalFailureTest.*:LoggingTest.* -- cgit v1.2.3 From f487e9510be94c70f08485887a16b48d756bf38f Mon Sep 17 00:00:00 2001 From: kosak Date: Mon, 27 Jul 2015 21:18:24 +0000 Subject: Inject the name of the Init function using a macro. --- test/gtest-port_test.cc | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'test') diff --git a/test/gtest-port_test.cc b/test/gtest-port_test.cc index 14418804..d17bad00 100644 --- a/test/gtest-port_test.cc +++ b/test/gtest-port_test.cc @@ -382,15 +382,17 @@ TEST(GtestCheckDeathTest, LivesSilentlyOnSuccess) { // the platform. The test will produce compiler errors in case of failure. // For simplicity, we only cover the most important platforms here. TEST(RegexEngineSelectionTest, SelectsCorrectRegexEngine) { -#if GTEST_HAS_POSIX_RE +#if !GTEST_USES_PCRE +# if GTEST_HAS_POSIX_RE EXPECT_TRUE(GTEST_USES_POSIX_RE); -#else +# else EXPECT_TRUE(GTEST_USES_SIMPLE_RE); -#endif +# endif +#endif // !GTEST_USES_PCRE } #if GTEST_USES_POSIX_RE -- cgit v1.2.3