Statistics
| Branch: | Tag: | Revision:

amiro-os / tools / cpplint / python / cpplint_unittest.py @ b2053cb5

History | View | Annotate | Download (216.815 KB)

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

    
36
import codecs
37
import os
38
import random
39
import re
40
import sys
41
import unittest
42

    
43
import cpplint
44

    
45

    
46
# This class works as an error collector and replaces cpplint.Error
47
# function for the unit tests.  We also verify each category we see
48
# is in cpplint._ERROR_CATEGORIES, to help keep that list up to date.
49
class ErrorCollector(object):
50
  # These are a global list, covering all categories seen ever.
51
  _ERROR_CATEGORIES = cpplint._ERROR_CATEGORIES
52
  _SEEN_ERROR_CATEGORIES = {}
53

    
54
  def __init__(self, assert_fn):
55
    """assert_fn: a function to call when we notice a problem."""
56
    self._assert_fn = assert_fn
57
    self._errors = []
58
    cpplint.ResetNolintSuppressions()
59

    
60
  def __call__(self, unused_filename, linenum,
61
               category, confidence, message):
62
    self._assert_fn(category in self._ERROR_CATEGORIES,
63
                    'Message "%s" has category "%s",'
64
                    ' which is not in _ERROR_CATEGORIES' % (message, category))
65
    self._SEEN_ERROR_CATEGORIES[category] = 1
66
    if cpplint._ShouldPrintError(category, confidence, linenum):
67
      self._errors.append('%s  [%s] [%d]' % (message, category, confidence))
68

    
69
  def Results(self):
70
    if len(self._errors) < 2:
71
      return ''.join(self._errors)  # Most tests expect to have a string.
72
    else:
73
      return self._errors  # Let's give a list if there is more than one.
74

    
75
  def ResultList(self):
76
    return self._errors
77

    
78
  def VerifyAllCategoriesAreSeen(self):
79
    """Fails if there's a category in _ERROR_CATEGORIES~_SEEN_ERROR_CATEGORIES.
80

81
    This should only be called after all tests are run, so
82
    _SEEN_ERROR_CATEGORIES has had a chance to fully populate.  Since
83
    this isn't called from within the normal unittest framework, we
84
    can't use the normal unittest assert macros.  Instead we just exit
85
    when we see an error.  Good thing this test is always run last!
86
    """
87
    for category in self._ERROR_CATEGORIES:
88
      if category not in self._SEEN_ERROR_CATEGORIES:
89
        sys.exit('FATAL ERROR: There are no tests for category "%s"' % category)
90

    
91
  def RemoveIfPresent(self, substr):
92
    for (index, error) in enumerate(self._errors):
93
      if error.find(substr) != -1:
94
        self._errors = self._errors[0:index] + self._errors[(index + 1):]
95
        break
96

    
97

    
98
# This class is a lame mock of codecs. We do not verify filename, mode, or
99
# encoding, but for the current use case it is not needed.
100
class MockIo(object):
101

    
102
  def __init__(self, mock_file):
103
    self.mock_file = mock_file
104

    
105
  def open(self,  # pylint: disable-msg=C6409
106
           unused_filename, unused_mode, unused_encoding, _):
107
    return self.mock_file
108

    
109

    
110
class CpplintTestBase(unittest.TestCase):
111
  """Provides some useful helper functions for cpplint tests."""
112

    
113
  def setUp(self):
114
    # Allow subclasses to cheat os.path.abspath called in FileInfo class.
115
    self.os_path_abspath_orig = os.path.abspath
116

    
117
  def tearDown(self):
118
    os.path.abspath = self.os_path_abspath_orig
119

    
120
  # Perform lint on single line of input and return the error message.
121
  def PerformSingleLineLint(self, code):
122
    error_collector = ErrorCollector(self.assert_)
123
    lines = code.split('\n')
124
    cpplint.RemoveMultiLineComments('foo.h', lines, error_collector)
125
    clean_lines = cpplint.CleansedLines(lines)
126
    include_state = cpplint._IncludeState()
127
    function_state = cpplint._FunctionState()
128
    nesting_state = cpplint.NestingState()
129
    cpplint.ProcessLine('foo.cc', 'cc', clean_lines, 0,
130
                        include_state, function_state,
131
                        nesting_state, error_collector)
132
    # Single-line lint tests are allowed to fail the 'unlintable function'
133
    # check.
134
    error_collector.RemoveIfPresent(
135
        'Lint failed to find start of function body.')
136
    return error_collector.Results()
137

    
138
  # Perform lint over multiple lines and return the error message.
139
  def PerformMultiLineLint(self, code):
140
    error_collector = ErrorCollector(self.assert_)
141
    lines = code.split('\n')
142
    cpplint.RemoveMultiLineComments('foo.h', lines, error_collector)
143
    lines = cpplint.CleansedLines(lines)
144
    nesting_state = cpplint.NestingState()
145
    for i in xrange(lines.NumLines()):
146
      nesting_state.Update('foo.h', lines, i, error_collector)
147
      cpplint.CheckStyle('foo.h', lines, i, 'h', nesting_state,
148
                         error_collector)
149
      cpplint.CheckForNonStandardConstructs('foo.h', lines, i,
150
                                            nesting_state, error_collector)
151
    nesting_state.CheckCompletedBlocks('foo.h', error_collector)
152
    return error_collector.Results()
153

    
154
  # Similar to PerformMultiLineLint, but calls CheckLanguage instead of
155
  # CheckForNonStandardConstructs
156
  def PerformLanguageRulesCheck(self, file_name, code):
157
    error_collector = ErrorCollector(self.assert_)
158
    include_state = cpplint._IncludeState()
159
    nesting_state = cpplint.NestingState()
160
    lines = code.split('\n')
161
    cpplint.RemoveMultiLineComments(file_name, lines, error_collector)
162
    lines = cpplint.CleansedLines(lines)
163
    ext = file_name[file_name.rfind('.') + 1:]
164
    for i in xrange(lines.NumLines()):
165
      cpplint.CheckLanguage(file_name, lines, i, ext, include_state,
166
                            nesting_state, error_collector)
167
    return error_collector.Results()
168

    
169
  def PerformFunctionLengthsCheck(self, code):
170
    """Perform Lint function length check on block of code and return warnings.
171

172
    Builds up an array of lines corresponding to the code and strips comments
173
    using cpplint functions.
174

175
    Establishes an error collector and invokes the function length checking
176
    function following cpplint's pattern.
177

178
    Args:
179
      code: C++ source code expected to generate a warning message.
180

181
    Returns:
182
      The accumulated errors.
183
    """
184
    file_name = 'foo.cc'
185
    error_collector = ErrorCollector(self.assert_)
186
    function_state = cpplint._FunctionState()
187
    lines = code.split('\n')
188
    cpplint.RemoveMultiLineComments(file_name, lines, error_collector)
189
    lines = cpplint.CleansedLines(lines)
190
    for i in xrange(lines.NumLines()):
191
      cpplint.CheckForFunctionLengths(file_name, lines, i,
192
                                      function_state, error_collector)
193
    return error_collector.Results()
194

    
195
  def PerformIncludeWhatYouUse(self, code, filename='foo.h', io=codecs):
196
    # First, build up the include state.
197
    error_collector = ErrorCollector(self.assert_)
198
    include_state = cpplint._IncludeState()
199
    nesting_state = cpplint.NestingState()
200
    lines = code.split('\n')
201
    cpplint.RemoveMultiLineComments(filename, lines, error_collector)
202
    lines = cpplint.CleansedLines(lines)
203
    for i in xrange(lines.NumLines()):
204
      cpplint.CheckLanguage(filename, lines, i, '.h', include_state,
205
                            nesting_state, error_collector)
206
    # We could clear the error_collector here, but this should
207
    # also be fine, since our IncludeWhatYouUse unittests do not
208
    # have language problems.
209

    
210
    # Second, look for missing includes.
211
    cpplint.CheckForIncludeWhatYouUse(filename, lines, include_state,
212
                                      error_collector, io)
213
    return error_collector.Results()
214

    
215
  # Perform lint and compare the error message with "expected_message".
216
  def TestLint(self, code, expected_message):
217
    self.assertEquals(expected_message, self.PerformSingleLineLint(code))
218

    
219
  def TestMultiLineLint(self, code, expected_message):
220
    self.assertEquals(expected_message, self.PerformMultiLineLint(code))
221

    
222
  def TestMultiLineLintRE(self, code, expected_message_re):
223
    message = self.PerformMultiLineLint(code)
224
    if not re.search(expected_message_re, message):
225
      self.fail('Message was:\n' + message + 'Expected match to "' +
226
                expected_message_re + '"')
227

    
228
  def TestLanguageRulesCheck(self, file_name, code, expected_message):
229
    self.assertEquals(expected_message,
230
                      self.PerformLanguageRulesCheck(file_name, code))
231

    
232
  def TestIncludeWhatYouUse(self, code, expected_message):
233
    self.assertEquals(expected_message,
234
                      self.PerformIncludeWhatYouUse(code))
235

    
236
  def TestBlankLinesCheck(self, lines, start_errors, end_errors):
237
    error_collector = ErrorCollector(self.assert_)
238
    cpplint.ProcessFileData('foo.cc', 'cc', lines, error_collector)
239
    self.assertEquals(
240
        start_errors,
241
        error_collector.Results().count(
242
            'Redundant blank line at the start of a code block '
243
            'should be deleted.  [whitespace/blank_line] [2]'))
244
    self.assertEquals(
245
        end_errors,
246
        error_collector.Results().count(
247
            'Redundant blank line at the end of a code block '
248
            'should be deleted.  [whitespace/blank_line] [3]'))
249

    
250

    
251
class CpplintTest(CpplintTestBase):
252

    
253
  def GetNamespaceResults(self, lines):
254
    error_collector = ErrorCollector(self.assert_)
255
    cpplint.RemoveMultiLineComments('foo.h', lines, error_collector)
256
    lines = cpplint.CleansedLines(lines)
257
    nesting_state = cpplint.NestingState()
258
    for i in xrange(lines.NumLines()):
259
      nesting_state.Update('foo.h', lines, i, error_collector)
260
      cpplint.CheckForNamespaceIndentation('foo.h', nesting_state,
261
                                           lines, i, error_collector)
262

    
263
    return error_collector.Results()
264

    
265
  def testForwardDeclarationNameSpaceIndentation(self):
266
    lines = ['namespace Test {',
267
             '  class ForwardDeclaration;',
268
             '}  // namespace Test']
269

    
270
    results = self.GetNamespaceResults(lines)
271
    self.assertEquals(results, 'Do not indent within a namespace '
272
                      ' [runtime/indentation_namespace] [4]')
273

    
274
  def testNameSpaceIndentationForClass(self):
275
    lines = ['namespace Test {',
276
             'void foo() { }',
277
             '  class Test {',
278
             '  };',
279
             '}  // namespace Test']
280

    
281
    results = self.GetNamespaceResults(lines)
282
    self.assertEquals(results, 'Do not indent within a namespace '
283
                      ' [runtime/indentation_namespace] [4]')
284

    
285
  def testNameSpaceIndentationNoError(self):
286
    lines = ['namespace Test {',
287
             'void foo() { }',
288
             '}  // namespace Test']
289

    
290
    results = self.GetNamespaceResults(lines)
291
    self.assertEquals(results, '')
292

    
293
  def testFalsePositivesNoError(self):
294
    lines = ['namespace Test {',
295
             'struct OuterClass {',
296
             '  struct NoFalsePositivesHere;',
297
             '  struct NoFalsePositivesHere member_variable;',
298
             '};',
299
             '}  // namespace Test']
300

    
301
    results = self.GetNamespaceResults(lines)
302
    self.assertEquals(results, '')
303

    
304

    
305
  # Test get line width.
306
  def testGetLineWidth(self):
307
    self.assertEquals(0, cpplint.GetLineWidth(''))
308
    self.assertEquals(10, cpplint.GetLineWidth(u'x' * 10))
309
    self.assertEquals(16, cpplint.GetLineWidth(u'都|道|府|県|支庁'))
310

    
311
  def testGetTextInside(self):
312
    self.assertEquals('', cpplint._GetTextInside('fun()', r'fun\('))
313
    self.assertEquals('x, y', cpplint._GetTextInside('f(x, y)', r'f\('))
314
    self.assertEquals('a(), b(c())', cpplint._GetTextInside(
315
        'printf(a(), b(c()))', r'printf\('))
316
    self.assertEquals('x, y{}', cpplint._GetTextInside('f[x, y{}]', r'f\['))
317
    self.assertEquals(None, cpplint._GetTextInside('f[a, b(}]', r'f\['))
318
    self.assertEquals(None, cpplint._GetTextInside('f[x, y]', r'f\('))
319
    self.assertEquals('y, h(z, (a + b))', cpplint._GetTextInside(
320
        'f(x, g(y, h(z, (a + b))))', r'g\('))
321
    self.assertEquals('f(f(x))', cpplint._GetTextInside('f(f(f(x)))', r'f\('))
322
    # Supports multiple lines.
323
    self.assertEquals('\n  return loop(x);\n',
324
                      cpplint._GetTextInside(
325
                          'int loop(int x) {\n  return loop(x);\n}\n', r'\{'))
326
    # '^' matches the beginning of each line.
327
    self.assertEquals('x, y',
328
                      cpplint._GetTextInside(
329
                          '#include "inl.h"  // skip #define\n'
330
                          '#define A2(x, y) a_inl_(x, y, __LINE__)\n'
331
                          '#define A(x) a_inl_(x, "", __LINE__)\n',
332
                          r'^\s*#define\s*\w+\('))
333

    
334
  def testFindNextMultiLineCommentStart(self):
335
    self.assertEquals(1, cpplint.FindNextMultiLineCommentStart([''], 0))
336

    
337
    lines = ['a', 'b', '/* c']
338
    self.assertEquals(2, cpplint.FindNextMultiLineCommentStart(lines, 0))
339

    
340
    lines = ['char a[] = "/*";']  # not recognized as comment.
341
    self.assertEquals(1, cpplint.FindNextMultiLineCommentStart(lines, 0))
342

    
343
  def testFindNextMultiLineCommentEnd(self):
344
    self.assertEquals(1, cpplint.FindNextMultiLineCommentEnd([''], 0))
345
    lines = ['a', 'b', ' c */']
346
    self.assertEquals(2, cpplint.FindNextMultiLineCommentEnd(lines, 0))
347

    
348
  def testRemoveMultiLineCommentsFromRange(self):
349
    lines = ['a', '  /* comment ', ' * still comment', ' comment */   ', 'b']
350
    cpplint.RemoveMultiLineCommentsFromRange(lines, 1, 4)
351
    self.assertEquals(['a', '/**/', '/**/', '/**/', 'b'], lines)
352

    
353
  def testSpacesAtEndOfLine(self):
354
    self.TestLint(
355
        '// Hello there ',
356
        'Line ends in whitespace.  Consider deleting these extra spaces.'
357
        '  [whitespace/end_of_line] [4]')
358

    
359
  # Test line length check.
360
  def testLineLengthCheck(self):
361
    self.TestLint(
362
        '// Hello',
363
        '')
364
    self.TestLint(
365
        '// ' + 'x' * 80,
366
        'Lines should be <= 80 characters long'
367
        '  [whitespace/line_length] [2]')
368
    self.TestLint(
369
        '// ' + 'x' * 100,
370
        'Lines should very rarely be longer than 100 characters'
371
        '  [whitespace/line_length] [4]')
372
    self.TestLint(
373
        '// http://g' + ('o' * 100) + 'gle.com/',
374
        '')
375
    self.TestLint(
376
        '//   https://g' + ('o' * 100) + 'gle.com/',
377
        '')
378
    self.TestLint(
379
        '//   https://g' + ('o' * 60) + 'gle.com/ and some comments',
380
        'Lines should be <= 80 characters long'
381
        '  [whitespace/line_length] [2]')
382
    self.TestLint(
383
        '// Read https://g' + ('o' * 60) + 'gle.com/',
384
        '')
385
    self.TestLint(
386
        '// $Id: g' + ('o' * 80) + 'gle.cc#1 $',
387
        '')
388
    self.TestLint(
389
        '// $Id: g' + ('o' * 80) + 'gle.cc#1',
390
        'Lines should be <= 80 characters long'
391
        '  [whitespace/line_length] [2]')
392
    self.TestMultiLineLint(
393
        'static const char kCStr[] = "g' + ('o' * 50) + 'gle";\n',
394
        'Lines should be <= 80 characters long'
395
        '  [whitespace/line_length] [2]')
396
    self.TestMultiLineLint(
397
        'static const char kRawStr[] = R"(g' + ('o' * 50) + 'gle)";\n',
398
        '')  # no warning because raw string content is elided
399
    self.TestMultiLineLint(
400
        'static const char kMultiLineRawStr[] = R"(\n'
401
        'g' + ('o' * 80) + 'gle\n'
402
        ')";',
403
        '')
404
    self.TestMultiLineLint(
405
        'static const char kL' + ('o' * 50) + 'ngIdentifier[] = R"()";\n',
406
        'Lines should be <= 80 characters long'
407
        '  [whitespace/line_length] [2]')
408

    
409
  # Test error suppression annotations.
410
  def testErrorSuppression(self):
411
    # Two errors on same line:
412
    self.TestLint(
413
        'long a = (int64) 65;',
414
        ['Using C-style cast.  Use static_cast<int64>(...) instead'
415
         '  [readability/casting] [4]',
416
         'Use int16/int64/etc, rather than the C type long'
417
         '  [runtime/int] [4]',
418
        ])
419
    # One category of error suppressed:
420
    self.TestLint(
421
        'long a = (int64) 65;  // NOLINT(runtime/int)',
422
        'Using C-style cast.  Use static_cast<int64>(...) instead'
423
        '  [readability/casting] [4]')
424
    # All categories suppressed: (two aliases)
425
    self.TestLint('long a = (int64) 65;  // NOLINT', '')
426
    self.TestLint('long a = (int64) 65;  // NOLINT(*)', '')
427
    # Malformed NOLINT directive:
428
    self.TestLint(
429
        'long a = 65;  // NOLINT(foo)',
430
        ['Unknown NOLINT error category: foo'
431
         '  [readability/nolint] [5]',
432
         'Use int16/int64/etc, rather than the C type long  [runtime/int] [4]',
433
        ])
434
    # Irrelevant NOLINT directive has no effect:
435
    self.TestLint(
436
        'long a = 65;  // NOLINT(readability/casting)',
437
        'Use int16/int64/etc, rather than the C type long'
438
        '  [runtime/int] [4]')
439
    # NOLINTNEXTLINE silences warning for the next line instead of current line
440
    error_collector = ErrorCollector(self.assert_)
441
    cpplint.ProcessFileData('test.cc', 'cc',
442
                            ['// Copyright 2014 Your Company.',
443
                             '// NOLINTNEXTLINE(whitespace/line_length)',
444
                             '//  ./command' + (' -verbose' * 80),
445
                             ''],
446
                            error_collector)
447
    self.assertEquals('', error_collector.Results())
448

    
449
  # Test Variable Declarations.
450
  def testVariableDeclarations(self):
451
    self.TestLint(
452
        'long a = 65;',
453
        'Use int16/int64/etc, rather than the C type long'
454
        '  [runtime/int] [4]')
455
    self.TestLint(
456
        'long double b = 65.0;',
457
        '')
458
    self.TestLint(
459
        'long long aa = 6565;',
460
        'Use int16/int64/etc, rather than the C type long'
461
        '  [runtime/int] [4]')
462

    
463
  # Test C-style cast cases.
464
  def testCStyleCast(self):
465
    self.TestLint(
466
        'int a = (int)1.0;',
467
        'Using C-style cast.  Use static_cast<int>(...) instead'
468
        '  [readability/casting] [4]')
469
    self.TestLint(
470
        'int a = (int)-1.0;',
471
        'Using C-style cast.  Use static_cast<int>(...) instead'
472
        '  [readability/casting] [4]')
473
    self.TestLint(
474
        'int *a = (int *)NULL;',
475
        'Using C-style cast.  Use reinterpret_cast<int *>(...) instead'
476
        '  [readability/casting] [4]')
477

    
478
    self.TestLint(
479
        'uint16 a = (uint16)1.0;',
480
        'Using C-style cast.  Use static_cast<uint16>(...) instead'
481
        '  [readability/casting] [4]')
482
    self.TestLint(
483
        'int32 a = (int32)1.0;',
484
        'Using C-style cast.  Use static_cast<int32>(...) instead'
485
        '  [readability/casting] [4]')
486
    self.TestLint(
487
        'uint64 a = (uint64)1.0;',
488
        'Using C-style cast.  Use static_cast<uint64>(...) instead'
489
        '  [readability/casting] [4]')
490

    
491
    # These shouldn't be recognized casts.
492
    self.TestLint('u a = (u)NULL;', '')
493
    self.TestLint('uint a = (uint)NULL;', '')
494
    self.TestLint('typedef MockCallback<int(int)> CallbackType;', '')
495
    self.TestLint('scoped_ptr< MockCallback<int(int)> > callback_value;', '')
496
    self.TestLint('std::function<int(bool)>', '')
497
    self.TestLint('x = sizeof(int)', '')
498
    self.TestLint('x = alignof(int)', '')
499
    self.TestLint('alignas(int) char x[42]', '')
500
    self.TestLint('alignas(alignof(x)) char y[42]', '')
501
    self.TestLint('void F(int (func)(int));', '')
502
    self.TestLint('void F(int (func)(int*));', '')
503
    self.TestLint('void F(int (Class::member)(int));', '')
504
    self.TestLint('void F(int (Class::member)(int*));', '')
505
    self.TestLint('void F(int (Class::member)(int), int param);', '')
506
    self.TestLint('void F(int (Class::member)(int*), int param);', '')
507

    
508
    # These should not be recognized (lambda functions without arg names).
509
    self.TestLint('[](int/*unused*/) -> bool {', '')
510
    self.TestLint('[](int /*unused*/) -> bool {', '')
511
    self.TestLint('auto f = [](MyStruct* /*unused*/)->int {', '')
512
    self.TestLint(
513
        '[](int) -> bool {',
514
        'All parameters should be named in a function'
515
        '  [readability/function] [3]')
516
    self.TestLint(
517
        'auto f = [](MyStruct*)->int {',
518
        'All parameters should be named in a function'
519
        '  [readability/function] [3]')
520

    
521
  # Test taking address of casts (runtime/casting)
522
  def testRuntimeCasting(self):
523
    error_msg = ('Are you taking an address of a cast?  '
524
                 'This is dangerous: could be a temp var.  '
525
                 'Take the address before doing the cast, rather than after'
526
                 '  [runtime/casting] [4]')
527
    self.TestLint('int* x = &static_cast<int*>(foo);', error_msg)
528
    self.TestLint('int* x = &reinterpret_cast<int *>(foo);', error_msg)
529
    self.TestLint('int* x = &(int*)foo;',
530
                  ['Using C-style cast.  Use reinterpret_cast<int*>(...) '
531
                   'instead  [readability/casting] [4]',
532
                   error_msg])
533
    self.TestLint('BudgetBuckets&(BudgetWinHistory::*BucketFn)(void) const;',
534
                  '')
535
    self.TestLint('&(*func_ptr)(arg)', '')
536
    self.TestLint('Compute(arg, &(*func_ptr)(i, j));', '')
537

    
538
    # Alternative error message
539
    alt_error_msg = ('Are you taking an address of something dereferenced '
540
                     'from a cast?  Wrapping the dereferenced expression in '
541
                     'parentheses will make the binding more obvious'
542
                     '  [readability/casting] [4]')
543
    self.TestLint('int* x = &down_cast<Obj*>(obj)->member_;', alt_error_msg)
544
    self.TestLint('int* x = &down_cast<Obj*>(obj)[index];', alt_error_msg)
545
    self.TestLint('int* x = &(down_cast<Obj*>(obj)->member_);', '')
546
    self.TestLint('int* x = &(down_cast<Obj*>(obj)[index]);', '')
547
    self.TestLint('int* x = &down_cast<Obj*>(obj)\n->member_;', alt_error_msg)
548
    self.TestLint('int* x = &(down_cast<Obj*>(obj)\n->member_);', '')
549

    
550
    # It's OK to cast an address.
551
    self.TestLint('int* x = reinterpret_cast<int *>(&foo);', '')
552

    
553
    # Function pointers returning references should not be confused
554
    # with taking address of old-style casts.
555
    self.TestLint('auto x = implicit_cast<string &(*)(int)>(&foo);', '')
556

    
557
  def testRuntimeSelfinit(self):
558
    self.TestLint(
559
        'Foo::Foo(Bar r, Bel l) : r_(r_), l_(l_) { }',
560
        'You seem to be initializing a member variable with itself.'
561
        '  [runtime/init] [4]')
562
    self.TestLint(
563
        'Foo::Foo(Bar r, Bel l) : r_(r), l_(l) { }',
564
        '')
565
    self.TestLint(
566
        'Foo::Foo(Bar r) : r_(r), l_(r_), ll_(l_) { }',
567
        '')
568

    
569
  # Test for unnamed arguments in a method.
570
  def testCheckForUnnamedParams(self):
571
    message = ('All parameters should be named in a function'
572
               '  [readability/function] [3]')
573
    self.TestLint('virtual void Func(int*) const;', message)
574
    self.TestLint('virtual void Func(int*);', message)
575
    self.TestLint('void Method(char*) {', message)
576
    self.TestLint('void Method(char*);', message)
577
    self.TestLint('static void operator delete[](void*) throw();', message)
578
    self.TestLint('int Method(int);', message)
579

    
580
    self.TestLint('virtual void Func(int* p);', '')
581
    self.TestLint('void operator delete(void* x) throw();', '')
582
    self.TestLint('void Method(char* x) {', '')
583
    self.TestLint('void Method(char* /*x*/) {', '')
584
    self.TestLint('void Method(char* x);', '')
585
    self.TestLint('typedef void (*Method)(int32 x);', '')
586
    self.TestLint('static void operator delete[](void* x) throw();', '')
587
    self.TestLint('static void operator delete[](void* /*x*/) throw();', '')
588

    
589
    self.TestLint('X operator++(int);', '')
590
    self.TestLint('X operator++(int) {', '')
591
    self.TestLint('X operator--(int);', '')
592
    self.TestLint('X operator--(int /*unused*/) {', '')
593
    self.TestLint('MACRO(int);', '')
594
    self.TestLint('MACRO(func(int));', '')
595
    self.TestLint('MACRO(arg, func(int));', '')
596

    
597
    self.TestLint('void (*func)(void*);', '')
598
    self.TestLint('void Func((*func)(void*)) {}', '')
599
    self.TestLint('template <void Func(void*)> void func();', '')
600
    self.TestLint('virtual void f(int /*unused*/) {', '')
601
    self.TestLint('void f(int /*unused*/) override {', '')
602
    self.TestLint('void f(int /*unused*/) final {', '')
603

    
604
  # Test deprecated casts such as int(d)
605
  def testDeprecatedCast(self):
606
    self.TestLint(
607
        'int a = int(2.2);',
608
        'Using deprecated casting style.  '
609
        'Use static_cast<int>(...) instead'
610
        '  [readability/casting] [4]')
611

    
612
    self.TestLint(
613
        '(char *) "foo"',
614
        'Using C-style cast.  '
615
        'Use const_cast<char *>(...) instead'
616
        '  [readability/casting] [4]')
617

    
618
    self.TestLint(
619
        '(int*)foo',
620
        'Using C-style cast.  '
621
        'Use reinterpret_cast<int*>(...) instead'
622
        '  [readability/casting] [4]')
623

    
624
    # Checks for false positives...
625
    self.TestLint('int a = int();', '')  # constructor
626
    self.TestLint('X::X() : a(int()) {}', '')  # default constructor
627
    self.TestLint('operator bool();', '')  # Conversion operator
628
    self.TestLint('new int64(123);', '')  # "new" operator on basic type
629
    self.TestLint('new   int64(123);', '')  # "new" operator on basic type
630
    self.TestLint('using a = bool(int arg);', '')  # C++11 alias-declaration
631
    self.TestLint('x = bit_cast<double(*)[3]>(y);', '')  # array of array
632
    self.TestLint('void F(const char(&src)[N]);', '')  # array of references
633

    
634
    # Placement new
635
    self.TestLint(
636
        'new(field_ptr) int(field->default_value_enum()->number());',
637
        '')
638

    
639
    # C++11 function wrappers
640
    self.TestLint('std::function<int(bool)>', '')
641
    self.TestLint('std::function<const int(bool)>', '')
642
    self.TestLint('std::function< int(bool) >', '')
643
    self.TestLint('mfunction<int(bool)>', '')
644

    
645
    error_collector = ErrorCollector(self.assert_)
646
    cpplint.ProcessFileData(
647
        'test.cc', 'cc',
648
        ['// Copyright 2014 Your Company. All Rights Reserved.',
649
         'typedef std::function<',
650
         '    bool(int)> F;',
651
         ''],
652
        error_collector)
653
    self.assertEquals('', error_collector.Results())
654

    
655
    # Return types for function pointers
656
    self.TestLint('typedef bool(FunctionPointer)();', '')
657
    self.TestLint('typedef bool(FunctionPointer)(int param);', '')
658
    self.TestLint('typedef bool(MyClass::*MemberFunctionPointer)();', '')
659
    self.TestLint('typedef bool(MyClass::* MemberFunctionPointer)();', '')
660
    self.TestLint('typedef bool(MyClass::*MemberFunctionPointer)() const;', '')
661
    self.TestLint('void Function(bool(FunctionPointerArg)());', '')
662
    self.TestLint('void Function(bool(FunctionPointerArg)()) {}', '')
663
    self.TestLint('typedef set<int64, bool(*)(int64, int64)> SortedIdSet', '')
664
    self.TestLint(
665
        'bool TraverseNode(T *Node, bool(VisitorBase:: *traverse) (T *t)) {}',
666
        '')
667

    
668
  # The second parameter to a gMock method definition is a function signature
669
  # that often looks like a bad cast but should not picked up by lint.
670
  def testMockMethod(self):
671
    self.TestLint(
672
        'MOCK_METHOD0(method, int());',
673
        '')
674
    self.TestLint(
675
        'MOCK_CONST_METHOD1(method, float(string));',
676
        '')
677
    self.TestLint(
678
        'MOCK_CONST_METHOD2_T(method, double(float, float));',
679
        '')
680
    self.TestLint(
681
        'MOCK_CONST_METHOD1(method, SomeType(int));',
682
        '')
683

    
684
    error_collector = ErrorCollector(self.assert_)
685
    cpplint.ProcessFileData('mock.cc', 'cc',
686
                            ['MOCK_METHOD1(method1,',
687
                             '             bool(int));',
688
                             'MOCK_METHOD1(',
689
                             '    method2,',
690
                             '    bool(int));',
691
                             'MOCK_CONST_METHOD2(',
692
                             '    method3, bool(int,',
693
                             '                  int));',
694
                             'MOCK_METHOD1(method4, int(bool));',
695
                             'const int kConstant = int(42);'],  # true positive
696
                            error_collector)
697
    self.assertEquals(
698
        0,
699
        error_collector.Results().count(
700
            ('Using deprecated casting style.  '
701
             'Use static_cast<bool>(...) instead  '
702
             '[readability/casting] [4]')))
703
    self.assertEquals(
704
        1,
705
        error_collector.Results().count(
706
            ('Using deprecated casting style.  '
707
             'Use static_cast<int>(...) instead  '
708
             '[readability/casting] [4]')))
