Compare commits

...
Author SHA1 Message Date
zhanyong.wan c99458533a Cuts release 1.7.0 2013-09-19 00:29:48 +00:00
zhanyong.wan 2d3543f81d avoids clash with the max() macro on Windows 2013-09-18 17:49:56 +00:00
zhanyong.wan c306ef2e14 supports a protocol for catching tests that prematurely exit 2013-09-06 22:50:25 +00:00
zhanyong.wan 492986a5d0 Updates gtest.xcodeproj to be compatible with OS X 10.8.4 & Xcode 4.6.3 2013-08-27 20:09:54 +00:00
zhanyong.wan 9ba29fae92 fixes a typo in CMake script; h/t to Jay Mueller for reporting the issue 2013-07-09 04:45:37 +00:00
zhanyong.wan 665faa1622 allows gtest-config.in to work with an absoulte path for @top_srcdir@. h/t to Jimi Xenidis for reporting the issue and the fix. 2013-07-08 05:51:32 +00:00
zhanyong.wan 81ddb8434f makes gtest-death-test_test.cc compile on platforms that don't support death tests; h/t to Steve Robbins for reporting the issue and suggesting the fix. 2013-07-08 04:40:28 +00:00
zhanyong.wan 48568d0688 Fixes compatibility with C++11: (1 - 1) is no longer a NULL pointer constant. 2013-06-18 18:44:25 +00:00
vladlosev c506784b08 When --gtest_filter is specified, XML report now doesn't contain information about tests that are filtered out (issue 141). 2013-04-25 17:58:52 +00:00
zhanyong.wan c84afbeaf1 Fixes a thread annotation; updates CHANGES for 1.7.0 2013-04-24 02:48:07 +00:00
zhanyong.wan 0fac83390a prints type/value parameters when listing tests 2013-04-10 04:29:33 +00:00
zhanyong.wan c97e3001cd Updates the version number to 1.7.0 2013-04-07 03:15:36 +00:00
vladlosev f5fa71f728 Implements support for calling Test::RecordProperty() outside of a test. 2013-04-05 20:50:46 +00:00
zhanyong.wan 5f18b68bfc Fixes some compatibility issues with STLport. 2013-04-04 22:44:57 +00:00
zhanyong.wan c08ec2a768 Replaces unportable == with portable = in configure.ac.
Contributed by tk@giga.or.at.
2013-03-19 00:04:54 +00:00
zhanyong.wan 1edbcbad73 Prints a useful message when GetParam() is called in a non-parameterized test. 2013-03-12 21:17:22 +00:00
zhanyong.wan 6b7a167dca Supports colored output on term type screen-256color.
Proposed as a one-line patch by Tom Jakubowski (tom@crystae.net);
finished by Zhanyong Wan.
2013-03-11 17:52:13 +00:00
zhanyong.wan fc01f532a6 Fixes unused function warning on Mac, and fixes compatibility with newer GCC. 2013-02-28 23:52:42 +00:00
zhanyong.wan 6a036a5c8c Fixes a nasty issue in gtest's template instantiation. 2013-02-28 23:46:07 +00:00
zhanyong.wan b3ed14ac17 Implements RUN_ALL_TESTS() as a function. 2013-02-28 23:29:06 +00:00
zhanyong.wan 1b89db9705 Removes an unused variable; also refactors to support an up-coming
googlemock change.
2013-02-28 22:55:25 +00:00
zhanyong.wan 88fe90793c Removes dangling references in make/cmake files. 2013-02-27 18:51:27 +00:00
zhanyong.wan b854938bd0 Adds -pthread and changes -I to -isystem in gtest's build instructions. 2013-02-27 17:49:18 +00:00
kosak ba072ccca4 Fixes gUnit streaming output format. 2013-02-22 20:25:42 +00:00
kosak cc1fdb58ca Removes testing::internal::String::Format(), which causes problems as it truncates the result at 4096 chars. Also update an obsolete link in comment. 2013-02-22 20:10:40 +00:00
zhanyong.wan 65b5c22436 Fixes an out-dated URL. 2013-02-02 18:45:13 +00:00
vladlosev d367343685 Adds the LICENSE file to the distribution. 2013-01-29 20:34:47 +00:00
jgm 268ba61815 Unbreak building gtest with -std=c++11 on Mac OS X 10.6. Also, better support for death tests in iOS simulator. 2012-12-03 18:52:06 +00:00
jgm 87fdda2cf2 Unfortunately, the svn repo is a bit out of date. This commit contains 8
changes that haven't made it to svn. The descriptions of each change are listed
below.

- Fixes some python shebang lines.

- Add ElementsAreArray overloads to gmock. ElementsAreArray now makes a copy of
  its input elements before the conversion to a Matcher. ElementsAreArray can
  now take a vector as input. ElementsAreArray can now take an iterator pair as
  input.

- Templatize MatchAndExplain to allow independent string types for the matcher
  and matchee. I also templatized the ConstCharPointer version of
  MatchAndExplain to avoid calls with "char*" from using the new templated
  MatchAndExplain.

- Fixes the bug where the constructor of the return type of ElementsAre() saves
  a reference instead of a copy of the arguments.

- Extends ElementsAre() to accept arrays whose sizes aren't known.

- Switches gTest's internal FilePath class from testing::internal::String to
  std::string. testing::internal::String was introduced when gTest couldn't
  depend on std::string.  It's now deprecated.

- Switches gTest & gMock from using testing::internal::String objects to
  std::string. Some static methods of String are still in use.  We may be able
  to remove some but not all of them.  In particular, String::Format() should
  eventually be removed as it truncates the result at 4096 characters, often
  causing problems.
2012-11-15 15:47:38 +00:00
vladlosev 78bf6d5724 Improves Android support (by David Turner). 2012-09-19 17:58:01 +00:00
vladlosev b535c1767e Removes obsolete debug code. 2012-09-06 17:09:27 +00:00
vladlosev ff8d732cef Fixes gtest-tuple.h in Visual C++ 7.1. 2012-09-06 16:41:18 +00:00
vladlosev 2147489625 Fixed Native Client build of gtest when using glibc (by Ben Smith). 2012-08-14 15:20:28 +00:00
vladlosev 1f7bb45e07 Prevents pump.py from splitting long IWYU pragma lines. 2012-08-14 15:20:01 +00:00
jgm 4c97512141 fixes a problem in which we pass the address one byte ~/svn/googletest/trunk
after the end of stack space in a call to clone().  According to
Linux's man page on clone(), the 'stack' parameter usually points
to the topmost address of the memory space set up for the child stack.  The existing code points one byte after the end
2012-07-12 16:46:50 +00:00
jgm a1c4b46bc2 added defines for iOS 2012-07-09 13:22:29 +00:00
zhanyong.wan a88c9a88e4 Improves gtest's failure messages. In particulars, char pointers and
char arrays are not escapped properly.
2012-06-07 20:34:34 +00:00
zhanyong.wan a3b859162d Fixes threading annotations and compatibility with C++11, which doesn't
allow exepctions to be thrown in a destructor.
2012-05-31 20:37:13 +00:00
vladlosev cdb24f86d5 Teach gtest to autodetect rtti support with clang (by Nico Weber). 2012-05-02 18:09:59 +00:00
jgm 9a56024c9a Added support for platforms where pthread_t is a struct rather than an integral
type.
2012-04-02 17:41:03 +00:00
jgm f0b86fc3b0 Misc small updates to some debug death code, and to messages streaming to macros 2012-03-09 17:12:39 +00:00
jgm cfb40870bc Locking for Notification class. 2012-01-27 21:26:58 +00:00
jgm 4d6f296e8e Adds file and line information to the "message", which is used as the summary
of a failure.
2012-01-17 15:11:32 +00:00
vladlosev 69a071bc0d Removes spurious semicolon. 2011-11-28 19:52:07 +00:00
vladlosev 8965a6a0d2 Improves conformance to the Google C++ Style Guide (by Greg Miller). 2011-11-04 17:56:23 +00:00
vladlosev 829402edcf Adds support for detection of running in death test child processes. 2011-10-28 16:19:04 +00:00
vladlosev 83fe024fb0 Adds empty methods to Mutex on platforms where Google Test is not thread-safe. This will support a reentrancy fix in Google Mock. 2011-10-24 23:36:46 +00:00
vladlosev 4c11f25f8c Expressed the thread-safety annotations in code, replacing the existing comment-based system (by Aaron Jacobs). 2011-10-24 21:13:56 +00:00
vladlosev 97ef1c705e Changes to fix gtest-printers_test on VC++ 2010. 2011-10-24 18:33:26 +00:00
vladlosev c7c7961d23 Simplifies test assertions in sample5. 2011-10-14 01:18:53 +00:00
vladlosev 431a8be166 Implements the timestamp attribute for the testsuites element in the output XML (external contribution by Dirk Meister). 2011-10-05 05:52:34 +00:00
vladlosev 69a40b7d4a Adds ability to inject death test child arguments for test purposes. 2011-10-05 05:51:10 +00:00
vladlosev 879916a939 Fixes test failure on 32-bit Ubuntu. 2011-10-05 05:49:40 +00:00
vladlosev f7d58e81c3 Adds a new macro simplifying use of snprinf on MS platforms. 2011-09-26 17:54:02 +00:00
vladlosev 1b2e509958 Fixes C++0x compatibility problems. 2011-09-26 17:52:19 +00:00
zhanyong.wan 2ca4d21500 Simplifies the implementatoin of the test result printer; by Ulfar Erlingsson 2011-09-16 16:43:37 +00:00
vladlosev 27615dbc5f Renames the license file. 2011-09-09 07:02:56 +00:00
vladlosev 4b07d73f4e Ignore SIGPROF signal during clone()/fork() call. clone()/fork() call hangs permanently if it consumes more cpu than the SIGPROF signal timer interval (by Nabeel Mian). 2011-09-09 05:42:09 +00:00
vladlosev 294f69f957 Adds explanation on how to build the Xcode project under Xcode 4+ to README. 2011-08-22 21:30:01 +00:00
vladlosev cf3f92ef93 Fixes a user reported test break (modifying a dict while iterating). 2011-08-16 00:47:22 +00:00
vladlosev c2922d4ed2 Fixes a resource leak in gtest-port_test (by Haruka Iwao). 2011-07-11 19:27:07 +00:00
vladlosev 386da2037d QNX compatibility patch (by Haruka Iwao). 2011-06-20 21:43:18 +00:00
vladlosev f3cf0a2316 Suppresses the tail-call optimization of StackGrowsDown() in GCC4.6 (by Paul Pluzhnikov). 2011-06-13 20:09:57 +00:00
vladlosev cc265df8b4 Fixes broken build on VC++ 7.1. 2011-06-13 19:00:37 +00:00
vladlosev 7e29bb7f7e Adds support for building Google Mock as a shared library (DLL). 2011-05-20 00:38:55 +00:00
vladlosev ee2f8caecc Simplifies the code by removing condfitional section that is no longer necessary. 2011-05-12 17:32:42 +00:00
vladlosev 814a5e9310 Adds support for death tests in OpenBSD (by Paweł Hajdan Jr.) 2011-05-03 01:58:34 +00:00
vladlosev 758728ba9b Makes generation of fused sources contingent on availability of Python. 2011-04-21 21:48:51 +00:00
80 changed files with 4498 additions and 2536 deletions
+27
View File
@@ -1,3 +1,30 @@
Changes for 1.7.0:
* New feature: death tests are supported on OpenBSD and in iOS
simulator now.
* New feature: Google Test now implements a protocol to allow
a test runner to detect that a test program has exited
prematurely and report it as a failure (before it would be
falsely reported as a success if the exit code is 0).
* New feature: Test::RecordProperty() can now be used outside of the
lifespan of a test method, in which case it will be attributed to
the current test case or the test program in the XML report.
* New feature (potentially breaking): --gtest_list_tests now prints
the type parameters and value parameters for each test.
* Improvement: char pointers and char arrays are now escaped properly
in failure messages.
* Improvement: failure summary in XML reports now includes file and
line information.
* Improvement: the <testsuites> XML element now has a timestamp attribute.
* Improvement: When --gtest_filter is specified, XML report now doesn't
contain information about tests that are filtered out.
* Fixed the bug where long --gtest_filter flag values are truncated in
death tests.
* Potentially breaking change: RUN_ALL_TESTS() is now implemented as a
function instead of a macro in order to work better with Clang.
* Compatibility fixes with C++ 11 and various platforms.
* Bug/warning fixes.
Changes for 1.6.0: Changes for 1.6.0:
* New feature: ADD_FAILURE_AT() for reporting a test failure at the * New feature: ADD_FAILURE_AT() for reporting a test failure at the
+27 -15
View File
@@ -77,7 +77,7 @@ target_link_libraries(gtest_main gtest)
# #
# They are not built by default. To build them, set the # They are not built by default. To build them, set the
# gtest_build_samples option to ON. You can do it by running ccmake # gtest_build_samples option to ON. You can do it by running ccmake
# or specifying the -Dbuild_gtest_samples=ON flag when running cmake. # or specifying the -Dgtest_build_samples=ON flag when running cmake.
if (gtest_build_samples) if (gtest_build_samples)
cxx_executable(sample1_unittest samples gtest_main samples/sample1.cc) cxx_executable(sample1_unittest samples gtest_main samples/sample1.cc)
@@ -124,6 +124,8 @@ if (gtest_build_tests)
test/gtest-param-test2_test.cc) test/gtest-param-test2_test.cc)
cxx_test(gtest-port_test gtest_main) cxx_test(gtest-port_test gtest_main)
cxx_test(gtest_pred_impl_unittest gtest_main) cxx_test(gtest_pred_impl_unittest gtest_main)
cxx_test(gtest_premature_exit_test gtest
test/gtest_premature_exit_test.cc)
cxx_test(gtest-printers_test gtest_main) cxx_test(gtest-printers_test gtest_main)
cxx_test(gtest_prod_test gtest_main cxx_test(gtest_prod_test gtest_main
test/production.cc) test/production.cc)
@@ -140,10 +142,13 @@ if (gtest_build_tests)
############################################################ ############################################################
# C++ tests built with non-standard compiler flags. # C++ tests built with non-standard compiler flags.
cxx_library(gtest_no_exception "${cxx_no_exception}" # MSVC 7.1 does not support STL with exceptions disabled.
src/gtest-all.cc) if (NOT MSVC OR MSVC_VERSION GREATER 1310)
cxx_library(gtest_main_no_exception "${cxx_no_exception}" cxx_library(gtest_no_exception "${cxx_no_exception}"
src/gtest-all.cc src/gtest_main.cc) src/gtest-all.cc)
cxx_library(gtest_main_no_exception "${cxx_no_exception}"
src/gtest-all.cc src/gtest_main.cc)
endif()
cxx_library(gtest_main_no_rtti "${cxx_no_rtti}" cxx_library(gtest_main_no_rtti "${cxx_no_rtti}"
src/gtest-all.cc src/gtest_main.cc) src/gtest-all.cc src/gtest_main.cc)
@@ -189,11 +194,15 @@ if (gtest_build_tests)
cxx_executable(gtest_break_on_failure_unittest_ test gtest) cxx_executable(gtest_break_on_failure_unittest_ test gtest)
py_test(gtest_break_on_failure_unittest) py_test(gtest_break_on_failure_unittest)
cxx_executable_with_flags( # MSVC 7.1 does not support STL with exceptions disabled.
gtest_catch_exceptions_no_ex_test_ if (NOT MSVC OR MSVC_VERSION GREATER 1310)
"${cxx_no_exception}" cxx_executable_with_flags(
gtest_main_no_exception gtest_catch_exceptions_no_ex_test_
test/gtest_catch_exceptions_test_.cc) "${cxx_no_exception}"
gtest_main_no_exception
test/gtest_catch_exceptions_test_.cc)
endif()
cxx_executable_with_flags( cxx_executable_with_flags(
gtest_catch_exceptions_ex_test_ gtest_catch_exceptions_ex_test_
"${cxx_exception}" "${cxx_exception}"
@@ -222,11 +231,14 @@ if (gtest_build_tests)
cxx_executable(gtest_shuffle_test_ test gtest) cxx_executable(gtest_shuffle_test_ test gtest)
py_test(gtest_shuffle_test) py_test(gtest_shuffle_test)
cxx_executable(gtest_throw_on_failure_test_ test gtest_no_exception) # MSVC 7.1 does not support STL with exceptions disabled.
set_target_properties(gtest_throw_on_failure_test_ if (NOT MSVC OR MSVC_VERSION GREATER 1310)
PROPERTIES cxx_executable(gtest_throw_on_failure_test_ test gtest_no_exception)
COMPILE_FLAGS "${cxx_no_exception}") set_target_properties(gtest_throw_on_failure_test_
py_test(gtest_throw_on_failure_test) PROPERTIES
COMPILE_FLAGS "${cxx_no_exception}")
py_test(gtest_throw_on_failure_test)
endif()
cxx_executable(gtest_uninitialized_test_ test gtest) cxx_executable(gtest_uninitialized_test_ test gtest)
py_test(gtest_uninitialized_test) py_test(gtest_uninitialized_test)
View File
+4
View File
@@ -6,6 +6,7 @@ ACLOCAL_AMFLAGS = -I m4
EXTRA_DIST = \ EXTRA_DIST = \
CHANGES \ CHANGES \
CONTRIBUTORS \ CONTRIBUTORS \
LICENSE \
include/gtest/gtest-param-test.h.pump \ include/gtest/gtest-param-test.h.pump \
include/gtest/internal/gtest-param-util-generated.h.pump \ include/gtest/internal/gtest-param-util-generated.h.pump \
include/gtest/internal/gtest-tuple.h.pump \ include/gtest/internal/gtest-tuple.h.pump \
@@ -57,6 +58,7 @@ EXTRA_DIST += \
test/gtest-param-test_test.cc \ test/gtest-param-test_test.cc \
test/gtest-param-test_test.h \ test/gtest-param-test_test.h \
test/gtest-port_test.cc \ test/gtest-port_test.cc \
test/gtest_premature_exit_test.cc \
test/gtest-printers_test.cc \ test/gtest-printers_test.cc \
test/gtest-test-part_test.cc \ test/gtest-test-part_test.cc \
test/gtest-tuple_test.cc \ test/gtest-tuple_test.cc \
@@ -261,6 +263,7 @@ FUSED_GTEST_SRC = \
fused-src/gtest/gtest.h \ fused-src/gtest/gtest.h \
fused-src/gtest/gtest_main.cc fused-src/gtest/gtest_main.cc
if HAVE_PYTHON
TESTS += test/fused_gtest_test TESTS += test/fused_gtest_test
check_PROGRAMS += test/fused_gtest_test check_PROGRAMS += test/fused_gtest_test
test_fused_gtest_test_SOURCES = $(FUSED_GTEST_SRC) \ test_fused_gtest_test_SOURCES = $(FUSED_GTEST_SRC) \
@@ -284,6 +287,7 @@ fused-gtest: $(pkginclude_HEADERS) $(pkginclude_internal_HEADERS) \
maintainer-clean-local: maintainer-clean-local:
rm -rf "$(srcdir)/fused-src" rm -rf "$(srcdir)/fused-src"
endif
# Death tests may produce core dumps in the build directory. In case # Death tests may produce core dumps in the build directory. In case
# this happens, clean them to keep distcleancheck happy. # this happens, clean them to keep distcleancheck happy.
+21 -10
View File
@@ -119,21 +119,22 @@ and Xcode) to compile
${GTEST_DIR}/src/gtest-all.cc ${GTEST_DIR}/src/gtest-all.cc
with with ${GTEST_DIR}/include in the system header search path and ${GTEST_DIR}
in the normal header search path. Assuming a Linux-like system and gcc,
${GTEST_DIR}/include and ${GTEST_DIR}
in the header search path. Assuming a Linux-like system and gcc,
something like the following will do: something like the following will do:
g++ -I${GTEST_DIR}/include -I${GTEST_DIR} -c ${GTEST_DIR}/src/gtest-all.cc g++ -isystem ${GTEST_DIR}/include -I${GTEST_DIR} \
-pthread -c ${GTEST_DIR}/src/gtest-all.cc
ar -rv libgtest.a gtest-all.o ar -rv libgtest.a gtest-all.o
Next, you should compile your test source file with (We need -pthread as Google Test uses threads.)
${GTEST_DIR}/include in the header search path, and link it with gtest
and any other necessary libraries:
g++ -I${GTEST_DIR}/include path/to/your_test.cc libgtest.a -o your_test Next, you should compile your test source file with
${GTEST_DIR}/include in the system header search path, and link it
with gtest and any other necessary libraries:
g++ -isystem ${GTEST_DIR}/include -pthread path/to/your_test.cc libgtest.a \
-o your_test
As an example, the make/ directory contains a Makefile that you can As an example, the make/ directory contains a Makefile that you can
use to build Google Test on systems where GNU make is available use to build Google Test on systems where GNU make is available
@@ -217,6 +218,16 @@ default build location. See the "xcodebuild" man page for more
information about building different configurations and building in information about building different configurations and building in
different locations. different locations.
If you wish to use the Google Test Xcode project with Xcode 4.x and
above, you need to either:
* update the SDK configuration options in xcode/Config/General.xconfig.
Comment options SDKROOT, MACOS_DEPLOYMENT_TARGET, and GCC_VERSION. If
you choose this route you lose the ability to target earlier versions
of MacOS X.
* Install an SDK for an earlier version. This doesn't appear to be
supported by Apple, but has been reported to work
(http://stackoverflow.com/questions/5378518).
Tweaking Google Test Tweaking Google Test
-------------------- --------------------
+12 -1
View File
@@ -56,6 +56,16 @@ macro(config_compiler_and_linker)
# Newlines inside flags variables break CMake's NMake generator. # Newlines inside flags variables break CMake's NMake generator.
# TODO(vladl@google.com): Add -RTCs and -RTCu to debug builds. # TODO(vladl@google.com): Add -RTCs and -RTCu to debug builds.
set(cxx_base_flags "-GS -W4 -WX -wd4127 -wd4251 -wd4275 -nologo -J -Zi") set(cxx_base_flags "-GS -W4 -WX -wd4127 -wd4251 -wd4275 -nologo -J -Zi")
if (MSVC_VERSION LESS 1400)
# Suppress spurious warnings MSVC 7.1 sometimes issues.
# Forcing value to bool.
set(cxx_base_flags "${cxx_base_flags} -wd4800")
# Copy constructor and assignment operator could not be generated.
set(cxx_base_flags "${cxx_base_flags} -wd4511 -wd4512")
# Compatibility warnings not applicable to Google Test.
# Resolved overload was found by argument-dependent lookup.
set(cxx_base_flags "${cxx_base_flags} -wd4675")
endif()
set(cxx_base_flags "${cxx_base_flags} -D_UNICODE -DUNICODE -DWIN32 -D_WIN32") set(cxx_base_flags "${cxx_base_flags} -D_UNICODE -DUNICODE -DWIN32 -D_WIN32")
set(cxx_base_flags "${cxx_base_flags} -DSTRICT -DWIN32_LEAN_AND_MEAN") set(cxx_base_flags "${cxx_base_flags} -DSTRICT -DWIN32_LEAN_AND_MEAN")
set(cxx_exception_flags "-EHsc -D_HAS_EXCEPTIONS=1") set(cxx_exception_flags "-EHsc -D_HAS_EXCEPTIONS=1")
@@ -69,7 +79,8 @@ macro(config_compiler_and_linker)
# whether RTTI is enabled. Therefore we define GTEST_HAS_RTTI # whether RTTI is enabled. Therefore we define GTEST_HAS_RTTI
# explicitly. # explicitly.
set(cxx_no_rtti_flags "-fno-rtti -DGTEST_HAS_RTTI=0") set(cxx_no_rtti_flags "-fno-rtti -DGTEST_HAS_RTTI=0")
set(cxx_strict_flags "-Wextra") set(cxx_strict_flags
"-Wextra -Wno-unused-parameter -Wno-missing-field-initializers")
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "SunPro") elseif (CMAKE_CXX_COMPILER_ID STREQUAL "SunPro")
set(cxx_exception_flags "-features=except") set(cxx_exception_flags "-features=except")
# Sun Pro doesn't provide macros to indicate whether exceptions and # Sun Pro doesn't provide macros to indicate whether exceptions and
+3 -3
View File
@@ -5,13 +5,13 @@ m4_include(m4/acx_pthread.m4)
# "[1.0.1]"). It also asumes that there won't be any closing parenthesis # "[1.0.1]"). It also asumes that there won't be any closing parenthesis
# between "AC_INIT(" and the closing ")" including comments and strings. # between "AC_INIT(" and the closing ")" including comments and strings.
AC_INIT([Google C++ Testing Framework], AC_INIT([Google C++ Testing Framework],
[1.6.0], [1.7.0],
[googletestframework@googlegroups.com], [googletestframework@googlegroups.com],
[gtest]) [gtest])
# Provide various options to initialize the Autoconf and configure processes. # Provide various options to initialize the Autoconf and configure processes.
AC_PREREQ([2.59]) AC_PREREQ([2.59])
AC_CONFIG_SRCDIR([./COPYING]) AC_CONFIG_SRCDIR([./LICENSE])
AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_AUX_DIR([build-aux]) AC_CONFIG_AUX_DIR([build-aux])
AC_CONFIG_HEADERS([build-aux/config.h]) AC_CONFIG_HEADERS([build-aux/config.h])
@@ -55,7 +55,7 @@ AS_IF([test "x$with_pthreads" != "xno"],
[AC_MSG_FAILURE( [AC_MSG_FAILURE(
[--with-pthreads was specified, but unable to be used])])]) [--with-pthreads was specified, but unable to be used])])])
have_pthreads="$acx_pthread_ok"]) have_pthreads="$acx_pthread_ok"])
AM_CONDITIONAL([HAVE_PTHREADS],[test "x$have_pthreads" == "xyes"]) AM_CONDITIONAL([HAVE_PTHREADS],[test "x$have_pthreads" = "xyes"])
AC_SUBST(PTHREAD_CFLAGS) AC_SUBST(PTHREAD_CFLAGS)
AC_SUBST(PTHREAD_LIBS) AC_SUBST(PTHREAD_LIBS)
+14 -3
View File
@@ -51,6 +51,17 @@ GTEST_DECLARE_string_(death_test_style);
#if GTEST_HAS_DEATH_TEST #if GTEST_HAS_DEATH_TEST
namespace internal {
// Returns a Boolean value indicating whether the caller is currently
// executing in the context of the death test child process. Tools such as
// Valgrind heap checkers may need this to modify their behavior in death
// tests. IMPORTANT: This is an internal utility. Using it may break the
// implementation of death tests. User code MUST NOT use it.
GTEST_API_ bool InDeathTestChild();
} // namespace internal
// The following macros are useful for writing death tests. // The following macros are useful for writing death tests.
// Here's what happens when an ASSERT_DEATH* or EXPECT_DEATH* is // Here's what happens when an ASSERT_DEATH* or EXPECT_DEATH* is
@@ -75,7 +86,7 @@ GTEST_DECLARE_string_(death_test_style);
// for (int i = 0; i < 5; i++) { // for (int i = 0; i < 5; i++) {
// EXPECT_DEATH(server.ProcessRequest(i), // EXPECT_DEATH(server.ProcessRequest(i),
// "Invalid request .* in ProcessRequest()") // "Invalid request .* in ProcessRequest()")
// << "Failed to die on request " << i); // << "Failed to die on request " << i;
// } // }
// //
// ASSERT_EXIT(server.ExitNow(), ::testing::ExitedWithCode(0), "Exiting"); // ASSERT_EXIT(server.ExitNow(), ::testing::ExitedWithCode(0), "Exiting");
@@ -245,10 +256,10 @@ class GTEST_API_ KilledBySignal {
# ifdef NDEBUG # ifdef NDEBUG
# define EXPECT_DEBUG_DEATH(statement, regex) \ # define EXPECT_DEBUG_DEATH(statement, regex) \
do { statement; } while (::testing::internal::AlwaysFalse()) GTEST_EXECUTE_STATEMENT_(statement, regex)
# define ASSERT_DEBUG_DEATH(statement, regex) \ # define ASSERT_DEBUG_DEATH(statement, regex) \
do { statement; } while (::testing::internal::AlwaysFalse()) GTEST_EXECUTE_STATEMENT_(statement, regex)
# else # else
+47 -27
View File
@@ -48,8 +48,11 @@
#include <limits> #include <limits>
#include "gtest/internal/gtest-string.h" #include "gtest/internal/gtest-port.h"
#include "gtest/internal/gtest-internal.h"
// Ensures that there is at least one operator<< in the global namespace.
// See Message& operator<<(...) below for why.
void operator<<(const testing::internal::Secret&, int);
namespace testing { namespace testing {
@@ -87,15 +90,7 @@ class GTEST_API_ Message {
public: public:
// Constructs an empty Message. // Constructs an empty Message.
// We allocate the stringstream separately because otherwise each use of Message();
// ASSERT/EXPECT in a procedure adds over 200 bytes to the procedure's
// stack frame leading to huge stack frames in some cases; gcc does not reuse
// the stack space.
Message() : ss_(new ::std::stringstream) {
// By default, we want there to be enough precision when printing
// a double to a Message.
*ss_ << std::setprecision(std::numeric_limits<double>::digits10 + 2);
}
// Copy constructor. // Copy constructor.
Message(const Message& msg) : ss_(new ::std::stringstream) { // NOLINT Message(const Message& msg) : ss_(new ::std::stringstream) { // NOLINT
@@ -118,7 +113,22 @@ class GTEST_API_ Message {
// Streams a non-pointer value to this object. // Streams a non-pointer value to this object.
template <typename T> template <typename T>
inline Message& operator <<(const T& val) { inline Message& operator <<(const T& val) {
::GTestStreamToHelper(ss_.get(), val); // Some libraries overload << for STL containers. These
// overloads are defined in the global namespace instead of ::std.
//
// C++'s symbol lookup rule (i.e. Koenig lookup) says that these
// overloads are visible in either the std namespace or the global
// namespace, but not other namespaces, including the testing
// namespace which Google Test's Message class is in.
//
// To allow STL containers (and other types that has a << operator
// defined in the global namespace) to be used in Google Test
// assertions, testing::Message must access the custom << operator
// from the global namespace. With this using declaration,
// overloads of << defined in the global namespace and those
// visible via Koenig lookup are both exposed in this function.
using ::operator <<;
*ss_ << val;
return *this; return *this;
} }
@@ -140,7 +150,7 @@ class GTEST_API_ Message {
if (pointer == NULL) { if (pointer == NULL) {
*ss_ << "(null)"; *ss_ << "(null)";
} else { } else {
::GTestStreamToHelper(ss_.get(), pointer); *ss_ << pointer;
} }
return *this; return *this;
} }
@@ -164,12 +174,8 @@ class GTEST_API_ Message {
// These two overloads allow streaming a wide C string to a Message // These two overloads allow streaming a wide C string to a Message
// using the UTF-8 encoding. // using the UTF-8 encoding.
Message& operator <<(const wchar_t* wide_c_str) { Message& operator <<(const wchar_t* wide_c_str);
return *this << internal::String::ShowWideCString(wide_c_str); Message& operator <<(wchar_t* wide_c_str);
}
Message& operator <<(wchar_t* wide_c_str) {
return *this << internal::String::ShowWideCString(wide_c_str);
}
#if GTEST_HAS_STD_WSTRING #if GTEST_HAS_STD_WSTRING
// Converts the given wide string to a narrow string using the UTF-8 // Converts the given wide string to a narrow string using the UTF-8
@@ -183,13 +189,11 @@ class GTEST_API_ Message {
Message& operator <<(const ::wstring& wstr); Message& operator <<(const ::wstring& wstr);
#endif // GTEST_HAS_GLOBAL_WSTRING #endif // GTEST_HAS_GLOBAL_WSTRING
// Gets the text streamed to this object so far as a String. // Gets the text streamed to this object so far as an std::string.
// Each '\0' character in the buffer is replaced with "\\0". // Each '\0' character in the buffer is replaced with "\\0".
// //
// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
internal::String GetString() const { std::string GetString() const;
return internal::StringStreamToString(ss_.get());
}
private: private:
@@ -199,16 +203,20 @@ class GTEST_API_ Message {
// decide between class template specializations for T and T*, so a // decide between class template specializations for T and T*, so a
// tr1::type_traits-like is_pointer works, and we can overload on that. // tr1::type_traits-like is_pointer works, and we can overload on that.
template <typename T> template <typename T>
inline void StreamHelper(internal::true_type /*dummy*/, T* pointer) { inline void StreamHelper(internal::true_type /*is_pointer*/, T* pointer) {
if (pointer == NULL) { if (pointer == NULL) {
*ss_ << "(null)"; *ss_ << "(null)";
} else { } else {
::GTestStreamToHelper(ss_.get(), pointer); *ss_ << pointer;
} }
} }
template <typename T> template <typename T>
inline void StreamHelper(internal::false_type /*dummy*/, const T& value) { inline void StreamHelper(internal::false_type /*is_pointer*/,
::GTestStreamToHelper(ss_.get(), value); const T& value) {
// See the comments in Message& operator <<(const T&) above for why
// we need this using statement.
using ::operator <<;
*ss_ << value;
} }
#endif // GTEST_OS_SYMBIAN #endif // GTEST_OS_SYMBIAN
@@ -225,6 +233,18 @@ inline std::ostream& operator <<(std::ostream& os, const Message& sb) {
return os << sb.GetString(); return os << sb.GetString();
} }
namespace internal {
// Converts a streamable value to an std::string. A NULL pointer is
// converted to "(null)". When the input value is a ::string,
// ::std::string, ::wstring, or ::std::wstring object, each NUL
// character in it is replaced with "\\0".
template <typename T>
std::string StreamableToString(const T& streamable) {
return (Message() << streamable).GetString();
}
} // namespace internal
} // namespace testing } // namespace testing
#endif // GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_ #endif // GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_
+1 -1
View File
@@ -1257,7 +1257,7 @@ inline internal::ParamGenerator<bool> Bool() {
// Boolean flags: // Boolean flags:
// //
// class FlagDependentTest // class FlagDependentTest
// : public testing::TestWithParam<tuple(bool, bool)> > { // : public testing::TestWithParam<tuple<bool, bool> > {
// virtual void SetUp() { // virtual void SetUp() {
// // Assigns external_flag_1 and external_flag_2 values from the tuple. // // Assigns external_flag_1 and external_flag_2 values from the tuple.
// tie(external_flag_1, external_flag_2) = GetParam(); // tie(external_flag_1, external_flag_2) = GetParam();
+1 -1
View File
@@ -414,7 +414,7 @@ inline internal::ParamGenerator<bool> Bool() {
// Boolean flags: // Boolean flags:
// //
// class FlagDependentTest // class FlagDependentTest
// : public testing::TestWithParam<tuple(bool, bool)> > { // : public testing::TestWithParam<tuple<bool, bool> > {
// virtual void SetUp() { // virtual void SetUp() {
// // Assigns external_flag_1 and external_flag_2 values from the tuple. // // Assigns external_flag_1 and external_flag_2 values from the tuple.
// tie(external_flag_1, external_flag_2) = GetParam(); // tie(external_flag_1, external_flag_2) = GetParam();
+75 -16
View File
@@ -630,9 +630,12 @@ void UniversalPrintArray(const T* begin, size_t len, ::std::ostream* os) {
} }
} }
// This overload prints a (const) char array compactly. // This overload prints a (const) char array compactly.
GTEST_API_ void UniversalPrintArray(const char* begin, GTEST_API_ void UniversalPrintArray(
size_t len, const char* begin, size_t len, ::std::ostream* os);
::std::ostream* os);
// This overload prints a (const) wchar_t array compactly.
GTEST_API_ void UniversalPrintArray(
const wchar_t* begin, size_t len, ::std::ostream* os);
// Implements printing an array type T[N]. // Implements printing an array type T[N].
template <typename T, size_t N> template <typename T, size_t N>
@@ -673,19 +676,72 @@ class UniversalPrinter<T&> {
// Prints a value tersely: for a reference type, the referenced value // Prints a value tersely: for a reference type, the referenced value
// (but not the address) is printed; for a (const) char pointer, the // (but not the address) is printed; for a (const) char pointer, the
// NUL-terminated string (but not the pointer) is printed. // NUL-terminated string (but not the pointer) is printed.
template <typename T>
class UniversalTersePrinter {
public:
static void Print(const T& value, ::std::ostream* os) {
UniversalPrint(value, os);
}
};
template <typename T>
class UniversalTersePrinter<T&> {
public:
static void Print(const T& value, ::std::ostream* os) {
UniversalPrint(value, os);
}
};
template <typename T, size_t N>
class UniversalTersePrinter<T[N]> {
public:
static void Print(const T (&value)[N], ::std::ostream* os) {
UniversalPrinter<T[N]>::Print(value, os);
}
};
template <>
class UniversalTersePrinter<const char*> {
public:
static void Print(const char* str, ::std::ostream* os) {
if (str == NULL) {
*os << "NULL";
} else {
UniversalPrint(string(str), os);
}
}
};
template <>
class UniversalTersePrinter<char*> {
public:
static void Print(char* str, ::std::ostream* os) {
UniversalTersePrinter<const char*>::Print(str, os);
}
};
#if GTEST_HAS_STD_WSTRING
template <>
class UniversalTersePrinter<const wchar_t*> {
public:
static void Print(const wchar_t* str, ::std::ostream* os) {
if (str == NULL) {
*os << "NULL";
} else {
UniversalPrint(::std::wstring(str), os);
}
}
};
#endif
template <>
class UniversalTersePrinter<wchar_t*> {
public:
static void Print(wchar_t* str, ::std::ostream* os) {
UniversalTersePrinter<const wchar_t*>::Print(str, os);
}
};
template <typename T> template <typename T>
void UniversalTersePrint(const T& value, ::std::ostream* os) { void UniversalTersePrint(const T& value, ::std::ostream* os) {
UniversalPrint(value, os); UniversalTersePrinter<T>::Print(value, os);
}
inline void UniversalTersePrint(const char* str, ::std::ostream* os) {
if (str == NULL) {
*os << "NULL";
} else {
UniversalPrint(string(str), os);
}
}
inline void UniversalTersePrint(char* str, ::std::ostream* os) {
UniversalTersePrint(static_cast<const char*>(str), os);
} }
// Prints a value using the type inferred by the compiler. The // Prints a value using the type inferred by the compiler. The
@@ -694,7 +750,10 @@ inline void UniversalTersePrint(char* str, ::std::ostream* os) {
// NUL-terminated string. // NUL-terminated string.
template <typename T> template <typename T>
void UniversalPrint(const T& value, ::std::ostream* os) { void UniversalPrint(const T& value, ::std::ostream* os) {
UniversalPrinter<T>::Print(value, os); // A workarond for the bug in VC++ 7.1 that prevents us from instantiating
// UniversalPrinter with T directly.
typedef T T1;
UniversalPrinter<T1>::Print(value, os);
} }
#if GTEST_HAS_TR1_TUPLE #if GTEST_HAS_TR1_TUPLE
@@ -787,7 +846,7 @@ Strings UniversalTersePrintTupleFieldsToStrings(const Tuple& value) {
template <typename T> template <typename T>
::std::string PrintToString(const T& value) { ::std::string PrintToString(const T& value) {
::std::stringstream ss; ::std::stringstream ss;
internal::UniversalTersePrint(value, &ss); internal::UniversalTersePrinter<T>::Print(value, &ss);
return ss.str(); return ss.str();
} }
+1 -1
View File
@@ -223,7 +223,7 @@ class GTEST_API_ SingleFailureChecker {
(substr));\ (substr));\
{\ {\
::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\
::testing::ScopedFakeTestPartResultReporter::INTERCEPT_ALL_THREADS,\ ::testing::ScopedFakeTestPartResultReporter::INTERCEPT_ALL_THREADS, \
&gtest_failures);\ &gtest_failures);\
if (::testing::internal::AlwaysTrue()) { statement; }\ if (::testing::internal::AlwaysTrue()) { statement; }\
}\ }\
+10 -7
View File
@@ -62,7 +62,7 @@ class GTEST_API_ TestPartResult {
int a_line_number, int a_line_number,
const char* a_message) const char* a_message)
: type_(a_type), : type_(a_type),
file_name_(a_file_name), file_name_(a_file_name == NULL ? "" : a_file_name),
line_number_(a_line_number), line_number_(a_line_number),
summary_(ExtractSummary(a_message)), summary_(ExtractSummary(a_message)),
message_(a_message) { message_(a_message) {
@@ -73,7 +73,9 @@ class GTEST_API_ TestPartResult {
// Gets the name of the source file where the test part took place, or // Gets the name of the source file where the test part took place, or
// NULL if it's unknown. // NULL if it's unknown.
const char* file_name() const { return file_name_.c_str(); } const char* file_name() const {
return file_name_.empty() ? NULL : file_name_.c_str();
}
// Gets the line in the source file where the test part took place, // Gets the line in the source file where the test part took place,
// or -1 if it's unknown. // or -1 if it's unknown.
@@ -96,21 +98,22 @@ class GTEST_API_ TestPartResult {
// Returns true iff the test part fatally failed. // Returns true iff the test part fatally failed.
bool fatally_failed() const { return type_ == kFatalFailure; } bool fatally_failed() const { return type_ == kFatalFailure; }
private: private:
Type type_; Type type_;
// Gets the summary of the failure message by omitting the stack // Gets the summary of the failure message by omitting the stack
// trace in it. // trace in it.
static internal::String ExtractSummary(const char* message); static std::string ExtractSummary(const char* message);
// The name of the source file where the test part took place, or // The name of the source file where the test part took place, or
// NULL if the source file is unknown. // "" if the source file is unknown.
internal::String file_name_; std::string file_name_;
// The line in the source file where the test part took place, or -1 // The line in the source file where the test part took place, or -1
// if the line number is unknown. // if the line number is unknown.
int line_number_; int line_number_;
internal::String summary_; // The test failure summary. std::string summary_; // The test failure summary.
internal::String message_; // The test failure message. std::string message_; // The test failure message.
}; };
// Prints a TestPartResult object. // Prints a TestPartResult object.
+220 -84
View File
@@ -52,6 +52,7 @@
#define GTEST_INCLUDE_GTEST_GTEST_H_ #define GTEST_INCLUDE_GTEST_GTEST_H_
#include <limits> #include <limits>
#include <ostream>
#include <vector> #include <vector>
#include "gtest/internal/gtest-internal.h" #include "gtest/internal/gtest-internal.h"
@@ -153,25 +154,15 @@ class ExecDeathTest;
class NoExecDeathTest; class NoExecDeathTest;
class FinalSuccessChecker; class FinalSuccessChecker;
class GTestFlagSaver; class GTestFlagSaver;
class StreamingListenerTest;
class TestResultAccessor; class TestResultAccessor;
class TestEventListenersAccessor; class TestEventListenersAccessor;
class TestEventRepeater; class TestEventRepeater;
class UnitTestRecordPropertyTestHelper;
class WindowsDeathTest; class WindowsDeathTest;
class UnitTestImpl* GetUnitTestImpl(); class UnitTestImpl* GetUnitTestImpl();
void ReportFailureInUnknownLocation(TestPartResult::Type result_type, void ReportFailureInUnknownLocation(TestPartResult::Type result_type,
const String& message); const std::string& message);
// Converts a streamable value to a String. A NULL pointer is
// converted to "(null)". When the input value is a ::string,
// ::std::string, ::wstring, or ::std::wstring object, each NUL
// character in it is replaced with "\\0".
// Declared in gtest-internal.h but defined here, so that it has access
// to the definition of the Message class, required by the ARM
// compiler.
template <typename T>
String StreamableToString(const T& streamable) {
return (Message() << streamable).GetString();
}
} // namespace internal } // namespace internal
@@ -391,20 +382,21 @@ class GTEST_API_ Test {
// non-fatal) failure. // non-fatal) failure.
static bool HasFailure() { return HasFatalFailure() || HasNonfatalFailure(); } static bool HasFailure() { return HasFatalFailure() || HasNonfatalFailure(); }
// Logs a property for the current test. Only the last value for a given // Logs a property for the current test, test case, or for the entire
// key is remembered. // invocation of the test program when used outside of the context of a
// These are public static so they can be called from utility functions // test case. Only the last value for a given key is remembered. These
// that are not members of the test fixture. // are public static so they can be called from utility functions that are
// The arguments are const char* instead strings, as Google Test is used // not members of the test fixture. Calls to RecordProperty made during
// on platforms where string doesn't compile. // lifespan of the test (from the moment its constructor starts to the
// // moment its destructor finishes) will be output in XML as attributes of
// Note that a driving consideration for these RecordProperty methods // the <testcase> element. Properties recorded from fixture's
// was to produce xml output suited to the Greenspan charting utility, // SetUpTestCase or TearDownTestCase are logged as attributes of the
// which at present will only chart values that fit in a 32-bit int. It // corresponding <testsuite> element. Calls to RecordProperty made in the
// is the user's responsibility to restrict their values to 32-bit ints // global context (before or after invocation of RUN_ALL_TESTS and from
// if they intend them to be used with Greenspan. // SetUp/TearDown method of Environment objects registered with Google
static void RecordProperty(const char* key, const char* value); // Test) will be output as attributes of the <testsuites> element.
static void RecordProperty(const char* key, int value); static void RecordProperty(const std::string& key, const std::string& value);
static void RecordProperty(const std::string& key, int value);
protected: protected:
// Creates a Test object. // Creates a Test object.
@@ -473,7 +465,7 @@ class TestProperty {
// C'tor. TestProperty does NOT have a default constructor. // C'tor. TestProperty does NOT have a default constructor.
// Always use this constructor (with parameters) to create a // Always use this constructor (with parameters) to create a
// TestProperty object. // TestProperty object.
TestProperty(const char* a_key, const char* a_value) : TestProperty(const std::string& a_key, const std::string& a_value) :
key_(a_key), value_(a_value) { key_(a_key), value_(a_value) {
} }
@@ -488,15 +480,15 @@ class TestProperty {
} }
// Sets a new value, overriding the one supplied in the constructor. // Sets a new value, overriding the one supplied in the constructor.
void SetValue(const char* new_value) { void SetValue(const std::string& new_value) {
value_ = new_value; value_ = new_value;
} }
private: private:
// The key supplied by the user. // The key supplied by the user.
internal::String key_; std::string key_;
// The value supplied by the user. // The value supplied by the user.
internal::String value_; std::string value_;
}; };
// The result of a single Test. This includes a list of // The result of a single Test. This includes a list of
@@ -547,6 +539,7 @@ class GTEST_API_ TestResult {
private: private:
friend class TestInfo; friend class TestInfo;
friend class TestCase;
friend class UnitTest; friend class UnitTest;
friend class internal::DefaultGlobalTestPartResultReporter; friend class internal::DefaultGlobalTestPartResultReporter;
friend class internal::ExecDeathTest; friend class internal::ExecDeathTest;
@@ -571,13 +564,16 @@ class GTEST_API_ TestResult {
// a non-fatal failure if invalid (e.g., if it conflicts with reserved // a non-fatal failure if invalid (e.g., if it conflicts with reserved
// key names). If a property is already recorded for the same key, the // key names). If a property is already recorded for the same key, the
// value will be updated, rather than storing multiple values for the same // value will be updated, rather than storing multiple values for the same
// key. // key. xml_element specifies the element for which the property is being
void RecordProperty(const TestProperty& test_property); // recorded and is used for validation.
void RecordProperty(const std::string& xml_element,
const TestProperty& test_property);
// Adds a failure if the key is a reserved attribute of Google Test // Adds a failure if the key is a reserved attribute of Google Test
// testcase tags. Returns true if the property is valid. // testcase tags. Returns true if the property is valid.
// TODO(russr): Validate attribute names are legal and human readable. // TODO(russr): Validate attribute names are legal and human readable.
static bool ValidateTestProperty(const TestProperty& test_property); static bool ValidateTestProperty(const std::string& xml_element,
const TestProperty& test_property);
// Adds a test part result to the list. // Adds a test part result to the list.
void AddTestPartResult(const TestPartResult& test_part_result); void AddTestPartResult(const TestPartResult& test_part_result);
@@ -650,9 +646,9 @@ class GTEST_API_ TestInfo {
return NULL; return NULL;
} }
// Returns true if this test should run, that is if the test is not disabled // Returns true if this test should run, that is if the test is not
// (or it is disabled but the also_run_disabled_tests flag has been specified) // disabled (or it is disabled but the also_run_disabled_tests flag has
// and its full name matches the user-specified filter. // been specified) and its full name matches the user-specified filter.
// //
// Google Test allows the user to filter the tests by their full names. // Google Test allows the user to filter the tests by their full names.
// The full name of a test Bar in test case Foo is defined as // The full name of a test Bar in test case Foo is defined as
@@ -668,19 +664,28 @@ class GTEST_API_ TestInfo {
// contains the character 'A' or starts with "Foo.". // contains the character 'A' or starts with "Foo.".
bool should_run() const { return should_run_; } bool should_run() const { return should_run_; }
// Returns true iff this test will appear in the XML report.
bool is_reportable() const {
// For now, the XML report includes all tests matching the filter.
// In the future, we may trim tests that are excluded because of
// sharding.
return matches_filter_;
}
// Returns the result of the test. // Returns the result of the test.
const TestResult* result() const { return &result_; } const TestResult* result() const { return &result_; }
private: private:
#if GTEST_HAS_DEATH_TEST #if GTEST_HAS_DEATH_TEST
friend class internal::DefaultDeathTestFactory; friend class internal::DefaultDeathTestFactory;
#endif // GTEST_HAS_DEATH_TEST #endif // GTEST_HAS_DEATH_TEST
friend class Test; friend class Test;
friend class TestCase; friend class TestCase;
friend class internal::UnitTestImpl; friend class internal::UnitTestImpl;
friend class internal::StreamingListenerTest;
friend TestInfo* internal::MakeAndRegisterTestInfo( friend TestInfo* internal::MakeAndRegisterTestInfo(
const char* test_case_name, const char* name, const char* test_case_name,
const char* name,
const char* type_param, const char* type_param,
const char* value_param, const char* value_param,
internal::TypeId fixture_class_id, internal::TypeId fixture_class_id,
@@ -690,9 +695,10 @@ class GTEST_API_ TestInfo {
// Constructs a TestInfo object. The newly constructed instance assumes // Constructs a TestInfo object. The newly constructed instance assumes
// ownership of the factory object. // ownership of the factory object.
TestInfo(const char* test_case_name, const char* name, TestInfo(const std::string& test_case_name,
const char* a_type_param, const std::string& name,
const char* a_value_param, const char* a_type_param, // NULL if not a type-parameterized test
const char* a_value_param, // NULL if not a value-parameterized test
internal::TypeId fixture_class_id, internal::TypeId fixture_class_id,
internal::TestFactoryBase* factory); internal::TestFactoryBase* factory);
@@ -778,9 +784,15 @@ class GTEST_API_ TestCase {
// Gets the number of failed tests in this test case. // Gets the number of failed tests in this test case.
int failed_test_count() const; int failed_test_count() const;
// Gets the number of disabled tests that will be reported in the XML report.
int reportable_disabled_test_count() const;
// Gets the number of disabled tests in this test case. // Gets the number of disabled tests in this test case.
int disabled_test_count() const; int disabled_test_count() const;
// Gets the number of tests to be printed in the XML report.
int reportable_test_count() const;
// Get the number of tests in this test case that should run. // Get the number of tests in this test case that should run.
int test_to_run_count() const; int test_to_run_count() const;
@@ -800,6 +812,10 @@ class GTEST_API_ TestCase {
// total_test_count() - 1. If i is not in that range, returns NULL. // total_test_count() - 1. If i is not in that range, returns NULL.
const TestInfo* GetTestInfo(int i) const; const TestInfo* GetTestInfo(int i) const;
// Returns the TestResult that holds test properties recorded during
// execution of SetUpTestCase and TearDownTestCase.
const TestResult& ad_hoc_test_result() const { return ad_hoc_test_result_; }
private: private:
friend class Test; friend class Test;
friend class internal::UnitTestImpl; friend class internal::UnitTestImpl;
@@ -852,11 +868,22 @@ class GTEST_API_ TestCase {
return test_info->should_run() && test_info->result()->Failed(); return test_info->should_run() && test_info->result()->Failed();
} }
// Returns true iff the test is disabled and will be reported in the XML
// report.
static bool TestReportableDisabled(const TestInfo* test_info) {
return test_info->is_reportable() && test_info->is_disabled_;
}
// Returns true iff test is disabled. // Returns true iff test is disabled.
static bool TestDisabled(const TestInfo* test_info) { static bool TestDisabled(const TestInfo* test_info) {
return test_info->is_disabled_; return test_info->is_disabled_;
} }
// Returns true iff this test will appear in the XML report.
static bool TestReportable(const TestInfo* test_info) {
return test_info->is_reportable();
}
// Returns true if the given test should run. // Returns true if the given test should run.
static bool ShouldRunTest(const TestInfo* test_info) { static bool ShouldRunTest(const TestInfo* test_info) {
return test_info->should_run(); return test_info->should_run();
@@ -869,7 +896,7 @@ class GTEST_API_ TestCase {
void UnshuffleTests(); void UnshuffleTests();
// Name of the test case. // Name of the test case.
internal::String name_; std::string name_;
// Name of the parameter type, or NULL if this is not a typed or a // Name of the parameter type, or NULL if this is not a typed or a
// type-parameterized test. // type-parameterized test.
const internal::scoped_ptr<const ::std::string> type_param_; const internal::scoped_ptr<const ::std::string> type_param_;
@@ -888,6 +915,9 @@ class GTEST_API_ TestCase {
bool should_run_; bool should_run_;
// Elapsed time, in milliseconds. // Elapsed time, in milliseconds.
TimeInMillis elapsed_time_; TimeInMillis elapsed_time_;
// Holds test properties recorded during execution of SetUpTestCase and
// TearDownTestCase.
TestResult ad_hoc_test_result_;
// We disallow copying TestCases. // We disallow copying TestCases.
GTEST_DISALLOW_COPY_AND_ASSIGN_(TestCase); GTEST_DISALLOW_COPY_AND_ASSIGN_(TestCase);
@@ -1107,11 +1137,13 @@ class GTEST_API_ UnitTest {
// Returns the TestCase object for the test that's currently running, // Returns the TestCase object for the test that's currently running,
// or NULL if no test is running. // or NULL if no test is running.
const TestCase* current_test_case() const; const TestCase* current_test_case() const
GTEST_LOCK_EXCLUDED_(mutex_);
// Returns the TestInfo object for the test that's currently running, // Returns the TestInfo object for the test that's currently running,
// or NULL if no test is running. // or NULL if no test is running.
const TestInfo* current_test_info() const; const TestInfo* current_test_info() const
GTEST_LOCK_EXCLUDED_(mutex_);
// Returns the random seed used at the start of the current test run. // Returns the random seed used at the start of the current test run.
int random_seed() const; int random_seed() const;
@@ -1121,7 +1153,8 @@ class GTEST_API_ UnitTest {
// value-parameterized tests and instantiate and register them. // value-parameterized tests and instantiate and register them.
// //
// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
internal::ParameterizedTestCaseRegistry& parameterized_test_registry(); internal::ParameterizedTestCaseRegistry& parameterized_test_registry()
GTEST_LOCK_EXCLUDED_(mutex_);
#endif // GTEST_HAS_PARAM_TEST #endif // GTEST_HAS_PARAM_TEST
// Gets the number of successful test cases. // Gets the number of successful test cases.
@@ -1143,15 +1176,25 @@ class GTEST_API_ UnitTest {
// Gets the number of failed tests. // Gets the number of failed tests.
int failed_test_count() const; int failed_test_count() const;
// Gets the number of disabled tests that will be reported in the XML report.
int reportable_disabled_test_count() const;
// Gets the number of disabled tests. // Gets the number of disabled tests.
int disabled_test_count() const; int disabled_test_count() const;
// Gets the number of tests to be printed in the XML report.
int reportable_test_count() const;
// Gets the number of all tests. // Gets the number of all tests.
int total_test_count() const; int total_test_count() const;
// Gets the number of tests that should run. // Gets the number of tests that should run.
int test_to_run_count() const; int test_to_run_count() const;
// Gets the time of the test program start, in ms from the start of the
// UNIX epoch.
TimeInMillis start_timestamp() const;
// Gets the elapsed time, in milliseconds. // Gets the elapsed time, in milliseconds.
TimeInMillis elapsed_time() const; TimeInMillis elapsed_time() const;
@@ -1166,6 +1209,10 @@ class GTEST_API_ UnitTest {
// total_test_case_count() - 1. If i is not in that range, returns NULL. // total_test_case_count() - 1. If i is not in that range, returns NULL.
const TestCase* GetTestCase(int i) const; const TestCase* GetTestCase(int i) const;
// Returns the TestResult containing information on test failures and
// properties logged outside of individual test cases.
const TestResult& ad_hoc_test_result() const;
// Returns the list of event listeners that can be used to track events // Returns the list of event listeners that can be used to track events
// inside Google Test. // inside Google Test.
TestEventListeners& listeners(); TestEventListeners& listeners();
@@ -1189,12 +1236,16 @@ class GTEST_API_ UnitTest {
void AddTestPartResult(TestPartResult::Type result_type, void AddTestPartResult(TestPartResult::Type result_type,
const char* file_name, const char* file_name,
int line_number, int line_number,
const internal::String& message, const std::string& message,
const internal::String& os_stack_trace); const std::string& os_stack_trace)
GTEST_LOCK_EXCLUDED_(mutex_);
// Adds a TestProperty to the current TestResult object. If the result already // Adds a TestProperty to the current TestResult object when invoked from
// contains a property with the same key, the value will be updated. // inside a test, to current TestCase's ad_hoc_test_result_ when invoked
void RecordPropertyForCurrentTest(const char* key, const char* value); // from SetUpTestCase or TearDownTestCase, or to the global property set
// when invoked elsewhere. If the result already contains a property with
// the same key, the value will be updated.
void RecordProperty(const std::string& key, const std::string& value);
// Gets the i-th test case among all the test cases. i can range from 0 to // Gets the i-th test case among all the test cases. i can range from 0 to
// total_test_case_count() - 1. If i is not in that range, returns NULL. // total_test_case_count() - 1. If i is not in that range, returns NULL.
@@ -1209,11 +1260,13 @@ class GTEST_API_ UnitTest {
friend class Test; friend class Test;
friend class internal::AssertHelper; friend class internal::AssertHelper;
friend class internal::ScopedTrace; friend class internal::ScopedTrace;
friend class internal::StreamingListenerTest;
friend class internal::UnitTestRecordPropertyTestHelper;
friend Environment* AddGlobalTestEnvironment(Environment* env); friend Environment* AddGlobalTestEnvironment(Environment* env);
friend internal::UnitTestImpl* internal::GetUnitTestImpl(); friend internal::UnitTestImpl* internal::GetUnitTestImpl();
friend void internal::ReportFailureInUnknownLocation( friend void internal::ReportFailureInUnknownLocation(
TestPartResult::Type result_type, TestPartResult::Type result_type,
const internal::String& message); const std::string& message);
// Creates an empty UnitTest. // Creates an empty UnitTest.
UnitTest(); UnitTest();
@@ -1223,10 +1276,12 @@ class GTEST_API_ UnitTest {
// Pushes a trace defined by SCOPED_TRACE() on to the per-thread // Pushes a trace defined by SCOPED_TRACE() on to the per-thread
// Google Test trace stack. // Google Test trace stack.
void PushGTestTrace(const internal::TraceInfo& trace); void PushGTestTrace(const internal::TraceInfo& trace)
GTEST_LOCK_EXCLUDED_(mutex_);
// Pops a trace from the per-thread Google Test trace stack. // Pops a trace from the per-thread Google Test trace stack.
void PopGTestTrace(); void PopGTestTrace()
GTEST_LOCK_EXCLUDED_(mutex_);
// Protects mutable state in *impl_. This is mutable as some const // Protects mutable state in *impl_. This is mutable as some const
// methods need to lock it too. // methods need to lock it too.
@@ -1281,24 +1336,101 @@ GTEST_API_ void InitGoogleTest(int* argc, wchar_t** argv);
namespace internal { namespace internal {
// FormatForComparison<ToPrint, OtherOperand>::Format(value) formats a
// value of type ToPrint that is an operand of a comparison assertion
// (e.g. ASSERT_EQ). OtherOperand is the type of the other operand in
// the comparison, and is used to help determine the best way to
// format the value. In particular, when the value is a C string
// (char pointer) and the other operand is an STL string object, we
// want to format the C string as a string, since we know it is
// compared by value with the string object. If the value is a char
// pointer but the other operand is not an STL string object, we don't
// know whether the pointer is supposed to point to a NUL-terminated
// string, and thus want to print it as a pointer to be safe.
//
// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
// The default case.
template <typename ToPrint, typename OtherOperand>
class FormatForComparison {
public:
static ::std::string Format(const ToPrint& value) {
return ::testing::PrintToString(value);
}
};
// Array.
template <typename ToPrint, size_t N, typename OtherOperand>
class FormatForComparison<ToPrint[N], OtherOperand> {
public:
static ::std::string Format(const ToPrint* value) {
return FormatForComparison<const ToPrint*, OtherOperand>::Format(value);
}
};
// By default, print C string as pointers to be safe, as we don't know
// whether they actually point to a NUL-terminated string.
#define GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(CharType) \
template <typename OtherOperand> \
class FormatForComparison<CharType*, OtherOperand> { \
public: \
static ::std::string Format(CharType* value) { \
return ::testing::PrintToString(static_cast<const void*>(value)); \
} \
}
GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(char);
GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const char);
GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(wchar_t);
GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const wchar_t);
#undef GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_
// If a C string is compared with an STL string object, we know it's meant
// to point to a NUL-terminated string, and thus can print it as a string.
#define GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(CharType, OtherStringType) \
template <> \
class FormatForComparison<CharType*, OtherStringType> { \
public: \
static ::std::string Format(CharType* value) { \
return ::testing::PrintToString(value); \
} \
}
GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(char, ::std::string);
GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const char, ::std::string);
#if GTEST_HAS_GLOBAL_STRING
GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(char, ::string);
GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const char, ::string);
#endif
#if GTEST_HAS_GLOBAL_WSTRING
GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(wchar_t, ::wstring);
GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const wchar_t, ::wstring);
#endif
#if GTEST_HAS_STD_WSTRING
GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(wchar_t, ::std::wstring);
GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const wchar_t, ::std::wstring);
#endif
#undef GTEST_IMPL_FORMAT_C_STRING_AS_STRING_
// Formats a comparison assertion (e.g. ASSERT_EQ, EXPECT_LT, and etc) // Formats a comparison assertion (e.g. ASSERT_EQ, EXPECT_LT, and etc)
// operand to be used in a failure message. The type (but not value) // operand to be used in a failure message. The type (but not value)
// of the other operand may affect the format. This allows us to // of the other operand may affect the format. This allows us to
// print a char* as a raw pointer when it is compared against another // print a char* as a raw pointer when it is compared against another
// char*, and print it as a C string when it is compared against an // char* or void*, and print it as a C string when it is compared
// std::string object, for example. // against an std::string object, for example.
//
// The default implementation ignores the type of the other operand.
// Some specialized versions are used to handle formatting wide or
// narrow C strings.
// //
// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
template <typename T1, typename T2> template <typename T1, typename T2>
String FormatForComparisonFailureMessage(const T1& value, std::string FormatForComparisonFailureMessage(
const T2& /* other_operand */) { const T1& value, const T2& /* other_operand */) {
// C++Builder compiles this incorrectly if the namespace isn't explicitly return FormatForComparison<T1, T2>::Format(value);
// given.
return ::testing::PrintToString(value);
} }
// The helper function for {ASSERT|EXPECT}_EQ. // The helper function for {ASSERT|EXPECT}_EQ.
@@ -1310,7 +1442,7 @@ AssertionResult CmpHelperEQ(const char* expected_expression,
#ifdef _MSC_VER #ifdef _MSC_VER
# pragma warning(push) // Saves the current warning state. # pragma warning(push) // Saves the current warning state.
# pragma warning(disable:4389) // Temporarily disables warning on # pragma warning(disable:4389) // Temporarily disables warning on
// signed/unsigned mismatch. // signed/unsigned mismatch.
#endif #endif
if (expected == actual) { if (expected == actual) {
@@ -1446,11 +1578,11 @@ GTEST_IMPL_CMP_HELPER_(NE, !=);
// Implements the helper function for {ASSERT|EXPECT}_LE // Implements the helper function for {ASSERT|EXPECT}_LE
GTEST_IMPL_CMP_HELPER_(LE, <=); GTEST_IMPL_CMP_HELPER_(LE, <=);
// Implements the helper function for {ASSERT|EXPECT}_LT // Implements the helper function for {ASSERT|EXPECT}_LT
GTEST_IMPL_CMP_HELPER_(LT, < ); GTEST_IMPL_CMP_HELPER_(LT, <);
// Implements the helper function for {ASSERT|EXPECT}_GE // Implements the helper function for {ASSERT|EXPECT}_GE
GTEST_IMPL_CMP_HELPER_(GE, >=); GTEST_IMPL_CMP_HELPER_(GE, >=);
// Implements the helper function for {ASSERT|EXPECT}_GT // Implements the helper function for {ASSERT|EXPECT}_GT
GTEST_IMPL_CMP_HELPER_(GT, > ); GTEST_IMPL_CMP_HELPER_(GT, >);
#undef GTEST_IMPL_CMP_HELPER_ #undef GTEST_IMPL_CMP_HELPER_
@@ -1614,9 +1746,9 @@ class GTEST_API_ AssertHelper {
: type(t), file(srcfile), line(line_num), message(msg) { } : type(t), file(srcfile), line(line_num), message(msg) { }
TestPartResult::Type const type; TestPartResult::Type const type;
const char* const file; const char* const file;
int const line; int const line;
String const message; std::string const message;
private: private:
GTEST_DISALLOW_COPY_AND_ASSIGN_(AssertHelperData); GTEST_DISALLOW_COPY_AND_ASSIGN_(AssertHelperData);
@@ -1675,7 +1807,12 @@ class WithParamInterface {
// references static data, to reduce the opportunity for incorrect uses // references static data, to reduce the opportunity for incorrect uses
// like writing 'WithParamInterface<bool>::GetParam()' for a test that // like writing 'WithParamInterface<bool>::GetParam()' for a test that
// uses a fixture whose parameter type is int. // uses a fixture whose parameter type is int.
const ParamType& GetParam() const { return *parameter_; } const ParamType& GetParam() const {
GTEST_CHECK_(parameter_ != NULL)
<< "GetParam() can only be called inside a value-parameterized test "
<< "-- did you intend to write TEST_P instead of TEST_F?";
return *parameter_;
}
private: private:
// Sets parameter value. The caller is responsible for making sure the value // Sets parameter value. The caller is responsible for making sure the value
@@ -1721,12 +1858,6 @@ class TestWithParam : public Test, public WithParamInterface<T> {
// usually want the fail-fast behavior of FAIL and ASSERT_*, but those // usually want the fail-fast behavior of FAIL and ASSERT_*, but those
// writing data-driven tests often find themselves using ADD_FAILURE // writing data-driven tests often find themselves using ADD_FAILURE
// and EXPECT_* more. // and EXPECT_* more.
//
// Examples:
//
// EXPECT_TRUE(server.StatusIsOK());
// ASSERT_FALSE(server.HasPendingRequest(port))
// << "There are still pending requests " << "on port " << port;
// Generates a nonfatal failure with a generic message. // Generates a nonfatal failure with a generic message.
#define ADD_FAILURE() GTEST_NONFATAL_FAILURE_("Failed") #define ADD_FAILURE() GTEST_NONFATAL_FAILURE_("Failed")
@@ -1900,7 +2031,7 @@ class TestWithParam : public Test, public WithParamInterface<T> {
# define ASSERT_GT(val1, val2) GTEST_ASSERT_GT(val1, val2) # define ASSERT_GT(val1, val2) GTEST_ASSERT_GT(val1, val2)
#endif #endif
// C String Comparisons. All tests treat NULL and any non-NULL string // C-string Comparisons. All tests treat NULL and any non-NULL string
// as different. Two NULLs are equal. // as different. Two NULLs are equal.
// //
// * {ASSERT|EXPECT}_STREQ(s1, s2): Tests that s1 == s2 // * {ASSERT|EXPECT}_STREQ(s1, s2): Tests that s1 == s2
@@ -2141,15 +2272,20 @@ bool StaticAssertTypeEq() {
GTEST_TEST_(test_fixture, test_name, test_fixture, \ GTEST_TEST_(test_fixture, test_name, test_fixture, \
::testing::internal::GetTypeId<test_fixture>()) ::testing::internal::GetTypeId<test_fixture>())
// Use this macro in main() to run all tests. It returns 0 if all } // namespace testing
// Use this function in main() to run all tests. It returns 0 if all
// tests are successful, or 1 otherwise. // tests are successful, or 1 otherwise.
// //
// RUN_ALL_TESTS() should be invoked after the command line has been // RUN_ALL_TESTS() should be invoked after the command line has been
// parsed by InitGoogleTest(). // parsed by InitGoogleTest().
//
// This function was formerly a macro; thus, it is in the global
// namespace and has an all-caps name.
int RUN_ALL_TESTS() GTEST_MUST_USE_RESULT_;
#define RUN_ALL_TESTS()\ inline int RUN_ALL_TESTS() {
(::testing::UnitTest::GetInstance()->Run()) return ::testing::UnitTest::GetInstance()->Run();
}
} // namespace testing
#endif // GTEST_INCLUDE_GTEST_GTEST_H_ #endif // GTEST_INCLUDE_GTEST_GTEST_H_
+6 -6
View File
@@ -27,7 +27,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// This file is AUTOMATICALLY GENERATED on 09/24/2010 by command // This file is AUTOMATICALLY GENERATED on 10/31/2011 by command
// 'gen_gtest_pred_impl.py 5'. DO NOT EDIT BY HAND! // 'gen_gtest_pred_impl.py 5'. DO NOT EDIT BY HAND!
// //
// Implements a family of generic predicate assertion macros. // Implements a family of generic predicate assertion macros.
@@ -98,7 +98,7 @@ AssertionResult AssertPred1Helper(const char* pred_text,
// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT1. // Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT1.
// Don't use this in your code. // Don't use this in your code.
#define GTEST_PRED_FORMAT1_(pred_format, v1, on_failure)\ #define GTEST_PRED_FORMAT1_(pred_format, v1, on_failure)\
GTEST_ASSERT_(pred_format(#v1, v1),\ GTEST_ASSERT_(pred_format(#v1, v1), \
on_failure) on_failure)
// Internal macro for implementing {EXPECT|ASSERT}_PRED1. Don't use // Internal macro for implementing {EXPECT|ASSERT}_PRED1. Don't use
@@ -144,7 +144,7 @@ AssertionResult AssertPred2Helper(const char* pred_text,
// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT2. // Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT2.
// Don't use this in your code. // Don't use this in your code.
#define GTEST_PRED_FORMAT2_(pred_format, v1, v2, on_failure)\ #define GTEST_PRED_FORMAT2_(pred_format, v1, v2, on_failure)\
GTEST_ASSERT_(pred_format(#v1, #v2, v1, v2),\ GTEST_ASSERT_(pred_format(#v1, #v2, v1, v2), \
on_failure) on_failure)
// Internal macro for implementing {EXPECT|ASSERT}_PRED2. Don't use // Internal macro for implementing {EXPECT|ASSERT}_PRED2. Don't use
@@ -197,7 +197,7 @@ AssertionResult AssertPred3Helper(const char* pred_text,
// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT3. // Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT3.
// Don't use this in your code. // Don't use this in your code.
#define GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, on_failure)\ #define GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, on_failure)\
GTEST_ASSERT_(pred_format(#v1, #v2, #v3, v1, v2, v3),\ GTEST_ASSERT_(pred_format(#v1, #v2, #v3, v1, v2, v3), \
on_failure) on_failure)
// Internal macro for implementing {EXPECT|ASSERT}_PRED3. Don't use // Internal macro for implementing {EXPECT|ASSERT}_PRED3. Don't use
@@ -257,7 +257,7 @@ AssertionResult AssertPred4Helper(const char* pred_text,
// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT4. // Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT4.
// Don't use this in your code. // Don't use this in your code.
#define GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, on_failure)\ #define GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, on_failure)\
GTEST_ASSERT_(pred_format(#v1, #v2, #v3, #v4, v1, v2, v3, v4),\ GTEST_ASSERT_(pred_format(#v1, #v2, #v3, #v4, v1, v2, v3, v4), \
on_failure) on_failure)
// Internal macro for implementing {EXPECT|ASSERT}_PRED4. Don't use // Internal macro for implementing {EXPECT|ASSERT}_PRED4. Don't use
@@ -324,7 +324,7 @@ AssertionResult AssertPred5Helper(const char* pred_text,
// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT5. // Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT5.
// Don't use this in your code. // Don't use this in your code.
#define GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, on_failure)\ #define GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, on_failure)\
GTEST_ASSERT_(pred_format(#v1, #v2, #v3, #v4, #v5, v1, v2, v3, v4, v5),\ GTEST_ASSERT_(pred_format(#v1, #v2, #v3, #v4, #v5, v1, v2, v3, v4, v5), \
on_failure) on_failure)
// Internal macro for implementing {EXPECT|ASSERT}_PRED5. Don't use // Internal macro for implementing {EXPECT|ASSERT}_PRED5. Don't use
@@ -127,11 +127,11 @@ class GTEST_API_ DeathTest {
// the last death test. // the last death test.
static const char* LastMessage(); static const char* LastMessage();
static void set_last_death_test_message(const String& message); static void set_last_death_test_message(const std::string& message);
private: private:
// A string containing a description of the outcome of the last death test. // A string containing a description of the outcome of the last death test.
static String last_death_test_message_; static std::string last_death_test_message_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(DeathTest); GTEST_DISALLOW_COPY_AND_ASSIGN_(DeathTest);
}; };
@@ -217,12 +217,23 @@ GTEST_API_ bool ExitedUnsuccessfully(int exit_status);
// The symbol "fail" here expands to something into which a message // The symbol "fail" here expands to something into which a message
// can be streamed. // can be streamed.
// This macro is for implementing ASSERT/EXPECT_DEBUG_DEATH when compiled in
// NDEBUG mode. In this case we need the statements to be executed, the regex is
// ignored, and the macro must accept a streamed message even though the message
// is never printed.
# define GTEST_EXECUTE_STATEMENT_(statement, regex) \
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
if (::testing::internal::AlwaysTrue()) { \
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
} else \
::testing::Message()
// A class representing the parsed contents of the // A class representing the parsed contents of the
// --gtest_internal_run_death_test flag, as it existed when // --gtest_internal_run_death_test flag, as it existed when
// RUN_ALL_TESTS was called. // RUN_ALL_TESTS was called.
class InternalRunDeathTestFlag { class InternalRunDeathTestFlag {
public: public:
InternalRunDeathTestFlag(const String& a_file, InternalRunDeathTestFlag(const std::string& a_file,
int a_line, int a_line,
int an_index, int an_index,
int a_write_fd) int a_write_fd)
@@ -234,13 +245,13 @@ class InternalRunDeathTestFlag {
posix::Close(write_fd_); posix::Close(write_fd_);
} }
String file() const { return file_; } const std::string& file() const { return file_; }
int line() const { return line_; } int line() const { return line_; }
int index() const { return index_; } int index() const { return index_; }
int write_fd() const { return write_fd_; } int write_fd() const { return write_fd_; }
private: private:
String file_; std::string file_;
int line_; int line_;
int index_; int index_;
int write_fd_; int write_fd_;
+5 -9
View File
@@ -61,11 +61,7 @@ class GTEST_API_ FilePath {
FilePath() : pathname_("") { } FilePath() : pathname_("") { }
FilePath(const FilePath& rhs) : pathname_(rhs.pathname_) { } FilePath(const FilePath& rhs) : pathname_(rhs.pathname_) { }
explicit FilePath(const char* pathname) : pathname_(pathname) { explicit FilePath(const std::string& pathname) : pathname_(pathname) {
Normalize();
}
explicit FilePath(const String& pathname) : pathname_(pathname) {
Normalize(); Normalize();
} }
@@ -78,7 +74,7 @@ class GTEST_API_ FilePath {
pathname_ = rhs.pathname_; pathname_ = rhs.pathname_;
} }
String ToString() const { return pathname_; } const std::string& string() const { return pathname_; }
const char* c_str() const { return pathname_.c_str(); } const char* c_str() const { return pathname_.c_str(); }
// Returns the current working directory, or "" if unsuccessful. // Returns the current working directory, or "" if unsuccessful.
@@ -111,8 +107,8 @@ class GTEST_API_ FilePath {
const FilePath& base_name, const FilePath& base_name,
const char* extension); const char* extension);
// Returns true iff the path is NULL or "". // Returns true iff the path is "".
bool IsEmpty() const { return c_str() == NULL || *c_str() == '\0'; } bool IsEmpty() const { return pathname_.empty(); }
// If input name has a trailing separator character, removes it and returns // If input name has a trailing separator character, removes it and returns
// the name, otherwise return the name string unmodified. // the name, otherwise return the name string unmodified.
@@ -201,7 +197,7 @@ class GTEST_API_ FilePath {
// separators. Returns NULL if no path separator was found. // separators. Returns NULL if no path separator was found.
const char* FindLastPathSeparator() const; const char* FindLastPathSeparator() const;
String pathname_; std::string pathname_;
}; // class FilePath }; // class FilePath
} // namespace internal } // namespace internal
+57 -125
View File
@@ -46,12 +46,18 @@
# include <unistd.h> # include <unistd.h>
#endif // GTEST_OS_LINUX #endif // GTEST_OS_LINUX
#if GTEST_HAS_EXCEPTIONS
# include <stdexcept>
#endif
#include <ctype.h> #include <ctype.h>
#include <float.h>
#include <string.h> #include <string.h>
#include <iomanip> #include <iomanip>
#include <limits> #include <limits>
#include <set> #include <set>
#include "gtest/gtest-message.h"
#include "gtest/internal/gtest-string.h" #include "gtest/internal/gtest-string.h"
#include "gtest/internal/gtest-filepath.h" #include "gtest/internal/gtest-filepath.h"
#include "gtest/internal/gtest-type-util.h" #include "gtest/internal/gtest-type-util.h"
@@ -67,36 +73,6 @@
#define GTEST_CONCAT_TOKEN_(foo, bar) GTEST_CONCAT_TOKEN_IMPL_(foo, bar) #define GTEST_CONCAT_TOKEN_(foo, bar) GTEST_CONCAT_TOKEN_IMPL_(foo, bar)
#define GTEST_CONCAT_TOKEN_IMPL_(foo, bar) foo ## bar #define GTEST_CONCAT_TOKEN_IMPL_(foo, bar) foo ## bar
// Google Test defines the testing::Message class to allow construction of
// test messages via the << operator. The idea is that anything
// streamable to std::ostream can be streamed to a testing::Message.
// This allows a user to use his own types in Google Test assertions by
// overloading the << operator.
//
// util/gtl/stl_logging-inl.h overloads << for STL containers. These
// overloads cannot be defined in the std namespace, as that will be
// undefined behavior. Therefore, they are defined in the global
// namespace instead.
//
// C++'s symbol lookup rule (i.e. Koenig lookup) says that these
// overloads are visible in either the std namespace or the global
// namespace, but not other namespaces, including the testing
// namespace which Google Test's Message class is in.
//
// To allow STL containers (and other types that has a << operator
// defined in the global namespace) to be used in Google Test assertions,
// testing::Message must access the custom << operator from the global
// namespace. Hence this helper function.
//
// Note: Jeffrey Yasskin suggested an alternative fix by "using
// ::operator<<;" in the definition of Message's operator<<. That fix
// doesn't require a helper function, but unfortunately doesn't
// compile with MSVC.
template <typename T>
inline void GTestStreamToHelper(std::ostream* os, const T& val) {
*os << val;
}
class ProtocolMessage; class ProtocolMessage;
namespace proto2 { class Message; } namespace proto2 { class Message; }
@@ -122,17 +98,12 @@ class TestInfoImpl; // Opaque implementation of TestInfo
class UnitTestImpl; // Opaque implementation of UnitTest class UnitTestImpl; // Opaque implementation of UnitTest
// How many times InitGoogleTest() has been called. // How many times InitGoogleTest() has been called.
extern int g_init_gtest_count; GTEST_API_ extern int g_init_gtest_count;
// The text used in failure messages to indicate the start of the // The text used in failure messages to indicate the start of the
// stack trace. // stack trace.
GTEST_API_ extern const char kStackTraceMarker[]; GTEST_API_ extern const char kStackTraceMarker[];
// A secret type that Google Test users don't know about. It has no
// definition on purpose. Therefore it's impossible to create a
// Secret object, which is what we want.
class Secret;
// Two overloaded helpers for checking at compile time whether an // Two overloaded helpers for checking at compile time whether an
// expression is a null pointer literal (i.e. NULL or any 0-valued // expression is a null pointer literal (i.e. NULL or any 0-valued
// compile-time integral constant). Their return values have // compile-time integral constant). Their return values have
@@ -163,8 +134,23 @@ char (&IsNullLiteralHelper(...))[2]; // NOLINT
#endif // GTEST_ELLIPSIS_NEEDS_POD_ #endif // GTEST_ELLIPSIS_NEEDS_POD_
// Appends the user-supplied message to the Google-Test-generated message. // Appends the user-supplied message to the Google-Test-generated message.
GTEST_API_ String AppendUserMessage(const String& gtest_msg, GTEST_API_ std::string AppendUserMessage(
const Message& user_msg); const std::string& gtest_msg, const Message& user_msg);
#if GTEST_HAS_EXCEPTIONS
// This exception is thrown by (and only by) a failed Google Test
// assertion when GTEST_FLAG(throw_on_failure) is true (if exceptions
// are enabled). We derive it from std::runtime_error, which is for
// errors presumably detectable only at run time. Since
// std::runtime_error inherits from std::exception, many testing
// frameworks know how to extract and print the message inside it.
class GTEST_API_ GoogleTestFailureException : public ::std::runtime_error {
public:
explicit GoogleTestFailureException(const TestPartResult& failure);
};
#endif // GTEST_HAS_EXCEPTIONS
// A helper class for creating scoped traces in user programs. // A helper class for creating scoped traces in user programs.
class GTEST_API_ ScopedTrace { class GTEST_API_ ScopedTrace {
@@ -185,77 +171,6 @@ class GTEST_API_ ScopedTrace {
// c'tor and d'tor. Therefore it doesn't // c'tor and d'tor. Therefore it doesn't
// need to be used otherwise. // need to be used otherwise.
// Converts a streamable value to a String. A NULL pointer is
// converted to "(null)". When the input value is a ::string,
// ::std::string, ::wstring, or ::std::wstring object, each NUL
// character in it is replaced with "\\0".
// Declared here but defined in gtest.h, so that it has access
// to the definition of the Message class, required by the ARM
// compiler.
template <typename T>
String StreamableToString(const T& streamable);
// The Symbian compiler has a bug that prevents it from selecting the
// correct overload of FormatForComparisonFailureMessage (see below)
// unless we pass the first argument by reference. If we do that,
// however, Visual Age C++ 10.1 generates a compiler error. Therefore
// we only apply the work-around for Symbian.
#if defined(__SYMBIAN32__)
# define GTEST_CREF_WORKAROUND_ const&
#else
# define GTEST_CREF_WORKAROUND_
#endif
// When this operand is a const char* or char*, if the other operand
// is a ::std::string or ::string, we print this operand as a C string
// rather than a pointer (we do the same for wide strings); otherwise
// we print it as a pointer to be safe.
// This internal macro is used to avoid duplicated code.
#define GTEST_FORMAT_IMPL_(operand2_type, operand1_printer)\
inline String FormatForComparisonFailureMessage(\
operand2_type::value_type* GTEST_CREF_WORKAROUND_ str, \
const operand2_type& /*operand2*/) {\
return operand1_printer(str);\
}\
inline String FormatForComparisonFailureMessage(\
const operand2_type::value_type* GTEST_CREF_WORKAROUND_ str, \
const operand2_type& /*operand2*/) {\
return operand1_printer(str);\
}
GTEST_FORMAT_IMPL_(::std::string, String::ShowCStringQuoted)
#if GTEST_HAS_STD_WSTRING
GTEST_FORMAT_IMPL_(::std::wstring, String::ShowWideCStringQuoted)
#endif // GTEST_HAS_STD_WSTRING
#if GTEST_HAS_GLOBAL_STRING
GTEST_FORMAT_IMPL_(::string, String::ShowCStringQuoted)
#endif // GTEST_HAS_GLOBAL_STRING
#if GTEST_HAS_GLOBAL_WSTRING
GTEST_FORMAT_IMPL_(::wstring, String::ShowWideCStringQuoted)
#endif // GTEST_HAS_GLOBAL_WSTRING
#undef GTEST_FORMAT_IMPL_
// The next four overloads handle the case where the operand being
// printed is a char/wchar_t pointer and the other operand is not a
// string/wstring object. In such cases, we just print the operand as
// a pointer to be safe.
#define GTEST_FORMAT_CHAR_PTR_IMPL_(CharType) \
template <typename T> \
String FormatForComparisonFailureMessage(CharType* GTEST_CREF_WORKAROUND_ p, \
const T&) { \
return PrintToString(static_cast<const void*>(p)); \
}
GTEST_FORMAT_CHAR_PTR_IMPL_(char)
GTEST_FORMAT_CHAR_PTR_IMPL_(const char)
GTEST_FORMAT_CHAR_PTR_IMPL_(wchar_t)
GTEST_FORMAT_CHAR_PTR_IMPL_(const wchar_t)
#undef GTEST_FORMAT_CHAR_PTR_IMPL_
// Constructs and returns the message for an equality assertion // Constructs and returns the message for an equality assertion
// (e.g. ASSERT_EQ, EXPECT_STREQ, etc) failure. // (e.g. ASSERT_EQ, EXPECT_STREQ, etc) failure.
// //
@@ -273,12 +188,12 @@ GTEST_FORMAT_CHAR_PTR_IMPL_(const wchar_t)
// be inserted into the message. // be inserted into the message.
GTEST_API_ AssertionResult EqFailure(const char* expected_expression, GTEST_API_ AssertionResult EqFailure(const char* expected_expression,
const char* actual_expression, const char* actual_expression,
const String& expected_value, const std::string& expected_value,
const String& actual_value, const std::string& actual_value,
bool ignoring_case); bool ignoring_case);
// Constructs a failure message for Boolean assertions such as EXPECT_TRUE. // Constructs a failure message for Boolean assertions such as EXPECT_TRUE.
GTEST_API_ String GetBoolAssertionFailureMessage( GTEST_API_ std::string GetBoolAssertionFailureMessage(
const AssertionResult& assertion_result, const AssertionResult& assertion_result,
const char* expression_text, const char* expression_text,
const char* actual_predicate_value, const char* actual_predicate_value,
@@ -353,7 +268,7 @@ class FloatingPoint {
// bits. Therefore, 4 should be enough for ordinary use. // bits. Therefore, 4 should be enough for ordinary use.
// //
// See the following article for more details on ULP: // See the following article for more details on ULP:
// http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm. // http://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/
static const size_t kMaxUlps = 4; static const size_t kMaxUlps = 4;
// Constructs a FloatingPoint from a raw floating-point number. // Constructs a FloatingPoint from a raw floating-point number.
@@ -380,6 +295,9 @@ class FloatingPoint {
return ReinterpretBits(kExponentBitMask); return ReinterpretBits(kExponentBitMask);
} }
// Returns the maximum representable finite floating-point number.
static RawType Max();
// Non-static methods // Non-static methods
// Returns the bits that represents this number. // Returns the bits that represents this number.
@@ -460,6 +378,13 @@ class FloatingPoint {
FloatingPointUnion u_; FloatingPointUnion u_;
}; };
// We cannot use std::numeric_limits<T>::max() as it clashes with the max()
// macro defined by <windows.h>.
template <>
inline float FloatingPoint<float>::Max() { return FLT_MAX; }
template <>
inline double FloatingPoint<double>::Max() { return DBL_MAX; }
// Typedefs the instances of the FloatingPoint template class that we // Typedefs the instances of the FloatingPoint template class that we
// care to use. // care to use.
typedef FloatingPoint<float> Float; typedef FloatingPoint<float> Float;
@@ -554,7 +479,7 @@ typedef void (*TearDownTestCaseFunc)();
// test_case_name: name of the test case // test_case_name: name of the test case
// name: name of the test // name: name of the test
// type_param the name of the test's type parameter, or NULL if // type_param the name of the test's type parameter, or NULL if
// this is not a typed or a type-parameterized test. // this is not a typed or a type-parameterized test.
// value_param text representation of the test's value parameter, // value_param text representation of the test's value parameter,
// or NULL if this is not a type-parameterized test. // or NULL if this is not a type-parameterized test.
// fixture_class_id: ID of the test fixture class // fixture_class_id: ID of the test fixture class
@@ -564,7 +489,8 @@ typedef void (*TearDownTestCaseFunc)();
// The newly created TestInfo instance will assume // The newly created TestInfo instance will assume
// ownership of the factory object. // ownership of the factory object.
GTEST_API_ TestInfo* MakeAndRegisterTestInfo( GTEST_API_ TestInfo* MakeAndRegisterTestInfo(
const char* test_case_name, const char* name, const char* test_case_name,
const char* name,
const char* type_param, const char* type_param,
const char* value_param, const char* value_param,
TypeId fixture_class_id, TypeId fixture_class_id,
@@ -624,9 +550,9 @@ inline const char* SkipComma(const char* str) {
// Returns the prefix of 'str' before the first comma in it; returns // Returns the prefix of 'str' before the first comma in it; returns
// the entire string if it contains no comma. // the entire string if it contains no comma.
inline String GetPrefixUntilComma(const char* str) { inline std::string GetPrefixUntilComma(const char* str) {
const char* comma = strchr(str, ','); const char* comma = strchr(str, ',');
return comma == NULL ? String(str) : String(str, comma - str); return comma == NULL ? str : std::string(str, comma);
} }
// TypeParameterizedTest<Fixture, TestSel, Types>::Register() // TypeParameterizedTest<Fixture, TestSel, Types>::Register()
@@ -652,8 +578,8 @@ class TypeParameterizedTest {
// First, registers the first type-parameterized test in the type // First, registers the first type-parameterized test in the type
// list. // list.
MakeAndRegisterTestInfo( MakeAndRegisterTestInfo(
String::Format("%s%s%s/%d", prefix, prefix[0] == '\0' ? "" : "/", (std::string(prefix) + (prefix[0] == '\0' ? "" : "/") + case_name + "/"
case_name, index).c_str(), + StreamableToString(index)).c_str(),
GetPrefixUntilComma(test_names).c_str(), GetPrefixUntilComma(test_names).c_str(),
GetTypeName<Type>().c_str(), GetTypeName<Type>().c_str(),
NULL, // No value parameter. NULL, // No value parameter.
@@ -711,7 +637,7 @@ class TypeParameterizedTestCase<Fixture, Templates0, Types> {
#endif // GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P #endif // GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P
// Returns the current OS stack trace as a String. // Returns the current OS stack trace as an std::string.
// //
// The maximum number of stack frames to be included is specified by // The maximum number of stack frames to be included is specified by
// the gtest_stack_trace_depth flag. The skip_count parameter // the gtest_stack_trace_depth flag. The skip_count parameter
@@ -721,8 +647,8 @@ class TypeParameterizedTestCase<Fixture, Templates0, Types> {
// For example, if Foo() calls Bar(), which in turn calls // For example, if Foo() calls Bar(), which in turn calls
// GetCurrentOsStackTraceExceptTop(..., 1), Foo() will be included in // GetCurrentOsStackTraceExceptTop(..., 1), Foo() will be included in
// the trace but Bar() and GetCurrentOsStackTraceExceptTop() won't. // the trace but Bar() and GetCurrentOsStackTraceExceptTop() won't.
GTEST_API_ String GetCurrentOsStackTraceExceptTop(UnitTest* unit_test, GTEST_API_ std::string GetCurrentOsStackTraceExceptTop(
int skip_count); UnitTest* unit_test, int skip_count);
// Helpers for suppressing warnings on unreachable code or constant // Helpers for suppressing warnings on unreachable code or constant
// condition. // condition.
@@ -797,13 +723,19 @@ struct RemoveConst<const T> { typedef T type; }; // NOLINT
// MSVC 8.0, Sun C++, and IBM XL C++ have a bug which causes the above // MSVC 8.0, Sun C++, and IBM XL C++ have a bug which causes the above
// definition to fail to remove the const in 'const int[3]' and 'const // definition to fail to remove the const in 'const int[3]' and 'const
// char[3][4]'. The following specialization works around the bug. // char[3][4]'. The following specialization works around the bug.
// However, it causes trouble with GCC and thus needs to be
// conditionally compiled.
#if defined(_MSC_VER) || defined(__SUNPRO_CC) || defined(__IBMCPP__)
template <typename T, size_t N> template <typename T, size_t N>
struct RemoveConst<const T[N]> { struct RemoveConst<const T[N]> {
typedef typename RemoveConst<T>::type type[N]; typedef typename RemoveConst<T>::type type[N];
}; };
#if defined(_MSC_VER) && _MSC_VER < 1400
// This is the only specialization that allows VC++ 7.1 to remove const in
// 'const int[3] and 'const int[3][4]'. However, it causes trouble with GCC
// and thus needs to be conditionally compiled.
template <typename T, size_t N>
struct RemoveConst<T[N]> {
typedef typename RemoveConst<T>::type type[N];
};
#endif #endif
// A handy wrapper around RemoveConst that works when the argument // A handy wrapper around RemoveConst that works when the argument
+4 -4
View File
@@ -105,8 +105,8 @@ class linked_ptr_internal {
// framework. // framework.
// Join an existing circle. // Join an existing circle.
// L < g_linked_ptr_mutex void join(linked_ptr_internal const* ptr)
void join(linked_ptr_internal const* ptr) { GTEST_LOCK_EXCLUDED_(g_linked_ptr_mutex) {
MutexLock lock(&g_linked_ptr_mutex); MutexLock lock(&g_linked_ptr_mutex);
linked_ptr_internal const* p = ptr; linked_ptr_internal const* p = ptr;
@@ -117,8 +117,8 @@ class linked_ptr_internal {
// Leave whatever circle we're part of. Returns true if we were the // Leave whatever circle we're part of. Returns true if we were the
// last member of the circle. Once this is done, you can join() another. // last member of the circle. Once this is done, you can join() another.
// L < g_linked_ptr_mutex bool depart()
bool depart() { GTEST_LOCK_EXCLUDED_(g_linked_ptr_mutex) {
MutexLock lock(&g_linked_ptr_mutex); MutexLock lock(&g_linked_ptr_mutex);
if (next_ == this) return true; if (next_ == this) return true;
@@ -95,7 +95,7 @@ class ValueArray2 {
template <typename T> template <typename T>
operator ParamGenerator<T>() const { operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_}; const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_)};
return ValuesIn(array); return ValuesIn(array);
} }
@@ -114,7 +114,8 @@ class ValueArray3 {
template <typename T> template <typename T>
operator ParamGenerator<T>() const { operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_}; const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
static_cast<T>(v3_)};
return ValuesIn(array); return ValuesIn(array);
} }
@@ -135,7 +136,8 @@ class ValueArray4 {
template <typename T> template <typename T>
operator ParamGenerator<T>() const { operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_}; const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
static_cast<T>(v3_), static_cast<T>(v4_)};
return ValuesIn(array); return ValuesIn(array);
} }
@@ -157,7 +159,8 @@ class ValueArray5 {
template <typename T> template <typename T>
operator ParamGenerator<T>() const { operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_, v5_}; const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_)};
return ValuesIn(array); return ValuesIn(array);
} }
@@ -181,7 +184,9 @@ class ValueArray6 {
template <typename T> template <typename T>
operator ParamGenerator<T>() const { operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_}; const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
static_cast<T>(v6_)};
return ValuesIn(array); return ValuesIn(array);
} }
@@ -206,7 +211,9 @@ class ValueArray7 {
template <typename T> template <typename T>
operator ParamGenerator<T>() const { operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_}; const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
static_cast<T>(v6_), static_cast<T>(v7_)};
return ValuesIn(array); return ValuesIn(array);
} }
@@ -233,7 +240,9 @@ class ValueArray8 {
template <typename T> template <typename T>
operator ParamGenerator<T>() const { operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_}; const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_)};
return ValuesIn(array); return ValuesIn(array);
} }
@@ -261,7 +270,10 @@ class ValueArray9 {
template <typename T> template <typename T>
operator ParamGenerator<T>() const { operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_}; const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
static_cast<T>(v9_)};
return ValuesIn(array); return ValuesIn(array);
} }
@@ -290,7 +302,10 @@ class ValueArray10 {
template <typename T> template <typename T>
operator ParamGenerator<T>() const { operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_}; const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
static_cast<T>(v9_), static_cast<T>(v10_)};
return ValuesIn(array); return ValuesIn(array);
} }
@@ -321,7 +336,10 @@ class ValueArray11 {
template <typename T> template <typename T>
operator ParamGenerator<T>() const { operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_}; const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_)};
return ValuesIn(array); return ValuesIn(array);
} }
@@ -353,8 +371,11 @@ class ValueArray12 {
template <typename T> template <typename T>
operator ParamGenerator<T>() const { operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
v12_}; static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
static_cast<T>(v12_)};
return ValuesIn(array); return ValuesIn(array);
} }
@@ -388,8 +409,11 @@ class ValueArray13 {
template <typename T> template <typename T>
operator ParamGenerator<T>() const { operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
v12_, v13_}; static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
static_cast<T>(v12_), static_cast<T>(v13_)};
return ValuesIn(array); return ValuesIn(array);
} }
@@ -424,8 +448,11 @@ class ValueArray14 {
template <typename T> template <typename T>
operator ParamGenerator<T>() const { operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
v12_, v13_, v14_}; static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_)};
return ValuesIn(array); return ValuesIn(array);
} }
@@ -461,8 +488,12 @@ class ValueArray15 {
template <typename T> template <typename T>
operator ParamGenerator<T>() const { operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
v12_, v13_, v14_, v15_}; static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
static_cast<T>(v15_)};
return ValuesIn(array); return ValuesIn(array);
} }
@@ -501,8 +532,12 @@ class ValueArray16 {
template <typename T> template <typename T>
operator ParamGenerator<T>() const { operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
v12_, v13_, v14_, v15_, v16_}; static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
static_cast<T>(v15_), static_cast<T>(v16_)};
return ValuesIn(array); return ValuesIn(array);
} }
@@ -542,8 +577,12 @@ class ValueArray17 {
template <typename T> template <typename T>
operator ParamGenerator<T>() const { operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
v12_, v13_, v14_, v15_, v16_, v17_}; static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_)};
return ValuesIn(array); return ValuesIn(array);
} }
@@ -584,8 +623,13 @@ class ValueArray18 {
template <typename T> template <typename T>
operator ParamGenerator<T>() const { operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
v12_, v13_, v14_, v15_, v16_, v17_, v18_}; static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
static_cast<T>(v18_)};
return ValuesIn(array); return ValuesIn(array);
} }
@@ -627,8 +671,13 @@ class ValueArray19 {
template <typename T> template <typename T>
operator ParamGenerator<T>() const { operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_}; static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
static_cast<T>(v18_), static_cast<T>(v19_)};
return ValuesIn(array); return ValuesIn(array);
} }
@@ -672,8 +721,13 @@ class ValueArray20 {
template <typename T> template <typename T>
operator ParamGenerator<T>() const { operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_}; static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_)};
return ValuesIn(array); return ValuesIn(array);
} }
@@ -719,8 +773,14 @@ class ValueArray21 {
template <typename T> template <typename T>
operator ParamGenerator<T>() const { operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_}; static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),
static_cast<T>(v21_)};
return ValuesIn(array); return ValuesIn(array);
} }
@@ -767,8 +827,14 @@ class ValueArray22 {
template <typename T> template <typename T>
operator ParamGenerator<T>() const { operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_}; static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),
static_cast<T>(v21_), static_cast<T>(v22_)};
return ValuesIn(array); return ValuesIn(array);
} }
@@ -817,9 +883,14 @@ class ValueArray23 {
template <typename T> template <typename T>
operator ParamGenerator<T>() const { operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
v23_}; static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),
static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_)};
return ValuesIn(array); return ValuesIn(array);
} }
@@ -869,9 +940,15 @@ class ValueArray24 {
template <typename T> template <typename T>
operator ParamGenerator<T>() const { operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
v24_}; static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),
static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),
static_cast<T>(v24_)};
return ValuesIn(array); return ValuesIn(array);
} }
@@ -922,9 +999,15 @@ class ValueArray25 {
template <typename T> template <typename T>
operator ParamGenerator<T>() const { operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
v24_, v25_}; static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),
static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),
static_cast<T>(v24_), static_cast<T>(v25_)};
return ValuesIn(array); return ValuesIn(array);
} }
@@ -977,9 +1060,15 @@ class ValueArray26 {
template <typename T> template <typename T>
operator ParamGenerator<T>() const { operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
v24_, v25_, v26_}; static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),
static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),
static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_)};
return ValuesIn(array); return ValuesIn(array);
} }
@@ -1034,9 +1123,16 @@ class ValueArray27 {
template <typename T> template <typename T>
operator ParamGenerator<T>() const { operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
v24_, v25_, v26_, v27_}; static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),
static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),
static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),
static_cast<T>(v27_)};
return ValuesIn(array); return ValuesIn(array);
} }
@@ -1092,9 +1188,16 @@ class ValueArray28 {
template <typename T> template <typename T>
operator ParamGenerator<T>() const { operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
v24_, v25_, v26_, v27_, v28_}; static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),
static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),
static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),
static_cast<T>(v27_), static_cast<T>(v28_)};
return ValuesIn(array); return ValuesIn(array);
} }
@@ -1151,9 +1254,16 @@ class ValueArray29 {
template <typename T> template <typename T>
operator ParamGenerator<T>() const { operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
v24_, v25_, v26_, v27_, v28_, v29_}; static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),
static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),
static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),
static_cast<T>(v27_), static_cast<T>(v28_), static_cast<T>(v29_)};
return ValuesIn(array); return ValuesIn(array);
} }
@@ -1212,9 +1322,17 @@ class ValueArray30 {
template <typename T> template <typename T>
operator ParamGenerator<T>() const { operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
v24_, v25_, v26_, v27_, v28_, v29_, v30_}; static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),
static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),
static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),
static_cast<T>(v27_), static_cast<T>(v28_), static_cast<T>(v29_),
static_cast<T>(v30_)};
return ValuesIn(array); return ValuesIn(array);
} }
@@ -1275,9 +1393,17 @@ class ValueArray31 {
template <typename T> template <typename T>
operator ParamGenerator<T>() const { operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_}; static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),
static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),
static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),
static_cast<T>(v27_), static_cast<T>(v28_), static_cast<T>(v29_),
static_cast<T>(v30_), static_cast<T>(v31_)};
return ValuesIn(array); return ValuesIn(array);
} }
@@ -1339,9 +1465,17 @@ class ValueArray32 {
template <typename T> template <typename T>
operator ParamGenerator<T>() const { operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_}; static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),
static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),
static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),
static_cast<T>(v27_), static_cast<T>(v28_), static_cast<T>(v29_),
static_cast<T>(v30_), static_cast<T>(v31_), static_cast<T>(v32_)};
return ValuesIn(array); return ValuesIn(array);
} }
@@ -1405,9 +1539,18 @@ class ValueArray33 {
template <typename T> template <typename T>
operator ParamGenerator<T>() const { operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_}; static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),
static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),
static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),
static_cast<T>(v27_), static_cast<T>(v28_), static_cast<T>(v29_),
static_cast<T>(v30_), static_cast<T>(v31_), static_cast<T>(v32_),
static_cast<T>(v33_)};
return ValuesIn(array); return ValuesIn(array);
} }
@@ -1472,9 +1615,18 @@ class ValueArray34 {
template <typename T> template <typename T>
operator ParamGenerator<T>() const { operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_}; static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),
static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),
static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),
static_cast<T>(v27_), static_cast<T>(v28_), static_cast<T>(v29_),
static_cast<T>(v30_), static_cast<T>(v31_), static_cast<T>(v32_),
static_cast<T>(v33_), static_cast<T>(v34_)};
return ValuesIn(array); return ValuesIn(array);
} }
@@ -1540,10 +1692,18 @@ class ValueArray35 {
template <typename T> template <typename T>
operator ParamGenerator<T>() const { operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
v35_}; static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),
static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),
static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),
static_cast<T>(v27_), static_cast<T>(v28_), static_cast<T>(v29_),
static_cast<T>(v30_), static_cast<T>(v31_), static_cast<T>(v32_),
static_cast<T>(v33_), static_cast<T>(v34_), static_cast<T>(v35_)};
return ValuesIn(array); return ValuesIn(array);
} }
@@ -1611,10 +1771,19 @@ class ValueArray36 {
template <typename T> template <typename T>
operator ParamGenerator<T>() const { operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_, static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
v36_}; static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),
static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),
static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),
static_cast<T>(v27_), static_cast<T>(v28_), static_cast<T>(v29_),
static_cast<T>(v30_), static_cast<T>(v31_), static_cast<T>(v32_),
static_cast<T>(v33_), static_cast<T>(v34_), static_cast<T>(v35_),
static_cast<T>(v36_)};
return ValuesIn(array); return ValuesIn(array);
} }
@@ -1684,10 +1853,19 @@ class ValueArray37 {
template <typename T> template <typename T>
operator ParamGenerator<T>() const { operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_, static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
v36_, v37_}; static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),
static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),
static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),
static_cast<T>(v27_), static_cast<T>(v28_), static_cast<T>(v29_),
static_cast<T>(v30_), static_cast<T>(v31_), static_cast<T>(v32_),
static_cast<T>(v33_), static_cast<T>(v34_), static_cast<T>(v35_),
static_cast<T>(v36_), static_cast<T>(v37_)};
return ValuesIn(array); return ValuesIn(array);
} }
@@ -1758,10 +1936,19 @@ class ValueArray38 {
template <typename T> template <typename T>
operator ParamGenerator<T>() const { operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_, static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
v36_, v37_, v38_}; static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),
static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),
static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),
static_cast<T>(v27_), static_cast<T>(v28_), static_cast<T>(v29_),
static_cast<T>(v30_), static_cast<T>(v31_), static_cast<T>(v32_),
static_cast<T>(v33_), static_cast<T>(v34_), static_cast<T>(v35_),
static_cast<T>(v36_), static_cast<T>(v37_), static_cast<T>(v38_)};
return ValuesIn(array); return ValuesIn(array);
} }
@@ -1833,10 +2020,20 @@ class ValueArray39 {
template <typename T> template <typename T>
operator ParamGenerator<T>() const { operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_, static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
v36_, v37_, v38_, v39_}; static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),
static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),
static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),
static_cast<T>(v27_), static_cast<T>(v28_), static_cast<T>(v29_),
static_cast<T>(v30_), static_cast<T>(v31_), static_cast<T>(v32_),
static_cast<T>(v33_), static_cast<T>(v34_), static_cast<T>(v35_),
static_cast<T>(v36_), static_cast<T>(v37_), static_cast<T>(v38_),
static_cast<T>(v39_)};
return ValuesIn(array); return ValuesIn(array);
} }
@@ -1910,10 +2107,20 @@ class ValueArray40 {
template <typename T> template <typename T>
operator ParamGenerator<T>() const { operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_, static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
v36_, v37_, v38_, v39_, v40_}; static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),
static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),
static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),
static_cast<T>(v27_), static_cast<T>(v28_), static_cast<T>(v29_),
static_cast<T>(v30_), static_cast<T>(v31_), static_cast<T>(v32_),
static_cast<T>(v33_), static_cast<T>(v34_), static_cast<T>(v35_),
static_cast<T>(v36_), static_cast<T>(v37_), static_cast<T>(v38_),
static_cast<T>(v39_), static_cast<T>(v40_)};
return ValuesIn(array); return ValuesIn(array);
} }
@@ -1989,10 +2196,20 @@ class ValueArray41 {
template <typename T> template <typename T>
operator ParamGenerator<T>() const { operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_, static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
v36_, v37_, v38_, v39_, v40_, v41_}; static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),
static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),
static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),
static_cast<T>(v27_), static_cast<T>(v28_), static_cast<T>(v29_),
static_cast<T>(v30_), static_cast<T>(v31_), static_cast<T>(v32_),
static_cast<T>(v33_), static_cast<T>(v34_), static_cast<T>(v35_),
static_cast<T>(v36_), static_cast<T>(v37_), static_cast<T>(v38_),
static_cast<T>(v39_), static_cast<T>(v40_), static_cast<T>(v41_)};
return ValuesIn(array); return ValuesIn(array);
} }
@@ -2069,10 +2286,21 @@ class ValueArray42 {
template <typename T> template <typename T>
operator ParamGenerator<T>() const { operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_, static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
v36_, v37_, v38_, v39_, v40_, v41_, v42_}; static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),
static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),
static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),
static_cast<T>(v27_), static_cast<T>(v28_), static_cast<T>(v29_),
static_cast<T>(v30_), static_cast<T>(v31_), static_cast<T>(v32_),
static_cast<T>(v33_), static_cast<T>(v34_), static_cast<T>(v35_),
static_cast<T>(v36_), static_cast<T>(v37_), static_cast<T>(v38_),
static_cast<T>(v39_), static_cast<T>(v40_), static_cast<T>(v41_),
static_cast<T>(v42_)};
return ValuesIn(array); return ValuesIn(array);
} }
@@ -2150,10 +2378,21 @@ class ValueArray43 {
template <typename T> template <typename T>
operator ParamGenerator<T>() const { operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_, static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_}; static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),
static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),
static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),
static_cast<T>(v27_), static_cast<T>(v28_), static_cast<T>(v29_),
static_cast<T>(v30_), static_cast<T>(v31_), static_cast<T>(v32_),
static_cast<T>(v33_), static_cast<T>(v34_), static_cast<T>(v35_),
static_cast<T>(v36_), static_cast<T>(v37_), static_cast<T>(v38_),
static_cast<T>(v39_), static_cast<T>(v40_), static_cast<T>(v41_),
static_cast<T>(v42_), static_cast<T>(v43_)};
return ValuesIn(array); return ValuesIn(array);
} }
@@ -2233,10 +2472,21 @@ class ValueArray44 {
template <typename T> template <typename T>
operator ParamGenerator<T>() const { operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_, static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_}; static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),
static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),
static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),
static_cast<T>(v27_), static_cast<T>(v28_), static_cast<T>(v29_),
static_cast<T>(v30_), static_cast<T>(v31_), static_cast<T>(v32_),
static_cast<T>(v33_), static_cast<T>(v34_), static_cast<T>(v35_),
static_cast<T>(v36_), static_cast<T>(v37_), static_cast<T>(v38_),
static_cast<T>(v39_), static_cast<T>(v40_), static_cast<T>(v41_),
static_cast<T>(v42_), static_cast<T>(v43_), static_cast<T>(v44_)};
return ValuesIn(array); return ValuesIn(array);
} }
@@ -2317,10 +2567,22 @@ class ValueArray45 {
template <typename T> template <typename T>
operator ParamGenerator<T>() const { operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_, static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_, v45_}; static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),
static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),
static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),
static_cast<T>(v27_), static_cast<T>(v28_), static_cast<T>(v29_),
static_cast<T>(v30_), static_cast<T>(v31_), static_cast<T>(v32_),
static_cast<T>(v33_), static_cast<T>(v34_), static_cast<T>(v35_),
static_cast<T>(v36_), static_cast<T>(v37_), static_cast<T>(v38_),
static_cast<T>(v39_), static_cast<T>(v40_), static_cast<T>(v41_),
static_cast<T>(v42_), static_cast<T>(v43_), static_cast<T>(v44_),
static_cast<T>(v45_)};
return ValuesIn(array); return ValuesIn(array);
} }
@@ -2403,10 +2665,22 @@ class ValueArray46 {
template <typename T> template <typename T>
operator ParamGenerator<T>() const { operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_, static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_, v45_, v46_}; static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),
static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),
static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),
static_cast<T>(v27_), static_cast<T>(v28_), static_cast<T>(v29_),
static_cast<T>(v30_), static_cast<T>(v31_), static_cast<T>(v32_),
static_cast<T>(v33_), static_cast<T>(v34_), static_cast<T>(v35_),
static_cast<T>(v36_), static_cast<T>(v37_), static_cast<T>(v38_),
static_cast<T>(v39_), static_cast<T>(v40_), static_cast<T>(v41_),
static_cast<T>(v42_), static_cast<T>(v43_), static_cast<T>(v44_),
static_cast<T>(v45_), static_cast<T>(v46_)};
return ValuesIn(array); return ValuesIn(array);
} }
@@ -2491,11 +2765,22 @@ class ValueArray47 {
template <typename T> template <typename T>
operator ParamGenerator<T>() const { operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_, static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_, v45_, v46_, static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
v47_}; static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),
static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),
static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),
static_cast<T>(v27_), static_cast<T>(v28_), static_cast<T>(v29_),
static_cast<T>(v30_), static_cast<T>(v31_), static_cast<T>(v32_),
static_cast<T>(v33_), static_cast<T>(v34_), static_cast<T>(v35_),
static_cast<T>(v36_), static_cast<T>(v37_), static_cast<T>(v38_),
static_cast<T>(v39_), static_cast<T>(v40_), static_cast<T>(v41_),
static_cast<T>(v42_), static_cast<T>(v43_), static_cast<T>(v44_),
static_cast<T>(v45_), static_cast<T>(v46_), static_cast<T>(v47_)};
return ValuesIn(array); return ValuesIn(array);
} }
@@ -2581,11 +2866,23 @@ class ValueArray48 {
template <typename T> template <typename T>
operator ParamGenerator<T>() const { operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_, static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_, v45_, v46_, v47_, static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
v48_}; static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),
static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),
static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),
static_cast<T>(v27_), static_cast<T>(v28_), static_cast<T>(v29_),
static_cast<T>(v30_), static_cast<T>(v31_), static_cast<T>(v32_),
static_cast<T>(v33_), static_cast<T>(v34_), static_cast<T>(v35_),
static_cast<T>(v36_), static_cast<T>(v37_), static_cast<T>(v38_),
static_cast<T>(v39_), static_cast<T>(v40_), static_cast<T>(v41_),
static_cast<T>(v42_), static_cast<T>(v43_), static_cast<T>(v44_),
static_cast<T>(v45_), static_cast<T>(v46_), static_cast<T>(v47_),
static_cast<T>(v48_)};
return ValuesIn(array); return ValuesIn(array);
} }
@@ -2672,11 +2969,23 @@ class ValueArray49 {
template <typename T> template <typename T>
operator ParamGenerator<T>() const { operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_, static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_, v45_, v46_, v47_, static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
v48_, v49_}; static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),
static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),
static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),
static_cast<T>(v27_), static_cast<T>(v28_), static_cast<T>(v29_),
static_cast<T>(v30_), static_cast<T>(v31_), static_cast<T>(v32_),
static_cast<T>(v33_), static_cast<T>(v34_), static_cast<T>(v35_),
static_cast<T>(v36_), static_cast<T>(v37_), static_cast<T>(v38_),
static_cast<T>(v39_), static_cast<T>(v40_), static_cast<T>(v41_),
static_cast<T>(v42_), static_cast<T>(v43_), static_cast<T>(v44_),
static_cast<T>(v45_), static_cast<T>(v46_), static_cast<T>(v47_),
static_cast<T>(v48_), static_cast<T>(v49_)};
return ValuesIn(array); return ValuesIn(array);
} }
@@ -2764,11 +3073,23 @@ class ValueArray50 {
template <typename T> template <typename T>
operator ParamGenerator<T>() const { operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_, static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_, v45_, v46_, v47_, static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
v48_, v49_, v50_}; static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),
static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),
static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),
static_cast<T>(v27_), static_cast<T>(v28_), static_cast<T>(v29_),
static_cast<T>(v30_), static_cast<T>(v31_), static_cast<T>(v32_),
static_cast<T>(v33_), static_cast<T>(v34_), static_cast<T>(v35_),
static_cast<T>(v36_), static_cast<T>(v37_), static_cast<T>(v38_),
static_cast<T>(v39_), static_cast<T>(v40_), static_cast<T>(v41_),
static_cast<T>(v42_), static_cast<T>(v43_), static_cast<T>(v44_),
static_cast<T>(v45_), static_cast<T>(v46_), static_cast<T>(v47_),
static_cast<T>(v48_), static_cast<T>(v49_), static_cast<T>(v50_)};
return ValuesIn(array); return ValuesIn(array);
} }
@@ -98,7 +98,7 @@ class ValueArray$i {
template <typename T> template <typename T>
operator ParamGenerator<T>() const { operator ParamGenerator<T>() const {
const T array[] = {$for j, [[v$(j)_]]}; const T array[] = {$for j, [[static_cast<T>(v$(j)_)]]};
return ValuesIn(array); return ValuesIn(array);
} }
+4 -4
View File
@@ -494,10 +494,10 @@ class ParameterizedTestCaseInfo : public ParameterizedTestCaseInfoBase {
const string& instantiation_name = gen_it->first; const string& instantiation_name = gen_it->first;
ParamGenerator<ParamType> generator((*gen_it->second)()); ParamGenerator<ParamType> generator((*gen_it->second)());
Message test_case_name_stream; string test_case_name;
if ( !instantiation_name.empty() ) if ( !instantiation_name.empty() )
test_case_name_stream << instantiation_name << "/"; test_case_name = instantiation_name + "/";
test_case_name_stream << test_info->test_case_base_name; test_case_name += test_info->test_case_base_name;
int i = 0; int i = 0;
for (typename ParamGenerator<ParamType>::iterator param_it = for (typename ParamGenerator<ParamType>::iterator param_it =
@@ -506,7 +506,7 @@ class ParameterizedTestCaseInfo : public ParameterizedTestCaseInfoBase {
Message test_name_stream; Message test_name_stream;
test_name_stream << test_info->test_base_name << "/" << i; test_name_stream << test_info->test_base_name << "/" << i;
MakeAndRegisterTestInfo( MakeAndRegisterTestInfo(
test_case_name_stream.GetString().c_str(), test_case_name.c_str(),
test_name_stream.GetString().c_str(), test_name_stream.GetString().c_str(),
NULL, // No type parameter. NULL, // No type parameter.
PrintToString(*param_it).c_str(), PrintToString(*param_it).c_str(),
+223 -51
View File
@@ -32,6 +32,10 @@
// Low-level types and utilities for porting Google Test to various // Low-level types and utilities for porting Google Test to various
// platforms. They are subject to change without notice. DO NOT USE // platforms. They are subject to change without notice. DO NOT USE
// THEM IN USER CODE. // THEM IN USER CODE.
//
// This file is fundamental to Google Test. All other Google Test source
// files are expected to #include this. Therefore, it cannot #include
// any other Google Test header.
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_ #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_ #define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_
@@ -72,6 +76,8 @@
// Test's own tr1 tuple implementation should be // Test's own tr1 tuple implementation should be
// used. Unused when the user sets // used. Unused when the user sets
// GTEST_HAS_TR1_TUPLE to 0. // GTEST_HAS_TR1_TUPLE to 0.
// GTEST_LANG_CXX11 - Define it to 1/0 to indicate that Google Test
// is building in C++11/C++98 mode.
// GTEST_LINKED_AS_SHARED_LIBRARY // GTEST_LINKED_AS_SHARED_LIBRARY
// - Define to 1 when compiling tests that use // - Define to 1 when compiling tests that use
// Google Test as a shared library (known as // Google Test as a shared library (known as
@@ -90,7 +96,11 @@
// GTEST_OS_LINUX - Linux // GTEST_OS_LINUX - Linux
// GTEST_OS_LINUX_ANDROID - Google Android // GTEST_OS_LINUX_ANDROID - Google Android
// GTEST_OS_MAC - Mac OS X // GTEST_OS_MAC - Mac OS X
// GTEST_OS_IOS - iOS
// GTEST_OS_IOS_SIMULATOR - iOS simulator
// GTEST_OS_NACL - Google Native Client (NaCl) // GTEST_OS_NACL - Google Native Client (NaCl)
// GTEST_OS_OPENBSD - OpenBSD
// GTEST_OS_QNX - QNX
// GTEST_OS_SOLARIS - Sun Solaris // GTEST_OS_SOLARIS - Sun Solaris
// GTEST_OS_SYMBIAN - Symbian // GTEST_OS_SYMBIAN - Symbian
// GTEST_OS_WINDOWS - Windows (Desktop, MinGW, or Mobile) // GTEST_OS_WINDOWS - Windows (Desktop, MinGW, or Mobile)
@@ -175,7 +185,7 @@
// GTEST_FLAG() - references a flag. // GTEST_FLAG() - references a flag.
// GTEST_DECLARE_*() - declares a flag. // GTEST_DECLARE_*() - declares a flag.
// GTEST_DEFINE_*() - defines a flag. // GTEST_DEFINE_*() - defines a flag.
// GetArgvs() - returns the command line as a vector of strings. // GetInjectableArgvs() - returns the command line as a vector of strings.
// //
// Environment variable utilities: // Environment variable utilities:
// GetEnv() - gets the value of an environment variable. // GetEnv() - gets the value of an environment variable.
@@ -193,6 +203,11 @@
# include <sys/stat.h> # include <sys/stat.h>
#endif // !_WIN32_WCE #endif // !_WIN32_WCE
#if defined __APPLE__
# include <AvailabilityMacros.h>
# include <TargetConditionals.h>
#endif
#include <iostream> // NOLINT #include <iostream> // NOLINT
#include <sstream> // NOLINT #include <sstream> // NOLINT
#include <string> // NOLINT #include <string> // NOLINT
@@ -227,11 +242,17 @@
# endif // _WIN32_WCE # endif // _WIN32_WCE
#elif defined __APPLE__ #elif defined __APPLE__
# define GTEST_OS_MAC 1 # define GTEST_OS_MAC 1
# if TARGET_OS_IPHONE
# define GTEST_OS_IOS 1
# if TARGET_IPHONE_SIMULATOR
# define GTEST_OS_IOS_SIMULATOR 1
# endif
# endif
#elif defined __linux__ #elif defined __linux__
# define GTEST_OS_LINUX 1 # define GTEST_OS_LINUX 1
# ifdef ANDROID # if defined __ANDROID__
# define GTEST_OS_LINUX_ANDROID 1 # define GTEST_OS_LINUX_ANDROID 1
# endif // ANDROID # endif
#elif defined __MVS__ #elif defined __MVS__
# define GTEST_OS_ZOS 1 # define GTEST_OS_ZOS 1
#elif defined(__sun) && defined(__SVR4) #elif defined(__sun) && defined(__SVR4)
@@ -242,8 +263,25 @@
# define GTEST_OS_HPUX 1 # define GTEST_OS_HPUX 1
#elif defined __native_client__ #elif defined __native_client__
# define GTEST_OS_NACL 1 # define GTEST_OS_NACL 1
#elif defined __OpenBSD__
# define GTEST_OS_OPENBSD 1
#elif defined __QNX__
# define GTEST_OS_QNX 1
#endif // __CYGWIN__ #endif // __CYGWIN__
#ifndef GTEST_LANG_CXX11
// gcc and clang define __GXX_EXPERIMENTAL_CXX0X__ when
// -std={c,gnu}++{0x,11} is passed. The C++11 standard specifies a
// value for __cplusplus, and recent versions of clang, gcc, and
// probably other compilers set that too in C++11 mode.
# if __GXX_EXPERIMENTAL_CXX0X__ || __cplusplus >= 201103L
// Compiling in at least C++11 mode.
# define GTEST_LANG_CXX11 1
# else
# define GTEST_LANG_CXX11 0
# endif
#endif
// Brings in definitions for functions used in the testing::internal::posix // Brings in definitions for functions used in the testing::internal::posix
// namespace (read, write, close, chdir, isatty, stat). We do not currently // namespace (read, write, close, chdir, isatty, stat). We do not currently
// use them on Windows Mobile. // use them on Windows Mobile.
@@ -252,20 +290,25 @@
// is not the case, we need to include headers that provide the functions // is not the case, we need to include headers that provide the functions
// mentioned above. // mentioned above.
# include <unistd.h> # include <unistd.h>
# if !GTEST_OS_NACL # include <strings.h>
// TODO(vladl@google.com): Remove this condition when Native Client SDK adds
// strings.h (tracked in
// http://code.google.com/p/nativeclient/issues/detail?id=1175).
# include <strings.h> // Native Client doesn't provide strings.h.
# endif
#elif !GTEST_OS_WINDOWS_MOBILE #elif !GTEST_OS_WINDOWS_MOBILE
# include <direct.h> # include <direct.h>
# include <io.h> # include <io.h>
#endif #endif
#if GTEST_OS_LINUX_ANDROID
// Used to define __ANDROID_API__ matching the target NDK API level.
# include <android/api-level.h> // NOLINT
#endif
// Defines this to true iff Google Test can use POSIX regular expressions. // Defines this to true iff Google Test can use POSIX regular expressions.
#ifndef GTEST_HAS_POSIX_RE #ifndef GTEST_HAS_POSIX_RE
# define GTEST_HAS_POSIX_RE (!GTEST_OS_WINDOWS) # if GTEST_OS_LINUX_ANDROID
// On Android, <regex.h> is only available starting with Gingerbread.
# define GTEST_HAS_POSIX_RE (__ANDROID_API__ >= 9)
# else
# define GTEST_HAS_POSIX_RE (!GTEST_OS_WINDOWS)
# endif
#endif #endif
#if GTEST_HAS_POSIX_RE #if GTEST_HAS_POSIX_RE
@@ -380,11 +423,27 @@
# elif defined(__GNUC__) && (GTEST_GCC_VER_ >= 40302) # elif defined(__GNUC__) && (GTEST_GCC_VER_ >= 40302)
# ifdef __GXX_RTTI # ifdef __GXX_RTTI
# define GTEST_HAS_RTTI 1 // When building against STLport with the Android NDK and with
// -frtti -fno-exceptions, the build fails at link time with undefined
// references to __cxa_bad_typeid. Note sure if STL or toolchain bug,
// so disable RTTI when detected.
# if GTEST_OS_LINUX_ANDROID && defined(_STLPORT_MAJOR) && \
!defined(__EXCEPTIONS)
# define GTEST_HAS_RTTI 0
# else
# define GTEST_HAS_RTTI 1
# endif // GTEST_OS_LINUX_ANDROID && __STLPORT_MAJOR && !__EXCEPTIONS
# else # else
# define GTEST_HAS_RTTI 0 # define GTEST_HAS_RTTI 0
# endif // __GXX_RTTI # endif // __GXX_RTTI
// Clang defines __GXX_RTTI starting with version 3.0, but its manual recommends
// using has_feature instead. has_feature(cxx_rtti) is supported since 2.7, the
// first version with C++ support.
# elif defined(__clang__)
# define GTEST_HAS_RTTI __has_feature(cxx_rtti)
// Starting with version 9.0 IBM Visual Age defines __RTTI_ALL__ to 1 if // Starting with version 9.0 IBM Visual Age defines __RTTI_ALL__ to 1 if
// both the typeid and dynamic_cast features are present. // both the typeid and dynamic_cast features are present.
# elif defined(__IBMCPP__) && (__IBMCPP__ >= 900) # elif defined(__IBMCPP__) && (__IBMCPP__ >= 900)
@@ -417,7 +476,8 @@
// //
// To disable threading support in Google Test, add -DGTEST_HAS_PTHREAD=0 // To disable threading support in Google Test, add -DGTEST_HAS_PTHREAD=0
// to your compiler flags. // to your compiler flags.
# define GTEST_HAS_PTHREAD (GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_HPUX) # define GTEST_HAS_PTHREAD (GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_HPUX \
|| GTEST_OS_QNX)
#endif // GTEST_HAS_PTHREAD #endif // GTEST_HAS_PTHREAD
#if GTEST_HAS_PTHREAD #if GTEST_HAS_PTHREAD
@@ -433,8 +493,13 @@
// this macro to 0 to prevent Google Test from using tuple (any // this macro to 0 to prevent Google Test from using tuple (any
// feature depending on tuple with be disabled in this mode). // feature depending on tuple with be disabled in this mode).
#ifndef GTEST_HAS_TR1_TUPLE #ifndef GTEST_HAS_TR1_TUPLE
# if GTEST_OS_LINUX_ANDROID && defined(_STLPORT_MAJOR)
// STLport, provided with the Android NDK, has neither <tr1/tuple> or <tuple>.
# define GTEST_HAS_TR1_TUPLE 0
# else
// The user didn't tell us not to do it, so we assume it's OK. // The user didn't tell us not to do it, so we assume it's OK.
# define GTEST_HAS_TR1_TUPLE 1 # define GTEST_HAS_TR1_TUPLE 1
# endif
#endif // GTEST_HAS_TR1_TUPLE #endif // GTEST_HAS_TR1_TUPLE
// Determines whether Google Test's own tr1 tuple implementation // Determines whether Google Test's own tr1 tuple implementation
@@ -443,14 +508,28 @@
// The user didn't tell us, so we need to figure it out. // The user didn't tell us, so we need to figure it out.
// We use our own TR1 tuple if we aren't sure the user has an // We use our own TR1 tuple if we aren't sure the user has an
// implementation of it already. At this time, GCC 4.0.0+ and MSVC // implementation of it already. At this time, libstdc++ 4.0.0+ and
// 2010 are the only mainstream compilers that come with a TR1 tuple // MSVC 2010 are the only mainstream standard libraries that come
// implementation. NVIDIA's CUDA NVCC compiler pretends to be GCC by // with a TR1 tuple implementation. NVIDIA's CUDA NVCC compiler
// defining __GNUC__ and friends, but cannot compile GCC's tuple // pretends to be GCC by defining __GNUC__ and friends, but cannot
// implementation. MSVC 2008 (9.0) provides TR1 tuple in a 323 MB // compile GCC's tuple implementation. MSVC 2008 (9.0) provides TR1
// Feature Pack download, which we cannot assume the user has. // tuple in a 323 MB Feature Pack download, which we cannot assume the
# if (defined(__GNUC__) && !defined(__CUDACC__) && (GTEST_GCC_VER_ >= 40000)) \ // user has. QNX's QCC compiler is a modified GCC but it doesn't
|| _MSC_VER >= 1600 // support TR1 tuple. libc++ only provides std::tuple, in C++11 mode,
// and it can be used with some compilers that define __GNUC__.
# if (defined(__GNUC__) && !defined(__CUDACC__) && (GTEST_GCC_VER_ >= 40000) \
&& !GTEST_OS_QNX && !defined(_LIBCPP_VERSION)) || _MSC_VER >= 1600
# define GTEST_ENV_HAS_TR1_TUPLE_ 1
# endif
// C++11 specifies that <tuple> provides std::tuple. Use that if gtest is used
// in C++11 mode and libstdc++ isn't very old (binaries targeting OS X 10.6
// can build with clang but need to use gcc4.2's libstdc++).
# if GTEST_LANG_CXX11 && (!defined(__GLIBCXX__) || __GLIBCXX__ > 20110325)
# define GTEST_ENV_HAS_STD_TUPLE_ 1
# endif
# if GTEST_ENV_HAS_TR1_TUPLE_ || GTEST_ENV_HAS_STD_TUPLE_
# define GTEST_USE_OWN_TR1_TUPLE 0 # define GTEST_USE_OWN_TR1_TUPLE 0
# else # else
# define GTEST_USE_OWN_TR1_TUPLE 1 # define GTEST_USE_OWN_TR1_TUPLE 1
@@ -465,6 +544,22 @@
# if GTEST_USE_OWN_TR1_TUPLE # if GTEST_USE_OWN_TR1_TUPLE
# include "gtest/internal/gtest-tuple.h" # include "gtest/internal/gtest-tuple.h"
# elif GTEST_ENV_HAS_STD_TUPLE_
# include <tuple>
// C++11 puts its tuple into the ::std namespace rather than
// ::std::tr1. gtest expects tuple to live in ::std::tr1, so put it there.
// This causes undefined behavior, but supported compilers react in
// the way we intend.
namespace std {
namespace tr1 {
using ::std::get;
using ::std::make_tuple;
using ::std::tuple;
using ::std::tuple_element;
using ::std::tuple_size;
}
}
# elif GTEST_OS_SYMBIAN # elif GTEST_OS_SYMBIAN
// On Symbian, BOOST_HAS_TR1_TUPLE causes Boost's TR1 tuple library to // On Symbian, BOOST_HAS_TR1_TUPLE causes Boost's TR1 tuple library to
@@ -515,7 +610,16 @@
// The user didn't tell us, so we need to figure it out. // The user didn't tell us, so we need to figure it out.
# if GTEST_OS_LINUX && !defined(__ia64__) # if GTEST_OS_LINUX && !defined(__ia64__)
# define GTEST_HAS_CLONE 1 # if GTEST_OS_LINUX_ANDROID
// On Android, clone() is only available on ARM starting with Gingerbread.
# if defined(__arm__) && __ANDROID_API__ >= 9
# define GTEST_HAS_CLONE 1
# else
# define GTEST_HAS_CLONE 0
# endif
# else
# define GTEST_HAS_CLONE 1
# endif
# else # else
# define GTEST_HAS_CLONE 0 # define GTEST_HAS_CLONE 0
# endif // GTEST_OS_LINUX && !defined(__ia64__) # endif // GTEST_OS_LINUX && !defined(__ia64__)
@@ -538,9 +642,11 @@
// Google Test does not support death tests for VC 7.1 and earlier as // Google Test does not support death tests for VC 7.1 and earlier as
// abort() in a VC 7.1 application compiled as GUI in debug config // abort() in a VC 7.1 application compiled as GUI in debug config
// pops up a dialog window that cannot be suppressed programmatically. // pops up a dialog window that cannot be suppressed programmatically.
#if (GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_CYGWIN || GTEST_OS_SOLARIS || \ #if (GTEST_OS_LINUX || GTEST_OS_CYGWIN || GTEST_OS_SOLARIS || \
(GTEST_OS_MAC && !GTEST_OS_IOS) || GTEST_OS_IOS_SIMULATOR || \
(GTEST_OS_WINDOWS_DESKTOP && _MSC_VER >= 1400) || \ (GTEST_OS_WINDOWS_DESKTOP && _MSC_VER >= 1400) || \
GTEST_OS_WINDOWS_MINGW || GTEST_OS_AIX || GTEST_OS_HPUX) GTEST_OS_WINDOWS_MINGW || GTEST_OS_AIX || GTEST_OS_HPUX || \
GTEST_OS_OPENBSD || GTEST_OS_QNX)
# define GTEST_HAS_DEATH_TEST 1 # define GTEST_HAS_DEATH_TEST 1
# include <vector> // NOLINT # include <vector> // NOLINT
#endif #endif
@@ -669,13 +775,23 @@
# define GTEST_NO_INLINE_ # define GTEST_NO_INLINE_
#endif #endif
// _LIBCPP_VERSION is defined by the libc++ library from the LLVM project.
#if defined(__GLIBCXX__) || defined(_LIBCPP_VERSION)
# define GTEST_HAS_CXXABI_H_ 1
#else
# define GTEST_HAS_CXXABI_H_ 0
#endif
namespace testing { namespace testing {
class Message; class Message;
namespace internal { namespace internal {
class String; // A secret type that Google Test users don't know about. It has no
// definition on purpose. Therefore it's impossible to create a
// Secret object, which is what we want.
class Secret;
// The GTEST_COMPILE_ASSERT_ macro can be used to verify that a compile time // The GTEST_COMPILE_ASSERT_ macro can be used to verify that a compile time
// expression is true. For example, you could use it to verify the // expression is true. For example, you could use it to verify the
@@ -697,8 +813,8 @@ struct CompileAssert {
}; };
#define GTEST_COMPILE_ASSERT_(expr, msg) \ #define GTEST_COMPILE_ASSERT_(expr, msg) \
typedef ::testing::internal::CompileAssert<(bool(expr))> \ typedef ::testing::internal::CompileAssert<(static_cast<bool>(expr))> \
msg[bool(expr) ? 1 : -1] msg[static_cast<bool>(expr) ? 1 : -1] GTEST_ATTRIBUTE_UNUSED_
// Implementation details of GTEST_COMPILE_ASSERT_: // Implementation details of GTEST_COMPILE_ASSERT_:
// //
@@ -796,6 +912,7 @@ class scoped_ptr {
ptr_ = p; ptr_ = p;
} }
} }
private: private:
T* ptr_; T* ptr_;
@@ -858,10 +975,9 @@ class GTEST_API_ RE {
private: private:
void Init(const char* regex); void Init(const char* regex);
// We use a const char* instead of a string, as Google Test may be used // We use a const char* instead of an std::string, as Google Test used to be
// where string is not available. We also do not use Google Test's own // used where std::string is not available. TODO(wan@google.com): change to
// String type here, in order to simplify dependencies between the // std::string.
// files.
const char* pattern_; const char* pattern_;
bool is_valid_; bool is_valid_;
@@ -1044,20 +1160,21 @@ Derived* CheckedDowncastToActualType(Base* base) {
// GetCapturedStderr - stops capturing stderr and returns the captured string. // GetCapturedStderr - stops capturing stderr and returns the captured string.
// //
GTEST_API_ void CaptureStdout(); GTEST_API_ void CaptureStdout();
GTEST_API_ String GetCapturedStdout(); GTEST_API_ std::string GetCapturedStdout();
GTEST_API_ void CaptureStderr(); GTEST_API_ void CaptureStderr();
GTEST_API_ String GetCapturedStderr(); GTEST_API_ std::string GetCapturedStderr();
#endif // GTEST_HAS_STREAM_REDIRECTION #endif // GTEST_HAS_STREAM_REDIRECTION
#if GTEST_HAS_DEATH_TEST #if GTEST_HAS_DEATH_TEST
// A copy of all command line arguments. Set by InitGoogleTest(). const ::std::vector<testing::internal::string>& GetInjectableArgvs();
extern ::std::vector<String> g_argvs; void SetInjectableArgvs(const ::std::vector<testing::internal::string>*
new_argvs);
// GTEST_HAS_DEATH_TEST implies we have ::std::string. // A copy of all command line arguments. Set by InitGoogleTest().
const ::std::vector<String>& GetArgvs(); extern ::std::vector<testing::internal::string> g_argvs;
#endif // GTEST_HAS_DEATH_TEST #endif // GTEST_HAS_DEATH_TEST
@@ -1084,22 +1201,37 @@ inline void SleepMilliseconds(int n) {
// use it in user tests, either directly or indirectly. // use it in user tests, either directly or indirectly.
class Notification { class Notification {
public: public:
Notification() : notified_(false) {} Notification() : notified_(false) {
GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_init(&mutex_, NULL));
}
~Notification() {
pthread_mutex_destroy(&mutex_);
}
// Notifies all threads created with this notification to start. Must // Notifies all threads created with this notification to start. Must
// be called from the controller thread. // be called from the controller thread.
void Notify() { notified_ = true; } void Notify() {
pthread_mutex_lock(&mutex_);
notified_ = true;
pthread_mutex_unlock(&mutex_);
}
// Blocks until the controller thread notifies. Must be called from a test // Blocks until the controller thread notifies. Must be called from a test
// thread. // thread.
void WaitForNotification() { void WaitForNotification() {
while(!notified_) { for (;;) {
pthread_mutex_lock(&mutex_);
const bool notified = notified_;
pthread_mutex_unlock(&mutex_);
if (notified)
break;
SleepMilliseconds(10); SleepMilliseconds(10);
} }
} }
private: private:
volatile bool notified_; pthread_mutex_t mutex_;
bool notified_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(Notification); GTEST_DISALLOW_COPY_AND_ASSIGN_(Notification);
}; };
@@ -1207,21 +1339,23 @@ class MutexBase {
void Lock() { void Lock() {
GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_lock(&mutex_)); GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_lock(&mutex_));
owner_ = pthread_self(); owner_ = pthread_self();
has_owner_ = true;
} }
// Releases this mutex. // Releases this mutex.
void Unlock() { void Unlock() {
// We don't protect writing to owner_ here, as it's the caller's // Since the lock is being released the owner_ field should no longer be
// responsibility to ensure that the current thread holds the // considered valid. We don't protect writing to has_owner_ here, as it's
// the caller's responsibility to ensure that the current thread holds the
// mutex when this is called. // mutex when this is called.
owner_ = 0; has_owner_ = false;
GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_unlock(&mutex_)); GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_unlock(&mutex_));
} }
// Does nothing if the current thread holds the mutex. Otherwise, crashes // Does nothing if the current thread holds the mutex. Otherwise, crashes
// with high probability. // with high probability.
void AssertHeld() const { void AssertHeld() const {
GTEST_CHECK_(owner_ == pthread_self()) GTEST_CHECK_(has_owner_ && pthread_equal(owner_, pthread_self()))
<< "The current thread is not holding the mutex @" << this; << "The current thread is not holding the mutex @" << this;
} }
@@ -1232,7 +1366,14 @@ class MutexBase {
// have to be public. // have to be public.
public: public:
pthread_mutex_t mutex_; // The underlying pthread mutex. pthread_mutex_t mutex_; // The underlying pthread mutex.
pthread_t owner_; // The thread holding the mutex; 0 means no one holds it. // has_owner_ indicates whether the owner_ field below contains a valid thread
// ID and is therefore safe to inspect (e.g., to use in pthread_equal()). All
// accesses to the owner_ field should be protected by a check of this field.
// An alternative might be to memset() owner_ to all zeros, but there's no
// guarantee that a zero'd pthread_t is necessarily invalid or even different
// from pthread_self().
bool has_owner_;
pthread_t owner_; // The thread holding the mutex.
}; };
// Forward-declares a static mutex. // Forward-declares a static mutex.
@@ -1240,8 +1381,13 @@ class MutexBase {
extern ::testing::internal::MutexBase mutex extern ::testing::internal::MutexBase mutex
// Defines and statically (i.e. at link time) initializes a static mutex. // Defines and statically (i.e. at link time) initializes a static mutex.
// The initialization list here does not explicitly initialize each field,
// instead relying on default initialization for the unspecified fields. In
// particular, the owner_ field (a pthread_t) is not explicitly initialized.
// This allows initialization to work whether pthread_t is a scalar or struct.
// The flag -Wmissing-field-initializers must not be specified for this to work.
# define GTEST_DEFINE_STATIC_MUTEX_(mutex) \ # define GTEST_DEFINE_STATIC_MUTEX_(mutex) \
::testing::internal::MutexBase mutex = { PTHREAD_MUTEX_INITIALIZER, 0 } ::testing::internal::MutexBase mutex = { PTHREAD_MUTEX_INITIALIZER, false }
// The Mutex class can only be used for mutexes created at runtime. It // The Mutex class can only be used for mutexes created at runtime. It
// shares its API with MutexBase otherwise. // shares its API with MutexBase otherwise.
@@ -1249,7 +1395,7 @@ class Mutex : public MutexBase {
public: public:
Mutex() { Mutex() {
GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_init(&mutex_, NULL)); GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_init(&mutex_, NULL));
owner_ = 0; has_owner_ = false;
} }
~Mutex() { ~Mutex() {
GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_destroy(&mutex_)); GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_destroy(&mutex_));
@@ -1399,6 +1545,8 @@ class ThreadLocal {
class Mutex { class Mutex {
public: public:
Mutex() {} Mutex() {}
void Lock() {}
void Unlock() {}
void AssertHeld() const {} void AssertHeld() const {}
}; };
@@ -1529,6 +1677,10 @@ inline bool IsUpper(char ch) {
inline bool IsXDigit(char ch) { inline bool IsXDigit(char ch) {
return isxdigit(static_cast<unsigned char>(ch)) != 0; return isxdigit(static_cast<unsigned char>(ch)) != 0;
} }
inline bool IsXDigit(wchar_t ch) {
const unsigned char low_byte = static_cast<unsigned char>(ch);
return ch == low_byte && isxdigit(low_byte) != 0;
}
inline char ToLower(char ch) { inline char ToLower(char ch) {
return static_cast<char>(tolower(static_cast<unsigned char>(ch))); return static_cast<char>(tolower(static_cast<unsigned char>(ch)));
@@ -1666,6 +1818,23 @@ inline void Abort() { abort(); }
} // namespace posix } // namespace posix
// MSVC "deprecates" snprintf and issues warnings wherever it is used. In
// order to avoid these warnings, we need to use _snprintf or _snprintf_s on
// MSVC-based platforms. We map the GTEST_SNPRINTF_ macro to the appropriate
// function in order to achieve that. We use macro definition here because
// snprintf is a variadic function.
#if _MSC_VER >= 1400 && !GTEST_OS_WINDOWS_MOBILE
// MSVC 2005 and above support variadic macros.
# define GTEST_SNPRINTF_(buffer, size, format, ...) \
_snprintf_s(buffer, size, size, format, __VA_ARGS__)
#elif defined(_MSC_VER)
// Windows CE does not define _snprintf_s and MSVC prior to 2005 doesn't
// complain about _snprintf.
# define GTEST_SNPRINTF_ _snprintf
#else
# define GTEST_SNPRINTF_ snprintf
#endif
// The maximum number a BiggestInt can represent. This definition // The maximum number a BiggestInt can represent. This definition
// works no matter BiggestInt is represented in one's complement or // works no matter BiggestInt is represented in one's complement or
// two's complement. // two's complement.
@@ -1718,7 +1887,6 @@ class TypeWithSize<4> {
template <> template <>
class TypeWithSize<8> { class TypeWithSize<8> {
public: public:
#if GTEST_OS_WINDOWS #if GTEST_OS_WINDOWS
typedef __int64 Int; typedef __int64 Int;
typedef unsigned __int64 UInt; typedef unsigned __int64 UInt;
@@ -1745,7 +1913,7 @@ typedef TypeWithSize<8>::Int TimeInMillis; // Represents time in milliseconds.
#define GTEST_DECLARE_int32_(name) \ #define GTEST_DECLARE_int32_(name) \
GTEST_API_ extern ::testing::internal::Int32 GTEST_FLAG(name) GTEST_API_ extern ::testing::internal::Int32 GTEST_FLAG(name)
#define GTEST_DECLARE_string_(name) \ #define GTEST_DECLARE_string_(name) \
GTEST_API_ extern ::testing::internal::String GTEST_FLAG(name) GTEST_API_ extern ::std::string GTEST_FLAG(name)
// Macros for defining flags. // Macros for defining flags.
#define GTEST_DEFINE_bool_(name, default_val, doc) \ #define GTEST_DEFINE_bool_(name, default_val, doc) \
@@ -1753,7 +1921,11 @@ typedef TypeWithSize<8>::Int TimeInMillis; // Represents time in milliseconds.
#define GTEST_DEFINE_int32_(name, default_val, doc) \ #define GTEST_DEFINE_int32_(name, default_val, doc) \
GTEST_API_ ::testing::internal::Int32 GTEST_FLAG(name) = (default_val) GTEST_API_ ::testing::internal::Int32 GTEST_FLAG(name) = (default_val)
#define GTEST_DEFINE_string_(name, default_val, doc) \ #define GTEST_DEFINE_string_(name, default_val, doc) \
GTEST_API_ ::testing::internal::String GTEST_FLAG(name) = (default_val) GTEST_API_ ::std::string GTEST_FLAG(name) = (default_val)
// Thread annotations
#define GTEST_EXCLUSIVE_LOCK_REQUIRED_(locks)
#define GTEST_LOCK_EXCLUDED_(locks)
// Parses 'str' for a 32-bit signed integer. If successful, writes the result // Parses 'str' for a 32-bit signed integer. If successful, writes the result
// to *value and returns true; otherwise leaves *value unchanged and returns // to *value and returns true; otherwise leaves *value unchanged and returns
+17 -200
View File
@@ -47,50 +47,18 @@
#endif #endif
#include <string.h> #include <string.h>
#include "gtest/internal/gtest-port.h"
#include <string> #include <string>
#include "gtest/internal/gtest-port.h"
namespace testing { namespace testing {
namespace internal { namespace internal {
// String - a UTF-8 string class. // String - an abstract class holding static string utilities.
//
// For historic reasons, we don't use std::string.
//
// TODO(wan@google.com): replace this class with std::string or
// implement it in terms of the latter.
//
// Note that String can represent both NULL and the empty string,
// while std::string cannot represent NULL.
//
// NULL and the empty string are considered different. NULL is less
// than anything (including the empty string) except itself.
//
// This class only provides minimum functionality necessary for
// implementing Google Test. We do not intend to implement a full-fledged
// string class here.
//
// Since the purpose of this class is to provide a substitute for
// std::string on platforms where it cannot be used, we define a copy
// constructor and assignment operators such that we don't need
// conditional compilation in a lot of places.
//
// In order to make the representation efficient, the d'tor of String
// is not virtual. Therefore DO NOT INHERIT FROM String.
class GTEST_API_ String { class GTEST_API_ String {
public: public:
// Static utility methods // Static utility methods
// Returns the input enclosed in double quotes if it's not NULL;
// otherwise returns "(null)". For example, "\"Hello\"" is returned
// for input "Hello".
//
// This is useful for printing a C string in the syntax of a literal.
//
// Known issue: escape sequences are not handled yet.
static String ShowCStringQuoted(const char* c_str);
// Clones a 0-terminated C string, allocating memory using new. The // Clones a 0-terminated C string, allocating memory using new. The
// caller is responsible for deleting the return value using // caller is responsible for deleting the return value using
// delete[]. Returns the cloned string, or NULL if the input is // delete[]. Returns the cloned string, or NULL if the input is
@@ -137,11 +105,7 @@ class GTEST_API_ String {
// NULL will be converted to "(null)". If an error occurred during // NULL will be converted to "(null)". If an error occurred during
// the conversion, "(failed to convert from wide string)" is // the conversion, "(failed to convert from wide string)" is
// returned. // returned.
static String ShowWideCString(const wchar_t* wide_c_str); static std::string ShowWideCString(const wchar_t* wide_c_str);
// Similar to ShowWideCString(), except that this function encloses
// the converted string in double quotes.
static String ShowWideCStringQuoted(const wchar_t* wide_c_str);
// Compares two wide C strings. Returns true iff they have the same // Compares two wide C strings. Returns true iff they have the same
// content. // content.
@@ -175,174 +139,27 @@ class GTEST_API_ String {
static bool CaseInsensitiveWideCStringEquals(const wchar_t* lhs, static bool CaseInsensitiveWideCStringEquals(const wchar_t* lhs,
const wchar_t* rhs); const wchar_t* rhs);
// Formats a list of arguments to a String, using the same format // Returns true iff the given string ends with the given suffix, ignoring
// spec string as for printf. // case. Any string is considered to end with an empty suffix.
// static bool EndsWithCaseInsensitive(
// We do not use the StringPrintf class as it is not universally const std::string& str, const std::string& suffix);
// available.
//
// The result is limited to 4096 characters (including the tailing
// 0). If 4096 characters are not enough to format the input,
// "<buffer exceeded>" is returned.
static String Format(const char* format, ...);
// C'tors // Formats an int value as "%02d".
static std::string FormatIntWidth2(int value); // "%02d" for width == 2
// The default c'tor constructs a NULL string. // Formats an int value as "%X".
String() : c_str_(NULL), length_(0) {} static std::string FormatHexInt(int value);
// Constructs a String by cloning a 0-terminated C string. // Formats a byte as "%02X".
String(const char* a_c_str) { // NOLINT static std::string FormatByte(unsigned char value);
if (a_c_str == NULL) {
c_str_ = NULL;
length_ = 0;
} else {
ConstructNonNull(a_c_str, strlen(a_c_str));
}
}
// Constructs a String by copying a given number of chars from a
// buffer. E.g. String("hello", 3) creates the string "hel",
// String("a\0bcd", 4) creates "a\0bc", String(NULL, 0) creates "",
// and String(NULL, 1) results in access violation.
String(const char* buffer, size_t a_length) {
ConstructNonNull(buffer, a_length);
}
// The copy c'tor creates a new copy of the string. The two
// String objects do not share content.
String(const String& str) : c_str_(NULL), length_(0) { *this = str; }
// D'tor. String is intended to be a final class, so the d'tor
// doesn't need to be virtual.
~String() { delete[] c_str_; }
// Allows a String to be implicitly converted to an ::std::string or
// ::string, and vice versa. Converting a String containing a NULL
// pointer to ::std::string or ::string is undefined behavior.
// Converting a ::std::string or ::string containing an embedded NUL
// character to a String will result in the prefix up to the first
// NUL character.
String(const ::std::string& str) {
ConstructNonNull(str.c_str(), str.length());
}
operator ::std::string() const { return ::std::string(c_str(), length()); }
#if GTEST_HAS_GLOBAL_STRING
String(const ::string& str) {
ConstructNonNull(str.c_str(), str.length());
}
operator ::string() const { return ::string(c_str(), length()); }
#endif // GTEST_HAS_GLOBAL_STRING
// Returns true iff this is an empty string (i.e. "").
bool empty() const { return (c_str() != NULL) && (length() == 0); }
// Compares this with another String.
// Returns < 0 if this is less than rhs, 0 if this is equal to rhs, or > 0
// if this is greater than rhs.
int Compare(const String& rhs) const;
// Returns true iff this String equals the given C string. A NULL
// string and a non-NULL string are considered not equal.
bool operator==(const char* a_c_str) const { return Compare(a_c_str) == 0; }
// Returns true iff this String is less than the given String. A
// NULL string is considered less than "".
bool operator<(const String& rhs) const { return Compare(rhs) < 0; }
// Returns true iff this String doesn't equal the given C string. A NULL
// string and a non-NULL string are considered not equal.
bool operator!=(const char* a_c_str) const { return !(*this == a_c_str); }
// Returns true iff this String ends with the given suffix. *Any*
// String is considered to end with a NULL or empty suffix.
bool EndsWith(const char* suffix) const;
// Returns true iff this String ends with the given suffix, not considering
// case. Any String is considered to end with a NULL or empty suffix.
bool EndsWithCaseInsensitive(const char* suffix) const;
// Returns the length of the encapsulated string, or 0 if the
// string is NULL.
size_t length() const { return length_; }
// Gets the 0-terminated C string this String object represents.
// The String object still owns the string. Therefore the caller
// should NOT delete the return value.
const char* c_str() const { return c_str_; }
// Assigns a C string to this object. Self-assignment works.
const String& operator=(const char* a_c_str) {
return *this = String(a_c_str);
}
// Assigns a String object to this object. Self-assignment works.
const String& operator=(const String& rhs) {
if (this != &rhs) {
delete[] c_str_;
if (rhs.c_str() == NULL) {
c_str_ = NULL;
length_ = 0;
} else {
ConstructNonNull(rhs.c_str(), rhs.length());
}
}
return *this;
}
private: private:
// Constructs a non-NULL String from the given content. This String(); // Not meant to be instantiated.
// function can only be called when c_str_ has not been allocated.
// ConstructNonNull(NULL, 0) results in an empty string ("").
// ConstructNonNull(NULL, non_zero) is undefined behavior.
void ConstructNonNull(const char* buffer, size_t a_length) {
char* const str = new char[a_length + 1];
memcpy(str, buffer, a_length);
str[a_length] = '\0';
c_str_ = str;
length_ = a_length;
}
const char* c_str_;
size_t length_;
}; // class String }; // class String
// Streams a String to an ostream. Each '\0' character in the String // Gets the content of the stringstream's buffer as an std::string. Each '\0'
// is replaced with "\\0".
inline ::std::ostream& operator<<(::std::ostream& os, const String& str) {
if (str.c_str() == NULL) {
os << "(null)";
} else {
const char* const c_str = str.c_str();
for (size_t i = 0; i != str.length(); i++) {
if (c_str[i] == '\0') {
os << "\\0";
} else {
os << c_str[i];
}
}
}
return os;
}
// Gets the content of the stringstream's buffer as a String. Each '\0'
// character in the buffer is replaced with "\\0". // character in the buffer is replaced with "\\0".
GTEST_API_ String StringStreamToString(::std::stringstream* stream); GTEST_API_ std::string StringStreamToString(::std::stringstream* stream);
// Converts a streamable value to a String. A NULL pointer is
// converted to "(null)". When the input value is a ::string,
// ::std::string, ::wstring, or ::std::wstring object, each NUL
// character in it is replaced with "\\0".
// Declared here but defined in gtest.h, so that it has access
// to the definition of the Message class, required by the ARM
// compiler.
template <typename T>
String StreamableToString(const T& streamable);
} // namespace internal } // namespace internal
} // namespace testing } // namespace testing
+68 -24
View File
@@ -1,4 +1,6 @@
// This file was GENERATED by a script. DO NOT EDIT BY HAND!!! // This file was GENERATED by command:
// pump.py gtest-tuple.h.pump
// DO NOT EDIT BY HAND!!!
// Copyright 2009 Google Inc. // Copyright 2009 Google Inc.
// All Rights Reserved. // All Rights Reserved.
@@ -140,34 +142,54 @@ template <bool kIndexValid, int kIndex, class Tuple>
struct TupleElement; struct TupleElement;
template <GTEST_10_TYPENAMES_(T)> template <GTEST_10_TYPENAMES_(T)>
struct TupleElement<true, 0, GTEST_10_TUPLE_(T)> { typedef T0 type; }; struct TupleElement<true, 0, GTEST_10_TUPLE_(T) > {
typedef T0 type;
};
template <GTEST_10_TYPENAMES_(T)> template <GTEST_10_TYPENAMES_(T)>
struct TupleElement<true, 1, GTEST_10_TUPLE_(T)> { typedef T1 type; }; struct TupleElement<true, 1, GTEST_10_TUPLE_(T) > {
typedef T1 type;
};
template <GTEST_10_TYPENAMES_(T)> template <GTEST_10_TYPENAMES_(T)>
struct TupleElement<true, 2, GTEST_10_TUPLE_(T)> { typedef T2 type; }; struct TupleElement<true, 2, GTEST_10_TUPLE_(T) > {
typedef T2 type;
};
template <GTEST_10_TYPENAMES_(T)> template <GTEST_10_TYPENAMES_(T)>
struct TupleElement<true, 3, GTEST_10_TUPLE_(T)> { typedef T3 type; }; struct TupleElement<true, 3, GTEST_10_TUPLE_(T) > {
typedef T3 type;
};
template <GTEST_10_TYPENAMES_(T)> template <GTEST_10_TYPENAMES_(T)>
struct TupleElement<true, 4, GTEST_10_TUPLE_(T)> { typedef T4 type; }; struct TupleElement<true, 4, GTEST_10_TUPLE_(T) > {
typedef T4 type;
};
template <GTEST_10_TYPENAMES_(T)> template <GTEST_10_TYPENAMES_(T)>
struct TupleElement<true, 5, GTEST_10_TUPLE_(T)> { typedef T5 type; }; struct TupleElement<true, 5, GTEST_10_TUPLE_(T) > {
typedef T5 type;
};
template <GTEST_10_TYPENAMES_(T)> template <GTEST_10_TYPENAMES_(T)>
struct TupleElement<true, 6, GTEST_10_TUPLE_(T)> { typedef T6 type; }; struct TupleElement<true, 6, GTEST_10_TUPLE_(T) > {
typedef T6 type;
};
template <GTEST_10_TYPENAMES_(T)> template <GTEST_10_TYPENAMES_(T)>
struct TupleElement<true, 7, GTEST_10_TUPLE_(T)> { typedef T7 type; }; struct TupleElement<true, 7, GTEST_10_TUPLE_(T) > {
typedef T7 type;
};
template <GTEST_10_TYPENAMES_(T)> template <GTEST_10_TYPENAMES_(T)>
struct TupleElement<true, 8, GTEST_10_TUPLE_(T)> { typedef T8 type; }; struct TupleElement<true, 8, GTEST_10_TUPLE_(T) > {
typedef T8 type;
};
template <GTEST_10_TYPENAMES_(T)> template <GTEST_10_TYPENAMES_(T)>
struct TupleElement<true, 9, GTEST_10_TUPLE_(T)> { typedef T9 type; }; struct TupleElement<true, 9, GTEST_10_TUPLE_(T) > {
typedef T9 type;
};
} // namespace gtest_internal } // namespace gtest_internal
@@ -708,37 +730,59 @@ inline GTEST_10_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2,
template <typename Tuple> struct tuple_size; template <typename Tuple> struct tuple_size;
template <GTEST_0_TYPENAMES_(T)> template <GTEST_0_TYPENAMES_(T)>
struct tuple_size<GTEST_0_TUPLE_(T)> { static const int value = 0; }; struct tuple_size<GTEST_0_TUPLE_(T) > {
static const int value = 0;
};
template <GTEST_1_TYPENAMES_(T)> template <GTEST_1_TYPENAMES_(T)>
struct tuple_size<GTEST_1_TUPLE_(T)> { static const int value = 1; }; struct tuple_size<GTEST_1_TUPLE_(T) > {
static const int value = 1;
};
template <GTEST_2_TYPENAMES_(T)> template <GTEST_2_TYPENAMES_(T)>
struct tuple_size<GTEST_2_TUPLE_(T)> { static const int value = 2; }; struct tuple_size<GTEST_2_TUPLE_(T) > {
static const int value = 2;
};
template <GTEST_3_TYPENAMES_(T)> template <GTEST_3_TYPENAMES_(T)>
struct tuple_size<GTEST_3_TUPLE_(T)> { static const int value = 3; }; struct tuple_size<GTEST_3_TUPLE_(T) > {
static const int value = 3;
};
template <GTEST_4_TYPENAMES_(T)> template <GTEST_4_TYPENAMES_(T)>
struct tuple_size<GTEST_4_TUPLE_(T)> { static const int value = 4; }; struct tuple_size<GTEST_4_TUPLE_(T) > {
static const int value = 4;
};
template <GTEST_5_TYPENAMES_(T)> template <GTEST_5_TYPENAMES_(T)>
struct tuple_size<GTEST_5_TUPLE_(T)> { static const int value = 5; }; struct tuple_size<GTEST_5_TUPLE_(T) > {
static const int value = 5;
};
template <GTEST_6_TYPENAMES_(T)> template <GTEST_6_TYPENAMES_(T)>
struct tuple_size<GTEST_6_TUPLE_(T)> { static const int value = 6; }; struct tuple_size<GTEST_6_TUPLE_(T) > {
static const int value = 6;
};
template <GTEST_7_TYPENAMES_(T)> template <GTEST_7_TYPENAMES_(T)>
struct tuple_size<GTEST_7_TUPLE_(T)> { static const int value = 7; }; struct tuple_size<GTEST_7_TUPLE_(T) > {
static const int value = 7;
};
template <GTEST_8_TYPENAMES_(T)> template <GTEST_8_TYPENAMES_(T)>
struct tuple_size<GTEST_8_TUPLE_(T)> { static const int value = 8; }; struct tuple_size<GTEST_8_TUPLE_(T) > {
static const int value = 8;
};
template <GTEST_9_TYPENAMES_(T)> template <GTEST_9_TYPENAMES_(T)>
struct tuple_size<GTEST_9_TUPLE_(T)> { static const int value = 9; }; struct tuple_size<GTEST_9_TUPLE_(T) > {
static const int value = 9;
};
template <GTEST_10_TYPENAMES_(T)> template <GTEST_10_TYPENAMES_(T)>
struct tuple_size<GTEST_10_TUPLE_(T)> { static const int value = 10; }; struct tuple_size<GTEST_10_TUPLE_(T) > {
static const int value = 10;
};
template <int k, class Tuple> template <int k, class Tuple>
struct tuple_element { struct tuple_element {
@@ -922,8 +966,8 @@ template <GTEST_10_TYPENAMES_(T), GTEST_10_TYPENAMES_(U)>
inline bool operator==(const GTEST_10_TUPLE_(T)& t, inline bool operator==(const GTEST_10_TUPLE_(T)& t,
const GTEST_10_TUPLE_(U)& u) { const GTEST_10_TUPLE_(U)& u) {
return gtest_internal::SameSizeTuplePrefixComparator< return gtest_internal::SameSizeTuplePrefixComparator<
tuple_size<GTEST_10_TUPLE_(T)>::value, tuple_size<GTEST_10_TUPLE_(T) >::value,
tuple_size<GTEST_10_TUPLE_(U)>::value>::Eq(t, u); tuple_size<GTEST_10_TUPLE_(U) >::value>::Eq(t, u);
} }
template <GTEST_10_TYPENAMES_(T), GTEST_10_TYPENAMES_(U)> template <GTEST_10_TYPENAMES_(T), GTEST_10_TYPENAMES_(U)>
+8 -5
View File
@@ -118,8 +118,9 @@ struct TupleElement;
$for i [[ $for i [[
template <GTEST_$(n)_TYPENAMES_(T)> template <GTEST_$(n)_TYPENAMES_(T)>
struct TupleElement<true, $i, GTEST_$(n)_TUPLE_(T)> [[]] struct TupleElement<true, $i, GTEST_$(n)_TUPLE_(T) > {
{ typedef T$i type; }; typedef T$i type;
};
]] ]]
@@ -220,7 +221,9 @@ template <typename Tuple> struct tuple_size;
$for j [[ $for j [[
template <GTEST_$(j)_TYPENAMES_(T)> template <GTEST_$(j)_TYPENAMES_(T)>
struct tuple_size<GTEST_$(j)_TUPLE_(T)> { static const int value = $j; }; struct tuple_size<GTEST_$(j)_TUPLE_(T) > {
static const int value = $j;
};
]] ]]
@@ -302,8 +305,8 @@ template <GTEST_$(n)_TYPENAMES_(T), GTEST_$(n)_TYPENAMES_(U)>
inline bool operator==(const GTEST_$(n)_TUPLE_(T)& t, inline bool operator==(const GTEST_$(n)_TUPLE_(T)& t,
const GTEST_$(n)_TUPLE_(U)& u) { const GTEST_$(n)_TUPLE_(U)& u) {
return gtest_internal::SameSizeTuplePrefixComparator< return gtest_internal::SameSizeTuplePrefixComparator<
tuple_size<GTEST_$(n)_TUPLE_(T)>::value, tuple_size<GTEST_$(n)_TUPLE_(T) >::value,
tuple_size<GTEST_$(n)_TUPLE_(U)>::value>::Eq(t, u); tuple_size<GTEST_$(n)_TUPLE_(U) >::value>::Eq(t, u);
} }
template <GTEST_$(n)_TYPENAMES_(T), GTEST_$(n)_TYPENAMES_(U)> template <GTEST_$(n)_TYPENAMES_(T), GTEST_$(n)_TYPENAMES_(U)>
+11 -10
View File
@@ -45,15 +45,14 @@
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ #define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_
#include "gtest/internal/gtest-port.h" #include "gtest/internal/gtest-port.h"
#include "gtest/internal/gtest-string.h"
// #ifdef __GNUC__ is too general here. It is possible to use gcc without using // #ifdef __GNUC__ is too general here. It is possible to use gcc without using
// libstdc++ (which is where cxxabi.h comes from). // libstdc++ (which is where cxxabi.h comes from).
# ifdef __GLIBCXX__ # if GTEST_HAS_CXXABI_H_
# include <cxxabi.h> # include <cxxabi.h>
# elif defined(__HP_aCC) # elif defined(__HP_aCC)
# include <acxx_demangle.h> # include <acxx_demangle.h>
# endif // __GLIBCXX__ # endif // GTEST_HASH_CXXABI_H_
namespace testing { namespace testing {
namespace internal { namespace internal {
@@ -62,24 +61,24 @@ namespace internal {
// NB: This function is also used in Google Mock, so don't move it inside of // NB: This function is also used in Google Mock, so don't move it inside of
// the typed-test-only section below. // the typed-test-only section below.
template <typename T> template <typename T>
String GetTypeName() { std::string GetTypeName() {
# if GTEST_HAS_RTTI # if GTEST_HAS_RTTI
const char* const name = typeid(T).name(); const char* const name = typeid(T).name();
# if defined(__GLIBCXX__) || defined(__HP_aCC) # if GTEST_HAS_CXXABI_H_ || defined(__HP_aCC)
int status = 0; int status = 0;
// gcc's implementation of typeid(T).name() mangles the type name, // gcc's implementation of typeid(T).name() mangles the type name,
// so we have to demangle it. // so we have to demangle it.
# ifdef __GLIBCXX__ # if GTEST_HAS_CXXABI_H_
using abi::__cxa_demangle; using abi::__cxa_demangle;
# endif // __GLIBCXX__ # endif // GTEST_HAS_CXXABI_H_
char* const readable_name = __cxa_demangle(name, 0, 0, &status); char* const readable_name = __cxa_demangle(name, 0, 0, &status);
const String name_str(status == 0 ? readable_name : name); const std::string name_str(status == 0 ? readable_name : name);
free(readable_name); free(readable_name);
return name_str; return name_str;
# else # else
return name; return name;
# endif // __GLIBCXX__ || __HP_aCC # endif // GTEST_HAS_CXXABI_H_ || __HP_aCC
# else # else
@@ -3300,7 +3299,9 @@ struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
// INSTANTIATE_TYPED_TEST_CASE_P(). // INSTANTIATE_TYPED_TEST_CASE_P().
template <typename T> template <typename T>
struct TypeList { typedef Types1<T> type; }; struct TypeList {
typedef Types1<T> type;
};
template <typename T1, typename T2, typename T3, typename T4, typename T5, template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10, typename T6, typename T7, typename T8, typename T9, typename T10,
+11 -10
View File
@@ -43,15 +43,14 @@ $var n = 50 $$ Maximum length of type lists we want to support.
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ #define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_
#include "gtest/internal/gtest-port.h" #include "gtest/internal/gtest-port.h"
#include "gtest/internal/gtest-string.h"
// #ifdef __GNUC__ is too general here. It is possible to use gcc without using // #ifdef __GNUC__ is too general here. It is possible to use gcc without using
// libstdc++ (which is where cxxabi.h comes from). // libstdc++ (which is where cxxabi.h comes from).
# ifdef __GLIBCXX__ # if GTEST_HAS_CXXABI_H_
# include <cxxabi.h> # include <cxxabi.h>
# elif defined(__HP_aCC) # elif defined(__HP_aCC)
# include <acxx_demangle.h> # include <acxx_demangle.h>
# endif // __GLIBCXX__ # endif // GTEST_HASH_CXXABI_H_
namespace testing { namespace testing {
namespace internal { namespace internal {
@@ -60,24 +59,24 @@ namespace internal {
// NB: This function is also used in Google Mock, so don't move it inside of // NB: This function is also used in Google Mock, so don't move it inside of
// the typed-test-only section below. // the typed-test-only section below.
template <typename T> template <typename T>
String GetTypeName() { std::string GetTypeName() {
# if GTEST_HAS_RTTI # if GTEST_HAS_RTTI
const char* const name = typeid(T).name(); const char* const name = typeid(T).name();
# if defined(__GLIBCXX__) || defined(__HP_aCC) # if GTEST_HAS_CXXABI_H_ || defined(__HP_aCC)
int status = 0; int status = 0;
// gcc's implementation of typeid(T).name() mangles the type name, // gcc's implementation of typeid(T).name() mangles the type name,
// so we have to demangle it. // so we have to demangle it.
# ifdef __GLIBCXX__ # if GTEST_HAS_CXXABI_H_
using abi::__cxa_demangle; using abi::__cxa_demangle;
# endif // __GLIBCXX__ # endif // GTEST_HAS_CXXABI_H_
char* const readable_name = __cxa_demangle(name, 0, 0, &status); char* const readable_name = __cxa_demangle(name, 0, 0, &status);
const String name_str(status == 0 ? readable_name : name); const std::string name_str(status == 0 ? readable_name : name);
free(readable_name); free(readable_name);
return name_str; return name_str;
# else # else
return name; return name;
# endif // __GLIBCXX__ || __HP_aCC # endif // GTEST_HAS_CXXABI_H_ || __HP_aCC
# else # else
@@ -279,7 +278,9 @@ struct Templates<$for j, [[T$j]]$for k[[, NoneT]]> {
// INSTANTIATE_TYPED_TEST_CASE_P(). // INSTANTIATE_TYPED_TEST_CASE_P().
template <typename T> template <typename T>
struct TypeList { typedef Types1<T> type; }; struct TypeList {
typedef Types1<T> type;
};
$range i 1..n $range i 1..n
+4 -2
View File
@@ -20,10 +20,12 @@ GTEST_DIR = ..
USER_DIR = ../samples USER_DIR = ../samples
# Flags passed to the preprocessor. # Flags passed to the preprocessor.
CPPFLAGS += -I$(GTEST_DIR)/include # Set Google Test's header directory as a system directory, such that
# the compiler doesn't generate warnings in Google Test headers.
CPPFLAGS += -isystem $(GTEST_DIR)/include
# Flags passed to the C++ compiler. # Flags passed to the C++ compiler.
CXXFLAGS += -g -Wall -Wextra CXXFLAGS += -g -Wall -Wextra -pthread
# All tests produced by this Makefile. Remember to add new tests you # All tests produced by this Makefile. Remember to add new tests you
# created to the list. # created to the list.
+1 -2
View File
@@ -89,8 +89,7 @@ class LeakChecker : public EmptyTestEventListener {
// You can generate a failure in any event handler except // You can generate a failure in any event handler except
// OnTestPartResult. Just use an appropriate Google Test assertion to do // OnTestPartResult. Just use an appropriate Google Test assertion to do
// it. // it.
EXPECT_TRUE(difference <= 0) EXPECT_LE(difference, 0) << "Leaked " << difference << " unit(s) of Water!";
<< "Leaked " << difference << " unit(s) of Water!";
} }
int initially_allocated_; int initially_allocated_;
+1 -1
View File
@@ -81,7 +81,7 @@ TEST(FactorialTest, Negative) {
// test case. // test case.
EXPECT_EQ(1, Factorial(-5)); EXPECT_EQ(1, Factorial(-5));
EXPECT_EQ(1, Factorial(-1)); EXPECT_EQ(1, Factorial(-1));
EXPECT_TRUE(Factorial(-10) > 0); EXPECT_GT(Factorial(-10), 0);
// <TechnicalDetails> // <TechnicalDetails>
// //
-1
View File
@@ -44,7 +44,6 @@ class MyString {
const MyString& operator=(const MyString& rhs); const MyString& operator=(const MyString& rhs);
public: public:
// Clones a 0-terminated C string, allocating memory using new. // Clones a 0-terminated C string, allocating memory using new.
static const char* CloneCString(const char* a_c_string); static const char* CloneCString(const char* a_c_string);
+4 -4
View File
@@ -79,7 +79,7 @@ const char kHelloString[] = "Hello, world!";
// Tests the c'tor that accepts a C string. // Tests the c'tor that accepts a C string.
TEST(MyString, ConstructorFromCString) { TEST(MyString, ConstructorFromCString) {
const MyString s(kHelloString); const MyString s(kHelloString);
EXPECT_TRUE(strcmp(s.c_string(), kHelloString) == 0); EXPECT_EQ(0, strcmp(s.c_string(), kHelloString));
EXPECT_EQ(sizeof(kHelloString)/sizeof(kHelloString[0]) - 1, EXPECT_EQ(sizeof(kHelloString)/sizeof(kHelloString[0]) - 1,
s.Length()); s.Length());
} }
@@ -88,7 +88,7 @@ TEST(MyString, ConstructorFromCString) {
TEST(MyString, CopyConstructor) { TEST(MyString, CopyConstructor) {
const MyString s1(kHelloString); const MyString s1(kHelloString);
const MyString s2 = s1; const MyString s2 = s1;
EXPECT_TRUE(strcmp(s2.c_string(), kHelloString) == 0); EXPECT_EQ(0, strcmp(s2.c_string(), kHelloString));
} }
// Tests the Set method. // Tests the Set method.
@@ -96,12 +96,12 @@ TEST(MyString, Set) {
MyString s; MyString s;
s.Set(kHelloString); s.Set(kHelloString);
EXPECT_TRUE(strcmp(s.c_string(), kHelloString) == 0); EXPECT_EQ(0, strcmp(s.c_string(), kHelloString));
// Set should work when the input pointer is the same as the one // Set should work when the input pointer is the same as the one
// already in the MyString object. // already in the MyString object.
s.Set(s.c_string()); s.Set(s.c_string());
EXPECT_TRUE(strcmp(s.c_string(), kHelloString) == 0); EXPECT_EQ(0, strcmp(s.c_string(), kHelloString));
// Can we set the MyString to NULL? // Can we set the MyString to NULL?
s.Set(NULL); s.Set(NULL);
+3 -4
View File
@@ -60,7 +60,7 @@ class QueueNode {
private: private:
// Creates a node with a given element value. The next pointer is // Creates a node with a given element value. The next pointer is
// set to NULL. // set to NULL.
QueueNode(const E& an_element) : element_(an_element), next_(NULL) {} explicit QueueNode(const E& an_element) : element_(an_element), next_(NULL) {}
// We disable the default assignment operator and copy c'tor. // We disable the default assignment operator and copy c'tor.
const QueueNode& operator = (const QueueNode&); const QueueNode& operator = (const QueueNode&);
@@ -72,8 +72,7 @@ class QueueNode {
template <typename E> // E is the element type. template <typename E> // E is the element type.
class Queue { class Queue {
public: public:
// Creates an empty queue. // Creates an empty queue.
Queue() : head_(NULL), last_(NULL), size_(0) {} Queue() : head_(NULL), last_(NULL), size_(0) {}
@@ -168,6 +167,6 @@ public:
// We disallow copying a queue. // We disallow copying a queue.
Queue(const Queue&); Queue(const Queue&);
const Queue& operator = (const Queue&); const Queue& operator = (const Queue&);
}; };
#endif // GTEST_SAMPLES_SAMPLE3_INL_H_ #endif // GTEST_SAMPLES_SAMPLE3_INL_H_
+8 -8
View File
@@ -101,7 +101,7 @@ TEST_F(IntegerFunctionTest, Factorial) {
// Tests factorial of negative numbers. // Tests factorial of negative numbers.
EXPECT_EQ(1, Factorial(-5)); EXPECT_EQ(1, Factorial(-5));
EXPECT_EQ(1, Factorial(-1)); EXPECT_EQ(1, Factorial(-1));
EXPECT_TRUE(Factorial(-10) > 0); EXPECT_GT(Factorial(-10), 0);
// Tests factorial of 0. // Tests factorial of 0.
EXPECT_EQ(1, Factorial(0)); EXPECT_EQ(1, Factorial(0));
@@ -117,20 +117,20 @@ TEST_F(IntegerFunctionTest, Factorial) {
// Tests IsPrime() // Tests IsPrime()
TEST_F(IntegerFunctionTest, IsPrime) { TEST_F(IntegerFunctionTest, IsPrime) {
// Tests negative input. // Tests negative input.
EXPECT_TRUE(!IsPrime(-1)); EXPECT_FALSE(IsPrime(-1));
EXPECT_TRUE(!IsPrime(-2)); EXPECT_FALSE(IsPrime(-2));
EXPECT_TRUE(!IsPrime(INT_MIN)); EXPECT_FALSE(IsPrime(INT_MIN));
// Tests some trivial cases. // Tests some trivial cases.
EXPECT_TRUE(!IsPrime(0)); EXPECT_FALSE(IsPrime(0));
EXPECT_TRUE(!IsPrime(1)); EXPECT_FALSE(IsPrime(1));
EXPECT_TRUE(IsPrime(2)); EXPECT_TRUE(IsPrime(2));
EXPECT_TRUE(IsPrime(3)); EXPECT_TRUE(IsPrime(3));
// Tests positive input. // Tests positive input.
EXPECT_TRUE(!IsPrime(4)); EXPECT_FALSE(IsPrime(4));
EXPECT_TRUE(IsPrime(5)); EXPECT_TRUE(IsPrime(5));
EXPECT_TRUE(!IsPrime(6)); EXPECT_FALSE(IsPrime(6));
EXPECT_TRUE(IsPrime(23)); EXPECT_TRUE(IsPrime(23));
} }
+2 -2
View File
@@ -117,7 +117,7 @@ def HeaderPreamble(n):
// Makes sure this header is not included before gtest.h. // Makes sure this header is not included before gtest.h.
#ifndef GTEST_INCLUDE_GTEST_GTEST_H_ #ifndef GTEST_INCLUDE_GTEST_GTEST_H_
#error Do not include gtest_pred_impl.h directly. Include gtest.h instead. # error Do not include gtest_pred_impl.h directly. Include gtest.h instead.
#endif // GTEST_INCLUDE_GTEST_GTEST_H_ #endif // GTEST_INCLUDE_GTEST_GTEST_H_
// This header implements a family of generic predicate assertion // This header implements a family of generic predicate assertion
@@ -256,7 +256,7 @@ AssertionResult AssertPred%(n)sHelper(const char* pred_text""" % DEFS
// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT%(n)s. // Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT%(n)s.
// Don't use this in your code. // Don't use this in your code.
#define GTEST_PRED_FORMAT%(n)s_(pred_format, %(vs)s, on_failure)\\ #define GTEST_PRED_FORMAT%(n)s_(pred_format, %(vs)s, on_failure)\\
GTEST_ASSERT_(pred_format(%(vts)s, %(vs)s),\\ GTEST_ASSERT_(pred_format(%(vts)s, %(vs)s), \\
on_failure) on_failure)
// Internal macro for implementing {EXPECT|ASSERT}_PRED%(n)s. Don't use // Internal macro for implementing {EXPECT|ASSERT}_PRED%(n)s. Don't use
+1 -1
View File
@@ -209,7 +209,7 @@ if test "${this_bindir}" = "${this_bindir%${bindir}}"; then
# The path to the script doesn't end in the bindir sequence from Autoconf, # The path to the script doesn't end in the bindir sequence from Autoconf,
# assume that we are in a build tree. # assume that we are in a build tree.
build_dir=`dirname ${this_bindir}` build_dir=`dirname ${this_bindir}`
src_dir=`cd ${this_bindir}/@top_srcdir@; pwd -P` src_dir=`cd ${this_bindir}; cd @top_srcdir@; pwd -P`
# TODO(chandlerc@google.com): This is a dangerous dependency on libtool, we # TODO(chandlerc@google.com): This is a dangerous dependency on libtool, we
# should work to remove it, and/or remove libtool altogether, replacing it # should work to remove it, and/or remove libtool altogether, replacing it
+23 -15
View File
@@ -704,14 +704,14 @@ def RunCode(env, code_node, output):
RunAtomicCode(env, atomic_code, output) RunAtomicCode(env, atomic_code, output)
def IsComment(cur_line): def IsSingleLineComment(cur_line):
return '//' in cur_line return '//' in cur_line
def IsInPreprocessorDirevative(prev_lines, cur_line): def IsInPreprocessorDirective(prev_lines, cur_line):
if cur_line.lstrip().startswith('#'): if cur_line.lstrip().startswith('#'):
return True return True
return prev_lines != [] and prev_lines[-1].endswith('\\') return prev_lines and prev_lines[-1].endswith('\\')
def WrapComment(line, output): def WrapComment(line, output):
@@ -768,7 +768,7 @@ def WrapCode(line, line_concat, output):
output.append(prefix + cur_line.strip()) output.append(prefix + cur_line.strip())
def WrapPreprocessorDirevative(line, output): def WrapPreprocessorDirective(line, output):
WrapCode(line, ' \\', output) WrapCode(line, ' \\', output)
@@ -776,29 +776,37 @@ def WrapPlainCode(line, output):
WrapCode(line, '', output) WrapCode(line, '', output)
def IsHeaderGuardOrInclude(line): def IsMultiLineIWYUPragma(line):
return re.search(r'/\* IWYU pragma: ', line)
def IsHeaderGuardIncludeOrOneLineIWYUPragma(line):
return (re.match(r'^#(ifndef|define|endif\s*//)\s*[\w_]+\s*$', line) or return (re.match(r'^#(ifndef|define|endif\s*//)\s*[\w_]+\s*$', line) or
re.match(r'^#include\s', line)) re.match(r'^#include\s', line) or
# Don't break IWYU pragmas, either; that causes iwyu.py problems.
re.search(r'// IWYU pragma: ', line))
def WrapLongLine(line, output): def WrapLongLine(line, output):
line = line.rstrip() line = line.rstrip()
if len(line) <= 80: if len(line) <= 80:
output.append(line) output.append(line)
elif IsComment(line): elif IsSingleLineComment(line):
if IsHeaderGuardOrInclude(line): if IsHeaderGuardIncludeOrOneLineIWYUPragma(line):
# The style guide made an exception to allow long header guard lines # The style guide made an exception to allow long header guard lines,
# and includes. # includes and IWYU pragmas.
output.append(line) output.append(line)
else: else:
WrapComment(line, output) WrapComment(line, output)
elif IsInPreprocessorDirevative(output, line): elif IsInPreprocessorDirective(output, line):
if IsHeaderGuardOrInclude(line): if IsHeaderGuardIncludeOrOneLineIWYUPragma(line):
# The style guide made an exception to allow long header guard lines # The style guide made an exception to allow long header guard lines,
# and includes. # includes and IWYU pragmas.
output.append(line) output.append(line)
else: else:
WrapPreprocessorDirevative(line, output) WrapPreprocessorDirective(line, output)
elif IsMultiLineIWYUPragma(line):
output.append(line)
else: else:
WrapPlainCode(line, output) WrapPlainCode(line, output)
+195 -85
View File
@@ -43,6 +43,11 @@
# include <errno.h> # include <errno.h>
# include <fcntl.h> # include <fcntl.h>
# include <limits.h> # include <limits.h>
# if GTEST_OS_LINUX
# include <signal.h>
# endif // GTEST_OS_LINUX
# include <stdarg.h> # include <stdarg.h>
# if GTEST_OS_WINDOWS # if GTEST_OS_WINDOWS
@@ -52,6 +57,10 @@
# include <sys/wait.h> # include <sys/wait.h>
# endif // GTEST_OS_WINDOWS # endif // GTEST_OS_WINDOWS
# if GTEST_OS_QNX
# include <spawn.h>
# endif // GTEST_OS_QNX
#endif // GTEST_HAS_DEATH_TEST #endif // GTEST_HAS_DEATH_TEST
#include "gtest/gtest-message.h" #include "gtest/gtest-message.h"
@@ -100,13 +109,42 @@ GTEST_DEFINE_string_(
"Indicates the file, line number, temporal index of " "Indicates the file, line number, temporal index of "
"the single death test to run, and a file descriptor to " "the single death test to run, and a file descriptor to "
"which a success code may be sent, all separated by " "which a success code may be sent, all separated by "
"colons. This flag is specified if and only if the current " "the '|' characters. This flag is specified if and only if the current "
"process is a sub-process launched for running a thread-safe " "process is a sub-process launched for running a thread-safe "
"death test. FOR INTERNAL USE ONLY."); "death test. FOR INTERNAL USE ONLY.");
} // namespace internal } // namespace internal
#if GTEST_HAS_DEATH_TEST #if GTEST_HAS_DEATH_TEST
namespace internal {
// Valid only for fast death tests. Indicates the code is running in the
// child process of a fast style death test.
static bool g_in_fast_death_test_child = false;
// Returns a Boolean value indicating whether the caller is currently
// executing in the context of the death test child process. Tools such as
// Valgrind heap checkers may need this to modify their behavior in death
// tests. IMPORTANT: This is an internal utility. Using it may break the
// implementation of death tests. User code MUST NOT use it.
bool InDeathTestChild() {
# if GTEST_OS_WINDOWS
// On Windows, death tests are thread-safe regardless of the value of the
// death_test_style flag.
return !GTEST_FLAG(internal_run_death_test).empty();
# else
if (GTEST_FLAG(death_test_style) == "threadsafe")
return !GTEST_FLAG(internal_run_death_test).empty();
else
return g_in_fast_death_test_child;
#endif
}
} // namespace internal
// ExitedWithCode constructor. // ExitedWithCode constructor.
ExitedWithCode::ExitedWithCode(int exit_code) : exit_code_(exit_code) { ExitedWithCode::ExitedWithCode(int exit_code) : exit_code_(exit_code) {
} }
@@ -141,7 +179,7 @@ namespace internal {
// Generates a textual description of a given exit code, in the format // Generates a textual description of a given exit code, in the format
// specified by wait(2). // specified by wait(2).
static String ExitSummary(int exit_code) { static std::string ExitSummary(int exit_code) {
Message m; Message m;
# if GTEST_OS_WINDOWS # if GTEST_OS_WINDOWS
@@ -176,7 +214,7 @@ bool ExitedUnsuccessfully(int exit_status) {
// one thread running, or cannot determine the number of threads, prior // one thread running, or cannot determine the number of threads, prior
// to executing the given statement. It is the responsibility of the // to executing the given statement. It is the responsibility of the
// caller not to pass a thread_count of 1. // caller not to pass a thread_count of 1.
static String DeathTestThreadWarning(size_t thread_count) { static std::string DeathTestThreadWarning(size_t thread_count) {
Message msg; Message msg;
msg << "Death tests use fork(), which is unsafe particularly" msg << "Death tests use fork(), which is unsafe particularly"
<< " in a threaded context. For this test, " << GTEST_NAME_ << " "; << " in a threaded context. For this test, " << GTEST_NAME_ << " ";
@@ -210,7 +248,7 @@ enum DeathTestOutcome { IN_PROGRESS, DIED, LIVED, RETURNED, THREW };
// message is propagated back to the parent process. Otherwise, the // message is propagated back to the parent process. Otherwise, the
// message is simply printed to stderr. In either case, the program // message is simply printed to stderr. In either case, the program
// then exits with status 1. // then exits with status 1.
void DeathTestAbort(const String& message) { void DeathTestAbort(const std::string& message) {
// On a POSIX system, this function may be called from a threadsafe-style // On a POSIX system, this function may be called from a threadsafe-style
// death test child process, which operates on a very small stack. Use // death test child process, which operates on a very small stack. Use
// the heap for any additional non-minuscule memory requirements. // the heap for any additional non-minuscule memory requirements.
@@ -234,9 +272,10 @@ void DeathTestAbort(const String& message) {
# define GTEST_DEATH_TEST_CHECK_(expression) \ # define GTEST_DEATH_TEST_CHECK_(expression) \
do { \ do { \
if (!::testing::internal::IsTrue(expression)) { \ if (!::testing::internal::IsTrue(expression)) { \
DeathTestAbort(::testing::internal::String::Format( \ DeathTestAbort( \
"CHECK failed: File %s, line %d: %s", \ ::std::string("CHECK failed: File ") + __FILE__ + ", line " \
__FILE__, __LINE__, #expression)); \ + ::testing::internal::StreamableToString(__LINE__) + ": " \
+ #expression); \
} \ } \
} while (::testing::internal::AlwaysFalse()) } while (::testing::internal::AlwaysFalse())
@@ -254,15 +293,16 @@ void DeathTestAbort(const String& message) {
gtest_retval = (expression); \ gtest_retval = (expression); \
} while (gtest_retval == -1 && errno == EINTR); \ } while (gtest_retval == -1 && errno == EINTR); \
if (gtest_retval == -1) { \ if (gtest_retval == -1) { \
DeathTestAbort(::testing::internal::String::Format( \ DeathTestAbort( \
"CHECK failed: File %s, line %d: %s != -1", \ ::std::string("CHECK failed: File ") + __FILE__ + ", line " \
__FILE__, __LINE__, #expression)); \ + ::testing::internal::StreamableToString(__LINE__) + ": " \
+ #expression + " != -1"); \
} \ } \
} while (::testing::internal::AlwaysFalse()) } while (::testing::internal::AlwaysFalse())
// Returns the message describing the last system error in errno. // Returns the message describing the last system error in errno.
String GetLastErrnoDescription() { std::string GetLastErrnoDescription() {
return String(errno == 0 ? "" : posix::StrError(errno)); return errno == 0 ? "" : posix::StrError(errno);
} }
// This is called from a death test parent process to read a failure // This is called from a death test parent process to read a failure
@@ -312,11 +352,11 @@ const char* DeathTest::LastMessage() {
return last_death_test_message_.c_str(); return last_death_test_message_.c_str();
} }
void DeathTest::set_last_death_test_message(const String& message) { void DeathTest::set_last_death_test_message(const std::string& message) {
last_death_test_message_ = message; last_death_test_message_ = message;
} }
String DeathTest::last_death_test_message_; std::string DeathTest::last_death_test_message_;
// Provides cross platform implementation for some death functionality. // Provides cross platform implementation for some death functionality.
class DeathTestImpl : public DeathTest { class DeathTestImpl : public DeathTest {
@@ -491,7 +531,7 @@ bool DeathTestImpl::Passed(bool status_ok) {
if (!spawned()) if (!spawned())
return false; return false;
const String error_message = GetCapturedStderr(); const std::string error_message = GetCapturedStderr();
bool success = false; bool success = false;
Message buffer; Message buffer;
@@ -673,22 +713,19 @@ DeathTest::TestRole WindowsDeathTest::AssumeRole() {
FALSE, // The initial state is non-signalled. FALSE, // The initial state is non-signalled.
NULL)); // The even is unnamed. NULL)); // The even is unnamed.
GTEST_DEATH_TEST_CHECK_(event_handle_.Get() != NULL); GTEST_DEATH_TEST_CHECK_(event_handle_.Get() != NULL);
const String filter_flag = String::Format("--%s%s=%s.%s", const std::string filter_flag =
GTEST_FLAG_PREFIX_, kFilterFlag, std::string("--") + GTEST_FLAG_PREFIX_ + kFilterFlag + "=" +
info->test_case_name(), info->test_case_name() + "." + info->name();
info->name()); const std::string internal_flag =
const String internal_flag = String::Format( std::string("--") + GTEST_FLAG_PREFIX_ + kInternalRunDeathTestFlag +
"--%s%s=%s|%d|%d|%u|%Iu|%Iu", "=" + file_ + "|" + StreamableToString(line_) + "|" +
GTEST_FLAG_PREFIX_, StreamableToString(death_test_index) + "|" +
kInternalRunDeathTestFlag, StreamableToString(static_cast<unsigned int>(::GetCurrentProcessId())) +
file_, line_, // size_t has the same width as pointers on both 32-bit and 64-bit
death_test_index,
static_cast<unsigned int>(::GetCurrentProcessId()),
// size_t has the same with as pointers on both 32-bit and 64-bit
// Windows platforms. // Windows platforms.
// See http://msdn.microsoft.com/en-us/library/tcxf1dw6.aspx. // See http://msdn.microsoft.com/en-us/library/tcxf1dw6.aspx.
reinterpret_cast<size_t>(write_handle), "|" + StreamableToString(reinterpret_cast<size_t>(write_handle)) +
reinterpret_cast<size_t>(event_handle_.Get())); "|" + StreamableToString(reinterpret_cast<size_t>(event_handle_.Get()));
char executable_path[_MAX_PATH + 1]; // NOLINT char executable_path[_MAX_PATH + 1]; // NOLINT
GTEST_DEATH_TEST_CHECK_( GTEST_DEATH_TEST_CHECK_(
@@ -696,10 +733,9 @@ DeathTest::TestRole WindowsDeathTest::AssumeRole() {
executable_path, executable_path,
_MAX_PATH)); _MAX_PATH));
String command_line = String::Format("%s %s \"%s\"", std::string command_line =
::GetCommandLineA(), std::string(::GetCommandLineA()) + " " + filter_flag + " \"" +
filter_flag.c_str(), internal_flag + "\"";
internal_flag.c_str());
DeathTest::set_last_death_test_message(""); DeathTest::set_last_death_test_message("");
@@ -816,6 +852,7 @@ DeathTest::TestRole NoExecDeathTest::AssumeRole() {
// Event forwarding to the listeners of event listener API mush be shut // Event forwarding to the listeners of event listener API mush be shut
// down in death test subprocesses. // down in death test subprocesses.
GetUnitTestImpl()->listeners()->SuppressEventForwarding(); GetUnitTestImpl()->listeners()->SuppressEventForwarding();
g_in_fast_death_test_child = true;
return EXECUTE_TEST; return EXECUTE_TEST;
} else { } else {
GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1])); GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1]));
@@ -835,6 +872,11 @@ class ExecDeathTest : public ForkingDeathTest {
ForkingDeathTest(a_statement, a_regex), file_(file), line_(line) { } ForkingDeathTest(a_statement, a_regex), file_(file), line_(line) { }
virtual TestRole AssumeRole(); virtual TestRole AssumeRole();
private: private:
static ::std::vector<testing::internal::string>
GetArgvsForDeathTestChildProcess() {
::std::vector<testing::internal::string> args = GetInjectableArgvs();
return args;
}
// The name of the file in which the death test is located. // The name of the file in which the death test is located.
const char* const file_; const char* const file_;
// The line number on which the death test is located. // The line number on which the death test is located.
@@ -869,6 +911,7 @@ class Arguments {
char* const* Argv() { char* const* Argv() {
return &args_[0]; return &args_[0];
} }
private: private:
std::vector<char*> args_; std::vector<char*> args_;
}; };
@@ -894,6 +937,7 @@ extern "C" char** environ;
inline char** GetEnviron() { return environ; } inline char** GetEnviron() { return environ; }
# endif // GTEST_OS_MAC # endif // GTEST_OS_MAC
# if !GTEST_OS_QNX
// The main function for a threadsafe-style death test child process. // The main function for a threadsafe-style death test child process.
// This function is called in a clone()-ed process and thus must avoid // This function is called in a clone()-ed process and thus must avoid
// any potentially unsafe operations like malloc or libc functions. // any potentially unsafe operations like malloc or libc functions.
@@ -908,9 +952,8 @@ static int ExecDeathTestChildMain(void* child_arg) {
UnitTest::GetInstance()->original_working_dir(); UnitTest::GetInstance()->original_working_dir();
// We can safely call chdir() as it's a direct system call. // We can safely call chdir() as it's a direct system call.
if (chdir(original_dir) != 0) { if (chdir(original_dir) != 0) {
DeathTestAbort(String::Format("chdir(\"%s\") failed: %s", DeathTestAbort(std::string("chdir(\"") + original_dir + "\") failed: " +
original_dir, GetLastErrnoDescription());
GetLastErrnoDescription().c_str()));
return EXIT_FAILURE; return EXIT_FAILURE;
} }
@@ -920,12 +963,12 @@ static int ExecDeathTestChildMain(void* child_arg) {
// invoke the test program via a valid path that contains at least // invoke the test program via a valid path that contains at least
// one path separator. // one path separator.
execve(args->argv[0], args->argv, GetEnviron()); execve(args->argv[0], args->argv, GetEnviron());
DeathTestAbort(String::Format("execve(%s, ...) in %s failed: %s", DeathTestAbort(std::string("execve(") + args->argv[0] + ", ...) in " +
args->argv[0], original_dir + " failed: " +
original_dir, GetLastErrnoDescription());
GetLastErrnoDescription().c_str()));
return EXIT_FAILURE; return EXIT_FAILURE;
} }
# endif // !GTEST_OS_QNX
// Two utility routines that together determine the direction the stack // Two utility routines that together determine the direction the stack
// grows. // grows.
@@ -936,25 +979,75 @@ static int ExecDeathTestChildMain(void* child_arg) {
// GTEST_NO_INLINE_ is required to prevent GCC 4.6 from inlining // GTEST_NO_INLINE_ is required to prevent GCC 4.6 from inlining
// StackLowerThanAddress into StackGrowsDown, which then doesn't give // StackLowerThanAddress into StackGrowsDown, which then doesn't give
// correct answer. // correct answer.
bool StackLowerThanAddress(const void* ptr) GTEST_NO_INLINE_; void StackLowerThanAddress(const void* ptr, bool* result) GTEST_NO_INLINE_;
bool StackLowerThanAddress(const void* ptr) { void StackLowerThanAddress(const void* ptr, bool* result) {
int dummy; int dummy;
return &dummy < ptr; *result = (&dummy < ptr);
} }
bool StackGrowsDown() { bool StackGrowsDown() {
int dummy; int dummy;
return StackLowerThanAddress(&dummy); bool result;
StackLowerThanAddress(&dummy, &result);
return result;
} }
// A threadsafe implementation of fork(2) for threadsafe-style death tests // Spawns a child process with the same executable as the current process in
// that uses clone(2). It dies with an error message if anything goes // a thread-safe manner and instructs it to run the death test. The
// wrong. // implementation uses fork(2) + exec. On systems where clone(2) is
static pid_t ExecDeathTestFork(char* const* argv, int close_fd) { // available, it is used instead, being slightly more thread-safe. On QNX,
// fork supports only single-threaded environments, so this function uses
// spawn(2) there instead. The function dies with an error message if
// anything goes wrong.
static pid_t ExecDeathTestSpawnChild(char* const* argv, int close_fd) {
ExecDeathTestArgs args = { argv, close_fd }; ExecDeathTestArgs args = { argv, close_fd };
pid_t child_pid = -1; pid_t child_pid = -1;
# if GTEST_HAS_CLONE # if GTEST_OS_QNX
// Obtains the current directory and sets it to be closed in the child
// process.
const int cwd_fd = open(".", O_RDONLY);
GTEST_DEATH_TEST_CHECK_(cwd_fd != -1);
GTEST_DEATH_TEST_CHECK_SYSCALL_(fcntl(cwd_fd, F_SETFD, FD_CLOEXEC));
// We need to execute the test program in the same environment where
// it was originally invoked. Therefore we change to the original
// working directory first.
const char* const original_dir =
UnitTest::GetInstance()->original_working_dir();
// We can safely call chdir() as it's a direct system call.
if (chdir(original_dir) != 0) {
DeathTestAbort(std::string("chdir(\"") + original_dir + "\") failed: " +
GetLastErrnoDescription());
return EXIT_FAILURE;
}
int fd_flags;
// Set close_fd to be closed after spawn.
GTEST_DEATH_TEST_CHECK_SYSCALL_(fd_flags = fcntl(close_fd, F_GETFD));
GTEST_DEATH_TEST_CHECK_SYSCALL_(fcntl(close_fd, F_SETFD,
fd_flags | FD_CLOEXEC));
struct inheritance inherit = {0};
// spawn is a system call.
child_pid = spawn(args.argv[0], 0, NULL, &inherit, args.argv, GetEnviron());
// Restores the current working directory.
GTEST_DEATH_TEST_CHECK_(fchdir(cwd_fd) != -1);
GTEST_DEATH_TEST_CHECK_SYSCALL_(close(cwd_fd));
# else // GTEST_OS_QNX
# if GTEST_OS_LINUX
// When a SIGPROF signal is received while fork() or clone() are executing,
// the process may hang. To avoid this, we ignore SIGPROF here and re-enable
// it after the call to fork()/clone() is complete.
struct sigaction saved_sigprof_action;
struct sigaction ignore_sigprof_action;
memset(&ignore_sigprof_action, 0, sizeof(ignore_sigprof_action));
sigemptyset(&ignore_sigprof_action.sa_mask);
ignore_sigprof_action.sa_handler = SIG_IGN;
GTEST_DEATH_TEST_CHECK_SYSCALL_(sigaction(
SIGPROF, &ignore_sigprof_action, &saved_sigprof_action));
# endif // GTEST_OS_LINUX
# if GTEST_HAS_CLONE
const bool use_fork = GTEST_FLAG(death_test_use_fork); const bool use_fork = GTEST_FLAG(death_test_use_fork);
if (!use_fork) { if (!use_fork) {
@@ -964,21 +1057,37 @@ static pid_t ExecDeathTestFork(char* const* argv, int close_fd) {
void* const stack = mmap(NULL, stack_size, PROT_READ | PROT_WRITE, void* const stack = mmap(NULL, stack_size, PROT_READ | PROT_WRITE,
MAP_ANON | MAP_PRIVATE, -1, 0); MAP_ANON | MAP_PRIVATE, -1, 0);
GTEST_DEATH_TEST_CHECK_(stack != MAP_FAILED); GTEST_DEATH_TEST_CHECK_(stack != MAP_FAILED);
// Maximum stack alignment in bytes: For a downward-growing stack, this
// amount is subtracted from size of the stack space to get an address
// that is within the stack space and is aligned on all systems we care
// about. As far as I know there is no ABI with stack alignment greater
// than 64. We assume stack and stack_size already have alignment of
// kMaxStackAlignment.
const size_t kMaxStackAlignment = 64;
void* const stack_top = void* const stack_top =
static_cast<char*>(stack) + (stack_grows_down ? stack_size : 0); static_cast<char*>(stack) +
(stack_grows_down ? stack_size - kMaxStackAlignment : 0);
GTEST_DEATH_TEST_CHECK_(stack_size > kMaxStackAlignment &&
reinterpret_cast<intptr_t>(stack_top) % kMaxStackAlignment == 0);
child_pid = clone(&ExecDeathTestChildMain, stack_top, SIGCHLD, &args); child_pid = clone(&ExecDeathTestChildMain, stack_top, SIGCHLD, &args);
GTEST_DEATH_TEST_CHECK_(munmap(stack, stack_size) != -1); GTEST_DEATH_TEST_CHECK_(munmap(stack, stack_size) != -1);
} }
# else # else
const bool use_fork = true; const bool use_fork = true;
# endif // GTEST_HAS_CLONE # endif // GTEST_HAS_CLONE
if (use_fork && (child_pid = fork()) == 0) { if (use_fork && (child_pid = fork()) == 0) {
ExecDeathTestChildMain(&args); ExecDeathTestChildMain(&args);
_exit(0); _exit(0);
} }
# endif // GTEST_OS_QNX
# if GTEST_OS_LINUX
GTEST_DEATH_TEST_CHECK_SYSCALL_(
sigaction(SIGPROF, &saved_sigprof_action, NULL));
# endif // GTEST_OS_LINUX
GTEST_DEATH_TEST_CHECK_(child_pid != -1); GTEST_DEATH_TEST_CHECK_(child_pid != -1);
return child_pid; return child_pid;
@@ -1006,16 +1115,16 @@ DeathTest::TestRole ExecDeathTest::AssumeRole() {
// it be closed when the child process does an exec: // it be closed when the child process does an exec:
GTEST_DEATH_TEST_CHECK_(fcntl(pipe_fd[1], F_SETFD, 0) != -1); GTEST_DEATH_TEST_CHECK_(fcntl(pipe_fd[1], F_SETFD, 0) != -1);
const String filter_flag = const std::string filter_flag =
String::Format("--%s%s=%s.%s", std::string("--") + GTEST_FLAG_PREFIX_ + kFilterFlag + "="
GTEST_FLAG_PREFIX_, kFilterFlag, + info->test_case_name() + "." + info->name();
info->test_case_name(), info->name()); const std::string internal_flag =
const String internal_flag = std::string("--") + GTEST_FLAG_PREFIX_ + kInternalRunDeathTestFlag + "="
String::Format("--%s%s=%s|%d|%d|%d", + file_ + "|" + StreamableToString(line_) + "|"
GTEST_FLAG_PREFIX_, kInternalRunDeathTestFlag, + StreamableToString(death_test_index) + "|"
file_, line_, death_test_index, pipe_fd[1]); + StreamableToString(pipe_fd[1]);
Arguments args; Arguments args;
args.AddArguments(GetArgvs()); args.AddArguments(GetArgvsForDeathTestChildProcess());
args.AddArgument(filter_flag.c_str()); args.AddArgument(filter_flag.c_str());
args.AddArgument(internal_flag.c_str()); args.AddArgument(internal_flag.c_str());
@@ -1026,7 +1135,7 @@ DeathTest::TestRole ExecDeathTest::AssumeRole() {
// is necessary. // is necessary.
FlushInfoLog(); FlushInfoLog();
const pid_t child_pid = ExecDeathTestFork(args.Argv(), pipe_fd[0]); const pid_t child_pid = ExecDeathTestSpawnChild(args.Argv(), pipe_fd[0]);
GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1])); GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1]));
set_child_pid(child_pid); set_child_pid(child_pid);
set_read_fd(pipe_fd[0]); set_read_fd(pipe_fd[0]);
@@ -1052,9 +1161,10 @@ bool DefaultDeathTestFactory::Create(const char* statement, const RE* regex,
if (flag != NULL) { if (flag != NULL) {
if (death_test_index > flag->index()) { if (death_test_index > flag->index()) {
DeathTest::set_last_death_test_message(String::Format( DeathTest::set_last_death_test_message(
"Death test count (%d) somehow exceeded expected maximum (%d)", "Death test count (" + StreamableToString(death_test_index)
death_test_index, flag->index())); + ") somehow exceeded expected maximum ("
+ StreamableToString(flag->index()) + ")");
return false; return false;
} }
@@ -1083,9 +1193,9 @@ bool DefaultDeathTestFactory::Create(const char* statement, const RE* regex,
# endif // GTEST_OS_WINDOWS # endif // GTEST_OS_WINDOWS
else { // NOLINT - this is more readable than unbalanced brackets inside #if. else { // NOLINT - this is more readable than unbalanced brackets inside #if.
DeathTest::set_last_death_test_message(String::Format( DeathTest::set_last_death_test_message(
"Unknown death test style \"%s\" encountered", "Unknown death test style \"" + GTEST_FLAG(death_test_style)
GTEST_FLAG(death_test_style).c_str())); + "\" encountered");
return false; return false;
} }
@@ -1123,8 +1233,8 @@ int GetStatusFileDescriptor(unsigned int parent_process_id,
FALSE, // Non-inheritable. FALSE, // Non-inheritable.
parent_process_id)); parent_process_id));
if (parent_process_handle.Get() == INVALID_HANDLE_VALUE) { if (parent_process_handle.Get() == INVALID_HANDLE_VALUE) {
DeathTestAbort(String::Format("Unable to open parent process %u", DeathTestAbort("Unable to open parent process " +
parent_process_id)); StreamableToString(parent_process_id));
} }
// TODO(vladl@google.com): Replace the following check with a // TODO(vladl@google.com): Replace the following check with a
@@ -1144,9 +1254,10 @@ int GetStatusFileDescriptor(unsigned int parent_process_id,
// DUPLICATE_SAME_ACCESS is used. // DUPLICATE_SAME_ACCESS is used.
FALSE, // Request non-inheritable handler. FALSE, // Request non-inheritable handler.
DUPLICATE_SAME_ACCESS)) { DUPLICATE_SAME_ACCESS)) {
DeathTestAbort(String::Format( DeathTestAbort("Unable to duplicate the pipe handle " +
"Unable to duplicate the pipe handle %Iu from the parent process %u", StreamableToString(write_handle_as_size_t) +
write_handle_as_size_t, parent_process_id)); " from the parent process " +
StreamableToString(parent_process_id));
} }
const HANDLE event_handle = reinterpret_cast<HANDLE>(event_handle_as_size_t); const HANDLE event_handle = reinterpret_cast<HANDLE>(event_handle_as_size_t);
@@ -1157,17 +1268,18 @@ int GetStatusFileDescriptor(unsigned int parent_process_id,
0x0, 0x0,
FALSE, FALSE,
DUPLICATE_SAME_ACCESS)) { DUPLICATE_SAME_ACCESS)) {
DeathTestAbort(String::Format( DeathTestAbort("Unable to duplicate the event handle " +
"Unable to duplicate the event handle %Iu from the parent process %u", StreamableToString(event_handle_as_size_t) +
event_handle_as_size_t, parent_process_id)); " from the parent process " +
StreamableToString(parent_process_id));
} }
const int write_fd = const int write_fd =
::_open_osfhandle(reinterpret_cast<intptr_t>(dup_write_handle), O_APPEND); ::_open_osfhandle(reinterpret_cast<intptr_t>(dup_write_handle), O_APPEND);
if (write_fd == -1) { if (write_fd == -1) {
DeathTestAbort(String::Format( DeathTestAbort("Unable to convert pipe handle " +
"Unable to convert pipe handle %Iu to a file descriptor", StreamableToString(write_handle_as_size_t) +
write_handle_as_size_t)); " to a file descriptor");
} }
// Signals the parent that the write end of the pipe has been acquired // Signals the parent that the write end of the pipe has been acquired
@@ -1204,9 +1316,8 @@ InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag() {
|| !ParseNaturalNumber(fields[3], &parent_process_id) || !ParseNaturalNumber(fields[3], &parent_process_id)
|| !ParseNaturalNumber(fields[4], &write_handle_as_size_t) || !ParseNaturalNumber(fields[4], &write_handle_as_size_t)
|| !ParseNaturalNumber(fields[5], &event_handle_as_size_t)) { || !ParseNaturalNumber(fields[5], &event_handle_as_size_t)) {
DeathTestAbort(String::Format( DeathTestAbort("Bad --gtest_internal_run_death_test flag: " +
"Bad --gtest_internal_run_death_test flag: %s", GTEST_FLAG(internal_run_death_test));
GTEST_FLAG(internal_run_death_test).c_str()));
} }
write_fd = GetStatusFileDescriptor(parent_process_id, write_fd = GetStatusFileDescriptor(parent_process_id,
write_handle_as_size_t, write_handle_as_size_t,
@@ -1217,9 +1328,8 @@ InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag() {
|| !ParseNaturalNumber(fields[1], &line) || !ParseNaturalNumber(fields[1], &line)
|| !ParseNaturalNumber(fields[2], &index) || !ParseNaturalNumber(fields[2], &index)
|| !ParseNaturalNumber(fields[3], &write_fd)) { || !ParseNaturalNumber(fields[3], &write_fd)) {
DeathTestAbort(String::Format( DeathTestAbort("Bad --gtest_internal_run_death_test flag: "
"Bad --gtest_internal_run_death_test flag: %s", + GTEST_FLAG(internal_run_death_test));
GTEST_FLAG(internal_run_death_test).c_str()));
} }
# endif // GTEST_OS_WINDOWS # endif // GTEST_OS_WINDOWS
+16 -14
View File
@@ -29,6 +29,7 @@
// //
// Authors: keith.ray@gmail.com (Keith Ray) // Authors: keith.ray@gmail.com (Keith Ray)
#include "gtest/gtest-message.h"
#include "gtest/internal/gtest-filepath.h" #include "gtest/internal/gtest-filepath.h"
#include "gtest/internal/gtest-port.h" #include "gtest/internal/gtest-port.h"
@@ -39,8 +40,8 @@
#elif GTEST_OS_WINDOWS #elif GTEST_OS_WINDOWS
# include <direct.h> # include <direct.h>
# include <io.h> # include <io.h>
#elif GTEST_OS_SYMBIAN || GTEST_OS_NACL #elif GTEST_OS_SYMBIAN
// Symbian OpenC and NaCl have PATH_MAX in sys/syslimits.h // Symbian OpenC has PATH_MAX in sys/syslimits.h
# include <sys/syslimits.h> # include <sys/syslimits.h>
#else #else
# include <limits.h> # include <limits.h>
@@ -116,9 +117,10 @@ FilePath FilePath::GetCurrentDir() {
// FilePath("dir/file"). If a case-insensitive extension is not // FilePath("dir/file"). If a case-insensitive extension is not
// found, returns a copy of the original FilePath. // found, returns a copy of the original FilePath.
FilePath FilePath::RemoveExtension(const char* extension) const { FilePath FilePath::RemoveExtension(const char* extension) const {
String dot_extension(String::Format(".%s", extension)); const std::string dot_extension = std::string(".") + extension;
if (pathname_.EndsWithCaseInsensitive(dot_extension.c_str())) { if (String::EndsWithCaseInsensitive(pathname_, dot_extension)) {
return FilePath(String(pathname_.c_str(), pathname_.length() - 4)); return FilePath(pathname_.substr(
0, pathname_.length() - dot_extension.length()));
} }
return *this; return *this;
} }
@@ -147,7 +149,7 @@ const char* FilePath::FindLastPathSeparator() const {
// On Windows platform, '\' is the path separator, otherwise it is '/'. // On Windows platform, '\' is the path separator, otherwise it is '/'.
FilePath FilePath::RemoveDirectoryName() const { FilePath FilePath::RemoveDirectoryName() const {
const char* const last_sep = FindLastPathSeparator(); const char* const last_sep = FindLastPathSeparator();
return last_sep ? FilePath(String(last_sep + 1)) : *this; return last_sep ? FilePath(last_sep + 1) : *this;
} }
// RemoveFileName returns the directory path with the filename removed. // RemoveFileName returns the directory path with the filename removed.
@@ -158,9 +160,9 @@ FilePath FilePath::RemoveDirectoryName() const {
// On Windows platform, '\' is the path separator, otherwise it is '/'. // On Windows platform, '\' is the path separator, otherwise it is '/'.
FilePath FilePath::RemoveFileName() const { FilePath FilePath::RemoveFileName() const {
const char* const last_sep = FindLastPathSeparator(); const char* const last_sep = FindLastPathSeparator();
String dir; std::string dir;
if (last_sep) { if (last_sep) {
dir = String(c_str(), last_sep + 1 - c_str()); dir = std::string(c_str(), last_sep + 1 - c_str());
} else { } else {
dir = kCurrentDirectoryString; dir = kCurrentDirectoryString;
} }
@@ -177,11 +179,12 @@ FilePath FilePath::MakeFileName(const FilePath& directory,
const FilePath& base_name, const FilePath& base_name,
int number, int number,
const char* extension) { const char* extension) {
String file; std::string file;
if (number == 0) { if (number == 0) {
file = String::Format("%s.%s", base_name.c_str(), extension); file = base_name.string() + "." + extension;
} else { } else {
file = String::Format("%s_%d.%s", base_name.c_str(), number, extension); file = base_name.string() + "_" + StreamableToString(number)
+ "." + extension;
} }
return ConcatPaths(directory, FilePath(file)); return ConcatPaths(directory, FilePath(file));
} }
@@ -193,8 +196,7 @@ FilePath FilePath::ConcatPaths(const FilePath& directory,
if (directory.IsEmpty()) if (directory.IsEmpty())
return relative_path; return relative_path;
const FilePath dir(directory.RemoveTrailingPathSeparator()); const FilePath dir(directory.RemoveTrailingPathSeparator());
return FilePath(String::Format("%s%c%s", dir.c_str(), kPathSeparator, return FilePath(dir.string() + kPathSeparator + relative_path.string());
relative_path.c_str()));
} }
// Returns true if pathname describes something findable in the file-system, // Returns true if pathname describes something findable in the file-system,
@@ -338,7 +340,7 @@ bool FilePath::CreateFolder() const {
// On Windows platform, uses \ as the separator, other platforms use /. // On Windows platform, uses \ as the separator, other platforms use /.
FilePath FilePath::RemoveTrailingPathSeparator() const { FilePath FilePath::RemoveTrailingPathSeparator() const {
return IsDirectory() return IsDirectory()
? FilePath(String(pathname_.c_str(), pathname_.length() - 1)) ? FilePath(pathname_.substr(0, pathname_.length() - 1))
: *this; : *this;
} }
+211 -31
View File
@@ -58,6 +58,11 @@
#include "gtest/internal/gtest-port.h" #include "gtest/internal/gtest-port.h"
#if GTEST_CAN_STREAM_RESULTS_
# include <arpa/inet.h> // NOLINT
# include <netdb.h> // NOLINT
#endif
#if GTEST_OS_WINDOWS #if GTEST_OS_WINDOWS
# include <windows.h> // NOLINT # include <windows.h> // NOLINT
#endif // GTEST_OS_WINDOWS #endif // GTEST_OS_WINDOWS
@@ -112,6 +117,12 @@ GTEST_API_ bool ShouldUseColor(bool stdout_is_tty);
// Formats the given time in milliseconds as seconds. // Formats the given time in milliseconds as seconds.
GTEST_API_ std::string FormatTimeInMillisAsSeconds(TimeInMillis ms); GTEST_API_ std::string FormatTimeInMillisAsSeconds(TimeInMillis ms);
// Converts the given time in milliseconds to a date string in the ISO 8601
// format, without the timezone information. N.B.: due to the use the
// non-reentrant localtime() function, this function is not thread safe. Do
// not use it in any code that can be called from multiple threads.
GTEST_API_ std::string FormatEpochTimeInMillisAsIso8601(TimeInMillis ms);
// Parses a string for an Int32 flag, in the form of "--flag=value". // Parses a string for an Int32 flag, in the form of "--flag=value".
// //
// On success, stores the value of the flag in *value, and returns // On success, stores the value of the flag in *value, and returns
@@ -190,37 +201,35 @@ class GTestFlagSaver {
GTEST_FLAG(stream_result_to) = stream_result_to_; GTEST_FLAG(stream_result_to) = stream_result_to_;
GTEST_FLAG(throw_on_failure) = throw_on_failure_; GTEST_FLAG(throw_on_failure) = throw_on_failure_;
} }
private: private:
// Fields for saving the original values of flags. // Fields for saving the original values of flags.
bool also_run_disabled_tests_; bool also_run_disabled_tests_;
bool break_on_failure_; bool break_on_failure_;
bool catch_exceptions_; bool catch_exceptions_;
String color_; std::string color_;
String death_test_style_; std::string death_test_style_;
bool death_test_use_fork_; bool death_test_use_fork_;
String filter_; std::string filter_;
String internal_run_death_test_; std::string internal_run_death_test_;
bool list_tests_; bool list_tests_;
String output_; std::string output_;
bool print_time_; bool print_time_;
bool pretty_;
internal::Int32 random_seed_; internal::Int32 random_seed_;
internal::Int32 repeat_; internal::Int32 repeat_;
bool shuffle_; bool shuffle_;
internal::Int32 stack_trace_depth_; internal::Int32 stack_trace_depth_;
String stream_result_to_; std::string stream_result_to_;
bool throw_on_failure_; bool throw_on_failure_;
} GTEST_ATTRIBUTE_UNUSED_; } GTEST_ATTRIBUTE_UNUSED_;
// Converts a Unicode code point to a narrow string in UTF-8 encoding. // Converts a Unicode code point to a narrow string in UTF-8 encoding.
// code_point parameter is of type UInt32 because wchar_t may not be // code_point parameter is of type UInt32 because wchar_t may not be
// wide enough to contain a code point. // wide enough to contain a code point.
// The output buffer str must containt at least 32 characters.
// The function returns the address of the output buffer.
// If the code_point is not a valid Unicode code point // If the code_point is not a valid Unicode code point
// (i.e. outside of Unicode range U+0 to U+10FFFF) it will be output // (i.e. outside of Unicode range U+0 to U+10FFFF) it will be converted
// as '(Invalid Unicode 0xXXXXXXXX)'. // to "(Invalid Unicode 0xXXXXXXXX)".
GTEST_API_ char* CodePointToUtf8(UInt32 code_point, char* str); GTEST_API_ std::string CodePointToUtf8(UInt32 code_point);
// Converts a wide string to a narrow string in UTF-8 encoding. // Converts a wide string to a narrow string in UTF-8 encoding.
// The wide string is assumed to have the following encoding: // The wide string is assumed to have the following encoding:
@@ -235,7 +244,7 @@ GTEST_API_ char* CodePointToUtf8(UInt32 code_point, char* str);
// as '(Invalid Unicode 0xXXXXXXXX)'. If the string is in UTF16 encoding // as '(Invalid Unicode 0xXXXXXXXX)'. If the string is in UTF16 encoding
// and contains invalid UTF-16 surrogate pairs, values in those pairs // and contains invalid UTF-16 surrogate pairs, values in those pairs
// will be encoded as individual Unicode characters from Basic Normal Plane. // will be encoded as individual Unicode characters from Basic Normal Plane.
GTEST_API_ String WideStringToUtf8(const wchar_t* str, int num_chars); GTEST_API_ std::string WideStringToUtf8(const wchar_t* str, int num_chars);
// Reads the GTEST_SHARD_STATUS_FILE environment variable, and creates the file // Reads the GTEST_SHARD_STATUS_FILE environment variable, and creates the file
// if the variable is present. If a file already exists at this location, this // if the variable is present. If a file already exists at this location, this
@@ -339,16 +348,15 @@ class TestPropertyKeyIs {
// Constructor. // Constructor.
// //
// TestPropertyKeyIs has NO default constructor. // TestPropertyKeyIs has NO default constructor.
explicit TestPropertyKeyIs(const char* key) explicit TestPropertyKeyIs(const std::string& key) : key_(key) {}
: key_(key) {}
// Returns true iff the test name of test property matches on key_. // Returns true iff the test name of test property matches on key_.
bool operator()(const TestProperty& test_property) const { bool operator()(const TestProperty& test_property) const {
return String(test_property.key()).Compare(key_) == 0; return test_property.key() == key_;
} }
private: private:
String key_; std::string key_;
}; };
// Class UnitTestOptions. // Class UnitTestOptions.
@@ -366,12 +374,12 @@ class GTEST_API_ UnitTestOptions {
// Functions for processing the gtest_output flag. // Functions for processing the gtest_output flag.
// Returns the output format, or "" for normal printed output. // Returns the output format, or "" for normal printed output.
static String GetOutputFormat(); static std::string GetOutputFormat();
// Returns the absolute path of the requested output file, or the // Returns the absolute path of the requested output file, or the
// default (test_detail.xml in the original working directory) if // default (test_detail.xml in the original working directory) if
// none was explicitly specified. // none was explicitly specified.
static String GetAbsolutePathToOutputFile(); static std::string GetAbsolutePathToOutputFile();
// Functions for processing the gtest_filter flag. // Functions for processing the gtest_filter flag.
@@ -384,8 +392,8 @@ class GTEST_API_ UnitTestOptions {
// Returns true iff the user-specified filter matches the test case // Returns true iff the user-specified filter matches the test case
// name and the test name. // name and the test name.
static bool FilterMatchesTest(const String &test_case_name, static bool FilterMatchesTest(const std::string &test_case_name,
const String &test_name); const std::string &test_name);
#if GTEST_OS_WINDOWS #if GTEST_OS_WINDOWS
// Function for supporting the gtest_catch_exception flag. // Function for supporting the gtest_catch_exception flag.
@@ -398,7 +406,7 @@ class GTEST_API_ UnitTestOptions {
// Returns true if "name" matches the ':' separated list of glob-style // Returns true if "name" matches the ':' separated list of glob-style
// filters in "filter". // filters in "filter".
static bool MatchesFilter(const String& name, const char* filter); static bool MatchesFilter(const std::string& name, const char* filter);
}; };
// Returns the current application's name, removing directory path if that // Returns the current application's name, removing directory path if that
@@ -411,13 +419,13 @@ class OsStackTraceGetterInterface {
OsStackTraceGetterInterface() {} OsStackTraceGetterInterface() {}
virtual ~OsStackTraceGetterInterface() {} virtual ~OsStackTraceGetterInterface() {}
// Returns the current OS stack trace as a String. Parameters: // Returns the current OS stack trace as an std::string. Parameters:
// //
// max_depth - the maximum number of stack frames to be included // max_depth - the maximum number of stack frames to be included
// in the trace. // in the trace.
// skip_count - the number of top frames to be skipped; doesn't count // skip_count - the number of top frames to be skipped; doesn't count
// against max_depth. // against max_depth.
virtual String CurrentStackTrace(int max_depth, int skip_count) = 0; virtual string CurrentStackTrace(int max_depth, int skip_count) = 0;
// UponLeavingGTest() should be called immediately before Google Test calls // UponLeavingGTest() should be called immediately before Google Test calls
// user code. It saves some information about the current stack that // user code. It saves some information about the current stack that
@@ -432,8 +440,11 @@ class OsStackTraceGetterInterface {
class OsStackTraceGetter : public OsStackTraceGetterInterface { class OsStackTraceGetter : public OsStackTraceGetterInterface {
public: public:
OsStackTraceGetter() : caller_frame_(NULL) {} OsStackTraceGetter() : caller_frame_(NULL) {}
virtual String CurrentStackTrace(int max_depth, int skip_count);
virtual void UponLeavingGTest(); virtual string CurrentStackTrace(int max_depth, int skip_count)
GTEST_LOCK_EXCLUDED_(mutex_);
virtual void UponLeavingGTest() GTEST_LOCK_EXCLUDED_(mutex_);
// This string is inserted in place of stack frames that are part of // This string is inserted in place of stack frames that are part of
// Google Test's implementation. // Google Test's implementation.
@@ -455,7 +466,7 @@ class OsStackTraceGetter : public OsStackTraceGetterInterface {
struct TraceInfo { struct TraceInfo {
const char* file; const char* file;
int line; int line;
String message; std::string message;
}; };
// This is the default global test part result reporter used in UnitTestImpl. // This is the default global test part result reporter used in UnitTestImpl.
@@ -539,15 +550,25 @@ class GTEST_API_ UnitTestImpl {
// Gets the number of failed tests. // Gets the number of failed tests.
int failed_test_count() const; int failed_test_count() const;
// Gets the number of disabled tests that will be reported in the XML report.
int reportable_disabled_test_count() const;
// Gets the number of disabled tests. // Gets the number of disabled tests.
int disabled_test_count() const; int disabled_test_count() const;
// Gets the number of tests to be printed in the XML report.
int reportable_test_count() const;
// Gets the number of all tests. // Gets the number of all tests.
int total_test_count() const; int total_test_count() const;
// Gets the number of tests that should run. // Gets the number of tests that should run.
int test_to_run_count() const; int test_to_run_count() const;
// Gets the time of the test program start, in ms from the start of the
// UNIX epoch.
TimeInMillis start_timestamp() const { return start_timestamp_; }
// Gets the elapsed time, in milliseconds. // Gets the elapsed time, in milliseconds.
TimeInMillis elapsed_time() const { return elapsed_time_; } TimeInMillis elapsed_time() const { return elapsed_time_; }
@@ -596,7 +617,7 @@ class GTEST_API_ UnitTestImpl {
// getter, and returns it. // getter, and returns it.
OsStackTraceGetterInterface* os_stack_trace_getter(); OsStackTraceGetterInterface* os_stack_trace_getter();
// Returns the current OS stack trace as a String. // Returns the current OS stack trace as an std::string.
// //
// The maximum number of stack frames to be included is specified by // The maximum number of stack frames to be included is specified by
// the gtest_stack_trace_depth flag. The skip_count parameter // the gtest_stack_trace_depth flag. The skip_count parameter
@@ -606,7 +627,7 @@ class GTEST_API_ UnitTestImpl {
// For example, if Foo() calls Bar(), which in turn calls // For example, if Foo() calls Bar(), which in turn calls
// CurrentOsStackTraceExceptTop(1), Foo() will be included in the // CurrentOsStackTraceExceptTop(1), Foo() will be included in the
// trace but Bar() and CurrentOsStackTraceExceptTop() won't. // trace but Bar() and CurrentOsStackTraceExceptTop() won't.
String CurrentOsStackTraceExceptTop(int skip_count); std::string CurrentOsStackTraceExceptTop(int skip_count) GTEST_NO_INLINE_;
// Finds and returns a TestCase with the given name. If one doesn't // Finds and returns a TestCase with the given name. If one doesn't
// exist, creates one and returns it. // exist, creates one and returns it.
@@ -696,6 +717,12 @@ class GTEST_API_ UnitTestImpl {
ad_hoc_test_result_.Clear(); ad_hoc_test_result_.Clear();
} }
// Adds a TestProperty to the current TestResult object when invoked in a
// context of a test or a test case, or to the global property set. If the
// result already contains a property with the same key, the value will be
// updated.
void RecordProperty(const TestProperty& test_property);
enum ReactionToSharding { enum ReactionToSharding {
HONOR_SHARDING_PROTOCOL, HONOR_SHARDING_PROTOCOL,
IGNORE_SHARDING_PROTOCOL IGNORE_SHARDING_PROTOCOL
@@ -880,6 +907,10 @@ class GTEST_API_ UnitTestImpl {
// Our random number generator. // Our random number generator.
internal::Random random_; internal::Random random_;
// The time of the test program start, in ms from the start of the
// UNIX epoch.
TimeInMillis start_timestamp_;
// How long the test took to run, in milliseconds. // How long the test took to run, in milliseconds.
TimeInMillis elapsed_time_; TimeInMillis elapsed_time_;
@@ -935,7 +966,7 @@ GTEST_API_ void ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv);
// Returns the message describing the last system error, regardless of the // Returns the message describing the last system error, regardless of the
// platform. // platform.
GTEST_API_ String GetLastErrnoDescription(); GTEST_API_ std::string GetLastErrnoDescription();
# if GTEST_OS_WINDOWS # if GTEST_OS_WINDOWS
// Provides leak-safe Windows kernel handle ownership. // Provides leak-safe Windows kernel handle ownership.
@@ -1018,8 +1049,9 @@ bool ParseNaturalNumber(const ::std::string& str, Integer* number) {
class TestResultAccessor { class TestResultAccessor {
public: public:
static void RecordProperty(TestResult* test_result, static void RecordProperty(TestResult* test_result,
const std::string& xml_element,
const TestProperty& property) { const TestProperty& property) {
test_result->RecordProperty(property); test_result->RecordProperty(xml_element, property);
} }
static void ClearTestPartResults(TestResult* test_result) { static void ClearTestPartResults(TestResult* test_result) {
@@ -1032,6 +1064,154 @@ class TestResultAccessor {
} }
}; };
#if GTEST_CAN_STREAM_RESULTS_
// Streams test results to the given port on the given host machine.
class StreamingListener : public EmptyTestEventListener {
public:
// Abstract base class for writing strings to a socket.
class AbstractSocketWriter {
public:
virtual ~AbstractSocketWriter() {}
// Sends a string to the socket.
virtual void Send(const string& message) = 0;
// Closes the socket.
virtual void CloseConnection() {}
// Sends a string and a newline to the socket.
void SendLn(const string& message) {
Send(message + "\n");
}
};
// Concrete class for actually writing strings to a socket.
class SocketWriter : public AbstractSocketWriter {
public:
SocketWriter(const string& host, const string& port)
: sockfd_(-1), host_name_(host), port_num_(port) {
MakeConnection();
}
virtual ~SocketWriter() {
if (sockfd_ != -1)
CloseConnection();
}
// Sends a string to the socket.
virtual void Send(const string& message) {
GTEST_CHECK_(sockfd_ != -1)
<< "Send() can be called only when there is a connection.";
const int len = static_cast<int>(message.length());
if (write(sockfd_, message.c_str(), len) != len) {
GTEST_LOG_(WARNING)
<< "stream_result_to: failed to stream to "
<< host_name_ << ":" << port_num_;
}
}
private:
// Creates a client socket and connects to the server.
void MakeConnection();
// Closes the socket.
void CloseConnection() {
GTEST_CHECK_(sockfd_ != -1)
<< "CloseConnection() can be called only when there is a connection.";
close(sockfd_);
sockfd_ = -1;
}
int sockfd_; // socket file descriptor
const string host_name_;
const string port_num_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(SocketWriter);
}; // class SocketWriter
// Escapes '=', '&', '%', and '\n' characters in str as "%xx".
static string UrlEncode(const char* str);
StreamingListener(const string& host, const string& port)
: socket_writer_(new SocketWriter(host, port)) { Start(); }
explicit StreamingListener(AbstractSocketWriter* socket_writer)
: socket_writer_(socket_writer) { Start(); }
void OnTestProgramStart(const UnitTest& /* unit_test */) {
SendLn("event=TestProgramStart");
}
void OnTestProgramEnd(const UnitTest& unit_test) {
// Note that Google Test current only report elapsed time for each
// test iteration, not for the entire test program.
SendLn("event=TestProgramEnd&passed=" + FormatBool(unit_test.Passed()));
// Notify the streaming server to stop.
socket_writer_->CloseConnection();
}
void OnTestIterationStart(const UnitTest& /* unit_test */, int iteration) {
SendLn("event=TestIterationStart&iteration=" +
StreamableToString(iteration));
}
void OnTestIterationEnd(const UnitTest& unit_test, int /* iteration */) {
SendLn("event=TestIterationEnd&passed=" +
FormatBool(unit_test.Passed()) + "&elapsed_time=" +
StreamableToString(unit_test.elapsed_time()) + "ms");
}
void OnTestCaseStart(const TestCase& test_case) {
SendLn(std::string("event=TestCaseStart&name=") + test_case.name());
}
void OnTestCaseEnd(const TestCase& test_case) {
SendLn("event=TestCaseEnd&passed=" + FormatBool(test_case.Passed())
+ "&elapsed_time=" + StreamableToString(test_case.elapsed_time())
+ "ms");
}
void OnTestStart(const TestInfo& test_info) {
SendLn(std::string("event=TestStart&name=") + test_info.name());
}
void OnTestEnd(const TestInfo& test_info) {
SendLn("event=TestEnd&passed=" +
FormatBool((test_info.result())->Passed()) +
"&elapsed_time=" +
StreamableToString((test_info.result())->elapsed_time()) + "ms");
}
void OnTestPartResult(const TestPartResult& test_part_result) {
const char* file_name = test_part_result.file_name();
if (file_name == NULL)
file_name = "";
SendLn("event=TestPartResult&file=" + UrlEncode(file_name) +
"&line=" + StreamableToString(test_part_result.line_number()) +
"&message=" + UrlEncode(test_part_result.message()));
}
private:
// Sends the given message and a newline to the socket.
void SendLn(const string& message) { socket_writer_->SendLn(message); }
// Called at the start of streaming to notify the receiver what
// protocol we are using.
void Start() { SendLn("gtest_streaming_protocol_version=1.0"); }
string FormatBool(bool value) { return value ? "1" : "0"; }
const scoped_ptr<AbstractSocketWriter> socket_writer_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(StreamingListener);
}; // class StreamingListener
#endif // GTEST_CAN_STREAM_RESULTS_
} // namespace internal } // namespace internal
} // namespace testing } // namespace testing
+89 -30
View File
@@ -51,6 +51,11 @@
# include <mach/vm_map.h> # include <mach/vm_map.h>
#endif // GTEST_OS_MAC #endif // GTEST_OS_MAC
#if GTEST_OS_QNX
# include <devctl.h>
# include <sys/procfs.h>
#endif // GTEST_OS_QNX
#include "gtest/gtest-spi.h" #include "gtest/gtest-spi.h"
#include "gtest/gtest-message.h" #include "gtest/gtest-message.h"
#include "gtest/internal/gtest-internal.h" #include "gtest/internal/gtest-internal.h"
@@ -98,6 +103,26 @@ size_t GetThreadCount() {
} }
} }
#elif GTEST_OS_QNX
// Returns the number of threads running in the process, or 0 to indicate that
// we cannot detect it.
size_t GetThreadCount() {
const int fd = open("/proc/self/as", O_RDONLY);
if (fd < 0) {
return 0;
}
procfs_info process_info;
const int status =
devctl(fd, DCMD_PROC_INFO, &process_info, sizeof(process_info), NULL);
close(fd);
if (status == EOK) {
return static_cast<size_t>(process_info.num_threads);
} else {
return 0;
}
}
#else #else
size_t GetThreadCount() { size_t GetThreadCount() {
@@ -222,7 +247,7 @@ bool AtomMatchesChar(bool escaped, char pattern_char, char ch) {
} }
// Helper function used by ValidateRegex() to format error messages. // Helper function used by ValidateRegex() to format error messages.
String FormatRegexSyntaxError(const char* regex, int index) { std::string FormatRegexSyntaxError(const char* regex, int index) {
return (Message() << "Syntax error at index " << index return (Message() << "Syntax error at index " << index
<< " in simple regular expression \"" << regex << "\": ").GetString(); << " in simple regular expression \"" << regex << "\": ").GetString();
} }
@@ -429,15 +454,15 @@ const char kUnknownFile[] = "unknown file";
// Formats a source file path and a line number as they would appear // Formats a source file path and a line number as they would appear
// in an error message from the compiler used to compile this code. // in an error message from the compiler used to compile this code.
GTEST_API_ ::std::string FormatFileLocation(const char* file, int line) { GTEST_API_ ::std::string FormatFileLocation(const char* file, int line) {
const char* const file_name = file == NULL ? kUnknownFile : file; const std::string file_name(file == NULL ? kUnknownFile : file);
if (line < 0) { if (line < 0) {
return String::Format("%s:", file_name).c_str(); return file_name + ":";
} }
#ifdef _MSC_VER #ifdef _MSC_VER
return String::Format("%s(%d):", file_name, line).c_str(); return file_name + "(" + StreamableToString(line) + "):";
#else #else
return String::Format("%s:%d:", file_name, line).c_str(); return file_name + ":" + StreamableToString(line) + ":";
#endif // _MSC_VER #endif // _MSC_VER
} }
@@ -448,12 +473,12 @@ GTEST_API_ ::std::string FormatFileLocation(const char* file, int line) {
// to the file location it produces, unlike FormatFileLocation(). // to the file location it produces, unlike FormatFileLocation().
GTEST_API_ ::std::string FormatCompilerIndependentFileLocation( GTEST_API_ ::std::string FormatCompilerIndependentFileLocation(
const char* file, int line) { const char* file, int line) {
const char* const file_name = file == NULL ? kUnknownFile : file; const std::string file_name(file == NULL ? kUnknownFile : file);
if (line < 0) if (line < 0)
return file_name; return file_name;
else else
return String::Format("%s:%d", file_name, line).c_str(); return file_name + ":" + StreamableToString(line);
} }
@@ -488,8 +513,7 @@ GTestLog::~GTestLog() {
class CapturedStream { class CapturedStream {
public: public:
// The ctor redirects the stream to a temporary file. // The ctor redirects the stream to a temporary file.
CapturedStream(int fd) : fd_(fd), uncaptured_fd_(dup(fd)) { explicit CapturedStream(int fd) : fd_(fd), uncaptured_fd_(dup(fd)) {
# if GTEST_OS_WINDOWS # if GTEST_OS_WINDOWS
char temp_dir_path[MAX_PATH + 1] = { '\0' }; // NOLINT char temp_dir_path[MAX_PATH + 1] = { '\0' }; // NOLINT
char temp_file_path[MAX_PATH + 1] = { '\0' }; // NOLINT char temp_file_path[MAX_PATH + 1] = { '\0' }; // NOLINT
@@ -506,10 +530,29 @@ class CapturedStream {
<< temp_file_path; << temp_file_path;
filename_ = temp_file_path; filename_ = temp_file_path;
# else # else
// There's no guarantee that a test has write access to the // There's no guarantee that a test has write access to the current
// current directory, so we create the temporary file in the /tmp // directory, so we create the temporary file in the /tmp directory
// directory instead. // instead. We use /tmp on most systems, and /sdcard on Android.
// That's because Android doesn't have /tmp.
# if GTEST_OS_LINUX_ANDROID
// Note: Android applications are expected to call the framework's
// Context.getExternalStorageDirectory() method through JNI to get
// the location of the world-writable SD Card directory. However,
// this requires a Context handle, which cannot be retrieved
// globally from native code. Doing so also precludes running the
// code as part of a regular standalone executable, which doesn't
// run in a Dalvik process (e.g. when running it through 'adb shell').
//
// The location /sdcard is directly accessible from native code
// and is the only location (unofficially) supported by the Android
// team. It's generally a symlink to the real SD Card mount point
// which can be /mnt/sdcard, /mnt/sdcard0, /system/media/sdcard, or
// other OEM-customized locations. Never rely on these, and always
// use /sdcard.
char name_template[] = "/sdcard/gtest_captured_stream.XXXXXX";
# else
char name_template[] = "/tmp/captured_stream.XXXXXX"; char name_template[] = "/tmp/captured_stream.XXXXXX";
# endif // GTEST_OS_LINUX_ANDROID
const int captured_fd = mkstemp(name_template); const int captured_fd = mkstemp(name_template);
filename_ = name_template; filename_ = name_template;
# endif // GTEST_OS_WINDOWS # endif // GTEST_OS_WINDOWS
@@ -522,7 +565,7 @@ class CapturedStream {
remove(filename_.c_str()); remove(filename_.c_str());
} }
String GetCapturedString() { std::string GetCapturedString() {
if (uncaptured_fd_ != -1) { if (uncaptured_fd_ != -1) {
// Restores the original stream. // Restores the original stream.
fflush(NULL); fflush(NULL);
@@ -532,14 +575,14 @@ class CapturedStream {
} }
FILE* const file = posix::FOpen(filename_.c_str(), "r"); FILE* const file = posix::FOpen(filename_.c_str(), "r");
const String content = ReadEntireFile(file); const std::string content = ReadEntireFile(file);
posix::FClose(file); posix::FClose(file);
return content; return content;
} }
private: private:
// Reads the entire content of a file as a String. // Reads the entire content of a file as an std::string.
static String ReadEntireFile(FILE* file); static std::string ReadEntireFile(FILE* file);
// Returns the size (in bytes) of a file. // Returns the size (in bytes) of a file.
static size_t GetFileSize(FILE* file); static size_t GetFileSize(FILE* file);
@@ -559,7 +602,7 @@ size_t CapturedStream::GetFileSize(FILE* file) {
} }
// Reads the entire content of a file as a string. // Reads the entire content of a file as a string.
String CapturedStream::ReadEntireFile(FILE* file) { std::string CapturedStream::ReadEntireFile(FILE* file) {
const size_t file_size = GetFileSize(file); const size_t file_size = GetFileSize(file);
char* const buffer = new char[file_size]; char* const buffer = new char[file_size];
@@ -575,7 +618,7 @@ String CapturedStream::ReadEntireFile(FILE* file) {
bytes_read += bytes_last_read; bytes_read += bytes_last_read;
} while (bytes_last_read > 0 && bytes_read < file_size); } while (bytes_last_read > 0 && bytes_read < file_size);
const String content(buffer, bytes_read); const std::string content(buffer, bytes_read);
delete[] buffer; delete[] buffer;
return content; return content;
@@ -598,8 +641,8 @@ void CaptureStream(int fd, const char* stream_name, CapturedStream** stream) {
} }
// Stops capturing the output stream and returns the captured string. // Stops capturing the output stream and returns the captured string.
String GetCapturedStream(CapturedStream** captured_stream) { std::string GetCapturedStream(CapturedStream** captured_stream) {
const String content = (*captured_stream)->GetCapturedString(); const std::string content = (*captured_stream)->GetCapturedString();
delete *captured_stream; delete *captured_stream;
*captured_stream = NULL; *captured_stream = NULL;
@@ -618,21 +661,37 @@ void CaptureStderr() {
} }
// Stops capturing stdout and returns the captured string. // Stops capturing stdout and returns the captured string.
String GetCapturedStdout() { return GetCapturedStream(&g_captured_stdout); } std::string GetCapturedStdout() {
return GetCapturedStream(&g_captured_stdout);
}
// Stops capturing stderr and returns the captured string. // Stops capturing stderr and returns the captured string.
String GetCapturedStderr() { return GetCapturedStream(&g_captured_stderr); } std::string GetCapturedStderr() {
return GetCapturedStream(&g_captured_stderr);
}
#endif // GTEST_HAS_STREAM_REDIRECTION #endif // GTEST_HAS_STREAM_REDIRECTION
#if GTEST_HAS_DEATH_TEST #if GTEST_HAS_DEATH_TEST
// A copy of all command line arguments. Set by InitGoogleTest(). // A copy of all command line arguments. Set by InitGoogleTest().
::std::vector<String> g_argvs; ::std::vector<testing::internal::string> g_argvs;
// Returns the command line as a vector of strings. static const ::std::vector<testing::internal::string>* g_injected_test_argvs =
const ::std::vector<String>& GetArgvs() { return g_argvs; } NULL; // Owned.
void SetInjectableArgvs(const ::std::vector<testing::internal::string>* argvs) {
if (g_injected_test_argvs != argvs)
delete g_injected_test_argvs;
g_injected_test_argvs = argvs;
}
const ::std::vector<testing::internal::string>& GetInjectableArgvs() {
if (g_injected_test_argvs != NULL) {
return *g_injected_test_argvs;
}
return g_argvs;
}
#endif // GTEST_HAS_DEATH_TEST #endif // GTEST_HAS_DEATH_TEST
#if GTEST_OS_WINDOWS_MOBILE #if GTEST_OS_WINDOWS_MOBILE
@@ -647,8 +706,8 @@ void Abort() {
// Returns the name of the environment variable corresponding to the // Returns the name of the environment variable corresponding to the
// given flag. For example, FlagToEnvVar("foo") will return // given flag. For example, FlagToEnvVar("foo") will return
// "GTEST_FOO" in the open-source version. // "GTEST_FOO" in the open-source version.
static String FlagToEnvVar(const char* flag) { static std::string FlagToEnvVar(const char* flag) {
const String full_flag = const std::string full_flag =
(Message() << GTEST_FLAG_PREFIX_ << flag).GetString(); (Message() << GTEST_FLAG_PREFIX_ << flag).GetString();
Message env_var; Message env_var;
@@ -705,7 +764,7 @@ bool ParseInt32(const Message& src_text, const char* str, Int32* value) {
// //
// The value is considered true iff it's not "0". // The value is considered true iff it's not "0".
bool BoolFromGTestEnv(const char* flag, bool default_value) { bool BoolFromGTestEnv(const char* flag, bool default_value) {
const String env_var = FlagToEnvVar(flag); const std::string env_var = FlagToEnvVar(flag);
const char* const string_value = posix::GetEnv(env_var.c_str()); const char* const string_value = posix::GetEnv(env_var.c_str());
return string_value == NULL ? return string_value == NULL ?
default_value : strcmp(string_value, "0") != 0; default_value : strcmp(string_value, "0") != 0;
@@ -715,7 +774,7 @@ bool BoolFromGTestEnv(const char* flag, bool default_value) {
// variable corresponding to the given flag; if it isn't set or // variable corresponding to the given flag; if it isn't set or
// doesn't represent a valid 32-bit integer, returns default_value. // doesn't represent a valid 32-bit integer, returns default_value.
Int32 Int32FromGTestEnv(const char* flag, Int32 default_value) { Int32 Int32FromGTestEnv(const char* flag, Int32 default_value) {
const String env_var = FlagToEnvVar(flag); const std::string env_var = FlagToEnvVar(flag);
const char* const string_value = posix::GetEnv(env_var.c_str()); const char* const string_value = posix::GetEnv(env_var.c_str());
if (string_value == NULL) { if (string_value == NULL) {
// The environment variable is not set. // The environment variable is not set.
@@ -737,7 +796,7 @@ Int32 Int32FromGTestEnv(const char* flag, Int32 default_value) {
// Reads and returns the string environment variable corresponding to // Reads and returns the string environment variable corresponding to
// the given flag; if it's not set, returns default_value. // the given flag; if it's not set, returns default_value.
const char* StringFromGTestEnv(const char* flag, const char* default_value) { const char* StringFromGTestEnv(const char* flag, const char* default_value) {
const String env_var = FlagToEnvVar(flag); const std::string env_var = FlagToEnvVar(flag);
const char* const value = posix::GetEnv(env_var.c_str()); const char* const value = posix::GetEnv(env_var.c_str());
return value == NULL ? default_value : value; return value == NULL ? default_value : value;
} }
+54 -47
View File
@@ -55,14 +55,6 @@ namespace {
using ::std::ostream; using ::std::ostream;
#if GTEST_OS_WINDOWS_MOBILE // Windows CE does not define _snprintf_s.
# define snprintf _snprintf
#elif _MSC_VER >= 1400 // VC 8.0 and later deprecate snprintf and _snprintf.
# define snprintf _snprintf_s
#elif _MSC_VER
# define snprintf _snprintf
#endif // GTEST_OS_WINDOWS_MOBILE
// Prints a segment of bytes in the given object. // Prints a segment of bytes in the given object.
void PrintByteSegmentInObjectTo(const unsigned char* obj_bytes, size_t start, void PrintByteSegmentInObjectTo(const unsigned char* obj_bytes, size_t start,
size_t count, ostream* os) { size_t count, ostream* os) {
@@ -77,7 +69,7 @@ void PrintByteSegmentInObjectTo(const unsigned char* obj_bytes, size_t start,
else else
*os << '-'; *os << '-';
} }
snprintf(text, sizeof(text), "%02X", obj_bytes[j]); GTEST_SNPRINTF_(text, sizeof(text), "%02X", obj_bytes[j]);
*os << text; *os << text;
} }
} }
@@ -184,16 +176,16 @@ static CharFormat PrintAsCharLiteralTo(Char c, ostream* os) {
*os << static_cast<char>(c); *os << static_cast<char>(c);
return kAsIs; return kAsIs;
} else { } else {
*os << String::Format("\\x%X", static_cast<UnsignedChar>(c)); *os << "\\x" + String::FormatHexInt(static_cast<UnsignedChar>(c));
return kHexEscape; return kHexEscape;
} }
} }
return kSpecialEscape; return kSpecialEscape;
} }
// Prints a char c as if it's part of a string literal, escaping it when // Prints a wchar_t c as if it's part of a string literal, escaping it when
// necessary; returns how c was formatted. // necessary; returns how c was formatted.
static CharFormat PrintAsWideStringLiteralTo(wchar_t c, ostream* os) { static CharFormat PrintAsStringLiteralTo(wchar_t c, ostream* os) {
switch (c) { switch (c) {
case L'\'': case L'\'':
*os << "'"; *os << "'";
@@ -208,8 +200,9 @@ static CharFormat PrintAsWideStringLiteralTo(wchar_t c, ostream* os) {
// Prints a char c as if it's part of a string literal, escaping it when // Prints a char c as if it's part of a string literal, escaping it when
// necessary; returns how c was formatted. // necessary; returns how c was formatted.
static CharFormat PrintAsNarrowStringLiteralTo(char c, ostream* os) { static CharFormat PrintAsStringLiteralTo(char c, ostream* os) {
return PrintAsWideStringLiteralTo(static_cast<unsigned char>(c), os); return PrintAsStringLiteralTo(
static_cast<wchar_t>(static_cast<unsigned char>(c)), os);
} }
// Prints a wide or narrow character c and its code. '\0' is printed // Prints a wide or narrow character c and its code. '\0' is printed
@@ -228,7 +221,7 @@ void PrintCharAndCodeTo(Char c, ostream* os) {
// obvious). // obvious).
if (c == 0) if (c == 0)
return; return;
*os << " (" << String::Format("%d", c).c_str(); *os << " (" << static_cast<int>(c);
// For more convenience, we print c's code again in hexidecimal, // For more convenience, we print c's code again in hexidecimal,
// unless c was already printed in the form '\x##' or the code is in // unless c was already printed in the form '\x##' or the code is in
@@ -236,8 +229,7 @@ void PrintCharAndCodeTo(Char c, ostream* os) {
if (format == kHexEscape || (1 <= c && c <= 9)) { if (format == kHexEscape || (1 <= c && c <= 9)) {
// Do nothing. // Do nothing.
} else { } else {
*os << String::Format(", 0x%X", *os << ", 0x" << String::FormatHexInt(static_cast<UnsignedChar>(c));
static_cast<UnsignedChar>(c)).c_str();
} }
*os << ")"; *os << ")";
} }
@@ -255,48 +247,63 @@ void PrintTo(wchar_t wc, ostream* os) {
PrintCharAndCodeTo<wchar_t>(wc, os); PrintCharAndCodeTo<wchar_t>(wc, os);
} }
// Prints the given array of characters to the ostream. // Prints the given array of characters to the ostream. CharType must be either
// The array starts at *begin, the length is len, it may include '\0' characters // char or wchar_t.
// and may not be null-terminated. // The array starts at begin, the length is len, it may include '\0' characters
static void PrintCharsAsStringTo(const char* begin, size_t len, ostream* os) { // and may not be NUL-terminated.
*os << "\""; template <typename CharType>
static void PrintCharsAsStringTo(
const CharType* begin, size_t len, ostream* os) {
const char* const kQuoteBegin = sizeof(CharType) == 1 ? "\"" : "L\"";
*os << kQuoteBegin;
bool is_previous_hex = false; bool is_previous_hex = false;
for (size_t index = 0; index < len; ++index) { for (size_t index = 0; index < len; ++index) {
const char cur = begin[index]; const CharType cur = begin[index];
if (is_previous_hex && IsXDigit(cur)) { if (is_previous_hex && IsXDigit(cur)) {
// Previous character is of '\x..' form and this character can be // Previous character is of '\x..' form and this character can be
// interpreted as another hexadecimal digit in its number. Break string to // interpreted as another hexadecimal digit in its number. Break string to
// disambiguate. // disambiguate.
*os << "\" \""; *os << "\" " << kQuoteBegin;
} }
is_previous_hex = PrintAsNarrowStringLiteralTo(cur, os) == kHexEscape; is_previous_hex = PrintAsStringLiteralTo(cur, os) == kHexEscape;
} }
*os << "\""; *os << "\"";
} }
// Prints a (const) char/wchar_t array of 'len' elements, starting at address
// 'begin'. CharType must be either char or wchar_t.
template <typename CharType>
static void UniversalPrintCharArray(
const CharType* begin, size_t len, ostream* os) {
// The code
// const char kFoo[] = "foo";
// generates an array of 4, not 3, elements, with the last one being '\0'.
//
// Therefore when printing a char array, we don't print the last element if
// it's '\0', such that the output matches the string literal as it's
// written in the source code.
if (len > 0 && begin[len - 1] == '\0') {
PrintCharsAsStringTo(begin, len - 1, os);
return;
}
// If, however, the last element in the array is not '\0', e.g.
// const char kFoo[] = { 'f', 'o', 'o' };
// we must print the entire array. We also print a message to indicate
// that the array is not NUL-terminated.
PrintCharsAsStringTo(begin, len, os);
*os << " (no terminating NUL)";
}
// Prints a (const) char array of 'len' elements, starting at address 'begin'. // Prints a (const) char array of 'len' elements, starting at address 'begin'.
void UniversalPrintArray(const char* begin, size_t len, ostream* os) { void UniversalPrintArray(const char* begin, size_t len, ostream* os) {
PrintCharsAsStringTo(begin, len, os); UniversalPrintCharArray(begin, len, os);
} }
// Prints the given array of wide characters to the ostream. // Prints a (const) wchar_t array of 'len' elements, starting at address
// The array starts at *begin, the length is len, it may include L'\0' // 'begin'.
// characters and may not be null-terminated. void UniversalPrintArray(const wchar_t* begin, size_t len, ostream* os) {
static void PrintWideCharsAsStringTo(const wchar_t* begin, size_t len, UniversalPrintCharArray(begin, len, os);
ostream* os) {
*os << "L\"";
bool is_previous_hex = false;
for (size_t index = 0; index < len; ++index) {
const wchar_t cur = begin[index];
if (is_previous_hex && isascii(cur) && IsXDigit(static_cast<char>(cur))) {
// Previous character is of '\x..' form and this character can be
// interpreted as another hexadecimal digit in its number. Break string to
// disambiguate.
*os << "\" L\"";
}
is_previous_hex = PrintAsWideStringLiteralTo(cur, os) == kHexEscape;
}
*os << "\"";
} }
// Prints the given C string to the ostream. // Prints the given C string to the ostream.
@@ -322,7 +329,7 @@ void PrintTo(const wchar_t* s, ostream* os) {
*os << "NULL"; *os << "NULL";
} else { } else {
*os << ImplicitCast_<const void*>(s) << " pointing to "; *os << ImplicitCast_<const void*>(s) << " pointing to ";
PrintWideCharsAsStringTo(s, wcslen(s), os); PrintCharsAsStringTo(s, wcslen(s), os);
} }
} }
#endif // wchar_t is native #endif // wchar_t is native
@@ -341,13 +348,13 @@ void PrintStringTo(const ::std::string& s, ostream* os) {
// Prints a ::wstring object. // Prints a ::wstring object.
#if GTEST_HAS_GLOBAL_WSTRING #if GTEST_HAS_GLOBAL_WSTRING
void PrintWideStringTo(const ::wstring& s, ostream* os) { void PrintWideStringTo(const ::wstring& s, ostream* os) {
PrintWideCharsAsStringTo(s.data(), s.size(), os); PrintCharsAsStringTo(s.data(), s.size(), os);
} }
#endif // GTEST_HAS_GLOBAL_WSTRING #endif // GTEST_HAS_GLOBAL_WSTRING
#if GTEST_HAS_STD_WSTRING #if GTEST_HAS_STD_WSTRING
void PrintWideStringTo(const ::std::wstring& s, ostream* os) { void PrintWideStringTo(const ::std::wstring& s, ostream* os) {
PrintWideCharsAsStringTo(s.data(), s.size(), os); PrintCharsAsStringTo(s.data(), s.size(), os);
} }
#endif // GTEST_HAS_STD_WSTRING #endif // GTEST_HAS_STD_WSTRING
+3 -3
View File
@@ -48,10 +48,10 @@ using internal::GetUnitTestImpl;
// Gets the summary of the failure message by omitting the stack trace // Gets the summary of the failure message by omitting the stack trace
// in it. // in it.
internal::String TestPartResult::ExtractSummary(const char* message) { std::string TestPartResult::ExtractSummary(const char* message) {
const char* const stack_trace = strstr(message, internal::kStackTraceMarker); const char* const stack_trace = strstr(message, internal::kStackTraceMarker);
return stack_trace == NULL ? internal::String(message) : return stack_trace == NULL ? message :
internal::String(message, stack_trace - message); std::string(message, stack_trace);
} }
// Prints a TestPartResult object. // Prints a TestPartResult object.
+3 -3
View File
@@ -58,10 +58,10 @@ const char* TypedTestCasePState::VerifyRegisteredTestNames(
registered_tests = SkipSpaces(registered_tests); registered_tests = SkipSpaces(registered_tests);
Message errors; Message errors;
::std::set<String> tests; ::std::set<std::string> tests;
for (const char* names = registered_tests; names != NULL; for (const char* names = registered_tests; names != NULL;
names = SkipComma(names)) { names = SkipComma(names)) {
const String name = GetPrefixUntilComma(names); const std::string name = GetPrefixUntilComma(names);
if (tests.count(name) != 0) { if (tests.count(name) != 0) {
errors << "Test " << name << " is listed more than once.\n"; errors << "Test " << name << " is listed more than once.\n";
continue; continue;
@@ -93,7 +93,7 @@ const char* TypedTestCasePState::VerifyRegisteredTestNames(
} }
} }
const String& errors_str = errors.GetString(); const std::string& errors_str = errors.GetString();
if (errors_str != "") { if (errors_str != "") {
fprintf(stderr, "%s %s", FormatFileLocation(file, line).c_str(), fprintf(stderr, "%s %s", FormatFileLocation(file, line).c_str(),
errors_str.c_str()); errors_str.c_str());
+679 -562
View File
File diff suppressed because it is too large Load Diff
+2 -3
View File
@@ -27,13 +27,12 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <iostream> #include <stdio.h>
#include "gtest/gtest.h" #include "gtest/gtest.h"
GTEST_API_ int main(int argc, char **argv) { GTEST_API_ int main(int argc, char **argv) {
std::cout << "Running main() from gtest_main.cc\n"; printf("Running main() from gtest_main.cc\n");
testing::InitGoogleTest(&argc, argv); testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS(); return RUN_ALL_TESTS();
} }
+112 -41
View File
@@ -45,13 +45,16 @@ using testing::internal::AlwaysTrue;
# else # else
# include <unistd.h> # include <unistd.h>
# include <sys/wait.h> // For waitpid. # include <sys/wait.h> // For waitpid.
# include <limits> // For std::numeric_limits.
# endif // GTEST_OS_WINDOWS # endif // GTEST_OS_WINDOWS
# include <limits.h> # include <limits.h>
# include <signal.h> # include <signal.h>
# include <stdio.h> # include <stdio.h>
# if GTEST_OS_LINUX
# include <sys/time.h>
# endif // GTEST_OS_LINUX
# include "gtest/gtest-spi.h" # include "gtest/gtest-spi.h"
// Indicates that this translation unit is part of Google Test's // Indicates that this translation unit is part of Google Test's
@@ -71,8 +74,8 @@ using testing::internal::DeathTestFactory;
using testing::internal::FilePath; using testing::internal::FilePath;
using testing::internal::GetLastErrnoDescription; using testing::internal::GetLastErrnoDescription;
using testing::internal::GetUnitTestImpl; using testing::internal::GetUnitTestImpl;
using testing::internal::InDeathTestChild;
using testing::internal::ParseNaturalNumber; using testing::internal::ParseNaturalNumber;
using testing::internal::String;
namespace testing { namespace testing {
namespace internal { namespace internal {
@@ -372,6 +375,58 @@ TEST_F(TestForDeathTest, FastDeathTestInChangedDir) {
ASSERT_DEATH(_exit(1), ""); ASSERT_DEATH(_exit(1), "");
} }
# if GTEST_OS_LINUX
void SigprofAction(int, siginfo_t*, void*) { /* no op */ }
// Sets SIGPROF action and ITIMER_PROF timer (interval: 1ms).
void SetSigprofActionAndTimer() {
struct itimerval timer;
timer.it_interval.tv_sec = 0;
timer.it_interval.tv_usec = 1;
timer.it_value = timer.it_interval;
ASSERT_EQ(0, setitimer(ITIMER_PROF, &timer, NULL));
struct sigaction signal_action;
memset(&signal_action, 0, sizeof(signal_action));
sigemptyset(&signal_action.sa_mask);
signal_action.sa_sigaction = SigprofAction;
signal_action.sa_flags = SA_RESTART | SA_SIGINFO;
ASSERT_EQ(0, sigaction(SIGPROF, &signal_action, NULL));
}
// Disables ITIMER_PROF timer and ignores SIGPROF signal.
void DisableSigprofActionAndTimer(struct sigaction* old_signal_action) {
struct itimerval timer;
timer.it_interval.tv_sec = 0;
timer.it_interval.tv_usec = 0;
timer.it_value = timer.it_interval;
ASSERT_EQ(0, setitimer(ITIMER_PROF, &timer, NULL));
struct sigaction signal_action;
memset(&signal_action, 0, sizeof(signal_action));
sigemptyset(&signal_action.sa_mask);
signal_action.sa_handler = SIG_IGN;
ASSERT_EQ(0, sigaction(SIGPROF, &signal_action, old_signal_action));
}
// Tests that death tests work when SIGPROF handler and timer are set.
TEST_F(TestForDeathTest, FastSigprofActionSet) {
testing::GTEST_FLAG(death_test_style) = "fast";
SetSigprofActionAndTimer();
EXPECT_DEATH(_exit(1), "");
struct sigaction old_signal_action;
DisableSigprofActionAndTimer(&old_signal_action);
EXPECT_TRUE(old_signal_action.sa_sigaction == SigprofAction);
}
TEST_F(TestForDeathTest, ThreadSafeSigprofActionSet) {
testing::GTEST_FLAG(death_test_style) = "threadsafe";
SetSigprofActionAndTimer();
EXPECT_DEATH(_exit(1), "");
struct sigaction old_signal_action;
DisableSigprofActionAndTimer(&old_signal_action);
EXPECT_TRUE(old_signal_action.sa_sigaction == SigprofAction);
}
# endif // GTEST_OS_LINUX
// Repeats a representative sample of death tests in the "threadsafe" style: // Repeats a representative sample of death tests in the "threadsafe" style:
TEST_F(TestForDeathTest, StaticMemberFunctionThreadsafeStyle) { TEST_F(TestForDeathTest, StaticMemberFunctionThreadsafeStyle) {
@@ -409,6 +464,8 @@ TEST_F(TestForDeathTest, MixedStyles) {
EXPECT_DEATH(_exit(1), ""); EXPECT_DEATH(_exit(1), "");
} }
# if GTEST_HAS_CLONE && GTEST_HAS_PTHREAD
namespace { namespace {
bool pthread_flag; bool pthread_flag;
@@ -419,8 +476,6 @@ void SetPthreadFlag() {
} // namespace } // namespace
# if GTEST_HAS_CLONE && GTEST_HAS_PTHREAD
TEST_F(TestForDeathTest, DoesNotExecuteAtforkHooks) { TEST_F(TestForDeathTest, DoesNotExecuteAtforkHooks) {
if (!testing::GTEST_FLAG(death_test_use_fork)) { if (!testing::GTEST_FLAG(death_test_use_fork)) {
testing::GTEST_FLAG(death_test_style) = "threadsafe"; testing::GTEST_FLAG(death_test_style) = "threadsafe";
@@ -561,8 +616,8 @@ TEST_F(TestForDeathTest, ReturnIsFailure) {
"illegal return in test statement."); "illegal return in test statement.");
} }
// Tests that EXPECT_DEBUG_DEATH works as expected, // Tests that EXPECT_DEBUG_DEATH works as expected, that is, you can stream a
// that is, in debug mode, it: // message to it, and in debug mode it:
// 1. Asserts on death. // 1. Asserts on death.
// 2. Has no side effect. // 2. Has no side effect.
// //
@@ -571,8 +626,8 @@ TEST_F(TestForDeathTest, ReturnIsFailure) {
TEST_F(TestForDeathTest, TestExpectDebugDeath) { TEST_F(TestForDeathTest, TestExpectDebugDeath) {
int sideeffect = 0; int sideeffect = 0;
EXPECT_DEBUG_DEATH(DieInDebugElse12(&sideeffect), EXPECT_DEBUG_DEATH(DieInDebugElse12(&sideeffect), "death.*DieInDebugElse12")
"death.*DieInDebugElse12"); << "Must accept a streamed message";
# ifdef NDEBUG # ifdef NDEBUG
@@ -587,22 +642,18 @@ TEST_F(TestForDeathTest, TestExpectDebugDeath) {
# endif # endif
} }
// Tests that ASSERT_DEBUG_DEATH works as expected // Tests that ASSERT_DEBUG_DEATH works as expected, that is, you can stream a
// In debug mode: // message to it, and in debug mode it:
// 1. Asserts on debug death. // 1. Asserts on death.
// 2. Has no side effect. // 2. Has no side effect.
// //
// In opt mode: // And in opt mode, it:
// 1. Has side effects and returns the expected value (12). // 1. Has side effects but does not assert.
TEST_F(TestForDeathTest, TestAssertDebugDeath) { TEST_F(TestForDeathTest, TestAssertDebugDeath) {
int sideeffect = 0; int sideeffect = 0;
ASSERT_DEBUG_DEATH({ // NOLINT ASSERT_DEBUG_DEATH(DieInDebugElse12(&sideeffect), "death.*DieInDebugElse12")
// Tests that the return value is 12 in opt mode. << "Must accept a streamed message";
EXPECT_EQ(12, DieInDebugElse12(&sideeffect));
// Tests that the side effect occurred in opt mode.
EXPECT_EQ(12, sideeffect);
}, "death.*DieInDebugElse12");
# ifdef NDEBUG # ifdef NDEBUG
@@ -673,7 +724,7 @@ static void TestExitMacros() {
// Of all signals effects on the process exit code, only those of SIGABRT // Of all signals effects on the process exit code, only those of SIGABRT
// are documented on Windows. // are documented on Windows.
// See http://msdn.microsoft.com/en-us/library/dwwzkt4c(VS.71).aspx. // See http://msdn.microsoft.com/en-us/library/dwwzkt4c(VS.71).aspx.
EXPECT_EXIT(raise(SIGABRT), testing::ExitedWithCode(3), ""); EXPECT_EXIT(raise(SIGABRT), testing::ExitedWithCode(3), "") << "b_ar";
# else # else
@@ -682,14 +733,14 @@ static void TestExitMacros() {
EXPECT_FATAL_FAILURE({ // NOLINT EXPECT_FATAL_FAILURE({ // NOLINT
ASSERT_EXIT(_exit(0), testing::KilledBySignal(SIGSEGV), "") ASSERT_EXIT(_exit(0), testing::KilledBySignal(SIGSEGV), "")
<< "This failure is expected, too."; << "This failure is expected, too.";
}, "This failure is expected, too."); }, "This failure is expected, too.");
# endif // GTEST_OS_WINDOWS # endif // GTEST_OS_WINDOWS
EXPECT_NONFATAL_FAILURE({ // NOLINT EXPECT_NONFATAL_FAILURE({ // NOLINT
EXPECT_EXIT(raise(SIGSEGV), testing::ExitedWithCode(0), "") EXPECT_EXIT(raise(SIGSEGV), testing::ExitedWithCode(0), "")
<< "This failure is expected."; << "This failure is expected.";
}, "This failure is expected."); }, "This failure is expected.");
} }
@@ -839,6 +890,7 @@ class MockDeathTest : public DeathTest {
virtual void Abort(AbortReason reason) { virtual void Abort(AbortReason reason) {
parent_->abort_args_.push_back(reason); parent_->abort_args_.push_back(reason);
} }
private: private:
MockDeathTestFactory* const parent_; MockDeathTestFactory* const parent_;
const TestRole role_; const TestRole role_;
@@ -1070,41 +1122,40 @@ TEST(AutoHandleTest, AutoHandleWorks) {
# if GTEST_OS_WINDOWS # if GTEST_OS_WINDOWS
typedef unsigned __int64 BiggestParsable; typedef unsigned __int64 BiggestParsable;
typedef signed __int64 BiggestSignedParsable; typedef signed __int64 BiggestSignedParsable;
const BiggestParsable kBiggestParsableMax = ULLONG_MAX;
const BiggestSignedParsable kBiggestSignedParsableMax = LLONG_MAX;
# else # else
typedef unsigned long long BiggestParsable; typedef unsigned long long BiggestParsable;
typedef signed long long BiggestSignedParsable; typedef signed long long BiggestSignedParsable;
const BiggestParsable kBiggestParsableMax =
::std::numeric_limits<BiggestParsable>::max();
const BiggestSignedParsable kBiggestSignedParsableMax =
::std::numeric_limits<BiggestSignedParsable>::max();
# endif // GTEST_OS_WINDOWS # endif // GTEST_OS_WINDOWS
// We cannot use std::numeric_limits<T>::max() as it clashes with the
// max() macro defined by <windows.h>.
const BiggestParsable kBiggestParsableMax = ULLONG_MAX;
const BiggestSignedParsable kBiggestSignedParsableMax = LLONG_MAX;
TEST(ParseNaturalNumberTest, RejectsInvalidFormat) { TEST(ParseNaturalNumberTest, RejectsInvalidFormat) {
BiggestParsable result = 0; BiggestParsable result = 0;
// Rejects non-numbers. // Rejects non-numbers.
EXPECT_FALSE(ParseNaturalNumber(String("non-number string"), &result)); EXPECT_FALSE(ParseNaturalNumber("non-number string", &result));
// Rejects numbers with whitespace prefix. // Rejects numbers with whitespace prefix.
EXPECT_FALSE(ParseNaturalNumber(String(" 123"), &result)); EXPECT_FALSE(ParseNaturalNumber(" 123", &result));
// Rejects negative numbers. // Rejects negative numbers.
EXPECT_FALSE(ParseNaturalNumber(String("-123"), &result)); EXPECT_FALSE(ParseNaturalNumber("-123", &result));
// Rejects numbers starting with a plus sign. // Rejects numbers starting with a plus sign.
EXPECT_FALSE(ParseNaturalNumber(String("+123"), &result)); EXPECT_FALSE(ParseNaturalNumber("+123", &result));
errno = 0; errno = 0;
} }
TEST(ParseNaturalNumberTest, RejectsOverflownNumbers) { TEST(ParseNaturalNumberTest, RejectsOverflownNumbers) {
BiggestParsable result = 0; BiggestParsable result = 0;
EXPECT_FALSE(ParseNaturalNumber(String("99999999999999999999999"), &result)); EXPECT_FALSE(ParseNaturalNumber("99999999999999999999999", &result));
signed char char_result = 0; signed char char_result = 0;
EXPECT_FALSE(ParseNaturalNumber(String("200"), &char_result)); EXPECT_FALSE(ParseNaturalNumber("200", &char_result));
errno = 0; errno = 0;
} }
@@ -1112,16 +1163,16 @@ TEST(ParseNaturalNumberTest, AcceptsValidNumbers) {
BiggestParsable result = 0; BiggestParsable result = 0;
result = 0; result = 0;
ASSERT_TRUE(ParseNaturalNumber(String("123"), &result)); ASSERT_TRUE(ParseNaturalNumber("123", &result));
EXPECT_EQ(123U, result); EXPECT_EQ(123U, result);
// Check 0 as an edge case. // Check 0 as an edge case.
result = 1; result = 1;
ASSERT_TRUE(ParseNaturalNumber(String("0"), &result)); ASSERT_TRUE(ParseNaturalNumber("0", &result));
EXPECT_EQ(0U, result); EXPECT_EQ(0U, result);
result = 1; result = 1;
ASSERT_TRUE(ParseNaturalNumber(String("00000"), &result)); ASSERT_TRUE(ParseNaturalNumber("00000", &result));
EXPECT_EQ(0U, result); EXPECT_EQ(0U, result);
} }
@@ -1157,11 +1208,11 @@ TEST(ParseNaturalNumberTest, AcceptsTypeLimits) {
TEST(ParseNaturalNumberTest, WorksForShorterIntegers) { TEST(ParseNaturalNumberTest, WorksForShorterIntegers) {
short short_result = 0; short short_result = 0;
ASSERT_TRUE(ParseNaturalNumber(String("123"), &short_result)); ASSERT_TRUE(ParseNaturalNumber("123", &short_result));
EXPECT_EQ(123, short_result); EXPECT_EQ(123, short_result);
signed char char_result = 0; signed char char_result = 0;
ASSERT_TRUE(ParseNaturalNumber(String("123"), &char_result)); ASSERT_TRUE(ParseNaturalNumber("123", &char_result));
EXPECT_EQ(123, char_result); EXPECT_EQ(123, char_result);
} }
@@ -1191,7 +1242,6 @@ TEST(ConditionalDeathMacrosDeathTest, ExpectsDeathWhenDeathTestsAvailable) {
using testing::internal::CaptureStderr; using testing::internal::CaptureStderr;
using testing::internal::GetCapturedStderr; using testing::internal::GetCapturedStderr;
using testing::internal::String;
// Tests that EXPECT_DEATH_IF_SUPPORTED/ASSERT_DEATH_IF_SUPPORTED are still // Tests that EXPECT_DEATH_IF_SUPPORTED/ASSERT_DEATH_IF_SUPPORTED are still
// defined but do not trigger failures when death tests are not available on // defined but do not trigger failures when death tests are not available on
@@ -1201,7 +1251,7 @@ TEST(ConditionalDeathMacrosTest, WarnsWhenDeathTestsNotAvailable) {
// when death tests are not supported. // when death tests are not supported.
CaptureStderr(); CaptureStderr();
EXPECT_DEATH_IF_SUPPORTED(;, ""); EXPECT_DEATH_IF_SUPPORTED(;, "");
String output = GetCapturedStderr(); std::string output = GetCapturedStderr();
ASSERT_TRUE(NULL != strstr(output.c_str(), ASSERT_TRUE(NULL != strstr(output.c_str(),
"Death tests are not supported on this platform")); "Death tests are not supported on this platform"));
ASSERT_TRUE(NULL != strstr(output.c_str(), ";")); ASSERT_TRUE(NULL != strstr(output.c_str(), ";"));
@@ -1237,6 +1287,27 @@ TEST(ConditionalDeathMacrosTest, AssertDeatDoesNotReturnhIfUnsupported) {
FuncWithAssert(&n); FuncWithAssert(&n);
EXPECT_EQ(1, n); EXPECT_EQ(1, n);
} }
TEST(InDeathTestChildDeathTest, ReportsDeathTestCorrectlyInFastStyle) {
testing::GTEST_FLAG(death_test_style) = "fast";
EXPECT_FALSE(InDeathTestChild());
EXPECT_DEATH({
fprintf(stderr, InDeathTestChild() ? "Inside" : "Outside");
fflush(stderr);
_exit(1);
}, "Inside");
}
TEST(InDeathTestChildDeathTest, ReportsDeathTestCorrectlyInThreadSafeStyle) {
testing::GTEST_FLAG(death_test_style) = "threadsafe";
EXPECT_FALSE(InDeathTestChild());
EXPECT_DEATH({
fprintf(stderr, InDeathTestChild() ? "Inside" : "Outside");
fflush(stderr);
_exit(1);
}, "Inside");
}
#endif // GTEST_HAS_DEATH_TEST #endif // GTEST_HAS_DEATH_TEST
// Tests that the death test macros expand to code which may or may not // Tests that the death test macros expand to code which may or may not
+120 -136
View File
@@ -100,7 +100,7 @@ TEST(GetCurrentDirTest, ReturnsCurrentDir) {
# else # else
EXPECT_STREQ(GTEST_PATH_SEP_, cwd.c_str()); EXPECT_EQ(GTEST_PATH_SEP_, cwd.string());
# endif # endif
} }
@@ -109,7 +109,6 @@ TEST(GetCurrentDirTest, ReturnsCurrentDir) {
TEST(IsEmptyTest, ReturnsTrueForEmptyPath) { TEST(IsEmptyTest, ReturnsTrueForEmptyPath) {
EXPECT_TRUE(FilePath("").IsEmpty()); EXPECT_TRUE(FilePath("").IsEmpty());
EXPECT_TRUE(FilePath(NULL).IsEmpty());
} }
TEST(IsEmptyTest, ReturnsFalseForNonEmptyPath) { TEST(IsEmptyTest, ReturnsFalseForNonEmptyPath) {
@@ -121,38 +120,38 @@ TEST(IsEmptyTest, ReturnsFalseForNonEmptyPath) {
// RemoveDirectoryName "" -> "" // RemoveDirectoryName "" -> ""
TEST(RemoveDirectoryNameTest, WhenEmptyName) { TEST(RemoveDirectoryNameTest, WhenEmptyName) {
EXPECT_STREQ("", FilePath("").RemoveDirectoryName().c_str()); EXPECT_EQ("", FilePath("").RemoveDirectoryName().string());
} }
// RemoveDirectoryName "afile" -> "afile" // RemoveDirectoryName "afile" -> "afile"
TEST(RemoveDirectoryNameTest, ButNoDirectory) { TEST(RemoveDirectoryNameTest, ButNoDirectory) {
EXPECT_STREQ("afile", EXPECT_EQ("afile",
FilePath("afile").RemoveDirectoryName().c_str()); FilePath("afile").RemoveDirectoryName().string());
} }
// RemoveDirectoryName "/afile" -> "afile" // RemoveDirectoryName "/afile" -> "afile"
TEST(RemoveDirectoryNameTest, RootFileShouldGiveFileName) { TEST(RemoveDirectoryNameTest, RootFileShouldGiveFileName) {
EXPECT_STREQ("afile", EXPECT_EQ("afile",
FilePath(GTEST_PATH_SEP_ "afile").RemoveDirectoryName().c_str()); FilePath(GTEST_PATH_SEP_ "afile").RemoveDirectoryName().string());
} }
// RemoveDirectoryName "adir/" -> "" // RemoveDirectoryName "adir/" -> ""
TEST(RemoveDirectoryNameTest, WhereThereIsNoFileName) { TEST(RemoveDirectoryNameTest, WhereThereIsNoFileName) {
EXPECT_STREQ("", EXPECT_EQ("",
FilePath("adir" GTEST_PATH_SEP_).RemoveDirectoryName().c_str()); FilePath("adir" GTEST_PATH_SEP_).RemoveDirectoryName().string());
} }
// RemoveDirectoryName "adir/afile" -> "afile" // RemoveDirectoryName "adir/afile" -> "afile"
TEST(RemoveDirectoryNameTest, ShouldGiveFileName) { TEST(RemoveDirectoryNameTest, ShouldGiveFileName) {
EXPECT_STREQ("afile", EXPECT_EQ("afile",
FilePath("adir" GTEST_PATH_SEP_ "afile").RemoveDirectoryName().c_str()); FilePath("adir" GTEST_PATH_SEP_ "afile").RemoveDirectoryName().string());
} }
// RemoveDirectoryName "adir/subdir/afile" -> "afile" // RemoveDirectoryName "adir/subdir/afile" -> "afile"
TEST(RemoveDirectoryNameTest, ShouldAlsoGiveFileName) { TEST(RemoveDirectoryNameTest, ShouldAlsoGiveFileName) {
EXPECT_STREQ("afile", EXPECT_EQ("afile",
FilePath("adir" GTEST_PATH_SEP_ "subdir" GTEST_PATH_SEP_ "afile") FilePath("adir" GTEST_PATH_SEP_ "subdir" GTEST_PATH_SEP_ "afile")
.RemoveDirectoryName().c_str()); .RemoveDirectoryName().string());
} }
#if GTEST_HAS_ALT_PATH_SEP_ #if GTEST_HAS_ALT_PATH_SEP_
@@ -162,26 +161,23 @@ TEST(RemoveDirectoryNameTest, ShouldAlsoGiveFileName) {
// RemoveDirectoryName("/afile") -> "afile" // RemoveDirectoryName("/afile") -> "afile"
TEST(RemoveDirectoryNameTest, RootFileShouldGiveFileNameForAlternateSeparator) { TEST(RemoveDirectoryNameTest, RootFileShouldGiveFileNameForAlternateSeparator) {
EXPECT_STREQ("afile", EXPECT_EQ("afile", FilePath("/afile").RemoveDirectoryName().string());
FilePath("/afile").RemoveDirectoryName().c_str());
} }
// RemoveDirectoryName("adir/") -> "" // RemoveDirectoryName("adir/") -> ""
TEST(RemoveDirectoryNameTest, WhereThereIsNoFileNameForAlternateSeparator) { TEST(RemoveDirectoryNameTest, WhereThereIsNoFileNameForAlternateSeparator) {
EXPECT_STREQ("", EXPECT_EQ("", FilePath("adir/").RemoveDirectoryName().string());
FilePath("adir/").RemoveDirectoryName().c_str());
} }
// RemoveDirectoryName("adir/afile") -> "afile" // RemoveDirectoryName("adir/afile") -> "afile"
TEST(RemoveDirectoryNameTest, ShouldGiveFileNameForAlternateSeparator) { TEST(RemoveDirectoryNameTest, ShouldGiveFileNameForAlternateSeparator) {
EXPECT_STREQ("afile", EXPECT_EQ("afile", FilePath("adir/afile").RemoveDirectoryName().string());
FilePath("adir/afile").RemoveDirectoryName().c_str());
} }
// RemoveDirectoryName("adir/subdir/afile") -> "afile" // RemoveDirectoryName("adir/subdir/afile") -> "afile"
TEST(RemoveDirectoryNameTest, ShouldAlsoGiveFileNameForAlternateSeparator) { TEST(RemoveDirectoryNameTest, ShouldAlsoGiveFileNameForAlternateSeparator) {
EXPECT_STREQ("afile", EXPECT_EQ("afile",
FilePath("adir/subdir/afile").RemoveDirectoryName().c_str()); FilePath("adir/subdir/afile").RemoveDirectoryName().string());
} }
#endif #endif
@@ -190,38 +186,35 @@ TEST(RemoveDirectoryNameTest, ShouldAlsoGiveFileNameForAlternateSeparator) {
TEST(RemoveFileNameTest, EmptyName) { TEST(RemoveFileNameTest, EmptyName) {
#if GTEST_OS_WINDOWS_MOBILE #if GTEST_OS_WINDOWS_MOBILE
// On Windows CE, we use the root as the current directory. // On Windows CE, we use the root as the current directory.
EXPECT_STREQ(GTEST_PATH_SEP_, EXPECT_EQ(GTEST_PATH_SEP_, FilePath("").RemoveFileName().string());
FilePath("").RemoveFileName().c_str());
#else #else
EXPECT_STREQ("." GTEST_PATH_SEP_, EXPECT_EQ("." GTEST_PATH_SEP_, FilePath("").RemoveFileName().string());
FilePath("").RemoveFileName().c_str());
#endif #endif
} }
// RemoveFileName "adir/" -> "adir/" // RemoveFileName "adir/" -> "adir/"
TEST(RemoveFileNameTest, ButNoFile) { TEST(RemoveFileNameTest, ButNoFile) {
EXPECT_STREQ("adir" GTEST_PATH_SEP_, EXPECT_EQ("adir" GTEST_PATH_SEP_,
FilePath("adir" GTEST_PATH_SEP_).RemoveFileName().c_str()); FilePath("adir" GTEST_PATH_SEP_).RemoveFileName().string());
} }
// RemoveFileName "adir/afile" -> "adir/" // RemoveFileName "adir/afile" -> "adir/"
TEST(RemoveFileNameTest, GivesDirName) { TEST(RemoveFileNameTest, GivesDirName) {
EXPECT_STREQ("adir" GTEST_PATH_SEP_, EXPECT_EQ("adir" GTEST_PATH_SEP_,
FilePath("adir" GTEST_PATH_SEP_ "afile") FilePath("adir" GTEST_PATH_SEP_ "afile").RemoveFileName().string());
.RemoveFileName().c_str());
} }
// RemoveFileName "adir/subdir/afile" -> "adir/subdir/" // RemoveFileName "adir/subdir/afile" -> "adir/subdir/"
TEST(RemoveFileNameTest, GivesDirAndSubDirName) { TEST(RemoveFileNameTest, GivesDirAndSubDirName) {
EXPECT_STREQ("adir" GTEST_PATH_SEP_ "subdir" GTEST_PATH_SEP_, EXPECT_EQ("adir" GTEST_PATH_SEP_ "subdir" GTEST_PATH_SEP_,
FilePath("adir" GTEST_PATH_SEP_ "subdir" GTEST_PATH_SEP_ "afile") FilePath("adir" GTEST_PATH_SEP_ "subdir" GTEST_PATH_SEP_ "afile")
.RemoveFileName().c_str()); .RemoveFileName().string());
} }
// RemoveFileName "/afile" -> "/" // RemoveFileName "/afile" -> "/"
TEST(RemoveFileNameTest, GivesRootDir) { TEST(RemoveFileNameTest, GivesRootDir) {
EXPECT_STREQ(GTEST_PATH_SEP_, EXPECT_EQ(GTEST_PATH_SEP_,
FilePath(GTEST_PATH_SEP_ "afile").RemoveFileName().c_str()); FilePath(GTEST_PATH_SEP_ "afile").RemoveFileName().string());
} }
#if GTEST_HAS_ALT_PATH_SEP_ #if GTEST_HAS_ALT_PATH_SEP_
@@ -231,26 +224,25 @@ TEST(RemoveFileNameTest, GivesRootDir) {
// RemoveFileName("adir/") -> "adir/" // RemoveFileName("adir/") -> "adir/"
TEST(RemoveFileNameTest, ButNoFileForAlternateSeparator) { TEST(RemoveFileNameTest, ButNoFileForAlternateSeparator) {
EXPECT_STREQ("adir" GTEST_PATH_SEP_, EXPECT_EQ("adir" GTEST_PATH_SEP_,
FilePath("adir/").RemoveFileName().c_str()); FilePath("adir/").RemoveFileName().string());
} }
// RemoveFileName("adir/afile") -> "adir/" // RemoveFileName("adir/afile") -> "adir/"
TEST(RemoveFileNameTest, GivesDirNameForAlternateSeparator) { TEST(RemoveFileNameTest, GivesDirNameForAlternateSeparator) {
EXPECT_STREQ("adir" GTEST_PATH_SEP_, EXPECT_EQ("adir" GTEST_PATH_SEP_,
FilePath("adir/afile").RemoveFileName().c_str()); FilePath("adir/afile").RemoveFileName().string());
} }
// RemoveFileName("adir/subdir/afile") -> "adir/subdir/" // RemoveFileName("adir/subdir/afile") -> "adir/subdir/"
TEST(RemoveFileNameTest, GivesDirAndSubDirNameForAlternateSeparator) { TEST(RemoveFileNameTest, GivesDirAndSubDirNameForAlternateSeparator) {
EXPECT_STREQ("adir" GTEST_PATH_SEP_ "subdir" GTEST_PATH_SEP_, EXPECT_EQ("adir" GTEST_PATH_SEP_ "subdir" GTEST_PATH_SEP_,
FilePath("adir/subdir/afile").RemoveFileName().c_str()); FilePath("adir/subdir/afile").RemoveFileName().string());
} }
// RemoveFileName("/afile") -> "\" // RemoveFileName("/afile") -> "\"
TEST(RemoveFileNameTest, GivesRootDirForAlternateSeparator) { TEST(RemoveFileNameTest, GivesRootDirForAlternateSeparator) {
EXPECT_STREQ(GTEST_PATH_SEP_, EXPECT_EQ(GTEST_PATH_SEP_, FilePath("/afile").RemoveFileName().string());
FilePath("/afile").RemoveFileName().c_str());
} }
#endif #endif
@@ -258,125 +250,120 @@ TEST(RemoveFileNameTest, GivesRootDirForAlternateSeparator) {
TEST(MakeFileNameTest, GenerateWhenNumberIsZero) { TEST(MakeFileNameTest, GenerateWhenNumberIsZero) {
FilePath actual = FilePath::MakeFileName(FilePath("foo"), FilePath("bar"), FilePath actual = FilePath::MakeFileName(FilePath("foo"), FilePath("bar"),
0, "xml"); 0, "xml");
EXPECT_STREQ("foo" GTEST_PATH_SEP_ "bar.xml", actual.c_str()); EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar.xml", actual.string());
} }
TEST(MakeFileNameTest, GenerateFileNameNumberGtZero) { TEST(MakeFileNameTest, GenerateFileNameNumberGtZero) {
FilePath actual = FilePath::MakeFileName(FilePath("foo"), FilePath("bar"), FilePath actual = FilePath::MakeFileName(FilePath("foo"), FilePath("bar"),
12, "xml"); 12, "xml");
EXPECT_STREQ("foo" GTEST_PATH_SEP_ "bar_12.xml", actual.c_str()); EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar_12.xml", actual.string());
} }
TEST(MakeFileNameTest, GenerateFileNameWithSlashNumberIsZero) { TEST(MakeFileNameTest, GenerateFileNameWithSlashNumberIsZero) {
FilePath actual = FilePath::MakeFileName(FilePath("foo" GTEST_PATH_SEP_), FilePath actual = FilePath::MakeFileName(FilePath("foo" GTEST_PATH_SEP_),
FilePath("bar"), 0, "xml"); FilePath("bar"), 0, "xml");
EXPECT_STREQ("foo" GTEST_PATH_SEP_ "bar.xml", actual.c_str()); EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar.xml", actual.string());
} }
TEST(MakeFileNameTest, GenerateFileNameWithSlashNumberGtZero) { TEST(MakeFileNameTest, GenerateFileNameWithSlashNumberGtZero) {
FilePath actual = FilePath::MakeFileName(FilePath("foo" GTEST_PATH_SEP_), FilePath actual = FilePath::MakeFileName(FilePath("foo" GTEST_PATH_SEP_),
FilePath("bar"), 12, "xml"); FilePath("bar"), 12, "xml");
EXPECT_STREQ("foo" GTEST_PATH_SEP_ "bar_12.xml", actual.c_str()); EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar_12.xml", actual.string());
} }
TEST(MakeFileNameTest, GenerateWhenNumberIsZeroAndDirIsEmpty) { TEST(MakeFileNameTest, GenerateWhenNumberIsZeroAndDirIsEmpty) {
FilePath actual = FilePath::MakeFileName(FilePath(""), FilePath("bar"), FilePath actual = FilePath::MakeFileName(FilePath(""), FilePath("bar"),
0, "xml"); 0, "xml");
EXPECT_STREQ("bar.xml", actual.c_str()); EXPECT_EQ("bar.xml", actual.string());
} }
TEST(MakeFileNameTest, GenerateWhenNumberIsNotZeroAndDirIsEmpty) { TEST(MakeFileNameTest, GenerateWhenNumberIsNotZeroAndDirIsEmpty) {
FilePath actual = FilePath::MakeFileName(FilePath(""), FilePath("bar"), FilePath actual = FilePath::MakeFileName(FilePath(""), FilePath("bar"),
14, "xml"); 14, "xml");
EXPECT_STREQ("bar_14.xml", actual.c_str()); EXPECT_EQ("bar_14.xml", actual.string());
} }
TEST(ConcatPathsTest, WorksWhenDirDoesNotEndWithPathSep) { TEST(ConcatPathsTest, WorksWhenDirDoesNotEndWithPathSep) {
FilePath actual = FilePath::ConcatPaths(FilePath("foo"), FilePath actual = FilePath::ConcatPaths(FilePath("foo"),
FilePath("bar.xml")); FilePath("bar.xml"));
EXPECT_STREQ("foo" GTEST_PATH_SEP_ "bar.xml", actual.c_str()); EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar.xml", actual.string());
} }
TEST(ConcatPathsTest, WorksWhenPath1EndsWithPathSep) { TEST(ConcatPathsTest, WorksWhenPath1EndsWithPathSep) {
FilePath actual = FilePath::ConcatPaths(FilePath("foo" GTEST_PATH_SEP_), FilePath actual = FilePath::ConcatPaths(FilePath("foo" GTEST_PATH_SEP_),
FilePath("bar.xml")); FilePath("bar.xml"));
EXPECT_STREQ("foo" GTEST_PATH_SEP_ "bar.xml", actual.c_str()); EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar.xml", actual.string());
} }
TEST(ConcatPathsTest, Path1BeingEmpty) { TEST(ConcatPathsTest, Path1BeingEmpty) {
FilePath actual = FilePath::ConcatPaths(FilePath(""), FilePath actual = FilePath::ConcatPaths(FilePath(""),
FilePath("bar.xml")); FilePath("bar.xml"));
EXPECT_STREQ("bar.xml", actual.c_str()); EXPECT_EQ("bar.xml", actual.string());
} }
TEST(ConcatPathsTest, Path2BeingEmpty) { TEST(ConcatPathsTest, Path2BeingEmpty) {
FilePath actual = FilePath::ConcatPaths(FilePath("foo"), FilePath actual = FilePath::ConcatPaths(FilePath("foo"), FilePath(""));
FilePath("")); EXPECT_EQ("foo" GTEST_PATH_SEP_, actual.string());
EXPECT_STREQ("foo" GTEST_PATH_SEP_, actual.c_str());
} }
TEST(ConcatPathsTest, BothPathBeingEmpty) { TEST(ConcatPathsTest, BothPathBeingEmpty) {
FilePath actual = FilePath::ConcatPaths(FilePath(""), FilePath actual = FilePath::ConcatPaths(FilePath(""),
FilePath("")); FilePath(""));
EXPECT_STREQ("", actual.c_str()); EXPECT_EQ("", actual.string());
} }
TEST(ConcatPathsTest, Path1ContainsPathSep) { TEST(ConcatPathsTest, Path1ContainsPathSep) {
FilePath actual = FilePath::ConcatPaths(FilePath("foo" GTEST_PATH_SEP_ "bar"), FilePath actual = FilePath::ConcatPaths(FilePath("foo" GTEST_PATH_SEP_ "bar"),
FilePath("foobar.xml")); FilePath("foobar.xml"));
EXPECT_STREQ("foo" GTEST_PATH_SEP_ "bar" GTEST_PATH_SEP_ "foobar.xml", EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar" GTEST_PATH_SEP_ "foobar.xml",
actual.c_str()); actual.string());
} }
TEST(ConcatPathsTest, Path2ContainsPathSep) { TEST(ConcatPathsTest, Path2ContainsPathSep) {
FilePath actual = FilePath::ConcatPaths( FilePath actual = FilePath::ConcatPaths(
FilePath("foo" GTEST_PATH_SEP_), FilePath("foo" GTEST_PATH_SEP_),
FilePath("bar" GTEST_PATH_SEP_ "bar.xml")); FilePath("bar" GTEST_PATH_SEP_ "bar.xml"));
EXPECT_STREQ("foo" GTEST_PATH_SEP_ "bar" GTEST_PATH_SEP_ "bar.xml", EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar" GTEST_PATH_SEP_ "bar.xml",
actual.c_str()); actual.string());
} }
TEST(ConcatPathsTest, Path2EndsWithPathSep) { TEST(ConcatPathsTest, Path2EndsWithPathSep) {
FilePath actual = FilePath::ConcatPaths(FilePath("foo"), FilePath actual = FilePath::ConcatPaths(FilePath("foo"),
FilePath("bar" GTEST_PATH_SEP_)); FilePath("bar" GTEST_PATH_SEP_));
EXPECT_STREQ("foo" GTEST_PATH_SEP_ "bar" GTEST_PATH_SEP_, actual.c_str()); EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar" GTEST_PATH_SEP_, actual.string());
} }
// RemoveTrailingPathSeparator "" -> "" // RemoveTrailingPathSeparator "" -> ""
TEST(RemoveTrailingPathSeparatorTest, EmptyString) { TEST(RemoveTrailingPathSeparatorTest, EmptyString) {
EXPECT_STREQ("", EXPECT_EQ("", FilePath("").RemoveTrailingPathSeparator().string());
FilePath("").RemoveTrailingPathSeparator().c_str());
} }
// RemoveTrailingPathSeparator "foo" -> "foo" // RemoveTrailingPathSeparator "foo" -> "foo"
TEST(RemoveTrailingPathSeparatorTest, FileNoSlashString) { TEST(RemoveTrailingPathSeparatorTest, FileNoSlashString) {
EXPECT_STREQ("foo", EXPECT_EQ("foo", FilePath("foo").RemoveTrailingPathSeparator().string());
FilePath("foo").RemoveTrailingPathSeparator().c_str());
} }
// RemoveTrailingPathSeparator "foo/" -> "foo" // RemoveTrailingPathSeparator "foo/" -> "foo"
TEST(RemoveTrailingPathSeparatorTest, ShouldRemoveTrailingSeparator) { TEST(RemoveTrailingPathSeparatorTest, ShouldRemoveTrailingSeparator) {
EXPECT_STREQ( EXPECT_EQ("foo",
"foo", FilePath("foo" GTEST_PATH_SEP_).RemoveTrailingPathSeparator().string());
FilePath("foo" GTEST_PATH_SEP_).RemoveTrailingPathSeparator().c_str());
#if GTEST_HAS_ALT_PATH_SEP_ #if GTEST_HAS_ALT_PATH_SEP_
EXPECT_STREQ("foo", EXPECT_EQ("foo", FilePath("foo/").RemoveTrailingPathSeparator().string());
FilePath("foo/").RemoveTrailingPathSeparator().c_str());
#endif #endif
} }
// RemoveTrailingPathSeparator "foo/bar/" -> "foo/bar/" // RemoveTrailingPathSeparator "foo/bar/" -> "foo/bar/"
TEST(RemoveTrailingPathSeparatorTest, ShouldRemoveLastSeparator) { TEST(RemoveTrailingPathSeparatorTest, ShouldRemoveLastSeparator) {
EXPECT_STREQ("foo" GTEST_PATH_SEP_ "bar", EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar",
FilePath("foo" GTEST_PATH_SEP_ "bar" GTEST_PATH_SEP_) FilePath("foo" GTEST_PATH_SEP_ "bar" GTEST_PATH_SEP_)
.RemoveTrailingPathSeparator().c_str()); .RemoveTrailingPathSeparator().string());
} }
// RemoveTrailingPathSeparator "foo/bar" -> "foo/bar" // RemoveTrailingPathSeparator "foo/bar" -> "foo/bar"
TEST(RemoveTrailingPathSeparatorTest, ShouldReturnUnmodified) { TEST(RemoveTrailingPathSeparatorTest, ShouldReturnUnmodified) {
EXPECT_STREQ("foo" GTEST_PATH_SEP_ "bar", EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar",
FilePath("foo" GTEST_PATH_SEP_ "bar") FilePath("foo" GTEST_PATH_SEP_ "bar")
.RemoveTrailingPathSeparator().c_str()); .RemoveTrailingPathSeparator().string());
} }
TEST(DirectoryTest, RootDirectoryExists) { TEST(DirectoryTest, RootDirectoryExists) {
@@ -431,40 +418,35 @@ TEST(DirectoryTest, CurrentDirectoryExists) {
#endif // GTEST_OS_WINDOWS #endif // GTEST_OS_WINDOWS
} }
TEST(NormalizeTest, NullStringsEqualEmptyDirectory) {
EXPECT_STREQ("", FilePath(NULL).c_str());
EXPECT_STREQ("", FilePath(String(NULL)).c_str());
}
// "foo/bar" == foo//bar" == "foo///bar" // "foo/bar" == foo//bar" == "foo///bar"
TEST(NormalizeTest, MultipleConsecutiveSepaparatorsInMidstring) { TEST(NormalizeTest, MultipleConsecutiveSepaparatorsInMidstring) {
EXPECT_STREQ("foo" GTEST_PATH_SEP_ "bar", EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar",
FilePath("foo" GTEST_PATH_SEP_ "bar").c_str()); FilePath("foo" GTEST_PATH_SEP_ "bar").string());
EXPECT_STREQ("foo" GTEST_PATH_SEP_ "bar", EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar",
FilePath("foo" GTEST_PATH_SEP_ GTEST_PATH_SEP_ "bar").c_str()); FilePath("foo" GTEST_PATH_SEP_ GTEST_PATH_SEP_ "bar").string());
EXPECT_STREQ("foo" GTEST_PATH_SEP_ "bar", EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar",
FilePath("foo" GTEST_PATH_SEP_ GTEST_PATH_SEP_ FilePath("foo" GTEST_PATH_SEP_ GTEST_PATH_SEP_
GTEST_PATH_SEP_ "bar").c_str()); GTEST_PATH_SEP_ "bar").string());
} }
// "/bar" == //bar" == "///bar" // "/bar" == //bar" == "///bar"
TEST(NormalizeTest, MultipleConsecutiveSepaparatorsAtStringStart) { TEST(NormalizeTest, MultipleConsecutiveSepaparatorsAtStringStart) {
EXPECT_STREQ(GTEST_PATH_SEP_ "bar", EXPECT_EQ(GTEST_PATH_SEP_ "bar",
FilePath(GTEST_PATH_SEP_ "bar").c_str()); FilePath(GTEST_PATH_SEP_ "bar").string());
EXPECT_STREQ(GTEST_PATH_SEP_ "bar", EXPECT_EQ(GTEST_PATH_SEP_ "bar",
FilePath(GTEST_PATH_SEP_ GTEST_PATH_SEP_ "bar").c_str()); FilePath(GTEST_PATH_SEP_ GTEST_PATH_SEP_ "bar").string());
EXPECT_STREQ(GTEST_PATH_SEP_ "bar", EXPECT_EQ(GTEST_PATH_SEP_ "bar",
FilePath(GTEST_PATH_SEP_ GTEST_PATH_SEP_ GTEST_PATH_SEP_ "bar").c_str()); FilePath(GTEST_PATH_SEP_ GTEST_PATH_SEP_ GTEST_PATH_SEP_ "bar").string());
} }
// "foo/" == foo//" == "foo///" // "foo/" == foo//" == "foo///"
TEST(NormalizeTest, MultipleConsecutiveSepaparatorsAtStringEnd) { TEST(NormalizeTest, MultipleConsecutiveSepaparatorsAtStringEnd) {
EXPECT_STREQ("foo" GTEST_PATH_SEP_, EXPECT_EQ("foo" GTEST_PATH_SEP_,
FilePath("foo" GTEST_PATH_SEP_).c_str()); FilePath("foo" GTEST_PATH_SEP_).string());
EXPECT_STREQ("foo" GTEST_PATH_SEP_, EXPECT_EQ("foo" GTEST_PATH_SEP_,
FilePath("foo" GTEST_PATH_SEP_ GTEST_PATH_SEP_).c_str()); FilePath("foo" GTEST_PATH_SEP_ GTEST_PATH_SEP_).string());
EXPECT_STREQ("foo" GTEST_PATH_SEP_, EXPECT_EQ("foo" GTEST_PATH_SEP_,
FilePath("foo" GTEST_PATH_SEP_ GTEST_PATH_SEP_ GTEST_PATH_SEP_).c_str()); FilePath("foo" GTEST_PATH_SEP_ GTEST_PATH_SEP_ GTEST_PATH_SEP_).string());
} }
#if GTEST_HAS_ALT_PATH_SEP_ #if GTEST_HAS_ALT_PATH_SEP_
@@ -473,12 +455,12 @@ TEST(NormalizeTest, MultipleConsecutiveSepaparatorsAtStringEnd) {
// regardless of their combination (e.g. "foo\" =="foo/\" == // regardless of their combination (e.g. "foo\" =="foo/\" ==
// "foo\\/"). // "foo\\/").
TEST(NormalizeTest, MixAlternateSeparatorAtStringEnd) { TEST(NormalizeTest, MixAlternateSeparatorAtStringEnd) {
EXPECT_STREQ("foo" GTEST_PATH_SEP_, EXPECT_EQ("foo" GTEST_PATH_SEP_,
FilePath("foo/").c_str()); FilePath("foo/").string());
EXPECT_STREQ("foo" GTEST_PATH_SEP_, EXPECT_EQ("foo" GTEST_PATH_SEP_,
FilePath("foo" GTEST_PATH_SEP_ "/").c_str()); FilePath("foo" GTEST_PATH_SEP_ "/").string());
EXPECT_STREQ("foo" GTEST_PATH_SEP_, EXPECT_EQ("foo" GTEST_PATH_SEP_,
FilePath("foo//" GTEST_PATH_SEP_).c_str()); FilePath("foo//" GTEST_PATH_SEP_).string());
} }
#endif #endif
@@ -487,31 +469,31 @@ TEST(AssignmentOperatorTest, DefaultAssignedToNonDefault) {
FilePath default_path; FilePath default_path;
FilePath non_default_path("path"); FilePath non_default_path("path");
non_default_path = default_path; non_default_path = default_path;
EXPECT_STREQ("", non_default_path.c_str()); EXPECT_EQ("", non_default_path.string());
EXPECT_STREQ("", default_path.c_str()); // RHS var is unchanged. EXPECT_EQ("", default_path.string()); // RHS var is unchanged.
} }
TEST(AssignmentOperatorTest, NonDefaultAssignedToDefault) { TEST(AssignmentOperatorTest, NonDefaultAssignedToDefault) {
FilePath non_default_path("path"); FilePath non_default_path("path");
FilePath default_path; FilePath default_path;
default_path = non_default_path; default_path = non_default_path;
EXPECT_STREQ("path", default_path.c_str()); EXPECT_EQ("path", default_path.string());
EXPECT_STREQ("path", non_default_path.c_str()); // RHS var is unchanged. EXPECT_EQ("path", non_default_path.string()); // RHS var is unchanged.
} }
TEST(AssignmentOperatorTest, ConstAssignedToNonConst) { TEST(AssignmentOperatorTest, ConstAssignedToNonConst) {
const FilePath const_default_path("const_path"); const FilePath const_default_path("const_path");
FilePath non_default_path("path"); FilePath non_default_path("path");
non_default_path = const_default_path; non_default_path = const_default_path;
EXPECT_STREQ("const_path", non_default_path.c_str()); EXPECT_EQ("const_path", non_default_path.string());
} }
class DirectoryCreationTest : public Test { class DirectoryCreationTest : public Test {
protected: protected:
virtual void SetUp() { virtual void SetUp() {
testdata_path_.Set(FilePath(String::Format("%s%s%s", testdata_path_.Set(FilePath(
TempDir().c_str(), GetCurrentExecutableName().c_str(), TempDir() + GetCurrentExecutableName().string() +
"_directory_creation" GTEST_PATH_SEP_ "test" GTEST_PATH_SEP_))); "_directory_creation" GTEST_PATH_SEP_ "test" GTEST_PATH_SEP_));
testdata_file_.Set(testdata_path_.RemoveTrailingPathSeparator()); testdata_file_.Set(testdata_path_.RemoveTrailingPathSeparator());
unique_file0_.Set(FilePath::MakeFileName(testdata_path_, FilePath("unique"), unique_file0_.Set(FilePath::MakeFileName(testdata_path_, FilePath("unique"),
@@ -532,19 +514,21 @@ class DirectoryCreationTest : public Test {
posix::RmDir(testdata_path_.c_str()); posix::RmDir(testdata_path_.c_str());
} }
String TempDir() const { std::string TempDir() const {
#if GTEST_OS_WINDOWS_MOBILE #if GTEST_OS_WINDOWS_MOBILE
return String("\\temp\\"); return "\\temp\\";
#elif GTEST_OS_WINDOWS #elif GTEST_OS_WINDOWS
const char* temp_dir = posix::GetEnv("TEMP"); const char* temp_dir = posix::GetEnv("TEMP");
if (temp_dir == NULL || temp_dir[0] == '\0') if (temp_dir == NULL || temp_dir[0] == '\0')
return String("\\temp\\"); return "\\temp\\";
else if (String(temp_dir).EndsWith("\\")) else if (temp_dir[strlen(temp_dir) - 1] == '\\')
return String(temp_dir); return temp_dir;
else else
return String::Format("%s\\", temp_dir); return std::string(temp_dir) + "\\";
#elif GTEST_OS_LINUX_ANDROID
return "/sdcard/";
#else #else
return String("/tmp/"); return "/tmp/";
#endif // GTEST_OS_WINDOWS_MOBILE #endif // GTEST_OS_WINDOWS_MOBILE
} }
@@ -564,13 +548,13 @@ class DirectoryCreationTest : public Test {
}; };
TEST_F(DirectoryCreationTest, CreateDirectoriesRecursively) { TEST_F(DirectoryCreationTest, CreateDirectoriesRecursively) {
EXPECT_FALSE(testdata_path_.DirectoryExists()) << testdata_path_.c_str(); EXPECT_FALSE(testdata_path_.DirectoryExists()) << testdata_path_.string();
EXPECT_TRUE(testdata_path_.CreateDirectoriesRecursively()); EXPECT_TRUE(testdata_path_.CreateDirectoriesRecursively());
EXPECT_TRUE(testdata_path_.DirectoryExists()); EXPECT_TRUE(testdata_path_.DirectoryExists());
} }
TEST_F(DirectoryCreationTest, CreateDirectoriesForAlreadyExistingPath) { TEST_F(DirectoryCreationTest, CreateDirectoriesForAlreadyExistingPath) {
EXPECT_FALSE(testdata_path_.DirectoryExists()) << testdata_path_.c_str(); EXPECT_FALSE(testdata_path_.DirectoryExists()) << testdata_path_.string();
EXPECT_TRUE(testdata_path_.CreateDirectoriesRecursively()); EXPECT_TRUE(testdata_path_.CreateDirectoriesRecursively());
// Call 'create' again... should still succeed. // Call 'create' again... should still succeed.
EXPECT_TRUE(testdata_path_.CreateDirectoriesRecursively()); EXPECT_TRUE(testdata_path_.CreateDirectoriesRecursively());
@@ -579,7 +563,7 @@ TEST_F(DirectoryCreationTest, CreateDirectoriesForAlreadyExistingPath) {
TEST_F(DirectoryCreationTest, CreateDirectoriesAndUniqueFilename) { TEST_F(DirectoryCreationTest, CreateDirectoriesAndUniqueFilename) {
FilePath file_path(FilePath::GenerateUniqueFileName(testdata_path_, FilePath file_path(FilePath::GenerateUniqueFileName(testdata_path_,
FilePath("unique"), "txt")); FilePath("unique"), "txt"));
EXPECT_STREQ(unique_file0_.c_str(), file_path.c_str()); EXPECT_EQ(unique_file0_.string(), file_path.string());
EXPECT_FALSE(file_path.FileOrDirectoryExists()); // file not there EXPECT_FALSE(file_path.FileOrDirectoryExists()); // file not there
testdata_path_.CreateDirectoriesRecursively(); testdata_path_.CreateDirectoriesRecursively();
@@ -589,7 +573,7 @@ TEST_F(DirectoryCreationTest, CreateDirectoriesAndUniqueFilename) {
FilePath file_path2(FilePath::GenerateUniqueFileName(testdata_path_, FilePath file_path2(FilePath::GenerateUniqueFileName(testdata_path_,
FilePath("unique"), "txt")); FilePath("unique"), "txt"));
EXPECT_STREQ(unique_file1_.c_str(), file_path2.c_str()); EXPECT_EQ(unique_file1_.string(), file_path2.string());
EXPECT_FALSE(file_path2.FileOrDirectoryExists()); // file not there EXPECT_FALSE(file_path2.FileOrDirectoryExists()); // file not there
CreateTextFile(file_path2.c_str()); CreateTextFile(file_path2.c_str());
EXPECT_TRUE(file_path2.FileOrDirectoryExists()); EXPECT_TRUE(file_path2.FileOrDirectoryExists());
@@ -610,43 +594,43 @@ TEST(NoDirectoryCreationTest, CreateNoDirectoriesForDefaultXmlFile) {
TEST(FilePathTest, DefaultConstructor) { TEST(FilePathTest, DefaultConstructor) {
FilePath fp; FilePath fp;
EXPECT_STREQ("", fp.c_str()); EXPECT_EQ("", fp.string());
} }
TEST(FilePathTest, CharAndCopyConstructors) { TEST(FilePathTest, CharAndCopyConstructors) {
const FilePath fp("spicy"); const FilePath fp("spicy");
EXPECT_STREQ("spicy", fp.c_str()); EXPECT_EQ("spicy", fp.string());
const FilePath fp_copy(fp); const FilePath fp_copy(fp);
EXPECT_STREQ("spicy", fp_copy.c_str()); EXPECT_EQ("spicy", fp_copy.string());
} }
TEST(FilePathTest, StringConstructor) { TEST(FilePathTest, StringConstructor) {
const FilePath fp(String("cider")); const FilePath fp(std::string("cider"));
EXPECT_STREQ("cider", fp.c_str()); EXPECT_EQ("cider", fp.string());
} }
TEST(FilePathTest, Set) { TEST(FilePathTest, Set) {
const FilePath apple("apple"); const FilePath apple("apple");
FilePath mac("mac"); FilePath mac("mac");
mac.Set(apple); // Implement Set() since overloading operator= is forbidden. mac.Set(apple); // Implement Set() since overloading operator= is forbidden.
EXPECT_STREQ("apple", mac.c_str()); EXPECT_EQ("apple", mac.string());
EXPECT_STREQ("apple", apple.c_str()); EXPECT_EQ("apple", apple.string());
} }
TEST(FilePathTest, ToString) { TEST(FilePathTest, ToString) {
const FilePath file("drink"); const FilePath file("drink");
String str(file.ToString()); EXPECT_EQ("drink", file.string());
EXPECT_STREQ("drink", str.c_str());
} }
TEST(FilePathTest, RemoveExtension) { TEST(FilePathTest, RemoveExtension) {
EXPECT_STREQ("app", FilePath("app.exe").RemoveExtension("exe").c_str()); EXPECT_EQ("app", FilePath("app.cc").RemoveExtension("cc").string());
EXPECT_STREQ("APP", FilePath("APP.EXE").RemoveExtension("exe").c_str()); EXPECT_EQ("app", FilePath("app.exe").RemoveExtension("exe").string());
EXPECT_EQ("APP", FilePath("APP.EXE").RemoveExtension("exe").string());
} }
TEST(FilePathTest, RemoveExtensionWhenThereIsNoExtension) { TEST(FilePathTest, RemoveExtensionWhenThereIsNoExtension) {
EXPECT_STREQ("app", FilePath("app").RemoveExtension("exe").c_str()); EXPECT_EQ("app", FilePath("app").RemoveExtension("exe").string());
} }
TEST(FilePathTest, IsDirectory) { TEST(FilePathTest, IsDirectory) {
+1 -2
View File
@@ -148,8 +148,7 @@ TEST_F(LinkedPtrTest, GeneralTest) {
"A0 dtor\n" "A0 dtor\n"
"A3 dtor\n" "A3 dtor\n"
"A1 dtor\n", "A1 dtor\n",
history->GetString().c_str() history->GetString().c_str());
);
} }
} // Unnamed namespace } // Unnamed namespace
+15 -18
View File
@@ -45,17 +45,16 @@ using ::testing::TestEventListener;
using ::testing::TestInfo; using ::testing::TestInfo;
using ::testing::TestPartResult; using ::testing::TestPartResult;
using ::testing::UnitTest; using ::testing::UnitTest;
using ::testing::internal::String;
// Used by tests to register their events. // Used by tests to register their events.
std::vector<String>* g_events = NULL; std::vector<std::string>* g_events = NULL;
namespace testing { namespace testing {
namespace internal { namespace internal {
class EventRecordingListener : public TestEventListener { class EventRecordingListener : public TestEventListener {
public: public:
EventRecordingListener(const char* name) : name_(name) {} explicit EventRecordingListener(const char* name) : name_(name) {}
protected: protected:
virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) { virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) {
@@ -119,54 +118,52 @@ class EventRecordingListener : public TestEventListener {
} }
private: private:
String GetFullMethodName(const char* name) { std::string GetFullMethodName(const char* name) {
Message message; return name_ + "." + name;
message << name_ << "." << name;
return message.GetString();
} }
String name_; std::string name_;
}; };
class EnvironmentInvocationCatcher : public Environment { class EnvironmentInvocationCatcher : public Environment {
protected: protected:
virtual void SetUp() { virtual void SetUp() {
g_events->push_back(String("Environment::SetUp")); g_events->push_back("Environment::SetUp");
} }
virtual void TearDown() { virtual void TearDown() {
g_events->push_back(String("Environment::TearDown")); g_events->push_back("Environment::TearDown");
} }
}; };
class ListenerTest : public Test { class ListenerTest : public Test {
protected: protected:
static void SetUpTestCase() { static void SetUpTestCase() {
g_events->push_back(String("ListenerTest::SetUpTestCase")); g_events->push_back("ListenerTest::SetUpTestCase");
} }
static void TearDownTestCase() { static void TearDownTestCase() {
g_events->push_back(String("ListenerTest::TearDownTestCase")); g_events->push_back("ListenerTest::TearDownTestCase");
} }
virtual void SetUp() { virtual void SetUp() {
g_events->push_back(String("ListenerTest::SetUp")); g_events->push_back("ListenerTest::SetUp");
} }
virtual void TearDown() { virtual void TearDown() {
g_events->push_back(String("ListenerTest::TearDown")); g_events->push_back("ListenerTest::TearDown");
} }
}; };
TEST_F(ListenerTest, DoesFoo) { TEST_F(ListenerTest, DoesFoo) {
// Test execution order within a test case is not guaranteed so we are not // Test execution order within a test case is not guaranteed so we are not
// recording the test name. // recording the test name.
g_events->push_back(String("ListenerTest::* Test Body")); g_events->push_back("ListenerTest::* Test Body");
SUCCEED(); // Triggers OnTestPartResult. SUCCEED(); // Triggers OnTestPartResult.
} }
TEST_F(ListenerTest, DoesBar) { TEST_F(ListenerTest, DoesBar) {
g_events->push_back(String("ListenerTest::* Test Body")); g_events->push_back("ListenerTest::* Test Body");
SUCCEED(); // Triggers OnTestPartResult. SUCCEED(); // Triggers OnTestPartResult.
} }
@@ -177,7 +174,7 @@ TEST_F(ListenerTest, DoesBar) {
using ::testing::internal::EnvironmentInvocationCatcher; using ::testing::internal::EnvironmentInvocationCatcher;
using ::testing::internal::EventRecordingListener; using ::testing::internal::EventRecordingListener;
void VerifyResults(const std::vector<String>& data, void VerifyResults(const std::vector<std::string>& data,
const char* const* expected_data, const char* const* expected_data,
int expected_data_size) { int expected_data_size) {
const int actual_size = data.size(); const int actual_size = data.size();
@@ -201,7 +198,7 @@ void VerifyResults(const std::vector<String>& data,
} }
int main(int argc, char **argv) { int main(int argc, char **argv) {
std::vector<String> events; std::vector<std::string> events;
g_events = &events; g_events = &events;
InitGoogleTest(&argc, argv); InitGoogleTest(&argc, argv);
+24 -31
View File
@@ -39,79 +39,72 @@ namespace {
using ::testing::Message; using ::testing::Message;
// A helper function that turns a Message into a C string.
const char* ToCString(const Message& msg) {
static testing::internal::String result;
result = msg.GetString();
return result.c_str();
}
// Tests the testing::Message class // Tests the testing::Message class
// Tests the default constructor. // Tests the default constructor.
TEST(MessageTest, DefaultConstructor) { TEST(MessageTest, DefaultConstructor) {
const Message msg; const Message msg;
EXPECT_STREQ("", ToCString(msg)); EXPECT_EQ("", msg.GetString());
} }
// Tests the copy constructor. // Tests the copy constructor.
TEST(MessageTest, CopyConstructor) { TEST(MessageTest, CopyConstructor) {
const Message msg1("Hello"); const Message msg1("Hello");
const Message msg2(msg1); const Message msg2(msg1);
EXPECT_STREQ("Hello", ToCString(msg2)); EXPECT_EQ("Hello", msg2.GetString());
} }
// Tests constructing a Message from a C-string. // Tests constructing a Message from a C-string.
TEST(MessageTest, ConstructsFromCString) { TEST(MessageTest, ConstructsFromCString) {
Message msg("Hello"); Message msg("Hello");
EXPECT_STREQ("Hello", ToCString(msg)); EXPECT_EQ("Hello", msg.GetString());
} }
// Tests streaming a float. // Tests streaming a float.
TEST(MessageTest, StreamsFloat) { TEST(MessageTest, StreamsFloat) {
const char* const s = ToCString(Message() << 1.23456F << " " << 2.34567F); const std::string s = (Message() << 1.23456F << " " << 2.34567F).GetString();
// Both numbers should be printed with enough precision. // Both numbers should be printed with enough precision.
EXPECT_PRED_FORMAT2(testing::IsSubstring, "1.234560", s); EXPECT_PRED_FORMAT2(testing::IsSubstring, "1.234560", s.c_str());
EXPECT_PRED_FORMAT2(testing::IsSubstring, " 2.345669", s); EXPECT_PRED_FORMAT2(testing::IsSubstring, " 2.345669", s.c_str());
} }
// Tests streaming a double. // Tests streaming a double.
TEST(MessageTest, StreamsDouble) { TEST(MessageTest, StreamsDouble) {
const char* const s = ToCString(Message() << 1260570880.4555497 << " " const std::string s = (Message() << 1260570880.4555497 << " "
<< 1260572265.1954534); << 1260572265.1954534).GetString();
// Both numbers should be printed with enough precision. // Both numbers should be printed with enough precision.
EXPECT_PRED_FORMAT2(testing::IsSubstring, "1260570880.45", s); EXPECT_PRED_FORMAT2(testing::IsSubstring, "1260570880.45", s.c_str());
EXPECT_PRED_FORMAT2(testing::IsSubstring, " 1260572265.19", s); EXPECT_PRED_FORMAT2(testing::IsSubstring, " 1260572265.19", s.c_str());
} }
// Tests streaming a non-char pointer. // Tests streaming a non-char pointer.
TEST(MessageTest, StreamsPointer) { TEST(MessageTest, StreamsPointer) {
int n = 0; int n = 0;
int* p = &n; int* p = &n;
EXPECT_STRNE("(null)", ToCString(Message() << p)); EXPECT_NE("(null)", (Message() << p).GetString());
} }
// Tests streaming a NULL non-char pointer. // Tests streaming a NULL non-char pointer.
TEST(MessageTest, StreamsNullPointer) { TEST(MessageTest, StreamsNullPointer) {
int* p = NULL; int* p = NULL;
EXPECT_STREQ("(null)", ToCString(Message() << p)); EXPECT_EQ("(null)", (Message() << p).GetString());
} }
// Tests streaming a C string. // Tests streaming a C string.
TEST(MessageTest, StreamsCString) { TEST(MessageTest, StreamsCString) {
EXPECT_STREQ("Foo", ToCString(Message() << "Foo")); EXPECT_EQ("Foo", (Message() << "Foo").GetString());
} }
// Tests streaming a NULL C string. // Tests streaming a NULL C string.
TEST(MessageTest, StreamsNullCString) { TEST(MessageTest, StreamsNullCString) {
char* p = NULL; char* p = NULL;
EXPECT_STREQ("(null)", ToCString(Message() << p)); EXPECT_EQ("(null)", (Message() << p).GetString());
} }
// Tests streaming std::string. // Tests streaming std::string.
TEST(MessageTest, StreamsString) { TEST(MessageTest, StreamsString) {
const ::std::string str("Hello"); const ::std::string str("Hello");
EXPECT_STREQ("Hello", ToCString(Message() << str)); EXPECT_EQ("Hello", (Message() << str).GetString());
} }
// Tests that we can output strings containing embedded NULs. // Tests that we can output strings containing embedded NULs.
@@ -120,34 +113,34 @@ TEST(MessageTest, StreamsStringWithEmbeddedNUL) {
"Here's a NUL\0 and some more string"; "Here's a NUL\0 and some more string";
const ::std::string string_with_nul(char_array_with_nul, const ::std::string string_with_nul(char_array_with_nul,
sizeof(char_array_with_nul) - 1); sizeof(char_array_with_nul) - 1);
EXPECT_STREQ("Here's a NUL\\0 and some more string", EXPECT_EQ("Here's a NUL\\0 and some more string",
ToCString(Message() << string_with_nul)); (Message() << string_with_nul).GetString());
} }
// Tests streaming a NUL char. // Tests streaming a NUL char.
TEST(MessageTest, StreamsNULChar) { TEST(MessageTest, StreamsNULChar) {
EXPECT_STREQ("\\0", ToCString(Message() << '\0')); EXPECT_EQ("\\0", (Message() << '\0').GetString());
} }
// Tests streaming int. // Tests streaming int.
TEST(MessageTest, StreamsInt) { TEST(MessageTest, StreamsInt) {
EXPECT_STREQ("123", ToCString(Message() << 123)); EXPECT_EQ("123", (Message() << 123).GetString());
} }
// Tests that basic IO manipulators (endl, ends, and flush) can be // Tests that basic IO manipulators (endl, ends, and flush) can be
// streamed to Message. // streamed to Message.
TEST(MessageTest, StreamsBasicIoManip) { TEST(MessageTest, StreamsBasicIoManip) {
EXPECT_STREQ("Line 1.\nA NUL char \\0 in line 2.", EXPECT_EQ("Line 1.\nA NUL char \\0 in line 2.",
ToCString(Message() << "Line 1." << std::endl (Message() << "Line 1." << std::endl
<< "A NUL char " << std::ends << std::flush << "A NUL char " << std::ends << std::flush
<< " in line 2.")); << " in line 2.").GetString());
} }
// Tests Message::GetString() // Tests Message::GetString()
TEST(MessageTest, GetString) { TEST(MessageTest, GetString) {
Message msg; Message msg;
msg << 1 << " lamb"; msg << 1 << " lamb";
EXPECT_STREQ("1 lamb", msg.GetString().c_str()); EXPECT_EQ("1 lamb", msg.GetString());
} }
// Tests streaming a Message object to an ostream. // Tests streaming a Message object to an ostream.
@@ -155,7 +148,7 @@ TEST(MessageTest, StreamsToOStream) {
Message msg("Hello"); Message msg("Hello");
::std::stringstream ss; ::std::stringstream ss;
ss << msg; ss << msg;
EXPECT_STREQ("Hello", testing::internal::StringStreamToString(&ss).c_str()); EXPECT_EQ("Hello", testing::internal::StringStreamToString(&ss));
} }
// Tests that a Message object doesn't take up too much stack space. // Tests that a Message object doesn't take up too much stack space.
+30 -27
View File
@@ -78,14 +78,14 @@ TEST(XmlOutputTest, GetOutputFormat) {
TEST(XmlOutputTest, GetOutputFileDefault) { TEST(XmlOutputTest, GetOutputFileDefault) {
GTEST_FLAG(output) = ""; GTEST_FLAG(output) = "";
EXPECT_STREQ(GetAbsolutePathOf(FilePath("test_detail.xml")).c_str(), EXPECT_EQ(GetAbsolutePathOf(FilePath("test_detail.xml")).string(),
UnitTestOptions::GetAbsolutePathToOutputFile().c_str()); UnitTestOptions::GetAbsolutePathToOutputFile());
} }
TEST(XmlOutputTest, GetOutputFileSingleFile) { TEST(XmlOutputTest, GetOutputFileSingleFile) {
GTEST_FLAG(output) = "xml:filename.abc"; GTEST_FLAG(output) = "xml:filename.abc";
EXPECT_STREQ(GetAbsolutePathOf(FilePath("filename.abc")).c_str(), EXPECT_EQ(GetAbsolutePathOf(FilePath("filename.abc")).string(),
UnitTestOptions::GetAbsolutePathToOutputFile().c_str()); UnitTestOptions::GetAbsolutePathToOutputFile());
} }
TEST(XmlOutputTest, GetOutputFileFromDirectoryPath) { TEST(XmlOutputTest, GetOutputFileFromDirectoryPath) {
@@ -93,8 +93,9 @@ TEST(XmlOutputTest, GetOutputFileFromDirectoryPath) {
const std::string expected_output_file = const std::string expected_output_file =
GetAbsolutePathOf( GetAbsolutePathOf(
FilePath(std::string("path") + GTEST_PATH_SEP_ + FilePath(std::string("path") + GTEST_PATH_SEP_ +
GetCurrentExecutableName().c_str() + ".xml")).c_str(); GetCurrentExecutableName().string() + ".xml")).string();
const String& output_file = UnitTestOptions::GetAbsolutePathToOutputFile(); const std::string& output_file =
UnitTestOptions::GetAbsolutePathToOutputFile();
#if GTEST_OS_WINDOWS #if GTEST_OS_WINDOWS
EXPECT_STRCASEEQ(expected_output_file.c_str(), output_file.c_str()); EXPECT_STRCASEEQ(expected_output_file.c_str(), output_file.c_str());
#else #else
@@ -103,7 +104,7 @@ TEST(XmlOutputTest, GetOutputFileFromDirectoryPath) {
} }
TEST(OutputFileHelpersTest, GetCurrentExecutableName) { TEST(OutputFileHelpersTest, GetCurrentExecutableName) {
const std::string exe_str = GetCurrentExecutableName().c_str(); const std::string exe_str = GetCurrentExecutableName().string();
#if GTEST_OS_WINDOWS #if GTEST_OS_WINDOWS
const bool success = const bool success =
_strcmpi("gtest-options_test", exe_str.c_str()) == 0 || _strcmpi("gtest-options_test", exe_str.c_str()) == 0 ||
@@ -129,12 +130,12 @@ class XmlOutputChangeDirTest : public Test {
original_working_dir_ = FilePath::GetCurrentDir(); original_working_dir_ = FilePath::GetCurrentDir();
posix::ChDir(".."); posix::ChDir("..");
// This will make the test fail if run from the root directory. // This will make the test fail if run from the root directory.
EXPECT_STRNE(original_working_dir_.c_str(), EXPECT_NE(original_working_dir_.string(),
FilePath::GetCurrentDir().c_str()); FilePath::GetCurrentDir().string());
} }
virtual void TearDown() { virtual void TearDown() {
posix::ChDir(original_working_dir_.c_str()); posix::ChDir(original_working_dir_.string().c_str());
} }
FilePath original_working_dir_; FilePath original_working_dir_;
@@ -142,23 +143,23 @@ class XmlOutputChangeDirTest : public Test {
TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithDefault) { TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithDefault) {
GTEST_FLAG(output) = ""; GTEST_FLAG(output) = "";
EXPECT_STREQ(FilePath::ConcatPaths(original_working_dir_, EXPECT_EQ(FilePath::ConcatPaths(original_working_dir_,
FilePath("test_detail.xml")).c_str(), FilePath("test_detail.xml")).string(),
UnitTestOptions::GetAbsolutePathToOutputFile().c_str()); UnitTestOptions::GetAbsolutePathToOutputFile());
} }
TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithDefaultXML) { TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithDefaultXML) {
GTEST_FLAG(output) = "xml"; GTEST_FLAG(output) = "xml";
EXPECT_STREQ(FilePath::ConcatPaths(original_working_dir_, EXPECT_EQ(FilePath::ConcatPaths(original_working_dir_,
FilePath("test_detail.xml")).c_str(), FilePath("test_detail.xml")).string(),
UnitTestOptions::GetAbsolutePathToOutputFile().c_str()); UnitTestOptions::GetAbsolutePathToOutputFile());
} }
TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithRelativeFile) { TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithRelativeFile) {
GTEST_FLAG(output) = "xml:filename.abc"; GTEST_FLAG(output) = "xml:filename.abc";
EXPECT_STREQ(FilePath::ConcatPaths(original_working_dir_, EXPECT_EQ(FilePath::ConcatPaths(original_working_dir_,
FilePath("filename.abc")).c_str(), FilePath("filename.abc")).string(),
UnitTestOptions::GetAbsolutePathToOutputFile().c_str()); UnitTestOptions::GetAbsolutePathToOutputFile());
} }
TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithRelativePath) { TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithRelativePath) {
@@ -167,8 +168,9 @@ TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithRelativePath) {
FilePath::ConcatPaths( FilePath::ConcatPaths(
original_working_dir_, original_working_dir_,
FilePath(std::string("path") + GTEST_PATH_SEP_ + FilePath(std::string("path") + GTEST_PATH_SEP_ +
GetCurrentExecutableName().c_str() + ".xml")).c_str(); GetCurrentExecutableName().string() + ".xml")).string();
const String& output_file = UnitTestOptions::GetAbsolutePathToOutputFile(); const std::string& output_file =
UnitTestOptions::GetAbsolutePathToOutputFile();
#if GTEST_OS_WINDOWS #if GTEST_OS_WINDOWS
EXPECT_STRCASEEQ(expected_output_file.c_str(), output_file.c_str()); EXPECT_STRCASEEQ(expected_output_file.c_str(), output_file.c_str());
#else #else
@@ -179,12 +181,12 @@ TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithRelativePath) {
TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithAbsoluteFile) { TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithAbsoluteFile) {
#if GTEST_OS_WINDOWS #if GTEST_OS_WINDOWS
GTEST_FLAG(output) = "xml:c:\\tmp\\filename.abc"; GTEST_FLAG(output) = "xml:c:\\tmp\\filename.abc";
EXPECT_STREQ(FilePath("c:\\tmp\\filename.abc").c_str(), EXPECT_EQ(FilePath("c:\\tmp\\filename.abc").string(),
UnitTestOptions::GetAbsolutePathToOutputFile().c_str()); UnitTestOptions::GetAbsolutePathToOutputFile());
#else #else
GTEST_FLAG(output) ="xml:/tmp/filename.abc"; GTEST_FLAG(output) ="xml:/tmp/filename.abc";
EXPECT_STREQ(FilePath("/tmp/filename.abc").c_str(), EXPECT_EQ(FilePath("/tmp/filename.abc").string(),
UnitTestOptions::GetAbsolutePathToOutputFile().c_str()); UnitTestOptions::GetAbsolutePathToOutputFile());
#endif #endif
} }
@@ -197,8 +199,9 @@ TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithAbsolutePath) {
GTEST_FLAG(output) = "xml:" + path; GTEST_FLAG(output) = "xml:" + path;
const std::string expected_output_file = const std::string expected_output_file =
path + GetCurrentExecutableName().c_str() + ".xml"; path + GetCurrentExecutableName().string() + ".xml";
const String& output_file = UnitTestOptions::GetAbsolutePathToOutputFile(); const std::string& output_file =
UnitTestOptions::GetAbsolutePathToOutputFile();
#if GTEST_OS_WINDOWS #if GTEST_OS_WINDOWS
EXPECT_STRCASEEQ(expected_output_file.c_str(), output_file.c_str()); EXPECT_STRCASEEQ(expected_output_file.c_str(), output_file.c_str());
+11 -2
View File
@@ -280,10 +280,10 @@ class DogAdder {
bool operator<(const DogAdder& other) const { bool operator<(const DogAdder& other) const {
return value_ < other.value_; return value_ < other.value_;
} }
const ::testing::internal::String& value() const { return value_; } const std::string& value() const { return value_; }
private: private:
::testing::internal::String value_; std::string value_;
}; };
TEST(RangeTest, WorksWithACustomType) { TEST(RangeTest, WorksWithACustomType) {
@@ -606,6 +606,7 @@ class TestGenerationEnvironment : public ::testing::Environment {
<< "has not been run as expected."; << "has not been run as expected.";
} }
} }
private: private:
TestGenerationEnvironment() : fixture_constructor_count_(0), set_up_count_(0), TestGenerationEnvironment() : fixture_constructor_count_(0), set_up_count_(0),
tear_down_count_(0), test_body_count_(0) {} tear_down_count_(0), test_body_count_(0) {}
@@ -674,6 +675,7 @@ class TestGenerationTest : public TestWithParam<int> {
EXPECT_TRUE(collected_parameters_ == expected_values); EXPECT_TRUE(collected_parameters_ == expected_values);
} }
protected: protected:
int current_parameter_; int current_parameter_;
static vector<int> collected_parameters_; static vector<int> collected_parameters_;
@@ -863,6 +865,13 @@ TEST_P(ParameterizedDerivedTest, SeesSequence) {
EXPECT_EQ(GetParam(), global_count_++); EXPECT_EQ(GetParam(), global_count_++);
} }
class ParameterizedDeathTest : public ::testing::TestWithParam<int> { };
TEST_F(ParameterizedDeathTest, GetParamDiesFromTestF) {
EXPECT_DEATH_IF_SUPPORTED(GetParam(),
".* value-parameterized test .*");
}
INSTANTIATE_TEST_CASE_P(RangeZeroToFive, ParameterizedDerivedTest, Range(0, 5)); INSTANTIATE_TEST_CASE_P(RangeZeroToFive, ParameterizedDerivedTest, Range(0, 5));
#endif // GTEST_HAS_PARAM_TEST #endif // GTEST_HAS_PARAM_TEST
+4 -2
View File
@@ -43,12 +43,14 @@
// Test fixture for testing definition and instantiation of a test // Test fixture for testing definition and instantiation of a test
// in separate translation units. // in separate translation units.
class ExternalInstantiationTest : public ::testing::TestWithParam<int> {}; class ExternalInstantiationTest : public ::testing::TestWithParam<int> {
};
// Test fixture for testing instantiation of a test in multiple // Test fixture for testing instantiation of a test in multiple
// translation units. // translation units.
class InstantiationInMultipleTranslaionUnitsTest class InstantiationInMultipleTranslaionUnitsTest
: public ::testing::TestWithParam<int> {}; : public ::testing::TestWithParam<int> {
};
#endif // GTEST_HAS_PARAM_TEST #endif // GTEST_HAS_PARAM_TEST
+85 -38
View File
@@ -61,6 +61,43 @@ using std::pair;
namespace testing { namespace testing {
namespace internal { namespace internal {
TEST(IsXDigitTest, WorksForNarrowAscii) {
EXPECT_TRUE(IsXDigit('0'));
EXPECT_TRUE(IsXDigit('9'));
EXPECT_TRUE(IsXDigit('A'));
EXPECT_TRUE(IsXDigit('F'));
EXPECT_TRUE(IsXDigit('a'));
EXPECT_TRUE(IsXDigit('f'));
EXPECT_FALSE(IsXDigit('-'));
EXPECT_FALSE(IsXDigit('g'));
EXPECT_FALSE(IsXDigit('G'));
}
TEST(IsXDigitTest, ReturnsFalseForNarrowNonAscii) {
EXPECT_FALSE(IsXDigit(static_cast<char>(0x80)));
EXPECT_FALSE(IsXDigit(static_cast<char>('0' | 0x80)));
}
TEST(IsXDigitTest, WorksForWideAscii) {
EXPECT_TRUE(IsXDigit(L'0'));
EXPECT_TRUE(IsXDigit(L'9'));
EXPECT_TRUE(IsXDigit(L'A'));
EXPECT_TRUE(IsXDigit(L'F'));
EXPECT_TRUE(IsXDigit(L'a'));
EXPECT_TRUE(IsXDigit(L'f'));
EXPECT_FALSE(IsXDigit(L'-'));
EXPECT_FALSE(IsXDigit(L'g'));
EXPECT_FALSE(IsXDigit(L'G'));
}
TEST(IsXDigitTest, ReturnsFalseForWideNonAscii) {
EXPECT_FALSE(IsXDigit(static_cast<wchar_t>(0x80)));
EXPECT_FALSE(IsXDigit(static_cast<wchar_t>(L'0' | 0x80)));
EXPECT_FALSE(IsXDigit(static_cast<wchar_t>(L'0' | 0x100)));
}
class Base { class Base {
public: public:
// Copy constructor and assignment operator do exactly what we need, so we // Copy constructor and assignment operator do exactly what we need, so we
@@ -92,7 +129,7 @@ TEST(ImplicitCastTest, CanUseInheritance) {
class Castable { class Castable {
public: public:
Castable(bool* converted) : converted_(converted) {} explicit Castable(bool* converted) : converted_(converted) {}
operator Base() { operator Base() {
*converted_ = true; *converted_ = true;
return Base(); return Base();
@@ -111,7 +148,7 @@ TEST(ImplicitCastTest, CanUseNonConstCastOperator) {
class ConstCastable { class ConstCastable {
public: public:
ConstCastable(bool* converted) : converted_(converted) {} explicit ConstCastable(bool* converted) : converted_(converted) {}
operator Base() const { operator Base() const {
*converted_ = true; *converted_ = true;
return Base(); return Base();
@@ -224,7 +261,7 @@ TEST(GtestCheckSyntaxTest, WorksWithSwitch) {
GTEST_CHECK_(true); GTEST_CHECK_(true);
} }
switch(0) switch (0)
case 0: case 0:
GTEST_CHECK_(true) << "Check failed in switch case"; GTEST_CHECK_(true) << "Check failed in switch case";
} }
@@ -267,7 +304,7 @@ TEST(FormatCompilerIndependentFileLocationTest, FormatsUknownFileAndLine) {
EXPECT_EQ("unknown file", FormatCompilerIndependentFileLocation(NULL, -1)); EXPECT_EQ("unknown file", FormatCompilerIndependentFileLocation(NULL, -1));
} }
#if GTEST_OS_MAC #if GTEST_OS_MAC || GTEST_OS_QNX
void* ThreadFunc(void* data) { void* ThreadFunc(void* data) {
pthread_mutex_t* mutex = static_cast<pthread_mutex_t*>(data); pthread_mutex_t* mutex = static_cast<pthread_mutex_t*>(data);
pthread_mutex_lock(mutex); pthread_mutex_lock(mutex);
@@ -297,6 +334,8 @@ TEST(GetThreadCountTest, ReturnsCorrectValue) {
void* dummy; void* dummy;
ASSERT_EQ(0, pthread_join(thread_id, &dummy)); ASSERT_EQ(0, pthread_join(thread_id, &dummy));
# if GTEST_OS_MAC
// MacOS X may not immediately report the updated thread count after // MacOS X may not immediately report the updated thread count after
// joining a thread, causing flakiness in this test. To counter that, we // joining a thread, causing flakiness in this test. To counter that, we
// wait for up to .5 seconds for the OS to report the correct value. // wait for up to .5 seconds for the OS to report the correct value.
@@ -306,6 +345,9 @@ TEST(GetThreadCountTest, ReturnsCorrectValue) {
SleepMilliseconds(100); SleepMilliseconds(100);
} }
# endif // GTEST_OS_MAC
EXPECT_EQ(1U, GetThreadCount()); EXPECT_EQ(1U, GetThreadCount());
pthread_mutex_destroy(&mutex); pthread_mutex_destroy(&mutex);
} }
@@ -313,7 +355,7 @@ TEST(GetThreadCountTest, ReturnsCorrectValue) {
TEST(GetThreadCountTest, ReturnsZeroWhenUnableToCountThreads) { TEST(GetThreadCountTest, ReturnsZeroWhenUnableToCountThreads) {
EXPECT_EQ(0U, GetThreadCount()); EXPECT_EQ(0U, GetThreadCount());
} }
#endif // GTEST_OS_MAC #endif // GTEST_OS_MAC || GTEST_OS_QNX
TEST(GtestCheckDeathTest, DiesWithCorrectOutputOnFailure) { TEST(GtestCheckDeathTest, DiesWithCorrectOutputOnFailure) {
const bool a_false_condition = false; const bool a_false_condition = false;
@@ -924,7 +966,7 @@ TEST(CaptureTest, CapturesStdoutAndStderr) {
TEST(CaptureDeathTest, CannotReenterStdoutCapture) { TEST(CaptureDeathTest, CannotReenterStdoutCapture) {
CaptureStdout(); CaptureStdout();
EXPECT_DEATH_IF_SUPPORTED(CaptureStdout();, EXPECT_DEATH_IF_SUPPORTED(CaptureStdout(),
"Only one stdout capturer can exist at a time"); "Only one stdout capturer can exist at a time");
GetCapturedStdout(); GetCapturedStdout();
@@ -963,23 +1005,24 @@ TEST(ThreadLocalTest, ValueDefaultContructorIsNotRequiredForParamVersion) {
} }
TEST(ThreadLocalTest, GetAndPointerReturnSameValue) { TEST(ThreadLocalTest, GetAndPointerReturnSameValue) {
ThreadLocal<String> thread_local; ThreadLocal<std::string> thread_local_string;
EXPECT_EQ(thread_local.pointer(), &(thread_local.get())); EXPECT_EQ(thread_local_string.pointer(), &(thread_local_string.get()));
// Verifies the condition still holds after calling set. // Verifies the condition still holds after calling set.
thread_local.set("foo"); thread_local_string.set("foo");
EXPECT_EQ(thread_local.pointer(), &(thread_local.get())); EXPECT_EQ(thread_local_string.pointer(), &(thread_local_string.get()));
} }
TEST(ThreadLocalTest, PointerAndConstPointerReturnSameValue) { TEST(ThreadLocalTest, PointerAndConstPointerReturnSameValue) {
ThreadLocal<String> thread_local; ThreadLocal<std::string> thread_local_string;
const ThreadLocal<String>& const_thread_local = thread_local; const ThreadLocal<std::string>& const_thread_local_string =
thread_local_string;
EXPECT_EQ(thread_local.pointer(), const_thread_local.pointer()); EXPECT_EQ(thread_local_string.pointer(), const_thread_local_string.pointer());
thread_local.set("foo"); thread_local_string.set("foo");
EXPECT_EQ(thread_local.pointer(), const_thread_local.pointer()); EXPECT_EQ(thread_local_string.pointer(), const_thread_local_string.pointer());
} }
#if GTEST_IS_THREADSAFE #if GTEST_IS_THREADSAFE
@@ -1032,6 +1075,7 @@ class AtomicCounterWithMutex {
SleepMilliseconds(random_.Generate(30)); SleepMilliseconds(random_.Generate(30));
GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_unlock(&memory_barrier_mutex)); GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_unlock(&memory_barrier_mutex));
GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_destroy(&memory_barrier_mutex));
} }
value_ = temp + 1; value_ = temp + 1;
} }
@@ -1083,19 +1127,21 @@ void RunFromThread(void (func)(T), T param) {
thread.Join(); thread.Join();
} }
void RetrieveThreadLocalValue(pair<ThreadLocal<String>*, String*> param) { void RetrieveThreadLocalValue(
pair<ThreadLocal<std::string>*, std::string*> param) {
*param.second = param.first->get(); *param.second = param.first->get();
} }
TEST(ThreadLocalTest, ParameterizedConstructorSetsDefault) { TEST(ThreadLocalTest, ParameterizedConstructorSetsDefault) {
ThreadLocal<String> thread_local("foo"); ThreadLocal<std::string> thread_local_string("foo");
EXPECT_STREQ("foo", thread_local.get().c_str()); EXPECT_STREQ("foo", thread_local_string.get().c_str());
thread_local.set("bar"); thread_local_string.set("bar");
EXPECT_STREQ("bar", thread_local.get().c_str()); EXPECT_STREQ("bar", thread_local_string.get().c_str());
String result; std::string result;
RunFromThread(&RetrieveThreadLocalValue, make_pair(&thread_local, &result)); RunFromThread(&RetrieveThreadLocalValue,
make_pair(&thread_local_string, &result));
EXPECT_STREQ("foo", result.c_str()); EXPECT_STREQ("foo", result.c_str());
} }
@@ -1124,8 +1170,8 @@ class DestructorTracker {
typedef ThreadLocal<DestructorTracker>* ThreadParam; typedef ThreadLocal<DestructorTracker>* ThreadParam;
void CallThreadLocalGet(ThreadParam thread_local) { void CallThreadLocalGet(ThreadParam thread_local_param) {
thread_local->get(); thread_local_param->get();
} }
// Tests that when a ThreadLocal object dies in a thread, it destroys // Tests that when a ThreadLocal object dies in a thread, it destroys
@@ -1135,19 +1181,19 @@ TEST(ThreadLocalTest, DestroysManagedObjectForOwnThreadWhenDying) {
{ {
// The next line default constructs a DestructorTracker object as // The next line default constructs a DestructorTracker object as
// the default value of objects managed by thread_local. // the default value of objects managed by thread_local_tracker.
ThreadLocal<DestructorTracker> thread_local; ThreadLocal<DestructorTracker> thread_local_tracker;
ASSERT_EQ(1U, g_destroyed.size()); ASSERT_EQ(1U, g_destroyed.size());
ASSERT_FALSE(g_destroyed[0]); ASSERT_FALSE(g_destroyed[0]);
// This creates another DestructorTracker object for the main thread. // This creates another DestructorTracker object for the main thread.
thread_local.get(); thread_local_tracker.get();
ASSERT_EQ(2U, g_destroyed.size()); ASSERT_EQ(2U, g_destroyed.size());
ASSERT_FALSE(g_destroyed[0]); ASSERT_FALSE(g_destroyed[0]);
ASSERT_FALSE(g_destroyed[1]); ASSERT_FALSE(g_destroyed[1]);
} }
// Now thread_local has died. It should have destroyed both the // Now thread_local_tracker has died. It should have destroyed both the
// default value shared by all threads and the value for the main // default value shared by all threads and the value for the main
// thread. // thread.
ASSERT_EQ(2U, g_destroyed.size()); ASSERT_EQ(2U, g_destroyed.size());
@@ -1164,14 +1210,14 @@ TEST(ThreadLocalTest, DestroysManagedObjectAtThreadExit) {
{ {
// The next line default constructs a DestructorTracker object as // The next line default constructs a DestructorTracker object as
// the default value of objects managed by thread_local. // the default value of objects managed by thread_local_tracker.
ThreadLocal<DestructorTracker> thread_local; ThreadLocal<DestructorTracker> thread_local_tracker;
ASSERT_EQ(1U, g_destroyed.size()); ASSERT_EQ(1U, g_destroyed.size());
ASSERT_FALSE(g_destroyed[0]); ASSERT_FALSE(g_destroyed[0]);
// This creates another DestructorTracker object in the new thread. // This creates another DestructorTracker object in the new thread.
ThreadWithParam<ThreadParam> thread( ThreadWithParam<ThreadParam> thread(
&CallThreadLocalGet, &thread_local, NULL); &CallThreadLocalGet, &thread_local_tracker, NULL);
thread.Join(); thread.Join();
// Now the new thread has exited. The per-thread object for it // Now the new thread has exited. The per-thread object for it
@@ -1181,7 +1227,7 @@ TEST(ThreadLocalTest, DestroysManagedObjectAtThreadExit) {
ASSERT_TRUE(g_destroyed[1]); ASSERT_TRUE(g_destroyed[1]);
} }
// Now thread_local has died. The default value should have been // Now thread_local_tracker has died. The default value should have been
// destroyed too. // destroyed too.
ASSERT_EQ(2U, g_destroyed.size()); ASSERT_EQ(2U, g_destroyed.size());
EXPECT_TRUE(g_destroyed[0]); EXPECT_TRUE(g_destroyed[0]);
@@ -1191,13 +1237,14 @@ TEST(ThreadLocalTest, DestroysManagedObjectAtThreadExit) {
} }
TEST(ThreadLocalTest, ThreadLocalMutationsAffectOnlyCurrentThread) { TEST(ThreadLocalTest, ThreadLocalMutationsAffectOnlyCurrentThread) {
ThreadLocal<String> thread_local; ThreadLocal<std::string> thread_local_string;
thread_local.set("Foo"); thread_local_string.set("Foo");
EXPECT_STREQ("Foo", thread_local.get().c_str()); EXPECT_STREQ("Foo", thread_local_string.get().c_str());
String result; std::string result;
RunFromThread(&RetrieveThreadLocalValue, make_pair(&thread_local, &result)); RunFromThread(&RetrieveThreadLocalValue,
EXPECT_TRUE(result.c_str() == NULL); make_pair(&thread_local_string, &result));
EXPECT_TRUE(result.empty());
} }
#endif // GTEST_IS_THREADSAFE #endif // GTEST_IS_THREADSAFE
+275 -16
View File
@@ -197,13 +197,15 @@ using ::std::pair;
using ::std::set; using ::std::set;
using ::std::vector; using ::std::vector;
using ::testing::PrintToString; using ::testing::PrintToString;
using ::testing::internal::FormatForComparisonFailureMessage;
using ::testing::internal::ImplicitCast_;
using ::testing::internal::NativeArray; using ::testing::internal::NativeArray;
using ::testing::internal::RE; using ::testing::internal::RE;
using ::testing::internal::Strings; using ::testing::internal::Strings;
using ::testing::internal::UniversalTersePrint;
using ::testing::internal::UniversalPrint; using ::testing::internal::UniversalPrint;
using ::testing::internal::UniversalTersePrintTupleFieldsToStrings;
using ::testing::internal::UniversalPrinter; using ::testing::internal::UniversalPrinter;
using ::testing::internal::UniversalTersePrint;
using ::testing::internal::UniversalTersePrintTupleFieldsToStrings;
using ::testing::internal::kReference; using ::testing::internal::kReference;
using ::testing::internal::string; using ::testing::internal::string;
@@ -212,10 +214,15 @@ using ::std::tr1::make_tuple;
using ::std::tr1::tuple; using ::std::tr1::tuple;
#endif #endif
#if _MSC_VER // The hash_* classes are not part of the C++ standard. STLport
// MSVC defines the following classes in the ::stdext namespace while // defines them in namespace std. MSVC defines them in ::stdext. GCC
// gcc defines them in the :: namespace. Note that they are not part // defines them in ::.
// of the C++ standard. #ifdef _STLP_HASH_MAP // We got <hash_map> from STLport.
using ::std::hash_map;
using ::std::hash_set;
using ::std::hash_multimap;
using ::std::hash_multiset;
#elif _MSC_VER
using ::stdext::hash_map; using ::stdext::hash_map;
using ::stdext::hash_set; using ::stdext::hash_set;
using ::stdext::hash_multimap; using ::stdext::hash_multimap;
@@ -612,17 +619,30 @@ TEST(PrintArrayTest, ConstArray) {
EXPECT_EQ("{ false }", PrintArrayHelper(a)); EXPECT_EQ("{ false }", PrintArrayHelper(a));
} }
// Char array. // char array without terminating NUL.
TEST(PrintArrayTest, CharArray) { TEST(PrintArrayTest, CharArrayWithNoTerminatingNul) {
// Array a contains '\0' in the middle and doesn't end with '\0'. // Array a contains '\0' in the middle and doesn't end with '\0'.
char a[3] = { 'H', '\0', 'i' }; char a[] = { 'H', '\0', 'i' };
EXPECT_EQ("\"H\\0i\"", PrintArrayHelper(a)); EXPECT_EQ("\"H\\0i\" (no terminating NUL)", PrintArrayHelper(a));
} }
// Const char array. // const char array with terminating NUL.
TEST(PrintArrayTest, ConstCharArray) { TEST(PrintArrayTest, ConstCharArrayWithTerminatingNul) {
const char a[4] = "\0Hi"; const char a[] = "\0Hi";
EXPECT_EQ("\"\\0Hi\\0\"", PrintArrayHelper(a)); EXPECT_EQ("\"\\0Hi\"", PrintArrayHelper(a));
}
// const wchar_t array without terminating NUL.
TEST(PrintArrayTest, WCharArrayWithNoTerminatingNul) {
// Array a contains '\0' in the middle and doesn't end with '\0'.
const wchar_t a[] = { L'H', L'\0', L'i' };
EXPECT_EQ("L\"H\\0i\" (no terminating NUL)", PrintArrayHelper(a));
}
// wchar_t array with terminating NUL.
TEST(PrintArrayTest, WConstCharArrayWithTerminatingNul) {
const wchar_t a[] = L"\0Hi";
EXPECT_EQ("L\"\\0Hi\"", PrintArrayHelper(a));
} }
// Array of objects. // Array of objects.
@@ -840,7 +860,7 @@ TEST(PrintStlContainerTest, HashMultiSet) {
std::vector<int> numbers; std::vector<int> numbers;
for (size_t i = 0; i != result.length(); i++) { for (size_t i = 0; i != result.length(); i++) {
if (expected_pattern[i] == 'd') { if (expected_pattern[i] == 'd') {
ASSERT_TRUE(isdigit(static_cast<unsigned char>(result[i])) != 0); ASSERT_NE(isdigit(static_cast<unsigned char>(result[i])), 0);
numbers.push_back(result[i] - '0'); numbers.push_back(result[i] - '0');
} else { } else {
EXPECT_EQ(expected_pattern[i], result[i]) << " where result is " EXPECT_EQ(expected_pattern[i], result[i]) << " where result is "
@@ -1002,9 +1022,12 @@ TEST(PrintTupleTest, VariousSizes) {
EXPECT_EQ("(false, 2, 3, 4, true, 6, 7, true, 9)", Print(t9)); EXPECT_EQ("(false, 2, 3, 4, true, 6, 7, true, 9)", Print(t9));
const char* const str = "8"; const char* const str = "8";
// VC++ 2010's implementation of tuple of C++0x is deficient, requiring
// an explicit type cast of NULL to be used.
tuple<bool, char, short, testing::internal::Int32, // NOLINT tuple<bool, char, short, testing::internal::Int32, // NOLINT
testing::internal::Int64, float, double, const char*, void*, string> testing::internal::Int64, float, double, const char*, void*, string>
t10(false, 'a', 3, 4, 5, 1.5F, -2.5, str, NULL, "10"); t10(false, 'a', 3, 4, 5, 1.5F, -2.5, str,
ImplicitCast_<void*>(NULL), "10");
EXPECT_EQ("(false, 'a' (97, 0x61), 3, 4, 5, 1.5, -2.5, " + PrintPointer(str) + EXPECT_EQ("(false, 'a' (97, 0x61), 3, 4, 5, 1.5, -2.5, " + PrintPointer(str) +
" pointing to \"8\", NULL, \"10\")", " pointing to \"8\", NULL, \"10\")",
Print(t10)); Print(t10));
@@ -1182,6 +1205,207 @@ TEST(PrintReferenceTest, HandlesMemberVariablePointer) {
"@" + PrintPointer(&p) + " " + Print(sizeof(p)) + "-byte object ")); "@" + PrintPointer(&p) + " " + Print(sizeof(p)) + "-byte object "));
} }
// Tests that FormatForComparisonFailureMessage(), which is used to print
// an operand in a comparison assertion (e.g. ASSERT_EQ) when the assertion
// fails, formats the operand in the desired way.
// scalar
TEST(FormatForComparisonFailureMessageTest, WorksForScalar) {
EXPECT_STREQ("123",
FormatForComparisonFailureMessage(123, 124).c_str());
}
// non-char pointer
TEST(FormatForComparisonFailureMessageTest, WorksForNonCharPointer) {
int n = 0;
EXPECT_EQ(PrintPointer(&n),
FormatForComparisonFailureMessage(&n, &n).c_str());
}
// non-char array
TEST(FormatForComparisonFailureMessageTest, FormatsNonCharArrayAsPointer) {
// In expression 'array == x', 'array' is compared by pointer.
// Therefore we want to print an array operand as a pointer.
int n[] = { 1, 2, 3 };
EXPECT_EQ(PrintPointer(n),
FormatForComparisonFailureMessage(n, n).c_str());
}
// Tests formatting a char pointer when it's compared with another pointer.
// In this case we want to print it as a raw pointer, as the comparision is by
// pointer.
// char pointer vs pointer
TEST(FormatForComparisonFailureMessageTest, WorksForCharPointerVsPointer) {
// In expression 'p == x', where 'p' and 'x' are (const or not) char
// pointers, the operands are compared by pointer. Therefore we
// want to print 'p' as a pointer instead of a C string (we don't
// even know if it's supposed to point to a valid C string).
// const char*
const char* s = "hello";
EXPECT_EQ(PrintPointer(s),
FormatForComparisonFailureMessage(s, s).c_str());
// char*
char ch = 'a';
EXPECT_EQ(PrintPointer(&ch),
FormatForComparisonFailureMessage(&ch, &ch).c_str());
}
// wchar_t pointer vs pointer
TEST(FormatForComparisonFailureMessageTest, WorksForWCharPointerVsPointer) {
// In expression 'p == x', where 'p' and 'x' are (const or not) char
// pointers, the operands are compared by pointer. Therefore we
// want to print 'p' as a pointer instead of a wide C string (we don't
// even know if it's supposed to point to a valid wide C string).
// const wchar_t*
const wchar_t* s = L"hello";
EXPECT_EQ(PrintPointer(s),
FormatForComparisonFailureMessage(s, s).c_str());
// wchar_t*
wchar_t ch = L'a';
EXPECT_EQ(PrintPointer(&ch),
FormatForComparisonFailureMessage(&ch, &ch).c_str());
}
// Tests formatting a char pointer when it's compared to a string object.
// In this case we want to print the char pointer as a C string.
#if GTEST_HAS_GLOBAL_STRING
// char pointer vs ::string
TEST(FormatForComparisonFailureMessageTest, WorksForCharPointerVsString) {
const char* s = "hello \"world";
EXPECT_STREQ("\"hello \\\"world\"", // The string content should be escaped.
FormatForComparisonFailureMessage(s, ::string()).c_str());
// char*
char str[] = "hi\1";
char* p = str;
EXPECT_STREQ("\"hi\\x1\"", // The string content should be escaped.
FormatForComparisonFailureMessage(p, ::string()).c_str());
}
#endif
// char pointer vs std::string
TEST(FormatForComparisonFailureMessageTest, WorksForCharPointerVsStdString) {
const char* s = "hello \"world";
EXPECT_STREQ("\"hello \\\"world\"", // The string content should be escaped.
FormatForComparisonFailureMessage(s, ::std::string()).c_str());
// char*
char str[] = "hi\1";
char* p = str;
EXPECT_STREQ("\"hi\\x1\"", // The string content should be escaped.
FormatForComparisonFailureMessage(p, ::std::string()).c_str());
}
#if GTEST_HAS_GLOBAL_WSTRING
// wchar_t pointer vs ::wstring
TEST(FormatForComparisonFailureMessageTest, WorksForWCharPointerVsWString) {
const wchar_t* s = L"hi \"world";
EXPECT_STREQ("L\"hi \\\"world\"", // The string content should be escaped.
FormatForComparisonFailureMessage(s, ::wstring()).c_str());
// wchar_t*
wchar_t str[] = L"hi\1";
wchar_t* p = str;
EXPECT_STREQ("L\"hi\\x1\"", // The string content should be escaped.
FormatForComparisonFailureMessage(p, ::wstring()).c_str());
}
#endif
#if GTEST_HAS_STD_WSTRING
// wchar_t pointer vs std::wstring
TEST(FormatForComparisonFailureMessageTest, WorksForWCharPointerVsStdWString) {
const wchar_t* s = L"hi \"world";
EXPECT_STREQ("L\"hi \\\"world\"", // The string content should be escaped.
FormatForComparisonFailureMessage(s, ::std::wstring()).c_str());
// wchar_t*
wchar_t str[] = L"hi\1";
wchar_t* p = str;
EXPECT_STREQ("L\"hi\\x1\"", // The string content should be escaped.
FormatForComparisonFailureMessage(p, ::std::wstring()).c_str());
}
#endif
// Tests formatting a char array when it's compared with a pointer or array.
// In this case we want to print the array as a row pointer, as the comparison
// is by pointer.
// char array vs pointer
TEST(FormatForComparisonFailureMessageTest, WorksForCharArrayVsPointer) {
char str[] = "hi \"world\"";
char* p = NULL;
EXPECT_EQ(PrintPointer(str),
FormatForComparisonFailureMessage(str, p).c_str());
}
// char array vs char array
TEST(FormatForComparisonFailureMessageTest, WorksForCharArrayVsCharArray) {
const char str[] = "hi \"world\"";
EXPECT_EQ(PrintPointer(str),
FormatForComparisonFailureMessage(str, str).c_str());
}
// wchar_t array vs pointer
TEST(FormatForComparisonFailureMessageTest, WorksForWCharArrayVsPointer) {
wchar_t str[] = L"hi \"world\"";
wchar_t* p = NULL;
EXPECT_EQ(PrintPointer(str),
FormatForComparisonFailureMessage(str, p).c_str());
}
// wchar_t array vs wchar_t array
TEST(FormatForComparisonFailureMessageTest, WorksForWCharArrayVsWCharArray) {
const wchar_t str[] = L"hi \"world\"";
EXPECT_EQ(PrintPointer(str),
FormatForComparisonFailureMessage(str, str).c_str());
}
// Tests formatting a char array when it's compared with a string object.
// In this case we want to print the array as a C string.
#if GTEST_HAS_GLOBAL_STRING
// char array vs string
TEST(FormatForComparisonFailureMessageTest, WorksForCharArrayVsString) {
const char str[] = "hi \"w\0rld\"";
EXPECT_STREQ("\"hi \\\"w\"", // The content should be escaped.
// Embedded NUL terminates the string.
FormatForComparisonFailureMessage(str, ::string()).c_str());
}
#endif
// char array vs std::string
TEST(FormatForComparisonFailureMessageTest, WorksForCharArrayVsStdString) {
const char str[] = "hi \"world\"";
EXPECT_STREQ("\"hi \\\"world\\\"\"", // The content should be escaped.
FormatForComparisonFailureMessage(str, ::std::string()).c_str());
}
#if GTEST_HAS_GLOBAL_WSTRING
// wchar_t array vs wstring
TEST(FormatForComparisonFailureMessageTest, WorksForWCharArrayVsWString) {
const wchar_t str[] = L"hi \"world\"";
EXPECT_STREQ("L\"hi \\\"world\\\"\"", // The content should be escaped.
FormatForComparisonFailureMessage(str, ::wstring()).c_str());
}
#endif
#if GTEST_HAS_STD_WSTRING
// wchar_t array vs std::wstring
TEST(FormatForComparisonFailureMessageTest, WorksForWCharArrayVsStdWString) {
const wchar_t str[] = L"hi \"w\0rld\"";
EXPECT_STREQ(
"L\"hi \\\"w\"", // The content should be escaped.
// Embedded NUL terminates the string.
FormatForComparisonFailureMessage(str, ::std::wstring()).c_str());
}
#endif
// Useful for testing PrintToString(). We cannot use EXPECT_EQ() // Useful for testing PrintToString(). We cannot use EXPECT_EQ()
// there as its implementation uses PrintToString(). The caller must // there as its implementation uses PrintToString(). The caller must
// ensure that 'value' has no side effect. // ensure that 'value' has no side effect.
@@ -1204,11 +1428,35 @@ TEST(PrintToStringTest, WorksForPointerToNonConstChar) {
EXPECT_PRINT_TO_STRING_(p, "\"hello\""); EXPECT_PRINT_TO_STRING_(p, "\"hello\"");
} }
TEST(PrintToStringTest, EscapesForPointerToConstChar) {
const char* p = "hello\n";
EXPECT_PRINT_TO_STRING_(p, "\"hello\\n\"");
}
TEST(PrintToStringTest, EscapesForPointerToNonConstChar) {
char s[] = "hello\1";
char* p = s;
EXPECT_PRINT_TO_STRING_(p, "\"hello\\x1\"");
}
TEST(PrintToStringTest, WorksForArray) { TEST(PrintToStringTest, WorksForArray) {
int n[3] = { 1, 2, 3 }; int n[3] = { 1, 2, 3 };
EXPECT_PRINT_TO_STRING_(n, "{ 1, 2, 3 }"); EXPECT_PRINT_TO_STRING_(n, "{ 1, 2, 3 }");
} }
TEST(PrintToStringTest, WorksForCharArray) {
char s[] = "hello";
EXPECT_PRINT_TO_STRING_(s, "\"hello\"");
}
TEST(PrintToStringTest, WorksForCharArrayWithEmbeddedNul) {
const char str_with_nul[] = "hello\0 world";
EXPECT_PRINT_TO_STRING_(str_with_nul, "\"hello\\0 world\"");
char mutable_str_with_nul[] = "hello\0 world";
EXPECT_PRINT_TO_STRING_(mutable_str_with_nul, "\"hello\\0 world\"");
}
#undef EXPECT_PRINT_TO_STRING_ #undef EXPECT_PRINT_TO_STRING_
TEST(UniversalTersePrintTest, WorksForNonReference) { TEST(UniversalTersePrintTest, WorksForNonReference) {
@@ -1271,6 +1519,17 @@ TEST(UniversalPrintTest, WorksForCString) {
EXPECT_EQ("NULL", ss3.str()); EXPECT_EQ("NULL", ss3.str());
} }
TEST(UniversalPrintTest, WorksForCharArray) {
const char str[] = "\"Line\0 1\"\nLine 2";
::std::stringstream ss1;
UniversalPrint(str, &ss1);
EXPECT_EQ("\"\\\"Line\\0 1\\\"\\nLine 2\"", ss1.str());
const char mutable_str[] = "\"Line\0 1\"\nLine 2";
::std::stringstream ss2;
UniversalPrint(mutable_str, &ss2);
EXPECT_EQ("\"\\\"Line\\0 1\\\"\\nLine 2\"", ss2.str());
}
#if GTEST_HAS_TR1_TUPLE #if GTEST_HAS_TR1_TUPLE
+8 -14
View File
@@ -66,21 +66,15 @@ EXE_PATH = gtest_test_utils.GetTestExecutablePath(
'gtest_break_on_failure_unittest_') 'gtest_break_on_failure_unittest_')
# Utilities. environ = gtest_test_utils.environ
SetEnvVar = gtest_test_utils.SetEnvVar
# Tests in this file run a Google-Test-based test program and expect it
environ = os.environ.copy() # to terminate prematurely. Therefore they are incompatible with
# the premature-exit-file protocol by design. Unset the
# premature-exit filepath to prevent Google Test from creating
def SetEnvVar(env_var, value): # the file.
"""Sets an environment variable to a given value; unsets it when the SetEnvVar(gtest_test_utils.PREMATURE_EXIT_FILE_ENV_VAR, None)
given value is None.
"""
if value is not None:
environ[env_var] = value
elif env_var in environ:
del environ[env_var]
def Run(command): def Run(command):
+29 -12
View File
@@ -57,14 +57,27 @@ EX_EXE_PATH = gtest_test_utils.GetTestExecutablePath(
EXE_PATH = gtest_test_utils.GetTestExecutablePath( EXE_PATH = gtest_test_utils.GetTestExecutablePath(
'gtest_catch_exceptions_no_ex_test_') 'gtest_catch_exceptions_no_ex_test_')
TEST_LIST = gtest_test_utils.Subprocess([EXE_PATH, LIST_TESTS_FLAG]).output environ = gtest_test_utils.environ
SetEnvVar = gtest_test_utils.SetEnvVar
# Tests in this file run a Google-Test-based test program and expect it
# to terminate prematurely. Therefore they are incompatible with
# the premature-exit-file protocol by design. Unset the
# premature-exit filepath to prevent Google Test from creating
# the file.
SetEnvVar(gtest_test_utils.PREMATURE_EXIT_FILE_ENV_VAR, None)
TEST_LIST = gtest_test_utils.Subprocess(
[EXE_PATH, LIST_TESTS_FLAG], env=environ).output
SUPPORTS_SEH_EXCEPTIONS = 'ThrowsSehException' in TEST_LIST SUPPORTS_SEH_EXCEPTIONS = 'ThrowsSehException' in TEST_LIST
if SUPPORTS_SEH_EXCEPTIONS: if SUPPORTS_SEH_EXCEPTIONS:
BINARY_OUTPUT = gtest_test_utils.Subprocess([EXE_PATH]).output BINARY_OUTPUT = gtest_test_utils.Subprocess([EXE_PATH], env=environ).output
EX_BINARY_OUTPUT = gtest_test_utils.Subprocess(
[EX_EXE_PATH], env=environ).output
EX_BINARY_OUTPUT = gtest_test_utils.Subprocess([EX_EXE_PATH]).output
# The tests. # The tests.
if SUPPORTS_SEH_EXCEPTIONS: if SUPPORTS_SEH_EXCEPTIONS:
@@ -117,14 +130,17 @@ class CatchCxxExceptionsTest(gtest_test_utils.TestCase):
'"CxxExceptionInConstructorTest" (no quotes) ' '"CxxExceptionInConstructorTest" (no quotes) '
'appears on the same line as words "called unexpectedly"') 'appears on the same line as words "called unexpectedly"')
def testCatchesCxxExceptionsInFixtureDestructor(self): if ('CxxExceptionInDestructorTest.ThrowsExceptionInDestructor' in
self.assert_('C++ exception with description ' EX_BINARY_OUTPUT):
'"Standard C++ exception" thrown '
'in the test fixture\'s destructor' def testCatchesCxxExceptionsInFixtureDestructor(self):
in EX_BINARY_OUTPUT) self.assert_('C++ exception with description '
self.assert_('CxxExceptionInDestructorTest::TearDownTestCase() ' '"Standard C++ exception" thrown '
'called as expected.' 'in the test fixture\'s destructor'
in EX_BINARY_OUTPUT) in EX_BINARY_OUTPUT)
self.assert_('CxxExceptionInDestructorTest::TearDownTestCase() '
'called as expected.'
in EX_BINARY_OUTPUT)
def testCatchesCxxExceptionsInSetUpTestCase(self): def testCatchesCxxExceptionsInSetUpTestCase(self):
self.assert_('C++ exception with description "Standard C++ exception"' self.assert_('C++ exception with description "Standard C++ exception"'
@@ -209,7 +225,8 @@ class CatchCxxExceptionsTest(gtest_test_utils.TestCase):
uncaught_exceptions_ex_binary_output = gtest_test_utils.Subprocess( uncaught_exceptions_ex_binary_output = gtest_test_utils.Subprocess(
[EX_EXE_PATH, [EX_EXE_PATH,
NO_CATCH_EXCEPTIONS_FLAG, NO_CATCH_EXCEPTIONS_FLAG,
FITLER_OUT_SEH_TESTS_FLAG]).output FITLER_OUT_SEH_TESTS_FLAG],
env=environ).output
self.assert_('Unhandled C++ exception terminating the program' self.assert_('Unhandled C++ exception terminating the program'
in uncaught_exceptions_ex_binary_output) in uncaught_exceptions_ex_binary_output)
+3
View File
@@ -137,6 +137,8 @@ TEST_F(CxxExceptionInConstructorTest, ThrowsExceptionInConstructor) {
<< "called unexpectedly."; << "called unexpectedly.";
} }
// Exceptions in destructors are not supported in C++11.
#if !defined(__GXX_EXPERIMENTAL_CXX0X__) && __cplusplus < 201103L
class CxxExceptionInDestructorTest : public Test { class CxxExceptionInDestructorTest : public Test {
public: public:
static void TearDownTestCase() { static void TearDownTestCase() {
@@ -153,6 +155,7 @@ class CxxExceptionInDestructorTest : public Test {
}; };
TEST_F(CxxExceptionInDestructorTest, ThrowsExceptionInDestructor) {} TEST_F(CxxExceptionInDestructorTest, ThrowsExceptionInDestructor) {}
#endif // C++11 mode
class CxxExceptionInSetUpTestCaseTest : public Test { class CxxExceptionInSetUpTestCaseTest : public Test {
public: public:
+1
View File
@@ -96,6 +96,7 @@ class MyEnvironment : public testing::Environment {
// Was TearDown() run? // Was TearDown() run?
bool tear_down_was_run() const { return tear_down_was_run_; } bool tear_down_was_run() const { return tear_down_was_run_; }
private: private:
FailureType failure_in_set_up_; FailureType failure_in_set_up_;
bool set_up_was_run_; bool set_up_was_run_;
+61 -31
View File
@@ -40,6 +40,7 @@ Google Test) the command line flags.
__author__ = 'phanna@google.com (Patrick Hanna)' __author__ = 'phanna@google.com (Patrick Hanna)'
import gtest_test_utils import gtest_test_utils
import re
# Constants. # Constants.
@@ -52,38 +53,63 @@ EXE_PATH = gtest_test_utils.GetTestExecutablePath('gtest_list_tests_unittest_')
# The expected output when running gtest_list_tests_unittest_ with # The expected output when running gtest_list_tests_unittest_ with
# --gtest_list_tests # --gtest_list_tests
EXPECTED_OUTPUT_NO_FILTER = """FooDeathTest. EXPECTED_OUTPUT_NO_FILTER_RE = re.compile(r"""FooDeathTest\.
Test1 Test1
Foo. Foo\.
Bar1 Bar1
Bar2 Bar2
DISABLED_Bar3 DISABLED_Bar3
Abc. Abc\.
Xyz Xyz
Def Def
FooBar. FooBar\.
Baz Baz
FooTest. FooTest\.
Test1 Test1
DISABLED_Test2 DISABLED_Test2
Test3 Test3
""" TypedTest/0\. # TypeParam = (VeryLo{245}|class VeryLo{239})\.\.\.
TestA
TestB
TypedTest/1\. # TypeParam = int\s*\*
TestA
TestB
TypedTest/2\. # TypeParam = .*MyArray<bool,\s*42>
TestA
TestB
My/TypeParamTest/0\. # TypeParam = (VeryLo{245}|class VeryLo{239})\.\.\.
TestA
TestB
My/TypeParamTest/1\. # TypeParam = int\s*\*
TestA
TestB
My/TypeParamTest/2\. # TypeParam = .*MyArray<bool,\s*42>
TestA
TestB
MyInstantiation/ValueParamTest\.
TestA/0 # GetParam\(\) = one line
TestA/1 # GetParam\(\) = two\\nlines
TestA/2 # GetParam\(\) = a very\\nlo{241}\.\.\.
TestB/0 # GetParam\(\) = one line
TestB/1 # GetParam\(\) = two\\nlines
TestB/2 # GetParam\(\) = a very\\nlo{241}\.\.\.
""")
# The expected output when running gtest_list_tests_unittest_ with # The expected output when running gtest_list_tests_unittest_ with
# --gtest_list_tests and --gtest_filter=Foo*. # --gtest_list_tests and --gtest_filter=Foo*.
EXPECTED_OUTPUT_FILTER_FOO = """FooDeathTest. EXPECTED_OUTPUT_FILTER_FOO_RE = re.compile(r"""FooDeathTest\.
Test1 Test1
Foo. Foo\.
Bar1 Bar1
Bar2 Bar2
DISABLED_Bar3 DISABLED_Bar3
FooBar. FooBar\.
Baz Baz
FooTest. FooTest\.
Test1 Test1
DISABLED_Test2 DISABLED_Test2
Test3 Test3
""" """)
# Utilities. # Utilities.
@@ -100,19 +126,18 @@ def Run(args):
class GTestListTestsUnitTest(gtest_test_utils.TestCase): class GTestListTestsUnitTest(gtest_test_utils.TestCase):
"""Tests using the --gtest_list_tests flag to list all tests.""" """Tests using the --gtest_list_tests flag to list all tests."""
def RunAndVerify(self, flag_value, expected_output, other_flag): def RunAndVerify(self, flag_value, expected_output_re, other_flag):
"""Runs gtest_list_tests_unittest_ and verifies that it prints """Runs gtest_list_tests_unittest_ and verifies that it prints
the correct tests. the correct tests.
Args: Args:
flag_value: value of the --gtest_list_tests flag; flag_value: value of the --gtest_list_tests flag;
None if the flag should not be present. None if the flag should not be present.
expected_output_re: regular expression that matches the expected
expected_output: the expected output after running command; output after running command;
other_flag: a different flag to be passed to command
other_flag: a different flag to be passed to command along with gtest_list_tests;
along with gtest_list_tests; None if the flag should not be present.
None if the flag should not be present.
""" """
if flag_value is None: if flag_value is None:
@@ -132,36 +157,41 @@ class GTestListTestsUnitTest(gtest_test_utils.TestCase):
output = Run(args) output = Run(args)
msg = ('when %s is %s, the output of "%s" is "%s".' % if expected_output_re:
(LIST_TESTS_FLAG, flag_expression, ' '.join(args), output)) self.assert_(
expected_output_re.match(output),
if expected_output is not None: ('when %s is %s, the output of "%s" is "%s",\n'
self.assert_(output == expected_output, msg) 'which does not match regex "%s"' %
(LIST_TESTS_FLAG, flag_expression, ' '.join(args), output,
expected_output_re.pattern)))
else: else:
self.assert_(output != EXPECTED_OUTPUT_NO_FILTER, msg) self.assert_(
not EXPECTED_OUTPUT_NO_FILTER_RE.match(output),
('when %s is %s, the output of "%s" is "%s"'%
(LIST_TESTS_FLAG, flag_expression, ' '.join(args), output)))
def testDefaultBehavior(self): def testDefaultBehavior(self):
"""Tests the behavior of the default mode.""" """Tests the behavior of the default mode."""
self.RunAndVerify(flag_value=None, self.RunAndVerify(flag_value=None,
expected_output=None, expected_output_re=None,
other_flag=None) other_flag=None)
def testFlag(self): def testFlag(self):
"""Tests using the --gtest_list_tests flag.""" """Tests using the --gtest_list_tests flag."""
self.RunAndVerify(flag_value='0', self.RunAndVerify(flag_value='0',
expected_output=None, expected_output_re=None,
other_flag=None) other_flag=None)
self.RunAndVerify(flag_value='1', self.RunAndVerify(flag_value='1',
expected_output=EXPECTED_OUTPUT_NO_FILTER, expected_output_re=EXPECTED_OUTPUT_NO_FILTER_RE,
other_flag=None) other_flag=None)
def testOverrideNonFilterFlags(self): def testOverrideNonFilterFlags(self):
"""Tests that --gtest_list_tests overrides the non-filter flags.""" """Tests that --gtest_list_tests overrides the non-filter flags."""
self.RunAndVerify(flag_value='1', self.RunAndVerify(flag_value='1',
expected_output=EXPECTED_OUTPUT_NO_FILTER, expected_output_re=EXPECTED_OUTPUT_NO_FILTER_RE,
other_flag='--gtest_break_on_failure') other_flag='--gtest_break_on_failure')
def testWithFilterFlags(self): def testWithFilterFlags(self):
@@ -169,7 +199,7 @@ class GTestListTestsUnitTest(gtest_test_utils.TestCase):
--gtest_filter flag.""" --gtest_filter flag."""
self.RunAndVerify(flag_value='1', self.RunAndVerify(flag_value='1',
expected_output=EXPECTED_OUTPUT_FILTER_FOO, expected_output_re=EXPECTED_OUTPUT_FILTER_FOO_RE,
other_flag='--gtest_filter=Foo*') other_flag='--gtest_filter=Foo*')
+75 -3
View File
@@ -40,8 +40,6 @@
#include "gtest/gtest.h" #include "gtest/gtest.h"
namespace {
// Several different test cases and tests that will be listed. // Several different test cases and tests that will be listed.
TEST(Foo, Bar1) { TEST(Foo, Bar1) {
} }
@@ -76,7 +74,81 @@ TEST_F(FooTest, Test3) {
TEST(FooDeathTest, Test1) { TEST(FooDeathTest, Test1) {
} }
} // namespace // A group of value-parameterized tests.
class MyType {
public:
explicit MyType(const std::string& a_value) : value_(a_value) {}
const std::string& value() const { return value_; }
private:
std::string value_;
};
// Teaches Google Test how to print a MyType.
void PrintTo(const MyType& x, std::ostream* os) {
*os << x.value();
}
class ValueParamTest : public testing::TestWithParam<MyType> {
};
TEST_P(ValueParamTest, TestA) {
}
TEST_P(ValueParamTest, TestB) {
}
INSTANTIATE_TEST_CASE_P(
MyInstantiation, ValueParamTest,
testing::Values(MyType("one line"),
MyType("two\nlines"),
MyType("a very\nloooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong line"))); // NOLINT
// A group of typed tests.
// A deliberately long type name for testing the line-truncating
// behavior when printing a type parameter.
class VeryLoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooogName { // NOLINT
};
template <typename T>
class TypedTest : public testing::Test {
};
template <typename T, int kSize>
class MyArray {
};
typedef testing::Types<VeryLoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooogName, // NOLINT
int*, MyArray<bool, 42> > MyTypes;
TYPED_TEST_CASE(TypedTest, MyTypes);
TYPED_TEST(TypedTest, TestA) {
}
TYPED_TEST(TypedTest, TestB) {
}
// A group of type-parameterized tests.
template <typename T>
class TypeParamTest : public testing::Test {
};
TYPED_TEST_CASE_P(TypeParamTest);
TYPED_TEST_P(TypeParamTest, TestA) {
}
TYPED_TEST_P(TypeParamTest, TestB) {
}
REGISTER_TYPED_TEST_CASE_P(TypeParamTest, TestA, TestB);
INSTANTIATE_TYPED_TEST_CASE_P(My, TypeParamTest, MyTypes);
int main(int argc, char **argv) { int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv); ::testing::InitGoogleTest(&argc, argv);
-1
View File
@@ -34,7 +34,6 @@
#include "gtest/gtest.h" #include "gtest/gtest.h"
int main(int argc, char **argv) { int main(int argc, char **argv) {
testing::InitGoogleTest(&argc, argv); testing::InitGoogleTest(&argc, argv);
+22 -8
View File
@@ -27,8 +27,11 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// //
// A unit test for Google Test itself. This verifies that the basic // The purpose of this file is to generate Google Test output under
// constructs of Google Test work. // various conditions. The output will then be verified by
// gtest_output_test.py to ensure that Google Test generates the
// desired messages. Therefore, most tests in this file are MEANT TO
// FAIL.
// //
// Author: wan@google.com (Zhanyong Wan) // Author: wan@google.com (Zhanyong Wan)
@@ -55,7 +58,6 @@ using testing::internal::ThreadWithParam;
#endif #endif
namespace posix = ::testing::internal::posix; namespace posix = ::testing::internal::posix;
using testing::internal::String;
using testing::internal::scoped_ptr; using testing::internal::scoped_ptr;
// Tests catching fatal failures. // Tests catching fatal failures.
@@ -101,6 +103,16 @@ INSTANTIATE_TEST_CASE_P(PrintingFailingParams,
FailingParamTest, FailingParamTest,
testing::Values(2)); testing::Values(2));
static const char kGoldenString[] = "\"Line\0 1\"\nLine 2";
TEST(NonfatalFailureTest, EscapesStringOperands) {
std::string actual = "actual \"string\"";
EXPECT_EQ(kGoldenString, actual);
const char* golden = kGoldenString;
EXPECT_EQ(golden, actual);
}
// Tests catching a fatal failure in a subroutine. // Tests catching a fatal failure in a subroutine.
TEST(FatalFailureTest, FatalFailureInSubroutine) { TEST(FatalFailureTest, FatalFailureInSubroutine) {
printf("(expecting a failure that x should be 1)\n"); printf("(expecting a failure that x should be 1)\n");
@@ -221,13 +233,13 @@ TEST(SCOPED_TRACETest, CanBeRepeated) {
{ {
SCOPED_TRACE("C"); SCOPED_TRACE("C");
ADD_FAILURE() << "This failure is expected, and should contain " ADD_FAILURE() << "This failure is expected, and should "
<< "trace point A, B, and C."; << "contain trace point A, B, and C.";
} }
SCOPED_TRACE("D"); SCOPED_TRACE("D");
ADD_FAILURE() << "This failure is expected, and should contain " ADD_FAILURE() << "This failure is expected, and should "
<< "trace point A, B, and D."; << "contain trace point A, B, and D.";
} }
#if GTEST_IS_THREADSAFE #if GTEST_IS_THREADSAFE
@@ -378,6 +390,7 @@ class FatalFailureInFixtureConstructorTest : public testing::Test {
<< "We should never get here, as the test fixture c'tor " << "We should never get here, as the test fixture c'tor "
<< "had a fatal failure."; << "had a fatal failure.";
} }
private: private:
void Init() { void Init() {
FAIL() << "Expected failure #1, in the test fixture c'tor."; FAIL() << "Expected failure #1, in the test fixture c'tor.";
@@ -991,7 +1004,8 @@ int main(int argc, char **argv) {
// for it. // for it.
testing::InitGoogleTest(&argc, argv); testing::InitGoogleTest(&argc, argv);
if (argc >= 2 && if (argc >= 2 &&
String(argv[1]) == "--gtest_internal_skip_environment_and_ad_hoc_tests") (std::string(argv[1]) ==
"--gtest_internal_skip_environment_and_ad_hoc_tests"))
GTEST_FLAG(internal_skip_environment_and_ad_hoc_tests) = true; GTEST_FLAG(internal_skip_environment_and_ad_hoc_tests) = true;
#if GTEST_HAS_DEATH_TEST #if GTEST_HAS_DEATH_TEST
+18 -9
View File
@@ -7,7 +7,7 @@ Expected: true
gtest_output_test_.cc:#: Failure gtest_output_test_.cc:#: Failure
Value of: 3 Value of: 3
Expected: 2 Expected: 2
[==========] Running 62 tests from 27 test cases. [==========] Running 63 tests from 28 test cases.
[----------] Global test environment set-up. [----------] Global test environment set-up.
FooEnvironment::SetUp() called. FooEnvironment::SetUp() called.
BarEnvironment::SetUp() called. BarEnvironment::SetUp() called.
@@ -31,6 +31,19 @@ BarEnvironment::SetUp() called.
[ OK ] PassingTest.PassingTest1 [ OK ] PassingTest.PassingTest1
[ RUN ] PassingTest.PassingTest2 [ RUN ] PassingTest.PassingTest2
[ OK ] PassingTest.PassingTest2 [ OK ] PassingTest.PassingTest2
[----------] 1 test from NonfatalFailureTest
[ RUN ] NonfatalFailureTest.EscapesStringOperands
gtest_output_test_.cc:#: Failure
Value of: actual
Actual: "actual \"string\""
Expected: kGoldenString
Which is: "\"Line"
gtest_output_test_.cc:#: Failure
Value of: actual
Actual: "actual \"string\""
Expected: golden
Which is: "\"Line"
[ FAILED ] NonfatalFailureTest.EscapesStringOperands
[----------] 3 tests from FatalFailureTest [----------] 3 tests from FatalFailureTest
[ RUN ] FatalFailureTest.FatalFailureInSubroutine [ RUN ] FatalFailureTest.FatalFailureInSubroutine
(expecting a failure that x should be 1) (expecting a failure that x should be 1)
@@ -586,9 +599,10 @@ FooEnvironment::TearDown() called.
gtest_output_test_.cc:#: Failure gtest_output_test_.cc:#: Failure
Failed Failed
Expected fatal failure. Expected fatal failure.
[==========] 62 tests from 27 test cases ran. [==========] 63 tests from 28 test cases ran.
[ PASSED ] 21 tests. [ PASSED ] 21 tests.
[ FAILED ] 41 tests, listed below: [ FAILED ] 42 tests, listed below:
[ FAILED ] NonfatalFailureTest.EscapesStringOperands
[ FAILED ] FatalFailureTest.FatalFailureInSubroutine [ FAILED ] FatalFailureTest.FatalFailureInSubroutine
[ FAILED ] FatalFailureTest.FatalFailureInNestedSubroutine [ FAILED ] FatalFailureTest.FatalFailureInNestedSubroutine
[ FAILED ] FatalFailureTest.NonfatalFailureInSubroutine [ FAILED ] FatalFailureTest.NonfatalFailureInSubroutine
@@ -631,7 +645,7 @@ Expected fatal failure.
[ FAILED ] ScopedFakeTestPartResultReporterTest.InterceptOnlyCurrentThread [ FAILED ] ScopedFakeTestPartResultReporterTest.InterceptOnlyCurrentThread
[ FAILED ] PrintingFailingParams/FailingParamTest.Fails/0, where GetParam() = 2 [ FAILED ] PrintingFailingParams/FailingParamTest.Fails/0, where GetParam() = 2
41 FAILED TESTS 42 FAILED TESTS
 YOU HAVE 1 DISABLED TEST  YOU HAVE 1 DISABLED TEST
Note: Google Test filter = FatalFailureTest.*:LoggingTest.* Note: Google Test filter = FatalFailureTest.*:LoggingTest.*
@@ -685,8 +699,6 @@ Expected: (3) >= (a[i]), actual: 3 vs 6
[ FAILED ] LoggingTest.InterleavingLoggingAndAssertions [ FAILED ] LoggingTest.InterleavingLoggingAndAssertions
4 FAILED TESTS 4 FAILED TESTS
YOU HAVE 1 DISABLED TEST
Note: Google Test filter = *DISABLED_* Note: Google Test filter = *DISABLED_*
[==========] Running 1 test from 1 test case. [==========] Running 1 test from 1 test case.
[----------] Global test environment set-up. [----------] Global test environment set-up.
@@ -706,6 +718,3 @@ Note: This is test shard 2 of 2.
[----------] Global test environment tear-down [----------] Global test environment tear-down
[==========] 1 test from 1 test case ran. [==========] 1 test from 1 test case ran.
[ PASSED ] 1 test. [ PASSED ] 1 test.
YOU HAVE 1 DISABLED TEST
+1 -1
View File
@@ -27,7 +27,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// This file is AUTOMATICALLY GENERATED on 09/24/2010 by command // This file is AUTOMATICALLY GENERATED on 10/31/2011 by command
// 'gen_gtest_pred_impl.py 5'. DO NOT EDIT BY HAND! // 'gen_gtest_pred_impl.py 5'. DO NOT EDIT BY HAND!
// Regression test for gtest_pred_impl.h // Regression test for gtest_pred_impl.h
+141
View File
@@ -0,0 +1,141 @@
// Copyright 2013, 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)
//
// Tests that Google Test manipulates the premature-exit-detection
// file correctly.
#include <stdio.h>
#include "gtest/gtest.h"
using ::testing::InitGoogleTest;
using ::testing::Test;
using ::testing::internal::posix::GetEnv;
using ::testing::internal::posix::Stat;
using ::testing::internal::posix::StatStruct;
namespace {
// Is the TEST_PREMATURE_EXIT_FILE environment variable expected to be
// set?
const bool kTestPrematureExitFileEnvVarShouldBeSet = false;
class PrematureExitTest : public Test {
public:
// Returns true iff the given file exists.
static bool FileExists(const char* filepath) {
StatStruct stat;
return Stat(filepath, &stat) == 0;
}
protected:
PrematureExitTest() {
premature_exit_file_path_ = GetEnv("TEST_PREMATURE_EXIT_FILE");
// Normalize NULL to "" for ease of handling.
if (premature_exit_file_path_ == NULL) {
premature_exit_file_path_ = "";
}
}
// Returns true iff the premature-exit file exists.
bool PrematureExitFileExists() const {
return FileExists(premature_exit_file_path_);
}
const char* premature_exit_file_path_;
};
typedef PrematureExitTest PrematureExitDeathTest;
// Tests that:
// - the premature-exit file exists during the execution of a
// death test (EXPECT_DEATH*), and
// - a death test doesn't interfere with the main test process's
// handling of the premature-exit file.
TEST_F(PrematureExitDeathTest, FileExistsDuringExecutionOfDeathTest) {
if (*premature_exit_file_path_ == '\0') {
return;
}
EXPECT_DEATH_IF_SUPPORTED({
// If the file exists, crash the process such that the main test
// process will catch the (expected) crash and report a success;
// otherwise don't crash, which will cause the main test process
// to report that the death test has failed.
if (PrematureExitFileExists()) {
exit(1);
}
}, "");
}
// Tests that TEST_PREMATURE_EXIT_FILE is set where it's expected to
// be set.
TEST_F(PrematureExitTest, TestPrematureExitFileEnvVarIsSet) {
if (kTestPrematureExitFileEnvVarShouldBeSet) {
const char* const filepath = GetEnv("TEST_PREMATURE_EXIT_FILE");
ASSERT_TRUE(filepath != NULL);
ASSERT_NE(*filepath, '\0');
}
}
// Tests that the premature-exit file exists during the execution of a
// normal (non-death) test.
TEST_F(PrematureExitTest, PrematureExitFileExistsDuringTestExecution) {
if (*premature_exit_file_path_ == '\0') {
return;
}
EXPECT_TRUE(PrematureExitFileExists())
<< " file " << premature_exit_file_path_
<< " should exist during test execution, but doesn't.";
}
} // namespace
int main(int argc, char **argv) {
InitGoogleTest(&argc, argv);
const int exit_code = RUN_ALL_TESTS();
// Test that the premature-exit file is deleted upon return from
// RUN_ALL_TESTS().
const char* const filepath = GetEnv("TEST_PREMATURE_EXIT_FILE");
if (filepath != NULL && *filepath != '\0') {
if (PrematureExitTest::FileExists(filepath)) {
printf(
"File %s shouldn't exist after the test program finishes, but does.",
filepath);
return 1;
}
}
return exit_code;
}
+1 -1
View File
@@ -71,7 +71,7 @@ namespace {
<< "Which is: " << expected_val << "\n";\ << "Which is: " << expected_val << "\n";\
::testing::internal::posix::Abort();\ ::testing::internal::posix::Abort();\
}\ }\
} while(::testing::internal::AlwaysFalse()) } while (::testing::internal::AlwaysFalse())
// Used for verifying that global environment set-up and tear-down are // Used for verifying that global environment set-up and tear-down are
-1
View File
@@ -42,7 +42,6 @@ using ::testing::Test;
using ::testing::TestEventListeners; using ::testing::TestEventListeners;
using ::testing::TestInfo; using ::testing::TestInfo;
using ::testing::UnitTest; using ::testing::UnitTest;
using ::testing::internal::String;
using ::testing::internal::scoped_ptr; using ::testing::internal::scoped_ptr;
// The test methods are empty, as the sole purpose of this program is // The test methods are empty, as the sole purpose of this program is
+2 -3
View File
@@ -50,7 +50,6 @@ namespace testing {
namespace { namespace {
using internal::Notification; using internal::Notification;
using internal::String;
using internal::TestPropertyKeyIs; using internal::TestPropertyKeyIs;
using internal::ThreadWithParam; using internal::ThreadWithParam;
using internal::scoped_ptr; using internal::scoped_ptr;
@@ -62,13 +61,13 @@ using internal::scoped_ptr;
// How many threads to create? // How many threads to create?
const int kThreadCount = 50; const int kThreadCount = 50;
String IdToKey(int id, const char* suffix) { std::string IdToKey(int id, const char* suffix) {
Message key; Message key;
key << "key_" << id << "_" << suffix; key << "key_" << id << "_" << suffix;
return key.GetString(); return key.GetString();
} }
String IdToString(int id) { std::string IdToString(int id) {
Message id_message; Message id_message;
id_message << id; id_message << id;
return id_message.GetString(); return id_message.GetString();
+16 -1
View File
@@ -56,6 +56,21 @@ GTEST_OUTPUT_VAR_NAME = 'GTEST_OUTPUT'
IS_WINDOWS = os.name == 'nt' IS_WINDOWS = os.name == 'nt'
IS_CYGWIN = os.name == 'posix' and 'CYGWIN' in os.uname()[0] IS_CYGWIN = os.name == 'posix' and 'CYGWIN' in os.uname()[0]
# The environment variable for specifying the path to the premature-exit file.
PREMATURE_EXIT_FILE_ENV_VAR = 'TEST_PREMATURE_EXIT_FILE'
environ = os.environ.copy()
def SetEnvVar(env_var, value):
"""Sets/unsets an environment variable to a given value."""
if value is not None:
environ[env_var] = value
elif env_var in environ:
del environ[env_var]
# Here we expose a class from a particular module, depending on the # Here we expose a class from a particular module, depending on the
# environment. The comment suppresses the 'Invalid variable name' lint # environment. The comment suppresses the 'Invalid variable name' lint
# complaint. # complaint.
@@ -241,7 +256,7 @@ class Subprocess:
# Changes made by os.environ.clear are not inheritable by child # Changes made by os.environ.clear are not inheritable by child
# processes until Python 2.6. To produce inheritable changes we have # processes until Python 2.6. To produce inheritable changes we have
# to delete environment items with the del statement. # to delete environment items with the del statement.
for key in dest: for key in dest.keys():
del dest[key] del dest[key]
dest.update(src) dest.update(src)
+17 -1
View File
@@ -37,12 +37,28 @@
#include "gtest/gtest.h" #include "gtest/gtest.h"
#include <stdio.h> // for fflush, fprintf, NULL, etc.
#include <stdlib.h> // for exit
#include <exception> // for set_terminate
// This terminate handler aborts the program using exit() rather than abort().
// This avoids showing pop-ups on Windows systems and core dumps on Unix-like
// ones.
void TerminateHandler() {
fprintf(stderr, "%s\n", "Unhandled C++ exception terminating the program.");
fflush(NULL);
exit(1);
}
int main(int argc, char** argv) { int main(int argc, char** argv) {
#if GTEST_HAS_EXCEPTIONS
std::set_terminate(&TerminateHandler);
#endif
testing::InitGoogleTest(&argc, argv); testing::InitGoogleTest(&argc, argv);
// We want to ensure that people can use Google Test assertions in // We want to ensure that people can use Google Test assertions in
// other testing frameworks, as long as they initialize Google Test // other testing frameworks, as long as they initialize Google Test
// properly and set the thrown-on-failure mode. Therefore, we don't // properly and set the throw-on-failure mode. Therefore, we don't
// use Google Test's constructs for defining and running tests // use Google Test's constructs for defining and running tests
// (e.g. TEST and RUN_ALL_TESTS) here. // (e.g. TEST and RUN_ALL_TESTS) here.
+545 -467
View File
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -45,7 +45,7 @@ GTEST_OUTPUT_1_TEST = "gtest_xml_outfile1_test_"
GTEST_OUTPUT_2_TEST = "gtest_xml_outfile2_test_" GTEST_OUTPUT_2_TEST = "gtest_xml_outfile2_test_"
EXPECTED_XML_1 = """<?xml version="1.0" encoding="UTF-8"?> EXPECTED_XML_1 = """<?xml version="1.0" encoding="UTF-8"?>
<testsuites tests="1" failures="0" disabled="0" errors="0" time="*" name="AllTests"> <testsuites tests="1" failures="0" disabled="0" errors="0" time="*" timestamp="*" name="AllTests">
<testsuite name="PropertyOne" tests="1" failures="0" disabled="0" errors="0" time="*"> <testsuite name="PropertyOne" tests="1" failures="0" disabled="0" errors="0" time="*">
<testcase name="TestSomeProperties" status="run" time="*" classname="PropertyOne" SetUpProp="1" TestSomeProperty="1" TearDownProp="1" /> <testcase name="TestSomeProperties" status="run" time="*" classname="PropertyOne" SetUpProp="1" TestSomeProperty="1" TearDownProp="1" />
</testsuite> </testsuite>
@@ -53,7 +53,7 @@ EXPECTED_XML_1 = """<?xml version="1.0" encoding="UTF-8"?>
""" """
EXPECTED_XML_2 = """<?xml version="1.0" encoding="UTF-8"?> EXPECTED_XML_2 = """<?xml version="1.0" encoding="UTF-8"?>
<testsuites tests="1" failures="0" disabled="0" errors="0" time="*" name="AllTests"> <testsuites tests="1" failures="0" disabled="0" errors="0" time="*" timestamp="*" name="AllTests">
<testsuite name="PropertyTwo" tests="1" failures="0" disabled="0" errors="0" time="*"> <testsuite name="PropertyTwo" tests="1" failures="0" disabled="0" errors="0" time="*">
<testcase name="TestSomeProperties" status="run" time="*" classname="PropertyTwo" SetUpProp="2" TestSomeProperty="2" TearDownProp="2" /> <testcase name="TestSomeProperties" status="run" time="*" classname="PropertyTwo" SetUpProp="2" TestSomeProperty="2" TearDownProp="2" />
</testsuite> </testsuite>
+114 -49
View File
@@ -33,8 +33,10 @@
__author__ = 'eefacm@gmail.com (Sean Mcafee)' __author__ = 'eefacm@gmail.com (Sean Mcafee)'
import datetime
import errno import errno
import os import os
import re
import sys import sys
from xml.dom import minidom, Node from xml.dom import minidom, Node
@@ -42,6 +44,8 @@ import gtest_test_utils
import gtest_xml_test_utils import gtest_xml_test_utils
GTEST_FILTER_FLAG = '--gtest_filter'
GTEST_LIST_TESTS_FLAG = '--gtest_list_tests'
GTEST_OUTPUT_FLAG = "--gtest_output" GTEST_OUTPUT_FLAG = "--gtest_output"
GTEST_DEFAULT_OUTPUT_FILE = "test_detail.xml" GTEST_DEFAULT_OUTPUT_FILE = "test_detail.xml"
GTEST_PROGRAM_NAME = "gtest_xml_output_unittest_" GTEST_PROGRAM_NAME = "gtest_xml_output_unittest_"
@@ -49,18 +53,18 @@ GTEST_PROGRAM_NAME = "gtest_xml_output_unittest_"
SUPPORTS_STACK_TRACES = False SUPPORTS_STACK_TRACES = False
if SUPPORTS_STACK_TRACES: if SUPPORTS_STACK_TRACES:
STACK_TRACE_TEMPLATE = "\nStack trace:\n*" STACK_TRACE_TEMPLATE = '\nStack trace:\n*'
else: else:
STACK_TRACE_TEMPLATE = "" STACK_TRACE_TEMPLATE = ''
EXPECTED_NON_EMPTY_XML = """<?xml version="1.0" encoding="UTF-8"?> EXPECTED_NON_EMPTY_XML = """<?xml version="1.0" encoding="UTF-8"?>
<testsuites tests="23" failures="4" disabled="2" errors="0" time="*" name="AllTests"> <testsuites tests="23" failures="4" disabled="2" errors="0" time="*" timestamp="*" name="AllTests" ad_hoc_property="42">
<testsuite name="SuccessfulTest" tests="1" failures="0" disabled="0" errors="0" time="*"> <testsuite name="SuccessfulTest" tests="1" failures="0" disabled="0" errors="0" time="*">
<testcase name="Succeeds" status="run" time="*" classname="SuccessfulTest"/> <testcase name="Succeeds" status="run" time="*" classname="SuccessfulTest"/>
</testsuite> </testsuite>
<testsuite name="FailedTest" tests="1" failures="1" disabled="0" errors="0" time="*"> <testsuite name="FailedTest" tests="1" failures="1" disabled="0" errors="0" time="*">
<testcase name="Fails" status="run" time="*" classname="FailedTest"> <testcase name="Fails" status="run" time="*" classname="FailedTest">
<failure message="Value of: 2&#x0A;Expected: 1" type=""><![CDATA[gtest_xml_output_unittest_.cc:* <failure message="gtest_xml_output_unittest_.cc:*&#x0A;Value of: 2&#x0A;Expected: 1" type=""><![CDATA[gtest_xml_output_unittest_.cc:*
Value of: 2 Value of: 2
Expected: 1%(stack)s]]></failure> Expected: 1%(stack)s]]></failure>
</testcase> </testcase>
@@ -68,10 +72,10 @@ Expected: 1%(stack)s]]></failure>
<testsuite name="MixedResultTest" tests="3" failures="1" disabled="1" errors="0" time="*"> <testsuite name="MixedResultTest" tests="3" failures="1" disabled="1" errors="0" time="*">
<testcase name="Succeeds" status="run" time="*" classname="MixedResultTest"/> <testcase name="Succeeds" status="run" time="*" classname="MixedResultTest"/>
<testcase name="Fails" status="run" time="*" classname="MixedResultTest"> <testcase name="Fails" status="run" time="*" classname="MixedResultTest">
<failure message="Value of: 2&#x0A;Expected: 1" type=""><![CDATA[gtest_xml_output_unittest_.cc:* <failure message="gtest_xml_output_unittest_.cc:*&#x0A;Value of: 2&#x0A;Expected: 1" type=""><![CDATA[gtest_xml_output_unittest_.cc:*
Value of: 2 Value of: 2
Expected: 1%(stack)s]]></failure> Expected: 1%(stack)s]]></failure>
<failure message="Value of: 3&#x0A;Expected: 2" type=""><![CDATA[gtest_xml_output_unittest_.cc:* <failure message="gtest_xml_output_unittest_.cc:*&#x0A;Value of: 3&#x0A;Expected: 2" type=""><![CDATA[gtest_xml_output_unittest_.cc:*
Value of: 3 Value of: 3
Expected: 2%(stack)s]]></failure> Expected: 2%(stack)s]]></failure>
</testcase> </testcase>
@@ -79,14 +83,14 @@ Expected: 2%(stack)s]]></failure>
</testsuite> </testsuite>
<testsuite name="XmlQuotingTest" tests="1" failures="1" disabled="0" errors="0" time="*"> <testsuite name="XmlQuotingTest" tests="1" failures="1" disabled="0" errors="0" time="*">
<testcase name="OutputsCData" status="run" time="*" classname="XmlQuotingTest"> <testcase name="OutputsCData" status="run" time="*" classname="XmlQuotingTest">
<failure message="Failed&#x0A;XML output: &lt;?xml encoding=&quot;utf-8&quot;&gt;&lt;top&gt;&lt;![CDATA[cdata text]]&gt;&lt;/top&gt;" type=""><![CDATA[gtest_xml_output_unittest_.cc:* <failure message="gtest_xml_output_unittest_.cc:*&#x0A;Failed&#x0A;XML output: &lt;?xml encoding=&quot;utf-8&quot;&gt;&lt;top&gt;&lt;![CDATA[cdata text]]&gt;&lt;/top&gt;" type=""><![CDATA[gtest_xml_output_unittest_.cc:*
Failed Failed
XML output: <?xml encoding="utf-8"><top><![CDATA[cdata text]]>]]&gt;<![CDATA[</top>%(stack)s]]></failure> XML output: <?xml encoding="utf-8"><top><![CDATA[cdata text]]>]]&gt;<![CDATA[</top>%(stack)s]]></failure>
</testcase> </testcase>
</testsuite> </testsuite>
<testsuite name="InvalidCharactersTest" tests="1" failures="1" disabled="0" errors="0" time="*"> <testsuite name="InvalidCharactersTest" tests="1" failures="1" disabled="0" errors="0" time="*">
<testcase name="InvalidCharactersInMessage" status="run" time="*" classname="InvalidCharactersTest"> <testcase name="InvalidCharactersInMessage" status="run" time="*" classname="InvalidCharactersTest">
<failure message="Failed&#x0A;Invalid characters in brackets []" type=""><![CDATA[gtest_xml_output_unittest_.cc:* <failure message="gtest_xml_output_unittest_.cc:*&#x0A;Failed&#x0A;Invalid characters in brackets []" type=""><![CDATA[gtest_xml_output_unittest_.cc:*
Failed Failed
Invalid characters in brackets []%(stack)s]]></failure> Invalid characters in brackets []%(stack)s]]></failure>
</testcase> </testcase>
@@ -94,7 +98,7 @@ Invalid characters in brackets []%(stack)s]]></failure>
<testsuite name="DisabledTest" tests="1" failures="0" disabled="1" errors="0" time="*"> <testsuite name="DisabledTest" tests="1" failures="0" disabled="1" errors="0" time="*">
<testcase name="DISABLED_test_not_run" status="notrun" time="*" classname="DisabledTest"/> <testcase name="DISABLED_test_not_run" status="notrun" time="*" classname="DisabledTest"/>
</testsuite> </testsuite>
<testsuite name="PropertyRecordingTest" tests="4" failures="0" disabled="0" errors="0" time="*"> <testsuite name="PropertyRecordingTest" tests="4" failures="0" disabled="0" errors="0" time="*" SetUpTestCase="yes" TearDownTestCase="aye">
<testcase name="OneProperty" status="run" time="*" classname="PropertyRecordingTest" key_1="1"/> <testcase name="OneProperty" status="run" time="*" classname="PropertyRecordingTest" key_1="1"/>
<testcase name="IntValuedProperty" status="run" time="*" classname="PropertyRecordingTest" key_int="1"/> <testcase name="IntValuedProperty" status="run" time="*" classname="PropertyRecordingTest" key_int="1"/>
<testcase name="ThreeProperties" status="run" time="*" classname="PropertyRecordingTest" key_1="1" key_2="2" key_3="3"/> <testcase name="ThreeProperties" status="run" time="*" classname="PropertyRecordingTest" key_1="1" key_2="2" key_3="3"/>
@@ -125,32 +129,74 @@ Invalid characters in brackets []%(stack)s]]></failure>
</testsuite> </testsuite>
</testsuites>""" % {'stack': STACK_TRACE_TEMPLATE} </testsuites>""" % {'stack': STACK_TRACE_TEMPLATE}
EXPECTED_FILTERED_TEST_XML = """<?xml version="1.0" encoding="UTF-8"?>
<testsuites tests="1" failures="0" disabled="0" errors="0" time="*"
timestamp="*" name="AllTests" ad_hoc_property="42">
<testsuite name="SuccessfulTest" tests="1" failures="0" disabled="0"
errors="0" time="*">
<testcase name="Succeeds" status="run" time="*" classname="SuccessfulTest"/>
</testsuite>
</testsuites>"""
EXPECTED_EMPTY_XML = """<?xml version="1.0" encoding="UTF-8"?> EXPECTED_EMPTY_XML = """<?xml version="1.0" encoding="UTF-8"?>
<testsuites tests="0" failures="0" disabled="0" errors="0" time="*" name="AllTests"> <testsuites tests="0" failures="0" disabled="0" errors="0" time="*"
timestamp="*" name="AllTests">
</testsuites>""" </testsuites>"""
GTEST_PROGRAM_PATH = gtest_test_utils.GetTestExecutablePath(GTEST_PROGRAM_NAME)
SUPPORTS_TYPED_TESTS = 'TypedTest' in gtest_test_utils.Subprocess(
[GTEST_PROGRAM_PATH, GTEST_LIST_TESTS_FLAG], capture_stderr=False).output
class GTestXMLOutputUnitTest(gtest_xml_test_utils.GTestXMLTestCase): class GTestXMLOutputUnitTest(gtest_xml_test_utils.GTestXMLTestCase):
""" """
Unit test for Google Test's XML output functionality. Unit test for Google Test's XML output functionality.
""" """
def testNonEmptyXmlOutput(self): # This test currently breaks on platforms that do not support typed and
""" # type-parameterized tests, so we don't run it under them.
Runs a test program that generates a non-empty XML output, and if SUPPORTS_TYPED_TESTS:
tests that the XML output is expected. def testNonEmptyXmlOutput(self):
""" """
self._TestXmlOutput(GTEST_PROGRAM_NAME, EXPECTED_NON_EMPTY_XML, 1) Runs a test program that generates a non-empty XML output, and
tests that the XML output is expected.
"""
self._TestXmlOutput(GTEST_PROGRAM_NAME, EXPECTED_NON_EMPTY_XML, 1)
def testEmptyXmlOutput(self): def testEmptyXmlOutput(self):
""" """Verifies XML output for a Google Test binary without actual tests.
Runs a test program that generates an empty XML output, and Runs a test program that generates an empty XML output, and
tests that the XML output is expected. tests that the XML output is expected.
""" """
self._TestXmlOutput("gtest_no_test_unittest", self._TestXmlOutput('gtest_no_test_unittest', EXPECTED_EMPTY_XML, 0)
EXPECTED_EMPTY_XML, 0)
def testTimestampValue(self):
"""Checks whether the timestamp attribute in the XML output is valid.
Runs a test program that generates an empty XML output, and checks if
the timestamp attribute in the testsuites tag is valid.
"""
actual = self._GetXmlOutput('gtest_no_test_unittest', [], 0)
date_time_str = actual.documentElement.getAttributeNode('timestamp').value
# datetime.strptime() is only available in Python 2.5+ so we have to
# parse the expected datetime manually.
match = re.match(r'(\d+)-(\d\d)-(\d\d)T(\d\d):(\d\d):(\d\d)', date_time_str)
self.assertTrue(
re.match,
'XML datettime string %s has incorrect format' % date_time_str)
date_time_from_xml = datetime.datetime(
year=int(match.group(1)), month=int(match.group(2)),
day=int(match.group(3)), hour=int(match.group(4)),
minute=int(match.group(5)), second=int(match.group(6)))
time_delta = abs(datetime.datetime.now() - date_time_from_xml)
# timestamp value should be near the current local time
self.assertTrue(time_delta < datetime.timedelta(seconds=600),
'time_delta is %s' % time_delta)
actual.unlink()
def testDefaultOutputFile(self): def testDefaultOutputFile(self):
""" """
@@ -160,7 +206,7 @@ class GTestXMLOutputUnitTest(gtest_xml_test_utils.GTestXMLTestCase):
output_file = os.path.join(gtest_test_utils.GetTempDir(), output_file = os.path.join(gtest_test_utils.GetTempDir(),
GTEST_DEFAULT_OUTPUT_FILE) GTEST_DEFAULT_OUTPUT_FILE)
gtest_prog_path = gtest_test_utils.GetTestExecutablePath( gtest_prog_path = gtest_test_utils.GetTestExecutablePath(
"gtest_no_test_unittest") 'gtest_no_test_unittest')
try: try:
os.remove(output_file) os.remove(output_file)
except OSError, e: except OSError, e:
@@ -168,7 +214,7 @@ class GTestXMLOutputUnitTest(gtest_xml_test_utils.GTestXMLTestCase):
raise raise
p = gtest_test_utils.Subprocess( p = gtest_test_utils.Subprocess(
[gtest_prog_path, "%s=xml" % GTEST_OUTPUT_FLAG], [gtest_prog_path, '%s=xml' % GTEST_OUTPUT_FLAG],
working_dir=gtest_test_utils.GetTempDir()) working_dir=gtest_test_utils.GetTempDir())
self.assert_(p.exited) self.assert_(p.exited)
self.assertEquals(0, p.exit_code) self.assertEquals(0, p.exit_code)
@@ -181,60 +227,79 @@ class GTestXMLOutputUnitTest(gtest_xml_test_utils.GTestXMLTestCase):
""" """
xml_path = os.path.join(gtest_test_utils.GetTempDir(), xml_path = os.path.join(gtest_test_utils.GetTempDir(),
GTEST_PROGRAM_NAME + "out.xml") GTEST_PROGRAM_NAME + 'out.xml')
if os.path.isfile(xml_path): if os.path.isfile(xml_path):
os.remove(xml_path) os.remove(xml_path)
gtest_prog_path = gtest_test_utils.GetTestExecutablePath(GTEST_PROGRAM_NAME) command = [GTEST_PROGRAM_PATH,
'%s=xml:%s' % (GTEST_OUTPUT_FLAG, xml_path),
command = [gtest_prog_path, '--shut_down_xml']
"%s=xml:%s" % (GTEST_OUTPUT_FLAG, xml_path),
"--shut_down_xml"]
p = gtest_test_utils.Subprocess(command) p = gtest_test_utils.Subprocess(command)
if p.terminated_by_signal: if p.terminated_by_signal:
self.assert_(False, # p.signal is avalable only if p.terminated_by_signal is True.
"%s was killed by signal %d" % (gtest_prog_name, p.signal)) self.assertFalse(
p.terminated_by_signal,
'%s was killed by signal %d' % (GTEST_PROGRAM_NAME, p.signal))
else: else:
self.assert_(p.exited) self.assert_(p.exited)
self.assertEquals(1, p.exit_code, self.assertEquals(1, p.exit_code,
"'%s' exited with code %s, which doesn't match " "'%s' exited with code %s, which doesn't match "
"the expected exit code %s." 'the expected exit code %s.'
% (command, p.exit_code, 1)) % (command, p.exit_code, 1))
self.assert_(not os.path.isfile(xml_path)) self.assert_(not os.path.isfile(xml_path))
def testFilteredTestXmlOutput(self):
"""Verifies XML output when a filter is applied.
def _TestXmlOutput(self, gtest_prog_name, expected_xml, expected_exit_code): Runs a test program that executes only some tests and verifies that
non-selected tests do not show up in the XML output.
"""
self._TestXmlOutput(GTEST_PROGRAM_NAME, EXPECTED_FILTERED_TEST_XML, 0,
extra_args=['%s=SuccessfulTest.*' % GTEST_FILTER_FLAG])
def _GetXmlOutput(self, gtest_prog_name, extra_args, expected_exit_code):
"""
Returns the xml output generated by running the program gtest_prog_name.
Furthermore, the program's exit code must be expected_exit_code.
"""
xml_path = os.path.join(gtest_test_utils.GetTempDir(),
gtest_prog_name + 'out.xml')
gtest_prog_path = gtest_test_utils.GetTestExecutablePath(gtest_prog_name)
command = ([gtest_prog_path, '%s=xml:%s' % (GTEST_OUTPUT_FLAG, xml_path)] +
extra_args)
p = gtest_test_utils.Subprocess(command)
if p.terminated_by_signal:
self.assert_(False,
'%s was killed by signal %d' % (gtest_prog_name, p.signal))
else:
self.assert_(p.exited)
self.assertEquals(expected_exit_code, p.exit_code,
"'%s' exited with code %s, which doesn't match "
'the expected exit code %s.'
% (command, p.exit_code, expected_exit_code))
actual = minidom.parse(xml_path)
return actual
def _TestXmlOutput(self, gtest_prog_name, expected_xml,
expected_exit_code, extra_args=None):
""" """
Asserts that the XML document generated by running the program Asserts that the XML document generated by running the program
gtest_prog_name matches expected_xml, a string containing another gtest_prog_name matches expected_xml, a string containing another
XML document. Furthermore, the program's exit code must be XML document. Furthermore, the program's exit code must be
expected_exit_code. expected_exit_code.
""" """
xml_path = os.path.join(gtest_test_utils.GetTempDir(),
gtest_prog_name + "out.xml")
gtest_prog_path = gtest_test_utils.GetTestExecutablePath(gtest_prog_name)
command = [gtest_prog_path, "%s=xml:%s" % (GTEST_OUTPUT_FLAG, xml_path)]
p = gtest_test_utils.Subprocess(command)
if p.terminated_by_signal:
self.assert_(False,
"%s was killed by signal %d" % (gtest_prog_name, p.signal))
else:
self.assert_(p.exited)
self.assertEquals(expected_exit_code, p.exit_code,
"'%s' exited with code %s, which doesn't match "
"the expected exit code %s."
% (command, p.exit_code, expected_exit_code))
actual = self._GetXmlOutput(gtest_prog_name, extra_args or [],
expected_exit_code)
expected = minidom.parseString(expected_xml) expected = minidom.parseString(expected_xml)
actual = minidom.parse(xml_path)
self.NormalizeXml(actual.documentElement) self.NormalizeXml(actual.documentElement)
self.AssertEquivalentNodes(expected.documentElement, self.AssertEquivalentNodes(expected.documentElement,
actual.documentElement) actual.documentElement)
expected.unlink() expected.unlink()
actual .unlink() actual.unlink()
if __name__ == '__main__': if __name__ == '__main__':
+13 -6
View File
@@ -45,7 +45,6 @@ using ::testing::TestEventListeners;
using ::testing::TestWithParam; using ::testing::TestWithParam;
using ::testing::UnitTest; using ::testing::UnitTest;
using ::testing::Test; using ::testing::Test;
using ::testing::Types;
using ::testing::Values; using ::testing::Values;
class SuccessfulTest : public Test { class SuccessfulTest : public Test {
@@ -96,6 +95,9 @@ TEST(InvalidCharactersTest, InvalidCharactersInMessage) {
} }
class PropertyRecordingTest : public Test { class PropertyRecordingTest : public Test {
public:
static void SetUpTestCase() { RecordProperty("SetUpTestCase", "yes"); }
static void TearDownTestCase() { RecordProperty("TearDownTestCase", "aye"); }
}; };
TEST_F(PropertyRecordingTest, OneProperty) { TEST_F(PropertyRecordingTest, OneProperty) {
@@ -121,12 +123,12 @@ TEST(NoFixtureTest, RecordProperty) {
RecordProperty("key", "1"); RecordProperty("key", "1");
} }
void ExternalUtilityThatCallsRecordProperty(const char* key, int value) { void ExternalUtilityThatCallsRecordProperty(const std::string& key, int value) {
testing::Test::RecordProperty(key, value); testing::Test::RecordProperty(key, value);
} }
void ExternalUtilityThatCallsRecordProperty(const char* key, void ExternalUtilityThatCallsRecordProperty(const std::string& key,
const char* value) { const std::string& value) {
testing::Test::RecordProperty(key, value); testing::Test::RecordProperty(key, value);
} }
@@ -145,23 +147,27 @@ TEST_P(ValueParamTest, HasValueParamAttribute) {}
TEST_P(ValueParamTest, AnotherTestThatHasValueParamAttribute) {} TEST_P(ValueParamTest, AnotherTestThatHasValueParamAttribute) {}
INSTANTIATE_TEST_CASE_P(Single, ValueParamTest, Values(33, 42)); INSTANTIATE_TEST_CASE_P(Single, ValueParamTest, Values(33, 42));
#if GTEST_HAS_TYPED_TEST
// Verifies that the type parameter name is output in the 'type_param' // Verifies that the type parameter name is output in the 'type_param'
// XML attribute for typed tests. // XML attribute for typed tests.
template <typename T> class TypedTest : public Test {}; template <typename T> class TypedTest : public Test {};
typedef Types<int, long> TypedTestTypes; typedef testing::Types<int, long> TypedTestTypes;
TYPED_TEST_CASE(TypedTest, TypedTestTypes); TYPED_TEST_CASE(TypedTest, TypedTestTypes);
TYPED_TEST(TypedTest, HasTypeParamAttribute) {} TYPED_TEST(TypedTest, HasTypeParamAttribute) {}
#endif
#if GTEST_HAS_TYPED_TEST_P
// Verifies that the type parameter name is output in the 'type_param' // Verifies that the type parameter name is output in the 'type_param'
// XML attribute for type-parameterized tests. // XML attribute for type-parameterized tests.
template <typename T> class TypeParameterizedTestCase : public Test {}; template <typename T> class TypeParameterizedTestCase : public Test {};
TYPED_TEST_CASE_P(TypeParameterizedTestCase); TYPED_TEST_CASE_P(TypeParameterizedTestCase);
TYPED_TEST_P(TypeParameterizedTestCase, HasTypeParamAttribute) {} TYPED_TEST_P(TypeParameterizedTestCase, HasTypeParamAttribute) {}
REGISTER_TYPED_TEST_CASE_P(TypeParameterizedTestCase, HasTypeParamAttribute); REGISTER_TYPED_TEST_CASE_P(TypeParameterizedTestCase, HasTypeParamAttribute);
typedef Types<int, long> TypeParameterizedTestCaseTypes; typedef testing::Types<int, long> TypeParameterizedTestCaseTypes;
INSTANTIATE_TYPED_TEST_CASE_P(Single, INSTANTIATE_TYPED_TEST_CASE_P(Single,
TypeParameterizedTestCase, TypeParameterizedTestCase,
TypeParameterizedTestCaseTypes); TypeParameterizedTestCaseTypes);
#endif
int main(int argc, char** argv) { int main(int argc, char** argv) {
InitGoogleTest(&argc, argv); InitGoogleTest(&argc, argv);
@@ -170,5 +176,6 @@ int main(int argc, char** argv) {
TestEventListeners& listeners = UnitTest::GetInstance()->listeners(); TestEventListeners& listeners = UnitTest::GetInstance()->listeners();
delete listeners.Release(listeners.default_xml_generator()); delete listeners.Release(listeners.default_xml_generator());
} }
testing::Test::RecordProperty("ad_hoc_property", "42");
return RUN_ALL_TESTS(); return RUN_ALL_TESTS();
} }
+44 -29
View File
@@ -39,8 +39,8 @@ from xml.dom import minidom, Node
import gtest_test_utils import gtest_test_utils
GTEST_OUTPUT_FLAG = "--gtest_output" GTEST_OUTPUT_FLAG = '--gtest_output'
GTEST_DEFAULT_OUTPUT_FILE = "test_detail.xml" GTEST_DEFAULT_OUTPUT_FILE = 'test_detail.xml'
class GTestXMLTestCase(gtest_test_utils.TestCase): class GTestXMLTestCase(gtest_test_utils.TestCase):
""" """
@@ -80,23 +80,27 @@ class GTestXMLTestCase(gtest_test_utils.TestCase):
actual_attributes = actual_node .attributes actual_attributes = actual_node .attributes
self.assertEquals( self.assertEquals(
expected_attributes.length, actual_attributes.length, expected_attributes.length, actual_attributes.length,
"attribute numbers differ in element " + actual_node.tagName) 'attribute numbers differ in element %s:\nExpected: %r\nActual: %r' % (
actual_node.tagName, expected_attributes.keys(),
actual_attributes.keys()))
for i in range(expected_attributes.length): for i in range(expected_attributes.length):
expected_attr = expected_attributes.item(i) expected_attr = expected_attributes.item(i)
actual_attr = actual_attributes.get(expected_attr.name) actual_attr = actual_attributes.get(expected_attr.name)
self.assert_( self.assert_(
actual_attr is not None, actual_attr is not None,
"expected attribute %s not found in element %s" % 'expected attribute %s not found in element %s' %
(expected_attr.name, actual_node.tagName)) (expected_attr.name, actual_node.tagName))
self.assertEquals(expected_attr.value, actual_attr.value, self.assertEquals(
" values of attribute %s in element %s differ" % expected_attr.value, actual_attr.value,
(expected_attr.name, actual_node.tagName)) ' values of attribute %s in element %s differ: %s vs %s' %
(expected_attr.name, actual_node.tagName,
expected_attr.value, actual_attr.value))
expected_children = self._GetChildren(expected_node) expected_children = self._GetChildren(expected_node)
actual_children = self._GetChildren(actual_node) actual_children = self._GetChildren(actual_node)
self.assertEquals( self.assertEquals(
len(expected_children), len(actual_children), len(expected_children), len(actual_children),
"number of child elements differ in element " + actual_node.tagName) 'number of child elements differ in element ' + actual_node.tagName)
for child_id, child in expected_children.iteritems(): for child_id, child in expected_children.iteritems():
self.assert_(child_id in actual_children, self.assert_(child_id in actual_children,
'<%s> is not in <%s> (in element %s)' % '<%s> is not in <%s> (in element %s)' %
@@ -104,10 +108,10 @@ class GTestXMLTestCase(gtest_test_utils.TestCase):
self.AssertEquivalentNodes(child, actual_children[child_id]) self.AssertEquivalentNodes(child, actual_children[child_id])
identifying_attribute = { identifying_attribute = {
"testsuites": "name", 'testsuites': 'name',
"testsuite": "name", 'testsuite': 'name',
"testcase": "name", 'testcase': 'name',
"failure": "message", 'failure': 'message',
} }
def _GetChildren(self, element): def _GetChildren(self, element):
@@ -127,20 +131,20 @@ class GTestXMLTestCase(gtest_test_utils.TestCase):
for child in element.childNodes: for child in element.childNodes:
if child.nodeType == Node.ELEMENT_NODE: if child.nodeType == Node.ELEMENT_NODE:
self.assert_(child.tagName in self.identifying_attribute, self.assert_(child.tagName in self.identifying_attribute,
"Encountered unknown element <%s>" % child.tagName) 'Encountered unknown element <%s>' % child.tagName)
childID = child.getAttribute(self.identifying_attribute[child.tagName]) childID = child.getAttribute(self.identifying_attribute[child.tagName])
self.assert_(childID not in children) self.assert_(childID not in children)
children[childID] = child children[childID] = child
elif child.nodeType in [Node.TEXT_NODE, Node.CDATA_SECTION_NODE]: elif child.nodeType in [Node.TEXT_NODE, Node.CDATA_SECTION_NODE]:
if "detail" not in children: if 'detail' not in children:
if (child.nodeType == Node.CDATA_SECTION_NODE or if (child.nodeType == Node.CDATA_SECTION_NODE or
not child.nodeValue.isspace()): not child.nodeValue.isspace()):
children["detail"] = child.ownerDocument.createCDATASection( children['detail'] = child.ownerDocument.createCDATASection(
child.nodeValue) child.nodeValue)
else: else:
children["detail"].nodeValue += child.nodeValue children['detail'].nodeValue += child.nodeValue
else: else:
self.fail("Encountered unexpected node type %d" % child.nodeType) self.fail('Encountered unexpected node type %d' % child.nodeType)
return children return children
def NormalizeXml(self, element): def NormalizeXml(self, element):
@@ -151,29 +155,40 @@ class GTestXMLTestCase(gtest_test_utils.TestCase):
* The "time" attribute of <testsuites>, <testsuite> and <testcase> * The "time" attribute of <testsuites>, <testsuite> and <testcase>
elements is replaced with a single asterisk, if it contains elements is replaced with a single asterisk, if it contains
only digit characters. only digit characters.
* The "timestamp" attribute of <testsuites> elements is replaced with a
single asterisk, if it contains a valid ISO8601 datetime value.
* The "type_param" attribute of <testcase> elements is replaced with a * The "type_param" attribute of <testcase> elements is replaced with a
single asterisk (if it sn non-empty) as it is the type name returned single asterisk (if it sn non-empty) as it is the type name returned
by the compiler and is platform dependent. by the compiler and is platform dependent.
* The line number reported in the first line of the "message" * The line info reported in the first line of the "message"
attribute of <failure> elements is replaced with a single asterisk. attribute and CDATA section of <failure> elements is replaced with the
file's basename and a single asterisk for the line number.
* The directory names in file paths are removed. * The directory names in file paths are removed.
* The stack traces are removed. * The stack traces are removed.
""" """
if element.tagName in ("testsuites", "testsuite", "testcase"): if element.tagName == 'testsuites':
time = element.getAttributeNode("time") timestamp = element.getAttributeNode('timestamp')
time.value = re.sub(r"^\d+(\.\d+)?$", "*", time.value) timestamp.value = re.sub(r'^\d{4}-\d\d-\d\dT\d\d:\d\d:\d\d$',
type_param = element.getAttributeNode("type_param") '*', timestamp.value)
if element.tagName in ('testsuites', 'testsuite', 'testcase'):
time = element.getAttributeNode('time')
time.value = re.sub(r'^\d+(\.\d+)?$', '*', time.value)
type_param = element.getAttributeNode('type_param')
if type_param and type_param.value: if type_param and type_param.value:
type_param.value = "*" type_param.value = '*'
elif element.tagName == "failure": elif element.tagName == 'failure':
source_line_pat = r'^.*[/\\](.*:)\d+\n'
# Replaces the source line information with a normalized form.
message = element.getAttributeNode('message')
message.value = re.sub(source_line_pat, '\\1*\n', message.value)
for child in element.childNodes: for child in element.childNodes:
if child.nodeType == Node.CDATA_SECTION_NODE: if child.nodeType == Node.CDATA_SECTION_NODE:
# Removes the source line number. # Replaces the source line information with a normalized form.
cdata = re.sub(r"^.*[/\\](.*:)\d+\n", "\\1*\n", child.nodeValue) cdata = re.sub(source_line_pat, '\\1*\n', child.nodeValue)
# Removes the actual stack trace. # Removes the actual stack trace.
child.nodeValue = re.sub(r"\nStack trace:\n(.|\n)*", child.nodeValue = re.sub(r'\nStack trace:\n(.|\n)*',
"", cdata) '', cdata)
for child in element.childNodes: for child in element.childNodes:
if child.nodeType == Node.ELEMENT_NODE: if child.nodeType == Node.ELEMENT_NODE:
self.NormalizeXml(child) self.NormalizeXml(child)
+58 -7
View File
@@ -3,7 +3,7 @@
archiveVersion = 1; archiveVersion = 1;
classes = { classes = {
}; };
objectVersion = 42; objectVersion = 46;
objects = { objects = {
/* Begin PBXAggregateTarget section */ /* Begin PBXAggregateTarget section */
@@ -54,7 +54,7 @@
404884A40E2F7BE600CF7658 /* gtest-string.h in Copy Headers Internal */ = {isa = PBXBuildFile; fileRef = 404883E60E2F799B00CF7658 /* gtest-string.h */; }; 404884A40E2F7BE600CF7658 /* gtest-string.h in Copy Headers Internal */ = {isa = PBXBuildFile; fileRef = 404883E60E2F799B00CF7658 /* gtest-string.h */; };
404884AC0E2F7CD900CF7658 /* CHANGES in Resources */ = {isa = PBXBuildFile; fileRef = 404884A90E2F7CD900CF7658 /* CHANGES */; }; 404884AC0E2F7CD900CF7658 /* CHANGES in Resources */ = {isa = PBXBuildFile; fileRef = 404884A90E2F7CD900CF7658 /* CHANGES */; };
404884AD0E2F7CD900CF7658 /* CONTRIBUTORS in Resources */ = {isa = PBXBuildFile; fileRef = 404884AA0E2F7CD900CF7658 /* CONTRIBUTORS */; }; 404884AD0E2F7CD900CF7658 /* CONTRIBUTORS in Resources */ = {isa = PBXBuildFile; fileRef = 404884AA0E2F7CD900CF7658 /* CONTRIBUTORS */; };
404884AE0E2F7CD900CF7658 /* COPYING in Resources */ = {isa = PBXBuildFile; fileRef = 404884AB0E2F7CD900CF7658 /* COPYING */; }; 404884AE0E2F7CD900CF7658 /* LICENSE in Resources */ = {isa = PBXBuildFile; fileRef = 404884AB0E2F7CD900CF7658 /* LICENSE */; };
40899F3A0FFA70D4000B29AE /* gtest-all.cc in Sources */ = {isa = PBXBuildFile; fileRef = 224A12A10E9EADA700BD17FD /* gtest-all.cc */; }; 40899F3A0FFA70D4000B29AE /* gtest-all.cc in Sources */ = {isa = PBXBuildFile; fileRef = 224A12A10E9EADA700BD17FD /* gtest-all.cc */; };
40899F500FFA7281000B29AE /* gtest-tuple.h in Copy Headers Internal */ = {isa = PBXBuildFile; fileRef = 40899F4D0FFA7271000B29AE /* gtest-tuple.h */; }; 40899F500FFA7281000B29AE /* gtest-tuple.h in Copy Headers Internal */ = {isa = PBXBuildFile; fileRef = 40899F4D0FFA7271000B29AE /* gtest-tuple.h */; };
40899F530FFA72A0000B29AE /* gtest_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = 3B238C120E7FE13C00846E11 /* gtest_unittest.cc */; }; 40899F530FFA72A0000B29AE /* gtest_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = 3B238C120E7FE13C00846E11 /* gtest_unittest.cc */; };
@@ -221,7 +221,7 @@
4048840D0E2F799B00CF7658 /* gtest_main.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gtest_main.cc; sourceTree = "<group>"; }; 4048840D0E2F799B00CF7658 /* gtest_main.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gtest_main.cc; sourceTree = "<group>"; };
404884A90E2F7CD900CF7658 /* CHANGES */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = CHANGES; path = ../CHANGES; sourceTree = SOURCE_ROOT; }; 404884A90E2F7CD900CF7658 /* CHANGES */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = CHANGES; path = ../CHANGES; sourceTree = SOURCE_ROOT; };
404884AA0E2F7CD900CF7658 /* CONTRIBUTORS */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = CONTRIBUTORS; path = ../CONTRIBUTORS; sourceTree = SOURCE_ROOT; }; 404884AA0E2F7CD900CF7658 /* CONTRIBUTORS */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = CONTRIBUTORS; path = ../CONTRIBUTORS; sourceTree = SOURCE_ROOT; };
404884AB0E2F7CD900CF7658 /* COPYING */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = COPYING; path = ../COPYING; sourceTree = SOURCE_ROOT; }; 404884AB0E2F7CD900CF7658 /* LICENSE */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = LICENSE; path = ../LICENSE; sourceTree = SOURCE_ROOT; };
40899F430FFA7184000B29AE /* gtest_unittest-framework */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "gtest_unittest-framework"; sourceTree = BUILT_PRODUCTS_DIR; }; 40899F430FFA7184000B29AE /* gtest_unittest-framework */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "gtest_unittest-framework"; sourceTree = BUILT_PRODUCTS_DIR; };
40899F4D0FFA7271000B29AE /* gtest-tuple.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-tuple.h"; sourceTree = "<group>"; }; 40899F4D0FFA7271000B29AE /* gtest-tuple.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-tuple.h"; sourceTree = "<group>"; };
40899FB30FFA7567000B29AE /* StaticLibraryTarget.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = StaticLibraryTarget.xcconfig; sourceTree = "<group>"; }; 40899FB30FFA7567000B29AE /* StaticLibraryTarget.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = StaticLibraryTarget.xcconfig; sourceTree = "<group>"; };
@@ -317,7 +317,7 @@
children = ( children = (
404884A90E2F7CD900CF7658 /* CHANGES */, 404884A90E2F7CD900CF7658 /* CHANGES */,
404884AA0E2F7CD900CF7658 /* CONTRIBUTORS */, 404884AA0E2F7CD900CF7658 /* CONTRIBUTORS */,
404884AB0E2F7CD900CF7658 /* COPYING */, 404884AB0E2F7CD900CF7658 /* LICENSE */,
404883F60E2F799B00CF7658 /* README */, 404883F60E2F799B00CF7658 /* README */,
404883D90E2F799B00CF7658 /* include */, 404883D90E2F799B00CF7658 /* include */,
4089A02F0FFACF84000B29AE /* samples */, 4089A02F0FFACF84000B29AE /* samples */,
@@ -580,8 +580,12 @@
/* Begin PBXProject section */ /* Begin PBXProject section */
0867D690FE84028FC02AAC07 /* Project object */ = { 0867D690FE84028FC02AAC07 /* Project object */ = {
isa = PBXProject; isa = PBXProject;
attributes = {
LastUpgradeCheck = 0460;
};
buildConfigurationList = 4FADC24608B4156D00ABE55E /* Build configuration list for PBXProject "gtest" */; buildConfigurationList = 4FADC24608B4156D00ABE55E /* Build configuration list for PBXProject "gtest" */;
compatibilityVersion = "Xcode 2.4"; compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 1; hasScannedForEncodings = 1;
knownRegions = ( knownRegions = (
English, English,
@@ -616,7 +620,7 @@
404884500E2F799B00CF7658 /* README in Resources */, 404884500E2F799B00CF7658 /* README in Resources */,
404884AC0E2F7CD900CF7658 /* CHANGES in Resources */, 404884AC0E2F7CD900CF7658 /* CHANGES in Resources */,
404884AD0E2F7CD900CF7658 /* CONTRIBUTORS in Resources */, 404884AD0E2F7CD900CF7658 /* CONTRIBUTORS in Resources */,
404884AE0E2F7CD900CF7658 /* COPYING in Resources */, 404884AE0E2F7CD900CF7658 /* LICENSE in Resources */,
40C84978101A36540083642A /* libgtest_main.a in Resources */, 40C84978101A36540083642A /* libgtest_main.a in Resources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
@@ -789,20 +793,25 @@
3B238F600E828B5400846E11 /* Debug */ = { 3B238F600E828B5400846E11 /* Debug */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
COMBINE_HIDPI_IMAGES = YES;
COPY_PHASE_STRIP = NO; COPY_PHASE_STRIP = NO;
GCC_DYNAMIC_NO_PIC = NO; GCC_DYNAMIC_NO_PIC = NO;
GCC_OPTIMIZATION_LEVEL = 0; GCC_OPTIMIZATION_LEVEL = 0;
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
PRODUCT_NAME = Check; PRODUCT_NAME = Check;
SDKROOT = macosx;
}; };
name = Debug; name = Debug;
}; };
3B238F610E828B5400846E11 /* Release */ = { 3B238F610E828B5400846E11 /* Release */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
COMBINE_HIDPI_IMAGES = YES;
COPY_PHASE_STRIP = YES; COPY_PHASE_STRIP = YES;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
PRODUCT_NAME = Check; PRODUCT_NAME = Check;
SDKROOT = macosx;
ZERO_LINK = NO; ZERO_LINK = NO;
}; };
name = Release; name = Release;
@@ -810,37 +819,49 @@
40899F450FFA7185000B29AE /* Debug */ = { 40899F450FFA7185000B29AE /* Debug */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
HEADER_SEARCH_PATHS = ../; HEADER_SEARCH_PATHS = ../;
PRODUCT_NAME = "gtest_unittest-framework"; PRODUCT_NAME = "gtest_unittest-framework";
SDKROOT = macosx;
}; };
name = Debug; name = Debug;
}; };
40899F460FFA7185000B29AE /* Release */ = { 40899F460FFA7185000B29AE /* Release */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
HEADER_SEARCH_PATHS = ../; HEADER_SEARCH_PATHS = ../;
PRODUCT_NAME = "gtest_unittest-framework"; PRODUCT_NAME = "gtest_unittest-framework";
SDKROOT = macosx;
}; };
name = Release; name = Release;
}; };
4089A0150FFACEFD000B29AE /* Debug */ = { 4089A0150FFACEFD000B29AE /* Debug */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
PRODUCT_NAME = "sample1_unittest-framework"; PRODUCT_NAME = "sample1_unittest-framework";
SDKROOT = macosx;
}; };
name = Debug; name = Debug;
}; };
4089A0160FFACEFD000B29AE /* Release */ = { 4089A0160FFACEFD000B29AE /* Release */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
PRODUCT_NAME = "sample1_unittest-framework"; PRODUCT_NAME = "sample1_unittest-framework";
SDKROOT = macosx;
}; };
name = Release; name = Release;
}; };
40C44ADF0E3798F4008FCC51 /* Debug */ = { 40C44ADF0E3798F4008FCC51 /* Debug */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
COMBINE_HIDPI_IMAGES = YES;
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
MACOSX_DEPLOYMENT_TARGET = 10.7;
PRODUCT_NAME = gtest; PRODUCT_NAME = gtest;
SDKROOT = macosx;
TARGET_NAME = gtest; TARGET_NAME = gtest;
}; };
name = Debug; name = Debug;
@@ -848,7 +869,11 @@
40C44AE00E3798F4008FCC51 /* Release */ = { 40C44AE00E3798F4008FCC51 /* Release */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
COMBINE_HIDPI_IMAGES = YES;
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
MACOSX_DEPLOYMENT_TARGET = 10.7;
PRODUCT_NAME = gtest; PRODUCT_NAME = gtest;
SDKROOT = macosx;
TARGET_NAME = gtest; TARGET_NAME = gtest;
}; };
name = Release; name = Release;
@@ -857,13 +882,16 @@
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
baseConfigurationReference = 40899FB30FFA7567000B29AE /* StaticLibraryTarget.xcconfig */; baseConfigurationReference = 40899FB30FFA7567000B29AE /* StaticLibraryTarget.xcconfig */;
buildSettings = { buildSettings = {
COMBINE_HIDPI_IMAGES = YES;
GCC_INLINES_ARE_PRIVATE_EXTERN = YES; GCC_INLINES_ARE_PRIVATE_EXTERN = YES;
GCC_SYMBOLS_PRIVATE_EXTERN = YES; GCC_SYMBOLS_PRIVATE_EXTERN = YES;
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
HEADER_SEARCH_PATHS = ( HEADER_SEARCH_PATHS = (
../, ../,
../include/, ../include/,
); );
PRODUCT_NAME = gtest; PRODUCT_NAME = gtest;
SDKROOT = macosx;
}; };
name = Debug; name = Debug;
}; };
@@ -871,13 +899,16 @@
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
baseConfigurationReference = 40899FB30FFA7567000B29AE /* StaticLibraryTarget.xcconfig */; baseConfigurationReference = 40899FB30FFA7567000B29AE /* StaticLibraryTarget.xcconfig */;
buildSettings = { buildSettings = {
COMBINE_HIDPI_IMAGES = YES;
GCC_INLINES_ARE_PRIVATE_EXTERN = YES; GCC_INLINES_ARE_PRIVATE_EXTERN = YES;
GCC_SYMBOLS_PRIVATE_EXTERN = YES; GCC_SYMBOLS_PRIVATE_EXTERN = YES;
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
HEADER_SEARCH_PATHS = ( HEADER_SEARCH_PATHS = (
../, ../,
../include/, ../include/,
); );
PRODUCT_NAME = gtest; PRODUCT_NAME = gtest;
SDKROOT = macosx;
}; };
name = Release; name = Release;
}; };
@@ -885,11 +916,14 @@
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
baseConfigurationReference = 40899FB30FFA7567000B29AE /* StaticLibraryTarget.xcconfig */; baseConfigurationReference = 40899FB30FFA7567000B29AE /* StaticLibraryTarget.xcconfig */;
buildSettings = { buildSettings = {
COMBINE_HIDPI_IMAGES = YES;
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
HEADER_SEARCH_PATHS = ( HEADER_SEARCH_PATHS = (
../, ../,
../include/, ../include/,
); );
PRODUCT_NAME = gtest_main; PRODUCT_NAME = gtest_main;
SDKROOT = macosx;
}; };
name = Debug; name = Debug;
}; };
@@ -897,41 +931,52 @@
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
baseConfigurationReference = 40899FB30FFA7567000B29AE /* StaticLibraryTarget.xcconfig */; baseConfigurationReference = 40899FB30FFA7567000B29AE /* StaticLibraryTarget.xcconfig */;
buildSettings = { buildSettings = {
COMBINE_HIDPI_IMAGES = YES;
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
HEADER_SEARCH_PATHS = ( HEADER_SEARCH_PATHS = (
../, ../,
../include/, ../include/,
); );
PRODUCT_NAME = gtest_main; PRODUCT_NAME = gtest_main;
SDKROOT = macosx;
}; };
name = Release; name = Release;
}; };
40C84985101A36850083642A /* Debug */ = { 40C84985101A36850083642A /* Debug */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
HEADER_SEARCH_PATHS = ../; HEADER_SEARCH_PATHS = ../;
PRODUCT_NAME = gtest_unittest; PRODUCT_NAME = gtest_unittest;
SDKROOT = macosx;
}; };
name = Debug; name = Debug;
}; };
40C84986101A36850083642A /* Release */ = { 40C84986101A36850083642A /* Release */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
HEADER_SEARCH_PATHS = ../; HEADER_SEARCH_PATHS = ../;
PRODUCT_NAME = gtest_unittest; PRODUCT_NAME = gtest_unittest;
SDKROOT = macosx;
}; };
name = Release; name = Release;
}; };
40C84995101A36A60083642A /* Debug */ = { 40C84995101A36A60083642A /* Debug */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
PRODUCT_NAME = "sample1_unittest-static"; PRODUCT_NAME = "sample1_unittest-static";
SDKROOT = macosx;
}; };
name = Debug; name = Debug;
}; };
40C84996101A36A60083642A /* Release */ = { 40C84996101A36A60083642A /* Release */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
PRODUCT_NAME = "sample1_unittest-static"; PRODUCT_NAME = "sample1_unittest-static";
SDKROOT = macosx;
}; };
name = Release; name = Release;
}; };
@@ -939,8 +984,10 @@
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
baseConfigurationReference = 40D4CDF20E30E07400294801 /* FrameworkTarget.xcconfig */; baseConfigurationReference = 40D4CDF20E30E07400294801 /* FrameworkTarget.xcconfig */;
buildSettings = { buildSettings = {
COMBINE_HIDPI_IMAGES = YES;
DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1; DYLIB_CURRENT_VERSION = 1;
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
HEADER_SEARCH_PATHS = ( HEADER_SEARCH_PATHS = (
../, ../,
../include/, ../include/,
@@ -949,6 +996,7 @@
INFOPLIST_PREFIX_HEADER = "$(PROJECT_TEMP_DIR)/Version.h"; INFOPLIST_PREFIX_HEADER = "$(PROJECT_TEMP_DIR)/Version.h";
INFOPLIST_PREPROCESS = YES; INFOPLIST_PREPROCESS = YES;
PRODUCT_NAME = gtest; PRODUCT_NAME = gtest;
SDKROOT = macosx;
VERSIONING_SYSTEM = "apple-generic"; VERSIONING_SYSTEM = "apple-generic";
}; };
name = Debug; name = Debug;
@@ -957,8 +1005,10 @@
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
baseConfigurationReference = 40D4CDF20E30E07400294801 /* FrameworkTarget.xcconfig */; baseConfigurationReference = 40D4CDF20E30E07400294801 /* FrameworkTarget.xcconfig */;
buildSettings = { buildSettings = {
COMBINE_HIDPI_IMAGES = YES;
DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1; DYLIB_CURRENT_VERSION = 1;
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
HEADER_SEARCH_PATHS = ( HEADER_SEARCH_PATHS = (
../, ../,
../include/, ../include/,
@@ -967,6 +1017,7 @@
INFOPLIST_PREFIX_HEADER = "$(PROJECT_TEMP_DIR)/Version.h"; INFOPLIST_PREFIX_HEADER = "$(PROJECT_TEMP_DIR)/Version.h";
INFOPLIST_PREPROCESS = YES; INFOPLIST_PREPROCESS = YES;
PRODUCT_NAME = gtest; PRODUCT_NAME = gtest;
SDKROOT = macosx;
VERSIONING_SYSTEM = "apple-generic"; VERSIONING_SYSTEM = "apple-generic";
}; };
name = Release; name = Release;