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).
This commit is contained in:
parent
e56daa7de1
commit
19eb9e9e3d
|
@ -81,39 +81,22 @@ namespace internal {
|
||||||
#error "At least Visual C++ 2003 (7.1) is required to compile Google Mock."
|
#error "At least Visual C++ 2003 (7.1) is required to compile Google Mock."
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Use implicit_cast as a safe version of static_cast or const_cast
|
// Use implicit_cast as a safe version of static_cast for upcasting in
|
||||||
// for upcasting in the type hierarchy (i.e. casting a pointer to Foo
|
// the type hierarchy (e.g. casting a Foo* to a SuperclassOfFoo* or a
|
||||||
// to a pointer to SuperclassOfFoo or casting a pointer to Foo to
|
// const Foo*). When you use implicit_cast, the compiler checks that
|
||||||
// a const pointer to Foo).
|
// the cast is safe. Such explicit implicit_casts are necessary in
|
||||||
// When you use implicit_cast, the compiler checks that the cast is safe.
|
// surprisingly many situations where C++ demands an exact type match
|
||||||
// Such explicit implicit_casts are necessary in surprisingly many
|
// instead of an argument type convertable to a target type.
|
||||||
// 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
|
// The syntax for using implicit_cast is the same as for static_cast:
|
||||||
// implicit_cast is the same as for static_cast etc.:
|
|
||||||
//
|
//
|
||||||
// implicit_cast<ToType>(expr)
|
// implicit_cast<ToType>(expr)
|
||||||
//
|
//
|
||||||
// implicit_cast would have been part of the C++ standard library,
|
// implicit_cast would have been part of the C++ standard library,
|
||||||
// but the proposal was submitted too late. It will probably make
|
// but the proposal was submitted too late. It will probably make
|
||||||
// its way into the language in the future.
|
// its way into the language in the future.
|
||||||
template<typename To, typename From>
|
template<typename To>
|
||||||
inline To implicit_cast(const From& f) {
|
inline To implicit_cast(To x) { return x; }
|
||||||
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
|
|
||||||
|
|
||||||
// When you upcast (that is, cast a pointer from type Foo to type
|
// When you upcast (that is, cast a pointer from type Foo to type
|
||||||
// SuperclassOfFoo), it's fine to use implicit_cast<>, since upcasts
|
// 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
|
// optimized build at run-time, as it will be optimized away
|
||||||
// completely.
|
// completely.
|
||||||
if (false) {
|
if (false) {
|
||||||
implicit_cast<From*, To>(0);
|
const To to = NULL;
|
||||||
|
implicit_cast<From*>(to);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if GTEST_HAS_RTTI
|
#if GTEST_HAS_RTTI
|
||||||
|
|
82
run_tests.py
Executable file
82
run_tests.py
Executable file
|
@ -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()
|
|
@ -340,11 +340,11 @@ def _NeedToUseReturnNullDiagnoser(msg):
|
||||||
regex = ('instantiated from \'testing::internal::ReturnAction<R>'
|
regex = ('instantiated from \'testing::internal::ReturnAction<R>'
|
||||||
'::operator testing::Action<Func>\(\) const.*\n' +
|
'::operator testing::Action<Func>\(\) const.*\n' +
|
||||||
_FILE_LINE_RE + r'instantiated from here\n'
|
_FILE_LINE_RE + r'instantiated from here\n'
|
||||||
r'.*gmock-port\.h.*error: invalid conversion from '
|
r'.*error: no matching function for call to \'implicit_cast\('
|
||||||
r'\'long int\' to \'(?P<type>.+\*)')
|
r'long int&\)')
|
||||||
diagnosis = """
|
diagnosis = """
|
||||||
You are probably calling Return(NULL) and the compiler isn't sure how to turn
|
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)."""
|
Note: the line number may be off; please fix all instances of Return(NULL)."""
|
||||||
return _GenericDiagnoser('NRNULL', 'Need to use ReturnNull',
|
return _GenericDiagnoser('NRNULL', 'Need to use ReturnNull',
|
||||||
regex, diagnosis, msg)
|
regex, diagnosis, msg)
|
||||||
|
|
|
@ -545,9 +545,6 @@ TEST(ReturnTest, ConvertsArgumentWhenConverted) {
|
||||||
<< "when performed." ;
|
<< "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 DestinationType {};
|
||||||
|
|
||||||
class SourceType {
|
class SourceType {
|
||||||
|
@ -560,7 +557,6 @@ TEST(ReturnTest, CanConvertArgumentUsingNonConstTypeCastOperator) {
|
||||||
SourceType s;
|
SourceType s;
|
||||||
Action<DestinationType()> action(Return(s));
|
Action<DestinationType()> action(Return(s));
|
||||||
}
|
}
|
||||||
#endif // !GTEST_OS_SYMBIAN
|
|
||||||
|
|
||||||
// Tests that ReturnNull() returns NULL in a pointer-returning function.
|
// Tests that ReturnNull() returns NULL in a pointer-returning function.
|
||||||
TEST(ReturnNullTest, WorksInPointerReturningFunction) {
|
TEST(ReturnNullTest, WorksInPointerReturningFunction) {
|
||||||
|
|
|
@ -76,10 +76,6 @@ TEST(ImplicitCastTest, CanUseInheritance) {
|
||||||
EXPECT_EQ(derived.member(), base.member());
|
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 {
|
class Castable {
|
||||||
public:
|
public:
|
||||||
Castable(bool* converted) : converted_(converted) {}
|
Castable(bool* converted) : converted_(converted) {}
|
||||||
|
@ -98,7 +94,6 @@ TEST(ImplicitCastTest, CanUseNonConstCastOperator) {
|
||||||
Base base = ::testing::internal::implicit_cast<Base>(castable);
|
Base base = ::testing::internal::implicit_cast<Base>(castable);
|
||||||
EXPECT_TRUE(converted);
|
EXPECT_TRUE(converted);
|
||||||
}
|
}
|
||||||
#endif // !GTEST_OS_SYMBIAN
|
|
||||||
|
|
||||||
class ConstCastable {
|
class ConstCastable {
|
||||||
public:
|
public:
|
||||||
|
@ -119,10 +114,6 @@ TEST(ImplicitCastTest, CanUseConstCastOperatorOnConstValues) {
|
||||||
EXPECT_TRUE(converted);
|
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 {
|
class ConstAndNonConstCastable {
|
||||||
public:
|
public:
|
||||||
ConstAndNonConstCastable(bool* converted, bool* const_converted)
|
ConstAndNonConstCastable(bool* converted, bool* const_converted)
|
||||||
|
@ -156,7 +147,6 @@ TEST(ImplicitCastTest, CanSelectBetweenConstAndNonConstCasrAppropriately) {
|
||||||
EXPECT_FALSE(converted);
|
EXPECT_FALSE(converted);
|
||||||
EXPECT_TRUE(const_converted);
|
EXPECT_TRUE(const_converted);
|
||||||
}
|
}
|
||||||
#endif // !GTEST_OS_SYMBIAN
|
|
||||||
|
|
||||||
class To {
|
class To {
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -33,51 +33,59 @@
|
||||||
|
|
||||||
__author__ = 'wan@google.com (Zhanyong Wan)'
|
__author__ = 'wan@google.com (Zhanyong Wan)'
|
||||||
|
|
||||||
import gmock_test_utils
|
|
||||||
import os
|
import os
|
||||||
import unittest
|
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)
|
PROGRAM_PATH = gmock_test_utils.GetTestExecutablePath('gmock_leak_test_')
|
||||||
TEST_WITH_EXPECT_CALL = PROGRAM_PATH + ' --gtest_filter=*ExpectCall*'
|
TEST_WITH_EXPECT_CALL = [PROGRAM_PATH, '--gtest_filter=*ExpectCall*']
|
||||||
TEST_WITH_ON_CALL = PROGRAM_PATH + ' --gtest_filter=*OnCall*'
|
TEST_WITH_ON_CALL = [PROGRAM_PATH, '--gtest_filter=*OnCall*']
|
||||||
TEST_MULTIPLE_LEAKS = PROGRAM_PATH + ' --gtest_filter=*MultipleLeaked*'
|
TEST_MULTIPLE_LEAKS = [PROGRAM_PATH, '--gtest_filter=*MultipleLeaked*']
|
||||||
|
|
||||||
|
|
||||||
class GMockLeakTest(unittest.TestCase):
|
class GMockLeakTest(unittest.TestCase):
|
||||||
|
|
||||||
def testCatchesLeakedMockByDefault(self):
|
def testCatchesLeakedMockByDefault(self):
|
||||||
self.assertNotEqual(os.system(TEST_WITH_EXPECT_CALL), 0)
|
self.assertNotEqual(
|
||||||
self.assertNotEqual(os.system(TEST_WITH_ON_CALL), 0)
|
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):
|
def testDoesNotCatchLeakedMockWhenDisabled(self):
|
||||||
self.assertEquals(
|
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(
|
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):
|
def testCatchesLeakedMockWhenEnabled(self):
|
||||||
self.assertNotEqual(
|
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(
|
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):
|
def testCatchesLeakedMockWhenEnabledWithExplictFlagValue(self):
|
||||||
self.assertNotEqual(
|
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):
|
def testCatchesMultipleLeakedMocks(self):
|
||||||
self.assertNotEqual(
|
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__':
|
if __name__ == '__main__':
|
||||||
|
|
|
@ -40,29 +40,21 @@ SYNOPSIS
|
||||||
|
|
||||||
__author__ = 'wan@google.com (Zhanyong Wan)'
|
__author__ = 'wan@google.com (Zhanyong Wan)'
|
||||||
|
|
||||||
import gmock_test_utils
|
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import string
|
|
||||||
import sys
|
import sys
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
|
import gmock_test_utils
|
||||||
|
|
||||||
|
|
||||||
# The flag for generating the golden file
|
# The flag for generating the golden file
|
||||||
GENGOLDEN_FLAG = '--gengolden'
|
GENGOLDEN_FLAG = '--gengolden'
|
||||||
|
|
||||||
IS_WINDOWS = os.name == 'nt'
|
PROGRAM_PATH = gmock_test_utils.GetTestExecutablePath('gmock_output_test_')
|
||||||
|
COMMAND = [PROGRAM_PATH, '--gtest_stack_trace_depth=0', '--gtest_print_time=0']
|
||||||
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'
|
|
||||||
GOLDEN_NAME = 'gmock_output_test_golden.txt'
|
GOLDEN_NAME = 'gmock_output_test_golden.txt'
|
||||||
GOLDEN_PATH = os.path.join(gmock_test_utils.GetSourceDir(),
|
GOLDEN_PATH = os.path.join(gmock_test_utils.GetSourceDir(), GOLDEN_NAME)
|
||||||
GOLDEN_NAME)
|
|
||||||
|
|
||||||
|
|
||||||
def ToUnixLineEnding(s):
|
def ToUnixLineEnding(s):
|
||||||
|
@ -144,51 +136,10 @@ def GetNormalizedOutputAndLeakyTests(output):
|
||||||
return (RemoveTestNamesOfLeakedMocks(output), GetLeakyTests(output))
|
return (RemoveTestNamesOfLeakedMocks(output), GetLeakyTests(output))
|
||||||
|
|
||||||
|
|
||||||
def IterShellCommandOutput(cmd, stdin_string=None):
|
def GetShellCommandOutput(cmd):
|
||||||
"""Runs a command in a sub-process, and iterates the lines in its STDOUT.
|
"""Runs a command in a sub-process, and returns its STDOUT in a string."""
|
||||||
|
|
||||||
Args:
|
return gmock_test_utils.Subprocess(cmd, capture_stderr=False).output
|
||||||
|
|
||||||
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 GetNormalizedCommandOutputAndLeakyTests(cmd):
|
def GetNormalizedCommandOutputAndLeakyTests(cmd):
|
||||||
|
@ -200,7 +151,7 @@ def GetNormalizedCommandOutputAndLeakyTests(cmd):
|
||||||
|
|
||||||
# Disables exception pop-ups on Windows.
|
# Disables exception pop-ups on Windows.
|
||||||
os.environ['GTEST_CATCH_EXCEPTIONS'] = '1'
|
os.environ['GTEST_CATCH_EXCEPTIONS'] = '1'
|
||||||
return GetNormalizedOutputAndLeakyTests(GetShellCommandOutput(cmd, ''))
|
return GetNormalizedOutputAndLeakyTests(GetShellCommandOutput(cmd))
|
||||||
|
|
||||||
|
|
||||||
class GMockOutputTest(unittest.TestCase):
|
class GMockOutputTest(unittest.TestCase):
|
||||||
|
|
|
@ -35,7 +35,19 @@ __author__ = 'wan@google.com (Zhanyong Wan)'
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
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
|
# Initially maps a flag to its default value. After
|
||||||
|
@ -96,6 +108,22 @@ def GetBuildDir():
|
||||||
return os.path.abspath(GetFlag('gmock_build_dir'))
|
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):
|
def GetExitStatus(exit_code):
|
||||||
"""Returns the argument to exit(), or -1 if exit() wasn't called.
|
"""Returns the argument to exit(), or -1 if exit() wasn't called.
|
||||||
|
|
||||||
|
@ -116,11 +144,15 @@ def GetExitStatus(exit_code):
|
||||||
return -1
|
return -1
|
||||||
|
|
||||||
|
|
||||||
|
# Exposes Subprocess from gtest_test_utils.
|
||||||
|
Subprocess = gtest_test_utils.Subprocess # pylint: disable-msg=C6409
|
||||||
|
|
||||||
|
|
||||||
def Main():
|
def Main():
|
||||||
"""Runs the unit test."""
|
"""Runs the unit test."""
|
||||||
|
|
||||||
# We must call _ParseAndStripGMockFlags() before calling
|
# We must call _ParseAndStripGMockFlags() before calling
|
||||||
# unittest.main(). Otherwise the latter will be confused by the
|
# gtest_test_utils.Main(). Otherwise unittest.main it calls will be
|
||||||
# --gmock_* flags.
|
# confused by the --gmock_* flags.
|
||||||
_ParseAndStripGMockFlags(sys.argv)
|
_ParseAndStripGMockFlags(sys.argv)
|
||||||
unittest.main()
|
gtest_test_utils.Main()
|
||||||
|
|
Loading…
Reference in New Issue
Block a user