709

    
710
  # Like gMock method definitions, MockCallback instantiations look very similar
711
  # to bad casts.
712
  def testMockCallback(self):
713
    self.TestLint(
714
        'MockCallback<bool(int)>',
715
        '')
716
    self.TestLint(
717
        'MockCallback<int(float, char)>',
718
        '')
719

    
720
  # Test false errors that happened with some include file names
721
  def testIncludeFilenameFalseError(self):
722
    self.TestLint(
723
        '#include "foo/long-foo.h"',
724
        '')
725
    self.TestLint(
726
        '#include "foo/sprintf.h"',
727
        '')
728

    
729
  # Test typedef cases.  There was a bug that cpplint misidentified
730
  # typedef for pointer to function as C-style cast and produced
731
  # false-positive error messages.
732
  def testTypedefForPointerToFunction(self):
733
    self.TestLint(
734
        'typedef void (*Func)(int x);',
735
        '')
736
    self.TestLint(
737
        'typedef void (*Func)(int *x);',
738
        '')
739
    self.TestLint(
740
        'typedef void Func(int x);',
741
        '')
742
    self.TestLint(
743
        'typedef void Func(int *x);',
744
        '')
745

    
746
  def testIncludeWhatYouUseNoImplementationFiles(self):
747
    code = 'std::vector<int> foo;'
748
    self.assertEquals('Add #include <vector> for vector<>'
749
                      '  [build/include_what_you_use] [4]',
750
                      self.PerformIncludeWhatYouUse(code, 'foo.h'))
751
    self.assertEquals('',
752
                      self.PerformIncludeWhatYouUse(code, 'foo.cc'))
753

    
754
  def testIncludeWhatYouUse(self):
755
    self.TestIncludeWhatYouUse(
756
        """#include <vector>
757
           std::vector<int> foo;
758
        """,
759
        '')
760
    self.TestIncludeWhatYouUse(
761
        """#include <map>
762
           std::pair<int,int> foo;
763
        """,
764
        'Add #include <utility> for pair<>'
765
        '  [build/include_what_you_use] [4]')
766
    self.TestIncludeWhatYouUse(
767
        """#include <multimap>
768
           std::pair<int,int> foo;
769
        """,
770
        'Add #include <utility> for pair<>'
771
        '  [build/include_what_you_use] [4]')
772
    self.TestIncludeWhatYouUse(
773
        """#include <hash_map>
774
           std::pair<int,int> foo;
775
        """,
776
        'Add #include <utility> for pair<>'
777
        '  [build/include_what_you_use] [4]')
778
    self.TestIncludeWhatYouUse(
779
        """#include <utility>
780
           std::pair<int,int> foo;
781
        """,
782
        '')
783
    self.TestIncludeWhatYouUse(
784
        """#include <vector>
785
           DECLARE_string(foobar);
786
        """,
787
        '')
788
    self.TestIncludeWhatYouUse(
789
        """#include <vector>
790
           DEFINE_string(foobar, "", "");
791
        """,
792
        '')
793
    self.TestIncludeWhatYouUse(
794
        """#include <vector>
795
           std::pair<int,int> foo;
796
        """,
797
        'Add #include <utility> for pair<>'
798
        '  [build/include_what_you_use] [4]')
799
    self.TestIncludeWhatYouUse(
800
        """#include "base/foobar.h"
801
           std::vector<int> foo;
802
        """,
803
        'Add #include <vector> for vector<>'
804
        '  [build/include_what_you_use] [4]')
805
    self.TestIncludeWhatYouUse(
806
        """#include <vector>
807
           std::set<int> foo;
808
        """,
809
        'Add #include <set> for set<>'
810
        '  [build/include_what_you_use] [4]')
811
    self.TestIncludeWhatYouUse(
812
        """#include "base/foobar.h"
813
          hash_map<int, int> foobar;
814
        """,
815
        'Add #include <hash_map> for hash_map<>'
816
        '  [build/include_what_you_use] [4]')
817
    self.TestIncludeWhatYouUse(
818
        """#include "base/foobar.h"
819
           bool foobar = std::less<int>(0,1);
820
        """,
821
        'Add #include <functional> for less<>'
822
        '  [build/include_what_you_use] [4]')
823
    self.TestIncludeWhatYouUse(
824
        """#include "base/foobar.h"
825
           bool foobar = min<int>(0,1);
826
        """,
827
        'Add #include <algorithm> for min  [build/include_what_you_use] [4]')
828
    self.TestIncludeWhatYouUse(
829
        'void a(const string &foobar);',
830
        'Add #include <string> for string  [build/include_what_you_use] [4]')
831
    self.TestIncludeWhatYouUse(
832
        'void a(const std::string &foobar);',
833
        'Add #include <string> for string  [build/include_what_you_use] [4]')
834
    self.TestIncludeWhatYouUse(
835
        'void a(const my::string &foobar);',
836
        '')  # Avoid false positives on strings in other namespaces.
837
    self.TestIncludeWhatYouUse(
838
        """#include "base/foobar.h"
839
           bool foobar = swap(0,1);
840
        """,
841
        'Add #include <algorithm> for swap  [build/include_what_you_use] [4]')
842
    self.TestIncludeWhatYouUse(
843
        """#include "base/foobar.h"
844
           bool foobar = transform(a.begin(), a.end(), b.start(), Foo);
845
        """,
846
        'Add #include <algorithm> for transform  '
847
        '[build/include_what_you_use] [4]')
848
    self.TestIncludeWhatYouUse(
849
        """#include "base/foobar.h"
850
           bool foobar = min_element(a.begin(), a.end());
851
        """,
852
        'Add #include <algorithm> for min_element  '
853
        '[build/include_what_you_use] [4]')
854
    self.TestIncludeWhatYouUse(
855
        """foo->swap(0,1);
856
           foo.swap(0,1);
857
        """,
858
        '')
859
    self.TestIncludeWhatYouUse(
860
        """#include <string>
861
           void a(const std::multimap<int,string> &foobar);
862
        """,
863
        'Add #include <map> for multimap<>'
864
        '  [build/include_what_you_use] [4]')
865
    self.TestIncludeWhatYouUse(
866
        """#include <queue>
867
           void a(const std::priority_queue<int> &foobar);
868
        """,
869
        '')
870
    self.TestIncludeWhatYouUse(
871
        """#include <assert.h>
872
           #include <string>
873
           #include <vector>
874
           #include "base/basictypes.h"
875
           #include "base/port.h"
876
           vector<string> hajoa;""", '')
877
    self.TestIncludeWhatYouUse(
878
        """#include <string>
879
           int i = numeric_limits<int>::max()
880
        """,
881
        'Add #include <limits> for numeric_limits<>'
882
        '  [build/include_what_you_use] [4]')
883
    self.TestIncludeWhatYouUse(
884
        """#include <limits>
885
           int i = numeric_limits<int>::max()
886
        """,
887
        '')
888

    
889
    # Test the UpdateIncludeState code path.
890
    mock_header_contents = ['#include "blah/foo.h"', '#include "blah/bar.h"']
891
    message = self.PerformIncludeWhatYouUse(
892
        '#include "blah/a.h"',
893
        filename='blah/a.cc',
894
        io=MockIo(mock_header_contents))
895
    self.assertEquals(message, '')
896

    
897
    mock_header_contents = ['#include <set>']
898
    message = self.PerformIncludeWhatYouUse(
899
        """#include "blah/a.h"
900
           std::set<int> foo;""",
901
        filename='blah/a.cc',
902
        io=MockIo(mock_header_contents))
903
    self.assertEquals(message, '')
904

    
905
    # Make sure we can find the correct header file if the cc file seems to be
906
    # a temporary file generated by Emacs's flymake.
907
    mock_header_contents = ['']
908
    message = self.PerformIncludeWhatYouUse(
909
        """#include "blah/a.h"
910
           std::set<int> foo;""",
911
        filename='blah/a_flymake.cc',
912
        io=MockIo(mock_header_contents))
913
    self.assertEquals(message, 'Add #include <set> for set<>  '
914
                      '[build/include_what_you_use] [4]')
915

    
916
    # If there's just a cc and the header can't be found then it's ok.
917
    message = self.PerformIncludeWhatYouUse(
918
        """#include "blah/a.h"
919
           std::set<int> foo;""",
920
        filename='blah/a.cc')
921
    self.assertEquals(message, '')
922

    
923
    # Make sure we find the headers with relative paths.
924
    mock_header_contents = ['']
925
    message = self.PerformIncludeWhatYouUse(
926
        """#include "%s/a.h"
927
           std::set<int> foo;""" % os.path.basename(os.getcwd()),
928
        filename='a.cc',
929
        io=MockIo(mock_header_contents))
930
    self.assertEquals(message, 'Add #include <set> for set<>  '
931
                      '[build/include_what_you_use] [4]')
932

    
933
  def testFilesBelongToSameModule(self):
934
    f = cpplint.FilesBelongToSameModule
935
    self.assertEquals((True, ''), f('a.cc', 'a.h'))
936
    self.assertEquals((True, ''), f('base/google.cc', 'base/google.h'))
937
    self.assertEquals((True, ''), f('base/google_test.cc', 'base/google.h'))
938
    self.assertEquals((True, ''),
939
                      f('base/google_unittest.cc', 'base/google.h'))
940
    self.assertEquals((True, ''),
941
                      f('base/internal/google_unittest.cc',
942
                        'base/public/google.h'))
943
    self.assertEquals((True, 'xxx/yyy/'),
944
                      f('xxx/yyy/base/internal/google_unittest.cc',
945
                        'base/public/google.h'))
946
    self.assertEquals((True, 'xxx/yyy/'),
947
                      f('xxx/yyy/base/google_unittest.cc',
948
                        'base/public/google.h'))
949
    self.assertEquals((True, ''),
950
                      f('base/google_unittest.cc', 'base/google-inl.h'))
951
    self.assertEquals((True, '/home/build/google3/'),
952
                      f('/home/build/google3/base/google.cc', 'base/google.h'))
953

    
954
    self.assertEquals((False, ''),
955
                      f('/home/build/google3/base/google.cc', 'basu/google.h'))
956
    self.assertEquals((False, ''), f('a.cc', 'b.h'))
957

    
958
  def testCleanseLine(self):
959
    self.assertEquals('int foo = 0;',
960
                      cpplint.CleanseComments('int foo = 0;  // danger!'))
961
    self.assertEquals('int o = 0;',
962
                      cpplint.CleanseComments('int /* foo */ o = 0;'))
963
    self.assertEquals('foo(int a, int b);',
964
                      cpplint.CleanseComments('foo(int a /* abc */, int b);'))
965
    self.assertEqual('f(a, b);',
966
                     cpplint.CleanseComments('f(a, /* name */ b);'))
967
    self.assertEqual('f(a, b);',
968
                     cpplint.CleanseComments('f(a /* name */, b);'))
969
    self.assertEqual('f(a, b);',
970
                     cpplint.CleanseComments('f(a, /* name */b);'))
971
    self.assertEqual('f(a, b, c);',
972
                     cpplint.CleanseComments('f(a, /**/b, /**/c);'))
973
    self.assertEqual('f(a, b, c);',
974
                     cpplint.CleanseComments('f(a, /**/b/**/, c);'))
975

    
976
  def testRawStrings(self):
977
    self.TestMultiLineLint(
978
        """
979
        void Func() {
980
          static const char kString[] = R"(
981
            #endif  <- invalid preprocessor should be ignored
982
            */      <- invalid comment should be ignored too
983
          )";
984
        }""",
985
        '')
986
    self.TestMultiLineLint(
987
        """
988
        void Func() {
989
          string s = R"TrueDelimiter(
990
              )"
991
              )FalseDelimiter"
992
              )TrueDelimiter";
993
        }""",
994
        '')
995
    self.TestMultiLineLint(
996
        """
997
        void Func() {
998
          char char kString[] = R"(  ";" )";
999
        }""",
1000
        '')
1001
    self.TestMultiLineLint(
1002
        """
1003
        static const char kRawString[] = R"(
1004
          \tstatic const int kLineWithTab = 1;
1005
          static const int kLineWithTrailingWhiteSpace = 1;\x20
1006

1007
           void WeirdNumberOfSpacesAtLineStart() {
1008
            string x;
1009
            x += StrCat("Use StrAppend instead");
1010
          }
1011

1012
          void BlankLineAtEndOfBlock() {
1013
            // TODO incorrectly formatted
1014
            //Badly formatted comment
1015

1016
          }
1017

1018
        )";""",
1019
        '')
1020
    self.TestMultiLineLint(
1021
        """
1022
        void Func() {
1023
          string s = StrCat(R"TrueDelimiter(
1024
              )"
1025
              )FalseDelimiter"
1026
              )TrueDelimiter", R"TrueDelimiter2(
1027
              )"
1028
              )FalseDelimiter2"
1029
              )TrueDelimiter2");
1030
        }""",
1031
        '')
1032
    self.TestMultiLineLint(
1033
        """
1034
        static SomeStruct kData = {
1035
            {0, R"(line1
1036
                   line2
1037
                   )"}
1038
            };""",
1039
        '')
1040

    
1041
  def testMultiLineComments(self):
1042
    # missing explicit is bad
1043
    self.TestMultiLineLint(
1044
        r"""int a = 0;
1045
            /* multi-liner
1046
            class Foo {
1047
            Foo(int f);  // should cause a lint warning in code
1048
            }
1049
            */ """,
1050
        '')
1051
    self.TestMultiLineLint(
1052
        r"""/* int a = 0; multi-liner
1053
              static const int b = 0;""",
1054
        'Could not find end of multi-line comment'
1055
        '  [readability/multiline_comment] [5]')
1056
    self.TestMultiLineLint(r"""  /* multi-line comment""",
1057
                           'Could not find end of multi-line comment'
1058
                           '  [readability/multiline_comment] [5]')
1059
    self.TestMultiLineLint(r"""  // /* comment, but not multi-line""", '')
1060
    self.TestMultiLineLint(r"""/**********
1061
                                 */""", '')
1062
    self.TestMultiLineLint(r"""/**
1063
                                 * Doxygen comment
1064
                                 */""",
1065
                           '')
1066
    self.TestMultiLineLint(r"""/*!
1067
                                 * Doxygen comment
1068
                                 */""",
1069
                           '')
1070

    
1071
  def testMultilineStrings(self):
1072
    multiline_string_error_message = (
1073
        'Multi-line string ("...") found.  This lint script doesn\'t '
1074
        'do well with such strings, and may give bogus warnings.  '
1075
        'Use C++11 raw strings or concatenation instead.'
1076
        '  [readability/multiline_string] [5]')
1077

    
1078
    file_path = 'mydir/foo.cc'
1079

    
1080
    error_collector = ErrorCollector(self.assert_)
1081
    cpplint.ProcessFileData(file_path, 'cc',
1082
                            ['const char* str = "This is a\\',
1083
                             ' multiline string.";'],
1084
                            error_collector)
1085
    self.assertEquals(
1086
        2,  # One per line.
1087
        error_collector.ResultList().count(multiline_string_error_message))
1088

    
1089
  # Test non-explicit single-argument constructors
1090
  def testExplicitSingleArgumentConstructors(self):
1091
    old_verbose_level = cpplint._cpplint_state.verbose_level
1092
    cpplint._cpplint_state.verbose_level = 0
1093

    
1094
    try:
1095
      # missing explicit is bad
1096
      self.TestMultiLineLint(
1097
          """
1098
          class Foo {
1099
            Foo(int f);
1100
          };""",
1101
          'Single-parameter constructors should be marked explicit.'
1102
          '  [runtime/explicit] [5]')
1103
      # missing explicit is bad, even with whitespace
1104
      self.TestMultiLineLint(
1105
          """
1106
          class Foo {
1107
            Foo (int f);
1108
          };""",
1109
          ['Extra space before ( in function call  [whitespace/parens] [4]',
1110
           'Single-parameter constructors should be marked explicit.'
1111
           '  [runtime/explicit] [5]'])
1112
      # missing explicit, with distracting comment, is still bad
1113
      self.TestMultiLineLint(
1114
          """
1115
          class Foo {
1116
            Foo(int f);  // simpler than Foo(blargh, blarg)
1117
          };""",
1118
          'Single-parameter constructors should be marked explicit.'
1119
          '  [runtime/explicit] [5]')
1120
      # missing explicit, with qualified classname
1121
      self.TestMultiLineLint(
1122
          """
1123
          class Qualifier::AnotherOne::Foo {
1124
            Foo(int f);
1125
          };""",
1126
          'Single-parameter constructors should be marked explicit.'
1127
          '  [runtime/explicit] [5]')
1128
      # missing explicit for inline constructors is bad as well
1129
      self.TestMultiLineLint(
1130
          """
1131
          class Foo {
1132
            inline Foo(int f);
1133
          };""",
1134
          'Single-parameter constructors should be marked explicit.'
1135
          '  [runtime/explicit] [5]')
1136
      # structs are caught as well.
1137
      self.TestMultiLineLint(
1138
          """
1139
          struct Foo {
1140
            Foo(int f);
1141
          };""",
1142
          'Single-parameter constructors should be marked explicit.'
1143
          '  [runtime/explicit] [5]')
1144
      # Templatized classes are caught as well.
1145
      self.TestMultiLineLint(
1146
          """
1147
          template<typename T> class Foo {
1148
            Foo(int f);
1149
          };""",
1150
          'Single-parameter constructors should be marked explicit.'
1151
          '  [runtime/explicit] [5]')
1152
      # inline case for templatized classes.
1153
      self.TestMultiLineLint(
1154
          """
1155
          template<typename T> class Foo {
1156
            inline Foo(int f);
1157
          };""",
1158
          'Single-parameter constructors should be marked explicit.'
1159
          '  [runtime/explicit] [5]')
1160
      # constructors with a default argument should still be marked explicit
1161
      self.TestMultiLineLint(
1162
          """
1163
          class Foo {
1164
            Foo(int f = 0);
1165
          };""",
1166
          'Constructors callable with one argument should be marked explicit.'
1167
          '  [runtime/explicit] [5]')
1168
      # multi-argument constructors with all but one default argument should be
1169
      # marked explicit
1170
      self.TestMultiLineLint(
1171
          """
1172
          class Foo {
1173
            Foo(int f, int g = 0);
1174
          };""",
1175
          'Constructors callable with one argument should be marked explicit.'
1176
          '  [runtime/explicit] [5]')
1177
      # multi-argument constructors with all default arguments should be marked
1178
      # explicit
1179
      self.TestMultiLineLint(
1180
          """
1181
          class Foo {
1182
            Foo(int f = 0, int g = 0);
1183
          };""",
1184
          'Constructors callable with one argument should be marked explicit.'
1185
          '  [runtime/explicit] [5]')
1186
      # explicit no-argument constructors are bad
1187
      self.TestMultiLineLint(
1188
          """
1189
          class Foo {
1190
            explicit Foo();
1191
          };""",
1192
          'Zero-parameter constructors should not be marked explicit.'
1193
          '  [runtime/explicit] [5]')
1194
      # void constructors are considered no-argument
1195
      self.TestMultiLineLint(
1196
          """
1197
          class Foo {
1198
            explicit Foo(void);
1199
          };""",
1200
          'Zero-parameter constructors should not be marked explicit.'
1201
          '  [runtime/explicit] [5]')
1202
      # Warn explicit multi-argument constructors at lowest severity
1203
      self.TestMultiLineLint(
1204
          """
1205
          class Foo {
1206
            explicit Foo(int f, int g);
1207
          };""",
1208
          'Constructors that require multiple arguments '
1209
          'should not be marked explicit.  [runtime/explicit] [0]')
1210
      # but explicit multi-argument constructors with only one non-default
1211
      # argument are OK
1212
      self.TestMultiLineLint(
1213
          """
1214
          class Foo {
1215
            explicit Foo(int f, int g = 0);
1216
          };""",
1217
          '')
1218
      # single-argument constructors that take a function that takes multiple
1219
      # arguments should be explicit
1220
      self.TestMultiLineLint(
1221
          """
1222
          class Foo {
1223
            Foo(void (*f)(int f, int g));
1224
          };""",
1225
          'Single-parameter constructors should be marked explicit.'
1226
          '  [runtime/explicit] [5]')
1227
      # single-argument constructors that take a single template argument with
1228
      # multiple parameters should be explicit
1229
      self.TestMultiLineLint(
1230
          """
1231
          template <typename T, typename S>
1232
          class Foo {
1233
            Foo(Bar<T, S> b);
1234
          };""",
1235
          'Single-parameter constructors should be marked explicit.'
1236
          '  [runtime/explicit] [5]')
1237
      # but copy constructors that take multiple template parameters are OK
1238
      self.TestMultiLineLint(
1239
          """
1240
          template <typename T, S>
1241
          class Foo {
1242
            Foo(Foo<T, S>& f);
1243
          };""",
1244
          '')
1245
      # proper style is okay
1246
      self.TestMultiLineLint(
1247
          """
1248
          class Foo {
1249
            explicit Foo(int f);
1250
          };""",
1251
          '')
1252
      # two argument constructor is okay
1253
      self.TestMultiLineLint(
1254
          """
1255
          class Foo {
1256
            Foo(int f, int b);
1257
          };""",
1258
          '')
1259
      # two argument constructor, across two lines, is okay
1260
      self.TestMultiLineLint(
1261
          """
1262
          class Foo {
1263
            Foo(int f,
1264
                int b);
1265
          };""",
1266
          '')
1267
      # non-constructor (but similar name), is okay
1268
      self.TestMultiLineLint(
1269
          """
1270
          class Foo {
1271
            aFoo(int f);
1272
          };""",
1273
          '')
1274
      # constructor with void argument is okay
1275
      self.TestMultiLineLint(
1276
          """
1277
          class Foo {
1278
            Foo(void);
1279
          };""",
1280
          '')
1281
      # single argument method is okay
1282
      self.TestMultiLineLint(
1283
          """
1284
          class Foo {
1285
            Bar(int b);
1286
          };""",
1287
          '')
1288
      # comments should be ignored
1289
      self.TestMultiLineLint(
1290
          """
1291
          class Foo {
1292
          // Foo(int f);
1293
          };""",
1294
          '')
1295
      # single argument function following class definition is okay
1296
      # (okay, it's not actually valid, but we don't want a false positive)
1297
      self.TestMultiLineLint(
1298
          """
1299
          class Foo {
1300
            Foo(int f, int b);
1301
          };
1302
          Foo(int f);""",
1303
          '')
1304
      # single argument function is okay
1305
      self.TestMultiLineLint(
1306
          """static Foo(int f);""",
1307
          '')
1308
      # single argument copy constructor is okay.
1309
      self.TestMultiLineLint(
1310
          """
1311
          class Foo {
1312
            Foo(const Foo&);
1313
          };""",
1314
          '')
1315
      self.TestMultiLineLint(
1316
          """
1317
          class Foo {
1318
            Foo(Foo const&);
1319
          };""",
1320
          '')
1321
      self.TestMultiLineLint(
1322
          """
1323
          class Foo {
1324
            Foo(Foo&);
1325
          };""",
1326
          '')
1327
      # templatized copy constructor is okay.
1328
      self.TestMultiLineLint(
1329
          """
1330
          template<typename T> class Foo {
1331
            Foo(const Foo<T>&);
1332
          };""",
1333
          '')
1334
      # Special case for std::initializer_list
1335
      self.TestMultiLineLint(
1336
          """
1337
          class Foo {
1338
            Foo(std::initializer_list<T> &arg) {}
1339
          };""",
1340
          '')
1341
      # Anything goes inside an assembly block
1342
      error_collector = ErrorCollector(self.assert_)
1343
      cpplint.ProcessFileData('foo.cc', 'cc',
1344
                              ['void Func() {',
1345
                               '  __asm__ (',
1346
                               '    "hlt"',
1347
                               '  );',
1348
                               '  asm {',
1349
                               '    movdqa [edx + 32], xmm2',
1350
                               '  }',
1351
                               '}'],
1352
                              error_collector)
1353
      self.assertEquals(
1354
          0,
1355
          error_collector.ResultList().count(
1356
              'Extra space before ( in function call  [whitespace/parens] [4]'))
1357
      self.assertEquals(
1358
          0,
1359
          error_collector.ResultList().count(
1360
              'Closing ) should be moved to the previous line  '
1361
              '[whitespace/parens] [2]'))
1362
      self.assertEquals(
1363
          0,
1364
          error_collector.ResultList().count(
1365
              'Extra space before [  [whitespace/braces] [5]'))
1366
    finally:
1367
      cpplint._cpplint_state.verbose_level = old_verbose_level
1368

    
1369
  def testSlashStarCommentOnSingleLine(self):
1370
    self.TestMultiLineLint(
1371
        """/* static */ Foo(int f);""",
1372
        '')
1373
    self.TestMultiLineLint(
1374
        """/*/ static */  Foo(int f);""",
1375
        '')
1376
    self.TestMultiLineLint(
1377
        """/*/ static Foo(int f);""",
1378
        'Could not find end of multi-line comment'
1379
        '  [readability/multiline_comment] [5]')
1380
    self.TestMultiLineLint(
1381
        """  /*/ static Foo(int f);""",
1382
        'Could not find end of multi-line comment'
1383
        '  [readability/multiline_comment] [5]')
1384
    self.TestMultiLineLint(
1385
        """  /**/ static Foo(int f);""",
1386
        '')
1387

    
1388
  # Test suspicious usage of "if" like this:
1389
  # if (a == b) {
1390
  #   DoSomething();
1391
  # } if (a == c) {   // Should be "else if".
1392
  #   DoSomething();  // This gets called twice if a == b && a == c.
1393
  # }
1394
  def testSuspiciousUsageOfIf(self):
1395
    self.TestLint(
1396
        '  if (a == b) {',
1397
        '')
1398
    self.TestLint(
1399
        '  } if (a == b) {',
1400
        'Did you mean "else if"? If not, start a new line for "if".'
1401
        '  [readability/braces] [4]')
1402

    
1403
  # Test suspicious usage of memset. Specifically, a 0
1404
  # as the final argument is almost certainly an error.
1405
  def testSuspiciousUsageOfMemset(self):
1406
    # Normal use is okay.
1407
    self.TestLint(
1408
        '  memset(buf, 0, sizeof(buf))',
1409
        '')
1410

    
1411
    # A 0 as the final argument is almost certainly an error.
1412
    self.TestLint(
1413
        '  memset(buf, sizeof(buf), 0)',
1414
        'Did you mean "memset(buf, 0, sizeof(buf))"?'
1415
        '  [runtime/memset] [4]')
1416
    self.TestLint(
1417
        '  memset(buf, xsize * ysize, 0)',
1418
        'Did you mean "memset(buf, 0, xsize * ysize)"?'
1419
        '  [runtime/memset] [4]')
1420

    
1421
    # There is legitimate test code that uses this form.
1422
    # This is okay since the second argument is a literal.
1423
    self.TestLint(
1424
        "  memset(buf, 'y', 0)",
1425
        '')
1426
    self.TestLint(
1427
        '  memset(buf, 4, 0)',
1428
        '')
1429
    self.TestLint(
1430
        '  memset(buf, -1, 0)',
1431
        '')
1432
    self.TestLint(
1433
        '  memset(buf, 0xF1, 0)',
1434
        '')
1435
    self.TestLint(
1436
        '  memset(buf, 0xcd, 0)',
1437
        '')
1438

    
1439
  def testRedundantVirtual(self):
1440
    self.TestLint('virtual void F()', '')
1441
    self.TestLint('virtual void F();', '')
1442
    self.TestLint('virtual void F() {}', '')
1443

    
1444
    message_template = ('"%s" is redundant since function is already '
1445
                        'declared as "%s"  [readability/inheritance] [4]')
1446
    for virt_specifier in ['override', 'final']:
1447
      error_message = message_template % ('virtual', virt_specifier)
1448
      self.TestLint('virtual int F() %s' % virt_specifier, error_message)
1449
      self.TestLint('virtual int F() %s;' % virt_specifier, error_message)
1450
      self.TestLint('virtual int F() %s {' % virt_specifier, error_message)
1451

    
1452
      error_collector = ErrorCollector(self.assert_)
1453
      cpplint.ProcessFileData(
1454
          'foo.cc', 'cc',
1455
          ['// Copyright 2014 Your Company.',
1456
           'virtual void F(int a,',
1457
           '               int b) ' + virt_specifier + ';',
1458
           'virtual void F(int a,',
1459
           '               int b) LOCKS_EXCLUDED(lock) ' + virt_specifier + ';',
1460
           'virtual void F(int a,',
1461
           '               int b)',
1462
           '    LOCKS_EXCLUDED(lock) ' + virt_specifier + ';',
1463
           ''],
1464
          error_collector)
1465
      self.assertEquals(
1466
          [error_message, error_message, error_message],
1467
          error_collector.Results())
1468

    
1469
    error_message = message_template % ('override', 'final')
1470
    self.TestLint('int F() override final', error_message)
1471
    self.TestLint('int F() override final;', error_message)
1472
    self.TestLint('int F() override final {}', error_message)
1473
    self.TestLint('int F() final override', error_message)
1474
    self.TestLint('int F() final override;', error_message)
1475
    self.TestLint('int F() final override {}', error_message)
1476

    
1477
    error_collector = ErrorCollector(self.assert_)
1478
    cpplint.ProcessFileData(
1479
        'foo.cc', 'cc',
1480
        ['// Copyright 2014 Your Company.',
1481
         'struct A : virtual B {',
1482
         '  ~A() override;'
1483
         '};',
1484
         'class C',
1485
         '    : public D,',
1486
         '      public virtual E {',
1487
         '  void Func() override;',
1488
         '}',
1489
         ''],
1490
        error_collector)
1491
    self.assertEquals('', error_collector.Results())
1492

    
1493
    self.TestLint('void Finalize(AnnotationProto *final) override;', '')
1494

    
1495
  def testCheckDeprecated(self):
1496
    self.TestLanguageRulesCheck('foo_test.cc', '#include <iostream>', '')
1497
    self.TestLanguageRulesCheck('foo_unittest.cc', '#include <iostream>', '')
1498

    
1499
  def testCheckPosixThreading(self):
1500
    self.TestLint('var = sctime_r()', '')
1501
    self.TestLint('var = strtok_r()', '')
1502
    self.TestLint('var = strtok_r(foo, ba, r)', '')
1503
    self.TestLint('var = brand()', '')
1504
    self.TestLint('_rand()', '')
1505
    self.TestLint('.rand()', '')
1506
    self.TestLint('->rand()', '')
1507
    self.TestLint('ACMRandom rand(seed)', '')
1508
    self.TestLint('ISAACRandom rand()', '')
1509
    self.TestLint('var = rand()',
1510
                  'Consider using rand_r(...) instead of rand(...)'
1511
                  ' for improved thread safety.'
1512
                  '  [runtime/threadsafe_fn] [2]')
1513
    self.TestLint('var = strtok(str, delim)',
1514
                  'Consider using strtok_r(...) '
1515
                  'instead of strtok(...)'
1516
                  ' for improved thread safety.'
1517
                  '  [runtime/threadsafe_fn] [2]')
1518

    
1519
  def testVlogMisuse(self):
1520
    self.TestLint('VLOG(1)', '')
1521
    self.TestLint('VLOG(99)', '')
1522
    self.TestLint('LOG(ERROR)', '')
1523
    self.TestLint('LOG(INFO)', '')
1524
    self.TestLint('LOG(WARNING)', '')
1525
    self.TestLint('LOG(FATAL)', '')
1526
    self.TestLint('LOG(DFATAL)', '')
