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