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