1527
    self.TestLint('VLOG(SOMETHINGWEIRD)', '')
1528
    self.TestLint('MYOWNVLOG(ERROR)', '')
1529
    errmsg = ('VLOG() should be used with numeric verbosity level.  '
1530
              'Use LOG() if you want symbolic severity levels.'
1531
              '  [runtime/vlog] [5]')
1532
    self.TestLint('VLOG(ERROR)', errmsg)
1533
    self.TestLint('VLOG(INFO)', errmsg)
1534
    self.TestLint('VLOG(WARNING)', errmsg)
1535
    self.TestLint('VLOG(FATAL)', errmsg)
1536
    self.TestLint('VLOG(DFATAL)', errmsg)
1537
    self.TestLint('  VLOG(ERROR)', errmsg)
1538
    self.TestLint('  VLOG(INFO)', errmsg)
1539
    self.TestLint('  VLOG(WARNING)', errmsg)
1540
    self.TestLint('  VLOG(FATAL)', errmsg)
1541
    self.TestLint('  VLOG(DFATAL)', errmsg)
1542

    
1543

    
1544
  # Test potential format string bugs like printf(foo).
1545
  def testFormatStrings(self):
1546
    self.TestLint('printf("foo")', '')
1547
    self.TestLint('printf("foo: %s", foo)', '')
1548
    self.TestLint('DocidForPrintf(docid)', '')  # Should not trigger.
1549
    self.TestLint('printf(format, value)', '')  # Should not trigger.
1550
    self.TestLint('printf(__VA_ARGS__)', '')  # Should not trigger.
1551
    self.TestLint('printf(format.c_str(), value)', '')  # Should not trigger.
1552
    self.TestLint('printf(format(index).c_str(), value)', '')
1553
    self.TestLint(
1554
        'printf(foo)',
1555
        'Potential format string bug. Do printf("%s", foo) instead.'
1556
        '  [runtime/printf] [4]')
1557
    self.TestLint(
1558
        'printf(foo.c_str())',
1559
        'Potential format string bug. '
1560
        'Do printf("%s", foo.c_str()) instead.'
1561
        '  [runtime/printf] [4]')
1562
    self.TestLint(
1563
        'printf(foo->c_str())',
1564
        'Potential format string bug. '
1565
        'Do printf("%s", foo->c_str()) instead.'
1566
        '  [runtime/printf] [4]')
1567
    self.TestLint(
1568
        'StringPrintf(foo)',
1569
        'Potential format string bug. Do StringPrintf("%s", foo) instead.'
1570
        ''
1571
        '  [runtime/printf] [4]')
1572

    
1573
  # Test disallowed use of operator& and other operators.
1574
  def testIllegalOperatorOverloading(self):
1575
    errmsg = ('Unary operator& is dangerous.  Do not use it.'
1576
              '  [runtime/operator] [4]')
1577
    self.TestLint('void operator=(const Myclass&)', '')
1578
    self.TestLint('void operator&(int a, int b)', '')   # binary operator& ok
1579
    self.TestLint('void operator&() { }', errmsg)
1580
    self.TestLint('void operator & (  ) { }',
1581
                  ['Extra space after (  [whitespace/parens] [2]', errmsg])
1582

    
1583
  # const string reference members are dangerous..
1584
  def testConstStringReferenceMembers(self):
1585
    errmsg = ('const string& members are dangerous. It is much better to use '
1586
              'alternatives, such as pointers or simple constants.'
1587
              '  [runtime/member_string_references] [2]')
1588

    
1589
    members_declarations = ['const string& church',
1590
                            'const string &turing',
1591
                            'const string & godel']
1592
    # TODO(unknown): Enable also these tests if and when we ever
1593
    # decide to check for arbitrary member references.
1594
    #                         "const Turing & a",
1595
    #                         "const Church& a",
1596
    #                         "const vector<int>& a",
1597
    #                         "const     Kurt::Godel    &    godel",
1598
    #                         "const Kazimierz::Kuratowski& kk" ]
1599

    
1600
    # The Good.
1601

    
1602
    self.TestLint('void f(const string&)', '')
1603
    self.TestLint('const string& f(const string& a, const string& b)', '')
1604
    self.TestLint('typedef const string& A;', '')
1605

    
1606
    for decl in members_declarations:
1607
      self.TestLint(decl + ' = b;', '')
1608
      self.TestLint(decl + '      =', '')
1609

    
1610
    # The Bad.
1611

    
1612
    for decl in members_declarations:
1613
      self.TestLint(decl + ';', errmsg)
1614

    
1615
  # Variable-length arrays are not permitted.
1616
  def testVariableLengthArrayDetection(self):
1617
    errmsg = ('Do not use variable-length arrays.  Use an appropriately named '
1618
              "('k' followed by CamelCase) compile-time constant for the size."
1619
              '  [runtime/arrays] [1]')
1620

    
1621
    self.TestLint('int a[any_old_variable];', errmsg)
1622
    self.TestLint('int doublesize[some_var * 2];', errmsg)
1623
    self.TestLint('int a[afunction()];', errmsg)
1624
    self.TestLint('int a[function(kMaxFooBars)];', errmsg)
1625
    self.TestLint('bool a_list[items_->size()];', errmsg)
1626
    self.TestLint('namespace::Type buffer[len+1];', errmsg)
1627

    
1628
    self.TestLint('int a[64];', '')
1629
    self.TestLint('int a[0xFF];', '')
1630
    self.TestLint('int first[256], second[256];', '')
1631
    self.TestLint('int array_name[kCompileTimeConstant];', '')
1632
    self.TestLint('char buf[somenamespace::kBufSize];', '')
1633
    self.TestLint('int array_name[ALL_CAPS];', '')
1634
    self.TestLint('AClass array1[foo::bar::ALL_CAPS];', '')
1635
    self.TestLint('int a[kMaxStrLen + 1];', '')
1636
    self.TestLint('int a[sizeof(foo)];', '')
1637
    self.TestLint('int a[sizeof(*foo)];', '')
1638
    self.TestLint('int a[sizeof foo];', '')
1639
    self.TestLint('int a[sizeof(struct Foo)];', '')
1640
    self.TestLint('int a[128 - sizeof(const bar)];', '')
1641
    self.TestLint('int a[(sizeof(foo) * 4)];', '')
1642
    self.TestLint('int a[(arraysize(fixed_size_array)/2) << 1];', '')
1643
    self.TestLint('delete a[some_var];', '')
1644
    self.TestLint('return a[some_var];', '')
1645

    
1646
  # DISALLOW_COPY_AND_ASSIGN and DISALLOW_IMPLICIT_CONSTRUCTORS should be at
1647
  # end of class if present.
1648
  def testDisallowMacrosAtEnd(self):
1649
    for macro_name in (
1650
        'DISALLOW_COPY_AND_ASSIGN',
1651
        'DISALLOW_IMPLICIT_CONSTRUCTORS'):
1652
      error_collector = ErrorCollector(self.assert_)
1653
      cpplint.ProcessFileData(
1654
          'foo.cc', 'cc',
1655
          ['// Copyright 2014 Your Company.',
1656
           'class SomeClass {',
1657
           ' private:',
1658
           '  %s(SomeClass);' % macro_name,
1659
           '  int member_;',
1660
           '};',
1661
           ''],
1662
          error_collector)
1663
      self.assertEquals(
1664
          ('%s should be the last thing in the class' % macro_name) +
1665
          '  [readability/constructors] [3]',
1666
          error_collector.Results())
1667

    
1668
      error_collector = ErrorCollector(self.assert_)
1669
      cpplint.ProcessFileData(
1670
          'foo.cc', 'cc',
1671
          ['// Copyright 2014 Your Company.',
1672
           'class OuterClass {',
1673
           ' private:',
1674
           '  struct InnerClass {',
1675
           '   private:',
1676
           '    %s(InnerClass);' % macro_name,
1677
           '    int member;',
1678
           '  };',
1679
           '};',
1680
           ''],
1681
          error_collector)
1682
      self.assertEquals(
1683
          ('%s should be the last thing in the class' % macro_name) +
1684
          '  [readability/constructors] [3]',
1685
          error_collector.Results())
1686

    
1687
      error_collector = ErrorCollector(self.assert_)
1688
      cpplint.ProcessFileData(
1689
          'foo.cc', 'cc',
1690
          ['// Copyright 2014 Your Company.',
1691
           'class OuterClass1 {',
1692
           ' private:',
1693
           '  struct InnerClass1 {',
1694
           '   private:',
1695
           '    %s(InnerClass1);' % macro_name,
1696
           '  };',
1697
           '  %s(OuterClass1);' % macro_name,
1698
           '};',
1699
           'struct OuterClass2 {',
1700
           ' private:',
1701
           '  class InnerClass2 {',
1702
           '   private:',
1703
           '    %s(InnerClass2);' % macro_name,
1704
           '    // comment',
1705
           '  };',
1706
           '',
1707
           '  %s(OuterClass2);' % macro_name,
1708
           '',
1709
           '  // comment',
1710
           '};',
1711
           'void Func() {',
1712
           '  struct LocalClass {',
1713
           '   private:',
1714
           '    %s(LocalClass);' % macro_name,
1715
           '  } variable;',
1716
           '}',
1717
           ''],
1718
          error_collector)
1719
      self.assertEquals('', error_collector.Results())
1720

    
1721
  # DISALLOW* macros should be in the private: section.
1722
  def testMisplacedDisallowMacros(self):
1723
    for macro_name in (
1724
        'DISALLOW_COPY_AND_ASSIGN',
1725
        'DISALLOW_IMPLICIT_CONSTRUCTORS'):
1726
      self.TestMultiLineLint(
1727
          """
1728
          class A {'
1729
           public:
1730
            %s(A);
1731
          };""" % macro_name,
1732
          ('%s must be in the private: section' % macro_name) +
1733
          '  [readability/constructors] [3]')
1734

    
1735
      self.TestMultiLineLint(
1736
          """
1737
          struct B {'
1738
            %s(B);
1739
          };""" % macro_name,
1740
          ('%s must be in the private: section' % macro_name) +
1741
          '  [readability/constructors] [3]')
1742

    
1743
      self.TestMultiLineLint(
1744
          """
1745
          class Outer1 {'
1746
           private:
1747
            struct Inner1 {
1748
              %s(Inner1);
1749
            };
1750
            %s(Outer1);
1751
          };""" % (macro_name, macro_name),
1752
          ('%s must be in the private: section' % macro_name) +
1753
          '  [readability/constructors] [3]')
1754

    
1755
      self.TestMultiLineLint(
1756
          """
1757
          class Outer2 {'
1758
           private:
1759
            class Inner2 {
1760
              %s(Inner2);
1761
            };
1762
            %s(Outer2);
1763
          };""" % (macro_name, macro_name),
1764
          '')
1765
    # Extra checks to make sure that nested classes are handled
1766
    # correctly.  Use different macros for inner and outer classes so
1767
    # that we can tell the error messages apart.
1768
    self.TestMultiLineLint(
1769
        """
1770
        class Outer3 {
1771
          struct Inner3 {
1772
            DISALLOW_COPY_AND_ASSIGN(Inner3);
1773
          };
1774
          DISALLOW_IMPLICIT_CONSTRUCTORS(Outer3);
1775
        };""",
1776
        ('DISALLOW_COPY_AND_ASSIGN must be in the private: section'
1777
         '  [readability/constructors] [3]'))
1778
    self.TestMultiLineLint(
1779
        """
1780
        struct Outer4 {
1781
          class Inner4 {
1782
            DISALLOW_COPY_AND_ASSIGN(Inner4);
1783
          };
1784
          DISALLOW_IMPLICIT_CONSTRUCTORS(Outer4);
1785
        };""",
1786
        ('DISALLOW_IMPLICIT_CONSTRUCTORS must be in the private: section'
1787
         '  [readability/constructors] [3]'))
1788

    
1789
  # Brace usage
1790
  def testBraces(self):
1791
    # Braces shouldn't be followed by a ; unless they're defining a struct
1792
    # or initializing an array
1793
    self.TestLint('int a[3] = { 1, 2, 3 };', '')
1794
    self.TestLint(
1795
        """const int foo[] =
1796
               {1, 2, 3 };""",
1797
        '')
1798
    # For single line, unmatched '}' with a ';' is ignored (not enough context)
1799
    self.TestMultiLineLint(
1800
        """int a[3] = { 1,
1801
                        2,
1802
                        3 };""",
1803
        '')
1804
    self.TestMultiLineLint(
1805
        """int a[2][3] = { { 1, 2 },
1806
                         { 3, 4 } };""",
1807
        '')
1808
    self.TestMultiLineLint(
1809
        """int a[2][3] =
1810
               { { 1, 2 },
1811
                 { 3, 4 } };""",
1812
        '')
1813

    
1814
  # CHECK/EXPECT_TRUE/EXPECT_FALSE replacements
1815
  def testCheckCheck(self):
1816
    self.TestLint('CHECK(x == 42);',
1817
                  'Consider using CHECK_EQ instead of CHECK(a == b)'
1818
                  '  [readability/check] [2]')
1819
    self.TestLint('CHECK(x != 42);',
1820
                  'Consider using CHECK_NE instead of CHECK(a != b)'
1821
                  '  [readability/check] [2]')
1822
    self.TestLint('CHECK(x >= 42);',
1823
                  'Consider using CHECK_GE instead of CHECK(a >= b)'
1824
                  '  [readability/check] [2]')
1825
    self.TestLint('CHECK(x > 42);',
1826
                  'Consider using CHECK_GT instead of CHECK(a > b)'
1827
                  '  [readability/check] [2]')
1828
    self.TestLint('CHECK(x <= 42);',
1829
                  'Consider using CHECK_LE instead of CHECK(a <= b)'
1830
                  '  [readability/check] [2]')
1831
    self.TestLint('CHECK(x < 42);',
1832
                  'Consider using CHECK_LT instead of CHECK(a < b)'
1833
                  '  [readability/check] [2]')
1834

    
1835
    self.TestLint('DCHECK(x == 42);',
1836
                  'Consider using DCHECK_EQ instead of DCHECK(a == b)'
1837
                  '  [readability/check] [2]')
1838
    self.TestLint('DCHECK(x != 42);',
1839
                  'Consider using DCHECK_NE instead of DCHECK(a != b)'
1840
                  '  [readability/check] [2]')
1841
    self.TestLint('DCHECK(x >= 42);',
1842
                  'Consider using DCHECK_GE instead of DCHECK(a >= b)'
1843
                  '  [readability/check] [2]')
1844
    self.TestLint('DCHECK(x > 42);',
1845
                  'Consider using DCHECK_GT instead of DCHECK(a > b)'
1846
                  '  [readability/check] [2]')
1847
    self.TestLint('DCHECK(x <= 42);',
1848
                  'Consider using DCHECK_LE instead of DCHECK(a <= b)'
1849
                  '  [readability/check] [2]')
1850
    self.TestLint('DCHECK(x < 42);',
1851
                  'Consider using DCHECK_LT instead of DCHECK(a < b)'
1852
                  '  [readability/check] [2]')
1853

    
1854
    self.TestLint(
1855
        'EXPECT_TRUE("42" == x);',
1856
        'Consider using EXPECT_EQ instead of EXPECT_TRUE(a == b)'
1857
        '  [readability/check] [2]')
1858
    self.TestLint(
1859
        'EXPECT_TRUE("42" != x);',
1860
        'Consider using EXPECT_NE instead of EXPECT_TRUE(a != b)'
1861
        '  [readability/check] [2]')
1862
    self.TestLint(
1863
        'EXPECT_TRUE(+42 >= x);',
1864
        'Consider using EXPECT_GE instead of EXPECT_TRUE(a >= b)'
1865
        '  [readability/check] [2]')
1866
    self.TestLint(
1867
        'EXPECT_TRUE_M(-42 > x);',
1868
        'Consider using EXPECT_GT_M instead of EXPECT_TRUE_M(a > b)'
1869
        '  [readability/check] [2]')
1870
    self.TestLint(
1871
        'EXPECT_TRUE_M(42U <= x);',
1872
        'Consider using EXPECT_LE_M instead of EXPECT_TRUE_M(a <= b)'
1873
        '  [readability/check] [2]')
1874
    self.TestLint(
1875
        'EXPECT_TRUE_M(42L < x);',
1876
        'Consider using EXPECT_LT_M instead of EXPECT_TRUE_M(a < b)'
1877
        '  [readability/check] [2]')
1878

    
1879
    self.TestLint(
1880
        'EXPECT_FALSE(x == 42);',
1881
        'Consider using EXPECT_NE instead of EXPECT_FALSE(a == b)'
1882
        '  [readability/check] [2]')
1883
    self.TestLint(
1884
        'EXPECT_FALSE(x != 42);',
1885
        'Consider using EXPECT_EQ instead of EXPECT_FALSE(a != b)'
1886
        '  [readability/check] [2]')
1887
    self.TestLint(
1888
        'EXPECT_FALSE(x >= 42);',
1889
        'Consider using EXPECT_LT instead of EXPECT_FALSE(a >= b)'
1890
        '  [readability/check] [2]')
1891
    self.TestLint(
1892
        'ASSERT_FALSE(x > 42);',
1893
        'Consider using ASSERT_LE instead of ASSERT_FALSE(a > b)'
1894
        '  [readability/check] [2]')
1895
    self.TestLint(
1896
        'ASSERT_FALSE(x <= 42);',
1897
        'Consider using ASSERT_GT instead of ASSERT_FALSE(a <= b)'
1898
        '  [readability/check] [2]')
1899
    self.TestLint(
1900
        'ASSERT_FALSE_M(x < 42);',
1901
        'Consider using ASSERT_GE_M instead of ASSERT_FALSE_M(a < b)'
1902
        '  [readability/check] [2]')
1903

    
1904
    self.TestLint('CHECK(x<42);',
1905
                  ['Missing spaces around <'
1906
                   '  [whitespace/operators] [3]',
1907
                   'Consider using CHECK_LT instead of CHECK(a < b)'
1908
                   '  [readability/check] [2]'])
1909
    self.TestLint('CHECK(x>42);',
1910
                  ['Missing spaces around >'
1911
                   '  [whitespace/operators] [3]',
1912
                   'Consider using CHECK_GT instead of CHECK(a > b)'
1913
                   '  [readability/check] [2]'])
1914

    
1915
    self.TestLint('using some::namespace::operator<<;', '')
1916
    self.TestLint('using some::namespace::operator>>;', '')
1917

    
1918
    self.TestLint('CHECK(x->y == 42);',
1919
                  'Consider using CHECK_EQ instead of CHECK(a == b)'
1920
                  '  [readability/check] [2]')
1921

    
1922
    self.TestLint(
1923
        '  EXPECT_TRUE(42 < x);  // Random comment.',
1924
        'Consider using EXPECT_LT instead of EXPECT_TRUE(a < b)'
1925
        '  [readability/check] [2]')
1926
    self.TestLint(
1927
        'EXPECT_TRUE( 42 < x );',
1928
        ['Extra space after ( in function call'
1929
         '  [whitespace/parens] [4]',
1930
         'Extra space before )  [whitespace/parens] [2]',
1931
         'Consider using EXPECT_LT instead of EXPECT_TRUE(a < b)'
1932
         '  [readability/check] [2]'])
1933

    
1934
    self.TestLint('CHECK(4\'2 == x);',
1935
                  'Consider using CHECK_EQ instead of CHECK(a == b)'
1936
                  '  [readability/check] [2]')
1937

    
1938
  def testCheckCheckFalsePositives(self):
1939
    self.TestLint('CHECK(some_iterator == obj.end());', '')
1940
    self.TestLint('EXPECT_TRUE(some_iterator == obj.end());', '')
1941
    self.TestLint('EXPECT_FALSE(some_iterator == obj.end());', '')
1942
    self.TestLint('CHECK(some_pointer != NULL);', '')
1943
    self.TestLint('EXPECT_TRUE(some_pointer != NULL);', '')
1944
    self.TestLint('EXPECT_FALSE(some_pointer != NULL);', '')
1945

    
1946
    self.TestLint('CHECK(CreateTestFile(dir, (1 << 20)));', '')
1947
    self.TestLint('CHECK(CreateTestFile(dir, (1 >> 20)));', '')
1948

    
1949
    self.TestLint('CHECK(x ^ (y < 42));', '')
1950
    self.TestLint('CHECK((x > 42) ^ (x < 54));', '')
1951
    self.TestLint('CHECK(a && b < 42);', '')
1952
    self.TestLint('CHECK(42 < a && a < b);', '')
1953
    self.TestLint('SOFT_CHECK(x > 42);', '')
1954

    
1955
    self.TestMultiLineLint(
1956
        """_STLP_DEFINE_BINARY_OP_CHECK(==, _OP_EQUAL);
1957
        _STLP_DEFINE_BINARY_OP_CHECK(!=, _OP_NOT_EQUAL);
1958
        _STLP_DEFINE_BINARY_OP_CHECK(<, _OP_LESS_THAN);
1959
        _STLP_DEFINE_BINARY_OP_CHECK(<=, _OP_LESS_EQUAL);
1960
        _STLP_DEFINE_BINARY_OP_CHECK(>, _OP_GREATER_THAN);
1961
        _STLP_DEFINE_BINARY_OP_CHECK(>=, _OP_GREATER_EQUAL);
1962
        _STLP_DEFINE_BINARY_OP_CHECK(+, _OP_PLUS);
1963
        _STLP_DEFINE_BINARY_OP_CHECK(*, _OP_TIMES);
1964
        _STLP_DEFINE_BINARY_OP_CHECK(/, _OP_DIVIDE);
1965
        _STLP_DEFINE_BINARY_OP_CHECK(-, _OP_SUBTRACT);
1966
        _STLP_DEFINE_BINARY_OP_CHECK(%, _OP_MOD);""",
1967
        '')
1968

    
1969
    self.TestLint('CHECK(x < 42) << "Custom error message";', '')
1970

    
1971
  # Alternative token to punctuation operator replacements
1972
  def testCheckAltTokens(self):
1973
    self.TestLint('true or true',
1974
                  'Use operator || instead of or'
1975
                  '  [readability/alt_tokens] [2]')
1976
    self.TestLint('true and true',
1977
                  'Use operator && instead of and'
1978
                  '  [readability/alt_tokens] [2]')
1979
    self.TestLint('if (not true)',
1980
                  'Use operator ! instead of not'
1981
                  '  [readability/alt_tokens] [2]')
1982
    self.TestLint('1 bitor 1',
1983
                  'Use operator | instead of bitor'
1984
                  '  [readability/alt_tokens] [2]')
1985
    self.TestLint('1 xor 1',
1986
                  'Use operator ^ instead of xor'
1987
                  '  [readability/alt_tokens] [2]')
1988
    self.TestLint('1 bitand 1',
1989
                  'Use operator & instead of bitand'
1990
                  '  [readability/alt_tokens] [2]')
1991
    self.TestLint('x = compl 1',
1992
                  'Use operator ~ instead of compl'
1993
                  '  [readability/alt_tokens] [2]')
1994
    self.TestLint('x and_eq y',
1995
                  'Use operator &= instead of and_eq'
1996
                  '  [readability/alt_tokens] [2]')
1997
    self.TestLint('x or_eq y',
1998
                  'Use operator |= instead of or_eq'
1999
                  '  [readability/alt_tokens] [2]')
2000
    self.TestLint('x xor_eq y',
2001
                  'Use operator ^= instead of xor_eq'
2002
                  '  [readability/alt_tokens] [2]')
2003
    self.TestLint('x not_eq y',
2004
                  'Use operator != instead of not_eq'
2005
                  '  [readability/alt_tokens] [2]')
2006
    self.TestLint('line_continuation or',
2007
                  'Use operator || instead of or'
2008
                  '  [readability/alt_tokens] [2]')
2009
    self.TestLint('if(true and(parentheses',
2010
                  'Use operator && instead of and'
2011
                  '  [readability/alt_tokens] [2]')
2012

    
2013
    self.TestLint('#include "base/false-and-false.h"', '')
2014
    self.TestLint('#error false or false', '')
2015
    self.TestLint('false nor false', '')
2016
    self.TestLint('false nand false', '')
2017

    
2018
  # Passing and returning non-const references
2019
  def testNonConstReference(self):
2020
    # Passing a non-const reference as function parameter is forbidden.
2021
    operand_error_message = ('Is this a non-const reference? '
2022
                             'If so, make const or use a pointer: %s'
2023
                             '  [runtime/references] [2]')
2024
    # Warn of use of a non-const reference in operators and functions
2025
    self.TestLint('bool operator>(Foo& s, Foo& f);',
2026
                  [operand_error_message % 'Foo& s',
2027
                   operand_error_message % 'Foo& f'])
2028
    self.TestLint('bool operator+(Foo& s, Foo& f);',
2029
                  [operand_error_message % 'Foo& s',
2030
                   operand_error_message % 'Foo& f'])
2031
    self.TestLint('int len(Foo& s);', operand_error_message % 'Foo& s')
2032
    # Allow use of non-const references in a few specific cases
2033
    self.TestLint('stream& operator>>(stream& s, Foo& f);', '')
2034
    self.TestLint('stream& operator<<(stream& s, Foo& f);', '')
2035
    self.TestLint('void swap(Bar& a, Bar& b);', '')
2036
    # Returning a non-const reference from a function is OK.
2037
    self.TestLint('int& g();', '')
2038
    # Passing a const reference to a struct (using the struct keyword) is OK.
2039
    self.TestLint('void foo(const struct tm& tm);', '')
2040
    # Passing a const reference to a typename is OK.
2041
    self.TestLint('void foo(const typename tm& tm);', '')
2042
    # Const reference to a pointer type is OK.
2043
    self.TestLint('void foo(const Bar* const& p) {', '')
2044
    self.TestLint('void foo(Bar const* const& p) {', '')
2045
    self.TestLint('void foo(Bar* const& p) {', '')
2046
    # Const reference to a templated type is OK.
2047
    self.TestLint('void foo(const std::vector<std::string>& v);', '')
2048
    # Non-const reference to a pointer type is not OK.
2049
    self.TestLint('void foo(Bar*& p);',
2050
                  operand_error_message % 'Bar*& p')
2051
    self.TestLint('void foo(const Bar*& p);',
2052
                  operand_error_message % 'const Bar*& p')
2053
    self.TestLint('void foo(Bar const*& p);',
2054
                  operand_error_message % 'Bar const*& p')
2055
    self.TestLint('void foo(struct Bar*& p);',
2056
                  operand_error_message % 'struct Bar*& p')
2057
    self.TestLint('void foo(const struct Bar*& p);',
2058
                  operand_error_message % 'const struct Bar*& p')
2059
    self.TestLint('void foo(struct Bar const*& p);',
2060
                  operand_error_message % 'struct Bar const*& p')
2061
    # Non-const reference to a templated type is not OK.
2062
    self.TestLint('void foo(std::vector<int>& p);',
2063
                  operand_error_message % 'std::vector<int>& p')
2064
    # Returning an address of something is not prohibited.
2065
    self.TestLint('return &something;', '')
2066
    self.TestLint('if (condition) {return &something; }', '')
2067
    self.TestLint('if (condition) return &something;', '')
2068
    self.TestLint('if (condition) address = &something;', '')
2069
    self.TestLint('if (condition) result = lhs&rhs;', '')
2070
    self.TestLint('if (condition) result = lhs & rhs;', '')
2071
    self.TestLint('a = (b+c) * sizeof &f;', '')
2072
    self.TestLint('a = MySize(b) * sizeof &f;', '')
2073
    # We don't get confused by C++11 range-based for loops.
2074
    self.TestLint('for (const string& s : c)', '')
2075
    self.TestLint('for (auto& r : c)', '')
2076
    self.TestLint('for (typename Type& a : b)', '')
2077
    # We don't get confused by some other uses of '&'.
2078
    self.TestLint('T& operator=(const T& t);', '')
2079
    self.TestLint('int g() { return (a & b); }', '')
2080
    self.TestLint('T& r = (T&)*(vp());', '')
2081
    self.TestLint('T& r = v', '')
2082
    self.TestLint('static_assert((kBits & kMask) == 0, "text");', '')
2083
    self.TestLint('COMPILE_ASSERT((kBits & kMask) == 0, text);', '')
2084
    # Spaces before template arguments.  This is poor style, but
2085
    # happens 0.15% of the time.
2086
    self.TestLint('void Func(const vector <int> &const_x, '
2087
                  'vector <int> &nonconst_x) {',
2088
                  operand_error_message % 'vector<int> &nonconst_x')
2089

    
2090
    # Derived member functions are spared from override check
2091
    self.TestLint('void Func(X& x);', operand_error_message % 'X& x')
2092
    self.TestLint('void Func(X& x) {}', operand_error_message % 'X& x')
2093
    self.TestLint('void Func(X& x) override;', '')
2094
    self.TestLint('void Func(X& x) override {', '')
2095
    self.TestLint('void Func(X& x) const override;', '')
2096
    self.TestLint('void Func(X& x) const override {', '')
2097

    
2098
    # Don't warn on out-of-line method definitions.
2099
    self.TestLint('void NS::Func(X& x) {', '')
2100
    error_collector = ErrorCollector(self.assert_)
2101
    cpplint.ProcessFileData(
2102
        'foo.cc', 'cc',
2103
        ['// Copyright 2014 Your Company. All Rights Reserved.',
2104
         'void a::b() {}',
2105
         'void f(int& q) {}',
2106
         ''],
2107
        error_collector)
2108
    self.assertEquals(
2109
        operand_error_message % 'int& q',
2110
        error_collector.Results())
2111

    
2112
    # Other potential false positives.  These need full parser
2113
    # state to reproduce as opposed to just TestLint.
2114
    error_collector = ErrorCollector(self.assert_)
2115
    cpplint.ProcessFileData(
2116
        'foo.cc', 'cc',
2117
        ['// Copyright 2014 Your Company. All Rights Reserved.',
2118
         'void swap(int &x,',
2119
         '          int &y) {',
2120
         '}',
2121
         'void swap(',
2122
         '    sparsegroup<T, GROUP_SIZE, Alloc> &x,',
2123
         '    sparsegroup<T, GROUP_SIZE, Alloc> &y) {',
2124
         '}',
2125
         'ostream& operator<<(',
2126
         '    ostream& out',
2127
         '    const dense_hash_set<Value, Hash, Equals, Alloc>& seq) {',
2128
         '}',
2129
         'class A {',
2130
         '  void Function(',
2131
         '      string &x) override {',
2132
         '  }',
2133
         '};',
2134
         'void Derived::Function(',
2135
         '    string &x) {',
2136
         '}',
2137
         '#define UNSUPPORTED_MASK(_mask) \\',
2138
         '  if (flags & _mask) { \\',
2139
         '    LOG(FATAL) << "Unsupported flag: " << #_mask; \\',
2140
         '  }',
2141
         'Constructor::Constructor()',
2142
         '    : initializer1_(a1 & b1),',
2143
         '      initializer2_(a2 & b2) {',
2144
         '}',
2145
         'Constructor::Constructor()',
2146
         '    : initializer1_{a3 & b3},',
2147
         '      initializer2_(a4 & b4) {',
2148
         '}',
2149
         'Constructor::Constructor()',
2150
         '    : initializer1_{a5 & b5},',
2151
         '      initializer2_(a6 & b6) {}',
2152
         ''],
2153
        error_collector)
2154
    self.assertEquals('', error_collector.Results())
2155

    
2156
    # Multi-line references
2157
    error_collector = ErrorCollector(self.assert_)
