diff options
Diffstat (limited to 'googlemock/scripts/generator/cpp')
| -rwxr-xr-x | googlemock/scripts/generator/cpp/gmock_class.py | 348 | ||||
| -rwxr-xr-x | googlemock/scripts/generator/cpp/gmock_class_test.py | 429 | 
2 files changed, 406 insertions, 371 deletions
| diff --git a/googlemock/scripts/generator/cpp/gmock_class.py b/googlemock/scripts/generator/cpp/gmock_class.py index 85a3e61e..89862ae1 100755 --- a/googlemock/scripts/generator/cpp/gmock_class.py +++ b/googlemock/scripts/generator/cpp/gmock_class.py @@ -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,182 +47,202 @@ _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 of the type +    Rendered string and a boolean to indicate whether we have multiple args +    (which is not handled correctly).    """ -  # 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 +    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  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. -      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) -      ]) +    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)])  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) diff --git a/googlemock/scripts/generator/cpp/gmock_class_test.py b/googlemock/scripts/generator/cpp/gmock_class_test.py index 4e18a850..211a92dd 100755 --- a/googlemock/scripts/generator/cpp/gmock_class_test.py +++ b/googlemock/scripts/generator/cpp/gmock_class_test.py @@ -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_METHOD(int, Bar, (), (override));', -        self.GenerateMethodSource(source)) +        self.assertEqualIgnoreLeadingWhitespace( +            'MOCK_METHOD0(Bar,\nint());', +            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_METHOD(int, Bar, (), (override));', -        self.GenerateMethodSource(source)) +        # The constructors and destructor should be ignored. +        self.assertEqualIgnoreLeadingWhitespace( +            'MOCK_METHOD0(Bar,\nint());', +            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_METHOD(int, Bar, (), (override));', -        self.GenerateMethodSource(source)) +        # The destructor should be ignored. +        self.assertEqualIgnoreLeadingWhitespace( +            'MOCK_METHOD0(Bar,\nint());', +            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_METHOD(int, Bar, (), (override));', -        self.GenerateMethodSource(source)) +        # The constructors and destructor should be ignored. +        self.assertEqualIgnoreLeadingWhitespace( +            'MOCK_METHOD0(Bar,\nint());', +            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_METHOD(int, Bar, (), (override));', -        self.GenerateMethodSource(source)) +        # The constructors and destructor should be ignored. +        self.assertEqualIgnoreLeadingWhitespace( +            'MOCK_METHOD0(Bar,\nint());', +            self.GenerateMethodSource(source)) -  def testSimpleOverrideMethod(self): -    source = """ +    def testSimpleOverrideMethod(self): +        source = """  class Foo {   public:    int Bar() override;  };  """ -    self.assertEqualIgnoreLeadingWhitespace( -        'MOCK_METHOD(int, Bar, (), (override));', -        self.GenerateMethodSource(source)) +        self.assertEqualIgnoreLeadingWhitespace( +            'MOCK_METHOD0(Bar,\nint());', +            self.GenerateMethodSource(source)) -  def testSimpleConstMethod(self): -    source = """ +    def testSimpleConstMethod(self): +        source = """  class Foo {   public:    virtual void Bar(bool flag) const;  };  """ -    self.assertEqualIgnoreLeadingWhitespace( -        'MOCK_METHOD(void, Bar, (bool flag), (const, override));', -        self.GenerateMethodSource(source)) +        self.assertEqualIgnoreLeadingWhitespace( +            'MOCK_CONST_METHOD1(Bar,\nvoid(bool flag));', +            self.GenerateMethodSource(source)) -  def testExplicitVoid(self): -    source = """ +    def testExplicitVoid(self): +        source = """  class Foo {   public:    virtual int Bar(void);  };  """ -    self.assertEqualIgnoreLeadingWhitespace( -        'MOCK_METHOD(int, Bar, (void), (override));', -        self.GenerateMethodSource(source)) +        self.assertEqualIgnoreLeadingWhitespace( +            'MOCK_METHOD0(Bar,\nint(void));', +            self.GenerateMethodSource(source)) -  def testStrangeNewlineInParameter(self): -    source = """ +    def testStrangeNewlineInParameter(self): +        source = """  class Foo {   public:    virtual void Bar(int  a) = 0;  };  """ -    self.assertEqualIgnoreLeadingWhitespace( -        'MOCK_METHOD(void, Bar, (int a), (override));', -        self.GenerateMethodSource(source)) +        self.assertEqualIgnoreLeadingWhitespace( +            'MOCK_METHOD1(Bar,\nvoid(int a));', +            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_METHOD(void, Bar, (int a, char c), (override));', -        self.GenerateMethodSource(source)) +        self.assertEqualIgnoreLeadingWhitespace( +            'MOCK_METHOD2(Bar,\nvoid(int a, char c ));', +            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_METHOD(void, Bar, ' -        '(int a, char c, const int* const p, const std::string& s, char tab[], int const *& rp), ' -        '(override));', self.GenerateMethodSource(source)) +        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)) -  def testConstDefaultParameter(self): -    source = """ +    def testConstDefaultParameter(self): +        source = """  class Test {   public:    virtual bool Bar(const int test_arg = 42) = 0;  };  """ -    self.assertEqualIgnoreLeadingWhitespace( -        'MOCK_METHOD(bool, Bar, (const int test_arg), (override));', -        self.GenerateMethodSource(source)) +        expected = 'MOCK_METHOD1(Bar,\nbool(const int test_arg ));' +        self.assertEqualIgnoreLeadingWhitespace( +            expected, self.GenerateMethodSource(source)) -  def testConstRefDefaultParameter(self): -    source = """ +    def testConstRefDefaultParameter(self): +        source = """  class Test {   public:    virtual bool Bar(const std::string& test_arg = "42" ) = 0;  };  """ -    self.assertEqualIgnoreLeadingWhitespace( -        'MOCK_METHOD(bool, Bar, (const std::string& test_arg), (override));', -        self.GenerateMethodSource(source)) +        expected = 'MOCK_METHOD1(Bar,\nbool(const std::string& test_arg ));' +        self.assertEqualIgnoreLeadingWhitespace( +            expected, 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_METHOD(void, Bar, (int a, char c), (override));', -        self.GenerateMethodSource(source)) +        self.assertEqualIgnoreLeadingWhitespace( +            'MOCK_METHOD2(Bar,\nvoid(int a , char c));', +            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,111 +243,117 @@ class Foo {                     ) const = 0;  };  """ -    self.assertEqualIgnoreLeadingWhitespace( -        'MOCK_METHOD(void, Bar, (int a, int b), (const, override));', -        self.GenerateMethodSource(source)) +        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 = """ +    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_METHOD(const string&, Bar, (int, int b), (override));', -        self.GenerateMethodSource(source)) +        self.assertEqualIgnoreLeadingWhitespace( +            'MOCK_METHOD2(Bar,\nconst string&(int , int b));', +            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_METHOD(int, Bar, (const vector<int>& v, map<int, string>* output), (override));', -        self.GenerateMethodSource(source)) +        self.assertEqualIgnoreLeadingWhitespace( +            'MOCK_METHOD2(Bar,\n' +            'int(const vector<int>& v, map<int, string>* output));', +            self.GenerateMethodSource(source)) -  def testReturnTypeWithOneTemplateArg(self): -    source = """ +    def testReturnTypeWithOneTemplateArg(self): +        source = """  class Foo {   public:    virtual vector<int>* Bar(int n);  };""" -    self.assertEqualIgnoreLeadingWhitespace( -        'MOCK_METHOD(vector<int>*, Bar, (int n), (override));', -        self.GenerateMethodSource(source)) +        self.assertEqualIgnoreLeadingWhitespace( +            'MOCK_METHOD1(Bar,\nvector<int>*(int n));', +            self.GenerateMethodSource(source)) -  def testReturnTypeWithManyTemplateArgs(self): -    source = """ +    def testReturnTypeWithManyTemplateArgs(self): +        source = """  class Foo {   public:    virtual map<int, string> Bar();  };""" -    self.assertEqualIgnoreLeadingWhitespace( -        'MOCK_METHOD((map<int, string>), Bar, (), (override));', -        self.GenerateMethodSource(source)) - -  def testSimpleMethodInTemplatedClass(self): -    source = """ +        # 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_METHOD(int, Bar, (), (override));', -        self.GenerateMethodSource(source)) +        self.assertEqualIgnoreLeadingWhitespace( +            'MOCK_METHOD0_T(Bar,\nint());', +            self.GenerateMethodSource(source)) -  def testPointerArgWithoutNames(self): -    source = """ +    def testPointerArgWithoutNames(self): +        source = """  class Foo {    virtual int Bar(C*);  };  """ -    self.assertEqualIgnoreLeadingWhitespace( -        'MOCK_METHOD(int, Bar, (C*), (override));', -        self.GenerateMethodSource(source)) +        self.assertEqualIgnoreLeadingWhitespace( +            'MOCK_METHOD1(Bar,\nint(C*));', +            self.GenerateMethodSource(source)) -  def testReferenceArgWithoutNames(self): -    source = """ +    def testReferenceArgWithoutNames(self): +        source = """  class Foo {    virtual int Bar(C&);  };  """ -    self.assertEqualIgnoreLeadingWhitespace( -        'MOCK_METHOD(int, Bar, (C&), (override));', -        self.GenerateMethodSource(source)) +        self.assertEqualIgnoreLeadingWhitespace( +            'MOCK_METHOD1(Bar,\nint(C&));', +            self.GenerateMethodSource(source)) -  def testArrayArgWithoutNames(self): -    source = """ +    def testArrayArgWithoutNames(self): +        source = """  class Foo {    virtual int Bar(C[]);  };  """ -    self.assertEqualIgnoreLeadingWhitespace( -        'MOCK_METHOD(int, Bar, (C[]), (override));', -        self.GenerateMethodSource(source)) +        self.assertEqualIgnoreLeadingWhitespace( +            'MOCK_METHOD1(Bar,\nint(C[]));', +            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 { @@ -360,91 +366,96 @@ class Test {  }  // namespace Baz  }  // namespace Foo  """ -    expected = """\ +        expected = """\  namespace Foo {  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 = """ +    def testClassWithStorageSpecifierMacro(self): +        source = """  class STORAGE_SPECIFIER Test {   public:    virtual void Foo();  };  """ -    expected = """\ +        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 = """ +    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_METHOD(void, Foo, (), (override)); +MOCK_METHOD0(Foo, +void());  };  """ -    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_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 = """ +    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_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 = """ +    def testTemplateInATemplateTypedefWithComma(self): +        source = """  class Test {   public:    typedef std::function<void( @@ -452,17 +463,18 @@ class Test {    virtual void Bar(const FooType& test_arg);  };  """ -    expected = """\ +        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 = """ +    def testEnumType(self): +        source = """  class Test {   public:    enum Bar { @@ -471,17 +483,18 @@ class Test {    virtual void Foo();  };  """ -    expected = """\ +        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 = """ +    def testEnumClassType(self): +        source = """  class Test {   public:    enum class Bar { @@ -490,17 +503,18 @@ class Test {    virtual void Foo();  };  """ -    expected = """\ +        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 = """ +    def testStdFunction(self): +        source = """  class Test {   public:    Test(std::function<int(std::string)> foo) : foo_(foo) {} @@ -511,15 +525,16 @@ class Test {    std::function<int(std::string)> foo_;  };  """ -    expected = """\ +        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__': -  unittest.main() +    unittest.main() | 
