Googletest export

Fix gmock_gen to use MOCK_METHOD instead of old style macros.

PiperOrigin-RevId: 294360947
This commit is contained in:
Abseil Team 2020-02-10 22:57:19 -05:00 committed by Mark Barolak
parent 360f5f70a3
commit 56de7cc8b5
2 changed files with 389 additions and 354 deletions

View File

@ -53,8 +53,10 @@ def _RenderType(ast_type):
ast_type: The AST of the type.
Returns:
Rendered string of the type
Rendered string and a boolean to indicate whether we have multiple args
(which is not handled correctly).
"""
has_multiarg_error = False
# Add modifiers like 'const'.
modifiers = ''
if ast_type.modifiers:
@ -64,37 +66,59 @@ def _RenderType(ast_type):
# Collect template args.
template_args = []
for arg in ast_type.templated_types:
rendered_arg = _RenderType(arg)
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
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
def _GenerateMethods(output_lines, source, class_node):
function_type = (
ast.FUNCTION_VIRTUAL | ast.FUNCTION_PURE_VIRTUAL | ast.FUNCTION_OVERRIDE)
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
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'
const = ''
if node.modifiers & ast.FUNCTION_CONST:
modifiers = 'const, ' + modifiers
const = 'CONST_'
num_parameters = _GetNumParameters(node.parameters, source)
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 + ')'
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:
@ -113,15 +137,11 @@ def _GenerateMethods(output_lines, source, class_node):
# 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()
args = re.sub(' +', ' ', args_strings.replace('\n', ' '))
# Create the mock method definition.
output_lines.extend([
'%sMOCK_METHOD(%s, %s, (%s), (%s));' %
(indent, return_type, node.name, args, modifiers)
])
output_lines.extend(['%s%s(%s,' % (indent, mock_method_macro, node.name),
'%s%s(%s));' % (indent * 3, return_type, args)])
def _GenerateMocks(filename, source, ast_list, desired_class_names):

View File

@ -61,7 +61,7 @@ class Foo {
};
"""
self.assertEqualIgnoreLeadingWhitespace(
'MOCK_METHOD(int, Bar, (), (override));',
'MOCK_METHOD0(Bar,\nint());',
self.GenerateMethodSource(source))
def testSimpleConstructorsAndDestructor(self):
@ -78,7 +78,7 @@ class Foo {
"""
# The constructors and destructor should be ignored.
self.assertEqualIgnoreLeadingWhitespace(
'MOCK_METHOD(int, Bar, (), (override));',
'MOCK_METHOD0(Bar,\nint());',
self.GenerateMethodSource(source))
def testVirtualDestructor(self):
@ -91,7 +91,7 @@ class Foo {
"""
# The destructor should be ignored.
self.assertEqualIgnoreLeadingWhitespace(
'MOCK_METHOD(int, Bar, (), (override));',
'MOCK_METHOD0(Bar,\nint());',
self.GenerateMethodSource(source))
def testExplicitlyDefaultedConstructorsAndDestructor(self):
@ -107,7 +107,7 @@ class Foo {
"""
# The constructors and destructor should be ignored.
self.assertEqualIgnoreLeadingWhitespace(
'MOCK_METHOD(int, Bar, (), (override));',
'MOCK_METHOD0(Bar,\nint());',
self.GenerateMethodSource(source))
def testExplicitlyDeletedConstructorsAndDestructor(self):
@ -123,7 +123,7 @@ class Foo {
"""
# The constructors and destructor should be ignored.
self.assertEqualIgnoreLeadingWhitespace(
'MOCK_METHOD(int, Bar, (), (override));',
'MOCK_METHOD0(Bar,\nint());',
self.GenerateMethodSource(source))
def testSimpleOverrideMethod(self):
@ -134,7 +134,7 @@ class Foo {
};
"""
self.assertEqualIgnoreLeadingWhitespace(
'MOCK_METHOD(int, Bar, (), (override));',
'MOCK_METHOD0(Bar,\nint());',
self.GenerateMethodSource(source))
def testSimpleConstMethod(self):
@ -145,7 +145,7 @@ class Foo {
};
"""
self.assertEqualIgnoreLeadingWhitespace(
'MOCK_METHOD(void, Bar, (bool flag), (const, override));',
'MOCK_CONST_METHOD1(Bar,\nvoid(bool flag));',
self.GenerateMethodSource(source))
def testExplicitVoid(self):
@ -156,7 +156,7 @@ class Foo {
};
"""
self.assertEqualIgnoreLeadingWhitespace(
'MOCK_METHOD(int, Bar, (void), (override));',
'MOCK_METHOD0(Bar,\nint(void));',
self.GenerateMethodSource(source))
def testStrangeNewlineInParameter(self):
@ -168,7 +168,7 @@ a) = 0;
};
"""
self.assertEqualIgnoreLeadingWhitespace(
'MOCK_METHOD(void, Bar, (int a), (override));',
'MOCK_METHOD1(Bar,\nvoid(int a));',
self.GenerateMethodSource(source))
def testDefaultParameters(self):
@ -179,7 +179,7 @@ class Foo {
};
"""
self.assertEqualIgnoreLeadingWhitespace(
'MOCK_METHOD(void, Bar, (int a, char c), (override));',
'MOCK_METHOD2(Bar,\nvoid(int a, char c ));',
self.GenerateMethodSource(source))
def testMultipleDefaultParameters(self):
@ -196,9 +196,9 @@ class Foo {
};
"""
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))
"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))
def testConstDefaultParameter(self):
source = """
@ -207,9 +207,9 @@ class Test {
virtual bool Bar(const int test_arg = 42) = 0;
};
"""
expected = 'MOCK_METHOD1(Bar,\nbool(const int test_arg ));'
self.assertEqualIgnoreLeadingWhitespace(
'MOCK_METHOD(bool, Bar, (const int test_arg), (override));',
self.GenerateMethodSource(source))
expected, self.GenerateMethodSource(source))
def testConstRefDefaultParameter(self):
source = """
@ -218,9 +218,9 @@ class Test {
virtual bool Bar(const std::string& test_arg = "42" ) = 0;
};
"""
expected = 'MOCK_METHOD1(Bar,\nbool(const std::string& test_arg ));'
self.assertEqualIgnoreLeadingWhitespace(
'MOCK_METHOD(bool, Bar, (const std::string& test_arg), (override));',
self.GenerateMethodSource(source))
expected, self.GenerateMethodSource(source))
def testRemovesCommentsWhenDefaultsArePresent(self):
source = """
@ -231,7 +231,7 @@ class Foo {
};
"""
self.assertEqualIgnoreLeadingWhitespace(
'MOCK_METHOD(void, Bar, (int a, char c), (override));',
'MOCK_METHOD2(Bar,\nvoid(int a , char c));',
self.GenerateMethodSource(source))
def testDoubleSlashCommentsInParameterListAreRemoved(self):
@ -244,7 +244,7 @@ class Foo {
};
"""
self.assertEqualIgnoreLeadingWhitespace(
'MOCK_METHOD(void, Bar, (int a, int b), (const, override));',
'MOCK_CONST_METHOD2(Bar,\nvoid(int a, int b));',
self.GenerateMethodSource(source))
def testCStyleCommentsInParameterListAreNotRemoved(self):
@ -258,7 +258,7 @@ class Foo {
};
"""
self.assertEqualIgnoreLeadingWhitespace(
'MOCK_METHOD(const string&, Bar, (int, int b), (override));',
'MOCK_METHOD2(Bar,\nconst string&(int , int b));',
self.GenerateMethodSource(source))
def testArgsOfTemplateTypes(self):
@ -268,7 +268,8 @@ class Foo {
virtual int Bar(const vector<int>& v, map<int, string>* output);
};"""
self.assertEqualIgnoreLeadingWhitespace(
'MOCK_METHOD(int, Bar, (const vector<int>& v, map<int, string>* output), (override));',
'MOCK_METHOD2(Bar,\n'
'int(const vector<int>& v, map<int, string>* output));',
self.GenerateMethodSource(source))
def testReturnTypeWithOneTemplateArg(self):
@ -278,7 +279,7 @@ class Foo {
virtual vector<int>* Bar(int n);
};"""
self.assertEqualIgnoreLeadingWhitespace(
'MOCK_METHOD(vector<int>*, Bar, (int n), (override));',
'MOCK_METHOD1(Bar,\nvector<int>*(int n));',
self.GenerateMethodSource(source))
def testReturnTypeWithManyTemplateArgs(self):
@ -287,8 +288,13 @@ 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(
'MOCK_METHOD((map<int, string>), Bar, (), (override));',
'// The following line won\'t really compile, as the return\n'
'// type has multiple template arguments. To fix it, use a\n'
'// typedef for the return type.\n'
'MOCK_METHOD0(Bar,\nmap<int, string>());',
self.GenerateMethodSource(source))
def testSimpleMethodInTemplatedClass(self):
@ -300,7 +306,7 @@ class Foo {
};
"""
self.assertEqualIgnoreLeadingWhitespace(
'MOCK_METHOD(int, Bar, (), (override));',
'MOCK_METHOD0_T(Bar,\nint());',
self.GenerateMethodSource(source))
def testPointerArgWithoutNames(self):
@ -310,7 +316,7 @@ class Foo {
};
"""
self.assertEqualIgnoreLeadingWhitespace(
'MOCK_METHOD(int, Bar, (C*), (override));',
'MOCK_METHOD1(Bar,\nint(C*));',
self.GenerateMethodSource(source))
def testReferenceArgWithoutNames(self):
@ -320,7 +326,7 @@ class Foo {
};
"""
self.assertEqualIgnoreLeadingWhitespace(
'MOCK_METHOD(int, Bar, (C&), (override));',
'MOCK_METHOD1(Bar,\nint(C&));',
self.GenerateMethodSource(source))
def testArrayArgWithoutNames(self):
@ -330,7 +336,7 @@ class Foo {
};
"""
self.assertEqualIgnoreLeadingWhitespace(
'MOCK_METHOD(int, Bar, (C[]), (override));',
'MOCK_METHOD1(Bar,\nint(C[]));',
self.GenerateMethodSource(source))
@ -366,14 +372,15 @@ namespace Baz {
class MockTest : public Test {
public:
MOCK_METHOD(void, Foo, (), (override));
MOCK_METHOD0(Foo,
void());
};
} // namespace Baz
} // namespace Foo
"""
self.assertEqualIgnoreLeadingWhitespace(expected,
self.GenerateMocks(source))
self.assertEqualIgnoreLeadingWhitespace(
expected, self.GenerateMocks(source))
def testClassWithStorageSpecifierMacro(self):
source = """
@ -385,11 +392,12 @@ class STORAGE_SPECIFIER Test {
expected = """\
class MockTest : public Test {
public:
MOCK_METHOD(void, Foo, (), (override));
MOCK_METHOD0(Foo,
void());
};
"""
self.assertEqualIgnoreLeadingWhitespace(expected,
self.GenerateMocks(source))
self.assertEqualIgnoreLeadingWhitespace(
expected, self.GenerateMocks(source))
def testTemplatedForwardDeclaration(self):
source = """
@ -402,11 +410,12 @@ class Test {
expected = """\
class MockTest : public Test {
public:
MOCK_METHOD(void, Foo, (), (override));
MOCK_METHOD0(Foo,
void());
};
"""
self.assertEqualIgnoreLeadingWhitespace(expected,
self.GenerateMocks(source))
self.assertEqualIgnoreLeadingWhitespace(
expected, self.GenerateMocks(source))
def testTemplatedClass(self):
source = """
@ -420,11 +429,12 @@ class Test {
template <typename T0, typename T1>
class MockTest : public Test<T0, T1> {
public:
MOCK_METHOD(void, Foo, (), (override));
MOCK_METHOD0_T(Foo,
void());
};
"""
self.assertEqualIgnoreLeadingWhitespace(expected,
self.GenerateMocks(source))
self.assertEqualIgnoreLeadingWhitespace(
expected, self.GenerateMocks(source))
def testTemplateInATemplateTypedef(self):
source = """
@ -437,11 +447,12 @@ class Test {
expected = """\
class MockTest : public Test {
public:
MOCK_METHOD(void, Bar, (const FooType& test_arg), (override));
MOCK_METHOD1(Bar,
void(const FooType& test_arg));
};
"""
self.assertEqualIgnoreLeadingWhitespace(expected,
self.GenerateMocks(source))
self.assertEqualIgnoreLeadingWhitespace(
expected, self.GenerateMocks(source))
def testTemplateInATemplateTypedefWithComma(self):
source = """
@ -455,11 +466,12 @@ class Test {
expected = """\
class MockTest : public Test {
public:
MOCK_METHOD(void, Bar, (const FooType& test_arg), (override));
MOCK_METHOD1(Bar,
void(const FooType& test_arg));
};
"""
self.assertEqualIgnoreLeadingWhitespace(expected,
self.GenerateMocks(source))
self.assertEqualIgnoreLeadingWhitespace(
expected, self.GenerateMocks(source))
def testEnumType(self):
source = """
@ -474,11 +486,12 @@ class Test {
expected = """\
class MockTest : public Test {
public:
MOCK_METHOD(void, Foo, (), (override));
MOCK_METHOD0(Foo,
void());
};
"""
self.assertEqualIgnoreLeadingWhitespace(expected,
self.GenerateMocks(source))
self.assertEqualIgnoreLeadingWhitespace(
expected, self.GenerateMocks(source))
def testEnumClassType(self):
source = """
@ -493,11 +506,12 @@ class Test {
expected = """\
class MockTest : public Test {
public:
MOCK_METHOD(void, Foo, (), (override));
MOCK_METHOD0(Foo,
void());
};
"""
self.assertEqualIgnoreLeadingWhitespace(expected,
self.GenerateMocks(source))
self.assertEqualIgnoreLeadingWhitespace(
expected, self.GenerateMocks(source))
def testStdFunction(self):
source = """
@ -514,11 +528,12 @@ class Test {
expected = """\
class MockTest : public Test {
public:
MOCK_METHOD(std::function<int (std::string)>, foo, (), (override));
MOCK_METHOD0(foo,
std::function<int (std::string)>());
};
"""
self.assertEqualIgnoreLeadingWhitespace(expected,
self.GenerateMocks(source))
self.assertEqualIgnoreLeadingWhitespace(
expected, self.GenerateMocks(source))
if __name__ == '__main__':