2158
    cpplint.ProcessFileData(
2159
        'foo.cc', 'cc',
2160
        ['// Copyright 2014 Your Company. All Rights Reserved.',
2161
         'void Func(const Outer::',
2162
         '              Inner& const_x,',
2163
         '          const Outer',
2164
         '              ::Inner& const_y,',
2165
         '          const Outer<',
2166
         '              int>::Inner& const_z,',
2167
         '          Outer::',
2168
         '              Inner& nonconst_x,',
2169
         '          Outer',
2170
         '              ::Inner& nonconst_y,',
2171
         '          Outer<',
2172
         '              int>::Inner& nonconst_z) {',
2173
         '}',
2174
         ''],
2175
        error_collector)
2176
    self.assertEquals(
2177
        [operand_error_message % 'Outer::Inner& nonconst_x',
2178
         operand_error_message % 'Outer::Inner& nonconst_y',
2179
         operand_error_message % 'Outer<int>::Inner& nonconst_z'],
2180
        error_collector.Results())
2181

    
2182
    # A peculiar false positive due to bad template argument parsing
2183
    error_collector = ErrorCollector(self.assert_)
2184
    cpplint.ProcessFileData(
2185
        'foo.cc', 'cc',
2186
        ['// Copyright 2014 Your Company. All Rights Reserved.',
2187
         'inline RCULocked<X>::ReadPtr::ReadPtr(const RCULocked* rcu) {',
2188
         '  DCHECK(!(data & kFlagMask)) << "Error";',
2189
         '}',
2190
         '',
2191
         'RCULocked<X>::WritePtr::WritePtr(RCULocked* rcu)',
2192
         '    : lock_(&rcu_->mutex_) {',
2193
         '}',
2194
         ''],
2195
        error_collector.Results())
2196
    self.assertEquals('', error_collector.Results())
2197

    
2198
  def testBraceAtBeginOfLine(self):
2199
    self.TestLint('{',
2200
                  '{ should almost always be at the end of the previous line'
2201
                  '  [whitespace/braces] [4]')
2202

    
2203
    error_collector = ErrorCollector(self.assert_)
2204
    cpplint.ProcessFileData('foo.cc', 'cc',
2205
                            ['int function()',
2206
                             '{',  # warning here
2207
                             '  MutexLock l(&mu);',
2208
                             '}',
2209
                             'int variable;'
2210
                             '{',  # no warning
2211
                             '  MutexLock l(&mu);',
2212
                             '}',
2213
                             'MyType m = {',
2214
                             '  {value1, value2},',
2215
                             '  {',  # no warning
2216
                             '    loooong_value1, looooong_value2',
2217
                             '  }',
2218
                             '};',
2219
                             '#if PREPROCESSOR',
2220
                             '{',  # no warning
2221
                             '  MutexLock l(&mu);',
2222
                             '}',
2223
                             '#endif'],
2224
                            error_collector)
2225
    self.assertEquals(1, error_collector.Results().count(
2226
        '{ should almost always be at the end of the previous line'
2227
        '  [whitespace/braces] [4]'))
2228

    
2229
    self.TestMultiLineLint(
2230
        """
2231
        foo(
2232
          {
2233
            loooooooooooooooong_value,
2234
          });""",
2235
        '')
2236

    
2237
  def testMismatchingSpacesInParens(self):
2238
    self.TestLint('if (foo ) {', 'Mismatching spaces inside () in if'
2239
                  '  [whitespace/parens] [5]')
2240
    self.TestLint('switch ( foo) {', 'Mismatching spaces inside () in switch'
2241
                  '  [whitespace/parens] [5]')
2242
    self.TestLint('for (foo; ba; bar ) {', 'Mismatching spaces inside () in for'
2243
                  '  [whitespace/parens] [5]')
2244
    self.TestLint('for (; foo; bar) {', '')
2245
    self.TestLint('for ( ; foo; bar) {', '')
2246
    self.TestLint('for ( ; foo; bar ) {', '')
2247
    self.TestLint('for (foo; bar; ) {', '')
2248
    self.TestLint('while (  foo  ) {', 'Should have zero or one spaces inside'
2249
                  ' ( and ) in while  [whitespace/parens] [5]')
2250

    
2251
  def testSpacingForFncall(self):
2252
    self.TestLint('if (foo) {', '')
2253
    self.TestLint('for (foo; bar; baz) {', '')
2254
    self.TestLint('for (;;) {', '')
2255
    # Space should be allowed in placement new operators.
2256
    self.TestLint('Something* p = new (place) Something();', '')
2257
    # Test that there is no warning when increment statement is empty.
2258
    self.TestLint('for (foo; baz;) {', '')
2259
    self.TestLint('for (foo;bar;baz) {', 'Missing space after ;'
2260
                  '  [whitespace/semicolon] [3]')
2261
    # we don't warn about this semicolon, at least for now
2262
    self.TestLint('if (condition) {return &something; }',
2263
                  '')
2264
    # seen in some macros
2265
    self.TestLint('DoSth();\\', '')
2266
    # Test that there is no warning about semicolon here.
2267
    self.TestLint('abc;// this is abc',
2268
                  'At least two spaces is best between code'
2269
                  ' and comments  [whitespace/comments] [2]')
2270
    self.TestLint('while (foo) {', '')
2271
    self.TestLint('switch (foo) {', '')
2272
    self.TestLint('foo( bar)', 'Extra space after ( in function call'
2273
                  '  [whitespace/parens] [4]')
2274
    self.TestLint('foo(  // comment', '')
2275
    self.TestLint('foo( // comment',
2276
                  'At least two spaces is best between code'
2277
                  ' and comments  [whitespace/comments] [2]')
2278
    self.TestLint('foobar( \\', '')
2279
    self.TestLint('foobar(     \\', '')
2280
    self.TestLint('( a + b)', 'Extra space after ('
2281
                  '  [whitespace/parens] [2]')
2282
    self.TestLint('((a+b))', '')
2283
    self.TestLint('foo (foo)', 'Extra space before ( in function call'
2284
                  '  [whitespace/parens] [4]')
2285
    self.TestLint('} catch (const Foo& ex) {', '')
2286
    self.TestLint('case (42):', '')
2287
    self.TestLint('typedef foo (*foo)(foo)', '')
2288
    self.TestLint('typedef foo (*foo12bar_)(foo)', '')
2289
    self.TestLint('typedef foo (Foo::*bar)(foo)', '')
2290
    self.TestLint('using foo = type (Foo::*bar)(foo)', '')
2291
    self.TestLint('using foo = type (Foo::*bar)(', '')
2292
    self.TestLint('using foo = type (Foo::*)(', '')
2293
    self.TestLint('foo (Foo::*bar)(', '')
2294
    self.TestLint('foo (x::y::*z)(', '')
2295
    self.TestLint('foo (Foo::bar)(',
2296
                  'Extra space before ( in function call'
2297
                  '  [whitespace/parens] [4]')
2298
    self.TestLint('foo (*bar)(', '')
2299
    self.TestLint('typedef foo (Foo::*bar)(', '')
2300
    self.TestLint('(foo)(bar)', '')
2301
    self.TestLint('Foo (*foo)(bar)', '')
2302
    self.TestLint('Foo (*foo)(Bar bar,', '')
2303
    self.TestLint('char (*p)[sizeof(foo)] = &foo', '')
2304
    self.TestLint('char (&ref)[sizeof(foo)] = &foo', '')
2305
    self.TestLint('const char32 (*table[])[6];', '')
2306
    # The sizeof operator is often written as if it were a function call, with
2307
    # an opening parenthesis directly following the operator name, but it can
2308
    # also be written like any other operator, with a space following the
2309
    # operator name, and the argument optionally in parentheses.
2310
    self.TestLint('sizeof(foo)', '')
2311
    self.TestLint('sizeof foo', '')
2312
    self.TestLint('sizeof (foo)', '')
2313

    
2314
  def testSpacingBeforeBraces(self):
2315
    self.TestLint('if (foo){', 'Missing space before {'
2316
                  '  [whitespace/braces] [5]')
2317
    self.TestLint('for{', 'Missing space before {'
2318
                  '  [whitespace/braces] [5]')
2319
    self.TestLint('for {', '')
2320
    self.TestLint('EXPECT_DEBUG_DEATH({', '')
2321
    self.TestLint('std::is_convertible<A, B>{}', '')
2322

    
2323
  def testSemiColonAfterBraces(self):
2324
    self.TestLint('if (cond) {};',
2325
                  'You don\'t need a ; after a }  [readability/braces] [4]')
2326
    self.TestLint('void Func() {};',
2327
                  'You don\'t need a ; after a }  [readability/braces] [4]')
2328
    self.TestLint('void Func() const {};',
2329
                  'You don\'t need a ; after a }  [readability/braces] [4]')
2330
    self.TestLint('class X {};', '')
2331
    for keyword in ['struct', 'union']:
2332
      for align in ['', ' alignas(16)']:
2333
        for typename in ['', ' X']:
2334
          for identifier in ['', ' x']:
2335
            self.TestLint(keyword + align + typename + ' {}' + identifier + ';',
2336
                          '')
2337

    
2338
    self.TestLint('class X : public Y {};', '')
2339
    self.TestLint('class X : public MACRO() {};', '')
2340
    self.TestLint('DEFINE_FACADE(PCQueue::Watcher, PCQueue) {};', '')
2341
    self.TestLint('VCLASS(XfaTest, XfaContextTest) {};', '')
2342
    self.TestLint('TEST(TestCase, TestName) {};',
2343
                  'You don\'t need a ; after a }  [readability/braces] [4]')
2344
    self.TestLint('TEST_F(TestCase, TestName) {};',
2345
                  'You don\'t need a ; after a }  [readability/braces] [4]')
2346

    
2347
    self.TestLint('file_tocs_[i] = (FileToc) {a, b, c};', '')
2348
    self.TestMultiLineLint('class X : public Y,\npublic Z {};', '')
2349

    
2350
  def testLambda(self):
2351
    self.TestLint('auto x = []() {};', '')
2352
    self.TestLint('return []() {};', '')
2353
    self.TestMultiLineLint('auto x = []() {\n};\n', '')
2354
    self.TestLint('int operator[](int x) {};',
2355
                  'You don\'t need a ; after a }  [readability/braces] [4]')
2356

    
2357
    self.TestMultiLineLint('auto x = [&a,\nb]() {};', '')
2358
    self.TestMultiLineLint('auto x = [&a,\nb]\n() {};', '')
2359
    self.TestMultiLineLint('auto x = [&a,\n'
2360
                           '          b](\n'
2361
                           '    int a,\n'
2362
                           '    int b) {\n'
2363
                           '  return a +\n'
2364
                           '         b;\n'
2365
                           '};\n',
2366
                           '')
2367

    
2368
    for lambda_with_default_capture in ('void f() { [=]{}; }',
2369
                                        'void f() { [=](int i) {}; }',
2370
                                        'void f() { [=, &x]{}; }',
2371
                                        'void f() { [&]{}; }',
2372
                                        'void f() { [ & ]{}; }',
2373
                                        'void f() { [&, y]{}; }'):
2374
      self.TestLint(lambda_with_default_capture,
2375
                    'Default lambda captures are an unapproved C++ feature.  '
2376
                    '[build/c++11] [4]')
2377

    
2378
    # "[&...]" isn't necessarily a default capture, though "[=...]" always is.
2379
    self.TestLint('void f() { [&variable]{}; }', '')
2380

    
2381
    # Avoid false positives with operator[]
2382
    self.TestLint('table_to_children[&*table].push_back(dependent);', '')
2383

    
2384
  def testBraceInitializerList(self):
2385
    self.TestLint('MyStruct p = {1, 2};', '')
2386
    self.TestLint('MyStruct p{1, 2};', '')
2387
    self.TestLint('vector<int> p = {1, 2};', '')
2388
    self.TestLint('vector<int> p{1, 2};', '')
2389
    self.TestLint('x = vector<int>{1, 2};', '')
2390
    self.TestLint('x = (struct in_addr){ 0 };', '')
2391
    self.TestLint('Func(vector<int>{1, 2})', '')
2392
    self.TestLint('Func((struct in_addr){ 0 })', '')
2393
    self.TestLint('Func(vector<int>{1, 2}, 3)', '')
2394
    self.TestLint('Func((struct in_addr){ 0 }, 3)', '')
2395
    self.TestLint('LOG(INFO) << char{7};', '')
2396
    self.TestLint('LOG(INFO) << char{7} << "!";', '')
2397
    self.TestLint('int p[2] = {1, 2};', '')
2398
    self.TestLint('return {1, 2};', '')
2399
    self.TestLint('std::unique_ptr<Foo> foo{new Foo{}};', '')
2400
    self.TestLint('auto foo = std::unique_ptr<Foo>{new Foo{}};', '')
2401
    self.TestLint('static_assert(Max7String{}.IsValid(), "");', '')
2402
    self.TestLint('map_of_pairs[{1, 2}] = 3;', '')
2403
    self.TestLint('ItemView{has_offer() ? new Offer{offer()} : nullptr', '')
2404
    self.TestLint('template <class T, EnableIf<::std::is_const<T>{}> = 0>', '')
2405

    
2406
    self.TestMultiLineLint('std::unique_ptr<Foo> foo{\n'
2407
                           '  new Foo{}\n'
2408
                           '};\n', '')
2409
    self.TestMultiLineLint('std::unique_ptr<Foo> foo{\n'
2410
                           '  new Foo{\n'
2411
                           '    new Bar{}\n'
2412
                           '  }\n'
2413
                           '};\n', '')
2414
    self.TestMultiLineLint('if (true) {\n'
2415
                           '  if (false){}\n'
2416
                           '}\n',
2417
                           'Missing space before {  [whitespace/braces] [5]')
2418
    self.TestMultiLineLint('MyClass::MyClass()\n'
2419
                           '    : initializer_{\n'
2420
                           '          Func()} {\n'
2421
                           '}\n', '')
2422

    
2423
  def testSpacingAroundElse(self):
2424
    self.TestLint('}else {', 'Missing space before else'
2425
                  '  [whitespace/braces] [5]')
2426
    self.TestLint('} else{', 'Missing space before {'
2427
                  '  [whitespace/braces] [5]')
2428
    self.TestLint('} else {', '')
2429
    self.TestLint('} else if (foo) {', '')
2430

    
2431
  def testSpacingWithInitializerLists(self):
2432
    self.TestLint('int v[1][3] = {{1, 2, 3}};', '')
2433
    self.TestLint('int v[1][1] = {{0}};', '')
2434

    
2435
  def testSpacingForBinaryOps(self):
2436
    self.TestLint('if (foo||bar) {', 'Missing spaces around ||'
2437
                  '  [whitespace/operators] [3]')
2438
    self.TestLint('if (foo<=bar) {', 'Missing spaces around <='
2439
                  '  [whitespace/operators] [3]')
2440
    self.TestLint('if (foo<bar) {', 'Missing spaces around <'
2441
                  '  [whitespace/operators] [3]')
2442
    self.TestLint('if (foo>bar) {', 'Missing spaces around >'
2443
                  '  [whitespace/operators] [3]')
2444
    self.TestLint('if (foo<bar->baz) {', 'Missing spaces around <'
2445
                  '  [whitespace/operators] [3]')
2446
    self.TestLint('if (foo<bar->bar) {', 'Missing spaces around <'
2447
                  '  [whitespace/operators] [3]')
2448
    self.TestLint('template<typename T = double>', '')
2449
    self.TestLint('std::unique_ptr<No<Spaces>>', '')
2450
    self.TestLint('typedef hash_map<Foo, Bar>', '')
2451
    self.TestLint('10<<20', '')
2452
    self.TestLint('10<<a',
2453
                  'Missing spaces around <<  [whitespace/operators] [3]')
2454
    self.TestLint('a<<20',
2455
                  'Missing spaces around <<  [whitespace/operators] [3]')
2456
    self.TestLint('a<<b',
2457
                  'Missing spaces around <<  [whitespace/operators] [3]')
2458
    self.TestLint('10ULL<<20', '')
2459
    self.TestLint('a>>b',
2460
                  'Missing spaces around >>  [whitespace/operators] [3]')
2461
    self.TestLint('10>>b',
2462
                  'Missing spaces around >>  [whitespace/operators] [3]')
2463
    self.TestLint('LOG(ERROR)<<*foo',
2464
                  'Missing spaces around <<  [whitespace/operators] [3]')
2465
    self.TestLint('LOG(ERROR)<<&foo',
2466
                  'Missing spaces around <<  [whitespace/operators] [3]')
2467
    self.TestLint('StringCoder<vector<string>>::ToString()', '')
2468
    self.TestLint('map<pair<int, int>, map<int, int>>::iterator', '')
2469
    self.TestLint('func<int, pair<int, pair<int, int>>>()', '')
2470
    self.TestLint('MACRO1(list<list<int>>)', '')
2471
    self.TestLint('MACRO2(list<list<int>>, 42)', '')
2472
    self.TestLint('void DoFoo(const set<vector<string>>& arg1);', '')
2473
    self.TestLint('void SetFoo(set<vector<string>>* arg1);', '')
2474
    self.TestLint('foo = new set<vector<string>>;', '')
2475
    self.TestLint('reinterpret_cast<set<vector<string>>*>(a);', '')
2476
    self.TestLint('MACRO(<<)', '')
2477
    self.TestLint('MACRO(<<, arg)', '')
2478
    self.TestLint('MACRO(<<=)', '')
2479
    self.TestLint('MACRO(<<=, arg)', '')
2480

    
2481
    self.TestLint('using Vector3<T>::operator==;', '')
2482
    self.TestLint('using Vector3<T>::operator!=;', '')
2483

    
2484
  def testRvalueReference(self):
2485
    space_error = 'Missing spaces around &&  [whitespace/operators] [3]'
2486
    rvalue_error = ('RValue references are an unapproved C++ feature.'
2487
                    '  [build/c++11] [3]')
2488

    
2489
    # Places where lack of space are allowed
2490
    self.TestLint('DEFINE_BINARY_OPERATOR(&&)', '')
2491
    self.TestLint('bool operator&&(A b) {}', '')
2492
    self.TestLint('bool operator&&(A b) {', '')
2493
    self.TestLint('bool operator&&(A b);', '')
2494

    
2495
    # Assignment expressions
2496
    self.TestLint('a = b && c;', '')
2497
    self.TestLint('a = b&& c;', space_error)
2498
    self.TestLint('a = b &&c;', space_error)
2499
    self.TestLint('a = (b&& c);', space_error)
2500
    self.TestLint('a = (b &&c);', space_error)
2501
    self.TestLint('a&& b = c;', rvalue_error)
2502
    self.TestLint('a<b>&& c = d;', rvalue_error)
2503
    self.TestLint('auto&& a = b;', rvalue_error)
2504
    self.TestLint('const a&& b = c;', rvalue_error)
2505
    self.TestLint('struct a&& b = c;', rvalue_error)
2506
    self.TestLint('decltype(a)&& b = c;', rvalue_error)
2507

    
2508
    # Cast expressions
2509
    self.TestLint('a = const_cast<b&&>(c);', rvalue_error)
2510
    self.TestLint('a = const_cast<const b&&>(c);', rvalue_error)
2511
    self.TestLint('a = static_cast<b&&>(c);', rvalue_error)
2512
    self.TestLint('a = static_cast<const b&&>(c);', rvalue_error)
2513
    self.TestLint('a = dynamic_cast<b&&>(c);', rvalue_error)
2514
    self.TestLint('a = dynamic_cast<const b&&>(c);', rvalue_error)
2515
    self.TestLint('a = reinterpret_cast<b&&>(c);', rvalue_error)
2516
    self.TestLint('a = reinterpret_cast<const b&&>(c);', rvalue_error)
2517
    self.TestLint('a = cast < b&& c;', space_error)
2518

    
2519
    # Function parameters
2520
    for indent in ['', '  ']:
2521
      for head in ['void Func', 'vector<int> Func', 'vector<int>\nFunc',
2522
                   'inline void Func',
2523
                   'Constructor', 'Constructor::Constructor',
2524
                   'operator=', 'operator =', 'operator = ']:
2525
        for body in [' {}', ' {', ';']:
2526
          self.TestMultiLineLint(indent + head + '(A&& b)' + body, rvalue_error)
2527
          self.TestMultiLineLint(indent + head + '(A &&b)' + body, rvalue_error)
2528
          self.TestMultiLineLint(indent + head + '(A&&... b)' + body,
2529
                                 rvalue_error)
2530
          self.TestMultiLineLint(indent + head + '(A<B>&& c)' + body,
2531
                                 rvalue_error)
2532
          self.TestMultiLineLint(indent + head + '(A<B> &&c)' + body,
2533
                                 rvalue_error)
2534

    
2535
    # Function templates
2536
    self.TestLint('std::conditional<A, B&, C&&>::type', rvalue_error)
2537
    self.TestLint('std::conditional<A, B&&, C&>::type', rvalue_error)
2538

    
2539
    # Template functions
2540
    self.TestLint('template <typename T> R&& F()', rvalue_error)
2541
    self.TestLint('template <typename T> R&& F() {', rvalue_error)
2542
    self.TestMultiLineLint('template <typename T>\nR&& F()', rvalue_error)
2543
    self.TestMultiLineLint('template <typename T>\nR&& F() {', rvalue_error)
2544
    self.TestLint('template <typename T> void F(T a, R&& b)', rvalue_error)
2545
    self.TestLint('template <typename T> void F(T a, R &&b)', rvalue_error)
2546
    self.TestLint('template <typename T> void F(T a, R&& b) {', rvalue_error)
2547

    
2548
    # For loops
2549
    self.TestLint('for (a&& b;;)', rvalue_error)
2550
    self.TestLint('for (a&& b;;) {', rvalue_error)
2551
    self.TestLint('for (; a&& b;)', space_error)
2552
    self.TestLint('for (; a&& b;) {', space_error)
2553

    
2554
    # Constructors
2555
    self.TestLint('A(a&& b)', rvalue_error)
2556
    self.TestLint('explicit A(a&& b)', rvalue_error)
2557
    self.TestLint('A(a b) : c(d&& e)', space_error)
2558
    self.TestLint('A(a b) : c(), d(e&& f)', space_error)
2559

    
2560
  def testAllowedRvalueReference(self):
2561
    # Verify that RValue reference warnings for a line range can be silenced
2562
    error_collector = ErrorCollector(self.assert_)
2563
    cpplint.ProcessFileData('foo.cc', 'cc',
2564
                            ['// Copyright 2014 Your Company.',
2565
                             'GOOGLE_ALLOW_RVALUE_REFERENCES_PUSH',
2566
                             'void F(A&& b);',
2567
                             'GOOGLE_ALLOW_RVALUE_REFERENCES_POP',
2568
                             ''],
2569
                            error_collector)
2570
    self.assertEquals(error_collector.Results(), '')
2571

    
2572
    # RValue references for constructors and operator=
2573
    error_collector = ErrorCollector(self.assert_)
2574
    cpplint.ProcessFileData(
2575
        'foo.cc', 'cc',
2576
        ['// Copyright 2014 Your Company.',
2577
         'class X {',
2578
         '  X(X&& param) = delete;  // NOLINT(runtime/explicit)',
2579
         '  X(X &&param) = default;  // NOLINT(runtime/explicit)',
2580
         '  inline X(X&& param) = default;  // NOLINT(runtime/explicit)',
2581
         '',
2582
         '  X& operator=(X&& param) = delete;',
2583
         '  X& operator=(X&& param) = default;',
2584
         '};',
2585
         'A::A(A&&) = default;',
2586
         'Outer::Inner::Inner(Inner&&) = default;',
2587
         ''],
2588
        error_collector)
2589
    self.assertEquals(error_collector.Results(), '')
2590

    
2591
    # Assume templated function parameters are forwarded, and are allowed
2592
    error_collector = ErrorCollector(self.assert_)
2593
    cpplint.ProcessFileData(
2594
        'foo.cc', 'cc',
2595
        ['// Copyright 2014 Your Company.',
2596
         'template <typename Allowed1>',
2597
         'void Function1(Allowed1&& a);',
2598
         '',
2599
         'template <typename Allowed2, typename Allowed3>',
2600
         'void Function2(Allowed2&& a, Allowed3 &&b) {',
2601
         '}',
2602
         '',
2603
         'template <class Allowed4>',
2604
         'void Function3(Ignored1 *a, Allowed4&& b) {',
2605
         '}',
2606
         '',
2607
         'template <typename... Allowed5>',
2608
         'void Function4(Allowed5&&... a) {',
2609
         '}',
2610
         '',
2611
         'template <class... Allowed6>',
2612
         'void Function5(',
2613
         '    Allowed6 &&...a) {',
2614
         '}',
2615
         ''],
2616
        error_collector)
2617
    self.assertEquals(error_collector.Results(), '')
2618

    
2619
  def testSpacingBeforeLastSemicolon(self):
2620
    self.TestLint('call_function() ;',
2621
                  'Extra space before last semicolon. If this should be an '
2622
                  'empty statement, use {} instead.'
2623
                  '  [whitespace/semicolon] [5]')
2624
    self.TestLint('while (true) ;',
2625
                  'Extra space before last semicolon. If this should be an '
2626
                  'empty statement, use {} instead.'
2627
                  '  [whitespace/semicolon] [5]')
2628
    self.TestLint('default:;',
2629
                  'Semicolon defining empty statement. Use {} instead.'
2630
                  '  [whitespace/semicolon] [5]')
2631
    self.TestLint('      ;',
2632
                  'Line contains only semicolon. If this should be an empty '
2633
                  'statement, use {} instead.'
2634
                  '  [whitespace/semicolon] [5]')
2635
    self.TestLint('for (int i = 0; ;', '')
2636

    
2637
  def testEmptyBlockBody(self):
2638
    self.TestLint('while (true);',
2639
                  'Empty loop bodies should use {} or continue'
2640
                  '  [whitespace/empty_loop_body] [5]')
2641
    self.TestLint('if (true);',
2642
                  'Empty conditional bodies should use {}'
2643
                  '  [whitespace/empty_conditional_body] [5]')
2644
    self.TestLint('while (true)', '')
2645
    self.TestLint('while (true) continue;', '')
2646
    self.TestLint('for (;;);',
2647
                  'Empty loop bodies should use {} or continue'
2648
                  '  [whitespace/empty_loop_body] [5]')
2649
    self.TestLint('for (;;)', '')
2650
    self.TestLint('for (;;) continue;', '')
2651
    self.TestLint('for (;;) func();', '')
2652
    self.TestMultiLineLint("""while (true &&
2653
                                     false);""",
2654
                           'Empty loop bodies should use {} or continue'
2655
                           '  [whitespace/empty_loop_body] [5]')
2656
    self.TestMultiLineLint("""do {
2657
                           } while (false);""",
2658
                           '')
2659
    self.TestMultiLineLint("""#define MACRO \\
2660
                           do { \\
2661
                           } while (false);""",
2662
                           '')
2663
    self.TestMultiLineLint("""do {
2664
                           } while (false);  // next line gets a warning
2665
                           while (false);""",
2666
                           'Empty loop bodies should use {} or continue'
2667
                           '  [whitespace/empty_loop_body] [5]')
2668

    
2669
  def testSpacingForRangeBasedFor(self):
2670
    # Basic correctly formatted case:
2671
    self.TestLint('for (int i : numbers) {', '')
2672

    
2673
    # Missing space before colon:
2674
    self.TestLint('for (int i: numbers) {',
2675
                  'Missing space around colon in range-based for loop'
2676
                  '  [whitespace/forcolon] [2]')
2677
    # Missing space after colon:
2678
    self.TestLint('for (int i :numbers) {',
2679
                  'Missing space around colon in range-based for loop'
2680
                  '  [whitespace/forcolon] [2]')
2681
    # Missing spaces both before and after the colon.
2682
    self.TestLint('for (int i:numbers) {',
2683
                  'Missing space around colon in range-based for loop'
2684
                  '  [whitespace/forcolon] [2]')
2685

    
2686
    # The scope operator '::' shouldn't cause warnings...
2687
    self.TestLint('for (std::size_t i : sizes) {}', '')
2688
    # ...but it shouldn't suppress them either.
2689
    self.TestLint('for (std::size_t i: sizes) {}',
2690
                  'Missing space around colon in range-based for loop'
2691
                  '  [whitespace/forcolon] [2]')
2692

    
2693

    
2694
  # Static or global STL strings.
2695
  def testStaticOrGlobalSTLStrings(self):
2696
    error_msg = ('For a static/global string constant, use a C style '
2697
                 'string instead: "%s[]".  [runtime/string] [4]')
2698

    
2699
    self.TestLint('string foo;',
2700
                  error_msg % 'char foo')
2701
    self.TestLint('string kFoo = "hello";  // English',
2702
                  error_msg % 'char kFoo')
2703
    self.TestLint('static string foo;',
2704
                  error_msg % 'static char foo')
2705
    self.TestLint('static const string foo;',
2706
                  error_msg % 'static const char foo')
2707
    self.TestLint('string Foo::bar;',
2708
                  error_msg % 'char Foo::bar')
2709
    self.TestLint('string* pointer', '')
2710
    self.TestLint('string *pointer', '')
2711
    self.TestLint('string* pointer = Func();', '')
2712
    self.TestLint('string *pointer = Func();', '')
2713
    self.TestLint('const string* pointer', '')
2714
    self.TestLint('const string *pointer', '')
2715
    self.TestLint('const string* pointer = Func();', '')
2716
    self.TestLint('const string *pointer = Func();', '')
2717
    self.TestLint('string const* pointer', '')
2718
    self.TestLint('string const *pointer', '')
2719
    self.TestLint('string const* pointer = Func();', '')
2720
    self.TestLint('string const *pointer = Func();', '')
2721
    self.TestLint('string* const pointer', '')
2722
    self.TestLint('string *const pointer', '')
2723
    self.TestLint('string* const pointer = Func();', '')
2724
    self.TestLint('string *const pointer = Func();', '')
2725
    self.TestLint('string Foo::bar() {}', '')
2726
    self.TestLint('string Foo::operator*() {}', '')
2727
    # Rare case.
2728
    self.TestLint('string foo("foobar");', error_msg % 'char foo')
2729
    # Should not catch local or member variables.
2730
    self.TestLint('  string foo', '')
2731
    # Should not catch functions.
2732
    self.TestLint('string EmptyString() { return ""; }', '')
2733
    self.TestLint('string EmptyString () { return ""; }', '')
2734
    self.TestLint('string VeryLongNameFunctionSometimesEndsWith(\n'
2735
                  '    VeryLongNameType very_long_name_variable) {}', '')
2736
    self.TestLint('template<>\n'
2737
                  'string FunctionTemplateSpecialization<SomeType>(\n'
2738
                  '      int x) { return ""; }', '')
2739
    self.TestLint('template<>\n'
2740
                  'string FunctionTemplateSpecialization<vector<A::B>* >(\n'
2741
                  '      int x) { return ""; }', '')
2742

    
2743
    # should not catch methods of template classes.
2744
    self.TestLint('string Class<Type>::Method() const {\n'
2745
                  '  return "";\n'
2746
                  '}\n', '')
2747
    self.TestLint('string Class<Type>::Method(\n'
2748
                  '   int arg) const {\n'
2749
                  '  return "";\n'
2750
                  '}\n', '')
2751

    
2752
    # Check multiline cases.
2753
    error_collector = ErrorCollector(self.assert_)
