1#!/usr/bin/python 2# -*- coding: utf-8; -*- 3# 4# Copyright (C) 2009 Google Inc. All rights reserved. 5# Copyright (C) 2009 Torch Mobile Inc. 6# 7# Redistribution and use in source and binary forms, with or without 8# modification, are permitted provided that the following conditions are 9# met: 10# 11# * Redistributions of source code must retain the above copyright 12# notice, this list of conditions and the following disclaimer. 13# * Redistributions in binary form must reproduce the above 14# copyright notice, this list of conditions and the following disclaimer 15# in the documentation and/or other materials provided with the 16# distribution. 17# * Neither the name of Google Inc. nor the names of its 18# contributors may be used to endorse or promote products derived from 19# this software without specific prior written permission. 20# 21# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 33"""Unit test for cpp_style.py.""" 34 35# FIXME: Add a good test that tests UpdateIncludeState. 36 37import codecs 38import os 39import random 40import re 41import unittest 42import cpp_style 43 44 45# This class works as an error collector and replaces cpp_style.Error 46# function for the unit tests. We also verify each category we see 47# is in cpp_style._ERROR_CATEGORIES, to help keep that list up to date. 48class ErrorCollector: 49 # These are a global list, covering all categories seen ever. 50 _ERROR_CATEGORIES = [x.strip() # get rid of leading whitespace 51 for x in cpp_style._ERROR_CATEGORIES.split()] 52 _SEEN_ERROR_CATEGORIES = {} 53 54 def __init__(self, assert_fn): 55 """assert_fn: a function to call when we notice a problem.""" 56 self._assert_fn = assert_fn 57 self._errors = [] 58 59 def __call__(self, unused_filename, unused_linenum, 60 category, confidence, message): 61 self._assert_fn(category in self._ERROR_CATEGORIES, 62 'Message "%s" has category "%s",' 63 ' which is not in _ERROR_CATEGORIES' % (message, category)) 64 self._SEEN_ERROR_CATEGORIES[category] = 1 65 if cpp_style._should_print_error(category, confidence): 66 self._errors.append('%s [%s] [%d]' % (message, category, confidence)) 67 68 def results(self): 69 if len(self._errors) < 2: 70 return ''.join(self._errors) # Most tests expect to have a string. 71 else: 72 return self._errors # Let's give a list if there is more than one. 73 74 def result_list(self): 75 return self._errors 76 77 def verify_all_categories_are_seen(self): 78 """Fails if there's a category in _ERROR_CATEGORIES - _SEEN_ERROR_CATEGORIES. 79 80 This should only be called after all tests are run, so 81 _SEEN_ERROR_CATEGORIES has had a chance to fully populate. Since 82 this isn't called from within the normal unittest framework, we 83 can't use the normal unittest assert macros. Instead we just exit 84 when we see an error. Good thing this test is always run last! 85 """ 86 for category in self._ERROR_CATEGORIES: 87 if category not in self._SEEN_ERROR_CATEGORIES: 88 import sys 89 sys.exit('FATAL ERROR: There are no tests for category "%s"' % category) 90 91 def remove_if_present(self, substr): 92 for (index, error) in enumerate(self._errors): 93 if error.find(substr) != -1: 94 self._errors = self._errors[0:index] + self._errors[(index + 1):] 95 break 96 97 98# This class is a lame mock of codecs. We do not verify filename, mode, or 99# encoding, but for the current use case it is not needed. 100class MockIo: 101 def __init__(self, mock_file): 102 self.mock_file = mock_file 103 104 def open(self, unused_filename, unused_mode, unused_encoding, _): # NOLINT 105 # (lint doesn't like open as a method name) 106 return self.mock_file 107 108 109class CppStyleTestBase(unittest.TestCase): 110 """Provides some useful helper functions for cpp_style tests.""" 111 112 # Perform lint on single line of input and return the error message. 113 def perform_single_line_lint(self, code, file_name): 114 error_collector = ErrorCollector(self.assert_) 115 lines = code.split('\n') 116 cpp_style.remove_multi_line_comments(file_name, lines, error_collector) 117 clean_lines = cpp_style.CleansedLines(lines) 118 include_state = cpp_style._IncludeState() 119 function_state = cpp_style._FunctionState() 120 ext = file_name[file_name.rfind('.') + 1:] 121 class_state = cpp_style._ClassState() 122 cpp_style.process_line(file_name, ext, clean_lines, 0, 123 include_state, function_state, 124 class_state, error_collector) 125 # Single-line lint tests are allowed to fail the 'unlintable function' 126 # check. 127 error_collector.remove_if_present( 128 'Lint failed to find start of function body.') 129 return error_collector.results() 130 131 # Perform lint over multiple lines and return the error message. 132 def perform_multi_line_lint(self, code, file_name): 133 error_collector = ErrorCollector(self.assert_) 134 lines = code.split('\n') 135 cpp_style.remove_multi_line_comments(file_name, lines, error_collector) 136 lines = cpp_style.CleansedLines(lines) 137 ext = file_name[file_name.rfind('.') + 1:] 138 class_state = cpp_style._ClassState() 139 for i in xrange(lines.num_lines()): 140 cpp_style.check_style(file_name, lines, i, ext, error_collector) 141 cpp_style.check_for_non_standard_constructs(file_name, lines, i, class_state, 142 error_collector) 143 class_state.check_finished(file_name, error_collector) 144 return error_collector.results() 145 146 # Similar to perform_multi_line_lint, but calls check_language instead of 147 # check_for_non_standard_constructs 148 def perform_language_rules_check(self, file_name, code): 149 error_collector = ErrorCollector(self.assert_) 150 include_state = cpp_style._IncludeState() 151 lines = code.split('\n') 152 cpp_style.remove_multi_line_comments(file_name, lines, error_collector) 153 lines = cpp_style.CleansedLines(lines) 154 ext = file_name[file_name.rfind('.') + 1:] 155 for i in xrange(lines.num_lines()): 156 cpp_style.check_language(file_name, lines, i, ext, include_state, 157 error_collector) 158 return error_collector.results() 159 160 def perform_function_lengths_check(self, code): 161 """Perform Lint function length check on block of code and return warnings. 162 163 Builds up an array of lines corresponding to the code and strips comments 164 using cpp_style functions. 165 166 Establishes an error collector and invokes the function length checking 167 function following cpp_style's pattern. 168 169 Args: 170 code: C++ source code expected to generate a warning message. 171 172 Returns: 173 The accumulated errors. 174 """ 175 file_name = 'foo.cpp' 176 error_collector = ErrorCollector(self.assert_) 177 function_state = cpp_style._FunctionState() 178 lines = code.split('\n') 179 cpp_style.remove_multi_line_comments(file_name, lines, error_collector) 180 lines = cpp_style.CleansedLines(lines) 181 for i in xrange(lines.num_lines()): 182 cpp_style.check_for_function_lengths(file_name, lines, i, 183 function_state, error_collector) 184 return error_collector.results() 185 186 def perform_include_what_you_use(self, code, filename='foo.h', io=codecs): 187 # First, build up the include state. 188 error_collector = ErrorCollector(self.assert_) 189 include_state = cpp_style._IncludeState() 190 lines = code.split('\n') 191 cpp_style.remove_multi_line_comments(filename, lines, error_collector) 192 lines = cpp_style.CleansedLines(lines) 193 for i in xrange(lines.num_lines()): 194 cpp_style.check_language(filename, lines, i, '.h', include_state, 195 error_collector) 196 # We could clear the error_collector here, but this should 197 # also be fine, since our IncludeWhatYouUse unittests do not 198 # have language problems. 199 200 # Second, look for missing includes. 201 cpp_style.check_for_include_what_you_use(filename, lines, include_state, 202 error_collector, io) 203 return error_collector.results() 204 205 # Perform lint and compare the error message with "expected_message". 206 def assert_lint(self, code, expected_message, file_name='foo.cpp'): 207 self.assertEquals(expected_message, self.perform_single_line_lint(code, file_name)) 208 209 def assert_lint_one_of_many_errors_re(self, code, expected_message_re, file_name='foo.cpp'): 210 messages = self.perform_single_line_lint(code, file_name) 211 for message in messages: 212 if re.search(expected_message_re, message): 213 return 214 215 self.assertEquals(expected_message, messages) 216 217 def assert_multi_line_lint(self, code, expected_message, file_name='foo.h'): 218 self.assertEquals(expected_message, self.perform_multi_line_lint(code, file_name)) 219 220 def assert_multi_line_lint_re(self, code, expected_message_re, file_name='foo.h'): 221 message = self.perform_multi_line_lint(code, file_name) 222 if not re.search(expected_message_re, message): 223 self.fail('Message was:\n' + message + 'Expected match to "' + expected_message_re + '"') 224 225 def assert_language_rules_check(self, file_name, code, expected_message): 226 self.assertEquals(expected_message, 227 self.perform_language_rules_check(file_name, code)) 228 229 def assert_include_what_you_use(self, code, expected_message): 230 self.assertEquals(expected_message, 231 self.perform_include_what_you_use(code)) 232 233 def assert_blank_lines_check(self, lines, start_errors, end_errors): 234 error_collector = ErrorCollector(self.assert_) 235 cpp_style.process_file_data('foo.cpp', 'cpp', lines, error_collector) 236 self.assertEquals( 237 start_errors, 238 error_collector.results().count( 239 'Blank line at the start of a code block. Is this needed?' 240 ' [whitespace/blank_line] [2]')) 241 self.assertEquals( 242 end_errors, 243 error_collector.results().count( 244 'Blank line at the end of a code block. Is this needed?' 245 ' [whitespace/blank_line] [3]')) 246 247 248class CppStyleTest(CppStyleTestBase): 249 250 # Test get line width. 251 def test_get_line_width(self): 252 self.assertEquals(0, cpp_style.get_line_width('')) 253 self.assertEquals(10, cpp_style.get_line_width(u'x' * 10)) 254 self.assertEquals(16, cpp_style.get_line_width(u'都|道|府|県|支庁')) 255 256 def test_find_next_multi_line_comment_start(self): 257 self.assertEquals(1, cpp_style.find_next_multi_line_comment_start([''], 0)) 258 259 lines = ['a', 'b', '/* c'] 260 self.assertEquals(2, cpp_style.find_next_multi_line_comment_start(lines, 0)) 261 262 lines = ['char a[] = "/*";'] # not recognized as comment. 263 self.assertEquals(1, cpp_style.find_next_multi_line_comment_start(lines, 0)) 264 265 def test_find_next_multi_line_comment_end(self): 266 self.assertEquals(1, cpp_style.find_next_multi_line_comment_end([''], 0)) 267 lines = ['a', 'b', ' c */'] 268 self.assertEquals(2, cpp_style.find_next_multi_line_comment_end(lines, 0)) 269 270 def test_remove_multi_line_comments_from_range(self): 271 lines = ['a', ' /* comment ', ' * still comment', ' comment */ ', 'b'] 272 cpp_style.remove_multi_line_comments_from_range(lines, 1, 4) 273 self.assertEquals(['a', '// dummy', '// dummy', '// dummy', 'b'], lines) 274 275 def test_spaces_at_end_of_line(self): 276 self.assert_lint( 277 '// Hello there ', 278 'Line ends in whitespace. Consider deleting these extra spaces.' 279 ' [whitespace/end_of_line] [4]') 280 281 # Test C-style cast cases. 282 def test_cstyle_cast(self): 283 self.assert_lint( 284 'int a = (int)1.0;', 285 'Using C-style cast. Use static_cast<int>(...) instead' 286 ' [readability/casting] [4]') 287 self.assert_lint( 288 'int *a = (int *)DEFINED_VALUE;', 289 'Using C-style cast. Use reinterpret_cast<int *>(...) instead' 290 ' [readability/casting] [4]', 'foo.c') 291 self.assert_lint( 292 'uint16 a = (uint16)1.0;', 293 'Using C-style cast. Use static_cast<uint16>(...) instead' 294 ' [readability/casting] [4]') 295 self.assert_lint( 296 'int32 a = (int32)1.0;', 297 'Using C-style cast. Use static_cast<int32>(...) instead' 298 ' [readability/casting] [4]') 299 self.assert_lint( 300 'uint64 a = (uint64)1.0;', 301 'Using C-style cast. Use static_cast<uint64>(...) instead' 302 ' [readability/casting] [4]') 303 304 # Test taking address of casts (runtime/casting) 305 def test_runtime_casting(self): 306 self.assert_lint( 307 'int* x = &static_cast<int*>(foo);', 308 'Are you taking an address of a cast? ' 309 'This is dangerous: could be a temp var. ' 310 'Take the address before doing the cast, rather than after' 311 ' [runtime/casting] [4]') 312 313 self.assert_lint( 314 'int* x = &dynamic_cast<int *>(foo);', 315 ['Are you taking an address of a cast? ' 316 'This is dangerous: could be a temp var. ' 317 'Take the address before doing the cast, rather than after' 318 ' [runtime/casting] [4]', 319 'Do not use dynamic_cast<>. If you need to cast within a class ' 320 'hierarchy, use static_cast<> to upcast. Google doesn\'t support ' 321 'RTTI. [runtime/rtti] [5]']) 322 323 self.assert_lint( 324 'int* x = &reinterpret_cast<int *>(foo);', 325 'Are you taking an address of a cast? ' 326 'This is dangerous: could be a temp var. ' 327 'Take the address before doing the cast, rather than after' 328 ' [runtime/casting] [4]') 329 330 # It's OK to cast an address. 331 self.assert_lint( 332 'int* x = reinterpret_cast<int *>(&foo);', 333 '') 334 335 def test_runtime_selfinit(self): 336 self.assert_lint( 337 'Foo::Foo(Bar r, Bel l) : r_(r_), l_(l_) { }', 338 'You seem to be initializing a member variable with itself.' 339 ' [runtime/init] [4]') 340 self.assert_lint( 341 'Foo::Foo(Bar r, Bel l) : r_(r), l_(l) { }', 342 '') 343 self.assert_lint( 344 'Foo::Foo(Bar r) : r_(r), l_(r_), ll_(l_) { }', 345 '') 346 347 def test_runtime_rtti(self): 348 statement = 'int* x = dynamic_cast<int*>(&foo);' 349 error_message = ( 350 'Do not use dynamic_cast<>. If you need to cast within a class ' 351 'hierarchy, use static_cast<> to upcast. Google doesn\'t support ' 352 'RTTI. [runtime/rtti] [5]') 353 # dynamic_cast is disallowed in most files. 354 self.assert_language_rules_check('foo.cpp', statement, error_message) 355 self.assert_language_rules_check('foo.h', statement, error_message) 356 # It is explicitly allowed in tests, however. 357 self.assert_language_rules_check('foo_test.cpp', statement, '') 358 self.assert_language_rules_check('foo_unittest.cpp', statement, '') 359 self.assert_language_rules_check('foo_regtest.cpp', statement, '') 360 361 # We cannot test this functionality because of difference of 362 # function definitions. Anyway, we may never enable this. 363 # 364 # # Test for unnamed arguments in a method. 365 # def test_check_for_unnamed_params(self): 366 # message = ('All parameters should be named in a function' 367 # ' [readability/function] [3]') 368 # self.assert_lint('virtual void A(int*) const;', message) 369 # self.assert_lint('virtual void B(void (*fn)(int*));', message) 370 # self.assert_lint('virtual void C(int*);', message) 371 # self.assert_lint('void *(*f)(void *) = x;', message) 372 # self.assert_lint('void Method(char*) {', message) 373 # self.assert_lint('void Method(char*);', message) 374 # self.assert_lint('void Method(char* /*x*/);', message) 375 # self.assert_lint('typedef void (*Method)(int32);', message) 376 # self.assert_lint('static void operator delete[](void*) throw();', message) 377 # 378 # self.assert_lint('virtual void D(int* p);', '') 379 # self.assert_lint('void operator delete(void* x) throw();', '') 380 # self.assert_lint('void Method(char* x)\n{', '') 381 # self.assert_lint('void Method(char* /*x*/)\n{', '') 382 # self.assert_lint('void Method(char* x);', '') 383 # self.assert_lint('typedef void (*Method)(int32 x);', '') 384 # self.assert_lint('static void operator delete[](void* x) throw();', '') 385 # self.assert_lint('static void operator delete[](void* /*x*/) throw();', '') 386 # 387 # # This one should technically warn, but doesn't because the function 388 # # pointer is confusing. 389 # self.assert_lint('virtual void E(void (*fn)(int* p));', '') 390 391 # Test deprecated casts such as int(d) 392 def test_deprecated_cast(self): 393 self.assert_lint( 394 'int a = int(2.2);', 395 'Using deprecated casting style. ' 396 'Use static_cast<int>(...) instead' 397 ' [readability/casting] [4]') 398 # Checks for false positives... 399 self.assert_lint( 400 'int a = int(); // Constructor, o.k.', 401 '') 402 self.assert_lint( 403 'X::X() : a(int()) {} // default Constructor, o.k.', 404 '') 405 self.assert_lint( 406 'operator bool(); // Conversion operator, o.k.', 407 '') 408 409 # The second parameter to a gMock method definition is a function signature 410 # that often looks like a bad cast but should not picked up by lint. 411 def test_mock_method(self): 412 self.assert_lint( 413 'MOCK_METHOD0(method, int());', 414 '') 415 self.assert_lint( 416 'MOCK_CONST_METHOD1(method, float(string));', 417 '') 418 self.assert_lint( 419 'MOCK_CONST_METHOD2_T(method, double(float, float));', 420 '') 421 422 # Test sizeof(type) cases. 423 def test_sizeof_type(self): 424 self.assert_lint( 425 'sizeof(int);', 426 'Using sizeof(type). Use sizeof(varname) instead if possible' 427 ' [runtime/sizeof] [1]') 428 self.assert_lint( 429 'sizeof(int *);', 430 'Using sizeof(type). Use sizeof(varname) instead if possible' 431 ' [runtime/sizeof] [1]') 432 433 # Test typedef cases. There was a bug that cpp_style misidentified 434 # typedef for pointer to function as C-style cast and produced 435 # false-positive error messages. 436 def test_typedef_for_pointer_to_function(self): 437 self.assert_lint( 438 'typedef void (*Func)(int x);', 439 '') 440 self.assert_lint( 441 'typedef void (*Func)(int *x);', 442 '') 443 self.assert_lint( 444 'typedef void Func(int x);', 445 '') 446 self.assert_lint( 447 'typedef void Func(int *x);', 448 '') 449 450 def test_include_what_you_use_no_implementation_files(self): 451 code = 'std::vector<int> foo;' 452 self.assertEquals('Add #include <vector> for vector<>' 453 ' [build/include_what_you_use] [4]', 454 self.perform_include_what_you_use(code, 'foo.h')) 455 self.assertEquals('', 456 self.perform_include_what_you_use(code, 'foo.cpp')) 457 458 def test_include_what_you_use(self): 459 self.assert_include_what_you_use( 460 '''#include <vector> 461 std::vector<int> foo; 462 ''', 463 '') 464 self.assert_include_what_you_use( 465 '''#include <map> 466 std::pair<int,int> foo; 467 ''', 468 '') 469 self.assert_include_what_you_use( 470 '''#include <multimap> 471 std::pair<int,int> foo; 472 ''', 473 '') 474 self.assert_include_what_you_use( 475 '''#include <hash_map> 476 std::pair<int,int> foo; 477 ''', 478 '') 479 self.assert_include_what_you_use( 480 '''#include <utility> 481 std::pair<int,int> foo; 482 ''', 483 '') 484 self.assert_include_what_you_use( 485 '''#include <vector> 486 DECLARE_string(foobar); 487 ''', 488 '') 489 self.assert_include_what_you_use( 490 '''#include <vector> 491 DEFINE_string(foobar, "", ""); 492 ''', 493 '') 494 self.assert_include_what_you_use( 495 '''#include <vector> 496 std::pair<int,int> foo; 497 ''', 498 'Add #include <utility> for pair<>' 499 ' [build/include_what_you_use] [4]') 500 self.assert_include_what_you_use( 501 '''#include "base/foobar.h" 502 std::vector<int> foo; 503 ''', 504 'Add #include <vector> for vector<>' 505 ' [build/include_what_you_use] [4]') 506 self.assert_include_what_you_use( 507 '''#include <vector> 508 std::set<int> foo; 509 ''', 510 'Add #include <set> for set<>' 511 ' [build/include_what_you_use] [4]') 512 self.assert_include_what_you_use( 513 '''#include "base/foobar.h" 514 hash_map<int, int> foobar; 515 ''', 516 'Add #include <hash_map> for hash_map<>' 517 ' [build/include_what_you_use] [4]') 518 self.assert_include_what_you_use( 519 '''#include "base/foobar.h" 520 bool foobar = std::less<int>(0,1); 521 ''', 522 'Add #include <functional> for less<>' 523 ' [build/include_what_you_use] [4]') 524 self.assert_include_what_you_use( 525 '''#include "base/foobar.h" 526 bool foobar = min<int>(0,1); 527 ''', 528 'Add #include <algorithm> for min [build/include_what_you_use] [4]') 529 self.assert_include_what_you_use( 530 'void a(const string &foobar);', 531 'Add #include <string> for string [build/include_what_you_use] [4]') 532 self.assert_include_what_you_use( 533 '''#include "base/foobar.h" 534 bool foobar = swap(0,1); 535 ''', 536 'Add #include <algorithm> for swap [build/include_what_you_use] [4]') 537 self.assert_include_what_you_use( 538 '''#include "base/foobar.h" 539 bool foobar = transform(a.begin(), a.end(), b.start(), Foo); 540 ''', 541 'Add #include <algorithm> for transform ' 542 '[build/include_what_you_use] [4]') 543 self.assert_include_what_you_use( 544 '''#include "base/foobar.h" 545 bool foobar = min_element(a.begin(), a.end()); 546 ''', 547 'Add #include <algorithm> for min_element ' 548 '[build/include_what_you_use] [4]') 549 self.assert_include_what_you_use( 550 '''foo->swap(0,1); 551 foo.swap(0,1); 552 ''', 553 '') 554 self.assert_include_what_you_use( 555 '''#include <string> 556 void a(const std::multimap<int,string> &foobar); 557 ''', 558 'Add #include <map> for multimap<>' 559 ' [build/include_what_you_use] [4]') 560 self.assert_include_what_you_use( 561 '''#include <queue> 562 void a(const std::priority_queue<int> &foobar); 563 ''', 564 '') 565 self.assert_include_what_you_use( 566 '''#include "base/basictypes.h" 567 #include "base/port.h" 568 #include <assert.h> 569 #include <string> 570 #include <vector> 571 vector<string> hajoa;''', '') 572 self.assert_include_what_you_use( 573 '''#include <string> 574 int i = numeric_limits<int>::max() 575 ''', 576 'Add #include <limits> for numeric_limits<>' 577 ' [build/include_what_you_use] [4]') 578 self.assert_include_what_you_use( 579 '''#include <limits> 580 int i = numeric_limits<int>::max() 581 ''', 582 '') 583 584 # Test the UpdateIncludeState code path. 585 mock_header_contents = ['#include "blah/foo.h"', '#include "blah/bar.h"'] 586 message = self.perform_include_what_you_use( 587 '#include "config.h"\n' 588 '#include "blah/a.h"\n', 589 filename='blah/a.cpp', 590 io=MockIo(mock_header_contents)) 591 self.assertEquals(message, '') 592 593 mock_header_contents = ['#include <set>'] 594 message = self.perform_include_what_you_use( 595 '''#include "config.h" 596 #include "blah/a.h" 597 598 std::set<int> foo;''', 599 filename='blah/a.cpp', 600 io=MockIo(mock_header_contents)) 601 self.assertEquals(message, '') 602 603 # If there's just a .cpp and the header can't be found then it's ok. 604 message = self.perform_include_what_you_use( 605 '''#include "config.h" 606 #include "blah/a.h" 607 608 std::set<int> foo;''', 609 filename='blah/a.cpp') 610 self.assertEquals(message, '') 611 612 # Make sure we find the headers with relative paths. 613 mock_header_contents = [''] 614 message = self.perform_include_what_you_use( 615 '''#include "config.h" 616 #include "%s/a.h" 617 618 std::set<int> foo;''' % os.path.basename(os.getcwd()), 619 filename='a.cpp', 620 io=MockIo(mock_header_contents)) 621 self.assertEquals(message, 'Add #include <set> for set<> ' 622 '[build/include_what_you_use] [4]') 623 624 def test_files_belong_to_same_module(self): 625 f = cpp_style.files_belong_to_same_module 626 self.assertEquals((True, ''), f('a.cpp', 'a.h')) 627 self.assertEquals((True, ''), f('base/google.cpp', 'base/google.h')) 628 self.assertEquals((True, ''), f('base/google_test.cpp', 'base/google.h')) 629 self.assertEquals((True, ''), 630 f('base/google_unittest.cpp', 'base/google.h')) 631 self.assertEquals((True, ''), 632 f('base/internal/google_unittest.cpp', 633 'base/public/google.h')) 634 self.assertEquals((True, 'xxx/yyy/'), 635 f('xxx/yyy/base/internal/google_unittest.cpp', 636 'base/public/google.h')) 637 self.assertEquals((True, 'xxx/yyy/'), 638 f('xxx/yyy/base/google_unittest.cpp', 639 'base/public/google.h')) 640 self.assertEquals((True, ''), 641 f('base/google_unittest.cpp', 'base/google-inl.h')) 642 self.assertEquals((True, '/home/build/google3/'), 643 f('/home/build/google3/base/google.cpp', 'base/google.h')) 644 645 self.assertEquals((False, ''), 646 f('/home/build/google3/base/google.cpp', 'basu/google.h')) 647 self.assertEquals((False, ''), f('a.cpp', 'b.h')) 648 649 def test_cleanse_line(self): 650 self.assertEquals('int foo = 0; ', 651 cpp_style.cleanse_comments('int foo = 0; // danger!')) 652 self.assertEquals('int o = 0;', 653 cpp_style.cleanse_comments('int /* foo */ o = 0;')) 654 self.assertEquals('foo(int a, int b);', 655 cpp_style.cleanse_comments('foo(int a /* abc */, int b);')) 656 self.assertEqual('f(a, b);', 657 cpp_style.cleanse_comments('f(a, /* name */ b);')) 658 self.assertEqual('f(a, b);', 659 cpp_style.cleanse_comments('f(a /* name */, b);')) 660 self.assertEqual('f(a, b);', 661 cpp_style.cleanse_comments('f(a, /* name */b);')) 662 663 def test_multi_line_comments(self): 664 # missing explicit is bad 665 self.assert_multi_line_lint( 666 r'''int a = 0; 667 /* multi-liner 668 class Foo { 669 Foo(int f); // should cause a lint warning in code 670 } 671 */ ''', 672 '') 673 self.assert_multi_line_lint( 674 r'''/* int a = 0; multi-liner 675 static const int b = 0;''', 676 'Could not find end of multi-line comment' 677 ' [readability/multiline_comment] [5]') 678 self.assert_multi_line_lint(r''' /* multi-line comment''', 679 'Could not find end of multi-line comment' 680 ' [readability/multiline_comment] [5]') 681 self.assert_multi_line_lint(r''' // /* comment, but not multi-line''', '') 682 683 def test_multiline_strings(self): 684 multiline_string_error_message = ( 685 'Multi-line string ("...") found. This lint script doesn\'t ' 686 'do well with such strings, and may give bogus warnings. They\'re ' 687 'ugly and unnecessary, and you should use concatenation instead".' 688 ' [readability/multiline_string] [5]') 689 690 file_path = 'mydir/foo.cpp' 691 692 error_collector = ErrorCollector(self.assert_) 693 cpp_style.process_file_data(file_path, 'cpp', 694 ['const char* str = "This is a\\', 695 ' multiline string.";'], 696 error_collector) 697 self.assertEquals( 698 2, # One per line. 699 error_collector.result_list().count(multiline_string_error_message)) 700 701 # Test non-explicit single-argument constructors 702 def test_explicit_single_argument_constructors(self): 703 # missing explicit is bad 704 self.assert_multi_line_lint( 705 '''class Foo { 706 Foo(int f); 707 };''', 708 'Single-argument constructors should be marked explicit.' 709 ' [runtime/explicit] [5]') 710 # missing explicit is bad, even with whitespace 711 self.assert_multi_line_lint( 712 '''class Foo { 713 Foo (int f); 714 };''', 715 ['Extra space before ( in function call [whitespace/parens] [4]', 716 'Single-argument constructors should be marked explicit.' 717 ' [runtime/explicit] [5]']) 718 # missing explicit, with distracting comment, is still bad 719 self.assert_multi_line_lint( 720 '''class Foo { 721 Foo(int f); // simpler than Foo(blargh, blarg) 722 };''', 723 'Single-argument constructors should be marked explicit.' 724 ' [runtime/explicit] [5]') 725 # missing explicit, with qualified classname 726 self.assert_multi_line_lint( 727 '''class Qualifier::AnotherOne::Foo { 728 Foo(int f); 729 };''', 730 'Single-argument constructors should be marked explicit.' 731 ' [runtime/explicit] [5]') 732 # structs are caught as well. 733 self.assert_multi_line_lint( 734 '''struct Foo { 735 Foo(int f); 736 };''', 737 'Single-argument constructors should be marked explicit.' 738 ' [runtime/explicit] [5]') 739 # Templatized classes are caught as well. 740 self.assert_multi_line_lint( 741 '''template<typename T> class Foo { 742 Foo(int f); 743 };''', 744 'Single-argument constructors should be marked explicit.' 745 ' [runtime/explicit] [5]') 746 # proper style is okay 747 self.assert_multi_line_lint( 748 '''class Foo { 749 explicit Foo(int f); 750 };''', 751 '') 752 # two argument constructor is okay 753 self.assert_multi_line_lint( 754 '''class Foo { 755 Foo(int f, int b); 756 };''', 757 '') 758 # two argument constructor, across two lines, is okay 759 self.assert_multi_line_lint( 760 '''class Foo { 761 Foo(int f, 762 int b); 763 };''', 764 '') 765 # non-constructor (but similar name), is okay 766 self.assert_multi_line_lint( 767 '''class Foo { 768 aFoo(int f); 769 };''', 770 '') 771 # constructor with void argument is okay 772 self.assert_multi_line_lint( 773 '''class Foo { 774 Foo(void); 775 };''', 776 '') 777 # single argument method is okay 778 self.assert_multi_line_lint( 779 '''class Foo { 780 Bar(int b); 781 };''', 782 '') 783 # comments should be ignored 784 self.assert_multi_line_lint( 785 '''class Foo { 786 // Foo(int f); 787 };''', 788 '') 789 # single argument function following class definition is okay 790 # (okay, it's not actually valid, but we don't want a false positive) 791 self.assert_multi_line_lint( 792 '''class Foo { 793 Foo(int f, int b); 794 }; 795 Foo(int f);''', 796 '') 797 # single argument function is okay 798 self.assert_multi_line_lint( 799 '''static Foo(int f);''', 800 '') 801 # single argument copy constructor is okay. 802 self.assert_multi_line_lint( 803 '''class Foo { 804 Foo(const Foo&); 805 };''', 806 '') 807 self.assert_multi_line_lint( 808 '''class Foo { 809 Foo(Foo&); 810 };''', 811 '') 812 813 def test_slash_star_comment_on_single_line(self): 814 self.assert_multi_line_lint( 815 '''/* static */ Foo(int f);''', 816 '') 817 self.assert_multi_line_lint( 818 '''/*/ static */ Foo(int f);''', 819 '') 820 self.assert_multi_line_lint( 821 '''/*/ static Foo(int f);''', 822 'Could not find end of multi-line comment' 823 ' [readability/multiline_comment] [5]') 824 self.assert_multi_line_lint( 825 ''' /*/ static Foo(int f);''', 826 'Could not find end of multi-line comment' 827 ' [readability/multiline_comment] [5]') 828 self.assert_multi_line_lint( 829 ''' /**/ static Foo(int f);''', 830 '') 831 832 # Test suspicious usage of "if" like this: 833 # if (a == b) { 834 # DoSomething(); 835 # } if (a == c) { // Should be "else if". 836 # DoSomething(); // This gets called twice if a == b && a == c. 837 # } 838 def test_suspicious_usage_of_if(self): 839 self.assert_lint( 840 ' if (a == b) {', 841 '') 842 self.assert_lint( 843 ' } if (a == b) {', 844 'Did you mean "else if"? If not, start a new line for "if".' 845 ' [readability/braces] [4]') 846 847 # Test suspicious usage of memset. Specifically, a 0 848 # as the final argument is almost certainly an error. 849 def test_suspicious_usage_of_memset(self): 850 # Normal use is okay. 851 self.assert_lint( 852 ' memset(buf, 0, sizeof(buf))', 853 '') 854 855 # A 0 as the final argument is almost certainly an error. 856 self.assert_lint( 857 ' memset(buf, sizeof(buf), 0)', 858 'Did you mean "memset(buf, 0, sizeof(buf))"?' 859 ' [runtime/memset] [4]') 860 self.assert_lint( 861 ' memset(buf, xsize * ysize, 0)', 862 'Did you mean "memset(buf, 0, xsize * ysize)"?' 863 ' [runtime/memset] [4]') 864 865 # There is legitimate test code that uses this form. 866 # This is okay since the second argument is a literal. 867 self.assert_lint( 868 " memset(buf, 'y', 0)", 869 '') 870 self.assert_lint( 871 ' memset(buf, 4, 0)', 872 '') 873 self.assert_lint( 874 ' memset(buf, -1, 0)', 875 '') 876 self.assert_lint( 877 ' memset(buf, 0xF1, 0)', 878 '') 879 self.assert_lint( 880 ' memset(buf, 0xcd, 0)', 881 '') 882 883 def test_check_posix_threading(self): 884 self.assert_lint('sctime_r()', '') 885 self.assert_lint('strtok_r()', '') 886 self.assert_lint(' strtok_r(foo, ba, r)', '') 887 self.assert_lint('brand()', '') 888 self.assert_lint('_rand()', '') 889 self.assert_lint('.rand()', '') 890 self.assert_lint('>rand()', '') 891 self.assert_lint('rand()', 892 'Consider using rand_r(...) instead of rand(...)' 893 ' for improved thread safety.' 894 ' [runtime/threadsafe_fn] [2]') 895 self.assert_lint('strtok()', 896 'Consider using strtok_r(...) ' 897 'instead of strtok(...)' 898 ' for improved thread safety.' 899 ' [runtime/threadsafe_fn] [2]') 900 901 # Test potential format string bugs like printf(foo). 902 def test_format_strings(self): 903 self.assert_lint('printf("foo")', '') 904 self.assert_lint('printf("foo: %s", foo)', '') 905 self.assert_lint('DocidForPrintf(docid)', '') # Should not trigger. 906 self.assert_lint( 907 'printf(foo)', 908 'Potential format string bug. Do printf("%s", foo) instead.' 909 ' [runtime/printf] [4]') 910 self.assert_lint( 911 'printf(foo.c_str())', 912 'Potential format string bug. ' 913 'Do printf("%s", foo.c_str()) instead.' 914 ' [runtime/printf] [4]') 915 self.assert_lint( 916 'printf(foo->c_str())', 917 'Potential format string bug. ' 918 'Do printf("%s", foo->c_str()) instead.' 919 ' [runtime/printf] [4]') 920 self.assert_lint( 921 'StringPrintf(foo)', 922 'Potential format string bug. Do StringPrintf("%s", foo) instead.' 923 '' 924 ' [runtime/printf] [4]') 925 926 # Variable-length arrays are not permitted. 927 def test_variable_length_array_detection(self): 928 errmsg = ('Do not use variable-length arrays. Use an appropriately named ' 929 "('k' followed by CamelCase) compile-time constant for the size." 930 ' [runtime/arrays] [1]') 931 932 self.assert_lint('int a[any_old_variable];', errmsg) 933 self.assert_lint('int doublesize[some_var * 2];', errmsg) 934 self.assert_lint('int a[afunction()];', errmsg) 935 self.assert_lint('int a[function(kMaxFooBars)];', errmsg) 936 self.assert_lint('bool a_list[items_->size()];', errmsg) 937 self.assert_lint('namespace::Type buffer[len+1];', errmsg) 938 939 self.assert_lint('int a[64];', '') 940 self.assert_lint('int a[0xFF];', '') 941 self.assert_lint('int first[256], second[256];', '') 942 self.assert_lint('int array_name[kCompileTimeConstant];', '') 943 self.assert_lint('char buf[somenamespace::kBufSize];', '') 944 self.assert_lint('int array_name[ALL_CAPS];', '') 945 self.assert_lint('AClass array1[foo::bar::ALL_CAPS];', '') 946 self.assert_lint('int a[kMaxStrLen + 1];', '') 947 self.assert_lint('int a[sizeof(foo)];', '') 948 self.assert_lint('int a[sizeof(*foo)];', '') 949 self.assert_lint('int a[sizeof foo];', '') 950 self.assert_lint('int a[sizeof(struct Foo)];', '') 951 self.assert_lint('int a[128 - sizeof(const bar)];', '') 952 self.assert_lint('int a[(sizeof(foo) * 4)];', '') 953 self.assert_lint('int a[(arraysize(fixed_size_array)/2) << 1];', '') 954 self.assert_lint('delete a[some_var];', '') 955 self.assert_lint('return a[some_var];', '') 956 957 # Brace usage 958 def test_braces(self): 959 # Braces shouldn't be followed by a ; unless they're defining a struct 960 # or initializing an array 961 self.assert_lint('int a[3] = { 1, 2, 3 };', '') 962 self.assert_lint( 963 '''const int foo[] = 964 {1, 2, 3 };''', 965 '') 966 # For single line, unmatched '}' with a ';' is ignored (not enough context) 967 self.assert_multi_line_lint( 968 '''int a[3] = { 1, 969 2, 970 3 };''', 971 '') 972 self.assert_multi_line_lint( 973 '''int a[2][3] = { { 1, 2 }, 974 { 3, 4 } };''', 975 '') 976 self.assert_multi_line_lint( 977 '''int a[2][3] = 978 { { 1, 2 }, 979 { 3, 4 } };''', 980 '') 981 982 # CHECK/EXPECT_TRUE/EXPECT_FALSE replacements 983 def test_check_check(self): 984 self.assert_lint('CHECK(x == 42)', 985 'Consider using CHECK_EQ instead of CHECK(a == b)' 986 ' [readability/check] [2]') 987 self.assert_lint('CHECK(x != 42)', 988 'Consider using CHECK_NE instead of CHECK(a != b)' 989 ' [readability/check] [2]') 990 self.assert_lint('CHECK(x >= 42)', 991 'Consider using CHECK_GE instead of CHECK(a >= b)' 992 ' [readability/check] [2]') 993 self.assert_lint('CHECK(x > 42)', 994 'Consider using CHECK_GT instead of CHECK(a > b)' 995 ' [readability/check] [2]') 996 self.assert_lint('CHECK(x <= 42)', 997 'Consider using CHECK_LE instead of CHECK(a <= b)' 998 ' [readability/check] [2]') 999 self.assert_lint('CHECK(x < 42)', 1000 'Consider using CHECK_LT instead of CHECK(a < b)' 1001 ' [readability/check] [2]') 1002 1003 self.assert_lint('DCHECK(x == 42)', 1004 'Consider using DCHECK_EQ instead of DCHECK(a == b)' 1005 ' [readability/check] [2]') 1006 self.assert_lint('DCHECK(x != 42)', 1007 'Consider using DCHECK_NE instead of DCHECK(a != b)' 1008 ' [readability/check] [2]') 1009 self.assert_lint('DCHECK(x >= 42)', 1010 'Consider using DCHECK_GE instead of DCHECK(a >= b)' 1011 ' [readability/check] [2]') 1012 self.assert_lint('DCHECK(x > 42)', 1013 'Consider using DCHECK_GT instead of DCHECK(a > b)' 1014 ' [readability/check] [2]') 1015 self.assert_lint('DCHECK(x <= 42)', 1016 'Consider using DCHECK_LE instead of DCHECK(a <= b)' 1017 ' [readability/check] [2]') 1018 self.assert_lint('DCHECK(x < 42)', 1019 'Consider using DCHECK_LT instead of DCHECK(a < b)' 1020 ' [readability/check] [2]') 1021 1022 self.assert_lint( 1023 'EXPECT_TRUE("42" == x)', 1024 'Consider using EXPECT_EQ instead of EXPECT_TRUE(a == b)' 1025 ' [readability/check] [2]') 1026 self.assert_lint( 1027 'EXPECT_TRUE("42" != x)', 1028 'Consider using EXPECT_NE instead of EXPECT_TRUE(a != b)' 1029 ' [readability/check] [2]') 1030 self.assert_lint( 1031 'EXPECT_TRUE(+42 >= x)', 1032 'Consider using EXPECT_GE instead of EXPECT_TRUE(a >= b)' 1033 ' [readability/check] [2]') 1034 self.assert_lint( 1035 'EXPECT_TRUE_M(-42 > x)', 1036 'Consider using EXPECT_GT_M instead of EXPECT_TRUE_M(a > b)' 1037 ' [readability/check] [2]') 1038 self.assert_lint( 1039 'EXPECT_TRUE_M(42U <= x)', 1040 'Consider using EXPECT_LE_M instead of EXPECT_TRUE_M(a <= b)' 1041 ' [readability/check] [2]') 1042 self.assert_lint( 1043 'EXPECT_TRUE_M(42L < x)', 1044 'Consider using EXPECT_LT_M instead of EXPECT_TRUE_M(a < b)' 1045 ' [readability/check] [2]') 1046 1047 self.assert_lint( 1048 'EXPECT_FALSE(x == 42)', 1049 'Consider using EXPECT_NE instead of EXPECT_FALSE(a == b)' 1050 ' [readability/check] [2]') 1051 self.assert_lint( 1052 'EXPECT_FALSE(x != 42)', 1053 'Consider using EXPECT_EQ instead of EXPECT_FALSE(a != b)' 1054 ' [readability/check] [2]') 1055 self.assert_lint( 1056 'EXPECT_FALSE(x >= 42)', 1057 'Consider using EXPECT_LT instead of EXPECT_FALSE(a >= b)' 1058 ' [readability/check] [2]') 1059 self.assert_lint( 1060 'ASSERT_FALSE(x > 42)', 1061 'Consider using ASSERT_LE instead of ASSERT_FALSE(a > b)' 1062 ' [readability/check] [2]') 1063 self.assert_lint( 1064 'ASSERT_FALSE(x <= 42)', 1065 'Consider using ASSERT_GT instead of ASSERT_FALSE(a <= b)' 1066 ' [readability/check] [2]') 1067 self.assert_lint( 1068 'ASSERT_FALSE_M(x < 42)', 1069 'Consider using ASSERT_GE_M instead of ASSERT_FALSE_M(a < b)' 1070 ' [readability/check] [2]') 1071 1072 self.assert_lint('CHECK(some_iterator == obj.end())', '') 1073 self.assert_lint('EXPECT_TRUE(some_iterator == obj.end())', '') 1074 self.assert_lint('EXPECT_FALSE(some_iterator == obj.end())', '') 1075 1076 self.assert_lint('CHECK(CreateTestFile(dir, (1 << 20)));', '') 1077 self.assert_lint('CHECK(CreateTestFile(dir, (1 >> 20)));', '') 1078 1079 self.assert_lint('CHECK(x<42)', 1080 ['Missing spaces around <' 1081 ' [whitespace/operators] [3]', 1082 'Consider using CHECK_LT instead of CHECK(a < b)' 1083 ' [readability/check] [2]']) 1084 self.assert_lint('CHECK(x>42)', 1085 'Consider using CHECK_GT instead of CHECK(a > b)' 1086 ' [readability/check] [2]') 1087 1088 self.assert_lint( 1089 ' EXPECT_TRUE(42 < x) // Random comment.', 1090 'Consider using EXPECT_LT instead of EXPECT_TRUE(a < b)' 1091 ' [readability/check] [2]') 1092 self.assert_lint( 1093 'EXPECT_TRUE( 42 < x )', 1094 ['Extra space after ( in function call' 1095 ' [whitespace/parens] [4]', 1096 'Consider using EXPECT_LT instead of EXPECT_TRUE(a < b)' 1097 ' [readability/check] [2]']) 1098 self.assert_lint( 1099 'CHECK("foo" == "foo")', 1100 'Consider using CHECK_EQ instead of CHECK(a == b)' 1101 ' [readability/check] [2]') 1102 1103 self.assert_lint('CHECK_EQ("foo", "foo")', '') 1104 1105 def test_brace_at_begin_of_line(self): 1106 self.assert_lint('{', 1107 'This { should be at the end of the previous line' 1108 ' [whitespace/braces] [4]') 1109 self.assert_multi_line_lint( 1110 '#endif\n' 1111 '{\n' 1112 '}\n', 1113 '') 1114 self.assert_multi_line_lint( 1115 'if (condition) {', 1116 '') 1117 self.assert_multi_line_lint( 1118 'int foo() {', 1119 'Place brace on its own line for function definitions. [whitespace/braces] [4]') 1120 self.assert_multi_line_lint( 1121 'int foo() const {', 1122 'Place brace on its own line for function definitions. [whitespace/braces] [4]') 1123 self.assert_multi_line_lint( 1124 'int foo() const\n' 1125 '{\n' 1126 '}\n', 1127 '') 1128 self.assert_multi_line_lint( 1129 'if (condition\n' 1130 ' && condition2\n' 1131 ' && condition3) {\n' 1132 '}\n', 1133 '') 1134 1135 def test_mismatching_spaces_in_parens(self): 1136 self.assert_lint('if (foo ) {', 'Mismatching spaces inside () in if' 1137 ' [whitespace/parens] [5]') 1138 self.assert_lint('switch ( foo) {', 'Mismatching spaces inside () in switch' 1139 ' [whitespace/parens] [5]') 1140 self.assert_lint('for (foo; ba; bar ) {', 'Mismatching spaces inside () in for' 1141 ' [whitespace/parens] [5]') 1142 self.assert_lint('for (; foo; bar) {', '') 1143 self.assert_lint('for ( ; foo; bar) {', '') 1144 self.assert_lint('for ( ; foo; bar ) {', '') 1145 self.assert_lint('for (foo; bar; ) {', '') 1146 self.assert_lint('foreach (foo, foos ) {', 'Mismatching spaces inside () in foreach' 1147 ' [whitespace/parens] [5]') 1148 self.assert_lint('foreach ( foo, foos) {', 'Mismatching spaces inside () in foreach' 1149 ' [whitespace/parens] [5]') 1150 self.assert_lint('while ( foo ) {', 'Should have zero or one spaces inside' 1151 ' ( and ) in while [whitespace/parens] [5]') 1152 1153 def test_spacing_for_fncall(self): 1154 self.assert_lint('if (foo) {', '') 1155 self.assert_lint('for (foo;bar;baz) {', '') 1156 self.assert_lint('foreach (foo, foos) {', '') 1157 self.assert_lint('while (foo) {', '') 1158 self.assert_lint('switch (foo) {', '') 1159 self.assert_lint('new (RenderArena()) RenderInline(document())', '') 1160 self.assert_lint('foo( bar)', 'Extra space after ( in function call' 1161 ' [whitespace/parens] [4]') 1162 self.assert_lint('foobar( \\', '') 1163 self.assert_lint('foobar( \\', '') 1164 self.assert_lint('( a + b)', 'Extra space after (' 1165 ' [whitespace/parens] [2]') 1166 self.assert_lint('((a+b))', '') 1167 self.assert_lint('foo (foo)', 'Extra space before ( in function call' 1168 ' [whitespace/parens] [4]') 1169 self.assert_lint('typedef foo (*foo)(foo)', '') 1170 self.assert_lint('typedef foo (*foo12bar_)(foo)', '') 1171 self.assert_lint('typedef foo (Foo::*bar)(foo)', '') 1172 self.assert_lint('foo (Foo::*bar)(', 1173 'Extra space before ( in function call' 1174 ' [whitespace/parens] [4]') 1175 self.assert_lint('typedef foo (Foo::*bar)(', '') 1176 self.assert_lint('(foo)(bar)', '') 1177 self.assert_lint('Foo (*foo)(bar)', '') 1178 self.assert_lint('Foo (*foo)(Bar bar,', '') 1179 self.assert_lint('char (*p)[sizeof(foo)] = &foo', '') 1180 self.assert_lint('char (&ref)[sizeof(foo)] = &foo', '') 1181 self.assert_lint('const char32 (*table[])[6];', '') 1182 1183 def test_spacing_before_braces(self): 1184 self.assert_lint('if (foo){', 'Missing space before {' 1185 ' [whitespace/braces] [5]') 1186 self.assert_lint('for{', 'Missing space before {' 1187 ' [whitespace/braces] [5]') 1188 self.assert_lint('for {', '') 1189 self.assert_lint('EXPECT_DEBUG_DEATH({', '') 1190 1191 def test_spacing_around_else(self): 1192 self.assert_lint('}else {', 'Missing space before else' 1193 ' [whitespace/braces] [5]') 1194 self.assert_lint('} else{', 'Missing space before {' 1195 ' [whitespace/braces] [5]') 1196 self.assert_lint('} else {', '') 1197 self.assert_lint('} else if', '') 1198 1199 def test_spacing_for_binary_ops(self): 1200 self.assert_lint('if (foo<=bar) {', 'Missing spaces around <=' 1201 ' [whitespace/operators] [3]') 1202 self.assert_lint('if (foo<bar) {', 'Missing spaces around <' 1203 ' [whitespace/operators] [3]') 1204 self.assert_lint('if (foo<bar->baz) {', 'Missing spaces around <' 1205 ' [whitespace/operators] [3]') 1206 self.assert_lint('if (foo<bar->bar) {', 'Missing spaces around <' 1207 ' [whitespace/operators] [3]') 1208 self.assert_lint('typedef hash_map<Foo, Bar', 'Missing spaces around <' 1209 ' [whitespace/operators] [3]') 1210 self.assert_lint('typedef hash_map<FoooooType, BaaaaarType,', '') 1211 1212 def test_spacing_before_last_semicolon(self): 1213 self.assert_lint('call_function() ;', 1214 'Extra space before last semicolon. If this should be an ' 1215 'empty statement, use { } instead.' 1216 ' [whitespace/semicolon] [5]') 1217 self.assert_lint('while (true) ;', 1218 'Extra space before last semicolon. If this should be an ' 1219 'empty statement, use { } instead.' 1220 ' [whitespace/semicolon] [5]') 1221 self.assert_lint('default:;', 1222 'Semicolon defining empty statement. Use { } instead.' 1223 ' [whitespace/semicolon] [5]') 1224 self.assert_lint(' ;', 1225 'Line contains only semicolon. If this should be an empty ' 1226 'statement, use { } instead.' 1227 ' [whitespace/semicolon] [5]') 1228 self.assert_lint('for (int i = 0; ;', '') 1229 1230 # Static or global STL strings. 1231 def test_static_or_global_stlstrings(self): 1232 self.assert_lint('string foo;', 1233 'For a static/global string constant, use a C style ' 1234 'string instead: "char foo[]".' 1235 ' [runtime/string] [4]') 1236 self.assert_lint('string kFoo = "hello"; // English', 1237 'For a static/global string constant, use a C style ' 1238 'string instead: "char kFoo[]".' 1239 ' [runtime/string] [4]') 1240 self.assert_lint('static string foo;', 1241 'For a static/global string constant, use a C style ' 1242 'string instead: "static char foo[]".' 1243 ' [runtime/string] [4]') 1244 self.assert_lint('static const string foo;', 1245 'For a static/global string constant, use a C style ' 1246 'string instead: "static const char foo[]".' 1247 ' [runtime/string] [4]') 1248 self.assert_lint('string Foo::bar;', 1249 'For a static/global string constant, use a C style ' 1250 'string instead: "char Foo::bar[]".' 1251 ' [runtime/string] [4]') 1252 # Rare case. 1253 self.assert_lint('string foo("foobar");', 1254 'For a static/global string constant, use a C style ' 1255 'string instead: "char foo[]".' 1256 ' [runtime/string] [4]') 1257 # Should not catch local or member variables. 1258 self.assert_lint(' string foo', '') 1259 # Should not catch functions. 1260 self.assert_lint('string EmptyString() { return ""; }', '') 1261 self.assert_lint('string EmptyString () { return ""; }', '') 1262 self.assert_lint('string VeryLongNameFunctionSometimesEndsWith(\n' 1263 ' VeryLongNameType very_long_name_variable) {}', '') 1264 self.assert_lint('template<>\n' 1265 'string FunctionTemplateSpecialization<SomeType>(\n' 1266 ' int x) { return ""; }', '') 1267 self.assert_lint('template<>\n' 1268 'string FunctionTemplateSpecialization<vector<A::B>* >(\n' 1269 ' int x) { return ""; }', '') 1270 1271 # should not catch methods of template classes. 1272 self.assert_lint('string Class<Type>::Method() const\n' 1273 '{\n' 1274 ' return "";\n' 1275 '}\n', '') 1276 self.assert_lint('string Class<Type>::Method(\n' 1277 ' int arg) const\n' 1278 '{\n' 1279 ' return "";\n' 1280 '}\n', '') 1281 1282 def test_no_spaces_in_function_calls(self): 1283 self.assert_lint('TellStory(1, 3);', 1284 '') 1285 self.assert_lint('TellStory(1, 3 );', 1286 'Extra space before )' 1287 ' [whitespace/parens] [2]') 1288 self.assert_lint('TellStory(1 /* wolf */, 3 /* pigs */);', 1289 '') 1290 self.assert_multi_line_lint('#endif\n );', 1291 '') 1292 1293 def test_two_spaces_between_code_and_comments(self): 1294 self.assert_lint('} // namespace foo', 1295 'At least two spaces is best between code and comments' 1296 ' [whitespace/comments] [2]') 1297 self.assert_lint('}// namespace foo', 1298 'At least two spaces is best between code and comments' 1299 ' [whitespace/comments] [2]') 1300 self.assert_lint('printf("foo"); // Outside quotes.', 1301 'At least two spaces is best between code and comments' 1302 ' [whitespace/comments] [2]') 1303 self.assert_lint('int i = 0; // Having two spaces is fine.', '') 1304 self.assert_lint('int i = 0; // Having three spaces is OK.', '') 1305 self.assert_lint('// Top level comment', '') 1306 self.assert_lint(' // Line starts with four spaces.', '') 1307 self.assert_lint('foo();\n' 1308 '{ // A scope is opening.', '') 1309 self.assert_lint(' foo();\n' 1310 ' { // An indented scope is opening.', '') 1311 self.assert_lint('if (foo) { // not a pure scope; comment is too close!', 1312 'At least two spaces is best between code and comments' 1313 ' [whitespace/comments] [2]') 1314 self.assert_lint('printf("// In quotes.")', '') 1315 self.assert_lint('printf("\\"%s // In quotes.")', '') 1316 self.assert_lint('printf("%s", "// In quotes.")', '') 1317 1318 def test_space_after_comment_marker(self): 1319 self.assert_lint('//', '') 1320 self.assert_lint('//x', 'Should have a space between // and comment' 1321 ' [whitespace/comments] [4]') 1322 self.assert_lint('// x', '') 1323 self.assert_lint('//----', '') 1324 self.assert_lint('//====', '') 1325 self.assert_lint('//////', '') 1326 self.assert_lint('////// x', '') 1327 self.assert_lint('/// x', '') 1328 self.assert_lint('////x', 'Should have a space between // and comment' 1329 ' [whitespace/comments] [4]') 1330 1331 def test_newline_at_eof(self): 1332 def do_test(self, data, is_missing_eof): 1333 error_collector = ErrorCollector(self.assert_) 1334 cpp_style.process_file_data('foo.cpp', 'cpp', data.split('\n'), 1335 error_collector) 1336 # The warning appears only once. 1337 self.assertEquals( 1338 int(is_missing_eof), 1339 error_collector.results().count( 1340 'Could not find a newline character at the end of the file.' 1341 ' [whitespace/ending_newline] [5]')) 1342 1343 do_test(self, '// Newline\n// at EOF\n', False) 1344 do_test(self, '// No newline\n// at EOF', True) 1345 1346 def test_invalid_utf8(self): 1347 def do_test(self, raw_bytes, has_invalid_utf8): 1348 error_collector = ErrorCollector(self.assert_) 1349 cpp_style.process_file_data( 1350 'foo.cpp', 'cpp', 1351 unicode(raw_bytes, 'utf8', 'replace').split('\n'), 1352 error_collector) 1353 # The warning appears only once. 1354 self.assertEquals( 1355 int(has_invalid_utf8), 1356 error_collector.results().count( 1357 'Line contains invalid UTF-8' 1358 ' (or Unicode replacement character).' 1359 ' [readability/utf8] [5]')) 1360 1361 do_test(self, 'Hello world\n', False) 1362 do_test(self, '\xe9\x8e\xbd\n', False) 1363 do_test(self, '\xe9x\x8e\xbd\n', True) 1364 # This is the encoding of the replacement character itself (which 1365 # you can see by evaluating codecs.getencoder('utf8')(u'\ufffd')). 1366 do_test(self, '\xef\xbf\xbd\n', True) 1367 1368 def test_is_blank_line(self): 1369 self.assert_(cpp_style.is_blank_line('')) 1370 self.assert_(cpp_style.is_blank_line(' ')) 1371 self.assert_(cpp_style.is_blank_line(' \t\r\n')) 1372 self.assert_(not cpp_style.is_blank_line('int a;')) 1373 self.assert_(not cpp_style.is_blank_line('{')) 1374 1375 def test_blank_lines_check(self): 1376 self.assert_blank_lines_check(['{\n', '\n', '\n', '}\n'], 1, 1) 1377 self.assert_blank_lines_check([' if (foo) {\n', '\n', ' }\n'], 1, 1) 1378 self.assert_blank_lines_check( 1379 ['\n', '// {\n', '\n', '\n', '// Comment\n', '{\n', '}\n'], 0, 0) 1380 self.assert_blank_lines_check(['\n', 'run("{");\n', '\n'], 0, 0) 1381 self.assert_blank_lines_check(['\n', ' if (foo) { return 0; }\n', '\n'], 0, 0) 1382 1383 def test_allow_blank_line_before_closing_namespace(self): 1384 error_collector = ErrorCollector(self.assert_) 1385 cpp_style.process_file_data('foo.cpp', 'cpp', 1386 ['namespace {', '', '} // namespace'], 1387 error_collector) 1388 self.assertEquals(0, error_collector.results().count( 1389 'Blank line at the end of a code block. Is this needed?' 1390 ' [whitespace/blank_line] [3]')) 1391 1392 def test_allow_blank_line_before_if_else_chain(self): 1393 error_collector = ErrorCollector(self.assert_) 1394 cpp_style.process_file_data('foo.cpp', 'cpp', 1395 ['if (hoge) {', 1396 '', # No warning 1397 '} else if (piyo) {', 1398 '', # No warning 1399 '} else if (piyopiyo) {', 1400 ' hoge = true;', # No warning 1401 '} else {', 1402 '', # Warning on this line 1403 '}'], 1404 error_collector) 1405 self.assertEquals(1, error_collector.results().count( 1406 'Blank line at the end of a code block. Is this needed?' 1407 ' [whitespace/blank_line] [3]')) 1408 1409 def test_else_on_same_line_as_closing_braces(self): 1410 error_collector = ErrorCollector(self.assert_) 1411 cpp_style.process_file_data('foo.cpp', 'cpp', 1412 ['if (hoge) {', 1413 '', 1414 '}', 1415 ' else {' # Warning on this line 1416 '', 1417 '}'], 1418 error_collector) 1419 self.assertEquals(1, error_collector.results().count( 1420 'An else should appear on the same line as the preceding }' 1421 ' [whitespace/newline] [4]')) 1422 1423 def test_else_clause_not_on_same_line_as_else(self): 1424 self.assert_lint(' else DoSomethingElse();', 1425 'Else clause should never be on same line as else ' 1426 '(use 2 lines) [whitespace/newline] [4]') 1427 self.assert_lint(' else ifDoSomethingElse();', 1428 'Else clause should never be on same line as else ' 1429 '(use 2 lines) [whitespace/newline] [4]') 1430 self.assert_lint(' else if (blah) {', '') 1431 self.assert_lint(' variable_ends_in_else = true;', '') 1432 1433 def test_comma(self): 1434 self.assert_lint('a = f(1,2);', 1435 'Missing space after , [whitespace/comma] [3]') 1436 self.assert_lint('int tmp=a,a=b,b=tmp;', 1437 ['Missing spaces around = [whitespace/operators] [4]', 1438 'Missing space after , [whitespace/comma] [3]']) 1439 self.assert_lint('f(a, /* name */ b);', '') 1440 self.assert_lint('f(a, /* name */b);', '') 1441 1442 def test_pointer_reference_marker_location(self): 1443 self.assert_lint('int* b;', '', 'foo.cpp') 1444 self.assert_lint('int *b;', 1445 'Declaration has space between type name and * in int *b [whitespace/declaration] [3]', 1446 'foo.cpp') 1447 self.assert_lint('return *b;', '', 'foo.cpp') 1448 self.assert_lint('int *b;', '', 'foo.c') 1449 self.assert_lint('int* b;', 1450 'Declaration has space between * and variable name in int* b [whitespace/declaration] [3]', 1451 'foo.c') 1452 self.assert_lint('int& b;', '', 'foo.cpp') 1453 self.assert_lint('int &b;', 1454 'Declaration has space between type name and & in int &b [whitespace/declaration] [3]', 1455 'foo.cpp') 1456 self.assert_lint('return &b;', '', 'foo.cpp') 1457 1458 def test_indent(self): 1459 self.assert_lint('static int noindent;', '') 1460 self.assert_lint(' int four_space_indent;', '') 1461 self.assert_lint(' int one_space_indent;', 1462 'Weird number of spaces at line-start. ' 1463 'Are you using a 4-space indent? [whitespace/indent] [3]') 1464 self.assert_lint(' int three_space_indent;', 1465 'Weird number of spaces at line-start. ' 1466 'Are you using a 4-space indent? [whitespace/indent] [3]') 1467 self.assert_lint(' char* one_space_indent = "public:";', 1468 'Weird number of spaces at line-start. ' 1469 'Are you using a 4-space indent? [whitespace/indent] [3]') 1470 self.assert_lint(' public:', '') 1471 self.assert_lint(' public:', '') 1472 self.assert_lint(' public:', '') 1473 1474 def test_label(self): 1475 self.assert_lint('public:', 1476 'Labels should always be indented at least one space. ' 1477 'If this is a member-initializer list in a constructor, ' 1478 'the colon should be on the line after the definition ' 1479 'header. [whitespace/labels] [4]') 1480 self.assert_lint(' public:', '') 1481 self.assert_lint(' public:', '') 1482 self.assert_lint(' public:', '') 1483 self.assert_lint(' public:', '') 1484 self.assert_lint(' public:', '') 1485 1486 def test_not_alabel(self): 1487 self.assert_lint('MyVeryLongNamespace::MyVeryLongClassName::', '') 1488 1489 def test_tab(self): 1490 self.assert_lint('\tint a;', 1491 'Tab found; better to use spaces [whitespace/tab] [1]') 1492 self.assert_lint('int a = 5;\t\t// set a to 5', 1493 'Tab found; better to use spaces [whitespace/tab] [1]') 1494 1495 def test_parse_arguments(self): 1496 old_usage = cpp_style._USAGE 1497 old_error_categories = cpp_style._ERROR_CATEGORIES 1498 old_output_format = cpp_style._cpp_style_state.output_format 1499 old_verbose_level = cpp_style._cpp_style_state.verbose_level 1500 old_filters = cpp_style._cpp_style_state.filters 1501 try: 1502 # Don't print usage during the tests, or filter categories 1503 cpp_style._USAGE = '' 1504 cpp_style._ERROR_CATEGORIES = '' 1505 1506 self.assertRaises(SystemExit, cpp_style.parse_arguments, ['--badopt']) 1507 self.assertRaises(SystemExit, cpp_style.parse_arguments, ['--help']) 1508 self.assertRaises(SystemExit, cpp_style.parse_arguments, ['--filter=']) 1509 # This is illegal because all filters must start with + or - 1510 self.assertRaises(ValueError, cpp_style.parse_arguments, ['--filter=foo']) 1511 self.assertRaises(ValueError, cpp_style.parse_arguments, 1512 ['--filter=+a,b,-c']) 1513 1514 self.assertEquals((['foo.cpp'], {}), cpp_style.parse_arguments(['foo.cpp'])) 1515 self.assertEquals(old_output_format, cpp_style._cpp_style_state.output_format) 1516 self.assertEquals(old_verbose_level, cpp_style._cpp_style_state.verbose_level) 1517 1518 self.assertEquals(([], {}), cpp_style.parse_arguments([])) 1519 self.assertEquals(([], {}), cpp_style.parse_arguments(['--v=0'])) 1520 1521 self.assertEquals((['foo.cpp'], {}), 1522 cpp_style.parse_arguments(['--v=1', 'foo.cpp'])) 1523 self.assertEquals(1, cpp_style._cpp_style_state.verbose_level) 1524 self.assertEquals((['foo.h'], {}), 1525 cpp_style.parse_arguments(['--v=3', 'foo.h'])) 1526 self.assertEquals(3, cpp_style._cpp_style_state.verbose_level) 1527 self.assertEquals((['foo.cpp'], {}), 1528 cpp_style.parse_arguments(['--verbose=5', 'foo.cpp'])) 1529 self.assertEquals(5, cpp_style._cpp_style_state.verbose_level) 1530 self.assertRaises(ValueError, 1531 cpp_style.parse_arguments, ['--v=f', 'foo.cpp']) 1532 1533 self.assertEquals((['foo.cpp'], {}), 1534 cpp_style.parse_arguments(['--output=emacs', 'foo.cpp'])) 1535 self.assertEquals('emacs', cpp_style._cpp_style_state.output_format) 1536 self.assertEquals((['foo.h'], {}), 1537 cpp_style.parse_arguments(['--output=vs7', 'foo.h'])) 1538 self.assertEquals('vs7', cpp_style._cpp_style_state.output_format) 1539 self.assertRaises(SystemExit, 1540 cpp_style.parse_arguments, ['--output=blah', 'foo.cpp']) 1541 1542 filt = '-,+whitespace,-whitespace/indent' 1543 self.assertEquals((['foo.h'], {}), 1544 cpp_style.parse_arguments(['--filter='+filt, 'foo.h'])) 1545 self.assertEquals(['-', '+whitespace', '-whitespace/indent'], 1546 cpp_style._cpp_style_state.filters) 1547 1548 self.assertEquals((['foo.cpp', 'foo.h'], {}), 1549 cpp_style.parse_arguments(['foo.cpp', 'foo.h'])) 1550 1551 self.assertEquals((['foo.cpp'], {'--foo': ''}), 1552 cpp_style.parse_arguments(['--foo', 'foo.cpp'], ['foo'])) 1553 self.assertEquals((['foo.cpp'], {'--foo': 'bar'}), 1554 cpp_style.parse_arguments(['--foo=bar', 'foo.cpp'], ['foo='])) 1555 self.assertEquals((['foo.cpp'], {}), 1556 cpp_style.parse_arguments(['foo.cpp'], ['foo='])) 1557 self.assertRaises(SystemExit, 1558 cpp_style.parse_arguments, 1559 ['--footypo=bar', 'foo.cpp'], ['foo=']) 1560 finally: 1561 cpp_style._USAGE = old_usage 1562 cpp_style._ERROR_CATEGORIES = old_error_categories 1563 cpp_style._cpp_style_state.output_format = old_output_format 1564 cpp_style._cpp_style_state.verbose_level = old_verbose_level 1565 cpp_style._cpp_style_state.filters = old_filters 1566 1567 def test_filter(self): 1568 old_filters = cpp_style._cpp_style_state.filters 1569 try: 1570 cpp_style._cpp_style_state.set_filters('-,+whitespace,-whitespace/indent') 1571 self.assert_lint( 1572 '// Hello there ', 1573 'Line ends in whitespace. Consider deleting these extra spaces.' 1574 ' [whitespace/end_of_line] [4]') 1575 self.assert_lint('int a = (int)1.0;', '') 1576 self.assert_lint(' weird opening space', '') 1577 finally: 1578 cpp_style._cpp_style_state.filters = old_filters 1579 1580 def test_default_filter(self): 1581 default_filters = cpp_style._DEFAULT_FILTERS 1582 old_filters = cpp_style._cpp_style_state.filters 1583 cpp_style._DEFAULT_FILTERS = [ '-whitespace' ] 1584 try: 1585 # Reset filters 1586 cpp_style._cpp_style_state.set_filters('') 1587 self.assert_lint('// Hello there ', '') 1588 cpp_style._cpp_style_state.set_filters('+whitespace/end_of_line') 1589 self.assert_lint( 1590 '// Hello there ', 1591 'Line ends in whitespace. Consider deleting these extra spaces.' 1592 ' [whitespace/end_of_line] [4]') 1593 self.assert_lint(' weird opening space', '') 1594 finally: 1595 cpp_style._cpp_style_state.filters = old_filters 1596 cpp_style._DEFAULT_FILTERS = default_filters 1597 1598 def test_unnamed_namespaces_in_headers(self): 1599 self.assert_language_rules_check( 1600 'foo.h', 'namespace {', 1601 'Do not use unnamed namespaces in header files. See' 1602 ' http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Namespaces' 1603 ' for more information. [build/namespaces] [4]') 1604 # namespace registration macros are OK. 1605 self.assert_language_rules_check('foo.h', 'namespace { \\', '') 1606 # named namespaces are OK. 1607 self.assert_language_rules_check('foo.h', 'namespace foo {', '') 1608 self.assert_language_rules_check('foo.h', 'namespace foonamespace {', '') 1609 self.assert_language_rules_check('foo.cpp', 'namespace {', '') 1610 self.assert_language_rules_check('foo.cpp', 'namespace foo {', '') 1611 1612 def test_build_class(self): 1613 # Test that the linter can parse to the end of class definitions, 1614 # and that it will report when it can't. 1615 # Use multi-line linter because it performs the ClassState check. 1616 self.assert_multi_line_lint( 1617 'class Foo {', 1618 'Failed to find complete declaration of class Foo' 1619 ' [build/class] [5]') 1620 # Don't warn on forward declarations of various types. 1621 self.assert_multi_line_lint( 1622 'class Foo;', 1623 '') 1624 self.assert_multi_line_lint( 1625 '''struct Foo* 1626 foo = NewFoo();''', 1627 '') 1628 # Here is an example where the linter gets confused, even though 1629 # the code doesn't violate the style guide. 1630 self.assert_multi_line_lint( 1631 '''class Foo 1632 #ifdef DERIVE_FROM_GOO 1633 : public Goo { 1634 #else 1635 : public Hoo { 1636 #endif 1637 };''', 1638 'Failed to find complete declaration of class Foo' 1639 ' [build/class] [5]') 1640 1641 def test_build_end_comment(self): 1642 # The crosstool compiler we currently use will fail to compile the 1643 # code in this test, so we might consider removing the lint check. 1644 self.assert_lint('#endif Not a comment', 1645 'Uncommented text after #endif is non-standard.' 1646 ' Use a comment.' 1647 ' [build/endif_comment] [5]') 1648 1649 def test_build_forward_decl(self): 1650 # The crosstool compiler we currently use will fail to compile the 1651 # code in this test, so we might consider removing the lint check. 1652 self.assert_lint('class Foo::Goo;', 1653 'Inner-style forward declarations are invalid.' 1654 ' Remove this line.' 1655 ' [build/forward_decl] [5]') 1656 1657 def test_build_header_guard(self): 1658 file_path = 'mydir/foo.h' 1659 1660 # We can't rely on our internal stuff to get a sane path on the open source 1661 # side of things, so just parse out the suggested header guard. This 1662 # doesn't allow us to test the suggested header guard, but it does let us 1663 # test all the other header tests. 1664 error_collector = ErrorCollector(self.assert_) 1665 cpp_style.process_file_data(file_path, 'h', [], error_collector) 1666 expected_guard = '' 1667 matcher = re.compile( 1668 'No \#ifndef header guard found\, suggested CPP variable is\: ([A-Z_0-9]+) ') 1669 for error in error_collector.result_list(): 1670 matches = matcher.match(error) 1671 if matches: 1672 expected_guard = matches.group(1) 1673 break 1674 1675 # Make sure we extracted something for our header guard. 1676 self.assertNotEqual(expected_guard, '') 1677 1678 # Wrong guard 1679 error_collector = ErrorCollector(self.assert_) 1680 cpp_style.process_file_data(file_path, 'h', 1681 ['#ifndef FOO_H', '#define FOO_H'], error_collector) 1682 self.assertEquals( 1683 1, 1684 error_collector.result_list().count( 1685 '#ifndef header guard has wrong style, please use: %s' 1686 ' [build/header_guard] [5]' % expected_guard), 1687 error_collector.result_list()) 1688 1689 # No define 1690 error_collector = ErrorCollector(self.assert_) 1691 cpp_style.process_file_data(file_path, 'h', 1692 ['#ifndef %s' % expected_guard], error_collector) 1693 self.assertEquals( 1694 1, 1695 error_collector.result_list().count( 1696 'No #ifndef header guard found, suggested CPP variable is: %s' 1697 ' [build/header_guard] [5]' % expected_guard), 1698 error_collector.result_list()) 1699 1700 # Mismatched define 1701 error_collector = ErrorCollector(self.assert_) 1702 cpp_style.process_file_data(file_path, 'h', 1703 ['#ifndef %s' % expected_guard, 1704 '#define FOO_H'], 1705 error_collector) 1706 self.assertEquals( 1707 1, 1708 error_collector.result_list().count( 1709 'No #ifndef header guard found, suggested CPP variable is: %s' 1710 ' [build/header_guard] [5]' % expected_guard), 1711 error_collector.result_list()) 1712 1713 # No endif 1714 error_collector = ErrorCollector(self.assert_) 1715 cpp_style.process_file_data(file_path, 'h', 1716 ['#ifndef %s' % expected_guard, 1717 '#define %s' % expected_guard], 1718 error_collector) 1719 self.assertEquals( 1720 1, 1721 error_collector.result_list().count( 1722 '#endif line should be "#endif // %s"' 1723 ' [build/header_guard] [5]' % expected_guard), 1724 error_collector.result_list()) 1725 1726 # Commentless endif 1727 error_collector = ErrorCollector(self.assert_) 1728 cpp_style.process_file_data(file_path, 'h', 1729 ['#ifndef %s' % expected_guard, 1730 '#define %s' % expected_guard, 1731 '#endif'], 1732 error_collector) 1733 self.assertEquals( 1734 1, 1735 error_collector.result_list().count( 1736 '#endif line should be "#endif // %s"' 1737 ' [build/header_guard] [5]' % expected_guard), 1738 error_collector.result_list()) 1739 1740 # Commentless endif for old-style guard 1741 error_collector = ErrorCollector(self.assert_) 1742 cpp_style.process_file_data(file_path, 'h', 1743 ['#ifndef %s_' % expected_guard, 1744 '#define %s_' % expected_guard, 1745 '#endif'], 1746 error_collector) 1747 self.assertEquals( 1748 1, 1749 error_collector.result_list().count( 1750 '#endif line should be "#endif // %s"' 1751 ' [build/header_guard] [5]' % expected_guard), 1752 error_collector.result_list()) 1753 1754 # No header guard errors 1755 error_collector = ErrorCollector(self.assert_) 1756 cpp_style.process_file_data(file_path, 'h', 1757 ['#ifndef %s' % expected_guard, 1758 '#define %s' % expected_guard, 1759 '#endif // %s' % expected_guard], 1760 error_collector) 1761 for line in error_collector.result_list(): 1762 if line.find('build/header_guard') != -1: 1763 self.fail('Unexpected error: %s' % line) 1764 1765 # No header guard errors for old-style guard 1766 error_collector = ErrorCollector(self.assert_) 1767 cpp_style.process_file_data(file_path, 'h', 1768 ['#ifndef %s_' % expected_guard, 1769 '#define %s_' % expected_guard, 1770 '#endif // %s_' % expected_guard], 1771 error_collector) 1772 for line in error_collector.result_list(): 1773 if line.find('build/header_guard') != -1: 1774 self.fail('Unexpected error: %s' % line) 1775 1776 old_verbose_level = cpp_style._cpp_style_state.verbose_level 1777 try: 1778 cpp_style._cpp_style_state.verbose_level = 0 1779 # Warn on old-style guard if verbosity is 0. 1780 error_collector = ErrorCollector(self.assert_) 1781 cpp_style.process_file_data(file_path, 'h', 1782 ['#ifndef %s_' % expected_guard, 1783 '#define %s_' % expected_guard, 1784 '#endif // %s_' % expected_guard], 1785 error_collector) 1786 self.assertEquals( 1787 1, 1788 error_collector.result_list().count( 1789 '#ifndef header guard has wrong style, please use: %s' 1790 ' [build/header_guard] [0]' % expected_guard), 1791 error_collector.result_list()) 1792 finally: 1793 cpp_style._cpp_style_state.verbose_level = old_verbose_level 1794 1795 # Completely incorrect header guard 1796 error_collector = ErrorCollector(self.assert_) 1797 cpp_style.process_file_data(file_path, 'h', 1798 ['#ifndef FOO', 1799 '#define FOO', 1800 '#endif // FOO'], 1801 error_collector) 1802 self.assertEquals( 1803 1, 1804 error_collector.result_list().count( 1805 '#ifndef header guard has wrong style, please use: %s' 1806 ' [build/header_guard] [5]' % expected_guard), 1807 error_collector.result_list()) 1808 self.assertEquals( 1809 1, 1810 error_collector.result_list().count( 1811 '#endif line should be "#endif // %s"' 1812 ' [build/header_guard] [5]' % expected_guard), 1813 error_collector.result_list()) 1814 1815 def test_build_printf_format(self): 1816 self.assert_lint( 1817 r'printf("\%%d", value);', 1818 '%, [, (, and { are undefined character escapes. Unescape them.' 1819 ' [build/printf_format] [3]') 1820 1821 self.assert_lint( 1822 r'snprintf(buffer, sizeof(buffer), "\[%d", value);', 1823 '%, [, (, and { are undefined character escapes. Unescape them.' 1824 ' [build/printf_format] [3]') 1825 1826 self.assert_lint( 1827 r'fprintf(file, "\(%d", value);', 1828 '%, [, (, and { are undefined character escapes. Unescape them.' 1829 ' [build/printf_format] [3]') 1830 1831 self.assert_lint( 1832 r'vsnprintf(buffer, sizeof(buffer), "\\\{%d", ap);', 1833 '%, [, (, and { are undefined character escapes. Unescape them.' 1834 ' [build/printf_format] [3]') 1835 1836 # Don't warn if double-slash precedes the symbol 1837 self.assert_lint(r'printf("\\%%%d", value);', 1838 '') 1839 1840 def test_runtime_printf_format(self): 1841 self.assert_lint( 1842 r'fprintf(file, "%q", value);', 1843 '%q in format strings is deprecated. Use %ll instead.' 1844 ' [runtime/printf_format] [3]') 1845 1846 self.assert_lint( 1847 r'aprintf(file, "The number is %12q", value);', 1848 '%q in format strings is deprecated. Use %ll instead.' 1849 ' [runtime/printf_format] [3]') 1850 1851 self.assert_lint( 1852 r'printf(file, "The number is" "%-12q", value);', 1853 '%q in format strings is deprecated. Use %ll instead.' 1854 ' [runtime/printf_format] [3]') 1855 1856 self.assert_lint( 1857 r'printf(file, "The number is" "%+12q", value);', 1858 '%q in format strings is deprecated. Use %ll instead.' 1859 ' [runtime/printf_format] [3]') 1860 1861 self.assert_lint( 1862 r'printf(file, "The number is" "% 12q", value);', 1863 '%q in format strings is deprecated. Use %ll instead.' 1864 ' [runtime/printf_format] [3]') 1865 1866 self.assert_lint( 1867 r'snprintf(file, "Never mix %d and %1$d parmaeters!", value);', 1868 '%N$ formats are unconventional. Try rewriting to avoid them.' 1869 ' [runtime/printf_format] [2]') 1870 1871 def assert_lintLogCodeOnError(self, code, expected_message): 1872 # Special assert_lint which logs the input code on error. 1873 result = self.perform_single_line_lint(code, 'foo.cpp') 1874 if result != expected_message: 1875 self.fail('For code: "%s"\nGot: "%s"\nExpected: "%s"' 1876 % (code, result, expected_message)) 1877 1878 def test_build_storage_class(self): 1879 qualifiers = [None, 'const', 'volatile'] 1880 signs = [None, 'signed', 'unsigned'] 1881 types = ['void', 'char', 'int', 'float', 'double', 1882 'schar', 'int8', 'uint8', 'int16', 'uint16', 1883 'int32', 'uint32', 'int64', 'uint64'] 1884 storage_classes = ['auto', 'extern', 'register', 'static', 'typedef'] 1885 1886 build_storage_class_error_message = ( 1887 'Storage class (static, extern, typedef, etc) should be first.' 1888 ' [build/storage_class] [5]') 1889 1890 # Some explicit cases. Legal in C++, deprecated in C99. 1891 self.assert_lint('const int static foo = 5;', 1892 build_storage_class_error_message) 1893 1894 self.assert_lint('char static foo;', 1895 build_storage_class_error_message) 1896 1897 self.assert_lint('double const static foo = 2.0;', 1898 build_storage_class_error_message) 1899 1900 self.assert_lint('uint64 typedef unsigned_long_long;', 1901 build_storage_class_error_message) 1902 1903 self.assert_lint('int register foo = 0;', 1904 build_storage_class_error_message) 1905 1906 # Since there are a very large number of possibilities, randomly 1907 # construct declarations. 1908 # Make sure that the declaration is logged if there's an error. 1909 # Seed generator with an integer for absolute reproducibility. 1910 random.seed(25) 1911 for unused_i in range(10): 1912 # Build up random list of non-storage-class declaration specs. 1913 other_decl_specs = [random.choice(qualifiers), random.choice(signs), 1914 random.choice(types)] 1915 # remove None 1916 other_decl_specs = filter(lambda x: x is not None, other_decl_specs) 1917 1918 # shuffle 1919 random.shuffle(other_decl_specs) 1920 1921 # insert storage class after the first 1922 storage_class = random.choice(storage_classes) 1923 insertion_point = random.randint(1, len(other_decl_specs)) 1924 decl_specs = (other_decl_specs[0:insertion_point] 1925 + [storage_class] 1926 + other_decl_specs[insertion_point:]) 1927 1928 self.assert_lintLogCodeOnError( 1929 ' '.join(decl_specs) + ';', 1930 build_storage_class_error_message) 1931 1932 # but no error if storage class is first 1933 self.assert_lintLogCodeOnError( 1934 storage_class + ' ' + ' '.join(other_decl_specs), 1935 '') 1936 1937 def test_legal_copyright(self): 1938 legal_copyright_message = ( 1939 'No copyright message found. ' 1940 'You should have a line: "Copyright [year] <Copyright Owner>"' 1941 ' [legal/copyright] [5]') 1942 1943 copyright_line = '// Copyright 2008 Google Inc. All Rights Reserved.' 1944 1945 file_path = 'mydir/googleclient/foo.cpp' 1946 1947 # There should be a copyright message in the first 10 lines 1948 error_collector = ErrorCollector(self.assert_) 1949 cpp_style.process_file_data(file_path, 'cpp', [], error_collector) 1950 self.assertEquals( 1951 1, 1952 error_collector.result_list().count(legal_copyright_message)) 1953 1954 error_collector = ErrorCollector(self.assert_) 1955 cpp_style.process_file_data( 1956 file_path, 'cpp', 1957 ['' for unused_i in range(10)] + [copyright_line], 1958 error_collector) 1959 self.assertEquals( 1960 1, 1961 error_collector.result_list().count(legal_copyright_message)) 1962 1963 # Test that warning isn't issued if Copyright line appears early enough. 1964 error_collector = ErrorCollector(self.assert_) 1965 cpp_style.process_file_data(file_path, 'cpp', [copyright_line], error_collector) 1966 for message in error_collector.result_list(): 1967 if message.find('legal/copyright') != -1: 1968 self.fail('Unexpected error: %s' % message) 1969 1970 error_collector = ErrorCollector(self.assert_) 1971 cpp_style.process_file_data( 1972 file_path, 'cpp', 1973 ['' for unused_i in range(9)] + [copyright_line], 1974 error_collector) 1975 for message in error_collector.result_list(): 1976 if message.find('legal/copyright') != -1: 1977 self.fail('Unexpected error: %s' % message) 1978 1979 def test_invalid_increment(self): 1980 self.assert_lint('*count++;', 1981 'Changing pointer instead of value (or unused value of ' 1982 'operator*). [runtime/invalid_increment] [5]') 1983 1984class CleansedLinesTest(unittest.TestCase): 1985 def test_init(self): 1986 lines = ['Line 1', 1987 'Line 2', 1988 'Line 3 // Comment test', 1989 'Line 4 "foo"'] 1990 1991 clean_lines = cpp_style.CleansedLines(lines) 1992 self.assertEquals(lines, clean_lines.raw_lines) 1993 self.assertEquals(4, clean_lines.num_lines()) 1994 1995 self.assertEquals(['Line 1', 1996 'Line 2', 1997 'Line 3 ', 1998 'Line 4 "foo"'], 1999 clean_lines.lines) 2000 2001 self.assertEquals(['Line 1', 2002 'Line 2', 2003 'Line 3 ', 2004 'Line 4 ""'], 2005 clean_lines.elided) 2006 2007 def test_init_empty(self): 2008 clean_lines = cpp_style.CleansedLines([]) 2009 self.assertEquals([], clean_lines.raw_lines) 2010 self.assertEquals(0, clean_lines.num_lines()) 2011 2012 def test_collapse_strings(self): 2013 collapse = cpp_style.CleansedLines.collapse_strings 2014 self.assertEquals('""', collapse('""')) # "" (empty) 2015 self.assertEquals('"""', collapse('"""')) # """ (bad) 2016 self.assertEquals('""', collapse('"xyz"')) # "xyz" (string) 2017 self.assertEquals('""', collapse('"\\\""')) # "\"" (string) 2018 self.assertEquals('""', collapse('"\'"')) # "'" (string) 2019 self.assertEquals('"\"', collapse('"\"')) # "\" (bad) 2020 self.assertEquals('""', collapse('"\\\\"')) # "\\" (string) 2021 self.assertEquals('"', collapse('"\\\\\\"')) # "\\\" (bad) 2022 self.assertEquals('""', collapse('"\\\\\\\\"')) # "\\\\" (string) 2023 2024 self.assertEquals('\'\'', collapse('\'\'')) # '' (empty) 2025 self.assertEquals('\'\'', collapse('\'a\'')) # 'a' (char) 2026 self.assertEquals('\'\'', collapse('\'\\\'\'')) # '\'' (char) 2027 self.assertEquals('\'', collapse('\'\\\'')) # '\' (bad) 2028 self.assertEquals('', collapse('\\012')) # '\012' (char) 2029 self.assertEquals('', collapse('\\xfF0')) # '\xfF0' (char) 2030 self.assertEquals('', collapse('\\n')) # '\n' (char) 2031 self.assertEquals('\#', collapse('\\#')) # '\#' (bad) 2032 2033 self.assertEquals('StringReplace(body, "", "");', 2034 collapse('StringReplace(body, "\\\\", "\\\\\\\\");')) 2035 self.assertEquals('\'\' ""', 2036 collapse('\'"\' "foo"')) 2037 2038 2039class OrderOfIncludesTest(CppStyleTestBase): 2040 def setUp(self): 2041 self.include_state = cpp_style._IncludeState() 2042 2043 # Cheat os.path.abspath called in FileInfo class. 2044 self.os_path_abspath_orig = os.path.abspath 2045 os.path.abspath = lambda value: value 2046 2047 def tearDown(self): 2048 os.path.abspath = self.os_path_abspath_orig 2049 2050 def test_try_drop_common_suffixes(self): 2051 self.assertEqual('foo/foo', cpp_style._drop_common_suffixes('foo/foo-inl.h')) 2052 self.assertEqual('foo/bar/foo', 2053 cpp_style._drop_common_suffixes('foo/bar/foo_inl.h')) 2054 self.assertEqual('foo/foo', cpp_style._drop_common_suffixes('foo/foo.cpp')) 2055 self.assertEqual('foo/foo_unusualinternal', 2056 cpp_style._drop_common_suffixes('foo/foo_unusualinternal.h')) 2057 self.assertEqual('', 2058 cpp_style._drop_common_suffixes('_test.cpp')) 2059 self.assertEqual('test', 2060 cpp_style._drop_common_suffixes('test.cpp')) 2061 2062 2063class OrderOfIncludesTest(CppStyleTestBase): 2064 def setUp(self): 2065 self.include_state = cpp_style._IncludeState() 2066 2067 # Cheat os.path.abspath called in FileInfo class. 2068 self.os_path_abspath_orig = os.path.abspath 2069 os.path.abspath = lambda value: value 2070 2071 def tearDown(self): 2072 os.path.abspath = self.os_path_abspath_orig 2073 2074 def test_check_next_include_order__no_config(self): 2075 self.assertEqual('Header file should not contain WebCore config.h.', 2076 self.include_state.check_next_include_order(cpp_style._CONFIG_HEADER, True)) 2077 2078 def test_check_next_include_order__no_self(self): 2079 self.assertEqual('Header file should not contain itself.', 2080 self.include_state.check_next_include_order(cpp_style._PRIMARY_HEADER, True)) 2081 # Test actual code to make sure that header types are correctly assigned. 2082 self.assert_language_rules_check('Foo.h', 2083 '#include "Foo.h"\n', 2084 'Header file should not contain itself. Should be: alphabetically sorted.' 2085 ' [build/include_order] [4]') 2086 self.assert_language_rules_check('FooBar.h', 2087 '#include "Foo.h"\n', 2088 '') 2089 2090 def test_check_next_include_order__likely_then_config(self): 2091 self.assertEqual('Found header this file implements before WebCore config.h.', 2092 self.include_state.check_next_include_order(cpp_style._PRIMARY_HEADER, False)) 2093 self.assertEqual('Found WebCore config.h after a header this file implements.', 2094 self.include_state.check_next_include_order(cpp_style._CONFIG_HEADER, False)) 2095 2096 def test_check_next_include_order__other_then_config(self): 2097 self.assertEqual('Found other header before WebCore config.h.', 2098 self.include_state.check_next_include_order(cpp_style._OTHER_HEADER, False)) 2099 self.assertEqual('Found WebCore config.h after other header.', 2100 self.include_state.check_next_include_order(cpp_style._CONFIG_HEADER, False)) 2101 2102 def test_check_next_include_order__config_then_other_then_likely(self): 2103 self.assertEqual('', self.include_state.check_next_include_order(cpp_style._CONFIG_HEADER, False)) 2104 self.assertEqual('Found other header before a header this file implements.', 2105 self.include_state.check_next_include_order(cpp_style._OTHER_HEADER, False)) 2106 self.assertEqual('Found header this file implements after other header.', 2107 self.include_state.check_next_include_order(cpp_style._PRIMARY_HEADER, False)) 2108 2109 def test_check_alphabetical_include_order(self): 2110 self.assert_language_rules_check('foo.h', 2111 '#include "a.h"\n' 2112 '#include "c.h"\n' 2113 '#include "b.h"\n', 2114 'Alphabetical sorting problem. [build/include_order] [4]') 2115 2116 self.assert_language_rules_check('foo.h', 2117 '#include "a.h"\n' 2118 '#include "b.h"\n' 2119 '#include "c.h"\n', 2120 '') 2121 2122 self.assert_language_rules_check('foo.h', 2123 '#include <assert.h>\n' 2124 '#include "bar.h"\n', 2125 'Alphabetical sorting problem. [build/include_order] [4]') 2126 2127 self.assert_language_rules_check('foo.h', 2128 '#include "bar.h"\n' 2129 '#include <assert.h>\n', 2130 '') 2131 2132 def test_check_line_break_after_own_header(self): 2133 self.assert_language_rules_check('foo.cpp', 2134 '#include "config.h"\n' 2135 '#include "foo.h"\n' 2136 '#include "bar.h"\n', 2137 'You should add a blank line after implementation file\'s own header. [build/include_order] [4]') 2138 2139 self.assert_language_rules_check('foo.cpp', 2140 '#include "config.h"\n' 2141 '#include "foo.h"\n' 2142 '\n' 2143 '#include "bar.h"\n', 2144 '') 2145 2146 def test_check_preprocessor_in_include_section(self): 2147 self.assert_language_rules_check('foo.cpp', 2148 '#include "config.h"\n' 2149 '#include "foo.h"\n' 2150 '\n' 2151 '#ifdef BAZ\n' 2152 '#include "baz.h"\n' 2153 '#else\n' 2154 '#include "foobar.h"\n' 2155 '#endif"\n' 2156 '#include "bar.h"\n', # No flag because previous is in preprocessor section 2157 '') 2158 2159 self.assert_language_rules_check('foo.cpp', 2160 '#include "config.h"\n' 2161 '#include "foo.h"\n' 2162 '\n' 2163 '#ifdef BAZ\n' 2164 '#include "baz.h"\n' 2165 '#endif"\n' 2166 '#include "bar.h"\n' 2167 '#include "a.h"\n', # Should still flag this. 2168 'Alphabetical sorting problem. [build/include_order] [4]') 2169 2170 self.assert_language_rules_check('foo.cpp', 2171 '#include "config.h"\n' 2172 '#include "foo.h"\n' 2173 '\n' 2174 '#ifdef BAZ\n' 2175 '#include "baz.h"\n' 2176 '#include "bar.h"\n' #Should still flag this 2177 '#endif"\n', 2178 'Alphabetical sorting problem. [build/include_order] [4]') 2179 2180 self.assert_language_rules_check('foo.cpp', 2181 '#include "config.h"\n' 2182 '#include "foo.h"\n' 2183 '\n' 2184 '#ifdef BAZ\n' 2185 '#include "baz.h"\n' 2186 '#endif"\n' 2187 '#ifdef FOOBAR\n' 2188 '#include "foobar.h"\n' 2189 '#endif"\n' 2190 '#include "bar.h"\n' 2191 '#include "a.h"\n', # Should still flag this. 2192 'Alphabetical sorting problem. [build/include_order] [4]') 2193 2194 # Check that after an already included error, the sorting rules still work. 2195 self.assert_language_rules_check('foo.cpp', 2196 '#include "config.h"\n' 2197 '#include "foo.h"\n' 2198 '\n' 2199 '#include "foo.h"\n' 2200 '#include "g.h"\n', 2201 '"foo.h" already included at foo.cpp:1 [build/include] [4]') 2202 2203 def test_check_wtf_includes(self): 2204 self.assert_language_rules_check('foo.cpp', 2205 '#include "config.h"\n' 2206 '#include "foo.h"\n' 2207 '\n' 2208 '#include <wtf/Assertions.h>\n', 2209 '') 2210 self.assert_language_rules_check('foo.cpp', 2211 '#include "config.h"\n' 2212 '#include "foo.h"\n' 2213 '\n' 2214 '#include "wtf/Assertions.h"\n', 2215 'wtf includes should be <wtf/file.h> instead of "wtf/file.h".' 2216 ' [build/include] [4]') 2217 2218 def test_classify_include(self): 2219 classify_include = cpp_style._classify_include 2220 include_state = cpp_style._IncludeState() 2221 self.assertEqual(cpp_style._CONFIG_HEADER, 2222 classify_include('foo/foo.cpp', 2223 'config.h', 2224 False, include_state)) 2225 self.assertEqual(cpp_style._PRIMARY_HEADER, 2226 classify_include('foo/internal/foo.cpp', 2227 'foo/public/foo.h', 2228 False, include_state)) 2229 self.assertEqual(cpp_style._PRIMARY_HEADER, 2230 classify_include('foo/internal/foo.cpp', 2231 'foo/other/public/foo.h', 2232 False, include_state)) 2233 self.assertEqual(cpp_style._OTHER_HEADER, 2234 classify_include('foo/internal/foo.cpp', 2235 'foo/other/public/foop.h', 2236 False, include_state)) 2237 self.assertEqual(cpp_style._OTHER_HEADER, 2238 classify_include('foo/foo.cpp', 2239 'string', 2240 True, include_state)) 2241 self.assertEqual(cpp_style._PRIMARY_HEADER, 2242 classify_include('fooCustom.cpp', 2243 'foo.h', 2244 False, include_state)) 2245 # Tricky example where both includes might be classified as primary. 2246 self.assert_language_rules_check('ScrollbarThemeWince.cpp', 2247 '#include "config.h"\n' 2248 '#include "ScrollbarThemeWince.h"\n' 2249 '\n' 2250 '#include "Scrollbar.h"\n', 2251 '') 2252 self.assert_language_rules_check('ScrollbarThemeWince.cpp', 2253 '#include "config.h"\n' 2254 '#include "Scrollbar.h"\n' 2255 '\n' 2256 '#include "ScrollbarThemeWince.h"\n', 2257 'Found header this file implements after a header this file implements.' 2258 ' Should be: config.h, primary header, blank line, and then alphabetically sorted.' 2259 ' [build/include_order] [4]') 2260 2261 def test_try_drop_common_suffixes(self): 2262 self.assertEqual('foo/foo', cpp_style._drop_common_suffixes('foo/foo-inl.h')) 2263 self.assertEqual('foo/bar/foo', 2264 cpp_style._drop_common_suffixes('foo/bar/foo_inl.h')) 2265 self.assertEqual('foo/foo', cpp_style._drop_common_suffixes('foo/foo.cpp')) 2266 self.assertEqual('foo/foo_unusualinternal', 2267 cpp_style._drop_common_suffixes('foo/foo_unusualinternal.h')) 2268 self.assertEqual('', 2269 cpp_style._drop_common_suffixes('_test.cpp')) 2270 self.assertEqual('test', 2271 cpp_style._drop_common_suffixes('test.cpp')) 2272 self.assertEqual('test', 2273 cpp_style._drop_common_suffixes('test.cpp')) 2274 2275class CheckForFunctionLengthsTest(CppStyleTestBase): 2276 def setUp(self): 2277 # Reducing these thresholds for the tests speeds up tests significantly. 2278 self.old_normal_trigger = cpp_style._FunctionState._NORMAL_TRIGGER 2279 self.old_test_trigger = cpp_style._FunctionState._TEST_TRIGGER 2280 2281 cpp_style._FunctionState._NORMAL_TRIGGER = 10 2282 cpp_style._FunctionState._TEST_TRIGGER = 25 2283 2284 def tearDown(self): 2285 cpp_style._FunctionState._NORMAL_TRIGGER = self.old_normal_trigger 2286 cpp_style._FunctionState._TEST_TRIGGER = self.old_test_trigger 2287 2288 def assert_function_lengths_check(self, code, expected_message): 2289 """Check warnings for long function bodies are as expected. 2290 2291 Args: 2292 code: C++ source code expected to generate a warning message. 2293 expected_message: Message expected to be generated by the C++ code. 2294 """ 2295 self.assertEquals(expected_message, 2296 self.perform_function_lengths_check(code)) 2297 2298 def trigger_lines(self, error_level): 2299 """Return number of lines needed to trigger a function length warning. 2300 2301 Args: 2302 error_level: --v setting for cpp_style. 2303 2304 Returns: 2305 Number of lines needed to trigger a function length warning. 2306 """ 2307 return cpp_style._FunctionState._NORMAL_TRIGGER * 2 ** error_level 2308 2309 def trigger_test_lines(self, error_level): 2310 """Return number of lines needed to trigger a test function length warning. 2311 2312 Args: 2313 error_level: --v setting for cpp_style. 2314 2315 Returns: 2316 Number of lines needed to trigger a test function length warning. 2317 """ 2318 return cpp_style._FunctionState._TEST_TRIGGER * 2 ** error_level 2319 2320 def assert_function_length_check_definition(self, lines, error_level): 2321 """Generate long function definition and check warnings are as expected. 2322 2323 Args: 2324 lines: Number of lines to generate. 2325 error_level: --v setting for cpp_style. 2326 """ 2327 trigger_level = self.trigger_lines(cpp_style._verbose_level()) 2328 self.assert_function_lengths_check( 2329 'void test(int x)' + self.function_body(lines), 2330 ('Small and focused functions are preferred: ' 2331 'test() has %d non-comment lines ' 2332 '(error triggered by exceeding %d lines).' 2333 ' [readability/fn_size] [%d]' 2334 % (lines, trigger_level, error_level))) 2335 2336 def assert_function_length_check_definition_ok(self, lines): 2337 """Generate shorter function definition and check no warning is produced. 2338 2339 Args: 2340 lines: Number of lines to generate. 2341 """ 2342 self.assert_function_lengths_check( 2343 'void test(int x)' + self.function_body(lines), 2344 '') 2345 2346 def assert_function_length_check_at_error_level(self, error_level): 2347 """Generate and check function at the trigger level for --v setting. 2348 2349 Args: 2350 error_level: --v setting for cpp_style. 2351 """ 2352 self.assert_function_length_check_definition(self.trigger_lines(error_level), 2353 error_level) 2354 2355 def assert_function_length_check_below_error_level(self, error_level): 2356 """Generate and check function just below the trigger level for --v setting. 2357 2358 Args: 2359 error_level: --v setting for cpp_style. 2360 """ 2361 self.assert_function_length_check_definition(self.trigger_lines(error_level) - 1, 2362 error_level - 1) 2363 2364 def assert_function_length_check_above_error_level(self, error_level): 2365 """Generate and check function just above the trigger level for --v setting. 2366 2367 Args: 2368 error_level: --v setting for cpp_style. 2369 """ 2370 self.assert_function_length_check_definition(self.trigger_lines(error_level) + 1, 2371 error_level) 2372 2373 def function_body(self, number_of_lines): 2374 return ' {\n' + ' this_is_just_a_test();\n' * number_of_lines + '}' 2375 2376 def function_body_with_blank_lines(self, number_of_lines): 2377 return ' {\n' + ' this_is_just_a_test();\n\n' * number_of_lines + '}' 2378 2379 def function_body_with_no_lints(self, number_of_lines): 2380 return ' {\n' + ' this_is_just_a_test(); // NOLINT\n' * number_of_lines + '}' 2381 2382 # Test line length checks. 2383 def test_function_length_check_declaration(self): 2384 self.assert_function_lengths_check( 2385 'void test();', # Not a function definition 2386 '') 2387 2388 def test_function_length_check_declaration_with_block_following(self): 2389 self.assert_function_lengths_check( 2390 ('void test();\n' 2391 + self.function_body(66)), # Not a function definition 2392 '') 2393 2394 def test_function_length_check_class_definition(self): 2395 self.assert_function_lengths_check( # Not a function definition 2396 'class Test' + self.function_body(66) + ';', 2397 '') 2398 2399 def test_function_length_check_trivial(self): 2400 self.assert_function_lengths_check( 2401 'void test() {}', # Not counted 2402 '') 2403 2404 def test_function_length_check_empty(self): 2405 self.assert_function_lengths_check( 2406 'void test() {\n}', 2407 '') 2408 2409 def test_function_length_check_definition_below_severity0(self): 2410 old_verbosity = cpp_style._set_verbose_level(0) 2411 self.assert_function_length_check_definition_ok(self.trigger_lines(0) - 1) 2412 cpp_style._set_verbose_level(old_verbosity) 2413 2414 def test_function_length_check_definition_at_severity0(self): 2415 old_verbosity = cpp_style._set_verbose_level(0) 2416 self.assert_function_length_check_definition_ok(self.trigger_lines(0)) 2417 cpp_style._set_verbose_level(old_verbosity) 2418 2419 def test_function_length_check_definition_above_severity0(self): 2420 old_verbosity = cpp_style._set_verbose_level(0) 2421 self.assert_function_length_check_above_error_level(0) 2422 cpp_style._set_verbose_level(old_verbosity) 2423 2424 def test_function_length_check_definition_below_severity1v0(self): 2425 old_verbosity = cpp_style._set_verbose_level(0) 2426 self.assert_function_length_check_below_error_level(1) 2427 cpp_style._set_verbose_level(old_verbosity) 2428 2429 def test_function_length_check_definition_at_severity1v0(self): 2430 old_verbosity = cpp_style._set_verbose_level(0) 2431 self.assert_function_length_check_at_error_level(1) 2432 cpp_style._set_verbose_level(old_verbosity) 2433 2434 def test_function_length_check_definition_below_severity1(self): 2435 self.assert_function_length_check_definition_ok(self.trigger_lines(1) - 1) 2436 2437 def test_function_length_check_definition_at_severity1(self): 2438 self.assert_function_length_check_definition_ok(self.trigger_lines(1)) 2439 2440 def test_function_length_check_definition_above_severity1(self): 2441 self.assert_function_length_check_above_error_level(1) 2442 2443 def test_function_length_check_definition_severity1_plus_blanks(self): 2444 error_level = 1 2445 error_lines = self.trigger_lines(error_level) + 1 2446 trigger_level = self.trigger_lines(cpp_style._verbose_level()) 2447 self.assert_function_lengths_check( 2448 'void test_blanks(int x)' + self.function_body(error_lines), 2449 ('Small and focused functions are preferred: ' 2450 'test_blanks() has %d non-comment lines ' 2451 '(error triggered by exceeding %d lines).' 2452 ' [readability/fn_size] [%d]') 2453 % (error_lines, trigger_level, error_level)) 2454 2455 def test_function_length_check_complex_definition_severity1(self): 2456 error_level = 1 2457 error_lines = self.trigger_lines(error_level) + 1 2458 trigger_level = self.trigger_lines(cpp_style._verbose_level()) 2459 self.assert_function_lengths_check( 2460 ('my_namespace::my_other_namespace::MyVeryLongTypeName*\n' 2461 'my_namespace::my_other_namespace::MyFunction(int arg1, char* arg2)' 2462 + self.function_body(error_lines)), 2463 ('Small and focused functions are preferred: ' 2464 'my_namespace::my_other_namespace::MyFunction()' 2465 ' has %d non-comment lines ' 2466 '(error triggered by exceeding %d lines).' 2467 ' [readability/fn_size] [%d]') 2468 % (error_lines, trigger_level, error_level)) 2469 2470 def test_function_length_check_definition_severity1_for_test(self): 2471 error_level = 1 2472 error_lines = self.trigger_test_lines(error_level) + 1 2473 trigger_level = self.trigger_test_lines(cpp_style._verbose_level()) 2474 self.assert_function_lengths_check( 2475 'TEST_F(Test, Mutator)' + self.function_body(error_lines), 2476 ('Small and focused functions are preferred: ' 2477 'TEST_F(Test, Mutator) has %d non-comment lines ' 2478 '(error triggered by exceeding %d lines).' 2479 ' [readability/fn_size] [%d]') 2480 % (error_lines, trigger_level, error_level)) 2481 2482 def test_function_length_check_definition_severity1_for_split_line_test(self): 2483 error_level = 1 2484 error_lines = self.trigger_test_lines(error_level) + 1 2485 trigger_level = self.trigger_test_lines(cpp_style._verbose_level()) 2486 self.assert_function_lengths_check( 2487 ('TEST_F(GoogleUpdateRecoveryRegistryProtectedTest,\n' 2488 ' FixGoogleUpdate_AllValues_MachineApp)' # note: 4 spaces 2489 + self.function_body(error_lines)), 2490 ('Small and focused functions are preferred: ' 2491 'TEST_F(GoogleUpdateRecoveryRegistryProtectedTest, ' # 1 space 2492 'FixGoogleUpdate_AllValues_MachineApp) has %d non-comment lines ' 2493 '(error triggered by exceeding %d lines).' 2494 ' [readability/fn_size] [%d]') 2495 % (error_lines+1, trigger_level, error_level)) 2496 2497 def test_function_length_check_definition_severity1_for_bad_test_doesnt_break(self): 2498 error_level = 1 2499 error_lines = self.trigger_test_lines(error_level) + 1 2500 trigger_level = self.trigger_test_lines(cpp_style._verbose_level()) 2501 self.assert_function_lengths_check( 2502 ('TEST_F(' 2503 + self.function_body(error_lines)), 2504 ('Small and focused functions are preferred: ' 2505 'TEST_F has %d non-comment lines ' 2506 '(error triggered by exceeding %d lines).' 2507 ' [readability/fn_size] [%d]') 2508 % (error_lines, trigger_level, error_level)) 2509 2510 def test_function_length_check_definition_severity1_with_embedded_no_lints(self): 2511 error_level = 1 2512 error_lines = self.trigger_lines(error_level) + 1 2513 trigger_level = self.trigger_lines(cpp_style._verbose_level()) 2514 self.assert_function_lengths_check( 2515 'void test(int x)' + self.function_body_with_no_lints(error_lines), 2516 ('Small and focused functions are preferred: ' 2517 'test() has %d non-comment lines ' 2518 '(error triggered by exceeding %d lines).' 2519 ' [readability/fn_size] [%d]') 2520 % (error_lines, trigger_level, error_level)) 2521 2522 def test_function_length_check_definition_severity1_with_no_lint(self): 2523 self.assert_function_lengths_check( 2524 ('void test(int x)' + self.function_body(self.trigger_lines(1)) 2525 + ' // NOLINT -- long function'), 2526 '') 2527 2528 def test_function_length_check_definition_below_severity2(self): 2529 self.assert_function_length_check_below_error_level(2) 2530 2531 def test_function_length_check_definition_severity2(self): 2532 self.assert_function_length_check_at_error_level(2) 2533 2534 def test_function_length_check_definition_above_severity2(self): 2535 self.assert_function_length_check_above_error_level(2) 2536 2537 def test_function_length_check_definition_below_severity3(self): 2538 self.assert_function_length_check_below_error_level(3) 2539 2540 def test_function_length_check_definition_severity3(self): 2541 self.assert_function_length_check_at_error_level(3) 2542 2543 def test_function_length_check_definition_above_severity3(self): 2544 self.assert_function_length_check_above_error_level(3) 2545 2546 def test_function_length_check_definition_below_severity4(self): 2547 self.assert_function_length_check_below_error_level(4) 2548 2549 def test_function_length_check_definition_severity4(self): 2550 self.assert_function_length_check_at_error_level(4) 2551 2552 def test_function_length_check_definition_above_severity4(self): 2553 self.assert_function_length_check_above_error_level(4) 2554 2555 def test_function_length_check_definition_below_severity5(self): 2556 self.assert_function_length_check_below_error_level(5) 2557 2558 def test_function_length_check_definition_at_severity5(self): 2559 self.assert_function_length_check_at_error_level(5) 2560 2561 def test_function_length_check_definition_above_severity5(self): 2562 self.assert_function_length_check_above_error_level(5) 2563 2564 def test_function_length_check_definition_huge_lines(self): 2565 # 5 is the limit 2566 self.assert_function_length_check_definition(self.trigger_lines(10), 5) 2567 2568 def test_function_length_not_determinable(self): 2569 # Macro invocation without terminating semicolon. 2570 self.assert_function_lengths_check( 2571 'MACRO(arg)', 2572 '') 2573 2574 # Macro with underscores 2575 self.assert_function_lengths_check( 2576 'MACRO_WITH_UNDERSCORES(arg1, arg2, arg3)', 2577 '') 2578 2579 self.assert_function_lengths_check( 2580 'NonMacro(arg)', 2581 'Lint failed to find start of function body.' 2582 ' [readability/fn_size] [5]') 2583 2584 2585class NoNonVirtualDestructorsTest(CppStyleTestBase): 2586 2587 def test_no_error(self): 2588 self.assert_multi_line_lint( 2589 '''class Foo { 2590 virtual ~Foo(); 2591 virtual void foo(); 2592 };''', 2593 '') 2594 2595 self.assert_multi_line_lint( 2596 '''class Foo { 2597 virtual inline ~Foo(); 2598 virtual void foo(); 2599 };''', 2600 '') 2601 2602 self.assert_multi_line_lint( 2603 '''class Foo { 2604 inline virtual ~Foo(); 2605 virtual void foo(); 2606 };''', 2607 '') 2608 2609 self.assert_multi_line_lint( 2610 '''class Foo::Goo { 2611 virtual ~Goo(); 2612 virtual void goo(); 2613 };''', 2614 '') 2615 self.assert_multi_line_lint( 2616 'class Foo { void foo(); };', 2617 'More than one command on the same line [whitespace/newline] [4]') 2618 2619 self.assert_multi_line_lint( 2620 '''class Qualified::Goo : public Foo { 2621 virtual void goo(); 2622 };''', 2623 '') 2624 2625 self.assert_multi_line_lint( 2626 # Line-ending : 2627 '''class Goo : 2628 public Foo { 2629 virtual void goo(); 2630 };''', 2631 'Labels should always be indented at least one space. If this is a ' 2632 'member-initializer list in a constructor, the colon should be on the ' 2633 'line after the definition header. [whitespace/labels] [4]') 2634 2635 def test_no_destructor_when_virtual_needed(self): 2636 self.assert_multi_line_lint_re( 2637 '''class Foo { 2638 virtual void foo(); 2639 };''', 2640 'The class Foo probably needs a virtual destructor') 2641 2642 def test_destructor_non_virtual_when_virtual_needed(self): 2643 self.assert_multi_line_lint_re( 2644 '''class Foo { 2645 ~Foo(); 2646 virtual void foo(); 2647 };''', 2648 'The class Foo probably needs a virtual destructor') 2649 2650 def test_no_warn_when_derived(self): 2651 self.assert_multi_line_lint( 2652 '''class Foo : public Goo { 2653 virtual void foo(); 2654 };''', 2655 '') 2656 2657 def test_internal_braces(self): 2658 self.assert_multi_line_lint_re( 2659 '''class Foo { 2660 enum Goo { 2661 GOO 2662 }; 2663 virtual void foo(); 2664 };''', 2665 'The class Foo probably needs a virtual destructor') 2666 2667 def test_inner_class_needs_virtual_destructor(self): 2668 self.assert_multi_line_lint_re( 2669 '''class Foo { 2670 class Goo { 2671 virtual void goo(); 2672 }; 2673 };''', 2674 'The class Goo probably needs a virtual destructor') 2675 2676 def test_outer_class_needs_virtual_destructor(self): 2677 self.assert_multi_line_lint_re( 2678 '''class Foo { 2679 class Goo { 2680 }; 2681 virtual void foo(); 2682 };''', 2683 'The class Foo probably needs a virtual destructor') 2684 2685 def test_qualified_class_needs_virtual_destructor(self): 2686 self.assert_multi_line_lint_re( 2687 '''class Qualified::Foo { 2688 virtual void foo(); 2689 };''', 2690 'The class Qualified::Foo probably needs a virtual destructor') 2691 2692 def test_multi_line_declaration_no_error(self): 2693 self.assert_multi_line_lint_re( 2694 '''class Foo 2695 : public Goo { 2696 virtual void foo(); 2697 };''', 2698 '') 2699 2700 def test_multi_line_declaration_with_error(self): 2701 self.assert_multi_line_lint( 2702 '''class Foo 2703 { 2704 virtual void foo(); 2705 };''', 2706 ['This { should be at the end of the previous line ' 2707 '[whitespace/braces] [4]', 2708 'The class Foo probably needs a virtual destructor due to having ' 2709 'virtual method(s), one declared at line 2. [runtime/virtual] [4]']) 2710 2711 2712class CppStyleStateTest(unittest.TestCase): 2713 def test_error_count(self): 2714 self.assertEquals(0, cpp_style.error_count()) 2715 cpp_style._cpp_style_state.increment_error_count() 2716 cpp_style._cpp_style_state.increment_error_count() 2717 self.assertEquals(2, cpp_style.error_count()) 2718 cpp_style._cpp_style_state.reset_error_count() 2719 self.assertEquals(0, cpp_style.error_count()) 2720 2721 2722class WebKitStyleTest(CppStyleTestBase): 2723 2724 # for http://webkit.org/coding/coding-style.html 2725 def test_indentation(self): 2726 # 1. Use spaces, not tabs. Tabs should only appear in files that 2727 # require them for semantic meaning, like Makefiles. 2728 self.assert_multi_line_lint( 2729 'class Foo {\n' 2730 ' int goo;\n' 2731 '};', 2732 '') 2733 self.assert_multi_line_lint( 2734 'class Foo {\n' 2735 '\tint goo;\n' 2736 '};', 2737 'Tab found; better to use spaces [whitespace/tab] [1]') 2738 2739 # 2. The indent size is 4 spaces. 2740 self.assert_multi_line_lint( 2741 'class Foo {\n' 2742 ' int goo;\n' 2743 '};', 2744 '') 2745 self.assert_multi_line_lint( 2746 'class Foo {\n' 2747 ' int goo;\n' 2748 '};', 2749 'Weird number of spaces at line-start. Are you using a 4-space indent? [whitespace/indent] [3]') 2750 # FIXME: No tests for 8-spaces. 2751 2752 # 3. In a header, code inside a namespace should be indented. 2753 self.assert_multi_line_lint( 2754 'namespace WebCore {\n\n' 2755 ' class Document {\n' 2756 ' int myVariable;\n' 2757 ' };\n' 2758 '}', 2759 '', 2760 'foo.h') 2761 self.assert_multi_line_lint( 2762 'namespace OuterNamespace {\n' 2763 ' namespace InnerNamespace {\n' 2764 ' class Document {\n' 2765 ' };\n' 2766 ' };\n' 2767 '}', 2768 '', 2769 'foo.h') 2770 self.assert_multi_line_lint( 2771 'namespace WebCore {\n' 2772 '#if 0\n' 2773 ' class Document {\n' 2774 ' };\n' 2775 '#endif\n' 2776 '}', 2777 '', 2778 'foo.h') 2779 self.assert_multi_line_lint( 2780 'namespace WebCore {\n' 2781 'class Document {\n' 2782 '};\n' 2783 '}', 2784 'In a header, code inside a namespace should be indented.' 2785 ' [whitespace/indent] [4]', 2786 'foo.h') 2787 2788 # 4. In an implementation file (files with the extension .cpp, .c 2789 # or .mm), code inside a namespace should not be indented. 2790 self.assert_multi_line_lint( 2791 'namespace WebCore {\n\n' 2792 'Document::Foo()\n' 2793 ' : foo(bar)\n' 2794 ' , boo(far)\n' 2795 '{\n' 2796 ' stuff();\n' 2797 '}', 2798 '', 2799 'foo.cpp') 2800 self.assert_multi_line_lint( 2801 'namespace OuterNamespace {\n' 2802 'namespace InnerNamespace {\n' 2803 'Document::Foo() { }\n' 2804 '}', 2805 '', 2806 'foo.cpp') 2807 self.assert_multi_line_lint( 2808 ' namespace WebCore {\n\n' 2809 'start: // Pointless code, but tests the label regexp.\n' 2810 ' goto start;\n' 2811 ' }', 2812 '', 2813 'foo.cpp') 2814 self.assert_multi_line_lint( 2815 ' namespace WebCore {\n\n' 2816 ' void Document::Foo()\n' 2817 ' {\n' 2818 'start: // infinite loops are fun!\n' 2819 ' goto start;\n' 2820 ' }', 2821 '', 2822 'foo.cpp') 2823 self.assert_multi_line_lint( 2824 'namespace WebCore {\n' 2825 ' Document::Foo() { }\n' 2826 '}', 2827 'In an implementation file, code inside a namespace should not be indented.' 2828 ' [whitespace/indent] [4]', 2829 'foo.cpp') 2830 2831 # 5. A case label should line up with its switch statement. The 2832 # case statement is indented. 2833 self.assert_multi_line_lint( 2834 ' switch (condition) {\n' 2835 ' case fooCondition:\n' 2836 ' case barCondition:\n' 2837 ' i++;\n' 2838 ' break;\n' 2839 ' default:\n' 2840 ' i--;\n' 2841 ' }\n', 2842 '') 2843 self.assert_multi_line_lint( 2844 ' switch (condition) {\n' 2845 ' case fooCondition:\n' 2846 ' switch (otherCondition) {\n' 2847 ' default:\n' 2848 ' return;\n' 2849 ' }\n' 2850 ' default:\n' 2851 ' i--;\n' 2852 ' }\n', 2853 '') 2854 self.assert_multi_line_lint( 2855 ' switch (condition) {\n' 2856 ' case fooCondition: break;\n' 2857 ' default: return;\n' 2858 ' }\n', 2859 '') 2860 self.assert_multi_line_lint( 2861 ' switch (condition) {\n' 2862 ' case fooCondition:\n' 2863 ' case barCondition:\n' 2864 ' i++;\n' 2865 ' break;\n' 2866 ' default:\n' 2867 ' i--;\n' 2868 ' }\n', 2869 'A case label should not be indented, but line up with its switch statement.' 2870 ' [whitespace/indent] [4]') 2871 self.assert_multi_line_lint( 2872 ' switch (condition) {\n' 2873 ' case fooCondition:\n' 2874 ' break;\n' 2875 ' default:\n' 2876 ' i--;\n' 2877 ' }\n', 2878 'A case label should not be indented, but line up with its switch statement.' 2879 ' [whitespace/indent] [4]') 2880 self.assert_multi_line_lint( 2881 ' switch (condition) {\n' 2882 ' case fooCondition:\n' 2883 ' case barCondition:\n' 2884 ' switch (otherCondition) {\n' 2885 ' default:\n' 2886 ' return;\n' 2887 ' }\n' 2888 ' default:\n' 2889 ' i--;\n' 2890 ' }\n', 2891 'A case label should not be indented, but line up with its switch statement.' 2892 ' [whitespace/indent] [4]') 2893 self.assert_multi_line_lint( 2894 ' switch (condition) {\n' 2895 ' case fooCondition:\n' 2896 ' case barCondition:\n' 2897 ' i++;\n' 2898 ' break;\n\n' 2899 ' default:\n' 2900 ' i--;\n' 2901 ' }\n', 2902 'Non-label code inside switch statements should be indented.' 2903 ' [whitespace/indent] [4]') 2904 self.assert_multi_line_lint( 2905 ' switch (condition) {\n' 2906 ' case fooCondition:\n' 2907 ' case barCondition:\n' 2908 ' switch (otherCondition) {\n' 2909 ' default:\n' 2910 ' return;\n' 2911 ' }\n' 2912 ' default:\n' 2913 ' i--;\n' 2914 ' }\n', 2915 'Non-label code inside switch statements should be indented.' 2916 ' [whitespace/indent] [4]') 2917 2918 # 6. Boolean expressions at the same nesting level that span 2919 # multiple lines should have their operators on the left side of 2920 # the line instead of the right side. 2921 self.assert_multi_line_lint( 2922 ' return attr->name() == srcAttr\n' 2923 ' || attr->name() == lowsrcAttr;\n', 2924 '') 2925 self.assert_multi_line_lint( 2926 ' return attr->name() == srcAttr ||\n' 2927 ' attr->name() == lowsrcAttr;\n', 2928 'Boolean expressions that span multiple lines should have their ' 2929 'operators on the left side of the line instead of the right side.' 2930 ' [whitespace/operators] [4]') 2931 2932 def test_spacing(self): 2933 # 1. Do not place spaces around unary operators. 2934 self.assert_multi_line_lint( 2935 'i++;', 2936 '') 2937 self.assert_multi_line_lint( 2938 'i ++;', 2939 'Extra space for operator ++; [whitespace/operators] [4]') 2940 2941 # 2. Do place spaces around binary and ternary operators. 2942 self.assert_multi_line_lint( 2943 'y = m * x + b;', 2944 '') 2945 self.assert_multi_line_lint( 2946 'f(a, b);', 2947 '') 2948 self.assert_multi_line_lint( 2949 'c = a | b;', 2950 '') 2951 self.assert_multi_line_lint( 2952 'return condition ? 1 : 0;', 2953 '') 2954 self.assert_multi_line_lint( 2955 'y=m*x+b;', 2956 'Missing spaces around = [whitespace/operators] [4]') 2957 self.assert_multi_line_lint( 2958 'f(a,b);', 2959 'Missing space after , [whitespace/comma] [3]') 2960 self.assert_multi_line_lint( 2961 'c = a|b;', 2962 '') 2963 # FIXME: We cannot catch this lint error. 2964 # self.assert_multi_line_lint( 2965 # 'return condition ? 1:0;', 2966 # '') 2967 2968 # 3. Place spaces between control statements and their parentheses. 2969 self.assert_multi_line_lint( 2970 ' if (condition)\n' 2971 ' doIt();\n', 2972 '') 2973 self.assert_multi_line_lint( 2974 ' if(condition)\n' 2975 ' doIt();\n', 2976 'Missing space before ( in if( [whitespace/parens] [5]') 2977 2978 # 4. Do not place spaces between a function and its parentheses, 2979 # or between a parenthesis and its content. 2980 self.assert_multi_line_lint( 2981 'f(a, b);', 2982 '') 2983 self.assert_multi_line_lint( 2984 'f (a, b);', 2985 'Extra space before ( in function call [whitespace/parens] [4]') 2986 self.assert_multi_line_lint( 2987 'f( a, b );', 2988 ['Extra space after ( in function call [whitespace/parens] [4]', 2989 'Extra space before ) [whitespace/parens] [2]']) 2990 2991 def test_line_breaking(self): 2992 # 1. Each statement should get its own line. 2993 self.assert_multi_line_lint( 2994 ' x++;\n' 2995 ' y++;\n' 2996 ' if (condition);\n' 2997 ' doIt();\n', 2998 '') 2999 self.assert_multi_line_lint( 3000 ' x++; y++;', 3001 'More than one command on the same line [whitespace/newline] [4]') 3002 # FIXME: Make this fail. 3003 # self.assert_multi_line_lint( 3004 # ' if (condition) doIt();\n', 3005 # '') 3006 3007 # 2. An else statement should go on the same line as a preceding 3008 # close brace if one is present, else it should line up with the 3009 # if statement. 3010 self.assert_multi_line_lint( 3011 'if (condition) {\n' 3012 ' doSomething();\n' 3013 ' doSomethingAgain();\n' 3014 '} else {\n' 3015 ' doSomethingElse();\n' 3016 ' doSomethingElseAgain();\n' 3017 '}\n', 3018 '') 3019 self.assert_multi_line_lint( 3020 'if (condition)\n' 3021 ' doSomething();\n' 3022 'else\n' 3023 ' doSomethingElse();\n', 3024 '') 3025 self.assert_multi_line_lint( 3026 'if (condition)\n' 3027 ' doSomething();\n' 3028 'else {\n' 3029 ' doSomethingElse();\n' 3030 ' doSomethingElseAgain();\n' 3031 '}\n', 3032 '') 3033 3034 self.assert_multi_line_lint( 3035 'if (condition) {\n' 3036 ' doSomething();\n' 3037 ' doSomethingAgain();\n' 3038 '}\n' 3039 'else {\n' 3040 ' doSomethingElse();\n' 3041 ' doSomethingElseAgain();\n' 3042 '}\n', 3043 'An else should appear on the same line as the preceding } [whitespace/newline] [4]') 3044 self.assert_multi_line_lint( 3045 'if (condition) doSomething(); else doSomethingElse();\n', 3046 ['More than one command on the same line [whitespace/newline] [4]', 3047 'Else clause should never be on same line as else (use 2 lines) [whitespace/newline] [4]']) 3048 # FIXME: Make this fail. 3049 # self.assert_multi_line_lint( 3050 # 'if (condition) doSomething(); else {\n' 3051 # ' doSomethingElse();\n' 3052 # '}\n', 3053 # '') 3054 3055 # 3. An else if statement should be written as an if statement 3056 # when the prior if concludes with a return statement. 3057 self.assert_multi_line_lint( 3058 'if (motivated) {\n' 3059 ' if (liquid)\n' 3060 ' return money;\n' 3061 '} else if (tired)\n' 3062 ' break;\n', 3063 '') 3064 self.assert_multi_line_lint( 3065 'if (condition)\n' 3066 ' doSomething();\n' 3067 'else if (otherCondition)\n' 3068 ' doSomethingElse();\n', 3069 '') 3070 self.assert_multi_line_lint( 3071 'if (condition)\n' 3072 ' doSomething();\n' 3073 'else\n' 3074 ' doSomethingElse();\n', 3075 '') 3076 self.assert_multi_line_lint( 3077 'if (condition)\n' 3078 ' returnValue = foo;\n' 3079 'else if (otherCondition)\n' 3080 ' returnValue = bar;\n', 3081 '') 3082 self.assert_multi_line_lint( 3083 'if (condition)\n' 3084 ' returnValue = foo;\n' 3085 'else\n' 3086 ' returnValue = bar;\n', 3087 '') 3088 self.assert_multi_line_lint( 3089 'if (condition)\n' 3090 ' doSomething();\n' 3091 'else if (liquid)\n' 3092 ' return money;\n' 3093 'else if (broke)\n' 3094 ' return favor;\n' 3095 'else\n' 3096 ' sleep(28800);\n', 3097 '') 3098 self.assert_multi_line_lint( 3099 'if (liquid) {\n' 3100 ' prepare();\n' 3101 ' return money;\n' 3102 '} else if (greedy) {\n' 3103 ' keep();\n' 3104 ' return nothing;\n' 3105 '}\n', 3106 'An else if statement should be written as an if statement when the ' 3107 'prior "if" concludes with a return, break, continue or goto statement.' 3108 ' [readability/control_flow] [4]') 3109 self.assert_multi_line_lint( 3110 ' if (stupid) {\n' 3111 'infiniteLoop:\n' 3112 ' goto infiniteLoop;\n' 3113 ' } else if (evil)\n' 3114 ' goto hell;\n', 3115 'An else if statement should be written as an if statement when the ' 3116 'prior "if" concludes with a return, break, continue or goto statement.' 3117 ' [readability/control_flow] [4]') 3118 self.assert_multi_line_lint( 3119 'if (liquid)\n' 3120 '{\n' 3121 ' prepare();\n' 3122 ' return money;\n' 3123 '}\n' 3124 'else if (greedy)\n' 3125 ' keep();\n', 3126 ['This { should be at the end of the previous line [whitespace/braces] [4]', 3127 'An else should appear on the same line as the preceding } [whitespace/newline] [4]', 3128 'An else if statement should be written as an if statement when the ' 3129 'prior "if" concludes with a return, break, continue or goto statement.' 3130 ' [readability/control_flow] [4]']) 3131 self.assert_multi_line_lint( 3132 'if (gone)\n' 3133 ' return;\n' 3134 'else if (here)\n' 3135 ' go();\n', 3136 'An else if statement should be written as an if statement when the ' 3137 'prior "if" concludes with a return, break, continue or goto statement.' 3138 ' [readability/control_flow] [4]') 3139 self.assert_multi_line_lint( 3140 'if (gone)\n' 3141 ' return;\n' 3142 'else\n' 3143 ' go();\n', 3144 'An else statement can be removed when the prior "if" concludes ' 3145 'with a return, break, continue or goto statement.' 3146 ' [readability/control_flow] [4]') 3147 self.assert_multi_line_lint( 3148 'if (motivated) {\n' 3149 ' prepare();\n' 3150 ' continue;\n' 3151 '} else {\n' 3152 ' cleanUp();\n' 3153 ' break;\n' 3154 '}\n', 3155 'An else statement can be removed when the prior "if" concludes ' 3156 'with a return, break, continue or goto statement.' 3157 ' [readability/control_flow] [4]') 3158 self.assert_multi_line_lint( 3159 'if (tired)\n' 3160 ' break;\n' 3161 'else {\n' 3162 ' prepare();\n' 3163 ' continue;\n' 3164 '}\n', 3165 'An else statement can be removed when the prior "if" concludes ' 3166 'with a return, break, continue or goto statement.' 3167 ' [readability/control_flow] [4]') 3168 3169 def test_braces(self): 3170 # 1. Function definitions: place each brace on its own line. 3171 self.assert_multi_line_lint( 3172 'int main()\n' 3173 '{\n' 3174 ' doSomething();\n' 3175 '}\n', 3176 '') 3177 self.assert_multi_line_lint( 3178 'int main() {\n' 3179 ' doSomething();\n' 3180 '}\n', 3181 'Place brace on its own line for function definitions. [whitespace/braces] [4]') 3182 3183 # 2. Other braces: place the open brace on the line preceding the 3184 # code block; place the close brace on its own line. 3185 self.assert_multi_line_lint( 3186 'class MyClass {\n' 3187 ' int foo;\n' 3188 '};\n', 3189 '') 3190 self.assert_multi_line_lint( 3191 'namespace WebCore {\n' 3192 ' int foo;\n' 3193 '};\n', 3194 '') 3195 self.assert_multi_line_lint( 3196 'for (int i = 0; i < 10; i++) {\n' 3197 ' DoSomething();\n' 3198 '};\n', 3199 '') 3200 self.assert_multi_line_lint( 3201 'class MyClass\n' 3202 '{\n' 3203 ' int foo;\n' 3204 '};\n', 3205 'This { should be at the end of the previous line [whitespace/braces] [4]') 3206 self.assert_multi_line_lint( 3207 'if (condition)\n' 3208 '{\n' 3209 ' int foo;\n' 3210 '}\n', 3211 'This { should be at the end of the previous line [whitespace/braces] [4]') 3212 self.assert_multi_line_lint( 3213 'for (int i = 0; i < 10; i++)\n' 3214 '{\n' 3215 ' int foo;\n' 3216 '}\n', 3217 'This { should be at the end of the previous line [whitespace/braces] [4]') 3218 self.assert_multi_line_lint( 3219 'while (true)\n' 3220 '{\n' 3221 ' int foo;\n' 3222 '}\n', 3223 'This { should be at the end of the previous line [whitespace/braces] [4]') 3224 self.assert_multi_line_lint( 3225 'foreach (Foo* foo, foos)\n' 3226 '{\n' 3227 ' int bar;\n' 3228 '}\n', 3229 'This { should be at the end of the previous line [whitespace/braces] [4]') 3230 self.assert_multi_line_lint( 3231 'switch (type)\n' 3232 '{\n' 3233 'case foo: return;\n' 3234 '}\n', 3235 'This { should be at the end of the previous line [whitespace/braces] [4]') 3236 self.assert_multi_line_lint( 3237 'if (condition)\n' 3238 '{\n' 3239 ' int foo;\n' 3240 '}\n', 3241 'This { should be at the end of the previous line [whitespace/braces] [4]') 3242 self.assert_multi_line_lint( 3243 'for (int i = 0; i < 10; i++)\n' 3244 '{\n' 3245 ' int foo;\n' 3246 '}\n', 3247 'This { should be at the end of the previous line [whitespace/braces] [4]') 3248 self.assert_multi_line_lint( 3249 'while (true)\n' 3250 '{\n' 3251 ' int foo;\n' 3252 '}\n', 3253 'This { should be at the end of the previous line [whitespace/braces] [4]') 3254 self.assert_multi_line_lint( 3255 'switch (type)\n' 3256 '{\n' 3257 'case foo: return;\n' 3258 '}\n', 3259 'This { should be at the end of the previous line [whitespace/braces] [4]') 3260 self.assert_multi_line_lint( 3261 'else if (type)\n' 3262 '{\n' 3263 'case foo: return;\n' 3264 '}\n', 3265 'This { should be at the end of the previous line [whitespace/braces] [4]') 3266 3267 # 3. One-line control clauses should not use braces unless 3268 # comments are included or a single statement spans multiple 3269 # lines. 3270 self.assert_multi_line_lint( 3271 'if (true) {\n' 3272 ' int foo;\n' 3273 '}\n', 3274 'One line control clauses should not use braces. [whitespace/braces] [4]') 3275 3276 self.assert_multi_line_lint( 3277 'for (; foo; bar) {\n' 3278 ' int foo;\n' 3279 '}\n', 3280 'One line control clauses should not use braces. [whitespace/braces] [4]') 3281 3282 self.assert_multi_line_lint( 3283 'foreach (foo, foos) {\n' 3284 ' int bar;\n' 3285 '}\n', 3286 'One line control clauses should not use braces. [whitespace/braces] [4]') 3287 3288 self.assert_multi_line_lint( 3289 'while (true) {\n' 3290 ' int foo;\n' 3291 '}\n', 3292 'One line control clauses should not use braces. [whitespace/braces] [4]') 3293 3294 self.assert_multi_line_lint( 3295 'if (true)\n' 3296 ' int foo;\n' 3297 'else {\n' 3298 ' int foo;\n' 3299 '}\n', 3300 'One line control clauses should not use braces. [whitespace/braces] [4]') 3301 3302 self.assert_multi_line_lint( 3303 'if (true) {\n' 3304 ' int foo;\n' 3305 '} else\n' 3306 ' int foo;\n', 3307 'One line control clauses should not use braces. [whitespace/braces] [4]') 3308 3309 self.assert_multi_line_lint( 3310 'if (true) {\n' 3311 ' // Some comment\n' 3312 ' int foo;\n' 3313 '}\n', 3314 '') 3315 3316 self.assert_multi_line_lint( 3317 'if (true) {\n' 3318 ' myFunction(reallyLongParam1, reallyLongParam2,\n' 3319 ' reallyLongParam3);\n' 3320 '}\n', 3321 '') 3322 3323 # 4. Control clauses without a body should use empty braces. 3324 self.assert_multi_line_lint( 3325 'for ( ; current; current = current->next) { }\n', 3326 '') 3327 self.assert_multi_line_lint( 3328 'for ( ; current;\n' 3329 ' current = current->next) {}\n', 3330 '') 3331 self.assert_multi_line_lint( 3332 'for ( ; current; current = current->next);\n', 3333 'Semicolon defining empty statement for this loop. Use { } instead. [whitespace/semicolon] [5]') 3334 self.assert_multi_line_lint( 3335 'while (true);\n', 3336 'Semicolon defining empty statement for this loop. Use { } instead. [whitespace/semicolon] [5]') 3337 self.assert_multi_line_lint( 3338 '} while (true);\n', 3339 '') 3340 3341 def test_null_false_zero(self): 3342 # 1. In C++, the null pointer value should be written as 0. In C, 3343 # it should be written as NULL. In Objective-C and Objective-C++, 3344 # follow the guideline for C or C++, respectively, but use nil to 3345 # represent a null Objective-C object. 3346 self.assert_lint( 3347 'functionCall(NULL)', 3348 'Use 0 instead of NULL.' 3349 ' [readability/null] [5]', 3350 'foo.cpp') 3351 self.assert_lint( 3352 "// Don't use NULL in comments since it isn't in code.", 3353 'Use 0 instead of NULL.' 3354 ' [readability/null] [4]', 3355 'foo.cpp') 3356 self.assert_lint( 3357 '"A string with NULL" // and a comment with NULL is tricky to flag correctly in cpp_style.', 3358 'Use 0 instead of NULL.' 3359 ' [readability/null] [4]', 3360 'foo.cpp') 3361 self.assert_lint( 3362 '"A string containing NULL is ok"', 3363 '', 3364 'foo.cpp') 3365 self.assert_lint( 3366 'if (aboutNULL)', 3367 '', 3368 'foo.cpp') 3369 self.assert_lint( 3370 'myVariable = NULLify', 3371 '', 3372 'foo.cpp') 3373 # Make sure that the NULL check does not apply to C and Objective-C files. 3374 self.assert_lint( 3375 'functionCall(NULL)', 3376 '', 3377 'foo.c') 3378 self.assert_lint( 3379 'functionCall(NULL)', 3380 '', 3381 'foo.m') 3382 3383 # 2. C++ and C bool values should be written as true and 3384 # false. Objective-C BOOL values should be written as YES and NO. 3385 # FIXME: Implement this. 3386 3387 # 3. Tests for true/false, null/non-null, and zero/non-zero should 3388 # all be done without equality comparisons. 3389 self.assert_lint( 3390 'if (count == 0)', 3391 'Tests for true/false, null/non-null, and zero/non-zero should all be done without equality comparisons.' 3392 ' [readability/comparison_to_zero] [5]') 3393 self.assert_lint_one_of_many_errors_re( 3394 'if (string != NULL)', 3395 r'Tests for true/false, null/non-null, and zero/non-zero should all be done without equality comparisons\.') 3396 self.assert_lint( 3397 'if (condition == true)', 3398 'Tests for true/false, null/non-null, and zero/non-zero should all be done without equality comparisons.' 3399 ' [readability/comparison_to_zero] [5]') 3400 self.assert_lint( 3401 'if (myVariable != /* Why would anyone put a comment here? */ false)', 3402 'Tests for true/false, null/non-null, and zero/non-zero should all be done without equality comparisons.' 3403 ' [readability/comparison_to_zero] [5]') 3404 3405 self.assert_lint( 3406 'if (0 /* This comment also looks odd to me. */ != aLongerVariableName)', 3407 'Tests for true/false, null/non-null, and zero/non-zero should all be done without equality comparisons.' 3408 ' [readability/comparison_to_zero] [5]') 3409 self.assert_lint_one_of_many_errors_re( 3410 'if (NULL == thisMayBeNull)', 3411 r'Tests for true/false, null/non-null, and zero/non-zero should all be done without equality comparisons\.') 3412 self.assert_lint( 3413 'if (true != anotherCondition)', 3414 'Tests for true/false, null/non-null, and zero/non-zero should all be done without equality comparisons.' 3415 ' [readability/comparison_to_zero] [5]') 3416 self.assert_lint( 3417 'if (false == myBoolValue)', 3418 'Tests for true/false, null/non-null, and zero/non-zero should all be done without equality comparisons.' 3419 ' [readability/comparison_to_zero] [5]') 3420 3421 self.assert_lint( 3422 'if (fontType == trueType)', 3423 '') 3424 self.assert_lint( 3425 'if (othertrue == fontType)', 3426 '') 3427 3428 def test_names(self): 3429 # FIXME: Implement this. 3430 pass 3431 3432 def test_other(self): 3433 # FIXME: Implement this. 3434 pass 3435 3436 3437def tearDown(): 3438 """A global check to make sure all error-categories have been tested. 3439 3440 The main tearDown() routine is the only code we can guarantee will be 3441 run after all other tests have been executed. 3442 """ 3443 try: 3444 if _run_verifyallcategoriesseen: 3445 ErrorCollector(None).verify_all_categories_are_seen() 3446 except NameError: 3447 # If nobody set the global _run_verifyallcategoriesseen, then 3448 # we assume we shouldn't run the test 3449 pass 3450 3451if __name__ == '__main__': 3452 import sys 3453 # We don't want to run the verify_all_categories_are_seen() test unless 3454 # we're running the full test suite: if we only run one test, 3455 # obviously we're not going to see all the error categories. So we 3456 # only run verify_all_categories_are_seen() when no commandline flags 3457 # are passed in. 3458 global _run_verifyallcategoriesseen 3459 _run_verifyallcategoriesseen = (len(sys.argv) == 1) 3460 3461 unittest.main() 3462