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