gmock_class_test.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466
  1. #!/usr/bin/env python
  2. #
  3. # Copyright 2009 Neal Norwitz All Rights Reserved.
  4. # Portions Copyright 2009 Google Inc. All Rights Reserved.
  5. #
  6. # Licensed under the Apache License, Version 2.0 (the "License");
  7. # you may not use this file except in compliance with the License.
  8. # You may obtain a copy of the License at
  9. #
  10. # http://www.apache.org/licenses/LICENSE-2.0
  11. #
  12. # Unless required by applicable law or agreed to in writing, software
  13. # distributed under the License is distributed on an "AS IS" BASIS,
  14. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. # See the License for the specific language governing permissions and
  16. # limitations under the License.
  17. """Tests for gmock.scripts.generator.cpp.gmock_class."""
  18. __author__ = 'nnorwitz@google.com (Neal Norwitz)'
  19. import os
  20. import sys
  21. import unittest
  22. # Allow the cpp imports below to work when run as a standalone script.
  23. sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
  24. from cpp import ast
  25. from cpp import gmock_class
  26. class TestCase(unittest.TestCase):
  27. """Helper class that adds assert methods."""
  28. def StripLeadingWhitespace(self, lines):
  29. """Strip leading whitespace in each line in 'lines'."""
  30. return '\n'.join([s.lstrip() for s in lines.split('\n')])
  31. def assertEqualIgnoreLeadingWhitespace(self, expected_lines, lines):
  32. """Specialized assert that ignores the indent level."""
  33. self.assertEqual(expected_lines, self.StripLeadingWhitespace(lines))
  34. class GenerateMethodsTest(TestCase):
  35. def GenerateMethodSource(self, cpp_source):
  36. """Convert C++ source to Google Mock output source lines."""
  37. method_source_lines = []
  38. # <test> is a pseudo-filename, it is not read or written.
  39. builder = ast.BuilderFromSource(cpp_source, '<test>')
  40. ast_list = list(builder.Generate())
  41. gmock_class._GenerateMethods(method_source_lines, cpp_source, ast_list[0])
  42. return '\n'.join(method_source_lines)
  43. def testSimpleMethod(self):
  44. source = """
  45. class Foo {
  46. public:
  47. virtual int Bar();
  48. };
  49. """
  50. self.assertEqualIgnoreLeadingWhitespace(
  51. 'MOCK_METHOD0(Bar,\nint());',
  52. self.GenerateMethodSource(source))
  53. def testSimpleConstructorsAndDestructor(self):
  54. source = """
  55. class Foo {
  56. public:
  57. Foo();
  58. Foo(int x);
  59. Foo(const Foo& f);
  60. Foo(Foo&& f);
  61. ~Foo();
  62. virtual int Bar() = 0;
  63. };
  64. """
  65. # The constructors and destructor should be ignored.
  66. self.assertEqualIgnoreLeadingWhitespace(
  67. 'MOCK_METHOD0(Bar,\nint());',
  68. self.GenerateMethodSource(source))
  69. def testVirtualDestructor(self):
  70. source = """
  71. class Foo {
  72. public:
  73. virtual ~Foo();
  74. virtual int Bar() = 0;
  75. };
  76. """
  77. # The destructor should be ignored.
  78. self.assertEqualIgnoreLeadingWhitespace(
  79. 'MOCK_METHOD0(Bar,\nint());',
  80. self.GenerateMethodSource(source))
  81. def testExplicitlyDefaultedConstructorsAndDestructor(self):
  82. source = """
  83. class Foo {
  84. public:
  85. Foo() = default;
  86. Foo(const Foo& f) = default;
  87. Foo(Foo&& f) = default;
  88. ~Foo() = default;
  89. virtual int Bar() = 0;
  90. };
  91. """
  92. # The constructors and destructor should be ignored.
  93. self.assertEqualIgnoreLeadingWhitespace(
  94. 'MOCK_METHOD0(Bar,\nint());',
  95. self.GenerateMethodSource(source))
  96. def testExplicitlyDeletedConstructorsAndDestructor(self):
  97. source = """
  98. class Foo {
  99. public:
  100. Foo() = delete;
  101. Foo(const Foo& f) = delete;
  102. Foo(Foo&& f) = delete;
  103. ~Foo() = delete;
  104. virtual int Bar() = 0;
  105. };
  106. """
  107. # The constructors and destructor should be ignored.
  108. self.assertEqualIgnoreLeadingWhitespace(
  109. 'MOCK_METHOD0(Bar,\nint());',
  110. self.GenerateMethodSource(source))
  111. def testSimpleOverrideMethod(self):
  112. source = """
  113. class Foo {
  114. public:
  115. int Bar() override;
  116. };
  117. """
  118. self.assertEqualIgnoreLeadingWhitespace(
  119. 'MOCK_METHOD0(Bar,\nint());',
  120. self.GenerateMethodSource(source))
  121. def testSimpleConstMethod(self):
  122. source = """
  123. class Foo {
  124. public:
  125. virtual void Bar(bool flag) const;
  126. };
  127. """
  128. self.assertEqualIgnoreLeadingWhitespace(
  129. 'MOCK_CONST_METHOD1(Bar,\nvoid(bool flag));',
  130. self.GenerateMethodSource(source))
  131. def testExplicitVoid(self):
  132. source = """
  133. class Foo {
  134. public:
  135. virtual int Bar(void);
  136. };
  137. """
  138. self.assertEqualIgnoreLeadingWhitespace(
  139. 'MOCK_METHOD0(Bar,\nint(void));',
  140. self.GenerateMethodSource(source))
  141. def testStrangeNewlineInParameter(self):
  142. source = """
  143. class Foo {
  144. public:
  145. virtual void Bar(int
  146. a) = 0;
  147. };
  148. """
  149. self.assertEqualIgnoreLeadingWhitespace(
  150. 'MOCK_METHOD1(Bar,\nvoid(int a));',
  151. self.GenerateMethodSource(source))
  152. def testDefaultParameters(self):
  153. source = """
  154. class Foo {
  155. public:
  156. virtual void Bar(int a, char c = 'x') = 0;
  157. };
  158. """
  159. self.assertEqualIgnoreLeadingWhitespace(
  160. 'MOCK_METHOD2(Bar,\nvoid(int, char));',
  161. self.GenerateMethodSource(source))
  162. def testMultipleDefaultParameters(self):
  163. source = """
  164. class Foo {
  165. public:
  166. virtual void Bar(int a = 42, char c = 'x') = 0;
  167. };
  168. """
  169. self.assertEqualIgnoreLeadingWhitespace(
  170. 'MOCK_METHOD2(Bar,\nvoid(int, char));',
  171. self.GenerateMethodSource(source))
  172. def testRemovesCommentsWhenDefaultsArePresent(self):
  173. source = """
  174. class Foo {
  175. public:
  176. virtual void Bar(int a = 42 /* a comment */,
  177. char /* other comment */ c= 'x') = 0;
  178. };
  179. """
  180. self.assertEqualIgnoreLeadingWhitespace(
  181. 'MOCK_METHOD2(Bar,\nvoid(int, char));',
  182. self.GenerateMethodSource(source))
  183. def testDoubleSlashCommentsInParameterListAreRemoved(self):
  184. source = """
  185. class Foo {
  186. public:
  187. virtual void Bar(int a, // inline comments should be elided.
  188. int b // inline comments should be elided.
  189. ) const = 0;
  190. };
  191. """
  192. self.assertEqualIgnoreLeadingWhitespace(
  193. 'MOCK_CONST_METHOD2(Bar,\nvoid(int a, int b));',
  194. self.GenerateMethodSource(source))
  195. def testCStyleCommentsInParameterListAreNotRemoved(self):
  196. # NOTE(nnorwitz): I'm not sure if it's the best behavior to keep these
  197. # comments. Also note that C style comments after the last parameter
  198. # are still elided.
  199. source = """
  200. class Foo {
  201. public:
  202. virtual const string& Bar(int /* keeper */, int b);
  203. };
  204. """
  205. self.assertEqualIgnoreLeadingWhitespace(
  206. 'MOCK_METHOD2(Bar,\nconst string&(int /* keeper */, int b));',
  207. self.GenerateMethodSource(source))
  208. def testArgsOfTemplateTypes(self):
  209. source = """
  210. class Foo {
  211. public:
  212. virtual int Bar(const vector<int>& v, map<int, string>* output);
  213. };"""
  214. self.assertEqualIgnoreLeadingWhitespace(
  215. 'MOCK_METHOD2(Bar,\n'
  216. 'int(const vector<int>& v, map<int, string>* output));',
  217. self.GenerateMethodSource(source))
  218. def testReturnTypeWithOneTemplateArg(self):
  219. source = """
  220. class Foo {
  221. public:
  222. virtual vector<int>* Bar(int n);
  223. };"""
  224. self.assertEqualIgnoreLeadingWhitespace(
  225. 'MOCK_METHOD1(Bar,\nvector<int>*(int n));',
  226. self.GenerateMethodSource(source))
  227. def testReturnTypeWithManyTemplateArgs(self):
  228. source = """
  229. class Foo {
  230. public:
  231. virtual map<int, string> Bar();
  232. };"""
  233. # Comparing the comment text is brittle - we'll think of something
  234. # better in case this gets annoying, but for now let's keep it simple.
  235. self.assertEqualIgnoreLeadingWhitespace(
  236. '// The following line won\'t really compile, as the return\n'
  237. '// type has multiple template arguments. To fix it, use a\n'
  238. '// typedef for the return type.\n'
  239. 'MOCK_METHOD0(Bar,\nmap<int, string>());',
  240. self.GenerateMethodSource(source))
  241. def testSimpleMethodInTemplatedClass(self):
  242. source = """
  243. template<class T>
  244. class Foo {
  245. public:
  246. virtual int Bar();
  247. };
  248. """
  249. self.assertEqualIgnoreLeadingWhitespace(
  250. 'MOCK_METHOD0_T(Bar,\nint());',
  251. self.GenerateMethodSource(source))
  252. def testPointerArgWithoutNames(self):
  253. source = """
  254. class Foo {
  255. virtual int Bar(C*);
  256. };
  257. """
  258. self.assertEqualIgnoreLeadingWhitespace(
  259. 'MOCK_METHOD1(Bar,\nint(C*));',
  260. self.GenerateMethodSource(source))
  261. def testReferenceArgWithoutNames(self):
  262. source = """
  263. class Foo {
  264. virtual int Bar(C&);
  265. };
  266. """
  267. self.assertEqualIgnoreLeadingWhitespace(
  268. 'MOCK_METHOD1(Bar,\nint(C&));',
  269. self.GenerateMethodSource(source))
  270. def testArrayArgWithoutNames(self):
  271. source = """
  272. class Foo {
  273. virtual int Bar(C[]);
  274. };
  275. """
  276. self.assertEqualIgnoreLeadingWhitespace(
  277. 'MOCK_METHOD1(Bar,\nint(C[]));',
  278. self.GenerateMethodSource(source))
  279. class GenerateMocksTest(TestCase):
  280. def GenerateMocks(self, cpp_source):
  281. """Convert C++ source to complete Google Mock output source."""
  282. # <test> is a pseudo-filename, it is not read or written.
  283. filename = '<test>'
  284. builder = ast.BuilderFromSource(cpp_source, filename)
  285. ast_list = list(builder.Generate())
  286. lines = gmock_class._GenerateMocks(filename, cpp_source, ast_list, None)
  287. return '\n'.join(lines)
  288. def testNamespaces(self):
  289. source = """
  290. namespace Foo {
  291. namespace Bar { class Forward; }
  292. namespace Baz {
  293. class Test {
  294. public:
  295. virtual void Foo();
  296. };
  297. } // namespace Baz
  298. } // namespace Foo
  299. """
  300. expected = """\
  301. namespace Foo {
  302. namespace Baz {
  303. class MockTest : public Test {
  304. public:
  305. MOCK_METHOD0(Foo,
  306. void());
  307. };
  308. } // namespace Baz
  309. } // namespace Foo
  310. """
  311. self.assertEqualIgnoreLeadingWhitespace(
  312. expected, self.GenerateMocks(source))
  313. def testClassWithStorageSpecifierMacro(self):
  314. source = """
  315. class STORAGE_SPECIFIER Test {
  316. public:
  317. virtual void Foo();
  318. };
  319. """
  320. expected = """\
  321. class MockTest : public Test {
  322. public:
  323. MOCK_METHOD0(Foo,
  324. void());
  325. };
  326. """
  327. self.assertEqualIgnoreLeadingWhitespace(
  328. expected, self.GenerateMocks(source))
  329. def testTemplatedForwardDeclaration(self):
  330. source = """
  331. template <class T> class Forward; // Forward declaration should be ignored.
  332. class Test {
  333. public:
  334. virtual void Foo();
  335. };
  336. """
  337. expected = """\
  338. class MockTest : public Test {
  339. public:
  340. MOCK_METHOD0(Foo,
  341. void());
  342. };
  343. """
  344. self.assertEqualIgnoreLeadingWhitespace(
  345. expected, self.GenerateMocks(source))
  346. def testTemplatedClass(self):
  347. source = """
  348. template <typename S, typename T>
  349. class Test {
  350. public:
  351. virtual void Foo();
  352. };
  353. """
  354. expected = """\
  355. template <typename T0, typename T1>
  356. class MockTest : public Test<T0, T1> {
  357. public:
  358. MOCK_METHOD0_T(Foo,
  359. void());
  360. };
  361. """
  362. self.assertEqualIgnoreLeadingWhitespace(
  363. expected, self.GenerateMocks(source))
  364. def testTemplateInATemplateTypedef(self):
  365. source = """
  366. class Test {
  367. public:
  368. typedef std::vector<std::list<int>> FooType;
  369. virtual void Bar(const FooType& test_arg);
  370. };
  371. """
  372. expected = """\
  373. class MockTest : public Test {
  374. public:
  375. MOCK_METHOD1(Bar,
  376. void(const FooType& test_arg));
  377. };
  378. """
  379. self.assertEqualIgnoreLeadingWhitespace(
  380. expected, self.GenerateMocks(source))
  381. def testTemplateInATemplateTypedefWithComma(self):
  382. source = """
  383. class Test {
  384. public:
  385. typedef std::function<void(
  386. const vector<std::list<int>>&, int> FooType;
  387. virtual void Bar(const FooType& test_arg);
  388. };
  389. """
  390. expected = """\
  391. class MockTest : public Test {
  392. public:
  393. MOCK_METHOD1(Bar,
  394. void(const FooType& test_arg));
  395. };
  396. """
  397. self.assertEqualIgnoreLeadingWhitespace(
  398. expected, self.GenerateMocks(source))
  399. def testEnumClass(self):
  400. source = """
  401. class Test {
  402. public:
  403. enum class Baz { BAZINGA };
  404. virtual void Bar(const FooType& test_arg);
  405. };
  406. """
  407. expected = """\
  408. class MockTest : public Test {
  409. public:
  410. MOCK_METHOD1(Bar,
  411. void(const FooType& test_arg));
  412. };
  413. """
  414. self.assertEqualIgnoreLeadingWhitespace(
  415. expected, self.GenerateMocks(source))
  416. if __name__ == '__main__':
  417. unittest.main()