113481Sgiacomo.travaglini@arm.com#!/usr/bin/env python
213481Sgiacomo.travaglini@arm.com#
313481Sgiacomo.travaglini@arm.com# Copyright 2009 Neal Norwitz All Rights Reserved.
413481Sgiacomo.travaglini@arm.com# Portions Copyright 2009 Google Inc. All Rights Reserved.
513481Sgiacomo.travaglini@arm.com#
613481Sgiacomo.travaglini@arm.com# Licensed under the Apache License, Version 2.0 (the "License");
713481Sgiacomo.travaglini@arm.com# you may not use this file except in compliance with the License.
813481Sgiacomo.travaglini@arm.com# You may obtain a copy of the License at
913481Sgiacomo.travaglini@arm.com#
1013481Sgiacomo.travaglini@arm.com#      http://www.apache.org/licenses/LICENSE-2.0
1113481Sgiacomo.travaglini@arm.com#
1213481Sgiacomo.travaglini@arm.com# Unless required by applicable law or agreed to in writing, software
1313481Sgiacomo.travaglini@arm.com# distributed under the License is distributed on an "AS IS" BASIS,
1413481Sgiacomo.travaglini@arm.com# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1513481Sgiacomo.travaglini@arm.com# See the License for the specific language governing permissions and
1613481Sgiacomo.travaglini@arm.com# limitations under the License.
1713481Sgiacomo.travaglini@arm.com
1813481Sgiacomo.travaglini@arm.com"""Tests for gmock.scripts.generator.cpp.gmock_class."""
1913481Sgiacomo.travaglini@arm.com
2013481Sgiacomo.travaglini@arm.com__author__ = 'nnorwitz@google.com (Neal Norwitz)'
2113481Sgiacomo.travaglini@arm.com
2213481Sgiacomo.travaglini@arm.com
2313481Sgiacomo.travaglini@arm.comimport os
2413481Sgiacomo.travaglini@arm.comimport sys
2513481Sgiacomo.travaglini@arm.comimport unittest
2613481Sgiacomo.travaglini@arm.com
2713481Sgiacomo.travaglini@arm.com# Allow the cpp imports below to work when run as a standalone script.
2813481Sgiacomo.travaglini@arm.comsys.path.append(os.path.join(os.path.dirname(__file__), '..'))
2913481Sgiacomo.travaglini@arm.com
3013481Sgiacomo.travaglini@arm.comfrom cpp import ast
3113481Sgiacomo.travaglini@arm.comfrom cpp import gmock_class
3213481Sgiacomo.travaglini@arm.com
3313481Sgiacomo.travaglini@arm.com
3413481Sgiacomo.travaglini@arm.comclass TestCase(unittest.TestCase):
3513481Sgiacomo.travaglini@arm.com  """Helper class that adds assert methods."""
3613481Sgiacomo.travaglini@arm.com
3713481Sgiacomo.travaglini@arm.com  def StripLeadingWhitespace(self, lines):
3813481Sgiacomo.travaglini@arm.com    """Strip leading whitespace in each line in 'lines'."""
3913481Sgiacomo.travaglini@arm.com    return '\n'.join([s.lstrip() for s in lines.split('\n')])
4013481Sgiacomo.travaglini@arm.com
4113481Sgiacomo.travaglini@arm.com  def assertEqualIgnoreLeadingWhitespace(self, expected_lines, lines):
4213481Sgiacomo.travaglini@arm.com    """Specialized assert that ignores the indent level."""
4313481Sgiacomo.travaglini@arm.com    self.assertEqual(expected_lines, self.StripLeadingWhitespace(lines))
4413481Sgiacomo.travaglini@arm.com
4513481Sgiacomo.travaglini@arm.com
4613481Sgiacomo.travaglini@arm.comclass GenerateMethodsTest(TestCase):
4713481Sgiacomo.travaglini@arm.com
4813481Sgiacomo.travaglini@arm.com  def GenerateMethodSource(self, cpp_source):
4913481Sgiacomo.travaglini@arm.com    """Convert C++ source to Google Mock output source lines."""
5013481Sgiacomo.travaglini@arm.com    method_source_lines = []
5113481Sgiacomo.travaglini@arm.com    # <test> is a pseudo-filename, it is not read or written.
5213481Sgiacomo.travaglini@arm.com    builder = ast.BuilderFromSource(cpp_source, '<test>')
5313481Sgiacomo.travaglini@arm.com    ast_list = list(builder.Generate())
5413481Sgiacomo.travaglini@arm.com    gmock_class._GenerateMethods(method_source_lines, cpp_source, ast_list[0])
5513481Sgiacomo.travaglini@arm.com    return '\n'.join(method_source_lines)
5613481Sgiacomo.travaglini@arm.com
5713481Sgiacomo.travaglini@arm.com  def testSimpleMethod(self):
5813481Sgiacomo.travaglini@arm.com    source = """
5913481Sgiacomo.travaglini@arm.comclass Foo {
6013481Sgiacomo.travaglini@arm.com public:
6113481Sgiacomo.travaglini@arm.com  virtual int Bar();
6213481Sgiacomo.travaglini@arm.com};
6313481Sgiacomo.travaglini@arm.com"""
6413481Sgiacomo.travaglini@arm.com    self.assertEqualIgnoreLeadingWhitespace(
6513481Sgiacomo.travaglini@arm.com        'MOCK_METHOD0(Bar,\nint());',
6613481Sgiacomo.travaglini@arm.com        self.GenerateMethodSource(source))
6713481Sgiacomo.travaglini@arm.com
6813481Sgiacomo.travaglini@arm.com  def testSimpleConstructorsAndDestructor(self):
6913481Sgiacomo.travaglini@arm.com    source = """
7013481Sgiacomo.travaglini@arm.comclass Foo {
7113481Sgiacomo.travaglini@arm.com public:
7213481Sgiacomo.travaglini@arm.com  Foo();
7313481Sgiacomo.travaglini@arm.com  Foo(int x);
7413481Sgiacomo.travaglini@arm.com  Foo(const Foo& f);
7513481Sgiacomo.travaglini@arm.com  Foo(Foo&& f);
7613481Sgiacomo.travaglini@arm.com  ~Foo();
7713481Sgiacomo.travaglini@arm.com  virtual int Bar() = 0;
7813481Sgiacomo.travaglini@arm.com};
7913481Sgiacomo.travaglini@arm.com"""
8013481Sgiacomo.travaglini@arm.com    # The constructors and destructor should be ignored.
8113481Sgiacomo.travaglini@arm.com    self.assertEqualIgnoreLeadingWhitespace(
8213481Sgiacomo.travaglini@arm.com        'MOCK_METHOD0(Bar,\nint());',
8313481Sgiacomo.travaglini@arm.com        self.GenerateMethodSource(source))
8413481Sgiacomo.travaglini@arm.com
8513481Sgiacomo.travaglini@arm.com  def testVirtualDestructor(self):
8613481Sgiacomo.travaglini@arm.com    source = """
8713481Sgiacomo.travaglini@arm.comclass Foo {
8813481Sgiacomo.travaglini@arm.com public:
8913481Sgiacomo.travaglini@arm.com  virtual ~Foo();
9013481Sgiacomo.travaglini@arm.com  virtual int Bar() = 0;
9113481Sgiacomo.travaglini@arm.com};
9213481Sgiacomo.travaglini@arm.com"""
9313481Sgiacomo.travaglini@arm.com    # The destructor should be ignored.
9413481Sgiacomo.travaglini@arm.com    self.assertEqualIgnoreLeadingWhitespace(
9513481Sgiacomo.travaglini@arm.com        'MOCK_METHOD0(Bar,\nint());',
9613481Sgiacomo.travaglini@arm.com        self.GenerateMethodSource(source))
9713481Sgiacomo.travaglini@arm.com
9813481Sgiacomo.travaglini@arm.com  def testExplicitlyDefaultedConstructorsAndDestructor(self):
9913481Sgiacomo.travaglini@arm.com    source = """
10013481Sgiacomo.travaglini@arm.comclass Foo {
10113481Sgiacomo.travaglini@arm.com public:
10213481Sgiacomo.travaglini@arm.com  Foo() = default;
10313481Sgiacomo.travaglini@arm.com  Foo(const Foo& f) = default;
10413481Sgiacomo.travaglini@arm.com  Foo(Foo&& f) = default;
10513481Sgiacomo.travaglini@arm.com  ~Foo() = default;
10613481Sgiacomo.travaglini@arm.com  virtual int Bar() = 0;
10713481Sgiacomo.travaglini@arm.com};
10813481Sgiacomo.travaglini@arm.com"""
10913481Sgiacomo.travaglini@arm.com    # The constructors and destructor should be ignored.
11013481Sgiacomo.travaglini@arm.com    self.assertEqualIgnoreLeadingWhitespace(
11113481Sgiacomo.travaglini@arm.com        'MOCK_METHOD0(Bar,\nint());',
11213481Sgiacomo.travaglini@arm.com        self.GenerateMethodSource(source))
11313481Sgiacomo.travaglini@arm.com
11413481Sgiacomo.travaglini@arm.com  def testExplicitlyDeletedConstructorsAndDestructor(self):
11513481Sgiacomo.travaglini@arm.com    source = """
11613481Sgiacomo.travaglini@arm.comclass Foo {
11713481Sgiacomo.travaglini@arm.com public:
11813481Sgiacomo.travaglini@arm.com  Foo() = delete;
11913481Sgiacomo.travaglini@arm.com  Foo(const Foo& f) = delete;
12013481Sgiacomo.travaglini@arm.com  Foo(Foo&& f) = delete;
12113481Sgiacomo.travaglini@arm.com  ~Foo() = delete;
12213481Sgiacomo.travaglini@arm.com  virtual int Bar() = 0;
12313481Sgiacomo.travaglini@arm.com};
12413481Sgiacomo.travaglini@arm.com"""
12513481Sgiacomo.travaglini@arm.com    # The constructors and destructor should be ignored.
12613481Sgiacomo.travaglini@arm.com    self.assertEqualIgnoreLeadingWhitespace(
12713481Sgiacomo.travaglini@arm.com        'MOCK_METHOD0(Bar,\nint());',
12813481Sgiacomo.travaglini@arm.com        self.GenerateMethodSource(source))
12913481Sgiacomo.travaglini@arm.com
13013481Sgiacomo.travaglini@arm.com  def testSimpleOverrideMethod(self):
13113481Sgiacomo.travaglini@arm.com    source = """
13213481Sgiacomo.travaglini@arm.comclass Foo {
13313481Sgiacomo.travaglini@arm.com public:
13413481Sgiacomo.travaglini@arm.com  int Bar() override;
13513481Sgiacomo.travaglini@arm.com};
13613481Sgiacomo.travaglini@arm.com"""
13713481Sgiacomo.travaglini@arm.com    self.assertEqualIgnoreLeadingWhitespace(
13813481Sgiacomo.travaglini@arm.com        'MOCK_METHOD0(Bar,\nint());',
13913481Sgiacomo.travaglini@arm.com        self.GenerateMethodSource(source))
14013481Sgiacomo.travaglini@arm.com
14113481Sgiacomo.travaglini@arm.com  def testSimpleConstMethod(self):
14213481Sgiacomo.travaglini@arm.com    source = """
14313481Sgiacomo.travaglini@arm.comclass Foo {
14413481Sgiacomo.travaglini@arm.com public:
14513481Sgiacomo.travaglini@arm.com  virtual void Bar(bool flag) const;
14613481Sgiacomo.travaglini@arm.com};
14713481Sgiacomo.travaglini@arm.com"""
14813481Sgiacomo.travaglini@arm.com    self.assertEqualIgnoreLeadingWhitespace(
14913481Sgiacomo.travaglini@arm.com        'MOCK_CONST_METHOD1(Bar,\nvoid(bool flag));',
15013481Sgiacomo.travaglini@arm.com        self.GenerateMethodSource(source))
15113481Sgiacomo.travaglini@arm.com
15213481Sgiacomo.travaglini@arm.com  def testExplicitVoid(self):
15313481Sgiacomo.travaglini@arm.com    source = """
15413481Sgiacomo.travaglini@arm.comclass Foo {
15513481Sgiacomo.travaglini@arm.com public:
15613481Sgiacomo.travaglini@arm.com  virtual int Bar(void);
15713481Sgiacomo.travaglini@arm.com};
15813481Sgiacomo.travaglini@arm.com"""
15913481Sgiacomo.travaglini@arm.com    self.assertEqualIgnoreLeadingWhitespace(
16013481Sgiacomo.travaglini@arm.com        'MOCK_METHOD0(Bar,\nint(void));',
16113481Sgiacomo.travaglini@arm.com        self.GenerateMethodSource(source))
16213481Sgiacomo.travaglini@arm.com
16313481Sgiacomo.travaglini@arm.com  def testStrangeNewlineInParameter(self):
16413481Sgiacomo.travaglini@arm.com    source = """
16513481Sgiacomo.travaglini@arm.comclass Foo {
16613481Sgiacomo.travaglini@arm.com public:
16713481Sgiacomo.travaglini@arm.com  virtual void Bar(int
16813481Sgiacomo.travaglini@arm.coma) = 0;
16913481Sgiacomo.travaglini@arm.com};
17013481Sgiacomo.travaglini@arm.com"""
17113481Sgiacomo.travaglini@arm.com    self.assertEqualIgnoreLeadingWhitespace(
17213481Sgiacomo.travaglini@arm.com        'MOCK_METHOD1(Bar,\nvoid(int a));',
17313481Sgiacomo.travaglini@arm.com        self.GenerateMethodSource(source))
17413481Sgiacomo.travaglini@arm.com
17513481Sgiacomo.travaglini@arm.com  def testDefaultParameters(self):
17613481Sgiacomo.travaglini@arm.com    source = """
17713481Sgiacomo.travaglini@arm.comclass Foo {
17813481Sgiacomo.travaglini@arm.com public:
17913481Sgiacomo.travaglini@arm.com  virtual void Bar(int a, char c = 'x') = 0;
18013481Sgiacomo.travaglini@arm.com};
18113481Sgiacomo.travaglini@arm.com"""
18213481Sgiacomo.travaglini@arm.com    self.assertEqualIgnoreLeadingWhitespace(
18313481Sgiacomo.travaglini@arm.com        'MOCK_METHOD2(Bar,\nvoid(int, char));',
18413481Sgiacomo.travaglini@arm.com        self.GenerateMethodSource(source))
18513481Sgiacomo.travaglini@arm.com
18613481Sgiacomo.travaglini@arm.com  def testMultipleDefaultParameters(self):
18713481Sgiacomo.travaglini@arm.com    source = """
18813481Sgiacomo.travaglini@arm.comclass Foo {
18913481Sgiacomo.travaglini@arm.com public:
19013481Sgiacomo.travaglini@arm.com  virtual void Bar(int a = 42, char c = 'x') = 0;
19113481Sgiacomo.travaglini@arm.com};
19213481Sgiacomo.travaglini@arm.com"""
19313481Sgiacomo.travaglini@arm.com    self.assertEqualIgnoreLeadingWhitespace(
19413481Sgiacomo.travaglini@arm.com        'MOCK_METHOD2(Bar,\nvoid(int, char));',
19513481Sgiacomo.travaglini@arm.com        self.GenerateMethodSource(source))
19613481Sgiacomo.travaglini@arm.com
19713481Sgiacomo.travaglini@arm.com  def testRemovesCommentsWhenDefaultsArePresent(self):
19813481Sgiacomo.travaglini@arm.com    source = """
19913481Sgiacomo.travaglini@arm.comclass Foo {
20013481Sgiacomo.travaglini@arm.com public:
20113481Sgiacomo.travaglini@arm.com  virtual void Bar(int a = 42 /* a comment */,
20213481Sgiacomo.travaglini@arm.com                   char /* other comment */ c= 'x') = 0;
20313481Sgiacomo.travaglini@arm.com};
20413481Sgiacomo.travaglini@arm.com"""
20513481Sgiacomo.travaglini@arm.com    self.assertEqualIgnoreLeadingWhitespace(
20613481Sgiacomo.travaglini@arm.com        'MOCK_METHOD2(Bar,\nvoid(int, char));',
20713481Sgiacomo.travaglini@arm.com        self.GenerateMethodSource(source))
20813481Sgiacomo.travaglini@arm.com
20913481Sgiacomo.travaglini@arm.com  def testDoubleSlashCommentsInParameterListAreRemoved(self):
21013481Sgiacomo.travaglini@arm.com    source = """
21113481Sgiacomo.travaglini@arm.comclass Foo {
21213481Sgiacomo.travaglini@arm.com public:
21313481Sgiacomo.travaglini@arm.com  virtual void Bar(int a,  // inline comments should be elided.
21413481Sgiacomo.travaglini@arm.com                   int b   // inline comments should be elided.
21513481Sgiacomo.travaglini@arm.com                   ) const = 0;
21613481Sgiacomo.travaglini@arm.com};
21713481Sgiacomo.travaglini@arm.com"""
21813481Sgiacomo.travaglini@arm.com    self.assertEqualIgnoreLeadingWhitespace(
21913481Sgiacomo.travaglini@arm.com        'MOCK_CONST_METHOD2(Bar,\nvoid(int a, int b));',
22013481Sgiacomo.travaglini@arm.com        self.GenerateMethodSource(source))
22113481Sgiacomo.travaglini@arm.com
22213481Sgiacomo.travaglini@arm.com  def testCStyleCommentsInParameterListAreNotRemoved(self):
22313481Sgiacomo.travaglini@arm.com    # NOTE(nnorwitz): I'm not sure if it's the best behavior to keep these
22413481Sgiacomo.travaglini@arm.com    # comments.  Also note that C style comments after the last parameter
22513481Sgiacomo.travaglini@arm.com    # are still elided.
22613481Sgiacomo.travaglini@arm.com    source = """
22713481Sgiacomo.travaglini@arm.comclass Foo {
22813481Sgiacomo.travaglini@arm.com public:
22913481Sgiacomo.travaglini@arm.com  virtual const string& Bar(int /* keeper */, int b);
23013481Sgiacomo.travaglini@arm.com};
23113481Sgiacomo.travaglini@arm.com"""
23213481Sgiacomo.travaglini@arm.com    self.assertEqualIgnoreLeadingWhitespace(
23313481Sgiacomo.travaglini@arm.com        'MOCK_METHOD2(Bar,\nconst string&(int /* keeper */, int b));',
23413481Sgiacomo.travaglini@arm.com        self.GenerateMethodSource(source))
23513481Sgiacomo.travaglini@arm.com
23613481Sgiacomo.travaglini@arm.com  def testArgsOfTemplateTypes(self):
23713481Sgiacomo.travaglini@arm.com    source = """
23813481Sgiacomo.travaglini@arm.comclass Foo {
23913481Sgiacomo.travaglini@arm.com public:
24013481Sgiacomo.travaglini@arm.com  virtual int Bar(const vector<int>& v, map<int, string>* output);
24113481Sgiacomo.travaglini@arm.com};"""
24213481Sgiacomo.travaglini@arm.com    self.assertEqualIgnoreLeadingWhitespace(
24313481Sgiacomo.travaglini@arm.com        'MOCK_METHOD2(Bar,\n'
24413481Sgiacomo.travaglini@arm.com        'int(const vector<int>& v, map<int, string>* output));',
24513481Sgiacomo.travaglini@arm.com        self.GenerateMethodSource(source))
24613481Sgiacomo.travaglini@arm.com
24713481Sgiacomo.travaglini@arm.com  def testReturnTypeWithOneTemplateArg(self):
24813481Sgiacomo.travaglini@arm.com    source = """
24913481Sgiacomo.travaglini@arm.comclass Foo {
25013481Sgiacomo.travaglini@arm.com public:
25113481Sgiacomo.travaglini@arm.com  virtual vector<int>* Bar(int n);
25213481Sgiacomo.travaglini@arm.com};"""
25313481Sgiacomo.travaglini@arm.com    self.assertEqualIgnoreLeadingWhitespace(
25413481Sgiacomo.travaglini@arm.com        'MOCK_METHOD1(Bar,\nvector<int>*(int n));',
25513481Sgiacomo.travaglini@arm.com        self.GenerateMethodSource(source))
25613481Sgiacomo.travaglini@arm.com
25713481Sgiacomo.travaglini@arm.com  def testReturnTypeWithManyTemplateArgs(self):
25813481Sgiacomo.travaglini@arm.com    source = """
25913481Sgiacomo.travaglini@arm.comclass Foo {
26013481Sgiacomo.travaglini@arm.com public:
26113481Sgiacomo.travaglini@arm.com  virtual map<int, string> Bar();
26213481Sgiacomo.travaglini@arm.com};"""
26313481Sgiacomo.travaglini@arm.com    # Comparing the comment text is brittle - we'll think of something
26413481Sgiacomo.travaglini@arm.com    # better in case this gets annoying, but for now let's keep it simple.
26513481Sgiacomo.travaglini@arm.com    self.assertEqualIgnoreLeadingWhitespace(
26613481Sgiacomo.travaglini@arm.com        '// The following line won\'t really compile, as the return\n'
26713481Sgiacomo.travaglini@arm.com        '// type has multiple template arguments.  To fix it, use a\n'
26813481Sgiacomo.travaglini@arm.com        '// typedef for the return type.\n'
26913481Sgiacomo.travaglini@arm.com        'MOCK_METHOD0(Bar,\nmap<int, string>());',
27013481Sgiacomo.travaglini@arm.com        self.GenerateMethodSource(source))
27113481Sgiacomo.travaglini@arm.com
27213481Sgiacomo.travaglini@arm.com  def testSimpleMethodInTemplatedClass(self):
27313481Sgiacomo.travaglini@arm.com    source = """
27413481Sgiacomo.travaglini@arm.comtemplate<class T>
27513481Sgiacomo.travaglini@arm.comclass Foo {
27613481Sgiacomo.travaglini@arm.com public:
27713481Sgiacomo.travaglini@arm.com  virtual int Bar();
27813481Sgiacomo.travaglini@arm.com};
27913481Sgiacomo.travaglini@arm.com"""
28013481Sgiacomo.travaglini@arm.com    self.assertEqualIgnoreLeadingWhitespace(
28113481Sgiacomo.travaglini@arm.com        'MOCK_METHOD0_T(Bar,\nint());',
28213481Sgiacomo.travaglini@arm.com        self.GenerateMethodSource(source))
28313481Sgiacomo.travaglini@arm.com
28413481Sgiacomo.travaglini@arm.com  def testPointerArgWithoutNames(self):
28513481Sgiacomo.travaglini@arm.com    source = """
28613481Sgiacomo.travaglini@arm.comclass Foo {
28713481Sgiacomo.travaglini@arm.com  virtual int Bar(C*);
28813481Sgiacomo.travaglini@arm.com};
28913481Sgiacomo.travaglini@arm.com"""
29013481Sgiacomo.travaglini@arm.com    self.assertEqualIgnoreLeadingWhitespace(
29113481Sgiacomo.travaglini@arm.com        'MOCK_METHOD1(Bar,\nint(C*));',
29213481Sgiacomo.travaglini@arm.com        self.GenerateMethodSource(source))
29313481Sgiacomo.travaglini@arm.com
29413481Sgiacomo.travaglini@arm.com  def testReferenceArgWithoutNames(self):
29513481Sgiacomo.travaglini@arm.com    source = """
29613481Sgiacomo.travaglini@arm.comclass Foo {
29713481Sgiacomo.travaglini@arm.com  virtual int Bar(C&);
29813481Sgiacomo.travaglini@arm.com};
29913481Sgiacomo.travaglini@arm.com"""
30013481Sgiacomo.travaglini@arm.com    self.assertEqualIgnoreLeadingWhitespace(
30113481Sgiacomo.travaglini@arm.com        'MOCK_METHOD1(Bar,\nint(C&));',
30213481Sgiacomo.travaglini@arm.com        self.GenerateMethodSource(source))
30313481Sgiacomo.travaglini@arm.com
30413481Sgiacomo.travaglini@arm.com  def testArrayArgWithoutNames(self):
30513481Sgiacomo.travaglini@arm.com    source = """
30613481Sgiacomo.travaglini@arm.comclass Foo {
30713481Sgiacomo.travaglini@arm.com  virtual int Bar(C[]);
30813481Sgiacomo.travaglini@arm.com};
30913481Sgiacomo.travaglini@arm.com"""
31013481Sgiacomo.travaglini@arm.com    self.assertEqualIgnoreLeadingWhitespace(
31113481Sgiacomo.travaglini@arm.com        'MOCK_METHOD1(Bar,\nint(C[]));',
31213481Sgiacomo.travaglini@arm.com        self.GenerateMethodSource(source))
31313481Sgiacomo.travaglini@arm.com
31413481Sgiacomo.travaglini@arm.com
31513481Sgiacomo.travaglini@arm.comclass GenerateMocksTest(TestCase):
31613481Sgiacomo.travaglini@arm.com
31713481Sgiacomo.travaglini@arm.com  def GenerateMocks(self, cpp_source):
31813481Sgiacomo.travaglini@arm.com    """Convert C++ source to complete Google Mock output source."""
31913481Sgiacomo.travaglini@arm.com    # <test> is a pseudo-filename, it is not read or written.
32013481Sgiacomo.travaglini@arm.com    filename = '<test>'
32113481Sgiacomo.travaglini@arm.com    builder = ast.BuilderFromSource(cpp_source, filename)
32213481Sgiacomo.travaglini@arm.com    ast_list = list(builder.Generate())
32313481Sgiacomo.travaglini@arm.com    lines = gmock_class._GenerateMocks(filename, cpp_source, ast_list, None)
32413481Sgiacomo.travaglini@arm.com    return '\n'.join(lines)
32513481Sgiacomo.travaglini@arm.com
32613481Sgiacomo.travaglini@arm.com  def testNamespaces(self):
32713481Sgiacomo.travaglini@arm.com    source = """
32813481Sgiacomo.travaglini@arm.comnamespace Foo {
32913481Sgiacomo.travaglini@arm.comnamespace Bar { class Forward; }
33013481Sgiacomo.travaglini@arm.comnamespace Baz {
33113481Sgiacomo.travaglini@arm.com
33213481Sgiacomo.travaglini@arm.comclass Test {
33313481Sgiacomo.travaglini@arm.com public:
33413481Sgiacomo.travaglini@arm.com  virtual void Foo();
33513481Sgiacomo.travaglini@arm.com};
33613481Sgiacomo.travaglini@arm.com
33713481Sgiacomo.travaglini@arm.com}  // namespace Baz
33813481Sgiacomo.travaglini@arm.com}  // namespace Foo
33913481Sgiacomo.travaglini@arm.com"""
34013481Sgiacomo.travaglini@arm.com    expected = """\
34113481Sgiacomo.travaglini@arm.comnamespace Foo {
34213481Sgiacomo.travaglini@arm.comnamespace Baz {
34313481Sgiacomo.travaglini@arm.com
34413481Sgiacomo.travaglini@arm.comclass MockTest : public Test {
34513481Sgiacomo.travaglini@arm.compublic:
34613481Sgiacomo.travaglini@arm.comMOCK_METHOD0(Foo,
34713481Sgiacomo.travaglini@arm.comvoid());
34813481Sgiacomo.travaglini@arm.com};
34913481Sgiacomo.travaglini@arm.com
35013481Sgiacomo.travaglini@arm.com}  // namespace Baz
35113481Sgiacomo.travaglini@arm.com}  // namespace Foo
35213481Sgiacomo.travaglini@arm.com"""
35313481Sgiacomo.travaglini@arm.com    self.assertEqualIgnoreLeadingWhitespace(
35413481Sgiacomo.travaglini@arm.com        expected, self.GenerateMocks(source))
35513481Sgiacomo.travaglini@arm.com
35613481Sgiacomo.travaglini@arm.com  def testClassWithStorageSpecifierMacro(self):
35713481Sgiacomo.travaglini@arm.com    source = """
35813481Sgiacomo.travaglini@arm.comclass STORAGE_SPECIFIER Test {
35913481Sgiacomo.travaglini@arm.com public:
36013481Sgiacomo.travaglini@arm.com  virtual void Foo();
36113481Sgiacomo.travaglini@arm.com};
36213481Sgiacomo.travaglini@arm.com"""
36313481Sgiacomo.travaglini@arm.com    expected = """\
36413481Sgiacomo.travaglini@arm.comclass MockTest : public Test {
36513481Sgiacomo.travaglini@arm.compublic:
36613481Sgiacomo.travaglini@arm.comMOCK_METHOD0(Foo,
36713481Sgiacomo.travaglini@arm.comvoid());
36813481Sgiacomo.travaglini@arm.com};
36913481Sgiacomo.travaglini@arm.com"""
37013481Sgiacomo.travaglini@arm.com    self.assertEqualIgnoreLeadingWhitespace(
37113481Sgiacomo.travaglini@arm.com        expected, self.GenerateMocks(source))
37213481Sgiacomo.travaglini@arm.com
37313481Sgiacomo.travaglini@arm.com  def testTemplatedForwardDeclaration(self):
37413481Sgiacomo.travaglini@arm.com    source = """
37513481Sgiacomo.travaglini@arm.comtemplate <class T> class Forward;  // Forward declaration should be ignored.
37613481Sgiacomo.travaglini@arm.comclass Test {
37713481Sgiacomo.travaglini@arm.com public:
37813481Sgiacomo.travaglini@arm.com  virtual void Foo();
37913481Sgiacomo.travaglini@arm.com};
38013481Sgiacomo.travaglini@arm.com"""
38113481Sgiacomo.travaglini@arm.com    expected = """\
38213481Sgiacomo.travaglini@arm.comclass MockTest : public Test {
38313481Sgiacomo.travaglini@arm.compublic:
38413481Sgiacomo.travaglini@arm.comMOCK_METHOD0(Foo,
38513481Sgiacomo.travaglini@arm.comvoid());
38613481Sgiacomo.travaglini@arm.com};
38713481Sgiacomo.travaglini@arm.com"""
38813481Sgiacomo.travaglini@arm.com    self.assertEqualIgnoreLeadingWhitespace(
38913481Sgiacomo.travaglini@arm.com        expected, self.GenerateMocks(source))
39013481Sgiacomo.travaglini@arm.com
39113481Sgiacomo.travaglini@arm.com  def testTemplatedClass(self):
39213481Sgiacomo.travaglini@arm.com    source = """
39313481Sgiacomo.travaglini@arm.comtemplate <typename S, typename T>
39413481Sgiacomo.travaglini@arm.comclass Test {
39513481Sgiacomo.travaglini@arm.com public:
39613481Sgiacomo.travaglini@arm.com  virtual void Foo();
39713481Sgiacomo.travaglini@arm.com};
39813481Sgiacomo.travaglini@arm.com"""
39913481Sgiacomo.travaglini@arm.com    expected = """\
40013481Sgiacomo.travaglini@arm.comtemplate <typename T0, typename T1>
40113481Sgiacomo.travaglini@arm.comclass MockTest : public Test<T0, T1> {
40213481Sgiacomo.travaglini@arm.compublic:
40313481Sgiacomo.travaglini@arm.comMOCK_METHOD0_T(Foo,
40413481Sgiacomo.travaglini@arm.comvoid());
40513481Sgiacomo.travaglini@arm.com};
40613481Sgiacomo.travaglini@arm.com"""
40713481Sgiacomo.travaglini@arm.com    self.assertEqualIgnoreLeadingWhitespace(
40813481Sgiacomo.travaglini@arm.com        expected, self.GenerateMocks(source))
40913481Sgiacomo.travaglini@arm.com
41013481Sgiacomo.travaglini@arm.com  def testTemplateInATemplateTypedef(self):
41113481Sgiacomo.travaglini@arm.com    source = """
41213481Sgiacomo.travaglini@arm.comclass Test {
41313481Sgiacomo.travaglini@arm.com public:
41413481Sgiacomo.travaglini@arm.com  typedef std::vector<std::list<int>> FooType;
41513481Sgiacomo.travaglini@arm.com  virtual void Bar(const FooType& test_arg);
41613481Sgiacomo.travaglini@arm.com};
41713481Sgiacomo.travaglini@arm.com"""
41813481Sgiacomo.travaglini@arm.com    expected = """\
41913481Sgiacomo.travaglini@arm.comclass MockTest : public Test {
42013481Sgiacomo.travaglini@arm.compublic:
42113481Sgiacomo.travaglini@arm.comMOCK_METHOD1(Bar,
42213481Sgiacomo.travaglini@arm.comvoid(const FooType& test_arg));
42313481Sgiacomo.travaglini@arm.com};
42413481Sgiacomo.travaglini@arm.com"""
42513481Sgiacomo.travaglini@arm.com    self.assertEqualIgnoreLeadingWhitespace(
42613481Sgiacomo.travaglini@arm.com        expected, self.GenerateMocks(source))
42713481Sgiacomo.travaglini@arm.com
42813481Sgiacomo.travaglini@arm.com  def testTemplateInATemplateTypedefWithComma(self):
42913481Sgiacomo.travaglini@arm.com    source = """
43013481Sgiacomo.travaglini@arm.comclass Test {
43113481Sgiacomo.travaglini@arm.com public:
43213481Sgiacomo.travaglini@arm.com  typedef std::function<void(
43313481Sgiacomo.travaglini@arm.com      const vector<std::list<int>>&, int> FooType;
43413481Sgiacomo.travaglini@arm.com  virtual void Bar(const FooType& test_arg);
43513481Sgiacomo.travaglini@arm.com};
43613481Sgiacomo.travaglini@arm.com"""
43713481Sgiacomo.travaglini@arm.com    expected = """\
43813481Sgiacomo.travaglini@arm.comclass MockTest : public Test {
43913481Sgiacomo.travaglini@arm.compublic:
44013481Sgiacomo.travaglini@arm.comMOCK_METHOD1(Bar,
44113481Sgiacomo.travaglini@arm.comvoid(const FooType& test_arg));
44213481Sgiacomo.travaglini@arm.com};
44313481Sgiacomo.travaglini@arm.com"""
44413481Sgiacomo.travaglini@arm.com    self.assertEqualIgnoreLeadingWhitespace(
44513481Sgiacomo.travaglini@arm.com        expected, self.GenerateMocks(source))
44613481Sgiacomo.travaglini@arm.com
44713481Sgiacomo.travaglini@arm.comif __name__ == '__main__':
44813481Sgiacomo.travaglini@arm.com  unittest.main()
449