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