xref: /aosp_15_r20/external/google-styleguide/cpplint/cpplint_unittest.py (revision 8c35d5ee8e2913d4bd6623e2b93232b1da0ab719)
1#!/usr/bin/python
2# -*- coding: utf-8; -*-
3#
4# Copyright (c) 2009 Google Inc. All rights reserved.
5#
6# Redistribution and use in source and binary forms, with or without
7# modification, are permitted provided that the following conditions are
8# met:
9#
10#    * Redistributions of source code must retain the above copyright
11# notice, this list of conditions and the following disclaimer.
12#    * Redistributions in binary form must reproduce the above
13# copyright notice, this list of conditions and the following disclaimer
14# in the documentation and/or other materials provided with the
15# distribution.
16#    * Neither the name of Google Inc. nor the names of its
17# contributors may be used to endorse or promote products derived from
18# this software without specific prior written permission.
19#
20# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
32"""Unit test for cpplint.py."""
33
34# TODO(unknown): Add a good test that tests UpdateIncludeState.
35
36import codecs
37import os
38import random
39import re
40import subprocess
41import sys
42import unittest
43
44import cpplint
45
46try:
47  xrange          # Python 2
48except NameError:
49  xrange = range  # Python 3
50
51
52# This class works as an error collector and replaces cpplint.Error
53# function for the unit tests.  We also verify each category we see
54# is in cpplint._ERROR_CATEGORIES, to help keep that list up to date.
55class ErrorCollector(object):
56  # These are a global list, covering all categories seen ever.
57  _ERROR_CATEGORIES = cpplint._ERROR_CATEGORIES
58  _SEEN_ERROR_CATEGORIES = {}
59
60  def __init__(self, assert_fn):
61    """assert_fn: a function to call when we notice a problem."""
62    self._assert_fn = assert_fn
63    self._errors = []
64    cpplint.ResetNolintSuppressions()
65
66  def __call__(self, unused_filename, linenum,
67               category, confidence, message):
68    self._assert_fn(category in self._ERROR_CATEGORIES,
69                    'Message "%s" has category "%s",'
70                    ' which is not in _ERROR_CATEGORIES' % (message, category))
71    self._SEEN_ERROR_CATEGORIES[category] = 1
72    if cpplint._ShouldPrintError(category, confidence, linenum):
73      self._errors.append('%s  [%s] [%d]' % (message, category, confidence))
74
75  def Results(self):
76    if len(self._errors) < 2:
77      return ''.join(self._errors)  # Most tests expect to have a string.
78    else:
79      return self._errors  # Let's give a list if there is more than one.
80
81  def ResultList(self):
82    return self._errors
83
84  def VerifyAllCategoriesAreSeen(self):
85    """Fails if there's a category in _ERROR_CATEGORIES~_SEEN_ERROR_CATEGORIES.
86
87    This should only be called after all tests are run, so
88    _SEEN_ERROR_CATEGORIES has had a chance to fully populate.  Since
89    this isn't called from within the normal unittest framework, we
90    can't use the normal unittest assert macros.  Instead we just exit
91    when we see an error.  Good thing this test is always run last!
92    """
93    for category in self._ERROR_CATEGORIES:
94      if category not in self._SEEN_ERROR_CATEGORIES:
95        sys.exit('FATAL ERROR: There are no tests for category "%s"' % category)
96
97  def RemoveIfPresent(self, substr):
98    for (index, error) in enumerate(self._errors):
99      if error.find(substr) != -1:
100        self._errors = self._errors[0:index] + self._errors[(index + 1):]
101        break
102
103
104# This class is a lame mock of codecs. We do not verify filename, mode, or
105# encoding, but for the current use case it is not needed.
106class MockIo(object):
107
108  def __init__(self, mock_file):
109    self.mock_file = mock_file
110
111  def open(self,  # pylint: disable-msg=C6409
112           unused_filename, unused_mode, unused_encoding, _):
113    return self.mock_file
114
115
116class CpplintTestBase(unittest.TestCase):
117  """Provides some useful helper functions for cpplint tests."""
118
119  def setUp(self):
120    # Allow subclasses to cheat os.path.abspath called in FileInfo class.
121    self.os_path_abspath_orig = os.path.abspath
122
123  def tearDown(self):
124    os.path.abspath = self.os_path_abspath_orig
125
126  # Perform lint on single line of input and return the error message.
127  def PerformSingleLineLint(self, code):
128    error_collector = ErrorCollector(self.assert_)
129    lines = code.split('\n')
130    cpplint.RemoveMultiLineComments('foo.h', lines, error_collector)
131    clean_lines = cpplint.CleansedLines(lines)
132    include_state = cpplint._IncludeState()
133    function_state = cpplint._FunctionState()
134    nesting_state = cpplint.NestingState()
135    cpplint.ProcessLine('foo.cc', 'cc', clean_lines, 0,
136                        include_state, function_state,
137                        nesting_state, error_collector)
138    # Single-line lint tests are allowed to fail the 'unlintable function'
139    # check.
140    error_collector.RemoveIfPresent(
141        'Lint failed to find start of function body.')
142    return error_collector.Results()
143
144  # Perform lint over multiple lines and return the error message.
145  def PerformMultiLineLint(self, code):
146    error_collector = ErrorCollector(self.assert_)
147    lines = code.split('\n')
148    cpplint.RemoveMultiLineComments('foo.h', lines, error_collector)
149    lines = cpplint.CleansedLines(lines)
150    nesting_state = cpplint.NestingState()
151    for i in xrange(lines.NumLines()):
152      nesting_state.Update('foo.h', lines, i, error_collector)
153      cpplint.CheckStyle('foo.h', lines, i, 'h', nesting_state,
154                         error_collector)
155      cpplint.CheckForNonStandardConstructs('foo.h', lines, i,
156                                            nesting_state, error_collector)
157    nesting_state.CheckCompletedBlocks('foo.h', error_collector)
158    return error_collector.Results()
159
160  # Similar to PerformMultiLineLint, but calls CheckLanguage instead of
161  # CheckForNonStandardConstructs
162  def PerformLanguageRulesCheck(self, file_name, code):
163    error_collector = ErrorCollector(self.assert_)
164    include_state = cpplint._IncludeState()
165    nesting_state = cpplint.NestingState()
166    lines = code.split('\n')
167    cpplint.RemoveMultiLineComments(file_name, lines, error_collector)
168    lines = cpplint.CleansedLines(lines)
169    ext = file_name[file_name.rfind('.') + 1:]
170    for i in xrange(lines.NumLines()):
171      cpplint.CheckLanguage(file_name, lines, i, ext, include_state,
172                            nesting_state, error_collector)
173    return error_collector.Results()
174
175  def PerformFunctionLengthsCheck(self, code):
176    """Perform Lint function length check on block of code and return warnings.
177
178    Builds up an array of lines corresponding to the code and strips comments
179    using cpplint functions.
180
181    Establishes an error collector and invokes the function length checking
182    function following cpplint's pattern.
183
184    Args:
185      code: C++ source code expected to generate a warning message.
186
187    Returns:
188      The accumulated errors.
189    """
190    file_name = 'foo.cc'
191    error_collector = ErrorCollector(self.assert_)
192    function_state = cpplint._FunctionState()
193    lines = code.split('\n')
194    cpplint.RemoveMultiLineComments(file_name, lines, error_collector)
195    lines = cpplint.CleansedLines(lines)
196    for i in xrange(lines.NumLines()):
197      cpplint.CheckForFunctionLengths(file_name, lines, i,
198                                      function_state, error_collector)
199    return error_collector.Results()
200
201  def PerformIncludeWhatYouUse(self, code, filename='foo.h', io=codecs):
202    # First, build up the include state.
203    error_collector = ErrorCollector(self.assert_)
204    include_state = cpplint._IncludeState()
205    nesting_state = cpplint.NestingState()
206    lines = code.split('\n')
207    cpplint.RemoveMultiLineComments(filename, lines, error_collector)
208    lines = cpplint.CleansedLines(lines)
209    for i in xrange(lines.NumLines()):
210      cpplint.CheckLanguage(filename, lines, i, '.h', include_state,
211                            nesting_state, error_collector)
212    # We could clear the error_collector here, but this should
213    # also be fine, since our IncludeWhatYouUse unittests do not
214    # have language problems.
215
216    # Second, look for missing includes.
217    cpplint.CheckForIncludeWhatYouUse(filename, lines, include_state,
218                                      error_collector, io)
219    return error_collector.Results()
220
221  # Perform lint and compare the error message with "expected_message".
222  def TestLint(self, code, expected_message):
223    self.assertEquals(expected_message, self.PerformSingleLineLint(code))
224
225  def TestMultiLineLint(self, code, expected_message):
226    self.assertEquals(expected_message, self.PerformMultiLineLint(code))
227
228  def TestMultiLineLintRE(self, code, expected_message_re):
229    message = self.PerformMultiLineLint(code)
230    if not re.search(expected_message_re, message):
231      self.fail('Message was:\n' + message + 'Expected match to "' +
232                expected_message_re + '"')
233
234  def TestLanguageRulesCheck(self, file_name, code, expected_message):
235    self.assertEquals(expected_message,
236                      self.PerformLanguageRulesCheck(file_name, code))
237
238  def TestIncludeWhatYouUse(self, code, expected_message):
239    self.assertEquals(expected_message,
240                      self.PerformIncludeWhatYouUse(code))
241
242  def TestBlankLinesCheck(self, lines, start_errors, end_errors):
243    error_collector = ErrorCollector(self.assert_)
244    cpplint.ProcessFileData('foo.cc', 'cc', lines, error_collector)
245    self.assertEquals(
246        start_errors,
247        error_collector.Results().count(
248            'Redundant blank line at the start of a code block '
249            'should be deleted.  [whitespace/blank_line] [2]'))
250    self.assertEquals(
251        end_errors,
252        error_collector.Results().count(
253            'Redundant blank line at the end of a code block '
254            'should be deleted.  [whitespace/blank_line] [3]'))
255
256
257class CpplintTest(CpplintTestBase):
258
259  def GetNamespaceResults(self, lines):
260    error_collector = ErrorCollector(self.assert_)
261    cpplint.RemoveMultiLineComments('foo.h', lines, error_collector)
262    lines = cpplint.CleansedLines(lines)
263    nesting_state = cpplint.NestingState()
264    for i in xrange(lines.NumLines()):
265      nesting_state.Update('foo.h', lines, i, error_collector)
266      cpplint.CheckForNamespaceIndentation('foo.h', nesting_state,
267                                           lines, i, error_collector)
268
269    return error_collector.Results()
270
271  def testForwardDeclarationNameSpaceIndentation(self):
272    lines = ['namespace Test {',
273             '  class ForwardDeclaration;',
274             '}  // namespace Test']
275
276    results = self.GetNamespaceResults(lines)
277    self.assertEquals(results, 'Do not indent within a namespace '
278                      ' [runtime/indentation_namespace] [4]')
279
280  def testNameSpaceIndentationForClass(self):
281    lines = ['namespace Test {',
282             'void foo() { }',
283             '  class Test {',
284             '  };',
285             '}  // namespace Test']
286
287    results = self.GetNamespaceResults(lines)
288    self.assertEquals(results, 'Do not indent within a namespace '
289                      ' [runtime/indentation_namespace] [4]')
290
291  def testNameSpaceIndentationNoError(self):
292    lines = ['namespace Test {',
293             'void foo() { }',
294             '}  // namespace Test']
295
296    results = self.GetNamespaceResults(lines)
297    self.assertEquals(results, '')
298
299  def testWhitespaceBeforeNamespace(self):
300    lines = ['  namespace Test {',
301             '  void foo() { }',
302             '  }  // namespace Test']
303
304    results = self.GetNamespaceResults(lines)
305    self.assertEquals(results, '')
306
307  def testFalsePositivesNoError(self):
308    lines = ['namespace Test {',
309             'struct OuterClass {',
310             '  struct NoFalsePositivesHere;',
311             '  struct NoFalsePositivesHere member_variable;',
312             '};',
313             '}  // namespace Test']
314
315    results = self.GetNamespaceResults(lines)
316    self.assertEquals(results, '')
317
318
319  # Test get line width.
320  def testGetLineWidth(self):
321    self.assertEquals(0, cpplint.GetLineWidth(''))
322    self.assertEquals(10, cpplint.GetLineWidth(u'x' * 10))
323    self.assertEquals(16, cpplint.GetLineWidth(u'都|道|府|県|支庁'))
324    self.assertEquals(5 + 13 + 9, cpplint.GetLineWidth(
325        u'd��/dt' + u'f : t ⨯ �� → ℝ' + u't ⨯ �� → ℝ'))
326
327  def testGetTextInside(self):
328    self.assertEquals('', cpplint._GetTextInside('fun()', r'fun\('))
329    self.assertEquals('x, y', cpplint._GetTextInside('f(x, y)', r'f\('))
330    self.assertEquals('a(), b(c())', cpplint._GetTextInside(
331        'printf(a(), b(c()))', r'printf\('))
332    self.assertEquals('x, y{}', cpplint._GetTextInside('f[x, y{}]', r'f\['))
333    self.assertEquals(None, cpplint._GetTextInside('f[a, b(}]', r'f\['))
334    self.assertEquals(None, cpplint._GetTextInside('f[x, y]', r'f\('))
335    self.assertEquals('y, h(z, (a + b))', cpplint._GetTextInside(
336        'f(x, g(y, h(z, (a + b))))', r'g\('))
337    self.assertEquals('f(f(x))', cpplint._GetTextInside('f(f(f(x)))', r'f\('))
338    # Supports multiple lines.
339    self.assertEquals('\n  return loop(x);\n',
340                      cpplint._GetTextInside(
341                          'int loop(int x) {\n  return loop(x);\n}\n', r'\{'))
342    # '^' matches the beginning of each line.
343    self.assertEquals('x, y',
344                      cpplint._GetTextInside(
345                          '#include "inl.h"  // skip #define\n'
346                          '#define A2(x, y) a_inl_(x, y, __LINE__)\n'
347                          '#define A(x) a_inl_(x, "", __LINE__)\n',
348                          r'^\s*#define\s*\w+\('))
349
350  def testFindNextMultiLineCommentStart(self):
351    self.assertEquals(1, cpplint.FindNextMultiLineCommentStart([''], 0))
352
353    lines = ['a', 'b', '/* c']
354    self.assertEquals(2, cpplint.FindNextMultiLineCommentStart(lines, 0))
355
356    lines = ['char a[] = "/*";']  # not recognized as comment.
357    self.assertEquals(1, cpplint.FindNextMultiLineCommentStart(lines, 0))
358
359  def testFindNextMultiLineCommentEnd(self):
360    self.assertEquals(1, cpplint.FindNextMultiLineCommentEnd([''], 0))
361    lines = ['a', 'b', ' c */']
362    self.assertEquals(2, cpplint.FindNextMultiLineCommentEnd(lines, 0))
363
364  def testRemoveMultiLineCommentsFromRange(self):
365    lines = ['a', '  /* comment ', ' * still comment', ' comment */   ', 'b']
366    cpplint.RemoveMultiLineCommentsFromRange(lines, 1, 4)
367    self.assertEquals(['a', '/**/', '/**/', '/**/', 'b'], lines)
368
369  def testSpacesAtEndOfLine(self):
370    self.TestLint(
371        '// Hello there ',
372        'Line ends in whitespace.  Consider deleting these extra spaces.'
373        '  [whitespace/end_of_line] [4]')
374
375  # Test line length check.
376  def testLineLengthCheck(self):
377    self.TestLint(
378        '// Hello',
379        '')
380    self.TestLint(
381        '// x' + ' x' * 40,
382        'Lines should be <= 80 characters long'
383        '  [whitespace/line_length] [2]')
384    self.TestLint(
385        '// x' + ' x' * 50,
386        'Lines should be <= 80 characters long'
387        '  [whitespace/line_length] [2]')
388    self.TestLint(
389        '// //some/path/to/f' + ('i' * 100) + 'le',
390        '')
391    self.TestLint(
392        '//   //some/path/to/f' + ('i' * 100) + 'le',
393        '')
394    self.TestLint(
395        '//   //some/path/to/f' + ('i' * 50) + 'le and some comments',
396        'Lines should be <= 80 characters long'
397        '  [whitespace/line_length] [2]')
398    self.TestLint(
399        '// http://g' + ('o' * 100) + 'gle.com/',
400        '')
401    self.TestLint(
402        '//   https://g' + ('o' * 100) + 'gle.com/',
403        '')
404    self.TestLint(
405        '//   https://g' + ('o' * 60) + 'gle.com/ and some comments',
406        'Lines should be <= 80 characters long'
407        '  [whitespace/line_length] [2]')
408    self.TestLint(
409        '// Read https://g' + ('o' * 60) + 'gle.com/',
410        '')
411    self.TestLint(
412        '// $Id: g' + ('o' * 80) + 'gle.cc#1 $',
413        '')
414    self.TestLint(
415        '// $Id: g' + ('o' * 80) + 'gle.cc#1',
416        'Lines should be <= 80 characters long'
417        '  [whitespace/line_length] [2]')
418    self.TestMultiLineLint(
419        'static const char kCStr[] = "g' + ('o' * 50) + 'gle";\n',
420        'Lines should be <= 80 characters long'
421        '  [whitespace/line_length] [2]')
422    self.TestMultiLineLint(
423        'static const char kRawStr[] = R"(g' + ('o' * 50) + 'gle)";\n',
424        '')  # no warning because raw string content is elided
425    self.TestMultiLineLint(
426        'static const char kMultiLineRawStr[] = R"(\n'
427        'g' + ('o' * 80) + 'gle\n'
428        ')";',
429        '')
430    self.TestMultiLineLint(
431        'static const char kL' + ('o' * 50) + 'ngIdentifier[] = R"()";\n',
432        'Lines should be <= 80 characters long'
433        '  [whitespace/line_length] [2]')
434
435  # Test error suppression annotations.
436  def testErrorSuppression(self):
437    # Two errors on same line:
438    self.TestLint(
439        'long a = (int64) 65;',
440        ['Using C-style cast.  Use static_cast<int64>(...) instead'
441         '  [readability/casting] [4]',
442         'Use int16/int64/etc, rather than the C type long'
443         '  [runtime/int] [4]',
444        ])
445    # One category of error suppressed:
446    self.TestLint(
447        'long a = (int64) 65;  // NOLINT(runtime/int)',
448        'Using C-style cast.  Use static_cast<int64>(...) instead'
449        '  [readability/casting] [4]')
450    # All categories suppressed: (two aliases)
451    self.TestLint('long a = (int64) 65;  // NOLINT', '')
452    self.TestLint('long a = (int64) 65;  // NOLINT(*)', '')
453    # Malformed NOLINT directive:
454    self.TestLint(
455        'long a = 65;  // NOLINT(foo)',
456        ['Unknown NOLINT error category: foo'
457         '  [readability/nolint] [5]',
458         'Use int16/int64/etc, rather than the C type long  [runtime/int] [4]',
459        ])
460    # Irrelevant NOLINT directive has no effect:
461    self.TestLint(
462        'long a = 65;  // NOLINT(readability/casting)',
463        'Use int16/int64/etc, rather than the C type long'
464        '  [runtime/int] [4]')
465    # NOLINTNEXTLINE silences warning for the next line instead of current line
466    error_collector = ErrorCollector(self.assert_)
467    cpplint.ProcessFileData('test.cc', 'cc',
468                            ['// Copyright 2014 Your Company.',
469                             '// NOLINTNEXTLINE(whitespace/line_length)',
470                             '//  ./command' + (' -verbose' * 80),
471                             ''],
472                            error_collector)
473    self.assertEquals('', error_collector.Results())
474    # LINT_C_FILE silences cast warnings for entire file.
475    error_collector = ErrorCollector(self.assert_)
476    cpplint.ProcessFileData('test.h', 'h',
477                            ['// Copyright 2014 Your Company.',
478                             '// NOLINT(build/header_guard)',
479                             'int64 a = (uint64) 65;',
480                             '//  LINT_C_FILE',
481                             ''],
482                            error_collector)
483    self.assertEquals('', error_collector.Results())
484    # Vim modes silence cast warnings for entire file.
485    for modeline in ['vi:filetype=c',
486                     'vi:sw=8 filetype=c',
487                     'vi:sw=8 filetype=c ts=8',
488                     'vi: filetype=c',
489                     'vi: sw=8 filetype=c',
490                     'vi: sw=8 filetype=c ts=8',
491                     'vim:filetype=c',
492                     'vim:sw=8 filetype=c',
493                     'vim:sw=8 filetype=c ts=8',
494                     'vim: filetype=c',
495                     'vim: sw=8 filetype=c',
496                     'vim: sw=8 filetype=c ts=8',
497                     'vim: set filetype=c:',
498                     'vim: set sw=8 filetype=c:',
499                     'vim: set sw=8 filetype=c ts=8:',
500                     'vim: set filetype=c :',
501                     'vim: set sw=8 filetype=c :',
502                     'vim: set sw=8 filetype=c ts=8 :',
503                     'vim: se filetype=c:',
504                     'vim: se sw=8 filetype=c:',
505                     'vim: se sw=8 filetype=c ts=8:',
506                     'vim: se filetype=c :',
507                     'vim: se sw=8 filetype=c :',
508                     'vim: se sw=8 filetype=c ts=8 :']:
509      error_collector = ErrorCollector(self.assert_)
510      cpplint.ProcessFileData('test.h', 'h',
511                              ['// Copyright 2014 Your Company.',
512                               '// NOLINT(build/header_guard)',
513                               'int64 a = (uint64) 65;',
514                               '/* Prevent warnings about the modeline',
515                               modeline,
516                               '*/',
517                               ''],
518                              error_collector)
519      self.assertEquals('', error_collector.Results())
520    # LINT_KERNEL_FILE silences whitespace/tab warnings for entire file.
521    error_collector = ErrorCollector(self.assert_)
522    cpplint.ProcessFileData('test.h', 'h',
523                            ['// Copyright 2014 Your Company.',
524                             '// NOLINT(build/header_guard)',
525                             'struct test {',
526                             '\tint member;',
527                             '};',
528                             '//  LINT_KERNEL_FILE',
529                             ''],
530                            error_collector)
531    self.assertEquals('', error_collector.Results())
532    # NOLINT, NOLINTNEXTLINE silences the readability/braces warning for "};".
533    error_collector = ErrorCollector(self.assert_)
534    cpplint.ProcessFileData('test.cc', 'cc',
535                            ['// Copyright 2014 Your Company.',
536                             'for (int i = 0; i != 100; ++i) {',
537                             '\tstd::cout << i << std::endl;',
538                             '};  // NOLINT',
539                             'for (int i = 0; i != 100; ++i) {',
540                             '\tstd::cout << i << std::endl;',
541                             '// NOLINTNEXTLINE',
542                             '};',
543                             '//  LINT_KERNEL_FILE',
544                             ''],
545                            error_collector)
546    self.assertEquals('', error_collector.Results())
547
548  # Test Variable Declarations.
549  def testVariableDeclarations(self):
550    self.TestLint(
551        'long a = 65;',
552        'Use int16/int64/etc, rather than the C type long'
553        '  [runtime/int] [4]')
554    self.TestLint(
555        'long double b = 65.0;',
556        '')
557    self.TestLint(
558        'long long aa = 6565;',
559        'Use int16/int64/etc, rather than the C type long'
560        '  [runtime/int] [4]')
561
562  # Test C-style cast cases.
563  def testCStyleCast(self):
564    self.TestLint(
565        'int a = (int)1.0;',
566        'Using C-style cast.  Use static_cast<int>(...) instead'
567        '  [readability/casting] [4]')
568    self.TestLint(
569        'int a = (int)-1.0;',
570        'Using C-style cast.  Use static_cast<int>(...) instead'
571        '  [readability/casting] [4]')
572    self.TestLint(
573        'int *a = (int *)NULL;',
574        'Using C-style cast.  Use reinterpret_cast<int *>(...) instead'
575        '  [readability/casting] [4]')
576
577    self.TestLint(
578        'uint16 a = (uint16)1.0;',
579        'Using C-style cast.  Use static_cast<uint16>(...) instead'
580        '  [readability/casting] [4]')
581    self.TestLint(
582        'int32 a = (int32)1.0;',
583        'Using C-style cast.  Use static_cast<int32>(...) instead'
584        '  [readability/casting] [4]')
585    self.TestLint(
586        'uint64 a = (uint64)1.0;',
587        'Using C-style cast.  Use static_cast<uint64>(...) instead'
588        '  [readability/casting] [4]')
589
590    # These shouldn't be recognized casts.
591    self.TestLint('u a = (u)NULL;', '')
592    self.TestLint('uint a = (uint)NULL;', '')
593    self.TestLint('typedef MockCallback<int(int)> CallbackType;', '')
594    self.TestLint('scoped_ptr< MockCallback<int(int)> > callback_value;', '')
595    self.TestLint('std::function<int(bool)>', '')
596    self.TestLint('x = sizeof(int)', '')
597    self.TestLint('x = alignof(int)', '')
598    self.TestLint('alignas(int) char x[42]', '')
599    self.TestLint('alignas(alignof(x)) char y[42]', '')
600    self.TestLint('void F(int (func)(int));', '')
601    self.TestLint('void F(int (func)(int*));', '')
602    self.TestLint('void F(int (Class::member)(int));', '')
603    self.TestLint('void F(int (Class::member)(int*));', '')
604    self.TestLint('void F(int (Class::member)(int), int param);', '')
605    self.TestLint('void F(int (Class::member)(int*), int param);', '')
606
607    # These should not be recognized (lambda functions without arg names).
608    self.TestLint('[](int/*unused*/) -> bool {', '')
609    self.TestLint('[](int /*unused*/) -> bool {', '')
610    self.TestLint('auto f = [](MyStruct* /*unused*/)->int {', '')
611    self.TestLint('[](int) -> bool {', '')
612    self.TestLint('auto f = [](MyStruct*)->int {', '')
613
614    # Cast with brace initializers
615    self.TestLint('int64_t{4096} * 1000 * 1000', '')
616    self.TestLint('size_t{4096} * 1000 * 1000', '')
617    self.TestLint('uint_fast16_t{4096} * 1000 * 1000', '')
618
619    # Brace initializer with templated type
620    self.TestMultiLineLint(
621        """
622        template <typename Type1,
623                  typename Type2>
624        void Function(int arg1,
625                      int arg2) {
626          variable &= ~Type1{0} - 1;
627        }""",
628        '')
629    self.TestMultiLineLint(
630        """
631        template <typename Type>
632        class Class {
633          void Function() {
634            variable &= ~Type{0} - 1;
635          }
636        };""",
637        '')
638    self.TestMultiLineLint(
639        """
640        template <typename Type>
641        class Class {
642          void Function() {
643            variable &= ~Type{0} - 1;
644          }
645        };""",
646        '')
647    self.TestMultiLineLint(
648        """
649        namespace {
650        template <typename Type>
651        class Class {
652          void Function() {
653            if (block) {
654              variable &= ~Type{0} - 1;
655            }
656          }
657        };
658        }""",
659        '')
660
661  # Test taking address of casts (runtime/casting)
662  def testRuntimeCasting(self):
663    error_msg = ('Are you taking an address of a cast?  '
664                 'This is dangerous: could be a temp var.  '
665                 'Take the address before doing the cast, rather than after'
666                 '  [runtime/casting] [4]')
667    self.TestLint('int* x = &static_cast<int*>(foo);', error_msg)
668    self.TestLint('int* x = &reinterpret_cast<int *>(foo);', error_msg)
669    self.TestLint('int* x = &(int*)foo;',
670                  ['Using C-style cast.  Use reinterpret_cast<int*>(...) '
671                   'instead  [readability/casting] [4]',
672                   error_msg])
673    self.TestLint('BudgetBuckets&(BudgetWinHistory::*BucketFn)(void) const;',
674                  '')
675    self.TestLint('&(*func_ptr)(arg)', '')
676    self.TestLint('Compute(arg, &(*func_ptr)(i, j));', '')
677
678    # Alternative error message
679    alt_error_msg = ('Are you taking an address of something dereferenced '
680                     'from a cast?  Wrapping the dereferenced expression in '
681                     'parentheses will make the binding more obvious'
682                     '  [readability/casting] [4]')
683    self.TestLint('int* x = &down_cast<Obj*>(obj)->member_;', alt_error_msg)
684    self.TestLint('int* x = &down_cast<Obj*>(obj)[index];', alt_error_msg)
685    self.TestLint('int* x = &(down_cast<Obj*>(obj)->member_);', '')
686    self.TestLint('int* x = &(down_cast<Obj*>(obj)[index]);', '')
687    self.TestLint('int* x = &down_cast<Obj*>(obj)\n->member_;', alt_error_msg)
688    self.TestLint('int* x = &(down_cast<Obj*>(obj)\n->member_);', '')
689
690    # It's OK to cast an address.
691    self.TestLint('int* x = reinterpret_cast<int *>(&foo);', '')
692
693    # Function pointers returning references should not be confused
694    # with taking address of old-style casts.
695    self.TestLint('auto x = implicit_cast<string &(*)(int)>(&foo);', '')
696
697  def testRuntimeSelfinit(self):
698    self.TestLint(
699        'Foo::Foo(Bar r, Bel l) : r_(r_), l_(l_) { }',
700        'You seem to be initializing a member variable with itself.'
701        '  [runtime/init] [4]')
702    self.TestLint(
703        'Foo::Foo(Bar r, Bel l) : r_(CHECK_NOTNULL(r_)) { }',
704        'You seem to be initializing a member variable with itself.'
705        '  [runtime/init] [4]')
706    self.TestLint(
707        'Foo::Foo(Bar r, Bel l) : r_(r), l_(l) { }',
708        '')
709    self.TestLint(
710        'Foo::Foo(Bar r) : r_(r), l_(r_), ll_(l_) { }',
711        '')
712
713  # Test for unnamed arguments in a method.
714  def testCheckForUnnamedParams(self):
715    self.TestLint('virtual void Func(int*) const;', '')
716    self.TestLint('virtual void Func(int*);', '')
717    self.TestLint('void Method(char*) {', '')
718    self.TestLint('void Method(char*);', '')
719    self.TestLint('static void operator delete[](void*) throw();', '')
720    self.TestLint('int Method(int);', '')
721
722    self.TestLint('virtual void Func(int* p);', '')
723    self.TestLint('void operator delete(void* x) throw();', '')
724    self.TestLint('void Method(char* x) {', '')
725    self.TestLint('void Method(char* /*x*/) {', '')
726    self.TestLint('void Method(char* x);', '')
727    self.TestLint('typedef void (*Method)(int32 x);', '')
728    self.TestLint('static void operator delete[](void* x) throw();', '')
729    self.TestLint('static void operator delete[](void* /*x*/) throw();', '')
730
731    self.TestLint('X operator++(int);', '')
732    self.TestLint('X operator++(int) {', '')
733    self.TestLint('X operator--(int);', '')
734    self.TestLint('X operator--(int /*unused*/) {', '')
735    self.TestLint('MACRO(int);', '')
736    self.TestLint('MACRO(func(int));', '')
737    self.TestLint('MACRO(arg, func(int));', '')
738
739    self.TestLint('void (*func)(void*);', '')
740    self.TestLint('void Func((*func)(void*)) {}', '')
741    self.TestLint('template <void Func(void*)> void func();', '')
742    self.TestLint('virtual void f(int /*unused*/) {', '')
743    self.TestLint('void f(int /*unused*/) override {', '')
744    self.TestLint('void f(int /*unused*/) final {', '')
745
746  # Test deprecated casts such as int(d)
747  def testDeprecatedCast(self):
748    self.TestLint(
749        'int a = int(2.2);',
750        'Using deprecated casting style.  '
751        'Use static_cast<int>(...) instead'
752        '  [readability/casting] [4]')
753
754    self.TestLint(
755        '(char *) "foo"',
756        'Using C-style cast.  '
757        'Use const_cast<char *>(...) instead'
758        '  [readability/casting] [4]')
759
760    self.TestLint(
761        '(int*)foo',
762        'Using C-style cast.  '
763        'Use reinterpret_cast<int*>(...) instead'
764        '  [readability/casting] [4]')
765
766    # Checks for false positives...
767    self.TestLint('int a = int();', '')  # constructor
768    self.TestLint('X::X() : a(int()) {}', '')  # default constructor
769    self.TestLint('operator bool();', '')  # Conversion operator
770    self.TestLint('new int64(123);', '')  # "new" operator on basic type
771    self.TestLint('new   int64(123);', '')  # "new" operator on basic type
772    self.TestLint('new const int(42);', '')  # "new" on const-qualified type
773    self.TestLint('using a = bool(int arg);', '')  # C++11 alias-declaration
774    self.TestLint('x = bit_cast<double(*)[3]>(y);', '')  # array of array
775    self.TestLint('void F(const char(&src)[N]);', '')  # array of references
776
777    # Placement new
778    self.TestLint(
779        'new(field_ptr) int(field->default_value_enum()->number());',
780        '')
781
782    # C++11 function wrappers
783    self.TestLint('std::function<int(bool)>', '')
784    self.TestLint('std::function<const int(bool)>', '')
785    self.TestLint('std::function< int(bool) >', '')
786    self.TestLint('mfunction<int(bool)>', '')
787
788    error_collector = ErrorCollector(self.assert_)
789    cpplint.ProcessFileData(
790        'test.cc', 'cc',
791        ['// Copyright 2014 Your Company. All Rights Reserved.',
792         'typedef std::function<',
793         '    bool(int)> F;',
794         ''],
795        error_collector)
796    self.assertEquals('', error_collector.Results())
797
798    # Return types for function pointers
799    self.TestLint('typedef bool(FunctionPointer)();', '')
800    self.TestLint('typedef bool(FunctionPointer)(int param);', '')
801    self.TestLint('typedef bool(MyClass::*MemberFunctionPointer)();', '')
802    self.TestLint('typedef bool(MyClass::* MemberFunctionPointer)();', '')
803    self.TestLint('typedef bool(MyClass::*MemberFunctionPointer)() const;', '')
804    self.TestLint('void Function(bool(FunctionPointerArg)());', '')
805    self.TestLint('void Function(bool(FunctionPointerArg)()) {}', '')
806    self.TestLint('typedef set<int64, bool(*)(int64, int64)> SortedIdSet', '')
807    self.TestLint(
808        'bool TraverseNode(T *Node, bool(VisitorBase:: *traverse) (T *t)) {}',
809        '')
810
811  # The second parameter to a gMock method definition is a function signature
812  # that often looks like a bad cast but should not picked up by lint.
813  def testMockMethod(self):
814    self.TestLint(
815        'MOCK_METHOD0(method, int());',
816        '')
817    self.TestLint(
818        'MOCK_CONST_METHOD1(method, float(string));',
819        '')
820    self.TestLint(
821        'MOCK_CONST_METHOD2_T(method, double(float, float));',
822        '')
823    self.TestLint(
824        'MOCK_CONST_METHOD1(method, SomeType(int));',
825        '')
826
827    error_collector = ErrorCollector(self.assert_)
828    cpplint.ProcessFileData('mock.cc', 'cc',
829                            ['MOCK_METHOD1(method1,',
830                             '             bool(int));',
831                             'MOCK_METHOD1(',
832                             '    method2,',
833                             '    bool(int));',
834                             'MOCK_CONST_METHOD2(',
835                             '    method3, bool(int,',
836                             '                  int));',
837                             'MOCK_METHOD1(method4, int(bool));',
838                             'const int kConstant = int(42);'],  # true positive
839                            error_collector)
840    self.assertEquals(
841        0,
842        error_collector.Results().count(
843            ('Using deprecated casting style.  '
844             'Use static_cast<bool>(...) instead  '
845             '[readability/casting] [4]')))
846    self.assertEquals(
847        1,
848        error_collector.Results().count(
849            ('Using deprecated casting style.  '
850             'Use static_cast<int>(...) instead  '
851             '[readability/casting] [4]')))
852
853  # Like gMock method definitions, MockCallback instantiations look very similar
854  # to bad casts.
855  def testMockCallback(self):
856    self.TestLint(
857        'MockCallback<bool(int)>',
858        '')
859    self.TestLint(
860        'MockCallback<int(float, char)>',
861        '')
862
863  # Test false errors that happened with some include file names
864  def testIncludeFilenameFalseError(self):
865    self.TestLint(
866        '#include "foo/long-foo.h"',
867        '')
868    self.TestLint(
869        '#include "foo/sprintf.h"',
870        '')
871
872  # Test typedef cases.  There was a bug that cpplint misidentified
873  # typedef for pointer to function as C-style cast and produced
874  # false-positive error messages.
875  def testTypedefForPointerToFunction(self):
876    self.TestLint(
877        'typedef void (*Func)(int x);',
878        '')
879    self.TestLint(
880        'typedef void (*Func)(int *x);',
881        '')
882    self.TestLint(
883        'typedef void Func(int x);',
884        '')
885    self.TestLint(
886        'typedef void Func(int *x);',
887        '')
888
889  def testIncludeWhatYouUseNoImplementationFiles(self):
890    code = 'std::vector<int> foo;'
891    self.assertEquals('Add #include <vector> for vector<>'
892                      '  [build/include_what_you_use] [4]',
893                      self.PerformIncludeWhatYouUse(code, 'foo.h'))
894    self.assertEquals('',
895                      self.PerformIncludeWhatYouUse(code, 'foo.cc'))
896
897  def testIncludeWhatYouUse(self):
898    self.TestIncludeWhatYouUse(
899        """#include <vector>
900           std::vector<int> foo;
901        """,
902        '')
903    self.TestIncludeWhatYouUse(
904        """#include <map>
905           std::pair<int,int> foo;
906        """,
907        'Add #include <utility> for pair<>'
908        '  [build/include_what_you_use] [4]')
909    self.TestIncludeWhatYouUse(
910        """#include <multimap>
911           std::pair<int,int> foo;
912        """,
913        'Add #include <utility> for pair<>'
914        '  [build/include_what_you_use] [4]')
915    self.TestIncludeWhatYouUse(
916        """#include <hash_map>
917           std::pair<int,int> foo;
918        """,
919        'Add #include <utility> for pair<>'
920        '  [build/include_what_you_use] [4]')
921    self.TestIncludeWhatYouUse(
922        """#include <hash_map>
923           auto foo = std::make_pair(1, 2);
924        """,
925        'Add #include <utility> for make_pair'
926        '  [build/include_what_you_use] [4]')
927    self.TestIncludeWhatYouUse(
928        """#include <utility>
929           std::pair<int,int> foo;
930        """,
931        '')
932    self.TestIncludeWhatYouUse(
933        """#include <vector>
934           DECLARE_string(foobar);
935        """,
936        '')
937    self.TestIncludeWhatYouUse(
938        """#include <vector>
939           DEFINE_string(foobar, "", "");
940        """,
941        '')
942    self.TestIncludeWhatYouUse(
943        """#include <vector>
944           std::pair<int,int> foo;
945        """,
946        'Add #include <utility> for pair<>'
947        '  [build/include_what_you_use] [4]')
948    self.TestIncludeWhatYouUse(
949        """#include "base/foobar.h"
950           std::vector<int> foo;
951        """,
952        'Add #include <vector> for vector<>'
953        '  [build/include_what_you_use] [4]')
954    self.TestIncludeWhatYouUse(
955        """#include <vector>
956           std::set<int> foo;
957        """,
958        'Add #include <set> for set<>'
959        '  [build/include_what_you_use] [4]')
960    self.TestIncludeWhatYouUse(
961        """#include "base/foobar.h"
962          hash_map<int, int> foobar;
963        """,
964        'Add #include <hash_map> for hash_map<>'
965        '  [build/include_what_you_use] [4]')
966    self.TestIncludeWhatYouUse(
967        """#include "base/containers/hash_tables.h"
968          base::hash_map<int, int> foobar;
969        """,
970        '')
971    self.TestIncludeWhatYouUse(
972        """#include "base/foobar.h"
973           bool foobar = std::less<int>(0,1);
974        """,
975        'Add #include <functional> for less<>'
976        '  [build/include_what_you_use] [4]')
977    self.TestIncludeWhatYouUse(
978        """#include "base/foobar.h"
979           bool foobar = min<int>(0,1);
980        """,
981        'Add #include <algorithm> for min  [build/include_what_you_use] [4]')
982    self.TestIncludeWhatYouUse(
983        'void a(const string &foobar);',
984        'Add #include <string> for string  [build/include_what_you_use] [4]')
985    self.TestIncludeWhatYouUse(
986        'void a(const std::string &foobar);',
987        'Add #include <string> for string  [build/include_what_you_use] [4]')
988    self.TestIncludeWhatYouUse(
989        'void a(const my::string &foobar);',
990        '')  # Avoid false positives on strings in other namespaces.
991    self.TestIncludeWhatYouUse(
992        """#include "base/foobar.h"
993           bool foobar = swap(0,1);
994        """,
995        'Add #include <utility> for swap  [build/include_what_you_use] [4]')
996    self.TestIncludeWhatYouUse(
997        """#include "base/foobar.h"
998           bool foobar = transform(a.begin(), a.end(), b.start(), Foo);
999        """,
1000        'Add #include <algorithm> for transform  '
1001        '[build/include_what_you_use] [4]')
1002    self.TestIncludeWhatYouUse(
1003        """#include "base/foobar.h"
1004           bool foobar = min_element(a.begin(), a.end());
1005        """,
1006        'Add #include <algorithm> for min_element  '
1007        '[build/include_what_you_use] [4]')
1008    self.TestIncludeWhatYouUse(
1009        """foo->swap(0,1);
1010           foo.swap(0,1);
1011        """,
1012        '')
1013    self.TestIncludeWhatYouUse(
1014        """#include <string>
1015           void a(const std::multimap<int,string> &foobar);
1016        """,
1017        'Add #include <map> for multimap<>'
1018        '  [build/include_what_you_use] [4]')
1019    self.TestIncludeWhatYouUse(
1020        """#include <string>
1021           void a(const std::unordered_map<int,string> &foobar);
1022        """,
1023        'Add #include <unordered_map> for unordered_map<>'
1024        '  [build/include_what_you_use] [4]')
1025    self.TestIncludeWhatYouUse(
1026        """#include <string>
1027           void a(const std::unordered_set<int> &foobar);
1028        """,
1029        'Add #include <unordered_set> for unordered_set<>'
1030        '  [build/include_what_you_use] [4]')
1031    self.TestIncludeWhatYouUse(
1032        """#include <queue>
1033           void a(const std::priority_queue<int> &foobar);
1034        """,
1035        '')
1036    self.TestIncludeWhatYouUse(
1037        """#include <assert.h>
1038           #include <string>
1039           #include <vector>
1040           #include "base/basictypes.h"
1041           #include "base/port.h"
1042           vector<string> hajoa;""", '')
1043    self.TestIncludeWhatYouUse(
1044        """#include <string>
1045           int i = numeric_limits<int>::max()
1046        """,
1047        'Add #include <limits> for numeric_limits<>'
1048        '  [build/include_what_you_use] [4]')
1049    self.TestIncludeWhatYouUse(
1050        """#include <limits>
1051           int i = numeric_limits<int>::max()
1052        """,
1053        '')
1054    self.TestIncludeWhatYouUse(
1055        """#include <string>
1056           std::unique_ptr<int> x;
1057        """,
1058        'Add #include <memory> for unique_ptr<>'
1059        '  [build/include_what_you_use] [4]')
1060    self.TestIncludeWhatYouUse(
1061        """#include <string>
1062           auto x = std::make_unique<int>(0);
1063        """,
1064        'Add #include <memory> for make_unique<>'
1065        '  [build/include_what_you_use] [4]')
1066    self.TestIncludeWhatYouUse(
1067        """#include <vector>
1068           vector<int> foo(vector<int> x) { return std::move(x); }
1069        """,
1070        'Add #include <utility> for move'
1071        '  [build/include_what_you_use] [4]')
1072    self.TestIncludeWhatYouUse(
1073        """#include <string>
1074           int a, b;
1075           std::swap(a, b);
1076        """,
1077        'Add #include <utility> for swap'
1078        '  [build/include_what_you_use] [4]')
1079
1080    # Test the UpdateIncludeState code path.
1081    mock_header_contents = ['#include "blah/foo.h"', '#include "blah/bar.h"']
1082    message = self.PerformIncludeWhatYouUse(
1083        '#include "blah/a.h"',
1084        filename='blah/a.cc',
1085        io=MockIo(mock_header_contents))
1086    self.assertEquals(message, '')
1087
1088    mock_header_contents = ['#include <set>']
1089    message = self.PerformIncludeWhatYouUse(
1090        """#include "blah/a.h"
1091           std::set<int> foo;""",
1092        filename='blah/a.cc',
1093        io=MockIo(mock_header_contents))
1094    self.assertEquals(message, '')
1095
1096    # Make sure we can find the correct header file if the cc file seems to be
1097    # a temporary file generated by Emacs's flymake.
1098    mock_header_contents = ['']
1099    message = self.PerformIncludeWhatYouUse(
1100        """#include "blah/a.h"
1101           std::set<int> foo;""",
1102        filename='blah/a_flymake.cc',
1103        io=MockIo(mock_header_contents))
1104    self.assertEquals(message, 'Add #include <set> for set<>  '
1105                      '[build/include_what_you_use] [4]')
1106
1107    # If there's just a cc and the header can't be found then it's ok.
1108    message = self.PerformIncludeWhatYouUse(
1109        """#include "blah/a.h"
1110           std::set<int> foo;""",
1111        filename='blah/a.cc')
1112    self.assertEquals(message, '')
1113
1114    # Make sure we find the headers with relative paths.
1115    mock_header_contents = ['']
1116    message = self.PerformIncludeWhatYouUse(
1117        """#include "%s/a.h"
1118           std::set<int> foo;""" % os.path.basename(os.getcwd()),
1119        filename='a.cc',
1120        io=MockIo(mock_header_contents))
1121    self.assertEquals(message, 'Add #include <set> for set<>  '
1122                      '[build/include_what_you_use] [4]')
1123
1124  def testFilesBelongToSameModule(self):
1125    f = cpplint.FilesBelongToSameModule
1126    self.assertEquals((True, ''), f('a.cc', 'a.h'))
1127    self.assertEquals((True, ''), f('base/google.cc', 'base/google.h'))
1128    self.assertEquals((True, ''), f('base/google_test.cc', 'base/google.h'))
1129    self.assertEquals((True, ''),
1130                      f('base/google_unittest.cc', 'base/google.h'))
1131    self.assertEquals((True, ''),
1132                      f('base/internal/google_unittest.cc',
1133                        'base/public/google.h'))
1134    self.assertEquals((True, 'xxx/yyy/'),
1135                      f('xxx/yyy/base/internal/google_unittest.cc',
1136                        'base/public/google.h'))
1137    self.assertEquals((True, 'xxx/yyy/'),
1138                      f('xxx/yyy/base/google_unittest.cc',
1139                        'base/public/google.h'))
1140    self.assertEquals((True, ''),
1141                      f('base/google_unittest.cc', 'base/google-inl.h'))
1142    self.assertEquals((True, '/home/build/google3/'),
1143                      f('/home/build/google3/base/google.cc', 'base/google.h'))
1144
1145    self.assertEquals((False, ''),
1146                      f('/home/build/google3/base/google.cc', 'basu/google.h'))
1147    self.assertEquals((False, ''), f('a.cc', 'b.h'))
1148
1149  def testCleanseLine(self):
1150    self.assertEquals('int foo = 0;',
1151                      cpplint.CleanseComments('int foo = 0;  // danger!'))
1152    self.assertEquals('int o = 0;',
1153                      cpplint.CleanseComments('int /* foo */ o = 0;'))
1154    self.assertEquals('foo(int a, int b);',
1155                      cpplint.CleanseComments('foo(int a /* abc */, int b);'))
1156    self.assertEqual('f(a, b);',
1157                     cpplint.CleanseComments('f(a, /* name */ b);'))
1158    self.assertEqual('f(a, b);',
1159                     cpplint.CleanseComments('f(a /* name */, b);'))
1160    self.assertEqual('f(a, b);',
1161                     cpplint.CleanseComments('f(a, /* name */b);'))
1162    self.assertEqual('f(a, b, c);',
1163                     cpplint.CleanseComments('f(a, /**/b, /**/c);'))
1164    self.assertEqual('f(a, b, c);',
1165                     cpplint.CleanseComments('f(a, /**/b/**/, c);'))
1166
1167  def testRawStrings(self):
1168    self.TestMultiLineLint(
1169        """
1170        void Func() {
1171          static const char kString[] = R"(
1172            #endif  <- invalid preprocessor should be ignored
1173            */      <- invalid comment should be ignored too
1174          )";
1175        }""",
1176        '')
1177    self.TestMultiLineLint(
1178        """
1179        void Func() {
1180          string s = R"TrueDelimiter(
1181              )"
1182              )FalseDelimiter"
1183              )TrueDelimiter";
1184        }""",
1185        '')
1186    self.TestMultiLineLint(
1187        """
1188        void Func() {
1189          char char kString[] = R"(  ";" )";
1190        }""",
1191        '')
1192    self.TestMultiLineLint(
1193        """
1194        static const char kRawString[] = R"(
1195          \tstatic const int kLineWithTab = 1;
1196          static const int kLineWithTrailingWhiteSpace = 1;\x20
1197
1198           void WeirdNumberOfSpacesAtLineStart() {
1199            string x;
1200            x += StrCat("Use StrAppend instead");
1201          }
1202
1203          void BlankLineAtEndOfBlock() {
1204            // TODO incorrectly formatted
1205            //Badly formatted comment
1206
1207          }
1208
1209        )";""",
1210        '')
1211    self.TestMultiLineLint(
1212        """
1213        void Func() {
1214          string s = StrCat(R"TrueDelimiter(
1215              )"
1216              )FalseDelimiter"
1217              )TrueDelimiter", R"TrueDelimiter2(
1218              )"
1219              )FalseDelimiter2"
1220              )TrueDelimiter2");
1221        }""",
1222        '')
1223    self.TestMultiLineLint(
1224        """
1225        static SomeStruct kData = {
1226            {0, R"(line1
1227                   line2
1228                   )"}
1229            };""",
1230        '')
1231
1232  def testMultiLineComments(self):
1233    # missing explicit is bad
1234    self.TestMultiLineLint(
1235        r"""int a = 0;
1236            /* multi-liner
1237            class Foo {
1238            Foo(int f);  // should cause a lint warning in code
1239            }
1240            */ """,
1241        '')
1242    self.TestMultiLineLint(
1243        r"""/* int a = 0; multi-liner
1244              static const int b = 0;""",
1245        'Could not find end of multi-line comment'
1246        '  [readability/multiline_comment] [5]')
1247    self.TestMultiLineLint(r"""  /* multi-line comment""",
1248                           'Could not find end of multi-line comment'
1249                           '  [readability/multiline_comment] [5]')
1250    self.TestMultiLineLint(r"""  // /* comment, but not multi-line""", '')
1251    self.TestMultiLineLint(r"""/**********
1252                                 */""", '')
1253    self.TestMultiLineLint(r"""/**
1254                                 * Doxygen comment
1255                                 */""",
1256                           '')
1257    self.TestMultiLineLint(r"""/*!
1258                                 * Doxygen comment
1259                                 */""",
1260                           '')
1261
1262  def testMultilineStrings(self):
1263    multiline_string_error_message = (
1264        'Multi-line string ("...") found.  This lint script doesn\'t '
1265        'do well with such strings, and may give bogus warnings.  '
1266        'Use C++11 raw strings or concatenation instead.'
1267        '  [readability/multiline_string] [5]')
1268
1269    file_path = 'mydir/foo.cc'
1270
1271    error_collector = ErrorCollector(self.assert_)
1272    cpplint.ProcessFileData(file_path, 'cc',
1273                            ['const char* str = "This is a\\',
1274                             ' multiline string.";'],
1275                            error_collector)
1276    self.assertEquals(
1277        2,  # One per line.
1278        error_collector.ResultList().count(multiline_string_error_message))
1279
1280  # Test non-explicit single-argument constructors
1281  def testExplicitSingleArgumentConstructors(self):
1282    old_verbose_level = cpplint._cpplint_state.verbose_level
1283    cpplint._cpplint_state.verbose_level = 0
1284
1285    try:
1286      # missing explicit is bad
1287      self.TestMultiLineLint(
1288          """
1289          class Foo {
1290            Foo(int f);
1291          };""",
1292          'Single-parameter constructors should be marked explicit.'
1293          '  [runtime/explicit] [5]')
1294      # missing explicit is bad, even with whitespace
1295      self.TestMultiLineLint(
1296          """
1297          class Foo {
1298            Foo (int f);
1299          };""",
1300          ['Extra space before ( in function call  [whitespace/parens] [4]',
1301           'Single-parameter constructors should be marked explicit.'
1302           '  [runtime/explicit] [5]'])
1303      # missing explicit, with distracting comment, is still bad
1304      self.TestMultiLineLint(
1305          """
1306          class Foo {
1307            Foo(int f);  // simpler than Foo(blargh, blarg)
1308          };""",
1309          'Single-parameter constructors should be marked explicit.'
1310          '  [runtime/explicit] [5]')
1311      # missing explicit, with qualified classname
1312      self.TestMultiLineLint(
1313          """
1314          class Qualifier::AnotherOne::Foo {
1315            Foo(int f);
1316          };""",
1317          'Single-parameter constructors should be marked explicit.'
1318          '  [runtime/explicit] [5]')
1319      # missing explicit for inline constructors is bad as well
1320      self.TestMultiLineLint(
1321          """
1322          class Foo {
1323            inline Foo(int f);
1324          };""",
1325          'Single-parameter constructors should be marked explicit.'
1326          '  [runtime/explicit] [5]')
1327      # missing explicit for constexpr constructors is bad as well
1328      self.TestMultiLineLint(
1329          """
1330          class Foo {
1331            constexpr Foo(int f);
1332          };""",
1333          'Single-parameter constructors should be marked explicit.'
1334          '  [runtime/explicit] [5]')
1335      # missing explicit for constexpr+inline constructors is bad as well
1336      self.TestMultiLineLint(
1337          """
1338          class Foo {
1339            constexpr inline Foo(int f);
1340          };""",
1341          'Single-parameter constructors should be marked explicit.'
1342          '  [runtime/explicit] [5]')
1343      self.TestMultiLineLint(
1344          """
1345          class Foo {
1346            inline constexpr Foo(int f);
1347          };""",
1348          'Single-parameter constructors should be marked explicit.'
1349          '  [runtime/explicit] [5]')
1350      # explicit with inline is accepted
1351      self.TestMultiLineLint(
1352          """
1353          class Foo {
1354            inline explicit Foo(int f);
1355          };""",
1356          '')
1357      self.TestMultiLineLint(
1358          """
1359          class Foo {
1360            explicit inline Foo(int f);
1361          };""",
1362          '')
1363      # explicit with constexpr is accepted
1364      self.TestMultiLineLint(
1365          """
1366          class Foo {
1367            constexpr explicit Foo(int f);
1368          };""",
1369          '')
1370      self.TestMultiLineLint(
1371          """
1372          class Foo {
1373            explicit constexpr Foo(int f);
1374          };""",
1375          '')
1376      # explicit with constexpr+inline is accepted
1377      self.TestMultiLineLint(
1378          """
1379          class Foo {
1380            inline constexpr explicit Foo(int f);
1381          };""",
1382          '')
1383      self.TestMultiLineLint(
1384          """
1385          class Foo {
1386            explicit inline constexpr Foo(int f);
1387          };""",
1388          '')
1389      self.TestMultiLineLint(
1390          """
1391          class Foo {
1392            constexpr inline explicit Foo(int f);
1393          };""",
1394          '')
1395      self.TestMultiLineLint(
1396          """
1397          class Foo {
1398            explicit constexpr inline Foo(int f);
1399          };""",
1400          '')
1401      # structs are caught as well.
1402      self.TestMultiLineLint(
1403          """
1404          struct Foo {
1405            Foo(int f);
1406          };""",
1407          'Single-parameter constructors should be marked explicit.'
1408          '  [runtime/explicit] [5]')
1409      # Templatized classes are caught as well.
1410      self.TestMultiLineLint(
1411          """
1412          template<typename T> class Foo {
1413            Foo(int f);
1414          };""",
1415          'Single-parameter constructors should be marked explicit.'
1416          '  [runtime/explicit] [5]')
1417      # inline case for templatized classes.
1418      self.TestMultiLineLint(
1419          """
1420          template<typename T> class Foo {
1421            inline Foo(int f);
1422          };""",
1423          'Single-parameter constructors should be marked explicit.'
1424          '  [runtime/explicit] [5]')
1425      # constructors with a default argument should still be marked explicit
1426      self.TestMultiLineLint(
1427          """
1428          class Foo {
1429            Foo(int f = 0);
1430          };""",
1431          'Constructors callable with one argument should be marked explicit.'
1432          '  [runtime/explicit] [5]')
1433      # multi-argument constructors with all but one default argument should be
1434      # marked explicit
1435      self.TestMultiLineLint(
1436          """
1437          class Foo {
1438            Foo(int f, int g = 0);
1439          };""",
1440          'Constructors callable with one argument should be marked explicit.'
1441          '  [runtime/explicit] [5]')
1442      # multi-argument constructors with all default arguments should be marked
1443      # explicit
1444      self.TestMultiLineLint(
1445          """
1446          class Foo {
1447            Foo(int f = 0, int g = 0);
1448          };""",
1449          'Constructors callable with one argument should be marked explicit.'
1450          '  [runtime/explicit] [5]')
1451      # explicit no-argument constructors are bad
1452      self.TestMultiLineLint(
1453          """
1454          class Foo {
1455            explicit Foo();
1456          };""",
1457          'Zero-parameter constructors should not be marked explicit.'
1458          '  [runtime/explicit] [5]')
1459      # void constructors are considered no-argument
1460      self.TestMultiLineLint(
1461          """
1462          class Foo {
1463            explicit Foo(void);
1464          };""",
1465          'Zero-parameter constructors should not be marked explicit.'
1466          '  [runtime/explicit] [5]')
1467      # No warning for multi-parameter constructors
1468      self.TestMultiLineLint(
1469          """
1470          class Foo {
1471            explicit Foo(int f, int g);
1472          };""",
1473          '')
1474      self.TestMultiLineLint(
1475          """
1476          class Foo {
1477            explicit Foo(int f, int g = 0);
1478          };""",
1479          '')
1480      # single-argument constructors that take a function that takes multiple
1481      # arguments should be explicit
1482      self.TestMultiLineLint(
1483          """
1484          class Foo {
1485            Foo(void (*f)(int f, int g));
1486          };""",
1487          'Single-parameter constructors should be marked explicit.'
1488          '  [runtime/explicit] [5]')
1489      # single-argument constructors that take a single template argument with
1490      # multiple parameters should be explicit
1491      self.TestMultiLineLint(
1492          """
1493          template <typename T, typename S>
1494          class Foo {
1495            Foo(Bar<T, S> b);
1496          };""",
1497          'Single-parameter constructors should be marked explicit.'
1498          '  [runtime/explicit] [5]')
1499      # but copy constructors that take multiple template parameters are OK
1500      self.TestMultiLineLint(
1501          """
1502          template <typename T, S>
1503          class Foo {
1504            Foo(Foo<T, S>& f);
1505          };""",
1506          '')
1507      # proper style is okay
1508      self.TestMultiLineLint(
1509          """
1510          class Foo {
1511            explicit Foo(int f);
1512          };""",
1513          '')
1514      # two argument constructor is okay
1515      self.TestMultiLineLint(
1516          """
1517          class Foo {
1518            Foo(int f, int b);
1519          };""",
1520          '')
1521      # two argument constructor, across two lines, is okay
1522      self.TestMultiLineLint(
1523          """
1524          class Foo {
1525            Foo(int f,
1526                int b);
1527          };""",
1528          '')
1529      # non-constructor (but similar name), is okay
1530      self.TestMultiLineLint(
1531          """
1532          class Foo {
1533            aFoo(int f);
1534          };""",
1535          '')
1536      # constructor with void argument is okay
1537      self.TestMultiLineLint(
1538          """
1539          class Foo {
1540            Foo(void);
1541          };""",
1542          '')
1543      # single argument method is okay
1544      self.TestMultiLineLint(
1545          """
1546          class Foo {
1547            Bar(int b);
1548          };""",
1549          '')
1550      # comments should be ignored
1551      self.TestMultiLineLint(
1552          """
1553          class Foo {
1554          // Foo(int f);
1555          };""",
1556          '')
1557      # single argument function following class definition is okay
1558      # (okay, it's not actually valid, but we don't want a false positive)
1559      self.TestMultiLineLint(
1560          """
1561          class Foo {
1562            Foo(int f, int b);
1563          };
1564          Foo(int f);""",
1565          '')
1566      # single argument function is okay
1567      self.TestMultiLineLint(
1568          """static Foo(int f);""",
1569          '')
1570      # single argument copy constructor is okay.
1571      self.TestMultiLineLint(
1572          """
1573          class Foo {
1574            Foo(const Foo&);
1575          };""",
1576          '')
1577      self.TestMultiLineLint(
1578          """
1579          class Foo {
1580            Foo(Foo const&);
1581          };""",
1582          '')
1583      self.TestMultiLineLint(
1584          """
1585          class Foo {
1586            Foo(Foo&);
1587          };""",
1588          '')
1589      # templatized copy constructor is okay.
1590      self.TestMultiLineLint(
1591          """
1592          template<typename T> class Foo {
1593            Foo(const Foo<T>&);
1594          };""",
1595          '')
1596      # Special case for std::initializer_list
1597      self.TestMultiLineLint(
1598          """
1599          class Foo {
1600            Foo(std::initializer_list<T> &arg) {}
1601          };""",
1602          '')
1603      # Anything goes inside an assembly block
1604      error_collector = ErrorCollector(self.assert_)
1605      cpplint.ProcessFileData('foo.cc', 'cc',
1606                              ['void Func() {',
1607                               '  __asm__ (',
1608                               '    "hlt"',
1609                               '  );',
1610                               '  asm {',
1611                               '    movdqa [edx + 32], xmm2',
1612                               '  }',
1613                               '}'],
1614                              error_collector)
1615      self.assertEquals(
1616          0,
1617          error_collector.ResultList().count(
1618              'Extra space before ( in function call  [whitespace/parens] [4]'))
1619      self.assertEquals(
1620          0,
1621          error_collector.ResultList().count(
1622              'Closing ) should be moved to the previous line  '
1623              '[whitespace/parens] [2]'))
1624      self.assertEquals(
1625          0,
1626          error_collector.ResultList().count(
1627              'Extra space before [  [whitespace/braces] [5]'))
1628    finally:
1629      cpplint._cpplint_state.verbose_level = old_verbose_level
1630
1631  def testSlashStarCommentOnSingleLine(self):
1632    self.TestMultiLineLint(
1633        """/* static */ Foo(int f);""",
1634        '')
1635    self.TestMultiLineLint(
1636        """/*/ static */  Foo(int f);""",
1637        '')
1638    self.TestMultiLineLint(
1639        """/*/ static Foo(int f);""",
1640        'Could not find end of multi-line comment'
1641        '  [readability/multiline_comment] [5]')
1642    self.TestMultiLineLint(
1643        """  /*/ static Foo(int f);""",
1644        'Could not find end of multi-line comment'
1645        '  [readability/multiline_comment] [5]')
1646    self.TestMultiLineLint(
1647        """  /**/ static Foo(int f);""",
1648        '')
1649
1650  # Test suspicious usage of "if" like this:
1651  # if (a == b) {
1652  #   DoSomething();
1653  # } if (a == c) {   // Should be "else if".
1654  #   DoSomething();  // This gets called twice if a == b && a == c.
1655  # }
1656  def testSuspiciousUsageOfIf(self):
1657    self.TestLint(
1658        '  if (a == b) {',
1659        '')
1660    self.TestLint(
1661        '  } if (a == b) {',
1662        'Did you mean "else if"? If not, start a new line for "if".'
1663        '  [readability/braces] [4]')
1664
1665  # Test suspicious usage of memset. Specifically, a 0
1666  # as the final argument is almost certainly an error.
1667  def testSuspiciousUsageOfMemset(self):
1668    # Normal use is okay.
1669    self.TestLint(
1670        '  memset(buf, 0, sizeof(buf))',
1671        '')
1672
1673    # A 0 as the final argument is almost certainly an error.
1674    self.TestLint(
1675        '  memset(buf, sizeof(buf), 0)',
1676        'Did you mean "memset(buf, 0, sizeof(buf))"?'
1677        '  [runtime/memset] [4]')
1678    self.TestLint(
1679        '  memset(buf, xsize * ysize, 0)',
1680        'Did you mean "memset(buf, 0, xsize * ysize)"?'
1681        '  [runtime/memset] [4]')
1682
1683    # There is legitimate test code that uses this form.
1684    # This is okay since the second argument is a literal.
1685    self.TestLint(
1686        "  memset(buf, 'y', 0)",
1687        '')
1688    self.TestLint(
1689        '  memset(buf, 4, 0)',
1690        '')
1691    self.TestLint(
1692        '  memset(buf, -1, 0)',
1693        '')
1694    self.TestLint(
1695        '  memset(buf, 0xF1, 0)',
1696        '')
1697    self.TestLint(
1698        '  memset(buf, 0xcd, 0)',
1699        '')
1700
1701  def testRedundantVirtual(self):
1702    self.TestLint('virtual void F()', '')
1703    self.TestLint('virtual void F();', '')
1704    self.TestLint('virtual void F() {}', '')
1705
1706    message_template = ('"%s" is redundant since function is already '
1707                        'declared as "%s"  [readability/inheritance] [4]')
1708    for virt_specifier in ['override', 'final']:
1709      error_message = message_template % ('virtual', virt_specifier)
1710      self.TestLint('virtual int F() %s' % virt_specifier, error_message)
1711      self.TestLint('virtual int F() %s;' % virt_specifier, error_message)
1712      self.TestLint('virtual int F() %s {' % virt_specifier, error_message)
1713
1714      error_collector = ErrorCollector(self.assert_)
1715      cpplint.ProcessFileData(
1716          'foo.cc', 'cc',
1717          ['// Copyright 2014 Your Company.',
1718           'virtual void F(int a,',
1719           '               int b) ' + virt_specifier + ';',
1720           'virtual void F(int a,',
1721           '               int b) LOCKS_EXCLUDED(lock) ' + virt_specifier + ';',
1722           'virtual void F(int a,',
1723           '               int b)',
1724           '    LOCKS_EXCLUDED(lock) ' + virt_specifier + ';',
1725           ''],
1726          error_collector)
1727      self.assertEquals(
1728          [error_message, error_message, error_message],
1729          error_collector.Results())
1730
1731    error_message = message_template % ('override', 'final')
1732    self.TestLint('int F() override final', error_message)
1733    self.TestLint('int F() override final;', error_message)
1734    self.TestLint('int F() override final {}', error_message)
1735    self.TestLint('int F() final override', error_message)
1736    self.TestLint('int F() final override;', error_message)
1737    self.TestLint('int F() final override {}', error_message)
1738
1739    error_collector = ErrorCollector(self.assert_)
1740    cpplint.ProcessFileData(
1741        'foo.cc', 'cc',
1742        ['// Copyright 2014 Your Company.',
1743         'struct A : virtual B {',
1744         '  ~A() override;'
1745         '};',
1746         'class C',
1747         '    : public D,',
1748         '      public virtual E {',
1749         '  void Func() override;',
1750         '}',
1751         ''],
1752        error_collector)
1753    self.assertEquals('', error_collector.Results())
1754
1755    self.TestLint('void Finalize(AnnotationProto *final) override;', '')
1756
1757  def testCheckDeprecated(self):
1758    self.TestLanguageRulesCheck('foo_test.cc', '#include <iostream>', '')
1759    self.TestLanguageRulesCheck('foo_unittest.cc', '#include <iostream>', '')
1760
1761  def testCheckPosixThreading(self):
1762    self.TestLint('var = sctime_r()', '')
1763    self.TestLint('var = strtok_r()', '')
1764    self.TestLint('var = strtok_r(foo, ba, r)', '')
1765    self.TestLint('var = brand()', '')
1766    self.TestLint('_rand()', '')
1767    self.TestLint('.rand()', '')
1768    self.TestLint('->rand()', '')
1769    self.TestLint('ACMRandom rand(seed)', '')
1770    self.TestLint('ISAACRandom rand()', '')
1771    self.TestLint('var = rand()',
1772                  'Consider using rand_r(...) instead of rand(...)'
1773                  ' for improved thread safety.'
1774                  '  [runtime/threadsafe_fn] [2]')
1775    self.TestLint('var = strtok(str, delim)',
1776                  'Consider using strtok_r(...) '
1777                  'instead of strtok(...)'
1778                  ' for improved thread safety.'
1779                  '  [runtime/threadsafe_fn] [2]')
1780
1781  def testVlogMisuse(self):
1782    self.TestLint('VLOG(1)', '')
1783    self.TestLint('VLOG(99)', '')
1784    self.TestLint('LOG(ERROR)', '')
1785    self.TestLint('LOG(INFO)', '')
1786    self.TestLint('LOG(WARNING)', '')
1787    self.TestLint('LOG(FATAL)', '')
1788    self.TestLint('LOG(DFATAL)', '')
1789    self.TestLint('VLOG(SOMETHINGWEIRD)', '')
1790    self.TestLint('MYOWNVLOG(ERROR)', '')
1791    errmsg = ('VLOG() should be used with numeric verbosity level.  '
1792              'Use LOG() if you want symbolic severity levels.'
1793              '  [runtime/vlog] [5]')
1794    self.TestLint('VLOG(ERROR)', errmsg)
1795    self.TestLint('VLOG(INFO)', errmsg)
1796    self.TestLint('VLOG(WARNING)', errmsg)
1797    self.TestLint('VLOG(FATAL)', errmsg)
1798    self.TestLint('VLOG(DFATAL)', errmsg)
1799    self.TestLint('  VLOG(ERROR)', errmsg)
1800    self.TestLint('  VLOG(INFO)', errmsg)
1801    self.TestLint('  VLOG(WARNING)', errmsg)
1802    self.TestLint('  VLOG(FATAL)', errmsg)
1803    self.TestLint('  VLOG(DFATAL)', errmsg)
1804
1805
1806  # Test potential format string bugs like printf(foo).
1807  def testFormatStrings(self):
1808    self.TestLint('printf("foo")', '')
1809    self.TestLint('printf("foo: %s", foo)', '')
1810    self.TestLint('DocidForPrintf(docid)', '')  # Should not trigger.
1811    self.TestLint('printf(format, value)', '')  # Should not trigger.
1812    self.TestLint('printf(__VA_ARGS__)', '')  # Should not trigger.
1813    self.TestLint('printf(format.c_str(), value)', '')  # Should not trigger.
1814    self.TestLint('printf(format(index).c_str(), value)', '')
1815    self.TestLint(
1816        'printf(foo)',
1817        'Potential format string bug. Do printf("%s", foo) instead.'
1818        '  [runtime/printf] [4]')
1819    self.TestLint(
1820        'printf(foo.c_str())',
1821        'Potential format string bug. '
1822        'Do printf("%s", foo.c_str()) instead.'
1823        '  [runtime/printf] [4]')
1824    self.TestLint(
1825        'printf(foo->c_str())',
1826        'Potential format string bug. '
1827        'Do printf("%s", foo->c_str()) instead.'
1828        '  [runtime/printf] [4]')
1829    self.TestLint(
1830        'StringPrintf(foo)',
1831        'Potential format string bug. Do StringPrintf("%s", foo) instead.'
1832        ''
1833        '  [runtime/printf] [4]')
1834
1835  # Test disallowed use of operator& and other operators.
1836  def testIllegalOperatorOverloading(self):
1837    errmsg = ('Unary operator& is dangerous.  Do not use it.'
1838              '  [runtime/operator] [4]')
1839    self.TestLint('void operator=(const Myclass&)', '')
1840    self.TestLint('void operator&(int a, int b)', '')   # binary operator& ok
1841    self.TestLint('void operator&() { }', errmsg)
1842    self.TestLint('void operator & (  ) { }',
1843                  ['Extra space after (  [whitespace/parens] [2]', errmsg])
1844
1845  # const string reference members are dangerous..
1846  def testConstStringReferenceMembers(self):
1847    errmsg = ('const string& members are dangerous. It is much better to use '
1848              'alternatives, such as pointers or simple constants.'
1849              '  [runtime/member_string_references] [2]')
1850
1851    members_declarations = ['const string& church',
1852                            'const string &turing',
1853                            'const string & godel']
1854    # TODO(unknown): Enable also these tests if and when we ever
1855    # decide to check for arbitrary member references.
1856    #                         "const Turing & a",
1857    #                         "const Church& a",
1858    #                         "const vector<int>& a",
1859    #                         "const     Kurt::Godel    &    godel",
1860    #                         "const Kazimierz::Kuratowski& kk" ]
1861
1862    # The Good.
1863
1864    self.TestLint('void f(const string&)', '')
1865    self.TestLint('const string& f(const string& a, const string& b)', '')
1866    self.TestLint('typedef const string& A;', '')
1867
1868    for decl in members_declarations:
1869      self.TestLint(decl + ' = b;', '')
1870      self.TestLint(decl + '      =', '')
1871
1872    # The Bad.
1873
1874    for decl in members_declarations:
1875      self.TestLint(decl + ';', errmsg)
1876
1877  # Variable-length arrays are not permitted.
1878  def testVariableLengthArrayDetection(self):
1879    errmsg = ('Do not use variable-length arrays.  Use an appropriately named '
1880              "('k' followed by CamelCase) compile-time constant for the size."
1881              '  [runtime/arrays] [1]')
1882
1883    self.TestLint('int a[any_old_variable];', errmsg)
1884    self.TestLint('int doublesize[some_var * 2];', errmsg)
1885    self.TestLint('int a[afunction()];', errmsg)
1886    self.TestLint('int a[function(kMaxFooBars)];', errmsg)
1887    self.TestLint('bool a_list[items_->size()];', errmsg)
1888    self.TestLint('namespace::Type buffer[len+1];', errmsg)
1889
1890    self.TestLint('int a[64];', '')
1891    self.TestLint('int a[0xFF];', '')
1892    self.TestLint('int first[256], second[256];', '')
1893    self.TestLint('int array_name[kCompileTimeConstant];', '')
1894    self.TestLint('char buf[somenamespace::kBufSize];', '')
1895    self.TestLint('int array_name[ALL_CAPS];', '')
1896    self.TestLint('AClass array1[foo::bar::ALL_CAPS];', '')
1897    self.TestLint('int a[kMaxStrLen + 1];', '')
1898    self.TestLint('int a[sizeof(foo)];', '')
1899    self.TestLint('int a[sizeof(*foo)];', '')
1900    self.TestLint('int a[sizeof foo];', '')
1901    self.TestLint('int a[sizeof(struct Foo)];', '')
1902    self.TestLint('int a[128 - sizeof(const bar)];', '')
1903    self.TestLint('int a[(sizeof(foo) * 4)];', '')
1904    self.TestLint('int a[(arraysize(fixed_size_array)/2) << 1];', '')
1905    self.TestLint('delete a[some_var];', '')
1906    self.TestLint('return a[some_var];', '')
1907
1908  # DISALLOW_COPY_AND_ASSIGN and DISALLOW_IMPLICIT_CONSTRUCTORS should be at
1909  # end of class if present.
1910  def testDisallowMacrosAtEnd(self):
1911    for macro_name in (
1912        'DISALLOW_COPY_AND_ASSIGN',
1913        'DISALLOW_IMPLICIT_CONSTRUCTORS'):
1914      error_collector = ErrorCollector(self.assert_)
1915      cpplint.ProcessFileData(
1916          'foo.cc', 'cc',
1917          ['// Copyright 2014 Your Company.',
1918           'class SomeClass {',
1919           ' private:',
1920           '  %s(SomeClass);' % macro_name,
1921           '  int member_;',
1922           '};',
1923           ''],
1924          error_collector)
1925      self.assertEquals(
1926          ('%s should be the last thing in the class' % macro_name) +
1927          '  [readability/constructors] [3]',
1928          error_collector.Results())
1929
1930      error_collector = ErrorCollector(self.assert_)
1931      cpplint.ProcessFileData(
1932          'foo.cc', 'cc',
1933          ['// Copyright 2014 Your Company.',
1934           'class OuterClass {',
1935           ' private:',
1936           '  struct InnerClass {',
1937           '   private:',
1938           '    %s(InnerClass);' % macro_name,
1939           '    int member;',
1940           '  };',
1941           '};',
1942           ''],
1943          error_collector)
1944      self.assertEquals(
1945          ('%s should be the last thing in the class' % macro_name) +
1946          '  [readability/constructors] [3]',
1947          error_collector.Results())
1948
1949      error_collector = ErrorCollector(self.assert_)
1950      cpplint.ProcessFileData(
1951          'foo.cc', 'cc',
1952          ['// Copyright 2014 Your Company.',
1953           'class OuterClass1 {',
1954           ' private:',
1955           '  struct InnerClass1 {',
1956           '   private:',
1957           '    %s(InnerClass1);' % macro_name,
1958           '  };',
1959           '  %s(OuterClass1);' % macro_name,
1960           '};',
1961           'struct OuterClass2 {',
1962           ' private:',
1963           '  class InnerClass2 {',
1964           '   private:',
1965           '    %s(InnerClass2);' % macro_name,
1966           '    // comment',
1967           '  };',
1968           '',
1969           '  %s(OuterClass2);' % macro_name,
1970           '',
1971           '  // comment',
1972           '};',
1973           'void Func() {',
1974           '  struct LocalClass {',
1975           '   private:',
1976           '    %s(LocalClass);' % macro_name,
1977           '  } variable;',
1978           '}',
1979           ''],
1980          error_collector)
1981      self.assertEquals('', error_collector.Results())
1982
1983  # Brace usage
1984  def testBraces(self):
1985    # Braces shouldn't be followed by a ; unless they're defining a struct
1986    # or initializing an array
1987    self.TestLint('int a[3] = { 1, 2, 3 };', '')
1988    self.TestLint(
1989        """const int foo[] =
1990               {1, 2, 3 };""",
1991        '')
1992    # For single line, unmatched '}' with a ';' is ignored (not enough context)
1993    self.TestMultiLineLint(
1994        """int a[3] = { 1,
1995                        2,
1996                        3 };""",
1997        '')
1998    self.TestMultiLineLint(
1999        """int a[2][3] = { { 1, 2 },
2000                         { 3, 4 } };""",
2001        '')
2002    self.TestMultiLineLint(
2003        """int a[2][3] =
2004               { { 1, 2 },
2005                 { 3, 4 } };""",
2006        '')
2007
2008  # CHECK/EXPECT_TRUE/EXPECT_FALSE replacements
2009  def testCheckCheck(self):
2010    self.TestLint('CHECK(x == 42);',
2011                  'Consider using CHECK_EQ instead of CHECK(a == b)'
2012                  '  [readability/check] [2]')
2013    self.TestLint('CHECK(x != 42);',
2014                  'Consider using CHECK_NE instead of CHECK(a != b)'
2015                  '  [readability/check] [2]')
2016    self.TestLint('CHECK(x >= 42);',
2017                  'Consider using CHECK_GE instead of CHECK(a >= b)'
2018                  '  [readability/check] [2]')
2019    self.TestLint('CHECK(x > 42);',
2020                  'Consider using CHECK_GT instead of CHECK(a > b)'
2021                  '  [readability/check] [2]')
2022    self.TestLint('CHECK(x <= 42);',
2023                  'Consider using CHECK_LE instead of CHECK(a <= b)'
2024                  '  [readability/check] [2]')
2025    self.TestLint('CHECK(x < 42);',
2026                  'Consider using CHECK_LT instead of CHECK(a < b)'
2027                  '  [readability/check] [2]')
2028
2029    self.TestLint('DCHECK(x == 42);',
2030                  'Consider using DCHECK_EQ instead of DCHECK(a == b)'
2031                  '  [readability/check] [2]')
2032    self.TestLint('DCHECK(x != 42);',
2033                  'Consider using DCHECK_NE instead of DCHECK(a != b)'
2034                  '  [readability/check] [2]')
2035    self.TestLint('DCHECK(x >= 42);',
2036                  'Consider using DCHECK_GE instead of DCHECK(a >= b)'
2037                  '  [readability/check] [2]')
2038    self.TestLint('DCHECK(x > 42);',
2039                  'Consider using DCHECK_GT instead of DCHECK(a > b)'
2040                  '  [readability/check] [2]')
2041    self.TestLint('DCHECK(x <= 42);',
2042                  'Consider using DCHECK_LE instead of DCHECK(a <= b)'
2043                  '  [readability/check] [2]')
2044    self.TestLint('DCHECK(x < 42);',
2045                  'Consider using DCHECK_LT instead of DCHECK(a < b)'
2046                  '  [readability/check] [2]')
2047
2048    self.TestLint(
2049        'EXPECT_TRUE("42" == x);',
2050        'Consider using EXPECT_EQ instead of EXPECT_TRUE(a == b)'
2051        '  [readability/check] [2]')
2052    self.TestLint(
2053        'EXPECT_TRUE("42" != x);',
2054        'Consider using EXPECT_NE instead of EXPECT_TRUE(a != b)'
2055        '  [readability/check] [2]')
2056    self.TestLint(
2057        'EXPECT_TRUE(+42 >= x);',
2058        'Consider using EXPECT_GE instead of EXPECT_TRUE(a >= b)'
2059        '  [readability/check] [2]')
2060
2061    self.TestLint(
2062        'EXPECT_FALSE(x == 42);',
2063        'Consider using EXPECT_NE instead of EXPECT_FALSE(a == b)'
2064        '  [readability/check] [2]')
2065    self.TestLint(
2066        'EXPECT_FALSE(x != 42);',
2067        'Consider using EXPECT_EQ instead of EXPECT_FALSE(a != b)'
2068        '  [readability/check] [2]')
2069    self.TestLint(
2070        'EXPECT_FALSE(x >= 42);',
2071        'Consider using EXPECT_LT instead of EXPECT_FALSE(a >= b)'
2072        '  [readability/check] [2]')
2073    self.TestLint(
2074        'ASSERT_FALSE(x > 42);',
2075        'Consider using ASSERT_LE instead of ASSERT_FALSE(a > b)'
2076        '  [readability/check] [2]')
2077    self.TestLint(
2078        'ASSERT_FALSE(x <= 42);',
2079        'Consider using ASSERT_GT instead of ASSERT_FALSE(a <= b)'
2080        '  [readability/check] [2]')
2081
2082    self.TestLint('CHECK(x<42);',
2083                  ['Missing spaces around <'
2084                   '  [whitespace/operators] [3]',
2085                   'Consider using CHECK_LT instead of CHECK(a < b)'
2086                   '  [readability/check] [2]'])
2087    self.TestLint('CHECK(x>42);',
2088                  ['Missing spaces around >'
2089                   '  [whitespace/operators] [3]',
2090                   'Consider using CHECK_GT instead of CHECK(a > b)'
2091                   '  [readability/check] [2]'])
2092
2093    self.TestLint('using some::namespace::operator<<;', '')
2094    self.TestLint('using some::namespace::operator>>;', '')
2095
2096    self.TestLint('CHECK(x->y == 42);',
2097                  'Consider using CHECK_EQ instead of CHECK(a == b)'
2098                  '  [readability/check] [2]')
2099
2100    self.TestLint(
2101        '  EXPECT_TRUE(42 < x);  // Random comment.',
2102        'Consider using EXPECT_LT instead of EXPECT_TRUE(a < b)'
2103        '  [readability/check] [2]')
2104    self.TestLint(
2105        'EXPECT_TRUE( 42 < x );',
2106        ['Extra space after ( in function call'
2107         '  [whitespace/parens] [4]',
2108         'Extra space before )  [whitespace/parens] [2]',
2109         'Consider using EXPECT_LT instead of EXPECT_TRUE(a < b)'
2110         '  [readability/check] [2]'])
2111
2112    self.TestLint('CHECK(4\'2 == x);',
2113                  'Consider using CHECK_EQ instead of CHECK(a == b)'
2114                  '  [readability/check] [2]')
2115
2116  def testCheckCheckFalsePositives(self):
2117    self.TestLint('CHECK(some_iterator == obj.end());', '')
2118    self.TestLint('EXPECT_TRUE(some_iterator == obj.end());', '')
2119    self.TestLint('EXPECT_FALSE(some_iterator == obj.end());', '')
2120    self.TestLint('CHECK(some_pointer != NULL);', '')
2121    self.TestLint('EXPECT_TRUE(some_pointer != NULL);', '')
2122    self.TestLint('EXPECT_FALSE(some_pointer != NULL);', '')
2123
2124    self.TestLint('CHECK(CreateTestFile(dir, (1 << 20)));', '')
2125    self.TestLint('CHECK(CreateTestFile(dir, (1 >> 20)));', '')
2126
2127    self.TestLint('CHECK(x ^ (y < 42));', '')
2128    self.TestLint('CHECK((x > 42) ^ (x < 54));', '')
2129    self.TestLint('CHECK(a && b < 42);', '')
2130    self.TestLint('CHECK(42 < a && a < b);', '')
2131    self.TestLint('SOFT_CHECK(x > 42);', '')
2132
2133    self.TestMultiLineLint(
2134        """_STLP_DEFINE_BINARY_OP_CHECK(==, _OP_EQUAL);
2135        _STLP_DEFINE_BINARY_OP_CHECK(!=, _OP_NOT_EQUAL);
2136        _STLP_DEFINE_BINARY_OP_CHECK(<, _OP_LESS_THAN);
2137        _STLP_DEFINE_BINARY_OP_CHECK(<=, _OP_LESS_EQUAL);
2138        _STLP_DEFINE_BINARY_OP_CHECK(>, _OP_GREATER_THAN);
2139        _STLP_DEFINE_BINARY_OP_CHECK(>=, _OP_GREATER_EQUAL);
2140        _STLP_DEFINE_BINARY_OP_CHECK(+, _OP_PLUS);
2141        _STLP_DEFINE_BINARY_OP_CHECK(*, _OP_TIMES);
2142        _STLP_DEFINE_BINARY_OP_CHECK(/, _OP_DIVIDE);
2143        _STLP_DEFINE_BINARY_OP_CHECK(-, _OP_SUBTRACT);
2144        _STLP_DEFINE_BINARY_OP_CHECK(%, _OP_MOD);""",
2145        '')
2146
2147    self.TestLint('CHECK(x < 42) << "Custom error message";', '')
2148
2149  # Alternative token to punctuation operator replacements
2150  def testCheckAltTokens(self):
2151    self.TestLint('true or true',
2152                  'Use operator || instead of or'
2153                  '  [readability/alt_tokens] [2]')
2154    self.TestLint('true and true',
2155                  'Use operator && instead of and'
2156                  '  [readability/alt_tokens] [2]')
2157    self.TestLint('if (not true)',
2158                  'Use operator ! instead of not'
2159                  '  [readability/alt_tokens] [2]')
2160    self.TestLint('1 bitor 1',
2161                  'Use operator | instead of bitor'
2162                  '  [readability/alt_tokens] [2]')
2163    self.TestLint('1 xor 1',
2164                  'Use operator ^ instead of xor'
2165                  '  [readability/alt_tokens] [2]')
2166    self.TestLint('1 bitand 1',
2167                  'Use operator & instead of bitand'
2168                  '  [readability/alt_tokens] [2]')
2169    self.TestLint('x = compl 1',
2170                  'Use operator ~ instead of compl'
2171                  '  [readability/alt_tokens] [2]')
2172    self.TestLint('x and_eq y',
2173                  'Use operator &= instead of and_eq'
2174                  '  [readability/alt_tokens] [2]')
2175    self.TestLint('x or_eq y',
2176                  'Use operator |= instead of or_eq'
2177                  '  [readability/alt_tokens] [2]')
2178    self.TestLint('x xor_eq y',
2179                  'Use operator ^= instead of xor_eq'
2180                  '  [readability/alt_tokens] [2]')
2181    self.TestLint('x not_eq y',
2182                  'Use operator != instead of not_eq'
2183                  '  [readability/alt_tokens] [2]')
2184    self.TestLint('line_continuation or',
2185                  'Use operator || instead of or'
2186                  '  [readability/alt_tokens] [2]')
2187    self.TestLint('if(true and(parentheses',
2188                  'Use operator && instead of and'
2189                  '  [readability/alt_tokens] [2]')
2190
2191    self.TestLint('#include "base/false-and-false.h"', '')
2192    self.TestLint('#error false or false', '')
2193    self.TestLint('false nor false', '')
2194    self.TestLint('false nand false', '')
2195
2196  # Passing and returning non-const references
2197  def testNonConstReference(self):
2198    # Passing a non-const reference as function parameter is forbidden.
2199    operand_error_message = ('Is this a non-const reference? '
2200                             'If so, make const or use a pointer: %s'
2201                             '  [runtime/references] [2]')
2202    # Warn of use of a non-const reference in operators and functions
2203    self.TestLint('bool operator>(Foo& s, Foo& f);',
2204                  [operand_error_message % 'Foo& s',
2205                   operand_error_message % 'Foo& f'])
2206    self.TestLint('bool operator+(Foo& s, Foo& f);',
2207                  [operand_error_message % 'Foo& s',
2208                   operand_error_message % 'Foo& f'])
2209    self.TestLint('int len(Foo& s);', operand_error_message % 'Foo& s')
2210    # Allow use of non-const references in a few specific cases
2211    self.TestLint('stream& operator>>(stream& s, Foo& f);', '')
2212    self.TestLint('stream& operator<<(stream& s, Foo& f);', '')
2213    self.TestLint('void swap(Bar& a, Bar& b);', '')
2214    self.TestLint('ostream& LogFunc(ostream& s);', '')
2215    self.TestLint('ostringstream& LogFunc(ostringstream& s);', '')
2216    self.TestLint('istream& LogFunc(istream& s);', '')
2217    self.TestLint('istringstream& LogFunc(istringstream& s);', '')
2218    # Returning a non-const reference from a function is OK.
2219    self.TestLint('int& g();', '')
2220    # Passing a const reference to a struct (using the struct keyword) is OK.
2221    self.TestLint('void foo(const struct tm& tm);', '')
2222    # Passing a const reference to a typename is OK.
2223    self.TestLint('void foo(const typename tm& tm);', '')
2224    # Const reference to a pointer type is OK.
2225    self.TestLint('void foo(const Bar* const& p) {', '')
2226    self.TestLint('void foo(Bar const* const& p) {', '')
2227    self.TestLint('void foo(Bar* const& p) {', '')
2228    # Const reference to a templated type is OK.
2229    self.TestLint('void foo(const std::vector<std::string>& v);', '')
2230    # Non-const reference to a pointer type is not OK.
2231    self.TestLint('void foo(Bar*& p);',
2232                  operand_error_message % 'Bar*& p')
2233    self.TestLint('void foo(const Bar*& p);',
2234                  operand_error_message % 'const Bar*& p')
2235    self.TestLint('void foo(Bar const*& p);',
2236                  operand_error_message % 'Bar const*& p')
2237    self.TestLint('void foo(struct Bar*& p);',
2238                  operand_error_message % 'struct Bar*& p')
2239    self.TestLint('void foo(const struct Bar*& p);',
2240                  operand_error_message % 'const struct Bar*& p')
2241    self.TestLint('void foo(struct Bar const*& p);',
2242                  operand_error_message % 'struct Bar const*& p')
2243    # Non-const reference to a templated type is not OK.
2244    self.TestLint('void foo(std::vector<int>& p);',
2245                  operand_error_message % 'std::vector<int>& p')
2246    # Returning an address of something is not prohibited.
2247    self.TestLint('return &something;', '')
2248    self.TestLint('if (condition) {return &something; }', '')
2249    self.TestLint('if (condition) return &something;', '')
2250    self.TestLint('if (condition) address = &something;', '')
2251    self.TestLint('if (condition) result = lhs&rhs;', '')
2252    self.TestLint('if (condition) result = lhs & rhs;', '')
2253    self.TestLint('a = (b+c) * sizeof &f;', '')
2254    self.TestLint('a = MySize(b) * sizeof &f;', '')
2255    # We don't get confused by C++11 range-based for loops.
2256    self.TestLint('for (const string& s : c)', '')
2257    self.TestLint('for (auto& r : c)', '')
2258    self.TestLint('for (typename Type& a : b)', '')
2259    # We don't get confused by some other uses of '&'.
2260    self.TestLint('T& operator=(const T& t);', '')
2261    self.TestLint('int g() { return (a & b); }', '')
2262    self.TestLint('T& r = (T&)*(vp());', '')
2263    self.TestLint('T& r = v', '')
2264    self.TestLint('static_assert((kBits & kMask) == 0, "text");', '')
2265    self.TestLint('COMPILE_ASSERT((kBits & kMask) == 0, text);', '')
2266    # Spaces before template arguments.  This is poor style, but
2267    # happens 0.15% of the time.
2268    self.TestLint('void Func(const vector <int> &const_x, '
2269                  'vector <int> &nonconst_x) {',
2270                  operand_error_message % 'vector<int> &nonconst_x')
2271
2272    # Derived member functions are spared from override check
2273    self.TestLint('void Func(X& x);', operand_error_message % 'X& x')
2274    self.TestLint('void Func(X& x) {}', operand_error_message % 'X& x')
2275    self.TestLint('void Func(X& x) override;', '')
2276    self.TestLint('void Func(X& x) override {', '')
2277    self.TestLint('void Func(X& x) const override;', '')
2278    self.TestLint('void Func(X& x) const override {', '')
2279
2280    # Don't warn on out-of-line method definitions.
2281    self.TestLint('void NS::Func(X& x) {', '')
2282    error_collector = ErrorCollector(self.assert_)
2283    cpplint.ProcessFileData(
2284        'foo.cc', 'cc',
2285        ['// Copyright 2014 Your Company. All Rights Reserved.',
2286         'void a::b() {}',
2287         'void f(int& q) {}',
2288         ''],
2289        error_collector)
2290    self.assertEquals(
2291        operand_error_message % 'int& q',
2292        error_collector.Results())
2293
2294    # Other potential false positives.  These need full parser
2295    # state to reproduce as opposed to just TestLint.
2296    error_collector = ErrorCollector(self.assert_)
2297    cpplint.ProcessFileData(
2298        'foo.cc', 'cc',
2299        ['// Copyright 2014 Your Company. All Rights Reserved.',
2300         'void swap(int &x,',
2301         '          int &y) {',
2302         '}',
2303         'void swap(',
2304         '    sparsegroup<T, GROUP_SIZE, Alloc> &x,',
2305         '    sparsegroup<T, GROUP_SIZE, Alloc> &y) {',
2306         '}',
2307         'ostream& operator<<(',
2308         '    ostream& out',
2309         '    const dense_hash_set<Value, Hash, Equals, Alloc>& seq) {',
2310         '}',
2311         'class A {',
2312         '  void Function(',
2313         '      string &x) override {',
2314         '  }',
2315         '};',
2316         'void Derived::Function(',
2317         '    string &x) {',
2318         '}',
2319         '#define UNSUPPORTED_MASK(_mask) \\',
2320         '  if (flags & _mask) { \\',
2321         '    LOG(FATAL) << "Unsupported flag: " << #_mask; \\',
2322         '  }',
2323         'Constructor::Constructor()',
2324         '    : initializer1_(a1 & b1),',
2325         '      initializer2_(a2 & b2) {',
2326         '}',
2327         'Constructor::Constructor()',
2328         '    : initializer1_{a3 & b3},',
2329         '      initializer2_(a4 & b4) {',
2330         '}',
2331         'Constructor::Constructor()',
2332         '    : initializer1_{a5 & b5},',
2333         '      initializer2_(a6 & b6) {}',
2334         ''],
2335        error_collector)
2336    self.assertEquals('', error_collector.Results())
2337
2338    # Multi-line references
2339    error_collector = ErrorCollector(self.assert_)
2340    cpplint.ProcessFileData(
2341        'foo.cc', 'cc',
2342        ['// Copyright 2014 Your Company. All Rights Reserved.',
2343         'void Func(const Outer::',
2344         '              Inner& const_x,',
2345         '          const Outer',
2346         '              ::Inner& const_y,',
2347         '          const Outer<',
2348         '              int>::Inner& const_z,',
2349         '          Outer::',
2350         '              Inner& nonconst_x,',
2351         '          Outer',
2352         '              ::Inner& nonconst_y,',
2353         '          Outer<',
2354         '              int>::Inner& nonconst_z) {',
2355         '}',
2356         ''],
2357        error_collector)
2358    self.assertEquals(
2359        [operand_error_message % 'Outer::Inner& nonconst_x',
2360         operand_error_message % 'Outer::Inner& nonconst_y',
2361         operand_error_message % 'Outer<int>::Inner& nonconst_z'],
2362        error_collector.Results())
2363
2364    # A peculiar false positive due to bad template argument parsing
2365    error_collector = ErrorCollector(self.assert_)
2366    cpplint.ProcessFileData(
2367        'foo.cc', 'cc',
2368        ['// Copyright 2014 Your Company. All Rights Reserved.',
2369         'inline RCULocked<X>::ReadPtr::ReadPtr(const RCULocked* rcu) {',
2370         '  DCHECK(!(data & kFlagMask)) << "Error";',
2371         '}',
2372         '',
2373         'RCULocked<X>::WritePtr::WritePtr(RCULocked* rcu)',
2374         '    : lock_(&rcu_->mutex_) {',
2375         '}',
2376         ''],
2377        error_collector.Results())
2378    self.assertEquals('', error_collector.Results())
2379
2380  def testBraceAtBeginOfLine(self):
2381    self.TestLint('{',
2382                  '{ should almost always be at the end of the previous line'
2383                  '  [whitespace/braces] [4]')
2384
2385    error_collector = ErrorCollector(self.assert_)
2386    cpplint.ProcessFileData('foo.cc', 'cc',
2387                            ['int function()',
2388                             '{',  # warning here
2389                             '  MutexLock l(&mu);',
2390                             '}',
2391                             'int variable;'
2392                             '{',  # no warning
2393                             '  MutexLock l(&mu);',
2394                             '}',
2395                             'MyType m = {',
2396                             '  {value1, value2},',
2397                             '  {',  # no warning
2398                             '    loooong_value1, looooong_value2',
2399                             '  }',
2400                             '};',
2401                             '#if PREPROCESSOR',
2402                             '{',  # no warning
2403                             '  MutexLock l(&mu);',
2404                             '}',
2405                             '#endif'],
2406                            error_collector)
2407    self.assertEquals(1, error_collector.Results().count(
2408        '{ should almost always be at the end of the previous line'
2409        '  [whitespace/braces] [4]'))
2410
2411    self.TestMultiLineLint(
2412        """
2413        foo(
2414          {
2415            loooooooooooooooong_value,
2416          });""",
2417        '')
2418
2419  def testMismatchingSpacesInParens(self):
2420    self.TestLint('if (foo ) {', 'Mismatching spaces inside () in if'
2421                  '  [whitespace/parens] [5]')
2422    self.TestLint('switch ( foo) {', 'Mismatching spaces inside () in switch'
2423                  '  [whitespace/parens] [5]')
2424    self.TestLint('for (foo; ba; bar ) {', 'Mismatching spaces inside () in for'
2425                  '  [whitespace/parens] [5]')
2426    self.TestLint('for (; foo; bar) {', '')
2427    self.TestLint('for ( ; foo; bar) {', '')
2428    self.TestLint('for ( ; foo; bar ) {', '')
2429    self.TestLint('for (foo; bar; ) {', '')
2430    self.TestLint('while (  foo  ) {', 'Should have zero or one spaces inside'
2431                  ' ( and ) in while  [whitespace/parens] [5]')
2432
2433  def testSpacingForFncall(self):
2434    self.TestLint('if (foo) {', '')
2435    self.TestLint('for (foo; bar; baz) {', '')
2436    self.TestLint('for (;;) {', '')
2437    # Space should be allowed in placement new operators.
2438    self.TestLint('Something* p = new (place) Something();', '')
2439    # Test that there is no warning when increment statement is empty.
2440    self.TestLint('for (foo; baz;) {', '')
2441    self.TestLint('for (foo;bar;baz) {', 'Missing space after ;'
2442                  '  [whitespace/semicolon] [3]')
2443    # we don't warn about this semicolon, at least for now
2444    self.TestLint('if (condition) {return &something; }',
2445                  '')
2446    # seen in some macros
2447    self.TestLint('DoSth();\\', '')
2448    # Test that there is no warning about semicolon here.
2449    self.TestLint('abc;// this is abc',
2450                  'At least two spaces is best between code'
2451                  ' and comments  [whitespace/comments] [2]')
2452    self.TestLint('while (foo) {', '')
2453    self.TestLint('switch (foo) {', '')
2454    self.TestLint('foo( bar)', 'Extra space after ( in function call'
2455                  '  [whitespace/parens] [4]')
2456    self.TestLint('foo(  // comment', '')
2457    self.TestLint('foo( // comment',
2458                  'At least two spaces is best between code'
2459                  ' and comments  [whitespace/comments] [2]')
2460    self.TestLint('foobar( \\', '')
2461    self.TestLint('foobar(     \\', '')
2462    self.TestLint('( a + b)', 'Extra space after ('
2463                  '  [whitespace/parens] [2]')
2464    self.TestLint('((a+b))', '')
2465    self.TestLint('foo (foo)', 'Extra space before ( in function call'
2466                  '  [whitespace/parens] [4]')
2467    # asm volatile () may have a space, as it isn't a function call.
2468    self.TestLint('asm volatile ("")', '')
2469    self.TestLint('__asm__ __volatile__ ("")', '')
2470    self.TestLint('} catch (const Foo& ex) {', '')
2471    self.TestLint('case (42):', '')
2472    self.TestLint('typedef foo (*foo)(foo)', '')
2473    self.TestLint('typedef foo (*foo12bar_)(foo)', '')
2474    self.TestLint('typedef foo (Foo::*bar)(foo)', '')
2475    self.TestLint('using foo = type (Foo::*bar)(foo)', '')
2476    self.TestLint('using foo = type (Foo::*bar)(', '')
2477    self.TestLint('using foo = type (Foo::*)(', '')
2478    self.TestLint('foo (Foo::*bar)(', '')
2479    self.TestLint('foo (x::y::*z)(', '')
2480    self.TestLint('foo (Foo::bar)(',
2481                  'Extra space before ( in function call'
2482                  '  [whitespace/parens] [4]')
2483    self.TestLint('foo (*bar)(', '')
2484    self.TestLint('typedef foo (Foo::*bar)(', '')
2485    self.TestLint('(foo)(bar)', '')
2486    self.TestLint('Foo (*foo)(bar)', '')
2487    self.TestLint('Foo (*foo)(Bar bar,', '')
2488    self.TestLint('char (*p)[sizeof(foo)] = &foo', '')
2489    self.TestLint('char (&ref)[sizeof(foo)] = &foo', '')
2490    self.TestLint('const char32 (*table[])[6];', '')
2491    # The sizeof operator is often written as if it were a function call, with
2492    # an opening parenthesis directly following the operator name, but it can
2493    # also be written like any other operator, with a space following the
2494    # operator name, and the argument optionally in parentheses.
2495    self.TestLint('sizeof(foo)', '')
2496    self.TestLint('sizeof foo', '')
2497    self.TestLint('sizeof (foo)', '')
2498
2499  def testSpacingBeforeBraces(self):
2500    self.TestLint('if (foo){', 'Missing space before {'
2501                  '  [whitespace/braces] [5]')
2502    self.TestLint('for{', 'Missing space before {'
2503                  '  [whitespace/braces] [5]')
2504    self.TestLint('for {', '')
2505    self.TestLint('EXPECT_DEBUG_DEATH({', '')
2506    self.TestLint('std::is_convertible<A, B>{}', '')
2507    self.TestLint('blah{32}', 'Missing space before {'
2508                  '  [whitespace/braces] [5]')
2509    self.TestLint('int8_t{3}', '')
2510    self.TestLint('int16_t{3}', '')
2511    self.TestLint('int32_t{3}', '')
2512    self.TestLint('uint64_t{12345}', '')
2513    self.TestLint('constexpr int64_t kBatchGapMicros ='
2514                  ' int64_t{7} * 24 * 3600 * 1000000;  // 1 wk.', '')
2515    self.TestLint('MoveOnly(int i1, int i2) : ip1{new int{i1}}, '
2516                  'ip2{new int{i2}} {}',
2517                  '')
2518
2519  def testSemiColonAfterBraces(self):
2520    self.TestLint('if (cond) { func(); };',
2521                  'You don\'t need a ; after a }  [readability/braces] [4]')
2522    self.TestLint('void Func() {};',
2523                  'You don\'t need a ; after a }  [readability/braces] [4]')
2524    self.TestLint('void Func() const {};',
2525                  'You don\'t need a ; after a }  [readability/braces] [4]')
2526    self.TestLint('class X {};', '')
2527    for keyword in ['struct', 'union']:
2528      for align in ['', ' alignas(16)']:
2529        for typename in ['', ' X']:
2530          for identifier in ['', ' x']:
2531            self.TestLint(keyword + align + typename + ' {}' + identifier + ';',
2532                          '')
2533
2534    self.TestLint('class X : public Y {};', '')
2535    self.TestLint('class X : public MACRO() {};', '')
2536    self.TestLint('class X : public decltype(expr) {};', '')
2537    self.TestLint('DEFINE_FACADE(PCQueue::Watcher, PCQueue) {};', '')
2538    self.TestLint('VCLASS(XfaTest, XfaContextTest) {};', '')
2539    self.TestLint('class STUBBY_CLASS(H, E) {};', '')
2540    self.TestLint('class STUBBY2_CLASS(H, E) {};', '')
2541    self.TestLint('TEST(TestCase, TestName) {};',
2542                  'You don\'t need a ; after a }  [readability/braces] [4]')
2543    self.TestLint('TEST_F(TestCase, TestName) {};',
2544                  'You don\'t need a ; after a }  [readability/braces] [4]')
2545
2546    self.TestLint('file_tocs_[i] = (FileToc) {a, b, c};', '')
2547    self.TestMultiLineLint('class X : public Y,\npublic Z {};', '')
2548
2549  def testLambda(self):
2550    self.TestLint('auto x = []() {};', '')
2551    self.TestLint('return []() {};', '')
2552    self.TestMultiLineLint('auto x = []() {\n};\n', '')
2553    self.TestLint('int operator[](int x) {};',
2554                  'You don\'t need a ; after a }  [readability/braces] [4]')
2555
2556    self.TestMultiLineLint('auto x = [&a,\nb]() {};', '')
2557    self.TestMultiLineLint('auto x = [&a,\nb]\n() {};', '')
2558    self.TestMultiLineLint('auto x = [&a,\n'
2559                           '          b](\n'
2560                           '    int a,\n'
2561                           '    int b) {\n'
2562                           '  return a +\n'
2563                           '         b;\n'
2564                           '};\n',
2565                           '')
2566
2567    # Avoid false positives with operator[]
2568    self.TestLint('table_to_children[&*table].push_back(dependent);', '')
2569
2570  def testBraceInitializerList(self):
2571    self.TestLint('MyStruct p = {1, 2};', '')
2572    self.TestLint('MyStruct p{1, 2};', '')
2573    self.TestLint('vector<int> p = {1, 2};', '')
2574    self.TestLint('vector<int> p{1, 2};', '')
2575    self.TestLint('x = vector<int>{1, 2};', '')
2576    self.TestLint('x = (struct in_addr){ 0 };', '')
2577    self.TestLint('Func(vector<int>{1, 2})', '')
2578    self.TestLint('Func((struct in_addr){ 0 })', '')
2579    self.TestLint('Func(vector<int>{1, 2}, 3)', '')
2580    self.TestLint('Func((struct in_addr){ 0 }, 3)', '')
2581    self.TestLint('LOG(INFO) << char{7};', '')
2582    self.TestLint('LOG(INFO) << char{7} << "!";', '')
2583    self.TestLint('int p[2] = {1, 2};', '')
2584    self.TestLint('return {1, 2};', '')
2585    self.TestLint('std::unique_ptr<Foo> foo{new Foo{}};', '')
2586    self.TestLint('auto foo = std::unique_ptr<Foo>{new Foo{}};', '')
2587    self.TestLint('static_assert(Max7String{}.IsValid(), "");', '')
2588    self.TestLint('map_of_pairs[{1, 2}] = 3;', '')
2589    self.TestLint('ItemView{has_offer() ? new Offer{offer()} : nullptr', '')
2590    self.TestLint('template <class T, EnableIf<::std::is_const<T>{}> = 0>', '')
2591
2592    self.TestMultiLineLint('std::unique_ptr<Foo> foo{\n'
2593                           '  new Foo{}\n'
2594                           '};\n', '')
2595    self.TestMultiLineLint('std::unique_ptr<Foo> foo{\n'
2596                           '  new Foo{\n'
2597                           '    new Bar{}\n'
2598                           '  }\n'
2599                           '};\n', '')
2600    self.TestMultiLineLint('if (true) {\n'
2601                           '  if (false){ func(); }\n'
2602                           '}\n',
2603                           'Missing space before {  [whitespace/braces] [5]')
2604    self.TestMultiLineLint('MyClass::MyClass()\n'
2605                           '    : initializer_{\n'
2606                           '          Func()} {\n'
2607                           '}\n', '')
2608    self.TestLint('const pair<string, string> kCL' +
2609                  ('o' * 41) + 'gStr[] = {\n',
2610                  'Lines should be <= 80 characters long'
2611                  '  [whitespace/line_length] [2]')
2612    self.TestMultiLineLint('const pair<string, string> kCL' +
2613                           ('o' * 40) + 'ngStr[] =\n'
2614                           '    {\n'
2615                           '        {"gooooo", "oooogle"},\n'
2616                           '};\n', '')
2617    self.TestMultiLineLint('const pair<string, string> kCL' +
2618                           ('o' * 39) + 'ngStr[] =\n'
2619                           '    {\n'
2620                           '        {"gooooo", "oooogle"},\n'
2621                           '};\n', '{ should almost always be at the end of '
2622                           'the previous line  [whitespace/braces] [4]')
2623
2624  def testSpacingAroundElse(self):
2625    self.TestLint('}else {', 'Missing space before else'
2626                  '  [whitespace/braces] [5]')
2627    self.TestLint('} else{', 'Missing space before {'
2628                  '  [whitespace/braces] [5]')
2629    self.TestLint('} else {', '')
2630    self.TestLint('} else if (foo) {', '')
2631
2632  def testSpacingWithInitializerLists(self):
2633    self.TestLint('int v[1][3] = {{1, 2, 3}};', '')
2634    self.TestLint('int v[1][1] = {{0}};', '')
2635
2636  def testSpacingForBinaryOps(self):
2637    self.TestLint('if (foo||bar) {', 'Missing spaces around ||'
2638                  '  [whitespace/operators] [3]')
2639    self.TestLint('if (foo<=bar) {', 'Missing spaces around <='
2640                  '  [whitespace/operators] [3]')
2641    self.TestLint('if (foo<bar) {', 'Missing spaces around <'
2642                  '  [whitespace/operators] [3]')
2643    self.TestLint('if (foo>bar) {', 'Missing spaces around >'
2644                  '  [whitespace/operators] [3]')
2645    self.TestLint('if (foo<bar->baz) {', 'Missing spaces around <'
2646                  '  [whitespace/operators] [3]')
2647    self.TestLint('if (foo<bar->bar) {', 'Missing spaces around <'
2648                  '  [whitespace/operators] [3]')
2649    self.TestLint('template<typename T = double>', '')
2650    self.TestLint('std::unique_ptr<No<Spaces>>', '')
2651    self.TestLint('typedef hash_map<Foo, Bar>', '')
2652    self.TestLint('10<<20', '')
2653    self.TestLint('10<<a',
2654                  'Missing spaces around <<  [whitespace/operators] [3]')
2655    self.TestLint('a<<20',
2656                  'Missing spaces around <<  [whitespace/operators] [3]')
2657    self.TestLint('a<<b',
2658                  'Missing spaces around <<  [whitespace/operators] [3]')
2659    self.TestLint('10LL<<20', '')
2660    self.TestLint('10ULL<<20', '')
2661    self.TestLint('a>>b',
2662                  'Missing spaces around >>  [whitespace/operators] [3]')
2663    self.TestLint('10>>b',
2664                  'Missing spaces around >>  [whitespace/operators] [3]')
2665    self.TestLint('LOG(ERROR)<<*foo',
2666                  'Missing spaces around <<  [whitespace/operators] [3]')
2667    self.TestLint('LOG(ERROR)<<&foo',
2668                  'Missing spaces around <<  [whitespace/operators] [3]')
2669    self.TestLint('StringCoder<vector<string>>::ToString()', '')
2670    self.TestLint('map<pair<int, int>, map<int, int>>::iterator', '')
2671    self.TestLint('func<int, pair<int, pair<int, int>>>()', '')
2672    self.TestLint('MACRO1(list<list<int>>)', '')
2673    self.TestLint('MACRO2(list<list<int>>, 42)', '')
2674    self.TestLint('void DoFoo(const set<vector<string>>& arg1);', '')
2675    self.TestLint('void SetFoo(set<vector<string>>* arg1);', '')
2676    self.TestLint('foo = new set<vector<string>>;', '')
2677    self.TestLint('reinterpret_cast<set<vector<string>>*>(a);', '')
2678    self.TestLint('MACRO(<<)', '')
2679    self.TestLint('MACRO(<<, arg)', '')
2680    self.TestLint('MACRO(<<=)', '')
2681    self.TestLint('MACRO(<<=, arg)', '')
2682
2683    self.TestLint('using Vector3<T>::operator==;', '')
2684    self.TestLint('using Vector3<T>::operator!=;', '')
2685
2686  def testSpacingBeforeLastSemicolon(self):
2687    self.TestLint('call_function() ;',
2688                  'Extra space before last semicolon. If this should be an '
2689                  'empty statement, use {} instead.'
2690                  '  [whitespace/semicolon] [5]')
2691    self.TestLint('while (true) ;',
2692                  'Extra space before last semicolon. If this should be an '
2693                  'empty statement, use {} instead.'
2694                  '  [whitespace/semicolon] [5]')
2695    self.TestLint('default:;',
2696                  'Semicolon defining empty statement. Use {} instead.'
2697                  '  [whitespace/semicolon] [5]')
2698    self.TestLint('      ;',
2699                  'Line contains only semicolon. If this should be an empty '
2700                  'statement, use {} instead.'
2701                  '  [whitespace/semicolon] [5]')
2702    self.TestLint('for (int i = 0; ;', '')
2703
2704  def testEmptyBlockBody(self):
2705    self.TestLint('while (true);',
2706                  'Empty loop bodies should use {} or continue'
2707                  '  [whitespace/empty_loop_body] [5]')
2708    self.TestLint('if (true);',
2709                  'Empty conditional bodies should use {}'
2710                  '  [whitespace/empty_conditional_body] [5]')
2711    self.TestLint('while (true)', '')
2712    self.TestLint('while (true) continue;', '')
2713    self.TestLint('for (;;);',
2714                  'Empty loop bodies should use {} or continue'
2715                  '  [whitespace/empty_loop_body] [5]')
2716    self.TestLint('for (;;)', '')
2717    self.TestLint('for (;;) continue;', '')
2718    self.TestLint('for (;;) func();', '')
2719    self.TestLint('if (test) {}',
2720                  'If statement had no body and no else clause'
2721                  '  [whitespace/empty_if_body] [4]')
2722    self.TestLint('if (test) func();', '')
2723    self.TestLint('if (test) {} else {}', '')
2724    self.TestMultiLineLint("""while (true &&
2725                                     false);""",
2726                           'Empty loop bodies should use {} or continue'
2727                           '  [whitespace/empty_loop_body] [5]')
2728    self.TestMultiLineLint("""do {
2729                           } while (false);""",
2730                           '')
2731    self.TestMultiLineLint("""#define MACRO \\
2732                           do { \\
2733                           } while (false);""",
2734                           '')
2735    self.TestMultiLineLint("""do {
2736                           } while (false);  // next line gets a warning
2737                           while (false);""",
2738                           'Empty loop bodies should use {} or continue'
2739                           '  [whitespace/empty_loop_body] [5]')
2740    self.TestMultiLineLint("""if (test) {
2741                           }""",
2742                           'If statement had no body and no else clause'
2743                           '  [whitespace/empty_if_body] [4]')
2744    self.TestMultiLineLint("""if (test,
2745                               func({})) {
2746                           }""",
2747                           'If statement had no body and no else clause'
2748                           '  [whitespace/empty_if_body] [4]')
2749    self.TestMultiLineLint("""if (test)
2750                             func();""", '')
2751    self.TestLint('if (test) { hello; }', '')
2752    self.TestLint('if (test({})) { hello; }', '')
2753    self.TestMultiLineLint("""if (test) {
2754                             func();
2755                           }""", '')
2756    self.TestMultiLineLint("""if (test) {
2757                             // multiline
2758                             // comment
2759                           }""", '')
2760    self.TestMultiLineLint("""if (test) {  // comment
2761                           }""", '')
2762    self.TestMultiLineLint("""if (test) {
2763                           } else {
2764                           }""", '')
2765    self.TestMultiLineLint("""if (func(p1,
2766                               p2,
2767                               p3)) {
2768                             func();
2769                           }""", '')
2770    self.TestMultiLineLint("""if (func({}, p1)) {
2771                             func();
2772                           }""", '')
2773
2774  def testSpacingForRangeBasedFor(self):
2775    # Basic correctly formatted case:
2776    self.TestLint('for (int i : numbers) {', '')
2777
2778    # Missing space before colon:
2779    self.TestLint('for (int i: numbers) {',
2780                  'Missing space around colon in range-based for loop'
2781                  '  [whitespace/forcolon] [2]')
2782    # Missing space after colon:
2783    self.TestLint('for (int i :numbers) {',
2784                  'Missing space around colon in range-based for loop'
2785                  '  [whitespace/forcolon] [2]')
2786    # Missing spaces both before and after the colon.
2787    self.TestLint('for (int i:numbers) {',
2788                  'Missing space around colon in range-based for loop'
2789                  '  [whitespace/forcolon] [2]')
2790
2791    # The scope operator '::' shouldn't cause warnings...
2792    self.TestLint('for (std::size_t i : sizes) {}', '')
2793    # ...but it shouldn't suppress them either.
2794    self.TestLint('for (std::size_t i: sizes) {}',
2795                  'Missing space around colon in range-based for loop'
2796                  '  [whitespace/forcolon] [2]')
2797
2798
2799  # Static or global STL strings.
2800  def testStaticOrGlobalSTLStrings(self):
2801    # A template for the error message for a const global/static string.
2802    error_msg = ('For a static/global string constant, use a C style '
2803                 'string instead: "%s[]".  [runtime/string] [4]')
2804
2805    # The error message for a non-const global/static string variable.
2806    nonconst_error_msg = ('Static/global string variables are not permitted.'
2807                          '  [runtime/string] [4]')
2808
2809    self.TestLint('string foo;',
2810                  nonconst_error_msg)
2811    self.TestLint('string kFoo = "hello";  // English',
2812                  nonconst_error_msg)
2813    self.TestLint('static string foo;',
2814                  nonconst_error_msg)
2815    self.TestLint('static const string foo;',
2816                  error_msg % 'static const char foo')
2817    self.TestLint('static const std::string foo;',
2818                  error_msg % 'static const char foo')
2819    self.TestLint('string Foo::bar;',
2820                  nonconst_error_msg)
2821
2822    self.TestLint('std::string foo;',
2823                  nonconst_error_msg)
2824    self.TestLint('std::string kFoo = "hello";  // English',
2825                  nonconst_error_msg)
2826    self.TestLint('static std::string foo;',
2827                  nonconst_error_msg)
2828    self.TestLint('static const std::string foo;',
2829                  error_msg % 'static const char foo')
2830    self.TestLint('std::string Foo::bar;',
2831                  nonconst_error_msg)
2832
2833    self.TestLint('::std::string foo;',
2834                  nonconst_error_msg)
2835    self.TestLint('::std::string kFoo = "hello";  // English',
2836                  nonconst_error_msg)
2837    self.TestLint('static ::std::string foo;',
2838                  nonconst_error_msg)
2839    self.TestLint('static const ::std::string foo;',
2840                  error_msg % 'static const char foo')
2841    self.TestLint('::std::string Foo::bar;',
2842                  nonconst_error_msg)
2843
2844    self.TestLint('string* pointer', '')
2845    self.TestLint('string *pointer', '')
2846    self.TestLint('string* pointer = Func();', '')
2847    self.TestLint('string *pointer = Func();', '')
2848    self.TestLint('const string* pointer', '')
2849    self.TestLint('const string *pointer', '')
2850    self.TestLint('const string* pointer = Func();', '')
2851    self.TestLint('const string *pointer = Func();', '')
2852    self.TestLint('string const* pointer', '')
2853    self.TestLint('string const *pointer', '')
2854    self.TestLint('string const* pointer = Func();', '')
2855    self.TestLint('string const *pointer = Func();', '')
2856    self.TestLint('string* const pointer', '')
2857    self.TestLint('string *const pointer', '')
2858    self.TestLint('string* const pointer = Func();', '')
2859    self.TestLint('string *const pointer = Func();', '')
2860    self.TestLint('string Foo::bar() {}', '')
2861    self.TestLint('string Foo::operator*() {}', '')
2862    # Rare case.
2863    self.TestLint('string foo("foobar");', nonconst_error_msg)
2864    # Should not catch local or member variables.
2865    self.TestLint('  string foo', '')
2866    # Should not catch functions.
2867    self.TestLint('string EmptyString() { return ""; }', '')
2868    self.TestLint('string EmptyString () { return ""; }', '')
2869    self.TestLint('string const& FileInfo::Pathname() const;', '')
2870    self.TestLint('string const &FileInfo::Pathname() const;', '')
2871    self.TestLint('string VeryLongNameFunctionSometimesEndsWith(\n'
2872                  '    VeryLongNameType very_long_name_variable) {}', '')
2873    self.TestLint('template<>\n'
2874                  'string FunctionTemplateSpecialization<SomeType>(\n'
2875                  '      int x) { return ""; }', '')
2876    self.TestLint('template<>\n'
2877                  'string FunctionTemplateSpecialization<vector<A::B>* >(\n'
2878                  '      int x) { return ""; }', '')
2879
2880    # should not catch methods of template classes.
2881    self.TestLint('string Class<Type>::Method() const {\n'
2882                  '  return "";\n'
2883                  '}\n', '')
2884    self.TestLint('string Class<Type>::Method(\n'
2885                  '   int arg) const {\n'
2886                  '  return "";\n'
2887                  '}\n', '')
2888
2889    # Check multiline cases.
2890    error_collector = ErrorCollector(self.assert_)
2891    cpplint.ProcessFileData('foo.cc', 'cc',
2892                            ['// Copyright 2014 Your Company.',
2893                             'string Class',
2894                             '::MemberFunction1();',
2895                             'string Class::',
2896                             'MemberFunction2();',
2897                             'string Class::',
2898                             'NestedClass::MemberFunction3();',
2899                             'string TemplateClass<T>::',
2900                             'NestedClass::MemberFunction4();',
2901                             'const string Class',
2902                             '::static_member_variable1;',
2903                             'const string Class::',
2904                             'static_member_variable2;',
2905                             'const string Class',
2906                             '::static_member_variable3 = "initial value";',
2907                             'const string Class::',
2908                             'static_member_variable4 = "initial value";',
2909                             'string Class::',
2910                             'static_member_variable5;',
2911                             ''],
2912                            error_collector)
2913    self.assertEquals(error_collector.Results(),
2914                      [error_msg % 'const char Class::static_member_variable1',
2915                       error_msg % 'const char Class::static_member_variable2',
2916                       error_msg % 'const char Class::static_member_variable3',
2917                       error_msg % 'const char Class::static_member_variable4',
2918                       nonconst_error_msg])
2919
2920  def testNoSpacesInFunctionCalls(self):
2921    self.TestLint('TellStory(1, 3);',
2922                  '')
2923    self.TestLint('TellStory(1, 3 );',
2924                  'Extra space before )'
2925                  '  [whitespace/parens] [2]')
2926    self.TestLint('TellStory(1 /* wolf */, 3 /* pigs */);',
2927                  '')
2928    self.TestMultiLineLint("""TellStory(1, 3
2929                                        );""",
2930                           'Closing ) should be moved to the previous line'
2931                           '  [whitespace/parens] [2]')
2932    self.TestMultiLineLint("""TellStory(Wolves(1),
2933                                        Pigs(3
2934                                        ));""",
2935                           'Closing ) should be moved to the previous line'
2936                           '  [whitespace/parens] [2]')
2937    self.TestMultiLineLint("""TellStory(1,
2938                                        3 );""",
2939                           'Extra space before )'
2940                           '  [whitespace/parens] [2]')
2941
2942  def testToDoComments(self):
2943    start_space = ('Too many spaces before TODO'
2944                   '  [whitespace/todo] [2]')
2945    missing_username = ('Missing username in TODO; it should look like '
2946                        '"// TODO(my_username): Stuff."'
2947                        '  [readability/todo] [2]')
2948    end_space = ('TODO(my_username) should be followed by a space'
2949                 '  [whitespace/todo] [2]')
2950
2951    self.TestLint('//   TODOfix this',
2952                  [start_space, missing_username, end_space])
2953    self.TestLint('//   TODO(ljenkins)fix this',
2954                  [start_space, end_space])
2955    self.TestLint('//   TODO fix this',
2956                  [start_space, missing_username])
2957    self.TestLint('// TODO fix this', missing_username)
2958    self.TestLint('// TODO: fix this', missing_username)
2959    self.TestLint('//TODO(ljenkins): Fix this',
2960                  'Should have a space between // and comment'
2961                  '  [whitespace/comments] [4]')
2962    self.TestLint('// TODO(ljenkins):Fix this', end_space)
2963    self.TestLint('// TODO(ljenkins):', '')
2964    self.TestLint('// TODO(ljenkins): fix this', '')
2965    self.TestLint('// TODO(ljenkins): Fix this', '')
2966    self.TestLint('#if 1  // TEST_URLTODOCID_WHICH_HAS_THAT_WORD_IN_IT_H_', '')
2967    self.TestLint('// See also similar TODO above', '')
2968    self.TestLint(r'EXPECT_EQ("\\", '
2969                  r'NormalizePath("/./../foo///bar/..//x/../..", ""));',
2970                  '')
2971
2972  def testTwoSpacesBetweenCodeAndComments(self):
2973    self.TestLint('} // namespace foo',
2974                  'At least two spaces is best between code and comments'
2975                  '  [whitespace/comments] [2]')
2976    self.TestLint('}// namespace foo',
2977                  'At least two spaces is best between code and comments'
2978                  '  [whitespace/comments] [2]')
2979    self.TestLint('printf("foo"); // Outside quotes.',
2980                  'At least two spaces is best between code and comments'
2981                  '  [whitespace/comments] [2]')
2982    self.TestLint('int i = 0;  // Having two spaces is fine.', '')
2983    self.TestLint('int i = 0;   // Having three spaces is OK.', '')
2984    self.TestLint('// Top level comment', '')
2985    self.TestLint('  // Line starts with two spaces.', '')
2986    self.TestMultiLineLint('void foo() {\n'
2987                           '  { // A scope is opening.\n'
2988                           '    int a;', '')
2989    self.TestMultiLineLint('void foo() {\n'
2990                           '  { // A scope is opening.\n'
2991                           '#define A a',
2992                           'At least two spaces is best between code and '
2993                           'comments  [whitespace/comments] [2]')
2994    self.TestMultiLineLint('  foo();\n'
2995                           '  { // An indented scope is opening.\n'
2996                           '    int a;', '')
2997    self.TestMultiLineLint('vector<int> my_elements = {// first\n'
2998                           '                           1,', '')
2999    self.TestMultiLineLint('vector<int> my_elements = {// my_elements is ..\n'
3000                           '    1,',
3001                           'At least two spaces is best between code and '
3002                           'comments  [whitespace/comments] [2]')
3003    self.TestLint('if (foo) { // not a pure scope; comment is too close!',
3004                  'At least two spaces is best between code and comments'
3005                  '  [whitespace/comments] [2]')
3006    self.TestLint('printf("// In quotes.")', '')
3007    self.TestLint('printf("\\"%s // In quotes.")', '')
3008    self.TestLint('printf("%s", "// In quotes.")', '')
3009
3010  def testSpaceAfterCommentMarker(self):
3011    self.TestLint('//', '')
3012    self.TestLint('//x', 'Should have a space between // and comment'
3013                  '  [whitespace/comments] [4]')
3014    self.TestLint('// x', '')
3015    self.TestLint('///', '')
3016    self.TestLint('/// x', '')
3017    self.TestLint('//!', '')
3018    self.TestLint('//----', '')
3019    self.TestLint('//====', '')
3020    self.TestLint('//////', '')
3021    self.TestLint('////// x', '')
3022    self.TestLint('///< x', '') # After-member Doxygen comment
3023    self.TestLint('//!< x', '') # After-member Doxygen comment
3024    self.TestLint('////x', 'Should have a space between // and comment'
3025                  '  [whitespace/comments] [4]')
3026    self.TestLint('//}', '')
3027    self.TestLint('//}x', 'Should have a space between // and comment'
3028                  '  [whitespace/comments] [4]')
3029    self.TestLint('//!<x', 'Should have a space between // and comment'
3030                  '  [whitespace/comments] [4]')
3031    self.TestLint('///<x', 'Should have a space between // and comment'
3032                  '  [whitespace/comments] [4]')
3033
3034  # Test a line preceded by empty or comment lines.  There was a bug
3035  # that caused it to print the same warning N times if the erroneous
3036  # line was preceded by N lines of empty or comment lines.  To be
3037  # precise, the '// marker so line numbers and indices both start at
3038  # 1' line was also causing the issue.
3039  def testLinePrecededByEmptyOrCommentLines(self):
3040    def DoTest(self, lines):
3041      error_collector = ErrorCollector(self.assert_)
3042      cpplint.ProcessFileData('foo.cc', 'cc', lines, error_collector)
3043      # The warning appears only once.
3044      self.assertEquals(
3045          1,
3046          error_collector.Results().count(
3047              'Do not use namespace using-directives.  '
3048              'Use using-declarations instead.'
3049              '  [build/namespaces] [5]'))
3050    DoTest(self, ['using namespace foo;'])
3051    DoTest(self, ['', '', '', 'using namespace foo;'])
3052    DoTest(self, ['// hello', 'using namespace foo;'])
3053
3054  def testNewlineAtEOF(self):
3055    def DoTest(self, data, is_missing_eof):
3056      error_collector = ErrorCollector(self.assert_)
3057      cpplint.ProcessFileData('foo.cc', 'cc', data.split('\n'),
3058                              error_collector)
3059      # The warning appears only once.
3060      self.assertEquals(
3061          int(is_missing_eof),
3062          error_collector.Results().count(
3063              'Could not find a newline character at the end of the file.'
3064              '  [whitespace/ending_newline] [5]'))
3065
3066    DoTest(self, '// Newline\n// at EOF\n', False)
3067    DoTest(self, '// No newline\n// at EOF', True)
3068
3069  def testInvalidUtf8(self):
3070    def DoTest(self, raw_bytes, has_invalid_utf8):
3071      error_collector = ErrorCollector(self.assert_)
3072      cpplint.ProcessFileData(
3073          'foo.cc', 'cc',
3074          unicode(raw_bytes, 'utf8', 'replace').split('\n'),
3075          error_collector)
3076      # The warning appears only once.
3077      self.assertEquals(
3078          int(has_invalid_utf8),
3079          error_collector.Results().count(
3080              'Line contains invalid UTF-8'
3081              ' (or Unicode replacement character).'
3082              '  [readability/utf8] [5]'))
3083
3084    DoTest(self, 'Hello world\n', False)
3085    DoTest(self, '\xe9\x8e\xbd\n', False)
3086    DoTest(self, '\xe9x\x8e\xbd\n', True)
3087    # This is the encoding of the replacement character itself (which
3088    # you can see by evaluating codecs.getencoder('utf8')(u'\ufffd')).
3089    DoTest(self, '\xef\xbf\xbd\n', True)
3090
3091  def testBadCharacters(self):
3092    # Test for NUL bytes only
3093    error_collector = ErrorCollector(self.assert_)
3094    cpplint.ProcessFileData('nul.cc', 'cc',
3095                            ['// Copyright 2014 Your Company.',
3096                             '\0', ''], error_collector)
3097    self.assertEquals(
3098        error_collector.Results(),
3099        'Line contains NUL byte.  [readability/nul] [5]')
3100
3101    # Make sure both NUL bytes and UTF-8 are caught if they appear on
3102    # the same line.
3103    error_collector = ErrorCollector(self.assert_)
3104    cpplint.ProcessFileData(
3105        'nul_utf8.cc', 'cc',
3106        ['// Copyright 2014 Your Company.',
3107         unicode('\xe9x\0', 'utf8', 'replace'), ''],
3108        error_collector)
3109    self.assertEquals(
3110        error_collector.Results(),
3111        ['Line contains invalid UTF-8 (or Unicode replacement character).'
3112         '  [readability/utf8] [5]',
3113         'Line contains NUL byte.  [readability/nul] [5]'])
3114
3115  def testIsBlankLine(self):
3116    self.assert_(cpplint.IsBlankLine(''))
3117    self.assert_(cpplint.IsBlankLine(' '))
3118    self.assert_(cpplint.IsBlankLine(' \t\r\n'))
3119    self.assert_(not cpplint.IsBlankLine('int a;'))
3120    self.assert_(not cpplint.IsBlankLine('{'))
3121
3122  def testBlankLinesCheck(self):
3123    self.TestBlankLinesCheck(['{\n', '\n', '\n', '}\n'], 1, 1)
3124    self.TestBlankLinesCheck(['  if (foo) {\n', '\n', '  }\n'], 1, 1)
3125    self.TestBlankLinesCheck(
3126        ['\n', '// {\n', '\n', '\n', '// Comment\n', '{\n', '}\n'], 0, 0)
3127    self.TestBlankLinesCheck(['\n', 'run("{");\n', '\n'], 0, 0)
3128    self.TestBlankLinesCheck(['\n', '  if (foo) { return 0; }\n', '\n'], 0, 0)
3129    self.TestBlankLinesCheck(
3130        ['int x(\n', '    int a) {\n', '\n', 'return 0;\n', '}'], 0, 0)
3131    self.TestBlankLinesCheck(
3132        ['int x(\n', '    int a) const {\n', '\n', 'return 0;\n', '}'], 0, 0)
3133    self.TestBlankLinesCheck(
3134        ['int x(\n', '     int a) {\n', '\n', 'return 0;\n', '}'], 1, 0)
3135    self.TestBlankLinesCheck(
3136        ['int x(\n', '   int a) {\n', '\n', 'return 0;\n', '}'], 1, 0)
3137
3138  def testAllowBlankLineBeforeClosingNamespace(self):
3139    error_collector = ErrorCollector(self.assert_)
3140    cpplint.ProcessFileData('foo.cc', 'cc',
3141                            ['namespace {',
3142                             '',
3143                             '}  // namespace',
3144                             'namespace another_namespace {',
3145                             '',
3146                             '}',
3147                             'namespace {',
3148                             '',
3149                             'template<class T, ',
3150                             '         class A = hoge<T>, ',
3151                             '         class B = piyo<T>, ',
3152                             '         class C = fuga<T> >',
3153                             'class D {',
3154                             ' public:',
3155                             '};',
3156                             '', '', '', '',
3157                             '}'],
3158                            error_collector)
3159    self.assertEquals(0, error_collector.Results().count(
3160        'Redundant blank line at the end of a code block should be deleted.'
3161        '  [whitespace/blank_line] [3]'))
3162
3163  def testAllowBlankLineBeforeIfElseChain(self):
3164    error_collector = ErrorCollector(self.assert_)
3165    cpplint.ProcessFileData('foo.cc', 'cc',
3166                            ['if (hoge) {',
3167                             '',  # No warning
3168                             '} else if (piyo) {',
3169                             '',  # No warning
3170                             '} else if (piyopiyo) {',
3171                             '  hoge = true;',  # No warning
3172                             '} else {',
3173                             '',  # Warning on this line
3174                             '}'],
3175                            error_collector)
3176    self.assertEquals(1, error_collector.Results().count(
3177        'Redundant blank line at the end of a code block should be deleted.'
3178        '  [whitespace/blank_line] [3]'))
3179
3180  def testAllowBlankLineAfterExtern(self):
3181    error_collector = ErrorCollector(self.assert_)
3182    cpplint.ProcessFileData('foo.cc', 'cc',
3183                            ['extern "C" {',
3184                             '',
3185                             'EXPORTAPI void APICALL Some_function() {}',
3186                             '',
3187                             '}'],
3188                            error_collector)
3189    self.assertEquals(0, error_collector.Results().count(
3190        'Redundant blank line at the start of a code block should be deleted.'
3191        '  [whitespace/blank_line] [2]'))
3192    self.assertEquals(0, error_collector.Results().count(
3193        'Redundant blank line at the end of a code block should be deleted.'
3194        '  [whitespace/blank_line] [3]'))
3195
3196  def testBlankLineBeforeSectionKeyword(self):
3197    error_collector = ErrorCollector(self.assert_)
3198    cpplint.ProcessFileData('foo.cc', 'cc',
3199                            ['class A {',
3200                             ' public:',
3201                             ' protected:',   # warning 1
3202                             ' private:',     # warning 2
3203                             '  struct B {',
3204                             '   public:',
3205                             '   private:'] +  # warning 3
3206                            ([''] * 100) +  # Make A and B longer than 100 lines
3207                            ['  };',
3208                             '  struct C {',
3209                             '   protected:',
3210                             '   private:',  # C is too short for warnings
3211                             '  };',
3212                             '};',
3213                             'class D',
3214                             '    : public {',
3215                             ' public:',  # no warning
3216                             '};',
3217                             'class E {\\',
3218                             ' public:\\'] +
3219                            (['\\'] * 100) +  # Makes E > 100 lines
3220                            ['  int non_empty_line;\\',
3221                             ' private:\\',   # no warning
3222                             '  int a;\\',
3223                             '};'],
3224                            error_collector)
3225    self.assertEquals(2, error_collector.Results().count(
3226        '"private:" should be preceded by a blank line'
3227        '  [whitespace/blank_line] [3]'))
3228    self.assertEquals(1, error_collector.Results().count(
3229        '"protected:" should be preceded by a blank line'
3230        '  [whitespace/blank_line] [3]'))
3231
3232  def testNoBlankLineAfterSectionKeyword(self):
3233    error_collector = ErrorCollector(self.assert_)
3234    cpplint.ProcessFileData('foo.cc', 'cc',
3235                            ['class A {',
3236                             ' public:',
3237                             '',  # warning 1
3238                             ' private:',
3239                             '',  # warning 2
3240                             '  struct B {',
3241                             '   protected:',
3242                             '',  # warning 3
3243                             '  };',
3244                             '};'],
3245                            error_collector)
3246    self.assertEquals(1, error_collector.Results().count(
3247        'Do not leave a blank line after "public:"'
3248        '  [whitespace/blank_line] [3]'))
3249    self.assertEquals(1, error_collector.Results().count(
3250        'Do not leave a blank line after "protected:"'
3251        '  [whitespace/blank_line] [3]'))
3252    self.assertEquals(1, error_collector.Results().count(
3253        'Do not leave a blank line after "private:"'
3254        '  [whitespace/blank_line] [3]'))
3255
3256  def testAllowBlankLinesInRawStrings(self):
3257    error_collector = ErrorCollector(self.assert_)
3258    cpplint.ProcessFileData('foo.cc', 'cc',
3259                            ['// Copyright 2014 Your Company.',
3260                             'static const char *kData[] = {R"(',
3261                             '',
3262                             ')", R"(',
3263                             '',
3264                             ')"};',
3265                             ''],
3266                            error_collector)
3267    self.assertEquals('', error_collector.Results())
3268
3269  def testElseOnSameLineAsClosingBraces(self):
3270    error_collector = ErrorCollector(self.assert_)
3271    cpplint.ProcessFileData('foo.cc', 'cc',
3272                            ['if (hoge) {',
3273                             '}',
3274                             'else if (piyo) {',  # Warning on this line
3275                             '}',
3276                             ' else {'  # Warning on this line
3277                             '',
3278                             '}'],
3279                            error_collector)
3280    self.assertEquals(2, error_collector.Results().count(
3281        'An else should appear on the same line as the preceding }'
3282        '  [whitespace/newline] [4]'))
3283
3284    error_collector = ErrorCollector(self.assert_)
3285    cpplint.ProcessFileData('foo.cc', 'cc',
3286                            ['if (hoge) {',
3287                             '',
3288                             '}',
3289                             'else',  # Warning on this line
3290                             '{',
3291                             '',
3292                             '}'],
3293                            error_collector)
3294    self.assertEquals(1, error_collector.Results().count(
3295        'An else should appear on the same line as the preceding }'
3296        '  [whitespace/newline] [4]'))
3297
3298    error_collector = ErrorCollector(self.assert_)
3299    cpplint.ProcessFileData('foo.cc', 'cc',
3300                            ['if (hoge) {',
3301                             '',
3302                             '}',
3303                             'else_function();'],
3304                            error_collector)
3305    self.assertEquals(0, error_collector.Results().count(
3306        'An else should appear on the same line as the preceding }'
3307        '  [whitespace/newline] [4]'))
3308
3309  def testMultipleStatementsOnSameLine(self):
3310    error_collector = ErrorCollector(self.assert_)
3311    cpplint.ProcessFileData('foo.cc', 'cc',
3312                            ['for (int i = 0; i < 1; i++) {}',
3313                             'switch (x) {',
3314                             '  case 0: func(); break; ',
3315                             '}',
3316                             'sum += MathUtil::SafeIntRound(x); x += 0.1;'],
3317                            error_collector)
3318    self.assertEquals(0, error_collector.Results().count(
3319        'More than one command on the same line  [whitespace/newline] [0]'))
3320
3321    old_verbose_level = cpplint._cpplint_state.verbose_level
3322    cpplint._cpplint_state.verbose_level = 0
3323    cpplint.ProcessFileData('foo.cc', 'cc',
3324                            ['sum += MathUtil::SafeIntRound(x); x += 0.1;'],
3325                            error_collector)
3326    cpplint._cpplint_state.verbose_level = old_verbose_level
3327
3328  def testEndOfNamespaceComments(self):
3329    error_collector = ErrorCollector(self.assert_)
3330    cpplint.ProcessFileData('foo.cc', 'cc',
3331                            ['namespace {',
3332                             '',
3333                             '}',  # No warning (too short)
3334                             'namespace expected {',
3335                             '}  // namespace mismatched',  # Warning here
3336                             'namespace {',
3337                             '}  // namespace mismatched',  # Warning here
3338                             'namespace outer { namespace nested {'] +
3339                            ([''] * 10) +
3340                            ['}',  # Warning here
3341                             '}',  # Warning here
3342                             'namespace {'] +
3343                            ([''] * 10) +
3344                            ['}',  # Warning here
3345                             'namespace {'] +
3346                            ([''] * 10) +
3347                            ['}  // namespace some description',  # Anon warning
3348                             'namespace {'] +
3349                            ([''] * 10) +
3350                            ['}  // namespace anonymous',  # Variant warning
3351                             'namespace {'] +
3352                            ([''] * 10) +
3353                            ['}  // anonymous namespace (utils)',  # Variant
3354                             'namespace {'] +
3355                            ([''] * 10) +
3356                            ['}  // anonymous namespace',  # No warning
3357                             'namespace missing_comment {'] +
3358                            ([''] * 10) +
3359                            ['}',  # Warning here
3360                             'namespace no_warning {'] +
3361                            ([''] * 10) +
3362                            ['}  // namespace no_warning',
3363                             'namespace no_warning {'] +
3364                            ([''] * 10) +
3365                            ['};  // end namespace no_warning',
3366                             '#define MACRO \\',
3367                             'namespace c_style { \\'] +
3368                            (['\\'] * 10) +
3369                            ['}  /* namespace c_style. */ \\',
3370                             ';'],
3371                            error_collector)
3372    self.assertEquals(1, error_collector.Results().count(
3373        'Namespace should be terminated with "// namespace expected"'
3374        '  [readability/namespace] [5]'))
3375    self.assertEquals(1, error_collector.Results().count(
3376        'Namespace should be terminated with "// namespace outer"'
3377        '  [readability/namespace] [5]'))
3378    self.assertEquals(1, error_collector.Results().count(
3379        'Namespace should be terminated with "// namespace nested"'
3380        '  [readability/namespace] [5]'))
3381    self.assertEquals(3, error_collector.Results().count(
3382        'Anonymous namespace should be terminated with "// namespace"'
3383        '  [readability/namespace] [5]'))
3384    self.assertEquals(2, error_collector.Results().count(
3385        'Anonymous namespace should be terminated with "// namespace" or'
3386        ' "// anonymous namespace"'
3387        '  [readability/namespace] [5]'))
3388    self.assertEquals(1, error_collector.Results().count(
3389        'Namespace should be terminated with "// namespace missing_comment"'
3390        '  [readability/namespace] [5]'))
3391    self.assertEquals(0, error_collector.Results().count(
3392        'Namespace should be terminated with "// namespace no_warning"'
3393        '  [readability/namespace] [5]'))
3394
3395  def testElseClauseNotOnSameLineAsElse(self):
3396    self.TestLint('  else DoSomethingElse();',
3397                  'Else clause should never be on same line as else '
3398                  '(use 2 lines)  [whitespace/newline] [4]')
3399    self.TestLint('  else ifDoSomethingElse();',
3400                  'Else clause should never be on same line as else '
3401                  '(use 2 lines)  [whitespace/newline] [4]')
3402    self.TestLint('  } else if (blah) {', '')
3403    self.TestLint('  variable_ends_in_else = true;', '')
3404
3405  def testComma(self):
3406    self.TestLint('a = f(1,2);',
3407                  'Missing space after ,  [whitespace/comma] [3]')
3408    self.TestLint('int tmp=a,a=b,b=tmp;',
3409                  ['Missing spaces around =  [whitespace/operators] [4]',
3410                   'Missing space after ,  [whitespace/comma] [3]'])
3411    self.TestLint('f(a, /* name */ b);', '')
3412    self.TestLint('f(a, /* name */b);', '')
3413    self.TestLint('f(a, /* name */-1);', '')
3414    self.TestLint('f(a, /* name */"1");', '')
3415    self.TestLint('f(1, /* empty macro arg */, 2)', '')
3416    self.TestLint('f(1,, 2)', '')
3417    self.TestLint('operator,()', '')
3418    self.TestLint('operator,(a,b)',
3419                  'Missing space after ,  [whitespace/comma] [3]')
3420
3421  def testEqualsOperatorSpacing(self):
3422    self.TestLint('int tmp= a;',
3423                  'Missing spaces around =  [whitespace/operators] [4]')
3424    self.TestLint('int tmp =a;',
3425                  'Missing spaces around =  [whitespace/operators] [4]')
3426    self.TestLint('int tmp=a;',
3427                  'Missing spaces around =  [whitespace/operators] [4]')
3428    self.TestLint('int tmp= 7;',
3429                  'Missing spaces around =  [whitespace/operators] [4]')
3430    self.TestLint('int tmp =7;',
3431                  'Missing spaces around =  [whitespace/operators] [4]')
3432    self.TestLint('int tmp=7;',
3433                  'Missing spaces around =  [whitespace/operators] [4]')
3434    self.TestLint('int* tmp=*p;',
3435                  'Missing spaces around =  [whitespace/operators] [4]')
3436    self.TestLint('int* tmp= *p;',
3437                  'Missing spaces around =  [whitespace/operators] [4]')
3438    self.TestMultiLineLint(
3439        TrimExtraIndent('''
3440            lookahead_services_=
3441              ::strings::Split(FLAGS_ls, ",", ::strings::SkipEmpty());'''),
3442        'Missing spaces around =  [whitespace/operators] [4]')
3443    self.TestLint('bool result = a>=42;',
3444                  'Missing spaces around >=  [whitespace/operators] [3]')
3445    self.TestLint('bool result = a<=42;',
3446                  'Missing spaces around <=  [whitespace/operators] [3]')
3447    self.TestLint('bool result = a==42;',
3448                  'Missing spaces around ==  [whitespace/operators] [3]')
3449    self.TestLint('auto result = a!=42;',
3450                  'Missing spaces around !=  [whitespace/operators] [3]')
3451    self.TestLint('int a = b!=c;',
3452                  'Missing spaces around !=  [whitespace/operators] [3]')
3453    self.TestLint('a&=42;', '')
3454    self.TestLint('a|=42;', '')
3455    self.TestLint('a^=42;', '')
3456    self.TestLint('a+=42;', '')
3457    self.TestLint('a*=42;', '')
3458    self.TestLint('a/=42;', '')
3459    self.TestLint('a%=42;', '')
3460    self.TestLint('a>>=5;', '')
3461    self.TestLint('a<<=5;', '')
3462
3463  def testShiftOperatorSpacing(self):
3464    self.TestLint('a<<b',
3465                  'Missing spaces around <<  [whitespace/operators] [3]')
3466    self.TestLint('a>>b',
3467                  'Missing spaces around >>  [whitespace/operators] [3]')
3468    self.TestLint('1<<20', '')
3469    self.TestLint('1024>>10', '')
3470    self.TestLint('Kernel<<<1, 2>>>()', '')
3471
3472  def testIndent(self):
3473    self.TestLint('static int noindent;', '')
3474    self.TestLint('  int two_space_indent;', '')
3475    self.TestLint('    int four_space_indent;', '')
3476    self.TestLint(' int one_space_indent;',
3477                  'Weird number of spaces at line-start.  '
3478                  'Are you using a 2-space indent?  [whitespace/indent] [3]')
3479    self.TestLint('   int three_space_indent;',
3480                  'Weird number of spaces at line-start.  '
3481                  'Are you using a 2-space indent?  [whitespace/indent] [3]')
3482    self.TestLint(' char* one_space_indent = "public:";',
3483                  'Weird number of spaces at line-start.  '
3484                  'Are you using a 2-space indent?  [whitespace/indent] [3]')
3485    self.TestLint(' public:', '')
3486    self.TestLint('  protected:', '')
3487    self.TestLint('   private:', '')
3488    self.TestLint(' protected: \\', '')
3489    self.TestLint('  public:      \\', '')
3490    self.TestLint('   private:   \\', '')
3491    self.TestMultiLineLint(
3492        TrimExtraIndent("""
3493            class foo {
3494             public slots:
3495              void bar();
3496            };"""),
3497        'Weird number of spaces at line-start.  '
3498        'Are you using a 2-space indent?  [whitespace/indent] [3]')
3499    self.TestMultiLineLint(
3500        TrimExtraIndent('''
3501            static const char kRawString[] = R"("
3502             ")";'''),
3503        '')
3504    self.TestMultiLineLint(
3505        TrimExtraIndent('''
3506            KV<Query,
3507               Tuple<TaxonomyId, PetacatCategoryId, double>>'''),
3508        '')
3509    self.TestMultiLineLint(
3510        ' static const char kSingleLineRawString[] = R"(...)";',
3511        'Weird number of spaces at line-start.  '
3512        'Are you using a 2-space indent?  [whitespace/indent] [3]')
3513
3514  def testSectionIndent(self):
3515    self.TestMultiLineLint(
3516        """
3517        class A {
3518         public:  // no warning
3519          private:  // warning here
3520        };""",
3521        'private: should be indented +1 space inside class A'
3522        '  [whitespace/indent] [3]')
3523    self.TestMultiLineLint(
3524        """
3525        class B {
3526         public:  // no warning
3527          template<> struct C {
3528            public:    // warning here
3529           protected:  // no warning
3530          };
3531        };""",
3532        'public: should be indented +1 space inside struct C'
3533        '  [whitespace/indent] [3]')
3534    self.TestMultiLineLint(
3535        """
3536        struct D {
3537         };""",
3538        'Closing brace should be aligned with beginning of struct D'
3539        '  [whitespace/indent] [3]')
3540    self.TestMultiLineLint(
3541        """
3542         template<typename E> class F {
3543        };""",
3544        'Closing brace should be aligned with beginning of class F'
3545        '  [whitespace/indent] [3]')
3546    self.TestMultiLineLint(
3547        """
3548        class G {
3549          Q_OBJECT
3550        public slots:
3551        signals:
3552        };""",
3553        ['public slots: should be indented +1 space inside class G'
3554         '  [whitespace/indent] [3]',
3555         'signals: should be indented +1 space inside class G'
3556         '  [whitespace/indent] [3]'])
3557    self.TestMultiLineLint(
3558        """
3559        class H {
3560          /* comments */ class I {
3561           public:  // no warning
3562            private:  // warning here
3563          };
3564        };""",
3565        'private: should be indented +1 space inside class I'
3566        '  [whitespace/indent] [3]')
3567    self.TestMultiLineLint(
3568        """
3569        class J
3570            : public ::K {
3571         public:  // no warning
3572          protected:  // warning here
3573        };""",
3574        'protected: should be indented +1 space inside class J'
3575        '  [whitespace/indent] [3]')
3576    self.TestMultiLineLint(
3577        """
3578        class L
3579            : public M,
3580              public ::N {
3581        };""",
3582        '')
3583    self.TestMultiLineLint(
3584        """
3585        template <class O,
3586                  class P,
3587                  class Q,
3588                  typename R>
3589        static void Func() {
3590        }""",
3591        '')
3592
3593  def testConditionals(self):
3594    self.TestMultiLineLint(
3595        """
3596        if (foo)
3597          goto fail;
3598          goto fail;""",
3599        'If/else bodies with multiple statements require braces'
3600        '  [readability/braces] [4]')
3601    self.TestMultiLineLint(
3602        """
3603        if (foo)
3604          goto fail; goto fail;""",
3605        'If/else bodies with multiple statements require braces'
3606        '  [readability/braces] [4]')
3607    self.TestMultiLineLint(
3608        """
3609        if (foo)
3610          foo;
3611        else
3612          goto fail;
3613          goto fail;""",
3614        'If/else bodies with multiple statements require braces'
3615        '  [readability/braces] [4]')
3616    self.TestMultiLineLint(
3617        """
3618        if (foo) goto fail;
3619          goto fail;""",
3620        'If/else bodies with multiple statements require braces'
3621        '  [readability/braces] [4]')
3622    self.TestMultiLineLint(
3623        """
3624        if (foo)
3625          if (bar)
3626            baz;
3627          else
3628            qux;""",
3629        'Else clause should be indented at the same level as if. Ambiguous'
3630        ' nested if/else chains require braces.  [readability/braces] [4]')
3631    self.TestMultiLineLint(
3632        """
3633        if (foo)
3634          if (bar)
3635            baz;
3636        else
3637          qux;""",
3638        'Else clause should be indented at the same level as if. Ambiguous'
3639        ' nested if/else chains require braces.  [readability/braces] [4]')
3640    self.TestMultiLineLint(
3641        """
3642        if (foo) {
3643          bar;
3644          baz;
3645        } else
3646          qux;""",
3647        'If an else has a brace on one side, it should have it on both'
3648        '  [readability/braces] [5]')
3649    self.TestMultiLineLint(
3650        """
3651        if (foo)
3652          bar;
3653        else {
3654          baz;
3655        }""",
3656        'If an else has a brace on one side, it should have it on both'
3657        '  [readability/braces] [5]')
3658    self.TestMultiLineLint(
3659        """
3660        if (foo)
3661          bar;
3662        else if (baz) {
3663          qux;
3664        }""",
3665        'If an else has a brace on one side, it should have it on both'
3666        '  [readability/braces] [5]')
3667    self.TestMultiLineLint(
3668        """
3669        if (foo) {
3670          bar;
3671        } else if (baz)
3672          qux;""",
3673        'If an else has a brace on one side, it should have it on both'
3674        '  [readability/braces] [5]')
3675    self.TestMultiLineLint(
3676        """
3677        if (foo)
3678          goto fail;
3679        bar;""",
3680        '')
3681    self.TestMultiLineLint(
3682        """
3683        if (foo
3684            && bar) {
3685          baz;
3686          qux;
3687        }""",
3688        '')
3689    self.TestMultiLineLint(
3690        """
3691        if (foo)
3692          goto
3693            fail;""",
3694        '')
3695    self.TestMultiLineLint(
3696        """
3697        if (foo)
3698          bar;
3699        else
3700          baz;
3701        qux;""",
3702        '')
3703    self.TestMultiLineLint(
3704        """
3705        for (;;) {
3706          if (foo)
3707            bar;
3708          else
3709            baz;
3710        }""",
3711        '')
3712    self.TestMultiLineLint(
3713        """
3714        if (foo)
3715          bar;
3716        else if (baz)
3717          baz;""",
3718        '')
3719    self.TestMultiLineLint(
3720        """
3721        if (foo)
3722          bar;
3723        else
3724          baz;""",
3725        '')
3726    self.TestMultiLineLint(
3727        """
3728        if (foo) {
3729          bar;
3730        } else {
3731          baz;
3732        }""",
3733        '')
3734    self.TestMultiLineLint(
3735        """
3736        if (foo) {
3737          bar;
3738        } else if (baz) {
3739          qux;
3740        }""",
3741        '')
3742    # Note: this is an error for a different reason, but should not trigger the
3743    # single-line if error.
3744    self.TestMultiLineLint(
3745        """
3746        if (foo)
3747        {
3748          bar;
3749          baz;
3750        }""",
3751        '{ should almost always be at the end of the previous line'
3752        '  [whitespace/braces] [4]')
3753    self.TestMultiLineLint(
3754        """
3755        if (foo) { \\
3756          bar; \\
3757          baz; \\
3758        }""",
3759        '')
3760    self.TestMultiLineLint(
3761        """
3762        void foo() { if (bar) baz; }""",
3763        '')
3764    self.TestMultiLineLint(
3765        """
3766        #if foo
3767          bar;
3768        #else
3769          baz;
3770          qux;
3771        #endif""",
3772        '')
3773    self.TestMultiLineLint(
3774        """void F() {
3775          variable = [] { if (true); };
3776          variable =
3777              [] { if (true); };
3778          Call(
3779              [] { if (true); },
3780              [] { if (true); });
3781        }""",
3782        '')
3783
3784  def testTab(self):
3785    self.TestLint('\tint a;',
3786                  'Tab found; better to use spaces  [whitespace/tab] [1]')
3787    self.TestLint('int a = 5;\t\t// set a to 5',
3788                  'Tab found; better to use spaces  [whitespace/tab] [1]')
3789
3790  def testParseArguments(self):
3791    old_usage = cpplint._USAGE
3792    old_error_categories = cpplint._ERROR_CATEGORIES
3793    old_output_format = cpplint._cpplint_state.output_format
3794    old_verbose_level = cpplint._cpplint_state.verbose_level
3795    old_headers = cpplint._hpp_headers
3796    old_filters = cpplint._cpplint_state.filters
3797    old_line_length = cpplint._line_length
3798    old_valid_extensions = cpplint._valid_extensions
3799    try:
3800      # Don't print usage during the tests, or filter categories
3801      cpplint._USAGE = ''
3802      cpplint._ERROR_CATEGORIES = ''
3803
3804      self.assertRaises(SystemExit, cpplint.ParseArguments, [])
3805      self.assertRaises(SystemExit, cpplint.ParseArguments, ['--badopt'])
3806      self.assertRaises(SystemExit, cpplint.ParseArguments, ['--help'])
3807      self.assertRaises(SystemExit, cpplint.ParseArguments, ['--v=0'])
3808      self.assertRaises(SystemExit, cpplint.ParseArguments, ['--filter='])
3809      # This is illegal because all filters must start with + or -
3810      self.assertRaises(SystemExit, cpplint.ParseArguments, ['--filter=foo'])
3811      self.assertRaises(SystemExit, cpplint.ParseArguments,
3812                        ['--filter=+a,b,-c'])
3813      self.assertRaises(SystemExit, cpplint.ParseArguments, ['--headers'])
3814
3815      self.assertEquals(['foo.cc'], cpplint.ParseArguments(['foo.cc']))
3816      self.assertEquals(old_output_format, cpplint._cpplint_state.output_format)
3817      self.assertEquals(old_verbose_level, cpplint._cpplint_state.verbose_level)
3818
3819      self.assertEquals(['foo.cc'],
3820                        cpplint.ParseArguments(['--v=1', 'foo.cc']))
3821      self.assertEquals(1, cpplint._cpplint_state.verbose_level)
3822      self.assertEquals(['foo.h'],
3823                        cpplint.ParseArguments(['--v=3', 'foo.h']))
3824      self.assertEquals(3, cpplint._cpplint_state.verbose_level)
3825      self.assertEquals(['foo.cpp'],
3826                        cpplint.ParseArguments(['--verbose=5', 'foo.cpp']))
3827      self.assertEquals(5, cpplint._cpplint_state.verbose_level)
3828      self.assertRaises(ValueError,
3829                        cpplint.ParseArguments, ['--v=f', 'foo.cc'])
3830
3831      self.assertEquals(['foo.cc'],
3832                        cpplint.ParseArguments(['--output=emacs', 'foo.cc']))
3833      self.assertEquals('emacs', cpplint._cpplint_state.output_format)
3834      self.assertEquals(['foo.h'],
3835                        cpplint.ParseArguments(['--output=vs7', 'foo.h']))
3836      self.assertEquals('vs7', cpplint._cpplint_state.output_format)
3837      self.assertRaises(SystemExit,
3838                        cpplint.ParseArguments, ['--output=blah', 'foo.cc'])
3839
3840      filt = '-,+whitespace,-whitespace/indent'
3841      self.assertEquals(['foo.h'],
3842                        cpplint.ParseArguments(['--filter='+filt, 'foo.h']))
3843      self.assertEquals(['-', '+whitespace', '-whitespace/indent'],
3844                        cpplint._cpplint_state.filters)
3845
3846      self.assertEquals(['foo.cc', 'foo.h'],
3847                        cpplint.ParseArguments(['foo.cc', 'foo.h']))
3848
3849      self.assertEqual(['foo.h'],
3850                       cpplint.ParseArguments(['--linelength=120', 'foo.h']))
3851      self.assertEqual(120, cpplint._line_length)
3852
3853      self.assertEqual(['foo.h'],
3854                       cpplint.ParseArguments(['--extensions=hpp,cpp,cpp', 'foo.h']))
3855      self.assertEqual(set(['hpp', 'cpp']), cpplint._valid_extensions)
3856
3857      self.assertEqual(set(['h']), cpplint._hpp_headers)  # Default value
3858      self.assertEqual(['foo.h'],
3859                       cpplint.ParseArguments(['--extensions=cpp,cpp', '--headers=hpp,h', 'foo.h']))
3860      self.assertEqual(set(['hpp', 'h']), cpplint._hpp_headers)
3861      self.assertEqual(set(['hpp', 'h', 'cpp']), cpplint._valid_extensions)
3862
3863    finally:
3864      cpplint._USAGE = old_usage
3865      cpplint._ERROR_CATEGORIES = old_error_categories
3866      cpplint._cpplint_state.output_format = old_output_format
3867      cpplint._cpplint_state.verbose_level = old_verbose_level
3868      cpplint._cpplint_state.filters = old_filters
3869      cpplint._line_length = old_line_length
3870      cpplint._valid_extensions = old_valid_extensions
3871      cpplint._hpp_headers = old_headers
3872
3873  def testLineLength(self):
3874    old_line_length = cpplint._line_length
3875    try:
3876      cpplint._line_length = 80
3877      self.TestLint(
3878          '// H %s' % ('H' * 75),
3879          '')
3880      self.TestLint(
3881          '// H %s' % ('H' * 76),
3882          'Lines should be <= 80 characters long'
3883          '  [whitespace/line_length] [2]')
3884      cpplint._line_length = 120
3885      self.TestLint(
3886          '// H %s' % ('H' * 115),
3887          '')
3888      self.TestLint(
3889          '// H %s' % ('H' * 116),
3890          'Lines should be <= 120 characters long'
3891          '  [whitespace/line_length] [2]')
3892    finally:
3893      cpplint._line_length = old_line_length
3894
3895  def testFilter(self):
3896    old_filters = cpplint._cpplint_state.filters
3897    try:
3898      cpplint._cpplint_state.SetFilters('-,+whitespace,-whitespace/indent')
3899      self.TestLint(
3900          '// Hello there ',
3901          'Line ends in whitespace.  Consider deleting these extra spaces.'
3902          '  [whitespace/end_of_line] [4]')
3903      self.TestLint('int a = (int)1.0;', '')
3904      self.TestLint(' weird opening space', '')
3905    finally:
3906      cpplint._cpplint_state.filters = old_filters
3907
3908  def testDefaultFilter(self):
3909    default_filters = cpplint._DEFAULT_FILTERS
3910    old_filters = cpplint._cpplint_state.filters
3911    cpplint._DEFAULT_FILTERS = ['-whitespace']
3912    try:
3913      # Reset filters
3914      cpplint._cpplint_state.SetFilters('')
3915      self.TestLint('// Hello there ', '')
3916      cpplint._cpplint_state.SetFilters('+whitespace/end_of_line')
3917      self.TestLint(
3918          '// Hello there ',
3919          'Line ends in whitespace.  Consider deleting these extra spaces.'
3920          '  [whitespace/end_of_line] [4]')
3921      self.TestLint(' weird opening space', '')
3922    finally:
3923      cpplint._cpplint_state.filters = old_filters
3924      cpplint._DEFAULT_FILTERS = default_filters
3925
3926  def testDuplicateHeader(self):
3927    error_collector = ErrorCollector(self.assert_)
3928    cpplint.ProcessFileData('path/self.cc', 'cc',
3929                            ['// Copyright 2014 Your Company. All Rights Reserved.',
3930                             '#include "path/self.h"',
3931                             '#include "path/duplicate.h"',
3932                             '#include "path/duplicate.h"',
3933                             '#ifdef MACRO',
3934                             '#include "path/unique.h"',
3935                             '#else',
3936                             '#include "path/unique.h"',
3937                             '#endif',
3938                             ''],
3939                            error_collector)
3940    self.assertEquals(
3941        ['"path/duplicate.h" already included at path/self.cc:3  '
3942         '[build/include] [4]'],
3943        error_collector.ResultList())
3944
3945  def testUnnamedNamespacesInHeaders(self):
3946    self.TestLanguageRulesCheck(
3947        'foo.h', 'namespace {',
3948        'Do not use unnamed namespaces in header files.  See'
3949        ' https://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Namespaces'
3950        ' for more information.  [build/namespaces] [4]')
3951    # namespace registration macros are OK.
3952    self.TestLanguageRulesCheck('foo.h', 'namespace {  \\', '')
3953    # named namespaces are OK.
3954    self.TestLanguageRulesCheck('foo.h', 'namespace foo {', '')
3955    self.TestLanguageRulesCheck('foo.h', 'namespace foonamespace {', '')
3956    self.TestLanguageRulesCheck('foo.cc', 'namespace {', '')
3957    self.TestLanguageRulesCheck('foo.cc', 'namespace foo {', '')
3958
3959  def testBuildClass(self):
3960    # Test that the linter can parse to the end of class definitions,
3961    # and that it will report when it can't.
3962    # Use multi-line linter because it performs the ClassState check.
3963    self.TestMultiLineLint(
3964        'class Foo {',
3965        'Failed to find complete declaration of class Foo'
3966        '  [build/class] [5]')
3967    # Do the same for namespaces
3968    self.TestMultiLineLint(
3969        'namespace Foo {',
3970        'Failed to find complete declaration of namespace Foo'
3971        '  [build/namespaces] [5]')
3972    # Don't warn on forward declarations of various types.
3973    self.TestMultiLineLint(
3974        'class Foo;',
3975        '')
3976    self.TestMultiLineLint(
3977        """struct Foo*
3978             foo = NewFoo();""",
3979        '')
3980    # Test preprocessor.
3981    self.TestMultiLineLint(
3982        """#ifdef DERIVE_FROM_GOO
3983          struct Foo : public Goo {
3984        #else
3985          struct Foo : public Hoo {
3986        #endif
3987          };""",
3988        '')
3989    self.TestMultiLineLint(
3990        """
3991        class Foo
3992        #ifdef DERIVE_FROM_GOO
3993          : public Goo {
3994        #else
3995          : public Hoo {
3996        #endif
3997        };""",
3998        '')
3999    # Test incomplete class
4000    self.TestMultiLineLint(
4001        'class Foo {',
4002        'Failed to find complete declaration of class Foo'
4003        '  [build/class] [5]')
4004
4005  def testBuildEndComment(self):
4006    # The crosstool compiler we currently use will fail to compile the
4007    # code in this test, so we might consider removing the lint check.
4008    self.TestMultiLineLint(
4009        """#if 0
4010        #endif Not a comment""",
4011        'Uncommented text after #endif is non-standard.  Use a comment.'
4012        '  [build/endif_comment] [5]')
4013
4014  def testBuildForwardDecl(self):
4015    # The crosstool compiler we currently use will fail to compile the
4016    # code in this test, so we might consider removing the lint check.
4017    self.TestLint('class Foo::Goo;',
4018                  'Inner-style forward declarations are invalid.'
4019                  '  Remove this line.'
4020                  '  [build/forward_decl] [5]')
4021
4022  def GetBuildHeaderGuardPreprocessorSymbol(self, file_path):
4023    # Figure out the expected header guard by processing an empty file.
4024    error_collector = ErrorCollector(self.assert_)
4025    cpplint.ProcessFileData(file_path, 'h', [], error_collector)
4026    for error in error_collector.ResultList():
4027      matched = re.search(
4028          'No #ifndef header guard found, suggested CPP variable is: '
4029          '([A-Z0-9_]+)',
4030          error)
4031      if matched is not None:
4032        return matched.group(1)
4033
4034  def testBuildHeaderGuard(self):
4035    file_path = 'mydir/foo.h'
4036    expected_guard = self.GetBuildHeaderGuardPreprocessorSymbol(file_path)
4037    self.assertTrue(re.search('MYDIR_FOO_H_$', expected_guard))
4038
4039    # No guard at all: expect one error.
4040    error_collector = ErrorCollector(self.assert_)
4041    cpplint.ProcessFileData(file_path, 'h', [], error_collector)
4042    self.assertEquals(
4043        1,
4044        error_collector.ResultList().count(
4045            'No #ifndef header guard found, suggested CPP variable is: %s'
4046            '  [build/header_guard] [5]' % expected_guard),
4047        error_collector.ResultList())
4048
4049    # No header guard, but the error is suppressed.
4050    error_collector = ErrorCollector(self.assert_)
4051    cpplint.ProcessFileData(file_path, 'h',
4052                            ['// Copyright 2014 Your Company.',
4053                             '// NOLINT(build/header_guard)', ''],
4054                            error_collector)
4055    self.assertEquals([], error_collector.ResultList())
4056
4057    # Wrong guard
4058    error_collector = ErrorCollector(self.assert_)
4059    cpplint.ProcessFileData(file_path, 'h',
4060                            ['#ifndef FOO_H', '#define FOO_H'], error_collector)
4061    self.assertEquals(
4062        1,
4063        error_collector.ResultList().count(
4064            '#ifndef header guard has wrong style, please use: %s'
4065            '  [build/header_guard] [5]' % expected_guard),
4066        error_collector.ResultList())
4067
4068    # No define
4069    error_collector = ErrorCollector(self.assert_)
4070    cpplint.ProcessFileData(file_path, 'h',
4071                            ['#ifndef %s' % expected_guard], error_collector)
4072    self.assertEquals(
4073        1,
4074        error_collector.ResultList().count(
4075            'No #ifndef header guard found, suggested CPP variable is: %s'
4076            '  [build/header_guard] [5]' % expected_guard),
4077        error_collector.ResultList())
4078
4079    # Mismatched define
4080    error_collector = ErrorCollector(self.assert_)
4081    cpplint.ProcessFileData(file_path, 'h',
4082                            ['#ifndef %s' % expected_guard,
4083                             '#define FOO_H'],
4084                            error_collector)
4085    self.assertEquals(
4086        1,
4087        error_collector.ResultList().count(
4088            'No #ifndef header guard found, suggested CPP variable is: %s'
4089            '  [build/header_guard] [5]' % expected_guard),
4090        error_collector.ResultList())
4091
4092    # No endif
4093    error_collector = ErrorCollector(self.assert_)
4094    cpplint.ProcessFileData(file_path, 'h',
4095                            ['#ifndef %s' % expected_guard,
4096                             '#define %s' % expected_guard,
4097                             ''],
4098                            error_collector)
4099    self.assertEquals(
4100        1,
4101        error_collector.ResultList().count(
4102            '#endif line should be "#endif  // %s"'
4103            '  [build/header_guard] [5]' % expected_guard),
4104        error_collector.ResultList())
4105
4106    # Commentless endif
4107    error_collector = ErrorCollector(self.assert_)
4108    cpplint.ProcessFileData(file_path, 'h',
4109                            ['#ifndef %s' % expected_guard,
4110                             '#define %s' % expected_guard,
4111                             '#endif'],
4112                            error_collector)
4113    self.assertEquals(
4114        1,
4115        error_collector.ResultList().count(
4116            '#endif line should be "#endif  // %s"'
4117            '  [build/header_guard] [5]' % expected_guard),
4118        error_collector.ResultList())
4119
4120    # Commentless endif for old-style guard
4121    error_collector = ErrorCollector(self.assert_)
4122    cpplint.ProcessFileData(file_path, 'h',
4123                            ['#ifndef %s_' % expected_guard,
4124                             '#define %s_' % expected_guard,
4125                             '#endif'],
4126                            error_collector)
4127    self.assertEquals(
4128        1,
4129        error_collector.ResultList().count(
4130            '#endif line should be "#endif  // %s"'
4131            '  [build/header_guard] [5]' % expected_guard),
4132        error_collector.ResultList())
4133
4134    # No header guard errors
4135    error_collector = ErrorCollector(self.assert_)
4136    cpplint.ProcessFileData(file_path, 'h',
4137                            ['#ifndef %s' % expected_guard,
4138                             '#define %s' % expected_guard,
4139                             '#endif  // %s' % expected_guard],
4140                            error_collector)
4141    for line in error_collector.ResultList():
4142      if line.find('build/header_guard') != -1:
4143        self.fail('Unexpected error: %s' % line)
4144
4145    # No header guard errors for old-style guard
4146    error_collector = ErrorCollector(self.assert_)
4147    cpplint.ProcessFileData(file_path, 'h',
4148                            ['#ifndef %s_' % expected_guard,
4149                             '#define %s_' % expected_guard,
4150                             '#endif  // %s_' % expected_guard],
4151                            error_collector)
4152    for line in error_collector.ResultList():
4153      if line.find('build/header_guard') != -1:
4154        self.fail('Unexpected error: %s' % line)
4155
4156    old_verbose_level = cpplint._cpplint_state.verbose_level
4157    try:
4158      cpplint._cpplint_state.verbose_level = 0
4159      # Warn on old-style guard if verbosity is 0.
4160      error_collector = ErrorCollector(self.assert_)
4161      cpplint.ProcessFileData(file_path, 'h',
4162                              ['#ifndef %s_' % expected_guard,
4163                               '#define %s_' % expected_guard,
4164                               '#endif  // %s_' % expected_guard],
4165                              error_collector)
4166      self.assertEquals(
4167          1,
4168          error_collector.ResultList().count(
4169              '#ifndef header guard has wrong style, please use: %s'
4170              '  [build/header_guard] [0]' % expected_guard),
4171          error_collector.ResultList())
4172    finally:
4173      cpplint._cpplint_state.verbose_level = old_verbose_level
4174
4175    # Completely incorrect header guard
4176    error_collector = ErrorCollector(self.assert_)
4177    cpplint.ProcessFileData(file_path, 'h',
4178                            ['#ifndef FOO',
4179                             '#define FOO',
4180                             '#endif  // FOO'],
4181                            error_collector)
4182    self.assertEquals(
4183        1,
4184        error_collector.ResultList().count(
4185            '#ifndef header guard has wrong style, please use: %s'
4186            '  [build/header_guard] [5]' % expected_guard),
4187        error_collector.ResultList())
4188    self.assertEquals(
4189        1,
4190        error_collector.ResultList().count(
4191            '#endif line should be "#endif  // %s"'
4192            '  [build/header_guard] [5]' % expected_guard),
4193        error_collector.ResultList())
4194
4195    # incorrect header guard with nolint
4196    error_collector = ErrorCollector(self.assert_)
4197    cpplint.ProcessFileData(file_path, 'h',
4198                            ['#ifndef FOO  // NOLINT',
4199                             '#define FOO',
4200                             '#endif  // FOO NOLINT'],
4201                            error_collector)
4202    self.assertEquals(
4203        0,
4204        error_collector.ResultList().count(
4205            '#ifndef header guard has wrong style, please use: %s'
4206            '  [build/header_guard] [5]' % expected_guard),
4207        error_collector.ResultList())
4208    self.assertEquals(
4209        0,
4210        error_collector.ResultList().count(
4211            '#endif line should be "#endif  // %s"'
4212            '  [build/header_guard] [5]' % expected_guard),
4213        error_collector.ResultList())
4214
4215    # Special case for flymake
4216    for test_file in ['mydir/foo_flymake.h', 'mydir/.flymake/foo.h']:
4217      error_collector = ErrorCollector(self.assert_)
4218      cpplint.ProcessFileData(test_file, 'h',
4219                              ['// Copyright 2014 Your Company.', ''],
4220                              error_collector)
4221      self.assertEquals(
4222          1,
4223          error_collector.ResultList().count(
4224              'No #ifndef header guard found, suggested CPP variable is: %s'
4225              '  [build/header_guard] [5]' % expected_guard),
4226          error_collector.ResultList())
4227
4228  def testBuildHeaderGuardWithRoot(self):
4229    # note: Tested file paths must be real, otherwise
4230    # the repository name lookup will fail.
4231    file_path = os.path.join(os.path.dirname(os.path.abspath(__file__)),
4232                             'cpplint_test_header.h')
4233    file_info = cpplint.FileInfo(file_path)
4234    if file_info.FullName() == file_info.RepositoryName():
4235      # When FileInfo cannot deduce the root directory of the repository,
4236      # FileInfo.RepositoryName returns the same value as FileInfo.FullName.
4237      # This can happen when this source file was obtained without .svn or
4238      # .git directory. (e.g. using 'svn export' or 'git archive').
4239      # Skip this test in such a case because --root flag makes sense only
4240      # when the root directory of the repository is properly deduced.
4241      return
4242
4243    self.assertEquals('CPPLINT_CPPLINT_TEST_HEADER_H_',
4244                      cpplint.GetHeaderGuardCPPVariable(file_path))
4245    #
4246    # test --root flags:
4247    #   this changes the cpp header guard prefix
4248    #
4249
4250    # left-strip the header guard by using a root dir inside of the repo dir.
4251    # relative directory
4252    cpplint._root = 'cpplint'
4253    self.assertEquals('CPPLINT_TEST_HEADER_H_',
4254                      cpplint.GetHeaderGuardCPPVariable(file_path))
4255
4256    nested_file_path = os.path.join(os.path.dirname(os.path.abspath(__file__)),
4257                                    os.path.join('nested',
4258                                                 'cpplint_test_header.h'))
4259    cpplint._root = os.path.join('cpplint', 'nested')
4260    actual = cpplint.GetHeaderGuardCPPVariable(nested_file_path)
4261    self.assertEquals('CPPLINT_TEST_HEADER_H_',
4262                      actual)
4263
4264    # absolute directory
4265    # (note that CPPLINT.cfg root=setting is always made absolute)
4266    cpplint._root = os.path.join(os.path.dirname(os.path.abspath(__file__)))
4267    self.assertEquals('CPPLINT_TEST_HEADER_H_',
4268                      cpplint.GetHeaderGuardCPPVariable(file_path))
4269
4270    nested_file_path = os.path.join(os.path.dirname(os.path.abspath(__file__)),
4271                                    os.path.join('nested',
4272                                                 'cpplint_test_header.h'))
4273    cpplint._root = os.path.join(os.path.dirname(os.path.abspath(__file__)),
4274                                 'nested')
4275    self.assertEquals('CPPLINT_TEST_HEADER_H_',
4276                      cpplint.GetHeaderGuardCPPVariable(nested_file_path))
4277
4278    # --root flag is ignored if an non-existent directory is specified.
4279    cpplint._root = 'NON_EXISTENT_DIR'
4280    self.assertEquals('CPPLINT_CPPLINT_TEST_HEADER_H_',
4281                      cpplint.GetHeaderGuardCPPVariable(file_path))
4282
4283    # prepend to the header guard by using a root dir that is more outer
4284    # than the repo dir
4285
4286    # (using absolute paths)
4287    # (note that CPPLINT.cfg root=setting is always made absolute)
4288    this_files_path = os.path.dirname(os.path.abspath(__file__))
4289    (styleguide_path, this_files_dir) = os.path.split(this_files_path)
4290    (styleguide_parent_path, styleguide_dir_name) = os.path.split(styleguide_path)
4291    # parent dir of styleguide
4292    cpplint._root = styleguide_parent_path
4293    self.assertIsNotNone(styleguide_parent_path)
4294    # do not hardcode the 'styleguide' repository name, it could be anything.
4295    expected_prefix = re.sub(r'[^a-zA-Z0-9]', '_', styleguide_dir_name).upper() + '_'
4296    # do not have 'styleguide' repo in '/'
4297    self.assertEquals('%sCPPLINT_CPPLINT_TEST_HEADER_H_' %(expected_prefix),
4298                      cpplint.GetHeaderGuardCPPVariable(file_path))
4299
4300    # To run the 'relative path' tests, we must be in the directory of this test file.
4301    cur_dir = os.getcwd()
4302    os.chdir(this_files_path)
4303
4304    # (using relative paths)
4305    styleguide_rel_path = os.path.relpath(styleguide_path, this_files_path)
4306    # '..'
4307    cpplint._root = styleguide_rel_path
4308    self.assertEquals('CPPLINT_CPPLINT_TEST_HEADER_H_',
4309                      cpplint.GetHeaderGuardCPPVariable(file_path))
4310
4311    styleguide_rel_path = os.path.relpath(styleguide_parent_path,
4312                                          this_files_path) # '../..'
4313    cpplint._root = styleguide_rel_path
4314    self.assertEquals('%sCPPLINT_CPPLINT_TEST_HEADER_H_' %(expected_prefix),
4315                      cpplint.GetHeaderGuardCPPVariable(file_path))
4316
4317    cpplint._root = None
4318
4319    # Restore previous CWD.
4320    os.chdir(cur_dir)
4321
4322  def testPathSplitToList(self):
4323    self.assertEquals([''],
4324                      cpplint.PathSplitToList(os.path.join('')))
4325
4326    self.assertEquals(['.'],
4327                      cpplint.PathSplitToList(os.path.join('.')))
4328
4329    self.assertEquals(['..'],
4330                      cpplint.PathSplitToList(os.path.join('..')))
4331
4332    self.assertEquals(['..', 'a', 'b'],
4333                      cpplint.PathSplitToList(os.path.join('..', 'a', 'b')))
4334
4335    self.assertEquals(['a', 'b', 'c', 'd'],
4336                      cpplint.PathSplitToList(os.path.join('a', 'b', 'c', 'd')))
4337
4338  def testBuildInclude(self):
4339    # Test that include statements have slashes in them.
4340    self.TestLint('#include "foo.h"',
4341                  'Include the directory when naming .h files'
4342                  '  [build/include] [4]')
4343    self.TestLint('#include "Python.h"', '')
4344    self.TestLint('#include "lua.h"', '')
4345
4346  def testBuildPrintfFormat(self):
4347    error_collector = ErrorCollector(self.assert_)
4348    cpplint.ProcessFileData(
4349        'foo.cc', 'cc',
4350        [r'printf("\%%d", value);',
4351         r'snprintf(buffer, sizeof(buffer), "\[%d", value);',
4352         r'fprintf(file, "\(%d", value);',
4353         r'vsnprintf(buffer, sizeof(buffer), "\\\{%d", ap);'],
4354        error_collector)
4355    self.assertEquals(
4356        4,
4357        error_collector.Results().count(
4358            '%, [, (, and { are undefined character escapes.  Unescape them.'
4359            '  [build/printf_format] [3]'))
4360
4361    error_collector = ErrorCollector(self.assert_)
4362    cpplint.ProcessFileData(
4363        'foo.cc', 'cc',
4364        ['// Copyright 2014 Your Company.',
4365         r'printf("\\%%%d", value);',
4366         r'printf(R"(\[)");',
4367         r'printf(R"(\[%s)", R"(\])");',
4368         ''],
4369        error_collector)
4370    self.assertEquals('', error_collector.Results())
4371
4372  def testRuntimePrintfFormat(self):
4373    self.TestLint(
4374        r'fprintf(file, "%q", value);',
4375        '%q in format strings is deprecated.  Use %ll instead.'
4376        '  [runtime/printf_format] [3]')
4377
4378    self.TestLint(
4379        r'aprintf(file, "The number is %12q", value);',
4380        '%q in format strings is deprecated.  Use %ll instead.'
4381        '  [runtime/printf_format] [3]')
4382
4383    self.TestLint(
4384        r'printf(file, "The number is" "%-12q", value);',
4385        '%q in format strings is deprecated.  Use %ll instead.'
4386        '  [runtime/printf_format] [3]')
4387
4388    self.TestLint(
4389        r'printf(file, "The number is" "%+12q", value);',
4390        '%q in format strings is deprecated.  Use %ll instead.'
4391        '  [runtime/printf_format] [3]')
4392
4393    self.TestLint(
4394        r'printf(file, "The number is" "% 12q", value);',
4395        '%q in format strings is deprecated.  Use %ll instead.'
4396        '  [runtime/printf_format] [3]')
4397
4398    self.TestLint(
4399        r'snprintf(file, "Never mix %d and %1$d parameters!", value);',
4400        '%N$ formats are unconventional.  Try rewriting to avoid them.'
4401        '  [runtime/printf_format] [2]')
4402
4403  def TestLintLogCodeOnError(self, code, expected_message):
4404    # Special TestLint which logs the input code on error.
4405    result = self.PerformSingleLineLint(code)
4406    if result != expected_message:
4407      self.fail('For code: "%s"\nGot: "%s"\nExpected: "%s"'
4408                % (code, result, expected_message))
4409
4410  def testBuildStorageClass(self):
4411    qualifiers = [None, 'const', 'volatile']
4412    signs = [None, 'signed', 'unsigned']
4413    types = ['void', 'char', 'int', 'float', 'double',
4414             'schar', 'int8', 'uint8', 'int16', 'uint16',
4415             'int32', 'uint32', 'int64', 'uint64']
4416    storage_classes = ['extern', 'register', 'static', 'typedef']
4417
4418    build_storage_class_error_message = (
4419        'Storage-class specifier (static, extern, typedef, etc) should be '
4420        'at the beginning of the declaration.  [build/storage_class] [5]')
4421
4422    # Some explicit cases. Legal in C++, deprecated in C99.
4423    self.TestLint('const int static foo = 5;',
4424                  build_storage_class_error_message)
4425
4426    self.TestLint('char static foo;',
4427                  build_storage_class_error_message)
4428
4429    self.TestLint('double const static foo = 2.0;',
4430                  build_storage_class_error_message)
4431
4432    self.TestLint('uint64 typedef unsigned_long_long;',
4433                  build_storage_class_error_message)
4434
4435    self.TestLint('int register foo = 0;',
4436                  build_storage_class_error_message)
4437
4438    # Since there are a very large number of possibilities, randomly
4439    # construct declarations.
4440    # Make sure that the declaration is logged if there's an error.
4441    # Seed generator with an integer for absolute reproducibility.
4442    random.seed(25)
4443    for unused_i in range(10):
4444      # Build up random list of non-storage-class declaration specs.
4445      other_decl_specs = [random.choice(qualifiers), random.choice(signs),
4446                          random.choice(types)]
4447      # remove None
4448      other_decl_specs = [x for x in other_decl_specs if x is not None]
4449
4450      # shuffle
4451      random.shuffle(other_decl_specs)
4452
4453      # insert storage class after the first
4454      storage_class = random.choice(storage_classes)
4455      insertion_point = random.randint(1, len(other_decl_specs))
4456      decl_specs = (other_decl_specs[0:insertion_point]
4457                    + [storage_class]
4458                    + other_decl_specs[insertion_point:])
4459
4460      self.TestLintLogCodeOnError(
4461          ' '.join(decl_specs) + ';',
4462          build_storage_class_error_message)
4463
4464      # but no error if storage class is first
4465      self.TestLintLogCodeOnError(
4466          storage_class + ' ' + ' '.join(other_decl_specs),
4467          '')
4468
4469  def testLegalCopyright(self):
4470    legal_copyright_message = (
4471        'No copyright message found.  '
4472        'You should have a line: "Copyright [year] <Copyright Owner>"'
4473        '  [legal/copyright] [5]')
4474
4475    copyright_line = '// Copyright 2014 Google Inc. All Rights Reserved.'
4476
4477    file_path = 'mydir/googleclient/foo.cc'
4478
4479    # There should be a copyright message in the first 10 lines
4480    error_collector = ErrorCollector(self.assert_)
4481    cpplint.ProcessFileData(file_path, 'cc', [], error_collector)
4482    self.assertEquals(
4483        1,
4484        error_collector.ResultList().count(legal_copyright_message))
4485
4486    error_collector = ErrorCollector(self.assert_)
4487    cpplint.ProcessFileData(
4488        file_path, 'cc',
4489        ['' for unused_i in range(10)] + [copyright_line],
4490        error_collector)
4491    self.assertEquals(
4492        1,
4493        error_collector.ResultList().count(legal_copyright_message))
4494
4495    # Test that warning isn't issued if Copyright line appears early enough.
4496    error_collector = ErrorCollector(self.assert_)
4497    cpplint.ProcessFileData(file_path, 'cc', [copyright_line], error_collector)
4498    for message in error_collector.ResultList():
4499      if message.find('legal/copyright') != -1:
4500        self.fail('Unexpected error: %s' % message)
4501
4502    error_collector = ErrorCollector(self.assert_)
4503    cpplint.ProcessFileData(
4504        file_path, 'cc',
4505        ['' for unused_i in range(9)] + [copyright_line],
4506        error_collector)
4507    for message in error_collector.ResultList():
4508      if message.find('legal/copyright') != -1:
4509        self.fail('Unexpected error: %s' % message)
4510
4511  def testInvalidIncrement(self):
4512    self.TestLint('*count++;',
4513                  'Changing pointer instead of value (or unused value of '
4514                  'operator*).  [runtime/invalid_increment] [5]')
4515
4516  def testSnprintfSize(self):
4517    self.TestLint('vsnprintf(NULL, 0, format)', '')
4518    self.TestLint('snprintf(fisk, 1, format)',
4519                  'If you can, use sizeof(fisk) instead of 1 as the 2nd arg '
4520                  'to snprintf.  [runtime/printf] [3]')
4521class Cxx11Test(CpplintTestBase):
4522
4523  def Helper(self, package, extension, lines, count):
4524    filename = package + '/foo.' + extension
4525    lines = lines[:]
4526
4527    # Header files need to have an ifdef guard wrapped around their code.
4528    if extension == 'h':
4529      guard = filename.upper().replace('/', '_').replace('.', '_') + '_'
4530      lines.insert(0, '#ifndef ' + guard)
4531      lines.insert(1, '#define ' + guard)
4532      lines.append('#endif  // ' + guard)
4533
4534    # All files need a final blank line.
4535    lines.append('')
4536
4537    # Process the file and check resulting error count.
4538    collector = ErrorCollector(self.assert_)
4539    cpplint.ProcessFileData(filename, extension, lines, collector)
4540    error_list = collector.ResultList()
4541    self.assertEquals(count, len(error_list), error_list)
4542
4543  def TestCxx11Feature(self, code, expected_error):
4544    lines = code.split('\n')
4545    collector = ErrorCollector(self.assert_)
4546    cpplint.RemoveMultiLineComments('foo.h', lines, collector)
4547    clean_lines = cpplint.CleansedLines(lines)
4548    cpplint.FlagCxx11Features('foo.cc', clean_lines, 0, collector)
4549    self.assertEquals(expected_error, collector.Results())
4550
4551  def testBlockedHeaders(self):
4552    self.TestCxx11Feature('#include <tr1/regex>',
4553                          'C++ TR1 headers such as <tr1/regex> are '
4554                          'unapproved.  [build/c++tr1] [5]')
4555    self.TestCxx11Feature('#include <mutex>',
4556                          '<mutex> is an unapproved C++11 header.'
4557                          '  [build/c++11] [5]')
4558
4559  def testBlockedClasses(self):
4560    self.TestCxx11Feature('std::alignment_of<T>',
4561                          'std::alignment_of is an unapproved '
4562                          'C++11 class or function.  Send c-style an example '
4563                          'of where it would make your code more readable, '
4564                          'and they may let you use it.'
4565                          '  [build/c++11] [5]')
4566    self.TestCxx11Feature('std::alignment_offer', '')
4567    self.TestCxx11Feature('mystd::alignment_of', '')
4568    self.TestCxx11Feature('std::binomial_distribution', '')
4569
4570  def testBlockedFunctions(self):
4571    self.TestCxx11Feature('std::alignment_of<int>',
4572                          'std::alignment_of is an unapproved '
4573                          'C++11 class or function.  Send c-style an example '
4574                          'of where it would make your code more readable, '
4575                          'and they may let you use it.'
4576                          '  [build/c++11] [5]')
4577    # Missed because of the lack of "std::".  Compiles because ADL
4578    # looks in the namespace of my_shared_ptr, which (presumably) is
4579    # std::.  But there will be a lint error somewhere in this file
4580    # since my_shared_ptr had to be defined.
4581    self.TestCxx11Feature('static_pointer_cast<Base>(my_shared_ptr)', '')
4582    self.TestCxx11Feature('std::declval<T>()', '')
4583
4584  def testExplicitMakePair(self):
4585    self.TestLint('make_pair', '')
4586    self.TestLint('make_pair(42, 42)', '')
4587    self.TestLint('make_pair<',
4588                  'For C++11-compatibility, omit template arguments from'
4589                  ' make_pair OR use pair directly OR if appropriate,'
4590                  ' construct a pair directly'
4591                  '  [build/explicit_make_pair] [4]')
4592    self.TestLint('make_pair <',
4593                  'For C++11-compatibility, omit template arguments from'
4594                  ' make_pair OR use pair directly OR if appropriate,'
4595                  ' construct a pair directly'
4596                  '  [build/explicit_make_pair] [4]')
4597    self.TestLint('my_make_pair<int, int>', '')
4598
4599class Cxx14Test(CpplintTestBase):
4600
4601  def TestCxx14Feature(self, code, expected_error):
4602    lines = code.split('\n')
4603    collector = ErrorCollector(self.assert_)
4604    cpplint.RemoveMultiLineComments('foo.h', lines, collector)
4605    clean_lines = cpplint.CleansedLines(lines)
4606    cpplint.FlagCxx14Features('foo.cc', clean_lines, 0, collector)
4607    self.assertEquals(expected_error, collector.Results())
4608
4609  def testBlockedHeaders(self):
4610    self.TestCxx14Feature('#include <scoped_allocator>',
4611                          '<scoped_allocator> is an unapproved C++14 header.'
4612                           '  [build/c++14] [5]')
4613    self.TestCxx14Feature('#include <shared_mutex>',
4614                          '<shared_mutex> is an unapproved C++14 header.'
4615                          '  [build/c++14] [5]')
4616
4617
4618class CleansedLinesTest(unittest.TestCase):
4619
4620  def testInit(self):
4621    lines = ['Line 1',
4622             'Line 2',
4623             'Line 3 // Comment test',
4624             'Line 4 /* Comment test */',
4625             'Line 5 "foo"']
4626
4627    clean_lines = cpplint.CleansedLines(lines)
4628    self.assertEquals(lines, clean_lines.raw_lines)
4629    self.assertEquals(5, clean_lines.NumLines())
4630
4631    self.assertEquals(['Line 1',
4632                       'Line 2',
4633                       'Line 3',
4634                       'Line 4',
4635                       'Line 5 "foo"'],
4636                      clean_lines.lines)
4637
4638    self.assertEquals(['Line 1',
4639                       'Line 2',
4640                       'Line 3',
4641                       'Line 4',
4642                       'Line 5 ""'],
4643                      clean_lines.elided)
4644
4645  def testInitEmpty(self):
4646    clean_lines = cpplint.CleansedLines([])
4647    self.assertEquals([], clean_lines.raw_lines)
4648    self.assertEquals(0, clean_lines.NumLines())
4649
4650  def testCollapseStrings(self):
4651    collapse = cpplint.CleansedLines._CollapseStrings
4652    self.assertEquals('""', collapse('""'))             # ""     (empty)
4653    self.assertEquals('"""', collapse('"""'))           # """    (bad)
4654    self.assertEquals('""', collapse('"xyz"'))          # "xyz"  (string)
4655    self.assertEquals('""', collapse('"\\\""'))         # "\""   (string)
4656    self.assertEquals('""', collapse('"\'"'))           # "'"    (string)
4657    self.assertEquals('"\"', collapse('"\"'))           # "\"    (bad)
4658    self.assertEquals('""', collapse('"\\\\"'))         # "\\"   (string)
4659    self.assertEquals('"', collapse('"\\\\\\"'))        # "\\\"  (bad)
4660    self.assertEquals('""', collapse('"\\\\\\\\"'))     # "\\\\" (string)
4661
4662    self.assertEquals('\'\'', collapse('\'\''))         # ''     (empty)
4663    self.assertEquals('\'\'', collapse('\'a\''))        # 'a'    (char)
4664    self.assertEquals('\'\'', collapse('\'\\\'\''))     # '\''   (char)
4665    self.assertEquals('\'', collapse('\'\\\''))         # '\'    (bad)
4666    self.assertEquals('', collapse('\\012'))            # '\012' (char)
4667    self.assertEquals('', collapse('\\xfF0'))           # '\xfF0' (char)
4668    self.assertEquals('', collapse('\\n'))              # '\n' (char)
4669    self.assertEquals(r'\#', collapse('\\#'))           # '\#' (bad)
4670
4671    self.assertEquals('"" + ""', collapse('"\'" + "\'"'))
4672    self.assertEquals("'', ''", collapse("'\"', '\"'"))
4673    self.assertEquals('""[0b10]', collapse('"a\'b"[0b1\'0]'))
4674
4675    self.assertEquals('42', collapse("4'2"))
4676    self.assertEquals('0b0101', collapse("0b0'1'0'1"))
4677    self.assertEquals('1048576', collapse("1'048'576"))
4678    self.assertEquals('0X100000', collapse("0X10'0000"))
4679    self.assertEquals('0004000000', collapse("0'004'000'000"))
4680    self.assertEquals('1.602176565e-19', collapse("1.602'176'565e-19"))
4681    self.assertEquals('\'\' + 0xffff', collapse("'i' + 0xf'f'f'f"))
4682    self.assertEquals('sizeof\'\' == 1', collapse("sizeof'x' == 1"))
4683    self.assertEquals('0x.03p100', collapse('0x.0\'3p1\'0\'0'))
4684    self.assertEquals('123.45', collapse('1\'23.4\'5'))
4685
4686    self.assertEquals('StringReplace(body, "", "");',
4687                      collapse('StringReplace(body, "\\\\", "\\\\\\\\");'))
4688    self.assertEquals('\'\' ""',
4689                      collapse('\'"\' "foo"'))
4690
4691
4692class OrderOfIncludesTest(CpplintTestBase):
4693
4694  def setUp(self):
4695    CpplintTestBase.setUp(self)
4696    self.include_state = cpplint._IncludeState()
4697    os.path.abspath = lambda value: value
4698
4699  def testCheckNextIncludeOrder_OtherThenCpp(self):
4700    self.assertEqual('', self.include_state.CheckNextIncludeOrder(
4701        cpplint._OTHER_HEADER))
4702    self.assertEqual('Found C++ system header after other header',
4703                     self.include_state.CheckNextIncludeOrder(
4704                         cpplint._CPP_SYS_HEADER))
4705
4706  def testCheckNextIncludeOrder_CppThenC(self):
4707    self.assertEqual('', self.include_state.CheckNextIncludeOrder(
4708        cpplint._CPP_SYS_HEADER))
4709    self.assertEqual('Found C system header after C++ system header',
4710                     self.include_state.CheckNextIncludeOrder(
4711                         cpplint._C_SYS_HEADER))
4712
4713  def testCheckNextIncludeOrder_LikelyThenCpp(self):
4714    self.assertEqual('', self.include_state.CheckNextIncludeOrder(
4715        cpplint._LIKELY_MY_HEADER))
4716    self.assertEqual('', self.include_state.CheckNextIncludeOrder(
4717        cpplint._CPP_SYS_HEADER))
4718
4719  def testCheckNextIncludeOrder_PossibleThenCpp(self):
4720    self.assertEqual('', self.include_state.CheckNextIncludeOrder(
4721        cpplint._POSSIBLE_MY_HEADER))
4722    self.assertEqual('', self.include_state.CheckNextIncludeOrder(
4723        cpplint._CPP_SYS_HEADER))
4724
4725  def testCheckNextIncludeOrder_CppThenLikely(self):
4726    self.assertEqual('', self.include_state.CheckNextIncludeOrder(
4727        cpplint._CPP_SYS_HEADER))
4728    # This will eventually fail.
4729    self.assertEqual('', self.include_state.CheckNextIncludeOrder(
4730        cpplint._LIKELY_MY_HEADER))
4731
4732  def testCheckNextIncludeOrder_CppThenPossible(self):
4733    self.assertEqual('', self.include_state.CheckNextIncludeOrder(
4734        cpplint._CPP_SYS_HEADER))
4735    self.assertEqual('', self.include_state.CheckNextIncludeOrder(
4736        cpplint._POSSIBLE_MY_HEADER))
4737
4738  def testClassifyInclude(self):
4739    file_info = cpplint.FileInfo
4740    classify_include = cpplint._ClassifyInclude
4741    self.assertEqual(cpplint._C_SYS_HEADER,
4742                     classify_include(file_info('foo/foo.cc'),
4743                                      'stdio.h',
4744                                      True))
4745    self.assertEqual(cpplint._CPP_SYS_HEADER,
4746                     classify_include(file_info('foo/foo.cc'),
4747                                      'string',
4748                                      True))
4749    self.assertEqual(cpplint._CPP_SYS_HEADER,
4750                     classify_include(file_info('foo/foo.cc'),
4751                                      'typeinfo',
4752                                      True))
4753    self.assertEqual(cpplint._OTHER_HEADER,
4754                     classify_include(file_info('foo/foo.cc'),
4755                                      'string',
4756                                      False))
4757
4758    self.assertEqual(cpplint._LIKELY_MY_HEADER,
4759                     classify_include(file_info('foo/foo.cc'),
4760                                      'foo/foo-inl.h',
4761                                      False))
4762    self.assertEqual(cpplint._LIKELY_MY_HEADER,
4763                     classify_include(file_info('foo/internal/foo.cc'),
4764                                      'foo/public/foo.h',
4765                                      False))
4766    self.assertEqual(cpplint._POSSIBLE_MY_HEADER,
4767                     classify_include(file_info('foo/internal/foo.cc'),
4768                                      'foo/other/public/foo.h',
4769                                      False))
4770    self.assertEqual(cpplint._OTHER_HEADER,
4771                     classify_include(file_info('foo/internal/foo.cc'),
4772                                      'foo/other/public/foop.h',
4773                                      False))
4774
4775  def testTryDropCommonSuffixes(self):
4776    self.assertEqual('foo/foo', cpplint._DropCommonSuffixes('foo/foo-inl.h'))
4777    self.assertEqual('foo/bar/foo',
4778                     cpplint._DropCommonSuffixes('foo/bar/foo_inl.h'))
4779    self.assertEqual('foo/foo', cpplint._DropCommonSuffixes('foo/foo.cc'))
4780    self.assertEqual('foo/foo_unusualinternal',
4781                     cpplint._DropCommonSuffixes('foo/foo_unusualinternal.h'))
4782    self.assertEqual('',
4783                     cpplint._DropCommonSuffixes('_test.cc'))
4784    self.assertEqual('test',
4785                     cpplint._DropCommonSuffixes('test.cc'))
4786
4787  def testRegression(self):
4788    def Format(includes):
4789      include_list = []
4790      for item in includes:
4791        if item.startswith('"') or item.startswith('<'):
4792          include_list.append('#include %s\n' % item)
4793        else:
4794          include_list.append(item + '\n')
4795      return ''.join(include_list)
4796
4797    # Test singleton cases first.
4798    self.TestLanguageRulesCheck('foo/foo.cc', Format(['"foo/foo.h"']), '')
4799    self.TestLanguageRulesCheck('foo/foo.cc', Format(['<stdio.h>']), '')
4800    self.TestLanguageRulesCheck('foo/foo.cc', Format(['<string>']), '')
4801    self.TestLanguageRulesCheck('foo/foo.cc', Format(['"foo/foo-inl.h"']), '')
4802    self.TestLanguageRulesCheck('foo/foo.cc', Format(['"bar/bar-inl.h"']), '')
4803    self.TestLanguageRulesCheck('foo/foo.cc', Format(['"bar/bar.h"']), '')
4804
4805    # Test everything in a good and new order.
4806    self.TestLanguageRulesCheck('foo/foo.cc',
4807                                Format(['"foo/foo.h"',
4808                                        '"foo/foo-inl.h"',
4809                                        '<stdio.h>',
4810                                        '<string>',
4811                                        '<unordered_map>',
4812                                        '"bar/bar-inl.h"',
4813                                        '"bar/bar.h"']),
4814                                '')
4815
4816    # Test bad orders.
4817    self.TestLanguageRulesCheck(
4818        'foo/foo.cc',
4819        Format(['<string>', '<stdio.h>']),
4820        'Found C system header after C++ system header.'
4821        ' Should be: foo.h, c system, c++ system, other.'
4822        '  [build/include_order] [4]')
4823    self.TestLanguageRulesCheck(
4824        'foo/foo.cc',
4825        Format(['"foo/bar-inl.h"',
4826                '"foo/foo-inl.h"']),
4827        '')
4828    self.TestLanguageRulesCheck(
4829        'foo/foo.cc',
4830        Format(['"foo/e.h"',
4831                '"foo/b.h"',  # warning here (e>b)
4832                '"foo/c.h"',
4833                '"foo/d.h"',
4834                '"foo/a.h"']),  # warning here (d>a)
4835        ['Include "foo/b.h" not in alphabetical order'
4836         '  [build/include_alpha] [4]',
4837         'Include "foo/a.h" not in alphabetical order'
4838         '  [build/include_alpha] [4]'])
4839    # -inl.h headers are no longer special.
4840    self.TestLanguageRulesCheck('foo/foo.cc',
4841                                Format(['"foo/foo-inl.h"', '<string>']),
4842                                '')
4843    self.TestLanguageRulesCheck('foo/foo.cc',
4844                                Format(['"foo/bar.h"', '"foo/bar-inl.h"']),
4845                                '')
4846    # Test componentized header.  OK to have my header in ../public dir.
4847    self.TestLanguageRulesCheck('foo/internal/foo.cc',
4848                                Format(['"foo/public/foo.h"', '<string>']),
4849                                '')
4850    # OK to have my header in other dir (not stylistically, but
4851    # cpplint isn't as good as a human).
4852    self.TestLanguageRulesCheck('foo/internal/foo.cc',
4853                                Format(['"foo/other/public/foo.h"',
4854                                        '<string>']),
4855                                '')
4856    self.TestLanguageRulesCheck('foo/foo.cc',
4857                                Format(['"foo/foo.h"',
4858                                        '<string>',
4859                                        '"base/google.h"',
4860                                        '"base/flags.h"']),
4861                                'Include "base/flags.h" not in alphabetical '
4862                                'order  [build/include_alpha] [4]')
4863    # According to the style, -inl.h should come before .h, but we don't
4864    # complain about that.
4865    self.TestLanguageRulesCheck('foo/foo.cc',
4866                                Format(['"foo/foo-inl.h"',
4867                                        '"foo/foo.h"',
4868                                        '"base/google.h"',
4869                                        '"base/google-inl.h"']),
4870                                '')
4871    # Allow project includes to be separated by blank lines
4872    self.TestLanguageRulesCheck('a/a.cc',
4873                                Format(['"a/a.h"',
4874                                        '<string>',
4875                                        '"base/google.h"',
4876                                        '',
4877                                        '"b/c.h"',
4878                                        '',
4879                                        'MACRO',
4880                                        '"a/b.h"']),
4881                                '')
4882    self.TestLanguageRulesCheck('a/a.cc',
4883                                Format(['"a/a.h"',
4884                                        '<string>',
4885                                        '"base/google.h"',
4886                                        '"a/b.h"']),
4887                                'Include "a/b.h" not in alphabetical '
4888                                'order  [build/include_alpha] [4]')
4889
4890    # Test conditional includes
4891    self.TestLanguageRulesCheck(
4892        'a/a.cc',
4893        ''.join(['#include <string.h>\n',
4894                 '#include "base/port.h"\n',
4895                 '#include <initializer_list>\n']),
4896        ('Found C++ system header after other header. '
4897         'Should be: a.h, c system, c++ system, other.  '
4898         '[build/include_order] [4]'))
4899    self.TestLanguageRulesCheck(
4900        'a/a.cc',
4901        ''.join(['#include <string.h>\n',
4902                 '#include "base/port.h"\n',
4903                 '#ifdef LANG_CXX11\n',
4904                 '#include <initializer_list>\n',
4905                 '#endif  // LANG_CXX11\n']),
4906        '')
4907    self.TestLanguageRulesCheck(
4908        'a/a.cc',
4909        ''.join(['#include <string.h>\n',
4910                 '#ifdef LANG_CXX11\n',
4911                 '#include "base/port.h"\n',
4912                 '#include <initializer_list>\n',
4913                 '#endif  // LANG_CXX11\n']),
4914        ('Found C++ system header after other header. '
4915         'Should be: a.h, c system, c++ system, other.  '
4916         '[build/include_order] [4]'))
4917
4918    # Third party headers are exempt from order checks
4919    self.TestLanguageRulesCheck('foo/foo.cc',
4920                                Format(['<string>', '"Python.h"', '<vector>']),
4921                                '')
4922
4923
4924class CheckForFunctionLengthsTest(CpplintTestBase):
4925
4926  def setUp(self):
4927    # Reducing these thresholds for the tests speeds up tests significantly.
4928    self.old_normal_trigger = cpplint._FunctionState._NORMAL_TRIGGER
4929    self.old_test_trigger = cpplint._FunctionState._TEST_TRIGGER
4930
4931    cpplint._FunctionState._NORMAL_TRIGGER = 10
4932    cpplint._FunctionState._TEST_TRIGGER = 25
4933
4934  def tearDown(self):
4935    cpplint._FunctionState._NORMAL_TRIGGER = self.old_normal_trigger
4936    cpplint._FunctionState._TEST_TRIGGER = self.old_test_trigger
4937
4938  def TestFunctionLengthsCheck(self, code, expected_message):
4939    """Check warnings for long function bodies are as expected.
4940
4941    Args:
4942      code: C++ source code expected to generate a warning message.
4943      expected_message: Message expected to be generated by the C++ code.
4944    """
4945    self.assertEquals(expected_message,
4946                      self.PerformFunctionLengthsCheck(code))
4947
4948  def TriggerLines(self, error_level):
4949    """Return number of lines needed to trigger a function length warning.
4950
4951    Args:
4952      error_level: --v setting for cpplint.
4953
4954    Returns:
4955      Number of lines needed to trigger a function length warning.
4956    """
4957    return cpplint._FunctionState._NORMAL_TRIGGER * 2**error_level
4958
4959  def TestLines(self, error_level):
4960    """Return number of lines needed to trigger a test function length warning.
4961
4962    Args:
4963      error_level: --v setting for cpplint.
4964
4965    Returns:
4966      Number of lines needed to trigger a test function length warning.
4967    """
4968    return cpplint._FunctionState._TEST_TRIGGER * 2**error_level
4969
4970  def TestFunctionLengthCheckDefinition(self, lines, error_level):
4971    """Generate long function definition and check warnings are as expected.
4972
4973    Args:
4974      lines: Number of lines to generate.
4975      error_level:  --v setting for cpplint.
4976    """
4977    trigger_level = self.TriggerLines(cpplint._VerboseLevel())
4978    self.TestFunctionLengthsCheck(
4979        'void test(int x)' + self.FunctionBody(lines),
4980        ('Small and focused functions are preferred: '
4981         'test() has %d non-comment lines '
4982         '(error triggered by exceeding %d lines).'
4983         '  [readability/fn_size] [%d]'
4984         % (lines, trigger_level, error_level)))
4985
4986  def TestFunctionLengthCheckDefinitionOK(self, lines):
4987    """Generate shorter function definition and check no warning is produced.
4988
4989    Args:
4990      lines: Number of lines to generate.
4991    """
4992    self.TestFunctionLengthsCheck(
4993        'void test(int x)' + self.FunctionBody(lines),
4994        '')
4995
4996  def TestFunctionLengthCheckAtErrorLevel(self, error_level):
4997    """Generate and check function at the trigger level for --v setting.
4998
4999    Args:
5000      error_level: --v setting for cpplint.
5001    """
5002    self.TestFunctionLengthCheckDefinition(self.TriggerLines(error_level),
5003                                           error_level)
5004
5005  def TestFunctionLengthCheckBelowErrorLevel(self, error_level):
5006    """Generate and check function just below the trigger level for --v setting.
5007
5008    Args:
5009      error_level: --v setting for cpplint.
5010    """
5011    self.TestFunctionLengthCheckDefinition(self.TriggerLines(error_level)-1,
5012                                           error_level-1)
5013
5014  def TestFunctionLengthCheckAboveErrorLevel(self, error_level):
5015    """Generate and check function just above the trigger level for --v setting.
5016
5017    Args:
5018      error_level: --v setting for cpplint.
5019    """
5020    self.TestFunctionLengthCheckDefinition(self.TriggerLines(error_level)+1,
5021                                           error_level)
5022
5023  def FunctionBody(self, number_of_lines):
5024    return ' {\n' + '    this_is_just_a_test();\n'*number_of_lines + '}'
5025
5026  def FunctionBodyWithBlankLines(self, number_of_lines):
5027    return ' {\n' + '    this_is_just_a_test();\n\n'*number_of_lines + '}'
5028
5029  def FunctionBodyWithNoLints(self, number_of_lines):
5030    return (' {\n' +
5031            '    this_is_just_a_test();  // NOLINT\n'*number_of_lines + '}')
5032
5033  # Test line length checks.
5034  def testFunctionLengthCheckDeclaration(self):
5035    self.TestFunctionLengthsCheck(
5036        'void test();',  # Not a function definition
5037        '')
5038
5039  def testFunctionLengthCheckDeclarationWithBlockFollowing(self):
5040    self.TestFunctionLengthsCheck(
5041        ('void test();\n'
5042         + self.FunctionBody(66)),  # Not a function definition
5043        '')
5044
5045  def testFunctionLengthCheckClassDefinition(self):
5046    self.TestFunctionLengthsCheck(  # Not a function definition
5047        'class Test' + self.FunctionBody(66) + ';',
5048        '')
5049
5050  def testFunctionLengthCheckTrivial(self):
5051    self.TestFunctionLengthsCheck(
5052        'void test() {}',  # Not counted
5053        '')
5054
5055  def testFunctionLengthCheckEmpty(self):
5056    self.TestFunctionLengthsCheck(
5057        'void test() {\n}',
5058        '')
5059
5060  def testFunctionLengthCheckDefinitionBelowSeverity0(self):
5061    old_verbosity = cpplint._SetVerboseLevel(0)
5062    self.TestFunctionLengthCheckDefinitionOK(self.TriggerLines(0)-1)
5063    cpplint._SetVerboseLevel(old_verbosity)
5064
5065  def testFunctionLengthCheckDefinitionAtSeverity0(self):
5066    old_verbosity = cpplint._SetVerboseLevel(0)
5067    self.TestFunctionLengthCheckDefinitionOK(self.TriggerLines(0))
5068    cpplint._SetVerboseLevel(old_verbosity)
5069
5070  def testFunctionLengthCheckDefinitionAboveSeverity0(self):
5071    old_verbosity = cpplint._SetVerboseLevel(0)
5072    self.TestFunctionLengthCheckAboveErrorLevel(0)
5073    cpplint._SetVerboseLevel(old_verbosity)
5074
5075  def testFunctionLengthCheckDefinitionBelowSeverity1v0(self):
5076    old_verbosity = cpplint._SetVerboseLevel(0)
5077    self.TestFunctionLengthCheckBelowErrorLevel(1)
5078    cpplint._SetVerboseLevel(old_verbosity)
5079
5080  def testFunctionLengthCheckDefinitionAtSeverity1v0(self):
5081    old_verbosity = cpplint._SetVerboseLevel(0)
5082    self.TestFunctionLengthCheckAtErrorLevel(1)
5083    cpplint._SetVerboseLevel(old_verbosity)
5084
5085  def testFunctionLengthCheckDefinitionBelowSeverity1(self):
5086    self.TestFunctionLengthCheckDefinitionOK(self.TriggerLines(1)-1)
5087
5088  def testFunctionLengthCheckDefinitionAtSeverity1(self):
5089    self.TestFunctionLengthCheckDefinitionOK(self.TriggerLines(1))
5090
5091  def testFunctionLengthCheckDefinitionAboveSeverity1(self):
5092    self.TestFunctionLengthCheckAboveErrorLevel(1)
5093
5094  def testFunctionLengthCheckDefinitionSeverity1PlusBlanks(self):
5095    error_level = 1
5096    error_lines = self.TriggerLines(error_level) + 1
5097    trigger_level = self.TriggerLines(cpplint._VerboseLevel())
5098    self.TestFunctionLengthsCheck(
5099        'void test_blanks(int x)' + self.FunctionBody(error_lines),
5100        ('Small and focused functions are preferred: '
5101         'test_blanks() has %d non-comment lines '
5102         '(error triggered by exceeding %d lines).'
5103         '  [readability/fn_size] [%d]')
5104        % (error_lines, trigger_level, error_level))
5105
5106  def testFunctionLengthCheckComplexDefinitionSeverity1(self):
5107    error_level = 1
5108    error_lines = self.TriggerLines(error_level) + 1
5109    trigger_level = self.TriggerLines(cpplint._VerboseLevel())
5110    self.TestFunctionLengthsCheck(
5111        ('my_namespace::my_other_namespace::MyVeryLongTypeName*\n'
5112         'my_namespace::my_other_namespace::MyFunction(int arg1, char* arg2)'
5113         + self.FunctionBody(error_lines)),
5114        ('Small and focused functions are preferred: '
5115         'my_namespace::my_other_namespace::MyFunction()'
5116         ' has %d non-comment lines '
5117         '(error triggered by exceeding %d lines).'
5118         '  [readability/fn_size] [%d]')
5119        % (error_lines, trigger_level, error_level))
5120
5121  def testFunctionLengthCheckDefinitionSeverity1ForTest(self):
5122    error_level = 1
5123    error_lines = self.TestLines(error_level) + 1
5124    trigger_level = self.TestLines(cpplint._VerboseLevel())
5125    self.TestFunctionLengthsCheck(
5126        'TEST_F(Test, Mutator)' + self.FunctionBody(error_lines),
5127        ('Small and focused functions are preferred: '
5128         'TEST_F(Test, Mutator) has %d non-comment lines '
5129         '(error triggered by exceeding %d lines).'
5130         '  [readability/fn_size] [%d]')
5131        % (error_lines, trigger_level, error_level))
5132
5133  def testFunctionLengthCheckDefinitionSeverity1ForSplitLineTest(self):
5134    error_level = 1
5135    error_lines = self.TestLines(error_level) + 1
5136    trigger_level = self.TestLines(cpplint._VerboseLevel())
5137    self.TestFunctionLengthsCheck(
5138        ('TEST_F(GoogleUpdateRecoveryRegistryProtectedTest,\n'
5139         '    FixGoogleUpdate_AllValues_MachineApp)'  # note: 4 spaces
5140         + self.FunctionBody(error_lines)),
5141        ('Small and focused functions are preferred: '
5142         'TEST_F(GoogleUpdateRecoveryRegistryProtectedTest, '  # 1 space
5143         'FixGoogleUpdate_AllValues_MachineApp) has %d non-comment lines '
5144         '(error triggered by exceeding %d lines).'
5145         '  [readability/fn_size] [%d]')
5146        % (error_lines+1, trigger_level, error_level))
5147
5148  def testFunctionLengthCheckDefinitionSeverity1ForBadTestDoesntBreak(self):
5149    error_level = 1
5150    error_lines = self.TestLines(error_level) + 1
5151    trigger_level = self.TestLines(cpplint._VerboseLevel())
5152    self.TestFunctionLengthsCheck(
5153        ('TEST_F('
5154         + self.FunctionBody(error_lines)),
5155        ('Small and focused functions are preferred: '
5156         'TEST_F has %d non-comment lines '
5157         '(error triggered by exceeding %d lines).'
5158         '  [readability/fn_size] [%d]')
5159        % (error_lines, trigger_level, error_level))
5160
5161  def testFunctionLengthCheckDefinitionSeverity1WithEmbeddedNoLints(self):
5162    error_level = 1
5163    error_lines = self.TriggerLines(error_level)+1
5164    trigger_level = self.TriggerLines(cpplint._VerboseLevel())
5165    self.TestFunctionLengthsCheck(
5166        'void test(int x)' + self.FunctionBodyWithNoLints(error_lines),
5167        ('Small and focused functions are preferred: '
5168         'test() has %d non-comment lines '
5169         '(error triggered by exceeding %d lines).'
5170         '  [readability/fn_size] [%d]')
5171        % (error_lines, trigger_level, error_level))
5172
5173  def testFunctionLengthCheckDefinitionSeverity1WithNoLint(self):
5174    self.TestFunctionLengthsCheck(
5175        ('void test(int x)' + self.FunctionBody(self.TriggerLines(1))
5176         + '  // NOLINT -- long function'),
5177        '')
5178
5179  def testFunctionLengthCheckDefinitionBelowSeverity2(self):
5180    self.TestFunctionLengthCheckBelowErrorLevel(2)
5181
5182  def testFunctionLengthCheckDefinitionSeverity2(self):
5183    self.TestFunctionLengthCheckAtErrorLevel(2)
5184
5185  def testFunctionLengthCheckDefinitionAboveSeverity2(self):
5186    self.TestFunctionLengthCheckAboveErrorLevel(2)
5187
5188  def testFunctionLengthCheckDefinitionBelowSeverity3(self):
5189    self.TestFunctionLengthCheckBelowErrorLevel(3)
5190
5191  def testFunctionLengthCheckDefinitionSeverity3(self):
5192    self.TestFunctionLengthCheckAtErrorLevel(3)
5193
5194  def testFunctionLengthCheckDefinitionAboveSeverity3(self):
5195    self.TestFunctionLengthCheckAboveErrorLevel(3)
5196
5197  def testFunctionLengthCheckDefinitionBelowSeverity4(self):
5198    self.TestFunctionLengthCheckBelowErrorLevel(4)
5199
5200  def testFunctionLengthCheckDefinitionSeverity4(self):
5201    self.TestFunctionLengthCheckAtErrorLevel(4)
5202
5203  def testFunctionLengthCheckDefinitionAboveSeverity4(self):
5204    self.TestFunctionLengthCheckAboveErrorLevel(4)
5205
5206  def testFunctionLengthCheckDefinitionBelowSeverity5(self):
5207    self.TestFunctionLengthCheckBelowErrorLevel(5)
5208
5209  def testFunctionLengthCheckDefinitionAtSeverity5(self):
5210    self.TestFunctionLengthCheckAtErrorLevel(5)
5211
5212  def testFunctionLengthCheckDefinitionAboveSeverity5(self):
5213    self.TestFunctionLengthCheckAboveErrorLevel(5)
5214
5215  def testFunctionLengthCheckDefinitionHugeLines(self):
5216    # 5 is the limit
5217    self.TestFunctionLengthCheckDefinition(self.TriggerLines(10), 5)
5218
5219  def testFunctionLengthNotDeterminable(self):
5220    # Macro invocation without terminating semicolon.
5221    self.TestFunctionLengthsCheck(
5222        'MACRO(arg)',
5223        '')
5224
5225    # Macro with underscores
5226    self.TestFunctionLengthsCheck(
5227        'MACRO_WITH_UNDERSCORES(arg1, arg2, arg3)',
5228        '')
5229
5230    self.TestFunctionLengthsCheck(
5231        'NonMacro(arg)',
5232        'Lint failed to find start of function body.'
5233        '  [readability/fn_size] [5]')
5234
5235  def testFunctionLengthCheckWithNamespace(self):
5236    old_verbosity = cpplint._SetVerboseLevel(1)
5237    self.TestFunctionLengthsCheck(
5238        ('namespace {\n'
5239         'void CodeCoverageCL35256059() {\n' +
5240         ('  X++;\n' * 3000) +
5241         '}\n'
5242         '}  // namespace\n'),
5243        ('Small and focused functions are preferred: '
5244         'CodeCoverageCL35256059() has 3000 non-comment lines '
5245         '(error triggered by exceeding 20 lines).'
5246         '  [readability/fn_size] [5]'))
5247    cpplint._SetVerboseLevel(old_verbosity)
5248
5249
5250def TrimExtraIndent(text_block):
5251  """Trim a uniform amount of whitespace off of each line in a string.
5252
5253  Compute the minimum indent on all non blank lines and trim that from each, so
5254  that the block of text has no extra indentation.
5255
5256  Args:
5257    text_block: a multiline string
5258
5259  Returns:
5260    text_block with the common whitespace indent of each line removed.
5261  """
5262
5263  def CountLeadingWhitespace(s):
5264    count = 0
5265    for c in s:
5266      if not c.isspace():
5267        break
5268      count += 1
5269    return count
5270  # find the minimum indent (except for blank lines)
5271  min_indent = min([CountLeadingWhitespace(line)
5272                    for line in text_block.split('\n') if line])
5273  return '\n'.join([line[min_indent:] for line in text_block.split('\n')])
5274
5275
5276class CloseExpressionTest(unittest.TestCase):
5277
5278  def setUp(self):
5279    self.lines = cpplint.CleansedLines(
5280        #           1         2         3         4         5
5281        # 0123456789012345678901234567890123456789012345678901234567890
5282        ['// Line 0',
5283         'inline RCULocked<X>::ReadPtr::ReadPtr(const RCULocked* rcu) {',
5284         '  DCHECK(!(data & kFlagMask)) << "Error";',
5285         '}',
5286         '// Line 4',
5287         'RCULocked<X>::WritePtr::WritePtr(RCULocked* rcu)',
5288         '    : lock_(&rcu_->mutex_) {',
5289         '}',
5290         '// Line 8',
5291         'template <typename T, typename... A>',
5292         'typename std::enable_if<',
5293         '    std::is_array<T>::value && (std::extent<T>::value > 0)>::type',
5294         'MakeUnique(A&&... a) = delete;',
5295         '// Line 13',
5296         'auto x = []() {};',
5297         '// Line 15',
5298         'template <typename U>',
5299         'friend bool operator==(const reffed_ptr& a,',
5300         '                       const reffed_ptr<U>& b) {',
5301         '  return a.get() == b.get();',
5302         '}',
5303         '// Line 21'])
5304
5305  def testCloseExpression(self):
5306    # List of positions to test:
5307    # (start line, start position, end line, end position + 1)
5308    positions = [(1, 16, 1, 19),
5309                 (1, 37, 1, 59),
5310                 (1, 60, 3, 1),
5311                 (2, 8, 2, 29),
5312                 (2, 30, 22, -1),  # Left shift operator
5313                 (9, 9, 9, 36),
5314                 (10, 23, 11, 59),
5315                 (11, 54, 22, -1),  # Greater than operator
5316                 (14, 9, 14, 11),
5317                 (14, 11, 14, 13),
5318                 (14, 14, 14, 16),
5319                 (17, 22, 18, 46),
5320                 (18, 47, 20, 1)]
5321    for p in positions:
5322      (_, line, column) = cpplint.CloseExpression(self.lines, p[0], p[1])
5323      self.assertEquals((p[2], p[3]), (line, column))
5324
5325  def testReverseCloseExpression(self):
5326    # List of positions to test:
5327    # (end line, end position, start line, start position)
5328    positions = [(1, 18, 1, 16),
5329                 (1, 58, 1, 37),
5330                 (2, 27, 2, 10),
5331                 (2, 28, 2, 8),
5332                 (6, 18, 0, -1),  # -> operator
5333                 (9, 35, 9, 9),
5334                 (11, 54, 0, -1),  # Greater than operator
5335                 (11, 57, 11, 31),
5336                 (14, 10, 14, 9),
5337                 (14, 12, 14, 11),
5338                 (14, 15, 14, 14),
5339                 (18, 45, 17, 22),
5340                 (20, 0, 18, 47)]
5341    for p in positions:
5342      (_, line, column) = cpplint.ReverseCloseExpression(self.lines, p[0], p[1])
5343      self.assertEquals((p[2], p[3]), (line, column))
5344
5345
5346class NestingStateTest(unittest.TestCase):
5347
5348  def setUp(self):
5349    self.nesting_state = cpplint.NestingState()
5350    self.error_collector = ErrorCollector(self.assert_)
5351
5352  def UpdateWithLines(self, lines):
5353    clean_lines = cpplint.CleansedLines(lines)
5354    for line in xrange(clean_lines.NumLines()):
5355      self.nesting_state.Update('test.cc',
5356                                clean_lines, line, self.error_collector)
5357
5358  def testEmpty(self):
5359    self.UpdateWithLines([])
5360    self.assertEquals(self.nesting_state.stack, [])
5361
5362  def testNamespace(self):
5363    self.UpdateWithLines(['namespace {'])
5364    self.assertEquals(len(self.nesting_state.stack), 1)
5365    self.assertTrue(isinstance(self.nesting_state.stack[0],
5366                               cpplint._NamespaceInfo))
5367    self.assertTrue(self.nesting_state.stack[0].seen_open_brace)
5368    self.assertEquals(self.nesting_state.stack[0].name, '')
5369
5370    self.UpdateWithLines(['namespace outer { namespace inner'])
5371    self.assertEquals(len(self.nesting_state.stack), 3)
5372    self.assertTrue(self.nesting_state.stack[0].seen_open_brace)
5373    self.assertTrue(self.nesting_state.stack[1].seen_open_brace)
5374    self.assertFalse(self.nesting_state.stack[2].seen_open_brace)
5375    self.assertEquals(self.nesting_state.stack[0].name, '')
5376    self.assertEquals(self.nesting_state.stack[1].name, 'outer')
5377    self.assertEquals(self.nesting_state.stack[2].name, 'inner')
5378
5379    self.UpdateWithLines(['{'])
5380    self.assertTrue(self.nesting_state.stack[2].seen_open_brace)
5381
5382    self.UpdateWithLines(['}', '}}'])
5383    self.assertEquals(len(self.nesting_state.stack), 0)
5384
5385  def testClass(self):
5386    self.UpdateWithLines(['class A {'])
5387    self.assertEquals(len(self.nesting_state.stack), 1)
5388    self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo))
5389    self.assertEquals(self.nesting_state.stack[0].name, 'A')
5390    self.assertFalse(self.nesting_state.stack[0].is_derived)
5391    self.assertEquals(self.nesting_state.stack[0].class_indent, 0)
5392
5393    self.UpdateWithLines(['};',
5394                          'struct B : public A {'])
5395    self.assertEquals(len(self.nesting_state.stack), 1)
5396    self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo))
5397    self.assertEquals(self.nesting_state.stack[0].name, 'B')
5398    self.assertTrue(self.nesting_state.stack[0].is_derived)
5399
5400    self.UpdateWithLines(['};',
5401                          'class C',
5402                          ': public A {'])
5403    self.assertEquals(len(self.nesting_state.stack), 1)
5404    self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo))
5405    self.assertEquals(self.nesting_state.stack[0].name, 'C')
5406    self.assertTrue(self.nesting_state.stack[0].is_derived)
5407
5408    self.UpdateWithLines(['};',
5409                          'template<T>'])
5410    self.assertEquals(len(self.nesting_state.stack), 0)
5411
5412    self.UpdateWithLines(['class D {', '  class E {'])
5413    self.assertEquals(len(self.nesting_state.stack), 2)
5414    self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo))
5415    self.assertEquals(self.nesting_state.stack[0].name, 'D')
5416    self.assertFalse(self.nesting_state.stack[0].is_derived)
5417    self.assertTrue(isinstance(self.nesting_state.stack[1], cpplint._ClassInfo))
5418    self.assertEquals(self.nesting_state.stack[1].name, 'E')
5419    self.assertFalse(self.nesting_state.stack[1].is_derived)
5420    self.assertEquals(self.nesting_state.stack[1].class_indent, 2)
5421    self.assertEquals(self.nesting_state.InnermostClass().name, 'E')
5422
5423    self.UpdateWithLines(['}', '}'])
5424    self.assertEquals(len(self.nesting_state.stack), 0)
5425
5426  def testClassAccess(self):
5427    self.UpdateWithLines(['class A {'])
5428    self.assertEquals(len(self.nesting_state.stack), 1)
5429    self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo))
5430    self.assertEquals(self.nesting_state.stack[0].access, 'private')
5431
5432    self.UpdateWithLines([' public:'])
5433    self.assertEquals(self.nesting_state.stack[0].access, 'public')
5434    self.UpdateWithLines([' protracted:'])
5435    self.assertEquals(self.nesting_state.stack[0].access, 'public')
5436    self.UpdateWithLines([' protected:'])
5437    self.assertEquals(self.nesting_state.stack[0].access, 'protected')
5438    self.UpdateWithLines([' private:'])
5439    self.assertEquals(self.nesting_state.stack[0].access, 'private')
5440
5441    self.UpdateWithLines(['  struct B {'])
5442    self.assertEquals(len(self.nesting_state.stack), 2)
5443    self.assertTrue(isinstance(self.nesting_state.stack[1], cpplint._ClassInfo))
5444    self.assertEquals(self.nesting_state.stack[1].access, 'public')
5445    self.assertEquals(self.nesting_state.stack[0].access, 'private')
5446
5447    self.UpdateWithLines(['   protected  :'])
5448    self.assertEquals(self.nesting_state.stack[1].access, 'protected')
5449    self.assertEquals(self.nesting_state.stack[0].access, 'private')
5450
5451    self.UpdateWithLines(['  }', '}'])
5452    self.assertEquals(len(self.nesting_state.stack), 0)
5453
5454  def testStruct(self):
5455    self.UpdateWithLines(['struct A {'])
5456    self.assertEquals(len(self.nesting_state.stack), 1)
5457    self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo))
5458    self.assertEquals(self.nesting_state.stack[0].name, 'A')
5459    self.assertFalse(self.nesting_state.stack[0].is_derived)
5460
5461    self.UpdateWithLines(['}',
5462                          'void Func(struct B arg) {'])
5463    self.assertEquals(len(self.nesting_state.stack), 1)
5464    self.assertFalse(isinstance(self.nesting_state.stack[0],
5465                                cpplint._ClassInfo))
5466
5467    self.UpdateWithLines(['}'])
5468    self.assertEquals(len(self.nesting_state.stack), 0)
5469
5470  def testPreprocessor(self):
5471    self.assertEquals(len(self.nesting_state.pp_stack), 0)
5472    self.UpdateWithLines(['#if MACRO1'])
5473    self.assertEquals(len(self.nesting_state.pp_stack), 1)
5474    self.UpdateWithLines(['#endif'])
5475    self.assertEquals(len(self.nesting_state.pp_stack), 0)
5476
5477    self.UpdateWithLines(['#ifdef MACRO2'])
5478    self.assertEquals(len(self.nesting_state.pp_stack), 1)
5479    self.UpdateWithLines(['#else'])
5480    self.assertEquals(len(self.nesting_state.pp_stack), 1)
5481    self.UpdateWithLines(['#ifdef MACRO3'])
5482    self.assertEquals(len(self.nesting_state.pp_stack), 2)
5483    self.UpdateWithLines(['#elif MACRO4'])
5484    self.assertEquals(len(self.nesting_state.pp_stack), 2)
5485    self.UpdateWithLines(['#endif'])
5486    self.assertEquals(len(self.nesting_state.pp_stack), 1)
5487    self.UpdateWithLines(['#endif'])
5488    self.assertEquals(len(self.nesting_state.pp_stack), 0)
5489
5490    self.UpdateWithLines(['#ifdef MACRO5',
5491                          'class A {',
5492                          '#elif MACRO6',
5493                          'class B {',
5494                          '#else',
5495                          'class C {',
5496                          '#endif'])
5497    self.assertEquals(len(self.nesting_state.pp_stack), 0)
5498    self.assertEquals(len(self.nesting_state.stack), 1)
5499    self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo))
5500    self.assertEquals(self.nesting_state.stack[0].name, 'A')
5501    self.UpdateWithLines(['};'])
5502    self.assertEquals(len(self.nesting_state.stack), 0)
5503
5504    self.UpdateWithLines(['class D',
5505                          '#ifdef MACRO7'])
5506    self.assertEquals(len(self.nesting_state.pp_stack), 1)
5507    self.assertEquals(len(self.nesting_state.stack), 1)
5508    self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo))
5509    self.assertEquals(self.nesting_state.stack[0].name, 'D')
5510    self.assertFalse(self.nesting_state.stack[0].is_derived)
5511
5512    self.UpdateWithLines(['#elif MACRO8',
5513                          ': public E'])
5514    self.assertEquals(len(self.nesting_state.stack), 1)
5515    self.assertEquals(self.nesting_state.stack[0].name, 'D')
5516    self.assertTrue(self.nesting_state.stack[0].is_derived)
5517    self.assertFalse(self.nesting_state.stack[0].seen_open_brace)
5518
5519    self.UpdateWithLines(['#else',
5520                          '{'])
5521    self.assertEquals(len(self.nesting_state.stack), 1)
5522    self.assertEquals(self.nesting_state.stack[0].name, 'D')
5523    self.assertFalse(self.nesting_state.stack[0].is_derived)
5524    self.assertTrue(self.nesting_state.stack[0].seen_open_brace)
5525
5526    self.UpdateWithLines(['#endif'])
5527    self.assertEquals(len(self.nesting_state.pp_stack), 0)
5528    self.assertEquals(len(self.nesting_state.stack), 1)
5529    self.assertEquals(self.nesting_state.stack[0].name, 'D')
5530    self.assertFalse(self.nesting_state.stack[0].is_derived)
5531    self.assertFalse(self.nesting_state.stack[0].seen_open_brace)
5532
5533    self.UpdateWithLines([';'])
5534    self.assertEquals(len(self.nesting_state.stack), 0)
5535
5536  def testTemplate(self):
5537    self.UpdateWithLines(['template <T,',
5538                          '          class Arg1 = tmpl<T> >'])
5539    self.assertEquals(len(self.nesting_state.stack), 0)
5540    self.UpdateWithLines(['class A {'])
5541    self.assertEquals(len(self.nesting_state.stack), 1)
5542    self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo))
5543    self.assertEquals(self.nesting_state.stack[0].name, 'A')
5544
5545    self.UpdateWithLines(['};',
5546                          'template <T,',
5547                          '  template <typename, typename> class B>',
5548                          'class C'])
5549    self.assertEquals(len(self.nesting_state.stack), 1)
5550    self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo))
5551    self.assertEquals(self.nesting_state.stack[0].name, 'C')
5552    self.UpdateWithLines([';'])
5553    self.assertEquals(len(self.nesting_state.stack), 0)
5554
5555    self.UpdateWithLines(['class D : public Tmpl<E>'])
5556    self.assertEquals(len(self.nesting_state.stack), 1)
5557    self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo))
5558    self.assertEquals(self.nesting_state.stack[0].name, 'D')
5559
5560    self.UpdateWithLines(['{', '};'])
5561    self.assertEquals(len(self.nesting_state.stack), 0)
5562
5563    self.UpdateWithLines(['template <class F,',
5564                          '          class G,',
5565                          '          class H,',
5566                          '          typename I>',
5567                          'static void Func() {'])
5568    self.assertEquals(len(self.nesting_state.stack), 1)
5569    self.assertFalse(isinstance(self.nesting_state.stack[0],
5570                                cpplint._ClassInfo))
5571    self.UpdateWithLines(['}',
5572                          'template <class J> class K {'])
5573    self.assertEquals(len(self.nesting_state.stack), 1)
5574    self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo))
5575    self.assertEquals(self.nesting_state.stack[0].name, 'K')
5576
5577  def testTemplateInnerClass(self):
5578    self.UpdateWithLines(['class A {',
5579                          ' public:'])
5580    self.assertEquals(len(self.nesting_state.stack), 1)
5581    self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo))
5582
5583    self.UpdateWithLines(['  template <class B>',
5584                          '  class C<alloc<B> >',
5585                          '      : public A {'])
5586    self.assertEquals(len(self.nesting_state.stack), 2)
5587    self.assertTrue(isinstance(self.nesting_state.stack[1], cpplint._ClassInfo))
5588
5589  def testArguments(self):
5590    self.UpdateWithLines(['class A {'])
5591    self.assertEquals(len(self.nesting_state.stack), 1)
5592    self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo))
5593    self.assertEquals(self.nesting_state.stack[0].name, 'A')
5594    self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 0)
5595
5596    self.UpdateWithLines(['  void Func(',
5597                          '    struct X arg1,'])
5598    self.assertEquals(len(self.nesting_state.stack), 1)
5599    self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 1)
5600    self.UpdateWithLines(['    struct X *arg2);'])
5601    self.assertEquals(len(self.nesting_state.stack), 1)
5602    self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 0)
5603
5604    self.UpdateWithLines(['};'])
5605    self.assertEquals(len(self.nesting_state.stack), 0)
5606
5607    self.UpdateWithLines(['struct B {'])
5608    self.assertEquals(len(self.nesting_state.stack), 1)
5609    self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo))
5610    self.assertEquals(self.nesting_state.stack[0].name, 'B')
5611
5612    self.UpdateWithLines(['#ifdef MACRO',
5613                          '  void Func(',
5614                          '    struct X arg1'])
5615    self.assertEquals(len(self.nesting_state.stack), 1)
5616    self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 1)
5617    self.UpdateWithLines(['#else'])
5618
5619    self.assertEquals(len(self.nesting_state.stack), 1)
5620    self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 0)
5621    self.UpdateWithLines(['  void Func(',
5622                          '    struct X arg1'])
5623    self.assertEquals(len(self.nesting_state.stack), 1)
5624    self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 1)
5625
5626    self.UpdateWithLines(['#endif'])
5627    self.assertEquals(len(self.nesting_state.stack), 1)
5628    self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 1)
5629    self.UpdateWithLines(['    struct X *arg2);'])
5630    self.assertEquals(len(self.nesting_state.stack), 1)
5631    self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 0)
5632
5633    self.UpdateWithLines(['};'])
5634    self.assertEquals(len(self.nesting_state.stack), 0)
5635
5636  def testInlineAssembly(self):
5637    self.UpdateWithLines(['void CopyRow_SSE2(const uint8* src, uint8* dst,',
5638                          '                  int count) {'])
5639    self.assertEquals(len(self.nesting_state.stack), 1)
5640    self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 0)
5641    self.assertEquals(self.nesting_state.stack[-1].inline_asm, cpplint._NO_ASM)
5642
5643    self.UpdateWithLines(['  asm volatile ('])
5644    self.assertEquals(len(self.nesting_state.stack), 1)
5645    self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 1)
5646    self.assertEquals(self.nesting_state.stack[-1].inline_asm,
5647                      cpplint._INSIDE_ASM)
5648
5649    self.UpdateWithLines(['    "sub        %0,%1                         \\n"',
5650                          '  "1:                                         \\n"',
5651                          '    "movdqa    (%0),%%xmm0                    \\n"',
5652                          '    "movdqa    0x10(%0),%%xmm1                \\n"',
5653                          '    "movdqa    %%xmm0,(%0,%1)                 \\n"',
5654                          '    "movdqa    %%xmm1,0x10(%0,%1)             \\n"',
5655                          '    "lea       0x20(%0),%0                    \\n"',
5656                          '    "sub       $0x20,%2                       \\n"',
5657                          '    "jg        1b                             \\n"',
5658                          '  : "+r"(src),   // %0',
5659                          '    "+r"(dst),   // %1',
5660                          '    "+r"(count)  // %2',
5661                          '  :',
5662                          '  : "memory", "cc"'])
5663    self.assertEquals(len(self.nesting_state.stack), 1)
5664    self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 1)
5665    self.assertEquals(self.nesting_state.stack[-1].inline_asm,
5666                      cpplint._INSIDE_ASM)
5667
5668    self.UpdateWithLines(['#if defined(__SSE2__)',
5669                          '    , "xmm0", "xmm1"'])
5670    self.assertEquals(len(self.nesting_state.stack), 1)
5671    self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 1)
5672    self.assertEquals(self.nesting_state.stack[-1].inline_asm,
5673                      cpplint._INSIDE_ASM)
5674
5675    self.UpdateWithLines(['#endif'])
5676    self.assertEquals(len(self.nesting_state.stack), 1)
5677    self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 1)
5678    self.assertEquals(self.nesting_state.stack[-1].inline_asm,
5679                      cpplint._INSIDE_ASM)
5680
5681    self.UpdateWithLines(['  );'])
5682    self.assertEquals(len(self.nesting_state.stack), 1)
5683    self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 0)
5684    self.assertEquals(self.nesting_state.stack[-1].inline_asm, cpplint._END_ASM)
5685
5686    self.UpdateWithLines(['__asm {'])
5687    self.assertEquals(len(self.nesting_state.stack), 2)
5688    self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 0)
5689    self.assertEquals(self.nesting_state.stack[-1].inline_asm,
5690                      cpplint._BLOCK_ASM)
5691
5692    self.UpdateWithLines(['}'])
5693    self.assertEquals(len(self.nesting_state.stack), 1)
5694
5695    self.UpdateWithLines(['}'])
5696    self.assertEquals(len(self.nesting_state.stack), 0)
5697
5698
5699class QuietTest(unittest.TestCase):
5700
5701  def setUp(self):
5702    self.this_dir_path = os.path.dirname(os.path.abspath(__file__))
5703    self.python_executable = sys.executable or 'python'
5704    self.cpplint_test_h = os.path.join(self.this_dir_path,
5705                                       'cpplint_test_header.h')
5706
5707  def _runCppLint(self, *args):
5708    cpplint_abspath = os.path.join(self.this_dir_path, 'cpplint.py')
5709
5710    cmd_line = [self.python_executable, cpplint_abspath] +                     \
5711        list(args) +                                                           \
5712        [ self.cpplint_test_h ]
5713
5714    return_code = 0
5715    try:
5716      output = subprocess.check_output(cmd_line,
5717                                       stderr=subprocess.STDOUT)
5718    except subprocess.CalledProcessError as err:
5719      return_code = err.returncode
5720      output = err.output
5721
5722    return (return_code, output)
5723
5724  def testNonQuietWithErrors(self):
5725    # This will fail: the test header is missing a copyright and header guard.
5726    (return_code, output) = self._runCppLint()
5727    self.assertEquals(1, return_code)
5728    # Always-on behavior: Print error messages as they come up.
5729    self.assertIn("[legal/copyright]", output)
5730    self.assertIn("[build/header_guard]", output)
5731    # If --quiet was unspecified: Print 'Done processing' and 'Total errors..'
5732    self.assertIn("Done processing", output)
5733    self.assertIn("Total errors found:", output)
5734
5735  def testQuietWithErrors(self):
5736    # When there are errors, behavior is identical to not passing --quiet.
5737    (return_code, output) = self._runCppLint('--quiet')
5738    self.assertEquals(1, return_code)
5739    self.assertIn("[legal/copyright]", output)
5740    self.assertIn("[build/header_guard]", output)
5741    # Even though --quiet was used, print these since there were errors.
5742    self.assertIn("Done processing", output)
5743    self.assertIn("Total errors found:", output)
5744
5745  def testNonQuietWithoutErrors(self):
5746    # This will succeed. We filtered out all the known errors for that file.
5747    (return_code, output) = self._runCppLint('--filter=' +
5748                                                '-legal/copyright,' +
5749                                                '-build/header_guard')
5750    self.assertEquals(0, return_code, output)
5751    # No cpplint errors are printed since there were no errors.
5752    self.assertNotIn("[legal/copyright]", output)
5753    self.assertNotIn("[build/header_guard]", output)
5754    # Print 'Done processing' and 'Total errors found' since
5755    # --quiet was not specified.
5756    self.assertIn("Done processing", output)
5757    self.assertIn("Total errors found:", output)
5758
5759  def testQuietWithoutErrors(self):
5760    # This will succeed. We filtered out all the known errors for that file.
5761    (return_code, output) = self._runCppLint('--quiet',
5762                                             '--filter=' +
5763                                                 '-legal/copyright,' +
5764                                                 '-build/header_guard')
5765    self.assertEquals(0, return_code, output)
5766    # No cpplint errors are printed since there were no errors.
5767    self.assertNotIn("[legal/copyright]", output)
5768    self.assertNotIn("[build/header_guard]", output)
5769    # --quiet was specified and there were no errors:
5770    # skip the printing of 'Done processing' and 'Total errors..'
5771    self.assertNotIn("Done processing", output)
5772    self.assertNotIn("Total errors found:", output)
5773    # Output with no errors must be completely blank!
5774    self.assertEquals("", output)
5775
5776# pylint: disable-msg=C6409
5777def setUp():
5778  """Runs before all tests are executed.
5779  """
5780  # Enable all filters, so we don't miss anything that is off by default.
5781  cpplint._DEFAULT_FILTERS = []
5782  cpplint._cpplint_state.SetFilters('')
5783
5784
5785# pylint: disable-msg=C6409
5786def tearDown():
5787  """A global check to make sure all error-categories have been tested.
5788
5789  The main tearDown() routine is the only code we can guarantee will be
5790  run after all other tests have been executed.
5791  """
5792  try:
5793    if _run_verifyallcategoriesseen:
5794      ErrorCollector(None).VerifyAllCategoriesAreSeen()
5795  except NameError:
5796    # If nobody set the global _run_verifyallcategoriesseen, then
5797    # we assume we should silently not run the test
5798    pass
5799
5800
5801if __name__ == '__main__':
5802  # We don't want to run the VerifyAllCategoriesAreSeen() test unless
5803  # we're running the full test suite: if we only run one test,
5804  # obviously we're not going to see all the error categories.  So we
5805  # only run VerifyAllCategoriesAreSeen() when no commandline flags
5806  # are passed in.
5807  global _run_verifyallcategoriesseen
5808  _run_verifyallcategoriesseen = (len(sys.argv) == 1)
5809
5810  setUp()
5811  unittest.main()
5812  tearDown()
5813