2754
    cpplint.ProcessFileData('foo.cc', 'cc',
2755
                            ['// Copyright 2014 Your Company.',
2756
                             'string Class',
2757
                             '::MemberFunction1();',
2758
                             'string Class::',
2759
                             'MemberFunction2();',
2760
                             'string Class::',
2761
                             'NestedClass::MemberFunction3();',
2762
                             'string TemplateClass<T>::',
2763
                             'NestedClass::MemberFunction4();',
2764
                             'string Class',
2765
                             '::static_member_variable1;',
2766
                             'string Class::',
2767
                             'static_member_variable2;',
2768
                             'string Class',
2769
                             '::static_member_variable3 = "initial value";',
2770
                             'string Class::',
2771
                             'static_member_variable4 = "initial value";',
2772
                             ''],
2773
                            error_collector)
2774
    self.assertEquals(error_collector.Results(),
2775
                      [error_msg % 'char Class::static_member_variable1',
2776
                       error_msg % 'char Class::static_member_variable2',
2777
                       error_msg % 'char Class::static_member_variable3',
2778
                       error_msg % 'char Class::static_member_variable4'])
2779

    
2780
  def testNoSpacesInFunctionCalls(self):
2781
    self.TestLint('TellStory(1, 3);',
2782
                  '')
2783
    self.TestLint('TellStory(1, 3 );',
2784
                  'Extra space before )'
2785
                  '  [whitespace/parens] [2]')
2786
    self.TestLint('TellStory(1 /* wolf */, 3 /* pigs */);',
2787
                  '')
2788
    self.TestMultiLineLint("""TellStory(1, 3
2789
                                        );""",
2790
                           'Closing ) should be moved to the previous line'
2791
                           '  [whitespace/parens] [2]')
2792
    self.TestMultiLineLint("""TellStory(Wolves(1),
2793
                                        Pigs(3
2794
                                        ));""",
2795
                           'Closing ) should be moved to the previous line'
2796
                           '  [whitespace/parens] [2]')
2797
    self.TestMultiLineLint("""TellStory(1,
2798
                                        3 );""",
2799
                           'Extra space before )'
2800
                           '  [whitespace/parens] [2]')
2801

    
2802
  def testToDoComments(self):
2803
    start_space = ('Too many spaces before TODO'
2804
                   '  [whitespace/todo] [2]')
2805
    missing_username = ('Missing username in TODO; it should look like '
2806
                        '"// TODO(my_username): Stuff."'
2807
                        '  [readability/todo] [2]')
2808
    end_space = ('TODO(my_username) should be followed by a space'
2809
                 '  [whitespace/todo] [2]')
2810

    
2811
    self.TestLint('//   TODOfix this',
2812
                  [start_space, missing_username, end_space])
2813
    self.TestLint('//   TODO(ljenkins)fix this',
2814
                  [start_space, end_space])
2815
    self.TestLint('//   TODO fix this',
2816
                  [start_space, missing_username])
2817
    self.TestLint('// TODO fix this', missing_username)
2818
    self.TestLint('// TODO: fix this', missing_username)
2819
    self.TestLint('//TODO(ljenkins): Fix this',
2820
                  'Should have a space between // and comment'
2821
                  '  [whitespace/comments] [4]')
2822
    self.TestLint('// TODO(ljenkins):Fix this', end_space)
2823
    self.TestLint('// TODO(ljenkins):', '')
2824
    self.TestLint('// TODO(ljenkins): fix this', '')
2825
    self.TestLint('// TODO(ljenkins): Fix this', '')
2826
    self.TestLint('#if 1  // TEST_URLTODOCID_WHICH_HAS_THAT_WORD_IN_IT_H_', '')
2827
    self.TestLint('// See also similar TODO above', '')
2828

    
2829
  def testTwoSpacesBetweenCodeAndComments(self):
2830
    self.TestLint('} // namespace foo',
2831
                  'At least two spaces is best between code and comments'
2832
                  '  [whitespace/comments] [2]')
2833
    self.TestLint('}// namespace foo',
2834
                  'At least two spaces is best between code and comments'
2835
                  '  [whitespace/comments] [2]')
2836
    self.TestLint('printf("foo"); // Outside quotes.',
2837
                  'At least two spaces is best between code and comments'
2838
                  '  [whitespace/comments] [2]')
2839
    self.TestLint('int i = 0;  // Having two spaces is fine.', '')
2840
    self.TestLint('int i = 0;   // Having three spaces is OK.', '')
2841
    self.TestLint('// Top level comment', '')
2842
    self.TestLint('  // Line starts with two spaces.', '')
2843
    self.TestMultiLineLint('void foo() {\n'
2844
                           '  { // A scope is opening.\n'
2845
                           '    int a;', '')
2846
    self.TestMultiLineLint('void foo() {\n'
2847
                           '  { // A scope is opening.\n'
2848
                           '#define A a',
2849
                           'At least two spaces is best between code and '
2850
                           'comments  [whitespace/comments] [2]')
2851
    self.TestMultiLineLint('  foo();\n'
2852
                           '  { // An indented scope is opening.\n'
2853
                           '    int a;', '')
2854
    self.TestMultiLineLint('vector<int> my_elements = {// first\n'
2855
                           '                           1,', '')
2856
    self.TestMultiLineLint('vector<int> my_elements = {// my_elements is ..\n'
2857
                           '    1,',
2858
                           'At least two spaces is best between code and '
2859
                           'comments  [whitespace/comments] [2]')
2860
    self.TestLint('if (foo) { // not a pure scope; comment is too close!',
2861
                  'At least two spaces is best between code and comments'
2862
                  '  [whitespace/comments] [2]')
2863
    self.TestLint('printf("// In quotes.")', '')
2864
    self.TestLint('printf("\\"%s // In quotes.")', '')
2865
    self.TestLint('printf("%s", "// In quotes.")', '')
2866

    
2867
  def testSpaceAfterCommentMarker(self):
2868
    self.TestLint('//', '')
2869
    self.TestLint('//x', 'Should have a space between // and comment'
2870
                  '  [whitespace/comments] [4]')
2871
    self.TestLint('// x', '')
2872
    self.TestLint('///', '')
2873
    self.TestLint('/// x', '')
2874
    self.TestLint('//!', '')
2875
    self.TestLint('//----', '')
2876
    self.TestLint('//====', '')
2877
    self.TestLint('//////', '')
2878
    self.TestLint('////// x', '')
2879
    self.TestLint('///< x', '') # After-member Doxygen comment
2880
    self.TestLint('//!< x', '') # After-member Doxygen comment
2881
    self.TestLint('////x', 'Should have a space between // and comment'
2882
                  '  [whitespace/comments] [4]')
2883
    self.TestLint('//}', '')
2884
    self.TestLint('//}x', 'Should have a space between // and comment'
2885
                  '  [whitespace/comments] [4]')
2886
    self.TestLint('//!<x', 'Should have a space between // and comment'
2887
                  '  [whitespace/comments] [4]')
2888
    self.TestLint('///<x', 'Should have a space between // and comment'
2889
                  '  [whitespace/comments] [4]')
2890

    
2891
  # Test a line preceded by empty or comment lines.  There was a bug
2892
  # that caused it to print the same warning N times if the erroneous
2893
  # line was preceded by N lines of empty or comment lines.  To be
2894
  # precise, the '// marker so line numbers and indices both start at
2895
  # 1' line was also causing the issue.
2896
  def testLinePrecededByEmptyOrCommentLines(self):
2897
    def DoTest(self, lines):
2898
      error_collector = ErrorCollector(self.assert_)
2899
      cpplint.ProcessFileData('foo.cc', 'cc', lines, error_collector)
2900
      # The warning appears only once.
2901
      self.assertEquals(
2902
          1,
2903
          error_collector.Results().count(
2904
              'Do not use namespace using-directives.  '
2905
              'Use using-declarations instead.'
2906
              '  [build/namespaces] [5]'))
2907
    DoTest(self, ['using namespace foo;'])
2908
    DoTest(self, ['', '', '', 'using namespace foo;'])
2909
    DoTest(self, ['// hello', 'using namespace foo;'])
2910

    
2911
  def testNewlineAtEOF(self):
2912
    def DoTest(self, data, is_missing_eof):
2913
      error_collector = ErrorCollector(self.assert_)
2914
      cpplint.ProcessFileData('foo.cc', 'cc', data.split('\n'),
2915
                              error_collector)
2916
      # The warning appears only once.
2917
      self.assertEquals(
2918
          int(is_missing_eof),
2919
          error_collector.Results().count(
2920
              'Could not find a newline character at the end of the file.'
2921
              '  [whitespace/ending_newline] [5]'))
2922

    
2923
    DoTest(self, '// Newline\n// at EOF\n', False)
2924
    DoTest(self, '// No newline\n// at EOF', True)
2925

    
2926
  def testInvalidUtf8(self):
2927
    def DoTest(self, raw_bytes, has_invalid_utf8):
2928
      error_collector = ErrorCollector(self.assert_)
2929
      cpplint.ProcessFileData(
2930
          'foo.cc', 'cc',
2931
          unicode(raw_bytes, 'utf8', 'replace').split('\n'),
2932
          error_collector)
2933
      # The warning appears only once.
2934
      self.assertEquals(
2935
          int(has_invalid_utf8),
2936
          error_collector.Results().count(
2937
              'Line contains invalid UTF-8'
2938
              ' (or Unicode replacement character).'
2939
              '  [readability/utf8] [5]'))
2940

    
2941
    DoTest(self, 'Hello world\n', False)
2942
    DoTest(self, '\xe9\x8e\xbd\n', False)
2943
    DoTest(self, '\xe9x\x8e\xbd\n', True)
2944
    # This is the encoding of the replacement character itself (which
2945
    # you can see by evaluating codecs.getencoder('utf8')(u'\ufffd')).
2946
    DoTest(self, '\xef\xbf\xbd\n', True)
2947

    
2948
  def testBadCharacters(self):
2949
    # Test for NUL bytes only
2950
    error_collector = ErrorCollector(self.assert_)
2951
    cpplint.ProcessFileData('nul.cc', 'cc',
2952
                            ['// Copyright 2014 Your Company.',
2953
                             '\0', ''], error_collector)
2954
    self.assertEquals(
2955
        error_collector.Results(),
2956
        'Line contains NUL byte.  [readability/nul] [5]')
2957

    
2958
    # Make sure both NUL bytes and UTF-8 are caught if they appear on
2959
    # the same line.
2960
    error_collector = ErrorCollector(self.assert_)
2961
    cpplint.ProcessFileData(
2962
        'nul_utf8.cc', 'cc',
2963
        ['// Copyright 2014 Your Company.',
2964
         unicode('\xe9x\0', 'utf8', 'replace'), ''],
2965
        error_collector)
2966
    self.assertEquals(
2967
        error_collector.Results(),
2968
        ['Line contains invalid UTF-8 (or Unicode replacement character).'
2969
         '  [readability/utf8] [5]',
2970
         'Line contains NUL byte.  [readability/nul] [5]'])
2971

    
2972
  def testIsBlankLine(self):
2973
    self.assert_(cpplint.IsBlankLine(''))
2974
    self.assert_(cpplint.IsBlankLine(' '))
2975
    self.assert_(cpplint.IsBlankLine(' \t\r\n'))
2976
    self.assert_(not cpplint.IsBlankLine('int a;'))
2977
    self.assert_(not cpplint.IsBlankLine('{'))
2978

    
2979
  def testBlankLinesCheck(self):
2980
    self.TestBlankLinesCheck(['{\n', '\n', '\n', '}\n'], 1, 1)
2981
    self.TestBlankLinesCheck(['  if (foo) {\n', '\n', '  }\n'], 1, 1)
2982
    self.TestBlankLinesCheck(
2983
        ['\n', '// {\n', '\n', '\n', '// Comment\n', '{\n', '}\n'], 0, 0)
2984
    self.TestBlankLinesCheck(['\n', 'run("{");\n', '\n'], 0, 0)
2985
    self.TestBlankLinesCheck(['\n', '  if (foo) { return 0; }\n', '\n'], 0, 0)
2986
    self.TestBlankLinesCheck(
2987
        ['int x(\n', '    int a) {\n', '\n', 'return 0;\n', '}'], 0, 0)
2988
    self.TestBlankLinesCheck(
2989
        ['int x(\n', '    int a) const {\n', '\n', 'return 0;\n', '}'], 0, 0)
2990
    self.TestBlankLinesCheck(
2991
        ['int x(\n', '     int a) {\n', '\n', 'return 0;\n', '}'], 1, 0)
2992
    self.TestBlankLinesCheck(
2993
        ['int x(\n', '   int a) {\n', '\n', 'return 0;\n', '}'], 1, 0)
2994

    
2995
  def testAllowBlankLineBeforeClosingNamespace(self):
2996
    error_collector = ErrorCollector(self.assert_)
2997
    cpplint.ProcessFileData('foo.cc', 'cc',
2998
                            ['namespace {',
2999
                             '',
3000
                             '}  // namespace',
3001
                             'namespace another_namespace {',
3002
                             '',
3003
                             '}',
3004
                             'namespace {',
3005
                             '',
3006
                             'template<class T, ',
3007
                             '         class A = hoge<T>, ',
3008
                             '         class B = piyo<T>, ',
3009
                             '         class C = fuga<T> >',
3010
                             'class D {',
3011
                             ' public:',
3012
                             '};',
3013
                             '', '', '', '',
3014
                             '}'],
3015
                            error_collector)
3016
    self.assertEquals(0, error_collector.Results().count(
3017
        'Redundant blank line at the end of a code block should be deleted.'
3018
        '  [whitespace/blank_line] [3]'))
3019

    
3020
  def testAllowBlankLineBeforeIfElseChain(self):
3021
    error_collector = ErrorCollector(self.assert_)
3022
    cpplint.ProcessFileData('foo.cc', 'cc',
3023
                            ['if (hoge) {',
3024
                             '',  # No warning
3025
                             '} else if (piyo) {',
3026
                             '',  # No warning
3027
                             '} else if (piyopiyo) {',
3028
                             '  hoge = true;',  # No warning
3029
                             '} else {',
3030
                             '',  # Warning on this line
3031
                             '}'],
3032
                            error_collector)
3033
    self.assertEquals(1, error_collector.Results().count(
3034
        'Redundant blank line at the end of a code block should be deleted.'
3035
        '  [whitespace/blank_line] [3]'))
3036

    
3037
  def testAllowBlankLineAfterExtern(self):
3038
    error_collector = ErrorCollector(self.assert_)
3039
    cpplint.ProcessFileData('foo.cc', 'cc',
3040
                            ['extern "C" {',
3041
                             '',
3042
                             'EXPORTAPI void APICALL Some_function() {}',
3043
                             '',
3044
                             '}'],
3045
                            error_collector)
3046
    self.assertEquals(0, error_collector.Results().count(
3047
        'Redundant blank line at the start of a code block should be deleted.'
3048
        '  [whitespace/blank_line] [2]'))
3049
    self.assertEquals(0, error_collector.Results().count(
3050
        'Redundant blank line at the end of a code block should be deleted.'
3051
        '  [whitespace/blank_line] [3]'))
3052

    
3053
  def testBlankLineBeforeSectionKeyword(self):
3054
    error_collector = ErrorCollector(self.assert_)
3055
    cpplint.ProcessFileData('foo.cc', 'cc',
3056
                            ['class A {',
3057
                             ' public:',
3058
                             ' protected:',   # warning 1
3059
                             ' private:',     # warning 2
3060
                             '  struct B {',
3061
                             '   public:',
3062
                             '   private:'] +  # warning 3
3063
                            ([''] * 100) +  # Make A and B longer than 100 lines
3064
                            ['  };',
3065
                             '  struct C {',
3066
                             '   protected:',
3067
                             '   private:',  # C is too short for warnings
3068
                             '  };',
3069
                             '};',
3070
                             'class D',
3071
                             '    : public {',
3072
                             ' public:',  # no warning
3073
                             '};',
3074
                             'class E {\\',
3075
                             ' public:\\'] +
3076
                            (['\\'] * 100) +  # Makes E > 100 lines
3077
                            ['  int non_empty_line;\\',
3078
                             ' private:\\',   # no warning
3079
                             '  int a;\\',
3080
                             '};'],
3081
                            error_collector)
3082
    self.assertEquals(2, error_collector.Results().count(
3083
        '"private:" should be preceded by a blank line'
3084
        '  [whitespace/blank_line] [3]'))
3085
    self.assertEquals(1, error_collector.Results().count(
3086
        '"protected:" should be preceded by a blank line'
3087
        '  [whitespace/blank_line] [3]'))
3088

    
3089
  def testNoBlankLineAfterSectionKeyword(self):
3090
    error_collector = ErrorCollector(self.assert_)
3091
    cpplint.ProcessFileData('foo.cc', 'cc',
3092
                            ['class A {',
3093
                             ' public:',
3094
                             '',  # warning 1
3095
                             ' private:',
3096
                             '',  # warning 2
3097
                             '  struct B {',
3098
                             '   protected:',
3099
                             '',  # warning 3
3100
                             '  };',
3101
                             '};'],
3102
                            error_collector)
3103
    self.assertEquals(1, error_collector.Results().count(
3104
        'Do not leave a blank line after "public:"'
3105
        '  [whitespace/blank_line] [3]'))
3106
    self.assertEquals(1, error_collector.Results().count(
3107
        'Do not leave a blank line after "protected:"'
3108
        '  [whitespace/blank_line] [3]'))
3109
    self.assertEquals(1, error_collector.Results().count(
3110
        'Do not leave a blank line after "private:"'
3111
        '  [whitespace/blank_line] [3]'))
3112

    
3113
  def testAllowBlankLinesInRawStrings(self):
3114
    error_collector = ErrorCollector(self.assert_)
3115
    cpplint.ProcessFileData('foo.cc', 'cc',
3116
                            ['// Copyright 2014 Your Company.',
3117
                             'static const char *kData[] = {R"(',
3118
                             '',
3119
                             ')", R"(',
3120
                             '',
3121
                             ')"};',
3122
                             ''],
3123
                            error_collector)
3124
    self.assertEquals('', error_collector.Results())
3125

    
3126
  def testElseOnSameLineAsClosingBraces(self):
3127
    error_collector = ErrorCollector(self.assert_)
3128
    cpplint.ProcessFileData('foo.cc', 'cc',
3129
                            ['if (hoge) {',
3130
                             '}',
3131
                             'else if (piyo) {',  # Warning on this line
3132
                             '}',
3133
                             ' else {'  # Warning on this line
3134
                             '',
3135
                             '}'],
3136
                            error_collector)
3137
    self.assertEquals(2, error_collector.Results().count(
3138
        'An else should appear on the same line as the preceding }'
3139
        '  [whitespace/newline] [4]'))
3140

    
3141
    error_collector = ErrorCollector(self.assert_)
3142
    cpplint.ProcessFileData('foo.cc', 'cc',
3143
                            ['if (hoge) {',
3144
                             '',
3145
                             '}',
3146
                             'else',  # Warning on this line
3147
                             '{',
3148
                             '',
3149
                             '}'],
3150
                            error_collector)
3151
    self.assertEquals(1, error_collector.Results().count(
3152
        'An else should appear on the same line as the preceding }'
3153
        '  [whitespace/newline] [4]'))
3154

    
3155
    error_collector = ErrorCollector(self.assert_)
3156
    cpplint.ProcessFileData('foo.cc', 'cc',
3157
                            ['if (hoge) {',
3158
                             '',
3159
                             '}',
3160
                             'else_function();'],
3161
                            error_collector)
3162
    self.assertEquals(0, error_collector.Results().count(
3163
        'An else should appear on the same line as the preceding }'
3164
        '  [whitespace/newline] [4]'))
3165

    
3166
  def testMultipleStatementsOnSameLine(self):
3167
    error_collector = ErrorCollector(self.assert_)
3168
    cpplint.ProcessFileData('foo.cc', 'cc',
3169
                            ['for (int i = 0; i < 1; i++) {}',
3170
                             'switch (x) {',
3171
                             '  case 0: func(); break; ',
3172
                             '}',
3173
                             'sum += MathUtil::SafeIntRound(x); x += 0.1;'],
3174
                            error_collector)
3175
    self.assertEquals(0, error_collector.Results().count(
3176
        'More than one command on the same line  [whitespace/newline] [0]'))
3177

    
3178
    old_verbose_level = cpplint._cpplint_state.verbose_level
3179
    cpplint._cpplint_state.verbose_level = 0
3180
    cpplint.ProcessFileData('foo.cc', 'cc',
3181
                            ['sum += MathUtil::SafeIntRound(x); x += 0.1;'],
3182
                            error_collector)
3183
    cpplint._cpplint_state.verbose_level = old_verbose_level
3184

    
3185
  def testEndOfNamespaceComments(self):
3186
    error_collector = ErrorCollector(self.assert_)
3187
    cpplint.ProcessFileData('foo.cc', 'cc',
3188
                            ['namespace {',
3189
                             '',
3190
                             '}',  # No warning (too short)
3191
                             'namespace expected {',
3192
                             '}  // namespace mismatched',  # Warning here
3193
                             'namespace {',
3194
                             '}  // namespace mismatched',  # Warning here
3195
                             'namespace outer { namespace nested {'] +
3196
                            ([''] * 10) +
3197
                            ['}',  # Warning here
3198
                             '}',  # Warning here
3199
                             'namespace {'] +
3200
                            ([''] * 10) +
3201
                            ['}',  # Warning here
3202
                             'namespace {'] +
3203
                            ([''] * 10) +
3204
                            ['}  // namespace some description',  # Anon warning
3205
                             'namespace {'] +
3206
                            ([''] * 10) +
3207
                            ['}  // namespace anonymous',  # Variant warning
3208
                             'namespace {'] +
3209
                            ([''] * 10) +
3210
                            ['}  // anonymous namespace (utils)',  # Variant
3211
                             'namespace {'] +
3212
                            ([''] * 10) +
3213
                            ['}  // anonymous namespace',  # No warning
3214
                             'namespace missing_comment {'] +
3215
                            ([''] * 10) +
3216
                            ['}',  # Warning here
3217
                             'namespace no_warning {'] +
3218
                            ([''] * 10) +
3219
                            ['}  // namespace no_warning',
3220
                             'namespace no_warning {'] +
3221
                            ([''] * 10) +
3222
                            ['};  // end namespace no_warning',
3223
                             '#define MACRO \\',
3224
                             'namespace c_style { \\'] +
3225
                            (['\\'] * 10) +
3226
                            ['}  /* namespace c_style. */ \\',
3227
                             ';'],
3228
                            error_collector)
3229
    self.assertEquals(1, error_collector.Results().count(
3230
        'Namespace should be terminated with "// namespace expected"'
3231
        '  [readability/namespace] [5]'))
3232
    self.assertEquals(1, error_collector.Results().count(
3233
        'Namespace should be terminated with "// namespace outer"'
3234
        '  [readability/namespace] [5]'))
3235
    self.assertEquals(1, error_collector.Results().count(
3236
        'Namespace should be terminated with "// namespace nested"'
3237
        '  [readability/namespace] [5]'))
3238
    self.assertEquals(3, error_collector.Results().count(
3239
        'Anonymous namespace should be terminated with "// namespace"'
3240
        '  [readability/namespace] [5]'))
3241
    self.assertEquals(2, error_collector.Results().count(
3242
        'Anonymous namespace should be terminated with "// namespace" or'
3243
        ' "// anonymous namespace"'
3244
        '  [readability/namespace] [5]'))
3245
    self.assertEquals(1, error_collector.Results().count(
3246
        'Namespace should be terminated with "// namespace missing_comment"'
3247
        '  [readability/namespace] [5]'))
3248
    self.assertEquals(0, error_collector.Results().count(
3249
        'Namespace should be terminated with "// namespace no_warning"'
3250
        '  [readability/namespace] [5]'))
3251

    
3252
  def testElseClauseNotOnSameLineAsElse(self):
3253
    self.TestLint('  else DoSomethingElse();',
3254
                  'Else clause should never be on same line as else '
3255
                  '(use 2 lines)  [whitespace/newline] [4]')
3256
    self.TestLint('  else ifDoSomethingElse();',
3257
                  'Else clause should never be on same line as else '
3258
                  '(use 2 lines)  [whitespace/newline] [4]')
3259
    self.TestLint('  } else if (blah) {', '')
3260
    self.TestLint('  variable_ends_in_else = true;', '')
3261

    
3262
  def testComma(self):
3263
    self.TestLint('a = f(1,2);',
3264
                  'Missing space after ,  [whitespace/comma] [3]')
3265
    self.TestLint('int tmp=a,a=b,b=tmp;',
3266
                  ['Missing spaces around =  [whitespace/operators] [4]',
3267
                   'Missing space after ,  [whitespace/comma] [3]'])
3268
    self.TestLint('f(a, /* name */ b);', '')
3269
    self.TestLint('f(a, /* name */b);', '')
3270
    self.TestLint('f(a, /* name */-1);', '')
3271
    self.TestLint('f(a, /* name */"1");', '')
3272
    self.TestLint('f(1, /* empty macro arg */, 2)', '')
3273
    self.TestLint('f(1,, 2)', '')
3274
    self.TestLint('operator,()', '')
3275
    self.TestLint('operator,(a,b)',
3276
                  'Missing space after ,  [whitespace/comma] [3]')
3277

    
3278
  def testEqualsOperatorSpacing(self):
3279
    self.TestLint('int tmp= a;',
3280
                  'Missing spaces around =  [whitespace/operators] [4]')
3281
    self.TestLint('int tmp =a;',
3282
                  'Missing spaces around =  [whitespace/operators] [4]')
3283
    self.TestLint('int tmp=a;',
3284
                  'Missing spaces around =  [whitespace/operators] [4]')
3285
    self.TestLint('int tmp= 7;',
3286
                  'Missing spaces around =  [whitespace/operators] [4]')
3287
    self.TestLint('int tmp =7;',
3288
                  'Missing spaces around =  [whitespace/operators] [4]')
3289
    self.TestLint('int tmp=7;',
3290
                  'Missing spaces around =  [whitespace/operators] [4]')
3291
    self.TestLint('int* tmp=*p;',
3292
                  'Missing spaces around =  [whitespace/operators] [4]')
3293
    self.TestLint('int* tmp= *p;',
3294
                  'Missing spaces around =  [whitespace/operators] [4]')
3295
    self.TestMultiLineLint(
3296
        TrimExtraIndent('''
3297
            lookahead_services_=
3298
              ::strings::Split(FLAGS_ls, ",", ::strings::SkipEmpty());'''),
3299
        'Missing spaces around =  [whitespace/operators] [4]')
3300
    self.TestLint('bool result = a>=42;',
3301
                  'Missing spaces around >=  [whitespace/operators] [3]')
3302
    self.TestLint('bool result = a<=42;',
3303
                  'Missing spaces around <=  [whitespace/operators] [3]')
3304
    self.TestLint('bool result = a==42;',
3305
                  'Missing spaces around ==  [whitespace/operators] [3]')
3306
    self.TestLint('auto result = a!=42;',
3307
                  'Missing spaces around !=  [whitespace/operators] [3]')
3308
    self.TestLint('int a = b!=c;',
3309
                  'Missing spaces around !=  [whitespace/operators] [3]')
3310
    self.TestLint('a&=42;', '')
3311
    self.TestLint('a|=42;', '')
3312
    self.TestLint('a^=42;', '')
3313
    self.TestLint('a+=42;', '')
3314
    self.TestLint('a*=42;', '')
3315
    self.TestLint('a/=42;', '')
3316
    self.TestLint('a%=42;', '')
3317
    self.TestLint('a>>=5;', '')
3318
    self.TestLint('a<<=5;', '')
3319

    
3320
  def testShiftOperatorSpacing(self):
3321
    self.TestLint('a<<b',
3322
                  'Missing spaces around <<  [whitespace/operators] [3]')
3323
    self.TestLint('a>>b',
3324
                  'Missing spaces around >>  [whitespace/operators] [3]')
3325
    self.TestLint('1<<20', '')
3326
    self.TestLint('1024>>10', '')
3327
    self.TestLint('Kernel<<<1, 2>>>()', '')
3328

    
3329
  def testIndent(self):
3330
    self.TestLint('static int noindent;', '')
3331
    self.TestLint('  int two_space_indent;', '')
3332
    self.TestLint('    int four_space_indent;', '')
3333
    self.TestLint(' int one_space_indent;',
3334
                  'Weird number of spaces at line-start.  '
3335
                  'Are you using a 2-space indent?  [whitespace/indent] [3]')
3336
    self.TestLint('   int three_space_indent;',
3337
                  'Weird number of spaces at line-start.  '
3338
                  'Are you using a 2-space indent?  [whitespace/indent] [3]')
3339
    self.TestLint(' char* one_space_indent = "public:";',
3340
                  'Weird number of spaces at line-start.  '
3341
                  'Are you using a 2-space indent?  [whitespace/indent] [3]')
3342
    self.TestLint(' public:', '')
3343
    self.TestLint('  protected:', '')
3344
    self.TestLint('   private:', '')
3345
    self.TestLint(' protected: \\', '')
3346
    self.TestLint('  public:      \\', '')
3347
    self.TestLint('   private:   \\', '')
3348
    self.TestMultiLineLint(
3349
        TrimExtraIndent("""
3350
            class foo {
3351
             public slots:
3352
              void bar();
3353
            };"""),
3354
        'Weird number of spaces at line-start.  '
3355
        'Are you using a 2-space indent?  [whitespace/indent] [3]')
3356
    self.TestMultiLineLint(
3357
        TrimExtraIndent('''
3358
            static const char kRawString[] = R"("
3359
             ")";'''),
3360
        '')
3361
    self.TestMultiLineLint(
3362
        TrimExtraIndent('''
3363
            static const char kNotRawString[] = "("
3364
             ")";'''),
3365
        'Weird number of spaces at line-start.  '
3366
        'Are you using a 2-space indent?  [whitespace/indent] [3]')
3367
    self.TestMultiLineLint(
3368
        ' static const char kSingleLineRawString[] = R"(...)";',
3369
        'Weird number of spaces at line-start.  '
3370
        'Are you using a 2-space indent?  [whitespace/indent] [3]')
3371

    
3372
  def testSectionIndent(self):
3373
    self.TestMultiLineLint(
3374
        """
3375
        class A {
3376
         public:  // no warning
3377
          private:  // warning here
3378
        };""",
3379
        'private: should be indented +1 space inside class A'
3380
        '  [whitespace/indent] [3]')
3381
    self.TestMultiLineLint(
3382
        """
3383
        class B {
3384
         public:  // no warning
3385
          template<> struct C {
3386
            public:    // warning here
3387
           protected:  // no warning
3388
          };
3389
        };""",
3390
        'public: should be indented +1 space inside struct C'
3391
        '  [whitespace/indent] [3]')
3392
    self.TestMultiLineLint(
3393
        """
3394
        struct D {
3395
         };""",
3396
        'Closing brace should be aligned with beginning of struct D'
3397
        '  [whitespace/indent] [3]')
3398
    self.TestMultiLineLint(
3399
        """
3400
         template<typename E> class F {
3401
        };""",
3402
        'Closing brace should be aligned with beginning of class F'
3403
        '  [whitespace/indent] [3]')
3404
    self.TestMultiLineLint(
3405
        """
3406
        class G {
3407
          Q_OBJECT
3408
        public slots:
3409
        signals:
3410
        };""",
3411
        ['public slots: should be indented +1 space inside class G'
3412
         '  [whitespace/indent] [3]',
3413
         'signals: should be indented +1 space inside class G'
3414
         '  [whitespace/indent] [3]'])
