1 # -*- coding: utf-8; -*- 2 # 3 # Copyright (C) 2011 Google Inc. All rights reserved. 4 # Copyright (C) 2009 Torch Mobile Inc. 5 # Copyright (C) 2009 Apple Inc. All rights reserved. 6 # Copyright (C) 2010 Chris Jerdonek (cjerdonek (at] webkit.org) 7 # 8 # Redistribution and use in source and binary forms, with or without 9 # modification, are permitted provided that the following conditions are 10 # met: 11 # 12 # * Redistributions of source code must retain the above copyright 13 # notice, this list of conditions and the following disclaimer. 14 # * Redistributions in binary form must reproduce the above 15 # copyright notice, this list of conditions and the following disclaimer 16 # in the documentation and/or other materials provided with the 17 # distribution. 18 # * Neither the name of Google Inc. nor the names of its 19 # contributors may be used to endorse or promote products derived from 20 # this software without specific prior written permission. 21 # 22 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 23 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 24 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 25 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 26 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 27 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 28 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 29 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 30 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 32 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 34 """Unit test for cpp_style.py.""" 35 36 # FIXME: Add a good test that tests UpdateIncludeState. 37 38 import os 39 import random 40 import re 41 import unittest 42 43 import cpp as cpp_style 44 from cpp import CppChecker 45 from ..filter import FilterConfiguration 46 from webkitpy.common.system.filesystem import FileSystem 47 48 # This class works as an error collector and replaces cpp_style.Error 49 # function for the unit tests. We also verify each category we see 50 # is in STYLE_CATEGORIES, to help keep that list up to date. 51 class ErrorCollector: 52 _all_style_categories = CppChecker.categories 53 # This is a list including all categories seen in any unit test. 54 _seen_style_categories = {} 55 56 def __init__(self, assert_fn, filter=None, lines_to_check=None): 57 """assert_fn: a function to call when we notice a problem. 58 filter: filters the errors that we are concerned about.""" 59 self._assert_fn = assert_fn 60 self._errors = [] 61 self._lines_to_check = lines_to_check 62 if not filter: 63 filter = FilterConfiguration() 64 self._filter = filter 65 66 def __call__(self, line_number, category, confidence, message): 67 self._assert_fn(category in self._all_style_categories, 68 'Message "%s" has category "%s",' 69 ' which is not in STYLE_CATEGORIES' % (message, category)) 70 71 if self._lines_to_check and not line_number in self._lines_to_check: 72 return False 73 74 if self._filter.should_check(category, ""): 75 self._seen_style_categories[category] = 1 76 self._errors.append('%s [%s] [%d]' % (message, category, confidence)) 77 return True 78 79 def results(self): 80 if len(self._errors) < 2: 81 return ''.join(self._errors) # Most tests expect to have a string. 82 else: 83 return self._errors # Let's give a list if there is more than one. 84 85 def result_list(self): 86 return self._errors 87 88 def verify_all_categories_are_seen(self): 89 """Fails if there's a category in _all_style_categories - _seen_style_categories. 90 91 This should only be called after all tests are run, so 92 _seen_style_categories has had a chance to fully populate. Since 93 this isn't called from within the normal unittest framework, we 94 can't use the normal unittest assert macros. Instead we just exit 95 when we see an error. Good thing this test is always run last! 96 """ 97 for category in self._all_style_categories: 98 if category not in self._seen_style_categories: 99 import sys 100 sys.exit('FATAL ERROR: There are no tests for category "%s"' % category) 101 102 103 class CppFunctionsTest(unittest.TestCase): 104 105 """Supports testing functions that do not need CppStyleTestBase.""" 106 107 def test_convert_to_lower_with_underscores(self): 108 self.assertEqual(cpp_style._convert_to_lower_with_underscores('ABC'), 'abc') 109 self.assertEqual(cpp_style._convert_to_lower_with_underscores('aB'), 'a_b') 110 self.assertEqual(cpp_style._convert_to_lower_with_underscores('isAName'), 'is_a_name') 111 self.assertEqual(cpp_style._convert_to_lower_with_underscores('AnotherTest'), 'another_test') 112 self.assertEqual(cpp_style._convert_to_lower_with_underscores('PassRefPtr<MyClass>'), 'pass_ref_ptr<my_class>') 113 self.assertEqual(cpp_style._convert_to_lower_with_underscores('_ABC'), '_abc') 114 115 def test_create_acronym(self): 116 self.assertEqual(cpp_style._create_acronym('ABC'), 'ABC') 117 self.assertEqual(cpp_style._create_acronym('IsAName'), 'IAN') 118 self.assertEqual(cpp_style._create_acronym('PassRefPtr<MyClass>'), 'PRP<MC>') 119 120 def test_is_c_or_objective_c(self): 121 clean_lines = cpp_style.CleansedLines(['']) 122 clean_objc_lines = cpp_style.CleansedLines(['#import "header.h"']) 123 self.assertTrue(cpp_style._FileState(clean_lines, 'c').is_c_or_objective_c()) 124 self.assertTrue(cpp_style._FileState(clean_lines, 'm').is_c_or_objective_c()) 125 self.assertFalse(cpp_style._FileState(clean_lines, 'cpp').is_c_or_objective_c()) 126 self.assertFalse(cpp_style._FileState(clean_lines, 'cc').is_c_or_objective_c()) 127 self.assertFalse(cpp_style._FileState(clean_lines, 'h').is_c_or_objective_c()) 128 self.assertTrue(cpp_style._FileState(clean_objc_lines, 'h').is_c_or_objective_c()) 129 130 def test_parameter(self): 131 # Test type. 132 parameter = cpp_style.Parameter('ExceptionCode', 13, 1) 133 self.assertEqual(parameter.type, 'ExceptionCode') 134 self.assertEqual(parameter.name, '') 135 self.assertEqual(parameter.row, 1) 136 137 # Test type and name. 138 parameter = cpp_style.Parameter('PassRefPtr<MyClass> parent', 19, 1) 139 self.assertEqual(parameter.type, 'PassRefPtr<MyClass>') 140 self.assertEqual(parameter.name, 'parent') 141 self.assertEqual(parameter.row, 1) 142 143 # Test type, no name, with default value. 144 parameter = cpp_style.Parameter('MyClass = 0', 7, 0) 145 self.assertEqual(parameter.type, 'MyClass') 146 self.assertEqual(parameter.name, '') 147 self.assertEqual(parameter.row, 0) 148 149 # Test type, name, and default value. 150 parameter = cpp_style.Parameter('MyClass a = 0', 7, 0) 151 self.assertEqual(parameter.type, 'MyClass') 152 self.assertEqual(parameter.name, 'a') 153 self.assertEqual(parameter.row, 0) 154 155 def test_single_line_view(self): 156 start_position = cpp_style.Position(row=1, column=1) 157 end_position = cpp_style.Position(row=3, column=1) 158 single_line_view = cpp_style.SingleLineView(['0', 'abcde', 'fgh', 'i'], start_position, end_position) 159 self.assertEqual(single_line_view.single_line, 'bcde fgh i') 160 self.assertEqual(single_line_view.convert_column_to_row(0), 1) 161 self.assertEqual(single_line_view.convert_column_to_row(4), 1) 162 self.assertEqual(single_line_view.convert_column_to_row(5), 2) 163 self.assertEqual(single_line_view.convert_column_to_row(8), 2) 164 self.assertEqual(single_line_view.convert_column_to_row(9), 3) 165 self.assertEqual(single_line_view.convert_column_to_row(100), 3) 166 167 start_position = cpp_style.Position(row=0, column=3) 168 end_position = cpp_style.Position(row=0, column=4) 169 single_line_view = cpp_style.SingleLineView(['abcdef'], start_position, end_position) 170 self.assertEqual(single_line_view.single_line, 'd') 171 172 def test_create_skeleton_parameters(self): 173 self.assertEqual(cpp_style.create_skeleton_parameters(''), '') 174 self.assertEqual(cpp_style.create_skeleton_parameters(' '), ' ') 175 self.assertEqual(cpp_style.create_skeleton_parameters('long'), 'long,') 176 self.assertEqual(cpp_style.create_skeleton_parameters('const unsigned long int'), ' int,') 177 self.assertEqual(cpp_style.create_skeleton_parameters('long int*'), ' int ,') 178 self.assertEqual(cpp_style.create_skeleton_parameters('PassRefPtr<Foo> a'), 'PassRefPtr a,') 179 self.assertEqual(cpp_style.create_skeleton_parameters( 180 'ComplexTemplate<NestedTemplate1<MyClass1, MyClass2>, NestedTemplate1<MyClass1, MyClass2> > param, int second'), 181 'ComplexTemplate param, int second,') 182 self.assertEqual(cpp_style.create_skeleton_parameters('int = 0, Namespace::Type& a'), 'int , Type a,') 183 # Create skeleton parameters is a bit too aggressive with function variables, but 184 # it allows for parsing other parameters and declarations like this are rare. 185 self.assertEqual(cpp_style.create_skeleton_parameters('void (*fn)(int a, int b), Namespace::Type& a'), 186 'void , Type a,') 187 188 # This doesn't look like functions declarations but the simplifications help to eliminate false positives. 189 self.assertEqual(cpp_style.create_skeleton_parameters('b{d}'), 'b ,') 190 191 def test_find_parameter_name_index(self): 192 self.assertEqual(cpp_style.find_parameter_name_index(' int a '), 5) 193 self.assertEqual(cpp_style.find_parameter_name_index(' PassRefPtr '), 16) 194 self.assertEqual(cpp_style.find_parameter_name_index('double'), 6) 195 196 def test_parameter_list(self): 197 elided_lines = ['int blah(PassRefPtr<MyClass> paramName,', 198 'const Other1Class& foo,', 199 'const ComplexTemplate<Class1, NestedTemplate<P1, P2> >* const * param = new ComplexTemplate<Class1, NestedTemplate<P1, P2> >(34, 42),', 200 'int* myCount = 0);'] 201 start_position = cpp_style.Position(row=0, column=8) 202 end_position = cpp_style.Position(row=3, column=16) 203 204 expected_parameters = ({'type': 'PassRefPtr<MyClass>', 'name': 'paramName', 'row': 0}, 205 {'type': 'const Other1Class&', 'name': 'foo', 'row': 1}, 206 {'type': 'const ComplexTemplate<Class1, NestedTemplate<P1, P2> >* const *', 'name': 'param', 'row': 2}, 207 {'type': 'int*', 'name': 'myCount', 'row': 3}) 208 index = 0 209 for parameter in cpp_style.parameter_list(elided_lines, start_position, end_position): 210 expected_parameter = expected_parameters[index] 211 self.assertEqual(parameter.type, expected_parameter['type']) 212 self.assertEqual(parameter.name, expected_parameter['name']) 213 self.assertEqual(parameter.row, expected_parameter['row']) 214 index += 1 215 self.assertEqual(index, len(expected_parameters)) 216 217 def test_check_parameter_against_text(self): 218 error_collector = ErrorCollector(self.assertTrue) 219 parameter = cpp_style.Parameter('FooF ooF', 4, 1) 220 self.assertFalse(cpp_style._check_parameter_name_against_text(parameter, 'FooF', error_collector)) 221 self.assertEqual(error_collector.results(), 222 'The parameter name "ooF" adds no information, so it should be removed. [readability/parameter_name] [5]') 223 224 class CppStyleTestBase(unittest.TestCase): 225 """Provides some useful helper functions for cpp_style tests. 226 227 Attributes: 228 min_confidence: An integer that is the current minimum confidence 229 level for the tests. 230 231 """ 232 233 # FIXME: Refactor the unit tests so the confidence level is passed 234 # explicitly, just like it is in the real code. 235 min_confidence = 1; 236 237 # Helper function to avoid needing to explicitly pass confidence 238 # in all the unit test calls to cpp_style.process_file_data(). 239 def process_file_data(self, filename, file_extension, lines, error, fs=None): 240 """Call cpp_style.process_file_data() with the min_confidence.""" 241 return cpp_style.process_file_data(filename, file_extension, lines, 242 error, self.min_confidence, fs) 243 244 def perform_lint(self, code, filename, basic_error_rules, fs=None, lines_to_check=None): 245 error_collector = ErrorCollector(self.assertTrue, FilterConfiguration(basic_error_rules), lines_to_check) 246 lines = code.split('\n') 247 extension = filename.split('.')[1] 248 self.process_file_data(filename, extension, lines, error_collector, fs) 249 return error_collector.results() 250 251 # Perform lint on single line of input and return the error message. 252 def perform_single_line_lint(self, code, filename): 253 basic_error_rules = ('-build/header_guard', 254 '-legal/copyright', 255 '-readability/fn_size', 256 '-readability/parameter_name', 257 '-readability/pass_ptr', 258 '-whitespace/ending_newline') 259 return self.perform_lint(code, filename, basic_error_rules) 260 261 # Perform lint over multiple lines and return the error message. 262 def perform_multi_line_lint(self, code, file_extension): 263 basic_error_rules = ('-build/header_guard', 264 '-legal/copyright', 265 '-readability/parameter_name', 266 '-whitespace/ending_newline') 267 return self.perform_lint(code, 'test.' + file_extension, basic_error_rules) 268 269 # Only keep some errors related to includes, namespaces and rtti. 270 def perform_language_rules_check(self, filename, code, lines_to_check=None): 271 basic_error_rules = ('-', 272 '+build/include', 273 '+build/include_order', 274 '+build/namespaces', 275 '+runtime/rtti') 276 return self.perform_lint(code, filename, basic_error_rules, lines_to_check=lines_to_check) 277 278 # Only keep function length errors. 279 def perform_function_lengths_check(self, code): 280 basic_error_rules = ('-', 281 '+readability/fn_size') 282 return self.perform_lint(code, 'test.cpp', basic_error_rules) 283 284 # Only keep pass ptr errors. 285 def perform_pass_ptr_check(self, code): 286 basic_error_rules = ('-', 287 '+readability/pass_ptr') 288 return self.perform_lint(code, 'test.cpp', basic_error_rules) 289 290 # Only keep leaky pattern errors. 291 def perform_leaky_pattern_check(self, code): 292 basic_error_rules = ('-', 293 '+runtime/leaky_pattern') 294 return self.perform_lint(code, 'test.cpp', basic_error_rules) 295 296 # Only include what you use errors. 297 def perform_include_what_you_use(self, code, filename='foo.h', fs=None): 298 basic_error_rules = ('-', 299 '+build/include_what_you_use') 300 return self.perform_lint(code, filename, basic_error_rules, fs) 301 302 def perform_avoid_static_cast_of_objects(self, code, filename='foo.cpp', fs=None): 303 basic_error_rules = ('-', 304 '+runtime/casting') 305 return self.perform_lint(code, filename, basic_error_rules, fs) 306 307 # Perform lint and compare the error message with "expected_message". 308 def assert_lint(self, code, expected_message, file_name='foo.cpp'): 309 self.assertEqual(expected_message, self.perform_single_line_lint(code, file_name)) 310 311 def assert_lint_one_of_many_errors_re(self, code, expected_message_re, file_name='foo.cpp'): 312 messages = self.perform_single_line_lint(code, file_name) 313 for message in messages: 314 if re.search(expected_message_re, message): 315 return 316 317 self.assertEqual(expected_message_re, messages) 318 319 def assert_multi_line_lint(self, code, expected_message, file_name='foo.h'): 320 file_extension = file_name[file_name.rfind('.') + 1:] 321 self.assertEqual(expected_message, self.perform_multi_line_lint(code, file_extension)) 322 323 def assert_multi_line_lint_re(self, code, expected_message_re, file_name='foo.h'): 324 file_extension = file_name[file_name.rfind('.') + 1:] 325 message = self.perform_multi_line_lint(code, file_extension) 326 if not re.search(expected_message_re, message): 327 self.fail('Message was:\n' + message + 'Expected match to "' + expected_message_re + '"') 328 329 def assert_language_rules_check(self, file_name, code, expected_message, lines_to_check=None): 330 self.assertEqual(expected_message, 331 self.perform_language_rules_check(file_name, code, lines_to_check)) 332 333 def assert_include_what_you_use(self, code, expected_message): 334 self.assertEqual(expected_message, 335 self.perform_include_what_you_use(code)) 336 337 def assert_blank_lines_check(self, lines, start_errors, end_errors): 338 error_collector = ErrorCollector(self.assertTrue) 339 self.process_file_data('foo.cpp', 'cpp', lines, error_collector) 340 self.assertEqual( 341 start_errors, 342 error_collector.results().count( 343 'Blank line at the start of a code block. Is this needed?' 344 ' [whitespace/blank_line] [2]')) 345 self.assertEqual( 346 end_errors, 347 error_collector.results().count( 348 'Blank line at the end of a code block. Is this needed?' 349 ' [whitespace/blank_line] [3]')) 350 351 def assert_positions_equal(self, position, tuple_position): 352 """Checks if the two positions are equal. 353 354 position: a cpp_style.Position object. 355 tuple_position: a tuple (row, column) to compare against.""" 356 self.assertEqual(position, cpp_style.Position(tuple_position[0], tuple_position[1]), 357 'position %s, tuple_position %s' % (position, tuple_position)) 358 359 360 class FunctionDetectionTest(CppStyleTestBase): 361 def perform_function_detection(self, lines, function_information, detection_line=0): 362 clean_lines = cpp_style.CleansedLines(lines) 363 function_state = cpp_style._FunctionState(5) 364 error_collector = ErrorCollector(self.assertTrue) 365 cpp_style.detect_functions(clean_lines, detection_line, function_state, error_collector) 366 if not function_information: 367 self.assertEqual(function_state.in_a_function, False) 368 return 369 self.assertEqual(function_state.in_a_function, True) 370 self.assertEqual(function_state.current_function, function_information['name'] + '()') 371 self.assertEqual(function_state.modifiers_and_return_type(), function_information['modifiers_and_return_type']) 372 self.assertEqual(function_state.is_pure, function_information['is_pure']) 373 self.assertEqual(function_state.is_declaration, function_information['is_declaration']) 374 self.assert_positions_equal(function_state.function_name_start_position, function_information['function_name_start_position']) 375 self.assert_positions_equal(function_state.parameter_start_position, function_information['parameter_start_position']) 376 self.assert_positions_equal(function_state.parameter_end_position, function_information['parameter_end_position']) 377 self.assert_positions_equal(function_state.body_start_position, function_information['body_start_position']) 378 self.assert_positions_equal(function_state.end_position, function_information['end_position']) 379 expected_parameters = function_information.get('parameter_list') 380 if expected_parameters: 381 actual_parameters = function_state.parameter_list() 382 self.assertEqual(len(actual_parameters), len(expected_parameters)) 383 for index in range(len(expected_parameters)): 384 actual_parameter = actual_parameters[index] 385 expected_parameter = expected_parameters[index] 386 self.assertEqual(actual_parameter.type, expected_parameter['type']) 387 self.assertEqual(actual_parameter.name, expected_parameter['name']) 388 self.assertEqual(actual_parameter.row, expected_parameter['row']) 389 390 def test_basic_function_detection(self): 391 self.perform_function_detection( 392 ['void theTestFunctionName(int) {', 393 '}'], 394 {'name': 'theTestFunctionName', 395 'modifiers_and_return_type': 'void', 396 'function_name_start_position': (0, 5), 397 'parameter_start_position': (0, 24), 398 'parameter_end_position': (0, 29), 399 'body_start_position': (0, 30), 400 'end_position': (1, 1), 401 'is_pure': False, 402 'is_declaration': False}) 403 404 def test_function_declaration_detection(self): 405 self.perform_function_detection( 406 ['void aFunctionName(int);'], 407 {'name': 'aFunctionName', 408 'modifiers_and_return_type': 'void', 409 'function_name_start_position': (0, 5), 410 'parameter_start_position': (0, 18), 411 'parameter_end_position': (0, 23), 412 'body_start_position': (0, 23), 413 'end_position': (0, 24), 414 'is_pure': False, 415 'is_declaration': True}) 416 417 self.perform_function_detection( 418 ['CheckedInt<T> operator /(const CheckedInt<T> &lhs, const CheckedInt<T> &rhs);'], 419 {'name': 'operator /', 420 'modifiers_and_return_type': 'CheckedInt<T>', 421 'function_name_start_position': (0, 14), 422 'parameter_start_position': (0, 24), 423 'parameter_end_position': (0, 76), 424 'body_start_position': (0, 76), 425 'end_position': (0, 77), 426 'is_pure': False, 427 'is_declaration': True}) 428 429 self.perform_function_detection( 430 ['CheckedInt<T> operator -(const CheckedInt<T> &lhs, const CheckedInt<T> &rhs);'], 431 {'name': 'operator -', 432 'modifiers_and_return_type': 'CheckedInt<T>', 433 'function_name_start_position': (0, 14), 434 'parameter_start_position': (0, 24), 435 'parameter_end_position': (0, 76), 436 'body_start_position': (0, 76), 437 'end_position': (0, 77), 438 'is_pure': False, 439 'is_declaration': True}) 440 441 self.perform_function_detection( 442 ['CheckedInt<T> operator !=(const CheckedInt<T> &lhs, const CheckedInt<T> &rhs);'], 443 {'name': 'operator !=', 444 'modifiers_and_return_type': 'CheckedInt<T>', 445 'function_name_start_position': (0, 14), 446 'parameter_start_position': (0, 25), 447 'parameter_end_position': (0, 77), 448 'body_start_position': (0, 77), 449 'end_position': (0, 78), 450 'is_pure': False, 451 'is_declaration': True}) 452 453 self.perform_function_detection( 454 ['CheckedInt<T> operator +(const CheckedInt<T> &lhs, const CheckedInt<T> &rhs);'], 455 {'name': 'operator +', 456 'modifiers_and_return_type': 'CheckedInt<T>', 457 'function_name_start_position': (0, 14), 458 'parameter_start_position': (0, 24), 459 'parameter_end_position': (0, 76), 460 'body_start_position': (0, 76), 461 'end_position': (0, 77), 462 'is_pure': False, 463 'is_declaration': True}) 464 465 def test_pure_function_detection(self): 466 self.perform_function_detection( 467 ['virtual void theTestFunctionName(int = 0);'], 468 {'name': 'theTestFunctionName', 469 'modifiers_and_return_type': 'virtual void', 470 'function_name_start_position': (0, 13), 471 'parameter_start_position': (0, 32), 472 'parameter_end_position': (0, 41), 473 'body_start_position': (0, 41), 474 'end_position': (0, 42), 475 'is_pure': False, 476 'is_declaration': True}) 477 478 self.perform_function_detection( 479 ['virtual void theTestFunctionName(int) = 0;'], 480 {'name': 'theTestFunctionName', 481 'modifiers_and_return_type': 'virtual void', 482 'function_name_start_position': (0, 13), 483 'parameter_start_position': (0, 32), 484 'parameter_end_position': (0, 37), 485 'body_start_position': (0, 41), 486 'end_position': (0, 42), 487 'is_pure': True, 488 'is_declaration': True}) 489 490 # Hopefully, no one writes code like this but it is a tricky case. 491 self.perform_function_detection( 492 ['virtual void theTestFunctionName(int)', 493 ' = ', 494 ' 0 ;'], 495 {'name': 'theTestFunctionName', 496 'modifiers_and_return_type': 'virtual void', 497 'function_name_start_position': (0, 13), 498 'parameter_start_position': (0, 32), 499 'parameter_end_position': (0, 37), 500 'body_start_position': (2, 3), 501 'end_position': (2, 4), 502 'is_pure': True, 503 'is_declaration': True}) 504 505 def test_ignore_macros(self): 506 self.perform_function_detection(['void aFunctionName(int); \\'], None) 507 508 def test_non_functions(self): 509 # This case exposed an error because the open brace was in quotes. 510 self.perform_function_detection( 511 ['asm(', 512 ' "stmdb sp!, {r1-r3}" "\n"', 513 ');'], 514 # This isn't a function but it looks like one to our simple 515 # algorithm and that is ok. 516 {'name': 'asm', 517 'modifiers_and_return_type': '', 518 'function_name_start_position': (0, 0), 519 'parameter_start_position': (0, 3), 520 'parameter_end_position': (2, 1), 521 'body_start_position': (2, 1), 522 'end_position': (2, 2), 523 'is_pure': False, 524 'is_declaration': True}) 525 526 # Simple test case with something that is not a function. 527 self.perform_function_detection(['class Stuff;'], None) 528 529 def test_parameter_list(self): 530 # A function with no arguments. 531 function_state = self.perform_function_detection( 532 ['void functionName();'], 533 {'name': 'functionName', 534 'modifiers_and_return_type': 'void', 535 'function_name_start_position': (0, 5), 536 'parameter_start_position': (0, 17), 537 'parameter_end_position': (0, 19), 538 'body_start_position': (0, 19), 539 'end_position': (0, 20), 540 'is_pure': False, 541 'is_declaration': True, 542 'parameter_list': ()}) 543 544 # A function with one argument. 545 function_state = self.perform_function_detection( 546 ['void functionName(int);'], 547 {'name': 'functionName', 548 'modifiers_and_return_type': 'void', 549 'function_name_start_position': (0, 5), 550 'parameter_start_position': (0, 17), 551 'parameter_end_position': (0, 22), 552 'body_start_position': (0, 22), 553 'end_position': (0, 23), 554 'is_pure': False, 555 'is_declaration': True, 556 'parameter_list': 557 ({'type': 'int', 'name': '', 'row': 0},)}) 558 559 # A function with unsigned and short arguments 560 function_state = self.perform_function_detection( 561 ['void functionName(unsigned a, short b, long c, long long short unsigned int);'], 562 {'name': 'functionName', 563 'modifiers_and_return_type': 'void', 564 'function_name_start_position': (0, 5), 565 'parameter_start_position': (0, 17), 566 'parameter_end_position': (0, 76), 567 'body_start_position': (0, 76), 568 'end_position': (0, 77), 569 'is_pure': False, 570 'is_declaration': True, 571 'parameter_list': 572 ({'type': 'unsigned', 'name': 'a', 'row': 0}, 573 {'type': 'short', 'name': 'b', 'row': 0}, 574 {'type': 'long', 'name': 'c', 'row': 0}, 575 {'type': 'long long short unsigned int', 'name': '', 'row': 0})}) 576 577 # Some parameter type with modifiers and no parameter names. 578 function_state = self.perform_function_detection( 579 ['virtual void determineARIADropEffects(Vector<String>*&, const unsigned long int*&, const MediaPlayer::Preload, Other<Other2, Other3<P1, P2> >, int);'], 580 {'name': 'determineARIADropEffects', 581 'modifiers_and_return_type': 'virtual void', 582 'parameter_start_position': (0, 37), 583 'function_name_start_position': (0, 13), 584 'parameter_end_position': (0, 147), 585 'body_start_position': (0, 147), 586 'end_position': (0, 148), 587 'is_pure': False, 588 'is_declaration': True, 589 'parameter_list': 590 ({'type': 'Vector<String>*&', 'name': '', 'row': 0}, 591 {'type': 'const unsigned long int*&', 'name': '', 'row': 0}, 592 {'type': 'const MediaPlayer::Preload', 'name': '', 'row': 0}, 593 {'type': 'Other<Other2, Other3<P1, P2> >', 'name': '', 'row': 0}, 594 {'type': 'int', 'name': '', 'row': 0})}) 595 596 # Try parsing a function with a very complex definition. 597 function_state = self.perform_function_detection( 598 ['#define MyMacro(a) a', 599 'virtual', 600 'AnotherTemplate<Class1, Class2> aFunctionName(PassRefPtr<MyClass> paramName,', 601 'const Other1Class& foo,', 602 'const ComplexTemplate<Class1, NestedTemplate<P1, P2> >* const * param = new ComplexTemplate<Class1, NestedTemplate<P1, P2> >(34, 42),', 603 'int* myCount = 0);'], 604 {'name': 'aFunctionName', 605 'modifiers_and_return_type': 'virtual AnotherTemplate<Class1, Class2>', 606 'function_name_start_position': (2, 32), 607 'parameter_start_position': (2, 45), 608 'parameter_end_position': (5, 17), 609 'body_start_position': (5, 17), 610 'end_position': (5, 18), 611 'is_pure': False, 612 'is_declaration': True, 613 'parameter_list': 614 ({'type': 'PassRefPtr<MyClass>', 'name': 'paramName', 'row': 2}, 615 {'type': 'const Other1Class&', 'name': 'foo', 'row': 3}, 616 {'type': 'const ComplexTemplate<Class1, NestedTemplate<P1, P2> >* const *', 'name': 'param', 'row': 4}, 617 {'type': 'int*', 'name': 'myCount', 'row': 5})}, 618 detection_line=2) 619 620 621 class CppStyleTest(CppStyleTestBase): 622 623 def test_asm_lines_ignored(self): 624 self.assert_lint( 625 '__asm mov [registration], eax', 626 '') 627 628 # Test get line width. 629 def test_get_line_width(self): 630 self.assertEqual(0, cpp_style.get_line_width('')) 631 self.assertEqual(10, cpp_style.get_line_width(u'x' * 10)) 632 self.assertEqual(16, cpp_style.get_line_width(u'||||')) 633 634 def test_find_next_multi_line_comment_start(self): 635 self.assertEqual(1, cpp_style.find_next_multi_line_comment_start([''], 0)) 636 637 lines = ['a', 'b', '/* c'] 638 self.assertEqual(2, cpp_style.find_next_multi_line_comment_start(lines, 0)) 639 640 lines = ['char a[] = "/*";'] # not recognized as comment. 641 self.assertEqual(1, cpp_style.find_next_multi_line_comment_start(lines, 0)) 642 643 def test_find_next_multi_line_comment_end(self): 644 self.assertEqual(1, cpp_style.find_next_multi_line_comment_end([''], 0)) 645 lines = ['a', 'b', ' c */'] 646 self.assertEqual(2, cpp_style.find_next_multi_line_comment_end(lines, 0)) 647 648 def test_remove_multi_line_comments_from_range(self): 649 lines = ['a', ' /* comment ', ' * still comment', ' comment */ ', 'b'] 650 cpp_style.remove_multi_line_comments_from_range(lines, 1, 4) 651 self.assertEqual(['a', '// dummy', '// dummy', '// dummy', 'b'], lines) 652 653 def test_position(self): 654 position = cpp_style.Position(3, 4) 655 self.assert_positions_equal(position, (3, 4)) 656 self.assertEqual(position.row, 3) 657 self.assertTrue(position > cpp_style.Position(position.row - 1, position.column + 1)) 658 self.assertTrue(position > cpp_style.Position(position.row, position.column - 1)) 659 self.assertTrue(position < cpp_style.Position(position.row, position.column + 1)) 660 self.assertTrue(position < cpp_style.Position(position.row + 1, position.column - 1)) 661 self.assertEqual(position.__str__(), '(3, 4)') 662 663 def test_rfind_in_lines(self): 664 not_found_position = cpp_style.Position(10, 11) 665 start_position = cpp_style.Position(2, 2) 666 lines = ['ab', 'ace', 'test'] 667 self.assertEqual(not_found_position, cpp_style._rfind_in_lines('st', lines, start_position, not_found_position)) 668 self.assertTrue(cpp_style.Position(1, 1) == cpp_style._rfind_in_lines('a', lines, start_position, not_found_position)) 669 self.assertEqual(cpp_style.Position(2, 2), cpp_style._rfind_in_lines('(te|a)', lines, start_position, not_found_position)) 670 671 def test_close_expression(self): 672 self.assertEqual(cpp_style.Position(1, -1), cpp_style.close_expression([')('], cpp_style.Position(0, 1))) 673 self.assertEqual(cpp_style.Position(1, -1), cpp_style.close_expression([') ()'], cpp_style.Position(0, 1))) 674 self.assertEqual(cpp_style.Position(0, 4), cpp_style.close_expression([')[)]'], cpp_style.Position(0, 1))) 675 self.assertEqual(cpp_style.Position(0, 5), cpp_style.close_expression(['}{}{}'], cpp_style.Position(0, 3))) 676 self.assertEqual(cpp_style.Position(1, 1), cpp_style.close_expression(['}{}{', '}'], cpp_style.Position(0, 3))) 677 self.assertEqual(cpp_style.Position(2, -1), cpp_style.close_expression(['][][', ' '], cpp_style.Position(0, 3))) 678 679 def test_spaces_at_end_of_line(self): 680 self.assert_lint( 681 '// Hello there ', 682 'Line ends in whitespace. Consider deleting these extra spaces.' 683 ' [whitespace/end_of_line] [4]') 684 685 # Test C-style cast cases. 686 def test_cstyle_cast(self): 687 self.assert_lint( 688 'int a = (int)1.0;', 689 'Using C-style cast. Use static_cast<int>(...) instead' 690 ' [readability/casting] [4]') 691 self.assert_lint( 692 'int *a = (int *)DEFINED_VALUE;', 693 'Using C-style cast. Use reinterpret_cast<int *>(...) instead' 694 ' [readability/casting] [4]', 'foo.c') 695 self.assert_lint( 696 'uint16 a = (uint16)1.0;', 697 'Using C-style cast. Use static_cast<uint16>(...) instead' 698 ' [readability/casting] [4]') 699 self.assert_lint( 700 'int32 a = (int32)1.0;', 701 'Using C-style cast. Use static_cast<int32>(...) instead' 702 ' [readability/casting] [4]') 703 self.assert_lint( 704 'uint64 a = (uint64)1.0;', 705 'Using C-style cast. Use static_cast<uint64>(...) instead' 706 ' [readability/casting] [4]') 707 708 # Test taking address of casts (runtime/casting) 709 def test_runtime_casting(self): 710 self.assert_lint( 711 'int* x = &static_cast<int*>(foo);', 712 'Are you taking an address of a cast? ' 713 'This is dangerous: could be a temp var. ' 714 'Take the address before doing the cast, rather than after' 715 ' [runtime/casting] [4]') 716 717 self.assert_lint( 718 'int* x = &dynamic_cast<int *>(foo);', 719 ['Are you taking an address of a cast? ' 720 'This is dangerous: could be a temp var. ' 721 'Take the address before doing the cast, rather than after' 722 ' [runtime/casting] [4]', 723 'Do not use dynamic_cast<>. If you need to cast within a class ' 724 'hierarchy, use static_cast<> to upcast. Google doesn\'t support ' 725 'RTTI. [runtime/rtti] [5]']) 726 727 self.assert_lint( 728 'int* x = &reinterpret_cast<int *>(foo);', 729 'Are you taking an address of a cast? ' 730 'This is dangerous: could be a temp var. ' 731 'Take the address before doing the cast, rather than after' 732 ' [runtime/casting] [4]') 733 734 # It's OK to cast an address. 735 self.assert_lint( 736 'int* x = reinterpret_cast<int *>(&foo);', 737 '') 738 739 def test_runtime_selfinit(self): 740 self.assert_lint( 741 'Foo::Foo(Bar r, Bel l) : r_(r_), l_(l_) { }', 742 'You seem to be initializing a member variable with itself.' 743 ' [runtime/init] [4]') 744 self.assert_lint( 745 'Foo::Foo(Bar r, Bel l) : r_(r), l_(l) { }', 746 '') 747 self.assert_lint( 748 'Foo::Foo(Bar r) : r_(r), l_(r_), ll_(l_) { }', 749 '') 750 751 def test_runtime_rtti(self): 752 statement = 'int* x = dynamic_cast<int*>(&foo);' 753 error_message = ( 754 'Do not use dynamic_cast<>. If you need to cast within a class ' 755 'hierarchy, use static_cast<> to upcast. Google doesn\'t support ' 756 'RTTI. [runtime/rtti] [5]') 757 # dynamic_cast is disallowed in most files. 758 self.assert_language_rules_check('foo.cpp', statement, error_message) 759 self.assert_language_rules_check('foo.h', statement, error_message) 760 761 # Tests for static_cast readability. 762 def test_static_cast_on_objects_with_toFoo(self): 763 mock_header_contents = ['inline Foo* toFoo(Bar* bar)'] 764 fs = FileSystem() 765 orig_read_text_file_fn = fs.read_text_file 766 767 def mock_read_text_file_fn(path): 768 return mock_header_contents 769 770 try: 771 fs.read_text_file = mock_read_text_file_fn 772 message = self.perform_avoid_static_cast_of_objects( 773 'Foo* x = static_cast<Foo*>(bar);', 774 filename='casting.cpp', 775 fs=fs) 776 self.assertEqual(message, 'static_cast of class objects is not allowed. Use toFoo defined in Foo.h.' 777 ' [runtime/casting] [4]') 778 finally: 779 fs.read_text_file = orig_read_text_file_fn 780 781 def test_static_cast_on_objects_without_toFoo(self): 782 mock_header_contents = ['inline FooBar* toFooBar(Bar* bar)'] 783 fs = FileSystem() 784 orig_read_text_file_fn = fs.read_text_file 785 786 def mock_read_text_file_fn(path): 787 return mock_header_contents 788 789 try: 790 fs.read_text_file = mock_read_text_file_fn 791 message = self.perform_avoid_static_cast_of_objects( 792 'Foo* x = static_cast<Foo*>(bar);', 793 filename='casting.cpp', 794 fs=fs) 795 self.assertEqual(message, 'static_cast of class objects is not allowed. Add toFoo in Foo.h and use it instead.' 796 ' [runtime/casting] [4]') 797 finally: 798 fs.read_text_file = orig_read_text_file_fn 799 800 # We cannot test this functionality because of difference of 801 # function definitions. Anyway, we may never enable this. 802 # 803 # # Test for unnamed arguments in a method. 804 # def test_check_for_unnamed_params(self): 805 # message = ('All parameters should be named in a function' 806 # ' [readability/function] [3]') 807 # self.assert_lint('virtual void A(int*) const;', message) 808 # self.assert_lint('virtual void B(void (*fn)(int*));', message) 809 # self.assert_lint('virtual void C(int*);', message) 810 # self.assert_lint('void *(*f)(void *) = x;', message) 811 # self.assert_lint('void Method(char*) {', message) 812 # self.assert_lint('void Method(char*);', message) 813 # self.assert_lint('void Method(char* /*x*/);', message) 814 # self.assert_lint('typedef void (*Method)(int32);', message) 815 # self.assert_lint('static void operator delete[](void*) throw();', message) 816 # 817 # self.assert_lint('virtual void D(int* p);', '') 818 # self.assert_lint('void operator delete(void* x) throw();', '') 819 # self.assert_lint('void Method(char* x)\n{', '') 820 # self.assert_lint('void Method(char* /*x*/)\n{', '') 821 # self.assert_lint('void Method(char* x);', '') 822 # self.assert_lint('typedef void (*Method)(int32 x);', '') 823 # self.assert_lint('static void operator delete[](void* x) throw();', '') 824 # self.assert_lint('static void operator delete[](void* /*x*/) throw();', '') 825 # 826 # # This one should technically warn, but doesn't because the function 827 # # pointer is confusing. 828 # self.assert_lint('virtual void E(void (*fn)(int* p));', '') 829 830 # Test deprecated casts such as int(d) 831 def test_deprecated_cast(self): 832 self.assert_lint( 833 'int a = int(2.2);', 834 'Using deprecated casting style. ' 835 'Use static_cast<int>(...) instead' 836 ' [readability/casting] [4]') 837 # Checks for false positives... 838 self.assert_lint( 839 'int a = int(); // Constructor, o.k.', 840 '') 841 self.assert_lint( 842 'X::X() : a(int()) { } // default Constructor, o.k.', 843 '') 844 self.assert_lint( 845 'operator bool(); // Conversion operator, o.k.', 846 '') 847 848 # The second parameter to a gMock method definition is a function signature 849 # that often looks like a bad cast but should not picked up by lint. 850 def test_mock_method(self): 851 self.assert_lint( 852 'MOCK_METHOD0(method, int());', 853 '') 854 self.assert_lint( 855 'MOCK_CONST_METHOD1(method, float(string));', 856 '') 857 self.assert_lint( 858 'MOCK_CONST_METHOD2_T(method, double(float, float));', 859 '') 860 861 # Test sizeof(type) cases. 862 def test_sizeof_type(self): 863 self.assert_lint( 864 'sizeof(int);', 865 'Using sizeof(type). Use sizeof(varname) instead if possible' 866 ' [runtime/sizeof] [1]') 867 self.assert_lint( 868 'sizeof(int *);', 869 'Using sizeof(type). Use sizeof(varname) instead if possible' 870 ' [runtime/sizeof] [1]') 871 872 # Test typedef cases. There was a bug that cpp_style misidentified 873 # typedef for pointer to function as C-style cast and produced 874 # false-positive error messages. 875 def test_typedef_for_pointer_to_function(self): 876 self.assert_lint( 877 'typedef void (*Func)(int x);', 878 '') 879 self.assert_lint( 880 'typedef void (*Func)(int *x);', 881 '') 882 self.assert_lint( 883 'typedef void Func(int x);', 884 '') 885 self.assert_lint( 886 'typedef void Func(int *x);', 887 '') 888 889 def test_include_what_you_use_no_implementation_files(self): 890 code = 'std::vector<int> foo;' 891 self.assertEqual('Add #include <vector> for vector<>' 892 ' [build/include_what_you_use] [4]', 893 self.perform_include_what_you_use(code, 'foo.h')) 894 self.assertEqual('', 895 self.perform_include_what_you_use(code, 'foo.cpp')) 896 897 def test_include_what_you_use(self): 898 self.assert_include_what_you_use( 899 '''#include <vector> 900 std::vector<int> foo; 901 ''', 902 '') 903 self.assert_include_what_you_use( 904 '''#include <map> 905 std::pair<int,int> foo; 906 ''', 907 '') 908 self.assert_include_what_you_use( 909 '''#include <multimap> 910 std::pair<int,int> foo; 911 ''', 912 '') 913 self.assert_include_what_you_use( 914 '''#include <hash_map> 915 std::pair<int,int> foo; 916 ''', 917 '') 918 self.assert_include_what_you_use( 919 '''#include <utility> 920 std::pair<int,int> foo; 921 ''', 922 '') 923 self.assert_include_what_you_use( 924 '''#include <vector> 925 DECLARE_string(foobar); 926 ''', 927 '') 928 self.assert_include_what_you_use( 929 '''#include <vector> 930 DEFINE_string(foobar, "", ""); 931 ''', 932 '') 933 self.assert_include_what_you_use( 934 '''#include <vector> 935 std::pair<int,int> foo; 936 ''', 937 'Add #include <utility> for pair<>' 938 ' [build/include_what_you_use] [4]') 939 self.assert_include_what_you_use( 940 '''#include "base/foobar.h" 941 std::vector<int> foo; 942 ''', 943 'Add #include <vector> for vector<>' 944 ' [build/include_what_you_use] [4]') 945 self.assert_include_what_you_use( 946 '''#include <vector> 947 std::set<int> foo; 948 ''', 949 'Add #include <set> for set<>' 950 ' [build/include_what_you_use] [4]') 951 self.assert_include_what_you_use( 952 '''#include "base/foobar.h" 953 hash_map<int, int> foobar; 954 ''', 955 'Add #include <hash_map> for hash_map<>' 956 ' [build/include_what_you_use] [4]') 957 self.assert_include_what_you_use( 958 '''#include "base/foobar.h" 959 bool foobar = std::less<int>(0,1); 960 ''', 961 'Add #include <functional> for less<>' 962 ' [build/include_what_you_use] [4]') 963 self.assert_include_what_you_use( 964 '''#include "base/foobar.h" 965 bool foobar = min<int>(0,1); 966 ''', 967 'Add #include <algorithm> for min [build/include_what_you_use] [4]') 968 self.assert_include_what_you_use( 969 'void a(const string &foobar);', 970 'Add #include <string> for string [build/include_what_you_use] [4]') 971 self.assert_include_what_you_use( 972 '''#include "base/foobar.h" 973 bool foobar = swap(0,1); 974 ''', 975 'Add #include <algorithm> for swap [build/include_what_you_use] [4]') 976 self.assert_include_what_you_use( 977 '''#include "base/foobar.h" 978 bool foobar = transform(a.begin(), a.end(), b.start(), Foo); 979 ''', 980 'Add #include <algorithm> for transform ' 981 '[build/include_what_you_use] [4]') 982 self.assert_include_what_you_use( 983 '''#include "base/foobar.h" 984 bool foobar = min_element(a.begin(), a.end()); 985 ''', 986 'Add #include <algorithm> for min_element ' 987 '[build/include_what_you_use] [4]') 988 self.assert_include_what_you_use( 989 '''foo->swap(0,1); 990 foo.swap(0,1); 991 ''', 992 '') 993 self.assert_include_what_you_use( 994 '''#include <string> 995 void a(const std::multimap<int,string> &foobar); 996 ''', 997 'Add #include <map> for multimap<>' 998 ' [build/include_what_you_use] [4]') 999 self.assert_include_what_you_use( 1000 '''#include <queue> 1001 void a(const std::priority_queue<int> &foobar); 1002 ''', 1003 '') 1004 self.assert_include_what_you_use( 1005 '''#include "base/basictypes.h" 1006 #include "base/port.h" 1007 #include <assert.h> 1008 #include <string> 1009 #include <vector> 1010 vector<string> hajoa;''', '') 1011 self.assert_include_what_you_use( 1012 '''#include <string> 1013 int i = numeric_limits<int>::max() 1014 ''', 1015 'Add #include <limits> for numeric_limits<>' 1016 ' [build/include_what_you_use] [4]') 1017 self.assert_include_what_you_use( 1018 '''#include <limits> 1019 int i = numeric_limits<int>::max() 1020 ''', 1021 '') 1022 1023 # Test the UpdateIncludeState code path. 1024 mock_header_contents = ['#include "blah/foo.h"', '#include "blah/bar.h"'] 1025 fs = FileSystem() 1026 orig_read_text_file_fn = fs.read_text_file 1027 1028 def mock_read_text_file_fn(path): 1029 return mock_header_contents 1030 1031 try: 1032 fs.read_text_file = mock_read_text_file_fn 1033 message = self.perform_include_what_you_use( 1034 '#include "config.h"\n' 1035 '#include "blah/a.h"\n', 1036 filename='blah/a.cpp', 1037 fs=fs) 1038 self.assertEqual(message, '') 1039 1040 mock_header_contents = ['#include <set>'] 1041 message = self.perform_include_what_you_use( 1042 '''#include "config.h" 1043 #include "blah/a.h" 1044 1045 std::set<int> foo;''', 1046 filename='blah/a.cpp', 1047 fs=fs) 1048 self.assertEqual(message, '') 1049 1050 # If there's just a .cpp and the header can't be found then it's ok. 1051 message = self.perform_include_what_you_use( 1052 '''#include "config.h" 1053 #include "blah/a.h" 1054 1055 std::set<int> foo;''', 1056 filename='blah/a.cpp') 1057 self.assertEqual(message, '') 1058 1059 # Make sure we find the headers with relative paths. 1060 mock_header_contents = [''] 1061 message = self.perform_include_what_you_use( 1062 '''#include "config.h" 1063 #include "%s%sa.h" 1064 1065 std::set<int> foo;''' % (os.path.basename(os.getcwd()), os.path.sep), 1066 filename='a.cpp', 1067 fs=fs) 1068 self.assertEqual(message, 'Add #include <set> for set<> ' 1069 '[build/include_what_you_use] [4]') 1070 finally: 1071 fs.read_text_file = orig_read_text_file_fn 1072 1073 def test_files_belong_to_same_module(self): 1074 f = cpp_style.files_belong_to_same_module 1075 self.assertEqual((True, ''), f('a.cpp', 'a.h')) 1076 self.assertEqual((True, ''), f('base/google.cpp', 'base/google.h')) 1077 self.assertEqual((True, ''), f('base/google_test.cpp', 'base/google.h')) 1078 self.assertEqual((True, ''), 1079 f('base/google_unittest.cpp', 'base/google.h')) 1080 self.assertEqual((True, ''), 1081 f('base/internal/google_unittest.cpp', 1082 'base/public/google.h')) 1083 self.assertEqual((True, 'xxx/yyy/'), 1084 f('xxx/yyy/base/internal/google_unittest.cpp', 1085 'base/public/google.h')) 1086 self.assertEqual((True, 'xxx/yyy/'), 1087 f('xxx/yyy/base/google_unittest.cpp', 1088 'base/public/google.h')) 1089 self.assertEqual((True, ''), 1090 f('base/google_unittest.cpp', 'base/google-inl.h')) 1091 self.assertEqual((True, '/home/build/google3/'), 1092 f('/home/build/google3/base/google.cpp', 'base/google.h')) 1093 1094 self.assertEqual((False, ''), 1095 f('/home/build/google3/base/google.cpp', 'basu/google.h')) 1096 self.assertEqual((False, ''), f('a.cpp', 'b.h')) 1097 1098 def test_cleanse_line(self): 1099 self.assertEqual('int foo = 0; ', 1100 cpp_style.cleanse_comments('int foo = 0; // danger!')) 1101 self.assertEqual('int o = 0;', 1102 cpp_style.cleanse_comments('int /* foo */ o = 0;')) 1103 self.assertEqual('foo(int a, int b);', 1104 cpp_style.cleanse_comments('foo(int a /* abc */, int b);')) 1105 self.assertEqual('f(a, b);', 1106 cpp_style.cleanse_comments('f(a, /* name */ b);')) 1107 self.assertEqual('f(a, b);', 1108 cpp_style.cleanse_comments('f(a /* name */, b);')) 1109 self.assertEqual('f(a, b);', 1110 cpp_style.cleanse_comments('f(a, /* name */b);')) 1111 1112 def test_multi_line_comments(self): 1113 # missing explicit is bad 1114 self.assert_multi_line_lint( 1115 r'''int a = 0; 1116 /* multi-liner 1117 class Foo { 1118 Foo(int f); // should cause a lint warning in code 1119 } 1120 */ ''', 1121 '') 1122 self.assert_multi_line_lint( 1123 '''\ 1124 /* int a = 0; multi-liner 1125 static const int b = 0;''', 1126 ['Could not find end of multi-line comment' 1127 ' [readability/multiline_comment] [5]', 1128 'Complex multi-line /*...*/-style comment found. ' 1129 'Lint may give bogus warnings. Consider replacing these with ' 1130 '//-style comments, with #if 0...#endif, or with more clearly ' 1131 'structured multi-line comments. [readability/multiline_comment] [5]']) 1132 self.assert_multi_line_lint(r''' /* multi-line comment''', 1133 ['Could not find end of multi-line comment' 1134 ' [readability/multiline_comment] [5]', 1135 'Complex multi-line /*...*/-style comment found. ' 1136 'Lint may give bogus warnings. Consider replacing these with ' 1137 '//-style comments, with #if 0...#endif, or with more clearly ' 1138 'structured multi-line comments. [readability/multiline_comment] [5]']) 1139 self.assert_multi_line_lint(r''' // /* comment, but not multi-line''', '') 1140 1141 def test_multiline_strings(self): 1142 multiline_string_error_message = ( 1143 'Multi-line string ("...") found. This lint script doesn\'t ' 1144 'do well with such strings, and may give bogus warnings. They\'re ' 1145 'ugly and unnecessary, and you should use concatenation instead".' 1146 ' [readability/multiline_string] [5]') 1147 1148 file_path = 'mydir/foo.cpp' 1149 1150 error_collector = ErrorCollector(self.assertTrue) 1151 self.process_file_data(file_path, 'cpp', 1152 ['const char* str = "This is a\\', 1153 ' multiline string.";'], 1154 error_collector) 1155 self.assertEqual( 1156 2, # One per line. 1157 error_collector.result_list().count(multiline_string_error_message)) 1158 1159 # Test non-explicit single-argument constructors 1160 def test_explicit_single_argument_constructors(self): 1161 # missing explicit is bad 1162 self.assert_multi_line_lint( 1163 '''\ 1164 class Foo { 1165 Foo(int f); 1166 };''', 1167 'Single-argument constructors should be marked explicit.' 1168 ' [runtime/explicit] [5]') 1169 # missing explicit is bad, even with whitespace 1170 self.assert_multi_line_lint( 1171 '''\ 1172 class Foo { 1173 Foo (int f); 1174 };''', 1175 ['Extra space before ( in function call [whitespace/parens] [4]', 1176 'Single-argument constructors should be marked explicit.' 1177 ' [runtime/explicit] [5]']) 1178 # missing explicit, with distracting comment, is still bad 1179 self.assert_multi_line_lint( 1180 '''\ 1181 class Foo { 1182 Foo(int f); // simpler than Foo(blargh, blarg) 1183 };''', 1184 'Single-argument constructors should be marked explicit.' 1185 ' [runtime/explicit] [5]') 1186 # missing explicit, with qualified classname 1187 self.assert_multi_line_lint( 1188 '''\ 1189 class Qualifier::AnotherOne::Foo { 1190 Foo(int f); 1191 };''', 1192 'Single-argument constructors should be marked explicit.' 1193 ' [runtime/explicit] [5]') 1194 # structs are caught as well. 1195 self.assert_multi_line_lint( 1196 '''\ 1197 struct Foo { 1198 Foo(int f); 1199 };''', 1200 'Single-argument constructors should be marked explicit.' 1201 ' [runtime/explicit] [5]') 1202 # Templatized classes are caught as well. 1203 self.assert_multi_line_lint( 1204 '''\ 1205 template<typename T> class Foo { 1206 Foo(int f); 1207 };''', 1208 'Single-argument constructors should be marked explicit.' 1209 ' [runtime/explicit] [5]') 1210 # proper style is okay 1211 self.assert_multi_line_lint( 1212 '''\ 1213 class Foo { 1214 explicit Foo(int f); 1215 };''', 1216 '') 1217 # two argument constructor is okay 1218 self.assert_multi_line_lint( 1219 '''\ 1220 class Foo { 1221 Foo(int f, int b); 1222 };''', 1223 '') 1224 # two argument constructor, across two lines, is okay 1225 self.assert_multi_line_lint( 1226 '''\ 1227 class Foo { 1228 Foo(int f, 1229 int b); 1230 };''', 1231 '') 1232 # non-constructor (but similar name), is okay 1233 self.assert_multi_line_lint( 1234 '''\ 1235 class Foo { 1236 aFoo(int f); 1237 };''', 1238 '') 1239 # constructor with void argument is okay 1240 self.assert_multi_line_lint( 1241 '''\ 1242 class Foo { 1243 Foo(void); 1244 };''', 1245 '') 1246 # single argument method is okay 1247 self.assert_multi_line_lint( 1248 '''\ 1249 class Foo { 1250 Bar(int b); 1251 };''', 1252 '') 1253 # comments should be ignored 1254 self.assert_multi_line_lint( 1255 '''\ 1256 class Foo { 1257 // Foo(int f); 1258 };''', 1259 '') 1260 # single argument function following class definition is okay 1261 # (okay, it's not actually valid, but we don't want a false positive) 1262 self.assert_multi_line_lint( 1263 '''\ 1264 class Foo { 1265 Foo(int f, int b); 1266 }; 1267 Foo(int f);''', 1268 '') 1269 # single argument function is okay 1270 self.assert_multi_line_lint( 1271 '''static Foo(int f);''', 1272 '') 1273 # single argument copy constructor is okay. 1274 self.assert_multi_line_lint( 1275 '''\ 1276 class Foo { 1277 Foo(const Foo&); 1278 };''', 1279 '') 1280 self.assert_multi_line_lint( 1281 '''\ 1282 class Foo { 1283 Foo(Foo&); 1284 };''', 1285 '') 1286 1287 def test_slash_star_comment_on_single_line(self): 1288 self.assert_multi_line_lint( 1289 '''/* static */ Foo(int f);''', 1290 '') 1291 self.assert_multi_line_lint( 1292 '''/*/ static */ Foo(int f);''', 1293 '') 1294 self.assert_multi_line_lint( 1295 '''/*/ static Foo(int f);''', 1296 'Could not find end of multi-line comment' 1297 ' [readability/multiline_comment] [5]') 1298 self.assert_multi_line_lint( 1299 ''' /*/ static Foo(int f);''', 1300 'Could not find end of multi-line comment' 1301 ' [readability/multiline_comment] [5]') 1302 1303 # Test suspicious usage of "if" like this: 1304 # if (a == b) { 1305 # DoSomething(); 1306 # } if (a == c) { // Should be "else if". 1307 # DoSomething(); // This gets called twice if a == b && a == c. 1308 # } 1309 def test_suspicious_usage_of_if(self): 1310 self.assert_lint( 1311 ' if (a == b) {', 1312 '') 1313 self.assert_lint( 1314 ' } if (a == b) {', 1315 'Did you mean "else if"? If not, start a new line for "if".' 1316 ' [readability/braces] [4]') 1317 1318 # Test suspicious usage of memset. Specifically, a 0 1319 # as the final argument is almost certainly an error. 1320 def test_suspicious_usage_of_memset(self): 1321 # Normal use is okay. 1322 self.assert_lint( 1323 ' memset(buf, 0, sizeof(buf))', 1324 '') 1325 1326 # A 0 as the final argument is almost certainly an error. 1327 self.assert_lint( 1328 ' memset(buf, sizeof(buf), 0)', 1329 'Did you mean "memset(buf, 0, sizeof(buf))"?' 1330 ' [runtime/memset] [4]') 1331 self.assert_lint( 1332 ' memset(buf, xsize * ysize, 0)', 1333 'Did you mean "memset(buf, 0, xsize * ysize)"?' 1334 ' [runtime/memset] [4]') 1335 1336 # There is legitimate test code that uses this form. 1337 # This is okay since the second argument is a literal. 1338 self.assert_lint( 1339 " memset(buf, 'y', 0)", 1340 '') 1341 self.assert_lint( 1342 ' memset(buf, 4, 0)', 1343 '') 1344 self.assert_lint( 1345 ' memset(buf, -1, 0)', 1346 '') 1347 self.assert_lint( 1348 ' memset(buf, 0xF1, 0)', 1349 '') 1350 self.assert_lint( 1351 ' memset(buf, 0xcd, 0)', 1352 '') 1353 1354 def test_check_posix_threading(self): 1355 self.assert_lint('sctime_r()', '') 1356 self.assert_lint('strtok_r()', '') 1357 self.assert_lint(' strtok_r(foo, ba, r)', '') 1358 self.assert_lint('brand()', '') 1359 self.assert_lint('_rand()', '') 1360 self.assert_lint('.rand()', '') 1361 self.assert_lint('>rand()', '') 1362 self.assert_lint('rand()', 1363 'Consider using rand_r(...) instead of rand(...)' 1364 ' for improved thread safety.' 1365 ' [runtime/threadsafe_fn] [2]') 1366 self.assert_lint('strtok()', 1367 'Consider using strtok_r(...) ' 1368 'instead of strtok(...)' 1369 ' for improved thread safety.' 1370 ' [runtime/threadsafe_fn] [2]') 1371 1372 # Test potential format string bugs like printf(foo). 1373 def test_format_strings(self): 1374 self.assert_lint('printf("foo")', '') 1375 self.assert_lint('printf("foo: %s", foo)', '') 1376 self.assert_lint('DocidForPrintf(docid)', '') # Should not trigger. 1377 self.assert_lint( 1378 'printf(foo)', 1379 'Potential format string bug. Do printf("%s", foo) instead.' 1380 ' [runtime/printf] [4]') 1381 self.assert_lint( 1382 'printf(foo.c_str())', 1383 'Potential format string bug. ' 1384 'Do printf("%s", foo.c_str()) instead.' 1385 ' [runtime/printf] [4]') 1386 self.assert_lint( 1387 'printf(foo->c_str())', 1388 'Potential format string bug. ' 1389 'Do printf("%s", foo->c_str()) instead.' 1390 ' [runtime/printf] [4]') 1391 self.assert_lint( 1392 'StringPrintf(foo)', 1393 'Potential format string bug. Do StringPrintf("%s", foo) instead.' 1394 '' 1395 ' [runtime/printf] [4]') 1396 1397 # Variable-length arrays are not permitted. 1398 def test_variable_length_array_detection(self): 1399 errmsg = ('Do not use variable-length arrays. Use an appropriately named ' 1400 "('k' followed by CamelCase) compile-time constant for the size." 1401 ' [runtime/arrays] [1]') 1402 1403 self.assert_lint('int a[any_old_variable];', errmsg) 1404 self.assert_lint('int doublesize[some_var * 2];', errmsg) 1405 self.assert_lint('int a[afunction()];', errmsg) 1406 self.assert_lint('int a[function(kMaxFooBars)];', errmsg) 1407 self.assert_lint('bool aList[items_->size()];', errmsg) 1408 self.assert_lint('namespace::Type buffer[len+1];', errmsg) 1409 1410 self.assert_lint('int a[64];', '') 1411 self.assert_lint('int a[0xFF];', '') 1412 self.assert_lint('int first[256], second[256];', '') 1413 self.assert_lint('int arrayName[kCompileTimeConstant];', '') 1414 self.assert_lint('char buf[somenamespace::kBufSize];', '') 1415 self.assert_lint('int arrayName[ALL_CAPS];', '') 1416 self.assert_lint('AClass array1[foo::bar::ALL_CAPS];', '') 1417 self.assert_lint('int a[kMaxStrLen + 1];', '') 1418 self.assert_lint('int a[sizeof(foo)];', '') 1419 self.assert_lint('int a[sizeof(*foo)];', '') 1420 self.assert_lint('int a[sizeof foo];', '') 1421 self.assert_lint('int a[sizeof(struct Foo)];', '') 1422 self.assert_lint('int a[128 - sizeof(const bar)];', '') 1423 self.assert_lint('int a[(sizeof(foo) * 4)];', '') 1424 self.assert_lint('int a[(arraysize(fixed_size_array)/2) << 1];', 'Missing spaces around / [whitespace/operators] [3]') 1425 self.assert_lint('delete a[some_var];', '') 1426 self.assert_lint('return a[some_var];', '') 1427 1428 # Brace usage 1429 def test_braces(self): 1430 # Braces shouldn't be followed by a ; unless they're defining a struct 1431 # or initializing an array 1432 self.assert_lint('int a[3] = { 1, 2, 3 };', '') 1433 self.assert_lint( 1434 '''\ 1435 const int foo[] = 1436 {1, 2, 3 };''', 1437 '') 1438 # For single line, unmatched '}' with a ';' is ignored (not enough context) 1439 self.assert_multi_line_lint( 1440 '''\ 1441 int a[3] = { 1, 1442 2, 1443 3 };''', 1444 '') 1445 self.assert_multi_line_lint( 1446 '''\ 1447 int a[2][3] = { { 1, 2 }, 1448 { 3, 4 } };''', 1449 '') 1450 self.assert_multi_line_lint( 1451 '''\ 1452 int a[2][3] = 1453 { { 1, 2 }, 1454 { 3, 4 } };''', 1455 '') 1456 1457 # CHECK/EXPECT_TRUE/EXPECT_FALSE replacements 1458 def test_check_check(self): 1459 self.assert_lint('CHECK(x == 42)', 1460 'Consider using CHECK_EQ instead of CHECK(a == b)' 1461 ' [readability/check] [2]') 1462 self.assert_lint('CHECK(x != 42)', 1463 'Consider using CHECK_NE instead of CHECK(a != b)' 1464 ' [readability/check] [2]') 1465 self.assert_lint('CHECK(x >= 42)', 1466 'Consider using CHECK_GE instead of CHECK(a >= b)' 1467 ' [readability/check] [2]') 1468 self.assert_lint('CHECK(x > 42)', 1469 'Consider using CHECK_GT instead of CHECK(a > b)' 1470 ' [readability/check] [2]') 1471 self.assert_lint('CHECK(x <= 42)', 1472 'Consider using CHECK_LE instead of CHECK(a <= b)' 1473 ' [readability/check] [2]') 1474 self.assert_lint('CHECK(x < 42)', 1475 'Consider using CHECK_LT instead of CHECK(a < b)' 1476 ' [readability/check] [2]') 1477 1478 self.assert_lint('DCHECK(x == 42)', 1479 'Consider using DCHECK_EQ instead of DCHECK(a == b)' 1480 ' [readability/check] [2]') 1481 self.assert_lint('DCHECK(x != 42)', 1482 'Consider using DCHECK_NE instead of DCHECK(a != b)' 1483 ' [readability/check] [2]') 1484 self.assert_lint('DCHECK(x >= 42)', 1485 'Consider using DCHECK_GE instead of DCHECK(a >= b)' 1486 ' [readability/check] [2]') 1487 self.assert_lint('DCHECK(x > 42)', 1488 'Consider using DCHECK_GT instead of DCHECK(a > b)' 1489 ' [readability/check] [2]') 1490 self.assert_lint('DCHECK(x <= 42)', 1491 'Consider using DCHECK_LE instead of DCHECK(a <= b)' 1492 ' [readability/check] [2]') 1493 self.assert_lint('DCHECK(x < 42)', 1494 'Consider using DCHECK_LT instead of DCHECK(a < b)' 1495 ' [readability/check] [2]') 1496 1497 self.assert_lint( 1498 'EXPECT_TRUE("42" == x)', 1499 'Consider using EXPECT_EQ instead of EXPECT_TRUE(a == b)' 1500 ' [readability/check] [2]') 1501 self.assert_lint( 1502 'EXPECT_TRUE("42" != x)', 1503 'Consider using EXPECT_NE instead of EXPECT_TRUE(a != b)' 1504 ' [readability/check] [2]') 1505 self.assert_lint( 1506 'EXPECT_TRUE(+42 >= x)', 1507 'Consider using EXPECT_GE instead of EXPECT_TRUE(a >= b)' 1508 ' [readability/check] [2]') 1509 self.assert_lint( 1510 'EXPECT_TRUE_M(-42 > x)', 1511 'Consider using EXPECT_GT_M instead of EXPECT_TRUE_M(a > b)' 1512 ' [readability/check] [2]') 1513 self.assert_lint( 1514 'EXPECT_TRUE_M(42U <= x)', 1515 'Consider using EXPECT_LE_M instead of EXPECT_TRUE_M(a <= b)' 1516 ' [readability/check] [2]') 1517 self.assert_lint( 1518 'EXPECT_TRUE_M(42L < x)', 1519 'Consider using EXPECT_LT_M instead of EXPECT_TRUE_M(a < b)' 1520 ' [readability/check] [2]') 1521 1522 self.assert_lint( 1523 'EXPECT_FALSE(x == 42)', 1524 'Consider using EXPECT_NE instead of EXPECT_FALSE(a == b)' 1525 ' [readability/check] [2]') 1526 self.assert_lint( 1527 'EXPECT_FALSE(x != 42)', 1528 'Consider using EXPECT_EQ instead of EXPECT_FALSE(a != b)' 1529 ' [readability/check] [2]') 1530 self.assert_lint( 1531 'EXPECT_FALSE(x >= 42)', 1532 'Consider using EXPECT_LT instead of EXPECT_FALSE(a >= b)' 1533 ' [readability/check] [2]') 1534 self.assert_lint( 1535 'ASSERT_FALSE(x > 42)', 1536 'Consider using ASSERT_LE instead of ASSERT_FALSE(a > b)' 1537 ' [readability/check] [2]') 1538 self.assert_lint( 1539 'ASSERT_FALSE(x <= 42)', 1540 'Consider using ASSERT_GT instead of ASSERT_FALSE(a <= b)' 1541 ' [readability/check] [2]') 1542 self.assert_lint( 1543 'ASSERT_FALSE_M(x < 42)', 1544 'Consider using ASSERT_GE_M instead of ASSERT_FALSE_M(a < b)' 1545 ' [readability/check] [2]') 1546 1547 self.assert_lint('CHECK(some_iterator == obj.end())', '') 1548 self.assert_lint('EXPECT_TRUE(some_iterator == obj.end())', '') 1549 self.assert_lint('EXPECT_FALSE(some_iterator == obj.end())', '') 1550 1551 self.assert_lint('CHECK(CreateTestFile(dir, (1 << 20)));', '') 1552 self.assert_lint('CHECK(CreateTestFile(dir, (1 >> 20)));', '') 1553 1554 self.assert_lint('CHECK(x<42)', 1555 ['Missing spaces around <' 1556 ' [whitespace/operators] [3]', 1557 'Consider using CHECK_LT instead of CHECK(a < b)' 1558 ' [readability/check] [2]']) 1559 self.assert_lint('CHECK(x>42)', 1560 'Consider using CHECK_GT instead of CHECK(a > b)' 1561 ' [readability/check] [2]') 1562 1563 self.assert_lint( 1564 ' EXPECT_TRUE(42 < x) // Random comment.', 1565 'Consider using EXPECT_LT instead of EXPECT_TRUE(a < b)' 1566 ' [readability/check] [2]') 1567 self.assert_lint( 1568 'EXPECT_TRUE( 42 < x )', 1569 ['Extra space after ( in function call' 1570 ' [whitespace/parens] [4]', 1571 'Consider using EXPECT_LT instead of EXPECT_TRUE(a < b)' 1572 ' [readability/check] [2]']) 1573 self.assert_lint( 1574 'CHECK("foo" == "foo")', 1575 'Consider using CHECK_EQ instead of CHECK(a == b)' 1576 ' [readability/check] [2]') 1577 1578 self.assert_lint('CHECK_EQ("foo", "foo")', '') 1579 1580 def test_brace_at_begin_of_line(self): 1581 self.assert_lint('{', 1582 'This { should be at the end of the previous line' 1583 ' [whitespace/braces] [4]') 1584 self.assert_multi_line_lint( 1585 '#endif\n' 1586 '{\n' 1587 '}\n', 1588 '') 1589 self.assert_multi_line_lint( 1590 'if (condition) {', 1591 '') 1592 self.assert_multi_line_lint( 1593 ' MACRO1(macroArg) {', 1594 '') 1595 self.assert_multi_line_lint( 1596 'ACCESSOR_GETTER(MessageEventPorts) {', 1597 'Place brace on its own line for function definitions. [whitespace/braces] [4]') 1598 self.assert_multi_line_lint( 1599 'int foo() {', 1600 'Place brace on its own line for function definitions. [whitespace/braces] [4]') 1601 self.assert_multi_line_lint( 1602 'int foo() const {', 1603 'Place brace on its own line for function definitions. [whitespace/braces] [4]') 1604 self.assert_multi_line_lint( 1605 'int foo() const OVERRIDE {', 1606 'Place brace on its own line for function definitions. [whitespace/braces] [4]') 1607 self.assert_multi_line_lint( 1608 'int foo() OVERRIDE {', 1609 'Place brace on its own line for function definitions. [whitespace/braces] [4]') 1610 self.assert_multi_line_lint( 1611 'int foo() const\n' 1612 '{\n' 1613 '}\n', 1614 '') 1615 self.assert_multi_line_lint( 1616 'int foo() OVERRIDE\n' 1617 '{\n' 1618 '}\n', 1619 '') 1620 self.assert_multi_line_lint( 1621 'if (condition\n' 1622 ' && condition2\n' 1623 ' && condition3) {\n' 1624 '}\n', 1625 '') 1626 1627 def test_mismatching_spaces_in_parens(self): 1628 self.assert_lint('if (foo ) {', 'Extra space before ) in if' 1629 ' [whitespace/parens] [5]') 1630 self.assert_lint('switch ( foo) {', 'Extra space after ( in switch' 1631 ' [whitespace/parens] [5]') 1632 self.assert_lint('for (foo; ba; bar ) {', 'Extra space before ) in for' 1633 ' [whitespace/parens] [5]') 1634 self.assert_lint('for ((foo); (ba); (bar) ) {', 'Extra space before ) in for' 1635 ' [whitespace/parens] [5]') 1636 self.assert_lint('for (; foo; bar) {', '') 1637 self.assert_lint('for (; (foo); (bar)) {', '') 1638 self.assert_lint('for ( ; foo; bar) {', '') 1639 self.assert_lint('for ( ; (foo); (bar)) {', '') 1640 self.assert_lint('for ( ; foo; bar ) {', 'Extra space before ) in for' 1641 ' [whitespace/parens] [5]') 1642 self.assert_lint('for ( ; (foo); (bar) ) {', 'Extra space before ) in for' 1643 ' [whitespace/parens] [5]') 1644 self.assert_lint('for (foo; bar; ) {', '') 1645 self.assert_lint('for ((foo); (bar); ) {', '') 1646 self.assert_lint('foreach (foo, foos ) {', 'Extra space before ) in foreach' 1647 ' [whitespace/parens] [5]') 1648 self.assert_lint('foreach ( foo, foos) {', 'Extra space after ( in foreach' 1649 ' [whitespace/parens] [5]') 1650 self.assert_lint('while ( foo) {', 'Extra space after ( in while' 1651 ' [whitespace/parens] [5]') 1652 1653 def test_spacing_for_fncall(self): 1654 self.assert_lint('if (foo) {', '') 1655 self.assert_lint('for (foo;bar;baz) {', '') 1656 self.assert_lint('foreach (foo, foos) {', '') 1657 self.assert_lint('while (foo) {', '') 1658 self.assert_lint('switch (foo) {', '') 1659 self.assert_lint('new (RenderArena()) RenderInline(document())', '') 1660 self.assert_lint('foo( bar)', 'Extra space after ( in function call' 1661 ' [whitespace/parens] [4]') 1662 self.assert_lint('foobar( \\', '') 1663 self.assert_lint('foobar( \\', '') 1664 self.assert_lint('( a + b)', 'Extra space after (' 1665 ' [whitespace/parens] [2]') 1666 self.assert_lint('((a+b))', '') 1667 self.assert_lint('foo (foo)', 'Extra space before ( in function call' 1668 ' [whitespace/parens] [4]') 1669 self.assert_lint('#elif (foo(bar))', '') 1670 self.assert_lint('#elif (foo(bar) && foo(baz))', '') 1671 self.assert_lint('typedef foo (*foo)(foo)', '') 1672 self.assert_lint('typedef foo (*foo12bar_)(foo)', '') 1673 self.assert_lint('typedef foo (Foo::*bar)(foo)', '') 1674 self.assert_lint('foo (Foo::*bar)(', 1675 'Extra space before ( in function call' 1676 ' [whitespace/parens] [4]') 1677 self.assert_lint('typedef foo (Foo::*bar)(', '') 1678 self.assert_lint('(foo)(bar)', '') 1679 self.assert_lint('Foo (*foo)(bar)', '') 1680 self.assert_lint('Foo (*foo)(Bar bar,', '') 1681 self.assert_lint('char (*p)[sizeof(foo)] = &foo', '') 1682 self.assert_lint('char (&ref)[sizeof(foo)] = &foo', '') 1683 self.assert_lint('const char32 (*table[])[6];', '') 1684 1685 def test_spacing_before_braces(self): 1686 self.assert_lint('if (foo){', 'Missing space before {' 1687 ' [whitespace/braces] [5]') 1688 self.assert_lint('for{', 'Missing space before {' 1689 ' [whitespace/braces] [5]') 1690 self.assert_lint('for {', '') 1691 self.assert_lint('EXPECT_DEBUG_DEATH({', '') 1692 1693 def test_spacing_between_braces(self): 1694 self.assert_lint(' { }', '') 1695 self.assert_lint(' {}', 'Missing space inside { }. [whitespace/braces] [5]') 1696 self.assert_lint(' { }', 'Too many spaces inside { }. [whitespace/braces] [5]') 1697 1698 def test_spacing_around_else(self): 1699 self.assert_lint('}else {', 'Missing space before else' 1700 ' [whitespace/braces] [5]') 1701 self.assert_lint('} else{', 'Missing space before {' 1702 ' [whitespace/braces] [5]') 1703 self.assert_lint('} else {', '') 1704 self.assert_lint('} else if', '') 1705 1706 def test_spacing_for_binary_ops(self): 1707 self.assert_lint('if (foo<=bar) {', 'Missing spaces around <=' 1708 ' [whitespace/operators] [3]') 1709 self.assert_lint('if (foo<bar) {', 'Missing spaces around <' 1710 ' [whitespace/operators] [3]') 1711 self.assert_lint('if (foo<bar->baz) {', 'Missing spaces around <' 1712 ' [whitespace/operators] [3]') 1713 self.assert_lint('if (foo<bar->bar) {', 'Missing spaces around <' 1714 ' [whitespace/operators] [3]') 1715 self.assert_lint('typedef hash_map<Foo, Bar', 'Missing spaces around <' 1716 ' [whitespace/operators] [3]') 1717 self.assert_lint('typedef hash_map<FoooooType, BaaaaarType,', '') 1718 self.assert_lint('a<Foo> t+=b;', 'Missing spaces around +=' 1719 ' [whitespace/operators] [3]') 1720 self.assert_lint('a<Foo> t-=b;', 'Missing spaces around -=' 1721 ' [whitespace/operators] [3]') 1722 self.assert_lint('a<Foo*> t*=b;', 'Missing spaces around *=' 1723 ' [whitespace/operators] [3]') 1724 self.assert_lint('a<Foo*> t/=b;', 'Missing spaces around /=' 1725 ' [whitespace/operators] [3]') 1726 self.assert_lint('a<Foo*> t|=b;', 'Missing spaces around |=' 1727 ' [whitespace/operators] [3]') 1728 self.assert_lint('a<Foo*> t&=b;', 'Missing spaces around &=' 1729 ' [whitespace/operators] [3]') 1730 self.assert_lint('a<Foo*> t<<=b;', 'Missing spaces around <<=' 1731 ' [whitespace/operators] [3]') 1732 self.assert_lint('a<Foo*> t>>=b;', 'Missing spaces around >>=' 1733 ' [whitespace/operators] [3]') 1734 self.assert_lint('a<Foo*> t>>=&b|c;', 'Missing spaces around >>=' 1735 ' [whitespace/operators] [3]') 1736 self.assert_lint('a<Foo*> t<<=*b/c;', 'Missing spaces around <<=' 1737 ' [whitespace/operators] [3]') 1738 self.assert_lint('a<Foo> t -= b;', '') 1739 self.assert_lint('a<Foo> t += b;', '') 1740 self.assert_lint('a<Foo*> t *= b;', '') 1741 self.assert_lint('a<Foo*> t /= b;', '') 1742 self.assert_lint('a<Foo*> t |= b;', '') 1743 self.assert_lint('a<Foo*> t &= b;', '') 1744 self.assert_lint('a<Foo*> t <<= b;', '') 1745 self.assert_lint('a<Foo*> t >>= b;', '') 1746 self.assert_lint('a<Foo*> t >>= &b|c;', 'Missing spaces around |' 1747 ' [whitespace/operators] [3]') 1748 self.assert_lint('a<Foo*> t <<= *b/c;', 'Missing spaces around /' 1749 ' [whitespace/operators] [3]') 1750 self.assert_lint('a<Foo*> t <<= b/c; //Test', [ 1751 'Should have a space between // and comment ' 1752 '[whitespace/comments] [4]', 'Missing' 1753 ' spaces around / [whitespace/operators] [3]']) 1754 self.assert_lint('a<Foo*> t <<= b||c; //Test', ['One space before end' 1755 ' of line comments [whitespace/comments] [5]', 1756 'Should have a space between // and comment ' 1757 '[whitespace/comments] [4]', 1758 'Missing spaces around || [whitespace/operators] [3]']) 1759 self.assert_lint('a<Foo*> t <<= b&&c; // Test', 'Missing spaces around' 1760 ' && [whitespace/operators] [3]') 1761 self.assert_lint('a<Foo*> t <<= b&&&c; // Test', 'Missing spaces around' 1762 ' && [whitespace/operators] [3]') 1763 self.assert_lint('a<Foo*> t <<= b&&*c; // Test', 'Missing spaces around' 1764 ' && [whitespace/operators] [3]') 1765 self.assert_lint('a<Foo*> t <<= b && *c; // Test', '') 1766 self.assert_lint('a<Foo*> t <<= b && &c; // Test', '') 1767 self.assert_lint('a<Foo*> t <<= b || &c; /*Test', 'Complex multi-line ' 1768 '/*...*/-style comment found. Lint may give bogus ' 1769 'warnings. Consider replacing these with //-style' 1770 ' comments, with #if 0...#endif, or with more clearly' 1771 ' structured multi-line comments. [readability/multiline_comment] [5]') 1772 self.assert_lint('a<Foo&> t <<= &b | &c;', '') 1773 self.assert_lint('a<Foo*> t <<= &b & &c; // Test', '') 1774 self.assert_lint('a<Foo*> t <<= *b / &c; // Test', '') 1775 self.assert_lint('if (a=b == 1)', 'Missing spaces around = [whitespace/operators] [4]') 1776 self.assert_lint('a = 1<<20', 'Missing spaces around << [whitespace/operators] [3]') 1777 self.assert_lint('if (a = b == 1)', '') 1778 self.assert_lint('a = 1 << 20', '') 1779 self.assert_multi_line_lint('#include <sys/io.h>\n', '') 1780 self.assert_multi_line_lint('#import <foo/bar.h>\n', '') 1781 1782 def test_operator_methods(self): 1783 self.assert_lint('String operator+(const String&, const String&);', '') 1784 self.assert_lint('String operator/(const String&, const String&);', '') 1785 self.assert_lint('bool operator==(const String&, const String&);', '') 1786 self.assert_lint('String& operator-=(const String&, const String&);', '') 1787 self.assert_lint('String& operator+=(const String&, const String&);', '') 1788 self.assert_lint('String& operator*=(const String&, const String&);', '') 1789 self.assert_lint('String& operator%=(const String&, const String&);', '') 1790 self.assert_lint('String& operator&=(const String&, const String&);', '') 1791 self.assert_lint('String& operator<<=(const String&, const String&);', '') 1792 self.assert_lint('String& operator>>=(const String&, const String&);', '') 1793 self.assert_lint('String& operator|=(const String&, const String&);', '') 1794 self.assert_lint('String& operator^=(const String&, const String&);', '') 1795 1796 def test_spacing_before_last_semicolon(self): 1797 self.assert_lint('call_function() ;', 1798 'Extra space before last semicolon. If this should be an ' 1799 'empty statement, use { } instead.' 1800 ' [whitespace/semicolon] [5]') 1801 self.assert_lint('while (true) ;', 1802 'Extra space before last semicolon. If this should be an ' 1803 'empty statement, use { } instead.' 1804 ' [whitespace/semicolon] [5]') 1805 self.assert_lint('default:;', 1806 'Semicolon defining empty statement. Use { } instead.' 1807 ' [whitespace/semicolon] [5]') 1808 self.assert_lint(' ;', 1809 'Line contains only semicolon. If this should be an empty ' 1810 'statement, use { } instead.' 1811 ' [whitespace/semicolon] [5]') 1812 self.assert_lint('for (int i = 0; ;', '') 1813 1814 # Static or global STL strings. 1815 def test_static_or_global_stlstrings(self): 1816 self.assert_lint('string foo;', 1817 'For a static/global string constant, use a C style ' 1818 'string instead: "char foo[]".' 1819 ' [runtime/string] [4]') 1820 self.assert_lint('string kFoo = "hello"; // English', 1821 'For a static/global string constant, use a C style ' 1822 'string instead: "char kFoo[]".' 1823 ' [runtime/string] [4]') 1824 self.assert_lint('static string foo;', 1825 'For a static/global string constant, use a C style ' 1826 'string instead: "static char foo[]".' 1827 ' [runtime/string] [4]') 1828 self.assert_lint('static const string foo;', 1829 'For a static/global string constant, use a C style ' 1830 'string instead: "static const char foo[]".' 1831 ' [runtime/string] [4]') 1832 self.assert_lint('string Foo::bar;', 1833 'For a static/global string constant, use a C style ' 1834 'string instead: "char Foo::bar[]".' 1835 ' [runtime/string] [4]') 1836 # Rare case. 1837 self.assert_lint('string foo("foobar");', 1838 'For a static/global string constant, use a C style ' 1839 'string instead: "char foo[]".' 1840 ' [runtime/string] [4]') 1841 # Should not catch local or member variables. 1842 self.assert_lint(' string foo', '') 1843 # Should not catch functions. 1844 self.assert_lint('string EmptyString() { return ""; }', '') 1845 self.assert_lint('string EmptyString () { return ""; }', '') 1846 self.assert_lint('string VeryLongNameFunctionSometimesEndsWith(\n' 1847 ' VeryLongNameType veryLongNameVariable) { }', '') 1848 self.assert_lint('template<>\n' 1849 'string FunctionTemplateSpecialization<SomeType>(\n' 1850 ' int x) { return ""; }', '') 1851 self.assert_lint('template<>\n' 1852 'string FunctionTemplateSpecialization<vector<A::B>* >(\n' 1853 ' int x) { return ""; }', '') 1854 1855 # should not catch methods of template classes. 1856 self.assert_lint('string Class<Type>::Method() const\n' 1857 '{\n' 1858 ' return "";\n' 1859 '}\n', '') 1860 self.assert_lint('string Class<Type>::Method(\n' 1861 ' int arg) const\n' 1862 '{\n' 1863 ' return "";\n' 1864 '}\n', '') 1865 1866 def test_no_spaces_in_function_calls(self): 1867 self.assert_lint('TellStory(1, 3);', 1868 '') 1869 self.assert_lint('TellStory(1, 3 );', 1870 'Extra space before )' 1871 ' [whitespace/parens] [2]') 1872 self.assert_lint('TellStory(1 /* wolf */, 3 /* pigs */);', 1873 '') 1874 self.assert_multi_line_lint('#endif\n );', 1875 '') 1876 1877 def test_one_spaces_between_code_and_comments(self): 1878 self.assert_lint('} // namespace foo', 1879 '') 1880 self.assert_lint('}// namespace foo', 1881 'One space before end of line comments' 1882 ' [whitespace/comments] [5]') 1883 self.assert_lint('printf("foo"); // Outside quotes.', 1884 '') 1885 self.assert_lint('int i = 0; // Having one space is fine.','') 1886 self.assert_lint('int i = 0; // Having two spaces is bad.', 1887 'One space before end of line comments' 1888 ' [whitespace/comments] [5]') 1889 self.assert_lint('int i = 0; // Having three spaces is bad.', 1890 'One space before end of line comments' 1891 ' [whitespace/comments] [5]') 1892 self.assert_lint('// Top level comment', '') 1893 self.assert_lint(' // Line starts with four spaces.', '') 1894 self.assert_lint('foo();\n' 1895 '{ // A scope is opening.', '') 1896 self.assert_lint(' foo();\n' 1897 ' { // An indented scope is opening.', '') 1898 self.assert_lint('if (foo) { // not a pure scope', 1899 '') 1900 self.assert_lint('printf("// In quotes.")', '') 1901 self.assert_lint('printf("\\"%s // In quotes.")', '') 1902 self.assert_lint('printf("%s", "// In quotes.")', '') 1903 1904 def test_one_spaces_after_punctuation_in_comments(self): 1905 self.assert_lint('int a; // This is a sentence.', 1906 '') 1907 self.assert_lint('int a; // This is a sentence. ', 1908 'Line ends in whitespace. Consider deleting these extra spaces. [whitespace/end_of_line] [4]') 1909 self.assert_lint('int a; // This is a sentence. This is a another sentence.', 1910 '') 1911 self.assert_lint('int a; // This is a sentence. This is a another sentence.', 1912 'Should have only a single space after a punctuation in a comment. [whitespace/comments] [5]') 1913 self.assert_lint('int a; // This is a sentence! This is a another sentence.', 1914 'Should have only a single space after a punctuation in a comment. [whitespace/comments] [5]') 1915 self.assert_lint('int a; // Why did I write this? This is a another sentence.', 1916 'Should have only a single space after a punctuation in a comment. [whitespace/comments] [5]') 1917 self.assert_lint('int a; // Elementary, my dear.', 1918 'Should have only a single space after a punctuation in a comment. [whitespace/comments] [5]') 1919 self.assert_lint('int a; // The following should be clear: Is it?', 1920 'Should have only a single space after a punctuation in a comment. [whitespace/comments] [5]') 1921 self.assert_lint('int a; // Look at the follow semicolon; I hope this gives an error.', 1922 'Should have only a single space after a punctuation in a comment. [whitespace/comments] [5]') 1923 1924 def test_space_after_comment_marker(self): 1925 self.assert_lint('//', '') 1926 self.assert_lint('//x', 'Should have a space between // and comment' 1927 ' [whitespace/comments] [4]') 1928 self.assert_lint('// x', '') 1929 self.assert_lint('//----', '') 1930 self.assert_lint('//====', '') 1931 self.assert_lint('//////', '') 1932 self.assert_lint('////// x', '') 1933 self.assert_lint('/// x', '') 1934 self.assert_lint('////x', 'Should have a space between // and comment' 1935 ' [whitespace/comments] [4]') 1936 1937 def test_newline_at_eof(self): 1938 def do_test(self, data, is_missing_eof): 1939 error_collector = ErrorCollector(self.assertTrue) 1940 self.process_file_data('foo.cpp', 'cpp', data.split('\n'), 1941 error_collector) 1942 # The warning appears only once. 1943 self.assertEqual( 1944 int(is_missing_eof), 1945 error_collector.results().count( 1946 'Could not find a newline character at the end of the file.' 1947 ' [whitespace/ending_newline] [5]')) 1948 1949 do_test(self, '// Newline\n// at EOF\n', False) 1950 do_test(self, '// No newline\n// at EOF', True) 1951 1952 def test_invalid_utf8(self): 1953 def do_test(self, raw_bytes, has_invalid_utf8): 1954 error_collector = ErrorCollector(self.assertTrue) 1955 self.process_file_data('foo.cpp', 'cpp', 1956 unicode(raw_bytes, 'utf8', 'replace').split('\n'), 1957 error_collector) 1958 # The warning appears only once. 1959 self.assertEqual( 1960 int(has_invalid_utf8), 1961 error_collector.results().count( 1962 'Line contains invalid UTF-8' 1963 ' (or Unicode replacement character).' 1964 ' [readability/utf8] [5]')) 1965 1966 do_test(self, 'Hello world\n', False) 1967 do_test(self, '\xe9\x8e\xbd\n', False) 1968 do_test(self, '\xe9x\x8e\xbd\n', True) 1969 # This is the encoding of the replacement character itself (which 1970 # you can see by evaluating codecs.getencoder('utf8')(u'\ufffd')). 1971 do_test(self, '\xef\xbf\xbd\n', True) 1972 1973 def test_is_blank_line(self): 1974 self.assertTrue(cpp_style.is_blank_line('')) 1975 self.assertTrue(cpp_style.is_blank_line(' ')) 1976 self.assertTrue(cpp_style.is_blank_line(' \t\r\n')) 1977 self.assertTrue(not cpp_style.is_blank_line('int a;')) 1978 self.assertTrue(not cpp_style.is_blank_line('{')) 1979 1980 def test_blank_lines_check(self): 1981 self.assert_blank_lines_check(['{\n', '\n', '\n', '}\n'], 1, 1) 1982 self.assert_blank_lines_check([' if (foo) {\n', '\n', ' }\n'], 1, 1) 1983 self.assert_blank_lines_check( 1984 ['\n', '// {\n', '\n', '\n', '// Comment\n', '{\n', '}\n'], 0, 0) 1985 self.assert_blank_lines_check(['\n', 'run("{");\n', '\n'], 0, 0) 1986 self.assert_blank_lines_check(['\n', ' if (foo) { return 0; }\n', '\n'], 0, 0) 1987 1988 def test_allow_blank_line_before_closing_namespace(self): 1989 error_collector = ErrorCollector(self.assertTrue) 1990 self.process_file_data('foo.cpp', 'cpp', 1991 ['namespace {', '', '} // namespace'], 1992 error_collector) 1993 self.assertEqual(0, error_collector.results().count( 1994 'Blank line at the end of a code block. Is this needed?' 1995 ' [whitespace/blank_line] [3]')) 1996 1997 def test_allow_blank_line_before_if_else_chain(self): 1998 error_collector = ErrorCollector(self.assertTrue) 1999 self.process_file_data('foo.cpp', 'cpp', 2000 ['if (hoge) {', 2001 '', # No warning 2002 '} else if (piyo) {', 2003 '', # No warning 2004 '} else if (piyopiyo) {', 2005 ' hoge = true;', # No warning 2006 '} else {', 2007 '', # Warning on this line 2008 '}'], 2009 error_collector) 2010 self.assertEqual(1, error_collector.results().count( 2011 'Blank line at the end of a code block. Is this needed?' 2012 ' [whitespace/blank_line] [3]')) 2013 2014 def test_else_on_same_line_as_closing_braces(self): 2015 error_collector = ErrorCollector(self.assertTrue) 2016 self.process_file_data('foo.cpp', 'cpp', 2017 ['if (hoge) {', 2018 '', 2019 '}', 2020 ' else {' # Warning on this line 2021 '', 2022 '}'], 2023 error_collector) 2024 self.assertEqual(1, error_collector.results().count( 2025 'An else should appear on the same line as the preceding }' 2026 ' [whitespace/newline] [4]')) 2027 2028 def test_else_clause_not_on_same_line_as_else(self): 2029 self.assert_lint(' else DoSomethingElse();', 2030 'Else clause should never be on same line as else ' 2031 '(use 2 lines) [whitespace/newline] [4]') 2032 self.assert_lint(' else ifDoSomethingElse();', 2033 'Else clause should never be on same line as else ' 2034 '(use 2 lines) [whitespace/newline] [4]') 2035 self.assert_lint(' else if (blah) {', '') 2036 self.assert_lint(' variable_ends_in_else = true;', '') 2037 2038 def test_comma(self): 2039 self.assert_lint('a = f(1,2);', 2040 'Missing space after , [whitespace/comma] [3]') 2041 self.assert_lint('int tmp=a,a=b,b=tmp;', 2042 ['Missing spaces around = [whitespace/operators] [4]', 2043 'Missing space after , [whitespace/comma] [3]']) 2044 self.assert_lint('f(a, /* name */ b);', '') 2045 self.assert_lint('f(a, /* name */b);', '') 2046 2047 def test_declaration(self): 2048 self.assert_lint('int a;', '') 2049 self.assert_lint('int a;', 'Extra space between int and a [whitespace/declaration] [3]') 2050 self.assert_lint('int* a;', 'Extra space between int* and a [whitespace/declaration] [3]') 2051 self.assert_lint('else if { }', '') 2052 self.assert_lint('else if { }', 'Extra space between else and if [whitespace/declaration] [3]') 2053 2054 def test_pointer_reference_marker_location(self): 2055 self.assert_lint('int* b;', '', 'foo.cpp') 2056 self.assert_lint('int *b;', 2057 'Declaration has space between type name and * in int *b [whitespace/declaration] [3]', 2058 'foo.cpp') 2059 self.assert_lint('return *b;', '', 'foo.cpp') 2060 self.assert_lint('delete *b;', '', 'foo.cpp') 2061 self.assert_lint('int *b;', '', 'foo.c') 2062 self.assert_lint('int* b;', 2063 'Declaration has space between * and variable name in int* b [whitespace/declaration] [3]', 2064 'foo.c') 2065 self.assert_lint('int& b;', '', 'foo.cpp') 2066 self.assert_lint('int &b;', 2067 'Declaration has space between type name and & in int &b [whitespace/declaration] [3]', 2068 'foo.cpp') 2069 self.assert_lint('return &b;', '', 'foo.cpp') 2070 2071 def test_indent(self): 2072 self.assert_lint('static int noindent;', '') 2073 self.assert_lint(' int fourSpaceIndent;', '') 2074 self.assert_lint(' int oneSpaceIndent;', 2075 'Weird number of spaces at line-start. ' 2076 'Are you using a 4-space indent? [whitespace/indent] [3]') 2077 self.assert_lint(' int threeSpaceIndent;', 2078 'Weird number of spaces at line-start. ' 2079 'Are you using a 4-space indent? [whitespace/indent] [3]') 2080 self.assert_lint(' char* oneSpaceIndent = "public:";', 2081 'Weird number of spaces at line-start. ' 2082 'Are you using a 4-space indent? [whitespace/indent] [3]') 2083 self.assert_lint(' public:', 2084 'Weird number of spaces at line-start. ' 2085 'Are you using a 4-space indent? [whitespace/indent] [3]') 2086 self.assert_lint(' public:', 2087 'Weird number of spaces at line-start. ' 2088 'Are you using a 4-space indent? [whitespace/indent] [3]') 2089 self.assert_lint(' public:', 2090 'Weird number of spaces at line-start. ' 2091 'Are you using a 4-space indent? [whitespace/indent] [3]') 2092 self.assert_multi_line_lint( 2093 'class Foo {\n' 2094 'public:\n' 2095 ' enum Bar {\n' 2096 ' Alpha,\n' 2097 ' Beta,\n' 2098 '#if ENABLED_BETZ\n' 2099 ' Charlie,\n' 2100 '#endif\n' 2101 ' };\n' 2102 '};', 2103 '') 2104 self.assert_multi_line_lint( 2105 'if (true) {\n' 2106 ' myFunction(reallyLongParam1, reallyLongParam2,\n' 2107 ' reallyLongParam3);\n' 2108 '}\n', 2109 'Weird number of spaces at line-start. Are you using a 4-space indent? [whitespace/indent] [3]') 2110 2111 self.assert_multi_line_lint( 2112 'if (true) {\n' 2113 ' myFunction(reallyLongParam1, reallyLongParam2,\n' 2114 ' reallyLongParam3);\n' 2115 '}\n', 2116 'When wrapping a line, only indent 4 spaces. [whitespace/indent] [3]') 2117 2118 2119 def test_not_alabel(self): 2120 self.assert_lint('MyVeryLongNamespace::MyVeryLongClassName::', '') 2121 2122 def test_tab(self): 2123 self.assert_lint('\tint a;', 2124 'Tab found; better to use spaces [whitespace/tab] [1]') 2125 self.assert_lint('int a = 5;\t// set a to 5', 2126 'Tab found; better to use spaces [whitespace/tab] [1]') 2127 2128 def test_unnamed_namespaces_in_headers(self): 2129 self.assert_language_rules_check( 2130 'foo.h', 'namespace {', 2131 'Do not use unnamed namespaces in header files. See' 2132 ' http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Namespaces' 2133 ' for more information. [build/namespaces] [4]') 2134 # namespace registration macros are OK. 2135 self.assert_language_rules_check('foo.h', 'namespace { \\', '') 2136 # named namespaces are OK. 2137 self.assert_language_rules_check('foo.h', 'namespace foo {', '') 2138 self.assert_language_rules_check('foo.h', 'namespace foonamespace {', '') 2139 self.assert_language_rules_check('foo.cpp', 'namespace {', '') 2140 self.assert_language_rules_check('foo.cpp', 'namespace foo {', '') 2141 2142 def test_build_class(self): 2143 # Test that the linter can parse to the end of class definitions, 2144 # and that it will report when it can't. 2145 # Use multi-line linter because it performs the ClassState check. 2146 self.assert_multi_line_lint( 2147 'class Foo {', 2148 'Failed to find complete declaration of class Foo' 2149 ' [build/class] [5]') 2150 # Don't warn on forward declarations of various types. 2151 self.assert_multi_line_lint( 2152 'class Foo;', 2153 '') 2154 self.assert_multi_line_lint( 2155 '''\ 2156 struct Foo* 2157 foo = NewFoo();''', 2158 '') 2159 # Here is an example where the linter gets confused, even though 2160 # the code doesn't violate the style guide. 2161 self.assert_multi_line_lint( 2162 'class Foo\n' 2163 '#ifdef DERIVE_FROM_GOO\n' 2164 ' : public Goo {\n' 2165 '#else\n' 2166 ' : public Hoo {\n' 2167 '#endif\n' 2168 '};', 2169 'Failed to find complete declaration of class Foo' 2170 ' [build/class] [5]') 2171 2172 def test_build_end_comment(self): 2173 # The crosstool compiler we currently use will fail to compile the 2174 # code in this test, so we might consider removing the lint check. 2175 self.assert_lint('#endif Not a comment', 2176 'Uncommented text after #endif is non-standard.' 2177 ' Use a comment.' 2178 ' [build/endif_comment] [5]') 2179 2180 def test_build_forward_decl(self): 2181 # The crosstool compiler we currently use will fail to compile the 2182 # code in this test, so we might consider removing the lint check. 2183 self.assert_lint('class Foo::Goo;', 2184 'Inner-style forward declarations are invalid.' 2185 ' Remove this line.' 2186 ' [build/forward_decl] [5]') 2187 2188 def test_build_header_guard(self): 2189 file_path = 'mydir/Foo.h' 2190 2191 # We can't rely on our internal stuff to get a sane path on the open source 2192 # side of things, so just parse out the suggested header guard. This 2193 # doesn't allow us to test the suggested header guard, but it does let us 2194 # test all the other header tests. 2195 error_collector = ErrorCollector(self.assertTrue) 2196 self.process_file_data(file_path, 'h', [], error_collector) 2197 expected_guard = '' 2198 matcher = re.compile( 2199 'No \#ifndef header guard found\, suggested CPP variable is\: ([A-Za-z_0-9]+) ') 2200 for error in error_collector.result_list(): 2201 matches = matcher.match(error) 2202 if matches: 2203 expected_guard = matches.group(1) 2204 break 2205 2206 # Make sure we extracted something for our header guard. 2207 self.assertNotEqual(expected_guard, '') 2208 2209 # Wrong guard 2210 error_collector = ErrorCollector(self.assertTrue) 2211 self.process_file_data(file_path, 'h', 2212 ['#ifndef FOO_H', '#define FOO_H'], error_collector) 2213 self.assertEqual( 2214 1, 2215 error_collector.result_list().count( 2216 '#ifndef header guard has wrong style, please use: %s' 2217 ' [build/header_guard] [5]' % expected_guard), 2218 error_collector.result_list()) 2219 2220 # No define 2221 error_collector = ErrorCollector(self.assertTrue) 2222 self.process_file_data(file_path, 'h', 2223 ['#ifndef %s' % expected_guard], error_collector) 2224 self.assertEqual( 2225 1, 2226 error_collector.result_list().count( 2227 'No #ifndef header guard found, suggested CPP variable is: %s' 2228 ' [build/header_guard] [5]' % expected_guard), 2229 error_collector.result_list()) 2230 2231 # Mismatched define 2232 error_collector = ErrorCollector(self.assertTrue) 2233 self.process_file_data(file_path, 'h', 2234 ['#ifndef %s' % expected_guard, 2235 '#define FOO_H'], 2236 error_collector) 2237 self.assertEqual( 2238 1, 2239 error_collector.result_list().count( 2240 'No #ifndef header guard found, suggested CPP variable is: %s' 2241 ' [build/header_guard] [5]' % expected_guard), 2242 error_collector.result_list()) 2243 2244 # No header guard errors 2245 error_collector = ErrorCollector(self.assertTrue) 2246 self.process_file_data(file_path, 'h', 2247 ['#ifndef %s' % expected_guard, 2248 '#define %s' % expected_guard, 2249 '#endif // %s' % expected_guard], 2250 error_collector) 2251 for line in error_collector.result_list(): 2252 if line.find('build/header_guard') != -1: 2253 self.fail('Unexpected error: %s' % line) 2254 2255 # Completely incorrect header guard 2256 error_collector = ErrorCollector(self.assertTrue) 2257 self.process_file_data(file_path, 'h', 2258 ['#ifndef FOO', 2259 '#define FOO', 2260 '#endif // FOO'], 2261 error_collector) 2262 self.assertEqual( 2263 1, 2264 error_collector.result_list().count( 2265 '#ifndef header guard has wrong style, please use: %s' 2266 ' [build/header_guard] [5]' % expected_guard), 2267 error_collector.result_list()) 2268 2269 # Special case for flymake 2270 error_collector = ErrorCollector(self.assertTrue) 2271 self.process_file_data('mydir/Foo_flymake.h', 'h', 2272 ['#ifndef %s' % expected_guard, 2273 '#define %s' % expected_guard, 2274 '#endif // %s' % expected_guard], 2275 error_collector) 2276 for line in error_collector.result_list(): 2277 if line.find('build/header_guard') != -1: 2278 self.fail('Unexpected error: %s' % line) 2279 2280 error_collector = ErrorCollector(self.assertTrue) 2281 self.process_file_data('mydir/Foo_flymake.h', 'h', [], error_collector) 2282 self.assertEqual( 2283 1, 2284 error_collector.result_list().count( 2285 'No #ifndef header guard found, suggested CPP variable is: %s' 2286 ' [build/header_guard] [5]' % expected_guard), 2287 error_collector.result_list()) 2288 2289 # Verify that we don't blindly suggest the WTF prefix for all headers. 2290 self.assertFalse(expected_guard.startswith('WTF_')) 2291 2292 # Allow the WTF_ prefix for files in that directory. 2293 header_guard_filter = FilterConfiguration(('-', '+build/header_guard')) 2294 error_collector = ErrorCollector(self.assertTrue, header_guard_filter) 2295 self.process_file_data('Source/JavaScriptCore/wtf/TestName.h', 'h', 2296 ['#ifndef WTF_TestName_h', '#define WTF_TestName_h'], 2297 error_collector) 2298 self.assertEqual(0, len(error_collector.result_list()), 2299 error_collector.result_list()) 2300 2301 # Also allow the non WTF_ prefix for files in that directory. 2302 error_collector = ErrorCollector(self.assertTrue, header_guard_filter) 2303 self.process_file_data('Source/JavaScriptCore/wtf/TestName.h', 'h', 2304 ['#ifndef TestName_h', '#define TestName_h'], 2305 error_collector) 2306 self.assertEqual(0, len(error_collector.result_list()), 2307 error_collector.result_list()) 2308 2309 # Verify that we suggest the WTF prefix version. 2310 error_collector = ErrorCollector(self.assertTrue, header_guard_filter) 2311 self.process_file_data('Source/JavaScriptCore/wtf/TestName.h', 'h', 2312 ['#ifndef BAD_TestName_h', '#define BAD_TestName_h'], 2313 error_collector) 2314 self.assertEqual( 2315 1, 2316 error_collector.result_list().count( 2317 '#ifndef header guard has wrong style, please use: WTF_TestName_h' 2318 ' [build/header_guard] [5]'), 2319 error_collector.result_list()) 2320 2321 # Verify that the Chromium-style header guard is allowed as well. 2322 error_collector = ErrorCollector(self.assertTrue, header_guard_filter) 2323 self.process_file_data('Source/foo/testname.h', 'h', 2324 ['#ifndef BLINK_FOO_TESTNAME_H_', 2325 '#define BLINK_FOO_TESTNAME_H_'], 2326 error_collector) 2327 self.assertEqual(0, len(error_collector.result_list()), 2328 error_collector.result_list()) 2329 2330 def test_build_printf_format(self): 2331 self.assert_lint( 2332 r'printf("\%%d", value);', 2333 '%, [, (, and { are undefined character escapes. Unescape them.' 2334 ' [build/printf_format] [3]') 2335 2336 self.assert_lint( 2337 r'snprintf(buffer, sizeof(buffer), "\[%d", value);', 2338 '%, [, (, and { are undefined character escapes. Unescape them.' 2339 ' [build/printf_format] [3]') 2340 2341 self.assert_lint( 2342 r'fprintf(file, "\(%d", value);', 2343 '%, [, (, and { are undefined character escapes. Unescape them.' 2344 ' [build/printf_format] [3]') 2345 2346 self.assert_lint( 2347 r'vsnprintf(buffer, sizeof(buffer), "\\\{%d", ap);', 2348 '%, [, (, and { are undefined character escapes. Unescape them.' 2349 ' [build/printf_format] [3]') 2350 2351 # Don't warn if double-slash precedes the symbol 2352 self.assert_lint(r'printf("\\%%%d", value);', 2353 '') 2354 2355 def test_runtime_printf_format(self): 2356 self.assert_lint( 2357 r'fprintf(file, "%q", value);', 2358 '%q in format strings is deprecated. Use %ll instead.' 2359 ' [runtime/printf_format] [3]') 2360 2361 self.assert_lint( 2362 r'aprintf(file, "The number is %12q", value);', 2363 '%q in format strings is deprecated. Use %ll instead.' 2364 ' [runtime/printf_format] [3]') 2365 2366 self.assert_lint( 2367 r'printf(file, "The number is" "%-12q", value);', 2368 '%q in format strings is deprecated. Use %ll instead.' 2369 ' [runtime/printf_format] [3]') 2370 2371 self.assert_lint( 2372 r'printf(file, "The number is" "%+12q", value);', 2373 '%q in format strings is deprecated. Use %ll instead.' 2374 ' [runtime/printf_format] [3]') 2375 2376 self.assert_lint( 2377 r'printf(file, "The number is" "% 12q", value);', 2378 '%q in format strings is deprecated. Use %ll instead.' 2379 ' [runtime/printf_format] [3]') 2380 2381 self.assert_lint( 2382 r'snprintf(file, "Never mix %d and %1$d parmaeters!", value);', 2383 '%N$ formats are unconventional. Try rewriting to avoid them.' 2384 ' [runtime/printf_format] [2]') 2385 2386 def assert_lintLogCodeOnError(self, code, expected_message): 2387 # Special assert_lint which logs the input code on error. 2388 result = self.perform_single_line_lint(code, 'foo.cpp') 2389 if result != expected_message: 2390 self.fail('For code: "%s"\nGot: "%s"\nExpected: "%s"' 2391 % (code, result, expected_message)) 2392 2393 def test_build_storage_class(self): 2394 qualifiers = [None, 'const', 'volatile'] 2395 signs = [None, 'signed', 'unsigned'] 2396 types = ['void', 'char', 'int', 'float', 'double', 2397 'schar', 'int8', 'uint8', 'int16', 'uint16', 2398 'int32', 'uint32', 'int64', 'uint64'] 2399 storage_classes = ['auto', 'extern', 'register', 'static', 'typedef'] 2400 2401 build_storage_class_error_message = ( 2402 'Storage class (static, extern, typedef, etc) should be first.' 2403 ' [build/storage_class] [5]') 2404 2405 # Some explicit cases. Legal in C++, deprecated in C99. 2406 self.assert_lint('const int static foo = 5;', 2407 build_storage_class_error_message) 2408 2409 self.assert_lint('char static foo;', 2410 build_storage_class_error_message) 2411 2412 self.assert_lint('double const static foo = 2.0;', 2413 build_storage_class_error_message) 2414 2415 self.assert_lint('uint64 typedef unsignedLongLong;', 2416 build_storage_class_error_message) 2417 2418 self.assert_lint('int register foo = 0;', 2419 build_storage_class_error_message) 2420 2421 # Since there are a very large number of possibilities, randomly 2422 # construct declarations. 2423 # Make sure that the declaration is logged if there's an error. 2424 # Seed generator with an integer for absolute reproducibility. 2425 random.seed(25) 2426 for unused_i in range(10): 2427 # Build up random list of non-storage-class declaration specs. 2428 other_decl_specs = [random.choice(qualifiers), random.choice(signs), 2429 random.choice(types)] 2430 # remove None 2431 other_decl_specs = filter(lambda x: x is not None, other_decl_specs) 2432 2433 # shuffle 2434 random.shuffle(other_decl_specs) 2435 2436 # insert storage class after the first 2437 storage_class = random.choice(storage_classes) 2438 insertion_point = random.randint(1, len(other_decl_specs)) 2439 decl_specs = (other_decl_specs[0:insertion_point] 2440 + [storage_class] 2441 + other_decl_specs[insertion_point:]) 2442 2443 self.assert_lintLogCodeOnError( 2444 ' '.join(decl_specs) + ';', 2445 build_storage_class_error_message) 2446 2447 # but no error if storage class is first 2448 self.assert_lintLogCodeOnError( 2449 storage_class + ' ' + ' '.join(other_decl_specs), 2450 '') 2451 2452 def test_legal_copyright(self): 2453 legal_copyright_message = ( 2454 'No copyright message found. ' 2455 'You should have a line: "Copyright [year] <Copyright Owner>"' 2456 ' [legal/copyright] [5]') 2457 2458 copyright_line = '// Copyright 2008 Google Inc. All Rights Reserved.' 2459 2460 file_path = 'mydir/googleclient/foo.cpp' 2461 2462 # There should be a copyright message in the first 10 lines 2463 error_collector = ErrorCollector(self.assertTrue) 2464 self.process_file_data(file_path, 'cpp', [], error_collector) 2465 self.assertEqual( 2466 1, 2467 error_collector.result_list().count(legal_copyright_message)) 2468 2469 error_collector = ErrorCollector(self.assertTrue) 2470 self.process_file_data( 2471 file_path, 'cpp', 2472 ['' for unused_i in range(10)] + [copyright_line], 2473 error_collector) 2474 self.assertEqual( 2475 1, 2476 error_collector.result_list().count(legal_copyright_message)) 2477 2478 # Test that warning isn't issued if Copyright line appears early enough. 2479 error_collector = ErrorCollector(self.assertTrue) 2480 self.process_file_data(file_path, 'cpp', [copyright_line], error_collector) 2481 for message in error_collector.result_list(): 2482 if message.find('legal/copyright') != -1: 2483 self.fail('Unexpected error: %s' % message) 2484 2485 error_collector = ErrorCollector(self.assertTrue) 2486 self.process_file_data( 2487 file_path, 'cpp', 2488 ['' for unused_i in range(9)] + [copyright_line], 2489 error_collector) 2490 for message in error_collector.result_list(): 2491 if message.find('legal/copyright') != -1: 2492 self.fail('Unexpected error: %s' % message) 2493 2494 def test_invalid_increment(self): 2495 self.assert_lint('*count++;', 2496 'Changing pointer instead of value (or unused value of ' 2497 'operator*). [runtime/invalid_increment] [5]') 2498 2499 # Integral bitfields must be declared with either signed or unsigned keyword. 2500 def test_plain_integral_bitfields(self): 2501 errmsg = ('Please declare integral type bitfields with either signed or unsigned. [runtime/bitfields] [5]') 2502 2503 self.assert_lint('int a : 30;', errmsg) 2504 self.assert_lint('mutable short a : 14;', errmsg) 2505 self.assert_lint('const char a : 6;', errmsg) 2506 self.assert_lint('long int a : 30;', errmsg) 2507 self.assert_lint('int a = 1 ? 0 : 30;', '') 2508 2509 # A mixture of unsigned and bool bitfields in a class will generate a warning. 2510 def test_mixing_unsigned_bool_bitfields(self): 2511 def errmsg(bool_bitfields, unsigned_bitfields, name): 2512 bool_list = ', '.join(bool_bitfields) 2513 unsigned_list = ', '.join(unsigned_bitfields) 2514 return ('The class %s contains mixed unsigned and bool bitfields, ' 2515 'which will pack into separate words on the MSVC compiler.\n' 2516 'Bool bitfields are [%s].\nUnsigned bitfields are [%s].\n' 2517 'Consider converting bool bitfields to unsigned. [runtime/bitfields] [5]' 2518 % (name, bool_list, unsigned_list)) 2519 2520 def build_test_case(bitfields, name, will_warn, extra_warnings=[]): 2521 bool_bitfields = [] 2522 unsigned_bitfields = [] 2523 test_string = 'class %s {\n' % (name,) 2524 line = 2 2525 for bitfield in bitfields: 2526 test_string += ' %s %s : %d;\n' % bitfield 2527 if bitfield[0] == 'bool': 2528 bool_bitfields.append('%d: %s' % (line, bitfield[1])) 2529 elif bitfield[0].startswith('unsigned'): 2530 unsigned_bitfields.append('%d: %s' % (line, bitfield[1])) 2531 line += 1 2532 test_string += '}\n' 2533 error = '' 2534 if will_warn: 2535 error = errmsg(bool_bitfields, unsigned_bitfields, name) 2536 if extra_warnings and error: 2537 error = extra_warnings + [error] 2538 self.assert_multi_line_lint(test_string, error) 2539 2540 build_test_case([('bool', 'm_boolMember', 4), ('unsigned', 'm_unsignedMember', 3)], 2541 'MyClass', True) 2542 build_test_case([('bool', 'm_boolMember', 4), ('bool', 'm_anotherBool', 3)], 2543 'MyClass', False) 2544 build_test_case([('unsigned', 'm_unsignedMember', 4), ('unsigned', 'm_anotherUnsigned', 3)], 2545 'MyClass', False) 2546 2547 build_test_case([('bool', 'm_boolMember', 4), ('bool', 'm_anotherbool', 3), 2548 ('bool', 'm_moreBool', 1), ('bool', 'm_lastBool', 1), 2549 ('unsigned int', 'm_tokenUnsigned', 4)], 2550 'MyClass', True, ['Omit int when using unsigned [runtime/unsigned] [1]']) 2551 2552 self.assert_multi_line_lint('class NoProblemsHere {\n' 2553 ' bool m_boolMember;\n' 2554 ' unsigned m_unsignedMember;\n' 2555 ' unsigned m_bitField1 : 1;\n' 2556 ' unsigned m_bitField4 : 4;\n' 2557 '}\n', '') 2558 2559 # Bitfields which are not declared unsigned or bool will generate a warning. 2560 def test_unsigned_bool_bitfields(self): 2561 def errmsg(member, name, bit_type): 2562 return ('Member %s of class %s defined as a bitfield of type %s. ' 2563 'Please declare all bitfields as unsigned. [runtime/bitfields] [4]' 2564 % (member, name, bit_type)) 2565 2566 def warning_bitfield_test(member, name, bit_type, bits): 2567 self.assert_multi_line_lint('class %s {\n%s %s: %d;\n}\n' 2568 % (name, bit_type, member, bits), 2569 errmsg(member, name, bit_type)) 2570 2571 def safe_bitfield_test(member, name, bit_type, bits): 2572 self.assert_multi_line_lint('class %s {\n%s %s: %d;\n}\n' 2573 % (name, bit_type, member, bits), 2574 '') 2575 2576 warning_bitfield_test('a', 'A', 'int32_t', 25) 2577 warning_bitfield_test('m_someField', 'SomeClass', 'signed', 4) 2578 warning_bitfield_test('m_someField', 'SomeClass', 'SomeEnum', 2) 2579 2580 safe_bitfield_test('a', 'A', 'unsigned', 22) 2581 safe_bitfield_test('m_someField', 'SomeClass', 'bool', 1) 2582 safe_bitfield_test('m_someField', 'SomeClass', 'unsigned', 2) 2583 2584 # Declarations in 'Expected' or 'SameSizeAs' classes are OK. 2585 warning_bitfield_test('m_bitfields', 'SomeClass', 'int32_t', 32) 2586 safe_bitfield_test('m_bitfields', 'ExpectedSomeClass', 'int32_t', 32) 2587 safe_bitfield_test('m_bitfields', 'SameSizeAsSomeClass', 'int32_t', 32) 2588 2589 class CleansedLinesTest(unittest.TestCase): 2590 def test_init(self): 2591 lines = ['Line 1', 2592 'Line 2', 2593 'Line 3 // Comment test', 2594 'Line 4 "foo"'] 2595 2596 clean_lines = cpp_style.CleansedLines(lines) 2597 self.assertEqual(lines, clean_lines.raw_lines) 2598 self.assertEqual(4, clean_lines.num_lines()) 2599 2600 self.assertEqual(['Line 1', 2601 'Line 2', 2602 'Line 3 ', 2603 'Line 4 "foo"'], 2604 clean_lines.lines) 2605 2606 self.assertEqual(['Line 1', 2607 'Line 2', 2608 'Line 3 ', 2609 'Line 4 ""'], 2610 clean_lines.elided) 2611 2612 def test_init_empty(self): 2613 clean_lines = cpp_style.CleansedLines([]) 2614 self.assertEqual([], clean_lines.raw_lines) 2615 self.assertEqual(0, clean_lines.num_lines()) 2616 2617 def test_collapse_strings(self): 2618 collapse = cpp_style.CleansedLines.collapse_strings 2619 self.assertEqual('""', collapse('""')) # "" (empty) 2620 self.assertEqual('"""', collapse('"""')) # """ (bad) 2621 self.assertEqual('""', collapse('"xyz"')) # "xyz" (string) 2622 self.assertEqual('""', collapse('"\\\""')) # "\"" (string) 2623 self.assertEqual('""', collapse('"\'"')) # "'" (string) 2624 self.assertEqual('"\"', collapse('"\"')) # "\" (bad) 2625 self.assertEqual('""', collapse('"\\\\"')) # "\\" (string) 2626 self.assertEqual('"', collapse('"\\\\\\"')) # "\\\" (bad) 2627 self.assertEqual('""', collapse('"\\\\\\\\"')) # "\\\\" (string) 2628 2629 self.assertEqual('\'\'', collapse('\'\'')) # '' (empty) 2630 self.assertEqual('\'\'', collapse('\'a\'')) # 'a' (char) 2631 self.assertEqual('\'\'', collapse('\'\\\'\'')) # '\'' (char) 2632 self.assertEqual('\'', collapse('\'\\\'')) # '\' (bad) 2633 self.assertEqual('', collapse('\\012')) # '\012' (char) 2634 self.assertEqual('', collapse('\\xfF0')) # '\xfF0' (char) 2635 self.assertEqual('', collapse('\\n')) # '\n' (char) 2636 self.assertEqual('\#', collapse('\\#')) # '\#' (bad) 2637 2638 self.assertEqual('StringReplace(body, "", "");', 2639 collapse('StringReplace(body, "\\\\", "\\\\\\\\");')) 2640 self.assertEqual('\'\' ""', 2641 collapse('\'"\' "foo"')) 2642 2643 2644 class OrderOfIncludesTest(CppStyleTestBase): 2645 def setUp(self): 2646 self.include_state = cpp_style._IncludeState() 2647 2648 # Cheat os.path.abspath called in FileInfo class. 2649 self.os_path_abspath_orig = os.path.abspath 2650 os.path.abspath = lambda value: value 2651 2652 def tearDown(self): 2653 os.path.abspath = self.os_path_abspath_orig 2654 2655 def test_try_drop_common_suffixes(self): 2656 self.assertEqual('foo/foo', cpp_style._drop_common_suffixes('foo/foo-inl.h')) 2657 self.assertEqual('foo/bar/foo', 2658 cpp_style._drop_common_suffixes('foo/bar/foo_inl.h')) 2659 self.assertEqual('foo/foo', cpp_style._drop_common_suffixes('foo/foo.cpp')) 2660 self.assertEqual('foo/foo_unusualinternal', 2661 cpp_style._drop_common_suffixes('foo/foo_unusualinternal.h')) 2662 self.assertEqual('', 2663 cpp_style._drop_common_suffixes('_test.cpp')) 2664 self.assertEqual('test', 2665 cpp_style._drop_common_suffixes('test.cpp')) 2666 2667 2668 class OrderOfIncludesTest(CppStyleTestBase): 2669 def setUp(self): 2670 self.include_state = cpp_style._IncludeState() 2671 2672 # Cheat os.path.abspath called in FileInfo class. 2673 self.os_path_abspath_orig = os.path.abspath 2674 self.os_path_isfile_orig = os.path.isfile 2675 os.path.abspath = lambda value: value 2676 2677 def tearDown(self): 2678 os.path.abspath = self.os_path_abspath_orig 2679 os.path.isfile = self.os_path_isfile_orig 2680 2681 def test_check_next_include_order__no_config(self): 2682 self.assertEqual('Header file should not contain WebCore config.h.', 2683 self.include_state.check_next_include_order(cpp_style._CONFIG_HEADER, True, True)) 2684 2685 def test_check_next_include_order__no_self(self): 2686 self.assertEqual('Header file should not contain itself.', 2687 self.include_state.check_next_include_order(cpp_style._PRIMARY_HEADER, True, True)) 2688 # Test actual code to make sure that header types are correctly assigned. 2689 self.assert_language_rules_check('Foo.h', 2690 '#include "Foo.h"\n', 2691 'Header file should not contain itself. Should be: alphabetically sorted.' 2692 ' [build/include_order] [4]') 2693 self.assert_language_rules_check('FooBar.h', 2694 '#include "Foo.h"\n', 2695 '') 2696 2697 def test_check_next_include_order__likely_then_config(self): 2698 self.assertEqual('Found header this file implements before WebCore config.h.', 2699 self.include_state.check_next_include_order(cpp_style._PRIMARY_HEADER, False, True)) 2700 self.assertEqual('Found WebCore config.h after a header this file implements.', 2701 self.include_state.check_next_include_order(cpp_style._CONFIG_HEADER, False, True)) 2702 2703 def test_check_next_include_order__other_then_config(self): 2704 self.assertEqual('Found other header before WebCore config.h.', 2705 self.include_state.check_next_include_order(cpp_style._OTHER_HEADER, False, True)) 2706 self.assertEqual('Found WebCore config.h after other header.', 2707 self.include_state.check_next_include_order(cpp_style._CONFIG_HEADER, False, True)) 2708 2709 def test_check_next_include_order__config_then_other_then_likely(self): 2710 self.assertEqual('', self.include_state.check_next_include_order(cpp_style._CONFIG_HEADER, False, True)) 2711 self.assertEqual('Found other header before a header this file implements.', 2712 self.include_state.check_next_include_order(cpp_style._OTHER_HEADER, False, True)) 2713 self.assertEqual('Found header this file implements after other header.', 2714 self.include_state.check_next_include_order(cpp_style._PRIMARY_HEADER, False, True)) 2715 2716 def test_check_alphabetical_include_order(self): 2717 self.assert_language_rules_check('foo.h', 2718 '#include "a.h"\n' 2719 '#include "c.h"\n' 2720 '#include "b.h"\n', 2721 'Alphabetical sorting problem. [build/include_order] [4]') 2722 2723 self.assert_language_rules_check('foo.h', 2724 '#include "a.h"\n' 2725 '#include "b.h"\n' 2726 '#include "c.h"\n', 2727 '') 2728 2729 self.assert_language_rules_check('foo.h', 2730 '#include <assert.h>\n' 2731 '#include "bar.h"\n', 2732 'Alphabetical sorting problem. [build/include_order] [4]') 2733 2734 self.assert_language_rules_check('foo.h', 2735 '#include "bar.h"\n' 2736 '#include <assert.h>\n', 2737 '') 2738 2739 def test_check_alphabetical_include_order_errors_reported_for_both_lines(self): 2740 # If one of the two lines of out of order headers are filtered, the error should be 2741 # reported on the other line. 2742 self.assert_language_rules_check('foo.h', 2743 '#include "a.h"\n' 2744 '#include "c.h"\n' 2745 '#include "b.h"\n', 2746 'Alphabetical sorting problem. [build/include_order] [4]', 2747 lines_to_check=[2]) 2748 2749 self.assert_language_rules_check('foo.h', 2750 '#include "a.h"\n' 2751 '#include "c.h"\n' 2752 '#include "b.h"\n', 2753 'Alphabetical sorting problem. [build/include_order] [4]', 2754 lines_to_check=[3]) 2755 2756 # If no lines are filtered, the error should be reported only once. 2757 self.assert_language_rules_check('foo.h', 2758 '#include "a.h"\n' 2759 '#include "c.h"\n' 2760 '#include "b.h"\n', 2761 'Alphabetical sorting problem. [build/include_order] [4]') 2762 2763 def test_check_line_break_after_own_header(self): 2764 self.assert_language_rules_check('foo.cpp', 2765 '#include "config.h"\n' 2766 '#include "foo.h"\n' 2767 '#include "bar.h"\n', 2768 'You should add a blank line after implementation file\'s own header. [build/include_order] [4]') 2769 2770 self.assert_language_rules_check('foo.cpp', 2771 '#include "config.h"\n' 2772 '#include "foo.h"\n' 2773 '\n' 2774 '#include "bar.h"\n', 2775 '') 2776 2777 def test_check_preprocessor_in_include_section(self): 2778 self.assert_language_rules_check('foo.cpp', 2779 '#include "config.h"\n' 2780 '#include "foo.h"\n' 2781 '\n' 2782 '#ifdef BAZ\n' 2783 '#include "baz.h"\n' 2784 '#else\n' 2785 '#include "foobar.h"\n' 2786 '#endif"\n' 2787 '#include "bar.h"\n', # No flag because previous is in preprocessor section 2788 '') 2789 2790 self.assert_language_rules_check('foo.cpp', 2791 '#include "config.h"\n' 2792 '#include "foo.h"\n' 2793 '\n' 2794 '#ifdef BAZ\n' 2795 '#include "baz.h"\n' 2796 '#endif"\n' 2797 '#include "bar.h"\n' 2798 '#include "a.h"\n', # Should still flag this. 2799 'Alphabetical sorting problem. [build/include_order] [4]') 2800 2801 self.assert_language_rules_check('foo.cpp', 2802 '#include "config.h"\n' 2803 '#include "foo.h"\n' 2804 '\n' 2805 '#ifdef BAZ\n' 2806 '#include "baz.h"\n' 2807 '#include "bar.h"\n' #Should still flag this 2808 '#endif"\n', 2809 'Alphabetical sorting problem. [build/include_order] [4]') 2810 2811 self.assert_language_rules_check('foo.cpp', 2812 '#include "config.h"\n' 2813 '#include "foo.h"\n' 2814 '\n' 2815 '#ifdef BAZ\n' 2816 '#include "baz.h"\n' 2817 '#endif"\n' 2818 '#ifdef FOOBAR\n' 2819 '#include "foobar.h"\n' 2820 '#endif"\n' 2821 '#include "bar.h"\n' 2822 '#include "a.h"\n', # Should still flag this. 2823 'Alphabetical sorting problem. [build/include_order] [4]') 2824 2825 # Check that after an already included error, the sorting rules still work. 2826 self.assert_language_rules_check('foo.cpp', 2827 '#include "config.h"\n' 2828 '#include "foo.h"\n' 2829 '\n' 2830 '#include "foo.h"\n' 2831 '#include "g.h"\n', 2832 '"foo.h" already included at foo.cpp:2 [build/include] [4]') 2833 2834 def test_primary_header(self): 2835 # File with non-existing primary header should not produce errors. 2836 self.assert_language_rules_check('foo.cpp', 2837 '#include "config.h"\n' 2838 '\n' 2839 '#include "bar.h"\n', 2840 '') 2841 # Pretend that header files exist. 2842 os.path.isfile = lambda filename: True 2843 # Missing include for existing primary header -> error. 2844 self.assert_language_rules_check('foo.cpp', 2845 '#include "config.h"\n' 2846 '\n' 2847 '#include "bar.h"\n', 2848 'Found other header before a header this file implements. ' 2849 'Should be: config.h, primary header, blank line, and then ' 2850 'alphabetically sorted. [build/include_order] [4]') 2851 # Having include for existing primary header -> no error. 2852 self.assert_language_rules_check('foo.cpp', 2853 '#include "config.h"\n' 2854 '#include "foo.h"\n' 2855 '\n' 2856 '#include "bar.h"\n', 2857 '') 2858 2859 os.path.isfile = self.os_path_isfile_orig 2860 2861 def test_public_primary_header(self): 2862 # System header is not considered a primary header. 2863 self.assert_language_rules_check('foo.cpp', 2864 '#include "config.h"\n' 2865 '#include <other/foo.h>\n' 2866 '\n' 2867 '#include "a.h"\n', 2868 'Alphabetical sorting problem. [build/include_order] [4]') 2869 2870 # ...except that it starts with public/. 2871 self.assert_language_rules_check('foo.cpp', 2872 '#include "config.h"\n' 2873 '#include <public/foo.h>\n' 2874 '\n' 2875 '#include "a.h"\n', 2876 '') 2877 2878 # Even if it starts with public/ its base part must match with the source file name. 2879 self.assert_language_rules_check('foo.cpp', 2880 '#include "config.h"\n' 2881 '#include <public/foop.h>\n' 2882 '\n' 2883 '#include "a.h"\n', 2884 'Alphabetical sorting problem. [build/include_order] [4]') 2885 2886 def test_check_wtf_includes(self): 2887 self.assert_language_rules_check('foo.cpp', 2888 '#include "config.h"\n' 2889 '#include "foo.h"\n' 2890 '\n' 2891 '#include <wtf/Assertions.h>\n', 2892 'wtf includes should be "wtf/file.h" instead of <wtf/file.h>.' 2893 ' [build/include] [4]') 2894 self.assert_language_rules_check('foo.cpp', 2895 '#include "config.h"\n' 2896 '#include "foo.h"\n' 2897 '\n' 2898 '#include "wtf/Assertions.h"\n', 2899 '') 2900 2901 def test_check_cc_includes(self): 2902 self.assert_language_rules_check('bar/chromium/foo.cpp', 2903 '#include "config.h"\n' 2904 '#include "foo.h"\n' 2905 '\n' 2906 '#include "cc/CCProxy.h"\n', 2907 'cc includes should be "CCFoo.h" instead of "cc/CCFoo.h".' 2908 ' [build/include] [4]') 2909 2910 def test_classify_include(self): 2911 classify_include = cpp_style._classify_include 2912 include_state = cpp_style._IncludeState() 2913 self.assertEqual(cpp_style._CONFIG_HEADER, 2914 classify_include('foo/foo.cpp', 2915 'config.h', 2916 False, include_state)) 2917 self.assertEqual(cpp_style._PRIMARY_HEADER, 2918 classify_include('foo/internal/foo.cpp', 2919 'foo/public/foo.h', 2920 False, include_state)) 2921 self.assertEqual(cpp_style._PRIMARY_HEADER, 2922 classify_include('foo/internal/foo.cpp', 2923 'foo/other/public/foo.h', 2924 False, include_state)) 2925 self.assertEqual(cpp_style._OTHER_HEADER, 2926 classify_include('foo/internal/foo.cpp', 2927 'foo/other/public/foop.h', 2928 False, include_state)) 2929 self.assertEqual(cpp_style._OTHER_HEADER, 2930 classify_include('foo/foo.cpp', 2931 'string', 2932 True, include_state)) 2933 self.assertEqual(cpp_style._PRIMARY_HEADER, 2934 classify_include('fooCustom.cpp', 2935 'foo.h', 2936 False, include_state)) 2937 self.assertEqual(cpp_style._PRIMARY_HEADER, 2938 classify_include('PrefixFooCustom.cpp', 2939 'Foo.h', 2940 False, include_state)) 2941 self.assertEqual(cpp_style._MOC_HEADER, 2942 classify_include('foo.cpp', 2943 'foo.moc', 2944 False, include_state)) 2945 self.assertEqual(cpp_style._MOC_HEADER, 2946 classify_include('foo.cpp', 2947 'moc_foo.cpp', 2948 False, include_state)) 2949 # <public/foo.h> must be considered as primary even if is_system is True. 2950 self.assertEqual(cpp_style._PRIMARY_HEADER, 2951 classify_include('foo/foo.cpp', 2952 'public/foo.h', 2953 True, include_state)) 2954 self.assertEqual(cpp_style._OTHER_HEADER, 2955 classify_include('foo.cpp', 2956 'foo.h', 2957 True, include_state)) 2958 self.assertEqual(cpp_style._OTHER_HEADER, 2959 classify_include('foo.cpp', 2960 'public/foop.h', 2961 True, include_state)) 2962 # Qt private APIs use _p.h suffix. 2963 self.assertEqual(cpp_style._PRIMARY_HEADER, 2964 classify_include('foo.cpp', 2965 'foo_p.h', 2966 False, include_state)) 2967 # Tricky example where both includes might be classified as primary. 2968 self.assert_language_rules_check('ScrollbarThemeWince.cpp', 2969 '#include "config.h"\n' 2970 '#include "ScrollbarThemeWince.h"\n' 2971 '\n' 2972 '#include "Scrollbar.h"\n', 2973 '') 2974 self.assert_language_rules_check('ScrollbarThemeWince.cpp', 2975 '#include "config.h"\n' 2976 '#include "Scrollbar.h"\n' 2977 '\n' 2978 '#include "ScrollbarThemeWince.h"\n', 2979 'Found header this file implements after a header this file implements.' 2980 ' Should be: config.h, primary header, blank line, and then alphabetically sorted.' 2981 ' [build/include_order] [4]') 2982 self.assert_language_rules_check('ResourceHandleWin.cpp', 2983 '#include "config.h"\n' 2984 '#include "ResourceHandle.h"\n' 2985 '\n' 2986 '#include "ResourceHandleWin.h"\n', 2987 '') 2988 2989 def test_try_drop_common_suffixes(self): 2990 self.assertEqual('foo/foo', cpp_style._drop_common_suffixes('foo/foo-inl.h')) 2991 self.assertEqual('foo/bar/foo', 2992 cpp_style._drop_common_suffixes('foo/bar/foo_inl.h')) 2993 self.assertEqual('foo/foo', cpp_style._drop_common_suffixes('foo/foo.cpp')) 2994 self.assertEqual('foo/foo_unusualinternal', 2995 cpp_style._drop_common_suffixes('foo/foo_unusualinternal.h')) 2996 self.assertEqual('', 2997 cpp_style._drop_common_suffixes('_test.cpp')) 2998 self.assertEqual('test', 2999 cpp_style._drop_common_suffixes('test.cpp')) 3000 self.assertEqual('test', 3001 cpp_style._drop_common_suffixes('test.cpp')) 3002 3003 class CheckForFunctionLengthsTest(CppStyleTestBase): 3004 def setUp(self): 3005 # Reducing these thresholds for the tests speeds up tests significantly. 3006 self.old_normal_trigger = cpp_style._FunctionState._NORMAL_TRIGGER 3007 self.old_test_trigger = cpp_style._FunctionState._TEST_TRIGGER 3008 3009 cpp_style._FunctionState._NORMAL_TRIGGER = 10 3010 cpp_style._FunctionState._TEST_TRIGGER = 25 3011 3012 def tearDown(self): 3013 cpp_style._FunctionState._NORMAL_TRIGGER = self.old_normal_trigger 3014 cpp_style._FunctionState._TEST_TRIGGER = self.old_test_trigger 3015 3016 # FIXME: Eliminate the need for this function. 3017 def set_min_confidence(self, min_confidence): 3018 """Set new test confidence and return old test confidence.""" 3019 old_min_confidence = self.min_confidence 3020 self.min_confidence = min_confidence 3021 return old_min_confidence 3022 3023 def assert_function_lengths_check(self, code, expected_message): 3024 """Check warnings for long function bodies are as expected. 3025 3026 Args: 3027 code: C++ source code expected to generate a warning message. 3028 expected_message: Message expected to be generated by the C++ code. 3029 """ 3030 self.assertEqual(expected_message, 3031 self.perform_function_lengths_check(code)) 3032 3033 def trigger_lines(self, error_level): 3034 """Return number of lines needed to trigger a function length warning. 3035 3036 Args: 3037 error_level: --v setting for cpp_style. 3038 3039 Returns: 3040 Number of lines needed to trigger a function length warning. 3041 """ 3042 return cpp_style._FunctionState._NORMAL_TRIGGER * 2 ** error_level 3043 3044 def trigger_test_lines(self, error_level): 3045 """Return number of lines needed to trigger a test function length warning. 3046 3047 Args: 3048 error_level: --v setting for cpp_style. 3049 3050 Returns: 3051 Number of lines needed to trigger a test function length warning. 3052 """ 3053 return cpp_style._FunctionState._TEST_TRIGGER * 2 ** error_level 3054 3055 def assert_function_length_check_definition(self, lines, error_level): 3056 """Generate long function definition and check warnings are as expected. 3057 3058 Args: 3059 lines: Number of lines to generate. 3060 error_level: --v setting for cpp_style. 3061 """ 3062 trigger_level = self.trigger_lines(self.min_confidence) 3063 self.assert_function_lengths_check( 3064 'void test(int x)' + self.function_body(lines), 3065 ('Small and focused functions are preferred: ' 3066 'test() has %d non-comment lines ' 3067 '(error triggered by exceeding %d lines).' 3068 ' [readability/fn_size] [%d]' 3069 % (lines, trigger_level, error_level))) 3070 3071 def assert_function_length_check_definition_ok(self, lines): 3072 """Generate shorter function definition and check no warning is produced. 3073 3074 Args: 3075 lines: Number of lines to generate. 3076 """ 3077 self.assert_function_lengths_check( 3078 'void test(int x)' + self.function_body(lines), 3079 '') 3080 3081 def assert_function_length_check_at_error_level(self, error_level): 3082 """Generate and check function at the trigger level for --v setting. 3083 3084 Args: 3085 error_level: --v setting for cpp_style. 3086 """ 3087 self.assert_function_length_check_definition(self.trigger_lines(error_level), 3088 error_level) 3089 3090 def assert_function_length_check_below_error_level(self, error_level): 3091 """Generate and check function just below the trigger level for --v setting. 3092 3093 Args: 3094 error_level: --v setting for cpp_style. 3095 """ 3096 self.assert_function_length_check_definition(self.trigger_lines(error_level) - 1, 3097 error_level - 1) 3098 3099 def assert_function_length_check_above_error_level(self, error_level): 3100 """Generate and check function just above the trigger level for --v setting. 3101 3102 Args: 3103 error_level: --v setting for cpp_style. 3104 """ 3105 self.assert_function_length_check_definition(self.trigger_lines(error_level) + 1, 3106 error_level) 3107 3108 def function_body(self, number_of_lines): 3109 return ' {\n' + ' this_is_just_a_test();\n' * number_of_lines + '}' 3110 3111 def function_body_with_blank_lines(self, number_of_lines): 3112 return ' {\n' + ' this_is_just_a_test();\n\n' * number_of_lines + '}' 3113 3114 def function_body_with_no_lints(self, number_of_lines): 3115 return ' {\n' + ' this_is_just_a_test(); // NOLINT\n' * number_of_lines + '}' 3116 3117 # Test line length checks. 3118 def test_function_length_check_declaration(self): 3119 self.assert_function_lengths_check( 3120 'void test();', # Not a function definition 3121 '') 3122 3123 def test_function_length_check_declaration_with_block_following(self): 3124 self.assert_function_lengths_check( 3125 ('void test();\n' 3126 + self.function_body(66)), # Not a function definition 3127 '') 3128 3129 def test_function_length_check_class_definition(self): 3130 self.assert_function_lengths_check( # Not a function definition 3131 'class Test' + self.function_body(66) + ';', 3132 '') 3133 3134 def test_function_length_check_trivial(self): 3135 self.assert_function_lengths_check( 3136 'void test() {}', # Not counted 3137 '') 3138 3139 def test_function_length_check_empty(self): 3140 self.assert_function_lengths_check( 3141 'void test() {\n}', 3142 '') 3143 3144 def test_function_length_check_definition_below_severity0(self): 3145 old_min_confidence = self.set_min_confidence(0) 3146 self.assert_function_length_check_definition_ok(self.trigger_lines(0) - 1) 3147 self.set_min_confidence(old_min_confidence) 3148 3149 def test_function_length_check_definition_at_severity0(self): 3150 old_min_confidence = self.set_min_confidence(0) 3151 self.assert_function_length_check_definition_ok(self.trigger_lines(0)) 3152 self.set_min_confidence(old_min_confidence) 3153 3154 def test_function_length_check_definition_above_severity0(self): 3155 old_min_confidence = self.set_min_confidence(0) 3156 self.assert_function_length_check_above_error_level(0) 3157 self.set_min_confidence(old_min_confidence) 3158 3159 def test_function_length_check_definition_below_severity1v0(self): 3160 old_min_confidence = self.set_min_confidence(0) 3161 self.assert_function_length_check_below_error_level(1) 3162 self.set_min_confidence(old_min_confidence) 3163 3164 def test_function_length_check_definition_at_severity1v0(self): 3165 old_min_confidence = self.set_min_confidence(0) 3166 self.assert_function_length_check_at_error_level(1) 3167 self.set_min_confidence(old_min_confidence) 3168 3169 def test_function_length_check_definition_below_severity1(self): 3170 self.assert_function_length_check_definition_ok(self.trigger_lines(1) - 1) 3171 3172 def test_function_length_check_definition_at_severity1(self): 3173 self.assert_function_length_check_definition_ok(self.trigger_lines(1)) 3174 3175 def test_function_length_check_definition_above_severity1(self): 3176 self.assert_function_length_check_above_error_level(1) 3177 3178 def test_function_length_check_definition_severity1_plus_indented(self): 3179 error_level = 1 3180 error_lines = self.trigger_lines(error_level) + 1 3181 trigger_level = self.trigger_lines(self.min_confidence) 3182 indent_spaces = ' ' 3183 self.assert_function_lengths_check( 3184 re.sub(r'(?m)^(.)', indent_spaces + r'\1', 3185 'void test_indent(int x)\n' + self.function_body(error_lines)), 3186 ('Small and focused functions are preferred: ' 3187 'test_indent() has %d non-comment lines ' 3188 '(error triggered by exceeding %d lines).' 3189 ' [readability/fn_size] [%d]') 3190 % (error_lines, trigger_level, error_level)) 3191 3192 def test_function_length_check_definition_severity1_plus_blanks(self): 3193 error_level = 1 3194 error_lines = self.trigger_lines(error_level) + 1 3195 trigger_level = self.trigger_lines(self.min_confidence) 3196 self.assert_function_lengths_check( 3197 'void test_blanks(int x)' + self.function_body(error_lines), 3198 ('Small and focused functions are preferred: ' 3199 'test_blanks() has %d non-comment lines ' 3200 '(error triggered by exceeding %d lines).' 3201 ' [readability/fn_size] [%d]') 3202 % (error_lines, trigger_level, error_level)) 3203 3204 def test_function_length_check_complex_definition_severity1(self): 3205 error_level = 1 3206 error_lines = self.trigger_lines(error_level) + 1 3207 trigger_level = self.trigger_lines(self.min_confidence) 3208 self.assert_function_lengths_check( 3209 ('my_namespace::my_other_namespace::MyVeryLongTypeName<Type1, bool func(const Element*)>*\n' 3210 'my_namespace::my_other_namespace<Type3, Type4>::~MyFunction<Type5<Type6, Type7> >(int arg1, char* arg2)' 3211 + self.function_body(error_lines)), 3212 ('Small and focused functions are preferred: ' 3213 'my_namespace::my_other_namespace<Type3, Type4>::~MyFunction<Type5<Type6, Type7> >()' 3214 ' has %d non-comment lines ' 3215 '(error triggered by exceeding %d lines).' 3216 ' [readability/fn_size] [%d]') 3217 % (error_lines, trigger_level, error_level)) 3218 3219 def test_function_length_check_definition_severity1_for_test(self): 3220 error_level = 1 3221 error_lines = self.trigger_test_lines(error_level) + 1 3222 trigger_level = self.trigger_test_lines(self.min_confidence) 3223 self.assert_function_lengths_check( 3224 'TEST_F(Test, Mutator)' + self.function_body(error_lines), 3225 ('Small and focused functions are preferred: ' 3226 'TEST_F(Test, Mutator) has %d non-comment lines ' 3227 '(error triggered by exceeding %d lines).' 3228 ' [readability/fn_size] [%d]') 3229 % (error_lines, trigger_level, error_level)) 3230 3231 def test_function_length_check_definition_severity1_for_split_line_test(self): 3232 error_level = 1 3233 error_lines = self.trigger_test_lines(error_level) + 1 3234 trigger_level = self.trigger_test_lines(self.min_confidence) 3235 self.assert_function_lengths_check( 3236 ('TEST_F(GoogleUpdateRecoveryRegistryProtectedTest,\n' 3237 ' FixGoogleUpdate_AllValues_MachineApp)' # note: 4 spaces 3238 + self.function_body(error_lines)), 3239 ('Small and focused functions are preferred: ' 3240 'TEST_F(GoogleUpdateRecoveryRegistryProtectedTest, ' # 1 space 3241 'FixGoogleUpdate_AllValues_MachineApp) has %d non-comment lines ' 3242 '(error triggered by exceeding %d lines).' 3243 ' [readability/fn_size] [%d]') 3244 % (error_lines, trigger_level, error_level)) 3245 3246 def test_function_length_check_definition_severity1_for_bad_test_doesnt_break(self): 3247 error_level = 1 3248 error_lines = self.trigger_test_lines(error_level) + 1 3249 trigger_level = self.trigger_test_lines(self.min_confidence) 3250 # Since the function name isn't valid, the function detection algorithm 3251 # will skip it, so no error is produced. 3252 self.assert_function_lengths_check( 3253 ('TEST_F(' 3254 + self.function_body(error_lines)), 3255 '') 3256 3257 def test_function_length_check_definition_severity1_with_embedded_no_lints(self): 3258 error_level = 1 3259 error_lines = self.trigger_lines(error_level) + 1 3260 trigger_level = self.trigger_lines(self.min_confidence) 3261 self.assert_function_lengths_check( 3262 'void test(int x)' + self.function_body_with_no_lints(error_lines), 3263 ('Small and focused functions are preferred: ' 3264 'test() has %d non-comment lines ' 3265 '(error triggered by exceeding %d lines).' 3266 ' [readability/fn_size] [%d]') 3267 % (error_lines, trigger_level, error_level)) 3268 3269 def test_function_length_check_definition_severity1_with_no_lint(self): 3270 self.assert_function_lengths_check( 3271 ('void test(int x)' + self.function_body(self.trigger_lines(1)) 3272 + ' // NOLINT -- long function'), 3273 '') 3274 3275 def test_function_length_check_definition_below_severity2(self): 3276 self.assert_function_length_check_below_error_level(2) 3277 3278 def test_function_length_check_definition_severity2(self): 3279 self.assert_function_length_check_at_error_level(2) 3280 3281 def test_function_length_check_definition_above_severity2(self): 3282 self.assert_function_length_check_above_error_level(2) 3283 3284 def test_function_length_check_definition_below_severity3(self): 3285 self.assert_function_length_check_below_error_level(3) 3286 3287 def test_function_length_check_definition_severity3(self): 3288 self.assert_function_length_check_at_error_level(3) 3289 3290 def test_function_length_check_definition_above_severity3(self): 3291 self.assert_function_length_check_above_error_level(3) 3292 3293 def test_function_length_check_definition_below_severity4(self): 3294 self.assert_function_length_check_below_error_level(4) 3295 3296 def test_function_length_check_definition_severity4(self): 3297 self.assert_function_length_check_at_error_level(4) 3298 3299 def test_function_length_check_definition_above_severity4(self): 3300 self.assert_function_length_check_above_error_level(4) 3301 3302 def test_function_length_check_definition_below_severity5(self): 3303 self.assert_function_length_check_below_error_level(5) 3304 3305 def test_function_length_check_definition_at_severity5(self): 3306 self.assert_function_length_check_at_error_level(5) 3307 3308 def test_function_length_check_definition_above_severity5(self): 3309 self.assert_function_length_check_above_error_level(5) 3310 3311 def test_function_length_check_definition_huge_lines(self): 3312 # 5 is the limit 3313 self.assert_function_length_check_definition(self.trigger_lines(6), 5) 3314 3315 def test_function_length_not_determinable(self): 3316 # Macro invocation without terminating semicolon. 3317 self.assert_function_lengths_check( 3318 'MACRO(arg)', 3319 '') 3320 3321 # Macro with underscores 3322 self.assert_function_lengths_check( 3323 'MACRO_WITH_UNDERSCORES(arg1, arg2, arg3)', 3324 '') 3325 3326 self.assert_function_lengths_check( 3327 'NonMacro(arg)', 3328 'Lint failed to find start of function body.' 3329 ' [readability/fn_size] [5]') 3330 3331 3332 class NoNonVirtualDestructorsTest(CppStyleTestBase): 3333 3334 def test_no_error(self): 3335 self.assert_multi_line_lint( 3336 '''\ 3337 class Foo { 3338 virtual ~Foo(); 3339 virtual void foo(); 3340 };''', 3341 '') 3342 3343 self.assert_multi_line_lint( 3344 '''\ 3345 class Foo { 3346 virtual inline ~Foo(); 3347 virtual void foo(); 3348 };''', 3349 '') 3350 3351 self.assert_multi_line_lint( 3352 '''\ 3353 class Foo { 3354 inline virtual ~Foo(); 3355 virtual void foo(); 3356 };''', 3357 '') 3358 3359 self.assert_multi_line_lint( 3360 '''\ 3361 class Foo::Goo { 3362 virtual ~Goo(); 3363 virtual void goo(); 3364 };''', 3365 '') 3366 self.assert_multi_line_lint( 3367 'class Foo { void foo(); };', 3368 'More than one command on the same line [whitespace/newline] [4]') 3369 self.assert_multi_line_lint( 3370 'class MyClass {\n' 3371 ' int getIntValue() { ASSERT(m_ptr); return *m_ptr; }\n' 3372 '};\n', 3373 '') 3374 self.assert_multi_line_lint( 3375 'class MyClass {\n' 3376 ' int getIntValue()\n' 3377 ' {\n' 3378 ' ASSERT(m_ptr); return *m_ptr;\n' 3379 ' }\n' 3380 '};\n', 3381 'More than one command on the same line [whitespace/newline] [4]') 3382 3383 self.assert_multi_line_lint( 3384 '''\ 3385 class Qualified::Goo : public Foo { 3386 virtual void goo(); 3387 };''', 3388 '') 3389 3390 def test_no_destructor_when_virtual_needed(self): 3391 self.assert_multi_line_lint_re( 3392 '''\ 3393 class Foo { 3394 virtual void foo(); 3395 };''', 3396 'The class Foo probably needs a virtual destructor') 3397 3398 def test_enum_casing(self): 3399 self.assert_multi_line_lint( 3400 '''\ 3401 enum Foo { 3402 FOO_ONE = 1, 3403 FOO_TWO 3404 }; 3405 enum { FOO_ONE }; 3406 enum {FooOne, fooTwo}; 3407 enum { 3408 FOO_ONE 3409 };''', 3410 ['enum members should use InterCaps with an initial capital letter. [readability/enum_casing] [4]'] * 5) 3411 3412 self.assert_multi_line_lint( 3413 '''\ 3414 enum Foo { 3415 fooOne = 1, 3416 FooTwo = 2 3417 };''', 3418 'enum members should use InterCaps with an initial capital letter. [readability/enum_casing] [4]') 3419 3420 self.assert_multi_line_lint( 3421 '''\ 3422 enum Foo { 3423 FooOne = 1, 3424 FooTwo 3425 } fooVar = FooOne; 3426 enum { FooOne, FooTwo }; 3427 enum { FooOne, FooTwo } fooVar = FooTwo; 3428 enum { FooOne= FooTwo } foo; 3429 enum Enum123 { 3430 FooOne, 3431 FooTwo = FooOne, 3432 };''', 3433 '') 3434 3435 self.assert_multi_line_lint( 3436 '''\ 3437 // WebIDL enum 3438 enum Foo { 3439 FOO_ONE = 1, 3440 FOO_TWO = 2, 3441 };''', 3442 '') 3443 3444 self.assert_multi_line_lint( 3445 '''\ 3446 // WebKitIDL enum 3447 enum Foo { FOO_ONE, FOO_TWO };''', 3448 '') 3449 3450 def test_destructor_non_virtual_when_virtual_needed(self): 3451 self.assert_multi_line_lint_re( 3452 '''\ 3453 class Foo { 3454 ~Foo(); 3455 virtual void foo(); 3456 };''', 3457 'The class Foo probably needs a virtual destructor') 3458 3459 def test_no_warn_when_derived(self): 3460 self.assert_multi_line_lint( 3461 '''\ 3462 class Foo : public Goo { 3463 virtual void foo(); 3464 };''', 3465 '') 3466 3467 def test_internal_braces(self): 3468 self.assert_multi_line_lint_re( 3469 '''\ 3470 class Foo { 3471 enum Goo { 3472 Goo 3473 }; 3474 virtual void foo(); 3475 };''', 3476 'The class Foo probably needs a virtual destructor') 3477 3478 def test_inner_class_needs_virtual_destructor(self): 3479 self.assert_multi_line_lint_re( 3480 '''\ 3481 class Foo { 3482 class Goo { 3483 virtual void goo(); 3484 }; 3485 };''', 3486 'The class Goo probably needs a virtual destructor') 3487 3488 def test_outer_class_needs_virtual_destructor(self): 3489 self.assert_multi_line_lint_re( 3490 '''\ 3491 class Foo { 3492 class Goo { 3493 }; 3494 virtual void foo(); 3495 };''', 3496 'The class Foo probably needs a virtual destructor') 3497 3498 def test_qualified_class_needs_virtual_destructor(self): 3499 self.assert_multi_line_lint_re( 3500 '''\ 3501 class Qualified::Foo { 3502 virtual void foo(); 3503 };''', 3504 'The class Qualified::Foo probably needs a virtual destructor') 3505 3506 def test_multi_line_declaration_no_error(self): 3507 self.assert_multi_line_lint_re( 3508 '''\ 3509 class Foo 3510 : public Goo { 3511 virtual void foo(); 3512 };''', 3513 '') 3514 3515 def test_multi_line_declaration_with_error(self): 3516 self.assert_multi_line_lint( 3517 '''\ 3518 class Foo 3519 { 3520 virtual void foo(); 3521 };''', 3522 ['This { should be at the end of the previous line ' 3523 '[whitespace/braces] [4]', 3524 'The class Foo probably needs a virtual destructor due to having ' 3525 'virtual method(s), one declared at line 3. [runtime/virtual] [4]']) 3526 3527 3528 class PassPtrTest(CppStyleTestBase): 3529 # For http://webkit.org/coding/RefPtr.html 3530 3531 def assert_pass_ptr_check(self, code, expected_message): 3532 """Check warnings for Pass*Ptr are as expected. 3533 3534 Args: 3535 code: C++ source code expected to generate a warning message. 3536 expected_message: Message expected to be generated by the C++ code. 3537 """ 3538 self.assertEqual(expected_message, 3539 self.perform_pass_ptr_check(code)) 3540 3541 def test_pass_ref_ptr_in_function(self): 3542 self.assert_pass_ptr_check( 3543 'int myFunction()\n' 3544 '{\n' 3545 ' PassRefPtr<Type1> variable = variable2;\n' 3546 '}', 3547 'Local variables should never be PassRefPtr (see ' 3548 'http://webkit.org/coding/RefPtr.html). [readability/pass_ptr] [5]') 3549 3550 def test_pass_own_ptr_in_function(self): 3551 self.assert_pass_ptr_check( 3552 'int myFunction()\n' 3553 '{\n' 3554 ' PassOwnPtr<Type1> variable = variable2;\n' 3555 '}', 3556 'Local variables should never be PassOwnPtr (see ' 3557 'http://webkit.org/coding/RefPtr.html). [readability/pass_ptr] [5]') 3558 3559 def test_pass_other_type_ptr_in_function(self): 3560 self.assert_pass_ptr_check( 3561 'int myFunction()\n' 3562 '{\n' 3563 ' PassOtherTypePtr<Type1> variable;\n' 3564 '}', 3565 'Local variables should never be PassOtherTypePtr (see ' 3566 'http://webkit.org/coding/RefPtr.html). [readability/pass_ptr] [5]') 3567 3568 def test_pass_ref_ptr_return_value(self): 3569 self.assert_pass_ptr_check( 3570 'PassRefPtr<Type1>\n' 3571 'myFunction(int)\n' 3572 '{\n' 3573 '}', 3574 '') 3575 self.assert_pass_ptr_check( 3576 'PassRefPtr<Type1> myFunction(int)\n' 3577 '{\n' 3578 '}', 3579 '') 3580 self.assert_pass_ptr_check( 3581 'PassRefPtr<Type1> myFunction();\n', 3582 '') 3583 self.assert_pass_ptr_check( 3584 'OwnRefPtr<Type1> myFunction();\n', 3585 '') 3586 self.assert_pass_ptr_check( 3587 'RefPtr<Type1> myFunction(int)\n' 3588 '{\n' 3589 '}', 3590 'The return type should use PassRefPtr instead of RefPtr. [readability/pass_ptr] [5]') 3591 self.assert_pass_ptr_check( 3592 'OwnPtr<Type1> myFunction(int)\n' 3593 '{\n' 3594 '}', 3595 'The return type should use PassOwnPtr instead of OwnPtr. [readability/pass_ptr] [5]') 3596 3597 def test_ref_ptr_parameter_value(self): 3598 self.assert_pass_ptr_check( 3599 'int myFunction(PassRefPtr<Type1>)\n' 3600 '{\n' 3601 '}', 3602 '') 3603 self.assert_pass_ptr_check( 3604 'int myFunction(RefPtr<Type1>)\n' 3605 '{\n' 3606 '}', 3607 'The parameter type should use PassRefPtr instead of RefPtr. [readability/pass_ptr] [5]') 3608 self.assert_pass_ptr_check( 3609 'int myFunction(RefPtr<Type1>&)\n' 3610 '{\n' 3611 '}', 3612 '') 3613 self.assert_pass_ptr_check( 3614 'int myFunction(RefPtr<Type1>*)\n' 3615 '{\n' 3616 '}', 3617 '') 3618 self.assert_pass_ptr_check( 3619 'int myFunction(RefPtr<Type1>* = 0)\n' 3620 '{\n' 3621 '}', 3622 '') 3623 self.assert_pass_ptr_check( 3624 'int myFunction(RefPtr<Type1>* = 0)\n' 3625 '{\n' 3626 '}', 3627 '') 3628 3629 def test_own_ptr_parameter_value(self): 3630 self.assert_pass_ptr_check( 3631 'int myFunction(PassOwnPtr<Type1>)\n' 3632 '{\n' 3633 '}', 3634 '') 3635 self.assert_pass_ptr_check( 3636 'int myFunction(OwnPtr<Type1>)\n' 3637 '{\n' 3638 '}', 3639 'The parameter type should use PassOwnPtr instead of OwnPtr. [readability/pass_ptr] [5]') 3640 self.assert_pass_ptr_check( 3641 'int myFunction(OwnPtr<Type1>& simple)\n' 3642 '{\n' 3643 '}', 3644 '') 3645 3646 def test_ref_ptr_member_variable(self): 3647 self.assert_pass_ptr_check( 3648 'class Foo {' 3649 ' RefPtr<Type1> m_other;\n' 3650 '};\n', 3651 '') 3652 3653 3654 class LeakyPatternTest(CppStyleTestBase): 3655 3656 def assert_leaky_pattern_check(self, code, expected_message): 3657 """Check warnings for leaky patterns are as expected. 3658 3659 Args: 3660 code: C++ source code expected to generate a warning message. 3661 expected_message: Message expected to be generated by the C++ code. 3662 """ 3663 self.assertEqual(expected_message, 3664 self.perform_leaky_pattern_check(code)) 3665 3666 def test_get_dc(self): 3667 self.assert_leaky_pattern_check( 3668 'HDC hdc = GetDC(hwnd);', 3669 'Use the class HWndDC instead of calling GetDC to avoid potential ' 3670 'memory leaks. [runtime/leaky_pattern] [5]') 3671 3672 def test_get_dc(self): 3673 self.assert_leaky_pattern_check( 3674 'HDC hdc = GetDCEx(hwnd, 0, 0);', 3675 'Use the class HWndDC instead of calling GetDCEx to avoid potential ' 3676 'memory leaks. [runtime/leaky_pattern] [5]') 3677 3678 def test_own_get_dc(self): 3679 self.assert_leaky_pattern_check( 3680 'HWndDC hdc(hwnd);', 3681 '') 3682 3683 def test_create_dc(self): 3684 self.assert_leaky_pattern_check( 3685 'HDC dc2 = ::CreateDC();', 3686 'Use adoptPtr and OwnPtr<HDC> when calling CreateDC to avoid potential ' 3687 'memory leaks. [runtime/leaky_pattern] [5]') 3688 3689 self.assert_leaky_pattern_check( 3690 'adoptPtr(CreateDC());', 3691 '') 3692 3693 def test_create_compatible_dc(self): 3694 self.assert_leaky_pattern_check( 3695 'HDC dc2 = CreateCompatibleDC(dc);', 3696 'Use adoptPtr and OwnPtr<HDC> when calling CreateCompatibleDC to avoid potential ' 3697 'memory leaks. [runtime/leaky_pattern] [5]') 3698 self.assert_leaky_pattern_check( 3699 'adoptPtr(CreateCompatibleDC(dc));', 3700 '') 3701 3702 3703 class WebKitStyleTest(CppStyleTestBase): 3704 3705 # for http://webkit.org/coding/coding-style.html 3706 def test_indentation(self): 3707 # 1. Use spaces, not tabs. Tabs should only appear in files that 3708 # require them for semantic meaning, like Makefiles. 3709 self.assert_multi_line_lint( 3710 'class Foo {\n' 3711 ' int goo;\n' 3712 '};', 3713 '') 3714 self.assert_multi_line_lint( 3715 'class Foo {\n' 3716 '\tint goo;\n' 3717 '};', 3718 'Tab found; better to use spaces [whitespace/tab] [1]') 3719 3720 # 2. The indent size is 4 spaces. 3721 self.assert_multi_line_lint( 3722 'class Foo {\n' 3723 ' int goo;\n' 3724 '};', 3725 '') 3726 self.assert_multi_line_lint( 3727 'class Foo {\n' 3728 ' int goo;\n' 3729 '};', 3730 'Weird number of spaces at line-start. Are you using a 4-space indent? [whitespace/indent] [3]') 3731 3732 # 3. In a header, code inside a namespace should not be indented. 3733 self.assert_multi_line_lint( 3734 'namespace WebCore {\n\n' 3735 'class Document {\n' 3736 ' int myVariable;\n' 3737 '};\n' 3738 '}', 3739 '', 3740 'foo.h') 3741 self.assert_multi_line_lint( 3742 'namespace OuterNamespace {\n' 3743 ' namespace InnerNamespace {\n' 3744 ' class Document {\n' 3745 '};\n' 3746 '};\n' 3747 '}', 3748 'Code inside a namespace should not be indented. [whitespace/indent] [4]', 3749 'foo.h') 3750 self.assert_multi_line_lint( 3751 'namespace OuterNamespace {\n' 3752 ' class Document {\n' 3753 ' namespace InnerNamespace {\n' 3754 '};\n' 3755 '};\n' 3756 '}', 3757 'Code inside a namespace should not be indented. [whitespace/indent] [4]', 3758 'foo.h') 3759 self.assert_multi_line_lint( 3760 'namespace WebCore {\n' 3761 '#if 0\n' 3762 ' class Document {\n' 3763 '};\n' 3764 '#endif\n' 3765 '}', 3766 'Code inside a namespace should not be indented. [whitespace/indent] [4]', 3767 'foo.h') 3768 self.assert_multi_line_lint( 3769 'namespace WebCore {\n' 3770 'class Document {\n' 3771 '};\n' 3772 '}', 3773 '', 3774 'foo.h') 3775 3776 # 4. In an implementation file (files with the extension .cpp, .c 3777 # or .mm), code inside a namespace should not be indented. 3778 self.assert_multi_line_lint( 3779 'namespace WebCore {\n\n' 3780 'Document::Foo()\n' 3781 ' : foo(bar)\n' 3782 ' , boo(far)\n' 3783 '{\n' 3784 ' stuff();\n' 3785 '}', 3786 '', 3787 'foo.cpp') 3788 self.assert_multi_line_lint( 3789 'namespace OuterNamespace {\n' 3790 'namespace InnerNamespace {\n' 3791 'Document::Foo() { }\n' 3792 ' void* p;\n' 3793 '}\n' 3794 '}\n', 3795 'Code inside a namespace should not be indented. [whitespace/indent] [4]', 3796 'foo.cpp') 3797 self.assert_multi_line_lint( 3798 'namespace OuterNamespace {\n' 3799 'namespace InnerNamespace {\n' 3800 'Document::Foo() { }\n' 3801 '}\n' 3802 ' void* p;\n' 3803 '}\n', 3804 'Code inside a namespace should not be indented. [whitespace/indent] [4]', 3805 'foo.cpp') 3806 self.assert_multi_line_lint( 3807 'namespace WebCore {\n\n' 3808 ' const char* foo = "start:;"\n' 3809 ' "dfsfsfs";\n' 3810 '}\n', 3811 'Code inside a namespace should not be indented. [whitespace/indent] [4]', 3812 'foo.cpp') 3813 self.assert_multi_line_lint( 3814 'namespace WebCore {\n\n' 3815 'const char* foo(void* a = ";", // ;\n' 3816 ' void* b);\n' 3817 ' void* p;\n' 3818 '}\n', 3819 'Code inside a namespace should not be indented. [whitespace/indent] [4]', 3820 'foo.cpp') 3821 self.assert_multi_line_lint( 3822 'namespace WebCore {\n\n' 3823 'const char* foo[] = {\n' 3824 ' "void* b);", // ;\n' 3825 ' "asfdf",\n' 3826 ' }\n' 3827 ' void* p;\n' 3828 '}\n', 3829 'Code inside a namespace should not be indented. [whitespace/indent] [4]', 3830 'foo.cpp') 3831 self.assert_multi_line_lint( 3832 'namespace WebCore {\n\n' 3833 'const char* foo[] = {\n' 3834 ' "void* b);", // }\n' 3835 ' "asfdf",\n' 3836 ' }\n' 3837 '}\n', 3838 '', 3839 'foo.cpp') 3840 self.assert_multi_line_lint( 3841 ' namespace WebCore {\n\n' 3842 ' void Document::Foo()\n' 3843 ' {\n' 3844 'start: // infinite loops are fun!\n' 3845 ' goto start;\n' 3846 ' }', 3847 'namespace should never be indented. [whitespace/indent] [4]', 3848 'foo.cpp') 3849 self.assert_multi_line_lint( 3850 'namespace WebCore {\n' 3851 ' Document::Foo() { }\n' 3852 '}', 3853 'Code inside a namespace should not be indented.' 3854 ' [whitespace/indent] [4]', 3855 'foo.cpp') 3856 self.assert_multi_line_lint( 3857 'namespace WebCore {\n' 3858 '#define abc(x) x; \\\n' 3859 ' x\n' 3860 '}', 3861 '', 3862 'foo.cpp') 3863 self.assert_multi_line_lint( 3864 'namespace WebCore {\n' 3865 '#define abc(x) x; \\\n' 3866 ' x\n' 3867 ' void* x;' 3868 '}', 3869 'Code inside a namespace should not be indented. [whitespace/indent] [4]', 3870 'foo.cpp') 3871 3872 # 5. A case label should line up with its switch statement. The 3873 # case statement is indented. 3874 self.assert_multi_line_lint( 3875 ' switch (condition) {\n' 3876 ' case fooCondition:\n' 3877 ' case barCondition:\n' 3878 ' i++;\n' 3879 ' break;\n' 3880 ' default:\n' 3881 ' i--;\n' 3882 ' }\n', 3883 '') 3884 self.assert_multi_line_lint( 3885 ' switch (condition) {\n' 3886 ' case fooCondition:\n' 3887 ' switch (otherCondition) {\n' 3888 ' default:\n' 3889 ' return;\n' 3890 ' }\n' 3891 ' default:\n' 3892 ' i--;\n' 3893 ' }\n', 3894 '') 3895 self.assert_multi_line_lint( 3896 ' switch (condition) {\n' 3897 ' case fooCondition: break;\n' 3898 ' default: return;\n' 3899 ' }\n', 3900 '') 3901 self.assert_multi_line_lint( 3902 ' switch (condition) {\n' 3903 ' case fooCondition:\n' 3904 ' case barCondition:\n' 3905 ' i++;\n' 3906 ' break;\n' 3907 ' default:\n' 3908 ' i--;\n' 3909 ' }\n', 3910 'A case label should not be indented, but line up with its switch statement.' 3911 ' [whitespace/indent] [4]') 3912 self.assert_multi_line_lint( 3913 ' switch (condition) {\n' 3914 ' case fooCondition:\n' 3915 ' break;\n' 3916 ' default:\n' 3917 ' i--;\n' 3918 ' }\n', 3919 'A case label should not be indented, but line up with its switch statement.' 3920 ' [whitespace/indent] [4]') 3921 self.assert_multi_line_lint( 3922 ' switch (condition) {\n' 3923 ' case fooCondition:\n' 3924 ' case barCondition:\n' 3925 ' switch (otherCondition) {\n' 3926 ' default:\n' 3927 ' return;\n' 3928 ' }\n' 3929 ' default:\n' 3930 ' i--;\n' 3931 ' }\n', 3932 'A case label should not be indented, but line up with its switch statement.' 3933 ' [whitespace/indent] [4]') 3934 self.assert_multi_line_lint( 3935 ' switch (condition) {\n' 3936 ' case fooCondition:\n' 3937 ' case barCondition:\n' 3938 ' i++;\n' 3939 ' break;\n\n' 3940 ' default:\n' 3941 ' i--;\n' 3942 ' }\n', 3943 'Non-label code inside switch statements should be indented.' 3944 ' [whitespace/indent] [4]') 3945 self.assert_multi_line_lint( 3946 ' switch (condition) {\n' 3947 ' case fooCondition:\n' 3948 ' case barCondition:\n' 3949 ' switch (otherCondition) {\n' 3950 ' default:\n' 3951 ' return;\n' 3952 ' }\n' 3953 ' default:\n' 3954 ' i--;\n' 3955 ' }\n', 3956 'Non-label code inside switch statements should be indented.' 3957 ' [whitespace/indent] [4]') 3958 3959 # 6. Boolean expressions at the same nesting level that span 3960 # multiple lines should have their operators on the left side of 3961 # the line instead of the right side. 3962 self.assert_multi_line_lint( 3963 ' return attr->name() == srcAttr\n' 3964 ' || attr->name() == lowsrcAttr;\n', 3965 '') 3966 self.assert_multi_line_lint( 3967 ' return attr->name() == srcAttr ||\n' 3968 ' attr->name() == lowsrcAttr;\n', 3969 'Boolean expressions that span multiple lines should have their ' 3970 'operators on the left side of the line instead of the right side.' 3971 ' [whitespace/operators] [4]') 3972 3973 def test_spacing(self): 3974 # 1. Do not place spaces around unary operators. 3975 self.assert_multi_line_lint( 3976 'i++;', 3977 '') 3978 self.assert_multi_line_lint( 3979 'i ++;', 3980 'Extra space for operator ++; [whitespace/operators] [4]') 3981 3982 # 2. Do place spaces around binary and ternary operators. 3983 self.assert_multi_line_lint( 3984 'y = m * x + b;', 3985 '') 3986 self.assert_multi_line_lint( 3987 'f(a, b);', 3988 '') 3989 self.assert_multi_line_lint( 3990 'c = a | b;', 3991 '') 3992 self.assert_multi_line_lint( 3993 'return condition ? 1 : 0;', 3994 '') 3995 self.assert_multi_line_lint( 3996 'y=m*x+b;', 3997 'Missing spaces around = [whitespace/operators] [4]') 3998 self.assert_multi_line_lint( 3999 'f(a,b);', 4000 'Missing space after , [whitespace/comma] [3]') 4001 self.assert_multi_line_lint( 4002 'c = a|b;', 4003 'Missing spaces around | [whitespace/operators] [3]') 4004 # FIXME: We cannot catch this lint error. 4005 # self.assert_multi_line_lint( 4006 # 'return condition ? 1:0;', 4007 # '') 4008 4009 # 3. Place spaces between control statements and their parentheses. 4010 self.assert_multi_line_lint( 4011 ' if (condition)\n' 4012 ' doIt();\n', 4013 '') 4014 self.assert_multi_line_lint( 4015 ' if(condition)\n' 4016 ' doIt();\n', 4017 'Missing space before ( in if( [whitespace/parens] [5]') 4018 4019 # 4. Do not place spaces between a function and its parentheses, 4020 # or between a parenthesis and its content. 4021 self.assert_multi_line_lint( 4022 'f(a, b);', 4023 '') 4024 self.assert_multi_line_lint( 4025 'f (a, b);', 4026 'Extra space before ( in function call [whitespace/parens] [4]') 4027 self.assert_multi_line_lint( 4028 'f( a, b );', 4029 ['Extra space after ( in function call [whitespace/parens] [4]', 4030 'Extra space before ) [whitespace/parens] [2]']) 4031 4032 def test_line_breaking(self): 4033 # 1. Each statement should get its own line. 4034 self.assert_multi_line_lint( 4035 ' x++;\n' 4036 ' y++;\n' 4037 ' if (condition);\n' 4038 ' doIt();\n', 4039 '') 4040 self.assert_multi_line_lint( 4041 ' if (condition) \\\n' 4042 ' doIt();\n', 4043 '') 4044 self.assert_multi_line_lint( 4045 ' x++; y++;', 4046 'More than one command on the same line [whitespace/newline] [4]') 4047 self.assert_multi_line_lint( 4048 ' if (condition) doIt();\n', 4049 'More than one command on the same line in if [whitespace/parens] [4]') 4050 # Ensure that having a # in the line doesn't hide the error. 4051 self.assert_multi_line_lint( 4052 ' x++; char a[] = "#";', 4053 'More than one command on the same line [whitespace/newline] [4]') 4054 # Ignore preprocessor if's. 4055 self.assert_multi_line_lint( 4056 '#if (condition) || (condition2)\n', 4057 '') 4058 4059 # 2. An else statement should go on the same line as a preceding 4060 # close brace if one is present, else it should line up with the 4061 # if statement. 4062 self.assert_multi_line_lint( 4063 'if (condition) {\n' 4064 ' doSomething();\n' 4065 ' doSomethingAgain();\n' 4066 '} else {\n' 4067 ' doSomethingElse();\n' 4068 ' doSomethingElseAgain();\n' 4069 '}\n', 4070 '') 4071 self.assert_multi_line_lint( 4072 'if (condition)\n' 4073 ' doSomething();\n' 4074 'else\n' 4075 ' doSomethingElse();\n', 4076 '') 4077 self.assert_multi_line_lint( 4078 'if (condition) {\n' 4079 ' doSomething();\n' 4080 '} else {\n' 4081 ' doSomethingElse();\n' 4082 ' doSomethingElseAgain();\n' 4083 '}\n', 4084 '') 4085 self.assert_multi_line_lint( 4086 '#define TEST_ASSERT(expression) do { if (!(expression)) { TestsController::shared().testFailed(__FILE__, __LINE__, #expression); return; } } while (0)\n', 4087 '') 4088 self.assert_multi_line_lint( 4089 '#define TEST_ASSERT(expression) do { if ( !(expression)) { TestsController::shared().testFailed(__FILE__, __LINE__, #expression); return; } } while (0)\n', 4090 'Extra space after ( in if [whitespace/parens] [5]') 4091 # FIXME: currently we only check first conditional, so we cannot detect errors in next ones. 4092 # self.assert_multi_line_lint( 4093 # '#define TEST_ASSERT(expression) do { if (!(expression)) { TestsController::shared().testFailed(__FILE__, __LINE__, #expression); return; } } while (0 )\n', 4094 # 'Mismatching spaces inside () in if [whitespace/parens] [5]') 4095 self.assert_multi_line_lint( 4096 'WTF_MAKE_NONCOPYABLE(ClassName); WTF_MAKE_FAST_ALLOCATED;\n', 4097 '') 4098 self.assert_multi_line_lint( 4099 'if (condition) {\n' 4100 ' doSomething();\n' 4101 ' doSomethingAgain();\n' 4102 '}\n' 4103 'else {\n' 4104 ' doSomethingElse();\n' 4105 ' doSomethingElseAgain();\n' 4106 '}\n', 4107 'An else should appear on the same line as the preceding } [whitespace/newline] [4]') 4108 self.assert_multi_line_lint( 4109 'if (condition) doSomething(); else doSomethingElse();\n', 4110 ['More than one command on the same line [whitespace/newline] [4]', 4111 'Else clause should never be on same line as else (use 2 lines) [whitespace/newline] [4]', 4112 'More than one command on the same line in if [whitespace/parens] [4]']) 4113 self.assert_multi_line_lint( 4114 'if (condition) doSomething(); else {\n' 4115 ' doSomethingElse();\n' 4116 '}\n', 4117 ['More than one command on the same line in if [whitespace/parens] [4]', 4118 'If one part of an if-else statement uses curly braces, the other part must too. [whitespace/braces] [4]']) 4119 self.assert_multi_line_lint( 4120 'void func()\n' 4121 '{\n' 4122 ' while (condition) { }\n' 4123 ' return 0;\n' 4124 '}\n', 4125 '') 4126 self.assert_multi_line_lint( 4127 'void func()\n' 4128 '{\n' 4129 ' for (i = 0; i < 42; i++) { foobar(); }\n' 4130 ' return 0;\n' 4131 '}\n', 4132 'More than one command on the same line in for [whitespace/parens] [4]') 4133 4134 # 3. An else if statement should be written as an if statement 4135 # when the prior if concludes with a return statement. 4136 self.assert_multi_line_lint( 4137 'if (motivated) {\n' 4138 ' if (liquid)\n' 4139 ' return money;\n' 4140 '} else if (tired) {\n' 4141 ' break;\n' 4142 '}', 4143 '') 4144 self.assert_multi_line_lint( 4145 'if (condition)\n' 4146 ' doSomething();\n' 4147 'else if (otherCondition)\n' 4148 ' doSomethingElse();\n', 4149 '') 4150 self.assert_multi_line_lint( 4151 'if (condition)\n' 4152 ' doSomething();\n' 4153 'else\n' 4154 ' doSomethingElse();\n', 4155 '') 4156 self.assert_multi_line_lint( 4157 'if (condition)\n' 4158 ' returnValue = foo;\n' 4159 'else if (otherCondition)\n' 4160 ' returnValue = bar;\n', 4161 '') 4162 self.assert_multi_line_lint( 4163 'if (condition)\n' 4164 ' returnValue = foo;\n' 4165 'else\n' 4166 ' returnValue = bar;\n', 4167 '') 4168 self.assert_multi_line_lint( 4169 'if (condition)\n' 4170 ' doSomething();\n' 4171 'else if (liquid)\n' 4172 ' return money;\n' 4173 'else if (broke)\n' 4174 ' return favor;\n' 4175 'else\n' 4176 ' sleep(28800);\n', 4177 '') 4178 self.assert_multi_line_lint( 4179 'if (liquid) {\n' 4180 ' prepare();\n' 4181 ' return money;\n' 4182 '} else if (greedy) {\n' 4183 ' keep();\n' 4184 ' return nothing;\n' 4185 '}\n', 4186 'An else if statement should be written as an if statement when the ' 4187 'prior "if" concludes with a return, break, continue or goto statement.' 4188 ' [readability/control_flow] [4]') 4189 self.assert_multi_line_lint( 4190 ' if (stupid) {\n' 4191 'infiniteLoop:\n' 4192 ' goto infiniteLoop;\n' 4193 ' } else if (evil)\n' 4194 ' goto hell;\n', 4195 ['If one part of an if-else statement uses curly braces, the other part must too. [whitespace/braces] [4]', 4196 'An else if statement should be written as an if statement when the ' 4197 'prior "if" concludes with a return, break, continue or goto statement.' 4198 ' [readability/control_flow] [4]']) 4199 self.assert_multi_line_lint( 4200 'if (liquid)\n' 4201 '{\n' 4202 ' prepare();\n' 4203 ' return money;\n' 4204 '}\n' 4205 'else if (greedy)\n' 4206 ' keep();\n', 4207 ['If one part of an if-else statement uses curly braces, the other part must too. [whitespace/braces] [4]', 4208 'This { should be at the end of the previous line [whitespace/braces] [4]', 4209 'An else should appear on the same line as the preceding } [whitespace/newline] [4]', 4210 'An else if statement should be written as an if statement when the ' 4211 'prior "if" concludes with a return, break, continue or goto statement.' 4212 ' [readability/control_flow] [4]']) 4213 self.assert_multi_line_lint( 4214 'if (gone)\n' 4215 ' return;\n' 4216 'else if (here)\n' 4217 ' go();\n', 4218 'An else if statement should be written as an if statement when the ' 4219 'prior "if" concludes with a return, break, continue or goto statement.' 4220 ' [readability/control_flow] [4]') 4221 self.assert_multi_line_lint( 4222 'if (gone)\n' 4223 ' return;\n' 4224 'else\n' 4225 ' go();\n', 4226 'An else statement can be removed when the prior "if" concludes ' 4227 'with a return, break, continue or goto statement.' 4228 ' [readability/control_flow] [4]') 4229 self.assert_multi_line_lint( 4230 'if (motivated) {\n' 4231 ' prepare();\n' 4232 ' continue;\n' 4233 '} else {\n' 4234 ' cleanUp();\n' 4235 ' break;\n' 4236 '}\n', 4237 'An else statement can be removed when the prior "if" concludes ' 4238 'with a return, break, continue or goto statement.' 4239 ' [readability/control_flow] [4]') 4240 self.assert_multi_line_lint( 4241 'if (tired)\n' 4242 ' break;\n' 4243 'else {\n' 4244 ' prepare();\n' 4245 ' continue;\n' 4246 '}\n', 4247 ['If one part of an if-else statement uses curly braces, the other part must too. [whitespace/braces] [4]', 4248 'An else statement can be removed when the prior "if" concludes ' 4249 'with a return, break, continue or goto statement.' 4250 ' [readability/control_flow] [4]']) 4251 4252 def test_braces(self): 4253 # 1. Function definitions: place each brace on its own line. 4254 self.assert_multi_line_lint( 4255 'int main()\n' 4256 '{\n' 4257 ' doSomething();\n' 4258 '}\n', 4259 '') 4260 self.assert_multi_line_lint( 4261 'int main() {\n' 4262 ' doSomething();\n' 4263 '}\n', 4264 'Place brace on its own line for function definitions. [whitespace/braces] [4]') 4265 4266 # 2. Other braces: place the open brace on the line preceding the 4267 # code block; place the close brace on its own line. 4268 self.assert_multi_line_lint( 4269 'class MyClass {\n' 4270 ' int foo;\n' 4271 '};\n', 4272 '') 4273 self.assert_multi_line_lint( 4274 'namespace WebCore {\n' 4275 'int foo;\n' 4276 '};\n', 4277 '') 4278 self.assert_multi_line_lint( 4279 'for (int i = 0; i < 10; i++) {\n' 4280 ' DoSomething();\n' 4281 '};\n', 4282 '') 4283 self.assert_multi_line_lint( 4284 'class MyClass\n' 4285 '{\n' 4286 ' int foo;\n' 4287 '};\n', 4288 'This { should be at the end of the previous line [whitespace/braces] [4]') 4289 self.assert_multi_line_lint( 4290 'if (condition)\n' 4291 '{\n' 4292 ' int foo;\n' 4293 '}\n', 4294 'This { should be at the end of the previous line [whitespace/braces] [4]') 4295 self.assert_multi_line_lint( 4296 'for (int i = 0; i < 10; i++)\n' 4297 '{\n' 4298 ' int foo;\n' 4299 '}\n', 4300 'This { should be at the end of the previous line [whitespace/braces] [4]') 4301 self.assert_multi_line_lint( 4302 'while (true)\n' 4303 '{\n' 4304 ' int foo;\n' 4305 '}\n', 4306 'This { should be at the end of the previous line [whitespace/braces] [4]') 4307 self.assert_multi_line_lint( 4308 'foreach (Foo* foo, foos)\n' 4309 '{\n' 4310 ' int bar;\n' 4311 '}\n', 4312 'This { should be at the end of the previous line [whitespace/braces] [4]') 4313 self.assert_multi_line_lint( 4314 'switch (type)\n' 4315 '{\n' 4316 'case foo: return;\n' 4317 '}\n', 4318 'This { should be at the end of the previous line [whitespace/braces] [4]') 4319 self.assert_multi_line_lint( 4320 'if (condition)\n' 4321 '{\n' 4322 ' int foo;\n' 4323 '}\n', 4324 'This { should be at the end of the previous line [whitespace/braces] [4]') 4325 self.assert_multi_line_lint( 4326 'for (int i = 0; i < 10; i++)\n' 4327 '{\n' 4328 ' int foo;\n' 4329 '}\n', 4330 'This { should be at the end of the previous line [whitespace/braces] [4]') 4331 self.assert_multi_line_lint( 4332 'while (true)\n' 4333 '{\n' 4334 ' int foo;\n' 4335 '}\n', 4336 'This { should be at the end of the previous line [whitespace/braces] [4]') 4337 self.assert_multi_line_lint( 4338 'switch (type)\n' 4339 '{\n' 4340 'case foo: return;\n' 4341 '}\n', 4342 'This { should be at the end of the previous line [whitespace/braces] [4]') 4343 self.assert_multi_line_lint( 4344 'else if (type)\n' 4345 '{\n' 4346 'case foo: return;\n' 4347 '}\n', 4348 'This { should be at the end of the previous line [whitespace/braces] [4]') 4349 4350 # 3. Curly braces are not required for single-line conditionals and 4351 # loop bodies, but are required for single-statement bodies that 4352 # span multiple lines. 4353 4354 # 4355 # Positive tests 4356 # 4357 self.assert_multi_line_lint( 4358 'if (condition1)\n' 4359 ' statement1();\n' 4360 'else\n' 4361 ' statement2();\n', 4362 '') 4363 4364 self.assert_multi_line_lint( 4365 'if (condition1)\n' 4366 ' statement1();\n' 4367 'else if (condition2)\n' 4368 ' statement2();\n', 4369 '') 4370 4371 self.assert_multi_line_lint( 4372 'if (condition1)\n' 4373 ' statement1();\n' 4374 'else if (condition2)\n' 4375 ' statement2();\n' 4376 'else\n' 4377 ' statement3();\n', 4378 '') 4379 4380 self.assert_multi_line_lint( 4381 'for (; foo; bar)\n' 4382 ' int foo;\n', 4383 '') 4384 4385 self.assert_multi_line_lint( 4386 'for (; foo; bar) {\n' 4387 ' int foo;\n' 4388 '}\n', 4389 '') 4390 4391 self.assert_multi_line_lint( 4392 'foreach (foo, foos) {\n' 4393 ' int bar;\n' 4394 '}\n', 4395 '') 4396 4397 self.assert_multi_line_lint( 4398 'foreach (foo, foos)\n' 4399 ' int bar;\n', 4400 '') 4401 4402 self.assert_multi_line_lint( 4403 'while (true) {\n' 4404 ' int foo;\n' 4405 '}\n', 4406 '') 4407 4408 self.assert_multi_line_lint( 4409 'while (true)\n' 4410 ' int foo;\n', 4411 '') 4412 4413 self.assert_multi_line_lint( 4414 'if (condition1) {\n' 4415 ' statement1();\n' 4416 '} else {\n' 4417 ' statement2();\n' 4418 '}\n', 4419 '') 4420 4421 self.assert_multi_line_lint( 4422 'if (condition1) {\n' 4423 ' statement1();\n' 4424 '} else if (condition2) {\n' 4425 ' statement2();\n' 4426 '}\n', 4427 '') 4428 4429 self.assert_multi_line_lint( 4430 'if (condition1) {\n' 4431 ' statement1();\n' 4432 '} else if (condition2) {\n' 4433 ' statement2();\n' 4434 '} else {\n' 4435 ' statement3();\n' 4436 '}\n', 4437 '') 4438 4439 self.assert_multi_line_lint( 4440 'if (condition1) {\n' 4441 ' statement1();\n' 4442 ' statement1_2();\n' 4443 '} else if (condition2) {\n' 4444 ' statement2();\n' 4445 ' statement2_2();\n' 4446 '}\n', 4447 '') 4448 4449 self.assert_multi_line_lint( 4450 'if (condition1) {\n' 4451 ' statement1();\n' 4452 ' statement1_2();\n' 4453 '} else if (condition2) {\n' 4454 ' statement2();\n' 4455 ' statement2_2();\n' 4456 '} else {\n' 4457 ' statement3();\n' 4458 ' statement3_2();\n' 4459 '}\n', 4460 '') 4461 4462 # 4463 # Negative tests 4464 # 4465 4466 self.assert_multi_line_lint( 4467 'if (condition)\n' 4468 ' doSomething(\n' 4469 ' spanningMultipleLines);\n', 4470 'A conditional or loop body must use braces if the statement is more than one line long. [whitespace/braces] [4]') 4471 4472 self.assert_multi_line_lint( 4473 'if (condition)\n' 4474 ' // Single-line comment\n' 4475 ' doSomething();\n', 4476 'A conditional or loop body must use braces if the statement is more than one line long. [whitespace/braces] [4]') 4477 4478 self.assert_multi_line_lint( 4479 'if (condition1)\n' 4480 ' statement1();\n' 4481 'else if (condition2)\n' 4482 ' // Single-line comment\n' 4483 ' statement2();\n', 4484 'A conditional or loop body must use braces if the statement is more than one line long. [whitespace/braces] [4]') 4485 4486 self.assert_multi_line_lint( 4487 'if (condition1)\n' 4488 ' statement1();\n' 4489 'else if (condition2)\n' 4490 ' statement2();\n' 4491 'else\n' 4492 ' // Single-line comment\n' 4493 ' statement3();\n', 4494 'A conditional or loop body must use braces if the statement is more than one line long. [whitespace/braces] [4]') 4495 4496 self.assert_multi_line_lint( 4497 'for (; foo; bar)\n' 4498 ' // Single-line comment\n' 4499 ' int foo;\n', 4500 'A conditional or loop body must use braces if the statement is more than one line long. [whitespace/braces] [4]') 4501 4502 self.assert_multi_line_lint( 4503 'foreach (foo, foos)\n' 4504 ' // Single-line comment\n' 4505 ' int bar;\n', 4506 'A conditional or loop body must use braces if the statement is more than one line long. [whitespace/braces] [4]') 4507 4508 self.assert_multi_line_lint( 4509 'while (true)\n' 4510 ' // Single-line comment\n' 4511 ' int foo;\n' 4512 '\n', 4513 'A conditional or loop body must use braces if the statement is more than one line long. [whitespace/braces] [4]') 4514 4515 # 4. If one part of an if-else statement uses curly braces, the 4516 # other part must too. 4517 4518 self.assert_multi_line_lint( 4519 'if (condition1) {\n' 4520 ' doSomething1();\n' 4521 ' doSomething1_2();\n' 4522 '} else if (condition2)\n' 4523 ' doSomething2();\n' 4524 'else\n' 4525 ' doSomething3();\n', 4526 'If one part of an if-else statement uses curly braces, the other part must too. [whitespace/braces] [4]') 4527 4528 self.assert_multi_line_lint( 4529 'if (condition1)\n' 4530 ' doSomething1();\n' 4531 'else if (condition2) {\n' 4532 ' doSomething2();\n' 4533 ' doSomething2_2();\n' 4534 '} else\n' 4535 ' doSomething3();\n', 4536 'If one part of an if-else statement uses curly braces, the other part must too. [whitespace/braces] [4]') 4537 4538 self.assert_multi_line_lint( 4539 'if (condition1) {\n' 4540 ' doSomething1();\n' 4541 '} else if (condition2) {\n' 4542 ' doSomething2();\n' 4543 ' doSomething2_2();\n' 4544 '} else\n' 4545 ' doSomething3();\n', 4546 'If one part of an if-else statement uses curly braces, the other part must too. [whitespace/braces] [4]') 4547 4548 self.assert_multi_line_lint( 4549 'if (condition1)\n' 4550 ' doSomething1();\n' 4551 'else if (condition2)\n' 4552 ' doSomething2();\n' 4553 'else {\n' 4554 ' doSomething3();\n' 4555 ' doSomething3_2();\n' 4556 '}\n', 4557 'If one part of an if-else statement uses curly braces, the other part must too. [whitespace/braces] [4]') 4558 4559 self.assert_multi_line_lint( 4560 'if (condition1) {\n' 4561 ' doSomething1();\n' 4562 ' doSomething1_2();\n' 4563 '} else if (condition2)\n' 4564 ' doSomething2();\n' 4565 'else {\n' 4566 ' doSomething3();\n' 4567 ' doSomething3_2();\n' 4568 '}\n', 4569 'If one part of an if-else statement uses curly braces, the other part must too. [whitespace/braces] [4]') 4570 4571 self.assert_multi_line_lint( 4572 'if (condition1)\n' 4573 ' doSomething1();\n' 4574 'else if (condition2) {\n' 4575 ' doSomething2();\n' 4576 ' doSomething2_2();\n' 4577 '} else {\n' 4578 ' doSomething3();\n' 4579 ' doSomething3_2();\n' 4580 '}\n', 4581 'If one part of an if-else statement uses curly braces, the other part must too. [whitespace/braces] [4]') 4582 4583 4584 # 5. Control clauses without a body should use empty braces. 4585 self.assert_multi_line_lint( 4586 'for ( ; current; current = current->next) { }\n', 4587 '') 4588 self.assert_multi_line_lint( 4589 'for ( ; current;\n' 4590 ' current = current->next) { }\n', 4591 'Weird number of spaces at line-start. Are you using a 4-space indent? [whitespace/indent] [3]') 4592 self.assert_multi_line_lint( 4593 'for ( ; current; current = current->next);\n', 4594 'Semicolon defining empty statement for this loop. Use { } instead. [whitespace/semicolon] [5]') 4595 self.assert_multi_line_lint( 4596 'while (true);\n', 4597 'Semicolon defining empty statement for this loop. Use { } instead. [whitespace/semicolon] [5]') 4598 self.assert_multi_line_lint( 4599 '} while (true);\n', 4600 '') 4601 4602 def test_null_false_zero(self): 4603 # 1. In C++, the null pointer value should be written as 0. In C, 4604 # it should be written as NULL. In Objective-C and Objective-C++, 4605 # follow the guideline for C or C++, respectively, but use nil to 4606 # represent a null Objective-C object. 4607 self.assert_lint( 4608 'functionCall(NULL)', 4609 'Use 0 instead of NULL.' 4610 ' [readability/null] [5]', 4611 'foo.cpp') 4612 self.assert_lint( 4613 "// Don't use NULL in comments since it isn't in code.", 4614 'Use 0 or null instead of NULL (even in *comments*).' 4615 ' [readability/null] [4]', 4616 'foo.cpp') 4617 self.assert_lint( 4618 '"A string with NULL" // and a comment with NULL is tricky to flag correctly in cpp_style.', 4619 'Use 0 or null instead of NULL (even in *comments*).' 4620 ' [readability/null] [4]', 4621 'foo.cpp') 4622 self.assert_lint( 4623 '"A string containing NULL is ok"', 4624 '', 4625 'foo.cpp') 4626 self.assert_lint( 4627 'if (aboutNULL)', 4628 '', 4629 'foo.cpp') 4630 self.assert_lint( 4631 'myVariable = NULLify', 4632 '', 4633 'foo.cpp') 4634 # Make sure that the NULL check does not apply to C and Objective-C files. 4635 self.assert_lint( 4636 'functionCall(NULL)', 4637 '', 4638 'foo.c') 4639 self.assert_lint( 4640 'functionCall(NULL)', 4641 '', 4642 'foo.m') 4643 4644 # Make sure that the NULL check does not apply to g_object_{set,get} and 4645 # g_str{join,concat} 4646 self.assert_lint( 4647 'g_object_get(foo, "prop", &bar, NULL);', 4648 '') 4649 self.assert_lint( 4650 'g_object_set(foo, "prop", bar, NULL);', 4651 '') 4652 self.assert_lint( 4653 'g_build_filename(foo, bar, NULL);', 4654 '') 4655 self.assert_lint( 4656 'gst_bin_add_many(foo, bar, boo, NULL);', 4657 '') 4658 self.assert_lint( 4659 'gst_bin_remove_many(foo, bar, boo, NULL);', 4660 '') 4661 self.assert_lint( 4662 'gst_element_link_many(foo, bar, boo, NULL);', 4663 '') 4664 self.assert_lint( 4665 'gst_element_unlink_many(foo, bar, boo, NULL);', 4666 '') 4667 self.assert_lint( 4668 'gst_structure_get(foo, "value", G_TYPE_INT, &value, NULL);', 4669 '') 4670 self.assert_lint( 4671 'gst_structure_set(foo, "value", G_TYPE_INT, value, NULL);', 4672 '') 4673 self.assert_lint( 4674 'gst_structure_remove_fields(foo, "value", "bar", NULL);', 4675 '') 4676 self.assert_lint( 4677 'gst_structure_new("foo", "value", G_TYPE_INT, value, NULL);', 4678 '') 4679 self.assert_lint( 4680 'gst_structure_id_new(FOO, VALUE, G_TYPE_INT, value, NULL);', 4681 '') 4682 self.assert_lint( 4683 'gst_structure_id_set(FOO, VALUE, G_TYPE_INT, value, NULL);', 4684 '') 4685 self.assert_lint( 4686 'gst_structure_id_get(FOO, VALUE, G_TYPE_INT, &value, NULL);', 4687 '') 4688 self.assert_lint( 4689 'gst_caps_new_simple(mime, "value", G_TYPE_INT, &value, NULL);', 4690 '') 4691 self.assert_lint( 4692 'gst_caps_new_full(structure1, structure2, NULL);', 4693 '') 4694 self.assert_lint( 4695 'gchar* result = g_strconcat("part1", "part2", "part3", NULL);', 4696 '') 4697 self.assert_lint( 4698 'gchar* result = g_strconcat("part1", NULL);', 4699 '') 4700 self.assert_lint( 4701 'gchar* result = g_strjoin(",", "part1", "part2", "part3", NULL);', 4702 '') 4703 self.assert_lint( 4704 'gchar* result = g_strjoin(",", "part1", NULL);', 4705 '') 4706 self.assert_lint( 4707 'gchar* result = gdk_pixbuf_save_to_callback(pixbuf, function, data, type, error, NULL);', 4708 '') 4709 self.assert_lint( 4710 'gchar* result = gdk_pixbuf_save_to_buffer(pixbuf, function, data, type, error, NULL);', 4711 '') 4712 self.assert_lint( 4713 'gchar* result = gdk_pixbuf_save_to_stream(pixbuf, function, data, type, error, NULL);', 4714 '') 4715 self.assert_lint( 4716 'gtk_widget_style_get(style, "propertyName", &value, "otherName", &otherValue, NULL);', 4717 '') 4718 self.assert_lint( 4719 'gtk_style_context_get_style(context, "propertyName", &value, "otherName", &otherValue, NULL);', 4720 '') 4721 self.assert_lint( 4722 'gtk_style_context_get(context, static_cast<GtkStateFlags>(0), "property", &value, NULL);', 4723 '') 4724 self.assert_lint( 4725 'gtk_widget_style_get_property(style, NULL, NULL);', 4726 'Use 0 instead of NULL. [readability/null] [5]', 4727 'foo.cpp') 4728 self.assert_lint( 4729 'gtk_widget_style_get_valist(style, NULL, NULL);', 4730 'Use 0 instead of NULL. [readability/null] [5]', 4731 'foo.cpp') 4732 4733 # 2. C++ and C bool values should be written as true and 4734 # false. Objective-C BOOL values should be written as YES and NO. 4735 # FIXME: Implement this. 4736 4737 # 3. Tests for true/false and null/non-null should be done without 4738 # equality comparisons. 4739 self.assert_lint_one_of_many_errors_re( 4740 'if (string != NULL)', 4741 r'Tests for true/false and null/non-null should be done without equality comparisons\.') 4742 self.assert_lint( 4743 'if (p == nullptr)', 4744 'Tests for true/false and null/non-null should be done without equality comparisons.' 4745 ' [readability/comparison_to_boolean] [5]') 4746 self.assert_lint( 4747 'if (condition == true)', 4748 'Tests for true/false and null/non-null should be done without equality comparisons.' 4749 ' [readability/comparison_to_boolean] [5]') 4750 self.assert_lint( 4751 'if (myVariable != /* Why would anyone put a comment here? */ false)', 4752 'Tests for true/false and null/non-null should be done without equality comparisons.' 4753 ' [readability/comparison_to_boolean] [5]') 4754 4755 self.assert_lint_one_of_many_errors_re( 4756 'if (NULL == thisMayBeNull)', 4757 r'Tests for true/false and null/non-null should be done without equality comparisons\.') 4758 self.assert_lint( 4759 'if (nullptr /* funny place for a comment */ == p)', 4760 'Tests for true/false and null/non-null should be done without equality comparisons.' 4761 ' [readability/comparison_to_boolean] [5]') 4762 self.assert_lint( 4763 'if (true != anotherCondition)', 4764 'Tests for true/false and null/non-null should be done without equality comparisons.' 4765 ' [readability/comparison_to_boolean] [5]') 4766 self.assert_lint( 4767 'if (false == myBoolValue)', 4768 'Tests for true/false and null/non-null should be done without equality comparisons.' 4769 ' [readability/comparison_to_boolean] [5]') 4770 4771 self.assert_lint( 4772 'if (fontType == trueType)', 4773 '') 4774 self.assert_lint( 4775 'if (othertrue == fontType)', 4776 '') 4777 self.assert_lint( 4778 'if (LIKELY(foo == 0))', 4779 '') 4780 self.assert_lint( 4781 'if (UNLIKELY(foo == 0))', 4782 '') 4783 self.assert_lint( 4784 'if ((a - b) == 0.5)', 4785 '') 4786 self.assert_lint( 4787 'if (0.5 == (a - b))', 4788 '') 4789 self.assert_lint( 4790 'if (LIKELY(foo == NULL))', 4791 'Use 0 instead of NULL. [readability/null] [5]') 4792 self.assert_lint( 4793 'if (UNLIKELY(foo == NULL))', 4794 'Use 0 instead of NULL. [readability/null] [5]') 4795 4796 def test_directive_indentation(self): 4797 self.assert_lint( 4798 " #if FOO", 4799 "preprocessor directives (e.g., #ifdef, #define, #import) should never be indented." 4800 " [whitespace/indent] [4]", 4801 "foo.cpp") 4802 4803 def test_using_std(self): 4804 self.assert_lint( 4805 'using std::min;', 4806 "Use 'using namespace std;' instead of 'using std::min;'." 4807 " [build/using_std] [4]", 4808 'foo.cpp') 4809 4810 def test_using_std_swap_ignored(self): 4811 self.assert_lint( 4812 'using std::swap;', 4813 '', 4814 'foo.cpp') 4815 4816 def test_max_macro(self): 4817 self.assert_lint( 4818 'int i = MAX(0, 1);', 4819 '', 4820 'foo.c') 4821 4822 self.assert_lint( 4823 'int i = MAX(0, 1);', 4824 'Use std::max() or std::max<type>() instead of the MAX() macro.' 4825 ' [runtime/max_min_macros] [4]', 4826 'foo.cpp') 4827 4828 self.assert_lint( 4829 'inline int foo() { return MAX(0, 1); }', 4830 'Use std::max() or std::max<type>() instead of the MAX() macro.' 4831 ' [runtime/max_min_macros] [4]', 4832 'foo.h') 4833 4834 def test_min_macro(self): 4835 self.assert_lint( 4836 'int i = MIN(0, 1);', 4837 '', 4838 'foo.c') 4839 4840 self.assert_lint( 4841 'int i = MIN(0, 1);', 4842 'Use std::min() or std::min<type>() instead of the MIN() macro.' 4843 ' [runtime/max_min_macros] [4]', 4844 'foo.cpp') 4845 4846 self.assert_lint( 4847 'inline int foo() { return MIN(0, 1); }', 4848 'Use std::min() or std::min<type>() instead of the MIN() macro.' 4849 ' [runtime/max_min_macros] [4]', 4850 'foo.h') 4851 4852 def test_ctype_fucntion(self): 4853 self.assert_lint( 4854 'int i = isascii(8);', 4855 'Use equivelent function in <wtf/ASCIICType.h> instead of the ' 4856 'isascii() function. [runtime/ctype_function] [4]', 4857 'foo.cpp') 4858 4859 def test_names(self): 4860 name_underscore_error_message = " is incorrectly named. Don't use underscores in your identifier names. [readability/naming/underscores] [4]" 4861 name_tooshort_error_message = " is incorrectly named. Don't use the single letter 'l' as an identifier name. [readability/naming] [4]" 4862 4863 # Basic cases from WebKit style guide. 4864 self.assert_lint('struct Data;', '') 4865 self.assert_lint('size_t bufferSize;', '') 4866 self.assert_lint('class HTMLDocument;', '') 4867 self.assert_lint('String mimeType();', '') 4868 self.assert_lint('size_t buffer_size;', 4869 'buffer_size' + name_underscore_error_message) 4870 self.assert_lint('short m_length;', '') 4871 self.assert_lint('short _length;', 4872 '_length' + name_underscore_error_message) 4873 self.assert_lint('short length_;', 4874 'length_' + name_underscore_error_message) 4875 self.assert_lint('unsigned _length;', 4876 '_length' + name_underscore_error_message) 4877 self.assert_lint('unsigned long _length;', 4878 '_length' + name_underscore_error_message) 4879 self.assert_lint('unsigned long long _length;', 4880 '_length' + name_underscore_error_message) 4881 4882 # Allow underscores in Objective C files. 4883 self.assert_lint('unsigned long long _length;', 4884 '', 4885 'foo.m') 4886 self.assert_lint('unsigned long long _length;', 4887 '', 4888 'foo.mm') 4889 self.assert_lint('#import "header_file.h"\n' 4890 'unsigned long long _length;', 4891 '', 4892 'foo.h') 4893 self.assert_lint('unsigned long long _length;\n' 4894 '@interface WebFullscreenWindow;', 4895 '', 4896 'foo.h') 4897 self.assert_lint('unsigned long long _length;\n' 4898 '@implementation WebFullscreenWindow;', 4899 '', 4900 'foo.h') 4901 self.assert_lint('unsigned long long _length;\n' 4902 '@class WebWindowFadeAnimation;', 4903 '', 4904 'foo.h') 4905 4906 # Variable name 'l' is easy to confuse with '1' 4907 self.assert_lint('int l;', 'l' + name_tooshort_error_message) 4908 self.assert_lint('size_t l;', 'l' + name_tooshort_error_message) 4909 self.assert_lint('long long l;', 'l' + name_tooshort_error_message) 4910 4911 # Pointers, references, functions, templates, and adjectives. 4912 self.assert_lint('char* under_score;', 4913 'under_score' + name_underscore_error_message) 4914 self.assert_lint('const int UNDER_SCORE;', 4915 'UNDER_SCORE' + name_underscore_error_message) 4916 self.assert_lint('static inline const char const& const under_score;', 4917 'under_score' + name_underscore_error_message) 4918 self.assert_lint('WebCore::RenderObject* under_score;', 4919 'under_score' + name_underscore_error_message) 4920 self.assert_lint('int func_name();', 4921 'func_name' + name_underscore_error_message) 4922 self.assert_lint('RefPtr<RenderObject*> under_score;', 4923 'under_score' + name_underscore_error_message) 4924 self.assert_lint('WTF::Vector<WTF::RefPtr<const RenderObject* const> > under_score;', 4925 'under_score' + name_underscore_error_message) 4926 self.assert_lint('int under_score[];', 4927 'under_score' + name_underscore_error_message) 4928 self.assert_lint('struct dirent* under_score;', 4929 'under_score' + name_underscore_error_message) 4930 self.assert_lint('long under_score;', 4931 'under_score' + name_underscore_error_message) 4932 self.assert_lint('long long under_score;', 4933 'under_score' + name_underscore_error_message) 4934 self.assert_lint('long double under_score;', 4935 'under_score' + name_underscore_error_message) 4936 self.assert_lint('long long int under_score;', 4937 'under_score' + name_underscore_error_message) 4938 4939 # Declarations in control statement. 4940 self.assert_lint('if (int under_score = 42) {', 4941 'under_score' + name_underscore_error_message) 4942 self.assert_lint('else if (int under_score = 42) {', 4943 'under_score' + name_underscore_error_message) 4944 self.assert_lint('for (int under_score = 42; cond; i++) {', 4945 'under_score' + name_underscore_error_message) 4946 self.assert_lint('while (foo & under_score = bar) {', 4947 'under_score' + name_underscore_error_message) 4948 self.assert_lint('for (foo * under_score = p; cond; i++) {', 4949 'under_score' + name_underscore_error_message) 4950 self.assert_lint('for (foo * under_score; cond; i++) {', 4951 'under_score' + name_underscore_error_message) 4952 self.assert_lint('while (foo & value_in_thirdparty_library) {', '') 4953 self.assert_lint('while (foo * value_in_thirdparty_library) {', '') 4954 self.assert_lint('if (mli && S_OK == mli->foo()) {', '') 4955 4956 # More member variables and functions. 4957 self.assert_lint('int SomeClass::s_validName', '') 4958 self.assert_lint('int m_under_score;', 4959 'm_under_score' + name_underscore_error_message) 4960 self.assert_lint('int SomeClass::s_under_score = 0;', 4961 'SomeClass::s_under_score' + name_underscore_error_message) 4962 self.assert_lint('int SomeClass::under_score = 0;', 4963 'SomeClass::under_score' + name_underscore_error_message) 4964 4965 # Other statements. 4966 self.assert_lint('return INT_MAX;', '') 4967 self.assert_lint('return_t under_score;', 4968 'under_score' + name_underscore_error_message) 4969 self.assert_lint('goto under_score;', 4970 'under_score' + name_underscore_error_message) 4971 self.assert_lint('delete static_cast<Foo*>(p);', '') 4972 4973 # Multiple variables in one line. 4974 self.assert_lint('void myFunction(int variable1, int another_variable);', 4975 'another_variable' + name_underscore_error_message) 4976 self.assert_lint('int variable1, another_variable;', 4977 'another_variable' + name_underscore_error_message) 4978 self.assert_lint('int first_variable, secondVariable;', 4979 'first_variable' + name_underscore_error_message) 4980 self.assert_lint('void my_function(int variable_1, int variable_2);', 4981 ['my_function' + name_underscore_error_message, 4982 'variable_1' + name_underscore_error_message, 4983 'variable_2' + name_underscore_error_message]) 4984 self.assert_lint('for (int variable_1, variable_2;;) {', 4985 ['variable_1' + name_underscore_error_message, 4986 'variable_2' + name_underscore_error_message]) 4987 4988 # There is an exception for op code functions but only in the JavaScriptCore directory. 4989 self.assert_lint('void this_op_code(int var1, int var2)', '', 'Source/JavaScriptCore/foo.cpp') 4990 self.assert_lint('void op_code(int var1, int var2)', '', 'Source/JavaScriptCore/foo.cpp') 4991 self.assert_lint('void this_op_code(int var1, int var2)', 'this_op_code' + name_underscore_error_message) 4992 4993 # GObject requires certain magical names in class declarations. 4994 self.assert_lint('void webkit_dom_object_init();', '') 4995 self.assert_lint('void webkit_dom_object_class_init();', '') 4996 4997 # There is an exception for GTK+ API. 4998 self.assert_lint('void webkit_web_view_load(int var1, int var2)', '', 'Source/Webkit/gtk/webkit/foo.cpp') 4999 self.assert_lint('void webkit_web_view_load(int var1, int var2)', '', 'Source/Webkit2/UIProcess/gtk/foo.cpp') 5000 5001 # Test that this doesn't also apply to files not in a 'gtk' directory. 5002 self.assert_lint('void webkit_web_view_load(int var1, int var2)', 5003 'webkit_web_view_load is incorrectly named. Don\'t use underscores in your identifier names.' 5004 ' [readability/naming/underscores] [4]', 'Source/Webkit/webkit/foo.cpp') 5005 # Test that this doesn't also apply to names that don't start with 'webkit_'. 5006 self.assert_lint_one_of_many_errors_re('void otherkit_web_view_load(int var1, int var2)', 5007 'otherkit_web_view_load is incorrectly named. Don\'t use underscores in your identifier names.' 5008 ' [readability/naming/underscores] [4]', 'Source/Webkit/webkit/foo.cpp') 5009 5010 # There is an exception for some unit tests that begin with "tst_". 5011 self.assert_lint('void tst_QWebFrame::arrayObjectEnumerable(int var1, int var2)', '') 5012 5013 # The Qt API uses names that begin with "qt_" or "_q_". 5014 self.assert_lint('void QTFrame::qt_drt_is_awesome(int var1, int var2)', '') 5015 self.assert_lint('void QTFrame::_q_drt_is_awesome(int var1, int var2)', '') 5016 self.assert_lint('void qt_drt_is_awesome(int var1, int var2);', '') 5017 self.assert_lint('void _q_drt_is_awesome(int var1, int var2);', '') 5018 5019 # Cairo forward-declarations should not be a failure. 5020 self.assert_lint('typedef struct _cairo cairo_t;', '') 5021 self.assert_lint('typedef struct _cairo_surface cairo_surface_t;', '') 5022 self.assert_lint('typedef struct _cairo_scaled_font cairo_scaled_font_t;', '') 5023 5024 # EFL forward-declarations should not be a failure. 5025 self.assert_lint('typedef struct _Ecore_Evas Ecore_Evas;', '') 5026 self.assert_lint('typedef struct _Ecore_Pipe Ecore_Pipe;', '') 5027 self.assert_lint('typedef struct _Eina_Rectangle Eina_Rectangle;', '') 5028 self.assert_lint('typedef struct _Evas_Object Evas_Object;', '') 5029 self.assert_lint('typedef struct _Ewk_History_Item Ewk_History_Item;', '') 5030 5031 # NPAPI functions that start with NPN_, NPP_ or NP_ are allowed. 5032 self.assert_lint('void NPN_Status(NPP, const char*)', '') 5033 self.assert_lint('NPError NPP_SetWindow(NPP instance, NPWindow *window)', '') 5034 self.assert_lint('NPObject* NP_Allocate(NPP, NPClass*)', '') 5035 5036 # const_iterator is allowed as well. 5037 self.assert_lint('typedef VectorType::const_iterator const_iterator;', '') 5038 5039 # vm_throw is allowed as well. 5040 self.assert_lint('int vm_throw;', '') 5041 5042 # Attributes. 5043 self.assert_lint('int foo ALLOW_UNUSED;', '') 5044 self.assert_lint('int foo_error ALLOW_UNUSED;', 'foo_error' + name_underscore_error_message) 5045 self.assert_lint('ThreadFunctionInvocation* leakedInvocation ALLOW_UNUSED = invocation.leakPtr()', '') 5046 5047 # Bitfields. 5048 self.assert_lint('unsigned _fillRule : 1;', 5049 '_fillRule' + name_underscore_error_message) 5050 5051 # new operators in initialization. 5052 self.assert_lint('OwnPtr<uint32_t> variable(new uint32_t);', '') 5053 self.assert_lint('OwnPtr<uint32_t> variable(new (expr) uint32_t);', '') 5054 self.assert_lint('OwnPtr<uint32_t> under_score(new uint32_t);', 5055 'under_score' + name_underscore_error_message) 5056 5057 # Conversion operator declaration. 5058 self.assert_lint('operator int64_t();', '') 5059 5060 def test_parameter_names(self): 5061 # Leave meaningless variable names out of function declarations. 5062 meaningless_variable_name_error_message = 'The parameter name "%s" adds no information, so it should be removed. [readability/parameter_name] [5]' 5063 5064 parameter_error_rules = ('-', 5065 '+readability/parameter_name') 5066 # No variable name, so no error. 5067 self.assertEqual('', 5068 self.perform_lint('void func(int);', 'test.cpp', parameter_error_rules)) 5069 5070 # Verify that copying the name of the set function causes the error (with some odd casing). 5071 self.assertEqual(meaningless_variable_name_error_message % 'itemCount', 5072 self.perform_lint('void setItemCount(size_t itemCount);', 'test.cpp', parameter_error_rules)) 5073 self.assertEqual(meaningless_variable_name_error_message % 'abcCount', 5074 self.perform_lint('void setABCCount(size_t abcCount);', 'test.cpp', parameter_error_rules)) 5075 5076 # Verify that copying a type name will trigger the warning (even if the type is a template parameter). 5077 self.assertEqual(meaningless_variable_name_error_message % 'context', 5078 self.perform_lint('void funct(PassRefPtr<ScriptExecutionContext> context);', 'test.cpp', parameter_error_rules)) 5079 5080 # Verify that acronyms as variable names trigger the error (for both set functions and type names). 5081 self.assertEqual(meaningless_variable_name_error_message % 'ec', 5082 self.perform_lint('void setExceptionCode(int ec);', 'test.cpp', parameter_error_rules)) 5083 self.assertEqual(meaningless_variable_name_error_message % 'ec', 5084 self.perform_lint('void funct(ExceptionCode ec);', 'test.cpp', parameter_error_rules)) 5085 5086 # 'object' alone, appended, or as part of an acronym is meaningless. 5087 self.assertEqual(meaningless_variable_name_error_message % 'object', 5088 self.perform_lint('void funct(RenderView object);', 'test.cpp', parameter_error_rules)) 5089 self.assertEqual(meaningless_variable_name_error_message % 'viewObject', 5090 self.perform_lint('void funct(RenderView viewObject);', 'test.cpp', parameter_error_rules)) 5091 self.assertEqual(meaningless_variable_name_error_message % 'rvo', 5092 self.perform_lint('void funct(RenderView rvo);', 'test.cpp', parameter_error_rules)) 5093 5094 # Check that r, g, b, and a are allowed. 5095 self.assertEqual('', 5096 self.perform_lint('void setRGBAValues(int r, int g, int b, int a);', 'test.cpp', parameter_error_rules)) 5097 5098 # Verify that a simple substring match isn't done which would cause false positives. 5099 self.assertEqual('', 5100 self.perform_lint('void setNateLateCount(size_t elate);', 'test.cpp', parameter_error_rules)) 5101 self.assertEqual('', 5102 self.perform_lint('void funct(NateLate elate);', 'test.cpp', parameter_error_rules)) 5103 5104 # Don't have generate warnings for functions (only declarations). 5105 self.assertEqual('', 5106 self.perform_lint('void funct(PassRefPtr<ScriptExecutionContext> context)\n' 5107 '{\n' 5108 '}\n', 'test.cpp', parameter_error_rules)) 5109 5110 def test_comments(self): 5111 # A comment at the beginning of a line is ok. 5112 self.assert_lint('// comment', '') 5113 self.assert_lint(' // comment', '') 5114 5115 self.assert_lint('} // namespace WebCore', 5116 'One space before end of line comments' 5117 ' [whitespace/comments] [5]') 5118 5119 def test_webkit_export_check(self): 5120 webkit_export_error_rules = ('-', 5121 '+readability/webkit_export') 5122 self.assertEqual('', 5123 self.perform_lint('WEBKIT_EXPORT int foo();\n', 5124 'WebKit/chromium/public/test.h', 5125 webkit_export_error_rules)) 5126 self.assertEqual('', 5127 self.perform_lint('WEBKIT_EXPORT int foo();\n', 5128 'WebKit/chromium/tests/test.h', 5129 webkit_export_error_rules)) 5130 self.assertEqual('WEBKIT_EXPORT should only be used in header files. [readability/webkit_export] [5]', 5131 self.perform_lint('WEBKIT_EXPORT int foo();\n', 5132 'WebKit/chromium/public/test.cpp', 5133 webkit_export_error_rules)) 5134 self.assertEqual('WEBKIT_EXPORT should only appear in the chromium public (or tests) directory. [readability/webkit_export] [5]', 5135 self.perform_lint('WEBKIT_EXPORT int foo();\n', 5136 'WebKit/chromium/src/test.h', 5137 webkit_export_error_rules)) 5138 self.assertEqual('WEBKIT_EXPORT should not be used on a function with a body. [readability/webkit_export] [5]', 5139 self.perform_lint('WEBKIT_EXPORT int foo() { }\n', 5140 'WebKit/chromium/public/test.h', 5141 webkit_export_error_rules)) 5142 self.assertEqual('WEBKIT_EXPORT should not be used on a function with a body. [readability/webkit_export] [5]', 5143 self.perform_lint('WEBKIT_EXPORT inline int foo()\n' 5144 '{\n' 5145 '}\n', 5146 'WebKit/chromium/public/test.h', 5147 webkit_export_error_rules)) 5148 self.assertEqual('WEBKIT_EXPORT should not be used with a pure virtual function. [readability/webkit_export] [5]', 5149 self.perform_lint('{}\n' 5150 'WEBKIT_EXPORT\n' 5151 'virtual\n' 5152 'int\n' 5153 'foo() = 0;\n', 5154 'WebKit/chromium/public/test.h', 5155 webkit_export_error_rules)) 5156 self.assertEqual('', 5157 self.perform_lint('{}\n' 5158 'WEBKIT_EXPORT\n' 5159 'virtual\n' 5160 'int\n' 5161 'foo() = 0;\n', 5162 'test.h', 5163 webkit_export_error_rules)) 5164 5165 def test_other(self): 5166 # FIXME: Implement this. 5167 pass 5168 5169 5170 class CppCheckerTest(unittest.TestCase): 5171 5172 """Tests CppChecker class.""" 5173 5174 def mock_handle_style_error(self): 5175 pass 5176 5177 def _checker(self): 5178 return CppChecker("foo", "h", self.mock_handle_style_error, 3) 5179 5180 def test_init(self): 5181 """Test __init__ constructor.""" 5182 checker = self._checker() 5183 self.assertEqual(checker.file_extension, "h") 5184 self.assertEqual(checker.file_path, "foo") 5185 self.assertEqual(checker.handle_style_error, self.mock_handle_style_error) 5186 self.assertEqual(checker.min_confidence, 3) 5187 5188 def test_eq(self): 5189 """Test __eq__ equality function.""" 5190 checker1 = self._checker() 5191 checker2 = self._checker() 5192 5193 # == calls __eq__. 5194 self.assertTrue(checker1 == checker2) 5195 5196 def mock_handle_style_error2(self): 5197 pass 5198 5199 # Verify that a difference in any argument cause equality to fail. 5200 checker = CppChecker("foo", "h", self.mock_handle_style_error, 3) 5201 self.assertFalse(checker == CppChecker("bar", "h", self.mock_handle_style_error, 3)) 5202 self.assertFalse(checker == CppChecker("foo", "c", self.mock_handle_style_error, 3)) 5203 self.assertFalse(checker == CppChecker("foo", "h", mock_handle_style_error2, 3)) 5204 self.assertFalse(checker == CppChecker("foo", "h", self.mock_handle_style_error, 4)) 5205 5206 def test_ne(self): 5207 """Test __ne__ inequality function.""" 5208 checker1 = self._checker() 5209 checker2 = self._checker() 5210 5211 # != calls __ne__. 5212 # By default, __ne__ always returns true on different objects. 5213 # Thus, just check the distinguishing case to verify that the 5214 # code defines __ne__. 5215 self.assertFalse(checker1 != checker2) 5216