aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorzhanyong.wan <zhanyong.wan@8415998a-534a-0410-bf83-d39667b30386>2009-11-24 20:23:18 +0000
committerzhanyong.wan <zhanyong.wan@8415998a-534a-0410-bf83-d39667b30386>2009-11-24 20:23:18 +0000
commit19eb9e9e3d4d5a4f0eee786d7664ca0e45137390 (patch)
treef28c91fcdbbac205124a68b4e5f9641d05288d07
parente56daa7de1d85c35d1cdc252b500ab276b5c1c9c (diff)
downloadgoogletest-19eb9e9e3d4d5a4f0eee786d7664ca0e45137390.tar.gz
googletest-19eb9e9e3d4d5a4f0eee786d7664ca0e45137390.tar.bz2
googletest-19eb9e9e3d4d5a4f0eee786d7664ca0e45137390.zip
Pulls in gtest r344; improves implicit_cast (by Zhanyong Wan); makes the Python tests work on Windows (by Vlad Losev); adds run_tests.py (by Vlad Losev).
-rw-r--r--include/gmock/internal/gmock-port.h40
-rwxr-xr-xrun_tests.py82
-rwxr-xr-xscripts/gmock_doctor.py6
-rw-r--r--test/gmock-actions_test.cc4
-rw-r--r--test/gmock-port_test.cc10
-rwxr-xr-xtest/gmock_leak_test.py50
-rwxr-xr-xtest/gmock_output_test.py67
-rwxr-xr-xtest/gmock_test_utils.py40
8 files changed, 171 insertions, 128 deletions
diff --git a/include/gmock/internal/gmock-port.h b/include/gmock/internal/gmock-port.h
index 1bd455b2..0cff73fe 100644
--- a/include/gmock/internal/gmock-port.h
+++ b/include/gmock/internal/gmock-port.h
@@ -81,39 +81,22 @@ namespace internal {
#error "At least Visual C++ 2003 (7.1) is required to compile Google Mock."
#endif
-// Use implicit_cast as a safe version of static_cast or const_cast
-// for upcasting in the type hierarchy (i.e. casting a pointer to Foo
-// to a pointer to SuperclassOfFoo or casting a pointer to Foo to
-// a const pointer to Foo).
-// When you use implicit_cast, the compiler checks that the cast is safe.
-// Such explicit implicit_casts are necessary in surprisingly many
-// situations where C++ demands an exact type match instead of an
-// argument type convertable to a target type.
-//
-// The From type can be inferred, so the preferred syntax for using
-// implicit_cast is the same as for static_cast etc.:
+// Use implicit_cast as a safe version of static_cast for upcasting in
+// the type hierarchy (e.g. casting a Foo* to a SuperclassOfFoo* or a
+// const Foo*). When you use implicit_cast, the compiler checks that
+// the cast is safe. Such explicit implicit_casts are necessary in
+// surprisingly many situations where C++ demands an exact type match
+// instead of an argument type convertable to a target type.
+//
+// The syntax for using implicit_cast is the same as for static_cast:
//
// implicit_cast<ToType>(expr)
//
// implicit_cast would have been part of the C++ standard library,
// but the proposal was submitted too late. It will probably make
// its way into the language in the future.
-template<typename To, typename From>
-inline To implicit_cast(const From& f) {
- return f;
-}
-// Nokia's compiler can't tell which version of implicit_cast to use when
-// the source is a const, causing the compilation to fail with the error
-// "ambiguous access to overloaded function". So we only support the const
-// version of implicit_cast on Symbian.
-#if !GTEST_OS_SYMBIAN
-// This overload is needed in case the From type has a non-const type
-// conversion operator to type To.
-template<typename To, typename From>
-inline To implicit_cast(From& f) {
- return f;
-}
-#endif
+template<typename To>
+inline To implicit_cast(To x) { return x; }
// When you upcast (that is, cast a pointer from type Foo to type
// SuperclassOfFoo), it's fine to use implicit_cast<>, since upcasts
@@ -139,7 +122,8 @@ inline To down_cast(From* f) { // so we only accept pointers
// optimized build at run-time, as it will be optimized away
// completely.
if (false) {
- implicit_cast<From*, To>(0);
+ const To to = NULL;
+ implicit_cast<From*>(to);
}
#if GTEST_HAS_RTTI
diff --git a/run_tests.py b/run_tests.py
new file mode 100755
index 00000000..42dc14bf
--- /dev/null
+++ b/run_tests.py
@@ -0,0 +1,82 @@
+#!/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.
+
+"""Runs the specified tests for Google Mock.
+
+This script requires Python 2.3 or higher. To learn the usage, run it
+with -h.
+"""
+
+__author__ = 'vladl@google.com (Vlad Losev)'
+
+
+import os
+import sys
+
+SCRIPT_DIR = os.path.dirname(__file__) or '.'
+
+# Path to the Google Test code this Google Mock will use. We assume the
+# gtest/ directory is either a subdirectory (possibly via a symbolic link)
+# of gmock/ or a sibling.
+#
+# isdir resolves symbolic links.
+if os.path.isdir(os.path.join(SCRIPT_DIR, 'gtest/test')):
+ RUN_TESTS_UTIL_DIR = os.path.join(SCRIPT_DIR, 'gtest/test')
+else:
+ RUN_TESTS_UTIL_DIR = os.path.join(SCRIPT_DIR, '../gtest/test')
+
+sys.path.append(RUN_TESTS_UTIL_DIR)
+import run_tests_util
+
+def GetGmockBuildDir(injected_os, script_dir, config):
+ return injected_os.path.normpath(injected_os.path.join(script_dir,
+ 'scons/build',
+ config,
+ 'gmock/scons'))
+
+
+def _Main():
+ """Runs all tests for Google Mock."""
+
+ options, args = run_tests_util.ParseArgs('gtest')
+ test_runner = run_tests_util.TestRunner(
+ script_dir=SCRIPT_DIR,
+ build_dir_var_name='GMOCK_BUILD_DIR',
+ injected_build_dir_finder=GetGmockBuildDir)
+ tests = test_runner.GetTestsToRun(args,
+ options.configurations,
+ options.built_configurations)
+ if not tests:
+ sys.exit(1) # Incorrect parameters given, abort execution.
+
+ sys.exit(test_runner.RunTests(tests[0], tests[1]))
+
+if __name__ == '__main__':
+ _Main()
diff --git a/scripts/gmock_doctor.py b/scripts/gmock_doctor.py
index d21b9ee7..74af1083 100755
--- a/scripts/gmock_doctor.py
+++ b/scripts/gmock_doctor.py
@@ -340,11 +340,11 @@ def _NeedToUseReturnNullDiagnoser(msg):
regex = ('instantiated from \'testing::internal::ReturnAction<R>'
'::operator testing::Action<Func>\(\) const.*\n' +
_FILE_LINE_RE + r'instantiated from here\n'
- r'.*gmock-port\.h.*error: invalid conversion from '
- r'\'long int\' to \'(?P<type>.+\*)')
+ r'.*error: no matching function for call to \'implicit_cast\('
+ r'long int&\)')
diagnosis = """
You are probably calling Return(NULL) and the compiler isn't sure how to turn
-NULL into a %(type)s*. Use ReturnNull() instead.
+NULL into the right type. Use ReturnNull() instead.
Note: the line number may be off; please fix all instances of Return(NULL)."""
return _GenericDiagnoser('NRNULL', 'Need to use ReturnNull',
regex, diagnosis, msg)
diff --git a/test/gmock-actions_test.cc b/test/gmock-actions_test.cc
index e2b1d052..1be4a16c 100644
--- a/test/gmock-actions_test.cc
+++ b/test/gmock-actions_test.cc
@@ -545,9 +545,6 @@ TEST(ReturnTest, ConvertsArgumentWhenConverted) {
<< "when performed." ;
}
-// We do not support non-const type conversions on Symbian. See
-// definition of implicit_cast in gmock-port.h for more information.
-#if !GTEST_OS_SYMBIAN
class DestinationType {};
class SourceType {
@@ -560,7 +557,6 @@ TEST(ReturnTest, CanConvertArgumentUsingNonConstTypeCastOperator) {
SourceType s;
Action<DestinationType()> action(Return(s));
}
-#endif // !GTEST_OS_SYMBIAN
// Tests that ReturnNull() returns NULL in a pointer-returning function.
TEST(ReturnNullTest, WorksInPointerReturningFunction) {
diff --git a/test/gmock-port_test.cc b/test/gmock-port_test.cc
index 3d983d52..b2afb932 100644
--- a/test/gmock-port_test.cc
+++ b/test/gmock-port_test.cc
@@ -76,10 +76,6 @@ TEST(ImplicitCastTest, CanUseInheritance) {
EXPECT_EQ(derived.member(), base.member());
}
-// The non-const version is not enabled for Symbian since the Nokia compiler
-// cannot decide which version of the overloaded implicit_cast method to use
-// when the source is a const.
-#if !GTEST_OS_SYMBIAN
class Castable {
public:
Castable(bool* converted) : converted_(converted) {}
@@ -98,7 +94,6 @@ TEST(ImplicitCastTest, CanUseNonConstCastOperator) {
Base base = ::testing::internal::implicit_cast<Base>(castable);
EXPECT_TRUE(converted);
}
-#endif // !GTEST_OS_SYMBIAN
class ConstCastable {
public:
@@ -119,10 +114,6 @@ TEST(ImplicitCastTest, CanUseConstCastOperatorOnConstValues) {
EXPECT_TRUE(converted);
}
-// The non-const version is not enabled for Symbian since the Nokia compiler
-// cannot decide which version of the overloaded implicit_cast method to use
-// when the source is a const.
-#if !GTEST_OS_SYMBIAN
class ConstAndNonConstCastable {
public:
ConstAndNonConstCastable(bool* converted, bool* const_converted)
@@ -156,7 +147,6 @@ TEST(ImplicitCastTest, CanSelectBetweenConstAndNonConstCasrAppropriately) {
EXPECT_FALSE(converted);
EXPECT_TRUE(const_converted);
}
-#endif // !GTEST_OS_SYMBIAN
class To {
public:
diff --git a/test/gmock_leak_test.py b/test/gmock_leak_test.py
index 1337e0b0..429cc6ad 100755
--- a/test/gmock_leak_test.py
+++ b/test/gmock_leak_test.py
@@ -33,51 +33,59 @@
__author__ = 'wan@google.com (Zhanyong Wan)'
-import gmock_test_utils
import os
import unittest
-IS_WINDOWS = os.name == 'nt'
+import gmock_test_utils
-if IS_WINDOWS:
- # TODO(wan@google.com): test the opt build too. We should do it
- # when Vlad Losev's work on Google Test's Python test driver is
- # done, such that we can reuse the work.
- PROGRAM = r'..\build.dbg\gmock_leak_test_.exe'
-else:
- PROGRAM = 'gmock_leak_test_'
-PROGRAM_PATH = os.path.join(gmock_test_utils.GetBuildDir(), PROGRAM)
-TEST_WITH_EXPECT_CALL = PROGRAM_PATH + ' --gtest_filter=*ExpectCall*'
-TEST_WITH_ON_CALL = PROGRAM_PATH + ' --gtest_filter=*OnCall*'
-TEST_MULTIPLE_LEAKS = PROGRAM_PATH + ' --gtest_filter=*MultipleLeaked*'
+PROGRAM_PATH = gmock_test_utils.GetTestExecutablePath('gmock_leak_test_')
+TEST_WITH_EXPECT_CALL = [PROGRAM_PATH, '--gtest_filter=*ExpectCall*']
+TEST_WITH_ON_CALL = [PROGRAM_PATH, '--gtest_filter=*OnCall*']
+TEST_MULTIPLE_LEAKS = [PROGRAM_PATH, '--gtest_filter=*MultipleLeaked*']
class GMockLeakTest(unittest.TestCase):
def testCatchesLeakedMockByDefault(self):
- self.assertNotEqual(os.system(TEST_WITH_EXPECT_CALL), 0)
- self.assertNotEqual(os.system(TEST_WITH_ON_CALL), 0)
+ self.assertNotEqual(
+ 0,
+ gmock_test_utils.Subprocess(TEST_WITH_EXPECT_CALL).exit_code)
+ self.assertNotEqual(
+ 0,
+ gmock_test_utils.Subprocess(TEST_WITH_ON_CALL).exit_code)
def testDoesNotCatchLeakedMockWhenDisabled(self):
self.assertEquals(
- 0, os.system(TEST_WITH_EXPECT_CALL + ' --gmock_catch_leaked_mocks=0'))
+ 0,
+ gmock_test_utils.Subprocess(TEST_WITH_EXPECT_CALL +
+ ['--gmock_catch_leaked_mocks=0']).exit_code)
self.assertEquals(
- 0, os.system(TEST_WITH_ON_CALL + ' --gmock_catch_leaked_mocks=0'))
+ 0,
+ gmock_test_utils.Subprocess(TEST_WITH_ON_CALL +
+ ['--gmock_catch_leaked_mocks=0']).exit_code)
def testCatchesLeakedMockWhenEnabled(self):
self.assertNotEqual(
- os.system(TEST_WITH_EXPECT_CALL + ' --gmock_catch_leaked_mocks'), 0)
+ 0,
+ gmock_test_utils.Subprocess(TEST_WITH_EXPECT_CALL +
+ ['--gmock_catch_leaked_mocks']).exit_code)
self.assertNotEqual(
- os.system(TEST_WITH_ON_CALL + ' --gmock_catch_leaked_mocks'), 0)
+ 0,
+ gmock_test_utils.Subprocess(TEST_WITH_ON_CALL +
+ ['--gmock_catch_leaked_mocks']).exit_code)
def testCatchesLeakedMockWhenEnabledWithExplictFlagValue(self):
self.assertNotEqual(
- os.system(TEST_WITH_EXPECT_CALL + ' --gmock_catch_leaked_mocks=1'), 0)
+ 0,
+ gmock_test_utils.Subprocess(TEST_WITH_EXPECT_CALL +
+ ['--gmock_catch_leaked_mocks=1']).exit_code)
def testCatchesMultipleLeakedMocks(self):
self.assertNotEqual(
- os.system(TEST_MULTIPLE_LEAKS + ' --gmock_catch_leaked_mocks'), 0)
+ 0,
+ gmock_test_utils.Subprocess(TEST_MULTIPLE_LEAKS +
+ ['--gmock_catch_leaked_mocks']).exit_code)
if __name__ == '__main__':
diff --git a/test/gmock_output_test.py b/test/gmock_output_test.py
index f43f7074..c5f05b34 100755
--- a/test/gmock_output_test.py
+++ b/test/gmock_output_test.py
@@ -40,29 +40,21 @@ SYNOPSIS
__author__ = 'wan@google.com (Zhanyong Wan)'
-import gmock_test_utils
import os
import re
-import string
import sys
import unittest
+import gmock_test_utils
+
# The flag for generating the golden file
GENGOLDEN_FLAG = '--gengolden'
-IS_WINDOWS = os.name == 'nt'
-
-if IS_WINDOWS:
- PROGRAM = r'..\build.dbg\gmock_output_test_.exe'
-else:
- PROGRAM = 'gmock_output_test_'
-
-PROGRAM_PATH = os.path.join(gmock_test_utils.GetBuildDir(), PROGRAM)
-COMMAND = PROGRAM_PATH + ' --gtest_stack_trace_depth=0 --gtest_print_time=0'
+PROGRAM_PATH = gmock_test_utils.GetTestExecutablePath('gmock_output_test_')
+COMMAND = [PROGRAM_PATH, '--gtest_stack_trace_depth=0', '--gtest_print_time=0']
GOLDEN_NAME = 'gmock_output_test_golden.txt'
-GOLDEN_PATH = os.path.join(gmock_test_utils.GetSourceDir(),
- GOLDEN_NAME)
+GOLDEN_PATH = os.path.join(gmock_test_utils.GetSourceDir(), GOLDEN_NAME)
def ToUnixLineEnding(s):
@@ -144,51 +136,10 @@ def GetNormalizedOutputAndLeakyTests(output):
return (RemoveTestNamesOfLeakedMocks(output), GetLeakyTests(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.
- """
+def GetShellCommandOutput(cmd):
+ """Runs a command in a sub-process, and returns its STDOUT in a string."""
- lines = list(IterShellCommandOutput(cmd, stdin_string))
- return string.join(lines, '')
+ return gmock_test_utils.Subprocess(cmd, capture_stderr=False).output
def GetNormalizedCommandOutputAndLeakyTests(cmd):
@@ -200,7 +151,7 @@ def GetNormalizedCommandOutputAndLeakyTests(cmd):
# Disables exception pop-ups on Windows.
os.environ['GTEST_CATCH_EXCEPTIONS'] = '1'
- return GetNormalizedOutputAndLeakyTests(GetShellCommandOutput(cmd, ''))
+ return GetNormalizedOutputAndLeakyTests(GetShellCommandOutput(cmd))
class GMockOutputTest(unittest.TestCase):
diff --git a/test/gmock_test_utils.py b/test/gmock_test_utils.py
index 2fda138d..ae15a108 100755
--- a/test/gmock_test_utils.py
+++ b/test/gmock_test_utils.py
@@ -35,7 +35,19 @@ __author__ = 'wan@google.com (Zhanyong Wan)'
import os
import sys
-import unittest
+
+# Determines path to gtest_test_utils and imports it.
+SCRIPT_DIR = os.path.dirname(__file__) or '.'
+
+# isdir resolves symbolic links.
+gtest_tests_util_dir = os.path.join(SCRIPT_DIR, '../gtest/test')
+if os.path.isdir(gtest_tests_util_dir):
+ GTEST_TESTS_UTIL_DIR = gtest_tests_util_dir
+else:
+ GTEST_TESTS_UTIL_DIR = os.path.join(SCRIPT_DIR, '../../gtest/test')
+
+sys.path.append(GTEST_TESTS_UTIL_DIR)
+import gtest_test_utils # pylint: disable-msg=C6204
# Initially maps a flag to its default value. After
@@ -96,6 +108,22 @@ def GetBuildDir():
return os.path.abspath(GetFlag('gmock_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.
+ """
+
+ return gtest_test_utils.GetTestExecutablePath(executable_name, GetBuildDir())
+
+
def GetExitStatus(exit_code):
"""Returns the argument to exit(), or -1 if exit() wasn't called.
@@ -116,11 +144,15 @@ def GetExitStatus(exit_code):
return -1
+# Exposes Subprocess from gtest_test_utils.
+Subprocess = gtest_test_utils.Subprocess # pylint: disable-msg=C6409
+
+
def Main():
"""Runs the unit test."""
# We must call _ParseAndStripGMockFlags() before calling
- # unittest.main(). Otherwise the latter will be confused by the
- # --gmock_* flags.
+ # gtest_test_utils.Main(). Otherwise unittest.main it calls will be
+ # confused by the --gmock_* flags.
_ParseAndStripGMockFlags(sys.argv)
- unittest.main()
+ gtest_test_utils.Main()