Retry to checkin a version of gmock, modified to use our boost_tuple in VS2005.
This checkin adds gmock, and a small example of how to write a gmock-based unittest. Original Review URL: http://codereview.chromium.org/113807 Review URL: http://codereview.chromium.org/115846 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@17066 0039d316-1c4b-4281-b951-d872f2087c98
Esse commit está contido em:
+7
-5
@@ -590,16 +590,12 @@
|
||||
'type': 'executable',
|
||||
'msvs_guid': '27A30967-4BBA-48D1-8522-CDE95F7B1CEC',
|
||||
'sources': [
|
||||
'crypto/signature_verifier_unittest.cc',
|
||||
'gfx/jpeg_codec_unittest.cc',
|
||||
'gfx/native_theme_unittest.cc',
|
||||
'gfx/png_codec_unittest.cc',
|
||||
'gfx/rect_unittest.cc',
|
||||
'at_exit_unittest.cc',
|
||||
'atomicops_unittest.cc',
|
||||
'clipboard_unittest.cc',
|
||||
'command_line_unittest.cc',
|
||||
'condition_variable_unittest.cc',
|
||||
'crypto/signature_verifier_unittest.cc',
|
||||
'data_pack_unittest.cc',
|
||||
'debug_util_unittest.cc',
|
||||
'directory_watcher_unittest.cc',
|
||||
@@ -608,6 +604,11 @@
|
||||
'file_path_unittest.cc',
|
||||
'file_util_unittest.cc',
|
||||
'file_version_info_unittest.cc',
|
||||
'gfx/jpeg_codec_unittest.cc',
|
||||
'gfx/native_theme_unittest.cc',
|
||||
'gfx/png_codec_unittest.cc',
|
||||
'gfx/rect_unittest.cc',
|
||||
'gmock_unittest.cc',
|
||||
'histogram_unittest.cc',
|
||||
'hmac_unittest.cc',
|
||||
'idletimer_unittest.cc',
|
||||
@@ -673,6 +674,7 @@
|
||||
'base',
|
||||
'base_gfx',
|
||||
'../skia/skia.gyp:skia',
|
||||
'../testing/gmock.gyp:gmock',
|
||||
'../testing/gtest.gyp:gtest',
|
||||
],
|
||||
'conditions': [
|
||||
|
||||
@@ -0,0 +1,137 @@
|
||||
// Copyright (c) 2009 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
// This test is a simple sanity check to make sure gmock is able to build/link
|
||||
// correctly. It just instantiates a mock object and runs through a couple of
|
||||
// the basic mock features.
|
||||
|
||||
#include "testing/gmock/include/gmock/gmock.h"
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
|
||||
// Gmock matchers and actions that we use below.
|
||||
using testing::AnyOf;
|
||||
using testing::Eq;
|
||||
using testing::Return;
|
||||
using testing::SetArgumentPointee;
|
||||
using testing::WithArg;
|
||||
using testing::_;
|
||||
|
||||
namespace {
|
||||
|
||||
// Simple class that we can mock out the behavior for. Everything is virtual
|
||||
// for easy mocking.
|
||||
class SampleClass {
|
||||
public:
|
||||
SampleClass() {}
|
||||
virtual ~SampleClass() {}
|
||||
|
||||
virtual int ReturnSomething() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
virtual void ReturnNothingConstly() const {
|
||||
}
|
||||
|
||||
virtual void OutputParam(int* a) {
|
||||
}
|
||||
|
||||
virtual int ReturnSecond(int a, int b) {
|
||||
return b;
|
||||
}
|
||||
};
|
||||
|
||||
// Declare a mock for the class.
|
||||
class MockSampleClass : public SampleClass {
|
||||
public:
|
||||
MOCK_METHOD0(ReturnSomething, int());
|
||||
MOCK_CONST_METHOD0(ReturnNothingConstly, void());
|
||||
MOCK_METHOD1(OutputParam, void(int* a));
|
||||
MOCK_METHOD2(ReturnSecond, int(int a, int b));
|
||||
};
|
||||
|
||||
// Create a couple of custom actions. Custom actions can be used for adding
|
||||
// more complex behavior into your mock...though if you start needing these, ask
|
||||
// if you're asking your mock to do too much.
|
||||
ACTION(ReturnVal) {
|
||||
// Return the first argument received.
|
||||
return arg0;
|
||||
}
|
||||
ACTION(ReturnSecond) {
|
||||
// Returns the second argument. This basically implemetns ReturnSecond.
|
||||
return arg1;
|
||||
}
|
||||
|
||||
TEST(GmockTest, SimpleMatchAndActions) {
|
||||
// Basic test of some simple gmock matchers, actions, and cardinality
|
||||
// expectations.
|
||||
MockSampleClass mock;
|
||||
|
||||
EXPECT_CALL(mock, ReturnSomething())
|
||||
.WillOnce(Return(1))
|
||||
.WillOnce(Return(2))
|
||||
.WillOnce(Return(3));
|
||||
EXPECT_EQ(1, mock.ReturnSomething());
|
||||
EXPECT_EQ(2, mock.ReturnSomething());
|
||||
EXPECT_EQ(3, mock.ReturnSomething());
|
||||
|
||||
EXPECT_CALL(mock, ReturnNothingConstly()).Times(2);
|
||||
mock.ReturnNothingConstly();
|
||||
mock.ReturnNothingConstly();
|
||||
}
|
||||
|
||||
TEST(GmockTest, AssignArgument) {
|
||||
// Capture an argument for examination.
|
||||
MockSampleClass mock;
|
||||
|
||||
EXPECT_CALL(mock, OutputParam(_))
|
||||
.WillRepeatedly(SetArgumentPointee<0>(5));
|
||||
|
||||
int arg = 0;
|
||||
mock.OutputParam(&arg);
|
||||
EXPECT_EQ(5, arg);
|
||||
}
|
||||
|
||||
TEST(GmockTest, SideEffects) {
|
||||
// Capture an argument for examination.
|
||||
MockSampleClass mock;
|
||||
|
||||
EXPECT_CALL(mock, OutputParam(_))
|
||||
.WillRepeatedly(SetArgumentPointee<0>(5));
|
||||
|
||||
int arg = 0;
|
||||
mock.OutputParam(&arg);
|
||||
EXPECT_EQ(5, arg);
|
||||
}
|
||||
|
||||
TEST(GmockTest, CustomAction_ReturnSecond) {
|
||||
// Test a mock of the ReturnSecond behavior using an action that provides an
|
||||
// alternate implementation of the function. Danger here though, this is
|
||||
// starting to add too much behavior of the mock, which means the mock
|
||||
// implementation might start to have bugs itself.
|
||||
MockSampleClass mock;
|
||||
|
||||
EXPECT_CALL(mock, ReturnSecond(_, AnyOf(Eq(4), Eq(5))))
|
||||
.WillRepeatedly(ReturnSecond());
|
||||
EXPECT_EQ(4, mock.ReturnSecond(-1, 4));
|
||||
EXPECT_EQ(5, mock.ReturnSecond(0, 5));
|
||||
EXPECT_EQ(4, mock.ReturnSecond(0xdeadbeef, 4));
|
||||
EXPECT_EQ(4, mock.ReturnSecond(112358, 4));
|
||||
EXPECT_EQ(5, mock.ReturnSecond(1337, 5));
|
||||
}
|
||||
|
||||
TEST(GmockTest, CustomAction_ReturnVal) {
|
||||
// Alternate implemention of ReturnSecond using a more general custom action,
|
||||
// and a WithArg adapter to bridge the interfaces.
|
||||
MockSampleClass mock;
|
||||
|
||||
EXPECT_CALL(mock, ReturnSecond(_, AnyOf(Eq(4), Eq(5))))
|
||||
.WillRepeatedly(WithArg<1>(ReturnVal()));
|
||||
EXPECT_EQ(4, mock.ReturnSecond(-1, 4));
|
||||
EXPECT_EQ(5, mock.ReturnSecond(0, 5));
|
||||
EXPECT_EQ(4, mock.ReturnSecond(0xdeadbeef, 4));
|
||||
EXPECT_EQ(4, mock.ReturnSecond(112358, 4));
|
||||
EXPECT_EQ(5, mock.ReturnSecond(1337, 5));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
@@ -28,6 +28,7 @@
|
||||
'../printing/printing.gyp:*',
|
||||
'../sdch/sdch.gyp:*',
|
||||
'../skia/skia.gyp:*',
|
||||
'../testing/gmock.gyp:*',
|
||||
'../testing/gtest.gyp:*',
|
||||
'../third_party/bzip2/bzip2.gyp:*',
|
||||
'../third_party/codesighs/codesighs.gyp:*',
|
||||
|
||||
@@ -657,6 +657,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "base_unittests", "..\base\b
|
||||
{BFE8E2A7-3B3B-43B0-A994-3058B852DB8B} = {BFE8E2A7-3B3B-43B0-A994-3058B852DB8B}
|
||||
{C564F145-9172-42C3-BFCB-6014CA97DBCD} = {C564F145-9172-42C3-BFCB-6014CA97DBCD}
|
||||
{CD9CA56E-4E94-444C-87D4-58CA1E6F300D} = {CD9CA56E-4E94-444C-87D4-58CA1E6F300D}
|
||||
{F9D886ED-B09F-4B74-932F-D8E4691E6B7F} = {F9D886ED-B09F-4B74-932F-D8E4691E6B7F}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "plugin_tests", "test\plugin\plugin_tests.vcproj", "{A1CAA831-C507-4B2E-87F3-AEC63C9907F9}"
|
||||
@@ -1644,6 +1645,9 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_shell_common", "..\web
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "utility", "utility\utility.vcproj", "{4D2B38E6-65FF-4F97-B88A-E441DF54EBF7}"
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gmock", "..\testing\gmock.vcproj", "{F9D886ED-B09F-4B74-932F-D8E4691E6B7F}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gmockmain", "..\testing\gmockmain.vcproj", "{1B231A30-92B6-A027-DDBA-A0682336765E}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "app_unittests", "..\app\app_unittests.vcproj", "{B4D59AE8-8D2F-97E1-A8E9-6D2826729530}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
@@ -1765,6 +1769,14 @@ Global
|
||||
{1846F110-8263-413F-9924-36F64DD8FE41}.Release|Mixed Platforms.Build.0 = Release|Win32
|
||||
{1846F110-8263-413F-9924-36F64DD8FE41}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{1846F110-8263-413F-9924-36F64DD8FE41}.Release|Win32.Build.0 = Release|Win32
|
||||
{1B231A30-92B6-A027-DDBA-A0682336765E}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
|
||||
{1B231A30-92B6-A027-DDBA-A0682336765E}.Debug|Mixed Platforms.Build.0 = Debug|Win32
|
||||
{1B231A30-92B6-A027-DDBA-A0682336765E}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{1B231A30-92B6-A027-DDBA-A0682336765E}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{1B231A30-92B6-A027-DDBA-A0682336765E}.Release|Mixed Platforms.ActiveCfg = Release|Win32
|
||||
{1B231A30-92B6-A027-DDBA-A0682336765E}.Release|Mixed Platforms.Build.0 = Release|Win32
|
||||
{1B231A30-92B6-A027-DDBA-A0682336765E}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{1B231A30-92B6-A027-DDBA-A0682336765E}.Release|Win32.Build.0 = Release|Win32
|
||||
{1C16337B-ACF3-4D03-AA90-851C5B5EADA6}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
|
||||
{1C16337B-ACF3-4D03-AA90-851C5B5EADA6}.Debug|Mixed Platforms.Build.0 = Debug|Win32
|
||||
{1C16337B-ACF3-4D03-AA90-851C5B5EADA6}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
@@ -3063,6 +3075,14 @@ Global
|
||||
{F9810DE8-CBC3-4605-A7B1-ECA2D5292FD7}.Release|Mixed Platforms.Build.0 = Release|Win32
|
||||
{F9810DE8-CBC3-4605-A7B1-ECA2D5292FD7}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{F9810DE8-CBC3-4605-A7B1-ECA2D5292FD7}.Release|Win32.Build.0 = Release|Win32
|
||||
{F9D886ED-B09F-4B74-932F-D8E4691E6B7F}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
|
||||
{F9D886ED-B09F-4B74-932F-D8E4691E6B7F}.Debug|Mixed Platforms.Build.0 = Debug|Win32
|
||||
{F9D886ED-B09F-4B74-932F-D8E4691E6B7F}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{F9D886ED-B09F-4B74-932F-D8E4691E6B7F}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{F9D886ED-B09F-4B74-932F-D8E4691E6B7F}.Release|Mixed Platforms.ActiveCfg = Release|Win32
|
||||
{F9D886ED-B09F-4B74-932F-D8E4691E6B7F}.Release|Mixed Platforms.Build.0 = Release|Win32
|
||||
{F9D886ED-B09F-4B74-932F-D8E4691E6B7F}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{F9D886ED-B09F-4B74-932F-D8E4691E6B7F}.Release|Win32.Build.0 = Release|Win32
|
||||
{FA39524D-3067-4141-888D-28A86C66F2B9}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
|
||||
{FA39524D-3067-4141-888D-28A86C66F2B9}.Debug|Mixed Platforms.Build.0 = Debug|Win32
|
||||
{FA39524D-3067-4141-888D-28A86C66F2B9}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
@@ -3118,6 +3138,7 @@ Global
|
||||
{1832A374-8A74-4F9E-B536-69A699B3E165} = {EF78C1F9-AA17-4CA5-B6CB-39B37A73A3DA}
|
||||
{1846F110-8263-413F-9924-36F64DD8FE41} = {EF78C1F9-AA17-4CA5-B6CB-39B37A73A3DA}
|
||||
{1AFC1EC3-24FA-4260-B099-76319EC9977A} = {EF78C1F9-AA17-4CA5-B6CB-39B37A73A3DA}
|
||||
{1B231A30-92B6-A027-DDBA-A0682336765E} = {1174D37F-6ABB-45DA-81B3-C631281273B7}
|
||||
{20A560A0-2CD0-4D9E-A58B-1F24B99C087A} = {97555540-8163-4D0F-BCAC-EFA0FFED3453}
|
||||
{21C76E6E-8B38-44D6-8148-B589C13B9554} = {EB684A4B-98F7-4E68-8EA7-EA74ACF7060B}
|
||||
{21E22961-22BF-4493-BD3A-868F93DA5179} = {B353A6A5-9551-4B76-908E-0F0A9B31E4CE}
|
||||
@@ -3274,6 +3295,7 @@ Global
|
||||
{F54ABC59-5C00-414A-A9BA-BAF26D1699F0} = {EF78C1F9-AA17-4CA5-B6CB-39B37A73A3DA}
|
||||
{F7790A54-4078-4E4A-8231-818BE9FB1F94} = {2325D8C4-8EF5-42AC-8900-492225750DE4}
|
||||
{F9810DE8-CBC3-4605-A7B1-ECA2D5292FD7} = {EF78C1F9-AA17-4CA5-B6CB-39B37A73A3DA}
|
||||
{F9D886ED-B09F-4B74-932F-D8E4691E6B7F} = {1174D37F-6ABB-45DA-81B3-C631281273B7}
|
||||
{FA39524D-3067-4141-888D-28A86C66F2B9} = {1174D37F-6ABB-45DA-81B3-C631281273B7}
|
||||
{FA537565-7B03-4FFC-AF15-F7A979B72E22} = {97555540-8163-4D0F-BCAC-EFA0FFED3453}
|
||||
{FA660037-EB40-4A43-AA9D-9653C57F2789} = {2325D8C4-8EF5-42AC-8900-492225750DE4}
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
We include a snapshot of gmock from http://googlemock.googlecode.com/svn/trunk
|
||||
with chromium.patch applied.
|
||||
|
||||
Current revision: 157
|
||||
|
||||
|
||||
-- HOW TO USE --
|
||||
|
||||
If you are unfamiliar with gmock, there is an example of how to write a test
|
||||
based on gmock in base/gmock_unittest.cc. To use gmock, just add a dependency
|
||||
onto testing/gmock.gyp:gmock in your gyp target.
|
||||
|
||||
For more general informaiton, there is a lot of good documentation availble on
|
||||
the googlemock website:
|
||||
|
||||
http://code.google.com/p/googlemock/
|
||||
|
||||
In particular, the "For Dummies" guide is a good place to start. The
|
||||
"CheatSheet" and "CookBook" are better as references.
|
||||
|
||||
|
||||
-- RECREATING PACKAGE --
|
||||
|
||||
Gmock requires tr1 tuple. However, Visual Studio 2005 does not include
|
||||
tr1 tuple, so a version of boost tuple was added into the third_party
|
||||
tree for chromium. Our version of gmock has been patched to search for
|
||||
this version of tuple inside our source tree.
|
||||
|
||||
chromium.patch modifies gmock/include/gmock/internal/gmock-port.h so that
|
||||
for _MSC_VER < 1500 (anything newer than Visual Studio 2008), boost tuple
|
||||
is loaded from boost/tr1/tr1/tuple.
|
||||
|
||||
To recreate this install, do the following:
|
||||
|
||||
*1) Checkout a copy from svn trunk using --ignore-externals to avoid
|
||||
getting an extra copy of gtest. Use the following command:
|
||||
svn export --ignore-externals \
|
||||
http://googlemock.googlecode.com/svn/trunk/ gmock
|
||||
2) Patch it with chromium.patch.
|
||||
|
||||
* Pass -r [revision number] to svn export if you want a specific revision.
|
||||
The current revision of the source is listed at the top of the README.
|
||||
|
||||
|
||||
-- ALTERNATIVES TO PATCHING --
|
||||
|
||||
The patching of gmock to use boost in VS2005 was settled upon as the lowest
|
||||
impact solution for getting gmock working in VS2005. Patching gmock trades
|
||||
making some assumptions regarding the internal implementations of gmock
|
||||
and boost for a simple, easy to underatnd, implementation that provides
|
||||
relatively good insulation for the rest of the build from the boost dependency.
|
||||
|
||||
Alternate soltuions are:
|
||||
1) Drop support for VS2005 -- too heavy-handed.
|
||||
2) Add a "tuple" file parallel to gmock-port.h -- still makes assumptions
|
||||
about boost's structure.
|
||||
3) Add boost/tr1/tr1 into the include path -- dirties the include path for
|
||||
all dependencies.
|
||||
@@ -0,0 +1,20 @@
|
||||
diff -ru gmock.orig/include/gmock/internal/gmock-port.h gmock/include/gmock/internal/gmock-port.h
|
||||
--- gmock.orig/include/gmock/internal/gmock-port.h 2009-05-22 23:58:41.000000000 -0700
|
||||
+++ gmock/include/gmock/internal/gmock-port.h 2009-05-23 00:49:01.000000000 -0700
|
||||
@@ -54,9 +54,14 @@
|
||||
// GCC 4.0+ implements tr1/tuple in the <tr1/tuple> header. This does
|
||||
// not conform to the TR1 spec, which requires the header to be <tuple>.
|
||||
#include <tr1/tuple>
|
||||
+#elif defined(_MSC_VER) && _MSC_VER < 1500
|
||||
+// For Visual Studio older than 2008, we redirect directly to boost tuple
|
||||
+// searching from boost's root. This is to avoid extra dirtying of the
|
||||
+// compiler include paths.
|
||||
+#include "boost/tr1/tr1/tuple"
|
||||
#else
|
||||
-// If the compiler is not GCC 4.0+, we assume the user is using a
|
||||
-// spec-conforming TR1 implementation.
|
||||
+// If the compiler is neither GCC 4.0+, nor Visual Studio 2008, we assume the
|
||||
+// user is using a spec-conforming TR1 implementation.
|
||||
#include <tuple>
|
||||
#endif // __GNUC__
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
# Copyright (c) 2009 The Chromium Authors. All rights reserved.
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
{
|
||||
'includes': [
|
||||
'../build/common.gypi',
|
||||
],
|
||||
'targets': [
|
||||
{
|
||||
'target_name': 'gmock',
|
||||
'type': '<(library)',
|
||||
'msvs_guid': 'F9D886ED-B09F-4b74-932F-D8E4691E6B7F',
|
||||
'dependencies': [
|
||||
'gtest.gyp:gtest',
|
||||
],
|
||||
'sources': [
|
||||
'gmock/include/gmock/gmock-actions.h',
|
||||
'gmock/include/gmock/gmock-cardinalities.h',
|
||||
'gmock/include/gmock/gmock-generated-actions.h',
|
||||
'gmock/include/gmock/gmock-generated-function-mockers.h',
|
||||
'gmock/include/gmock/gmock-generated-matchers.h',
|
||||
'gmock/include/gmock/gmock-generated-nice-strict.h',
|
||||
'gmock/include/gmock/gmock-matchers.h',
|
||||
'gmock/include/gmock/gmock-printers.h',
|
||||
'gmock/include/gmock/gmock-spec-builders.h',
|
||||
'gmock/include/gmock/gmock.h',
|
||||
'gmock/include/gmock/internal/gmock-generated-internal-utils.h',
|
||||
'gmock/include/gmock/internal/gmock-internal-utils.h',
|
||||
'gmock/include/gmock/internal/gmock-port.h',
|
||||
'gmock/src/gmock-all.cc',
|
||||
'gmock/src/gmock-cardinalities.cc',
|
||||
'gmock/src/gmock-internal-utils.cc',
|
||||
'gmock/src/gmock-matchers.cc',
|
||||
'gmock/src/gmock-printers.cc',
|
||||
'gmock/src/gmock-spec-builders.cc',
|
||||
'gmock/src/gmock.cc',
|
||||
],
|
||||
'sources!': [
|
||||
'gmock/src/gmock-all.cc', # Not needed by our build.
|
||||
],
|
||||
'include_dirs': [
|
||||
'gmock',
|
||||
'gmock/include',
|
||||
],
|
||||
'direct_dependent_settings': {
|
||||
'include_dirs': [
|
||||
'gmock/include', # So that gmock headers can find themselves.
|
||||
],
|
||||
},
|
||||
'export_dependent_settings': [
|
||||
'gtest.gyp:gtest',
|
||||
],
|
||||
'conditions': [
|
||||
['OS=="win"', {
|
||||
'dependencies': [
|
||||
'../third_party/boost/boost.gyp:boost_tuple',
|
||||
],
|
||||
'export_dependent_settings': [
|
||||
'../third_party/boost/boost.gyp:boost_tuple',
|
||||
]
|
||||
}],
|
||||
],
|
||||
},
|
||||
{
|
||||
# Note that calling this "gmock_main" confuses the scons build,
|
||||
# which uses "_main" on scons files to produce special behavior.
|
||||
'target_name': 'gmockmain',
|
||||
'type': '<(library)',
|
||||
'dependencies': [
|
||||
'gmock',
|
||||
],
|
||||
'sources': [
|
||||
'gmock/src/gmock_main.cc',
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
Changes for 1.1.0:
|
||||
|
||||
* New feature: ability to use Google Mock with any testing framework.
|
||||
* New feature: macros for easily defining new matchers
|
||||
* New feature: macros for easily defining new actions.
|
||||
* New feature: more container matchers.
|
||||
* New feature: actions for accessing function arguments and throwing
|
||||
exceptions.
|
||||
* Improved the Google Mock doctor script for diagnosing compiler errors.
|
||||
* Bug fixes and implementation clean-up.
|
||||
|
||||
Changes for 1.0.0:
|
||||
|
||||
* Initial Open Source release of Google Mock
|
||||
@@ -0,0 +1,38 @@
|
||||
# This file contains a list of people who've made non-trivial
|
||||
# contribution to the Google C++ Mocking Framework project. People
|
||||
# who commit code to the project are encouraged to add their names
|
||||
# here. Please keep the list sorted by first names.
|
||||
|
||||
Benoit Sigoure <tsuna@google.com>
|
||||
Bogdan Piloca <boo@google.com>
|
||||
Chandler Carruth <chandlerc@google.com>
|
||||
Dave MacLachlan <dmaclach@gmail.com>
|
||||
David Anderson <danderson@google.com>
|
||||
Dean Sturtevant
|
||||
Gene Volovich <gv@cite.com>
|
||||
Hal Burch <gmock@hburch.com>
|
||||
Jeffrey Yasskin <jyasskin@google.com>
|
||||
Jim Keller <jimkeller@google.com>
|
||||
Joe Walnes <joe@truemesh.com>
|
||||
Jon Wray <jwray@google.com>
|
||||
Keir Mierle <mierle@gmail.com>
|
||||
Keith Ray <keith.ray@gmail.com>
|
||||
Kostya Serebryany <kcc@google.com>
|
||||
Lev Makhlis
|
||||
Mario Tanev <radix@google.com>
|
||||
Mark Paskin
|
||||
Markus Heule <markus.heule@gmail.com>
|
||||
Matthew Simmons <simmonmt@acm.org>
|
||||
Mike Bland <mbland@google.com>
|
||||
Neal Norwitz <nnorwitz@gmail.com>
|
||||
Nermin Ozkiranartli <nermin@google.com>
|
||||
Owen Carlsen <ocarlsen@google.com>
|
||||
Paneendra Ba <paneendra@google.com>
|
||||
Paul Menage <menage@google.com>
|
||||
Piotr Kaminski <piotrk@google.com>
|
||||
Russ Rufer <russ@pentad.com>
|
||||
Takeshi Yoshino <tyoshino@google.com>
|
||||
Vadim Berman <vadimb@google.com>
|
||||
Vlad Losev <vladl@google.com>
|
||||
Wolfgang Klier <wklier@google.com>
|
||||
Zhanyong Wan <wan@google.com>
|
||||
@@ -0,0 +1,28 @@
|
||||
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.
|
||||
@@ -0,0 +1,210 @@
|
||||
# Nonstandard package files for distribution.
|
||||
EXTRA_DIST =
|
||||
|
||||
# We may need to build our internally packaged gtest. If so, it will be
|
||||
# included in the 'subdirs' variable.
|
||||
SUBDIRS = $(subdirs)
|
||||
|
||||
# Scripts and utilities to be installed by 'make install'.
|
||||
dist_bin_SCRIPTS = scripts/gmock_doctor.py
|
||||
bin_SCRIPTS = scripts/gmock-config
|
||||
|
||||
# This is generated by the configure script, so clean it for distribution.
|
||||
DISTCLEANFILES = scripts/gmock-config
|
||||
|
||||
# We define the global AM_CPPFLAGS as everything we compile includes from these
|
||||
# directories.
|
||||
AM_CPPFLAGS = $(GTEST_CPPFLAGS) -I$(srcdir)/include
|
||||
|
||||
# Build rules for libraries.
|
||||
lib_LTLIBRARIES = lib/libgmock.la lib/libgmock_main.la
|
||||
|
||||
lib_libgmock_la_SOURCES = src/gmock.cc \
|
||||
src/gmock-cardinalities.cc \
|
||||
src/gmock-internal-utils.cc \
|
||||
src/gmock-matchers.cc \
|
||||
src/gmock-printers.cc \
|
||||
src/gmock-spec-builders.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-printers.h \
|
||||
include/gmock/gmock-spec-builders.h
|
||||
|
||||
pkginclude_internaldir = $(pkgincludedir)/internal
|
||||
pkginclude_internal_HEADERS = \
|
||||
include/gmock/internal/gmock-generated-internal-utils.h \
|
||||
include/gmock/internal/gmock-internal-utils.h \
|
||||
include/gmock/internal/gmock-port.h
|
||||
|
||||
lib_libgmock_main_la_SOURCES = src/gmock_main.cc
|
||||
lib_libgmock_main_la_LIBADD = lib/libgmock.la
|
||||
|
||||
# Build rules for tests. Automake's naming for some of these variables isn't
|
||||
# terribly obvious, so this is a brief reference:
|
||||
#
|
||||
# TESTS -- Programs run automatically by "make check"
|
||||
# check_PROGRAMS -- Programs built by "make check" but not necessarily run
|
||||
|
||||
TESTS=
|
||||
TESTS_ENVIRONMENT = GMOCK_SOURCE_DIR="$(srcdir)/test" \
|
||||
GMOCK_BUILD_DIR="$(top_builddir)/test"
|
||||
check_PROGRAMS=
|
||||
AM_LDFLAGS = $(GTEST_LDFLAGS)
|
||||
|
||||
TESTS += test/gmock-actions_test
|
||||
check_PROGRAMS += test/gmock-actions_test
|
||||
test_gmock_actions_test_SOURCES = test/gmock-actions_test.cc
|
||||
test_gmock_actions_test_LDADD = $(GTEST_LIBS) lib/libgmock_main.la
|
||||
|
||||
TESTS += test/gmock-cardinalities_test
|
||||
check_PROGRAMS += test/gmock-cardinalities_test
|
||||
test_gmock_cardinalities_test_SOURCES = test/gmock-cardinalities_test.cc
|
||||
test_gmock_cardinalities_test_LDADD = $(GTEST_LIBS) lib/libgmock_main.la
|
||||
|
||||
TESTS += test/gmock-generated-actions_test
|
||||
check_PROGRAMS += test/gmock-generated-actions_test
|
||||
test_gmock_generated_actions_test_SOURCES = test/gmock-generated-actions_test.cc
|
||||
test_gmock_generated_actions_test_LDADD = $(GTEST_LIBS) lib/libgmock_main.la
|
||||
|
||||
TESTS += test/gmock-generated-function-mockers_test
|
||||
check_PROGRAMS += test/gmock-generated-function-mockers_test
|
||||
test_gmock_generated_function_mockers_test_SOURCES = \
|
||||
test/gmock-generated-function-mockers_test.cc
|
||||
test_gmock_generated_function_mockers_test_LDADD = $(GTEST_LIBS) \
|
||||
lib/libgmock_main.la
|
||||
|
||||
TESTS += test/gmock-generated-internal-utils_test
|
||||
check_PROGRAMS += test/gmock-generated-internal-utils_test
|
||||
test_gmock_generated_internal_utils_test_SOURCES = \
|
||||
test/gmock-generated-internal-utils_test.cc
|
||||
test_gmock_generated_internal_utils_test_LDADD = $(GTEST_LIBS) \
|
||||
lib/libgmock_main.la
|
||||
|
||||
TESTS += test/gmock-generated-matchers_test
|
||||
check_PROGRAMS += test/gmock-generated-matchers_test
|
||||
test_gmock_generated_matchers_test_SOURCES = \
|
||||
test/gmock-generated-matchers_test.cc
|
||||
test_gmock_generated_matchers_test_LDADD = $(GTEST_LIBS) lib/libgmock_main.la
|
||||
|
||||
TESTS += test/gmock-internal-utils_test
|
||||
check_PROGRAMS += test/gmock-internal-utils_test
|
||||
test_gmock_internal_utils_test_SOURCES = test/gmock-internal-utils_test.cc
|
||||
test_gmock_internal_utils_test_LDADD = $(GTEST_LIBS) lib/libgmock_main.la
|
||||
|
||||
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_LDADD = $(GTEST_LIBS) lib/libgmock_main.la
|
||||
|
||||
TESTS += test/gmock-matchers_test
|
||||
check_PROGRAMS += test/gmock-matchers_test
|
||||
test_gmock_matchers_test_SOURCES = test/gmock-matchers_test.cc
|
||||
test_gmock_matchers_test_LDADD = $(GTEST_LIBS) lib/libgmock_main.la
|
||||
|
||||
TESTS += test/gmock-nice-strict_test
|
||||
check_PROGRAMS += test/gmock-nice-strict_test
|
||||
test_gmock_nice_strict_test_SOURCES = test/gmock-nice-strict_test.cc
|
||||
test_gmock_nice_strict_test_LDADD = $(GTEST_LIBS) lib/libgmock_main.la
|
||||
|
||||
TESTS += test/gmock-port_test
|
||||
check_PROGRAMS += test/gmock-port_test
|
||||
test_gmock_port_test_SOURCES = test/gmock-port_test.cc
|
||||
test_gmock_port_test_LDADD = $(GTEST_LIBS) lib/libgmock_main.la
|
||||
|
||||
TESTS += test/gmock-printers_test
|
||||
check_PROGRAMS += test/gmock-printers_test
|
||||
test_gmock_printers_test_SOURCES = test/gmock-printers_test.cc
|
||||
test_gmock_printers_test_LDADD = $(GTEST_LIBS) lib/libgmock_main.la
|
||||
|
||||
TESTS += test/gmock-spec-builders_test
|
||||
check_PROGRAMS += test/gmock-spec-builders_test
|
||||
test_gmock_spec_builders_test_SOURCES = test/gmock-spec-builders_test.cc
|
||||
test_gmock_spec_builders_test_LDADD = $(GTEST_LIBS) lib/libgmock.la
|
||||
|
||||
TESTS += test/gmock_test
|
||||
check_PROGRAMS += test/gmock_test
|
||||
test_gmock_test_SOURCES = test/gmock_test.cc
|
||||
test_gmock_test_LDADD = $(GTEST_LIBS) lib/libgmock_main.la
|
||||
|
||||
# The following tests depend on the presence of a Python installation and are
|
||||
# keyed off of it. We only add them to the TESTS variable when a Python
|
||||
# interpreter is available. TODO(chandlerc@google.com): While we currently only
|
||||
# attempt to build and execute these tests if Autoconf has found Python v2.3 on
|
||||
# the system, we don't use the PYTHON variable it specified as the valid
|
||||
# interpreter. The problem is that TESTS_ENVIRONMENT is a global variable, and
|
||||
# thus we cannot distinguish between C++ unit tests and Python unit tests.
|
||||
dist_check_SCRIPTS =
|
||||
|
||||
# Python modules used by multiple Python tests below.
|
||||
dist_check_SCRIPTS += test/gmock_test_utils.py
|
||||
|
||||
check_PROGRAMS += test/gmock_leak_test_
|
||||
test_gmock_leak_test__SOURCES = test/gmock_leak_test_.cc
|
||||
test_gmock_leak_test__LDADD = $(GTEST_LIBS) lib/libgmock_main.la
|
||||
dist_check_SCRIPTS += test/gmock_leak_test.py
|
||||
|
||||
check_PROGRAMS += test/gmock_output_test_
|
||||
test_gmock_output_test__SOURCES = test/gmock_output_test_.cc
|
||||
test_gmock_output_test__LDADD = $(GTEST_LIBS) lib/libgmock_main.la
|
||||
dist_check_SCRIPTS += test/gmock_output_test.py
|
||||
EXTRA_DIST += test/gmock_output_test_golden.txt
|
||||
|
||||
# Enable all the python driven tests when we can run them.
|
||||
if HAVE_PYTHON
|
||||
TESTS += \
|
||||
test/gmock_leak_test.py \
|
||||
test/gmock_output_test.py
|
||||
endif
|
||||
|
||||
# Nonstandard package files for distribution.
|
||||
EXTRA_DIST += \
|
||||
CHANGES \
|
||||
CONTRIBUTORS \
|
||||
make/Makefile \
|
||||
src/gmock-all.cc
|
||||
|
||||
# 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
|
||||
|
||||
# Script for fusing Google Mock and Google Test source files.
|
||||
EXTRA_DIST += \
|
||||
scripts/fuse_gmock_files.py \
|
||||
scripts/test/Makefile
|
||||
|
||||
# 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
|
||||
|
||||
# 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_output_test_.vcproj \
|
||||
msvc/gmock-spec-builders_test.vcproj \
|
||||
msvc/gmock_test.vcproj
|
||||
@@ -0,0 +1,345 @@
|
||||
Google C++ Mocking Framework
|
||||
============================
|
||||
http://code.google.com/p/googlemock/
|
||||
|
||||
Overview
|
||||
--------
|
||||
Google's framework for writing and using C++ mock classes on Linux,
|
||||
Mac OS X, and Windows. Inspired by jMock, EasyMock, and Hamcrest, and
|
||||
designed with C++'s specifics in mind, it can help you derive better
|
||||
designs of your system and write better tests.
|
||||
|
||||
Google Mock:
|
||||
|
||||
- provides a declarative syntax for defining mocks,
|
||||
- can easily define partial (hybrid) mocks, which are a cross of real
|
||||
and mock objects,
|
||||
- handles functions of arbitrary types and overloaded functions,
|
||||
- comes with a rich set of matchers for validating function arguments,
|
||||
- uses an intuitive syntax for controlling the behavior of a mock,
|
||||
- does automatic verification of expectations (no record-and-replay
|
||||
needed),
|
||||
- allows arbitrary (partial) ordering constraints on
|
||||
function calls to be expressed,
|
||||
- lets a user extend it by defining new matchers and actions.
|
||||
- does not use exceptions, and
|
||||
- is easy to learn and use.
|
||||
|
||||
Please see the project page above for more information as well as mailing lists
|
||||
for questions, discussions, and development. There is also an IRC channel on
|
||||
OFTC (irc.oftc.net) #gtest available. Please join us!
|
||||
|
||||
Please note that code under scripts/generator/ is from the cppclean
|
||||
project (http://code.google.com/p/cppclean/) and under the Apache
|
||||
License, which is different from Google Mock's license.
|
||||
|
||||
Requirements
|
||||
------------
|
||||
Google Mock is not a testing framework itself. Instead, it needs a
|
||||
testing framework for writing tests. It works with Google Test
|
||||
(http://code.google.com/p/googletest/) out of the box. You can use
|
||||
either the copy of Google Test that comes with Google Mock, or a
|
||||
compatible version you already have. This version of Google Mock
|
||||
requires Google Test 1.3.0.
|
||||
|
||||
You can also easily configure Google Mock to work with another testing
|
||||
framework of your choice; although it will still need Google Test as
|
||||
an internal dependency. Please read
|
||||
http://code.google.com/p/googlemock/wiki/ForDummies#Using_Google_Mock_with_Any_Testing_Framework
|
||||
for how to do it.
|
||||
|
||||
Google Mock depends on advanced C++ features and thus requires a more
|
||||
modern compiler. The following are needed to use Google Mock:
|
||||
|
||||
### Linux Requirements ###
|
||||
These are the base requirements to build and use Google Mock from a source
|
||||
package (as described below):
|
||||
* GNU-compatible Make or "gmake"
|
||||
* POSIX-standard shell
|
||||
* POSIX(-2) Regular Expressions (regex.h)
|
||||
* gcc 4.0 or newer, or gcc 3.4 or newer with the tr1 tuple library
|
||||
(from Boost or other vendors).
|
||||
|
||||
Furthermore, if you are building Google Mock from a VCS Checkout (also
|
||||
described below), there are further requirements:
|
||||
* Automake version 1.9 or newer
|
||||
* Autoconf version 2.59 or newer
|
||||
* Libtool / Libtoolize
|
||||
* Python version 2.3 or newer
|
||||
|
||||
### Windows Requirements ###
|
||||
* Microsoft Visual C++ 8.0 SP1 or newer
|
||||
* An implementation of the tr1 tuple C++ library (You can get it for
|
||||
free from http://www.boost.org/. We have verified that version
|
||||
1.36.0 works. One caveat is this implementation exposes a bug in
|
||||
Visual C++'s <type_info> header when exceptions are disabled.
|
||||
Therefore your project must enable exceptions for this
|
||||
configuration to work.)
|
||||
|
||||
### Mac OS X Requirements ###
|
||||
* Mac OS X 10.4 Tiger or newer
|
||||
* Developer Tools Installed
|
||||
|
||||
Getting the Source
|
||||
------------------
|
||||
There are two primary ways of getting Google Mock's source code: you can
|
||||
download a source release in your preferred archive format, or directly check
|
||||
out the source from a Version Control System (VCS, we use Google Code's
|
||||
Subversion hosting). The VCS checkout requires a few extra steps and some extra
|
||||
software packages on your system, but lets you track development, and make
|
||||
patches to contribute much more easily, so we highly encourage it.
|
||||
|
||||
### VCS Checkout: ###
|
||||
The first step is to select whether you want to check out the main line of
|
||||
development on Google Mock, or one of the released branches. The former will be
|
||||
much more active and have the latest features, but the latter provides much
|
||||
more stability and predictability. Choose whichever fits your needs best, and
|
||||
proceed with the following Subversion commands:
|
||||
|
||||
svn checkout http://googlemock.googlecode.com/svn/trunk/ gmock-svn
|
||||
|
||||
or for a release version X.Y.*'s branch:
|
||||
|
||||
svn checkout http://googlemock.googlecode.com/svn/branches/release-X.Y/ \
|
||||
gmock-X.Y-svn
|
||||
|
||||
Next you will need to prepare the GNU Autotools build system, if you
|
||||
are using Linux or Mac OS X. Enter the target directory of the
|
||||
checkout command you used ('gmock-svn' or 'gmock-X.Y-svn' above) and
|
||||
proceed with the following command:
|
||||
|
||||
autoreconf -fvi
|
||||
|
||||
Once you have completed this step, you are ready to build the library. Note
|
||||
that you should only need to complete this step once. The subsequent `make'
|
||||
invocations will automatically re-generate the bits of the build system that
|
||||
need to be changed.
|
||||
|
||||
If your system uses older versions of the autotools, the above command will
|
||||
fail. You may need to explicitly specify a version to use. For instance, if you
|
||||
have both GNU Automake 1.4 and 1.9 installed and `automake' would invoke the
|
||||
1.4, use instead:
|
||||
|
||||
AUTOMAKE=automake-1.9 ACLOCAL=aclocal-1.9 autoreconf -fvi
|
||||
|
||||
Make sure you're using the same version of automake and aclocal.
|
||||
|
||||
### Source Package: ###
|
||||
Google Mock is also released in source packages which can be downloaded from
|
||||
its Google Code download page[1]. Several different archive formats are
|
||||
provided, but the only difference is the tools needed to extract their
|
||||
contents, and the size of the resulting file. Download whichever you are most
|
||||
comfortable with.
|
||||
|
||||
[1] Google Mock Downloads: http://code.google.com/p/googlemock/downloads/list
|
||||
|
||||
Once downloaded expand the archive using whichever tools you prefer for that
|
||||
type. This will always result in a new directory with the name "gmock-X.Y.Z"
|
||||
which contains all of the source code. Here are some examples in Linux:
|
||||
|
||||
tar -xvzf gmock-X.Y.Z.tar.gz
|
||||
tar -xvjf gmock-X.Y.Z.tar.bz2
|
||||
unzip gmock-X.Y.Z.zip
|
||||
|
||||
Building the Source
|
||||
-------------------
|
||||
### Linux and Mac OS X (without Xcode) ###
|
||||
There are two primary options for building the source at this point: build it
|
||||
inside the source code tree, or in a separate directory. We recommend building
|
||||
in a separate directory as that tends to produce both more consistent results
|
||||
and be easier to clean up should anything go wrong, but both patterns are
|
||||
supported. The only hard restriction is that while the build directory can be
|
||||
a subdirectory of the source directory, the opposite is not possible and will
|
||||
result in errors. Once you have selected where you wish to build Google Mock,
|
||||
create the directory if necessary, and enter it. The following steps apply for
|
||||
either approach by simply substituting the shell variable SRCDIR with "." for
|
||||
building inside the source directory, and the relative path to the source
|
||||
directory otherwise.
|
||||
|
||||
${SRCDIR}/configure # Standard GNU configure script, --help for more info
|
||||
|
||||
The default behavior of the configure script with respect to locating and using
|
||||
Google Test is to first search for a 'gtest-config' in the system path, and
|
||||
lacking this, build an internal copy of Google Test. You may optionally specify
|
||||
a custom Google Test you wish to build Google Mock against, provided it is
|
||||
a new enough version.
|
||||
|
||||
# Configure against an installation in '/opt' with '/opt/bin/gtest-config'.
|
||||
${SRCDIR}/configure --with-gtest=/opt
|
||||
|
||||
This can also be used to specify a Google Test which hasn't yet been installed.
|
||||
However, it must have been configured and built as described in the Google Test
|
||||
README before you configure Google Mock. To enable this feature, simply pass
|
||||
the directory where you configured and built Google Test (which is not
|
||||
necessarily its source directory) to Google Mock's configure script.
|
||||
|
||||
# Configure against a build of Google Test in an arbitrary directory.
|
||||
${SRCDIR}/configure --with-gtest=../../my_gtest_build
|
||||
|
||||
Finally, if you have a version of Google Test installed but for some reason
|
||||
wish to forcibly prevent it from being used, we provide a special option.
|
||||
Typically this is not needed as we fall back to the internal Google Test
|
||||
packaged with Google Mock if an installed version is either unavailable or too
|
||||
old to build Google Mock. When using the internally packaged Google Test, the
|
||||
user does *not* need to configure or build it, that is automatically handled by
|
||||
Google Mock's build system.
|
||||
|
||||
# Force the use of the internally packaged Google Test, despite
|
||||
# 'gtest-config' being in your PATH.
|
||||
${SRCDIR}/configure --disable-external-gtest
|
||||
|
||||
Once you have successfully configured Google Mock, the build steps are standard
|
||||
for GNU-style OSS packages.
|
||||
|
||||
make # Standard makefile following GNU conventions
|
||||
make check # Builds and runs all tests - all should pass
|
||||
|
||||
Other programs will only be able to use Google Mock's functionality if you
|
||||
install it in a location which they can access, in Linux this is typically
|
||||
under '/usr/local'. The following command will install all of the Google Mock
|
||||
libraries, public headers, and utilities necessary for other programs and
|
||||
libraries to leverage it. Note that if Google Mock was unable to find an
|
||||
external Google Test to build against, it will also install the internally
|
||||
packaged Google Test in order to allow the installed Google Mock to function
|
||||
properly. This Google Test install will be fully functional, and if installed
|
||||
will also be uninstalled by uninstalling Google Mock.
|
||||
|
||||
sudo make install # Not necessary, but allows use by other programs
|
||||
|
||||
Should you need to remove Google Mock from your system after having installed
|
||||
it, run the following command, and it will back out its changes. However, note
|
||||
carefully that you must run this command on the *same* Google Mock build that
|
||||
you ran the install from, or the results are not predictable. If you install
|
||||
Google Mock on your system, and are working from a VCS checkout, make sure you
|
||||
run this *before* updating your checkout of the source in order to uninstall
|
||||
the same version which you installed.
|
||||
|
||||
sudo make uninstall # Must be run against the exact same build as "install"
|
||||
|
||||
Your project can build against Google Mock and Google Test simply by leveraging
|
||||
the 'gmock-config' script. This script can be invoked directly out of the
|
||||
'scripts' subdirectory of the build tree, and it will be installed in the
|
||||
binary directory specified during the 'configure'. Here are some examples of
|
||||
its use, see 'gmock-config --help' for more detailed information.
|
||||
|
||||
gmock-config --min-version=1.0 || echo "Insufficient Google Mock version."
|
||||
|
||||
g++ $(gmock-config --cppflags --cxxflags) -o foo.o -c foo.cpp
|
||||
g++ $(gmock-config --ldflags --libs) -o foo foo.o
|
||||
|
||||
# When using a built but not installed Google Mock:
|
||||
g++ $(../../my_gmock_build/scripts/gmock-config ...) ...
|
||||
|
||||
Note that when building your project against Google Mock, you are building
|
||||
against Google Test as well. There is no need to configure Google Test
|
||||
separately.
|
||||
|
||||
### Windows ###
|
||||
The msvc/ directory contains VC++ 2005 projects for building Google
|
||||
Mock and selected tests. In order to build Google Mock you must have
|
||||
an implementation of TR1 tuple. One library that provides such
|
||||
implementation is Boost. If you choose to use Boost, download it from
|
||||
www.boost.org and install it on your system. Note that Boost TR1 tuple
|
||||
is a header-only library, so the installation only involves unpacking
|
||||
it to a suitable location - you don't need to compile it or download a
|
||||
pre-compiled Boost binary.
|
||||
|
||||
Since Boost is quite large, you may prefer to only install the files
|
||||
actually needed by Google Mock. If so, you can download TR1 tuple
|
||||
without other parts of Boost from
|
||||
http://code.google.com/p/googlemock/downloads/list.
|
||||
|
||||
After that you have two options: either set up Boost globally or
|
||||
modify the Google Mock project to point to your copy of Boost. The
|
||||
former will let all your tests use the same Boost library while the
|
||||
latter will allow each of your projects use its own copy. You can also
|
||||
use a hybrid solution: your project settings will override the
|
||||
system-wide one.
|
||||
|
||||
For example, if you unpacked boost v1.36.0 into C:\boost:
|
||||
To set up Boost such that all projects can use it:
|
||||
* Assuming you are using the Visual Studio 2005 IDE, select Tools |
|
||||
Options | Projects And Solutions | VC++ Directories.
|
||||
* In the "Show directories for" drop-down select Include Files. Add
|
||||
C:\boost\boost_1_36_0\boost\tr1\tr1 and C:\boost\boost_1_36_0 to the
|
||||
list of directories.
|
||||
|
||||
To configure your project to point to that version of Boost, replace
|
||||
the value of the BoostDir user macro with C:\boost\boost_1_36_0 in the
|
||||
msvc/gmock_config.vsprops file. You can use any text editor to edit
|
||||
that file.
|
||||
|
||||
If you want to use a version of Google Test other then the one bundled with
|
||||
Google Mock, change the value of the GTestDir macro in gmock_config.vsprop
|
||||
to point to the new location.
|
||||
|
||||
After configuring Boost, just 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:
|
||||
* 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.
|
||||
* In Project Properties | Configuration Properties | General | Additional
|
||||
Include Directories, type <path to Google Mock>/include.
|
||||
|
||||
TODO(wan@google.com): update the .vsprops and .vcproj files such that the
|
||||
last step is unnecessary.
|
||||
|
||||
### Using GNU Make ###
|
||||
The make/ directory contains a Makefile that you can use to build
|
||||
Google Mock on systems where GNU make is available (e.g. Linux and Mac
|
||||
OS X). It doesn't try to build Google Mock's own tests. Instead, it
|
||||
just builds the Google Mock libraries and some sample tests. You can
|
||||
use it as a starting point for your own Makefile.
|
||||
|
||||
If the default settings are correct for your environment, the
|
||||
following commands should succeed:
|
||||
|
||||
cd ${SRCDIR}/make
|
||||
make
|
||||
./gmock_test
|
||||
|
||||
If you see errors, try to tweak the contents of make/Makefile to make
|
||||
them go away. There are instructions in make/Makefile on how to do
|
||||
it.
|
||||
|
||||
### Using Your Own Build System ###
|
||||
If none of the build solutions we provide works for you, or if you
|
||||
prefer your own build system, you just need to compile
|
||||
${GTEST_SRCDIR}/src/gtest-all.cc (where GTEST_SRCDIR is the root of
|
||||
the Google Test source tree) and src/gmock-all.cc into a library and
|
||||
link your tests with it. Assuming a Linux-like system and gcc,
|
||||
something like the following will do:
|
||||
|
||||
cd ${SRCDIR}
|
||||
g++ -I. -I./include -I${GTEST_SRCDIR} -I${GTEST_SRCDIR}/include \
|
||||
-c {GTEST_SRCDIR}/src/gtest-all.cc
|
||||
g++ -I. -I./include -I${GTEST_SRCDIR} -I${GTEST_SRCDIR}/include \
|
||||
-c src/gmock-all.cc
|
||||
ar -rv libgmock.a gtest-all.o gmock-all.o
|
||||
g++ -I. -I./include -I${GTEST_SRCDIR} -I${GTEST_SRCDIR}/include \
|
||||
path/to/your_test.cc libgmock.a -o your_test
|
||||
|
||||
On Windows, you'll also need to add the include path for the boost
|
||||
headers to the compiler command line. See
|
||||
http://www.boost.org/doc/libs/1_36_0/doc/html/boost_tr1/usage.html for
|
||||
how to do it.
|
||||
|
||||
Regenerating Source Files
|
||||
-------------------------
|
||||
Some of Google Mock's source files are generated from templates (not
|
||||
in the C++ sense) using a script. A template file is named FOO.pump,
|
||||
where FOO is the name of the file it will generate. For example, the
|
||||
file include/gmock/gmock-generated-actions.h.pump is used to generate
|
||||
gmock-generated-actions.h in the same directory.
|
||||
|
||||
Normally you don't need to worry about regenerating the source files,
|
||||
unless you need to modify them (e.g. if you are working on a patch for
|
||||
Google Mock). In that case, you should modify the corresponding .pump
|
||||
files instead and run the 'pump' script (for Pump is Useful for Meta
|
||||
Programming) to regenerate them. We are still working on releasing
|
||||
the script and its documentation. If you need it now, please email
|
||||
googlemock@googlegroups.com such that we know to make it happen
|
||||
sooner.
|
||||
|
||||
Happy testing!
|
||||
@@ -0,0 +1,125 @@
|
||||
AC_INIT([Google C++ Mocking Framework],
|
||||
[1.1.0],
|
||||
[googlemock@googlegroups.com],
|
||||
[gmock])
|
||||
|
||||
# Provide various options to initialize the Autoconf and configure processes.
|
||||
AC_PREREQ([2.59])
|
||||
AC_CONFIG_SRCDIR([./COPYING])
|
||||
AC_CONFIG_AUX_DIR([build-aux])
|
||||
AC_CONFIG_HEADERS([build-aux/config.h])
|
||||
AC_CONFIG_FILES([Makefile])
|
||||
AC_CONFIG_FILES([scripts/gmock-config], [chmod +x scripts/gmock-config])
|
||||
|
||||
# Initialize Automake with various options. We require at least v1.9, prevent
|
||||
# pedantic complaints about package files, and enable various distribution
|
||||
# targets.
|
||||
AM_INIT_AUTOMAKE([1.9 dist-bzip2 dist-zip foreign subdir-objects])
|
||||
|
||||
# Check for programs used in building Google Test.
|
||||
AC_PROG_CC
|
||||
AC_PROG_CXX
|
||||
AC_LANG([C++])
|
||||
AC_PROG_LIBTOOL
|
||||
|
||||
# TODO(chandlerc@google.com): Currently we aren't running the Python tests
|
||||
# against the interpreter detected by AM_PATH_PYTHON, and so we condition
|
||||
# HAVE_PYTHON by requiring "python" to be in the PATH, and that interpreter's
|
||||
# version to be >= 2.3. This will allow the scripts to use a "/usr/bin/env"
|
||||
# hashbang.
|
||||
PYTHON= # We *do not* allow the user to specify a python interpreter
|
||||
AC_PATH_PROG([PYTHON],[python],[:])
|
||||
AS_IF([test "$PYTHON" != ":"],
|
||||
[AM_PYTHON_CHECK_VERSION([$PYTHON],[2.3],[:],[PYTHON=":"])])
|
||||
AM_CONDITIONAL([HAVE_PYTHON],[test "$PYTHON" != ":"])
|
||||
|
||||
# TODO(chandlerc@google.com) Check for the necessary system headers.
|
||||
|
||||
# GoogleMock currently has hard dependencies upon GoogleTest above and beyond
|
||||
# running its own test suite, so we both provide our own version in
|
||||
# a subdirectory and provide some logic to use a custom version or a system
|
||||
# installed version.
|
||||
AC_ARG_WITH([gtest],
|
||||
[AS_HELP_STRING([--with-gtest],
|
||||
[Specifies how to find the gtest package. If no
|
||||
arguments are given, the default behavior, a
|
||||
system installed gtest will be used if present,
|
||||
and an internal version built otherwise. If a
|
||||
path is provided, the gtest built or installed at
|
||||
that prefix will be used.])],
|
||||
[],
|
||||
[with_gtest=yes])
|
||||
AC_ARG_ENABLE([external-gtest],
|
||||
[AS_HELP_STRING([--disable-external-gtest],
|
||||
[Disables any detection or use of a system
|
||||
installed or user provided gtest. Any option to
|
||||
'--with-gtest' is ignored. (Default is enabled.)])
|
||||
], [], [enable_external_gtest=yes])
|
||||
AS_IF([test "x$with_gtest" == "xno"],
|
||||
[AC_MSG_ERROR([dnl
|
||||
Support for GoogleTest was explicitly disabled. Currently GoogleMock has a hard
|
||||
dependency upon GoogleTest to build, please provide a version, or allow
|
||||
GoogleMock to use any installed version and fall back upon its internal
|
||||
version.])])
|
||||
|
||||
# Setup various GTEST variables. TODO(chandlerc@google.com): When these are
|
||||
# used below, they should be used such that any pre-existing values always
|
||||
# trump values we set them to, so that they can be used to selectively override
|
||||
# details of the detection process.
|
||||
AC_ARG_VAR([GTEST_CONFIG],
|
||||
[The exact path of Google Test's 'gtest-config' script.])
|
||||
AC_ARG_VAR([GTEST_CPPFLAGS],
|
||||
[C-like preprocessor flags for Google Test.])
|
||||
AC_ARG_VAR([GTEST_CXXFLAGS],
|
||||
[C++ compile flags for Google Test.])
|
||||
AC_ARG_VAR([GTEST_LDFLAGS],
|
||||
[Linker path and option flags for Google Test.])
|
||||
AC_ARG_VAR([GTEST_LIBS],
|
||||
[Library linking flags for Google Test.])
|
||||
AC_ARG_VAR([GTEST_VERSION],
|
||||
[The version of Google Test available.])
|
||||
HAVE_BUILT_GTEST="no"
|
||||
|
||||
GTEST_MIN_VERSION="1.2.1"
|
||||
|
||||
AS_IF([test "x${enable_external_gtest}" = "xyes"],
|
||||
[# Begin filling in variables as we are able.
|
||||
AS_IF([test "x${with_gtest}" != "xyes"],
|
||||
[AS_IF([test -x "${with_gtest}/scripts/gtest-config"],
|
||||
[GTEST_CONFIG="${with_gtest}/scripts/gtest-config"],
|
||||
[GTEST_CONFIG="${with_gtest}/bin/gtest-config"])
|
||||
AS_IF([test -x "${GTEST_CONFIG}"], [],
|
||||
[AC_MSG_ERROR([dnl
|
||||
Unable to locate either a built or installed Google Test at '${with_gtest}'.])
|
||||
])])
|
||||
|
||||
AS_IF([test -x "${GTEST_CONFIG}"], [],
|
||||
[AC_PATH_PROG([GTEST_CONFIG], [gtest-config])])
|
||||
AS_IF([test -x "${GTEST_CONFIG}"],
|
||||
[AC_MSG_CHECKING([for Google Test version >= ${GTEST_MIN_VERSION}])
|
||||
AS_IF([${GTEST_CONFIG} --min-version=${GTEST_MIN_VERSION}],
|
||||
[AC_MSG_RESULT([yes])
|
||||
HAVE_BUILT_GTEST="yes"],
|
||||
[AC_MSG_RESULT([no])])])])
|
||||
|
||||
AS_IF([test "x${HAVE_BUILT_GTEST}" = "xyes"],
|
||||
[GTEST_CPPFLAGS=`${GTEST_CONFIG} --cppflags`
|
||||
GTEST_CXXFLAGS=`${GTEST_CONFIG} --cxxflags`
|
||||
GTEST_LDFLAGS=`${GTEST_CONFIG} --ldflags`
|
||||
GTEST_LIBS=`${GTEST_CONFIG} --libs`
|
||||
GTEST_VERSION=`${GTEST_CONFIG} --version`],
|
||||
[AC_CONFIG_SUBDIRS([gtest])
|
||||
# GTEST_CONFIG needs to be executable both in a Makefile environmont and
|
||||
# in a shell script environment, so resolve an absolute path for it here.
|
||||
GTEST_CONFIG="`pwd -P`/gtest/scripts/gtest-config"
|
||||
GTEST_CPPFLAGS='-I$(top_srcdir)/gtest/include'
|
||||
GTEST_CXXFLAGS='-g'
|
||||
GTEST_LDFLAGS=''
|
||||
GTEST_LIBS='$(top_builddir)/gtest/lib/libgtest.la'
|
||||
GTEST_VERSION="${GTEST_MIN_VERSION}"])
|
||||
|
||||
# TODO(chandlerc@google.com) Check the types, structures, and other compiler
|
||||
# and architecture characteristics.
|
||||
|
||||
# Output the generated files. No further autoconf macros may be used.
|
||||
AC_OUTPUT
|
||||
@@ -0,0 +1,931 @@
|
||||
// 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)
|
||||
|
||||
// Google Mock - a framework for writing C++ mock classes.
|
||||
//
|
||||
// This file implements some commonly used actions.
|
||||
|
||||
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_
|
||||
#define GMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_
|
||||
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
|
||||
#ifndef _WIN32_WCE
|
||||
#include <errno.h>
|
||||
#endif
|
||||
|
||||
#include <gmock/internal/gmock-internal-utils.h>
|
||||
#include <gmock/internal/gmock-port.h>
|
||||
|
||||
namespace testing {
|
||||
|
||||
// To implement an action Foo, define:
|
||||
// 1. a class FooAction that implements the ActionInterface interface, and
|
||||
// 2. a factory function that creates an Action object from a
|
||||
// const FooAction*.
|
||||
//
|
||||
// The two-level delegation design follows that of Matcher, providing
|
||||
// consistency for extension developers. It also eases ownership
|
||||
// management as Action objects can now be copied like plain values.
|
||||
|
||||
namespace internal {
|
||||
|
||||
template <typename F>
|
||||
class MonomorphicDoDefaultActionImpl;
|
||||
|
||||
template <typename F1, typename F2>
|
||||
class ActionAdaptor;
|
||||
|
||||
// BuiltInDefaultValue<T>::Get() returns the "built-in" default
|
||||
// value for type T, which is NULL when T is a pointer type, 0 when T
|
||||
// is a numeric type, false when T is bool, or "" when T is string or
|
||||
// std::string. For any other type T, this value is undefined and the
|
||||
// function will abort the process.
|
||||
template <typename T>
|
||||
class BuiltInDefaultValue {
|
||||
public:
|
||||
// This function returns true iff type T has a built-in default value.
|
||||
static bool Exists() { return false; }
|
||||
static T Get() {
|
||||
Assert(false, __FILE__, __LINE__,
|
||||
"Default action undefined for the function return type.");
|
||||
return internal::Invalid<T>();
|
||||
// The above statement will never be reached, but is required in
|
||||
// order for this function to compile.
|
||||
}
|
||||
};
|
||||
|
||||
// This partial specialization says that we use the same built-in
|
||||
// default value for T and const T.
|
||||
template <typename T>
|
||||
class BuiltInDefaultValue<const T> {
|
||||
public:
|
||||
static bool Exists() { return BuiltInDefaultValue<T>::Exists(); }
|
||||
static T Get() { return BuiltInDefaultValue<T>::Get(); }
|
||||
};
|
||||
|
||||
// This partial specialization defines the default values for pointer
|
||||
// types.
|
||||
template <typename T>
|
||||
class BuiltInDefaultValue<T*> {
|
||||
public:
|
||||
static bool Exists() { return true; }
|
||||
static T* Get() { return NULL; }
|
||||
};
|
||||
|
||||
// The following specializations define the default values for
|
||||
// specific types we care about.
|
||||
#define GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(type, value) \
|
||||
template <> \
|
||||
class BuiltInDefaultValue<type> { \
|
||||
public: \
|
||||
static bool Exists() { return true; } \
|
||||
static type Get() { return value; } \
|
||||
}
|
||||
|
||||
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(void, ); // NOLINT
|
||||
#if GTEST_HAS_GLOBAL_STRING
|
||||
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(::string, "");
|
||||
#endif // GTEST_HAS_GLOBAL_STRING
|
||||
#if GTEST_HAS_STD_STRING
|
||||
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(::std::string, "");
|
||||
#endif // GTEST_HAS_STD_STRING
|
||||
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(bool, false);
|
||||
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(unsigned char, '\0');
|
||||
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(signed char, '\0');
|
||||
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(char, '\0');
|
||||
|
||||
// signed wchar_t and unsigned wchar_t are NOT in the C++ standard.
|
||||
// Using them is a bad practice and not portable. So don't use them.
|
||||
//
|
||||
// Still, Google Mock is designed to work even if the user uses signed
|
||||
// wchar_t or unsigned wchar_t (obviously, assuming the compiler
|
||||
// supports them).
|
||||
//
|
||||
// To gcc,
|
||||
//
|
||||
// wchar_t == signed wchar_t != unsigned wchar_t == unsigned int
|
||||
//
|
||||
// MSVC does not recognize signed wchar_t or unsigned wchar_t. It
|
||||
// treats wchar_t as a native type usually, but treats it as the same
|
||||
// as unsigned short when the compiler option /Zc:wchar_t- is
|
||||
// specified.
|
||||
//
|
||||
// Therefore we provide a default action for wchar_t when compiled
|
||||
// with gcc or _NATIVE_WCHAR_T_DEFINED is defined.
|
||||
//
|
||||
// There's no need for a default action for signed wchar_t, as that
|
||||
// type is the same as wchar_t for gcc, and invalid for MSVC.
|
||||
//
|
||||
// There's also no need for a default action for unsigned wchar_t, as
|
||||
// that type is the same as unsigned int for gcc, and invalid for
|
||||
// MSVC.
|
||||
#if defined(__GNUC__) || defined(_NATIVE_WCHAR_T_DEFINED)
|
||||
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(wchar_t, 0U); // NOLINT
|
||||
#endif
|
||||
|
||||
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(unsigned short, 0U); // NOLINT
|
||||
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(signed short, 0); // NOLINT
|
||||
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(unsigned int, 0U);
|
||||
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(signed int, 0);
|
||||
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(unsigned long, 0UL); // NOLINT
|
||||
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(signed long, 0L); // NOLINT
|
||||
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(UInt64, 0);
|
||||
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(Int64, 0);
|
||||
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(float, 0);
|
||||
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(double, 0);
|
||||
|
||||
#undef GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_
|
||||
|
||||
} // namespace internal
|
||||
|
||||
// When an unexpected function call is encountered, Google Mock will
|
||||
// let it return a default value if the user has specified one for its
|
||||
// return type, or if the return type has a built-in default value;
|
||||
// otherwise Google Mock won't know what value to return and will have
|
||||
// to abort the process.
|
||||
//
|
||||
// The DefaultValue<T> class allows a user to specify the
|
||||
// default value for a type T that is both copyable and publicly
|
||||
// destructible (i.e. anything that can be used as a function return
|
||||
// type). The usage is:
|
||||
//
|
||||
// // Sets the default value for type T to be foo.
|
||||
// DefaultValue<T>::Set(foo);
|
||||
template <typename T>
|
||||
class DefaultValue {
|
||||
public:
|
||||
// Sets the default value for type T; requires T to be
|
||||
// copy-constructable and have a public destructor.
|
||||
static void Set(T x) {
|
||||
delete value_;
|
||||
value_ = new T(x);
|
||||
}
|
||||
|
||||
// Unsets the default value for type T.
|
||||
static void Clear() {
|
||||
delete value_;
|
||||
value_ = NULL;
|
||||
}
|
||||
|
||||
// Returns true iff the user has set the default value for type T.
|
||||
static bool IsSet() { return value_ != NULL; }
|
||||
|
||||
// Returns true if T has a default return value set by the user or there
|
||||
// exists a built-in default value.
|
||||
static bool Exists() {
|
||||
return IsSet() || internal::BuiltInDefaultValue<T>::Exists();
|
||||
}
|
||||
|
||||
// Returns the default value for type T if the user has set one;
|
||||
// otherwise returns the built-in default value if there is one;
|
||||
// otherwise aborts the process.
|
||||
static T Get() {
|
||||
return value_ == NULL ?
|
||||
internal::BuiltInDefaultValue<T>::Get() : *value_;
|
||||
}
|
||||
private:
|
||||
static const T* value_;
|
||||
};
|
||||
|
||||
// This partial specialization allows a user to set default values for
|
||||
// reference types.
|
||||
template <typename T>
|
||||
class DefaultValue<T&> {
|
||||
public:
|
||||
// Sets the default value for type T&.
|
||||
static void Set(T& x) { // NOLINT
|
||||
address_ = &x;
|
||||
}
|
||||
|
||||
// Unsets the default value for type T&.
|
||||
static void Clear() {
|
||||
address_ = NULL;
|
||||
}
|
||||
|
||||
// Returns true iff the user has set the default value for type T&.
|
||||
static bool IsSet() { return address_ != NULL; }
|
||||
|
||||
// Returns true if T has a default return value set by the user or there
|
||||
// exists a built-in default value.
|
||||
static bool Exists() {
|
||||
return IsSet() || internal::BuiltInDefaultValue<T&>::Exists();
|
||||
}
|
||||
|
||||
// Returns the default value for type T& if the user has set one;
|
||||
// otherwise returns the built-in default value if there is one;
|
||||
// otherwise aborts the process.
|
||||
static T& Get() {
|
||||
return address_ == NULL ?
|
||||
internal::BuiltInDefaultValue<T&>::Get() : *address_;
|
||||
}
|
||||
private:
|
||||
static T* address_;
|
||||
};
|
||||
|
||||
// This specialization allows DefaultValue<void>::Get() to
|
||||
// compile.
|
||||
template <>
|
||||
class DefaultValue<void> {
|
||||
public:
|
||||
static bool Exists() { return true; }
|
||||
static void Get() {}
|
||||
};
|
||||
|
||||
// Points to the user-set default value for type T.
|
||||
template <typename T>
|
||||
const T* DefaultValue<T>::value_ = NULL;
|
||||
|
||||
// Points to the user-set default value for type T&.
|
||||
template <typename T>
|
||||
T* DefaultValue<T&>::address_ = NULL;
|
||||
|
||||
// Implement this interface to define an action for function type F.
|
||||
template <typename F>
|
||||
class ActionInterface {
|
||||
public:
|
||||
typedef typename internal::Function<F>::Result Result;
|
||||
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
|
||||
|
||||
ActionInterface() : is_do_default_(false) {}
|
||||
|
||||
virtual ~ActionInterface() {}
|
||||
|
||||
// Performs the action. This method is not const, as in general an
|
||||
// action can have side effects and be stateful. For example, a
|
||||
// get-the-next-element-from-the-collection action will need to
|
||||
// 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_;
|
||||
};
|
||||
|
||||
// An Action<F> is a copyable and IMMUTABLE (except by assignment)
|
||||
// object that represents an action to be taken when a mock function
|
||||
// of type F is called. The implementation of Action<T> is just a
|
||||
// linked_ptr to const ActionInterface<T>, so copying is fairly cheap.
|
||||
// Don't inherit from Action!
|
||||
//
|
||||
// You can view an object implementing ActionInterface<F> as a
|
||||
// concrete action (including its current state), and an Action<F>
|
||||
// object as a handle to it.
|
||||
template <typename F>
|
||||
class Action {
|
||||
public:
|
||||
typedef typename internal::Function<F>::Result Result;
|
||||
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
|
||||
|
||||
// Constructs a null Action. Needed for storing Action objects in
|
||||
// STL containers.
|
||||
Action() : impl_(NULL) {}
|
||||
|
||||
// Constructs an Action from its implementation.
|
||||
explicit Action(ActionInterface<F>* impl) : impl_(impl) {}
|
||||
|
||||
// Copy constructor.
|
||||
Action(const Action& action) : impl_(action.impl_) {}
|
||||
|
||||
// This constructor allows us to turn an Action<Func> object into an
|
||||
// Action<F>, as long as F's arguments can be implicitly converted
|
||||
// to Func's and Func's return type cann be implicitly converted to
|
||||
// F's.
|
||||
template <typename Func>
|
||||
explicit Action(const Action<Func>& action);
|
||||
|
||||
// Returns true iff this is the DoDefault() action.
|
||||
bool IsDoDefault() const { return impl_->IsDoDefault(); }
|
||||
|
||||
// Performs the action. Note that this method is const even though
|
||||
// the corresponding method in ActionInterface is not. The reason
|
||||
// is that a const Action<F> means that it cannot be re-bound to
|
||||
// another concrete action, not that the concrete action it binds to
|
||||
// cannot change state. (Think of the difference between a const
|
||||
// pointer and a pointer to const.)
|
||||
Result Perform(const ArgumentTuple& args) const {
|
||||
return impl_->Perform(args);
|
||||
}
|
||||
private:
|
||||
template <typename F1, typename F2>
|
||||
friend class internal::ActionAdaptor;
|
||||
|
||||
internal::linked_ptr<ActionInterface<F> > impl_;
|
||||
};
|
||||
|
||||
// The PolymorphicAction class template makes it easy to implement a
|
||||
// polymorphic action (i.e. an action that can be used in mock
|
||||
// functions of than one type, e.g. Return()).
|
||||
//
|
||||
// To define a polymorphic action, a user first provides a COPYABLE
|
||||
// implementation class that has a Perform() method template:
|
||||
//
|
||||
// class FooAction {
|
||||
// public:
|
||||
// template <typename Result, typename ArgumentTuple>
|
||||
// Result Perform(const ArgumentTuple& args) const {
|
||||
// // Processes the arguments and returns a result, using
|
||||
// // tr1::get<N>(args) to get the N-th (0-based) argument in the tuple.
|
||||
// }
|
||||
// ...
|
||||
// };
|
||||
//
|
||||
// Then the user creates the polymorphic action using
|
||||
// MakePolymorphicAction(object) where object has type FooAction. See
|
||||
// the definition of Return(void) and SetArgumentPointee<N>(value) for
|
||||
// complete examples.
|
||||
template <typename Impl>
|
||||
class PolymorphicAction {
|
||||
public:
|
||||
explicit PolymorphicAction(const Impl& impl) : impl_(impl) {}
|
||||
|
||||
template <typename F>
|
||||
operator Action<F>() const {
|
||||
return Action<F>(new MonomorphicImpl<F>(impl_));
|
||||
}
|
||||
private:
|
||||
template <typename F>
|
||||
class MonomorphicImpl : public ActionInterface<F> {
|
||||
public:
|
||||
typedef typename internal::Function<F>::Result Result;
|
||||
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
|
||||
|
||||
explicit MonomorphicImpl(const Impl& impl) : impl_(impl) {}
|
||||
|
||||
virtual Result Perform(const ArgumentTuple& args) {
|
||||
return impl_.template Perform<Result>(args);
|
||||
}
|
||||
|
||||
private:
|
||||
Impl impl_;
|
||||
};
|
||||
|
||||
Impl impl_;
|
||||
};
|
||||
|
||||
// Creates an Action from its implementation and returns it. The
|
||||
// created Action object owns the implementation.
|
||||
template <typename F>
|
||||
Action<F> MakeAction(ActionInterface<F>* impl) {
|
||||
return Action<F>(impl);
|
||||
}
|
||||
|
||||
// Creates a polymorphic action from its implementation. This is
|
||||
// easier to use than the PolymorphicAction<Impl> constructor as it
|
||||
// doesn't require you to explicitly write the template argument, e.g.
|
||||
//
|
||||
// MakePolymorphicAction(foo);
|
||||
// vs
|
||||
// PolymorphicAction<TypeOfFoo>(foo);
|
||||
template <typename Impl>
|
||||
inline PolymorphicAction<Impl> MakePolymorphicAction(const Impl& impl) {
|
||||
return PolymorphicAction<Impl>(impl);
|
||||
}
|
||||
|
||||
namespace internal {
|
||||
|
||||
// Allows an Action<F2> object to pose as an Action<F1>, as long as F2
|
||||
// and F1 are compatible.
|
||||
template <typename F1, typename F2>
|
||||
class ActionAdaptor : public ActionInterface<F1> {
|
||||
public:
|
||||
typedef typename internal::Function<F1>::Result Result;
|
||||
typedef typename internal::Function<F1>::ArgumentTuple ArgumentTuple;
|
||||
|
||||
explicit ActionAdaptor(const Action<F2>& from) : impl_(from.impl_) {}
|
||||
|
||||
virtual Result Perform(const ArgumentTuple& args) {
|
||||
return impl_->Perform(args);
|
||||
}
|
||||
private:
|
||||
const internal::linked_ptr<ActionInterface<F2> > impl_;
|
||||
};
|
||||
|
||||
// Implements the polymorphic Return(x) action, which can be used in
|
||||
// any function that returns the type of x, regardless of the argument
|
||||
// types.
|
||||
template <typename R>
|
||||
class ReturnAction {
|
||||
public:
|
||||
// Constructs a ReturnAction object from the value to be returned.
|
||||
// 'value' is passed by value instead of by const reference in order
|
||||
// to allow Return("string literal") to compile.
|
||||
explicit ReturnAction(R value) : value_(value) {}
|
||||
|
||||
// This template type conversion operator allows Return(x) to be
|
||||
// used in ANY function that returns x's type.
|
||||
template <typename F>
|
||||
operator Action<F>() const {
|
||||
// Assert statement belongs here because this is the best place to verify
|
||||
// conditions on F. It produces the clearest error messages
|
||||
// in most compilers.
|
||||
// Impl really belongs in this scope as a local class but can't
|
||||
// because MSVC produces duplicate symbols in different translation units
|
||||
// in this case. Until MS fixes that bug we put Impl into the class scope
|
||||
// and put the typedef both here (for use in assert statement) and
|
||||
// in the Impl class. But both definitions must be the same.
|
||||
typedef typename Function<F>::Result Result;
|
||||
GMOCK_COMPILE_ASSERT_(
|
||||
!internal::is_reference<Result>::value,
|
||||
use_ReturnRef_instead_of_Return_to_return_a_reference);
|
||||
return Action<F>(new Impl<F>(value_));
|
||||
}
|
||||
private:
|
||||
// Implements the Return(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(R value) : value_(value) {}
|
||||
|
||||
virtual Result Perform(const ArgumentTuple&) { return value_; }
|
||||
|
||||
private:
|
||||
R value_;
|
||||
};
|
||||
|
||||
R value_;
|
||||
};
|
||||
|
||||
// Implements the ReturnNull() action.
|
||||
class ReturnNullAction {
|
||||
public:
|
||||
// Allows ReturnNull() to be used in any pointer-returning function.
|
||||
template <typename Result, typename ArgumentTuple>
|
||||
static Result Perform(const ArgumentTuple&) {
|
||||
GMOCK_COMPILE_ASSERT_(internal::is_pointer<Result>::value,
|
||||
ReturnNull_can_be_used_to_return_a_pointer_only);
|
||||
return NULL;
|
||||
}
|
||||
};
|
||||
|
||||
// Implements the Return() action.
|
||||
class ReturnVoidAction {
|
||||
public:
|
||||
// Allows Return() to be used in any void-returning function.
|
||||
template <typename Result, typename ArgumentTuple>
|
||||
static void Perform(const ArgumentTuple&) {
|
||||
CompileAssertTypesEqual<void, Result>();
|
||||
}
|
||||
};
|
||||
|
||||
// Implements the polymorphic ReturnRef(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 ReturnRefAction {
|
||||
public:
|
||||
// Constructs a ReturnRefAction object from the reference to be returned.
|
||||
explicit ReturnRefAction(T& ref) : ref_(ref) {} // NOLINT
|
||||
|
||||
// This template type conversion operator allows ReturnRef(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 ReturnRef(x) when Return(x)
|
||||
// should be used, and generates some helpful error message.
|
||||
GMOCK_COMPILE_ASSERT_(internal::is_reference<Result>::value,
|
||||
use_Return_instead_of_ReturnRef_to_return_a_value);
|
||||
return Action<F>(new Impl<F>(ref_));
|
||||
}
|
||||
private:
|
||||
// Implements the ReturnRef(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(T& ref) : ref_(ref) {} // NOLINT
|
||||
|
||||
virtual Result Perform(const ArgumentTuple&) {
|
||||
return ref_;
|
||||
}
|
||||
private:
|
||||
T& ref_;
|
||||
};
|
||||
|
||||
T& ref_;
|
||||
};
|
||||
|
||||
// Implements the DoDefault() action for a particular function type F.
|
||||
template <typename F>
|
||||
class MonomorphicDoDefaultActionImpl : public ActionInterface<F> {
|
||||
public:
|
||||
typedef typename Function<F>::Result Result;
|
||||
typedef typename Function<F>::ArgumentTuple ArgumentTuple;
|
||||
|
||||
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.
|
||||
}
|
||||
};
|
||||
|
||||
// Implements the polymorphic DoDefault() action.
|
||||
class DoDefaultAction {
|
||||
public:
|
||||
// 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>);
|
||||
}
|
||||
};
|
||||
|
||||
// Implements the Assign action to set a given pointer referent to a
|
||||
// particular value.
|
||||
template <typename T1, typename T2>
|
||||
class AssignAction {
|
||||
public:
|
||||
AssignAction(T1* ptr, T2 value) : ptr_(ptr), value_(value) {}
|
||||
|
||||
template <typename Result, typename ArgumentTuple>
|
||||
void Perform(const ArgumentTuple& /* args */) const {
|
||||
*ptr_ = value_;
|
||||
}
|
||||
private:
|
||||
T1* const ptr_;
|
||||
const T2 value_;
|
||||
};
|
||||
|
||||
#ifndef _WIN32_WCE
|
||||
|
||||
// Implements the SetErrnoAndReturn action to simulate return from
|
||||
// various system calls and libc functions.
|
||||
template <typename T>
|
||||
class SetErrnoAndReturnAction {
|
||||
public:
|
||||
SetErrnoAndReturnAction(int errno_value, T result)
|
||||
: errno_(errno_value),
|
||||
result_(result) {}
|
||||
template <typename Result, typename ArgumentTuple>
|
||||
Result Perform(const ArgumentTuple& /* args */) const {
|
||||
errno = errno_;
|
||||
return result_;
|
||||
}
|
||||
private:
|
||||
const int errno_;
|
||||
const T result_;
|
||||
};
|
||||
|
||||
#endif // _WIN32_WCE
|
||||
|
||||
// Implements the SetArgumentPointee<N>(x) action for any function
|
||||
// whose N-th argument (0-based) is a pointer to x's type. The
|
||||
// template parameter kIsProto is true iff type A is ProtocolMessage,
|
||||
// proto2::Message, or a sub-class of those.
|
||||
template <size_t N, typename A, bool kIsProto>
|
||||
class SetArgumentPointeeAction {
|
||||
public:
|
||||
// Constructs an action that sets the variable pointed to by the
|
||||
// N-th function argument to 'value'.
|
||||
explicit SetArgumentPointeeAction(const A& value) : value_(value) {}
|
||||
|
||||
template <typename Result, typename ArgumentTuple>
|
||||
void Perform(const ArgumentTuple& args) const {
|
||||
CompileAssertTypesEqual<void, Result>();
|
||||
*::std::tr1::get<N>(args) = value_;
|
||||
}
|
||||
|
||||
private:
|
||||
const A value_;
|
||||
};
|
||||
|
||||
template <size_t N, typename Proto>
|
||||
class SetArgumentPointeeAction<N, Proto, true> {
|
||||
public:
|
||||
// Constructs an action that sets the variable pointed to by the
|
||||
// N-th function argument to 'proto'. Both ProtocolMessage and
|
||||
// proto2::Message have the CopyFrom() method, so the same
|
||||
// implementation works for both.
|
||||
explicit SetArgumentPointeeAction(const Proto& proto) : proto_(new Proto) {
|
||||
proto_->CopyFrom(proto);
|
||||
}
|
||||
|
||||
template <typename Result, typename ArgumentTuple>
|
||||
void Perform(const ArgumentTuple& args) const {
|
||||
CompileAssertTypesEqual<void, Result>();
|
||||
::std::tr1::get<N>(args)->CopyFrom(*proto_);
|
||||
}
|
||||
private:
|
||||
const internal::linked_ptr<Proto> proto_;
|
||||
};
|
||||
|
||||
// Implements the SetArrayArgument<N>(first, last) action for any function
|
||||
// whose N-th argument (0-based) is a pointer or iterator to a type that can be
|
||||
// implicitly converted from *first.
|
||||
template <size_t N, typename InputIterator>
|
||||
class SetArrayArgumentAction {
|
||||
public:
|
||||
// Constructs an action that sets the variable pointed to by the
|
||||
// N-th function argument to 'value'.
|
||||
explicit SetArrayArgumentAction(InputIterator first, InputIterator last)
|
||||
: first_(first), last_(last) {
|
||||
}
|
||||
|
||||
template <typename Result, typename ArgumentTuple>
|
||||
void Perform(const ArgumentTuple& args) const {
|
||||
CompileAssertTypesEqual<void, Result>();
|
||||
|
||||
// Microsoft compiler deprecates ::std::copy, so we want to suppress warning
|
||||
// 4996 (Function call with parameters that may be unsafe) there.
|
||||
#if GTEST_OS_WINDOWS
|
||||
#pragma warning(push) // Saves the current warning state.
|
||||
#pragma warning(disable:4996) // Temporarily disables warning 4996.
|
||||
#endif // GTEST_OS_WINDOWS
|
||||
::std::copy(first_, last_, ::std::tr1::get<N>(args));
|
||||
#if GTEST_OS_WINDOWS
|
||||
#pragma warning(pop) // Restores the warning state.
|
||||
#endif // GTEST_OS_WINDOWS
|
||||
}
|
||||
|
||||
private:
|
||||
const InputIterator first_;
|
||||
const InputIterator last_;
|
||||
};
|
||||
|
||||
// Implements the InvokeWithoutArgs(f) action. The template argument
|
||||
// FunctionImpl is the implementation type of f, which can be either a
|
||||
// function pointer or a functor. InvokeWithoutArgs(f) can be used as an
|
||||
// Action<F> as long as f's type is compatible with F (i.e. f can be
|
||||
// assigned to a tr1::function<F>).
|
||||
template <typename FunctionImpl>
|
||||
class InvokeWithoutArgsAction {
|
||||
public:
|
||||
// The c'tor makes a copy of function_impl (either a function
|
||||
// pointer or a functor).
|
||||
explicit InvokeWithoutArgsAction(FunctionImpl function_impl)
|
||||
: function_impl_(function_impl) {}
|
||||
|
||||
// Allows InvokeWithoutArgs(f) to be used as any action whose type is
|
||||
// compatible with f.
|
||||
template <typename Result, typename ArgumentTuple>
|
||||
Result Perform(const ArgumentTuple&) { return function_impl_(); }
|
||||
private:
|
||||
FunctionImpl function_impl_;
|
||||
};
|
||||
|
||||
// Implements the InvokeWithoutArgs(object_ptr, &Class::Method) action.
|
||||
template <class Class, typename MethodPtr>
|
||||
class InvokeMethodWithoutArgsAction {
|
||||
public:
|
||||
InvokeMethodWithoutArgsAction(Class* obj_ptr, MethodPtr method_ptr)
|
||||
: obj_ptr_(obj_ptr), method_ptr_(method_ptr) {}
|
||||
|
||||
template <typename Result, typename ArgumentTuple>
|
||||
Result Perform(const ArgumentTuple&) const {
|
||||
return (obj_ptr_->*method_ptr_)();
|
||||
}
|
||||
private:
|
||||
Class* const obj_ptr_;
|
||||
const MethodPtr method_ptr_;
|
||||
};
|
||||
|
||||
// Implements the IgnoreResult(action) action.
|
||||
template <typename A>
|
||||
class IgnoreResultAction {
|
||||
public:
|
||||
explicit IgnoreResultAction(const A& action) : action_(action) {}
|
||||
|
||||
template <typename F>
|
||||
operator Action<F>() const {
|
||||
// Assert statement belongs here because this is the best place to verify
|
||||
// conditions on F. It produces the clearest error messages
|
||||
// in most compilers.
|
||||
// Impl really belongs in this scope as a local class but can't
|
||||
// because MSVC produces duplicate symbols in different translation units
|
||||
// in this case. Until MS fixes that bug we put Impl into the class scope
|
||||
// and put the typedef both here (for use in assert statement) and
|
||||
// in the Impl class. But both definitions must be the same.
|
||||
typedef typename internal::Function<F>::Result Result;
|
||||
|
||||
// Asserts at compile time that F returns void.
|
||||
CompileAssertTypesEqual<void, Result>();
|
||||
|
||||
return Action<F>(new Impl<F>(action_));
|
||||
}
|
||||
private:
|
||||
template <typename F>
|
||||
class Impl : public ActionInterface<F> {
|
||||
public:
|
||||
typedef typename internal::Function<F>::Result Result;
|
||||
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
|
||||
|
||||
explicit Impl(const A& action) : action_(action) {}
|
||||
|
||||
virtual void Perform(const ArgumentTuple& args) {
|
||||
// Performs the action and ignores its result.
|
||||
action_.Perform(args);
|
||||
}
|
||||
|
||||
private:
|
||||
// Type OriginalFunction is the same as F except that its return
|
||||
// type is IgnoredValue.
|
||||
typedef typename internal::Function<F>::MakeResultIgnoredValue
|
||||
OriginalFunction;
|
||||
|
||||
const Action<OriginalFunction> action_;
|
||||
};
|
||||
|
||||
const A action_;
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
// An Unused object can be implicitly constructed from ANY value.
|
||||
// This is handy when defining actions that ignore some or all of the
|
||||
// mock function arguments. For example, given
|
||||
//
|
||||
// MOCK_METHOD3(Foo, double(const string& label, double x, double y));
|
||||
// MOCK_METHOD3(Bar, double(int index, double x, double y));
|
||||
//
|
||||
// instead of
|
||||
//
|
||||
// double DistanceToOriginWithLabel(const string& label, double x, double y) {
|
||||
// return sqrt(x*x + y*y);
|
||||
// }
|
||||
// double DistanceToOriginWithIndex(int index, double x, double y) {
|
||||
// return sqrt(x*x + y*y);
|
||||
// }
|
||||
// ...
|
||||
// EXEPCT_CALL(mock, Foo("abc", _, _))
|
||||
// .WillOnce(Invoke(DistanceToOriginWithLabel));
|
||||
// EXEPCT_CALL(mock, Bar(5, _, _))
|
||||
// .WillOnce(Invoke(DistanceToOriginWithIndex));
|
||||
//
|
||||
// you could write
|
||||
//
|
||||
// // We can declare any uninteresting argument as Unused.
|
||||
// double DistanceToOrigin(Unused, double x, double y) {
|
||||
// return sqrt(x*x + y*y);
|
||||
// }
|
||||
// ...
|
||||
// EXEPCT_CALL(mock, Foo("abc", _, _)).WillOnce(Invoke(DistanceToOrigin));
|
||||
// EXEPCT_CALL(mock, Bar(5, _, _)).WillOnce(Invoke(DistanceToOrigin));
|
||||
typedef internal::IgnoredValue Unused;
|
||||
|
||||
// This constructor allows us to turn an Action<From> object into an
|
||||
// Action<To>, as long as To's arguments can be implicitly converted
|
||||
// to From's and From's return type cann be implicitly converted to
|
||||
// To's.
|
||||
template <typename To>
|
||||
template <typename From>
|
||||
Action<To>::Action(const Action<From>& from)
|
||||
: impl_(new internal::ActionAdaptor<To, From>(from)) {}
|
||||
|
||||
// Creates an action that returns 'value'. 'value' is passed by value
|
||||
// instead of const reference - otherwise Return("string literal")
|
||||
// will trigger a compiler error about using array as initializer.
|
||||
template <typename R>
|
||||
internal::ReturnAction<R> Return(R value) {
|
||||
return internal::ReturnAction<R>(value);
|
||||
}
|
||||
|
||||
// Creates an action that returns NULL.
|
||||
inline PolymorphicAction<internal::ReturnNullAction> ReturnNull() {
|
||||
return MakePolymorphicAction(internal::ReturnNullAction());
|
||||
}
|
||||
|
||||
// Creates an action that returns from a void function.
|
||||
inline PolymorphicAction<internal::ReturnVoidAction> Return() {
|
||||
return MakePolymorphicAction(internal::ReturnVoidAction());
|
||||
}
|
||||
|
||||
// Creates an action that returns the reference to a variable.
|
||||
template <typename R>
|
||||
inline internal::ReturnRefAction<R> ReturnRef(R& x) { // NOLINT
|
||||
return internal::ReturnRefAction<R>(x);
|
||||
}
|
||||
|
||||
// Creates an action that does the default action for the give mock function.
|
||||
inline internal::DoDefaultAction DoDefault() {
|
||||
return internal::DoDefaultAction();
|
||||
}
|
||||
|
||||
// Creates an action that sets the variable pointed by the N-th
|
||||
// (0-based) function argument to 'value'.
|
||||
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));
|
||||
}
|
||||
|
||||
// Creates an action that sets the elements of the array pointed to by the N-th
|
||||
// (0-based) function argument, which can be either a pointer or an iterator,
|
||||
// to the values of the elements in the source range [first, last).
|
||||
template <size_t N, typename InputIterator>
|
||||
PolymorphicAction<internal::SetArrayArgumentAction<N, InputIterator> >
|
||||
SetArrayArgument(InputIterator first, InputIterator last) {
|
||||
return MakePolymorphicAction(internal::SetArrayArgumentAction<
|
||||
N, InputIterator>(first, last));
|
||||
}
|
||||
|
||||
// Creates an action that sets a pointer referent to a given value.
|
||||
template <typename T1, typename T2>
|
||||
PolymorphicAction<internal::AssignAction<T1, T2> > Assign(T1* ptr, T2 val) {
|
||||
return MakePolymorphicAction(internal::AssignAction<T1, T2>(ptr, val));
|
||||
}
|
||||
|
||||
#ifndef _WIN32_WCE
|
||||
|
||||
// Creates an action that sets errno and returns the appropriate error.
|
||||
template <typename T>
|
||||
PolymorphicAction<internal::SetErrnoAndReturnAction<T> >
|
||||
SetErrnoAndReturn(int errval, T result) {
|
||||
return MakePolymorphicAction(
|
||||
internal::SetErrnoAndReturnAction<T>(errval, result));
|
||||
}
|
||||
|
||||
#endif // _WIN32_WCE
|
||||
|
||||
// Various overloads for InvokeWithoutArgs().
|
||||
|
||||
// Creates an action that invokes 'function_impl' with no argument.
|
||||
template <typename FunctionImpl>
|
||||
PolymorphicAction<internal::InvokeWithoutArgsAction<FunctionImpl> >
|
||||
InvokeWithoutArgs(FunctionImpl function_impl) {
|
||||
return MakePolymorphicAction(
|
||||
internal::InvokeWithoutArgsAction<FunctionImpl>(function_impl));
|
||||
}
|
||||
|
||||
// Creates an action that invokes the given method on the given object
|
||||
// with no argument.
|
||||
template <class Class, typename MethodPtr>
|
||||
PolymorphicAction<internal::InvokeMethodWithoutArgsAction<Class, MethodPtr> >
|
||||
InvokeWithoutArgs(Class* obj_ptr, MethodPtr method_ptr) {
|
||||
return MakePolymorphicAction(
|
||||
internal::InvokeMethodWithoutArgsAction<Class, MethodPtr>(
|
||||
obj_ptr, method_ptr));
|
||||
}
|
||||
|
||||
// Creates an action that performs an_action and throws away its
|
||||
// result. In other words, it changes the return type of an_action to
|
||||
// void. an_action MUST NOT return void, or the code won't compile.
|
||||
template <typename A>
|
||||
inline internal::IgnoreResultAction<A> IgnoreResult(const A& an_action) {
|
||||
return internal::IgnoreResultAction<A>(an_action);
|
||||
}
|
||||
|
||||
} // namespace testing
|
||||
|
||||
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_
|
||||
@@ -0,0 +1,146 @@
|
||||
// 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)
|
||||
|
||||
// Google Mock - a framework for writing C++ mock classes.
|
||||
//
|
||||
// This file implements some commonly used cardinalities. More
|
||||
// cardinalities can be defined by the user implementing the
|
||||
// CardinalityInterface interface if necessary.
|
||||
|
||||
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_
|
||||
#define GMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_
|
||||
|
||||
#include <limits.h>
|
||||
#include <ostream> // NOLINT
|
||||
#include <gmock/internal/gmock-port.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
namespace testing {
|
||||
|
||||
// To implement a cardinality Foo, define:
|
||||
// 1. a class FooCardinality that implements the
|
||||
// CardinalityInterface interface, and
|
||||
// 2. a factory function that creates a Cardinality object from a
|
||||
// const FooCardinality*.
|
||||
//
|
||||
// The two-level delegation design follows that of Matcher, providing
|
||||
// consistency for extension developers. It also eases ownership
|
||||
// management as Cardinality objects can now be copied like plain values.
|
||||
|
||||
// The implementation of a cardinality.
|
||||
class CardinalityInterface {
|
||||
public:
|
||||
virtual ~CardinalityInterface() {}
|
||||
|
||||
// Conservative estimate on the lower/upper bound of the number of
|
||||
// calls allowed.
|
||||
virtual int ConservativeLowerBound() const { return 0; }
|
||||
virtual int ConservativeUpperBound() const { return INT_MAX; }
|
||||
|
||||
// Returns true iff call_count calls will satisfy this cardinality.
|
||||
virtual bool IsSatisfiedByCallCount(int call_count) const = 0;
|
||||
|
||||
// Returns true iff call_count calls will saturate this cardinality.
|
||||
virtual bool IsSaturatedByCallCount(int call_count) const = 0;
|
||||
|
||||
// Describes self to an ostream.
|
||||
virtual void DescribeTo(::std::ostream* os) const = 0;
|
||||
};
|
||||
|
||||
// A Cardinality is a copyable and IMMUTABLE (except by assignment)
|
||||
// object that specifies how many times a mock function is expected to
|
||||
// be called. The implementation of Cardinality is just a linked_ptr
|
||||
// to const CardinalityInterface, so copying is fairly cheap.
|
||||
// Don't inherit from Cardinality!
|
||||
class Cardinality {
|
||||
public:
|
||||
// Constructs a null cardinality. Needed for storing Cardinality
|
||||
// objects in STL containers.
|
||||
Cardinality() {}
|
||||
|
||||
// Constructs a Cardinality from its implementation.
|
||||
explicit Cardinality(const CardinalityInterface* impl) : impl_(impl) {}
|
||||
|
||||
// Conservative estimate on the lower/upper bound of the number of
|
||||
// calls allowed.
|
||||
int ConservativeLowerBound() const { return impl_->ConservativeLowerBound(); }
|
||||
int ConservativeUpperBound() const { return impl_->ConservativeUpperBound(); }
|
||||
|
||||
// Returns true iff call_count calls will satisfy this cardinality.
|
||||
bool IsSatisfiedByCallCount(int call_count) const {
|
||||
return impl_->IsSatisfiedByCallCount(call_count);
|
||||
}
|
||||
|
||||
// Returns true iff call_count calls will saturate this cardinality.
|
||||
bool IsSaturatedByCallCount(int call_count) const {
|
||||
return impl_->IsSaturatedByCallCount(call_count);
|
||||
}
|
||||
|
||||
// Returns true iff call_count calls will over-saturate this
|
||||
// cardinality, i.e. exceed the maximum number of allowed calls.
|
||||
bool IsOverSaturatedByCallCount(int call_count) const {
|
||||
return impl_->IsSaturatedByCallCount(call_count) &&
|
||||
!impl_->IsSatisfiedByCallCount(call_count);
|
||||
}
|
||||
|
||||
// Describes self to an ostream
|
||||
void DescribeTo(::std::ostream* os) const { impl_->DescribeTo(os); }
|
||||
|
||||
// Describes the given actual call count to an ostream.
|
||||
static void DescribeActualCallCountTo(int actual_call_count,
|
||||
::std::ostream* os);
|
||||
private:
|
||||
internal::linked_ptr<const CardinalityInterface> impl_;
|
||||
};
|
||||
|
||||
// Creates a cardinality that allows at least n calls.
|
||||
Cardinality AtLeast(int n);
|
||||
|
||||
// Creates a cardinality that allows at most n calls.
|
||||
Cardinality AtMost(int n);
|
||||
|
||||
// Creates a cardinality that allows any number of calls.
|
||||
Cardinality AnyNumber();
|
||||
|
||||
// Creates a cardinality that allows between min and max calls.
|
||||
Cardinality Between(int min, int max);
|
||||
|
||||
// Creates a cardinality that allows exactly n calls.
|
||||
Cardinality Exactly(int n);
|
||||
|
||||
// Creates a cardinality from its implementation.
|
||||
inline Cardinality MakeCardinality(const CardinalityInterface* c) {
|
||||
return Cardinality(c);
|
||||
}
|
||||
|
||||
} // namespace testing
|
||||
|
||||
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_
|
||||
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
@@ -0,0 +1,717 @@
|
||||
// This file was GENERATED by a script. DO NOT EDIT BY HAND!!!
|
||||
|
||||
// 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)
|
||||
|
||||
// Google Mock - a framework for writing C++ mock classes.
|
||||
//
|
||||
// This file implements function mockers of various arities.
|
||||
|
||||
#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>
|
||||
|
||||
namespace testing {
|
||||
|
||||
template <typename F>
|
||||
class MockSpec;
|
||||
|
||||
namespace internal {
|
||||
|
||||
template <typename F>
|
||||
class FunctionMockerBase;
|
||||
|
||||
// Note: class FunctionMocker really belongs to the ::testing
|
||||
// namespace. However if we define it in ::testing, MSVC will
|
||||
// complain when classes in ::testing::internal declare it as a
|
||||
// friend class template. To workaround this compiler bug, we define
|
||||
// FunctionMocker in ::testing::internal and import it into ::testing.
|
||||
template <typename F>
|
||||
class FunctionMocker;
|
||||
|
||||
template <typename R>
|
||||
class FunctionMocker<R()> : public
|
||||
internal::FunctionMockerBase<R()> {
|
||||
public:
|
||||
typedef R F();
|
||||
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
|
||||
|
||||
MockSpec<F>& With() {
|
||||
return this->current_spec();
|
||||
}
|
||||
|
||||
R Invoke() {
|
||||
return InvokeWith(ArgumentTuple());
|
||||
}
|
||||
};
|
||||
|
||||
template <typename R, typename A1>
|
||||
class FunctionMocker<R(A1)> : public
|
||||
internal::FunctionMockerBase<R(A1)> {
|
||||
public:
|
||||
typedef R F(A1);
|
||||
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
|
||||
|
||||
MockSpec<F>& With(const Matcher<A1>& m1) {
|
||||
this->current_spec().SetMatchers(::std::tr1::make_tuple(m1));
|
||||
return this->current_spec();
|
||||
}
|
||||
|
||||
R Invoke(A1 a1) {
|
||||
return InvokeWith(ArgumentTuple(a1));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename R, typename A1, typename A2>
|
||||
class FunctionMocker<R(A1, A2)> : public
|
||||
internal::FunctionMockerBase<R(A1, A2)> {
|
||||
public:
|
||||
typedef R F(A1, A2);
|
||||
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
|
||||
|
||||
MockSpec<F>& With(const Matcher<A1>& m1, const Matcher<A2>& m2) {
|
||||
this->current_spec().SetMatchers(::std::tr1::make_tuple(m1, m2));
|
||||
return this->current_spec();
|
||||
}
|
||||
|
||||
R Invoke(A1 a1, A2 a2) {
|
||||
return InvokeWith(ArgumentTuple(a1, a2));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename R, typename A1, typename A2, typename A3>
|
||||
class FunctionMocker<R(A1, A2, A3)> : public
|
||||
internal::FunctionMockerBase<R(A1, A2, A3)> {
|
||||
public:
|
||||
typedef R F(A1, A2, A3);
|
||||
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
|
||||
|
||||
MockSpec<F>& With(const Matcher<A1>& m1, const Matcher<A2>& m2,
|
||||
const Matcher<A3>& m3) {
|
||||
this->current_spec().SetMatchers(::std::tr1::make_tuple(m1, m2, m3));
|
||||
return this->current_spec();
|
||||
}
|
||||
|
||||
R Invoke(A1 a1, A2 a2, A3 a3) {
|
||||
return InvokeWith(ArgumentTuple(a1, a2, a3));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename R, typename A1, typename A2, typename A3, typename A4>
|
||||
class FunctionMocker<R(A1, A2, A3, A4)> : public
|
||||
internal::FunctionMockerBase<R(A1, A2, A3, A4)> {
|
||||
public:
|
||||
typedef R F(A1, A2, A3, A4);
|
||||
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
|
||||
|
||||
MockSpec<F>& With(const Matcher<A1>& m1, const Matcher<A2>& m2,
|
||||
const Matcher<A3>& m3, const Matcher<A4>& m4) {
|
||||
this->current_spec().SetMatchers(::std::tr1::make_tuple(m1, m2, m3, m4));
|
||||
return this->current_spec();
|
||||
}
|
||||
|
||||
R Invoke(A1 a1, A2 a2, A3 a3, A4 a4) {
|
||||
return InvokeWith(ArgumentTuple(a1, a2, a3, a4));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename R, typename A1, typename A2, typename A3, typename A4,
|
||||
typename A5>
|
||||
class FunctionMocker<R(A1, A2, A3, A4, A5)> : public
|
||||
internal::FunctionMockerBase<R(A1, A2, A3, A4, A5)> {
|
||||
public:
|
||||
typedef R F(A1, A2, A3, A4, A5);
|
||||
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
|
||||
|
||||
MockSpec<F>& With(const Matcher<A1>& m1, const Matcher<A2>& m2,
|
||||
const Matcher<A3>& m3, const Matcher<A4>& m4, const Matcher<A5>& m5) {
|
||||
this->current_spec().SetMatchers(::std::tr1::make_tuple(m1, m2, m3, m4,
|
||||
m5));
|
||||
return this->current_spec();
|
||||
}
|
||||
|
||||
R Invoke(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) {
|
||||
return InvokeWith(ArgumentTuple(a1, a2, a3, a4, a5));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename R, typename A1, typename A2, typename A3, typename A4,
|
||||
typename A5, typename A6>
|
||||
class FunctionMocker<R(A1, A2, A3, A4, A5, A6)> : public
|
||||
internal::FunctionMockerBase<R(A1, A2, A3, A4, A5, A6)> {
|
||||
public:
|
||||
typedef R F(A1, A2, A3, A4, A5, A6);
|
||||
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
|
||||
|
||||
MockSpec<F>& With(const Matcher<A1>& m1, const Matcher<A2>& m2,
|
||||
const Matcher<A3>& m3, const Matcher<A4>& m4, const Matcher<A5>& m5,
|
||||
const Matcher<A6>& m6) {
|
||||
this->current_spec().SetMatchers(::std::tr1::make_tuple(m1, m2, m3, m4, m5,
|
||||
m6));
|
||||
return this->current_spec();
|
||||
}
|
||||
|
||||
R Invoke(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) {
|
||||
return InvokeWith(ArgumentTuple(a1, a2, a3, a4, a5, a6));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename R, typename A1, typename A2, typename A3, typename A4,
|
||||
typename A5, typename A6, typename A7>
|
||||
class FunctionMocker<R(A1, A2, A3, A4, A5, A6, A7)> : public
|
||||
internal::FunctionMockerBase<R(A1, A2, A3, A4, A5, A6, A7)> {
|
||||
public:
|
||||
typedef R F(A1, A2, A3, A4, A5, A6, A7);
|
||||
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
|
||||
|
||||
MockSpec<F>& With(const Matcher<A1>& m1, const Matcher<A2>& m2,
|
||||
const Matcher<A3>& m3, const Matcher<A4>& m4, const Matcher<A5>& m5,
|
||||
const Matcher<A6>& m6, const Matcher<A7>& m7) {
|
||||
this->current_spec().SetMatchers(::std::tr1::make_tuple(m1, m2, m3, m4, m5,
|
||||
m6, m7));
|
||||
return this->current_spec();
|
||||
}
|
||||
|
||||
R Invoke(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) {
|
||||
return InvokeWith(ArgumentTuple(a1, a2, a3, a4, a5, a6, a7));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename R, typename A1, typename A2, typename A3, typename A4,
|
||||
typename A5, typename A6, typename A7, typename A8>
|
||||
class FunctionMocker<R(A1, A2, A3, A4, A5, A6, A7, A8)> : public
|
||||
internal::FunctionMockerBase<R(A1, A2, A3, A4, A5, A6, A7, A8)> {
|
||||
public:
|
||||
typedef R F(A1, A2, A3, A4, A5, A6, A7, A8);
|
||||
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
|
||||
|
||||
MockSpec<F>& With(const Matcher<A1>& m1, const Matcher<A2>& m2,
|
||||
const Matcher<A3>& m3, const Matcher<A4>& m4, const Matcher<A5>& m5,
|
||||
const Matcher<A6>& m6, const Matcher<A7>& m7, const Matcher<A8>& m8) {
|
||||
this->current_spec().SetMatchers(::std::tr1::make_tuple(m1, m2, m3, m4, m5,
|
||||
m6, m7, m8));
|
||||
return this->current_spec();
|
||||
}
|
||||
|
||||
R Invoke(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) {
|
||||
return InvokeWith(ArgumentTuple(a1, a2, a3, a4, a5, a6, a7, a8));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename R, typename A1, typename A2, typename A3, typename A4,
|
||||
typename A5, typename A6, typename A7, typename A8, typename A9>
|
||||
class FunctionMocker<R(A1, A2, A3, A4, A5, A6, A7, A8, A9)> : public
|
||||
internal::FunctionMockerBase<R(A1, A2, A3, A4, A5, A6, A7, A8, A9)> {
|
||||
public:
|
||||
typedef R F(A1, A2, A3, A4, A5, A6, A7, A8, A9);
|
||||
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
|
||||
|
||||
MockSpec<F>& With(const Matcher<A1>& m1, const Matcher<A2>& m2,
|
||||
const Matcher<A3>& m3, const Matcher<A4>& m4, const Matcher<A5>& m5,
|
||||
const Matcher<A6>& m6, const Matcher<A7>& m7, const Matcher<A8>& m8,
|
||||
const Matcher<A9>& m9) {
|
||||
this->current_spec().SetMatchers(::std::tr1::make_tuple(m1, m2, m3, m4, m5,
|
||||
m6, m7, m8, m9));
|
||||
return this->current_spec();
|
||||
}
|
||||
|
||||
R Invoke(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) {
|
||||
return InvokeWith(ArgumentTuple(a1, a2, a3, a4, a5, a6, a7, a8, a9));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename R, typename A1, typename A2, typename A3, typename A4,
|
||||
typename A5, typename A6, typename A7, typename A8, typename A9,
|
||||
typename A10>
|
||||
class FunctionMocker<R(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10)> : public
|
||||
internal::FunctionMockerBase<R(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10)> {
|
||||
public:
|
||||
typedef R F(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10);
|
||||
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
|
||||
|
||||
MockSpec<F>& With(const Matcher<A1>& m1, const Matcher<A2>& m2,
|
||||
const Matcher<A3>& m3, const Matcher<A4>& m4, const Matcher<A5>& m5,
|
||||
const Matcher<A6>& m6, const Matcher<A7>& m7, const Matcher<A8>& m8,
|
||||
const Matcher<A9>& m9, const Matcher<A10>& m10) {
|
||||
this->current_spec().SetMatchers(::std::tr1::make_tuple(m1, m2, m3, m4, m5,
|
||||
m6, m7, m8, m9, m10));
|
||||
return this->current_spec();
|
||||
}
|
||||
|
||||
R Invoke(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9,
|
||||
A10 a10) {
|
||||
return InvokeWith(ArgumentTuple(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10));
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
// The style guide prohibits "using" statements in a namespace scope
|
||||
// inside a header file. However, the FunctionMocker class template
|
||||
// is meant to be defined in the ::testing namespace. The following
|
||||
// line is just a trick for working around a bug in MSVC 8.0, which
|
||||
// cannot handle it if we define FunctionMocker in ::testing.
|
||||
using internal::FunctionMocker;
|
||||
|
||||
// The result type of function type F.
|
||||
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
|
||||
#define GMOCK_RESULT_(tn, F) tn ::testing::internal::Function<F>::Result
|
||||
|
||||
// The type of argument N of function type F.
|
||||
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
|
||||
#define GMOCK_ARG_(tn, F, N) tn ::testing::internal::Function<F>::Argument##N
|
||||
|
||||
// The matcher type for argument N of function type F.
|
||||
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
|
||||
#define GMOCK_MATCHER_(tn, F, N) const ::testing::Matcher<GMOCK_ARG_(tn, F, N)>&
|
||||
|
||||
// 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__)
|
||||
|
||||
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
|
||||
#define GMOCK_METHOD0_(tn, constness, ct, Method, F) \
|
||||
GMOCK_RESULT_(tn, F) ct Method() constness { \
|
||||
GMOCK_COMPILE_ASSERT_(::std::tr1::tuple_size< \
|
||||
tn ::testing::internal::Function<F>::ArgumentTuple>::value == 0, \
|
||||
this_method_does_not_take_0_arguments); \
|
||||
GMOCK_MOCKER_(0, constness, Method).SetOwnerAndName(this, #Method); \
|
||||
return GMOCK_MOCKER_(0, constness, Method).Invoke(); \
|
||||
} \
|
||||
::testing::MockSpec<F>& \
|
||||
gmock_##Method() constness { \
|
||||
return GMOCK_MOCKER_(0, constness, Method).RegisterOwner(this).With(); \
|
||||
} \
|
||||
mutable ::testing::FunctionMocker<F> GMOCK_MOCKER_(0, constness, Method)
|
||||
|
||||
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
|
||||
#define GMOCK_METHOD1_(tn, constness, ct, Method, F) \
|
||||
GMOCK_RESULT_(tn, F) ct Method(GMOCK_ARG_(tn, F, 1) gmock_a1) constness { \
|
||||
GMOCK_COMPILE_ASSERT_(::std::tr1::tuple_size< \
|
||||
tn ::testing::internal::Function<F>::ArgumentTuple>::value == 1, \
|
||||
this_method_does_not_take_1_argument); \
|
||||
GMOCK_MOCKER_(1, constness, Method).SetOwnerAndName(this, #Method); \
|
||||
return GMOCK_MOCKER_(1, constness, Method).Invoke(gmock_a1); \
|
||||
} \
|
||||
::testing::MockSpec<F>& \
|
||||
gmock_##Method(GMOCK_MATCHER_(tn, F, 1) gmock_a1) constness { \
|
||||
return GMOCK_MOCKER_(1, constness, \
|
||||
Method).RegisterOwner(this).With(gmock_a1); \
|
||||
} \
|
||||
mutable ::testing::FunctionMocker<F> GMOCK_MOCKER_(1, constness, Method)
|
||||
|
||||
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
|
||||
#define GMOCK_METHOD2_(tn, constness, ct, Method, F) \
|
||||
GMOCK_RESULT_(tn, F) ct Method(GMOCK_ARG_(tn, F, 1) gmock_a1, \
|
||||
GMOCK_ARG_(tn, F, 2) gmock_a2) constness { \
|
||||
GMOCK_COMPILE_ASSERT_(::std::tr1::tuple_size< \
|
||||
tn ::testing::internal::Function<F>::ArgumentTuple>::value == 2, \
|
||||
this_method_does_not_take_2_arguments); \
|
||||
GMOCK_MOCKER_(2, constness, Method).SetOwnerAndName(this, #Method); \
|
||||
return GMOCK_MOCKER_(2, constness, Method).Invoke(gmock_a1, gmock_a2); \
|
||||
} \
|
||||
::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); \
|
||||
} \
|
||||
mutable ::testing::FunctionMocker<F> GMOCK_MOCKER_(2, constness, Method)
|
||||
|
||||
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
|
||||
#define GMOCK_METHOD3_(tn, constness, ct, Method, F) \
|
||||
GMOCK_RESULT_(tn, F) ct Method(GMOCK_ARG_(tn, F, 1) gmock_a1, \
|
||||
GMOCK_ARG_(tn, F, 2) gmock_a2, \
|
||||
GMOCK_ARG_(tn, F, 3) gmock_a3) constness { \
|
||||
GMOCK_COMPILE_ASSERT_(::std::tr1::tuple_size< \
|
||||
tn ::testing::internal::Function<F>::ArgumentTuple>::value == 3, \
|
||||
this_method_does_not_take_3_arguments); \
|
||||
GMOCK_MOCKER_(3, constness, Method).SetOwnerAndName(this, #Method); \
|
||||
return GMOCK_MOCKER_(3, constness, Method).Invoke(gmock_a1, gmock_a2, \
|
||||
gmock_a3); \
|
||||
} \
|
||||
::testing::MockSpec<F>& \
|
||||
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); \
|
||||
} \
|
||||
mutable ::testing::FunctionMocker<F> GMOCK_MOCKER_(3, constness, Method)
|
||||
|
||||
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
|
||||
#define GMOCK_METHOD4_(tn, constness, ct, Method, F) \
|
||||
GMOCK_RESULT_(tn, F) ct Method(GMOCK_ARG_(tn, F, 1) gmock_a1, \
|
||||
GMOCK_ARG_(tn, F, 2) gmock_a2, \
|
||||
GMOCK_ARG_(tn, F, 3) gmock_a3, \
|
||||
GMOCK_ARG_(tn, F, 4) gmock_a4) constness { \
|
||||
GMOCK_COMPILE_ASSERT_(::std::tr1::tuple_size< \
|
||||
tn ::testing::internal::Function<F>::ArgumentTuple>::value == 4, \
|
||||
this_method_does_not_take_4_arguments); \
|
||||
GMOCK_MOCKER_(4, constness, Method).SetOwnerAndName(this, #Method); \
|
||||
return GMOCK_MOCKER_(4, constness, Method).Invoke(gmock_a1, gmock_a2, \
|
||||
gmock_a3, gmock_a4); \
|
||||
} \
|
||||
::testing::MockSpec<F>& \
|
||||
gmock_##Method(GMOCK_MATCHER_(tn, F, 1) gmock_a1, \
|
||||
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); \
|
||||
} \
|
||||
mutable ::testing::FunctionMocker<F> GMOCK_MOCKER_(4, constness, Method)
|
||||
|
||||
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
|
||||
#define GMOCK_METHOD5_(tn, constness, ct, Method, F) \
|
||||
GMOCK_RESULT_(tn, F) ct Method(GMOCK_ARG_(tn, F, 1) gmock_a1, \
|
||||
GMOCK_ARG_(tn, F, 2) gmock_a2, \
|
||||
GMOCK_ARG_(tn, F, 3) gmock_a3, \
|
||||
GMOCK_ARG_(tn, F, 4) gmock_a4, \
|
||||
GMOCK_ARG_(tn, F, 5) gmock_a5) constness { \
|
||||
GMOCK_COMPILE_ASSERT_(::std::tr1::tuple_size< \
|
||||
tn ::testing::internal::Function<F>::ArgumentTuple>::value == 5, \
|
||||
this_method_does_not_take_5_arguments); \
|
||||
GMOCK_MOCKER_(5, constness, Method).SetOwnerAndName(this, #Method); \
|
||||
return GMOCK_MOCKER_(5, constness, Method).Invoke(gmock_a1, gmock_a2, \
|
||||
gmock_a3, gmock_a4, gmock_a5); \
|
||||
} \
|
||||
::testing::MockSpec<F>& \
|
||||
gmock_##Method(GMOCK_MATCHER_(tn, F, 1) gmock_a1, \
|
||||
GMOCK_MATCHER_(tn, F, 2) gmock_a2, \
|
||||
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); \
|
||||
} \
|
||||
mutable ::testing::FunctionMocker<F> GMOCK_MOCKER_(5, constness, Method)
|
||||
|
||||
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
|
||||
#define GMOCK_METHOD6_(tn, constness, ct, Method, F) \
|
||||
GMOCK_RESULT_(tn, F) ct Method(GMOCK_ARG_(tn, F, 1) gmock_a1, \
|
||||
GMOCK_ARG_(tn, F, 2) gmock_a2, \
|
||||
GMOCK_ARG_(tn, F, 3) gmock_a3, \
|
||||
GMOCK_ARG_(tn, F, 4) gmock_a4, \
|
||||
GMOCK_ARG_(tn, F, 5) gmock_a5, \
|
||||
GMOCK_ARG_(tn, F, 6) gmock_a6) constness { \
|
||||
GMOCK_COMPILE_ASSERT_(::std::tr1::tuple_size< \
|
||||
tn ::testing::internal::Function<F>::ArgumentTuple>::value == 6, \
|
||||
this_method_does_not_take_6_arguments); \
|
||||
GMOCK_MOCKER_(6, constness, Method).SetOwnerAndName(this, #Method); \
|
||||
return GMOCK_MOCKER_(6, constness, Method).Invoke(gmock_a1, gmock_a2, \
|
||||
gmock_a3, gmock_a4, gmock_a5, gmock_a6); \
|
||||
} \
|
||||
::testing::MockSpec<F>& \
|
||||
gmock_##Method(GMOCK_MATCHER_(tn, F, 1) gmock_a1, \
|
||||
GMOCK_MATCHER_(tn, F, 2) gmock_a2, \
|
||||
GMOCK_MATCHER_(tn, F, 3) gmock_a3, \
|
||||
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); \
|
||||
} \
|
||||
mutable ::testing::FunctionMocker<F> GMOCK_MOCKER_(6, constness, Method)
|
||||
|
||||
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
|
||||
#define GMOCK_METHOD7_(tn, constness, ct, Method, F) \
|
||||
GMOCK_RESULT_(tn, F) ct Method(GMOCK_ARG_(tn, F, 1) gmock_a1, \
|
||||
GMOCK_ARG_(tn, F, 2) gmock_a2, \
|
||||
GMOCK_ARG_(tn, F, 3) gmock_a3, \
|
||||
GMOCK_ARG_(tn, F, 4) gmock_a4, \
|
||||
GMOCK_ARG_(tn, F, 5) gmock_a5, \
|
||||
GMOCK_ARG_(tn, F, 6) gmock_a6, \
|
||||
GMOCK_ARG_(tn, F, 7) gmock_a7) constness { \
|
||||
GMOCK_COMPILE_ASSERT_(::std::tr1::tuple_size< \
|
||||
tn ::testing::internal::Function<F>::ArgumentTuple>::value == 7, \
|
||||
this_method_does_not_take_7_arguments); \
|
||||
GMOCK_MOCKER_(7, constness, Method).SetOwnerAndName(this, #Method); \
|
||||
return GMOCK_MOCKER_(7, constness, Method).Invoke(gmock_a1, gmock_a2, \
|
||||
gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7); \
|
||||
} \
|
||||
::testing::MockSpec<F>& \
|
||||
gmock_##Method(GMOCK_MATCHER_(tn, F, 1) gmock_a1, \
|
||||
GMOCK_MATCHER_(tn, F, 2) gmock_a2, \
|
||||
GMOCK_MATCHER_(tn, F, 3) gmock_a3, \
|
||||
GMOCK_MATCHER_(tn, F, 4) gmock_a4, \
|
||||
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); \
|
||||
} \
|
||||
mutable ::testing::FunctionMocker<F> GMOCK_MOCKER_(7, constness, Method)
|
||||
|
||||
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
|
||||
#define GMOCK_METHOD8_(tn, constness, ct, Method, F) \
|
||||
GMOCK_RESULT_(tn, F) ct Method(GMOCK_ARG_(tn, F, 1) gmock_a1, \
|
||||
GMOCK_ARG_(tn, F, 2) gmock_a2, \
|
||||
GMOCK_ARG_(tn, F, 3) gmock_a3, \
|
||||
GMOCK_ARG_(tn, F, 4) gmock_a4, \
|
||||
GMOCK_ARG_(tn, F, 5) gmock_a5, \
|
||||
GMOCK_ARG_(tn, F, 6) gmock_a6, \
|
||||
GMOCK_ARG_(tn, F, 7) gmock_a7, \
|
||||
GMOCK_ARG_(tn, F, 8) gmock_a8) constness { \
|
||||
GMOCK_COMPILE_ASSERT_(::std::tr1::tuple_size< \
|
||||
tn ::testing::internal::Function<F>::ArgumentTuple>::value == 8, \
|
||||
this_method_does_not_take_8_arguments); \
|
||||
GMOCK_MOCKER_(8, constness, Method).SetOwnerAndName(this, #Method); \
|
||||
return GMOCK_MOCKER_(8, constness, Method).Invoke(gmock_a1, gmock_a2, \
|
||||
gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8); \
|
||||
} \
|
||||
::testing::MockSpec<F>& \
|
||||
gmock_##Method(GMOCK_MATCHER_(tn, F, 1) gmock_a1, \
|
||||
GMOCK_MATCHER_(tn, F, 2) gmock_a2, \
|
||||
GMOCK_MATCHER_(tn, F, 3) gmock_a3, \
|
||||
GMOCK_MATCHER_(tn, F, 4) gmock_a4, \
|
||||
GMOCK_MATCHER_(tn, F, 5) gmock_a5, \
|
||||
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); \
|
||||
} \
|
||||
mutable ::testing::FunctionMocker<F> GMOCK_MOCKER_(8, constness, Method)
|
||||
|
||||
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
|
||||
#define GMOCK_METHOD9_(tn, constness, ct, Method, F) \
|
||||
GMOCK_RESULT_(tn, F) ct Method(GMOCK_ARG_(tn, F, 1) gmock_a1, \
|
||||
GMOCK_ARG_(tn, F, 2) gmock_a2, \
|
||||
GMOCK_ARG_(tn, F, 3) gmock_a3, \
|
||||
GMOCK_ARG_(tn, F, 4) gmock_a4, \
|
||||
GMOCK_ARG_(tn, F, 5) gmock_a5, \
|
||||
GMOCK_ARG_(tn, F, 6) gmock_a6, \
|
||||
GMOCK_ARG_(tn, F, 7) gmock_a7, \
|
||||
GMOCK_ARG_(tn, F, 8) gmock_a8, \
|
||||
GMOCK_ARG_(tn, F, 9) gmock_a9) constness { \
|
||||
GMOCK_COMPILE_ASSERT_(::std::tr1::tuple_size< \
|
||||
tn ::testing::internal::Function<F>::ArgumentTuple>::value == 9, \
|
||||
this_method_does_not_take_9_arguments); \
|
||||
GMOCK_MOCKER_(9, constness, Method).SetOwnerAndName(this, #Method); \
|
||||
return GMOCK_MOCKER_(9, constness, Method).Invoke(gmock_a1, gmock_a2, \
|
||||
gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8, \
|
||||
gmock_a9); \
|
||||
} \
|
||||
::testing::MockSpec<F>& \
|
||||
gmock_##Method(GMOCK_MATCHER_(tn, F, 1) gmock_a1, \
|
||||
GMOCK_MATCHER_(tn, F, 2) gmock_a2, \
|
||||
GMOCK_MATCHER_(tn, F, 3) gmock_a3, \
|
||||
GMOCK_MATCHER_(tn, F, 4) gmock_a4, \
|
||||
GMOCK_MATCHER_(tn, F, 5) gmock_a5, \
|
||||
GMOCK_MATCHER_(tn, F, 6) gmock_a6, \
|
||||
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); \
|
||||
} \
|
||||
mutable ::testing::FunctionMocker<F> GMOCK_MOCKER_(9, constness, Method)
|
||||
|
||||
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
|
||||
#define GMOCK_METHOD10_(tn, constness, ct, Method, F) \
|
||||
GMOCK_RESULT_(tn, F) ct Method(GMOCK_ARG_(tn, F, 1) gmock_a1, \
|
||||
GMOCK_ARG_(tn, F, 2) gmock_a2, \
|
||||
GMOCK_ARG_(tn, F, 3) gmock_a3, \
|
||||
GMOCK_ARG_(tn, F, 4) gmock_a4, \
|
||||
GMOCK_ARG_(tn, F, 5) gmock_a5, \
|
||||
GMOCK_ARG_(tn, F, 6) gmock_a6, \
|
||||
GMOCK_ARG_(tn, F, 7) gmock_a7, \
|
||||
GMOCK_ARG_(tn, F, 8) gmock_a8, \
|
||||
GMOCK_ARG_(tn, F, 9) gmock_a9, \
|
||||
GMOCK_ARG_(tn, F, 10) gmock_a10) constness { \
|
||||
GMOCK_COMPILE_ASSERT_(::std::tr1::tuple_size< \
|
||||
tn ::testing::internal::Function<F>::ArgumentTuple>::value == 10, \
|
||||
this_method_does_not_take_10_arguments); \
|
||||
GMOCK_MOCKER_(10, constness, Method).SetOwnerAndName(this, #Method); \
|
||||
return GMOCK_MOCKER_(10, constness, Method).Invoke(gmock_a1, gmock_a2, \
|
||||
gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8, gmock_a9, \
|
||||
gmock_a10); \
|
||||
} \
|
||||
::testing::MockSpec<F>& \
|
||||
gmock_##Method(GMOCK_MATCHER_(tn, F, 1) gmock_a1, \
|
||||
GMOCK_MATCHER_(tn, F, 2) gmock_a2, \
|
||||
GMOCK_MATCHER_(tn, F, 3) gmock_a3, \
|
||||
GMOCK_MATCHER_(tn, F, 4) gmock_a4, \
|
||||
GMOCK_MATCHER_(tn, F, 5) gmock_a5, \
|
||||
GMOCK_MATCHER_(tn, F, 6) gmock_a6, \
|
||||
GMOCK_MATCHER_(tn, F, 7) gmock_a7, \
|
||||
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_a10); \
|
||||
} \
|
||||
mutable ::testing::FunctionMocker<F> GMOCK_MOCKER_(10, constness, Method)
|
||||
|
||||
#define MOCK_METHOD0(m, F) GMOCK_METHOD0_(, , , m, F)
|
||||
#define MOCK_METHOD1(m, F) GMOCK_METHOD1_(, , , m, F)
|
||||
#define MOCK_METHOD2(m, F) GMOCK_METHOD2_(, , , m, F)
|
||||
#define MOCK_METHOD3(m, F) GMOCK_METHOD3_(, , , m, F)
|
||||
#define MOCK_METHOD4(m, F) GMOCK_METHOD4_(, , , m, F)
|
||||
#define MOCK_METHOD5(m, F) GMOCK_METHOD5_(, , , m, F)
|
||||
#define MOCK_METHOD6(m, F) GMOCK_METHOD6_(, , , m, F)
|
||||
#define MOCK_METHOD7(m, F) GMOCK_METHOD7_(, , , m, F)
|
||||
#define MOCK_METHOD8(m, F) GMOCK_METHOD8_(, , , m, F)
|
||||
#define MOCK_METHOD9(m, F) GMOCK_METHOD9_(, , , m, F)
|
||||
#define MOCK_METHOD10(m, F) GMOCK_METHOD10_(, , , m, F)
|
||||
|
||||
#define MOCK_CONST_METHOD0(m, F) GMOCK_METHOD0_(, const, , m, F)
|
||||
#define MOCK_CONST_METHOD1(m, F) GMOCK_METHOD1_(, const, , m, F)
|
||||
#define MOCK_CONST_METHOD2(m, F) GMOCK_METHOD2_(, const, , m, F)
|
||||
#define MOCK_CONST_METHOD3(m, F) GMOCK_METHOD3_(, const, , m, F)
|
||||
#define MOCK_CONST_METHOD4(m, F) GMOCK_METHOD4_(, const, , m, F)
|
||||
#define MOCK_CONST_METHOD5(m, F) GMOCK_METHOD5_(, const, , m, F)
|
||||
#define MOCK_CONST_METHOD6(m, F) GMOCK_METHOD6_(, const, , m, F)
|
||||
#define MOCK_CONST_METHOD7(m, F) GMOCK_METHOD7_(, const, , m, F)
|
||||
#define MOCK_CONST_METHOD8(m, F) GMOCK_METHOD8_(, const, , m, F)
|
||||
#define MOCK_CONST_METHOD9(m, F) GMOCK_METHOD9_(, const, , m, F)
|
||||
#define MOCK_CONST_METHOD10(m, F) GMOCK_METHOD10_(, const, , m, F)
|
||||
|
||||
#define MOCK_METHOD0_T(m, F) GMOCK_METHOD0_(typename, , , m, F)
|
||||
#define MOCK_METHOD1_T(m, F) GMOCK_METHOD1_(typename, , , m, F)
|
||||
#define MOCK_METHOD2_T(m, F) GMOCK_METHOD2_(typename, , , m, F)
|
||||
#define MOCK_METHOD3_T(m, F) GMOCK_METHOD3_(typename, , , m, F)
|
||||
#define MOCK_METHOD4_T(m, F) GMOCK_METHOD4_(typename, , , m, F)
|
||||
#define MOCK_METHOD5_T(m, F) GMOCK_METHOD5_(typename, , , m, F)
|
||||
#define MOCK_METHOD6_T(m, F) GMOCK_METHOD6_(typename, , , m, F)
|
||||
#define MOCK_METHOD7_T(m, F) GMOCK_METHOD7_(typename, , , m, F)
|
||||
#define MOCK_METHOD8_T(m, F) GMOCK_METHOD8_(typename, , , m, F)
|
||||
#define MOCK_METHOD9_T(m, F) GMOCK_METHOD9_(typename, , , m, F)
|
||||
#define MOCK_METHOD10_T(m, F) GMOCK_METHOD10_(typename, , , m, F)
|
||||
|
||||
#define MOCK_CONST_METHOD0_T(m, F) GMOCK_METHOD0_(typename, const, , m, F)
|
||||
#define MOCK_CONST_METHOD1_T(m, F) GMOCK_METHOD1_(typename, const, , m, F)
|
||||
#define MOCK_CONST_METHOD2_T(m, F) GMOCK_METHOD2_(typename, const, , m, F)
|
||||
#define MOCK_CONST_METHOD3_T(m, F) GMOCK_METHOD3_(typename, const, , m, F)
|
||||
#define MOCK_CONST_METHOD4_T(m, F) GMOCK_METHOD4_(typename, const, , m, F)
|
||||
#define MOCK_CONST_METHOD5_T(m, F) GMOCK_METHOD5_(typename, const, , m, F)
|
||||
#define MOCK_CONST_METHOD6_T(m, F) GMOCK_METHOD6_(typename, const, , m, F)
|
||||
#define MOCK_CONST_METHOD7_T(m, F) GMOCK_METHOD7_(typename, const, , m, F)
|
||||
#define MOCK_CONST_METHOD8_T(m, F) GMOCK_METHOD8_(typename, const, , m, F)
|
||||
#define MOCK_CONST_METHOD9_T(m, F) GMOCK_METHOD9_(typename, const, , m, F)
|
||||
#define MOCK_CONST_METHOD10_T(m, F) GMOCK_METHOD10_(typename, const, , m, F)
|
||||
|
||||
#define MOCK_METHOD0_WITH_CALLTYPE(ct, m, F) GMOCK_METHOD0_(, , ct, m, F)
|
||||
#define MOCK_METHOD1_WITH_CALLTYPE(ct, m, F) GMOCK_METHOD1_(, , ct, m, F)
|
||||
#define MOCK_METHOD2_WITH_CALLTYPE(ct, m, F) GMOCK_METHOD2_(, , ct, m, F)
|
||||
#define MOCK_METHOD3_WITH_CALLTYPE(ct, m, F) GMOCK_METHOD3_(, , ct, m, F)
|
||||
#define MOCK_METHOD4_WITH_CALLTYPE(ct, m, F) GMOCK_METHOD4_(, , ct, m, F)
|
||||
#define MOCK_METHOD5_WITH_CALLTYPE(ct, m, F) GMOCK_METHOD5_(, , ct, m, F)
|
||||
#define MOCK_METHOD6_WITH_CALLTYPE(ct, m, F) GMOCK_METHOD6_(, , ct, m, F)
|
||||
#define MOCK_METHOD7_WITH_CALLTYPE(ct, m, F) GMOCK_METHOD7_(, , ct, m, F)
|
||||
#define MOCK_METHOD8_WITH_CALLTYPE(ct, m, F) GMOCK_METHOD8_(, , ct, m, F)
|
||||
#define MOCK_METHOD9_WITH_CALLTYPE(ct, m, F) GMOCK_METHOD9_(, , ct, m, F)
|
||||
#define MOCK_METHOD10_WITH_CALLTYPE(ct, m, F) GMOCK_METHOD10_(, , ct, m, F)
|
||||
|
||||
#define MOCK_CONST_METHOD0_WITH_CALLTYPE(ct, m, F) \
|
||||
GMOCK_METHOD0_(, const, ct, m, F)
|
||||
#define MOCK_CONST_METHOD1_WITH_CALLTYPE(ct, m, F) \
|
||||
GMOCK_METHOD1_(, const, ct, m, F)
|
||||
#define MOCK_CONST_METHOD2_WITH_CALLTYPE(ct, m, F) \
|
||||
GMOCK_METHOD2_(, const, ct, m, F)
|
||||
#define MOCK_CONST_METHOD3_WITH_CALLTYPE(ct, m, F) \
|
||||
GMOCK_METHOD3_(, const, ct, m, F)
|
||||
#define MOCK_CONST_METHOD4_WITH_CALLTYPE(ct, m, F) \
|
||||
GMOCK_METHOD4_(, const, ct, m, F)
|
||||
#define MOCK_CONST_METHOD5_WITH_CALLTYPE(ct, m, F) \
|
||||
GMOCK_METHOD5_(, const, ct, m, F)
|
||||
#define MOCK_CONST_METHOD6_WITH_CALLTYPE(ct, m, F) \
|
||||
GMOCK_METHOD6_(, const, ct, m, F)
|
||||
#define MOCK_CONST_METHOD7_WITH_CALLTYPE(ct, m, F) \
|
||||
GMOCK_METHOD7_(, const, ct, m, F)
|
||||
#define MOCK_CONST_METHOD8_WITH_CALLTYPE(ct, m, F) \
|
||||
GMOCK_METHOD8_(, const, ct, m, F)
|
||||
#define MOCK_CONST_METHOD9_WITH_CALLTYPE(ct, m, F) \
|
||||
GMOCK_METHOD9_(, const, ct, m, F)
|
||||
#define MOCK_CONST_METHOD10_WITH_CALLTYPE(ct, m, F) \
|
||||
GMOCK_METHOD10_(, const, ct, m, F)
|
||||
|
||||
#define MOCK_METHOD0_T_WITH_CALLTYPE(ct, m, F) \
|
||||
GMOCK_METHOD0_(typename, , ct, m, F)
|
||||
#define MOCK_METHOD1_T_WITH_CALLTYPE(ct, m, F) \
|
||||
GMOCK_METHOD1_(typename, , ct, m, F)
|
||||
#define MOCK_METHOD2_T_WITH_CALLTYPE(ct, m, F) \
|
||||
GMOCK_METHOD2_(typename, , ct, m, F)
|
||||
#define MOCK_METHOD3_T_WITH_CALLTYPE(ct, m, F) \
|
||||
GMOCK_METHOD3_(typename, , ct, m, F)
|
||||
#define MOCK_METHOD4_T_WITH_CALLTYPE(ct, m, F) \
|
||||
GMOCK_METHOD4_(typename, , ct, m, F)
|
||||
#define MOCK_METHOD5_T_WITH_CALLTYPE(ct, m, F) \
|
||||
GMOCK_METHOD5_(typename, , ct, m, F)
|
||||
#define MOCK_METHOD6_T_WITH_CALLTYPE(ct, m, F) \
|
||||
GMOCK_METHOD6_(typename, , ct, m, F)
|
||||
#define MOCK_METHOD7_T_WITH_CALLTYPE(ct, m, F) \
|
||||
GMOCK_METHOD7_(typename, , ct, m, F)
|
||||
#define MOCK_METHOD8_T_WITH_CALLTYPE(ct, m, F) \
|
||||
GMOCK_METHOD8_(typename, , ct, m, F)
|
||||
#define MOCK_METHOD9_T_WITH_CALLTYPE(ct, m, F) \
|
||||
GMOCK_METHOD9_(typename, , ct, m, F)
|
||||
#define MOCK_METHOD10_T_WITH_CALLTYPE(ct, m, F) \
|
||||
GMOCK_METHOD10_(typename, , ct, m, F)
|
||||
|
||||
#define MOCK_CONST_METHOD0_T_WITH_CALLTYPE(ct, m, F) \
|
||||
GMOCK_METHOD0_(typename, const, ct, m, F)
|
||||
#define MOCK_CONST_METHOD1_T_WITH_CALLTYPE(ct, m, F) \
|
||||
GMOCK_METHOD1_(typename, const, ct, m, F)
|
||||
#define MOCK_CONST_METHOD2_T_WITH_CALLTYPE(ct, m, F) \
|
||||
GMOCK_METHOD2_(typename, const, ct, m, F)
|
||||
#define MOCK_CONST_METHOD3_T_WITH_CALLTYPE(ct, m, F) \
|
||||
GMOCK_METHOD3_(typename, const, ct, m, F)
|
||||
#define MOCK_CONST_METHOD4_T_WITH_CALLTYPE(ct, m, F) \
|
||||
GMOCK_METHOD4_(typename, const, ct, m, F)
|
||||
#define MOCK_CONST_METHOD5_T_WITH_CALLTYPE(ct, m, F) \
|
||||
GMOCK_METHOD5_(typename, const, ct, m, F)
|
||||
#define MOCK_CONST_METHOD6_T_WITH_CALLTYPE(ct, m, F) \
|
||||
GMOCK_METHOD6_(typename, const, ct, m, F)
|
||||
#define MOCK_CONST_METHOD7_T_WITH_CALLTYPE(ct, m, F) \
|
||||
GMOCK_METHOD7_(typename, const, ct, m, F)
|
||||
#define MOCK_CONST_METHOD8_T_WITH_CALLTYPE(ct, m, F) \
|
||||
GMOCK_METHOD8_(typename, const, ct, m, F)
|
||||
#define MOCK_CONST_METHOD9_T_WITH_CALLTYPE(ct, m, F) \
|
||||
GMOCK_METHOD9_(typename, const, ct, m, F)
|
||||
#define MOCK_CONST_METHOD10_T_WITH_CALLTYPE(ct, m, F) \
|
||||
GMOCK_METHOD10_(typename, const, ct, m, F)
|
||||
|
||||
} // namespace testing
|
||||
|
||||
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_
|
||||
@@ -0,0 +1,203 @@
|
||||
$$ -*- mode: c++; -*-
|
||||
$$ This is a Pump source file. Please use Pump to convert it to
|
||||
$$ gmock-generated-function-mockers.h.
|
||||
$$
|
||||
$var n = 10 $$ The maximum arity we support.
|
||||
// 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)
|
||||
|
||||
// Google Mock - a framework for writing C++ mock classes.
|
||||
//
|
||||
// This file implements function mockers of various arities.
|
||||
|
||||
#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>
|
||||
|
||||
namespace testing {
|
||||
|
||||
template <typename F>
|
||||
class MockSpec;
|
||||
|
||||
namespace internal {
|
||||
|
||||
template <typename F>
|
||||
class FunctionMockerBase;
|
||||
|
||||
// Note: class FunctionMocker really belongs to the ::testing
|
||||
// namespace. However if we define it in ::testing, MSVC will
|
||||
// complain when classes in ::testing::internal declare it as a
|
||||
// friend class template. To workaround this compiler bug, we define
|
||||
// FunctionMocker in ::testing::internal and import it into ::testing.
|
||||
template <typename F>
|
||||
class FunctionMocker;
|
||||
|
||||
|
||||
$range i 0..n
|
||||
$for i [[
|
||||
$range j 1..i
|
||||
$var typename_As = [[$for j [[, typename A$j]]]]
|
||||
$var As = [[$for j, [[A$j]]]]
|
||||
$var as = [[$for j, [[a$j]]]]
|
||||
$var Aas = [[$for j, [[A$j a$j]]]]
|
||||
$var ms = [[$for j, [[m$j]]]]
|
||||
$var matchers = [[$for j, [[const Matcher<A$j>& m$j]]]]
|
||||
template <typename R$typename_As>
|
||||
class FunctionMocker<R($As)> : public
|
||||
internal::FunctionMockerBase<R($As)> {
|
||||
public:
|
||||
typedef R F($As);
|
||||
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
|
||||
|
||||
MockSpec<F>& With($matchers) {
|
||||
|
||||
$if i >= 1 [[
|
||||
this->current_spec().SetMatchers(::std::tr1::make_tuple($ms));
|
||||
|
||||
]]
|
||||
return this->current_spec();
|
||||
}
|
||||
|
||||
R Invoke($Aas) {
|
||||
return InvokeWith(ArgumentTuple($as));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
]]
|
||||
} // namespace internal
|
||||
|
||||
// The style guide prohibits "using" statements in a namespace scope
|
||||
// inside a header file. However, the FunctionMocker class template
|
||||
// is meant to be defined in the ::testing namespace. The following
|
||||
// line is just a trick for working around a bug in MSVC 8.0, which
|
||||
// cannot handle it if we define FunctionMocker in ::testing.
|
||||
using internal::FunctionMocker;
|
||||
|
||||
// The result type of function type F.
|
||||
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
|
||||
#define GMOCK_RESULT_(tn, F) tn ::testing::internal::Function<F>::Result
|
||||
|
||||
// The type of argument N of function type F.
|
||||
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
|
||||
#define GMOCK_ARG_(tn, F, N) tn ::testing::internal::Function<F>::Argument##N
|
||||
|
||||
// The matcher type for argument N of function type F.
|
||||
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
|
||||
#define GMOCK_MATCHER_(tn, F, N) const ::testing::Matcher<GMOCK_ARG_(tn, F, N)>&
|
||||
|
||||
// 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__)
|
||||
|
||||
|
||||
$for i [[
|
||||
$range j 1..i
|
||||
$var arg_as = [[$for j, \
|
||||
[[GMOCK_ARG_(tn, F, $j) gmock_a$j]]]]
|
||||
$var as = [[$for j, [[gmock_a$j]]]]
|
||||
$var matcher_as = [[$for j, \
|
||||
[[GMOCK_MATCHER_(tn, F, $j) gmock_a$j]]]]
|
||||
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
|
||||
#define GMOCK_METHOD$i[[]]_(tn, constness, ct, Method, F) \
|
||||
GMOCK_RESULT_(tn, F) ct Method($arg_as) constness { \
|
||||
GMOCK_COMPILE_ASSERT_(::std::tr1::tuple_size< \
|
||||
tn ::testing::internal::Function<F>::ArgumentTuple>::value == $i, \
|
||||
this_method_does_not_take_$i[[]]_argument[[$if i != 1 [[s]]]]); \
|
||||
GMOCK_MOCKER_($i, constness, Method).SetOwnerAndName(this, #Method); \
|
||||
return GMOCK_MOCKER_($i, constness, Method).Invoke($as); \
|
||||
} \
|
||||
::testing::MockSpec<F>& \
|
||||
gmock_##Method($matcher_as) constness { \
|
||||
return GMOCK_MOCKER_($i, constness, Method).RegisterOwner(this).With($as); \
|
||||
} \
|
||||
mutable ::testing::FunctionMocker<F> GMOCK_MOCKER_($i, constness, Method)
|
||||
|
||||
|
||||
]]
|
||||
$for i [[
|
||||
#define MOCK_METHOD$i(m, F) GMOCK_METHOD$i[[]]_(, , , m, F)
|
||||
|
||||
]]
|
||||
|
||||
|
||||
$for i [[
|
||||
#define MOCK_CONST_METHOD$i(m, F) GMOCK_METHOD$i[[]]_(, const, , m, F)
|
||||
|
||||
]]
|
||||
|
||||
|
||||
$for i [[
|
||||
#define MOCK_METHOD$i[[]]_T(m, F) GMOCK_METHOD$i[[]]_(typename, , , m, F)
|
||||
|
||||
]]
|
||||
|
||||
|
||||
$for i [[
|
||||
#define MOCK_CONST_METHOD$i[[]]_T(m, F) [[]]
|
||||
GMOCK_METHOD$i[[]]_(typename, const, , m, F)
|
||||
|
||||
]]
|
||||
|
||||
|
||||
$for i [[
|
||||
#define MOCK_METHOD$i[[]]_WITH_CALLTYPE(ct, m, F) [[]]
|
||||
GMOCK_METHOD$i[[]]_(, , ct, m, F)
|
||||
|
||||
]]
|
||||
|
||||
|
||||
$for i [[
|
||||
#define MOCK_CONST_METHOD$i[[]]_WITH_CALLTYPE(ct, m, F) \
|
||||
GMOCK_METHOD$i[[]]_(, const, ct, m, F)
|
||||
|
||||
]]
|
||||
|
||||
|
||||
$for i [[
|
||||
#define MOCK_METHOD$i[[]]_T_WITH_CALLTYPE(ct, m, F) \
|
||||
GMOCK_METHOD$i[[]]_(typename, , ct, m, F)
|
||||
|
||||
]]
|
||||
|
||||
|
||||
$for i [[
|
||||
#define MOCK_CONST_METHOD$i[[]]_T_WITH_CALLTYPE(ct, m, F) \
|
||||
GMOCK_METHOD$i[[]]_(typename, const, ct, m, F)
|
||||
|
||||
]]
|
||||
|
||||
} // namespace testing
|
||||
|
||||
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_
|
||||
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
@@ -0,0 +1,634 @@
|
||||
$$ -*- mode: c++; -*-
|
||||
$$ This is a Pump source file. Please use Pump to convert it to
|
||||
$$ gmock-generated-variadic-actions.h.
|
||||
$$
|
||||
$var n = 10 $$ The maximum arity we support.
|
||||
// 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.
|
||||
|
||||
// Google Mock - a framework for writing C++ mock classes.
|
||||
//
|
||||
// This file implements some commonly used variadic matchers.
|
||||
|
||||
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_
|
||||
#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_
|
||||
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <gmock/gmock-matchers.h>
|
||||
#include <gmock/gmock-printers.h>
|
||||
|
||||
namespace testing {
|
||||
namespace internal {
|
||||
|
||||
// Implements ElementsAre() and ElementsAreArray().
|
||||
template <typename Container>
|
||||
class ElementsAreMatcherImpl : public MatcherInterface<Container> {
|
||||
public:
|
||||
typedef GMOCK_REMOVE_CONST_(GMOCK_REMOVE_REFERENCE_(Container)) RawContainer;
|
||||
typedef typename RawContainer::value_type Element;
|
||||
|
||||
// Constructs the matcher from a sequence of element values or
|
||||
// element matchers.
|
||||
template <typename InputIter>
|
||||
ElementsAreMatcherImpl(InputIter first, size_t count) {
|
||||
matchers_.reserve(count);
|
||||
InputIter it = first;
|
||||
for (size_t i = 0; i != count; ++i, ++it) {
|
||||
matchers_.push_back(MatcherCast<const Element&>(*it));
|
||||
}
|
||||
}
|
||||
|
||||
// Returns true iff 'container' matches.
|
||||
virtual bool Matches(Container container) const {
|
||||
if (container.size() != count())
|
||||
return false;
|
||||
|
||||
typename RawContainer::const_iterator container_iter = container.begin();
|
||||
for (size_t i = 0; i != count(); ++container_iter, ++i) {
|
||||
if (!matchers_[i].Matches(*container_iter))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Describes what this matcher does.
|
||||
virtual void DescribeTo(::std::ostream* os) const {
|
||||
if (count() == 0) {
|
||||
*os << "is empty";
|
||||
} else if (count() == 1) {
|
||||
*os << "has 1 element that ";
|
||||
matchers_[0].DescribeTo(os);
|
||||
} else {
|
||||
*os << "has " << Elements(count()) << " where\n";
|
||||
for (size_t i = 0; i != count(); ++i) {
|
||||
*os << "element " << i << " ";
|
||||
matchers_[i].DescribeTo(os);
|
||||
if (i + 1 < count()) {
|
||||
*os << ",\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Describes what the negation of this matcher does.
|
||||
virtual void DescribeNegationTo(::std::ostream* os) const {
|
||||
if (count() == 0) {
|
||||
*os << "is not empty";
|
||||
return;
|
||||
}
|
||||
|
||||
*os << "does not have " << Elements(count()) << ", or\n";
|
||||
for (size_t i = 0; i != count(); ++i) {
|
||||
*os << "element " << i << " ";
|
||||
matchers_[i].DescribeNegationTo(os);
|
||||
if (i + 1 < count()) {
|
||||
*os << ", or\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Explains why 'container' matches, or doesn't match, this matcher.
|
||||
virtual void ExplainMatchResultTo(Container container,
|
||||
::std::ostream* os) const {
|
||||
if (Matches(container)) {
|
||||
// We need to explain why *each* element matches (the obvious
|
||||
// ones can be skipped).
|
||||
|
||||
bool reason_printed = false;
|
||||
typename RawContainer::const_iterator container_iter = container.begin();
|
||||
for (size_t i = 0; i != count(); ++container_iter, ++i) {
|
||||
::std::stringstream ss;
|
||||
matchers_[i].ExplainMatchResultTo(*container_iter, &ss);
|
||||
|
||||
const string s = ss.str();
|
||||
if (!s.empty()) {
|
||||
if (reason_printed) {
|
||||
*os << ",\n";
|
||||
}
|
||||
*os << "element " << i << " " << s;
|
||||
reason_printed = true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// We need to explain why the container doesn't match.
|
||||
const size_t actual_count = container.size();
|
||||
if (actual_count != count()) {
|
||||
// The element count doesn't match. If the container is
|
||||
// empty, there's no need to explain anything as Google Mock
|
||||
// already prints the empty container. Otherwise we just need
|
||||
// to show how many elements there actually are.
|
||||
if (actual_count != 0) {
|
||||
*os << "has " << Elements(actual_count);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// The container has the right size but at least one element
|
||||
// doesn't match expectation. We need to find this element and
|
||||
// explain why it doesn't match.
|
||||
typename RawContainer::const_iterator container_iter = container.begin();
|
||||
for (size_t i = 0; i != count(); ++container_iter, ++i) {
|
||||
if (matchers_[i].Matches(*container_iter)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
*os << "element " << i << " doesn't match";
|
||||
|
||||
::std::stringstream ss;
|
||||
matchers_[i].ExplainMatchResultTo(*container_iter, &ss);
|
||||
const string s = ss.str();
|
||||
if (!s.empty()) {
|
||||
*os << " (" << s << ")";
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
static Message Elements(size_t count) {
|
||||
return Message() << count << (count == 1 ? " element" : " elements");
|
||||
}
|
||||
|
||||
size_t count() const { return matchers_.size(); }
|
||||
std::vector<Matcher<const Element&> > matchers_;
|
||||
};
|
||||
|
||||
// Implements ElementsAre() of 0-10 arguments.
|
||||
|
||||
class ElementsAreMatcher0 {
|
||||
public:
|
||||
ElementsAreMatcher0() {}
|
||||
|
||||
template <typename Container>
|
||||
operator Matcher<Container>() const {
|
||||
typedef GMOCK_REMOVE_CONST_(GMOCK_REMOVE_REFERENCE_(Container))
|
||||
RawContainer;
|
||||
typedef typename RawContainer::value_type Element;
|
||||
|
||||
const Matcher<const Element&>* const matchers = NULL;
|
||||
return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers, 0));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
$range i 1..n
|
||||
$for i [[
|
||||
$range j 1..i
|
||||
template <$for j, [[typename T$j]]>
|
||||
class ElementsAreMatcher$i {
|
||||
public:
|
||||
$if i==1 [[explicit ]]ElementsAreMatcher$i($for j, [[const T$j& e$j]])$if i > 0 [[ : ]]
|
||||
$for j, [[e$j[[]]_(e$j)]] {}
|
||||
|
||||
template <typename Container>
|
||||
operator Matcher<Container>() const {
|
||||
typedef GMOCK_REMOVE_CONST_(GMOCK_REMOVE_REFERENCE_(Container))
|
||||
RawContainer;
|
||||
typedef typename RawContainer::value_type Element;
|
||||
|
||||
const Matcher<const Element&> matchers[] = {
|
||||
|
||||
$for j [[
|
||||
MatcherCast<const Element&>(e$j[[]]_),
|
||||
|
||||
]]
|
||||
};
|
||||
|
||||
return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers, $i));
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
$for j [[
|
||||
const T$j& e$j[[]]_;
|
||||
|
||||
]]
|
||||
};
|
||||
|
||||
|
||||
]]
|
||||
// Implements ElementsAreArray().
|
||||
template <typename T>
|
||||
class ElementsAreArrayMatcher {
|
||||
public:
|
||||
ElementsAreArrayMatcher(const T* first, size_t count) :
|
||||
first_(first), count_(count) {}
|
||||
|
||||
template <typename Container>
|
||||
operator Matcher<Container>() const {
|
||||
typedef GMOCK_REMOVE_CONST_(GMOCK_REMOVE_REFERENCE_(Container))
|
||||
RawContainer;
|
||||
typedef typename RawContainer::value_type Element;
|
||||
|
||||
return MakeMatcher(new ElementsAreMatcherImpl<Container>(first_, count_));
|
||||
}
|
||||
|
||||
private:
|
||||
const T* const first_;
|
||||
const size_t count_;
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
// ElementsAre(e0, e1, ..., e_n) matches an STL-style container with
|
||||
// (n + 1) elements, where the i-th element in the container must
|
||||
// match the i-th argument in the list. Each argument of
|
||||
// ElementsAre() can be either a value or a matcher. We support up to
|
||||
// $n arguments.
|
||||
//
|
||||
// NOTE: Since ElementsAre() cares about the order of the elements, it
|
||||
// must not be used with containers whose elements's order is
|
||||
// undefined (e.g. hash_map).
|
||||
|
||||
inline internal::ElementsAreMatcher0 ElementsAre() {
|
||||
return internal::ElementsAreMatcher0();
|
||||
}
|
||||
|
||||
$for i [[
|
||||
$range j 1..i
|
||||
|
||||
template <$for j, [[typename T$j]]>
|
||||
inline internal::ElementsAreMatcher$i<$for j, [[T$j]]> ElementsAre($for j, [[const T$j& e$j]]) {
|
||||
return internal::ElementsAreMatcher$i<$for j, [[T$j]]>($for j, [[e$j]]);
|
||||
}
|
||||
|
||||
]]
|
||||
|
||||
// ElementsAreArray(array) and ElementAreArray(array, count) are like
|
||||
// ElementsAre(), except that they take an array of values or
|
||||
// matchers. The former form infers the size of 'array', which must
|
||||
// be a static C-style array. In the latter form, 'array' can either
|
||||
// be a static array or a pointer to a dynamically created array.
|
||||
|
||||
template <typename T>
|
||||
inline internal::ElementsAreArrayMatcher<T> ElementsAreArray(
|
||||
const T* first, size_t count) {
|
||||
return internal::ElementsAreArrayMatcher<T>(first, count);
|
||||
}
|
||||
|
||||
template <typename T, size_t N>
|
||||
inline internal::ElementsAreArrayMatcher<T>
|
||||
ElementsAreArray(const T (&array)[N]) {
|
||||
return internal::ElementsAreArrayMatcher<T>(array, N);
|
||||
}
|
||||
|
||||
} // namespace testing
|
||||
$$ } // This Pump meta comment fixes auto-indentation in Emacs. It will not
|
||||
$$ // show up in the generated code.
|
||||
|
||||
|
||||
// The MATCHER* family of macros can be used in a namespace scope to
|
||||
// define custom matchers easily. The syntax:
|
||||
//
|
||||
// MATCHER(name, description_string) { statements; }
|
||||
//
|
||||
// will define a matcher with the given name that executes the
|
||||
// statements, which must return a bool to indicate if the match
|
||||
// succeeds. Inside the statements, you can refer to the value being
|
||||
// matched by 'arg', and refer to its type by 'arg_type'.
|
||||
//
|
||||
// The description string documents what the matcher does, and is used
|
||||
// to generate the failure message when the match fails. Since a
|
||||
// MATCHER() is usually defined in a header file shared by multiple
|
||||
// C++ source files, we require the description to be a C-string
|
||||
// literal to avoid possible side effects. It can be empty, in which
|
||||
// case we'll use the sequence of words in the matcher name as the
|
||||
// description.
|
||||
//
|
||||
// For example:
|
||||
//
|
||||
// MATCHER(IsEven, "") { return (arg % 2) == 0; }
|
||||
//
|
||||
// allows you to write
|
||||
//
|
||||
// // Expects mock_foo.Bar(n) to be called where n is even.
|
||||
// EXPECT_CALL(mock_foo, Bar(IsEven()));
|
||||
//
|
||||
// or,
|
||||
//
|
||||
// // Verifies that the value of some_expression is even.
|
||||
// EXPECT_THAT(some_expression, IsEven());
|
||||
//
|
||||
// If the above assertion fails, it will print something like:
|
||||
//
|
||||
// Value of: some_expression
|
||||
// Expected: is even
|
||||
// Actual: 7
|
||||
//
|
||||
// where the description "is even" is automatically calculated from the
|
||||
// matcher name IsEven.
|
||||
//
|
||||
// Note that the type of the value being matched (arg_type) is
|
||||
// determined by the context in which you use the matcher and is
|
||||
// supplied to you by the compiler, so you don't need to worry about
|
||||
// declaring it (nor can you). This allows the matcher to be
|
||||
// polymorphic. For example, IsEven() can be used to match any type
|
||||
// where the value of "(arg % 2) == 0" can be implicitly converted to
|
||||
// a bool. In the "Bar(IsEven())" example above, if method Bar()
|
||||
// takes an int, 'arg_type' will be int; if it takes an unsigned long,
|
||||
// 'arg_type' will be unsigned long; and so on.
|
||||
//
|
||||
// Sometimes you'll want to parameterize the matcher. For that you
|
||||
// can use another macro:
|
||||
//
|
||||
// MATCHER_P(name, param_name, description_string) { statements; }
|
||||
//
|
||||
// For example:
|
||||
//
|
||||
// MATCHER_P(HasAbsoluteValue, value, "") { return abs(arg) == value; }
|
||||
//
|
||||
// will allow you to write:
|
||||
//
|
||||
// EXPECT_THAT(Blah("a"), HasAbsoluteValue(n));
|
||||
//
|
||||
// which may lead to this message (assuming n is 10):
|
||||
//
|
||||
// Value of: Blah("a")
|
||||
// Expected: has absolute value 10
|
||||
// Actual: -9
|
||||
//
|
||||
// Note that both the matcher description and its parameter are
|
||||
// printed, making the message human-friendly.
|
||||
//
|
||||
// In the matcher definition body, you can write 'foo_type' to
|
||||
// reference the type of a parameter named 'foo'. For example, in the
|
||||
// body of MATCHER_P(HasAbsoluteValue, value) above, you can write
|
||||
// 'value_type' to refer to the type of 'value'.
|
||||
//
|
||||
// We also provide MATCHER_P2, MATCHER_P3, ..., up to MATCHER_P$n to
|
||||
// support multi-parameter 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:
|
||||
//
|
||||
// %% a single '%' character
|
||||
// %(*)s all parameters of the matcher printed as a tuple
|
||||
// %(foo)s value of the matcher parameter named 'foo'
|
||||
//
|
||||
// For example,
|
||||
//
|
||||
// MATCHER_P2(InClosedRange, low, hi, "is in range [%(low)s, %(hi)s]") {
|
||||
// return low <= arg && arg <= hi;
|
||||
// }
|
||||
// ...
|
||||
// EXPECT_THAT(3, InClosedRange(4, 6));
|
||||
//
|
||||
// would generate a failure that contains the message:
|
||||
//
|
||||
// Expected: is in range [4, 6]
|
||||
//
|
||||
// If you specify "" as the description, the failure message will
|
||||
// contain the sequence of words in the matcher name followed by the
|
||||
// parameter values printed as a tuple. For example,
|
||||
//
|
||||
// MATCHER_P2(InClosedRange, low, hi, "") { ... }
|
||||
// ...
|
||||
// EXPECT_THAT(3, InClosedRange(4, 6));
|
||||
//
|
||||
// would generate a failure that contains the text:
|
||||
//
|
||||
// Expected: in closed range (4, 6)
|
||||
//
|
||||
// For the purpose of typing, you can view
|
||||
//
|
||||
// MATCHER_Pk(Foo, p1, ..., pk, description_string) { ... }
|
||||
//
|
||||
// as shorthand for
|
||||
//
|
||||
// template <typename p1_type, ..., typename pk_type>
|
||||
// FooMatcherPk<p1_type, ..., pk_type>
|
||||
// Foo(p1_type p1, ..., pk_type pk) { ... }
|
||||
//
|
||||
// When you write Foo(v1, ..., vk), the compiler infers the types of
|
||||
// the parameters v1, ..., and vk for you. If you are not happy with
|
||||
// the result of the type inference, you can specify the types by
|
||||
// explicitly instantiating the template, as in Foo<long, bool>(5,
|
||||
// false). As said earlier, you don't get to (or need to) specify
|
||||
// 'arg_type' as that's determined by the context in which the matcher
|
||||
// is used. You can assign the result of expression Foo(p1, ..., pk)
|
||||
// to a variable of type FooMatcherPk<p1_type, ..., pk_type>. This
|
||||
// can be useful when composing matchers.
|
||||
//
|
||||
// While you can instantiate a matcher template with reference types,
|
||||
// passing the parameters by pointer usually makes your code more
|
||||
// readable. If, however, you still want to pass a parameter by
|
||||
// reference, be aware that in the failure message generated by the
|
||||
// matcher you will see the value of the referenced object but not its
|
||||
// address.
|
||||
//
|
||||
// You can overload matchers with different numbers of parameters:
|
||||
//
|
||||
// MATCHER_P(Blah, a, description_string1) { ... }
|
||||
// MATCHER_P2(Blah, a, b, description_string2) { ... }
|
||||
//
|
||||
// While it's tempting to always use the MATCHER* macros when defining
|
||||
// a new matcher, you should also consider implementing
|
||||
// MatcherInterface or using MakePolymorphicMatcher() instead,
|
||||
// especially if you need to use the matcher a lot. While these
|
||||
// approaches require more work, they give you more control on the
|
||||
// types of the value being matched and the matcher parameters, which
|
||||
// in general leads to better compiler error messages that pay off in
|
||||
// the long run. They also allow overloading matchers based on
|
||||
// parameter types (as opposed to just based on the number of
|
||||
// parameters).
|
||||
//
|
||||
// CAVEAT:
|
||||
//
|
||||
// MATCHER*() can only be used in a namespace scope. The reason is
|
||||
// that C++ doesn't yet allow function-local types to be used to
|
||||
// instantiate templates. The up-coming C++0x standard will fix this.
|
||||
// Once that's done, we'll consider supporting using MATCHER*() inside
|
||||
// a function.
|
||||
//
|
||||
// MORE INFORMATION:
|
||||
//
|
||||
// To learn more about using these macros, please search for 'MATCHER'
|
||||
// on http://code.google.com/p/googlemock/wiki/CookBook.
|
||||
|
||||
namespace testing {
|
||||
namespace internal {
|
||||
|
||||
// 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);
|
||||
|
||||
} // namespace internal
|
||||
} // namespace testing
|
||||
|
||||
$range i 0..n
|
||||
$for i
|
||||
|
||||
[[
|
||||
$var macro_name = [[$if i==0 [[MATCHER]] $elif i==1 [[MATCHER_P]]
|
||||
$else [[MATCHER_P$i]]]]
|
||||
$var class_name = [[name##Matcher[[$if i==0 [[]] $elif i==1 [[P]]
|
||||
$else [[P$i]]]]]]
|
||||
$range j 0..i-1
|
||||
$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 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]]]]
|
||||
$var param_field_decls = [[$for j
|
||||
[[
|
||||
|
||||
p$j##_type p$j;\
|
||||
]]]]
|
||||
$var param_field_decls2 = [[$for j
|
||||
[[
|
||||
|
||||
p$j##_type p$j;\
|
||||
]]]]
|
||||
|
||||
#define $macro_name(name$for j [[, p$j]], description)\$template
|
||||
class $class_name {\
|
||||
public:\
|
||||
template <typename arg_type>\
|
||||
class gmock_Impl : public ::testing::MatcherInterface<arg_type> {\
|
||||
public:\
|
||||
[[$if i==1 [[explicit ]]]]gmock_Impl($impl_ctor_param_list)\
|
||||
$impl_inits {}\
|
||||
virtual bool Matches(arg_type arg) 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);\
|
||||
}\$param_field_decls
|
||||
const ::testing::internal::Interpolations gmock_interp_;\
|
||||
};\
|
||||
template <typename arg_type>\
|
||||
operator ::testing::Matcher<arg_type>() const {\
|
||||
return ::testing::Matcher<arg_type>(\
|
||||
new gmock_Impl<arg_type>($params_and_interp));\
|
||||
}\
|
||||
$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
|
||||
::testing::internal::Interpolations gmock_interp_;\
|
||||
};\$template
|
||||
inline $class_name$param_types name($param_types_and_names) {\
|
||||
return $class_name$param_types($params);\
|
||||
}\$template
|
||||
template <typename arg_type>\
|
||||
bool $class_name$param_types::\
|
||||
gmock_Impl<arg_type>::Matches(arg_type arg) const
|
||||
]]
|
||||
|
||||
|
||||
namespace testing {
|
||||
namespace internal {
|
||||
|
||||
// Returns true iff element is in the STL-style container.
|
||||
template <typename Container, typename Element>
|
||||
inline bool Contains(const Container& container, const Element& element) {
|
||||
return ::std::find(container.begin(), container.end(), element) !=
|
||||
container.end();
|
||||
}
|
||||
|
||||
// Returns true iff element is in the C-style array.
|
||||
template <typename ArrayElement, size_t N, typename Element>
|
||||
inline bool Contains(const ArrayElement (&array)[N], const Element& element) {
|
||||
return ::std::find(array, array + N, element) != array + N;
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
|
||||
// Matches an STL-style container or a C-style array that contains the given
|
||||
// element.
|
||||
//
|
||||
// Examples:
|
||||
// ::std::set<int> page_ids;
|
||||
// page_ids.insert(3);
|
||||
// page_ids.insert(1);
|
||||
// EXPECT_THAT(page_ids, Contains(1));
|
||||
// EXPECT_THAT(page_ids, Contains(3.0));
|
||||
// EXPECT_THAT(page_ids, Not(Contains(4)));
|
||||
//
|
||||
// ::std::map<int, size_t> page_lengths;
|
||||
// page_lengths[1] = 100;
|
||||
// EXPECT_THAT(map_int, Contains(::std::pair<const int, size_t>(1, 100)));
|
||||
//
|
||||
// const char* user_ids[] = { "joe", "mike", "tom" };
|
||||
// EXPECT_THAT(user_ids, Contains(::std::string("tom")));
|
||||
MATCHER_P(Contains, element, "") {
|
||||
return internal::Contains(arg, element);
|
||||
}
|
||||
|
||||
} // namespace testing
|
||||
|
||||
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_
|
||||
@@ -0,0 +1,244 @@
|
||||
// This file was GENERATED by a script. DO NOT EDIT BY HAND!!!
|
||||
|
||||
// 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.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
|
||||
// Implements class templates NiceMock and StrictMock.
|
||||
//
|
||||
// Given a mock class MockFoo that is created using Google Mock,
|
||||
// NiceMock<MockFoo> is a subclass of MockFoo that allows
|
||||
// uninteresting calls (i.e. calls to mock methods that have no
|
||||
// EXPECT_CALL specs), and StrictMock<MockFoo> is a subclass of
|
||||
// MockFoo that treats all uninteresting calls as errors.
|
||||
//
|
||||
// NiceMock and StrictMock "inherits" the constructors of their
|
||||
// respective base class, with up-to 10 arguments. Therefore you can
|
||||
// write NiceMock<MockFoo>(5, "a") to construct a nice mock where
|
||||
// MockFoo has a constructor that accepts (int, const char*), for
|
||||
// example.
|
||||
//
|
||||
// A known limitation is that NiceMock<MockFoo> and
|
||||
// StrictMock<MockFoo> only works for mock methods defined using the
|
||||
// MOCK_METHOD* family of macros DIRECTLY in the MockFoo class. If a
|
||||
// mock method is defined in a base class of MockFoo, the "nice" or
|
||||
// "strict" modifier may not affect it, depending on the compiler. In
|
||||
// particular, nesting NiceMock and StrictMock is NOT supported.
|
||||
//
|
||||
// Another known limitation is that the constructors of the base mock
|
||||
// cannot have arguments passed by non-const reference, which are
|
||||
// banned by the Google C++ style guide anyway.
|
||||
|
||||
#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>
|
||||
|
||||
namespace testing {
|
||||
|
||||
template <class MockClass>
|
||||
class NiceMock : public MockClass {
|
||||
public:
|
||||
// We don't factor out the constructor body to a common method, as
|
||||
// we have to avoid a possible clash with members of MockClass.
|
||||
NiceMock() {
|
||||
Mock::AllowUninterestingCalls(internal::implicit_cast<MockClass*>(this));
|
||||
}
|
||||
|
||||
// C++ doesn't (yet) allow inheritance of constructors, so we have
|
||||
// to define it for each arity.
|
||||
template <typename A1>
|
||||
explicit NiceMock(const A1& a1) : MockClass(a1) {
|
||||
Mock::AllowUninterestingCalls(internal::implicit_cast<MockClass*>(this));
|
||||
}
|
||||
template <typename A1, typename A2>
|
||||
NiceMock(const A1& a1, const A2& a2) : MockClass(a1, a2) {
|
||||
Mock::AllowUninterestingCalls(internal::implicit_cast<MockClass*>(this));
|
||||
}
|
||||
|
||||
template <typename A1, typename A2, typename A3>
|
||||
NiceMock(const A1& a1, const A2& a2, const A3& a3) : MockClass(a1, a2, a3) {
|
||||
Mock::AllowUninterestingCalls(internal::implicit_cast<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) {
|
||||
Mock::AllowUninterestingCalls(internal::implicit_cast<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) {
|
||||
Mock::AllowUninterestingCalls(internal::implicit_cast<MockClass*>(this));
|
||||
}
|
||||
|
||||
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
||||
typename A6>
|
||||
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) {
|
||||
Mock::AllowUninterestingCalls(internal::implicit_cast<MockClass*>(this));
|
||||
}
|
||||
|
||||
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
||||
typename A6, typename A7>
|
||||
NiceMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
|
||||
const A5& a5, const A6& a6, const A7& a7) : MockClass(a1, a2, a3, a4, a5,
|
||||
a6, a7) {
|
||||
Mock::AllowUninterestingCalls(internal::implicit_cast<MockClass*>(this));
|
||||
}
|
||||
|
||||
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
||||
typename A6, typename A7, typename A8>
|
||||
NiceMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
|
||||
const A5& a5, const A6& a6, const A7& a7, const A8& a8) : MockClass(a1,
|
||||
a2, a3, a4, a5, a6, a7, a8) {
|
||||
Mock::AllowUninterestingCalls(internal::implicit_cast<MockClass*>(this));
|
||||
}
|
||||
|
||||
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
||||
typename A6, typename A7, typename A8, typename A9>
|
||||
NiceMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
|
||||
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) {
|
||||
Mock::AllowUninterestingCalls(internal::implicit_cast<MockClass*>(this));
|
||||
}
|
||||
|
||||
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
||||
typename A6, typename A7, typename A8, typename A9, typename A10>
|
||||
NiceMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
|
||||
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) {
|
||||
Mock::AllowUninterestingCalls(internal::implicit_cast<MockClass*>(this));
|
||||
}
|
||||
|
||||
virtual ~NiceMock() {
|
||||
Mock::UnregisterCallReaction(internal::implicit_cast<MockClass*>(this));
|
||||
}
|
||||
};
|
||||
|
||||
template <class MockClass>
|
||||
class StrictMock : public MockClass {
|
||||
public:
|
||||
// We don't factor out the constructor body to a common method, as
|
||||
// we have to avoid a possible clash with members of MockClass.
|
||||
StrictMock() {
|
||||
Mock::FailUninterestingCalls(internal::implicit_cast<MockClass*>(this));
|
||||
}
|
||||
|
||||
template <typename A1>
|
||||
explicit StrictMock(const A1& a1) : MockClass(a1) {
|
||||
Mock::FailUninterestingCalls(internal::implicit_cast<MockClass*>(this));
|
||||
}
|
||||
template <typename A1, typename A2>
|
||||
StrictMock(const A1& a1, const A2& a2) : MockClass(a1, a2) {
|
||||
Mock::FailUninterestingCalls(internal::implicit_cast<MockClass*>(this));
|
||||
}
|
||||
|
||||
template <typename A1, typename A2, typename A3>
|
||||
StrictMock(const A1& a1, const A2& a2, const A3& a3) : MockClass(a1, a2, a3) {
|
||||
Mock::FailUninterestingCalls(internal::implicit_cast<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) {
|
||||
Mock::FailUninterestingCalls(internal::implicit_cast<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) {
|
||||
Mock::FailUninterestingCalls(internal::implicit_cast<MockClass*>(this));
|
||||
}
|
||||
|
||||
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
||||
typename A6>
|
||||
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) {
|
||||
Mock::FailUninterestingCalls(internal::implicit_cast<MockClass*>(this));
|
||||
}
|
||||
|
||||
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
||||
typename A6, typename A7>
|
||||
StrictMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
|
||||
const A5& a5, const A6& a6, const A7& a7) : MockClass(a1, a2, a3, a4, a5,
|
||||
a6, a7) {
|
||||
Mock::FailUninterestingCalls(internal::implicit_cast<MockClass*>(this));
|
||||
}
|
||||
|
||||
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
||||
typename A6, typename A7, typename A8>
|
||||
StrictMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
|
||||
const A5& a5, const A6& a6, const A7& a7, const A8& a8) : MockClass(a1,
|
||||
a2, a3, a4, a5, a6, a7, a8) {
|
||||
Mock::FailUninterestingCalls(internal::implicit_cast<MockClass*>(this));
|
||||
}
|
||||
|
||||
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
||||
typename A6, typename A7, typename A8, typename A9>
|
||||
StrictMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
|
||||
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) {
|
||||
Mock::FailUninterestingCalls(internal::implicit_cast<MockClass*>(this));
|
||||
}
|
||||
|
||||
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
||||
typename A6, typename A7, typename A8, typename A9, typename A10>
|
||||
StrictMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
|
||||
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) {
|
||||
Mock::FailUninterestingCalls(internal::implicit_cast<MockClass*>(this));
|
||||
}
|
||||
|
||||
virtual ~StrictMock() {
|
||||
Mock::UnregisterCallReaction(internal::implicit_cast<MockClass*>(this));
|
||||
}
|
||||
};
|
||||
|
||||
// The following specializations catch some (relatively more common)
|
||||
// user errors of nesting nice and strict mocks. They do NOT catch
|
||||
// all possible errors.
|
||||
|
||||
// These specializations are declared but not defined, as NiceMock and
|
||||
// StrictMock cannot be nested.
|
||||
template <typename MockClass>
|
||||
class NiceMock<NiceMock<MockClass> >;
|
||||
template <typename MockClass>
|
||||
class NiceMock<StrictMock<MockClass> >;
|
||||
template <typename MockClass>
|
||||
class StrictMock<NiceMock<MockClass> >;
|
||||
template <typename MockClass>
|
||||
class StrictMock<StrictMock<MockClass> >;
|
||||
|
||||
} // namespace testing
|
||||
|
||||
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_
|
||||
@@ -0,0 +1,146 @@
|
||||
$$ -*- mode: c++; -*-
|
||||
$$ This is a Pump source file. Please use Pump to convert it to
|
||||
$$ gmock-generated-nice-strict.h.
|
||||
$$
|
||||
$var n = 10 $$ The maximum arity we support.
|
||||
// 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.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
|
||||
// Implements class templates NiceMock and StrictMock.
|
||||
//
|
||||
// Given a mock class MockFoo that is created using Google Mock,
|
||||
// NiceMock<MockFoo> is a subclass of MockFoo that allows
|
||||
// uninteresting calls (i.e. calls to mock methods that have no
|
||||
// EXPECT_CALL specs), and StrictMock<MockFoo> is a subclass of
|
||||
// MockFoo that treats all uninteresting calls as errors.
|
||||
//
|
||||
// NiceMock and StrictMock "inherits" the constructors of their
|
||||
// respective base class, with up-to $n arguments. Therefore you can
|
||||
// write NiceMock<MockFoo>(5, "a") to construct a nice mock where
|
||||
// MockFoo has a constructor that accepts (int, const char*), for
|
||||
// example.
|
||||
//
|
||||
// A known limitation is that NiceMock<MockFoo> and
|
||||
// StrictMock<MockFoo> only works for mock methods defined using the
|
||||
// MOCK_METHOD* family of macros DIRECTLY in the MockFoo class. If a
|
||||
// mock method is defined in a base class of MockFoo, the "nice" or
|
||||
// "strict" modifier may not affect it, depending on the compiler. In
|
||||
// particular, nesting NiceMock and StrictMock is NOT supported.
|
||||
//
|
||||
// Another known limitation is that the constructors of the base mock
|
||||
// cannot have arguments passed by non-const reference, which are
|
||||
// banned by the Google C++ style guide anyway.
|
||||
|
||||
#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>
|
||||
|
||||
namespace testing {
|
||||
|
||||
template <class MockClass>
|
||||
class NiceMock : public MockClass {
|
||||
public:
|
||||
// We don't factor out the constructor body to a common method, as
|
||||
// we have to avoid a possible clash with members of MockClass.
|
||||
NiceMock() {
|
||||
Mock::AllowUninterestingCalls(internal::implicit_cast<MockClass*>(this));
|
||||
}
|
||||
|
||||
// C++ doesn't (yet) allow inheritance of constructors, so we have
|
||||
// to define it for each arity.
|
||||
template <typename A1>
|
||||
explicit NiceMock(const A1& a1) : MockClass(a1) {
|
||||
Mock::AllowUninterestingCalls(internal::implicit_cast<MockClass*>(this));
|
||||
}
|
||||
|
||||
$range i 2..n
|
||||
$for i [[
|
||||
$range j 1..i
|
||||
template <$for j, [[typename A$j]]>
|
||||
NiceMock($for j, [[const A$j& a$j]]) : MockClass($for j, [[a$j]]) {
|
||||
Mock::AllowUninterestingCalls(internal::implicit_cast<MockClass*>(this));
|
||||
}
|
||||
|
||||
|
||||
]]
|
||||
virtual ~NiceMock() {
|
||||
Mock::UnregisterCallReaction(internal::implicit_cast<MockClass*>(this));
|
||||
}
|
||||
};
|
||||
|
||||
template <class MockClass>
|
||||
class StrictMock : public MockClass {
|
||||
public:
|
||||
// We don't factor out the constructor body to a common method, as
|
||||
// we have to avoid a possible clash with members of MockClass.
|
||||
StrictMock() {
|
||||
Mock::FailUninterestingCalls(internal::implicit_cast<MockClass*>(this));
|
||||
}
|
||||
|
||||
template <typename A1>
|
||||
explicit StrictMock(const A1& a1) : MockClass(a1) {
|
||||
Mock::FailUninterestingCalls(internal::implicit_cast<MockClass*>(this));
|
||||
}
|
||||
|
||||
$for i [[
|
||||
$range j 1..i
|
||||
template <$for j, [[typename A$j]]>
|
||||
StrictMock($for j, [[const A$j& a$j]]) : MockClass($for j, [[a$j]]) {
|
||||
Mock::FailUninterestingCalls(internal::implicit_cast<MockClass*>(this));
|
||||
}
|
||||
|
||||
|
||||
]]
|
||||
virtual ~StrictMock() {
|
||||
Mock::UnregisterCallReaction(internal::implicit_cast<MockClass*>(this));
|
||||
}
|
||||
};
|
||||
|
||||
// The following specializations catch some (relatively more common)
|
||||
// user errors of nesting nice and strict mocks. They do NOT catch
|
||||
// all possible errors.
|
||||
|
||||
// These specializations are declared but not defined, as NiceMock and
|
||||
// StrictMock cannot be nested.
|
||||
template <typename MockClass>
|
||||
class NiceMock<NiceMock<MockClass> >;
|
||||
template <typename MockClass>
|
||||
class NiceMock<StrictMock<MockClass> >;
|
||||
template <typename MockClass>
|
||||
class StrictMock<NiceMock<MockClass> >;
|
||||
template <typename MockClass>
|
||||
class StrictMock<StrictMock<MockClass> >;
|
||||
|
||||
} // namespace testing
|
||||
|
||||
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_
|
||||
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
@@ -0,0 +1,693 @@
|
||||
// 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)
|
||||
|
||||
// Google Mock - a framework for writing C++ mock classes.
|
||||
//
|
||||
// This file implements a universal value printer that can print a
|
||||
// value of any type T:
|
||||
//
|
||||
// void ::testing::internal::UniversalPrinter<T>::Print(value, ostream_ptr);
|
||||
//
|
||||
// A user can teach this function how to print a class type T by
|
||||
// defining either operator<<() or PrintTo() in the namespace that
|
||||
// defines T. More specifically, the FIRST defined function in the
|
||||
// following list will be used (assuming T is defined in namespace
|
||||
// foo):
|
||||
//
|
||||
// 1. foo::PrintTo(const T&, ostream*)
|
||||
// 2. operator<<(ostream&, const T&) defined in either foo or the
|
||||
// global namespace.
|
||||
//
|
||||
// If none of the above is defined, it will print the debug string of
|
||||
// the value if it is a protocol buffer, or print the raw bytes in the
|
||||
// value otherwise.
|
||||
//
|
||||
// To aid debugging: when T is a reference type, the address of the
|
||||
// value is also printed; when T is a (const) char pointer, both the
|
||||
// pointer value and the NUL-terminated string it points to are
|
||||
// printed.
|
||||
//
|
||||
// We also provide some convenient wrappers:
|
||||
//
|
||||
// // Prints a value as the given type to a string.
|
||||
// string ::testing::internal::UniversalPrinter<T>::PrintToString(value);
|
||||
//
|
||||
// // Prints a value tersely: for a reference type, the referenced
|
||||
// // value (but not the address) is printed; for a (const) char
|
||||
// // pointer, the NUL-terminated string (but not the pointer) is
|
||||
// // printed.
|
||||
// void ::testing::internal::UniversalTersePrint(const T& value, ostream*);
|
||||
//
|
||||
// // Prints the fields of a tuple tersely to a string vector, one
|
||||
// // element for each field.
|
||||
// std::vector<string> UniversalTersePrintTupleFieldsToStrings(
|
||||
// const Tuple& value);
|
||||
|
||||
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_PRINTERS_H_
|
||||
#define GMOCK_INCLUDE_GMOCK_GMOCK_PRINTERS_H_
|
||||
|
||||
#include <ostream> // NOLINT
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include <gmock/internal/gmock-internal-utils.h>
|
||||
#include <gmock/internal/gmock-port.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
namespace testing {
|
||||
|
||||
// Definitions in the 'internal' and 'internal2' name spaces are
|
||||
// subject to change without notice. DO NOT USE THEM IN USER CODE!
|
||||
namespace internal2 {
|
||||
|
||||
// Prints the given number of bytes in the given object to the given
|
||||
// ostream.
|
||||
void PrintBytesInObjectTo(const unsigned char* obj_bytes,
|
||||
size_t count,
|
||||
::std::ostream* os);
|
||||
|
||||
// TypeWithoutFormatter<T, kIsProto>::PrintValue(value, os) is called
|
||||
// by the universal printer to print a value of type T when neither
|
||||
// operator<< nor PrintTo() is defined for type T. When T is
|
||||
// ProtocolMessage, proto2::Message, or a subclass of those, kIsProto
|
||||
// will be true and the short debug string of the protocol message
|
||||
// value will be printed; otherwise kIsProto will be false and the
|
||||
// bytes in the value will be printed.
|
||||
template <typename T, bool kIsProto>
|
||||
class TypeWithoutFormatter {
|
||||
public:
|
||||
static void PrintValue(const T& value, ::std::ostream* os) {
|
||||
PrintBytesInObjectTo(reinterpret_cast<const unsigned char*>(&value),
|
||||
sizeof(value), os);
|
||||
}
|
||||
};
|
||||
template <typename T>
|
||||
class TypeWithoutFormatter<T, true> {
|
||||
public:
|
||||
static void PrintValue(const T& value, ::std::ostream* os) {
|
||||
// Both ProtocolMessage and proto2::Message have the
|
||||
// ShortDebugString() method, so the same implementation works for
|
||||
// both.
|
||||
::std::operator<<(*os, "<" + value.ShortDebugString() + ">");
|
||||
}
|
||||
};
|
||||
|
||||
// Prints the given value to the given ostream. If the value is a
|
||||
// protocol message, its short debug string is printed; otherwise the
|
||||
// bytes in the value are printed. This is what
|
||||
// UniversalPrinter<T>::Print() does when it knows nothing about type
|
||||
// T and T has no << operator.
|
||||
//
|
||||
// A user can override this behavior for a class type Foo by defining
|
||||
// a << operator in the namespace where Foo is defined.
|
||||
//
|
||||
// We put this operator in namespace 'internal2' instead of 'internal'
|
||||
// to simplify the implementation, as much code in 'internal' needs to
|
||||
// use << in STL, which would conflict with our own << were it defined
|
||||
// in 'internal'.
|
||||
//
|
||||
// Note that this operator<< takes a generic std::basic_ostream<Char,
|
||||
// CharTraits> type instead of the more restricted std::ostream. If
|
||||
// we define it to take an std::ostream instead, we'll get an
|
||||
// "ambiguous overloads" compiler error when trying to print a type
|
||||
// Foo that supports streaming to std::basic_ostream<Char,
|
||||
// CharTraits>, as the compiler cannot tell whether
|
||||
// operator<<(std::ostream&, const T&) or
|
||||
// operator<<(std::basic_stream<Char, CharTraits>, const Foo&) is more
|
||||
// specific.
|
||||
template <typename Char, typename CharTraits, typename T>
|
||||
::std::basic_ostream<Char, CharTraits>& operator<<(
|
||||
::std::basic_ostream<Char, CharTraits>& os, const T& x) {
|
||||
TypeWithoutFormatter<T, ::testing::internal::IsAProtocolMessage<T>::value>::
|
||||
PrintValue(x, &os);
|
||||
return os;
|
||||
}
|
||||
|
||||
} // namespace internal2
|
||||
} // namespace testing
|
||||
|
||||
// This namespace MUST NOT BE NESTED IN ::testing, or the name look-up
|
||||
// magic needed for implementing UniversalPrinter won't work.
|
||||
namespace testing_internal {
|
||||
|
||||
// Used to print a value that is not an STL-style container when the
|
||||
// user doesn't define PrintTo() for it.
|
||||
template <typename T>
|
||||
void DefaultPrintNonContainerTo(const T& value, ::std::ostream* os) {
|
||||
// With the following statement, during unqualified name lookup,
|
||||
// testing::internal2::operator<< appears as if it was declared in
|
||||
// the nearest enclosing namespace that contains both
|
||||
// ::testing_internal and ::testing::internal2, i.e. the global
|
||||
// namespace. For more details, refer to the C++ Standard section
|
||||
// 7.3.4-1 [namespace.udir]. This allows us to fall back onto
|
||||
// testing::internal2::operator<< in case T doesn't come with a <<
|
||||
// operator.
|
||||
//
|
||||
// We cannot write 'using ::testing::internal2::operator<<;', which
|
||||
// gcc 3.3 fails to compile due to a compiler bug.
|
||||
using namespace ::testing::internal2; // NOLINT
|
||||
|
||||
// Assuming T is defined in namespace foo, in the next statement,
|
||||
// the compiler will consider all of:
|
||||
//
|
||||
// 1. foo::operator<< (thanks to Koenig look-up),
|
||||
// 2. ::operator<< (as the current namespace is enclosed in ::),
|
||||
// 3. testing::internal2::operator<< (thanks to the using statement above).
|
||||
//
|
||||
// The operator<< whose type matches T best will be picked.
|
||||
//
|
||||
// We deliberately allow #2 to be a candidate, as sometimes it's
|
||||
// impossible to define #1 (e.g. when foo is ::std, defining
|
||||
// anything in it is undefined behavior unless you are a compiler
|
||||
// vendor.).
|
||||
*os << value;
|
||||
}
|
||||
|
||||
} // namespace testing_internal
|
||||
|
||||
namespace testing {
|
||||
namespace internal {
|
||||
|
||||
// UniversalPrinter<T>::Print(value, ostream_ptr) prints the given
|
||||
// value to the given ostream. The caller must ensure that
|
||||
// 'ostream_ptr' is not NULL, or the behavior is undefined.
|
||||
//
|
||||
// We define UniversalPrinter as a class template (as opposed to a
|
||||
// function template), as we need to partially specialize it for
|
||||
// reference types, which cannot be done with function templates.
|
||||
template <typename T>
|
||||
class UniversalPrinter;
|
||||
|
||||
// Used to print an STL-style container when the user doesn't define
|
||||
// a PrintTo() for it.
|
||||
template <typename C>
|
||||
void DefaultPrintTo(IsContainer /* dummy */,
|
||||
false_type /* is not a pointer */,
|
||||
const C& container, ::std::ostream* os) {
|
||||
const size_t kMaxCount = 32; // The maximum number of elements to print.
|
||||
*os << '{';
|
||||
size_t count = 0;
|
||||
for (typename C::const_iterator it = container.begin();
|
||||
it != container.end(); ++it, ++count) {
|
||||
if (count > 0) {
|
||||
*os << ',';
|
||||
if (count == kMaxCount) { // Enough has been printed.
|
||||
*os << " ...";
|
||||
break;
|
||||
}
|
||||
}
|
||||
*os << ' ';
|
||||
PrintTo(*it, os);
|
||||
}
|
||||
|
||||
if (count > 0) {
|
||||
*os << ' ';
|
||||
}
|
||||
*os << '}';
|
||||
}
|
||||
|
||||
// Used to print a pointer that is neither a char pointer nor a member
|
||||
// pointer, when the user doesn't define PrintTo() for it. (A member
|
||||
// variable pointer or member function pointer doesn't really point to
|
||||
// a location in the address space. Their representation is
|
||||
// implementation-defined. Therefore they will be printed as raw
|
||||
// bytes.)
|
||||
template <typename T>
|
||||
void DefaultPrintTo(IsNotContainer /* dummy */,
|
||||
true_type /* is a pointer */,
|
||||
T* p, ::std::ostream* os) {
|
||||
if (p == NULL) {
|
||||
*os << "NULL";
|
||||
} else {
|
||||
// We cannot use implicit_cast or static_cast here, as they don't
|
||||
// work when p is a function pointer.
|
||||
*os << reinterpret_cast<const void*>(p);
|
||||
}
|
||||
}
|
||||
|
||||
// Used to print a non-container, non-pointer value when the user
|
||||
// doesn't define PrintTo() for it.
|
||||
template <typename T>
|
||||
void DefaultPrintTo(IsNotContainer /* dummy */,
|
||||
false_type /* is not a pointer */,
|
||||
const T& value, ::std::ostream* os) {
|
||||
::testing_internal::DefaultPrintNonContainerTo(value, os);
|
||||
}
|
||||
|
||||
// Prints the given value using the << operator if it has one;
|
||||
// otherwise prints the bytes in it. This is what
|
||||
// UniversalPrinter<T>::Print() does when PrintTo() is not specialized
|
||||
// or overloaded for type T.
|
||||
//
|
||||
// A user can override this behavior for a class type Foo by defining
|
||||
// an overload of PrintTo() in the namespace where Foo is defined. We
|
||||
// give the user this option as sometimes defining a << operator for
|
||||
// Foo is not desirable (e.g. the coding style may prevent doing it,
|
||||
// or there is already a << operator but it doesn't do what the user
|
||||
// wants).
|
||||
template <typename T>
|
||||
void PrintTo(const T& value, ::std::ostream* os) {
|
||||
// DefaultPrintTo() is overloaded. The type of its first two
|
||||
// arguments determine which version will be picked. If T is an
|
||||
// STL-style container, the version for container will be called; if
|
||||
// T is a pointer, the pointer version will be called; otherwise the
|
||||
// generic version will be called.
|
||||
//
|
||||
// Note that we check for container types here, prior to we check
|
||||
// for protocol message types in our operator<<. The rationale is:
|
||||
//
|
||||
// For protocol messages, we want to give people a chance to
|
||||
// override Google Mock's format by defining a PrintTo() or
|
||||
// operator<<. For STL containers, other formats can be
|
||||
// incompatible with Google Mock's format for the container
|
||||
// elements; therefore we check for container types here to ensure
|
||||
// that our format is used.
|
||||
//
|
||||
// The second argument of DefaultPrintTo() is needed to bypass a bug
|
||||
// in Symbian's C++ compiler that prevents it from picking the right
|
||||
// overload between:
|
||||
//
|
||||
// PrintTo(const T& x, ...);
|
||||
// PrintTo(T* x, ...);
|
||||
DefaultPrintTo(IsContainerTest<T>(0), is_pointer<T>(), value, os);
|
||||
}
|
||||
|
||||
// The following list of PrintTo() overloads tells
|
||||
// UniversalPrinter<T>::Print() how to print standard types (built-in
|
||||
// types, strings, plain arrays, and pointers).
|
||||
|
||||
// Overloads for various char types.
|
||||
void PrintCharTo(char c, int char_code, ::std::ostream* os);
|
||||
inline void PrintTo(unsigned char c, ::std::ostream* os) {
|
||||
PrintCharTo(c, c, os);
|
||||
}
|
||||
inline void PrintTo(signed char c, ::std::ostream* os) {
|
||||
PrintCharTo(c, c, os);
|
||||
}
|
||||
inline void PrintTo(char c, ::std::ostream* os) {
|
||||
// When printing a plain char, we always treat it as unsigned. This
|
||||
// way, the output won't be affected by whether the compiler thinks
|
||||
// char is signed or not.
|
||||
PrintTo(static_cast<unsigned char>(c), os);
|
||||
}
|
||||
|
||||
// Overloads for other simple built-in types.
|
||||
inline void PrintTo(bool x, ::std::ostream* os) {
|
||||
*os << (x ? "true" : "false");
|
||||
}
|
||||
|
||||
// Overload for wchar_t type.
|
||||
// Prints a wchar_t as a symbol if it is printable or as its internal
|
||||
// code otherwise and also as its decimal code (except for L'\0').
|
||||
// The L'\0' char is printed as "L'\\0'". The decimal code is printed
|
||||
// as signed integer when wchar_t is implemented by the compiler
|
||||
// as a signed type and is printed as an unsigned integer when wchar_t
|
||||
// is implemented as an unsigned type.
|
||||
void PrintTo(wchar_t wc, ::std::ostream* os);
|
||||
|
||||
// Overloads for C strings.
|
||||
void PrintTo(const char* s, ::std::ostream* os);
|
||||
inline void PrintTo(char* s, ::std::ostream* os) {
|
||||
PrintTo(implicit_cast<const char*>(s), os);
|
||||
}
|
||||
|
||||
// MSVC can be configured to define wchar_t as a typedef of unsigned
|
||||
// short. It defines _NATIVE_WCHAR_T_DEFINED when wchar_t is a native
|
||||
// type. When wchar_t is a typedef, defining an overload for const
|
||||
// wchar_t* would cause unsigned short* be printed as a wide string,
|
||||
// possibly causing invalid memory accesses.
|
||||
#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED)
|
||||
// Overloads for wide C strings
|
||||
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);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Overload for C arrays. Multi-dimensional arrays are printed
|
||||
// properly.
|
||||
|
||||
// Prints the given number of elements in an array, without printing
|
||||
// the curly braces.
|
||||
template <typename T>
|
||||
void PrintRawArrayTo(const T a[], size_t count, ::std::ostream* os) {
|
||||
UniversalPrinter<T>::Print(a[0], os);
|
||||
for (size_t i = 1; i != count; i++) {
|
||||
*os << ", ";
|
||||
UniversalPrinter<T>::Print(a[i], os);
|
||||
}
|
||||
}
|
||||
|
||||
// Overloads for ::string and ::std::string.
|
||||
#if GTEST_HAS_GLOBAL_STRING
|
||||
void PrintStringTo(const ::string&s, ::std::ostream* os);
|
||||
inline void PrintTo(const ::string& s, ::std::ostream* os) {
|
||||
PrintStringTo(s, os);
|
||||
}
|
||||
#endif // GTEST_HAS_GLOBAL_STRING
|
||||
|
||||
#if GTEST_HAS_STD_STRING
|
||||
void PrintStringTo(const ::std::string&s, ::std::ostream* os);
|
||||
inline void PrintTo(const ::std::string& s, ::std::ostream* os) {
|
||||
PrintStringTo(s, os);
|
||||
}
|
||||
#endif // GTEST_HAS_STD_STRING
|
||||
|
||||
// Overloads for ::wstring and ::std::wstring.
|
||||
#if GTEST_HAS_GLOBAL_WSTRING
|
||||
void PrintWideStringTo(const ::wstring&s, ::std::ostream* os);
|
||||
inline void PrintTo(const ::wstring& s, ::std::ostream* os) {
|
||||
PrintWideStringTo(s, os);
|
||||
}
|
||||
#endif // GTEST_HAS_GLOBAL_WSTRING
|
||||
|
||||
#if GTEST_HAS_STD_WSTRING
|
||||
void PrintWideStringTo(const ::std::wstring&s, ::std::ostream* os);
|
||||
inline void PrintTo(const ::std::wstring& s, ::std::ostream* os) {
|
||||
PrintWideStringTo(s, os);
|
||||
}
|
||||
#endif // GTEST_HAS_STD_WSTRING
|
||||
|
||||
// Overload for ::std::tr1::tuple. Needed for printing function
|
||||
// arguments, which are packed as tuples.
|
||||
|
||||
typedef ::std::vector<string> Strings;
|
||||
|
||||
// This helper template allows PrintTo() for tuples and
|
||||
// UniversalTersePrintTupleFieldsToStrings() to be defined by
|
||||
// induction on the number of tuple fields. The idea is that
|
||||
// TuplePrefixPrinter<N>::PrintPrefixTo(t, os) prints the first N
|
||||
// fields in tuple t, and can be defined in terms of
|
||||
// TuplePrefixPrinter<N - 1>.
|
||||
|
||||
// The inductive case.
|
||||
template <size_t N>
|
||||
struct TuplePrefixPrinter {
|
||||
// Prints the first N fields of a tuple.
|
||||
template <typename Tuple>
|
||||
static void PrintPrefixTo(const Tuple& t, ::std::ostream* os) {
|
||||
TuplePrefixPrinter<N - 1>::PrintPrefixTo(t, os);
|
||||
*os << ", ";
|
||||
UniversalPrinter<typename ::std::tr1::tuple_element<N - 1, Tuple>::type>
|
||||
::Print(::std::tr1::get<N - 1>(t), os);
|
||||
}
|
||||
|
||||
// Tersely prints the first N fields of a tuple to a string vector,
|
||||
// one element for each field.
|
||||
template <typename Tuple>
|
||||
static void TersePrintPrefixToStrings(const Tuple& t, Strings* strings) {
|
||||
TuplePrefixPrinter<N - 1>::TersePrintPrefixToStrings(t, strings);
|
||||
::std::stringstream ss;
|
||||
UniversalTersePrint(::std::tr1::get<N - 1>(t), &ss);
|
||||
strings->push_back(ss.str());
|
||||
}
|
||||
};
|
||||
|
||||
// Base cases.
|
||||
template <>
|
||||
struct TuplePrefixPrinter<0> {
|
||||
template <typename Tuple>
|
||||
static void PrintPrefixTo(const Tuple&, ::std::ostream*) {}
|
||||
|
||||
template <typename Tuple>
|
||||
static void TersePrintPrefixToStrings(const Tuple&, Strings*) {}
|
||||
};
|
||||
template <>
|
||||
template <typename Tuple>
|
||||
void TuplePrefixPrinter<1>::PrintPrefixTo(const Tuple& t, ::std::ostream* os) {
|
||||
UniversalPrinter<typename ::std::tr1::tuple_element<0, Tuple>::type>::
|
||||
Print(::std::tr1::get<0>(t), os);
|
||||
}
|
||||
|
||||
// Helper function for printing a tuple. T must be instantiated with
|
||||
// a tuple type.
|
||||
template <typename T>
|
||||
void PrintTupleTo(const T& t, ::std::ostream* os) {
|
||||
*os << "(";
|
||||
TuplePrefixPrinter< ::std::tr1::tuple_size<T>::value>::
|
||||
PrintPrefixTo(t, os);
|
||||
*os << ")";
|
||||
}
|
||||
|
||||
// Overloaded PrintTo() for tuples of various arities. We support
|
||||
// tuples of up-to 10 fields. The following implementation works
|
||||
// regardless of whether tr1::tuple is implemented using the
|
||||
// non-standard variadic template feature or not.
|
||||
|
||||
inline void PrintTo(const ::std::tr1::tuple<>& t, ::std::ostream* os) {
|
||||
PrintTupleTo(t, os);
|
||||
}
|
||||
|
||||
template <typename T1>
|
||||
void PrintTo(const ::std::tr1::tuple<T1>& t, ::std::ostream* os) {
|
||||
PrintTupleTo(t, os);
|
||||
}
|
||||
|
||||
template <typename T1, typename T2>
|
||||
void PrintTo(const ::std::tr1::tuple<T1, T2>& t, ::std::ostream* os) {
|
||||
PrintTupleTo(t, os);
|
||||
}
|
||||
|
||||
template <typename T1, typename T2, typename T3>
|
||||
void PrintTo(const ::std::tr1::tuple<T1, T2, T3>& t, ::std::ostream* os) {
|
||||
PrintTupleTo(t, os);
|
||||
}
|
||||
|
||||
template <typename T1, typename T2, typename T3, typename T4>
|
||||
void PrintTo(const ::std::tr1::tuple<T1, T2, T3, T4>& t, ::std::ostream* os) {
|
||||
PrintTupleTo(t, os);
|
||||
}
|
||||
|
||||
template <typename T1, typename T2, typename T3, typename T4, typename T5>
|
||||
void PrintTo(const ::std::tr1::tuple<T1, T2, T3, T4, T5>& t,
|
||||
::std::ostream* os) {
|
||||
PrintTupleTo(t, os);
|
||||
}
|
||||
|
||||
template <typename T1, typename T2, typename T3, typename T4, typename T5,
|
||||
typename T6>
|
||||
void PrintTo(const ::std::tr1::tuple<T1, T2, T3, T4, T5, T6>& t,
|
||||
::std::ostream* os) {
|
||||
PrintTupleTo(t, os);
|
||||
}
|
||||
|
||||
template <typename T1, typename T2, typename T3, typename T4, typename T5,
|
||||
typename T6, typename T7>
|
||||
void PrintTo(const ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7>& t,
|
||||
::std::ostream* os) {
|
||||
PrintTupleTo(t, os);
|
||||
}
|
||||
|
||||
template <typename T1, typename T2, typename T3, typename T4, typename T5,
|
||||
typename T6, typename T7, typename T8>
|
||||
void PrintTo(const ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8>& t,
|
||||
::std::ostream* os) {
|
||||
PrintTupleTo(t, os);
|
||||
}
|
||||
|
||||
template <typename T1, typename T2, typename T3, typename T4, typename T5,
|
||||
typename T6, typename T7, typename T8, typename T9>
|
||||
void PrintTo(const ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9>& t,
|
||||
::std::ostream* os) {
|
||||
PrintTupleTo(t, os);
|
||||
}
|
||||
|
||||
template <typename T1, typename T2, typename T3, typename T4, typename T5,
|
||||
typename T6, typename T7, typename T8, typename T9, typename T10>
|
||||
void PrintTo(
|
||||
const ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>& t,
|
||||
::std::ostream* os) {
|
||||
PrintTupleTo(t, os);
|
||||
}
|
||||
|
||||
// Overload for std::pair.
|
||||
template <typename T1, typename T2>
|
||||
void PrintTo(const ::std::pair<T1, T2>& value, ::std::ostream* os) {
|
||||
*os << '(';
|
||||
UniversalPrinter<T1>::Print(value.first, os);
|
||||
*os << ", ";
|
||||
UniversalPrinter<T2>::Print(value.second, os);
|
||||
*os << ')';
|
||||
}
|
||||
|
||||
// Implements printing a non-reference type T by letting the compiler
|
||||
// pick the right overload of PrintTo() for T.
|
||||
template <typename T>
|
||||
class UniversalPrinter {
|
||||
public:
|
||||
// MSVC warns about adding const to a function type, so we want to
|
||||
// disable the warning.
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push) // Saves the current warning state.
|
||||
#pragma warning(disable:4180) // Temporarily disables warning 4180.
|
||||
#endif // _MSC_VER
|
||||
|
||||
// Note: we deliberately don't call this PrintTo(), as that name
|
||||
// conflicts with ::testing::internal::PrintTo in the body of the
|
||||
// function.
|
||||
static void Print(const T& value, ::std::ostream* os) {
|
||||
// By default, ::testing::internal::PrintTo() is used for printing
|
||||
// the value.
|
||||
//
|
||||
// Thanks to Koenig look-up, if T is a class and has its own
|
||||
// PrintTo() function defined in its namespace, that function will
|
||||
// be visible here. Since it is more specific than the generic ones
|
||||
// in ::testing::internal, it will be picked by the compiler in the
|
||||
// following statement - exactly what we want.
|
||||
PrintTo(value, os);
|
||||
}
|
||||
|
||||
// A convenient wrapper for Print() that returns the print-out as a
|
||||
// string.
|
||||
static string PrintToString(const T& value) {
|
||||
::std::stringstream ss;
|
||||
Print(value, &ss);
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop) // Restores the warning state.
|
||||
#endif // _MSC_VER
|
||||
};
|
||||
|
||||
// Implements printing an array type T[N].
|
||||
template <typename T, size_t N>
|
||||
class UniversalPrinter<T[N]> {
|
||||
public:
|
||||
// Prints the given array, omitting some elements when there are too
|
||||
// many.
|
||||
static void Print(const T (&a)[N], ::std::ostream* os) {
|
||||
// Prints a char array as a C string. Note that we compare 'const
|
||||
// T' with 'const char' instead of comparing T with char, in case
|
||||
// that T is already a const type.
|
||||
if (internal::type_equals<const T, const char>::value) {
|
||||
UniversalPrinter<const T*>::Print(a, os);
|
||||
return;
|
||||
}
|
||||
|
||||
if (N == 0) {
|
||||
*os << "{}";
|
||||
} else {
|
||||
*os << "{ ";
|
||||
const size_t kThreshold = 18;
|
||||
const size_t kChunkSize = 8;
|
||||
// If the array has more than kThreshold elements, we'll have to
|
||||
// omit some details by printing only the first and the last
|
||||
// kChunkSize elements.
|
||||
// TODO(wan): let the user control the threshold using a flag.
|
||||
if (N <= kThreshold) {
|
||||
PrintRawArrayTo(a, N, os);
|
||||
} else {
|
||||
PrintRawArrayTo(a, kChunkSize, os);
|
||||
*os << ", ..., ";
|
||||
PrintRawArrayTo(a + N - kChunkSize, kChunkSize, os);
|
||||
}
|
||||
*os << " }";
|
||||
}
|
||||
}
|
||||
|
||||
// A convenient wrapper for Print() that returns the print-out as a
|
||||
// string.
|
||||
static string PrintToString(const T (&a)[N]) {
|
||||
::std::stringstream ss;
|
||||
Print(a, &ss);
|
||||
return ss.str();
|
||||
}
|
||||
};
|
||||
|
||||
// Implements printing a reference type T&.
|
||||
template <typename T>
|
||||
class UniversalPrinter<T&> {
|
||||
public:
|
||||
// MSVC warns about adding const to a function type, so we want to
|
||||
// disable the warning.
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push) // Saves the current warning state.
|
||||
#pragma warning(disable:4180) // Temporarily disables warning 4180.
|
||||
#endif // _MSC_VER
|
||||
|
||||
static void Print(const T& value, ::std::ostream* os) {
|
||||
// Prints the address of the value. We use reinterpret_cast here
|
||||
// as static_cast doesn't compile when T is a function type.
|
||||
*os << "@" << reinterpret_cast<const void*>(&value) << " ";
|
||||
|
||||
// Then prints the value itself.
|
||||
UniversalPrinter<T>::Print(value, os);
|
||||
}
|
||||
|
||||
// A convenient wrapper for Print() that returns the print-out as a
|
||||
// string.
|
||||
static string PrintToString(const T& value) {
|
||||
::std::stringstream ss;
|
||||
Print(value, &ss);
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop) // Restores the warning state.
|
||||
#endif // _MSC_VER
|
||||
};
|
||||
|
||||
// Prints a value tersely: for a reference type, the referenced value
|
||||
// (but not the address) is printed; for a (const) char pointer, the
|
||||
// NUL-terminated string (but not the pointer) is printed.
|
||||
template <typename T>
|
||||
void UniversalTersePrint(const T& value, ::std::ostream* os) {
|
||||
UniversalPrinter<T>::Print(value, os);
|
||||
}
|
||||
inline void UniversalTersePrint(const char* str, ::std::ostream* os) {
|
||||
if (str == NULL) {
|
||||
*os << "NULL";
|
||||
} else {
|
||||
UniversalPrinter<string>::Print(string(str), os);
|
||||
}
|
||||
}
|
||||
inline void UniversalTersePrint(char* str, ::std::ostream* os) {
|
||||
UniversalTersePrint(static_cast<const char*>(str), os);
|
||||
}
|
||||
|
||||
// Prints the fields of a tuple tersely to a string vector, one
|
||||
// element for each field. See the comment before
|
||||
// UniversalTersePrint() for how we define "tersely".
|
||||
template <typename Tuple>
|
||||
Strings UniversalTersePrintTupleFieldsToStrings(const Tuple& value) {
|
||||
Strings result;
|
||||
TuplePrefixPrinter< ::std::tr1::tuple_size<Tuple>::value>::
|
||||
TersePrintPrefixToStrings(value, &result);
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace testing
|
||||
|
||||
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_PRINTERS_H_
|
||||
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
@@ -0,0 +1,93 @@
|
||||
// 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)
|
||||
|
||||
// Google Mock - a framework for writing C++ mock classes.
|
||||
//
|
||||
// This is the main header file a user should include.
|
||||
|
||||
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_H_
|
||||
#define GMOCK_INCLUDE_GMOCK_GMOCK_H_
|
||||
|
||||
// This file implements the following syntax:
|
||||
//
|
||||
// ON_CALL(mock_object.Method(...))
|
||||
// .WithArguments(...) ?
|
||||
// .WillByDefault(...);
|
||||
//
|
||||
// where WithArguments() is optional and WillByDefault() must appear
|
||||
// exactly once.
|
||||
//
|
||||
// EXPECT_CALL(mock_object.Method(...))
|
||||
// .WithArguments(...) ?
|
||||
// .Times(...) ?
|
||||
// .InSequence(...) *
|
||||
// .WillOnce(...) *
|
||||
// .WillRepeatedly(...) ?
|
||||
// .RetiresOnSaturation() ? ;
|
||||
//
|
||||
// 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-generated-nice-strict.h>
|
||||
#include <gmock/gmock-matchers.h>
|
||||
#include <gmock/gmock-printers.h>
|
||||
#include <gmock/internal/gmock-internal-utils.h>
|
||||
|
||||
namespace testing {
|
||||
|
||||
// Declares Google Mock flags that we want a user to use programmatically.
|
||||
GMOCK_DECLARE_bool_(catch_leaked_mocks);
|
||||
GMOCK_DECLARE_string_(verbose);
|
||||
|
||||
// Initializes Google Mock. This must be called before running the
|
||||
// tests. In particular, it parses the command line for the flags
|
||||
// that Google Mock recognizes. Whenever a Google Mock flag is seen,
|
||||
// it is removed from argv, and *argc is decremented.
|
||||
//
|
||||
// No value is returned. Instead, the Google Mock flag variables are
|
||||
// updated.
|
||||
//
|
||||
// Since Google Test is needed for Google Mock to work, this function
|
||||
// also initializes Google Test and parses its flags, if that hasn't
|
||||
// been done.
|
||||
void InitGoogleMock(int* argc, char** argv);
|
||||
|
||||
// This overloaded version can be used in Windows programs compiled in
|
||||
// UNICODE mode.
|
||||
void InitGoogleMock(int* argc, wchar_t** argv);
|
||||
|
||||
} // namespace testing
|
||||
|
||||
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_H_
|
||||
@@ -0,0 +1,277 @@
|
||||
// This file was GENERATED by a script. DO NOT EDIT BY HAND!!!
|
||||
|
||||
// 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)
|
||||
|
||||
// Google Mock - a framework for writing C++ mock classes.
|
||||
//
|
||||
// This file contains template meta-programming utility classes needed
|
||||
// for implementing Google Mock.
|
||||
|
||||
#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>
|
||||
|
||||
namespace testing {
|
||||
|
||||
template <typename T>
|
||||
class Matcher;
|
||||
|
||||
namespace internal {
|
||||
|
||||
// An IgnoredValue object can be implicitly constructed from ANY value.
|
||||
// This is used in implementing the IgnoreResult(a) action.
|
||||
class IgnoredValue {
|
||||
public:
|
||||
// This constructor template allows any value to be implicitly
|
||||
// converted to IgnoredValue. The object has no data member and
|
||||
// doesn't try to remember anything about the argument. We
|
||||
// deliberately omit the 'explicit' keyword in order to allow the
|
||||
// conversion to be implicit.
|
||||
template <typename T>
|
||||
IgnoredValue(const T&) {}
|
||||
};
|
||||
|
||||
// MatcherTuple<T>::type is a tuple type where each field is a Matcher
|
||||
// for the corresponding field in tuple type T.
|
||||
template <typename Tuple>
|
||||
struct MatcherTuple;
|
||||
|
||||
template <>
|
||||
struct MatcherTuple< ::std::tr1::tuple<> > {
|
||||
typedef ::std::tr1::tuple< > type;
|
||||
};
|
||||
|
||||
template <typename A1>
|
||||
struct MatcherTuple< ::std::tr1::tuple<A1> > {
|
||||
typedef ::std::tr1::tuple<Matcher<A1> > type;
|
||||
};
|
||||
|
||||
template <typename A1, typename A2>
|
||||
struct MatcherTuple< ::std::tr1::tuple<A1, A2> > {
|
||||
typedef ::std::tr1::tuple<Matcher<A1>, Matcher<A2> > type;
|
||||
};
|
||||
|
||||
template <typename A1, typename A2, typename A3>
|
||||
struct MatcherTuple< ::std::tr1::tuple<A1, A2, A3> > {
|
||||
typedef ::std::tr1::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3> > type;
|
||||
};
|
||||
|
||||
template <typename A1, typename A2, typename A3, typename A4>
|
||||
struct MatcherTuple< ::std::tr1::tuple<A1, A2, A3, A4> > {
|
||||
typedef ::std::tr1::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>,
|
||||
Matcher<A4> > type;
|
||||
};
|
||||
|
||||
template <typename A1, typename A2, typename A3, typename A4, typename A5>
|
||||
struct MatcherTuple< ::std::tr1::tuple<A1, A2, A3, A4, A5> > {
|
||||
typedef ::std::tr1::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4>,
|
||||
Matcher<A5> > type;
|
||||
};
|
||||
|
||||
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
||||
typename A6>
|
||||
struct MatcherTuple< ::std::tr1::tuple<A1, A2, A3, A4, A5, A6> > {
|
||||
typedef ::std::tr1::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4>,
|
||||
Matcher<A5>, Matcher<A6> > type;
|
||||
};
|
||||
|
||||
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
||||
typename A6, typename A7>
|
||||
struct MatcherTuple< ::std::tr1::tuple<A1, A2, A3, A4, A5, A6, A7> > {
|
||||
typedef ::std::tr1::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4>,
|
||||
Matcher<A5>, Matcher<A6>, Matcher<A7> > type;
|
||||
};
|
||||
|
||||
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
||||
typename A6, typename A7, typename A8>
|
||||
struct MatcherTuple< ::std::tr1::tuple<A1, A2, A3, A4, A5, A6, A7, A8> > {
|
||||
typedef ::std::tr1::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4>,
|
||||
Matcher<A5>, Matcher<A6>, Matcher<A7>, Matcher<A8> > type;
|
||||
};
|
||||
|
||||
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
||||
typename A6, typename A7, typename A8, typename A9>
|
||||
struct MatcherTuple< ::std::tr1::tuple<A1, A2, A3, A4, A5, A6, A7, A8, A9> > {
|
||||
typedef ::std::tr1::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4>,
|
||||
Matcher<A5>, Matcher<A6>, Matcher<A7>, Matcher<A8>, Matcher<A9> > type;
|
||||
};
|
||||
|
||||
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
||||
typename A6, typename A7, typename A8, typename A9, typename A10>
|
||||
struct MatcherTuple< ::std::tr1::tuple<A1, A2, A3, A4, A5, A6, A7, A8, A9,
|
||||
A10> > {
|
||||
typedef ::std::tr1::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4>,
|
||||
Matcher<A5>, Matcher<A6>, Matcher<A7>, Matcher<A8>, Matcher<A9>,
|
||||
Matcher<A10> > type;
|
||||
};
|
||||
|
||||
// Template struct Function<F>, where F must be a function type, contains
|
||||
// the following typedefs:
|
||||
//
|
||||
// Result: the function's return type.
|
||||
// ArgumentN: the type of the N-th argument, where N starts with 1.
|
||||
// ArgumentTuple: the tuple type consisting of all parameters of F.
|
||||
// ArgumentMatcherTuple: the tuple type consisting of Matchers for all
|
||||
// parameters of F.
|
||||
// MakeResultVoid: the function type obtained by substituting void
|
||||
// for the return type of F.
|
||||
// MakeResultIgnoredValue:
|
||||
// the function type obtained by substituting Something
|
||||
// for the return type of F.
|
||||
template <typename F>
|
||||
struct Function;
|
||||
|
||||
template <typename R>
|
||||
struct Function<R()> {
|
||||
typedef R Result;
|
||||
typedef ::std::tr1::tuple<> ArgumentTuple;
|
||||
typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
|
||||
typedef void MakeResultVoid();
|
||||
typedef IgnoredValue MakeResultIgnoredValue();
|
||||
};
|
||||
|
||||
template <typename R, typename A1>
|
||||
struct Function<R(A1)>
|
||||
: Function<R()> {
|
||||
typedef A1 Argument1;
|
||||
typedef ::std::tr1::tuple<A1> ArgumentTuple;
|
||||
typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
|
||||
typedef void MakeResultVoid(A1);
|
||||
typedef IgnoredValue MakeResultIgnoredValue(A1);
|
||||
};
|
||||
|
||||
template <typename R, typename A1, typename A2>
|
||||
struct Function<R(A1, A2)>
|
||||
: Function<R(A1)> {
|
||||
typedef A2 Argument2;
|
||||
typedef ::std::tr1::tuple<A1, A2> ArgumentTuple;
|
||||
typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
|
||||
typedef void MakeResultVoid(A1, A2);
|
||||
typedef IgnoredValue MakeResultIgnoredValue(A1, A2);
|
||||
};
|
||||
|
||||
template <typename R, typename A1, typename A2, typename A3>
|
||||
struct Function<R(A1, A2, A3)>
|
||||
: Function<R(A1, A2)> {
|
||||
typedef A3 Argument3;
|
||||
typedef ::std::tr1::tuple<A1, A2, A3> ArgumentTuple;
|
||||
typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
|
||||
typedef void MakeResultVoid(A1, A2, A3);
|
||||
typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3);
|
||||
};
|
||||
|
||||
template <typename R, typename A1, typename A2, typename A3, typename A4>
|
||||
struct Function<R(A1, A2, A3, A4)>
|
||||
: Function<R(A1, A2, A3)> {
|
||||
typedef A4 Argument4;
|
||||
typedef ::std::tr1::tuple<A1, A2, A3, A4> ArgumentTuple;
|
||||
typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
|
||||
typedef void MakeResultVoid(A1, A2, A3, A4);
|
||||
typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3, A4);
|
||||
};
|
||||
|
||||
template <typename R, typename A1, typename A2, typename A3, typename A4,
|
||||
typename A5>
|
||||
struct Function<R(A1, A2, A3, A4, A5)>
|
||||
: Function<R(A1, A2, A3, A4)> {
|
||||
typedef A5 Argument5;
|
||||
typedef ::std::tr1::tuple<A1, A2, A3, A4, A5> ArgumentTuple;
|
||||
typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
|
||||
typedef void MakeResultVoid(A1, A2, A3, A4, A5);
|
||||
typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3, A4, A5);
|
||||
};
|
||||
|
||||
template <typename R, typename A1, typename A2, typename A3, typename A4,
|
||||
typename A5, typename A6>
|
||||
struct Function<R(A1, A2, A3, A4, A5, A6)>
|
||||
: Function<R(A1, A2, A3, A4, A5)> {
|
||||
typedef A6 Argument6;
|
||||
typedef ::std::tr1::tuple<A1, A2, A3, A4, A5, A6> ArgumentTuple;
|
||||
typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
|
||||
typedef void MakeResultVoid(A1, A2, A3, A4, A5, A6);
|
||||
typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3, A4, A5, A6);
|
||||
};
|
||||
|
||||
template <typename R, typename A1, typename A2, typename A3, typename A4,
|
||||
typename A5, typename A6, typename A7>
|
||||
struct Function<R(A1, A2, A3, A4, A5, A6, A7)>
|
||||
: Function<R(A1, A2, A3, A4, A5, A6)> {
|
||||
typedef A7 Argument7;
|
||||
typedef ::std::tr1::tuple<A1, A2, A3, A4, A5, A6, A7> ArgumentTuple;
|
||||
typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
|
||||
typedef void MakeResultVoid(A1, A2, A3, A4, A5, A6, A7);
|
||||
typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3, A4, A5, A6, A7);
|
||||
};
|
||||
|
||||
template <typename R, typename A1, typename A2, typename A3, typename A4,
|
||||
typename A5, typename A6, typename A7, typename A8>
|
||||
struct Function<R(A1, A2, A3, A4, A5, A6, A7, A8)>
|
||||
: Function<R(A1, A2, A3, A4, A5, A6, A7)> {
|
||||
typedef A8 Argument8;
|
||||
typedef ::std::tr1::tuple<A1, A2, A3, A4, A5, A6, A7, A8> ArgumentTuple;
|
||||
typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
|
||||
typedef void MakeResultVoid(A1, A2, A3, A4, A5, A6, A7, A8);
|
||||
typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3, A4, A5, A6, A7, A8);
|
||||
};
|
||||
|
||||
template <typename R, typename A1, typename A2, typename A3, typename A4,
|
||||
typename A5, typename A6, typename A7, typename A8, typename A9>
|
||||
struct Function<R(A1, A2, A3, A4, A5, A6, A7, A8, A9)>
|
||||
: Function<R(A1, A2, A3, A4, A5, A6, A7, A8)> {
|
||||
typedef A9 Argument9;
|
||||
typedef ::std::tr1::tuple<A1, A2, A3, A4, A5, A6, A7, A8, A9> ArgumentTuple;
|
||||
typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
|
||||
typedef void MakeResultVoid(A1, A2, A3, A4, A5, A6, A7, A8, A9);
|
||||
typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3, A4, A5, A6, A7, A8,
|
||||
A9);
|
||||
};
|
||||
|
||||
template <typename R, typename A1, typename A2, typename A3, typename A4,
|
||||
typename A5, typename A6, typename A7, typename A8, typename A9,
|
||||
typename A10>
|
||||
struct Function<R(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10)>
|
||||
: Function<R(A1, A2, A3, A4, A5, A6, A7, A8, A9)> {
|
||||
typedef A10 Argument10;
|
||||
typedef ::std::tr1::tuple<A1, A2, A3, A4, A5, A6, A7, A8, A9,
|
||||
A10> ArgumentTuple;
|
||||
typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
|
||||
typedef void MakeResultVoid(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10);
|
||||
typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3, A4, A5, A6, A7, A8,
|
||||
A9, A10);
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
} // namespace testing
|
||||
|
||||
#endif // GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_GENERATED_INTERNAL_UTILS_H_
|
||||
@@ -0,0 +1,136 @@
|
||||
$$ -*- mode: c++; -*-
|
||||
$$ This is a Pump source file. Please use Pump to convert it to
|
||||
$$ gmock-generated-function-mockers.h.
|
||||
$$
|
||||
$var n = 10 $$ The maximum arity we support.
|
||||
// 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)
|
||||
|
||||
// Google Mock - a framework for writing C++ mock classes.
|
||||
//
|
||||
// This file contains template meta-programming utility classes needed
|
||||
// for implementing Google Mock.
|
||||
|
||||
#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>
|
||||
|
||||
namespace testing {
|
||||
|
||||
template <typename T>
|
||||
class Matcher;
|
||||
|
||||
namespace internal {
|
||||
|
||||
// An IgnoredValue object can be implicitly constructed from ANY value.
|
||||
// This is used in implementing the IgnoreResult(a) action.
|
||||
class IgnoredValue {
|
||||
public:
|
||||
// This constructor template allows any value to be implicitly
|
||||
// converted to IgnoredValue. The object has no data member and
|
||||
// doesn't try to remember anything about the argument. We
|
||||
// deliberately omit the 'explicit' keyword in order to allow the
|
||||
// conversion to be implicit.
|
||||
template <typename T>
|
||||
IgnoredValue(const T&) {}
|
||||
};
|
||||
|
||||
// MatcherTuple<T>::type is a tuple type where each field is a Matcher
|
||||
// for the corresponding field in tuple type T.
|
||||
template <typename Tuple>
|
||||
struct MatcherTuple;
|
||||
|
||||
|
||||
$range i 0..n
|
||||
$for i [[
|
||||
$range j 1..i
|
||||
$var typename_As = [[$for j, [[typename A$j]]]]
|
||||
$var As = [[$for j, [[A$j]]]]
|
||||
$var matcher_As = [[$for j, [[Matcher<A$j>]]]]
|
||||
template <$typename_As>
|
||||
struct MatcherTuple< ::std::tr1::tuple<$As> > {
|
||||
typedef ::std::tr1::tuple<$matcher_As > type;
|
||||
};
|
||||
|
||||
|
||||
]]
|
||||
// Template struct Function<F>, where F must be a function type, contains
|
||||
// the following typedefs:
|
||||
//
|
||||
// Result: the function's return type.
|
||||
// ArgumentN: the type of the N-th argument, where N starts with 1.
|
||||
// ArgumentTuple: the tuple type consisting of all parameters of F.
|
||||
// ArgumentMatcherTuple: the tuple type consisting of Matchers for all
|
||||
// parameters of F.
|
||||
// MakeResultVoid: the function type obtained by substituting void
|
||||
// for the return type of F.
|
||||
// MakeResultIgnoredValue:
|
||||
// the function type obtained by substituting Something
|
||||
// for the return type of F.
|
||||
template <typename F>
|
||||
struct Function;
|
||||
|
||||
template <typename R>
|
||||
struct Function<R()> {
|
||||
typedef R Result;
|
||||
typedef ::std::tr1::tuple<> ArgumentTuple;
|
||||
typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
|
||||
typedef void MakeResultVoid();
|
||||
typedef IgnoredValue MakeResultIgnoredValue();
|
||||
};
|
||||
|
||||
|
||||
$range i 1..n
|
||||
$for i [[
|
||||
$range j 1..i
|
||||
$var typename_As = [[$for j [[, typename A$j]]]]
|
||||
$var As = [[$for j, [[A$j]]]]
|
||||
$var matcher_As = [[$for j, [[Matcher<A$j>]]]]
|
||||
$range k 1..i-1
|
||||
$var prev_As = [[$for k, [[A$k]]]]
|
||||
template <typename R$typename_As>
|
||||
struct Function<R($As)>
|
||||
: Function<R($prev_As)> {
|
||||
typedef A$i Argument$i;
|
||||
typedef ::std::tr1::tuple<$As> ArgumentTuple;
|
||||
typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
|
||||
typedef void MakeResultVoid($As);
|
||||
typedef IgnoredValue MakeResultIgnoredValue($As);
|
||||
};
|
||||
|
||||
|
||||
]]
|
||||
} // namespace internal
|
||||
|
||||
} // namespace testing
|
||||
|
||||
#endif // GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_GENERATED_INTERNAL_UTILS_H_
|
||||
@@ -0,0 +1,484 @@
|
||||
// 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)
|
||||
|
||||
// Google Mock - a framework for writing C++ mock classes.
|
||||
//
|
||||
// This file defines some utilities useful for implementing Google
|
||||
// Mock. They are subject to change without notice, so please DO NOT
|
||||
// USE THEM IN USER CODE.
|
||||
|
||||
#ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_
|
||||
#define GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_
|
||||
|
||||
#include <stdio.h>
|
||||
#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__
|
||||
|
||||
class ProtocolMessage;
|
||||
namespace proto2 { class Message; }
|
||||
|
||||
namespace testing {
|
||||
namespace internal {
|
||||
|
||||
// Converts an identifier name to a space-separated list of lower-case
|
||||
// words. Each maximum substring of the form [A-Za-z][a-z]*|\d+ is
|
||||
// treated as one word. For example, both "FooBar123" and
|
||||
// "foo_bar_123" are converted to "foo bar 123".
|
||||
string ConvertIdentifierNameToWords(const char* id_name);
|
||||
|
||||
// Defining a variable of type CompileAssertTypesEqual<T1, T2> will cause a
|
||||
// compiler error iff T1 and T2 are different types.
|
||||
template <typename T1, typename T2>
|
||||
struct CompileAssertTypesEqual;
|
||||
|
||||
template <typename T>
|
||||
struct CompileAssertTypesEqual<T, T> {
|
||||
};
|
||||
|
||||
// Removes the reference from a type if it is a reference type,
|
||||
// otherwise leaves it unchanged. This is the same as
|
||||
// tr1::remove_reference, which is not widely available yet.
|
||||
template <typename T>
|
||||
struct RemoveReference { typedef T type; }; // NOLINT
|
||||
template <typename T>
|
||||
struct RemoveReference<T&> { typedef T type; }; // NOLINT
|
||||
|
||||
// A handy wrapper around RemoveReference that works when the argument
|
||||
// T depends on template parameters.
|
||||
#define GMOCK_REMOVE_REFERENCE_(T) \
|
||||
typename ::testing::internal::RemoveReference<T>::type
|
||||
|
||||
// Removes const from a type if it is a const type, otherwise leaves
|
||||
// it unchanged. This is the same as tr1::remove_const, which is not
|
||||
// widely available yet.
|
||||
template <typename T>
|
||||
struct RemoveConst { typedef T type; }; // NOLINT
|
||||
template <typename T>
|
||||
struct RemoveConst<const T> { typedef T type; }; // NOLINT
|
||||
|
||||
// A handy wrapper around RemoveConst that works when the argument
|
||||
// T depends on template parameters.
|
||||
#define GMOCK_REMOVE_CONST_(T) \
|
||||
typename ::testing::internal::RemoveConst<T>::type
|
||||
|
||||
// Adds reference to a type if it is not a reference type,
|
||||
// otherwise leaves it unchanged. This is the same as
|
||||
// tr1::add_reference, which is not widely available yet.
|
||||
template <typename T>
|
||||
struct AddReference { typedef T& type; }; // NOLINT
|
||||
template <typename T>
|
||||
struct AddReference<T&> { typedef T& type; }; // NOLINT
|
||||
|
||||
// A handy wrapper around AddReference that works when the argument T
|
||||
// depends on template parameters.
|
||||
#define GMOCK_ADD_REFERENCE_(T) \
|
||||
typename ::testing::internal::AddReference<T>::type
|
||||
|
||||
// Adds a reference to const on top of T as necessary. For example,
|
||||
// it transforms
|
||||
//
|
||||
// char ==> const char&
|
||||
// const char ==> const char&
|
||||
// char& ==> const char&
|
||||
// const char& ==> const char&
|
||||
//
|
||||
// The argument T must depend on some template parameters.
|
||||
#define GMOCK_REFERENCE_TO_CONST_(T) \
|
||||
GMOCK_ADD_REFERENCE_(const GMOCK_REMOVE_REFERENCE_(T))
|
||||
|
||||
// PointeeOf<Pointer>::type is the type of a value pointed to by a
|
||||
// Pointer, which can be either a smart pointer or a raw pointer. The
|
||||
// following default implementation is for the case where Pointer is a
|
||||
// smart pointer.
|
||||
template <typename Pointer>
|
||||
struct PointeeOf {
|
||||
// Smart pointer classes define type element_type as the type of
|
||||
// their pointees.
|
||||
typedef typename Pointer::element_type type;
|
||||
};
|
||||
// This specialization is for the raw pointer case.
|
||||
template <typename T>
|
||||
struct PointeeOf<T*> { typedef T type; }; // NOLINT
|
||||
|
||||
// GetRawPointer(p) returns the raw pointer underlying p when p is a
|
||||
// smart pointer, or returns p itself when p is already a raw pointer.
|
||||
// The following default implementation is for the smart pointer case.
|
||||
template <typename Pointer>
|
||||
inline typename Pointer::element_type* GetRawPointer(const Pointer& p) {
|
||||
return p.get();
|
||||
}
|
||||
// This overloaded version is for the raw pointer case.
|
||||
template <typename Element>
|
||||
inline Element* GetRawPointer(Element* p) { return p; }
|
||||
|
||||
// This comparator allows linked_ptr to be stored in sets.
|
||||
template <typename T>
|
||||
struct LinkedPtrLessThan {
|
||||
bool operator()(const ::testing::internal::linked_ptr<T>& lhs,
|
||||
const ::testing::internal::linked_ptr<T>& rhs) const {
|
||||
return lhs.get() < rhs.get();
|
||||
}
|
||||
};
|
||||
|
||||
// ImplicitlyConvertible<From, To>::value is a compile-time bool
|
||||
// constant that's true iff type From can be implicitly converted to
|
||||
// type To.
|
||||
template <typename From, typename To>
|
||||
class ImplicitlyConvertible {
|
||||
private:
|
||||
// We need the following helper functions only for their types.
|
||||
// They have no implementations.
|
||||
|
||||
// MakeFrom() is an expression whose type is From. We cannot simply
|
||||
// use From(), as the type From may not have a public default
|
||||
// constructor.
|
||||
static From MakeFrom();
|
||||
|
||||
// These two functions are overloaded. Given an expression
|
||||
// Helper(x), the compiler will pick the first version if x can be
|
||||
// implicitly converted to type To; otherwise it will pick the
|
||||
// second version.
|
||||
//
|
||||
// The first version returns a value of size 1, and the second
|
||||
// version returns a value of size 2. Therefore, by checking the
|
||||
// size of Helper(x), which can be done at compile time, we can tell
|
||||
// which version of Helper() is used, and hence whether x can be
|
||||
// implicitly converted to type To.
|
||||
static char Helper(To);
|
||||
static char (&Helper(...))[2]; // NOLINT
|
||||
|
||||
// We have to put the 'public' section after the 'private' section,
|
||||
// or MSVC refuses to compile the code.
|
||||
public:
|
||||
// MSVC warns about implicitly converting from double to int for
|
||||
// possible loss of data, so we need to temporarily disable the
|
||||
// warning.
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push) // Saves the current warning state.
|
||||
#pragma warning(disable:4244) // Temporarily disables warning 4244.
|
||||
static const bool value =
|
||||
sizeof(Helper(ImplicitlyConvertible::MakeFrom())) == 1;
|
||||
#pragma warning(pop) // Restores the warning state.
|
||||
#else
|
||||
static const bool value =
|
||||
sizeof(Helper(ImplicitlyConvertible::MakeFrom())) == 1;
|
||||
#endif // _MSV_VER
|
||||
};
|
||||
template <typename From, typename To>
|
||||
const bool ImplicitlyConvertible<From, To>::value;
|
||||
|
||||
// In what follows, we use the term "kind" to indicate whether a type
|
||||
// is bool, an integer type (excluding bool), a floating-point type,
|
||||
// or none of them. This categorization is useful for determining
|
||||
// when a matcher argument type can be safely converted to another
|
||||
// type in the implementation of SafeMatcherCast.
|
||||
enum TypeKind {
|
||||
kBool, kInteger, kFloatingPoint, kOther
|
||||
};
|
||||
|
||||
// KindOf<T>::value is the kind of type T.
|
||||
template <typename T> struct KindOf {
|
||||
enum { value = kOther }; // The default kind.
|
||||
};
|
||||
|
||||
// This macro declares that the kind of 'type' is 'kind'.
|
||||
#define GMOCK_DECLARE_KIND_(type, kind) \
|
||||
template <> struct KindOf<type> { enum { value = kind }; }
|
||||
|
||||
GMOCK_DECLARE_KIND_(bool, kBool);
|
||||
|
||||
// All standard integer types.
|
||||
GMOCK_DECLARE_KIND_(char, kInteger);
|
||||
GMOCK_DECLARE_KIND_(signed char, kInteger);
|
||||
GMOCK_DECLARE_KIND_(unsigned char, kInteger);
|
||||
GMOCK_DECLARE_KIND_(short, kInteger); // NOLINT
|
||||
GMOCK_DECLARE_KIND_(unsigned short, kInteger); // NOLINT
|
||||
GMOCK_DECLARE_KIND_(int, kInteger);
|
||||
GMOCK_DECLARE_KIND_(unsigned int, kInteger);
|
||||
GMOCK_DECLARE_KIND_(long, kInteger); // NOLINT
|
||||
GMOCK_DECLARE_KIND_(unsigned long, kInteger); // NOLINT
|
||||
|
||||
// MSVC can be configured to define wchar_t as a typedef of unsigned
|
||||
// short. It defines _NATIVE_WCHAR_T_DEFINED symbol when wchar_t is a
|
||||
// native type.
|
||||
#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED)
|
||||
GMOCK_DECLARE_KIND_(wchar_t, kInteger);
|
||||
#endif
|
||||
|
||||
// Non-standard integer types.
|
||||
GMOCK_DECLARE_KIND_(Int64, kInteger);
|
||||
GMOCK_DECLARE_KIND_(UInt64, kInteger);
|
||||
|
||||
// All standard floating-point types.
|
||||
GMOCK_DECLARE_KIND_(float, kFloatingPoint);
|
||||
GMOCK_DECLARE_KIND_(double, kFloatingPoint);
|
||||
GMOCK_DECLARE_KIND_(long double, kFloatingPoint);
|
||||
|
||||
#undef GMOCK_DECLARE_KIND_
|
||||
|
||||
// Evaluates to the kind of 'type'.
|
||||
#define GMOCK_KIND_OF_(type) \
|
||||
static_cast< ::testing::internal::TypeKind>( \
|
||||
::testing::internal::KindOf<type>::value)
|
||||
|
||||
// Evaluates to true iff integer type T is signed.
|
||||
#define GMOCK_IS_SIGNED_(T) (static_cast<T>(-1) < 0)
|
||||
|
||||
// LosslessArithmeticConvertibleImpl<kFromKind, From, kToKind, To>::value
|
||||
// is true iff arithmetic type From can be losslessly converted to
|
||||
// arithmetic type To.
|
||||
//
|
||||
// It's the user's responsibility to ensure that both From and To are
|
||||
// raw (i.e. has no CV modifier, is not a pointer, and is not a
|
||||
// reference) built-in arithmetic types, kFromKind is the kind of
|
||||
// From, and kToKind is the kind of To; the value is
|
||||
// implementation-defined when the above pre-condition is violated.
|
||||
template <TypeKind kFromKind, typename From, TypeKind kToKind, typename To>
|
||||
struct LosslessArithmeticConvertibleImpl : public false_type {};
|
||||
|
||||
// Converting bool to bool is lossless.
|
||||
template <>
|
||||
struct LosslessArithmeticConvertibleImpl<kBool, bool, kBool, bool>
|
||||
: public true_type {}; // NOLINT
|
||||
|
||||
// Converting bool to any integer type is lossless.
|
||||
template <typename To>
|
||||
struct LosslessArithmeticConvertibleImpl<kBool, bool, kInteger, To>
|
||||
: public true_type {}; // NOLINT
|
||||
|
||||
// Converting bool to any floating-point type is lossless.
|
||||
template <typename To>
|
||||
struct LosslessArithmeticConvertibleImpl<kBool, bool, kFloatingPoint, To>
|
||||
: public true_type {}; // NOLINT
|
||||
|
||||
// Converting an integer to bool is lossy.
|
||||
template <typename From>
|
||||
struct LosslessArithmeticConvertibleImpl<kInteger, From, kBool, bool>
|
||||
: public false_type {}; // NOLINT
|
||||
|
||||
// Converting an integer to another non-bool integer is lossless iff
|
||||
// the target type's range encloses the source type's range.
|
||||
template <typename From, typename To>
|
||||
struct LosslessArithmeticConvertibleImpl<kInteger, From, kInteger, To>
|
||||
: public bool_constant<
|
||||
// When converting from a smaller size to a larger size, we are
|
||||
// fine as long as we are not converting from signed to unsigned.
|
||||
((sizeof(From) < sizeof(To)) &&
|
||||
(!GMOCK_IS_SIGNED_(From) || GMOCK_IS_SIGNED_(To))) ||
|
||||
// When converting between the same size, the signedness must match.
|
||||
((sizeof(From) == sizeof(To)) &&
|
||||
(GMOCK_IS_SIGNED_(From) == GMOCK_IS_SIGNED_(To)))> {}; // NOLINT
|
||||
|
||||
#undef GMOCK_IS_SIGNED_
|
||||
|
||||
// Converting an integer to a floating-point type may be lossy, since
|
||||
// the format of a floating-point number is implementation-defined.
|
||||
template <typename From, typename To>
|
||||
struct LosslessArithmeticConvertibleImpl<kInteger, From, kFloatingPoint, To>
|
||||
: public false_type {}; // NOLINT
|
||||
|
||||
// Converting a floating-point to bool is lossy.
|
||||
template <typename From>
|
||||
struct LosslessArithmeticConvertibleImpl<kFloatingPoint, From, kBool, bool>
|
||||
: public false_type {}; // NOLINT
|
||||
|
||||
// Converting a floating-point to an integer is lossy.
|
||||
template <typename From, typename To>
|
||||
struct LosslessArithmeticConvertibleImpl<kFloatingPoint, From, kInteger, To>
|
||||
: public false_type {}; // NOLINT
|
||||
|
||||
// Converting a floating-point to another floating-point is lossless
|
||||
// iff the target type is at least as big as the source type.
|
||||
template <typename From, typename To>
|
||||
struct LosslessArithmeticConvertibleImpl<
|
||||
kFloatingPoint, From, kFloatingPoint, To>
|
||||
: public bool_constant<sizeof(From) <= sizeof(To)> {}; // NOLINT
|
||||
|
||||
// LosslessArithmeticConvertible<From, To>::value is true iff arithmetic
|
||||
// type From can be losslessly converted to arithmetic type To.
|
||||
//
|
||||
// It's the user's responsibility to ensure that both From and To are
|
||||
// raw (i.e. has no CV modifier, is not a pointer, and is not a
|
||||
// reference) built-in arithmetic types; the value is
|
||||
// implementation-defined when the above pre-condition is violated.
|
||||
template <typename From, typename To>
|
||||
struct LosslessArithmeticConvertible
|
||||
: public LosslessArithmeticConvertibleImpl<
|
||||
GMOCK_KIND_OF_(From), From, GMOCK_KIND_OF_(To), To> {}; // NOLINT
|
||||
|
||||
// IsAProtocolMessage<T>::value is a compile-time bool constant that's
|
||||
// true iff T is type ProtocolMessage, proto2::Message, or a subclass
|
||||
// of those.
|
||||
template <typename T>
|
||||
struct IsAProtocolMessage
|
||||
: public bool_constant<
|
||||
ImplicitlyConvertible<const T*, const ::ProtocolMessage*>::value ||
|
||||
ImplicitlyConvertible<const T*, const ::proto2::Message*>::value> {
|
||||
};
|
||||
|
||||
// When the compiler sees expression IsContainerTest<C>(0), the first
|
||||
// overload of IsContainerTest will be picked if C is an STL-style
|
||||
// container class (since C::const_iterator* is a valid type and 0 can
|
||||
// be converted to it), while the second overload will be picked
|
||||
// otherwise (since C::const_iterator will be an invalid type in this
|
||||
// case). Therefore, we can determine whether C is a container class
|
||||
// by checking the type of IsContainerTest<C>(0). The value of the
|
||||
// expression is insignificant.
|
||||
typedef int IsContainer;
|
||||
template <class C>
|
||||
IsContainer IsContainerTest(typename C::const_iterator*) { return 0; }
|
||||
|
||||
typedef char IsNotContainer;
|
||||
template <class C>
|
||||
IsNotContainer IsContainerTest(...) { return '\0'; }
|
||||
|
||||
// This interface knows how to report a Google Mock failure (either
|
||||
// non-fatal or fatal).
|
||||
class FailureReporterInterface {
|
||||
public:
|
||||
// The type of a failure (either non-fatal or fatal).
|
||||
enum FailureType {
|
||||
NONFATAL, FATAL
|
||||
};
|
||||
|
||||
virtual ~FailureReporterInterface() {}
|
||||
|
||||
// Reports a failure that occurred at the given source file location.
|
||||
virtual void ReportFailure(FailureType type, const char* file, int line,
|
||||
const string& message) = 0;
|
||||
};
|
||||
|
||||
// Returns the failure reporter used by Google Mock.
|
||||
FailureReporterInterface* GetFailureReporter();
|
||||
|
||||
// Asserts that condition is true; aborts the process with the given
|
||||
// message if condition is false. We cannot use LOG(FATAL) or CHECK()
|
||||
// as Google Mock might be used to mock the log sink itself. We
|
||||
// inline this function to prevent it from showing up in the stack
|
||||
// trace.
|
||||
inline void Assert(bool condition, const char* file, int line,
|
||||
const string& msg) {
|
||||
if (!condition) {
|
||||
GetFailureReporter()->ReportFailure(FailureReporterInterface::FATAL,
|
||||
file, line, msg);
|
||||
}
|
||||
}
|
||||
inline void Assert(bool condition, const char* file, int line) {
|
||||
Assert(condition, file, line, "Assertion failed.");
|
||||
}
|
||||
|
||||
// Verifies that condition is true; generates a non-fatal failure if
|
||||
// condition is false.
|
||||
inline void Expect(bool condition, const char* file, int line,
|
||||
const string& msg) {
|
||||
if (!condition) {
|
||||
GetFailureReporter()->ReportFailure(FailureReporterInterface::NONFATAL,
|
||||
file, line, msg);
|
||||
}
|
||||
}
|
||||
inline void Expect(bool condition, const char* file, int line) {
|
||||
Expect(condition, file, line, "Expectation failed.");
|
||||
}
|
||||
|
||||
// Severity level of a log.
|
||||
enum LogSeverity {
|
||||
INFO = 0,
|
||||
WARNING = 1,
|
||||
};
|
||||
|
||||
// Valid values for the --gmock_verbose flag.
|
||||
|
||||
// All logs (informational and warnings) are printed.
|
||||
const char kInfoVerbosity[] = "info";
|
||||
// Only warnings are printed.
|
||||
const char kWarningVerbosity[] = "warning";
|
||||
// No logs are printed.
|
||||
const char kErrorVerbosity[] = "error";
|
||||
|
||||
// Prints the given message to stdout iff 'severity' >= the level
|
||||
// specified by the --gmock_verbose flag. If stack_frames_to_skip >=
|
||||
// 0, also prints the stack trace excluding the top
|
||||
// stack_frames_to_skip frames. In opt mode, any positive
|
||||
// stack_frames_to_skip is treated as 0, since we don't know which
|
||||
// function calls will be inlined by the compiler and need to be
|
||||
// conservative.
|
||||
void Log(LogSeverity severity, const string& message, int stack_frames_to_skip);
|
||||
|
||||
// The universal value printer (public/gmock-printers.h) needs this
|
||||
// to declare an unused << operator in the global namespace.
|
||||
struct Unused {};
|
||||
|
||||
// TODO(wan@google.com): group all type utilities together.
|
||||
|
||||
// Type traits.
|
||||
|
||||
// is_reference<T>::value is non-zero iff T is a reference type.
|
||||
template <typename T> struct is_reference : public false_type {};
|
||||
template <typename T> struct is_reference<T&> : public true_type {};
|
||||
|
||||
// type_equals<T1, T2>::value is non-zero iff T1 and T2 are the same type.
|
||||
template <typename T1, typename T2> struct type_equals : public false_type {};
|
||||
template <typename T> struct type_equals<T, T> : public true_type {};
|
||||
|
||||
// remove_reference<T>::type removes the reference from type T, if any.
|
||||
template <typename T> struct remove_reference { typedef T type; }; // NOLINT
|
||||
template <typename T> struct remove_reference<T&> { typedef T type; }; // NOLINT
|
||||
|
||||
// Invalid<T>() returns an invalid value of type T. This is useful
|
||||
// when a value of type T is needed for compilation, but the statement
|
||||
// will not really be executed (or we don't care if the statement
|
||||
// crashes).
|
||||
template <typename T>
|
||||
inline T Invalid() {
|
||||
return *static_cast<typename remove_reference<T>::type*>(NULL);
|
||||
}
|
||||
template <>
|
||||
inline void Invalid<void>() {}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace testing
|
||||
|
||||
#endif // GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_
|
||||
@@ -0,0 +1,326 @@
|
||||
// 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.
|
||||
//
|
||||
// Author: vadimb@google.com (Vadim Berman)
|
||||
//
|
||||
// Low-level types and utilities for porting Google Mock to various
|
||||
// platforms. They are subject to change without notice. DO NOT USE
|
||||
// THEM IN USER CODE.
|
||||
|
||||
#ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_
|
||||
#define GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <iostream>
|
||||
|
||||
// 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>
|
||||
|
||||
// To avoid conditional compilation everywhere, we make it
|
||||
// gmock-port.h's responsibility to #include the header implementing
|
||||
// tr1/tuple.
|
||||
#if defined(__GNUC__) && GTEST_GCC_VER_ >= 40000
|
||||
// GTEST_GCC_VER_ is defined in gtest-port.h and 40000 corresponds to
|
||||
// version 4.0.0.
|
||||
// GCC 4.0+ implements tr1/tuple in the <tr1/tuple> header. This does
|
||||
// not conform to the TR1 spec, which requires the header to be <tuple>.
|
||||
#include <tr1/tuple>
|
||||
#elif defined(_MSC_VER) && _MSC_VER < 1500
|
||||
// For Visual Studio older than 2008, we redirect directly to boost tuple
|
||||
// searching from boost's root. This is to avoid extra dirtying of the
|
||||
// compiler include paths.
|
||||
#include "boost/tr1/tr1/tuple"
|
||||
#else
|
||||
// If the compiler is neither GCC 4.0+, nor Visual Studio 2008, we assume the
|
||||
// user is using a spec-conforming TR1 implementation.
|
||||
#include <tuple>
|
||||
#endif // __GNUC__
|
||||
|
||||
#if GTEST_OS_LINUX
|
||||
|
||||
// On some platforms, <regex.h> needs someone to define size_t, and
|
||||
// won't compile otherwise. We can #include it here as we already
|
||||
// included <stdlib.h>, which is guaranteed to define size_t through
|
||||
// <stddef.h>.
|
||||
#include <regex.h> // NOLINT
|
||||
|
||||
// Defines this iff Google Mock uses the enhanced POSIX regular
|
||||
// expression syntax. This is public as it affects how a user uses
|
||||
// regular expression matchers.
|
||||
#define GMOCK_USES_POSIX_RE 1
|
||||
|
||||
#endif // GTEST_OS_LINUX
|
||||
|
||||
#if defined(GMOCK_USES_PCRE) || defined(GMOCK_USES_POSIX_RE)
|
||||
// Defines this iff regular expression matchers are supported. This
|
||||
// is public as it tells a user whether he can use regular expression
|
||||
// matchers.
|
||||
#define GMOCK_HAS_REGEX 1
|
||||
#endif // defined(GMOCK_USES_PCRE) || defined(GMOCK_USES_POSIX_RE)
|
||||
|
||||
namespace testing {
|
||||
namespace internal {
|
||||
|
||||
// For Windows, check the compiler version. At least VS 2005 SP1 is
|
||||
// required to compile Google Mock.
|
||||
#if GTEST_OS_WINDOWS
|
||||
|
||||
#if _MSC_VER < 1400
|
||||
#error "At least Visual Studio 2005 SP1 is required to compile Google Mock."
|
||||
#elif _MSC_VER == 1400
|
||||
|
||||
// Unfortunately there is no unique _MSC_VER number for SP1. So for VS 2005
|
||||
// we have to check if it has SP1 by checking whether a bug fixed in SP1
|
||||
// is present. The bug in question is
|
||||
// http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=101702
|
||||
// where the compiler incorrectly reports sizeof(poiter to an array).
|
||||
|
||||
class TestForSP1 {
|
||||
private: // GCC complains if x_ is used by sizeof before defining it.
|
||||
static char x_[100];
|
||||
// VS 2005 RTM incorrectly reports sizeof(&x) as 100, and that value
|
||||
// is used to trigger 'invalid negative array size' error. If you
|
||||
// see this error, upgrade to VS 2005 SP1 since Google Mock will not
|
||||
// compile in VS 2005 RTM.
|
||||
static char Google_Mock_requires_Visual_Studio_2005_SP1_or_later_to_compile_[
|
||||
sizeof(&x_) != 100 ? 1 : -1];
|
||||
};
|
||||
|
||||
#endif // _MSC_VER
|
||||
#endif // GTEST_OS_WINDOWS
|
||||
|
||||
// Use implicit_cast as a safe version of static_cast or const_cast
|
||||
// for upcasting in the type hierarchy (i.e. casting a pointer to Foo
|
||||
// to a pointer to SuperclassOfFoo or casting a pointer to Foo to
|
||||
// a const pointer to Foo).
|
||||
// When you use implicit_cast, the compiler checks that the cast is safe.
|
||||
// Such explicit implicit_casts are necessary in surprisingly many
|
||||
// situations where C++ demands an exact type match instead of an
|
||||
// argument type convertable to a target type.
|
||||
//
|
||||
// The From type can be inferred, so the preferred syntax for using
|
||||
// implicit_cast is the same as for static_cast etc.:
|
||||
//
|
||||
// implicit_cast<ToType>(expr)
|
||||
//
|
||||
// implicit_cast would have been part of the C++ standard library,
|
||||
// but the proposal was submitted too late. It will probably make
|
||||
// its way into the language in the future.
|
||||
template<typename To, typename From>
|
||||
inline To implicit_cast(From const &f) {
|
||||
return f;
|
||||
}
|
||||
|
||||
// When you upcast (that is, cast a pointer from type Foo to type
|
||||
// SuperclassOfFoo), it's fine to use implicit_cast<>, 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
|
||||
// could be a bare Foo, or of type DifferentSubclassOfFoo. Thus,
|
||||
// when you downcast, you should use this macro. In debug mode, we
|
||||
// use dynamic_cast<> to double-check the downcast is legal (we die
|
||||
// if it's not). In normal mode, we do the efficient static_cast<>
|
||||
// instead. Thus, it's important to test in debug mode to make sure
|
||||
// the cast is legal!
|
||||
// This is the only place in the code we should use dynamic_cast<>.
|
||||
// In particular, you SHOULDN'T be using dynamic_cast<> in order to
|
||||
// do RTTI (eg code like this:
|
||||
// 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
|
||||
// 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) {
|
||||
implicit_cast<From*, To>(0);
|
||||
}
|
||||
|
||||
#if GTEST_HAS_RTTI
|
||||
assert(f == NULL || dynamic_cast<To>(f) != NULL); // RTTI: debug mode only!
|
||||
#endif
|
||||
return static_cast<To>(f);
|
||||
}
|
||||
|
||||
// The GMOCK_COMPILE_ASSERT_ macro can be used to verify that a compile time
|
||||
// expression is true. For example, you could use it to verify the
|
||||
// size of a static array:
|
||||
//
|
||||
// GMOCK_COMPILE_ASSERT_(ARRAYSIZE(content_type_names) == CONTENT_NUM_TYPES,
|
||||
// content_type_names_incorrect_size);
|
||||
//
|
||||
// or to make sure a struct is smaller than a certain size:
|
||||
//
|
||||
// GMOCK_COMPILE_ASSERT_(sizeof(foo) < 128, foo_too_large);
|
||||
//
|
||||
// The second argument to the macro is the name of the variable. If
|
||||
// the expression is false, most compilers will issue a warning/error
|
||||
// containing the name of the variable.
|
||||
|
||||
template <bool>
|
||||
struct CompileAssert {
|
||||
};
|
||||
|
||||
#define GMOCK_COMPILE_ASSERT_(expr, msg) \
|
||||
typedef ::testing::internal::CompileAssert<(bool(expr))> \
|
||||
msg[bool(expr) ? 1 : -1]
|
||||
|
||||
// Implementation details of GMOCK_COMPILE_ASSERT_:
|
||||
//
|
||||
// - GMOCK_COMPILE_ASSERT_ works by defining an array type that has -1
|
||||
// elements (and thus is invalid) when the expression is false.
|
||||
//
|
||||
// - The simpler definition
|
||||
//
|
||||
// #define GMOCK_COMPILE_ASSERT_(expr, msg) typedef char msg[(expr) ? 1 : -1]
|
||||
//
|
||||
// does not work, as gcc supports variable-length arrays whose sizes
|
||||
// are determined at run-time (this is gcc's extension and not part
|
||||
// of the C++ standard). As a result, gcc fails to reject the
|
||||
// following code with the simple definition:
|
||||
//
|
||||
// int foo;
|
||||
// GMOCK_COMPILE_ASSERT_(foo, msg); // not supposed to compile as foo is
|
||||
// // not a compile-time constant.
|
||||
//
|
||||
// - By using the type CompileAssert<(bool(expr))>, we ensures that
|
||||
// expr is a compile-time constant. (Template arguments must be
|
||||
// determined at compile-time.)
|
||||
//
|
||||
// - The outter parentheses in CompileAssert<(bool(expr))> are necessary
|
||||
// to work around a bug in gcc 3.4.4 and 4.0.1. If we had written
|
||||
//
|
||||
// CompileAssert<bool(expr)>
|
||||
//
|
||||
// instead, these compilers will refuse to compile
|
||||
//
|
||||
// GMOCK_COMPILE_ASSERT_(5 > 0, some_message);
|
||||
//
|
||||
// (They seem to think the ">" in "5 > 0" marks the end of the
|
||||
// template argument list.)
|
||||
//
|
||||
// - The array size is (bool(expr) ? 1 : -1), instead of simply
|
||||
//
|
||||
// ((expr) ? 1 : -1).
|
||||
//
|
||||
// This is to avoid running into a bug in MS VC 7.1, which
|
||||
// causes ((0.0) ? 1 : -1) to incorrectly evaluate to 1.
|
||||
|
||||
#if GTEST_HAS_GLOBAL_STRING
|
||||
typedef ::string string;
|
||||
#elif GTEST_HAS_STD_STRING
|
||||
typedef ::std::string string;
|
||||
#else
|
||||
#error "Google Mock requires ::std::string to compile."
|
||||
#endif // GTEST_HAS_GLOBAL_STRING
|
||||
|
||||
#if GTEST_HAS_GLOBAL_WSTRING
|
||||
typedef ::wstring wstring;
|
||||
#elif GTEST_HAS_STD_WSTRING
|
||||
typedef ::std::wstring wstring;
|
||||
#endif // GTEST_HAS_GLOBAL_WSTRING
|
||||
|
||||
// Prints the file location in the format native to the compiler.
|
||||
inline void FormatFileLocation(const char* file, int line, ::std::ostream* os) {
|
||||
if (file == NULL)
|
||||
file = "unknown file";
|
||||
if (line < 0) {
|
||||
*os << file << ":";
|
||||
} else {
|
||||
#if _MSC_VER
|
||||
*os << file << "(" << line << "):";
|
||||
#else
|
||||
*os << file << ":" << line << ":";
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
// INTERNAL IMPLEMENTATION - DO NOT USE.
|
||||
//
|
||||
// GMOCK_CHECK_ is an all mode assert. It aborts the program if the condition
|
||||
// is not satisfied.
|
||||
// Synopsys:
|
||||
// GMOCK_CHECK_(boolean_condition);
|
||||
// or
|
||||
// GMOCK_CHECK_(boolean_condition) << "Additional message";
|
||||
//
|
||||
// This checks the condition and if the condition is not satisfied
|
||||
// it prints message about the condition violation, including the
|
||||
// condition itself, plus additional message streamed into it, if any,
|
||||
// and then it aborts the program. It aborts the program irrespective of
|
||||
// whether it is built in the debug mode or not.
|
||||
|
||||
class GMockCheckProvider {
|
||||
public:
|
||||
GMockCheckProvider(const char* condition, const char* file, int line) {
|
||||
FormatFileLocation(file, line, &::std::cerr);
|
||||
::std::cerr << " ERROR: Condition " << condition << " failed. ";
|
||||
}
|
||||
~GMockCheckProvider() {
|
||||
::std::cerr << ::std::endl;
|
||||
abort();
|
||||
}
|
||||
::std::ostream& GetStream() { return ::std::cerr; }
|
||||
};
|
||||
#define GMOCK_CHECK_(condition) \
|
||||
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
|
||||
if (condition) \
|
||||
; \
|
||||
else \
|
||||
::testing::internal::GMockCheckProvider(\
|
||||
#condition, __FILE__, __LINE__).GetStream()
|
||||
|
||||
} // namespace internal
|
||||
} // namespace testing
|
||||
|
||||
// Macro for referencing flags. This is public as we want the user to
|
||||
// use this syntax to reference Google Mock flags.
|
||||
#define GMOCK_FLAG(name) FLAGS_gmock_##name
|
||||
|
||||
// Macros for declaring flags.
|
||||
#define GMOCK_DECLARE_bool_(name) extern bool GMOCK_FLAG(name)
|
||||
#define GMOCK_DECLARE_int32_(name) \
|
||||
extern ::testing::internal::Int32 GMOCK_FLAG(name)
|
||||
#define GMOCK_DECLARE_string_(name) \
|
||||
extern ::testing::internal::String GMOCK_FLAG(name)
|
||||
|
||||
// Macros for defining flags.
|
||||
#define GMOCK_DEFINE_bool_(name, default_val, doc) \
|
||||
bool GMOCK_FLAG(name) = (default_val)
|
||||
#define GMOCK_DEFINE_int32_(name, default_val, doc) \
|
||||
::testing::internal::Int32 GMOCK_FLAG(name) = (default_val)
|
||||
#define GMOCK_DEFINE_string_(name, default_val, doc) \
|
||||
::testing::internal::String GMOCK_FLAG(name) = (default_val)
|
||||
|
||||
#endif // GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_
|
||||
@@ -0,0 +1,326 @@
|
||||
// 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.
|
||||
//
|
||||
// Author: vadimb@google.com (Vadim Berman)
|
||||
//
|
||||
// Low-level types and utilities for porting Google Mock to various
|
||||
// platforms. They are subject to change without notice. DO NOT USE
|
||||
// THEM IN USER CODE.
|
||||
|
||||
#ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_
|
||||
#define GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <iostream>
|
||||
|
||||
// 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>
|
||||
|
||||
// To avoid conditional compilation everywhere, we make it
|
||||
// gmock-port.h's responsibility to #include the header implementing
|
||||
// tr1/tuple.
|
||||
#if defined(__GNUC__) && GTEST_GCC_VER_ >= 40000
|
||||
// GTEST_GCC_VER_ is defined in gtest-port.h and 40000 corresponds to
|
||||
// version 4.0.0.
|
||||
// GCC 4.0+ implements tr1/tuple in the <tr1/tuple> header. This does
|
||||
// not conform to the TR1 spec, which requires the header to be <tuple>.
|
||||
#include <tr1/tuple>
|
||||
#elif defined(_MSC_VER) && _MSC_VER < 1500
|
||||
// For Visual Studio older than 2008, we redirect directly to boost tuple
|
||||
// searching from boost's root. This is to avoid extra dirtying of the
|
||||
// compiler include paths.
|
||||
#include "boost/tr1/tr1/tuple"
|
||||
#else
|
||||
// If the compiler is not GCC 4.0+, or Visual Studio 2008, we assume the
|
||||
// user is using a spec-conforming TR1 implementation.
|
||||
#include <tuple>
|
||||
#endif // __GNUC__
|
||||
|
||||
#if GTEST_OS_LINUX
|
||||
|
||||
// On some platforms, <regex.h> needs someone to define size_t, and
|
||||
// won't compile otherwise. We can #include it here as we already
|
||||
// included <stdlib.h>, which is guaranteed to define size_t through
|
||||
// <stddef.h>.
|
||||
#include <regex.h> // NOLINT
|
||||
|
||||
// Defines this iff Google Mock uses the enhanced POSIX regular
|
||||
// expression syntax. This is public as it affects how a user uses
|
||||
// regular expression matchers.
|
||||
#define GMOCK_USES_POSIX_RE 1
|
||||
|
||||
#endif // GTEST_OS_LINUX
|
||||
|
||||
#if defined(GMOCK_USES_PCRE) || defined(GMOCK_USES_POSIX_RE)
|
||||
// Defines this iff regular expression matchers are supported. This
|
||||
// is public as it tells a user whether he can use regular expression
|
||||
// matchers.
|
||||
#define GMOCK_HAS_REGEX 1
|
||||
#endif // defined(GMOCK_USES_PCRE) || defined(GMOCK_USES_POSIX_RE)
|
||||
|
||||
namespace testing {
|
||||
namespace internal {
|
||||
|
||||
// For Windows, check the compiler version. At least VS 2005 SP1 is
|
||||
// required to compile Google Mock.
|
||||
#if GTEST_OS_WINDOWS
|
||||
|
||||
#if _MSC_VER < 1400
|
||||
#error "At least Visual Studio 2005 SP1 is required to compile Google Mock."
|
||||
#elif _MSC_VER == 1400
|
||||
|
||||
// Unfortunately there is no unique _MSC_VER number for SP1. So for VS 2005
|
||||
// we have to check if it has SP1 by checking whether a bug fixed in SP1
|
||||
// is present. The bug in question is
|
||||
// http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=101702
|
||||
// where the compiler incorrectly reports sizeof(poiter to an array).
|
||||
|
||||
class TestForSP1 {
|
||||
private: // GCC complains if x_ is used by sizeof before defining it.
|
||||
static char x_[100];
|
||||
// VS 2005 RTM incorrectly reports sizeof(&x) as 100, and that value
|
||||
// is used to trigger 'invalid negative array size' error. If you
|
||||
// see this error, upgrade to VS 2005 SP1 since Google Mock will not
|
||||
// compile in VS 2005 RTM.
|
||||
static char Google_Mock_requires_Visual_Studio_2005_SP1_or_later_to_compile_[
|
||||
sizeof(&x_) != 100 ? 1 : -1];
|
||||
};
|
||||
|
||||
#endif // _MSC_VER
|
||||
#endif // GTEST_OS_WINDOWS
|
||||
|
||||
// Use implicit_cast as a safe version of static_cast or const_cast
|
||||
// for upcasting in the type hierarchy (i.e. casting a pointer to Foo
|
||||
// to a pointer to SuperclassOfFoo or casting a pointer to Foo to
|
||||
// a const pointer to Foo).
|
||||
// When you use implicit_cast, the compiler checks that the cast is safe.
|
||||
// Such explicit implicit_casts are necessary in surprisingly many
|
||||
// situations where C++ demands an exact type match instead of an
|
||||
// argument type convertable to a target type.
|
||||
//
|
||||
// The From type can be inferred, so the preferred syntax for using
|
||||
// implicit_cast is the same as for static_cast etc.:
|
||||
//
|
||||
// implicit_cast<ToType>(expr)
|
||||
//
|
||||
// implicit_cast would have been part of the C++ standard library,
|
||||
// but the proposal was submitted too late. It will probably make
|
||||
// its way into the language in the future.
|
||||
template<typename To, typename From>
|
||||
inline To implicit_cast(From const &f) {
|
||||
return f;
|
||||
}
|
||||
|
||||
// When you upcast (that is, cast a pointer from type Foo to type
|
||||
// SuperclassOfFoo), it's fine to use implicit_cast<>, 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
|
||||
// could be a bare Foo, or of type DifferentSubclassOfFoo. Thus,
|
||||
// when you downcast, you should use this macro. In debug mode, we
|
||||
// use dynamic_cast<> to double-check the downcast is legal (we die
|
||||
// if it's not). In normal mode, we do the efficient static_cast<>
|
||||
// instead. Thus, it's important to test in debug mode to make sure
|
||||
// the cast is legal!
|
||||
// This is the only place in the code we should use dynamic_cast<>.
|
||||
// In particular, you SHOULDN'T be using dynamic_cast<> in order to
|
||||
// do RTTI (eg code like this:
|
||||
// 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
|
||||
// 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) {
|
||||
implicit_cast<From*, To>(0);
|
||||
}
|
||||
|
||||
#if GTEST_HAS_RTTI
|
||||
assert(f == NULL || dynamic_cast<To>(f) != NULL); // RTTI: debug mode only!
|
||||
#endif
|
||||
return static_cast<To>(f);
|
||||
}
|
||||
|
||||
// The GMOCK_COMPILE_ASSERT_ macro can be used to verify that a compile time
|
||||
// expression is true. For example, you could use it to verify the
|
||||
// size of a static array:
|
||||
//
|
||||
// GMOCK_COMPILE_ASSERT_(ARRAYSIZE(content_type_names) == CONTENT_NUM_TYPES,
|
||||
// content_type_names_incorrect_size);
|
||||
//
|
||||
// or to make sure a struct is smaller than a certain size:
|
||||
//
|
||||
// GMOCK_COMPILE_ASSERT_(sizeof(foo) < 128, foo_too_large);
|
||||
//
|
||||
// The second argument to the macro is the name of the variable. If
|
||||
// the expression is false, most compilers will issue a warning/error
|
||||
// containing the name of the variable.
|
||||
|
||||
template <bool>
|
||||
struct CompileAssert {
|
||||
};
|
||||
|
||||
#define GMOCK_COMPILE_ASSERT_(expr, msg) \
|
||||
typedef ::testing::internal::CompileAssert<(bool(expr))> \
|
||||
msg[bool(expr) ? 1 : -1]
|
||||
|
||||
// Implementation details of GMOCK_COMPILE_ASSERT_:
|
||||
//
|
||||
// - GMOCK_COMPILE_ASSERT_ works by defining an array type that has -1
|
||||
// elements (and thus is invalid) when the expression is false.
|
||||
//
|
||||
// - The simpler definition
|
||||
//
|
||||
// #define GMOCK_COMPILE_ASSERT_(expr, msg) typedef char msg[(expr) ? 1 : -1]
|
||||
//
|
||||
// does not work, as gcc supports variable-length arrays whose sizes
|
||||
// are determined at run-time (this is gcc's extension and not part
|
||||
// of the C++ standard). As a result, gcc fails to reject the
|
||||
// following code with the simple definition:
|
||||
//
|
||||
// int foo;
|
||||
// GMOCK_COMPILE_ASSERT_(foo, msg); // not supposed to compile as foo is
|
||||
// // not a compile-time constant.
|
||||
//
|
||||
// - By using the type CompileAssert<(bool(expr))>, we ensures that
|
||||
// expr is a compile-time constant. (Template arguments must be
|
||||
// determined at compile-time.)
|
||||
//
|
||||
// - The outter parentheses in CompileAssert<(bool(expr))> are necessary
|
||||
// to work around a bug in gcc 3.4.4 and 4.0.1. If we had written
|
||||
//
|
||||
// CompileAssert<bool(expr)>
|
||||
//
|
||||
// instead, these compilers will refuse to compile
|
||||
//
|
||||
// GMOCK_COMPILE_ASSERT_(5 > 0, some_message);
|
||||
//
|
||||
// (They seem to think the ">" in "5 > 0" marks the end of the
|
||||
// template argument list.)
|
||||
//
|
||||
// - The array size is (bool(expr) ? 1 : -1), instead of simply
|
||||
//
|
||||
// ((expr) ? 1 : -1).
|
||||
//
|
||||
// This is to avoid running into a bug in MS VC 7.1, which
|
||||
// causes ((0.0) ? 1 : -1) to incorrectly evaluate to 1.
|
||||
|
||||
#if GTEST_HAS_GLOBAL_STRING
|
||||
typedef ::string string;
|
||||
#elif GTEST_HAS_STD_STRING
|
||||
typedef ::std::string string;
|
||||
#else
|
||||
#error "Google Mock requires ::std::string to compile."
|
||||
#endif // GTEST_HAS_GLOBAL_STRING
|
||||
|
||||
#if GTEST_HAS_GLOBAL_WSTRING
|
||||
typedef ::wstring wstring;
|
||||
#elif GTEST_HAS_STD_WSTRING
|
||||
typedef ::std::wstring wstring;
|
||||
#endif // GTEST_HAS_GLOBAL_WSTRING
|
||||
|
||||
// Prints the file location in the format native to the compiler.
|
||||
inline void FormatFileLocation(const char* file, int line, ::std::ostream* os) {
|
||||
if (file == NULL)
|
||||
file = "unknown file";
|
||||
if (line < 0) {
|
||||
*os << file << ":";
|
||||
} else {
|
||||
#if _MSC_VER
|
||||
*os << file << "(" << line << "):";
|
||||
#else
|
||||
*os << file << ":" << line << ":";
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
// INTERNAL IMPLEMENTATION - DO NOT USE.
|
||||
//
|
||||
// GMOCK_CHECK_ is an all mode assert. It aborts the program if the condition
|
||||
// is not satisfied.
|
||||
// Synopsys:
|
||||
// GMOCK_CHECK_(boolean_condition);
|
||||
// or
|
||||
// GMOCK_CHECK_(boolean_condition) << "Additional message";
|
||||
//
|
||||
// This checks the condition and if the condition is not satisfied
|
||||
// it prints message about the condition violation, including the
|
||||
// condition itself, plus additional message streamed into it, if any,
|
||||
// and then it aborts the program. It aborts the program irrespective of
|
||||
// whether it is built in the debug mode or not.
|
||||
|
||||
class GMockCheckProvider {
|
||||
public:
|
||||
GMockCheckProvider(const char* condition, const char* file, int line) {
|
||||
FormatFileLocation(file, line, &::std::cerr);
|
||||
::std::cerr << " ERROR: Condition " << condition << " failed. ";
|
||||
}
|
||||
~GMockCheckProvider() {
|
||||
::std::cerr << ::std::endl;
|
||||
abort();
|
||||
}
|
||||
::std::ostream& GetStream() { return ::std::cerr; }
|
||||
};
|
||||
#define GMOCK_CHECK_(condition) \
|
||||
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
|
||||
if (condition) \
|
||||
; \
|
||||
else \
|
||||
::testing::internal::GMockCheckProvider(\
|
||||
#condition, __FILE__, __LINE__).GetStream()
|
||||
|
||||
} // namespace internal
|
||||
} // namespace testing
|
||||
|
||||
// Macro for referencing flags. This is public as we want the user to
|
||||
// use this syntax to reference Google Mock flags.
|
||||
#define GMOCK_FLAG(name) FLAGS_gmock_##name
|
||||
|
||||
// Macros for declaring flags.
|
||||
#define GMOCK_DECLARE_bool_(name) extern bool GMOCK_FLAG(name)
|
||||
#define GMOCK_DECLARE_int32_(name) \
|
||||
extern ::testing::internal::Int32 GMOCK_FLAG(name)
|
||||
#define GMOCK_DECLARE_string_(name) \
|
||||
extern ::testing::internal::String GMOCK_FLAG(name)
|
||||
|
||||
// Macros for defining flags.
|
||||
#define GMOCK_DEFINE_bool_(name, default_val, doc) \
|
||||
bool GMOCK_FLAG(name) = (default_val)
|
||||
#define GMOCK_DEFINE_int32_(name, default_val, doc) \
|
||||
::testing::internal::Int32 GMOCK_FLAG(name) = (default_val)
|
||||
#define GMOCK_DEFINE_string_(name, default_val, doc) \
|
||||
::testing::internal::String GMOCK_FLAG(name) = (default_val)
|
||||
|
||||
#endif // GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_
|
||||
@@ -0,0 +1,109 @@
|
||||
# A sample Makefile for building both Google Mock and Google Test and
|
||||
# using them in user tests. This file is self-contained, so you don't
|
||||
# need to use the Makefile in Google Test's source tree. Please tweak
|
||||
# it to suit your environment and project. You may want to move it to
|
||||
# your project's root directory.
|
||||
#
|
||||
# SYNOPSIS:
|
||||
#
|
||||
# make [all] - makes everything.
|
||||
# make TARGET - makes the given target.
|
||||
# make clean - removes all files generated by make.
|
||||
|
||||
# Please tweak the following variable definitions as needed by your
|
||||
# project, except GMOCK_HEADERS and GTEST_HEADERS, which you can use
|
||||
# in your own targets but shouldn't modify.
|
||||
|
||||
# Points to the root of Google Test, relative to where this file is.
|
||||
# Remember to tweak this if you move this file, or if you want to use
|
||||
# a copy of Google Test at a different location.
|
||||
GTEST_DIR = ../gtest
|
||||
|
||||
# Points to the root of Google Mock, relative to where this file is.
|
||||
# Remember to tweak this if you move this file.
|
||||
GMOCK_DIR = ..
|
||||
|
||||
# Where to find user code.
|
||||
USER_DIR = ../test
|
||||
|
||||
# Flags passed to the preprocessor.
|
||||
CPPFLAGS += -I$(GMOCK_DIR) -I$(GMOCK_DIR)/include \
|
||||
-I$(GTEST_DIR) -I$(GTEST_DIR)/include
|
||||
|
||||
# Flags passed to the C++ compiler.
|
||||
CXXFLAGS += -g -Wall -Wextra
|
||||
|
||||
# All tests produced by this Makefile. Remember to add new tests you
|
||||
# created to the list.
|
||||
TESTS = gmock_link_test gmock_test
|
||||
|
||||
# All Google Test headers. Usually you shouldn't change this
|
||||
# definition.
|
||||
GTEST_HEADERS = $(GTEST_DIR)/include/gtest/*.h \
|
||||
$(GTEST_DIR)/include/gtest/internal/*.h
|
||||
|
||||
# All Google Mock headers. Note that all Google Test headers are
|
||||
# included here too, as they are #included by Google Mock headers.
|
||||
# Usually you shouldn't change this definition.
|
||||
GMOCK_HEADERS = $(GMOCK_DIR)/include/gmock/*.h \
|
||||
$(GMOCK_DIR)/include/gmock/internal/*.h \
|
||||
$(GTEST_HEADERS)
|
||||
|
||||
# House-keeping build targets.
|
||||
|
||||
all : $(TESTS)
|
||||
|
||||
clean :
|
||||
rm -f $(TESTS) gmock.a gmock_main.a *.o
|
||||
|
||||
# Builds gmock.a and gmock_main.a. These libraries contain both
|
||||
# Google Mock and Google Test. A test should link with either gmock.a
|
||||
# or gmock_main.a, depending on whether it defines its own main()
|
||||
# function. It's fine if your test only uses features from Google
|
||||
# Test (and not Google Mock).
|
||||
|
||||
# Usually you shouldn't tweak such internal variables, indicated by a
|
||||
# trailing _.
|
||||
GTEST_SRCS_ = $(GTEST_DIR)/src/*.cc $(GTEST_DIR)/src/*.h $(GTEST_HEADERS)
|
||||
GMOCK_SRCS_ = $(GMOCK_DIR)/src/*.cc $(GMOCK_HEADERS)
|
||||
|
||||
# For simplicity and to avoid depending on implementation details of
|
||||
# Google Mock and Google Test, the dependencies specified below are
|
||||
# conservative and not optimized. This is fine as Google Mock and
|
||||
# Google Test compile fast and for ordinary users their source rarely
|
||||
# changes.
|
||||
gtest-all.o : $(GTEST_SRCS_)
|
||||
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(GTEST_DIR)/src/gtest-all.cc
|
||||
|
||||
gmock-all.o : $(GMOCK_SRCS_)
|
||||
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(GMOCK_DIR)/src/gmock-all.cc
|
||||
|
||||
gmock_main.o : $(GMOCK_SRCS_)
|
||||
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(GMOCK_DIR)/src/gmock_main.cc
|
||||
|
||||
gmock.a : gmock-all.o gtest-all.o
|
||||
$(AR) $(ARFLAGS) $@ $^
|
||||
|
||||
gmock_main.a : gmock-all.o gtest-all.o gmock_main.o
|
||||
$(AR) $(ARFLAGS) $@ $^
|
||||
|
||||
# Builds a sample test.
|
||||
|
||||
gmock_link_test.o : $(USER_DIR)/gmock_link_test.cc \
|
||||
$(USER_DIR)/gmock_link_test.h $(GMOCK_HEADERS)
|
||||
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/gmock_link_test.cc
|
||||
|
||||
gmock_link2_test.o : $(USER_DIR)/gmock_link2_test.cc \
|
||||
$(USER_DIR)/gmock_link_test.h $(GMOCK_HEADERS)
|
||||
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/gmock_link2_test.cc
|
||||
|
||||
gmock_link_test : gmock_link_test.o gmock_link2_test.o gmock_main.a
|
||||
$(CXX) $(CPPFLAGS) $(CXXFLAGS) $^ -o $@
|
||||
|
||||
# Builds another sample test.
|
||||
|
||||
gmock_test.o : $(USER_DIR)/gmock_test.cc $(GMOCK_HEADERS)
|
||||
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/gmock_test.cc
|
||||
|
||||
gmock_test : gmock_test.o gmock_main.a
|
||||
$(CXX) $(CPPFLAGS) $(CXXFLAGS) $^ -o $@
|
||||
Arquivo executável
+205
@@ -0,0 +1,205 @@
|
||||
<?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>
|
||||
@@ -0,0 +1,50 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 9.00
|
||||
# Visual Studio 2005
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gmock", "gmock.vcproj", "{34681F0D-CE45-415D-B5F2-5C662DFE3BD5}"
|
||||
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_output_test_", "gmock_output_test_.vcproj", "{EDCE4C87-C2C0-4D22-98AC-7B6466F89A15}"
|
||||
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
|
||||
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
|
||||
{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
|
||||
{EDCE4C87-C2C0-4D22-98AC-7B6466F89A15}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{EDCE4C87-C2C0-4D22-98AC-7B6466F89A15}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{EDCE4C87-C2C0-4D22-98AC-7B6466F89A15}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{EDCE4C87-C2C0-4D22-98AC-7B6466F89A15}.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
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@@ -0,0 +1,263 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="8.00"
|
||||
Name="gmock"
|
||||
ProjectGUID="{34681F0D-CE45-415D-B5F2-5C662DFE3BD5}"
|
||||
RootNamespace="gmock"
|
||||
Keyword="Win32Proj"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(OutDir)\$(ProjectName)"
|
||||
ConfigurationType="4"
|
||||
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;_LIB"
|
||||
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="VCLibrarianTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(OutDir)\$(ProjectName)"
|
||||
ConfigurationType="4"
|
||||
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;_LIB"
|
||||
RuntimeLibrary="0"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="true"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</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="..\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"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="$(GTestDir)\src\gtest-all.cc"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories="$(GTestDir)"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories="$(GTestDir)"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Public Header Files"
|
||||
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>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioPropertySheet
|
||||
ProjectType="Visual C++"
|
||||
Version="8.00"
|
||||
Name="gmock_config"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""$(BoostDir)/boost/tr1/tr1";"$(BoostDir)";"$(GTestDir)/include""
|
||||
PreprocessorDefinitions="GTEST_HAS_TR1_TUPLE=1"
|
||||
/>
|
||||
<UserMacro
|
||||
Name="GTestDir"
|
||||
Value="../gtest"
|
||||
/>
|
||||
<UserMacro
|
||||
Name="BoostDir"
|
||||
Value="../boost"
|
||||
/>
|
||||
</VisualStudioPropertySheet>
|
||||
@@ -0,0 +1,203 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="8.00"
|
||||
Name="gmock_link_test"
|
||||
ProjectGUID="{ED597847-A714-4327-B569-70029D2311F0}"
|
||||
RootNamespace="gmock_link_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_link2_test.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\test\gmock_link_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>
|
||||
@@ -0,0 +1,187 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="8.00"
|
||||
Name="gmock_main"
|
||||
ProjectGUID="{E4EF614B-30DF-4954-8C53-580A0BF6B589}"
|
||||
RootNamespace="gmock_main"
|
||||
Keyword="Win32Proj"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(OutDir)\$(ProjectName)"
|
||||
ConfigurationType="4"
|
||||
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;_LIB"
|
||||
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="VCLibrarianTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(OutDir)\$(ProjectName)"
|
||||
ConfigurationType="4"
|
||||
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;_LIB"
|
||||
RuntimeLibrary="0"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="true"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<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="..\src\gmock_main.cc"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories="../include"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</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>
|
||||
@@ -0,0 +1,199 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="8.00"
|
||||
Name="gmock_output_test_"
|
||||
ProjectGUID="{EDCE4C87-C2C0-4D22-98AC-7B6466F89A15}"
|
||||
RootNamespace="gmock_output_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="{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_output_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>
|
||||
@@ -0,0 +1,243 @@
|
||||
<?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>
|
||||
Arquivo executável
+240
@@ -0,0 +1,240 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright 2009, 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.
|
||||
|
||||
"""fuse_gmock_files.py v0.1.0
|
||||
Fuses Google Mock and Google Test source code into two .h files and a .cc file.
|
||||
|
||||
SYNOPSIS
|
||||
fuse_gmock_files.py [GMOCK_ROOT_DIR] OUTPUT_DIR
|
||||
|
||||
Scans GMOCK_ROOT_DIR for Google Mock and Google Test source
|
||||
code, assuming Google Test is in the GMOCK_ROOT_DIR/gtest
|
||||
sub-directory, and generates three files:
|
||||
OUTPUT_DIR/gtest/gtest.h, OUTPUT_DIR/gmock/gmock.h, and
|
||||
OUTPUT_DIR/gmock-gtest-all.cc. Then you can build your tests
|
||||
by adding OUTPUT_DIR to the include search path and linking
|
||||
with OUTPUT_DIR/gmock-gtest-all.cc. These three files contain
|
||||
everything you need to use Google Mock. Hence you can
|
||||
"install" Google Mock by copying them to wherever you want.
|
||||
|
||||
GMOCK_ROOT_DIR can be omitted and defaults to the parent
|
||||
directory of the directory holding this script.
|
||||
|
||||
EXAMPLES
|
||||
./fuse_gmock_files.py fused_gmock
|
||||
./fuse_gmock_files.py path/to/unpacked/gmock fused_gmock
|
||||
|
||||
This tool is experimental. In particular, it assumes that there is no
|
||||
conditional inclusion of Google Mock or Google Test headers. Please
|
||||
report any problems to googlemock@googlegroups.com. You can read
|
||||
http://code.google.com/p/googlemock/wiki/CookBook for more
|
||||
information.
|
||||
"""
|
||||
|
||||
__author__ = 'wan@google.com (Zhanyong Wan)'
|
||||
|
||||
import os
|
||||
import re
|
||||
import sets
|
||||
import sys
|
||||
|
||||
# We assume that this file is in the scripts/ directory in the Google
|
||||
# Mock root directory.
|
||||
DEFAULT_GMOCK_ROOT_DIR = os.path.join(os.path.dirname(__file__), '..')
|
||||
|
||||
# We need to call into gtest/scripts/fuse_gtest_files.py.
|
||||
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/.+)>')
|
||||
|
||||
# Where to find the source seed files.
|
||||
GMOCK_H_SEED = 'include/gmock/gmock.h'
|
||||
GMOCK_ALL_CC_SEED = 'src/gmock-all.cc'
|
||||
|
||||
# Where to put the generated files.
|
||||
GTEST_H_OUTPUT = 'gtest/gtest.h'
|
||||
GMOCK_H_OUTPUT = 'gmock/gmock.h'
|
||||
GMOCK_GTEST_ALL_CC_OUTPUT = 'gmock-gtest-all.cc'
|
||||
|
||||
|
||||
def GetGTestRootDir(gmock_root):
|
||||
"""Returns the root directory of Google Test."""
|
||||
|
||||
return os.path.join(gmock_root, 'gtest')
|
||||
|
||||
|
||||
def ValidateGMockRootDir(gmock_root):
|
||||
"""Makes sure gmock_root points to a valid gmock root directory.
|
||||
|
||||
The function aborts the program on failure.
|
||||
"""
|
||||
|
||||
gtest.ValidateGTestRootDir(GetGTestRootDir(gmock_root))
|
||||
gtest.VerifyFileExists(gmock_root, GMOCK_H_SEED)
|
||||
gtest.VerifyFileExists(gmock_root, GMOCK_ALL_CC_SEED)
|
||||
|
||||
|
||||
def ValidateOutputDir(output_dir):
|
||||
"""Makes sure output_dir points to a valid output directory.
|
||||
|
||||
The function aborts the program on failure.
|
||||
"""
|
||||
|
||||
gtest.VerifyOutputFile(output_dir, gtest.GTEST_H_OUTPUT)
|
||||
gtest.VerifyOutputFile(output_dir, GMOCK_H_OUTPUT)
|
||||
gtest.VerifyOutputFile(output_dir, GMOCK_GTEST_ALL_CC_OUTPUT)
|
||||
|
||||
|
||||
def FuseGMockH(gmock_root, output_dir):
|
||||
"""Scans folder gmock_root to generate gmock/gmock.h in output_dir."""
|
||||
|
||||
output_file = file(os.path.join(output_dir, GMOCK_H_OUTPUT), 'w')
|
||||
processed_files = sets.Set() # Holds all gmock headers we've processed.
|
||||
|
||||
def ProcessFile(gmock_header_path):
|
||||
"""Processes the given gmock header file."""
|
||||
|
||||
# We don't process the same header twice.
|
||||
if gmock_header_path in processed_files:
|
||||
return
|
||||
|
||||
processed_files.add(gmock_header_path)
|
||||
|
||||
# Reads each line in the given gmock header.
|
||||
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.
|
||||
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
|
||||
# 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,))
|
||||
else:
|
||||
# Otherwise we copy the line unchanged to the output file.
|
||||
output_file.write(line)
|
||||
|
||||
ProcessFile(GMOCK_H_SEED)
|
||||
output_file.close()
|
||||
|
||||
|
||||
def FuseGMockAllCcToFile(gmock_root, output_file):
|
||||
"""Scans folder gmock_root to fuse gmock-all.cc into output_file."""
|
||||
|
||||
processed_files = sets.Set()
|
||||
|
||||
def ProcessFile(gmock_source_file):
|
||||
"""Processes the given gmock source file."""
|
||||
|
||||
# We don't process the same #included file twice.
|
||||
if gmock_source_file in processed_files:
|
||||
return
|
||||
|
||||
processed_files.add(gmock_source_file)
|
||||
|
||||
# Reads each line in the given gmock source 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
|
||||
# into gmock.h and cannot be #included directly.
|
||||
|
||||
# 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,))
|
||||
else:
|
||||
m = gtest.INCLUDE_GTEST_FILE_REGEX.match(line)
|
||||
if m:
|
||||
# It's '#include <gtest/...>'.
|
||||
# There is no need to #include gtest.h as it has been
|
||||
# #included by gtest-all.cc.
|
||||
pass
|
||||
else:
|
||||
m = gtest.INCLUDE_SRC_FILE_REGEX.match(line)
|
||||
if m:
|
||||
# It's '#include "src/foo"' - let's process it recursively.
|
||||
ProcessFile(m.group(1))
|
||||
else:
|
||||
# Otherwise we copy the line unchanged to the output file.
|
||||
output_file.write(line)
|
||||
|
||||
ProcessFile(GMOCK_ALL_CC_SEED)
|
||||
|
||||
|
||||
def FuseGMockGTestAllCc(gmock_root, output_dir):
|
||||
"""Scans folder gmock_root to generate gmock-gtest-all.cc in output_dir."""
|
||||
|
||||
output_file = file(os.path.join(output_dir, GMOCK_GTEST_ALL_CC_OUTPUT), 'w')
|
||||
# First, fuse gtest-all.cc into gmock-gtest-all.cc.
|
||||
gtest.FuseGTestAllCcToFile(GetGTestRootDir(gmock_root), output_file)
|
||||
# Next, append fused gmock-all.cc to gmock-gtest-all.cc.
|
||||
FuseGMockAllCcToFile(gmock_root, output_file)
|
||||
output_file.close()
|
||||
|
||||
|
||||
def FuseGMock(gmock_root, output_dir):
|
||||
"""Fuses gtest.h, gmock.h, and gmock-gtest-all.h."""
|
||||
|
||||
ValidateGMockRootDir(gmock_root)
|
||||
ValidateOutputDir(output_dir)
|
||||
|
||||
gtest.FuseGTestH(GetGTestRootDir(gmock_root), output_dir)
|
||||
FuseGMockH(gmock_root, output_dir)
|
||||
FuseGMockGTestAllCc(gmock_root, output_dir)
|
||||
|
||||
|
||||
def main():
|
||||
argc = len(sys.argv)
|
||||
if argc == 2:
|
||||
# fuse_gmock_files.py OUTPUT_DIR
|
||||
FuseGMock(DEFAULT_GMOCK_ROOT_DIR, sys.argv[1])
|
||||
elif argc == 3:
|
||||
# fuse_gmock_files.py GMOCK_ROOT_DIR OUTPUT_DIR
|
||||
FuseGMock(sys.argv[1], sys.argv[2])
|
||||
else:
|
||||
print __doc__
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -0,0 +1,203 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [2007] Neal Norwitz
|
||||
Portions Copyright [2007] Google Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
@@ -0,0 +1,35 @@
|
||||
|
||||
The Google Mock class generator is an application that is part of cppclean.
|
||||
For more information about cppclean, see the README.cppclean file or
|
||||
visit http://code.google.com/p/cppclean/
|
||||
|
||||
cppclean requires Python 2.3.5 or later. If you don't have Python installed
|
||||
on your system, you will also need to install it. You can download Python
|
||||
from: http://www.python.org/download/releases/
|
||||
|
||||
To use the Google Mock class generator, you need to call it
|
||||
on the command line passing the header file and class for which you want
|
||||
to generate a Google Mock class.
|
||||
|
||||
Make sure to install the scripts somewhere in your path. Then you can
|
||||
run the program.
|
||||
|
||||
gmock_gen.py header-file.h [ClassName]...
|
||||
|
||||
If no ClassNames are specified, all classes in the file are emitted.
|
||||
|
||||
To change the indentation from the default of 2, set INDENT in
|
||||
the environment. For example to use an indent of 4 spaces:
|
||||
|
||||
INDENT=4 gmock_gen.py header-file.h ClassName
|
||||
|
||||
This version was made from SVN revision 279 in the cppclean repository.
|
||||
|
||||
Known Limitations
|
||||
-----------------
|
||||
Not all code will be generated properly. For example, when mocking templated
|
||||
classes, the template information is lost. You will need to add the template
|
||||
information manually.
|
||||
|
||||
Not all permutations of using multiple pointers/references will be rendered
|
||||
properly. These will also have to be fixed manually.
|
||||
@@ -0,0 +1,115 @@
|
||||
Goal:
|
||||
-----
|
||||
CppClean attempts to find problems in C++ source that slow development
|
||||
in large code bases, for example various forms of unused code.
|
||||
Unused code can be unused functions, methods, data members, types, etc
|
||||
to unnecessary #include directives. Unnecessary #includes can cause
|
||||
considerable extra compiles increasing the edit-compile-run cycle.
|
||||
|
||||
The project home page is: http://code.google.com/p/cppclean/
|
||||
|
||||
|
||||
Features:
|
||||
---------
|
||||
* Find and print C++ language constructs: classes, methods, functions, etc.
|
||||
* Find classes with virtual methods, no virtual destructor, and no bases
|
||||
* Find global/static data that are potential problems when using threads
|
||||
* Unnecessary forward class declarations
|
||||
* Unnecessary function declarations
|
||||
* Undeclared function definitions
|
||||
* (planned) Find unnecessary header files #included
|
||||
- No direct reference to anything in the header
|
||||
- Header is unnecessary if classes were forward declared instead
|
||||
* (planned) Source files that reference headers not directly #included,
|
||||
ie, files that rely on a transitive #include from another header
|
||||
* (planned) Unused members (private, protected, & public) methods and data
|
||||
* (planned) Store AST in a SQL database so relationships can be queried
|
||||
|
||||
AST is Abstract Syntax Tree, a representation of parsed source code.
|
||||
http://en.wikipedia.org/wiki/Abstract_syntax_tree
|
||||
|
||||
|
||||
System Requirements:
|
||||
--------------------
|
||||
* Python 2.4 or later (2.3 probably works too)
|
||||
* Works on Windows (untested), Mac OS X, and Unix
|
||||
|
||||
|
||||
How to Run:
|
||||
-----------
|
||||
For all examples, it is assumed that cppclean resides in a directory called
|
||||
/cppclean.
|
||||
|
||||
To print warnings for classes with virtual methods, no virtual destructor and
|
||||
no base classes:
|
||||
|
||||
/cppclean/run.sh nonvirtual_dtors.py file1.h file2.h file3.cc ...
|
||||
|
||||
To print all the functions defined in header file(s):
|
||||
|
||||
/cppclean/run.sh functions.py file1.h file2.h ...
|
||||
|
||||
All the commands take multiple files on the command line. Other programs
|
||||
include: find_warnings, headers, methods, and types. Some other programs
|
||||
are available, but used primarily for debugging.
|
||||
|
||||
run.sh is a simple wrapper that sets PYTHONPATH to /cppclean and then
|
||||
runs the program in /cppclean/cpp/PROGRAM.py. There is currently
|
||||
no equivalent for Windows. Contributions for a run.bat file
|
||||
would be greatly appreciated.
|
||||
|
||||
|
||||
How to Configure:
|
||||
-----------------
|
||||
You can add a siteheaders.py file in /cppclean/cpp to configure where
|
||||
to look for other headers (typically -I options passed to a compiler).
|
||||
Currently two values are supported: _TRANSITIVE and GetIncludeDirs.
|
||||
_TRANSITIVE should be set to a boolean value (True or False) indicating
|
||||
whether to transitively process all header files. The default is False.
|
||||
|
||||
GetIncludeDirs is a function that takes a single argument and returns
|
||||
a sequence of directories to include. This can be a generator or
|
||||
return a static list.
|
||||
|
||||
def GetIncludeDirs(filename):
|
||||
return ['/some/path/with/other/headers']
|
||||
|
||||
# Here is a more complicated example.
|
||||
def GetIncludeDirs(filename):
|
||||
yield '/path1'
|
||||
yield os.path.join('/path2', os.path.dirname(filename))
|
||||
yield '/path3'
|
||||
|
||||
|
||||
How to Test:
|
||||
------------
|
||||
For all examples, it is assumed that cppclean resides in a directory called
|
||||
/cppclean. The tests require
|
||||
|
||||
cd /cppclean
|
||||
make test
|
||||
# To generate expected results after a change:
|
||||
make expected
|
||||
|
||||
|
||||
Current Status:
|
||||
---------------
|
||||
The parser works pretty well for header files, parsing about 99% of Google's
|
||||
header files. Anything which inspects structure of C++ source files should
|
||||
work reasonably well. Function bodies are not transformed to an AST,
|
||||
but left as tokens. Much work is still needed on finding unused header files
|
||||
and storing an AST in a database.
|
||||
|
||||
|
||||
Non-goals:
|
||||
----------
|
||||
* Parsing all valid C++ source
|
||||
* Handling invalid C++ source gracefully
|
||||
* Compiling to machine code (or anything beyond an AST)
|
||||
|
||||
|
||||
Contact:
|
||||
--------
|
||||
If you used cppclean, I would love to hear about your experiences
|
||||
cppclean@googlegroups.com. Even if you don't use cppclean, I'd like to
|
||||
hear from you. :-) (You can contact me directly at: nnorwitz@gmail.com)
|
||||
Arquivo executável
Arquivo executável
+1713
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
Arquivo executável
+171
@@ -0,0 +1,171 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright 2008 Google Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
"""Generate Google Mock classes from base classes.
|
||||
|
||||
This program will read in a C++ source file and output the Google Mock
|
||||
classes for the specified classes. If no class is specified, all
|
||||
classes in the source file are emitted.
|
||||
|
||||
Usage:
|
||||
gmock_class.py header-file.h [ClassName]...
|
||||
|
||||
Output is sent to stdout.
|
||||
"""
|
||||
|
||||
__author__ = 'nnorwitz@google.com (Neal Norwitz)'
|
||||
|
||||
|
||||
import os
|
||||
import re
|
||||
import sets
|
||||
import sys
|
||||
|
||||
from cpp import ast
|
||||
from cpp import utils
|
||||
|
||||
_VERSION = (1, 0, 1) # The version of this script.
|
||||
# How many spaces to indent. Can set me with the INDENT environment variable.
|
||||
_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
|
||||
|
||||
for node in class_node.body:
|
||||
# We only care about virtual functions.
|
||||
if (isinstance(node, ast.Function) and
|
||||
node.modifiers & function_type and
|
||||
not node.modifiers & ctor_or_dtor):
|
||||
# Pick out all the elements we need from the original function.
|
||||
const = ''
|
||||
if node.modifiers & ast.FUNCTION_CONST:
|
||||
const = 'CONST_'
|
||||
return_type = 'void'
|
||||
if node.return_type:
|
||||
# Add modifiers like 'const'.
|
||||
modifiers = ''
|
||||
if node.return_type.modifiers:
|
||||
modifiers = ' '.join(node.return_type.modifiers) + ' '
|
||||
return_type = modifiers + node.return_type.name
|
||||
if node.return_type.pointer:
|
||||
return_type += '*'
|
||||
if node.return_type.reference:
|
||||
return_type += '&'
|
||||
prefix = 'MOCK_%sMETHOD%d' % (const, len(node.parameters))
|
||||
args = ''
|
||||
if node.parameters:
|
||||
# Get the full text of the parameters from the start
|
||||
# of the first parameter to the end of the last parameter.
|
||||
start = node.parameters[0].start
|
||||
end = node.parameters[-1].end
|
||||
args = re.sub(' +', ' ', source[start:end].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)
|
||||
|
||||
|
||||
def _GenerateMocks(filename, source, ast_list, desired_class_names):
|
||||
processed_class_names = sets.Set()
|
||||
lines = []
|
||||
for node in ast_list:
|
||||
if (isinstance(node, ast.Class) and node.body and
|
||||
# desired_class_names being None means that all classes are selected.
|
||||
(not desired_class_names or node.name in desired_class_names)):
|
||||
class_name = node.name
|
||||
processed_class_names.add(class_name)
|
||||
class_node = node
|
||||
# Add namespace before the class.
|
||||
if class_node.namespace:
|
||||
lines.extend(['namespace %s {' % n for n in class_node.namespace]) # }
|
||||
lines.append('')
|
||||
|
||||
# Add the class prolog.
|
||||
lines.append('class Mock%s : public %s {' % (class_name, class_name)) # }
|
||||
lines.append('%spublic:' % (' ' * (_INDENT // 2)))
|
||||
|
||||
# Add all the methods.
|
||||
_GenerateMethods(lines, source, class_node)
|
||||
|
||||
# Close the class.
|
||||
if lines:
|
||||
# If there are no virtual methods, no need for a public label.
|
||||
if len(lines) == 2:
|
||||
del lines[-1]
|
||||
|
||||
# Only close the class if there really is a class.
|
||||
lines.append('};')
|
||||
lines.append('') # Add an extra newline.
|
||||
|
||||
# Close the namespace.
|
||||
if class_node.namespace:
|
||||
for i in range(len(class_node.namespace)-1, -1, -1):
|
||||
lines.append('} // namespace %s' % class_node.namespace[i])
|
||||
lines.append('') # Add an extra newline.
|
||||
|
||||
sys.stdout.write('\n'.join(lines))
|
||||
|
||||
if desired_class_names:
|
||||
missing_class_name_list = list(desired_class_names - processed_class_names)
|
||||
if missing_class_name_list:
|
||||
missing_class_name_list.sort()
|
||||
sys.stderr.write('Class(es) not found in %s: %s\n' %
|
||||
(filename, ', '.join(missing_class_name_list)))
|
||||
elif not processed_class_names:
|
||||
sys.stderr.write('No class found in %s\n' % filename)
|
||||
|
||||
|
||||
def main(argv=sys.argv):
|
||||
if len(argv) < 2:
|
||||
sys.stderr.write('Google Mock Class Generator v%s\n\n' %
|
||||
'.'.join(map(str, _VERSION)))
|
||||
sys.stderr.write(__doc__)
|
||||
return 1
|
||||
|
||||
global _INDENT
|
||||
try:
|
||||
_INDENT = int(os.environ['INDENT'])
|
||||
except KeyError:
|
||||
pass
|
||||
except:
|
||||
sys.stderr.write('Unable to use indent of %s\n' % os.environ.get('INDENT'))
|
||||
|
||||
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:])
|
||||
source = utils.ReadFile(filename)
|
||||
if source is None:
|
||||
return 1
|
||||
|
||||
builder = ast.BuilderFromSource(source, filename)
|
||||
try:
|
||||
entire_ast = filter(None, builder.Generate())
|
||||
except KeyboardInterrupt:
|
||||
return
|
||||
except:
|
||||
# An error message was already printed since we couldn't parse.
|
||||
pass
|
||||
else:
|
||||
_GenerateMocks(filename, source, entire_ast, desired_class_names)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main(sys.argv)
|
||||
Arquivo executável
+59
@@ -0,0 +1,59 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright 2007 Neal Norwitz
|
||||
# Portions Copyright 2007 Google Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
"""C++ keywords and helper utilities for determining keywords."""
|
||||
|
||||
__author__ = 'nnorwitz@google.com (Neal Norwitz)'
|
||||
|
||||
|
||||
try:
|
||||
# Python 3.x
|
||||
import builtins
|
||||
except ImportError:
|
||||
# Python 2.x
|
||||
import __builtin__ as builtins
|
||||
|
||||
|
||||
if not hasattr(builtins, 'set'):
|
||||
# Nominal support for Python 2.3.
|
||||
from sets import Set as set
|
||||
|
||||
|
||||
TYPES = set('bool char int long short double float void wchar_t unsigned signed'.split())
|
||||
TYPE_MODIFIERS = set('auto register const inline extern static virtual volatile mutable'.split())
|
||||
ACCESS = set('public protected private friend'.split())
|
||||
|
||||
CASTS = set('static_cast const_cast dynamic_cast reinterpret_cast'.split())
|
||||
|
||||
OTHERS = set('true false asm class namespace using explicit this operator sizeof'.split())
|
||||
OTHER_TYPES = set('new delete typedef struct union enum typeid typename template'.split())
|
||||
|
||||
CONTROL = set('case switch default if else return goto'.split())
|
||||
EXCEPTION = set('try catch throw'.split())
|
||||
LOOP = set('while do for break continue'.split())
|
||||
|
||||
ALL = TYPES | TYPE_MODIFIERS | ACCESS | CASTS | OTHERS | OTHER_TYPES | CONTROL | EXCEPTION | LOOP
|
||||
|
||||
|
||||
def IsKeyword(token):
|
||||
return token in ALL
|
||||
|
||||
def IsBuiltinType(token):
|
||||
if token in ('virtual', 'inline'):
|
||||
# These only apply to methods, they can't be types by themselves.
|
||||
return False
|
||||
return token in TYPES or token in TYPE_MODIFIERS
|
||||
Arquivo executável
+287
@@ -0,0 +1,287 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright 2007 Neal Norwitz
|
||||
# Portions Copyright 2007 Google Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
"""Tokenize C++ source code."""
|
||||
|
||||
__author__ = 'nnorwitz@google.com (Neal Norwitz)'
|
||||
|
||||
|
||||
try:
|
||||
# Python 3.x
|
||||
import builtins
|
||||
except ImportError:
|
||||
# Python 2.x
|
||||
import __builtin__ as builtins
|
||||
|
||||
|
||||
import sys
|
||||
|
||||
from cpp import utils
|
||||
|
||||
|
||||
if not hasattr(builtins, 'set'):
|
||||
# Nominal support for Python 2.3.
|
||||
from sets import Set as set
|
||||
|
||||
|
||||
# Add $ as a valid identifier char since so much code uses it.
|
||||
_letters = 'abcdefghijklmnopqrstuvwxyz'
|
||||
VALID_IDENTIFIER_CHARS = set(_letters + _letters.upper() + '_0123456789$')
|
||||
HEX_DIGITS = set('0123456789abcdefABCDEF')
|
||||
INT_OR_FLOAT_DIGITS = set('01234567890eE-+')
|
||||
|
||||
|
||||
# C++0x string preffixes.
|
||||
_STR_PREFIXES = set(('R', 'u8', 'u8R', 'u', 'uR', 'U', 'UR', 'L', 'LR'))
|
||||
|
||||
|
||||
# Token types.
|
||||
UNKNOWN = 'UNKNOWN'
|
||||
SYNTAX = 'SYNTAX'
|
||||
CONSTANT = 'CONSTANT'
|
||||
NAME = 'NAME'
|
||||
PREPROCESSOR = 'PREPROCESSOR'
|
||||
|
||||
# Where the token originated from. This can be used for backtracking.
|
||||
# It is always set to WHENCE_STREAM in this code.
|
||||
WHENCE_STREAM, WHENCE_QUEUE = range(2)
|
||||
|
||||
|
||||
class Token(object):
|
||||
"""Data container to represent a C++ token.
|
||||
|
||||
Tokens can be identifiers, syntax char(s), constants, or
|
||||
pre-processor directives.
|
||||
|
||||
start contains the index of the first char of the token in the source
|
||||
end contains the index of the last char of the token in the source
|
||||
"""
|
||||
|
||||
def __init__(self, token_type, name, start, end):
|
||||
self.token_type = token_type
|
||||
self.name = name
|
||||
self.start = start
|
||||
self.end = end
|
||||
self.whence = WHENCE_STREAM
|
||||
|
||||
def __str__(self):
|
||||
if not utils.DEBUG:
|
||||
return 'Token(%r)' % self.name
|
||||
return 'Token(%r, %s, %s)' % (self.name, self.start, self.end)
|
||||
|
||||
__repr__ = __str__
|
||||
|
||||
|
||||
def _GetString(source, start, i):
|
||||
i = source.find('"', i+1)
|
||||
while source[i-1] == '\\':
|
||||
# Count the trailing backslashes.
|
||||
backslash_count = 1
|
||||
j = i - 2
|
||||
while source[j] == '\\':
|
||||
backslash_count += 1
|
||||
j -= 1
|
||||
# When trailing backslashes are even, they escape each other.
|
||||
if (backslash_count % 2) == 0:
|
||||
break
|
||||
i = source.find('"', i+1)
|
||||
return i + 1
|
||||
|
||||
|
||||
def _GetChar(source, start, i):
|
||||
# NOTE(nnorwitz): may not be quite correct, should be good enough.
|
||||
i = source.find("'", i+1)
|
||||
while source[i-1] == '\\':
|
||||
# Need to special case '\\'.
|
||||
if (i - 2) > start and source[i-2] == '\\':
|
||||
break
|
||||
i = source.find("'", i+1)
|
||||
# Try to handle unterminated single quotes (in a #if 0 block).
|
||||
if i < 0:
|
||||
i = start
|
||||
return i + 1
|
||||
|
||||
|
||||
def GetTokens(source):
|
||||
"""Returns a sequence of Tokens.
|
||||
|
||||
Args:
|
||||
source: string of C++ source code.
|
||||
|
||||
Yields:
|
||||
Token that represents the next token in the source.
|
||||
"""
|
||||
# Cache various valid character sets for speed.
|
||||
valid_identifier_chars = VALID_IDENTIFIER_CHARS
|
||||
hex_digits = HEX_DIGITS
|
||||
int_or_float_digits = INT_OR_FLOAT_DIGITS
|
||||
int_or_float_digits2 = int_or_float_digits | set('.')
|
||||
|
||||
# Only ignore errors while in a #if 0 block.
|
||||
ignore_errors = False
|
||||
count_ifs = 0
|
||||
|
||||
i = 0
|
||||
end = len(source)
|
||||
while i < end:
|
||||
# Skip whitespace.
|
||||
while i < end and source[i].isspace():
|
||||
i += 1
|
||||
if i >= end:
|
||||
return
|
||||
|
||||
token_type = UNKNOWN
|
||||
start = i
|
||||
c = source[i]
|
||||
if c.isalpha() or c == '_': # Find a string token.
|
||||
token_type = NAME
|
||||
while source[i] in valid_identifier_chars:
|
||||
i += 1
|
||||
# String and character constants can look like a name if
|
||||
# they are something like L"".
|
||||
if (source[i] == "'" and (i - start) == 1 and
|
||||
source[start:i] in 'uUL'):
|
||||
# u, U, and L are valid C++0x character preffixes.
|
||||
token_type = CONSTANT
|
||||
i = _GetChar(source, start, i)
|
||||
elif source[i] == "'" and source[start:i] in _STR_PREFIXES:
|
||||
token_type = CONSTANT
|
||||
i = _GetString(source, start, i)
|
||||
elif c == '/' and source[i+1] == '/': # Find // comments.
|
||||
i = source.find('\n', i)
|
||||
if i == -1: # Handle EOF.
|
||||
i = end
|
||||
continue
|
||||
elif c == '/' and source[i+1] == '*': # Find /* comments. */
|
||||
i = source.find('*/', i) + 2
|
||||
continue
|
||||
elif c in ':+-<>&|*=': # : or :: (plus other chars).
|
||||
token_type = SYNTAX
|
||||
i += 1
|
||||
new_ch = source[i]
|
||||
if new_ch == c:
|
||||
i += 1
|
||||
elif c == '-' and new_ch == '>':
|
||||
i += 1
|
||||
elif new_ch == '=':
|
||||
i += 1
|
||||
elif c in '()[]{}~!?^%;/.,': # Handle single char tokens.
|
||||
token_type = SYNTAX
|
||||
i += 1
|
||||
if c == '.' and source[i].isdigit():
|
||||
token_type = CONSTANT
|
||||
i += 1
|
||||
while source[i] in int_or_float_digits:
|
||||
i += 1
|
||||
# Handle float suffixes.
|
||||
for suffix in ('l', 'f'):
|
||||
if suffix == source[i:i+1].lower():
|
||||
i += 1
|
||||
break
|
||||
elif c.isdigit(): # Find integer.
|
||||
token_type = CONSTANT
|
||||
if c == '0' and source[i+1] in 'xX':
|
||||
# Handle hex digits.
|
||||
i += 2
|
||||
while source[i] in hex_digits:
|
||||
i += 1
|
||||
else:
|
||||
while source[i] in int_or_float_digits2:
|
||||
i += 1
|
||||
# Handle integer (and float) suffixes.
|
||||
for suffix in ('ull', 'll', 'ul', 'l', 'f', 'u'):
|
||||
size = len(suffix)
|
||||
if suffix == source[i:i+size].lower():
|
||||
i += size
|
||||
break
|
||||
elif c == '"': # Find string.
|
||||
token_type = CONSTANT
|
||||
i = _GetString(source, start, i)
|
||||
elif c == "'": # Find char.
|
||||
token_type = CONSTANT
|
||||
i = _GetChar(source, start, i)
|
||||
elif c == '#': # Find pre-processor command.
|
||||
token_type = PREPROCESSOR
|
||||
got_if = source[i:i+3] == '#if' and source[i+3:i+4].isspace()
|
||||
if got_if:
|
||||
count_ifs += 1
|
||||
elif source[i:i+6] == '#endif':
|
||||
count_ifs -= 1
|
||||
if count_ifs == 0:
|
||||
ignore_errors = False
|
||||
|
||||
# TODO(nnorwitz): handle preprocessor statements (\ continuations).
|
||||
while 1:
|
||||
i1 = source.find('\n', i)
|
||||
i2 = source.find('//', i)
|
||||
i3 = source.find('/*', i)
|
||||
i4 = source.find('"', i)
|
||||
# NOTE(nnorwitz): doesn't handle comments in #define macros.
|
||||
# Get the first important symbol (newline, comment, EOF/end).
|
||||
i = min([x for x in (i1, i2, i3, i4, end) if x != -1])
|
||||
|
||||
# Handle #include "dir//foo.h" properly.
|
||||
if source[i] == '"':
|
||||
i = source.find('"', i+1) + 1
|
||||
assert i > 0
|
||||
continue
|
||||
# Keep going if end of the line and the line ends with \.
|
||||
if not (i == i1 and source[i-1] == '\\'):
|
||||
if got_if:
|
||||
condition = source[start+4:i].lstrip()
|
||||
if (condition.startswith('0') or
|
||||
condition.startswith('(0)')):
|
||||
ignore_errors = True
|
||||
break
|
||||
i += 1
|
||||
elif c == '\\': # Handle \ in code.
|
||||
# This is different from the pre-processor \ handling.
|
||||
i += 1
|
||||
continue
|
||||
elif ignore_errors:
|
||||
# The tokenizer seems to be in pretty good shape. This
|
||||
# raise is conditionally disabled so that bogus code
|
||||
# in an #if 0 block can be handled. Since we will ignore
|
||||
# it anyways, this is probably fine. So disable the
|
||||
# exception and return the bogus char.
|
||||
i += 1
|
||||
else:
|
||||
sys.stderr.write('Got invalid token in %s @ %d token:%s: %r\n' %
|
||||
('?', i, c, source[i-10:i+10]))
|
||||
raise RuntimeError('unexpected token')
|
||||
|
||||
if i <= 0:
|
||||
print('Invalid index, exiting now.')
|
||||
return
|
||||
yield Token(token_type, source[start:i], start, i)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
def main(argv):
|
||||
"""Driver mostly for testing purposes."""
|
||||
for filename in argv[1:]:
|
||||
source = utils.ReadFile(filename)
|
||||
if source is None:
|
||||
continue
|
||||
|
||||
for token in GetTokens(source):
|
||||
print('%-12s: %s' % (token.token_type, token.name))
|
||||
# print('\r%6.2f%%' % (100.0 * index / token.end),)
|
||||
sys.stdout.write('\n')
|
||||
|
||||
|
||||
main(sys.argv)
|
||||
Arquivo executável
+41
@@ -0,0 +1,41 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright 2007 Neal Norwitz
|
||||
# Portions Copyright 2007 Google Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
"""Generic utilities for C++ parsing."""
|
||||
|
||||
__author__ = 'nnorwitz@google.com (Neal Norwitz)'
|
||||
|
||||
|
||||
import sys
|
||||
|
||||
|
||||
# Set to True to see the start/end token indices.
|
||||
DEBUG = True
|
||||
|
||||
|
||||
def ReadFile(filename, print_error=True):
|
||||
"""Returns the contents of a file."""
|
||||
try:
|
||||
fp = open(filename)
|
||||
try:
|
||||
return fp.read()
|
||||
finally:
|
||||
fp.close()
|
||||
except IOError:
|
||||
if print_error:
|
||||
print('Error reading %s: %s' % (filename, sys.exc_info()[1]))
|
||||
return None
|
||||
Arquivo executável
+31
@@ -0,0 +1,31 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright 2008 Google Inc. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
"""Driver for starting up Google Mock class generator."""
|
||||
|
||||
__author__ = 'nnorwitz@google.com (Neal Norwitz)'
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
if __name__ == '__main__':
|
||||
# Add the directory of this script to the path so we can import gmock_class.
|
||||
sys.path.append(os.path.dirname(__file__))
|
||||
|
||||
from cpp import gmock_class
|
||||
# Fix the docstring in case they require the usage.
|
||||
gmock_class.__doc__ = gmock_class.__doc__.replace('gmock_class.py', __file__)
|
||||
gmock_class.main()
|
||||
Arquivo executável
+303
@@ -0,0 +1,303 @@
|
||||
#!/bin/sh
|
||||
|
||||
# These variables are automatically filled in by the configure script.
|
||||
name="@PACKAGE_TARNAME@"
|
||||
version="@PACKAGE_VERSION@"
|
||||
|
||||
show_usage()
|
||||
{
|
||||
echo "Usage: gmock-config [OPTIONS...]"
|
||||
}
|
||||
|
||||
show_help()
|
||||
{
|
||||
show_usage
|
||||
cat <<\EOF
|
||||
|
||||
The `gmock-config' script provides access to the necessary compile and linking
|
||||
flags to connect with Google C++ Mocking Framework, both in a build prior to
|
||||
installation, and on the system proper after installation. The installation
|
||||
overrides may be issued in combination with any other queries, but will only
|
||||
affect installation queries if called on a built but not installed gmock. The
|
||||
installation queries may not be issued with any other types of queries, and
|
||||
only one installation query may be made at a time. The version queries and
|
||||
compiler flag queries may be combined as desired but not mixed. Different
|
||||
version queries are always combined with logical "and" semantics, and only the
|
||||
last of any particular query is used while all previous ones ignored. All
|
||||
versions must be specified as a sequence of numbers separated by periods.
|
||||
Compiler flag queries output the union of the sets of flags when combined.
|
||||
|
||||
Examples:
|
||||
gmock-config --min-version=1.0 || echo "Insufficient Google Mock version."
|
||||
|
||||
g++ $(gmock-config --cppflags --cxxflags) -o foo.o -c foo.cpp
|
||||
g++ $(gmock-config --ldflags --libs) -o foo foo.o
|
||||
|
||||
# When using a built but not installed Google Mock:
|
||||
g++ $(../../my_gmock_build/scripts/gmock-config ...) ...
|
||||
|
||||
# When using an installed Google Mock, but with installation overrides:
|
||||
export GMOCK_PREFIX="/opt"
|
||||
g++ $(gmock-config --libdir="/opt/lib64" ...) ...
|
||||
|
||||
Help:
|
||||
--usage brief usage information
|
||||
--help display this help message
|
||||
|
||||
Installation Overrides:
|
||||
--prefix=<dir> overrides the installation prefix
|
||||
--exec-prefix=<dir> overrides the executable installation prefix
|
||||
--libdir=<dir> overrides the library installation prefix
|
||||
--includedir=<dir> overrides the header file installation prefix
|
||||
|
||||
Installation Queries:
|
||||
--prefix installation prefix
|
||||
--exec-prefix executable installation prefix
|
||||
--libdir library installation directory
|
||||
--includedir header file installation directory
|
||||
--version the version of the Google Mock installation
|
||||
|
||||
Version Queries:
|
||||
--min-version=VERSION return 0 if the version is at least VERSION
|
||||
--exact-version=VERSION return 0 if the version is exactly VERSION
|
||||
--max-version=VERSION return 0 if the version is at most VERSION
|
||||
|
||||
Compilation Flag Queries:
|
||||
--cppflags compile flags specific to the C-like preprocessors
|
||||
--cxxflags compile flags appropriate for C++ programs
|
||||
--ldflags linker flags
|
||||
--libs libraries for linking
|
||||
|
||||
EOF
|
||||
}
|
||||
|
||||
# This function bounds our version with a min and a max. It uses some clever
|
||||
# POSIX-compliant variable expansion to portably do all the work in the shell
|
||||
# and avoid any dependency on a particular "sed" or "awk" implementation.
|
||||
# Notable is that it will only ever compare the first 3 components of versions.
|
||||
# Further components will be cleanly stripped off. All versions must be
|
||||
# unadorned, so "v1.0" will *not* work. The minimum version must be in $1, and
|
||||
# the max in $2. TODO(chandlerc@google.com): If this ever breaks, we should
|
||||
# investigate expanding this via autom4te from AS_VERSION_COMPARE rather than
|
||||
# continuing to maintain our own shell version.
|
||||
check_versions()
|
||||
{
|
||||
major_version=${version%%.*}
|
||||
minor_version="0"
|
||||
point_version="0"
|
||||
if test "${version#*.}" != "${version}"; then
|
||||
minor_version=${version#*.}
|
||||
minor_version=${minor_version%%.*}
|
||||
fi
|
||||
if test "${version#*.*.}" != "${version}"; then
|
||||
point_version=${version#*.*.}
|
||||
point_version=${point_version%%.*}
|
||||
fi
|
||||
|
||||
min_version="$1"
|
||||
min_major_version=${min_version%%.*}
|
||||
min_minor_version="0"
|
||||
min_point_version="0"
|
||||
if test "${min_version#*.}" != "${min_version}"; then
|
||||
min_minor_version=${min_version#*.}
|
||||
min_minor_version=${min_minor_version%%.*}
|
||||
fi
|
||||
if test "${min_version#*.*.}" != "${min_version}"; then
|
||||
min_point_version=${min_version#*.*.}
|
||||
min_point_version=${min_point_version%%.*}
|
||||
fi
|
||||
|
||||
max_version="$2"
|
||||
max_major_version=${max_version%%.*}
|
||||
max_minor_version="0"
|
||||
max_point_version="0"
|
||||
if test "${max_version#*.}" != "${max_version}"; then
|
||||
max_minor_version=${max_version#*.}
|
||||
max_minor_version=${max_minor_version%%.*}
|
||||
fi
|
||||
if test "${max_version#*.*.}" != "${max_version}"; then
|
||||
max_point_version=${max_version#*.*.}
|
||||
max_point_version=${max_point_version%%.*}
|
||||
fi
|
||||
|
||||
test $(($major_version)) -lt $(($min_major_version)) && exit 1
|
||||
if test $(($major_version)) -eq $(($min_major_version)); then
|
||||
test $(($minor_version)) -lt $(($min_minor_version)) && exit 1
|
||||
if test $(($minor_version)) -eq $(($min_minor_version)); then
|
||||
test $(($point_version)) -lt $(($min_point_version)) && exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
test $(($major_version)) -gt $(($max_major_version)) && exit 1
|
||||
if test $(($major_version)) -eq $(($max_major_version)); then
|
||||
test $(($minor_version)) -gt $(($max_minor_version)) && exit 1
|
||||
if test $(($minor_version)) -eq $(($max_minor_version)); then
|
||||
test $(($point_version)) -gt $(($max_point_version)) && exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
exit 0
|
||||
}
|
||||
|
||||
# Show the usage line when no arguments are specified.
|
||||
if test $# -eq 0; then
|
||||
show_usage
|
||||
exit 1
|
||||
fi
|
||||
|
||||
while test $# -gt 0; do
|
||||
case $1 in
|
||||
--usage) show_usage; exit 0;;
|
||||
--help) show_help; exit 0;;
|
||||
|
||||
# Installation overrides
|
||||
--prefix=*) GMOCK_PREFIX=${1#--prefix=};;
|
||||
--exec-prefix=*) GMOCK_EXEC_PREFIX=${1#--exec-prefix=};;
|
||||
--libdir=*) GMOCK_LIBDIR=${1#--libdir=};;
|
||||
--includedir=*) GMOCK_INCLUDEDIR=${1#--includedir=};;
|
||||
|
||||
# Installation queries
|
||||
--prefix|--exec-prefix|--libdir|--includedir|--version)
|
||||
if test -n "${do_query}"; then
|
||||
show_usage
|
||||
exit 1
|
||||
fi
|
||||
do_query=${1#--}
|
||||
;;
|
||||
|
||||
# Version checking
|
||||
--min-version=*)
|
||||
do_check_versions=yes
|
||||
min_version=${1#--min-version=}
|
||||
;;
|
||||
--max-version=*)
|
||||
do_check_versions=yes
|
||||
max_version=${1#--max-version=}
|
||||
;;
|
||||
--exact-version=*)
|
||||
do_check_versions=yes
|
||||
exact_version=${1#--exact-version=}
|
||||
;;
|
||||
|
||||
# Compiler flag output
|
||||
--cppflags) echo_cppflags=yes;;
|
||||
--cxxflags) echo_cxxflags=yes;;
|
||||
--ldflags) echo_ldflags=yes;;
|
||||
--libs) echo_libs=yes;;
|
||||
|
||||
# Everything else is an error
|
||||
*) show_usage; exit 1;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
# These have defaults filled in by the configure script but can also be
|
||||
# overridden by environment variables or command line parameters.
|
||||
prefix="${GMOCK_PREFIX:-@prefix@}"
|
||||
exec_prefix="${GMOCK_EXEC_PREFIX:-@exec_prefix@}"
|
||||
libdir="${GMOCK_LIBDIR:-@libdir@}"
|
||||
includedir="${GMOCK_INCLUDEDIR:-@includedir@}"
|
||||
|
||||
# We try and detect if our binary is not located at its installed location. If
|
||||
# it's not, we provide variables pointing to the source and build tree rather
|
||||
# than to the install tree. We also locate Google Test using the configured
|
||||
# gtest-config script rather than searching the PATH and our bindir for one.
|
||||
# This allows building against a just-built gmock rather than an installed
|
||||
# gmock.
|
||||
bindir="@bindir@"
|
||||
this_relative_bindir=`dirname $0`
|
||||
this_bindir=`cd ${this_relative_bindir}; pwd -P`
|
||||
if test "${this_bindir}" = "${this_bindir%${bindir}}"; then
|
||||
# The path to the script doesn't end in the bindir sequence from Autoconf,
|
||||
# assume that we are in a build tree.
|
||||
build_dir=`dirname ${this_bindir}`
|
||||
src_dir=`cd ${this_bindir}/@top_srcdir@; pwd -P`
|
||||
|
||||
# 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_ldflags=""
|
||||
|
||||
# We provide hooks to include from either the source or build dir, where the
|
||||
# build dir is always preferred. This will potentially allow us to write
|
||||
# build rules for generated headers and have them automatically be preferred
|
||||
# over provided versions.
|
||||
gmock_cppflags="-I${build_dir}/include -I${src_dir}/include"
|
||||
gmock_cxxflags=""
|
||||
|
||||
# Directly invoke the gtest-config script used during the build process.
|
||||
gtest_config="@GTEST_CONFIG@"
|
||||
else
|
||||
# We're using an installed gmock, although it may be staged under some
|
||||
# prefix. Assume (as our own libraries do) that we can resolve the prefix,
|
||||
# and are present in the dynamic link paths.
|
||||
gmock_ldflags="-L${libdir}"
|
||||
gmock_libs="-l${name}"
|
||||
gmock_cppflags="-I${includedir}"
|
||||
gmock_cxxflags=""
|
||||
|
||||
# We also prefer any gtest-config script installed in our prefix. Lacking
|
||||
# one, we look in the PATH for one.
|
||||
gtest_config="${bindir}/gtest-config"
|
||||
if test ! -x "${gtest_config}"; then
|
||||
gtest_config=`which gtest-config`
|
||||
fi
|
||||
fi
|
||||
|
||||
# Ensure that we have located a Google Test to link against.
|
||||
if ! test -x "${gtest_config}"; then
|
||||
echo "Unable to locate Google Test, check your Google Mock configuration" \
|
||||
"and installation" >&2
|
||||
exit 1
|
||||
elif ! "${gtest_config}" "--exact-version=@GTEST_VERSION@"; then
|
||||
echo "The Google Test found is not the same version as Google Mock was " \
|
||||
"built against" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Add the necessary Google Test bits into the various flag variables
|
||||
gmock_cppflags="${gmock_cppflags} `${gtest_config} --cppflags`"
|
||||
gmock_cxxflags="${gmock_cxxflags} `${gtest_config} --cxxflags`"
|
||||
gmock_ldflags="${gmock_ldflags}`${gtest_config} --ldflags`"
|
||||
gmock_libs="${gmock_libs} `${gtest_config} --libs`"
|
||||
|
||||
# Do an installation query if requested.
|
||||
if test -n "$do_query"; then
|
||||
case $do_query in
|
||||
prefix) echo $prefix; exit 0;;
|
||||
exec-prefix) echo $exec_prefix; exit 0;;
|
||||
libdir) echo $libdir; exit 0;;
|
||||
includedir) echo $includedir; exit 0;;
|
||||
version) echo $version; exit 0;;
|
||||
*) show_usage; exit 1;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Do a version check if requested.
|
||||
if test "$do_check_versions" = "yes"; then
|
||||
# Make sure we didn't receive a bad combination of parameters.
|
||||
test "$echo_cppflags" = "yes" && show_usage && exit 1
|
||||
test "$echo_cxxflags" = "yes" && show_usage && exit 1
|
||||
test "$echo_ldflags" = "yes" && show_usage && exit 1
|
||||
test "$echo_libs" = "yes" && show_usage && exit 1
|
||||
|
||||
if test "$exact_version" != ""; then
|
||||
check_versions $exact_version $exact_version
|
||||
# unreachable
|
||||
else
|
||||
check_versions ${min_version:-0.0.0} ${max_version:-9999.9999.9999}
|
||||
# unreachable
|
||||
fi
|
||||
fi
|
||||
|
||||
# Do the output in the correct order so that these can be used in-line of
|
||||
# a compiler invocation.
|
||||
output=""
|
||||
test "$echo_cppflags" = "yes" && output="$output $gmock_cppflags"
|
||||
test "$echo_cxxflags" = "yes" && output="$output $gmock_cxxflags"
|
||||
test "$echo_ldflags" = "yes" && output="$output $gmock_ldflags"
|
||||
test "$echo_libs" = "yes" && output="$output $gmock_libs"
|
||||
echo $output
|
||||
|
||||
exit 0
|
||||
Arquivo executável
+416
@@ -0,0 +1,416 @@
|
||||
#!/usr/bin/python2.4
|
||||
#
|
||||
# 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.
|
||||
|
||||
"""Converts gcc errors in code using Google Mock to plain English."""
|
||||
|
||||
__author__ = 'wan@google.com (Zhanyong Wan)'
|
||||
|
||||
import re
|
||||
import sys
|
||||
|
||||
_VERSION = '1.0.0'
|
||||
|
||||
_COMMON_GMOCK_SYMBOLS = [
|
||||
# Matchers
|
||||
'_',
|
||||
'A',
|
||||
'AddressSatisfies',
|
||||
'AllOf',
|
||||
'An',
|
||||
'AnyOf',
|
||||
'ContainsRegex',
|
||||
'DoubleEq',
|
||||
'EndsWith',
|
||||
'Eq',
|
||||
'Field',
|
||||
'FloatEq',
|
||||
'Ge',
|
||||
'Gt',
|
||||
'HasSubstr',
|
||||
'IsInitializedProto',
|
||||
'Le',
|
||||
'Lt',
|
||||
'MatcherCast',
|
||||
'MatchesRegex',
|
||||
'Ne',
|
||||
'Not',
|
||||
'NotNull',
|
||||
'Pointee',
|
||||
'PointeeIsInitializedProto',
|
||||
'Property',
|
||||
'Ref',
|
||||
'StartsWith',
|
||||
'StrCaseEq',
|
||||
'StrCaseNe',
|
||||
'StrEq',
|
||||
'StrNe',
|
||||
'Truly',
|
||||
'TypedEq',
|
||||
|
||||
# Actions
|
||||
'ByRef',
|
||||
'DoAll',
|
||||
'DoDefault',
|
||||
'IgnoreResult',
|
||||
'Invoke',
|
||||
'InvokeArgument',
|
||||
'InvokeWithoutArgs',
|
||||
'Return',
|
||||
'ReturnNull',
|
||||
'ReturnRef',
|
||||
'SetArgumentPointee',
|
||||
'SetArrayArgument',
|
||||
'WithArgs',
|
||||
|
||||
# Cardinalities
|
||||
'AnyNumber',
|
||||
'AtLeast',
|
||||
'AtMost',
|
||||
'Between',
|
||||
'Exactly',
|
||||
|
||||
# Sequences
|
||||
'InSequence',
|
||||
'Sequence',
|
||||
|
||||
# Misc
|
||||
'DefaultValue',
|
||||
'Mock',
|
||||
]
|
||||
|
||||
|
||||
def _FindAllMatches(regex, s):
|
||||
"""Generates all matches of regex in string s."""
|
||||
|
||||
r = re.compile(regex)
|
||||
return r.finditer(s)
|
||||
|
||||
|
||||
def _GenericDiagnoser(short_name, long_name, regex, diagnosis, msg):
|
||||
"""Diagnoses the given disease by pattern matching.
|
||||
|
||||
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.
|
||||
Yields:
|
||||
Tuples of the form
|
||||
(short name of disease, long name of disease, 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'
|
||||
r'(?P<file>.*):(?P<line>\d+):\s+instantiated from here\n'
|
||||
r'.*gmock-actions\.h.*error: creating array with negative size')
|
||||
diagnosis = """%(file)s:%(line)s:
|
||||
You are using an Return() action in a function that returns a reference.
|
||||
Please use ReturnRef() instead."""
|
||||
return _GenericDiagnoser('NRR', 'Need to Return Reference',
|
||||
regex, diagnosis, msg)
|
||||
|
||||
|
||||
def _NeedToReturnSomethingDiagnoser(msg):
|
||||
"""Diagnoses the NRS disease, given the error messages by gcc."""
|
||||
|
||||
regex = (r'(?P<file>.*):(?P<line>\d+):\s+'
|
||||
r'(instantiated from here\n.'
|
||||
r'*gmock-actions\.h.*error: void value not ignored)'
|
||||
r'|(error: control reaches end of non-void function)')
|
||||
diagnosis = """%(file)s:%(line)s:
|
||||
You are using an action that returns void, but it needs to return
|
||||
*something*. 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)
|
||||
|
||||
|
||||
def _NeedToReturnNothingDiagnoser(msg):
|
||||
"""Diagnoses the NRN disease, given the error messages by gcc."""
|
||||
|
||||
regex = (r'(?P<file>.*):(?P<line>\d+):\s+instantiated from here\n'
|
||||
r'.*gmock-actions\.h.*error: return-statement with a value, '
|
||||
r'in function returning \'void\'')
|
||||
diagnosis = """%(file)s:%(line)s:
|
||||
You are using an action that returns *something*, 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)
|
||||
|
||||
|
||||
def _IncompleteByReferenceArgumentDiagnoser(msg):
|
||||
"""Diagnoses the IBRA disease, given the error messages by gcc."""
|
||||
|
||||
regex = (r'(?P<file>.*):(?P<line>\d+):\s+instantiated from here\n'
|
||||
r'.*gmock-printers\.h.*error: invalid application of '
|
||||
r'\'sizeof\' to incomplete type \'(?P<type>.*)\'')
|
||||
diagnosis = """%(file)s:%(line)s:
|
||||
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)
|
||||
|
||||
|
||||
def _OverloadedFunctionMatcherDiagnoser(msg):
|
||||
"""Diagnoses the OFM disease, given the error messages by gcc."""
|
||||
|
||||
regex = (r'(?P<file>.*):(?P<line>\d+): error: no matching function for '
|
||||
r'call to \'Truly\(<unresolved overloaded function type>\)')
|
||||
diagnosis = """%(file)s:%(line)s:
|
||||
The argument you gave to Truly() is an overloaded function. Please tell
|
||||
gcc 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)
|
||||
|
||||
|
||||
def _OverloadedFunctionActionDiagnoser(msg):
|
||||
"""Diagnoses the OFA disease, given the error messages by gcc."""
|
||||
|
||||
regex = (r'(?P<file>.*):(?P<line>\d+): error: '
|
||||
r'no matching function for call to \'Invoke\('
|
||||
r'<unresolved overloaded function type>')
|
||||
diagnosis = """%(file)s:%(line)s:
|
||||
You are passing an overloaded function to Invoke(). Please tell gcc
|
||||
which overloaded version you want to use.
|
||||
|
||||
For example, if you want to use the version whose signature is
|
||||
bool MyFunction(int n, double x);
|
||||
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 = (r'(?P<file>.*):(?P<line>\d+): error: '
|
||||
r'.*no matching function for call to \'Invoke\(.*, '
|
||||
r'unresolved overloaded function type>')
|
||||
diagnosis = """%(file)s:%(line)s:
|
||||
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)
|
||||
|
||||
|
||||
def _MockObjectPointerDiagnoser(msg):
|
||||
"""Diagnoses the MOP disease, given the error messages by gcc."""
|
||||
|
||||
regex = (r'(?P<file>.*):(?P<line>\d+): error: request for member '
|
||||
r'\'gmock_(?P<method>.+)\' in \'(?P<mock_object>.+)\', '
|
||||
r'which is of non-class type \'(.*::)*(?P<class_name>.+)\*\'')
|
||||
diagnosis = """%(file)s:%(line)s:
|
||||
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
|
||||
'%(mock_object)s' as your first argument.
|
||||
|
||||
For example, given the mock class:
|
||||
|
||||
class %(class_name)s : public ... {
|
||||
...
|
||||
MOCK_METHOD0(%(method)s, ...);
|
||||
};
|
||||
|
||||
and the following mock instance:
|
||||
|
||||
%(class_name)s* mock_ptr = ...
|
||||
|
||||
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 = (r'(?P<file>.*):(?P<line>\d+): error: no matching function for '
|
||||
r'call to \'Invoke\(.+, <unresolved overloaded function type>\)')
|
||||
diagnosis = """%(file)s:%(line)s:
|
||||
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)
|
||||
|
||||
|
||||
def _NeedToUseSymbolDiagnoser(msg):
|
||||
"""Diagnoses the NUS disease, given the error messages by gcc."""
|
||||
|
||||
regex = (r'(?P<file>.*):(?P<line>\d+): error: \'(?P<symbol>.+)\' '
|
||||
r'(was not declared in this scope|has not been declared)')
|
||||
diagnosis = """%(file)s:%(line)s:
|
||||
'%(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):
|
||||
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 = (r'(?P<file>.*):(?P<line>\d+):\s+instantiated from here\n'
|
||||
r'.*gmock-actions\.h.*error: invalid conversion from '
|
||||
r'\'long int\' to \'(?P<type>.+\*)')
|
||||
|
||||
diagnosis = """%(file)s:%(line)s:
|
||||
You are probably calling Return(NULL) and the compiler isn't sure how to turn
|
||||
NULL into a %(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)
|
||||
|
||||
|
||||
def _WrongMockMethodMacroDiagnoser(msg):
|
||||
"""Diagnoses the WMM disease, given the error messages by gcc."""
|
||||
|
||||
regex = (r'(?P<file>.*):(?P<line>\d+):\s+'
|
||||
r'.*this_method_does_not_take_(?P<wrong_args>\d+)_argument.*\n'
|
||||
r'.*\n'
|
||||
r'.*candidates are.*FunctionMocker<[^>]+A(?P<args>\d+)\)>'
|
||||
)
|
||||
|
||||
diagnosis = """%(file)s:%(line)s:
|
||||
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)
|
||||
|
||||
|
||||
|
||||
_DIAGNOSERS = [
|
||||
_IncompleteByReferenceArgumentDiagnoser,
|
||||
_MockObjectPointerDiagnoser,
|
||||
_NeedToReturnNothingDiagnoser,
|
||||
_NeedToReturnReferenceDiagnoser,
|
||||
_NeedToReturnSomethingDiagnoser,
|
||||
_NeedToUseReturnNullDiagnoser,
|
||||
_NeedToUseSymbolDiagnoser,
|
||||
_OverloadedFunctionActionDiagnoser,
|
||||
_OverloadedFunctionMatcherDiagnoser,
|
||||
_OverloadedMethodActionDiagnoser1,
|
||||
_OverloadedMethodActionDiagnoser2,
|
||||
_WrongMockMethodMacroDiagnoser,
|
||||
]
|
||||
|
||||
|
||||
def Diagnose(msg):
|
||||
"""Generates all possible diagnoses given the gcc error message."""
|
||||
|
||||
for diagnoser in _DIAGNOSERS:
|
||||
for diagnosis in diagnoser(msg):
|
||||
yield '[%s - %s]\n%s' % diagnosis
|
||||
|
||||
|
||||
def main():
|
||||
print ('Google Mock Doctor v%s - '
|
||||
'diagnoses problems in code using Google Mock.' % _VERSION)
|
||||
|
||||
if sys.stdin.isatty():
|
||||
print ('Please copy and paste the compiler errors here. Press c-D when '
|
||||
'you are done:')
|
||||
else:
|
||||
print 'Waiting for compiler errors on stdin . . .'
|
||||
|
||||
msg = sys.stdin.read().strip()
|
||||
diagnoses = list(Diagnose(msg))
|
||||
count = len(diagnoses)
|
||||
if not count:
|
||||
print '\nGcc complained:'
|
||||
print '8<------------------------------------------------------------'
|
||||
print msg
|
||||
print '------------------------------------------------------------>8'
|
||||
print """
|
||||
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!"""
|
||||
else:
|
||||
print '------------------------------------------------------------'
|
||||
print 'Your code appears to have the following',
|
||||
if count > 1:
|
||||
print '%s diseases:' % (count,)
|
||||
else:
|
||||
print 'disease:'
|
||||
i = 0
|
||||
for d in diagnoses:
|
||||
i += 1
|
||||
if count > 1:
|
||||
print '\n#%s:' % (i,)
|
||||
print d
|
||||
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!"""
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -0,0 +1,57 @@
|
||||
# A Makefile for fusing Google Mock and building a sample test against it.
|
||||
#
|
||||
# SYNOPSIS:
|
||||
#
|
||||
# make [all] - makes everything.
|
||||
# make TARGET - makes the given target.
|
||||
# make check - makes everything and runs the built sample test.
|
||||
# make clean - removes all files generated by make.
|
||||
|
||||
# Points to the root of fused Google Mock, relative to where this file is.
|
||||
FUSED_GMOCK_DIR = output
|
||||
|
||||
# Paths to the fused gmock files.
|
||||
FUSED_GTEST_H = $(FUSED_GMOCK_DIR)/gtest/gtest.h
|
||||
FUSED_GMOCK_H = $(FUSED_GMOCK_DIR)/gmock/gmock.h
|
||||
FUSED_GMOCK_GTEST_ALL_CC = $(FUSED_GMOCK_DIR)/gmock-gtest-all.cc
|
||||
|
||||
# Where to find the gmock_test.cc.
|
||||
GMOCK_TEST_CC = ../../test/gmock_test.cc
|
||||
|
||||
# Where to find gmock_main.cc.
|
||||
GMOCK_MAIN_CC = ../../src/gmock_main.cc
|
||||
|
||||
# Flags passed to the preprocessor.
|
||||
CPPFLAGS += -I$(FUSED_GMOCK_DIR)
|
||||
|
||||
# Flags passed to the C++ compiler.
|
||||
CXXFLAGS += -g
|
||||
|
||||
all : gmock_test
|
||||
|
||||
check : all
|
||||
./gmock_test
|
||||
|
||||
clean :
|
||||
rm -rf $(FUSED_GMOCK_DIR) gmock_test *.o
|
||||
|
||||
$(FUSED_GTEST_H) :
|
||||
../fuse_gmock_files.py $(FUSED_GMOCK_DIR)
|
||||
|
||||
$(FUSED_GMOCK_H) :
|
||||
../fuse_gmock_files.py $(FUSED_GMOCK_DIR)
|
||||
|
||||
$(FUSED_GMOCK_GTEST_ALL_CC) :
|
||||
../fuse_gmock_files.py $(FUSED_GMOCK_DIR)
|
||||
|
||||
gmock-gtest-all.o : $(FUSED_GTEST_H) $(FUSED_GMOCK_H) $(FUSED_GMOCK_GTEST_ALL_CC)
|
||||
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(FUSED_GMOCK_GTEST_ALL_CC)
|
||||
|
||||
gmock_main.o : $(FUSED_GTEST_H) $(FUSED_GMOCK_H) $(GMOCK_MAIN_CC)
|
||||
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(GMOCK_MAIN_CC)
|
||||
|
||||
gmock_test.o : $(FUSED_GTEST_H) $(FUSED_GMOCK_H) $(GMOCK_TEST_CC)
|
||||
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(GMOCK_TEST_CC)
|
||||
|
||||
gmock_test : gmock_test.o gmock-gtest-all.o gmock_main.o
|
||||
$(CXX) $(CPPFLAGS) $(CXXFLAGS) $^ -o $@
|
||||
Arquivo executável
+1387
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
Arquivo executável
+78
@@ -0,0 +1,78 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright 2009, 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.
|
||||
|
||||
"""upload_gmock.py v0.1.0 -- uploads a Google Mock patch for review.
|
||||
|
||||
This simple wrapper passes all command line flags and
|
||||
--cc=googlemock@googlegroups.com to upload.py.
|
||||
|
||||
USAGE: upload_gmock.py [options for upload.py]
|
||||
"""
|
||||
|
||||
__author__ = 'wan@google.com (Zhanyong Wan)'
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
CC_FLAG = '--cc='
|
||||
GMOCK_GROUP = 'googlemock@googlegroups.com'
|
||||
|
||||
|
||||
def main():
|
||||
# Finds the path to upload.py, assuming it is in the same directory
|
||||
# as this file.
|
||||
my_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
upload_py_path = os.path.join(my_dir, 'upload.py')
|
||||
|
||||
# Adds Google Mock discussion group to the cc line if it's not there
|
||||
# already.
|
||||
upload_py_argv = [upload_py_path]
|
||||
found_cc_flag = False
|
||||
for arg in sys.argv[1:]:
|
||||
if arg.startswith(CC_FLAG):
|
||||
found_cc_flag = True
|
||||
cc_line = arg[len(CC_FLAG):]
|
||||
cc_list = [addr for addr in cc_line.split(',') if addr]
|
||||
if GMOCK_GROUP not in cc_list:
|
||||
cc_list.append(GMOCK_GROUP)
|
||||
upload_py_argv.append(CC_FLAG + ','.join(cc_list))
|
||||
else:
|
||||
upload_py_argv.append(arg)
|
||||
|
||||
if not found_cc_flag:
|
||||
upload_py_argv.append(CC_FLAG + GMOCK_GROUP)
|
||||
|
||||
# Invokes upload.py with the modified command line flags.
|
||||
os.execv(upload_py_path, upload_py_argv)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -0,0 +1,43 @@
|
||||
// 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.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
//
|
||||
// Google C++ Mocking Framework (Google Mock)
|
||||
//
|
||||
// This file #includes all Google Mock implementation .cc files. The
|
||||
// purpose is to allow a user to build Google Mock by compiling this
|
||||
// file alone.
|
||||
|
||||
#include "src/gmock-cardinalities.cc"
|
||||
#include "src/gmock-internal-utils.cc"
|
||||
#include "src/gmock-matchers.cc"
|
||||
#include "src/gmock-printers.cc"
|
||||
#include "src/gmock-spec-builders.cc"
|
||||
#include "src/gmock.cc"
|
||||
@@ -0,0 +1,155 @@
|
||||
// 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)
|
||||
|
||||
// Google Mock - a framework for writing C++ mock classes.
|
||||
//
|
||||
// This file implements cardinalities.
|
||||
|
||||
#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>
|
||||
|
||||
namespace testing {
|
||||
|
||||
namespace {
|
||||
|
||||
// Implements the Between(m, n) cardinality.
|
||||
class BetweenCardinalityImpl : public CardinalityInterface {
|
||||
public:
|
||||
BetweenCardinalityImpl(int min, int max)
|
||||
: min_(min >= 0 ? min : 0),
|
||||
max_(max >= min_ ? max : min_) {
|
||||
std::stringstream ss;
|
||||
if (min < 0) {
|
||||
ss << "The invocation lower bound must be >= 0, "
|
||||
<< "but is actually " << min << ".";
|
||||
internal::Expect(false, __FILE__, __LINE__, ss.str());
|
||||
} else if (max < 0) {
|
||||
ss << "The invocation upper bound must be >= 0, "
|
||||
<< "but is actually " << max << ".";
|
||||
internal::Expect(false, __FILE__, __LINE__, ss.str());
|
||||
} else if (min > max) {
|
||||
ss << "The invocation upper bound (" << max
|
||||
<< ") must be >= the invocation lower bound (" << min
|
||||
<< ").";
|
||||
internal::Expect(false, __FILE__, __LINE__, ss.str());
|
||||
}
|
||||
}
|
||||
|
||||
// Conservative estimate on the lower/upper bound of the number of
|
||||
// calls allowed.
|
||||
virtual int ConservativeLowerBound() const { return min_; }
|
||||
virtual int ConservativeUpperBound() const { return max_; }
|
||||
|
||||
virtual bool IsSatisfiedByCallCount(int call_count) const {
|
||||
return min_ <= call_count && call_count <= max_ ;
|
||||
}
|
||||
|
||||
virtual bool IsSaturatedByCallCount(int call_count) const {
|
||||
return call_count >= max_;
|
||||
}
|
||||
|
||||
virtual void DescribeTo(::std::ostream* os) const;
|
||||
private:
|
||||
const int min_;
|
||||
const int max_;
|
||||
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(BetweenCardinalityImpl);
|
||||
};
|
||||
|
||||
// Formats "n times" in a human-friendly way.
|
||||
inline internal::string FormatTimes(int n) {
|
||||
if (n == 1) {
|
||||
return "once";
|
||||
} else if (n == 2) {
|
||||
return "twice";
|
||||
} else {
|
||||
std::stringstream ss;
|
||||
ss << n << " times";
|
||||
return ss.str();
|
||||
}
|
||||
}
|
||||
|
||||
// Describes the Between(m, n) cardinality in human-friendly text.
|
||||
void BetweenCardinalityImpl::DescribeTo(::std::ostream* os) const {
|
||||
if (min_ == 0) {
|
||||
if (max_ == 0) {
|
||||
*os << "never called";
|
||||
} else if (max_ == INT_MAX) {
|
||||
*os << "called any number of times";
|
||||
} else {
|
||||
*os << "called at most " << FormatTimes(max_);
|
||||
}
|
||||
} else if (min_ == max_) {
|
||||
*os << "called " << FormatTimes(min_);
|
||||
} else if (max_ == INT_MAX) {
|
||||
*os << "called at least " << FormatTimes(min_);
|
||||
} else {
|
||||
// 0 < min_ < max_ < INT_MAX
|
||||
*os << "called between " << min_ << " and " << max_ << " times";
|
||||
}
|
||||
}
|
||||
|
||||
} // Unnamed namespace
|
||||
|
||||
// Describes the given call count to an ostream.
|
||||
void Cardinality::DescribeActualCallCountTo(int actual_call_count,
|
||||
::std::ostream* os) {
|
||||
if (actual_call_count > 0) {
|
||||
*os << "called " << FormatTimes(actual_call_count);
|
||||
} else {
|
||||
*os << "never called";
|
||||
}
|
||||
}
|
||||
|
||||
// Creates a cardinality that allows at least n calls.
|
||||
Cardinality AtLeast(int n) { return Between(n, INT_MAX); }
|
||||
|
||||
// Creates a cardinality that allows at most n calls.
|
||||
Cardinality AtMost(int n) { return Between(0, n); }
|
||||
|
||||
// Creates a cardinality that allows any number of calls.
|
||||
Cardinality AnyNumber() { return AtLeast(0); }
|
||||
|
||||
// Creates a cardinality that allows between min and max calls.
|
||||
Cardinality Between(int min, int max) {
|
||||
return Cardinality(new BetweenCardinalityImpl(min, max));
|
||||
}
|
||||
|
||||
// Creates a cardinality that allows exactly n calls.
|
||||
Cardinality Exactly(int n) { return Between(n, n); }
|
||||
|
||||
} // namespace testing
|
||||
@@ -0,0 +1,159 @@
|
||||
// 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)
|
||||
|
||||
// Google Mock - a framework for writing C++ mock classes.
|
||||
//
|
||||
// This file defines some utilities useful for implementing Google
|
||||
// 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 <ctype.h>
|
||||
#include <ostream> // NOLINT
|
||||
#include <string>
|
||||
#include <gmock/gmock.h>
|
||||
#include <gmock/internal/gmock-port.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
namespace testing {
|
||||
namespace internal {
|
||||
|
||||
// Converts an identifier name to a space-separated list of lower-case
|
||||
// words. Each maximum substring of the form [A-Za-z][a-z]*|\d+ is
|
||||
// treated as one word. For example, both "FooBar123" and
|
||||
// "foo_bar_123" are converted to "foo bar 123".
|
||||
string ConvertIdentifierNameToWords(const char* id_name) {
|
||||
string result;
|
||||
char prev_char = '\0';
|
||||
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));
|
||||
|
||||
if (isalnum(*p)) {
|
||||
if (starts_new_word && result != "")
|
||||
result += ' ';
|
||||
result += tolower(*p);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// This class reports Google Mock failures as Google Test failures. A
|
||||
// user can define another class in a similar fashion if he intends to
|
||||
// use Google Mock with a testing framework other than Google Test.
|
||||
class GoogleTestFailureReporter : public FailureReporterInterface {
|
||||
public:
|
||||
virtual void ReportFailure(FailureType type, const char* file, int line,
|
||||
const string& message) {
|
||||
AssertHelper(type == FATAL ? TPRT_FATAL_FAILURE : TPRT_NONFATAL_FAILURE,
|
||||
file, line, message.c_str()) = Message();
|
||||
if (type == FATAL) {
|
||||
abort();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Returns the global failure reporter. Will create a
|
||||
// GoogleTestFailureReporter and return it the first time called.
|
||||
FailureReporterInterface* GetFailureReporter() {
|
||||
// Points to the global failure reporter used by Google Mock. gcc
|
||||
// guarantees that the following use of failure_reporter is
|
||||
// thread-safe. We may need to add additional synchronization to
|
||||
// protect failure_reporter if we port Google Mock to other
|
||||
// compilers.
|
||||
static FailureReporterInterface* const failure_reporter =
|
||||
new GoogleTestFailureReporter();
|
||||
return failure_reporter;
|
||||
}
|
||||
|
||||
// Protects global resources (stdout in particular) used by Log().
|
||||
static Mutex g_log_mutex(Mutex::NO_CONSTRUCTOR_NEEDED_FOR_STATIC_MUTEX);
|
||||
|
||||
// Prints the given message to stdout iff 'severity' >= the level
|
||||
// specified by the --gmock_verbose flag. If stack_frames_to_skip >=
|
||||
// 0, also prints the stack trace excluding the top
|
||||
// stack_frames_to_skip frames. In opt mode, any positive
|
||||
// stack_frames_to_skip is treated as 0, since we don't know which
|
||||
// function calls will be inlined by the compiler and need to be
|
||||
// conservative.
|
||||
void Log(LogSeverity severity, const string& message,
|
||||
int stack_frames_to_skip) {
|
||||
if (GMOCK_FLAG(verbose) == kErrorVerbosity) {
|
||||
// The user is not interested in logs.
|
||||
return;
|
||||
} else if (GMOCK_FLAG(verbose) != kInfoVerbosity) {
|
||||
// The user is interested in warnings but not informational logs.
|
||||
// Note that invalid values of GMOCK_FLAG(verbose) are treated as
|
||||
// "warning", which is the default value of the flag.
|
||||
if (severity == INFO) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Ensures that logs from different threads don't interleave.
|
||||
MutexLock l(&g_log_mutex);
|
||||
using ::std::cout;
|
||||
if (severity == WARNING) {
|
||||
// Prints a GMOCK WARNING marker to make the warnings easily searchable.
|
||||
cout << "\nGMOCK WARNING:";
|
||||
}
|
||||
// Pre-pends a new-line to message if it doesn't start with one.
|
||||
if (message.empty() || message[0] != '\n') {
|
||||
cout << "\n";
|
||||
}
|
||||
cout << message;
|
||||
if (stack_frames_to_skip >= 0) {
|
||||
#ifdef NDEBUG
|
||||
// In opt mode, we have to be conservative and skip no stack frame.
|
||||
const int actual_to_skip = 0;
|
||||
#else
|
||||
// In dbg mode, we can do what the caller tell us to do (plus one
|
||||
// for skipping this function's stack frame).
|
||||
const int actual_to_skip = stack_frames_to_skip + 1;
|
||||
#endif // NDEBUG
|
||||
|
||||
// Appends a new-line to message if it doesn't end with one.
|
||||
if (!message.empty() && *message.rbegin() != '\n') {
|
||||
cout << "\n";
|
||||
}
|
||||
cout << "Stack trace:\n"
|
||||
<< ::testing::internal::GetCurrentOsStackTraceExceptTop(
|
||||
::testing::UnitTest::GetInstance(), actual_to_skip);
|
||||
}
|
||||
cout << ::std::flush;
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace testing
|
||||
@@ -0,0 +1,202 @@
|
||||
// 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)
|
||||
|
||||
// Google Mock - a framework for writing C++ mock classes.
|
||||
//
|
||||
// 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 <string.h>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
namespace testing {
|
||||
|
||||
// Constructs a matcher that matches a const string& whose value is
|
||||
// equal to s.
|
||||
Matcher<const internal::string&>::Matcher(const internal::string& s) {
|
||||
*this = Eq(s);
|
||||
}
|
||||
|
||||
// Constructs a matcher that matches a const string& whose value is
|
||||
// equal to s.
|
||||
Matcher<const internal::string&>::Matcher(const char* s) {
|
||||
*this = Eq(internal::string(s));
|
||||
}
|
||||
|
||||
// Constructs a matcher that matches a string whose value is equal to s.
|
||||
Matcher<internal::string>::Matcher(const internal::string& s) { *this = Eq(s); }
|
||||
|
||||
// Constructs a matcher that matches a string whose value is equal to s.
|
||||
Matcher<internal::string>::Matcher(const char* s) {
|
||||
*this = Eq(internal::string(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;
|
||||
}
|
||||
|
||||
// If *pstr starts with the given prefix, modifies *pstr to be right
|
||||
// past the prefix and returns true; otherwise leaves *pstr unchanged
|
||||
// and returns false. None of pstr, *pstr, and prefix can be NULL.
|
||||
bool SkipPrefix(const char* prefix, const char** pstr) {
|
||||
const size_t prefix_len = strlen(prefix);
|
||||
if (strncmp(*pstr, prefix, prefix_len) == 0) {
|
||||
*pstr += prefix_len;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// 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) {
|
||||
switch (fields.size()) {
|
||||
case 0:
|
||||
return "";
|
||||
case 1:
|
||||
return fields[0];
|
||||
default:
|
||||
string result = "(" + fields[0];
|
||||
for (size_t i = 1; i < fields.size(); i++) {
|
||||
result += ", ";
|
||||
result += fields[i];
|
||||
}
|
||||
result += ")";
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace testing
|
||||
@@ -0,0 +1,313 @@
|
||||
// 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)
|
||||
|
||||
// Google Mock - a framework for writing C++ mock classes.
|
||||
//
|
||||
// This file implements a universal value printer that can print a
|
||||
// value of any type T:
|
||||
//
|
||||
// void ::testing::internal::UniversalPrinter<T>::Print(value, ostream_ptr);
|
||||
//
|
||||
// It uses the << operator when possible, and prints the bytes in the
|
||||
// object otherwise. A user can override its behavior for a class
|
||||
// type Foo by defining either operator<<(::std::ostream&, const Foo&)
|
||||
// or void PrintTo(const Foo&, ::std::ostream*) in the namespace that
|
||||
// defines Foo.
|
||||
|
||||
#include <gmock/gmock-printers.h>
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <ostream> // NOLINT
|
||||
#include <string>
|
||||
#include <gmock/internal/gmock-port.h>
|
||||
|
||||
namespace testing {
|
||||
|
||||
namespace {
|
||||
|
||||
using ::std::ostream;
|
||||
|
||||
#ifdef _WIN32_WCE
|
||||
#define snprintf _snprintf
|
||||
#elif GTEST_OS_WINDOWS
|
||||
#define snprintf _snprintf_s
|
||||
#endif
|
||||
|
||||
// Prints a segment of bytes in the given object.
|
||||
void PrintByteSegmentInObjectTo(const unsigned char* obj_bytes, size_t start,
|
||||
size_t count, ostream* os) {
|
||||
char text[5] = "";
|
||||
for (size_t i = 0; i != count; i++) {
|
||||
const size_t j = start + i;
|
||||
if (i != 0) {
|
||||
// Organizes the bytes into groups of 2 for easy parsing by
|
||||
// human.
|
||||
if ((j % 2) == 0) {
|
||||
*os << " ";
|
||||
}
|
||||
}
|
||||
snprintf(text, sizeof(text), "%02X", obj_bytes[j]);
|
||||
*os << text;
|
||||
}
|
||||
}
|
||||
|
||||
// Prints the bytes in the given value to the given ostream.
|
||||
void PrintBytesInObjectToImpl(const unsigned char* obj_bytes, size_t count,
|
||||
ostream* os) {
|
||||
// Tells the user how big the object is.
|
||||
*os << count << "-byte object <";
|
||||
|
||||
const size_t kThreshold = 132;
|
||||
const size_t kChunkSize = 64;
|
||||
// If the object size is bigger than kThreshold, we'll have to omit
|
||||
// some details by printing only the first and the last kChunkSize
|
||||
// bytes.
|
||||
// TODO(wan): let the user control the threshold using a flag.
|
||||
if (count < kThreshold) {
|
||||
PrintByteSegmentInObjectTo(obj_bytes, 0, count, os);
|
||||
} else {
|
||||
PrintByteSegmentInObjectTo(obj_bytes, 0, kChunkSize, os);
|
||||
*os << " ... ";
|
||||
// Rounds up to 2-byte boundary.
|
||||
const size_t resume_pos = (count - kChunkSize + 1)/2*2;
|
||||
PrintByteSegmentInObjectTo(obj_bytes, resume_pos, count - resume_pos, os);
|
||||
}
|
||||
*os << ">";
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace internal2 {
|
||||
|
||||
// Delegates to PrintBytesInObjectToImpl() to print the bytes in the
|
||||
// given object. The delegation simplifies the implementation, which
|
||||
// uses the << operator and thus is easier done outside of the
|
||||
// ::testing::internal namespace, which contains a << operator that
|
||||
// sometimes conflicts with the one in STL.
|
||||
void PrintBytesInObjectTo(const unsigned char* obj_bytes, size_t count,
|
||||
ostream* os) {
|
||||
PrintBytesInObjectToImpl(obj_bytes, count, os);
|
||||
}
|
||||
|
||||
} // namespace internal2
|
||||
|
||||
namespace internal {
|
||||
|
||||
// Prints a wide char as a char literal without the quotes, escaping it
|
||||
// when necessary.
|
||||
static void PrintAsWideCharLiteralTo(wchar_t c, ostream* os) {
|
||||
switch (c) {
|
||||
case L'\0':
|
||||
*os << "\\0";
|
||||
break;
|
||||
case L'\'':
|
||||
*os << "\\'";
|
||||
break;
|
||||
case L'\?':
|
||||
*os << "\\?";
|
||||
break;
|
||||
case L'\\':
|
||||
*os << "\\\\";
|
||||
break;
|
||||
case L'\a':
|
||||
*os << "\\a";
|
||||
break;
|
||||
case L'\b':
|
||||
*os << "\\b";
|
||||
break;
|
||||
case L'\f':
|
||||
*os << "\\f";
|
||||
break;
|
||||
case L'\n':
|
||||
*os << "\\n";
|
||||
break;
|
||||
case L'\r':
|
||||
*os << "\\r";
|
||||
break;
|
||||
case L'\t':
|
||||
*os << "\\t";
|
||||
break;
|
||||
case L'\v':
|
||||
*os << "\\v";
|
||||
break;
|
||||
default:
|
||||
// Checks whether c is printable or not. Printable characters are in
|
||||
// the range [0x20,0x7E].
|
||||
// We test the value of c directly instead of calling isprint(), as
|
||||
// isprint() is buggy on Windows mobile.
|
||||
if (0x20 <= c && c <= 0x7E) {
|
||||
*os << static_cast<char>(c);
|
||||
} else {
|
||||
// Buffer size enough for the maximum number of digits and \0.
|
||||
char text[2 * sizeof(unsigned long) + 1] = "";
|
||||
snprintf(text, sizeof(text), "%lX", static_cast<unsigned long>(c));
|
||||
*os << "\\x" << text;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Prints a char as if it's part of a string literal, escaping it when
|
||||
// necessary.
|
||||
static void PrintAsWideStringLiteralTo(wchar_t c, ostream* os) {
|
||||
switch (c) {
|
||||
case L'\'':
|
||||
*os << "'";
|
||||
break;
|
||||
case L'"':
|
||||
*os << "\\\"";
|
||||
break;
|
||||
default:
|
||||
PrintAsWideCharLiteralTo(c, os);
|
||||
}
|
||||
}
|
||||
|
||||
// Prints a char as a char literal without the quotes, escaping it
|
||||
// when necessary.
|
||||
static void PrintAsCharLiteralTo(char c, ostream* os) {
|
||||
PrintAsWideCharLiteralTo(static_cast<unsigned char>(c), os);
|
||||
}
|
||||
|
||||
// Prints a char as if it's part of a string literal, escaping it when
|
||||
// necessary.
|
||||
static void PrintAsStringLiteralTo(char c, ostream* os) {
|
||||
PrintAsWideStringLiteralTo(static_cast<unsigned char>(c), os);
|
||||
}
|
||||
|
||||
// Prints a char and its code. The '\0' char is printed as "'\\0'",
|
||||
// other unprintable characters are also properly escaped using the
|
||||
// standard C++ escape sequence.
|
||||
void PrintCharTo(char c, int char_code, ostream* os) {
|
||||
*os << "'";
|
||||
PrintAsCharLiteralTo(c, os);
|
||||
*os << "'";
|
||||
if (c != '\0')
|
||||
*os << " (" << char_code << ")";
|
||||
}
|
||||
|
||||
// Prints a wchar_t as a symbol if it is printable or as its internal
|
||||
// code otherwise and also as its decimal code (except for L'\0').
|
||||
// The L'\0' char is printed as "L'\\0'". The decimal code is printed
|
||||
// as signed integer when wchar_t is implemented by the compiler
|
||||
// as a signed type and is printed as an unsigned integer when wchar_t
|
||||
// is implemented as an unsigned type.
|
||||
void PrintTo(wchar_t wc, ostream* os) {
|
||||
*os << "L'";
|
||||
PrintAsWideCharLiteralTo(wc, os);
|
||||
*os << "'";
|
||||
if (wc != L'\0') {
|
||||
// Type Int64 is used because it provides more storage than wchar_t thus
|
||||
// when the compiler converts signed or unsigned implementation of wchar_t
|
||||
// to Int64 it fills higher bits with either zeros or the sign bit
|
||||
// passing it to operator <<() as either signed or unsigned integer.
|
||||
*os << " (" << static_cast<Int64>(wc) << ")";
|
||||
}
|
||||
}
|
||||
|
||||
// Prints the given array of characters to the ostream.
|
||||
// The array starts at *begin, the length is len, it may include '\0' characters
|
||||
// and may not be null-terminated.
|
||||
static void PrintCharsAsStringTo(const char* begin, size_t len, ostream* os) {
|
||||
*os << "\"";
|
||||
for (size_t index = 0; index < len; ++index) {
|
||||
PrintAsStringLiteralTo(begin[index], os);
|
||||
}
|
||||
*os << "\"";
|
||||
}
|
||||
|
||||
// Prints the given array of wide characters to the ostream.
|
||||
// The array starts at *begin, the length is len, it may include L'\0'
|
||||
// characters and may not be null-terminated.
|
||||
static void PrintWideCharsAsStringTo(const wchar_t* begin, size_t len,
|
||||
ostream* os) {
|
||||
*os << "L\"";
|
||||
for (size_t index = 0; index < len; ++index) {
|
||||
PrintAsWideStringLiteralTo(begin[index], os);
|
||||
}
|
||||
*os << "\"";
|
||||
}
|
||||
|
||||
// Prints the given C string to the ostream.
|
||||
void PrintTo(const char* s, ostream* os) {
|
||||
if (s == NULL) {
|
||||
*os << "NULL";
|
||||
} else {
|
||||
*os << implicit_cast<const void*>(s) << " pointing to ";
|
||||
PrintCharsAsStringTo(s, strlen(s), os);
|
||||
}
|
||||
}
|
||||
|
||||
// MSVC compiler can be configured to define whar_t as a typedef
|
||||
// of unsigned short. Defining an overload for const wchar_t* in that case
|
||||
// would cause pointers to unsigned shorts be printed as wide strings,
|
||||
// possibly accessing more memory than intended and causing invalid
|
||||
// memory accesses. MSVC defines _NATIVE_WCHAR_T_DEFINED symbol when
|
||||
// wchar_t is implemented as a native type.
|
||||
#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED)
|
||||
// Prints the given wide C string to the ostream.
|
||||
void PrintTo(const wchar_t* s, ostream* os) {
|
||||
if (s == NULL) {
|
||||
*os << "NULL";
|
||||
} else {
|
||||
*os << implicit_cast<const void*>(s) << " pointing to ";
|
||||
PrintWideCharsAsStringTo(s, wcslen(s), os);
|
||||
}
|
||||
}
|
||||
#endif // wchar_t is native
|
||||
|
||||
// Prints a ::string object.
|
||||
#if GTEST_HAS_GLOBAL_STRING
|
||||
void PrintStringTo(const ::string& s, ostream* os) {
|
||||
PrintCharsAsStringTo(s.data(), s.size(), os);
|
||||
}
|
||||
#endif // GTEST_HAS_GLOBAL_STRING
|
||||
|
||||
#if GTEST_HAS_STD_STRING
|
||||
void PrintStringTo(const ::std::string& s, ostream* os) {
|
||||
PrintCharsAsStringTo(s.data(), s.size(), os);
|
||||
}
|
||||
#endif // GTEST_HAS_STD_STRING
|
||||
|
||||
// Prints a ::wstring object.
|
||||
#if GTEST_HAS_GLOBAL_WSTRING
|
||||
void PrintWideStringTo(const ::wstring& s, ostream* os) {
|
||||
PrintWideCharsAsStringTo(s.data(), s.size(), os);
|
||||
}
|
||||
#endif // GTEST_HAS_GLOBAL_WSTRING
|
||||
|
||||
#if GTEST_HAS_STD_WSTRING
|
||||
void PrintWideStringTo(const ::std::wstring& s, ostream* os) {
|
||||
PrintWideCharsAsStringTo(s.data(), s.size(), os);
|
||||
}
|
||||
#endif // GTEST_HAS_STD_WSTRING
|
||||
|
||||
} // namespace internal
|
||||
|
||||
} // namespace testing
|
||||
@@ -0,0 +1,453 @@
|
||||
// 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)
|
||||
|
||||
// Google Mock - a framework for writing C++ mock classes.
|
||||
//
|
||||
// This file implements the spec builder syntax (ON_CALL and
|
||||
// EXPECT_CALL).
|
||||
|
||||
#include <gmock/gmock-spec-builders.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <iostream> // NOLINT
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <gmock/gmock.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#if GTEST_OS_CYGWIN || GTEST_OS_LINUX || GTEST_OS_MAC
|
||||
#include <unistd.h> // NOLINT
|
||||
#endif
|
||||
|
||||
namespace testing {
|
||||
namespace internal {
|
||||
|
||||
// Protects the mock object registry (in class Mock), all function
|
||||
// mockers, and all expectations.
|
||||
Mutex g_gmock_mutex(Mutex::NO_CONSTRUCTOR_NEEDED_FOR_STATIC_MUTEX);
|
||||
|
||||
// Constructs an ExpectationBase object.
|
||||
ExpectationBase::ExpectationBase(const char* file, int line)
|
||||
: file_(file),
|
||||
line_(line),
|
||||
cardinality_specified_(false),
|
||||
cardinality_(Exactly(1)),
|
||||
call_count_(0),
|
||||
retired_(false) {
|
||||
}
|
||||
|
||||
// Destructs an ExpectationBase object.
|
||||
ExpectationBase::~ExpectationBase() {}
|
||||
|
||||
// Explicitly specifies the cardinality of this expectation. Used by
|
||||
// the subclasses to implement the .Times() clause.
|
||||
void ExpectationBase::SpecifyCardinality(const Cardinality& cardinality) {
|
||||
cardinality_specified_ = true;
|
||||
cardinality_ = cardinality;
|
||||
}
|
||||
|
||||
// Retires all pre-requisites of this expectation.
|
||||
void ExpectationBase::RetireAllPreRequisites() {
|
||||
if (is_retired()) {
|
||||
// We can take this short-cut as we never retire an expectation
|
||||
// until we have retired all its pre-requisites.
|
||||
return;
|
||||
}
|
||||
|
||||
for (ExpectationBaseSet::const_iterator it =
|
||||
immediate_prerequisites_.begin();
|
||||
it != immediate_prerequisites_.end();
|
||||
++it) {
|
||||
ExpectationBase* const prerequisite = (*it).get();
|
||||
if (!prerequisite->is_retired()) {
|
||||
prerequisite->RetireAllPreRequisites();
|
||||
prerequisite->Retire();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Returns true iff all pre-requisites of this expectation have been
|
||||
// satisfied.
|
||||
// L >= g_gmock_mutex
|
||||
bool ExpectationBase::AllPrerequisitesAreSatisfied() const {
|
||||
g_gmock_mutex.AssertHeld();
|
||||
for (ExpectationBaseSet::const_iterator it = immediate_prerequisites_.begin();
|
||||
it != immediate_prerequisites_.end(); ++it) {
|
||||
if (!(*it)->IsSatisfied() ||
|
||||
!(*it)->AllPrerequisitesAreSatisfied())
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Adds unsatisfied pre-requisites of this expectation to 'result'.
|
||||
// L >= g_gmock_mutex
|
||||
void ExpectationBase::FindUnsatisfiedPrerequisites(
|
||||
ExpectationBaseSet* result) const {
|
||||
g_gmock_mutex.AssertHeld();
|
||||
for (ExpectationBaseSet::const_iterator it = immediate_prerequisites_.begin();
|
||||
it != immediate_prerequisites_.end(); ++it) {
|
||||
if ((*it)->IsSatisfied()) {
|
||||
// If *it is satisfied and has a call count of 0, some of its
|
||||
// pre-requisites may not be satisfied yet.
|
||||
if ((*it)->call_count_ == 0) {
|
||||
(*it)->FindUnsatisfiedPrerequisites(result);
|
||||
}
|
||||
} else {
|
||||
// Now that we know *it is unsatisfied, we are not so interested
|
||||
// in whether its pre-requisites are satisfied. Therefore we
|
||||
// don't recursively call FindUnsatisfiedPrerequisites() here.
|
||||
result->insert(*it);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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;
|
||||
|
||||
// Reports an uninteresting call (whose description is in msg) in the
|
||||
// manner specified by 'reaction'.
|
||||
void ReportUninterestingCall(CallReaction reaction, const string& msg) {
|
||||
switch (reaction) {
|
||||
case ALLOW:
|
||||
Log(INFO, msg, 4);
|
||||
break;
|
||||
case WARN:
|
||||
Log(WARNING, msg, 4);
|
||||
break;
|
||||
default: // FAIL
|
||||
Expect(false, NULL, -1, msg);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
|
||||
// Class Mock.
|
||||
|
||||
namespace {
|
||||
|
||||
typedef std::set<internal::UntypedFunctionMockerBase*> FunctionMockers;
|
||||
|
||||
// The current state of a mock object. Such information is needed for
|
||||
// detecting leaked mock objects and explicitly verifying a mock's
|
||||
// expectations.
|
||||
struct MockObjectState {
|
||||
MockObjectState()
|
||||
: first_used_file(NULL), first_used_line(-1), leakable(false) {}
|
||||
|
||||
// Where in the source file an ON_CALL or EXPECT_CALL is first
|
||||
// invoked on this mock object.
|
||||
const char* first_used_file;
|
||||
int first_used_line;
|
||||
::std::string first_used_test_case;
|
||||
::std::string first_used_test;
|
||||
bool leakable; // true iff it's OK to leak the object.
|
||||
FunctionMockers function_mockers; // All registered methods of the object.
|
||||
};
|
||||
|
||||
// A global registry holding the state of all mock objects that are
|
||||
// alive. A mock object is added to this registry the first time
|
||||
// Mock::AllowLeak(), ON_CALL(), or EXPECT_CALL() is called on it. It
|
||||
// is removed from the registry in the mock object's destructor.
|
||||
class MockObjectRegistry {
|
||||
public:
|
||||
// Maps a mock object (identified by its address) to its state.
|
||||
typedef std::map<const void*, MockObjectState> StateMap;
|
||||
|
||||
// This destructor will be called when a program exits, after all
|
||||
// tests in it have been run. By then, there should be no mock
|
||||
// object alive. Therefore we report any living object as test
|
||||
// failure, unless the user explicitly asked us to ignore it.
|
||||
~MockObjectRegistry() {
|
||||
using ::std::cout;
|
||||
|
||||
if (!GMOCK_FLAG(catch_leaked_mocks))
|
||||
return;
|
||||
|
||||
int leaked_count = 0;
|
||||
for (StateMap::const_iterator it = states_.begin(); it != states_.end();
|
||||
++it) {
|
||||
if (it->second.leakable) // The user said it's fine to leak this object.
|
||||
continue;
|
||||
|
||||
// TODO(wan@google.com): Print the type of the leaked object.
|
||||
// This can help the user identify the leaked object.
|
||||
cout << "\n";
|
||||
const MockObjectState& state = it->second;
|
||||
internal::FormatFileLocation(
|
||||
state.first_used_file, state.first_used_line, &cout);
|
||||
cout << " ERROR: this mock object";
|
||||
if (state.first_used_test != "") {
|
||||
cout << " (used in test " << state.first_used_test_case << "."
|
||||
<< state.first_used_test << ")";
|
||||
}
|
||||
cout << " should be deleted but never is. Its address is @"
|
||||
<< it->first << ".";
|
||||
leaked_count++;
|
||||
}
|
||||
if (leaked_count > 0) {
|
||||
cout << "\nERROR: " << leaked_count
|
||||
<< " leaked mock " << (leaked_count == 1 ? "object" : "objects")
|
||||
<< " found at program exit.\n";
|
||||
cout.flush();
|
||||
::std::cerr.flush();
|
||||
// RUN_ALL_TESTS() has already returned when this destructor is
|
||||
// called. Therefore we cannot use the normal Google Test
|
||||
// failure reporting mechanism.
|
||||
_exit(1); // We cannot call exit() as it is not reentrant and
|
||||
// may already have been called.
|
||||
}
|
||||
}
|
||||
|
||||
StateMap& states() { return states_; }
|
||||
private:
|
||||
StateMap states_;
|
||||
};
|
||||
|
||||
// Protected by g_gmock_mutex.
|
||||
MockObjectRegistry g_mock_object_registry;
|
||||
|
||||
// Maps a mock object to the reaction Google Mock should have when an
|
||||
// uninteresting method is called. Protected by g_gmock_mutex.
|
||||
std::map<const void*, internal::CallReaction> g_uninteresting_call_reaction;
|
||||
|
||||
// Sets the reaction Google Mock should have when an uninteresting
|
||||
// method of the given mock object is called.
|
||||
// L < g_gmock_mutex
|
||||
void SetReactionOnUninterestingCalls(const void* mock_obj,
|
||||
internal::CallReaction reaction) {
|
||||
internal::MutexLock l(&internal::g_gmock_mutex);
|
||||
g_uninteresting_call_reaction[mock_obj] = reaction;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
// Tells Google Mock to allow uninteresting calls on the given mock
|
||||
// object.
|
||||
// L < g_gmock_mutex
|
||||
void Mock::AllowUninterestingCalls(const void* mock_obj) {
|
||||
SetReactionOnUninterestingCalls(mock_obj, internal::ALLOW);
|
||||
}
|
||||
|
||||
// Tells Google Mock to warn the user about uninteresting calls on the
|
||||
// given mock object.
|
||||
// L < g_gmock_mutex
|
||||
void Mock::WarnUninterestingCalls(const void* mock_obj) {
|
||||
SetReactionOnUninterestingCalls(mock_obj, internal::WARN);
|
||||
}
|
||||
|
||||
// Tells Google Mock to fail uninteresting calls on the given mock
|
||||
// object.
|
||||
// L < g_gmock_mutex
|
||||
void Mock::FailUninterestingCalls(const void* mock_obj) {
|
||||
SetReactionOnUninterestingCalls(mock_obj, internal::FAIL);
|
||||
}
|
||||
|
||||
// Tells Google Mock the given mock object is being destroyed and its
|
||||
// entry in the call-reaction table should be removed.
|
||||
// L < g_gmock_mutex
|
||||
void Mock::UnregisterCallReaction(const void* mock_obj) {
|
||||
internal::MutexLock l(&internal::g_gmock_mutex);
|
||||
g_uninteresting_call_reaction.erase(mock_obj);
|
||||
}
|
||||
|
||||
// Returns the reaction Google Mock will have on uninteresting calls
|
||||
// made on the given mock object.
|
||||
// L < g_gmock_mutex
|
||||
internal::CallReaction Mock::GetReactionOnUninterestingCalls(
|
||||
const void* mock_obj) {
|
||||
internal::MutexLock l(&internal::g_gmock_mutex);
|
||||
return (g_uninteresting_call_reaction.count(mock_obj) == 0) ?
|
||||
internal::WARN : g_uninteresting_call_reaction[mock_obj];
|
||||
}
|
||||
|
||||
// Tells Google Mock to ignore mock_obj when checking for leaked mock
|
||||
// objects.
|
||||
// L < g_gmock_mutex
|
||||
void Mock::AllowLeak(const void* mock_obj) {
|
||||
internal::MutexLock l(&internal::g_gmock_mutex);
|
||||
g_mock_object_registry.states()[mock_obj].leakable = true;
|
||||
}
|
||||
|
||||
// Verifies and clears all expectations on the given mock object. If
|
||||
// the expectations aren't satisfied, generates one or more Google
|
||||
// Test non-fatal failures and returns false.
|
||||
// L < g_gmock_mutex
|
||||
bool Mock::VerifyAndClearExpectations(void* mock_obj) {
|
||||
internal::MutexLock l(&internal::g_gmock_mutex);
|
||||
return VerifyAndClearExpectationsLocked(mock_obj);
|
||||
}
|
||||
|
||||
// Verifies all expectations on the given mock object and clears its
|
||||
// default actions and expectations. Returns true iff the
|
||||
// verification was successful.
|
||||
// L < g_gmock_mutex
|
||||
bool Mock::VerifyAndClear(void* mock_obj) {
|
||||
internal::MutexLock l(&internal::g_gmock_mutex);
|
||||
ClearDefaultActionsLocked(mock_obj);
|
||||
return VerifyAndClearExpectationsLocked(mock_obj);
|
||||
}
|
||||
|
||||
// Verifies and clears all expectations on the given mock object. If
|
||||
// the expectations aren't satisfied, generates one or more Google
|
||||
// Test non-fatal failures and returns false.
|
||||
// L >= g_gmock_mutex
|
||||
bool Mock::VerifyAndClearExpectationsLocked(void* mock_obj) {
|
||||
internal::g_gmock_mutex.AssertHeld();
|
||||
if (g_mock_object_registry.states().count(mock_obj) == 0) {
|
||||
// No EXPECT_CALL() was set on the given mock object.
|
||||
return true;
|
||||
}
|
||||
|
||||
// Verifies and clears the expectations on each mock method in the
|
||||
// given mock object.
|
||||
bool expectations_met = true;
|
||||
FunctionMockers& mockers =
|
||||
g_mock_object_registry.states()[mock_obj].function_mockers;
|
||||
for (FunctionMockers::const_iterator it = mockers.begin();
|
||||
it != mockers.end(); ++it) {
|
||||
if (!(*it)->VerifyAndClearExpectationsLocked()) {
|
||||
expectations_met = false;
|
||||
}
|
||||
}
|
||||
|
||||
// We don't clear the content of mockers, as they may still be
|
||||
// needed by ClearDefaultActionsLocked().
|
||||
return expectations_met;
|
||||
}
|
||||
|
||||
// Registers a mock object and a mock method it owns.
|
||||
// L < g_gmock_mutex
|
||||
void Mock::Register(const void* mock_obj,
|
||||
internal::UntypedFunctionMockerBase* mocker) {
|
||||
internal::MutexLock l(&internal::g_gmock_mutex);
|
||||
g_mock_object_registry.states()[mock_obj].function_mockers.insert(mocker);
|
||||
}
|
||||
|
||||
// Tells Google Mock where in the source code mock_obj is used in an
|
||||
// ON_CALL or EXPECT_CALL. In case mock_obj is leaked, this
|
||||
// information helps the user identify which object it is.
|
||||
// L < g_gmock_mutex
|
||||
void Mock::RegisterUseByOnCallOrExpectCall(
|
||||
const void* mock_obj, const char* file, int line) {
|
||||
internal::MutexLock l(&internal::g_gmock_mutex);
|
||||
MockObjectState& state = g_mock_object_registry.states()[mock_obj];
|
||||
if (state.first_used_file == NULL) {
|
||||
state.first_used_file = file;
|
||||
state.first_used_line = line;
|
||||
const TestInfo* const test_info =
|
||||
UnitTest::GetInstance()->current_test_info();
|
||||
if (test_info != NULL) {
|
||||
// TODO(wan@google.com): record the test case name when the
|
||||
// ON_CALL or EXPECT_CALL is invoked from SetUpTestCase() or
|
||||
// TearDownTestCase().
|
||||
state.first_used_test_case = test_info->test_case_name();
|
||||
state.first_used_test = test_info->name();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Unregisters a mock method; removes the owning mock object from the
|
||||
// registry when the last mock method associated with it has been
|
||||
// unregistered. This is called only in the destructor of
|
||||
// FunctionMockerBase.
|
||||
// L >= g_gmock_mutex
|
||||
void Mock::UnregisterLocked(internal::UntypedFunctionMockerBase* mocker) {
|
||||
internal::g_gmock_mutex.AssertHeld();
|
||||
for (MockObjectRegistry::StateMap::iterator it =
|
||||
g_mock_object_registry.states().begin();
|
||||
it != g_mock_object_registry.states().end(); ++it) {
|
||||
FunctionMockers& mockers = it->second.function_mockers;
|
||||
if (mockers.erase(mocker) > 0) {
|
||||
// mocker was in mockers and has been just removed.
|
||||
if (mockers.empty()) {
|
||||
g_mock_object_registry.states().erase(it);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Clears all ON_CALL()s set on the given mock object.
|
||||
// L >= g_gmock_mutex
|
||||
void Mock::ClearDefaultActionsLocked(void* mock_obj) {
|
||||
internal::g_gmock_mutex.AssertHeld();
|
||||
|
||||
if (g_mock_object_registry.states().count(mock_obj) == 0) {
|
||||
// No ON_CALL() was set on the given mock object.
|
||||
return;
|
||||
}
|
||||
|
||||
// Clears the default actions for each mock method in the given mock
|
||||
// object.
|
||||
FunctionMockers& mockers =
|
||||
g_mock_object_registry.states()[mock_obj].function_mockers;
|
||||
for (FunctionMockers::const_iterator it = mockers.begin();
|
||||
it != mockers.end(); ++it) {
|
||||
(*it)->ClearDefaultActionsLocked();
|
||||
}
|
||||
|
||||
// We don't clear the content of mockers, as they may still be
|
||||
// needed by VerifyAndClearExpectationsLocked().
|
||||
}
|
||||
|
||||
// Adds an expectation to a sequence.
|
||||
void Sequence::AddExpectation(
|
||||
const internal::linked_ptr<internal::ExpectationBase>& expectation) const {
|
||||
if (*last_expectation_ != expectation) {
|
||||
if (*last_expectation_ != NULL) {
|
||||
expectation->immediate_prerequisites_.insert(*last_expectation_);
|
||||
}
|
||||
*last_expectation_ = expectation;
|
||||
}
|
||||
}
|
||||
|
||||
// Creates the implicit sequence if there isn't one.
|
||||
InSequence::InSequence() {
|
||||
if (internal::g_gmock_implicit_sequence.get() == NULL) {
|
||||
internal::g_gmock_implicit_sequence.set(new Sequence);
|
||||
sequence_created_ = true;
|
||||
} else {
|
||||
sequence_created_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Deletes the implicit sequence if it was created by the constructor
|
||||
// of this object.
|
||||
InSequence::~InSequence() {
|
||||
if (sequence_created_) {
|
||||
delete internal::g_gmock_implicit_sequence.get();
|
||||
internal::g_gmock_implicit_sequence.set(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace testing
|
||||
@@ -0,0 +1,182 @@
|
||||
// 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.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
|
||||
#include <gmock/gmock.h>
|
||||
#include <gmock/internal/gmock-port.h>
|
||||
|
||||
namespace testing {
|
||||
|
||||
// TODO(wan@google.com): support using environment variables to
|
||||
// control the flag values, like what Google Test does.
|
||||
|
||||
GMOCK_DEFINE_bool_(catch_leaked_mocks, true,
|
||||
"true iff Google Mock should report leaked mock objects "
|
||||
"as failures.");
|
||||
|
||||
GMOCK_DEFINE_string_(verbose, internal::kWarningVerbosity,
|
||||
"Controls how verbose Google Mock's output is."
|
||||
" Valid values:\n"
|
||||
" info - prints all messages.\n"
|
||||
" warning - prints warnings and errors.\n"
|
||||
" error - prints errors only.");
|
||||
|
||||
namespace internal {
|
||||
|
||||
// Parses a string as a command line flag. The string should have the
|
||||
// format "--gmock_flag=value". When def_optional is true, the
|
||||
// "=value" part can be omitted.
|
||||
//
|
||||
// Returns the value of the flag, or NULL if the parsing failed.
|
||||
static const char* ParseGoogleMockFlagValue(const char* str,
|
||||
const char* flag,
|
||||
bool def_optional) {
|
||||
// str and flag must not be NULL.
|
||||
if (str == NULL || flag == NULL) return NULL;
|
||||
|
||||
// The flag must start with "--gmock_".
|
||||
const String flag_str = String::Format("--gmock_%s", flag);
|
||||
const size_t flag_len = flag_str.GetLength();
|
||||
if (strncmp(str, flag_str.c_str(), flag_len) != 0) return NULL;
|
||||
|
||||
// Skips the flag name.
|
||||
const char* flag_end = str + flag_len;
|
||||
|
||||
// When def_optional is true, it's OK to not have a "=value" part.
|
||||
if (def_optional && (flag_end[0] == '\0')) {
|
||||
return flag_end;
|
||||
}
|
||||
|
||||
// If def_optional is true and there are more characters after the
|
||||
// flag name, or if def_optional is false, there must be a '=' after
|
||||
// the flag name.
|
||||
if (flag_end[0] != '=') return NULL;
|
||||
|
||||
// Returns the string after "=".
|
||||
return flag_end + 1;
|
||||
}
|
||||
|
||||
// Parses a string for a Google Mock bool flag, in the form of
|
||||
// "--gmock_flag=value".
|
||||
//
|
||||
// On success, stores the value of the flag in *value, and returns
|
||||
// true. On failure, returns false without changing *value.
|
||||
static bool ParseGoogleMockBoolFlag(const char* str, const char* flag,
|
||||
bool* value) {
|
||||
// Gets the value of the flag as a string.
|
||||
const char* const value_str = ParseGoogleMockFlagValue(str, flag, true);
|
||||
|
||||
// Aborts if the parsing failed.
|
||||
if (value_str == NULL) return false;
|
||||
|
||||
// Converts the string value to a bool.
|
||||
*value = !(*value_str == '0' || *value_str == 'f' || *value_str == 'F');
|
||||
return true;
|
||||
}
|
||||
|
||||
// Parses a string for a Google Mock string flag, in the form of
|
||||
// "--gmock_flag=value".
|
||||
//
|
||||
// On success, stores the value of the flag in *value, and returns
|
||||
// true. On failure, returns false without changing *value.
|
||||
static bool ParseGoogleMockStringFlag(const char* str, const char* flag,
|
||||
String* value) {
|
||||
// Gets the value of the flag as a string.
|
||||
const char* const value_str = ParseGoogleMockFlagValue(str, flag, false);
|
||||
|
||||
// Aborts if the parsing failed.
|
||||
if (value_str == NULL) return false;
|
||||
|
||||
// Sets *value to the value of the flag.
|
||||
*value = value_str;
|
||||
return true;
|
||||
}
|
||||
|
||||
// The internal implementation of InitGoogleMock().
|
||||
//
|
||||
// The type parameter CharType can be instantiated to either char or
|
||||
// wchar_t.
|
||||
template <typename CharType>
|
||||
void InitGoogleMockImpl(int* argc, CharType** argv) {
|
||||
// Makes sure Google Test is initialized. InitGoogleTest() is
|
||||
// idempotent, so it's fine if the user has already called it.
|
||||
InitGoogleTest(argc, argv);
|
||||
if (*argc <= 0) return;
|
||||
|
||||
for (int i = 1; i != *argc; i++) {
|
||||
const String arg_string = StreamableToString(argv[i]);
|
||||
const char* const arg = arg_string.c_str();
|
||||
|
||||
// Do we see a Google Mock flag?
|
||||
if (ParseGoogleMockBoolFlag(arg, "catch_leaked_mocks",
|
||||
&GMOCK_FLAG(catch_leaked_mocks)) ||
|
||||
ParseGoogleMockStringFlag(arg, "verbose", &GMOCK_FLAG(verbose))) {
|
||||
// Yes. Shift the remainder of the argv list left by one. Note
|
||||
// that argv has (*argc + 1) elements, the last one always being
|
||||
// NULL. The following loop moves the trailing NULL element as
|
||||
// well.
|
||||
for (int j = i; j != *argc; j++) {
|
||||
argv[j] = argv[j + 1];
|
||||
}
|
||||
|
||||
// Decrements the argument count.
|
||||
(*argc)--;
|
||||
|
||||
// We also need to decrement the iterator as we just removed
|
||||
// an element.
|
||||
i--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
|
||||
// Initializes Google Mock. This must be called before running the
|
||||
// tests. In particular, it parses a command line for the flags that
|
||||
// Google Mock recognizes. Whenever a Google Mock flag is seen, it is
|
||||
// removed from argv, and *argc is decremented.
|
||||
//
|
||||
// No value is returned. Instead, the Google Mock flag variables are
|
||||
// updated.
|
||||
//
|
||||
// Since Google Test is needed for Google Mock to work, this function
|
||||
// also initializes Google Test and parses its flags, if that hasn't
|
||||
// been done.
|
||||
void InitGoogleMock(int* argc, char** argv) {
|
||||
internal::InitGoogleMockImpl(argc, argv);
|
||||
}
|
||||
|
||||
// This overloaded version can be used in Windows programs compiled in
|
||||
// UNICODE mode.
|
||||
void InitGoogleMock(int* argc, wchar_t** argv) {
|
||||
internal::InitGoogleMockImpl(argc, argv);
|
||||
}
|
||||
|
||||
} // namespace testing
|
||||
@@ -0,0 +1,54 @@
|
||||
// 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.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
|
||||
#include <iostream>
|
||||
#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
|
||||
// is enabled. For this reason instead of _tmain, main function is used on
|
||||
// Windows. See the following link to track the current status of this bug:
|
||||
// http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=394464 // NOLINT
|
||||
#ifdef _WIN32_WCE
|
||||
#include <tchar.h> // NOLINT
|
||||
|
||||
int _tmain(int argc, TCHAR** argv) {
|
||||
#else
|
||||
int main(int argc, char** argv) {
|
||||
#endif // _WIN32_WCE
|
||||
std::cout << "Running main() from gmock_main.cc\n";
|
||||
// Since Google Mock depends on Google Test, InitGoogleMock() is
|
||||
// also responsible for initializing Google Test. Therefore there's
|
||||
// no need for calling testing::InitGoogleTest() separately.
|
||||
testing::InitGoogleMock(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
@@ -0,0 +1,422 @@
|
||||
// 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)
|
||||
|
||||
// Google Mock - a framework for writing C++ mock classes.
|
||||
//
|
||||
// This file tests the built-in cardinalities.
|
||||
|
||||
#include <gmock/gmock.h>
|
||||
#include <gtest/gtest.h>
|
||||
#include <gtest/gtest-spi.h>
|
||||
|
||||
namespace {
|
||||
|
||||
using std::stringstream;
|
||||
using testing::AnyNumber;
|
||||
using testing::AtLeast;
|
||||
using testing::AtMost;
|
||||
using testing::Between;
|
||||
using testing::Cardinality;
|
||||
using testing::CardinalityInterface;
|
||||
using testing::Exactly;
|
||||
using testing::IsSubstring;
|
||||
using testing::MakeCardinality;
|
||||
|
||||
class MockFoo {
|
||||
public:
|
||||
MOCK_METHOD0(Bar, int()); // NOLINT
|
||||
};
|
||||
|
||||
// Tests that Cardinality objects can be default constructed.
|
||||
TEST(CardinalityTest, IsDefaultConstructable) {
|
||||
Cardinality c;
|
||||
}
|
||||
|
||||
// Tests that Cardinality objects are copyable.
|
||||
TEST(CardinalityTest, IsCopyable) {
|
||||
// Tests the copy constructor.
|
||||
Cardinality c = Exactly(1);
|
||||
EXPECT_FALSE(c.IsSatisfiedByCallCount(0));
|
||||
EXPECT_TRUE(c.IsSatisfiedByCallCount(1));
|
||||
EXPECT_TRUE(c.IsSaturatedByCallCount(1));
|
||||
|
||||
// Tests the assignment operator.
|
||||
c = Exactly(2);
|
||||
EXPECT_FALSE(c.IsSatisfiedByCallCount(1));
|
||||
EXPECT_TRUE(c.IsSatisfiedByCallCount(2));
|
||||
EXPECT_TRUE(c.IsSaturatedByCallCount(2));
|
||||
}
|
||||
|
||||
TEST(CardinalityTest, IsOverSaturatedByCallCountWorks) {
|
||||
const Cardinality c = AtMost(5);
|
||||
EXPECT_FALSE(c.IsOverSaturatedByCallCount(4));
|
||||
EXPECT_FALSE(c.IsOverSaturatedByCallCount(5));
|
||||
EXPECT_TRUE(c.IsOverSaturatedByCallCount(6));
|
||||
}
|
||||
|
||||
// Tests that Cardinality::DescribeActualCallCountTo() creates the
|
||||
// correct description.
|
||||
TEST(CardinalityTest, CanDescribeActualCallCount) {
|
||||
stringstream ss0;
|
||||
Cardinality::DescribeActualCallCountTo(0, &ss0);
|
||||
EXPECT_EQ("never called", ss0.str());
|
||||
|
||||
stringstream ss1;
|
||||
Cardinality::DescribeActualCallCountTo(1, &ss1);
|
||||
EXPECT_EQ("called once", ss1.str());
|
||||
|
||||
stringstream ss2;
|
||||
Cardinality::DescribeActualCallCountTo(2, &ss2);
|
||||
EXPECT_EQ("called twice", ss2.str());
|
||||
|
||||
stringstream ss3;
|
||||
Cardinality::DescribeActualCallCountTo(3, &ss3);
|
||||
EXPECT_EQ("called 3 times", ss3.str());
|
||||
}
|
||||
|
||||
// Tests AnyNumber()
|
||||
TEST(AnyNumber, Works) {
|
||||
const Cardinality c = AnyNumber();
|
||||
EXPECT_TRUE(c.IsSatisfiedByCallCount(0));
|
||||
EXPECT_FALSE(c.IsSaturatedByCallCount(0));
|
||||
|
||||
EXPECT_TRUE(c.IsSatisfiedByCallCount(1));
|
||||
EXPECT_FALSE(c.IsSaturatedByCallCount(1));
|
||||
|
||||
EXPECT_TRUE(c.IsSatisfiedByCallCount(9));
|
||||
EXPECT_FALSE(c.IsSaturatedByCallCount(9));
|
||||
|
||||
stringstream ss;
|
||||
c.DescribeTo(&ss);
|
||||
EXPECT_PRED_FORMAT2(IsSubstring, "called any number of times",
|
||||
ss.str());
|
||||
}
|
||||
|
||||
TEST(AnyNumberTest, HasCorrectBounds) {
|
||||
const Cardinality c = AnyNumber();
|
||||
EXPECT_EQ(0, c.ConservativeLowerBound());
|
||||
EXPECT_EQ(INT_MAX, c.ConservativeUpperBound());
|
||||
}
|
||||
|
||||
// Tests AtLeast(n).
|
||||
|
||||
TEST(AtLeastTest, OnNegativeNumber) {
|
||||
EXPECT_NONFATAL_FAILURE({ // NOLINT
|
||||
AtLeast(-1);
|
||||
}, "The invocation lower bound must be >= 0");
|
||||
}
|
||||
|
||||
TEST(AtLeastTest, OnZero) {
|
||||
const Cardinality c = AtLeast(0);
|
||||
EXPECT_TRUE(c.IsSatisfiedByCallCount(0));
|
||||
EXPECT_FALSE(c.IsSaturatedByCallCount(0));
|
||||
|
||||
EXPECT_TRUE(c.IsSatisfiedByCallCount(1));
|
||||
EXPECT_FALSE(c.IsSaturatedByCallCount(1));
|
||||
|
||||
stringstream ss;
|
||||
c.DescribeTo(&ss);
|
||||
EXPECT_PRED_FORMAT2(IsSubstring, "any number of times",
|
||||
ss.str());
|
||||
}
|
||||
|
||||
TEST(AtLeastTest, OnPositiveNumber) {
|
||||
const Cardinality c = AtLeast(2);
|
||||
EXPECT_FALSE(c.IsSatisfiedByCallCount(0));
|
||||
EXPECT_FALSE(c.IsSaturatedByCallCount(0));
|
||||
|
||||
EXPECT_FALSE(c.IsSatisfiedByCallCount(1));
|
||||
EXPECT_FALSE(c.IsSaturatedByCallCount(1));
|
||||
|
||||
EXPECT_TRUE(c.IsSatisfiedByCallCount(2));
|
||||
EXPECT_FALSE(c.IsSaturatedByCallCount(2));
|
||||
|
||||
stringstream ss1;
|
||||
AtLeast(1).DescribeTo(&ss1);
|
||||
EXPECT_PRED_FORMAT2(IsSubstring, "at least once",
|
||||
ss1.str());
|
||||
|
||||
stringstream ss2;
|
||||
c.DescribeTo(&ss2);
|
||||
EXPECT_PRED_FORMAT2(IsSubstring, "at least twice",
|
||||
ss2.str());
|
||||
|
||||
stringstream ss3;
|
||||
AtLeast(3).DescribeTo(&ss3);
|
||||
EXPECT_PRED_FORMAT2(IsSubstring, "at least 3 times",
|
||||
ss3.str());
|
||||
}
|
||||
|
||||
TEST(AtLeastTest, HasCorrectBounds) {
|
||||
const Cardinality c = AtLeast(2);
|
||||
EXPECT_EQ(2, c.ConservativeLowerBound());
|
||||
EXPECT_EQ(INT_MAX, c.ConservativeUpperBound());
|
||||
}
|
||||
|
||||
// Tests AtMost(n).
|
||||
|
||||
TEST(AtMostTest, OnNegativeNumber) {
|
||||
EXPECT_NONFATAL_FAILURE({ // NOLINT
|
||||
AtMost(-1);
|
||||
}, "The invocation upper bound must be >= 0");
|
||||
}
|
||||
|
||||
TEST(AtMostTest, OnZero) {
|
||||
const Cardinality c = AtMost(0);
|
||||
EXPECT_TRUE(c.IsSatisfiedByCallCount(0));
|
||||
EXPECT_TRUE(c.IsSaturatedByCallCount(0));
|
||||
|
||||
EXPECT_FALSE(c.IsSatisfiedByCallCount(1));
|
||||
EXPECT_TRUE(c.IsSaturatedByCallCount(1));
|
||||
|
||||
stringstream ss;
|
||||
c.DescribeTo(&ss);
|
||||
EXPECT_PRED_FORMAT2(IsSubstring, "never called",
|
||||
ss.str());
|
||||
}
|
||||
|
||||
TEST(AtMostTest, OnPositiveNumber) {
|
||||
const Cardinality c = AtMost(2);
|
||||
EXPECT_TRUE(c.IsSatisfiedByCallCount(0));
|
||||
EXPECT_FALSE(c.IsSaturatedByCallCount(0));
|
||||
|
||||
EXPECT_TRUE(c.IsSatisfiedByCallCount(1));
|
||||
EXPECT_FALSE(c.IsSaturatedByCallCount(1));
|
||||
|
||||
EXPECT_TRUE(c.IsSatisfiedByCallCount(2));
|
||||
EXPECT_TRUE(c.IsSaturatedByCallCount(2));
|
||||
|
||||
stringstream ss1;
|
||||
AtMost(1).DescribeTo(&ss1);
|
||||
EXPECT_PRED_FORMAT2(IsSubstring, "called at most once",
|
||||
ss1.str());
|
||||
|
||||
stringstream ss2;
|
||||
c.DescribeTo(&ss2);
|
||||
EXPECT_PRED_FORMAT2(IsSubstring, "called at most twice",
|
||||
ss2.str());
|
||||
|
||||
stringstream ss3;
|
||||
AtMost(3).DescribeTo(&ss3);
|
||||
EXPECT_PRED_FORMAT2(IsSubstring, "called at most 3 times",
|
||||
ss3.str());
|
||||
}
|
||||
|
||||
TEST(AtMostTest, HasCorrectBounds) {
|
||||
const Cardinality c = AtMost(2);
|
||||
EXPECT_EQ(0, c.ConservativeLowerBound());
|
||||
EXPECT_EQ(2, c.ConservativeUpperBound());
|
||||
}
|
||||
|
||||
// Tests Between(m, n).
|
||||
|
||||
TEST(BetweenTest, OnNegativeStart) {
|
||||
EXPECT_NONFATAL_FAILURE({ // NOLINT
|
||||
Between(-1, 2);
|
||||
}, "The invocation lower bound must be >= 0, but is actually -1");
|
||||
}
|
||||
|
||||
TEST(BetweenTest, OnNegativeEnd) {
|
||||
EXPECT_NONFATAL_FAILURE({ // NOLINT
|
||||
Between(1, -2);
|
||||
}, "The invocation upper bound must be >= 0, but is actually -2");
|
||||
}
|
||||
|
||||
TEST(BetweenTest, OnStartBiggerThanEnd) {
|
||||
EXPECT_NONFATAL_FAILURE({ // NOLINT
|
||||
Between(2, 1);
|
||||
}, "The invocation upper bound (1) must be >= "
|
||||
"the invocation lower bound (2)");
|
||||
}
|
||||
|
||||
TEST(BetweenTest, OnZeroStartAndZeroEnd) {
|
||||
const Cardinality c = Between(0, 0);
|
||||
|
||||
EXPECT_TRUE(c.IsSatisfiedByCallCount(0));
|
||||
EXPECT_TRUE(c.IsSaturatedByCallCount(0));
|
||||
|
||||
EXPECT_FALSE(c.IsSatisfiedByCallCount(1));
|
||||
EXPECT_TRUE(c.IsSaturatedByCallCount(1));
|
||||
|
||||
stringstream ss;
|
||||
c.DescribeTo(&ss);
|
||||
EXPECT_PRED_FORMAT2(IsSubstring, "never called",
|
||||
ss.str());
|
||||
}
|
||||
|
||||
TEST(BetweenTest, OnZeroStartAndNonZeroEnd) {
|
||||
const Cardinality c = Between(0, 2);
|
||||
|
||||
EXPECT_TRUE(c.IsSatisfiedByCallCount(0));
|
||||
EXPECT_FALSE(c.IsSaturatedByCallCount(0));
|
||||
|
||||
EXPECT_TRUE(c.IsSatisfiedByCallCount(2));
|
||||
EXPECT_TRUE(c.IsSaturatedByCallCount(2));
|
||||
|
||||
EXPECT_FALSE(c.IsSatisfiedByCallCount(4));
|
||||
EXPECT_TRUE(c.IsSaturatedByCallCount(4));
|
||||
|
||||
stringstream ss;
|
||||
c.DescribeTo(&ss);
|
||||
EXPECT_PRED_FORMAT2(IsSubstring, "called at most twice",
|
||||
ss.str());
|
||||
}
|
||||
|
||||
TEST(BetweenTest, OnSameStartAndEnd) {
|
||||
const Cardinality c = Between(3, 3);
|
||||
|
||||
EXPECT_FALSE(c.IsSatisfiedByCallCount(2));
|
||||
EXPECT_FALSE(c.IsSaturatedByCallCount(2));
|
||||
|
||||
EXPECT_TRUE(c.IsSatisfiedByCallCount(3));
|
||||
EXPECT_TRUE(c.IsSaturatedByCallCount(3));
|
||||
|
||||
EXPECT_FALSE(c.IsSatisfiedByCallCount(4));
|
||||
EXPECT_TRUE(c.IsSaturatedByCallCount(4));
|
||||
|
||||
stringstream ss;
|
||||
c.DescribeTo(&ss);
|
||||
EXPECT_PRED_FORMAT2(IsSubstring, "called 3 times",
|
||||
ss.str());
|
||||
}
|
||||
|
||||
TEST(BetweenTest, OnDifferentStartAndEnd) {
|
||||
const Cardinality c = Between(3, 5);
|
||||
|
||||
EXPECT_FALSE(c.IsSatisfiedByCallCount(2));
|
||||
EXPECT_FALSE(c.IsSaturatedByCallCount(2));
|
||||
|
||||
EXPECT_TRUE(c.IsSatisfiedByCallCount(3));
|
||||
EXPECT_FALSE(c.IsSaturatedByCallCount(3));
|
||||
|
||||
EXPECT_TRUE(c.IsSatisfiedByCallCount(5));
|
||||
EXPECT_TRUE(c.IsSaturatedByCallCount(5));
|
||||
|
||||
EXPECT_FALSE(c.IsSatisfiedByCallCount(6));
|
||||
EXPECT_TRUE(c.IsSaturatedByCallCount(6));
|
||||
|
||||
stringstream ss;
|
||||
c.DescribeTo(&ss);
|
||||
EXPECT_PRED_FORMAT2(IsSubstring, "called between 3 and 5 times",
|
||||
ss.str());
|
||||
}
|
||||
|
||||
TEST(BetweenTest, HasCorrectBounds) {
|
||||
const Cardinality c = Between(3, 5);
|
||||
EXPECT_EQ(3, c.ConservativeLowerBound());
|
||||
EXPECT_EQ(5, c.ConservativeUpperBound());
|
||||
}
|
||||
|
||||
// Tests Exactly(n).
|
||||
|
||||
TEST(ExactlyTest, OnNegativeNumber) {
|
||||
EXPECT_NONFATAL_FAILURE({ // NOLINT
|
||||
Exactly(-1);
|
||||
}, "The invocation lower bound must be >= 0");
|
||||
}
|
||||
|
||||
TEST(ExactlyTest, OnZero) {
|
||||
const Cardinality c = Exactly(0);
|
||||
EXPECT_TRUE(c.IsSatisfiedByCallCount(0));
|
||||
EXPECT_TRUE(c.IsSaturatedByCallCount(0));
|
||||
|
||||
EXPECT_FALSE(c.IsSatisfiedByCallCount(1));
|
||||
EXPECT_TRUE(c.IsSaturatedByCallCount(1));
|
||||
|
||||
stringstream ss;
|
||||
c.DescribeTo(&ss);
|
||||
EXPECT_PRED_FORMAT2(IsSubstring, "never called",
|
||||
ss.str());
|
||||
}
|
||||
|
||||
TEST(ExactlyTest, OnPositiveNumber) {
|
||||
const Cardinality c = Exactly(2);
|
||||
EXPECT_FALSE(c.IsSatisfiedByCallCount(0));
|
||||
EXPECT_FALSE(c.IsSaturatedByCallCount(0));
|
||||
|
||||
EXPECT_TRUE(c.IsSatisfiedByCallCount(2));
|
||||
EXPECT_TRUE(c.IsSaturatedByCallCount(2));
|
||||
|
||||
stringstream ss1;
|
||||
Exactly(1).DescribeTo(&ss1);
|
||||
EXPECT_PRED_FORMAT2(IsSubstring, "called once",
|
||||
ss1.str());
|
||||
|
||||
stringstream ss2;
|
||||
c.DescribeTo(&ss2);
|
||||
EXPECT_PRED_FORMAT2(IsSubstring, "called twice",
|
||||
ss2.str());
|
||||
|
||||
stringstream ss3;
|
||||
Exactly(3).DescribeTo(&ss3);
|
||||
EXPECT_PRED_FORMAT2(IsSubstring, "called 3 times",
|
||||
ss3.str());
|
||||
}
|
||||
|
||||
TEST(ExactlyTest, HasCorrectBounds) {
|
||||
const Cardinality c = Exactly(3);
|
||||
EXPECT_EQ(3, c.ConservativeLowerBound());
|
||||
EXPECT_EQ(3, c.ConservativeUpperBound());
|
||||
}
|
||||
|
||||
// Tests that a user can make his own cardinality by implementing
|
||||
// CardinalityInterface and calling MakeCardinality().
|
||||
|
||||
class EvenCardinality : public CardinalityInterface {
|
||||
public:
|
||||
// Returns true iff call_count calls will satisfy this cardinality.
|
||||
virtual bool IsSatisfiedByCallCount(int call_count) const {
|
||||
return (call_count % 2 == 0);
|
||||
}
|
||||
|
||||
// Returns true iff call_count calls will saturate this cardinality.
|
||||
virtual bool IsSaturatedByCallCount(int call_count) const { return false; }
|
||||
|
||||
// Describes self to an ostream.
|
||||
virtual void DescribeTo(::std::ostream* ss) const {
|
||||
*ss << "called even number of times";
|
||||
}
|
||||
};
|
||||
|
||||
TEST(MakeCardinalityTest, ConstructsCardinalityFromInterface) {
|
||||
const Cardinality c = MakeCardinality(new EvenCardinality);
|
||||
|
||||
EXPECT_TRUE(c.IsSatisfiedByCallCount(2));
|
||||
EXPECT_FALSE(c.IsSatisfiedByCallCount(3));
|
||||
|
||||
EXPECT_FALSE(c.IsSaturatedByCallCount(10000));
|
||||
|
||||
stringstream ss;
|
||||
c.DescribeTo(&ss);
|
||||
EXPECT_EQ("called even number of times", ss.str());
|
||||
}
|
||||
|
||||
} // Unnamed namespace
|
||||
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
@@ -0,0 +1,466 @@
|
||||
// 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)
|
||||
|
||||
// Google Mock - a framework for writing C++ mock classes.
|
||||
//
|
||||
// This file tests the function mocker classes.
|
||||
|
||||
#include <gmock/gmock-generated-function-mockers.h>
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#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
|
||||
// we are getting compiler errors if we use basetyps.h, hence including
|
||||
// objbase.h for definition of STDMETHOD.
|
||||
#include <objbase.h>
|
||||
#endif // GTEST_OS_WINDOWS
|
||||
|
||||
// There is a bug in MSVC (fixed in VS 2008) that prevents creating a
|
||||
// mock for a function with const arguments, so we don't test such
|
||||
// cases for MSVC versions older than 2008.
|
||||
#if !GTEST_OS_WINDOWS || (_MSC_VER >= 1500)
|
||||
#define GMOCK_ALLOWS_CONST_PARAM_FUNCTIONS
|
||||
#endif // !GTEST_OS_WINDOWS || (_MSC_VER >= 1500)
|
||||
|
||||
namespace testing {
|
||||
namespace gmock_generated_function_mockers_test {
|
||||
|
||||
using testing::internal::string;
|
||||
using testing::_;
|
||||
using testing::A;
|
||||
using testing::An;
|
||||
using testing::AnyNumber;
|
||||
using testing::Const;
|
||||
using testing::DoDefault;
|
||||
using testing::Eq;
|
||||
using testing::Lt;
|
||||
using testing::Ref;
|
||||
using testing::Return;
|
||||
using testing::ReturnRef;
|
||||
using testing::TypedEq;
|
||||
|
||||
class FooInterface {
|
||||
public:
|
||||
virtual ~FooInterface() {}
|
||||
|
||||
virtual void VoidReturning(int x) = 0;
|
||||
|
||||
virtual int Nullary() = 0;
|
||||
virtual bool Unary(int x) = 0;
|
||||
virtual long Binary(short x, int y) = 0; // NOLINT
|
||||
virtual int Decimal(bool b, char c, short d, int e, long f, // NOLINT
|
||||
float g, double h, unsigned i, char* j, const string& k)
|
||||
= 0;
|
||||
|
||||
virtual bool TakesNonConstReference(int& n) = 0; // NOLINT
|
||||
virtual string TakesConstReference(const int& n) = 0;
|
||||
#ifdef GMOCK_ALLOWS_CONST_PARAM_FUNCTIONS
|
||||
virtual bool TakesConst(const int x) = 0;
|
||||
#endif // GMOCK_ALLOWS_CONST_PARAM_FUNCTIONS
|
||||
|
||||
virtual int OverloadedOnArgumentNumber() = 0;
|
||||
virtual int OverloadedOnArgumentNumber(int n) = 0;
|
||||
|
||||
virtual int OverloadedOnArgumentType(int n) = 0;
|
||||
virtual char OverloadedOnArgumentType(char c) = 0;
|
||||
|
||||
virtual int OverloadedOnConstness() = 0;
|
||||
virtual char OverloadedOnConstness() const = 0;
|
||||
|
||||
virtual int TypeWithHole(int (*func)()) = 0;
|
||||
virtual int TypeWithComma(const std::map<int, string>& a_map) = 0;
|
||||
|
||||
#if GTEST_OS_WINDOWS
|
||||
STDMETHOD_(int, CTNullary)() = 0;
|
||||
STDMETHOD_(bool, CTUnary)(int x) = 0;
|
||||
STDMETHOD_(int, CTDecimal)(bool b, char c, short d, int e, long f, // NOLINT
|
||||
float g, double h, unsigned i, char* j, const string& k) = 0;
|
||||
STDMETHOD_(char, CTConst)(int x) const = 0;
|
||||
#endif // GTEST_OS_WINDOWS
|
||||
};
|
||||
|
||||
class MockFoo : public FooInterface {
|
||||
public:
|
||||
// Makes sure that a mock function parameter can be named.
|
||||
MOCK_METHOD1(VoidReturning, void(int n)); // NOLINT
|
||||
|
||||
MOCK_METHOD0(Nullary, int()); // NOLINT
|
||||
|
||||
// Makes sure that a mock function parameter can be unnamed.
|
||||
MOCK_METHOD1(Unary, bool(int)); // NOLINT
|
||||
MOCK_METHOD2(Binary, long(short, int)); // NOLINT
|
||||
MOCK_METHOD10(Decimal, int(bool, char, short, int, long, float, // NOLINT
|
||||
double, unsigned, char*, const string& str));
|
||||
|
||||
MOCK_METHOD1(TakesNonConstReference, bool(int&)); // NOLINT
|
||||
MOCK_METHOD1(TakesConstReference, string(const int&));
|
||||
#ifdef GMOCK_ALLOWS_CONST_PARAM_FUNCTIONS
|
||||
MOCK_METHOD1(TakesConst, bool(const int)); // NOLINT
|
||||
#endif // GMOCK_ALLOWS_CONST_PARAM_FUNCTIONS
|
||||
MOCK_METHOD0(OverloadedOnArgumentNumber, int()); // NOLINT
|
||||
MOCK_METHOD1(OverloadedOnArgumentNumber, int(int)); // NOLINT
|
||||
|
||||
MOCK_METHOD1(OverloadedOnArgumentType, int(int)); // NOLINT
|
||||
MOCK_METHOD1(OverloadedOnArgumentType, char(char)); // NOLINT
|
||||
|
||||
MOCK_METHOD0(OverloadedOnConstness, int()); // NOLINT
|
||||
MOCK_CONST_METHOD0(OverloadedOnConstness, char()); // NOLINT
|
||||
|
||||
MOCK_METHOD1(TypeWithHole, int(int (*)())); // NOLINT
|
||||
MOCK_METHOD1(TypeWithComma, int(const std::map<int, string>&)); // NOLINT
|
||||
#if GTEST_OS_WINDOWS
|
||||
MOCK_METHOD0_WITH_CALLTYPE(STDMETHODCALLTYPE, CTNullary, int());
|
||||
MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE, CTUnary, bool(int));
|
||||
MOCK_METHOD10_WITH_CALLTYPE(STDMETHODCALLTYPE, CTDecimal, int(bool b, char c,
|
||||
short d, int e, long f, float g, double h, unsigned i, char* j,
|
||||
const string& k));
|
||||
MOCK_CONST_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE, CTConst, char(int));
|
||||
#endif // GTEST_OS_WINDOWS
|
||||
};
|
||||
|
||||
class FunctionMockerTest : public testing::Test {
|
||||
protected:
|
||||
FunctionMockerTest() : foo_(&mock_foo_) {}
|
||||
|
||||
FooInterface* const foo_;
|
||||
MockFoo mock_foo_;
|
||||
};
|
||||
|
||||
// Tests mocking a void-returning function.
|
||||
TEST_F(FunctionMockerTest, MocksVoidFunction) {
|
||||
EXPECT_CALL(mock_foo_, VoidReturning(Lt(100)));
|
||||
foo_->VoidReturning(0);
|
||||
}
|
||||
|
||||
// Tests mocking a nullary function.
|
||||
TEST_F(FunctionMockerTest, MocksNullaryFunction) {
|
||||
EXPECT_CALL(mock_foo_, Nullary())
|
||||
.WillOnce(DoDefault())
|
||||
.WillOnce(Return(1));
|
||||
|
||||
EXPECT_EQ(0, foo_->Nullary());
|
||||
EXPECT_EQ(1, foo_->Nullary());
|
||||
}
|
||||
|
||||
// Tests mocking a unary function.
|
||||
TEST_F(FunctionMockerTest, MocksUnaryFunction) {
|
||||
EXPECT_CALL(mock_foo_, Unary(Eq(2)))
|
||||
.Times(2)
|
||||
.WillOnce(Return(true));
|
||||
|
||||
EXPECT_TRUE(foo_->Unary(2));
|
||||
EXPECT_FALSE(foo_->Unary(2));
|
||||
}
|
||||
|
||||
// Tests mocking a binary function.
|
||||
TEST_F(FunctionMockerTest, MocksBinaryFunction) {
|
||||
EXPECT_CALL(mock_foo_, Binary(2, _))
|
||||
.WillOnce(Return(3));
|
||||
|
||||
EXPECT_EQ(3, foo_->Binary(2, 1));
|
||||
}
|
||||
|
||||
// Tests mocking a decimal function.
|
||||
TEST_F(FunctionMockerTest, MocksDecimalFunction) {
|
||||
EXPECT_CALL(mock_foo_, Decimal(true, 'a', 0, 0, 1L, A<float>(),
|
||||
Lt(100), 5U, NULL, "hi"))
|
||||
.WillOnce(Return(5));
|
||||
|
||||
EXPECT_EQ(5, foo_->Decimal(true, 'a', 0, 0, 1, 0, 0, 5, NULL, "hi"));
|
||||
}
|
||||
|
||||
// Tests mocking a function that takes a non-const reference.
|
||||
TEST_F(FunctionMockerTest, MocksFunctionWithNonConstReferenceArgument) {
|
||||
int a = 0;
|
||||
EXPECT_CALL(mock_foo_, TakesNonConstReference(Ref(a)))
|
||||
.WillOnce(Return(true));
|
||||
|
||||
EXPECT_TRUE(foo_->TakesNonConstReference(a));
|
||||
}
|
||||
|
||||
// Tests mocking a function that takes a const reference.
|
||||
TEST_F(FunctionMockerTest, MocksFunctionWithConstReferenceArgument) {
|
||||
int a = 0;
|
||||
EXPECT_CALL(mock_foo_, TakesConstReference(Ref(a)))
|
||||
.WillOnce(Return("Hello"));
|
||||
|
||||
EXPECT_EQ("Hello", foo_->TakesConstReference(a));
|
||||
}
|
||||
|
||||
#ifdef GMOCK_ALLOWS_CONST_PARAM_FUNCTIONS
|
||||
// Tests mocking a function that takes a const variable.
|
||||
TEST_F(FunctionMockerTest, MocksFunctionWithConstArgument) {
|
||||
EXPECT_CALL(mock_foo_, TakesConst(Lt(10)))
|
||||
.WillOnce(DoDefault());
|
||||
|
||||
EXPECT_FALSE(foo_->TakesConst(5));
|
||||
}
|
||||
#endif // GMOCK_ALLOWS_CONST_PARAM_FUNCTIONS
|
||||
|
||||
// Tests mocking functions overloaded on the number of arguments.
|
||||
TEST_F(FunctionMockerTest, MocksFunctionsOverloadedOnArgumentNumber) {
|
||||
EXPECT_CALL(mock_foo_, OverloadedOnArgumentNumber())
|
||||
.WillOnce(Return(1));
|
||||
EXPECT_CALL(mock_foo_, OverloadedOnArgumentNumber(_))
|
||||
.WillOnce(Return(2));
|
||||
|
||||
EXPECT_EQ(2, foo_->OverloadedOnArgumentNumber(1));
|
||||
EXPECT_EQ(1, foo_->OverloadedOnArgumentNumber());
|
||||
}
|
||||
|
||||
// Tests mocking functions overloaded on the types of argument.
|
||||
TEST_F(FunctionMockerTest, MocksFunctionsOverloadedOnArgumentType) {
|
||||
EXPECT_CALL(mock_foo_, OverloadedOnArgumentType(An<int>()))
|
||||
.WillOnce(Return(1));
|
||||
EXPECT_CALL(mock_foo_, OverloadedOnArgumentType(TypedEq<char>('a')))
|
||||
.WillOnce(Return('b'));
|
||||
|
||||
EXPECT_EQ(1, foo_->OverloadedOnArgumentType(0));
|
||||
EXPECT_EQ('b', foo_->OverloadedOnArgumentType('a'));
|
||||
}
|
||||
|
||||
// Tests mocking functions overloaded on the const-ness of this object.
|
||||
TEST_F(FunctionMockerTest, MocksFunctionsOverloadedOnConstnessOfThis) {
|
||||
EXPECT_CALL(mock_foo_, OverloadedOnConstness());
|
||||
EXPECT_CALL(Const(mock_foo_), OverloadedOnConstness())
|
||||
.WillOnce(Return('a'));
|
||||
|
||||
EXPECT_EQ(0, foo_->OverloadedOnConstness());
|
||||
EXPECT_EQ('a', Const(*foo_).OverloadedOnConstness());
|
||||
}
|
||||
|
||||
#if GTEST_OS_WINDOWS
|
||||
// Tests mocking a nullary function with calltype.
|
||||
TEST_F(FunctionMockerTest, MocksNullaryFunctionWithCallType) {
|
||||
EXPECT_CALL(mock_foo_, CTNullary())
|
||||
.WillOnce(Return(-1))
|
||||
.WillOnce(Return(0));
|
||||
|
||||
EXPECT_EQ(-1, foo_->CTNullary());
|
||||
EXPECT_EQ(0, foo_->CTNullary());
|
||||
}
|
||||
|
||||
// Tests mocking a unary function with calltype.
|
||||
TEST_F(FunctionMockerTest, MocksUnaryFunctionWithCallType) {
|
||||
EXPECT_CALL(mock_foo_, CTUnary(Eq(2)))
|
||||
.Times(2)
|
||||
.WillOnce(Return(true))
|
||||
.WillOnce(Return(false));
|
||||
|
||||
EXPECT_TRUE(foo_->CTUnary(2));
|
||||
EXPECT_FALSE(foo_->CTUnary(2));
|
||||
}
|
||||
|
||||
// Tests mocking a decimal function with calltype.
|
||||
TEST_F(FunctionMockerTest, MocksDecimalFunctionWithCallType) {
|
||||
EXPECT_CALL(mock_foo_, CTDecimal(true, 'a', 0, 0, 1L, A<float>(),
|
||||
Lt(100), 5U, NULL, "hi"))
|
||||
.WillOnce(Return(10));
|
||||
|
||||
EXPECT_EQ(10, foo_->CTDecimal(true, 'a', 0, 0, 1, 0, 0, 5, NULL, "hi"));
|
||||
}
|
||||
|
||||
// Tests mocking functions overloaded on the const-ness of this object.
|
||||
TEST_F(FunctionMockerTest, MocksFunctionsConstFunctionWithCallType) {
|
||||
EXPECT_CALL(Const(mock_foo_), CTConst(_))
|
||||
.WillOnce(Return('a'));
|
||||
|
||||
EXPECT_EQ('a', Const(*foo_).CTConst(0));
|
||||
}
|
||||
|
||||
#endif // GTEST_OS_WINDOWS
|
||||
|
||||
class MockB {
|
||||
public:
|
||||
MOCK_METHOD0(DoB, void());
|
||||
};
|
||||
|
||||
// Tests that functions with no EXPECT_CALL() ruls can be called any
|
||||
// number of times.
|
||||
TEST(ExpectCallTest, UnmentionedFunctionCanBeCalledAnyNumberOfTimes) {
|
||||
{
|
||||
MockB b;
|
||||
}
|
||||
|
||||
{
|
||||
MockB b;
|
||||
b.DoB();
|
||||
}
|
||||
|
||||
{
|
||||
MockB b;
|
||||
b.DoB();
|
||||
b.DoB();
|
||||
}
|
||||
}
|
||||
|
||||
// Tests mocking template interfaces.
|
||||
|
||||
template <typename T>
|
||||
class StackInterface {
|
||||
public:
|
||||
virtual ~StackInterface() {}
|
||||
|
||||
// Template parameter appears in function parameter.
|
||||
virtual void Push(const T& value) = 0;
|
||||
virtual void Pop() = 0;
|
||||
virtual int GetSize() const = 0;
|
||||
// Template parameter appears in function return type.
|
||||
virtual const T& GetTop() const = 0;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class MockStack : public StackInterface<T> {
|
||||
public:
|
||||
MOCK_METHOD1_T(Push, void(const T& elem));
|
||||
MOCK_METHOD0_T(Pop, void());
|
||||
MOCK_CONST_METHOD0_T(GetSize, int()); // NOLINT
|
||||
MOCK_CONST_METHOD0_T(GetTop, const T&());
|
||||
};
|
||||
|
||||
// Tests that template mock works.
|
||||
TEST(TemplateMockTest, Works) {
|
||||
MockStack<int> mock;
|
||||
|
||||
EXPECT_CALL(mock, GetSize())
|
||||
.WillOnce(Return(0))
|
||||
.WillOnce(Return(1))
|
||||
.WillOnce(Return(0));
|
||||
EXPECT_CALL(mock, Push(_));
|
||||
int n = 5;
|
||||
EXPECT_CALL(mock, GetTop())
|
||||
.WillOnce(ReturnRef(n));
|
||||
EXPECT_CALL(mock, Pop())
|
||||
.Times(AnyNumber());
|
||||
|
||||
EXPECT_EQ(0, mock.GetSize());
|
||||
mock.Push(5);
|
||||
EXPECT_EQ(1, mock.GetSize());
|
||||
EXPECT_EQ(5, mock.GetTop());
|
||||
mock.Pop();
|
||||
EXPECT_EQ(0, mock.GetSize());
|
||||
}
|
||||
|
||||
#if GTEST_OS_WINDOWS
|
||||
// Tests mocking template interfaces with calltype.
|
||||
|
||||
template <typename T>
|
||||
class StackInterfaceWithCallType {
|
||||
public:
|
||||
virtual ~StackInterfaceWithCallType() {}
|
||||
|
||||
// Template parameter appears in function parameter.
|
||||
STDMETHOD_(void, Push)(const T& value) = 0;
|
||||
STDMETHOD_(void, Pop)() = 0;
|
||||
STDMETHOD_(int, GetSize)() const = 0;
|
||||
// Template parameter appears in function return type.
|
||||
STDMETHOD_(const T&, GetTop)() const = 0;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class MockStackWithCallType : public StackInterfaceWithCallType<T> {
|
||||
public:
|
||||
MOCK_METHOD1_T_WITH_CALLTYPE(STDMETHODCALLTYPE, Push, void(const T& elem));
|
||||
MOCK_METHOD0_T_WITH_CALLTYPE(STDMETHODCALLTYPE, Pop, void());
|
||||
MOCK_CONST_METHOD0_T_WITH_CALLTYPE(STDMETHODCALLTYPE, GetSize, int());
|
||||
MOCK_CONST_METHOD0_T_WITH_CALLTYPE(STDMETHODCALLTYPE, GetTop, const T&());
|
||||
};
|
||||
|
||||
// Tests that template mock with calltype works.
|
||||
TEST(TemplateMockTestWithCallType, Works) {
|
||||
MockStackWithCallType<int> mock;
|
||||
|
||||
EXPECT_CALL(mock, GetSize())
|
||||
.WillOnce(Return(0))
|
||||
.WillOnce(Return(1))
|
||||
.WillOnce(Return(0));
|
||||
EXPECT_CALL(mock, Push(_));
|
||||
int n = 5;
|
||||
EXPECT_CALL(mock, GetTop())
|
||||
.WillOnce(ReturnRef(n));
|
||||
EXPECT_CALL(mock, Pop())
|
||||
.Times(AnyNumber());
|
||||
|
||||
EXPECT_EQ(0, mock.GetSize());
|
||||
mock.Push(5);
|
||||
EXPECT_EQ(1, mock.GetSize());
|
||||
EXPECT_EQ(5, mock.GetTop());
|
||||
mock.Pop();
|
||||
EXPECT_EQ(0, mock.GetSize());
|
||||
}
|
||||
#endif // GTEST_OS_WINDOWS
|
||||
|
||||
#define MY_MOCK_METHODS1_ \
|
||||
MOCK_METHOD0(Overloaded, void()); \
|
||||
MOCK_CONST_METHOD1(Overloaded, int(int n)); \
|
||||
MOCK_METHOD2(Overloaded, bool(bool f, int n))
|
||||
|
||||
class MockOverloadedOnArgNumber {
|
||||
public:
|
||||
MY_MOCK_METHODS1_;
|
||||
};
|
||||
|
||||
TEST(OverloadedMockMethodTest, CanOverloadOnArgNumberInMacroBody) {
|
||||
MockOverloadedOnArgNumber mock;
|
||||
EXPECT_CALL(mock, Overloaded());
|
||||
EXPECT_CALL(mock, Overloaded(1)).WillOnce(Return(2));
|
||||
EXPECT_CALL(mock, Overloaded(true, 1)).WillOnce(Return(true));
|
||||
|
||||
mock.Overloaded();
|
||||
EXPECT_EQ(2, mock.Overloaded(1));
|
||||
EXPECT_TRUE(mock.Overloaded(true, 1));
|
||||
}
|
||||
|
||||
#define MY_MOCK_METHODS2_ \
|
||||
MOCK_CONST_METHOD1(Overloaded, int(int n)); \
|
||||
MOCK_METHOD1(Overloaded, int(int n));
|
||||
|
||||
class MockOverloadedOnConstness {
|
||||
public:
|
||||
MY_MOCK_METHODS2_;
|
||||
};
|
||||
|
||||
TEST(OverloadedMockMethodTest, CanOverloadOnConstnessInMacroBody) {
|
||||
MockOverloadedOnConstness mock;
|
||||
const MockOverloadedOnConstness* const_mock = &mock;
|
||||
EXPECT_CALL(mock, Overloaded(1)).WillOnce(Return(2));
|
||||
EXPECT_CALL(*const_mock, Overloaded(1)).WillOnce(Return(3));
|
||||
|
||||
EXPECT_EQ(2, mock.Overloaded(1));
|
||||
EXPECT_EQ(3, const_mock->Overloaded(1));
|
||||
}
|
||||
|
||||
} // namespace gmock_generated_function_mockers_test
|
||||
} // namespace testing
|
||||
@@ -0,0 +1,127 @@
|
||||
// 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)
|
||||
|
||||
// Google Mock - a framework for writing C++ mock classes.
|
||||
//
|
||||
// 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>
|
||||
|
||||
namespace {
|
||||
|
||||
using ::std::tr1::tuple;
|
||||
using ::testing::Matcher;
|
||||
using ::testing::internal::CompileAssertTypesEqual;
|
||||
using ::testing::internal::MatcherTuple;
|
||||
using ::testing::internal::Function;
|
||||
using ::testing::internal::IgnoredValue;
|
||||
|
||||
// Tests the MatcherTuple template struct.
|
||||
|
||||
TEST(MatcherTupleTest, ForSize0) {
|
||||
CompileAssertTypesEqual<tuple<>, MatcherTuple<tuple<> >::type>();
|
||||
}
|
||||
|
||||
TEST(MatcherTupleTest, ForSize1) {
|
||||
CompileAssertTypesEqual<tuple<Matcher<int> >,
|
||||
MatcherTuple<tuple<int> >::type>();
|
||||
}
|
||||
|
||||
TEST(MatcherTupleTest, ForSize2) {
|
||||
CompileAssertTypesEqual<tuple<Matcher<int>, Matcher<char> >,
|
||||
MatcherTuple<tuple<int, char> >::type>();
|
||||
}
|
||||
|
||||
TEST(MatcherTupleTest, ForSize5) {
|
||||
CompileAssertTypesEqual<tuple<Matcher<int>, Matcher<char>, Matcher<bool>,
|
||||
Matcher<double>, Matcher<char*> >,
|
||||
MatcherTuple<tuple<int, char, bool, double, char*>
|
||||
>::type>();
|
||||
}
|
||||
|
||||
// Tests the Function template struct.
|
||||
|
||||
TEST(FunctionTest, Nullary) {
|
||||
typedef Function<int()> F; // NOLINT
|
||||
CompileAssertTypesEqual<int, F::Result>();
|
||||
CompileAssertTypesEqual<tuple<>, F::ArgumentTuple>();
|
||||
CompileAssertTypesEqual<tuple<>, F::ArgumentMatcherTuple>();
|
||||
CompileAssertTypesEqual<void(), F::MakeResultVoid>();
|
||||
CompileAssertTypesEqual<IgnoredValue(), F::MakeResultIgnoredValue>();
|
||||
}
|
||||
|
||||
TEST(FunctionTest, Unary) {
|
||||
typedef Function<int(bool)> F; // NOLINT
|
||||
CompileAssertTypesEqual<int, F::Result>();
|
||||
CompileAssertTypesEqual<bool, F::Argument1>();
|
||||
CompileAssertTypesEqual<tuple<bool>, F::ArgumentTuple>();
|
||||
CompileAssertTypesEqual<tuple<Matcher<bool> >, F::ArgumentMatcherTuple>();
|
||||
CompileAssertTypesEqual<void(bool), F::MakeResultVoid>(); // NOLINT
|
||||
CompileAssertTypesEqual<IgnoredValue(bool), // NOLINT
|
||||
F::MakeResultIgnoredValue>();
|
||||
}
|
||||
|
||||
TEST(FunctionTest, Binary) {
|
||||
typedef Function<int(bool, const long&)> F; // NOLINT
|
||||
CompileAssertTypesEqual<int, F::Result>();
|
||||
CompileAssertTypesEqual<bool, F::Argument1>();
|
||||
CompileAssertTypesEqual<const long&, F::Argument2>(); // NOLINT
|
||||
CompileAssertTypesEqual<tuple<bool, const long&>, F::ArgumentTuple>(); // NOLINT
|
||||
CompileAssertTypesEqual<tuple<Matcher<bool>, Matcher<const long&> >, // NOLINT
|
||||
F::ArgumentMatcherTuple>();
|
||||
CompileAssertTypesEqual<void(bool, const long&), F::MakeResultVoid>(); // NOLINT
|
||||
CompileAssertTypesEqual<IgnoredValue(bool, const long&), // NOLINT
|
||||
F::MakeResultIgnoredValue>();
|
||||
}
|
||||
|
||||
TEST(FunctionTest, LongArgumentList) {
|
||||
typedef Function<char(bool, int, char*, int&, const long&)> F; // NOLINT
|
||||
CompileAssertTypesEqual<char, F::Result>();
|
||||
CompileAssertTypesEqual<bool, F::Argument1>();
|
||||
CompileAssertTypesEqual<int, F::Argument2>();
|
||||
CompileAssertTypesEqual<char*, F::Argument3>();
|
||||
CompileAssertTypesEqual<int&, F::Argument4>();
|
||||
CompileAssertTypesEqual<const long&, F::Argument5>(); // NOLINT
|
||||
CompileAssertTypesEqual<tuple<bool, int, char*, int&, const long&>, // NOLINT
|
||||
F::ArgumentTuple>();
|
||||
CompileAssertTypesEqual<tuple<Matcher<bool>, Matcher<int>, Matcher<char*>,
|
||||
Matcher<int&>, Matcher<const long&> >, // NOLINT
|
||||
F::ArgumentMatcherTuple>();
|
||||
CompileAssertTypesEqual<void(bool, int, char*, int&, const long&), // NOLINT
|
||||
F::MakeResultVoid>();
|
||||
CompileAssertTypesEqual<
|
||||
IgnoredValue(bool, int, char*, int&, const long&), // NOLINT
|
||||
F::MakeResultIgnoredValue>();
|
||||
}
|
||||
|
||||
} // Unnamed namespace
|
||||
@@ -0,0 +1,834 @@
|
||||
// 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.
|
||||
|
||||
// Google Mock - a framework for writing C++ mock classes.
|
||||
//
|
||||
// This file tests the built-in matchers generated by a script.
|
||||
|
||||
#include <gmock/gmock-generated-matchers.h>
|
||||
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include <gmock/gmock.h>
|
||||
#include <gtest/gtest.h>
|
||||
#include <gtest/gtest-spi.h>
|
||||
|
||||
namespace {
|
||||
|
||||
using std::list;
|
||||
using std::map;
|
||||
using std::pair;
|
||||
using std::set;
|
||||
using std::stringstream;
|
||||
using std::vector;
|
||||
using testing::_;
|
||||
using testing::Contains;
|
||||
using testing::ElementsAre;
|
||||
using testing::ElementsAreArray;
|
||||
using testing::Eq;
|
||||
using testing::Ge;
|
||||
using testing::Gt;
|
||||
using testing::MakeMatcher;
|
||||
using testing::Matcher;
|
||||
using testing::MatcherInterface;
|
||||
using testing::Ne;
|
||||
using testing::Not;
|
||||
using testing::Pointee;
|
||||
using testing::Ref;
|
||||
using testing::StaticAssertTypeEq;
|
||||
using testing::StrEq;
|
||||
using testing::internal::string;
|
||||
|
||||
// Returns the description of the given matcher.
|
||||
template <typename T>
|
||||
string Describe(const Matcher<T>& m) {
|
||||
stringstream ss;
|
||||
m.DescribeTo(&ss);
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
// Returns the description of the negation of the given matcher.
|
||||
template <typename T>
|
||||
string DescribeNegation(const Matcher<T>& m) {
|
||||
stringstream ss;
|
||||
m.DescribeNegationTo(&ss);
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
// Returns the reason why x matches, or doesn't match, m.
|
||||
template <typename MatcherType, typename Value>
|
||||
string Explain(const MatcherType& m, const Value& x) {
|
||||
stringstream ss;
|
||||
m.ExplainMatchResultTo(x, &ss);
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
// For testing ExplainMatchResultTo().
|
||||
class GreaterThanMatcher : public MatcherInterface<int> {
|
||||
public:
|
||||
explicit GreaterThanMatcher(int rhs) : rhs_(rhs) {}
|
||||
|
||||
virtual bool Matches(int lhs) const { return lhs > rhs_; }
|
||||
|
||||
virtual void DescribeTo(::std::ostream* os) const {
|
||||
*os << "is greater than " << rhs_;
|
||||
}
|
||||
|
||||
virtual void ExplainMatchResultTo(int lhs, ::std::ostream* os) const {
|
||||
const int diff = lhs - rhs_;
|
||||
if (diff > 0) {
|
||||
*os << "is " << diff << " more than " << rhs_;
|
||||
} else if (diff == 0) {
|
||||
*os << "is the same as " << rhs_;
|
||||
} else {
|
||||
*os << "is " << -diff << " less than " << rhs_;
|
||||
}
|
||||
}
|
||||
private:
|
||||
const int rhs_;
|
||||
};
|
||||
|
||||
Matcher<int> GreaterThan(int n) {
|
||||
return MakeMatcher(new GreaterThanMatcher(n));
|
||||
}
|
||||
|
||||
// Tests for ElementsAre().
|
||||
|
||||
// Evaluates to the number of elements in 'array'.
|
||||
#define GMOCK_ARRAY_SIZE_(array) (sizeof(array)/sizeof(array[0]))
|
||||
|
||||
TEST(ElementsAreTest, CanDescribeExpectingNoElement) {
|
||||
Matcher<const vector<int>&> m = ElementsAre();
|
||||
EXPECT_EQ("is empty", Describe(m));
|
||||
}
|
||||
|
||||
TEST(ElementsAreTest, CanDescribeExpectingOneElement) {
|
||||
Matcher<vector<int> > m = ElementsAre(Gt(5));
|
||||
EXPECT_EQ("has 1 element that is greater than 5", Describe(m));
|
||||
}
|
||||
|
||||
TEST(ElementsAreTest, CanDescribeExpectingManyElements) {
|
||||
Matcher<list<string> > m = ElementsAre(StrEq("one"), "two");
|
||||
EXPECT_EQ("has 2 elements where\n"
|
||||
"element 0 is equal to \"one\",\n"
|
||||
"element 1 is equal to \"two\"", Describe(m));
|
||||
}
|
||||
|
||||
TEST(ElementsAreTest, CanDescribeNegationOfExpectingNoElement) {
|
||||
Matcher<vector<int> > m = ElementsAre();
|
||||
EXPECT_EQ("is not empty", DescribeNegation(m));
|
||||
}
|
||||
|
||||
TEST(ElementsAreTest, CanDescribeNegationOfExpectingOneElment) {
|
||||
Matcher<const list<int>& > m = ElementsAre(Gt(5));
|
||||
EXPECT_EQ("does not have 1 element, or\n"
|
||||
"element 0 is not greater than 5", DescribeNegation(m));
|
||||
}
|
||||
|
||||
TEST(ElementsAreTest, CanDescribeNegationOfExpectingManyElements) {
|
||||
Matcher<const list<string>& > m = ElementsAre("one", "two");
|
||||
EXPECT_EQ("does not have 2 elements, or\n"
|
||||
"element 0 is not equal to \"one\", or\n"
|
||||
"element 1 is not equal to \"two\"", DescribeNegation(m));
|
||||
}
|
||||
|
||||
TEST(ElementsAreTest, DoesNotExplainTrivialMatch) {
|
||||
Matcher<const list<int>& > m = ElementsAre(1, Ne(2));
|
||||
|
||||
list<int> test_list;
|
||||
test_list.push_back(1);
|
||||
test_list.push_back(3);
|
||||
EXPECT_EQ("", Explain(m, test_list)); // No need to explain anything.
|
||||
}
|
||||
|
||||
TEST(ElementsAreTest, ExplainsNonTrivialMatch) {
|
||||
Matcher<const vector<int>& > m =
|
||||
ElementsAre(GreaterThan(1), 0, GreaterThan(2));
|
||||
|
||||
const int a[] = { 10, 0, 100 };
|
||||
vector<int> test_vector(a, a + GMOCK_ARRAY_SIZE_(a));
|
||||
EXPECT_EQ("element 0 is 9 more than 1,\n"
|
||||
"element 2 is 98 more than 2", Explain(m, test_vector));
|
||||
}
|
||||
|
||||
TEST(ElementsAreTest, CanExplainMismatchWrongSize) {
|
||||
Matcher<const list<int>& > m = ElementsAre(1, 3);
|
||||
|
||||
list<int> test_list;
|
||||
// No need to explain when the container is empty.
|
||||
EXPECT_EQ("", Explain(m, test_list));
|
||||
|
||||
test_list.push_back(1);
|
||||
EXPECT_EQ("has 1 element", Explain(m, test_list));
|
||||
}
|
||||
|
||||
TEST(ElementsAreTest, CanExplainMismatchRightSize) {
|
||||
Matcher<const vector<int>& > m = ElementsAre(1, GreaterThan(5));
|
||||
|
||||
vector<int> v;
|
||||
v.push_back(2);
|
||||
v.push_back(1);
|
||||
EXPECT_EQ("element 0 doesn't match", Explain(m, v));
|
||||
|
||||
v[0] = 1;
|
||||
EXPECT_EQ("element 1 doesn't match (is 4 less than 5)", Explain(m, v));
|
||||
}
|
||||
|
||||
TEST(ElementsAreTest, MatchesOneElementVector) {
|
||||
vector<string> test_vector;
|
||||
test_vector.push_back("test string");
|
||||
|
||||
EXPECT_THAT(test_vector, ElementsAre(StrEq("test string")));
|
||||
}
|
||||
|
||||
TEST(ElementsAreTest, MatchesOneElementList) {
|
||||
list<string> test_list;
|
||||
test_list.push_back("test string");
|
||||
|
||||
EXPECT_THAT(test_list, ElementsAre("test string"));
|
||||
}
|
||||
|
||||
TEST(ElementsAreTest, MatchesThreeElementVector) {
|
||||
vector<string> test_vector;
|
||||
test_vector.push_back("one");
|
||||
test_vector.push_back("two");
|
||||
test_vector.push_back("three");
|
||||
|
||||
EXPECT_THAT(test_vector, ElementsAre("one", StrEq("two"), _));
|
||||
}
|
||||
|
||||
TEST(ElementsAreTest, MatchesOneElementEqMatcher) {
|
||||
vector<int> test_vector;
|
||||
test_vector.push_back(4);
|
||||
|
||||
EXPECT_THAT(test_vector, ElementsAre(Eq(4)));
|
||||
}
|
||||
|
||||
TEST(ElementsAreTest, MatchesOneElementAnyMatcher) {
|
||||
vector<int> test_vector;
|
||||
test_vector.push_back(4);
|
||||
|
||||
EXPECT_THAT(test_vector, ElementsAre(_));
|
||||
}
|
||||
|
||||
TEST(ElementsAreTest, MatchesOneElementValue) {
|
||||
vector<int> test_vector;
|
||||
test_vector.push_back(4);
|
||||
|
||||
EXPECT_THAT(test_vector, ElementsAre(4));
|
||||
}
|
||||
|
||||
TEST(ElementsAreTest, MatchesThreeElementsMixedMatchers) {
|
||||
vector<int> test_vector;
|
||||
test_vector.push_back(1);
|
||||
test_vector.push_back(2);
|
||||
test_vector.push_back(3);
|
||||
|
||||
EXPECT_THAT(test_vector, ElementsAre(1, Eq(2), _));
|
||||
}
|
||||
|
||||
TEST(ElementsAreTest, MatchesTenElementVector) {
|
||||
const int a[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
|
||||
vector<int> test_vector(a, a + GMOCK_ARRAY_SIZE_(a));
|
||||
|
||||
EXPECT_THAT(test_vector,
|
||||
// The element list can contain values and/or matchers
|
||||
// of different types.
|
||||
ElementsAre(0, Ge(0), _, 3, 4, Ne(2), Eq(6), 7, 8, _));
|
||||
}
|
||||
|
||||
TEST(ElementsAreTest, DoesNotMatchWrongSize) {
|
||||
vector<string> test_vector;
|
||||
test_vector.push_back("test string");
|
||||
test_vector.push_back("test string");
|
||||
|
||||
Matcher<vector<string> > m = ElementsAre(StrEq("test string"));
|
||||
EXPECT_FALSE(m.Matches(test_vector));
|
||||
}
|
||||
|
||||
TEST(ElementsAreTest, DoesNotMatchWrongValue) {
|
||||
vector<string> test_vector;
|
||||
test_vector.push_back("other string");
|
||||
|
||||
Matcher<vector<string> > m = ElementsAre(StrEq("test string"));
|
||||
EXPECT_FALSE(m.Matches(test_vector));
|
||||
}
|
||||
|
||||
TEST(ElementsAreTest, DoesNotMatchWrongOrder) {
|
||||
vector<string> test_vector;
|
||||
test_vector.push_back("one");
|
||||
test_vector.push_back("three");
|
||||
test_vector.push_back("two");
|
||||
|
||||
Matcher<vector<string> > m = ElementsAre(
|
||||
StrEq("one"), StrEq("two"), StrEq("three"));
|
||||
EXPECT_FALSE(m.Matches(test_vector));
|
||||
}
|
||||
|
||||
TEST(ElementsAreTest, WorksForNestedContainer) {
|
||||
const char* strings[] = {
|
||||
"Hi",
|
||||
"world"
|
||||
};
|
||||
|
||||
vector<list<char> > nested;
|
||||
for (int i = 0; i < GMOCK_ARRAY_SIZE_(strings); i++) {
|
||||
nested.push_back(list<char>(strings[i], strings[i] + strlen(strings[i])));
|
||||
}
|
||||
|
||||
EXPECT_THAT(nested, ElementsAre(ElementsAre('H', Ne('e')),
|
||||
ElementsAre('w', 'o', _, _, 'd')));
|
||||
EXPECT_THAT(nested, Not(ElementsAre(ElementsAre('H', 'e'),
|
||||
ElementsAre('w', 'o', _, _, 'd'))));
|
||||
}
|
||||
|
||||
TEST(ElementsAreTest, WorksWithByRefElementMatchers) {
|
||||
int a[] = { 0, 1, 2 };
|
||||
vector<int> v(a, a + GMOCK_ARRAY_SIZE_(a));
|
||||
|
||||
EXPECT_THAT(v, ElementsAre(Ref(v[0]), Ref(v[1]), Ref(v[2])));
|
||||
EXPECT_THAT(v, Not(ElementsAre(Ref(v[0]), Ref(v[1]), Ref(a[2]))));
|
||||
}
|
||||
|
||||
TEST(ElementsAreTest, WorksWithContainerPointerUsingPointee) {
|
||||
int a[] = { 0, 1, 2 };
|
||||
vector<int> v(a, a + GMOCK_ARRAY_SIZE_(a));
|
||||
|
||||
EXPECT_THAT(&v, Pointee(ElementsAre(0, 1, _)));
|
||||
EXPECT_THAT(&v, Not(Pointee(ElementsAre(0, _, 3))));
|
||||
}
|
||||
|
||||
// Tests for ElementsAreArray(). Since ElementsAreArray() shares most
|
||||
// of the implementation with ElementsAre(), we don't test it as
|
||||
// thoroughly here.
|
||||
|
||||
TEST(ElementsAreArrayTest, CanBeCreatedWithValueArray) {
|
||||
const int a[] = { 1, 2, 3 };
|
||||
|
||||
vector<int> test_vector(a, a + GMOCK_ARRAY_SIZE_(a));
|
||||
EXPECT_THAT(test_vector, ElementsAreArray(a));
|
||||
|
||||
test_vector[2] = 0;
|
||||
EXPECT_THAT(test_vector, Not(ElementsAreArray(a)));
|
||||
}
|
||||
|
||||
TEST(ElementsAreArrayTest, CanBeCreatedWithArraySize) {
|
||||
const char* a[] = { "one", "two", "three" };
|
||||
|
||||
vector<string> test_vector(a, a + GMOCK_ARRAY_SIZE_(a));
|
||||
EXPECT_THAT(test_vector, ElementsAreArray(a, GMOCK_ARRAY_SIZE_(a)));
|
||||
|
||||
const char** p = a;
|
||||
test_vector[0] = "1";
|
||||
EXPECT_THAT(test_vector, Not(ElementsAreArray(p, GMOCK_ARRAY_SIZE_(a))));
|
||||
}
|
||||
|
||||
TEST(ElementsAreArrayTest, CanBeCreatedWithoutArraySize) {
|
||||
const char* a[] = { "one", "two", "three" };
|
||||
|
||||
vector<string> test_vector(a, a + GMOCK_ARRAY_SIZE_(a));
|
||||
EXPECT_THAT(test_vector, ElementsAreArray(a));
|
||||
|
||||
test_vector[0] = "1";
|
||||
EXPECT_THAT(test_vector, Not(ElementsAreArray(a)));
|
||||
}
|
||||
|
||||
TEST(ElementsAreArrayTest, CanBeCreatedWithMatcherArray) {
|
||||
const Matcher<string> kMatcherArray[] =
|
||||
{ StrEq("one"), StrEq("two"), StrEq("three") };
|
||||
|
||||
vector<string> test_vector;
|
||||
test_vector.push_back("one");
|
||||
test_vector.push_back("two");
|
||||
test_vector.push_back("three");
|
||||
EXPECT_THAT(test_vector, ElementsAreArray(kMatcherArray));
|
||||
|
||||
test_vector.push_back("three");
|
||||
EXPECT_THAT(test_vector, Not(ElementsAreArray(kMatcherArray)));
|
||||
}
|
||||
|
||||
// Tests for the MATCHER*() macro family.
|
||||
|
||||
// Tests that a simple MATCHER() definition works.
|
||||
|
||||
MATCHER(IsEven, "") { return (arg % 2) == 0; }
|
||||
|
||||
TEST(MatcherMacroTest, Works) {
|
||||
const Matcher<int> m = IsEven();
|
||||
EXPECT_TRUE(m.Matches(6));
|
||||
EXPECT_FALSE(m.Matches(7));
|
||||
|
||||
EXPECT_EQ("is even", Describe(m));
|
||||
EXPECT_EQ("not (is even)", DescribeNegation(m));
|
||||
EXPECT_EQ("", Explain(m, 6));
|
||||
EXPECT_EQ("", Explain(m, 7));
|
||||
}
|
||||
|
||||
// Tests that the description string supplied to MATCHER() must be
|
||||
// valid.
|
||||
|
||||
MATCHER(HasBadDescription, "Invalid%") { return true; }
|
||||
|
||||
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 true; }
|
||||
|
||||
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.
|
||||
|
||||
MATCHER(IsEmptyString, "") {
|
||||
StaticAssertTypeEq< ::std::string, arg_type>();
|
||||
return arg == "";
|
||||
}
|
||||
|
||||
MATCHER(IsEmptyStringByRef, "") {
|
||||
StaticAssertTypeEq<const ::std::string&, arg_type>();
|
||||
return arg == "";
|
||||
}
|
||||
|
||||
TEST(MatcherMacroTest, CanReferenceArgType) {
|
||||
const Matcher< ::std::string> m1 = IsEmptyString();
|
||||
EXPECT_TRUE(m1.Matches(""));
|
||||
|
||||
const Matcher<const ::std::string&> m2 = IsEmptyStringByRef();
|
||||
EXPECT_TRUE(m2.Matches(""));
|
||||
}
|
||||
|
||||
// Tests that MATCHER() can be used in a namespace.
|
||||
|
||||
namespace matcher_test {
|
||||
MATCHER(IsOdd, "") { return (arg % 2) != 0; }
|
||||
} // namespace matcher_test
|
||||
|
||||
TEST(MatcherTest, WorksInNamespace) {
|
||||
Matcher<int> m = matcher_test::IsOdd();
|
||||
EXPECT_FALSE(m.Matches(4));
|
||||
EXPECT_TRUE(m.Matches(5));
|
||||
}
|
||||
|
||||
// Tests that a simple MATCHER_P() definition works.
|
||||
|
||||
MATCHER_P(IsGreaterThan32And, n, "") { return arg > 32 && arg > n; }
|
||||
|
||||
TEST(MatcherPMacroTest, Works) {
|
||||
const Matcher<int> m = IsGreaterThan32And(5);
|
||||
EXPECT_TRUE(m.Matches(36));
|
||||
EXPECT_FALSE(m.Matches(5));
|
||||
|
||||
EXPECT_EQ("is greater than 32 and 5", Describe(m));
|
||||
EXPECT_EQ("not (is greater than 32 and 5)", DescribeNegation(m));
|
||||
EXPECT_EQ("", Explain(m, 36));
|
||||
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 true; }
|
||||
|
||||
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; }
|
||||
|
||||
TEST(MatcherPMacroTest, GeneratesCorrectDescription) {
|
||||
const Matcher<int> m = _is_Greater_Than32and_(5);
|
||||
|
||||
EXPECT_EQ("is greater than 32 and 5", Describe(m));
|
||||
EXPECT_EQ("not (is greater than 32 and 5)", DescribeNegation(m));
|
||||
EXPECT_EQ("", Explain(m, 36));
|
||||
EXPECT_EQ("", Explain(m, 5));
|
||||
}
|
||||
|
||||
// Tests that a MATCHER_P matcher can be explicitly instantiated with
|
||||
// a reference parameter type.
|
||||
|
||||
class UncopyableFoo {
|
||||
public:
|
||||
explicit UncopyableFoo(char value) : value_(value) {}
|
||||
private:
|
||||
UncopyableFoo(const UncopyableFoo&);
|
||||
void operator=(const UncopyableFoo&);
|
||||
|
||||
char value_;
|
||||
};
|
||||
|
||||
MATCHER_P(ReferencesUncopyable, variable, "") { return &arg == &variable; }
|
||||
|
||||
TEST(MatcherPMacroTest, WorksWhenExplicitlyInstantiatedWithReference) {
|
||||
UncopyableFoo foo1('1'), foo2('2');
|
||||
const Matcher<const UncopyableFoo&> m =
|
||||
ReferencesUncopyable<const UncopyableFoo&>(foo1);
|
||||
|
||||
EXPECT_TRUE(m.Matches(foo1));
|
||||
EXPECT_FALSE(m.Matches(foo2));
|
||||
|
||||
// We don't want the address of the parameter printed, as most
|
||||
// likely it will just annoy the user. If the address is
|
||||
// interesting, the user should consider passing the parameter by
|
||||
// pointer instead.
|
||||
EXPECT_EQ("references uncopyable 1-byte object <31>", Describe(m));
|
||||
}
|
||||
|
||||
|
||||
// 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 true;
|
||||
}
|
||||
|
||||
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.
|
||||
|
||||
MATCHER_P3(ParamTypesAreIntLongAndChar, foo, bar, baz, "") {
|
||||
StaticAssertTypeEq<int, foo_type>();
|
||||
StaticAssertTypeEq<long, bar_type>(); // NOLINT
|
||||
StaticAssertTypeEq<char, baz_type>();
|
||||
return arg == 0;
|
||||
}
|
||||
|
||||
TEST(MatcherPnMacroTest, CanReferenceParamTypes) {
|
||||
EXPECT_THAT(0, ParamTypesAreIntLongAndChar(10, 20L, 'a'));
|
||||
}
|
||||
|
||||
// Tests that a MATCHER_Pn matcher can be explicitly instantiated with
|
||||
// reference parameter types.
|
||||
|
||||
MATCHER_P2(ReferencesAnyOf, variable1, variable2, "") {
|
||||
return &arg == &variable1 || &arg == &variable2;
|
||||
}
|
||||
|
||||
TEST(MatcherPnMacroTest, WorksWhenExplicitlyInstantiatedWithReferences) {
|
||||
UncopyableFoo foo1('1'), foo2('2'), foo3('3');
|
||||
const Matcher<const UncopyableFoo&> m =
|
||||
ReferencesAnyOf<const UncopyableFoo&, const UncopyableFoo&>(foo1, foo2);
|
||||
|
||||
EXPECT_TRUE(m.Matches(foo1));
|
||||
EXPECT_TRUE(m.Matches(foo2));
|
||||
EXPECT_FALSE(m.Matches(foo3));
|
||||
}
|
||||
|
||||
TEST(MatcherPnMacroTest,
|
||||
GeneratesCorretDescriptionWhenExplicitlyInstantiatedWithReferences) {
|
||||
UncopyableFoo foo1('1'), foo2('2');
|
||||
const Matcher<const UncopyableFoo&> m =
|
||||
ReferencesAnyOf<const UncopyableFoo&, const UncopyableFoo&>(foo1, foo2);
|
||||
|
||||
// We don't want the addresses of the parameters printed, as most
|
||||
// likely they will just annoy the user. If the addresses are
|
||||
// interesting, the user should consider passing the parameters by
|
||||
// pointers instead.
|
||||
EXPECT_EQ("references any of (1-byte object <31>, 1-byte object <32>)",
|
||||
Describe(m));
|
||||
}
|
||||
|
||||
// Tests that a simple MATCHER_P2() definition works.
|
||||
|
||||
MATCHER_P2(IsNotInClosedRange, low, hi, "") { return arg < low || arg > hi; }
|
||||
|
||||
TEST(MatcherPnMacroTest, Works) {
|
||||
const Matcher<const long&> m = IsNotInClosedRange(10, 20); // NOLINT
|
||||
EXPECT_TRUE(m.Matches(36L));
|
||||
EXPECT_FALSE(m.Matches(15L));
|
||||
|
||||
EXPECT_EQ("is not in closed range (10, 20)", Describe(m));
|
||||
EXPECT_EQ("not (is not in closed range (10, 20))", DescribeNegation(m));
|
||||
EXPECT_EQ("", Explain(m, 36L));
|
||||
EXPECT_EQ("", Explain(m, 15L));
|
||||
}
|
||||
|
||||
// Tests that MATCHER*() definitions can be overloaded on the number
|
||||
// of parameters; also tests MATCHER_Pn() where n >= 3.
|
||||
|
||||
MATCHER(EqualsSumOf, "") { return arg == 0; }
|
||||
MATCHER_P(EqualsSumOf, a, "") { return arg == a; }
|
||||
MATCHER_P2(EqualsSumOf, a, b, "") { return arg == a + b; }
|
||||
MATCHER_P3(EqualsSumOf, a, b, c, "") { return arg == a + b + c; }
|
||||
MATCHER_P4(EqualsSumOf, a, b, c, d, "") { return arg == a + b + c + d; }
|
||||
MATCHER_P5(EqualsSumOf, a, b, c, d, e, "") { return arg == a + b + c + d + e; }
|
||||
MATCHER_P6(EqualsSumOf, a, b, c, d, e, f, "") {
|
||||
return arg == a + b + c + d + e + f;
|
||||
}
|
||||
MATCHER_P7(EqualsSumOf, a, b, c, d, e, f, g, "") {
|
||||
return arg == a + b + c + d + e + f + g;
|
||||
}
|
||||
MATCHER_P8(EqualsSumOf, a, b, c, d, e, f, g, h, "") {
|
||||
return arg == a + b + c + d + e + f + g + h;
|
||||
}
|
||||
MATCHER_P9(EqualsSumOf, a, b, c, d, e, f, g, h, i, "") {
|
||||
return arg == a + b + c + d + e + f + g + h + i;
|
||||
}
|
||||
MATCHER_P10(EqualsSumOf, a, b, c, d, e, f, g, h, i, j, "") {
|
||||
return arg == a + b + c + d + e + f + g + h + i + j;
|
||||
}
|
||||
|
||||
TEST(MatcherPnMacroTest, CanBeOverloadedOnNumberOfParameters) {
|
||||
EXPECT_THAT(0, EqualsSumOf());
|
||||
EXPECT_THAT(1, EqualsSumOf(1));
|
||||
EXPECT_THAT(12, EqualsSumOf(10, 2));
|
||||
EXPECT_THAT(123, EqualsSumOf(100, 20, 3));
|
||||
EXPECT_THAT(1234, EqualsSumOf(1000, 200, 30, 4));
|
||||
EXPECT_THAT(12345, EqualsSumOf(10000, 2000, 300, 40, 5));
|
||||
EXPECT_THAT("abcdef",
|
||||
EqualsSumOf(::std::string("a"), 'b', 'c', "d", "e", 'f'));
|
||||
EXPECT_THAT("abcdefg",
|
||||
EqualsSumOf(::std::string("a"), 'b', 'c', "d", "e", 'f', 'g'));
|
||||
EXPECT_THAT("abcdefgh",
|
||||
EqualsSumOf(::std::string("a"), 'b', 'c', "d", "e", 'f', 'g',
|
||||
"h"));
|
||||
EXPECT_THAT("abcdefghi",
|
||||
EqualsSumOf(::std::string("a"), 'b', 'c', "d", "e", 'f', 'g',
|
||||
"h", 'i'));
|
||||
EXPECT_THAT("abcdefghij",
|
||||
EqualsSumOf(::std::string("a"), 'b', 'c', "d", "e", 'f', 'g',
|
||||
"h", 'i', ::std::string("j")));
|
||||
|
||||
EXPECT_THAT(1, Not(EqualsSumOf()));
|
||||
EXPECT_THAT(-1, Not(EqualsSumOf(1)));
|
||||
EXPECT_THAT(-12, Not(EqualsSumOf(10, 2)));
|
||||
EXPECT_THAT(-123, Not(EqualsSumOf(100, 20, 3)));
|
||||
EXPECT_THAT(-1234, Not(EqualsSumOf(1000, 200, 30, 4)));
|
||||
EXPECT_THAT(-12345, Not(EqualsSumOf(10000, 2000, 300, 40, 5)));
|
||||
EXPECT_THAT("abcdef ",
|
||||
Not(EqualsSumOf(::std::string("a"), 'b', 'c', "d", "e", 'f')));
|
||||
EXPECT_THAT("abcdefg ",
|
||||
Not(EqualsSumOf(::std::string("a"), 'b', 'c', "d", "e", 'f',
|
||||
'g')));
|
||||
EXPECT_THAT("abcdefgh ",
|
||||
Not(EqualsSumOf(::std::string("a"), 'b', 'c', "d", "e", 'f', 'g',
|
||||
"h")));
|
||||
EXPECT_THAT("abcdefghi ",
|
||||
Not(EqualsSumOf(::std::string("a"), 'b', 'c', "d", "e", 'f', 'g',
|
||||
"h", 'i')));
|
||||
EXPECT_THAT("abcdefghij ",
|
||||
Not(EqualsSumOf(::std::string("a"), 'b', 'c', "d", "e", 'f', 'g',
|
||||
"h", 'i', ::std::string("j"))));
|
||||
}
|
||||
|
||||
// Tests that a MATCHER_Pn() definition can be instantiated with any
|
||||
// compatible parameter types.
|
||||
TEST(MatcherPnMacroTest, WorksForDifferentParameterTypes) {
|
||||
EXPECT_THAT(123, EqualsSumOf(100L, 20, static_cast<char>(3)));
|
||||
EXPECT_THAT("abcd", EqualsSumOf(::std::string("a"), "b", 'c', "d"));
|
||||
|
||||
EXPECT_THAT(124, Not(EqualsSumOf(100L, 20, static_cast<char>(3))));
|
||||
EXPECT_THAT("abcde", Not(EqualsSumOf(::std::string("a"), "b", 'c', "d")));
|
||||
}
|
||||
|
||||
// Tests that the matcher body can promote the parameter types.
|
||||
|
||||
MATCHER_P2(EqConcat, prefix, suffix, "") {
|
||||
// The following lines promote the two parameters to desired types.
|
||||
std::string prefix_str(prefix);
|
||||
char suffix_char(suffix);
|
||||
return arg == prefix_str + suffix_char;
|
||||
}
|
||||
|
||||
TEST(MatcherPnMacroTest, SimpleTypePromotion) {
|
||||
Matcher<std::string> no_promo =
|
||||
EqConcat(std::string("foo"), 't');
|
||||
Matcher<const std::string&> promo =
|
||||
EqConcat("foo", static_cast<int>('t'));
|
||||
EXPECT_FALSE(no_promo.Matches("fool"));
|
||||
EXPECT_FALSE(promo.Matches("fool"));
|
||||
EXPECT_TRUE(no_promo.Matches("foot"));
|
||||
EXPECT_TRUE(promo.Matches("foot"));
|
||||
}
|
||||
|
||||
// Verifies the type of a MATCHER*.
|
||||
|
||||
TEST(MatcherPnMacroTest, TypesAreCorrect) {
|
||||
// EqualsSumOf() must be assignable to a EqualsSumOfMatcher variable.
|
||||
EqualsSumOfMatcher a0 = EqualsSumOf();
|
||||
|
||||
// EqualsSumOf(1) must be assignable to a EqualsSumOfMatcherP variable.
|
||||
EqualsSumOfMatcherP<int> a1 = EqualsSumOf(1);
|
||||
|
||||
// EqualsSumOf(p1, ..., pk) must be assignable to a EqualsSumOfMatcherPk
|
||||
// variable, and so on.
|
||||
EqualsSumOfMatcherP2<int, char> a2 = EqualsSumOf(1, '2');
|
||||
EqualsSumOfMatcherP3<int, int, char> a3 = EqualsSumOf(1, 2, '3');
|
||||
EqualsSumOfMatcherP4<int, int, int, char> a4 = EqualsSumOf(1, 2, 3, '4');
|
||||
EqualsSumOfMatcherP5<int, int, int, int, char> a5 =
|
||||
EqualsSumOf(1, 2, 3, 4, '5');
|
||||
EqualsSumOfMatcherP6<int, int, int, int, int, char> a6 =
|
||||
EqualsSumOf(1, 2, 3, 4, 5, '6');
|
||||
EqualsSumOfMatcherP7<int, int, int, int, int, int, char> a7 =
|
||||
EqualsSumOf(1, 2, 3, 4, 5, 6, '7');
|
||||
EqualsSumOfMatcherP8<int, int, int, int, int, int, int, char> a8 =
|
||||
EqualsSumOf(1, 2, 3, 4, 5, 6, 7, '8');
|
||||
EqualsSumOfMatcherP9<int, int, int, int, int, int, int, int, char> a9 =
|
||||
EqualsSumOf(1, 2, 3, 4, 5, 6, 7, 8, '9');
|
||||
EqualsSumOfMatcherP10<int, int, int, int, int, int, int, int, int, char> a10 =
|
||||
EqualsSumOf(1, 2, 3, 4, 5, 6, 7, 8, 9, '0');
|
||||
}
|
||||
|
||||
TEST(ContainsTest, ListMatchesWhenElementIsInContainer) {
|
||||
list<int> some_list;
|
||||
some_list.push_back(3);
|
||||
some_list.push_back(1);
|
||||
some_list.push_back(2);
|
||||
EXPECT_THAT(some_list, Contains(1));
|
||||
EXPECT_THAT(some_list, Contains(3.0));
|
||||
EXPECT_THAT(some_list, Contains(2.0f));
|
||||
|
||||
list<string> another_list;
|
||||
another_list.push_back("fee");
|
||||
another_list.push_back("fie");
|
||||
another_list.push_back("foe");
|
||||
another_list.push_back("fum");
|
||||
EXPECT_THAT(another_list, Contains(string("fee")));
|
||||
}
|
||||
|
||||
TEST(ContainsTest, ListDoesNotMatchWhenElementIsNotInContainer) {
|
||||
list<int> some_list;
|
||||
some_list.push_back(3);
|
||||
some_list.push_back(1);
|
||||
EXPECT_THAT(some_list, Not(Contains(4)));
|
||||
}
|
||||
|
||||
TEST(ContainsTest, SetMatchesWhenElementIsInContainer) {
|
||||
set<int> some_set;
|
||||
some_set.insert(3);
|
||||
some_set.insert(1);
|
||||
some_set.insert(2);
|
||||
EXPECT_THAT(some_set, Contains(1.0));
|
||||
EXPECT_THAT(some_set, Contains(3.0f));
|
||||
EXPECT_THAT(some_set, Contains(2));
|
||||
|
||||
set<const char*> another_set;
|
||||
another_set.insert("fee");
|
||||
another_set.insert("fie");
|
||||
another_set.insert("foe");
|
||||
another_set.insert("fum");
|
||||
EXPECT_THAT(another_set, Contains(string("fum")));
|
||||
}
|
||||
|
||||
TEST(ContainsTest, SetDoesNotMatchWhenElementIsNotInContainer) {
|
||||
set<int> some_set;
|
||||
some_set.insert(3);
|
||||
some_set.insert(1);
|
||||
EXPECT_THAT(some_set, Not(Contains(4)));
|
||||
|
||||
set<const char*> c_string_set;
|
||||
c_string_set.insert("hello");
|
||||
EXPECT_THAT(c_string_set, Not(Contains(string("hello").c_str())));
|
||||
}
|
||||
|
||||
TEST(ContainsTest, DescribesItselfCorrectly) {
|
||||
Matcher<vector<int> > m = Contains(1);
|
||||
EXPECT_EQ("contains 1", Describe(m));
|
||||
}
|
||||
|
||||
TEST(ContainsTest, MapMatchesWhenElementIsInContainer) {
|
||||
map<const char*, int> my_map;
|
||||
const char* bar = "a string";
|
||||
my_map[bar] = 2;
|
||||
EXPECT_THAT(my_map, Contains(pair<const char* const, int>(bar, 2)));
|
||||
|
||||
map<string, int> another_map;
|
||||
another_map["fee"] = 1;
|
||||
another_map["fie"] = 2;
|
||||
another_map["foe"] = 3;
|
||||
another_map["fum"] = 4;
|
||||
EXPECT_THAT(another_map, Contains(pair<const string, int>(string("fee"), 1)));
|
||||
EXPECT_THAT(another_map, Contains(pair<const string, int>("fie", 2)));
|
||||
}
|
||||
|
||||
TEST(ContainsTest, MapDoesNotMatchWhenElementIsNotInContainer) {
|
||||
map<int, int> some_map;
|
||||
some_map[1] = 11;
|
||||
some_map[2] = 22;
|
||||
EXPECT_THAT(some_map, Not(Contains(pair<const int, int>(2, 23))));
|
||||
}
|
||||
|
||||
TEST(ContainsTest, ArrayMatchesWhenElementIsInContainer) {
|
||||
const char* string_array[] = { "fee", "fie", "foe", "fum" };
|
||||
EXPECT_THAT(string_array, Contains(string("fum")));
|
||||
}
|
||||
|
||||
TEST(ContainsTest, ArrayDoesNotMatchWhenElementIsNotInContainer) {
|
||||
int int_array[] = { 1, 2, 3, 4 };
|
||||
EXPECT_THAT(int_array, Not(Contains(5)));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
@@ -0,0 +1,698 @@
|
||||
// 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)
|
||||
|
||||
// Google Mock - a framework for writing C++ mock classes.
|
||||
//
|
||||
// This file tests the internal utilities.
|
||||
|
||||
#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>
|
||||
|
||||
#if GTEST_OS_CYGWIN
|
||||
#include <sys/types.h> // For ssize_t. NOLINT
|
||||
#endif
|
||||
|
||||
namespace testing {
|
||||
namespace internal {
|
||||
|
||||
namespace {
|
||||
|
||||
using ::std::tr1::tuple;
|
||||
|
||||
TEST(ConvertIdentifierNameToWordsTest, WorksWhenNameContainsNoWord) {
|
||||
EXPECT_EQ("", ConvertIdentifierNameToWords(""));
|
||||
EXPECT_EQ("", ConvertIdentifierNameToWords("_"));
|
||||
EXPECT_EQ("", ConvertIdentifierNameToWords("__"));
|
||||
}
|
||||
|
||||
TEST(ConvertIdentifierNameToWordsTest, WorksWhenNameContainsDigits) {
|
||||
EXPECT_EQ("1", ConvertIdentifierNameToWords("_1"));
|
||||
EXPECT_EQ("2", ConvertIdentifierNameToWords("2_"));
|
||||
EXPECT_EQ("34", ConvertIdentifierNameToWords("_34_"));
|
||||
EXPECT_EQ("34 56", ConvertIdentifierNameToWords("_34_56"));
|
||||
}
|
||||
|
||||
TEST(ConvertIdentifierNameToWordsTest, WorksWhenNameContainsCamelCaseWords) {
|
||||
EXPECT_EQ("a big word", ConvertIdentifierNameToWords("ABigWord"));
|
||||
EXPECT_EQ("foo bar", ConvertIdentifierNameToWords("FooBar"));
|
||||
EXPECT_EQ("foo", ConvertIdentifierNameToWords("Foo_"));
|
||||
EXPECT_EQ("foo bar", ConvertIdentifierNameToWords("_Foo_Bar_"));
|
||||
EXPECT_EQ("foo and bar", ConvertIdentifierNameToWords("_Foo__And_Bar"));
|
||||
}
|
||||
|
||||
TEST(ConvertIdentifierNameToWordsTest, WorksWhenNameContains_SeparatedWords) {
|
||||
EXPECT_EQ("foo bar", ConvertIdentifierNameToWords("foo_bar"));
|
||||
EXPECT_EQ("foo", ConvertIdentifierNameToWords("_foo_"));
|
||||
EXPECT_EQ("foo bar", ConvertIdentifierNameToWords("_foo_bar_"));
|
||||
EXPECT_EQ("foo and bar", ConvertIdentifierNameToWords("_foo__and_bar"));
|
||||
}
|
||||
|
||||
TEST(ConvertIdentifierNameToWordsTest, WorksWhenNameIsMixture) {
|
||||
EXPECT_EQ("foo bar 123", ConvertIdentifierNameToWords("Foo_bar123"));
|
||||
EXPECT_EQ("chapter 11 section 1",
|
||||
ConvertIdentifierNameToWords("_Chapter11Section_1_"));
|
||||
}
|
||||
|
||||
// Tests that CompileAssertTypesEqual compiles when the type arguments are
|
||||
// equal.
|
||||
TEST(CompileAssertTypesEqual, CompilesWhenTypesAreEqual) {
|
||||
CompileAssertTypesEqual<void, void>();
|
||||
CompileAssertTypesEqual<int*, int*>();
|
||||
}
|
||||
|
||||
// Tests that RemoveReference does not affect non-reference types.
|
||||
TEST(RemoveReferenceTest, DoesNotAffectNonReferenceType) {
|
||||
CompileAssertTypesEqual<int, RemoveReference<int>::type>();
|
||||
CompileAssertTypesEqual<const char, RemoveReference<const char>::type>();
|
||||
}
|
||||
|
||||
// Tests that RemoveReference removes reference from reference types.
|
||||
TEST(RemoveReferenceTest, RemovesReference) {
|
||||
CompileAssertTypesEqual<int, RemoveReference<int&>::type>();
|
||||
CompileAssertTypesEqual<const char, RemoveReference<const char&>::type>();
|
||||
}
|
||||
|
||||
// Tests GMOCK_REMOVE_REFERENCE_.
|
||||
|
||||
template <typename T1, typename T2>
|
||||
void TestGMockRemoveReference() {
|
||||
CompileAssertTypesEqual<T1, GMOCK_REMOVE_REFERENCE_(T2)>();
|
||||
}
|
||||
|
||||
TEST(RemoveReferenceTest, MacroVersion) {
|
||||
TestGMockRemoveReference<int, int>();
|
||||
TestGMockRemoveReference<const char, const char&>();
|
||||
}
|
||||
|
||||
|
||||
// Tests that RemoveConst does not affect non-const types.
|
||||
TEST(RemoveConstTest, DoesNotAffectNonConstType) {
|
||||
CompileAssertTypesEqual<int, RemoveConst<int>::type>();
|
||||
CompileAssertTypesEqual<char&, RemoveConst<char&>::type>();
|
||||
}
|
||||
|
||||
// Tests that RemoveConst removes const from const types.
|
||||
TEST(RemoveConstTest, RemovesConst) {
|
||||
CompileAssertTypesEqual<int, RemoveConst<const int>::type>();
|
||||
}
|
||||
|
||||
// Tests GMOCK_REMOVE_CONST_.
|
||||
|
||||
template <typename T1, typename T2>
|
||||
void TestGMockRemoveConst() {
|
||||
CompileAssertTypesEqual<T1, GMOCK_REMOVE_CONST_(T2)>();
|
||||
}
|
||||
|
||||
TEST(RemoveConstTest, MacroVersion) {
|
||||
TestGMockRemoveConst<int, int>();
|
||||
TestGMockRemoveConst<double&, double&>();
|
||||
TestGMockRemoveConst<char, const char>();
|
||||
}
|
||||
|
||||
// Tests that AddReference does not affect reference types.
|
||||
TEST(AddReferenceTest, DoesNotAffectReferenceType) {
|
||||
CompileAssertTypesEqual<int&, AddReference<int&>::type>();
|
||||
CompileAssertTypesEqual<const char&, AddReference<const char&>::type>();
|
||||
}
|
||||
|
||||
// Tests that AddReference adds reference to non-reference types.
|
||||
TEST(AddReferenceTest, AddsReference) {
|
||||
CompileAssertTypesEqual<int&, AddReference<int>::type>();
|
||||
CompileAssertTypesEqual<const char&, AddReference<const char>::type>();
|
||||
}
|
||||
|
||||
// Tests GMOCK_ADD_REFERENCE_.
|
||||
|
||||
template <typename T1, typename T2>
|
||||
void TestGMockAddReference() {
|
||||
CompileAssertTypesEqual<T1, GMOCK_ADD_REFERENCE_(T2)>();
|
||||
}
|
||||
|
||||
TEST(AddReferenceTest, MacroVersion) {
|
||||
TestGMockAddReference<int&, int>();
|
||||
TestGMockAddReference<const char&, const char&>();
|
||||
}
|
||||
|
||||
// Tests GMOCK_REFERENCE_TO_CONST_.
|
||||
|
||||
template <typename T1, typename T2>
|
||||
void TestGMockReferenceToConst() {
|
||||
CompileAssertTypesEqual<T1, GMOCK_REFERENCE_TO_CONST_(T2)>();
|
||||
}
|
||||
|
||||
TEST(GMockReferenceToConstTest, Works) {
|
||||
TestGMockReferenceToConst<const char&, char>();
|
||||
TestGMockReferenceToConst<const int&, const int>();
|
||||
TestGMockReferenceToConst<const double&, double>();
|
||||
TestGMockReferenceToConst<const string&, const string&>();
|
||||
}
|
||||
|
||||
TEST(PointeeOfTest, WorksForSmartPointers) {
|
||||
CompileAssertTypesEqual<const char,
|
||||
PointeeOf<internal::linked_ptr<const char> >::type>();
|
||||
}
|
||||
|
||||
TEST(PointeeOfTest, WorksForRawPointers) {
|
||||
CompileAssertTypesEqual<int, PointeeOf<int*>::type>();
|
||||
CompileAssertTypesEqual<const char, PointeeOf<const char*>::type>();
|
||||
CompileAssertTypesEqual<void, PointeeOf<void*>::type>();
|
||||
}
|
||||
|
||||
TEST(GetRawPointerTest, WorksForSmartPointers) {
|
||||
const char* const raw_p4 = new const char('a'); // NOLINT
|
||||
const internal::linked_ptr<const char> p4(raw_p4);
|
||||
EXPECT_EQ(raw_p4, GetRawPointer(p4));
|
||||
}
|
||||
|
||||
TEST(GetRawPointerTest, WorksForRawPointers) {
|
||||
int* p = NULL;
|
||||
EXPECT_EQ(NULL, GetRawPointer(p));
|
||||
int n = 1;
|
||||
EXPECT_EQ(&n, GetRawPointer(&n));
|
||||
}
|
||||
|
||||
class Base {};
|
||||
class Derived : public Base {};
|
||||
|
||||
// Tests that ImplicitlyConvertible<T1, T2>::value is a compile-time constant.
|
||||
TEST(ImplicitlyConvertibleTest, ValueIsCompileTimeConstant) {
|
||||
GMOCK_COMPILE_ASSERT_((ImplicitlyConvertible<int, int>::value), const_true);
|
||||
GMOCK_COMPILE_ASSERT_((!ImplicitlyConvertible<void*, int*>::value),
|
||||
const_false);
|
||||
}
|
||||
|
||||
// Tests that ImplicitlyConvertible<T1, T2>::value is true when T1 can
|
||||
// be implicitly converted to T2.
|
||||
TEST(ImplicitlyConvertibleTest, ValueIsTrueWhenConvertible) {
|
||||
EXPECT_TRUE((ImplicitlyConvertible<int, double>::value));
|
||||
EXPECT_TRUE((ImplicitlyConvertible<double, int>::value));
|
||||
EXPECT_TRUE((ImplicitlyConvertible<int*, void*>::value));
|
||||
EXPECT_TRUE((ImplicitlyConvertible<int*, const int*>::value));
|
||||
EXPECT_TRUE((ImplicitlyConvertible<Derived&, const Base&>::value));
|
||||
EXPECT_TRUE((ImplicitlyConvertible<const Base, Base>::value));
|
||||
}
|
||||
|
||||
// Tests that ImplicitlyConvertible<T1, T2>::value is false when T1
|
||||
// cannot be implicitly converted to T2.
|
||||
TEST(ImplicitlyConvertibleTest, ValueIsFalseWhenNotConvertible) {
|
||||
EXPECT_FALSE((ImplicitlyConvertible<double, int*>::value));
|
||||
EXPECT_FALSE((ImplicitlyConvertible<void*, int*>::value));
|
||||
EXPECT_FALSE((ImplicitlyConvertible<const int*, int*>::value));
|
||||
EXPECT_FALSE((ImplicitlyConvertible<Base&, Derived&>::value));
|
||||
}
|
||||
|
||||
// Tests KindOf<T>.
|
||||
|
||||
TEST(KindOfTest, Bool) {
|
||||
EXPECT_EQ(kBool, GMOCK_KIND_OF_(bool)); // NOLINT
|
||||
}
|
||||
|
||||
TEST(KindOfTest, Integer) {
|
||||
EXPECT_EQ(kInteger, GMOCK_KIND_OF_(char)); // NOLINT
|
||||
EXPECT_EQ(kInteger, GMOCK_KIND_OF_(signed char)); // NOLINT
|
||||
EXPECT_EQ(kInteger, GMOCK_KIND_OF_(unsigned char)); // NOLINT
|
||||
EXPECT_EQ(kInteger, GMOCK_KIND_OF_(short)); // NOLINT
|
||||
EXPECT_EQ(kInteger, GMOCK_KIND_OF_(unsigned short)); // NOLINT
|
||||
EXPECT_EQ(kInteger, GMOCK_KIND_OF_(int)); // NOLINT
|
||||
EXPECT_EQ(kInteger, GMOCK_KIND_OF_(unsigned int)); // NOLINT
|
||||
EXPECT_EQ(kInteger, GMOCK_KIND_OF_(long)); // NOLINT
|
||||
EXPECT_EQ(kInteger, GMOCK_KIND_OF_(unsigned long)); // NOLINT
|
||||
EXPECT_EQ(kInteger, GMOCK_KIND_OF_(wchar_t)); // NOLINT
|
||||
EXPECT_EQ(kInteger, GMOCK_KIND_OF_(Int64)); // NOLINT
|
||||
EXPECT_EQ(kInteger, GMOCK_KIND_OF_(UInt64)); // NOLINT
|
||||
EXPECT_EQ(kInteger, GMOCK_KIND_OF_(size_t)); // NOLINT
|
||||
#if GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_CYGWIN
|
||||
// ssize_t is not defined on Windows and possibly some other OSes.
|
||||
EXPECT_EQ(kInteger, GMOCK_KIND_OF_(ssize_t)); // NOLINT
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST(KindOfTest, FloatingPoint) {
|
||||
EXPECT_EQ(kFloatingPoint, GMOCK_KIND_OF_(float)); // NOLINT
|
||||
EXPECT_EQ(kFloatingPoint, GMOCK_KIND_OF_(double)); // NOLINT
|
||||
EXPECT_EQ(kFloatingPoint, GMOCK_KIND_OF_(long double)); // NOLINT
|
||||
}
|
||||
|
||||
TEST(KindOfTest, Other) {
|
||||
EXPECT_EQ(kOther, GMOCK_KIND_OF_(void*)); // NOLINT
|
||||
EXPECT_EQ(kOther, GMOCK_KIND_OF_(char**)); // NOLINT
|
||||
EXPECT_EQ(kOther, GMOCK_KIND_OF_(Base)); // NOLINT
|
||||
}
|
||||
|
||||
// Tests LosslessArithmeticConvertible<T, U>.
|
||||
|
||||
TEST(LosslessArithmeticConvertibleTest, BoolToBool) {
|
||||
EXPECT_TRUE((LosslessArithmeticConvertible<bool, bool>::value));
|
||||
}
|
||||
|
||||
TEST(LosslessArithmeticConvertibleTest, BoolToInteger) {
|
||||
EXPECT_TRUE((LosslessArithmeticConvertible<bool, char>::value));
|
||||
EXPECT_TRUE((LosslessArithmeticConvertible<bool, int>::value));
|
||||
EXPECT_TRUE(
|
||||
(LosslessArithmeticConvertible<bool, unsigned long>::value)); // NOLINT
|
||||
}
|
||||
|
||||
TEST(LosslessArithmeticConvertibleTest, BoolToFloatingPoint) {
|
||||
EXPECT_TRUE((LosslessArithmeticConvertible<bool, float>::value));
|
||||
EXPECT_TRUE((LosslessArithmeticConvertible<bool, double>::value));
|
||||
}
|
||||
|
||||
TEST(LosslessArithmeticConvertibleTest, IntegerToBool) {
|
||||
EXPECT_FALSE((LosslessArithmeticConvertible<unsigned char, bool>::value));
|
||||
EXPECT_FALSE((LosslessArithmeticConvertible<int, bool>::value));
|
||||
}
|
||||
|
||||
TEST(LosslessArithmeticConvertibleTest, IntegerToInteger) {
|
||||
// Unsigned => larger signed is fine.
|
||||
EXPECT_TRUE((LosslessArithmeticConvertible<unsigned char, int>::value));
|
||||
|
||||
// Unsigned => larger unsigned is fine.
|
||||
EXPECT_TRUE(
|
||||
(LosslessArithmeticConvertible<unsigned short, UInt64>::value)); // NOLINT
|
||||
|
||||
// Signed => unsigned is not fine.
|
||||
EXPECT_FALSE((LosslessArithmeticConvertible<short, UInt64>::value)); // NOLINT
|
||||
EXPECT_FALSE((LosslessArithmeticConvertible<
|
||||
signed char, unsigned int>::value)); // NOLINT
|
||||
|
||||
// Same size and same signedness: fine too.
|
||||
EXPECT_TRUE((LosslessArithmeticConvertible<
|
||||
unsigned char, unsigned char>::value));
|
||||
EXPECT_TRUE((LosslessArithmeticConvertible<int, int>::value));
|
||||
EXPECT_TRUE((LosslessArithmeticConvertible<wchar_t, wchar_t>::value));
|
||||
EXPECT_TRUE((LosslessArithmeticConvertible<
|
||||
unsigned long, unsigned long>::value)); // NOLINT
|
||||
|
||||
// Same size, different signedness: not fine.
|
||||
EXPECT_FALSE((LosslessArithmeticConvertible<
|
||||
unsigned char, signed char>::value));
|
||||
EXPECT_FALSE((LosslessArithmeticConvertible<int, unsigned int>::value));
|
||||
EXPECT_FALSE((LosslessArithmeticConvertible<UInt64, Int64>::value));
|
||||
|
||||
// Larger size => smaller size is not fine.
|
||||
EXPECT_FALSE((LosslessArithmeticConvertible<long, char>::value)); // NOLINT
|
||||
EXPECT_FALSE((LosslessArithmeticConvertible<int, signed char>::value));
|
||||
EXPECT_FALSE((LosslessArithmeticConvertible<Int64, unsigned int>::value));
|
||||
}
|
||||
|
||||
TEST(LosslessArithmeticConvertibleTest, IntegerToFloatingPoint) {
|
||||
// Integers cannot be losslessly converted to floating-points, as
|
||||
// the format of the latter is implementation-defined.
|
||||
EXPECT_FALSE((LosslessArithmeticConvertible<char, float>::value));
|
||||
EXPECT_FALSE((LosslessArithmeticConvertible<int, double>::value));
|
||||
EXPECT_FALSE((LosslessArithmeticConvertible<
|
||||
short, long double>::value)); // NOLINT
|
||||
}
|
||||
|
||||
TEST(LosslessArithmeticConvertibleTest, FloatingPointToBool) {
|
||||
EXPECT_FALSE((LosslessArithmeticConvertible<float, bool>::value));
|
||||
EXPECT_FALSE((LosslessArithmeticConvertible<double, bool>::value));
|
||||
}
|
||||
|
||||
TEST(LosslessArithmeticConvertibleTest, FloatingPointToInteger) {
|
||||
EXPECT_FALSE((LosslessArithmeticConvertible<float, long>::value)); // NOLINT
|
||||
EXPECT_FALSE((LosslessArithmeticConvertible<double, Int64>::value));
|
||||
EXPECT_FALSE((LosslessArithmeticConvertible<long double, int>::value));
|
||||
}
|
||||
|
||||
TEST(LosslessArithmeticConvertibleTest, FloatingPointToFloatingPoint) {
|
||||
// Smaller size => larger size is fine.
|
||||
EXPECT_TRUE((LosslessArithmeticConvertible<float, double>::value));
|
||||
EXPECT_TRUE((LosslessArithmeticConvertible<float, long double>::value));
|
||||
EXPECT_TRUE((LosslessArithmeticConvertible<double, long double>::value));
|
||||
|
||||
// Same size: fine.
|
||||
EXPECT_TRUE((LosslessArithmeticConvertible<float, float>::value));
|
||||
EXPECT_TRUE((LosslessArithmeticConvertible<double, double>::value));
|
||||
|
||||
// Larger size => smaller size is not fine.
|
||||
EXPECT_FALSE((LosslessArithmeticConvertible<double, float>::value));
|
||||
if (sizeof(double) == sizeof(long double)) { // NOLINT
|
||||
// In some implementations (e.g. MSVC), double and long double
|
||||
// have the same size.
|
||||
EXPECT_TRUE((LosslessArithmeticConvertible<long double, double>::value));
|
||||
} else {
|
||||
EXPECT_FALSE((LosslessArithmeticConvertible<long double, double>::value));
|
||||
}
|
||||
}
|
||||
|
||||
// Tests that IsAProtocolMessage<T>::value is a compile-time constant.
|
||||
TEST(IsAProtocolMessageTest, ValueIsCompileTimeConstant) {
|
||||
GMOCK_COMPILE_ASSERT_(IsAProtocolMessage<ProtocolMessage>::value, const_true);
|
||||
GMOCK_COMPILE_ASSERT_(!IsAProtocolMessage<int>::value, const_false);
|
||||
}
|
||||
|
||||
// Tests that IsAProtocolMessage<T>::value is true when T is
|
||||
// ProtocolMessage or a sub-class of it.
|
||||
TEST(IsAProtocolMessageTest, ValueIsTrueWhenTypeIsAProtocolMessage) {
|
||||
EXPECT_TRUE(IsAProtocolMessage<ProtocolMessage>::value);
|
||||
#if GMOCK_HAS_PROTOBUF_
|
||||
EXPECT_TRUE(IsAProtocolMessage<const TestMessage>::value);
|
||||
#endif // GMOCK_HAS_PROTOBUF_
|
||||
}
|
||||
|
||||
// Tests that IsAProtocolMessage<T>::value is false when T is neither
|
||||
// ProtocolMessage nor a sub-class of it.
|
||||
TEST(IsAProtocolMessageTest, ValueIsFalseWhenTypeIsNotAProtocolMessage) {
|
||||
EXPECT_FALSE(IsAProtocolMessage<int>::value);
|
||||
EXPECT_FALSE(IsAProtocolMessage<const Base>::value);
|
||||
}
|
||||
|
||||
// Tests IsContainerTest.
|
||||
|
||||
class NonContainer {};
|
||||
|
||||
TEST(IsContainerTestTest, WorksForNonContainer) {
|
||||
EXPECT_EQ(sizeof(IsNotContainer), sizeof(IsContainerTest<int>(0)));
|
||||
EXPECT_EQ(sizeof(IsNotContainer), sizeof(IsContainerTest<char[5]>(0)));
|
||||
EXPECT_EQ(sizeof(IsNotContainer), sizeof(IsContainerTest<NonContainer>(0)));
|
||||
}
|
||||
|
||||
TEST(IsContainerTestTest, WorksForContainer) {
|
||||
EXPECT_EQ(sizeof(IsContainer),
|
||||
sizeof(IsContainerTest<std::vector<bool> >(0)));
|
||||
EXPECT_EQ(sizeof(IsContainer),
|
||||
sizeof(IsContainerTest<std::map<int, double> >(0)));
|
||||
}
|
||||
|
||||
// Tests the TupleMatches() template function.
|
||||
|
||||
TEST(TupleMatchesTest, WorksForSize0) {
|
||||
tuple<> matchers;
|
||||
tuple<> values;
|
||||
|
||||
EXPECT_TRUE(TupleMatches(matchers, values));
|
||||
}
|
||||
|
||||
TEST(TupleMatchesTest, WorksForSize1) {
|
||||
tuple<Matcher<int> > matchers(Eq(1));
|
||||
tuple<int> values1(1),
|
||||
values2(2);
|
||||
|
||||
EXPECT_TRUE(TupleMatches(matchers, values1));
|
||||
EXPECT_FALSE(TupleMatches(matchers, values2));
|
||||
}
|
||||
|
||||
TEST(TupleMatchesTest, WorksForSize2) {
|
||||
tuple<Matcher<int>, Matcher<char> > matchers(Eq(1), Eq('a'));
|
||||
tuple<int, char> values1(1, 'a'),
|
||||
values2(1, 'b'),
|
||||
values3(2, 'a'),
|
||||
values4(2, 'b');
|
||||
|
||||
EXPECT_TRUE(TupleMatches(matchers, values1));
|
||||
EXPECT_FALSE(TupleMatches(matchers, values2));
|
||||
EXPECT_FALSE(TupleMatches(matchers, values3));
|
||||
EXPECT_FALSE(TupleMatches(matchers, values4));
|
||||
}
|
||||
|
||||
TEST(TupleMatchesTest, WorksForSize5) {
|
||||
tuple<Matcher<int>, Matcher<char>, Matcher<bool>, Matcher<long>, // NOLINT
|
||||
Matcher<string> >
|
||||
matchers(Eq(1), Eq('a'), Eq(true), Eq(2L), Eq("hi"));
|
||||
tuple<int, char, bool, long, string> // NOLINT
|
||||
values1(1, 'a', true, 2L, "hi"),
|
||||
values2(1, 'a', true, 2L, "hello"),
|
||||
values3(2, 'a', true, 2L, "hi");
|
||||
|
||||
EXPECT_TRUE(TupleMatches(matchers, values1));
|
||||
EXPECT_FALSE(TupleMatches(matchers, values2));
|
||||
EXPECT_FALSE(TupleMatches(matchers, values3));
|
||||
}
|
||||
|
||||
// Tests that Assert(true, ...) succeeds.
|
||||
TEST(AssertTest, SucceedsOnTrue) {
|
||||
Assert(true, __FILE__, __LINE__, "This should succeed.");
|
||||
Assert(true, __FILE__, __LINE__); // This should succeed too.
|
||||
}
|
||||
|
||||
#if GTEST_HAS_DEATH_TEST
|
||||
|
||||
// Tests that Assert(false, ...) generates a fatal failure.
|
||||
TEST(AssertTest, FailsFatallyOnFalse) {
|
||||
EXPECT_DEATH({ // NOLINT
|
||||
Assert(false, __FILE__, __LINE__, "This should fail.");
|
||||
}, "");
|
||||
|
||||
EXPECT_DEATH({ // NOLINT
|
||||
Assert(false, __FILE__, __LINE__);
|
||||
}, "");
|
||||
}
|
||||
|
||||
#endif // GTEST_HAS_DEATH_TEST
|
||||
|
||||
// Tests that Expect(true, ...) succeeds.
|
||||
TEST(ExpectTest, SucceedsOnTrue) {
|
||||
Expect(true, __FILE__, __LINE__, "This should succeed.");
|
||||
Expect(true, __FILE__, __LINE__); // This should succeed too.
|
||||
}
|
||||
|
||||
// Tests that Expect(false, ...) generates a non-fatal failure.
|
||||
TEST(ExpectTest, FailsNonfatallyOnFalse) {
|
||||
EXPECT_NONFATAL_FAILURE({ // NOLINT
|
||||
Expect(false, __FILE__, __LINE__, "This should fail.");
|
||||
}, "This should fail");
|
||||
|
||||
EXPECT_NONFATAL_FAILURE({ // NOLINT
|
||||
Expect(false, __FILE__, __LINE__);
|
||||
}, "Expectation failed");
|
||||
}
|
||||
|
||||
// TODO(wan@google.com): find a way to re-enable these tests.
|
||||
#if 0
|
||||
|
||||
// Tests the Log() function.
|
||||
|
||||
// Verifies that Log() behaves correctly for the given verbosity level
|
||||
// and log severity.
|
||||
void TestLogWithSeverity(const string& verbosity, LogSeverity severity,
|
||||
bool should_print) {
|
||||
const string old_flag = GMOCK_FLAG(verbose);
|
||||
GMOCK_FLAG(verbose) = verbosity;
|
||||
CaptureTestStdout();
|
||||
Log(severity, "Test log.\n", 0);
|
||||
if (should_print) {
|
||||
EXPECT_PRED2(RE::FullMatch,
|
||||
GetCapturedTestStdout(),
|
||||
severity == WARNING ?
|
||||
"\nGMOCK WARNING:\nTest log\\.\nStack trace:\n[\\s\\S]*" :
|
||||
"\nTest log\\.\nStack trace:\n[\\s\\S]*");
|
||||
} else {
|
||||
EXPECT_EQ("", GetCapturedTestStdout());
|
||||
}
|
||||
GMOCK_FLAG(verbose) = old_flag;
|
||||
}
|
||||
|
||||
// Tests that when the stack_frames_to_skip parameter is negative,
|
||||
// Log() doesn't include the stack trace in the output.
|
||||
TEST(LogTest, NoStackTraceWhenStackFramesToSkipIsNegative) {
|
||||
GMOCK_FLAG(verbose) = kInfoVerbosity;
|
||||
CaptureTestStdout();
|
||||
Log(INFO, "Test log.\n", -1);
|
||||
EXPECT_EQ("\nTest log.\n", GetCapturedTestStdout());
|
||||
}
|
||||
|
||||
// Tests that in opt mode, a positive stack_frames_to_skip argument is
|
||||
// treated as 0.
|
||||
TEST(LogTest, NoSkippingStackFrameInOptMode) {
|
||||
CaptureTestStdout();
|
||||
Log(WARNING, "Test log.\n", 100);
|
||||
const string log = GetCapturedTestStdout();
|
||||
#ifdef NDEBUG
|
||||
// In opt mode, no stack frame should be skipped.
|
||||
EXPECT_THAT(log, ContainsRegex("\nGMOCK WARNING:\n"
|
||||
"Test log\\.\n"
|
||||
"Stack trace:\n"
|
||||
".+"));
|
||||
#else
|
||||
// In dbg mode, the stack frames should be skipped.
|
||||
EXPECT_EQ("\nGMOCK WARNING:\n"
|
||||
"Test log.\n"
|
||||
"Stack trace:\n", log);
|
||||
#endif // NDEBUG
|
||||
}
|
||||
|
||||
// Tests that all logs are printed when the value of the
|
||||
// --gmock_verbose flag is "info".
|
||||
TEST(LogTest, AllLogsArePrintedWhenVerbosityIsInfo) {
|
||||
TestLogWithSeverity(kInfoVerbosity, INFO, true);
|
||||
TestLogWithSeverity(kInfoVerbosity, WARNING, true);
|
||||
}
|
||||
|
||||
// Tests that only warnings are printed when the value of the
|
||||
// --gmock_verbose flag is "warning".
|
||||
TEST(LogTest, OnlyWarningsArePrintedWhenVerbosityIsWarning) {
|
||||
TestLogWithSeverity(kWarningVerbosity, INFO, false);
|
||||
TestLogWithSeverity(kWarningVerbosity, WARNING, true);
|
||||
}
|
||||
|
||||
// Tests that no logs are printed when the value of the
|
||||
// --gmock_verbose flag is "error".
|
||||
TEST(LogTest, NoLogsArePrintedWhenVerbosityIsError) {
|
||||
TestLogWithSeverity(kErrorVerbosity, INFO, false);
|
||||
TestLogWithSeverity(kErrorVerbosity, WARNING, false);
|
||||
}
|
||||
|
||||
// Tests that only warnings are printed when the value of the
|
||||
// --gmock_verbose flag is invalid.
|
||||
TEST(LogTest, OnlyWarningsArePrintedWhenVerbosityIsInvalid) {
|
||||
TestLogWithSeverity("invalid", INFO, false);
|
||||
TestLogWithSeverity("invalid", WARNING, true);
|
||||
}
|
||||
|
||||
#endif // 0
|
||||
|
||||
TEST(TypeTraitsTest, true_type) {
|
||||
EXPECT_TRUE(true_type::value);
|
||||
}
|
||||
|
||||
TEST(TypeTraitsTest, false_type) {
|
||||
EXPECT_FALSE(false_type::value);
|
||||
}
|
||||
|
||||
TEST(TypeTraitsTest, is_reference) {
|
||||
EXPECT_FALSE(is_reference<int>::value);
|
||||
EXPECT_FALSE(is_reference<char*>::value);
|
||||
EXPECT_TRUE(is_reference<const int&>::value);
|
||||
}
|
||||
|
||||
TEST(TypeTraitsTest, is_pointer) {
|
||||
EXPECT_FALSE(is_pointer<int>::value);
|
||||
EXPECT_FALSE(is_pointer<char&>::value);
|
||||
EXPECT_TRUE(is_pointer<const int*>::value);
|
||||
}
|
||||
|
||||
TEST(TypeTraitsTest, type_equals) {
|
||||
EXPECT_FALSE((type_equals<int, const int>::value));
|
||||
EXPECT_FALSE((type_equals<int, int&>::value));
|
||||
EXPECT_FALSE((type_equals<int, double>::value));
|
||||
EXPECT_TRUE((type_equals<char, char>::value));
|
||||
}
|
||||
|
||||
TEST(TypeTraitsTest, remove_reference) {
|
||||
EXPECT_TRUE((type_equals<char, remove_reference<char&>::type>::value));
|
||||
EXPECT_TRUE((type_equals<const int,
|
||||
remove_reference<const int&>::type>::value));
|
||||
EXPECT_TRUE((type_equals<int, remove_reference<int>::type>::value));
|
||||
EXPECT_TRUE((type_equals<double*, remove_reference<double*>::type>::value));
|
||||
}
|
||||
|
||||
// TODO(wan@google.com): find a way to re-enable these tests.
|
||||
#if 0
|
||||
|
||||
// Verifies that Log() behaves correctly for the given verbosity level
|
||||
// and log severity.
|
||||
string GrabOutput(void(*logger)(), const char* verbosity) {
|
||||
const string saved_flag = GMOCK_FLAG(verbose);
|
||||
GMOCK_FLAG(verbose) = verbosity;
|
||||
CaptureTestStdout();
|
||||
logger();
|
||||
GMOCK_FLAG(verbose) = saved_flag;
|
||||
return GetCapturedTestStdout();
|
||||
}
|
||||
|
||||
class DummyMock {
|
||||
public:
|
||||
MOCK_METHOD0(TestMethod, void());
|
||||
MOCK_METHOD1(TestMethodArg, void(int dummy));
|
||||
};
|
||||
|
||||
void ExpectCallLogger() {
|
||||
DummyMock mock;
|
||||
EXPECT_CALL(mock, TestMethod());
|
||||
mock.TestMethod();
|
||||
};
|
||||
|
||||
// Verifies that EXPECT_CALL logs if the --gmock_verbose flag is set to "info".
|
||||
TEST(ExpectCallTest, LogsWhenVerbosityIsInfo) {
|
||||
EXPECT_THAT(GrabOutput(ExpectCallLogger, kInfoVerbosity),
|
||||
HasSubstr("EXPECT_CALL(mock, TestMethod())"));
|
||||
}
|
||||
|
||||
// Verifies that EXPECT_CALL doesn't log
|
||||
// if the --gmock_verbose flag is set to "warning".
|
||||
TEST(ExpectCallTest, DoesNotLogWhenVerbosityIsWarning) {
|
||||
EXPECT_EQ("", GrabOutput(ExpectCallLogger, kWarningVerbosity));
|
||||
}
|
||||
|
||||
// Verifies that EXPECT_CALL doesn't log
|
||||
// if the --gmock_verbose flag is set to "error".
|
||||
TEST(ExpectCallTest, DoesNotLogWhenVerbosityIsError) {
|
||||
EXPECT_EQ("", GrabOutput(ExpectCallLogger, kErrorVerbosity));
|
||||
}
|
||||
|
||||
void OnCallLogger() {
|
||||
DummyMock mock;
|
||||
ON_CALL(mock, TestMethod());
|
||||
};
|
||||
|
||||
// Verifies that ON_CALL logs if the --gmock_verbose flag is set to "info".
|
||||
TEST(OnCallTest, LogsWhenVerbosityIsInfo) {
|
||||
EXPECT_THAT(GrabOutput(OnCallLogger, kInfoVerbosity),
|
||||
HasSubstr("ON_CALL(mock, TestMethod())"));
|
||||
}
|
||||
|
||||
// Verifies that ON_CALL doesn't log
|
||||
// if the --gmock_verbose flag is set to "warning".
|
||||
TEST(OnCallTest, DoesNotLogWhenVerbosityIsWarning) {
|
||||
EXPECT_EQ("", GrabOutput(OnCallLogger, kWarningVerbosity));
|
||||
}
|
||||
|
||||
// Verifies that ON_CALL doesn't log if
|
||||
// the --gmock_verbose flag is set to "error".
|
||||
TEST(OnCallTest, DoesNotLogWhenVerbosityIsError) {
|
||||
EXPECT_EQ("", GrabOutput(OnCallLogger, kErrorVerbosity));
|
||||
}
|
||||
|
||||
void OnCallAnyArgumentLogger() {
|
||||
DummyMock mock;
|
||||
ON_CALL(mock, TestMethodArg(_));
|
||||
}
|
||||
|
||||
// Verifies that ON_CALL prints provided _ argument.
|
||||
TEST(OnCallTest, LogsAnythingArgument) {
|
||||
EXPECT_THAT(GrabOutput(OnCallAnyArgumentLogger, kInfoVerbosity),
|
||||
HasSubstr("ON_CALL(mock, TestMethodArg(_)"));
|
||||
}
|
||||
|
||||
#endif // 0
|
||||
|
||||
} // namespace
|
||||
} // namespace internal
|
||||
} // namespace testing
|
||||
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
@@ -0,0 +1,228 @@
|
||||
// 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.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
|
||||
#include <gmock/gmock-generated-nice-strict.h>
|
||||
|
||||
#include <string>
|
||||
#include <gmock/gmock.h>
|
||||
#include <gtest/gtest.h>
|
||||
#include <gtest/gtest-spi.h>
|
||||
|
||||
namespace testing {
|
||||
namespace gmock_nice_strict_test {
|
||||
|
||||
using testing::internal::string;
|
||||
using testing::GMOCK_FLAG(verbose);
|
||||
using testing::HasSubstr;
|
||||
using testing::NiceMock;
|
||||
using testing::StrictMock;
|
||||
|
||||
// Defines some mock classes needed by the tests.
|
||||
|
||||
class Foo {
|
||||
public:
|
||||
virtual ~Foo() {}
|
||||
|
||||
virtual void DoThis() = 0;
|
||||
virtual int DoThat(bool flag) = 0;
|
||||
};
|
||||
|
||||
class MockFoo : public Foo {
|
||||
public:
|
||||
void Delete() { delete this; }
|
||||
|
||||
MOCK_METHOD0(DoThis, void());
|
||||
MOCK_METHOD1(DoThat, int(bool flag));
|
||||
};
|
||||
|
||||
class MockBar {
|
||||
public:
|
||||
explicit MockBar(const string& s) : str_(s) {}
|
||||
|
||||
MockBar(char a1, char a2, string a3, string a4, int a5, int a6,
|
||||
const string& a7, const string& a8, bool a9, bool a10) {
|
||||
str_ = string() + a1 + a2 + a3 + a4 + static_cast<char>(a5) +
|
||||
static_cast<char>(a6) + a7 + a8 + (a9 ? 'T' : 'F') + (a10 ? 'T' : 'F');
|
||||
}
|
||||
|
||||
virtual ~MockBar() {}
|
||||
|
||||
const string& str() const { return str_; }
|
||||
|
||||
MOCK_METHOD0(This, int());
|
||||
MOCK_METHOD2(That, string(int, bool));
|
||||
|
||||
private:
|
||||
string str_;
|
||||
};
|
||||
|
||||
// TODO(wan@google.com): find a way to re-enable these tests.
|
||||
#if 0
|
||||
|
||||
// Tests that a nice mock generates no warning for uninteresting calls.
|
||||
TEST(NiceMockTest, NoWarningForUninterestingCall) {
|
||||
NiceMock<MockFoo> nice_foo;
|
||||
|
||||
CaptureTestStdout();
|
||||
nice_foo.DoThis();
|
||||
nice_foo.DoThat(true);
|
||||
EXPECT_EQ("", GetCapturedTestStdout());
|
||||
}
|
||||
|
||||
// Tests that a nice mock generates no warning for uninteresting calls
|
||||
// that delete the mock object.
|
||||
TEST(NiceMockTest, NoWarningForUninterestingCallAfterDeath) {
|
||||
NiceMock<MockFoo>* const nice_foo = new NiceMock<MockFoo>;
|
||||
|
||||
ON_CALL(*nice_foo, DoThis())
|
||||
.WillByDefault(Invoke(nice_foo, &MockFoo::Delete));
|
||||
|
||||
CaptureTestStdout();
|
||||
nice_foo->DoThis();
|
||||
EXPECT_EQ("", GetCapturedTestStdout());
|
||||
}
|
||||
|
||||
// Tests that a nice mock generates informational logs for
|
||||
// uninteresting calls.
|
||||
TEST(NiceMockTest, InfoForUninterestingCall) {
|
||||
NiceMock<MockFoo> nice_foo;
|
||||
|
||||
GMOCK_FLAG(verbose) = "info";
|
||||
CaptureTestStdout();
|
||||
nice_foo.DoThis();
|
||||
EXPECT_THAT(GetCapturedTestStdout(),
|
||||
HasSubstr("Uninteresting mock function call"));
|
||||
|
||||
CaptureTestStdout();
|
||||
nice_foo.DoThat(true);
|
||||
EXPECT_THAT(GetCapturedTestStdout(),
|
||||
HasSubstr("Uninteresting mock function call"));
|
||||
}
|
||||
|
||||
#endif // 0
|
||||
|
||||
// Tests that a nice mock allows expected calls.
|
||||
TEST(NiceMockTest, AllowsExpectedCall) {
|
||||
NiceMock<MockFoo> nice_foo;
|
||||
|
||||
EXPECT_CALL(nice_foo, DoThis());
|
||||
nice_foo.DoThis();
|
||||
}
|
||||
|
||||
// Tests that an unexpected call on a nice mock fails.
|
||||
TEST(NiceMockTest, UnexpectedCallFails) {
|
||||
NiceMock<MockFoo> nice_foo;
|
||||
|
||||
EXPECT_CALL(nice_foo, DoThis()).Times(0);
|
||||
EXPECT_NONFATAL_FAILURE(nice_foo.DoThis(), "called more times than expected");
|
||||
}
|
||||
|
||||
// Tests that NiceMock works with a mock class that has a non-default
|
||||
// constructor.
|
||||
TEST(NiceMockTest, NonDefaultConstructor) {
|
||||
NiceMock<MockBar> nice_bar("hi");
|
||||
EXPECT_EQ("hi", nice_bar.str());
|
||||
|
||||
nice_bar.This();
|
||||
nice_bar.That(5, true);
|
||||
}
|
||||
|
||||
// Tests that NiceMock works with a mock class that has a 10-ary
|
||||
// non-default constructor.
|
||||
TEST(NiceMockTest, NonDefaultConstructor10) {
|
||||
NiceMock<MockBar> nice_bar('a', 'b', "c", "d", 'e', 'f',
|
||||
"g", "h", true, false);
|
||||
EXPECT_EQ("abcdefghTF", nice_bar.str());
|
||||
|
||||
nice_bar.This();
|
||||
nice_bar.That(5, true);
|
||||
}
|
||||
|
||||
// Tests that a strict mock allows expected calls.
|
||||
TEST(StrictMockTest, AllowsExpectedCall) {
|
||||
StrictMock<MockFoo> strict_foo;
|
||||
|
||||
EXPECT_CALL(strict_foo, DoThis());
|
||||
strict_foo.DoThis();
|
||||
}
|
||||
|
||||
// Tests that an unexpected call on a strict mock fails.
|
||||
TEST(StrictMockTest, UnexpectedCallFails) {
|
||||
StrictMock<MockFoo> strict_foo;
|
||||
|
||||
EXPECT_CALL(strict_foo, DoThis()).Times(0);
|
||||
EXPECT_NONFATAL_FAILURE(strict_foo.DoThis(),
|
||||
"called more times than expected");
|
||||
}
|
||||
|
||||
// Tests that an uninteresting call on a strict mock fails.
|
||||
TEST(StrictMockTest, UninterestingCallFails) {
|
||||
StrictMock<MockFoo> strict_foo;
|
||||
|
||||
EXPECT_NONFATAL_FAILURE(strict_foo.DoThis(),
|
||||
"Uninteresting mock function call");
|
||||
}
|
||||
|
||||
// Tests that an uninteresting call on a strict mock fails, even if
|
||||
// the call deletes the mock object.
|
||||
TEST(StrictMockTest, UninterestingCallFailsAfterDeath) {
|
||||
StrictMock<MockFoo>* const strict_foo = new StrictMock<MockFoo>;
|
||||
|
||||
ON_CALL(*strict_foo, DoThis())
|
||||
.WillByDefault(Invoke(strict_foo, &MockFoo::Delete));
|
||||
|
||||
EXPECT_NONFATAL_FAILURE(strict_foo->DoThis(),
|
||||
"Uninteresting mock function call");
|
||||
}
|
||||
|
||||
// Tests that StrictMock works with a mock class that has a
|
||||
// non-default constructor.
|
||||
TEST(StrictMockTest, NonDefaultConstructor) {
|
||||
StrictMock<MockBar> strict_bar("hi");
|
||||
EXPECT_EQ("hi", strict_bar.str());
|
||||
|
||||
EXPECT_NONFATAL_FAILURE(strict_bar.That(5, true),
|
||||
"Uninteresting mock function call");
|
||||
}
|
||||
|
||||
// Tests that StrictMock works with a mock class that has a 10-ary
|
||||
// non-default constructor.
|
||||
TEST(StrictMockTest, NonDefaultConstructor10) {
|
||||
StrictMock<MockBar> strict_bar('a', 'b', "c", "d", 'e', 'f',
|
||||
"g", "h", true, false);
|
||||
EXPECT_EQ("abcdefghTF", strict_bar.str());
|
||||
|
||||
EXPECT_NONFATAL_FAILURE(strict_bar.That(5, true),
|
||||
"Uninteresting mock function call");
|
||||
}
|
||||
|
||||
} // namespace gmock_nice_strict_test
|
||||
} // namespace testing
|
||||
@@ -0,0 +1,95 @@
|
||||
// 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.
|
||||
//
|
||||
// Author: vladl@google.com (Vlad Losev)
|
||||
|
||||
// Google Mock - a framework for writing C++ mock classes.
|
||||
//
|
||||
// This file tests the internal cross-platform support utilities.
|
||||
|
||||
#include <gmock/internal/gmock-port.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
TEST(GmockCheckSyntaxTest, BehavesLikeASingleStatement) {
|
||||
if (false)
|
||||
GMOCK_CHECK_(false) << "This should never be executed; "
|
||||
"It's a compilation test only.";
|
||||
|
||||
if (true)
|
||||
GMOCK_CHECK_(true);
|
||||
else
|
||||
;
|
||||
|
||||
if (false)
|
||||
;
|
||||
else
|
||||
GMOCK_CHECK_(true) << "";
|
||||
}
|
||||
|
||||
TEST(GmockCheckSyntaxTest, WorksWithSwitch) {
|
||||
switch (0) {
|
||||
case 1:
|
||||
break;
|
||||
default:
|
||||
GMOCK_CHECK_(true);
|
||||
}
|
||||
|
||||
switch(0)
|
||||
case 0:
|
||||
GMOCK_CHECK_(true) << "Check failed in switch case";
|
||||
}
|
||||
|
||||
#if GTEST_HAS_DEATH_TEST
|
||||
|
||||
TEST(GmockCheckDeathTest, DiesWithCorrectOutputOnFailure) {
|
||||
const bool a_false_condition = false;
|
||||
// MSVC and gcc use different formats to print source file locations.
|
||||
// Google Mock's failure messages use the same format as used by the
|
||||
// compiler, in order for the IDE to recognize them. Therefore we look
|
||||
// for different patterns here depending on the compiler.
|
||||
const char regex[] =
|
||||
#ifdef _MSC_VER
|
||||
"gmock-port_test\\.cc\\(\\d+\\):"
|
||||
#else
|
||||
"gmock-port_test\\.cc:[0-9]+"
|
||||
#endif // _MSC_VER
|
||||
".*a_false_condition.*Extra info";
|
||||
|
||||
EXPECT_DEATH(GMOCK_CHECK_(a_false_condition) << "Extra info", regex);
|
||||
}
|
||||
|
||||
TEST(GmockCheckDeathTest, LivesSilentlyOnSuccess) {
|
||||
EXPECT_EXIT({
|
||||
GMOCK_CHECK_(true) << "Extra info";
|
||||
::std::cerr << "Success\n";
|
||||
exit(0); },
|
||||
::testing::ExitedWithCode(0), "Success");
|
||||
}
|
||||
|
||||
#endif // GTEST_HAS_DEATH_TEST
|
||||
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
Arquivo executável
+84
@@ -0,0 +1,84 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright 2009, 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.
|
||||
|
||||
"""Tests that leaked mock objects can be caught be Google Mock."""
|
||||
|
||||
__author__ = 'wan@google.com (Zhanyong Wan)'
|
||||
|
||||
import gmock_test_utils
|
||||
import os
|
||||
import unittest
|
||||
|
||||
IS_WINDOWS = os.name == 'nt'
|
||||
|
||||
if IS_WINDOWS:
|
||||
# TODO(wan@google.com): test the opt build too. We should do it
|
||||
# when Vlad Losev's work on Google Test's Python test driver is
|
||||
# done, such that we can reuse the work.
|
||||
PROGRAM = r'..\build.dbg\gmock_leak_test_.exe'
|
||||
else:
|
||||
PROGRAM = 'gmock_leak_test_'
|
||||
|
||||
PROGRAM_PATH = os.path.join(gmock_test_utils.GetBuildDir(), PROGRAM)
|
||||
TEST_WITH_EXPECT_CALL = PROGRAM_PATH + ' --gtest_filter=*ExpectCall*'
|
||||
TEST_WITH_ON_CALL = PROGRAM_PATH + ' --gtest_filter=*OnCall*'
|
||||
TEST_MULTIPLE_LEAKS = PROGRAM_PATH + ' --gtest_filter=*MultipleLeaked*'
|
||||
|
||||
|
||||
class GMockLeakTest(unittest.TestCase):
|
||||
|
||||
def testCatchesLeakedMockByDefault(self):
|
||||
self.assertNotEqual(os.system(TEST_WITH_EXPECT_CALL), 0)
|
||||
self.assertNotEqual(os.system(TEST_WITH_ON_CALL), 0)
|
||||
|
||||
def testDoesNotCatchLeakedMockWhenDisabled(self):
|
||||
self.assertEquals(
|
||||
0, os.system(TEST_WITH_EXPECT_CALL + ' --gmock_catch_leaked_mocks=0'))
|
||||
self.assertEquals(
|
||||
0, os.system(TEST_WITH_ON_CALL + ' --gmock_catch_leaked_mocks=0'))
|
||||
|
||||
def testCatchesLeakedMockWhenEnabled(self):
|
||||
self.assertNotEqual(
|
||||
os.system(TEST_WITH_EXPECT_CALL + ' --gmock_catch_leaked_mocks'), 0)
|
||||
self.assertNotEqual(
|
||||
os.system(TEST_WITH_ON_CALL + ' --gmock_catch_leaked_mocks'), 0)
|
||||
|
||||
def testCatchesLeakedMockWhenEnabledWithExplictFlagValue(self):
|
||||
self.assertNotEqual(
|
||||
os.system(TEST_WITH_EXPECT_CALL + ' --gmock_catch_leaked_mocks=1'), 0)
|
||||
|
||||
def testCatchesMultipleLeakedMocks(self):
|
||||
self.assertNotEqual(
|
||||
os.system(TEST_MULTIPLE_LEAKS + ' --gmock_catch_leaked_mocks'), 0)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
gmock_test_utils.Main()
|
||||
@@ -0,0 +1,95 @@
|
||||
// Copyright 2009, 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)
|
||||
|
||||
// Google Mock - a framework for writing C++ mock classes.
|
||||
//
|
||||
// This program is for verifying that a leaked mock object can be
|
||||
// caught by Google Mock's leak detector.
|
||||
|
||||
#include <gmock/gmock.h>
|
||||
|
||||
namespace {
|
||||
|
||||
using ::testing::Return;
|
||||
|
||||
class FooInterface {
|
||||
public:
|
||||
virtual ~FooInterface() {}
|
||||
virtual void DoThis() = 0;
|
||||
};
|
||||
|
||||
class MockFoo : public FooInterface {
|
||||
public:
|
||||
MOCK_METHOD0(DoThis, void());
|
||||
};
|
||||
|
||||
TEST(LeakTest, LeakedMockWithExpectCallCausesFailureWhenLeakCheckingIsEnabled) {
|
||||
MockFoo* foo = new MockFoo;
|
||||
|
||||
EXPECT_CALL(*foo, DoThis());
|
||||
foo->DoThis();
|
||||
|
||||
// In order to test the leak detector, we deliberately leak foo.
|
||||
|
||||
// Makes sure Google Mock's leak detector can change the exit code
|
||||
// to 1 even when the code is already exiting with 0.
|
||||
exit(0);
|
||||
}
|
||||
|
||||
TEST(LeakTest, LeakedMockWithOnCallCausesFailureWhenLeakCheckingIsEnabled) {
|
||||
MockFoo* foo = new MockFoo;
|
||||
|
||||
ON_CALL(*foo, DoThis()).WillByDefault(Return());
|
||||
|
||||
// In order to test the leak detector, we deliberately leak foo.
|
||||
|
||||
// Makes sure Google Mock's leak detector can change the exit code
|
||||
// to 1 even when the code is already exiting with 0.
|
||||
exit(0);
|
||||
}
|
||||
|
||||
TEST(LeakTest, CatchesMultipleLeakedMockObjects) {
|
||||
MockFoo* foo1 = new MockFoo;
|
||||
MockFoo* foo2 = new MockFoo;
|
||||
|
||||
ON_CALL(*foo1, DoThis()).WillByDefault(Return());
|
||||
EXPECT_CALL(*foo2, DoThis());
|
||||
foo2->DoThis();
|
||||
|
||||
// In order to test the leak detector, we deliberately leak foo1 and
|
||||
// foo2.
|
||||
|
||||
// Makes sure Google Mock's leak detector can change the exit code
|
||||
// to 1 even when the code is already exiting with 0.
|
||||
exit(0);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
@@ -0,0 +1,40 @@
|
||||
// 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.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan), vladl@google.com (Vlad Losev)
|
||||
|
||||
// Google Mock - a framework for writing C++ mock classes.
|
||||
//
|
||||
// This file is for verifying that various Google Mock constructs do not
|
||||
// produce linker errors when instantiated in different translation units.
|
||||
// Please see gmock_link_test.h for details.
|
||||
|
||||
#define LinkTest LinkTest2
|
||||
|
||||
#include "test/gmock_link_test.h"
|
||||
@@ -0,0 +1,40 @@
|
||||
// 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.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan), vladl@google.com (Vlad Losev)
|
||||
|
||||
// Google Mock - a framework for writing C++ mock classes.
|
||||
//
|
||||
// This file is for verifying that various Google Mock constructs do not
|
||||
// produce linker errors when instantiated in different translation units.
|
||||
// Please see gmock_link_test.h for details.
|
||||
|
||||
#define LinkTest LinkTest1
|
||||
|
||||
#include "test/gmock_link_test.h"
|
||||
@@ -0,0 +1,645 @@
|
||||
// Copyright 2009, 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)
|
||||
|
||||
// Google Mock - a framework for writing C++ mock classes.
|
||||
//
|
||||
// This file tests that:
|
||||
// a. A header file defining a mock class can be included in multiple
|
||||
// translation units without causing a link error.
|
||||
// b. Actions and matchers can be instantiated with identical template
|
||||
// arguments in different translation units without causing link
|
||||
// errors.
|
||||
// The following constructs are currently tested:
|
||||
// Actions:
|
||||
// Return()
|
||||
// Return(value)
|
||||
// ReturnNull
|
||||
// ReturnRef
|
||||
// Assign
|
||||
// SetArgumentPointee
|
||||
// SetArrayArgument
|
||||
// SetErrnoAndReturn
|
||||
// Invoke(function)
|
||||
// Invoke(object, method)
|
||||
// InvokeWithoutArgs(function)
|
||||
// InvokeWithoutArgs(object, method)
|
||||
// InvokeArgument
|
||||
// WithArg
|
||||
// WithArgs
|
||||
// WithoutArgs
|
||||
// DoAll
|
||||
// DoDefault
|
||||
// IgnoreResult
|
||||
// Throw
|
||||
// ACTION()-generated
|
||||
// ACTION_P()-generated
|
||||
// ACTION_P2()-generated
|
||||
// Matchers:
|
||||
// _
|
||||
// A
|
||||
// An
|
||||
// Eq
|
||||
// Gt, Lt, Ge, Le, Ne
|
||||
// NotNull
|
||||
// Ref
|
||||
// TypedEq
|
||||
// DoubleEq
|
||||
// FloatEq
|
||||
// NanSensitiveDoubleEq
|
||||
// NanSensitiveFloatEq
|
||||
// ContainsRegex
|
||||
// MatchesRegex
|
||||
// EndsWith
|
||||
// HasSubstr
|
||||
// StartsWith
|
||||
// StrCaseEq
|
||||
// StrCaseNe
|
||||
// StrEq
|
||||
// StrNe
|
||||
// ElementsAre
|
||||
// ElementsAreArray
|
||||
// ContainerEq
|
||||
// Field
|
||||
// Property
|
||||
// ResultOf(function)
|
||||
// Pointee
|
||||
// Truly(predicate)
|
||||
// AllOf
|
||||
// AnyOf
|
||||
// Not
|
||||
// MatcherCast<T>
|
||||
//
|
||||
// Please note: this test does not verify the functioning of these
|
||||
// constructs, only that the programs using them will link successfully.
|
||||
//
|
||||
// Implementation note:
|
||||
// This test requires identical definitions of Interface and Mock to be
|
||||
// included in different translation units. We achieve this by writing
|
||||
// them in this header and #including it in gmock_link_test.cc and
|
||||
// gmock_link2_test.cc. Because the symbols generated by the compiler for
|
||||
// those constructs must be identical in both translation units,
|
||||
// definitions of Interface and Mock tests MUST be kept in the SAME
|
||||
// NON-ANONYMOUS namespace in this file. The test fixture class LinkTest
|
||||
// is defined as LinkTest1 in gmock_link_test.cc and as LinkTest2 in
|
||||
// gmock_link2_test.cc to avoid producing linker errors.
|
||||
|
||||
#ifndef GMOCK_TEST_GMOCK_LINK_TEST_H_
|
||||
#define GMOCK_TEST_GMOCK_LINK_TEST_H_
|
||||
|
||||
#include <gmock/gmock.h>
|
||||
|
||||
#ifndef _WIN32_WCE
|
||||
#include <errno.h>
|
||||
#endif
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
using testing::_;
|
||||
using testing::A;
|
||||
using testing::AllOf;
|
||||
using testing::AnyOf;
|
||||
using testing::Assign;
|
||||
using testing::ContainerEq;
|
||||
using testing::DoAll;
|
||||
using testing::DoDefault;
|
||||
using testing::DoubleEq;
|
||||
using testing::ElementsAre;
|
||||
using testing::ElementsAreArray;
|
||||
using testing::EndsWith;
|
||||
using testing::Eq;
|
||||
using testing::Field;
|
||||
using testing::FloatEq;
|
||||
using testing::Ge;
|
||||
using testing::Gt;
|
||||
using testing::HasSubstr;
|
||||
using testing::IgnoreResult;
|
||||
using testing::Invoke;
|
||||
using testing::InvokeArgument;
|
||||
using testing::InvokeWithoutArgs;
|
||||
using testing::Le;
|
||||
using testing::Lt;
|
||||
using testing::Matcher;
|
||||
using testing::MatcherCast;
|
||||
using testing::NanSensitiveDoubleEq;
|
||||
using testing::NanSensitiveFloatEq;
|
||||
using testing::Ne;
|
||||
using testing::Not;
|
||||
using testing::NotNull;
|
||||
using testing::Pointee;
|
||||
using testing::Property;
|
||||
using testing::Ref;
|
||||
using testing::ResultOf;
|
||||
using testing::Return;
|
||||
using testing::ReturnNull;
|
||||
using testing::ReturnRef;
|
||||
using testing::SetArgumentPointee;
|
||||
using testing::SetArrayArgument;
|
||||
using testing::StartsWith;
|
||||
using testing::StrCaseEq;
|
||||
using testing::StrCaseNe;
|
||||
using testing::StrEq;
|
||||
using testing::StrNe;
|
||||
using testing::Truly;
|
||||
using testing::TypedEq;
|
||||
using testing::WithArg;
|
||||
using testing::WithArgs;
|
||||
using testing::WithoutArgs;
|
||||
|
||||
#ifndef _WIN32_WCE
|
||||
using testing::SetErrnoAndReturn;
|
||||
#endif // _WIN32_WCE
|
||||
|
||||
#if GTEST_HAS_EXCEPTIONS
|
||||
using testing::Throw;
|
||||
#endif // GTEST_HAS_EXCEPTIONS
|
||||
|
||||
#if GMOCK_HAS_REGEX
|
||||
using testing::ContainsRegex;
|
||||
using testing::MatchesRegex;
|
||||
#endif // GMOCK_HAS_REGEX
|
||||
|
||||
class Interface {
|
||||
public:
|
||||
virtual ~Interface() {}
|
||||
virtual void VoidFromString(char* str) = 0;
|
||||
virtual char* StringFromString(char* str) = 0;
|
||||
virtual int IntFromString(char* str) = 0;
|
||||
virtual int& IntRefFromString(char* str) = 0;
|
||||
virtual void VoidFromFunc(void(*)(char*)) = 0;
|
||||
virtual void VoidFromIntRef(int& n) = 0;
|
||||
virtual void VoidFromFloat(float n) = 0;
|
||||
virtual void VoidFromDouble(double n) = 0;
|
||||
virtual void VoidFromVector(const std::vector<int>& v) = 0;
|
||||
};
|
||||
|
||||
class Mock: public Interface {
|
||||
public:
|
||||
MOCK_METHOD1(VoidFromString, void(char* str));
|
||||
MOCK_METHOD1(StringFromString, char*(char* str));
|
||||
MOCK_METHOD1(IntFromString, int(char* str));
|
||||
MOCK_METHOD1(IntRefFromString, int&(char* str));
|
||||
MOCK_METHOD1(VoidFromFunc, void(void(*func)(char* str)));
|
||||
MOCK_METHOD1(VoidFromIntRef, void(int& n));
|
||||
MOCK_METHOD1(VoidFromFloat, void(float n));
|
||||
MOCK_METHOD1(VoidFromDouble, void(double n));
|
||||
MOCK_METHOD1(VoidFromVector, void(const std::vector<int>& v));
|
||||
};
|
||||
|
||||
class InvokeHelper {
|
||||
public:
|
||||
static void StaticVoidFromVoid() {}
|
||||
void VoidFromVoid() {}
|
||||
static void StaticVoidFromString(char*) {}
|
||||
void VoidFromString(char*) {}
|
||||
static int StaticIntFromString(char*) { return 1; }
|
||||
static bool StaticBoolFromString(const char*) { return true; }
|
||||
};
|
||||
|
||||
class FieldHelper {
|
||||
public:
|
||||
FieldHelper(int field) : field_(field) {}
|
||||
int field() const { return field_; }
|
||||
int field_; // NOLINT -- need external access to field_ to test
|
||||
// the Field matcher.
|
||||
};
|
||||
|
||||
// Tests the linkage of the ReturnVoid action.
|
||||
TEST(LinkTest, TestReturnVoid) {
|
||||
Mock mock;
|
||||
|
||||
EXPECT_CALL(mock, VoidFromString(_)).WillOnce(Return());
|
||||
mock.VoidFromString(NULL);
|
||||
}
|
||||
|
||||
// Tests the linkage of the Return action.
|
||||
TEST(LinkTest, TestReturn) {
|
||||
Mock mock;
|
||||
char ch = 'x';
|
||||
|
||||
EXPECT_CALL(mock, StringFromString(_)).WillOnce(Return(&ch));
|
||||
mock.StringFromString(NULL);
|
||||
}
|
||||
|
||||
// Tests the linkage of the ReturnNull action.
|
||||
TEST(LinkTest, TestReturnNull) {
|
||||
Mock mock;
|
||||
|
||||
EXPECT_CALL(mock, VoidFromString(_)).WillOnce(Return());
|
||||
mock.VoidFromString(NULL);
|
||||
}
|
||||
|
||||
// Tests the linkage of the ReturnRef action.
|
||||
TEST(LinkTest, TestReturnRef) {
|
||||
Mock mock;
|
||||
int n = 42;
|
||||
|
||||
EXPECT_CALL(mock, IntRefFromString(_)).WillOnce(ReturnRef(n));
|
||||
mock.IntRefFromString(NULL);
|
||||
}
|
||||
|
||||
// Tests the linkage of the Assign action.
|
||||
TEST(LinkTest, TestAssign) {
|
||||
Mock mock;
|
||||
char ch = 'x';
|
||||
|
||||
EXPECT_CALL(mock, VoidFromString(_)).WillOnce(Assign(&ch, 'y'));
|
||||
mock.VoidFromString(NULL);
|
||||
}
|
||||
|
||||
// Tests the linkage of the SetArgumentPointee action.
|
||||
TEST(LinkTest, TestSetArgumentPointee) {
|
||||
Mock mock;
|
||||
char ch = 'x';
|
||||
|
||||
EXPECT_CALL(mock, VoidFromString(_)).WillOnce(SetArgumentPointee<0>('y'));
|
||||
mock.VoidFromString(&ch);
|
||||
}
|
||||
|
||||
// Tests the linkage of the SetArrayArgument action.
|
||||
TEST(LinkTest, TestSetArrayArgument) {
|
||||
Mock mock;
|
||||
char ch = 'x';
|
||||
char ch2 = 'y';
|
||||
|
||||
EXPECT_CALL(mock, VoidFromString(_)).WillOnce(SetArrayArgument<0>(&ch2,
|
||||
&ch2 + 1));
|
||||
mock.VoidFromString(&ch);
|
||||
}
|
||||
|
||||
#ifndef _WIN32_WCE
|
||||
|
||||
// Tests the linkage of the SetErrnoAndReturn action.
|
||||
TEST(LinkTest, TestSetErrnoAndReturn) {
|
||||
Mock mock;
|
||||
|
||||
int saved_errno = errno;
|
||||
EXPECT_CALL(mock, IntFromString(_)).WillOnce(SetErrnoAndReturn(1, -1));
|
||||
mock.IntFromString(NULL);
|
||||
errno = saved_errno;
|
||||
}
|
||||
|
||||
#endif // _WIN32_WCE
|
||||
|
||||
// Tests the linkage of the Invoke(function) and Invoke(object, method) actions.
|
||||
TEST(LinkTest, TestInvoke) {
|
||||
Mock mock;
|
||||
InvokeHelper test_invoke_helper;
|
||||
|
||||
EXPECT_CALL(mock, VoidFromString(_))
|
||||
.WillOnce(Invoke(&InvokeHelper::StaticVoidFromString))
|
||||
.WillOnce(Invoke(&test_invoke_helper, &InvokeHelper::VoidFromString));
|
||||
mock.VoidFromString(NULL);
|
||||
mock.VoidFromString(NULL);
|
||||
}
|
||||
|
||||
// Tests the linkage of the InvokeWithoutArgs action.
|
||||
TEST(LinkTest, TestInvokeWithoutArgs) {
|
||||
Mock mock;
|
||||
InvokeHelper test_invoke_helper;
|
||||
|
||||
EXPECT_CALL(mock, VoidFromString(_))
|
||||
.WillOnce(InvokeWithoutArgs(&InvokeHelper::StaticVoidFromVoid))
|
||||
.WillOnce(InvokeWithoutArgs(&test_invoke_helper,
|
||||
&InvokeHelper::VoidFromVoid));
|
||||
mock.VoidFromString(NULL);
|
||||
mock.VoidFromString(NULL);
|
||||
}
|
||||
|
||||
// Tests the linkage of the InvokeArgument action.
|
||||
TEST(LinkTest, TestInvokeArgument) {
|
||||
Mock mock;
|
||||
char ch = 'x';
|
||||
|
||||
EXPECT_CALL(mock, VoidFromFunc(_)).WillOnce(InvokeArgument<0>(&ch));
|
||||
mock.VoidFromFunc(InvokeHelper::StaticVoidFromString);
|
||||
}
|
||||
|
||||
// Tests the linkage of the WithArg action.
|
||||
TEST(LinkTest, TestWithArg) {
|
||||
Mock mock;
|
||||
|
||||
EXPECT_CALL(mock, VoidFromString(_))
|
||||
.WillOnce(WithArg<0>(Invoke(&InvokeHelper::StaticVoidFromString)));
|
||||
mock.VoidFromString(NULL);
|
||||
}
|
||||
|
||||
// Tests the linkage of the WithArgs action.
|
||||
TEST(LinkTest, TestWithArgs) {
|
||||
Mock mock;
|
||||
|
||||
EXPECT_CALL(mock, VoidFromString(_))
|
||||
.WillOnce(WithArgs<0>(Invoke(&InvokeHelper::StaticVoidFromString)));
|
||||
mock.VoidFromString(NULL);
|
||||
}
|
||||
|
||||
// Tests the linkage of the WithoutArgs action.
|
||||
TEST(LinkTest, TestWithoutArgs) {
|
||||
Mock mock;
|
||||
|
||||
EXPECT_CALL(mock, VoidFromString(_)).WillOnce(WithoutArgs(Return()));
|
||||
mock.VoidFromString(NULL);
|
||||
}
|
||||
|
||||
// Tests the linkage of the DoAll action.
|
||||
TEST(LinkTest, TestDoAll) {
|
||||
Mock mock;
|
||||
char ch = 'x';
|
||||
|
||||
EXPECT_CALL(mock, VoidFromString(_))
|
||||
.WillOnce(DoAll(SetArgumentPointee<0>('y'), Return()));
|
||||
mock.VoidFromString(&ch);
|
||||
}
|
||||
|
||||
// Tests the linkage of the DoDefault action.
|
||||
TEST(LinkTest, TestDoDefault) {
|
||||
Mock mock;
|
||||
char ch = 'x';
|
||||
|
||||
ON_CALL(mock, VoidFromString(_)).WillByDefault(Return());
|
||||
EXPECT_CALL(mock, VoidFromString(_)).WillOnce(DoDefault());
|
||||
mock.VoidFromString(&ch);
|
||||
}
|
||||
|
||||
// Tests the linkage of the IgnoreResult action.
|
||||
TEST(LinkTest, TestIgnoreResult) {
|
||||
Mock mock;
|
||||
|
||||
EXPECT_CALL(mock, VoidFromString(_)).WillOnce(IgnoreResult(Return(42)));
|
||||
mock.VoidFromString(NULL);
|
||||
}
|
||||
|
||||
#if GTEST_HAS_EXCEPTIONS
|
||||
// Tests the linkage of the Throw action.
|
||||
TEST(LinkTest, TestThrow) {
|
||||
Mock mock;
|
||||
|
||||
EXPECT_CALL(mock, VoidFromString(_)).WillOnce(Throw(42));
|
||||
EXPECT_THROW(mock.VoidFromString(NULL), int);
|
||||
}
|
||||
#endif // GTEST_HAS_EXCEPTIONS
|
||||
|
||||
// Tests the linkage of actions created using ACTION macro.
|
||||
namespace {
|
||||
ACTION(Return1) { return 1; }
|
||||
}
|
||||
|
||||
TEST(LinkTest, TestActionMacro) {
|
||||
Mock mock;
|
||||
|
||||
EXPECT_CALL(mock, IntFromString(_)).WillOnce(Return1());
|
||||
mock.IntFromString(NULL);
|
||||
}
|
||||
|
||||
// Tests the linkage of actions created using ACTION_P macro.
|
||||
namespace {
|
||||
ACTION_P(ReturnArgument, ret_value) { return ret_value; }
|
||||
}
|
||||
|
||||
TEST(LinkTest, TestActionPMacro) {
|
||||
Mock mock;
|
||||
|
||||
EXPECT_CALL(mock, IntFromString(_)).WillOnce(ReturnArgument(42));
|
||||
mock.IntFromString(NULL);
|
||||
}
|
||||
|
||||
// Tests the linkage of actions created using ACTION_P2 macro.
|
||||
namespace {
|
||||
ACTION_P2(ReturnEqualsEitherOf, first, second) {
|
||||
return arg0 == first || arg0 == second;
|
||||
}
|
||||
}
|
||||
|
||||
TEST(LinkTest, TestActionP2Macro) {
|
||||
Mock mock;
|
||||
char ch = 'x';
|
||||
|
||||
EXPECT_CALL(mock, IntFromString(_))
|
||||
.WillOnce(ReturnEqualsEitherOf("one", "two"));
|
||||
mock.IntFromString(&ch);
|
||||
}
|
||||
|
||||
// Tests the linkage of the "_" matcher.
|
||||
TEST(LinkTest, TestMatcherAnything) {
|
||||
Mock mock;
|
||||
|
||||
ON_CALL(mock, VoidFromString(_)).WillByDefault(Return());
|
||||
}
|
||||
|
||||
// Tests the linkage of the A matcher.
|
||||
TEST(LinkTest, TestMatcherA) {
|
||||
Mock mock;
|
||||
|
||||
ON_CALL(mock, VoidFromString(A<char*>())).WillByDefault(Return());
|
||||
}
|
||||
|
||||
// Tests the linkage of the Eq and the "bare value" matcher.
|
||||
TEST(LinkTest, TestMatchersEq) {
|
||||
Mock mock;
|
||||
const char* p = "x";
|
||||
|
||||
ON_CALL(mock, VoidFromString(Eq(p))).WillByDefault(Return());
|
||||
ON_CALL(mock, VoidFromString(const_cast<char*>("y")))
|
||||
.WillByDefault(Return());
|
||||
}
|
||||
|
||||
// Tests the linkage of the Lt, Gt, Le, Ge, and Ne matchers.
|
||||
TEST(LinkTest, TestMatchersRelations) {
|
||||
Mock mock;
|
||||
|
||||
ON_CALL(mock, VoidFromFloat(Lt(1.0f))).WillByDefault(Return());
|
||||
ON_CALL(mock, VoidFromFloat(Gt(1.0f))).WillByDefault(Return());
|
||||
ON_CALL(mock, VoidFromFloat(Le(1.0f))).WillByDefault(Return());
|
||||
ON_CALL(mock, VoidFromFloat(Ge(1.0f))).WillByDefault(Return());
|
||||
ON_CALL(mock, VoidFromFloat(Ne(1.0f))).WillByDefault(Return());
|
||||
}
|
||||
|
||||
// Tests the linkage of the NotNull matcher.
|
||||
TEST(LinkTest, TestMatcherNotNull) {
|
||||
Mock mock;
|
||||
|
||||
ON_CALL(mock, VoidFromString(NotNull())).WillByDefault(Return());
|
||||
}
|
||||
|
||||
// Tests the linkage of the Ref matcher.
|
||||
TEST(LinkTest, TestMatcherRef) {
|
||||
Mock mock;
|
||||
int a = 0;
|
||||
|
||||
ON_CALL(mock, VoidFromIntRef(Ref(a))).WillByDefault(Return());
|
||||
}
|
||||
|
||||
// Tests the linkage of the TypedEq matcher.
|
||||
TEST(LinkTest, TestMatcherTypedEq) {
|
||||
Mock mock;
|
||||
long a = 0;
|
||||
|
||||
ON_CALL(mock, VoidFromIntRef(TypedEq<int&>(a))).WillByDefault(Return());
|
||||
}
|
||||
|
||||
// Tests the linkage of the FloatEq, DoubleEq, NanSensitiveFloatEq and
|
||||
// NanSensitiveDoubleEq matchers.
|
||||
TEST(LinkTest, TestMatchersFloatingPoint) {
|
||||
Mock mock;
|
||||
float a = 0;
|
||||
|
||||
ON_CALL(mock, VoidFromFloat(FloatEq(a))).WillByDefault(Return());
|
||||
ON_CALL(mock, VoidFromDouble(DoubleEq(a))).WillByDefault(Return());
|
||||
ON_CALL(mock, VoidFromFloat(NanSensitiveFloatEq(a))).WillByDefault(Return());
|
||||
ON_CALL(mock, VoidFromDouble(NanSensitiveDoubleEq(a)))
|
||||
.WillByDefault(Return());
|
||||
}
|
||||
|
||||
#if GMOCK_HAS_REGEX
|
||||
// Tests the linkage of the ContainsRegex matcher.
|
||||
TEST(LinkTest, TestMatcherContainsRegex) {
|
||||
Mock mock;
|
||||
|
||||
ON_CALL(mock, VoidFromString(ContainsRegex(".*"))).WillByDefault(Return());
|
||||
}
|
||||
|
||||
// Tests the linkage of the MatchesRegex matcher.
|
||||
TEST(LinkTest, TestMatcherMatchesRegex) {
|
||||
Mock mock;
|
||||
|
||||
ON_CALL(mock, VoidFromString(MatchesRegex(".*"))).WillByDefault(Return());
|
||||
}
|
||||
#endif // GMOCK_HAS_REGEX
|
||||
|
||||
// Tests the linkage of the StartsWith, EndsWith, and HasSubstr matchers.
|
||||
TEST(LinkTest, TestMatchersSubstrings) {
|
||||
Mock mock;
|
||||
|
||||
ON_CALL(mock, VoidFromString(StartsWith("a"))).WillByDefault(Return());
|
||||
ON_CALL(mock, VoidFromString(EndsWith("c"))).WillByDefault(Return());
|
||||
ON_CALL(mock, VoidFromString(HasSubstr("b"))).WillByDefault(Return());
|
||||
}
|
||||
|
||||
// Tests the linkage of the StrEq, StrNe, StrCaseEq, and StrCaseNe matchers.
|
||||
TEST(LinkTest, TestMatchersStringEquality) {
|
||||
Mock mock;
|
||||
ON_CALL(mock, VoidFromString(StrEq("a"))).WillByDefault(Return());
|
||||
ON_CALL(mock, VoidFromString(StrNe("a"))).WillByDefault(Return());
|
||||
ON_CALL(mock, VoidFromString(StrCaseEq("a"))).WillByDefault(Return());
|
||||
ON_CALL(mock, VoidFromString(StrCaseNe("a"))).WillByDefault(Return());
|
||||
}
|
||||
|
||||
// Tests the linkage of the ElementsAre matcher.
|
||||
TEST(LinkTest, TestMatcherElementsAre) {
|
||||
Mock mock;
|
||||
|
||||
ON_CALL(mock, VoidFromVector(ElementsAre('a', _))).WillByDefault(Return());
|
||||
}
|
||||
|
||||
// Tests the linkage of the ElementsAreArray matcher.
|
||||
TEST(LinkTest, TestMatcherElementsAreArray) {
|
||||
Mock mock;
|
||||
char arr[] = { 'a', 'b' };
|
||||
|
||||
ON_CALL(mock, VoidFromVector(ElementsAreArray(arr))).WillByDefault(Return());
|
||||
}
|
||||
|
||||
// Tests the linkage of the ContainerEq matcher.
|
||||
TEST(LinkTest, TestMatcherContainerEq) {
|
||||
Mock mock;
|
||||
std::vector<int> v;
|
||||
|
||||
ON_CALL(mock, VoidFromVector(ContainerEq(v))).WillByDefault(Return());
|
||||
}
|
||||
|
||||
// Tests the linkage of the Field matcher.
|
||||
TEST(LinkTest, TestMatcherField) {
|
||||
FieldHelper helper(0);
|
||||
|
||||
Matcher<const FieldHelper&> m = Field(&FieldHelper::field_, Eq(0));
|
||||
EXPECT_TRUE(m.Matches(helper));
|
||||
|
||||
Matcher<const FieldHelper*> m2 = Field(&FieldHelper::field_, Eq(0));
|
||||
EXPECT_TRUE(m2.Matches(&helper));
|
||||
}
|
||||
|
||||
// Tests the linkage of the Property matcher.
|
||||
TEST(LinkTest, TestMatcherProperty) {
|
||||
FieldHelper helper(0);
|
||||
|
||||
Matcher<const FieldHelper&> m = Property(&FieldHelper::field, Eq(0));
|
||||
EXPECT_TRUE(m.Matches(helper));
|
||||
|
||||
Matcher<const FieldHelper*> m2 = Property(&FieldHelper::field, Eq(0));
|
||||
EXPECT_TRUE(m2.Matches(&helper));
|
||||
}
|
||||
|
||||
// Tests the linkage of the ResultOf matcher.
|
||||
TEST(LinkTest, TestMatcherResultOf) {
|
||||
Matcher<char*> m = ResultOf(&InvokeHelper::StaticIntFromString, Eq(1));
|
||||
EXPECT_TRUE(m.Matches(NULL));
|
||||
}
|
||||
|
||||
// Tests the linkage of the ResultOf matcher.
|
||||
TEST(LinkTest, TestMatcherPointee) {
|
||||
int n = 1;
|
||||
|
||||
Matcher<int*> m = Pointee(Eq(1));
|
||||
EXPECT_TRUE(m.Matches(&n));
|
||||
}
|
||||
|
||||
// Tests the linkage of the Truly matcher.
|
||||
TEST(LinkTest, TestMatcherTruly) {
|
||||
Matcher<const char*> m = Truly(&InvokeHelper::StaticBoolFromString);
|
||||
EXPECT_TRUE(m.Matches(NULL));
|
||||
}
|
||||
|
||||
// Tests the linkage of the AllOf matcher.
|
||||
TEST(LinkTest, TestMatcherAllOf) {
|
||||
Matcher<int> m = AllOf(_, Eq(1));
|
||||
EXPECT_TRUE(m.Matches(1));
|
||||
}
|
||||
|
||||
// Tests the linkage of the AnyOf matcher.
|
||||
TEST(LinkTest, TestMatcherAnyOf) {
|
||||
Matcher<int> m = AnyOf(_, Eq(1));
|
||||
EXPECT_TRUE(m.Matches(1));
|
||||
}
|
||||
|
||||
// Tests the linkage of the Not matcher.
|
||||
TEST(LinkTest, TestMatcherNot) {
|
||||
Matcher<int> m = Not(_);
|
||||
EXPECT_FALSE(m.Matches(1));
|
||||
}
|
||||
|
||||
// Tests the linkage of the MatcherCast<T>() function.
|
||||
TEST(LinkTest, TestMatcherCast) {
|
||||
Matcher<const char*> m = MatcherCast<const char*>(_);
|
||||
EXPECT_TRUE(m.Matches(NULL));
|
||||
}
|
||||
|
||||
#endif // GMOCK_TEST_GMOCK_LINK_TEST_H_
|
||||
Arquivo executável
+230
@@ -0,0 +1,230 @@
|
||||
#!/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.
|
||||
|
||||
"""Tests the text output of Google C++ Mocking Framework.
|
||||
|
||||
SYNOPSIS
|
||||
gmock_output_test.py --gmock_build_dir=BUILD/DIR --gengolden
|
||||
# where BUILD/DIR contains the built gmock_output_test_ file.
|
||||
gmock_output_test.py --gengolden
|
||||
gmock_output_test.py
|
||||
"""
|
||||
|
||||
__author__ = 'wan@google.com (Zhanyong Wan)'
|
||||
|
||||
import gmock_test_utils
|
||||
import os
|
||||
import re
|
||||
import string
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
|
||||
# The flag for generating the golden file
|
||||
GENGOLDEN_FLAG = '--gengolden'
|
||||
|
||||
IS_WINDOWS = os.name == 'nt'
|
||||
|
||||
if IS_WINDOWS:
|
||||
PROGRAM = r'..\build.dbg\gmock_output_test_.exe'
|
||||
else:
|
||||
PROGRAM = 'gmock_output_test_'
|
||||
|
||||
PROGRAM_PATH = os.path.join(gmock_test_utils.GetBuildDir(), PROGRAM)
|
||||
COMMAND = PROGRAM_PATH + ' --gtest_stack_trace_depth=0 --gtest_print_time=0'
|
||||
GOLDEN_NAME = 'gmock_output_test_golden.txt'
|
||||
GOLDEN_PATH = os.path.join(gmock_test_utils.GetSourceDir(),
|
||||
GOLDEN_NAME)
|
||||
|
||||
|
||||
def ToUnixLineEnding(s):
|
||||
"""Changes all Windows/Mac line endings in s to UNIX line endings."""
|
||||
|
||||
return s.replace('\r\n', '\n').replace('\r', '\n')
|
||||
|
||||
|
||||
def RemoveReportHeaderAndFooter(output):
|
||||
"""Removes Google Test result report's header and footer from the output."""
|
||||
|
||||
output = re.sub(r'.*gtest_main.*\n', '', output)
|
||||
output = re.sub(r'\[.*\d+ tests.*\n', '', output)
|
||||
output = re.sub(r'\[.* test environment .*\n', '', output)
|
||||
output = re.sub(r'\[=+\] \d+ tests .* ran.*', '', output)
|
||||
output = re.sub(r'.* FAILED TESTS\n', '', output)
|
||||
return output
|
||||
|
||||
|
||||
def RemoveLocations(output):
|
||||
"""Removes all file location info from a Google Test program's output.
|
||||
|
||||
Args:
|
||||
output: the output of a Google Test program.
|
||||
|
||||
Returns:
|
||||
output with all file location info (in the form of
|
||||
'DIRECTORY/FILE_NAME:LINE_NUMBER: 'or
|
||||
'DIRECTORY\\FILE_NAME(LINE_NUMBER): ') replaced by
|
||||
'FILE:#: '.
|
||||
"""
|
||||
|
||||
return re.sub(r'.*[/\\](.+)(\:\d+|\(\d+\))\:', 'FILE:#:', output)
|
||||
|
||||
|
||||
def NormalizeErrorMarker(output):
|
||||
"""Normalizes the error marker, which is different on Windows vs on Linux."""
|
||||
|
||||
return re.sub(r' error: ', ' Failure\n', output)
|
||||
|
||||
|
||||
def RemoveMemoryAddresses(output):
|
||||
"""Removes memory addresses from the test output."""
|
||||
|
||||
return re.sub(r'@\w+', '@0x#', output)
|
||||
|
||||
|
||||
def RemoveTestNamesOfLeakedMocks(output):
|
||||
"""Removes the test names of leaked mock objects from the test output."""
|
||||
|
||||
return re.sub(r'\(used in test .+\) ', '', output)
|
||||
|
||||
|
||||
def GetLeakyTests(output):
|
||||
"""Returns a list of test names that leak mock objects."""
|
||||
|
||||
# findall() returns a list of all matches of the regex in output.
|
||||
# For example, if '(used in test FooTest.Bar)' is in output, the
|
||||
# list will contain 'FooTest.Bar'.
|
||||
return re.findall(r'\(used in test (.+)\)', output)
|
||||
|
||||
|
||||
def GetNormalizedOutputAndLeakyTests(output):
|
||||
"""Normalizes the output of gmock_output_test_.
|
||||
|
||||
Args:
|
||||
output: The test output.
|
||||
|
||||
Returns:
|
||||
A tuple (the normalized test output, the list of test names that have
|
||||
leaked mocks).
|
||||
"""
|
||||
|
||||
output = ToUnixLineEnding(output)
|
||||
output = RemoveReportHeaderAndFooter(output)
|
||||
output = NormalizeErrorMarker(output)
|
||||
output = RemoveLocations(output)
|
||||
output = RemoveMemoryAddresses(output)
|
||||
return (RemoveTestNamesOfLeakedMocks(output), GetLeakyTests(output))
|
||||
|
||||
|
||||
def IterShellCommandOutput(cmd, stdin_string=None):
|
||||
"""Runs a command in a sub-process, and iterates the lines in its STDOUT.
|
||||
|
||||
Args:
|
||||
|
||||
cmd: The shell command.
|
||||
stdin_string: The string to be fed to the STDIN of the sub-process;
|
||||
If None, the sub-process will inherit the STDIN
|
||||
from the parent process.
|
||||
"""
|
||||
|
||||
# Spawns cmd in a sub-process, and gets its standard I/O file objects.
|
||||
stdin_file, stdout_file = os.popen2(cmd, 'b')
|
||||
|
||||
# If the caller didn't specify a string for STDIN, gets it from the
|
||||
# parent process.
|
||||
if stdin_string is None:
|
||||
stdin_string = sys.stdin.read()
|
||||
|
||||
# Feeds the STDIN string to the sub-process.
|
||||
stdin_file.write(stdin_string)
|
||||
stdin_file.close()
|
||||
|
||||
while True:
|
||||
line = stdout_file.readline()
|
||||
if not line: # EOF
|
||||
stdout_file.close()
|
||||
break
|
||||
|
||||
yield line
|
||||
|
||||
|
||||
def GetShellCommandOutput(cmd, stdin_string=None):
|
||||
"""Runs a command in a sub-process, and returns its STDOUT in a string.
|
||||
|
||||
Args:
|
||||
|
||||
cmd: The shell command.
|
||||
stdin_string: The string to be fed to the STDIN of the sub-process;
|
||||
If None, the sub-process will inherit the STDIN
|
||||
from the parent process.
|
||||
"""
|
||||
|
||||
lines = list(IterShellCommandOutput(cmd, stdin_string))
|
||||
return string.join(lines, '')
|
||||
|
||||
|
||||
def GetNormalizedCommandOutputAndLeakyTests(cmd):
|
||||
"""Runs a command and returns its normalized output and a list of leaky tests.
|
||||
|
||||
Args:
|
||||
cmd: the shell command.
|
||||
"""
|
||||
|
||||
# Disables exception pop-ups on Windows.
|
||||
os.environ['GTEST_CATCH_EXCEPTIONS'] = '1'
|
||||
return GetNormalizedOutputAndLeakyTests(GetShellCommandOutput(cmd, ''))
|
||||
|
||||
|
||||
class GMockOutputTest(unittest.TestCase):
|
||||
def testOutput(self):
|
||||
(output, leaky_tests) = GetNormalizedCommandOutputAndLeakyTests(COMMAND)
|
||||
golden_file = open(GOLDEN_PATH, 'rb')
|
||||
golden = golden_file.read()
|
||||
golden_file.close()
|
||||
|
||||
# The normalized output should match the golden file.
|
||||
self.assertEquals(golden, output)
|
||||
|
||||
# The raw output should contain 2 leaked mock object errors for
|
||||
# test GMockOutputTest.CatchesLeakedMocks.
|
||||
self.assertEquals(['GMockOutputTest.CatchesLeakedMocks',
|
||||
'GMockOutputTest.CatchesLeakedMocks'],
|
||||
leaky_tests)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if sys.argv[1:] == [GENGOLDEN_FLAG]:
|
||||
(output, _) = GetNormalizedCommandOutputAndLeakyTests(COMMAND)
|
||||
golden_file = open(GOLDEN_PATH, 'wb')
|
||||
golden_file.write(output)
|
||||
golden_file.close()
|
||||
else:
|
||||
gmock_test_utils.Main()
|
||||
@@ -0,0 +1,281 @@
|
||||
// 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.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
|
||||
// Tests Google Mock's output in various scenarios. This ensures that
|
||||
// Google Mock's messages are readable and useful.
|
||||
|
||||
#include <gmock/gmock.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
using testing::_;
|
||||
using testing::AnyNumber;
|
||||
using testing::Ge;
|
||||
using testing::InSequence;
|
||||
using testing::Ref;
|
||||
using testing::Return;
|
||||
using testing::Sequence;
|
||||
|
||||
class MockFoo {
|
||||
public:
|
||||
MOCK_METHOD3(Bar, char(const std::string& s, int i, double x));
|
||||
MOCK_METHOD2(Bar2, bool(int x, int y));
|
||||
MOCK_METHOD2(Bar3, void(int x, int y));
|
||||
};
|
||||
|
||||
class GMockOutputTest : public testing::Test {
|
||||
protected:
|
||||
MockFoo foo_;
|
||||
};
|
||||
|
||||
TEST_F(GMockOutputTest, ExpectedCall) {
|
||||
testing::GMOCK_FLAG(verbose) = "info";
|
||||
|
||||
EXPECT_CALL(foo_, Bar2(0, _));
|
||||
foo_.Bar2(0, 0); // Expected call
|
||||
|
||||
testing::GMOCK_FLAG(verbose) = "warning";
|
||||
}
|
||||
|
||||
TEST_F(GMockOutputTest, ExpectedCallToVoidFunction) {
|
||||
testing::GMOCK_FLAG(verbose) = "info";
|
||||
|
||||
EXPECT_CALL(foo_, Bar3(0, _));
|
||||
foo_.Bar3(0, 0); // Expected call
|
||||
|
||||
testing::GMOCK_FLAG(verbose) = "warning";
|
||||
}
|
||||
|
||||
TEST_F(GMockOutputTest, ExplicitActionsRunOut) {
|
||||
EXPECT_CALL(foo_, Bar2(_, _))
|
||||
.Times(2)
|
||||
.WillOnce(Return(false));
|
||||
foo_.Bar2(2, 2);
|
||||
foo_.Bar2(1, 1); // Explicit actions in EXPECT_CALL run out.
|
||||
}
|
||||
|
||||
TEST_F(GMockOutputTest, UnexpectedCall) {
|
||||
EXPECT_CALL(foo_, Bar2(0, _));
|
||||
|
||||
foo_.Bar2(1, 0); // Unexpected call
|
||||
foo_.Bar2(0, 0); // Expected call
|
||||
}
|
||||
|
||||
TEST_F(GMockOutputTest, UnexpectedCallToVoidFunction) {
|
||||
EXPECT_CALL(foo_, Bar3(0, _));
|
||||
|
||||
foo_.Bar3(1, 0); // Unexpected call
|
||||
foo_.Bar3(0, 0); // Expected call
|
||||
}
|
||||
|
||||
TEST_F(GMockOutputTest, ExcessiveCall) {
|
||||
EXPECT_CALL(foo_, Bar2(0, _));
|
||||
|
||||
foo_.Bar2(0, 0); // Expected call
|
||||
foo_.Bar2(0, 1); // Excessive call
|
||||
}
|
||||
|
||||
TEST_F(GMockOutputTest, ExcessiveCallToVoidFunction) {
|
||||
EXPECT_CALL(foo_, Bar3(0, _));
|
||||
|
||||
foo_.Bar3(0, 0); // Expected call
|
||||
foo_.Bar3(0, 1); // Excessive call
|
||||
}
|
||||
|
||||
TEST_F(GMockOutputTest, UninterestingCall) {
|
||||
foo_.Bar2(0, 1); // Uninteresting call
|
||||
}
|
||||
|
||||
TEST_F(GMockOutputTest, UninterestingCallToVoidFunction) {
|
||||
foo_.Bar3(0, 1); // Uninteresting call
|
||||
}
|
||||
|
||||
TEST_F(GMockOutputTest, RetiredExpectation) {
|
||||
EXPECT_CALL(foo_, Bar2(_, _))
|
||||
.RetiresOnSaturation();
|
||||
EXPECT_CALL(foo_, Bar2(0, 0));
|
||||
|
||||
foo_.Bar2(1, 1);
|
||||
foo_.Bar2(1, 1); // Matches a retired expectation
|
||||
foo_.Bar2(0, 0);
|
||||
}
|
||||
|
||||
TEST_F(GMockOutputTest, UnsatisfiedPrerequisite) {
|
||||
{
|
||||
InSequence s;
|
||||
EXPECT_CALL(foo_, Bar(_, 0, _));
|
||||
EXPECT_CALL(foo_, Bar2(0, 0));
|
||||
EXPECT_CALL(foo_, Bar2(1, _));
|
||||
}
|
||||
|
||||
foo_.Bar2(1, 0); // Has one immediate unsatisfied pre-requisite
|
||||
foo_.Bar("Hi", 0, 0);
|
||||
foo_.Bar2(0, 0);
|
||||
foo_.Bar2(1, 0);
|
||||
}
|
||||
|
||||
TEST_F(GMockOutputTest, UnsatisfiedPrerequisites) {
|
||||
Sequence s1, s2;
|
||||
|
||||
EXPECT_CALL(foo_, Bar(_, 0, _))
|
||||
.InSequence(s1);
|
||||
EXPECT_CALL(foo_, Bar2(0, 0))
|
||||
.InSequence(s2);
|
||||
EXPECT_CALL(foo_, Bar2(1, _))
|
||||
.InSequence(s1, s2);
|
||||
|
||||
foo_.Bar2(1, 0); // Has two immediate unsatisfied pre-requisites
|
||||
foo_.Bar("Hi", 0, 0);
|
||||
foo_.Bar2(0, 0);
|
||||
foo_.Bar2(1, 0);
|
||||
}
|
||||
|
||||
TEST_F(GMockOutputTest, UnsatisfiedExpectation) {
|
||||
EXPECT_CALL(foo_, Bar(_, _, _));
|
||||
EXPECT_CALL(foo_, Bar2(0, _))
|
||||
.Times(2);
|
||||
|
||||
foo_.Bar2(0, 1);
|
||||
}
|
||||
|
||||
TEST_F(GMockOutputTest, MismatchArguments) {
|
||||
const std::string s = "Hi";
|
||||
EXPECT_CALL(foo_, Bar(Ref(s), _, Ge(0)));
|
||||
|
||||
foo_.Bar("Ho", 0, -0.1); // Mismatch arguments
|
||||
foo_.Bar(s, 0, 0);
|
||||
}
|
||||
|
||||
TEST_F(GMockOutputTest, MismatchWithArguments) {
|
||||
EXPECT_CALL(foo_, Bar2(Ge(2), Ge(1)))
|
||||
.WithArguments(Ge());
|
||||
|
||||
foo_.Bar2(2, 3); // Mismatch WithArguments()
|
||||
foo_.Bar2(2, 1);
|
||||
}
|
||||
|
||||
TEST_F(GMockOutputTest, MismatchArgumentsAndWithArguments) {
|
||||
EXPECT_CALL(foo_, Bar2(Ge(2), Ge(1)))
|
||||
.WithArguments(Ge());
|
||||
|
||||
foo_.Bar2(1, 3); // Mismatch arguments and mismatch WithArguments()
|
||||
foo_.Bar2(2, 1);
|
||||
}
|
||||
|
||||
TEST_F(GMockOutputTest, UnexpectedCallWithDefaultAction) {
|
||||
ON_CALL(foo_, Bar2(_, _))
|
||||
.WillByDefault(Return(true)); // Default action #1
|
||||
ON_CALL(foo_, Bar2(1, _))
|
||||
.WillByDefault(Return(false)); // Default action #2
|
||||
|
||||
EXPECT_CALL(foo_, Bar2(2, 2));
|
||||
foo_.Bar2(1, 0); // Unexpected call, takes default action #2.
|
||||
foo_.Bar2(0, 0); // Unexpected call, takes default action #1.
|
||||
foo_.Bar2(2, 2); // Expected call.
|
||||
}
|
||||
|
||||
TEST_F(GMockOutputTest, ExcessiveCallWithDefaultAction) {
|
||||
ON_CALL(foo_, Bar2(_, _))
|
||||
.WillByDefault(Return(true)); // Default action #1
|
||||
ON_CALL(foo_, Bar2(1, _))
|
||||
.WillByDefault(Return(false)); // Default action #2
|
||||
|
||||
EXPECT_CALL(foo_, Bar2(2, 2));
|
||||
EXPECT_CALL(foo_, Bar2(1, 1));
|
||||
|
||||
foo_.Bar2(2, 2); // Expected call.
|
||||
foo_.Bar2(2, 2); // Excessive call, takes default action #1.
|
||||
foo_.Bar2(1, 1); // Expected call.
|
||||
foo_.Bar2(1, 1); // Excessive call, takes default action #2.
|
||||
}
|
||||
|
||||
TEST_F(GMockOutputTest, UninterestingCallWithDefaultAction) {
|
||||
ON_CALL(foo_, Bar2(_, _))
|
||||
.WillByDefault(Return(true)); // Default action #1
|
||||
ON_CALL(foo_, Bar2(1, _))
|
||||
.WillByDefault(Return(false)); // Default action #2
|
||||
|
||||
foo_.Bar2(2, 2); // Uninteresting call, takes default action #1.
|
||||
foo_.Bar2(1, 1); // Uninteresting call, takes default action #2.
|
||||
}
|
||||
|
||||
TEST_F(GMockOutputTest, ExplicitActionsRunOutWithDefaultAction) {
|
||||
ON_CALL(foo_, Bar2(_, _))
|
||||
.WillByDefault(Return(true)); // Default action #1
|
||||
|
||||
EXPECT_CALL(foo_, Bar2(_, _))
|
||||
.Times(2)
|
||||
.WillOnce(Return(false));
|
||||
foo_.Bar2(2, 2);
|
||||
foo_.Bar2(1, 1); // Explicit actions in EXPECT_CALL run out.
|
||||
}
|
||||
|
||||
TEST_F(GMockOutputTest, CatchesLeakedMocks) {
|
||||
MockFoo* foo1 = new MockFoo;
|
||||
MockFoo* foo2 = new MockFoo;
|
||||
|
||||
// Invokes ON_CALL on foo1.
|
||||
ON_CALL(*foo1, Bar(_, _, _)).WillByDefault(Return('a'));
|
||||
|
||||
// Invokes EXPECT_CALL on foo2.
|
||||
EXPECT_CALL(*foo2, Bar2(_, _));
|
||||
EXPECT_CALL(*foo2, Bar2(1, _));
|
||||
EXPECT_CALL(*foo2, Bar3(_, _)).Times(AnyNumber());
|
||||
foo2->Bar2(2, 1);
|
||||
foo2->Bar2(1, 1);
|
||||
|
||||
// Both foo1 and foo2 are deliberately leaked.
|
||||
}
|
||||
|
||||
void TestCatchesLeakedMocksInAdHocTests() {
|
||||
MockFoo* foo = new MockFoo;
|
||||
|
||||
// Invokes EXPECT_CALL on foo.
|
||||
EXPECT_CALL(*foo, Bar2(_, _));
|
||||
foo->Bar2(2, 1);
|
||||
|
||||
// foo is deliberately leaked.
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
testing::InitGoogleMock(&argc, argv);
|
||||
|
||||
// Ensures that the tests pass no matter what value of
|
||||
// --gmock_catch_leaked_mocks and --gmock_verbose the user specifies.
|
||||
testing::GMOCK_FLAG(catch_leaked_mocks) = true;
|
||||
testing::GMOCK_FLAG(verbose) = "warning";
|
||||
|
||||
TestCatchesLeakedMocksInAdHocTests();
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
@@ -0,0 +1,302 @@
|
||||
[ RUN ] GMockOutputTest.ExpectedCall
|
||||
|
||||
FILE:#: EXPECT_CALL(foo_, Bar2(0, _)) invoked
|
||||
Stack trace:
|
||||
|
||||
FILE:#: Expected mock function call.
|
||||
Function call: Bar2(0, 0)
|
||||
Returns: false
|
||||
Stack trace:
|
||||
[ OK ] GMockOutputTest.ExpectedCall
|
||||
[ RUN ] GMockOutputTest.ExpectedCallToVoidFunction
|
||||
|
||||
FILE:#: EXPECT_CALL(foo_, Bar3(0, _)) invoked
|
||||
Stack trace:
|
||||
|
||||
FILE:#: Expected mock function call.
|
||||
Function call: Bar3(0, 0)
|
||||
Stack trace:
|
||||
[ OK ] GMockOutputTest.ExpectedCallToVoidFunction
|
||||
[ RUN ] GMockOutputTest.ExplicitActionsRunOut
|
||||
|
||||
GMOCK WARNING:
|
||||
FILE:#: Too few actions specified.
|
||||
Expected to be called twice, but has only 1 WillOnce().
|
||||
GMOCK WARNING:
|
||||
FILE:#: Actions ran out.
|
||||
Called 2 times, but only 1 WillOnce() is specified - returning default value.
|
||||
Stack trace:
|
||||
[ OK ] GMockOutputTest.ExplicitActionsRunOut
|
||||
[ RUN ] GMockOutputTest.UnexpectedCall
|
||||
unknown file: Failure
|
||||
|
||||
Unexpected mock function call - returning default value.
|
||||
Function call: Bar2(1, 0)
|
||||
Returns: false
|
||||
Google Mock tried the following 1 expectation, but it didn't match:
|
||||
|
||||
FILE:#:
|
||||
Expected arg #0: is equal to 0
|
||||
Actual: 1
|
||||
Expected: to be called once
|
||||
Actual: never called - unsatisfied and active
|
||||
[ FAILED ] GMockOutputTest.UnexpectedCall
|
||||
[ RUN ] GMockOutputTest.UnexpectedCallToVoidFunction
|
||||
unknown file: Failure
|
||||
|
||||
Unexpected mock function call - returning directly.
|
||||
Function call: Bar3(1, 0)
|
||||
Google Mock tried the following 1 expectation, but it didn't match:
|
||||
|
||||
FILE:#:
|
||||
Expected arg #0: is equal to 0
|
||||
Actual: 1
|
||||
Expected: to be called once
|
||||
Actual: never called - unsatisfied and active
|
||||
[ FAILED ] GMockOutputTest.UnexpectedCallToVoidFunction
|
||||
[ RUN ] GMockOutputTest.ExcessiveCall
|
||||
FILE:#: Failure
|
||||
Mock function called more times than expected - returning default value.
|
||||
Function call: Bar2(0, 1)
|
||||
Returns: false
|
||||
Expected: to be called once
|
||||
Actual: called twice - over-saturated and active
|
||||
[ FAILED ] GMockOutputTest.ExcessiveCall
|
||||
[ RUN ] GMockOutputTest.ExcessiveCallToVoidFunction
|
||||
FILE:#: Failure
|
||||
Mock function called more times than expected - returning directly.
|
||||
Function call: Bar3(0, 1)
|
||||
Expected: to be called once
|
||||
Actual: called twice - over-saturated and active
|
||||
[ FAILED ] GMockOutputTest.ExcessiveCallToVoidFunction
|
||||
[ RUN ] GMockOutputTest.UninterestingCall
|
||||
|
||||
GMOCK WARNING:
|
||||
Uninteresting mock function call - returning default value.
|
||||
Function call: Bar2(0, 1)
|
||||
Returns: false
|
||||
Stack trace:
|
||||
[ OK ] GMockOutputTest.UninterestingCall
|
||||
[ RUN ] GMockOutputTest.UninterestingCallToVoidFunction
|
||||
|
||||
GMOCK WARNING:
|
||||
Uninteresting mock function call - returning directly.
|
||||
Function call: Bar3(0, 1)
|
||||
Stack trace:
|
||||
[ OK ] GMockOutputTest.UninterestingCallToVoidFunction
|
||||
[ RUN ] GMockOutputTest.RetiredExpectation
|
||||
unknown file: Failure
|
||||
|
||||
Unexpected mock function call - returning default value.
|
||||
Function call: Bar2(1, 1)
|
||||
Returns: false
|
||||
Google Mock tried the following 2 expectations, but none matched:
|
||||
|
||||
FILE:#: tried expectation #0
|
||||
Expected: the expectation is active
|
||||
Actual: it is retired
|
||||
Expected: to be called once
|
||||
Actual: called once - saturated and retired
|
||||
FILE:#: tried expectation #1
|
||||
Expected arg #0: is equal to 0
|
||||
Actual: 1
|
||||
Expected arg #1: is equal to 0
|
||||
Actual: 1
|
||||
Expected: to be called once
|
||||
Actual: never called - unsatisfied and active
|
||||
[ FAILED ] GMockOutputTest.RetiredExpectation
|
||||
[ RUN ] GMockOutputTest.UnsatisfiedPrerequisite
|
||||
unknown file: Failure
|
||||
|
||||
Unexpected mock function call - returning default value.
|
||||
Function call: Bar2(1, 0)
|
||||
Returns: false
|
||||
Google Mock tried the following 2 expectations, but none matched:
|
||||
|
||||
FILE:#: tried expectation #0
|
||||
Expected arg #0: is equal to 0
|
||||
Actual: 1
|
||||
Expected: to be called once
|
||||
Actual: never called - unsatisfied and active
|
||||
FILE:#: tried expectation #1
|
||||
Expected: all pre-requisites are satisfied
|
||||
Actual: the following immediate pre-requisites are not satisfied:
|
||||
FILE:#: pre-requisite #0
|
||||
(end of pre-requisites)
|
||||
Expected: to be called once
|
||||
Actual: never called - unsatisfied and active
|
||||
[ FAILED ] GMockOutputTest.UnsatisfiedPrerequisite
|
||||
[ RUN ] GMockOutputTest.UnsatisfiedPrerequisites
|
||||
unknown file: Failure
|
||||
|
||||
Unexpected mock function call - returning default value.
|
||||
Function call: Bar2(1, 0)
|
||||
Returns: false
|
||||
Google Mock tried the following 2 expectations, but none matched:
|
||||
|
||||
FILE:#: tried expectation #0
|
||||
Expected arg #0: is equal to 0
|
||||
Actual: 1
|
||||
Expected: to be called once
|
||||
Actual: never called - unsatisfied and active
|
||||
FILE:#: tried expectation #1
|
||||
Expected: all pre-requisites are satisfied
|
||||
Actual: the following immediate pre-requisites are not satisfied:
|
||||
FILE:#: pre-requisite #0
|
||||
FILE:#: pre-requisite #1
|
||||
(end of pre-requisites)
|
||||
Expected: to be called once
|
||||
Actual: never called - unsatisfied and active
|
||||
[ FAILED ] GMockOutputTest.UnsatisfiedPrerequisites
|
||||
[ RUN ] GMockOutputTest.UnsatisfiedExpectation
|
||||
FILE:#: Failure
|
||||
Actual function call count doesn't match this expectation.
|
||||
Expected: to be called twice
|
||||
Actual: called once - unsatisfied and active
|
||||
FILE:#: Failure
|
||||
Actual function call count doesn't match this expectation.
|
||||
Expected: to be called once
|
||||
Actual: never called - unsatisfied and active
|
||||
[ FAILED ] GMockOutputTest.UnsatisfiedExpectation
|
||||
[ RUN ] GMockOutputTest.MismatchArguments
|
||||
unknown file: Failure
|
||||
|
||||
Unexpected mock function call - returning default value.
|
||||
Function call: Bar(@0x# "Ho", 0, -0.1)
|
||||
Returns: '\0'
|
||||
Google Mock tried the following 1 expectation, but it didn't match:
|
||||
|
||||
FILE:#:
|
||||
Expected arg #0: references the variable @0x# "Hi"
|
||||
Actual: "Ho" (is located @0x#)
|
||||
Expected arg #2: is greater than or equal to 0
|
||||
Actual: -0.1
|
||||
Expected: to be called once
|
||||
Actual: never called - unsatisfied and active
|
||||
[ FAILED ] GMockOutputTest.MismatchArguments
|
||||
[ RUN ] GMockOutputTest.MismatchWithArguments
|
||||
unknown file: Failure
|
||||
|
||||
Unexpected mock function call - returning default value.
|
||||
Function call: Bar2(2, 3)
|
||||
Returns: false
|
||||
Google Mock tried the following 1 expectation, but it didn't match:
|
||||
|
||||
FILE:#:
|
||||
Expected: argument #0 is greater than or equal to argument #1
|
||||
Actual: false
|
||||
Expected: to be called once
|
||||
Actual: never called - unsatisfied and active
|
||||
[ FAILED ] GMockOutputTest.MismatchWithArguments
|
||||
[ RUN ] GMockOutputTest.MismatchArgumentsAndWithArguments
|
||||
unknown file: Failure
|
||||
|
||||
Unexpected mock function call - returning default value.
|
||||
Function call: Bar2(1, 3)
|
||||
Returns: false
|
||||
Google Mock tried the following 1 expectation, but it didn't match:
|
||||
|
||||
FILE:#:
|
||||
Expected arg #0: is greater than or equal to 2
|
||||
Actual: 1
|
||||
Expected: argument #0 is greater than or equal to argument #1
|
||||
Actual: false
|
||||
Expected: to be called once
|
||||
Actual: never called - unsatisfied and active
|
||||
[ FAILED ] GMockOutputTest.MismatchArgumentsAndWithArguments
|
||||
[ RUN ] GMockOutputTest.UnexpectedCallWithDefaultAction
|
||||
unknown file: Failure
|
||||
|
||||
Unexpected mock function call - taking default action specified at:
|
||||
FILE:#:
|
||||
Function call: Bar2(1, 0)
|
||||
Returns: false
|
||||
Google Mock tried the following 1 expectation, but it didn't match:
|
||||
|
||||
FILE:#:
|
||||
Expected arg #0: is equal to 2
|
||||
Actual: 1
|
||||
Expected arg #1: is equal to 2
|
||||
Actual: 0
|
||||
Expected: to be called once
|
||||
Actual: never called - unsatisfied and active
|
||||
unknown file: Failure
|
||||
|
||||
Unexpected mock function call - taking default action specified at:
|
||||
FILE:#:
|
||||
Function call: Bar2(0, 0)
|
||||
Returns: true
|
||||
Google Mock tried the following 1 expectation, but it didn't match:
|
||||
|
||||
FILE:#:
|
||||
Expected arg #0: is equal to 2
|
||||
Actual: 0
|
||||
Expected arg #1: is equal to 2
|
||||
Actual: 0
|
||||
Expected: to be called once
|
||||
Actual: never called - unsatisfied and active
|
||||
[ FAILED ] GMockOutputTest.UnexpectedCallWithDefaultAction
|
||||
[ RUN ] GMockOutputTest.ExcessiveCallWithDefaultAction
|
||||
FILE:#: Failure
|
||||
Mock function called more times than expected - taking default action specified at:
|
||||
FILE:#:
|
||||
Function call: Bar2(2, 2)
|
||||
Returns: true
|
||||
Expected: to be called once
|
||||
Actual: called twice - over-saturated and active
|
||||
FILE:#: Failure
|
||||
Mock function called more times than expected - taking default action specified at:
|
||||
FILE:#:
|
||||
Function call: Bar2(1, 1)
|
||||
Returns: false
|
||||
Expected: to be called once
|
||||
Actual: called twice - over-saturated and active
|
||||
[ FAILED ] GMockOutputTest.ExcessiveCallWithDefaultAction
|
||||
[ RUN ] GMockOutputTest.UninterestingCallWithDefaultAction
|
||||
|
||||
GMOCK WARNING:
|
||||
Uninteresting mock function call - taking default action specified at:
|
||||
FILE:#:
|
||||
Function call: Bar2(2, 2)
|
||||
Returns: true
|
||||
Stack trace:
|
||||
|
||||
GMOCK WARNING:
|
||||
Uninteresting mock function call - taking default action specified at:
|
||||
FILE:#:
|
||||
Function call: Bar2(1, 1)
|
||||
Returns: false
|
||||
Stack trace:
|
||||
[ OK ] GMockOutputTest.UninterestingCallWithDefaultAction
|
||||
[ RUN ] GMockOutputTest.ExplicitActionsRunOutWithDefaultAction
|
||||
|
||||
GMOCK WARNING:
|
||||
FILE:#: Too few actions specified.
|
||||
Expected to be called twice, but has only 1 WillOnce().
|
||||
GMOCK WARNING:
|
||||
FILE:#: Actions ran out.
|
||||
Called 2 times, but only 1 WillOnce() is specified - taking default action specified at:
|
||||
FILE:#:
|
||||
Stack trace:
|
||||
[ OK ] GMockOutputTest.ExplicitActionsRunOutWithDefaultAction
|
||||
[ RUN ] GMockOutputTest.CatchesLeakedMocks
|
||||
[ OK ] GMockOutputTest.CatchesLeakedMocks
|
||||
[ FAILED ] GMockOutputTest.UnexpectedCall
|
||||
[ FAILED ] GMockOutputTest.UnexpectedCallToVoidFunction
|
||||
[ FAILED ] GMockOutputTest.ExcessiveCall
|
||||
[ FAILED ] GMockOutputTest.ExcessiveCallToVoidFunction
|
||||
[ FAILED ] GMockOutputTest.RetiredExpectation
|
||||
[ FAILED ] GMockOutputTest.UnsatisfiedPrerequisite
|
||||
[ FAILED ] GMockOutputTest.UnsatisfiedPrerequisites
|
||||
[ FAILED ] GMockOutputTest.UnsatisfiedExpectation
|
||||
[ FAILED ] GMockOutputTest.MismatchArguments
|
||||
[ FAILED ] GMockOutputTest.MismatchWithArguments
|
||||
[ FAILED ] GMockOutputTest.MismatchArgumentsAndWithArguments
|
||||
[ FAILED ] GMockOutputTest.UnexpectedCallWithDefaultAction
|
||||
[ FAILED ] GMockOutputTest.ExcessiveCallWithDefaultAction
|
||||
|
||||
|
||||
FILE:#: ERROR: this mock object should be deleted but never is. Its address is @0x#.
|
||||
FILE:#: ERROR: this mock object should be deleted but never is. Its address is @0x#.
|
||||
FILE:#: ERROR: this mock object should be deleted but never is. Its address is @0x#.
|
||||
ERROR: 3 leaked mock objects found at program exit.
|
||||
@@ -0,0 +1,255 @@
|
||||
// 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.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
|
||||
// Google Mock - a framework for writing C++ mock classes.
|
||||
//
|
||||
// This file tests code in gmock.cc.
|
||||
|
||||
#include <gmock/gmock.h>
|
||||
|
||||
#include <string>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
using testing::GMOCK_FLAG(verbose);
|
||||
using testing::InitGoogleMock;
|
||||
using testing::internal::g_init_gtest_count;
|
||||
|
||||
// Verifies that calling InitGoogleMock() on argv results in new_argv,
|
||||
// and the gmock_verbose flag's value is set to expected_gmock_verbose.
|
||||
template <typename Char, int M, int N>
|
||||
void TestInitGoogleMock(const Char* (&argv)[M], const Char* (&new_argv)[N],
|
||||
const ::std::string& expected_gmock_verbose) {
|
||||
const ::std::string old_verbose = GMOCK_FLAG(verbose);
|
||||
|
||||
int argc = M;
|
||||
InitGoogleMock(&argc, const_cast<Char**>(argv));
|
||||
ASSERT_EQ(N, argc) << "The new argv has wrong number of elements.";
|
||||
|
||||
for (int i = 0; i < N; i++) {
|
||||
EXPECT_STREQ(new_argv[i], argv[i]);
|
||||
}
|
||||
|
||||
EXPECT_EQ(expected_gmock_verbose, GMOCK_FLAG(verbose).c_str());
|
||||
GMOCK_FLAG(verbose) = old_verbose; // Restores the gmock_verbose flag.
|
||||
}
|
||||
|
||||
TEST(InitGoogleMockTest, ParsesInvalidCommandLine) {
|
||||
const char* argv[] = {
|
||||
NULL
|
||||
};
|
||||
|
||||
const char* new_argv[] = {
|
||||
NULL
|
||||
};
|
||||
|
||||
TestInitGoogleMock(argv, new_argv, GMOCK_FLAG(verbose));
|
||||
}
|
||||
|
||||
TEST(InitGoogleMockTest, ParsesEmptyCommandLine) {
|
||||
const char* argv[] = {
|
||||
"foo.exe",
|
||||
NULL
|
||||
};
|
||||
|
||||
const char* new_argv[] = {
|
||||
"foo.exe",
|
||||
NULL
|
||||
};
|
||||
|
||||
TestInitGoogleMock(argv, new_argv, GMOCK_FLAG(verbose));
|
||||
}
|
||||
|
||||
TEST(InitGoogleMockTest, ParsesSingleFlag) {
|
||||
const char* argv[] = {
|
||||
"foo.exe",
|
||||
"--gmock_verbose=info",
|
||||
NULL
|
||||
};
|
||||
|
||||
const char* new_argv[] = {
|
||||
"foo.exe",
|
||||
NULL
|
||||
};
|
||||
|
||||
TestInitGoogleMock(argv, new_argv, "info");
|
||||
}
|
||||
|
||||
TEST(InitGoogleMockTest, ParsesUnrecognizedFlag) {
|
||||
const char* argv[] = {
|
||||
"foo.exe",
|
||||
"--non_gmock_flag=blah",
|
||||
NULL
|
||||
};
|
||||
|
||||
const char* new_argv[] = {
|
||||
"foo.exe",
|
||||
"--non_gmock_flag=blah",
|
||||
NULL
|
||||
};
|
||||
|
||||
TestInitGoogleMock(argv, new_argv, GMOCK_FLAG(verbose));
|
||||
}
|
||||
|
||||
TEST(InitGoogleMockTest, ParsesGoogleMockFlagAndUnrecognizedFlag) {
|
||||
const char* argv[] = {
|
||||
"foo.exe",
|
||||
"--non_gmock_flag=blah",
|
||||
"--gmock_verbose=error",
|
||||
NULL
|
||||
};
|
||||
|
||||
const char* new_argv[] = {
|
||||
"foo.exe",
|
||||
"--non_gmock_flag=blah",
|
||||
NULL
|
||||
};
|
||||
|
||||
TestInitGoogleMock(argv, new_argv, "error");
|
||||
}
|
||||
|
||||
TEST(InitGoogleMockTest, CallsInitGoogleTest) {
|
||||
const int old_init_gtest_count = g_init_gtest_count;
|
||||
const char* argv[] = {
|
||||
"foo.exe",
|
||||
"--non_gmock_flag=blah",
|
||||
"--gmock_verbose=error",
|
||||
NULL
|
||||
};
|
||||
|
||||
const char* new_argv[] = {
|
||||
"foo.exe",
|
||||
"--non_gmock_flag=blah",
|
||||
NULL
|
||||
};
|
||||
|
||||
TestInitGoogleMock(argv, new_argv, "error");
|
||||
EXPECT_EQ(old_init_gtest_count + 1, g_init_gtest_count);
|
||||
}
|
||||
|
||||
TEST(WideInitGoogleMockTest, ParsesInvalidCommandLine) {
|
||||
const wchar_t* argv[] = {
|
||||
NULL
|
||||
};
|
||||
|
||||
const wchar_t* new_argv[] = {
|
||||
NULL
|
||||
};
|
||||
|
||||
TestInitGoogleMock(argv, new_argv, GMOCK_FLAG(verbose));
|
||||
}
|
||||
|
||||
TEST(WideInitGoogleMockTest, ParsesEmptyCommandLine) {
|
||||
const wchar_t* argv[] = {
|
||||
L"foo.exe",
|
||||
NULL
|
||||
};
|
||||
|
||||
const wchar_t* new_argv[] = {
|
||||
L"foo.exe",
|
||||
NULL
|
||||
};
|
||||
|
||||
TestInitGoogleMock(argv, new_argv, GMOCK_FLAG(verbose));
|
||||
}
|
||||
|
||||
TEST(WideInitGoogleMockTest, ParsesSingleFlag) {
|
||||
const wchar_t* argv[] = {
|
||||
L"foo.exe",
|
||||
L"--gmock_verbose=info",
|
||||
NULL
|
||||
};
|
||||
|
||||
const wchar_t* new_argv[] = {
|
||||
L"foo.exe",
|
||||
NULL
|
||||
};
|
||||
|
||||
TestInitGoogleMock(argv, new_argv, "info");
|
||||
}
|
||||
|
||||
TEST(WideInitGoogleMockTest, ParsesUnrecognizedFlag) {
|
||||
const wchar_t* argv[] = {
|
||||
L"foo.exe",
|
||||
L"--non_gmock_flag=blah",
|
||||
NULL
|
||||
};
|
||||
|
||||
const wchar_t* new_argv[] = {
|
||||
L"foo.exe",
|
||||
L"--non_gmock_flag=blah",
|
||||
NULL
|
||||
};
|
||||
|
||||
TestInitGoogleMock(argv, new_argv, GMOCK_FLAG(verbose));
|
||||
}
|
||||
|
||||
TEST(WideInitGoogleMockTest, ParsesGoogleMockFlagAndUnrecognizedFlag) {
|
||||
const wchar_t* argv[] = {
|
||||
L"foo.exe",
|
||||
L"--non_gmock_flag=blah",
|
||||
L"--gmock_verbose=error",
|
||||
NULL
|
||||
};
|
||||
|
||||
const wchar_t* new_argv[] = {
|
||||
L"foo.exe",
|
||||
L"--non_gmock_flag=blah",
|
||||
NULL
|
||||
};
|
||||
|
||||
TestInitGoogleMock(argv, new_argv, "error");
|
||||
}
|
||||
|
||||
TEST(WideInitGoogleMockTest, CallsInitGoogleTest) {
|
||||
const int old_init_gtest_count = g_init_gtest_count;
|
||||
const wchar_t* argv[] = {
|
||||
L"foo.exe",
|
||||
L"--non_gmock_flag=blah",
|
||||
L"--gmock_verbose=error",
|
||||
NULL
|
||||
};
|
||||
|
||||
const wchar_t* new_argv[] = {
|
||||
L"foo.exe",
|
||||
L"--non_gmock_flag=blah",
|
||||
NULL
|
||||
};
|
||||
|
||||
TestInitGoogleMock(argv, new_argv, "error");
|
||||
EXPECT_EQ(old_init_gtest_count + 1, g_init_gtest_count);
|
||||
}
|
||||
|
||||
// Makes sure Google Mock flags can be accessed in code.
|
||||
TEST(FlagTest, IsAccessibleInCode) {
|
||||
bool dummy = testing::GMOCK_FLAG(catch_leaked_mocks) &&
|
||||
testing::GMOCK_FLAG(verbose) == "";
|
||||
dummy = dummy; // Avoids the "unused local variable" warning.
|
||||
}
|
||||
Arquivo executável
+126
@@ -0,0 +1,126 @@
|
||||
#!/usr/bin/python2.4
|
||||
#
|
||||
# Copyright 2006, 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.
|
||||
|
||||
"""Unit test utilities for Google C++ Mocking Framework."""
|
||||
|
||||
__author__ = 'wan@google.com (Zhanyong Wan)'
|
||||
|
||||
import os
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
|
||||
# Initially maps a flag to its default value. After
|
||||
# _ParseAndStripGMockFlags() is called, maps a flag to its actual
|
||||
# value.
|
||||
_flag_map = {'gmock_source_dir': os.path.dirname(sys.argv[0]),
|
||||
'gmock_build_dir': os.path.dirname(sys.argv[0])}
|
||||
_gmock_flags_are_parsed = False
|
||||
|
||||
|
||||
def _ParseAndStripGMockFlags(argv):
|
||||
"""Parses and strips Google Test flags from argv. This is idempotent."""
|
||||
|
||||
global _gmock_flags_are_parsed
|
||||
if _gmock_flags_are_parsed:
|
||||
return
|
||||
|
||||
_gmock_flags_are_parsed = True
|
||||
for flag in _flag_map:
|
||||
# The environment variable overrides the default value.
|
||||
if flag.upper() in os.environ:
|
||||
_flag_map[flag] = os.environ[flag.upper()]
|
||||
|
||||
# The command line flag overrides the environment variable.
|
||||
i = 1 # Skips the program name.
|
||||
while i < len(argv):
|
||||
prefix = '--' + flag + '='
|
||||
if argv[i].startswith(prefix):
|
||||
_flag_map[flag] = argv[i][len(prefix):]
|
||||
del argv[i]
|
||||
break
|
||||
else:
|
||||
# We don't increment i in case we just found a --gmock_* flag
|
||||
# and removed it from argv.
|
||||
i += 1
|
||||
|
||||
|
||||
def GetFlag(flag):
|
||||
"""Returns the value of the given flag."""
|
||||
|
||||
# In case GetFlag() is called before Main(), we always call
|
||||
# _ParseAndStripGMockFlags() here to make sure the --gmock_* flags
|
||||
# are parsed.
|
||||
_ParseAndStripGMockFlags(sys.argv)
|
||||
|
||||
return _flag_map[flag]
|
||||
|
||||
|
||||
def GetSourceDir():
|
||||
"""Returns the absolute path of the directory where the .py files are."""
|
||||
|
||||
return os.path.abspath(GetFlag('gmock_source_dir'))
|
||||
|
||||
|
||||
def GetBuildDir():
|
||||
"""Returns the absolute path of the directory where the test binaries are."""
|
||||
|
||||
return os.path.abspath(GetFlag('gmock_build_dir'))
|
||||
|
||||
|
||||
def GetExitStatus(exit_code):
|
||||
"""Returns the argument to exit(), or -1 if exit() wasn't called.
|
||||
|
||||
Args:
|
||||
exit_code: the result value of os.system(command).
|
||||
"""
|
||||
|
||||
if os.name == 'nt':
|
||||
# On Windows, os.WEXITSTATUS() doesn't work and os.system() returns
|
||||
# the argument to exit() directly.
|
||||
return exit_code
|
||||
else:
|
||||
# On Unix, os.WEXITSTATUS() must be used to extract the exit status
|
||||
# from the result of os.system().
|
||||
if os.WIFEXITED(exit_code):
|
||||
return os.WEXITSTATUS(exit_code)
|
||||
else:
|
||||
return -1
|
||||
|
||||
|
||||
def Main():
|
||||
"""Runs the unit test."""
|
||||
|
||||
# We must call _ParseAndStripGMockFlags() before calling
|
||||
# unittest.main(). Otherwise the latter will be confused by the
|
||||
# --gmock_* flags.
|
||||
_ParseAndStripGMockFlags(sys.argv)
|
||||
unittest.main()
|
||||
+1
-5
@@ -3,9 +3,6 @@
|
||||
# found in the LICENSE file.
|
||||
|
||||
{
|
||||
'variables': {
|
||||
'chromium_code': 1,
|
||||
},
|
||||
'includes': [
|
||||
'../build/common.gypi',
|
||||
],
|
||||
@@ -56,8 +53,7 @@
|
||||
'UNIT_TEST',
|
||||
],
|
||||
'include_dirs': [
|
||||
'gtest',
|
||||
'gtest/include',
|
||||
'gtest/include', # So that gtest headers can find themselves.
|
||||
],
|
||||
'target_conditions': [
|
||||
['_type=="executable"', {'test': 1}],
|
||||
|
||||
externo
+1
-3
@@ -413,9 +413,7 @@
|
||||
],
|
||||
'direct_dependent_settings': {
|
||||
'include_dirs': [
|
||||
# TODO(ajwong): Enable with the gmock checkin.
|
||||
# 'boost_1_36_0/boost/tr1/tr1',
|
||||
# 'boost_1_36_0',
|
||||
'boost_1_36_0',
|
||||
],
|
||||
},
|
||||
}
|
||||
|
||||
Referência em uma Nova Issue
Bloquear um usuário