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