summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzhanyong.wan <zhanyong.wan@861a406c-534a-0410-8894-cb66d6ee9925>2009-03-11 22:18:52 +0000
committerzhanyong.wan <zhanyong.wan@861a406c-534a-0410-8894-cb66d6ee9925>2009-03-11 22:18:52 +0000
commitbaa766af2a71363fb1ccf8de5de444c4a88f0e61 (patch)
tree371303a68075a9188a758ad359689fc579ff8388
parent1fe95e6208c27cc989952fef40fb2074234d6529 (diff)
downloadgoogletest-baa766af2a71363fb1ccf8de5de444c4a88f0e61.tar.gz
Implements the --help flag; fixes tests on Windows.
git-svn-id: http://googletest.googlecode.com/svn/trunk@204 861a406c-534a-0410-8894-cb66d6ee9925
-rw-r--r--Makefile.am6
-rw-r--r--include/gtest/internal/gtest-port.h13
-rw-r--r--scons/SConscript1
-rw-r--r--src/gtest.cc145
-rw-r--r--test/gtest-death-test_test.cc13
-rw-r--r--test/gtest-filepath_test.cc12
-rw-r--r--test/gtest-options_test.cc40
-rw-r--r--test/gtest_all_test.cc1
-rwxr-xr-xtest/gtest_help_test.py127
-rw-r--r--test/gtest_help_test_.cc42
-rwxr-xr-xtest/gtest_test_utils.py28
11 files changed, 382 insertions, 46 deletions
diff --git a/Makefile.am b/Makefile.am
index fc182d9..3d72d26 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -319,6 +319,12 @@ test_gtest_filter_unittest__LDADD = lib/libgtest.la
check_SCRIPTS += test/gtest_filter_unittest.py
TESTS += test/gtest_filter_unittest.py
+check_PROGRAMS += test/gtest_help_test_
+test_gtest_help_test__SOURCES = test/gtest_help_test_.cc
+test_gtest_help_test__LDADD = lib/libgtest_main.la
+check_SCRIPTS += test/gtest_help_test.py
+TESTS += test/gtest_help_test.py
+
check_PROGRAMS += test/gtest_list_tests_unittest_
test_gtest_list_tests_unittest__SOURCES = test/gtest_list_tests_unittest_.cc
test_gtest_list_tests_unittest__LDADD = lib/libgtest.la
diff --git a/include/gtest/internal/gtest-port.h b/include/gtest/internal/gtest-port.h
index 0b4e721..5d22f24 100644
--- a/include/gtest/internal/gtest-port.h
+++ b/include/gtest/internal/gtest-port.h
@@ -151,9 +151,11 @@
#include <stdio.h>
#include <iostream> // Used for GTEST_CHECK_
-#define GTEST_NAME_ "Google Test"
+#define GTEST_DEV_EMAIL_ "googletestframework@@googlegroups.com"
#define GTEST_FLAG_PREFIX_ "gtest_"
#define GTEST_FLAG_PREFIX_UPPER_ "GTEST_"
+#define GTEST_NAME_ "Google Test"
+#define GTEST_PROJECT_URL_ "http://code.google.com/p/googletest/"
// Determines the version of gcc that is used to compile this.
#ifdef __GNUC__
@@ -696,13 +698,18 @@ struct is_pointer : public false_type {};
template <typename T>
struct is_pointer<T*> : public true_type {};
+#if GTEST_OS_WINDOWS
+#define GTEST_PATH_SEP_ "\\"
+#else
+#define GTEST_PATH_SEP_ "/"
+#endif // GTEST_OS_WINDOWS
+
// Defines BiggestInt as the biggest signed integer type the compiler
// supports.
-
#if GTEST_OS_WINDOWS
typedef __int64 BiggestInt;
#else
-typedef long long BiggestInt; // NOLINT
+typedef long long BiggestInt; // NOLINT
#endif // GTEST_OS_WINDOWS
// The maximum number a BiggestInt can represent. This definition
diff --git a/scons/SConscript b/scons/SConscript
index 8ca7fab..2e0edf3 100644
--- a/scons/SConscript
+++ b/scons/SConscript
@@ -213,6 +213,7 @@ GtestBinary(env_with_exceptions,
# TODO(wan@google.com) Add these unit tests:
# - gtest_break_on_failure_unittest_
# - gtest_filter_unittest_
+# - gtest_help_test_
# - gtest_list_tests_unittest_
# - gtest_throw_on_failure_ex_test
# - gtest_throw_on_failure_test_
diff --git a/src/gtest.cc b/src/gtest.cc
index 61a3484..a66b78f 100644
--- a/src/gtest.cc
+++ b/src/gtest.cc
@@ -244,6 +244,10 @@ GTEST_DEFINE_bool_(
namespace internal {
+// g_help_flag is true iff the --help flag or an equivalent form is
+// specified on the command line.
+static bool g_help_flag = false;
+
// GTestIsInitialized() returns true iff the user has initialized
// Google Test. Useful for catching the user mistake of not initializing
// Google Test before calling RUN_ALL_TESTS().
@@ -2471,6 +2475,7 @@ static void PrintTestPartResult(
namespace internal {
enum GTestColor {
+ COLOR_DEFAULT,
COLOR_RED,
COLOR_GREEN,
COLOR_YELLOW
@@ -2484,20 +2489,21 @@ WORD GetColorAttribute(GTestColor color) {
case COLOR_RED: return FOREGROUND_RED;
case COLOR_GREEN: return FOREGROUND_GREEN;
case COLOR_YELLOW: return FOREGROUND_RED | FOREGROUND_GREEN;
+ default: return 0;
}
- return 0;
}
#else
-// Returns the ANSI color code for the given color.
+// Returns the ANSI color code for the given color. COLOR_DEFAULT is
+// an invalid input.
const char* GetAnsiColorCode(GTestColor color) {
switch (color) {
case COLOR_RED: return "1";
case COLOR_GREEN: return "2";
case COLOR_YELLOW: return "3";
+ default: return NULL;
};
- return NULL;
}
#endif // GTEST_OS_WINDOWS && !_WIN32_WCE
@@ -2540,9 +2546,11 @@ void ColoredPrintf(GTestColor color, const char* fmt, ...) {
va_start(args, fmt);
#if defined(_WIN32_WCE) || GTEST_OS_SYMBIAN || GTEST_OS_ZOS
- static const bool use_color = false;
+ const bool use_color = false;
#else
- static const bool use_color = ShouldUseColor(isatty(fileno(stdout)) != 0);
+ static const bool in_color_mode =
+ ShouldUseColor(isatty(fileno(stdout)) != 0);
+ const bool use_color = in_color_mode && (color != COLOR_DEFAULT);
#endif // defined(_WIN32_WCE) || GTEST_OS_SYMBIAN || GTEST_OS_ZOS
// The '!= 0' comparison is necessary to satisfy MSVC 7.1.
@@ -2577,6 +2585,7 @@ void ColoredPrintf(GTestColor color, const char* fmt, ...) {
} // namespace internal
using internal::ColoredPrintf;
+using internal::COLOR_DEFAULT;
using internal::COLOR_RED;
using internal::COLOR_GREEN;
using internal::COLOR_YELLOW;
@@ -3590,6 +3599,10 @@ int UnitTestImpl::RunAllTests() {
return 1;
}
+ // Do not run any test if the --help flag was specified.
+ if (g_help_flag)
+ return 0;
+
RegisterParameterizedTests();
// Even if sharding is not on, test runners may want to use the
@@ -3789,9 +3802,9 @@ bool ShouldRunTestOnShard(int total_shards, int shard_index, int test_id) {
// Returns the number of tests that should run.
int UnitTestImpl::FilterTests(ReactionToSharding shard_tests) {
const Int32 total_shards = shard_tests == HONOR_SHARDING_PROTOCOL ?
- Int32FromEnvOrDie(kTestTotalShards, -1) : -1;
+ Int32FromEnvOrDie(kTestTotalShards, -1) : -1;
const Int32 shard_index = shard_tests == HONOR_SHARDING_PROTOCOL ?
- Int32FromEnvOrDie(kTestShardIndex, -1) : -1;
+ Int32FromEnvOrDie(kTestShardIndex, -1) : -1;
// num_runnable_tests are the number of tests that will
// run across all shards (i.e., match filter and are not disabled).
@@ -3800,7 +3813,7 @@ int UnitTestImpl::FilterTests(ReactionToSharding shard_tests) {
int num_runnable_tests = 0;
int num_selected_tests = 0;
for (const internal::ListNode<TestCase *> *test_case_node =
- test_cases_.Head();
+ test_cases_.Head();
test_case_node != NULL;
test_case_node = test_case_node->next()) {
TestCase * const test_case = test_case_node->element();
@@ -3808,7 +3821,7 @@ int UnitTestImpl::FilterTests(ReactionToSharding shard_tests) {
test_case->set_should_run(false);
for (const internal::ListNode<TestInfo *> *test_info_node =
- test_case->test_info_list().Head();
+ test_case->test_info_list().Head();
test_info_node != NULL;
test_info_node = test_info_node->next()) {
TestInfo * const test_info = test_info_node->element();
@@ -3816,10 +3829,10 @@ int UnitTestImpl::FilterTests(ReactionToSharding shard_tests) {
// A test is disabled if test case name or test name matches
// kDisableTestFilter.
const bool is_disabled =
- internal::UnitTestOptions::MatchesFilter(test_case_name,
- kDisableTestFilter) ||
- internal::UnitTestOptions::MatchesFilter(test_name,
- kDisableTestFilter);
+ internal::UnitTestOptions::MatchesFilter(test_case_name,
+ kDisableTestFilter) ||
+ internal::UnitTestOptions::MatchesFilter(test_name,
+ kDisableTestFilter);
test_info->impl()->set_is_disabled(is_disabled);
const bool is_runnable =
@@ -4089,6 +4102,102 @@ bool ParseStringFlag(const char* str, const char* flag, String* value) {
return true;
}
+// Prints a string containing code-encoded text. The following escape
+// sequences can be used in the string to control the text color:
+//
+// @@ prints a single '@' character.
+// @R changes the color to red.
+// @G changes the color to green.
+// @Y changes the color to yellow.
+// @D changes to the default terminal text color.
+//
+// TODO(wan@google.com): Write tests for this once we add stdout
+// capturing to Google Test.
+static void PrintColorEncoded(const char* str) {
+ GTestColor color = COLOR_DEFAULT; // The current color.
+
+ // Conceptually, we split the string into segments divided by escape
+ // sequences. Then we print one segment at a time. At the end of
+ // each iteration, the str pointer advances to the beginning of the
+ // next segment.
+ for (;;) {
+ const char* p = strchr(str, '@');
+ if (p == NULL) {
+ ColoredPrintf(color, "%s", str);
+ return;
+ }
+
+ ColoredPrintf(color, "%s", String(str, p - str).c_str());
+
+ const char ch = p[1];
+ str = p + 2;
+ if (ch == '@') {
+ ColoredPrintf(color, "@");
+ } else if (ch == 'D') {
+ color = COLOR_DEFAULT;
+ } else if (ch == 'R') {
+ color = COLOR_RED;
+ } else if (ch == 'G') {
+ color = COLOR_GREEN;
+ } else if (ch == 'Y') {
+ color = COLOR_YELLOW;
+ } else {
+ --str;
+ }
+ }
+}
+
+static const char kColorEncodedHelpMessage[] =
+"This program contains tests written using " GTEST_NAME_ ". You can use the\n"
+"following command line flags to control its behavior:\n"
+"\n"
+"Test Selection:\n"
+" @G--" GTEST_FLAG_PREFIX_ "list_tests@D\n"
+" List the names of all tests instead of running them. The name of\n"
+" TEST(Foo, Bar) is \"Foo.Bar\".\n"
+" @G--" GTEST_FLAG_PREFIX_ "filter=@YPOSTIVE_PATTERNS"
+ "[@G-@YNEGATIVE_PATTERNS]@D\n"
+" Run only the tests whose name matches one of the positive patterns but\n"
+" none of the negative patterns. '?' matches any single character; '*'\n"
+" matches any substring; ':' separates two patterns.\n"
+" @G--" GTEST_FLAG_PREFIX_ "also_run_disabled_tests@D\n"
+" Run all disabled tests too.\n"
+" @G--" GTEST_FLAG_PREFIX_ "repeat=@Y[COUNT]@D\n"
+" Run the tests repeatedly; use a negative count to repeat forever.\n"
+"\n"
+"Test Output:\n"
+" @G--" GTEST_FLAG_PREFIX_ "color=@Y(@Gyes@Y|@Gno@Y|@Gauto@Y)@D\n"
+" Enable/disable colored output. The default is @Gauto@D.\n"
+" -@G-" GTEST_FLAG_PREFIX_ "print_time@D\n"
+" Print the elapsed time of each test.\n"
+" @G--" GTEST_FLAG_PREFIX_ "output=xml@Y[@G:@YDIRECTORY_PATH@G"
+ GTEST_PATH_SEP_ "@Y|@G:@YFILE_PATH]@D\n"
+" Generate an XML report in the given directory or with the given file\n"
+" name. @YFILE_PATH@D defaults to @Gtest_details.xml@D.\n"
+"\n"
+"Failure Behavior:\n"
+" @G--" GTEST_FLAG_PREFIX_ "break_on_failure@D\n"
+" Turn assertion failures into debugger break-points.\n"
+" @G--" GTEST_FLAG_PREFIX_ "throw_on_failure@D\n"
+" Turn assertion failures into C++ exceptions.\n"
+#if GTEST_OS_WINDOWS
+" @G--" GTEST_FLAG_PREFIX_ "catch_exceptions@D\n"
+" Suppress pop-ups caused by exceptions.\n"
+#endif // GTEST_OS_WINDOWS
+"\n"
+"Except for @G--" GTEST_FLAG_PREFIX_ "list_tests@D, you can alternatively set "
+ "the corresponding\n"
+"environment variable of a flag (all letters in upper-case). For example, to\n"
+"print the elapsed time, you can either specify @G--" GTEST_FLAG_PREFIX_
+ "print_time@D or set the\n"
+"@G" GTEST_FLAG_PREFIX_UPPER_ "PRINT_TIME@D environment variable to a "
+ "non-zero value.\n"
+"\n"
+"For more information, please read the " GTEST_NAME_ " documentation at\n"
+"@G" GTEST_PROJECT_URL_ "@D. If you find a bug in " GTEST_NAME_ "\n"
+"(not one in your own code or tests), please report it to\n"
+"@G<" GTEST_DEV_EMAIL_ ">@D.\n";
+
// Parses the command line for Google Test flags, without initializing
// other parts of Google Test. The type parameter CharType can be
// instantiated to either char or wchar_t.
@@ -4137,8 +4246,18 @@ void ParseGoogleTestFlagsOnlyImpl(int* argc, CharType** argv) {
// We also need to decrement the iterator as we just removed
// an element.
i--;
+ } else if (arg_string == "--help" || arg_string == "-h" ||
+ arg_string == "-?" || arg_string == "/?") {
+ g_help_flag = true;
}
}
+
+ if (g_help_flag) {
+ // We print the help here instead of in RUN_ALL_TESTS(), as the
+ // latter may not be called at all if the user is using Google
+ // Test with another testing framework.
+ PrintColorEncoded(kColorEncodedHelpMessage);
+ }
}
// Parses the command line for Google Test flags, without initializing
diff --git a/test/gtest-death-test_test.cc b/test/gtest-death-test_test.cc
index e794a09..aa7e31c 100644
--- a/test/gtest-death-test_test.cc
+++ b/test/gtest-death-test_test.cc
@@ -33,6 +33,7 @@
#include <gtest/gtest-death-test.h>
#include <gtest/gtest.h>
+#include <gtest/internal/gtest-filepath.h>
#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 dfbd5f0..f8b68a7 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 <windows.h> // NOLINT
-#else
+#elif GTEST_OS_WINDOWS
#include <direct.h> // 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 5f24e7e..27a6fe5 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 f73044d..955aa62 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 0000000..cc5819c
--- /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 0000000..0282bc8
--- /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 <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,
+// 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 8ee99c0..8f55b07 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():