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