3415
    self.TestMultiLineLint(
3416
        """
3417
        class H {
3418
          /* comments */ class I {
3419
           public:  // no warning
3420
            private:  // warning here
3421
          };
3422
        };""",
3423
        'private: should be indented +1 space inside class I'
3424
        '  [whitespace/indent] [3]')
3425
    self.TestMultiLineLint(
3426
        """
3427
        class J
3428
            : public ::K {
3429
         public:  // no warning
3430
          protected:  // warning here
3431
        };""",
3432
        'protected: should be indented +1 space inside class J'
3433
        '  [whitespace/indent] [3]')
3434
    self.TestMultiLineLint(
3435
        """
3436
        class L
3437
            : public M,
3438
              public ::N {
3439
        };""",
3440
        '')
3441
    self.TestMultiLineLint(
3442
        """
3443
        template <class O,
3444
                  class P,
3445
                  class Q,
3446
                  typename R>
3447
        static void Func() {
3448
        }""",
3449
        '')
3450

    
3451
  def testConditionals(self):
3452
    self.TestMultiLineLint(
3453
        """
3454
        if (foo)
3455
          goto fail;
3456
          goto fail;""",
3457
        'If/else bodies with multiple statements require braces'
3458
        '  [readability/braces] [4]')
3459
    self.TestMultiLineLint(
3460
        """
3461
        if (foo)
3462
          goto fail; goto fail;""",
3463
        'If/else bodies with multiple statements require braces'
3464
        '  [readability/braces] [4]')
3465
    self.TestMultiLineLint(
3466
        """
3467
        if (foo)
3468
          foo;
3469
        else
3470
          goto fail;
3471
          goto fail;""",
3472
        'If/else bodies with multiple statements require braces'
3473
        '  [readability/braces] [4]')
3474
    self.TestMultiLineLint(
3475
        """
3476
        if (foo) goto fail;
3477
          goto fail;""",
3478
        'If/else bodies with multiple statements require braces'
3479
        '  [readability/braces] [4]')
3480
    self.TestMultiLineLint(
3481
        """
3482
        if (foo)
3483
          if (bar)
3484
            baz;
3485
          else
3486
            qux;""",
3487
        'Else clause should be indented at the same level as if. Ambiguous'
3488
        ' nested if/else chains require braces.  [readability/braces] [4]')
3489
    self.TestMultiLineLint(
3490
        """
3491
        if (foo)
3492
          if (bar)
3493
            baz;
3494
        else
3495
          qux;""",
3496
        'Else clause should be indented at the same level as if. Ambiguous'
3497
        ' nested if/else chains require braces.  [readability/braces] [4]')
3498
    self.TestMultiLineLint(
3499
        """
3500
        if (foo) {
3501
          bar;
3502
          baz;
3503
        } else
3504
          qux;""",
3505
        'If an else has a brace on one side, it should have it on both'
3506
        '  [readability/braces] [5]')
3507
    self.TestMultiLineLint(
3508
        """
3509
        if (foo)
3510
          bar;
3511
        else {
3512
          baz;
3513
        }""",
3514
        'If an else has a brace on one side, it should have it on both'
3515
        '  [readability/braces] [5]')
3516
    self.TestMultiLineLint(
3517
        """
3518
        if (foo)
3519
          bar;
3520
        else if (baz) {
3521
          qux;
3522
        }""",
3523
        'If an else has a brace on one side, it should have it on both'
3524
        '  [readability/braces] [5]')
3525
    self.TestMultiLineLint(
3526
        """
3527
        if (foo) {
3528
          bar;
3529
        } else if (baz)
3530
          qux;""",
3531
        'If an else has a brace on one side, it should have it on both'
3532
        '  [readability/braces] [5]')
3533
    self.TestMultiLineLint(
3534
        """
3535
        if (foo)
3536
          goto fail;
3537
        bar;""",
3538
        '')
3539
    self.TestMultiLineLint(
3540
        """
3541
        if (foo
3542
            && bar) {
3543
          baz;
3544
          qux;
3545
        }""",
3546
        '')
3547
    self.TestMultiLineLint(
3548
        """
3549
        if (foo)
3550
          goto
3551
            fail;""",
3552
        '')
3553
    self.TestMultiLineLint(
3554
        """
3555
        if (foo)
3556
          bar;
3557
        else
3558
          baz;
3559
        qux;""",
3560
        '')
3561
    self.TestMultiLineLint(
3562
        """
3563
        for (;;) {
3564
          if (foo)
3565
            bar;
3566
          else
3567
            baz;
3568
        }""",
3569
        '')
3570
    self.TestMultiLineLint(
3571
        """
3572
        if (foo)
3573
          bar;
3574
        else if (baz)
3575
          baz;""",
3576
        '')
3577
    self.TestMultiLineLint(
3578
        """
3579
        if (foo)
3580
          bar;
3581
        else
3582
          baz;""",
3583
        '')
3584
    self.TestMultiLineLint(
3585
        """
3586
        if (foo) {
3587
          bar;
3588
        } else {
3589
          baz;
3590
        }""",
3591
        '')
3592
    self.TestMultiLineLint(
3593
        """
3594
        if (foo) {
3595
          bar;
3596
        } else if (baz) {
3597
          qux;
3598
        }""",
3599
        '')
3600
    # Note: this is an error for a different reason, but should not trigger the
3601
    # single-line if error.
3602
    self.TestMultiLineLint(
3603
        """
3604
        if (foo)
3605
        {
3606
          bar;
3607
          baz;
3608
        }""",
3609
        '{ should almost always be at the end of the previous line'
3610
        '  [whitespace/braces] [4]')
3611
    self.TestMultiLineLint(
3612
        """
3613
        if (foo) { \\
3614
          bar; \\
3615
          baz; \\
3616
        }""",
3617
        '')
3618
    self.TestMultiLineLint(
3619
        """
3620
        void foo() { if (bar) baz; }""",
3621
        '')
3622
    self.TestMultiLineLint(
3623
        """
3624
        #if foo
3625
          bar;
3626
        #else
3627
          baz;
3628
          qux;
3629
        #endif""",
3630
        '')
3631
    self.TestMultiLineLint(
3632
        """void F() {
3633
          variable = [] { if (true); };
3634
          variable =
3635
              [] { if (true); };
3636
          Call(
3637
              [] { if (true); },
3638
              [] { if (true); });
3639
        }""",
3640
        '')
3641

    
3642
  def testTab(self):
3643
    self.TestLint('\tint a;',
3644
                  'Tab found; better to use spaces  [whitespace/tab] [1]')
3645
    self.TestLint('int a = 5;\t\t// set a to 5',
3646
                  'Tab found; better to use spaces  [whitespace/tab] [1]')
3647

    
3648
  def testParseArguments(self):
3649
    old_usage = cpplint._USAGE
3650
    old_error_categories = cpplint._ERROR_CATEGORIES
3651
    old_output_format = cpplint._cpplint_state.output_format
3652
    old_verbose_level = cpplint._cpplint_state.verbose_level
3653
    old_filters = cpplint._cpplint_state.filters
3654
    old_line_length = cpplint._line_length
3655
    old_valid_extensions = cpplint._valid_extensions
3656
    try:
3657
      # Don't print usage during the tests, or filter categories
3658
      cpplint._USAGE = ''
3659
      cpplint._ERROR_CATEGORIES = ''
3660

    
3661
      self.assertRaises(SystemExit, cpplint.ParseArguments, [])
3662
      self.assertRaises(SystemExit, cpplint.ParseArguments, ['--badopt'])
3663
      self.assertRaises(SystemExit, cpplint.ParseArguments, ['--help'])
3664
      self.assertRaises(SystemExit, cpplint.ParseArguments, ['--v=0'])
3665
      self.assertRaises(SystemExit, cpplint.ParseArguments, ['--filter='])
3666
      # This is illegal because all filters must start with + or -
3667
      self.assertRaises(SystemExit, cpplint.ParseArguments, ['--filter=foo'])
3668
      self.assertRaises(SystemExit, cpplint.ParseArguments,
3669
                        ['--filter=+a,b,-c'])
3670

    
3671
      self.assertEquals(['foo.cc'], cpplint.ParseArguments(['foo.cc']))
3672
      self.assertEquals(old_output_format, cpplint._cpplint_state.output_format)
3673
      self.assertEquals(old_verbose_level, cpplint._cpplint_state.verbose_level)
3674

    
3675
      self.assertEquals(['foo.cc'],
3676
                        cpplint.ParseArguments(['--v=1', 'foo.cc']))
3677
      self.assertEquals(1, cpplint._cpplint_state.verbose_level)
3678
      self.assertEquals(['foo.h'],
3679
                        cpplint.ParseArguments(['--v=3', 'foo.h']))
3680
      self.assertEquals(3, cpplint._cpplint_state.verbose_level)
3681
      self.assertEquals(['foo.cpp'],
3682
                        cpplint.ParseArguments(['--verbose=5', 'foo.cpp']))
3683
      self.assertEquals(5, cpplint._cpplint_state.verbose_level)
3684
      self.assertRaises(ValueError,
3685
                        cpplint.ParseArguments, ['--v=f', 'foo.cc'])
3686

    
3687
      self.assertEquals(['foo.cc'],
3688
                        cpplint.ParseArguments(['--output=emacs', 'foo.cc']))
3689
      self.assertEquals('emacs', cpplint._cpplint_state.output_format)
3690
      self.assertEquals(['foo.h'],
3691
                        cpplint.ParseArguments(['--output=vs7', 'foo.h']))
3692
      self.assertEquals('vs7', cpplint._cpplint_state.output_format)
3693
      self.assertRaises(SystemExit,
3694
                        cpplint.ParseArguments, ['--output=blah', 'foo.cc'])
3695

    
3696
      filt = '-,+whitespace,-whitespace/indent'
3697
      self.assertEquals(['foo.h'],
3698
                        cpplint.ParseArguments(['--filter='+filt, 'foo.h']))
3699
      self.assertEquals(['-', '+whitespace', '-whitespace/indent'],
3700
                        cpplint._cpplint_state.filters)
3701

    
3702
      self.assertEquals(['foo.cc', 'foo.h'],
3703
                        cpplint.ParseArguments(['foo.cc', 'foo.h']))
3704

    
3705
      self.assertEqual(['foo.h'],
3706
                       cpplint.ParseArguments(['--linelength=120', 'foo.h']))
3707
      self.assertEqual(120, cpplint._line_length)
3708

    
3709
      self.assertEqual(['foo.h'],
3710
                       cpplint.ParseArguments(['--extensions=hpp,cpp,cpp', 'foo.h']))
3711
      self.assertEqual(set(['hpp', 'cpp']), cpplint._valid_extensions)
3712
    finally:
3713
      cpplint._USAGE = old_usage
3714
      cpplint._ERROR_CATEGORIES = old_error_categories
3715
      cpplint._cpplint_state.output_format = old_output_format
3716
      cpplint._cpplint_state.verbose_level = old_verbose_level
3717
      cpplint._cpplint_state.filters = old_filters
3718
      cpplint._line_length = old_line_length
3719
      cpplint._valid_extensions = old_valid_extensions
3720

    
3721
  def testLineLength(self):
3722
    old_line_length = cpplint._line_length
3723
    try:
3724
      cpplint._line_length = 80
3725
      self.TestLint(
3726
          '// %s' % ('H' * 77),
3727
          '')
3728
      self.TestLint(
3729
          '// %s' % ('H' * 78),
3730
          'Lines should be <= 80 characters long'
3731
          '  [whitespace/line_length] [2]')
3732
      cpplint._line_length = 120
3733
      self.TestLint(
3734
          '// %s' % ('H' * 117),
3735
          '')
3736
      self.TestLint(
3737
          '// %s' % ('H' * 118),
3738
          'Lines should be <= 120 characters long'
3739
          '  [whitespace/line_length] [2]')
3740
    finally:
3741
      cpplint._line_length = old_line_length
3742

    
3743
  def testFilter(self):
3744
    old_filters = cpplint._cpplint_state.filters
3745
    try:
3746
      cpplint._cpplint_state.SetFilters('-,+whitespace,-whitespace/indent')
3747
      self.TestLint(
3748
          '// Hello there ',
3749
          'Line ends in whitespace.  Consider deleting these extra spaces.'
3750
          '  [whitespace/end_of_line] [4]')
3751
      self.TestLint('int a = (int)1.0;', '')
3752
      self.TestLint(' weird opening space', '')
3753
    finally:
3754
      cpplint._cpplint_state.filters = old_filters
3755

    
3756
  def testDefaultFilter(self):
3757
    default_filters = cpplint._DEFAULT_FILTERS
3758
    old_filters = cpplint._cpplint_state.filters
3759
    cpplint._DEFAULT_FILTERS = ['-whitespace']
3760
    try:
3761
      # Reset filters
3762
      cpplint._cpplint_state.SetFilters('')
3763
      self.TestLint('// Hello there ', '')
3764
      cpplint._cpplint_state.SetFilters('+whitespace/end_of_line')
3765
      self.TestLint(
3766
          '// Hello there ',
3767
          'Line ends in whitespace.  Consider deleting these extra spaces.'
3768
          '  [whitespace/end_of_line] [4]')
3769
      self.TestLint(' weird opening space', '')
3770
    finally:
3771
      cpplint._cpplint_state.filters = old_filters
3772
      cpplint._DEFAULT_FILTERS = default_filters
3773

    
3774
  def testDuplicateHeader(self):
3775
    error_collector = ErrorCollector(self.assert_)
3776
    cpplint.ProcessFileData('path/self.cc', 'cc',
3777
                            ['// Copyright 2014 Your Company. All Rights Reserved.',
3778
                             '#include "path/self.h"',
3779
                             '#include "path/duplicate.h"',
3780
                             '#include "path/duplicate.h"',
3781
                             '#ifdef MACRO',
3782
                             '#include "path/unique.h"',
3783
                             '#else',
3784
                             '#include "path/unique.h"',
3785
                             '#endif',
3786
                             ''],
3787
                            error_collector)
3788
    self.assertEquals(
3789
        ['"path/duplicate.h" already included at path/self.cc:3  '
3790
         '[build/include] [4]'],
3791
        error_collector.ResultList())
3792

    
3793
  def testUnnamedNamespacesInHeaders(self):
3794
    self.TestLanguageRulesCheck(
3795
        'foo.h', 'namespace {',
3796
        'Do not use unnamed namespaces in header files.  See'
3797
        ' http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Namespaces'
3798
        ' for more information.  [build/namespaces] [4]')
3799
    # namespace registration macros are OK.
3800
    self.TestLanguageRulesCheck('foo.h', 'namespace {  \\', '')
3801
    # named namespaces are OK.
3802
    self.TestLanguageRulesCheck('foo.h', 'namespace foo {', '')
3803
    self.TestLanguageRulesCheck('foo.h', 'namespace foonamespace {', '')
3804
    self.TestLanguageRulesCheck('foo.cc', 'namespace {', '')
3805
    self.TestLanguageRulesCheck('foo.cc', 'namespace foo {', '')
3806

    
3807
  def testBuildClass(self):
3808
    # Test that the linter can parse to the end of class definitions,
3809
    # and that it will report when it can't.
3810
    # Use multi-line linter because it performs the ClassState check.
3811
    self.TestMultiLineLint(
3812
        'class Foo {',
3813
        'Failed to find complete declaration of class Foo'
3814
        '  [build/class] [5]')
3815
    # Do the same for namespaces
3816
    self.TestMultiLineLint(
3817
        'namespace Foo {',
3818
        'Failed to find complete declaration of namespace Foo'
3819
        '  [build/namespaces] [5]')
3820
    # Don't warn on forward declarations of various types.
3821
    self.TestMultiLineLint(
3822
        'class Foo;',
3823
        '')
3824
    self.TestMultiLineLint(
3825
        """struct Foo*
3826
             foo = NewFoo();""",
3827
        '')
3828
    # Test preprocessor.
3829
    self.TestMultiLineLint(
3830
        """#ifdef DERIVE_FROM_GOO
3831
          struct Foo : public Goo {
3832
        #else
3833
          struct Foo : public Hoo {
3834
        #endif
3835
          };""",
3836
        '')
3837
    self.TestMultiLineLint(
3838
        """
3839
        class Foo
3840
        #ifdef DERIVE_FROM_GOO
3841
          : public Goo {
3842
        #else
3843
          : public Hoo {
3844
        #endif
3845
        };""",
3846
        '')
3847
    # Test incomplete class
3848
    self.TestMultiLineLint(
3849
        'class Foo {',
3850
        'Failed to find complete declaration of class Foo'
3851
        '  [build/class] [5]')
3852

    
3853
  def testBuildEndComment(self):
3854
    # The crosstool compiler we currently use will fail to compile the
3855
    # code in this test, so we might consider removing the lint check.
3856
    self.TestMultiLineLint(
3857
        """#if 0
3858
        #endif Not a comment""",
3859
        'Uncommented text after #endif is non-standard.  Use a comment.'
3860
        '  [build/endif_comment] [5]')
3861

    
3862
  def testBuildForwardDecl(self):
3863
    # The crosstool compiler we currently use will fail to compile the
3864
    # code in this test, so we might consider removing the lint check.
3865
    self.TestLint('class Foo::Goo;',
3866
                  'Inner-style forward declarations are invalid.'
3867
                  '  Remove this line.'
3868
                  '  [build/forward_decl] [5]')
3869

    
3870
  def GetBuildHeaderGuardPreprocessorSymbol(self, file_path):
3871
    # Figure out the expected header guard by processing an empty file.
3872
    error_collector = ErrorCollector(self.assert_)
3873
    cpplint.ProcessFileData(file_path, 'h', [], error_collector)
3874
    for error in error_collector.ResultList():
3875
      matched = re.search(
3876
          'No #ifndef header guard found, suggested CPP variable is: ([A-Z_]+)',
3877
          error)
3878
      if matched is not None:
3879
        return matched.group(1)
3880

    
3881
  def testBuildHeaderGuard(self):
3882
    file_path = 'mydir/foo.h'
3883
    expected_guard = self.GetBuildHeaderGuardPreprocessorSymbol(file_path)
3884
    self.assertTrue(re.search('MYDIR_FOO_H_$', expected_guard))
3885

    
3886
    # No guard at all: expect one error.
3887
    error_collector = ErrorCollector(self.assert_)
3888
    cpplint.ProcessFileData(file_path, 'h', [], error_collector)
3889
    self.assertEquals(
3890
        1,
3891
        error_collector.ResultList().count(
3892
            'No #ifndef header guard found, suggested CPP variable is: %s'
3893
            '  [build/header_guard] [5]' % expected_guard),
3894
        error_collector.ResultList())
3895

    
3896
    # No header guard, but the error is suppressed.
3897
    error_collector = ErrorCollector(self.assert_)
3898
    cpplint.ProcessFileData(file_path, 'h',
3899
                            ['// Copyright 2014 Your Company.',
3900
                             '// NOLINT(build/header_guard)', ''],
3901
                            error_collector)
3902
    self.assertEquals([], error_collector.ResultList())
3903

    
3904
    # Wrong guard
3905
    error_collector = ErrorCollector(self.assert_)
3906
    cpplint.ProcessFileData(file_path, 'h',
3907
                            ['#ifndef FOO_H', '#define FOO_H'], error_collector)
3908
    self.assertEquals(
3909
        1,
3910
        error_collector.ResultList().count(
3911
            '#ifndef header guard has wrong style, please use: %s'
3912
            '  [build/header_guard] [5]' % expected_guard),
3913
        error_collector.ResultList())
3914

    
3915
    # No define
3916
    error_collector = ErrorCollector(self.assert_)
3917
    cpplint.ProcessFileData(file_path, 'h',
3918
                            ['#ifndef %s' % expected_guard], error_collector)
3919
    self.assertEquals(
3920
        1,
3921
        error_collector.ResultList().count(
3922
            'No #ifndef header guard found, suggested CPP variable is: %s'
3923
            '  [build/header_guard] [5]' % expected_guard),
3924
        error_collector.ResultList())
3925

    
3926
    # Mismatched define
3927
    error_collector = ErrorCollector(self.assert_)
3928
    cpplint.ProcessFileData(file_path, 'h',
3929
                            ['#ifndef %s' % expected_guard,
3930
                             '#define FOO_H'],
3931
                            error_collector)
3932
    self.assertEquals(
3933
        1,
3934
        error_collector.ResultList().count(
3935
            'No #ifndef header guard found, suggested CPP variable is: %s'
3936
            '  [build/header_guard] [5]' % expected_guard),
3937
        error_collector.ResultList())
3938

    
3939
    # No endif
3940
    error_collector = ErrorCollector(self.assert_)
3941
    cpplint.ProcessFileData(file_path, 'h',
3942
                            ['#ifndef %s' % expected_guard,
3943
                             '#define %s' % expected_guard,
3944
                             ''],
3945
                            error_collector)
3946
    self.assertEquals(
3947
        1,
3948
        error_collector.ResultList().count(
3949
            '#endif line should be "#endif  // %s"'
3950
            '  [build/header_guard] [5]' % expected_guard),
3951
        error_collector.ResultList())
3952

    
3953
    # Commentless endif
3954
    error_collector = ErrorCollector(self.assert_)
3955
    cpplint.ProcessFileData(file_path, 'h',
3956
                            ['#ifndef %s' % expected_guard,
3957
                             '#define %s' % expected_guard,
3958
                             '#endif'],
3959
                            error_collector)
3960
    self.assertEquals(
3961
        1,
3962
        error_collector.ResultList().count(
3963
            '#endif line should be "#endif  // %s"'
3964
            '  [build/header_guard] [5]' % expected_guard),
3965
        error_collector.ResultList())
3966

    
3967
    # Commentless endif for old-style guard
3968
    error_collector = ErrorCollector(self.assert_)
3969
    cpplint.ProcessFileData(file_path, 'h',
3970
                            ['#ifndef %s_' % expected_guard,
3971
                             '#define %s_' % expected_guard,
3972
                             '#endif'],
3973
                            error_collector)
3974
    self.assertEquals(
3975
        1,
3976
        error_collector.ResultList().count(
3977
            '#endif line should be "#endif  // %s"'
3978
            '  [build/header_guard] [5]' % expected_guard),
3979
        error_collector.ResultList())
3980

    
3981
    # No header guard errors
3982
    error_collector = ErrorCollector(self.assert_)
3983
    cpplint.ProcessFileData(file_path, 'h',
3984
                            ['#ifndef %s' % expected_guard,
3985
                             '#define %s' % expected_guard,
3986
                             '#endif  // %s' % expected_guard],
3987
                            error_collector)
3988
    for line in error_collector.ResultList():
3989
      if line.find('build/header_guard') != -1:
3990
        self.fail('Unexpected error: %s' % line)
3991

    
3992
    # No header guard errors for old-style guard
3993
    error_collector = ErrorCollector(self.assert_)
3994
    cpplint.ProcessFileData(file_path, 'h',
3995
                            ['#ifndef %s_' % expected_guard,
3996
                             '#define %s_' % expected_guard,
3997
                             '#endif  // %s_' % expected_guard],
3998
                            error_collector)
3999
    for line in error_collector.ResultList():
4000
      if line.find('build/header_guard') != -1:
4001
        self.fail('Unexpected error: %s' % line)
4002

    
4003
    old_verbose_level = cpplint._cpplint_state.verbose_level
4004
    try:
4005
      cpplint._cpplint_state.verbose_level = 0
4006
      # Warn on old-style guard if verbosity is 0.
4007
      error_collector = ErrorCollector(self.assert_)
4008
      cpplint.ProcessFileData(file_path, 'h',
4009
                              ['#ifndef %s_' % expected_guard,
4010
                               '#define %s_' % expected_guard,
4011
                               '#endif  // %s_' % expected_guard],
4012
                              error_collector)
4013
      self.assertEquals(
4014
          1,
4015
          error_collector.ResultList().count(
4016
              '#ifndef header guard has wrong style, please use: %s'
4017
              '  [build/header_guard] [0]' % expected_guard),
4018
          error_collector.ResultList())
4019
    finally:
4020
      cpplint._cpplint_state.verbose_level = old_verbose_level
4021

    
4022
    # Completely incorrect header guard
4023
    error_collector = ErrorCollector(self.assert_)
4024
    cpplint.ProcessFileData(file_path, 'h',
4025
                            ['#ifndef FOO',
4026
                             '#define FOO',
4027
                             '#endif  // FOO'],
4028
                            error_collector)
4029
    self.assertEquals(
4030
        1,
4031
        error_collector.ResultList().count(
4032
            '#ifndef header guard has wrong style, please use: %s'
4033
            '  [build/header_guard] [5]' % expected_guard),
4034
        error_collector.ResultList())
4035
    self.assertEquals(
4036
        1,
4037
        error_collector.ResultList().count(
4038
            '#endif line should be "#endif  // %s"'
4039
            '  [build/header_guard] [5]' % expected_guard),
4040
        error_collector.ResultList())
4041

    
4042
    # incorrect header guard with nolint
4043
    error_collector = ErrorCollector(self.assert_)
4044
    cpplint.ProcessFileData(file_path, 'h',
4045
                            ['#ifndef FOO  // NOLINT',
4046
                             '#define FOO',
4047
                             '#endif  // FOO NOLINT'],
4048
                            error_collector)
4049
    self.assertEquals(
4050
        0,
4051
        error_collector.ResultList().count(
4052
            '#ifndef header guard has wrong style, please use: %s'
4053
            '  [build/header_guard] [5]' % expected_guard),
4054
        error_collector.ResultList())
4055
    self.assertEquals(
4056
        0,
4057
        error_collector.ResultList().count(
4058
            '#endif line should be "#endif  // %s"'
4059
            '  [build/header_guard] [5]' % expected_guard),
4060
        error_collector.ResultList())
4061

    
4062
    # Special case for flymake
4063
    for test_file in ['mydir/foo_flymake.h', 'mydir/.flymake/foo.h']:
4064
      error_collector = ErrorCollector(self.assert_)
4065
      cpplint.ProcessFileData(test_file, 'h',
4066
                              ['// Copyright 2014 Your Company.', ''],
4067
                              error_collector)
4068
      self.assertEquals(
4069
          1,
4070
          error_collector.ResultList().count(
4071
              'No #ifndef header guard found, suggested CPP variable is: %s'
4072
              '  [build/header_guard] [5]' % expected_guard),
4073
          error_collector.ResultList())
4074

    
4075
  def testBuildHeaderGuardWithRoot(self):
4076
    file_path = os.path.join(os.path.dirname(os.path.abspath(__file__)),
4077
                             'cpplint_test_header.h')
4078
    file_info = cpplint.FileInfo(file_path)
4079
    if file_info.FullName() == file_info.RepositoryName():
4080
      # When FileInfo cannot deduce the root directory of the repository,
4081
      # FileInfo.RepositoryName returns the same value as FileInfo.FullName.
4082
      # This can happen when this source file was obtained without .svn or
4083
      # .git directory. (e.g. using 'svn export' or 'git archive').
4084
      # Skip this test in such a case because --root flag makes sense only
4085
      # when the root directory of the repository is properly deduced.
4086
      return
4087

    
4088
    self.assertEquals('CPPLINT_CPPLINT_TEST_HEADER_H_',
4089
                      cpplint.GetHeaderGuardCPPVariable(file_path))
4090
    cpplint._root = 'cpplint'
4091
    self.assertEquals('CPPLINT_TEST_HEADER_H_',
4092
                      cpplint.GetHeaderGuardCPPVariable(file_path))
4093
    # --root flag is ignored if an non-existent directory is specified.
4094
    cpplint._root = 'NON_EXISTENT_DIR'
4095
    self.assertEquals('CPPLINT_CPPLINT_TEST_HEADER_H_',
4096
                      cpplint.GetHeaderGuardCPPVariable(file_path))
4097

    
4098
  def testBuildInclude(self):
4099
    # Test that include statements have slashes in them.
4100
    self.TestLint('#include "foo.h"',
4101
                  'Include the directory when naming .h files'
4102
                  '  [build/include] [4]')
4103
    self.TestLint('#include "Python.h"', '')
4104
    self.TestLint('#include "lua.h"', '')
4105

    
4106
  def testBuildPrintfFormat(self):
4107
    error_collector = ErrorCollector(self.assert_)
4108
    cpplint.ProcessFileData(
4109
        'foo.cc', 'cc',
4110
        [r'printf("\%%d", value);',
4111
         r'snprintf(buffer, sizeof(buffer), "\[%d", value);',
4112
         r'fprintf(file, "\(%d", value);',
4113
         r'vsnprintf(buffer, sizeof(buffer), "\\\{%d", ap);'],
4114
        error_collector)
4115
    self.assertEquals(
4116
        4,
4117
        error_collector.Results().count(
4118
            '%, [, (, and { are undefined character escapes.  Unescape them.'
4119
            '  [build/printf_format] [3]'))
4120

    
4121
    error_collector = ErrorCollector(self.assert_)
4122
    cpplint.ProcessFileData(
4123
        'foo.cc', 'cc',
4124
        ['// Copyright 2014 Your Company.',
4125
         r'printf("\\%%%d", value);',
4126
         r'printf(R"(\[)");',
4127
         r'printf(R"(\[%s)", R"(\])");',
4128
         ''],
4129
        error_collector)
4130
    self.assertEquals('', error_collector.Results())
4131

    
4132
  def testRuntimePrintfFormat(self):
4133
    self.TestLint(
4134
        r'fprintf(file, "%q", value);',
4135
        '%q in format strings is deprecated.  Use %ll instead.'
4136
        '  [runtime/printf_format] [3]')
4137

    
4138
    self.TestLint(
4139
        r'aprintf(file, "The number is %12q", value);',
4140
        '%q in format strings is deprecated.  Use %ll instead.'
4141
        '  [runtime/printf_format] [3]')
4142

    
4143
    self.TestLint(
4144
        r'printf(file, "The number is" "%-12q", value);',
4145
        '%q in format strings is deprecated.  Use %ll instead.'
4146
        '  [runtime/printf_format] [3]')
4147

    
4148
    self.TestLint(
4149
        r'printf(file, "The number is" "%+12q", value);',
4150
        '%q in format strings is deprecated.  Use %ll instead.'
4151
        '  [runtime/printf_format] [3]')
4152

    
4153
    self.TestLint(
4154
        r'printf(file, "The number is" "% 12q", value);',
4155
        '%q in format strings is deprecated.  Use %ll instead.'
4156
        '  [runtime/printf_format] [3]')
4157

    
4158
    self.TestLint(
4159
        r'snprintf(file, "Never mix %d and %1$d parameters!", value);',
4160
        '%N$ formats are unconventional.  Try rewriting to avoid them.'
4161
        '  [runtime/printf_format] [2]')
4162

    
4163
  def TestLintLogCodeOnError(self, code, expected_message):
4164
    # Special TestLint which logs the input code on error.
4165
    result = self.PerformSingleLineLint(code)
4166
    if result != expected_message:
4167
      self.fail('For code: "%s"\nGot: "%s"\nExpected: "%s"'
4168
                % (code, result, expected_message))
4169

    
4170
  def testBuildStorageClass(self):
4171
    qualifiers = [None, 'const', 'volatile']
4172
    signs = [None, 'signed', 'unsigned']
4173
    types = ['void', 'char', 'int', 'float', 'double',
4174
             'schar', 'int8', 'uint8', 'int16', 'uint16',
4175
             'int32', 'uint32', 'int64', 'uint64']
4176
    storage_classes = ['extern', 'register', 'static', 'typedef']
4177

    
4178
    build_storage_class_error_message = (
4179
        'Storage class (static, extern, typedef, etc) should be first.'
4180
        '  [build/storage_class] [5]')
