1 # -*- coding: utf-8; -*-
3 # Copyright (C) 2011 Google Inc. All rights reserved.
4 # Copyright (C) 2009 Torch Mobile Inc.
5 # Copyright (C) 2009 Apple Inc. All rights reserved.
6 # Copyright (C) 2010 Chris Jerdonek (cjerdonek@webkit.org)
8 # Redistribution and use in source and binary forms, with or without
9 # modification, are permitted provided that the following conditions are
12 # * Redistributions of source code must retain the above copyright
13 # notice, this list of conditions and the following disclaimer.
14 # * Redistributions in binary form must reproduce the above
15 # copyright notice, this list of conditions and the following disclaimer
16 # in the documentation and/or other materials provided with the
18 # * Neither the name of Google Inc. nor the names of its
19 # contributors may be used to endorse or promote products derived from
20 # this software without specific prior written permission.
22 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 """Unit test for cpp_style.py."""
36 # FIXME: Add a good test that tests UpdateIncludeState.
43 import cpp as cpp_style
44 from cpp import CppChecker
45 from ..filter import FilterConfiguration
46 from webkitpy.common.system.filesystem import FileSystem
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.
52 _all_style_categories = CppChecker.categories
53 # This is a list including all categories seen in any unit test.
54 _seen_style_categories = {}
56 def __init__(self, assert_fn, filter=None, lines_to_check=None):
57 """assert_fn: a function to call when we notice a problem.
58 filter: filters the errors that we are concerned about."""
59 self._assert_fn = assert_fn
61 self._lines_to_check = lines_to_check
63 filter = FilterConfiguration()
66 def __call__(self, line_number, category, confidence, message):
67 self._assert_fn(category in self._all_style_categories,
68 'Message "%s" has category "%s",'
69 ' which is not in STYLE_CATEGORIES' % (message, category))
71 if self._lines_to_check and not line_number in self._lines_to_check:
74 if self._filter.should_check(category, ""):
75 self._seen_style_categories[category] = 1
76 self._errors.append('%s [%s] [%d]' % (message, category, confidence))
80 if len(self._errors) < 2:
81 return ''.join(self._errors) # Most tests expect to have a string.
83 return self._errors # Let's give a list if there is more than one.
85 def result_list(self):
88 def verify_all_categories_are_seen(self):
89 """Fails if there's a category in _all_style_categories - _seen_style_categories.
91 This should only be called after all tests are run, so
92 _seen_style_categories has had a chance to fully populate. Since
93 this isn't called from within the normal unittest framework, we
94 can't use the normal unittest assert macros. Instead we just exit
95 when we see an error. Good thing this test is always run last!
97 for category in self._all_style_categories:
98 if category not in self._seen_style_categories:
100 sys.exit('FATAL ERROR: There are no tests for category "%s"' % category)
103 class CppFunctionsTest(unittest.TestCase):
105 """Supports testing functions that do not need CppStyleTestBase."""
107 def test_convert_to_lower_with_underscores(self):
108 self.assertEqual(cpp_style._convert_to_lower_with_underscores('ABC'), 'abc')
109 self.assertEqual(cpp_style._convert_to_lower_with_underscores('aB'), 'a_b')
110 self.assertEqual(cpp_style._convert_to_lower_with_underscores('isAName'), 'is_a_name')
111 self.assertEqual(cpp_style._convert_to_lower_with_underscores('AnotherTest'), 'another_test')
112 self.assertEqual(cpp_style._convert_to_lower_with_underscores('PassRefPtr<MyClass>'), 'pass_ref_ptr<my_class>')
113 self.assertEqual(cpp_style._convert_to_lower_with_underscores('_ABC'), '_abc')
115 def test_create_acronym(self):
116 self.assertEqual(cpp_style._create_acronym('ABC'), 'ABC')
117 self.assertEqual(cpp_style._create_acronym('IsAName'), 'IAN')
118 self.assertEqual(cpp_style._create_acronym('PassRefPtr<MyClass>'), 'PRP<MC>')
120 def test_is_c_or_objective_c(self):
121 clean_lines = cpp_style.CleansedLines([''])
122 clean_objc_lines = cpp_style.CleansedLines(['#import "header.h"'])
123 self.assertTrue(cpp_style._FileState(clean_lines, 'c').is_c_or_objective_c())
124 self.assertTrue(cpp_style._FileState(clean_lines, 'm').is_c_or_objective_c())
125 self.assertFalse(cpp_style._FileState(clean_lines, 'cpp').is_c_or_objective_c())
126 self.assertFalse(cpp_style._FileState(clean_lines, 'cc').is_c_or_objective_c())
127 self.assertFalse(cpp_style._FileState(clean_lines, 'h').is_c_or_objective_c())
128 self.assertTrue(cpp_style._FileState(clean_objc_lines, 'h').is_c_or_objective_c())
130 def test_parameter(self):
132 parameter = cpp_style.Parameter('ExceptionCode', 13, 1)
133 self.assertEqual(parameter.type, 'ExceptionCode')
134 self.assertEqual(parameter.name, '')
135 self.assertEqual(parameter.row, 1)
137 # Test type and name.
138 parameter = cpp_style.Parameter('PassRefPtr<MyClass> parent', 19, 1)
139 self.assertEqual(parameter.type, 'PassRefPtr<MyClass>')
140 self.assertEqual(parameter.name, 'parent')
141 self.assertEqual(parameter.row, 1)
143 # Test type, no name, with default value.
144 parameter = cpp_style.Parameter('MyClass = 0', 7, 0)
145 self.assertEqual(parameter.type, 'MyClass')
146 self.assertEqual(parameter.name, '')
147 self.assertEqual(parameter.row, 0)
149 # Test type, name, and default value.
150 parameter = cpp_style.Parameter('MyClass a = 0', 7, 0)
151 self.assertEqual(parameter.type, 'MyClass')
152 self.assertEqual(parameter.name, 'a')
153 self.assertEqual(parameter.row, 0)
155 def test_single_line_view(self):
156 start_position = cpp_style.Position(row=1, column=1)
157 end_position = cpp_style.Position(row=3, column=1)
158 single_line_view = cpp_style.SingleLineView(['0', 'abcde', 'fgh', 'i'], start_position, end_position)
159 self.assertEqual(single_line_view.single_line, 'bcde fgh i')
160 self.assertEqual(single_line_view.convert_column_to_row(0), 1)
161 self.assertEqual(single_line_view.convert_column_to_row(4), 1)
162 self.assertEqual(single_line_view.convert_column_to_row(5), 2)
163 self.assertEqual(single_line_view.convert_column_to_row(8), 2)
164 self.assertEqual(single_line_view.convert_column_to_row(9), 3)
165 self.assertEqual(single_line_view.convert_column_to_row(100), 3)
167 start_position = cpp_style.Position(row=0, column=3)
168 end_position = cpp_style.Position(row=0, column=4)
169 single_line_view = cpp_style.SingleLineView(['abcdef'], start_position, end_position)
170 self.assertEqual(single_line_view.single_line, 'd')
172 def test_create_skeleton_parameters(self):
173 self.assertEqual(cpp_style.create_skeleton_parameters(''), '')
174 self.assertEqual(cpp_style.create_skeleton_parameters(' '), ' ')
175 self.assertEqual(cpp_style.create_skeleton_parameters('long'), 'long,')
176 self.assertEqual(cpp_style.create_skeleton_parameters('const unsigned long int'), ' int,')
177 self.assertEqual(cpp_style.create_skeleton_parameters('long int*'), ' int ,')
178 self.assertEqual(cpp_style.create_skeleton_parameters('PassRefPtr<Foo> a'), 'PassRefPtr a,')
179 self.assertEqual(cpp_style.create_skeleton_parameters(
180 'ComplexTemplate<NestedTemplate1<MyClass1, MyClass2>, NestedTemplate1<MyClass1, MyClass2> > param, int second'),
181 'ComplexTemplate param, int second,')
182 self.assertEqual(cpp_style.create_skeleton_parameters('int = 0, Namespace::Type& a'), 'int , Type a,')
183 # Create skeleton parameters is a bit too aggressive with function variables, but
184 # it allows for parsing other parameters and declarations like this are rare.
185 self.assertEqual(cpp_style.create_skeleton_parameters('void (*fn)(int a, int b), Namespace::Type& a'),
188 # This doesn't look like functions declarations but the simplifications help to eliminate false positives.
189 self.assertEqual(cpp_style.create_skeleton_parameters('b{d}'), 'b ,')
191 def test_find_parameter_name_index(self):
192 self.assertEqual(cpp_style.find_parameter_name_index(' int a '), 5)
193 self.assertEqual(cpp_style.find_parameter_name_index(' PassRefPtr '), 16)
194 self.assertEqual(cpp_style.find_parameter_name_index('double'), 6)
196 def test_parameter_list(self):
197 elided_lines = ['int blah(PassRefPtr<MyClass> paramName,',
198 'const Other1Class& foo,',
199 'const ComplexTemplate<Class1, NestedTemplate<P1, P2> >* const * param = new ComplexTemplate<Class1, NestedTemplate<P1, P2> >(34, 42),',
200 'int* myCount = 0);']
201 start_position = cpp_style.Position(row=0, column=8)
202 end_position = cpp_style.Position(row=3, column=16)
204 expected_parameters = ({'type': 'PassRefPtr<MyClass>', 'name': 'paramName', 'row': 0},
205 {'type': 'const Other1Class&', 'name': 'foo', 'row': 1},
206 {'type': 'const ComplexTemplate<Class1, NestedTemplate<P1, P2> >* const *', 'name': 'param', 'row': 2},
207 {'type': 'int*', 'name': 'myCount', 'row': 3})
209 for parameter in cpp_style.parameter_list(elided_lines, start_position, end_position):
210 expected_parameter = expected_parameters[index]
211 self.assertEqual(parameter.type, expected_parameter['type'])
212 self.assertEqual(parameter.name, expected_parameter['name'])
213 self.assertEqual(parameter.row, expected_parameter['row'])
215 self.assertEqual(index, len(expected_parameters))
217 def test_check_parameter_against_text(self):
218 error_collector = ErrorCollector(self.assertTrue)
219 parameter = cpp_style.Parameter('FooF ooF', 4, 1)
220 self.assertFalse(cpp_style._check_parameter_name_against_text(parameter, 'FooF', error_collector))
221 self.assertEqual(error_collector.results(),
222 'The parameter name "ooF" adds no information, so it should be removed. [readability/parameter_name] [5]')
224 class CppStyleTestBase(unittest.TestCase):
225 """Provides some useful helper functions for cpp_style tests.
228 min_confidence: An integer that is the current minimum confidence
233 # FIXME: Refactor the unit tests so the confidence level is passed
234 # explicitly, just like it is in the real code.
237 # Helper function to avoid needing to explicitly pass confidence
238 # in all the unit test calls to cpp_style.process_file_data().
239 def process_file_data(self, filename, file_extension, lines, error, fs=None):
240 """Call cpp_style.process_file_data() with the min_confidence."""
241 return cpp_style.process_file_data(filename, file_extension, lines,
242 error, self.min_confidence, fs)
244 def perform_lint(self, code, filename, basic_error_rules, fs=None, lines_to_check=None):
245 error_collector = ErrorCollector(self.assertTrue, FilterConfiguration(basic_error_rules), lines_to_check)
246 lines = code.split('\n')
247 extension = filename.split('.')[1]
248 self.process_file_data(filename, extension, lines, error_collector, fs)
249 return error_collector.results()
251 # Perform lint on single line of input and return the error message.
252 def perform_single_line_lint(self, code, filename):
253 basic_error_rules = ('-build/header_guard',
255 '-readability/fn_size',
256 '-readability/parameter_name',
257 '-readability/pass_ptr',
258 '-whitespace/ending_newline')
259 return self.perform_lint(code, filename, basic_error_rules)
261 # Perform lint over multiple lines and return the error message.
262 def perform_multi_line_lint(self, code, file_extension):
263 basic_error_rules = ('-build/header_guard',
265 '-readability/parameter_name',
266 '-whitespace/ending_newline')
267 return self.perform_lint(code, 'test.' + file_extension, basic_error_rules)
269 # Only keep some errors related to includes, namespaces and rtti.
270 def perform_language_rules_check(self, filename, code, lines_to_check=None):
271 basic_error_rules = ('-',
273 '+build/include_order',
276 return self.perform_lint(code, filename, basic_error_rules, lines_to_check=lines_to_check)
278 # Only keep function length errors.
279 def perform_function_lengths_check(self, code):
280 basic_error_rules = ('-',
281 '+readability/fn_size')
282 return self.perform_lint(code, 'test.cpp', basic_error_rules)
284 # Only keep pass ptr errors.
285 def perform_pass_ptr_check(self, code):
286 basic_error_rules = ('-',
287 '+readability/pass_ptr')
288 return self.perform_lint(code, 'test.cpp', basic_error_rules)
290 # Only keep leaky pattern errors.
291 def perform_leaky_pattern_check(self, code):
292 basic_error_rules = ('-',
293 '+runtime/leaky_pattern')
294 return self.perform_lint(code, 'test.cpp', basic_error_rules)
296 # Only include what you use errors.
297 def perform_include_what_you_use(self, code, filename='foo.h', fs=None):
298 basic_error_rules = ('-',
299 '+build/include_what_you_use')
300 return self.perform_lint(code, filename, basic_error_rules, fs)
302 def perform_avoid_static_cast_of_objects(self, code, filename='foo.cpp', fs=None):
303 basic_error_rules = ('-',
305 return self.perform_lint(code, filename, basic_error_rules, fs)
307 # Perform lint and compare the error message with "expected_message".
308 def assert_lint(self, code, expected_message, file_name='foo.cpp'):
309 self.assertEqual(expected_message, self.perform_single_line_lint(code, file_name))
311 def assert_lint_one_of_many_errors_re(self, code, expected_message_re, file_name='foo.cpp'):
312 messages = self.perform_single_line_lint(code, file_name)
313 for message in messages:
314 if re.search(expected_message_re, message):
317 self.assertEqual(expected_message_re, messages)
319 def assert_multi_line_lint(self, code, expected_message, file_name='foo.h'):
320 file_extension = file_name[file_name.rfind('.') + 1:]
321 self.assertEqual(expected_message, self.perform_multi_line_lint(code, file_extension))
323 def assert_multi_line_lint_re(self, code, expected_message_re, file_name='foo.h'):
324 file_extension = file_name[file_name.rfind('.') + 1:]
325 message = self.perform_multi_line_lint(code, file_extension)
326 if not re.search(expected_message_re, message):
327 self.fail('Message was:\n' + message + 'Expected match to "' + expected_message_re + '"')
329 def assert_language_rules_check(self, file_name, code, expected_message, lines_to_check=None):
330 self.assertEqual(expected_message,
331 self.perform_language_rules_check(file_name, code, lines_to_check))
333 def assert_include_what_you_use(self, code, expected_message):
334 self.assertEqual(expected_message,
335 self.perform_include_what_you_use(code))
337 def assert_blank_lines_check(self, lines, start_errors, end_errors):
338 error_collector = ErrorCollector(self.assertTrue)
339 self.process_file_data('foo.cpp', 'cpp', lines, error_collector)
342 error_collector.results().count(
343 'Blank line at the start of a code block. Is this needed?'
344 ' [whitespace/blank_line] [2]'))
347 error_collector.results().count(
348 'Blank line at the end of a code block. Is this needed?'
349 ' [whitespace/blank_line] [3]'))
351 def assert_positions_equal(self, position, tuple_position):
352 """Checks if the two positions are equal.
354 position: a cpp_style.Position object.
355 tuple_position: a tuple (row, column) to compare against."""
356 self.assertEqual(position, cpp_style.Position(tuple_position[0], tuple_position[1]),
357 'position %s, tuple_position %s' % (position, tuple_position))
360 class FunctionDetectionTest(CppStyleTestBase):
361 def perform_function_detection(self, lines, function_information, detection_line=0):
362 clean_lines = cpp_style.CleansedLines(lines)
363 function_state = cpp_style._FunctionState(5)
364 error_collector = ErrorCollector(self.assertTrue)
365 cpp_style.detect_functions(clean_lines, detection_line, function_state, error_collector)
366 if not function_information:
367 self.assertEqual(function_state.in_a_function, False)
369 self.assertEqual(function_state.in_a_function, True)
370 self.assertEqual(function_state.current_function, function_information['name'] + '()')
371 self.assertEqual(function_state.modifiers_and_return_type(), function_information['modifiers_and_return_type'])
372 self.assertEqual(function_state.is_pure, function_information['is_pure'])
373 self.assertEqual(function_state.is_declaration, function_information['is_declaration'])
374 self.assert_positions_equal(function_state.function_name_start_position, function_information['function_name_start_position'])
375 self.assert_positions_equal(function_state.parameter_start_position, function_information['parameter_start_position'])
376 self.assert_positions_equal(function_state.parameter_end_position, function_information['parameter_end_position'])
377 self.assert_positions_equal(function_state.body_start_position, function_information['body_start_position'])
378 self.assert_positions_equal(function_state.end_position, function_information['end_position'])
379 expected_parameters = function_information.get('parameter_list')
380 if expected_parameters:
381 actual_parameters = function_state.parameter_list()
382 self.assertEqual(len(actual_parameters), len(expected_parameters))
383 for index in range(len(expected_parameters)):
384 actual_parameter = actual_parameters[index]
385 expected_parameter = expected_parameters[index]
386 self.assertEqual(actual_parameter.type, expected_parameter['type'])
387 self.assertEqual(actual_parameter.name, expected_parameter['name'])
388 self.assertEqual(actual_parameter.row, expected_parameter['row'])
390 def test_basic_function_detection(self):
391 self.perform_function_detection(
392 ['void theTestFunctionName(int) {',
394 {'name': 'theTestFunctionName',
395 'modifiers_and_return_type': 'void',
396 'function_name_start_position': (0, 5),
397 'parameter_start_position': (0, 24),
398 'parameter_end_position': (0, 29),
399 'body_start_position': (0, 30),
400 'end_position': (1, 1),
402 'is_declaration': False})
404 def test_function_declaration_detection(self):
405 self.perform_function_detection(
406 ['void aFunctionName(int);'],
407 {'name': 'aFunctionName',
408 'modifiers_and_return_type': 'void',
409 'function_name_start_position': (0, 5),
410 'parameter_start_position': (0, 18),
411 'parameter_end_position': (0, 23),
412 'body_start_position': (0, 23),
413 'end_position': (0, 24),
415 'is_declaration': True})
417 self.perform_function_detection(
418 ['CheckedInt<T> operator /(const CheckedInt<T> &lhs, const CheckedInt<T> &rhs);'],
419 {'name': 'operator /',
420 'modifiers_and_return_type': 'CheckedInt<T>',
421 'function_name_start_position': (0, 14),
422 'parameter_start_position': (0, 24),
423 'parameter_end_position': (0, 76),
424 'body_start_position': (0, 76),
425 'end_position': (0, 77),
427 'is_declaration': True})
429 self.perform_function_detection(
430 ['CheckedInt<T> operator -(const CheckedInt<T> &lhs, const CheckedInt<T> &rhs);'],
431 {'name': 'operator -',
432 'modifiers_and_return_type': 'CheckedInt<T>',
433 'function_name_start_position': (0, 14),
434 'parameter_start_position': (0, 24),
435 'parameter_end_position': (0, 76),
436 'body_start_position': (0, 76),
437 'end_position': (0, 77),
439 'is_declaration': True})
441 self.perform_function_detection(
442 ['CheckedInt<T> operator !=(const CheckedInt<T> &lhs, const CheckedInt<T> &rhs);'],
443 {'name': 'operator !=',
444 'modifiers_and_return_type': 'CheckedInt<T>',
445 'function_name_start_position': (0, 14),
446 'parameter_start_position': (0, 25),
447 'parameter_end_position': (0, 77),
448 'body_start_position': (0, 77),
449 'end_position': (0, 78),
451 'is_declaration': True})
453 self.perform_function_detection(
454 ['CheckedInt<T> operator +(const CheckedInt<T> &lhs, const CheckedInt<T> &rhs);'],
455 {'name': 'operator +',
456 'modifiers_and_return_type': 'CheckedInt<T>',
457 'function_name_start_position': (0, 14),
458 'parameter_start_position': (0, 24),
459 'parameter_end_position': (0, 76),
460 'body_start_position': (0, 76),
461 'end_position': (0, 77),
463 'is_declaration': True})
465 def test_pure_function_detection(self):
466 self.perform_function_detection(
467 ['virtual void theTestFunctionName(int = 0);'],
468 {'name': 'theTestFunctionName',
469 'modifiers_and_return_type': 'virtual void',
470 'function_name_start_position': (0, 13),
471 'parameter_start_position': (0, 32),
472 'parameter_end_position': (0, 41),
473 'body_start_position': (0, 41),
474 'end_position': (0, 42),
476 'is_declaration': True})
478 self.perform_function_detection(
479 ['virtual void theTestFunctionName(int) = 0;'],
480 {'name': 'theTestFunctionName',
481 'modifiers_and_return_type': 'virtual void',
482 'function_name_start_position': (0, 13),
483 'parameter_start_position': (0, 32),
484 'parameter_end_position': (0, 37),
485 'body_start_position': (0, 41),
486 'end_position': (0, 42),
488 'is_declaration': True})
490 # Hopefully, no one writes code like this but it is a tricky case.
491 self.perform_function_detection(
492 ['virtual void theTestFunctionName(int)',
495 {'name': 'theTestFunctionName',
496 'modifiers_and_return_type': 'virtual void',
497 'function_name_start_position': (0, 13),
498 'parameter_start_position': (0, 32),
499 'parameter_end_position': (0, 37),
500 'body_start_position': (2, 3),
501 'end_position': (2, 4),
503 'is_declaration': True})
505 def test_ignore_macros(self):
506 self.perform_function_detection(['void aFunctionName(int); \\'], None)
508 def test_non_functions(self):
509 # This case exposed an error because the open brace was in quotes.
510 self.perform_function_detection(
512 ' "stmdb sp!, {r1-r3}" "\n"',
514 # This isn't a function but it looks like one to our simple
515 # algorithm and that is ok.
517 'modifiers_and_return_type': '',
518 'function_name_start_position': (0, 0),
519 'parameter_start_position': (0, 3),
520 'parameter_end_position': (2, 1),
521 'body_start_position': (2, 1),
522 'end_position': (2, 2),
524 'is_declaration': True})
526 # Simple test case with something that is not a function.
527 self.perform_function_detection(['class Stuff;'], None)
529 def test_parameter_list(self):
530 # A function with no arguments.
531 function_state = self.perform_function_detection(
532 ['void functionName();'],
533 {'name': 'functionName',
534 'modifiers_and_return_type': 'void',
535 'function_name_start_position': (0, 5),
536 'parameter_start_position': (0, 17),
537 'parameter_end_position': (0, 19),
538 'body_start_position': (0, 19),
539 'end_position': (0, 20),
541 'is_declaration': True,
542 'parameter_list': ()})
544 # A function with one argument.
545 function_state = self.perform_function_detection(
546 ['void functionName(int);'],
547 {'name': 'functionName',
548 'modifiers_and_return_type': 'void',
549 'function_name_start_position': (0, 5),
550 'parameter_start_position': (0, 17),
551 'parameter_end_position': (0, 22),
552 'body_start_position': (0, 22),
553 'end_position': (0, 23),
555 'is_declaration': True,
557 ({'type': 'int', 'name': '', 'row': 0},)})
559 # A function with unsigned and short arguments
560 function_state = self.perform_function_detection(
561 ['void functionName(unsigned a, short b, long c, long long short unsigned int);'],
562 {'name': 'functionName',
563 'modifiers_and_return_type': 'void',
564 'function_name_start_position': (0, 5),
565 'parameter_start_position': (0, 17),
566 'parameter_end_position': (0, 76),
567 'body_start_position': (0, 76),
568 'end_position': (0, 77),
570 'is_declaration': True,
572 ({'type': 'unsigned', 'name': 'a', 'row': 0},
573 {'type': 'short', 'name': 'b', 'row': 0},
574 {'type': 'long', 'name': 'c', 'row': 0},
575 {'type': 'long long short unsigned int', 'name': '', 'row': 0})})
577 # Some parameter type with modifiers and no parameter names.
578 function_state = self.perform_function_detection(
579 ['virtual void determineARIADropEffects(Vector<String>*&, const unsigned long int*&, const MediaPlayer::Preload, Other<Other2, Other3<P1, P2> >, int);'],
580 {'name': 'determineARIADropEffects',
581 'modifiers_and_return_type': 'virtual void',
582 'parameter_start_position': (0, 37),
583 'function_name_start_position': (0, 13),
584 'parameter_end_position': (0, 147),
585 'body_start_position': (0, 147),
586 'end_position': (0, 148),
588 'is_declaration': True,
590 ({'type': 'Vector<String>*&', 'name': '', 'row': 0},
591 {'type': 'const unsigned long int*&', 'name': '', 'row': 0},
592 {'type': 'const MediaPlayer::Preload', 'name': '', 'row': 0},
593 {'type': 'Other<Other2, Other3<P1, P2> >', 'name': '', 'row': 0},
594 {'type': 'int', 'name': '', 'row': 0})})
596 # Try parsing a function with a very complex definition.
597 function_state = self.perform_function_detection(
598 ['#define MyMacro(a) a',
600 'AnotherTemplate<Class1, Class2> aFunctionName(PassRefPtr<MyClass> paramName,',
601 'const Other1Class& foo,',
602 'const ComplexTemplate<Class1, NestedTemplate<P1, P2> >* const * param = new ComplexTemplate<Class1, NestedTemplate<P1, P2> >(34, 42),',
603 'int* myCount = 0);'],
604 {'name': 'aFunctionName',
605 'modifiers_and_return_type': 'virtual AnotherTemplate<Class1, Class2>',
606 'function_name_start_position': (2, 32),
607 'parameter_start_position': (2, 45),
608 'parameter_end_position': (5, 17),
609 'body_start_position': (5, 17),
610 'end_position': (5, 18),
612 'is_declaration': True,
614 ({'type': 'PassRefPtr<MyClass>', 'name': 'paramName', 'row': 2},
615 {'type': 'const Other1Class&', 'name': 'foo', 'row': 3},
616 {'type': 'const ComplexTemplate<Class1, NestedTemplate<P1, P2> >* const *', 'name': 'param', 'row': 4},
617 {'type': 'int*', 'name': 'myCount', 'row': 5})},
621 class CppStyleTest(CppStyleTestBase):
623 def test_asm_lines_ignored(self):
625 '__asm mov [registration], eax',
628 # Test get line width.
629 def test_get_line_width(self):
630 self.assertEqual(0, cpp_style.get_line_width(''))
631 self.assertEqual(10, cpp_style.get_line_width(u'x' * 10))
632 self.assertEqual(16, cpp_style.get_line_width(u'都|道|府|県|支庁'))
634 def test_find_next_multi_line_comment_start(self):
635 self.assertEqual(1, cpp_style.find_next_multi_line_comment_start([''], 0))
637 lines = ['a', 'b', '/* c']
638 self.assertEqual(2, cpp_style.find_next_multi_line_comment_start(lines, 0))
640 lines = ['char a[] = "/*";'] # not recognized as comment.
641 self.assertEqual(1, cpp_style.find_next_multi_line_comment_start(lines, 0))
643 def test_find_next_multi_line_comment_end(self):
644 self.assertEqual(1, cpp_style.find_next_multi_line_comment_end([''], 0))
645 lines = ['a', 'b', ' c */']
646 self.assertEqual(2, cpp_style.find_next_multi_line_comment_end(lines, 0))
648 def test_remove_multi_line_comments_from_range(self):
649 lines = ['a', ' /* comment ', ' * still comment', ' comment */ ', 'b']
650 cpp_style.remove_multi_line_comments_from_range(lines, 1, 4)
651 self.assertEqual(['a', '// dummy', '// dummy', '// dummy', 'b'], lines)
653 def test_position(self):
654 position = cpp_style.Position(3, 4)
655 self.assert_positions_equal(position, (3, 4))
656 self.assertEqual(position.row, 3)
657 self.assertTrue(position > cpp_style.Position(position.row - 1, position.column + 1))
658 self.assertTrue(position > cpp_style.Position(position.row, position.column - 1))
659 self.assertTrue(position < cpp_style.Position(position.row, position.column + 1))
660 self.assertTrue(position < cpp_style.Position(position.row + 1, position.column - 1))
661 self.assertEqual(position.__str__(), '(3, 4)')
663 def test_rfind_in_lines(self):
664 not_found_position = cpp_style.Position(10, 11)
665 start_position = cpp_style.Position(2, 2)
666 lines = ['ab', 'ace', 'test']
667 self.assertEqual(not_found_position, cpp_style._rfind_in_lines('st', lines, start_position, not_found_position))
668 self.assertTrue(cpp_style.Position(1, 1) == cpp_style._rfind_in_lines('a', lines, start_position, not_found_position))
669 self.assertEqual(cpp_style.Position(2, 2), cpp_style._rfind_in_lines('(te|a)', lines, start_position, not_found_position))
671 def test_close_expression(self):
672 self.assertEqual(cpp_style.Position(1, -1), cpp_style.close_expression([')('], cpp_style.Position(0, 1)))
673 self.assertEqual(cpp_style.Position(1, -1), cpp_style.close_expression([') ()'], cpp_style.Position(0, 1)))
674 self.assertEqual(cpp_style.Position(0, 4), cpp_style.close_expression([')[)]'], cpp_style.Position(0, 1)))
675 self.assertEqual(cpp_style.Position(0, 5), cpp_style.close_expression(['}{}{}'], cpp_style.Position(0, 3)))
676 self.assertEqual(cpp_style.Position(1, 1), cpp_style.close_expression(['}{}{', '}'], cpp_style.Position(0, 3)))
677 self.assertEqual(cpp_style.Position(2, -1), cpp_style.close_expression(['][][', ' '], cpp_style.Position(0, 3)))
679 def test_spaces_at_end_of_line(self):
682 'Line ends in whitespace. Consider deleting these extra spaces.'
683 ' [whitespace/end_of_line] [4]')
685 # Test C-style cast cases.
686 def test_cstyle_cast(self):
689 'Using C-style cast. Use static_cast<int>(...) instead'
690 ' [readability/casting] [4]')
692 'int *a = (int *)DEFINED_VALUE;',
693 'Using C-style cast. Use reinterpret_cast<int *>(...) instead'
694 ' [readability/casting] [4]', 'foo.c')
696 'uint16 a = (uint16)1.0;',
697 'Using C-style cast. Use static_cast<uint16>(...) instead'
698 ' [readability/casting] [4]')
700 'int32 a = (int32)1.0;',
701 'Using C-style cast. Use static_cast<int32>(...) instead'
702 ' [readability/casting] [4]')
704 'uint64 a = (uint64)1.0;',
705 'Using C-style cast. Use static_cast<uint64>(...) instead'
706 ' [readability/casting] [4]')
708 # Test taking address of casts (runtime/casting)
709 def test_runtime_casting(self):
711 'int* x = &static_cast<int*>(foo);',
712 'Are you taking an address of a cast? '
713 'This is dangerous: could be a temp var. '
714 'Take the address before doing the cast, rather than after'
715 ' [runtime/casting] [4]')
718 'int* x = &dynamic_cast<int *>(foo);',
719 ['Are you taking an address of a cast? '
720 'This is dangerous: could be a temp var. '
721 'Take the address before doing the cast, rather than after'
722 ' [runtime/casting] [4]',
723 'Do not use dynamic_cast<>. If you need to cast within a class '
724 'hierarchy, use static_cast<> to upcast. Google doesn\'t support '
725 'RTTI. [runtime/rtti] [5]'])
728 'int* x = &reinterpret_cast<int *>(foo);',
729 'Are you taking an address of a cast? '
730 'This is dangerous: could be a temp var. '
731 'Take the address before doing the cast, rather than after'
732 ' [runtime/casting] [4]')
734 # It's OK to cast an address.
736 'int* x = reinterpret_cast<int *>(&foo);',
739 def test_runtime_selfinit(self):
741 'Foo::Foo(Bar r, Bel l) : r_(r_), l_(l_) { }',
742 'You seem to be initializing a member variable with itself.'
743 ' [runtime/init] [4]')
745 'Foo::Foo(Bar r, Bel l) : r_(r), l_(l) { }',
748 'Foo::Foo(Bar r) : r_(r), l_(r_), ll_(l_) { }',
751 def test_runtime_rtti(self):
752 statement = 'int* x = dynamic_cast<int*>(&foo);'
754 'Do not use dynamic_cast<>. If you need to cast within a class '
755 'hierarchy, use static_cast<> to upcast. Google doesn\'t support '
756 'RTTI. [runtime/rtti] [5]')
757 # dynamic_cast is disallowed in most files.
758 self.assert_language_rules_check('foo.cpp', statement, error_message)
759 self.assert_language_rules_check('foo.h', statement, error_message)
761 # Tests for static_cast readability.
762 def test_static_cast_on_objects_with_toFoo(self):
763 mock_header_contents = ['inline Foo* toFoo(Bar* bar)']
765 orig_read_text_file_fn = fs.read_text_file
767 def mock_read_text_file_fn(path):
768 return mock_header_contents
771 fs.read_text_file = mock_read_text_file_fn
772 message = self.perform_avoid_static_cast_of_objects(
773 'Foo* x = static_cast<Foo*>(bar);',
774 filename='casting.cpp',
776 self.assertEqual(message, 'static_cast of class objects is not allowed. Use toFoo defined in Foo.h.'
777 ' [runtime/casting] [4]')
779 fs.read_text_file = orig_read_text_file_fn
781 def test_static_cast_on_objects_without_toFoo(self):
782 mock_header_contents = ['inline FooBar* toFooBar(Bar* bar)']
784 orig_read_text_file_fn = fs.read_text_file
786 def mock_read_text_file_fn(path):
787 return mock_header_contents
790 fs.read_text_file = mock_read_text_file_fn
791 message = self.perform_avoid_static_cast_of_objects(
792 'Foo* x = static_cast<Foo*>(bar);',
793 filename='casting.cpp',
795 self.assertEqual(message, 'static_cast of class objects is not allowed. Add toFoo in Foo.h and use it instead.'
796 ' [runtime/casting] [4]')
798 fs.read_text_file = orig_read_text_file_fn
800 # We cannot test this functionality because of difference of
801 # function definitions. Anyway, we may never enable this.
803 # # Test for unnamed arguments in a method.
804 # def test_check_for_unnamed_params(self):
805 # message = ('All parameters should be named in a function'
806 # ' [readability/function] [3]')
807 # self.assert_lint('virtual void A(int*) const;', message)
808 # self.assert_lint('virtual void B(void (*fn)(int*));', message)
809 # self.assert_lint('virtual void C(int*);', message)
810 # self.assert_lint('void *(*f)(void *) = x;', message)
811 # self.assert_lint('void Method(char*) {', message)
812 # self.assert_lint('void Method(char*);', message)
813 # self.assert_lint('void Method(char* /*x*/);', message)
814 # self.assert_lint('typedef void (*Method)(int32);', message)
815 # self.assert_lint('static void operator delete[](void*) throw();', message)
817 # self.assert_lint('virtual void D(int* p);', '')
818 # self.assert_lint('void operator delete(void* x) throw();', '')
819 # self.assert_lint('void Method(char* x)\n{', '')
820 # self.assert_lint('void Method(char* /*x*/)\n{', '')
821 # self.assert_lint('void Method(char* x);', '')
822 # self.assert_lint('typedef void (*Method)(int32 x);', '')
823 # self.assert_lint('static void operator delete[](void* x) throw();', '')
824 # self.assert_lint('static void operator delete[](void* /*x*/) throw();', '')
826 # # This one should technically warn, but doesn't because the function
827 # # pointer is confusing.
828 # self.assert_lint('virtual void E(void (*fn)(int* p));', '')
830 # Test deprecated casts such as int(d)
831 def test_deprecated_cast(self):
834 'Using deprecated casting style. '
835 'Use static_cast<int>(...) instead'
836 ' [readability/casting] [4]')
837 # Checks for false positives...
839 'int a = int(); // Constructor, o.k.',
842 'X::X() : a(int()) { } // default Constructor, o.k.',
845 'operator bool(); // Conversion operator, o.k.',
848 # The second parameter to a gMock method definition is a function signature
849 # that often looks like a bad cast but should not picked up by lint.
850 def test_mock_method(self):
852 'MOCK_METHOD0(method, int());',
855 'MOCK_CONST_METHOD1(method, float(string));',
858 'MOCK_CONST_METHOD2_T(method, double(float, float));',
861 # Test sizeof(type) cases.
862 def test_sizeof_type(self):
865 'Using sizeof(type). Use sizeof(varname) instead if possible'
866 ' [runtime/sizeof] [1]')
869 'Using sizeof(type). Use sizeof(varname) instead if possible'
870 ' [runtime/sizeof] [1]')
872 # Test typedef cases. There was a bug that cpp_style misidentified
873 # typedef for pointer to function as C-style cast and produced
874 # false-positive error messages.
875 def test_typedef_for_pointer_to_function(self):
877 'typedef void (*Func)(int x);',
880 'typedef void (*Func)(int *x);',
883 'typedef void Func(int x);',
886 'typedef void Func(int *x);',
889 def test_include_what_you_use_no_implementation_files(self):
890 code = 'std::vector<int> foo;'
891 self.assertEqual('Add #include <vector> for vector<>'
892 ' [build/include_what_you_use] [4]',
893 self.perform_include_what_you_use(code, 'foo.h'))
895 self.perform_include_what_you_use(code, 'foo.cpp'))
897 def test_include_what_you_use(self):
898 self.assert_include_what_you_use(
900 std::vector<int> foo;
903 self.assert_include_what_you_use(
905 std::pair<int,int> foo;
908 self.assert_include_what_you_use(
909 '''#include <multimap>
910 std::pair<int,int> foo;
913 self.assert_include_what_you_use(
914 '''#include <hash_map>
915 std::pair<int,int> foo;
918 self.assert_include_what_you_use(
919 '''#include <utility>
920 std::pair<int,int> foo;
923 self.assert_include_what_you_use(
925 DECLARE_string(foobar);
928 self.assert_include_what_you_use(
930 DEFINE_string(foobar, "", "");
933 self.assert_include_what_you_use(
935 std::pair<int,int> foo;
937 'Add #include <utility> for pair<>'
938 ' [build/include_what_you_use] [4]')
939 self.assert_include_what_you_use(
940 '''#include "base/foobar.h"
941 std::vector<int> foo;
943 'Add #include <vector> for vector<>'
944 ' [build/include_what_you_use] [4]')
945 self.assert_include_what_you_use(
949 'Add #include <set> for set<>'
950 ' [build/include_what_you_use] [4]')
951 self.assert_include_what_you_use(
952 '''#include "base/foobar.h"
953 hash_map<int, int> foobar;
955 'Add #include <hash_map> for hash_map<>'
956 ' [build/include_what_you_use] [4]')
957 self.assert_include_what_you_use(
958 '''#include "base/foobar.h"
959 bool foobar = std::less<int>(0,1);
961 'Add #include <functional> for less<>'
962 ' [build/include_what_you_use] [4]')
963 self.assert_include_what_you_use(
964 '''#include "base/foobar.h"
965 bool foobar = min<int>(0,1);
967 'Add #include <algorithm> for min [build/include_what_you_use] [4]')
968 self.assert_include_what_you_use(
969 'void a(const string &foobar);',
970 'Add #include <string> for string [build/include_what_you_use] [4]')
971 self.assert_include_what_you_use(
972 '''#include "base/foobar.h"
973 bool foobar = swap(0,1);
975 'Add #include <algorithm> for swap [build/include_what_you_use] [4]')
976 self.assert_include_what_you_use(
977 '''#include "base/foobar.h"
978 bool foobar = transform(a.begin(), a.end(), b.start(), Foo);
980 'Add #include <algorithm> for transform '
981 '[build/include_what_you_use] [4]')
982 self.assert_include_what_you_use(
983 '''#include "base/foobar.h"
984 bool foobar = min_element(a.begin(), a.end());
986 'Add #include <algorithm> for min_element '
987 '[build/include_what_you_use] [4]')
988 self.assert_include_what_you_use(
993 self.assert_include_what_you_use(
995 void a(const std::multimap<int,string> &foobar);
997 'Add #include <map> for multimap<>'
998 ' [build/include_what_you_use] [4]')
999 self.assert_include_what_you_use(
1001 void a(const std::priority_queue<int> &foobar);
1004 self.assert_include_what_you_use(
1005 '''#include "base/basictypes.h"
1006 #include "base/port.h"
1010 vector<string> hajoa;''', '')
1011 self.assert_include_what_you_use(
1012 '''#include <string>
1013 int i = numeric_limits<int>::max()
1015 'Add #include <limits> for numeric_limits<>'
1016 ' [build/include_what_you_use] [4]')
1017 self.assert_include_what_you_use(
1018 '''#include <limits>
1019 int i = numeric_limits<int>::max()
1023 # Test the UpdateIncludeState code path.
1024 mock_header_contents = ['#include "blah/foo.h"', '#include "blah/bar.h"']
1026 orig_read_text_file_fn = fs.read_text_file
1028 def mock_read_text_file_fn(path):
1029 return mock_header_contents
1032 fs.read_text_file = mock_read_text_file_fn
1033 message = self.perform_include_what_you_use(
1034 '#include "config.h"\n'
1035 '#include "blah/a.h"\n',
1036 filename='blah/a.cpp',
1038 self.assertEqual(message, '')
1040 mock_header_contents = ['#include <set>']
1041 message = self.perform_include_what_you_use(
1042 '''#include "config.h"
1045 std::set<int> foo;''',
1046 filename='blah/a.cpp',
1048 self.assertEqual(message, '')
1050 # If there's just a .cpp and the header can't be found then it's ok.
1051 message = self.perform_include_what_you_use(
1052 '''#include "config.h"
1055 std::set<int> foo;''',
1056 filename='blah/a.cpp')
1057 self.assertEqual(message, '')
1059 # Make sure we find the headers with relative paths.
1060 mock_header_contents = ['']
1061 message = self.perform_include_what_you_use(
1062 '''#include "config.h"
1065 std::set<int> foo;''' % (os.path.basename(os.getcwd()), os.path.sep),
1068 self.assertEqual(message, 'Add #include <set> for set<> '
1069 '[build/include_what_you_use] [4]')
1071 fs.read_text_file = orig_read_text_file_fn
1073 def test_files_belong_to_same_module(self):
1074 f = cpp_style.files_belong_to_same_module
1075 self.assertEqual((True, ''), f('a.cpp', 'a.h'))
1076 self.assertEqual((True, ''), f('base/google.cpp', 'base/google.h'))
1077 self.assertEqual((True, ''), f('base/google_test.cpp', 'base/google.h'))
1078 self.assertEqual((True, ''),
1079 f('base/google_unittest.cpp', 'base/google.h'))
1080 self.assertEqual((True, ''),
1081 f('base/internal/google_unittest.cpp',
1082 'base/public/google.h'))
1083 self.assertEqual((True, 'xxx/yyy/'),
1084 f('xxx/yyy/base/internal/google_unittest.cpp',
1085 'base/public/google.h'))
1086 self.assertEqual((True, 'xxx/yyy/'),
1087 f('xxx/yyy/base/google_unittest.cpp',
1088 'base/public/google.h'))
1089 self.assertEqual((True, ''),
1090 f('base/google_unittest.cpp', 'base/google-inl.h'))
1091 self.assertEqual((True, '/home/build/google3/'),
1092 f('/home/build/google3/base/google.cpp', 'base/google.h'))
1094 self.assertEqual((False, ''),
1095 f('/home/build/google3/base/google.cpp', 'basu/google.h'))
1096 self.assertEqual((False, ''), f('a.cpp', 'b.h'))
1098 def test_cleanse_line(self):
1099 self.assertEqual('int foo = 0; ',
1100 cpp_style.cleanse_comments('int foo = 0; // danger!'))
1101 self.assertEqual('int o = 0;',
1102 cpp_style.cleanse_comments('int /* foo */ o = 0;'))
1103 self.assertEqual('foo(int a, int b);',
1104 cpp_style.cleanse_comments('foo(int a /* abc */, int b);'))
1105 self.assertEqual('f(a, b);',
1106 cpp_style.cleanse_comments('f(a, /* name */ b);'))
1107 self.assertEqual('f(a, b);',
1108 cpp_style.cleanse_comments('f(a /* name */, b);'))
1109 self.assertEqual('f(a, b);',
1110 cpp_style.cleanse_comments('f(a, /* name */b);'))
1112 def test_multi_line_comments(self):
1113 # missing explicit is bad
1114 self.assert_multi_line_lint(
1118 Foo(int f); // should cause a lint warning in code
1122 self.assert_multi_line_lint(
1124 /* int a = 0; multi-liner
1125 static const int b = 0;''',
1126 ['Could not find end of multi-line comment'
1127 ' [readability/multiline_comment] [5]',
1128 'Complex multi-line /*...*/-style comment found. '
1129 'Lint may give bogus warnings. Consider replacing these with '
1130 '//-style comments, with #if 0...#endif, or with more clearly '
1131 'structured multi-line comments. [readability/multiline_comment] [5]'])
1132 self.assert_multi_line_lint(r''' /* multi-line comment''',
1133 ['Could not find end of multi-line comment'
1134 ' [readability/multiline_comment] [5]',
1135 'Complex multi-line /*...*/-style comment found. '
1136 'Lint may give bogus warnings. Consider replacing these with '
1137 '//-style comments, with #if 0...#endif, or with more clearly '
1138 'structured multi-line comments. [readability/multiline_comment] [5]'])
1139 self.assert_multi_line_lint(r''' // /* comment, but not multi-line''', '')
1141 def test_multiline_strings(self):
1142 multiline_string_error_message = (
1143 'Multi-line string ("...") found. This lint script doesn\'t '
1144 'do well with such strings, and may give bogus warnings. They\'re '
1145 'ugly and unnecessary, and you should use concatenation instead".'
1146 ' [readability/multiline_string] [5]')
1148 file_path = 'mydir/foo.cpp'
1150 error_collector = ErrorCollector(self.assertTrue)
1151 self.process_file_data(file_path, 'cpp',
1152 ['const char* str = "This is a\\',
1153 ' multiline string.";'],
1157 error_collector.result_list().count(multiline_string_error_message))
1159 # Test non-explicit single-argument constructors
1160 def test_explicit_single_argument_constructors(self):
1161 # missing explicit is bad
1162 self.assert_multi_line_lint(
1167 'Single-argument constructors should be marked explicit.'
1168 ' [runtime/explicit] [5]')
1169 # missing explicit is bad, even with whitespace
1170 self.assert_multi_line_lint(
1175 ['Extra space before ( in function call [whitespace/parens] [4]',
1176 'Single-argument constructors should be marked explicit.'
1177 ' [runtime/explicit] [5]'])
1178 # missing explicit, with distracting comment, is still bad
1179 self.assert_multi_line_lint(
1182 Foo(int f); // simpler than Foo(blargh, blarg)
1184 'Single-argument constructors should be marked explicit.'
1185 ' [runtime/explicit] [5]')
1186 # missing explicit, with qualified classname
1187 self.assert_multi_line_lint(
1189 class Qualifier::AnotherOne::Foo {
1192 'Single-argument constructors should be marked explicit.'
1193 ' [runtime/explicit] [5]')
1194 # structs are caught as well.
1195 self.assert_multi_line_lint(
1200 'Single-argument constructors should be marked explicit.'
1201 ' [runtime/explicit] [5]')
1202 # Templatized classes are caught as well.
1203 self.assert_multi_line_lint(
1205 template<typename T> class Foo {
1208 'Single-argument constructors should be marked explicit.'
1209 ' [runtime/explicit] [5]')
1210 # proper style is okay
1211 self.assert_multi_line_lint(
1214 explicit Foo(int f);
1217 # two argument constructor is okay
1218 self.assert_multi_line_lint(
1224 # two argument constructor, across two lines, is okay
1225 self.assert_multi_line_lint(
1232 # non-constructor (but similar name), is okay
1233 self.assert_multi_line_lint(
1239 # constructor with void argument is okay
1240 self.assert_multi_line_lint(
1246 # single argument method is okay
1247 self.assert_multi_line_lint(
1253 # comments should be ignored
1254 self.assert_multi_line_lint(
1260 # single argument function following class definition is okay
1261 # (okay, it's not actually valid, but we don't want a false positive)
1262 self.assert_multi_line_lint(
1269 # single argument function is okay
1270 self.assert_multi_line_lint(
1271 '''static Foo(int f);''',
1273 # single argument copy constructor is okay.
1274 self.assert_multi_line_lint(
1280 self.assert_multi_line_lint(
1287 def test_slash_star_comment_on_single_line(self):
1288 self.assert_multi_line_lint(
1289 '''/* static */ Foo(int f);''',
1291 self.assert_multi_line_lint(
1292 '''/*/ static */ Foo(int f);''',
1294 self.assert_multi_line_lint(
1295 '''/*/ static Foo(int f);''',
1296 'Could not find end of multi-line comment'
1297 ' [readability/multiline_comment] [5]')
1298 self.assert_multi_line_lint(
1299 ''' /*/ static Foo(int f);''',
1300 'Could not find end of multi-line comment'
1301 ' [readability/multiline_comment] [5]')
1303 # Test suspicious usage of "if" like this:
1306 # } if (a == c) { // Should be "else if".
1307 # DoSomething(); // This gets called twice if a == b && a == c.
1309 def test_suspicious_usage_of_if(self):
1315 'Did you mean "else if"? If not, start a new line for "if".'
1316 ' [readability/braces] [4]')
1318 # Test suspicious usage of memset. Specifically, a 0
1319 # as the final argument is almost certainly an error.
1320 def test_suspicious_usage_of_memset(self):
1321 # Normal use is okay.
1323 ' memset(buf, 0, sizeof(buf))',
1326 # A 0 as the final argument is almost certainly an error.
1328 ' memset(buf, sizeof(buf), 0)',
1329 'Did you mean "memset(buf, 0, sizeof(buf))"?'
1330 ' [runtime/memset] [4]')
1332 ' memset(buf, xsize * ysize, 0)',
1333 'Did you mean "memset(buf, 0, xsize * ysize)"?'
1334 ' [runtime/memset] [4]')
1336 # There is legitimate test code that uses this form.
1337 # This is okay since the second argument is a literal.
1339 " memset(buf, 'y', 0)",
1342 ' memset(buf, 4, 0)',
1345 ' memset(buf, -1, 0)',
1348 ' memset(buf, 0xF1, 0)',
1351 ' memset(buf, 0xcd, 0)',
1354 def test_check_posix_threading(self):
1355 self.assert_lint('sctime_r()', '')
1356 self.assert_lint('strtok_r()', '')
1357 self.assert_lint(' strtok_r(foo, ba, r)', '')
1358 self.assert_lint('brand()', '')
1359 self.assert_lint('_rand()', '')
1360 self.assert_lint('.rand()', '')
1361 self.assert_lint('>rand()', '')
1362 self.assert_lint('rand()',
1363 'Consider using rand_r(...) instead of rand(...)'
1364 ' for improved thread safety.'
1365 ' [runtime/threadsafe_fn] [2]')
1366 self.assert_lint('strtok()',
1367 'Consider using strtok_r(...) '
1368 'instead of strtok(...)'
1369 ' for improved thread safety.'
1370 ' [runtime/threadsafe_fn] [2]')
1372 # Test potential format string bugs like printf(foo).
1373 def test_format_strings(self):
1374 self.assert_lint('printf("foo")', '')
1375 self.assert_lint('printf("foo: %s", foo)', '')
1376 self.assert_lint('DocidForPrintf(docid)', '') # Should not trigger.
1379 'Potential format string bug. Do printf("%s", foo) instead.'
1380 ' [runtime/printf] [4]')
1382 'printf(foo.c_str())',
1383 'Potential format string bug. '
1384 'Do printf("%s", foo.c_str()) instead.'
1385 ' [runtime/printf] [4]')
1387 'printf(foo->c_str())',
1388 'Potential format string bug. '
1389 'Do printf("%s", foo->c_str()) instead.'
1390 ' [runtime/printf] [4]')
1392 'StringPrintf(foo)',
1393 'Potential format string bug. Do StringPrintf("%s", foo) instead.'
1395 ' [runtime/printf] [4]')
1397 # Variable-length arrays are not permitted.
1398 def test_variable_length_array_detection(self):
1399 errmsg = ('Do not use variable-length arrays. Use an appropriately named '
1400 "('k' followed by CamelCase) compile-time constant for the size."
1401 ' [runtime/arrays] [1]')
1403 self.assert_lint('int a[any_old_variable];', errmsg)
1404 self.assert_lint('int doublesize[some_var * 2];', errmsg)
1405 self.assert_lint('int a[afunction()];', errmsg)
1406 self.assert_lint('int a[function(kMaxFooBars)];', errmsg)
1407 self.assert_lint('bool aList[items_->size()];', errmsg)
1408 self.assert_lint('namespace::Type buffer[len+1];', errmsg)
1410 self.assert_lint('int a[64];', '')
1411 self.assert_lint('int a[0xFF];', '')
1412 self.assert_lint('int first[256], second[256];', '')
1413 self.assert_lint('int arrayName[kCompileTimeConstant];', '')
1414 self.assert_lint('char buf[somenamespace::kBufSize];', '')
1415 self.assert_lint('int arrayName[ALL_CAPS];', '')
1416 self.assert_lint('AClass array1[foo::bar::ALL_CAPS];', '')
1417 self.assert_lint('int a[kMaxStrLen + 1];', '')
1418 self.assert_lint('int a[sizeof(foo)];', '')
1419 self.assert_lint('int a[sizeof(*foo)];', '')
1420 self.assert_lint('int a[sizeof foo];', '')
1421 self.assert_lint('int a[sizeof(struct Foo)];', '')
1422 self.assert_lint('int a[128 - sizeof(const bar)];', '')
1423 self.assert_lint('int a[(sizeof(foo) * 4)];', '')
1424 self.assert_lint('int a[(arraysize(fixed_size_array)/2) << 1];', 'Missing spaces around / [whitespace/operators] [3]')
1425 self.assert_lint('delete a[some_var];', '')
1426 self.assert_lint('return a[some_var];', '')
1429 def test_braces(self):
1430 # Braces shouldn't be followed by a ; unless they're defining a struct
1431 # or initializing an array
1432 self.assert_lint('int a[3] = { 1, 2, 3 };', '')
1438 # For single line, unmatched '}' with a ';' is ignored (not enough context)
1439 self.assert_multi_line_lint(
1445 self.assert_multi_line_lint(
1447 int a[2][3] = { { 1, 2 },
1450 self.assert_multi_line_lint(
1457 # CHECK/EXPECT_TRUE/EXPECT_FALSE replacements
1458 def test_check_check(self):
1459 self.assert_lint('CHECK(x == 42)',
1460 'Consider using CHECK_EQ instead of CHECK(a == b)'
1461 ' [readability/check] [2]')
1462 self.assert_lint('CHECK(x != 42)',
1463 'Consider using CHECK_NE instead of CHECK(a != b)'
1464 ' [readability/check] [2]')
1465 self.assert_lint('CHECK(x >= 42)',
1466 'Consider using CHECK_GE instead of CHECK(a >= b)'
1467 ' [readability/check] [2]')
1468 self.assert_lint('CHECK(x > 42)',
1469 'Consider using CHECK_GT instead of CHECK(a > b)'
1470 ' [readability/check] [2]')
1471 self.assert_lint('CHECK(x <= 42)',
1472 'Consider using CHECK_LE instead of CHECK(a <= b)'
1473 ' [readability/check] [2]')
1474 self.assert_lint('CHECK(x < 42)',
1475 'Consider using CHECK_LT instead of CHECK(a < b)'
1476 ' [readability/check] [2]')
1478 self.assert_lint('DCHECK(x == 42)',
1479 'Consider using DCHECK_EQ instead of DCHECK(a == b)'
1480 ' [readability/check] [2]')
1481 self.assert_lint('DCHECK(x != 42)',
1482 'Consider using DCHECK_NE instead of DCHECK(a != b)'
1483 ' [readability/check] [2]')
1484 self.assert_lint('DCHECK(x >= 42)',
1485 'Consider using DCHECK_GE instead of DCHECK(a >= b)'
1486 ' [readability/check] [2]')
1487 self.assert_lint('DCHECK(x > 42)',
1488 'Consider using DCHECK_GT instead of DCHECK(a > b)'
1489 ' [readability/check] [2]')
1490 self.assert_lint('DCHECK(x <= 42)',
1491 'Consider using DCHECK_LE instead of DCHECK(a <= b)'
1492 ' [readability/check] [2]')
1493 self.assert_lint('DCHECK(x < 42)',
1494 'Consider using DCHECK_LT instead of DCHECK(a < b)'
1495 ' [readability/check] [2]')
1498 'EXPECT_TRUE("42" == x)',
1499 'Consider using EXPECT_EQ instead of EXPECT_TRUE(a == b)'
1500 ' [readability/check] [2]')
1502 'EXPECT_TRUE("42" != x)',
1503 'Consider using EXPECT_NE instead of EXPECT_TRUE(a != b)'
1504 ' [readability/check] [2]')
1506 'EXPECT_TRUE(+42 >= x)',
1507 'Consider using EXPECT_GE instead of EXPECT_TRUE(a >= b)'
1508 ' [readability/check] [2]')
1510 'EXPECT_TRUE_M(-42 > x)',
1511 'Consider using EXPECT_GT_M instead of EXPECT_TRUE_M(a > b)'
1512 ' [readability/check] [2]')
1514 'EXPECT_TRUE_M(42U <= x)',
1515 'Consider using EXPECT_LE_M instead of EXPECT_TRUE_M(a <= b)'
1516 ' [readability/check] [2]')
1518 'EXPECT_TRUE_M(42L < x)',
1519 'Consider using EXPECT_LT_M instead of EXPECT_TRUE_M(a < b)'
1520 ' [readability/check] [2]')
1523 'EXPECT_FALSE(x == 42)',
1524 'Consider using EXPECT_NE instead of EXPECT_FALSE(a == b)'
1525 ' [readability/check] [2]')
1527 'EXPECT_FALSE(x != 42)',
1528 'Consider using EXPECT_EQ instead of EXPECT_FALSE(a != b)'
1529 ' [readability/check] [2]')
1531 'EXPECT_FALSE(x >= 42)',
1532 'Consider using EXPECT_LT instead of EXPECT_FALSE(a >= b)'
1533 ' [readability/check] [2]')
1535 'ASSERT_FALSE(x > 42)',
1536 'Consider using ASSERT_LE instead of ASSERT_FALSE(a > b)'
1537 ' [readability/check] [2]')
1539 'ASSERT_FALSE(x <= 42)',
1540 'Consider using ASSERT_GT instead of ASSERT_FALSE(a <= b)'
1541 ' [readability/check] [2]')
1543 'ASSERT_FALSE_M(x < 42)',
1544 'Consider using ASSERT_GE_M instead of ASSERT_FALSE_M(a < b)'
1545 ' [readability/check] [2]')
1547 self.assert_lint('CHECK(some_iterator == obj.end())', '')
1548 self.assert_lint('EXPECT_TRUE(some_iterator == obj.end())', '')
1549 self.assert_lint('EXPECT_FALSE(some_iterator == obj.end())', '')
1551 self.assert_lint('CHECK(CreateTestFile(dir, (1 << 20)));', '')
1552 self.assert_lint('CHECK(CreateTestFile(dir, (1 >> 20)));', '')
1554 self.assert_lint('CHECK(x<42)',
1555 ['Missing spaces around <'
1556 ' [whitespace/operators] [3]',
1557 'Consider using CHECK_LT instead of CHECK(a < b)'
1558 ' [readability/check] [2]'])
1559 self.assert_lint('CHECK(x>42)',
1560 'Consider using CHECK_GT instead of CHECK(a > b)'
1561 ' [readability/check] [2]')
1564 ' EXPECT_TRUE(42 < x) // Random comment.',
1565 'Consider using EXPECT_LT instead of EXPECT_TRUE(a < b)'
1566 ' [readability/check] [2]')
1568 'EXPECT_TRUE( 42 < x )',
1569 ['Extra space after ( in function call'
1570 ' [whitespace/parens] [4]',
1571 'Consider using EXPECT_LT instead of EXPECT_TRUE(a < b)'
1572 ' [readability/check] [2]'])
1574 'CHECK("foo" == "foo")',
1575 'Consider using CHECK_EQ instead of CHECK(a == b)'
1576 ' [readability/check] [2]')
1578 self.assert_lint('CHECK_EQ("foo", "foo")', '')
1580 def test_brace_at_begin_of_line(self):
1581 self.assert_lint('{',
1582 'This { should be at the end of the previous line'
1583 ' [whitespace/braces] [4]')
1584 self.assert_multi_line_lint(
1589 self.assert_multi_line_lint(
1592 self.assert_multi_line_lint(
1593 ' MACRO1(macroArg) {',
1595 self.assert_multi_line_lint(
1596 'ACCESSOR_GETTER(MessageEventPorts) {',
1597 'Place brace on its own line for function definitions. [whitespace/braces] [4]')
1598 self.assert_multi_line_lint(
1600 'Place brace on its own line for function definitions. [whitespace/braces] [4]')
1601 self.assert_multi_line_lint(
1602 'int foo() const {',
1603 'Place brace on its own line for function definitions. [whitespace/braces] [4]')
1604 self.assert_multi_line_lint(
1605 'int foo() const OVERRIDE {',
1606 'Place brace on its own line for function definitions. [whitespace/braces] [4]')
1607 self.assert_multi_line_lint(
1608 'int foo() OVERRIDE {',
1609 'Place brace on its own line for function definitions. [whitespace/braces] [4]')
1610 self.assert_multi_line_lint(
1615 self.assert_multi_line_lint(
1616 'int foo() OVERRIDE\n'
1620 self.assert_multi_line_lint(
1623 ' && condition3) {\n'
1627 def test_mismatching_spaces_in_parens(self):
1628 self.assert_lint('if (foo ) {', 'Extra space before ) in if'
1629 ' [whitespace/parens] [5]')
1630 self.assert_lint('switch ( foo) {', 'Extra space after ( in switch'
1631 ' [whitespace/parens] [5]')
1632 self.assert_lint('for (foo; ba; bar ) {', 'Extra space before ) in for'
1633 ' [whitespace/parens] [5]')
1634 self.assert_lint('for ((foo); (ba); (bar) ) {', 'Extra space before ) in for'
1635 ' [whitespace/parens] [5]')
1636 self.assert_lint('for (; foo; bar) {', '')
1637 self.assert_lint('for (; (foo); (bar)) {', '')
1638 self.assert_lint('for ( ; foo; bar) {', '')
1639 self.assert_lint('for ( ; (foo); (bar)) {', '')
1640 self.assert_lint('for ( ; foo; bar ) {', 'Extra space before ) in for'
1641 ' [whitespace/parens] [5]')
1642 self.assert_lint('for ( ; (foo); (bar) ) {', 'Extra space before ) in for'
1643 ' [whitespace/parens] [5]')
1644 self.assert_lint('for (foo; bar; ) {', '')
1645 self.assert_lint('for ((foo); (bar); ) {', '')
1646 self.assert_lint('foreach (foo, foos ) {', 'Extra space before ) in foreach'
1647 ' [whitespace/parens] [5]')
1648 self.assert_lint('foreach ( foo, foos) {', 'Extra space after ( in foreach'
1649 ' [whitespace/parens] [5]')
1650 self.assert_lint('while ( foo) {', 'Extra space after ( in while'
1651 ' [whitespace/parens] [5]')
1653 def test_spacing_for_fncall(self):
1654 self.assert_lint('if (foo) {', '')
1655 self.assert_lint('for (foo;bar;baz) {', '')
1656 self.assert_lint('foreach (foo, foos) {', '')
1657 self.assert_lint('while (foo) {', '')
1658 self.assert_lint('switch (foo) {', '')
1659 self.assert_lint('new (RenderArena()) RenderInline(document())', '')
1660 self.assert_lint('foo( bar)', 'Extra space after ( in function call'
1661 ' [whitespace/parens] [4]')
1662 self.assert_lint('foobar( \\', '')
1663 self.assert_lint('foobar( \\', '')
1664 self.assert_lint('( a + b)', 'Extra space after ('
1665 ' [whitespace/parens] [2]')
1666 self.assert_lint('((a+b))', '')
1667 self.assert_lint('foo (foo)', 'Extra space before ( in function call'
1668 ' [whitespace/parens] [4]')
1669 self.assert_lint('#elif (foo(bar))', '')
1670 self.assert_lint('#elif (foo(bar) && foo(baz))', '')
1671 self.assert_lint('typedef foo (*foo)(foo)', '')
1672 self.assert_lint('typedef foo (*foo12bar_)(foo)', '')
1673 self.assert_lint('typedef foo (Foo::*bar)(foo)', '')
1674 self.assert_lint('foo (Foo::*bar)(',
1675 'Extra space before ( in function call'
1676 ' [whitespace/parens] [4]')
1677 self.assert_lint('typedef foo (Foo::*bar)(', '')
1678 self.assert_lint('(foo)(bar)', '')
1679 self.assert_lint('Foo (*foo)(bar)', '')
1680 self.assert_lint('Foo (*foo)(Bar bar,', '')
1681 self.assert_lint('char (*p)[sizeof(foo)] = &foo', '')
1682 self.assert_lint('char (&ref)[sizeof(foo)] = &foo', '')
1683 self.assert_lint('const char32 (*table[])[6];', '')
1685 def test_spacing_before_braces(self):
1686 self.assert_lint('if (foo){', 'Missing space before {'
1687 ' [whitespace/braces] [5]')
1688 self.assert_lint('for{', 'Missing space before {'
1689 ' [whitespace/braces] [5]')
1690 self.assert_lint('for {', '')
1691 self.assert_lint('EXPECT_DEBUG_DEATH({', '')
1693 def test_spacing_between_braces(self):
1694 self.assert_lint(' { }', '')
1695 self.assert_lint(' {}', 'Missing space inside { }. [whitespace/braces] [5]')
1696 self.assert_lint(' { }', 'Too many spaces inside { }. [whitespace/braces] [5]')
1698 def test_spacing_around_else(self):
1699 self.assert_lint('}else {', 'Missing space before else'
1700 ' [whitespace/braces] [5]')
1701 self.assert_lint('} else{', 'Missing space before {'
1702 ' [whitespace/braces] [5]')
1703 self.assert_lint('} else {', '')
1704 self.assert_lint('} else if', '')
1706 def test_spacing_for_binary_ops(self):
1707 self.assert_lint('if (foo<=bar) {', 'Missing spaces around <='
1708 ' [whitespace/operators] [3]')
1709 self.assert_lint('if (foo<bar) {', 'Missing spaces around <'
1710 ' [whitespace/operators] [3]')
1711 self.assert_lint('if (foo<bar->baz) {', 'Missing spaces around <'
1712 ' [whitespace/operators] [3]')
1713 self.assert_lint('if (foo<bar->bar) {', 'Missing spaces around <'
1714 ' [whitespace/operators] [3]')
1715 self.assert_lint('typedef hash_map<Foo, Bar', 'Missing spaces around <'
1716 ' [whitespace/operators] [3]')
1717 self.assert_lint('typedef hash_map<FoooooType, BaaaaarType,', '')
1718 self.assert_lint('a<Foo> t+=b;', 'Missing spaces around +='
1719 ' [whitespace/operators] [3]')
1720 self.assert_lint('a<Foo> t-=b;', 'Missing spaces around -='
1721 ' [whitespace/operators] [3]')
1722 self.assert_lint('a<Foo*> t*=b;', 'Missing spaces around *='
1723 ' [whitespace/operators] [3]')
1724 self.assert_lint('a<Foo*> t/=b;', 'Missing spaces around /='
1725 ' [whitespace/operators] [3]')
1726 self.assert_lint('a<Foo*> t|=b;', 'Missing spaces around |='
1727 ' [whitespace/operators] [3]')
1728 self.assert_lint('a<Foo*> t&=b;', 'Missing spaces around &='
1729 ' [whitespace/operators] [3]')
1730 self.assert_lint('a<Foo*> t<<=b;', 'Missing spaces around <<='
1731 ' [whitespace/operators] [3]')
1732 self.assert_lint('a<Foo*> t>>=b;', 'Missing spaces around >>='
1733 ' [whitespace/operators] [3]')
1734 self.assert_lint('a<Foo*> t>>=&b|c;', 'Missing spaces around >>='
1735 ' [whitespace/operators] [3]')
1736 self.assert_lint('a<Foo*> t<<=*b/c;', 'Missing spaces around <<='
1737 ' [whitespace/operators] [3]')
1738 self.assert_lint('a<Foo> t -= b;', '')
1739 self.assert_lint('a<Foo> t += b;', '')
1740 self.assert_lint('a<Foo*> t *= b;', '')
1741 self.assert_lint('a<Foo*> t /= b;', '')
1742 self.assert_lint('a<Foo*> t |= b;', '')
1743 self.assert_lint('a<Foo*> t &= b;', '')
1744 self.assert_lint('a<Foo*> t <<= b;', '')
1745 self.assert_lint('a<Foo*> t >>= b;', '')
1746 self.assert_lint('a<Foo*> t >>= &b|c;', 'Missing spaces around |'
1747 ' [whitespace/operators] [3]')
1748 self.assert_lint('a<Foo*> t <<= *b/c;', 'Missing spaces around /'
1749 ' [whitespace/operators] [3]')
1750 self.assert_lint('a<Foo*> t <<= b/c; //Test', [
1751 'Should have a space between // and comment '
1752 '[whitespace/comments] [4]', 'Missing'
1753 ' spaces around / [whitespace/operators] [3]'])
1754 self.assert_lint('a<Foo*> t <<= b||c; //Test', ['One space before end'
1755 ' of line comments [whitespace/comments] [5]',
1756 'Should have a space between // and comment '
1757 '[whitespace/comments] [4]',
1758 'Missing spaces around || [whitespace/operators] [3]'])
1759 self.assert_lint('a<Foo*> t <<= b&&c; // Test', 'Missing spaces around'
1760 ' && [whitespace/operators] [3]')
1761 self.assert_lint('a<Foo*> t <<= b&&&c; // Test', 'Missing spaces around'
1762 ' && [whitespace/operators] [3]')
1763 self.assert_lint('a<Foo*> t <<= b&&*c; // Test', 'Missing spaces around'
1764 ' && [whitespace/operators] [3]')
1765 self.assert_lint('a<Foo*> t <<= b && *c; // Test', '')
1766 self.assert_lint('a<Foo*> t <<= b && &c; // Test', '')
1767 self.assert_lint('a<Foo*> t <<= b || &c; /*Test', 'Complex multi-line '
1768 '/*...*/-style comment found. Lint may give bogus '
1769 'warnings. Consider replacing these with //-style'
1770 ' comments, with #if 0...#endif, or with more clearly'
1771 ' structured multi-line comments. [readability/multiline_comment] [5]')
1772 self.assert_lint('a<Foo&> t <<= &b | &c;', '')
1773 self.assert_lint('a<Foo*> t <<= &b & &c; // Test', '')
1774 self.assert_lint('a<Foo*> t <<= *b / &c; // Test', '')
1775 self.assert_lint('if (a=b == 1)', 'Missing spaces around = [whitespace/operators] [4]')
1776 self.assert_lint('a = 1<<20', 'Missing spaces around << [whitespace/operators] [3]')
1777 self.assert_lint('if (a = b == 1)', '')
1778 self.assert_lint('a = 1 << 20', '')
1779 self.assert_multi_line_lint('#include <sys/io.h>\n', '')
1780 self.assert_multi_line_lint('#import <foo/bar.h>\n', '')
1782 def test_operator_methods(self):
1783 self.assert_lint('String operator+(const String&, const String&);', '')
1784 self.assert_lint('String operator/(const String&, const String&);', '')
1785 self.assert_lint('bool operator==(const String&, const String&);', '')
1786 self.assert_lint('String& operator-=(const String&, const String&);', '')
1787 self.assert_lint('String& operator+=(const String&, const String&);', '')
1788 self.assert_lint('String& operator*=(const String&, const String&);', '')
1789 self.assert_lint('String& operator%=(const String&, const String&);', '')
1790 self.assert_lint('String& operator&=(const String&, const String&);', '')
1791 self.assert_lint('String& operator<<=(const String&, const String&);', '')
1792 self.assert_lint('String& operator>>=(const String&, const String&);', '')
1793 self.assert_lint('String& operator|=(const String&, const String&);', '')
1794 self.assert_lint('String& operator^=(const String&, const String&);', '')
1796 def test_spacing_before_last_semicolon(self):
1797 self.assert_lint('call_function() ;',
1798 'Extra space before last semicolon. If this should be an '
1799 'empty statement, use { } instead.'
1800 ' [whitespace/semicolon] [5]')
1801 self.assert_lint('while (true) ;',
1802 'Extra space before last semicolon. If this should be an '
1803 'empty statement, use { } instead.'
1804 ' [whitespace/semicolon] [5]')
1805 self.assert_lint('default:;',
1806 'Semicolon defining empty statement. Use { } instead.'
1807 ' [whitespace/semicolon] [5]')
1808 self.assert_lint(' ;',
1809 'Line contains only semicolon. If this should be an empty '
1810 'statement, use { } instead.'
1811 ' [whitespace/semicolon] [5]')
1812 self.assert_lint('for (int i = 0; ;', '')
1814 # Static or global STL strings.
1815 def test_static_or_global_stlstrings(self):
1816 self.assert_lint('string foo;',
1817 'For a static/global string constant, use a C style '
1818 'string instead: "char foo[]".'
1819 ' [runtime/string] [4]')
1820 self.assert_lint('string kFoo = "hello"; // English',
1821 'For a static/global string constant, use a C style '
1822 'string instead: "char kFoo[]".'
1823 ' [runtime/string] [4]')
1824 self.assert_lint('static string foo;',
1825 'For a static/global string constant, use a C style '
1826 'string instead: "static char foo[]".'
1827 ' [runtime/string] [4]')
1828 self.assert_lint('static const string foo;',
1829 'For a static/global string constant, use a C style '
1830 'string instead: "static const char foo[]".'
1831 ' [runtime/string] [4]')
1832 self.assert_lint('string Foo::bar;',
1833 'For a static/global string constant, use a C style '
1834 'string instead: "char Foo::bar[]".'
1835 ' [runtime/string] [4]')
1837 self.assert_lint('string foo("foobar");',
1838 'For a static/global string constant, use a C style '
1839 'string instead: "char foo[]".'
1840 ' [runtime/string] [4]')
1841 # Should not catch local or member variables.
1842 self.assert_lint(' string foo', '')
1843 # Should not catch functions.
1844 self.assert_lint('string EmptyString() { return ""; }', '')
1845 self.assert_lint('string EmptyString () { return ""; }', '')
1846 self.assert_lint('string VeryLongNameFunctionSometimesEndsWith(\n'
1847 ' VeryLongNameType veryLongNameVariable) { }', '')
1848 self.assert_lint('template<>\n'
1849 'string FunctionTemplateSpecialization<SomeType>(\n'
1850 ' int x) { return ""; }', '')
1851 self.assert_lint('template<>\n'
1852 'string FunctionTemplateSpecialization<vector<A::B>* >(\n'
1853 ' int x) { return ""; }', '')
1855 # should not catch methods of template classes.
1856 self.assert_lint('string Class<Type>::Method() const\n'
1860 self.assert_lint('string Class<Type>::Method(\n'
1866 def test_no_spaces_in_function_calls(self):
1867 self.assert_lint('TellStory(1, 3);',
1869 self.assert_lint('TellStory(1, 3 );',
1870 'Extra space before )'
1871 ' [whitespace/parens] [2]')
1872 self.assert_lint('TellStory(1 /* wolf */, 3 /* pigs */);',
1874 self.assert_multi_line_lint('#endif\n );',
1877 def test_one_spaces_between_code_and_comments(self):
1878 self.assert_lint('} // namespace foo',
1880 self.assert_lint('}// namespace foo',
1881 'One space before end of line comments'
1882 ' [whitespace/comments] [5]')
1883 self.assert_lint('printf("foo"); // Outside quotes.',
1885 self.assert_lint('int i = 0; // Having one space is fine.','')
1886 self.assert_lint('int i = 0; // Having two spaces is bad.',
1887 'One space before end of line comments'
1888 ' [whitespace/comments] [5]')
1889 self.assert_lint('int i = 0; // Having three spaces is bad.',
1890 'One space before end of line comments'
1891 ' [whitespace/comments] [5]')
1892 self.assert_lint('// Top level comment', '')
1893 self.assert_lint(' // Line starts with four spaces.', '')
1894 self.assert_lint('foo();\n'
1895 '{ // A scope is opening.', '')
1896 self.assert_lint(' foo();\n'
1897 ' { // An indented scope is opening.', '')
1898 self.assert_lint('if (foo) { // not a pure scope',
1900 self.assert_lint('printf("// In quotes.")', '')
1901 self.assert_lint('printf("\\"%s // In quotes.")', '')
1902 self.assert_lint('printf("%s", "// In quotes.")', '')
1904 def test_one_spaces_after_punctuation_in_comments(self):
1905 self.assert_lint('int a; // This is a sentence.',
1907 self.assert_lint('int a; // This is a sentence. ',
1908 'Line ends in whitespace. Consider deleting these extra spaces. [whitespace/end_of_line] [4]')
1909 self.assert_lint('int a; // This is a sentence. This is a another sentence.',
1911 self.assert_lint('int a; // This is a sentence. This is a another sentence.',
1912 'Should have only a single space after a punctuation in a comment. [whitespace/comments] [5]')
1913 self.assert_lint('int a; // This is a sentence! This is a another sentence.',
1914 'Should have only a single space after a punctuation in a comment. [whitespace/comments] [5]')
1915 self.assert_lint('int a; // Why did I write this? This is a another sentence.',
1916 'Should have only a single space after a punctuation in a comment. [whitespace/comments] [5]')
1917 self.assert_lint('int a; // Elementary, my dear.',
1918 'Should have only a single space after a punctuation in a comment. [whitespace/comments] [5]')
1919 self.assert_lint('int a; // The following should be clear: Is it?',
1920 'Should have only a single space after a punctuation in a comment. [whitespace/comments] [5]')
1921 self.assert_lint('int a; // Look at the follow semicolon; I hope this gives an error.',
1922 'Should have only a single space after a punctuation in a comment. [whitespace/comments] [5]')
1924 def test_space_after_comment_marker(self):
1925 self.assert_lint('//', '')
1926 self.assert_lint('//x', 'Should have a space between // and comment'
1927 ' [whitespace/comments] [4]')
1928 self.assert_lint('// x', '')
1929 self.assert_lint('//----', '')
1930 self.assert_lint('//====', '')
1931 self.assert_lint('//////', '')
1932 self.assert_lint('////// x', '')
1933 self.assert_lint('/// x', '')
1934 self.assert_lint('////x', 'Should have a space between // and comment'
1935 ' [whitespace/comments] [4]')
1937 def test_newline_at_eof(self):
1938 def do_test(self, data, is_missing_eof):
1939 error_collector = ErrorCollector(self.assertTrue)
1940 self.process_file_data('foo.cpp', 'cpp', data.split('\n'),
1942 # The warning appears only once.
1944 int(is_missing_eof),
1945 error_collector.results().count(
1946 'Could not find a newline character at the end of the file.'
1947 ' [whitespace/ending_newline] [5]'))
1949 do_test(self, '// Newline\n// at EOF\n', False)
1950 do_test(self, '// No newline\n// at EOF', True)
1952 def test_invalid_utf8(self):
1953 def do_test(self, raw_bytes, has_invalid_utf8):
1954 error_collector = ErrorCollector(self.assertTrue)
1955 self.process_file_data('foo.cpp', 'cpp',
1956 unicode(raw_bytes, 'utf8', 'replace').split('\n'),
1958 # The warning appears only once.
1960 int(has_invalid_utf8),
1961 error_collector.results().count(
1962 'Line contains invalid UTF-8'
1963 ' (or Unicode replacement character).'
1964 ' [readability/utf8] [5]'))
1966 do_test(self, 'Hello world\n', False)
1967 do_test(self, '\xe9\x8e\xbd\n', False)
1968 do_test(self, '\xe9x\x8e\xbd\n', True)
1969 # This is the encoding of the replacement character itself (which
1970 # you can see by evaluating codecs.getencoder('utf8')(u'\ufffd')).
1971 do_test(self, '\xef\xbf\xbd\n', True)
1973 def test_is_blank_line(self):
1974 self.assertTrue(cpp_style.is_blank_line(''))
1975 self.assertTrue(cpp_style.is_blank_line(' '))
1976 self.assertTrue(cpp_style.is_blank_line(' \t\r\n'))
1977 self.assertTrue(not cpp_style.is_blank_line('int a;'))
1978 self.assertTrue(not cpp_style.is_blank_line('{'))
1980 def test_blank_lines_check(self):
1981 self.assert_blank_lines_check(['{\n', '\n', '\n', '}\n'], 1, 1)
1982 self.assert_blank_lines_check([' if (foo) {\n', '\n', ' }\n'], 1, 1)
1983 self.assert_blank_lines_check(
1984 ['\n', '// {\n', '\n', '\n', '// Comment\n', '{\n', '}\n'], 0, 0)
1985 self.assert_blank_lines_check(['\n', 'run("{");\n', '\n'], 0, 0)
1986 self.assert_blank_lines_check(['\n', ' if (foo) { return 0; }\n', '\n'], 0, 0)
1988 def test_allow_blank_line_before_closing_namespace(self):
1989 error_collector = ErrorCollector(self.assertTrue)
1990 self.process_file_data('foo.cpp', 'cpp',
1991 ['namespace {', '', '} // namespace'],
1993 self.assertEqual(0, error_collector.results().count(
1994 'Blank line at the end of a code block. Is this needed?'
1995 ' [whitespace/blank_line] [3]'))
1997 def test_allow_blank_line_before_if_else_chain(self):
1998 error_collector = ErrorCollector(self.assertTrue)
1999 self.process_file_data('foo.cpp', 'cpp',
2002 '} else if (piyo) {',
2004 '} else if (piyopiyo) {',
2005 ' hoge = true;', # No warning
2007 '', # Warning on this line
2010 self.assertEqual(1, error_collector.results().count(
2011 'Blank line at the end of a code block. Is this needed?'
2012 ' [whitespace/blank_line] [3]'))
2014 def test_else_on_same_line_as_closing_braces(self):
2015 error_collector = ErrorCollector(self.assertTrue)
2016 self.process_file_data('foo.cpp', 'cpp',
2020 ' else {' # Warning on this line
2024 self.assertEqual(1, error_collector.results().count(
2025 'An else should appear on the same line as the preceding }'
2026 ' [whitespace/newline] [4]'))
2028 def test_else_clause_not_on_same_line_as_else(self):
2029 self.assert_lint(' else DoSomethingElse();',
2030 'Else clause should never be on same line as else '
2031 '(use 2 lines) [whitespace/newline] [4]')
2032 self.assert_lint(' else ifDoSomethingElse();',
2033 'Else clause should never be on same line as else '
2034 '(use 2 lines) [whitespace/newline] [4]')
2035 self.assert_lint(' else if (blah) {', '')
2036 self.assert_lint(' variable_ends_in_else = true;', '')
2038 def test_comma(self):
2039 self.assert_lint('a = f(1,2);',
2040 'Missing space after , [whitespace/comma] [3]')
2041 self.assert_lint('int tmp=a,a=b,b=tmp;',
2042 ['Missing spaces around = [whitespace/operators] [4]',
2043 'Missing space after , [whitespace/comma] [3]'])
2044 self.assert_lint('f(a, /* name */ b);', '')
2045 self.assert_lint('f(a, /* name */b);', '')
2047 def test_declaration(self):
2048 self.assert_lint('int a;', '')
2049 self.assert_lint('int a;', 'Extra space between int and a [whitespace/declaration] [3]')
2050 self.assert_lint('int* a;', 'Extra space between int* and a [whitespace/declaration] [3]')
2051 self.assert_lint('else if { }', '')
2052 self.assert_lint('else if { }', 'Extra space between else and if [whitespace/declaration] [3]')
2054 def test_pointer_reference_marker_location(self):
2055 self.assert_lint('int* b;', '', 'foo.cpp')
2056 self.assert_lint('int *b;',
2057 'Declaration has space between type name and * in int *b [whitespace/declaration] [3]',
2059 self.assert_lint('return *b;', '', 'foo.cpp')
2060 self.assert_lint('delete *b;', '', 'foo.cpp')
2061 self.assert_lint('int *b;', '', 'foo.c')
2062 self.assert_lint('int* b;',
2063 'Declaration has space between * and variable name in int* b [whitespace/declaration] [3]',
2065 self.assert_lint('int& b;', '', 'foo.cpp')
2066 self.assert_lint('int &b;',
2067 'Declaration has space between type name and & in int &b [whitespace/declaration] [3]',
2069 self.assert_lint('return &b;', '', 'foo.cpp')
2071 def test_indent(self):
2072 self.assert_lint('static int noindent;', '')
2073 self.assert_lint(' int fourSpaceIndent;', '')
2074 self.assert_lint(' int oneSpaceIndent;',
2075 'Weird number of spaces at line-start. '
2076 'Are you using a 4-space indent? [whitespace/indent] [3]')
2077 self.assert_lint(' int threeSpaceIndent;',
2078 'Weird number of spaces at line-start. '
2079 'Are you using a 4-space indent? [whitespace/indent] [3]')
2080 self.assert_lint(' char* oneSpaceIndent = "public:";',
2081 'Weird number of spaces at line-start. '
2082 'Are you using a 4-space indent? [whitespace/indent] [3]')
2083 self.assert_lint(' public:',
2084 'Weird number of spaces at line-start. '
2085 'Are you using a 4-space indent? [whitespace/indent] [3]')
2086 self.assert_lint(' public:',
2087 'Weird number of spaces at line-start. '
2088 'Are you using a 4-space indent? [whitespace/indent] [3]')
2089 self.assert_lint(' public:',
2090 'Weird number of spaces at line-start. '
2091 'Are you using a 4-space indent? [whitespace/indent] [3]')
2092 self.assert_multi_line_lint(
2098 '#if ENABLED_BETZ\n'
2104 self.assert_multi_line_lint(
2106 ' myFunction(reallyLongParam1, reallyLongParam2,\n'
2107 ' reallyLongParam3);\n'
2109 'Weird number of spaces at line-start. Are you using a 4-space indent? [whitespace/indent] [3]')
2111 self.assert_multi_line_lint(
2113 ' myFunction(reallyLongParam1, reallyLongParam2,\n'
2114 ' reallyLongParam3);\n'
2116 'When wrapping a line, only indent 4 spaces. [whitespace/indent] [3]')
2119 def test_not_alabel(self):
2120 self.assert_lint('MyVeryLongNamespace::MyVeryLongClassName::', '')
2123 self.assert_lint('\tint a;',
2124 'Tab found; better to use spaces [whitespace/tab] [1]')
2125 self.assert_lint('int a = 5;\t// set a to 5',
2126 'Tab found; better to use spaces [whitespace/tab] [1]')
2128 def test_unnamed_namespaces_in_headers(self):
2129 self.assert_language_rules_check(
2130 'foo.h', 'namespace {',
2131 'Do not use unnamed namespaces in header files. See'
2132 ' http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Namespaces'
2133 ' for more information. [build/namespaces] [4]')
2134 # namespace registration macros are OK.
2135 self.assert_language_rules_check('foo.h', 'namespace { \\', '')
2136 # named namespaces are OK.
2137 self.assert_language_rules_check('foo.h', 'namespace foo {', '')
2138 self.assert_language_rules_check('foo.h', 'namespace foonamespace {', '')
2139 self.assert_language_rules_check('foo.cpp', 'namespace {', '')
2140 self.assert_language_rules_check('foo.cpp', 'namespace foo {', '')
2142 def test_build_class(self):
2143 # Test that the linter can parse to the end of class definitions,
2144 # and that it will report when it can't.
2145 # Use multi-line linter because it performs the ClassState check.
2146 self.assert_multi_line_lint(
2148 'Failed to find complete declaration of class Foo'
2149 ' [build/class] [5]')
2150 # Don't warn on forward declarations of various types.
2151 self.assert_multi_line_lint(
2154 self.assert_multi_line_lint(
2159 # Here is an example where the linter gets confused, even though
2160 # the code doesn't violate the style guide.
2161 self.assert_multi_line_lint(
2163 '#ifdef DERIVE_FROM_GOO\n'
2169 'Failed to find complete declaration of class Foo'
2170 ' [build/class] [5]')
2172 def test_build_end_comment(self):
2173 # The crosstool compiler we currently use will fail to compile the
2174 # code in this test, so we might consider removing the lint check.
2175 self.assert_lint('#endif Not a comment',
2176 'Uncommented text after #endif is non-standard.'
2178 ' [build/endif_comment] [5]')
2180 def test_build_forward_decl(self):
2181 # The crosstool compiler we currently use will fail to compile the
2182 # code in this test, so we might consider removing the lint check.
2183 self.assert_lint('class Foo::Goo;',
2184 'Inner-style forward declarations are invalid.'
2185 ' Remove this line.'
2186 ' [build/forward_decl] [5]')
2188 def test_build_header_guard(self):
2189 file_path = 'mydir/Foo.h'
2191 # We can't rely on our internal stuff to get a sane path on the open source
2192 # side of things, so just parse out the suggested header guard. This
2193 # doesn't allow us to test the suggested header guard, but it does let us
2194 # test all the other header tests.
2195 error_collector = ErrorCollector(self.assertTrue)
2196 self.process_file_data(file_path, 'h', [], error_collector)
2198 matcher = re.compile(
2199 'No \#ifndef header guard found\, suggested CPP variable is\: ([A-Za-z_0-9]+) ')
2200 for error in error_collector.result_list():
2201 matches = matcher.match(error)
2203 expected_guard = matches.group(1)
2206 # Make sure we extracted something for our header guard.
2207 self.assertNotEqual(expected_guard, '')
2210 error_collector = ErrorCollector(self.assertTrue)
2211 self.process_file_data(file_path, 'h',
2212 ['#ifndef FOO_H', '#define FOO_H'], error_collector)
2215 error_collector.result_list().count(
2216 '#ifndef header guard has wrong style, please use: %s'
2217 ' [build/header_guard] [5]' % expected_guard),
2218 error_collector.result_list())
2221 error_collector = ErrorCollector(self.assertTrue)
2222 self.process_file_data(file_path, 'h',
2223 ['#ifndef %s' % expected_guard], error_collector)
2226 error_collector.result_list().count(
2227 'No #ifndef header guard found, suggested CPP variable is: %s'
2228 ' [build/header_guard] [5]' % expected_guard),
2229 error_collector.result_list())
2232 error_collector = ErrorCollector(self.assertTrue)
2233 self.process_file_data(file_path, 'h',
2234 ['#ifndef %s' % expected_guard,
2239 error_collector.result_list().count(
2240 'No #ifndef header guard found, suggested CPP variable is: %s'
2241 ' [build/header_guard] [5]' % expected_guard),
2242 error_collector.result_list())
2244 # No header guard errors
2245 error_collector = ErrorCollector(self.assertTrue)
2246 self.process_file_data(file_path, 'h',
2247 ['#ifndef %s' % expected_guard,
2248 '#define %s' % expected_guard,
2249 '#endif // %s' % expected_guard],
2251 for line in error_collector.result_list():
2252 if line.find('build/header_guard') != -1:
2253 self.fail('Unexpected error: %s' % line)
2255 # Completely incorrect header guard
2256 error_collector = ErrorCollector(self.assertTrue)
2257 self.process_file_data(file_path, 'h',
2264 error_collector.result_list().count(
2265 '#ifndef header guard has wrong style, please use: %s'
2266 ' [build/header_guard] [5]' % expected_guard),
2267 error_collector.result_list())
2269 # Special case for flymake
2270 error_collector = ErrorCollector(self.assertTrue)
2271 self.process_file_data('mydir/Foo_flymake.h', 'h',
2272 ['#ifndef %s' % expected_guard,
2273 '#define %s' % expected_guard,
2274 '#endif // %s' % expected_guard],
2276 for line in error_collector.result_list():
2277 if line.find('build/header_guard') != -1:
2278 self.fail('Unexpected error: %s' % line)
2280 error_collector = ErrorCollector(self.assertTrue)
2281 self.process_file_data('mydir/Foo_flymake.h', 'h', [], error_collector)
2284 error_collector.result_list().count(
2285 'No #ifndef header guard found, suggested CPP variable is: %s'
2286 ' [build/header_guard] [5]' % expected_guard),
2287 error_collector.result_list())
2289 # Verify that we don't blindly suggest the WTF prefix for all headers.
2290 self.assertFalse(expected_guard.startswith('WTF_'))
2292 # Allow the WTF_ prefix for files in that directory.
2293 header_guard_filter = FilterConfiguration(('-', '+build/header_guard'))
2294 error_collector = ErrorCollector(self.assertTrue, header_guard_filter)
2295 self.process_file_data('Source/JavaScriptCore/wtf/TestName.h', 'h',
2296 ['#ifndef WTF_TestName_h', '#define WTF_TestName_h'],
2298 self.assertEqual(0, len(error_collector.result_list()),
2299 error_collector.result_list())
2301 # Also allow the non WTF_ prefix for files in that directory.
2302 error_collector = ErrorCollector(self.assertTrue, header_guard_filter)
2303 self.process_file_data('Source/JavaScriptCore/wtf/TestName.h', 'h',
2304 ['#ifndef TestName_h', '#define TestName_h'],
2306 self.assertEqual(0, len(error_collector.result_list()),
2307 error_collector.result_list())
2309 # Verify that we suggest the WTF prefix version.
2310 error_collector = ErrorCollector(self.assertTrue, header_guard_filter)
2311 self.process_file_data('Source/JavaScriptCore/wtf/TestName.h', 'h',
2312 ['#ifndef BAD_TestName_h', '#define BAD_TestName_h'],
2316 error_collector.result_list().count(
2317 '#ifndef header guard has wrong style, please use: WTF_TestName_h'
2318 ' [build/header_guard] [5]'),
2319 error_collector.result_list())
2321 # Verify that the Chromium-style header guard is allowed as well.
2322 error_collector = ErrorCollector(self.assertTrue, header_guard_filter)
2323 self.process_file_data('Source/foo/testname.h', 'h',
2324 ['#ifndef BLINK_FOO_TESTNAME_H_',
2325 '#define BLINK_FOO_TESTNAME_H_'],
2327 self.assertEqual(0, len(error_collector.result_list()),
2328 error_collector.result_list())
2330 def test_build_printf_format(self):
2332 r'printf("\%%d", value);',
2333 '%, [, (, and { are undefined character escapes. Unescape them.'
2334 ' [build/printf_format] [3]')
2337 r'snprintf(buffer, sizeof(buffer), "\[%d", value);',
2338 '%, [, (, and { are undefined character escapes. Unescape them.'
2339 ' [build/printf_format] [3]')
2342 r'fprintf(file, "\(%d", value);',
2343 '%, [, (, and { are undefined character escapes. Unescape them.'
2344 ' [build/printf_format] [3]')
2347 r'vsnprintf(buffer, sizeof(buffer), "\\\{%d", ap);',
2348 '%, [, (, and { are undefined character escapes. Unescape them.'
2349 ' [build/printf_format] [3]')
2351 # Don't warn if double-slash precedes the symbol
2352 self.assert_lint(r'printf("\\%%%d", value);',
2355 def test_runtime_printf_format(self):
2357 r'fprintf(file, "%q", value);',
2358 '%q in format strings is deprecated. Use %ll instead.'
2359 ' [runtime/printf_format] [3]')
2362 r'aprintf(file, "The number is %12q", value);',
2363 '%q in format strings is deprecated. Use %ll instead.'
2364 ' [runtime/printf_format] [3]')
2367 r'printf(file, "The number is" "%-12q", value);',
2368 '%q in format strings is deprecated. Use %ll instead.'
2369 ' [runtime/printf_format] [3]')
2372 r'printf(file, "The number is" "%+12q", value);',
2373 '%q in format strings is deprecated. Use %ll instead.'
2374 ' [runtime/printf_format] [3]')
2377 r'printf(file, "The number is" "% 12q", value);',
2378 '%q in format strings is deprecated. Use %ll instead.'
2379 ' [runtime/printf_format] [3]')
2382 r'snprintf(file, "Never mix %d and %1$d parmaeters!", value);',
2383 '%N$ formats are unconventional. Try rewriting to avoid them.'
2384 ' [runtime/printf_format] [2]')
2386 def assert_lintLogCodeOnError(self, code, expected_message):
2387 # Special assert_lint which logs the input code on error.
2388 result = self.perform_single_line_lint(code, 'foo.cpp')
2389 if result != expected_message:
2390 self.fail('For code: "%s"\nGot: "%s"\nExpected: "%s"'
2391 % (code, result, expected_message))
2393 def test_build_storage_class(self):
2394 qualifiers = [None, 'const', 'volatile']
2395 signs = [None, 'signed', 'unsigned']
2396 types = ['void', 'char', 'int', 'float', 'double',
2397 'schar', 'int8', 'uint8', 'int16', 'uint16',
2398 'int32', 'uint32', 'int64', 'uint64']
2399 storage_classes = ['auto', 'extern', 'register', 'static', 'typedef']
2401 build_storage_class_error_message = (
2402 'Storage class (static, extern, typedef, etc) should be first.'
2403 ' [build/storage_class] [5]')
2405 # Some explicit cases. Legal in C++, deprecated in C99.
2406 self.assert_lint('const int static foo = 5;',
2407 build_storage_class_error_message)
2409 self.assert_lint('char static foo;',
2410 build_storage_class_error_message)
2412 self.assert_lint('double const static foo = 2.0;',
2413 build_storage_class_error_message)
2415 self.assert_lint('uint64 typedef unsignedLongLong;',
2416 build_storage_class_error_message)
2418 self.assert_lint('int register foo = 0;',
2419 build_storage_class_error_message)
2421 # Since there are a very large number of possibilities, randomly
2422 # construct declarations.
2423 # Make sure that the declaration is logged if there's an error.
2424 # Seed generator with an integer for absolute reproducibility.
2426 for unused_i in range(10):
2427 # Build up random list of non-storage-class declaration specs.
2428 other_decl_specs = [random.choice(qualifiers), random.choice(signs),
2429 random.choice(types)]
2431 other_decl_specs = filter(lambda x: x is not None, other_decl_specs)
2434 random.shuffle(other_decl_specs)
2436 # insert storage class after the first
2437 storage_class = random.choice(storage_classes)
2438 insertion_point = random.randint(1, len(other_decl_specs))
2439 decl_specs = (other_decl_specs[0:insertion_point]
2441 + other_decl_specs[insertion_point:])
2443 self.assert_lintLogCodeOnError(
2444 ' '.join(decl_specs) + ';',
2445 build_storage_class_error_message)
2447 # but no error if storage class is first
2448 self.assert_lintLogCodeOnError(
2449 storage_class + ' ' + ' '.join(other_decl_specs),
2452 def test_legal_copyright(self):
2453 legal_copyright_message = (
2454 'No copyright message found. '
2455 'You should have a line: "Copyright [year] <Copyright Owner>"'
2456 ' [legal/copyright] [5]')
2458 copyright_line = '// Copyright 2008 Google Inc. All Rights Reserved.'
2460 file_path = 'mydir/googleclient/foo.cpp'
2462 # There should be a copyright message in the first 10 lines
2463 error_collector = ErrorCollector(self.assertTrue)
2464 self.process_file_data(file_path, 'cpp', [], error_collector)
2467 error_collector.result_list().count(legal_copyright_message))
2469 error_collector = ErrorCollector(self.assertTrue)
2470 self.process_file_data(
2472 ['' for unused_i in range(10)] + [copyright_line],
2476 error_collector.result_list().count(legal_copyright_message))
2478 # Test that warning isn't issued if Copyright line appears early enough.
2479 error_collector = ErrorCollector(self.assertTrue)
2480 self.process_file_data(file_path, 'cpp', [copyright_line], error_collector)
2481 for message in error_collector.result_list():
2482 if message.find('legal/copyright') != -1:
2483 self.fail('Unexpected error: %s' % message)
2485 error_collector = ErrorCollector(self.assertTrue)
2486 self.process_file_data(
2488 ['' for unused_i in range(9)] + [copyright_line],
2490 for message in error_collector.result_list():
2491 if message.find('legal/copyright') != -1:
2492 self.fail('Unexpected error: %s' % message)
2494 def test_invalid_increment(self):
2495 self.assert_lint('*count++;',
2496 'Changing pointer instead of value (or unused value of '
2497 'operator*). [runtime/invalid_increment] [5]')
2499 # Integral bitfields must be declared with either signed or unsigned keyword.
2500 def test_plain_integral_bitfields(self):
2501 errmsg = ('Please declare integral type bitfields with either signed or unsigned. [runtime/bitfields] [5]')
2503 self.assert_lint('int a : 30;', errmsg)
2504 self.assert_lint('mutable short a : 14;', errmsg)
2505 self.assert_lint('const char a : 6;', errmsg)
2506 self.assert_lint('long int a : 30;', errmsg)
2507 self.assert_lint('int a = 1 ? 0 : 30;', '')
2509 # A mixture of unsigned and bool bitfields in a class will generate a warning.
2510 def test_mixing_unsigned_bool_bitfields(self):
2511 def errmsg(bool_bitfields, unsigned_bitfields, name):
2512 bool_list = ', '.join(bool_bitfields)
2513 unsigned_list = ', '.join(unsigned_bitfields)
2514 return ('The class %s contains mixed unsigned and bool bitfields, '
2515 'which will pack into separate words on the MSVC compiler.\n'
2516 'Bool bitfields are [%s].\nUnsigned bitfields are [%s].\n'
2517 'Consider converting bool bitfields to unsigned. [runtime/bitfields] [5]'
2518 % (name, bool_list, unsigned_list))
2520 def build_test_case(bitfields, name, will_warn, extra_warnings=[]):
2522 unsigned_bitfields = []
2523 test_string = 'class %s {\n' % (name,)
2525 for bitfield in bitfields:
2526 test_string += ' %s %s : %d;\n' % bitfield
2527 if bitfield[0] == 'bool':
2528 bool_bitfields.append('%d: %s' % (line, bitfield[1]))
2529 elif bitfield[0].startswith('unsigned'):
2530 unsigned_bitfields.append('%d: %s' % (line, bitfield[1]))
2532 test_string += '}\n'
2535 error = errmsg(bool_bitfields, unsigned_bitfields, name)
2536 if extra_warnings and error:
2537 error = extra_warnings + [error]
2538 self.assert_multi_line_lint(test_string, error)
2540 build_test_case([('bool', 'm_boolMember', 4), ('unsigned', 'm_unsignedMember', 3)],
2542 build_test_case([('bool', 'm_boolMember', 4), ('bool', 'm_anotherBool', 3)],
2544 build_test_case([('unsigned', 'm_unsignedMember', 4), ('unsigned', 'm_anotherUnsigned', 3)],
2547 build_test_case([('bool', 'm_boolMember', 4), ('bool', 'm_anotherbool', 3),
2548 ('bool', 'm_moreBool', 1), ('bool', 'm_lastBool', 1),
2549 ('unsigned int', 'm_tokenUnsigned', 4)],
2550 'MyClass', True, ['Omit int when using unsigned [runtime/unsigned] [1]'])
2552 self.assert_multi_line_lint('class NoProblemsHere {\n'
2553 ' bool m_boolMember;\n'
2554 ' unsigned m_unsignedMember;\n'
2555 ' unsigned m_bitField1 : 1;\n'
2556 ' unsigned m_bitField4 : 4;\n'
2559 # Bitfields which are not declared unsigned or bool will generate a warning.
2560 def test_unsigned_bool_bitfields(self):
2561 def errmsg(member, name, bit_type):
2562 return ('Member %s of class %s defined as a bitfield of type %s. '
2563 'Please declare all bitfields as unsigned. [runtime/bitfields] [4]'
2564 % (member, name, bit_type))
2566 def warning_bitfield_test(member, name, bit_type, bits):
2567 self.assert_multi_line_lint('class %s {\n%s %s: %d;\n}\n'
2568 % (name, bit_type, member, bits),
2569 errmsg(member, name, bit_type))
2571 def safe_bitfield_test(member, name, bit_type, bits):
2572 self.assert_multi_line_lint('class %s {\n%s %s: %d;\n}\n'
2573 % (name, bit_type, member, bits),
2576 warning_bitfield_test('a', 'A', 'int32_t', 25)
2577 warning_bitfield_test('m_someField', 'SomeClass', 'signed', 4)
2578 warning_bitfield_test('m_someField', 'SomeClass', 'SomeEnum', 2)
2580 safe_bitfield_test('a', 'A', 'unsigned', 22)
2581 safe_bitfield_test('m_someField', 'SomeClass', 'bool', 1)
2582 safe_bitfield_test('m_someField', 'SomeClass', 'unsigned', 2)
2584 # Declarations in 'Expected' or 'SameSizeAs' classes are OK.
2585 warning_bitfield_test('m_bitfields', 'SomeClass', 'int32_t', 32)
2586 safe_bitfield_test('m_bitfields', 'ExpectedSomeClass', 'int32_t', 32)
2587 safe_bitfield_test('m_bitfields', 'SameSizeAsSomeClass', 'int32_t', 32)
2589 class CleansedLinesTest(unittest.TestCase):
2590 def test_init(self):
2593 'Line 3 // Comment test',
2596 clean_lines = cpp_style.CleansedLines(lines)
2597 self.assertEqual(lines, clean_lines.raw_lines)
2598 self.assertEqual(4, clean_lines.num_lines())
2600 self.assertEqual(['Line 1',
2606 self.assertEqual(['Line 1',
2612 def test_init_empty(self):
2613 clean_lines = cpp_style.CleansedLines([])
2614 self.assertEqual([], clean_lines.raw_lines)
2615 self.assertEqual(0, clean_lines.num_lines())
2617 def test_collapse_strings(self):
2618 collapse = cpp_style.CleansedLines.collapse_strings
2619 self.assertEqual('""', collapse('""')) # "" (empty)
2620 self.assertEqual('"""', collapse('"""')) # """ (bad)
2621 self.assertEqual('""', collapse('"xyz"')) # "xyz" (string)
2622 self.assertEqual('""', collapse('"\\\""')) # "\"" (string)
2623 self.assertEqual('""', collapse('"\'"')) # "'" (string)
2624 self.assertEqual('"\"', collapse('"\"')) # "\" (bad)
2625 self.assertEqual('""', collapse('"\\\\"')) # "\\" (string)
2626 self.assertEqual('"', collapse('"\\\\\\"')) # "\\\" (bad)
2627 self.assertEqual('""', collapse('"\\\\\\\\"')) # "\\\\" (string)
2629 self.assertEqual('\'\'', collapse('\'\'')) # '' (empty)
2630 self.assertEqual('\'\'', collapse('\'a\'')) # 'a' (char)
2631 self.assertEqual('\'\'', collapse('\'\\\'\'')) # '\'' (char)
2632 self.assertEqual('\'', collapse('\'\\\'')) # '\' (bad)
2633 self.assertEqual('', collapse('\\012')) # '\012' (char)
2634 self.assertEqual('', collapse('\\xfF0')) # '\xfF0' (char)
2635 self.assertEqual('', collapse('\\n')) # '\n' (char)
2636 self.assertEqual('\#', collapse('\\#')) # '\#' (bad)
2638 self.assertEqual('StringReplace(body, "", "");',
2639 collapse('StringReplace(body, "\\\\", "\\\\\\\\");'))
2640 self.assertEqual('\'\' ""',
2641 collapse('\'"\' "foo"'))
2644 class OrderOfIncludesTest(CppStyleTestBase):
2646 self.include_state = cpp_style._IncludeState()
2648 # Cheat os.path.abspath called in FileInfo class.
2649 self.os_path_abspath_orig = os.path.abspath
2650 os.path.abspath = lambda value: value
2653 os.path.abspath = self.os_path_abspath_orig
2655 def test_try_drop_common_suffixes(self):
2656 self.assertEqual('foo/foo', cpp_style._drop_common_suffixes('foo/foo-inl.h'))
2657 self.assertEqual('foo/bar/foo',
2658 cpp_style._drop_common_suffixes('foo/bar/foo_inl.h'))
2659 self.assertEqual('foo/foo', cpp_style._drop_common_suffixes('foo/foo.cpp'))
2660 self.assertEqual('foo/foo_unusualinternal',
2661 cpp_style._drop_common_suffixes('foo/foo_unusualinternal.h'))
2662 self.assertEqual('',
2663 cpp_style._drop_common_suffixes('_test.cpp'))
2664 self.assertEqual('test',
2665 cpp_style._drop_common_suffixes('test.cpp'))
2668 class OrderOfIncludesTest(CppStyleTestBase):
2670 self.include_state = cpp_style._IncludeState()
2672 # Cheat os.path.abspath called in FileInfo class.
2673 self.os_path_abspath_orig = os.path.abspath
2674 self.os_path_isfile_orig = os.path.isfile
2675 os.path.abspath = lambda value: value
2678 os.path.abspath = self.os_path_abspath_orig
2679 os.path.isfile = self.os_path_isfile_orig
2681 def test_check_next_include_order__no_config(self):
2682 self.assertEqual('Header file should not contain WebCore config.h.',
2683 self.include_state.check_next_include_order(cpp_style._CONFIG_HEADER, True, True))
2685 def test_check_next_include_order__no_self(self):
2686 self.assertEqual('Header file should not contain itself.',
2687 self.include_state.check_next_include_order(cpp_style._PRIMARY_HEADER, True, True))
2688 # Test actual code to make sure that header types are correctly assigned.
2689 self.assert_language_rules_check('Foo.h',
2690 '#include "Foo.h"\n',
2691 'Header file should not contain itself. Should be: alphabetically sorted.'
2692 ' [build/include_order] [4]')
2693 self.assert_language_rules_check('FooBar.h',
2694 '#include "Foo.h"\n',
2697 def test_check_next_include_order__likely_then_config(self):
2698 self.assertEqual('Found header this file implements before WebCore config.h.',
2699 self.include_state.check_next_include_order(cpp_style._PRIMARY_HEADER, False, True))
2700 self.assertEqual('Found WebCore config.h after a header this file implements.',
2701 self.include_state.check_next_include_order(cpp_style._CONFIG_HEADER, False, True))
2703 def test_check_next_include_order__other_then_config(self):
2704 self.assertEqual('Found other header before WebCore config.h.',
2705 self.include_state.check_next_include_order(cpp_style._OTHER_HEADER, False, True))
2706 self.assertEqual('Found WebCore config.h after other header.',
2707 self.include_state.check_next_include_order(cpp_style._CONFIG_HEADER, False, True))
2709 def test_check_next_include_order__config_then_other_then_likely(self):
2710 self.assertEqual('', self.include_state.check_next_include_order(cpp_style._CONFIG_HEADER, False, True))
2711 self.assertEqual('Found other header before a header this file implements.',
2712 self.include_state.check_next_include_order(cpp_style._OTHER_HEADER, False, True))
2713 self.assertEqual('Found header this file implements after other header.',
2714 self.include_state.check_next_include_order(cpp_style._PRIMARY_HEADER, False, True))
2716 def test_check_alphabetical_include_order(self):
2717 self.assert_language_rules_check('foo.h',
2721 'Alphabetical sorting problem. [build/include_order] [4]')
2723 self.assert_language_rules_check('foo.h',
2729 self.assert_language_rules_check('foo.h',
2730 '#include <assert.h>\n'
2731 '#include "bar.h"\n',
2732 'Alphabetical sorting problem. [build/include_order] [4]')
2734 self.assert_language_rules_check('foo.h',
2735 '#include "bar.h"\n'
2736 '#include <assert.h>\n',
2739 def test_check_alphabetical_include_order_errors_reported_for_both_lines(self):
2740 # If one of the two lines of out of order headers are filtered, the error should be
2741 # reported on the other line.
2742 self.assert_language_rules_check('foo.h',
2746 'Alphabetical sorting problem. [build/include_order] [4]',
2749 self.assert_language_rules_check('foo.h',
2753 'Alphabetical sorting problem. [build/include_order] [4]',
2756 # If no lines are filtered, the error should be reported only once.
2757 self.assert_language_rules_check('foo.h',
2761 'Alphabetical sorting problem. [build/include_order] [4]')
2763 def test_check_line_break_after_own_header(self):
2764 self.assert_language_rules_check('foo.cpp',
2765 '#include "config.h"\n'
2766 '#include "foo.h"\n'
2767 '#include "bar.h"\n',
2768 'You should add a blank line after implementation file\'s own header. [build/include_order] [4]')
2770 self.assert_language_rules_check('foo.cpp',
2771 '#include "config.h"\n'
2772 '#include "foo.h"\n'
2774 '#include "bar.h"\n',
2777 def test_check_preprocessor_in_include_section(self):
2778 self.assert_language_rules_check('foo.cpp',
2779 '#include "config.h"\n'
2780 '#include "foo.h"\n'
2783 '#include "baz.h"\n'
2785 '#include "foobar.h"\n'
2787 '#include "bar.h"\n', # No flag because previous is in preprocessor section
2790 self.assert_language_rules_check('foo.cpp',
2791 '#include "config.h"\n'
2792 '#include "foo.h"\n'
2795 '#include "baz.h"\n'
2797 '#include "bar.h"\n'
2798 '#include "a.h"\n', # Should still flag this.
2799 'Alphabetical sorting problem. [build/include_order] [4]')
2801 self.assert_language_rules_check('foo.cpp',
2802 '#include "config.h"\n'
2803 '#include "foo.h"\n'
2806 '#include "baz.h"\n'
2807 '#include "bar.h"\n' #Should still flag this
2809 'Alphabetical sorting problem. [build/include_order] [4]')
2811 self.assert_language_rules_check('foo.cpp',
2812 '#include "config.h"\n'
2813 '#include "foo.h"\n'
2816 '#include "baz.h"\n'
2819 '#include "foobar.h"\n'
2821 '#include "bar.h"\n'
2822 '#include "a.h"\n', # Should still flag this.
2823 'Alphabetical sorting problem. [build/include_order] [4]')
2825 # Check that after an already included error, the sorting rules still work.
2826 self.assert_language_rules_check('foo.cpp',
2827 '#include "config.h"\n'
2828 '#include "foo.h"\n'
2830 '#include "foo.h"\n'
2832 '"foo.h" already included at foo.cpp:2 [build/include] [4]')
2834 def test_primary_header(self):
2835 # File with non-existing primary header should not produce errors.
2836 self.assert_language_rules_check('foo.cpp',
2837 '#include "config.h"\n'
2839 '#include "bar.h"\n',
2841 # Pretend that header files exist.
2842 os.path.isfile = lambda filename: True
2843 # Missing include for existing primary header -> error.
2844 self.assert_language_rules_check('foo.cpp',
2845 '#include "config.h"\n'
2847 '#include "bar.h"\n',
2848 'Found other header before a header this file implements. '
2849 'Should be: config.h, primary header, blank line, and then '
2850 'alphabetically sorted. [build/include_order] [4]')
2851 # Having include for existing primary header -> no error.
2852 self.assert_language_rules_check('foo.cpp',
2853 '#include "config.h"\n'
2854 '#include "foo.h"\n'
2856 '#include "bar.h"\n',
2859 os.path.isfile = self.os_path_isfile_orig
2861 def test_public_primary_header(self):
2862 # System header is not considered a primary header.
2863 self.assert_language_rules_check('foo.cpp',
2864 '#include "config.h"\n'
2865 '#include <other/foo.h>\n'
2868 'Alphabetical sorting problem. [build/include_order] [4]')
2870 # ...except that it starts with public/.
2871 self.assert_language_rules_check('foo.cpp',
2872 '#include "config.h"\n'
2873 '#include <public/foo.h>\n'
2878 # Even if it starts with public/ its base part must match with the source file name.
2879 self.assert_language_rules_check('foo.cpp',
2880 '#include "config.h"\n'
2881 '#include <public/foop.h>\n'
2884 'Alphabetical sorting problem. [build/include_order] [4]')
2886 def test_check_wtf_includes(self):
2887 self.assert_language_rules_check('foo.cpp',
2888 '#include "config.h"\n'
2889 '#include "foo.h"\n'
2891 '#include <wtf/Assertions.h>\n',
2892 'wtf includes should be "wtf/file.h" instead of <wtf/file.h>.'
2893 ' [build/include] [4]')
2894 self.assert_language_rules_check('foo.cpp',
2895 '#include "config.h"\n'
2896 '#include "foo.h"\n'
2898 '#include "wtf/Assertions.h"\n',
2901 def test_check_cc_includes(self):
2902 self.assert_language_rules_check('bar/chromium/foo.cpp',
2903 '#include "config.h"\n'
2904 '#include "foo.h"\n'
2906 '#include "cc/CCProxy.h"\n',
2907 'cc includes should be "CCFoo.h" instead of "cc/CCFoo.h".'
2908 ' [build/include] [4]')
2910 def test_classify_include(self):
2911 classify_include = cpp_style._classify_include
2912 include_state = cpp_style._IncludeState()
2913 self.assertEqual(cpp_style._CONFIG_HEADER,
2914 classify_include('foo/foo.cpp',
2916 False, include_state))
2917 self.assertEqual(cpp_style._PRIMARY_HEADER,
2918 classify_include('foo/internal/foo.cpp',
2920 False, include_state))
2921 self.assertEqual(cpp_style._PRIMARY_HEADER,
2922 classify_include('foo/internal/foo.cpp',
2923 'foo/other/public/foo.h',
2924 False, include_state))
2925 self.assertEqual(cpp_style._OTHER_HEADER,
2926 classify_include('foo/internal/foo.cpp',
2927 'foo/other/public/foop.h',
2928 False, include_state))
2929 self.assertEqual(cpp_style._OTHER_HEADER,
2930 classify_include('foo/foo.cpp',
2932 True, include_state))
2933 self.assertEqual(cpp_style._PRIMARY_HEADER,
2934 classify_include('fooCustom.cpp',
2936 False, include_state))
2937 self.assertEqual(cpp_style._PRIMARY_HEADER,
2938 classify_include('PrefixFooCustom.cpp',
2940 False, include_state))
2941 self.assertEqual(cpp_style._MOC_HEADER,
2942 classify_include('foo.cpp',
2944 False, include_state))
2945 self.assertEqual(cpp_style._MOC_HEADER,
2946 classify_include('foo.cpp',
2948 False, include_state))
2949 # <public/foo.h> must be considered as primary even if is_system is True.
2950 self.assertEqual(cpp_style._PRIMARY_HEADER,
2951 classify_include('foo/foo.cpp',
2953 True, include_state))
2954 self.assertEqual(cpp_style._OTHER_HEADER,
2955 classify_include('foo.cpp',
2957 True, include_state))
2958 self.assertEqual(cpp_style._OTHER_HEADER,
2959 classify_include('foo.cpp',
2961 True, include_state))
2962 # Qt private APIs use _p.h suffix.
2963 self.assertEqual(cpp_style._PRIMARY_HEADER,
2964 classify_include('foo.cpp',
2966 False, include_state))
2967 # Tricky example where both includes might be classified as primary.
2968 self.assert_language_rules_check('ScrollbarThemeWince.cpp',
2969 '#include "config.h"\n'
2970 '#include "ScrollbarThemeWince.h"\n'
2972 '#include "Scrollbar.h"\n',
2974 self.assert_language_rules_check('ScrollbarThemeWince.cpp',
2975 '#include "config.h"\n'
2976 '#include "Scrollbar.h"\n'
2978 '#include "ScrollbarThemeWince.h"\n',
2979 'Found header this file implements after a header this file implements.'
2980 ' Should be: config.h, primary header, blank line, and then alphabetically sorted.'
2981 ' [build/include_order] [4]')
2982 self.assert_language_rules_check('ResourceHandleWin.cpp',
2983 '#include "config.h"\n'
2984 '#include "ResourceHandle.h"\n'
2986 '#include "ResourceHandleWin.h"\n',
2989 def test_try_drop_common_suffixes(self):
2990 self.assertEqual('foo/foo', cpp_style._drop_common_suffixes('foo/foo-inl.h'))
2991 self.assertEqual('foo/bar/foo',
2992 cpp_style._drop_common_suffixes('foo/bar/foo_inl.h'))
2993 self.assertEqual('foo/foo', cpp_style._drop_common_suffixes('foo/foo.cpp'))
2994 self.assertEqual('foo/foo_unusualinternal',
2995 cpp_style._drop_common_suffixes('foo/foo_unusualinternal.h'))
2996 self.assertEqual('',
2997 cpp_style._drop_common_suffixes('_test.cpp'))
2998 self.assertEqual('test',
2999 cpp_style._drop_common_suffixes('test.cpp'))
3000 self.assertEqual('test',
3001 cpp_style._drop_common_suffixes('test.cpp'))
3003 class CheckForFunctionLengthsTest(CppStyleTestBase):
3005 # Reducing these thresholds for the tests speeds up tests significantly.
3006 self.old_normal_trigger = cpp_style._FunctionState._NORMAL_TRIGGER
3007 self.old_test_trigger = cpp_style._FunctionState._TEST_TRIGGER
3009 cpp_style._FunctionState._NORMAL_TRIGGER = 10
3010 cpp_style._FunctionState._TEST_TRIGGER = 25
3013 cpp_style._FunctionState._NORMAL_TRIGGER = self.old_normal_trigger
3014 cpp_style._FunctionState._TEST_TRIGGER = self.old_test_trigger
3016 # FIXME: Eliminate the need for this function.
3017 def set_min_confidence(self, min_confidence):
3018 """Set new test confidence and return old test confidence."""
3019 old_min_confidence = self.min_confidence
3020 self.min_confidence = min_confidence
3021 return old_min_confidence
3023 def assert_function_lengths_check(self, code, expected_message):
3024 """Check warnings for long function bodies are as expected.
3027 code: C++ source code expected to generate a warning message.
3028 expected_message: Message expected to be generated by the C++ code.
3030 self.assertEqual(expected_message,
3031 self.perform_function_lengths_check(code))
3033 def trigger_lines(self, error_level):
3034 """Return number of lines needed to trigger a function length warning.
3037 error_level: --v setting for cpp_style.
3040 Number of lines needed to trigger a function length warning.
3042 return cpp_style._FunctionState._NORMAL_TRIGGER * 2 ** error_level
3044 def trigger_test_lines(self, error_level):
3045 """Return number of lines needed to trigger a test function length warning.
3048 error_level: --v setting for cpp_style.
3051 Number of lines needed to trigger a test function length warning.
3053 return cpp_style._FunctionState._TEST_TRIGGER * 2 ** error_level
3055 def assert_function_length_check_definition(self, lines, error_level):
3056 """Generate long function definition and check warnings are as expected.
3059 lines: Number of lines to generate.
3060 error_level: --v setting for cpp_style.
3062 trigger_level = self.trigger_lines(self.min_confidence)
3063 self.assert_function_lengths_check(
3064 'void test(int x)' + self.function_body(lines),
3065 ('Small and focused functions are preferred: '
3066 'test() has %d non-comment lines '
3067 '(error triggered by exceeding %d lines).'
3068 ' [readability/fn_size] [%d]'
3069 % (lines, trigger_level, error_level)))
3071 def assert_function_length_check_definition_ok(self, lines):
3072 """Generate shorter function definition and check no warning is produced.
3075 lines: Number of lines to generate.
3077 self.assert_function_lengths_check(
3078 'void test(int x)' + self.function_body(lines),
3081 def assert_function_length_check_at_error_level(self, error_level):
3082 """Generate and check function at the trigger level for --v setting.
3085 error_level: --v setting for cpp_style.
3087 self.assert_function_length_check_definition(self.trigger_lines(error_level),
3090 def assert_function_length_check_below_error_level(self, error_level):
3091 """Generate and check function just below the trigger level for --v setting.
3094 error_level: --v setting for cpp_style.
3096 self.assert_function_length_check_definition(self.trigger_lines(error_level) - 1,
3099 def assert_function_length_check_above_error_level(self, error_level):
3100 """Generate and check function just above the trigger level for --v setting.
3103 error_level: --v setting for cpp_style.
3105 self.assert_function_length_check_definition(self.trigger_lines(error_level) + 1,
3108 def function_body(self, number_of_lines):
3109 return ' {\n' + ' this_is_just_a_test();\n' * number_of_lines + '}'
3111 def function_body_with_blank_lines(self, number_of_lines):
3112 return ' {\n' + ' this_is_just_a_test();\n\n' * number_of_lines + '}'
3114 def function_body_with_no_lints(self, number_of_lines):
3115 return ' {\n' + ' this_is_just_a_test(); // NOLINT\n' * number_of_lines + '}'
3117 # Test line length checks.
3118 def test_function_length_check_declaration(self):
3119 self.assert_function_lengths_check(
3120 'void test();', # Not a function definition
3123 def test_function_length_check_declaration_with_block_following(self):
3124 self.assert_function_lengths_check(
3126 + self.function_body(66)), # Not a function definition
3129 def test_function_length_check_class_definition(self):
3130 self.assert_function_lengths_check( # Not a function definition
3131 'class Test' + self.function_body(66) + ';',
3134 def test_function_length_check_trivial(self):
3135 self.assert_function_lengths_check(
3136 'void test() {}', # Not counted
3139 def test_function_length_check_empty(self):
3140 self.assert_function_lengths_check(
3144 def test_function_length_check_definition_below_severity0(self):
3145 old_min_confidence = self.set_min_confidence(0)
3146 self.assert_function_length_check_definition_ok(self.trigger_lines(0) - 1)
3147 self.set_min_confidence(old_min_confidence)
3149 def test_function_length_check_definition_at_severity0(self):
3150 old_min_confidence = self.set_min_confidence(0)
3151 self.assert_function_length_check_definition_ok(self.trigger_lines(0))
3152 self.set_min_confidence(old_min_confidence)
3154 def test_function_length_check_definition_above_severity0(self):
3155 old_min_confidence = self.set_min_confidence(0)
3156 self.assert_function_length_check_above_error_level(0)
3157 self.set_min_confidence(old_min_confidence)
3159 def test_function_length_check_definition_below_severity1v0(self):
3160 old_min_confidence = self.set_min_confidence(0)
3161 self.assert_function_length_check_below_error_level(1)
3162 self.set_min_confidence(old_min_confidence)
3164 def test_function_length_check_definition_at_severity1v0(self):
3165 old_min_confidence = self.set_min_confidence(0)
3166 self.assert_function_length_check_at_error_level(1)
3167 self.set_min_confidence(old_min_confidence)
3169 def test_function_length_check_definition_below_severity1(self):
3170 self.assert_function_length_check_definition_ok(self.trigger_lines(1) - 1)
3172 def test_function_length_check_definition_at_severity1(self):
3173 self.assert_function_length_check_definition_ok(self.trigger_lines(1))
3175 def test_function_length_check_definition_above_severity1(self):
3176 self.assert_function_length_check_above_error_level(1)
3178 def test_function_length_check_definition_severity1_plus_indented(self):
3180 error_lines = self.trigger_lines(error_level) + 1
3181 trigger_level = self.trigger_lines(self.min_confidence)
3183 self.assert_function_lengths_check(
3184 re.sub(r'(?m)^(.)', indent_spaces + r'\1',
3185 'void test_indent(int x)\n' + self.function_body(error_lines)),
3186 ('Small and focused functions are preferred: '
3187 'test_indent() has %d non-comment lines '
3188 '(error triggered by exceeding %d lines).'
3189 ' [readability/fn_size] [%d]')
3190 % (error_lines, trigger_level, error_level))
3192 def test_function_length_check_definition_severity1_plus_blanks(self):
3194 error_lines = self.trigger_lines(error_level) + 1
3195 trigger_level = self.trigger_lines(self.min_confidence)
3196 self.assert_function_lengths_check(
3197 'void test_blanks(int x)' + self.function_body(error_lines),
3198 ('Small and focused functions are preferred: '
3199 'test_blanks() has %d non-comment lines '
3200 '(error triggered by exceeding %d lines).'
3201 ' [readability/fn_size] [%d]')
3202 % (error_lines, trigger_level, error_level))
3204 def test_function_length_check_complex_definition_severity1(self):
3206 error_lines = self.trigger_lines(error_level) + 1
3207 trigger_level = self.trigger_lines(self.min_confidence)
3208 self.assert_function_lengths_check(
3209 ('my_namespace::my_other_namespace::MyVeryLongTypeName<Type1, bool func(const Element*)>*\n'
3210 'my_namespace::my_other_namespace<Type3, Type4>::~MyFunction<Type5<Type6, Type7> >(int arg1, char* arg2)'
3211 + self.function_body(error_lines)),
3212 ('Small and focused functions are preferred: '
3213 'my_namespace::my_other_namespace<Type3, Type4>::~MyFunction<Type5<Type6, Type7> >()'
3214 ' has %d non-comment lines '
3215 '(error triggered by exceeding %d lines).'
3216 ' [readability/fn_size] [%d]')
3217 % (error_lines, trigger_level, error_level))
3219 def test_function_length_check_definition_severity1_for_test(self):
3221 error_lines = self.trigger_test_lines(error_level) + 1
3222 trigger_level = self.trigger_test_lines(self.min_confidence)
3223 self.assert_function_lengths_check(
3224 'TEST_F(Test, Mutator)' + self.function_body(error_lines),
3225 ('Small and focused functions are preferred: '
3226 'TEST_F(Test, Mutator) has %d non-comment lines '
3227 '(error triggered by exceeding %d lines).'
3228 ' [readability/fn_size] [%d]')
3229 % (error_lines, trigger_level, error_level))
3231 def test_function_length_check_definition_severity1_for_split_line_test(self):
3233 error_lines = self.trigger_test_lines(error_level) + 1
3234 trigger_level = self.trigger_test_lines(self.min_confidence)
3235 self.assert_function_lengths_check(
3236 ('TEST_F(GoogleUpdateRecoveryRegistryProtectedTest,\n'
3237 ' FixGoogleUpdate_AllValues_MachineApp)' # note: 4 spaces
3238 + self.function_body(error_lines)),
3239 ('Small and focused functions are preferred: '
3240 'TEST_F(GoogleUpdateRecoveryRegistryProtectedTest, ' # 1 space
3241 'FixGoogleUpdate_AllValues_MachineApp) has %d non-comment lines '
3242 '(error triggered by exceeding %d lines).'
3243 ' [readability/fn_size] [%d]')
3244 % (error_lines, trigger_level, error_level))
3246 def test_function_length_check_definition_severity1_for_bad_test_doesnt_break(self):
3248 error_lines = self.trigger_test_lines(error_level) + 1
3249 trigger_level = self.trigger_test_lines(self.min_confidence)
3250 # Since the function name isn't valid, the function detection algorithm
3251 # will skip it, so no error is produced.
3252 self.assert_function_lengths_check(
3254 + self.function_body(error_lines)),
3257 def test_function_length_check_definition_severity1_with_embedded_no_lints(self):
3259 error_lines = self.trigger_lines(error_level) + 1
3260 trigger_level = self.trigger_lines(self.min_confidence)
3261 self.assert_function_lengths_check(
3262 'void test(int x)' + self.function_body_with_no_lints(error_lines),
3263 ('Small and focused functions are preferred: '
3264 'test() has %d non-comment lines '
3265 '(error triggered by exceeding %d lines).'
3266 ' [readability/fn_size] [%d]')
3267 % (error_lines, trigger_level, error_level))
3269 def test_function_length_check_definition_severity1_with_no_lint(self):
3270 self.assert_function_lengths_check(
3271 ('void test(int x)' + self.function_body(self.trigger_lines(1))
3272 + ' // NOLINT -- long function'),
3275 def test_function_length_check_definition_below_severity2(self):
3276 self.assert_function_length_check_below_error_level(2)
3278 def test_function_length_check_definition_severity2(self):
3279 self.assert_function_length_check_at_error_level(2)
3281 def test_function_length_check_definition_above_severity2(self):
3282 self.assert_function_length_check_above_error_level(2)
3284 def test_function_length_check_definition_below_severity3(self):
3285 self.assert_function_length_check_below_error_level(3)
3287 def test_function_length_check_definition_severity3(self):
3288 self.assert_function_length_check_at_error_level(3)
3290 def test_function_length_check_definition_above_severity3(self):
3291 self.assert_function_length_check_above_error_level(3)
3293 def test_function_length_check_definition_below_severity4(self):
3294 self.assert_function_length_check_below_error_level(4)
3296 def test_function_length_check_definition_severity4(self):
3297 self.assert_function_length_check_at_error_level(4)
3299 def test_function_length_check_definition_above_severity4(self):
3300 self.assert_function_length_check_above_error_level(4)
3302 def test_function_length_check_definition_below_severity5(self):
3303 self.assert_function_length_check_below_error_level(5)
3305 def test_function_length_check_definition_at_severity5(self):
3306 self.assert_function_length_check_at_error_level(5)
3308 def test_function_length_check_definition_above_severity5(self):
3309 self.assert_function_length_check_above_error_level(5)
3311 def test_function_length_check_definition_huge_lines(self):
3313 self.assert_function_length_check_definition(self.trigger_lines(6), 5)
3315 def test_function_length_not_determinable(self):
3316 # Macro invocation without terminating semicolon.
3317 self.assert_function_lengths_check(
3321 # Macro with underscores
3322 self.assert_function_lengths_check(
3323 'MACRO_WITH_UNDERSCORES(arg1, arg2, arg3)',
3326 self.assert_function_lengths_check(
3328 'Lint failed to find start of function body.'
3329 ' [readability/fn_size] [5]')
3332 class NoNonVirtualDestructorsTest(CppStyleTestBase):
3334 def test_no_error(self):
3335 self.assert_multi_line_lint(
3343 self.assert_multi_line_lint(
3346 virtual inline ~Foo();
3351 self.assert_multi_line_lint(
3354 inline virtual ~Foo();
3359 self.assert_multi_line_lint(
3366 self.assert_multi_line_lint(
3367 'class Foo { void foo(); };',
3368 'More than one command on the same line [whitespace/newline] [4]')
3369 self.assert_multi_line_lint(
3371 ' int getIntValue() { ASSERT(m_ptr); return *m_ptr; }\n'
3374 self.assert_multi_line_lint(
3376 ' int getIntValue()\n'
3378 ' ASSERT(m_ptr); return *m_ptr;\n'
3381 'More than one command on the same line [whitespace/newline] [4]')
3383 self.assert_multi_line_lint(
3385 class Qualified::Goo : public Foo {
3390 def test_no_destructor_when_virtual_needed(self):
3391 self.assert_multi_line_lint_re(
3396 'The class Foo probably needs a virtual destructor')
3398 def test_enum_casing(self):
3399 self.assert_multi_line_lint(
3406 enum {FooOne, fooTwo};
3410 ['enum members should use InterCaps with an initial capital letter. [readability/enum_casing] [4]'] * 5)
3412 self.assert_multi_line_lint(
3418 'enum members should use InterCaps with an initial capital letter. [readability/enum_casing] [4]')
3420 self.assert_multi_line_lint(
3426 enum { FooOne, FooTwo };
3427 enum { FooOne, FooTwo } fooVar = FooTwo;
3428 enum { FooOne= FooTwo } foo;
3435 self.assert_multi_line_lint(
3444 self.assert_multi_line_lint(
3447 enum Foo { FOO_ONE, FOO_TWO };''',
3450 def test_destructor_non_virtual_when_virtual_needed(self):
3451 self.assert_multi_line_lint_re(
3457 'The class Foo probably needs a virtual destructor')
3459 def test_no_warn_when_derived(self):
3460 self.assert_multi_line_lint(
3462 class Foo : public Goo {
3467 def test_internal_braces(self):
3468 self.assert_multi_line_lint_re(
3476 'The class Foo probably needs a virtual destructor')
3478 def test_inner_class_needs_virtual_destructor(self):
3479 self.assert_multi_line_lint_re(
3486 'The class Goo probably needs a virtual destructor')
3488 def test_outer_class_needs_virtual_destructor(self):
3489 self.assert_multi_line_lint_re(
3496 'The class Foo probably needs a virtual destructor')
3498 def test_qualified_class_needs_virtual_destructor(self):
3499 self.assert_multi_line_lint_re(
3501 class Qualified::Foo {
3504 'The class Qualified::Foo probably needs a virtual destructor')
3506 def test_multi_line_declaration_no_error(self):
3507 self.assert_multi_line_lint_re(
3515 def test_multi_line_declaration_with_error(self):
3516 self.assert_multi_line_lint(
3522 ['This { should be at the end of the previous line '
3523 '[whitespace/braces] [4]',
3524 'The class Foo probably needs a virtual destructor due to having '
3525 'virtual method(s), one declared at line 3. [runtime/virtual] [4]'])
3528 class PassPtrTest(CppStyleTestBase):
3529 # For http://webkit.org/coding/RefPtr.html
3531 def assert_pass_ptr_check(self, code, expected_message):
3532 """Check warnings for Pass*Ptr are as expected.
3535 code: C++ source code expected to generate a warning message.
3536 expected_message: Message expected to be generated by the C++ code.
3538 self.assertEqual(expected_message,
3539 self.perform_pass_ptr_check(code))
3541 def test_pass_ref_ptr_in_function(self):
3542 self.assert_pass_ptr_check(
3543 'int myFunction()\n'
3545 ' PassRefPtr<Type1> variable = variable2;\n'
3547 'Local variables should never be PassRefPtr (see '
3548 'http://webkit.org/coding/RefPtr.html). [readability/pass_ptr] [5]')
3550 def test_pass_own_ptr_in_function(self):
3551 self.assert_pass_ptr_check(
3552 'int myFunction()\n'
3554 ' PassOwnPtr<Type1> variable = variable2;\n'
3556 'Local variables should never be PassOwnPtr (see '
3557 'http://webkit.org/coding/RefPtr.html). [readability/pass_ptr] [5]')
3559 def test_pass_other_type_ptr_in_function(self):
3560 self.assert_pass_ptr_check(
3561 'int myFunction()\n'
3563 ' PassOtherTypePtr<Type1> variable;\n'
3565 'Local variables should never be PassOtherTypePtr (see '
3566 'http://webkit.org/coding/RefPtr.html). [readability/pass_ptr] [5]')
3568 def test_pass_ref_ptr_return_value(self):
3569 self.assert_pass_ptr_check(
3570 'PassRefPtr<Type1>\n'
3575 self.assert_pass_ptr_check(
3576 'PassRefPtr<Type1> myFunction(int)\n'
3580 self.assert_pass_ptr_check(
3581 'PassRefPtr<Type1> myFunction();\n',
3583 self.assert_pass_ptr_check(
3584 'OwnRefPtr<Type1> myFunction();\n',
3586 self.assert_pass_ptr_check(
3587 'RefPtr<Type1> myFunction(int)\n'
3590 'The return type should use PassRefPtr instead of RefPtr. [readability/pass_ptr] [5]')
3591 self.assert_pass_ptr_check(
3592 'OwnPtr<Type1> myFunction(int)\n'
3595 'The return type should use PassOwnPtr instead of OwnPtr. [readability/pass_ptr] [5]')
3597 def test_ref_ptr_parameter_value(self):
3598 self.assert_pass_ptr_check(
3599 'int myFunction(PassRefPtr<Type1>)\n'
3603 self.assert_pass_ptr_check(
3604 'int myFunction(RefPtr<Type1>)\n'
3607 'The parameter type should use PassRefPtr instead of RefPtr. [readability/pass_ptr] [5]')
3608 self.assert_pass_ptr_check(
3609 'int myFunction(RefPtr<Type1>&)\n'
3613 self.assert_pass_ptr_check(
3614 'int myFunction(RefPtr<Type1>*)\n'
3618 self.assert_pass_ptr_check(
3619 'int myFunction(RefPtr<Type1>* = 0)\n'
3623 self.assert_pass_ptr_check(
3624 'int myFunction(RefPtr<Type1>* = 0)\n'
3629 def test_own_ptr_parameter_value(self):
3630 self.assert_pass_ptr_check(
3631 'int myFunction(PassOwnPtr<Type1>)\n'
3635 self.assert_pass_ptr_check(
3636 'int myFunction(OwnPtr<Type1>)\n'
3639 'The parameter type should use PassOwnPtr instead of OwnPtr. [readability/pass_ptr] [5]')
3640 self.assert_pass_ptr_check(
3641 'int myFunction(OwnPtr<Type1>& simple)\n'
3646 def test_ref_ptr_member_variable(self):
3647 self.assert_pass_ptr_check(
3649 ' RefPtr<Type1> m_other;\n'
3654 class LeakyPatternTest(CppStyleTestBase):
3656 def assert_leaky_pattern_check(self, code, expected_message):
3657 """Check warnings for leaky patterns are as expected.
3660 code: C++ source code expected to generate a warning message.
3661 expected_message: Message expected to be generated by the C++ code.
3663 self.assertEqual(expected_message,
3664 self.perform_leaky_pattern_check(code))
3666 def test_get_dc(self):
3667 self.assert_leaky_pattern_check(
3668 'HDC hdc = GetDC(hwnd);',
3669 'Use the class HWndDC instead of calling GetDC to avoid potential '
3670 'memory leaks. [runtime/leaky_pattern] [5]')
3672 def test_get_dc(self):
3673 self.assert_leaky_pattern_check(
3674 'HDC hdc = GetDCEx(hwnd, 0, 0);',
3675 'Use the class HWndDC instead of calling GetDCEx to avoid potential '
3676 'memory leaks. [runtime/leaky_pattern] [5]')
3678 def test_own_get_dc(self):
3679 self.assert_leaky_pattern_check(
3680 'HWndDC hdc(hwnd);',
3683 def test_create_dc(self):
3684 self.assert_leaky_pattern_check(
3685 'HDC dc2 = ::CreateDC();',
3686 'Use adoptPtr and OwnPtr<HDC> when calling CreateDC to avoid potential '
3687 'memory leaks. [runtime/leaky_pattern] [5]')
3689 self.assert_leaky_pattern_check(
3690 'adoptPtr(CreateDC());',
3693 def test_create_compatible_dc(self):
3694 self.assert_leaky_pattern_check(
3695 'HDC dc2 = CreateCompatibleDC(dc);',
3696 'Use adoptPtr and OwnPtr<HDC> when calling CreateCompatibleDC to avoid potential '
3697 'memory leaks. [runtime/leaky_pattern] [5]')
3698 self.assert_leaky_pattern_check(
3699 'adoptPtr(CreateCompatibleDC(dc));',
3703 class WebKitStyleTest(CppStyleTestBase):
3705 # for http://webkit.org/coding/coding-style.html
3706 def test_indentation(self):
3707 # 1. Use spaces, not tabs. Tabs should only appear in files that
3708 # require them for semantic meaning, like Makefiles.
3709 self.assert_multi_line_lint(
3714 self.assert_multi_line_lint(
3718 'Tab found; better to use spaces [whitespace/tab] [1]')
3720 # 2. The indent size is 4 spaces.
3721 self.assert_multi_line_lint(
3726 self.assert_multi_line_lint(
3730 'Weird number of spaces at line-start. Are you using a 4-space indent? [whitespace/indent] [3]')
3732 # 3. In a header, code inside a namespace should not be indented.
3733 self.assert_multi_line_lint(
3734 'namespace WebCore {\n\n'
3735 'class Document {\n'
3736 ' int myVariable;\n'
3741 self.assert_multi_line_lint(
3742 'namespace OuterNamespace {\n'
3743 ' namespace InnerNamespace {\n'
3744 ' class Document {\n'
3748 'Code inside a namespace should not be indented. [whitespace/indent] [4]',
3750 self.assert_multi_line_lint(
3751 'namespace OuterNamespace {\n'
3752 ' class Document {\n'
3753 ' namespace InnerNamespace {\n'
3757 'Code inside a namespace should not be indented. [whitespace/indent] [4]',
3759 self.assert_multi_line_lint(
3760 'namespace WebCore {\n'
3762 ' class Document {\n'
3766 'Code inside a namespace should not be indented. [whitespace/indent] [4]',
3768 self.assert_multi_line_lint(
3769 'namespace WebCore {\n'
3770 'class Document {\n'
3776 # 4. In an implementation file (files with the extension .cpp, .c
3777 # or .mm), code inside a namespace should not be indented.
3778 self.assert_multi_line_lint(
3779 'namespace WebCore {\n\n'
3788 self.assert_multi_line_lint(
3789 'namespace OuterNamespace {\n'
3790 'namespace InnerNamespace {\n'
3791 'Document::Foo() { }\n'
3795 'Code inside a namespace should not be indented. [whitespace/indent] [4]',
3797 self.assert_multi_line_lint(
3798 'namespace OuterNamespace {\n'
3799 'namespace InnerNamespace {\n'
3800 'Document::Foo() { }\n'
3804 'Code inside a namespace should not be indented. [whitespace/indent] [4]',
3806 self.assert_multi_line_lint(
3807 'namespace WebCore {\n\n'
3808 ' const char* foo = "start:;"\n'
3811 'Code inside a namespace should not be indented. [whitespace/indent] [4]',
3813 self.assert_multi_line_lint(
3814 'namespace WebCore {\n\n'
3815 'const char* foo(void* a = ";", // ;\n'
3819 'Code inside a namespace should not be indented. [whitespace/indent] [4]',
3821 self.assert_multi_line_lint(
3822 'namespace WebCore {\n\n'
3823 'const char* foo[] = {\n'
3824 ' "void* b);", // ;\n'
3829 'Code inside a namespace should not be indented. [whitespace/indent] [4]',
3831 self.assert_multi_line_lint(
3832 'namespace WebCore {\n\n'
3833 'const char* foo[] = {\n'
3834 ' "void* b);", // }\n'
3840 self.assert_multi_line_lint(
3841 ' namespace WebCore {\n\n'
3842 ' void Document::Foo()\n'
3844 'start: // infinite loops are fun!\n'
3847 'namespace should never be indented. [whitespace/indent] [4]',
3849 self.assert_multi_line_lint(
3850 'namespace WebCore {\n'
3851 ' Document::Foo() { }\n'
3853 'Code inside a namespace should not be indented.'
3854 ' [whitespace/indent] [4]',
3856 self.assert_multi_line_lint(
3857 'namespace WebCore {\n'
3858 '#define abc(x) x; \\\n'
3863 self.assert_multi_line_lint(
3864 'namespace WebCore {\n'
3865 '#define abc(x) x; \\\n'
3869 'Code inside a namespace should not be indented. [whitespace/indent] [4]',
3872 # 5. A case label should line up with its switch statement. The
3873 # case statement is indented.
3874 self.assert_multi_line_lint(
3875 ' switch (condition) {\n'
3876 ' case fooCondition:\n'
3877 ' case barCondition:\n'
3884 self.assert_multi_line_lint(
3885 ' switch (condition) {\n'
3886 ' case fooCondition:\n'
3887 ' switch (otherCondition) {\n'
3895 self.assert_multi_line_lint(
3896 ' switch (condition) {\n'
3897 ' case fooCondition: break;\n'
3898 ' default: return;\n'
3901 self.assert_multi_line_lint(
3902 ' switch (condition) {\n'
3903 ' case fooCondition:\n'
3904 ' case barCondition:\n'
3910 'A case label should not be indented, but line up with its switch statement.'
3911 ' [whitespace/indent] [4]')
3912 self.assert_multi_line_lint(
3913 ' switch (condition) {\n'
3914 ' case fooCondition:\n'
3919 'A case label should not be indented, but line up with its switch statement.'
3920 ' [whitespace/indent] [4]')
3921 self.assert_multi_line_lint(
3922 ' switch (condition) {\n'
3923 ' case fooCondition:\n'
3924 ' case barCondition:\n'
3925 ' switch (otherCondition) {\n'
3932 'A case label should not be indented, but line up with its switch statement.'
3933 ' [whitespace/indent] [4]')
3934 self.assert_multi_line_lint(
3935 ' switch (condition) {\n'
3936 ' case fooCondition:\n'
3937 ' case barCondition:\n'
3943 'Non-label code inside switch statements should be indented.'
3944 ' [whitespace/indent] [4]')
3945 self.assert_multi_line_lint(
3946 ' switch (condition) {\n'
3947 ' case fooCondition:\n'
3948 ' case barCondition:\n'
3949 ' switch (otherCondition) {\n'
3956 'Non-label code inside switch statements should be indented.'
3957 ' [whitespace/indent] [4]')
3959 # 6. Boolean expressions at the same nesting level that span
3960 # multiple lines should have their operators on the left side of
3961 # the line instead of the right side.
3962 self.assert_multi_line_lint(
3963 ' return attr->name() == srcAttr\n'
3964 ' || attr->name() == lowsrcAttr;\n',
3966 self.assert_multi_line_lint(
3967 ' return attr->name() == srcAttr ||\n'
3968 ' attr->name() == lowsrcAttr;\n',
3969 'Boolean expressions that span multiple lines should have their '
3970 'operators on the left side of the line instead of the right side.'
3971 ' [whitespace/operators] [4]')
3973 def test_spacing(self):
3974 # 1. Do not place spaces around unary operators.
3975 self.assert_multi_line_lint(
3978 self.assert_multi_line_lint(
3980 'Extra space for operator ++; [whitespace/operators] [4]')
3982 # 2. Do place spaces around binary and ternary operators.
3983 self.assert_multi_line_lint(
3986 self.assert_multi_line_lint(
3989 self.assert_multi_line_lint(
3992 self.assert_multi_line_lint(
3993 'return condition ? 1 : 0;',
3995 self.assert_multi_line_lint(
3997 'Missing spaces around = [whitespace/operators] [4]')
3998 self.assert_multi_line_lint(
4000 'Missing space after , [whitespace/comma] [3]')
4001 self.assert_multi_line_lint(
4003 'Missing spaces around | [whitespace/operators] [3]')
4004 # FIXME: We cannot catch this lint error.
4005 # self.assert_multi_line_lint(
4006 # 'return condition ? 1:0;',
4009 # 3. Place spaces between control statements and their parentheses.
4010 self.assert_multi_line_lint(
4014 self.assert_multi_line_lint(
4017 'Missing space before ( in if( [whitespace/parens] [5]')
4019 # 4. Do not place spaces between a function and its parentheses,
4020 # or between a parenthesis and its content.
4021 self.assert_multi_line_lint(
4024 self.assert_multi_line_lint(
4026 'Extra space before ( in function call [whitespace/parens] [4]')
4027 self.assert_multi_line_lint(
4029 ['Extra space after ( in function call [whitespace/parens] [4]',
4030 'Extra space before ) [whitespace/parens] [2]'])
4032 def test_line_breaking(self):
4033 # 1. Each statement should get its own line.
4034 self.assert_multi_line_lint(
4037 ' if (condition);\n'
4040 self.assert_multi_line_lint(
4041 ' if (condition) \\\n'
4044 self.assert_multi_line_lint(
4046 'More than one command on the same line [whitespace/newline] [4]')
4047 self.assert_multi_line_lint(
4048 ' if (condition) doIt();\n',
4049 'More than one command on the same line in if [whitespace/parens] [4]')
4050 # Ensure that having a # in the line doesn't hide the error.
4051 self.assert_multi_line_lint(
4052 ' x++; char a[] = "#";',
4053 'More than one command on the same line [whitespace/newline] [4]')
4054 # Ignore preprocessor if's.
4055 self.assert_multi_line_lint(
4056 '#if (condition) || (condition2)\n',
4059 # 2. An else statement should go on the same line as a preceding
4060 # close brace if one is present, else it should line up with the
4062 self.assert_multi_line_lint(
4063 'if (condition) {\n'
4065 ' doSomethingAgain();\n'
4067 ' doSomethingElse();\n'
4068 ' doSomethingElseAgain();\n'
4071 self.assert_multi_line_lint(
4075 ' doSomethingElse();\n',
4077 self.assert_multi_line_lint(
4078 'if (condition) {\n'
4081 ' doSomethingElse();\n'
4082 ' doSomethingElseAgain();\n'
4085 self.assert_multi_line_lint(
4086 '#define TEST_ASSERT(expression) do { if (!(expression)) { TestsController::shared().testFailed(__FILE__, __LINE__, #expression); return; } } while (0)\n',
4088 self.assert_multi_line_lint(
4089 '#define TEST_ASSERT(expression) do { if ( !(expression)) { TestsController::shared().testFailed(__FILE__, __LINE__, #expression); return; } } while (0)\n',
4090 'Extra space after ( in if [whitespace/parens] [5]')
4091 # FIXME: currently we only check first conditional, so we cannot detect errors in next ones.
4092 # self.assert_multi_line_lint(
4093 # '#define TEST_ASSERT(expression) do { if (!(expression)) { TestsController::shared().testFailed(__FILE__, __LINE__, #expression); return; } } while (0 )\n',
4094 # 'Mismatching spaces inside () in if [whitespace/parens] [5]')
4095 self.assert_multi_line_lint(
4096 'WTF_MAKE_NONCOPYABLE(ClassName); WTF_MAKE_FAST_ALLOCATED;\n',
4098 self.assert_multi_line_lint(
4099 'if (condition) {\n'
4101 ' doSomethingAgain();\n'
4104 ' doSomethingElse();\n'
4105 ' doSomethingElseAgain();\n'
4107 'An else should appear on the same line as the preceding } [whitespace/newline] [4]')
4108 self.assert_multi_line_lint(
4109 'if (condition) doSomething(); else doSomethingElse();\n',
4110 ['More than one command on the same line [whitespace/newline] [4]',
4111 'Else clause should never be on same line as else (use 2 lines) [whitespace/newline] [4]',
4112 'More than one command on the same line in if [whitespace/parens] [4]'])
4113 self.assert_multi_line_lint(
4114 'if (condition) doSomething(); else {\n'
4115 ' doSomethingElse();\n'
4117 ['More than one command on the same line in if [whitespace/parens] [4]',
4118 'If one part of an if-else statement uses curly braces, the other part must too. [whitespace/braces] [4]'])
4119 self.assert_multi_line_lint(
4122 ' while (condition) { }\n'
4126 self.assert_multi_line_lint(
4129 ' for (i = 0; i < 42; i++) { foobar(); }\n'
4132 'More than one command on the same line in for [whitespace/parens] [4]')
4134 # 3. An else if statement should be written as an if statement
4135 # when the prior if concludes with a return statement.
4136 self.assert_multi_line_lint(
4137 'if (motivated) {\n'
4140 '} else if (tired) {\n'
4144 self.assert_multi_line_lint(
4147 'else if (otherCondition)\n'
4148 ' doSomethingElse();\n',
4150 self.assert_multi_line_lint(
4154 ' doSomethingElse();\n',
4156 self.assert_multi_line_lint(
4158 ' returnValue = foo;\n'
4159 'else if (otherCondition)\n'
4160 ' returnValue = bar;\n',
4162 self.assert_multi_line_lint(
4164 ' returnValue = foo;\n'
4166 ' returnValue = bar;\n',
4168 self.assert_multi_line_lint(
4171 'else if (liquid)\n'
4178 self.assert_multi_line_lint(
4182 '} else if (greedy) {\n'
4184 ' return nothing;\n'
4186 'An else if statement should be written as an if statement when the '
4187 'prior "if" concludes with a return, break, continue or goto statement.'
4188 ' [readability/control_flow] [4]')
4189 self.assert_multi_line_lint(
4192 ' goto infiniteLoop;\n'
4193 ' } else if (evil)\n'
4195 ['If one part of an if-else statement uses curly braces, the other part must too. [whitespace/braces] [4]',
4196 'An else if statement should be written as an if statement when the '
4197 'prior "if" concludes with a return, break, continue or goto statement.'
4198 ' [readability/control_flow] [4]'])
4199 self.assert_multi_line_lint(
4205 'else if (greedy)\n'
4207 ['If one part of an if-else statement uses curly braces, the other part must too. [whitespace/braces] [4]',
4208 'This { should be at the end of the previous line [whitespace/braces] [4]',
4209 'An else should appear on the same line as the preceding } [whitespace/newline] [4]',
4210 'An else if statement should be written as an if statement when the '
4211 'prior "if" concludes with a return, break, continue or goto statement.'
4212 ' [readability/control_flow] [4]'])
4213 self.assert_multi_line_lint(
4218 'An else if statement should be written as an if statement when the '
4219 'prior "if" concludes with a return, break, continue or goto statement.'
4220 ' [readability/control_flow] [4]')
4221 self.assert_multi_line_lint(
4226 'An else statement can be removed when the prior "if" concludes '
4227 'with a return, break, continue or goto statement.'
4228 ' [readability/control_flow] [4]')
4229 self.assert_multi_line_lint(
4230 'if (motivated) {\n'
4237 'An else statement can be removed when the prior "if" concludes '
4238 'with a return, break, continue or goto statement.'
4239 ' [readability/control_flow] [4]')
4240 self.assert_multi_line_lint(
4247 ['If one part of an if-else statement uses curly braces, the other part must too. [whitespace/braces] [4]',
4248 'An else statement can be removed when the prior "if" concludes '
4249 'with a return, break, continue or goto statement.'
4250 ' [readability/control_flow] [4]'])
4252 def test_braces(self):
4253 # 1. Function definitions: place each brace on its own line.
4254 self.assert_multi_line_lint(
4260 self.assert_multi_line_lint(
4264 'Place brace on its own line for function definitions. [whitespace/braces] [4]')
4266 # 2. Other braces: place the open brace on the line preceding the
4267 # code block; place the close brace on its own line.
4268 self.assert_multi_line_lint(
4273 self.assert_multi_line_lint(
4274 'namespace WebCore {\n'
4278 self.assert_multi_line_lint(
4279 'for (int i = 0; i < 10; i++) {\n'
4283 self.assert_multi_line_lint(
4288 'This { should be at the end of the previous line [whitespace/braces] [4]')
4289 self.assert_multi_line_lint(
4294 'This { should be at the end of the previous line [whitespace/braces] [4]')
4295 self.assert_multi_line_lint(
4296 'for (int i = 0; i < 10; i++)\n'
4300 'This { should be at the end of the previous line [whitespace/braces] [4]')
4301 self.assert_multi_line_lint(
4306 'This { should be at the end of the previous line [whitespace/braces] [4]')
4307 self.assert_multi_line_lint(
4308 'foreach (Foo* foo, foos)\n'
4312 'This { should be at the end of the previous line [whitespace/braces] [4]')
4313 self.assert_multi_line_lint(
4316 'case foo: return;\n'
4318 'This { should be at the end of the previous line [whitespace/braces] [4]')
4319 self.assert_multi_line_lint(
4324 'This { should be at the end of the previous line [whitespace/braces] [4]')
4325 self.assert_multi_line_lint(
4326 'for (int i = 0; i < 10; i++)\n'
4330 'This { should be at the end of the previous line [whitespace/braces] [4]')
4331 self.assert_multi_line_lint(
4336 'This { should be at the end of the previous line [whitespace/braces] [4]')
4337 self.assert_multi_line_lint(
4340 'case foo: return;\n'
4342 'This { should be at the end of the previous line [whitespace/braces] [4]')
4343 self.assert_multi_line_lint(
4346 'case foo: return;\n'
4348 'This { should be at the end of the previous line [whitespace/braces] [4]')
4350 # 3. Curly braces are not required for single-line conditionals and
4351 # loop bodies, but are required for single-statement bodies that
4352 # span multiple lines.
4357 self.assert_multi_line_lint(
4364 self.assert_multi_line_lint(
4367 'else if (condition2)\n'
4371 self.assert_multi_line_lint(
4374 'else if (condition2)\n'
4380 self.assert_multi_line_lint(
4381 'for (; foo; bar)\n'
4385 self.assert_multi_line_lint(
4386 'for (; foo; bar) {\n'
4391 self.assert_multi_line_lint(
4392 'foreach (foo, foos) {\n'
4397 self.assert_multi_line_lint(
4398 'foreach (foo, foos)\n'
4402 self.assert_multi_line_lint(
4408 self.assert_multi_line_lint(
4413 self.assert_multi_line_lint(
4414 'if (condition1) {\n'
4421 self.assert_multi_line_lint(
4422 'if (condition1) {\n'
4424 '} else if (condition2) {\n'
4429 self.assert_multi_line_lint(
4430 'if (condition1) {\n'
4432 '} else if (condition2) {\n'
4439 self.assert_multi_line_lint(
4440 'if (condition1) {\n'
4442 ' statement1_2();\n'
4443 '} else if (condition2) {\n'
4445 ' statement2_2();\n'
4449 self.assert_multi_line_lint(
4450 'if (condition1) {\n'
4452 ' statement1_2();\n'
4453 '} else if (condition2) {\n'
4455 ' statement2_2();\n'
4458 ' statement3_2();\n'
4466 self.assert_multi_line_lint(
4469 ' spanningMultipleLines);\n',
4470 'A conditional or loop body must use braces if the statement is more than one line long. [whitespace/braces] [4]')
4472 self.assert_multi_line_lint(
4474 ' // Single-line comment\n'
4475 ' doSomething();\n',
4476 'A conditional or loop body must use braces if the statement is more than one line long. [whitespace/braces] [4]')
4478 self.assert_multi_line_lint(
4481 'else if (condition2)\n'
4482 ' // Single-line comment\n'
4484 'A conditional or loop body must use braces if the statement is more than one line long. [whitespace/braces] [4]')
4486 self.assert_multi_line_lint(
4489 'else if (condition2)\n'
4492 ' // Single-line comment\n'
4494 'A conditional or loop body must use braces if the statement is more than one line long. [whitespace/braces] [4]')
4496 self.assert_multi_line_lint(
4497 'for (; foo; bar)\n'
4498 ' // Single-line comment\n'
4500 'A conditional or loop body must use braces if the statement is more than one line long. [whitespace/braces] [4]')
4502 self.assert_multi_line_lint(
4503 'foreach (foo, foos)\n'
4504 ' // Single-line comment\n'
4506 'A conditional or loop body must use braces if the statement is more than one line long. [whitespace/braces] [4]')
4508 self.assert_multi_line_lint(
4510 ' // Single-line comment\n'
4513 'A conditional or loop body must use braces if the statement is more than one line long. [whitespace/braces] [4]')
4515 # 4. If one part of an if-else statement uses curly braces, the
4516 # other part must too.
4518 self.assert_multi_line_lint(
4519 'if (condition1) {\n'
4520 ' doSomething1();\n'
4521 ' doSomething1_2();\n'
4522 '} else if (condition2)\n'
4523 ' doSomething2();\n'
4525 ' doSomething3();\n',
4526 'If one part of an if-else statement uses curly braces, the other part must too. [whitespace/braces] [4]')
4528 self.assert_multi_line_lint(
4530 ' doSomething1();\n'
4531 'else if (condition2) {\n'
4532 ' doSomething2();\n'
4533 ' doSomething2_2();\n'
4535 ' doSomething3();\n',
4536 'If one part of an if-else statement uses curly braces, the other part must too. [whitespace/braces] [4]')
4538 self.assert_multi_line_lint(
4539 'if (condition1) {\n'
4540 ' doSomething1();\n'
4541 '} else if (condition2) {\n'
4542 ' doSomething2();\n'
4543 ' doSomething2_2();\n'
4545 ' doSomething3();\n',
4546 'If one part of an if-else statement uses curly braces, the other part must too. [whitespace/braces] [4]')
4548 self.assert_multi_line_lint(
4550 ' doSomething1();\n'
4551 'else if (condition2)\n'
4552 ' doSomething2();\n'
4554 ' doSomething3();\n'
4555 ' doSomething3_2();\n'
4557 'If one part of an if-else statement uses curly braces, the other part must too. [whitespace/braces] [4]')
4559 self.assert_multi_line_lint(
4560 'if (condition1) {\n'
4561 ' doSomething1();\n'
4562 ' doSomething1_2();\n'
4563 '} else if (condition2)\n'
4564 ' doSomething2();\n'
4566 ' doSomething3();\n'
4567 ' doSomething3_2();\n'
4569 'If one part of an if-else statement uses curly braces, the other part must too. [whitespace/braces] [4]')
4571 self.assert_multi_line_lint(
4573 ' doSomething1();\n'
4574 'else if (condition2) {\n'
4575 ' doSomething2();\n'
4576 ' doSomething2_2();\n'
4578 ' doSomething3();\n'
4579 ' doSomething3_2();\n'
4581 'If one part of an if-else statement uses curly braces, the other part must too. [whitespace/braces] [4]')
4584 # 5. Control clauses without a body should use empty braces.
4585 self.assert_multi_line_lint(
4586 'for ( ; current; current = current->next) { }\n',
4588 self.assert_multi_line_lint(
4589 'for ( ; current;\n'
4590 ' current = current->next) { }\n',
4591 'Weird number of spaces at line-start. Are you using a 4-space indent? [whitespace/indent] [3]')
4592 self.assert_multi_line_lint(
4593 'for ( ; current; current = current->next);\n',
4594 'Semicolon defining empty statement for this loop. Use { } instead. [whitespace/semicolon] [5]')
4595 self.assert_multi_line_lint(
4597 'Semicolon defining empty statement for this loop. Use { } instead. [whitespace/semicolon] [5]')
4598 self.assert_multi_line_lint(
4599 '} while (true);\n',
4602 def test_null_false_zero(self):
4603 # 1. In C++, the null pointer value should be written as 0. In C,
4604 # it should be written as NULL. In Objective-C and Objective-C++,
4605 # follow the guideline for C or C++, respectively, but use nil to
4606 # represent a null Objective-C object.
4608 'functionCall(NULL)',
4609 'Use 0 instead of NULL.'
4610 ' [readability/null] [5]',
4613 "// Don't use NULL in comments since it isn't in code.",
4614 'Use 0 or null instead of NULL (even in *comments*).'
4615 ' [readability/null] [4]',
4618 '"A string with NULL" // and a comment with NULL is tricky to flag correctly in cpp_style.',
4619 'Use 0 or null instead of NULL (even in *comments*).'
4620 ' [readability/null] [4]',
4623 '"A string containing NULL is ok"',
4631 'myVariable = NULLify',
4634 # Make sure that the NULL check does not apply to C and Objective-C files.
4636 'functionCall(NULL)',
4640 'functionCall(NULL)',
4644 # Make sure that the NULL check does not apply to g_object_{set,get} and
4645 # g_str{join,concat}
4647 'g_object_get(foo, "prop", &bar, NULL);',
4650 'g_object_set(foo, "prop", bar, NULL);',
4653 'g_build_filename(foo, bar, NULL);',
4656 'gst_bin_add_many(foo, bar, boo, NULL);',
4659 'gst_bin_remove_many(foo, bar, boo, NULL);',
4662 'gst_element_link_many(foo, bar, boo, NULL);',
4665 'gst_element_unlink_many(foo, bar, boo, NULL);',
4668 'gst_structure_get(foo, "value", G_TYPE_INT, &value, NULL);',
4671 'gst_structure_set(foo, "value", G_TYPE_INT, value, NULL);',
4674 'gst_structure_remove_fields(foo, "value", "bar", NULL);',
4677 'gst_structure_new("foo", "value", G_TYPE_INT, value, NULL);',
4680 'gst_structure_id_new(FOO, VALUE, G_TYPE_INT, value, NULL);',
4683 'gst_structure_id_set(FOO, VALUE, G_TYPE_INT, value, NULL);',
4686 'gst_structure_id_get(FOO, VALUE, G_TYPE_INT, &value, NULL);',
4689 'gst_caps_new_simple(mime, "value", G_TYPE_INT, &value, NULL);',
4692 'gst_caps_new_full(structure1, structure2, NULL);',
4695 'gchar* result = g_strconcat("part1", "part2", "part3", NULL);',
4698 'gchar* result = g_strconcat("part1", NULL);',
4701 'gchar* result = g_strjoin(",", "part1", "part2", "part3", NULL);',
4704 'gchar* result = g_strjoin(",", "part1", NULL);',
4707 'gchar* result = gdk_pixbuf_save_to_callback(pixbuf, function, data, type, error, NULL);',
4710 'gchar* result = gdk_pixbuf_save_to_buffer(pixbuf, function, data, type, error, NULL);',
4713 'gchar* result = gdk_pixbuf_save_to_stream(pixbuf, function, data, type, error, NULL);',
4716 'gtk_widget_style_get(style, "propertyName", &value, "otherName", &otherValue, NULL);',
4719 'gtk_style_context_get_style(context, "propertyName", &value, "otherName", &otherValue, NULL);',
4722 'gtk_style_context_get(context, static_cast<GtkStateFlags>(0), "property", &value, NULL);',
4725 'gtk_widget_style_get_property(style, NULL, NULL);',
4726 'Use 0 instead of NULL. [readability/null] [5]',
4729 'gtk_widget_style_get_valist(style, NULL, NULL);',
4730 'Use 0 instead of NULL. [readability/null] [5]',
4733 # 2. C++ and C bool values should be written as true and
4734 # false. Objective-C BOOL values should be written as YES and NO.
4735 # FIXME: Implement this.
4737 # 3. Tests for true/false and null/non-null should be done without
4738 # equality comparisons.
4739 self.assert_lint_one_of_many_errors_re(
4740 'if (string != NULL)',
4741 r'Tests for true/false and null/non-null should be done without equality comparisons\.')
4743 'if (p == nullptr)',
4744 'Tests for true/false and null/non-null should be done without equality comparisons.'
4745 ' [readability/comparison_to_boolean] [5]')
4747 'if (condition == true)',
4748 'Tests for true/false and null/non-null should be done without equality comparisons.'
4749 ' [readability/comparison_to_boolean] [5]')
4751 'if (myVariable != /* Why would anyone put a comment here? */ false)',
4752 'Tests for true/false and null/non-null should be done without equality comparisons.'
4753 ' [readability/comparison_to_boolean] [5]')
4755 self.assert_lint_one_of_many_errors_re(
4756 'if (NULL == thisMayBeNull)',
4757 r'Tests for true/false and null/non-null should be done without equality comparisons\.')
4759 'if (nullptr /* funny place for a comment */ == p)',
4760 'Tests for true/false and null/non-null should be done without equality comparisons.'
4761 ' [readability/comparison_to_boolean] [5]')
4763 'if (true != anotherCondition)',
4764 'Tests for true/false and null/non-null should be done without equality comparisons.'
4765 ' [readability/comparison_to_boolean] [5]')
4767 'if (false == myBoolValue)',
4768 'Tests for true/false and null/non-null should be done without equality comparisons.'
4769 ' [readability/comparison_to_boolean] [5]')
4772 'if (fontType == trueType)',
4775 'if (othertrue == fontType)',
4778 'if (LIKELY(foo == 0))',
4781 'if (UNLIKELY(foo == 0))',
4784 'if ((a - b) == 0.5)',
4787 'if (0.5 == (a - b))',
4790 'if (LIKELY(foo == NULL))',
4791 'Use 0 instead of NULL. [readability/null] [5]')
4793 'if (UNLIKELY(foo == NULL))',
4794 'Use 0 instead of NULL. [readability/null] [5]')
4796 def test_directive_indentation(self):
4799 "preprocessor directives (e.g., #ifdef, #define, #import) should never be indented."
4800 " [whitespace/indent] [4]",
4803 def test_using_std(self):
4806 "Use 'using namespace std;' instead of 'using std::min;'."
4807 " [build/using_std] [4]",
4810 def test_using_std_swap_ignored(self):
4816 def test_max_macro(self):
4818 'int i = MAX(0, 1);',
4823 'int i = MAX(0, 1);',
4824 'Use std::max() or std::max<type>() instead of the MAX() macro.'
4825 ' [runtime/max_min_macros] [4]',
4829 'inline int foo() { return MAX(0, 1); }',
4830 'Use std::max() or std::max<type>() instead of the MAX() macro.'
4831 ' [runtime/max_min_macros] [4]',
4834 def test_min_macro(self):
4836 'int i = MIN(0, 1);',
4841 'int i = MIN(0, 1);',
4842 'Use std::min() or std::min<type>() instead of the MIN() macro.'
4843 ' [runtime/max_min_macros] [4]',
4847 'inline int foo() { return MIN(0, 1); }',
4848 'Use std::min() or std::min<type>() instead of the MIN() macro.'
4849 ' [runtime/max_min_macros] [4]',
4852 def test_ctype_fucntion(self):
4854 'int i = isascii(8);',
4855 'Use equivelent function in <wtf/ASCIICType.h> instead of the '
4856 'isascii() function. [runtime/ctype_function] [4]',
4859 def test_names(self):
4860 name_underscore_error_message = " is incorrectly named. Don't use underscores in your identifier names. [readability/naming/underscores] [4]"
4861 name_tooshort_error_message = " is incorrectly named. Don't use the single letter 'l' as an identifier name. [readability/naming] [4]"
4863 # Basic cases from WebKit style guide.
4864 self.assert_lint('struct Data;', '')
4865 self.assert_lint('size_t bufferSize;', '')
4866 self.assert_lint('class HTMLDocument;', '')
4867 self.assert_lint('String mimeType();', '')
4868 self.assert_lint('size_t buffer_size;',
4869 'buffer_size' + name_underscore_error_message)
4870 self.assert_lint('short m_length;', '')
4871 self.assert_lint('short _length;',
4872 '_length' + name_underscore_error_message)
4873 self.assert_lint('short length_;',
4874 'length_' + name_underscore_error_message)
4875 self.assert_lint('unsigned _length;',
4876 '_length' + name_underscore_error_message)
4877 self.assert_lint('unsigned long _length;',
4878 '_length' + name_underscore_error_message)
4879 self.assert_lint('unsigned long long _length;',
4880 '_length' + name_underscore_error_message)
4882 # Allow underscores in Objective C files.
4883 self.assert_lint('unsigned long long _length;',
4886 self.assert_lint('unsigned long long _length;',
4889 self.assert_lint('#import "header_file.h"\n'
4890 'unsigned long long _length;',
4893 self.assert_lint('unsigned long long _length;\n'
4894 '@interface WebFullscreenWindow;',
4897 self.assert_lint('unsigned long long _length;\n'
4898 '@implementation WebFullscreenWindow;',
4901 self.assert_lint('unsigned long long _length;\n'
4902 '@class WebWindowFadeAnimation;',
4906 # Variable name 'l' is easy to confuse with '1'
4907 self.assert_lint('int l;', 'l' + name_tooshort_error_message)
4908 self.assert_lint('size_t l;', 'l' + name_tooshort_error_message)
4909 self.assert_lint('long long l;', 'l' + name_tooshort_error_message)
4911 # Pointers, references, functions, templates, and adjectives.
4912 self.assert_lint('char* under_score;',
4913 'under_score' + name_underscore_error_message)
4914 self.assert_lint('const int UNDER_SCORE;',
4915 'UNDER_SCORE' + name_underscore_error_message)
4916 self.assert_lint('static inline const char const& const under_score;',
4917 'under_score' + name_underscore_error_message)
4918 self.assert_lint('WebCore::RenderObject* under_score;',
4919 'under_score' + name_underscore_error_message)
4920 self.assert_lint('int func_name();',
4921 'func_name' + name_underscore_error_message)
4922 self.assert_lint('RefPtr<RenderObject*> under_score;',
4923 'under_score' + name_underscore_error_message)
4924 self.assert_lint('WTF::Vector<WTF::RefPtr<const RenderObject* const> > under_score;',
4925 'under_score' + name_underscore_error_message)
4926 self.assert_lint('int under_score[];',
4927 'under_score' + name_underscore_error_message)
4928 self.assert_lint('struct dirent* under_score;',
4929 'under_score' + name_underscore_error_message)
4930 self.assert_lint('long under_score;',
4931 'under_score' + name_underscore_error_message)
4932 self.assert_lint('long long under_score;',
4933 'under_score' + name_underscore_error_message)
4934 self.assert_lint('long double under_score;',
4935 'under_score' + name_underscore_error_message)
4936 self.assert_lint('long long int under_score;',
4937 'under_score' + name_underscore_error_message)
4939 # Declarations in control statement.
4940 self.assert_lint('if (int under_score = 42) {',
4941 'under_score' + name_underscore_error_message)
4942 self.assert_lint('else if (int under_score = 42) {',
4943 'under_score' + name_underscore_error_message)
4944 self.assert_lint('for (int under_score = 42; cond; i++) {',
4945 'under_score' + name_underscore_error_message)
4946 self.assert_lint('while (foo & under_score = bar) {',
4947 'under_score' + name_underscore_error_message)
4948 self.assert_lint('for (foo * under_score = p; cond; i++) {',
4949 'under_score' + name_underscore_error_message)
4950 self.assert_lint('for (foo * under_score; cond; i++) {',
4951 'under_score' + name_underscore_error_message)
4952 self.assert_lint('while (foo & value_in_thirdparty_library) {', '')
4953 self.assert_lint('while (foo * value_in_thirdparty_library) {', '')
4954 self.assert_lint('if (mli && S_OK == mli->foo()) {', '')
4956 # More member variables and functions.
4957 self.assert_lint('int SomeClass::s_validName', '')
4958 self.assert_lint('int m_under_score;',
4959 'm_under_score' + name_underscore_error_message)
4960 self.assert_lint('int SomeClass::s_under_score = 0;',
4961 'SomeClass::s_under_score' + name_underscore_error_message)
4962 self.assert_lint('int SomeClass::under_score = 0;',
4963 'SomeClass::under_score' + name_underscore_error_message)
4966 self.assert_lint('return INT_MAX;', '')
4967 self.assert_lint('return_t under_score;',
4968 'under_score' + name_underscore_error_message)
4969 self.assert_lint('goto under_score;',
4970 'under_score' + name_underscore_error_message)
4971 self.assert_lint('delete static_cast<Foo*>(p);', '')
4973 # Multiple variables in one line.
4974 self.assert_lint('void myFunction(int variable1, int another_variable);',
4975 'another_variable' + name_underscore_error_message)
4976 self.assert_lint('int variable1, another_variable;',
4977 'another_variable' + name_underscore_error_message)
4978 self.assert_lint('int first_variable, secondVariable;',
4979 'first_variable' + name_underscore_error_message)
4980 self.assert_lint('void my_function(int variable_1, int variable_2);',
4981 ['my_function' + name_underscore_error_message,
4982 'variable_1' + name_underscore_error_message,
4983 'variable_2' + name_underscore_error_message])
4984 self.assert_lint('for (int variable_1, variable_2;;) {',
4985 ['variable_1' + name_underscore_error_message,
4986 'variable_2' + name_underscore_error_message])
4988 # There is an exception for op code functions but only in the JavaScriptCore directory.
4989 self.assert_lint('void this_op_code(int var1, int var2)', '', 'Source/JavaScriptCore/foo.cpp')
4990 self.assert_lint('void op_code(int var1, int var2)', '', 'Source/JavaScriptCore/foo.cpp')
4991 self.assert_lint('void this_op_code(int var1, int var2)', 'this_op_code' + name_underscore_error_message)
4993 # GObject requires certain magical names in class declarations.
4994 self.assert_lint('void webkit_dom_object_init();', '')
4995 self.assert_lint('void webkit_dom_object_class_init();', '')
4997 # There is an exception for GTK+ API.
4998 self.assert_lint('void webkit_web_view_load(int var1, int var2)', '', 'Source/Webkit/gtk/webkit/foo.cpp')
4999 self.assert_lint('void webkit_web_view_load(int var1, int var2)', '', 'Source/Webkit2/UIProcess/gtk/foo.cpp')
5001 # Test that this doesn't also apply to files not in a 'gtk' directory.
5002 self.assert_lint('void webkit_web_view_load(int var1, int var2)',
5003 'webkit_web_view_load is incorrectly named. Don\'t use underscores in your identifier names.'
5004 ' [readability/naming/underscores] [4]', 'Source/Webkit/webkit/foo.cpp')
5005 # Test that this doesn't also apply to names that don't start with 'webkit_'.
5006 self.assert_lint_one_of_many_errors_re('void otherkit_web_view_load(int var1, int var2)',
5007 'otherkit_web_view_load is incorrectly named. Don\'t use underscores in your identifier names.'
5008 ' [readability/naming/underscores] [4]', 'Source/Webkit/webkit/foo.cpp')
5010 # There is an exception for some unit tests that begin with "tst_".
5011 self.assert_lint('void tst_QWebFrame::arrayObjectEnumerable(int var1, int var2)', '')
5013 # The Qt API uses names that begin with "qt_" or "_q_".
5014 self.assert_lint('void QTFrame::qt_drt_is_awesome(int var1, int var2)', '')
5015 self.assert_lint('void QTFrame::_q_drt_is_awesome(int var1, int var2)', '')
5016 self.assert_lint('void qt_drt_is_awesome(int var1, int var2);', '')
5017 self.assert_lint('void _q_drt_is_awesome(int var1, int var2);', '')
5019 # Cairo forward-declarations should not be a failure.
5020 self.assert_lint('typedef struct _cairo cairo_t;', '')
5021 self.assert_lint('typedef struct _cairo_surface cairo_surface_t;', '')
5022 self.assert_lint('typedef struct _cairo_scaled_font cairo_scaled_font_t;', '')
5024 # EFL forward-declarations should not be a failure.
5025 self.assert_lint('typedef struct _Ecore_Evas Ecore_Evas;', '')
5026 self.assert_lint('typedef struct _Ecore_Pipe Ecore_Pipe;', '')
5027 self.assert_lint('typedef struct _Eina_Rectangle Eina_Rectangle;', '')
5028 self.assert_lint('typedef struct _Evas_Object Evas_Object;', '')
5029 self.assert_lint('typedef struct _Ewk_History_Item Ewk_History_Item;', '')
5031 # NPAPI functions that start with NPN_, NPP_ or NP_ are allowed.
5032 self.assert_lint('void NPN_Status(NPP, const char*)', '')
5033 self.assert_lint('NPError NPP_SetWindow(NPP instance, NPWindow *window)', '')
5034 self.assert_lint('NPObject* NP_Allocate(NPP, NPClass*)', '')
5036 # const_iterator is allowed as well.
5037 self.assert_lint('typedef VectorType::const_iterator const_iterator;', '')
5039 # vm_throw is allowed as well.
5040 self.assert_lint('int vm_throw;', '')
5043 self.assert_lint('int foo ALLOW_UNUSED;', '')
5044 self.assert_lint('int foo_error ALLOW_UNUSED;', 'foo_error' + name_underscore_error_message)
5045 self.assert_lint('ThreadFunctionInvocation* leakedInvocation ALLOW_UNUSED = invocation.leakPtr()', '')
5048 self.assert_lint('unsigned _fillRule : 1;',
5049 '_fillRule' + name_underscore_error_message)
5051 # new operators in initialization.
5052 self.assert_lint('OwnPtr<uint32_t> variable(new uint32_t);', '')
5053 self.assert_lint('OwnPtr<uint32_t> variable(new (expr) uint32_t);', '')
5054 self.assert_lint('OwnPtr<uint32_t> under_score(new uint32_t);',
5055 'under_score' + name_underscore_error_message)
5057 # Conversion operator declaration.
5058 self.assert_lint('operator int64_t();', '')
5060 def test_parameter_names(self):
5061 # Leave meaningless variable names out of function declarations.
5062 meaningless_variable_name_error_message = 'The parameter name "%s" adds no information, so it should be removed. [readability/parameter_name] [5]'
5064 parameter_error_rules = ('-',
5065 '+readability/parameter_name')
5066 # No variable name, so no error.
5067 self.assertEqual('',
5068 self.perform_lint('void func(int);', 'test.cpp', parameter_error_rules))
5070 # Verify that copying the name of the set function causes the error (with some odd casing).
5071 self.assertEqual(meaningless_variable_name_error_message % 'itemCount',
5072 self.perform_lint('void setItemCount(size_t itemCount);', 'test.cpp', parameter_error_rules))
5073 self.assertEqual(meaningless_variable_name_error_message % 'abcCount',
5074 self.perform_lint('void setABCCount(size_t abcCount);', 'test.cpp', parameter_error_rules))
5076 # Verify that copying a type name will trigger the warning (even if the type is a template parameter).
5077 self.assertEqual(meaningless_variable_name_error_message % 'context',
5078 self.perform_lint('void funct(PassRefPtr<ScriptExecutionContext> context);', 'test.cpp', parameter_error_rules))
5080 # Verify that acronyms as variable names trigger the error (for both set functions and type names).
5081 self.assertEqual(meaningless_variable_name_error_message % 'ec',
5082 self.perform_lint('void setExceptionCode(int ec);', 'test.cpp', parameter_error_rules))
5083 self.assertEqual(meaningless_variable_name_error_message % 'ec',
5084 self.perform_lint('void funct(ExceptionCode ec);', 'test.cpp', parameter_error_rules))
5086 # 'object' alone, appended, or as part of an acronym is meaningless.
5087 self.assertEqual(meaningless_variable_name_error_message % 'object',
5088 self.perform_lint('void funct(RenderView object);', 'test.cpp', parameter_error_rules))
5089 self.assertEqual(meaningless_variable_name_error_message % 'viewObject',
5090 self.perform_lint('void funct(RenderView viewObject);', 'test.cpp', parameter_error_rules))
5091 self.assertEqual(meaningless_variable_name_error_message % 'rvo',
5092 self.perform_lint('void funct(RenderView rvo);', 'test.cpp', parameter_error_rules))
5094 # Check that r, g, b, and a are allowed.
5095 self.assertEqual('',
5096 self.perform_lint('void setRGBAValues(int r, int g, int b, int a);', 'test.cpp', parameter_error_rules))
5098 # Verify that a simple substring match isn't done which would cause false positives.
5099 self.assertEqual('',
5100 self.perform_lint('void setNateLateCount(size_t elate);', 'test.cpp', parameter_error_rules))
5101 self.assertEqual('',
5102 self.perform_lint('void funct(NateLate elate);', 'test.cpp', parameter_error_rules))
5104 # Don't have generate warnings for functions (only declarations).
5105 self.assertEqual('',
5106 self.perform_lint('void funct(PassRefPtr<ScriptExecutionContext> context)\n'
5108 '}\n', 'test.cpp', parameter_error_rules))
5110 def test_comments(self):
5111 # A comment at the beginning of a line is ok.
5112 self.assert_lint('// comment', '')
5113 self.assert_lint(' // comment', '')
5115 self.assert_lint('} // namespace WebCore',
5116 'One space before end of line comments'
5117 ' [whitespace/comments] [5]')
5119 def test_webkit_export_check(self):
5120 webkit_export_error_rules = ('-',
5121 '+readability/webkit_export')
5122 self.assertEqual('',
5123 self.perform_lint('WEBKIT_EXPORT int foo();\n',
5124 'WebKit/chromium/public/test.h',
5125 webkit_export_error_rules))
5126 self.assertEqual('',
5127 self.perform_lint('WEBKIT_EXPORT int foo();\n',
5128 'WebKit/chromium/tests/test.h',
5129 webkit_export_error_rules))
5130 self.assertEqual('WEBKIT_EXPORT should only be used in header files. [readability/webkit_export] [5]',
5131 self.perform_lint('WEBKIT_EXPORT int foo();\n',
5132 'WebKit/chromium/public/test.cpp',
5133 webkit_export_error_rules))
5134 self.assertEqual('WEBKIT_EXPORT should only appear in the chromium public (or tests) directory. [readability/webkit_export] [5]',
5135 self.perform_lint('WEBKIT_EXPORT int foo();\n',
5136 'WebKit/chromium/src/test.h',
5137 webkit_export_error_rules))
5138 self.assertEqual('WEBKIT_EXPORT should not be used on a function with a body. [readability/webkit_export] [5]',
5139 self.perform_lint('WEBKIT_EXPORT int foo() { }\n',
5140 'WebKit/chromium/public/test.h',
5141 webkit_export_error_rules))
5142 self.assertEqual('WEBKIT_EXPORT should not be used on a function with a body. [readability/webkit_export] [5]',
5143 self.perform_lint('WEBKIT_EXPORT inline int foo()\n'
5146 'WebKit/chromium/public/test.h',
5147 webkit_export_error_rules))
5148 self.assertEqual('WEBKIT_EXPORT should not be used with a pure virtual function. [readability/webkit_export] [5]',
5149 self.perform_lint('{}\n'
5154 'WebKit/chromium/public/test.h',
5155 webkit_export_error_rules))
5156 self.assertEqual('',
5157 self.perform_lint('{}\n'
5163 webkit_export_error_rules))
5165 def test_other(self):
5166 # FIXME: Implement this.
5170 class CppCheckerTest(unittest.TestCase):
5172 """Tests CppChecker class."""
5174 def mock_handle_style_error(self):
5178 return CppChecker("foo", "h", self.mock_handle_style_error, 3)
5180 def test_init(self):
5181 """Test __init__ constructor."""
5182 checker = self._checker()
5183 self.assertEqual(checker.file_extension, "h")
5184 self.assertEqual(checker.file_path, "foo")
5185 self.assertEqual(checker.handle_style_error, self.mock_handle_style_error)
5186 self.assertEqual(checker.min_confidence, 3)
5189 """Test __eq__ equality function."""
5190 checker1 = self._checker()
5191 checker2 = self._checker()
5194 self.assertTrue(checker1 == checker2)
5196 def mock_handle_style_error2(self):
5199 # Verify that a difference in any argument cause equality to fail.
5200 checker = CppChecker("foo", "h", self.mock_handle_style_error, 3)
5201 self.assertFalse(checker == CppChecker("bar", "h", self.mock_handle_style_error, 3))
5202 self.assertFalse(checker == CppChecker("foo", "c", self.mock_handle_style_error, 3))
5203 self.assertFalse(checker == CppChecker("foo", "h", mock_handle_style_error2, 3))
5204 self.assertFalse(checker == CppChecker("foo", "h", self.mock_handle_style_error, 4))
5207 """Test __ne__ inequality function."""
5208 checker1 = self._checker()
5209 checker2 = self._checker()
5212 # By default, __ne__ always returns true on different objects.
5213 # Thus, just check the distinguishing case to verify that the
5214 # code defines __ne__.
5215 self.assertFalse(checker1 != checker2)