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