4181

    
4182
    # Some explicit cases. Legal in C++, deprecated in C99.
4183
    self.TestLint('const int static foo = 5;',
4184
                  build_storage_class_error_message)
4185

    
4186
    self.TestLint('char static foo;',
4187
                  build_storage_class_error_message)
4188

    
4189
    self.TestLint('double const static foo = 2.0;',
4190
                  build_storage_class_error_message)
4191

    
4192
    self.TestLint('uint64 typedef unsigned_long_long;',
4193
                  build_storage_class_error_message)
4194

    
4195
    self.TestLint('int register foo = 0;',
4196
                  build_storage_class_error_message)
4197

    
4198
    # Since there are a very large number of possibilities, randomly
4199
    # construct declarations.
4200
    # Make sure that the declaration is logged if there's an error.
4201
    # Seed generator with an integer for absolute reproducibility.
4202
    random.seed(25)
4203
    for unused_i in range(10):
4204
      # Build up random list of non-storage-class declaration specs.
4205
      other_decl_specs = [random.choice(qualifiers), random.choice(signs),
4206
                          random.choice(types)]
4207
      # remove None
4208
      other_decl_specs = [x for x in other_decl_specs if x is not None]
4209

    
4210
      # shuffle
4211
      random.shuffle(other_decl_specs)
4212

    
4213
      # insert storage class after the first
4214
      storage_class = random.choice(storage_classes)
4215
      insertion_point = random.randint(1, len(other_decl_specs))
4216
      decl_specs = (other_decl_specs[0:insertion_point]
4217
                    + [storage_class]
4218
                    + other_decl_specs[insertion_point:])
4219

    
4220
      self.TestLintLogCodeOnError(
4221
          ' '.join(decl_specs) + ';',
4222
          build_storage_class_error_message)
4223

    
4224
      # but no error if storage class is first
4225
      self.TestLintLogCodeOnError(
4226
          storage_class + ' ' + ' '.join(other_decl_specs),
4227
          '')
4228

    
4229
  def testLegalCopyright(self):
4230
    legal_copyright_message = (
4231
        'No copyright message found.  '
4232
        'You should have a line: "Copyright [year] <Copyright Owner>"'
4233
        '  [legal/copyright] [5]')
4234

    
4235
    copyright_line = '// Copyright 2014 Google Inc. All Rights Reserved.'
4236

    
4237
    file_path = 'mydir/googleclient/foo.cc'
4238

    
4239
    # There should be a copyright message in the first 10 lines
4240
    error_collector = ErrorCollector(self.assert_)
4241
    cpplint.ProcessFileData(file_path, 'cc', [], error_collector)
4242
    self.assertEquals(
4243
        1,
4244
        error_collector.ResultList().count(legal_copyright_message))
4245

    
4246
    error_collector = ErrorCollector(self.assert_)
4247
    cpplint.ProcessFileData(
4248
        file_path, 'cc',
4249
        ['' for unused_i in range(10)] + [copyright_line],
4250
        error_collector)
4251
    self.assertEquals(
4252
        1,
4253
        error_collector.ResultList().count(legal_copyright_message))
4254

    
4255
    # Test that warning isn't issued if Copyright line appears early enough.
4256
    error_collector = ErrorCollector(self.assert_)
4257
    cpplint.ProcessFileData(file_path, 'cc', [copyright_line], error_collector)
4258
    for message in error_collector.ResultList():
4259
      if message.find('legal/copyright') != -1:
4260
        self.fail('Unexpected error: %s' % message)
4261

    
4262
    error_collector = ErrorCollector(self.assert_)
4263
    cpplint.ProcessFileData(
4264
        file_path, 'cc',
4265
        ['' for unused_i in range(9)] + [copyright_line],
4266
        error_collector)
4267
    for message in error_collector.ResultList():
4268
      if message.find('legal/copyright') != -1:
4269
        self.fail('Unexpected error: %s' % message)
4270

    
4271
  def testInvalidIncrement(self):
4272
    self.TestLint('*count++;',
4273
                  'Changing pointer instead of value (or unused value of '
4274
                  'operator*).  [runtime/invalid_increment] [5]')
4275

    
4276
  def testSnprintfSize(self):
4277
    self.TestLint('vsnprintf(NULL, 0, format)', '')
4278
    self.TestLint('snprintf(fisk, 1, format)',
4279
                  'If you can, use sizeof(fisk) instead of 1 as the 2nd arg '
4280
                  'to snprintf.  [runtime/printf] [3]')
4281
class Cxx11Test(CpplintTestBase):
4282

    
4283
  def Helper(self, package, extension, lines, count):
4284
    filename = package + '/foo.' + extension
4285
    lines = lines[:]
4286

    
4287
    # Header files need to have an ifdef guard wrapped around their code.
4288
    if extension == 'h':
4289
      guard = filename.upper().replace('/', '_').replace('.', '_') + '_'
4290
      lines.insert(0, '#ifndef ' + guard)
4291
      lines.insert(1, '#define ' + guard)
4292
      lines.append('#endif  // ' + guard)
4293

    
4294
    # All files need a final blank line.
4295
    lines.append('')
4296

    
4297
    # Process the file and check resulting error count.
4298
    collector = ErrorCollector(self.assert_)
4299
    cpplint.ProcessFileData(filename, extension, lines, collector)
4300
    error_list = collector.ResultList()
4301
    self.assertEquals(count, len(error_list), error_list)
4302

    
4303
  def TestCxx11Feature(self, code, expected_error):
4304
    lines = code.split('\n')
4305
    collector = ErrorCollector(self.assert_)
4306
    cpplint.RemoveMultiLineComments('foo.h', lines, collector)
4307
    clean_lines = cpplint.CleansedLines(lines)
4308
    cpplint.FlagCxx11Features('foo.cc', clean_lines, 0, collector)
4309
    self.assertEquals(expected_error, collector.Results())
4310

    
4311
  def testBlockedHeaders(self):
4312
    self.TestCxx11Feature('#include <mutex>',
4313
                          '<mutex> is an unapproved C++11 header.'
4314
                          '  [build/c++11] [5]')
4315

    
4316
  def testBlockedClasses(self):
4317
    self.TestCxx11Feature('std::alignment_of<T>',
4318
                          'std::alignment_of is an unapproved '
4319
                          'C++11 class or function.  Send c-style an example '
4320
                          'of where it would make your code more readable, '
4321
                          'and they may let you use it.'
4322
                          '  [build/c++11] [5]')
4323
    self.TestCxx11Feature('std::alignment_offer', '')
4324
    self.TestCxx11Feature('mystd::alignment_of', '')
4325
    self.TestCxx11Feature('std::binomial_distribution', '')
4326

    
4327
  def testBlockedFunctions(self):
4328
    self.TestCxx11Feature('std::alignment_of<int>',
4329
                          'std::alignment_of is an unapproved '
4330
                          'C++11 class or function.  Send c-style an example '
4331
                          'of where it would make your code more readable, '
4332
                          'and they may let you use it.'
4333
                          '  [build/c++11] [5]')
4334
    # Missed because of the lack of "std::".  Compiles because ADL
4335
    # looks in the namespace of my_shared_ptr, which (presumably) is
4336
    # std::.  But there will be a lint error somewhere in this file
4337
    # since my_shared_ptr had to be defined.
4338
    self.TestCxx11Feature('static_pointer_cast<Base>(my_shared_ptr)', '')
4339
    self.TestCxx11Feature('std::declval<T>()', '')
4340

    
4341
  def testExplicitMakePair(self):
4342
    self.TestLint('make_pair', '')
4343
    self.TestLint('make_pair(42, 42)', '')
4344
    self.TestLint('make_pair<',
4345
                  'For C++11-compatibility, omit template arguments from'
4346
                  ' make_pair OR use pair directly OR if appropriate,'
4347
                  ' construct a pair directly'
4348
                  '  [build/explicit_make_pair] [4]')
4349
    self.TestLint('make_pair <',
4350
                  'For C++11-compatibility, omit template arguments from'
4351
                  ' make_pair OR use pair directly OR if appropriate,'
4352
                  ' construct a pair directly'
4353
                  '  [build/explicit_make_pair] [4]')
4354
    self.TestLint('my_make_pair<int, int>', '')
4355

    
4356
class CleansedLinesTest(unittest.TestCase):
4357

    
4358
  def testInit(self):
4359
    lines = ['Line 1',
4360
             'Line 2',
4361
             'Line 3 // Comment test',
4362
             'Line 4 /* Comment test */',
4363
             'Line 5 "foo"']
4364

    
4365
    clean_lines = cpplint.CleansedLines(lines)
4366
    self.assertEquals(lines, clean_lines.raw_lines)
4367
    self.assertEquals(5, clean_lines.NumLines())
4368

    
4369
    self.assertEquals(['Line 1',
4370
                       'Line 2',
4371
                       'Line 3',
4372
                       'Line 4',
4373
                       'Line 5 "foo"'],
4374
                      clean_lines.lines)
4375

    
4376
    self.assertEquals(['Line 1',
4377
                       'Line 2',
4378
                       'Line 3',
4379
                       'Line 4',
4380
                       'Line 5 ""'],
4381
                      clean_lines.elided)
4382

    
4383
  def testInitEmpty(self):
4384
    clean_lines = cpplint.CleansedLines([])
4385
    self.assertEquals([], clean_lines.raw_lines)
4386
    self.assertEquals(0, clean_lines.NumLines())
4387

    
4388
  def testCollapseStrings(self):
4389
    collapse = cpplint.CleansedLines._CollapseStrings
4390
    self.assertEquals('""', collapse('""'))             # ""     (empty)
4391
    self.assertEquals('"""', collapse('"""'))           # """    (bad)
4392
    self.assertEquals('""', collapse('"xyz"'))          # "xyz"  (string)
4393
    self.assertEquals('""', collapse('"\\\""'))         # "\""   (string)
4394
    self.assertEquals('""', collapse('"\'"'))           # "'"    (string)
4395
    self.assertEquals('"\"', collapse('"\"'))           # "\"    (bad)
4396
    self.assertEquals('""', collapse('"\\\\"'))         # "\\"   (string)
4397
    self.assertEquals('"', collapse('"\\\\\\"'))        # "\\\"  (bad)
4398
    self.assertEquals('""', collapse('"\\\\\\\\"'))     # "\\\\" (string)
4399

    
4400
    self.assertEquals('\'\'', collapse('\'\''))         # ''     (empty)
4401
    self.assertEquals('\'\'', collapse('\'a\''))        # 'a'    (char)
4402
    self.assertEquals('\'\'', collapse('\'\\\'\''))     # '\''   (char)
4403
    self.assertEquals('\'', collapse('\'\\\''))         # '\'    (bad)
4404
    self.assertEquals('', collapse('\\012'))            # '\012' (char)
4405
    self.assertEquals('', collapse('\\xfF0'))           # '\xfF0' (char)
4406
    self.assertEquals('', collapse('\\n'))              # '\n' (char)
4407
    self.assertEquals(r'\#', collapse('\\#'))           # '\#' (bad)
4408

    
4409
    self.assertEquals('"" + ""', collapse('"\'" + "\'"'))
4410
    self.assertEquals("'', ''", collapse("'\"', '\"'"))
4411
    self.assertEquals('""[0b10]', collapse('"a\'b"[0b1\'0]'))
4412

    
4413
    self.assertEquals('42', collapse("4'2"))
4414
    self.assertEquals('0b0101', collapse("0b0'1'0'1"))
4415
    self.assertEquals('1048576', collapse("1'048'576"))
4416
    self.assertEquals('0X100000', collapse("0X10'0000"))
4417
    self.assertEquals('0004000000', collapse("0'004'000'000"))
4418
    self.assertEquals('1.602176565e-19', collapse("1.602'176'565e-19"))
4419
    self.assertEquals('\'\' + 0xffff', collapse("'i' + 0xf'f'f'f"))
4420
    self.assertEquals('sizeof\'\' == 1', collapse("sizeof'x' == 1"))
4421
    self.assertEquals('0x.03p100', collapse('0x.0\'3p1\'0\'0'))
4422
    self.assertEquals('123.45', collapse('1\'23.4\'5'))
4423

    
4424
    self.assertEquals('StringReplace(body, "", "");',
4425
                      collapse('StringReplace(body, "\\\\", "\\\\\\\\");'))
4426
    self.assertEquals('\'\' ""',
4427
                      collapse('\'"\' "foo"'))
4428

    
4429

    
4430
class OrderOfIncludesTest(CpplintTestBase):
4431

    
4432
  def setUp(self):
4433
    CpplintTestBase.setUp(self)
4434
    self.include_state = cpplint._IncludeState()
4435
    os.path.abspath = lambda value: value
4436

    
4437
  def testCheckNextIncludeOrder_OtherThenCpp(self):
4438
    self.assertEqual('', self.include_state.CheckNextIncludeOrder(
4439
        cpplint._OTHER_HEADER))
4440
    self.assertEqual('Found C++ system header after other header',
4441
                     self.include_state.CheckNextIncludeOrder(
4442
                         cpplint._CPP_SYS_HEADER))
4443

    
4444
  def testCheckNextIncludeOrder_CppThenC(self):
4445
    self.assertEqual('', self.include_state.CheckNextIncludeOrder(
4446
        cpplint._CPP_SYS_HEADER))
4447
    self.assertEqual('Found C system header after C++ system header',
4448
                     self.include_state.CheckNextIncludeOrder(
4449
                         cpplint._C_SYS_HEADER))
4450

    
4451
  def testCheckNextIncludeOrder_LikelyThenCpp(self):
4452
    self.assertEqual('', self.include_state.CheckNextIncludeOrder(
4453
        cpplint._LIKELY_MY_HEADER))
4454
    self.assertEqual('', self.include_state.CheckNextIncludeOrder(
4455
        cpplint._CPP_SYS_HEADER))
4456

    
4457
  def testCheckNextIncludeOrder_PossibleThenCpp(self):
4458
    self.assertEqual('', self.include_state.CheckNextIncludeOrder(
4459
        cpplint._POSSIBLE_MY_HEADER))
4460
    self.assertEqual('', self.include_state.CheckNextIncludeOrder(
4461
        cpplint._CPP_SYS_HEADER))
4462

    
4463
  def testCheckNextIncludeOrder_CppThenLikely(self):
4464
    self.assertEqual('', self.include_state.CheckNextIncludeOrder(
4465
        cpplint._CPP_SYS_HEADER))
4466
    # This will eventually fail.
4467
    self.assertEqual('', self.include_state.CheckNextIncludeOrder(
4468
        cpplint._LIKELY_MY_HEADER))
4469

    
4470
  def testCheckNextIncludeOrder_CppThenPossible(self):
4471
    self.assertEqual('', self.include_state.CheckNextIncludeOrder(
4472
        cpplint._CPP_SYS_HEADER))
4473
    self.assertEqual('', self.include_state.CheckNextIncludeOrder(
4474
        cpplint._POSSIBLE_MY_HEADER))
4475

    
4476
  def testClassifyInclude(self):
4477
    file_info = cpplint.FileInfo
4478
    classify_include = cpplint._ClassifyInclude
4479
    self.assertEqual(cpplint._C_SYS_HEADER,
4480
                     classify_include(file_info('foo/foo.cc'),
4481
                                      'stdio.h',
4482
                                      True))
4483
    self.assertEqual(cpplint._CPP_SYS_HEADER,
4484
                     classify_include(file_info('foo/foo.cc'),
4485
                                      'string',
4486
                                      True))
4487
    self.assertEqual(cpplint._CPP_SYS_HEADER,
4488
                     classify_include(file_info('foo/foo.cc'),
4489
                                      'typeinfo',
4490
                                      True))
4491
    self.assertEqual(cpplint._OTHER_HEADER,
4492
                     classify_include(file_info('foo/foo.cc'),
4493
                                      'string',
4494
                                      False))
4495

    
4496
    self.assertEqual(cpplint._LIKELY_MY_HEADER,
4497
                     classify_include(file_info('foo/foo.cc'),
4498
                                      'foo/foo-inl.h',
4499
                                      False))
4500
    self.assertEqual(cpplint._LIKELY_MY_HEADER,
4501
                     classify_include(file_info('foo/internal/foo.cc'),
4502
                                      'foo/public/foo.h',
4503
                                      False))
4504
    self.assertEqual(cpplint._POSSIBLE_MY_HEADER,
4505
                     classify_include(file_info('foo/internal/foo.cc'),
4506
                                      'foo/other/public/foo.h',
4507
                                      False))
4508
    self.assertEqual(cpplint._OTHER_HEADER,
4509
                     classify_include(file_info('foo/internal/foo.cc'),
4510
                                      'foo/other/public/foop.h',
4511
                                      False))
4512

    
4513
  def testTryDropCommonSuffixes(self):
4514
    self.assertEqual('foo/foo', cpplint._DropCommonSuffixes('foo/foo-inl.h'))
4515
    self.assertEqual('foo/bar/foo',
4516
                     cpplint._DropCommonSuffixes('foo/bar/foo_inl.h'))
4517
    self.assertEqual('foo/foo', cpplint._DropCommonSuffixes('foo/foo.cc'))
4518
    self.assertEqual('foo/foo_unusualinternal',
4519
                     cpplint._DropCommonSuffixes('foo/foo_unusualinternal.h'))
4520
    self.assertEqual('',
4521
                     cpplint._DropCommonSuffixes('_test.cc'))
4522
    self.assertEqual('test',
4523
                     cpplint._DropCommonSuffixes('test.cc'))
4524

    
4525
  def testRegression(self):
4526
    def Format(includes):
4527
      include_list = []
4528
      for item in includes:
4529
        if item.startswith('"') or item.startswith('<'):
4530
          include_list.append('#include %s\n' % item)
4531
        else:
4532
          include_list.append(item + '\n')
4533
      return ''.join(include_list)
4534

    
4535
    # Test singleton cases first.
4536
    self.TestLanguageRulesCheck('foo/foo.cc', Format(['"foo/foo.h"']), '')
4537
    self.TestLanguageRulesCheck('foo/foo.cc', Format(['<stdio.h>']), '')
4538
    self.TestLanguageRulesCheck('foo/foo.cc', Format(['<string>']), '')
4539
    self.TestLanguageRulesCheck('foo/foo.cc', Format(['"foo/foo-inl.h"']), '')
4540
    self.TestLanguageRulesCheck('foo/foo.cc', Format(['"bar/bar-inl.h"']), '')
4541
    self.TestLanguageRulesCheck('foo/foo.cc', Format(['"bar/bar.h"']), '')
4542

    
4543
    # Test everything in a good and new order.
4544
    self.TestLanguageRulesCheck('foo/foo.cc',
4545
                                Format(['"foo/foo.h"',
4546
                                        '"foo/foo-inl.h"',
4547
                                        '<stdio.h>',
4548
                                        '<string>',
4549
                                        '<unordered_map>',
4550
                                        '"bar/bar-inl.h"',
4551
                                        '"bar/bar.h"']),
4552
                                '')
4553

    
4554
    # Test bad orders.
4555
    self.TestLanguageRulesCheck(
4556
        'foo/foo.cc',
4557
        Format(['<string>', '<stdio.h>']),
4558
        'Found C system header after C++ system header.'
4559
        ' Should be: foo.h, c system, c++ system, other.'
4560
        '  [build/include_order] [4]')
4561
    self.TestLanguageRulesCheck(
4562
        'foo/foo.cc',
4563
        Format(['"foo/bar-inl.h"',
4564
                '"foo/foo-inl.h"']),
4565
        '')
4566
    self.TestLanguageRulesCheck(
4567
        'foo/foo.cc',
4568
        Format(['"foo/e.h"',
4569
                '"foo/b.h"',  # warning here (e>b)
4570
                '"foo/c.h"',
4571
                '"foo/d.h"',
4572
                '"foo/a.h"']),  # warning here (d>a)
4573
        ['Include "foo/b.h" not in alphabetical order'
4574
         '  [build/include_alpha] [4]',
4575
         'Include "foo/a.h" not in alphabetical order'
4576
         '  [build/include_alpha] [4]'])
4577
    # -inl.h headers are no longer special.
4578
    self.TestLanguageRulesCheck('foo/foo.cc',
4579
                                Format(['"foo/foo-inl.h"', '<string>']),
4580
                                '')
4581
    self.TestLanguageRulesCheck('foo/foo.cc',
4582
                                Format(['"foo/bar.h"', '"foo/bar-inl.h"']),
4583
                                '')
4584
    # Test componentized header.  OK to have my header in ../public dir.
4585
    self.TestLanguageRulesCheck('foo/internal/foo.cc',
4586
                                Format(['"foo/public/foo.h"', '<string>']),
4587
                                '')
4588
    # OK to have my header in other dir (not stylistically, but
4589
    # cpplint isn't as good as a human).
4590
    self.TestLanguageRulesCheck('foo/internal/foo.cc',
4591
                                Format(['"foo/other/public/foo.h"',
4592
                                        '<string>']),
4593
                                '')
4594
    self.TestLanguageRulesCheck('foo/foo.cc',
4595
                                Format(['"foo/foo.h"',
4596
                                        '<string>',
4597
                                        '"base/google.h"',
4598
                                        '"base/flags.h"']),
4599
                                'Include "base/flags.h" not in alphabetical '
4600
                                'order  [build/include_alpha] [4]')
4601
    # According to the style, -inl.h should come before .h, but we don't
4602
    # complain about that.
4603
    self.TestLanguageRulesCheck('foo/foo.cc',
4604
                                Format(['"foo/foo-inl.h"',
4605
                                        '"foo/foo.h"',
4606
                                        '"base/google.h"',
4607
                                        '"base/google-inl.h"']),
4608
                                '')
4609
    # Allow project includes to be separated by blank lines
4610
    self.TestLanguageRulesCheck('a/a.cc',
4611
                                Format(['"a/a.h"',
4612
                                        '<string>',
4613
                                        '"base/google.h"',
4614
                                        '',
4615
                                        '"b/c.h"',
4616
                                        '',
4617
                                        'MACRO',
4618
                                        '"a/b.h"']),
4619
                                '')
4620
    self.TestLanguageRulesCheck('a/a.cc',
4621
                                Format(['"a/a.h"',
4622
                                        '<string>',
4623
                                        '"base/google.h"',
4624
                                        '"a/b.h"']),
4625
                                'Include "a/b.h" not in alphabetical '
4626
                                'order  [build/include_alpha] [4]')
4627

    
4628
    # Test conditional includes
4629
    self.TestLanguageRulesCheck(
4630
        'a/a.cc',
4631
        ''.join(['#include <string.h>\n',
4632
                 '#include "base/port.h"\n',
4633
                 '#include <initializer_list>\n']),
4634
        ('Found C++ system header after other header. '
4635
         'Should be: a.h, c system, c++ system, other.  '
4636
         '[build/include_order] [4]'))
4637
    self.TestLanguageRulesCheck(
4638
        'a/a.cc',
4639
        ''.join(['#include <string.h>\n',
4640
                 '#include "base/port.h"\n',
4641
                 '#ifdef LANG_CXX11\n',
4642
                 '#include <initializer_list>\n',
4643
                 '#endif  // LANG_CXX11\n']),
4644
        '')
4645
    self.TestLanguageRulesCheck(
4646
        'a/a.cc',
4647
        ''.join(['#include <string.h>\n',
4648
                 '#ifdef LANG_CXX11\n',
4649
                 '#include "base/port.h"\n',
4650
                 '#include <initializer_list>\n',
4651
                 '#endif  // LANG_CXX11\n']),
4652
        ('Found C++ system header after other header. '
4653
         'Should be: a.h, c system, c++ system, other.  '
4654
         '[build/include_order] [4]'))
4655

    
4656
    # Third party headers are exempt from order checks
4657
    self.TestLanguageRulesCheck('foo/foo.cc',
4658
                                Format(['<string>', '"Python.h"', '<vector>']),
4659
                                '')
4660

    
4661

    
4662
class CheckForFunctionLengthsTest(CpplintTestBase):
4663

    
4664
  def setUp(self):
4665
    # Reducing these thresholds for the tests speeds up tests significantly.
4666
    self.old_normal_trigger = cpplint._FunctionState._NORMAL_TRIGGER
4667
    self.old_test_trigger = cpplint._FunctionState._TEST_TRIGGER
4668

    
4669
    cpplint._FunctionState._NORMAL_TRIGGER = 10
4670
    cpplint._FunctionState._TEST_TRIGGER = 25
4671

    
4672
  def tearDown(self):
4673
    cpplint._FunctionState._NORMAL_TRIGGER = self.old_normal_trigger
4674
    cpplint._FunctionState._TEST_TRIGGER = self.old_test_trigger
4675

    
4676
  def TestFunctionLengthsCheck(self, code, expected_message):
4677
    """Check warnings for long function bodies are as expected.
4678

4679
    Args:
4680
      code: C++ source code expected to generate a warning message.
4681
      expected_message: Message expected to be generated by the C++ code.
4682
    """
4683
    self.assertEquals(expected_message,
4684
                      self.PerformFunctionLengthsCheck(code))
4685

    
4686
  def TriggerLines(self, error_level):
4687
    """Return number of lines needed to trigger a function length warning.
4688

4689
    Args:
4690
      error_level: --v setting for cpplint.
4691

4692
    Returns:
4693
      Number of lines needed to trigger a function length warning.
4694
    """
4695
    return cpplint._FunctionState._NORMAL_TRIGGER * 2**error_level
4696

    
4697
  def TestLines(self, error_level):
4698
    """Return number of lines needed to trigger a test function length warning.
4699

4700
    Args:
4701
      error_level: --v setting for cpplint.
4702

4703
    Returns:
4704
      Number of lines needed to trigger a test function length warning.
4705
    """
4706
    return cpplint._FunctionState._TEST_TRIGGER * 2**error_level
4707

    
4708
  def TestFunctionLengthCheckDefinition(self, lines, error_level):
4709
    """Generate long function definition and check warnings are as expected.
4710

4711
    Args:
4712
      lines: Number of lines to generate.
4713
      error_level:  --v setting for cpplint.
4714
    """
4715
    trigger_level = self.TriggerLines(cpplint._VerboseLevel())
4716
    self.TestFunctionLengthsCheck(
4717
        'void test(int x)' + self.FunctionBody(lines),
4718
        ('Small and focused functions are preferred: '
4719
         'test() has %d non-comment lines '
4720
         '(error triggered by exceeding %d lines).'
4721
         '  [readability/fn_size] [%d]'
4722
         % (lines, trigger_level, error_level)))
4723

    
4724
  def TestFunctionLengthCheckDefinitionOK(self, lines):
4725
    """Generate shorter function definition and check no warning is produced.
4726

4727
    Args:
4728
      lines: Number of lines to generate.
4729
    """
4730
    self.TestFunctionLengthsCheck(
4731
        'void test(int x)' + self.FunctionBody(lines),
4732
        '')
4733

    
4734
  def TestFunctionLengthCheckAtErrorLevel(self, error_level):
4735
    """Generate and check function at the trigger level for --v setting.
4736

4737
    Args:
4738
      error_level: --v setting for cpplint.
4739
    """
4740
    self.TestFunctionLengthCheckDefinition(self.TriggerLines(error_level),
4741
                                           error_level)
4742

    
4743
  def TestFunctionLengthCheckBelowErrorLevel(self, error_level):
4744
    """Generate and check function just below the trigger level for --v setting.
4745

4746
    Args:
4747
      error_level: --v setting for cpplint.
4748
    """
4749
    self.TestFunctionLengthCheckDefinition(self.TriggerLines(error_level)-1,
4750
                                           error_level-1)
4751

    
4752
  def TestFunctionLengthCheckAboveErrorLevel(self, error_level):
4753
    """Generate and check function just above the trigger level for --v setting.
4754

4755
    Args:
4756
      error_level: --v setting for cpplint.
4757
    """
4758
    self.TestFunctionLengthCheckDefinition(self.TriggerLines(error_level)+1,
4759
                                           error_level)
4760

    
4761
  def FunctionBody(self, number_of_lines):
4762
    return ' {\n' + '    this_is_just_a_test();\n'*number_of_lines + '}'
4763

    
4764
  def FunctionBodyWithBlankLines(self, number_of_lines):
4765
    return ' {\n' + '    this_is_just_a_test();\n\n'*number_of_lines + '}'
4766

    
4767
  def FunctionBodyWithNoLints(self, number_of_lines):
4768
    return (' {\n' +
4769
            '    this_is_just_a_test();  // NOLINT\n'*number_of_lines + '}')
4770

    
4771
  # Test line length checks.
4772
  def testFunctionLengthCheckDeclaration(self):
4773
    self.TestFunctionLengthsCheck(
4774
        'void test();',  # Not a function definition
4775
        '')
4776

    
4777
  def testFunctionLengthCheckDeclarationWithBlockFollowing(self):
4778
    self.TestFunctionLengthsCheck(
4779
        ('void test();\n'
4780
         + self.FunctionBody(66)),  # Not a function definition
4781
        '')
4782

    
4783
  def testFunctionLengthCheckClassDefinition(self):
4784
    self.TestFunctionLengthsCheck(  # Not a function definition
4785
        'class Test' + self.FunctionBody(66) + ';',
4786
        '')
4787

    
4788
  def testFunctionLengthCheckTrivial(self):
4789
    self.TestFunctionLengthsCheck(
4790
        'void test() {}',  # Not counted
4791
        '')
4792

    
4793
  def testFunctionLengthCheckEmpty(self):
4794
    self.TestFunctionLengthsCheck(
4795
        'void test() {\n}',
4796
        '')
4797

    
4798
  def testFunctionLengthCheckDefinitionBelowSeverity0(self):
4799
    old_verbosity = cpplint._SetVerboseLevel(0)
4800
    self.TestFunctionLengthCheckDefinitionOK(self.TriggerLines(0)-1)
4801
    cpplint._SetVerboseLevel(old_verbosity)
4802

    
4803
  def testFunctionLengthCheckDefinitionAtSeverity0(self):
4804
    old_verbosity = cpplint._SetVerboseLevel(0)
4805
    self.TestFunctionLengthCheckDefinitionOK(self.TriggerLines(0))
4806
    cpplint._SetVerboseLevel(old_verbosity)
4807

    
4808
  def testFunctionLengthCheckDefinitionAboveSeverity0(self):
4809
    old_verbosity = cpplint._SetVerboseLevel(0)
4810
    self.TestFunctionLengthCheckAboveErrorLevel(0)
4811
    cpplint._SetVerboseLevel(old_verbosity)
4812

    
4813
  def testFunctionLengthCheckDefinitionBelowSeverity1v0(self):
4814
    old_verbosity = cpplint._SetVerboseLevel(0)
4815
    self.TestFunctionLengthCheckBelowErrorLevel(1)
4816
    cpplint._SetVerboseLevel(old_verbosity)
4817

    
4818
  def testFunctionLengthCheckDefinitionAtSeverity1v0(self):
4819
    old_verbosity = cpplint._SetVerboseLevel(0)
4820
    self.TestFunctionLengthCheckAtErrorLevel(1)
4821
    cpplint._SetVerboseLevel(old_verbosity)
4822

    
4823
  def testFunctionLengthCheckDefinitionBelowSeverity1(self):
4824
    self.TestFunctionLengthCheckDefinitionOK(self.TriggerLines(1)-1)
4825

    
4826
  def testFunctionLengthCheckDefinitionAtSeverity1(self):
4827
    self.TestFunctionLengthCheckDefinitionOK(self.TriggerLines(1))
4828

    
4829
  def testFunctionLengthCheckDefinitionAboveSeverity1(self):
