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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user