summaryrefslogtreecommitdiffstats
path: root/testing
diff options
context:
space:
mode:
authorKristian Monsen <kristianm@google.com>2011-06-09 11:47:42 +0100
committerKristian Monsen <kristianm@google.com>2011-06-29 14:33:03 +0100
commitdc0f95d653279beabeb9817299e2902918ba123e (patch)
tree32eb121cd532053a5b9cb0c390331349af8d6baa /testing
parentba160cd4054d13d0cb0b1b46e61c3bed67095811 (diff)
downloadexternal_chromium-dc0f95d653279beabeb9817299e2902918ba123e.zip
external_chromium-dc0f95d653279beabeb9817299e2902918ba123e.tar.gz
external_chromium-dc0f95d653279beabeb9817299e2902918ba123e.tar.bz2
Merge Chromium at r11.0.696.0: Initial merge by git
Change-Id: I273dde2843af0839dfc08b419bb443fbd449532d
Diffstat (limited to 'testing')
-rw-r--r--testing/gmock/CMakeLists.txt24
-rw-r--r--testing/gmock/Makefile.am112
-rw-r--r--testing/gmock/README14
-rw-r--r--testing/gmock/include/gmock/gmock-actions.h135
-rw-r--r--testing/gmock/include/gmock/gmock-cardinalities.h4
-rw-r--r--testing/gmock/include/gmock/gmock-generated-actions.h6
-rw-r--r--testing/gmock/include/gmock/gmock-generated-actions.h.pump6
-rw-r--r--testing/gmock/include/gmock/gmock-generated-function-mockers.h69
-rw-r--r--testing/gmock/include/gmock/gmock-generated-function-mockers.h.pump9
-rw-r--r--testing/gmock/include/gmock/gmock-generated-matchers.h579
-rw-r--r--testing/gmock/include/gmock/gmock-generated-matchers.h.pump108
-rw-r--r--testing/gmock/include/gmock/gmock-generated-nice-strict.h52
-rw-r--r--testing/gmock/include/gmock/gmock-generated-nice-strict.h.pump20
-rw-r--r--testing/gmock/include/gmock/gmock-matchers.h144
-rw-r--r--testing/gmock/include/gmock/gmock-more-actions.h15
-rw-r--r--testing/gmock/include/gmock/gmock-spec-builders.h870
-rw-r--r--testing/gmock/include/gmock/gmock.h18
-rw-r--r--testing/gmock/include/gmock/internal/gmock-generated-internal-utils.h2
-rw-r--r--testing/gmock/include/gmock/internal/gmock-generated-internal-utils.h.pump2
-rw-r--r--testing/gmock/include/gmock/internal/gmock-internal-utils.h17
-rw-r--r--testing/gmock/include/gmock/internal/gmock-port.h4
-rw-r--r--testing/gmock/msvc/2005/gmock.sln (renamed from testing/gmock/msvc/gmock.sln)12
-rw-r--r--testing/gmock/msvc/2005/gmock.vcproj (renamed from testing/gmock/msvc/gmock.vcproj)78
-rw-r--r--testing/gmock/msvc/2005/gmock_config.vsprops (renamed from testing/gmock/msvc/gmock_config.vsprops)2
-rw-r--r--testing/gmock/msvc/2005/gmock_main.vcproj (renamed from testing/gmock/msvc/gmock_main.vcproj)10
-rw-r--r--testing/gmock/msvc/2005/gmock_test.vcproj (renamed from testing/gmock/msvc/gmock_link_test.vcproj)18
-rw-r--r--testing/gmock/msvc/2010/gmock.sln32
-rw-r--r--testing/gmock/msvc/2010/gmock.vcxproj82
-rw-r--r--testing/gmock/msvc/2010/gmock_config.props19
-rw-r--r--testing/gmock/msvc/2010/gmock_main.vcxproj88
-rw-r--r--testing/gmock/msvc/2010/gmock_test.vcxproj101
-rwxr-xr-xtesting/gmock/msvc/gmock-spec-builders_test.vcproj205
-rw-r--r--testing/gmock/msvc/gmock_test.vcproj243
-rwxr-xr-xtesting/gmock/run_tests.py81
-rwxr-xr-xtesting/gmock/scripts/fuse_gmock_files.py22
-rwxr-xr-xtesting/gmock/scripts/generator/cpp/ast.py8
-rwxr-xr-xtesting/gmock/scripts/generator/cpp/gmock_class.py32
-rwxr-xr-xtesting/gmock/scripts/generator/cpp/gmock_class_test.py87
-rwxr-xr-xtesting/gmock/scripts/gmock-config.in2
-rwxr-xr-xtesting/gmock/scripts/gmock_doctor.py466
-rw-r--r--testing/gmock/src/gmock-all.cc2
-rw-r--r--testing/gmock/src/gmock-cardinalities.cc6
-rw-r--r--testing/gmock/src/gmock-internal-utils.cc18
-rw-r--r--testing/gmock/src/gmock-matchers.cc115
-rw-r--r--testing/gmock/src/gmock-spec-builders.cc344
-rw-r--r--testing/gmock/src/gmock.cc4
-rw-r--r--testing/gmock/src/gmock_main.cc4
-rw-r--r--testing/gmock/test/gmock-actions_test.cc195
-rw-r--r--testing/gmock/test/gmock-cardinalities_test.cc6
-rw-r--r--testing/gmock/test/gmock-generated-actions_test.cc98
-rw-r--r--testing/gmock/test/gmock-generated-function-mockers_test.cc6
-rw-r--r--testing/gmock/test/gmock-generated-internal-utils_test.cc6
-rw-r--r--testing/gmock/test/gmock-generated-matchers_test.cc107
-rw-r--r--testing/gmock/test/gmock-internal-utils_test.cc18
-rw-r--r--testing/gmock/test/gmock-matchers_test.cc437
-rw-r--r--testing/gmock/test/gmock-more-actions_test.cc44
-rw-r--r--testing/gmock/test/gmock-nice-strict_test.cc16
-rw-r--r--testing/gmock/test/gmock-port_test.cc4
-rw-r--r--testing/gmock/test/gmock-spec-builders_test.cc131
-rw-r--r--testing/gmock/test/gmock_leak_test_.cc2
-rw-r--r--testing/gmock/test/gmock_link_test.h18
-rw-r--r--testing/gmock/test/gmock_output_test_.cc4
-rw-r--r--testing/gmock/test/gmock_test.cc6
-rw-r--r--testing/gtest/CMakeLists.txt7
-rw-r--r--testing/gtest/include/gtest/gtest-param-test.h40
-rw-r--r--testing/gtest/include/gtest/gtest-param-test.h.pump45
-rw-r--r--testing/gtest/include/gtest/gtest-printers.h14
-rw-r--r--testing/gtest/include/gtest/gtest-typed-test.h6
-rw-r--r--testing/gtest/include/gtest/gtest.h157
-rw-r--r--testing/gtest/include/gtest/internal/gtest-death-test-internal.h35
-rw-r--r--testing/gtest/include/gtest/internal/gtest-internal.h26
-rw-r--r--testing/gtest/include/gtest/internal/gtest-param-util.h5
-rw-r--r--testing/gtest/include/gtest/internal/gtest-port.h43
-rw-r--r--testing/gtest/samples/sample7_unittest.cc20
-rwxr-xr-xtesting/gtest/scripts/pump.py48
-rw-r--r--testing/gtest/scripts/test/Makefile4
-rw-r--r--testing/gtest/src/gtest-death-test.cc60
-rw-r--r--testing/gtest/src/gtest-filepath.cc4
-rw-r--r--testing/gtest/src/gtest-internal-inl.h8
-rw-r--r--testing/gtest/src/gtest-port.cc1
-rw-r--r--testing/gtest/src/gtest-printers.cc45
-rw-r--r--testing/gtest/src/gtest.cc110
-rw-r--r--testing/gtest/test/gtest-death-test_ex_test.cc93
-rw-r--r--testing/gtest/test/gtest-death-test_test.cc69
-rw-r--r--testing/gtest/test/gtest-linked_ptr_test.cc3
-rw-r--r--testing/gtest/test/gtest-param-test_test.cc47
-rw-r--r--testing/gtest/test/gtest-port_test.cc15
-rw-r--r--testing/gtest/test/gtest-printers_test.cc24
-rw-r--r--testing/gtest/test/gtest-unittest-api_test.cc68
-rwxr-xr-xtesting/gtest/test/gtest_catch_exceptions_test.py17
-rwxr-xr-xtesting/gtest/test/gtest_env_var_test.py4
-rwxr-xr-xtesting/gtest/test/gtest_help_test.py2
-rw-r--r--testing/gtest/test/gtest_nc.cc234
-rwxr-xr-xtesting/gtest/test/gtest_nc_test.py114
-rw-r--r--testing/gtest/test/gtest_unittest.cc30
-rwxr-xr-xtesting/gtest/test/gtest_xml_output_unittest.py20
-rw-r--r--testing/gtest/test/gtest_xml_output_unittest_.cc37
-rwxr-xr-xtesting/gtest/test/gtest_xml_test_utils.py11
-rw-r--r--testing/gtest/xcode/gtest.xcodeproj/project.pbxproj4
99 files changed, 3686 insertions, 3173 deletions
diff --git a/testing/gmock/CMakeLists.txt b/testing/gmock/CMakeLists.txt
index 186a710..061c2fc 100644
--- a/testing/gmock/CMakeLists.txt
+++ b/testing/gmock/CMakeLists.txt
@@ -1,8 +1,5 @@
########################################################################
-# Experimental CMake build script for Google Mock.
-#
-# Consider this a prototype. It will change drastically. For now,
-# this is only for people on the cutting edge.
+# CMake build script for Google Mock.
#
# To run the tests for Google Mock itself on Linux, use 'make test' or
# ctest. You can select which tests to run using 'ctest -R regex'.
@@ -12,7 +9,7 @@
# make it prominent in the GUI.
option(BUILD_SHARED_LIBS "Build shared libraries (DLLs)." OFF)
-# Forses BUILD_SHARED_LIBS to OFF as Google Mock currently does not support
+# Forces BUILD_SHARED_LIBS to OFF as Google Mock currently does not support
# working in a DLL.
# TODO(vladl@google.com): Implement building gMock as a DLL.
set(BUILD_SHARED_LIBS OFF)
@@ -26,6 +23,7 @@ else()
set(gtest_dir ../gtest)
endif()
+# Defines pre_project_set_up_hermetic_build() and set_up_hermetic_build().
include("${gtest_dir}/cmake/hermetic_build.cmake" OPTIONAL)
if (COMMAND pre_project_set_up_hermetic_build)
@@ -51,19 +49,17 @@ if (COMMAND set_up_hermetic_build)
set_up_hermetic_build()
endif()
-# Defines functions and variables used by Google Mock.
-include("${gtest_dir}/cmake/internal_utils.cmake")
-
-# Google Test also calls this function from add_subdirectory,
-# although its changes will not affect things at the current scope.
-fix_default_settings() # Defined in internal_utils.cmake.
-
# Instructs CMake to process Google Test's CMakeLists.txt and add its
# targets to the current scope. We are placing Google Test's binary
-# directory in a subdirectory of our own as VC compilation may break if they
-# are the same (the default).
+# directory in a subdirectory of our own as VC compilation may break
+# if they are the same (the default).
add_subdirectory("${gtest_dir}" "${gmock_BINARY_DIR}/gtest")
+# Although Google Test's CMakeLists.txt calls this function, the
+# changes there don't affect the current scope. Therefore we have to
+# call it again here.
+config_compiler_and_linker() # from ${gtest_dir}/cmake/internal_utils.cmake
+
# Adds Google Mock's and Google Test's header directories to the search path.
include_directories("${gmock_SOURCE_DIR}/include"
"${gmock_SOURCE_DIR}"
diff --git a/testing/gmock/Makefile.am b/testing/gmock/Makefile.am
index e2a4673..e02c07e 100644
--- a/testing/gmock/Makefile.am
+++ b/testing/gmock/Makefile.am
@@ -29,16 +29,17 @@ lib_LTLIBRARIES = lib/libgmock.la lib/libgmock_main.la
lib_libgmock_la_SOURCES = src/gmock-all.cc
-pkginclude_HEADERS = include/gmock/gmock.h \
- include/gmock/gmock-actions.h \
- include/gmock/gmock-cardinalities.h \
- include/gmock/gmock-generated-actions.h \
- include/gmock/gmock-generated-function-mockers.h \
- include/gmock/gmock-generated-matchers.h \
- include/gmock/gmock-generated-nice-strict.h \
- include/gmock/gmock-matchers.h \
- include/gmock/gmock-more-actions.h \
- include/gmock/gmock-spec-builders.h
+pkginclude_HEADERS = \
+ include/gmock/gmock-actions.h \
+ include/gmock/gmock-cardinalities.h \
+ include/gmock/gmock-generated-actions.h \
+ include/gmock/gmock-generated-function-mockers.h \
+ include/gmock/gmock-generated-matchers.h \
+ include/gmock/gmock-generated-nice-strict.h \
+ include/gmock/gmock-matchers.h \
+ include/gmock/gmock-more-actions.h \
+ include/gmock/gmock-spec-builders.h \
+ include/gmock/gmock.h
pkginclude_internaldir = $(pkgincludedir)/internal
pkginclude_internal_HEADERS = \
@@ -70,34 +71,35 @@ test_gmock_spec_builders_test_LDADD = $(GTEST_LIBS) lib/libgmock.la
# verifies that libgmock_main works.
TESTS += test/gmock_link_test
check_PROGRAMS += test/gmock_link_test
-test_gmock_link_test_SOURCES = test/gmock_link_test.cc \
- test/gmock_link2_test.cc \
- test/gmock_link_test.h
+test_gmock_link_test_SOURCES = \
+ test/gmock_link2_test.cc \
+ test/gmock_link_test.cc \
+ test/gmock_link_test.h
test_gmock_link_test_LDADD = $(GTEST_LIBS) lib/libgmock_main.la
# Tests that fused gmock files compile and work.
TESTS += test/gmock_fused_test
check_PROGRAMS += test/gmock_fused_test
-test_gmock_fused_test_SOURCES = fused-src/gmock-gtest-all.cc \
- fused-src/gmock_main.cc \
- fused-src/gmock/gmock.h \
- fused-src/gtest/gtest.h \
- test/gmock_test.cc
+test_gmock_fused_test_SOURCES = \
+ fused-src/gmock-gtest-all.cc \
+ fused-src/gmock/gmock.h \
+ fused-src/gmock_main.cc \
+ fused-src/gtest/gtest.h \
+ test/gmock_test.cc
test_gmock_fused_test_CPPFLAGS = -I"$(srcdir)/fused-src"
# Google Mock source files that we don't compile directly.
GMOCK_SOURCE_INGLUDES = \
- src/gmock.cc \
src/gmock-cardinalities.cc \
src/gmock-internal-utils.cc \
src/gmock-matchers.cc \
- src/gmock-spec-builders.cc
+ src/gmock-spec-builders.cc \
+ src/gmock.cc
EXTRA_DIST += $(GMOCK_SOURCE_INGLUDES)
# C++ tests that we don't compile using autotools.
EXTRA_DIST += \
- test/gmock_all_test.cc \
test/gmock-actions_test.cc \
test/gmock-cardinalities_test.cc \
test/gmock-generated-actions_test.cc \
@@ -108,56 +110,64 @@ EXTRA_DIST += \
test/gmock-matchers_test.cc \
test/gmock-more-actions_test.cc \
test/gmock-nice-strict_test.cc \
- test/gmock-port_test.cc
+ test/gmock-port_test.cc \
+ test/gmock_all_test.cc
# Python tests, which we don't run using autotools.
EXTRA_DIST += \
- test/gmock_test_utils.py \
- test/gmock_leak_test_.cc \
test/gmock_leak_test.py \
- test/gmock_output_test_.cc \
+ test/gmock_leak_test_.cc \
test/gmock_output_test.py \
- test/gmock_output_test_golden.txt
+ test/gmock_output_test_.cc \
+ test/gmock_output_test_golden.txt \
+ test/gmock_test_utils.py
# Nonstandard package files for distribution.
EXTRA_DIST += \
- CHANGES \
- CONTRIBUTORS \
- make/Makefile
+ CHANGES \
+ CONTRIBUTORS \
+ make/Makefile
# Pump scripts for generating Google Mock headers.
# TODO(chandlerc@google.com): automate the generation of *.h from *.h.pump.
-EXTRA_DIST += include/gmock/gmock-generated-actions.h.pump \
- include/gmock/gmock-generated-function-mockers.h.pump \
- include/gmock/gmock-generated-matchers.h.pump \
- include/gmock/gmock-generated-nice-strict.h.pump \
- include/gmock/internal/gmock-generated-internal-utils.h.pump
+EXTRA_DIST += \
+ include/gmock/gmock-generated-actions.h.pump \
+ include/gmock/gmock-generated-function-mockers.h.pump \
+ include/gmock/gmock-generated-matchers.h.pump \
+ include/gmock/gmock-generated-nice-strict.h.pump \
+ include/gmock/internal/gmock-generated-internal-utils.h.pump
# Script for fusing Google Mock and Google Test source files.
EXTRA_DIST += scripts/fuse_gmock_files.py
# The Google Mock Generator tool from the cppclean project.
EXTRA_DIST += \
- scripts/generator/COPYING \
- scripts/generator/README \
- scripts/generator/README.cppclean \
- scripts/generator/cpp/__init__.py \
- scripts/generator/cpp/ast.py \
- scripts/generator/cpp/gmock_class.py \
- scripts/generator/cpp/keywords.py \
- scripts/generator/cpp/tokenize.py \
- scripts/generator/cpp/utils.py \
- scripts/generator/gmock_gen.py
+ scripts/generator/COPYING \
+ scripts/generator/README \
+ scripts/generator/README.cppclean \
+ scripts/generator/cpp/__init__.py \
+ scripts/generator/cpp/ast.py \
+ scripts/generator/cpp/gmock_class.py \
+ scripts/generator/cpp/keywords.py \
+ scripts/generator/cpp/tokenize.py \
+ scripts/generator/cpp/utils.py \
+ scripts/generator/gmock_gen.py
# Microsoft Visual Studio 2005 projects.
EXTRA_DIST += \
- msvc/gmock.sln \
- msvc/gmock.vcproj \
- msvc/gmock_config.vsprops \
- msvc/gmock_link_test.vcproj \
- msvc/gmock_main.vcproj \
- msvc/gmock-spec-builders_test.vcproj \
- msvc/gmock_test.vcproj
+ msvc/2005/gmock.sln \
+ msvc/2005/gmock.vcproj \
+ msvc/2005/gmock_config.vsprops \
+ msvc/2005/gmock_main.vcproj \
+ msvc/2005/gmock_test.vcproj
+
+# Microsoft Visual Studio 2010 projects.
+EXTRA_DIST += \
+ msvc/2010/gmock.sln \
+ msvc/2010/gmock.vcxproj \
+ msvc/2010/gmock_config.props \
+ msvc/2010/gmock_main.vcxproj \
+ msvc/2010/gmock_test.vcxproj
# gmock_test.cc does not really depend on files generated by the
# fused-gmock-internal rule. However, gmock_test.o does, and it is
diff --git a/testing/gmock/README b/testing/gmock/README
index 8e4150a..aa3283d 100644
--- a/testing/gmock/README
+++ b/testing/gmock/README
@@ -208,16 +208,18 @@ it.
### Windows ###
-The msvc/ directory contains VC++ 2005 projects for building Google
-Mock and selected tests.
+The msvc/2005 directory contains VC++ 2005 projects and the msvc/2010
+directory contains VC++ 2010 projects for building Google Mock and
+selected tests.
-Open msvc/gmock.sln and build the library and tests. If you want to
-create your own project to use with Google Mock, you'll have to
-configure it to use the gmock_config propety sheet. For that:
+Change to the appropriate directory and run "msbuild gmock.sln" to
+build the library and tests (or open the gmock.sln in the MSVC IDE).
+If you want to create your own project to use with Google Mock, you'll
+have to configure it to use the gmock_config propety sheet. For that:
* Open the Property Manager window (View | Other Windows | Property Manager)
* Right-click on your project and select "Add Existing Property Sheet..."
- * Navigate to gmock_config.vsprops and select it.
+ * Navigate to gmock_config.vsprops or gmock_config.props and select it.
* In Project Properties | Configuration Properties | General | Additional
Include Directories, type <path to Google Mock>/include.
diff --git a/testing/gmock/include/gmock/gmock-actions.h b/testing/gmock/include/gmock/gmock-actions.h
index 9fe1964..af3483f 100644
--- a/testing/gmock/include/gmock/gmock-actions.h
+++ b/testing/gmock/include/gmock/gmock-actions.h
@@ -43,8 +43,8 @@
#include <errno.h>
#endif
-#include <gmock/internal/gmock-internal-utils.h>
-#include <gmock/internal/gmock-port.h>
+#include "gmock/internal/gmock-internal-utils.h"
+#include "gmock/internal/gmock-port.h"
namespace testing {
@@ -59,9 +59,6 @@ namespace testing {
namespace internal {
-template <typename F>
-class MonomorphicDoDefaultActionImpl;
-
template <typename F1, typename F2>
class ActionAdaptor;
@@ -255,8 +252,7 @@ class ActionInterface {
typedef typename internal::Function<F>::Result Result;
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
- ActionInterface() : is_do_default_(false) {}
-
+ ActionInterface() {}
virtual ~ActionInterface() {}
// Performs the action. This method is not const, as in general an
@@ -265,21 +261,7 @@ class ActionInterface {
// remember the current element.
virtual Result Perform(const ArgumentTuple& args) = 0;
- // Returns true iff this is the DoDefault() action.
- bool IsDoDefault() const { return is_do_default_; }
-
private:
- template <typename Function>
- friend class internal::MonomorphicDoDefaultActionImpl;
-
- // This private constructor is reserved for implementing
- // DoDefault(), the default action for a given mock function.
- explicit ActionInterface(bool is_do_default)
- : is_do_default_(is_do_default) {}
-
- // True iff this action is DoDefault().
- const bool is_do_default_;
-
GTEST_DISALLOW_COPY_AND_ASSIGN_(ActionInterface);
};
@@ -302,7 +284,8 @@ class Action {
// STL containers.
Action() : impl_(NULL) {}
- // Constructs an Action from its implementation.
+ // Constructs an Action from its implementation. A NULL impl is
+ // used to represent the "do-default" action.
explicit Action(ActionInterface<F>* impl) : impl_(impl) {}
// Copy constructor.
@@ -316,7 +299,7 @@ class Action {
explicit Action(const Action<Func>& action);
// Returns true iff this is the DoDefault() action.
- bool IsDoDefault() const { return impl_->IsDoDefault(); }
+ bool IsDoDefault() const { return impl_.get() == NULL; }
// Performs the action. Note that this method is const even though
// the corresponding method in ActionInterface is not. The reason
@@ -325,6 +308,13 @@ class Action {
// cannot change state. (Think of the difference between a const
// pointer and a pointer to const.)
Result Perform(const ArgumentTuple& args) const {
+ internal::Assert(
+ !IsDoDefault(), __FILE__, __LINE__,
+ "You are using DoDefault() inside a composite action like "
+ "DoAll() or WithArgs(). This is not supported for technical "
+ "reasons. Please instead spell out the default action, or "
+ "assign the default action to an Action variable and use "
+ "the variable in various places.");
return impl_->Perform(args);
}
@@ -494,11 +484,11 @@ class ReturnAction {
// single-argument constructor (e.g. Result is std::vector<int>) and R
// has a type conversion operator template. In that case, value_(value)
// won't compile as the compiler doesn't known which constructor of
- // Result to call. implicit_cast forces the compiler to convert R to
+ // Result to call. ImplicitCast_ forces the compiler to convert R to
// Result without considering explicit constructors, thus resolving the
// ambiguity. value_ is then initialized using its copy constructor.
explicit Impl(R value)
- : value_(::testing::internal::implicit_cast<Result>(value)) {}
+ : value_(::testing::internal::ImplicitCast_<Result>(value)) {}
virtual Result Perform(const ArgumentTuple&) { return value_; }
@@ -584,31 +574,53 @@ class ReturnRefAction {
GTEST_DISALLOW_ASSIGN_(ReturnRefAction);
};
-// Implements the DoDefault() action for a particular function type F.
-template <typename F>
-class MonomorphicDoDefaultActionImpl : public ActionInterface<F> {
+// Implements the polymorphic ReturnRefOfCopy(x) action, which can be
+// used in any function that returns a reference to the type of x,
+// regardless of the argument types.
+template <typename T>
+class ReturnRefOfCopyAction {
public:
- typedef typename Function<F>::Result Result;
- typedef typename Function<F>::ArgumentTuple ArgumentTuple;
+ // Constructs a ReturnRefOfCopyAction object from the reference to
+ // be returned.
+ explicit ReturnRefOfCopyAction(const T& value) : value_(value) {} // NOLINT
- MonomorphicDoDefaultActionImpl() : ActionInterface<F>(true) {}
-
- // For technical reasons, DoDefault() cannot be used inside a
- // composite action (e.g. DoAll(...)). It can only be used at the
- // top level in an EXPECT_CALL(). If this function is called, the
- // user must be using DoDefault() inside a composite action, and we
- // have to generate a run-time error.
- virtual Result Perform(const ArgumentTuple&) {
- Assert(false, __FILE__, __LINE__,
- "You are using DoDefault() inside a composite action like "
- "DoAll() or WithArgs(). This is not supported for technical "
- "reasons. Please instead spell out the default action, or "
- "assign the default action to an Action variable and use "
- "the variable in various places.");
- return internal::Invalid<Result>();
- // The above statement will never be reached, but is required in
- // order for this function to compile.
+ // This template type conversion operator allows ReturnRefOfCopy(x) to be
+ // used in ANY function that returns a reference to x's type.
+ template <typename F>
+ operator Action<F>() const {
+ typedef typename Function<F>::Result Result;
+ // Asserts that the function return type is a reference. This
+ // catches the user error of using ReturnRefOfCopy(x) when Return(x)
+ // should be used, and generates some helpful error message.
+ GTEST_COMPILE_ASSERT_(
+ internal::is_reference<Result>::value,
+ use_Return_instead_of_ReturnRefOfCopy_to_return_a_value);
+ return Action<F>(new Impl<F>(value_));
}
+
+ private:
+ // Implements the ReturnRefOfCopy(x) action for a particular function type F.
+ template <typename F>
+ class Impl : public ActionInterface<F> {
+ public:
+ typedef typename Function<F>::Result Result;
+ typedef typename Function<F>::ArgumentTuple ArgumentTuple;
+
+ explicit Impl(const T& value) : value_(value) {} // NOLINT
+
+ virtual Result Perform(const ArgumentTuple&) {
+ return value_;
+ }
+
+ private:
+ T value_;
+
+ GTEST_DISALLOW_ASSIGN_(Impl);
+ };
+
+ const T value_;
+
+ GTEST_DISALLOW_ASSIGN_(ReturnRefOfCopyAction);
};
// Implements the polymorphic DoDefault() action.
@@ -617,9 +629,7 @@ class DoDefaultAction {
// This template type conversion operator allows DoDefault() to be
// used in any function.
template <typename F>
- operator Action<F>() const {
- return Action<F>(new MonomorphicDoDefaultActionImpl<F>);
- }
+ operator Action<F>() const { return Action<F>(NULL); }
};
// Implements the Assign action to set a given pointer referent to a
@@ -948,6 +958,14 @@ inline internal::ReturnRefAction<R> ReturnRef(R& x) { // NOLINT
return internal::ReturnRefAction<R>(x);
}
+// Creates an action that returns the reference to a copy of the
+// argument. The copy is created when the action is constructed and
+// lives as long as the action.
+template <typename R>
+inline internal::ReturnRefOfCopyAction<R> ReturnRefOfCopy(const R& x) {
+ return internal::ReturnRefOfCopyAction<R>(x);
+}
+
// Creates an action that does the default action for the give mock function.
inline internal::DoDefaultAction DoDefault() {
return internal::DoDefaultAction();
@@ -959,6 +977,23 @@ template <size_t N, typename T>
PolymorphicAction<
internal::SetArgumentPointeeAction<
N, T, internal::IsAProtocolMessage<T>::value> >
+SetArgPointee(const T& x) {
+ return MakePolymorphicAction(internal::SetArgumentPointeeAction<
+ N, T, internal::IsAProtocolMessage<T>::value>(x));
+}
+// This overload allows SetArgPointee() to accept a string literal.
+template <size_t N>
+PolymorphicAction<
+ internal::SetArgumentPointeeAction<N, const char*, false> >
+SetArgPointee(const char* p) {
+ return MakePolymorphicAction(internal::SetArgumentPointeeAction<
+ N, const char*, false>(p));
+}
+// The following version is DEPRECATED.
+template <size_t N, typename T>
+PolymorphicAction<
+ internal::SetArgumentPointeeAction<
+ N, T, internal::IsAProtocolMessage<T>::value> >
SetArgumentPointee(const T& x) {
return MakePolymorphicAction(internal::SetArgumentPointeeAction<
N, T, internal::IsAProtocolMessage<T>::value>(x));
diff --git a/testing/gmock/include/gmock/gmock-cardinalities.h b/testing/gmock/include/gmock/gmock-cardinalities.h
index ae4cb64..954a86e 100644
--- a/testing/gmock/include/gmock/gmock-cardinalities.h
+++ b/testing/gmock/include/gmock/gmock-cardinalities.h
@@ -40,8 +40,8 @@
#include <limits.h>
#include <ostream> // NOLINT
-#include <gmock/internal/gmock-port.h>
-#include <gtest/gtest.h>
+#include "gmock/internal/gmock-port.h"
+#include "gtest/gtest.h"
namespace testing {
diff --git a/testing/gmock/include/gmock/gmock-generated-actions.h b/testing/gmock/include/gmock/gmock-generated-actions.h
index 2b53c7b..6ab014d 100644
--- a/testing/gmock/include/gmock/gmock-generated-actions.h
+++ b/testing/gmock/include/gmock/gmock-generated-actions.h
@@ -38,8 +38,8 @@
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_
#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_
-#include <gmock/gmock-actions.h>
-#include <gmock/internal/gmock-port.h>
+#include "gmock/gmock-actions.h"
+#include "gmock/internal/gmock-port.h"
namespace testing {
namespace internal {
@@ -1378,7 +1378,7 @@ DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6,
// The name of the class template implementing the action template.
#define GMOCK_ACTION_CLASS_(name, value_params)\
- GMOCK_CONCAT_TOKEN_(name##Action, GMOCK_INTERNAL_COUNT_##value_params)
+ GTEST_CONCAT_TOKEN_(name##Action, GMOCK_INTERNAL_COUNT_##value_params)
#define ACTION_TEMPLATE(name, template_params, value_params)\
template <GMOCK_INTERNAL_DECL_##template_params\
diff --git a/testing/gmock/include/gmock/gmock-generated-actions.h.pump b/testing/gmock/include/gmock/gmock-generated-actions.h.pump
index 75b1e7a..4d7c5ce 100644
--- a/testing/gmock/include/gmock/gmock-generated-actions.h.pump
+++ b/testing/gmock/include/gmock/gmock-generated-actions.h.pump
@@ -42,8 +42,8 @@ $$}} This meta comment fixes auto-indentation in editors.
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_
#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_
-#include <gmock/gmock-actions.h>
-#include <gmock/internal/gmock-port.h>
+#include "gmock/gmock-actions.h"
+#include "gmock/internal/gmock-port.h"
namespace testing {
namespace internal {
@@ -605,7 +605,7 @@ $if i==1 [[P]] $elif i>=2 [[P$i]]
// The name of the class template implementing the action template.
#define GMOCK_ACTION_CLASS_(name, value_params)\
- GMOCK_CONCAT_TOKEN_(name##Action, GMOCK_INTERNAL_COUNT_##value_params)
+ GTEST_CONCAT_TOKEN_(name##Action, GMOCK_INTERNAL_COUNT_##value_params)
$range k 0..n-1
diff --git a/testing/gmock/include/gmock/gmock-generated-function-mockers.h b/testing/gmock/include/gmock/gmock-generated-function-mockers.h
index 58be7e1..509d46c 100644
--- a/testing/gmock/include/gmock/gmock-generated-function-mockers.h
+++ b/testing/gmock/include/gmock/gmock-generated-function-mockers.h
@@ -1,4 +1,6 @@
-// This file was GENERATED by a script. DO NOT EDIT BY HAND!!!
+// This file was GENERATED by command:
+// pump.py gmock-generated-function-mockers.h.pump
+// DO NOT EDIT BY HAND!!!
// Copyright 2007, Google Inc.
// All rights reserved.
@@ -38,8 +40,8 @@
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_
#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_
-#include <gmock/gmock-spec-builders.h>
-#include <gmock/internal/gmock-internal-utils.h>
+#include "gmock/gmock-spec-builders.h"
+#include "gmock/internal/gmock-internal-utils.h"
namespace testing {
namespace internal {
@@ -339,7 +341,7 @@ using internal::FunctionMocker;
// The variable for mocking the given method.
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
#define GMOCK_MOCKER_(arity, constness, Method) \
- GMOCK_CONCAT_TOKEN_(gmock##constness##arity##_##Method##_, __LINE__)
+ GTEST_CONCAT_TOKEN_(gmock##constness##arity##_##Method##_, __LINE__)
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
#define GMOCK_METHOD0_(tn, constness, ct, Method, F) \
@@ -352,7 +354,8 @@ using internal::FunctionMocker;
} \
::testing::MockSpec<F>& \
gmock_##Method() constness { \
- return GMOCK_MOCKER_(0, constness, Method).RegisterOwner(this).With(); \
+ GMOCK_MOCKER_(0, constness, Method).RegisterOwner(this); \
+ return GMOCK_MOCKER_(0, constness, Method).With(); \
} \
mutable ::testing::FunctionMocker<F> GMOCK_MOCKER_(0, constness, Method)
@@ -367,8 +370,8 @@ using internal::FunctionMocker;
} \
::testing::MockSpec<F>& \
gmock_##Method(GMOCK_MATCHER_(tn, F, 1) gmock_a1) constness { \
- return GMOCK_MOCKER_(1, constness, \
- Method).RegisterOwner(this).With(gmock_a1); \
+ GMOCK_MOCKER_(1, constness, Method).RegisterOwner(this); \
+ return GMOCK_MOCKER_(1, constness, Method).With(gmock_a1); \
} \
mutable ::testing::FunctionMocker<F> GMOCK_MOCKER_(1, constness, Method)
@@ -385,8 +388,8 @@ using internal::FunctionMocker;
::testing::MockSpec<F>& \
gmock_##Method(GMOCK_MATCHER_(tn, F, 1) gmock_a1, \
GMOCK_MATCHER_(tn, F, 2) gmock_a2) constness { \
- return GMOCK_MOCKER_(2, constness, \
- Method).RegisterOwner(this).With(gmock_a1, gmock_a2); \
+ GMOCK_MOCKER_(2, constness, Method).RegisterOwner(this); \
+ return GMOCK_MOCKER_(2, constness, Method).With(gmock_a1, gmock_a2); \
} \
mutable ::testing::FunctionMocker<F> GMOCK_MOCKER_(2, constness, Method)
@@ -406,8 +409,9 @@ using internal::FunctionMocker;
gmock_##Method(GMOCK_MATCHER_(tn, F, 1) gmock_a1, \
GMOCK_MATCHER_(tn, F, 2) gmock_a2, \
GMOCK_MATCHER_(tn, F, 3) gmock_a3) constness { \
- return GMOCK_MOCKER_(3, constness, \
- Method).RegisterOwner(this).With(gmock_a1, gmock_a2, gmock_a3); \
+ GMOCK_MOCKER_(3, constness, Method).RegisterOwner(this); \
+ return GMOCK_MOCKER_(3, constness, Method).With(gmock_a1, gmock_a2, \
+ gmock_a3); \
} \
mutable ::testing::FunctionMocker<F> GMOCK_MOCKER_(3, constness, Method)
@@ -429,9 +433,9 @@ using internal::FunctionMocker;
GMOCK_MATCHER_(tn, F, 2) gmock_a2, \
GMOCK_MATCHER_(tn, F, 3) gmock_a3, \
GMOCK_MATCHER_(tn, F, 4) gmock_a4) constness { \
- return GMOCK_MOCKER_(4, constness, \
- Method).RegisterOwner(this).With(gmock_a1, gmock_a2, gmock_a3, \
- gmock_a4); \
+ GMOCK_MOCKER_(4, constness, Method).RegisterOwner(this); \
+ return GMOCK_MOCKER_(4, constness, Method).With(gmock_a1, gmock_a2, \
+ gmock_a3, gmock_a4); \
} \
mutable ::testing::FunctionMocker<F> GMOCK_MOCKER_(4, constness, Method)
@@ -455,9 +459,9 @@ using internal::FunctionMocker;
GMOCK_MATCHER_(tn, F, 3) gmock_a3, \
GMOCK_MATCHER_(tn, F, 4) gmock_a4, \
GMOCK_MATCHER_(tn, F, 5) gmock_a5) constness { \
- return GMOCK_MOCKER_(5, constness, \
- Method).RegisterOwner(this).With(gmock_a1, gmock_a2, gmock_a3, \
- gmock_a4, gmock_a5); \
+ GMOCK_MOCKER_(5, constness, Method).RegisterOwner(this); \
+ return GMOCK_MOCKER_(5, constness, Method).With(gmock_a1, gmock_a2, \
+ gmock_a3, gmock_a4, gmock_a5); \
} \
mutable ::testing::FunctionMocker<F> GMOCK_MOCKER_(5, constness, Method)
@@ -483,9 +487,9 @@ using internal::FunctionMocker;
GMOCK_MATCHER_(tn, F, 4) gmock_a4, \
GMOCK_MATCHER_(tn, F, 5) gmock_a5, \
GMOCK_MATCHER_(tn, F, 6) gmock_a6) constness { \
- return GMOCK_MOCKER_(6, constness, \
- Method).RegisterOwner(this).With(gmock_a1, gmock_a2, gmock_a3, \
- gmock_a4, gmock_a5, gmock_a6); \
+ GMOCK_MOCKER_(6, constness, Method).RegisterOwner(this); \
+ return GMOCK_MOCKER_(6, constness, Method).With(gmock_a1, gmock_a2, \
+ gmock_a3, gmock_a4, gmock_a5, gmock_a6); \
} \
mutable ::testing::FunctionMocker<F> GMOCK_MOCKER_(6, constness, Method)
@@ -513,9 +517,9 @@ using internal::FunctionMocker;
GMOCK_MATCHER_(tn, F, 5) gmock_a5, \
GMOCK_MATCHER_(tn, F, 6) gmock_a6, \
GMOCK_MATCHER_(tn, F, 7) gmock_a7) constness { \
- return GMOCK_MOCKER_(7, constness, \
- Method).RegisterOwner(this).With(gmock_a1, gmock_a2, gmock_a3, \
- gmock_a4, gmock_a5, gmock_a6, gmock_a7); \
+ GMOCK_MOCKER_(7, constness, Method).RegisterOwner(this); \
+ return GMOCK_MOCKER_(7, constness, Method).With(gmock_a1, gmock_a2, \
+ gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7); \
} \
mutable ::testing::FunctionMocker<F> GMOCK_MOCKER_(7, constness, Method)
@@ -545,9 +549,9 @@ using internal::FunctionMocker;
GMOCK_MATCHER_(tn, F, 6) gmock_a6, \
GMOCK_MATCHER_(tn, F, 7) gmock_a7, \
GMOCK_MATCHER_(tn, F, 8) gmock_a8) constness { \
- return GMOCK_MOCKER_(8, constness, \
- Method).RegisterOwner(this).With(gmock_a1, gmock_a2, gmock_a3, \
- gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8); \
+ GMOCK_MOCKER_(8, constness, Method).RegisterOwner(this); \
+ return GMOCK_MOCKER_(8, constness, Method).With(gmock_a1, gmock_a2, \
+ gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8); \
} \
mutable ::testing::FunctionMocker<F> GMOCK_MOCKER_(8, constness, Method)
@@ -580,9 +584,10 @@ using internal::FunctionMocker;
GMOCK_MATCHER_(tn, F, 7) gmock_a7, \
GMOCK_MATCHER_(tn, F, 8) gmock_a8, \
GMOCK_MATCHER_(tn, F, 9) gmock_a9) constness { \
- return GMOCK_MOCKER_(9, constness, \
- Method).RegisterOwner(this).With(gmock_a1, gmock_a2, gmock_a3, \
- gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8, gmock_a9); \
+ GMOCK_MOCKER_(9, constness, Method).RegisterOwner(this); \
+ return GMOCK_MOCKER_(9, constness, Method).With(gmock_a1, gmock_a2, \
+ gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8, \
+ gmock_a9); \
} \
mutable ::testing::FunctionMocker<F> GMOCK_MOCKER_(9, constness, Method)
@@ -617,9 +622,9 @@ using internal::FunctionMocker;
GMOCK_MATCHER_(tn, F, 8) gmock_a8, \
GMOCK_MATCHER_(tn, F, 9) gmock_a9, \
GMOCK_MATCHER_(tn, F, 10) gmock_a10) constness { \
- return GMOCK_MOCKER_(10, constness, \
- Method).RegisterOwner(this).With(gmock_a1, gmock_a2, gmock_a3, \
- gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8, gmock_a9, \
+ GMOCK_MOCKER_(10, constness, Method).RegisterOwner(this); \
+ return GMOCK_MOCKER_(10, constness, Method).With(gmock_a1, gmock_a2, \
+ gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8, gmock_a9, \
gmock_a10); \
} \
mutable ::testing::FunctionMocker<F> GMOCK_MOCKER_(10, constness, Method)
diff --git a/testing/gmock/include/gmock/gmock-generated-function-mockers.h.pump b/testing/gmock/include/gmock/gmock-generated-function-mockers.h.pump
index 20a4454..4f82d62 100644
--- a/testing/gmock/include/gmock/gmock-generated-function-mockers.h.pump
+++ b/testing/gmock/include/gmock/gmock-generated-function-mockers.h.pump
@@ -41,8 +41,8 @@ $var n = 10 $$ The maximum arity we support.
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_
#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_
-#include <gmock/gmock-spec-builders.h>
-#include <gmock/internal/gmock-internal-utils.h>
+#include "gmock/gmock-spec-builders.h"
+#include "gmock/internal/gmock-internal-utils.h"
namespace testing {
namespace internal {
@@ -119,7 +119,7 @@ using internal::FunctionMocker;
// The variable for mocking the given method.
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
#define GMOCK_MOCKER_(arity, constness, Method) \
- GMOCK_CONCAT_TOKEN_(gmock##constness##arity##_##Method##_, __LINE__)
+ GTEST_CONCAT_TOKEN_(gmock##constness##arity##_##Method##_, __LINE__)
$for i [[
@@ -140,7 +140,8 @@ $var matcher_as = [[$for j, \
} \
::testing::MockSpec<F>& \
gmock_##Method($matcher_as) constness { \
- return GMOCK_MOCKER_($i, constness, Method).RegisterOwner(this).With($as); \
+ GMOCK_MOCKER_($i, constness, Method).RegisterOwner(this); \
+ return GMOCK_MOCKER_($i, constness, Method).With($as); \
} \
mutable ::testing::FunctionMocker<F> GMOCK_MOCKER_($i, constness, Method)
diff --git a/testing/gmock/include/gmock/gmock-generated-matchers.h b/testing/gmock/include/gmock/gmock-generated-matchers.h
index 2790e06..68af306 100644
--- a/testing/gmock/include/gmock/gmock-generated-matchers.h
+++ b/testing/gmock/include/gmock/gmock-generated-matchers.h
@@ -41,7 +41,7 @@
#include <sstream>
#include <string>
#include <vector>
-#include <gmock/gmock-matchers.h>
+#include "gmock/gmock-matchers.h"
namespace testing {
namespace internal {
@@ -849,6 +849,190 @@ ElementsAreArray(const T (&array)[N]) {
return internal::ElementsAreArrayMatcher<T>(array, N);
}
+// AllOf(m1, m2, ..., mk) matches any value that matches all of the given
+// sub-matchers.
+
+template <typename Matcher1, typename Matcher2>
+inline internal::BothOfMatcher<Matcher1, Matcher2>
+AllOf(Matcher1 m1, Matcher2 m2) {
+ return internal::BothOfMatcher<Matcher1, Matcher2>(m1, m2);
+}
+
+template <typename Matcher1, typename Matcher2, typename Matcher3>
+inline internal::BothOfMatcher<Matcher1, internal::BothOfMatcher<Matcher2,
+ Matcher3> >
+AllOf(Matcher1 m1, Matcher2 m2, Matcher3 m3) {
+ return AllOf(m1, AllOf(m2, m3));
+}
+
+template <typename Matcher1, typename Matcher2, typename Matcher3,
+ typename Matcher4>
+inline internal::BothOfMatcher<Matcher1, internal::BothOfMatcher<Matcher2,
+ internal::BothOfMatcher<Matcher3, Matcher4> > >
+AllOf(Matcher1 m1, Matcher2 m2, Matcher3 m3, Matcher4 m4) {
+ return AllOf(m1, AllOf(m2, m3, m4));
+}
+
+template <typename Matcher1, typename Matcher2, typename Matcher3,
+ typename Matcher4, typename Matcher5>
+inline internal::BothOfMatcher<Matcher1, internal::BothOfMatcher<Matcher2,
+ internal::BothOfMatcher<Matcher3, internal::BothOfMatcher<Matcher4,
+ Matcher5> > > >
+AllOf(Matcher1 m1, Matcher2 m2, Matcher3 m3, Matcher4 m4, Matcher5 m5) {
+ return AllOf(m1, AllOf(m2, m3, m4, m5));
+}
+
+template <typename Matcher1, typename Matcher2, typename Matcher3,
+ typename Matcher4, typename Matcher5, typename Matcher6>
+inline internal::BothOfMatcher<Matcher1, internal::BothOfMatcher<Matcher2,
+ internal::BothOfMatcher<Matcher3, internal::BothOfMatcher<Matcher4,
+ internal::BothOfMatcher<Matcher5, Matcher6> > > > >
+AllOf(Matcher1 m1, Matcher2 m2, Matcher3 m3, Matcher4 m4, Matcher5 m5,
+ Matcher6 m6) {
+ return AllOf(m1, AllOf(m2, m3, m4, m5, m6));
+}
+
+template <typename Matcher1, typename Matcher2, typename Matcher3,
+ typename Matcher4, typename Matcher5, typename Matcher6, typename Matcher7>
+inline internal::BothOfMatcher<Matcher1, internal::BothOfMatcher<Matcher2,
+ internal::BothOfMatcher<Matcher3, internal::BothOfMatcher<Matcher4,
+ internal::BothOfMatcher<Matcher5, internal::BothOfMatcher<Matcher6,
+ Matcher7> > > > > >
+AllOf(Matcher1 m1, Matcher2 m2, Matcher3 m3, Matcher4 m4, Matcher5 m5,
+ Matcher6 m6, Matcher7 m7) {
+ return AllOf(m1, AllOf(m2, m3, m4, m5, m6, m7));
+}
+
+template <typename Matcher1, typename Matcher2, typename Matcher3,
+ typename Matcher4, typename Matcher5, typename Matcher6, typename Matcher7,
+ typename Matcher8>
+inline internal::BothOfMatcher<Matcher1, internal::BothOfMatcher<Matcher2,
+ internal::BothOfMatcher<Matcher3, internal::BothOfMatcher<Matcher4,
+ internal::BothOfMatcher<Matcher5, internal::BothOfMatcher<Matcher6,
+ internal::BothOfMatcher<Matcher7, Matcher8> > > > > > >
+AllOf(Matcher1 m1, Matcher2 m2, Matcher3 m3, Matcher4 m4, Matcher5 m5,
+ Matcher6 m6, Matcher7 m7, Matcher8 m8) {
+ return AllOf(m1, AllOf(m2, m3, m4, m5, m6, m7, m8));
+}
+
+template <typename Matcher1, typename Matcher2, typename Matcher3,
+ typename Matcher4, typename Matcher5, typename Matcher6, typename Matcher7,
+ typename Matcher8, typename Matcher9>
+inline internal::BothOfMatcher<Matcher1, internal::BothOfMatcher<Matcher2,
+ internal::BothOfMatcher<Matcher3, internal::BothOfMatcher<Matcher4,
+ internal::BothOfMatcher<Matcher5, internal::BothOfMatcher<Matcher6,
+ internal::BothOfMatcher<Matcher7, internal::BothOfMatcher<Matcher8,
+ Matcher9> > > > > > > >
+AllOf(Matcher1 m1, Matcher2 m2, Matcher3 m3, Matcher4 m4, Matcher5 m5,
+ Matcher6 m6, Matcher7 m7, Matcher8 m8, Matcher9 m9) {
+ return AllOf(m1, AllOf(m2, m3, m4, m5, m6, m7, m8, m9));
+}
+
+template <typename Matcher1, typename Matcher2, typename Matcher3,
+ typename Matcher4, typename Matcher5, typename Matcher6, typename Matcher7,
+ typename Matcher8, typename Matcher9, typename Matcher10>
+inline internal::BothOfMatcher<Matcher1, internal::BothOfMatcher<Matcher2,
+ internal::BothOfMatcher<Matcher3, internal::BothOfMatcher<Matcher4,
+ internal::BothOfMatcher<Matcher5, internal::BothOfMatcher<Matcher6,
+ internal::BothOfMatcher<Matcher7, internal::BothOfMatcher<Matcher8,
+ internal::BothOfMatcher<Matcher9, Matcher10> > > > > > > > >
+AllOf(Matcher1 m1, Matcher2 m2, Matcher3 m3, Matcher4 m4, Matcher5 m5,
+ Matcher6 m6, Matcher7 m7, Matcher8 m8, Matcher9 m9, Matcher10 m10) {
+ return AllOf(m1, AllOf(m2, m3, m4, m5, m6, m7, m8, m9, m10));
+}
+
+// AnyOf(m1, m2, ..., mk) matches any value that matches any of the given
+// sub-matchers.
+
+template <typename Matcher1, typename Matcher2>
+inline internal::EitherOfMatcher<Matcher1, Matcher2>
+AnyOf(Matcher1 m1, Matcher2 m2) {
+ return internal::EitherOfMatcher<Matcher1, Matcher2>(m1, m2);
+}
+
+template <typename Matcher1, typename Matcher2, typename Matcher3>
+inline internal::EitherOfMatcher<Matcher1, internal::EitherOfMatcher<Matcher2,
+ Matcher3> >
+AnyOf(Matcher1 m1, Matcher2 m2, Matcher3 m3) {
+ return AnyOf(m1, AnyOf(m2, m3));
+}
+
+template <typename Matcher1, typename Matcher2, typename Matcher3,
+ typename Matcher4>
+inline internal::EitherOfMatcher<Matcher1, internal::EitherOfMatcher<Matcher2,
+ internal::EitherOfMatcher<Matcher3, Matcher4> > >
+AnyOf(Matcher1 m1, Matcher2 m2, Matcher3 m3, Matcher4 m4) {
+ return AnyOf(m1, AnyOf(m2, m3, m4));
+}
+
+template <typename Matcher1, typename Matcher2, typename Matcher3,
+ typename Matcher4, typename Matcher5>
+inline internal::EitherOfMatcher<Matcher1, internal::EitherOfMatcher<Matcher2,
+ internal::EitherOfMatcher<Matcher3, internal::EitherOfMatcher<Matcher4,
+ Matcher5> > > >
+AnyOf(Matcher1 m1, Matcher2 m2, Matcher3 m3, Matcher4 m4, Matcher5 m5) {
+ return AnyOf(m1, AnyOf(m2, m3, m4, m5));
+}
+
+template <typename Matcher1, typename Matcher2, typename Matcher3,
+ typename Matcher4, typename Matcher5, typename Matcher6>
+inline internal::EitherOfMatcher<Matcher1, internal::EitherOfMatcher<Matcher2,
+ internal::EitherOfMatcher<Matcher3, internal::EitherOfMatcher<Matcher4,
+ internal::EitherOfMatcher<Matcher5, Matcher6> > > > >
+AnyOf(Matcher1 m1, Matcher2 m2, Matcher3 m3, Matcher4 m4, Matcher5 m5,
+ Matcher6 m6) {
+ return AnyOf(m1, AnyOf(m2, m3, m4, m5, m6));
+}
+
+template <typename Matcher1, typename Matcher2, typename Matcher3,
+ typename Matcher4, typename Matcher5, typename Matcher6, typename Matcher7>
+inline internal::EitherOfMatcher<Matcher1, internal::EitherOfMatcher<Matcher2,
+ internal::EitherOfMatcher<Matcher3, internal::EitherOfMatcher<Matcher4,
+ internal::EitherOfMatcher<Matcher5, internal::EitherOfMatcher<Matcher6,
+ Matcher7> > > > > >
+AnyOf(Matcher1 m1, Matcher2 m2, Matcher3 m3, Matcher4 m4, Matcher5 m5,
+ Matcher6 m6, Matcher7 m7) {
+ return AnyOf(m1, AnyOf(m2, m3, m4, m5, m6, m7));
+}
+
+template <typename Matcher1, typename Matcher2, typename Matcher3,
+ typename Matcher4, typename Matcher5, typename Matcher6, typename Matcher7,
+ typename Matcher8>
+inline internal::EitherOfMatcher<Matcher1, internal::EitherOfMatcher<Matcher2,
+ internal::EitherOfMatcher<Matcher3, internal::EitherOfMatcher<Matcher4,
+ internal::EitherOfMatcher<Matcher5, internal::EitherOfMatcher<Matcher6,
+ internal::EitherOfMatcher<Matcher7, Matcher8> > > > > > >
+AnyOf(Matcher1 m1, Matcher2 m2, Matcher3 m3, Matcher4 m4, Matcher5 m5,
+ Matcher6 m6, Matcher7 m7, Matcher8 m8) {
+ return AnyOf(m1, AnyOf(m2, m3, m4, m5, m6, m7, m8));
+}
+
+template <typename Matcher1, typename Matcher2, typename Matcher3,
+ typename Matcher4, typename Matcher5, typename Matcher6, typename Matcher7,
+ typename Matcher8, typename Matcher9>
+inline internal::EitherOfMatcher<Matcher1, internal::EitherOfMatcher<Matcher2,
+ internal::EitherOfMatcher<Matcher3, internal::EitherOfMatcher<Matcher4,
+ internal::EitherOfMatcher<Matcher5, internal::EitherOfMatcher<Matcher6,
+ internal::EitherOfMatcher<Matcher7, internal::EitherOfMatcher<Matcher8,
+ Matcher9> > > > > > > >
+AnyOf(Matcher1 m1, Matcher2 m2, Matcher3 m3, Matcher4 m4, Matcher5 m5,
+ Matcher6 m6, Matcher7 m7, Matcher8 m8, Matcher9 m9) {
+ return AnyOf(m1, AnyOf(m2, m3, m4, m5, m6, m7, m8, m9));
+}
+
+template <typename Matcher1, typename Matcher2, typename Matcher3,
+ typename Matcher4, typename Matcher5, typename Matcher6, typename Matcher7,
+ typename Matcher8, typename Matcher9, typename Matcher10>
+inline internal::EitherOfMatcher<Matcher1, internal::EitherOfMatcher<Matcher2,
+ internal::EitherOfMatcher<Matcher3, internal::EitherOfMatcher<Matcher4,
+ internal::EitherOfMatcher<Matcher5, internal::EitherOfMatcher<Matcher6,
+ internal::EitherOfMatcher<Matcher7, internal::EitherOfMatcher<Matcher8,
+ internal::EitherOfMatcher<Matcher9, Matcher10> > > > > > > > >
+AnyOf(Matcher1 m1, Matcher2 m2, Matcher3 m3, Matcher4 m4, Matcher5 m5,
+ Matcher6 m6, Matcher7 m7, Matcher8 m8, Matcher9 m9, Matcher10 m10) {
+ return AnyOf(m1, AnyOf(m2, m3, m4, m5, m6, m7, m8, m9, m10));
+}
+
} // namespace testing
// The MATCHER* family of macros can be used in a namespace scope to
@@ -946,25 +1130,29 @@ ElementsAreArray(const T (&array)[N]) {
// Describing Parameterized Matchers
// =================================
//
-// When defining a parameterized matcher, you can use Python-style
-// interpolations in the description string to refer to the parameter
-// values. We support the following syntax currently:
+// The last argument to MATCHER*() is a string-typed expression. The
+// expression can reference all of the matcher's parameters and a
+// special bool-typed variable named 'negation'. When 'negation' is
+// false, the expression should evaluate to the matcher's description;
+// otherwise it should evaluate to the description of the negation of
+// the matcher. For example,
//
-// %% a single '%' character
-// %(*)s all parameters of the matcher printed as a tuple
-// %(foo)s value of the matcher parameter named 'foo'
+// using testing::PrintToString;
//
-// For example,
-//
-// MATCHER_P2(InClosedRange, low, hi, "is in range [%(low)s, %(hi)s]") {
+// MATCHER_P2(InClosedRange, low, hi,
+// string(negation ? "is not" : "is") + " in range [" +
+// PrintToString(low) + ", " + PrintToString(hi) + "]") {
// return low <= arg && arg <= hi;
// }
// ...
// EXPECT_THAT(3, InClosedRange(4, 6));
+// EXPECT_THAT(3, Not(InClosedRange(2, 4)));
//
-// would generate a failure that contains the message:
+// would generate two failures that contain the text:
//
// Expected: is in range [4, 6]
+// ...
+// Expected: is not in range [2, 4]
//
// If you specify "" as the description, the failure message will
// contain the sequence of words in the matcher name followed by the
@@ -973,10 +1161,13 @@ ElementsAreArray(const T (&array)[N]) {
// MATCHER_P2(InClosedRange, low, hi, "") { ... }
// ...
// EXPECT_THAT(3, InClosedRange(4, 6));
+// EXPECT_THAT(3, Not(InClosedRange(2, 4)));
//
-// would generate a failure that contains the text:
+// would generate two failures that contain the text:
//
// Expected: in closed range (4, 6)
+// ...
+// Expected: not (in closed range (2, 4))
//
// Types of Matcher Parameters
// ===========================
@@ -1065,33 +1256,36 @@ ElementsAreArray(const T (&array)[N]) {
template <typename arg_type>\
class gmock_Impl : public ::testing::MatcherInterface<arg_type> {\
public:\
- gmock_Impl(const ::testing::internal::Interpolations& gmock_interp)\
- : gmock_interp_(gmock_interp) {}\
+ gmock_Impl()\
+ {}\
virtual bool MatchAndExplain(\
arg_type arg, ::testing::MatchResultListener* result_listener) const;\
virtual void DescribeTo(::std::ostream* gmock_os) const {\
- const ::testing::internal::Strings& gmock_printed_params = \
- ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
- ::std::tr1::tuple<>());\
- *gmock_os << ::testing::internal::FormatMatcherDescription(\
- #name, description, gmock_interp_, gmock_printed_params);\
+ *gmock_os << FormatDescription(false);\
+ }\
+ virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\
+ *gmock_os << FormatDescription(true);\
}\
- const ::testing::internal::Interpolations gmock_interp_;\
private:\
+ ::testing::internal::string FormatDescription(bool negation) const {\
+ const ::testing::internal::string gmock_description = (description);\
+ if (!gmock_description.empty())\
+ return gmock_description;\
+ return ::testing::internal::FormatMatcherDescription(\
+ negation, #name,\
+ ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
+ ::std::tr1::tuple<>()));\
+ }\
GTEST_DISALLOW_ASSIGN_(gmock_Impl);\
};\
template <typename arg_type>\
operator ::testing::Matcher<arg_type>() const {\
return ::testing::Matcher<arg_type>(\
- new gmock_Impl<arg_type>(gmock_interp_));\
+ new gmock_Impl<arg_type>());\
}\
name##Matcher() {\
- const char* gmock_param_names[] = { NULL };\
- gmock_interp_ = ::testing::internal::ValidateMatcherDescription(\
- gmock_param_names, ("" description ""));\
}\
private:\
- ::testing::internal::Interpolations gmock_interp_;\
GTEST_DISALLOW_ASSIGN_(name##Matcher);\
};\
inline name##Matcher name() {\
@@ -1110,36 +1304,38 @@ ElementsAreArray(const T (&array)[N]) {
template <typename arg_type>\
class gmock_Impl : public ::testing::MatcherInterface<arg_type> {\
public:\
- explicit gmock_Impl(p0##_type gmock_p0, \
- const ::testing::internal::Interpolations& gmock_interp)\
- : p0(gmock_p0), gmock_interp_(gmock_interp) {}\
+ explicit gmock_Impl(p0##_type gmock_p0)\
+ : p0(gmock_p0) {}\
virtual bool MatchAndExplain(\
arg_type arg, ::testing::MatchResultListener* result_listener) const;\
virtual void DescribeTo(::std::ostream* gmock_os) const {\
- const ::testing::internal::Strings& gmock_printed_params = \
- ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
- ::std::tr1::tuple<p0##_type>(p0));\
- *gmock_os << ::testing::internal::FormatMatcherDescription(\
- #name, description, gmock_interp_, gmock_printed_params);\
+ *gmock_os << FormatDescription(false);\
+ }\
+ virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\
+ *gmock_os << FormatDescription(true);\
}\
p0##_type p0;\
- const ::testing::internal::Interpolations gmock_interp_;\
private:\
+ ::testing::internal::string FormatDescription(bool negation) const {\
+ const ::testing::internal::string gmock_description = (description);\
+ if (!gmock_description.empty())\
+ return gmock_description;\
+ return ::testing::internal::FormatMatcherDescription(\
+ negation, #name,\
+ ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
+ ::std::tr1::tuple<p0##_type>(p0)));\
+ }\
GTEST_DISALLOW_ASSIGN_(gmock_Impl);\
};\
template <typename arg_type>\
operator ::testing::Matcher<arg_type>() const {\
return ::testing::Matcher<arg_type>(\
- new gmock_Impl<arg_type>(p0, gmock_interp_));\
+ new gmock_Impl<arg_type>(p0));\
}\
name##MatcherP(p0##_type gmock_p0) : p0(gmock_p0) {\
- const char* gmock_param_names[] = { #p0, NULL };\
- gmock_interp_ = ::testing::internal::ValidateMatcherDescription(\
- gmock_param_names, ("" description ""));\
}\
p0##_type p0;\
private:\
- ::testing::internal::Interpolations gmock_interp_;\
GTEST_DISALLOW_ASSIGN_(name##MatcherP);\
};\
template <typename p0##_type>\
@@ -1160,39 +1356,41 @@ ElementsAreArray(const T (&array)[N]) {
template <typename arg_type>\
class gmock_Impl : public ::testing::MatcherInterface<arg_type> {\
public:\
- gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, \
- const ::testing::internal::Interpolations& gmock_interp)\
- : p0(gmock_p0), p1(gmock_p1), gmock_interp_(gmock_interp) {}\
+ gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1)\
+ : p0(gmock_p0), p1(gmock_p1) {}\
virtual bool MatchAndExplain(\
arg_type arg, ::testing::MatchResultListener* result_listener) const;\
virtual void DescribeTo(::std::ostream* gmock_os) const {\
- const ::testing::internal::Strings& gmock_printed_params = \
- ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
- ::std::tr1::tuple<p0##_type, p1##_type>(p0, p1));\
- *gmock_os << ::testing::internal::FormatMatcherDescription(\
- #name, description, gmock_interp_, gmock_printed_params);\
+ *gmock_os << FormatDescription(false);\
+ }\
+ virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\
+ *gmock_os << FormatDescription(true);\
}\
p0##_type p0;\
p1##_type p1;\
- const ::testing::internal::Interpolations gmock_interp_;\
private:\
+ ::testing::internal::string FormatDescription(bool negation) const {\
+ const ::testing::internal::string gmock_description = (description);\
+ if (!gmock_description.empty())\
+ return gmock_description;\
+ return ::testing::internal::FormatMatcherDescription(\
+ negation, #name,\
+ ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
+ ::std::tr1::tuple<p0##_type, p1##_type>(p0, p1)));\
+ }\
GTEST_DISALLOW_ASSIGN_(gmock_Impl);\
};\
template <typename arg_type>\
operator ::testing::Matcher<arg_type>() const {\
return ::testing::Matcher<arg_type>(\
- new gmock_Impl<arg_type>(p0, p1, gmock_interp_));\
+ new gmock_Impl<arg_type>(p0, p1));\
}\
name##MatcherP2(p0##_type gmock_p0, p1##_type gmock_p1) : p0(gmock_p0), \
p1(gmock_p1) {\
- const char* gmock_param_names[] = { #p0, #p1, NULL };\
- gmock_interp_ = ::testing::internal::ValidateMatcherDescription(\
- gmock_param_names, ("" description ""));\
}\
p0##_type p0;\
p1##_type p1;\
private:\
- ::testing::internal::Interpolations gmock_interp_;\
GTEST_DISALLOW_ASSIGN_(name##MatcherP2);\
};\
template <typename p0##_type, typename p1##_type>\
@@ -1215,43 +1413,44 @@ ElementsAreArray(const T (&array)[N]) {
template <typename arg_type>\
class gmock_Impl : public ::testing::MatcherInterface<arg_type> {\
public:\
- gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
- const ::testing::internal::Interpolations& gmock_interp)\
- : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \
- gmock_interp_(gmock_interp) {}\
+ gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2)\
+ : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2) {}\
virtual bool MatchAndExplain(\
arg_type arg, ::testing::MatchResultListener* result_listener) const;\
virtual void DescribeTo(::std::ostream* gmock_os) const {\
- const ::testing::internal::Strings& gmock_printed_params = \
- ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
- ::std::tr1::tuple<p0##_type, p1##_type, p2##_type>(p0, p1, \
- p2));\
- *gmock_os << ::testing::internal::FormatMatcherDescription(\
- #name, description, gmock_interp_, gmock_printed_params);\
+ *gmock_os << FormatDescription(false);\
+ }\
+ virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\
+ *gmock_os << FormatDescription(true);\
}\
p0##_type p0;\
p1##_type p1;\
p2##_type p2;\
- const ::testing::internal::Interpolations gmock_interp_;\
private:\
+ ::testing::internal::string FormatDescription(bool negation) const {\
+ const ::testing::internal::string gmock_description = (description);\
+ if (!gmock_description.empty())\
+ return gmock_description;\
+ return ::testing::internal::FormatMatcherDescription(\
+ negation, #name,\
+ ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
+ ::std::tr1::tuple<p0##_type, p1##_type, p2##_type>(p0, p1, \
+ p2)));\
+ }\
GTEST_DISALLOW_ASSIGN_(gmock_Impl);\
};\
template <typename arg_type>\
operator ::testing::Matcher<arg_type>() const {\
return ::testing::Matcher<arg_type>(\
- new gmock_Impl<arg_type>(p0, p1, p2, gmock_interp_));\
+ new gmock_Impl<arg_type>(p0, p1, p2));\
}\
name##MatcherP3(p0##_type gmock_p0, p1##_type gmock_p1, \
p2##_type gmock_p2) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2) {\
- const char* gmock_param_names[] = { #p0, #p1, #p2, NULL };\
- gmock_interp_ = ::testing::internal::ValidateMatcherDescription(\
- gmock_param_names, ("" description ""));\
}\
p0##_type p0;\
p1##_type p1;\
p2##_type p2;\
private:\
- ::testing::internal::Interpolations gmock_interp_;\
GTEST_DISALLOW_ASSIGN_(name##MatcherP3);\
};\
template <typename p0##_type, typename p1##_type, typename p2##_type>\
@@ -1276,46 +1475,47 @@ ElementsAreArray(const T (&array)[N]) {
class gmock_Impl : public ::testing::MatcherInterface<arg_type> {\
public:\
gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
- p3##_type gmock_p3, \
- const ::testing::internal::Interpolations& gmock_interp)\
- : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), p3(gmock_p3), \
- gmock_interp_(gmock_interp) {}\
+ p3##_type gmock_p3)\
+ : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), p3(gmock_p3) {}\
virtual bool MatchAndExplain(\
arg_type arg, ::testing::MatchResultListener* result_listener) const;\
virtual void DescribeTo(::std::ostream* gmock_os) const {\
- const ::testing::internal::Strings& gmock_printed_params = \
- ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
- ::std::tr1::tuple<p0##_type, p1##_type, p2##_type, \
- p3##_type>(p0, p1, p2, p3));\
- *gmock_os << ::testing::internal::FormatMatcherDescription(\
- #name, description, gmock_interp_, gmock_printed_params);\
+ *gmock_os << FormatDescription(false);\
+ }\
+ virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\
+ *gmock_os << FormatDescription(true);\
}\
p0##_type p0;\
p1##_type p1;\
p2##_type p2;\
p3##_type p3;\
- const ::testing::internal::Interpolations gmock_interp_;\
private:\
+ ::testing::internal::string FormatDescription(bool negation) const {\
+ const ::testing::internal::string gmock_description = (description);\
+ if (!gmock_description.empty())\
+ return gmock_description;\
+ return ::testing::internal::FormatMatcherDescription(\
+ negation, #name,\
+ ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
+ ::std::tr1::tuple<p0##_type, p1##_type, p2##_type, \
+ p3##_type>(p0, p1, p2, p3)));\
+ }\
GTEST_DISALLOW_ASSIGN_(gmock_Impl);\
};\
template <typename arg_type>\
operator ::testing::Matcher<arg_type>() const {\
return ::testing::Matcher<arg_type>(\
- new gmock_Impl<arg_type>(p0, p1, p2, p3, gmock_interp_));\
+ new gmock_Impl<arg_type>(p0, p1, p2, p3));\
}\
name##MatcherP4(p0##_type gmock_p0, p1##_type gmock_p1, \
p2##_type gmock_p2, p3##_type gmock_p3) : p0(gmock_p0), p1(gmock_p1), \
p2(gmock_p2), p3(gmock_p3) {\
- const char* gmock_param_names[] = { #p0, #p1, #p2, #p3, NULL };\
- gmock_interp_ = ::testing::internal::ValidateMatcherDescription(\
- gmock_param_names, ("" description ""));\
}\
p0##_type p0;\
p1##_type p1;\
p2##_type p2;\
p3##_type p3;\
private:\
- ::testing::internal::Interpolations gmock_interp_;\
GTEST_DISALLOW_ASSIGN_(name##MatcherP4);\
};\
template <typename p0##_type, typename p1##_type, typename p2##_type, \
@@ -1344,41 +1544,44 @@ ElementsAreArray(const T (&array)[N]) {
class gmock_Impl : public ::testing::MatcherInterface<arg_type> {\
public:\
gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
- p3##_type gmock_p3, p4##_type gmock_p4, \
- const ::testing::internal::Interpolations& gmock_interp)\
+ p3##_type gmock_p3, p4##_type gmock_p4)\
: p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), p3(gmock_p3), \
- p4(gmock_p4), gmock_interp_(gmock_interp) {}\
+ p4(gmock_p4) {}\
virtual bool MatchAndExplain(\
arg_type arg, ::testing::MatchResultListener* result_listener) const;\
virtual void DescribeTo(::std::ostream* gmock_os) const {\
- const ::testing::internal::Strings& gmock_printed_params = \
- ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
- ::std::tr1::tuple<p0##_type, p1##_type, p2##_type, p3##_type, \
- p4##_type>(p0, p1, p2, p3, p4));\
- *gmock_os << ::testing::internal::FormatMatcherDescription(\
- #name, description, gmock_interp_, gmock_printed_params);\
+ *gmock_os << FormatDescription(false);\
+ }\
+ virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\
+ *gmock_os << FormatDescription(true);\
}\
p0##_type p0;\
p1##_type p1;\
p2##_type p2;\
p3##_type p3;\
p4##_type p4;\
- const ::testing::internal::Interpolations gmock_interp_;\
private:\
+ ::testing::internal::string FormatDescription(bool negation) const {\
+ const ::testing::internal::string gmock_description = (description);\
+ if (!gmock_description.empty())\
+ return gmock_description;\
+ return ::testing::internal::FormatMatcherDescription(\
+ negation, #name,\
+ ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
+ ::std::tr1::tuple<p0##_type, p1##_type, p2##_type, p3##_type, \
+ p4##_type>(p0, p1, p2, p3, p4)));\
+ }\
GTEST_DISALLOW_ASSIGN_(gmock_Impl);\
};\
template <typename arg_type>\
operator ::testing::Matcher<arg_type>() const {\
return ::testing::Matcher<arg_type>(\
- new gmock_Impl<arg_type>(p0, p1, p2, p3, p4, gmock_interp_));\
+ new gmock_Impl<arg_type>(p0, p1, p2, p3, p4));\
}\
name##MatcherP5(p0##_type gmock_p0, p1##_type gmock_p1, \
p2##_type gmock_p2, p3##_type gmock_p3, \
p4##_type gmock_p4) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \
p3(gmock_p3), p4(gmock_p4) {\
- const char* gmock_param_names[] = { #p0, #p1, #p2, #p3, #p4, NULL };\
- gmock_interp_ = ::testing::internal::ValidateMatcherDescription(\
- gmock_param_names, ("" description ""));\
}\
p0##_type p0;\
p1##_type p1;\
@@ -1386,7 +1589,6 @@ ElementsAreArray(const T (&array)[N]) {
p3##_type p3;\
p4##_type p4;\
private:\
- ::testing::internal::Interpolations gmock_interp_;\
GTEST_DISALLOW_ASSIGN_(name##MatcherP5);\
};\
template <typename p0##_type, typename p1##_type, typename p2##_type, \
@@ -1415,19 +1617,16 @@ ElementsAreArray(const T (&array)[N]) {
class gmock_Impl : public ::testing::MatcherInterface<arg_type> {\
public:\
gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
- p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \
- const ::testing::internal::Interpolations& gmock_interp)\
+ p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5)\
: p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), p3(gmock_p3), \
- p4(gmock_p4), p5(gmock_p5), gmock_interp_(gmock_interp) {}\
+ p4(gmock_p4), p5(gmock_p5) {}\
virtual bool MatchAndExplain(\
arg_type arg, ::testing::MatchResultListener* result_listener) const;\
virtual void DescribeTo(::std::ostream* gmock_os) const {\
- const ::testing::internal::Strings& gmock_printed_params = \
- ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
- ::std::tr1::tuple<p0##_type, p1##_type, p2##_type, p3##_type, \
- p4##_type, p5##_type>(p0, p1, p2, p3, p4, p5));\
- *gmock_os << ::testing::internal::FormatMatcherDescription(\
- #name, description, gmock_interp_, gmock_printed_params);\
+ *gmock_os << FormatDescription(false);\
+ }\
+ virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\
+ *gmock_os << FormatDescription(true);\
}\
p0##_type p0;\
p1##_type p1;\
@@ -1435,22 +1634,28 @@ ElementsAreArray(const T (&array)[N]) {
p3##_type p3;\
p4##_type p4;\
p5##_type p5;\
- const ::testing::internal::Interpolations gmock_interp_;\
private:\
+ ::testing::internal::string FormatDescription(bool negation) const {\
+ const ::testing::internal::string gmock_description = (description);\
+ if (!gmock_description.empty())\
+ return gmock_description;\
+ return ::testing::internal::FormatMatcherDescription(\
+ negation, #name,\
+ ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
+ ::std::tr1::tuple<p0##_type, p1##_type, p2##_type, p3##_type, \
+ p4##_type, p5##_type>(p0, p1, p2, p3, p4, p5)));\
+ }\
GTEST_DISALLOW_ASSIGN_(gmock_Impl);\
};\
template <typename arg_type>\
operator ::testing::Matcher<arg_type>() const {\
return ::testing::Matcher<arg_type>(\
- new gmock_Impl<arg_type>(p0, p1, p2, p3, p4, p5, gmock_interp_));\
+ new gmock_Impl<arg_type>(p0, p1, p2, p3, p4, p5));\
}\
name##MatcherP6(p0##_type gmock_p0, p1##_type gmock_p1, \
p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \
p5##_type gmock_p5) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \
p3(gmock_p3), p4(gmock_p4), p5(gmock_p5) {\
- const char* gmock_param_names[] = { #p0, #p1, #p2, #p3, #p4, #p5, NULL };\
- gmock_interp_ = ::testing::internal::ValidateMatcherDescription(\
- gmock_param_names, ("" description ""));\
}\
p0##_type p0;\
p1##_type p1;\
@@ -1459,7 +1664,6 @@ ElementsAreArray(const T (&array)[N]) {
p4##_type p4;\
p5##_type p5;\
private:\
- ::testing::internal::Interpolations gmock_interp_;\
GTEST_DISALLOW_ASSIGN_(name##MatcherP6);\
};\
template <typename p0##_type, typename p1##_type, typename p2##_type, \
@@ -1490,21 +1694,16 @@ ElementsAreArray(const T (&array)[N]) {
public:\
gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \
- p6##_type gmock_p6, \
- const ::testing::internal::Interpolations& gmock_interp)\
+ p6##_type gmock_p6)\
: p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), p3(gmock_p3), \
- p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), \
- gmock_interp_(gmock_interp) {}\
+ p4(gmock_p4), p5(gmock_p5), p6(gmock_p6) {}\
virtual bool MatchAndExplain(\
arg_type arg, ::testing::MatchResultListener* result_listener) const;\
virtual void DescribeTo(::std::ostream* gmock_os) const {\
- const ::testing::internal::Strings& gmock_printed_params = \
- ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
- ::std::tr1::tuple<p0##_type, p1##_type, p2##_type, p3##_type, \
- p4##_type, p5##_type, p6##_type>(p0, p1, p2, p3, p4, p5, \
- p6));\
- *gmock_os << ::testing::internal::FormatMatcherDescription(\
- #name, description, gmock_interp_, gmock_printed_params);\
+ *gmock_os << FormatDescription(false);\
+ }\
+ virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\
+ *gmock_os << FormatDescription(true);\
}\
p0##_type p0;\
p1##_type p1;\
@@ -1513,24 +1712,30 @@ ElementsAreArray(const T (&array)[N]) {
p4##_type p4;\
p5##_type p5;\
p6##_type p6;\
- const ::testing::internal::Interpolations gmock_interp_;\
private:\
+ ::testing::internal::string FormatDescription(bool negation) const {\
+ const ::testing::internal::string gmock_description = (description);\
+ if (!gmock_description.empty())\
+ return gmock_description;\
+ return ::testing::internal::FormatMatcherDescription(\
+ negation, #name,\
+ ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
+ ::std::tr1::tuple<p0##_type, p1##_type, p2##_type, p3##_type, \
+ p4##_type, p5##_type, p6##_type>(p0, p1, p2, p3, p4, p5, \
+ p6)));\
+ }\
GTEST_DISALLOW_ASSIGN_(gmock_Impl);\
};\
template <typename arg_type>\
operator ::testing::Matcher<arg_type>() const {\
return ::testing::Matcher<arg_type>(\
- new gmock_Impl<arg_type>(p0, p1, p2, p3, p4, p5, p6, gmock_interp_));\
+ new gmock_Impl<arg_type>(p0, p1, p2, p3, p4, p5, p6));\
}\
name##MatcherP7(p0##_type gmock_p0, p1##_type gmock_p1, \
p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \
p5##_type gmock_p5, p6##_type gmock_p6) : p0(gmock_p0), p1(gmock_p1), \
p2(gmock_p2), p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), \
p6(gmock_p6) {\
- const char* gmock_param_names[] = { #p0, #p1, #p2, #p3, #p4, #p5, #p6, \
- NULL };\
- gmock_interp_ = ::testing::internal::ValidateMatcherDescription(\
- gmock_param_names, ("" description ""));\
}\
p0##_type p0;\
p1##_type p1;\
@@ -1540,7 +1745,6 @@ ElementsAreArray(const T (&array)[N]) {
p5##_type p5;\
p6##_type p6;\
private:\
- ::testing::internal::Interpolations gmock_interp_;\
GTEST_DISALLOW_ASSIGN_(name##MatcherP7);\
};\
template <typename p0##_type, typename p1##_type, typename p2##_type, \
@@ -1574,21 +1778,16 @@ ElementsAreArray(const T (&array)[N]) {
public:\
gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \
- p6##_type gmock_p6, p7##_type gmock_p7, \
- const ::testing::internal::Interpolations& gmock_interp)\
+ p6##_type gmock_p6, p7##_type gmock_p7)\
: p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), p3(gmock_p3), \
- p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), p7(gmock_p7), \
- gmock_interp_(gmock_interp) {}\
+ p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), p7(gmock_p7) {}\
virtual bool MatchAndExplain(\
arg_type arg, ::testing::MatchResultListener* result_listener) const;\
virtual void DescribeTo(::std::ostream* gmock_os) const {\
- const ::testing::internal::Strings& gmock_printed_params = \
- ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
- ::std::tr1::tuple<p0##_type, p1##_type, p2##_type, p3##_type, \
- p4##_type, p5##_type, p6##_type, p7##_type>(p0, p1, p2, \
- p3, p4, p5, p6, p7));\
- *gmock_os << ::testing::internal::FormatMatcherDescription(\
- #name, description, gmock_interp_, gmock_printed_params);\
+ *gmock_os << FormatDescription(false);\
+ }\
+ virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\
+ *gmock_os << FormatDescription(true);\
}\
p0##_type p0;\
p1##_type p1;\
@@ -1598,15 +1797,24 @@ ElementsAreArray(const T (&array)[N]) {
p5##_type p5;\
p6##_type p6;\
p7##_type p7;\
- const ::testing::internal::Interpolations gmock_interp_;\
private:\
+ ::testing::internal::string FormatDescription(bool negation) const {\
+ const ::testing::internal::string gmock_description = (description);\
+ if (!gmock_description.empty())\
+ return gmock_description;\
+ return ::testing::internal::FormatMatcherDescription(\
+ negation, #name,\
+ ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
+ ::std::tr1::tuple<p0##_type, p1##_type, p2##_type, p3##_type, \
+ p4##_type, p5##_type, p6##_type, p7##_type>(p0, p1, p2, \
+ p3, p4, p5, p6, p7)));\
+ }\
GTEST_DISALLOW_ASSIGN_(gmock_Impl);\
};\
template <typename arg_type>\
operator ::testing::Matcher<arg_type>() const {\
return ::testing::Matcher<arg_type>(\
- new gmock_Impl<arg_type>(p0, p1, p2, p3, p4, p5, p6, p7, \
- gmock_interp_));\
+ new gmock_Impl<arg_type>(p0, p1, p2, p3, p4, p5, p6, p7));\
}\
name##MatcherP8(p0##_type gmock_p0, p1##_type gmock_p1, \
p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \
@@ -1614,10 +1822,6 @@ ElementsAreArray(const T (&array)[N]) {
p7##_type gmock_p7) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \
p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), \
p7(gmock_p7) {\
- const char* gmock_param_names[] = { #p0, #p1, #p2, #p3, #p4, #p5, #p6, \
- #p7, NULL };\
- gmock_interp_ = ::testing::internal::ValidateMatcherDescription(\
- gmock_param_names, ("" description ""));\
}\
p0##_type p0;\
p1##_type p1;\
@@ -1628,7 +1832,6 @@ ElementsAreArray(const T (&array)[N]) {
p6##_type p6;\
p7##_type p7;\
private:\
- ::testing::internal::Interpolations gmock_interp_;\
GTEST_DISALLOW_ASSIGN_(name##MatcherP8);\
};\
template <typename p0##_type, typename p1##_type, typename p2##_type, \
@@ -1664,21 +1867,17 @@ ElementsAreArray(const T (&array)[N]) {
public:\
gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \
- p6##_type gmock_p6, p7##_type gmock_p7, p8##_type gmock_p8, \
- const ::testing::internal::Interpolations& gmock_interp)\
+ p6##_type gmock_p6, p7##_type gmock_p7, p8##_type gmock_p8)\
: p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), p3(gmock_p3), \
p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), p7(gmock_p7), \
- p8(gmock_p8), gmock_interp_(gmock_interp) {}\
+ p8(gmock_p8) {}\
virtual bool MatchAndExplain(\
arg_type arg, ::testing::MatchResultListener* result_listener) const;\
virtual void DescribeTo(::std::ostream* gmock_os) const {\
- const ::testing::internal::Strings& gmock_printed_params = \
- ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
- ::std::tr1::tuple<p0##_type, p1##_type, p2##_type, p3##_type, \
- p4##_type, p5##_type, p6##_type, p7##_type, \
- p8##_type>(p0, p1, p2, p3, p4, p5, p6, p7, p8));\
- *gmock_os << ::testing::internal::FormatMatcherDescription(\
- #name, description, gmock_interp_, gmock_printed_params);\
+ *gmock_os << FormatDescription(false);\
+ }\
+ virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\
+ *gmock_os << FormatDescription(true);\
}\
p0##_type p0;\
p1##_type p1;\
@@ -1689,15 +1888,24 @@ ElementsAreArray(const T (&array)[N]) {
p6##_type p6;\
p7##_type p7;\
p8##_type p8;\
- const ::testing::internal::Interpolations gmock_interp_;\
private:\
+ ::testing::internal::string FormatDescription(bool negation) const {\
+ const ::testing::internal::string gmock_description = (description);\
+ if (!gmock_description.empty())\
+ return gmock_description;\
+ return ::testing::internal::FormatMatcherDescription(\
+ negation, #name,\
+ ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
+ ::std::tr1::tuple<p0##_type, p1##_type, p2##_type, p3##_type, \
+ p4##_type, p5##_type, p6##_type, p7##_type, \
+ p8##_type>(p0, p1, p2, p3, p4, p5, p6, p7, p8)));\
+ }\
GTEST_DISALLOW_ASSIGN_(gmock_Impl);\
};\
template <typename arg_type>\
operator ::testing::Matcher<arg_type>() const {\
return ::testing::Matcher<arg_type>(\
- new gmock_Impl<arg_type>(p0, p1, p2, p3, p4, p5, p6, p7, p8, \
- gmock_interp_));\
+ new gmock_Impl<arg_type>(p0, p1, p2, p3, p4, p5, p6, p7, p8));\
}\
name##MatcherP9(p0##_type gmock_p0, p1##_type gmock_p1, \
p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \
@@ -1705,10 +1913,6 @@ ElementsAreArray(const T (&array)[N]) {
p8##_type gmock_p8) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \
p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), p7(gmock_p7), \
p8(gmock_p8) {\
- const char* gmock_param_names[] = { #p0, #p1, #p2, #p3, #p4, #p5, #p6, \
- #p7, #p8, NULL };\
- gmock_interp_ = ::testing::internal::ValidateMatcherDescription(\
- gmock_param_names, ("" description ""));\
}\
p0##_type p0;\
p1##_type p1;\
@@ -1720,7 +1924,6 @@ ElementsAreArray(const T (&array)[N]) {
p7##_type p7;\
p8##_type p8;\
private:\
- ::testing::internal::Interpolations gmock_interp_;\
GTEST_DISALLOW_ASSIGN_(name##MatcherP9);\
};\
template <typename p0##_type, typename p1##_type, typename p2##_type, \
@@ -1759,21 +1962,17 @@ ElementsAreArray(const T (&array)[N]) {
gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \
p6##_type gmock_p6, p7##_type gmock_p7, p8##_type gmock_p8, \
- p9##_type gmock_p9, \
- const ::testing::internal::Interpolations& gmock_interp)\
+ p9##_type gmock_p9)\
: p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), p3(gmock_p3), \
p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), p7(gmock_p7), \
- p8(gmock_p8), p9(gmock_p9), gmock_interp_(gmock_interp) {}\
+ p8(gmock_p8), p9(gmock_p9) {}\
virtual bool MatchAndExplain(\
arg_type arg, ::testing::MatchResultListener* result_listener) const;\
virtual void DescribeTo(::std::ostream* gmock_os) const {\
- const ::testing::internal::Strings& gmock_printed_params = \
- ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
- ::std::tr1::tuple<p0##_type, p1##_type, p2##_type, p3##_type, \
- p4##_type, p5##_type, p6##_type, p7##_type, p8##_type, \
- p9##_type>(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9));\
- *gmock_os << ::testing::internal::FormatMatcherDescription(\
- #name, description, gmock_interp_, gmock_printed_params);\
+ *gmock_os << FormatDescription(false);\
+ }\
+ virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\
+ *gmock_os << FormatDescription(true);\
}\
p0##_type p0;\
p1##_type p1;\
@@ -1785,15 +1984,24 @@ ElementsAreArray(const T (&array)[N]) {
p7##_type p7;\
p8##_type p8;\
p9##_type p9;\
- const ::testing::internal::Interpolations gmock_interp_;\
private:\
+ ::testing::internal::string FormatDescription(bool negation) const {\
+ const ::testing::internal::string gmock_description = (description);\
+ if (!gmock_description.empty())\
+ return gmock_description;\
+ return ::testing::internal::FormatMatcherDescription(\
+ negation, #name,\
+ ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
+ ::std::tr1::tuple<p0##_type, p1##_type, p2##_type, p3##_type, \
+ p4##_type, p5##_type, p6##_type, p7##_type, p8##_type, \
+ p9##_type>(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9)));\
+ }\
GTEST_DISALLOW_ASSIGN_(gmock_Impl);\
};\
template <typename arg_type>\
operator ::testing::Matcher<arg_type>() const {\
return ::testing::Matcher<arg_type>(\
- new gmock_Impl<arg_type>(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, \
- gmock_interp_));\
+ new gmock_Impl<arg_type>(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9));\
}\
name##MatcherP10(p0##_type gmock_p0, p1##_type gmock_p1, \
p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \
@@ -1801,10 +2009,6 @@ ElementsAreArray(const T (&array)[N]) {
p8##_type gmock_p8, p9##_type gmock_p9) : p0(gmock_p0), p1(gmock_p1), \
p2(gmock_p2), p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), \
p7(gmock_p7), p8(gmock_p8), p9(gmock_p9) {\
- const char* gmock_param_names[] = { #p0, #p1, #p2, #p3, #p4, #p5, #p6, \
- #p7, #p8, #p9, NULL };\
- gmock_interp_ = ::testing::internal::ValidateMatcherDescription(\
- gmock_param_names, ("" description ""));\
}\
p0##_type p0;\
p1##_type p1;\
@@ -1817,7 +2021,6 @@ ElementsAreArray(const T (&array)[N]) {
p8##_type p8;\
p9##_type p9;\
private:\
- ::testing::internal::Interpolations gmock_interp_;\
GTEST_DISALLOW_ASSIGN_(name##MatcherP10);\
};\
template <typename p0##_type, typename p1##_type, typename p2##_type, \
diff --git a/testing/gmock/include/gmock/gmock-generated-matchers.h.pump b/testing/gmock/include/gmock/gmock-generated-matchers.h.pump
index db498ec..cebdd0e 100644
--- a/testing/gmock/include/gmock/gmock-generated-matchers.h.pump
+++ b/testing/gmock/include/gmock/gmock-generated-matchers.h.pump
@@ -43,7 +43,7 @@ $$ }} This line fixes auto-indentation of the following code in Emacs.
#include <sstream>
#include <string>
#include <vector>
-#include <gmock/gmock-matchers.h>
+#include "gmock/gmock-matchers.h"
namespace testing {
namespace internal {
@@ -302,6 +302,52 @@ ElementsAreArray(const T (&array)[N]) {
return internal::ElementsAreArrayMatcher<T>(array, N);
}
+// AllOf(m1, m2, ..., mk) matches any value that matches all of the given
+// sub-matchers.
+
+$range i 2..n
+$for i [[
+$range j 1..i
+$range k 1..i-1
+
+template <$for j, [[typename Matcher$j]]>
+inline $for k[[internal::BothOfMatcher<Matcher$k, ]]Matcher$i[[]]$for k [[> ]]
+
+AllOf($for j, [[Matcher$j m$j]]) {
+
+$if i == 2 [[
+ return internal::BothOfMatcher<Matcher1, Matcher2>(m1, m2);
+]] $else [[
+ return AllOf(m1, AllOf($for k, [[m$(k + 1)]]));
+]]
+
+}
+
+]]
+
+// AnyOf(m1, m2, ..., mk) matches any value that matches any of the given
+// sub-matchers.
+
+$range i 2..n
+$for i [[
+$range j 1..i
+$range k 1..i-1
+
+template <$for j, [[typename Matcher$j]]>
+inline $for k[[internal::EitherOfMatcher<Matcher$k, ]]Matcher$i[[]]$for k [[> ]]
+
+AnyOf($for j, [[Matcher$j m$j]]) {
+
+$if i == 2 [[
+ return internal::EitherOfMatcher<Matcher1, Matcher2>(m1, m2);
+]] $else [[
+ return AnyOf(m1, AnyOf($for k, [[m$(k + 1)]]));
+]]
+
+}
+
+]]
+
} // namespace testing
$$ } // This Pump meta comment fixes auto-indentation in Emacs. It will not
$$ // show up in the generated code.
@@ -402,25 +448,29 @@ $$ // show up in the generated code.
// Describing Parameterized Matchers
// =================================
//
-// When defining a parameterized matcher, you can use Python-style
-// interpolations in the description string to refer to the parameter
-// values. We support the following syntax currently:
+// The last argument to MATCHER*() is a string-typed expression. The
+// expression can reference all of the matcher's parameters and a
+// special bool-typed variable named 'negation'. When 'negation' is
+// false, the expression should evaluate to the matcher's description;
+// otherwise it should evaluate to the description of the negation of
+// the matcher. For example,
//
-// %% a single '%' character
-// %(*)s all parameters of the matcher printed as a tuple
-// %(foo)s value of the matcher parameter named 'foo'
+// using testing::PrintToString;
//
-// For example,
-//
-// MATCHER_P2(InClosedRange, low, hi, "is in range [%(low)s, %(hi)s]") {
+// MATCHER_P2(InClosedRange, low, hi,
+// string(negation ? "is not" : "is") + " in range [" +
+// PrintToString(low) + ", " + PrintToString(hi) + "]") {
// return low <= arg && arg <= hi;
// }
// ...
// EXPECT_THAT(3, InClosedRange(4, 6));
+// EXPECT_THAT(3, Not(InClosedRange(2, 4)));
//
-// would generate a failure that contains the message:
+// would generate two failures that contain the text:
//
// Expected: is in range [4, 6]
+// ...
+// Expected: is not in range [2, 4]
//
// If you specify "" as the description, the failure message will
// contain the sequence of words in the matcher name followed by the
@@ -429,10 +479,13 @@ $$ // show up in the generated code.
// MATCHER_P2(InClosedRange, low, hi, "") { ... }
// ...
// EXPECT_THAT(3, InClosedRange(4, 6));
+// EXPECT_THAT(3, Not(InClosedRange(2, 4)));
//
-// would generate a failure that contains the text:
+// would generate two failures that contain the text:
//
// Expected: in closed range (4, 6)
+// ...
+// Expected: not (in closed range (2, 4))
//
// Types of Matcher Parameters
// ===========================
@@ -529,11 +582,9 @@ $var template = [[$if i==0 [[]] $else [[
template <$for j, [[typename p$j##_type]]>\
]]]]
$var ctor_param_list = [[$for j, [[p$j##_type gmock_p$j]]]]
-$var impl_ctor_param_list = [[$for j [[p$j##_type gmock_p$j, ]]
-const ::testing::internal::Interpolations& gmock_interp]]
-$var impl_inits = [[ : $for j [[p$j(gmock_p$j), ]]gmock_interp_(gmock_interp)]]
+$var impl_ctor_param_list = [[$for j, [[p$j##_type gmock_p$j]]]]
+$var impl_inits = [[$if i==0 [[]] $else [[ : $for j, [[p$j(gmock_p$j)]]]]]]
$var inits = [[$if i==0 [[]] $else [[ : $for j, [[p$j(gmock_p$j)]]]]]]
-$var params_and_interp = [[$for j [[p$j, ]]gmock_interp_]]
$var params = [[$for j, [[p$j]]]]
$var param_types = [[$if i==0 [[]] $else [[<$for j, [[p$j##_type]]>]]]]
$var param_types_and_names = [[$for j, [[p$j##_type p$j]]]]
@@ -559,28 +610,31 @@ $var param_field_decls2 = [[$for j
virtual bool MatchAndExplain(\
arg_type arg, ::testing::MatchResultListener* result_listener) const;\
virtual void DescribeTo(::std::ostream* gmock_os) const {\
- const ::testing::internal::Strings& gmock_printed_params = \
- ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
- ::std::tr1::tuple<$for j, [[p$j##_type]]>($for j, [[p$j]]));\
- *gmock_os << ::testing::internal::FormatMatcherDescription(\
- #name, description, gmock_interp_, gmock_printed_params);\
+ *gmock_os << FormatDescription(false);\
+ }\
+ virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\
+ *gmock_os << FormatDescription(true);\
}\$param_field_decls
- const ::testing::internal::Interpolations gmock_interp_;\
private:\
+ ::testing::internal::string FormatDescription(bool negation) const {\
+ const ::testing::internal::string gmock_description = (description);\
+ if (!gmock_description.empty())\
+ return gmock_description;\
+ return ::testing::internal::FormatMatcherDescription(\
+ negation, #name,\
+ ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
+ ::std::tr1::tuple<$for j, [[p$j##_type]]>($for j, [[p$j]])));\
+ }\
GTEST_DISALLOW_ASSIGN_(gmock_Impl);\
};\
template <typename arg_type>\
operator ::testing::Matcher<arg_type>() const {\
return ::testing::Matcher<arg_type>(\
- new gmock_Impl<arg_type>($params_and_interp));\
+ new gmock_Impl<arg_type>($params));\
}\
$class_name($ctor_param_list)$inits {\
- const char* gmock_param_names[] = { $for j [[#p$j, ]]NULL };\
- gmock_interp_ = ::testing::internal::ValidateMatcherDescription(\
- gmock_param_names, ("" description ""));\
}\$param_field_decls2
private:\
- ::testing::internal::Interpolations gmock_interp_;\
GTEST_DISALLOW_ASSIGN_($class_name);\
};\$template
inline $class_name$param_types name($param_types_and_names) {\
diff --git a/testing/gmock/include/gmock/gmock-generated-nice-strict.h b/testing/gmock/include/gmock/gmock-generated-nice-strict.h
index 435467f..6099e81 100644
--- a/testing/gmock/include/gmock/gmock-generated-nice-strict.h
+++ b/testing/gmock/include/gmock/gmock-generated-nice-strict.h
@@ -59,8 +59,8 @@
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_
#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_
-#include <gmock/gmock-spec-builders.h>
-#include <gmock/internal/gmock-port.h>
+#include "gmock/gmock-spec-builders.h"
+#include "gmock/internal/gmock-port.h"
namespace testing {
@@ -71,7 +71,7 @@ class NiceMock : public MockClass {
// we have to avoid a possible clash with members of MockClass.
NiceMock() {
::testing::Mock::AllowUninterestingCalls(
- internal::implicit_cast<MockClass*>(this));
+ internal::ImplicitCast_<MockClass*>(this));
}
// C++ doesn't (yet) allow inheritance of constructors, so we have
@@ -79,32 +79,32 @@ class NiceMock : public MockClass {
template <typename A1>
explicit NiceMock(const A1& a1) : MockClass(a1) {
::testing::Mock::AllowUninterestingCalls(
- internal::implicit_cast<MockClass*>(this));
+ internal::ImplicitCast_<MockClass*>(this));
}
template <typename A1, typename A2>
NiceMock(const A1& a1, const A2& a2) : MockClass(a1, a2) {
::testing::Mock::AllowUninterestingCalls(
- internal::implicit_cast<MockClass*>(this));
+ internal::ImplicitCast_<MockClass*>(this));
}
template <typename A1, typename A2, typename A3>
NiceMock(const A1& a1, const A2& a2, const A3& a3) : MockClass(a1, a2, a3) {
::testing::Mock::AllowUninterestingCalls(
- internal::implicit_cast<MockClass*>(this));
+ internal::ImplicitCast_<MockClass*>(this));
}
template <typename A1, typename A2, typename A3, typename A4>
NiceMock(const A1& a1, const A2& a2, const A3& a3,
const A4& a4) : MockClass(a1, a2, a3, a4) {
::testing::Mock::AllowUninterestingCalls(
- internal::implicit_cast<MockClass*>(this));
+ internal::ImplicitCast_<MockClass*>(this));
}
template <typename A1, typename A2, typename A3, typename A4, typename A5>
NiceMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
const A5& a5) : MockClass(a1, a2, a3, a4, a5) {
::testing::Mock::AllowUninterestingCalls(
- internal::implicit_cast<MockClass*>(this));
+ internal::ImplicitCast_<MockClass*>(this));
}
template <typename A1, typename A2, typename A3, typename A4, typename A5,
@@ -112,7 +112,7 @@ class NiceMock : public MockClass {
NiceMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
const A5& a5, const A6& a6) : MockClass(a1, a2, a3, a4, a5, a6) {
::testing::Mock::AllowUninterestingCalls(
- internal::implicit_cast<MockClass*>(this));
+ internal::ImplicitCast_<MockClass*>(this));
}
template <typename A1, typename A2, typename A3, typename A4, typename A5,
@@ -121,7 +121,7 @@ class NiceMock : public MockClass {
const A5& a5, const A6& a6, const A7& a7) : MockClass(a1, a2, a3, a4, a5,
a6, a7) {
::testing::Mock::AllowUninterestingCalls(
- internal::implicit_cast<MockClass*>(this));
+ internal::ImplicitCast_<MockClass*>(this));
}
template <typename A1, typename A2, typename A3, typename A4, typename A5,
@@ -130,7 +130,7 @@ class NiceMock : public MockClass {
const A5& a5, const A6& a6, const A7& a7, const A8& a8) : MockClass(a1,
a2, a3, a4, a5, a6, a7, a8) {
::testing::Mock::AllowUninterestingCalls(
- internal::implicit_cast<MockClass*>(this));
+ internal::ImplicitCast_<MockClass*>(this));
}
template <typename A1, typename A2, typename A3, typename A4, typename A5,
@@ -139,7 +139,7 @@ class NiceMock : public MockClass {
const A5& a5, const A6& a6, const A7& a7, const A8& a8,
const A9& a9) : MockClass(a1, a2, a3, a4, a5, a6, a7, a8, a9) {
::testing::Mock::AllowUninterestingCalls(
- internal::implicit_cast<MockClass*>(this));
+ internal::ImplicitCast_<MockClass*>(this));
}
template <typename A1, typename A2, typename A3, typename A4, typename A5,
@@ -148,12 +148,12 @@ class NiceMock : public MockClass {
const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9,
const A10& a10) : MockClass(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) {
::testing::Mock::AllowUninterestingCalls(
- internal::implicit_cast<MockClass*>(this));
+ internal::ImplicitCast_<MockClass*>(this));
}
virtual ~NiceMock() {
::testing::Mock::UnregisterCallReaction(
- internal::implicit_cast<MockClass*>(this));
+ internal::ImplicitCast_<MockClass*>(this));
}
private:
@@ -167,38 +167,38 @@ class StrictMock : public MockClass {
// we have to avoid a possible clash with members of MockClass.
StrictMock() {
::testing::Mock::FailUninterestingCalls(
- internal::implicit_cast<MockClass*>(this));
+ internal::ImplicitCast_<MockClass*>(this));
}
template <typename A1>
explicit StrictMock(const A1& a1) : MockClass(a1) {
::testing::Mock::FailUninterestingCalls(
- internal::implicit_cast<MockClass*>(this));
+ internal::ImplicitCast_<MockClass*>(this));
}
template <typename A1, typename A2>
StrictMock(const A1& a1, const A2& a2) : MockClass(a1, a2) {
::testing::Mock::FailUninterestingCalls(
- internal::implicit_cast<MockClass*>(this));
+ internal::ImplicitCast_<MockClass*>(this));
}
template <typename A1, typename A2, typename A3>
StrictMock(const A1& a1, const A2& a2, const A3& a3) : MockClass(a1, a2, a3) {
::testing::Mock::FailUninterestingCalls(
- internal::implicit_cast<MockClass*>(this));
+ internal::ImplicitCast_<MockClass*>(this));
}
template <typename A1, typename A2, typename A3, typename A4>
StrictMock(const A1& a1, const A2& a2, const A3& a3,
const A4& a4) : MockClass(a1, a2, a3, a4) {
::testing::Mock::FailUninterestingCalls(
- internal::implicit_cast<MockClass*>(this));
+ internal::ImplicitCast_<MockClass*>(this));
}
template <typename A1, typename A2, typename A3, typename A4, typename A5>
StrictMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
const A5& a5) : MockClass(a1, a2, a3, a4, a5) {
::testing::Mock::FailUninterestingCalls(
- internal::implicit_cast<MockClass*>(this));
+ internal::ImplicitCast_<MockClass*>(this));
}
template <typename A1, typename A2, typename A3, typename A4, typename A5,
@@ -206,7 +206,7 @@ class StrictMock : public MockClass {
StrictMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
const A5& a5, const A6& a6) : MockClass(a1, a2, a3, a4, a5, a6) {
::testing::Mock::FailUninterestingCalls(
- internal::implicit_cast<MockClass*>(this));
+ internal::ImplicitCast_<MockClass*>(this));
}
template <typename A1, typename A2, typename A3, typename A4, typename A5,
@@ -215,7 +215,7 @@ class StrictMock : public MockClass {
const A5& a5, const A6& a6, const A7& a7) : MockClass(a1, a2, a3, a4, a5,
a6, a7) {
::testing::Mock::FailUninterestingCalls(
- internal::implicit_cast<MockClass*>(this));
+ internal::ImplicitCast_<MockClass*>(this));
}
template <typename A1, typename A2, typename A3, typename A4, typename A5,
@@ -224,7 +224,7 @@ class StrictMock : public MockClass {
const A5& a5, const A6& a6, const A7& a7, const A8& a8) : MockClass(a1,
a2, a3, a4, a5, a6, a7, a8) {
::testing::Mock::FailUninterestingCalls(
- internal::implicit_cast<MockClass*>(this));
+ internal::ImplicitCast_<MockClass*>(this));
}
template <typename A1, typename A2, typename A3, typename A4, typename A5,
@@ -233,7 +233,7 @@ class StrictMock : public MockClass {
const A5& a5, const A6& a6, const A7& a7, const A8& a8,
const A9& a9) : MockClass(a1, a2, a3, a4, a5, a6, a7, a8, a9) {
::testing::Mock::FailUninterestingCalls(
- internal::implicit_cast<MockClass*>(this));
+ internal::ImplicitCast_<MockClass*>(this));
}
template <typename A1, typename A2, typename A3, typename A4, typename A5,
@@ -242,12 +242,12 @@ class StrictMock : public MockClass {
const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9,
const A10& a10) : MockClass(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) {
::testing::Mock::FailUninterestingCalls(
- internal::implicit_cast<MockClass*>(this));
+ internal::ImplicitCast_<MockClass*>(this));
}
virtual ~StrictMock() {
::testing::Mock::UnregisterCallReaction(
- internal::implicit_cast<MockClass*>(this));
+ internal::ImplicitCast_<MockClass*>(this));
}
private:
diff --git a/testing/gmock/include/gmock/gmock-generated-nice-strict.h.pump b/testing/gmock/include/gmock/gmock-generated-nice-strict.h.pump
index 96371f5..b7964db 100644
--- a/testing/gmock/include/gmock/gmock-generated-nice-strict.h.pump
+++ b/testing/gmock/include/gmock/gmock-generated-nice-strict.h.pump
@@ -62,8 +62,8 @@ $var n = 10 $$ The maximum arity we support.
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_
#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_
-#include <gmock/gmock-spec-builders.h>
-#include <gmock/internal/gmock-port.h>
+#include "gmock/gmock-spec-builders.h"
+#include "gmock/internal/gmock-port.h"
namespace testing {
@@ -74,7 +74,7 @@ class NiceMock : public MockClass {
// we have to avoid a possible clash with members of MockClass.
NiceMock() {
::testing::Mock::AllowUninterestingCalls(
- internal::implicit_cast<MockClass*>(this));
+ internal::ImplicitCast_<MockClass*>(this));
}
// C++ doesn't (yet) allow inheritance of constructors, so we have
@@ -82,7 +82,7 @@ class NiceMock : public MockClass {
template <typename A1>
explicit NiceMock(const A1& a1) : MockClass(a1) {
::testing::Mock::AllowUninterestingCalls(
- internal::implicit_cast<MockClass*>(this));
+ internal::ImplicitCast_<MockClass*>(this));
}
$range i 2..n
@@ -91,14 +91,14 @@ $range j 1..i
template <$for j, [[typename A$j]]>
NiceMock($for j, [[const A$j& a$j]]) : MockClass($for j, [[a$j]]) {
::testing::Mock::AllowUninterestingCalls(
- internal::implicit_cast<MockClass*>(this));
+ internal::ImplicitCast_<MockClass*>(this));
}
]]
virtual ~NiceMock() {
::testing::Mock::UnregisterCallReaction(
- internal::implicit_cast<MockClass*>(this));
+ internal::ImplicitCast_<MockClass*>(this));
}
private:
@@ -112,13 +112,13 @@ class StrictMock : public MockClass {
// we have to avoid a possible clash with members of MockClass.
StrictMock() {
::testing::Mock::FailUninterestingCalls(
- internal::implicit_cast<MockClass*>(this));
+ internal::ImplicitCast_<MockClass*>(this));
}
template <typename A1>
explicit StrictMock(const A1& a1) : MockClass(a1) {
::testing::Mock::FailUninterestingCalls(
- internal::implicit_cast<MockClass*>(this));
+ internal::ImplicitCast_<MockClass*>(this));
}
$for i [[
@@ -126,14 +126,14 @@ $range j 1..i
template <$for j, [[typename A$j]]>
StrictMock($for j, [[const A$j& a$j]]) : MockClass($for j, [[a$j]]) {
::testing::Mock::FailUninterestingCalls(
- internal::implicit_cast<MockClass*>(this));
+ internal::ImplicitCast_<MockClass*>(this));
}
]]
virtual ~StrictMock() {
::testing::Mock::UnregisterCallReaction(
- internal::implicit_cast<MockClass*>(this));
+ internal::ImplicitCast_<MockClass*>(this));
}
private:
diff --git a/testing/gmock/include/gmock/gmock-matchers.h b/testing/gmock/include/gmock/gmock-matchers.h
index 2a42bf9..86c3db7 100644
--- a/testing/gmock/include/gmock/gmock-matchers.h
+++ b/testing/gmock/include/gmock/gmock-matchers.h
@@ -46,9 +46,9 @@
#include <utility>
#include <vector>
-#include <gmock/internal/gmock-internal-utils.h>
-#include <gmock/internal/gmock-port.h>
-#include <gtest/gtest.h>
+#include "gmock/internal/gmock-internal-utils.h"
+#include "gmock/internal/gmock-port.h"
+#include "gtest/gtest.h"
namespace testing {
@@ -250,8 +250,9 @@ class MatcherBase {
template <typename T>
class Matcher : public internal::MatcherBase<T> {
public:
- // Constructs a null matcher. Needed for storing Matcher objects in
- // STL containers.
+ // Constructs a null matcher. Needed for storing Matcher objects in STL
+ // containers. A default-constructed matcher is not yet initialized. You
+ // cannot use it until a valid value has been assigned to it.
Matcher() {}
// Constructs a matcher from its implementation.
@@ -461,6 +462,16 @@ inline void PrintIfNotEmpty(const internal::string& explanation,
}
}
+// Returns true if the given type name is easy to read by a human.
+// This is used to decide whether printing the type of a value might
+// be helpful.
+inline bool IsReadableTypeName(const string& type_name) {
+ // We consider a type name readable if it's short or doesn't contain
+ // a template or function type.
+ return (type_name.length() <= 20 ||
+ type_name.find_first_of("<(") == string::npos);
+}
+
// Matches the value against the given matcher, prints the value and explains
// the match result to the listener. Returns the match result.
// 'listener' must not be NULL.
@@ -479,6 +490,11 @@ bool MatchPrintAndExplain(Value& value, const Matcher<T>& matcher,
const bool match = matcher.MatchAndExplain(value, &inner_listener);
UniversalPrint(value, listener->stream());
+#if GTEST_HAS_RTTI
+ const string& type_name = GetTypeName<Value>();
+ if (IsReadableTypeName(type_name))
+ *listener->stream() << " (of type " << type_name << ")";
+#endif
PrintIfNotEmpty(inner_listener.str(), listener->stream());
return match;
@@ -2527,41 +2543,13 @@ class ElementsAreArrayMatcher {
GTEST_DISALLOW_ASSIGN_(ElementsAreArrayMatcher);
};
-// Constants denoting interpolations in a matcher description string.
-const int kTupleInterpolation = -1; // "%(*)s"
-const int kPercentInterpolation = -2; // "%%"
-const int kInvalidInterpolation = -3; // "%" followed by invalid text
-
-// Records the location and content of an interpolation.
-struct Interpolation {
- Interpolation(const char* start, const char* end, int param)
- : start_pos(start), end_pos(end), param_index(param) {}
-
- // Points to the start of the interpolation (the '%' character).
- const char* start_pos;
- // Points to the first character after the interpolation.
- const char* end_pos;
- // 0-based index of the interpolated matcher parameter;
- // kTupleInterpolation for "%(*)s"; kPercentInterpolation for "%%".
- int param_index;
-};
-
-typedef ::std::vector<Interpolation> Interpolations;
-
-// Parses a matcher description string and returns a vector of
-// interpolations that appear in the string; generates non-fatal
-// failures iff 'description' is an invalid matcher description.
-// 'param_names' is a NULL-terminated array of parameter names in the
-// order they appear in the MATCHER_P*() parameter list.
-Interpolations ValidateMatcherDescription(
- const char* param_names[], const char* description);
-
-// Returns the actual matcher description, given the matcher name,
-// user-supplied description template string, interpolations in the
-// string, and the printed values of the matcher parameters.
-string FormatMatcherDescription(
- const char* matcher_name, const char* description,
- const Interpolations& interp, const Strings& param_values);
+// Returns the description for a matcher defined using the MATCHER*()
+// macro where the user-supplied description string is "", if
+// 'negation' is false; otherwise returns the description of the
+// negation of the matcher. 'param_values' contains a list of strings
+// that are the print-out of the matcher's parameters.
+string FormatMatcherDescription(bool negation, const char* matcher_name,
+ const Strings& param_values);
} // namespace internal
@@ -2917,82 +2905,6 @@ inline internal::NotMatcher<InnerMatcher> Not(InnerMatcher m) {
return internal::NotMatcher<InnerMatcher>(m);
}
-// Creates a matcher that matches any value that matches all of the
-// given matchers.
-//
-// For now we only support up to 5 matchers. Support for more
-// matchers can be added as needed, or the user can use nested
-// AllOf()s.
-template <typename Matcher1, typename Matcher2>
-inline internal::BothOfMatcher<Matcher1, Matcher2>
-AllOf(Matcher1 m1, Matcher2 m2) {
- return internal::BothOfMatcher<Matcher1, Matcher2>(m1, m2);
-}
-
-template <typename Matcher1, typename Matcher2, typename Matcher3>
-inline internal::BothOfMatcher<Matcher1,
- internal::BothOfMatcher<Matcher2, Matcher3> >
-AllOf(Matcher1 m1, Matcher2 m2, Matcher3 m3) {
- return AllOf(m1, AllOf(m2, m3));
-}
-
-template <typename Matcher1, typename Matcher2, typename Matcher3,
- typename Matcher4>
-inline internal::BothOfMatcher<Matcher1,
- internal::BothOfMatcher<Matcher2,
- internal::BothOfMatcher<Matcher3, Matcher4> > >
-AllOf(Matcher1 m1, Matcher2 m2, Matcher3 m3, Matcher4 m4) {
- return AllOf(m1, AllOf(m2, m3, m4));
-}
-
-template <typename Matcher1, typename Matcher2, typename Matcher3,
- typename Matcher4, typename Matcher5>
-inline internal::BothOfMatcher<Matcher1,
- internal::BothOfMatcher<Matcher2,
- internal::BothOfMatcher<Matcher3,
- internal::BothOfMatcher<Matcher4, Matcher5> > > >
-AllOf(Matcher1 m1, Matcher2 m2, Matcher3 m3, Matcher4 m4, Matcher5 m5) {
- return AllOf(m1, AllOf(m2, m3, m4, m5));
-}
-
-// Creates a matcher that matches any value that matches at least one
-// of the given matchers.
-//
-// For now we only support up to 5 matchers. Support for more
-// matchers can be added as needed, or the user can use nested
-// AnyOf()s.
-template <typename Matcher1, typename Matcher2>
-inline internal::EitherOfMatcher<Matcher1, Matcher2>
-AnyOf(Matcher1 m1, Matcher2 m2) {
- return internal::EitherOfMatcher<Matcher1, Matcher2>(m1, m2);
-}
-
-template <typename Matcher1, typename Matcher2, typename Matcher3>
-inline internal::EitherOfMatcher<Matcher1,
- internal::EitherOfMatcher<Matcher2, Matcher3> >
-AnyOf(Matcher1 m1, Matcher2 m2, Matcher3 m3) {
- return AnyOf(m1, AnyOf(m2, m3));
-}
-
-template <typename Matcher1, typename Matcher2, typename Matcher3,
- typename Matcher4>
-inline internal::EitherOfMatcher<Matcher1,
- internal::EitherOfMatcher<Matcher2,
- internal::EitherOfMatcher<Matcher3, Matcher4> > >
-AnyOf(Matcher1 m1, Matcher2 m2, Matcher3 m3, Matcher4 m4) {
- return AnyOf(m1, AnyOf(m2, m3, m4));
-}
-
-template <typename Matcher1, typename Matcher2, typename Matcher3,
- typename Matcher4, typename Matcher5>
-inline internal::EitherOfMatcher<Matcher1,
- internal::EitherOfMatcher<Matcher2,
- internal::EitherOfMatcher<Matcher3,
- internal::EitherOfMatcher<Matcher4, Matcher5> > > >
-AnyOf(Matcher1 m1, Matcher2 m2, Matcher3 m3, Matcher4 m4, Matcher5 m5) {
- return AnyOf(m1, AnyOf(m2, m3, m4, m5));
-}
-
// Returns a matcher that matches anything that satisfies the given
// predicate. The predicate can be any unary function or functor
// whose return type can be implicitly converted to bool.
diff --git a/testing/gmock/include/gmock/gmock-more-actions.h b/testing/gmock/include/gmock/gmock-more-actions.h
index 6d686cd..a547a64 100644
--- a/testing/gmock/include/gmock/gmock-more-actions.h
+++ b/testing/gmock/include/gmock/gmock-more-actions.h
@@ -36,7 +36,9 @@
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_
#define GMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_
-#include <gmock/gmock-generated-actions.h>
+#include <algorithm>
+
+#include "gmock/gmock-generated-actions.h"
namespace testing {
namespace internal {
@@ -153,6 +155,14 @@ ACTION_TEMPLATE(SaveArg,
*pointer = ::std::tr1::get<k>(args);
}
+// Action SaveArgPointee<k>(pointer) saves the value pointed to
+// by the k-th (0-based) argument of the mock function to *pointer.
+ACTION_TEMPLATE(SaveArgPointee,
+ HAS_1_TEMPLATE_PARAMS(int, k),
+ AND_1_VALUE_PARAMS(pointer)) {
+ *pointer = *::std::tr1::get<k>(args);
+}
+
// Action SetArgReferee<k>(value) assigns 'value' to the variable
// referenced by the k-th (0-based) argument of the mock function.
ACTION_TEMPLATE(SetArgReferee,
@@ -195,6 +205,9 @@ ACTION_TEMPLATE(DeleteArg,
delete ::std::tr1::get<k>(args);
}
+// This action returns the value pointed to by 'pointer'.
+ACTION_P(ReturnPointee, pointer) { return *pointer; }
+
// Action Throw(exception) can be used in a mock function of any type
// to throw the given exception. Any copyable value can be thrown.
#if GTEST_HAS_EXCEPTIONS
diff --git a/testing/gmock/include/gmock/gmock-spec-builders.h b/testing/gmock/include/gmock/gmock-spec-builders.h
index 7038c2e..9e18508 100644
--- a/testing/gmock/include/gmock/gmock-spec-builders.h
+++ b/testing/gmock/include/gmock/gmock-spec-builders.h
@@ -66,12 +66,12 @@
#include <string>
#include <vector>
-#include <gmock/gmock-actions.h>
-#include <gmock/gmock-cardinalities.h>
-#include <gmock/gmock-matchers.h>
-#include <gmock/internal/gmock-internal-utils.h>
-#include <gmock/internal/gmock-port.h>
-#include <gtest/gtest.h>
+#include "gmock/gmock-actions.h"
+#include "gmock/gmock-cardinalities.h"
+#include "gmock/gmock-matchers.h"
+#include "gmock/internal/gmock-internal-utils.h"
+#include "gmock/internal/gmock-port.h"
+#include "gtest/gtest.h"
namespace testing {
@@ -113,53 +113,190 @@ template <typename F> class FunctionMockerBase;
// calls to ensure the integrity of the mock objects' states.
GTEST_DECLARE_STATIC_MUTEX_(g_gmock_mutex);
+// Untyped base class for ActionResultHolder<R>.
+class UntypedActionResultHolderBase;
+
// Abstract base class of FunctionMockerBase. This is the
// type-agnostic part of the function mocker interface. Its pure
// virtual methods are implemented by FunctionMockerBase.
class UntypedFunctionMockerBase {
public:
- virtual ~UntypedFunctionMockerBase() {}
+ UntypedFunctionMockerBase();
+ virtual ~UntypedFunctionMockerBase();
// Verifies that all expectations on this mock function have been
// satisfied. Reports one or more Google Test non-fatal failures
// and returns false if not.
// L >= g_gmock_mutex
- virtual bool VerifyAndClearExpectationsLocked() = 0;
+ bool VerifyAndClearExpectationsLocked();
// Clears the ON_CALL()s set on this mock function.
// L >= g_gmock_mutex
virtual void ClearDefaultActionsLocked() = 0;
+
+ // In all of the following Untyped* functions, it's the caller's
+ // responsibility to guarantee the correctness of the arguments'
+ // types.
+
+ // Performs the default action with the given arguments and returns
+ // the action's result. The call description string will be used in
+ // the error message to describe the call in the case the default
+ // action fails.
+ // L = *
+ virtual UntypedActionResultHolderBase* UntypedPerformDefaultAction(
+ const void* untyped_args,
+ const string& call_description) const = 0;
+
+ // Performs the given action with the given arguments and returns
+ // the action's result.
+ // L = *
+ virtual UntypedActionResultHolderBase* UntypedPerformAction(
+ const void* untyped_action,
+ const void* untyped_args) const = 0;
+
+ // Writes a message that the call is uninteresting (i.e. neither
+ // explicitly expected nor explicitly unexpected) to the given
+ // ostream.
+ // L < g_gmock_mutex
+ virtual void UntypedDescribeUninterestingCall(const void* untyped_args,
+ ::std::ostream* os) const = 0;
+
+ // Returns the expectation that matches the given function arguments
+ // (or NULL is there's no match); when a match is found,
+ // untyped_action is set to point to the action that should be
+ // performed (or NULL if the action is "do default"), and
+ // is_excessive is modified to indicate whether the call exceeds the
+ // expected number.
+ // L < g_gmock_mutex
+ virtual const ExpectationBase* UntypedFindMatchingExpectation(
+ const void* untyped_args,
+ const void** untyped_action, bool* is_excessive,
+ ::std::ostream* what, ::std::ostream* why) = 0;
+
+ // Prints the given function arguments to the ostream.
+ virtual void UntypedPrintArgs(const void* untyped_args,
+ ::std::ostream* os) const = 0;
+
+ // Sets the mock object this mock method belongs to, and registers
+ // this information in the global mock registry. Will be called
+ // whenever an EXPECT_CALL() or ON_CALL() is executed on this mock
+ // method.
+ // TODO(wan@google.com): rename to SetAndRegisterOwner().
+ // L < g_gmock_mutex
+ void RegisterOwner(const void* mock_obj);
+
+ // Sets the mock object this mock method belongs to, and sets the
+ // name of the mock function. Will be called upon each invocation
+ // of this mock function.
+ // L < g_gmock_mutex
+ void SetOwnerAndName(const void* mock_obj, const char* name);
+
+ // Returns the mock object this mock method belongs to. Must be
+ // called after RegisterOwner() or SetOwnerAndName() has been
+ // called.
+ // L < g_gmock_mutex
+ const void* MockObject() const;
+
+ // Returns the name of this mock method. Must be called after
+ // SetOwnerAndName() has been called.
+ // L < g_gmock_mutex
+ const char* Name() const;
+
+ // Returns the result of invoking this mock function with the given
+ // arguments. This function can be safely called from multiple
+ // threads concurrently. The caller is responsible for deleting the
+ // result.
+ // L < g_gmock_mutex
+ const UntypedActionResultHolderBase* UntypedInvokeWith(
+ const void* untyped_args);
+
+ protected:
+ typedef std::vector<const void*> UntypedOnCallSpecs;
+
+ typedef std::vector<internal::linked_ptr<ExpectationBase> >
+ UntypedExpectations;
+
+ // Returns an Expectation object that references and co-owns exp,
+ // which must be an expectation on this mock function.
+ Expectation GetHandleOf(ExpectationBase* exp);
+
+ // Address of the mock object this mock method belongs to. Only
+ // valid after this mock method has been called or
+ // ON_CALL/EXPECT_CALL has been invoked on it.
+ const void* mock_obj_; // Protected by g_gmock_mutex.
+
+ // Name of the function being mocked. Only valid after this mock
+ // method has been called.
+ const char* name_; // Protected by g_gmock_mutex.
+
+ // All default action specs for this function mocker.
+ UntypedOnCallSpecs untyped_on_call_specs_;
+
+ // All expectations for this function mocker.
+ UntypedExpectations untyped_expectations_;
}; // class UntypedFunctionMockerBase
-// This template class implements a default action spec (i.e. an
-// ON_CALL() statement).
+// Untyped base class for OnCallSpec<F>.
+class UntypedOnCallSpecBase {
+ public:
+ // The arguments are the location of the ON_CALL() statement.
+ UntypedOnCallSpecBase(const char* a_file, int a_line)
+ : file_(a_file), line_(a_line), last_clause_(kNone) {}
+
+ // Where in the source file was the default action spec defined?
+ const char* file() const { return file_; }
+ int line() const { return line_; }
+
+ protected:
+ // Gives each clause in the ON_CALL() statement a name.
+ enum Clause {
+ // Do not change the order of the enum members! The run-time
+ // syntax checking relies on it.
+ kNone,
+ kWith,
+ kWillByDefault,
+ };
+
+ // Asserts that the ON_CALL() statement has a certain property.
+ void AssertSpecProperty(bool property, const string& failure_message) const {
+ Assert(property, file_, line_, failure_message);
+ }
+
+ // Expects that the ON_CALL() statement has a certain property.
+ void ExpectSpecProperty(bool property, const string& failure_message) const {
+ Expect(property, file_, line_, failure_message);
+ }
+
+ const char* file_;
+ int line_;
+
+ // The last clause in the ON_CALL() statement as seen so far.
+ // Initially kNone and changes as the statement is parsed.
+ Clause last_clause_;
+}; // class UntypedOnCallSpecBase
+
+// This template class implements an ON_CALL spec.
template <typename F>
-class DefaultActionSpec {
+class OnCallSpec : public UntypedOnCallSpecBase {
public:
typedef typename Function<F>::ArgumentTuple ArgumentTuple;
typedef typename Function<F>::ArgumentMatcherTuple ArgumentMatcherTuple;
- // Constructs a DefaultActionSpec object from the information inside
+ // Constructs an OnCallSpec object from the information inside
// the parenthesis of an ON_CALL() statement.
- DefaultActionSpec(const char* a_file, int a_line,
- const ArgumentMatcherTuple& matchers)
- : file_(a_file),
- line_(a_line),
+ OnCallSpec(const char* a_file, int a_line,
+ const ArgumentMatcherTuple& matchers)
+ : UntypedOnCallSpecBase(a_file, a_line),
matchers_(matchers),
// By default, extra_matcher_ should match anything. However,
// we cannot initialize it with _ as that triggers a compiler
// bug in Symbian's C++ compiler (cannot decide between two
// overloaded constructors of Matcher<const ArgumentTuple&>).
- extra_matcher_(A<const ArgumentTuple&>()),
- last_clause_(kNone) {
+ extra_matcher_(A<const ArgumentTuple&>()) {
}
- // Where in the source file was the default action spec defined?
- const char* file() const { return file_; }
- int line() const { return line_; }
-
// Implements the .With() clause.
- DefaultActionSpec& With(const Matcher<const ArgumentTuple&>& m) {
+ OnCallSpec& With(const Matcher<const ArgumentTuple&>& m) {
// Makes sure this is called at most once.
ExpectSpecProperty(last_clause_ < kWith,
".With() cannot appear "
@@ -171,7 +308,7 @@ class DefaultActionSpec {
}
// Implements the .WillByDefault() clause.
- DefaultActionSpec& WillByDefault(const Action<F>& action) {
+ OnCallSpec& WillByDefault(const Action<F>& action) {
ExpectSpecProperty(last_clause_ < kWillByDefault,
".WillByDefault() must appear "
"exactly once in an ON_CALL().");
@@ -197,25 +334,6 @@ class DefaultActionSpec {
}
private:
- // Gives each clause in the ON_CALL() statement a name.
- enum Clause {
- // Do not change the order of the enum members! The run-time
- // syntax checking relies on it.
- kNone,
- kWith,
- kWillByDefault,
- };
-
- // Asserts that the ON_CALL() statement has a certain property.
- void AssertSpecProperty(bool property, const string& failure_message) const {
- Assert(property, file_, line_, failure_message);
- }
-
- // Expects that the ON_CALL() statement has a certain property.
- void ExpectSpecProperty(bool property, const string& failure_message) const {
- Expect(property, file_, line_, failure_message);
- }
-
// The information in statement
//
// ON_CALL(mock_object, Method(matchers))
@@ -229,16 +347,10 @@ class DefaultActionSpec {
// matchers => matchers_
// multi-argument-matcher => extra_matcher_
// action => action_
- const char* file_;
- int line_;
ArgumentMatcherTuple matchers_;
Matcher<const ArgumentTuple&> extra_matcher_;
Action<F> action_;
-
- // The last clause in the ON_CALL() statement as seen so far.
- // Initially kNone and changes as the statement is parsed.
- Clause last_clause_;
-}; // class DefaultActionSpec
+}; // class OnCallSpec
// Possible reactions on uninteresting calls. TODO(wan@google.com):
// rename the enum values to the kFoo style.
@@ -269,6 +381,8 @@ class Mock {
// verification was successful.
static bool VerifyAndClear(void* mock_obj);
private:
+ friend class internal::UntypedFunctionMockerBase;
+
// Needed for a function mocker to register itself (so that we know
// how to clear a mock object).
template <typename F>
@@ -389,6 +503,7 @@ class Expectation {
friend class ExpectationSet;
friend class Sequence;
friend class ::testing::internal::ExpectationBase;
+ friend class ::testing::internal::UntypedFunctionMockerBase;
template <typename F>
friend class ::testing::internal::FunctionMockerBase;
@@ -537,7 +652,7 @@ class InSequence {
bool sequence_created_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(InSequence); // NOLINT
-} GMOCK_ATTRIBUTE_UNUSED_;
+} GTEST_ATTRIBUTE_UNUSED_;
namespace internal {
@@ -575,16 +690,21 @@ class ExpectationBase {
// Describes the source file location of this expectation.
void DescribeLocationTo(::std::ostream* os) const {
- *os << file() << ":" << line() << ": ";
+ *os << FormatFileLocation(file(), line()) << " ";
}
// Describes how many times a function call matching this
// expectation has occurred.
// L >= g_gmock_mutex
- virtual void DescribeCallCountTo(::std::ostream* os) const = 0;
+ void DescribeCallCountTo(::std::ostream* os) const;
+
+ // If this mock method has an extra matcher (i.e. .With(matcher)),
+ // describes it to the ostream.
+ virtual void MaybeDescribeExtraMatcherTo(::std::ostream* os) = 0;
protected:
friend class ::testing::Expectation;
+ friend class UntypedFunctionMockerBase;
enum Clause {
// Don't change the order of the enum members!
@@ -598,6 +718,8 @@ class ExpectationBase {
kRetiresOnSaturation,
};
+ typedef std::vector<const void*> UntypedActions;
+
// Returns an Expectation object that references and co-owns this
// expectation.
virtual Expectation GetHandle() = 0;
@@ -690,13 +812,22 @@ class ExpectationBase {
call_count_++;
}
- private:
+ // Checks the action count (i.e. the number of WillOnce() and
+ // WillRepeatedly() clauses) against the cardinality if this hasn't
+ // been done before. Prints a warning if there are too many or too
+ // few actions.
+ // L < mutex_
+ void CheckActionCountIfNotDone() const;
+
friend class ::testing::Sequence;
friend class ::testing::internal::ExpectationTester;
template <typename Function>
friend class TypedExpectation;
+ // Implements the .Times() clause.
+ void UntypedTimes(const Cardinality& a_cardinality);
+
// This group of fields are part of the spec and won't change after
// an EXPECT_CALL() statement finishes.
const char* file_; // The file that contains the expectation.
@@ -717,6 +848,13 @@ class ExpectationBase {
// and can change as the mock function is called.
int call_count_; // How many times this expectation has been invoked.
bool retired_; // True iff this expectation has retired.
+ UntypedActions untyped_actions_;
+ bool extra_matcher_specified_;
+ bool repeated_action_specified_; // True if a WillRepeatedly() was specified.
+ bool retires_on_saturation_;
+ Clause last_clause_;
+ mutable bool action_count_checked_; // Under mutex_.
+ mutable Mutex mutex_; // Protects action_count_checked_.
GTEST_DISALLOW_ASSIGN_(ExpectationBase);
}; // class ExpectationBase
@@ -735,22 +873,21 @@ class TypedExpectation : public ExpectationBase {
: ExpectationBase(a_file, a_line, a_source_text),
owner_(owner),
matchers_(m),
- extra_matcher_specified_(false),
// By default, extra_matcher_ should match anything. However,
// we cannot initialize it with _ as that triggers a compiler
// bug in Symbian's C++ compiler (cannot decide between two
// overloaded constructors of Matcher<const ArgumentTuple&>).
extra_matcher_(A<const ArgumentTuple&>()),
- repeated_action_specified_(false),
- repeated_action_(DoDefault()),
- retires_on_saturation_(false),
- last_clause_(kNone),
- action_count_checked_(false) {}
+ repeated_action_(DoDefault()) {}
virtual ~TypedExpectation() {
// Check the validity of the action count if it hasn't been done
// yet (for example, if the expectation was never used).
CheckActionCountIfNotDone();
+ for (UntypedActions::const_iterator it = untyped_actions_.begin();
+ it != untyped_actions_.end(); ++it) {
+ delete static_cast<const Action<F>*>(*it);
+ }
}
// Implements the .With() clause.
@@ -773,19 +910,7 @@ class TypedExpectation : public ExpectationBase {
// Implements the .Times() clause.
TypedExpectation& Times(const Cardinality& a_cardinality) {
- if (last_clause_ ==kTimes) {
- ExpectSpecProperty(false,
- ".Times() cannot appear "
- "more than once in an EXPECT_CALL().");
- } else {
- ExpectSpecProperty(last_clause_ < kTimes,
- ".Times() cannot appear after "
- ".InSequence(), .WillOnce(), .WillRepeatedly(), "
- "or .RetiresOnSaturation().");
- }
- last_clause_ = kTimes;
-
- ExpectationBase::SpecifyCardinality(a_cardinality);
+ ExpectationBase::UntypedTimes(a_cardinality);
return *this;
}
@@ -859,9 +984,9 @@ class TypedExpectation : public ExpectationBase {
".WillRepeatedly() or .RetiresOnSaturation().");
last_clause_ = kWillOnce;
- actions_.push_back(action);
+ untyped_actions_.push_back(new Action<F>(action));
if (!cardinality_specified()) {
- set_cardinality(Exactly(static_cast<int>(actions_.size())));
+ set_cardinality(Exactly(static_cast<int>(untyped_actions_.size())));
}
return *this;
}
@@ -882,7 +1007,7 @@ class TypedExpectation : public ExpectationBase {
repeated_action_ = action;
if (!cardinality_specified()) {
- set_cardinality(AtLeast(static_cast<int>(actions_.size())));
+ set_cardinality(AtLeast(static_cast<int>(untyped_actions_.size())));
}
// Now that no more action clauses can be specified, we check
@@ -916,38 +1041,12 @@ class TypedExpectation : public ExpectationBase {
return extra_matcher_;
}
- // Returns the sequence of actions specified by the .WillOnce() clause.
- const std::vector<Action<F> >& actions() const { return actions_; }
-
// Returns the action specified by the .WillRepeatedly() clause.
const Action<F>& repeated_action() const { return repeated_action_; }
- // Returns true iff the .RetiresOnSaturation() clause was specified.
- bool retires_on_saturation() const { return retires_on_saturation_; }
-
- // Describes how many times a function call matching this
- // expectation has occurred (implements
- // ExpectationBase::DescribeCallCountTo()).
- // L >= g_gmock_mutex
- virtual void DescribeCallCountTo(::std::ostream* os) const {
- g_gmock_mutex.AssertHeld();
-
- // Describes how many times the function is expected to be called.
- *os << " Expected: to be ";
- cardinality().DescribeTo(os);
- *os << "\n Actual: ";
- Cardinality::DescribeActualCallCountTo(call_count(), os);
-
- // Describes the state of the expectation (e.g. is it satisfied?
- // is it active?).
- *os << " - " << (IsOverSaturated() ? "over-saturated" :
- IsSaturated() ? "saturated" :
- IsSatisfied() ? "satisfied" : "unsatisfied")
- << " and "
- << (is_retired() ? "retired" : "active");
- }
-
- void MaybeDescribeExtraMatcherTo(::std::ostream* os) {
+ // If this mock method has an extra matcher (i.e. .With(matcher)),
+ // describes it to the ostream.
+ virtual void MaybeDescribeExtraMatcherTo(::std::ostream* os) {
if (extra_matcher_specified_) {
*os << " Expected args: ";
extra_matcher_.DescribeTo(os);
@@ -1044,7 +1143,7 @@ class TypedExpectation : public ExpectationBase {
"call_count() is <= 0 when GetCurrentAction() is "
"called - this should never happen.");
- const int action_count = static_cast<int>(actions().size());
+ const int action_count = static_cast<int>(untyped_actions_.size());
if (action_count > 0 && !repeated_action_specified_ &&
count > action_count) {
// If there is at least one WillOnce() and no WillRepeatedly(),
@@ -1059,7 +1158,9 @@ class TypedExpectation : public ExpectationBase {
Log(WARNING, ss.str(), 1);
}
- return count <= action_count ? actions()[count - 1] : repeated_action();
+ return count <= action_count ?
+ *static_cast<const Action<F>*>(untyped_actions_[count - 1]) :
+ repeated_action();
}
// Given the arguments of a mock function call, if the call will
@@ -1067,12 +1168,13 @@ class TypedExpectation : public ExpectationBase {
// otherwise, returns the next action in this expectation. Also
// describes *what* happened to 'what', and explains *why* Google
// Mock does it to 'why'. This method is not const as it calls
- // IncrementCallCount().
+ // IncrementCallCount(). A return value of NULL means the default
+ // action.
// L >= g_gmock_mutex
- Action<F> GetActionForArguments(const FunctionMockerBase<F>* mocker,
- const ArgumentTuple& args,
- ::std::ostream* what,
- ::std::ostream* why) {
+ const Action<F>* GetActionForArguments(const FunctionMockerBase<F>* mocker,
+ const ArgumentTuple& args,
+ ::std::ostream* what,
+ ::std::ostream* why) {
g_gmock_mutex.AssertHeld();
if (IsSaturated()) {
// We have an excessive call.
@@ -1081,92 +1183,30 @@ class TypedExpectation : public ExpectationBase {
mocker->DescribeDefaultActionTo(args, what);
DescribeCallCountTo(why);
- // TODO(wan): allow the user to control whether unexpected calls
- // should fail immediately or continue using a flag
- // --gmock_unexpected_calls_are_fatal.
- return DoDefault();
+ // TODO(wan@google.com): allow the user to control whether
+ // unexpected calls should fail immediately or continue using a
+ // flag --gmock_unexpected_calls_are_fatal.
+ return NULL;
}
IncrementCallCount();
RetireAllPreRequisites();
- if (retires_on_saturation() && IsSaturated()) {
+ if (retires_on_saturation_ && IsSaturated()) {
Retire();
}
// Must be done after IncrementCount()!
*what << "Mock function call matches " << source_text() <<"...\n";
- return GetCurrentAction(mocker, args);
- }
-
- // Checks the action count (i.e. the number of WillOnce() and
- // WillRepeatedly() clauses) against the cardinality if this hasn't
- // been done before. Prints a warning if there are too many or too
- // few actions.
- // L < mutex_
- void CheckActionCountIfNotDone() const {
- bool should_check = false;
- {
- MutexLock l(&mutex_);
- if (!action_count_checked_) {
- action_count_checked_ = true;
- should_check = true;
- }
- }
-
- if (should_check) {
- if (!cardinality_specified_) {
- // The cardinality was inferred - no need to check the action
- // count against it.
- return;
- }
-
- // The cardinality was explicitly specified.
- const int action_count = static_cast<int>(actions_.size());
- const int upper_bound = cardinality().ConservativeUpperBound();
- const int lower_bound = cardinality().ConservativeLowerBound();
- bool too_many; // True if there are too many actions, or false
- // if there are too few.
- if (action_count > upper_bound ||
- (action_count == upper_bound && repeated_action_specified_)) {
- too_many = true;
- } else if (0 < action_count && action_count < lower_bound &&
- !repeated_action_specified_) {
- too_many = false;
- } else {
- return;
- }
-
- ::std::stringstream ss;
- DescribeLocationTo(&ss);
- ss << "Too " << (too_many ? "many" : "few")
- << " actions specified in " << source_text() << "...\n"
- << "Expected to be ";
- cardinality().DescribeTo(&ss);
- ss << ", but has " << (too_many ? "" : "only ")
- << action_count << " WillOnce()"
- << (action_count == 1 ? "" : "s");
- if (repeated_action_specified_) {
- ss << " and a WillRepeatedly()";
- }
- ss << ".";
- Log(WARNING, ss.str(), -1); // -1 means "don't print stack trace".
- }
+ return &(GetCurrentAction(mocker, args));
}
// All the fields below won't change once the EXPECT_CALL()
// statement finishes.
FunctionMockerBase<F>* const owner_;
ArgumentMatcherTuple matchers_;
- bool extra_matcher_specified_;
Matcher<const ArgumentTuple&> extra_matcher_;
- std::vector<Action<F> > actions_;
- bool repeated_action_specified_; // True if a WillRepeatedly() was specified.
Action<F> repeated_action_;
- bool retires_on_saturation_;
- Clause last_clause_;
- mutable bool action_count_checked_; // Under mutex_.
- mutable Mutex mutex_; // Protects action_count_checked_.
GTEST_DISALLOW_COPY_AND_ASSIGN_(TypedExpectation);
}; // class TypedExpectation
@@ -1181,6 +1221,11 @@ class TypedExpectation : public ExpectationBase {
// template. To workaround this compiler bug, we define MockSpec in
// ::testing::internal and import it into ::testing.
+// Logs a message including file and line number information.
+void LogWithLocation(testing::internal::LogSeverity severity,
+ const char* file, int line,
+ const string& message);
+
template <typename F>
class MockSpec {
public:
@@ -1195,11 +1240,11 @@ class MockSpec {
// Adds a new default action spec to the function mocker and returns
// the newly created spec.
- internal::DefaultActionSpec<F>& InternalDefaultActionSetAt(
+ internal::OnCallSpec<F>& InternalDefaultActionSetAt(
const char* file, int line, const char* obj, const char* call) {
LogWithLocation(internal::INFO, file, line,
string("ON_CALL(") + obj + ", " + call + ") invoked");
- return function_mocker_->AddNewDefaultActionSpec(file, line, matchers_);
+ return function_mocker_->AddNewOnCallSpec(file, line, matchers_);
}
// Adds a new expectation spec to the function mocker and returns
@@ -1220,15 +1265,6 @@ class MockSpec {
matchers_ = matchers;
}
- // Logs a message including file and line number information.
- void LogWithLocation(testing::internal::LogSeverity severity,
- const char* file, int line,
- const string& message) {
- ::std::ostringstream s;
- s << file << ":" << line << ": " << message << ::std::endl;
- Log(severity, s.str(), 0);
- }
-
// The function mocker that owns this spec.
internal::FunctionMockerBase<F>* const function_mocker_;
// The argument matchers specified in the spec.
@@ -1253,42 +1289,58 @@ class MockSpec {
// copyable type or void (T doesn't need to be default-constructable).
// It hides the syntactic difference between void and other types, and
// is used to unify the code for invoking both void-returning and
-// non-void-returning mock functions. This generic definition is used
-// when T is not void.
+// non-void-returning mock functions.
+
+// Untyped base class for ActionResultHolder<T>.
+class UntypedActionResultHolderBase {
+ public:
+ virtual ~UntypedActionResultHolderBase() {}
+
+ // Prints the held value as an action's result to os.
+ virtual void PrintAsActionResult(::std::ostream* os) const = 0;
+};
+
+// This generic definition is used when T is not void.
template <typename T>
-class ActionResultHolder {
+class ActionResultHolder : public UntypedActionResultHolderBase {
public:
explicit ActionResultHolder(T a_value) : value_(a_value) {}
// The compiler-generated copy constructor and assignment operator
// are exactly what we need, so we don't need to define them.
- T value() const { return value_; }
+ // Returns the held value and deletes this object.
+ T GetValueAndDelete() const {
+ T retval(value_);
+ delete this;
+ return retval;
+ }
// Prints the held value as an action's result to os.
- void PrintAsActionResult(::std::ostream* os) const {
+ virtual void PrintAsActionResult(::std::ostream* os) const {
*os << "\n Returns: ";
// T may be a reference type, so we don't use UniversalPrint().
UniversalPrinter<T>::Print(value_, os);
}
// Performs the given mock function's default action and returns the
- // result in a ActionResultHolder.
- template <typename Function, typename Arguments>
- static ActionResultHolder PerformDefaultAction(
- const FunctionMockerBase<Function>* func_mocker,
- const Arguments& args,
+ // result in a new-ed ActionResultHolder.
+ template <typename F>
+ static ActionResultHolder* PerformDefaultAction(
+ const FunctionMockerBase<F>* func_mocker,
+ const typename Function<F>::ArgumentTuple& args,
const string& call_description) {
- return ActionResultHolder(
+ return new ActionResultHolder(
func_mocker->PerformDefaultAction(args, call_description));
}
- // Performs the given action and returns the result in a
+ // Performs the given action and returns the result in a new-ed
// ActionResultHolder.
- template <typename Function, typename Arguments>
- static ActionResultHolder PerformAction(const Action<Function>& action,
- const Arguments& args) {
- return ActionResultHolder(action.Perform(args));
+ template <typename F>
+ static ActionResultHolder*
+ PerformAction(const Action<F>& action,
+ const typename Function<F>::ArgumentTuple& args) {
+ return new ActionResultHolder(action.Perform(args));
}
private:
@@ -1300,26 +1352,29 @@ class ActionResultHolder {
// Specialization for T = void.
template <>
-class ActionResultHolder<void> {
+class ActionResultHolder<void> : public UntypedActionResultHolderBase {
public:
- ActionResultHolder() {}
- void value() const {}
- void PrintAsActionResult(::std::ostream* /* os */) const {}
-
- template <typename Function, typename Arguments>
- static ActionResultHolder PerformDefaultAction(
- const FunctionMockerBase<Function>* func_mocker,
- const Arguments& args,
+ void GetValueAndDelete() const { delete this; }
+
+ virtual void PrintAsActionResult(::std::ostream* /* os */) const {}
+
+ // Performs the given mock function's default action and returns NULL;
+ template <typename F>
+ static ActionResultHolder* PerformDefaultAction(
+ const FunctionMockerBase<F>* func_mocker,
+ const typename Function<F>::ArgumentTuple& args,
const string& call_description) {
func_mocker->PerformDefaultAction(args, call_description);
- return ActionResultHolder();
+ return NULL;
}
- template <typename Function, typename Arguments>
- static ActionResultHolder PerformAction(const Action<Function>& action,
- const Arguments& args) {
+ // Performs the given action and returns NULL.
+ template <typename F>
+ static ActionResultHolder* PerformAction(
+ const Action<F>& action,
+ const typename Function<F>::ArgumentTuple& args) {
action.Perform(args);
- return ActionResultHolder();
+ return NULL;
}
};
@@ -1333,7 +1388,7 @@ class FunctionMockerBase : public UntypedFunctionMockerBase {
typedef typename Function<F>::ArgumentTuple ArgumentTuple;
typedef typename Function<F>::ArgumentMatcherTuple ArgumentMatcherTuple;
- FunctionMockerBase() : mock_obj_(NULL), name_(""), current_spec_(this) {}
+ FunctionMockerBase() : current_spec_(this) {}
// The destructor verifies that all expectations on this mock
// function have been satisfied. If not, it will report Google Test
@@ -1343,19 +1398,20 @@ class FunctionMockerBase : public UntypedFunctionMockerBase {
MutexLock l(&g_gmock_mutex);
VerifyAndClearExpectationsLocked();
Mock::UnregisterLocked(this);
+ ClearDefaultActionsLocked();
}
// Returns the ON_CALL spec that matches this mock function with the
// given arguments; returns NULL if no matching ON_CALL is found.
// L = *
- const DefaultActionSpec<F>* FindDefaultActionSpec(
+ const OnCallSpec<F>* FindOnCallSpec(
const ArgumentTuple& args) const {
- for (typename std::vector<DefaultActionSpec<F> >::const_reverse_iterator it
- = default_actions_.rbegin();
- it != default_actions_.rend(); ++it) {
- const DefaultActionSpec<F>& spec = *it;
- if (spec.Matches(args))
- return &spec;
+ for (UntypedOnCallSpecs::const_reverse_iterator it
+ = untyped_on_call_specs_.rbegin();
+ it != untyped_on_call_specs_.rend(); ++it) {
+ const OnCallSpec<F>* spec = static_cast<const OnCallSpec<F>*>(*it);
+ if (spec->Matches(args))
+ return spec;
}
return NULL;
@@ -1368,7 +1424,8 @@ class FunctionMockerBase : public UntypedFunctionMockerBase {
// L = *
Result PerformDefaultAction(const ArgumentTuple& args,
const string& call_description) const {
- const DefaultActionSpec<F>* const spec = FindDefaultActionSpec(args);
+ const OnCallSpec<F>* const spec =
+ this->FindOnCallSpec(args);
if (spec != NULL) {
return spec->GetAction().Perform(args);
}
@@ -1378,91 +1435,70 @@ class FunctionMockerBase : public UntypedFunctionMockerBase {
return DefaultValue<Result>::Get();
}
- // Registers this function mocker and the mock object owning it;
- // returns a reference to the function mocker object. This is only
- // called by the ON_CALL() and EXPECT_CALL() macros.
- // L < g_gmock_mutex
- FunctionMocker<F>& RegisterOwner(const void* mock_obj) {
- {
- MutexLock l(&g_gmock_mutex);
- mock_obj_ = mock_obj;
- }
- Mock::Register(mock_obj, this);
- return *::testing::internal::down_cast<FunctionMocker<F>*>(this);
+ // Performs the default action with the given arguments and returns
+ // the action's result. The call description string will be used in
+ // the error message to describe the call in the case the default
+ // action fails. The caller is responsible for deleting the result.
+ // L = *
+ virtual UntypedActionResultHolderBase* UntypedPerformDefaultAction(
+ const void* untyped_args, // must point to an ArgumentTuple
+ const string& call_description) const {
+ const ArgumentTuple& args =
+ *static_cast<const ArgumentTuple*>(untyped_args);
+ return ResultHolder::PerformDefaultAction(this, args, call_description);
}
- // The following two functions are from UntypedFunctionMockerBase.
-
- // Verifies that all expectations on this mock function have been
- // satisfied. Reports one or more Google Test non-fatal failures
- // and returns false if not.
- // L >= g_gmock_mutex
- virtual bool VerifyAndClearExpectationsLocked();
-
- // Clears the ON_CALL()s set on this mock function.
+ // Performs the given action with the given arguments and returns
+ // the action's result. The caller is responsible for deleting the
+ // result.
+ // L = *
+ virtual UntypedActionResultHolderBase* UntypedPerformAction(
+ const void* untyped_action, const void* untyped_args) const {
+ // Make a copy of the action before performing it, in case the
+ // action deletes the mock object (and thus deletes itself).
+ const Action<F> action = *static_cast<const Action<F>*>(untyped_action);
+ const ArgumentTuple& args =
+ *static_cast<const ArgumentTuple*>(untyped_args);
+ return ResultHolder::PerformAction(action, args);
+ }
+
+ // Implements UntypedFunctionMockerBase::ClearDefaultActionsLocked():
+ // clears the ON_CALL()s set on this mock function.
// L >= g_gmock_mutex
virtual void ClearDefaultActionsLocked() {
g_gmock_mutex.AssertHeld();
- default_actions_.clear();
- }
-
- // Sets the name of the function being mocked. Will be called upon
- // each invocation of this mock function.
- // L < g_gmock_mutex
- void SetOwnerAndName(const void* mock_obj, const char* name) {
- // We protect name_ under g_gmock_mutex in case this mock function
- // is called from two threads concurrently.
- MutexLock l(&g_gmock_mutex);
- mock_obj_ = mock_obj;
- name_ = name;
- }
-
- // Returns the address of the mock object this method belongs to.
- // Must be called after SetOwnerAndName() has been called.
- // L < g_gmock_mutex
- const void* MockObject() const {
- const void* mock_obj;
- {
- // We protect mock_obj_ under g_gmock_mutex in case this mock
- // function is called from two threads concurrently.
- MutexLock l(&g_gmock_mutex);
- mock_obj = mock_obj_;
+ for (UntypedOnCallSpecs::const_iterator it =
+ untyped_on_call_specs_.begin();
+ it != untyped_on_call_specs_.end(); ++it) {
+ delete static_cast<const OnCallSpec<F>*>(*it);
}
- return mock_obj;
- }
-
- // Returns the name of the function being mocked. Must be called
- // after SetOwnerAndName() has been called.
- // L < g_gmock_mutex
- const char* Name() const {
- const char* name;
- {
- // We protect name_ under g_gmock_mutex in case this mock
- // function is called from two threads concurrently.
- MutexLock l(&g_gmock_mutex);
- name = name_;
- }
- return name;
+ untyped_on_call_specs_.clear();
}
protected:
template <typename Function>
friend class MockSpec;
+ typedef ActionResultHolder<Result> ResultHolder;
+
// Returns the result of invoking this mock function with the given
// arguments. This function can be safely called from multiple
// threads concurrently.
// L < g_gmock_mutex
- Result InvokeWith(const ArgumentTuple& args);
+ Result InvokeWith(const ArgumentTuple& args) {
+ return static_cast<const ResultHolder*>(
+ this->UntypedInvokeWith(&args))->GetValueAndDelete();
+ }
// Adds and returns a default action spec for this mock function.
// L < g_gmock_mutex
- DefaultActionSpec<F>& AddNewDefaultActionSpec(
+ OnCallSpec<F>& AddNewOnCallSpec(
const char* file, int line,
const ArgumentMatcherTuple& m) {
Mock::RegisterUseByOnCallOrExpectCall(MockObject(), file, line);
- default_actions_.push_back(DefaultActionSpec<F>(file, line, m));
- return default_actions_.back();
+ OnCallSpec<F>* const on_call_spec = new OnCallSpec<F>(file, line, m);
+ untyped_on_call_specs_.push_back(on_call_spec);
+ return *on_call_spec;
}
// Adds and returns an expectation spec for this mock function.
@@ -1473,14 +1509,15 @@ class FunctionMockerBase : public UntypedFunctionMockerBase {
const string& source_text,
const ArgumentMatcherTuple& m) {
Mock::RegisterUseByOnCallOrExpectCall(MockObject(), file, line);
- const linked_ptr<TypedExpectation<F> > expectation(
- new TypedExpectation<F>(this, file, line, source_text, m));
- expectations_.push_back(expectation);
+ TypedExpectation<F>* const expectation =
+ new TypedExpectation<F>(this, file, line, source_text, m);
+ const linked_ptr<ExpectationBase> untyped_expectation(expectation);
+ untyped_expectations_.push_back(untyped_expectation);
// Adds this expectation into the implicit sequence if there is one.
Sequence* const implicit_sequence = g_gmock_implicit_sequence.get();
if (implicit_sequence != NULL) {
- implicit_sequence->AddExpectation(Expectation(expectation));
+ implicit_sequence->AddExpectation(Expectation(untyped_expectation));
}
return *expectation;
@@ -1493,33 +1530,14 @@ class FunctionMockerBase : public UntypedFunctionMockerBase {
private:
template <typename Func> friend class TypedExpectation;
- typedef std::vector<internal::linked_ptr<TypedExpectation<F> > >
- TypedExpectations;
-
- // Returns an Expectation object that references and co-owns exp,
- // which must be an expectation on this mock function.
- Expectation GetHandleOf(TypedExpectation<F>* exp) {
- for (typename TypedExpectations::const_iterator it = expectations_.begin();
- it != expectations_.end(); ++it) {
- if (it->get() == exp) {
- return Expectation(*it);
- }
- }
-
- Assert(false, __FILE__, __LINE__, "Cannot find expectation.");
- return Expectation();
- // The above statement is just to make the code compile, and will
- // never be executed.
- }
-
- // Some utilities needed for implementing InvokeWith().
+ // Some utilities needed for implementing UntypedInvokeWith().
// Describes what default action will be performed for the given
// arguments.
// L = *
void DescribeDefaultActionTo(const ArgumentTuple& args,
::std::ostream* os) const {
- const DefaultActionSpec<F>* const spec = FindDefaultActionSpec(args);
+ const OnCallSpec<F>* const spec = FindOnCallSpec(args);
if (spec == NULL) {
*os << (internal::type_equals<Result, void>::value ?
@@ -1527,7 +1545,7 @@ class FunctionMockerBase : public UntypedFunctionMockerBase {
"returning default value.\n");
} else {
*os << "taking default action specified at:\n"
- << spec->file() << ":" << spec->line() << ":\n";
+ << FormatFileLocation(spec->file(), spec->line()) << "\n";
}
}
@@ -1535,14 +1553,23 @@ class FunctionMockerBase : public UntypedFunctionMockerBase {
// explicitly expected nor explicitly unexpected) to the given
// ostream.
// L < g_gmock_mutex
- void DescribeUninterestingCall(const ArgumentTuple& args,
- ::std::ostream* os) const {
+ virtual void UntypedDescribeUninterestingCall(const void* untyped_args,
+ ::std::ostream* os) const {
+ const ArgumentTuple& args =
+ *static_cast<const ArgumentTuple*>(untyped_args);
*os << "Uninteresting mock function call - ";
DescribeDefaultActionTo(args, os);
*os << " Function call: " << Name();
UniversalPrint(args, os);
}
+ // Returns the expectation that matches the given function arguments
+ // (or NULL is there's no match); when a match is found,
+ // untyped_action is set to point to the action that should be
+ // performed (or NULL if the action is "do default"), and
+ // is_excessive is modified to indicate whether the call exceeds the
+ // expected number.
+ //
// Critical section: We must find the matching expectation and the
// corresponding action that needs to be taken in an ATOMIC
// transaction. Otherwise another thread may call this mock
@@ -1553,23 +1580,36 @@ class FunctionMockerBase : public UntypedFunctionMockerBase {
// action does (it can invoke an arbitrary user function or even a
// mock function) and excessive locking could cause a dead lock.
// L < g_gmock_mutex
- bool FindMatchingExpectationAndAction(
- const ArgumentTuple& args, TypedExpectation<F>** exp, Action<F>* action,
- bool* is_excessive, ::std::ostream* what, ::std::ostream* why) {
+ virtual const ExpectationBase* UntypedFindMatchingExpectation(
+ const void* untyped_args,
+ const void** untyped_action, bool* is_excessive,
+ ::std::ostream* what, ::std::ostream* why) {
+ const ArgumentTuple& args =
+ *static_cast<const ArgumentTuple*>(untyped_args);
MutexLock l(&g_gmock_mutex);
- *exp = this->FindMatchingExpectationLocked(args);
- if (*exp == NULL) { // A match wasn't found.
- *action = DoDefault();
+ TypedExpectation<F>* exp = this->FindMatchingExpectationLocked(args);
+ if (exp == NULL) { // A match wasn't found.
this->FormatUnexpectedCallMessageLocked(args, what, why);
- return false;
+ return NULL;
}
// This line must be done before calling GetActionForArguments(),
// which will increment the call count for *exp and thus affect
// its saturation status.
- *is_excessive = (*exp)->IsSaturated();
- *action = (*exp)->GetActionForArguments(this, args, what, why);
- return true;
+ *is_excessive = exp->IsSaturated();
+ const Action<F>* action = exp->GetActionForArguments(this, args, what, why);
+ if (action != NULL && action->IsDoDefault())
+ action = NULL; // Normalize "do default" to NULL.
+ *untyped_action = action;
+ return exp;
+ }
+
+ // Prints the given function arguments to the ostream.
+ virtual void UntypedPrintArgs(const void* untyped_args,
+ ::std::ostream* os) const {
+ const ArgumentTuple& args =
+ *static_cast<const ArgumentTuple*>(untyped_args);
+ UniversalPrint(args, os);
}
// Returns the expectation that matches the arguments, or NULL if no
@@ -1578,10 +1618,11 @@ class FunctionMockerBase : public UntypedFunctionMockerBase {
TypedExpectation<F>* FindMatchingExpectationLocked(
const ArgumentTuple& args) const {
g_gmock_mutex.AssertHeld();
- for (typename TypedExpectations::const_reverse_iterator it =
- expectations_.rbegin();
- it != expectations_.rend(); ++it) {
- TypedExpectation<F>* const exp = it->get();
+ for (typename UntypedExpectations::const_reverse_iterator it =
+ untyped_expectations_.rbegin();
+ it != untyped_expectations_.rend(); ++it) {
+ TypedExpectation<F>* const exp =
+ static_cast<TypedExpectation<F>*>(it->get());
if (exp->ShouldHandleArguments(args)) {
return exp;
}
@@ -1606,41 +1647,29 @@ class FunctionMockerBase : public UntypedFunctionMockerBase {
void PrintTriedExpectationsLocked(const ArgumentTuple& args,
::std::ostream* why) const {
g_gmock_mutex.AssertHeld();
- const int count = static_cast<int>(expectations_.size());
+ const int count = static_cast<int>(untyped_expectations_.size());
*why << "Google Mock tried the following " << count << " "
<< (count == 1 ? "expectation, but it didn't match" :
"expectations, but none matched")
<< ":\n";
for (int i = 0; i < count; i++) {
+ TypedExpectation<F>* const expectation =
+ static_cast<TypedExpectation<F>*>(untyped_expectations_[i].get());
*why << "\n";
- expectations_[i]->DescribeLocationTo(why);
+ expectation->DescribeLocationTo(why);
if (count > 1) {
*why << "tried expectation #" << i << ": ";
}
- *why << expectations_[i]->source_text() << "...\n";
- expectations_[i]->ExplainMatchResultTo(args, why);
- expectations_[i]->DescribeCallCountTo(why);
+ *why << expectation->source_text() << "...\n";
+ expectation->ExplainMatchResultTo(args, why);
+ expectation->DescribeCallCountTo(why);
}
}
- // Address of the mock object this mock method belongs to. Only
- // valid after this mock method has been called or
- // ON_CALL/EXPECT_CALL has been invoked on it.
- const void* mock_obj_; // Protected by g_gmock_mutex.
-
- // Name of the function being mocked. Only valid after this mock
- // method has been called.
- const char* name_; // Protected by g_gmock_mutex.
-
// The current spec (either default action spec or expectation spec)
// being described on this function mocker.
MockSpec<F> current_spec_;
- // All default action specs for this function mocker.
- std::vector<DefaultActionSpec<F> > default_actions_;
- // All expectations for this function mocker.
- TypedExpectations expectations_;
-
// There is no generally useful and implementable semantics of
// copying a mock object, so copying a mock is usually a user error.
// Thus we disallow copying function mockers. If the user really
@@ -1666,144 +1695,11 @@ class FunctionMockerBase : public UntypedFunctionMockerBase {
// satisfied. Reports one or more Google Test non-fatal failures and
// returns false if not.
// L >= g_gmock_mutex
-template <typename F>
-bool FunctionMockerBase<F>::VerifyAndClearExpectationsLocked() {
- g_gmock_mutex.AssertHeld();
- bool expectations_met = true;
- for (typename TypedExpectations::const_iterator it = expectations_.begin();
- it != expectations_.end(); ++it) {
- TypedExpectation<F>* const exp = it->get();
-
- if (exp->IsOverSaturated()) {
- // There was an upper-bound violation. Since the error was
- // already reported when it occurred, there is no need to do
- // anything here.
- expectations_met = false;
- } else if (!exp->IsSatisfied()) {
- expectations_met = false;
- ::std::stringstream ss;
- ss << "Actual function call count doesn't match "
- << exp->source_text() << "...\n";
- // No need to show the source file location of the expectation
- // in the description, as the Expect() call that follows already
- // takes care of it.
- exp->MaybeDescribeExtraMatcherTo(&ss);
- exp->DescribeCallCountTo(&ss);
- Expect(false, exp->file(), exp->line(), ss.str());
- }
- }
- expectations_.clear();
- return expectations_met;
-}
// Reports an uninteresting call (whose description is in msg) in the
// manner specified by 'reaction'.
void ReportUninterestingCall(CallReaction reaction, const string& msg);
-// Calculates the result of invoking this mock function with the given
-// arguments, prints it, and returns it.
-// L < g_gmock_mutex
-template <typename F>
-typename Function<F>::Result FunctionMockerBase<F>::InvokeWith(
- const typename Function<F>::ArgumentTuple& args) {
- typedef ActionResultHolder<Result> ResultHolder;
-
- if (expectations_.size() == 0) {
- // No expectation is set on this mock method - we have an
- // uninteresting call.
-
- // We must get Google Mock's reaction on uninteresting calls
- // made on this mock object BEFORE performing the action,
- // because the action may DELETE the mock object and make the
- // following expression meaningless.
- const CallReaction reaction =
- Mock::GetReactionOnUninterestingCalls(MockObject());
-
- // True iff we need to print this call's arguments and return
- // value. This definition must be kept in sync with
- // the behavior of ReportUninterestingCall().
- const bool need_to_report_uninteresting_call =
- // If the user allows this uninteresting call, we print it
- // only when he wants informational messages.
- reaction == ALLOW ? LogIsVisible(INFO) :
- // If the user wants this to be a warning, we print it only
- // when he wants to see warnings.
- reaction == WARN ? LogIsVisible(WARNING) :
- // Otherwise, the user wants this to be an error, and we
- // should always print detailed information in the error.
- true;
-
- if (!need_to_report_uninteresting_call) {
- // Perform the action without printing the call information.
- return PerformDefaultAction(args, "");
- }
-
- // Warns about the uninteresting call.
- ::std::stringstream ss;
- DescribeUninterestingCall(args, &ss);
-
- // Calculates the function result.
- const ResultHolder result =
- ResultHolder::PerformDefaultAction(this, args, ss.str());
-
- // Prints the function result.
- result.PrintAsActionResult(&ss);
-
- ReportUninterestingCall(reaction, ss.str());
- return result.value();
- }
-
- bool is_excessive = false;
- ::std::stringstream ss;
- ::std::stringstream why;
- ::std::stringstream loc;
- Action<F> action;
- TypedExpectation<F>* exp;
-
- // The FindMatchingExpectationAndAction() function acquires and
- // releases g_gmock_mutex.
- const bool found = FindMatchingExpectationAndAction(
- args, &exp, &action, &is_excessive, &ss, &why);
-
- // True iff we need to print the call's arguments and return value.
- // This definition must be kept in sync with the uses of Expect()
- // and Log() in this function.
- const bool need_to_report_call = !found || is_excessive || LogIsVisible(INFO);
- if (!need_to_report_call) {
- // Perform the action without printing the call information.
- return action.IsDoDefault() ? PerformDefaultAction(args, "") :
- action.Perform(args);
- }
-
- ss << " Function call: " << Name();
- UniversalPrint(args, &ss);
-
- // In case the action deletes a piece of the expectation, we
- // generate the message beforehand.
- if (found && !is_excessive) {
- exp->DescribeLocationTo(&loc);
- }
-
- const ResultHolder result = action.IsDoDefault() ?
- ResultHolder::PerformDefaultAction(this, args, ss.str()) :
- ResultHolder::PerformAction(action, args);
- result.PrintAsActionResult(&ss);
- ss << "\n" << why.str();
-
- if (!found) {
- // No expectation matches this call - reports a failure.
- Expect(false, NULL, -1, ss.str());
- } else if (is_excessive) {
- // We had an upper-bound violation and the failure message is in ss.
- Expect(false, exp->file(), exp->line(), ss.str());
- } else {
- // We had an expected call and the matching expectation is
- // described in ss.
- Log(INFO, loc.str() + ss.str(), 2);
- }
- return result.value();
-}
-
} // namespace internal
// The style guide prohibits "using" statements in a namespace scope
diff --git a/testing/gmock/include/gmock/gmock.h b/testing/gmock/include/gmock/gmock.h
index e3d5fd8..ba9fa28 100644
--- a/testing/gmock/include/gmock/gmock.h
+++ b/testing/gmock/include/gmock/gmock.h
@@ -55,15 +55,15 @@
//
// where all clauses are optional and WillOnce() can be repeated.
-#include <gmock/gmock-actions.h>
-#include <gmock/gmock-cardinalities.h>
-#include <gmock/gmock-generated-actions.h>
-#include <gmock/gmock-generated-function-mockers.h>
-#include <gmock/gmock-generated-matchers.h>
-#include <gmock/gmock-more-actions.h>
-#include <gmock/gmock-generated-nice-strict.h>
-#include <gmock/gmock-matchers.h>
-#include <gmock/internal/gmock-internal-utils.h>
+#include "gmock/gmock-actions.h"
+#include "gmock/gmock-cardinalities.h"
+#include "gmock/gmock-generated-actions.h"
+#include "gmock/gmock-generated-function-mockers.h"
+#include "gmock/gmock-generated-matchers.h"
+#include "gmock/gmock-more-actions.h"
+#include "gmock/gmock-generated-nice-strict.h"
+#include "gmock/gmock-matchers.h"
+#include "gmock/internal/gmock-internal-utils.h"
namespace testing {
diff --git a/testing/gmock/include/gmock/internal/gmock-generated-internal-utils.h b/testing/gmock/include/gmock/internal/gmock-generated-internal-utils.h
index 6386b05..1b52dce 100644
--- a/testing/gmock/include/gmock/internal/gmock-generated-internal-utils.h
+++ b/testing/gmock/include/gmock/internal/gmock-generated-internal-utils.h
@@ -39,7 +39,7 @@
#ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_GENERATED_INTERNAL_UTILS_H_
#define GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_GENERATED_INTERNAL_UTILS_H_
-#include <gmock/internal/gmock-port.h>
+#include "gmock/internal/gmock-port.h"
namespace testing {
diff --git a/testing/gmock/include/gmock/internal/gmock-generated-internal-utils.h.pump b/testing/gmock/include/gmock/internal/gmock-generated-internal-utils.h.pump
index f3128b0..821e474 100644
--- a/testing/gmock/include/gmock/internal/gmock-generated-internal-utils.h.pump
+++ b/testing/gmock/include/gmock/internal/gmock-generated-internal-utils.h.pump
@@ -42,7 +42,7 @@ $var n = 10 $$ The maximum arity we support.
#ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_GENERATED_INTERNAL_UTILS_H_
#define GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_GENERATED_INTERNAL_UTILS_H_
-#include <gmock/internal/gmock-port.h>
+#include "gmock/internal/gmock-port.h"
namespace testing {
diff --git a/testing/gmock/include/gmock/internal/gmock-internal-utils.h b/testing/gmock/include/gmock/internal/gmock-internal-utils.h
index 69a2338..7aaf6de 100644
--- a/testing/gmock/include/gmock/internal/gmock-internal-utils.h
+++ b/testing/gmock/include/gmock/internal/gmock-internal-utils.h
@@ -42,20 +42,9 @@
#include <ostream> // NOLINT
#include <string>
-#include <gmock/internal/gmock-generated-internal-utils.h>
-#include <gmock/internal/gmock-port.h>
-#include <gtest/gtest.h>
-
-// Concatenates two pre-processor symbols; works for concatenating
-// built-in macros like __FILE__ and __LINE__.
-#define GMOCK_CONCAT_TOKEN_IMPL_(foo, bar) foo##bar
-#define GMOCK_CONCAT_TOKEN_(foo, bar) GMOCK_CONCAT_TOKEN_IMPL_(foo, bar)
-
-#ifdef __GNUC__
-#define GMOCK_ATTRIBUTE_UNUSED_ __attribute__ ((unused))
-#else
-#define GMOCK_ATTRIBUTE_UNUSED_
-#endif // __GNUC__
+#include "gmock/internal/gmock-generated-internal-utils.h"
+#include "gmock/internal/gmock-port.h"
+#include "gtest/gtest.h"
namespace testing {
namespace internal {
diff --git a/testing/gmock/include/gmock/internal/gmock-port.h b/testing/gmock/include/gmock/internal/gmock-port.h
index b644eb4..bb3f583 100644
--- a/testing/gmock/include/gmock/internal/gmock-port.h
+++ b/testing/gmock/include/gmock/internal/gmock-port.h
@@ -42,8 +42,8 @@
// Most of the types needed for porting Google Mock are also required
// for Google Test and are defined in gtest-port.h.
-#include <gtest/internal/gtest-linked_ptr.h>
-#include <gtest/internal/gtest-port.h>
+#include "gtest/internal/gtest-linked_ptr.h"
+#include "gtest/internal/gtest-port.h"
// To avoid conditional compilation everywhere, we make it
// gmock-port.h's responsibility to #include the header implementing
diff --git a/testing/gmock/msvc/gmock.sln b/testing/gmock/msvc/2005/gmock.sln
index f56dda6..b752f87 100644
--- a/testing/gmock/msvc/gmock.sln
+++ b/testing/gmock/msvc/2005/gmock.sln
@@ -5,12 +5,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gmock", "gmock.vcproj", "{3
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gmock_test", "gmock_test.vcproj", "{F10D22F8-AC7B-4213-8720-608E7D878CD2}"
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gmock_link_test", "gmock_link_test.vcproj", "{ED597847-A714-4327-B569-70029D2311F0}"
-EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gmock_main", "gmock_main.vcproj", "{E4EF614B-30DF-4954-8C53-580A0BF6B589}"
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gmock-spec-builders_test", "gmock-spec-builders_test.vcproj", "{46972604-5BE0-4493-BAE3-878DB825FDCB}"
-EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
@@ -25,18 +21,10 @@ Global
{F10D22F8-AC7B-4213-8720-608E7D878CD2}.Debug|Win32.Build.0 = Debug|Win32
{F10D22F8-AC7B-4213-8720-608E7D878CD2}.Release|Win32.ActiveCfg = Release|Win32
{F10D22F8-AC7B-4213-8720-608E7D878CD2}.Release|Win32.Build.0 = Release|Win32
- {ED597847-A714-4327-B569-70029D2311F0}.Debug|Win32.ActiveCfg = Debug|Win32
- {ED597847-A714-4327-B569-70029D2311F0}.Debug|Win32.Build.0 = Debug|Win32
- {ED597847-A714-4327-B569-70029D2311F0}.Release|Win32.ActiveCfg = Release|Win32
- {ED597847-A714-4327-B569-70029D2311F0}.Release|Win32.Build.0 = Release|Win32
{E4EF614B-30DF-4954-8C53-580A0BF6B589}.Debug|Win32.ActiveCfg = Debug|Win32
{E4EF614B-30DF-4954-8C53-580A0BF6B589}.Debug|Win32.Build.0 = Debug|Win32
{E4EF614B-30DF-4954-8C53-580A0BF6B589}.Release|Win32.ActiveCfg = Release|Win32
{E4EF614B-30DF-4954-8C53-580A0BF6B589}.Release|Win32.Build.0 = Release|Win32
- {46972604-5BE0-4493-BAE3-878DB825FDCB}.Debug|Win32.ActiveCfg = Debug|Win32
- {46972604-5BE0-4493-BAE3-878DB825FDCB}.Debug|Win32.Build.0 = Debug|Win32
- {46972604-5BE0-4493-BAE3-878DB825FDCB}.Release|Win32.ActiveCfg = Release|Win32
- {46972604-5BE0-4493-BAE3-878DB825FDCB}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/testing/gmock/msvc/gmock.vcproj b/testing/gmock/msvc/2005/gmock.vcproj
index b9036da..4bbfe98 100644
--- a/testing/gmock/msvc/gmock.vcproj
+++ b/testing/gmock/msvc/2005/gmock.vcproj
@@ -41,7 +41,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
- AdditionalIncludeDirectories="../include"
+ AdditionalIncludeDirectories="..\..\include;..\.."
PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
MinimalRebuild="true"
BasicRuntimeChecks="3"
@@ -105,7 +105,7 @@
/>
<Tool
Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="../include"
+ AdditionalIncludeDirectories="..\..\include;..\.."
PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
RuntimeLibrary="0"
UsePrecompiledHeader="0"
@@ -151,27 +151,7 @@
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
- RelativePath="..\src\gmock-cardinalities.cc"
- >
- </File>
- <File
- RelativePath="..\src\gmock-internal-utils.cc"
- >
- </File>
- <File
- RelativePath="..\src\gmock-matchers.cc"
- >
- </File>
- <File
- RelativePath="..\src\gmock-printers.cc"
- >
- </File>
- <File
- RelativePath="..\src\gmock-spec-builders.cc"
- >
- </File>
- <File
- RelativePath="..\src\gmock.cc"
+ RelativePath="..\..\src\gmock-all.cc"
>
</File>
<File
@@ -200,62 +180,10 @@
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
- <File
- RelativePath="..\include\gmock\gmock-actions.h"
- >
- </File>
- <File
- RelativePath="..\include\gmock\gmock-cardinalities.h"
- >
- </File>
- <File
- RelativePath="..\include\gmock\gmock-generated-actions.h"
- >
- </File>
- <File
- RelativePath="..\include\gmock\gmock-generated-function-mockers.h"
- >
- </File>
- <File
- RelativePath="..\include\gmock\gmock-generated-matchers.h"
- >
- </File>
- <File
- RelativePath="..\include\gmock\gmock-generated-nice-strict.h"
- >
- </File>
- <File
- RelativePath="..\include\gmock\gmock-matchers.h"
- >
- </File>
- <File
- RelativePath="..\include\gmock\gmock-printers.h"
- >
- </File>
- <File
- RelativePath="..\include\gmock\gmock-spec-builders.h"
- >
- </File>
- <File
- RelativePath="..\include\gmock\gmock.h"
- >
- </File>
</Filter>
<Filter
Name="Private Header Files"
>
- <File
- RelativePath="..\include\gmock\internal\gmock-generated-internal-utils.h"
- >
- </File>
- <File
- RelativePath="..\include\gmock\internal\gmock-internal-utils.h"
- >
- </File>
- <File
- RelativePath="..\include\gmock\internal\gmock-port.h"
- >
- </File>
</Filter>
</Files>
<Globals>
diff --git a/testing/gmock/msvc/gmock_config.vsprops b/testing/gmock/msvc/2005/gmock_config.vsprops
index a68c32e..8b65cfb 100644
--- a/testing/gmock/msvc/gmock_config.vsprops
+++ b/testing/gmock/msvc/2005/gmock_config.vsprops
@@ -10,6 +10,6 @@
/>
<UserMacro
Name="GTestDir"
- Value="../gtest"
+ Value="../../gtest"
/>
</VisualStudioPropertySheet>
diff --git a/testing/gmock/msvc/gmock_main.vcproj b/testing/gmock/msvc/2005/gmock_main.vcproj
index 8e0eccb..01505a9 100644
--- a/testing/gmock/msvc/gmock_main.vcproj
+++ b/testing/gmock/msvc/2005/gmock_main.vcproj
@@ -41,7 +41,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
- AdditionalIncludeDirectories="../include"
+ AdditionalIncludeDirectories="../../include"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
MinimalRebuild="true"
BasicRuntimeChecks="3"
@@ -105,7 +105,7 @@
/>
<Tool
Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="../include"
+ AdditionalIncludeDirectories="../../include"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
RuntimeLibrary="0"
UsePrecompiledHeader="0"
@@ -155,14 +155,14 @@
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
- RelativePath="..\src\gmock_main.cc"
+ RelativePath="..\..\src\gmock_main.cc"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="../include"
+ AdditionalIncludeDirectories="../../include"
/>
</FileConfiguration>
<FileConfiguration
@@ -170,7 +170,7 @@
>
<Tool
Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
+ AdditionalIncludeDirectories="../../include"
/>
</FileConfiguration>
</File>
diff --git a/testing/gmock/msvc/gmock_link_test.vcproj b/testing/gmock/msvc/2005/gmock_test.vcproj
index 3c1ee14..d1e01e7 100644
--- a/testing/gmock/msvc/gmock_link_test.vcproj
+++ b/testing/gmock/msvc/2005/gmock_test.vcproj
@@ -2,9 +2,9 @@
<VisualStudioProject
ProjectType="Visual C++"
Version="8.00"
- Name="gmock_link_test"
- ProjectGUID="{ED597847-A714-4327-B569-70029D2311F0}"
- RootNamespace="gmock_link_test"
+ Name="gmock_test"
+ ProjectGUID="{F10D22F8-AC7B-4213-8720-608E7D878CD2}"
+ RootNamespace="gmock_test"
Keyword="Win32Proj"
>
<Platforms>
@@ -40,8 +40,9 @@
/>
<Tool
Name="VCCLCompilerTool"
+ AdditionalOptions="/bigobj"
Optimization="0"
- AdditionalIncludeDirectories="../include;.."
+ AdditionalIncludeDirectories="..\..\include;..\.."
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
MinimalRebuild="true"
BasicRuntimeChecks="3"
@@ -118,7 +119,8 @@
/>
<Tool
Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="../include;.."
+ AdditionalOptions="/bigobj"
+ AdditionalIncludeDirectories="..\..\include;..\.."
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
RuntimeLibrary="0"
UsePrecompiledHeader="0"
@@ -183,11 +185,7 @@
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
- RelativePath="..\test\gmock_link2_test.cc"
- >
- </File>
- <File
- RelativePath="..\test\gmock_link_test.cc"
+ RelativePath="..\..\test\gmock_all_test.cc"
>
</File>
</Filter>
diff --git a/testing/gmock/msvc/2010/gmock.sln b/testing/gmock/msvc/2010/gmock.sln
new file mode 100644
index 0000000..d949656
--- /dev/null
+++ b/testing/gmock/msvc/2010/gmock.sln
@@ -0,0 +1,32 @@
+
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual C++ Express 2010
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gmock", "gmock.vcxproj", "{34681F0D-CE45-415D-B5F2-5C662DFE3BD5}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gmock_test", "gmock_test.vcxproj", "{F10D22F8-AC7B-4213-8720-608E7D878CD2}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gmock_main", "gmock_main.vcxproj", "{E4EF614B-30DF-4954-8C53-580A0BF6B589}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Release|Win32 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {34681F0D-CE45-415D-B5F2-5C662DFE3BD5}.Debug|Win32.ActiveCfg = Debug|Win32
+ {34681F0D-CE45-415D-B5F2-5C662DFE3BD5}.Debug|Win32.Build.0 = Debug|Win32
+ {34681F0D-CE45-415D-B5F2-5C662DFE3BD5}.Release|Win32.ActiveCfg = Release|Win32
+ {34681F0D-CE45-415D-B5F2-5C662DFE3BD5}.Release|Win32.Build.0 = Release|Win32
+ {F10D22F8-AC7B-4213-8720-608E7D878CD2}.Debug|Win32.ActiveCfg = Debug|Win32
+ {F10D22F8-AC7B-4213-8720-608E7D878CD2}.Debug|Win32.Build.0 = Debug|Win32
+ {F10D22F8-AC7B-4213-8720-608E7D878CD2}.Release|Win32.ActiveCfg = Release|Win32
+ {F10D22F8-AC7B-4213-8720-608E7D878CD2}.Release|Win32.Build.0 = Release|Win32
+ {E4EF614B-30DF-4954-8C53-580A0BF6B589}.Debug|Win32.ActiveCfg = Debug|Win32
+ {E4EF614B-30DF-4954-8C53-580A0BF6B589}.Debug|Win32.Build.0 = Debug|Win32
+ {E4EF614B-30DF-4954-8C53-580A0BF6B589}.Release|Win32.ActiveCfg = Release|Win32
+ {E4EF614B-30DF-4954-8C53-580A0BF6B589}.Release|Win32.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/testing/gmock/msvc/2010/gmock.vcxproj b/testing/gmock/msvc/2010/gmock.vcxproj
new file mode 100644
index 0000000..21a85ef
--- /dev/null
+++ b/testing/gmock/msvc/2010/gmock.vcxproj
@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{34681F0D-CE45-415D-B5F2-5C662DFE3BD5}</ProjectGuid>
+ <RootNamespace>gmock</RootNamespace>
+ <Keyword>Win32Proj</Keyword>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <CharacterSet>Unicode</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="gmock_config.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="gmock_config.props" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(OutDir)$(ProjectName)\</IntDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(OutDir)$(ProjectName)\</IntDir>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\include;..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <AdditionalIncludeDirectories>..\..\include;..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\src\gmock-all.cc" />
+ <ClCompile Include="$(GTestDir)\src\gtest-all.cc">
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(GTestDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(GTestDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ClCompile>
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project>
diff --git a/testing/gmock/msvc/2010/gmock_config.props b/testing/gmock/msvc/2010/gmock_config.props
new file mode 100644
index 0000000..bd497f1
--- /dev/null
+++ b/testing/gmock/msvc/2010/gmock_config.props
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup Label="UserMacros">
+ <GTestDir>../../gtest</GTestDir>
+ </PropertyGroup>
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
+ </PropertyGroup>
+ <ItemDefinitionGroup>
+ <ClCompile>
+ <AdditionalIncludeDirectories>$(GTestDir)/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <BuildMacro Include="GTestDir">
+ <Value>$(GTestDir)</Value>
+ </BuildMacro>
+ </ItemGroup>
+</Project>
diff --git a/testing/gmock/msvc/2010/gmock_main.vcxproj b/testing/gmock/msvc/2010/gmock_main.vcxproj
new file mode 100644
index 0000000..27fecd5
--- /dev/null
+++ b/testing/gmock/msvc/2010/gmock_main.vcxproj
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{E4EF614B-30DF-4954-8C53-580A0BF6B589}</ProjectGuid>
+ <RootNamespace>gmock_main</RootNamespace>
+ <Keyword>Win32Proj</Keyword>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <CharacterSet>Unicode</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="gmock_config.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="gmock_config.props" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(OutDir)$(ProjectName)\</IntDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(OutDir)$(ProjectName)\</IntDir>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <AdditionalIncludeDirectories>../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ProjectReference Include="gmock.vcxproj">
+ <Project>{34681f0d-ce45-415d-b5f2-5c662dfe3bd5}</Project>
+ <CopyLocalSatelliteAssemblies>true</CopyLocalSatelliteAssemblies>
+ <ReferenceOutputAssembly>true</ReferenceOutputAssembly>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\src\gmock_main.cc">
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ClCompile>
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project>
diff --git a/testing/gmock/msvc/2010/gmock_test.vcxproj b/testing/gmock/msvc/2010/gmock_test.vcxproj
new file mode 100644
index 0000000..265439e
--- /dev/null
+++ b/testing/gmock/msvc/2010/gmock_test.vcxproj
@@ -0,0 +1,101 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{F10D22F8-AC7B-4213-8720-608E7D878CD2}</ProjectGuid>
+ <RootNamespace>gmock_test</RootNamespace>
+ <Keyword>Win32Proj</Keyword>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>Unicode</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="gmock_config.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="gmock_config.props" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(OutDir)$(ProjectName)\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(OutDir)$(ProjectName)\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\include;..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
+ <AdditionalIncludeDirectories>..\..\include;..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ProjectReference Include="gmock_main.vcxproj">
+ <Project>{e4ef614b-30df-4954-8c53-580a0bf6b589}</Project>
+ <CopyLocalSatelliteAssemblies>true</CopyLocalSatelliteAssemblies>
+ <ReferenceOutputAssembly>true</ReferenceOutputAssembly>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\test\gmock_all_test.cc" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project>
diff --git a/testing/gmock/msvc/gmock-spec-builders_test.vcproj b/testing/gmock/msvc/gmock-spec-builders_test.vcproj
deleted file mode 100755
index 8440742..0000000
--- a/testing/gmock/msvc/gmock-spec-builders_test.vcproj
+++ /dev/null
@@ -1,205 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="8.00"
- Name="gmock-spec-builders_test"
- ProjectGUID="{46972604-5BE0-4493-BAE3-878DB825FDCB}"
- RootNamespace="gmockspecbuilders_test"
- Keyword="Win32Proj"
- >
- <Platforms>
- <Platform
- Name="Win32"
- />
- </Platforms>
- <ToolFiles>
- </ToolFiles>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory="$(SolutionDir)$(ConfigurationName)"
- IntermediateDirectory="$(ConfigurationName)"
- ConfigurationType="1"
- InheritedPropertySheets=".\gmock_config.vsprops"
- CharacterSet="1"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="../include"
- PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
- MinimalRebuild="true"
- BasicRuntimeChecks="3"
- RuntimeLibrary="1"
- UsePrecompiledHeader="0"
- WarningLevel="3"
- Detect64BitPortabilityProblems="true"
- DebugInformationFormat="4"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLinkerTool"
- LinkIncremental="2"
- GenerateDebugInformation="true"
- SubSystem="1"
- TargetMachine="1"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Release|Win32"
- OutputDirectory="$(SolutionDir)$(ConfigurationName)"
- IntermediateDirectory="$(ConfigurationName)"
- ConfigurationType="1"
- InheritedPropertySheets=".\gmock_config.vsprops"
- CharacterSet="1"
- WholeProgramOptimization="1"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="../include"
- PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
- RuntimeLibrary="0"
- UsePrecompiledHeader="0"
- WarningLevel="3"
- Detect64BitPortabilityProblems="true"
- DebugInformationFormat="3"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLinkerTool"
- LinkIncremental="1"
- GenerateDebugInformation="true"
- SubSystem="1"
- OptimizeReferences="2"
- EnableCOMDATFolding="2"
- TargetMachine="1"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- </Configurations>
- <References>
- <ProjectReference
- ReferencedProjectIdentifier="{34681F0D-CE45-415D-B5F2-5C662DFE3BD5}"
- RelativePathToProject=".\gmock.vcproj"
- />
- </References>
- <Files>
- <Filter
- Name="Source Files"
- Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
- UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
- >
- <File
- RelativePath="..\test\gmock-spec-builders_test.cc"
- >
- </File>
- </Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
- >
- </Filter>
- <Filter
- Name="Resource Files"
- Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
- UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
- >
- </Filter>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
diff --git a/testing/gmock/msvc/gmock_test.vcproj b/testing/gmock/msvc/gmock_test.vcproj
deleted file mode 100644
index 60e1b4b..0000000
--- a/testing/gmock/msvc/gmock_test.vcproj
+++ /dev/null
@@ -1,243 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="8.00"
- Name="gmock_test"
- ProjectGUID="{F10D22F8-AC7B-4213-8720-608E7D878CD2}"
- RootNamespace="gmock_test"
- Keyword="Win32Proj"
- >
- <Platforms>
- <Platform
- Name="Win32"
- />
- </Platforms>
- <ToolFiles>
- </ToolFiles>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory="$(SolutionDir)$(ConfigurationName)"
- IntermediateDirectory="$(OutDir)\$(ProjectName)"
- ConfigurationType="1"
- InheritedPropertySheets=".\gmock_config.vsprops"
- CharacterSet="1"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="../include"
- PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
- MinimalRebuild="true"
- BasicRuntimeChecks="3"
- RuntimeLibrary="1"
- UsePrecompiledHeader="0"
- WarningLevel="3"
- Detect64BitPortabilityProblems="true"
- DebugInformationFormat="3"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLinkerTool"
- LinkIncremental="2"
- GenerateDebugInformation="true"
- SubSystem="1"
- TargetMachine="1"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Release|Win32"
- OutputDirectory="$(SolutionDir)$(ConfigurationName)"
- IntermediateDirectory="$(OutDir)\$(ProjectName)"
- ConfigurationType="1"
- InheritedPropertySheets=".\gmock_config.vsprops"
- CharacterSet="1"
- WholeProgramOptimization="1"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="../include"
- PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
- RuntimeLibrary="0"
- UsePrecompiledHeader="0"
- WarningLevel="3"
- Detect64BitPortabilityProblems="true"
- DebugInformationFormat="3"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLinkerTool"
- LinkIncremental="1"
- GenerateDebugInformation="true"
- SubSystem="1"
- OptimizeReferences="2"
- EnableCOMDATFolding="2"
- TargetMachine="1"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- </Configurations>
- <References>
- <ProjectReference
- ReferencedProjectIdentifier="{E4EF614B-30DF-4954-8C53-580A0BF6B589}"
- RelativePathToProject=".\gmock_main.vcproj"
- />
- </References>
- <Files>
- <Filter
- Name="Source Files"
- Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
- UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
- >
- <File
- RelativePath="..\test\gmock-actions_test.cc"
- >
- </File>
- <File
- RelativePath="..\test\gmock-cardinalities_test.cc"
- >
- </File>
- <File
- RelativePath="..\test\gmock-generated-actions_test.cc"
- >
- </File>
- <File
- RelativePath="..\test\gmock-generated-function-mockers_test.cc"
- >
- </File>
- <File
- RelativePath="..\test\gmock-generated-internal-utils_test.cc"
- >
- </File>
- <File
- RelativePath="..\test\gmock-generated-matchers_test.cc"
- >
- </File>
- <File
- RelativePath="..\test\gmock-internal-utils_test.cc"
- >
- </File>
- <File
- RelativePath="..\test\gmock-matchers_test.cc"
- >
- </File>
- <File
- RelativePath="..\test\gmock-nice-strict_test.cc"
- >
- </File>
- <File
- RelativePath="..\test\gmock-port_test.cc"
- >
- </File>
- <File
- RelativePath="..\test\gmock-printers_test.cc"
- >
- </File>
- <File
- RelativePath="..\test\gmock_test.cc"
- >
- </File>
- </Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
- >
- </Filter>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
diff --git a/testing/gmock/run_tests.py b/testing/gmock/run_tests.py
deleted file mode 100755
index 5e7b308..0000000
--- a/testing/gmock/run_tests.py
+++ /dev/null
@@ -1,81 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2008, Google Inc. All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-# * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-# * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-"""Runs the specified tests for Google Mock.
-
-This script requires Python 2.3 or higher. To learn the usage, run it
-with -h.
-"""
-
-__author__ = 'vladl@google.com (Vlad Losev)'
-
-
-import os
-import sys
-
-SCRIPT_DIR = os.path.dirname(__file__) or '.'
-
-# Path to the Google Test code this Google Mock will use. We assume the
-# gtest/ directory is either a subdirectory (possibly via a symbolic link)
-# of gmock/ or a sibling.
-#
-# isdir resolves symbolic links.
-if os.path.isdir(os.path.join(SCRIPT_DIR, 'gtest/test')):
- RUN_TESTS_UTIL_DIR = os.path.join(SCRIPT_DIR, 'gtest/test')
-else:
- RUN_TESTS_UTIL_DIR = os.path.join(SCRIPT_DIR, '../gtest/test')
-
-sys.path.append(RUN_TESTS_UTIL_DIR)
-import run_tests_util
-
-def GetGmockBuildDir(injected_os, script_dir, config):
- return injected_os.path.normpath(injected_os.path.join(script_dir,
- 'scons/build',
- config,
- 'gmock/scons'))
-
-
-def _Main():
- """Runs all tests for Google Mock."""
-
- options, args = run_tests_util.ParseArgs('gtest')
- test_runner = run_tests_util.TestRunner(
- script_dir=SCRIPT_DIR,
- injected_build_dir_finder=GetGmockBuildDir)
- tests = test_runner.GetTestsToRun(args,
- options.configurations,
- options.built_configurations)
- if not tests:
- sys.exit(1) # Incorrect parameters given, abort execution.
-
- sys.exit(test_runner.RunTests(tests[0], tests[1]))
-
-if __name__ == '__main__':
- _Main()
diff --git a/testing/gmock/scripts/fuse_gmock_files.py b/testing/gmock/scripts/fuse_gmock_files.py
index 4e892e9..fc0baf7 100755
--- a/testing/gmock/scripts/fuse_gmock_files.py
+++ b/testing/gmock/scripts/fuse_gmock_files.py
@@ -75,8 +75,8 @@ sys.path.append(os.path.join(DEFAULT_GMOCK_ROOT_DIR, 'gtest/scripts'))
import fuse_gtest_files
gtest = fuse_gtest_files
-# Regex for matching '#include <gmock/...>'.
-INCLUDE_GMOCK_FILE_REGEX = re.compile(r'^\s*#\s*include\s*<(gmock/.+)>')
+# Regex for matching '#include "gmock/..."'.
+INCLUDE_GMOCK_FILE_REGEX = re.compile(r'^\s*#\s*include\s*"(gmock/.+)"')
# Where to find the source seed files.
GMOCK_H_SEED = 'include/gmock/gmock.h'
@@ -135,19 +135,19 @@ def FuseGMockH(gmock_root, output_dir):
for line in file(os.path.join(gmock_root, gmock_header_path), 'r'):
m = INCLUDE_GMOCK_FILE_REGEX.match(line)
if m:
- # It's '#include <gmock/...>' - let's process it recursively.
+ # It's '#include "gmock/..."' - let's process it recursively.
ProcessFile('include/' + m.group(1))
else:
m = gtest.INCLUDE_GTEST_FILE_REGEX.match(line)
if m:
- # It's '#include <gtest/foo.h>'. We translate it to
- # <gtest/gtest.h>, regardless of what foo is, since all
+ # It's '#include "gtest/foo.h"'. We translate it to
+ # "gtest/gtest.h", regardless of what foo is, since all
# gtest headers are fused into gtest/gtest.h.
# There is no need to #include gtest.h twice.
if not gtest.GTEST_H_SEED in processed_files:
processed_files.add(gtest.GTEST_H_SEED)
- output_file.write('#include <%s>\n' % (gtest.GTEST_H_OUTPUT,))
+ output_file.write('#include "%s"\n' % (gtest.GTEST_H_OUTPUT,))
else:
# Otherwise we copy the line unchanged to the output file.
output_file.write(line)
@@ -174,18 +174,18 @@ def FuseGMockAllCcToFile(gmock_root, output_file):
for line in file(os.path.join(gmock_root, gmock_source_file), 'r'):
m = INCLUDE_GMOCK_FILE_REGEX.match(line)
if m:
- # It's '#include <gmock/foo.h>'. We treat it as '#include
- # <gmock/gmock.h>', as all other gmock headers are being fused
+ # It's '#include "gmock/foo.h"'. We treat it as '#include
+ # "gmock/gmock.h"', as all other gmock headers are being fused
# into gmock.h and cannot be #included directly.
- # There is no need to #include <gmock/gmock.h> more than once.
+ # There is no need to #include "gmock/gmock.h" more than once.
if not GMOCK_H_SEED in processed_files:
processed_files.add(GMOCK_H_SEED)
- output_file.write('#include <%s>\n' % (GMOCK_H_OUTPUT,))
+ output_file.write('#include "%s"\n' % (GMOCK_H_OUTPUT,))
else:
m = gtest.INCLUDE_GTEST_FILE_REGEX.match(line)
if m:
- # It's '#include <gtest/...>'.
+ # It's '#include "gtest/..."'.
# There is no need to #include gtest.h as it has been
# #included by gtest-all.cc.
pass
diff --git a/testing/gmock/scripts/generator/cpp/ast.py b/testing/gmock/scripts/generator/cpp/ast.py
index 47dc9a0..6f61f87 100755
--- a/testing/gmock/scripts/generator/cpp/ast.py
+++ b/testing/gmock/scripts/generator/cpp/ast.py
@@ -1483,7 +1483,13 @@ class AstBuilder(object):
assert class_token.token_type == tokenize.SYNTAX, class_token
token = class_token
else:
- self._AddBackToken(class_token)
+ # Skip any macro (e.g. storage class specifiers) after the
+ # 'class' keyword.
+ next_token = self._GetNextToken()
+ if next_token.token_type == tokenize.NAME:
+ self._AddBackToken(next_token)
+ else:
+ self._AddBackTokens([class_token, next_token])
name_tokens, token = self.GetName()
class_name = ''.join([t.name for t in name_tokens])
bases = None
diff --git a/testing/gmock/scripts/generator/cpp/gmock_class.py b/testing/gmock/scripts/generator/cpp/gmock_class.py
index 3ad0bcd..645c295 100755
--- a/testing/gmock/scripts/generator/cpp/gmock_class.py
+++ b/testing/gmock/scripts/generator/cpp/gmock_class.py
@@ -31,12 +31,18 @@ __author__ = 'nnorwitz@google.com (Neal Norwitz)'
import os
import re
-import sets
import sys
from cpp import ast
from cpp import utils
+# Preserve compatibility with Python 2.3.
+try:
+ _dummy = set
+except NameError:
+ import sets
+ set = sets.Set
+
_VERSION = (1, 0, 1) # The version of this script.
# How many spaces to indent. Can set me with the INDENT environment variable.
_INDENT = 2
@@ -45,6 +51,7 @@ _INDENT = 2
def _GenerateMethods(output_lines, source, class_node):
function_type = ast.FUNCTION_VIRTUAL | ast.FUNCTION_PURE_VIRTUAL
ctor_or_dtor = ast.FUNCTION_CTOR | ast.FUNCTION_DTOR
+ indent = ' ' * _INDENT
for node in class_node.body:
# We only care about virtual functions.
@@ -62,11 +69,20 @@ def _GenerateMethods(output_lines, source, class_node):
if node.return_type.modifiers:
modifiers = ' '.join(node.return_type.modifiers) + ' '
return_type = modifiers + node.return_type.name
+ template_args = [arg.name for arg in node.return_type.templated_types]
+ if template_args:
+ return_type += '<' + ', '.join(template_args) + '>'
+ if len(template_args) > 1:
+ for line in [
+ '// The following line won\'t really compile, as the return',
+ '// type has multiple template arguments. To fix it, use a',
+ '// typedef for the return type.']:
+ output_lines.append(indent + line)
if node.return_type.pointer:
return_type += '*'
if node.return_type.reference:
return_type += '&'
- prefix = 'MOCK_%sMETHOD%d' % (const, len(node.parameters))
+ mock_method_macro = 'MOCK_%sMETHOD%d' % (const, len(node.parameters))
args = ''
if node.parameters:
# Get the full text of the parameters from the start
@@ -81,15 +97,13 @@ def _GenerateMethods(output_lines, source, class_node):
# intervening whitespace, e.g.: int\nBar
args = re.sub(' +', ' ', args_strings.replace('\n', ' '))
- # Create the prototype.
- indent = ' ' * _INDENT
- line = ('%s%s(%s,\n%s%s(%s));' %
- (indent, prefix, node.name, indent*3, return_type, args))
- output_lines.append(line)
+ # Create the mock method definition.
+ output_lines.extend(['%s%s(%s,' % (indent, mock_method_macro, node.name),
+ '%s%s(%s));' % (indent*3, return_type, args)])
def _GenerateMocks(filename, source, ast_list, desired_class_names):
- processed_class_names = sets.Set()
+ processed_class_names = set()
lines = []
for node in ast_list:
if (isinstance(node, ast.Class) and node.body and
@@ -156,7 +170,7 @@ def main(argv=sys.argv):
filename = argv[1]
desired_class_names = None # None means all classes in the source file.
if len(argv) >= 3:
- desired_class_names = sets.Set(argv[2:])
+ desired_class_names = set(argv[2:])
source = utils.ReadFile(filename)
if source is None:
return 1
diff --git a/testing/gmock/scripts/generator/cpp/gmock_class_test.py b/testing/gmock/scripts/generator/cpp/gmock_class_test.py
index ae00800..494720c 100755
--- a/testing/gmock/scripts/generator/cpp/gmock_class_test.py
+++ b/testing/gmock/scripts/generator/cpp/gmock_class_test.py
@@ -34,22 +34,47 @@ from cpp import gmock_class
class TestCase(unittest.TestCase):
"""Helper class that adds assert methods."""
+ def StripLeadingWhitespace(self, lines):
+ """Strip leading whitespace in each line in 'lines'."""
+ return '\n'.join([s.lstrip() for s in lines.split('\n')])
+
def assertEqualIgnoreLeadingWhitespace(self, expected_lines, lines):
"""Specialized assert that ignores the indent level."""
- stripped_lines = '\n'.join([s.lstrip() for s in lines.split('\n')])
- self.assertEqual(expected_lines, stripped_lines)
+ self.assertEqual(expected_lines, self.StripLeadingWhitespace(lines))
class GenerateMethodsTest(TestCase):
def GenerateMethodSource(self, cpp_source):
- """Helper method to convert C++ source to gMock output source lines."""
+ """Convert C++ source to Google Mock output source lines."""
method_source_lines = []
# <test> is a pseudo-filename, it is not read or written.
builder = ast.BuilderFromSource(cpp_source, '<test>')
ast_list = list(builder.Generate())
gmock_class._GenerateMethods(method_source_lines, cpp_source, ast_list[0])
- return ''.join(method_source_lines)
+ return '\n'.join(method_source_lines)
+
+ def testSimpleMethod(self):
+ source = """
+class Foo {
+ public:
+ virtual int Bar();
+};
+"""
+ self.assertEqualIgnoreLeadingWhitespace(
+ 'MOCK_METHOD0(Bar,\nint());',
+ self.GenerateMethodSource(source))
+
+ def testSimpleConstMethod(self):
+ source = """
+class Foo {
+ public:
+ virtual void Bar(bool flag) const;
+};
+"""
+ self.assertEqualIgnoreLeadingWhitespace(
+ 'MOCK_CONST_METHOD1(Bar,\nvoid(bool flag));',
+ self.GenerateMethodSource(source))
def testStrangeNewlineInParameter(self):
source = """
@@ -90,11 +115,47 @@ class Foo {
'MOCK_METHOD2(Bar,\nconst string&(int /* keeper */, int b));',
self.GenerateMethodSource(source))
+ def testArgsOfTemplateTypes(self):
+ source = """
+class Foo {
+ public:
+ virtual int Bar(const vector<int>& v, map<int, string>* output);
+};"""
+ self.assertEqualIgnoreLeadingWhitespace(
+ 'MOCK_METHOD2(Bar,\n'
+ 'int(const vector<int>& v, map<int, string>* output));',
+ self.GenerateMethodSource(source))
+
+ def testReturnTypeWithOneTemplateArg(self):
+ source = """
+class Foo {
+ public:
+ virtual vector<int>* Bar(int n);
+};"""
+ self.assertEqualIgnoreLeadingWhitespace(
+ 'MOCK_METHOD1(Bar,\nvector<int>*(int n));',
+ self.GenerateMethodSource(source))
+
+ def testReturnTypeWithManyTemplateArgs(self):
+ source = """
+class Foo {
+ public:
+ virtual map<int, string> Bar();
+};"""
+ # Comparing the comment text is brittle - we'll think of something
+ # better in case this gets annoying, but for now let's keep it simple.
+ self.assertEqualIgnoreLeadingWhitespace(
+ '// The following line won\'t really compile, as the return\n'
+ '// type has multiple template arguments. To fix it, use a\n'
+ '// typedef for the return type.\n'
+ 'MOCK_METHOD0(Bar,\nmap<int, string>());',
+ self.GenerateMethodSource(source))
+
class GenerateMocksTest(TestCase):
def GenerateMocks(self, cpp_source):
- """Helper method to convert C++ source to complete gMock output source."""
+ """Convert C++ source to complete Google Mock output source."""
# <test> is a pseudo-filename, it is not read or written.
filename = '<test>'
builder = ast.BuilderFromSource(cpp_source, filename)
@@ -132,6 +193,22 @@ void());
self.assertEqualIgnoreLeadingWhitespace(
expected, self.GenerateMocks(source))
+ def testClassWithStorageSpecifierMacro(self):
+ source = """
+class STORAGE_SPECIFIER Test {
+ public:
+ virtual void Foo();
+};
+"""
+ expected = """\
+class MockTest : public Test {
+public:
+MOCK_METHOD0(Foo,
+void());
+};
+"""
+ self.assertEqualIgnoreLeadingWhitespace(
+ expected, self.GenerateMocks(source))
if __name__ == '__main__':
unittest.main()
diff --git a/testing/gmock/scripts/gmock-config.in b/testing/gmock/scripts/gmock-config.in
index 9ce17a2..2baefe9 100755
--- a/testing/gmock/scripts/gmock-config.in
+++ b/testing/gmock/scripts/gmock-config.in
@@ -216,7 +216,7 @@ if test "${this_bindir}" = "${this_bindir%${bindir}}"; then
# TODO(chandlerc@google.com): This is a dangerous dependency on libtool, we
# should work to remove it, and/or remove libtool altogether, replacing it
# with direct references to the library and a link path.
- gmock_libs="${build_dir}/lib/libgtest.la"
+ gmock_libs="${build_dir}/lib/libgmock.la"
gmock_ldflags=""
# We provide hooks to include from either the source or build dir, where the
diff --git a/testing/gmock/scripts/gmock_doctor.py b/testing/gmock/scripts/gmock_doctor.py
index fad4e34..ab923ef 100755
--- a/testing/gmock/scripts/gmock_doctor.py
+++ b/testing/gmock/scripts/gmock_doctor.py
@@ -29,7 +29,7 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-"""Converts gcc errors in code using Google Mock to plain English."""
+"""Converts compiler's errors in code using Google Mock to plain English."""
__author__ = 'wan@google.com (Zhanyong Wan)'
@@ -38,6 +38,8 @@ import sys
_VERSION = '1.0.3'
+_EMAIL = 'googlemock@googlegroups.com'
+
_COMMON_GMOCK_SYMBOLS = [
# Matchers
'_',
@@ -100,6 +102,7 @@ _COMMON_GMOCK_SYMBOLS = [
'ReturnRef',
'SaveArg',
'SetArgReferee',
+ 'SetArgPointee',
'SetArgumentPointee',
'SetArrayArgument',
'SetErrnoAndReturn',
@@ -124,8 +127,11 @@ _COMMON_GMOCK_SYMBOLS = [
'Mock',
]
-# Regex for matching source file path and line number in gcc's errors.
-_FILE_LINE_RE = r'(?P<file>.*):(?P<line>\d+):\s+'
+# Regex for matching source file path and line number in the compiler's errors.
+_GCC_FILE_LINE_RE = r'(?P<file>.*):(?P<line>\d+):\s+'
+_CLANG_FILE_LINE_RE = r'(?P<file>.*):(?P<line>\d+):(?P<column>\d+):\s+'
+_CLANG_NON_GMOCK_FILE_LINE_RE = (
+ r'(?P<file>.*[/\\^](?!gmock-)[^/\\]+):(?P<line>\d+):(?P<column>\d+):\s+')
def _FindAllMatches(regex, s):
@@ -135,109 +141,174 @@ def _FindAllMatches(regex, s):
return r.finditer(s)
-def _GenericDiagnoser(short_name, long_name, regex, diagnosis, msg):
+def _GenericDiagnoser(short_name, long_name, diagnoses, msg):
"""Diagnoses the given disease by pattern matching.
+ Can provide different diagnoses for different patterns.
+
Args:
short_name: Short name of the disease.
long_name: Long name of the disease.
- regex: Regex for matching the symptoms.
- diagnosis: Pattern for formatting the diagnosis.
- msg: Gcc's error messages.
+ diagnoses: A list of pairs (regex, pattern for formatting the diagnosis
+ for matching regex).
+ msg: Compiler's error messages.
Yields:
Tuples of the form
(short name of disease, long name of disease, diagnosis).
"""
-
- diagnosis = '%(file)s:%(line)s:' + diagnosis
- for m in _FindAllMatches(regex, msg):
- yield (short_name, long_name, diagnosis % m.groupdict())
+ for regex, diagnosis in diagnoses:
+ if re.search(regex, msg):
+ diagnosis = '%(file)s:%(line)s:' + diagnosis
+ for m in _FindAllMatches(regex, msg):
+ yield (short_name, long_name, diagnosis % m.groupdict())
def _NeedToReturnReferenceDiagnoser(msg):
- """Diagnoses the NRR disease, given the error messages by gcc."""
-
- regex = (r'In member function \'testing::internal::ReturnAction<R>.*\n'
- + _FILE_LINE_RE + r'instantiated from here\n'
- r'.*gmock-actions\.h.*error: creating array with negative size')
+ """Diagnoses the NRR disease, given the error messages by the compiler."""
+
+ gcc_regex = (r'In member function \'testing::internal::ReturnAction<R>.*\n'
+ + _GCC_FILE_LINE_RE + r'instantiated from here\n'
+ r'.*gmock-actions\.h.*error: creating array with negative size')
+ clang_regex = (r'error:.*array.*negative.*\r?\n'
+ r'(.*\n)*?' +
+ _CLANG_NON_GMOCK_FILE_LINE_RE +
+ r'note: in instantiation of function template specialization '
+ r'\'testing::internal::ReturnAction<(?P<type>).*>'
+ r'::operator Action<.*>\' requested here')
diagnosis = """
-You are using an Return() action in a function that returns a reference.
-Please use ReturnRef() instead."""
+You are using a Return() action in a function that returns a reference to
+%(type)s. Please use ReturnRef() instead."""
return _GenericDiagnoser('NRR', 'Need to Return Reference',
- regex, diagnosis, msg)
+ [(clang_regex, diagnosis),
+ (gcc_regex, diagnosis % {'type': 'a type'})],
+ msg)
def _NeedToReturnSomethingDiagnoser(msg):
- """Diagnoses the NRS disease, given the error messages by gcc."""
-
- regex = (_FILE_LINE_RE +
- r'(instantiated from here\n.'
- r'*gmock.*actions\.h.*error: void value not ignored)'
- r'|(error: control reaches end of non-void function)')
+ """Diagnoses the NRS disease, given the error messages by the compiler."""
+
+ gcc_regex = (_GCC_FILE_LINE_RE + r'(instantiated from here\n.'
+ r'*gmock.*actions\.h.*error: void value not ignored)'
+ r'|(error: control reaches end of non-void function)')
+ clang_regex1 = (_CLANG_FILE_LINE_RE +
+ r'error: cannot initialize return object '
+ r'of type \'Result\' \(aka \'(?P<return_type>).*\'\) '
+ r'with an rvalue of type \'void\'')
+ clang_regex2 = (_CLANG_FILE_LINE_RE +
+ r'error: cannot initialize return object '
+ r'of type \'(?P<return_type>).*\' '
+ r'with an rvalue of type \'void\'')
diagnosis = """
You are using an action that returns void, but it needs to return
-*something*. Please tell it *what* to return. Perhaps you can use
+%(return_type)s. Please tell it *what* to return. Perhaps you can use
the pattern DoAll(some_action, Return(some_value))?"""
- return _GenericDiagnoser('NRS', 'Need to Return Something',
- regex, diagnosis, msg)
+ return _GenericDiagnoser(
+ 'NRS',
+ 'Need to Return Something',
+ [(gcc_regex, diagnosis % {'return_type': '*something*'}),
+ (clang_regex1, diagnosis),
+ (clang_regex2, diagnosis)],
+ msg)
def _NeedToReturnNothingDiagnoser(msg):
- """Diagnoses the NRN disease, given the error messages by gcc."""
-
- regex = (_FILE_LINE_RE + r'instantiated from here\n'
- r'.*gmock-actions\.h.*error: instantiation of '
- r'\'testing::internal::ReturnAction<R>::Impl<F>::value_\' '
- r'as type \'void\'')
+ """Diagnoses the NRN disease, given the error messages by the compiler."""
+
+ gcc_regex = (_GCC_FILE_LINE_RE + r'instantiated from here\n'
+ r'.*gmock-actions\.h.*error: instantiation of '
+ r'\'testing::internal::ReturnAction<R>::Impl<F>::value_\' '
+ r'as type \'void\'')
+ clang_regex1 = (r'error: field has incomplete type '
+ r'\'Result\' \(aka \'void\'\)(\r)?\n'
+ r'(.*\n)*?' +
+ _CLANG_NON_GMOCK_FILE_LINE_RE + r'note: in instantiation '
+ r'of function template specialization '
+ r'\'testing::internal::ReturnAction<(?P<return_type>.*)>'
+ r'::operator Action<void \(.*\)>\' requested here')
+ clang_regex2 = (r'error: field has incomplete type '
+ r'\'Result\' \(aka \'void\'\)(\r)?\n'
+ r'(.*\n)*?' +
+ _CLANG_NON_GMOCK_FILE_LINE_RE + r'note: in instantiation '
+ r'of function template specialization '
+ r'\'testing::internal::DoBothAction<.*>'
+ r'::operator Action<(?P<return_type>.*) \(.*\)>\' '
+ r'requested here')
diagnosis = """
-You are using an action that returns *something*, but it needs to return
+You are using an action that returns %(return_type)s, but it needs to return
void. Please use a void-returning action instead.
All actions but the last in DoAll(...) must return void. Perhaps you need
to re-arrange the order of actions in a DoAll(), if you are using one?"""
- return _GenericDiagnoser('NRN', 'Need to Return Nothing',
- regex, diagnosis, msg)
+ return _GenericDiagnoser(
+ 'NRN',
+ 'Need to Return Nothing',
+ [(gcc_regex, diagnosis % {'return_type': '*something*'}),
+ (clang_regex1, diagnosis),
+ (clang_regex2, diagnosis)],
+ msg)
def _IncompleteByReferenceArgumentDiagnoser(msg):
- """Diagnoses the IBRA disease, given the error messages by gcc."""
-
- regex = (_FILE_LINE_RE + r'instantiated from here\n'
- r'.*gtest-printers\.h.*error: invalid application of '
- r'\'sizeof\' to incomplete type \'(?P<type>.*)\'')
+ """Diagnoses the IBRA disease, given the error messages by the compiler."""
+
+ gcc_regex = (_GCC_FILE_LINE_RE + r'instantiated from here\n'
+ r'.*gtest-printers\.h.*error: invalid application of '
+ r'\'sizeof\' to incomplete type \'(?P<type>.*)\'')
+
+ clang_regex = (r'.*gtest-printers\.h.*error: invalid application of '
+ r'\'sizeof\' to an incomplete type '
+ r'\'(?P<type>.*)( const)?\'\r?\n'
+ r'(.*\n)*?' +
+ _CLANG_NON_GMOCK_FILE_LINE_RE +
+ r'note: in instantiation of member function '
+ r'\'testing::internal2::TypeWithoutFormatter<.*>::'
+ r'PrintValue\' requested here')
diagnosis = """
In order to mock this function, Google Mock needs to see the definition
of type "%(type)s" - declaration alone is not enough. Either #include
the header that defines it, or change the argument to be passed
by pointer."""
+
return _GenericDiagnoser('IBRA', 'Incomplete By-Reference Argument Type',
- regex, diagnosis, msg)
+ [(gcc_regex, diagnosis),
+ (clang_regex, diagnosis)],
+ msg)
def _OverloadedFunctionMatcherDiagnoser(msg):
- """Diagnoses the OFM disease, given the error messages by gcc."""
+ """Diagnoses the OFM disease, given the error messages by the compiler."""
- regex = (_FILE_LINE_RE + r'error: no matching function for '
- r'call to \'Truly\(<unresolved overloaded function type>\)')
+ gcc_regex = (_GCC_FILE_LINE_RE + r'error: no matching function for '
+ r'call to \'Truly\(<unresolved overloaded function type>\)')
+ clang_regex = (_CLANG_FILE_LINE_RE + r'error: no matching function for '
+ r'call to \'Truly')
diagnosis = """
The argument you gave to Truly() is an overloaded function. Please tell
-gcc which overloaded version you want to use.
+your compiler which overloaded version you want to use.
For example, if you want to use the version whose signature is
bool Foo(int n);
you should write
Truly(static_cast<bool (*)(int n)>(Foo))"""
return _GenericDiagnoser('OFM', 'Overloaded Function Matcher',
- regex, diagnosis, msg)
+ [(gcc_regex, diagnosis),
+ (clang_regex, diagnosis)],
+ msg)
def _OverloadedFunctionActionDiagnoser(msg):
- """Diagnoses the OFA disease, given the error messages by gcc."""
-
- regex = (_FILE_LINE_RE + r'error: no matching function for call to \'Invoke\('
- r'<unresolved overloaded function type>')
+ """Diagnoses the OFA disease, given the error messages by the compiler."""
+
+ gcc_regex = (_GCC_FILE_LINE_RE + r'error: no matching function for call to '
+ r'\'Invoke\(<unresolved overloaded function type>')
+ clang_regex = (_CLANG_FILE_LINE_RE + r'error: no matching '
+ r'function for call to \'Invoke\'\r?\n'
+ r'(.*\n)*?'
+ r'.*\bgmock-\w+-actions\.h:\d+:\d+:\s+'
+ r'note: candidate template ignored:\s+'
+ r'couldn\'t infer template argument \'FunctionImpl\'')
diagnosis = """
-You are passing an overloaded function to Invoke(). Please tell gcc
+Function you are passing to Invoke is overloaded. Please tell your compiler
which overloaded version you want to use.
For example, if you want to use the version whose signature is
@@ -245,18 +316,26 @@ For example, if you want to use the version whose signature is
you should write something like
Invoke(static_cast<bool (*)(int n, double x)>(MyFunction))"""
return _GenericDiagnoser('OFA', 'Overloaded Function Action',
- regex, diagnosis, msg)
-
-
-def _OverloadedMethodActionDiagnoser1(msg):
- """Diagnoses the OMA disease, given the error messages by gcc."""
-
- regex = (_FILE_LINE_RE + r'error: '
- r'.*no matching function for call to \'Invoke\(.*, '
- r'unresolved overloaded function type>')
+ [(gcc_regex, diagnosis),
+ (clang_regex, diagnosis)],
+ msg)
+
+
+def _OverloadedMethodActionDiagnoser(msg):
+ """Diagnoses the OMA disease, given the error messages by the compiler."""
+
+ gcc_regex = (_GCC_FILE_LINE_RE + r'error: no matching function for '
+ r'call to \'Invoke\(.+, <unresolved overloaded function '
+ r'type>\)')
+ clang_regex = (_CLANG_FILE_LINE_RE + r'error: no matching function '
+ r'for call to \'Invoke\'\r?\n'
+ r'(.*\n)*?'
+ r'.*\bgmock-\w+-actions\.h:\d+:\d+: '
+ r'note: candidate function template not viable: '
+ r'requires 1 argument, but 2 were provided')
diagnosis = """
The second argument you gave to Invoke() is an overloaded method. Please
-tell gcc which overloaded version you want to use.
+tell your compiler which overloaded version you want to use.
For example, if you want to use the version whose signature is
class Foo {
@@ -266,15 +345,20 @@ For example, if you want to use the version whose signature is
you should write something like
Invoke(foo, static_cast<bool (Foo::*)(int n, double x)>(&Foo::Bar))"""
return _GenericDiagnoser('OMA', 'Overloaded Method Action',
- regex, diagnosis, msg)
+ [(gcc_regex, diagnosis),
+ (clang_regex, diagnosis)],
+ msg)
def _MockObjectPointerDiagnoser(msg):
- """Diagnoses the MOP disease, given the error messages by gcc."""
-
- regex = (_FILE_LINE_RE + r'error: request for member '
- r'\'gmock_(?P<method>.+)\' in \'(?P<mock_object>.+)\', '
- r'which is of non-class type \'(.*::)*(?P<class_name>.+)\*\'')
+ """Diagnoses the MOP disease, given the error messages by the compiler."""
+
+ gcc_regex = (_GCC_FILE_LINE_RE + r'error: request for member '
+ r'\'gmock_(?P<method>.+)\' in \'(?P<mock_object>.+)\', '
+ r'which is of non-class type \'(.*::)*(?P<class_name>.+)\*\'')
+ clang_regex = (_CLANG_FILE_LINE_RE + r'error: member reference type '
+ r'\'(?P<class_name>.*?) *\' is a pointer; '
+ r'maybe you meant to use \'->\'\?')
diagnosis = """
The first argument to ON_CALL() and EXPECT_CALL() must be a mock *object*,
not a *pointer* to it. Please write '*(%(mock_object)s)' instead of
@@ -294,63 +378,103 @@ and the following mock instance:
you should use the EXPECT_CALL like this:
EXPECT_CALL(*mock_ptr, %(method)s(...));"""
- return _GenericDiagnoser('MOP', 'Mock Object Pointer',
- regex, diagnosis, msg)
-
-def _OverloadedMethodActionDiagnoser2(msg):
- """Diagnoses the OMA disease, given the error messages by gcc."""
-
- regex = (_FILE_LINE_RE + r'error: no matching function for '
- r'call to \'Invoke\(.+, <unresolved overloaded function type>\)')
- diagnosis = """
-The second argument you gave to Invoke() is an overloaded method. Please
-tell gcc which overloaded version you want to use.
-
-For example, if you want to use the version whose signature is
- class Foo {
- ...
- bool Bar(int n, double x);
- };
-you should write something like
- Invoke(foo, static_cast<bool (Foo::*)(int n, double x)>(&Foo::Bar))"""
- return _GenericDiagnoser('OMA', 'Overloaded Method Action',
- regex, diagnosis, msg)
+ return _GenericDiagnoser(
+ 'MOP',
+ 'Mock Object Pointer',
+ [(gcc_regex, diagnosis),
+ (clang_regex, diagnosis % {'mock_object': 'mock_object',
+ 'method': 'method',
+ 'class_name': '%(class_name)s'})],
+ msg)
def _NeedToUseSymbolDiagnoser(msg):
- """Diagnoses the NUS disease, given the error messages by gcc."""
+ """Diagnoses the NUS disease, given the error messages by the compiler."""
- regex = (_FILE_LINE_RE + r'error: \'(?P<symbol>.+)\' '
- r'(was not declared in this scope|has not been declared)')
+ gcc_regex = (_GCC_FILE_LINE_RE + r'error: \'(?P<symbol>.+)\' '
+ r'(was not declared in this scope|has not been declared)')
+ clang_regex = (_CLANG_FILE_LINE_RE + r'error: use of undeclared identifier '
+ r'\'(?P<symbol>.+)\'')
diagnosis = """
'%(symbol)s' is defined by Google Mock in the testing namespace.
Did you forget to write
using testing::%(symbol)s;
?"""
- for m in _FindAllMatches(regex, msg):
+ for m in (list(_FindAllMatches(gcc_regex, msg)) +
+ list(_FindAllMatches(clang_regex, msg))):
symbol = m.groupdict()['symbol']
if symbol in _COMMON_GMOCK_SYMBOLS:
yield ('NUS', 'Need to Use Symbol', diagnosis % m.groupdict())
def _NeedToUseReturnNullDiagnoser(msg):
- """Diagnoses the NRNULL disease, given the error messages by gcc."""
-
- regex = ('instantiated from \'testing::internal::ReturnAction<R>'
- '::operator testing::Action<Func>\(\) const.*\n' +
- _FILE_LINE_RE + r'instantiated from here\n'
- r'.*error: no matching function for call to \'implicit_cast\('
- r'long int&\)')
+ """Diagnoses the NRNULL disease, given the error messages by the compiler."""
+
+ gcc_regex = ('instantiated from \'testing::internal::ReturnAction<R>'
+ '::operator testing::Action<Func>\(\) const.*\n' +
+ _GCC_FILE_LINE_RE + r'instantiated from here\n'
+ r'.*error: no matching function for call to \'ImplicitCast_\('
+ r'long int&\)')
+ clang_regex = (r'\bgmock-actions.h:.* error: no matching function for '
+ r'call to \'ImplicitCast_\'\r?\n'
+ r'(.*\n)*?' +
+ _CLANG_NON_GMOCK_FILE_LINE_RE + r'note: in instantiation '
+ r'of function template specialization '
+ r'\'testing::internal::ReturnAction<long>::operator '
+ r'Action<(?P<type>.*)\(\)>\' requested here')
diagnosis = """
You are probably calling Return(NULL) and the compiler isn't sure how to turn
-NULL into the right type. Use ReturnNull() instead.
+NULL into %(type)s. Use ReturnNull() instead.
Note: the line number may be off; please fix all instances of Return(NULL)."""
- return _GenericDiagnoser('NRNULL', 'Need to use ReturnNull',
- regex, diagnosis, msg)
+ return _GenericDiagnoser(
+ 'NRNULL', 'Need to use ReturnNull',
+ [(clang_regex, diagnosis),
+ (gcc_regex, diagnosis % {'type': 'the right type'})],
+ msg)
+
+def _TypeInTemplatedBaseDiagnoser(msg):
+ """Diagnoses the TTB disease, given the error messages by the compiler."""
-_TTB_DIAGNOSIS = """
+ # This version works when the type is used as the mock function's return
+ # type.
+ gcc_4_3_1_regex_type_in_retval = (
+ r'In member function \'int .*\n' + _GCC_FILE_LINE_RE +
+ r'error: a function call cannot appear in a constant-expression')
+ gcc_4_4_0_regex_type_in_retval = (
+ r'error: a function call cannot appear in a constant-expression'
+ + _GCC_FILE_LINE_RE + r'error: template argument 1 is invalid\n')
+ # This version works when the type is used as the mock function's sole
+ # parameter type.
+ gcc_regex_type_of_sole_param = (
+ _GCC_FILE_LINE_RE +
+ r'error: \'(?P<type>.+)\' was not declared in this scope\n'
+ r'.*error: template argument 1 is invalid\n')
+ # This version works when the type is used as a parameter of a mock
+ # function that has multiple parameters.
+ gcc_regex_type_of_a_param = (
+ r'error: expected `;\' before \'::\' token\n'
+ + _GCC_FILE_LINE_RE +
+ r'error: \'(?P<type>.+)\' was not declared in this scope\n'
+ r'.*error: template argument 1 is invalid\n'
+ r'.*error: \'.+\' was not declared in this scope')
+ clang_regex_type_of_retval_or_sole_param = (
+ _CLANG_FILE_LINE_RE +
+ r'error: use of undeclared identifier \'(?P<type>.*)\'\n'
+ r'(.*\n)*?'
+ r'(?P=file):(?P=line):(?P=column): error: '
+ r'non-friend class member \'Result\' cannot have a qualified name'
+ )
+ clang_regex_type_of_a_param = (
+ _CLANG_FILE_LINE_RE +
+ r'error: C\+\+ requires a type specifier for all declarations\n'
+ r'(.*\n)*?'
+ r'(?P=file):(?P=line):(?P=column): error: '
+ r'C\+\+ requires a type specifier for all declarations'
+ )
+
+ diagnosis = """
In a mock class template, types or typedefs defined in the base class
template are *not* automatically visible. This is how C++ works. Before
you can use a type or typedef named %(type)s defined in base class Base<T>, you
@@ -358,78 +482,49 @@ need to make it visible. One way to do it is:
typedef typename Base<T>::%(type)s %(type)s;"""
-
-def _TypeInTemplatedBaseDiagnoser1(msg):
- """Diagnoses the TTB disease, given the error messages by gcc.
-
- This version works when the type is used as the mock function's return
- type.
- """
-
- gcc_4_3_1_regex = (
- r'In member function \'int .*\n' + _FILE_LINE_RE +
- r'error: a function call cannot appear in a constant-expression')
- gcc_4_4_0_regex = (
- r'error: a function call cannot appear in a constant-expression'
- + _FILE_LINE_RE + r'error: template argument 1 is invalid\n')
- diagnosis = _TTB_DIAGNOSIS % {'type': 'Foo'}
- return (list(_GenericDiagnoser('TTB', 'Type in Template Base',
- gcc_4_3_1_regex, diagnosis, msg)) +
- list(_GenericDiagnoser('TTB', 'Type in Template Base',
- gcc_4_4_0_regex, diagnosis, msg)))
-
-
-def _TypeInTemplatedBaseDiagnoser2(msg):
- """Diagnoses the TTB disease, given the error messages by gcc.
-
- This version works when the type is used as the mock function's sole
- parameter type.
- """
-
- regex = (_FILE_LINE_RE +
- r'error: \'(?P<type>.+)\' was not declared in this scope\n'
- r'.*error: template argument 1 is invalid\n')
- return _GenericDiagnoser('TTB', 'Type in Template Base',
- regex, _TTB_DIAGNOSIS, msg)
-
-
-def _TypeInTemplatedBaseDiagnoser3(msg):
- """Diagnoses the TTB disease, given the error messages by gcc.
-
- This version works when the type is used as a parameter of a mock
- function that has multiple parameters.
- """
-
- regex = (r'error: expected `;\' before \'::\' token\n'
- + _FILE_LINE_RE +
- r'error: \'(?P<type>.+)\' was not declared in this scope\n'
- r'.*error: template argument 1 is invalid\n'
- r'.*error: \'.+\' was not declared in this scope')
- return _GenericDiagnoser('TTB', 'Type in Template Base',
- regex, _TTB_DIAGNOSIS, msg)
+ return _GenericDiagnoser(
+ 'TTB', 'Type in Template Base',
+ [(gcc_4_3_1_regex_type_in_retval, diagnosis % {'type': 'Foo'}),
+ (gcc_4_4_0_regex_type_in_retval, diagnosis % {'type': 'Foo'}),
+ (gcc_regex_type_of_sole_param, diagnosis),
+ (gcc_regex_type_of_a_param, diagnosis),
+ (clang_regex_type_of_retval_or_sole_param, diagnosis),
+ (clang_regex_type_of_a_param, diagnosis % {'type': 'Foo'})],
+ msg)
def _WrongMockMethodMacroDiagnoser(msg):
- """Diagnoses the WMM disease, given the error messages by gcc."""
-
- regex = (_FILE_LINE_RE +
- r'.*this_method_does_not_take_(?P<wrong_args>\d+)_argument.*\n'
- r'.*\n'
- r'.*candidates are.*FunctionMocker<[^>]+A(?P<args>\d+)\)>')
+ """Diagnoses the WMM disease, given the error messages by the compiler."""
+
+ gcc_regex = (_GCC_FILE_LINE_RE +
+ r'.*this_method_does_not_take_(?P<wrong_args>\d+)_argument.*\n'
+ r'.*\n'
+ r'.*candidates are.*FunctionMocker<[^>]+A(?P<args>\d+)\)>')
+ clang_regex = (_CLANG_NON_GMOCK_FILE_LINE_RE +
+ r'error:.*array.*negative.*r?\n'
+ r'(.*\n)*?'
+ r'(?P=file):(?P=line):(?P=column): error: too few arguments '
+ r'to function call, expected (?P<args>\d+), '
+ r'have (?P<wrong_args>\d+)')
diagnosis = """
You are using MOCK_METHOD%(wrong_args)s to define a mock method that has
%(args)s arguments. Use MOCK_METHOD%(args)s (or MOCK_CONST_METHOD%(args)s,
MOCK_METHOD%(args)s_T, MOCK_CONST_METHOD%(args)s_T as appropriate) instead."""
return _GenericDiagnoser('WMM', 'Wrong MOCK_METHODn Macro',
- regex, diagnosis, msg)
+ [(gcc_regex, diagnosis),
+ (clang_regex, diagnosis)],
+ msg)
def _WrongParenPositionDiagnoser(msg):
- """Diagnoses the WPP disease, given the error messages by gcc."""
-
- regex = (_FILE_LINE_RE +
- r'error:.*testing::internal::MockSpec<.* has no member named \''
- r'(?P<method>\w+)\'')
+ """Diagnoses the WPP disease, given the error messages by the compiler."""
+
+ gcc_regex = (_GCC_FILE_LINE_RE +
+ r'error:.*testing::internal::MockSpec<.* has no member named \''
+ r'(?P<method>\w+)\'')
+ clang_regex = (_CLANG_NON_GMOCK_FILE_LINE_RE +
+ r'error: no member named \'(?P<method>\w+)\' in '
+ r'\'testing::internal::MockSpec<.*>\'')
diagnosis = """
The closing parenthesis of ON_CALL or EXPECT_CALL should be *before*
".%(method)s". For example, you should write:
@@ -437,7 +532,9 @@ The closing parenthesis of ON_CALL or EXPECT_CALL should be *before*
instead of:
EXPECT_CALL(my_mock, Foo(_).%(method)s(...));"""
return _GenericDiagnoser('WPP', 'Wrong Parenthesis Position',
- regex, diagnosis, msg)
+ [(gcc_regex, diagnosis),
+ (clang_regex, diagnosis)],
+ msg)
_DIAGNOSERS = [
@@ -450,18 +547,17 @@ _DIAGNOSERS = [
_NeedToUseSymbolDiagnoser,
_OverloadedFunctionActionDiagnoser,
_OverloadedFunctionMatcherDiagnoser,
- _OverloadedMethodActionDiagnoser1,
- _OverloadedMethodActionDiagnoser2,
- _TypeInTemplatedBaseDiagnoser1,
- _TypeInTemplatedBaseDiagnoser2,
- _TypeInTemplatedBaseDiagnoser3,
+ _OverloadedMethodActionDiagnoser,
+ _TypeInTemplatedBaseDiagnoser,
_WrongMockMethodMacroDiagnoser,
_WrongParenPositionDiagnoser,
]
def Diagnose(msg):
- """Generates all possible diagnoses given the gcc error message."""
+ """Generates all possible diagnoses given the compiler error message."""
+
+ msg = re.sub(r'\x1b\[[^m]*m', '', msg) # Strips all color formatting.
diagnoses = []
for diagnoser in _DIAGNOSERS:
@@ -486,16 +582,17 @@ def main():
diagnoses = Diagnose(msg)
count = len(diagnoses)
if not count:
- print '\nGcc complained:'
- print '8<------------------------------------------------------------'
- print msg
- print '------------------------------------------------------------>8'
- print """
+ print ("""
+Your compiler complained:
+8<------------------------------------------------------------
+%s
+------------------------------------------------------------>8
+
Uh-oh, I'm not smart enough to figure out what the problem is. :-(
However...
-If you send your source code and gcc's error messages to
-googlemock@googlegroups.com, you can be helped and I can get smarter --
-win-win for us!"""
+If you send your source code and the compiler's error messages to
+%s, you can be helped and I can get smarter --
+win-win for us!""" % (msg, _EMAIL))
else:
print '------------------------------------------------------------'
print 'Your code appears to have the following',
@@ -509,10 +606,11 @@ win-win for us!"""
if count > 1:
print '\n#%s:' % (i,)
print d
- print """
+ print ("""
How did I do? If you think I'm wrong or unhelpful, please send your
-source code and gcc's error messages to googlemock@googlegroups.com. Then
-you can be helped and I can get smarter -- I promise I won't be upset!"""
+source code and the compiler's error messages to %s.
+Then you can be helped and I can get smarter -- I promise I won't be upset!""" %
+ _EMAIL)
if __name__ == '__main__':
diff --git a/testing/gmock/src/gmock-all.cc b/testing/gmock/src/gmock-all.cc
index 76118d8..7aebce7 100644
--- a/testing/gmock/src/gmock-all.cc
+++ b/testing/gmock/src/gmock-all.cc
@@ -37,7 +37,7 @@
// This line ensures that gmock.h can be compiled on its own, even
// when it's fused.
-#include <gmock/gmock.h>
+#include "gmock/gmock.h"
// The following lines pull in the real gmock *.cc files.
#include "src/gmock-cardinalities.cc"
diff --git a/testing/gmock/src/gmock-cardinalities.cc b/testing/gmock/src/gmock-cardinalities.cc
index 07eed46..1a7902b 100644
--- a/testing/gmock/src/gmock-cardinalities.cc
+++ b/testing/gmock/src/gmock-cardinalities.cc
@@ -33,14 +33,14 @@
//
// This file implements cardinalities.
-#include <gmock/gmock-cardinalities.h>
+#include "gmock/gmock-cardinalities.h"
#include <limits.h>
#include <ostream> // NOLINT
#include <sstream>
#include <string>
-#include <gmock/internal/gmock-internal-utils.h>
-#include <gtest/gtest.h>
+#include "gmock/internal/gmock-internal-utils.h"
+#include "gtest/gtest.h"
namespace testing {
diff --git a/testing/gmock/src/gmock-internal-utils.cc b/testing/gmock/src/gmock-internal-utils.cc
index cc51836..dd38132 100644
--- a/testing/gmock/src/gmock-internal-utils.cc
+++ b/testing/gmock/src/gmock-internal-utils.cc
@@ -35,14 +35,14 @@
// Mock. They are subject to change without notice, so please DO NOT
// USE THEM IN USER CODE.
-#include <gmock/internal/gmock-internal-utils.h>
+#include "gmock/internal/gmock-internal-utils.h"
#include <ctype.h>
#include <ostream> // NOLINT
#include <string>
-#include <gmock/gmock.h>
-#include <gmock/internal/gmock-port.h>
-#include <gtest/gtest.h>
+#include "gmock/gmock.h"
+#include "gmock/internal/gmock-port.h"
+#include "gtest/gtest.h"
namespace testing {
namespace internal {
@@ -57,14 +57,14 @@ string ConvertIdentifierNameToWords(const char* id_name) {
for (const char* p = id_name; *p != '\0'; prev_char = *(p++)) {
// We don't care about the current locale as the input is
// guaranteed to be a valid C++ identifier name.
- const bool starts_new_word = isupper(*p) ||
- (!isalpha(prev_char) && islower(*p)) ||
- (!isdigit(prev_char) && isdigit(*p));
+ const bool starts_new_word = IsUpper(*p) ||
+ (!IsAlpha(prev_char) && IsLower(*p)) ||
+ (!IsDigit(prev_char) && IsDigit(*p));
- if (isalnum(*p)) {
+ if (IsAlNum(*p)) {
if (starts_new_word && result != "")
result += ' ';
- result += static_cast<char>(tolower(*p));
+ result += ToLower(*p);
}
}
return result;
diff --git a/testing/gmock/src/gmock-matchers.cc b/testing/gmock/src/gmock-matchers.cc
index 0abca70..a5e6824 100644
--- a/testing/gmock/src/gmock-matchers.cc
+++ b/testing/gmock/src/gmock-matchers.cc
@@ -34,8 +34,8 @@
// This file implements Matcher<const string&>, Matcher<string>, and
// utilities for defining matchers.
-#include <gmock/gmock-matchers.h>
-#include <gmock/gmock-generated-matchers.h>
+#include "gmock/gmock-matchers.h"
+#include "gmock/gmock-generated-matchers.h"
#include <string.h>
#include <sstream>
@@ -65,74 +65,6 @@ Matcher<internal::string>::Matcher(const char* s) {
namespace internal {
-// Utilities for validating and formatting description strings in the
-// MATCHER*() macros.
-
-// Returns the 0-based index of the given parameter in the
-// NULL-terminated parameter array; if the parameter is "*", returns
-// kTupleInterpolation; if it's not found in the list, returns
-// kInvalidInterpolation.
-int GetParamIndex(const char* param_names[], const string& param_name) {
- if (param_name == "*")
- return kTupleInterpolation;
-
- for (int i = 0; param_names[i] != NULL; i++) {
- if (param_name == param_names[i])
- return i;
- }
- return kInvalidInterpolation;
-}
-
-// Helper function used by ValidateMatcherDescription() to format
-// error messages.
-string FormatMatcherDescriptionSyntaxError(const char* description,
- const char* error_pos) {
- ::std::stringstream ss;
- ss << "Syntax error at index " << (error_pos - description)
- << " in matcher description \"" << description << "\": ";
- return ss.str();
-}
-
-// Parses a matcher description string and returns a vector of
-// interpolations that appear in the string; generates non-fatal
-// failures iff 'description' is an invalid matcher description.
-// 'param_names' is a NULL-terminated array of parameter names in the
-// order they appear in the MATCHER_P*() parameter list.
-Interpolations ValidateMatcherDescription(
- const char* param_names[], const char* description) {
- Interpolations interps;
- for (const char* p = description; *p != '\0';) {
- if (SkipPrefix("%%", &p)) {
- interps.push_back(Interpolation(p - 2, p, kPercentInterpolation));
- } else if (SkipPrefix("%(", &p)) {
- const char* const q = strstr(p, ")s");
- if (q == NULL) {
- // TODO(wan@google.com): change the source file location in
- // the failure to point to where the MATCHER*() macro is used.
- ADD_FAILURE() << FormatMatcherDescriptionSyntaxError(description, p - 2)
- << "an interpolation must end with \")s\", "
- << "but \"" << (p - 2) << "\" does not.";
- } else {
- const string param_name(p, q);
- const int param_index = GetParamIndex(param_names, param_name);
- if (param_index == kInvalidInterpolation) {
- ADD_FAILURE() << FormatMatcherDescriptionSyntaxError(description, p)
- << "\"" << param_name
- << "\" is an invalid parameter name.";
- } else {
- interps.push_back(Interpolation(p - 2, q + 2, param_index));
- p = q + 2;
- }
- }
- } else {
- EXPECT_NE(*p, '%') << FormatMatcherDescriptionSyntaxError(description, p)
- << "use \"%%\" instead of \"%\" to print \"%\".";
- ++p;
- }
- }
- return interps;
-}
-
// Joins a vector of strings as if they are fields of a tuple; returns
// the joined string.
string JoinAsTuple(const Strings& fields) {
@@ -152,38 +84,17 @@ string JoinAsTuple(const Strings& fields) {
}
}
-// Returns the actual matcher description, given the matcher name,
-// user-supplied description template string, interpolations in the
-// string, and the printed values of the matcher parameters.
-string FormatMatcherDescription(
- const char* matcher_name, const char* description,
- const Interpolations& interp, const Strings& param_values) {
- string result;
- if (*description == '\0') {
- // When the user supplies an empty description, we calculate one
- // from the matcher name.
- result = ConvertIdentifierNameToWords(matcher_name);
- if (param_values.size() >= 1)
- result += " " + JoinAsTuple(param_values);
- } else {
- // The end position of the last interpolation.
- const char* last_interp_end = description;
- for (size_t i = 0; i < interp.size(); i++) {
- result.append(last_interp_end, interp[i].start_pos);
- const int param_index = interp[i].param_index;
- if (param_index == kTupleInterpolation) {
- result += JoinAsTuple(param_values);
- } else if (param_index == kPercentInterpolation) {
- result += '%';
- } else if (param_index != kInvalidInterpolation) {
- result += param_values[param_index];
- }
- last_interp_end = interp[i].end_pos;
- }
- result += last_interp_end;
- }
-
- return result;
+// Returns the description for a matcher defined using the MATCHER*()
+// macro where the user-supplied description string is "", if
+// 'negation' is false; otherwise returns the description of the
+// negation of the matcher. 'param_values' contains a list of strings
+// that are the print-out of the matcher's parameters.
+string FormatMatcherDescription(bool negation, const char* matcher_name,
+ const Strings& param_values) {
+ string result = ConvertIdentifierNameToWords(matcher_name);
+ if (param_values.size() >= 1)
+ result += " " + JoinAsTuple(param_values);
+ return negation ? "not (" + result + ")" : result;
}
} // namespace internal
diff --git a/testing/gmock/src/gmock-spec-builders.cc b/testing/gmock/src/gmock-spec-builders.cc
index dab1a2c..a99caef 100644
--- a/testing/gmock/src/gmock-spec-builders.cc
+++ b/testing/gmock/src/gmock-spec-builders.cc
@@ -34,15 +34,15 @@
// This file implements the spec builder syntax (ON_CALL and
// EXPECT_CALL).
-#include <gmock/gmock-spec-builders.h>
+#include "gmock/gmock-spec-builders.h"
#include <stdlib.h>
#include <iostream> // NOLINT
#include <map>
#include <set>
#include <string>
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
#if GTEST_OS_CYGWIN || GTEST_OS_LINUX || GTEST_OS_MAC
#include <unistd.h> // NOLINT
@@ -55,6 +55,15 @@ namespace internal {
// mockers, and all expectations.
GTEST_DEFINE_STATIC_MUTEX_(g_gmock_mutex);
+// Logs a message including file and line number information.
+void LogWithLocation(testing::internal::LogSeverity severity,
+ const char* file, int line,
+ const string& message) {
+ ::std::ostringstream s;
+ s << file << ":" << line << ": " << message << ::std::endl;
+ Log(severity, s.str(), 0);
+}
+
// Constructs an ExpectationBase object.
ExpectationBase::ExpectationBase(const char* a_file,
int a_line,
@@ -65,8 +74,12 @@ ExpectationBase::ExpectationBase(const char* a_file,
cardinality_specified_(false),
cardinality_(Exactly(1)),
call_count_(0),
- retired_(false) {
-}
+ retired_(false),
+ extra_matcher_specified_(false),
+ repeated_action_specified_(false),
+ retires_on_saturation_(false),
+ last_clause_(kNone),
+ action_count_checked_(false) {}
// Destructs an ExpectationBase object.
ExpectationBase::~ExpectationBase() {}
@@ -132,6 +145,99 @@ void ExpectationBase::FindUnsatisfiedPrerequisites(
}
}
+// Describes how many times a function call matching this
+// expectation has occurred.
+// L >= g_gmock_mutex
+void ExpectationBase::DescribeCallCountTo(::std::ostream* os) const {
+ g_gmock_mutex.AssertHeld();
+
+ // Describes how many times the function is expected to be called.
+ *os << " Expected: to be ";
+ cardinality().DescribeTo(os);
+ *os << "\n Actual: ";
+ Cardinality::DescribeActualCallCountTo(call_count(), os);
+
+ // Describes the state of the expectation (e.g. is it satisfied?
+ // is it active?).
+ *os << " - " << (IsOverSaturated() ? "over-saturated" :
+ IsSaturated() ? "saturated" :
+ IsSatisfied() ? "satisfied" : "unsatisfied")
+ << " and "
+ << (is_retired() ? "retired" : "active");
+}
+
+// Checks the action count (i.e. the number of WillOnce() and
+// WillRepeatedly() clauses) against the cardinality if this hasn't
+// been done before. Prints a warning if there are too many or too
+// few actions.
+// L < mutex_
+void ExpectationBase::CheckActionCountIfNotDone() const {
+ bool should_check = false;
+ {
+ MutexLock l(&mutex_);
+ if (!action_count_checked_) {
+ action_count_checked_ = true;
+ should_check = true;
+ }
+ }
+
+ if (should_check) {
+ if (!cardinality_specified_) {
+ // The cardinality was inferred - no need to check the action
+ // count against it.
+ return;
+ }
+
+ // The cardinality was explicitly specified.
+ const int action_count = static_cast<int>(untyped_actions_.size());
+ const int upper_bound = cardinality().ConservativeUpperBound();
+ const int lower_bound = cardinality().ConservativeLowerBound();
+ bool too_many; // True if there are too many actions, or false
+ // if there are too few.
+ if (action_count > upper_bound ||
+ (action_count == upper_bound && repeated_action_specified_)) {
+ too_many = true;
+ } else if (0 < action_count && action_count < lower_bound &&
+ !repeated_action_specified_) {
+ too_many = false;
+ } else {
+ return;
+ }
+
+ ::std::stringstream ss;
+ DescribeLocationTo(&ss);
+ ss << "Too " << (too_many ? "many" : "few")
+ << " actions specified in " << source_text() << "...\n"
+ << "Expected to be ";
+ cardinality().DescribeTo(&ss);
+ ss << ", but has " << (too_many ? "" : "only ")
+ << action_count << " WillOnce()"
+ << (action_count == 1 ? "" : "s");
+ if (repeated_action_specified_) {
+ ss << " and a WillRepeatedly()";
+ }
+ ss << ".";
+ Log(WARNING, ss.str(), -1); // -1 means "don't print stack trace".
+ }
+}
+
+// Implements the .Times() clause.
+void ExpectationBase::UntypedTimes(const Cardinality& a_cardinality) {
+ if (last_clause_ == kTimes) {
+ ExpectSpecProperty(false,
+ ".Times() cannot appear "
+ "more than once in an EXPECT_CALL().");
+ } else {
+ ExpectSpecProperty(last_clause_ < kTimes,
+ ".Times() cannot appear after "
+ ".InSequence(), .WillOnce(), .WillRepeatedly(), "
+ "or .RetiresOnSaturation().");
+ }
+ last_clause_ = kTimes;
+
+ SpecifyCardinality(a_cardinality);
+}
+
// Points to the implicit sequence introduced by a living InSequence
// object (if any) in the current thread or NULL.
ThreadLocal<Sequence*> g_gmock_implicit_sequence;
@@ -151,6 +257,233 @@ void ReportUninterestingCall(CallReaction reaction, const string& msg) {
}
}
+UntypedFunctionMockerBase::UntypedFunctionMockerBase()
+ : mock_obj_(NULL), name_("") {}
+
+UntypedFunctionMockerBase::~UntypedFunctionMockerBase() {}
+
+// Sets the mock object this mock method belongs to, and registers
+// this information in the global mock registry. Will be called
+// whenever an EXPECT_CALL() or ON_CALL() is executed on this mock
+// method.
+// L < g_gmock_mutex
+void UntypedFunctionMockerBase::RegisterOwner(const void* mock_obj) {
+ {
+ MutexLock l(&g_gmock_mutex);
+ mock_obj_ = mock_obj;
+ }
+ Mock::Register(mock_obj, this);
+}
+
+// Sets the mock object this mock method belongs to, and sets the name
+// of the mock function. Will be called upon each invocation of this
+// mock function.
+// L < g_gmock_mutex
+void UntypedFunctionMockerBase::SetOwnerAndName(
+ const void* mock_obj, const char* name) {
+ // We protect name_ under g_gmock_mutex in case this mock function
+ // is called from two threads concurrently.
+ MutexLock l(&g_gmock_mutex);
+ mock_obj_ = mock_obj;
+ name_ = name;
+}
+
+// Returns the name of the function being mocked. Must be called
+// after RegisterOwner() or SetOwnerAndName() has been called.
+// L < g_gmock_mutex
+const void* UntypedFunctionMockerBase::MockObject() const {
+ const void* mock_obj;
+ {
+ // We protect mock_obj_ under g_gmock_mutex in case this mock
+ // function is called from two threads concurrently.
+ MutexLock l(&g_gmock_mutex);
+ Assert(mock_obj_ != NULL, __FILE__, __LINE__,
+ "MockObject() must not be called before RegisterOwner() or "
+ "SetOwnerAndName() has been called.");
+ mock_obj = mock_obj_;
+ }
+ return mock_obj;
+}
+
+// Returns the name of this mock method. Must be called after
+// SetOwnerAndName() has been called.
+// L < g_gmock_mutex
+const char* UntypedFunctionMockerBase::Name() const {
+ const char* name;
+ {
+ // We protect name_ under g_gmock_mutex in case this mock
+ // function is called from two threads concurrently.
+ MutexLock l(&g_gmock_mutex);
+ Assert(name_ != NULL, __FILE__, __LINE__,
+ "Name() must not be called before SetOwnerAndName() has "
+ "been called.");
+ name = name_;
+ }
+ return name;
+}
+
+// Calculates the result of invoking this mock function with the given
+// arguments, prints it, and returns it. The caller is responsible
+// for deleting the result.
+// L < g_gmock_mutex
+const UntypedActionResultHolderBase*
+UntypedFunctionMockerBase::UntypedInvokeWith(const void* const untyped_args) {
+ if (untyped_expectations_.size() == 0) {
+ // No expectation is set on this mock method - we have an
+ // uninteresting call.
+
+ // We must get Google Mock's reaction on uninteresting calls
+ // made on this mock object BEFORE performing the action,
+ // because the action may DELETE the mock object and make the
+ // following expression meaningless.
+ const CallReaction reaction =
+ Mock::GetReactionOnUninterestingCalls(MockObject());
+
+ // True iff we need to print this call's arguments and return
+ // value. This definition must be kept in sync with
+ // the behavior of ReportUninterestingCall().
+ const bool need_to_report_uninteresting_call =
+ // If the user allows this uninteresting call, we print it
+ // only when he wants informational messages.
+ reaction == ALLOW ? LogIsVisible(INFO) :
+ // If the user wants this to be a warning, we print it only
+ // when he wants to see warnings.
+ reaction == WARN ? LogIsVisible(WARNING) :
+ // Otherwise, the user wants this to be an error, and we
+ // should always print detailed information in the error.
+ true;
+
+ if (!need_to_report_uninteresting_call) {
+ // Perform the action without printing the call information.
+ return this->UntypedPerformDefaultAction(untyped_args, "");
+ }
+
+ // Warns about the uninteresting call.
+ ::std::stringstream ss;
+ this->UntypedDescribeUninterestingCall(untyped_args, &ss);
+
+ // Calculates the function result.
+ const UntypedActionResultHolderBase* const result =
+ this->UntypedPerformDefaultAction(untyped_args, ss.str());
+
+ // Prints the function result.
+ if (result != NULL)
+ result->PrintAsActionResult(&ss);
+
+ ReportUninterestingCall(reaction, ss.str());
+ return result;
+ }
+
+ bool is_excessive = false;
+ ::std::stringstream ss;
+ ::std::stringstream why;
+ ::std::stringstream loc;
+ const void* untyped_action = NULL;
+
+ // The UntypedFindMatchingExpectation() function acquires and
+ // releases g_gmock_mutex.
+ const ExpectationBase* const untyped_expectation =
+ this->UntypedFindMatchingExpectation(
+ untyped_args, &untyped_action, &is_excessive,
+ &ss, &why);
+ const bool found = untyped_expectation != NULL;
+
+ // True iff we need to print the call's arguments and return value.
+ // This definition must be kept in sync with the uses of Expect()
+ // and Log() in this function.
+ const bool need_to_report_call = !found || is_excessive || LogIsVisible(INFO);
+ if (!need_to_report_call) {
+ // Perform the action without printing the call information.
+ return
+ untyped_action == NULL ?
+ this->UntypedPerformDefaultAction(untyped_args, "") :
+ this->UntypedPerformAction(untyped_action, untyped_args);
+ }
+
+ ss << " Function call: " << Name();
+ this->UntypedPrintArgs(untyped_args, &ss);
+
+ // In case the action deletes a piece of the expectation, we
+ // generate the message beforehand.
+ if (found && !is_excessive) {
+ untyped_expectation->DescribeLocationTo(&loc);
+ }
+
+ const UntypedActionResultHolderBase* const result =
+ untyped_action == NULL ?
+ this->UntypedPerformDefaultAction(untyped_args, ss.str()) :
+ this->UntypedPerformAction(untyped_action, untyped_args);
+ if (result != NULL)
+ result->PrintAsActionResult(&ss);
+ ss << "\n" << why.str();
+
+ if (!found) {
+ // No expectation matches this call - reports a failure.
+ Expect(false, NULL, -1, ss.str());
+ } else if (is_excessive) {
+ // We had an upper-bound violation and the failure message is in ss.
+ Expect(false, untyped_expectation->file(),
+ untyped_expectation->line(), ss.str());
+ } else {
+ // We had an expected call and the matching expectation is
+ // described in ss.
+ Log(INFO, loc.str() + ss.str(), 2);
+ }
+
+ return result;
+}
+
+// Returns an Expectation object that references and co-owns exp,
+// which must be an expectation on this mock function.
+Expectation UntypedFunctionMockerBase::GetHandleOf(ExpectationBase* exp) {
+ for (UntypedExpectations::const_iterator it =
+ untyped_expectations_.begin();
+ it != untyped_expectations_.end(); ++it) {
+ if (it->get() == exp) {
+ return Expectation(*it);
+ }
+ }
+
+ Assert(false, __FILE__, __LINE__, "Cannot find expectation.");
+ return Expectation();
+ // The above statement is just to make the code compile, and will
+ // never be executed.
+}
+
+// Verifies that all expectations on this mock function have been
+// satisfied. Reports one or more Google Test non-fatal failures
+// and returns false if not.
+// L >= g_gmock_mutex
+bool UntypedFunctionMockerBase::VerifyAndClearExpectationsLocked() {
+ g_gmock_mutex.AssertHeld();
+ bool expectations_met = true;
+ for (UntypedExpectations::const_iterator it =
+ untyped_expectations_.begin();
+ it != untyped_expectations_.end(); ++it) {
+ ExpectationBase* const untyped_expectation = it->get();
+ if (untyped_expectation->IsOverSaturated()) {
+ // There was an upper-bound violation. Since the error was
+ // already reported when it occurred, there is no need to do
+ // anything here.
+ expectations_met = false;
+ } else if (!untyped_expectation->IsSatisfied()) {
+ expectations_met = false;
+ ::std::stringstream ss;
+ ss << "Actual function call count doesn't match "
+ << untyped_expectation->source_text() << "...\n";
+ // No need to show the source file location of the expectation
+ // in the description, as the Expect() call that follows already
+ // takes care of it.
+ untyped_expectation->MaybeDescribeExtraMatcherTo(&ss);
+ untyped_expectation->DescribeCallCountTo(&ss);
+ Expect(false, untyped_expectation->file(),
+ untyped_expectation->line(), ss.str());
+ }
+ }
+ untyped_expectations_.clear();
+ return expectations_met;
+}
+
} // namespace internal
// Class Mock.
@@ -190,7 +523,6 @@ class MockObjectRegistry {
// object alive. Therefore we report any living object as test
// failure, unless the user explicitly asked us to ignore it.
~MockObjectRegistry() {
-
// "using ::std::cout;" doesn't work with Symbian's STLport, where cout is
// a macro.
diff --git a/testing/gmock/src/gmock.cc b/testing/gmock/src/gmock.cc
index f487265..700bcb2 100644
--- a/testing/gmock/src/gmock.cc
+++ b/testing/gmock/src/gmock.cc
@@ -29,8 +29,8 @@
//
// Author: wan@google.com (Zhanyong Wan)
-#include <gmock/gmock.h>
-#include <gmock/internal/gmock-port.h>
+#include "gmock/gmock.h"
+#include "gmock/internal/gmock-port.h"
namespace testing {
diff --git a/testing/gmock/src/gmock_main.cc b/testing/gmock/src/gmock_main.cc
index 0a3071b..3725ae7 100644
--- a/testing/gmock/src/gmock_main.cc
+++ b/testing/gmock/src/gmock_main.cc
@@ -30,8 +30,8 @@
// Author: wan@google.com (Zhanyong Wan)
#include <iostream>
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
// MS C++ compiler/linker has a bug on Windows (not on Windows CE), which
// causes a link error when _tmain is defined in a static library and UNICODE
diff --git a/testing/gmock/test/gmock-actions_test.cc b/testing/gmock/test/gmock-actions_test.cc
index 8391e5f..b3f8d52 100644
--- a/testing/gmock/test/gmock-actions_test.cc
+++ b/testing/gmock/test/gmock-actions_test.cc
@@ -33,14 +33,14 @@
//
// This file tests the built-in actions.
-#include <gmock/gmock-actions.h>
+#include "gmock/gmock-actions.h"
#include <algorithm>
#include <iterator>
#include <string>
-#include <gmock/gmock.h>
-#include <gmock/internal/gmock-port.h>
-#include <gtest/gtest.h>
-#include <gtest/gtest-spi.h>
+#include "gmock/gmock.h"
+#include "gmock/internal/gmock-port.h"
+#include "gtest/gtest.h"
+#include "gtest/gtest-spi.h"
namespace {
@@ -68,6 +68,8 @@ using testing::PolymorphicAction;
using testing::Return;
using testing::ReturnNull;
using testing::ReturnRef;
+using testing::ReturnRefOfCopy;
+using testing::SetArgPointee;
using testing::SetArgumentPointee;
#if !GTEST_OS_WINDOWS_MOBILE
@@ -332,8 +334,7 @@ class MyActionImpl : public ActionInterface<MyFunction> {
TEST(ActionInterfaceTest, CanBeImplementedByDefiningPerform) {
MyActionImpl my_action_impl;
-
- EXPECT_FALSE(my_action_impl.IsDoDefault());
+ (void)my_action_impl;
}
TEST(ActionInterfaceTest, MakeAction) {
@@ -584,6 +585,30 @@ TEST(ReturnRefTest, IsCovariant) {
EXPECT_EQ(&derived, &a.Perform(make_tuple()));
}
+// Tests that ReturnRefOfCopy(v) works for reference types.
+TEST(ReturnRefOfCopyTest, WorksForReference) {
+ int n = 42;
+ const Action<const int&()> ret = ReturnRefOfCopy(n);
+
+ EXPECT_NE(&n, &ret.Perform(make_tuple()));
+ EXPECT_EQ(42, ret.Perform(make_tuple()));
+
+ n = 43;
+ EXPECT_NE(&n, &ret.Perform(make_tuple()));
+ EXPECT_EQ(42, ret.Perform(make_tuple()));
+}
+
+// Tests that ReturnRefOfCopy(v) is covariant.
+TEST(ReturnRefOfCopyTest, IsCovariant) {
+ Base base;
+ Derived derived;
+ Action<Base&()> a = ReturnRefOfCopy(base);
+ EXPECT_NE(&base, &a.Perform(make_tuple()));
+
+ a = ReturnRefOfCopy(derived);
+ EXPECT_NE(&derived, &a.Perform(make_tuple()));
+}
+
// Tests that DoDefault() does the default action for the mock method.
class MyClass {};
@@ -669,6 +694,162 @@ TEST(DoDefaultTest, CannotBeUsedInOnCall) {
}, "DoDefault() cannot be used in ON_CALL()");
}
+// Tests that SetArgPointee<N>(v) sets the variable pointed to by
+// the N-th (0-based) argument to v.
+TEST(SetArgPointeeTest, SetsTheNthPointee) {
+ typedef void MyFunction(bool, int*, char*);
+ Action<MyFunction> a = SetArgPointee<1>(2);
+
+ int n = 0;
+ char ch = '\0';
+ a.Perform(make_tuple(true, &n, &ch));
+ EXPECT_EQ(2, n);
+ EXPECT_EQ('\0', ch);
+
+ a = SetArgPointee<2>('a');
+ n = 0;
+ ch = '\0';
+ a.Perform(make_tuple(true, &n, &ch));
+ EXPECT_EQ(0, n);
+ EXPECT_EQ('a', ch);
+}
+
+// Tests that SetArgPointee<N>() accepts a string literal.
+TEST(SetArgPointeeTest, AcceptsStringLiteral) {
+ typedef void MyFunction(bool, std::string*, const char**);
+ Action<MyFunction> a = SetArgPointee<1>("hi");
+ std::string str;
+ const char* ptr = NULL;
+ a.Perform(make_tuple(true, &str, &ptr));
+ EXPECT_EQ("hi", str);
+ EXPECT_TRUE(ptr == NULL);
+
+ a = SetArgPointee<2>("world");
+ str = "";
+ a.Perform(make_tuple(true, &str, &ptr));
+ EXPECT_EQ("", str);
+ EXPECT_STREQ("world", ptr);
+}
+
+// Tests that SetArgPointee<N>() accepts a char pointer.
+TEST(SetArgPointeeTest, AcceptsCharPointer) {
+ typedef void MyFunction(bool, std::string*, const char**);
+ const char* const hi = "hi";
+ Action<MyFunction> a = SetArgPointee<1>(hi);
+ std::string str;
+ const char* ptr = NULL;
+ a.Perform(make_tuple(true, &str, &ptr));
+ EXPECT_EQ("hi", str);
+ EXPECT_TRUE(ptr == NULL);
+
+ char world_array[] = "world";
+ char* const world = world_array;
+ a = SetArgPointee<2>(world);
+ str = "";
+ a.Perform(make_tuple(true, &str, &ptr));
+ EXPECT_EQ("", str);
+ EXPECT_EQ(world, ptr);
+}
+
+#if GTEST_HAS_PROTOBUF_
+
+// Tests that SetArgPointee<N>(proto_buffer) sets the v1 protobuf
+// variable pointed to by the N-th (0-based) argument to proto_buffer.
+TEST(SetArgPointeeTest, SetsTheNthPointeeOfProtoBufferType) {
+ TestMessage* const msg = new TestMessage;
+ msg->set_member("yes");
+ TestMessage orig_msg;
+ orig_msg.CopyFrom(*msg);
+
+ Action<void(bool, TestMessage*)> a = SetArgPointee<1>(*msg);
+ // SetArgPointee<N>(proto_buffer) makes a copy of proto_buffer
+ // s.t. the action works even when the original proto_buffer has
+ // died. We ensure this behavior by deleting msg before using the
+ // action.
+ delete msg;
+
+ TestMessage dest;
+ EXPECT_FALSE(orig_msg.Equals(dest));
+ a.Perform(make_tuple(true, &dest));
+ EXPECT_TRUE(orig_msg.Equals(dest));
+}
+
+// Tests that SetArgPointee<N>(proto_buffer) sets the
+// ::ProtocolMessage variable pointed to by the N-th (0-based)
+// argument to proto_buffer.
+TEST(SetArgPointeeTest, SetsTheNthPointeeOfProtoBufferBaseType) {
+ TestMessage* const msg = new TestMessage;
+ msg->set_member("yes");
+ TestMessage orig_msg;
+ orig_msg.CopyFrom(*msg);
+
+ Action<void(bool, ::ProtocolMessage*)> a = SetArgPointee<1>(*msg);
+ // SetArgPointee<N>(proto_buffer) makes a copy of proto_buffer
+ // s.t. the action works even when the original proto_buffer has
+ // died. We ensure this behavior by deleting msg before using the
+ // action.
+ delete msg;
+
+ TestMessage dest;
+ ::ProtocolMessage* const dest_base = &dest;
+ EXPECT_FALSE(orig_msg.Equals(dest));
+ a.Perform(make_tuple(true, dest_base));
+ EXPECT_TRUE(orig_msg.Equals(dest));
+}
+
+// Tests that SetArgPointee<N>(proto2_buffer) sets the v2
+// protobuf variable pointed to by the N-th (0-based) argument to
+// proto2_buffer.
+TEST(SetArgPointeeTest, SetsTheNthPointeeOfProto2BufferType) {
+ using testing::internal::FooMessage;
+ FooMessage* const msg = new FooMessage;
+ msg->set_int_field(2);
+ msg->set_string_field("hi");
+ FooMessage orig_msg;
+ orig_msg.CopyFrom(*msg);
+
+ Action<void(bool, FooMessage*)> a = SetArgPointee<1>(*msg);
+ // SetArgPointee<N>(proto2_buffer) makes a copy of
+ // proto2_buffer s.t. the action works even when the original
+ // proto2_buffer has died. We ensure this behavior by deleting msg
+ // before using the action.
+ delete msg;
+
+ FooMessage dest;
+ dest.set_int_field(0);
+ a.Perform(make_tuple(true, &dest));
+ EXPECT_EQ(2, dest.int_field());
+ EXPECT_EQ("hi", dest.string_field());
+}
+
+// Tests that SetArgPointee<N>(proto2_buffer) sets the
+// proto2::Message variable pointed to by the N-th (0-based) argument
+// to proto2_buffer.
+TEST(SetArgPointeeTest, SetsTheNthPointeeOfProto2BufferBaseType) {
+ using testing::internal::FooMessage;
+ FooMessage* const msg = new FooMessage;
+ msg->set_int_field(2);
+ msg->set_string_field("hi");
+ FooMessage orig_msg;
+ orig_msg.CopyFrom(*msg);
+
+ Action<void(bool, ::proto2::Message*)> a = SetArgPointee<1>(*msg);
+ // SetArgPointee<N>(proto2_buffer) makes a copy of
+ // proto2_buffer s.t. the action works even when the original
+ // proto2_buffer has died. We ensure this behavior by deleting msg
+ // before using the action.
+ delete msg;
+
+ FooMessage dest;
+ dest.set_int_field(0);
+ ::proto2::Message* const dest_base = &dest;
+ a.Perform(make_tuple(true, dest_base));
+ EXPECT_EQ(2, dest.int_field());
+ EXPECT_EQ("hi", dest.string_field());
+}
+
+#endif // GTEST_HAS_PROTOBUF_
+
// Tests that SetArgumentPointee<N>(v) sets the variable pointed to by
// the N-th (0-based) argument to v.
TEST(SetArgumentPointeeTest, SetsTheNthPointee) {
diff --git a/testing/gmock/test/gmock-cardinalities_test.cc b/testing/gmock/test/gmock-cardinalities_test.cc
index f6a9491..64815e5 100644
--- a/testing/gmock/test/gmock-cardinalities_test.cc
+++ b/testing/gmock/test/gmock-cardinalities_test.cc
@@ -33,9 +33,9 @@
//
// This file tests the built-in cardinalities.
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-#include <gtest/gtest-spi.h>
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+#include "gtest/gtest-spi.h"
namespace {
diff --git a/testing/gmock/test/gmock-generated-actions_test.cc b/testing/gmock/test/gmock-generated-actions_test.cc
index 3c076d7..982be1b 100644
--- a/testing/gmock/test/gmock-generated-actions_test.cc
+++ b/testing/gmock/test/gmock-generated-actions_test.cc
@@ -33,13 +33,13 @@
//
// This file tests the built-in actions generated by a script.
-#include <gmock/gmock-generated-actions.h>
+#include "gmock/gmock-generated-actions.h"
#include <functional>
#include <sstream>
#include <string>
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
namespace testing {
namespace gmock_generated_actions_test {
@@ -58,7 +58,7 @@ using testing::DoAll;
using testing::Invoke;
using testing::Return;
using testing::ReturnNew;
-using testing::SetArgumentPointee;
+using testing::SetArgPointee;
using testing::StaticAssertTypeEq;
using testing::Unused;
using testing::WithArgs;
@@ -419,7 +419,7 @@ TEST(WithArgsTest, VoidAction) {
// Tests DoAll(a1, a2).
TEST(DoAllTest, TwoActions) {
int n = 0;
- Action<int(int*)> a = DoAll(SetArgumentPointee<0>(1), // NOLINT
+ Action<int(int*)> a = DoAll(SetArgPointee<0>(1), // NOLINT
Return(2));
EXPECT_EQ(2, a.Perform(make_tuple(&n)));
EXPECT_EQ(1, n);
@@ -428,8 +428,8 @@ TEST(DoAllTest, TwoActions) {
// Tests DoAll(a1, a2, a3).
TEST(DoAllTest, ThreeActions) {
int m = 0, n = 0;
- Action<int(int*, int*)> a = DoAll(SetArgumentPointee<0>(1), // NOLINT
- SetArgumentPointee<1>(2),
+ Action<int(int*, int*)> a = DoAll(SetArgPointee<0>(1), // NOLINT
+ SetArgPointee<1>(2),
Return(3));
EXPECT_EQ(3, a.Perform(make_tuple(&m, &n)));
EXPECT_EQ(1, m);
@@ -441,9 +441,9 @@ TEST(DoAllTest, FourActions) {
int m = 0, n = 0;
char ch = '\0';
Action<int(int*, int*, char*)> a = // NOLINT
- DoAll(SetArgumentPointee<0>(1),
- SetArgumentPointee<1>(2),
- SetArgumentPointee<2>('a'),
+ DoAll(SetArgPointee<0>(1),
+ SetArgPointee<1>(2),
+ SetArgPointee<2>('a'),
Return(3));
EXPECT_EQ(3, a.Perform(make_tuple(&m, &n, &ch)));
EXPECT_EQ(1, m);
@@ -456,10 +456,10 @@ TEST(DoAllTest, FiveActions) {
int m = 0, n = 0;
char a = '\0', b = '\0';
Action<int(int*, int*, char*, char*)> action = // NOLINT
- DoAll(SetArgumentPointee<0>(1),
- SetArgumentPointee<1>(2),
- SetArgumentPointee<2>('a'),
- SetArgumentPointee<3>('b'),
+ DoAll(SetArgPointee<0>(1),
+ SetArgPointee<1>(2),
+ SetArgPointee<2>('a'),
+ SetArgPointee<3>('b'),
Return(3));
EXPECT_EQ(3, action.Perform(make_tuple(&m, &n, &a, &b)));
EXPECT_EQ(1, m);
@@ -473,11 +473,11 @@ TEST(DoAllTest, SixActions) {
int m = 0, n = 0;
char a = '\0', b = '\0', c = '\0';
Action<int(int*, int*, char*, char*, char*)> action = // NOLINT
- DoAll(SetArgumentPointee<0>(1),
- SetArgumentPointee<1>(2),
- SetArgumentPointee<2>('a'),
- SetArgumentPointee<3>('b'),
- SetArgumentPointee<4>('c'),
+ DoAll(SetArgPointee<0>(1),
+ SetArgPointee<1>(2),
+ SetArgPointee<2>('a'),
+ SetArgPointee<3>('b'),
+ SetArgPointee<4>('c'),
Return(3));
EXPECT_EQ(3, action.Perform(make_tuple(&m, &n, &a, &b, &c)));
EXPECT_EQ(1, m);
@@ -492,12 +492,12 @@ TEST(DoAllTest, SevenActions) {
int m = 0, n = 0;
char a = '\0', b = '\0', c = '\0', d = '\0';
Action<int(int*, int*, char*, char*, char*, char*)> action = // NOLINT
- DoAll(SetArgumentPointee<0>(1),
- SetArgumentPointee<1>(2),
- SetArgumentPointee<2>('a'),
- SetArgumentPointee<3>('b'),
- SetArgumentPointee<4>('c'),
- SetArgumentPointee<5>('d'),
+ DoAll(SetArgPointee<0>(1),
+ SetArgPointee<1>(2),
+ SetArgPointee<2>('a'),
+ SetArgPointee<3>('b'),
+ SetArgPointee<4>('c'),
+ SetArgPointee<5>('d'),
Return(3));
EXPECT_EQ(3, action.Perform(make_tuple(&m, &n, &a, &b, &c, &d)));
EXPECT_EQ(1, m);
@@ -514,13 +514,13 @@ TEST(DoAllTest, EightActions) {
char a = '\0', b = '\0', c = '\0', d = '\0', e = '\0';
Action<int(int*, int*, char*, char*, char*, char*, // NOLINT
char*)> action =
- DoAll(SetArgumentPointee<0>(1),
- SetArgumentPointee<1>(2),
- SetArgumentPointee<2>('a'),
- SetArgumentPointee<3>('b'),
- SetArgumentPointee<4>('c'),
- SetArgumentPointee<5>('d'),
- SetArgumentPointee<6>('e'),
+ DoAll(SetArgPointee<0>(1),
+ SetArgPointee<1>(2),
+ SetArgPointee<2>('a'),
+ SetArgPointee<3>('b'),
+ SetArgPointee<4>('c'),
+ SetArgPointee<5>('d'),
+ SetArgPointee<6>('e'),
Return(3));
EXPECT_EQ(3, action.Perform(make_tuple(&m, &n, &a, &b, &c, &d, &e)));
EXPECT_EQ(1, m);
@@ -538,14 +538,14 @@ TEST(DoAllTest, NineActions) {
char a = '\0', b = '\0', c = '\0', d = '\0', e = '\0', f = '\0';
Action<int(int*, int*, char*, char*, char*, char*, // NOLINT
char*, char*)> action =
- DoAll(SetArgumentPointee<0>(1),
- SetArgumentPointee<1>(2),
- SetArgumentPointee<2>('a'),
- SetArgumentPointee<3>('b'),
- SetArgumentPointee<4>('c'),
- SetArgumentPointee<5>('d'),
- SetArgumentPointee<6>('e'),
- SetArgumentPointee<7>('f'),
+ DoAll(SetArgPointee<0>(1),
+ SetArgPointee<1>(2),
+ SetArgPointee<2>('a'),
+ SetArgPointee<3>('b'),
+ SetArgPointee<4>('c'),
+ SetArgPointee<5>('d'),
+ SetArgPointee<6>('e'),
+ SetArgPointee<7>('f'),
Return(3));
EXPECT_EQ(3, action.Perform(make_tuple(&m, &n, &a, &b, &c, &d, &e, &f)));
EXPECT_EQ(1, m);
@@ -565,15 +565,15 @@ TEST(DoAllTest, TenActions) {
char e = '\0', f = '\0', g = '\0';
Action<int(int*, int*, char*, char*, char*, char*, // NOLINT
char*, char*, char*)> action =
- DoAll(SetArgumentPointee<0>(1),
- SetArgumentPointee<1>(2),
- SetArgumentPointee<2>('a'),
- SetArgumentPointee<3>('b'),
- SetArgumentPointee<4>('c'),
- SetArgumentPointee<5>('d'),
- SetArgumentPointee<6>('e'),
- SetArgumentPointee<7>('f'),
- SetArgumentPointee<8>('g'),
+ DoAll(SetArgPointee<0>(1),
+ SetArgPointee<1>(2),
+ SetArgPointee<2>('a'),
+ SetArgPointee<3>('b'),
+ SetArgPointee<4>('c'),
+ SetArgPointee<5>('d'),
+ SetArgPointee<6>('e'),
+ SetArgPointee<7>('f'),
+ SetArgPointee<8>('g'),
Return(3));
EXPECT_EQ(3, action.Perform(make_tuple(&m, &n, &a, &b, &c, &d, &e, &f, &g)));
EXPECT_EQ(1, m);
diff --git a/testing/gmock/test/gmock-generated-function-mockers_test.cc b/testing/gmock/test/gmock-generated-function-mockers_test.cc
index 5d839c4..d000386 100644
--- a/testing/gmock/test/gmock-generated-function-mockers_test.cc
+++ b/testing/gmock/test/gmock-generated-function-mockers_test.cc
@@ -33,12 +33,12 @@
//
// This file tests the function mocker classes.
-#include <gmock/gmock-generated-function-mockers.h>
+#include "gmock/gmock-generated-function-mockers.h"
#include <map>
#include <string>
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
#if GTEST_OS_WINDOWS
// MSDN says the header file to be included for STDMETHOD is BaseTyps.h but
diff --git a/testing/gmock/test/gmock-generated-internal-utils_test.cc b/testing/gmock/test/gmock-generated-internal-utils_test.cc
index 13b4c5c..1156c7d 100644
--- a/testing/gmock/test/gmock-generated-internal-utils_test.cc
+++ b/testing/gmock/test/gmock-generated-internal-utils_test.cc
@@ -33,9 +33,9 @@
//
// This file tests the internal utilities.
-#include <gmock/internal/gmock-generated-internal-utils.h>
-#include <gmock/internal/gmock-internal-utils.h>
-#include <gtest/gtest.h>
+#include "gmock/internal/gmock-generated-internal-utils.h"
+#include "gmock/internal/gmock-internal-utils.h"
+#include "gtest/gtest.h"
namespace {
diff --git a/testing/gmock/test/gmock-generated-matchers_test.cc b/testing/gmock/test/gmock-generated-matchers_test.cc
index eebca8a..2a7f498 100644
--- a/testing/gmock/test/gmock-generated-matchers_test.cc
+++ b/testing/gmock/test/gmock-generated-matchers_test.cc
@@ -31,7 +31,7 @@
//
// This file tests the built-in matchers generated by a script.
-#include <gmock/gmock-generated-matchers.h>
+#include "gmock/gmock-generated-matchers.h"
#include <list>
#include <map>
@@ -41,9 +41,9 @@
#include <utility>
#include <vector>
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-#include <gtest/gtest-spi.h>
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+#include "gtest/gtest-spi.h"
namespace {
@@ -72,6 +72,7 @@ using testing::MatchResultListener;
using testing::Ne;
using testing::Not;
using testing::Pointee;
+using testing::PrintToString;
using testing::Ref;
using testing::StaticAssertTypeEq;
using testing::StrEq;
@@ -242,7 +243,7 @@ Matcher<tuple<char, int> > LessThan() {
TEST(ArgsTest, ExplainsMatchResultWithInnerExplanation) {
const Matcher<tuple<char, int, int> > m = Args<0, 2>(LessThan());
- EXPECT_EQ("whose fields (#0, #2) are ('a' (97), 42), "
+ EXPECT_EQ("whose fields (#0, #2) are ('a' (97, 0x61), 42), "
"where the first value is 55 more than the second",
Explain(m, make_tuple('a', 42, 42)));
EXPECT_EQ("whose fields (#0, #2) are ('\\0', 43)",
@@ -603,9 +604,8 @@ TEST(MatcherMacroTest, Works) {
EXPECT_EQ("", Explain(m, 7));
}
-// Tests explaining match result in a MATCHER* macro.
-
-MATCHER(IsEven2, "is even") {
+// This also tests that the description string can reference 'negation'.
+MATCHER(IsEven2, negation ? "is odd" : "is even") {
if ((arg % 2) == 0) {
// Verifies that we can stream to result_listener, a listener
// supplied by the MATCHER macro implicitly.
@@ -617,7 +617,11 @@ MATCHER(IsEven2, "is even") {
}
}
-MATCHER_P2(EqSumOf, x, y, "") {
+// This also tests that the description string can reference matcher
+// parameters.
+MATCHER_P2(EqSumOf, x, y,
+ string(negation ? "doesn't equal" : "equals") + " the sum of " +
+ PrintToString(x) + " and " + PrintToString(y)) {
if (arg == (x + y)) {
*result_listener << "OK";
return true;
@@ -631,6 +635,19 @@ MATCHER_P2(EqSumOf, x, y, "") {
}
}
+// Tests that the matcher description can reference 'negation' and the
+// matcher parameters.
+TEST(MatcherMacroTest, DescriptionCanReferenceNegationAndParameters) {
+ const Matcher<int> m1 = IsEven2();
+ EXPECT_EQ("is even", Describe(m1));
+ EXPECT_EQ("is odd", DescribeNegation(m1));
+
+ const Matcher<int> m2 = EqSumOf(5, 9);
+ EXPECT_EQ("equals the sum of 5 and 9", Describe(m2));
+ EXPECT_EQ("doesn't equal the sum of 5 and 9", DescribeNegation(m2));
+}
+
+// Tests explaining match result in a MATCHER* macro.
TEST(MatcherMacroTest, CanExplainMatchResult) {
const Matcher<int> m1 = IsEven2();
EXPECT_EQ("OK", Explain(m1, 4));
@@ -641,29 +658,6 @@ TEST(MatcherMacroTest, CanExplainMatchResult) {
EXPECT_EQ("diff == -1", Explain(m2, 4));
}
-// Tests that the description string supplied to MATCHER() must be
-// valid.
-
-MATCHER(HasBadDescription, "Invalid%") {
- // Uses arg to suppress "unused parameter" warning.
- return arg==arg;
-}
-
-TEST(MatcherMacroTest,
- CreatingMatcherWithBadDescriptionGeneratesNonfatalFailure) {
- EXPECT_NONFATAL_FAILURE(
- HasBadDescription(),
- "Syntax error at index 7 in matcher description \"Invalid%\": "
- "use \"%%\" instead of \"%\" to print \"%\".");
-}
-
-MATCHER(HasGoodDescription, "good") { return arg==arg; }
-
-TEST(MatcherMacroTest, AcceptsValidDescription) {
- const Matcher<int> m = HasGoodDescription();
- EXPECT_EQ("good", Describe(m));
-}
-
// Tests that the body of MATCHER() can reference the type of the
// value being matched.
@@ -723,29 +717,6 @@ TEST(MatcherPMacroTest, Works) {
EXPECT_EQ("", Explain(m, 5));
}
-// Tests that the description string supplied to MATCHER_P() must be
-// valid.
-
-MATCHER_P(HasBadDescription1, n, "not %(m)s good") {
- return arg > n;
-}
-
-TEST(MatcherPMacroTest,
- CreatingMatcherWithBadDescriptionGeneratesNonfatalFailure) {
- EXPECT_NONFATAL_FAILURE(
- HasBadDescription1(2),
- "Syntax error at index 6 in matcher description \"not %(m)s good\": "
- "\"m\" is an invalid parameter name.");
-}
-
-
-MATCHER_P(HasGoodDescription1, n, "good %(n)s") { return arg==arg; }
-
-TEST(MatcherPMacroTest, AcceptsValidDescription) {
- const Matcher<int> m = HasGoodDescription1(5);
- EXPECT_EQ("good 5", Describe(m));
-}
-
// Tests that the description is calculated correctly from the matcher name.
MATCHER_P(_is_Greater_Than32and_, n, "") { return arg > 32 && arg > n; }
@@ -789,32 +760,6 @@ TEST(MatcherPMacroTest, WorksWhenExplicitlyInstantiatedWithReference) {
}
-// Tests that the description string supplied to MATCHER_Pn() must be
-// valid.
-
-MATCHER_P2(HasBadDescription2, m, n, "not %(good") {
- return arg > m + n;
-}
-
-TEST(MatcherPnMacroTest,
- CreatingMatcherWithBadDescriptionGeneratesNonfatalFailure) {
- EXPECT_NONFATAL_FAILURE(
- HasBadDescription2(3, 4),
- "Syntax error at index 4 in matcher description \"not %(good\": "
- "an interpolation must end with \")s\", but \"%(good\" does not.");
-}
-
-MATCHER_P2(HasComplexDescription, foo, bar,
- "is as complex as %(foo)s %(bar)s (i.e. %(*)s or %%%(foo)s!)") {
- return arg==arg;
-}
-
-TEST(MatcherPnMacroTest, AcceptsValidDescription) {
- Matcher<int> m = HasComplexDescription(100, "ducks");
- EXPECT_EQ("is as complex as 100 \"ducks\" (i.e. (100, \"ducks\") or %100!)",
- Describe(m));
-}
-
// Tests that the body of MATCHER_Pn() can reference the parameter
// types.
diff --git a/testing/gmock/test/gmock-internal-utils_test.cc b/testing/gmock/test/gmock-internal-utils_test.cc
index 4309f7c..5b0e804 100644
--- a/testing/gmock/test/gmock-internal-utils_test.cc
+++ b/testing/gmock/test/gmock-internal-utils_test.cc
@@ -33,16 +33,16 @@
//
// This file tests the internal utilities.
-#include <gmock/internal/gmock-internal-utils.h>
+#include "gmock/internal/gmock-internal-utils.h"
#include <stdlib.h>
#include <map>
#include <string>
#include <sstream>
#include <vector>
-#include <gmock/gmock.h>
-#include <gmock/internal/gmock-port.h>
-#include <gtest/gtest.h>
-#include <gtest/gtest-spi.h>
+#include "gmock/gmock.h"
+#include "gmock/internal/gmock-port.h"
+#include "gtest/gtest.h"
+#include "gtest/gtest-spi.h"
#if GTEST_OS_CYGWIN
#include <sys/types.h> // For ssize_t. NOLINT
@@ -375,7 +375,7 @@ TEST_F(LogIsVisibleTest, WorksWhenVerbosityIsWarning) {
EXPECT_TRUE(LogIsVisible(WARNING));
}
-#if GTEST_HAS_STREAM_REDIRECTION_
+#if GTEST_HAS_STREAM_REDIRECTION
// Tests the Log() function.
@@ -458,7 +458,7 @@ TEST(LogTest, OnlyWarningsArePrintedWhenVerbosityIsInvalid) {
TestLogWithSeverity("invalid", WARNING, true);
}
-#endif // GTEST_HAS_STREAM_REDIRECTION_
+#endif // GTEST_HAS_STREAM_REDIRECTION
TEST(TypeTraitsTest, true_type) {
EXPECT_TRUE(true_type::value);
@@ -495,7 +495,7 @@ TEST(TypeTraitsTest, remove_reference) {
EXPECT_TRUE((type_equals<double*, remove_reference<double*>::type>::value));
}
-#if GTEST_HAS_STREAM_REDIRECTION_
+#if GTEST_HAS_STREAM_REDIRECTION
// Verifies that Log() behaves correctly for the given verbosity level
// and log severity.
@@ -572,7 +572,7 @@ TEST(OnCallTest, LogsAnythingArgument) {
HasSubstr("ON_CALL(mock, TestMethodArg(_)"));
}
-#endif // GTEST_HAS_STREAM_REDIRECTION_
+#endif // GTEST_HAS_STREAM_REDIRECTION
// Tests StlContainerView.
diff --git a/testing/gmock/test/gmock-matchers_test.cc b/testing/gmock/test/gmock-matchers_test.cc
index 3b151db..deff9b2 100644
--- a/testing/gmock/test/gmock-matchers_test.cc
+++ b/testing/gmock/test/gmock-matchers_test.cc
@@ -33,7 +33,7 @@
//
// This file tests some commonly used argument matchers.
-#include <gmock/gmock-matchers.h>
+#include "gmock/gmock-matchers.h"
#include <string.h>
#include <functional>
@@ -45,18 +45,14 @@
#include <string>
#include <utility>
#include <vector>
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-#include <gtest/gtest-spi.h>
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+#include "gtest/gtest-spi.h"
namespace testing {
namespace internal {
-string FormatMatcherDescriptionSyntaxError(const char* description,
- const char* error_pos);
-int GetParamIndex(const char* param_names[], const string& param_name);
string JoinAsTuple(const Strings& fields);
-bool SkipPrefix(const char* prefix, const char** pstr);
} // namespace internal
namespace gmock_matchers_test {
@@ -126,21 +122,14 @@ using testing::_;
using testing::internal::DummyMatchResultListener;
using testing::internal::ExplainMatchFailureTupleTo;
using testing::internal::FloatingEqMatcher;
-using testing::internal::FormatMatcherDescriptionSyntaxError;
-using testing::internal::GetParamIndex;
-using testing::internal::Interpolation;
-using testing::internal::Interpolations;
+using testing::internal::FormatMatcherDescription;
+using testing::internal::IsReadableTypeName;
using testing::internal::JoinAsTuple;
using testing::internal::RE;
-using testing::internal::SkipPrefix;
using testing::internal::StreamMatchResultListener;
using testing::internal::String;
using testing::internal::StringMatchResultListener;
using testing::internal::Strings;
-using testing::internal::ValidateMatcherDescription;
-using testing::internal::kInvalidInterpolation;
-using testing::internal::kPercentInterpolation;
-using testing::internal::kTupleInterpolation;
using testing::internal::linked_ptr;
using testing::internal::scoped_ptr;
using testing::internal::string;
@@ -176,6 +165,14 @@ Matcher<int> GreaterThan(int n) {
return MakeMatcher(new GreaterThanMatcher(n));
}
+string OfType(const string& type_name) {
+#if GTEST_HAS_RTTI
+ return " (of type " + type_name + ")";
+#else
+ return "";
+#endif
+}
+
// Returns the description of the given matcher.
template <typename T>
string Describe(const Matcher<T>& m) {
@@ -1869,6 +1866,16 @@ TEST(NotTest, NotMatcherSafelyCastsMonomorphicMatchers) {
Matcher<int&> m3 = Not(m);
}
+// Helper to allow easy testing of AllOf matchers with num parameters.
+void AllOfMatches(int num, const Matcher<int>& m) {
+ SCOPED_TRACE(Describe(m));
+ EXPECT_TRUE(m.Matches(0));
+ for (int i = 1; i <= num; ++i) {
+ EXPECT_FALSE(m.Matches(i));
+ }
+ EXPECT_TRUE(m.Matches(num + 1));
+}
+
// Tests that AllOf(m1, ..., mn) matches any value that matches all of
// the given matchers.
TEST(AllOfTest, MatchesWhenAllMatch) {
@@ -1896,6 +1903,23 @@ TEST(AllOfTest, MatchesWhenAllMatch) {
EXPECT_TRUE(m.Matches(0));
EXPECT_TRUE(m.Matches(1));
EXPECT_FALSE(m.Matches(3));
+
+ // The following tests for varying number of sub-matchers. Due to the way
+ // the sub-matchers are handled it is enough to test every sub-matcher once
+ // with sub-matchers using the same matcher type. Varying matcher types are
+ // checked for above.
+ AllOfMatches(2, AllOf(Ne(1), Ne(2)));
+ AllOfMatches(3, AllOf(Ne(1), Ne(2), Ne(3)));
+ AllOfMatches(4, AllOf(Ne(1), Ne(2), Ne(3), Ne(4)));
+ AllOfMatches(5, AllOf(Ne(1), Ne(2), Ne(3), Ne(4), Ne(5)));
+ AllOfMatches(6, AllOf(Ne(1), Ne(2), Ne(3), Ne(4), Ne(5), Ne(6)));
+ AllOfMatches(7, AllOf(Ne(1), Ne(2), Ne(3), Ne(4), Ne(5), Ne(6), Ne(7)));
+ AllOfMatches(8, AllOf(Ne(1), Ne(2), Ne(3), Ne(4), Ne(5), Ne(6), Ne(7),
+ Ne(8)));
+ AllOfMatches(9, AllOf(Ne(1), Ne(2), Ne(3), Ne(4), Ne(5), Ne(6), Ne(7),
+ Ne(8), Ne(9)));
+ AllOfMatches(10, AllOf(Ne(1), Ne(2), Ne(3), Ne(4), Ne(5), Ne(6), Ne(7), Ne(8),
+ Ne(9), Ne(10)));
}
// Tests that AllOf(m1, ..., mn) describes itself properly.
@@ -2018,6 +2042,16 @@ TEST(AllOfTest, ExplainsResult) {
EXPECT_EQ("which is 5 less than 20", Explain(m, 15));
}
+// Helper to allow easy testing of AnyOf matchers with num parameters.
+void AnyOfMatches(int num, const Matcher<int>& m) {
+ SCOPED_TRACE(Describe(m));
+ EXPECT_FALSE(m.Matches(0));
+ for (int i = 1; i <= num; ++i) {
+ EXPECT_TRUE(m.Matches(i));
+ }
+ EXPECT_FALSE(m.Matches(num + 1));
+}
+
// Tests that AnyOf(m1, ..., mn) matches any value that matches at
// least one of the given matchers.
TEST(AnyOfTest, MatchesWhenAnyMatches) {
@@ -2045,6 +2079,20 @@ TEST(AnyOfTest, MatchesWhenAnyMatches) {
EXPECT_TRUE(m.Matches(11));
EXPECT_TRUE(m.Matches(3));
EXPECT_FALSE(m.Matches(2));
+
+ // The following tests for varying number of sub-matchers. Due to the way
+ // the sub-matchers are handled it is enough to test every sub-matcher once
+ // with sub-matchers using the same matcher type. Varying matcher types are
+ // checked for above.
+ AnyOfMatches(2, AnyOf(1, 2));
+ AnyOfMatches(3, AnyOf(1, 2, 3));
+ AnyOfMatches(4, AnyOf(1, 2, 3, 4));
+ AnyOfMatches(5, AnyOf(1, 2, 3, 4, 5));
+ AnyOfMatches(6, AnyOf(1, 2, 3, 4, 5, 6));
+ AnyOfMatches(7, AnyOf(1, 2, 3, 4, 5, 6, 7));
+ AnyOfMatches(8, AnyOf(1, 2, 3, 4, 5, 6, 7, 8));
+ AnyOfMatches(9, AnyOf(1, 2, 3, 4, 5, 6, 7, 8, 9));
+ AnyOfMatches(10, AnyOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10));
}
// Tests that AnyOf(m1, ..., mn) describes itself properly.
@@ -2344,7 +2392,7 @@ TEST(MatcherAssertionTest, WorksWhenMatcherIsSatisfied) {
TEST(MatcherAssertionTest, WorksWhenMatcherIsNotSatisfied) {
// 'n' must be static as it is used in an EXPECT_FATAL_FAILURE(),
// which cannot reference auto variables.
- static int n;
+ static unsigned short n; // NOLINT
n = 5;
// VC++ prior to version 8.0 SP1 has a bug where it will not see any
@@ -2355,13 +2403,13 @@ TEST(MatcherAssertionTest, WorksWhenMatcherIsNotSatisfied) {
EXPECT_FATAL_FAILURE(ASSERT_THAT(n, ::testing::Gt(10)),
"Value of: n\n"
"Expected: is > 10\n"
- " Actual: 5");
+ " Actual: 5" + OfType("unsigned short"));
n = 0;
EXPECT_NONFATAL_FAILURE(
EXPECT_THAT(n, ::testing::AllOf(::testing::Le(7), ::testing::Ge(5))),
"Value of: n\n"
"Expected: (is <= 7) and (is >= 5)\n"
- " Actual: 0");
+ " Actual: 0" + OfType("unsigned short"));
}
// Tests that ASSERT_THAT() and EXPECT_THAT() work when the argument
@@ -2377,7 +2425,7 @@ TEST(MatcherAssertionTest, WorksForByRefArguments) {
"Expected: does not reference the variable @");
// Tests the "Actual" part.
EXPECT_FATAL_FAILURE(ASSERT_THAT(n, ::testing::Not(::testing::Ref(n))),
- "Actual: 0, which is located @");
+ "Actual: 0" + OfType("int") + ", which is located @");
}
#if !GTEST_OS_SYMBIAN
@@ -2400,12 +2448,16 @@ TEST(MatcherAssertionTest, WorksForMonomorphicMatcher) {
Matcher<const string&> ends_with_ok = EndsWith("ok");
ASSERT_THAT("book", ends_with_ok);
-
+ const string bad = "bad";
+ EXPECT_NONFATAL_FAILURE(EXPECT_THAT(bad, ends_with_ok),
+ "Value of: bad\n"
+ "Expected: ends with \"ok\"\n"
+ " Actual: \"bad\"");
Matcher<int> is_greater_than_5 = Gt(5);
EXPECT_NONFATAL_FAILURE(EXPECT_THAT(5, is_greater_than_5),
"Value of: 5\n"
"Expected: is > 5\n"
- " Actual: 5");
+ " Actual: 5" + OfType("int"));
}
#endif // !GTEST_OS_SYMBIAN
@@ -2729,16 +2781,16 @@ TEST(PointeeTest, CanExplainMatchResult) {
EXPECT_EQ("", Explain(m, static_cast<const string*>(NULL)));
- const Matcher<int*> m2 = Pointee(GreaterThan(1));
- int n = 3;
- EXPECT_EQ("which points to 3, which is 2 more than 1",
+ const Matcher<long*> m2 = Pointee(GreaterThan(1)); // NOLINT
+ long n = 3; // NOLINT
+ EXPECT_EQ("which points to 3" + OfType("long") + ", which is 2 more than 1",
Explain(m2, &n));
}
TEST(PointeeTest, AlwaysExplainsPointee) {
const Matcher<int*> m = Pointee(0);
int n = 42;
- EXPECT_EQ("which points to 42", Explain(m, &n));
+ EXPECT_EQ("which points to 42" + OfType("int"), Explain(m, &n));
}
// An uncopyable class.
@@ -2875,10 +2927,12 @@ TEST(FieldTest, CanExplainMatchResult) {
AStruct a;
a.x = 1;
- EXPECT_EQ("whose given field is 1", Explain(m, a));
+ EXPECT_EQ("whose given field is 1" + OfType("int"), Explain(m, a));
m = Field(&AStruct::x, GreaterThan(0));
- EXPECT_EQ("whose given field is 1, which is 1 more than 0", Explain(m, a));
+ EXPECT_EQ(
+ "whose given field is 1" + OfType("int") + ", which is 1 more than 0",
+ Explain(m, a));
}
// Tests that Field() works when the argument is a pointer to const.
@@ -2945,11 +2999,12 @@ TEST(FieldForPointerTest, CanExplainMatchResult) {
AStruct a;
a.x = 1;
EXPECT_EQ("", Explain(m, static_cast<const AStruct*>(NULL)));
- EXPECT_EQ("which points to an object whose given field is 1", Explain(m, &a));
+ EXPECT_EQ("which points to an object whose given field is 1" + OfType("int"),
+ Explain(m, &a));
m = Field(&AStruct::x, GreaterThan(0));
- EXPECT_EQ("which points to an object whose given field is 1, "
- "which is 1 more than 0", Explain(m, &a));
+ EXPECT_EQ("which points to an object whose given field is 1" + OfType("int") +
+ ", which is 1 more than 0", Explain(m, &a));
}
// A user-defined class for testing Property().
@@ -3079,10 +3134,12 @@ TEST(PropertyTest, CanExplainMatchResult) {
AClass a;
a.set_n(1);
- EXPECT_EQ("whose given property is 1", Explain(m, a));
+ EXPECT_EQ("whose given property is 1" + OfType("int"), Explain(m, a));
m = Property(&AClass::n, GreaterThan(0));
- EXPECT_EQ("whose given property is 1, which is 1 more than 0", Explain(m, a));
+ EXPECT_EQ(
+ "whose given property is 1" + OfType("int") + ", which is 1 more than 0",
+ Explain(m, a));
}
// Tests that Property() works when the argument is a pointer to const.
@@ -3159,12 +3216,14 @@ TEST(PropertyForPointerTest, CanExplainMatchResult) {
AClass a;
a.set_n(1);
EXPECT_EQ("", Explain(m, static_cast<const AClass*>(NULL)));
- EXPECT_EQ("which points to an object whose given property is 1",
- Explain(m, &a));
+ EXPECT_EQ(
+ "which points to an object whose given property is 1" + OfType("int"),
+ Explain(m, &a));
m = Property(&AClass::n, GreaterThan(0));
- EXPECT_EQ("which points to an object whose given property is 1, "
- "which is 1 more than 0", Explain(m, &a));
+ EXPECT_EQ("which points to an object whose given property is 1" +
+ OfType("int") + ", which is 1 more than 0",
+ Explain(m, &a));
}
// Tests ResultOf.
@@ -3195,12 +3254,12 @@ int IntFunction(int input) { return input == 42 ? 80 : 90; }
TEST(ResultOfTest, CanExplainMatchResult) {
Matcher<int> matcher = ResultOf(&IntFunction, Ge(85));
- EXPECT_EQ("which is mapped by the given callable to 90",
+ EXPECT_EQ("which is mapped by the given callable to 90" + OfType("int"),
Explain(matcher, 36));
matcher = ResultOf(&IntFunction, GreaterThan(85));
- EXPECT_EQ("which is mapped by the given callable to 90, "
- "which is 5 more than 85", Explain(matcher, 36));
+ EXPECT_EQ("which is mapped by the given callable to 90" + OfType("int") +
+ ", which is 5 more than 85", Explain(matcher, 36));
}
// Tests that ResultOf(f, ...) compiles and works as expected when f(x)
@@ -3214,9 +3273,9 @@ TEST(ResultOfTest, WorksForNonReferenceResults) {
// Tests that ResultOf(f, ...) compiles and works as expected when f(x)
// returns a reference to non-const.
-double& DoubleFunction(double& input) { return input; }
+double& DoubleFunction(double& input) { return input; } // NOLINT
-Uncopyable& RefUncopyableFunction(Uncopyable& obj) {
+Uncopyable& RefUncopyableFunction(Uncopyable& obj) { // NOLINT
return obj;
}
@@ -3265,7 +3324,7 @@ TEST(ResultOfTest, WorksForCompatibleMatcherTypes) {
// a NULL function pointer.
TEST(ResultOfDeathTest, DiesOnNullFunctionPointers) {
EXPECT_DEATH_IF_SUPPORTED(
- ResultOf(static_cast<string(*)(int)>(NULL), Eq(string("foo"))),
+ ResultOf(static_cast<string(*)(int dummy)>(NULL), Eq(string("foo"))),
"NULL function pointer is passed into ResultOf\\(\\)\\.");
}
@@ -3643,174 +3702,29 @@ TEST(ContainerEqExtraTest, CopiesNativeArrayParameter) {
EXPECT_THAT(a1, m);
}
-// Tests GetParamIndex().
+// Tests IsReadableTypeName().
-TEST(GetParamIndexTest, WorksForEmptyParamList) {
- const char* params[] = { NULL };
- EXPECT_EQ(kTupleInterpolation, GetParamIndex(params, "*"));
- EXPECT_EQ(kInvalidInterpolation, GetParamIndex(params, "a"));
+TEST(IsReadableTypeNameTest, ReturnsTrueForShortNames) {
+ EXPECT_TRUE(IsReadableTypeName("int"));
+ EXPECT_TRUE(IsReadableTypeName("const unsigned char*"));
+ EXPECT_TRUE(IsReadableTypeName("MyMap<int, void*>"));
+ EXPECT_TRUE(IsReadableTypeName("void (*)(int, bool)"));
}
-TEST(GetParamIndexTest, RecognizesStar) {
- const char* params[] = { "a", "b", NULL };
- EXPECT_EQ(kTupleInterpolation, GetParamIndex(params, "*"));
+TEST(IsReadableTypeNameTest, ReturnsTrueForLongNonTemplateNonFunctionNames) {
+ EXPECT_TRUE(IsReadableTypeName("my_long_namespace::MyClassName"));
+ EXPECT_TRUE(IsReadableTypeName("int [5][6][7][8][9][10][11]"));
+ EXPECT_TRUE(IsReadableTypeName("my_namespace::MyOuterClass::MyInnerClass"));
}
-TEST(GetParamIndexTest, RecognizesKnownParam) {
- const char* params[] = { "foo", "bar", NULL };
- EXPECT_EQ(0, GetParamIndex(params, "foo"));
- EXPECT_EQ(1, GetParamIndex(params, "bar"));
+TEST(IsReadableTypeNameTest, ReturnsFalseForLongTemplateNames) {
+ EXPECT_FALSE(
+ IsReadableTypeName("basic_string<char, std::char_traits<char> >"));
+ EXPECT_FALSE(IsReadableTypeName("std::vector<int, std::alloc_traits<int> >"));
}
-TEST(GetParamIndexTest, RejectsUnknownParam) {
- const char* params[] = { "foo", "bar", NULL };
- EXPECT_EQ(kInvalidInterpolation, GetParamIndex(params, "foobar"));
-}
-
-// Tests SkipPrefix().
-
-TEST(SkipPrefixTest, SkipsWhenPrefixMatches) {
- const char* const str = "hello";
-
- const char* p = str;
- EXPECT_TRUE(SkipPrefix("", &p));
- EXPECT_EQ(str, p);
-
- p = str;
- EXPECT_TRUE(SkipPrefix("hell", &p));
- EXPECT_EQ(str + 4, p);
-}
-
-TEST(SkipPrefixTest, DoesNotSkipWhenPrefixDoesNotMatch) {
- const char* const str = "world";
-
- const char* p = str;
- EXPECT_FALSE(SkipPrefix("W", &p));
- EXPECT_EQ(str, p);
-
- p = str;
- EXPECT_FALSE(SkipPrefix("world!", &p));
- EXPECT_EQ(str, p);
-}
-
-// Tests FormatMatcherDescriptionSyntaxError().
-TEST(FormatMatcherDescriptionSyntaxErrorTest, FormatsCorrectly) {
- const char* const description = "hello%world";
- EXPECT_EQ("Syntax error at index 5 in matcher description \"hello%world\": ",
- FormatMatcherDescriptionSyntaxError(description, description + 5));
-}
-
-// Tests ValidateMatcherDescription().
-
-TEST(ValidateMatcherDescriptionTest, AcceptsEmptyDescription) {
- const char* params[] = { "foo", "bar", NULL };
- EXPECT_THAT(ValidateMatcherDescription(params, ""),
- ElementsAre());
-}
-
-TEST(ValidateMatcherDescriptionTest,
- AcceptsNonEmptyDescriptionWithNoInterpolation) {
- const char* params[] = { "foo", "bar", NULL };
- EXPECT_THAT(ValidateMatcherDescription(params, "a simple description"),
- ElementsAre());
-}
-
-// The MATCHER*() macros trigger warning C4100 (unreferenced formal
-// parameter) in MSVC with -W4. Unfortunately they cannot be fixed in
-// the macro definition, as the warnings are generated when the macro
-// is expanded and macro expansion cannot contain #pragma. Therefore
-// we suppress them here.
-#ifdef _MSC_VER
-#pragma warning(push)
-#pragma warning(disable:4100)
-#endif
-
-// We use MATCHER_P3() to define a matcher for testing
-// ValidateMatcherDescription(); otherwise we'll end up with much
-// plumbing code. This is not circular as
-// ValidateMatcherDescription() doesn't affect whether the matcher
-// matches a value or not.
-MATCHER_P3(EqInterpolation, start, end, index, "equals Interpolation%(*)s") {
- return arg.start_pos == start && arg.end_pos == end &&
- arg.param_index == index;
-}
-
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif
-
-TEST(ValidateMatcherDescriptionTest, AcceptsPercentInterpolation) {
- const char* params[] = { "foo", NULL };
- const char* const desc = "one %%";
- EXPECT_THAT(ValidateMatcherDescription(params, desc),
- ElementsAre(EqInterpolation(desc + 4, desc + 6,
- kPercentInterpolation)));
-}
-
-TEST(ValidateMatcherDescriptionTest, AcceptsTupleInterpolation) {
- const char* params[] = { "foo", "bar", "baz", NULL };
- const char* const desc = "%(*)s after";
- EXPECT_THAT(ValidateMatcherDescription(params, desc),
- ElementsAre(EqInterpolation(desc, desc + 5,
- kTupleInterpolation)));
-}
-
-TEST(ValidateMatcherDescriptionTest, AcceptsParamInterpolation) {
- const char* params[] = { "foo", "bar", "baz", NULL };
- const char* const desc = "a %(bar)s.";
- EXPECT_THAT(ValidateMatcherDescription(params, desc),
- ElementsAre(EqInterpolation(desc + 2, desc + 9, 1)));
-}
-
-TEST(ValidateMatcherDescriptionTest, AcceptsMultiplenterpolations) {
- const char* params[] = { "foo", "bar", "baz", NULL };
- const char* const desc = "%(baz)s %(foo)s %(bar)s";
- EXPECT_THAT(ValidateMatcherDescription(params, desc),
- ElementsAre(EqInterpolation(desc, desc + 7, 2),
- EqInterpolation(desc + 8, desc + 15, 0),
- EqInterpolation(desc + 16, desc + 23, 1)));
-}
-
-TEST(ValidateMatcherDescriptionTest, AcceptsRepeatedParams) {
- const char* params[] = { "foo", "bar", NULL };
- const char* const desc = "%(foo)s and %(foo)s";
- EXPECT_THAT(ValidateMatcherDescription(params, desc),
- ElementsAre(EqInterpolation(desc, desc + 7, 0),
- EqInterpolation(desc + 12, desc + 19, 0)));
-}
-
-TEST(ValidateMatcherDescriptionTest, RejectsUnknownParam) {
- const char* params[] = { "a", "bar", NULL };
- EXPECT_NONFATAL_FAILURE({
- EXPECT_THAT(ValidateMatcherDescription(params, "%(foo)s"),
- ElementsAre());
- }, "Syntax error at index 2 in matcher description \"%(foo)s\": "
- "\"foo\" is an invalid parameter name.");
-}
-
-TEST(ValidateMatcherDescriptionTest, RejectsUnfinishedParam) {
- const char* params[] = { "a", "bar", NULL };
- EXPECT_NONFATAL_FAILURE({
- EXPECT_THAT(ValidateMatcherDescription(params, "%(foo)"),
- ElementsAre());
- }, "Syntax error at index 0 in matcher description \"%(foo)\": "
- "an interpolation must end with \")s\", but \"%(foo)\" does not.");
-
- EXPECT_NONFATAL_FAILURE({
- EXPECT_THAT(ValidateMatcherDescription(params, "x%(a"),
- ElementsAre());
- }, "Syntax error at index 1 in matcher description \"x%(a\": "
- "an interpolation must end with \")s\", but \"%(a\" does not.");
-}
-
-TEST(ValidateMatcherDescriptionTest, RejectsSinglePercent) {
- const char* params[] = { "a", NULL };
- EXPECT_NONFATAL_FAILURE({
- EXPECT_THAT(ValidateMatcherDescription(params, "a %."),
- ElementsAre());
- }, "Syntax error at index 2 in matcher description \"a %.\": "
- "use \"%%\" instead of \"%\" to print \"%\".");
-
+TEST(IsReadableTypeNameTest, ReturnsFalseForLongFunctionTypeNames) {
+ EXPECT_FALSE(IsReadableTypeName("void (&)(int, bool, char, float)"));
}
// Tests JoinAsTuple().
@@ -3839,118 +3753,21 @@ TEST(JoinAsTupleTest, JoinsTenTuple) {
TEST(FormatMatcherDescriptionTest, WorksForEmptyDescription) {
EXPECT_EQ("is even",
- FormatMatcherDescription("IsEven", "", Interpolations(),
- Strings()));
+ FormatMatcherDescription(false, "IsEven", Strings()));
+ EXPECT_EQ("not (is even)",
+ FormatMatcherDescription(true, "IsEven", Strings()));
const char* params[] = { "5" };
EXPECT_EQ("equals 5",
- FormatMatcherDescription("Equals", "", Interpolations(),
+ FormatMatcherDescription(false, "Equals",
Strings(params, params + 1)));
const char* params2[] = { "5", "8" };
EXPECT_EQ("is in range (5, 8)",
- FormatMatcherDescription("IsInRange", "", Interpolations(),
+ FormatMatcherDescription(false, "IsInRange",
Strings(params2, params2 + 2)));
}
-TEST(FormatMatcherDescriptionTest, WorksForDescriptionWithNoInterpolation) {
- EXPECT_EQ("is positive",
- FormatMatcherDescription("Gt0", "is positive", Interpolations(),
- Strings()));
-
- const char* params[] = { "5", "6" };
- EXPECT_EQ("is negative",
- FormatMatcherDescription("Lt0", "is negative", Interpolations(),
- Strings(params, params + 2)));
-}
-
-TEST(FormatMatcherDescriptionTest,
- WorksWhenDescriptionStartsWithInterpolation) {
- const char* params[] = { "5" };
- const char* const desc = "%(num)s times bigger";
- const Interpolation interp[] = { Interpolation(desc, desc + 7, 0) };
- EXPECT_EQ("5 times bigger",
- FormatMatcherDescription("Foo", desc,
- Interpolations(interp, interp + 1),
- Strings(params, params + 1)));
-}
-
-TEST(FormatMatcherDescriptionTest,
- WorksWhenDescriptionEndsWithInterpolation) {
- const char* params[] = { "5", "6" };
- const char* const desc = "is bigger than %(y)s";
- const Interpolation interp[] = { Interpolation(desc + 15, desc + 20, 1) };
- EXPECT_EQ("is bigger than 6",
- FormatMatcherDescription("Foo", desc,
- Interpolations(interp, interp + 1),
- Strings(params, params + 2)));
-}
-
-TEST(FormatMatcherDescriptionTest,
- WorksWhenDescriptionStartsAndEndsWithInterpolation) {
- const char* params[] = { "5", "6" };
- const char* const desc = "%(x)s <= arg <= %(y)s";
- const Interpolation interp[] = {
- Interpolation(desc, desc + 5, 0),
- Interpolation(desc + 16, desc + 21, 1)
- };
- EXPECT_EQ("5 <= arg <= 6",
- FormatMatcherDescription("Foo", desc,
- Interpolations(interp, interp + 2),
- Strings(params, params + 2)));
-}
-
-TEST(FormatMatcherDescriptionTest,
- WorksWhenDescriptionDoesNotStartOrEndWithInterpolation) {
- const char* params[] = { "5.2" };
- const char* const desc = "has %(x)s cents";
- const Interpolation interp[] = { Interpolation(desc + 4, desc + 9, 0) };
- EXPECT_EQ("has 5.2 cents",
- FormatMatcherDescription("Foo", desc,
- Interpolations(interp, interp + 1),
- Strings(params, params + 1)));
-}
-
-TEST(FormatMatcherDescriptionTest,
- WorksWhenDescriptionContainsMultipleInterpolations) {
- const char* params[] = { "5", "6" };
- const char* const desc = "in %(*)s or [%(x)s, %(y)s]";
- const Interpolation interp[] = {
- Interpolation(desc + 3, desc + 8, kTupleInterpolation),
- Interpolation(desc + 13, desc + 18, 0),
- Interpolation(desc + 20, desc + 25, 1)
- };
- EXPECT_EQ("in (5, 6) or [5, 6]",
- FormatMatcherDescription("Foo", desc,
- Interpolations(interp, interp + 3),
- Strings(params, params + 2)));
-}
-
-TEST(FormatMatcherDescriptionTest,
- WorksWhenDescriptionContainsRepeatedParams) {
- const char* params[] = { "9" };
- const char* const desc = "in [-%(x)s, %(x)s]";
- const Interpolation interp[] = {
- Interpolation(desc + 5, desc + 10, 0),
- Interpolation(desc + 12, desc + 17, 0)
- };
- EXPECT_EQ("in [-9, 9]",
- FormatMatcherDescription("Foo", desc,
- Interpolations(interp, interp + 2),
- Strings(params, params + 1)));
-}
-
-TEST(FormatMatcherDescriptionTest,
- WorksForDescriptionWithInvalidInterpolation) {
- const char* params[] = { "9" };
- const char* const desc = "> %(x)s %(x)";
- const Interpolation interp[] = { Interpolation(desc + 2, desc + 7, 0) };
- EXPECT_EQ("> 9 %(x)",
- FormatMatcherDescription("Foo", desc,
- Interpolations(interp, interp + 1),
- Strings(params, params + 1)));
-}
-
// Tests PolymorphicMatcher::mutable_impl().
TEST(PolymorphicMatcherTest, CanAccessMutableImpl) {
PolymorphicMatcher<DivisibleByImpl> m(DivisibleByImpl(42));
@@ -3979,8 +3796,8 @@ TEST(MatcherTupleTest, ExplainsMatchFailure) {
make_tuple(2, 'b'), &ss2);
EXPECT_EQ(" Expected arg #0: is > 5\n"
" Actual: 2, which is 3 less than 5\n"
- " Expected arg #1: is equal to 'a' (97)\n"
- " Actual: 'b' (98)\n",
+ " Expected arg #1: is equal to 'a' (97, 0x61)\n"
+ " Actual: 'b' (98, 0x62)\n",
ss2.str()); // Failed match where both arguments need explanation.
stringstream ss3;
@@ -4000,7 +3817,7 @@ TEST(EachTest, ExplainsMatchResultCorrectly) {
Matcher<set<int> > m = Each(2);
EXPECT_EQ("", Explain(m, a));
- Matcher<const int(&)[1]> n = Each(1);
+ Matcher<const int(&)[1]> n = Each(1); // NOLINT
const int b[1] = { 1 };
EXPECT_EQ("", Explain(n, b));
diff --git a/testing/gmock/test/gmock-more-actions_test.cc b/testing/gmock/test/gmock-more-actions_test.cc
index b3b17d3..43ff55d 100644
--- a/testing/gmock/test/gmock-more-actions_test.cc
+++ b/testing/gmock/test/gmock-more-actions_test.cc
@@ -33,13 +33,14 @@
//
// This file tests the built-in actions in gmock-more-actions.h.
-#include <gmock/gmock-more-actions.h>
+#include "gmock/gmock-more-actions.h"
#include <functional>
#include <sstream>
#include <string>
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+#include "gtest/internal/gtest-linked_ptr.h"
namespace testing {
namespace gmock_more_actions_test {
@@ -57,13 +58,15 @@ using testing::DeleteArg;
using testing::Invoke;
using testing::Return;
using testing::ReturnArg;
+using testing::ReturnPointee;
using testing::SaveArg;
+using testing::SaveArgPointee;
using testing::SetArgReferee;
-using testing::SetArgumentPointee;
using testing::StaticAssertTypeEq;
using testing::Unused;
using testing::WithArg;
using testing::WithoutArgs;
+using testing::internal::linked_ptr;
// For suppressing compiler warnings on conversion possibly losing precision.
inline short Short(short n) { return n; } // NOLINT
@@ -506,6 +509,30 @@ TEST(SaveArgActionTest, WorksForCompatibleType) {
EXPECT_EQ('a', result);
}
+TEST(SaveArgPointeeActionTest, WorksForSameType) {
+ int result = 0;
+ const int value = 5;
+ const Action<void(const int*)> a1 = SaveArgPointee<0>(&result);
+ a1.Perform(make_tuple(&value));
+ EXPECT_EQ(5, result);
+}
+
+TEST(SaveArgPointeeActionTest, WorksForCompatibleType) {
+ int result = 0;
+ char value = 'a';
+ const Action<void(bool, char*)> a1 = SaveArgPointee<1>(&result);
+ a1.Perform(make_tuple(true, &value));
+ EXPECT_EQ('a', result);
+}
+
+TEST(SaveArgPointeeActionTest, WorksForLinkedPtr) {
+ int result = 0;
+ linked_ptr<int> value(new int(5));
+ const Action<void(linked_ptr<int>)> a1 = SaveArgPointee<0>(&result);
+ a1.Perform(make_tuple(value));
+ EXPECT_EQ(5, result);
+}
+
TEST(SetArgRefereeActionTest, WorksForSameType) {
int value = 0;
const Action<void(int&)> a1 = SetArgReferee<0>(1);
@@ -664,5 +691,14 @@ TEST(SetArrayArgumentTest, SetsTheNthArrayWithIteratorArgument) {
EXPECT_EQ(letters, s);
}
+TEST(ReturnPointeeTest, Works) {
+ int n = 42;
+ const Action<int()> a = ReturnPointee(&n);
+ EXPECT_EQ(42, a.Perform(make_tuple()));
+
+ n = 43;
+ EXPECT_EQ(43, a.Perform(make_tuple()));
+}
+
} // namespace gmock_generated_actions_test
} // namespace testing
diff --git a/testing/gmock/test/gmock-nice-strict_test.cc b/testing/gmock/test/gmock-nice-strict_test.cc
index 0e52450..e334418 100644
--- a/testing/gmock/test/gmock-nice-strict_test.cc
+++ b/testing/gmock/test/gmock-nice-strict_test.cc
@@ -29,12 +29,12 @@
//
// Author: wan@google.com (Zhanyong Wan)
-#include <gmock/gmock-generated-nice-strict.h>
+#include "gmock/gmock-generated-nice-strict.h"
#include <string>
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-#include <gtest/gtest-spi.h>
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+#include "gtest/gtest-spi.h"
// This must not be defined inside the ::testing namespace, or it will
// clash with ::testing::Mock.
@@ -57,10 +57,10 @@ using testing::HasSubstr;
using testing::NiceMock;
using testing::StrictMock;
-#if GTEST_HAS_STREAM_REDIRECTION_
+#if GTEST_HAS_STREAM_REDIRECTION
using testing::internal::CaptureStdout;
using testing::internal::GetCapturedStdout;
-#endif // GTEST_HAS_STREAM_REDIRECTION_
+#endif
// Defines some mock classes needed by the tests.
@@ -107,7 +107,7 @@ class MockBar {
GTEST_DISALLOW_COPY_AND_ASSIGN_(MockBar);
};
-#if GTEST_HAS_STREAM_REDIRECTION_
+#if GTEST_HAS_STREAM_REDIRECTION
// Tests that a nice mock generates no warning for uninteresting calls.
TEST(NiceMockTest, NoWarningForUninterestingCall) {
@@ -151,7 +151,7 @@ TEST(NiceMockTest, InfoForUninterestingCall) {
GMOCK_FLAG(verbose) = saved_flag;
}
-#endif // GTEST_HAS_STREAM_REDIRECTION_
+#endif // GTEST_HAS_STREAM_REDIRECTION
// Tests that a nice mock allows expected calls.
TEST(NiceMockTest, AllowsExpectedCall) {
diff --git a/testing/gmock/test/gmock-port_test.cc b/testing/gmock/test/gmock-port_test.cc
index a84eb9e..d6a8d44 100644
--- a/testing/gmock/test/gmock-port_test.cc
+++ b/testing/gmock/test/gmock-port_test.cc
@@ -33,8 +33,8 @@
//
// This file tests the internal cross-platform support utilities.
-#include <gmock/internal/gmock-port.h>
-#include <gtest/gtest.h>
+#include "gmock/internal/gmock-port.h"
+#include "gtest/gtest.h"
// NOTE: if this file is left without tests for some reason, put a dummy
// test here to make references to symbols in the gtest library and avoid
diff --git a/testing/gmock/test/gmock-spec-builders_test.cc b/testing/gmock/test/gmock-spec-builders_test.cc
index ff30f02..aea5228 100644
--- a/testing/gmock/test/gmock-spec-builders_test.cc
+++ b/testing/gmock/test/gmock-spec-builders_test.cc
@@ -33,16 +33,17 @@
//
// This file tests the spec builder syntax.
-#include <gmock/gmock-spec-builders.h>
+#include "gmock/gmock-spec-builders.h"
#include <ostream> // NOLINT
#include <sstream>
#include <string>
-#include <gmock/gmock.h>
-#include <gmock/internal/gmock-port.h>
-#include <gtest/gtest.h>
-#include <gtest/gtest-spi.h>
+#include "gmock/gmock.h"
+#include "gmock/internal/gmock-port.h"
+#include "gtest/gtest.h"
+#include "gtest/gtest-spi.h"
+#include "gtest/internal/gtest-port.h"
namespace testing {
namespace internal {
@@ -88,6 +89,7 @@ using testing::Ne;
using testing::Return;
using testing::Sequence;
using testing::internal::ExpectationTester;
+using testing::internal::FormatFileLocation;
using testing::internal::g_gmock_mutex;
using testing::internal::kErrorVerbosity;
using testing::internal::kInfoVerbosity;
@@ -95,11 +97,39 @@ using testing::internal::kWarningVerbosity;
using testing::internal::String;
using testing::internal::string;
-#if GTEST_HAS_STREAM_REDIRECTION_
+#if GTEST_HAS_STREAM_REDIRECTION
using testing::HasSubstr;
using testing::internal::CaptureStdout;
using testing::internal::GetCapturedStdout;
-#endif // GTEST_HAS_STREAM_REDIRECTION_
+#endif
+
+class Incomplete;
+
+class MockIncomplete {
+ public:
+ // This line verifies that a mock method can take a by-reference
+ // argument of an incomplete type.
+ MOCK_METHOD1(ByRefFunc, void(const Incomplete& x));
+};
+
+// Tells Google Mock how to print a value of type Incomplete.
+void PrintTo(const Incomplete& x, ::std::ostream* os);
+
+TEST(MockMethodTest, CanInstantiateWithIncompleteArgType) {
+ // Even though this mock class contains a mock method that takes
+ // by-reference an argument whose type is incomplete, we can still
+ // use the mock, as long as Google Mock knows how to print the
+ // argument.
+ MockIncomplete incomplete;
+ EXPECT_CALL(incomplete, ByRefFunc(_))
+ .Times(AnyNumber());
+}
+
+// The definition of the printer for the argument type doesn't have to
+// be visible where the mock is used.
+void PrintTo(const Incomplete& /* x */, ::std::ostream* os) {
+ *os << "incomplete";
+}
class Result {};
@@ -518,7 +548,7 @@ TEST(ExpectCallSyntaxTest, DefaultCardinalityIsOnce) {
}, "to be called once");
}
-#if GTEST_HAS_STREAM_REDIRECTION_
+#if GTEST_HAS_STREAM_REDIRECTION
// Tests that Google Mock doesn't print a warning when the number of
// WillOnce() is adequate.
@@ -643,7 +673,7 @@ TEST(ExpectCallSyntaxTest, WarnsOnTooFewActions) {
b.DoB();
}
-#endif // GTEST_HAS_STREAM_REDIRECTION_
+#endif // GTEST_HAS_STREAM_REDIRECTION
// Tests the semantics of ON_CALL().
@@ -797,7 +827,20 @@ TEST(ExpectCallTest, NthMatchTakesNthAction) {
EXPECT_EQ(3, b.DoB());
}
-#if GTEST_HAS_STREAM_REDIRECTION_
+// Tests that the WillRepeatedly() action is taken when the WillOnce(...)
+// list is exhausted.
+TEST(ExpectCallTest, TakesRepeatedActionWhenWillListIsExhausted) {
+ MockB b;
+ EXPECT_CALL(b, DoB())
+ .WillOnce(Return(1))
+ .WillRepeatedly(Return(2));
+
+ EXPECT_EQ(1, b.DoB());
+ EXPECT_EQ(2, b.DoB());
+ EXPECT_EQ(2, b.DoB());
+}
+
+#if GTEST_HAS_STREAM_REDIRECTION
// Tests that the default action is taken when the WillOnce(...) list is
// exhausted and there is no WillRepeatedly().
@@ -832,21 +875,34 @@ TEST(ExpectCallTest, TakesDefaultActionWhenWillListIsExhausted) {
" - returning default value."));
}
-#endif // GTEST_HAS_STREAM_REDIRECTION_
-
-// Tests that the WillRepeatedly() action is taken when the WillOnce(...)
-// list is exhausted.
-TEST(ExpectCallTest, TakesRepeatedActionWhenWillListIsExhausted) {
+TEST(FunctionMockerTest, ReportsExpectCallLocationForExhausedActions) {
MockB b;
- EXPECT_CALL(b, DoB())
- .WillOnce(Return(1))
- .WillRepeatedly(Return(2));
+ std::string expect_call_location = FormatFileLocation(__FILE__, __LINE__ + 1);
+ EXPECT_CALL(b, DoB()).Times(AnyNumber()).WillOnce(Return(1));
EXPECT_EQ(1, b.DoB());
- EXPECT_EQ(2, b.DoB());
- EXPECT_EQ(2, b.DoB());
+
+ CaptureStdout();
+ EXPECT_EQ(0, b.DoB());
+ const String output = GetCapturedStdout();
+ // The warning message should contain the call location.
+ EXPECT_PRED_FORMAT2(IsSubstring, expect_call_location, output);
+}
+
+TEST(FunctionMockerTest, ReportsDefaultActionLocationOfUninterestingCalls) {
+ std::string on_call_location;
+ CaptureStdout();
+ {
+ MockB b;
+ on_call_location = FormatFileLocation(__FILE__, __LINE__ + 1);
+ ON_CALL(b, DoB(_)).WillByDefault(Return(0));
+ b.DoB(0);
+ }
+ EXPECT_PRED_FORMAT2(IsSubstring, on_call_location, GetCapturedStdout());
}
+#endif // GTEST_HAS_STREAM_REDIRECTION
+
// Tests that an uninteresting call performs the default action.
TEST(UninterestingCallTest, DoesDefaultAction) {
// When there is an ON_CALL() statement, the action specified by it
@@ -1299,12 +1355,33 @@ TEST(SequenceTest, Retirement) {
TEST(ExpectationTest, ConstrutorsWork) {
MockA a;
Expectation e1; // Default ctor.
- Expectation e2 = EXPECT_CALL(a, DoA(1)); // Ctor from EXPECT_CALL.
- Expectation e3 = e2; // Copy ctor.
+
+ // Ctor from various forms of EXPECT_CALL.
+ Expectation e2 = EXPECT_CALL(a, DoA(2));
+ Expectation e3 = EXPECT_CALL(a, DoA(3)).With(_);
+ {
+ Sequence s;
+ Expectation e4 = EXPECT_CALL(a, DoA(4)).Times(1);
+ Expectation e5 = EXPECT_CALL(a, DoA(5)).InSequence(s);
+ }
+ Expectation e6 = EXPECT_CALL(a, DoA(6)).After(e2);
+ Expectation e7 = EXPECT_CALL(a, DoA(7)).WillOnce(Return());
+ Expectation e8 = EXPECT_CALL(a, DoA(8)).WillRepeatedly(Return());
+ Expectation e9 = EXPECT_CALL(a, DoA(9)).RetiresOnSaturation();
+
+ Expectation e10 = e2; // Copy ctor.
EXPECT_THAT(e1, Ne(e2));
- EXPECT_THAT(e2, Eq(e3));
- a.DoA(1);
+ EXPECT_THAT(e2, Eq(e10));
+
+ a.DoA(2);
+ a.DoA(3);
+ a.DoA(4);
+ a.DoA(5);
+ a.DoA(6);
+ a.DoA(7);
+ a.DoA(8);
+ a.DoA(9);
}
TEST(ExpectationTest, AssignmentWorks) {
@@ -1802,7 +1879,7 @@ class VerboseFlagPreservingFixture : public testing::Test {
GTEST_DISALLOW_COPY_AND_ASSIGN_(VerboseFlagPreservingFixture);
};
-#if GTEST_HAS_STREAM_REDIRECTION_
+#if GTEST_HAS_STREAM_REDIRECTION
// Tests that an uninteresting mock function call generates a warning
// containing the stack trace.
@@ -1855,7 +1932,7 @@ TEST(FunctionCallMessageTest, UninterestingCallPrintsArgumentsAndReturnValue) {
"Uninteresting mock function call - returning directly\\.\n"
" Function call: VoidMethod"
"\\(false, 5, \"Hi\", NULL, @.+ "
- "Printable, 4-byte object <0000 0000>\\)"));
+ "Printable, 4-byte object <00-00 00-00>\\)"));
// A void function has no return value to print.
}
@@ -1979,7 +2056,7 @@ TEST_F(GMockVerboseFlagTest, InvalidFlagIsTreatedAsWarning) {
TestUninterestingCall(true);
}
-#endif // GTEST_HAS_STREAM_REDIRECTION_
+#endif // GTEST_HAS_STREAM_REDIRECTION
// A helper class that generates a failure when printed. We use it to
// ensure that Google Mock doesn't print a value (even to an internal
diff --git a/testing/gmock/test/gmock_leak_test_.cc b/testing/gmock/test/gmock_leak_test_.cc
index 24dfc1f..1d27d22 100644
--- a/testing/gmock/test/gmock_leak_test_.cc
+++ b/testing/gmock/test/gmock_leak_test_.cc
@@ -34,7 +34,7 @@
// This program is for verifying that a leaked mock object can be
// caught by Google Mock's leak detector.
-#include <gmock/gmock.h>
+#include "gmock/gmock.h"
namespace {
diff --git a/testing/gmock/test/gmock_link_test.h b/testing/gmock/test/gmock_link_test.h
index aa9aab3..499cc18 100644
--- a/testing/gmock/test/gmock_link_test.h
+++ b/testing/gmock/test/gmock_link_test.h
@@ -44,7 +44,7 @@
// ReturnNull
// ReturnRef
// Assign
-// SetArgumentPointee
+// SetArgPointee
// SetArrayArgument
// SetErrnoAndReturn
// Invoke(function)
@@ -114,14 +114,14 @@
#ifndef GMOCK_TEST_GMOCK_LINK_TEST_H_
#define GMOCK_TEST_GMOCK_LINK_TEST_H_
-#include <gmock/gmock.h>
+#include "gmock/gmock.h"
#if !GTEST_OS_WINDOWS_MOBILE
#include <errno.h>
#endif
-#include <gmock/internal/gmock-port.h>
-#include <gtest/gtest.h>
+#include "gmock/internal/gmock-port.h"
+#include "gtest/gtest.h"
#include <iostream>
#include <vector>
@@ -164,7 +164,7 @@ using testing::ResultOf;
using testing::Return;
using testing::ReturnNull;
using testing::ReturnRef;
-using testing::SetArgumentPointee;
+using testing::SetArgPointee;
using testing::SetArrayArgument;
using testing::StartsWith;
using testing::StrCaseEq;
@@ -281,12 +281,12 @@ TEST(LinkTest, TestAssign) {
mock.VoidFromString(NULL);
}
-// Tests the linkage of the SetArgumentPointee action.
-TEST(LinkTest, TestSetArgumentPointee) {
+// Tests the linkage of the SetArgPointee action.
+TEST(LinkTest, TestSetArgPointee) {
Mock mock;
char ch = 'x';
- EXPECT_CALL(mock, VoidFromString(_)).WillOnce(SetArgumentPointee<0>('y'));
+ EXPECT_CALL(mock, VoidFromString(_)).WillOnce(SetArgPointee<0>('y'));
mock.VoidFromString(&ch);
}
@@ -381,7 +381,7 @@ TEST(LinkTest, TestDoAll) {
char ch = 'x';
EXPECT_CALL(mock, VoidFromString(_))
- .WillOnce(DoAll(SetArgumentPointee<0>('y'), Return()));
+ .WillOnce(DoAll(SetArgPointee<0>('y'), Return()));
mock.VoidFromString(&ch);
}
diff --git a/testing/gmock/test/gmock_output_test_.cc b/testing/gmock/test/gmock_output_test_.cc
index 24c9b38..c8e6b83 100644
--- a/testing/gmock/test/gmock_output_test_.cc
+++ b/testing/gmock/test/gmock_output_test_.cc
@@ -32,12 +32,12 @@
// Tests Google Mock's output in various scenarios. This ensures that
// Google Mock's messages are readable and useful.
-#include <gmock/gmock.h>
+#include "gmock/gmock.h"
#include <stdio.h>
#include <string>
-#include <gtest/gtest.h>
+#include "gtest/gtest.h"
using testing::_;
using testing::AnyNumber;
diff --git a/testing/gmock/test/gmock_test.cc b/testing/gmock/test/gmock_test.cc
index 0c83260..0b89113 100644
--- a/testing/gmock/test/gmock_test.cc
+++ b/testing/gmock/test/gmock_test.cc
@@ -33,10 +33,10 @@
//
// This file tests code in gmock.cc.
-#include <gmock/gmock.h>
+#include "gmock/gmock.h"
#include <string>
-#include <gtest/gtest.h>
+#include "gtest/gtest.h"
using testing::GMOCK_FLAG(verbose);
using testing::InitGoogleMock;
@@ -251,5 +251,5 @@ TEST(WideInitGoogleMockTest, CallsInitGoogleTest) {
TEST(FlagTest, IsAccessibleInCode) {
bool dummy = testing::GMOCK_FLAG(catch_leaked_mocks) &&
testing::GMOCK_FLAG(verbose) == "";
- dummy = dummy; // Avoids the "unused local variable" warning.
+ (void)dummy; // Avoids the "unused local variable" warning.
}
diff --git a/testing/gtest/CMakeLists.txt b/testing/gtest/CMakeLists.txt
index 130719f..0fe2654 100644
--- a/testing/gtest/CMakeLists.txt
+++ b/testing/gtest/CMakeLists.txt
@@ -147,6 +147,13 @@ if (gtest_build_tests)
cxx_library(gtest_main_no_rtti "${cxx_no_rtti}"
src/gtest-all.cc src/gtest_main.cc)
+ cxx_test_with_flags(gtest-death-test_ex_nocatch_test
+ "${cxx_exception} -DGTEST_ENABLE_CATCH_EXCEPTIONS_=0"
+ gtest test/gtest-death-test_ex_test.cc)
+ cxx_test_with_flags(gtest-death-test_ex_catch_test
+ "${cxx_exception} -DGTEST_ENABLE_CATCH_EXCEPTIONS_=1"
+ gtest test/gtest-death-test_ex_test.cc)
+
cxx_test_with_flags(gtest_no_rtti_unittest "${cxx_no_rtti}"
gtest_main_no_rtti test/gtest_unittest.cc)
diff --git a/testing/gtest/include/gtest/gtest-param-test.h b/testing/gtest/include/gtest/gtest-param-test.h
index fb6ec8f..9a92303 100644
--- a/testing/gtest/include/gtest/gtest-param-test.h
+++ b/testing/gtest/include/gtest/gtest-param-test.h
@@ -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-param-test.h.pump
+// DO NOT EDIT BY HAND!!!
// Copyright 2008, Google Inc.
// All rights reserved.
@@ -48,10 +50,12 @@
#if 0
// To write value-parameterized tests, first you should define a fixture
-// class. It must be derived from testing::TestWithParam<T>, where T is
-// the type of your parameter values. TestWithParam<T> is itself derived
-// from testing::Test. T can be any copyable type. If it's a raw pointer,
-// you are responsible for managing the lifespan of the pointed values.
+// class. It is usually derived from testing::TestWithParam<T> (see below for
+// another inheritance scheme that's sometimes useful in more complicated
+// class hierarchies), where the type of your parameter values.
+// TestWithParam<T> is itself derived from testing::Test. T can be any
+// copyable type. If it's a raw pointer, you are responsible for managing the
+// lifespan of the pointed values.
class FooTest : public ::testing::TestWithParam<const char*> {
// You can implement all the usual class fixture members here.
@@ -146,6 +150,32 @@ INSTANTIATE_TEST_CASE_P(AnotherInstantiationName, FooTest, ValuesIn(pets));
// In the future, we plan to publish the API for defining new parameter
// generators. But for now this interface remains part of the internal
// implementation and is subject to change.
+//
+//
+// A parameterized test fixture must be derived from testing::Test and from
+// testing::WithParamInterface<T>, where T is the type of the parameter
+// values. Inheriting from TestWithParam<T> satisfies that requirement because
+// TestWithParam<T> inherits from both Test and WithParamInterface. In more
+// complicated hierarchies, however, it is occasionally useful to inherit
+// separately from Test and WithParamInterface. For example:
+
+class BaseTest : public ::testing::Test {
+ // You can inherit all the usual members for a non-parameterized test
+ // fixture here.
+};
+
+class DerivedTest : public BaseTest, public ::testing::WithParamInterface<int> {
+ // The usual test fixture members go here too.
+};
+
+TEST_F(BaseTest, HasFoo) {
+ // This is an ordinary non-parameterized test.
+}
+
+TEST_P(DerivedTest, DoesBlah) {
+ // GetParam works just the same here as if you inherit from TestWithParam.
+ EXPECT_TRUE(foo.Blah(GetParam()));
+}
#endif // 0
diff --git a/testing/gtest/include/gtest/gtest-param-test.h.pump b/testing/gtest/include/gtest/gtest-param-test.h.pump
index cff9972..d73f24d 100644
--- a/testing/gtest/include/gtest/gtest-param-test.h.pump
+++ b/testing/gtest/include/gtest/gtest-param-test.h.pump
@@ -49,10 +49,12 @@ $var maxtuple = 10 $$ Maximum number of Combine arguments we want to support.
#if 0
// To write value-parameterized tests, first you should define a fixture
-// class. It must be derived from testing::TestWithParam<T>, where T is
-// the type of your parameter values. TestWithParam<T> is itself derived
-// from testing::Test. T can be any copyable type. If it's a raw pointer,
-// you are responsible for managing the lifespan of the pointed values.
+// class. It is usually derived from testing::TestWithParam<T> (see below for
+// another inheritance scheme that's sometimes useful in more complicated
+// class hierarchies), where the type of your parameter values.
+// TestWithParam<T> is itself derived from testing::Test. T can be any
+// copyable type. If it's a raw pointer, you are responsible for managing the
+// lifespan of the pointed values.
class FooTest : public ::testing::TestWithParam<const char*> {
// You can implement all the usual class fixture members here.
@@ -134,9 +136,12 @@ INSTANTIATE_TEST_CASE_P(AnotherInstantiationName, FooTest, ValuesIn(pets));
// in the given test case, whether their definitions come before or
// AFTER the INSTANTIATE_TEST_CASE_P statement.
//
-// Please also note that generator expressions are evaluated in
-// RUN_ALL_TESTS(), after main() has started. This allows evaluation of
-// parameter list based on command line parameters.
+// Please also note that generator expressions (including parameters to the
+// generators) are evaluated in InitGoogleTest(), after main() has started.
+// This allows the user on one hand, to adjust generator parameters in order
+// to dynamically determine a set of tests to run and on the other hand,
+// give the user a chance to inspect the generated tests with Google Test
+// reflection API before RUN_ALL_TESTS() is executed.
//
// You can see samples/sample7_unittest.cc and samples/sample8_unittest.cc
// for more examples.
@@ -144,6 +149,32 @@ INSTANTIATE_TEST_CASE_P(AnotherInstantiationName, FooTest, ValuesIn(pets));
// In the future, we plan to publish the API for defining new parameter
// generators. But for now this interface remains part of the internal
// implementation and is subject to change.
+//
+//
+// A parameterized test fixture must be derived from testing::Test and from
+// testing::WithParamInterface<T>, where T is the type of the parameter
+// values. Inheriting from TestWithParam<T> satisfies that requirement because
+// TestWithParam<T> inherits from both Test and WithParamInterface. In more
+// complicated hierarchies, however, it is occasionally useful to inherit
+// separately from Test and WithParamInterface. For example:
+
+class BaseTest : public ::testing::Test {
+ // You can inherit all the usual members for a non-parameterized test
+ // fixture here.
+};
+
+class DerivedTest : public BaseTest, public ::testing::WithParamInterface<int> {
+ // The usual test fixture members go here too.
+};
+
+TEST_F(BaseTest, HasFoo) {
+ // This is an ordinary non-parameterized test.
+}
+
+TEST_P(DerivedTest, DoesBlah) {
+ // GetParam works just the same here as if you inherit from TestWithParam.
+ EXPECT_TRUE(foo.Blah(GetParam()));
+}
#endif // 0
diff --git a/testing/gtest/include/gtest/gtest-printers.h b/testing/gtest/include/gtest/gtest-printers.h
index 7d90f00..c8daa29 100644
--- a/testing/gtest/include/gtest/gtest-printers.h
+++ b/testing/gtest/include/gtest/gtest-printers.h
@@ -121,7 +121,7 @@ enum TypeKind {
kProtobuf, // a protobuf type
kConvertibleToInteger, // a type implicitly convertible to BiggestInt
// (e.g. a named or unnamed enum type)
- kOtherType, // anything else
+ kOtherType // anything else
};
// TypeWithoutFormatter<T, kTypeKind>::PrintValue(value, os) is called
@@ -404,22 +404,22 @@ GTEST_API_ void PrintTo(wchar_t wc, ::std::ostream* os);
// Overloads for C strings.
GTEST_API_ void PrintTo(const char* s, ::std::ostream* os);
inline void PrintTo(char* s, ::std::ostream* os) {
- PrintTo(implicit_cast<const char*>(s), os);
+ PrintTo(ImplicitCast_<const char*>(s), os);
}
// signed/unsigned char is often used for representing binary data, so
// we print pointers to it as void* to be safe.
inline void PrintTo(const signed char* s, ::std::ostream* os) {
- PrintTo(implicit_cast<const void*>(s), os);
+ PrintTo(ImplicitCast_<const void*>(s), os);
}
inline void PrintTo(signed char* s, ::std::ostream* os) {
- PrintTo(implicit_cast<const void*>(s), os);
+ PrintTo(ImplicitCast_<const void*>(s), os);
}
inline void PrintTo(const unsigned char* s, ::std::ostream* os) {
- PrintTo(implicit_cast<const void*>(s), os);
+ PrintTo(ImplicitCast_<const void*>(s), os);
}
inline void PrintTo(unsigned char* s, ::std::ostream* os) {
- PrintTo(implicit_cast<const void*>(s), os);
+ PrintTo(ImplicitCast_<const void*>(s), os);
}
// MSVC can be configured to define wchar_t as a typedef of unsigned
@@ -431,7 +431,7 @@ inline void PrintTo(unsigned char* s, ::std::ostream* os) {
// Overloads for wide C strings
GTEST_API_ void PrintTo(const wchar_t* s, ::std::ostream* os);
inline void PrintTo(wchar_t* s, ::std::ostream* os) {
- PrintTo(implicit_cast<const wchar_t*>(s), os);
+ PrintTo(ImplicitCast_<const wchar_t*>(s), os);
}
#endif
diff --git a/testing/gtest/include/gtest/gtest-typed-test.h b/testing/gtest/include/gtest/gtest-typed-test.h
index eb6b0b8..2d3b8bf 100644
--- a/testing/gtest/include/gtest/gtest-typed-test.h
+++ b/testing/gtest/include/gtest/gtest-typed-test.h
@@ -175,7 +175,7 @@ INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, MyTypes);
typedef gtest_TypeParam_ TypeParam; \
virtual void TestBody(); \
}; \
- bool gtest_##CaseName##_##TestName##_registered_ = \
+ bool gtest_##CaseName##_##TestName##_registered_ GTEST_ATTRIBUTE_UNUSED_ = \
::testing::internal::TypeParameterizedTest< \
CaseName, \
::testing::internal::TemplateSel< \
@@ -229,7 +229,7 @@ INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, MyTypes);
typedef gtest_TypeParam_ TypeParam; \
virtual void TestBody(); \
}; \
- static bool gtest_##TestName##_defined_ = \
+ static bool gtest_##TestName##_defined_ GTEST_ATTRIBUTE_UNUSED_ = \
GTEST_TYPED_TEST_CASE_P_STATE_(CaseName).AddTestName(\
__FILE__, __LINE__, #CaseName, #TestName); \
} \
@@ -248,7 +248,7 @@ INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, MyTypes);
// since some compilers may choke on '>>' when passing a template
// instance (e.g. Types<int>)
#define INSTANTIATE_TYPED_TEST_CASE_P(Prefix, CaseName, Types) \
- bool gtest_##Prefix##_##CaseName = \
+ bool gtest_##Prefix##_##CaseName GTEST_ATTRIBUTE_UNUSED_ = \
::testing::internal::TypeParameterizedTestCase<CaseName, \
GTEST_CASE_NAMESPACE_(CaseName)::gtest_AllTests_, \
::testing::internal::TypeList< Types >::type>::Register(\
diff --git a/testing/gtest/include/gtest/gtest.h b/testing/gtest/include/gtest/gtest.h
index c725e4c..741a360 100644
--- a/testing/gtest/include/gtest/gtest.h
+++ b/testing/gtest/include/gtest/gtest.h
@@ -281,20 +281,33 @@ class GTEST_API_ AssertionResult {
// assertion's expectation). When nothing has been streamed into the
// object, returns an empty string.
const char* message() const {
- return message_.get() != NULL && message_->c_str() != NULL ?
- message_->c_str() : "";
+ return message_.get() != NULL ? message_->c_str() : "";
}
// TODO(vladl@google.com): Remove this after making sure no clients use it.
// Deprecated; please use message() instead.
const char* failure_message() const { return message(); }
// Streams a custom failure message into this object.
- template <typename T> AssertionResult& operator<<(const T& value);
+ template <typename T> AssertionResult& operator<<(const T& value) {
+ AppendMessage(Message() << value);
+ return *this;
+ }
+
+ // Allows streaming basic output manipulators such as endl or flush into
+ // this object.
+ AssertionResult& operator<<(
+ ::std::ostream& (*basic_manipulator)(::std::ostream& stream)) {
+ AppendMessage(Message() << basic_manipulator);
+ return *this;
+ }
private:
- // No implementation - we want AssertionResult to be
- // copy-constructible but not assignable.
- void operator=(const AssertionResult& other);
+ // Appends the contents of message to message_.
+ void AppendMessage(const Message& a_message) {
+ if (message_.get() == NULL)
+ message_.reset(new ::std::string);
+ message_->append(a_message.GetString().c_str());
+ }
// Stores result of the assertion predicate.
bool success_;
@@ -302,19 +315,10 @@ class GTEST_API_ AssertionResult {
// construct is not satisfied with the predicate's outcome.
// Referenced via a pointer to avoid taking too much stack frame space
// with test assertions.
- internal::scoped_ptr<internal::String> message_;
-}; // class AssertionResult
+ internal::scoped_ptr< ::std::string> message_;
-// Streams a custom failure message into this object.
-template <typename T>
-AssertionResult& AssertionResult::operator<<(const T& value) {
- Message msg;
- if (message_.get() != NULL)
- msg << *message_;
- msg << value;
- message_.reset(new internal::String(msg.GetString()));
- return *this;
-}
+ GTEST_DISALLOW_ASSIGN_(AssertionResult);
+};
// Makes a successful assertion result.
GTEST_API_ AssertionResult AssertionSuccess();
@@ -630,11 +634,21 @@ class GTEST_API_ TestInfo {
// Returns the test name.
const char* name() const { return name_.c_str(); }
- // Returns the test case comment.
- const char* test_case_comment() const { return test_case_comment_.c_str(); }
+ // Returns the name of the parameter type, or NULL if this is not a typed
+ // or a type-parameterized test.
+ const char* type_param() const {
+ if (type_param_.get() != NULL)
+ return type_param_->c_str();
+ return NULL;
+ }
- // Returns the test comment.
- const char* comment() const { return comment_.c_str(); }
+ // Returns the text representation of the value parameter, or NULL if this
+ // is not a value-parameterized test.
+ const char* value_param() const {
+ if (value_param_.get() != NULL)
+ return value_param_->c_str();
+ return NULL;
+ }
// Returns true if this test should run, that is if the test is not disabled
// (or it is disabled but the also_run_disabled_tests flag has been specified)
@@ -666,7 +680,8 @@ class GTEST_API_ TestInfo {
friend class internal::UnitTestImpl;
friend TestInfo* internal::MakeAndRegisterTestInfo(
const char* test_case_name, const char* name,
- const char* test_case_comment, const char* comment,
+ const char* type_param,
+ const char* value_param,
internal::TypeId fixture_class_id,
Test::SetUpTestCaseFunc set_up_tc,
Test::TearDownTestCaseFunc tear_down_tc,
@@ -675,7 +690,8 @@ class GTEST_API_ TestInfo {
// Constructs a TestInfo object. The newly constructed instance assumes
// ownership of the factory object.
TestInfo(const char* test_case_name, const char* name,
- const char* test_case_comment, const char* comment,
+ const char* a_type_param,
+ const char* a_value_param,
internal::TypeId fixture_class_id,
internal::TestFactoryBase* factory);
@@ -696,8 +712,12 @@ class GTEST_API_ TestInfo {
// These fields are immutable properties of the test.
const std::string test_case_name_; // Test case name
const std::string name_; // Test name
- const std::string test_case_comment_; // Test case comment
- const std::string comment_; // Test comment
+ // Name of the parameter type, or NULL if this is not a typed or a
+ // type-parameterized test.
+ const internal::scoped_ptr<const ::std::string> type_param_;
+ // Text representation of the value parameter, or NULL if this is not a
+ // value-parameterized test.
+ const internal::scoped_ptr<const ::std::string> value_param_;
const internal::TypeId fixture_class_id_; // ID of the test fixture class
bool should_run_; // True iff this test should run
bool is_disabled_; // True iff this test is disabled
@@ -726,9 +746,11 @@ class GTEST_API_ TestCase {
// Arguments:
//
// name: name of the test case
+ // a_type_param: the name of the test's type parameter, or NULL if
+ // this is not a type-parameterized test.
// set_up_tc: pointer to the function that sets up the test case
// tear_down_tc: pointer to the function that tears down the test case
- TestCase(const char* name, const char* comment,
+ TestCase(const char* name, const char* a_type_param,
Test::SetUpTestCaseFunc set_up_tc,
Test::TearDownTestCaseFunc tear_down_tc);
@@ -738,8 +760,13 @@ class GTEST_API_ TestCase {
// Gets the name of the TestCase.
const char* name() const { return name_.c_str(); }
- // Returns the test case comment.
- const char* comment() const { return comment_.c_str(); }
+ // Returns the name of the parameter type, or NULL if this is not a
+ // type-parameterized test case.
+ const char* type_param() const {
+ if (type_param_.get() != NULL)
+ return type_param_->c_str();
+ return NULL;
+ }
// Returns true if any test in this test case should run.
bool should_run() const { return should_run_; }
@@ -842,8 +869,9 @@ class GTEST_API_ TestCase {
// Name of the test case.
internal::String name_;
- // Comment on the test case.
- internal::String comment_;
+ // Name of the parameter type, or NULL if this is not a typed or a
+ // type-parameterized test.
+ const internal::scoped_ptr<const ::std::string> type_param_;
// The vector of TestInfos in their original order. It owns the
// elements in the vector.
std::vector<TestInfo*> test_info_list_;
@@ -1338,7 +1366,7 @@ class EqHelper {
};
// This specialization is used when the first argument to ASSERT_EQ()
-// is a null pointer literal.
+// is a null pointer literal, like NULL, false, or 0.
template <>
class EqHelper<true> {
public:
@@ -1347,24 +1375,38 @@ class EqHelper<true> {
// NOT a pointer, e.g. ASSERT_EQ(0, AnIntFunction()) or
// EXPECT_EQ(false, a_bool).
template <typename T1, typename T2>
- static AssertionResult Compare(const char* expected_expression,
- const char* actual_expression,
- const T1& expected,
- const T2& actual) {
+ static AssertionResult Compare(
+ const char* expected_expression,
+ const char* actual_expression,
+ const T1& expected,
+ const T2& actual,
+ // The following line prevents this overload from being considered if T2
+ // is not a pointer type. We need this because ASSERT_EQ(NULL, my_ptr)
+ // expands to Compare("", "", NULL, my_ptr), which requires a conversion
+ // to match the Secret* in the other overload, which would otherwise make
+ // this template match better.
+ typename EnableIf<!is_pointer<T2>::value>::type* = 0) {
return CmpHelperEQ(expected_expression, actual_expression, expected,
actual);
}
- // This version will be picked when the second argument to
- // ASSERT_EQ() is a pointer, e.g. ASSERT_EQ(NULL, a_pointer).
- template <typename T1, typename T2>
- static AssertionResult Compare(const char* expected_expression,
- const char* actual_expression,
- const T1& /* expected */,
- T2* actual) {
+ // This version will be picked when the second argument to ASSERT_EQ() is a
+ // pointer, e.g. ASSERT_EQ(NULL, a_pointer).
+ template <typename T>
+ static AssertionResult Compare(
+ const char* expected_expression,
+ const char* actual_expression,
+ // We used to have a second template parameter instead of Secret*. That
+ // template parameter would deduce to 'long', making this a better match
+ // than the first overload even without the first overload's EnableIf.
+ // Unfortunately, gcc with -Wconversion-null warns when "passing NULL to
+ // non-pointer argument" (even a deduced integral argument), so the old
+ // implementation caused warnings in user code.
+ Secret* /* expected (NULL) */,
+ T* actual) {
// We already know that 'expected' is a null pointer.
return CmpHelperEQ(expected_expression, actual_expression,
- static_cast<T2*>(NULL), actual);
+ static_cast<T*>(NULL), actual);
}
};
@@ -1585,9 +1627,13 @@ class GTEST_API_ AssertHelper {
} // namespace internal
#if GTEST_HAS_PARAM_TEST
-// The abstract base class that all value-parameterized tests inherit from.
+// The pure interface class that all value-parameterized tests inherit from.
+// A value-parameterized class must inherit from both ::testing::Test and
+// ::testing::WithParamInterface. In most cases that just means inheriting
+// from ::testing::TestWithParam, but more complicated test hierarchies
+// may need to inherit from Test and WithParamInterface at different levels.
//
-// This class adds support for accessing the test parameter value via
+// This interface has support for accessing the test parameter value via
// the GetParam() method.
//
// Use it with one of the parameter generator defining functions, like Range(),
@@ -1616,12 +1662,16 @@ class GTEST_API_ AssertHelper {
// INSTANTIATE_TEST_CASE_P(OneToTenRange, FooTest, ::testing::Range(1, 10));
template <typename T>
-class TestWithParam : public Test {
+class WithParamInterface {
public:
typedef T ParamType;
+ virtual ~WithParamInterface() {}
// The current parameter value. Is also available in the test fixture's
- // constructor.
+ // constructor. This member function is non-static, even though it only
+ // references static data, to reduce the opportunity for incorrect uses
+ // like writing 'WithParamInterface<bool>::GetParam()' for a test that
+ // uses a fixture whose parameter type is int.
const ParamType& GetParam() const { return *parameter_; }
private:
@@ -1634,12 +1684,19 @@ class TestWithParam : public Test {
// Static value used for accessing parameter during a test lifetime.
static const ParamType* parameter_;
- // TestClass must be a subclass of TestWithParam<T>.
+ // TestClass must be a subclass of WithParamInterface<T> and Test.
template <class TestClass> friend class internal::ParameterizedTestFactory;
};
template <typename T>
-const T* TestWithParam<T>::parameter_ = NULL;
+const T* WithParamInterface<T>::parameter_ = NULL;
+
+// Most value-parameterized classes can ignore the existence of
+// WithParamInterface, and can just inherit from ::testing::TestWithParam.
+
+template <typename T>
+class TestWithParam : public Test, public WithParamInterface<T> {
+};
#endif // GTEST_HAS_PARAM_TEST
diff --git a/testing/gtest/include/gtest/internal/gtest-death-test-internal.h b/testing/gtest/include/gtest/internal/gtest-death-test-internal.h
index 9242bd3..2b2c98d 100644
--- a/testing/gtest/include/gtest/internal/gtest-death-test-internal.h
+++ b/testing/gtest/include/gtest/internal/gtest-death-test-internal.h
@@ -39,6 +39,8 @@
#include "gtest/internal/gtest-internal.h"
+#include <stdio.h>
+
namespace testing {
namespace internal {
@@ -96,8 +98,12 @@ class GTEST_API_ DeathTest {
// test, then wait for it to complete.
enum TestRole { OVERSEE_TEST, EXECUTE_TEST };
- // An enumeration of the two reasons that a test might be aborted.
- enum AbortReason { TEST_ENCOUNTERED_RETURN_STATEMENT, TEST_DID_NOT_DIE };
+ // An enumeration of the three reasons that a test might be aborted.
+ enum AbortReason {
+ TEST_ENCOUNTERED_RETURN_STATEMENT,
+ TEST_THREW_EXCEPTION,
+ TEST_DID_NOT_DIE
+ };
// Assumes one of the above roles.
virtual TestRole AssumeRole() = 0;
@@ -149,6 +155,29 @@ class DefaultDeathTestFactory : public DeathTestFactory {
// by a signal, or exited normally with a nonzero exit code.
GTEST_API_ bool ExitedUnsuccessfully(int exit_status);
+// Traps C++ exceptions escaping statement and reports them as test
+// failures. Note that trapping SEH exceptions is not implemented here.
+#if GTEST_HAS_EXCEPTIONS
+#define GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, death_test) \
+ try { \
+ GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
+ } catch (const ::std::exception& gtest_exception) { \
+ fprintf(\
+ stderr, \
+ "\n%s: Caught std::exception-derived exception escaping the " \
+ "death test statement. Exception message: %s\n", \
+ ::testing::internal::FormatFileLocation(__FILE__, __LINE__).c_str(), \
+ gtest_exception.what()); \
+ fflush(stderr); \
+ death_test->Abort(::testing::internal::DeathTest::TEST_THREW_EXCEPTION); \
+ } catch (...) { \
+ death_test->Abort(::testing::internal::DeathTest::TEST_THREW_EXCEPTION); \
+ }
+#else
+#define GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, death_test) \
+ GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement)
+#endif
+
// This macro is for implementing ASSERT_DEATH*, EXPECT_DEATH*,
// ASSERT_EXIT*, and EXPECT_EXIT*.
#define GTEST_DEATH_TEST_(statement, predicate, regex, fail) \
@@ -172,7 +201,7 @@ GTEST_API_ bool ExitedUnsuccessfully(int exit_status);
case ::testing::internal::DeathTest::EXECUTE_TEST: { \
::testing::internal::DeathTest::ReturnSentinel \
gtest_sentinel(gtest_dt); \
- GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
+ GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, gtest_dt); \
gtest_dt->Abort(::testing::internal::DeathTest::TEST_DID_NOT_DIE); \
break; \
} \
diff --git a/testing/gtest/include/gtest/internal/gtest-internal.h b/testing/gtest/include/gtest/internal/gtest-internal.h
index 3307855..23fcef7 100644
--- a/testing/gtest/include/gtest/internal/gtest-internal.h
+++ b/testing/gtest/include/gtest/internal/gtest-internal.h
@@ -561,10 +561,10 @@ typedef void (*TearDownTestCaseFunc)();
//
// test_case_name: name of the test case
// name: name of the test
-// test_case_comment: a comment on the test case that will be included in
-// the test output
-// comment: a comment on the test that will be included in the
-// test output
+// type_param the name of the test's type parameter, or NULL if
+// this is not a typed or a type-parameterized test.
+// value_param text representation of the test's value parameter,
+// or NULL if this is not a type-parameterized test.
// fixture_class_id: ID of the test fixture class
// set_up_tc: pointer to the function that sets up the test case
// tear_down_tc: pointer to the function that tears down the test case
@@ -573,7 +573,8 @@ typedef void (*TearDownTestCaseFunc)();
// ownership of the factory object.
GTEST_API_ TestInfo* MakeAndRegisterTestInfo(
const char* test_case_name, const char* name,
- const char* test_case_comment, const char* comment,
+ const char* type_param,
+ const char* value_param,
TypeId fixture_class_id,
SetUpTestCaseFunc set_up_tc,
TearDownTestCaseFunc tear_down_tc,
@@ -662,8 +663,8 @@ class TypeParameterizedTest {
String::Format("%s%s%s/%d", prefix, prefix[0] == '\0' ? "" : "/",
case_name, index).c_str(),
GetPrefixUntilComma(test_names).c_str(),
- String::Format("TypeParam = %s", GetTypeName<Type>().c_str()).c_str(),
- "",
+ GetTypeName<Type>().c_str(),
+ NULL, // No value parameter.
GetTypeId<FixtureClass>(),
TestClass::SetUpTestCase,
TestClass::TearDownTestCase,
@@ -919,6 +920,13 @@ typedef char IsNotContainer;
template <class C>
IsNotContainer IsContainerTest(...) { return '\0'; }
+// EnableIf<condition>::type is void when 'Cond' is true, and
+// undefined when 'Cond' is false. To use SFINAE to make a function
+// overload only apply when a particular expression is true, add
+// "typename EnableIf<expression>::type* = 0" as the last parameter.
+template<bool> struct EnableIf;
+template<> struct EnableIf<true> { typedef void type; }; // NOLINT
+
// Utilities for native arrays.
// ArrayEq() compares two k-dimensional native arrays using the
@@ -1182,7 +1190,7 @@ class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) : public parent_class {\
GTEST_TEST_CLASS_NAME_(test_case_name, test_name)() {}\
private:\
virtual void TestBody();\
- static ::testing::TestInfo* const test_info_;\
+ static ::testing::TestInfo* const test_info_ GTEST_ATTRIBUTE_UNUSED_;\
GTEST_DISALLOW_COPY_AND_ASSIGN_(\
GTEST_TEST_CLASS_NAME_(test_case_name, test_name));\
};\
@@ -1190,7 +1198,7 @@ class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) : public parent_class {\
::testing::TestInfo* const GTEST_TEST_CLASS_NAME_(test_case_name, test_name)\
::test_info_ =\
::testing::internal::MakeAndRegisterTestInfo(\
- #test_case_name, #test_name, "", "", \
+ #test_case_name, #test_name, NULL, NULL, \
(parent_id), \
parent_class::SetUpTestCase, \
parent_class::TearDownTestCase, \
diff --git a/testing/gtest/include/gtest/internal/gtest-param-util.h b/testing/gtest/include/gtest/internal/gtest-param-util.h
index d923b7d..61c3e37 100644
--- a/testing/gtest/include/gtest/internal/gtest-param-util.h
+++ b/testing/gtest/include/gtest/internal/gtest-param-util.h
@@ -505,12 +505,11 @@ class ParameterizedTestCaseInfo : public ParameterizedTestCaseInfoBase {
param_it != generator.end(); ++param_it, ++i) {
Message test_name_stream;
test_name_stream << test_info->test_base_name.c_str() << "/" << i;
- std::string comment = "GetParam() = " + PrintToString(*param_it);
MakeAndRegisterTestInfo(
test_case_name_stream.GetString().c_str(),
test_name_stream.GetString().c_str(),
- "", // test_case_comment
- comment.c_str(),
+ NULL, // No type parameter.
+ PrintToString(*param_it).c_str(),
GetTestCaseTypeId(),
TestCase::SetUpTestCase,
TestCase::TearDownTestCase,
diff --git a/testing/gtest/include/gtest/internal/gtest-port.h b/testing/gtest/include/gtest/internal/gtest-port.h
index a9c7cae..be2297e 100644
--- a/testing/gtest/include/gtest/internal/gtest-port.h
+++ b/testing/gtest/include/gtest/internal/gtest-port.h
@@ -88,6 +88,7 @@
// GTEST_OS_CYGWIN - Cygwin
// GTEST_OS_LINUX - Linux
// GTEST_OS_MAC - Mac OS X
+// GTEST_OS_NACL - Google Native Client (NaCl)
// GTEST_OS_SOLARIS - Sun Solaris
// GTEST_OS_SYMBIAN - Symbian
// GTEST_OS_WINDOWS - Windows (Desktop, MinGW, or Mobile)
@@ -230,6 +231,8 @@
#define GTEST_OS_SOLARIS 1
#elif defined(_AIX)
#define GTEST_OS_AIX 1
+#elif defined __native_client__
+#define GTEST_OS_NACL 1
#endif // __CYGWIN__
// Brings in definitions for functions used in the testing::internal::posix
@@ -240,7 +243,12 @@
// is not the case, we need to include headers that provide the functions
// mentioned above.
#include <unistd.h>
-#include <strings.h>
+#if !GTEST_OS_NACL
+// 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
#include <direct.h>
#include <io.h>
@@ -911,25 +919,29 @@ inline void FlushInfoLog() { fflush(NULL); }
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
//
-// Use implicit_cast as a safe version of static_cast for upcasting in
+// Use ImplicitCast_ as a safe version of static_cast for upcasting in
// the type hierarchy (e.g. casting a Foo* to a SuperclassOfFoo* or a
-// const Foo*). When you use implicit_cast, the compiler checks that
-// the cast is safe. Such explicit implicit_casts are necessary in
+// const Foo*). When you use ImplicitCast_, the compiler checks that
+// the cast is safe. Such explicit ImplicitCast_s are necessary in
// surprisingly many situations where C++ demands an exact type match
// instead of an argument type convertable to a target type.
//
-// The syntax for using implicit_cast is the same as for static_cast:
+// The syntax for using ImplicitCast_ is the same as for static_cast:
//
-// implicit_cast<ToType>(expr)
+// ImplicitCast_<ToType>(expr)
//
-// implicit_cast would have been part of the C++ standard library,
+// ImplicitCast_ would have been part of the C++ standard library,
// but the proposal was submitted too late. It will probably make
// its way into the language in the future.
+//
+// This relatively ugly name is intentional. It prevents clashes with
+// similar functions users may have (e.g., implicit_cast). The internal
+// namespace alone is not enough because the function can be found by ADL.
template<typename To>
-inline To implicit_cast(To x) { return x; }
+inline To ImplicitCast_(To x) { return x; }
// When you upcast (that is, cast a pointer from type Foo to type
-// SuperclassOfFoo), it's fine to use implicit_cast<>, since upcasts
+// SuperclassOfFoo), it's fine to use ImplicitCast_<>, since upcasts
// always succeed. When you downcast (that is, cast a pointer from
// type Foo to type SubclassOfFoo), static_cast<> isn't safe, because
// how do you know the pointer is really of type SubclassOfFoo? It
@@ -945,15 +957,19 @@ inline To implicit_cast(To x) { return x; }
// if (dynamic_cast<Subclass1>(foo)) HandleASubclass1Object(foo);
// if (dynamic_cast<Subclass2>(foo)) HandleASubclass2Object(foo);
// You should design the code some other way not to need this.
-template<typename To, typename From> // use like this: down_cast<T*>(foo);
-inline To down_cast(From* f) { // so we only accept pointers
+//
+// This relatively ugly name is intentional. It prevents clashes with
+// similar functions users may have (e.g., down_cast). The internal
+// namespace alone is not enough because the function can be found by ADL.
+template<typename To, typename From> // use like this: DownCast_<T*>(foo);
+inline To DownCast_(From* f) { // so we only accept pointers
// Ensures that To is a sub-type of From *. This test is here only
// for compile-time type checking, and has no overhead in an
// optimized build at run-time, as it will be optimized away
// completely.
if (false) {
const To to = NULL;
- ::testing::internal::implicit_cast<From*>(to);
+ ::testing::internal::ImplicitCast_<From*>(to);
}
#if GTEST_HAS_RTTI
@@ -1454,6 +1470,9 @@ inline bool IsSpace(char ch) {
inline bool IsUpper(char ch) {
return isupper(static_cast<unsigned char>(ch)) != 0;
}
+inline bool IsXDigit(char ch) {
+ return isxdigit(static_cast<unsigned char>(ch)) != 0;
+}
inline char ToLower(char ch) {
return static_cast<char>(tolower(static_cast<unsigned char>(ch)));
diff --git a/testing/gtest/samples/sample7_unittest.cc b/testing/gtest/samples/sample7_unittest.cc
index 441acf9..1b651a2 100644
--- a/testing/gtest/samples/sample7_unittest.cc
+++ b/testing/gtest/samples/sample7_unittest.cc
@@ -45,12 +45,11 @@
using ::testing::TestWithParam;
using ::testing::Values;
-// As a general rule, tested objects should not be reused between tests.
-// Also, their constructors and destructors of tested objects can have
-// side effects. Thus you should create and destroy them for each test.
-// In this sample we will define a simple factory function for PrimeTable
-// objects. We will instantiate objects in test's SetUp() method and
-// delete them in TearDown() method.
+// As a general rule, to prevent a test from affecting the tests that come
+// after it, you should create and destroy the tested objects for each test
+// instead of reusing them. In this sample we will define a simple factory
+// function for PrimeTable objects. We will instantiate objects in test's
+// SetUp() method and delete them in TearDown() method.
typedef PrimeTable* CreatePrimeTableFunc();
PrimeTable* CreateOnTheFlyPrimeTable() {
@@ -62,11 +61,10 @@ PrimeTable* CreatePreCalculatedPrimeTable() {
return new PreCalculatedPrimeTable(max_precalculated);
}
-// Inside the test body, fixture constructor, SetUp(), and TearDown()
-// you can refer to the test parameter by GetParam().
-// In this case, the test parameter is a PrimeTableFactory interface pointer
-// which we use in fixture's SetUp() to create and store an instance of
-// PrimeTable.
+// Inside the test body, fixture constructor, SetUp(), and TearDown() you
+// can refer to the test parameter by GetParam(). In this case, the test
+// parameter is a factory function which we call in fixture's SetUp() to
+// create and store an instance of PrimeTable.
class PrimeTableTest : public TestWithParam<CreatePrimeTableFunc*> {
public:
virtual ~PrimeTableTest() { delete table_; }
diff --git a/testing/gtest/scripts/pump.py b/testing/gtest/scripts/pump.py
index f15c1b6..8afe808 100755
--- a/testing/gtest/scripts/pump.py
+++ b/testing/gtest/scripts/pump.py
@@ -29,7 +29,7 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-"""pump v0.1 - Pretty Useful for Meta Programming.
+"""pump v0.2.0 - Pretty Useful for Meta Programming.
A tool for preprocessor meta programming. Useful for generating
repetitive boilerplate code. Especially useful for writing C++
@@ -78,7 +78,6 @@ TOKEN_TABLE = [
(re.compile(r'\$range\s+'), '$range'),
(re.compile(r'\$[_A-Za-z]\w*'), '$id'),
(re.compile(r'\$\(\$\)'), '$($)'),
- (re.compile(r'\$\$.*'), '$$'),
(re.compile(r'\$'), '$'),
(re.compile(r'\[\[\n?'), '[['),
(re.compile(r'\]\]\n?'), ']]'),
@@ -224,6 +223,17 @@ def SubString(lines, start, end):
return ''.join(result_lines)
+def StripMetaComments(str):
+ """Strip meta comments from each line in the given string."""
+
+ # First, completely remove lines containing nothing but a meta
+ # comment, including the trailing \n.
+ str = re.sub(r'^\s*\$\$.*\n', '', str)
+
+ # Then, remove meta comments from contentful lines.
+ return re.sub(r'\s*\$\$.*', '', str)
+
+
def MakeToken(lines, start, end, token_type):
"""Creates a new instance of Token."""
@@ -311,11 +321,7 @@ def TokenizeLines(lines, pos):
prev_token = MakeToken(lines, pos, found.start, 'code')
prev_token_rstripped = RStripNewLineFromToken(prev_token)
- if found.token_type == '$$': # A meta comment.
- if prev_token_rstripped:
- yield prev_token_rstripped
- pos = Cursor(found.end.line + 1, 0)
- elif found.token_type == '$var':
+ if found.token_type == '$var':
if prev_token_rstripped:
yield prev_token_rstripped
yield found
@@ -374,8 +380,11 @@ def TokenizeLines(lines, pos):
def Tokenize(s):
- lines = s.splitlines(True)
- return TokenizeLines(lines, Cursor(0, 0))
+ """A generator that yields the tokens in the given string."""
+ if s != '':
+ lines = s.splitlines(True)
+ for token in TokenizeLines(lines, Cursor(0, 0)):
+ yield token
class CodeNode:
@@ -565,11 +574,9 @@ def ParseCodeNode(tokens):
return CodeNode(atomic_code_list)
-def Convert(file_path):
- s = file(file_path, 'r').read()
- tokens = []
- for token in Tokenize(s):
- tokens.append(token)
+def ParseToAST(pump_src_text):
+ """Convert the given Pump source text into an AST."""
+ tokens = list(Tokenize(pump_src_text))
code_node = ParseCodeNode(tokens)
return code_node
@@ -805,16 +812,21 @@ def BeautifyCode(string):
return '\n'.join(output2) + '\n'
+def ConvertFromPumpSource(src_text):
+ """Return the text generated from the given Pump source text."""
+ ast = ParseToAST(StripMetaComments(src_text))
+ output = Output()
+ RunCode(Env(), ast, output)
+ return BeautifyCode(output.string)
+
+
def main(argv):
if len(argv) == 1:
print __doc__
sys.exit(1)
file_path = argv[-1]
- ast = Convert(file_path)
- output = Output()
- RunCode(Env(), ast, output)
- output_str = BeautifyCode(output.string)
+ output_str = ConvertFromPumpSource(file(file_path, 'r').read())
if file_path.endswith('.pump'):
output_file_path = file_path[:-5]
else:
diff --git a/testing/gtest/scripts/test/Makefile b/testing/gtest/scripts/test/Makefile
index ffc0c90..cdff584 100644
--- a/testing/gtest/scripts/test/Makefile
+++ b/testing/gtest/scripts/test/Makefile
@@ -21,7 +21,9 @@ SAMPLE_DIR = ../../samples
GTEST_MAIN_CC = ../../src/gtest_main.cc
# Flags passed to the preprocessor.
-CPPFLAGS += -I$(FUSED_GTEST_DIR)
+# We have no idea here whether pthreads is available in the system, so
+# disable its use.
+CPPFLAGS += -I$(FUSED_GTEST_DIR) -DGTEST_HAS_PTHREAD=0
# Flags passed to the C++ compiler.
CXXFLAGS += -g
diff --git a/testing/gtest/src/gtest-death-test.cc b/testing/gtest/src/gtest-death-test.cc
index e11f504..3e65193 100644
--- a/testing/gtest/src/gtest-death-test.cc
+++ b/testing/gtest/src/gtest-death-test.cc
@@ -182,15 +182,19 @@ static String DeathTestThreadWarning(size_t thread_count) {
// Flag characters for reporting a death test that did not die.
static const char kDeathTestLived = 'L';
static const char kDeathTestReturned = 'R';
+static const char kDeathTestThrew = 'T';
static const char kDeathTestInternalError = 'I';
-// An enumeration describing all of the possible ways that a death test
-// can conclude. DIED means that the process died while executing the
-// test code; LIVED means that process lived beyond the end of the test
-// code; and RETURNED means that the test statement attempted a "return,"
-// which is not allowed. IN_PROGRESS means the test has not yet
-// concluded.
-enum DeathTestOutcome { IN_PROGRESS, DIED, LIVED, RETURNED };
+// An enumeration describing all of the possible ways that a death test can
+// conclude. DIED means that the process died while executing the test
+// code; LIVED means that process lived beyond the end of the test code;
+// RETURNED means that the test statement attempted to execute a return
+// statement, which is not allowed; THREW means that the test statement
+// returned control by throwing an exception. IN_PROGRESS means the test
+// has not yet concluded.
+// TODO(vladl@google.com): Unify names and possibly values for
+// AbortReason, DeathTestOutcome, and flag characters above.
+enum DeathTestOutcome { IN_PROGRESS, DIED, LIVED, RETURNED, THREW };
// Routine for aborting the program which is safe to call from an
// exec-style death test child process, in which case the error
@@ -388,6 +392,9 @@ void DeathTestImpl::ReadAndInterpretStatusByte() {
case kDeathTestReturned:
set_outcome(RETURNED);
break;
+ case kDeathTestThrew:
+ set_outcome(THREW);
+ break;
case kDeathTestLived:
set_outcome(LIVED);
break;
@@ -416,7 +423,9 @@ void DeathTestImpl::Abort(AbortReason reason) {
// it finds any data in our pipe. So, here we write a single flag byte
// to the pipe, then exit.
const char status_ch =
- reason == TEST_DID_NOT_DIE ? kDeathTestLived : kDeathTestReturned;
+ reason == TEST_DID_NOT_DIE ? kDeathTestLived :
+ reason == TEST_THREW_EXCEPTION ? kDeathTestThrew : kDeathTestReturned;
+
GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Write(write_fd(), &status_ch, 1));
// We are leaking the descriptor here because on some platforms (i.e.,
// when built as Windows DLL), destructors of global objects will still
@@ -429,13 +438,31 @@ void DeathTestImpl::Abort(AbortReason reason) {
_exit(1); // Exits w/o any normal exit hooks (we were supposed to crash)
}
+// Returns an indented copy of stderr output for a death test.
+// This makes distinguishing death test output lines from regular log lines
+// much easier.
+static ::std::string FormatDeathTestOutput(const ::std::string& output) {
+ ::std::string ret;
+ for (size_t at = 0; ; ) {
+ const size_t line_end = output.find('\n', at);
+ ret += "[ DEATH ] ";
+ if (line_end == ::std::string::npos) {
+ ret += output.substr(at);
+ break;
+ }
+ ret += output.substr(at, line_end + 1 - at);
+ at = line_end + 1;
+ }
+ return ret;
+}
+
// Assesses the success or failure of a death test, using both private
// members which have previously been set, and one argument:
//
// Private data members:
// outcome: An enumeration describing how the death test
-// concluded: DIED, LIVED, or RETURNED. The death test fails
-// in the latter two cases.
+// concluded: DIED, LIVED, THREW, or RETURNED. The death test
+// fails in the latter three cases.
// status: The exit status of the child process. On *nix, it is in the
// in the format specified by wait(2). On Windows, this is the
// value supplied to the ExitProcess() API or a numeric code
@@ -464,11 +491,15 @@ bool DeathTestImpl::Passed(bool status_ok) {
switch (outcome()) {
case LIVED:
buffer << " Result: failed to die.\n"
- << " Error msg: " << error_message;
+ << " Error msg:\n" << FormatDeathTestOutput(error_message);
+ break;
+ case THREW:
+ buffer << " Result: threw an exception.\n"
+ << " Error msg:\n" << FormatDeathTestOutput(error_message);
break;
case RETURNED:
buffer << " Result: illegal return in test statement.\n"
- << " Error msg: " << error_message;
+ << " Error msg:\n" << FormatDeathTestOutput(error_message);
break;
case DIED:
if (status_ok) {
@@ -478,11 +509,12 @@ bool DeathTestImpl::Passed(bool status_ok) {
} else {
buffer << " Result: died but not with expected error.\n"
<< " Expected: " << regex()->pattern() << "\n"
- << "Actual msg: " << error_message;
+ << "Actual msg:\n" << FormatDeathTestOutput(error_message);
}
} else {
buffer << " Result: died but not with expected exit code:\n"
- << " " << ExitSummary(status()) << "\n";
+ << " " << ExitSummary(status()) << "\n"
+ << "Actual msg:\n" << FormatDeathTestOutput(error_message);
}
break;
case IN_PROGRESS:
diff --git a/testing/gtest/src/gtest-filepath.cc b/testing/gtest/src/gtest-filepath.cc
index 96557f3..118848a 100644
--- a/testing/gtest/src/gtest-filepath.cc
+++ b/testing/gtest/src/gtest-filepath.cc
@@ -39,8 +39,8 @@
#elif GTEST_OS_WINDOWS
#include <direct.h>
#include <io.h>
-#elif GTEST_OS_SYMBIAN
-// Symbian OpenC has PATH_MAX in sys/syslimits.h
+#elif GTEST_OS_SYMBIAN || GTEST_OS_NACL
+// Symbian OpenC and NaCl have PATH_MAX in sys/syslimits.h
#include <sys/syslimits.h>
#else
#include <limits.h>
diff --git a/testing/gtest/src/gtest-internal-inl.h b/testing/gtest/src/gtest-internal-inl.h
index e0f4af5..8629c6f 100644
--- a/testing/gtest/src/gtest-internal-inl.h
+++ b/testing/gtest/src/gtest-internal-inl.h
@@ -607,10 +607,12 @@ class GTEST_API_ UnitTestImpl {
// Arguments:
//
// test_case_name: name of the test case
+ // type_param: the name of the test's type parameter, or NULL if
+ // this is not a typed or a type-parameterized test.
// set_up_tc: pointer to the function that sets up the test case
// tear_down_tc: pointer to the function that tears down the test case
TestCase* GetTestCase(const char* test_case_name,
- const char* comment,
+ const char* type_param,
Test::SetUpTestCaseFunc set_up_tc,
Test::TearDownTestCaseFunc tear_down_tc);
@@ -623,7 +625,7 @@ class GTEST_API_ UnitTestImpl {
// test_info: the TestInfo object
void AddTestInfo(Test::SetUpTestCaseFunc set_up_tc,
Test::TearDownTestCaseFunc tear_down_tc,
- TestInfo * test_info) {
+ TestInfo* test_info) {
// In order to support thread-safe death tests, we need to
// remember the original working directory when the test program
// was first invoked. We cannot do this in RUN_ALL_TESTS(), as
@@ -638,7 +640,7 @@ class GTEST_API_ UnitTestImpl {
}
GetTestCase(test_info->test_case_name(),
- test_info->test_case_comment(),
+ test_info->type_param(),
set_up_tc,
tear_down_tc)->AddTestInfo(test_info);
}
diff --git a/testing/gtest/src/gtest-port.cc b/testing/gtest/src/gtest-port.cc
index ae0c663..da62fba 100644
--- a/testing/gtest/src/gtest-port.cc
+++ b/testing/gtest/src/gtest-port.cc
@@ -53,6 +53,7 @@
#include "gtest/gtest-spi.h"
#include "gtest/gtest-message.h"
+#include "gtest/internal/gtest-internal.h"
#include "gtest/internal/gtest-string.h"
// Indicates that this translation unit is part of Google Test's
diff --git a/testing/gtest/src/gtest-printers.cc b/testing/gtest/src/gtest-printers.cc
index 147f8b2..bfbca9c 100644
--- a/testing/gtest/src/gtest-printers.cc
+++ b/testing/gtest/src/gtest-printers.cc
@@ -194,25 +194,25 @@ static CharFormat PrintAsCharLiteralTo(Char c, ostream* os) {
return kSpecialEscape;
}
-// Prints a char as if it's part of a string literal, escaping it when
-// necessary.
-static void PrintAsWideStringLiteralTo(wchar_t c, ostream* os) {
+// Prints a char c as if it's part of a string literal, escaping it when
+// necessary; returns how c was formatted.
+static CharFormat PrintAsWideStringLiteralTo(wchar_t c, ostream* os) {
switch (c) {
case L'\'':
*os << "'";
- break;
+ return kAsIs;
case L'"':
*os << "\\\"";
- break;
+ return kSpecialEscape;
default:
- PrintAsCharLiteralTo<wchar_t>(c, os);
+ return PrintAsCharLiteralTo<wchar_t>(c, os);
}
}
-// Prints a char as if it's part of a string literal, escaping it when
-// necessary.
-static void PrintAsNarrowStringLiteralTo(char c, ostream* os) {
- PrintAsWideStringLiteralTo(static_cast<unsigned char>(c), os);
+// Prints a char c as if it's part of a string literal, escaping it when
+// necessary; returns how c was formatted.
+static CharFormat PrintAsNarrowStringLiteralTo(char c, ostream* os) {
+ return PrintAsWideStringLiteralTo(static_cast<unsigned char>(c), os);
}
// Prints a wide or narrow character c and its code. '\0' is printed
@@ -263,8 +263,16 @@ void PrintTo(wchar_t wc, ostream* os) {
// and may not be null-terminated.
static void PrintCharsAsStringTo(const char* begin, size_t len, ostream* os) {
*os << "\"";
+ bool is_previous_hex = false;
for (size_t index = 0; index < len; ++index) {
- PrintAsNarrowStringLiteralTo(begin[index], os);
+ const char cur = begin[index];
+ if (is_previous_hex && IsXDigit(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 << "\" \"";
+ }
+ is_previous_hex = PrintAsNarrowStringLiteralTo(cur, os) == kHexEscape;
}
*os << "\"";
}
@@ -280,8 +288,17 @@ void UniversalPrintArray(const char* begin, size_t len, ostream* os) {
static void PrintWideCharsAsStringTo(const wchar_t* begin, size_t len,
ostream* os) {
*os << "L\"";
+ bool is_previous_hex = false;
for (size_t index = 0; index < len; ++index) {
- PrintAsWideStringLiteralTo(begin[index], os);
+ const wchar_t cur = begin[index];
+ if (is_previous_hex && 0 <= cur && cur < 128 &&
+ 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 << "\"";
}
@@ -291,7 +308,7 @@ void PrintTo(const char* s, ostream* os) {
if (s == NULL) {
*os << "NULL";
} else {
- *os << implicit_cast<const void*>(s) << " pointing to ";
+ *os << ImplicitCast_<const void*>(s) << " pointing to ";
PrintCharsAsStringTo(s, strlen(s), os);
}
}
@@ -308,7 +325,7 @@ void PrintTo(const wchar_t* s, ostream* os) {
if (s == NULL) {
*os << "NULL";
} else {
- *os << implicit_cast<const void*>(s) << " pointing to ";
+ *os << ImplicitCast_<const void*>(s) << " pointing to ";
PrintWideCharsAsStringTo(s, wcslen(s), os);
}
}
diff --git a/testing/gtest/src/gtest.cc b/testing/gtest/src/gtest.cc
index 0d41e46..575a8a5 100644
--- a/testing/gtest/src/gtest.cc
+++ b/testing/gtest/src/gtest.cc
@@ -191,7 +191,7 @@ GTEST_DEFINE_bool_(
GTEST_DEFINE_bool_(
catch_exceptions,
- internal::BoolFromGTestEnv("catch_exceptions", false),
+ internal::BoolFromGTestEnv("catch_exceptions", true),
"True iff " GTEST_NAME_
" should catch exceptions and treat them as test failures.");
@@ -945,8 +945,8 @@ Message& Message::operator <<(const ::wstring& wstr) {
AssertionResult::AssertionResult(const AssertionResult& other)
: success_(other.success_),
message_(other.message_.get() != NULL ?
- new internal::String(*other.message_) :
- static_cast<internal::String*>(NULL)) {
+ new ::std::string(*other.message_) :
+ static_cast< ::std::string*>(NULL)) {
}
// Returns the assertion's negation. Used with EXPECT/ASSERT_FALSE.
@@ -2047,13 +2047,17 @@ class GoogleTestFailureException : public ::std::runtime_error {
};
#endif // GTEST_HAS_EXCEPTIONS
+namespace internal {
+// We put these helper functions in the internal namespace as IBM's xIC_r
+// compiler rejects the code if they were declared static.
+
// Runs the given method and handles SEH exceptions it throws, when
// SEH is supported; returns the 0-value for type Result in case of an
// SEH exception. (Microsoft compilers cannot handle SEH and C++
// exceptions in the same function. Therefore, we provide a separate
// wrapper function for handling SEH exceptions.)
template <class T, typename Result>
-static Result HandleSehExceptionsInMethodIfSupported(
+Result HandleSehExceptionsInMethodIfSupported(
T* object, Result (T::*method)(), const char* location) {
#if GTEST_HAS_SEH
__try {
@@ -2080,7 +2084,7 @@ static Result HandleSehExceptionsInMethodIfSupported(
// exceptions, if they are supported; returns the 0-value for type
// Result in case of an SEH exception.
template <class T, typename Result>
-static Result HandleExceptionsInMethodIfSupported(
+Result HandleExceptionsInMethodIfSupported(
T* object, Result (T::*method)(), const char* location) {
// NOTE: The user code can affect the way in which Google Test handles
// exceptions by setting GTEST_FLAG(catch_exceptions), but only before
@@ -2131,17 +2135,19 @@ static Result HandleExceptionsInMethodIfSupported(
}
}
+} // namespace internal
+
// Runs the test and updates the test result.
void Test::Run() {
if (!HasSameFixtureClass()) return;
internal::UnitTestImpl* const impl = internal::GetUnitTestImpl();
impl->os_stack_trace_getter()->UponLeavingGTest();
- HandleExceptionsInMethodIfSupported(this, &Test::SetUp, "SetUp()");
+ internal::HandleExceptionsInMethodIfSupported(this, &Test::SetUp, "SetUp()");
// We will run the test only if SetUp() was successful.
if (!HasFatalFailure()) {
impl->os_stack_trace_getter()->UponLeavingGTest();
- HandleExceptionsInMethodIfSupported(
+ internal::HandleExceptionsInMethodIfSupported(
this, &Test::TestBody, "the test body");
}
@@ -2149,7 +2155,7 @@ void Test::Run() {
// always call TearDown(), even if SetUp() or the test body has
// failed.
impl->os_stack_trace_getter()->UponLeavingGTest();
- HandleExceptionsInMethodIfSupported(
+ internal::HandleExceptionsInMethodIfSupported(
this, &Test::TearDown, "TearDown()");
}
@@ -2168,16 +2174,18 @@ bool Test::HasNonfatalFailure() {
// Constructs a TestInfo object. It assumes ownership of the test factory
// object.
+// TODO(vladl@google.com): Make a_test_case_name and a_name const string&'s
+// to signify they cannot be NULLs.
TestInfo::TestInfo(const char* a_test_case_name,
const char* a_name,
- const char* a_test_case_comment,
- const char* a_comment,
+ const char* a_type_param,
+ const char* a_value_param,
internal::TypeId fixture_class_id,
internal::TestFactoryBase* factory)
: test_case_name_(a_test_case_name),
name_(a_name),
- test_case_comment_(a_test_case_comment),
- comment_(a_comment),
+ type_param_(a_type_param ? new std::string(a_type_param) : NULL),
+ value_param_(a_value_param ? new std::string(a_value_param) : NULL),
fixture_class_id_(fixture_class_id),
should_run_(false),
is_disabled_(false),
@@ -2197,10 +2205,10 @@ namespace internal {
//
// test_case_name: name of the test case
// name: name of the test
-// test_case_comment: a comment on the test case that will be included in
-// the test output
-// comment: a comment on the test that will be included in the
-// test output
+// type_param: the name of the test's type parameter, or NULL if
+// this is not a typed or a type-parameterized test.
+// value_param: text representation of the test's value parameter,
+// or NULL if this is not a value-parameterized test.
// fixture_class_id: ID of the test fixture class
// set_up_tc: pointer to the function that sets up the test case
// tear_down_tc: pointer to the function that tears down the test case
@@ -2209,13 +2217,14 @@ namespace internal {
// ownership of the factory object.
TestInfo* MakeAndRegisterTestInfo(
const char* test_case_name, const char* name,
- const char* test_case_comment, const char* comment,
+ const char* type_param,
+ const char* value_param,
TypeId fixture_class_id,
SetUpTestCaseFunc set_up_tc,
TearDownTestCaseFunc tear_down_tc,
TestFactoryBase* factory) {
TestInfo* const test_info =
- new TestInfo(test_case_name, name, test_case_comment, comment,
+ new TestInfo(test_case_name, name, type_param, value_param,
fixture_class_id, factory);
GetUnitTestImpl()->AddTestInfo(set_up_tc, tear_down_tc, test_info);
return test_info;
@@ -2306,7 +2315,7 @@ void TestInfo::Run() {
impl->os_stack_trace_getter()->UponLeavingGTest();
// Creates the test object.
- Test* const test = HandleExceptionsInMethodIfSupported(
+ Test* const test = internal::HandleExceptionsInMethodIfSupported(
factory_, &internal::TestFactoryBase::CreateTest,
"the test fixture's constructor");
@@ -2320,7 +2329,7 @@ void TestInfo::Run() {
// Deletes the test object.
impl->os_stack_trace_getter()->UponLeavingGTest();
- HandleExceptionsInMethodIfSupported(
+ internal::HandleExceptionsInMethodIfSupported(
test, &Test::DeleteSelf_, "the test fixture's destructor");
result_.set_elapsed_time(internal::GetTimeInMillis() - start);
@@ -2364,13 +2373,15 @@ int TestCase::total_test_count() const {
// Arguments:
//
// name: name of the test case
+// a_type_param: the name of the test case's type parameter, or NULL if
+// this is not a typed or a type-parameterized test case.
// set_up_tc: pointer to the function that sets up the test case
// tear_down_tc: pointer to the function that tears down the test case
-TestCase::TestCase(const char* a_name, const char* a_comment,
+TestCase::TestCase(const char* a_name, const char* a_type_param,
Test::SetUpTestCaseFunc set_up_tc,
Test::TearDownTestCaseFunc tear_down_tc)
: name_(a_name),
- comment_(a_comment),
+ type_param_(a_type_param ? new std::string(a_type_param) : NULL),
set_up_tc_(set_up_tc),
tear_down_tc_(tear_down_tc),
should_run_(false),
@@ -2415,7 +2426,7 @@ void TestCase::Run() {
repeater->OnTestCaseStart(*this);
impl->os_stack_trace_getter()->UponLeavingGTest();
- HandleExceptionsInMethodIfSupported(
+ internal::HandleExceptionsInMethodIfSupported(
this, &TestCase::RunSetUpTestCase, "SetUpTestCase()");
const internal::TimeInMillis start = internal::GetTimeInMillis();
@@ -2425,7 +2436,7 @@ void TestCase::Run() {
elapsed_time_ = internal::GetTimeInMillis() - start;
impl->os_stack_trace_getter()->UponLeavingGTest();
- HandleExceptionsInMethodIfSupported(
+ internal::HandleExceptionsInMethodIfSupported(
this, &TestCase::RunTearDownTestCase, "TearDownTestCase()");
repeater->OnTestCaseEnd(*this);
@@ -2642,15 +2653,19 @@ void ColoredPrintf(GTestColor color, const char* fmt, ...) {
}
void PrintFullTestCommentIfPresent(const TestInfo& test_info) {
- const char* const comment = test_info.comment();
- const char* const test_case_comment = test_info.test_case_comment();
-
- if (test_case_comment[0] != '\0' || comment[0] != '\0') {
- printf(", where %s", test_case_comment);
- if (test_case_comment[0] != '\0' && comment[0] != '\0') {
- printf(" and ");
+ const char* const type_param = test_info.type_param();
+ const char* const value_param = test_info.value_param();
+
+ if (type_param != NULL || value_param != NULL) {
+ printf(", where ");
+ if (type_param != NULL) {
+ printf("TypeParam = %s", type_param);
+ if (value_param != NULL)
+ printf(" and ");
+ }
+ if (value_param != NULL) {
+ printf("GetParam() = %s", value_param);
}
- printf("%s", comment);
}
}
@@ -2733,10 +2748,10 @@ void PrettyUnitTestResultPrinter::OnTestCaseStart(const TestCase& test_case) {
FormatCountableNoun(test_case.test_to_run_count(), "test", "tests");
ColoredPrintf(COLOR_GREEN, "[----------] ");
printf("%s from %s", counts.c_str(), test_case_name_.c_str());
- if (test_case.comment()[0] == '\0') {
+ if (test_case.type_param() == NULL) {
printf("\n");
} else {
- printf(", where %s\n", test_case.comment());
+ printf(", where TypeParam = %s\n", test_case.type_param());
}
fflush(stdout);
}
@@ -3202,8 +3217,18 @@ void XmlUnitTestResultPrinter::OutputXmlTestInfo(::std::ostream* stream,
const TestInfo& test_info) {
const TestResult& result = *test_info.result();
*stream << " <testcase name=\""
- << EscapeXmlAttribute(test_info.name()).c_str()
- << "\" status=\""
+ << EscapeXmlAttribute(test_info.name()).c_str() << "\"";
+
+ if (test_info.value_param() != NULL) {
+ *stream << " value_param=\"" << EscapeXmlAttribute(test_info.value_param())
+ << "\"";
+ }
+ if (test_info.type_param() != NULL) {
+ *stream << " type_param=\"" << EscapeXmlAttribute(test_info.type_param())
+ << "\"";
+ }
+
+ *stream << " status=\""
<< (test_info.should_run() ? "run" : "notrun")
<< "\" time=\""
<< FormatTimeInMillisAsSeconds(result.elapsed_time())
@@ -3832,7 +3857,7 @@ int UnitTest::Run() {
}
#endif // GTEST_HAS_SEH
- return HandleExceptionsInMethodIfSupported(
+ return internal::HandleExceptionsInMethodIfSupported(
impl(),
&internal::UnitTestImpl::RunAllTests,
"auxiliary test code (environments or event listeners)") ? 0 : 1;
@@ -4053,10 +4078,12 @@ class TestCaseNameIs {
// Arguments:
//
// test_case_name: name of the test case
+// type_param: the name of the test case's type parameter, or NULL if
+// this is not a typed or a type-parameterized test case.
// set_up_tc: pointer to the function that sets up the test case
// tear_down_tc: pointer to the function that tears down the test case
TestCase* UnitTestImpl::GetTestCase(const char* test_case_name,
- const char* comment,
+ const char* type_param,
Test::SetUpTestCaseFunc set_up_tc,
Test::TearDownTestCaseFunc tear_down_tc) {
// Can we find a TestCase with the given name?
@@ -4069,7 +4096,7 @@ TestCase* UnitTestImpl::GetTestCase(const char* test_case_name,
// No. Let's create one.
TestCase* const new_test_case =
- new TestCase(test_case_name, comment, set_up_tc, tear_down_tc);
+ new TestCase(test_case_name, type_param, set_up_tc, tear_down_tc);
// Is this a death test case?
if (internal::UnitTestOptions::MatchesFilter(String(test_case_name),
@@ -4711,8 +4738,9 @@ static const char kColorEncodedHelpMessage[] =
" Turn assertion failures into debugger break-points.\n"
" @G--" GTEST_FLAG_PREFIX_ "throw_on_failure@D\n"
" Turn assertion failures into C++ exceptions.\n"
-" @G--" GTEST_FLAG_PREFIX_ "catch_exceptions@D\n"
-" Suppress pop-ups caused by exceptions.\n"
+" @G--" GTEST_FLAG_PREFIX_ "catch_exceptions=0@D\n"
+" Do not report exceptions as test failures. Instead, allow them\n"
+" to crash the program or throw a pop-up (on Windows).\n"
"\n"
"Except for @G--" GTEST_FLAG_PREFIX_ "list_tests@D, you can alternatively set "
"the corresponding\n"
diff --git a/testing/gtest/test/gtest-death-test_ex_test.cc b/testing/gtest/test/gtest-death-test_ex_test.cc
new file mode 100644
index 0000000..71cc7a3
--- /dev/null
+++ b/testing/gtest/test/gtest-death-test_ex_test.cc
@@ -0,0 +1,93 @@
+// Copyright 2010, 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: vladl@google.com (Vlad Losev)
+//
+// Tests that verify interaction of exceptions and death tests.
+
+#include "gtest/gtest-death-test.h"
+#include "gtest/gtest.h"
+
+#if GTEST_HAS_DEATH_TEST
+
+#if GTEST_HAS_SEH
+#include <windows.h> // For RaiseException().
+#endif
+
+#include "gtest/gtest-spi.h"
+
+#if GTEST_HAS_EXCEPTIONS
+
+#include <exception> // For std::exception.
+
+// Tests that death tests report thrown exceptions as failures and that the
+// exceptions do not escape death test macros.
+TEST(CxxExceptionDeathTest, ExceptionIsFailure) {
+ try {
+ EXPECT_NONFATAL_FAILURE(EXPECT_DEATH(throw 1, ""), "threw an exception");
+ } catch (...) { // NOLINT
+ FAIL() << "An exception escaped a death test macro invocation "
+ << "with catch_exceptions "
+ << (testing::GTEST_FLAG(catch_exceptions) ? "enabled" : "disabled");
+ }
+}
+
+class TestException : public std::exception {
+ public:
+ virtual const char* what() const throw() { return "exceptional message"; }
+};
+
+TEST(CxxExceptionDeathTest, PrintsMessageForStdExceptions) {
+ // Verifies that the exception message is quoted in the failure text.
+ EXPECT_NONFATAL_FAILURE(EXPECT_DEATH(throw TestException(), ""),
+ "exceptional message");
+ // Verifies that the location is mentioned in the failure text.
+ EXPECT_NONFATAL_FAILURE(EXPECT_DEATH(throw TestException(), ""),
+ "gtest-death-test_ex_test.cc");
+}
+#endif // GTEST_HAS_EXCEPTIONS
+
+#if GTEST_HAS_SEH
+// Tests that enabling interception of SEH exceptions with the
+// catch_exceptions flag does not interfere with SEH exceptions being
+// treated as death by death tests.
+TEST(SehExceptionDeasTest, CatchExceptionsDoesNotInterfere) {
+ EXPECT_DEATH(RaiseException(42, 0x0, 0, NULL), "")
+ << "with catch_exceptions "
+ << (testing::GTEST_FLAG(catch_exceptions) ? "enabled" : "disabled");
+}
+#endif
+
+#endif // GTEST_HAS_DEATH_TEST
+
+int main(int argc, char** argv) {
+ testing::InitGoogleTest(&argc, argv);
+ testing::GTEST_FLAG(catch_exceptions) = GTEST_ENABLE_CATCH_EXCEPTIONS_ != 0;
+ return RUN_ALL_TESTS();
+}
diff --git a/testing/gtest/test/gtest-death-test_test.cc b/testing/gtest/test/gtest-death-test_test.cc
index 2f1d385..6cc017b 100644
--- a/testing/gtest/test/gtest-death-test_test.cc
+++ b/testing/gtest/test/gtest-death-test_test.cc
@@ -103,9 +103,10 @@ class ReplaceDeathTestFactory {
} // namespace internal
} // namespace testing
-void DieInside(const char* function) {
- fprintf(stderr, "death inside %s().", function);
- fflush(stderr);
+void DieWithMessage(const ::std::string& message) {
+ fprintf(stderr, "%s", message.c_str());
+ fflush(stderr); // Make sure the text is printed before the process exits.
+
// We call _exit() instead of exit(), as the former is a direct
// system call and thus safer in the presence of threads. exit()
// will invoke user-defined exit-hooks, which may do dangerous
@@ -118,6 +119,10 @@ void DieInside(const char* function) {
_exit(1);
}
+void DieInside(const ::std::string& function) {
+ DieWithMessage("death inside " + function + "().");
+}
+
// Tests that death tests work.
class TestForDeathTest : public testing::Test {
@@ -538,15 +543,18 @@ TEST_F(TestForDeathTest, SingleEvaluation) {
}
// Tests that run-away death tests are reported as failures.
-TEST_F(TestForDeathTest, Runaway) {
+TEST_F(TestForDeathTest, RunawayIsFailure) {
EXPECT_NONFATAL_FAILURE(EXPECT_DEATH(static_cast<void>(0), "Foo"),
"failed to die.");
+}
+// Tests that death tests report executing 'return' in the statement as
+// failure.
+TEST_F(TestForDeathTest, ReturnIsFailure) {
EXPECT_FATAL_FAILURE(ASSERT_DEATH(return, "Bar"),
"illegal return in test statement.");
}
-
// Tests that EXPECT_DEBUG_DEATH works as expected,
// that is, in debug mode, it:
// 1. Asserts on death.
@@ -683,6 +691,57 @@ TEST_F(TestForDeathTest, InvalidStyle) {
}, "This failure is expected.");
}
+TEST_F(TestForDeathTest, DeathTestFailedOutput) {
+ testing::GTEST_FLAG(death_test_style) = "fast";
+ EXPECT_NONFATAL_FAILURE(
+ EXPECT_DEATH(DieWithMessage("death\n"),
+ "expected message"),
+ "Actual msg:\n"
+ "[ DEATH ] death\n");
+}
+
+TEST_F(TestForDeathTest, DeathTestUnexpectedReturnOutput) {
+ testing::GTEST_FLAG(death_test_style) = "fast";
+ EXPECT_NONFATAL_FAILURE(
+ EXPECT_DEATH({
+ fprintf(stderr, "returning\n");
+ fflush(stderr);
+ return;
+ }, ""),
+ " Result: illegal return in test statement.\n"
+ " Error msg:\n"
+ "[ DEATH ] returning\n");
+}
+
+TEST_F(TestForDeathTest, DeathTestBadExitCodeOutput) {
+ testing::GTEST_FLAG(death_test_style) = "fast";
+ EXPECT_NONFATAL_FAILURE(
+ EXPECT_EXIT(DieWithMessage("exiting with rc 1\n"),
+ testing::ExitedWithCode(3),
+ "expected message"),
+ " Result: died but not with expected exit code:\n"
+ " Exited with exit status 1\n"
+ "Actual msg:\n"
+ "[ DEATH ] exiting with rc 1\n");
+}
+
+TEST_F(TestForDeathTest, DeathTestMultiLineMatchFail) {
+ testing::GTEST_FLAG(death_test_style) = "fast";
+ EXPECT_NONFATAL_FAILURE(
+ EXPECT_DEATH(DieWithMessage("line 1\nline 2\nline 3\n"),
+ "line 1\nxyz\nline 3\n"),
+ "Actual msg:\n"
+ "[ DEATH ] line 1\n"
+ "[ DEATH ] line 2\n"
+ "[ DEATH ] line 3\n");
+}
+
+TEST_F(TestForDeathTest, DeathTestMultiLineMatchPass) {
+ testing::GTEST_FLAG(death_test_style) = "fast";
+ EXPECT_DEATH(DieWithMessage("line 1\nline 2\nline 3\n"),
+ "line 1\nline 2\nline 3\n");
+}
+
// A DeathTestFactory that returns MockDeathTests.
class MockDeathTestFactory : public DeathTestFactory {
public:
diff --git a/testing/gtest/test/gtest-linked_ptr_test.cc b/testing/gtest/test/gtest-linked_ptr_test.cc
index efd6b1e..0d5508a 100644
--- a/testing/gtest/test/gtest-linked_ptr_test.cc
+++ b/testing/gtest/test/gtest-linked_ptr_test.cc
@@ -77,7 +77,8 @@ class LinkedPtrTest : public testing::Test {
TEST_F(LinkedPtrTest, GeneralTest) {
{
linked_ptr<A> a0, a1, a2;
- a0 = a0;
+ // Use explicit function call notation here to suppress self-assign warning.
+ a0.operator=(a0);
a1 = a2;
ASSERT_EQ(a0.get(), static_cast<A*>(NULL));
ASSERT_EQ(a1.get(), static_cast<A*>(NULL));
diff --git a/testing/gtest/test/gtest-param-test_test.cc b/testing/gtest/test/gtest-param-test_test.cc
index c920f4f..5a681d8 100644
--- a/testing/gtest/test/gtest-param-test_test.cc
+++ b/testing/gtest/test/gtest-param-test_test.cc
@@ -792,19 +792,17 @@ INSTANTIATE_TEST_CASE_P(FourElemSequence, SeparateInstanceTest, Range(1, 4));
// sequence element used to instantiate the test.
class NamingTest : public TestWithParam<int> {};
-TEST_P(NamingTest, TestsAreNamedAndCommentedCorrectly) {
+TEST_P(NamingTest, TestsReportCorrectNamesAndParameters) {
const ::testing::TestInfo* const test_info =
::testing::UnitTest::GetInstance()->current_test_info();
EXPECT_STREQ("ZeroToFiveSequence/NamingTest", test_info->test_case_name());
Message index_stream;
- index_stream << "TestsAreNamedAndCommentedCorrectly/" << GetParam();
+ index_stream << "TestsReportCorrectNamesAndParameters/" << GetParam();
EXPECT_STREQ(index_stream.GetString().c_str(), test_info->name());
- const ::std::string comment =
- "GetParam() = " + ::testing::PrintToString(GetParam());
- EXPECT_EQ(comment, test_info->comment());
+ EXPECT_EQ(::testing::PrintToString(GetParam()), test_info->value_param());
}
INSTANTIATE_TEST_CASE_P(ZeroToFiveSequence, NamingTest, Range(0, 5));
@@ -823,19 +821,50 @@ class Unstreamable {
class CommentTest : public TestWithParam<Unstreamable> {};
-TEST_P(CommentTest, TestsWithUnstreamableParamsCommentedCorrectly) {
+TEST_P(CommentTest, TestsCorrectlyReportUnstreamableParams) {
const ::testing::TestInfo* const test_info =
::testing::UnitTest::GetInstance()->current_test_info();
- const ::std::string comment =
- "GetParam() = " + ::testing::PrintToString(GetParam());
- EXPECT_EQ(comment, test_info->comment());
+ EXPECT_EQ(::testing::PrintToString(GetParam()), test_info->value_param());
}
INSTANTIATE_TEST_CASE_P(InstantiationWithComments,
CommentTest,
Values(Unstreamable(1)));
+// Verify that we can create a hierarchy of test fixtures, where the base
+// class fixture is not parameterized and the derived class is. In this case
+// ParameterizedDerivedTest inherits from NonParameterizedBaseTest. We
+// perform simple tests on both.
+class NonParameterizedBaseTest : public ::testing::Test {
+ public:
+ NonParameterizedBaseTest() : n_(17) { }
+ protected:
+ int n_;
+};
+
+class ParameterizedDerivedTest : public NonParameterizedBaseTest,
+ public ::testing::WithParamInterface<int> {
+ protected:
+ ParameterizedDerivedTest() : count_(0) { }
+ int count_;
+ static int global_count_;
+};
+
+int ParameterizedDerivedTest::global_count_ = 0;
+
+TEST_F(NonParameterizedBaseTest, FixtureIsInitialized) {
+ EXPECT_EQ(17, n_);
+}
+
+TEST_P(ParameterizedDerivedTest, SeesSequence) {
+ EXPECT_EQ(17, n_);
+ EXPECT_EQ(0, count_++);
+ EXPECT_EQ(GetParam(), global_count_++);
+}
+
+INSTANTIATE_TEST_CASE_P(RangeZeroToFive, ParameterizedDerivedTest, Range(0, 5));
+
#endif // GTEST_HAS_PARAM_TEST
TEST(CompileTest, CombineIsDefinedOnlyWhenGtestHasParamTestIsDefined) {
diff --git a/testing/gtest/test/gtest-port_test.cc b/testing/gtest/test/gtest-port_test.cc
index bf42d8b..5afba2d 100644
--- a/testing/gtest/test/gtest-port_test.cc
+++ b/testing/gtest/test/gtest-port_test.cc
@@ -79,12 +79,12 @@ class Derived : public Base {
TEST(ImplicitCastTest, ConvertsPointers) {
Derived derived(0);
- EXPECT_TRUE(&derived == ::testing::internal::implicit_cast<Base*>(&derived));
+ EXPECT_TRUE(&derived == ::testing::internal::ImplicitCast_<Base*>(&derived));
}
TEST(ImplicitCastTest, CanUseInheritance) {
Derived derived(1);
- Base base = ::testing::internal::implicit_cast<Base>(derived);
+ Base base = ::testing::internal::ImplicitCast_<Base>(derived);
EXPECT_EQ(derived.member(), base.member());
}
@@ -103,7 +103,7 @@ class Castable {
TEST(ImplicitCastTest, CanUseNonConstCastOperator) {
bool converted = false;
Castable castable(&converted);
- Base base = ::testing::internal::implicit_cast<Base>(castable);
+ Base base = ::testing::internal::ImplicitCast_<Base>(castable);
EXPECT_TRUE(converted);
}
@@ -122,7 +122,7 @@ class ConstCastable {
TEST(ImplicitCastTest, CanUseConstCastOperatorOnConstValues) {
bool converted = false;
const ConstCastable const_castable(&converted);
- Base base = ::testing::internal::implicit_cast<Base>(const_castable);
+ Base base = ::testing::internal::ImplicitCast_<Base>(const_castable);
EXPECT_TRUE(converted);
}
@@ -148,14 +148,14 @@ TEST(ImplicitCastTest, CanSelectBetweenConstAndNonConstCasrAppropriately) {
bool converted = false;
bool const_converted = false;
ConstAndNonConstCastable castable(&converted, &const_converted);
- Base base = ::testing::internal::implicit_cast<Base>(castable);
+ Base base = ::testing::internal::ImplicitCast_<Base>(castable);
EXPECT_TRUE(converted);
EXPECT_FALSE(const_converted);
converted = false;
const_converted = false;
const ConstAndNonConstCastable const_castable(&converted, &const_converted);
- base = ::testing::internal::implicit_cast<Base>(const_castable);
+ base = ::testing::internal::ImplicitCast_<Base>(const_castable);
EXPECT_FALSE(converted);
EXPECT_TRUE(const_converted);
}
@@ -167,7 +167,8 @@ class To {
TEST(ImplicitCastTest, CanUseImplicitConstructor) {
bool converted = false;
- To to = ::testing::internal::implicit_cast<To>(&converted);
+ To to = ::testing::internal::ImplicitCast_<To>(&converted);
+ (void)to;
EXPECT_TRUE(converted);
}
diff --git a/testing/gtest/test/gtest-printers_test.cc b/testing/gtest/test/gtest-printers_test.cc
index 5eabd23..da1fbc2 100644
--- a/testing/gtest/test/gtest-printers_test.cc
+++ b/testing/gtest/test/gtest-printers_test.cc
@@ -658,6 +658,20 @@ TEST(PrintStringTest, StringInStdNamespace) {
Print(str));
}
+TEST(PrintStringTest, StringAmbiguousHex) {
+ // "\x6BANANA" is ambiguous, it can be interpreted as starting with either of:
+ // '\x6', '\x6B', or '\x6BA'.
+
+ // a hex escaping sequence following by a decimal digit
+ EXPECT_EQ("\"0\\x12\" \"3\"", Print(::std::string("0\x12" "3")));
+ // a hex escaping sequence following by a hex digit (lower-case)
+ EXPECT_EQ("\"mm\\x6\" \"bananas\"", Print(::std::string("mm\x6" "bananas")));
+ // a hex escaping sequence following by a hex digit (upper-case)
+ EXPECT_EQ("\"NOM\\x6\" \"BANANA\"", Print(::std::string("NOM\x6" "BANANA")));
+ // a hex escaping sequence following by a non-xdigit
+ EXPECT_EQ("\"!\\x5-!\"", Print(::std::string("!\x5-!")));
+}
+
// Tests printing ::wstring and ::std::wstring.
#if GTEST_HAS_GLOBAL_WSTRING
@@ -680,6 +694,16 @@ TEST(PrintWideStringTest, StringInStdNamespace) {
"\\xD3\\x576\\x8D3\\xC74D a\\0\"",
Print(str));
}
+
+TEST(PrintWideStringTest, StringAmbiguousHex) {
+ // same for wide strings.
+ EXPECT_EQ("L\"0\\x12\" L\"3\"", Print(::std::wstring(L"0\x12" L"3")));
+ EXPECT_EQ("L\"mm\\x6\" L\"bananas\"",
+ Print(::std::wstring(L"mm\x6" L"bananas")));
+ EXPECT_EQ("L\"NOM\\x6\" L\"BANANA\"",
+ Print(::std::wstring(L"NOM\x6" L"BANANA")));
+ EXPECT_EQ("L\"!\\x5-!\"", Print(::std::wstring(L"!\x5-!")));
+}
#endif // GTEST_HAS_STD_WSTRING
// Tests printing types that support generic streaming (i.e. streaming
diff --git a/testing/gtest/test/gtest-unittest-api_test.cc b/testing/gtest/test/gtest-unittest-api_test.cc
index ed5dea8..07083e5 100644
--- a/testing/gtest/test/gtest-unittest-api_test.cc
+++ b/testing/gtest/test/gtest-unittest-api_test.cc
@@ -103,12 +103,6 @@ TYPED_TEST(TestCaseWithCommentTest, Dummy) {}
const int kTypedTestCases = 1;
const int kTypedTests = 1;
-
-String GetExpectedTestCaseComment() {
- Message comment;
- comment << "TypeParam = " << GetTypeName<int>().c_str();
- return comment.GetString();
-}
#else
const int kTypedTestCases = 0;
const int kTypedTests = 0;
@@ -143,12 +137,19 @@ TEST(ApiTest, UnitTestImmutableAccessorsWork) {
RecordProperty("key", "value");
}
+AssertionResult IsNull(const char* str) {
+ if (str != NULL) {
+ return testing::AssertionFailure() << "argument is " << str;
+ }
+ return AssertionSuccess();
+}
+
TEST(ApiTest, TestCaseImmutableAccessorsWork) {
const TestCase* test_case = UnitTestHelper::FindTestCase("ApiTest");
ASSERT_TRUE(test_case != NULL);
EXPECT_STREQ("ApiTest", test_case->name());
- EXPECT_STREQ("", test_case->comment());
+ EXPECT_TRUE(IsNull(test_case->type_param()));
EXPECT_TRUE(test_case->should_run());
EXPECT_EQ(1, test_case->disabled_test_count());
EXPECT_EQ(3, test_case->test_to_run_count());
@@ -158,26 +159,26 @@ TEST(ApiTest, TestCaseImmutableAccessorsWork) {
EXPECT_STREQ("DISABLED_Dummy1", tests[0]->name());
EXPECT_STREQ("ApiTest", tests[0]->test_case_name());
- EXPECT_STREQ("", tests[0]->comment());
- EXPECT_STREQ("", tests[0]->test_case_comment());
+ EXPECT_TRUE(IsNull(tests[0]->value_param()));
+ EXPECT_TRUE(IsNull(tests[0]->type_param()));
EXPECT_FALSE(tests[0]->should_run());
EXPECT_STREQ("TestCaseDisabledAccessorsWork", tests[1]->name());
EXPECT_STREQ("ApiTest", tests[1]->test_case_name());
- EXPECT_STREQ("", tests[1]->comment());
- EXPECT_STREQ("", tests[1]->test_case_comment());
+ EXPECT_TRUE(IsNull(tests[1]->value_param()));
+ EXPECT_TRUE(IsNull(tests[1]->type_param()));
EXPECT_TRUE(tests[1]->should_run());
EXPECT_STREQ("TestCaseImmutableAccessorsWork", tests[2]->name());
EXPECT_STREQ("ApiTest", tests[2]->test_case_name());
- EXPECT_STREQ("", tests[2]->comment());
- EXPECT_STREQ("", tests[2]->test_case_comment());
+ EXPECT_TRUE(IsNull(tests[2]->value_param()));
+ EXPECT_TRUE(IsNull(tests[2]->type_param()));
EXPECT_TRUE(tests[2]->should_run());
EXPECT_STREQ("UnitTestImmutableAccessorsWork", tests[3]->name());
EXPECT_STREQ("ApiTest", tests[3]->test_case_name());
- EXPECT_STREQ("", tests[3]->comment());
- EXPECT_STREQ("", tests[3]->test_case_comment());
+ EXPECT_TRUE(IsNull(tests[3]->value_param()));
+ EXPECT_TRUE(IsNull(tests[3]->type_param()));
EXPECT_TRUE(tests[3]->should_run());
delete[] tests;
@@ -188,7 +189,7 @@ TEST(ApiTest, TestCaseImmutableAccessorsWork) {
ASSERT_TRUE(test_case != NULL);
EXPECT_STREQ("TestCaseWithCommentTest/0", test_case->name());
- EXPECT_STREQ(GetExpectedTestCaseComment().c_str(), test_case->comment());
+ EXPECT_STREQ(GetTypeName<int>().c_str(), test_case->type_param());
EXPECT_TRUE(test_case->should_run());
EXPECT_EQ(0, test_case->disabled_test_count());
EXPECT_EQ(1, test_case->test_to_run_count());
@@ -198,9 +199,8 @@ TEST(ApiTest, TestCaseImmutableAccessorsWork) {
EXPECT_STREQ("Dummy", tests[0]->name());
EXPECT_STREQ("TestCaseWithCommentTest/0", tests[0]->test_case_name());
- EXPECT_STREQ("", tests[0]->comment());
- EXPECT_STREQ(GetExpectedTestCaseComment().c_str(),
- tests[0]->test_case_comment());
+ EXPECT_TRUE(IsNull(tests[0]->value_param()));
+ EXPECT_STREQ(GetTypeName<int>().c_str(), tests[0]->type_param());
EXPECT_TRUE(tests[0]->should_run());
delete[] tests;
@@ -212,7 +212,7 @@ TEST(ApiTest, TestCaseDisabledAccessorsWork) {
ASSERT_TRUE(test_case != NULL);
EXPECT_STREQ("DISABLED_Test", test_case->name());
- EXPECT_STREQ("", test_case->comment());
+ EXPECT_TRUE(IsNull(test_case->type_param()));
EXPECT_FALSE(test_case->should_run());
EXPECT_EQ(1, test_case->disabled_test_count());
EXPECT_EQ(0, test_case->test_to_run_count());
@@ -221,8 +221,8 @@ TEST(ApiTest, TestCaseDisabledAccessorsWork) {
const TestInfo* const test_info = test_case->GetTestInfo(0);
EXPECT_STREQ("Dummy2", test_info->name());
EXPECT_STREQ("DISABLED_Test", test_info->test_case_name());
- EXPECT_STREQ("", test_info->comment());
- EXPECT_STREQ("", test_info->test_case_comment());
+ EXPECT_TRUE(IsNull(test_info->value_param()));
+ EXPECT_TRUE(IsNull(test_info->type_param()));
EXPECT_FALSE(test_info->should_run());
}
@@ -247,7 +247,7 @@ class FinalSuccessChecker : public Environment {
const TestCase** const test_cases = UnitTestHelper::GetSortedTestCases();
EXPECT_STREQ("ApiTest", test_cases[0]->name());
- EXPECT_STREQ("", test_cases[0]->comment());
+ EXPECT_TRUE(IsNull(test_cases[0]->type_param()));
EXPECT_TRUE(test_cases[0]->should_run());
EXPECT_EQ(1, test_cases[0]->disabled_test_count());
ASSERT_EQ(4, test_cases[0]->total_test_count());
@@ -257,7 +257,7 @@ class FinalSuccessChecker : public Environment {
EXPECT_FALSE(test_cases[0]->Failed());
EXPECT_STREQ("DISABLED_Test", test_cases[1]->name());
- EXPECT_STREQ("", test_cases[1]->comment());
+ EXPECT_TRUE(IsNull(test_cases[1]->type_param()));
EXPECT_FALSE(test_cases[1]->should_run());
EXPECT_EQ(1, test_cases[1]->disabled_test_count());
ASSERT_EQ(1, test_cases[1]->total_test_count());
@@ -266,8 +266,7 @@ class FinalSuccessChecker : public Environment {
#if GTEST_HAS_TYPED_TEST
EXPECT_STREQ("TestCaseWithCommentTest/0", test_cases[2]->name());
- EXPECT_STREQ(GetExpectedTestCaseComment().c_str(),
- test_cases[2]->comment());
+ EXPECT_STREQ(GetTypeName<int>().c_str(), test_cases[2]->type_param());
EXPECT_TRUE(test_cases[2]->should_run());
EXPECT_EQ(0, test_cases[2]->disabled_test_count());
ASSERT_EQ(1, test_cases[2]->total_test_count());
@@ -285,24 +284,24 @@ class FinalSuccessChecker : public Environment {
EXPECT_STREQ("TestCaseDisabledAccessorsWork", tests[1]->name());
EXPECT_STREQ("ApiTest", tests[1]->test_case_name());
- EXPECT_STREQ("", tests[1]->comment());
- EXPECT_STREQ("", tests[1]->test_case_comment());
+ EXPECT_TRUE(IsNull(tests[1]->value_param()));
+ EXPECT_TRUE(IsNull(tests[1]->type_param()));
EXPECT_TRUE(tests[1]->should_run());
EXPECT_TRUE(tests[1]->result()->Passed());
EXPECT_EQ(0, tests[1]->result()->test_property_count());
EXPECT_STREQ("TestCaseImmutableAccessorsWork", tests[2]->name());
EXPECT_STREQ("ApiTest", tests[2]->test_case_name());
- EXPECT_STREQ("", tests[2]->comment());
- EXPECT_STREQ("", tests[2]->test_case_comment());
+ EXPECT_TRUE(IsNull(tests[2]->value_param()));
+ EXPECT_TRUE(IsNull(tests[2]->type_param()));
EXPECT_TRUE(tests[2]->should_run());
EXPECT_TRUE(tests[2]->result()->Passed());
EXPECT_EQ(0, tests[2]->result()->test_property_count());
EXPECT_STREQ("UnitTestImmutableAccessorsWork", tests[3]->name());
EXPECT_STREQ("ApiTest", tests[3]->test_case_name());
- EXPECT_STREQ("", tests[3]->comment());
- EXPECT_STREQ("", tests[3]->test_case_comment());
+ EXPECT_TRUE(IsNull(tests[3]->value_param()));
+ EXPECT_TRUE(IsNull(tests[3]->type_param()));
EXPECT_TRUE(tests[3]->should_run());
EXPECT_TRUE(tests[3]->result()->Passed());
EXPECT_EQ(1, tests[3]->result()->test_property_count());
@@ -318,9 +317,8 @@ class FinalSuccessChecker : public Environment {
EXPECT_STREQ("Dummy", tests[0]->name());
EXPECT_STREQ("TestCaseWithCommentTest/0", tests[0]->test_case_name());
- EXPECT_STREQ("", tests[0]->comment());
- EXPECT_STREQ(GetExpectedTestCaseComment().c_str(),
- tests[0]->test_case_comment());
+ EXPECT_TRUE(IsNull(tests[0]->value_param()));
+ EXPECT_STREQ(GetTypeName<int>().c_str(), tests[0]->type_param());
EXPECT_TRUE(tests[0]->should_run());
EXPECT_TRUE(tests[0]->result()->Passed());
EXPECT_EQ(0, tests[0]->result()->test_property_count());
diff --git a/testing/gtest/test/gtest_catch_exceptions_test.py b/testing/gtest/test/gtest_catch_exceptions_test.py
index 061c5c3..7fd7dba 100755
--- a/testing/gtest/test/gtest_catch_exceptions_test.py
+++ b/testing/gtest/test/gtest_catch_exceptions_test.py
@@ -42,9 +42,10 @@ import os
import gtest_test_utils
# Constants.
-LIST_TESTS_FLAG = '--gtest_list_tests'
-CATCH_EXCEPTIONS_FLAG = '--gtest_catch_exceptions=1'
-FILTER_FLAG='--gtest_filter'
+FLAG_PREFIX = '--gtest_'
+LIST_TESTS_FLAG = FLAG_PREFIX + 'list_tests'
+NO_CATCH_EXCEPTIONS_FLAG = FLAG_PREFIX + 'catch_exceptions=0'
+FILTER_FLAG = FLAG_PREFIX + 'filter'
# Path to the gtest_catch_exceptions_ex_test_ binary, compiled with
# exceptions enabled.
@@ -61,11 +62,9 @@ TEST_LIST = gtest_test_utils.Subprocess([EXE_PATH, LIST_TESTS_FLAG]).output
SUPPORTS_SEH_EXCEPTIONS = 'ThrowsSehException' in TEST_LIST
if SUPPORTS_SEH_EXCEPTIONS:
- BINARY_OUTPUT = gtest_test_utils.Subprocess([EXE_PATH,
- CATCH_EXCEPTIONS_FLAG]).output
+ BINARY_OUTPUT = gtest_test_utils.Subprocess([EXE_PATH]).output
-EX_BINARY_OUTPUT = gtest_test_utils.Subprocess([EX_EXE_PATH,
- CATCH_EXCEPTIONS_FLAG]).output
+EX_BINARY_OUTPUT = gtest_test_utils.Subprocess([EX_EXE_PATH]).output
# The tests.
if SUPPORTS_SEH_EXCEPTIONS:
@@ -208,7 +207,9 @@ class CatchCxxExceptionsTest(gtest_test_utils.TestCase):
FITLER_OUT_SEH_TESTS_FLAG = FILTER_FLAG + '=-*Seh*'
# By default, Google Test doesn't catch the exceptions.
uncaught_exceptions_ex_binary_output = gtest_test_utils.Subprocess(
- [EX_EXE_PATH, FITLER_OUT_SEH_TESTS_FLAG]).output
+ [EX_EXE_PATH,
+ NO_CATCH_EXCEPTIONS_FLAG,
+ FITLER_OUT_SEH_TESTS_FLAG]).output
self.assert_('Unhandled C++ exception terminating the program'
in uncaught_exceptions_ex_binary_output)
diff --git a/testing/gtest/test/gtest_env_var_test.py b/testing/gtest/test/gtest_env_var_test.py
index bcc0bfd..ac24337 100755
--- a/testing/gtest/test/gtest_env_var_test.py
+++ b/testing/gtest/test/gtest_env_var_test.py
@@ -92,9 +92,7 @@ class GTestEnvVarTest(gtest_test_utils.TestCase):
TestFlag('repeat', '999', '1')
TestFlag('throw_on_failure', '1', '0')
TestFlag('death_test_style', 'threadsafe', 'fast')
-
- if IS_WINDOWS:
- TestFlag('catch_exceptions', '1', '0')
+ TestFlag('catch_exceptions', '0', '1')
if IS_LINUX:
TestFlag('death_test_use_fork', '1', '0')
diff --git a/testing/gtest/test/gtest_help_test.py b/testing/gtest/test/gtest_help_test.py
index 0777106..093c838 100755
--- a/testing/gtest/test/gtest_help_test.py
+++ b/testing/gtest/test/gtest_help_test.py
@@ -74,7 +74,7 @@ HELP_REGEX = re.compile(
FLAG_PREFIX + r'output=.*' +
FLAG_PREFIX + r'break_on_failure.*' +
FLAG_PREFIX + r'throw_on_failure.*' +
- FLAG_PREFIX + r'catch_exceptions.*',
+ FLAG_PREFIX + r'catch_exceptions=0.*',
re.DOTALL)
diff --git a/testing/gtest/test/gtest_nc.cc b/testing/gtest/test/gtest_nc.cc
deleted file mode 100644
index 71acf2b..0000000
--- a/testing/gtest/test/gtest_nc.cc
+++ /dev/null
@@ -1,234 +0,0 @@
-// Copyright 2007, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// Author: wan@google.com (Zhanyong Wan)
-
-// This file is the input to a negative-compilation test for Google
-// Test. Code here is NOT supposed to compile. Its purpose is to
-// verify that certain incorrect usages of the Google Test API are
-// indeed rejected by the compiler.
-//
-// We still need to write the negative-compilation test itself, which
-// will be tightly coupled with the build environment.
-//
-// TODO(wan@google.com): finish the negative-compilation test.
-
-#ifdef TEST_CANNOT_IGNORE_RUN_ALL_TESTS_RESULT
-// Tests that the result of RUN_ALL_TESTS() cannot be ignored.
-
-#include "gtest/gtest.h"
-
-int main(int argc, char** argv) {
- testing::InitGoogleTest(&argc, argv);
- RUN_ALL_TESTS(); // This line shouldn't compile.
-}
-
-#elif defined(TEST_USER_CANNOT_INCLUDE_GTEST_INTERNAL_INL_H)
-// Tests that a user cannot include gtest-internal-inl.h in his code.
-
-#include "src/gtest-internal-inl.h"
-
-#elif defined(TEST_CATCHES_DECLARING_SETUP_IN_TEST_FIXTURE_WITH_TYPO)
-// Tests that the compiler catches the typo when a user declares a
-// Setup() method in a test fixture.
-
-#include "gtest/gtest.h"
-
-class MyTest : public testing::Test {
- protected:
- void Setup() {}
-};
-
-#elif defined(TEST_CATCHES_CALLING_SETUP_IN_TEST_WITH_TYPO)
-// Tests that the compiler catches the typo when a user calls Setup()
-// from a test fixture.
-
-#include "gtest/gtest.h"
-
-class MyTest : public testing::Test {
- protected:
- virtual void SetUp() {
- testing::Test::Setup(); // Tries to call SetUp() in the parent class.
- }
-};
-
-#elif defined(TEST_CATCHES_DECLARING_SETUP_IN_ENVIRONMENT_WITH_TYPO)
-// Tests that the compiler catches the typo when a user declares a
-// Setup() method in a subclass of Environment.
-
-#include "gtest/gtest.h"
-
-class MyEnvironment : public testing::Environment {
- public:
- void Setup() {}
-};
-
-#elif defined(TEST_CATCHES_CALLING_SETUP_IN_ENVIRONMENT_WITH_TYPO)
-// Tests that the compiler catches the typo when a user calls Setup()
-// in an Environment.
-
-#include "gtest/gtest.h"
-
-class MyEnvironment : public testing::Environment {
- protected:
- virtual void SetUp() {
- // Tries to call SetUp() in the parent class.
- testing::Environment::Setup();
- }
-};
-
-#elif defined(TEST_CATCHES_WRONG_CASE_IN_TYPED_TEST_P)
-// Tests that the compiler catches using the wrong test case name in
-// TYPED_TEST_P.
-
-#include "gtest/gtest.h"
-
-template <typename T>
-class FooTest : public testing::Test {
-};
-
-template <typename T>
-class BarTest : public testing::Test {
-};
-
-TYPED_TEST_CASE_P(FooTest);
-TYPED_TEST_P(BarTest, A) {} // Wrong test case name.
-REGISTER_TYPED_TEST_CASE_P(FooTest, A);
-INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, testing::Types<int>);
-
-#elif defined(TEST_CATCHES_WRONG_CASE_IN_REGISTER_TYPED_TEST_CASE_P)
-// Tests that the compiler catches using the wrong test case name in
-// REGISTER_TYPED_TEST_CASE_P.
-
-#include "gtest/gtest.h"
-
-template <typename T>
-class FooTest : public testing::Test {
-};
-
-template <typename T>
-class BarTest : public testing::Test {
-};
-
-TYPED_TEST_CASE_P(FooTest);
-TYPED_TEST_P(FooTest, A) {}
-REGISTER_TYPED_TEST_CASE_P(BarTest, A); // Wrong test case name.
-INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, testing::Types<int>);
-
-#elif defined(TEST_CATCHES_WRONG_CASE_IN_INSTANTIATE_TYPED_TEST_CASE_P)
-// Tests that the compiler catches using the wrong test case name in
-// INSTANTIATE_TYPED_TEST_CASE_P.
-
-#include "gtest/gtest.h"
-
-template <typename T>
-class FooTest : public testing::Test {
-};
-
-template <typename T>
-class BarTest : public testing::Test {
-};
-
-TYPED_TEST_CASE_P(FooTest);
-TYPED_TEST_P(FooTest, A) {}
-REGISTER_TYPED_TEST_CASE_P(FooTest, A);
-
-// Wrong test case name.
-INSTANTIATE_TYPED_TEST_CASE_P(My, BarTest, testing::Types<int>);
-
-#elif defined(TEST_CATCHES_INSTANTIATE_TYPED_TESET_CASE_P_WITH_SAME_NAME_PREFIX)
-// Tests that the compiler catches instantiating TYPED_TEST_CASE_P
-// twice with the same name prefix.
-
-#include "gtest/gtest.h"
-
-template <typename T>
-class FooTest : public testing::Test {
-};
-
-TYPED_TEST_CASE_P(FooTest);
-TYPED_TEST_P(FooTest, A) {}
-REGISTER_TYPED_TEST_CASE_P(FooTest, A);
-
-INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, testing::Types<int>);
-
-// Wrong name prefix: "My" has been used.
-INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, testing::Types<double>);
-
-#elif defined(TEST_STATIC_ASSERT_TYPE_EQ_IS_NOT_A_TYPE)
-
-#include "gtest/gtest.h"
-
-// Tests that StaticAssertTypeEq<T1, T2> cannot be used as a type.
-testing::StaticAssertTypeEq<int, int> dummy;
-
-#elif defined(TEST_STATIC_ASSERT_TYPE_EQ_WORKS_IN_NAMESPACE)
-
-#include "gtest/gtest.h"
-
-// Tests that StaticAssertTypeEq<T1, T2> works in a namespace scope.
-static bool dummy = testing::StaticAssertTypeEq<int, const int>();
-
-#elif defined(TEST_STATIC_ASSERT_TYPE_EQ_WORKS_IN_CLASS)
-
-#include "gtest/gtest.h"
-
-template <typename T>
-class Helper {
- public:
- // Tests that StaticAssertTypeEq<T1, T2> works in a class.
- Helper() { testing::StaticAssertTypeEq<int, T>(); }
-
- void DoSomething() {}
-};
-
-void Test() {
- Helper<bool> h;
- h.DoSomething(); // To avoid the "unused variable" warning.
-}
-
-#elif defined(TEST_STATIC_ASSERT_TYPE_EQ_WORKS_IN_FUNCTION)
-
-#include "gtest/gtest.h"
-
-void Test() {
- // Tests that StaticAssertTypeEq<T1, T2> works inside a function.
- testing::StaticAssertTypeEq<const int, int>();
-}
-
-#else
-// A sanity test. This should compile.
-
-#include "gtest/gtest.h"
-
-int main() {
- return RUN_ALL_TESTS();
-}
-
-#endif
diff --git a/testing/gtest/test/gtest_nc_test.py b/testing/gtest/test/gtest_nc_test.py
deleted file mode 100755
index bf09234..0000000
--- a/testing/gtest/test/gtest_nc_test.py
+++ /dev/null
@@ -1,114 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2007, 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.
-
-"""Negative compilation test for Google Test."""
-
-__author__ = 'wan@google.com (Zhanyong Wan)'
-
-import os
-import sys
-import unittest
-
-
-IS_LINUX = os.name == 'posix' and os.uname()[0] == 'Linux'
-if not IS_LINUX:
- sys.exit(0) # Negative compilation tests are not supported on Windows & Mac.
-
-
-class GTestNCTest(unittest.TestCase):
- """Negative compilation test for Google Test."""
-
- def testCompilerError(self):
- """Verifies that erroneous code leads to expected compiler
- messages."""
-
- # Defines a list of test specs, where each element is a tuple
- # (test name, list of regexes for matching the compiler errors).
- test_specs = [
- ('CANNOT_IGNORE_RUN_ALL_TESTS_RESULT',
- [r'ignoring return value']),
-
- ('USER_CANNOT_INCLUDE_GTEST_INTERNAL_INL_H',
- [r'must not be included except by Google Test itself']),
-
- ('CATCHES_DECLARING_SETUP_IN_TEST_FIXTURE_WITH_TYPO',
- [r'Setup_should_be_spelled_SetUp']),
-
- ('CATCHES_CALLING_SETUP_IN_TEST_WITH_TYPO',
- [r'Setup_should_be_spelled_SetUp']),
-
- ('CATCHES_DECLARING_SETUP_IN_ENVIRONMENT_WITH_TYPO',
- [r'Setup_should_be_spelled_SetUp']),
-
- ('CATCHES_CALLING_SETUP_IN_ENVIRONMENT_WITH_TYPO',
- [r'Setup_should_be_spelled_SetUp']),
-
- ('CATCHES_WRONG_CASE_IN_TYPED_TEST_P',
- [r'BarTest.*was not declared', # GCC
- r'undeclared identifier .*BarTest', # Clang
- ]),
-
- ('CATCHES_WRONG_CASE_IN_REGISTER_TYPED_TEST_CASE_P',
- [r'BarTest.*was not declared', # GCC
- r'undeclared identifier .*BarTest', # Clang
- ]),
-
- ('CATCHES_WRONG_CASE_IN_INSTANTIATE_TYPED_TEST_CASE_P',
- [r'BarTest.*not declared', # GCC
- r'undeclared identifier .*BarTest', # Clang
- ]),
-
- ('CATCHES_INSTANTIATE_TYPED_TESET_CASE_P_WITH_SAME_NAME_PREFIX',
- [r'redefinition of.*My.*FooTest']),
-
- ('STATIC_ASSERT_TYPE_EQ_IS_NOT_A_TYPE',
- [r'StaticAssertTypeEq.* does not name a type', # GCC
- r'requires a type.*\n.*StaticAssertTypeEq', # Clang
- ]),
-
- ('STATIC_ASSERT_TYPE_EQ_WORKS_IN_NAMESPACE',
- [r'StaticAssertTypeEq.*int.*const int']),
-
- ('STATIC_ASSERT_TYPE_EQ_WORKS_IN_CLASS',
- [r'StaticAssertTypeEq.*int.*bool']),
-
- ('STATIC_ASSERT_TYPE_EQ_WORKS_IN_FUNCTION',
- [r'StaticAssertTypeEq.*const int.*int']),
-
- ('SANITY',
- None)
- ]
-
- # TODO(wan@google.com): verify that the test specs are satisfied.
-
-
-if __name__ == '__main__':
- unittest.main()
diff --git a/testing/gtest/test/gtest_unittest.cc b/testing/gtest/test/gtest_unittest.cc
index cb189a3..1069ecf 100644
--- a/testing/gtest/test/gtest_unittest.cc
+++ b/testing/gtest/test/gtest_unittest.cc
@@ -34,6 +34,7 @@
#include "gtest/gtest.h"
#include <vector>
+#include <ostream>
// Verifies that the command line flag variables can be accessed
// in code once <gtest/gtest.h> has been #included.
@@ -321,13 +322,11 @@ TEST(NullLiteralTest, IsTrueForNullLiterals) {
EXPECT_TRUE(GTEST_IS_NULL_LITERAL_(0));
EXPECT_TRUE(GTEST_IS_NULL_LITERAL_(0U));
EXPECT_TRUE(GTEST_IS_NULL_LITERAL_(0L));
- EXPECT_TRUE(GTEST_IS_NULL_LITERAL_(false));
#ifndef __BORLANDC__
// Some compilers may fail to detect some null pointer literals;
// as long as users of the framework don't use such literals, this
// is harmless.
EXPECT_TRUE(GTEST_IS_NULL_LITERAL_(1 - 1));
- EXPECT_TRUE(GTEST_IS_NULL_LITERAL_(true && false));
#endif
}
@@ -1149,7 +1148,8 @@ TEST(StringTest, CanBeAssignedNonEmpty) {
TEST(StringTest, CanBeAssignedSelf) {
String dest("hello");
- dest = dest;
+ // Use explicit function call notation here to suppress self-assign warning.
+ dest.operator=(dest);
EXPECT_STREQ("hello", dest.c_str());
}
@@ -3729,7 +3729,8 @@ TEST(AssertionTest, ASSERT_ANY_THROW) {
// compile.
TEST(AssertionTest, AssertPrecedence) {
ASSERT_EQ(1 < 2, true);
- ASSERT_EQ(true && false, false);
+ bool false_value = false;
+ ASSERT_EQ(true && false_value, false);
}
// A subroutine used by the following test.
@@ -4218,7 +4219,7 @@ TEST(ExpectTest, EXPECT_EQ_Double) {
TEST(ExpectTest, EXPECT_EQ_NULL) {
// A success.
const char* p = NULL;
- // Some older GCC versions may issue a spurious waring in this or the next
+ // Some older GCC versions may issue a spurious warning in this or the next
// assertion statement. This warning should not be suppressed with
// static_cast since the test verifies the ability to use bare NULL as the
// expected parameter to the macro.
@@ -4488,8 +4489,10 @@ TEST(MacroTest, SUCCEED) {
// Tests using bool values in {EXPECT|ASSERT}_EQ.
TEST(EqAssertionTest, Bool) {
EXPECT_EQ(true, true);
- EXPECT_FATAL_FAILURE(ASSERT_EQ(false, true),
- "Value of: true");
+ EXPECT_FATAL_FAILURE({
+ bool false_value = false;
+ ASSERT_EQ(false_value, true);
+ }, "Value of: true");
}
// Tests using int values in {EXPECT|ASSERT}_EQ.
@@ -4902,7 +4905,7 @@ TEST(AssertionResultTest, ConstructionWorks) {
EXPECT_STREQ("ghi", r5.message());
}
-// Tests that the negation fips the predicate result but keeps the message.
+// Tests that the negation flips the predicate result but keeps the message.
TEST(AssertionResultTest, NegationWorks) {
AssertionResult r1 = AssertionSuccess() << "abc";
EXPECT_FALSE(!r1);
@@ -4919,6 +4922,12 @@ TEST(AssertionResultTest, StreamingWorks) {
EXPECT_STREQ("abcd0true", r.message());
}
+TEST(AssertionResultTest, CanStreamOstreamManipulators) {
+ AssertionResult r = AssertionSuccess();
+ r << "Data" << std::endl << std::flush << std::ends << "Will be visible";
+ EXPECT_STREQ("Data\n\\0Will be visible", r.message());
+}
+
// Tests streaming a user type whose definition and operator << are
// both in the global namespace.
class Base {
@@ -6462,8 +6471,9 @@ TEST(ColoredOutputTest, UsesColorsWhenTermSupportsColors) {
// Verifies that StaticAssertTypeEq works in a namespace scope.
-static bool dummy1 = StaticAssertTypeEq<bool, bool>();
-static bool dummy2 = StaticAssertTypeEq<const int, const int>();
+static bool dummy1 GTEST_ATTRIBUTE_UNUSED_ = StaticAssertTypeEq<bool, bool>();
+static bool dummy2 GTEST_ATTRIBUTE_UNUSED_ =
+ StaticAssertTypeEq<const int, const int>();
// Verifies that StaticAssertTypeEq works in a class.
diff --git a/testing/gtest/test/gtest_xml_output_unittest.py b/testing/gtest/test/gtest_xml_output_unittest.py
index 6d44929..bdd5035 100755
--- a/testing/gtest/test/gtest_xml_output_unittest.py
+++ b/testing/gtest/test/gtest_xml_output_unittest.py
@@ -54,7 +54,7 @@ else:
STACK_TRACE_TEMPLATE = ""
EXPECTED_NON_EMPTY_XML = """<?xml version="1.0" encoding="UTF-8"?>
-<testsuites tests="15" failures="4" disabled="2" errors="0" time="*" name="AllTests">
+<testsuites tests="23" failures="4" disabled="2" errors="0" time="*" name="AllTests">
<testsuite name="SuccessfulTest" tests="1" failures="0" disabled="0" errors="0" time="*">
<testcase name="Succeeds" status="run" time="*" classname="SuccessfulTest"/>
</testsuite>
@@ -105,6 +105,24 @@ Invalid characters in brackets []%(stack)s]]></failure>
<testcase name="ExternalUtilityThatCallsRecordIntValuedProperty" status="run" time="*" classname="NoFixtureTest" key_for_utility_int="1"/>
<testcase name="ExternalUtilityThatCallsRecordStringValuedProperty" status="run" time="*" classname="NoFixtureTest" key_for_utility_string="1"/>
</testsuite>
+ <testsuite name="Single/ValueParamTest" tests="4" failures="0" disabled="0" errors="0" time="*">
+ <testcase name="HasValueParamAttribute/0" value_param="33" status="run" time="*" classname="Single/ValueParamTest" />
+ <testcase name="HasValueParamAttribute/1" value_param="42" status="run" time="*" classname="Single/ValueParamTest" />
+ <testcase name="AnotherTestThatHasValueParamAttribute/0" value_param="33" status="run" time="*" classname="Single/ValueParamTest" />
+ <testcase name="AnotherTestThatHasValueParamAttribute/1" value_param="42" status="run" time="*" classname="Single/ValueParamTest" />
+ </testsuite>
+ <testsuite name="TypedTest/0" tests="1" failures="0" disabled="0" errors="0" time="*">
+ <testcase name="HasTypeParamAttribute" type_param="*" status="run" time="*" classname="TypedTest/0" />
+ </testsuite>
+ <testsuite name="TypedTest/1" tests="1" failures="0" disabled="0" errors="0" time="*">
+ <testcase name="HasTypeParamAttribute" type_param="*" status="run" time="*" classname="TypedTest/1" />
+ </testsuite>
+ <testsuite name="Single/TypeParameterizedTestCase/0" tests="1" failures="0" disabled="0" errors="0" time="*">
+ <testcase name="HasTypeParamAttribute" type_param="*" status="run" time="*" classname="Single/TypeParameterizedTestCase/0" />
+ </testsuite>
+ <testsuite name="Single/TypeParameterizedTestCase/1" tests="1" failures="0" disabled="0" errors="0" time="*">
+ <testcase name="HasTypeParamAttribute" type_param="*" status="run" time="*" classname="Single/TypeParameterizedTestCase/1" />
+ </testsuite>
</testsuites>""" % {'stack': STACK_TRACE_TEMPLATE}
diff --git a/testing/gtest/test/gtest_xml_output_unittest_.cc b/testing/gtest/test/gtest_xml_output_unittest_.cc
index 693ffb9..741a887 100644
--- a/testing/gtest/test/gtest_xml_output_unittest_.cc
+++ b/testing/gtest/test/gtest_xml_output_unittest_.cc
@@ -42,9 +42,13 @@
using ::testing::InitGoogleTest;
using ::testing::TestEventListeners;
+using ::testing::TestWithParam;
using ::testing::UnitTest;
+using ::testing::Test;
+using ::testing::Types;
+using ::testing::Values;
-class SuccessfulTest : public testing::Test {
+class SuccessfulTest : public Test {
};
TEST_F(SuccessfulTest, Succeeds) {
@@ -52,14 +56,14 @@ TEST_F(SuccessfulTest, Succeeds) {
ASSERT_EQ(1, 1);
}
-class FailedTest : public testing::Test {
+class FailedTest : public Test {
};
TEST_F(FailedTest, Fails) {
ASSERT_EQ(1, 2);
}
-class DisabledTest : public testing::Test {
+class DisabledTest : public Test {
};
TEST_F(DisabledTest, DISABLED_test_not_run) {
@@ -91,7 +95,7 @@ TEST(InvalidCharactersTest, InvalidCharactersInMessage) {
FAIL() << "Invalid characters in brackets [\x1\x2]";
}
-class PropertyRecordingTest : public testing::Test {
+class PropertyRecordingTest : public Test {
};
TEST_F(PropertyRecordingTest, OneProperty) {
@@ -134,6 +138,31 @@ TEST(NoFixtureTest, ExternalUtilityThatCallsRecordStringValuedProperty) {
ExternalUtilityThatCallsRecordProperty("key_for_utility_string", "1");
}
+// Verifies that the test parameter value is output in the 'value_param'
+// XML attribute for value-parameterized tests.
+class ValueParamTest : public TestWithParam<int> {};
+TEST_P(ValueParamTest, HasValueParamAttribute) {}
+TEST_P(ValueParamTest, AnotherTestThatHasValueParamAttribute) {}
+INSTANTIATE_TEST_CASE_P(Single, ValueParamTest, Values(33, 42));
+
+// Verifies that the type parameter name is output in the 'type_param'
+// XML attribute for typed tests.
+template <typename T> class TypedTest : public Test {};
+typedef Types<int, long> TypedTestTypes;
+TYPED_TEST_CASE(TypedTest, TypedTestTypes);
+TYPED_TEST(TypedTest, HasTypeParamAttribute) {}
+
+// Verifies that the type parameter name is output in the 'type_param'
+// XML attribute for type-parameterized tests.
+template <typename T> class TypeParameterizedTestCase : public Test {};
+TYPED_TEST_CASE_P(TypeParameterizedTestCase);
+TYPED_TEST_P(TypeParameterizedTestCase, HasTypeParamAttribute) {}
+REGISTER_TYPED_TEST_CASE_P(TypeParameterizedTestCase, HasTypeParamAttribute);
+typedef Types<int, long> TypeParameterizedTestCaseTypes;
+INSTANTIATE_TYPED_TEST_CASE_P(Single,
+ TypeParameterizedTestCase,
+ TypeParameterizedTestCaseTypes);
+
int main(int argc, char** argv) {
InitGoogleTest(&argc, argv);
diff --git a/testing/gtest/test/gtest_xml_test_utils.py b/testing/gtest/test/gtest_xml_test_utils.py
index c83c3b7..0f55c16 100755
--- a/testing/gtest/test/gtest_xml_test_utils.py
+++ b/testing/gtest/test/gtest_xml_test_utils.py
@@ -58,8 +58,9 @@ class GTestXMLTestCase(gtest_test_utils.TestCase):
* It has the same tag name as expected_node.
* It has the same set of attributes as expected_node, each with
the same value as the corresponding attribute of expected_node.
- An exception is any attribute named "time", which needs only be
- convertible to a floating-point number.
+ Exceptions are any attribute named "time", which needs only be
+ convertible to a floating-point number and any attribute named
+ "type_param" which only has to be non-empty.
* It has an equivalent set of child nodes (including elements and
CDATA sections) as expected_node. Note that we ignore the
order of the children as they are not guaranteed to be in any
@@ -150,6 +151,9 @@ class GTestXMLTestCase(gtest_test_utils.TestCase):
* The "time" attribute of <testsuites>, <testsuite> and <testcase>
elements is replaced with a single asterisk, if it contains
only digit characters.
+ * 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
+ by the compiler and is platform dependent.
* The line number reported in the first line of the "message"
attribute of <failure> elements is replaced with a single asterisk.
* The directory names in file paths are removed.
@@ -159,6 +163,9 @@ class GTestXMLTestCase(gtest_test_utils.TestCase):
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:
+ type_param.value = "*"
elif element.tagName == "failure":
for child in element.childNodes:
if child.nodeType == Node.CDATA_SECTION_NODE:
diff --git a/testing/gtest/xcode/gtest.xcodeproj/project.pbxproj b/testing/gtest/xcode/gtest.xcodeproj/project.pbxproj
index 4234e72..74a7815 100644
--- a/testing/gtest/xcode/gtest.xcodeproj/project.pbxproj
+++ b/testing/gtest/xcode/gtest.xcodeproj/project.pbxproj
@@ -78,6 +78,7 @@
4539C9380EC280E200A70F4C /* gtest-linked_ptr.h in Copy Headers Internal */ = {isa = PBXBuildFile; fileRef = 4539C9350EC280E200A70F4C /* gtest-linked_ptr.h */; };
4539C9390EC280E200A70F4C /* gtest-param-util-generated.h in Copy Headers Internal */ = {isa = PBXBuildFile; fileRef = 4539C9360EC280E200A70F4C /* gtest-param-util-generated.h */; };
4539C93A0EC280E200A70F4C /* gtest-param-util.h in Copy Headers Internal */ = {isa = PBXBuildFile; fileRef = 4539C9370EC280E200A70F4C /* gtest-param-util.h */; };
+ 4567C8181264FF71007740BE /* gtest-printers.h in Headers */ = {isa = PBXBuildFile; fileRef = 4567C8171264FF71007740BE /* gtest-printers.h */; settings = {ATTRIBUTES = (Public, ); }; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -242,6 +243,7 @@
4539C9350EC280E200A70F4C /* gtest-linked_ptr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-linked_ptr.h"; sourceTree = "<group>"; };
4539C9360EC280E200A70F4C /* gtest-param-util-generated.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-param-util-generated.h"; sourceTree = "<group>"; };
4539C9370EC280E200A70F4C /* gtest-param-util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-param-util.h"; sourceTree = "<group>"; };
+ 4567C8171264FF71007740BE /* gtest-printers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-printers.h"; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -360,6 +362,7 @@
404883DB0E2F799B00CF7658 /* gtest-death-test.h */,
404883DC0E2F799B00CF7658 /* gtest-message.h */,
4539C9330EC280AE00A70F4C /* gtest-param-test.h */,
+ 4567C8171264FF71007740BE /* gtest-printers.h */,
404883DD0E2F799B00CF7658 /* gtest-spi.h */,
404883DE0E2F799B00CF7658 /* gtest.h */,
404883DF0E2F799B00CF7658 /* gtest_pred_impl.h */,
@@ -437,6 +440,7 @@
404884380E2F799B00CF7658 /* gtest-death-test.h in Headers */,
404884390E2F799B00CF7658 /* gtest-message.h in Headers */,
4539C9340EC280AE00A70F4C /* gtest-param-test.h in Headers */,
+ 4567C8181264FF71007740BE /* gtest-printers.h in Headers */,
3BF6F2A50E79B616000F2EEE /* gtest-typed-test.h in Headers */,
4048843A0E2F799B00CF7658 /* gtest-spi.h in Headers */,
4048843B0E2F799B00CF7658 /* gtest.h in Headers */,