4830
    self.TestFunctionLengthCheckAboveErrorLevel(1)
4831

    
4832
  def testFunctionLengthCheckDefinitionSeverity1PlusBlanks(self):
4833
    error_level = 1
4834
    error_lines = self.TriggerLines(error_level) + 1
4835
    trigger_level = self.TriggerLines(cpplint._VerboseLevel())
4836
    self.TestFunctionLengthsCheck(
4837
        'void test_blanks(int x)' + self.FunctionBody(error_lines),
4838
        ('Small and focused functions are preferred: '
4839
         'test_blanks() has %d non-comment lines '
4840
         '(error triggered by exceeding %d lines).'
4841
         '  [readability/fn_size] [%d]')
4842
        % (error_lines, trigger_level, error_level))
4843

    
4844
  def testFunctionLengthCheckComplexDefinitionSeverity1(self):
4845
    error_level = 1
4846
    error_lines = self.TriggerLines(error_level) + 1
4847
    trigger_level = self.TriggerLines(cpplint._VerboseLevel())
4848
    self.TestFunctionLengthsCheck(
4849
        ('my_namespace::my_other_namespace::MyVeryLongTypeName*\n'
4850
         'my_namespace::my_other_namespace::MyFunction(int arg1, char* arg2)'
4851
         + self.FunctionBody(error_lines)),
4852
        ('Small and focused functions are preferred: '
4853
         'my_namespace::my_other_namespace::MyFunction()'
4854
         ' has %d non-comment lines '
4855
         '(error triggered by exceeding %d lines).'
4856
         '  [readability/fn_size] [%d]')
4857
        % (error_lines, trigger_level, error_level))
4858

    
4859
  def testFunctionLengthCheckDefinitionSeverity1ForTest(self):
4860
    error_level = 1
4861
    error_lines = self.TestLines(error_level) + 1
4862
    trigger_level = self.TestLines(cpplint._VerboseLevel())
4863
    self.TestFunctionLengthsCheck(
4864
        'TEST_F(Test, Mutator)' + self.FunctionBody(error_lines),
4865
        ('Small and focused functions are preferred: '
4866
         'TEST_F(Test, Mutator) has %d non-comment lines '
4867
         '(error triggered by exceeding %d lines).'
4868
         '  [readability/fn_size] [%d]')
4869
        % (error_lines, trigger_level, error_level))
4870

    
4871
  def testFunctionLengthCheckDefinitionSeverity1ForSplitLineTest(self):
4872
    error_level = 1
4873
    error_lines = self.TestLines(error_level) + 1
4874
    trigger_level = self.TestLines(cpplint._VerboseLevel())
4875
    self.TestFunctionLengthsCheck(
4876
        ('TEST_F(GoogleUpdateRecoveryRegistryProtectedTest,\n'
4877
         '    FixGoogleUpdate_AllValues_MachineApp)'  # note: 4 spaces
4878
         + self.FunctionBody(error_lines)),
4879
        ('Small and focused functions are preferred: '
4880
         'TEST_F(GoogleUpdateRecoveryRegistryProtectedTest, '  # 1 space
4881
         'FixGoogleUpdate_AllValues_MachineApp) has %d non-comment lines '
4882
         '(error triggered by exceeding %d lines).'
4883
         '  [readability/fn_size] [%d]')
4884
        % (error_lines+1, trigger_level, error_level))
4885

    
4886
  def testFunctionLengthCheckDefinitionSeverity1ForBadTestDoesntBreak(self):
4887
    error_level = 1
4888
    error_lines = self.TestLines(error_level) + 1
4889
    trigger_level = self.TestLines(cpplint._VerboseLevel())
4890
    self.TestFunctionLengthsCheck(
4891
        ('TEST_F('
4892
         + self.FunctionBody(error_lines)),
4893
        ('Small and focused functions are preferred: '
4894
         'TEST_F has %d non-comment lines '
4895
         '(error triggered by exceeding %d lines).'
4896
         '  [readability/fn_size] [%d]')
4897
        % (error_lines, trigger_level, error_level))
4898

    
4899
  def testFunctionLengthCheckDefinitionSeverity1WithEmbeddedNoLints(self):
4900
    error_level = 1
4901
    error_lines = self.TriggerLines(error_level)+1
4902
    trigger_level = self.TriggerLines(cpplint._VerboseLevel())
4903
    self.TestFunctionLengthsCheck(
4904
        'void test(int x)' + self.FunctionBodyWithNoLints(error_lines),
4905
        ('Small and focused functions are preferred: '
4906
         'test() has %d non-comment lines '
4907
         '(error triggered by exceeding %d lines).'
4908
         '  [readability/fn_size] [%d]')
4909
        % (error_lines, trigger_level, error_level))
4910

    
4911
  def testFunctionLengthCheckDefinitionSeverity1WithNoLint(self):
4912
    self.TestFunctionLengthsCheck(
4913
        ('void test(int x)' + self.FunctionBody(self.TriggerLines(1))
4914
         + '  // NOLINT -- long function'),
4915
        '')
4916

    
4917
  def testFunctionLengthCheckDefinitionBelowSeverity2(self):
4918
    self.TestFunctionLengthCheckBelowErrorLevel(2)
4919

    
4920
  def testFunctionLengthCheckDefinitionSeverity2(self):
4921
    self.TestFunctionLengthCheckAtErrorLevel(2)
4922

    
4923
  def testFunctionLengthCheckDefinitionAboveSeverity2(self):
4924
    self.TestFunctionLengthCheckAboveErrorLevel(2)
4925

    
4926
  def testFunctionLengthCheckDefinitionBelowSeverity3(self):
4927
    self.TestFunctionLengthCheckBelowErrorLevel(3)
4928

    
4929
  def testFunctionLengthCheckDefinitionSeverity3(self):
4930
    self.TestFunctionLengthCheckAtErrorLevel(3)
4931

    
4932
  def testFunctionLengthCheckDefinitionAboveSeverity3(self):
4933
    self.TestFunctionLengthCheckAboveErrorLevel(3)
4934

    
4935
  def testFunctionLengthCheckDefinitionBelowSeverity4(self):
4936
    self.TestFunctionLengthCheckBelowErrorLevel(4)
4937

    
4938
  def testFunctionLengthCheckDefinitionSeverity4(self):
4939
    self.TestFunctionLengthCheckAtErrorLevel(4)
4940

    
4941
  def testFunctionLengthCheckDefinitionAboveSeverity4(self):
4942
    self.TestFunctionLengthCheckAboveErrorLevel(4)
4943

    
4944
  def testFunctionLengthCheckDefinitionBelowSeverity5(self):
4945
    self.TestFunctionLengthCheckBelowErrorLevel(5)
4946

    
4947
  def testFunctionLengthCheckDefinitionAtSeverity5(self):
4948
    self.TestFunctionLengthCheckAtErrorLevel(5)
4949

    
4950
  def testFunctionLengthCheckDefinitionAboveSeverity5(self):
4951
    self.TestFunctionLengthCheckAboveErrorLevel(5)
4952

    
4953
  def testFunctionLengthCheckDefinitionHugeLines(self):
4954
    # 5 is the limit
4955
    self.TestFunctionLengthCheckDefinition(self.TriggerLines(10), 5)
4956

    
4957
  def testFunctionLengthNotDeterminable(self):
4958
    # Macro invocation without terminating semicolon.
4959
    self.TestFunctionLengthsCheck(
4960
        'MACRO(arg)',
4961
        '')
4962

    
4963
    # Macro with underscores
4964
    self.TestFunctionLengthsCheck(
4965
        'MACRO_WITH_UNDERSCORES(arg1, arg2, arg3)',
4966
        '')
4967

    
4968
    self.TestFunctionLengthsCheck(
4969
        'NonMacro(arg)',
4970
        'Lint failed to find start of function body.'
4971
        '  [readability/fn_size] [5]')
4972

    
4973

    
4974
def TrimExtraIndent(text_block):
4975
  """Trim a uniform amount of whitespace off of each line in a string.
4976

4977
  Compute the minimum indent on all non blank lines and trim that from each, so
4978
  that the block of text has no extra indentation.
4979

4980
  Args:
4981
    text_block: a multiline string
4982

4983
  Returns:
4984
    text_block with the common whitespace indent of each line removed.
4985
  """
4986

    
4987
  def CountLeadingWhitespace(s):
4988
    count = 0
4989
    for c in s:
4990
      if not c.isspace():
4991
        break
4992
      count += 1
4993
    return count
4994
  # find the minimum indent (except for blank lines)
4995
  min_indent = min([CountLeadingWhitespace(line)
4996
                    for line in text_block.split('\n') if line])
4997
  return '\n'.join([line[min_indent:] for line in text_block.split('\n')])
4998

    
4999

    
5000
class CloseExpressionTest(unittest.TestCase):
5001

    
5002
  def setUp(self):
5003
    self.lines = cpplint.CleansedLines(
5004
        #           1         2         3         4         5
5005
        # 0123456789012345678901234567890123456789012345678901234567890
5006
        ['// Line 0',
5007
         'inline RCULocked<X>::ReadPtr::ReadPtr(const RCULocked* rcu) {',
5008
         '  DCHECK(!(data & kFlagMask)) << "Error";',
5009
         '}',
5010
         '// Line 4',
5011
         'RCULocked<X>::WritePtr::WritePtr(RCULocked* rcu)',
5012
         '    : lock_(&rcu_->mutex_) {',
5013
         '}',
5014
         '// Line 8',
5015
         'template <typename T, typename... A>',
5016
         'typename std::enable_if<',
5017
         '    std::is_array<T>::value && (std::extent<T>::value > 0)>::type',
5018
         'MakeUnique(A&&... a) = delete;',
5019
         '// Line 13',
5020
         'auto x = []() {};',
5021
         '// Line 15',
5022
         'template <typename U>',
5023
         'friend bool operator==(const reffed_ptr& a,',
5024
         '                       const reffed_ptr<U>& b) {',
5025
         '  return a.get() == b.get();',
5026
         '}',
5027
         '// Line 21'])
5028

    
5029
  def testCloseExpression(self):
5030
    # List of positions to test:
5031
    # (start line, start position, end line, end position + 1)
5032
    positions = [(1, 16, 1, 19),
5033
                 (1, 37, 1, 59),
5034
                 (1, 60, 3, 1),
5035
                 (2, 8, 2, 29),
5036
                 (2, 30, 22, -1),  # Left shift operator
5037
                 (9, 9, 9, 36),
5038
                 (10, 23, 11, 59),
5039
                 (11, 54, 22, -1),  # Greater than operator
5040
                 (14, 9, 14, 11),
5041
                 (14, 11, 14, 13),
5042
                 (14, 14, 14, 16),
5043
                 (17, 22, 18, 46),
5044
                 (18, 47, 20, 1)]
5045
    for p in positions:
5046
      (_, line, column) = cpplint.CloseExpression(self.lines, p[0], p[1])
5047
      self.assertEquals((p[2], p[3]), (line, column))
5048

    
5049
  def testReverseCloseExpression(self):
5050
    # List of positions to test:
5051
    # (end line, end position, start line, start position)
5052
    positions = [(1, 18, 1, 16),
5053
                 (1, 58, 1, 37),
5054
                 (2, 27, 2, 10),
5055
                 (2, 28, 2, 8),
5056
                 (6, 18, 0, -1),  # -> operator
5057
                 (9, 35, 9, 9),
5058
                 (11, 54, 0, -1),  # Greater than operator
5059
                 (11, 57, 11, 31),
5060
                 (14, 10, 14, 9),
5061
                 (14, 12, 14, 11),
5062
                 (14, 15, 14, 14),
5063
                 (18, 45, 17, 22),
5064
                 (20, 0, 18, 47)]
5065
    for p in positions:
5066
      (_, line, column) = cpplint.ReverseCloseExpression(self.lines, p[0], p[1])
5067
      self.assertEquals((p[2], p[3]), (line, column))
5068

    
5069

    
5070
class NestingStateTest(unittest.TestCase):
5071

    
5072
  def setUp(self):
5073
    self.nesting_state = cpplint.NestingState()
5074
    self.error_collector = ErrorCollector(self.assert_)
5075

    
5076
  def UpdateWithLines(self, lines):
5077
    clean_lines = cpplint.CleansedLines(lines)
5078
    for line in xrange(clean_lines.NumLines()):
5079
      self.nesting_state.Update('test.cc',
5080
                                clean_lines, line, self.error_collector)
5081

    
5082
  def testEmpty(self):
5083
    self.UpdateWithLines([])
5084
    self.assertEquals(self.nesting_state.stack, [])
5085

    
5086
  def testNamespace(self):
5087
    self.UpdateWithLines(['namespace {'])
5088
    self.assertEquals(len(self.nesting_state.stack), 1)
5089
    self.assertTrue(isinstance(self.nesting_state.stack[0],
5090
                               cpplint._NamespaceInfo))
5091
    self.assertTrue(self.nesting_state.stack[0].seen_open_brace)
5092
    self.assertEquals(self.nesting_state.stack[0].name, '')
5093

    
5094
    self.UpdateWithLines(['namespace outer { namespace inner'])
5095
    self.assertEquals(len(self.nesting_state.stack), 3)
5096
    self.assertTrue(self.nesting_state.stack[0].seen_open_brace)
5097
    self.assertTrue(self.nesting_state.stack[1].seen_open_brace)
5098
    self.assertFalse(self.nesting_state.stack[2].seen_open_brace)
5099
    self.assertEquals(self.nesting_state.stack[0].name, '')
5100
    self.assertEquals(self.nesting_state.stack[1].name, 'outer')
5101
    self.assertEquals(self.nesting_state.stack[2].name, 'inner')
5102

    
5103
    self.UpdateWithLines(['{'])
5104
    self.assertTrue(self.nesting_state.stack[2].seen_open_brace)
5105

    
5106
    self.UpdateWithLines(['}', '}}'])
5107
    self.assertEquals(len(self.nesting_state.stack), 0)
5108

    
5109
  def testClass(self):
5110
    self.UpdateWithLines(['class A {'])
5111
    self.assertEquals(len(self.nesting_state.stack), 1)
5112
    self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo))
5113
    self.assertEquals(self.nesting_state.stack[0].name, 'A')
5114
    self.assertFalse(self.nesting_state.stack[0].is_derived)
5115
    self.assertEquals(self.nesting_state.stack[0].class_indent, 0)
5116

    
5117
    self.UpdateWithLines(['};',
5118
                          'struct B : public A {'])
5119
    self.assertEquals(len(self.nesting_state.stack), 1)
5120
    self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo))
5121
    self.assertEquals(self.nesting_state.stack[0].name, 'B')
5122
    self.assertTrue(self.nesting_state.stack[0].is_derived)
5123

    
5124
    self.UpdateWithLines(['};',
5125
                          'class C',
5126
                          ': public A {'])
5127
    self.assertEquals(len(self.nesting_state.stack), 1)
5128
    self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo))
5129
    self.assertEquals(self.nesting_state.stack[0].name, 'C')
5130
    self.assertTrue(self.nesting_state.stack[0].is_derived)
5131

    
5132
    self.UpdateWithLines(['};',
5133
                          'template<T>'])
5134
    self.assertEquals(len(self.nesting_state.stack), 0)
5135

    
5136
    self.UpdateWithLines(['class D {', '  class E {'])
5137
    self.assertEquals(len(self.nesting_state.stack), 2)
5138
    self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo))
5139
    self.assertEquals(self.nesting_state.stack[0].name, 'D')
5140
    self.assertFalse(self.nesting_state.stack[0].is_derived)
5141
    self.assertTrue(isinstance(self.nesting_state.stack[1], cpplint._ClassInfo))
5142
    self.assertEquals(self.nesting_state.stack[1].name, 'E')
5143
    self.assertFalse(self.nesting_state.stack[1].is_derived)
5144
    self.assertEquals(self.nesting_state.stack[1].class_indent, 2)
5145
    self.assertEquals(self.nesting_state.InnermostClass().name, 'E')
5146

    
5147
    self.UpdateWithLines(['}', '}'])
5148
    self.assertEquals(len(self.nesting_state.stack), 0)
5149

    
5150
  def testClassAccess(self):
5151
    self.UpdateWithLines(['class A {'])
5152
    self.assertEquals(len(self.nesting_state.stack), 1)
5153
    self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo))
5154
    self.assertEquals(self.nesting_state.stack[0].access, 'private')
5155

    
5156
    self.UpdateWithLines([' public:'])
5157
    self.assertEquals(self.nesting_state.stack[0].access, 'public')
5158
    self.UpdateWithLines([' protracted:'])
5159
    self.assertEquals(self.nesting_state.stack[0].access, 'public')
5160
    self.UpdateWithLines([' protected:'])
5161
    self.assertEquals(self.nesting_state.stack[0].access, 'protected')
5162
    self.UpdateWithLines([' private:'])
5163
    self.assertEquals(self.nesting_state.stack[0].access, 'private')
5164

    
5165
    self.UpdateWithLines(['  struct B {'])
5166
    self.assertEquals(len(self.nesting_state.stack), 2)
5167
    self.assertTrue(isinstance(self.nesting_state.stack[1], cpplint._ClassInfo))
5168
    self.assertEquals(self.nesting_state.stack[1].access, 'public')
5169
    self.assertEquals(self.nesting_state.stack[0].access, 'private')
5170

    
5171
    self.UpdateWithLines(['   protected  :'])
5172
    self.assertEquals(self.nesting_state.stack[1].access, 'protected')
5173
    self.assertEquals(self.nesting_state.stack[0].access, 'private')
5174

    
5175
    self.UpdateWithLines(['  }', '}'])
5176
    self.assertEquals(len(self.nesting_state.stack), 0)
5177

    
5178
  def testStruct(self):
5179
    self.UpdateWithLines(['struct A {'])
5180
    self.assertEquals(len(self.nesting_state.stack), 1)
5181
    self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo))
5182
    self.assertEquals(self.nesting_state.stack[0].name, 'A')
5183
    self.assertFalse(self.nesting_state.stack[0].is_derived)
5184

    
5185
    self.UpdateWithLines(['}',
5186
                          'void Func(struct B arg) {'])
5187
    self.assertEquals(len(self.nesting_state.stack), 1)
5188
    self.assertFalse(isinstance(self.nesting_state.stack[0],
5189
                                cpplint._ClassInfo))
5190

    
5191
    self.UpdateWithLines(['}'])
5192
    self.assertEquals(len(self.nesting_state.stack), 0)
5193

    
5194
  def testPreprocessor(self):
5195
    self.assertEquals(len(self.nesting_state.pp_stack), 0)
5196
    self.UpdateWithLines(['#if MACRO1'])
5197
    self.assertEquals(len(self.nesting_state.pp_stack), 1)
5198
    self.UpdateWithLines(['#endif'])
5199
    self.assertEquals(len(self.nesting_state.pp_stack), 0)
5200

    
5201
    self.UpdateWithLines(['#ifdef MACRO2'])
5202
    self.assertEquals(len(self.nesting_state.pp_stack), 1)
5203
    self.UpdateWithLines(['#else'])
5204
    self.assertEquals(len(self.nesting_state.pp_stack), 1)
5205
    self.UpdateWithLines(['#ifdef MACRO3'])
5206
    self.assertEquals(len(self.nesting_state.pp_stack), 2)
5207
    self.UpdateWithLines(['#elif MACRO4'])
5208
    self.assertEquals(len(self.nesting_state.pp_stack), 2)
5209
    self.UpdateWithLines(['#endif'])
5210
    self.assertEquals(len(self.nesting_state.pp_stack), 1)
5211
    self.UpdateWithLines(['#endif'])
5212
    self.assertEquals(len(self.nesting_state.pp_stack), 0)
5213

    
5214
    self.UpdateWithLines(['#ifdef MACRO5',
5215
                          'class A {',
5216
                          '#elif MACRO6',
5217
                          'class B {',
5218
                          '#else',
5219
                          'class C {',
5220
                          '#endif'])
5221
    self.assertEquals(len(self.nesting_state.pp_stack), 0)
5222
    self.assertEquals(len(self.nesting_state.stack), 1)
5223
    self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo))
5224
    self.assertEquals(self.nesting_state.stack[0].name, 'A')
5225
    self.UpdateWithLines(['};'])
5226
    self.assertEquals(len(self.nesting_state.stack), 0)
5227

    
5228
    self.UpdateWithLines(['class D',
5229
                          '#ifdef MACRO7'])
5230
    self.assertEquals(len(self.nesting_state.pp_stack), 1)
5231
    self.assertEquals(len(self.nesting_state.stack), 1)
5232
    self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo))
5233
    self.assertEquals(self.nesting_state.stack[0].name, 'D')
5234
    self.assertFalse(self.nesting_state.stack[0].is_derived)
5235

    
5236
    self.UpdateWithLines(['#elif MACRO8',
5237
                          ': public E'])
5238
    self.assertEquals(len(self.nesting_state.stack), 1)
5239
    self.assertEquals(self.nesting_state.stack[0].name, 'D')
5240
    self.assertTrue(self.nesting_state.stack[0].is_derived)
5241
    self.assertFalse(self.nesting_state.stack[0].seen_open_brace)
5242

    
5243
    self.UpdateWithLines(['#else',
5244
                          '{'])
5245
    self.assertEquals(len(self.nesting_state.stack), 1)
5246
    self.assertEquals(self.nesting_state.stack[0].name, 'D')
5247
    self.assertFalse(self.nesting_state.stack[0].is_derived)
5248
    self.assertTrue(self.nesting_state.stack[0].seen_open_brace)
5249

    
5250
    self.UpdateWithLines(['#endif'])
5251
    self.assertEquals(len(self.nesting_state.pp_stack), 0)
5252
    self.assertEquals(len(self.nesting_state.stack), 1)
5253
    self.assertEquals(self.nesting_state.stack[0].name, 'D')
5254
    self.assertFalse(self.nesting_state.stack[0].is_derived)
5255
    self.assertFalse(self.nesting_state.stack[0].seen_open_brace)
5256

    
5257
    self.UpdateWithLines([';'])
5258
    self.assertEquals(len(self.nesting_state.stack), 0)
5259

    
5260
  def testTemplate(self):
5261
    self.UpdateWithLines(['template <T,',
5262
                          '          class Arg1 = tmpl<T> >'])
5263
    self.assertEquals(len(self.nesting_state.stack), 0)
5264
    self.UpdateWithLines(['class A {'])
5265
    self.assertEquals(len(self.nesting_state.stack), 1)
5266
    self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo))
5267
    self.assertEquals(self.nesting_state.stack[0].name, 'A')
5268

    
5269
    self.UpdateWithLines(['};',
5270
                          'template <T,',
5271
                          '  template <typename, typename> class B>',
5272
                          'class C'])
5273
    self.assertEquals(len(self.nesting_state.stack), 1)
5274
    self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo))
5275
    self.assertEquals(self.nesting_state.stack[0].name, 'C')
5276
    self.UpdateWithLines([';'])
5277
    self.assertEquals(len(self.nesting_state.stack), 0)
5278

    
5279
    self.UpdateWithLines(['class D : public Tmpl<E>'])
5280
    self.assertEquals(len(self.nesting_state.stack), 1)
5281
    self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo))
5282
    self.assertEquals(self.nesting_state.stack[0].name, 'D')
5283

    
5284
    self.UpdateWithLines(['{', '};'])
5285
    self.assertEquals(len(self.nesting_state.stack), 0)
5286

    
5287
    self.UpdateWithLines(['template <class F,',
5288
                          '          class G,',
5289
                          '          class H,',
5290
                          '          typename I>',
5291
                          'static void Func() {'])
5292
    self.assertEquals(len(self.nesting_state.stack), 1)
5293
    self.assertFalse(isinstance(self.nesting_state.stack[0],
5294
                                cpplint._ClassInfo))
5295
    self.UpdateWithLines(['}',
5296
                          'template <class J> class K {'])
5297
    self.assertEquals(len(self.nesting_state.stack), 1)
5298
    self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo))
5299
    self.assertEquals(self.nesting_state.stack[0].name, 'K')
5300

    
5301
  def testTemplateInnerClass(self):
5302
    self.UpdateWithLines(['class A {',
5303
                          ' public:'])
5304
    self.assertEquals(len(self.nesting_state.stack), 1)
5305
    self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo))
5306

    
5307
    self.UpdateWithLines(['  template <class B>',
5308
                          '  class C<alloc<B> >',
5309
                          '      : public A {'])
5310
    self.assertEquals(len(self.nesting_state.stack), 2)
5311
    self.assertTrue(isinstance(self.nesting_state.stack[1], cpplint._ClassInfo))
5312

    
5313
  def testArguments(self):
5314
    self.UpdateWithLines(['class A {'])
5315
    self.assertEquals(len(self.nesting_state.stack), 1)
5316
    self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo))
5317
    self.assertEquals(self.nesting_state.stack[0].name, 'A')
5318
    self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 0)
5319

    
5320
    self.UpdateWithLines(['  void Func(',
5321
                          '    struct X arg1,'])
5322
    self.assertEquals(len(self.nesting_state.stack), 1)
5323
    self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 1)
5324
    self.UpdateWithLines(['    struct X *arg2);'])
5325
    self.assertEquals(len(self.nesting_state.stack), 1)
5326
    self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 0)
5327

    
5328
    self.UpdateWithLines(['};'])
5329
    self.assertEquals(len(self.nesting_state.stack), 0)
5330

    
5331
    self.UpdateWithLines(['struct B {'])
5332
    self.assertEquals(len(self.nesting_state.stack), 1)
5333
    self.assertTrue(isinstance(self.nesting_state.stack[0], cpplint._ClassInfo))
5334
    self.assertEquals(self.nesting_state.stack[0].name, 'B')
5335

    
5336
    self.UpdateWithLines(['#ifdef MACRO',
5337
                          '  void Func(',
5338
                          '    struct X arg1'])
5339
    self.assertEquals(len(self.nesting_state.stack), 1)
5340
    self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 1)
5341
    self.UpdateWithLines(['#else'])
5342

    
5343
    self.assertEquals(len(self.nesting_state.stack), 1)
5344
    self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 0)
5345
    self.UpdateWithLines(['  void Func(',
5346
                          '    struct X arg1'])
5347
    self.assertEquals(len(self.nesting_state.stack), 1)
5348
    self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 1)
5349

    
5350
    self.UpdateWithLines(['#endif'])
5351
    self.assertEquals(len(self.nesting_state.stack), 1)
5352
    self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 1)
5353
    self.UpdateWithLines(['    struct X *arg2);'])
5354
    self.assertEquals(len(self.nesting_state.stack), 1)
5355
    self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 0)
5356

    
5357
    self.UpdateWithLines(['};'])
5358
    self.assertEquals(len(self.nesting_state.stack), 0)
5359

    
5360
  def testInlineAssembly(self):
5361
    self.UpdateWithLines(['void CopyRow_SSE2(const uint8* src, uint8* dst,',
5362
                          '                  int count) {'])
5363
    self.assertEquals(len(self.nesting_state.stack), 1)
5364
    self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 0)
5365
    self.assertEquals(self.nesting_state.stack[-1].inline_asm, cpplint._NO_ASM)
5366

    
5367
    self.UpdateWithLines(['  asm volatile ('])
5368
    self.assertEquals(len(self.nesting_state.stack), 1)
5369
    self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 1)
5370
    self.assertEquals(self.nesting_state.stack[-1].inline_asm,
5371
                      cpplint._INSIDE_ASM)
5372

    
5373
    self.UpdateWithLines(['    "sub        %0,%1                         \\n"',
5374
                          '  "1:                                         \\n"',
5375
                          '    "movdqa    (%0),%%xmm0                    \\n"',
5376
                          '    "movdqa    0x10(%0),%%xmm1                \\n"',
5377
                          '    "movdqa    %%xmm0,(%0,%1)                 \\n"',
5378
                          '    "movdqa    %%xmm1,0x10(%0,%1)             \\n"',
5379
                          '    "lea       0x20(%0),%0                    \\n"',
5380
                          '    "sub       $0x20,%2                       \\n"',
5381
                          '    "jg        1b                             \\n"',
5382
                          '  : "+r"(src),   // %0',
5383
                          '    "+r"(dst),   // %1',
5384
                          '    "+r"(count)  // %2',
5385
                          '  :',
5386
                          '  : "memory", "cc"'])
5387
    self.assertEquals(len(self.nesting_state.stack), 1)
5388
    self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 1)
5389
    self.assertEquals(self.nesting_state.stack[-1].inline_asm,
5390
                      cpplint._INSIDE_ASM)
5391

    
5392
    self.UpdateWithLines(['#if defined(__SSE2__)',
5393
                          '    , "xmm0", "xmm1"'])
5394
    self.assertEquals(len(self.nesting_state.stack), 1)
5395
    self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 1)
5396
    self.assertEquals(self.nesting_state.stack[-1].inline_asm,
5397
                      cpplint._INSIDE_ASM)
5398

    
5399
    self.UpdateWithLines(['#endif'])
5400
    self.assertEquals(len(self.nesting_state.stack), 1)
5401
    self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 1)
5402
    self.assertEquals(self.nesting_state.stack[-1].inline_asm,
5403
                      cpplint._INSIDE_ASM)
5404

    
5405
    self.UpdateWithLines(['  );'])
5406
    self.assertEquals(len(self.nesting_state.stack), 1)
5407
    self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 0)
5408
    self.assertEquals(self.nesting_state.stack[-1].inline_asm, cpplint._END_ASM)
5409

    
5410
    self.UpdateWithLines(['__asm {'])
5411
    self.assertEquals(len(self.nesting_state.stack), 2)
5412
    self.assertEquals(self.nesting_state.stack[-1].open_parentheses, 0)
5413
    self.assertEquals(self.nesting_state.stack[-1].inline_asm,
5414
                      cpplint._BLOCK_ASM)
5415

    
5416
    self.UpdateWithLines(['}'])
5417
    self.assertEquals(len(self.nesting_state.stack), 1)
5418

    
5419
    self.UpdateWithLines(['}'])
5420
    self.assertEquals(len(self.nesting_state.stack), 0)
5421

    
5422

    
5423
# pylint: disable-msg=C6409
5424
def setUp():
5425
  """Runs before all tests are executed.
5426
  """
5427
  # Enable all filters, so we don't miss anything that is off by default.
5428
  cpplint._DEFAULT_FILTERS = []
5429
  cpplint._cpplint_state.SetFilters('')
5430

    
5431

    
5432
# pylint: disable-msg=C6409
5433
def tearDown():
5434
  """A global check to make sure all error-categories have been tested.
5435

5436
  The main tearDown() routine is the only code we can guarantee will be
5437
  run after all other tests have been executed.
5438
  """
5439
  try:
5440
    if _run_verifyallcategoriesseen:
5441
      ErrorCollector(None).VerifyAllCategoriesAreSeen()
5442
  except NameError:
5443
    # If nobody set the global _run_verifyallcategoriesseen, then
5444
    # we assume we should silently not run the test
5445
    pass
5446

    
5447

    
5448
if __name__ == '__main__':
5449
  # We don't want to run the VerifyAllCategoriesAreSeen() test unless
5450
  # we're running the full test suite: if we only run one test,
5451
  # obviously we're not going to see all the error categories.  So we
5452
  # only run VerifyAllCategoriesAreSeen() when no commandline flags
5453
  # are passed in.
5454
  global _run_verifyallcategoriesseen
5455
  _run_verifyallcategoriesseen = (len(sys.argv) == 1)
5456

    
5457
  setUp()
5458
  unittest.main()
5459
  tearDown()