Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
G
googletest
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Chen Yisong
googletest
Commits
45fef502
Commit
45fef502
authored
Sep 06, 2013
by
zhanyong.wan
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
makes googlemock generator handle some class templates; pulls in gtest r662
parent
778358e3
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
103 additions
and
14 deletions
+103
-14
CHANGES
CHANGES
+2
-0
ast.py
scripts/generator/cpp/ast.py
+1
-1
gmock_class.py
scripts/generator/cpp/gmock_class.py
+20
-2
gmock_class_test.py
scripts/generator/cpp/gmock_class_test.py
+50
-0
gmock_leak_test.py
test/gmock_leak_test.py
+26
-8
gmock_test_utils.py
test/gmock_test_utils.py
+4
-3
No files found.
CHANGES
View file @
45fef502
...
@@ -23,6 +23,8 @@ Changes for 1.7.0:
...
@@ -23,6 +23,8 @@ Changes for 1.7.0:
* Improvement: the ElementsAreArray() matcher can now take a vector or
* Improvement: the ElementsAreArray() matcher can now take a vector or
iterator range as input, and makes a copy of its input elements
iterator range as input, and makes a copy of its input elements
before the conversion to a Matcher.
before the conversion to a Matcher.
* Improvement: the Google Mock Generator can now generate mocks for
some class templates.
* Bug fix: mock object destruction triggerred by another mock object's
* Bug fix: mock object destruction triggerred by another mock object's
destruction no longer hangs.
destruction no longer hangs.
* Improvement: Google Mock Doctor works better with newer Clang and
* Improvement: Google Mock Doctor works better with newer Clang and
...
...
scripts/generator/cpp/ast.py
View file @
45fef502
...
@@ -1546,7 +1546,7 @@ class AstBuilder(object):
...
@@ -1546,7 +1546,7 @@ class AstBuilder(object):
self
.
_AddBackToken
(
token
)
self
.
_AddBackToken
(
token
)
return
class_type
(
class_token
.
start
,
class_token
.
end
,
class_name
,
return
class_type
(
class_token
.
start
,
class_token
.
end
,
class_name
,
bases
,
None
,
body
,
self
.
namespace_stack
)
bases
,
templated_types
,
body
,
self
.
namespace_stack
)
def
handle_namespace
(
self
):
def
handle_namespace
(
self
):
token
=
self
.
_GetNextToken
()
token
=
self
.
_GetNextToken
()
...
...
scripts/generator/cpp/gmock_class.py
View file @
45fef502
...
@@ -88,7 +88,11 @@ def _GenerateMethods(output_lines, source, class_node):
...
@@ -88,7 +88,11 @@ def _GenerateMethods(output_lines, source, class_node):
if
source
[
first_param
.
start
:
first_param
.
end
]
.
strip
()
==
'void'
:
if
source
[
first_param
.
start
:
first_param
.
end
]
.
strip
()
==
'void'
:
# We must treat T(void) as a function with no parameters.
# We must treat T(void) as a function with no parameters.
num_parameters
=
0
num_parameters
=
0
mock_method_macro
=
'MOCK_
%
sMETHOD
%
d'
%
(
const
,
num_parameters
)
tmpl
=
''
if
class_node
.
templated_types
:
tmpl
=
'_T'
mock_method_macro
=
'MOCK_
%
sMETHOD
%
d
%
s'
%
(
const
,
num_parameters
,
tmpl
)
args
=
''
args
=
''
if
node
.
parameters
:
if
node
.
parameters
:
# Due to the parser limitations, it is impossible to keep comments
# Due to the parser limitations, it is impossible to keep comments
...
@@ -126,6 +130,7 @@ def _GenerateMocks(filename, source, ast_list, desired_class_names):
...
@@ -126,6 +130,7 @@ def _GenerateMocks(filename, source, ast_list, desired_class_names):
# desired_class_names being None means that all classes are selected.
# desired_class_names being None means that all classes are selected.
(
not
desired_class_names
or
node
.
name
in
desired_class_names
)):
(
not
desired_class_names
or
node
.
name
in
desired_class_names
)):
class_name
=
node
.
name
class_name
=
node
.
name
parent_name
=
class_name
processed_class_names
.
add
(
class_name
)
processed_class_names
.
add
(
class_name
)
class_node
=
node
class_node
=
node
# Add namespace before the class.
# Add namespace before the class.
...
@@ -133,8 +138,21 @@ def _GenerateMocks(filename, source, ast_list, desired_class_names):
...
@@ -133,8 +138,21 @@ def _GenerateMocks(filename, source, ast_list, desired_class_names):
lines
.
extend
([
'namespace
%
s {'
%
n
for
n
in
class_node
.
namespace
])
# }
lines
.
extend
([
'namespace
%
s {'
%
n
for
n
in
class_node
.
namespace
])
# }
lines
.
append
(
''
)
lines
.
append
(
''
)
# Add template args for templated classes.
if
class_node
.
templated_types
:
# TODO(paulchang): The AST doesn't preserve template argument order,
# so we have to make up names here.
# TODO(paulchang): Handle non-type template arguments (e.g.
# template<typename T, int N>).
template_arg_count
=
len
(
class_node
.
templated_types
.
keys
())
template_args
=
[
'T
%
d'
%
n
for
n
in
range
(
template_arg_count
)]
template_decls
=
[
'typename '
+
arg
for
arg
in
template_args
]
lines
.
append
(
'template <'
+
', '
.
join
(
template_decls
)
+
'>'
)
parent_name
+=
'<'
+
', '
.
join
(
template_args
)
+
'>'
# Add the class prolog.
# Add the class prolog.
lines
.
append
(
'class Mock
%
s : public
%
s {'
%
(
class_name
,
class_name
))
# }
lines
.
append
(
'class Mock
%
s : public
%
s {'
# }
%
(
class_name
,
parent_name
))
lines
.
append
(
'
%
spublic:'
%
(
' '
*
(
_INDENT
//
2
)))
lines
.
append
(
'
%
spublic:'
%
(
' '
*
(
_INDENT
//
2
)))
# Add all the methods.
# Add all the methods.
...
...
scripts/generator/cpp/gmock_class_test.py
View file @
45fef502
...
@@ -196,6 +196,18 @@ class Foo {
...
@@ -196,6 +196,18 @@ class Foo {
'MOCK_METHOD0(Bar,
\n
map<int, string>());'
,
'MOCK_METHOD0(Bar,
\n
map<int, string>());'
,
self
.
GenerateMethodSource
(
source
))
self
.
GenerateMethodSource
(
source
))
def
testSimpleMethodInTemplatedClass
(
self
):
source
=
"""
template<class T>
class Foo {
public:
virtual int Bar();
};
"""
self
.
assertEqualIgnoreLeadingWhitespace
(
'MOCK_METHOD0_T(Bar,
\n
int());'
,
self
.
GenerateMethodSource
(
source
))
class
GenerateMocksTest
(
TestCase
):
class
GenerateMocksTest
(
TestCase
):
...
@@ -255,5 +267,43 @@ void());
...
@@ -255,5 +267,43 @@ void());
self
.
assertEqualIgnoreLeadingWhitespace
(
self
.
assertEqualIgnoreLeadingWhitespace
(
expected
,
self
.
GenerateMocks
(
source
))
expected
,
self
.
GenerateMocks
(
source
))
def
testTemplatedForwardDeclaration
(
self
):
source
=
"""
template <class T> class Forward; // Forward declaration should be ignored.
class Test {
public:
virtual void Foo();
};
"""
expected
=
"""
\
class MockTest : public Test {
public:
MOCK_METHOD0(Foo,
void());
};
"""
self
.
assertEqualIgnoreLeadingWhitespace
(
expected
,
self
.
GenerateMocks
(
source
))
def
testTemplatedClass
(
self
):
source
=
"""
template <typename S, typename T>
class Test {
public:
virtual void Foo();
};
"""
expected
=
"""
\
template <typename T0, typename T1>
class MockTest : public Test<T0, T1> {
public:
MOCK_METHOD0_T(Foo,
void());
};
"""
self
.
assertEqualIgnoreLeadingWhitespace
(
expected
,
self
.
GenerateMocks
(
source
))
if
__name__
==
'__main__'
:
if
__name__
==
'__main__'
:
unittest
.
main
()
unittest
.
main
()
test/gmock_leak_test.py
View file @
45fef502
...
@@ -42,48 +42,66 @@ TEST_WITH_EXPECT_CALL = [PROGRAM_PATH, '--gtest_filter=*ExpectCall*']
...
@@ -42,48 +42,66 @@ TEST_WITH_EXPECT_CALL = [PROGRAM_PATH, '--gtest_filter=*ExpectCall*']
TEST_WITH_ON_CALL
=
[
PROGRAM_PATH
,
'--gtest_filter=*OnCall*'
]
TEST_WITH_ON_CALL
=
[
PROGRAM_PATH
,
'--gtest_filter=*OnCall*'
]
TEST_MULTIPLE_LEAKS
=
[
PROGRAM_PATH
,
'--gtest_filter=*MultipleLeaked*'
]
TEST_MULTIPLE_LEAKS
=
[
PROGRAM_PATH
,
'--gtest_filter=*MultipleLeaked*'
]
environ
=
gmock_test_utils
.
environ
SetEnvVar
=
gmock_test_utils
.
SetEnvVar
# Tests in this file run a Google-Test-based test program and expect it
# to terminate prematurely. Therefore they are incompatible with
# the premature-exit-file protocol by design. Unset the
# premature-exit filepath to prevent Google Test from creating
# the file.
SetEnvVar
(
gmock_test_utils
.
PREMATURE_EXIT_FILE_ENV_VAR
,
None
)
class
GMockLeakTest
(
gmock_test_utils
.
TestCase
):
class
GMockLeakTest
(
gmock_test_utils
.
TestCase
):
def
testCatchesLeakedMockByDefault
(
self
):
def
testCatchesLeakedMockByDefault
(
self
):
self
.
assertNotEqual
(
self
.
assertNotEqual
(
0
,
0
,
gmock_test_utils
.
Subprocess
(
TEST_WITH_EXPECT_CALL
)
.
exit_code
)
gmock_test_utils
.
Subprocess
(
TEST_WITH_EXPECT_CALL
,
env
=
environ
)
.
exit_code
)
self
.
assertNotEqual
(
self
.
assertNotEqual
(
0
,
0
,
gmock_test_utils
.
Subprocess
(
TEST_WITH_ON_CALL
)
.
exit_code
)
gmock_test_utils
.
Subprocess
(
TEST_WITH_ON_CALL
,
env
=
environ
)
.
exit_code
)
def
testDoesNotCatchLeakedMockWhenDisabled
(
self
):
def
testDoesNotCatchLeakedMockWhenDisabled
(
self
):
self
.
assertEquals
(
self
.
assertEquals
(
0
,
0
,
gmock_test_utils
.
Subprocess
(
TEST_WITH_EXPECT_CALL
+
gmock_test_utils
.
Subprocess
(
TEST_WITH_EXPECT_CALL
+
[
'--gmock_catch_leaked_mocks=0'
])
.
exit_code
)
[
'--gmock_catch_leaked_mocks=0'
],
env
=
environ
)
.
exit_code
)
self
.
assertEquals
(
self
.
assertEquals
(
0
,
0
,
gmock_test_utils
.
Subprocess
(
TEST_WITH_ON_CALL
+
gmock_test_utils
.
Subprocess
(
TEST_WITH_ON_CALL
+
[
'--gmock_catch_leaked_mocks=0'
])
.
exit_code
)
[
'--gmock_catch_leaked_mocks=0'
],
env
=
environ
)
.
exit_code
)
def
testCatchesLeakedMockWhenEnabled
(
self
):
def
testCatchesLeakedMockWhenEnabled
(
self
):
self
.
assertNotEqual
(
self
.
assertNotEqual
(
0
,
0
,
gmock_test_utils
.
Subprocess
(
TEST_WITH_EXPECT_CALL
+
gmock_test_utils
.
Subprocess
(
TEST_WITH_EXPECT_CALL
+
[
'--gmock_catch_leaked_mocks'
])
.
exit_code
)
[
'--gmock_catch_leaked_mocks'
],
env
=
environ
)
.
exit_code
)
self
.
assertNotEqual
(
self
.
assertNotEqual
(
0
,
0
,
gmock_test_utils
.
Subprocess
(
TEST_WITH_ON_CALL
+
gmock_test_utils
.
Subprocess
(
TEST_WITH_ON_CALL
+
[
'--gmock_catch_leaked_mocks'
])
.
exit_code
)
[
'--gmock_catch_leaked_mocks'
],
env
=
environ
)
.
exit_code
)
def
testCatchesLeakedMockWhenEnabledWithExplictFlagValue
(
self
):
def
testCatchesLeakedMockWhenEnabledWithExplictFlagValue
(
self
):
self
.
assertNotEqual
(
self
.
assertNotEqual
(
0
,
0
,
gmock_test_utils
.
Subprocess
(
TEST_WITH_EXPECT_CALL
+
gmock_test_utils
.
Subprocess
(
TEST_WITH_EXPECT_CALL
+
[
'--gmock_catch_leaked_mocks=1'
])
.
exit_code
)
[
'--gmock_catch_leaked_mocks=1'
],
env
=
environ
)
.
exit_code
)
def
testCatchesMultipleLeakedMocks
(
self
):
def
testCatchesMultipleLeakedMocks
(
self
):
self
.
assertNotEqual
(
self
.
assertNotEqual
(
0
,
0
,
gmock_test_utils
.
Subprocess
(
TEST_MULTIPLE_LEAKS
+
gmock_test_utils
.
Subprocess
(
TEST_MULTIPLE_LEAKS
+
[
'--gmock_catch_leaked_mocks'
])
.
exit_code
)
[
'--gmock_catch_leaked_mocks'
],
env
=
environ
)
.
exit_code
)
if
__name__
==
'__main__'
:
if
__name__
==
'__main__'
:
...
...
test/gmock_test_utils.py
View file @
45fef502
...
@@ -96,11 +96,12 @@ def GetExitStatus(exit_code):
...
@@ -96,11 +96,12 @@ def GetExitStatus(exit_code):
# Suppresses the "Invalid const name" lint complaint
# Suppresses the "Invalid const name" lint complaint
# pylint: disable-msg=C6409
# pylint: disable-msg=C6409
# Exposes
Subproces
s from gtest_test_utils.
# Exposes
utilitie
s from gtest_test_utils.
Subprocess
=
gtest_test_utils
.
Subprocess
Subprocess
=
gtest_test_utils
.
Subprocess
# Exposes TestCase from gtest_test_utils.
TestCase
=
gtest_test_utils
.
TestCase
TestCase
=
gtest_test_utils
.
TestCase
environ
=
gtest_test_utils
.
environ
SetEnvVar
=
gtest_test_utils
.
SetEnvVar
PREMATURE_EXIT_FILE_ENV_VAR
=
gtest_test_utils
.
PREMATURE_EXIT_FILE_ENV_VAR
# pylint: enable-msg=C6409
# pylint: enable-msg=C6409
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment