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