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