Differential D18622 Diff 52199 google/googletest/dist/googlemock/scripts/generator/cpp/gmock_class_test.py
Changeset View
Changeset View
Standalone View
Standalone View
google/googletest/dist/googlemock/scripts/generator/cpp/gmock_class_test.py
- This file was added.
Property | Old Value | New Value |
---|---|---|
svn:eol-style | null | native \ No newline at end of property |
svn:executable | null | * \ No newline at end of property |
svn:keywords | null | FreeBSD=%H \ No newline at end of property |
svn:mime-type | null | text/plain \ No newline at end of property |
#!/usr/bin/env python | |||||
# | |||||
# Copyright 2009 Neal Norwitz All Rights Reserved. | |||||
# Portions Copyright 2009 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. | |||||
"""Tests for gmock.scripts.generator.cpp.gmock_class.""" | |||||
__author__ = 'nnorwitz@google.com (Neal Norwitz)' | |||||
import os | |||||
import sys | |||||
import unittest | |||||
# Allow the cpp imports below to work when run as a standalone script. | |||||
sys.path.append(os.path.join(os.path.dirname(__file__), '..')) | |||||
from cpp import ast | |||||
from cpp import gmock_class | |||||
class TestCase(unittest.TestCase): | |||||
"""Helper class that adds assert methods.""" | |||||
def StripLeadingWhitespace(self, lines): | |||||
"""Strip leading whitespace in each line in 'lines'.""" | |||||
return '\n'.join([s.lstrip() for s in lines.split('\n')]) | |||||
def assertEqualIgnoreLeadingWhitespace(self, expected_lines, lines): | |||||
"""Specialized assert that ignores the indent level.""" | |||||
self.assertEqual(expected_lines, self.StripLeadingWhitespace(lines)) | |||||
class GenerateMethodsTest(TestCase): | |||||
def GenerateMethodSource(self, 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,\nint());', | |||||
self.GenerateMethodSource(source)) | |||||
def testSimpleConstructorsAndDestructor(self): | |||||
source = """ | |||||
class Foo { | |||||
public: | |||||
Foo(); | |||||
Foo(int x); | |||||
Foo(const Foo& f); | |||||
Foo(Foo&& f); | |||||
~Foo(); | |||||
virtual int Bar() = 0; | |||||
}; | |||||
""" | |||||
# The constructors and destructor should be ignored. | |||||
self.assertEqualIgnoreLeadingWhitespace( | |||||
'MOCK_METHOD0(Bar,\nint());', | |||||
self.GenerateMethodSource(source)) | |||||
def testVirtualDestructor(self): | |||||
source = """ | |||||
class Foo { | |||||
public: | |||||
virtual ~Foo(); | |||||
virtual int Bar() = 0; | |||||
}; | |||||
""" | |||||
# The destructor should be ignored. | |||||
self.assertEqualIgnoreLeadingWhitespace( | |||||
'MOCK_METHOD0(Bar,\nint());', | |||||
self.GenerateMethodSource(source)) | |||||
def testExplicitlyDefaultedConstructorsAndDestructor(self): | |||||
source = """ | |||||
class Foo { | |||||
public: | |||||
Foo() = default; | |||||
Foo(const Foo& f) = default; | |||||
Foo(Foo&& f) = default; | |||||
~Foo() = default; | |||||
virtual int Bar() = 0; | |||||
}; | |||||
""" | |||||
# The constructors and destructor should be ignored. | |||||
self.assertEqualIgnoreLeadingWhitespace( | |||||
'MOCK_METHOD0(Bar,\nint());', | |||||
self.GenerateMethodSource(source)) | |||||
def testExplicitlyDeletedConstructorsAndDestructor(self): | |||||
source = """ | |||||
class Foo { | |||||
public: | |||||
Foo() = delete; | |||||
Foo(const Foo& f) = delete; | |||||
Foo(Foo&& f) = delete; | |||||
~Foo() = delete; | |||||
virtual int Bar() = 0; | |||||
}; | |||||
""" | |||||
# The constructors and destructor should be ignored. | |||||
self.assertEqualIgnoreLeadingWhitespace( | |||||
'MOCK_METHOD0(Bar,\nint());', | |||||
self.GenerateMethodSource(source)) | |||||
def testSimpleOverrideMethod(self): | |||||
source = """ | |||||
class Foo { | |||||
public: | |||||
int Bar() override; | |||||
}; | |||||
""" | |||||
self.assertEqualIgnoreLeadingWhitespace( | |||||
'MOCK_METHOD0(Bar,\nint());', | |||||
self.GenerateMethodSource(source)) | |||||
def testSimpleConstMethod(self): | |||||
source = """ | |||||
class Foo { | |||||
public: | |||||
virtual void Bar(bool flag) const; | |||||
}; | |||||
""" | |||||
self.assertEqualIgnoreLeadingWhitespace( | |||||
'MOCK_CONST_METHOD1(Bar,\nvoid(bool flag));', | |||||
self.GenerateMethodSource(source)) | |||||
def testExplicitVoid(self): | |||||
source = """ | |||||
class Foo { | |||||
public: | |||||
virtual int Bar(void); | |||||
}; | |||||
""" | |||||
self.assertEqualIgnoreLeadingWhitespace( | |||||
'MOCK_METHOD0(Bar,\nint(void));', | |||||
self.GenerateMethodSource(source)) | |||||
def testStrangeNewlineInParameter(self): | |||||
source = """ | |||||
class Foo { | |||||
public: | |||||
virtual void Bar(int | |||||
a) = 0; | |||||
}; | |||||
""" | |||||
self.assertEqualIgnoreLeadingWhitespace( | |||||
'MOCK_METHOD1(Bar,\nvoid(int a));', | |||||
self.GenerateMethodSource(source)) | |||||
def testDefaultParameters(self): | |||||
source = """ | |||||
class Foo { | |||||
public: | |||||
virtual void Bar(int a, char c = 'x') = 0; | |||||
}; | |||||
""" | |||||
self.assertEqualIgnoreLeadingWhitespace( | |||||
'MOCK_METHOD2(Bar,\nvoid(int, char));', | |||||
self.GenerateMethodSource(source)) | |||||
def testMultipleDefaultParameters(self): | |||||
source = """ | |||||
class Foo { | |||||
public: | |||||
virtual void Bar(int a = 42, char c = 'x') = 0; | |||||
}; | |||||
""" | |||||
self.assertEqualIgnoreLeadingWhitespace( | |||||
'MOCK_METHOD2(Bar,\nvoid(int, char));', | |||||
self.GenerateMethodSource(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,\nvoid(int, char));', | |||||
self.GenerateMethodSource(source)) | |||||
def testDoubleSlashCommentsInParameterListAreRemoved(self): | |||||
source = """ | |||||
class Foo { | |||||
public: | |||||
virtual void Bar(int a, // inline comments should be elided. | |||||
int b // inline comments should be elided. | |||||
) const = 0; | |||||
}; | |||||
""" | |||||
self.assertEqualIgnoreLeadingWhitespace( | |||||
'MOCK_CONST_METHOD2(Bar,\nvoid(int a, int b));', | |||||
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 = """ | |||||
class Foo { | |||||
public: | |||||
virtual const string& Bar(int /* keeper */, int b); | |||||
}; | |||||
""" | |||||
self.assertEqualIgnoreLeadingWhitespace( | |||||
'MOCK_METHOD2(Bar,\nconst string&(int /* keeper */, int b));', | |||||
self.GenerateMethodSource(source)) | |||||
def testArgsOfTemplateTypes(self): | |||||
source = """ | |||||
class Foo { | |||||
public: | |||||
virtual int Bar(const vector<int>& v, map<int, string>* output); | |||||
};""" | |||||
self.assertEqualIgnoreLeadingWhitespace( | |||||
'MOCK_METHOD2(Bar,\n' | |||||
'int(const vector<int>& v, map<int, string>* output));', | |||||
self.GenerateMethodSource(source)) | |||||
def testReturnTypeWithOneTemplateArg(self): | |||||
source = """ | |||||
class Foo { | |||||
public: | |||||
virtual vector<int>* Bar(int n); | |||||
};""" | |||||
self.assertEqualIgnoreLeadingWhitespace( | |||||
'MOCK_METHOD1(Bar,\nvector<int>*(int n));', | |||||
self.GenerateMethodSource(source)) | |||||
def testReturnTypeWithManyTemplateArgs(self): | |||||
source = """ | |||||
class Foo { | |||||
public: | |||||
virtual map<int, string> Bar(); | |||||
};""" | |||||
# Comparing the comment text is brittle - we'll think of something | |||||
# better in case this gets annoying, but for now let's keep it simple. | |||||
self.assertEqualIgnoreLeadingWhitespace( | |||||
'// The following line won\'t really compile, as the return\n' | |||||
'// type has multiple template arguments. To fix it, use a\n' | |||||
'// typedef for the return type.\n' | |||||
'MOCK_METHOD0(Bar,\nmap<int, string>());', | |||||
self.GenerateMethodSource(source)) | |||||
def testSimpleMethodInTemplatedClass(self): | |||||
source = """ | |||||
template<class T> | |||||
class Foo { | |||||
public: | |||||
virtual int Bar(); | |||||
}; | |||||
""" | |||||
self.assertEqualIgnoreLeadingWhitespace( | |||||
'MOCK_METHOD0_T(Bar,\nint());', | |||||
self.GenerateMethodSource(source)) | |||||
def testPointerArgWithoutNames(self): | |||||
source = """ | |||||
class Foo { | |||||
virtual int Bar(C*); | |||||
}; | |||||
""" | |||||
self.assertEqualIgnoreLeadingWhitespace( | |||||
'MOCK_METHOD1(Bar,\nint(C*));', | |||||
self.GenerateMethodSource(source)) | |||||
def testReferenceArgWithoutNames(self): | |||||
source = """ | |||||
class Foo { | |||||
virtual int Bar(C&); | |||||
}; | |||||
""" | |||||
self.assertEqualIgnoreLeadingWhitespace( | |||||
'MOCK_METHOD1(Bar,\nint(C&));', | |||||
self.GenerateMethodSource(source)) | |||||
def testArrayArgWithoutNames(self): | |||||
source = """ | |||||
class Foo { | |||||
virtual int Bar(C[]); | |||||
}; | |||||
""" | |||||
self.assertEqualIgnoreLeadingWhitespace( | |||||
'MOCK_METHOD1(Bar,\nint(C[]));', | |||||
self.GenerateMethodSource(source)) | |||||
class GenerateMocksTest(TestCase): | |||||
def GenerateMocks(self, 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 { | |||||
class Test { | |||||
public: | |||||
virtual void Foo(); | |||||
}; | |||||
} // namespace Baz | |||||
} // namespace Foo | |||||
""" | |||||
expected = """\ | |||||
namespace Foo { | |||||
namespace Baz { | |||||
class MockTest : public Test { | |||||
public: | |||||
MOCK_METHOD0(Foo, | |||||
void()); | |||||
}; | |||||
} // namespace Baz | |||||
} // namespace Foo | |||||
""" | |||||
self.assertEqualIgnoreLeadingWhitespace( | |||||
expected, self.GenerateMocks(source)) | |||||
def testClassWithStorageSpecifierMacro(self): | |||||
source = """ | |||||
class STORAGE_SPECIFIER Test { | |||||
public: | |||||
virtual void Foo(); | |||||
}; | |||||
""" | |||||
expected = """\ | |||||
class MockTest : public Test { | |||||
public: | |||||
MOCK_METHOD0(Foo, | |||||
void()); | |||||
}; | |||||
""" | |||||
self.assertEqualIgnoreLeadingWhitespace( | |||||
expected, self.GenerateMocks(source)) | |||||
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)) | |||||
def testTemplateInATemplateTypedef(self): | |||||
source = """ | |||||
class Test { | |||||
public: | |||||
typedef std::vector<std::list<int>> FooType; | |||||
virtual void Bar(const FooType& test_arg); | |||||
}; | |||||
""" | |||||
expected = """\ | |||||
class MockTest : public Test { | |||||
public: | |||||
MOCK_METHOD1(Bar, | |||||
void(const FooType& test_arg)); | |||||
}; | |||||
""" | |||||
self.assertEqualIgnoreLeadingWhitespace( | |||||
expected, self.GenerateMocks(source)) | |||||
def testTemplateInATemplateTypedefWithComma(self): | |||||
source = """ | |||||
class Test { | |||||
public: | |||||
typedef std::function<void( | |||||
const vector<std::list<int>>&, int> FooType; | |||||
virtual void Bar(const FooType& test_arg); | |||||
}; | |||||
""" | |||||
expected = """\ | |||||
class MockTest : public Test { | |||||
public: | |||||
MOCK_METHOD1(Bar, | |||||
void(const FooType& test_arg)); | |||||
}; | |||||
""" | |||||
self.assertEqualIgnoreLeadingWhitespace( | |||||
expected, self.GenerateMocks(source)) | |||||
def testEnumClass(self): | |||||
source = """ | |||||
class Test { | |||||
public: | |||||
enum class Baz { BAZINGA }; | |||||
virtual void Bar(const FooType& test_arg); | |||||
}; | |||||
""" | |||||
expected = """\ | |||||
class MockTest : public Test { | |||||
public: | |||||
MOCK_METHOD1(Bar, | |||||
void(const FooType& test_arg)); | |||||
}; | |||||
""" | |||||
self.assertEqualIgnoreLeadingWhitespace( | |||||
expected, self.GenerateMocks(source)) | |||||
if __name__ == '__main__': | |||||
unittest.main() |