WebKitTools/Scripts/webkitpy/style/checkers/cpp_unittest.py
changeset 0 4f2f89ce4247
equal deleted inserted replaced
-1:000000000000 0:4f2f89ce4247
       
     1 #!/usr/bin/python
       
     2 # -*- coding: utf-8; -*-
       
     3 #
       
     4 # Copyright (C) 2009 Google Inc. All rights reserved.
       
     5 # Copyright (C) 2009 Torch Mobile Inc.
       
     6 # Copyright (C) 2009 Apple Inc. All rights reserved.
       
     7 # Copyright (C) 2010 Chris Jerdonek (cjerdonek@webkit.org)
       
     8 #
       
     9 # Redistribution and use in source and binary forms, with or without
       
    10 # modification, are permitted provided that the following conditions are
       
    11 # met:
       
    12 #
       
    13 #    * Redistributions of source code must retain the above copyright
       
    14 # notice, this list of conditions and the following disclaimer.
       
    15 #    * Redistributions in binary form must reproduce the above
       
    16 # copyright notice, this list of conditions and the following disclaimer
       
    17 # in the documentation and/or other materials provided with the
       
    18 # distribution.
       
    19 #    * Neither the name of Google Inc. nor the names of its
       
    20 # contributors may be used to endorse or promote products derived from
       
    21 # this software without specific prior written permission.
       
    22 #
       
    23 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
       
    24 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
       
    25 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
       
    26 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
       
    27 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
       
    28 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
       
    29 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
       
    30 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
       
    31 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
       
    32 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
       
    33 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
       
    34 
       
    35 """Unit test for cpp_style.py."""
       
    36 
       
    37 # FIXME: Add a good test that tests UpdateIncludeState.
       
    38 
       
    39 import codecs
       
    40 import os
       
    41 import random
       
    42 import re
       
    43 import unittest
       
    44 import cpp as cpp_style
       
    45 from cpp import CppChecker
       
    46 
       
    47 # This class works as an error collector and replaces cpp_style.Error
       
    48 # function for the unit tests.  We also verify each category we see
       
    49 # is in STYLE_CATEGORIES, to help keep that list up to date.
       
    50 class ErrorCollector:
       
    51     _all_style_categories = CppChecker.categories
       
    52     # This is a list including all categories seen in any unit test.
       
    53     _seen_style_categories = {}
       
    54 
       
    55     def __init__(self, assert_fn):
       
    56         """assert_fn: a function to call when we notice a problem."""
       
    57         self._assert_fn = assert_fn
       
    58         self._errors = []
       
    59 
       
    60     def __call__(self, unused_linenum, category, confidence, message):
       
    61         self._assert_fn(category in self._all_style_categories,
       
    62                         'Message "%s" has category "%s",'
       
    63                         ' which is not in STYLE_CATEGORIES' % (message, category))
       
    64         self._seen_style_categories[category] = 1
       
    65         self._errors.append('%s  [%s] [%d]' % (message, category, confidence))
       
    66 
       
    67     def results(self):
       
    68         if len(self._errors) < 2:
       
    69             return ''.join(self._errors)  # Most tests expect to have a string.
       
    70         else:
       
    71             return self._errors  # Let's give a list if there is more than one.
       
    72 
       
    73     def result_list(self):
       
    74         return self._errors
       
    75 
       
    76     def verify_all_categories_are_seen(self):
       
    77         """Fails if there's a category in _all_style_categories - _seen_style_categories.
       
    78 
       
    79         This should only be called after all tests are run, so
       
    80         _seen_style_categories has had a chance to fully populate.  Since
       
    81         this isn't called from within the normal unittest framework, we
       
    82         can't use the normal unittest assert macros.  Instead we just exit
       
    83         when we see an error.  Good thing this test is always run last!
       
    84         """
       
    85         for category in self._all_style_categories:
       
    86             if category not in self._seen_style_categories:
       
    87                 import sys
       
    88                 sys.exit('FATAL ERROR: There are no tests for category "%s"' % category)
       
    89 
       
    90     def remove_if_present(self, substr):
       
    91         for (index, error) in enumerate(self._errors):
       
    92             if error.find(substr) != -1:
       
    93                 self._errors = self._errors[0:index] + self._errors[(index + 1):]
       
    94                 break
       
    95 
       
    96 
       
    97 # This class is a lame mock of codecs. We do not verify filename, mode, or
       
    98 # encoding, but for the current use case it is not needed.
       
    99 class MockIo:
       
   100     def __init__(self, mock_file):
       
   101         self.mock_file = mock_file
       
   102 
       
   103     def open(self, unused_filename, unused_mode, unused_encoding, _):  # NOLINT
       
   104         # (lint doesn't like open as a method name)
       
   105         return self.mock_file
       
   106 
       
   107 
       
   108 class CppFunctionsTest(unittest.TestCase):
       
   109 
       
   110     """Supports testing functions that do not need CppStyleTestBase."""
       
   111 
       
   112     def test_is_c_or_objective_c(self):
       
   113         self.assertTrue(cpp_style.is_c_or_objective_c("c"))
       
   114         self.assertTrue(cpp_style.is_c_or_objective_c("m"))
       
   115         self.assertFalse(cpp_style.is_c_or_objective_c("cpp"))
       
   116 
       
   117 
       
   118 class CppStyleTestBase(unittest.TestCase):
       
   119     """Provides some useful helper functions for cpp_style tests.
       
   120 
       
   121     Attributes:
       
   122       min_confidence: An integer that is the current minimum confidence
       
   123                       level for the tests.
       
   124 
       
   125     """
       
   126 
       
   127     # FIXME: Refactor the unit tests so the confidence level is passed
       
   128     #        explicitly, just like it is in the real code.
       
   129     min_confidence = 1;
       
   130 
       
   131     # Helper function to avoid needing to explicitly pass confidence
       
   132     # in all the unit test calls to cpp_style.process_file_data().
       
   133     def process_file_data(self, filename, file_extension, lines, error):
       
   134         """Call cpp_style.process_file_data() with the min_confidence."""
       
   135         return cpp_style.process_file_data(filename, file_extension, lines,
       
   136                                            error, self.min_confidence)
       
   137 
       
   138     # Perform lint on single line of input and return the error message.
       
   139     def perform_single_line_lint(self, code, file_name):
       
   140         error_collector = ErrorCollector(self.assert_)
       
   141         lines = code.split('\n')
       
   142         cpp_style.remove_multi_line_comments(lines, error_collector)
       
   143         clean_lines = cpp_style.CleansedLines(lines)
       
   144         include_state = cpp_style._IncludeState()
       
   145         function_state = cpp_style._FunctionState(self.min_confidence)
       
   146         ext = file_name[file_name.rfind('.') + 1:]
       
   147         class_state = cpp_style._ClassState()
       
   148         file_state = cpp_style._FileState()
       
   149         cpp_style.process_line(file_name, ext, clean_lines, 0,
       
   150                                include_state, function_state,
       
   151                                class_state, file_state, error_collector)
       
   152         # Single-line lint tests are allowed to fail the 'unlintable function'
       
   153         # check.
       
   154         error_collector.remove_if_present(
       
   155             'Lint failed to find start of function body.')
       
   156         return error_collector.results()
       
   157 
       
   158     # Perform lint over multiple lines and return the error message.
       
   159     def perform_multi_line_lint(self, code, file_extension):
       
   160         error_collector = ErrorCollector(self.assert_)
       
   161         lines = code.split('\n')
       
   162         cpp_style.remove_multi_line_comments(lines, error_collector)
       
   163         lines = cpp_style.CleansedLines(lines)
       
   164         class_state = cpp_style._ClassState()
       
   165         file_state = cpp_style._FileState()
       
   166         for i in xrange(lines.num_lines()):
       
   167             cpp_style.check_style(lines, i, file_extension, file_state, error_collector)
       
   168             cpp_style.check_for_non_standard_constructs(lines, i, class_state,
       
   169                                                         error_collector)
       
   170         class_state.check_finished(error_collector)
       
   171         return error_collector.results()
       
   172 
       
   173     # Similar to perform_multi_line_lint, but calls check_language instead of
       
   174     # check_for_non_standard_constructs
       
   175     def perform_language_rules_check(self, file_name, code):
       
   176         error_collector = ErrorCollector(self.assert_)
       
   177         include_state = cpp_style._IncludeState()
       
   178         lines = code.split('\n')
       
   179         cpp_style.remove_multi_line_comments(lines, error_collector)
       
   180         lines = cpp_style.CleansedLines(lines)
       
   181         ext = file_name[file_name.rfind('.') + 1:]
       
   182         for i in xrange(lines.num_lines()):
       
   183             cpp_style.check_language(file_name, lines, i, ext, include_state,
       
   184                                      error_collector)
       
   185         return error_collector.results()
       
   186 
       
   187     def perform_function_lengths_check(self, code):
       
   188         """Perform Lint function length check on block of code and return warnings.
       
   189 
       
   190         Builds up an array of lines corresponding to the code and strips comments
       
   191         using cpp_style functions.
       
   192 
       
   193         Establishes an error collector and invokes the function length checking
       
   194         function following cpp_style's pattern.
       
   195 
       
   196         Args:
       
   197           code: C++ source code expected to generate a warning message.
       
   198 
       
   199         Returns:
       
   200           The accumulated errors.
       
   201         """
       
   202         error_collector = ErrorCollector(self.assert_)
       
   203         function_state = cpp_style._FunctionState(self.min_confidence)
       
   204         lines = code.split('\n')
       
   205         cpp_style.remove_multi_line_comments(lines, error_collector)
       
   206         lines = cpp_style.CleansedLines(lines)
       
   207         for i in xrange(lines.num_lines()):
       
   208             cpp_style.check_for_function_lengths(lines, i,
       
   209                                                  function_state, error_collector)
       
   210         return error_collector.results()
       
   211 
       
   212     def perform_include_what_you_use(self, code, filename='foo.h', io=codecs):
       
   213         # First, build up the include state.
       
   214         error_collector = ErrorCollector(self.assert_)
       
   215         include_state = cpp_style._IncludeState()
       
   216         lines = code.split('\n')
       
   217         cpp_style.remove_multi_line_comments(lines, error_collector)
       
   218         lines = cpp_style.CleansedLines(lines)
       
   219         file_extension = filename[filename.rfind('.') + 1:]
       
   220         for i in xrange(lines.num_lines()):
       
   221             cpp_style.check_language(filename, lines, i, file_extension, include_state,
       
   222                                      error_collector)
       
   223         # We could clear the error_collector here, but this should
       
   224         # also be fine, since our IncludeWhatYouUse unittests do not
       
   225         # have language problems.
       
   226 
       
   227         # Second, look for missing includes.
       
   228         cpp_style.check_for_include_what_you_use(filename, lines, include_state,
       
   229                                                  error_collector, io)
       
   230         return error_collector.results()
       
   231 
       
   232     # Perform lint and compare the error message with "expected_message".
       
   233     def assert_lint(self, code, expected_message, file_name='foo.cpp'):
       
   234         self.assertEquals(expected_message, self.perform_single_line_lint(code, file_name))
       
   235 
       
   236     def assert_lint_one_of_many_errors_re(self, code, expected_message_re, file_name='foo.cpp'):
       
   237         messages = self.perform_single_line_lint(code, file_name)
       
   238         for message in messages:
       
   239             if re.search(expected_message_re, message):
       
   240                 return
       
   241 
       
   242         self.assertEquals(expected_message_re, messages)
       
   243 
       
   244     def assert_multi_line_lint(self, code, expected_message, file_name='foo.h'):
       
   245         file_extension = file_name[file_name.rfind('.') + 1:]
       
   246         self.assertEquals(expected_message, self.perform_multi_line_lint(code, file_extension))
       
   247 
       
   248     def assert_multi_line_lint_re(self, code, expected_message_re, file_name='foo.h'):
       
   249         file_extension = file_name[file_name.rfind('.') + 1:]
       
   250         message = self.perform_multi_line_lint(code, file_extension)
       
   251         if not re.search(expected_message_re, message):
       
   252             self.fail('Message was:\n' + message + 'Expected match to "' + expected_message_re + '"')
       
   253 
       
   254     def assert_language_rules_check(self, file_name, code, expected_message):
       
   255         self.assertEquals(expected_message,
       
   256                           self.perform_language_rules_check(file_name, code))
       
   257 
       
   258     def assert_include_what_you_use(self, code, expected_message):
       
   259         self.assertEquals(expected_message,
       
   260                           self.perform_include_what_you_use(code))
       
   261 
       
   262     def assert_blank_lines_check(self, lines, start_errors, end_errors):
       
   263         error_collector = ErrorCollector(self.assert_)
       
   264         self.process_file_data('foo.cpp', 'cpp', lines, error_collector)
       
   265         self.assertEquals(
       
   266             start_errors,
       
   267             error_collector.results().count(
       
   268                 'Blank line at the start of a code block.  Is this needed?'
       
   269                 '  [whitespace/blank_line] [2]'))
       
   270         self.assertEquals(
       
   271             end_errors,
       
   272             error_collector.results().count(
       
   273                 'Blank line at the end of a code block.  Is this needed?'
       
   274                 '  [whitespace/blank_line] [3]'))
       
   275 
       
   276 
       
   277 class CppStyleTest(CppStyleTestBase):
       
   278 
       
   279     # Test get line width.
       
   280     def test_get_line_width(self):
       
   281         self.assertEquals(0, cpp_style.get_line_width(''))
       
   282         self.assertEquals(10, cpp_style.get_line_width(u'x' * 10))
       
   283         self.assertEquals(16, cpp_style.get_line_width(u'都|道|府|県|支庁'))
       
   284 
       
   285     def test_find_next_multi_line_comment_start(self):
       
   286         self.assertEquals(1, cpp_style.find_next_multi_line_comment_start([''], 0))
       
   287 
       
   288         lines = ['a', 'b', '/* c']
       
   289         self.assertEquals(2, cpp_style.find_next_multi_line_comment_start(lines, 0))
       
   290 
       
   291         lines = ['char a[] = "/*";']  # not recognized as comment.
       
   292         self.assertEquals(1, cpp_style.find_next_multi_line_comment_start(lines, 0))
       
   293 
       
   294     def test_find_next_multi_line_comment_end(self):
       
   295         self.assertEquals(1, cpp_style.find_next_multi_line_comment_end([''], 0))
       
   296         lines = ['a', 'b', ' c */']
       
   297         self.assertEquals(2, cpp_style.find_next_multi_line_comment_end(lines, 0))
       
   298 
       
   299     def test_remove_multi_line_comments_from_range(self):
       
   300         lines = ['a', '  /* comment ', ' * still comment', ' comment */   ', 'b']
       
   301         cpp_style.remove_multi_line_comments_from_range(lines, 1, 4)
       
   302         self.assertEquals(['a', '// dummy', '// dummy', '// dummy', 'b'], lines)
       
   303 
       
   304     def test_spaces_at_end_of_line(self):
       
   305         self.assert_lint(
       
   306             '// Hello there ',
       
   307             'Line ends in whitespace.  Consider deleting these extra spaces.'
       
   308             '  [whitespace/end_of_line] [4]')
       
   309 
       
   310     # Test C-style cast cases.
       
   311     def test_cstyle_cast(self):
       
   312         self.assert_lint(
       
   313             'int a = (int)1.0;',
       
   314             'Using C-style cast.  Use static_cast<int>(...) instead'
       
   315             '  [readability/casting] [4]')
       
   316         self.assert_lint(
       
   317             'int *a = (int *)DEFINED_VALUE;',
       
   318             'Using C-style cast.  Use reinterpret_cast<int *>(...) instead'
       
   319             '  [readability/casting] [4]', 'foo.c')
       
   320         self.assert_lint(
       
   321             'uint16 a = (uint16)1.0;',
       
   322             'Using C-style cast.  Use static_cast<uint16>(...) instead'
       
   323             '  [readability/casting] [4]')
       
   324         self.assert_lint(
       
   325             'int32 a = (int32)1.0;',
       
   326             'Using C-style cast.  Use static_cast<int32>(...) instead'
       
   327             '  [readability/casting] [4]')
       
   328         self.assert_lint(
       
   329             'uint64 a = (uint64)1.0;',
       
   330             'Using C-style cast.  Use static_cast<uint64>(...) instead'
       
   331             '  [readability/casting] [4]')
       
   332 
       
   333     # Test taking address of casts (runtime/casting)
       
   334     def test_runtime_casting(self):
       
   335         self.assert_lint(
       
   336             'int* x = &static_cast<int*>(foo);',
       
   337             'Are you taking an address of a cast?  '
       
   338             'This is dangerous: could be a temp var.  '
       
   339             'Take the address before doing the cast, rather than after'
       
   340             '  [runtime/casting] [4]')
       
   341 
       
   342         self.assert_lint(
       
   343             'int* x = &dynamic_cast<int *>(foo);',
       
   344             ['Are you taking an address of a cast?  '
       
   345              'This is dangerous: could be a temp var.  '
       
   346              'Take the address before doing the cast, rather than after'
       
   347              '  [runtime/casting] [4]',
       
   348              'Do not use dynamic_cast<>.  If you need to cast within a class '
       
   349              'hierarchy, use static_cast<> to upcast.  Google doesn\'t support '
       
   350              'RTTI.  [runtime/rtti] [5]'])
       
   351 
       
   352         self.assert_lint(
       
   353             'int* x = &reinterpret_cast<int *>(foo);',
       
   354             'Are you taking an address of a cast?  '
       
   355             'This is dangerous: could be a temp var.  '
       
   356             'Take the address before doing the cast, rather than after'
       
   357             '  [runtime/casting] [4]')
       
   358 
       
   359         # It's OK to cast an address.
       
   360         self.assert_lint(
       
   361             'int* x = reinterpret_cast<int *>(&foo);',
       
   362             '')
       
   363 
       
   364     def test_runtime_selfinit(self):
       
   365         self.assert_lint(
       
   366             'Foo::Foo(Bar r, Bel l) : r_(r_), l_(l_) { }',
       
   367             'You seem to be initializing a member variable with itself.'
       
   368             '  [runtime/init] [4]')
       
   369         self.assert_lint(
       
   370             'Foo::Foo(Bar r, Bel l) : r_(r), l_(l) { }',
       
   371             '')
       
   372         self.assert_lint(
       
   373             'Foo::Foo(Bar r) : r_(r), l_(r_), ll_(l_) { }',
       
   374             '')
       
   375 
       
   376     def test_runtime_rtti(self):
       
   377         statement = 'int* x = dynamic_cast<int*>(&foo);'
       
   378         error_message = (
       
   379             'Do not use dynamic_cast<>.  If you need to cast within a class '
       
   380             'hierarchy, use static_cast<> to upcast.  Google doesn\'t support '
       
   381             'RTTI.  [runtime/rtti] [5]')
       
   382         # dynamic_cast is disallowed in most files.
       
   383         self.assert_language_rules_check('foo.cpp', statement, error_message)
       
   384         self.assert_language_rules_check('foo.h', statement, error_message)
       
   385 
       
   386     # We cannot test this functionality because of difference of
       
   387     # function definitions.  Anyway, we may never enable this.
       
   388     #
       
   389     # # Test for unnamed arguments in a method.
       
   390     # def test_check_for_unnamed_params(self):
       
   391     #   message = ('All parameters should be named in a function'
       
   392     #              '  [readability/function] [3]')
       
   393     #   self.assert_lint('virtual void A(int*) const;', message)
       
   394     #   self.assert_lint('virtual void B(void (*fn)(int*));', message)
       
   395     #   self.assert_lint('virtual void C(int*);', message)
       
   396     #   self.assert_lint('void *(*f)(void *) = x;', message)
       
   397     #   self.assert_lint('void Method(char*) {', message)
       
   398     #   self.assert_lint('void Method(char*);', message)
       
   399     #   self.assert_lint('void Method(char* /*x*/);', message)
       
   400     #   self.assert_lint('typedef void (*Method)(int32);', message)
       
   401     #   self.assert_lint('static void operator delete[](void*) throw();', message)
       
   402     # 
       
   403     #   self.assert_lint('virtual void D(int* p);', '')
       
   404     #   self.assert_lint('void operator delete(void* x) throw();', '')
       
   405     #   self.assert_lint('void Method(char* x)\n{', '')
       
   406     #   self.assert_lint('void Method(char* /*x*/)\n{', '')
       
   407     #   self.assert_lint('void Method(char* x);', '')
       
   408     #   self.assert_lint('typedef void (*Method)(int32 x);', '')
       
   409     #   self.assert_lint('static void operator delete[](void* x) throw();', '')
       
   410     #   self.assert_lint('static void operator delete[](void* /*x*/) throw();', '')
       
   411     # 
       
   412     #   # This one should technically warn, but doesn't because the function
       
   413     #   # pointer is confusing.
       
   414     #   self.assert_lint('virtual void E(void (*fn)(int* p));', '')
       
   415 
       
   416     # Test deprecated casts such as int(d)
       
   417     def test_deprecated_cast(self):
       
   418         self.assert_lint(
       
   419             'int a = int(2.2);',
       
   420             'Using deprecated casting style.  '
       
   421             'Use static_cast<int>(...) instead'
       
   422             '  [readability/casting] [4]')
       
   423         # Checks for false positives...
       
   424         self.assert_lint(
       
   425             'int a = int(); // Constructor, o.k.',
       
   426             '')
       
   427         self.assert_lint(
       
   428             'X::X() : a(int()) {} // default Constructor, o.k.',
       
   429             '')
       
   430         self.assert_lint(
       
   431             'operator bool(); // Conversion operator, o.k.',
       
   432             '')
       
   433 
       
   434     # The second parameter to a gMock method definition is a function signature
       
   435     # that often looks like a bad cast but should not picked up by lint.
       
   436     def test_mock_method(self):
       
   437         self.assert_lint(
       
   438             'MOCK_METHOD0(method, int());',
       
   439             '')
       
   440         self.assert_lint(
       
   441             'MOCK_CONST_METHOD1(method, float(string));',
       
   442             '')
       
   443         self.assert_lint(
       
   444             'MOCK_CONST_METHOD2_T(method, double(float, float));',
       
   445             '')
       
   446 
       
   447     # Test sizeof(type) cases.
       
   448     def test_sizeof_type(self):
       
   449         self.assert_lint(
       
   450             'sizeof(int);',
       
   451             'Using sizeof(type).  Use sizeof(varname) instead if possible'
       
   452             '  [runtime/sizeof] [1]')
       
   453         self.assert_lint(
       
   454             'sizeof(int *);',
       
   455             'Using sizeof(type).  Use sizeof(varname) instead if possible'
       
   456             '  [runtime/sizeof] [1]')
       
   457 
       
   458     # Test typedef cases.  There was a bug that cpp_style misidentified
       
   459     # typedef for pointer to function as C-style cast and produced
       
   460     # false-positive error messages.
       
   461     def test_typedef_for_pointer_to_function(self):
       
   462         self.assert_lint(
       
   463             'typedef void (*Func)(int x);',
       
   464             '')
       
   465         self.assert_lint(
       
   466             'typedef void (*Func)(int *x);',
       
   467             '')
       
   468         self.assert_lint(
       
   469             'typedef void Func(int x);',
       
   470             '')
       
   471         self.assert_lint(
       
   472             'typedef void Func(int *x);',
       
   473             '')
       
   474 
       
   475     def test_include_what_you_use_no_implementation_files(self):
       
   476         code = 'std::vector<int> foo;'
       
   477         self.assertEquals('Add #include <vector> for vector<>'
       
   478                           '  [build/include_what_you_use] [4]',
       
   479                           self.perform_include_what_you_use(code, 'foo.h'))
       
   480         self.assertEquals('',
       
   481                           self.perform_include_what_you_use(code, 'foo.cpp'))
       
   482 
       
   483     def test_include_what_you_use(self):
       
   484         self.assert_include_what_you_use(
       
   485             '''#include <vector>
       
   486                std::vector<int> foo;
       
   487             ''',
       
   488             '')
       
   489         self.assert_include_what_you_use(
       
   490             '''#include <map>
       
   491                std::pair<int,int> foo;
       
   492             ''',
       
   493             '')
       
   494         self.assert_include_what_you_use(
       
   495             '''#include <multimap>
       
   496                std::pair<int,int> foo;
       
   497             ''',
       
   498             '')
       
   499         self.assert_include_what_you_use(
       
   500             '''#include <hash_map>
       
   501                std::pair<int,int> foo;
       
   502             ''',
       
   503             '')
       
   504         self.assert_include_what_you_use(
       
   505             '''#include <utility>
       
   506                std::pair<int,int> foo;
       
   507             ''',
       
   508             '')
       
   509         self.assert_include_what_you_use(
       
   510             '''#include <vector>
       
   511                DECLARE_string(foobar);
       
   512             ''',
       
   513             '')
       
   514         self.assert_include_what_you_use(
       
   515             '''#include <vector>
       
   516                DEFINE_string(foobar, "", "");
       
   517             ''',
       
   518             '')
       
   519         self.assert_include_what_you_use(
       
   520             '''#include <vector>
       
   521                std::pair<int,int> foo;
       
   522             ''',
       
   523             'Add #include <utility> for pair<>'
       
   524             '  [build/include_what_you_use] [4]')
       
   525         self.assert_include_what_you_use(
       
   526             '''#include "base/foobar.h"
       
   527                std::vector<int> foo;
       
   528             ''',
       
   529             'Add #include <vector> for vector<>'
       
   530             '  [build/include_what_you_use] [4]')
       
   531         self.assert_include_what_you_use(
       
   532             '''#include <vector>
       
   533                std::set<int> foo;
       
   534             ''',
       
   535             'Add #include <set> for set<>'
       
   536             '  [build/include_what_you_use] [4]')
       
   537         self.assert_include_what_you_use(
       
   538             '''#include "base/foobar.h"
       
   539               hash_map<int, int> foobar;
       
   540             ''',
       
   541             'Add #include <hash_map> for hash_map<>'
       
   542             '  [build/include_what_you_use] [4]')
       
   543         self.assert_include_what_you_use(
       
   544             '''#include "base/foobar.h"
       
   545                bool foobar = std::less<int>(0,1);
       
   546             ''',
       
   547             'Add #include <functional> for less<>'
       
   548             '  [build/include_what_you_use] [4]')
       
   549         self.assert_include_what_you_use(
       
   550             '''#include "base/foobar.h"
       
   551                bool foobar = min<int>(0,1);
       
   552             ''',
       
   553             'Add #include <algorithm> for min  [build/include_what_you_use] [4]')
       
   554         self.assert_include_what_you_use(
       
   555             'void a(const string &foobar);',
       
   556             'Add #include <string> for string  [build/include_what_you_use] [4]')
       
   557         self.assert_include_what_you_use(
       
   558             '''#include "base/foobar.h"
       
   559                bool foobar = swap(0,1);
       
   560             ''',
       
   561             'Add #include <algorithm> for swap  [build/include_what_you_use] [4]')
       
   562         self.assert_include_what_you_use(
       
   563             '''#include "base/foobar.h"
       
   564                bool foobar = transform(a.begin(), a.end(), b.start(), Foo);
       
   565             ''',
       
   566             'Add #include <algorithm> for transform  '
       
   567             '[build/include_what_you_use] [4]')
       
   568         self.assert_include_what_you_use(
       
   569             '''#include "base/foobar.h"
       
   570                bool foobar = min_element(a.begin(), a.end());
       
   571             ''',
       
   572             'Add #include <algorithm> for min_element  '
       
   573             '[build/include_what_you_use] [4]')
       
   574         self.assert_include_what_you_use(
       
   575             '''foo->swap(0,1);
       
   576                foo.swap(0,1);
       
   577             ''',
       
   578             '')
       
   579         self.assert_include_what_you_use(
       
   580             '''#include <string>
       
   581                void a(const std::multimap<int,string> &foobar);
       
   582             ''',
       
   583             'Add #include <map> for multimap<>'
       
   584             '  [build/include_what_you_use] [4]')
       
   585         self.assert_include_what_you_use(
       
   586             '''#include <queue>
       
   587                void a(const std::priority_queue<int> &foobar);
       
   588             ''',
       
   589             '')
       
   590         self.assert_include_what_you_use(
       
   591              '''#include "base/basictypes.h"
       
   592                 #include "base/port.h"
       
   593                 #include <assert.h>
       
   594                 #include <string>
       
   595                 #include <vector>
       
   596                 vector<string> hajoa;''', '')
       
   597         self.assert_include_what_you_use(
       
   598             '''#include <string>
       
   599                int i = numeric_limits<int>::max()
       
   600             ''',
       
   601             'Add #include <limits> for numeric_limits<>'
       
   602             '  [build/include_what_you_use] [4]')
       
   603         self.assert_include_what_you_use(
       
   604             '''#include <limits>
       
   605                int i = numeric_limits<int>::max()
       
   606             ''',
       
   607             '')
       
   608 
       
   609         # Test the UpdateIncludeState code path.
       
   610         mock_header_contents = ['#include "blah/foo.h"', '#include "blah/bar.h"']
       
   611         message = self.perform_include_what_you_use(
       
   612             '#include "config.h"\n'
       
   613             '#include "blah/a.h"\n',
       
   614             filename='blah/a.cpp',
       
   615             io=MockIo(mock_header_contents))
       
   616         self.assertEquals(message, '')
       
   617 
       
   618         mock_header_contents = ['#include <set>']
       
   619         message = self.perform_include_what_you_use(
       
   620             '''#include "config.h"
       
   621                #include "blah/a.h"
       
   622 
       
   623                std::set<int> foo;''',
       
   624             filename='blah/a.cpp',
       
   625             io=MockIo(mock_header_contents))
       
   626         self.assertEquals(message, '')
       
   627 
       
   628         # If there's just a .cpp and the header can't be found then it's ok.
       
   629         message = self.perform_include_what_you_use(
       
   630             '''#include "config.h"
       
   631                #include "blah/a.h"
       
   632 
       
   633                std::set<int> foo;''',
       
   634             filename='blah/a.cpp')
       
   635         self.assertEquals(message, '')
       
   636 
       
   637         # Make sure we find the headers with relative paths.
       
   638         mock_header_contents = ['']
       
   639         message = self.perform_include_what_you_use(
       
   640             '''#include "config.h"
       
   641                #include "%s/a.h"
       
   642 
       
   643                std::set<int> foo;''' % os.path.basename(os.getcwd()),
       
   644             filename='a.cpp',
       
   645             io=MockIo(mock_header_contents))
       
   646         self.assertEquals(message, 'Add #include <set> for set<>  '
       
   647                                    '[build/include_what_you_use] [4]')
       
   648 
       
   649     def test_files_belong_to_same_module(self):
       
   650         f = cpp_style.files_belong_to_same_module
       
   651         self.assertEquals((True, ''), f('a.cpp', 'a.h'))
       
   652         self.assertEquals((True, ''), f('base/google.cpp', 'base/google.h'))
       
   653         self.assertEquals((True, ''), f('base/google_test.cpp', 'base/google.h'))
       
   654         self.assertEquals((True, ''),
       
   655                           f('base/google_unittest.cpp', 'base/google.h'))
       
   656         self.assertEquals((True, ''),
       
   657                           f('base/internal/google_unittest.cpp',
       
   658                             'base/public/google.h'))
       
   659         self.assertEquals((True, 'xxx/yyy/'),
       
   660                           f('xxx/yyy/base/internal/google_unittest.cpp',
       
   661                             'base/public/google.h'))
       
   662         self.assertEquals((True, 'xxx/yyy/'),
       
   663                           f('xxx/yyy/base/google_unittest.cpp',
       
   664                             'base/public/google.h'))
       
   665         self.assertEquals((True, ''),
       
   666                           f('base/google_unittest.cpp', 'base/google-inl.h'))
       
   667         self.assertEquals((True, '/home/build/google3/'),
       
   668                           f('/home/build/google3/base/google.cpp', 'base/google.h'))
       
   669 
       
   670         self.assertEquals((False, ''),
       
   671                           f('/home/build/google3/base/google.cpp', 'basu/google.h'))
       
   672         self.assertEquals((False, ''), f('a.cpp', 'b.h'))
       
   673 
       
   674     def test_cleanse_line(self):
       
   675         self.assertEquals('int foo = 0;  ',
       
   676                           cpp_style.cleanse_comments('int foo = 0;  // danger!'))
       
   677         self.assertEquals('int o = 0;',
       
   678                           cpp_style.cleanse_comments('int /* foo */ o = 0;'))
       
   679         self.assertEquals('foo(int a, int b);',
       
   680                           cpp_style.cleanse_comments('foo(int a /* abc */, int b);'))
       
   681         self.assertEqual('f(a, b);',
       
   682                          cpp_style.cleanse_comments('f(a, /* name */ b);'))
       
   683         self.assertEqual('f(a, b);',
       
   684                          cpp_style.cleanse_comments('f(a /* name */, b);'))
       
   685         self.assertEqual('f(a, b);',
       
   686                          cpp_style.cleanse_comments('f(a, /* name */b);'))
       
   687 
       
   688     def test_multi_line_comments(self):
       
   689         # missing explicit is bad
       
   690         self.assert_multi_line_lint(
       
   691             r'''int a = 0;
       
   692                 /* multi-liner
       
   693                 class Foo {
       
   694                 Foo(int f);  // should cause a lint warning in code
       
   695                 }
       
   696             */ ''',
       
   697         '')
       
   698         self.assert_multi_line_lint(
       
   699             r'''/* int a = 0; multi-liner
       
   700             static const int b = 0;''',
       
   701       'Could not find end of multi-line comment'
       
   702       '  [readability/multiline_comment] [5]')
       
   703         self.assert_multi_line_lint(r'''    /* multi-line comment''',
       
   704                                     'Could not find end of multi-line comment'
       
   705                                     '  [readability/multiline_comment] [5]')
       
   706         self.assert_multi_line_lint(r'''    // /* comment, but not multi-line''', '')
       
   707 
       
   708     def test_multiline_strings(self):
       
   709         multiline_string_error_message = (
       
   710             'Multi-line string ("...") found.  This lint script doesn\'t '
       
   711             'do well with such strings, and may give bogus warnings.  They\'re '
       
   712             'ugly and unnecessary, and you should use concatenation instead".'
       
   713             '  [readability/multiline_string] [5]')
       
   714 
       
   715         file_path = 'mydir/foo.cpp'
       
   716 
       
   717         error_collector = ErrorCollector(self.assert_)
       
   718         self.process_file_data(file_path, 'cpp',
       
   719                                ['const char* str = "This is a\\',
       
   720                                 ' multiline string.";'],
       
   721                                error_collector)
       
   722         self.assertEquals(
       
   723             2,  # One per line.
       
   724             error_collector.result_list().count(multiline_string_error_message))
       
   725 
       
   726     # Test non-explicit single-argument constructors
       
   727     def test_explicit_single_argument_constructors(self):
       
   728         # missing explicit is bad
       
   729         self.assert_multi_line_lint(
       
   730             '''class Foo {
       
   731                  Foo(int f);
       
   732                };''',
       
   733             'Single-argument constructors should be marked explicit.'
       
   734             '  [runtime/explicit] [5]')
       
   735         # missing explicit is bad, even with whitespace
       
   736         self.assert_multi_line_lint(
       
   737             '''class Foo {
       
   738                  Foo (int f);
       
   739                };''',
       
   740             ['Extra space before ( in function call  [whitespace/parens] [4]',
       
   741              'Single-argument constructors should be marked explicit.'
       
   742              '  [runtime/explicit] [5]'])
       
   743         # missing explicit, with distracting comment, is still bad
       
   744         self.assert_multi_line_lint(
       
   745             '''class Foo {
       
   746                  Foo(int f); // simpler than Foo(blargh, blarg)
       
   747                };''',
       
   748             'Single-argument constructors should be marked explicit.'
       
   749             '  [runtime/explicit] [5]')
       
   750         # missing explicit, with qualified classname
       
   751         self.assert_multi_line_lint(
       
   752             '''class Qualifier::AnotherOne::Foo {
       
   753                  Foo(int f);
       
   754                };''',
       
   755             'Single-argument constructors should be marked explicit.'
       
   756             '  [runtime/explicit] [5]')
       
   757         # structs are caught as well.
       
   758         self.assert_multi_line_lint(
       
   759             '''struct Foo {
       
   760                  Foo(int f);
       
   761                };''',
       
   762             'Single-argument constructors should be marked explicit.'
       
   763             '  [runtime/explicit] [5]')
       
   764         # Templatized classes are caught as well.
       
   765         self.assert_multi_line_lint(
       
   766             '''template<typename T> class Foo {
       
   767                  Foo(int f);
       
   768                };''',
       
   769             'Single-argument constructors should be marked explicit.'
       
   770             '  [runtime/explicit] [5]')
       
   771         # proper style is okay
       
   772         self.assert_multi_line_lint(
       
   773             '''class Foo {
       
   774                  explicit Foo(int f);
       
   775                };''',
       
   776             '')
       
   777         # two argument constructor is okay
       
   778         self.assert_multi_line_lint(
       
   779             '''class Foo {
       
   780                  Foo(int f, int b);
       
   781                };''',
       
   782             '')
       
   783         # two argument constructor, across two lines, is okay
       
   784         self.assert_multi_line_lint(
       
   785             '''class Foo {
       
   786                  Foo(int f,
       
   787                      int b);
       
   788                };''',
       
   789             '')
       
   790         # non-constructor (but similar name), is okay
       
   791         self.assert_multi_line_lint(
       
   792             '''class Foo {
       
   793                  aFoo(int f);
       
   794                };''',
       
   795             '')
       
   796         # constructor with void argument is okay
       
   797         self.assert_multi_line_lint(
       
   798             '''class Foo {
       
   799                  Foo(void);
       
   800                };''',
       
   801             '')
       
   802         # single argument method is okay
       
   803         self.assert_multi_line_lint(
       
   804             '''class Foo {
       
   805                  Bar(int b);
       
   806                };''',
       
   807             '')
       
   808         # comments should be ignored
       
   809         self.assert_multi_line_lint(
       
   810             '''class Foo {
       
   811                // Foo(int f);
       
   812                };''',
       
   813             '')
       
   814         # single argument function following class definition is okay
       
   815         # (okay, it's not actually valid, but we don't want a false positive)
       
   816         self.assert_multi_line_lint(
       
   817             '''class Foo {
       
   818                  Foo(int f, int b);
       
   819                };
       
   820                Foo(int f);''',
       
   821             '')
       
   822         # single argument function is okay
       
   823         self.assert_multi_line_lint(
       
   824             '''static Foo(int f);''',
       
   825             '')
       
   826         # single argument copy constructor is okay.
       
   827         self.assert_multi_line_lint(
       
   828             '''class Foo {
       
   829                  Foo(const Foo&);
       
   830                };''',
       
   831             '')
       
   832         self.assert_multi_line_lint(
       
   833             '''class Foo {
       
   834                  Foo(Foo&);
       
   835                };''',
       
   836             '')
       
   837 
       
   838     def test_slash_star_comment_on_single_line(self):
       
   839         self.assert_multi_line_lint(
       
   840             '''/* static */ Foo(int f);''',
       
   841             '')
       
   842         self.assert_multi_line_lint(
       
   843             '''/*/ static */  Foo(int f);''',
       
   844             '')
       
   845         self.assert_multi_line_lint(
       
   846             '''/*/ static Foo(int f);''',
       
   847             'Could not find end of multi-line comment'
       
   848             '  [readability/multiline_comment] [5]')
       
   849         self.assert_multi_line_lint(
       
   850             '''    /*/ static Foo(int f);''',
       
   851             'Could not find end of multi-line comment'
       
   852             '  [readability/multiline_comment] [5]')
       
   853         self.assert_multi_line_lint(
       
   854             '''    /**/ static Foo(int f);''',
       
   855             '')
       
   856 
       
   857     # Test suspicious usage of "if" like this:
       
   858     # if (a == b) {
       
   859     #   DoSomething();
       
   860     # } if (a == c) {   // Should be "else if".
       
   861     #   DoSomething();  // This gets called twice if a == b && a == c.
       
   862     # }
       
   863     def test_suspicious_usage_of_if(self):
       
   864         self.assert_lint(
       
   865             '    if (a == b) {',
       
   866             '')
       
   867         self.assert_lint(
       
   868             '    } if (a == b) {',
       
   869             'Did you mean "else if"? If not, start a new line for "if".'
       
   870             '  [readability/braces] [4]')
       
   871 
       
   872     # Test suspicious usage of memset. Specifically, a 0
       
   873     # as the final argument is almost certainly an error.
       
   874     def test_suspicious_usage_of_memset(self):
       
   875         # Normal use is okay.
       
   876         self.assert_lint(
       
   877             '    memset(buf, 0, sizeof(buf))',
       
   878             '')
       
   879 
       
   880         # A 0 as the final argument is almost certainly an error.
       
   881         self.assert_lint(
       
   882             '    memset(buf, sizeof(buf), 0)',
       
   883             'Did you mean "memset(buf, 0, sizeof(buf))"?'
       
   884             '  [runtime/memset] [4]')
       
   885         self.assert_lint(
       
   886             '    memset(buf, xsize * ysize, 0)',
       
   887             'Did you mean "memset(buf, 0, xsize * ysize)"?'
       
   888             '  [runtime/memset] [4]')
       
   889 
       
   890         # There is legitimate test code that uses this form.
       
   891         # This is okay since the second argument is a literal.
       
   892         self.assert_lint(
       
   893             "    memset(buf, 'y', 0)",
       
   894             '')
       
   895         self.assert_lint(
       
   896             '    memset(buf, 4, 0)',
       
   897             '')
       
   898         self.assert_lint(
       
   899             '    memset(buf, -1, 0)',
       
   900             '')
       
   901         self.assert_lint(
       
   902             '    memset(buf, 0xF1, 0)',
       
   903             '')
       
   904         self.assert_lint(
       
   905             '    memset(buf, 0xcd, 0)',
       
   906             '')
       
   907 
       
   908     def test_check_posix_threading(self):
       
   909         self.assert_lint('sctime_r()', '')
       
   910         self.assert_lint('strtok_r()', '')
       
   911         self.assert_lint('    strtok_r(foo, ba, r)', '')
       
   912         self.assert_lint('brand()', '')
       
   913         self.assert_lint('_rand()', '')
       
   914         self.assert_lint('.rand()', '')
       
   915         self.assert_lint('>rand()', '')
       
   916         self.assert_lint('rand()',
       
   917                          'Consider using rand_r(...) instead of rand(...)'
       
   918                          ' for improved thread safety.'
       
   919                          '  [runtime/threadsafe_fn] [2]')
       
   920         self.assert_lint('strtok()',
       
   921                          'Consider using strtok_r(...) '
       
   922                          'instead of strtok(...)'
       
   923                          ' for improved thread safety.'
       
   924                          '  [runtime/threadsafe_fn] [2]')
       
   925 
       
   926     # Test potential format string bugs like printf(foo).
       
   927     def test_format_strings(self):
       
   928         self.assert_lint('printf("foo")', '')
       
   929         self.assert_lint('printf("foo: %s", foo)', '')
       
   930         self.assert_lint('DocidForPrintf(docid)', '')  # Should not trigger.
       
   931         self.assert_lint(
       
   932             'printf(foo)',
       
   933             'Potential format string bug. Do printf("%s", foo) instead.'
       
   934             '  [runtime/printf] [4]')
       
   935         self.assert_lint(
       
   936             'printf(foo.c_str())',
       
   937             'Potential format string bug. '
       
   938             'Do printf("%s", foo.c_str()) instead.'
       
   939             '  [runtime/printf] [4]')
       
   940         self.assert_lint(
       
   941             'printf(foo->c_str())',
       
   942             'Potential format string bug. '
       
   943             'Do printf("%s", foo->c_str()) instead.'
       
   944             '  [runtime/printf] [4]')
       
   945         self.assert_lint(
       
   946             'StringPrintf(foo)',
       
   947             'Potential format string bug. Do StringPrintf("%s", foo) instead.'
       
   948             ''
       
   949             '  [runtime/printf] [4]')
       
   950 
       
   951     # Variable-length arrays are not permitted.
       
   952     def test_variable_length_array_detection(self):
       
   953         errmsg = ('Do not use variable-length arrays.  Use an appropriately named '
       
   954                   "('k' followed by CamelCase) compile-time constant for the size."
       
   955                   '  [runtime/arrays] [1]')
       
   956 
       
   957         self.assert_lint('int a[any_old_variable];', errmsg)
       
   958         self.assert_lint('int doublesize[some_var * 2];', errmsg)
       
   959         self.assert_lint('int a[afunction()];', errmsg)
       
   960         self.assert_lint('int a[function(kMaxFooBars)];', errmsg)
       
   961         self.assert_lint('bool aList[items_->size()];', errmsg)
       
   962         self.assert_lint('namespace::Type buffer[len+1];', errmsg)
       
   963 
       
   964         self.assert_lint('int a[64];', '')
       
   965         self.assert_lint('int a[0xFF];', '')
       
   966         self.assert_lint('int first[256], second[256];', '')
       
   967         self.assert_lint('int arrayName[kCompileTimeConstant];', '')
       
   968         self.assert_lint('char buf[somenamespace::kBufSize];', '')
       
   969         self.assert_lint('int arrayName[ALL_CAPS];', '')
       
   970         self.assert_lint('AClass array1[foo::bar::ALL_CAPS];', '')
       
   971         self.assert_lint('int a[kMaxStrLen + 1];', '')
       
   972         self.assert_lint('int a[sizeof(foo)];', '')
       
   973         self.assert_lint('int a[sizeof(*foo)];', '')
       
   974         self.assert_lint('int a[sizeof foo];', '')
       
   975         self.assert_lint('int a[sizeof(struct Foo)];', '')
       
   976         self.assert_lint('int a[128 - sizeof(const bar)];', '')
       
   977         self.assert_lint('int a[(sizeof(foo) * 4)];', '')
       
   978         self.assert_lint('int a[(arraysize(fixed_size_array)/2) << 1];', 'Missing spaces around /  [whitespace/operators] [3]')
       
   979         self.assert_lint('delete a[some_var];', '')
       
   980         self.assert_lint('return a[some_var];', '')
       
   981 
       
   982     # Brace usage
       
   983     def test_braces(self):
       
   984         # Braces shouldn't be followed by a ; unless they're defining a struct
       
   985         # or initializing an array
       
   986         self.assert_lint('int a[3] = { 1, 2, 3 };', '')
       
   987         self.assert_lint(
       
   988             '''const int foo[] =
       
   989                    {1, 2, 3 };''',
       
   990             '')
       
   991         # For single line, unmatched '}' with a ';' is ignored (not enough context)
       
   992         self.assert_multi_line_lint(
       
   993             '''int a[3] = { 1,
       
   994                             2,
       
   995                             3 };''',
       
   996             '')
       
   997         self.assert_multi_line_lint(
       
   998             '''int a[2][3] = { { 1, 2 },
       
   999                              { 3, 4 } };''',
       
  1000             '')
       
  1001         self.assert_multi_line_lint(
       
  1002             '''int a[2][3] =
       
  1003                    { { 1, 2 },
       
  1004                      { 3, 4 } };''',
       
  1005             '')
       
  1006 
       
  1007     # CHECK/EXPECT_TRUE/EXPECT_FALSE replacements
       
  1008     def test_check_check(self):
       
  1009         self.assert_lint('CHECK(x == 42)',
       
  1010                          'Consider using CHECK_EQ instead of CHECK(a == b)'
       
  1011                          '  [readability/check] [2]')
       
  1012         self.assert_lint('CHECK(x != 42)',
       
  1013                          'Consider using CHECK_NE instead of CHECK(a != b)'
       
  1014                          '  [readability/check] [2]')
       
  1015         self.assert_lint('CHECK(x >= 42)',
       
  1016                          'Consider using CHECK_GE instead of CHECK(a >= b)'
       
  1017                          '  [readability/check] [2]')
       
  1018         self.assert_lint('CHECK(x > 42)',
       
  1019                          'Consider using CHECK_GT instead of CHECK(a > b)'
       
  1020                          '  [readability/check] [2]')
       
  1021         self.assert_lint('CHECK(x <= 42)',
       
  1022                          'Consider using CHECK_LE instead of CHECK(a <= b)'
       
  1023                          '  [readability/check] [2]')
       
  1024         self.assert_lint('CHECK(x < 42)',
       
  1025                          'Consider using CHECK_LT instead of CHECK(a < b)'
       
  1026                          '  [readability/check] [2]')
       
  1027 
       
  1028         self.assert_lint('DCHECK(x == 42)',
       
  1029                          'Consider using DCHECK_EQ instead of DCHECK(a == b)'
       
  1030                          '  [readability/check] [2]')
       
  1031         self.assert_lint('DCHECK(x != 42)',
       
  1032                          'Consider using DCHECK_NE instead of DCHECK(a != b)'
       
  1033                          '  [readability/check] [2]')
       
  1034         self.assert_lint('DCHECK(x >= 42)',
       
  1035                          'Consider using DCHECK_GE instead of DCHECK(a >= b)'
       
  1036                          '  [readability/check] [2]')
       
  1037         self.assert_lint('DCHECK(x > 42)',
       
  1038                          'Consider using DCHECK_GT instead of DCHECK(a > b)'
       
  1039                          '  [readability/check] [2]')
       
  1040         self.assert_lint('DCHECK(x <= 42)',
       
  1041                          'Consider using DCHECK_LE instead of DCHECK(a <= b)'
       
  1042                          '  [readability/check] [2]')
       
  1043         self.assert_lint('DCHECK(x < 42)',
       
  1044                          'Consider using DCHECK_LT instead of DCHECK(a < b)'
       
  1045                          '  [readability/check] [2]')
       
  1046 
       
  1047         self.assert_lint(
       
  1048             'EXPECT_TRUE("42" == x)',
       
  1049             'Consider using EXPECT_EQ instead of EXPECT_TRUE(a == b)'
       
  1050             '  [readability/check] [2]')
       
  1051         self.assert_lint(
       
  1052             'EXPECT_TRUE("42" != x)',
       
  1053             'Consider using EXPECT_NE instead of EXPECT_TRUE(a != b)'
       
  1054             '  [readability/check] [2]')
       
  1055         self.assert_lint(
       
  1056             'EXPECT_TRUE(+42 >= x)',
       
  1057             'Consider using EXPECT_GE instead of EXPECT_TRUE(a >= b)'
       
  1058             '  [readability/check] [2]')
       
  1059         self.assert_lint(
       
  1060             'EXPECT_TRUE_M(-42 > x)',
       
  1061             'Consider using EXPECT_GT_M instead of EXPECT_TRUE_M(a > b)'
       
  1062             '  [readability/check] [2]')
       
  1063         self.assert_lint(
       
  1064             'EXPECT_TRUE_M(42U <= x)',
       
  1065             'Consider using EXPECT_LE_M instead of EXPECT_TRUE_M(a <= b)'
       
  1066             '  [readability/check] [2]')
       
  1067         self.assert_lint(
       
  1068             'EXPECT_TRUE_M(42L < x)',
       
  1069             'Consider using EXPECT_LT_M instead of EXPECT_TRUE_M(a < b)'
       
  1070             '  [readability/check] [2]')
       
  1071 
       
  1072         self.assert_lint(
       
  1073             'EXPECT_FALSE(x == 42)',
       
  1074             'Consider using EXPECT_NE instead of EXPECT_FALSE(a == b)'
       
  1075             '  [readability/check] [2]')
       
  1076         self.assert_lint(
       
  1077             'EXPECT_FALSE(x != 42)',
       
  1078             'Consider using EXPECT_EQ instead of EXPECT_FALSE(a != b)'
       
  1079             '  [readability/check] [2]')
       
  1080         self.assert_lint(
       
  1081             'EXPECT_FALSE(x >= 42)',
       
  1082             'Consider using EXPECT_LT instead of EXPECT_FALSE(a >= b)'
       
  1083             '  [readability/check] [2]')
       
  1084         self.assert_lint(
       
  1085             'ASSERT_FALSE(x > 42)',
       
  1086             'Consider using ASSERT_LE instead of ASSERT_FALSE(a > b)'
       
  1087             '  [readability/check] [2]')
       
  1088         self.assert_lint(
       
  1089             'ASSERT_FALSE(x <= 42)',
       
  1090             'Consider using ASSERT_GT instead of ASSERT_FALSE(a <= b)'
       
  1091             '  [readability/check] [2]')
       
  1092         self.assert_lint(
       
  1093             'ASSERT_FALSE_M(x < 42)',
       
  1094             'Consider using ASSERT_GE_M instead of ASSERT_FALSE_M(a < b)'
       
  1095             '  [readability/check] [2]')
       
  1096 
       
  1097         self.assert_lint('CHECK(some_iterator == obj.end())', '')
       
  1098         self.assert_lint('EXPECT_TRUE(some_iterator == obj.end())', '')
       
  1099         self.assert_lint('EXPECT_FALSE(some_iterator == obj.end())', '')
       
  1100 
       
  1101         self.assert_lint('CHECK(CreateTestFile(dir, (1 << 20)));', '')
       
  1102         self.assert_lint('CHECK(CreateTestFile(dir, (1 >> 20)));', '')
       
  1103 
       
  1104         self.assert_lint('CHECK(x<42)',
       
  1105                          ['Missing spaces around <'
       
  1106                           '  [whitespace/operators] [3]',
       
  1107                           'Consider using CHECK_LT instead of CHECK(a < b)'
       
  1108                           '  [readability/check] [2]'])
       
  1109         self.assert_lint('CHECK(x>42)',
       
  1110                          'Consider using CHECK_GT instead of CHECK(a > b)'
       
  1111                          '  [readability/check] [2]')
       
  1112 
       
  1113         self.assert_lint(
       
  1114             '    EXPECT_TRUE(42 < x) // Random comment.',
       
  1115             'Consider using EXPECT_LT instead of EXPECT_TRUE(a < b)'
       
  1116             '  [readability/check] [2]')
       
  1117         self.assert_lint(
       
  1118             'EXPECT_TRUE( 42 < x )',
       
  1119             ['Extra space after ( in function call'
       
  1120              '  [whitespace/parens] [4]',
       
  1121              'Consider using EXPECT_LT instead of EXPECT_TRUE(a < b)'
       
  1122              '  [readability/check] [2]'])
       
  1123         self.assert_lint(
       
  1124             'CHECK("foo" == "foo")',
       
  1125             'Consider using CHECK_EQ instead of CHECK(a == b)'
       
  1126             '  [readability/check] [2]')
       
  1127 
       
  1128         self.assert_lint('CHECK_EQ("foo", "foo")', '')
       
  1129 
       
  1130     def test_brace_at_begin_of_line(self):
       
  1131         self.assert_lint('{',
       
  1132                          'This { should be at the end of the previous line'
       
  1133                          '  [whitespace/braces] [4]')
       
  1134         self.assert_multi_line_lint(
       
  1135             '#endif\n'
       
  1136             '{\n'
       
  1137             '}\n',
       
  1138             '')
       
  1139         self.assert_multi_line_lint(
       
  1140             'if (condition) {',
       
  1141             '')
       
  1142         self.assert_multi_line_lint(
       
  1143             '    MACRO1(macroArg) {',
       
  1144             '')
       
  1145         self.assert_multi_line_lint(
       
  1146             'ACCESSOR_GETTER(MessageEventPorts) {',
       
  1147             'Place brace on its own line for function definitions.  [whitespace/braces] [4]')
       
  1148         self.assert_multi_line_lint(
       
  1149             'int foo() {',
       
  1150             'Place brace on its own line for function definitions.  [whitespace/braces] [4]')
       
  1151         self.assert_multi_line_lint(
       
  1152             'int foo() const {',
       
  1153             'Place brace on its own line for function definitions.  [whitespace/braces] [4]')
       
  1154         self.assert_multi_line_lint(
       
  1155             'int foo() const\n'
       
  1156             '{\n'
       
  1157             '}\n',
       
  1158             '')
       
  1159         self.assert_multi_line_lint(
       
  1160             'if (condition\n'
       
  1161             '    && condition2\n'
       
  1162             '    && condition3) {\n'
       
  1163             '}\n',
       
  1164             '')
       
  1165 
       
  1166     def test_mismatching_spaces_in_parens(self):
       
  1167         self.assert_lint('if (foo ) {', 'Extra space before ) in if'
       
  1168                          '  [whitespace/parens] [5]')
       
  1169         self.assert_lint('switch ( foo) {', 'Extra space after ( in switch'
       
  1170                          '  [whitespace/parens] [5]')
       
  1171         self.assert_lint('for (foo; ba; bar ) {', 'Extra space before ) in for'
       
  1172                          '  [whitespace/parens] [5]')
       
  1173         self.assert_lint('for ((foo); (ba); (bar) ) {', 'Extra space before ) in for'
       
  1174                          '  [whitespace/parens] [5]')
       
  1175         self.assert_lint('for (; foo; bar) {', '')
       
  1176         self.assert_lint('for (; (foo); (bar)) {', '')
       
  1177         self.assert_lint('for ( ; foo; bar) {', '')
       
  1178         self.assert_lint('for ( ; (foo); (bar)) {', '')
       
  1179         self.assert_lint('for ( ; foo; bar ) {', 'Extra space before ) in for'
       
  1180                          '  [whitespace/parens] [5]')
       
  1181         self.assert_lint('for ( ; (foo); (bar) ) {', 'Extra space before ) in for'
       
  1182                          '  [whitespace/parens] [5]')
       
  1183         self.assert_lint('for (foo; bar; ) {', '')
       
  1184         self.assert_lint('for ((foo); (bar); ) {', '')
       
  1185         self.assert_lint('foreach (foo, foos ) {', 'Extra space before ) in foreach'
       
  1186                          '  [whitespace/parens] [5]')
       
  1187         self.assert_lint('foreach ( foo, foos) {', 'Extra space after ( in foreach'
       
  1188                          '  [whitespace/parens] [5]')
       
  1189         self.assert_lint('while (  foo) {', 'Extra space after ( in while'
       
  1190                          '  [whitespace/parens] [5]')
       
  1191 
       
  1192     def test_spacing_for_fncall(self):
       
  1193         self.assert_lint('if (foo) {', '')
       
  1194         self.assert_lint('for (foo;bar;baz) {', '')
       
  1195         self.assert_lint('foreach (foo, foos) {', '')
       
  1196         self.assert_lint('while (foo) {', '')
       
  1197         self.assert_lint('switch (foo) {', '')
       
  1198         self.assert_lint('new (RenderArena()) RenderInline(document())', '')
       
  1199         self.assert_lint('foo( bar)', 'Extra space after ( in function call'
       
  1200                          '  [whitespace/parens] [4]')
       
  1201         self.assert_lint('foobar( \\', '')
       
  1202         self.assert_lint('foobar(     \\', '')
       
  1203         self.assert_lint('( a + b)', 'Extra space after ('
       
  1204                          '  [whitespace/parens] [2]')
       
  1205         self.assert_lint('((a+b))', '')
       
  1206         self.assert_lint('foo (foo)', 'Extra space before ( in function call'
       
  1207                          '  [whitespace/parens] [4]')
       
  1208         self.assert_lint('typedef foo (*foo)(foo)', '')
       
  1209         self.assert_lint('typedef foo (*foo12bar_)(foo)', '')
       
  1210         self.assert_lint('typedef foo (Foo::*bar)(foo)', '')
       
  1211         self.assert_lint('foo (Foo::*bar)(',
       
  1212                          'Extra space before ( in function call'
       
  1213                          '  [whitespace/parens] [4]')
       
  1214         self.assert_lint('typedef foo (Foo::*bar)(', '')
       
  1215         self.assert_lint('(foo)(bar)', '')
       
  1216         self.assert_lint('Foo (*foo)(bar)', '')
       
  1217         self.assert_lint('Foo (*foo)(Bar bar,', '')
       
  1218         self.assert_lint('char (*p)[sizeof(foo)] = &foo', '')
       
  1219         self.assert_lint('char (&ref)[sizeof(foo)] = &foo', '')
       
  1220         self.assert_lint('const char32 (*table[])[6];', '')
       
  1221 
       
  1222     def test_spacing_before_braces(self):
       
  1223         self.assert_lint('if (foo){', 'Missing space before {'
       
  1224                          '  [whitespace/braces] [5]')
       
  1225         self.assert_lint('for{', 'Missing space before {'
       
  1226                          '  [whitespace/braces] [5]')
       
  1227         self.assert_lint('for {', '')
       
  1228         self.assert_lint('EXPECT_DEBUG_DEATH({', '')
       
  1229 
       
  1230     def test_spacing_around_else(self):
       
  1231         self.assert_lint('}else {', 'Missing space before else'
       
  1232                          '  [whitespace/braces] [5]')
       
  1233         self.assert_lint('} else{', 'Missing space before {'
       
  1234                          '  [whitespace/braces] [5]')
       
  1235         self.assert_lint('} else {', '')
       
  1236         self.assert_lint('} else if', '')
       
  1237 
       
  1238     def test_spacing_for_binary_ops(self):
       
  1239         self.assert_lint('if (foo<=bar) {', 'Missing spaces around <='
       
  1240                          '  [whitespace/operators] [3]')
       
  1241         self.assert_lint('if (foo<bar) {', 'Missing spaces around <'
       
  1242                          '  [whitespace/operators] [3]')
       
  1243         self.assert_lint('if (foo<bar->baz) {', 'Missing spaces around <'
       
  1244                          '  [whitespace/operators] [3]')
       
  1245         self.assert_lint('if (foo<bar->bar) {', 'Missing spaces around <'
       
  1246                          '  [whitespace/operators] [3]')
       
  1247         self.assert_lint('typedef hash_map<Foo, Bar', 'Missing spaces around <'
       
  1248                          '  [whitespace/operators] [3]')
       
  1249         self.assert_lint('typedef hash_map<FoooooType, BaaaaarType,', '')
       
  1250         self.assert_lint('a<Foo> t+=b;', 'Missing spaces around +='
       
  1251                          '  [whitespace/operators] [3]')
       
  1252         self.assert_lint('a<Foo> t-=b;', 'Missing spaces around -='
       
  1253                          '  [whitespace/operators] [3]')
       
  1254         self.assert_lint('a<Foo*> t*=b;', 'Missing spaces around *='
       
  1255                          '  [whitespace/operators] [3]')
       
  1256         self.assert_lint('a<Foo*> t/=b;', 'Missing spaces around /='
       
  1257                          '  [whitespace/operators] [3]')
       
  1258         self.assert_lint('a<Foo*> t|=b;', 'Missing spaces around |='
       
  1259                          '  [whitespace/operators] [3]')
       
  1260         self.assert_lint('a<Foo*> t&=b;', 'Missing spaces around &='
       
  1261                          '  [whitespace/operators] [3]')
       
  1262         self.assert_lint('a<Foo*> t<<=b;', 'Missing spaces around <<='
       
  1263                          '  [whitespace/operators] [3]')
       
  1264         self.assert_lint('a<Foo*> t>>=b;', 'Missing spaces around >>='
       
  1265                          '  [whitespace/operators] [3]')
       
  1266         self.assert_lint('a<Foo*> t>>=&b|c;', 'Missing spaces around >>='
       
  1267                          '  [whitespace/operators] [3]')
       
  1268         self.assert_lint('a<Foo*> t<<=*b/c;', 'Missing spaces around <<='
       
  1269                          '  [whitespace/operators] [3]')
       
  1270         self.assert_lint('a<Foo> t -= b;', '')
       
  1271         self.assert_lint('a<Foo> t += b;', '')
       
  1272         self.assert_lint('a<Foo*> t *= b;', '')
       
  1273         self.assert_lint('a<Foo*> t /= b;', '')
       
  1274         self.assert_lint('a<Foo*> t |= b;', '')
       
  1275         self.assert_lint('a<Foo*> t &= b;', '')
       
  1276         self.assert_lint('a<Foo*> t <<= b;', '')
       
  1277         self.assert_lint('a<Foo*> t >>= b;', '')
       
  1278         self.assert_lint('a<Foo*> t >>= &b|c;', 'Missing spaces around |'
       
  1279                          '  [whitespace/operators] [3]')
       
  1280         self.assert_lint('a<Foo*> t <<= *b/c;', 'Missing spaces around /'
       
  1281                          '  [whitespace/operators] [3]')
       
  1282         self.assert_lint('a<Foo*> t <<= b/c; //Test', [
       
  1283                          'Should have a space between // and comment  '
       
  1284                          '[whitespace/comments] [4]', 'Missing'
       
  1285                          ' spaces around /  [whitespace/operators] [3]'])
       
  1286         self.assert_lint('a<Foo*> t <<= b||c;  //Test', ['One space before end'
       
  1287                          ' of line comments  [whitespace/comments] [5]',
       
  1288                          'Should have a space between // and comment  '
       
  1289                          '[whitespace/comments] [4]',
       
  1290                          'Missing spaces around ||  [whitespace/operators] [3]'])
       
  1291         self.assert_lint('a<Foo*> t <<= b&&c; // Test', 'Missing spaces around'
       
  1292                          ' &&  [whitespace/operators] [3]')
       
  1293         self.assert_lint('a<Foo*> t <<= b&&&c; // Test', 'Missing spaces around'
       
  1294                          ' &&  [whitespace/operators] [3]')
       
  1295         self.assert_lint('a<Foo*> t <<= b&&*c; // Test', 'Missing spaces around'
       
  1296                          ' &&  [whitespace/operators] [3]')
       
  1297         self.assert_lint('a<Foo*> t <<= b && *c; // Test', '')
       
  1298         self.assert_lint('a<Foo*> t <<= b && &c; // Test', '')
       
  1299         self.assert_lint('a<Foo*> t <<= b || &c;  /*Test', 'Complex multi-line '
       
  1300                          '/*...*/-style comment found. Lint may give bogus '
       
  1301                          'warnings.  Consider replacing these with //-style'
       
  1302                          ' comments, with #if 0...#endif, or with more clearly'
       
  1303                          ' structured multi-line comments.  [readability/multiline_comment] [5]')
       
  1304         self.assert_lint('a<Foo&> t <<= &b | &c;', '')
       
  1305         self.assert_lint('a<Foo*> t <<= &b & &c; // Test', '')
       
  1306         self.assert_lint('a<Foo*> t <<= *b / &c; // Test', '')
       
  1307         self.assert_lint('if (a=b == 1)', 'Missing spaces around =  [whitespace/operators] [4]')
       
  1308         self.assert_lint('a = 1<<20', 'Missing spaces around <<  [whitespace/operators] [3]')
       
  1309         self.assert_lint('if (a = b == 1)', '')
       
  1310         self.assert_lint('a = 1 << 20', '')
       
  1311         self.assert_multi_line_lint('#include "config.h"\n#include <sys/io.h>\n',
       
  1312                                     '')
       
  1313         self.assert_multi_line_lint('#include "config.h"\n#import <foo/bar.h>\n',
       
  1314                                     '')
       
  1315 
       
  1316     def test_spacing_before_last_semicolon(self):
       
  1317         self.assert_lint('call_function() ;',
       
  1318                          'Extra space before last semicolon. If this should be an '
       
  1319                          'empty statement, use { } instead.'
       
  1320                          '  [whitespace/semicolon] [5]')
       
  1321         self.assert_lint('while (true) ;',
       
  1322                          'Extra space before last semicolon. If this should be an '
       
  1323                          'empty statement, use { } instead.'
       
  1324                          '  [whitespace/semicolon] [5]')
       
  1325         self.assert_lint('default:;',
       
  1326                          'Semicolon defining empty statement. Use { } instead.'
       
  1327                          '  [whitespace/semicolon] [5]')
       
  1328         self.assert_lint('      ;',
       
  1329                          'Line contains only semicolon. If this should be an empty '
       
  1330                          'statement, use { } instead.'
       
  1331                          '  [whitespace/semicolon] [5]')
       
  1332         self.assert_lint('for (int i = 0; ;', '')
       
  1333 
       
  1334     # Static or global STL strings.
       
  1335     def test_static_or_global_stlstrings(self):
       
  1336         self.assert_lint('string foo;',
       
  1337                          'For a static/global string constant, use a C style '
       
  1338                          'string instead: "char foo[]".'
       
  1339                          '  [runtime/string] [4]')
       
  1340         self.assert_lint('string kFoo = "hello"; // English',
       
  1341                          'For a static/global string constant, use a C style '
       
  1342                          'string instead: "char kFoo[]".'
       
  1343                          '  [runtime/string] [4]')
       
  1344         self.assert_lint('static string foo;',
       
  1345                          'For a static/global string constant, use a C style '
       
  1346                          'string instead: "static char foo[]".'
       
  1347                          '  [runtime/string] [4]')
       
  1348         self.assert_lint('static const string foo;',
       
  1349                          'For a static/global string constant, use a C style '
       
  1350                          'string instead: "static const char foo[]".'
       
  1351                          '  [runtime/string] [4]')
       
  1352         self.assert_lint('string Foo::bar;',
       
  1353                          'For a static/global string constant, use a C style '
       
  1354                          'string instead: "char Foo::bar[]".'
       
  1355                          '  [runtime/string] [4]')
       
  1356         # Rare case.
       
  1357         self.assert_lint('string foo("foobar");',
       
  1358                          'For a static/global string constant, use a C style '
       
  1359                          'string instead: "char foo[]".'
       
  1360                          '  [runtime/string] [4]')
       
  1361         # Should not catch local or member variables.
       
  1362         self.assert_lint('    string foo', '')
       
  1363         # Should not catch functions.
       
  1364         self.assert_lint('string EmptyString() { return ""; }', '')
       
  1365         self.assert_lint('string EmptyString () { return ""; }', '')
       
  1366         self.assert_lint('string VeryLongNameFunctionSometimesEndsWith(\n'
       
  1367                          '    VeryLongNameType very_long_name_variable) {}', '')
       
  1368         self.assert_lint('template<>\n'
       
  1369                          'string FunctionTemplateSpecialization<SomeType>(\n'
       
  1370                          '      int x) { return ""; }', '')
       
  1371         self.assert_lint('template<>\n'
       
  1372                          'string FunctionTemplateSpecialization<vector<A::B>* >(\n'
       
  1373                          '      int x) { return ""; }', '')
       
  1374 
       
  1375         # should not catch methods of template classes.
       
  1376         self.assert_lint('string Class<Type>::Method() const\n'
       
  1377                          '{\n'
       
  1378                          '  return "";\n'
       
  1379                          '}\n', '')
       
  1380         self.assert_lint('string Class<Type>::Method(\n'
       
  1381                          '   int arg) const\n'
       
  1382                          '{\n'
       
  1383                          '  return "";\n'
       
  1384                          '}\n', '')
       
  1385 
       
  1386     def test_no_spaces_in_function_calls(self):
       
  1387         self.assert_lint('TellStory(1, 3);',
       
  1388                          '')
       
  1389         self.assert_lint('TellStory(1, 3 );',
       
  1390                          'Extra space before )'
       
  1391                          '  [whitespace/parens] [2]')
       
  1392         self.assert_lint('TellStory(1 /* wolf */, 3 /* pigs */);',
       
  1393                          '')
       
  1394         self.assert_multi_line_lint('#endif\n    );',
       
  1395                                     '')
       
  1396 
       
  1397     def test_two_spaces_between_code_and_comments(self):
       
  1398         self.assert_lint('} // namespace foo',
       
  1399                          '')
       
  1400         self.assert_lint('}// namespace foo',
       
  1401                          'One space before end of line comments'
       
  1402                          '  [whitespace/comments] [5]')
       
  1403         self.assert_lint('printf("foo"); // Outside quotes.',
       
  1404                          '')
       
  1405         self.assert_lint('int i = 0; // Having one space is fine.','')
       
  1406         self.assert_lint('int i = 0;  // Having two spaces is bad.',
       
  1407                          'One space before end of line comments'
       
  1408                          '  [whitespace/comments] [5]')
       
  1409         self.assert_lint('int i = 0;   // Having three spaces is bad.',
       
  1410                          'One space before end of line comments'
       
  1411                          '  [whitespace/comments] [5]')
       
  1412         self.assert_lint('// Top level comment', '')
       
  1413         self.assert_lint('    // Line starts with four spaces.', '')
       
  1414         self.assert_lint('foo();\n'
       
  1415                          '{ // A scope is opening.', '')
       
  1416         self.assert_lint('    foo();\n'
       
  1417                          '    { // An indented scope is opening.', '')
       
  1418         self.assert_lint('if (foo) { // not a pure scope',
       
  1419                          '')
       
  1420         self.assert_lint('printf("// In quotes.")', '')
       
  1421         self.assert_lint('printf("\\"%s // In quotes.")', '')
       
  1422         self.assert_lint('printf("%s", "// In quotes.")', '')
       
  1423 
       
  1424     def test_space_after_comment_marker(self):
       
  1425         self.assert_lint('//', '')
       
  1426         self.assert_lint('//x', 'Should have a space between // and comment'
       
  1427                          '  [whitespace/comments] [4]')
       
  1428         self.assert_lint('// x', '')
       
  1429         self.assert_lint('//----', '')
       
  1430         self.assert_lint('//====', '')
       
  1431         self.assert_lint('//////', '')
       
  1432         self.assert_lint('////// x', '')
       
  1433         self.assert_lint('/// x', '')
       
  1434         self.assert_lint('////x', 'Should have a space between // and comment'
       
  1435                          '  [whitespace/comments] [4]')
       
  1436 
       
  1437     def test_newline_at_eof(self):
       
  1438         def do_test(self, data, is_missing_eof):
       
  1439             error_collector = ErrorCollector(self.assert_)
       
  1440             self.process_file_data('foo.cpp', 'cpp', data.split('\n'),
       
  1441                                    error_collector)
       
  1442             # The warning appears only once.
       
  1443             self.assertEquals(
       
  1444                 int(is_missing_eof),
       
  1445                 error_collector.results().count(
       
  1446                     'Could not find a newline character at the end of the file.'
       
  1447                     '  [whitespace/ending_newline] [5]'))
       
  1448 
       
  1449         do_test(self, '// Newline\n// at EOF\n', False)
       
  1450         do_test(self, '// No newline\n// at EOF', True)
       
  1451 
       
  1452     def test_invalid_utf8(self):
       
  1453         def do_test(self, raw_bytes, has_invalid_utf8):
       
  1454             error_collector = ErrorCollector(self.assert_)
       
  1455             self.process_file_data('foo.cpp', 'cpp',
       
  1456                                    unicode(raw_bytes, 'utf8', 'replace').split('\n'),
       
  1457                                    error_collector)
       
  1458             # The warning appears only once.
       
  1459             self.assertEquals(
       
  1460                 int(has_invalid_utf8),
       
  1461                 error_collector.results().count(
       
  1462                     'Line contains invalid UTF-8'
       
  1463                     ' (or Unicode replacement character).'
       
  1464                     '  [readability/utf8] [5]'))
       
  1465 
       
  1466         do_test(self, 'Hello world\n', False)
       
  1467         do_test(self, '\xe9\x8e\xbd\n', False)
       
  1468         do_test(self, '\xe9x\x8e\xbd\n', True)
       
  1469         # This is the encoding of the replacement character itself (which
       
  1470         # you can see by evaluating codecs.getencoder('utf8')(u'\ufffd')).
       
  1471         do_test(self, '\xef\xbf\xbd\n', True)
       
  1472 
       
  1473     def test_is_blank_line(self):
       
  1474         self.assert_(cpp_style.is_blank_line(''))
       
  1475         self.assert_(cpp_style.is_blank_line(' '))
       
  1476         self.assert_(cpp_style.is_blank_line(' \t\r\n'))
       
  1477         self.assert_(not cpp_style.is_blank_line('int a;'))
       
  1478         self.assert_(not cpp_style.is_blank_line('{'))
       
  1479 
       
  1480     def test_blank_lines_check(self):
       
  1481         self.assert_blank_lines_check(['{\n', '\n', '\n', '}\n'], 1, 1)
       
  1482         self.assert_blank_lines_check(['  if (foo) {\n', '\n', '  }\n'], 1, 1)
       
  1483         self.assert_blank_lines_check(
       
  1484             ['\n', '// {\n', '\n', '\n', '// Comment\n', '{\n', '}\n'], 0, 0)
       
  1485         self.assert_blank_lines_check(['\n', 'run("{");\n', '\n'], 0, 0)
       
  1486         self.assert_blank_lines_check(['\n', '  if (foo) { return 0; }\n', '\n'], 0, 0)
       
  1487 
       
  1488     def test_allow_blank_line_before_closing_namespace(self):
       
  1489         error_collector = ErrorCollector(self.assert_)
       
  1490         self.process_file_data('foo.cpp', 'cpp',
       
  1491                                ['namespace {', '', '}  // namespace'],
       
  1492                                error_collector)
       
  1493         self.assertEquals(0, error_collector.results().count(
       
  1494             'Blank line at the end of a code block.  Is this needed?'
       
  1495             '  [whitespace/blank_line] [3]'))
       
  1496 
       
  1497     def test_allow_blank_line_before_if_else_chain(self):
       
  1498         error_collector = ErrorCollector(self.assert_)
       
  1499         self.process_file_data('foo.cpp', 'cpp',
       
  1500                                ['if (hoge) {',
       
  1501                                 '',  # No warning
       
  1502                                 '} else if (piyo) {',
       
  1503                                 '',  # No warning
       
  1504                                 '} else if (piyopiyo) {',
       
  1505                                 '  hoge = true;',  # No warning
       
  1506                                 '} else {',
       
  1507                                 '',  # Warning on this line
       
  1508                                 '}'],
       
  1509                                error_collector)
       
  1510         self.assertEquals(1, error_collector.results().count(
       
  1511             'Blank line at the end of a code block.  Is this needed?'
       
  1512             '  [whitespace/blank_line] [3]'))
       
  1513 
       
  1514     def test_else_on_same_line_as_closing_braces(self):
       
  1515         error_collector = ErrorCollector(self.assert_)
       
  1516         self.process_file_data('foo.cpp', 'cpp',
       
  1517                                ['if (hoge) {',
       
  1518                                 '',
       
  1519                                 '}',
       
  1520                                 ' else {'  # Warning on this line
       
  1521                                 '',
       
  1522                                 '}'],
       
  1523                                error_collector)
       
  1524         self.assertEquals(1, error_collector.results().count(
       
  1525             'An else should appear on the same line as the preceding }'
       
  1526             '  [whitespace/newline] [4]'))
       
  1527 
       
  1528     def test_else_clause_not_on_same_line_as_else(self):
       
  1529         self.assert_lint('    else DoSomethingElse();',
       
  1530                          'Else clause should never be on same line as else '
       
  1531                          '(use 2 lines)  [whitespace/newline] [4]')
       
  1532         self.assert_lint('    else ifDoSomethingElse();',
       
  1533                          'Else clause should never be on same line as else '
       
  1534                          '(use 2 lines)  [whitespace/newline] [4]')
       
  1535         self.assert_lint('    else if (blah) {', '')
       
  1536         self.assert_lint('    variable_ends_in_else = true;', '')
       
  1537 
       
  1538     def test_comma(self):
       
  1539         self.assert_lint('a = f(1,2);',
       
  1540                          'Missing space after ,  [whitespace/comma] [3]')
       
  1541         self.assert_lint('int tmp=a,a=b,b=tmp;',
       
  1542                          ['Missing spaces around =  [whitespace/operators] [4]',
       
  1543                           'Missing space after ,  [whitespace/comma] [3]'])
       
  1544         self.assert_lint('f(a, /* name */ b);', '')
       
  1545         self.assert_lint('f(a, /* name */b);', '')
       
  1546 
       
  1547     def test_declaration(self):
       
  1548         self.assert_lint('int a;', '')
       
  1549         self.assert_lint('int   a;', 'Extra space between int and a  [whitespace/declaration] [3]')
       
  1550         self.assert_lint('int*  a;', 'Extra space between int* and a  [whitespace/declaration] [3]')
       
  1551         self.assert_lint('else if { }', '')
       
  1552         self.assert_lint('else   if { }', 'Extra space between else and if  [whitespace/declaration] [3]')
       
  1553 
       
  1554     def test_pointer_reference_marker_location(self):
       
  1555         self.assert_lint('int* b;', '', 'foo.cpp')
       
  1556         self.assert_lint('int *b;',
       
  1557                          'Declaration has space between type name and * in int *b  [whitespace/declaration] [3]',
       
  1558                          'foo.cpp')
       
  1559         self.assert_lint('return *b;', '', 'foo.cpp')
       
  1560         self.assert_lint('delete *b;', '', 'foo.cpp')
       
  1561         self.assert_lint('int *b;', '', 'foo.c')
       
  1562         self.assert_lint('int* b;',
       
  1563                          'Declaration has space between * and variable name in int* b  [whitespace/declaration] [3]',
       
  1564                          'foo.c')
       
  1565         self.assert_lint('int& b;', '', 'foo.cpp')
       
  1566         self.assert_lint('int &b;',
       
  1567                          'Declaration has space between type name and & in int &b  [whitespace/declaration] [3]',
       
  1568                          'foo.cpp')
       
  1569         self.assert_lint('return &b;', '', 'foo.cpp')
       
  1570 
       
  1571     def test_indent(self):
       
  1572         self.assert_lint('static int noindent;', '')
       
  1573         self.assert_lint('    int fourSpaceIndent;', '')
       
  1574         self.assert_lint(' int oneSpaceIndent;',
       
  1575                          'Weird number of spaces at line-start.  '
       
  1576                          'Are you using a 4-space indent?  [whitespace/indent] [3]')
       
  1577         self.assert_lint('   int threeSpaceIndent;',
       
  1578                          'Weird number of spaces at line-start.  '
       
  1579                          'Are you using a 4-space indent?  [whitespace/indent] [3]')
       
  1580         self.assert_lint(' char* oneSpaceIndent = "public:";',
       
  1581                          'Weird number of spaces at line-start.  '
       
  1582                          'Are you using a 4-space indent?  [whitespace/indent] [3]')
       
  1583         self.assert_lint(' public:', '')
       
  1584         self.assert_lint('  public:', '')
       
  1585         self.assert_lint('   public:', '')
       
  1586 
       
  1587     def test_label(self):
       
  1588         self.assert_lint('public:',
       
  1589                          'Labels should always be indented at least one space.  '
       
  1590                          'If this is a member-initializer list in a constructor, '
       
  1591                          'the colon should be on the line after the definition '
       
  1592                          'header.  [whitespace/labels] [4]')
       
  1593         self.assert_lint('  public:', '')
       
  1594         self.assert_lint('   public:', '')
       
  1595         self.assert_lint(' public:', '')
       
  1596         self.assert_lint('  public:', '')
       
  1597         self.assert_lint('   public:', '')
       
  1598 
       
  1599     def test_not_alabel(self):
       
  1600         self.assert_lint('MyVeryLongNamespace::MyVeryLongClassName::', '')
       
  1601 
       
  1602     def test_tab(self):
       
  1603         self.assert_lint('\tint a;',
       
  1604                          'Tab found; better to use spaces  [whitespace/tab] [1]')
       
  1605         self.assert_lint('int a = 5;\t// set a to 5',
       
  1606                          'Tab found; better to use spaces  [whitespace/tab] [1]')
       
  1607 
       
  1608     def test_unnamed_namespaces_in_headers(self):
       
  1609         self.assert_language_rules_check(
       
  1610             'foo.h', 'namespace {',
       
  1611             'Do not use unnamed namespaces in header files.  See'
       
  1612             ' http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Namespaces'
       
  1613             ' for more information.  [build/namespaces] [4]')
       
  1614         # namespace registration macros are OK.
       
  1615         self.assert_language_rules_check('foo.h', 'namespace {  \\', '')
       
  1616         # named namespaces are OK.
       
  1617         self.assert_language_rules_check('foo.h', 'namespace foo {', '')
       
  1618         self.assert_language_rules_check('foo.h', 'namespace foonamespace {', '')
       
  1619         self.assert_language_rules_check('foo.cpp', 'namespace {', '')
       
  1620         self.assert_language_rules_check('foo.cpp', 'namespace foo {', '')
       
  1621 
       
  1622     def test_build_class(self):
       
  1623         # Test that the linter can parse to the end of class definitions,
       
  1624         # and that it will report when it can't.
       
  1625         # Use multi-line linter because it performs the ClassState check.
       
  1626         self.assert_multi_line_lint(
       
  1627             'class Foo {',
       
  1628             'Failed to find complete declaration of class Foo'
       
  1629             '  [build/class] [5]')
       
  1630         # Don't warn on forward declarations of various types.
       
  1631         self.assert_multi_line_lint(
       
  1632             'class Foo;',
       
  1633             '')
       
  1634         self.assert_multi_line_lint(
       
  1635             '''struct Foo*
       
  1636                  foo = NewFoo();''',
       
  1637             '')
       
  1638         # Here is an example where the linter gets confused, even though
       
  1639         # the code doesn't violate the style guide.
       
  1640         self.assert_multi_line_lint(
       
  1641             '''class Foo
       
  1642             #ifdef DERIVE_FROM_GOO
       
  1643               : public Goo {
       
  1644             #else
       
  1645               : public Hoo {
       
  1646             #endif
       
  1647               };''',
       
  1648             'Failed to find complete declaration of class Foo'
       
  1649             '  [build/class] [5]')
       
  1650 
       
  1651     def test_build_end_comment(self):
       
  1652         # The crosstool compiler we currently use will fail to compile the
       
  1653         # code in this test, so we might consider removing the lint check.
       
  1654         self.assert_lint('#endif Not a comment',
       
  1655                          'Uncommented text after #endif is non-standard.'
       
  1656                          '  Use a comment.'
       
  1657                          '  [build/endif_comment] [5]')
       
  1658 
       
  1659     def test_build_forward_decl(self):
       
  1660         # The crosstool compiler we currently use will fail to compile the
       
  1661         # code in this test, so we might consider removing the lint check.
       
  1662         self.assert_lint('class Foo::Goo;',
       
  1663                          'Inner-style forward declarations are invalid.'
       
  1664                          '  Remove this line.'
       
  1665                          '  [build/forward_decl] [5]')
       
  1666 
       
  1667     def test_build_header_guard(self):
       
  1668         file_path = 'mydir/Foo.h'
       
  1669 
       
  1670         # We can't rely on our internal stuff to get a sane path on the open source
       
  1671         # side of things, so just parse out the suggested header guard. This
       
  1672         # doesn't allow us to test the suggested header guard, but it does let us
       
  1673         # test all the other header tests.
       
  1674         error_collector = ErrorCollector(self.assert_)
       
  1675         self.process_file_data(file_path, 'h', [], error_collector)
       
  1676         expected_guard = ''
       
  1677         matcher = re.compile(
       
  1678             'No \#ifndef header guard found\, suggested CPP variable is\: ([A-Za-z_0-9]+) ')
       
  1679         for error in error_collector.result_list():
       
  1680             matches = matcher.match(error)
       
  1681             if matches:
       
  1682                 expected_guard = matches.group(1)
       
  1683                 break
       
  1684 
       
  1685         # Make sure we extracted something for our header guard.
       
  1686         self.assertNotEqual(expected_guard, '')
       
  1687 
       
  1688         # Wrong guard
       
  1689         error_collector = ErrorCollector(self.assert_)
       
  1690         self.process_file_data(file_path, 'h',
       
  1691                                ['#ifndef FOO_H', '#define FOO_H'], error_collector)
       
  1692         self.assertEquals(
       
  1693             1,
       
  1694             error_collector.result_list().count(
       
  1695                 '#ifndef header guard has wrong style, please use: %s'
       
  1696                 '  [build/header_guard] [5]' % expected_guard),
       
  1697             error_collector.result_list())
       
  1698 
       
  1699         # No define
       
  1700         error_collector = ErrorCollector(self.assert_)
       
  1701         self.process_file_data(file_path, 'h',
       
  1702                                ['#ifndef %s' % expected_guard], error_collector)
       
  1703         self.assertEquals(
       
  1704             1,
       
  1705             error_collector.result_list().count(
       
  1706                 'No #ifndef header guard found, suggested CPP variable is: %s'
       
  1707                 '  [build/header_guard] [5]' % expected_guard),
       
  1708             error_collector.result_list())
       
  1709 
       
  1710         # Mismatched define
       
  1711         error_collector = ErrorCollector(self.assert_)
       
  1712         self.process_file_data(file_path, 'h',
       
  1713                                ['#ifndef %s' % expected_guard,
       
  1714                                 '#define FOO_H'],
       
  1715                                error_collector)
       
  1716         self.assertEquals(
       
  1717             1,
       
  1718             error_collector.result_list().count(
       
  1719                 'No #ifndef header guard found, suggested CPP variable is: %s'
       
  1720                 '  [build/header_guard] [5]' % expected_guard),
       
  1721             error_collector.result_list())
       
  1722 
       
  1723         # No header guard errors
       
  1724         error_collector = ErrorCollector(self.assert_)
       
  1725         self.process_file_data(file_path, 'h',
       
  1726                                ['#ifndef %s' % expected_guard,
       
  1727                                 '#define %s' % expected_guard,
       
  1728                                 '#endif // %s' % expected_guard],
       
  1729                                error_collector)
       
  1730         for line in error_collector.result_list():
       
  1731             if line.find('build/header_guard') != -1:
       
  1732                 self.fail('Unexpected error: %s' % line)
       
  1733 
       
  1734         # Completely incorrect header guard
       
  1735         error_collector = ErrorCollector(self.assert_)
       
  1736         self.process_file_data(file_path, 'h',
       
  1737                                ['#ifndef FOO',
       
  1738                                 '#define FOO',
       
  1739                                 '#endif  // FOO'],
       
  1740                                error_collector)
       
  1741         self.assertEquals(
       
  1742             1,
       
  1743             error_collector.result_list().count(
       
  1744                 '#ifndef header guard has wrong style, please use: %s'
       
  1745                 '  [build/header_guard] [5]' % expected_guard),
       
  1746             error_collector.result_list())
       
  1747 
       
  1748         # Special case for flymake
       
  1749         error_collector = ErrorCollector(self.assert_)
       
  1750         self.process_file_data('mydir/Foo_flymake.h', 'h',
       
  1751                                ['#ifndef %s' % expected_guard,
       
  1752                                 '#define %s' % expected_guard,
       
  1753                                 '#endif // %s' % expected_guard],
       
  1754                                error_collector)
       
  1755         for line in error_collector.result_list():
       
  1756             if line.find('build/header_guard') != -1:
       
  1757                 self.fail('Unexpected error: %s' % line)
       
  1758 
       
  1759         error_collector = ErrorCollector(self.assert_)
       
  1760         self.process_file_data('mydir/Foo_flymake.h', 'h', [], error_collector)
       
  1761         self.assertEquals(
       
  1762             1,
       
  1763             error_collector.result_list().count(
       
  1764                 'No #ifndef header guard found, suggested CPP variable is: %s'
       
  1765                 '  [build/header_guard] [5]' % expected_guard),
       
  1766             error_collector.result_list())
       
  1767 
       
  1768     def test_build_printf_format(self):
       
  1769         self.assert_lint(
       
  1770             r'printf("\%%d", value);',
       
  1771             '%, [, (, and { are undefined character escapes.  Unescape them.'
       
  1772             '  [build/printf_format] [3]')
       
  1773 
       
  1774         self.assert_lint(
       
  1775             r'snprintf(buffer, sizeof(buffer), "\[%d", value);',
       
  1776             '%, [, (, and { are undefined character escapes.  Unescape them.'
       
  1777             '  [build/printf_format] [3]')
       
  1778 
       
  1779         self.assert_lint(
       
  1780             r'fprintf(file, "\(%d", value);',
       
  1781             '%, [, (, and { are undefined character escapes.  Unescape them.'
       
  1782             '  [build/printf_format] [3]')
       
  1783 
       
  1784         self.assert_lint(
       
  1785             r'vsnprintf(buffer, sizeof(buffer), "\\\{%d", ap);',
       
  1786             '%, [, (, and { are undefined character escapes.  Unescape them.'
       
  1787             '  [build/printf_format] [3]')
       
  1788 
       
  1789         # Don't warn if double-slash precedes the symbol
       
  1790         self.assert_lint(r'printf("\\%%%d", value);',
       
  1791                          '')
       
  1792 
       
  1793     def test_runtime_printf_format(self):
       
  1794         self.assert_lint(
       
  1795             r'fprintf(file, "%q", value);',
       
  1796             '%q in format strings is deprecated.  Use %ll instead.'
       
  1797             '  [runtime/printf_format] [3]')
       
  1798 
       
  1799         self.assert_lint(
       
  1800             r'aprintf(file, "The number is %12q", value);',
       
  1801             '%q in format strings is deprecated.  Use %ll instead.'
       
  1802             '  [runtime/printf_format] [3]')
       
  1803 
       
  1804         self.assert_lint(
       
  1805             r'printf(file, "The number is" "%-12q", value);',
       
  1806             '%q in format strings is deprecated.  Use %ll instead.'
       
  1807             '  [runtime/printf_format] [3]')
       
  1808 
       
  1809         self.assert_lint(
       
  1810             r'printf(file, "The number is" "%+12q", value);',
       
  1811             '%q in format strings is deprecated.  Use %ll instead.'
       
  1812             '  [runtime/printf_format] [3]')
       
  1813 
       
  1814         self.assert_lint(
       
  1815             r'printf(file, "The number is" "% 12q", value);',
       
  1816             '%q in format strings is deprecated.  Use %ll instead.'
       
  1817             '  [runtime/printf_format] [3]')
       
  1818 
       
  1819         self.assert_lint(
       
  1820             r'snprintf(file, "Never mix %d and %1$d parmaeters!", value);',
       
  1821             '%N$ formats are unconventional.  Try rewriting to avoid them.'
       
  1822             '  [runtime/printf_format] [2]')
       
  1823 
       
  1824     def assert_lintLogCodeOnError(self, code, expected_message):
       
  1825         # Special assert_lint which logs the input code on error.
       
  1826         result = self.perform_single_line_lint(code, 'foo.cpp')
       
  1827         if result != expected_message:
       
  1828             self.fail('For code: "%s"\nGot: "%s"\nExpected: "%s"'
       
  1829                       % (code, result, expected_message))
       
  1830 
       
  1831     def test_build_storage_class(self):
       
  1832         qualifiers = [None, 'const', 'volatile']
       
  1833         signs = [None, 'signed', 'unsigned']
       
  1834         types = ['void', 'char', 'int', 'float', 'double',
       
  1835                  'schar', 'int8', 'uint8', 'int16', 'uint16',
       
  1836                  'int32', 'uint32', 'int64', 'uint64']
       
  1837         storage_classes = ['auto', 'extern', 'register', 'static', 'typedef']
       
  1838 
       
  1839         build_storage_class_error_message = (
       
  1840             'Storage class (static, extern, typedef, etc) should be first.'
       
  1841             '  [build/storage_class] [5]')
       
  1842 
       
  1843         # Some explicit cases. Legal in C++, deprecated in C99.
       
  1844         self.assert_lint('const int static foo = 5;',
       
  1845                          build_storage_class_error_message)
       
  1846 
       
  1847         self.assert_lint('char static foo;',
       
  1848                          build_storage_class_error_message)
       
  1849 
       
  1850         self.assert_lint('double const static foo = 2.0;',
       
  1851                          build_storage_class_error_message)
       
  1852 
       
  1853         self.assert_lint('uint64 typedef unsignedLongLong;',
       
  1854                          build_storage_class_error_message)
       
  1855 
       
  1856         self.assert_lint('int register foo = 0;',
       
  1857                          build_storage_class_error_message)
       
  1858 
       
  1859         # Since there are a very large number of possibilities, randomly
       
  1860         # construct declarations.
       
  1861         # Make sure that the declaration is logged if there's an error.
       
  1862         # Seed generator with an integer for absolute reproducibility.
       
  1863         random.seed(25)
       
  1864         for unused_i in range(10):
       
  1865             # Build up random list of non-storage-class declaration specs.
       
  1866             other_decl_specs = [random.choice(qualifiers), random.choice(signs),
       
  1867                                 random.choice(types)]
       
  1868             # remove None
       
  1869             other_decl_specs = filter(lambda x: x is not None, other_decl_specs)
       
  1870 
       
  1871             # shuffle
       
  1872             random.shuffle(other_decl_specs)
       
  1873 
       
  1874             # insert storage class after the first
       
  1875             storage_class = random.choice(storage_classes)
       
  1876             insertion_point = random.randint(1, len(other_decl_specs))
       
  1877             decl_specs = (other_decl_specs[0:insertion_point]
       
  1878                           + [storage_class]
       
  1879                           + other_decl_specs[insertion_point:])
       
  1880 
       
  1881             self.assert_lintLogCodeOnError(
       
  1882                 ' '.join(decl_specs) + ';',
       
  1883                 build_storage_class_error_message)
       
  1884 
       
  1885             # but no error if storage class is first
       
  1886             self.assert_lintLogCodeOnError(
       
  1887                 storage_class + ' ' + ' '.join(other_decl_specs),
       
  1888                 '')
       
  1889 
       
  1890     def test_legal_copyright(self):
       
  1891         legal_copyright_message = (
       
  1892             'No copyright message found.  '
       
  1893             'You should have a line: "Copyright [year] <Copyright Owner>"'
       
  1894             '  [legal/copyright] [5]')
       
  1895 
       
  1896         copyright_line = '// Copyright 2008 Google Inc. All Rights Reserved.'
       
  1897 
       
  1898         file_path = 'mydir/googleclient/foo.cpp'
       
  1899 
       
  1900         # There should be a copyright message in the first 10 lines
       
  1901         error_collector = ErrorCollector(self.assert_)
       
  1902         self.process_file_data(file_path, 'cpp', [], error_collector)
       
  1903         self.assertEquals(
       
  1904             1,
       
  1905             error_collector.result_list().count(legal_copyright_message))
       
  1906 
       
  1907         error_collector = ErrorCollector(self.assert_)
       
  1908         self.process_file_data(
       
  1909             file_path, 'cpp',
       
  1910             ['' for unused_i in range(10)] + [copyright_line],
       
  1911             error_collector)
       
  1912         self.assertEquals(
       
  1913             1,
       
  1914             error_collector.result_list().count(legal_copyright_message))
       
  1915 
       
  1916         # Test that warning isn't issued if Copyright line appears early enough.
       
  1917         error_collector = ErrorCollector(self.assert_)
       
  1918         self.process_file_data(file_path, 'cpp', [copyright_line], error_collector)
       
  1919         for message in error_collector.result_list():
       
  1920             if message.find('legal/copyright') != -1:
       
  1921                 self.fail('Unexpected error: %s' % message)
       
  1922 
       
  1923         error_collector = ErrorCollector(self.assert_)
       
  1924         self.process_file_data(
       
  1925             file_path, 'cpp',
       
  1926             ['' for unused_i in range(9)] + [copyright_line],
       
  1927             error_collector)
       
  1928         for message in error_collector.result_list():
       
  1929             if message.find('legal/copyright') != -1:
       
  1930                 self.fail('Unexpected error: %s' % message)
       
  1931 
       
  1932     def test_invalid_increment(self):
       
  1933         self.assert_lint('*count++;',
       
  1934                          'Changing pointer instead of value (or unused value of '
       
  1935                          'operator*).  [runtime/invalid_increment] [5]')
       
  1936 
       
  1937 
       
  1938 class CleansedLinesTest(unittest.TestCase):
       
  1939     def test_init(self):
       
  1940         lines = ['Line 1',
       
  1941                  'Line 2',
       
  1942                  'Line 3 // Comment test',
       
  1943                  'Line 4 "foo"']
       
  1944 
       
  1945         clean_lines = cpp_style.CleansedLines(lines)
       
  1946         self.assertEquals(lines, clean_lines.raw_lines)
       
  1947         self.assertEquals(4, clean_lines.num_lines())
       
  1948 
       
  1949         self.assertEquals(['Line 1',
       
  1950                            'Line 2',
       
  1951                            'Line 3 ',
       
  1952                            'Line 4 "foo"'],
       
  1953                           clean_lines.lines)
       
  1954 
       
  1955         self.assertEquals(['Line 1',
       
  1956                            'Line 2',
       
  1957                            'Line 3 ',
       
  1958                            'Line 4 ""'],
       
  1959                           clean_lines.elided)
       
  1960 
       
  1961     def test_init_empty(self):
       
  1962         clean_lines = cpp_style.CleansedLines([])
       
  1963         self.assertEquals([], clean_lines.raw_lines)
       
  1964         self.assertEquals(0, clean_lines.num_lines())
       
  1965 
       
  1966     def test_collapse_strings(self):
       
  1967         collapse = cpp_style.CleansedLines.collapse_strings
       
  1968         self.assertEquals('""', collapse('""'))             # ""     (empty)
       
  1969         self.assertEquals('"""', collapse('"""'))           # """    (bad)
       
  1970         self.assertEquals('""', collapse('"xyz"'))          # "xyz"  (string)
       
  1971         self.assertEquals('""', collapse('"\\\""'))         # "\""   (string)
       
  1972         self.assertEquals('""', collapse('"\'"'))           # "'"    (string)
       
  1973         self.assertEquals('"\"', collapse('"\"'))           # "\"    (bad)
       
  1974         self.assertEquals('""', collapse('"\\\\"'))         # "\\"   (string)
       
  1975         self.assertEquals('"', collapse('"\\\\\\"'))        # "\\\"  (bad)
       
  1976         self.assertEquals('""', collapse('"\\\\\\\\"'))     # "\\\\" (string)
       
  1977 
       
  1978         self.assertEquals('\'\'', collapse('\'\''))         # ''     (empty)
       
  1979         self.assertEquals('\'\'', collapse('\'a\''))        # 'a'    (char)
       
  1980         self.assertEquals('\'\'', collapse('\'\\\'\''))     # '\''   (char)
       
  1981         self.assertEquals('\'', collapse('\'\\\''))         # '\'    (bad)
       
  1982         self.assertEquals('', collapse('\\012'))            # '\012' (char)
       
  1983         self.assertEquals('', collapse('\\xfF0'))           # '\xfF0' (char)
       
  1984         self.assertEquals('', collapse('\\n'))              # '\n' (char)
       
  1985         self.assertEquals('\#', collapse('\\#'))            # '\#' (bad)
       
  1986 
       
  1987         self.assertEquals('StringReplace(body, "", "");',
       
  1988                           collapse('StringReplace(body, "\\\\", "\\\\\\\\");'))
       
  1989         self.assertEquals('\'\' ""',
       
  1990                           collapse('\'"\' "foo"'))
       
  1991 
       
  1992 
       
  1993 class OrderOfIncludesTest(CppStyleTestBase):
       
  1994     def setUp(self):
       
  1995         self.include_state = cpp_style._IncludeState()
       
  1996 
       
  1997         # Cheat os.path.abspath called in FileInfo class.
       
  1998         self.os_path_abspath_orig = os.path.abspath
       
  1999         os.path.abspath = lambda value: value
       
  2000 
       
  2001     def tearDown(self):
       
  2002         os.path.abspath = self.os_path_abspath_orig
       
  2003 
       
  2004     def test_try_drop_common_suffixes(self):
       
  2005         self.assertEqual('foo/foo', cpp_style._drop_common_suffixes('foo/foo-inl.h'))
       
  2006         self.assertEqual('foo/bar/foo',
       
  2007                          cpp_style._drop_common_suffixes('foo/bar/foo_inl.h'))
       
  2008         self.assertEqual('foo/foo', cpp_style._drop_common_suffixes('foo/foo.cpp'))
       
  2009         self.assertEqual('foo/foo_unusualinternal',
       
  2010                          cpp_style._drop_common_suffixes('foo/foo_unusualinternal.h'))
       
  2011         self.assertEqual('',
       
  2012                          cpp_style._drop_common_suffixes('_test.cpp'))
       
  2013         self.assertEqual('test',
       
  2014                          cpp_style._drop_common_suffixes('test.cpp'))
       
  2015 
       
  2016 
       
  2017 class OrderOfIncludesTest(CppStyleTestBase):
       
  2018     def setUp(self):
       
  2019         self.include_state = cpp_style._IncludeState()
       
  2020 
       
  2021         # Cheat os.path.abspath called in FileInfo class.
       
  2022         self.os_path_abspath_orig = os.path.abspath
       
  2023         os.path.abspath = lambda value: value
       
  2024 
       
  2025     def tearDown(self):
       
  2026         os.path.abspath = self.os_path_abspath_orig
       
  2027 
       
  2028     def test_check_next_include_order__no_config(self):
       
  2029         self.assertEqual('Header file should not contain WebCore config.h.',
       
  2030                          self.include_state.check_next_include_order(cpp_style._CONFIG_HEADER, True))
       
  2031 
       
  2032     def test_check_next_include_order__no_self(self):
       
  2033         self.assertEqual('Header file should not contain itself.',
       
  2034                          self.include_state.check_next_include_order(cpp_style._PRIMARY_HEADER, True))
       
  2035         # Test actual code to make sure that header types are correctly assigned.
       
  2036         self.assert_language_rules_check('Foo.h',
       
  2037                                          '#include "Foo.h"\n',
       
  2038                                          'Header file should not contain itself. Should be: alphabetically sorted.'
       
  2039                                          '  [build/include_order] [4]')
       
  2040         self.assert_language_rules_check('FooBar.h',
       
  2041                                          '#include "Foo.h"\n',
       
  2042                                          '')
       
  2043 
       
  2044     def test_check_next_include_order__likely_then_config(self):
       
  2045         self.assertEqual('Found header this file implements before WebCore config.h.',
       
  2046                          self.include_state.check_next_include_order(cpp_style._PRIMARY_HEADER, False))
       
  2047         self.assertEqual('Found WebCore config.h after a header this file implements.',
       
  2048                          self.include_state.check_next_include_order(cpp_style._CONFIG_HEADER, False))
       
  2049 
       
  2050     def test_check_next_include_order__other_then_config(self):
       
  2051         self.assertEqual('Found other header before WebCore config.h.',
       
  2052                          self.include_state.check_next_include_order(cpp_style._OTHER_HEADER, False))
       
  2053         self.assertEqual('Found WebCore config.h after other header.',
       
  2054                          self.include_state.check_next_include_order(cpp_style._CONFIG_HEADER, False))
       
  2055 
       
  2056     def test_check_next_include_order__config_then_other_then_likely(self):
       
  2057         self.assertEqual('', self.include_state.check_next_include_order(cpp_style._CONFIG_HEADER, False))
       
  2058         self.assertEqual('Found other header before a header this file implements.',
       
  2059                          self.include_state.check_next_include_order(cpp_style._OTHER_HEADER, False))
       
  2060         self.assertEqual('Found header this file implements after other header.',
       
  2061                          self.include_state.check_next_include_order(cpp_style._PRIMARY_HEADER, False))
       
  2062 
       
  2063     def test_check_alphabetical_include_order(self):
       
  2064         self.assert_language_rules_check('foo.h',
       
  2065                                          '#include "a.h"\n'
       
  2066                                          '#include "c.h"\n'
       
  2067                                          '#include "b.h"\n',
       
  2068                                          'Alphabetical sorting problem.  [build/include_order] [4]')
       
  2069 
       
  2070         self.assert_language_rules_check('foo.h',
       
  2071                                          '#include "a.h"\n'
       
  2072                                          '#include "b.h"\n'
       
  2073                                          '#include "c.h"\n',
       
  2074                                          '')
       
  2075 
       
  2076         self.assert_language_rules_check('foo.h',
       
  2077                                          '#include <assert.h>\n'
       
  2078                                          '#include "bar.h"\n',
       
  2079                                          'Alphabetical sorting problem.  [build/include_order] [4]')
       
  2080 
       
  2081         self.assert_language_rules_check('foo.h',
       
  2082                                          '#include "bar.h"\n'
       
  2083                                          '#include <assert.h>\n',
       
  2084                                          '')
       
  2085 
       
  2086     def test_check_line_break_after_own_header(self):
       
  2087         self.assert_language_rules_check('foo.cpp',
       
  2088                                          '#include "config.h"\n'
       
  2089                                          '#include "foo.h"\n'
       
  2090                                          '#include "bar.h"\n',
       
  2091                                          'You should add a blank line after implementation file\'s own header.  [build/include_order] [4]')
       
  2092 
       
  2093         self.assert_language_rules_check('foo.cpp',
       
  2094                                          '#include "config.h"\n'
       
  2095                                          '#include "foo.h"\n'
       
  2096                                          '\n'
       
  2097                                          '#include "bar.h"\n',
       
  2098                                          '')
       
  2099 
       
  2100     def test_check_preprocessor_in_include_section(self):
       
  2101         self.assert_language_rules_check('foo.cpp',
       
  2102                                          '#include "config.h"\n'
       
  2103                                          '#include "foo.h"\n'
       
  2104                                          '\n'
       
  2105                                          '#ifdef BAZ\n'
       
  2106                                          '#include "baz.h"\n'
       
  2107                                          '#else\n'
       
  2108                                          '#include "foobar.h"\n'
       
  2109                                          '#endif"\n'
       
  2110                                          '#include "bar.h"\n', # No flag because previous is in preprocessor section
       
  2111                                          '')
       
  2112 
       
  2113         self.assert_language_rules_check('foo.cpp',
       
  2114                                          '#include "config.h"\n'
       
  2115                                          '#include "foo.h"\n'
       
  2116                                          '\n'
       
  2117                                          '#ifdef BAZ\n'
       
  2118                                          '#include "baz.h"\n'
       
  2119                                          '#endif"\n'
       
  2120                                          '#include "bar.h"\n'
       
  2121                                          '#include "a.h"\n', # Should still flag this.
       
  2122                                          'Alphabetical sorting problem.  [build/include_order] [4]')
       
  2123 
       
  2124         self.assert_language_rules_check('foo.cpp',
       
  2125                                          '#include "config.h"\n'
       
  2126                                          '#include "foo.h"\n'
       
  2127                                          '\n'
       
  2128                                          '#ifdef BAZ\n'
       
  2129                                          '#include "baz.h"\n'
       
  2130                                          '#include "bar.h"\n' #Should still flag this
       
  2131                                          '#endif"\n',
       
  2132                                          'Alphabetical sorting problem.  [build/include_order] [4]')
       
  2133 
       
  2134         self.assert_language_rules_check('foo.cpp',
       
  2135                                          '#include "config.h"\n'
       
  2136                                          '#include "foo.h"\n'
       
  2137                                          '\n'
       
  2138                                          '#ifdef BAZ\n'
       
  2139                                          '#include "baz.h"\n'
       
  2140                                          '#endif"\n'
       
  2141                                          '#ifdef FOOBAR\n'
       
  2142                                          '#include "foobar.h"\n'
       
  2143                                          '#endif"\n'
       
  2144                                          '#include "bar.h"\n'
       
  2145                                          '#include "a.h"\n', # Should still flag this.
       
  2146                                          'Alphabetical sorting problem.  [build/include_order] [4]')
       
  2147 
       
  2148         # Check that after an already included error, the sorting rules still work.
       
  2149         self.assert_language_rules_check('foo.cpp',
       
  2150                                          '#include "config.h"\n'
       
  2151                                          '#include "foo.h"\n'
       
  2152                                          '\n'
       
  2153                                          '#include "foo.h"\n'
       
  2154                                          '#include "g.h"\n',
       
  2155                                          '"foo.h" already included at foo.cpp:1  [build/include] [4]')
       
  2156 
       
  2157     def test_check_wtf_includes(self):
       
  2158         self.assert_language_rules_check('foo.cpp',
       
  2159                                          '#include "config.h"\n'
       
  2160                                          '#include "foo.h"\n'
       
  2161                                          '\n'
       
  2162                                          '#include <wtf/Assertions.h>\n',
       
  2163                                          '')
       
  2164         self.assert_language_rules_check('foo.cpp',
       
  2165                                          '#include "config.h"\n'
       
  2166                                          '#include "foo.h"\n'
       
  2167                                          '\n'
       
  2168                                          '#include "wtf/Assertions.h"\n',
       
  2169                                          'wtf includes should be <wtf/file.h> instead of "wtf/file.h".'
       
  2170                                          '  [build/include] [4]')
       
  2171 
       
  2172     def test_classify_include(self):
       
  2173         classify_include = cpp_style._classify_include
       
  2174         include_state = cpp_style._IncludeState()
       
  2175         self.assertEqual(cpp_style._CONFIG_HEADER,
       
  2176                          classify_include('foo/foo.cpp',
       
  2177                                           'config.h',
       
  2178                                           False, include_state))
       
  2179         self.assertEqual(cpp_style._PRIMARY_HEADER,
       
  2180                          classify_include('foo/internal/foo.cpp',
       
  2181                                           'foo/public/foo.h',
       
  2182                                           False, include_state))
       
  2183         self.assertEqual(cpp_style._PRIMARY_HEADER,
       
  2184                          classify_include('foo/internal/foo.cpp',
       
  2185                                           'foo/other/public/foo.h',
       
  2186                                           False, include_state))
       
  2187         self.assertEqual(cpp_style._OTHER_HEADER,
       
  2188                          classify_include('foo/internal/foo.cpp',
       
  2189                                           'foo/other/public/foop.h',
       
  2190                                           False, include_state))
       
  2191         self.assertEqual(cpp_style._OTHER_HEADER,
       
  2192                          classify_include('foo/foo.cpp',
       
  2193                                           'string',
       
  2194                                           True, include_state))
       
  2195         self.assertEqual(cpp_style._PRIMARY_HEADER,
       
  2196                          classify_include('fooCustom.cpp',
       
  2197                                           'foo.h',
       
  2198                                           False, include_state))
       
  2199         self.assertEqual(cpp_style._PRIMARY_HEADER,
       
  2200                          classify_include('PrefixFooCustom.cpp',
       
  2201                                           'Foo.h',
       
  2202                                           False, include_state))
       
  2203         self.assertEqual(cpp_style._MOC_HEADER,
       
  2204                          classify_include('foo.cpp',
       
  2205                                           'foo.moc',
       
  2206                                           False, include_state))
       
  2207         self.assertEqual(cpp_style._MOC_HEADER,
       
  2208                          classify_include('foo.cpp',
       
  2209                                           'moc_foo.cpp',
       
  2210                                           False, include_state))
       
  2211         # Tricky example where both includes might be classified as primary.
       
  2212         self.assert_language_rules_check('ScrollbarThemeWince.cpp',
       
  2213                                          '#include "config.h"\n'
       
  2214                                          '#include "ScrollbarThemeWince.h"\n'
       
  2215                                          '\n'
       
  2216                                          '#include "Scrollbar.h"\n',
       
  2217                                          '')
       
  2218         self.assert_language_rules_check('ScrollbarThemeWince.cpp',
       
  2219                                          '#include "config.h"\n'
       
  2220                                          '#include "Scrollbar.h"\n'
       
  2221                                          '\n'
       
  2222                                          '#include "ScrollbarThemeWince.h"\n',
       
  2223                                          'Found header this file implements after a header this file implements.'
       
  2224                                          ' Should be: config.h, primary header, blank line, and then alphabetically sorted.'
       
  2225                                          '  [build/include_order] [4]')
       
  2226         self.assert_language_rules_check('ResourceHandleWin.cpp',
       
  2227                                          '#include "config.h"\n'
       
  2228                                          '#include "ResourceHandle.h"\n'
       
  2229                                          '\n'
       
  2230                                          '#include "ResourceHandleWin.h"\n',
       
  2231                                          '')
       
  2232 
       
  2233     def test_try_drop_common_suffixes(self):
       
  2234         self.assertEqual('foo/foo', cpp_style._drop_common_suffixes('foo/foo-inl.h'))
       
  2235         self.assertEqual('foo/bar/foo',
       
  2236                          cpp_style._drop_common_suffixes('foo/bar/foo_inl.h'))
       
  2237         self.assertEqual('foo/foo', cpp_style._drop_common_suffixes('foo/foo.cpp'))
       
  2238         self.assertEqual('foo/foo_unusualinternal',
       
  2239                          cpp_style._drop_common_suffixes('foo/foo_unusualinternal.h'))
       
  2240         self.assertEqual('',
       
  2241                          cpp_style._drop_common_suffixes('_test.cpp'))
       
  2242         self.assertEqual('test',
       
  2243                          cpp_style._drop_common_suffixes('test.cpp'))
       
  2244         self.assertEqual('test',
       
  2245                          cpp_style._drop_common_suffixes('test.cpp'))
       
  2246 
       
  2247 class CheckForFunctionLengthsTest(CppStyleTestBase):
       
  2248     def setUp(self):
       
  2249         # Reducing these thresholds for the tests speeds up tests significantly.
       
  2250         self.old_normal_trigger = cpp_style._FunctionState._NORMAL_TRIGGER
       
  2251         self.old_test_trigger = cpp_style._FunctionState._TEST_TRIGGER
       
  2252 
       
  2253         cpp_style._FunctionState._NORMAL_TRIGGER = 10
       
  2254         cpp_style._FunctionState._TEST_TRIGGER = 25
       
  2255 
       
  2256     def tearDown(self):
       
  2257         cpp_style._FunctionState._NORMAL_TRIGGER = self.old_normal_trigger
       
  2258         cpp_style._FunctionState._TEST_TRIGGER = self.old_test_trigger
       
  2259 
       
  2260     # FIXME: Eliminate the need for this function.
       
  2261     def set_min_confidence(self, min_confidence):
       
  2262         """Set new test confidence and return old test confidence."""
       
  2263         old_min_confidence = self.min_confidence
       
  2264         self.min_confidence = min_confidence
       
  2265         return old_min_confidence
       
  2266 
       
  2267     def assert_function_lengths_check(self, code, expected_message):
       
  2268         """Check warnings for long function bodies are as expected.
       
  2269 
       
  2270         Args:
       
  2271           code: C++ source code expected to generate a warning message.
       
  2272           expected_message: Message expected to be generated by the C++ code.
       
  2273         """
       
  2274         self.assertEquals(expected_message,
       
  2275                           self.perform_function_lengths_check(code))
       
  2276 
       
  2277     def trigger_lines(self, error_level):
       
  2278         """Return number of lines needed to trigger a function length warning.
       
  2279 
       
  2280         Args:
       
  2281           error_level: --v setting for cpp_style.
       
  2282 
       
  2283         Returns:
       
  2284           Number of lines needed to trigger a function length warning.
       
  2285         """
       
  2286         return cpp_style._FunctionState._NORMAL_TRIGGER * 2 ** error_level
       
  2287 
       
  2288     def trigger_test_lines(self, error_level):
       
  2289         """Return number of lines needed to trigger a test function length warning.
       
  2290 
       
  2291         Args:
       
  2292           error_level: --v setting for cpp_style.
       
  2293 
       
  2294         Returns:
       
  2295           Number of lines needed to trigger a test function length warning.
       
  2296         """
       
  2297         return cpp_style._FunctionState._TEST_TRIGGER * 2 ** error_level
       
  2298 
       
  2299     def assert_function_length_check_definition(self, lines, error_level):
       
  2300         """Generate long function definition and check warnings are as expected.
       
  2301 
       
  2302         Args:
       
  2303           lines: Number of lines to generate.
       
  2304           error_level:  --v setting for cpp_style.
       
  2305         """
       
  2306         trigger_level = self.trigger_lines(self.min_confidence)
       
  2307         self.assert_function_lengths_check(
       
  2308             'void test(int x)' + self.function_body(lines),
       
  2309             ('Small and focused functions are preferred: '
       
  2310              'test() has %d non-comment lines '
       
  2311              '(error triggered by exceeding %d lines).'
       
  2312              '  [readability/fn_size] [%d]'
       
  2313              % (lines, trigger_level, error_level)))
       
  2314 
       
  2315     def assert_function_length_check_definition_ok(self, lines):
       
  2316         """Generate shorter function definition and check no warning is produced.
       
  2317 
       
  2318         Args:
       
  2319           lines: Number of lines to generate.
       
  2320         """
       
  2321         self.assert_function_lengths_check(
       
  2322             'void test(int x)' + self.function_body(lines),
       
  2323             '')
       
  2324 
       
  2325     def assert_function_length_check_at_error_level(self, error_level):
       
  2326         """Generate and check function at the trigger level for --v setting.
       
  2327 
       
  2328         Args:
       
  2329           error_level: --v setting for cpp_style.
       
  2330         """
       
  2331         self.assert_function_length_check_definition(self.trigger_lines(error_level),
       
  2332                                                      error_level)
       
  2333 
       
  2334     def assert_function_length_check_below_error_level(self, error_level):
       
  2335         """Generate and check function just below the trigger level for --v setting.
       
  2336 
       
  2337         Args:
       
  2338           error_level: --v setting for cpp_style.
       
  2339         """
       
  2340         self.assert_function_length_check_definition(self.trigger_lines(error_level) - 1,
       
  2341                                                      error_level - 1)
       
  2342 
       
  2343     def assert_function_length_check_above_error_level(self, error_level):
       
  2344         """Generate and check function just above the trigger level for --v setting.
       
  2345 
       
  2346         Args:
       
  2347           error_level: --v setting for cpp_style.
       
  2348         """
       
  2349         self.assert_function_length_check_definition(self.trigger_lines(error_level) + 1,
       
  2350                                                      error_level)
       
  2351 
       
  2352     def function_body(self, number_of_lines):
       
  2353         return ' {\n' + '    this_is_just_a_test();\n' * number_of_lines + '}'
       
  2354 
       
  2355     def function_body_with_blank_lines(self, number_of_lines):
       
  2356         return ' {\n' + '    this_is_just_a_test();\n\n' * number_of_lines + '}'
       
  2357 
       
  2358     def function_body_with_no_lints(self, number_of_lines):
       
  2359         return ' {\n' + '    this_is_just_a_test();  // NOLINT\n' * number_of_lines + '}'
       
  2360 
       
  2361     # Test line length checks.
       
  2362     def test_function_length_check_declaration(self):
       
  2363         self.assert_function_lengths_check(
       
  2364             'void test();',  # Not a function definition
       
  2365             '')
       
  2366 
       
  2367     def test_function_length_check_declaration_with_block_following(self):
       
  2368         self.assert_function_lengths_check(
       
  2369             ('void test();\n'
       
  2370              + self.function_body(66)),  # Not a function definition
       
  2371             '')
       
  2372 
       
  2373     def test_function_length_check_class_definition(self):
       
  2374         self.assert_function_lengths_check(  # Not a function definition
       
  2375             'class Test' + self.function_body(66) + ';',
       
  2376             '')
       
  2377 
       
  2378     def test_function_length_check_trivial(self):
       
  2379         self.assert_function_lengths_check(
       
  2380             'void test() {}',  # Not counted
       
  2381             '')
       
  2382 
       
  2383     def test_function_length_check_empty(self):
       
  2384         self.assert_function_lengths_check(
       
  2385             'void test() {\n}',
       
  2386             '')
       
  2387 
       
  2388     def test_function_length_check_definition_below_severity0(self):
       
  2389         old_min_confidence = self.set_min_confidence(0)
       
  2390         self.assert_function_length_check_definition_ok(self.trigger_lines(0) - 1)
       
  2391         self.set_min_confidence(old_min_confidence)
       
  2392 
       
  2393     def test_function_length_check_definition_at_severity0(self):
       
  2394         old_min_confidence = self.set_min_confidence(0)
       
  2395         self.assert_function_length_check_definition_ok(self.trigger_lines(0))
       
  2396         self.set_min_confidence(old_min_confidence)
       
  2397 
       
  2398     def test_function_length_check_definition_above_severity0(self):
       
  2399         old_min_confidence = self.set_min_confidence(0)
       
  2400         self.assert_function_length_check_above_error_level(0)
       
  2401         self.set_min_confidence(old_min_confidence)
       
  2402 
       
  2403     def test_function_length_check_definition_below_severity1v0(self):
       
  2404         old_min_confidence = self.set_min_confidence(0)
       
  2405         self.assert_function_length_check_below_error_level(1)
       
  2406         self.set_min_confidence(old_min_confidence)
       
  2407 
       
  2408     def test_function_length_check_definition_at_severity1v0(self):
       
  2409         old_min_confidence = self.set_min_confidence(0)
       
  2410         self.assert_function_length_check_at_error_level(1)
       
  2411         self.set_min_confidence(old_min_confidence)
       
  2412 
       
  2413     def test_function_length_check_definition_below_severity1(self):
       
  2414         self.assert_function_length_check_definition_ok(self.trigger_lines(1) - 1)
       
  2415 
       
  2416     def test_function_length_check_definition_at_severity1(self):
       
  2417         self.assert_function_length_check_definition_ok(self.trigger_lines(1))
       
  2418 
       
  2419     def test_function_length_check_definition_above_severity1(self):
       
  2420         self.assert_function_length_check_above_error_level(1)
       
  2421 
       
  2422     def test_function_length_check_definition_severity1_plus_blanks(self):
       
  2423         error_level = 1
       
  2424         error_lines = self.trigger_lines(error_level) + 1
       
  2425         trigger_level = self.trigger_lines(self.min_confidence)
       
  2426         self.assert_function_lengths_check(
       
  2427             'void test_blanks(int x)' + self.function_body(error_lines),
       
  2428             ('Small and focused functions are preferred: '
       
  2429              'test_blanks() has %d non-comment lines '
       
  2430              '(error triggered by exceeding %d lines).'
       
  2431              '  [readability/fn_size] [%d]')
       
  2432             % (error_lines, trigger_level, error_level))
       
  2433 
       
  2434     def test_function_length_check_complex_definition_severity1(self):
       
  2435         error_level = 1
       
  2436         error_lines = self.trigger_lines(error_level) + 1
       
  2437         trigger_level = self.trigger_lines(self.min_confidence)
       
  2438         self.assert_function_lengths_check(
       
  2439             ('my_namespace::my_other_namespace::MyVeryLongTypeName*\n'
       
  2440              'my_namespace::my_other_namespace::MyFunction(int arg1, char* arg2)'
       
  2441              + self.function_body(error_lines)),
       
  2442             ('Small and focused functions are preferred: '
       
  2443              'my_namespace::my_other_namespace::MyFunction()'
       
  2444              ' has %d non-comment lines '
       
  2445              '(error triggered by exceeding %d lines).'
       
  2446              '  [readability/fn_size] [%d]')
       
  2447             % (error_lines, trigger_level, error_level))
       
  2448 
       
  2449     def test_function_length_check_definition_severity1_for_test(self):
       
  2450         error_level = 1
       
  2451         error_lines = self.trigger_test_lines(error_level) + 1
       
  2452         trigger_level = self.trigger_test_lines(self.min_confidence)
       
  2453         self.assert_function_lengths_check(
       
  2454             'TEST_F(Test, Mutator)' + self.function_body(error_lines),
       
  2455             ('Small and focused functions are preferred: '
       
  2456              'TEST_F(Test, Mutator) has %d non-comment lines '
       
  2457              '(error triggered by exceeding %d lines).'
       
  2458              '  [readability/fn_size] [%d]')
       
  2459             % (error_lines, trigger_level, error_level))
       
  2460 
       
  2461     def test_function_length_check_definition_severity1_for_split_line_test(self):
       
  2462         error_level = 1
       
  2463         error_lines = self.trigger_test_lines(error_level) + 1
       
  2464         trigger_level = self.trigger_test_lines(self.min_confidence)
       
  2465         self.assert_function_lengths_check(
       
  2466             ('TEST_F(GoogleUpdateRecoveryRegistryProtectedTest,\n'
       
  2467              '    FixGoogleUpdate_AllValues_MachineApp)'  # note: 4 spaces
       
  2468              + self.function_body(error_lines)),
       
  2469             ('Small and focused functions are preferred: '
       
  2470              'TEST_F(GoogleUpdateRecoveryRegistryProtectedTest, '  # 1 space
       
  2471              'FixGoogleUpdate_AllValues_MachineApp) has %d non-comment lines '
       
  2472              '(error triggered by exceeding %d lines).'
       
  2473              '  [readability/fn_size] [%d]')
       
  2474             % (error_lines+1, trigger_level, error_level))
       
  2475 
       
  2476     def test_function_length_check_definition_severity1_for_bad_test_doesnt_break(self):
       
  2477         error_level = 1
       
  2478         error_lines = self.trigger_test_lines(error_level) + 1
       
  2479         trigger_level = self.trigger_test_lines(self.min_confidence)
       
  2480         self.assert_function_lengths_check(
       
  2481             ('TEST_F('
       
  2482              + self.function_body(error_lines)),
       
  2483             ('Small and focused functions are preferred: '
       
  2484              'TEST_F has %d non-comment lines '
       
  2485              '(error triggered by exceeding %d lines).'
       
  2486              '  [readability/fn_size] [%d]')
       
  2487             % (error_lines, trigger_level, error_level))
       
  2488 
       
  2489     def test_function_length_check_definition_severity1_with_embedded_no_lints(self):
       
  2490         error_level = 1
       
  2491         error_lines = self.trigger_lines(error_level) + 1
       
  2492         trigger_level = self.trigger_lines(self.min_confidence)
       
  2493         self.assert_function_lengths_check(
       
  2494             'void test(int x)' + self.function_body_with_no_lints(error_lines),
       
  2495             ('Small and focused functions are preferred: '
       
  2496              'test() has %d non-comment lines '
       
  2497              '(error triggered by exceeding %d lines).'
       
  2498              '  [readability/fn_size] [%d]')
       
  2499             % (error_lines, trigger_level, error_level))
       
  2500 
       
  2501     def test_function_length_check_definition_severity1_with_no_lint(self):
       
  2502         self.assert_function_lengths_check(
       
  2503             ('void test(int x)' + self.function_body(self.trigger_lines(1))
       
  2504              + '  // NOLINT -- long function'),
       
  2505             '')
       
  2506 
       
  2507     def test_function_length_check_definition_below_severity2(self):
       
  2508         self.assert_function_length_check_below_error_level(2)
       
  2509 
       
  2510     def test_function_length_check_definition_severity2(self):
       
  2511         self.assert_function_length_check_at_error_level(2)
       
  2512 
       
  2513     def test_function_length_check_definition_above_severity2(self):
       
  2514         self.assert_function_length_check_above_error_level(2)
       
  2515 
       
  2516     def test_function_length_check_definition_below_severity3(self):
       
  2517         self.assert_function_length_check_below_error_level(3)
       
  2518 
       
  2519     def test_function_length_check_definition_severity3(self):
       
  2520         self.assert_function_length_check_at_error_level(3)
       
  2521 
       
  2522     def test_function_length_check_definition_above_severity3(self):
       
  2523         self.assert_function_length_check_above_error_level(3)
       
  2524 
       
  2525     def test_function_length_check_definition_below_severity4(self):
       
  2526         self.assert_function_length_check_below_error_level(4)
       
  2527 
       
  2528     def test_function_length_check_definition_severity4(self):
       
  2529         self.assert_function_length_check_at_error_level(4)
       
  2530 
       
  2531     def test_function_length_check_definition_above_severity4(self):
       
  2532         self.assert_function_length_check_above_error_level(4)
       
  2533 
       
  2534     def test_function_length_check_definition_below_severity5(self):
       
  2535         self.assert_function_length_check_below_error_level(5)
       
  2536 
       
  2537     def test_function_length_check_definition_at_severity5(self):
       
  2538         self.assert_function_length_check_at_error_level(5)
       
  2539 
       
  2540     def test_function_length_check_definition_above_severity5(self):
       
  2541         self.assert_function_length_check_above_error_level(5)
       
  2542 
       
  2543     def test_function_length_check_definition_huge_lines(self):
       
  2544         # 5 is the limit
       
  2545         self.assert_function_length_check_definition(self.trigger_lines(10), 5)
       
  2546 
       
  2547     def test_function_length_not_determinable(self):
       
  2548         # Macro invocation without terminating semicolon.
       
  2549         self.assert_function_lengths_check(
       
  2550             'MACRO(arg)',
       
  2551             '')
       
  2552 
       
  2553         # Macro with underscores
       
  2554         self.assert_function_lengths_check(
       
  2555             'MACRO_WITH_UNDERSCORES(arg1, arg2, arg3)',
       
  2556             '')
       
  2557 
       
  2558         self.assert_function_lengths_check(
       
  2559             'NonMacro(arg)',
       
  2560             'Lint failed to find start of function body.'
       
  2561             '  [readability/fn_size] [5]')
       
  2562 
       
  2563 
       
  2564 class NoNonVirtualDestructorsTest(CppStyleTestBase):
       
  2565 
       
  2566     def test_no_error(self):
       
  2567         self.assert_multi_line_lint(
       
  2568             '''class Foo {
       
  2569                    virtual ~Foo();
       
  2570                    virtual void foo();
       
  2571                };''',
       
  2572             '')
       
  2573 
       
  2574         self.assert_multi_line_lint(
       
  2575             '''class Foo {
       
  2576                    virtual inline ~Foo();
       
  2577                    virtual void foo();
       
  2578                };''',
       
  2579             '')
       
  2580 
       
  2581         self.assert_multi_line_lint(
       
  2582             '''class Foo {
       
  2583                    inline virtual ~Foo();
       
  2584                    virtual void foo();
       
  2585                };''',
       
  2586             '')
       
  2587 
       
  2588         self.assert_multi_line_lint(
       
  2589             '''class Foo::Goo {
       
  2590                    virtual ~Goo();
       
  2591                    virtual void goo();
       
  2592                };''',
       
  2593             '')
       
  2594         self.assert_multi_line_lint(
       
  2595             'class Foo { void foo(); };',
       
  2596             'More than one command on the same line  [whitespace/newline] [4]')
       
  2597 
       
  2598         self.assert_multi_line_lint(
       
  2599             '''class Qualified::Goo : public Foo {
       
  2600                    virtual void goo();
       
  2601                };''',
       
  2602             '')
       
  2603 
       
  2604         self.assert_multi_line_lint(
       
  2605             # Line-ending :
       
  2606             '''class Goo :
       
  2607                public Foo {
       
  2608                     virtual void goo();
       
  2609                };''',
       
  2610             'Labels should always be indented at least one space.  If this is a '
       
  2611             'member-initializer list in a constructor, the colon should be on the '
       
  2612             'line after the definition header.  [whitespace/labels] [4]')
       
  2613 
       
  2614     def test_no_destructor_when_virtual_needed(self):
       
  2615         self.assert_multi_line_lint_re(
       
  2616             '''class Foo {
       
  2617                    virtual void foo();
       
  2618                };''',
       
  2619             'The class Foo probably needs a virtual destructor')
       
  2620 
       
  2621     def test_destructor_non_virtual_when_virtual_needed(self):
       
  2622         self.assert_multi_line_lint_re(
       
  2623             '''class Foo {
       
  2624                    ~Foo();
       
  2625                    virtual void foo();
       
  2626                };''',
       
  2627             'The class Foo probably needs a virtual destructor')
       
  2628 
       
  2629     def test_no_warn_when_derived(self):
       
  2630         self.assert_multi_line_lint(
       
  2631             '''class Foo : public Goo {
       
  2632                    virtual void foo();
       
  2633                };''',
       
  2634             '')
       
  2635 
       
  2636     def test_internal_braces(self):
       
  2637         self.assert_multi_line_lint_re(
       
  2638             '''class Foo {
       
  2639                    enum Goo {
       
  2640                        GOO
       
  2641                    };
       
  2642                    virtual void foo();
       
  2643                };''',
       
  2644             'The class Foo probably needs a virtual destructor')
       
  2645 
       
  2646     def test_inner_class_needs_virtual_destructor(self):
       
  2647         self.assert_multi_line_lint_re(
       
  2648             '''class Foo {
       
  2649                    class Goo {
       
  2650                        virtual void goo();
       
  2651                    };
       
  2652                };''',
       
  2653             'The class Goo probably needs a virtual destructor')
       
  2654 
       
  2655     def test_outer_class_needs_virtual_destructor(self):
       
  2656         self.assert_multi_line_lint_re(
       
  2657             '''class Foo {
       
  2658                    class Goo {
       
  2659                    };
       
  2660                    virtual void foo();
       
  2661                };''',
       
  2662             'The class Foo probably needs a virtual destructor')
       
  2663 
       
  2664     def test_qualified_class_needs_virtual_destructor(self):
       
  2665         self.assert_multi_line_lint_re(
       
  2666             '''class Qualified::Foo {
       
  2667                    virtual void foo();
       
  2668                };''',
       
  2669             'The class Qualified::Foo probably needs a virtual destructor')
       
  2670 
       
  2671     def test_multi_line_declaration_no_error(self):
       
  2672         self.assert_multi_line_lint_re(
       
  2673             '''class Foo
       
  2674                    : public Goo {
       
  2675                    virtual void foo();
       
  2676                };''',
       
  2677             '')
       
  2678 
       
  2679     def test_multi_line_declaration_with_error(self):
       
  2680         self.assert_multi_line_lint(
       
  2681             '''class Foo
       
  2682                {
       
  2683                    virtual void foo();
       
  2684                };''',
       
  2685             ['This { should be at the end of the previous line  '
       
  2686              '[whitespace/braces] [4]',
       
  2687              'The class Foo probably needs a virtual destructor due to having '
       
  2688              'virtual method(s), one declared at line 2.  [runtime/virtual] [4]'])
       
  2689 
       
  2690 
       
  2691 class WebKitStyleTest(CppStyleTestBase):
       
  2692 
       
  2693     # for http://webkit.org/coding/coding-style.html
       
  2694     def test_indentation(self):
       
  2695         # 1. Use spaces, not tabs. Tabs should only appear in files that
       
  2696         #    require them for semantic meaning, like Makefiles.
       
  2697         self.assert_multi_line_lint(
       
  2698             'class Foo {\n'
       
  2699             '    int goo;\n'
       
  2700             '};',
       
  2701             '')
       
  2702         self.assert_multi_line_lint(
       
  2703             'class Foo {\n'
       
  2704             '\tint goo;\n'
       
  2705             '};',
       
  2706             'Tab found; better to use spaces  [whitespace/tab] [1]')
       
  2707 
       
  2708         # 2. The indent size is 4 spaces.
       
  2709         self.assert_multi_line_lint(
       
  2710             'class Foo {\n'
       
  2711             '    int goo;\n'
       
  2712             '};',
       
  2713             '')
       
  2714         self.assert_multi_line_lint(
       
  2715             'class Foo {\n'
       
  2716             '   int goo;\n'
       
  2717             '};',
       
  2718             'Weird number of spaces at line-start.  Are you using a 4-space indent?  [whitespace/indent] [3]')
       
  2719         # FIXME: No tests for 8-spaces.
       
  2720 
       
  2721         # 3. In a header, code inside a namespace should not be indented.
       
  2722         self.assert_multi_line_lint(
       
  2723             'namespace WebCore {\n\n'
       
  2724             'class Document {\n'
       
  2725             '    int myVariable;\n'
       
  2726             '};\n'
       
  2727             '}',
       
  2728             '',
       
  2729             'foo.h')
       
  2730         self.assert_multi_line_lint(
       
  2731             'namespace OuterNamespace {\n'
       
  2732             '    namespace InnerNamespace {\n'
       
  2733             '    class Document {\n'
       
  2734             '};\n'
       
  2735             '};\n'
       
  2736             '}',
       
  2737             'Code inside a namespace should not be indented.  [whitespace/indent] [4]',
       
  2738             'foo.h')
       
  2739         self.assert_multi_line_lint(
       
  2740             'namespace OuterNamespace {\n'
       
  2741             '    class Document {\n'
       
  2742             '    namespace InnerNamespace {\n'
       
  2743             '};\n'
       
  2744             '};\n'
       
  2745             '}',
       
  2746             'Code inside a namespace should not be indented.  [whitespace/indent] [4]',
       
  2747             'foo.h')
       
  2748         self.assert_multi_line_lint(
       
  2749             'namespace WebCore {\n'
       
  2750             '#if 0\n'
       
  2751             '    class Document {\n'
       
  2752             '};\n'
       
  2753             '#endif\n'
       
  2754             '}',
       
  2755             'Code inside a namespace should not be indented.  [whitespace/indent] [4]',
       
  2756             'foo.h')
       
  2757         self.assert_multi_line_lint(
       
  2758             'namespace WebCore {\n'
       
  2759             'class Document {\n'
       
  2760             '};\n'
       
  2761             '}',
       
  2762             '',
       
  2763             'foo.h')
       
  2764 
       
  2765         # 4. In an implementation file (files with the extension .cpp, .c
       
  2766         #    or .mm), code inside a namespace should not be indented.
       
  2767         self.assert_multi_line_lint(
       
  2768             'namespace WebCore {\n\n'
       
  2769             'Document::Foo()\n'
       
  2770             '    : foo(bar)\n'
       
  2771             '    , boo(far)\n'
       
  2772             '{\n'
       
  2773             '    stuff();\n'
       
  2774             '}',
       
  2775             '',
       
  2776             'foo.cpp')
       
  2777         self.assert_multi_line_lint(
       
  2778             'namespace OuterNamespace {\n'
       
  2779             'namespace InnerNamespace {\n'
       
  2780             'Document::Foo() { }\n'
       
  2781             '    void* p;\n'
       
  2782             '}\n'
       
  2783             '}\n',
       
  2784             'Code inside a namespace should not be indented.  [whitespace/indent] [4]',
       
  2785             'foo.cpp')
       
  2786         self.assert_multi_line_lint(
       
  2787             'namespace OuterNamespace {\n'
       
  2788             'namespace InnerNamespace {\n'
       
  2789             'Document::Foo() { }\n'
       
  2790             '}\n'
       
  2791             '    void* p;\n'
       
  2792             '}\n',
       
  2793             'Code inside a namespace should not be indented.  [whitespace/indent] [4]',
       
  2794             'foo.cpp')
       
  2795         self.assert_multi_line_lint(
       
  2796             'namespace WebCore {\n\n'
       
  2797             '    const char* foo = "start:;"\n'
       
  2798             '        "dfsfsfs";\n'
       
  2799             '}\n',
       
  2800             'Code inside a namespace should not be indented.  [whitespace/indent] [4]',
       
  2801             'foo.cpp')
       
  2802         self.assert_multi_line_lint(
       
  2803             'namespace WebCore {\n\n'
       
  2804             'const char* foo(void* a = ";", // ;\n'
       
  2805             '    void* b);\n'
       
  2806             '    void* p;\n'
       
  2807             '}\n',
       
  2808             'Code inside a namespace should not be indented.  [whitespace/indent] [4]',
       
  2809             'foo.cpp')
       
  2810         self.assert_multi_line_lint(
       
  2811             'namespace WebCore {\n\n'
       
  2812             'const char* foo[] = {\n'
       
  2813             '    "void* b);", // ;\n'
       
  2814             '    "asfdf",\n'
       
  2815             '    }\n'
       
  2816             '    void* p;\n'
       
  2817             '}\n',
       
  2818             'Code inside a namespace should not be indented.  [whitespace/indent] [4]',
       
  2819             'foo.cpp')
       
  2820         self.assert_multi_line_lint(
       
  2821             'namespace WebCore {\n\n'
       
  2822             'const char* foo[] = {\n'
       
  2823             '    "void* b);", // }\n'
       
  2824             '    "asfdf",\n'
       
  2825             '    }\n'
       
  2826             '}\n',
       
  2827             '',
       
  2828             'foo.cpp')
       
  2829         self.assert_multi_line_lint(
       
  2830             '    namespace WebCore {\n\n'
       
  2831             '    void Document::Foo()\n'
       
  2832             '    {\n'
       
  2833             'start: // infinite loops are fun!\n'
       
  2834             '        goto start;\n'
       
  2835             '    }',
       
  2836             'namespace should never be indented.  [whitespace/indent] [4]',
       
  2837             'foo.cpp')
       
  2838         self.assert_multi_line_lint(
       
  2839             'namespace WebCore {\n'
       
  2840             '    Document::Foo() { }\n'
       
  2841             '}',
       
  2842             'Code inside a namespace should not be indented.'
       
  2843             '  [whitespace/indent] [4]',
       
  2844             'foo.cpp')
       
  2845         self.assert_multi_line_lint(
       
  2846             'namespace WebCore {\n'
       
  2847             '#define abc(x) x; \\\n'
       
  2848             '    x\n'
       
  2849             '}',
       
  2850             '',
       
  2851             'foo.cpp')
       
  2852         self.assert_multi_line_lint(
       
  2853             'namespace WebCore {\n'
       
  2854             '#define abc(x) x; \\\n'
       
  2855             '    x\n'
       
  2856             '    void* x;'
       
  2857             '}',
       
  2858             'Code inside a namespace should not be indented.  [whitespace/indent] [4]',
       
  2859             'foo.cpp')
       
  2860 
       
  2861         # 5. A case label should line up with its switch statement. The
       
  2862         #    case statement is indented.
       
  2863         self.assert_multi_line_lint(
       
  2864             '    switch (condition) {\n'
       
  2865             '    case fooCondition:\n'
       
  2866             '    case barCondition:\n'
       
  2867             '        i++;\n'
       
  2868             '        break;\n'
       
  2869             '    default:\n'
       
  2870             '        i--;\n'
       
  2871             '    }\n',
       
  2872             '')
       
  2873         self.assert_multi_line_lint(
       
  2874             '    switch (condition) {\n'
       
  2875             '    case fooCondition:\n'
       
  2876             '        switch (otherCondition) {\n'
       
  2877             '        default:\n'
       
  2878             '            return;\n'
       
  2879             '        }\n'
       
  2880             '    default:\n'
       
  2881             '        i--;\n'
       
  2882             '    }\n',
       
  2883             '')
       
  2884         self.assert_multi_line_lint(
       
  2885             '    switch (condition) {\n'
       
  2886             '    case fooCondition: break;\n'
       
  2887             '    default: return;\n'
       
  2888             '    }\n',
       
  2889             '')
       
  2890         self.assert_multi_line_lint(
       
  2891             '    switch (condition) {\n'
       
  2892             '        case fooCondition:\n'
       
  2893             '        case barCondition:\n'
       
  2894             '            i++;\n'
       
  2895             '            break;\n'
       
  2896             '        default:\n'
       
  2897             '            i--;\n'
       
  2898             '    }\n',
       
  2899             'A case label should not be indented, but line up with its switch statement.'
       
  2900             '  [whitespace/indent] [4]')
       
  2901         self.assert_multi_line_lint(
       
  2902             '    switch (condition) {\n'
       
  2903             '        case fooCondition:\n'
       
  2904             '            break;\n'
       
  2905             '    default:\n'
       
  2906             '            i--;\n'
       
  2907             '    }\n',
       
  2908             'A case label should not be indented, but line up with its switch statement.'
       
  2909             '  [whitespace/indent] [4]')
       
  2910         self.assert_multi_line_lint(
       
  2911             '    switch (condition) {\n'
       
  2912             '    case fooCondition:\n'
       
  2913             '    case barCondition:\n'
       
  2914             '        switch (otherCondition) {\n'
       
  2915             '            default:\n'
       
  2916             '            return;\n'
       
  2917             '        }\n'
       
  2918             '    default:\n'
       
  2919             '        i--;\n'
       
  2920             '    }\n',
       
  2921             'A case label should not be indented, but line up with its switch statement.'
       
  2922             '  [whitespace/indent] [4]')
       
  2923         self.assert_multi_line_lint(
       
  2924             '    switch (condition) {\n'
       
  2925             '    case fooCondition:\n'
       
  2926             '    case barCondition:\n'
       
  2927             '    i++;\n'
       
  2928             '    break;\n\n'
       
  2929             '    default:\n'
       
  2930             '    i--;\n'
       
  2931             '    }\n',
       
  2932             'Non-label code inside switch statements should be indented.'
       
  2933             '  [whitespace/indent] [4]')
       
  2934         self.assert_multi_line_lint(
       
  2935             '    switch (condition) {\n'
       
  2936             '    case fooCondition:\n'
       
  2937             '    case barCondition:\n'
       
  2938             '        switch (otherCondition) {\n'
       
  2939             '        default:\n'
       
  2940             '        return;\n'
       
  2941             '        }\n'
       
  2942             '    default:\n'
       
  2943             '        i--;\n'
       
  2944             '    }\n',
       
  2945             'Non-label code inside switch statements should be indented.'
       
  2946             '  [whitespace/indent] [4]')
       
  2947 
       
  2948         # 6. Boolean expressions at the same nesting level that span
       
  2949         #   multiple lines should have their operators on the left side of
       
  2950         #   the line instead of the right side.
       
  2951         self.assert_multi_line_lint(
       
  2952             '    return attr->name() == srcAttr\n'
       
  2953             '        || attr->name() == lowsrcAttr;\n',
       
  2954             '')
       
  2955         self.assert_multi_line_lint(
       
  2956             '    return attr->name() == srcAttr ||\n'
       
  2957             '        attr->name() == lowsrcAttr;\n',
       
  2958             'Boolean expressions that span multiple lines should have their '
       
  2959             'operators on the left side of the line instead of the right side.'
       
  2960             '  [whitespace/operators] [4]')
       
  2961 
       
  2962     def test_spacing(self):
       
  2963         # 1. Do not place spaces around unary operators.
       
  2964         self.assert_multi_line_lint(
       
  2965             'i++;',
       
  2966             '')
       
  2967         self.assert_multi_line_lint(
       
  2968             'i ++;',
       
  2969             'Extra space for operator  ++;  [whitespace/operators] [4]')
       
  2970 
       
  2971         # 2. Do place spaces around binary and ternary operators.
       
  2972         self.assert_multi_line_lint(
       
  2973             'y = m * x + b;',
       
  2974             '')
       
  2975         self.assert_multi_line_lint(
       
  2976             'f(a, b);',
       
  2977             '')
       
  2978         self.assert_multi_line_lint(
       
  2979             'c = a | b;',
       
  2980             '')
       
  2981         self.assert_multi_line_lint(
       
  2982             'return condition ? 1 : 0;',
       
  2983             '')
       
  2984         self.assert_multi_line_lint(
       
  2985             'y=m*x+b;',
       
  2986             'Missing spaces around =  [whitespace/operators] [4]')
       
  2987         self.assert_multi_line_lint(
       
  2988             'f(a,b);',
       
  2989             'Missing space after ,  [whitespace/comma] [3]')
       
  2990         self.assert_multi_line_lint(
       
  2991             'c = a|b;',
       
  2992             'Missing spaces around |  [whitespace/operators] [3]')
       
  2993         # FIXME: We cannot catch this lint error.
       
  2994         # self.assert_multi_line_lint(
       
  2995         #     'return condition ? 1:0;',
       
  2996         #     '')
       
  2997 
       
  2998         # 3. Place spaces between control statements and their parentheses.
       
  2999         self.assert_multi_line_lint(
       
  3000             '    if (condition)\n'
       
  3001             '        doIt();\n',
       
  3002             '')
       
  3003         self.assert_multi_line_lint(
       
  3004             '    if(condition)\n'
       
  3005             '        doIt();\n',
       
  3006             'Missing space before ( in if(  [whitespace/parens] [5]')
       
  3007 
       
  3008         # 4. Do not place spaces between a function and its parentheses,
       
  3009         #    or between a parenthesis and its content.
       
  3010         self.assert_multi_line_lint(
       
  3011             'f(a, b);',
       
  3012             '')
       
  3013         self.assert_multi_line_lint(
       
  3014             'f (a, b);',
       
  3015             'Extra space before ( in function call  [whitespace/parens] [4]')
       
  3016         self.assert_multi_line_lint(
       
  3017             'f( a, b );',
       
  3018             ['Extra space after ( in function call  [whitespace/parens] [4]',
       
  3019              'Extra space before )  [whitespace/parens] [2]'])
       
  3020 
       
  3021     def test_line_breaking(self):
       
  3022         # 1. Each statement should get its own line.
       
  3023         self.assert_multi_line_lint(
       
  3024             '    x++;\n'
       
  3025             '    y++;\n'
       
  3026             '    if (condition);\n'
       
  3027             '        doIt();\n',
       
  3028             '')
       
  3029         self.assert_multi_line_lint(
       
  3030             '    if (condition) \\\n'
       
  3031             '        doIt();\n',
       
  3032             '')
       
  3033         self.assert_multi_line_lint(
       
  3034             '    x++; y++;',
       
  3035             'More than one command on the same line  [whitespace/newline] [4]')
       
  3036         self.assert_multi_line_lint(
       
  3037             '    if (condition) doIt();\n',
       
  3038             'More than one command on the same line in if  [whitespace/parens] [4]')
       
  3039 
       
  3040         # 2. An else statement should go on the same line as a preceding
       
  3041         #   close brace if one is present, else it should line up with the
       
  3042         #   if statement.
       
  3043         self.assert_multi_line_lint(
       
  3044             'if (condition) {\n'
       
  3045             '    doSomething();\n'
       
  3046             '    doSomethingAgain();\n'
       
  3047             '} else {\n'
       
  3048             '    doSomethingElse();\n'
       
  3049             '    doSomethingElseAgain();\n'
       
  3050             '}\n',
       
  3051             '')
       
  3052         self.assert_multi_line_lint(
       
  3053             'if (condition)\n'
       
  3054             '    doSomething();\n'
       
  3055             'else\n'
       
  3056             '    doSomethingElse();\n',
       
  3057             '')
       
  3058         self.assert_multi_line_lint(
       
  3059             'if (condition)\n'
       
  3060             '    doSomething();\n'
       
  3061             'else {\n'
       
  3062             '    doSomethingElse();\n'
       
  3063             '    doSomethingElseAgain();\n'
       
  3064             '}\n',
       
  3065             '')
       
  3066         self.assert_multi_line_lint(
       
  3067             '#define TEST_ASSERT(expression) do { if (!(expression)) { TestsController::shared().testFailed(__FILE__, __LINE__, #expression); return; } } while (0)\n',
       
  3068             '')
       
  3069         self.assert_multi_line_lint(
       
  3070             '#define TEST_ASSERT(expression) do { if ( !(expression)) { TestsController::shared().testFailed(__FILE__, __LINE__, #expression); return; } } while (0)\n',
       
  3071             'Extra space after ( in if  [whitespace/parens] [5]')
       
  3072         # FIXME: currently we only check first conditional, so we cannot detect errors in next ones.
       
  3073         # self.assert_multi_line_lint(
       
  3074         #     '#define TEST_ASSERT(expression) do { if (!(expression)) { TestsController::shared().testFailed(__FILE__, __LINE__, #expression); return; } } while (0 )\n',
       
  3075         #     'Mismatching spaces inside () in if  [whitespace/parens] [5]')
       
  3076         self.assert_multi_line_lint(
       
  3077             'if (condition) {\n'
       
  3078             '    doSomething();\n'
       
  3079             '    doSomethingAgain();\n'
       
  3080             '}\n'
       
  3081             'else {\n'
       
  3082             '    doSomethingElse();\n'
       
  3083             '    doSomethingElseAgain();\n'
       
  3084             '}\n',
       
  3085             'An else should appear on the same line as the preceding }  [whitespace/newline] [4]')
       
  3086         self.assert_multi_line_lint(
       
  3087             'if (condition) doSomething(); else doSomethingElse();\n',
       
  3088             ['More than one command on the same line  [whitespace/newline] [4]',
       
  3089              'Else clause should never be on same line as else (use 2 lines)  [whitespace/newline] [4]',
       
  3090              'More than one command on the same line in if  [whitespace/parens] [4]'])
       
  3091         self.assert_multi_line_lint(
       
  3092             'if (condition) doSomething(); else {\n'
       
  3093             '    doSomethingElse();\n'
       
  3094             '}\n',
       
  3095             ['More than one command on the same line in if  [whitespace/parens] [4]',
       
  3096              'One line control clauses should not use braces.  [whitespace/braces] [4]'])
       
  3097         self.assert_multi_line_lint(
       
  3098             'void func()\n'
       
  3099             '{\n'
       
  3100             '    while (condition) { }\n'
       
  3101             '    return 0;\n'
       
  3102             '}\n',
       
  3103             '')
       
  3104         self.assert_multi_line_lint(
       
  3105             'void func()\n'
       
  3106             '{\n'
       
  3107             '    for (i = 0; i < 42; i++) { foobar(); }\n'
       
  3108             '    return 0;\n'
       
  3109             '}\n',
       
  3110             'More than one command on the same line in for  [whitespace/parens] [4]')
       
  3111 
       
  3112         # 3. An else if statement should be written as an if statement
       
  3113         #    when the prior if concludes with a return statement.
       
  3114         self.assert_multi_line_lint(
       
  3115             'if (motivated) {\n'
       
  3116             '    if (liquid)\n'
       
  3117             '        return money;\n'
       
  3118             '} else if (tired)\n'
       
  3119             '    break;\n',
       
  3120             '')
       
  3121         self.assert_multi_line_lint(
       
  3122             'if (condition)\n'
       
  3123             '    doSomething();\n'
       
  3124             'else if (otherCondition)\n'
       
  3125             '    doSomethingElse();\n',
       
  3126             '')
       
  3127         self.assert_multi_line_lint(
       
  3128             'if (condition)\n'
       
  3129             '    doSomething();\n'
       
  3130             'else\n'
       
  3131             '    doSomethingElse();\n',
       
  3132             '')
       
  3133         self.assert_multi_line_lint(
       
  3134             'if (condition)\n'
       
  3135             '    returnValue = foo;\n'
       
  3136             'else if (otherCondition)\n'
       
  3137             '    returnValue = bar;\n',
       
  3138             '')
       
  3139         self.assert_multi_line_lint(
       
  3140             'if (condition)\n'
       
  3141             '    returnValue = foo;\n'
       
  3142             'else\n'
       
  3143             '    returnValue = bar;\n',
       
  3144             '')
       
  3145         self.assert_multi_line_lint(
       
  3146             'if (condition)\n'
       
  3147             '    doSomething();\n'
       
  3148             'else if (liquid)\n'
       
  3149             '    return money;\n'
       
  3150             'else if (broke)\n'
       
  3151             '    return favor;\n'
       
  3152             'else\n'
       
  3153             '    sleep(28800);\n',
       
  3154             '')
       
  3155         self.assert_multi_line_lint(
       
  3156             'if (liquid) {\n'
       
  3157             '    prepare();\n'
       
  3158             '    return money;\n'
       
  3159             '} else if (greedy) {\n'
       
  3160             '    keep();\n'
       
  3161             '    return nothing;\n'
       
  3162             '}\n',
       
  3163             'An else if statement should be written as an if statement when the '
       
  3164             'prior "if" concludes with a return, break, continue or goto statement.'
       
  3165             '  [readability/control_flow] [4]')
       
  3166         self.assert_multi_line_lint(
       
  3167             '    if (stupid) {\n'
       
  3168             'infiniteLoop:\n'
       
  3169             '        goto infiniteLoop;\n'
       
  3170             '    } else if (evil)\n'
       
  3171             '        goto hell;\n',
       
  3172             'An else if statement should be written as an if statement when the '
       
  3173             'prior "if" concludes with a return, break, continue or goto statement.'
       
  3174             '  [readability/control_flow] [4]')
       
  3175         self.assert_multi_line_lint(
       
  3176             'if (liquid)\n'
       
  3177             '{\n'
       
  3178             '    prepare();\n'
       
  3179             '    return money;\n'
       
  3180             '}\n'
       
  3181             'else if (greedy)\n'
       
  3182             '    keep();\n',
       
  3183             ['This { should be at the end of the previous line  [whitespace/braces] [4]',
       
  3184             'An else should appear on the same line as the preceding }  [whitespace/newline] [4]',
       
  3185             'An else if statement should be written as an if statement when the '
       
  3186             'prior "if" concludes with a return, break, continue or goto statement.'
       
  3187             '  [readability/control_flow] [4]'])
       
  3188         self.assert_multi_line_lint(
       
  3189             'if (gone)\n'
       
  3190             '    return;\n'
       
  3191             'else if (here)\n'
       
  3192             '    go();\n',
       
  3193             'An else if statement should be written as an if statement when the '
       
  3194             'prior "if" concludes with a return, break, continue or goto statement.'
       
  3195             '  [readability/control_flow] [4]')
       
  3196         self.assert_multi_line_lint(
       
  3197             'if (gone)\n'
       
  3198             '    return;\n'
       
  3199             'else\n'
       
  3200             '    go();\n',
       
  3201             'An else statement can be removed when the prior "if" concludes '
       
  3202             'with a return, break, continue or goto statement.'
       
  3203             '  [readability/control_flow] [4]')
       
  3204         self.assert_multi_line_lint(
       
  3205             'if (motivated) {\n'
       
  3206             '    prepare();\n'
       
  3207             '    continue;\n'
       
  3208             '} else {\n'
       
  3209             '    cleanUp();\n'
       
  3210             '    break;\n'
       
  3211             '}\n',
       
  3212             'An else statement can be removed when the prior "if" concludes '
       
  3213             'with a return, break, continue or goto statement.'
       
  3214             '  [readability/control_flow] [4]')
       
  3215         self.assert_multi_line_lint(
       
  3216             'if (tired)\n'
       
  3217             '    break;\n'
       
  3218             'else {\n'
       
  3219             '    prepare();\n'
       
  3220             '    continue;\n'
       
  3221             '}\n',
       
  3222             'An else statement can be removed when the prior "if" concludes '
       
  3223             'with a return, break, continue or goto statement.'
       
  3224             '  [readability/control_flow] [4]')
       
  3225 
       
  3226     def test_braces(self):
       
  3227         # 1. Function definitions: place each brace on its own line.
       
  3228         self.assert_multi_line_lint(
       
  3229             'int main()\n'
       
  3230             '{\n'
       
  3231             '    doSomething();\n'
       
  3232             '}\n',
       
  3233             '')
       
  3234         self.assert_multi_line_lint(
       
  3235             'int main() {\n'
       
  3236             '    doSomething();\n'
       
  3237             '}\n',
       
  3238             'Place brace on its own line for function definitions.  [whitespace/braces] [4]')
       
  3239 
       
  3240         # 2. Other braces: place the open brace on the line preceding the
       
  3241         #    code block; place the close brace on its own line.
       
  3242         self.assert_multi_line_lint(
       
  3243             'class MyClass {\n'
       
  3244             '    int foo;\n'
       
  3245             '};\n',
       
  3246             '')
       
  3247         self.assert_multi_line_lint(
       
  3248             'namespace WebCore {\n'
       
  3249             'int foo;\n'
       
  3250             '};\n',
       
  3251             '')
       
  3252         self.assert_multi_line_lint(
       
  3253             'for (int i = 0; i < 10; i++) {\n'
       
  3254             '    DoSomething();\n'
       
  3255             '};\n',
       
  3256             '')
       
  3257         self.assert_multi_line_lint(
       
  3258             'class MyClass\n'
       
  3259             '{\n'
       
  3260             '    int foo;\n'
       
  3261             '};\n',
       
  3262             'This { should be at the end of the previous line  [whitespace/braces] [4]')
       
  3263         self.assert_multi_line_lint(
       
  3264             'if (condition)\n'
       
  3265             '{\n'
       
  3266             '    int foo;\n'
       
  3267             '}\n',
       
  3268             'This { should be at the end of the previous line  [whitespace/braces] [4]')
       
  3269         self.assert_multi_line_lint(
       
  3270             'for (int i = 0; i < 10; i++)\n'
       
  3271             '{\n'
       
  3272             '    int foo;\n'
       
  3273             '}\n',
       
  3274             'This { should be at the end of the previous line  [whitespace/braces] [4]')
       
  3275         self.assert_multi_line_lint(
       
  3276             'while (true)\n'
       
  3277             '{\n'
       
  3278             '    int foo;\n'
       
  3279             '}\n',
       
  3280             'This { should be at the end of the previous line  [whitespace/braces] [4]')
       
  3281         self.assert_multi_line_lint(
       
  3282             'foreach (Foo* foo, foos)\n'
       
  3283             '{\n'
       
  3284             '    int bar;\n'
       
  3285             '}\n',
       
  3286             'This { should be at the end of the previous line  [whitespace/braces] [4]')
       
  3287         self.assert_multi_line_lint(
       
  3288             'switch (type)\n'
       
  3289             '{\n'
       
  3290             'case foo: return;\n'
       
  3291             '}\n',
       
  3292             'This { should be at the end of the previous line  [whitespace/braces] [4]')
       
  3293         self.assert_multi_line_lint(
       
  3294             'if (condition)\n'
       
  3295             '{\n'
       
  3296             '    int foo;\n'
       
  3297             '}\n',
       
  3298             'This { should be at the end of the previous line  [whitespace/braces] [4]')
       
  3299         self.assert_multi_line_lint(
       
  3300             'for (int i = 0; i < 10; i++)\n'
       
  3301             '{\n'
       
  3302             '    int foo;\n'
       
  3303             '}\n',
       
  3304             'This { should be at the end of the previous line  [whitespace/braces] [4]')
       
  3305         self.assert_multi_line_lint(
       
  3306             'while (true)\n'
       
  3307             '{\n'
       
  3308             '    int foo;\n'
       
  3309             '}\n',
       
  3310             'This { should be at the end of the previous line  [whitespace/braces] [4]')
       
  3311         self.assert_multi_line_lint(
       
  3312             'switch (type)\n'
       
  3313             '{\n'
       
  3314             'case foo: return;\n'
       
  3315             '}\n',
       
  3316             'This { should be at the end of the previous line  [whitespace/braces] [4]')
       
  3317         self.assert_multi_line_lint(
       
  3318             'else if (type)\n'
       
  3319             '{\n'
       
  3320             'case foo: return;\n'
       
  3321             '}\n',
       
  3322             'This { should be at the end of the previous line  [whitespace/braces] [4]')
       
  3323 
       
  3324         # 3. One-line control clauses should not use braces unless
       
  3325         #    comments are included or a single statement spans multiple
       
  3326         #    lines.
       
  3327         self.assert_multi_line_lint(
       
  3328             'if (true) {\n'
       
  3329             '    int foo;\n'
       
  3330             '}\n',
       
  3331             'One line control clauses should not use braces.  [whitespace/braces] [4]')
       
  3332 
       
  3333         self.assert_multi_line_lint(
       
  3334             'for (; foo; bar) {\n'
       
  3335             '    int foo;\n'
       
  3336             '}\n',
       
  3337             'One line control clauses should not use braces.  [whitespace/braces] [4]')
       
  3338 
       
  3339         self.assert_multi_line_lint(
       
  3340             'foreach (foo, foos) {\n'
       
  3341             '    int bar;\n'
       
  3342             '}\n',
       
  3343             'One line control clauses should not use braces.  [whitespace/braces] [4]')
       
  3344 
       
  3345         self.assert_multi_line_lint(
       
  3346             'while (true) {\n'
       
  3347             '    int foo;\n'
       
  3348             '}\n',
       
  3349             'One line control clauses should not use braces.  [whitespace/braces] [4]')
       
  3350 
       
  3351         self.assert_multi_line_lint(
       
  3352             'if (true)\n'
       
  3353             '    int foo;\n'
       
  3354             'else {\n'
       
  3355             '    int foo;\n'
       
  3356             '}\n',
       
  3357             'One line control clauses should not use braces.  [whitespace/braces] [4]')
       
  3358 
       
  3359         self.assert_multi_line_lint(
       
  3360             'if (true) {\n'
       
  3361             '    int foo;\n'
       
  3362             '} else\n'
       
  3363             '    int foo;\n',
       
  3364             'One line control clauses should not use braces.  [whitespace/braces] [4]')
       
  3365 
       
  3366         self.assert_multi_line_lint(
       
  3367             'if (true) {\n'
       
  3368             '    // Some comment\n'
       
  3369             '    int foo;\n'
       
  3370             '}\n',
       
  3371             '')
       
  3372 
       
  3373         self.assert_multi_line_lint(
       
  3374             'if (true) {\n'
       
  3375             '    myFunction(reallyLongParam1, reallyLongParam2,\n'
       
  3376             '               reallyLongParam3);\n'
       
  3377             '}\n',
       
  3378             '')
       
  3379 
       
  3380         # 4. Control clauses without a body should use empty braces.
       
  3381         self.assert_multi_line_lint(
       
  3382             'for ( ; current; current = current->next) { }\n',
       
  3383             '')
       
  3384         self.assert_multi_line_lint(
       
  3385             'for ( ; current;\n'
       
  3386             '     current = current->next) {}\n',
       
  3387             '')
       
  3388         self.assert_multi_line_lint(
       
  3389             'for ( ; current; current = current->next);\n',
       
  3390             'Semicolon defining empty statement for this loop. Use { } instead.  [whitespace/semicolon] [5]')
       
  3391         self.assert_multi_line_lint(
       
  3392             'while (true);\n',
       
  3393             'Semicolon defining empty statement for this loop. Use { } instead.  [whitespace/semicolon] [5]')
       
  3394         self.assert_multi_line_lint(
       
  3395             '} while (true);\n',
       
  3396             '')
       
  3397 
       
  3398     def test_null_false_zero(self):
       
  3399         # 1. In C++, the null pointer value should be written as 0. In C,
       
  3400         #    it should be written as NULL. In Objective-C and Objective-C++,
       
  3401         #    follow the guideline for C or C++, respectively, but use nil to
       
  3402         #    represent a null Objective-C object.
       
  3403         self.assert_lint(
       
  3404             'functionCall(NULL)',
       
  3405             'Use 0 instead of NULL.'
       
  3406             '  [readability/null] [5]',
       
  3407             'foo.cpp')
       
  3408         self.assert_lint(
       
  3409             "// Don't use NULL in comments since it isn't in code.",
       
  3410             'Use 0 instead of NULL.'
       
  3411             '  [readability/null] [4]',
       
  3412             'foo.cpp')
       
  3413         self.assert_lint(
       
  3414             '"A string with NULL" // and a comment with NULL is tricky to flag correctly in cpp_style.',
       
  3415             'Use 0 instead of NULL.'
       
  3416             '  [readability/null] [4]',
       
  3417             'foo.cpp')
       
  3418         self.assert_lint(
       
  3419             '"A string containing NULL is ok"',
       
  3420             '',
       
  3421             'foo.cpp')
       
  3422         self.assert_lint(
       
  3423             'if (aboutNULL)',
       
  3424             '',
       
  3425             'foo.cpp')
       
  3426         self.assert_lint(
       
  3427             'myVariable = NULLify',
       
  3428             '',
       
  3429             'foo.cpp')
       
  3430         # Make sure that the NULL check does not apply to C and Objective-C files.
       
  3431         self.assert_lint(
       
  3432             'functionCall(NULL)',
       
  3433             '',
       
  3434             'foo.c')
       
  3435         self.assert_lint(
       
  3436             'functionCall(NULL)',
       
  3437             '',
       
  3438             'foo.m')
       
  3439 
       
  3440         # Make sure that the NULL check does not apply to g_object_{set,get} and
       
  3441         # g_str{join,concat}
       
  3442         self.assert_lint(
       
  3443             'g_object_get(foo, "prop", &bar, NULL);',
       
  3444             '')
       
  3445         self.assert_lint(
       
  3446             'g_object_set(foo, "prop", bar, NULL);',
       
  3447             '')
       
  3448         self.assert_lint(
       
  3449             'g_build_filename(foo, bar, NULL);',
       
  3450             '')
       
  3451         self.assert_lint(
       
  3452             'gst_bin_add_many(foo, bar, boo, NULL);',
       
  3453             '')
       
  3454         self.assert_lint(
       
  3455             'gst_bin_remove_many(foo, bar, boo, NULL);',
       
  3456             '')
       
  3457         self.assert_lint(
       
  3458             'gst_element_link_many(foo, bar, boo, NULL);',
       
  3459             '')
       
  3460         self.assert_lint(
       
  3461             'gst_element_unlink_many(foo, bar, boo, NULL);',
       
  3462             '')
       
  3463         self.assert_lint(
       
  3464             'gchar* result = g_strconcat("part1", "part2", "part3", NULL);',
       
  3465             '')
       
  3466         self.assert_lint(
       
  3467             'gchar* result = g_strconcat("part1", NULL);',
       
  3468             '')
       
  3469         self.assert_lint(
       
  3470             'gchar* result = g_strjoin(",", "part1", "part2", "part3", NULL);',
       
  3471             '')
       
  3472         self.assert_lint(
       
  3473             'gchar* result = g_strjoin(",", "part1", NULL);',
       
  3474             '')
       
  3475 
       
  3476         # 2. C++ and C bool values should be written as true and
       
  3477         #    false. Objective-C BOOL values should be written as YES and NO.
       
  3478         # FIXME: Implement this.
       
  3479 
       
  3480         # 3. Tests for true/false, null/non-null, and zero/non-zero should
       
  3481         #    all be done without equality comparisons.
       
  3482         self.assert_lint(
       
  3483             'if (count == 0)',
       
  3484             'Tests for true/false, null/non-null, and zero/non-zero should all be done without equality comparisons.'
       
  3485             '  [readability/comparison_to_zero] [5]')
       
  3486         self.assert_lint_one_of_many_errors_re(
       
  3487             'if (string != NULL)',
       
  3488             r'Tests for true/false, null/non-null, and zero/non-zero should all be done without equality comparisons\.')
       
  3489         self.assert_lint(
       
  3490             'if (condition == true)',
       
  3491             'Tests for true/false, null/non-null, and zero/non-zero should all be done without equality comparisons.'
       
  3492             '  [readability/comparison_to_zero] [5]')
       
  3493         self.assert_lint(
       
  3494             'if (myVariable != /* Why would anyone put a comment here? */ false)',
       
  3495             'Tests for true/false, null/non-null, and zero/non-zero should all be done without equality comparisons.'
       
  3496             '  [readability/comparison_to_zero] [5]')
       
  3497 
       
  3498         self.assert_lint(
       
  3499             'if (0 /* This comment also looks odd to me. */ != aLongerVariableName)',
       
  3500             'Tests for true/false, null/non-null, and zero/non-zero should all be done without equality comparisons.'
       
  3501             '  [readability/comparison_to_zero] [5]')
       
  3502         self.assert_lint_one_of_many_errors_re(
       
  3503             'if (NULL == thisMayBeNull)',
       
  3504             r'Tests for true/false, null/non-null, and zero/non-zero should all be done without equality comparisons\.')
       
  3505         self.assert_lint(
       
  3506             'if (true != anotherCondition)',
       
  3507             'Tests for true/false, null/non-null, and zero/non-zero should all be done without equality comparisons.'
       
  3508             '  [readability/comparison_to_zero] [5]')
       
  3509         self.assert_lint(
       
  3510             'if (false == myBoolValue)',
       
  3511             'Tests for true/false, null/non-null, and zero/non-zero should all be done without equality comparisons.'
       
  3512             '  [readability/comparison_to_zero] [5]')
       
  3513 
       
  3514         self.assert_lint(
       
  3515             'if (fontType == trueType)',
       
  3516             '')
       
  3517         self.assert_lint(
       
  3518             'if (othertrue == fontType)',
       
  3519             '')
       
  3520 
       
  3521     def test_using_std(self):
       
  3522         self.assert_lint(
       
  3523             'using std::min;',
       
  3524             "Use 'using namespace std;' instead of 'using std::min;'."
       
  3525             "  [build/using_std] [4]",
       
  3526             'foo.cpp')
       
  3527 
       
  3528     def test_max_macro(self):
       
  3529         self.assert_lint(
       
  3530             'int i = MAX(0, 1);',
       
  3531             '',
       
  3532             'foo.c')
       
  3533 
       
  3534         self.assert_lint(
       
  3535             'int i = MAX(0, 1);',
       
  3536             'Use std::max() or std::max<type>() instead of the MAX() macro.'
       
  3537             '  [runtime/max_min_macros] [4]',
       
  3538             'foo.cpp')
       
  3539 
       
  3540         self.assert_lint(
       
  3541             'inline int foo() { return MAX(0, 1); }',
       
  3542             'Use std::max() or std::max<type>() instead of the MAX() macro.'
       
  3543             '  [runtime/max_min_macros] [4]',
       
  3544             'foo.h')
       
  3545 
       
  3546     def test_min_macro(self):
       
  3547         self.assert_lint(
       
  3548             'int i = MIN(0, 1);',
       
  3549             '',
       
  3550             'foo.c')
       
  3551 
       
  3552         self.assert_lint(
       
  3553             'int i = MIN(0, 1);',
       
  3554             'Use std::min() or std::min<type>() instead of the MIN() macro.'
       
  3555             '  [runtime/max_min_macros] [4]',
       
  3556             'foo.cpp')
       
  3557 
       
  3558         self.assert_lint(
       
  3559             'inline int foo() { return MIN(0, 1); }',
       
  3560             'Use std::min() or std::min<type>() instead of the MIN() macro.'
       
  3561             '  [runtime/max_min_macros] [4]',
       
  3562             'foo.h')
       
  3563 
       
  3564     def test_names(self):
       
  3565         name_underscore_error_message = " is incorrectly named. Don't use underscores in your identifier names.  [readability/naming] [4]"
       
  3566         name_tooshort_error_message = " is incorrectly named. Don't use the single letter 'l' as an identifier name.  [readability/naming] [4]"
       
  3567 
       
  3568         # Basic cases from WebKit style guide.
       
  3569         self.assert_lint('struct Data;', '')
       
  3570         self.assert_lint('size_t bufferSize;', '')
       
  3571         self.assert_lint('class HTMLDocument;', '')
       
  3572         self.assert_lint('String mimeType();', '')
       
  3573         self.assert_lint('size_t buffer_size;',
       
  3574                          'buffer_size' + name_underscore_error_message)
       
  3575         self.assert_lint('short m_length;', '')
       
  3576         self.assert_lint('short _length;',
       
  3577                          '_length' + name_underscore_error_message)
       
  3578         self.assert_lint('short length_;',
       
  3579                          'length_' + name_underscore_error_message)
       
  3580         self.assert_lint('unsigned _length;',
       
  3581                          '_length' + name_underscore_error_message)
       
  3582         self.assert_lint('unsigned int _length;',
       
  3583                          '_length' + name_underscore_error_message)
       
  3584         self.assert_lint('unsigned long long _length;',
       
  3585                          '_length' + name_underscore_error_message)
       
  3586 
       
  3587         # Variable name 'l' is easy to confuse with '1'
       
  3588         self.assert_lint('int l;', 'l' + name_tooshort_error_message)
       
  3589         self.assert_lint('size_t l;', 'l' + name_tooshort_error_message)
       
  3590         self.assert_lint('long long l;', 'l' + name_tooshort_error_message)
       
  3591 
       
  3592         # Pointers, references, functions, templates, and adjectives.
       
  3593         self.assert_lint('char* under_score;',
       
  3594                          'under_score' + name_underscore_error_message)
       
  3595         self.assert_lint('const int UNDER_SCORE;',
       
  3596                          'UNDER_SCORE' + name_underscore_error_message)
       
  3597         self.assert_lint('static inline const char const& const under_score;',
       
  3598                          'under_score' + name_underscore_error_message)
       
  3599         self.assert_lint('WebCore::RenderObject* under_score;',
       
  3600                          'under_score' + name_underscore_error_message)
       
  3601         self.assert_lint('int func_name();',
       
  3602                          'func_name' + name_underscore_error_message)
       
  3603         self.assert_lint('RefPtr<RenderObject*> under_score;',
       
  3604                          'under_score' + name_underscore_error_message)
       
  3605         self.assert_lint('WTF::Vector<WTF::RefPtr<const RenderObject* const> > under_score;',
       
  3606                          'under_score' + name_underscore_error_message)
       
  3607         self.assert_lint('int under_score[];',
       
  3608                          'under_score' + name_underscore_error_message)
       
  3609         self.assert_lint('struct dirent* under_score;',
       
  3610                          'under_score' + name_underscore_error_message)
       
  3611         self.assert_lint('long under_score;',
       
  3612                          'under_score' + name_underscore_error_message)
       
  3613         self.assert_lint('long long under_score;',
       
  3614                          'under_score' + name_underscore_error_message)
       
  3615         self.assert_lint('long double under_score;',
       
  3616                          'under_score' + name_underscore_error_message)
       
  3617         self.assert_lint('long long int under_score;',
       
  3618                          'under_score' + name_underscore_error_message)
       
  3619 
       
  3620         # Declarations in control statement.
       
  3621         self.assert_lint('if (int under_score = 42) {',
       
  3622                          'under_score' + name_underscore_error_message)
       
  3623         self.assert_lint('else if (int under_score = 42) {',
       
  3624                          'under_score' + name_underscore_error_message)
       
  3625         self.assert_lint('for (int under_score = 42; cond; i++) {',
       
  3626                          'under_score' + name_underscore_error_message)
       
  3627         self.assert_lint('while (foo & under_score = bar) {',
       
  3628                          'under_score' + name_underscore_error_message)
       
  3629         self.assert_lint('for (foo * under_score = p; cond; i++) {',
       
  3630                          'under_score' + name_underscore_error_message)
       
  3631         self.assert_lint('for (foo * under_score; cond; i++) {',
       
  3632                          'under_score' + name_underscore_error_message)
       
  3633         self.assert_lint('while (foo & value_in_thirdparty_library) {', '')
       
  3634         self.assert_lint('while (foo * value_in_thirdparty_library) {', '')
       
  3635         self.assert_lint('if (mli && S_OK == mli->foo()) {', '')
       
  3636 
       
  3637         # More member variables and functions.
       
  3638         self.assert_lint('int SomeClass::s_validName', '')
       
  3639         self.assert_lint('int m_under_score;',
       
  3640                          'm_under_score' + name_underscore_error_message)
       
  3641         self.assert_lint('int SomeClass::s_under_score = 0;',
       
  3642                          'SomeClass::s_under_score' + name_underscore_error_message)
       
  3643         self.assert_lint('int SomeClass::under_score = 0;',
       
  3644                          'SomeClass::under_score' + name_underscore_error_message)
       
  3645 
       
  3646         # Other statements.
       
  3647         self.assert_lint('return INT_MAX;', '')
       
  3648         self.assert_lint('return_t under_score;',
       
  3649                          'under_score' + name_underscore_error_message)
       
  3650         self.assert_lint('goto under_score;',
       
  3651                          'under_score' + name_underscore_error_message)
       
  3652         self.assert_lint('delete static_cast<Foo*>(p);', '')
       
  3653 
       
  3654         # Multiple variables in one line.
       
  3655         self.assert_lint('void myFunction(int variable1, int another_variable);',
       
  3656                          'another_variable' + name_underscore_error_message)
       
  3657         self.assert_lint('int variable1, another_variable;',
       
  3658                          'another_variable' + name_underscore_error_message)
       
  3659         self.assert_lint('int first_variable, secondVariable;',
       
  3660                          'first_variable' + name_underscore_error_message)
       
  3661         self.assert_lint('void my_function(int variable_1, int variable_2);',
       
  3662                          ['my_function' + name_underscore_error_message,
       
  3663                           'variable_1' + name_underscore_error_message,
       
  3664                           'variable_2' + name_underscore_error_message])
       
  3665         self.assert_lint('for (int variable_1, variable_2;;) {',
       
  3666                          ['variable_1' + name_underscore_error_message,
       
  3667                           'variable_2' + name_underscore_error_message])
       
  3668 
       
  3669         # There is an exception for op code functions but only in the JavaScriptCore directory.
       
  3670         self.assert_lint('void this_op_code(int var1, int var2)', '', 'JavaScriptCore/foo.cpp')
       
  3671         self.assert_lint('void this_op_code(int var1, int var2)', 'this_op_code' + name_underscore_error_message)
       
  3672 
       
  3673         # GObject requires certain magical names in class declarations.
       
  3674         self.assert_lint('void webkit_dom_object_init();', '')
       
  3675         self.assert_lint('void webkit_dom_object_class_init();', '')
       
  3676 
       
  3677         # There is an exception for some unit tests that begin with "tst_".
       
  3678         self.assert_lint('void tst_QWebFrame::arrayObjectEnumerable(int var1, int var2)', '')
       
  3679 
       
  3680         # The Qt API uses names that begin with "qt_".
       
  3681         self.assert_lint('void QTFrame::qt_drt_is_awesome(int var1, int var2)', '')
       
  3682         self.assert_lint('void qt_drt_is_awesome(int var1, int var2);', '')
       
  3683 
       
  3684         # const_iterator is allowed as well.
       
  3685         self.assert_lint('typedef VectorType::const_iterator const_iterator;', '')
       
  3686 
       
  3687         # Bitfields.
       
  3688         self.assert_lint('unsigned _fillRule : 1;',
       
  3689                          '_fillRule' + name_underscore_error_message)
       
  3690 
       
  3691 
       
  3692     def test_comments(self):
       
  3693         # A comment at the beginning of a line is ok.
       
  3694         self.assert_lint('// comment', '')
       
  3695         self.assert_lint('    // comment', '')
       
  3696 
       
  3697         self.assert_lint('}  // namespace WebCore',
       
  3698                          'One space before end of line comments'
       
  3699                          '  [whitespace/comments] [5]')
       
  3700 
       
  3701     def test_other(self):
       
  3702         # FIXME: Implement this.
       
  3703         pass
       
  3704 
       
  3705 
       
  3706 class CppCheckerTest(unittest.TestCase):
       
  3707 
       
  3708     """Tests CppChecker class."""
       
  3709 
       
  3710     def mock_handle_style_error(self):
       
  3711         pass
       
  3712 
       
  3713     def _checker(self):
       
  3714         return CppChecker("foo", "h", self.mock_handle_style_error, 3)
       
  3715 
       
  3716     def test_init(self):
       
  3717         """Test __init__ constructor."""
       
  3718         checker = self._checker()
       
  3719         self.assertEquals(checker.file_extension, "h")
       
  3720         self.assertEquals(checker.file_path, "foo")
       
  3721         self.assertEquals(checker.handle_style_error, self.mock_handle_style_error)
       
  3722         self.assertEquals(checker.min_confidence, 3)
       
  3723 
       
  3724     def test_eq(self):
       
  3725         """Test __eq__ equality function."""
       
  3726         checker1 = self._checker()
       
  3727         checker2 = self._checker()
       
  3728 
       
  3729         # == calls __eq__.
       
  3730         self.assertTrue(checker1 == checker2)
       
  3731 
       
  3732         def mock_handle_style_error2(self):
       
  3733             pass
       
  3734 
       
  3735         # Verify that a difference in any argument cause equality to fail.
       
  3736         checker = CppChecker("foo", "h", self.mock_handle_style_error, 3)
       
  3737         self.assertFalse(checker == CppChecker("bar", "h", self.mock_handle_style_error, 3))
       
  3738         self.assertFalse(checker == CppChecker("foo", "c", self.mock_handle_style_error, 3))
       
  3739         self.assertFalse(checker == CppChecker("foo", "h", mock_handle_style_error2, 3))
       
  3740         self.assertFalse(checker == CppChecker("foo", "h", self.mock_handle_style_error, 4))
       
  3741 
       
  3742     def test_ne(self):
       
  3743         """Test __ne__ inequality function."""
       
  3744         checker1 = self._checker()
       
  3745         checker2 = self._checker()
       
  3746 
       
  3747         # != calls __ne__.
       
  3748         # By default, __ne__ always returns true on different objects.
       
  3749         # Thus, just check the distinguishing case to verify that the
       
  3750         # code defines __ne__.
       
  3751         self.assertFalse(checker1 != checker2)
       
  3752 
       
  3753 
       
  3754 def tearDown():
       
  3755     """A global check to make sure all error-categories have been tested.
       
  3756 
       
  3757     The main tearDown() routine is the only code we can guarantee will be
       
  3758     run after all other tests have been executed.
       
  3759     """
       
  3760     try:
       
  3761         if _run_verifyallcategoriesseen:
       
  3762             ErrorCollector(None).verify_all_categories_are_seen()
       
  3763     except NameError:
       
  3764         # If nobody set the global _run_verifyallcategoriesseen, then
       
  3765         # we assume we shouldn't run the test
       
  3766         pass
       
  3767 
       
  3768 if __name__ == '__main__':
       
  3769     import sys
       
  3770     # We don't want to run the verify_all_categories_are_seen() test unless
       
  3771     # we're running the full test suite: if we only run one test,
       
  3772     # obviously we're not going to see all the error categories.  So we
       
  3773     # only run verify_all_categories_are_seen() when no commandline flags
       
  3774     # are passed in.
       
  3775     global _run_verifyallcategoriesseen
       
  3776     _run_verifyallcategoriesseen = (len(sys.argv) == 1)
       
  3777 
       
  3778     unittest.main()