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
360f5f70
Commit
360f5f70
authored
Feb 10, 2020
by
Abseil Team
Committed by
Mark Barolak
Feb 11, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Googletest export
Fix gmock_gen to use MOCK_METHOD instead of old style macros. PiperOrigin-RevId: 294332975
parent
139fa202
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
371 additions
and
406 deletions
+371
-406
gmock_class.py
googlemock/scripts/generator/cpp/gmock_class.py
+164
-184
gmock_class_test.py
googlemock/scripts/generator/cpp/gmock_class_test.py
+207
-222
No files found.
googlemock/scripts/generator/cpp/gmock_class.py
View file @
360f5f70
...
...
@@ -35,11 +35,11 @@ from cpp import utils
# Preserve compatibility with Python 2.3.
try
:
_dummy
=
set
_dummy
=
set
except
NameError
:
import
sets
import
sets
set
=
sets
.
Set
set
=
sets
.
Set
_VERSION
=
(
1
,
0
,
1
)
# The version of this script.
# How many spaces to indent. Can set me with the INDENT environment variable.
...
...
@@ -47,202 +47,182 @@ _INDENT = 2
def
_RenderType
(
ast_type
):
"""Renders the potentially recursively templated type into a string.
"""Renders the potentially recursively templated type into a string.
Args:
ast_type: The AST of the type.
Returns:
Rendered string and a boolean to indicate whether we have multiple args
(which is not handled correctly).
Rendered string of the type
"""
has_multiarg_error
=
False
# Add modifiers like 'const'.
modifiers
=
''
if
ast_type
.
modifiers
:
modifiers
=
' '
.
join
(
ast_type
.
modifiers
)
+
' '
return_type
=
modifiers
+
ast_type
.
name
if
ast_type
.
templated_types
:
# Collect template args.
template_args
=
[]
for
arg
in
ast_type
.
templated_types
:
rendered_arg
,
e
=
_RenderType
(
arg
)
if
e
:
has_multiarg_error
=
True
template_args
.
append
(
rendered_arg
)
return_type
+=
'<'
+
', '
.
join
(
template_args
)
+
'>'
# We are actually not handling multi-template-args correctly. So mark it.
if
len
(
template_args
)
>
1
:
has_multiarg_error
=
True
if
ast_type
.
pointer
:
return_type
+=
'*'
if
ast_type
.
reference
:
return_type
+=
'&'
return
return_type
,
has_multiarg_error
def
_GetNumParameters
(
parameters
,
source
):
num_parameters
=
len
(
parameters
)
if
num_parameters
==
1
:
first_param
=
parameters
[
0
]
if
source
[
first_param
.
start
:
first_param
.
end
]
.
strip
()
==
'void'
:
# We must treat T(void) as a function with no parameters.
return
0
return
num_parameters
# Add modifiers like 'const'.
modifiers
=
''
if
ast_type
.
modifiers
:
modifiers
=
' '
.
join
(
ast_type
.
modifiers
)
+
' '
return_type
=
modifiers
+
ast_type
.
name
if
ast_type
.
templated_types
:
# Collect template args.
template_args
=
[]
for
arg
in
ast_type
.
templated_types
:
rendered_arg
=
_RenderType
(
arg
)
template_args
.
append
(
rendered_arg
)
return_type
+=
'<'
+
', '
.
join
(
template_args
)
+
'>'
if
ast_type
.
pointer
:
return_type
+=
'*'
if
ast_type
.
reference
:
return_type
+=
'&'
return
return_type
def
_GenerateMethods
(
output_lines
,
source
,
class_node
):
function_type
=
(
ast
.
FUNCTION_VIRTUAL
|
ast
.
FUNCTION_PURE_VIRTUAL
|
ast
.
FUNCTION_OVERRIDE
)
ctor_or_dtor
=
ast
.
FUNCTION_CTOR
|
ast
.
FUNCTION_DTOR
indent
=
' '
*
_INDENT
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_'
num_parameters
=
_GetNumParameters
(
node
.
parameters
,
source
)
return_type
=
'void'
if
node
.
return_type
:
return_type
,
has_multiarg_error
=
_RenderType
(
node
.
return_type
)
if
has_multiarg_error
:
for
line
in
[
'// The following line won
\'
t really compile, as the return'
,
'// type has multiple template arguments. To fix it, use a'
,
'// typedef for the return type.'
]:
output_lines
.
append
(
indent
+
line
)
tmpl
=
''
if
class_node
.
templated_types
:
tmpl
=
'_T'
mock_method_macro
=
'MOCK_
%
sMETHOD
%
d
%
s'
%
(
const
,
num_parameters
,
tmpl
)
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
# Remove // comments.
args_strings
=
re
.
sub
(
r'//.*'
,
''
,
source
[
start
:
end
])
# Remove /* comments */.
args_strings
=
re
.
sub
(
r'/\*.*\*/'
,
''
,
args_strings
)
# Remove default arguments.
args_strings
=
re
.
sub
(
r'=.*,'
,
','
,
args_strings
)
args_strings
=
re
.
sub
(
r'=.*'
,
''
,
args_strings
)
# Condense multiple spaces and eliminate newlines putting the
# parameters together on a single line. Ensure there is a
# space in an argument which is split by a newline without
# intervening whitespace, e.g.: int\nBar
args
=
re
.
sub
(
' +'
,
' '
,
args_strings
.
replace
(
'
\n
'
,
' '
))
# Create the mock method definition.
output_lines
.
extend
([
'
%
s
%
s(
%
s,'
%
(
indent
,
mock_method_macro
,
node
.
name
),
'
%
s
%
s(
%
s));'
%
(
indent
*
3
,
return_type
,
args
)])
function_type
=
(
ast
.
FUNCTION_VIRTUAL
|
ast
.
FUNCTION_PURE_VIRTUAL
|
ast
.
FUNCTION_OVERRIDE
)
ctor_or_dtor
=
ast
.
FUNCTION_CTOR
|
ast
.
FUNCTION_DTOR
indent
=
' '
*
_INDENT
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.
modifiers
=
'override'
if
node
.
modifiers
&
ast
.
FUNCTION_CONST
:
modifiers
=
'const, '
+
modifiers
return_type
=
'void'
if
node
.
return_type
:
return_type
=
_RenderType
(
node
.
return_type
)
# commas mess with macros, so nest it in parens if it has one
if
','
in
return_type
:
return_type
=
'('
+
return_type
+
')'
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
# Remove // comments.
args_strings
=
re
.
sub
(
r'//.*'
,
''
,
source
[
start
:
end
])
# Remove /* comments */.
args_strings
=
re
.
sub
(
r'/\*.*\*/'
,
''
,
args_strings
)
# Remove default arguments.
args_strings
=
re
.
sub
(
r'=.*,'
,
','
,
args_strings
)
args_strings
=
re
.
sub
(
r'=.*'
,
''
,
args_strings
)
# Condense multiple spaces and eliminate newlines putting the
# parameters together on a single line. Ensure there is a
# space in an argument which is split by a newline without
# intervening whitespace, e.g.: int\nBar
args_strings
=
re
.
sub
(
' +'
,
' '
,
args_strings
.
replace
(
'
\n
'
,
' '
))
# Remove spaces from the begining, end, and before commas
args
=
re
.
sub
(
' ,'
,
','
,
args_strings
)
.
strip
()
# Create the mock method definition.
output_lines
.
extend
([
'
%
sMOCK_METHOD(
%
s,
%
s, (
%
s), (
%
s));'
%
(
indent
,
return_type
,
node
.
name
,
args
,
modifiers
)
])
def
_GenerateMocks
(
filename
,
source
,
ast_list
,
desired_class_names
):
processed_class_names
=
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
parent_name
=
class_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 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.
lines
.
append
(
'class Mock
%
s : public
%
s {'
# }
%
(
class_name
,
parent_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.
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
)
return
lines
processed_class_names
=
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
parent_name
=
class_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 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.
lines
.
append
(
'class Mock
%
s : public
%
s {'
# }
%
(
class_name
,
parent_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.
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
)
return
lines
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
=
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.
sys
.
exit
(
1
)
else
:
lines
=
_GenerateMocks
(
filename
,
source
,
entire_ast
,
desired_class_names
)
sys
.
stdout
.
write
(
'
\n
'
.
join
(
lines
))
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
=
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.
sys
.
exit
(
1
)
else
:
lines
=
_GenerateMocks
(
filename
,
source
,
entire_ast
,
desired_class_names
)
sys
.
stdout
.
write
(
'
\n
'
.
join
(
lines
))
if
__name__
==
'__main__'
:
main
(
sys
.
argv
)
main
(
sys
.
argv
)
googlemock/scripts/generator/cpp/gmock_class_test.py
View file @
360f5f70
...
...
@@ -29,43 +29,43 @@ from cpp import gmock_class
class
TestCase
(
unittest
.
TestCase
):
"""Helper class that adds assert methods."""
"""Helper class that adds assert methods."""
@staticmethod
def
StripLeadingWhitespace
(
lines
):
"""Strip leading whitespace in each line in 'lines'."""
return
'
\n
'
.
join
([
s
.
lstrip
()
for
s
in
lines
.
split
(
'
\n
'
)])
@staticmethod
def
StripLeadingWhitespace
(
lines
):
"""Strip leading whitespace in each line in 'lines'."""
return
'
\n
'
.
join
([
s
.
lstrip
()
for
s
in
lines
.
split
(
'
\n
'
)])
def
assertEqualIgnoreLeadingWhitespace
(
self
,
expected_lines
,
lines
):
"""Specialized assert that ignores the indent level."""
self
.
assertEqual
(
expected_lines
,
self
.
StripLeadingWhitespace
(
lines
))
def
assertEqualIgnoreLeadingWhitespace
(
self
,
expected_lines
,
lines
):
"""Specialized assert that ignores the indent level."""
self
.
assertEqual
(
expected_lines
,
self
.
StripLeadingWhitespace
(
lines
))
class
GenerateMethodsTest
(
TestCase
):
@staticmethod
def
GenerateMethodSource
(
cpp_source
):
"""Convert C++ source to Google Mock output source lines."""
method_source_lines
=
[]
# <test> is a pseudo-filename, it is not read or written.
builder
=
ast
.
BuilderFromSource
(
cpp_source
,
'<test>'
)
ast_list
=
list
(
builder
.
Generate
())
gmock_class
.
_GenerateMethods
(
method_source_lines
,
cpp_source
,
ast_list
[
0
])
return
'
\n
'
.
join
(
method_source_lines
)
def
testSimpleMethod
(
self
):
source
=
"""
@staticmethod
def
GenerateMethodSource
(
cpp_source
):
"""Convert C++ source to Google Mock output source lines."""
method_source_lines
=
[]
# <test> is a pseudo-filename, it is not read or written.
builder
=
ast
.
BuilderFromSource
(
cpp_source
,
'<test>'
)
ast_list
=
list
(
builder
.
Generate
())
gmock_class
.
_GenerateMethods
(
method_source_lines
,
cpp_source
,
ast_list
[
0
])
return
'
\n
'
.
join
(
method_source_lines
)
def
testSimpleMethod
(
self
):
source
=
"""
class Foo {
public:
virtual int Bar();
};
"""
self
.
assertEqualIgnoreLeadingWhitespace
(
'MOCK_METHOD0(Bar,
\n
int(
));'
,
self
.
GenerateMethodSource
(
source
))
self
.
assertEqualIgnoreLeadingWhitespace
(
'MOCK_METHOD(int, Bar, (), (override
));'
,
self
.
GenerateMethodSource
(
source
))
def
testSimpleConstructorsAndDestructor
(
self
):
source
=
"""
def
testSimpleConstructorsAndDestructor
(
self
):
source
=
"""
class Foo {
public:
Foo();
...
...
@@ -76,26 +76,26 @@ class Foo {
virtual int Bar() = 0;
};
"""
# The constructors and destructor should be ignored.
self
.
assertEqualIgnoreLeadingWhitespace
(
'MOCK_METHOD0(Bar,
\n
int(
));'
,
self
.
GenerateMethodSource
(
source
))
# The constructors and destructor should be ignored.
self
.
assertEqualIgnoreLeadingWhitespace
(
'MOCK_METHOD(int, Bar, (), (override
));'
,
self
.
GenerateMethodSource
(
source
))
def
testVirtualDestructor
(
self
):
source
=
"""
def
testVirtualDestructor
(
self
):
source
=
"""
class Foo {
public:
virtual ~Foo();
virtual int Bar() = 0;
};
"""
# The destructor should be ignored.
self
.
assertEqualIgnoreLeadingWhitespace
(
'MOCK_METHOD0(Bar,
\n
int(
));'
,
self
.
GenerateMethodSource
(
source
))
# The destructor should be ignored.
self
.
assertEqualIgnoreLeadingWhitespace
(
'MOCK_METHOD(int, Bar, (), (override
));'
,
self
.
GenerateMethodSource
(
source
))
def
testExplicitlyDefaultedConstructorsAndDestructor
(
self
):
source
=
"""
def
testExplicitlyDefaultedConstructorsAndDestructor
(
self
):
source
=
"""
class Foo {
public:
Foo() = default;
...
...
@@ -105,13 +105,13 @@ class Foo {
virtual int Bar() = 0;
};
"""
# The constructors and destructor should be ignored.
self
.
assertEqualIgnoreLeadingWhitespace
(
'MOCK_METHOD0(Bar,
\n
int(
));'
,
self
.
GenerateMethodSource
(
source
))
# The constructors and destructor should be ignored.
self
.
assertEqualIgnoreLeadingWhitespace
(
'MOCK_METHOD(int, Bar, (), (override
));'
,
self
.
GenerateMethodSource
(
source
))
def
testExplicitlyDeletedConstructorsAndDestructor
(
self
):
source
=
"""
def
testExplicitlyDeletedConstructorsAndDestructor
(
self
):
source
=
"""
class Foo {
public:
Foo() = delete;
...
...
@@ -121,69 +121,69 @@ class Foo {
virtual int Bar() = 0;
};
"""
# The constructors and destructor should be ignored.
self
.
assertEqualIgnoreLeadingWhitespace
(
'MOCK_METHOD0(Bar,
\n
int(
));'
,
self
.
GenerateMethodSource
(
source
))
# The constructors and destructor should be ignored.
self
.
assertEqualIgnoreLeadingWhitespace
(
'MOCK_METHOD(int, Bar, (), (override
));'
,
self
.
GenerateMethodSource
(
source
))
def
testSimpleOverrideMethod
(
self
):
source
=
"""
def
testSimpleOverrideMethod
(
self
):
source
=
"""
class Foo {
public:
int Bar() override;
};
"""
self
.
assertEqualIgnoreLeadingWhitespace
(
'MOCK_METHOD0(Bar,
\n
int(
));'
,
self
.
GenerateMethodSource
(
source
))
self
.
assertEqualIgnoreLeadingWhitespace
(
'MOCK_METHOD(int, Bar, (), (override
));'
,
self
.
GenerateMethodSource
(
source
))
def
testSimpleConstMethod
(
self
):
source
=
"""
def
testSimpleConstMethod
(
self
):
source
=
"""
class Foo {
public:
virtual void Bar(bool flag) const;
};
"""
self
.
assertEqualIgnoreLeadingWhitespace
(
'MOCK_CONST_METHOD1(Bar,
\n
void(bool flag
));'
,
self
.
GenerateMethodSource
(
source
))
self
.
assertEqualIgnoreLeadingWhitespace
(
'MOCK_METHOD(void, Bar, (bool flag), (const, override
));'
,
self
.
GenerateMethodSource
(
source
))
def
testExplicitVoid
(
self
):
source
=
"""
def
testExplicitVoid
(
self
):
source
=
"""
class Foo {
public:
virtual int Bar(void);
};
"""
self
.
assertEqualIgnoreLeadingWhitespace
(
'MOCK_METHOD0(Bar,
\n
int(void
));'
,
self
.
GenerateMethodSource
(
source
))
self
.
assertEqualIgnoreLeadingWhitespace
(
'MOCK_METHOD(int, Bar, (void), (override
));'
,
self
.
GenerateMethodSource
(
source
))
def
testStrangeNewlineInParameter
(
self
):
source
=
"""
def
testStrangeNewlineInParameter
(
self
):
source
=
"""
class Foo {
public:
virtual void Bar(int
a) = 0;
};
"""
self
.
assertEqualIgnoreLeadingWhitespace
(
'MOCK_METHOD1(Bar,
\n
void(int a
));'
,
self
.
GenerateMethodSource
(
source
))
self
.
assertEqualIgnoreLeadingWhitespace
(
'MOCK_METHOD(void, Bar, (int a), (override
));'
,
self
.
GenerateMethodSource
(
source
))
def
testDefaultParameters
(
self
):
source
=
"""
def
testDefaultParameters
(
self
):
source
=
"""
class Foo {
public:
virtual void Bar(int a, char c = 'x') = 0;
};
"""
self
.
assertEqualIgnoreLeadingWhitespace
(
'MOCK_METHOD2(Bar,
\n
void(int a, char c
));'
,
self
.
GenerateMethodSource
(
source
))
self
.
assertEqualIgnoreLeadingWhitespace
(
'MOCK_METHOD(void, Bar, (int a, char c), (override
));'
,
self
.
GenerateMethodSource
(
source
))
def
testMultipleDefaultParameters
(
self
):
source
=
"""
def
testMultipleDefaultParameters
(
self
):
source
=
"""
class Foo {
public:
virtual void Bar(
...
...
@@ -195,47 +195,47 @@ class Foo {
int const *& rp = aDefaultPointer) = 0;
};
"""
self
.
assertEqualIgnoreLeadingWhitespace
(
"MOCK_METHOD7(Bar,
\n
"
"void(int a , char c , const int* const p , const std::string& s , char tab[] , int const *& rp ));"
,
self
.
GenerateMethodSource
(
source
))
self
.
assertEqualIgnoreLeadingWhitespace
(
'MOCK_METHOD(void, Bar, '
'(int a, char c, const int* const p, const std::string& s, char tab[], int const *& rp), '
'(override));'
,
self
.
GenerateMethodSource
(
source
))
def
testConstDefaultParameter
(
self
):
source
=
"""
def
testConstDefaultParameter
(
self
):
source
=
"""
class Test {
public:
virtual bool Bar(const int test_arg = 42) = 0;
};
"""
expected
=
'MOCK_METHOD1(Bar,
\n
bool(const int test_arg ));'
self
.
assertEqualIgnoreLeadingWhitespace
(
expected
,
self
.
GenerateMethodSource
(
source
))
self
.
assertEqualIgnoreLeadingWhitespace
(
'MOCK_METHOD(bool, Bar, (const int test_arg), (override));'
,
self
.
GenerateMethodSource
(
source
))
def
testConstRefDefaultParameter
(
self
):
source
=
"""
def
testConstRefDefaultParameter
(
self
):
source
=
"""
class Test {
public:
virtual bool Bar(const std::string& test_arg = "42" ) = 0;
};
"""
expected
=
'MOCK_METHOD1(Bar,
\n
bool(const std::string& test_arg ));'
self
.
assertEqualIgnoreLeadingWhitespace
(
expected
,
self
.
GenerateMethodSource
(
source
))
self
.
assertEqualIgnoreLeadingWhitespace
(
'MOCK_METHOD(bool, Bar, (const std::string& test_arg), (override));'
,
self
.
GenerateMethodSource
(
source
))
def
testRemovesCommentsWhenDefaultsArePresent
(
self
):
source
=
"""
def
testRemovesCommentsWhenDefaultsArePresent
(
self
):
source
=
"""
class Foo {
public:
virtual void Bar(int a = 42 /* a comment */,
char /* other comment */ c= 'x') = 0;
};
"""
self
.
assertEqualIgnoreLeadingWhitespace
(
'MOCK_METHOD2(Bar,
\n
void(int a , char c
));'
,
self
.
GenerateMethodSource
(
source
))
self
.
assertEqualIgnoreLeadingWhitespace
(
'MOCK_METHOD(void, Bar, (int a, char c), (override
));'
,
self
.
GenerateMethodSource
(
source
))
def
testDoubleSlashCommentsInParameterListAreRemoved
(
self
):
source
=
"""
def
testDoubleSlashCommentsInParameterListAreRemoved
(
self
):
source
=
"""
class Foo {
public:
virtual void Bar(int a, // inline comments should be elided.
...
...
@@ -243,117 +243,111 @@ class Foo {
) const = 0;
};
"""
self
.
assertEqualIgnoreLeadingWhitespace
(
'MOCK_CONST_METHOD2(Bar,
\n
void(int a, int b
));'
,
self
.
GenerateMethodSource
(
source
))
self
.
assertEqualIgnoreLeadingWhitespace
(
'MOCK_METHOD(void, Bar, (int a, int b), (const, override
));'
,
self
.
GenerateMethodSource
(
source
))
def
testCStyleCommentsInParameterListAreNotRemoved
(
self
):
# NOTE(nnorwitz): I'm not sure if it's the best behavior to keep these
# comments. Also note that C style comments after the last parameter
# are still elided.
source
=
"""
def
testCStyleCommentsInParameterListAreNotRemoved
(
self
):
# NOTE(nnorwitz): I'm not sure if it's the best behavior to keep these
# comments. Also note that C style comments after the last parameter
# are still elided.
source
=
"""
class Foo {
public:
virtual const string& Bar(int /* keeper */, int b);
};
"""
self
.
assertEqualIgnoreLeadingWhitespace
(
'MOCK_METHOD2(Bar,
\n
const string&(int , int b
));'
,
self
.
GenerateMethodSource
(
source
))
self
.
assertEqualIgnoreLeadingWhitespace
(
'MOCK_METHOD(const string&, Bar, (int, int b), (override
));'
,
self
.
GenerateMethodSource
(
source
))
def
testArgsOfTemplateTypes
(
self
):
source
=
"""
def
testArgsOfTemplateTypes
(
self
):
source
=
"""
class Foo {
public:
virtual int Bar(const vector<int>& v, map<int, string>* output);
};"""
self
.
assertEqualIgnoreLeadingWhitespace
(
'MOCK_METHOD2(Bar,
\n
'
'int(const vector<int>& v, map<int, string>* output));'
,
self
.
GenerateMethodSource
(
source
))
self
.
assertEqualIgnoreLeadingWhitespace
(
'MOCK_METHOD(int, Bar, (const vector<int>& v, map<int, string>* output), (override));'
,
self
.
GenerateMethodSource
(
source
))
def
testReturnTypeWithOneTemplateArg
(
self
):
source
=
"""
def
testReturnTypeWithOneTemplateArg
(
self
):
source
=
"""
class Foo {
public:
virtual vector<int>* Bar(int n);
};"""
self
.
assertEqualIgnoreLeadingWhitespace
(
'MOCK_METHOD1(Bar,
\n
vector<int>*(int n
));'
,
self
.
GenerateMethodSource
(
source
))
self
.
assertEqualIgnoreLeadingWhitespace
(
'MOCK_METHOD(vector<int>*, Bar, (int n), (override
));'
,
self
.
GenerateMethodSource
(
source
))
def
testReturnTypeWithManyTemplateArgs
(
self
):
source
=
"""
def
testReturnTypeWithManyTemplateArgs
(
self
):
source
=
"""
class Foo {
public:
virtual map<int, string> Bar();
};"""
# Comparing the comment text is brittle - we'll think of something
# better in case this gets annoying, but for now let's keep it simple.
self
.
assertEqualIgnoreLeadingWhitespace
(
'// The following line won
\'
t really compile, as the return
\n
'
'// type has multiple template arguments. To fix it, use a
\n
'
'// typedef for the return type.
\n
'
'MOCK_METHOD0(Bar,
\n
map<int, string>());'
,
self
.
GenerateMethodSource
(
source
))
def
testSimpleMethodInTemplatedClass
(
self
):
source
=
"""
self
.
assertEqualIgnoreLeadingWhitespace
(
'MOCK_METHOD((map<int, string>), Bar, (), (override));'
,
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
))
self
.
assertEqualIgnoreLeadingWhitespace
(
'MOCK_METHOD(int, Bar, (), (override
));'
,
self
.
GenerateMethodSource
(
source
))
def
testPointerArgWithoutNames
(
self
):
source
=
"""
def
testPointerArgWithoutNames
(
self
):
source
=
"""
class Foo {
virtual int Bar(C*);
};
"""
self
.
assertEqualIgnoreLeadingWhitespace
(
'MOCK_METHOD1(Bar,
\n
int(C*
));'
,
self
.
GenerateMethodSource
(
source
))
self
.
assertEqualIgnoreLeadingWhitespace
(
'MOCK_METHOD(int, Bar, (C*), (override
));'
,
self
.
GenerateMethodSource
(
source
))
def
testReferenceArgWithoutNames
(
self
):
source
=
"""
def
testReferenceArgWithoutNames
(
self
):
source
=
"""
class Foo {
virtual int Bar(C&);
};
"""
self
.
assertEqualIgnoreLeadingWhitespace
(
'MOCK_METHOD1(Bar,
\n
int(C&
));'
,
self
.
GenerateMethodSource
(
source
))
self
.
assertEqualIgnoreLeadingWhitespace
(
'MOCK_METHOD(int, Bar, (C&), (override
));'
,
self
.
GenerateMethodSource
(
source
))
def
testArrayArgWithoutNames
(
self
):
source
=
"""
def
testArrayArgWithoutNames
(
self
):
source
=
"""
class Foo {
virtual int Bar(C[]);
};
"""
self
.
assertEqualIgnoreLeadingWhitespace
(
'MOCK_METHOD1(Bar,
\n
int(C[]
));'
,
self
.
GenerateMethodSource
(
source
))
self
.
assertEqualIgnoreLeadingWhitespace
(
'MOCK_METHOD(int, Bar, (C[]), (override
));'
,
self
.
GenerateMethodSource
(
source
))
class
GenerateMocksTest
(
TestCase
):
@staticmethod
def
GenerateMocks
(
cpp_source
):
"""Convert C++ source to complete Google Mock output source."""
# <test> is a pseudo-filename, it is not read or written.
filename
=
'<test>'
builder
=
ast
.
BuilderFromSource
(
cpp_source
,
filename
)
ast_list
=
list
(
builder
.
Generate
())
lines
=
gmock_class
.
_GenerateMocks
(
filename
,
cpp_source
,
ast_list
,
None
)
return
'
\n
'
.
join
(
lines
)
def
testNamespaces
(
self
):
source
=
"""
@staticmethod
def
GenerateMocks
(
cpp_source
):
"""Convert C++ source to complete Google Mock output source."""
# <test> is a pseudo-filename, it is not read or written.
filename
=
'<test>'
builder
=
ast
.
BuilderFromSource
(
cpp_source
,
filename
)
ast_list
=
list
(
builder
.
Generate
())
lines
=
gmock_class
.
_GenerateMocks
(
filename
,
cpp_source
,
ast_list
,
None
)
return
'
\n
'
.
join
(
lines
)
def
testNamespaces
(
self
):
source
=
"""
namespace Foo {
namespace Bar { class Forward; }
namespace Baz {
...
...
@@ -366,96 +360,91 @@ class Test {
} // namespace Baz
} // namespace Foo
"""
expected
=
"""
\
expected
=
"""
\
namespace Foo {
namespace Baz {
class MockTest : public Test {
public:
MOCK_METHOD0(Foo,
void());
MOCK_METHOD(void, Foo, (), (override));
};
} // namespace Baz
} // namespace Foo
"""
self
.
assertEqualIgnoreLeadingWhitespace
(
expected
,
self
.
GenerateMocks
(
source
))
self
.
assertEqualIgnoreLeadingWhitespace
(
expected
,
self
.
GenerateMocks
(
source
))
def
testClassWithStorageSpecifierMacro
(
self
):
source
=
"""
def
testClassWithStorageSpecifierMacro
(
self
):
source
=
"""
class STORAGE_SPECIFIER Test {
public:
virtual void Foo();
};
"""
expected
=
"""
\
expected
=
"""
\
class MockTest : public Test {
public:
MOCK_METHOD0(Foo,
void());
MOCK_METHOD(void, Foo, (), (override));
};
"""
self
.
assertEqualIgnoreLeadingWhitespace
(
expected
,
self
.
GenerateMocks
(
source
))
self
.
assertEqualIgnoreLeadingWhitespace
(
expected
,
self
.
GenerateMocks
(
source
))
def
testTemplatedForwardDeclaration
(
self
):
source
=
"""
def
testTemplatedForwardDeclaration
(
self
):
source
=
"""
template <class T> class Forward; // Forward declaration should be ignored.
class Test {
public:
virtual void Foo();
};
"""
expected
=
"""
\
expected
=
"""
\
class MockTest : public Test {
public:
MOCK_METHOD0(Foo,
void());
MOCK_METHOD(void, Foo, (), (override));
};
"""
self
.
assertEqualIgnoreLeadingWhitespace
(
expected
,
self
.
GenerateMocks
(
source
))
self
.
assertEqualIgnoreLeadingWhitespace
(
expected
,
self
.
GenerateMocks
(
source
))
def
testTemplatedClass
(
self
):
source
=
"""
def
testTemplatedClass
(
self
):
source
=
"""
template <typename S, typename T>
class Test {
public:
virtual void Foo();
};
"""
expected
=
"""
\
expected
=
"""
\
template <typename T0, typename T1>
class MockTest : public Test<T0, T1> {
public:
MOCK_METHOD0_T(Foo,
void());
MOCK_METHOD(void, Foo, (), (override));
};
"""
self
.
assertEqualIgnoreLeadingWhitespace
(
expected
,
self
.
GenerateMocks
(
source
))
self
.
assertEqualIgnoreLeadingWhitespace
(
expected
,
self
.
GenerateMocks
(
source
))
def
testTemplateInATemplateTypedef
(
self
):
source
=
"""
def
testTemplateInATemplateTypedef
(
self
):
source
=
"""
class Test {
public:
typedef std::vector<std::list<int>> FooType;
virtual void Bar(const FooType& test_arg);
};
"""
expected
=
"""
\
expected
=
"""
\
class MockTest : public Test {
public:
MOCK_METHOD1(Bar,
void(const FooType& test_arg));
MOCK_METHOD(void, Bar, (const FooType& test_arg), (override));
};
"""
self
.
assertEqualIgnoreLeadingWhitespace
(
expected
,
self
.
GenerateMocks
(
source
))
self
.
assertEqualIgnoreLeadingWhitespace
(
expected
,
self
.
GenerateMocks
(
source
))
def
testTemplateInATemplateTypedefWithComma
(
self
):
source
=
"""
def
testTemplateInATemplateTypedefWithComma
(
self
):
source
=
"""
class Test {
public:
typedef std::function<void(
...
...
@@ -463,18 +452,17 @@ class Test {
virtual void Bar(const FooType& test_arg);
};
"""
expected
=
"""
\
expected
=
"""
\
class MockTest : public Test {
public:
MOCK_METHOD1(Bar,
void(const FooType& test_arg));
MOCK_METHOD(void, Bar, (const FooType& test_arg), (override));
};
"""
self
.
assertEqualIgnoreLeadingWhitespace
(
expected
,
self
.
GenerateMocks
(
source
))
self
.
assertEqualIgnoreLeadingWhitespace
(
expected
,
self
.
GenerateMocks
(
source
))
def
testEnumType
(
self
):
source
=
"""
def
testEnumType
(
self
):
source
=
"""
class Test {
public:
enum Bar {
...
...
@@ -483,18 +471,17 @@ class Test {
virtual void Foo();
};
"""
expected
=
"""
\
expected
=
"""
\
class MockTest : public Test {
public:
MOCK_METHOD0(Foo,
void());
MOCK_METHOD(void, Foo, (), (override));
};
"""
self
.
assertEqualIgnoreLeadingWhitespace
(
expected
,
self
.
GenerateMocks
(
source
))
self
.
assertEqualIgnoreLeadingWhitespace
(
expected
,
self
.
GenerateMocks
(
source
))
def
testEnumClassType
(
self
):
source
=
"""
def
testEnumClassType
(
self
):
source
=
"""
class Test {
public:
enum class Bar {
...
...
@@ -503,18 +490,17 @@ class Test {
virtual void Foo();
};
"""
expected
=
"""
\
expected
=
"""
\
class MockTest : public Test {
public:
MOCK_METHOD0(Foo,
void());
MOCK_METHOD(void, Foo, (), (override));
};
"""
self
.
assertEqualIgnoreLeadingWhitespace
(
expected
,
self
.
GenerateMocks
(
source
))
self
.
assertEqualIgnoreLeadingWhitespace
(
expected
,
self
.
GenerateMocks
(
source
))
def
testStdFunction
(
self
):
source
=
"""
def
testStdFunction
(
self
):
source
=
"""
class Test {
public:
Test(std::function<int(std::string)> foo) : foo_(foo) {}
...
...
@@ -525,16 +511,15 @@ class Test {
std::function<int(std::string)> foo_;
};
"""
expected
=
"""
\
expected
=
"""
\
class MockTest : public Test {
public:
MOCK_METHOD0(foo,
std::function<int (std::string)>());
MOCK_METHOD(std::function<int (std::string)>, foo, (), (override));
};
"""
self
.
assertEqualIgnoreLeadingWhitespace
(
expected
,
self
.
GenerateMocks
(
source
))
self
.
assertEqualIgnoreLeadingWhitespace
(
expected
,
self
.
GenerateMocks
(
source
))
if
__name__
==
'__main__'
:
unittest
.
main
()
unittest
.
main
()
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